diff --git a/bindings/nodejs/.gitignore b/bindings/nodejs/.gitignore index aacfe4ff..74e32af8 100644 --- a/bindings/nodejs/.gitignore +++ b/bindings/nodejs/.gitignore @@ -5,3 +5,4 @@ index.d.ts *.wasm npm/ zen-engine.wasip1* +zen-engine.wasm32-wasip1.* diff --git a/bindings/nodejs/Makefile b/bindings/nodejs/Makefile index 481d9f9b..2b526956 100644 --- a/bindings/nodejs/Makefile +++ b/bindings/nodejs/Makefile @@ -18,7 +18,8 @@ darwinArm: cp zen-engine.darwin-arm64.node npm/darwin-arm64/ prepareLocalPublish: - yarn napi prepublish --skip-optional-publish + rm -f zen-engine.wasm32-wasip1.*.mjs zen-engine.wasm32-wasip1.*.mts + node prepublish.mjs --skip-optional-publish yarn createNpmDirs publish: diff --git a/bindings/nodejs/package.json b/bindings/nodejs/package.json index b7edabac..ff975c7d 100644 --- a/bindings/nodejs/package.json +++ b/bindings/nodejs/package.json @@ -37,7 +37,8 @@ "fs": false, "asyncInit": true }, - "asyncRuntime": true + "asyncRuntime": true, + "optionalDependency": true } }, "keywords": [ @@ -101,7 +102,7 @@ "test:wasm": "cross-env NAPI_RS_FORCE_WASI=error NAPI_RS_WASI_FLAVOR=wasm32-wasip1 __ZEN_MOCK_UTC_TIME=2025-08-19T16:55:02.078Z jest -c jest.wasm.config.js", "artifacts": "napi artifacts -d ../../artifacts", "createNpmDirs": "napi create-npm-dirs && node enrich-npm-dirs.mjs", - "prepublishOnly": "napi prepublish --no-gh-release", + "prepublishOnly": "node prepublish.mjs --no-gh-release", "version": "napi version" }, "resolutions": { diff --git a/bindings/nodejs/prepublish.mjs b/bindings/nodejs/prepublish.mjs new file mode 100644 index 00000000..719127ff --- /dev/null +++ b/bindings/nodejs/prepublish.mjs @@ -0,0 +1,32 @@ +import { spawnSync } from 'node:child_process'; +import { readFileSync, rmSync, writeFileSync } from 'node:fs'; +import { join } from 'node:path'; + +const packageJsonPath = join(import.meta.dirname, 'package.json'); +const readPackageJson = () => JSON.parse(readFileSync(packageJsonPath, 'utf8')); + +const before = readPackageJson(); + +const napi = spawnSync('napi', ['prepublish', ...process.argv.slice(2)], { + cwd: import.meta.dirname, + stdio: 'inherit', + shell: process.platform === 'win32', +}); +if (napi.status !== 0) process.exit(napi.status ?? 1); + +const after = readPackageJson(); +const keptFiles = new Set(before.files ?? []); +const generatedFiles = (after.files ?? []).filter((file) => !keptFiles.has(file)); + +const restoreField = (target, source, key) => { + if (source && Object.prototype.hasOwnProperty.call(source, key)) target[key] = source[key]; + else if (target) delete target[key]; +}; + +restoreField(after, before, 'files'); +restoreField(after, before, 'exports'); +if (after.publishConfig) restoreField(after.publishConfig, before.publishConfig, 'exports'); + +writeFileSync(packageJsonPath, `${JSON.stringify(after, null, 2)}\n`); + +for (const file of generatedFiles) rmSync(join(import.meta.dirname, file), { force: true });