From 68fb6915f16ae9ce449142073b3dd75949f0d61c Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 28 Aug 2026 13:19:04 +0000 Subject: [PATCH] fix(metadata-core, service-cluster): make the ./testing subpaths ESM-only Both packages published ./testing as a dual entry point, but the subpath re-exports vitest and vitest refuses to be loaded from CommonJS by design, so the require condition could never resolve to working code. Drop the condition and delete the two now-stale entries from the shrink-only scripts/dual-build-cjs-loads.baseline.json ledger in the same change. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01UjujZN219uFzBhSYfMykCd --- .../testing-subpath-exports-esm-only.md | 59 +++++++++++++++++++ packages/metadata-core/package.json | 3 +- .../services/service-cluster/package.json | 3 +- scripts/dual-build-cjs-loads.baseline.json | 11 +--- 4 files changed, 62 insertions(+), 14 deletions(-) create mode 100644 .changeset/testing-subpath-exports-esm-only.md diff --git a/.changeset/testing-subpath-exports-esm-only.md b/.changeset/testing-subpath-exports-esm-only.md new file mode 100644 index 0000000000..0f0bc3eda9 --- /dev/null +++ b/.changeset/testing-subpath-exports-esm-only.md @@ -0,0 +1,59 @@ +--- +"@objectstack/metadata-core": minor +"@objectstack/service-cluster": minor +--- + +fix: the `./testing` subpaths are ESM-only — they no longer advertise a `require` condition vitest refuses to serve (#12985) + +Both packages published their test-harness subpath as a dual entry point: + +```jsonc +// FROM — @objectstack/metadata-core and @objectstack/service-cluster +"./testing": { + "types": "./dist/testing.d.ts", + "import": "./dist/testing.js", + "require": "./dist/testing.cjs" +} + +// TO +"./testing": { + "types": "./dist/testing.d.ts", + "import": "./dist/testing.js" +} +``` + +The `require` half was a promise neither package could keep. Both subpaths +re-export `vitest`, and vitest **refuses** to be loaded from CommonJS by +design — its CJS entry is a single `throw`: + +``` +node -e "require('@objectstack/metadata-core/testing')" +Error: Vitest cannot be imported in a CommonJS module using require(). Please use "import" instead. +``` + +The emitted bytes parse; the load fails inside vitest's own entry, for every +consumer and every code path. So the condition could never resolve to working +code, on any release, since it was first declared. It is removed rather than +repaired because the failure is not ours to fix: a test harness has no business +advertising a `require` condition when the test runner it re-exports does not +serve one. + +**Nothing that worked stops working**, and that is why this is not filed as a +breaking removal. A CJS consumer that resolved through the old condition got a +hard `Error` at load; it now gets a resolution error from node instead — a +different message for the same non-working call, and an earlier and clearer +one. The `import` condition, the types and the runtime API are untouched, and +every in-repo consumer already reaches these subpaths through `import` +(`@objectstack/metadata-fs`, `@objectstack/metadata-protocol`, +`@objectstack/rest`, `@objectstack/runtime`, `@objectstack/service-cluster-redis`). + +**If you did spell it as `require`** — `require('@objectstack/metadata-core/testing')` +or `require('@objectstack/service-cluster/testing')` — switch the call to +`await import('@objectstack/metadata-core/testing')`, or move the calling +module to ESM. That is the same change the old condition already forced on +you, one error message earlier. + +`dist/testing.cjs` is still emitted (both packages build every entry in both +formats) and still parsed by `pnpm check:dual-build-cjs-loads`; it is simply no +longer reachable through the manifest. Removing it from the build is a +tsup-config change with its own risks and is not folded in here. diff --git a/packages/metadata-core/package.json b/packages/metadata-core/package.json index bfa5047705..4e61c57b8f 100644 --- a/packages/metadata-core/package.json +++ b/packages/metadata-core/package.json @@ -14,8 +14,7 @@ }, "./testing": { "types": "./dist/testing.d.ts", - "import": "./dist/testing.js", - "require": "./dist/testing.cjs" + "import": "./dist/testing.js" } }, "files": [ diff --git a/packages/services/service-cluster/package.json b/packages/services/service-cluster/package.json index 00b7469ab7..19a40e267b 100644 --- a/packages/services/service-cluster/package.json +++ b/packages/services/service-cluster/package.json @@ -14,8 +14,7 @@ }, "./testing": { "types": "./dist/testing.d.ts", - "import": "./dist/testing.js", - "require": "./dist/testing.cjs" + "import": "./dist/testing.js" } }, "scripts": { diff --git a/scripts/dual-build-cjs-loads.baseline.json b/scripts/dual-build-cjs-loads.baseline.json index 18606b5f2f..46929bddbe 100644 --- a/scripts/dual-build-cjs-loads.baseline.json +++ b/scripts/dual-build-cjs-loads.baseline.json @@ -1,13 +1,4 @@ { "$comment": "Shrink-only, hand-edited. Published `require` entry points that legitimately cannot be require()d, each with the reason. Read by scripts/check-dual-build-cjs-loads.mjs. An entry that starts loading must be DELETED in the same PR that fixes it — the gate reds on a stale exemption. ⛔ A parse failure (SyntaxError in our own emitted bytes) is NEVER ledgerable: the gate ignores an entry here for that class on purpose, because a parse failure is always a fact about what we emitted, never about a dependency. Its steady state is NOT empty — read the reasons, never the count.", - "entries": { - "@objectstack/metadata-core#./testing": { - "reason": "The subpath re-exports vitest, and vitest REFUSES to be loaded from CommonJS by design ('Vitest cannot be imported in a CommonJS module using require(). Please use \"import\" instead.'). The bytes parse; the load fails inside vitest's own entry. Pre-existing and independent of #12971 — the same `require` condition is present at b489d3c725e8, before the import.meta line landed. The real repair is at the manifest (a test-harness subpath has no business advertising a `require` condition), which is a published-exports change and belongs to its own card.", - "diagnostic": "Error: Vitest cannot be imported in a CommonJS module using require()." - }, - "@objectstack/service-cluster#./testing": { - "reason": "Same shape as @objectstack/metadata-core#./testing — a vitest-backed test-harness subpath that declares a `require` condition vitest itself refuses to serve. Bytes parse, load fails inside vitest. Repair is the same manifest-level one and belongs to the same card.", - "diagnostic": "Error: Vitest cannot be imported in a CommonJS module using require()." - } - } + "entries": {} }