Skip to content

Commit 4525eee

Browse files
committed
tooling(verify,cli): resolve the new cross-package imports to SOURCE (#15229)
Both halves are what `check:test-source-alias` and `check:type-source-resolution` prescribe for a dep a change newly reaches; neither registry is widened (both are shrink-only, and widening is never the fix): - `packages/verify/vitest.config.ts` gains its first `resolve.alias` — one ANCHORED entry for `@objectstack/core`, which `artifact-collections.ts` now imports and every test in the package reaches through `derive.ts` / `rls.ts`. Without it those tests resolve core through its `exports` map to `dist/`, i.e. they become verdicts about build state, and the dangerous half of that is a suite that passes GREEN over a stale artifact. - `packages/verify/tsconfig.json` gains the matching `paths` rule, and the `rootDir` widening that pulling core's source into the program requires (`packages/core/tsconfig.json`'s own precedent; emit is unaffected, this package builds with tsup). - `packages/cli/tsconfig.test.json` gains a FOURTH bare-name rule beside the three #15004 added, for the `@objectstack/verify` the probe rows now import. Bare names, no stars: `@objectstack/core` publishes a `./logger` subpath that keeps resolving through its own `exports` map, and a starred rule would swallow it and resolve it THROUGH a file (ENOTDIR). Measured after: `pnpm check:test-source-alias` OK (72 packages scanned), `pnpm check:type-source-resolution` OK (121 programs / 78 packages), `pnpm --filter @objectstack/verify typecheck` and `pnpm --filter @objectstack/cli typecheck` both clean, and the two suites the alias re-resolves stay green: verify 58/58, the option-B pin 6/6. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UHvF5hyiZjnCyExFnfQB8m
1 parent fdc04ea commit 4525eee

3 files changed

Lines changed: 59 additions & 8 deletions

File tree

packages/cli/tsconfig.test.json

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,10 @@
126126
"moduleResolution": "bundler",
127127
"lib": ["ES2022", "DOM", "DOM.Iterable"],
128128
"types": ["node"],
129-
// [#15004] THREE bare-name rules, no star, for the three workspace deps the
130-
// option-B acceptance pin reaches (`test/option-b-reader-acceptance.pin.test.ts`
131-
// and its two fixtures). Without them tsc resolves those specifiers through
129+
// [#15004, #15229] FOUR bare-name rules, no star, for the four workspace
130+
// deps the option-B acceptance pin reaches
131+
// (`test/option-b-reader-acceptance.pin.test.ts` and its two fixtures;
132+
// `@objectstack/verify` joined them with card 5/4's probe rows). Without them tsc resolves those specifiers through
132133
// each package's `exports` map to `dist/index.d.ts` — A BUILD ARTIFACT — so
133134
// this suite's type verdict about the readers the reader program is about to
134135
// CHANGE would be a verdict about the last `pnpm build` instead, which is
@@ -142,8 +143,8 @@
142143
// the specifier EXACTLY, which is load-bearing here rather than incidental:
143144
// `@objectstack/objectql` publishes a second subpath (`./core`), and that
144145
// specifier deliberately keeps resolving through the package's own
145-
// `exports` map, untouched by this table. `plugin-security` and `runtime`
146-
// each publish only `"."`. And a target matching nothing on disk is worse
146+
// `exports` map, untouched by this table. `plugin-security`, `runtime` and
147+
// `verify` each publish only `"."`. And a target matching nothing on disk is worse
147148
// than absent, because tsc then falls back to node resolution — i.e. to
148149
// `dist` — silently.
149150
//
@@ -152,7 +153,8 @@
152153
"paths": {
153154
"@objectstack/objectql": ["../objectql/src/index.ts"],
154155
"@objectstack/plugin-security": ["../plugins/plugin-security/src/index.ts"],
155-
"@objectstack/runtime": ["../runtime/src/index.ts"]
156+
"@objectstack/runtime": ["../runtime/src/index.ts"],
157+
"@objectstack/verify": ["../verify/src/index.ts"]
156158
}
157159
},
158160
"include": ["test/**/*", "vitest.config.ts", "vitest-tiers.ts", "vitest-tiers.fixtures.ts"],

