Skip to content

Commit b4706c1

Browse files
committed
test(metadata-protocol): read spec's export surface without a restricted root namespace import (#8660)
1 parent d8f950e commit b4706c1

1 file changed

Lines changed: 46 additions & 10 deletions

File tree

‎packages/metadata-protocol/src/union-branch-policy.cross-package-parity.test.ts‎

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,6 @@ import { z } from 'zod';
9191
// branch selection to the package-internal policy module #8318 extracted.
9292
import { formatZodIssue } from '@objectstack/spec';
9393
import { zodIssuesToFields } from '@objectstack/spec/api';
94-
import * as SpecRoot from '@objectstack/spec';
95-
import * as SpecApi from '@objectstack/spec/api';
96-
import * as SpecShared from '@objectstack/spec/shared';
9794
// This package's own copy of the ranking, at the surface every producer here
9895
// calls: `saveMetaItem`'s 422 (#5364) and `computeMetadataDiagnostics` (#5598).
9996
import { zodIssuesToMetadataIssues } from './protocol.js';
@@ -267,16 +264,55 @@ describe('#8660 §1 the two sides cannot be sharing an implementation', () => {
267264
'UNION_BRANCH_SELECTION_LIMIT',
268265
] as const;
269266

267+
/**
268+
* Every PUBLIC entry point of `@objectstack/spec` that could plausibly carry
269+
* the policy, loaded dynamically.
270+
*
271+
* ⛔ The natural spelling of the root case — `import * as SpecRoot from
272+
* '@objectstack/spec'` — is refused by this repo's `no-restricted-imports`
273+
* rule, and the refusal is correct rather than an obstacle: a static
274+
* namespace binding on the root keeps all fifteen domain namespaces
275+
* (`Data`, `UI`, `Kernel`, …) reachable, which Node ESM cannot tree-shake,
276+
* and that is the ~1.2GB RSS regression the rule exists to prevent. The
277+
* lint run uses `--no-inline-config`, so there is no per-site opt-out — by
278+
* design.
279+
*
280+
* Loading dynamically is not an evasion dressed up as a fix. This file
281+
* already loads the root module for `formatZodIssue` above, so nothing
282+
* extra is pulled in; what the dynamic form drops is the long-lived
283+
* namespace BINDING the rule targets. {@link policySymbolsReachableFrom}
284+
* reduces each namespace to the handful of names §1 asks about and lets the
285+
* object go, so the assertion below is strictly LESS retentive than the
286+
* static spelling it replaces — while making exactly the same claim about
287+
* exactly the same public surface.
288+
*/
289+
const SPEC_ENTRY_POINTS: ReadonlyArray<readonly [string, () => Promise<object>]> = [
290+
['@objectstack/spec', () => import('@objectstack/spec')],
291+
['@objectstack/spec/api', () => import('@objectstack/spec/api')],
292+
['@objectstack/spec/shared', () => import('@objectstack/spec/shared')],
293+
];
294+
295+
/**
296+
* Which policy symbols one entry point actually exports.
297+
*
298+
* `in` against the module namespace, which is what "publicly reachable"
299+
* means for an ESM consumer — the same test the static spelling ran, on the
300+
* same object, without keeping it.
301+
*/
302+
async function policySymbolsReachableFrom(load: () => Promise<object>): Promise<string[]> {
303+
const mod = (await load()) as Record<string, unknown>;
304+
return POLICY_SYMBOLS.filter((name) => name in mod);
305+
}
306+
270307
// If this goes red, the policy became reachable from outside `packages/spec`
271308
// and the right response is to REWIRE `protocol.ts` onto it — deleting its
272309
// copy — not to keep three copies with a parity test over two of them.
273-
it.each([
274-
['@objectstack/spec', SpecRoot as Record<string, unknown>],
275-
['@objectstack/spec/api', SpecApi as Record<string, unknown>],
276-
['@objectstack/spec/shared', SpecShared as Record<string, unknown>],
277-
])('%s exports none of the policy symbols, so this package must run its own copy', (_entry, mod) => {
278-
expect(POLICY_SYMBOLS.filter((name) => name in mod)).toEqual([]);
279-
});
310+
it.each(SPEC_ENTRY_POINTS)(
311+
'%s exports none of the policy symbols, so this package must run its own copy',
312+
async (_entry, load) => {
313+
expect(await policySymbolsReachableFrom(load)).toEqual([]);
314+
},
315+
);
280316

281317
it('drives the spec side through public surfaces that DO exist', () => {
282318
// The other half of the same claim: the comparison below is not green

0 commit comments

Comments
 (0)