@orkestrel/scaffold 0.0.101 → 0.0.102
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/skills/orkestrel-dispatch/scripts/brief.js +6 -14
- package/dist/agents/skills/orkestrel-dispatch/scripts/cite.js +41 -28
- package/dist/agents/skills/orkestrel-dispatch/scripts/helpers.js +5 -12
- package/dist/agents/skills/orkestrel-dispatch/scripts/launch.js +25 -13
- package/dist/agents/skills/orkestrel-dispatch/scripts/login.js +18 -25
- package/dist/agents/skills/orkestrel-dispatch/scripts/result.js +11 -9
- package/dist/agents/skills/orkestrel-harden/scripts/discovery.js +233 -232
- package/dist/agents/skills/orkestrel-publish/scripts/compare.js +95 -89
- package/dist/agents/skills/orkestrel-publish/scripts/pins.js +5 -7
- package/dist/agents/skills/orkestrel-publish/scripts/swap.js +1273 -0
- package/dist/agents/skills/orkestrel-publish/scripts/wave.js +99 -89
- package/dist/agents/skills/orkestrel-publish/scripts/window.js +54 -52
- package/dist/agents/skills/orkestrel-scout/scripts/map.js +160 -161
- package/dist/bin/main.js +483 -444
- package/dist/bin/main.js.map +1 -1
- package/dist/host/AGENTS.md +1 -0
- package/dist/host/agents/skills/orkestrel-dispatch/SKILL.md +10 -10
- package/dist/host/agents/skills/orkestrel-dispatch/scripts/brief.ts +8 -11
- package/dist/host/agents/skills/orkestrel-dispatch/scripts/cite.ts +58 -28
- package/dist/host/agents/skills/orkestrel-dispatch/scripts/helpers.ts +5 -10
- package/dist/host/agents/skills/orkestrel-dispatch/scripts/launch.ts +31 -12
- package/dist/host/agents/skills/orkestrel-dispatch/scripts/login.ts +28 -23
- package/dist/host/agents/skills/orkestrel-dispatch/scripts/result.ts +12 -10
- package/dist/host/agents/skills/orkestrel-harden/scripts/discovery.ts +318 -237
- package/dist/host/agents/skills/orkestrel-journey/references/statechart.md +2 -5
- package/dist/host/agents/skills/orkestrel-publish/SKILL.md +7 -6
- package/dist/host/agents/skills/orkestrel-publish/references/release.md +12 -10
- package/dist/host/agents/skills/orkestrel-publish/references/wave.md +12 -5
- package/dist/host/agents/skills/orkestrel-publish/scripts/compare.ts +124 -82
- package/dist/host/agents/skills/orkestrel-publish/scripts/pins.ts +5 -7
- package/dist/host/agents/skills/orkestrel-publish/scripts/swap.ts +1655 -0
- package/dist/host/agents/skills/orkestrel-publish/scripts/wave.ts +128 -97
- package/dist/host/agents/skills/orkestrel-publish/scripts/window.ts +70 -55
- package/dist/host/agents/skills/orkestrel-scout/scripts/map.ts +215 -155
- package/dist/host/claude/rules/architecture.md +2 -2
- package/dist/host/claude/rules/tests.md +8 -2
- package/dist/host/claude/rules/typescript.md +130 -0
- package/dist/host/claude/rules/workspace.md +30 -12
- package/dist/host/configs/helpers.ts +206 -133
- package/dist/host/configs/policy.ts +110 -105
- package/dist/host/guides/scaffold.md +244 -170
- package/dist/host/manifest.json +35 -29
- package/dist/host/tests/config.test.ts +1220 -633
- package/dist/host/tests/policy.test.ts +19 -0
- package/dist/host/tests/setupPolicy.ts +1669 -985
- package/dist/src/core/index.cjs +1595 -1686
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +202 -18
- package/dist/src/core/index.d.ts +202 -18
- package/dist/src/core/index.js +1590 -1687
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/server/index.cjs +448 -392
- package/dist/src/server/index.cjs.map +1 -1
- package/dist/src/server/index.d.cts +1182 -1052
- package/dist/src/server/index.d.ts +1182 -1052
- package/dist/src/server/index.js +447 -395
- package/dist/src/server/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -117,11 +117,11 @@ export declare const ARTIFACT_TEMPLATES: Readonly<{
|
|
|
117
117
|
browser: "<!doctype html>\n<html lang=\"en\">\n\t<head>\n\t\t<meta charset=\"UTF-8\" />\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n\t\t<title>Application</title>\n\t</head>\n\t<body>\n\t\t<script type=\"module\" src=\"/main.ts\"></script>\n\t</body>\n</html>\n";
|
|
118
118
|
}>;
|
|
119
119
|
tests: Readonly<{
|
|
120
|
-
journey: "import {\n\tACCESSIBLE_ROLES,\n\tcreatePortfolio,\n\texpandCaptures,\n\tisRendered,\n\treadRefusal,\n\treadStyle,\n} from '@orkestrel/test/browser'\n{{imports}}import { page } from 'vitest/browser'\nimport { describe, expect, inject, it } from 'vitest'\n\nconst VARIANT = inject('variant')\nconst VARIANTS = inject('variants')\nconst CAPTURE = inject('capture')\n\ndescribe('{{application}} arrival journey', () => {\n\tit('proves the declared arrival families', async () => {\n\t\tconst families =
|
|
120
|
+
journey: "import {\n\tACCESSIBLE_ROLES,\n\tcreatePortfolio,\n\texpandCaptures,\n\tisRendered,\n\treadRefusal,\n\treadStyle,\n} from '@orkestrel/test/browser'\n{{imports}}import { page } from 'vitest/browser'\nimport { describe, expect, inject, it } from 'vitest'\n\nconst VARIANT = inject('variant')\nconst VARIANTS = inject('variants')\nconst CAPTURE = inject('capture')\n\ndescribe('{{application}} arrival journey', () => {\n\tit('proves the declared arrival families', async () => {\n\t\tconst families = ['Journey', 'Refusal', 'Matrix', ...(CAPTURE ? ['Capture'] : [])]\n\t\tconst proven: string[] = []\n\t\tconst states = ['{{application}}-arrival']\n\t\tconst placed: string[] = []\n\t\tconst portfolio = createPortfolio({\n\t\t\tstates,\n\t\t\tvariants: VARIANTS,\n\t\t\tvariant: VARIANT,\n\t\t\tdirectory: '../../../tmp/captures/states',\n\t\t\tenabled: CAPTURE,\n\t\t})\n{{mount}}\t\ttry {\n{{arrival}}\t\t\tconst heading = page\n\t\t\t\t.getByRole('heading', {\n\t\t\t\t\tname: {{heading}},\n\t\t\t\t\texact: true,\n\t\t\t\t\tlevel: 1,\n\t\t\t\t})\n\t\t\t\t.element()\n\t\t\texpect(isRendered(heading)).toBe(true)\n\t\t\tproven.push('Journey')\n\t\t\tawait portfolio.place('{{application}}-arrival')\n\t\t\tplaced.push('{{application}}-arrival')\n\n\t\t\tfor (const role of ACCESSIBLE_ROLES) expect(page.getByRole(role).elements()).toEqual([])\n\t\t\texpect(readRefusal('Continue')).toBe(\n\t\t\t\t'No interactive element has the accessible name \"Continue\"',\n\t\t\t)\n\t\t\tproven.push('Refusal')\n\n\t\t\tconst measured: string[] = []\n\t\t\tfor (const variant of VARIANTS) {\n\t\t\t\tawait page.viewport(variant.width, variant.height)\n\t\t\t\texpect(readStyle(heading, 'display')).toBe('block')\n\t\t\t\texpect(window.innerWidth).toBe(variant.width)\n\t\t\t\tmeasured.push(variant.name)\n\t\t\t}\n\t\t\texpect(measured).toEqual(VARIANTS.map(({ name }) => name))\n\t\t\tproven.push('Matrix')\n\n\t\t\tconst files = expandCaptures(states, VARIANTS)\n\t\t\texpect(portfolio.files).toEqual(files)\n\t\t\texpect(new Set(files).size).toBe(states.length * VARIANTS.length)\n\t\t\texpect(placed).toEqual(states)\n\t\t\tconst expected = CAPTURE\n\t\t\t\t? expandCaptures(\n\t\t\t\t\t\tstates,\n\t\t\t\t\t\tVARIANTS.filter(({ name }) => name === VARIANT),\n\t\t\t\t\t)\n\t\t\t\t: []\n\t\t\texpect(portfolio.paths.map((path) => path.replaceAll('\\\\', '/').split('/').at(-1))).toEqual(\n\t\t\t\texpected,\n\t\t\t)\n\t\t\tif (CAPTURE) proven.push('Capture')\n\t\t\texpect(proven).toEqual(families)\n\t\t} finally {\n{{cleanup}}\t\t\tconst variant = VARIANTS.find(({ name }) => name === VARIANT)\n\t\t\tif (variant !== undefined) await page.viewport(variant.width, variant.height)\n\t\t}\n\t})\n})\n";
|
|
121
121
|
browser: "import type { JourneyVariant } from '@orkestrel/test'\n\ndeclare module 'vitest' {\n\texport interface ProvidedContext {\n\t\treadonly variant: string\n\t\treadonly variants: readonly JourneyVariant[]\n\t\treadonly capture: boolean\n\t}\n}\n";
|
|
122
122
|
sheet: "import sheet from '{{root}}dist/src/{{name}}/index.css?raw'\nimport { describe, expect, it } from 'vitest'\nimport { adoptSheet, readLayerNames } from '{{setup}}'\n\ndescribe('{{name}} entry', () => {\n\tit('opens with the declared cascade order', () => {\n\t\tconst adopted = adoptSheet(sheet)\n\t\ttry {\n\t\t\texpect(adopted.sheet.cssRules[0]?.cssText).toBe(\n\t\t\t\t'@layer theme, reset, base, elements, components, utilities;',\n\t\t\t)\n\t\t\texpect(readLayerNames(adopted.sheet).slice(0, 6)).toEqual([\n\t\t\t\t'theme',\n\t\t\t\t'reset',\n\t\t\t\t'base',\n\t\t\t\t'elements',\n\t\t\t\t'components',\n\t\t\t\t'utilities',\n\t\t\t])\n\t\t} finally {\n\t\t\tadopted.release()\n\t\t}\n\t})\n})\n";
|
|
123
123
|
styles: Readonly<{
|
|
124
|
-
module: "/**
|
|
124
|
+
module: "/** Describes an adopted stylesheet and its idempotent release operation. */\nexport interface SheetAdoption {\n\treadonly sheet: CSSStyleSheet\n\trelease(): void\n}\n\n/**\n * Adopts CSS text into the document with an idempotent release operation.\n * @param text - The compiled sheet text.\n * @returns The adopted sheet and its release operation.\n * @example\n * ```ts\n * const adopted = adoptSheet('.sample { color: red }')\n * adopted.release()\n * ```\n */\nexport function adoptSheet(text: string): SheetAdoption {\n\tconst sheet = new CSSStyleSheet()\n\tsheet.replaceSync(text)\n\tdocument.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet]\n\treturn {\n\t\tsheet,\n\t\trelease: () => {\n\t\t\tdocument.adoptedStyleSheets = document.adoptedStyleSheets.filter(\n\t\t\t\t(candidate) => candidate !== sheet,\n\t\t\t)\n\t\t},\n\t}\n}\n\n/**\n * Reads layer statements and blocks in declaration order, including repeated names.\n * @param source - The parsed sheet, or a grouping rule inside it.\n * @param layer - The qualified name of the layer that encloses `source`, when one does.\n * @returns Qualified layer names, with an empty name for an anonymous layer.\n * @example\n * ```ts\n * readLayerNames(new CSSStyleSheet()) // []\n * ```\n */\nexport function readLayerNames(\n\tsource: CSSStyleSheet | CSSGroupingRule,\n\tlayer?: string,\n): readonly string[] {\n\treturn Array.from(source.cssRules).flatMap((rule) => [\n\t\t...(rule instanceof CSSLayerStatementRule\n\t\t\t? rule.nameList\n\t\t\t: rule instanceof CSSLayerBlockRule\n\t\t\t\t? [rule.name]\n\t\t\t\t: []\n\t\t).map((name) => (layer === undefined ? name : layer + '.' + name)),\n\t\t...(rule instanceof CSSGroupingRule\n\t\t\t? readLayerNames(\n\t\t\t\t\trule,\n\t\t\t\t\trule instanceof CSSLayerBlockRule\n\t\t\t\t\t\t? layer === undefined\n\t\t\t\t\t\t\t? rule.name\n\t\t\t\t\t\t\t: layer + '.' + rule.name\n\t\t\t\t\t\t: layer,\n\t\t\t\t)\n\t\t\t: []),\n\t])\n}\n";
|
|
125
125
|
proof: "import type { SheetAdoption } from './setupStyles.js'\nimport { describe, expect, it } from 'vitest'\nimport { adoptSheet, readLayerNames } from './setupStyles.js'\n\ndescribe('CSSOM instruments', () => {\n\tit('adopts and releases only its own sheet, including repeated release', () => {\n\t\tconst previous = [...document.adoptedStyleSheets]\n\t\tconst first: SheetAdoption = adoptSheet('.sample { color: red }')\n\t\ttry {\n\t\t\tconst second = adoptSheet('.other { display: block }')\n\t\t\ttry {\n\t\t\t\texpect(document.adoptedStyleSheets).toEqual([...previous, first.sheet, second.sheet])\n\t\t\t\texpect(first.sheet.cssRules.length).toBe(1)\n\t\t\t\tfirst.release()\n\t\t\t\tfirst.release()\n\t\t\t\texpect(document.adoptedStyleSheets).toEqual([...previous, second.sheet])\n\t\t\t} finally {\n\t\t\t\tsecond.release()\n\t\t\t}\n\t\t} finally {\n\t\t\tfirst.release()\n\t\t}\n\t\texpect(document.adoptedStyleSheets).toEqual(previous)\n\t})\n\n\tit('reads statements, blocks, nested conditions, and anonymous layers in order', () => {\n\t\tconst adopted = adoptSheet(\n\t\t\t'@layer first, second; @layer first { @media all { @layer nested {} } } @layer {}',\n\t\t)\n\t\ttry {\n\t\t\texpect(readLayerNames(adopted.sheet)).toEqual([\n\t\t\t\t'first',\n\t\t\t\t'second',\n\t\t\t\t'first',\n\t\t\t\t'first.nested',\n\t\t\t\t'',\n\t\t\t])\n\t\t} finally {\n\t\t\tadopted.release()\n\t\t}\n\t})\n\n\tit('returns no layer names for an empty sheet or an unlayered rule', () => {\n\t\tconst sheet = new CSSStyleSheet()\n\t\texpect(readLayerNames(sheet)).toEqual([])\n\t\tsheet.replaceSync('.sample { color: red }')\n\t\texpect(readLayerNames(sheet)).toEqual([])\n\t})\n})\n";
|
|
126
126
|
}>;
|
|
127
127
|
setup: "";
|
|
@@ -132,7 +132,7 @@ export declare const ARTIFACT_TEMPLATES: Readonly<{
|
|
|
132
132
|
entry: "import * as entry from {{specifier}}\nimport { describe, expect, it } from 'vitest'\n\ndescribe({{label}}, () => {\n\tit('has no starter exports', () => {\n\t\texpect(Object.keys(entry)).toStrictEqual([])\n\t})\n})\n";
|
|
133
133
|
bin: "import { describe, expect, it } from 'vitest'\n\ndescribe('bin entry', () => {\n\tit('has no starter exports', async () => {\n{{import}}\n\t\texpect(Object.keys(entry)).toStrictEqual([])\n\t})\n})\n";
|
|
134
134
|
distribution: Readonly<{
|
|
135
|
-
proof: "// The artifact a consumer installs, measured rather than described. This workspace\n// is packed and installed into a throwaway consumer, and every following claim is read\n// off that installed tree: the exports map it publishes, the declarations it ships,\n// and the module objects a real runtime hands a consumer. Nothing here names this\n// package, one of its exports, or how many there are, so the proof stays true as\n// the published surface moves.\n{{types}}import type { SpawnSyncReturns } from 'node:child_process'\nimport type { TestContext } from 'vitest'\nimport { spawnSync } from 'node:child_process'\nimport {\n\texistsSync,\n\tmkdirSync,\n\tmkdtempSync,\n\treaddirSync,\n\treadFileSync,\n\trmSync,\n\tstatSync,\n\twriteFileSync,\n} from 'node:fs'\n{{transport}}import { createRequire } from 'node:module'\nimport { tmpdir } from 'node:os'\nimport { dirname, join, resolve } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n{{launcher}}import { afterAll, beforeAll, describe, expect, it } from 'vitest'\n\nconst ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..')\nconst NPM = process.platform === 'win32' ? 'npm.cmd' : 'npm'\n// The compiler this workspace installs, run as a command rather than called in\n// process: the command and its plain-text diagnostics are the same across the\n// compiler majors this toolchain supports, and its in-process API is not. It is\n// resolved from the workspace under proof, so a consumer of the packed artifact is\n// checked by the same compiler that workspace's own `check` script runs.\nconst TSC = createRequire(join(ROOT, 'package.json')).resolve('typescript/bin/tsc')\n// Windows needs a shell to launch a `.cmd`: Node refuses one directly since the\n// batch-argument hardening, and `spawnSync` returns `EINVAL` with a null status\n// rather than an exit code a caller can read. Every following argument is a literal or\n// a path this file built, so the shell has nothing to escape.\nconst SHELL = process.platform === 'win32'\n// `prepublishOnly` runs this proof as `npm run test:distribution -- --mode release`,\n// and the root configuration's project factories carry that mode into this project.\n// Release is the publish gate, so evidence it cannot obtain fails there and skips\n// everywhere else: a gate that passes on missing evidence proves nothing.\nconst RELEASE = import.meta.env.MODE === 'release'\n// The built output directory convention a browser face may publish from. Every\n// selection reads this prefix off the export target and never off the subpath name. A\n// workspace whose only published face is the browser one publishes that face at the\n// root subpath, so a rule keyed on the subpath name drives a browser bundle through\n// Node and the miss is silent.\nconst BROWSER_OUTPUT = './dist/src/browser/'\nconst ABSENT_SUBPATH = '/no-subpath-is-published-under-this-name'\n// A compiler diagnostic that says where it is: the path relative to the directory\n// the compiler ran in, the 1-based line and column, the code, and the message. The\n// diagnostics are the verdict rather than the exit code, which differs between the\n// compiler majors this toolchain supports, so a reported line matching nothing here\n// came from something other than a check of a consumer module.\nconst DIAGNOSTIC_PATTERN = /^(.+?)\\(\\d+,\\d+\\): error TS\\d+: /u\nconst PING = ['ping', '--fetch-retries=0', '--fetch-timeout=5000', '--loglevel=silent']\nconst ESM_DRIVER = 'drive.mjs'\nconst CJS_DRIVER = 'drive.cjs'\nconst CONSUMER_MANIFEST = `{ \"name\": \"distribution-consumer\", \"private\": true, \"type\": \"module\" }\\n`\nconst ESM_DRIVER_SOURCE = `const entry = await import(process.argv[2])\nprocess.stdout.write(JSON.stringify(Object.keys(entry).sort()))\n`\nconst CJS_DRIVER_SOURCE = `const entry = require(process.argv[2])\nprocess.stdout.write(JSON.stringify(Object.keys(entry).sort()))\n`\n\n// The extensions a JavaScript handler loads as modules. Node loads a native addon\n// through its addon handler instead, so that extension is named separately.\nconst MODULE_EXTENSIONS = ['.js', '.mjs', '.cjs']\nconst ADDON_EXTENSION = '.node'\n// The extensions a declaration file carries. A `require` condition declares\n// `.d.cts` and an ESM-only one `.d.mts`, so the `.d.ts` spelling alone does not\n// name them.\nconst DECLARATION_EXTENSIONS = ['.d.ts', '.d.cts', '.d.mts']\ntype Format = 'module' | 'commonjs'\n\n// The Node import target is resolved with the conditions that driver supplies. The\n// CommonJS compile probe is selected from its declaration's format, and its runtime\n// drive loads the same subpath through Node's require resolver. Vite's production\n// client build enables its module and browser conditions.\nconst RUNTIME_CONDITIONS = Object.freeze({\n\tmodule: Object.freeze(['node-addons', 'node', 'import', 'module-sync']),\n\tcommonjs: Object.freeze(['node-addons', 'node', 'require', 'module-sync']),\n\tbrowser: Object.freeze(['module', 'browser', 'production', 'import']),\n})\n// TypeScript's Node resolutions add `node` to the format condition. Its bundler\n// resolution does not, so a browser drive compares against the declaration a bundler\n// consumer reads rather than borrowing the Node declaration.\nconst BUNDLER_CONDITIONS = Object.freeze({\n\tmodule: ['types', 'import'],\n\tcommonjs: ['types', 'require'],\n})\nconst DECLARATION_CONDITIONS = Object.freeze({\n\tmodule: ['types', 'node', 'import'],\n\tcommonjs: ['types', 'node', 'require'],\n\tbrowser: BUNDLER_CONDITIONS.module,\n})\n\ninterface Resolution {\n\treadonly label: string\n\treadonly resolution: string\n\treadonly module: string\n\treadonly conditions: Readonly<Record<Format, readonly string[]>>\n}\n\ninterface TargetResolution {\n\treadonly target: string\n}\n\n// Each compile driver carries the compiler options its scratch project sets and\n// the conditions TypeScript applies for that resolution and importing format. A\n// `require`-only subpath therefore stays in each CommonJS probe that can resolve it.\n// The option values are the spellings the project file takes, so nothing here needs\n// the compiler's own API to name them.\nconst RESOLUTIONS: readonly Resolution[] = [\n\t{\n\t\tlabel: 'node16',\n\t\tresolution: 'node16',\n\t\tmodule: 'node16',\n\t\tconditions: DECLARATION_CONDITIONS,\n\t},\n\t{\n\t\tlabel: 'nodenext',\n\t\tresolution: 'nodenext',\n\t\tmodule: 'nodenext',\n\t\tconditions: DECLARATION_CONDITIONS,\n\t},\n\t{\n\t\tlabel: 'bundler',\n\t\tresolution: 'bundler',\n\t\tmodule: 'esnext',\n\t\tconditions: BUNDLER_CONDITIONS,\n\t},\n]\n\n// The driver a bundled consumer reads declarations under. A browser application\n// compiles through a bundler, so the browser drive answers under this one alone,\n// and naming it here is what keeps that selection tied to the driver it selects.\nconst BROWSER_DRIVER = RESOLUTIONS.find((candidate) => candidate.label === 'bundler')\nif (BROWSER_DRIVER === undefined) throw new Error(\"RESOLUTIONS carries no 'bundler' row\")\n\nconst FORMATS: ReadonlyArray<readonly [extension: string, format: Format]> = [\n\t['ts', 'module'],\n\t['cts', 'commonjs'],\n]\n\n// One published subpath, resolved to what this proof can drive: the specifier a\n// consumer writes, whether the declarations its consumer formats resolve at all,\n// whether the exports map answers the browser condition with a target of its own,\n// whether it answers `import` and `require` at all, and whether the target that\n// `require` answers with is one that a CommonJS consumer loads.\ninterface Entry {\n\treadonly subpath: string\n\treadonly specifier: string\n\treadonly mapping: unknown\n\treadonly declaration: {\n\t\treadonly importable: boolean\n\t\treadonly requirable: boolean\n\t\treadonly browsable: boolean\n\t}\n\treadonly browsable: boolean\n\treadonly importable: boolean\n\treadonly requirable: boolean\n\treadonly loadable: boolean\n}\n\n// The installed tree every claim is read from. Every subpath the exports map names\n// lands in exactly one of `entries`, `undeclared`, and `excluded`, so a subpath this\n// proof cannot drive is reported rather than dropped.\ninterface Stage {\n\treadonly consumer: string\n\treadonly installed: string\n\treadonly archives: readonly string[]\n\treadonly entries: readonly Entry[]\n\treadonly subpaths: readonly string[]\n\treadonly undeclared: readonly string[]\n\treadonly excluded: readonly string[]\n\treadonly targets: readonly string[]\n}\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n\treturn typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction isNames(value: unknown): value is readonly string[] {\n\treturn Array.isArray(value) && value.every((name) => typeof name === 'string')\n}\n\n// A fallback list, which is what Node reads an array in an exports entry as. The\n// narrowing is what the following walkers need: `Array.isArray` widens an `unknown`\n// member to `any`, and an entry read that way is not read at all.\nfunction isList(value: unknown): value is readonly unknown[] {\n\treturn Array.isArray(value)\n}\n\n// Whether a string is a valid package target. Node rejects a target outside the\n// package and a target containing a dot, parent, or node_modules segment during\n// package-target resolution. A later module-resolution failure is not the same\n// thing: an array falls through the former and keeps the latter.\nfunction isPackageTarget(target: string): boolean {\n\tif (!target.startsWith('./')) return false\n\tfor (const segment of target.slice(2).split(/[\\\\/]/u)) {\n\t\tlet decoded = segment\n\t\ttry {\n\t\t\tdecoded = decodeURIComponent(segment)\n\t\t} catch {}\n\t\tconst normalized = decoded.toLowerCase()\n\t\tif (normalized === '.' || normalized === '..' || normalized === 'node_modules') return false\n\t}\n\treturn true\n}\n\nfunction readJson(path: string): unknown {\n\tconst parsed: unknown = JSON.parse(readFileSync(path, 'utf8'))\n\treturn parsed\n}\n\nfunction readManifestName(path: string): string {\n\tconst manifest = readJson(path)\n\tif (!isRecord(manifest) || typeof manifest.name !== 'string') {\n\t\tthrow new Error(`The manifest at ${path} declares no package name`)\n\t}\n\treturn manifest.name\n}\n\nfunction writeFile(path: string, content: string): void {\n\tmkdirSync(dirname(path), { recursive: true })\n\twriteFileSync(path, content)\n}\n\nfunction readOutput(result: SpawnSyncReturns<string>): string {\n\treturn `${result.stdout ?? ''}${result.stderr ?? ''}`.trim()\n}\n\nfunction runNpm(args: readonly string[], cwd: string): SpawnSyncReturns<string> {\n\treturn spawnSync(NPM, [...args], {\n\t\tcwd,\n\t\tencoding: 'utf8',\n\t\tenv: { ...process.env, npm_config_cache: join(readScratch(), 'cache') },\n\t\tshell: SHELL,\n\t\twindowsHide: true,\n\t})\n}\n\nfunction runNode(args: readonly string[], cwd: string): SpawnSyncReturns<string> {\n\treturn spawnSync(process.execPath, [...args], { cwd, encoding: 'utf8', windowsHide: true })\n}\n\n// Node's own condition matching, read in declaration order.\nfunction resolvePackageTarget(\n\tentry: unknown,\n\tconditions: readonly string[],\n): TargetResolution | undefined {\n\tif (typeof entry === 'string') return { target: entry }\n\tif (isList(entry)) {\n\t\tfor (const member of entry) {\n\t\t\tconst resolved = resolvePackageTarget(member, conditions)\n\t\t\tif (resolved !== undefined && isPackageTarget(resolved.target)) return resolved\n\t\t}\n\t\treturn undefined\n\t}\n\tif (!isRecord(entry)) return undefined\n\tfor (const [condition, nested] of Object.entries(entry)) {\n\t\tif (condition !== 'default' && !conditions.includes(condition)) continue\n\t\tconst resolved = resolvePackageTarget(nested, conditions)\n\t\tif (resolved !== undefined) return resolved\n\t}\n\treturn undefined\n}\n\n// A flat entry, a condition-nested entry, and a fallback list all resolve through\n// one walker. An entry may declare `types` beside `default` at its top level\n// rather than inside `import`, so a fixed `entry.import.types` lookup is not\n// equivalent to condition resolution.\nfunction resolveTarget(entry: unknown, conditions: readonly string[]): string | undefined {\n\treturn resolvePackageTarget(entry, conditions)?.target\n}\n\n// Whether a path is a physical file. TypeScript's file-existence check refuses a\n// directory at the same spelling and continues to the outer package scope.\nfunction matchesFile(path: string): boolean {\n\ttry {\n\t\treturn statSync(path).isFile()\n\t} catch {\n\t\treturn false\n\t}\n}\n\n// TypeScript resolves a declaration target by accepting an existing declaration\n// directly or by substituting beside a JavaScript target. A missing target leaves\n// the containing condition or fallback list unresolved, so the walk continues.\nfunction targetToDeclaration(target: string, installed: string): string | undefined {\n\tif (!isPackageTarget(target)) return undefined\n\tlet declaration = target\n\tif (target.endsWith('.cjs')) declaration = `${target.slice(0, -4)}.d.cts`\n\telse if (target.endsWith('.mjs')) declaration = `${target.slice(0, -4)}.d.mts`\n\telse if (target.endsWith('.js')) declaration = `${target.slice(0, -3)}.d.ts`\n\telse if (!isDeclaration(target)) return undefined\n\treturn matchesFile(join(installed, declaration)) ? declaration : undefined\n}\n\n// The declaration TypeScript resolves through one importing format's conditions.\n// Condition objects keep manifest order, and arrays keep fallback order.\nfunction resolveDeclaration(\n\tentry: unknown,\n\tconditions: readonly string[],\n\tinstalled: string,\n): string | undefined {\n\tif (typeof entry === 'string') return targetToDeclaration(entry, installed)\n\tif (isList(entry)) {\n\t\tfor (const member of entry) {\n\t\t\tconst resolved = resolveDeclaration(member, conditions, installed)\n\t\t\tif (resolved !== undefined) return resolved\n\t\t}\n\t\treturn undefined\n\t}\n\tif (!isRecord(entry)) return undefined\n\tfor (const [condition, nested] of Object.entries(entry)) {\n\t\tif (condition !== 'default' && !conditions.includes(condition)) continue\n\t\tconst resolved = resolveDeclaration(nested, conditions, installed)\n\t\tif (resolved !== undefined) return resolved\n\t}\n\treturn undefined\n}\n\n// The nearest package scope that decides a `.d.ts` declaration's module format. A\n// physical nested manifest starts a scope even when it omits `type` or cannot be\n// parsed. A directory at that spelling is not a manifest, so the walk continues.\nfunction readPackageType(installed: string, target: string): unknown {\n\tlet directory = dirname(join(installed, target))\n\twhile (true) {\n\t\tconst path = join(directory, 'package.json')\n\t\tif (matchesFile(path)) {\n\t\t\ttry {\n\t\t\t\tconst manifest = readJson(path)\n\t\t\t\treturn isRecord(manifest) ? manifest.type : undefined\n\t\t\t} catch {\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t}\n\t\tif (directory === installed) return undefined\n\t\tconst parent = dirname(directory)\n\t\tif (parent === directory) return undefined\n\t\tdirectory = parent\n\t}\n}\n\nfunction resolvesBrowser(entry: unknown): boolean {\n\tconst module = resolveTarget(entry, RUNTIME_CONDITIONS.browser)\n\tif (module !== undefined && module.startsWith(BROWSER_OUTPUT)) return true\n\tif (module === undefined) return false\n\tconst imported = resolveTarget(entry, RUNTIME_CONDITIONS.module)\n\tconst required = resolveTarget(entry, RUNTIME_CONDITIONS.commonjs)\n\treturn module !== imported && module !== required\n}\n\n// Whether the target selected by Node's CommonJS conditions is a module require can\n// load. A JavaScript target takes its own nearest package scope. Native addons and\n// extensionless targets have their own CommonJS handlers.\nfunction resolvesCommonJS(entry: unknown, installed: string): boolean {\n\tconst target = resolveTarget(entry, RUNTIME_CONDITIONS.commonjs)\n\tif (target === undefined) return false\n\tconst name = target.slice(target.lastIndexOf('/') + 1)\n\tif (name.endsWith('.cjs')) return true\n\tif (name.endsWith('.mjs')) return false\n\tif (name.endsWith('.node')) return true\n\tif (!name.includes('.')) return true\n\treturn name.endsWith('.js') && readPackageType(installed, target) !== 'module'\n}\n\n// Whether the declaration selected by a typed CommonJS consumer admits that entry.\n// A `.d.cts` declaration admits and a `.d.mts` declaration refuses. A `.d.ts`\n// declaration takes its own nearest package scope.\nfunction declaresCommonJS(entry: unknown, installed: string): boolean {\n\tconst declaration = resolveDeclaration(entry, DECLARATION_CONDITIONS.commonjs, installed)\n\tif (declaration === undefined) return false\n\tif (declaration.endsWith('.d.cts')) return true\n\tif (declaration.endsWith('.d.mts')) return false\n\treturn declaration.endsWith('.d.ts') && readPackageType(installed, declaration) !== 'module'\n}\n\n// Every target an entry names under any condition. A fallback list omits members\n// Node rejects during package-target validation, because no reader can take them.\nfunction collectTargets(entry: unknown): readonly string[] {\n\tif (typeof entry === 'string') return [entry]\n\tif (isList(entry)) return entry.flatMap(collectTargets).filter(isPackageTarget)\n\tif (!isRecord(entry)) return []\n\treturn Object.values(entry).flatMap((nested) => collectTargets(nested))\n}\n\n// Whether a target is a file a runtime loads for its names, which is what a\n// declaration is owed for. The extension on the target's own file name decides it,\n// and a name carrying no extension is code: `require` reads such a file through its\n// JavaScript handler, so an extensionless target loads and publishes names. Node\n// loads `.node` through its native-addon handler. Every other extension is an asset\n// a consumer reads rather than imports — a stylesheet, a WebAssembly binary, the\n// `\"./package.json\"` manifest pointer, and a declaration alike.\n// The cost is an extensionless file published for a reader, such as a `LICENSE`:\n// that target reports undeclared until it is given an extension or a declaration.\nfunction isModule(target: string): boolean {\n\tconst name = target.slice(target.lastIndexOf('/') + 1)\n\tconst dot = name.lastIndexOf('.')\n\tif (name.endsWith(ADDON_EXTENSION)) return true\n\treturn dot === -1 || MODULE_EXTENSIONS.includes(name.slice(dot))\n}\n\n// Whether a resolved target is a declaration rather than the JavaScript a\n// `default` branch answers with when the entry declares no `types` condition.\nfunction isDeclaration(target: string): boolean {\n\treturn DECLARATION_EXTENSIONS.some((extension) => target.endsWith(extension))\n}\n\n// The declarations the Node module, Node CommonJS, and browser drives compare\n// against. Each field uses the conditions of the TypeScript consumer paired with\n// that runtime. A JavaScript target resolves through TypeScript's adjacent\n// declaration substitution rather than standing in for the declaration itself.\nfunction readDeclaration(\n\tentry: unknown,\n\tinstalled: string,\n): {\n\treadonly module: string | undefined\n\treadonly commonjs: string | undefined\n\treadonly browser: string | undefined\n} {\n\treturn {\n\t\tmodule: resolveDeclaration(entry, DECLARATION_CONDITIONS.module, installed),\n\t\tcommonjs: resolveDeclaration(entry, DECLARATION_CONDITIONS.commonjs, installed),\n\t\tbrowser: resolveDeclaration(entry, DECLARATION_CONDITIONS.browser, installed),\n\t}\n}\n\n// The entries one compile driver can resolve under its own conditions.\nfunction selectEntries(entries: readonly Entry[], conditions: readonly string[]): readonly Entry[] {\n\treturn entries.filter(\n\t\t(entry) =>\n\t\t\tresolveTarget(entry.mapping, conditions) !== undefined &&\n\t\t\t(!conditions.includes('require') || entry.loadable),\n\t)\n}\n\n// The compile drivers whose conditions reach one entry under one importing format.\n// A driver that resolves no target for that entry compiles nothing, so a consumer\n// written under it would report a resolution failure this package never made.\nfunction selectDrivers(entry: Entry, format: Format): readonly Resolution[] {\n\treturn RESOLUTIONS.filter(\n\t\t(driver) => selectEntries([entry], driver.conditions[format]).length > 0,\n\t)\n}\n\n// Requirable entries that declare CommonJS support but a typed CommonJS consumer\n// cannot compile against. A default branch resolving under the require condition\n// set makes no CommonJS claim.\nfunction selectUntypable(entries: readonly Entry[], installed: string): readonly Entry[] {\n\treturn entries.filter(\n\t\t(entry) =>\n\t\t\tentry.requirable &&\n\t\t\tisRecord(entry.mapping) &&\n\t\t\tObject.hasOwn(entry.mapping, 'require') &&\n\t\t\t!declaresCommonJS(entry.mapping, installed),\n\t)\n}\n\n// One surface comparison, written as the consumer module that proves it: the\n// installed entry that consumer imports, the file extension fixing its importing\n// format, the names a real runtime published off it, and the driver whose scratch\n// project compiles it.\ninterface Surface {\n\treadonly entry: Entry\n\treadonly extension: string\n\treadonly published: readonly string[]\n\treadonly driver: Resolution\n}\n\n// A scratch project over named consumer modules, written beside them so their own\n// resolution reaches the installed package. Nothing is emitted and no ambient types\n// are pulled in, so what the check reads is the installed declarations alone.\nfunction writeProject(\n\tstage: Stage,\n\tname: string,\n\tdriver: Resolution,\n\tfiles: readonly string[],\n): string {\n\tconst path = join(stage.consumer, `tsconfig.${name}.json`)\n\tconst project = {\n\t\tcompilerOptions: {\n\t\t\tmodule: driver.module,\n\t\t\tmoduleResolution: driver.resolution,\n\t\t\tnoEmit: true,\n\t\t\tskipLibCheck: true,\n\t\t\tstrict: true,\n\t\t\ttarget: 'esnext',\n\t\t\ttypes: [],\n\t\t},\n\t\tfiles: [...files],\n\t}\n\twriteFile(path, `${JSON.stringify(project, undefined, '\\t')}\\n`)\n\treturn path\n}\n\n// The diagnostics the compiler this workspace installs reports for one scratch\n// project. The compiler runs as a command, so nothing here reaches an API that\n// moves between its majors, and the located lines it prints are the verdict rather\n// than the exit code, which moves between them. A line carrying no location, a line\n// naming the scratch project rather than a consumer module, and anything at all on\n// the error stream are faults of this proof rather than of the package under proof,\n// so each is raised where it happens instead of counted against the package.\nfunction checkProject(stage: Stage, project: string): readonly string[] {\n\tconst result = runNode([TSC, '--noEmit', '--pretty', 'false', '-p', project], stage.consumer)\n\tconst refused = `${result.stderr ?? ''}`.trim()\n\tif (refused.length > 0) {\n\t\tthrow new Error(`The consumer compiler wrote ${refused} to its error stream`)\n\t}\n\tconst reported: string[] = []\n\tfor (const line of `${result.stdout ?? ''}`.split(/\\r\\n|\\n/u)) {\n\t\tif (line.trim().length === 0) continue\n\t\tconst last = reported.at(-1)\n\t\t// An elaborated diagnostic prints its detail on indented lines under its own\n\t\t// first line, so each of those joins the diagnostic it elaborates.\n\t\tif (/^\\s/u.test(line) && last !== undefined) {\n\t\t\treported[reported.length - 1] = `${last} ${line.trim()}`\n\t\t\tcontinue\n\t\t}\n\t\tconst located = DIAGNOSTIC_PATTERN.exec(line)?.[1]\n\t\tif (located === undefined) {\n\t\t\tthrow new Error(`The consumer compiler reported ${line}, which names no location`)\n\t\t}\n\t\tif (resolve(stage.consumer, located) === project) {\n\t\t\tthrow new Error(`The scratch project is itself at fault: ${line}`)\n\t\t}\n\t\treported.push(line)\n\t}\n\tif (reported.length === 0 && result.status !== 0) {\n\t\tthrow new Error(`The consumer compiler refused the project: ${readOutput(result)}`)\n\t}\n\treturn reported\n}\n\n// One installed entry's published names checked against its own declarations by\n// the compiler this workspace installs, in the direction each divergence surfaces\n// under. The runtime's key list is written into the consumer as a literal, so the\n// published side comes from a real process and the declared side from the\n// declarations that process's package ships, and the two can disagree. A name the\n// declarations carry and the runtime does not lands on `declared`. A name the\n// runtime carries and the declarations do not, and a name the declarations publish\n// as a type alone, land on `surfaced`: a variable widens into the type\n// `declared` annotates, and only `surfaced` reads the literal's own keys back.\n// Each names the member it is about, so the failure says which export moved.\nfunction checkSurface(stage: Stage, surface: Surface): readonly string[] {\n\tconst slug = surface.entry.subpath.replaceAll(/[^\\w]+/gu, '-')\n\tconst name = `surface.${surface.driver.label}${slug}.${surface.extension}`\n\tconst module = `${name}`\n\tconst keys = surface.published.map((key) => `${JSON.stringify(key)}: true`).join(', ')\n\twriteFile(\n\t\tjoin(stage.consumer, module),\n\t\t`import * as entry from ${JSON.stringify(surface.entry.specifier)}\nconst published = {${keys.length === 0 ? '' : ` ${keys} `}} as const\nconst declared: Record<keyof typeof entry, true> = published\nconst surfaced: Record<keyof typeof published, true> = declared\n`,\n\t)\n\tconst project = writeProject(stage, name, surface.driver, [`./${module}`])\n\treturn checkProject(stage, project).map((line) => `${surface.driver.label}: ${line}`)\n}\n\n// One consumer module importing every installed entry, written where its own\n// resolution finds the installed package.\nfunction writeConsumerProbe(stage: Stage, path: string, specifiers: readonly string[]): void {\n\tconst names: string[] = []\n\tconst bindings: string[] = []\n\tfor (const [index, specifier] of specifiers.entries()) {\n\t\tconst binding = `entry${String(index)}`\n\t\tnames.push(binding)\n\t\tbindings.push(`import * as ${binding} from ${JSON.stringify(specifier)}`)\n\t}\n\tconst source = `${bindings.join('\\n')}\\nexport const surface = [${names.join(', ')}]\\n`\n\twriteFile(join(stage.consumer, path), source)\n}\n\n// The runtime key set a real process reads off one installed entry under one\n// condition. The driver is a file rather than an `--eval` string, so the specifier\n// travels as an argument and nothing needs escaping.\nfunction driveRuntime(stage: Stage, specifier: string, driver: string): readonly string[] {\n\tconst result = runNode([join(stage.consumer, driver), specifier], stage.consumer)\n\tif (result.status !== 0) {\n\t\tthrow new Error(`Loading ${specifier} from the consumer failed: ${readOutput(result)}`)\n\t}\n\tconst published: unknown = JSON.parse(result.stdout)\n\tif (!isNames(published)) throw new Error(`The driver printed no name list for ${specifier}`)\n\treturn published\n}\n{{helpers}}\n// Pack this workspace, install the archive into an isolated consumer, and read the\n// published surface back off the installed tree. Every later claim reads this\n// result, so a failure here is raised where it happens rather than once per entry.\nfunction buildStage(): Stage {\n\tconst packed = join(readScratch(), 'packed')\n\tconst consumer = join(readScratch(), 'consumer')\n\tmkdirSync(packed, { recursive: true })\n\tconst pack = runNpm(['pack', '--ignore-scripts', '--pack-destination', packed], ROOT)\n\tif (pack.status !== 0) throw new Error(`npm pack refused this workspace: ${readOutput(pack)}`)\n\tconst archives = readdirSync(packed).filter((name) => name.endsWith('.tgz'))\n\tconst archive = archives[0]\n\tif (archives.length !== 1 || archive === undefined) {\n\t\tthrow new Error(`npm pack wrote no single archive: ${archives.join(', ')}`)\n\t}\n\twriteFile(join(consumer, 'package.json'), CONSUMER_MANIFEST)\n\twriteFile(join(consumer, ESM_DRIVER), ESM_DRIVER_SOURCE)\n\twriteFile(join(consumer, CJS_DRIVER), CJS_DRIVER_SOURCE)\n\tconst install = runNpm(\n\t\t['install', '--ignore-scripts', '--no-audit', '--no-fund', join(packed, archive)],\n\t\tconsumer,\n\t)\n\tif (install.status !== 0) {\n\t\tthrow new Error(`Installing the packed archive failed: ${readOutput(install)}`)\n\t}\n\tconst name = readManifestName(join(ROOT, 'package.json'))\n\tconst installed = join(consumer, 'node_modules', ...name.split('/'))\n\tconst manifest = readJson(join(installed, 'package.json'))\n\tif (!isRecord(manifest) || !isRecord(manifest.exports)) {\n\t\tthrow new Error('The installed manifest publishes no exports map')\n\t}\n\tconst entries: Entry[] = []\n\tconst targets: string[] = []\n\tconst subpaths: string[] = []\n\tconst undeclared: string[] = []\n\tconst excluded: string[] = []\n\tfor (const [subpath, entry] of Object.entries(manifest.exports)) {\n\t\tconst files = collectTargets(entry)\n\t\ttargets.push(...files)\n\t\tsubpaths.push(subpath)\n\t\tconst declaration = readDeclaration(entry, installed)\n\t\t// A subpath resolving no declaration is partitioned rather than dropped. It is a\n\t\t// defect when a runtime loads one of its targets for names, because a consumer\n\t\t// importing it compiles against nothing under `node16`. It is an excluded\n\t\t// publication otherwise: the `\"./package.json\"` manifest pointer and a stylesheet\n\t\t// are published for a reader rather than an importer.\n\t\tif (\n\t\t\tdeclaration.module === undefined &&\n\t\t\tdeclaration.commonjs === undefined &&\n\t\t\tdeclaration.browser === undefined\n\t\t) {\n\t\t\tif (files.some(isModule)) undeclared.push(subpath)\n\t\t\telse excluded.push(subpath)\n\t\t\tcontinue\n\t\t}\n\t\tconst importTarget = resolveTarget(entry, RUNTIME_CONDITIONS.module)\n\t\tconst requireTarget = resolveTarget(entry, RUNTIME_CONDITIONS.commonjs)\n\t\tconst browserTarget = resolveTarget(entry, RUNTIME_CONDITIONS.browser)\n\t\tconst browsable = resolvesBrowser(entry)\n\t\tconst shadowed = browsable && requireTarget === browserTarget\n\t\tconst requirable = requireTarget !== undefined && !shadowed\n\t\tconst loadable = requirable && resolvesCommonJS(entry, installed)\n\t\tentries.push({\n\t\t\tsubpath,\n\t\t\tspecifier: subpath === '.' ? name : `${name}${subpath.slice(1)}`,\n\t\t\tmapping: entry,\n\t\t\tdeclaration: {\n\t\t\t\timportable: declaration.module !== undefined,\n\t\t\t\trequirable: declaration.commonjs !== undefined,\n\t\t\t\tbrowsable: declaration.browser !== undefined,\n\t\t\t},\n\t\t\tbrowsable,\n\t\t\timportable: importTarget !== undefined && !(browsable && importTarget === browserTarget),\n\t\t\trequirable,\n\t\t\tloadable,\n\t\t})\n\t}\n\treturn { consumer, installed, archives, entries, subpaths, undeclared, excluded, targets }\n}\n\nlet scratch: string | undefined\nlet staged: Stage | undefined\n\nfunction readScratch(): string {\n\tif (scratch === undefined) {\n\t\tthrow new Error('The distribution setup has not allocated its scratch directory')\n\t}\n\treturn scratch\n}\n\nbeforeAll(() => {\n\tscratch = mkdtempSync(join(tmpdir(), 'distribution-'))\n\tmkdirSync(join(scratch, 'cache'), { recursive: true })\n\tstaged = openStage()\n})\n\nafterAll(() => {\n\tif (scratch !== undefined) {\n\t\trmSync(scratch, { force: true, recursive: true, maxRetries: 3, retryDelay: 100 })\n\t}\n})\n\n// Installing the packed archive resolves its own runtime dependencies, so an\n// unreachable registry leaves nothing to measure. Under release that is the gate\n// failing; anywhere else the suite skips and names the mechanism it wanted.\nfunction openStage(): Stage | undefined {\n\ttry {\n\t\tif (runNpm(PING, ROOT).status !== 0) {\n\t\t\tif (!RELEASE) return undefined\n\t\t\tthrow new Error(\n\t\t\t\t'The release gate requires a reachable npm registry, and npm ping did not answer',\n\t\t\t)\n\t\t}\n\t\treturn buildStage()\n\t} catch (error) {\n\t\trmSync(readScratch(), { force: true, recursive: true, maxRetries: 3, retryDelay: 100 })\n\t\tthrow error\n\t}\n}\n\ndescribe('distribution classifiers', () => {\n\tit('classifies synthetic export mappings without a registry stage', () => {\n\t\tconst root = join(readScratch(), 'classifiers')\n\t\twriteFile(\n\t\t\tjoin(root, 'package.json'),\n\t\t\tJSON.stringify({\n\t\t\t\ttype: 'commonjs',\n\t\t\t\texports: {\n\t\t\t\t\tcondition: { browser: './b.js', default: './n.js' },\n\t\t\t\t\tconvention: { default: './dist/src/browser/index.js' },\n\t\t\t\t\tuniversal: { default: './shared.js' },\n\t\t\t\t\t'import-shared': {\n\t\t\t\t\t\tbrowser: './shared.mjs',\n\t\t\t\t\t\timport: './shared.mjs',\n\t\t\t\t\t\tdefault: './node.js',\n\t\t\t\t\t},\n\t\t\t\t\t'require-shared': {\n\t\t\t\t\t\tbrowser: './shared.cjs',\n\t\t\t\t\t\trequire: './shared.cjs',\n\t\t\t\t\t\tdefault: './node.js',\n\t\t\t\t\t},\n\t\t\t\t\tnode: { node: './node.js', default: './node.js' },\n\t\t\t\t\tsilent: { 'module-sync': './x.cjs', import: './x.mjs' },\n\t\t\t\t\tmodule: { require: './x.mjs' },\n\t\t\t\t\t'nested-module': { require: './module/x.js' },\n\t\t\t\t\t'nested-commonjs': { require: './commonjs/x.js' },\n\t\t\t\t\tesm: { import: './x.mjs' },\n\t\t\t\t},\n\t\t\t}),\n\t\t)\n\t\twriteFile(join(root, 'module/package.json'), '{ \"type\": \"module\" }\\n')\n\t\twriteFile(join(root, 'commonjs/package.json'), '{ \"type\": \"commonjs\" }\\n')\n\t\tconst manifest = readJson(join(root, 'package.json'))\n\t\tif (!isRecord(manifest) || !isRecord(manifest.exports)) {\n\t\t\tthrow new Error('The classifier fixture declares no exports map')\n\t\t}\n\t\tconst mappings = manifest.exports\n\t\texpect({\n\t\t\tcondition: resolvesBrowser(mappings.condition),\n\t\t\tconvention: resolvesBrowser(mappings.convention),\n\t\t\tuniversal: resolvesBrowser(mappings.universal),\n\t\t\timport: resolvesBrowser(mappings['import-shared']),\n\t\t\trequire: resolvesBrowser(mappings['require-shared']),\n\t\t\tnode: resolvesBrowser(mappings.node),\n\t\t}).toStrictEqual({\n\t\t\tcondition: true,\n\t\t\tconvention: true,\n\t\t\tuniversal: false,\n\t\t\timport: false,\n\t\t\trequire: false,\n\t\t\tnode: false,\n\t\t})\n\t\texpect({\n\t\t\tsilent: resolvesCommonJS(mappings.silent, root),\n\t\t\tmodule: resolvesCommonJS(mappings.module, root),\n\t\t\tnestedModule: resolvesCommonJS(mappings['nested-module'], root),\n\t\t\tnestedCommonJS: resolvesCommonJS(mappings['nested-commonjs'], root),\n\t\t\tesm: resolvesCommonJS(mappings.esm, root),\n\t\t}).toStrictEqual({\n\t\t\tsilent: true,\n\t\t\tmodule: false,\n\t\t\tnestedModule: false,\n\t\t\tnestedCommonJS: true,\n\t\t\tesm: false,\n\t\t})\n\t})\n})\n\n// The staged consumer, or a skip naming what the run could not reach. `it.skipIf`\n// carries no reason, so the gate sits here where the test context can state one.\nfunction requireStage(context: TestContext): Stage {\n\tif (staged === undefined) {\n\t\treturn context.skip('`npm ping` did not answer, so nothing was packed or installed')\n\t}\n\treturn staged\n}\n\ndescribe('installed package consumer', () => {\n\tit('packs one archive and installs it in isolation [requires the registry]', (context) => {\n\t\tconst stage = requireStage(context)\n\t\texpect(stage.archives).toHaveLength(1)\n\t\texpect(existsSync(join(stage.installed, 'package.json'))).toBe(true)\n\t\texpect(stage.entries.length).toBeGreaterThan(0)\n\t})\n\n\tit('ships every relative target its exports map names [requires the registry]', (context) => {\n\t\tconst stage = requireStage(context)\n\t\tconst relative = stage.targets.filter((target) => target.startsWith('./'))\n\t\texpect(relative).not.toStrictEqual([])\n\t\texpect(relative.filter((target) => !existsSync(join(stage.installed, target)))).toStrictEqual(\n\t\t\t[],\n\t\t)\n\t})\n\n\t// Every published subpath is driven, excluded by name, or reported here. A dropped\n\t// one leaves no trace: no runtime test, no declaration comparison, and no place in\n\t// the resolution compile, so the run reports success for a subpath it never\n\t// measured.\n\tit('declares types for every module it publishes [requires the registry]', (context) => {\n\t\tconst stage = requireStage(context)\n\t\tconst partitioned = [\n\t\t\t...stage.entries.map((entry) => entry.subpath),\n\t\t\t...stage.undeclared,\n\t\t\t...stage.excluded,\n\t\t]\n\t\texpect(stage.undeclared).toStrictEqual([])\n\t\texpect(partitioned.sort()).toStrictEqual([...stage.subpaths].sort())\n\t\t// A driven subpath answers a runtime condition. One resolving a declaration and\n\t\t// no Node or browser target compiles for a consumer and throws when that consumer\n\t\t// loads it. Each later drive retires itself for that entry, so this assertion names\n\t\t// the subpath rather than counting it as driven.\n\t\tconst unreachable = stage.entries.filter(\n\t\t\t(entry) => !entry.importable && !entry.requirable && !entry.browsable,\n\t\t)\n\t\texpect(unreachable.map((entry) => entry.subpath)).toStrictEqual([])\n\t\tconst untypable = selectUntypable(stage.entries, stage.installed)\n\t\texpect(untypable.map((entry) => entry.subpath)).toStrictEqual([])\n\t})\n\n\tit('refuses a subpath its exports map does not name [requires the registry]', (context) => {\n\t\tconst stage = requireStage(context)\n\t\tconst name = readManifestName(join(stage.installed, 'package.json'))\n\t\tconst driver = join(stage.consumer, ESM_DRIVER)\n\t\tconst result = runNode([driver, `${name}${ABSENT_SUBPATH}`], stage.consumer)\n\t\texpect(result.status).not.toBe(0)\n\t\texpect(readOutput(result)).toContain('ERR_PACKAGE_PATH_NOT_EXPORTED')\n\t})\n\n\t// The absent subpath is the firing control: a resolution that reports nothing\n\t// for every published entry has not been shown to resolve anything at all. Each\n\t// module format carries its own control, because a format that resolves nothing\n\t// is silent for the same reason a resolution that resolves nothing is.\n\tit('compiles a consumer under every module resolution [requires the registry]', (context) => {\n\t\tconst stage = requireStage(context)\n\t\tconst name = readManifestName(join(stage.installed, 'package.json'))\n\t\tconst reported: string[] = []\n\t\tconst silent: string[] = []\n\t\tfor (const driver of RESOLUTIONS) {\n\t\t\tfor (const [extension, format] of FORMATS) {\n\t\t\t\tconst written = selectEntries(stage.entries, driver.conditions[format])\n\t\t\t\tif (written.length === 0) continue\n\t\t\t\tconst label = `${driver.label}.${extension}`\n\t\t\t\tconst probe = `probe.${label}`\n\t\t\t\tconst specifiers = written.map((entry) => entry.specifier)\n\t\t\t\twriteConsumerProbe(stage, probe, specifiers)\n\t\t\t\tconst project = writeProject(stage, probe, driver, [`./${probe}`])\n\t\t\t\tfor (const message of checkProject(stage, project)) {\n\t\t\t\t\treported.push(`${label}: ${message}`)\n\t\t\t\t}\n\t\t\t\tconst control = `control.${label}`\n\t\t\t\twriteConsumerProbe(stage, control, [`${name}${ABSENT_SUBPATH}`])\n\t\t\t\tconst refused = writeProject(stage, control, driver, [`./${control}`])\n\t\t\t\tif (checkProject(stage, refused).length === 0) silent.push(label)\n\t\t\t}\n\t\t}\n\t\texpect(reported).toStrictEqual([])\n\t\texpect(silent).toStrictEqual([])\n\t})\n{{guard}}})\n\ndescribe('installed entries', () => {\n\tit('publishes what it declares to a Node import, and no more', (context) => {\n\t\tconst stage = requireStage(context)\n\t\tconst entries = stage.entries.filter((entry) => entry.importable)\n\t\tif (entries.length === 0) return context.skip('No installed entry supports Node import')\n\t\tfor (const entry of entries) {\n\t\t\tif (!entry.declaration.importable) {\n\t\t\t\tthrow new Error(`${entry.subpath} publishes no import declaration`)\n\t\t\t}\n\t\t\tconst published = driveRuntime(stage, entry.specifier, ESM_DRIVER)\n\t\t\tconst drivers = selectDrivers(entry, 'module')\n\t\t\texpect(drivers).not.toStrictEqual([])\n\t\t\tconst reported = drivers.flatMap((driver) =>\n\t\t\t\tcheckSurface(stage, { entry, extension: 'ts', published, driver }),\n\t\t\t)\n\t\t\texpect(reported).toStrictEqual([])\n\t\t}\n\t})\n\n\tit('publishes what it declares to a Node require, and no more', (context) => {\n\t\tconst stage = requireStage(context)\n\t\tconst entries = stage.entries.filter((entry) => entry.requirable)\n\t\tif (entries.length === 0) return context.skip('No installed entry supports Node require')\n\t\tfor (const entry of entries) {\n\t\t\tif (!entry.declaration.requirable) {\n\t\t\t\tthrow new Error(`${entry.subpath} publishes no require declaration`)\n\t\t\t}\n\t\t\tconst published = driveRuntime(stage, entry.specifier, CJS_DRIVER)\n\t\t\tconst drivers = selectDrivers(entry, 'commonjs')\n\t\t\texpect(drivers).not.toStrictEqual([])\n\t\t\tconst reported = drivers.flatMap((driver) =>\n\t\t\t\tcheckSurface(stage, { entry, extension: 'cts', published, driver }),\n\t\t\t)\n\t\t\texpect(reported).toStrictEqual([])\n\t\t}\n\t})\n{{drive}}})\n";
|
|
135
|
+
proof: "// The artifact a consumer installs, measured rather than described. This workspace\n// is packed and installed into a throwaway consumer, and every following claim is read\n// off that installed tree: the exports map it publishes, the declarations it ships,\n// and the module objects a real runtime hands a consumer. Nothing here names this\n// package, one of its exports, or how many there are, so the proof stays true as\n// the published surface moves.\n{{types}}import type { SpawnSyncReturns } from 'node:child_process'\nimport type { TestContext } from 'vitest'\nimport { spawnSync } from 'node:child_process'\nimport {\n\texistsSync,\n\tmkdirSync,\n\tmkdtempSync,\n\treaddirSync,\n\treadFileSync,\n\trmSync,\n\tstatSync,\n\twriteFileSync,\n} from 'node:fs'\n{{transport}}import { createRequire } from 'node:module'\nimport { tmpdir } from 'node:os'\nimport { dirname, join, resolve } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n{{launcher}}import { afterAll, beforeAll, describe, expect, it } from 'vitest'\n\nconst ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..')\nconst NPM = process.platform === 'win32' ? 'npm.cmd' : 'npm'\n// The compiler this workspace installs, run as a command rather than called in\n// process: the command and its plain-text diagnostics are the same across the\n// compiler majors this toolchain supports, and its in-process API is not. It is\n// resolved from the workspace under proof, so a consumer of the packed artifact is\n// checked by the same compiler that workspace's own `check` script runs.\nconst TSC = createRequire(join(ROOT, 'package.json')).resolve('typescript/bin/tsc')\n// Windows needs a shell to launch a `.cmd`: Node refuses one directly since the\n// batch-argument hardening, and `spawnSync` returns `EINVAL` with a null status\n// rather than an exit code a caller can read. Every following argument is a literal or\n// a path this file built, so the shell has nothing to escape.\nconst SHELL = process.platform === 'win32'\n// `prepublishOnly` runs this proof as `npm run test:distribution -- --mode release`,\n// and the root configuration's project factories carry that mode into this project.\n// Release is the publish gate, so evidence it cannot obtain fails there and skips\n// everywhere else: a gate that passes on missing evidence proves nothing.\nconst RELEASE = import.meta.env.MODE === 'release'\n// The built output directory convention a browser face may publish from. Every\n// selection reads this prefix off the export target and never off the subpath name. A\n// workspace whose only published face is the browser one publishes that face at the\n// root subpath, so a rule keyed on the subpath name drives a browser bundle through\n// Node and the miss is silent.\nconst BROWSER_OUTPUT = './dist/src/browser/'\nconst ABSENT_SUBPATH = '/no-subpath-is-published-under-this-name'\n// A compiler diagnostic that says where it is: the path relative to the directory\n// the compiler ran in, the 1-based line and column, the code, and the message. The\n// diagnostics are the verdict rather than the exit code, which differs between the\n// compiler majors this toolchain supports, so a reported line matching nothing here\n// came from something other than a check of a consumer module.\nconst DIAGNOSTIC_PATTERN = /^(.+?)\\(\\d+,\\d+\\): error TS\\d+: /u\nconst PING = ['ping', '--fetch-retries=0', '--fetch-timeout=5000', '--loglevel=silent']\nconst ESM_DRIVER = 'drive.mjs'\nconst CJS_DRIVER = 'drive.cjs'\nconst CONSUMER_MANIFEST = `{ \"name\": \"distribution-consumer\", \"private\": true, \"type\": \"module\" }\\n`\nconst ESM_DRIVER_SOURCE = `const entry = await import(process.argv[2])\nprocess.stdout.write(JSON.stringify(Object.keys(entry).sort()))\n`\nconst CJS_DRIVER_SOURCE = `const entry = require(process.argv[2])\nprocess.stdout.write(JSON.stringify(Object.keys(entry).sort()))\n`\n\n// The extensions a JavaScript handler loads as modules. Node loads a native addon\n// through its addon handler instead, so that extension is named separately.\nconst MODULE_EXTENSIONS = ['.js', '.mjs', '.cjs']\nconst ADDON_EXTENSION = '.node'\n// The extensions a declaration file carries. A `require` condition declares\n// `.d.cts` and an ESM-only one `.d.mts`, so the `.d.ts` spelling alone does not\n// name them.\nconst DECLARATION_EXTENSIONS = ['.d.ts', '.d.cts', '.d.mts']\ntype Format = 'module' | 'commonjs'\n\n// The Node import target is resolved with the conditions that driver supplies. The\n// CommonJS compile probe is selected from its declaration's format, and its runtime\n// drive loads the same subpath through Node's require resolver. Vite's production\n// client build enables its module and browser conditions.\nconst RUNTIME_CONDITIONS = Object.freeze({\n\tmodule: Object.freeze(['node-addons', 'node', 'import', 'module-sync']),\n\tcommonjs: Object.freeze(['node-addons', 'node', 'require', 'module-sync']),\n\tbrowser: Object.freeze(['module', 'browser', 'production', 'import']),\n})\n// TypeScript's Node resolutions add `node` to the format condition. Its bundler\n// resolution does not, so a browser drive compares against the declaration a bundler\n// consumer reads rather than borrowing the Node declaration.\nconst BUNDLER_CONDITIONS = Object.freeze({\n\tmodule: ['types', 'import'],\n\tcommonjs: ['types', 'require'],\n})\nconst DECLARATION_CONDITIONS = Object.freeze({\n\tmodule: ['types', 'node', 'import'],\n\tcommonjs: ['types', 'node', 'require'],\n\tbrowser: BUNDLER_CONDITIONS.module,\n})\n\ninterface Resolution {\n\treadonly label: string\n\treadonly resolution: string\n\treadonly module: string\n\treadonly conditions: Readonly<Record<Format, readonly string[]>>\n}\n\ninterface TargetResolution {\n\treadonly target: string\n}\n\n// Each compile driver carries the compiler options its scratch project sets and\n// the conditions TypeScript applies for that resolution and importing format. A\n// `require`-only subpath therefore stays in each CommonJS probe that can resolve it.\n// The option values are the spellings the project file takes, so nothing here needs\n// the compiler's own API to name them.\nconst RESOLUTIONS: readonly Resolution[] = [\n\t{\n\t\tlabel: 'node16',\n\t\tresolution: 'node16',\n\t\tmodule: 'node16',\n\t\tconditions: DECLARATION_CONDITIONS,\n\t},\n\t{\n\t\tlabel: 'nodenext',\n\t\tresolution: 'nodenext',\n\t\tmodule: 'nodenext',\n\t\tconditions: DECLARATION_CONDITIONS,\n\t},\n\t{\n\t\tlabel: 'bundler',\n\t\tresolution: 'bundler',\n\t\tmodule: 'esnext',\n\t\tconditions: BUNDLER_CONDITIONS,\n\t},\n]\n\n// The driver a bundled consumer reads declarations under. A browser application\n// compiles through a bundler, so the browser drive answers under this one alone,\n// and naming it here is what keeps that selection tied to the driver it selects.\nconst BROWSER_DRIVER = RESOLUTIONS.find((candidate) => candidate.label === 'bundler')\nif (BROWSER_DRIVER === undefined) throw new Error(\"RESOLUTIONS carries no 'bundler' row\")\n\nconst FORMATS: ReadonlyArray<readonly [extension: string, format: Format]> = [\n\t['ts', 'module'],\n\t['cts', 'commonjs'],\n]\n\n// One published subpath, resolved to what this proof can drive: the specifier a\n// consumer writes, whether the declarations its consumer formats resolve at all,\n// whether the exports map answers the browser condition with a target of its own,\n// whether it answers `import` and `require` at all, and whether the target that\n// `require` answers with is one that a CommonJS consumer loads.\ninterface Entry {\n\treadonly subpath: string\n\treadonly specifier: string\n\treadonly mapping: unknown\n\treadonly declaration: {\n\t\treadonly importable: boolean\n\t\treadonly requirable: boolean\n\t\treadonly browsable: boolean\n\t}\n\treadonly browsable: boolean\n\treadonly importable: boolean\n\treadonly requirable: boolean\n\treadonly loadable: boolean\n}\n\n// The installed tree every claim is read from. Every subpath the exports map names\n// lands in exactly one of `entries`, `undeclared`, and `excluded`, so a subpath this\n// proof cannot drive is reported rather than dropped.\ninterface Stage {\n\treadonly consumer: string\n\treadonly installed: string\n\treadonly archives: readonly string[]\n\treadonly entries: readonly Entry[]\n\treadonly subpaths: readonly string[]\n\treadonly undeclared: readonly string[]\n\treadonly excluded: readonly string[]\n\treadonly targets: readonly string[]\n}\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n\treturn typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction isNames(value: unknown): value is readonly string[] {\n\treturn Array.isArray(value) && value.every((name) => typeof name === 'string')\n}\n\n// A fallback list, which is what Node reads an array in an exports entry as. The\n// narrowing is what the following walkers need: `Array.isArray` widens an `unknown`\n// member to `any`, and an entry read that way is not read at all.\nfunction isList(value: unknown): value is readonly unknown[] {\n\treturn Array.isArray(value)\n}\n\n// Whether a string is a valid package target. Node rejects a target outside the\n// package and a target containing a dot, parent, or node_modules segment during\n// package-target resolution. A later module-resolution failure is not the same\n// thing: an array falls through the former and keeps the latter.\nfunction isPackageTarget(target: string): boolean {\n\tif (!target.startsWith('./')) return false\n\tconst refused = ['.', '..', 'node_modules']\n\treturn target\n\t\t.slice(2)\n\t\t.split(/[\\\\/]/u)\n\t\t.every((segment) => {\n\t\t\ttry {\n\t\t\t\treturn !refused.includes(decodeURIComponent(segment).toLowerCase())\n\t\t\t} catch {\n\t\t\t\treturn !refused.includes(segment.toLowerCase())\n\t\t\t}\n\t\t})\n}\n\nfunction readJson(path: string): unknown {\n\tconst parsed: unknown = JSON.parse(readFileSync(path, 'utf8'))\n\treturn parsed\n}\n\nfunction readManifestName(path: string): string {\n\tconst manifest = readJson(path)\n\tif (!isRecord(manifest) || typeof manifest.name !== 'string') {\n\t\tthrow new Error(`The manifest at ${path} declares no package name`)\n\t}\n\treturn manifest.name\n}\n\nfunction writeFile(path: string, content: string): void {\n\tmkdirSync(dirname(path), { recursive: true })\n\twriteFileSync(path, content)\n}\n\nfunction readOutput(result: SpawnSyncReturns<string>): string {\n\treturn `${result.stdout ?? ''}${result.stderr ?? ''}`.trim()\n}\n\nfunction runNpm(args: readonly string[], cwd: string, scratch: string): SpawnSyncReturns<string> {\n\treturn spawnSync(NPM, [...args], {\n\t\tcwd,\n\t\tencoding: 'utf8',\n\t\tenv: { ...process.env, npm_config_cache: join(scratch, 'cache') },\n\t\tshell: SHELL,\n\t\twindowsHide: true,\n\t})\n}\n\nfunction runNode(args: readonly string[], cwd: string): SpawnSyncReturns<string> {\n\treturn spawnSync(process.execPath, [...args], { cwd, encoding: 'utf8', windowsHide: true })\n}\n\n// Node's own condition matching, read in declaration order.\nfunction resolvePackageTarget(\n\tentry: unknown,\n\tconditions: readonly string[],\n): TargetResolution | undefined {\n\tif (typeof entry === 'string') return { target: entry }\n\tif (isList(entry)) {\n\t\tfor (const member of entry) {\n\t\t\tconst resolved = resolvePackageTarget(member, conditions)\n\t\t\tif (resolved !== undefined && isPackageTarget(resolved.target)) return resolved\n\t\t}\n\t\treturn undefined\n\t}\n\tif (!isRecord(entry)) return undefined\n\tfor (const [condition, nested] of Object.entries(entry)) {\n\t\tif (condition !== 'default' && !conditions.includes(condition)) continue\n\t\tconst resolved = resolvePackageTarget(nested, conditions)\n\t\tif (resolved !== undefined) return resolved\n\t}\n\treturn undefined\n}\n\n// A flat entry, a condition-nested entry, and a fallback list all resolve through\n// one walker. An entry may declare `types` beside `default` at its top level\n// rather than inside `import`, so a fixed `entry.import.types` lookup is not\n// equivalent to condition resolution.\nfunction resolveTarget(entry: unknown, conditions: readonly string[]): string | undefined {\n\treturn resolvePackageTarget(entry, conditions)?.target\n}\n\n// Whether a path is a physical file. TypeScript's file-existence check refuses a\n// directory at the same spelling and continues to the outer package scope.\nfunction matchesFile(path: string): boolean {\n\ttry {\n\t\treturn statSync(path).isFile()\n\t} catch {\n\t\treturn false\n\t}\n}\n\n// TypeScript resolves a declaration target by accepting an existing declaration\n// directly or by substituting beside a JavaScript target. A missing target leaves\n// the containing condition or fallback list unresolved, so the walk continues.\nfunction targetToDeclaration(target: string, installed: string): string | undefined {\n\tif (!isPackageTarget(target)) return undefined\n\tconst declaration = target.endsWith('.cjs')\n\t\t? `${target.slice(0, -4)}.d.cts`\n\t\t: target.endsWith('.mjs')\n\t\t\t? `${target.slice(0, -4)}.d.mts`\n\t\t\t: target.endsWith('.js')\n\t\t\t\t? `${target.slice(0, -3)}.d.ts`\n\t\t\t\t: target\n\tif (declaration === target && !isDeclaration(target)) return undefined\n\treturn matchesFile(join(installed, declaration)) ? declaration : undefined\n}\n\n// The declaration TypeScript resolves through one importing format's conditions.\n// Condition objects keep manifest order, and arrays keep fallback order.\nfunction resolveDeclaration(\n\tentry: unknown,\n\tconditions: readonly string[],\n\tinstalled: string,\n): string | undefined {\n\tif (typeof entry === 'string') return targetToDeclaration(entry, installed)\n\tif (isList(entry)) {\n\t\tfor (const member of entry) {\n\t\t\tconst resolved = resolveDeclaration(member, conditions, installed)\n\t\t\tif (resolved !== undefined) return resolved\n\t\t}\n\t\treturn undefined\n\t}\n\tif (!isRecord(entry)) return undefined\n\tfor (const [condition, nested] of Object.entries(entry)) {\n\t\tif (condition !== 'default' && !conditions.includes(condition)) continue\n\t\tconst resolved = resolveDeclaration(nested, conditions, installed)\n\t\tif (resolved !== undefined) return resolved\n\t}\n\treturn undefined\n}\n\n// The nearest package scope that decides a `.d.ts` declaration's module format. A\n// physical nested manifest starts a scope even when it omits `type` or cannot be\n// parsed. A directory at that spelling is not a manifest, so the walk continues.\nfunction readPackageType(installed: string, target: string): unknown {\n\t// One `dirname` per path segment reaches the root from any path. The walk ends at the\n\t// installed package, so no scope above it is consulted.\n\tconst start = dirname(join(installed, target))\n\tconst chain = start\n\t\t.split(/[\\\\/]/u)\n\t\t.reduce<string[]>((climbed) => [...climbed, dirname(climbed.at(-1) ?? start)], [start])\n\tconst end = chain.indexOf(installed)\n\tconst scope = chain\n\t\t.slice(0, end === -1 ? chain.length : end + 1)\n\t\t.find((directory) => matchesFile(join(directory, 'package.json')))\n\tif (scope === undefined) return undefined\n\ttry {\n\t\tconst manifest = readJson(join(scope, 'package.json'))\n\t\treturn isRecord(manifest) ? manifest.type : undefined\n\t} catch {\n\t\treturn undefined\n\t}\n}\n\nfunction resolvesBrowser(entry: unknown): boolean {\n\tconst module = resolveTarget(entry, RUNTIME_CONDITIONS.browser)\n\tif (module !== undefined && module.startsWith(BROWSER_OUTPUT)) return true\n\tif (module === undefined) return false\n\tconst imported = resolveTarget(entry, RUNTIME_CONDITIONS.module)\n\tconst required = resolveTarget(entry, RUNTIME_CONDITIONS.commonjs)\n\treturn module !== imported && module !== required\n}\n\n// Whether the target selected by Node's CommonJS conditions is a module require can\n// load. A JavaScript target takes its own nearest package scope. Native addons and\n// extensionless targets have their own CommonJS handlers.\nfunction resolvesCommonJS(entry: unknown, installed: string): boolean {\n\tconst target = resolveTarget(entry, RUNTIME_CONDITIONS.commonjs)\n\tif (target === undefined) return false\n\tconst name = target.slice(target.lastIndexOf('/') + 1)\n\tif (name.endsWith('.cjs')) return true\n\tif (name.endsWith('.mjs')) return false\n\tif (name.endsWith('.node')) return true\n\tif (!name.includes('.')) return true\n\treturn name.endsWith('.js') && readPackageType(installed, target) !== 'module'\n}\n\n// Whether the declaration selected by a typed CommonJS consumer admits that entry.\n// A `.d.cts` declaration admits and a `.d.mts` declaration refuses. A `.d.ts`\n// declaration takes its own nearest package scope.\nfunction declaresCommonJS(entry: unknown, installed: string): boolean {\n\tconst declaration = resolveDeclaration(entry, DECLARATION_CONDITIONS.commonjs, installed)\n\tif (declaration === undefined) return false\n\tif (declaration.endsWith('.d.cts')) return true\n\tif (declaration.endsWith('.d.mts')) return false\n\treturn declaration.endsWith('.d.ts') && readPackageType(installed, declaration) !== 'module'\n}\n\n// Every target an entry names under any condition. A fallback list omits members\n// Node rejects during package-target validation, because no reader can take them.\nfunction collectTargets(entry: unknown): readonly string[] {\n\tif (typeof entry === 'string') return [entry]\n\tif (isList(entry)) return entry.flatMap(collectTargets).filter(isPackageTarget)\n\tif (!isRecord(entry)) return []\n\treturn Object.values(entry).flatMap((nested) => collectTargets(nested))\n}\n\n// Whether a target is a file a runtime loads for its names, which is what a\n// declaration is owed for. The extension on the target's own file name decides it,\n// and a name carrying no extension is code: `require` reads such a file through its\n// JavaScript handler, so an extensionless target loads and publishes names. Node\n// loads `.node` through its native-addon handler. Every other extension is an asset\n// a consumer reads rather than imports — a stylesheet, a WebAssembly binary, the\n// `\"./package.json\"` manifest pointer, and a declaration alike.\n// The cost is an extensionless file published for a reader, such as a `LICENSE`:\n// that target reports undeclared until it is given an extension or a declaration.\nfunction isModule(target: string): boolean {\n\tconst name = target.slice(target.lastIndexOf('/') + 1)\n\tconst dot = name.lastIndexOf('.')\n\tif (name.endsWith(ADDON_EXTENSION)) return true\n\treturn dot === -1 || MODULE_EXTENSIONS.includes(name.slice(dot))\n}\n\n// Whether a resolved target is a declaration rather than the JavaScript a\n// `default` branch answers with when the entry declares no `types` condition.\nfunction isDeclaration(target: string): boolean {\n\treturn DECLARATION_EXTENSIONS.some((extension) => target.endsWith(extension))\n}\n\n// The declarations the Node module, Node CommonJS, and browser drives compare\n// against. Each field uses the conditions of the TypeScript consumer paired with\n// that runtime. A JavaScript target resolves through TypeScript's adjacent\n// declaration substitution rather than standing in for the declaration itself.\nfunction readDeclaration(\n\tentry: unknown,\n\tinstalled: string,\n): {\n\treadonly module: string | undefined\n\treadonly commonjs: string | undefined\n\treadonly browser: string | undefined\n} {\n\treturn {\n\t\tmodule: resolveDeclaration(entry, DECLARATION_CONDITIONS.module, installed),\n\t\tcommonjs: resolveDeclaration(entry, DECLARATION_CONDITIONS.commonjs, installed),\n\t\tbrowser: resolveDeclaration(entry, DECLARATION_CONDITIONS.browser, installed),\n\t}\n}\n\n// The entries one compile driver can resolve under its own conditions.\nfunction selectEntries(entries: readonly Entry[], conditions: readonly string[]): readonly Entry[] {\n\treturn entries.filter(\n\t\t(entry) =>\n\t\t\tresolveTarget(entry.mapping, conditions) !== undefined &&\n\t\t\t(!conditions.includes('require') || entry.loadable),\n\t)\n}\n\n// The compile drivers whose conditions reach one entry under one importing format.\n// A driver that resolves no target for that entry compiles nothing, so a consumer\n// written under it would report a resolution failure this package never made.\nfunction selectDrivers(entry: Entry, format: Format): readonly Resolution[] {\n\treturn RESOLUTIONS.filter(\n\t\t(driver) => selectEntries([entry], driver.conditions[format]).length > 0,\n\t)\n}\n\n// Requirable entries that declare CommonJS support but a typed CommonJS consumer\n// cannot compile against. A default branch resolving under the require condition\n// set makes no CommonJS claim.\nfunction selectUntypable(entries: readonly Entry[], installed: string): readonly Entry[] {\n\treturn entries.filter(\n\t\t(entry) =>\n\t\t\tentry.requirable &&\n\t\t\tisRecord(entry.mapping) &&\n\t\t\tObject.hasOwn(entry.mapping, 'require') &&\n\t\t\t!declaresCommonJS(entry.mapping, installed),\n\t)\n}\n\n// One surface comparison, written as the consumer module that proves it: the\n// installed entry that consumer imports, the file extension fixing its importing\n// format, the names a real runtime published off it, and the driver whose scratch\n// project compiles it.\ninterface Surface {\n\treadonly entry: Entry\n\treadonly extension: string\n\treadonly published: readonly string[]\n\treadonly driver: Resolution\n}\n\n// A scratch project over named consumer modules, written beside them so their own\n// resolution reaches the installed package. Nothing is emitted and no ambient types\n// are pulled in, so what the check reads is the installed declarations alone.\nfunction writeProject(\n\tstage: Stage,\n\tname: string,\n\tdriver: Resolution,\n\tfiles: readonly string[],\n): string {\n\tconst path = join(stage.consumer, `tsconfig.${name}.json`)\n\tconst project = {\n\t\tcompilerOptions: {\n\t\t\tmodule: driver.module,\n\t\t\tmoduleResolution: driver.resolution,\n\t\t\tnoEmit: true,\n\t\t\tskipLibCheck: true,\n\t\t\tstrict: true,\n\t\t\ttarget: 'esnext',\n\t\t\ttypes: [],\n\t\t},\n\t\tfiles: [...files],\n\t}\n\twriteFile(path, `${JSON.stringify(project, undefined, '\\t')}\\n`)\n\treturn path\n}\n\n// The diagnostics the compiler this workspace installs reports for one scratch\n// project. The compiler runs as a command, so nothing here reaches an API that\n// moves between its majors, and the located lines it prints are the verdict rather\n// than the exit code, which moves between them. A line carrying no location, a line\n// naming the scratch project rather than a consumer module, and anything at all on\n// the error stream are faults of this proof rather than of the package under proof,\n// so each is raised where it happens instead of counted against the package.\nfunction checkProject(stage: Stage, project: string): readonly string[] {\n\tconst result = runNode([TSC, '--noEmit', '--pretty', 'false', '-p', project], stage.consumer)\n\tconst refused = `${result.stderr ?? ''}`.trim()\n\tif (refused.length > 0) {\n\t\tthrow new Error(`The consumer compiler wrote ${refused} to its error stream`)\n\t}\n\tconst lines = `${result.stdout ?? ''}`.split(/\\r\\n|\\n/u).filter((line) => line.trim().length > 0)\n\t// An elaborated diagnostic prints its detail on indented lines under its own\n\t// first line, so each of those joins the diagnostic it elaborates. The first line\n\t// has no diagnostic above it to join, so it opens one whatever its indentation.\n\tconst heads = lines.flatMap((line, index) => (index === 0 || !/^\\s/u.test(line) ? [index] : []))\n\tconst reported = heads.map((head, position) => {\n\t\tconst line = lines[head] ?? ''\n\t\tconst located = DIAGNOSTIC_PATTERN.exec(line)?.[1]\n\t\tif (located === undefined) {\n\t\t\tthrow new Error(`The consumer compiler reported ${line}, which names no location`)\n\t\t}\n\t\tif (resolve(stage.consumer, located) === project) {\n\t\t\tthrow new Error(`The scratch project is itself at fault: ${line}`)\n\t\t}\n\t\treturn [\n\t\t\tline,\n\t\t\t...lines.slice(head + 1, heads[position + 1] ?? lines.length).map((detail) => detail.trim()),\n\t\t].join(' ')\n\t})\n\tif (reported.length === 0 && result.status !== 0) {\n\t\tthrow new Error(`The consumer compiler refused the project: ${readOutput(result)}`)\n\t}\n\treturn reported\n}\n\n// One installed entry's published names checked against its own declarations by\n// the compiler this workspace installs, in the direction each divergence surfaces\n// under. The runtime's key list is written into the consumer as a literal, so the\n// published side comes from a real process and the declared side from the\n// declarations that process's package ships, and the two can disagree. A name the\n// declarations carry and the runtime does not lands on `declared`. A name the\n// runtime carries and the declarations do not, and a name the declarations publish\n// as a type alone, land on `surfaced`: a variable widens into the type\n// `declared` annotates, and only `surfaced` reads the literal's own keys back.\n// Each names the member it is about, so the failure says which export moved.\nfunction checkSurface(stage: Stage, surface: Surface): readonly string[] {\n\tconst slug = surface.entry.subpath.replaceAll(/[^\\w]+/gu, '-')\n\tconst name = `surface.${surface.driver.label}${slug}.${surface.extension}`\n\tconst module = `${name}`\n\tconst keys = surface.published.map((key) => `${JSON.stringify(key)}: true`).join(', ')\n\twriteFile(\n\t\tjoin(stage.consumer, module),\n\t\t`import * as entry from ${JSON.stringify(surface.entry.specifier)}\nconst published = {${keys.length === 0 ? '' : ` ${keys} `}} as const\nconst declared: Record<keyof typeof entry, true> = published\nconst surfaced: Record<keyof typeof published, true> = declared\n`,\n\t)\n\tconst project = writeProject(stage, name, surface.driver, [`./${module}`])\n\treturn checkProject(stage, project).map((line) => `${surface.driver.label}: ${line}`)\n}\n\n// One consumer module importing every installed entry, written where its own\n// resolution finds the installed package.\nfunction writeConsumerProbe(stage: Stage, path: string, specifiers: readonly string[]): void {\n\tconst modules = specifiers.map((specifier, index) => ({\n\t\tbinding: `entry${String(index)}`,\n\t\tspecifier,\n\t}))\n\tconst bindings = modules.map(\n\t\t({ binding, specifier }) => `import * as ${binding} from ${JSON.stringify(specifier)}`,\n\t)\n\tconst names = modules.map(({ binding }) => binding)\n\tconst source = `${bindings.join('\\n')}\\nexport const surface = [${names.join(', ')}]\\n`\n\twriteFile(join(stage.consumer, path), source)\n}\n\n// The runtime key set a real process reads off one installed entry under one\n// condition. The driver is a file rather than an `--eval` string, so the specifier\n// travels as an argument and nothing needs escaping.\nfunction driveRuntime(stage: Stage, specifier: string, driver: string): readonly string[] {\n\tconst result = runNode([join(stage.consumer, driver), specifier], stage.consumer)\n\tif (result.status !== 0) {\n\t\tthrow new Error(`Loading ${specifier} from the consumer failed: ${readOutput(result)}`)\n\t}\n\tconst published: unknown = JSON.parse(result.stdout)\n\tif (!isNames(published)) throw new Error(`The driver printed no name list for ${specifier}`)\n\treturn published\n}\n{{helpers}}\n// Pack this workspace, install the archive into an isolated consumer, and read the\n// published surface back off the installed tree. Every later claim reads this\n// result, so a failure here is raised where it happens rather than once per entry.\nfunction buildStage(scratch: string): Stage {\n\tconst packed = join(scratch, 'packed')\n\tconst consumer = join(scratch, 'consumer')\n\tmkdirSync(packed, { recursive: true })\n\tconst pack = runNpm(['pack', '--ignore-scripts', '--pack-destination', packed], ROOT, scratch)\n\tif (pack.status !== 0) throw new Error(`npm pack refused this workspace: ${readOutput(pack)}`)\n\tconst archives = readdirSync(packed).filter((name) => name.endsWith('.tgz'))\n\tconst archive = archives[0]\n\tif (archives.length !== 1 || archive === undefined) {\n\t\tthrow new Error(`npm pack wrote no single archive: ${archives.join(', ')}`)\n\t}\n\twriteFile(join(consumer, 'package.json'), CONSUMER_MANIFEST)\n\twriteFile(join(consumer, ESM_DRIVER), ESM_DRIVER_SOURCE)\n\twriteFile(join(consumer, CJS_DRIVER), CJS_DRIVER_SOURCE)\n\tconst install = runNpm(\n\t\t['install', '--ignore-scripts', '--no-audit', '--no-fund', join(packed, archive)],\n\t\tconsumer,\n\t\tscratch,\n\t)\n\tif (install.status !== 0) {\n\t\tthrow new Error(`Installing the packed archive failed: ${readOutput(install)}`)\n\t}\n\tconst name = readManifestName(join(ROOT, 'package.json'))\n\tconst installed = join(consumer, 'node_modules', ...name.split('/'))\n\tconst manifest = readJson(join(installed, 'package.json'))\n\tif (!isRecord(manifest) || !isRecord(manifest.exports)) {\n\t\tthrow new Error('The installed manifest publishes no exports map')\n\t}\n\tconst readings = Object.entries(manifest.exports).map(([subpath, mapping]) => {\n\t\tconst files = collectTargets(mapping)\n\t\tconst declaration = readDeclaration(mapping, installed)\n\t\t// A subpath resolving no declaration is partitioned rather than dropped. It is a\n\t\t// defect when a runtime loads one of its targets for names, because a consumer\n\t\t// importing it compiles against nothing under `node16`. It is an excluded\n\t\t// publication otherwise: the `\"./package.json\"` manifest pointer and a stylesheet\n\t\t// are published for a reader rather than an importer.\n\t\tif (\n\t\t\tdeclaration.module === undefined &&\n\t\t\tdeclaration.commonjs === undefined &&\n\t\t\tdeclaration.browser === undefined\n\t\t) {\n\t\t\treturn { subpath, files, entry: undefined }\n\t\t}\n\t\tconst importTarget = resolveTarget(mapping, RUNTIME_CONDITIONS.module)\n\t\tconst requireTarget = resolveTarget(mapping, RUNTIME_CONDITIONS.commonjs)\n\t\tconst browserTarget = resolveTarget(mapping, RUNTIME_CONDITIONS.browser)\n\t\tconst browsable = resolvesBrowser(mapping)\n\t\tconst shadowed = browsable && requireTarget === browserTarget\n\t\tconst requirable = requireTarget !== undefined && !shadowed\n\t\tconst loadable = requirable && resolvesCommonJS(mapping, installed)\n\t\tconst entry: Entry = {\n\t\t\tsubpath,\n\t\t\tspecifier: subpath === '.' ? name : `${name}${subpath.slice(1)}`,\n\t\t\tmapping,\n\t\t\tdeclaration: {\n\t\t\t\timportable: declaration.module !== undefined,\n\t\t\t\trequirable: declaration.commonjs !== undefined,\n\t\t\t\tbrowsable: declaration.browser !== undefined,\n\t\t\t},\n\t\t\tbrowsable,\n\t\t\timportable: importTarget !== undefined && !(browsable && importTarget === browserTarget),\n\t\t\trequirable,\n\t\t\tloadable,\n\t\t}\n\t\treturn { subpath, files, entry }\n\t})\n\tconst entries = readings.flatMap(({ entry }) => (entry === undefined ? [] : [entry]))\n\tconst targets = readings.flatMap(({ files }) => files)\n\tconst subpaths = readings.map(({ subpath }) => subpath)\n\tconst undeclared = readings\n\t\t.filter(({ entry, files }) => entry === undefined && files.some(isModule))\n\t\t.map(({ subpath }) => subpath)\n\tconst excluded = readings\n\t\t.filter(({ entry, files }) => entry === undefined && !files.some(isModule))\n\t\t.map(({ subpath }) => subpath)\n\treturn { consumer, installed, archives, entries, subpaths, undeclared, excluded, targets }\n}\n\n// One file's run: the scratch directory and the staged consumer, which is absent when the\n// registry could not be reached.\ninterface DistributionRun {\n\treadonly scratch: string\n\treadonly stage: Stage | undefined\n}\n\n// The run the start hook binds once for this file and the stop hook releases.\nclass DistributionSuite {\n\t#run: DistributionRun | undefined\n\n\tget scratch(): string {\n\t\tif (this.#run === undefined) {\n\t\t\tthrow new Error('The distribution setup has not allocated its scratch directory')\n\t\t}\n\t\treturn this.#run.scratch\n\t}\n\n\tget stage(): Stage | undefined {\n\t\treturn this.#run?.stage\n\t}\n\n\tstart(): void {\n\t\tif (this.#run !== undefined) {\n\t\t\tthrow new Error('The distribution setup has already allocated its scratch directory')\n\t\t}\n\t\tconst scratch = mkdtempSync(join(tmpdir(), 'distribution-'))\n\t\tthis.#run = { scratch, stage: openStage(scratch) }\n\t}\n\n\tdestroy(): void {\n\t\tif (this.#run !== undefined) {\n\t\t\trmSync(this.#run.scratch, { force: true, recursive: true, maxRetries: 3, retryDelay: 100 })\n\t\t}\n\t\tthis.#run = undefined\n\t}\n}\n\nconst DISTRIBUTION_SUITE = new DistributionSuite()\n\nbeforeAll(() => DISTRIBUTION_SUITE.start())\n\nafterAll(() => DISTRIBUTION_SUITE.destroy())\n\n// Installing the packed archive resolves its own runtime dependencies, so an\n// unreachable registry leaves nothing to measure. Under release that is the gate\n// failing; anywhere else the suite skips and names the mechanism it wanted.\nfunction openStage(scratch: string): Stage | undefined {\n\ttry {\n\t\tmkdirSync(join(scratch, 'cache'), { recursive: true })\n\t\tif (runNpm(PING, ROOT, scratch).status !== 0) {\n\t\t\tif (!RELEASE) return undefined\n\t\t\tthrow new Error(\n\t\t\t\t'The release gate requires a reachable npm registry, and npm ping did not answer',\n\t\t\t)\n\t\t}\n\t\treturn buildStage(scratch)\n\t} catch (error) {\n\t\trmSync(scratch, {\n\t\t\tforce: true,\n\t\t\trecursive: true,\n\t\t\tmaxRetries: 3,\n\t\t\tretryDelay: 100,\n\t\t})\n\t\tthrow error\n\t}\n}\n\ndescribe('distribution classifiers', () => {\n\tit('classifies synthetic export mappings without a registry stage', () => {\n\t\tconst root = join(DISTRIBUTION_SUITE.scratch, 'classifiers')\n\t\twriteFile(\n\t\t\tjoin(root, 'package.json'),\n\t\t\tJSON.stringify({\n\t\t\t\ttype: 'commonjs',\n\t\t\t\texports: {\n\t\t\t\t\tcondition: { browser: './b.js', default: './n.js' },\n\t\t\t\t\tconvention: { default: './dist/src/browser/index.js' },\n\t\t\t\t\tuniversal: { default: './shared.js' },\n\t\t\t\t\t'import-shared': {\n\t\t\t\t\t\tbrowser: './shared.mjs',\n\t\t\t\t\t\timport: './shared.mjs',\n\t\t\t\t\t\tdefault: './node.js',\n\t\t\t\t\t},\n\t\t\t\t\t'require-shared': {\n\t\t\t\t\t\tbrowser: './shared.cjs',\n\t\t\t\t\t\trequire: './shared.cjs',\n\t\t\t\t\t\tdefault: './node.js',\n\t\t\t\t\t},\n\t\t\t\t\tnode: { node: './node.js', default: './node.js' },\n\t\t\t\t\tsilent: { 'module-sync': './x.cjs', import: './x.mjs' },\n\t\t\t\t\tmodule: { require: './x.mjs' },\n\t\t\t\t\t'nested-module': { require: './module/x.js' },\n\t\t\t\t\t'nested-commonjs': { require: './commonjs/x.js' },\n\t\t\t\t\tesm: { import: './x.mjs' },\n\t\t\t\t},\n\t\t\t}),\n\t\t)\n\t\twriteFile(join(root, 'module/package.json'), '{ \"type\": \"module\" }\\n')\n\t\twriteFile(join(root, 'commonjs/package.json'), '{ \"type\": \"commonjs\" }\\n')\n\t\tconst manifest = readJson(join(root, 'package.json'))\n\t\tif (!isRecord(manifest) || !isRecord(manifest.exports)) {\n\t\t\tthrow new Error('The classifier fixture declares no exports map')\n\t\t}\n\t\tconst mappings = manifest.exports\n\t\texpect({\n\t\t\tcondition: resolvesBrowser(mappings.condition),\n\t\t\tconvention: resolvesBrowser(mappings.convention),\n\t\t\tuniversal: resolvesBrowser(mappings.universal),\n\t\t\timport: resolvesBrowser(mappings['import-shared']),\n\t\t\trequire: resolvesBrowser(mappings['require-shared']),\n\t\t\tnode: resolvesBrowser(mappings.node),\n\t\t}).toStrictEqual({\n\t\t\tcondition: true,\n\t\t\tconvention: true,\n\t\t\tuniversal: false,\n\t\t\timport: false,\n\t\t\trequire: false,\n\t\t\tnode: false,\n\t\t})\n\t\texpect({\n\t\t\tsilent: resolvesCommonJS(mappings.silent, root),\n\t\t\tmodule: resolvesCommonJS(mappings.module, root),\n\t\t\tnestedModule: resolvesCommonJS(mappings['nested-module'], root),\n\t\t\tnestedCommonJS: resolvesCommonJS(mappings['nested-commonjs'], root),\n\t\t\tesm: resolvesCommonJS(mappings.esm, root),\n\t\t}).toStrictEqual({\n\t\t\tsilent: true,\n\t\t\tmodule: false,\n\t\t\tnestedModule: false,\n\t\t\tnestedCommonJS: true,\n\t\t\tesm: false,\n\t\t})\n\t})\n})\n\n// The staged consumer, or a skip naming what the run could not reach. `it.skipIf`\n// carries no reason, so the gate sits here where the test context can state one.\nfunction requireStage(context: TestContext): Stage {\n\tconst staged = DISTRIBUTION_SUITE.stage\n\tif (staged === undefined) {\n\t\treturn context.skip('`npm ping` did not answer, so nothing was packed or installed')\n\t}\n\treturn staged\n}\n\ndescribe('installed package consumer', () => {\n\tit('packs one archive and installs it in isolation [requires the registry]', (context) => {\n\t\tconst stage = requireStage(context)\n\t\texpect(stage.archives).toHaveLength(1)\n\t\texpect(existsSync(join(stage.installed, 'package.json'))).toBe(true)\n\t\texpect(stage.entries.length).toBeGreaterThan(0)\n\t})\n\n\tit('ships every relative target its exports map names [requires the registry]', (context) => {\n\t\tconst stage = requireStage(context)\n\t\tconst relative = stage.targets.filter((target) => target.startsWith('./'))\n\t\texpect(relative).not.toStrictEqual([])\n\t\texpect(relative.filter((target) => !existsSync(join(stage.installed, target)))).toStrictEqual(\n\t\t\t[],\n\t\t)\n\t})\n\n\t// Every published subpath is driven, excluded by name, or reported here. A dropped\n\t// one leaves no trace: no runtime test, no declaration comparison, and no place in\n\t// the resolution compile, so the run reports success for a subpath it never\n\t// measured.\n\tit('declares types for every module it publishes [requires the registry]', (context) => {\n\t\tconst stage = requireStage(context)\n\t\tconst partitioned = [\n\t\t\t...stage.entries.map((entry) => entry.subpath),\n\t\t\t...stage.undeclared,\n\t\t\t...stage.excluded,\n\t\t]\n\t\texpect(stage.undeclared).toStrictEqual([])\n\t\texpect(partitioned.sort()).toStrictEqual([...stage.subpaths].sort())\n\t\t// A driven subpath answers a runtime condition. One resolving a declaration and\n\t\t// no Node or browser target compiles for a consumer and throws when that consumer\n\t\t// loads it. Each later drive retires itself for that entry, so this assertion names\n\t\t// the subpath rather than counting it as driven.\n\t\tconst unreachable = stage.entries.filter(\n\t\t\t(entry) => !entry.importable && !entry.requirable && !entry.browsable,\n\t\t)\n\t\texpect(unreachable.map((entry) => entry.subpath)).toStrictEqual([])\n\t\tconst untypable = selectUntypable(stage.entries, stage.installed)\n\t\texpect(untypable.map((entry) => entry.subpath)).toStrictEqual([])\n\t})\n\n\tit('refuses a subpath its exports map does not name [requires the registry]', (context) => {\n\t\tconst stage = requireStage(context)\n\t\tconst name = readManifestName(join(stage.installed, 'package.json'))\n\t\tconst driver = join(stage.consumer, ESM_DRIVER)\n\t\tconst result = runNode([driver, `${name}${ABSENT_SUBPATH}`], stage.consumer)\n\t\texpect(result.status).not.toBe(0)\n\t\texpect(readOutput(result)).toContain('ERR_PACKAGE_PATH_NOT_EXPORTED')\n\t})\n\n\t// The absent subpath is the firing control: a resolution that reports nothing\n\t// for every published entry has not been shown to resolve anything at all. Each\n\t// module format carries its own control, because a format that resolves nothing\n\t// is silent for the same reason a resolution that resolves nothing is.\n\tit('compiles a consumer under every module resolution [requires the registry]', (context) => {\n\t\tconst stage = requireStage(context)\n\t\tconst name = readManifestName(join(stage.installed, 'package.json'))\n\t\tconst readings = RESOLUTIONS.flatMap((driver) =>\n\t\t\tFORMATS.flatMap(([extension, format]) => {\n\t\t\t\tconst written = selectEntries(stage.entries, driver.conditions[format])\n\t\t\t\tif (written.length === 0) return []\n\t\t\t\tconst label = `${driver.label}.${extension}`\n\t\t\t\tconst probe = `probe.${label}`\n\t\t\t\tconst specifiers = written.map((entry) => entry.specifier)\n\t\t\t\twriteConsumerProbe(stage, probe, specifiers)\n\t\t\t\tconst project = writeProject(stage, probe, driver, [`./${probe}`])\n\t\t\t\tconst messages = checkProject(stage, project).map((message) => `${label}: ${message}`)\n\t\t\t\tconst control = `control.${label}`\n\t\t\t\twriteConsumerProbe(stage, control, [`${name}${ABSENT_SUBPATH}`])\n\t\t\t\tconst refused = writeProject(stage, control, driver, [`./${control}`])\n\t\t\t\treturn [{ messages, silent: checkProject(stage, refused).length === 0 ? [label] : [] }]\n\t\t\t}),\n\t\t)\n\t\texpect(readings.flatMap(({ messages }) => messages)).toStrictEqual([])\n\t\texpect(readings.flatMap(({ silent }) => silent)).toStrictEqual([])\n\t})\n{{guard}}})\n\ndescribe('installed entries', () => {\n\tit('publishes what it declares to a Node import, and no more', (context) => {\n\t\tconst stage = requireStage(context)\n\t\tconst entries = stage.entries.filter((entry) => entry.importable)\n\t\tif (entries.length === 0) return context.skip('No installed entry supports Node import')\n\t\tfor (const entry of entries) {\n\t\t\tif (!entry.declaration.importable) {\n\t\t\t\tthrow new Error(`${entry.subpath} publishes no import declaration`)\n\t\t\t}\n\t\t\tconst published = driveRuntime(stage, entry.specifier, ESM_DRIVER)\n\t\t\tconst drivers = selectDrivers(entry, 'module')\n\t\t\texpect(drivers).not.toStrictEqual([])\n\t\t\tconst reported = drivers.flatMap((driver) =>\n\t\t\t\tcheckSurface(stage, { entry, extension: 'ts', published, driver }),\n\t\t\t)\n\t\t\texpect(reported).toStrictEqual([])\n\t\t}\n\t})\n\n\tit('publishes what it declares to a Node require, and no more', (context) => {\n\t\tconst stage = requireStage(context)\n\t\tconst entries = stage.entries.filter((entry) => entry.requirable)\n\t\tif (entries.length === 0) return context.skip('No installed entry supports Node require')\n\t\tfor (const entry of entries) {\n\t\t\tif (!entry.declaration.requirable) {\n\t\t\t\tthrow new Error(`${entry.subpath} publishes no require declaration`)\n\t\t\t}\n\t\t\tconst published = driveRuntime(stage, entry.specifier, CJS_DRIVER)\n\t\t\tconst drivers = selectDrivers(entry, 'commonjs')\n\t\t\texpect(drivers).not.toStrictEqual([])\n\t\t\tconst reported = drivers.flatMap((driver) =>\n\t\t\t\tcheckSurface(stage, { entry, extension: 'cts', published, driver }),\n\t\t\t)\n\t\t\texpect(reported).toStrictEqual([])\n\t\t}\n\t})\n{{drive}}})\n";
|
|
136
136
|
transport: "import { createServer } from 'node:http'\n";
|
|
137
137
|
types: "import type { PlaywrightProviderOptions } from '@vitest/browser-playwright'\nimport type { Browser } from 'playwright'\n";
|
|
138
138
|
launcher: "import { chromium } from 'playwright'\nimport { build } from 'vite'\nimport { resolveBrowser, resolvePinnedBrowser } from '../configs/browsers.js'\n";
|
|
@@ -290,7 +290,7 @@ export declare const BIN_ENTRY_PATH = "src/bin/main.ts";
|
|
|
290
290
|
* fleet pin; every other peer is a floor. `extras` are package-specific
|
|
291
291
|
* development dependencies and may carry any valid npm name.
|
|
292
292
|
* `bin`, `setup`, `guides`, `integration`, `conformance`, `service`,
|
|
293
|
-
* `vendors`, `global`, `showcase`, `journey`, `styles`, `themes`, and `skills` are structural facts: each is
|
|
293
|
+
* `vendors`, `studies`, `global`, `showcase`, `journey`, `styles`, `themes`, and `skills` are structural facts: each is
|
|
294
294
|
* set only when the workspace physically ships the directory or exact-case file
|
|
295
295
|
* that defines it, never because of the workspace's name and never because a
|
|
296
296
|
* sibling fact is set.
|
|
@@ -310,6 +310,12 @@ export declare const BIN_ENTRY_PATH = "src/bin/main.ts";
|
|
|
310
310
|
* starts nothing. Neither is derivable from the other: a workspace may declare
|
|
311
311
|
* vendors before it writes a suite, and a suite may drive a service the skeleton
|
|
312
312
|
* does not start.
|
|
313
|
+
*
|
|
314
|
+
* `studies` says the workspace holds at least one exact-case `*.test.ts` file
|
|
315
|
+
* beneath `tests/studies`, nested or direct, outside any `node_modules` or `.git`
|
|
316
|
+
* directory, which Vitest's default exclude never collects, and it alone registers
|
|
317
|
+
* the `studies` Vitest project over that directory. The harness module the study tests import,
|
|
318
|
+
* `tests/setupStudy.ts`, selects nothing and is not planned.
|
|
313
319
|
*/
|
|
314
320
|
export declare interface Blueprint {
|
|
315
321
|
readonly name: string;
|
|
@@ -336,6 +342,7 @@ export declare interface Blueprint {
|
|
|
336
342
|
readonly conformance: boolean;
|
|
337
343
|
readonly service: boolean;
|
|
338
344
|
readonly vendors: readonly string[];
|
|
345
|
+
readonly studies: boolean;
|
|
339
346
|
readonly global: boolean;
|
|
340
347
|
readonly showcase: boolean;
|
|
341
348
|
readonly journey: boolean;
|
|
@@ -787,11 +794,12 @@ export declare function blueprintToRootVite(blueprint: Blueprint): string;
|
|
|
787
794
|
* proofs every workspace can pass before it has a public API, and one build per
|
|
788
795
|
* target that actually builds.
|
|
789
796
|
*
|
|
790
|
-
* A publishing workspace isolates its distribution and live-service proofs
|
|
791
|
-
* `test` and runs them from `prepublishOnly` instead. Publishing is what
|
|
792
|
-
* the distribution proof: what that proof measures is the packed tarball,
|
|
793
|
-
* workspace that packs no published source has nothing for it to read. A
|
|
794
|
-
* workspace therefore omits it and runs a
|
|
797
|
+
* A publishing workspace isolates its distribution, study, and live-service proofs
|
|
798
|
+
* from `test` and runs them from `prepublishOnly` instead. Publishing is what
|
|
799
|
+
* selects the distribution proof: what that proof measures is the packed tarball,
|
|
800
|
+
* so a workspace that packs no published source has nothing for it to read. A
|
|
801
|
+
* private workspace therefore omits it and runs a study proof and a live-service
|
|
802
|
+
* proof from `test`, the study proof first.
|
|
795
803
|
* Integration and conformance stay in `test` because they neither pack nor
|
|
796
804
|
* install the workspace and drive no external service. A conformance run may
|
|
797
805
|
* start a server, but it starts its own and reaches it over loopback, so the run
|
|
@@ -863,7 +871,8 @@ export declare function blueprintToSourceArtifacts(blueprint: Blueprint): readon
|
|
|
863
871
|
* is not: it names an official artifact only the package knows, so a generated
|
|
864
872
|
* placeholder would read as a proof while measuring nothing. `service` emits its
|
|
865
873
|
* readiness setup alone, because the root configuration names that module by
|
|
866
|
-
* path.
|
|
874
|
+
* path. `studies` emits nothing: the root configuration names no study harness,
|
|
875
|
+
* so `tests/setupStudy.ts` is the package's own module.
|
|
867
876
|
*
|
|
868
877
|
* The distribution proof is emitted, and the same test separates it from those
|
|
869
878
|
* two: its subject is the packed tarball rather than anything only the package
|
|
@@ -903,7 +912,9 @@ export declare function blueprintToTestArtifacts(blueprint: Blueprint): readonly
|
|
|
903
912
|
* guides entry accepts the generated command that invoked the guides project
|
|
904
913
|
* through Vitest alone. The pack hook accepts the build chain emitted before it
|
|
905
914
|
* delegated to `build`. The publication hook accepts the same gate chain without
|
|
906
|
-
* {@link RELEASE_PROOF_COMMAND}.
|
|
915
|
+
* {@link RELEASE_PROOF_COMMAND}. A workspace carrying studies also accepts the
|
|
916
|
+
* chain without its study step and the chain without both its study step and
|
|
917
|
+
* the release proof. The value being written is always writable, so
|
|
907
918
|
* it is not repeated there. Any other value is a script the workspace author
|
|
908
919
|
* customized, and {@link replaceManifestScripts} retains it while writing the
|
|
909
920
|
* other named scripts independently.
|
|
@@ -1437,6 +1448,27 @@ export declare class Compiler implements CompilerInterface {
|
|
|
1437
1448
|
*/
|
|
1438
1449
|
export declare function computeHash(text: string): string;
|
|
1439
1450
|
|
|
1451
|
+
/**
|
|
1452
|
+
* Computes the sum of a list of numbers.
|
|
1453
|
+
*
|
|
1454
|
+
* @param values - The numbers to add.
|
|
1455
|
+
* @returns The sum, and `0` for no numbers.
|
|
1456
|
+
*
|
|
1457
|
+
* @remarks
|
|
1458
|
+
* The one place a running tally is derived from the amounts that make it up, so a
|
|
1459
|
+
* byte budget is the allowance less what was spent rather than a counter that is
|
|
1460
|
+
* reassigned as reads land.
|
|
1461
|
+
*
|
|
1462
|
+
* @example
|
|
1463
|
+
* ```ts
|
|
1464
|
+
* import { computeTotal } from '@orkestrel/scaffold'
|
|
1465
|
+
*
|
|
1466
|
+
* computeTotal([65536, 65536, 12]) // 131084
|
|
1467
|
+
* computeTotal([]) // 0
|
|
1468
|
+
* ```
|
|
1469
|
+
*/
|
|
1470
|
+
export declare function computeTotal(values: readonly number[]): number;
|
|
1471
|
+
|
|
1440
1472
|
/**
|
|
1441
1473
|
* Holds formatter-stable template text for every configuration artifact.
|
|
1442
1474
|
*
|
|
@@ -1458,20 +1490,20 @@ export declare class Compiler implements CompilerInterface {
|
|
|
1458
1490
|
export declare const CONFIG_TEMPLATES: Readonly<{
|
|
1459
1491
|
root: Readonly<{
|
|
1460
1492
|
tsconfig: "{\n\t\"compilerOptions\": {\n\t\t\"target\": \"ESNext\",\n\t\t\"module\": \"ESNext\",\n\t\t\"moduleResolution\": \"bundler\",\n\t\t\"allowImportingTsExtensions\": true,\n\t\t\"lib\": [\"ESNext\", \"DOM\", \"DOM.Iterable\"],\n\t\t\"types\": [\"node\", \"vite/client\", \"vitest/globals\"],\n\t\t\"moduleDetection\": \"force\",\n\t\t\"resolveJsonModule\": true,\n\t\t\"strict\": true,\n\t\t\"verbatimModuleSyntax\": true,\n\t\t\"noUncheckedIndexedAccess\": true,\n\t\t\"noUncheckedSideEffectImports\": true,\n\t\t\"exactOptionalPropertyTypes\": true,\n\t\t\"noUnusedLocals\": true,\n\t\t\"noUnusedParameters\": true,\n\t\t\"noImplicitOverride\": true,\n\t\t\"noFallthroughCasesInSwitch\": true,\n\t\t\"forceConsistentCasingInFileNames\": true,\n\t\t\"skipLibCheck\": true,\n\t\t\"noEmit\": true,\n{{paths}}\n\t},\n\t\"exclude\": [\"node_modules\", \"dist\", \"tmp\"]\n}\n";
|
|
1461
|
-
vite: "{{journey}}import type { PluginOption, UserConfig } from 'vite'\nimport { mergeConfig } from 'vite'\n{{imports}}import { defineConfig } from 'vitest/config'\nimport manifest from './package.json' with { type: 'json' }\nimport tsconfig from './tsconfig.json' with { type: 'json' }\n{{helpers}}{{browsers}}import { fileURLToPath, URL } from 'node:url'\n\n{{options}}export function resolveWorkspacePath(relativePath: string): string {\n\treturn fileURLToPath(new URL(relativePath, import.meta.url))\n}\n\nconst peerDependencies = 'peerDependencies' in manifest ? manifest.peerDependencies : undefined\nif (\n\tpeerDependencies !== undefined &&\n\t(typeof peerDependencies !== 'object' ||\n\t\tpeerDependencies === null ||\n\t\tArray.isArray(peerDependencies))\n) {\n\tthrow new Error('package peerDependencies must be an object')\n}\nexport const peers: readonly string[] =\n\tpeerDependencies === undefined ? [] : Object.keys(peerDependencies)\n\nconst resolve = {\n\talias: Object.entries(tsconfig.compilerOptions.paths).
|
|
1493
|
+
vite: "{{journey}}import type { PluginOption, UserConfig } from 'vite'\nimport { mergeConfig } from 'vite'\n{{imports}}import { defineConfig } from 'vitest/config'\nimport manifest from './package.json' with { type: 'json' }\nimport tsconfig from './tsconfig.json' with { type: 'json' }\n{{helpers}}{{browsers}}import { fileURLToPath, URL } from 'node:url'\n\n{{options}}export function resolveWorkspacePath(relativePath: string): string {\n\treturn fileURLToPath(new URL(relativePath, import.meta.url))\n}\n\nconst peerDependencies = 'peerDependencies' in manifest ? manifest.peerDependencies : undefined\nif (\n\tpeerDependencies !== undefined &&\n\t(typeof peerDependencies !== 'object' ||\n\t\tpeerDependencies === null ||\n\t\tArray.isArray(peerDependencies))\n) {\n\tthrow new Error('package peerDependencies must be an object')\n}\nexport const peers: readonly string[] =\n\tpeerDependencies === undefined ? [] : Object.keys(peerDependencies)\n\nconst resolve = {\n\talias: Object.fromEntries(\n\t\tObject.entries(tsconfig.compilerOptions.paths).map(([key, values]) => {\n\t\t\tconst [path] = values\n\t\t\tif (path === undefined) throw new Error('tsconfig path alias ' + key + ' has no target')\n\t\t\treturn [key, resolveWorkspacePath(path)]\n\t\t}),\n\t),\n}\n\n// Merges a caller's override onto the configuration a factory declares, so a\n// package's own configuration reaches the factory through its parameter instead of\n// wrapping the call from outside.\n//\n// Vitest calls every registered project factory with its own invocation record —\n// `command`, `mode`, `isSsrBuild`, `isPreview` — so a factory that also takes an\n// override receives that record in the same position. A `UserConfig` declares `mode`\n// but not `command`, and the invocation record always carries both, so a value\n// carrying the pair is that record rather than an override. The merge returns the\n// base in the record's `mode` and carries none of the record's other fields. Vitest\n// runs a project that declares no `mode` in its own run mode, `test`, rather than in\n// the `--mode` value it was invoked with, so a distribution proof run with\n// `--mode release` would read `test` and skip where it must fail. A record whose\n// `mode` is not a string throws. The `tests/config.test.ts` file drives every\n// registered factory through it.\n//\n// `mergeConfig` concatenates arrays, so an override carrying `plugins` would otherwise\n// add a second copy of a plugin the base already declares. Only named top-level\n// objects replace a base plugin of the same name, in the base's position, and one\n// override entry is taken at most once. An entry no base position took appends in its\n// written order; the caller's own entries never merge with each other. Nested arrays,\n// promises, falsy entries, and anonymous objects pass through unchanged. An override\n// cannot remove a base plugin. Every key other than `plugins` merges as `mergeConfig`\n// merges it, so an override's arrays elsewhere concatenate with the base's rather than\n// replacing them.\nexport function mergeOverride(base: UserConfig, override?: UserConfig): UserConfig {\n\tif (\n\t\toverride !== undefined &&\n\t\t'command' in override &&\n\t\t'mode' in override &&\n\t\ttypeof override.mode !== 'string'\n\t) {\n\t\tthrow new Error('The project invocation carries no string mode')\n\t}\n\tconst effective: UserConfig | undefined =\n\t\toverride !== undefined && 'command' in override && typeof override.mode === 'string'\n\t\t\t? { mode: override.mode }\n\t\t\t: override\n\tconst merged: UserConfig = effective === undefined ? { ...base } : mergeConfig(base, effective)\n\tconst name = merged.test?.name\n\tconst label = typeof name === 'string' ? name : name?.label\n\tconst browser = merged.test?.browser\n\tconst named: UserConfig =\n\t\tlabel !== undefined && browser?.instances !== undefined\n\t\t\t? {\n\t\t\t\t\t...merged,\n\t\t\t\t\ttest: {\n\t\t\t\t\t\t...merged.test,\n\t\t\t\t\t\tbrowser: {\n\t\t\t\t\t\t\t...browser,\n\t\t\t\t\t\t\tinstances: browser.instances.map((instance) => ({\n\t\t\t\t\t\t\t\t...instance,\n\t\t\t\t\t\t\t\tname: instance.name ?? `${label} (${instance.browser})`,\n\t\t\t\t\t\t\t})),\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t: merged\n\tif (named.plugins === undefined || effective === undefined) return named\n\tconst candidates = [...(effective.plugins ?? [])]\n\tconst bases = [...(base.plugins ?? [])]\n\t// A base plugin takes the first candidate of its own name that no earlier base plugin took, and\n\t// candidates of other names never compete for it, so its pick is the candidate whose rank among\n\t// its name equals the number of earlier base plugins sharing that name.\n\tconst chosen = bases.map((plugin, position) =>\n\t\tisNamedPlugin(plugin)\n\t\t\t? candidates\n\t\t\t\t\t.flatMap((candidate, index) =>\n\t\t\t\t\t\tisNamedPlugin(candidate) && candidate.name === plugin.name ? [index] : [],\n\t\t\t\t\t)\n\t\t\t\t\t.at(\n\t\t\t\t\t\tbases\n\t\t\t\t\t\t\t.slice(0, position)\n\t\t\t\t\t\t\t.filter((earlier) => isNamedPlugin(earlier) && earlier.name === plugin.name).length,\n\t\t\t\t\t)\n\t\t\t: undefined,\n\t)\n\treturn {\n\t\t...named,\n\t\tplugins: [\n\t\t\t...bases.map((plugin, position) => {\n\t\t\t\tconst index = chosen[position]\n\t\t\t\treturn index === undefined ? plugin : (candidates[index] ?? plugin)\n\t\t\t}),\n\t\t\t...candidates.filter((_, index) => !chosen.includes(index)),\n\t\t],\n\t}\n}\n\nfunction isNamedPlugin(plugin: PluginOption): plugin is { name: string } {\n\treturn (\n\t\ttypeof plugin === 'object' &&\n\t\tplugin !== null &&\n\t\t!Array.isArray(plugin) &&\n\t\t!('then' in plugin && typeof plugin.then === 'function') &&\n\t\t'name' in plugin &&\n\t\ttypeof plugin.name === 'string'\n\t)\n}\n\n{{factories}}export default defineConfig({\n\tresolve,\n\ttest: {\n{{projects}}\n\t},\n})\n";
|
|
1462
1494
|
}>;
|
|
1463
1495
|
factories: Readonly<{
|
|
1464
|
-
sheet: "export function sheetProject(name: string, override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\toptimizeDeps,\n\t\tpublicDir: false,\n\t\ttest: {\n\t\t\tname: { label: name, color: 'magenta' },\n\t\t\troot: resolveWorkspacePath('.'),\n\t\t\tisolate: false,\n\t\t\tsetupFiles: ['./tests/setup.ts', './tests/setupBrowser.ts', './tests/setupStyles.ts'],\n\t\t\tbrowser: {\n\t\t\t\tenabled: true,\n\t\t\t\tprovider: playwright(browserOptions),\n\t\t\t\tinstances: [{ browser: 'chromium', headless: true }],\n\t\t\t},\n\t\t\tfileParallelism: false,\n\t\t\tsequence: { groupOrder: 1 },\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1496
|
+
sheet: "export function sheetProject(name: string, override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\toptimizeDeps,\n\t\tpublicDir: false,\n\t\ttest: {\n\t\t\tname: { label: name, color: 'magenta' },\n\t\t\troot: resolveWorkspacePath('.'),\n\t\t\tisolate: false,\n\t\t\tsetupFiles: ['./tests/setup.ts', './tests/setupBrowser.ts', './tests/setupStyles.ts'],\n\t\t\tbrowser: {\n\t\t\t\tenabled: true,\n\t\t\t\tprovider: playwright(browserOptions),\n\t\t\t\tcommands,\n\t\t\t\tinstances: [{ browser: 'chromium', headless: true }],\n\t\t\t},\n\t\t\tfileParallelism: false,\n\t\t\tsequence: { groupOrder: 1 },\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1465
1497
|
src: Readonly<{
|
|
1466
1498
|
core: "export function srcCore(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\tpublicDir: false,\n\t\tbuild: {\n\t\t\temptyOutDir: true,\n\t\t\tsourcemap: true,\n\t\t\tminify: false,\n\t\t\trolldownOptions: { onLog: enforceBuildLog },\n\t\t},\n\t\ttest: {\n\t\t\tname: { label: 'src:core', color: 'magenta' },\n\t\t\tinclude: ['tests/src/core/**/*.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts'],\n\t\t\tenvironment: 'node',\n\t\t\tbrowser: { enabled: false },\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1467
|
-
vue: "function resolveVueFilename(): string {\n\treturn 'index.js'\n}\n\nexport function srcVue(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\toptimizeDeps: { include: [...optimizeDeps.include, 'vue'] },\n\t\tpublicDir: false,\n\t\tplugins: [outputBoundary('dist/src/vue'), environmentBoundary('src/vue'), vue()],\n\t\tbuild: {\n\t\t\temptyOutDir: true,\n\t\t\tsourcemap: true,\n\t\t\tminify: false,\n\t\t\tlib: {\n\t\t\t\tentry: resolveWorkspacePath('src/vue/index.ts'),\n\t\t\t\tformats: ['es'],\n\t\t\t\tfileName: resolveVueFilename,\n\t\t\t},\n\t\t\toutDir: 'dist/src/vue',\n\t\t\trolldownOptions: { onLog: enforceBuildLog },\n\t\t},\n\t\ttest: {\n\t\t\tname: { label: 'src:vue', color: 'green' },\n\t\t\tinclude: ['tests/src/vue/**/*.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts', './tests/setupBrowser.ts'],\n\t\t\tbrowser: {\n\t\t\t\tenabled: true,\n\t\t\t\tprovider: playwright(browserOptions),\n\t\t\t\tinstances: [{ browser: 'chromium', headless: true }],\n\t\t\t},\n\t\t\tfileParallelism: false,\n\t\t\tsequence: { groupOrder: 1 },\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1468
|
-
browser: "function resolveBrowserFilename(): string {\n\treturn 'index.js'\n}\n\nexport function srcBrowser(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\toptimizeDeps,\n\t\tpublicDir: false,\n\t\tplugins: [outputBoundary('dist/src/browser'), environmentBoundary('src/browser')],\n\t\tbuild: {\n\t\t\temptyOutDir: true,\n\t\t\tsourcemap: true,\n\t\t\tminify: false,\n\t\t\tlib: {\n\t\t\t\tentry: resolveWorkspacePath('src/browser/index.ts'),\n\t\t\t\tformats: ['es'],\n\t\t\t\tfileName: resolveBrowserFilename,\n\t\t\t},\n\t\t\toutDir: 'dist/src/browser',\n\t\t\trolldownOptions: {\n\t\t\t\tonLog: enforceBuildLog,\n\t\t\t\t{{external}}\n{{output}}\n\t\t\t},\n\t\t},\n\t\ttest: {\n\t\t\tname: { label: 'src:browser', color: 'yellow' },\n\t\t\tinclude: ['tests/src/browser/**/*.test.ts'],\n{{exclude}}\t\t\tsetupFiles: ['./tests/setup.ts', './tests/setupBrowser.ts'],\n{{global}}\n\t\t\tbrowser: {\n\t\t\t\tenabled: true,\n\t\t\t\tprovider: playwright(browserOptions),\n\t\t\t\tinstances: [{ browser: 'chromium', headless: true }],\n\t\t\t},\n\t\t\tfileParallelism: false,\n\t\t\tsequence: { groupOrder: 1 },\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1499
|
+
vue: "function resolveVueFilename(): string {\n\treturn 'index.js'\n}\n\nexport function srcVue(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\toptimizeDeps: { include: [...optimizeDeps.include, 'vue'] },\n\t\tpublicDir: false,\n\t\tplugins: [outputBoundary('dist/src/vue'), environmentBoundary('src/vue'), vue()],\n\t\tbuild: {\n\t\t\temptyOutDir: true,\n\t\t\tsourcemap: true,\n\t\t\tminify: false,\n\t\t\tlib: {\n\t\t\t\tentry: resolveWorkspacePath('src/vue/index.ts'),\n\t\t\t\tformats: ['es'],\n\t\t\t\tfileName: resolveVueFilename,\n\t\t\t},\n\t\t\toutDir: 'dist/src/vue',\n\t\t\trolldownOptions: { onLog: enforceBuildLog },\n\t\t},\n\t\ttest: {\n\t\t\tname: { label: 'src:vue', color: 'green' },\n\t\t\tinclude: ['tests/src/vue/**/*.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts', './tests/setupBrowser.ts'],\n\t\t\tbrowser: {\n\t\t\t\tenabled: true,\n\t\t\t\tprovider: playwright(browserOptions),\n\t\t\t\tcommands,\n\t\t\t\tinstances: [{ browser: 'chromium', headless: true }],\n\t\t\t},\n\t\t\tfileParallelism: false,\n\t\t\tsequence: { groupOrder: 1 },\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1500
|
+
browser: "function resolveBrowserFilename(): string {\n\treturn 'index.js'\n}\n\nexport function srcBrowser(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\toptimizeDeps,\n\t\tpublicDir: false,\n\t\tplugins: [outputBoundary('dist/src/browser'), environmentBoundary('src/browser')],\n\t\tbuild: {\n\t\t\temptyOutDir: true,\n\t\t\tsourcemap: true,\n\t\t\tminify: false,\n\t\t\tlib: {\n\t\t\t\tentry: resolveWorkspacePath('src/browser/index.ts'),\n\t\t\t\tformats: ['es'],\n\t\t\t\tfileName: resolveBrowserFilename,\n\t\t\t},\n\t\t\toutDir: 'dist/src/browser',\n\t\t\trolldownOptions: {\n\t\t\t\tonLog: enforceBuildLog,\n\t\t\t\t{{external}}\n{{output}}\n\t\t\t},\n\t\t},\n\t\ttest: {\n\t\t\tname: { label: 'src:browser', color: 'yellow' },\n\t\t\tinclude: ['tests/src/browser/**/*.test.ts'],\n{{exclude}}\t\t\tsetupFiles: ['./tests/setup.ts', './tests/setupBrowser.ts'],\n{{global}}\n\t\t\tbrowser: {\n\t\t\t\tenabled: true,\n\t\t\t\tprovider: playwright(browserOptions),\n\t\t\t\tcommands,\n\t\t\t\tinstances: [{ browser: 'chromium', headless: true }],\n\t\t\t},\n\t\t\tfileParallelism: false,\n\t\t\tsequence: { groupOrder: 1 },\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1469
1501
|
server: "function resolveServerFilename(format: string): string {\n\treturn format === 'es' ? 'index.js' : 'index.cjs'\n}\n\nexport function srcServer(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\tpublicDir: false,\n\t\tplugins: [outputBoundary('dist/src/server'), environmentBoundary('src/server')],\n\t\tbuild: {\n\t\t\temptyOutDir: true,\n\t\t\tsourcemap: true,\n\t\t\tminify: false,\n\t\t\tlib: {\n\t\t\t\tentry: resolveWorkspacePath('src/server/index.ts'),\n\t\t\t\tformats: ['es', 'cjs'],\n\t\t\t\tfileName: resolveServerFilename,\n\t\t\t},\n\t\t\toutDir: 'dist/src/server',\n\t\t\ttarget: 'node22',\n\t\t\trolldownOptions: {\n\t\t\t\tonLog: enforceBuildLog,\n\t\t\t\tplatform: 'node',\n\t\t\t\t{{external}}\n{{output}}\n\t\t\t},\n\t\t},\n\t\ttest: {\n\t\t\tname: { label: 'src:server', color: 'red' },\n\t\t\tinclude: ['tests/src/server/**/*.test.ts'],\n{{exclude}}\t\t\tsetupFiles: ['./tests/setup.ts', './tests/setupServer.ts'],\n\t\t\tenvironment: 'node',\n\t\t\tbrowser: { enabled: false },\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1470
1502
|
bin: "function resolveBinFilename(): string {\n\treturn 'main.js'\n}\n\nfunction resolveBinExternal(id: string): boolean {\n\treturn id.startsWith('@src/') || resolveExternal(id, { peers, refused: [], siblings: [] })\n}\n\nexport function srcBin(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\tpublicDir: false,\n\t\tplugins: [outputBoundary('dist/bin')],\n\t\tbuild: {\n\t\t\temptyOutDir: true,\n\t\t\tsourcemap: true,\n\t\t\tminify: false,\n\t\t\tlib: {\n\t\t\t\tentry: resolveWorkspacePath('src/bin/main.ts'),\n\t\t\t\tformats: ['es'],\n\t\t\t\tfileName: resolveBinFilename,\n\t\t\t},\n\t\t\toutDir: 'dist/bin',\n\t\t\ttarget: 'node22',\n\t\t\trolldownOptions: {\n\t\t\t\tonLog: enforceBuildLog,\n\t\t\t\texternal: resolveBinExternal,\n\t\t\t},\n\t\t},\n\t\ttest: {\n\t\t\tname: { label: 'src:bin', color: 'yellow' },\n\t\t\tinclude: ['tests/src/bin/**/*.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts', './tests/setupServer.ts'],\n\t\t\tenvironment: 'node',\n\t\t\tbrowser: { enabled: false },\n\t\t\t// A bin test drives the real executable over a real temporary repository, so it\n\t\t\t// spends seconds in process startup and filesystem work rather than milliseconds.\n\t\t\t// Vitest's five-second default clears one alone and times out under a full suite.\n\t\t\ttestTimeout: 15_000,\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1471
1503
|
}>;
|
|
1472
1504
|
app: Readonly<{
|
|
1473
1505
|
core: "export function appCore(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\tpublicDir: false,\n\t\tplugins: [environmentBoundary('app/core')],\n\t\ttest: {\n\t\t\tname: { label: 'app:core', color: 'cyan' },\n\t\t\tinclude: ['tests/app/core/**/*.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts'],\n\t\t\tenvironment: 'node',\n\t\t\tbrowser: { enabled: false },\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1474
|
-
browser: "export function appBrowser(override?: UserConfig): UserConfig {\n\tconst output = 'dist/app/browser'\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\toptimizeDeps,\n\t\tplugins: [outputBoundary(output), environmentBoundary('app/browser')],\n\t\troot: resolveWorkspacePath('app/browser'),\n\t\tpublicDir: false,\n\t\tbuild: {\n\t\t\tassetsInlineLimit: 0,\n\t\t\temptyOutDir: true,\n\t\t\toutDir: resolveWorkspacePath(output),\n\t\t\trolldownOptions: {\n\t\t\t\tonLog: enforceBuildLog,\n\t\t\t\tinput: resolveWorkspacePath('app/browser/index.html'),\n\t\t\t},\n\t\t},\n\t\ttest: {\n\t\t\tname: { label: 'app:browser', color: 'blue' },\n\t\t\troot: resolveWorkspacePath('.'),\n\t\t\tdir: resolveWorkspacePath('.'),\n\t\t\tinclude: ['tests/app/browser/**/*.test.ts'],\n{{journeyExclude}}\t\t\tsetupFiles: ['./tests/setup.ts', './tests/setupBrowser.ts'],\n\t\t\tbrowser: {\n\t\t\t\tenabled: true,\n\t\t\t\tprovider: playwright(browserOptions),\n\t\t\t\tinstances: [{ browser: 'chromium', headless: true }],\n\t\t\t},\n\t\t\tfileParallelism: false,\n\t\t\tsequence: { groupOrder: 1 },\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n{{showcaseFactory}}{{journeyFactory}}";
|
|
1506
|
+
browser: "export function appBrowser(override?: UserConfig): UserConfig {\n\tconst output = 'dist/app/browser'\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\toptimizeDeps,\n\t\tplugins: [outputBoundary(output), environmentBoundary('app/browser')],\n\t\troot: resolveWorkspacePath('app/browser'),\n\t\tpublicDir: false,\n\t\tbuild: {\n\t\t\tassetsInlineLimit: 0,\n\t\t\temptyOutDir: true,\n\t\t\toutDir: resolveWorkspacePath(output),\n\t\t\trolldownOptions: {\n\t\t\t\tonLog: enforceBuildLog,\n\t\t\t\tinput: resolveWorkspacePath('app/browser/index.html'),\n\t\t\t},\n\t\t},\n\t\ttest: {\n\t\t\tname: { label: 'app:browser', color: 'blue' },\n\t\t\troot: resolveWorkspacePath('.'),\n\t\t\tdir: resolveWorkspacePath('.'),\n\t\t\tinclude: ['tests/app/browser/**/*.test.ts'],\n{{journeyExclude}}\t\t\tsetupFiles: ['./tests/setup.ts', './tests/setupBrowser.ts'],\n\t\t\tbrowser: {\n\t\t\t\tenabled: true,\n\t\t\t\tprovider: playwright(browserOptions),\n\t\t\t\tcommands,\n\t\t\t\tinstances: [{ browser: 'chromium', headless: true }],\n\t\t\t},\n\t\t\tfileParallelism: false,\n\t\t\tsequence: { groupOrder: 1 },\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n{{showcaseFactory}}{{journeyFactory}}";
|
|
1475
1507
|
vue: "export function appVue(override?: UserConfig): UserConfig {\n\tconst output = 'dist/app/vue'\n\tconst browser = appBrowser()\n\tconst project: UserConfig = {\n\t\t...browser,\n\t\toptimizeDeps: { include: [...optimizeDeps.include, 'vue'] },\n\t\tplugins: [outputBoundary(output), environmentBoundary('app/vue'), vue()],\n\t\troot: resolveWorkspacePath('app/vue'),\n\t\tbuild: {\n\t\t\t...browser.build,\n\t\t\toutDir: resolveWorkspacePath(output),\n\t\t\trolldownOptions: {\n\t\t\t\t...browser.build?.rolldownOptions,\n\t\t\t\tinput: resolveWorkspacePath('app/vue/index.html'),\n\t\t\t},\n\t\t},\n\t\ttest: {\n\t\t\t...browser.test,\n\t\t\tname: { label: 'app:vue', color: 'magenta' },\n\t\t\tbrowser: {\n\t\t\t\t...browser.test?.browser,\n\t\t\t\tinstances: (browser.test?.browser?.instances ?? []).map(\n\t\t\t\t\t({ name: _name, ...instance }) => instance,\n\t\t\t\t),\n\t\t\t},\n\t\t\tinclude: ['tests/app/vue/**/*.test.ts'],\n{{journeyExclude}}\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1476
1508
|
journey: "\n// Replace the journey fields directly: merging would concatenate the ordinary include\n// and retain the exclusion of the journey suite.\nexport function appJourney(\n\tvariant: JourneyVariant,\n\tvariants: readonly JourneyVariant[],\n\tmode?: string,\n): UserConfig {\n\tconst application = resolveApplication(mode, applications)\n\tconst browser = applications[application]()\n\tconst project: UserConfig = {\n\t\t...browser,\n\t\ttest: {\n\t\t\t...browser.test,\n\t\t\tname: { label: `journey:${variant.name}`, color: 'green' },\n\t\t\tinclude: [`tests/app/${application}/integration.test.ts`],\n\t\t\texclude: [],\n\t\t\tprovide: { variant: variant.name, variants, capture },\n\t\t\tbrowser: {\n\t\t\t\t...browser.test?.browser,\n\t\t\t\tenabled: true,\n\t\t\t\tviewport: { width: variant.width, height: variant.height },\n\t\t\t\tinstances: (browser.test?.browser?.instances ?? []).map(\n\t\t\t\t\t({ name: _name, ...instance }) => instance,\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t}\n\treturn mergeOverride(project)\n}\n";
|
|
1477
1509
|
showcase: "\nconst showcaseStamp: PluginOption = {\n\tname: 'orkestrel-showcase-html',\n\tenforce: 'post',\n\tgenerateBundle(_, bundle) {\n\t\tfor (const file of Object.values(bundle)) {\n\t\t\tif (\n\t\t\t\tfile.type === 'asset' &&\n\t\t\t\ttypeof file.source === 'string' &&\n\t\t\t\tfile.fileName.endsWith('.html')\n\t\t\t) {\n\t\t\t\tfile.source = stampPage(file.source)\n\t\t\t}\n\t\t}\n\t},\n}\n\nfunction createShowcaseNaming(application: string): PluginOption {\n\treturn {\n\t\tname: 'orkestrel-showcase-name',\n\t\tenforce: 'post',\n\t\twriteBundle(options) {\n\t\t\tif (options.dir === undefined) throw new Error('The showcase output is absent.')\n\t\t\trenameSync(\n\t\t\t\tresolvePath(options.dir, 'index.html'),\n\t\t\t\tresolvePath(options.dir, application + '.html'),\n\t\t\t)\n\t\t},\n\t}\n}\n\nexport function appShowcase(mode: string, override?: UserConfig): UserConfig {\n\tconst application = resolveApplication(mode, applications)\n\tconst output = 'showcase'\n\tconst showcase: UserConfig = {\n\t\tplugins: [\n\t\t\toutputBoundary(output),\n\t\t\tviteSingleFile({\n\t\t\t\tremoveViteModuleLoader: true,\n\t\t\t\tuseRecommendedBuildConfig: true,\n\t\t\t}),\n\t\t\tshowcaseStamp,\n\t\t\tcreateShowcaseNaming(application),\n\t\t],\n\t\tbuild: {\n\t\t\t// The `appBrowser` factory sets `assetsInlineLimit` to 0, so every asset becomes\n\t\t\t// its own file, and 4096 is Vite's own default put back. The `viteSingleFile`\n\t\t\t// plugin overwrites the value while the `useRecommendedBuildConfig` option stays\n\t\t\t// true, so this line takes effect only in a workspace that turns that option off.\n\t\t\tassetsInlineLimit: 4096,\n\t\t\tcssMinify: 'lightningcss',\n\t\t\temptyOutDir: false,\n\t\t\tminify: 'oxc',\n\t\t\tmodulePreload: false,\n\t\t\toutDir: resolveWorkspacePath(output),\n\t\t\treportCompressedSize: false,\n\t\t\tsourcemap: false,\n\t\t\ttarget: 'esnext',\n\t\t},\n\t}\n\treturn applications[application](mergeOverride(showcase, override))\n}\n";
|
|
@@ -1480,11 +1512,12 @@ export declare class Compiler implements CompilerInterface {
|
|
|
1480
1512
|
policy: "export function policy(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\ttest: {\n\t\t\tname: { label: 'policy', color: 'white' },\n\t\t\tinclude: ['tests/policy.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts'],\n\t\t\tenvironment: 'node',\n\t\t\tbrowser: { enabled: false },\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1481
1513
|
config: "export function config(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\ttest: {\n\t\t\tname: { label: 'config', color: 'yellow' },\n\t\t\tinclude: ['tests/config.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts'],\n\t\t\tenvironment: 'node',\n\t\t\tbrowser: { enabled: false },\n\t\t\t// A config test validates every target wrapper, spawns the real linter twice under\n\t\t\t// 15-second child caps, and rolls one face up through the compiler and the extractor it\n\t\t\t// spawns, so this budget clears the capped pair with room for a contended host.\n\t\t\ttestTimeout: 60_000,\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1482
1514
|
setup: "export function setup(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\ttest: {\n\t\t\tname: { label: 'setup', color: 'white' },\n\t\t\tinclude: ['tests/setup*.test.ts'],\n\t\t\texclude: ['tests/setupBrowser.test.ts', 'tests/setupStyles.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts'],\n\t\t\tpool: 'threads',\n\t\t\tisolate: false,\n\t\t\tenvironment: 'node',\n\t\t\tbrowser: { enabled: false },\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1483
|
-
browser: "export function setupBrowser(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\t{{optimization}},\n{{plugins}}\t\ttest: {\n\t\t\tname: { label: 'setup:browser', color: 'blue' },\n\t\t\tinclude: ['tests/setupBrowser.test.ts', 'tests/setupStyles.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts', './tests/setupBrowser.ts'],\n{{global}}\t\t\tbrowser: {\n\t\t\t\tenabled: true,\n\t\t\t\tprovider: playwright(browserOptions),\n\t\t\t\tinstances: [{ browser: 'chromium', headless: true }],\n\t\t\t},\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1515
|
+
browser: "export function setupBrowser(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\t{{optimization}},\n{{plugins}}\t\ttest: {\n\t\t\tname: { label: 'setup:browser', color: 'blue' },\n\t\t\tinclude: ['tests/setupBrowser.test.ts', 'tests/setupStyles.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts', './tests/setupBrowser.ts'],\n{{global}}\t\t\tbrowser: {\n\t\t\t\tenabled: true,\n\t\t\t\tprovider: playwright(browserOptions),\n\t\t\t\tcommands,\n\t\t\t\tinstances: [{ browser: 'chromium', headless: true }],\n\t\t\t},\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1484
1516
|
guides: "export function guides(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\ttest: {\n\t\t\tname: { label: 'guides', color: 'green' },\n\t\t\tinclude: ['tests/guides.test.ts'],\n\t\t\texclude: ['tests/src/**/*.test.ts', 'tests/app/**/*.test.ts', 'tests/setup.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts'],\n\t\t\tenvironment: 'node',\n\t\t\tbrowser: { enabled: false },\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1485
1517
|
skills: "// The skill scripts this package ships as canon, each driven as a child process against a\n// scratch fixture from its mirrored proof under `tests/agents/skills/<skill>/scripts/`. The\n// `configs/agents/tsconfig.skills.json` wrapper selects the project.\nexport function skills(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\ttest: {\n\t\t\tname: { label: 'skills', color: 'blue' },\n\t\t\tinclude: ['tests/agents/**/*.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts'],\n\t\t\tenvironment: 'node',\n\t\t\tbrowser: { enabled: false },\n\t\t\t// Each case spawns node on a script; a census case runs `vitest list` over this checkout.\n\t\t\ttestTimeout: 60_000,\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1486
1518
|
conformance: "// Where this package drifts from the official tooling it stays compatible with.\n// The subject is this package, so the proof is hermetic and stays in `npm test`.\nexport function conformance(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\ttest: {\n\t\t\tname: { label: 'conformance', color: 'magenta' },\n\t\t\tinclude: ['tests/conformance.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts', './tests/setupServer.ts'],\n\t\t\tpool: 'threads',\n\t\t\tisolate: false,\n\t\t\tenvironment: 'node',\n\t\t\tbrowser: { enabled: false },\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1487
1519
|
service: "// The caller prepares the live external services before this project.\n// `tests/setupService.ts` verifies readiness, and the project stays out of `npm test`\n// because a real service answers it.\nexport function service(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\ttest: {\n\t\t\tname: { label: 'service', color: 'red' },\n\t\t\tinclude: ['tests/service/**/*.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts', './tests/setupService.ts'],\n\t\t\tenvironment: 'node',\n\t\t\tbrowser: { enabled: false },\n\t\t\ttestTimeout: 120_000,\n\t\t\thookTimeout: 120_000,\n\t\t\tfileParallelism: false,\n\t\t\tsequence: { groupOrder: 1 },\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1520
|
+
studies: "// Authored study proofs run installed packages through bounded subprocesses and protocol fixtures,\n// so this project is isolated in its own gate script, test:studies.\nexport function studies(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\ttest: {\n\t\t\tname: { label: 'studies', color: 'red' },\n\t\t\tinclude: ['tests/studies/**/*.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts'],\n\t\t\tenvironment: 'node',\n\t\t\tbrowser: { enabled: false },\n\t\t\ttestTimeout: 120_000,\n\t\t\thookTimeout: 120_000,\n\t\t\tfileParallelism: false,\n\t\t\tsequence: { groupOrder: 1 },\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1488
1521
|
distribution: "export function distribution(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\ttest: {\n\t\t\tname: { label: 'distribution', color: 'cyan' },\n\t\t\tinclude: ['tests/distribution.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts'],\n\t\t\tenvironment: 'node',\n\t\t\ttestTimeout: 120_000,\n\t\t\thookTimeout: 120_000,\n\t\t\tfileParallelism: false,\n\t\t\tsequence: { groupOrder: 1 },\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1489
1522
|
probe: "// A workbench, not a proof. No gate selects this project. Run in test mode by the\n// `test:probe` script, it collects `tmp/probes/**/*.test.ts`. Run in benchmark mode by the\n// `test:bench` script, the same workbench also collects `tests/**/*.test.ts` for a `bench` block,\n// so a suite may carry a bench beside its ordinary tests without a second project. The mode\n// guard around each `bench` call keeps it out of test mode, so it never executes there.\nexport function probe(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\ttest: {\n\t\t\tname: { label: 'probe', color: 'black' },\n\t\t\tinclude: ['tmp/probes/**/*.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts'],\n\t\t\tenvironment: 'node',\n\t\t\tbrowser: { enabled: false },\n\t\t\tfileParallelism: false,\n\t\t\tsequence: { groupOrder: 1 },\n\t\t\tpool: 'threads',\n\t\t\tbenchmark: { include: ['tmp/probes/**/*.test.ts', 'tests/**/*.test.ts'] },\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1490
1523
|
integration: Readonly<{
|
|
@@ -1528,7 +1561,8 @@ export declare class Compiler implements CompilerInterface {
|
|
|
1528
1561
|
journey: "import type { JourneyVariant } from '@orkestrel/test'\nimport { defineConfig } from 'vitest/config'\nimport { appJourney } from '../../vite.config.ts'\n\n// Rename and extend these viewports for the application. Apply themes through its interface.\nconst VARIANTS: readonly JourneyVariant[] = Object.freeze([\n\t{ name: 'desktop', width: 1280, height: 800 },\n\t{ name: 'compact', width: 390, height: 844 },\n])\n\nexport default defineConfig(({ mode }) => ({\n\ttest: {\n\t\tprojects: VARIANTS.map((variant) => () => appJourney(variant, VARIANTS, mode)),\n\t},\n}))\n";
|
|
1529
1562
|
}>;
|
|
1530
1563
|
}>;
|
|
1531
|
-
browsers: "// A generated browser workspace resolves its own Chromium here rather than in\n// `configs/helpers.ts`, because that leaf is vendored byte-identical to every\n// workspace and most of them declare no `playwright` to import.\n\nimport type { PlaywrightProviderOptions } from '@vitest/browser-playwright'\nimport { chromium } from 'playwright'\nimport { accessSync, constants as FS_CONSTANTS, globSync, readdirSync, statSync } from 'node:fs'\nimport { basename, dirname, join, resolve as resolvePath } from 'node:path'\n\n/**\n * Lists the Chromium executable layouts inside a `chromium-<revision>` browsers-directory\n * entry, per platform.\n *\n * @remarks\n * The current Playwright build ships Chrome for Testing on macOS. The trailing `Chromium.app`\n * layouts are what earlier builds shipped, so the list spans Playwright versions instead of\n * pinning to the installed one.\n */\nexport const CHROMIUM_LAYOUTS = Object.freeze([\n\t'chrome-linux/chrome',\n\t'chrome-linux64/chrome',\n\t'chrome-win/chrome.exe',\n\t'chrome-win64/chrome.exe',\n\t'chrome-mac-x64/Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing',\n\t'chrome-mac-arm64/Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing',\n\t'chrome-mac/Chromium.app/Contents/MacOS/Chromium',\n\t'chrome-mac-arm64/Chromium.app/Contents/MacOS/Chromium',\n])\n\n/** Matches the `chromium-<revision>` entry name Playwright installs one managed build into. */\nexport const CHROMIUM_ENTRY_PATTERN = /^chromium-\\d+$/\n\n/** Matches the revision number carried by any path containing a `chromium-<revision>` segment. */\nexport const CHROMIUM_REVISION_PATTERN = /chromium-(\\d+)/\n\n/** Names the directory a managed Linux container installs its bundled Playwright browsers into. */\nexport const BUNDLED_BROWSERS_ROOT = '/opt/pw-browsers'\n\n/**\n * Lists the bundled Chromium layouts under the managed-container browsers root, as glob patterns.\n *\n * @remarks\n * The revision directory and its inner layout both drift across Playwright builds, and the\n * container also carries a top-level `chromium` alias, so every known shape is globbed.\n */\nexport const BUNDLED_CHROMIUM_LAYOUTS = Object.freeze([\n\t'chromium',\n\t'chromium-*/chrome-linux64/chrome',\n\t'chromium-*/chrome-linux/chrome',\n])\n\n/** Lists the stable Playwright Chromium channels and their standard executable layouts. */\nexport const SYSTEM_BROWSER_CHANNELS = Object.freeze([\n\tObject.freeze({\n\t\tchannel: 'chrome',\n\t\tlayouts: Object.freeze({\n\t\t\tlinux: '/opt/google/chrome/chrome',\n\t\t\tdarwin: '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',\n\t\t\twin32: Object.freeze(['Google', 'Chrome', 'Application', 'chrome.exe']),\n\t\t}),\n\t}),\n\tObject.freeze({\n\t\tchannel: 'msedge',\n\t\tlayouts: Object.freeze({\n\t\t\tlinux: '/opt/microsoft/msedge/msedge',\n\t\t\tdarwin: '/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge',\n\t\t\twin32: Object.freeze(['Microsoft', 'Edge', 'Application', 'msedge.exe']),\n\t\t}),\n\t}),\n])\n\n/**\n * Determines whether a path identifies an executable regular file.\n *\n * @param path - The filesystem path to inspect.\n * @returns True if the path is a regular file with execute access; false otherwise.\n *\n * @example\n * ```ts\n * isBrowserExecutable('/opt/google/chrome/chrome')\n * ```\n */\nexport function isBrowserExecutable(path: string): boolean {\n\ttry {\n\t\tif (!statSync(path).isFile()) return false\n\t\taccessSync(path, FS_CONSTANTS.X_OK)\n\t\treturn true\n\t} catch {\n\t\treturn false\n\t}\n}\n\n/**\n * Orders two Chromium paths so the highest revision sorts first.\n *\n * @param left - The first path or directory entry to compare.\n * @param right - The second path or directory entry to compare.\n * @returns A negative number when `left` sorts first, positive when `right` does.\n *\n * @remarks\n * Revisions are numbers, so `chromium-1200` outranks `chromium-999` despite sorting below it\n * lexically. A path carrying no revision falls back to descending name order.\n *\n * @example\n * ```ts\n * ['chromium-999', 'chromium-1200'].sort(compareRevisions)\n * ```\n */\nexport function compareRevisions(left: string, right: string): number {\n\tconst leftRevision = CHROMIUM_REVISION_PATTERN.exec(left)?.[1]\n\tconst rightRevision = CHROMIUM_REVISION_PATTERN.exec(right)?.[1]\n\tif (leftRevision === undefined || rightRevision === undefined) return right.localeCompare(left)\n\treturn Number(rightRevision) - Number(leftRevision)\n}\n\n/**\n * Reads the executable path of Playwright's pinned Chromium revision.\n *\n * @returns The pinned executable path, or `undefined` when this platform has none.\n *\n * @remarks\n * Playwright throws rather than returning a path when the current platform carries no initialized\n * executable, and an unguarded call would fail configuration evaluation for every project.\n *\n * @example\n * ```ts\n * resolvePinnedBrowser()\n * ```\n */\nexport function resolvePinnedBrowser(): string | undefined {\n\ttry {\n\t\tconst pinned = chromium.executablePath()\n\t\treturn pinned.length === 0 ? undefined : pinned\n\t} catch {\n\t\treturn undefined\n\t}\n}\n\n/**\n * Resolves a launchable Playwright-managed Chromium executable: the pinned revision when installed,\n * otherwise a `chromium` / `chromium.exe` alias or any other `chromium-*` revision under the same\n * Playwright browsers directory. A pinned-revision miss is not Chromium absence — managed\n * containers ship one usable build, often behind a revision-agnostic alias, for many Playwright\n * versions.\n *\n * @param pinned - The executable path for Playwright's pinned Chromium revision.\n * @returns The managed executable path, or `undefined` when none is executable.\n *\n * @example\n * ```ts\n * resolveManagedBrowser('/root/.cache/ms-playwright/chromium-1234/chrome-linux64/chrome')\n * ```\n */\nexport function resolveManagedBrowser(pinned: string): string | undefined {\n\tif (isBrowserExecutable(pinned)) return pinned\n\tlet revisionRoot = dirname(pinned)\n\tfor (;;) {\n\t\tif (CHROMIUM_ENTRY_PATTERN.test(basename(revisionRoot))) break\n\t\tconst parent = dirname(revisionRoot)\n\t\tif (parent === revisionRoot) return undefined\n\t\trevisionRoot = parent\n\t}\n\tconst browsersRoot = dirname(revisionRoot)\n\tfor (const alias of ['chromium', 'chromium.exe']) {\n\t\tconst candidate = resolvePath(browsersRoot, alias)\n\t\tif (isBrowserExecutable(candidate)) return candidate\n\t}\n\tlet entries: readonly string[]\n\ttry {\n\t\tentries = readdirSync(browsersRoot)\n\t} catch {\n\t\treturn undefined\n\t}\n\tconst revisions = entries\n\t\t.filter((entry) => CHROMIUM_ENTRY_PATTERN.test(entry))\n\t\t.sort(compareRevisions)\n\tfor (const revision of revisions) {\n\t\tfor (const layout of CHROMIUM_LAYOUTS) {\n\t\t\tconst candidate = resolvePath(browsersRoot, revision, layout)\n\t\t\tif (isBrowserExecutable(candidate)) return candidate\n\t\t}\n\t}\n\treturn undefined\n}\n\n/**\n * Resolves the Chromium a managed Linux container bundles outside the Playwright cache.\n *\n * @param platform - The Node platform the container runs on.\n * @param root - The bundled browsers directory to search.\n * @returns The highest matching executable path, or `undefined` when none is executable.\n *\n * @example\n * ```ts\n * resolveBundledBrowser('linux', BUNDLED_BROWSERS_ROOT)\n * ```\n */\nexport function resolveBundledBrowser(platform: NodeJS.Platform, root: string): string | undefined {\n\tif (platform !== 'linux') return undefined\n\tfor (const layout of BUNDLED_CHROMIUM_LAYOUTS) {\n\t\tlet matches: readonly string[]\n\t\ttry {\n\t\t\tmatches = globSync(layout, { cwd: root })\n\t\t} catch {\n\t\t\treturn undefined\n\t\t}\n\t\tfor (const match of [...matches].sort(compareRevisions)) {\n\t\t\tconst candidate = resolvePath(root, match)\n\t\t\tif (isBrowserExecutable(candidate)) return candidate\n\t\t}\n\t}\n\treturn undefined\n}\n\n/**\n * Resolves the first installed stable system Chromium channel.\n *\n * @param platform - The Node platform whose standard layouts this call probes.\n * @param environment - The process environment supplying Windows installation roots.\n * @returns `chrome`, then `msedge`, or `undefined` when neither is executable.\n *\n * @example\n * ```ts\n * resolveSystemBrowser(process.platform, process.env)\n * ```\n */\nexport function resolveSystemBrowser(\n\tplatform: NodeJS.Platform,\n\tenvironment: NodeJS.ProcessEnv,\n): string | undefined {\n\tif (platform !== 'linux' && platform !== 'darwin' && platform !== 'win32') return undefined\n\tconst roots = new Set<string>()\n\tif (platform === 'win32') {\n\t\tfor (const root of [\n\t\t\tenvironment.LOCALAPPDATA,\n\t\t\tenvironment.PROGRAMFILES,\n\t\t\tenvironment['PROGRAMFILES(X86)'],\n\t\t]) {\n\t\t\tif (root !== undefined && root.length > 0) roots.add(root)\n\t\t}\n\t\tconst homeDrive = environment.HOMEDRIVE\n\t\tif (homeDrive !== undefined && homeDrive.length > 0) {\n\t\t\troots.add(join(homeDrive, 'Program Files'))\n\t\t\troots.add(join(homeDrive, 'Program Files (x86)'))\n\t\t}\n\t}\n\tfor (const browser of SYSTEM_BROWSER_CHANNELS) {\n\t\tif (platform === 'win32') {\n\t\t\tfor (const root of roots) {\n\t\t\t\tif (isBrowserExecutable(join(root, ...browser.layouts.win32))) return browser.channel\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tif (isBrowserExecutable(browser.layouts[platform])) return browser.channel\n\t}\n\treturn undefined\n}\n\n/**\n * Resolves Playwright provider options for Chromium on this host.\n *\n * @param pinned - The executable path for Playwright's pinned Chromium revision, when it has one.\n * @param platform - The Node platform whose standard layouts this call probes.\n * @param environment - The process environment supplying operator overrides and Windows roots.\n * @param root - The managed-container bundled browsers directory to search.\n * @returns Provider options naming an executable, a WebSocket endpoint, or a channel.\n *\n * @remarks\n * Precedence, most important first: `PLAYWRIGHT_EXECUTABLE_PATH`, `PLAYWRIGHT_WS_ENDPOINT`,\n * `PLAYWRIGHT_CHANNEL`, the managed Playwright Chromium, the container's bundled Chromium, a\n * verified system channel, then the platform default channel. An operator override outranks\n * discovery and is returned exactly as given: none of those environment values is checked\n * against the filesystem, because verifying an override would defeat the override. The pinned\n * managed revision outranks anything found on the host because it is deterministic. The installed\n * pinned revision returns empty options unless `PLAYWRIGHT_SCROLLBARS=classic` is set. Only a\n * discovered system channel is verified before it is named. The platform default is unverified\n * as well and exists only as a last resort: Windows takes `msedge`, which ships with the OS and\n * never collides with a foreground Chrome.\n *\n * Set `PLAYWRIGHT_SCROLLBARS=classic` only for runs that measure scrollbar compensation, never\n * for a standing gate. Every Chromium launch in that run omits Playwright's `--hide-scrollbars`\n * default argument so classic scrollbars can take layout space in every case. An empty or unset\n * value preserves the launch defaults; any other value throws an `Error`. Pairing `classic`\n * with `PLAYWRIGHT_WS_ENDPOINT` throws an `Error`, even with an executable override, because the\n * server owns the launch.\n *\n * The resolver and the gate cover Chromium alone. Reopen engine selection when another\n * Playwright engine is installed and launches on the host with a `captureFrame` reading\n * back at its declared size, or when a journey or style divergence is recorded.\n *\n * @example\n * ```ts\n * resolveBrowser(resolvePinnedBrowser(), process.platform, process.env)\n * ```\n */\nexport function resolveBrowser(\n\tpinned: string | undefined,\n\tplatform: NodeJS.Platform,\n\tenvironment: NodeJS.ProcessEnv,\n\troot: string = BUNDLED_BROWSERS_ROOT,\n): PlaywrightProviderOptions {\n\tconst scrollbars = environment.PLAYWRIGHT_SCROLLBARS\n\tif (scrollbars !== undefined && scrollbars.length > 0 && scrollbars !== 'classic') {\n\t\tthrow new Error('PLAYWRIGHT_SCROLLBARS must be classic or empty')\n\t}\n\tconst endpoint = environment.PLAYWRIGHT_WS_ENDPOINT\n\tif (scrollbars === 'classic' && endpoint !== undefined && endpoint.length > 0) {\n\t\tthrow new Error('PLAYWRIGHT_SCROLLBARS=classic cannot be used with PLAYWRIGHT_WS_ENDPOINT')\n\t}\n\tconst launch: PlaywrightProviderOptions['launchOptions'] =\n\t\tscrollbars === 'classic' ? { ignoreDefaultArgs: ['--hide-scrollbars'] } : {}\n\tconst executable = environment.PLAYWRIGHT_EXECUTABLE_PATH\n\tif (executable !== undefined && executable.length > 0) {\n\t\treturn { launchOptions: { executablePath: executable, ...launch } }\n\t}\n\tif (endpoint !== undefined && endpoint.length > 0) {\n\t\treturn { connectOptions: { wsEndpoint: endpoint } }\n\t}\n\tconst requested = environment.PLAYWRIGHT_CHANNEL\n\tif (requested !== undefined && requested.length > 0) {\n\t\treturn { launchOptions: { channel: requested, ...launch } }\n\t}\n\tconst managed = pinned === undefined ? undefined : resolveManagedBrowser(pinned)\n\tif (managed !== undefined) {\n\t\tif (managed === pinned) return scrollbars === 'classic' ? { launchOptions: launch } : {}\n\t\treturn { launchOptions: { executablePath: managed, ...launch } }\n\t}\n\tconst bundled = resolveBundledBrowser(platform, root)\n\tif (bundled !== undefined) return { launchOptions: { executablePath: bundled, ...launch } }\n\tconst fallback = platform === 'win32' ? 'msedge' : 'chrome'\n\treturn {\n\t\tlaunchOptions: { channel: resolveSystemBrowser(platform, environment) ?? fallback, ...launch },\n\t}\n}\n";
|
|
1564
|
+
browsers: "// A generated browser workspace resolves its own Chromium here rather than in\n// `configs/helpers.ts`, because that leaf is vendored byte-identical to every\n// workspace and most of them declare no `playwright` to import.\n\nimport type { PlaywrightProviderOptions } from '@vitest/browser-playwright'\nimport { chromium } from 'playwright'\nimport { accessSync, constants as FS_CONSTANTS, globSync, readdirSync, statSync } from 'node:fs'\nimport { basename, dirname, join, resolve as resolvePath } from 'node:path'\n\n/**\n * Lists the Chromium executable layouts inside a `chromium-<revision>` browsers-directory\n * entry, per platform.\n *\n * @remarks\n * The current Playwright build ships Chrome for Testing on macOS. The trailing `Chromium.app`\n * layouts are what earlier builds shipped, so the list spans Playwright versions instead of\n * pinning to the installed one.\n */\nexport const CHROMIUM_LAYOUTS = Object.freeze([\n\t'chrome-linux/chrome',\n\t'chrome-linux64/chrome',\n\t'chrome-win/chrome.exe',\n\t'chrome-win64/chrome.exe',\n\t'chrome-mac-x64/Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing',\n\t'chrome-mac-arm64/Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing',\n\t'chrome-mac/Chromium.app/Contents/MacOS/Chromium',\n\t'chrome-mac-arm64/Chromium.app/Contents/MacOS/Chromium',\n])\n\n/** Matches the `chromium-<revision>` entry name Playwright installs one managed build into. */\nexport const CHROMIUM_ENTRY_PATTERN = /^chromium-\\d+$/\n\n/** Matches the revision number carried by any path containing a `chromium-<revision>` segment. */\nexport const CHROMIUM_REVISION_PATTERN = /chromium-(\\d+)/\n\n/** Names the directory a managed Linux container installs its bundled Playwright browsers into. */\nexport const BUNDLED_BROWSERS_ROOT = '/opt/pw-browsers'\n\n/**\n * Lists the bundled Chromium layouts under the managed-container browsers root, as glob patterns.\n *\n * @remarks\n * The revision directory and its inner layout both drift across Playwright builds, and the\n * container also carries a top-level `chromium` alias, so every known shape is globbed.\n */\nexport const BUNDLED_CHROMIUM_LAYOUTS = Object.freeze([\n\t'chromium',\n\t'chromium-*/chrome-linux64/chrome',\n\t'chromium-*/chrome-linux/chrome',\n])\n\n/** Lists the stable Playwright Chromium channels and their standard executable layouts. */\nexport const SYSTEM_BROWSER_CHANNELS = Object.freeze([\n\tObject.freeze({\n\t\tchannel: 'chrome',\n\t\tlayouts: Object.freeze({\n\t\t\tlinux: '/opt/google/chrome/chrome',\n\t\t\tdarwin: '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',\n\t\t\twin32: Object.freeze(['Google', 'Chrome', 'Application', 'chrome.exe']),\n\t\t}),\n\t}),\n\tObject.freeze({\n\t\tchannel: 'msedge',\n\t\tlayouts: Object.freeze({\n\t\t\tlinux: '/opt/microsoft/msedge/msedge',\n\t\t\tdarwin: '/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge',\n\t\t\twin32: Object.freeze(['Microsoft', 'Edge', 'Application', 'msedge.exe']),\n\t\t}),\n\t}),\n])\n\n/**\n * Determines whether a path identifies an executable regular file.\n *\n * @param path - The filesystem path to inspect.\n * @returns True if the path is a regular file with execute access; false otherwise.\n *\n * @example\n * ```ts\n * isBrowserExecutable('/opt/google/chrome/chrome')\n * ```\n */\nexport function isBrowserExecutable(path: string): boolean {\n\ttry {\n\t\tif (!statSync(path).isFile()) return false\n\t\taccessSync(path, FS_CONSTANTS.X_OK)\n\t\treturn true\n\t} catch {\n\t\treturn false\n\t}\n}\n\n/**\n * Orders two Chromium paths so the highest revision sorts first.\n *\n * @param left - The first path or directory entry to compare.\n * @param right - The second path or directory entry to compare.\n * @returns A negative number when `left` sorts first, positive when `right` does.\n *\n * @remarks\n * Revisions are numbers, so `chromium-1200` outranks `chromium-999` despite sorting below it\n * lexically. A path carrying no revision falls back to descending name order.\n *\n * @example\n * ```ts\n * ['chromium-999', 'chromium-1200'].sort(compareRevisions)\n * ```\n */\nexport function compareRevisions(left: string, right: string): number {\n\tconst leftRevision = CHROMIUM_REVISION_PATTERN.exec(left)?.[1]\n\tconst rightRevision = CHROMIUM_REVISION_PATTERN.exec(right)?.[1]\n\tif (leftRevision === undefined || rightRevision === undefined) return right.localeCompare(left)\n\treturn Number(rightRevision) - Number(leftRevision)\n}\n\n/**\n * Reads the executable path of Playwright's pinned Chromium revision.\n *\n * @returns The pinned executable path, or `undefined` when this platform has none.\n *\n * @remarks\n * Playwright throws rather than returning a path when the current platform carries no initialized\n * executable, and an unguarded call would fail configuration evaluation for every project.\n *\n * @example\n * ```ts\n * resolvePinnedBrowser()\n * ```\n */\nexport function resolvePinnedBrowser(): string | undefined {\n\ttry {\n\t\tconst pinned = chromium.executablePath()\n\t\treturn pinned.length === 0 ? undefined : pinned\n\t} catch {\n\t\treturn undefined\n\t}\n}\n\n/**\n * Resolves a launchable Playwright-managed Chromium executable: the pinned revision when installed,\n * otherwise a `chromium` / `chromium.exe` alias or any other `chromium-*` revision under the same\n * Playwright browsers directory. A pinned-revision miss is not Chromium absence — managed\n * containers ship one usable build, often behind a revision-agnostic alias, for many Playwright\n * versions.\n *\n * @param pinned - The executable path for Playwright's pinned Chromium revision.\n * @returns The managed executable path, or `undefined` when none is executable.\n *\n * @example\n * ```ts\n * resolveManagedBrowser('/root/.cache/ms-playwright/chromium-1234/chrome-linux64/chrome')\n * ```\n */\nexport function resolveManagedBrowser(pinned: string): string | undefined {\n\tif (isBrowserExecutable(pinned)) return pinned\n\t// One `dirname` per path segment reaches the root from any path, and the nearest\n\t// ancestor named `chromium-<revision>` is the revision directory this build sits in.\n\tconst directory = dirname(pinned)\n\tconst ancestors = directory\n\t\t.split(/[\\\\/]/u)\n\t\t.reduce<string[]>((chain) => [...chain, dirname(chain.at(-1) ?? directory)], [directory])\n\tconst revisionRoot = ancestors.find((ancestor) => CHROMIUM_ENTRY_PATTERN.test(basename(ancestor)))\n\tif (revisionRoot === undefined) return undefined\n\tconst browsersRoot = dirname(revisionRoot)\n\tfor (const alias of ['chromium', 'chromium.exe']) {\n\t\tconst candidate = resolvePath(browsersRoot, alias)\n\t\tif (isBrowserExecutable(candidate)) return candidate\n\t}\n\ttry {\n\t\tconst revisions = readdirSync(browsersRoot)\n\t\t\t.filter((entry) => CHROMIUM_ENTRY_PATTERN.test(entry))\n\t\t\t.sort(compareRevisions)\n\t\tfor (const revision of revisions) {\n\t\t\tfor (const layout of CHROMIUM_LAYOUTS) {\n\t\t\t\tconst candidate = resolvePath(browsersRoot, revision, layout)\n\t\t\t\tif (isBrowserExecutable(candidate)) return candidate\n\t\t\t}\n\t\t}\n\t\treturn undefined\n\t} catch {\n\t\treturn undefined\n\t}\n}\n\n/**\n * Resolves the Chromium a managed Linux container bundles outside the Playwright cache.\n *\n * @param platform - The Node platform the container runs on.\n * @param root - The bundled browsers directory to search.\n * @returns The highest matching executable path, or `undefined` when none is executable.\n *\n * @example\n * ```ts\n * resolveBundledBrowser('linux', BUNDLED_BROWSERS_ROOT)\n * ```\n */\nexport function resolveBundledBrowser(platform: NodeJS.Platform, root: string): string | undefined {\n\tif (platform !== 'linux') return undefined\n\tfor (const layout of BUNDLED_CHROMIUM_LAYOUTS) {\n\t\ttry {\n\t\t\tfor (const match of globSync(layout, { cwd: root }).sort(compareRevisions)) {\n\t\t\t\tconst candidate = resolvePath(root, match)\n\t\t\t\tif (isBrowserExecutable(candidate)) return candidate\n\t\t\t}\n\t\t} catch {\n\t\t\treturn undefined\n\t\t}\n\t}\n\treturn undefined\n}\n\n/**\n * Resolves the first installed stable system Chromium channel.\n *\n * @param platform - The Node platform whose standard layouts this call probes.\n * @param environment - The process environment supplying Windows installation roots.\n * @returns `chrome`, then `msedge`, or `undefined` when neither is executable.\n *\n * @example\n * ```ts\n * resolveSystemBrowser(process.platform, process.env)\n * ```\n */\nexport function resolveSystemBrowser(\n\tplatform: NodeJS.Platform,\n\tenvironment: NodeJS.ProcessEnv,\n): string | undefined {\n\tif (platform !== 'linux' && platform !== 'darwin' && platform !== 'win32') return undefined\n\tconst roots = new Set(\n\t\tplatform === 'win32'\n\t\t\t? [\n\t\t\t\t\t...[\n\t\t\t\t\t\tenvironment.LOCALAPPDATA,\n\t\t\t\t\t\tenvironment.PROGRAMFILES,\n\t\t\t\t\t\tenvironment['PROGRAMFILES(X86)'],\n\t\t\t\t\t].flatMap((root) => (root !== undefined && root.length > 0 ? [root] : [])),\n\t\t\t\t\t...[environment.HOMEDRIVE].flatMap((homeDrive) =>\n\t\t\t\t\t\thomeDrive !== undefined && homeDrive.length > 0\n\t\t\t\t\t\t\t? [join(homeDrive, 'Program Files'), join(homeDrive, 'Program Files (x86)')]\n\t\t\t\t\t\t\t: [],\n\t\t\t\t\t),\n\t\t\t\t]\n\t\t\t: [],\n\t)\n\tfor (const browser of SYSTEM_BROWSER_CHANNELS) {\n\t\tif (platform === 'win32') {\n\t\t\tfor (const root of roots) {\n\t\t\t\tif (isBrowserExecutable(join(root, ...browser.layouts.win32))) return browser.channel\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tif (isBrowserExecutable(browser.layouts[platform])) return browser.channel\n\t}\n\treturn undefined\n}\n\n/**\n * Resolves Playwright provider options for Chromium on this host.\n *\n * @param pinned - The executable path for Playwright's pinned Chromium revision, when it has one.\n * @param platform - The Node platform whose standard layouts this call probes.\n * @param environment - The process environment supplying operator overrides and Windows roots.\n * @param root - The managed-container bundled browsers directory to search.\n * @returns Provider options naming an executable, a WebSocket endpoint, or a channel.\n *\n * @remarks\n * Precedence, most important first: `PLAYWRIGHT_EXECUTABLE_PATH`, `PLAYWRIGHT_WS_ENDPOINT`,\n * `PLAYWRIGHT_CHANNEL`, the managed Playwright Chromium, the container's bundled Chromium, a\n * verified system channel, then the platform default channel. An operator override outranks\n * discovery and is returned exactly as given: none of those environment values is checked\n * against the filesystem, because verifying an override would defeat the override. The pinned\n * managed revision outranks anything found on the host because it is deterministic. The installed\n * pinned revision returns empty options unless `PLAYWRIGHT_SCROLLBARS=classic` is set. Only a\n * discovered system channel is verified before it is named. The platform default is unverified\n * as well and exists only as a last resort: Windows takes `msedge`, which ships with the OS and\n * never collides with a foreground Chrome.\n *\n * Set `PLAYWRIGHT_SCROLLBARS=classic` only for runs that measure scrollbar compensation, never\n * for a standing gate. Every Chromium launch in that run omits Playwright's `--hide-scrollbars`\n * default argument so classic scrollbars can take layout space in every case. An empty or unset\n * value preserves the launch defaults; any other value throws an `Error`. Pairing `classic`\n * with `PLAYWRIGHT_WS_ENDPOINT` throws an `Error`, even with an executable override, because the\n * server owns the launch.\n *\n * The resolver and the gate cover Chromium alone. Reopen engine selection when another\n * Playwright engine is installed and launches on the host with a `captureFrame` reading\n * back at its declared size, or when a journey or style divergence is recorded.\n *\n * @example\n * ```ts\n * resolveBrowser(resolvePinnedBrowser(), process.platform, process.env)\n * ```\n */\nexport function resolveBrowser(\n\tpinned: string | undefined,\n\tplatform: NodeJS.Platform,\n\tenvironment: NodeJS.ProcessEnv,\n\troot: string = BUNDLED_BROWSERS_ROOT,\n): PlaywrightProviderOptions {\n\tconst scrollbars = environment.PLAYWRIGHT_SCROLLBARS\n\tif (scrollbars !== undefined && scrollbars.length > 0 && scrollbars !== 'classic') {\n\t\tthrow new Error('PLAYWRIGHT_SCROLLBARS must be classic or empty')\n\t}\n\tconst endpoint = environment.PLAYWRIGHT_WS_ENDPOINT\n\tif (scrollbars === 'classic' && endpoint !== undefined && endpoint.length > 0) {\n\t\tthrow new Error('PLAYWRIGHT_SCROLLBARS=classic cannot be used with PLAYWRIGHT_WS_ENDPOINT')\n\t}\n\tconst launch: PlaywrightProviderOptions['launchOptions'] =\n\t\tscrollbars === 'classic' ? { ignoreDefaultArgs: ['--hide-scrollbars'] } : {}\n\tconst executable = environment.PLAYWRIGHT_EXECUTABLE_PATH\n\tif (executable !== undefined && executable.length > 0) {\n\t\treturn { launchOptions: { executablePath: executable, ...launch } }\n\t}\n\tif (endpoint !== undefined && endpoint.length > 0) {\n\t\treturn { connectOptions: { wsEndpoint: endpoint } }\n\t}\n\tconst requested = environment.PLAYWRIGHT_CHANNEL\n\tif (requested !== undefined && requested.length > 0) {\n\t\treturn { launchOptions: { channel: requested, ...launch } }\n\t}\n\tconst managed = pinned === undefined ? undefined : resolveManagedBrowser(pinned)\n\tif (managed !== undefined) {\n\t\tif (managed === pinned) return scrollbars === 'classic' ? { launchOptions: launch } : {}\n\t\treturn { launchOptions: { executablePath: managed, ...launch } }\n\t}\n\tconst bundled = resolveBundledBrowser(platform, root)\n\tif (bundled !== undefined) return { launchOptions: { executablePath: bundled, ...launch } }\n\tconst fallback = platform === 'win32' ? 'msedge' : 'chrome'\n\treturn {\n\t\tlaunchOptions: { channel: resolveSystemBrowser(platform, environment) ?? fallback, ...launch },\n\t}\n}\n";
|
|
1565
|
+
commands: "import type { BrowserConfigOptions } from 'vitest/node'\n\nexport const commands: Readonly<NonNullable<BrowserConfigOptions['commands']>> = Object.freeze({})\n";
|
|
1532
1566
|
}>;
|
|
1533
1567
|
|
|
1534
1568
|
/** Names the official-tooling drift proof whose presence makes a workspace `conformance`. */
|
|
@@ -2111,6 +2145,33 @@ export declare class Compiler implements CompilerInterface {
|
|
|
2111
2145
|
*/
|
|
2112
2146
|
export declare function insertManifestDependencies(manifest: string, additions: DependencyPinSet): string | undefined;
|
|
2113
2147
|
|
|
2148
|
+
/**
|
|
2149
|
+
* Inserts dependencies into one section of package manifest text.
|
|
2150
|
+
*
|
|
2151
|
+
* @param manifest - The manifest text to compile, already known to be a JSON object.
|
|
2152
|
+
* @param section - The section the additions enter: `dependencies` or `devDependencies`.
|
|
2153
|
+
* @param dependencies - The names and ranges to declare; the section declares none of them.
|
|
2154
|
+
* @param present - If `true`, the manifest declares the section as an object; if `false`, it declares none.
|
|
2155
|
+
* @returns The manifest declaring every addition in the section, or `undefined` when the section
|
|
2156
|
+
* cannot be located as an object the text declares.
|
|
2157
|
+
*
|
|
2158
|
+
* @remarks
|
|
2159
|
+
* The one step {@link insertManifestDependencies} repeats per section. Each addition lands before
|
|
2160
|
+
* the first declared key that sorts after it, or after the last declared key when none does, and
|
|
2161
|
+
* copies the indentation of the section's first entry. An empty section takes its entries one
|
|
2162
|
+
* level inside the indentation of its opening line, and an absent section is created as one
|
|
2163
|
+
* top-level key beside its sibling, or last in the manifest object when the sibling is absent too.
|
|
2164
|
+
*
|
|
2165
|
+
* @example
|
|
2166
|
+
* ```ts
|
|
2167
|
+
* import { insertManifestSection } from '@orkestrel/scaffold'
|
|
2168
|
+
*
|
|
2169
|
+
* insertManifestSection('{"dependencies":{}}', 'dependencies', [{ name: 'vite', range: '^8' }], true)
|
|
2170
|
+
* // '{"dependencies":{"vite": "^8"}}'
|
|
2171
|
+
* ```
|
|
2172
|
+
*/
|
|
2173
|
+
export declare function insertManifestSection(manifest: string, section: 'dependencies' | 'devDependencies', dependencies: readonly Dependency[], present: boolean): string | undefined;
|
|
2174
|
+
|
|
2114
2175
|
/**
|
|
2115
2176
|
* Names the cross-environment composition proof whose presence makes a workspace
|
|
2116
2177
|
* `integration`.
|
|
@@ -2637,6 +2698,37 @@ export declare class Compiler implements CompilerInterface {
|
|
|
2637
2698
|
*/
|
|
2638
2699
|
export declare const isSurface: Guard<Surface>;
|
|
2639
2700
|
|
|
2701
|
+
/**
|
|
2702
|
+
* Yields the answer to each value of a source and ends after the first refused answer.
|
|
2703
|
+
*
|
|
2704
|
+
* @param source - The values to answer, requested one at a time as the answers are read.
|
|
2705
|
+
* @param answer - Answers one value, or returns `undefined` to refuse it.
|
|
2706
|
+
* @returns A generator of the answers in source order, whose last answer is the first refusal when
|
|
2707
|
+
* the source holds one.
|
|
2708
|
+
* @throws Thrown when `answer` throws for a value, with that error, or when closing `source` after
|
|
2709
|
+
* a refusal throws, with the close's error.
|
|
2710
|
+
*
|
|
2711
|
+
* @remarks
|
|
2712
|
+
* The body is a `for…of` loop, so the source's iterator is requested once, when the first answer
|
|
2713
|
+
* is read, and stepped only as the answers are read: a length the source reports never bounds the
|
|
2714
|
+
* read, a hole reads as an `undefined` value, and an infinite source is read as far as the first
|
|
2715
|
+
* refusal. The iterator is closed after a refusal with a normal completion, so a raising close
|
|
2716
|
+
* surfaces, and is closed when `answer` throws with a throw completion, so the error from `answer`
|
|
2717
|
+
* wins. An iterator that ends is left alone. A caller that stops at a refusal and keeps what came
|
|
2718
|
+
* before it reads the answers into a list and checks that none is `undefined`.
|
|
2719
|
+
*
|
|
2720
|
+
* @example
|
|
2721
|
+
* ```ts
|
|
2722
|
+
* import { iterateAnswers } from '@orkestrel/scaffold'
|
|
2723
|
+
*
|
|
2724
|
+
* const halve = (value: number): number | undefined => (value % 2 === 0 ? value / 2 : undefined)
|
|
2725
|
+
*
|
|
2726
|
+
* Array.from(iterateAnswers([2, 4, 5, 6], halve)).length // 3
|
|
2727
|
+
* Array.from(iterateAnswers([2, 4], halve)) // [1, 2]
|
|
2728
|
+
* ```
|
|
2729
|
+
*/
|
|
2730
|
+
export declare function iterateAnswers<TValue, TAnswer>(source: Iterable<TValue>, answer: (value: TValue) => TAnswer | undefined): Generator<TAnswer | undefined, void, undefined>;
|
|
2731
|
+
|
|
2640
2732
|
/** Names the Vite wrapper whose presence makes a workspace `journey`. */
|
|
2641
2733
|
export declare const JOURNEY_CONFIG_PATH = "configs/app/vite.journey.config.ts";
|
|
2642
2734
|
|
|
@@ -2664,6 +2756,20 @@ export declare class Compiler implements CompilerInterface {
|
|
|
2664
2756
|
readonly peer: readonly Dependency[];
|
|
2665
2757
|
}
|
|
2666
2758
|
|
|
2759
|
+
/**
|
|
2760
|
+
* Represents one in-place replacement of manifest text.
|
|
2761
|
+
*
|
|
2762
|
+
* @remarks
|
|
2763
|
+
* `start` and `end` bound the replaced bytes, with `end` exclusive, and `text` takes their
|
|
2764
|
+
* place. A writer collects its edits and lands them from the last offset to the first, so
|
|
2765
|
+
* each offset still names the text it was read from.
|
|
2766
|
+
*/
|
|
2767
|
+
export declare interface ManifestEdit {
|
|
2768
|
+
readonly start: number;
|
|
2769
|
+
readonly end: number;
|
|
2770
|
+
readonly text: string;
|
|
2771
|
+
}
|
|
2772
|
+
|
|
2667
2773
|
/**
|
|
2668
2774
|
* Describes the manifest regions a writing operation may change.
|
|
2669
2775
|
*
|
|
@@ -2728,6 +2834,23 @@ export declare class Compiler implements CompilerInterface {
|
|
|
2728
2834
|
*/
|
|
2729
2835
|
export declare function manifestToDependencies(manifest: string): ManifestDependencySet;
|
|
2730
2836
|
|
|
2837
|
+
/**
|
|
2838
|
+
* Represents one string or object brace found in manifest text.
|
|
2839
|
+
*
|
|
2840
|
+
* @remarks
|
|
2841
|
+
* `text` is the brace character or the quoted string with its quotes, `index` is
|
|
2842
|
+
* where it starts in the scanned text, and `depth` counts the objects open once
|
|
2843
|
+
* it is read, braces alone. `value` is set only for a string that a colon
|
|
2844
|
+
* follows, and is the offset of the first character after that colon and the
|
|
2845
|
+
* whitespace beside it, so the character at `value` begins the string's value.
|
|
2846
|
+
*/
|
|
2847
|
+
export declare interface ManifestToken {
|
|
2848
|
+
readonly text: string;
|
|
2849
|
+
readonly index: number;
|
|
2850
|
+
readonly depth: number;
|
|
2851
|
+
readonly value: number | undefined;
|
|
2852
|
+
}
|
|
2853
|
+
|
|
2731
2854
|
/**
|
|
2732
2855
|
* Projects a package manifest's text to its own name.
|
|
2733
2856
|
*
|
|
@@ -3440,6 +3563,30 @@ export declare class Compiler implements CompilerInterface {
|
|
|
3440
3563
|
*/
|
|
3441
3564
|
export declare function renderSkillPointer(canonical: string, name: string): string | undefined;
|
|
3442
3565
|
|
|
3566
|
+
/**
|
|
3567
|
+
* Replaces one npm override leaf in manifest text, inserting its absent ancestors.
|
|
3568
|
+
*
|
|
3569
|
+
* @param manifest - The JSON package manifest text, already known to be an object.
|
|
3570
|
+
* @param path - The object keys from the manifest root to the leaf, ending at the leaf's key.
|
|
3571
|
+
* @param range - The string the leaf must hold.
|
|
3572
|
+
* @returns The text carrying the leaf, or `undefined` for a duplicate selected key, a malformed
|
|
3573
|
+
* ancestor, or a non-string leaf.
|
|
3574
|
+
*
|
|
3575
|
+
* @remarks
|
|
3576
|
+
* The one step {@link replaceManifestOverrides} repeats per leaf. Absent ancestors and the leaf are
|
|
3577
|
+
* inserted after the last member of the deepest ancestor the text declares, and a leaf already
|
|
3578
|
+
* holding `range` keeps its original spelling. Every byte outside the edited path survives.
|
|
3579
|
+
*
|
|
3580
|
+
* @example
|
|
3581
|
+
* ```ts
|
|
3582
|
+
* import { replaceManifestOverride } from '@orkestrel/scaffold'
|
|
3583
|
+
*
|
|
3584
|
+
* replaceManifestOverride('{}', ['overrides', 'plugin@1.0.0', 'child'], '2.0.0')
|
|
3585
|
+
* // '{"overrides":{"plugin@1.0.0":{"child":"2.0.0"}}}'
|
|
3586
|
+
* ```
|
|
3587
|
+
*/
|
|
3588
|
+
export declare function replaceManifestOverride(manifest: string, path: readonly string[], range: string): string | undefined;
|
|
3589
|
+
|
|
3443
3590
|
/**
|
|
3444
3591
|
* Replaces selected npm override leaves while preserving every byte outside the edited path.
|
|
3445
3592
|
*
|
|
@@ -3621,6 +3768,32 @@ export declare class Compiler implements CompilerInterface {
|
|
|
3621
3768
|
readonly stages: readonly CompileRecord[];
|
|
3622
3769
|
}
|
|
3623
3770
|
|
|
3771
|
+
/**
|
|
3772
|
+
* Scans manifest text for its strings and object braces, in order.
|
|
3773
|
+
*
|
|
3774
|
+
* @param text - The manifest text to scan.
|
|
3775
|
+
* @returns One token per quoted string and per `{` or `}` outside a string, or
|
|
3776
|
+
* `undefined` when a string is never closed.
|
|
3777
|
+
*
|
|
3778
|
+
* @remarks
|
|
3779
|
+
* Native JSON validation owns syntax; this scan only locates the byte ranges an
|
|
3780
|
+
* in-place writer edits. A string is opaque, so a brace inside one is never read,
|
|
3781
|
+
* and a backslash escapes the character after it. Depth counts objects alone and
|
|
3782
|
+
* ignores arrays, exactly as the range writers count them, so a key nested inside
|
|
3783
|
+
* another object never reads as a top-level one. A string that a colon follows
|
|
3784
|
+
* carries `value`, the offset of the character after that colon and the
|
|
3785
|
+
* whitespace beside it.
|
|
3786
|
+
*
|
|
3787
|
+
* @example
|
|
3788
|
+
* ```ts
|
|
3789
|
+
* import { scanManifestTokens } from '@orkestrel/scaffold'
|
|
3790
|
+
*
|
|
3791
|
+
* scanManifestTokens('{"a": "b"}')?.length // 4
|
|
3792
|
+
* scanManifestTokens('{"a') // undefined
|
|
3793
|
+
* ```
|
|
3794
|
+
*/
|
|
3795
|
+
export declare function scanManifestTokens(text: string): readonly ManifestToken[] | undefined;
|
|
3796
|
+
|
|
3624
3797
|
/**
|
|
3625
3798
|
* Lists the guide paths a generated workspace starts with, frozen.
|
|
3626
3799
|
*
|
|
@@ -3841,6 +4014,17 @@ export declare class Compiler implements CompilerInterface {
|
|
|
3841
4014
|
*/
|
|
3842
4015
|
export declare function srcToRoot(src: readonly Environment[]): Environment | undefined;
|
|
3843
4016
|
|
|
4017
|
+
/**
|
|
4018
|
+
* Names the include the study project covers, where an exact-case `*.test.ts` file beneath
|
|
4019
|
+
* `tests/studies`, outside any `node_modules` or `.git` directory, makes a workspace `studies`.
|
|
4020
|
+
*
|
|
4021
|
+
* @remarks
|
|
4022
|
+
* The selector reads the include's population less Vitest's default exclude: an exact-case file
|
|
4023
|
+
* beneath `tests/studies`, nested or direct, whose name ends in `.test.ts`, outside any
|
|
4024
|
+
* `node_modules` or `.git` directory, which Vitest's default exclude never collects.
|
|
4025
|
+
*/
|
|
4026
|
+
export declare const STUDIES_TEST_INCLUDE = "tests/studies/**/*.test.ts";
|
|
4027
|
+
|
|
3844
4028
|
/** Lists the development dependencies the styles surface adds, frozen. */
|
|
3845
4029
|
export declare const STYLES_DEV_DEPENDENCIES: Readonly<Record<string, string>>;
|
|
3846
4030
|
|