import { readFile, writeFile } from "node:fs/promises";
import path from "node:path";
import { fileURLToPath } from "node:url";
import prettier from "prettier";
import { loadNativeModule } from "../js/node/loader.js";
import { NODE_ARRAY_TYPES } from "../js/node/napi-compat.js";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const FILE = path.resolve(__dirname, "../js/node-index.js");
const START = "// <generated:napi-reexports>";
const END = "// </generated:napi-reexports>";
const MANUAL = new Set(["WebClient", "AuthScheme"]);
async function buildFile() {
const napi = loadNativeModule();
const names = [
...new Set([
...Object.keys(napi).filter((name) => !MANUAL.has(name)),
...NODE_ARRAY_TYPES,
]),
].sort();
const block = names
.map(
(name) => `export const ${name} = /* @__PURE__ */ _reexport("${name}");`
)
.join("\n");
const src = await readFile(FILE, "utf8");
const startIdx = src.indexOf(START);
const endIdx = src.indexOf(END);
if (startIdx === -1 || endIdx === -1 || endIdx < startIdx) {
throw new Error(
`Could not find the ${START} ... ${END} markers in ${FILE}`
);
}
const next =
src.slice(0, startIdx + START.length) +
"\n" +
block +
"\n" +
src.slice(endIdx);
const prettierConfig = (await prettier.resolveConfig(FILE)) ?? {};
const formatted = await prettier.format(next, {
...prettierConfig,
filepath: FILE,
});
return { src, formatted, count: names.length, names };
}
const check = process.argv.includes("--check");
const { src, formatted, count, names } = await buildFile();
if (check) {
if (formatted !== src) {
const committed = new Set(
[...src.matchAll(/_reexport\(\s*"([^"]+)"\s*\)/g)].map((m) => m[1])
);
const live = new Set(names);
const onlyNapi = names.filter((name) => !committed.has(name));
const onlyFile = [...committed].filter((name) => !live.has(name)).sort();
console.error(
"❌ js/node-index.js is out of sync with the napi surface.\n" +
" Run `pnpm --filter @miden-sdk/miden-sdk gen:node-reexports` and commit the result."
);
if (onlyNapi.length === 0 && onlyFile.length === 0) {
console.error(
" Class names match; prettier formatted the file differently."
);
} else {
console.error(` napi only: ${onlyNapi.join(", ") || "(none)"}`);
console.error(` file only: ${onlyFile.join(", ") || "(none)"}`);
}
process.exit(1);
}
console.log(
`✓ node-index.js re-exports are up to date (${count} napi classes).`
);
} else {
await writeFile(FILE, formatted);
console.log(`✓ Wrote ${count} napi re-exports into js/node-index.js.`);
}