packages/verify/tsconfig.json

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,30 @@
22
"extends": "../../tsconfig.json",
33
"compilerOptions": {
44
"outDir": "./dist",
5-
"rootDir": "./src",
6-
"types": ["node"]
5+
// [#15229] Widened from `./src` as a CONSEQUENCE of the `paths` rule below,
6+
// exactly as `packages/core/tsconfig.json` documents: redirecting
7+
// `@objectstack/core` to its source puts `packages/core/src/**` into this
8+
// program, and `rootDir` is enforced over every program file even under
9+
// `--noEmit`. `..` (= `packages/`) is the directory that contains every
10+
// file in the program. Emit is unaffected: this package builds with tsup.
11+
"rootDir": "..",
12+
"types": ["node"],
13+
// [#15229] `@objectstack/core` is imported as a VALUE by
14+
// `src/artifact-collections.ts` (`resolveArtifactPackageOrder`, the
15+
// ADR-0130 D4+D5 package ordering every reader in this package now resolves
16+
// its collections through). Without this rule its types resolve through the
17+
// workspace link to `dist/*.d.ts` — a build artifact — so this package's
18+
// type verdict would be a function of build state rather than of the source
19+
// in the checkout, which `check:type-source-resolution` refuses (its
20+
// registry is shrink-only; widening it is not the fix).
21+
//
22+
// Bare name, no star: core publishes a second subpath (`./logger`) that
23+
// deliberately keeps resolving through its own `exports` map, and a star
24+
// would swallow it and resolve it THROUGH a file
25+
// (`…/core/src/index.ts/logger`, ENOTDIR). Nothing here imports it.
26+
"paths": {
27+
"@objectstack/core": ["../core/src/index.ts"]
28+
}
729
},
830
"include": ["src/**/*"],
931
"exclude": ["node_modules", "dist", "**/*.spec.ts", "**/*.test.ts"]

packages/verify/vitest.config.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,36 @@
2929
// runner would make every log reading in tests a reading of something other
3030
// than production. The request lives HERE, in the harness, where the test
3131
// author can see it.
32+
// ── Why there is now a `resolve.alias` (#15229) ────────────────────────────
33+
//
34+
// `artifact-collections.ts` reads the app's collections through
35+
// `resolveArtifactPackageOrder` — `@objectstack/core`'s ADR-0130 D4+D5 package
36+
// ordering — and `derive.ts` / `rls.ts` reach it from every test in this
37+
// package. Without an anchored alias that specifier resolves through core's
38+
// `exports` to its **dist**, which makes each of those tests a verdict about
39+
// build state rather than about the source in this checkout, and the dangerous
40+
// half of that is not a loud error but a suite that passes GREEN over a stale
41+
// artifact with nothing in the output saying so.
42+
// `scripts/check-test-source-alias.mjs` names it; that script's registry is
43+
// SHRINK-ONLY, so widening `KNOWN_UNALIASED_TEST_IMPORTS['@objectstack/verify']`
44+
// was never the fix. ANCHORED (`/^…$/`, array form) so the entry cannot swallow
45+
// core's published subpaths and resolve `@objectstack/core/logger` to
46+
// `…/core/src/index.ts/logger` — the ENOTDIR shape that gate's rule 5 exists
47+
// for. The 14 other entries in this package's ledger are real and untouched:
48+
// this adds nothing to it and removes nothing from it.
49+
import path from 'node:path';
50+
import { fileURLToPath } from 'node:url';
51+
3252
import { defineConfig } from 'vitest/config';
3353

54+
const HERE = path.dirname(fileURLToPath(import.meta.url));
55+
3456
export default defineConfig({
57+
resolve: {
58+
alias: [
59+
{ find: /^@objectstack\/core$/, replacement: path.resolve(HERE, '../core/src/index.ts') },
60+
],
61+
},
3562
test: {
3663
// A late console.* must not redden a green suite (#10374): vitest's worker
3764
// forwards console output over RPC and discards the promise, and a write

0 commit comments

Comments
 (0)