@orkestrel/scaffold 0.0.62 → 0.0.64
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/README.md +18 -103
- package/dist/bin/main.js +95 -27
- package/dist/bin/main.js.map +1 -1
- package/dist/host/AGENTS.md +2 -2
- package/dist/host/CLAUDE.md +6 -0
- package/dist/host/agents/orchestration.md +23 -15
- package/dist/host/agents/skills/enterprise-bootstrap/references/bootstrap-reference.md +16 -16
- package/dist/host/agents/skills/enterprise-bootstrap/references/frontend-design.md +6 -6
- package/dist/host/agents/skills/enterprise-bootstrap/references/utilities.md +4 -4
- package/dist/host/agents/skills/orkestrel-debrief/references/field-testing.md +5 -5
- package/dist/host/agents/skills/orkestrel-falsify/references/reconcile.md +1 -1
- package/dist/host/agents/skills/orkestrel-publish/SKILL.md +15 -15
- package/dist/host/agents/skills/orkestrel-publish/references/wave.md +43 -17
- package/dist/host/agents/skills/orkestrel-publish/references/window.md +41 -16
- package/dist/host/claude/agents/orkestrel.md +56 -56
- package/dist/host/claude/agents/reviewer.md +13 -0
- package/dist/host/claude/rules/architecture.md +51 -45
- package/dist/host/claude/rules/documentation.md +18 -1
- package/dist/host/claude/rules/portability.md +2 -0
- package/dist/host/claude/rules/quality.md +1 -1
- package/dist/host/claude/rules/tests.md +12 -11
- package/dist/host/claude/rules/typescript.md +5 -0
- package/dist/host/claude/rules/workspace.md +23 -18
- package/dist/host/claude/rules/writing.md +4 -0
- package/dist/host/codex/agents/orkestrel.toml +3 -3
- package/dist/host/codex/agents/reviewer.toml +4 -2
- package/dist/host/configs/helpers.ts +311 -2
- package/dist/host/configs/policy.ts +1100 -51
- package/dist/host/dotfiles/oxlintrc.json +72 -1
- package/dist/host/guides/guide.md +749 -222
- package/dist/host/guides/scaffold.md +472 -378
- package/dist/host/manifest.json +34 -33
- package/dist/host/scripts/codex.sh +0 -0
- package/dist/host/scripts/cursor.sh +0 -0
- package/dist/host/scripts/deps.sh +0 -0
- package/dist/host/scripts/ollama.sh +0 -0
- package/dist/host/tests/config.test.ts +1200 -16
- package/dist/host/tests/policy.test.ts +157 -173
- package/dist/host/tests/setupPolicy.ts +522 -1007
- package/dist/src/core/index.cjs +373 -279
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +130 -120
- package/dist/src/core/index.d.ts +130 -120
- package/dist/src/core/index.js +373 -278
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/server/index.cjs +28 -21
- package/dist/src/server/index.cjs.map +1 -1
- package/dist/src/server/index.d.cts +38 -33
- package/dist/src/server/index.d.ts +38 -33
- package/dist/src/server/index.js +28 -21
- package/dist/src/server/index.js.map +1 -1
- package/package.json +17 -18
package/dist/src/core/index.js
CHANGED
|
@@ -3,8 +3,8 @@ import { fillTemplate } from "@orkestrel/template";
|
|
|
3
3
|
import { Emitter } from "@orkestrel/emitter";
|
|
4
4
|
var package_default = {
|
|
5
5
|
name: "@orkestrel/scaffold",
|
|
6
|
-
version: "0.0.
|
|
7
|
-
description: "Scaffold workspaces with
|
|
6
|
+
version: "0.0.64",
|
|
7
|
+
description: "Scaffold workspaces with commands: new, audit, repair, catalog, and overwrite.",
|
|
8
8
|
keywords: [
|
|
9
9
|
"audit",
|
|
10
10
|
"catalog",
|
|
@@ -73,7 +73,7 @@ var package_default = {
|
|
|
73
73
|
"test:src:bin": "vitest run --config vite.config.ts --no-cache --reporter=dot --project src:bin",
|
|
74
74
|
"test:policy": "vitest run --config vite.config.ts --no-cache --reporter=dot --project policy",
|
|
75
75
|
"test:config": "vitest run --config vite.config.ts --no-cache --reporter=dot --project config",
|
|
76
|
-
"test:guides": "
|
|
76
|
+
"test:guides": "node --experimental-strip-types tests/guides.test.ts",
|
|
77
77
|
"test:distribution": "vitest run --config vite.config.ts --no-cache --reporter=dot --project distribution",
|
|
78
78
|
"test:probe": "vitest run --config vite.config.ts --no-cache --reporter=verbose --project probe",
|
|
79
79
|
"test:bench": "vitest bench --config vite.config.ts --no-cache --project probe",
|
|
@@ -89,27 +89,26 @@ var package_default = {
|
|
|
89
89
|
"prepublishOnly": "npm run format:check && npm run lint:check && npm run check && npm run build && npm test && npm run test:distribution -- --mode release"
|
|
90
90
|
},
|
|
91
91
|
dependencies: {
|
|
92
|
-
"@orkestrel/console": "^0.0.
|
|
93
|
-
"@orkestrel/contract": "^0.0.
|
|
94
|
-
"@orkestrel/emitter": "^0.0.
|
|
95
|
-
"@orkestrel/markdown": "^0.0.
|
|
96
|
-
"@orkestrel/process": "^0.0.
|
|
97
|
-
"@orkestrel/template": "^0.0.
|
|
92
|
+
"@orkestrel/console": "^0.0.13",
|
|
93
|
+
"@orkestrel/contract": "^0.0.17",
|
|
94
|
+
"@orkestrel/emitter": "^0.0.10",
|
|
95
|
+
"@orkestrel/markdown": "^0.0.14",
|
|
96
|
+
"@orkestrel/process": "^0.0.11",
|
|
97
|
+
"@orkestrel/template": "^0.0.7"
|
|
98
98
|
},
|
|
99
99
|
devDependencies: {
|
|
100
100
|
"@microsoft/api-extractor": "^7.59.0",
|
|
101
|
-
"@orkestrel/guide": "^0.0.
|
|
102
|
-
"@orkestrel/html": "^0.0.
|
|
103
|
-
"@orkestrel/probe": "^0.0.
|
|
104
|
-
"@orkestrel/test": "^0.0.
|
|
105
|
-
"@types/node": "^26.
|
|
101
|
+
"@orkestrel/guide": "^0.0.17",
|
|
102
|
+
"@orkestrel/html": "^0.0.9",
|
|
103
|
+
"@orkestrel/probe": "^0.0.12",
|
|
104
|
+
"@orkestrel/test": "^0.0.14",
|
|
105
|
+
"@types/node": "^26.5.0",
|
|
106
106
|
"@vitest/browser-playwright": "^4.1.11",
|
|
107
|
-
"oxfmt": "^0.
|
|
108
|
-
"oxlint": "^1.
|
|
109
|
-
"playwright": "^1.
|
|
107
|
+
"oxfmt": "^0.67.0",
|
|
108
|
+
"oxlint": "^1.82.0",
|
|
109
|
+
"playwright": "^1.63.0",
|
|
110
110
|
"typescript": "^6.0.3",
|
|
111
111
|
"vite": "^8.2.2",
|
|
112
|
-
"vite-plugin-dts": "^5.0.3",
|
|
113
112
|
"vitest": "^4.1.11"
|
|
114
113
|
},
|
|
115
114
|
engines: { "node": ">=22.12.0" }
|
|
@@ -212,10 +211,11 @@ var BIN_ENTRY_PATH = "src/bin/main.ts";
|
|
|
212
211
|
* @remarks
|
|
213
212
|
* These are the files the fleet shares verbatim, and each target holds a copy
|
|
214
213
|
* of the paths it selects: the licence, the harness permission file, the
|
|
215
|
-
* session-start hooks, the shared policy
|
|
216
|
-
* the shared policy
|
|
217
|
-
* byte-identical root dotfiles, and the
|
|
218
|
-
* starts from. A directory entry vendors
|
|
214
|
+
* session-start hooks, the shared policy
|
|
215
|
+
* register, the shared policy proof, the shared policy plugin, the shared
|
|
216
|
+
* configuration leaf and its proof, the byte-identical root dotfiles, and the
|
|
217
|
+
* guide mirrors a generated workspace starts from. A directory entry vendors
|
|
218
|
+
* everything beneath it.
|
|
219
219
|
*
|
|
220
220
|
* A plan carries the subset its target selects, which is why the list is a
|
|
221
221
|
* candidate set rather than a plan: a workspace never mirrors its own guide.
|
|
@@ -224,16 +224,13 @@ var BIN_ENTRY_PATH = "src/bin/main.ts";
|
|
|
224
224
|
* its rules, its skills, its agent roles, its bench configuration, and its MCP
|
|
225
225
|
* registrations from {@link CANON_PATHS} inside the installed package, so no
|
|
226
226
|
* file scaffold leaves in a target names a path the target does not hold.
|
|
227
|
-
* `
|
|
227
|
+
* `blueprintToHostArtifacts` appends {@link CATALOG_AGENT_PATH} to what this list
|
|
228
228
|
* selects, which is what keeps the list itself disjoint from the canon.
|
|
229
229
|
*/
|
|
230
230
|
var HOST_PATHS = Object.freeze([
|
|
231
231
|
"LICENSE",
|
|
232
232
|
".claude/settings.json",
|
|
233
|
-
"scripts
|
|
234
|
-
"scripts/cursor.sh",
|
|
235
|
-
"scripts/codex.sh",
|
|
236
|
-
"scripts/ollama.sh",
|
|
233
|
+
"scripts",
|
|
237
234
|
"tests/setupPolicy.ts",
|
|
238
235
|
"tests/policy.test.ts",
|
|
239
236
|
"tests/config.test.ts",
|
|
@@ -272,7 +269,7 @@ var HOST_PATHS = Object.freeze([
|
|
|
272
269
|
*
|
|
273
270
|
* The plan claims paths inside the canon deliberately, and each has a reason.
|
|
274
271
|
* `blueprintToDocumentArtifacts` claims `AGENTS.md` and `CLAUDE.md` as this
|
|
275
|
-
* package's own template pointers. `
|
|
272
|
+
* package's own template pointers. `blueprintToHostArtifacts` claims
|
|
276
273
|
* {@link CATALOG_AGENT_PATH}, because the catalog verb refuses a target that
|
|
277
274
|
* lacks the file and repair restores its absence.
|
|
278
275
|
*
|
|
@@ -346,19 +343,19 @@ var ORCHESTRATION_PATH_PREFIXES = Object.freeze([
|
|
|
346
343
|
"scripts/"
|
|
347
344
|
]);
|
|
348
345
|
/**
|
|
349
|
-
* Lists the exact root
|
|
346
|
+
* Lists the exact root paths that wire an agent bench or own an orchestration directory, frozen.
|
|
350
347
|
*
|
|
351
348
|
* @remarks
|
|
352
|
-
* `.mcp.json` registers MCP servers for the harness.
|
|
353
|
-
*
|
|
349
|
+
* `.mcp.json` registers MCP servers for the harness. `scripts` is the owned
|
|
350
|
+
* directory whose members wire the development environment.
|
|
354
351
|
*/
|
|
355
|
-
var ORCHESTRATION_PATH_NAMES = Object.freeze([".mcp.json"]);
|
|
352
|
+
var ORCHESTRATION_PATH_NAMES = Object.freeze([".mcp.json", "scripts"]);
|
|
356
353
|
/**
|
|
357
354
|
* Names the agent file whose marker-bounded package table the catalog verb alone owns.
|
|
358
355
|
*
|
|
359
356
|
* @remarks
|
|
360
357
|
* A plan claims it at a canon path, because the catalog verb refuses a target
|
|
361
|
-
* that lacks the file. `
|
|
358
|
+
* that lacks the file. `blueprintToHostArtifacts` appends it to the vendored
|
|
362
359
|
* selection, and it reaches a release through the `.claude/agents` directory in
|
|
363
360
|
* {@link CANON_PATHS} rather than through {@link HOST_PATHS}, which is what
|
|
364
361
|
* keeps the two lists disjoint.
|
|
@@ -390,7 +387,7 @@ var CATALOG_CLOSING_MARKER = "<!-- /orkestrel:catalog -->";
|
|
|
390
387
|
var SERVICE_SCRIPT_PATH = "scripts/service.sh";
|
|
391
388
|
/** Names the shared Vitest global-setup module whose presence makes a workspace `global`. */
|
|
392
389
|
var GLOBAL_SETUP_PATH = "tests/setupGlobal.ts";
|
|
393
|
-
/** Names the guide-parity
|
|
390
|
+
/** Names the package-owned guide-parity entry used by `test:guides` and to select the `guides` project. */
|
|
394
391
|
var GUIDES_TEST_PATH = "tests/guides.test.ts";
|
|
395
392
|
/** Names the generated packed-package proof every publishing workspace is planned at. */
|
|
396
393
|
var DISTRIBUTION_TEST_PATH = "tests/distribution.test.ts";
|
|
@@ -548,13 +545,13 @@ var BASE_DEV_DEPENDENCIES = Object.freeze({
|
|
|
548
545
|
vitest: package_default.devDependencies.vitest
|
|
549
546
|
});
|
|
550
547
|
/**
|
|
551
|
-
* Lists the development dependencies that
|
|
552
|
-
*
|
|
548
|
+
* Lists the development dependencies that roll declarations up for published source.
|
|
549
|
+
*
|
|
550
|
+
* @remarks
|
|
551
|
+
* The toolchain runs the compiler it already installs as a command, emitting one declaration per
|
|
552
|
+
* module, and the extractor rolls that emit into the single file each published face ships.
|
|
553
553
|
*/
|
|
554
|
-
var DECLARATION_DEV_DEPENDENCIES = Object.freeze({
|
|
555
|
-
"@microsoft/api-extractor": package_default.devDependencies["@microsoft/api-extractor"],
|
|
556
|
-
"vite-plugin-dts": package_default.devDependencies["vite-plugin-dts"]
|
|
557
|
-
});
|
|
554
|
+
var DECLARATION_DEV_DEPENDENCIES = Object.freeze({ "@microsoft/api-extractor": package_default.devDependencies["@microsoft/api-extractor"] });
|
|
558
555
|
/** Lists the development dependencies a published browser `src` environment adds. */
|
|
559
556
|
var SOURCE_BROWSER_DEV_DEPENDENCIES = Object.freeze({
|
|
560
557
|
"@vitest/browser-playwright": package_default.devDependencies["@vitest/browser-playwright"],
|
|
@@ -895,9 +892,10 @@ export function appBrowser(): UserConfig {
|
|
|
895
892
|
setupFiles: ['./tests/setup.ts'],
|
|
896
893
|
environment: 'node',
|
|
897
894
|
browser: { enabled: false },
|
|
898
|
-
// A config test validates every target wrapper
|
|
899
|
-
// 15-second child caps,
|
|
900
|
-
|
|
895
|
+
// A config test validates every target wrapper, spawns the real linter twice under
|
|
896
|
+
// 15-second child caps, and rolls one face up through the compiler and the extractor it
|
|
897
|
+
// spawns, so this budget clears the capped pair with room for a contended host.
|
|
898
|
+
testTimeout: 60_000,
|
|
901
899
|
},
|
|
902
900
|
})
|
|
903
901
|
`,
|
|
@@ -1123,8 +1121,7 @@ export const probe = (): UserConfig => ({
|
|
|
1123
1121
|
vites: Object.freeze({
|
|
1124
1122
|
src: Object.freeze({
|
|
1125
1123
|
core: `import { defineConfig, mergeConfig } from 'vite'
|
|
1126
|
-
import
|
|
1127
|
-
import { environmentBoundary, outputBoundary } from '../helpers.js'
|
|
1124
|
+
import { declarationRollup, environmentBoundary, outputBoundary } from '../helpers.js'
|
|
1128
1125
|
import { peers, srcCore, resolveWorkspacePath } from '../../vite.config.ts'
|
|
1129
1126
|
|
|
1130
1127
|
export default defineConfig(
|
|
@@ -1133,17 +1130,9 @@ export default defineConfig(
|
|
|
1133
1130
|
plugins: [
|
|
1134
1131
|
outputBoundary('dist/src/core'),
|
|
1135
1132
|
environmentBoundary('src/core'),
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
extractorConfig: {
|
|
1140
|
-
compiler: {
|
|
1141
|
-
overrideTsconfig: {
|
|
1142
|
-
compilerOptions: { types: ['node'] },
|
|
1143
|
-
},
|
|
1144
|
-
},
|
|
1145
|
-
},
|
|
1146
|
-
},
|
|
1133
|
+
declarationRollup({
|
|
1134
|
+
project: resolveWorkspacePath('configs/src/tsconfig.core.json'),
|
|
1135
|
+
types: ['node'],
|
|
1147
1136
|
}),
|
|
1148
1137
|
],
|
|
1149
1138
|
build: {
|
|
@@ -1164,49 +1153,34 @@ export default defineConfig(
|
|
|
1164
1153
|
)
|
|
1165
1154
|
`,
|
|
1166
1155
|
browser: `import { defineConfig, mergeConfig } from 'vite'
|
|
1167
|
-
import
|
|
1156
|
+
import { declarationRollup, rewriteCoreSpecifier } from '../helpers.js'
|
|
1168
1157
|
import { srcBrowser, resolveWorkspacePath } from '../../vite.config.ts'
|
|
1169
1158
|
|
|
1170
|
-
//
|
|
1171
|
-
//
|
|
1172
|
-
// keeps each source module's own depth, so a module in a browser subfolder emits
|
|
1173
|
-
// one that leaves dist/src entirely. The following rewrite externalizes core
|
|
1174
|
-
// through the package's own published root export, on the final roll-up only.
|
|
1159
|
+
// The roll-up reaches src/core through a specifier the tarball does not carry, so the rewrite
|
|
1160
|
+
// externalizes core through the package's own published root export, on the final roll-up alone.
|
|
1175
1161
|
export default defineConfig(
|
|
1176
1162
|
mergeConfig(srcBrowser(), {
|
|
1177
1163
|
plugins: [
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
beforeWriteFile: (path, content) => ({
|
|
1182
|
-
content: /[\\\\/]dist[\\\\/]src[\\\\/]browser[\\\\/]index\\.d\\.ts$/.test(path)
|
|
1183
|
-
{{replacement}}
|
|
1184
|
-
: content,
|
|
1185
|
-
}),
|
|
1164
|
+
declarationRollup({
|
|
1165
|
+
project: resolveWorkspacePath('configs/src/tsconfig.browser.json'),
|
|
1166
|
+
rewrite: rewriteCoreSpecifier,
|
|
1186
1167
|
}),
|
|
1187
1168
|
],
|
|
1188
1169
|
}),
|
|
1189
1170
|
)
|
|
1190
1171
|
`,
|
|
1191
1172
|
server: `import { defineConfig, mergeConfig } from 'vite'
|
|
1192
|
-
import
|
|
1173
|
+
import { declarationRollup, rewriteCoreSpecifier } from '../helpers.js'
|
|
1193
1174
|
import { srcServer, resolveWorkspacePath } from '../../vite.config.ts'
|
|
1194
1175
|
|
|
1195
|
-
//
|
|
1196
|
-
//
|
|
1197
|
-
// following rewrite externalizes core through the package's own published root
|
|
1198
|
-
// export, on the final roll-up only.
|
|
1176
|
+
// The roll-up reaches src/core through a specifier the tarball does not carry, so the rewrite
|
|
1177
|
+
// externalizes core through the package's own published root export, on the final roll-up alone.
|
|
1199
1178
|
export default defineConfig(
|
|
1200
1179
|
mergeConfig(srcServer(), {
|
|
1201
1180
|
plugins: [
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
beforeWriteFile: (path, content) => ({
|
|
1206
|
-
content: /[\\\\/]dist[\\\\/]src[\\\\/]server[\\\\/]index\\.d\\.ts$/.test(path)
|
|
1207
|
-
{{replacement}}
|
|
1208
|
-
: content,
|
|
1209
|
-
}),
|
|
1181
|
+
declarationRollup({
|
|
1182
|
+
project: resolveWorkspacePath('configs/src/tsconfig.server.json'),
|
|
1183
|
+
rewrite: rewriteCoreSpecifier,
|
|
1210
1184
|
}),
|
|
1211
1185
|
],
|
|
1212
1186
|
}),
|
|
@@ -1643,14 +1617,20 @@ import {
|
|
|
1643
1617
|
statSync,
|
|
1644
1618
|
writeFileSync,
|
|
1645
1619
|
} from 'node:fs'
|
|
1646
|
-
{{transport}}import {
|
|
1620
|
+
{{transport}}import { createRequire } from 'node:module'
|
|
1621
|
+
import { tmpdir } from 'node:os'
|
|
1647
1622
|
import { dirname, join, resolve } from 'node:path'
|
|
1648
1623
|
import { fileURLToPath } from 'node:url'
|
|
1649
|
-
{{launcher}}import
|
|
1650
|
-
import { afterAll, describe, expect, it } from 'vitest'
|
|
1624
|
+
{{launcher}}import { afterAll, describe, expect, it } from 'vitest'
|
|
1651
1625
|
|
|
1652
1626
|
const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..')
|
|
1653
1627
|
const NPM = process.platform === 'win32' ? 'npm.cmd' : 'npm'
|
|
1628
|
+
// The compiler this workspace installs, run as a command rather than called in
|
|
1629
|
+
// process: the command and its plain-text diagnostics are the same across the
|
|
1630
|
+
// compiler majors this toolchain supports, and its in-process API is not. It is
|
|
1631
|
+
// resolved from the workspace under proof, so a consumer of the packed artifact is
|
|
1632
|
+
// checked by the same compiler that workspace's own \`check\` script runs.
|
|
1633
|
+
const TSC = createRequire(join(ROOT, 'package.json')).resolve('typescript/bin/tsc')
|
|
1654
1634
|
// Windows needs a shell to launch a \`.cmd\`: Node refuses one directly since the
|
|
1655
1635
|
// batch-argument hardening, and \`spawnSync\` returns \`EINVAL\` with a null status
|
|
1656
1636
|
// rather than an exit code a caller can read. Every following argument is a literal or
|
|
@@ -1667,6 +1647,12 @@ const RELEASE = import.meta.env.MODE === 'release'
|
|
|
1667
1647
|
// Node and the miss is silent.
|
|
1668
1648
|
const BROWSER_OUTPUT = './dist/src/browser/'
|
|
1669
1649
|
const ABSENT_SUBPATH = '/no-subpath-is-published-under-this-name'
|
|
1650
|
+
// A compiler diagnostic that says where it is: the path relative to the directory
|
|
1651
|
+
// the compiler ran in, the 1-based line and column, the code, and the message. The
|
|
1652
|
+
// diagnostics are the verdict rather than the exit code, which differs between the
|
|
1653
|
+
// compiler majors this toolchain supports, so a reported line matching nothing here
|
|
1654
|
+
// came from something other than a check of a consumer module.
|
|
1655
|
+
const DIAGNOSTIC_PATTERN = /^(.+?)\\(\\d+,\\d+\\): error TS\\d+: /u
|
|
1670
1656
|
const PING = ['ping', '--fetch-retries=0', '--fetch-timeout=5000', '--loglevel=silent']
|
|
1671
1657
|
const ESM_DRIVER = 'drive.mjs'
|
|
1672
1658
|
const CJS_DRIVER = 'drive.cjs'
|
|
@@ -1712,8 +1698,8 @@ const DECLARATION_CONDITIONS = Object.freeze({
|
|
|
1712
1698
|
|
|
1713
1699
|
interface Resolution {
|
|
1714
1700
|
readonly label: string
|
|
1715
|
-
readonly resolution:
|
|
1716
|
-
readonly module:
|
|
1701
|
+
readonly resolution: string
|
|
1702
|
+
readonly module: string
|
|
1717
1703
|
readonly conditions: Readonly<Record<Format, readonly string[]>>
|
|
1718
1704
|
}
|
|
1719
1705
|
|
|
@@ -1721,51 +1707,61 @@ interface TargetResolution {
|
|
|
1721
1707
|
readonly target: string
|
|
1722
1708
|
}
|
|
1723
1709
|
|
|
1724
|
-
// Each compile driver carries the
|
|
1725
|
-
//
|
|
1726
|
-
// probe that can resolve it.
|
|
1710
|
+
// Each compile driver carries the compiler options its scratch project sets and
|
|
1711
|
+
// the conditions TypeScript applies for that resolution and importing format. A
|
|
1712
|
+
// \`require\`-only subpath therefore stays in each CommonJS probe that can resolve it.
|
|
1713
|
+
// The option values are the spellings the project file takes, so nothing here needs
|
|
1714
|
+
// the compiler's own API to name them.
|
|
1727
1715
|
const RESOLUTIONS: readonly Resolution[] = [
|
|
1728
1716
|
{
|
|
1729
1717
|
label: 'node16',
|
|
1730
|
-
resolution:
|
|
1731
|
-
module:
|
|
1718
|
+
resolution: 'node16',
|
|
1719
|
+
module: 'node16',
|
|
1732
1720
|
conditions: DECLARATION_CONDITIONS,
|
|
1733
1721
|
},
|
|
1734
1722
|
{
|
|
1735
1723
|
label: 'nodenext',
|
|
1736
|
-
resolution:
|
|
1737
|
-
module:
|
|
1724
|
+
resolution: 'nodenext',
|
|
1725
|
+
module: 'nodenext',
|
|
1738
1726
|
conditions: DECLARATION_CONDITIONS,
|
|
1739
1727
|
},
|
|
1740
1728
|
{
|
|
1741
1729
|
label: 'bundler',
|
|
1742
|
-
resolution:
|
|
1743
|
-
module:
|
|
1730
|
+
resolution: 'bundler',
|
|
1731
|
+
module: 'esnext',
|
|
1744
1732
|
conditions: BUNDLER_CONDITIONS,
|
|
1745
1733
|
},
|
|
1746
1734
|
]
|
|
1747
1735
|
|
|
1736
|
+
// The driver a bundled consumer reads declarations under. A browser application
|
|
1737
|
+
// compiles through a bundler, so the browser drive answers under this one alone,
|
|
1738
|
+
// and naming it here is what keeps that selection tied to the driver it selects.
|
|
1739
|
+
const BROWSER_DRIVER = RESOLUTIONS.find((candidate) => candidate.label === 'bundler')
|
|
1740
|
+
if (BROWSER_DRIVER === undefined) throw new Error("RESOLUTIONS carries no 'bundler' row")
|
|
1741
|
+
|
|
1748
1742
|
const FORMATS: ReadonlyArray<readonly [extension: string, format: Format]> = [
|
|
1749
1743
|
['ts', 'module'],
|
|
1750
1744
|
['cts', 'commonjs'],
|
|
1751
1745
|
]
|
|
1752
1746
|
|
|
1753
1747
|
// One published subpath, resolved to what this proof can drive: the specifier a
|
|
1754
|
-
// consumer writes, the declarations its consumer formats
|
|
1755
|
-
//
|
|
1748
|
+
// consumer writes, whether the declarations its consumer formats resolve at all,
|
|
1749
|
+
// whether the exports map answers the browser condition with a target of its own,
|
|
1750
|
+
// whether it answers \`import\` and \`require\` at all, and whether the target that
|
|
1751
|
+
// \`require\` answers with is one that a CommonJS consumer loads.
|
|
1756
1752
|
interface Entry {
|
|
1757
1753
|
readonly subpath: string
|
|
1758
1754
|
readonly specifier: string
|
|
1759
1755
|
readonly mapping: unknown
|
|
1760
1756
|
readonly declaration: {
|
|
1761
|
-
readonly
|
|
1762
|
-
readonly
|
|
1763
|
-
readonly
|
|
1757
|
+
readonly importable: boolean
|
|
1758
|
+
readonly requirable: boolean
|
|
1759
|
+
readonly browsable: boolean
|
|
1764
1760
|
}
|
|
1765
|
-
readonly
|
|
1766
|
-
readonly
|
|
1767
|
-
readonly
|
|
1768
|
-
readonly
|
|
1761
|
+
readonly browsable: boolean
|
|
1762
|
+
readonly importable: boolean
|
|
1763
|
+
readonly requirable: boolean
|
|
1764
|
+
readonly loadable: boolean
|
|
1769
1765
|
}
|
|
1770
1766
|
|
|
1771
1767
|
// The installed tree every claim is read from. Every subpath the exports map names
|
|
@@ -2018,7 +2014,14 @@ function isDeclaration(target: string): boolean {
|
|
|
2018
2014
|
// against. Each field uses the conditions of the TypeScript consumer paired with
|
|
2019
2015
|
// that runtime. A JavaScript target resolves through TypeScript's adjacent
|
|
2020
2016
|
// declaration substitution rather than standing in for the declaration itself.
|
|
2021
|
-
function readDeclaration(
|
|
2017
|
+
function readDeclaration(
|
|
2018
|
+
entry: unknown,
|
|
2019
|
+
installed: string,
|
|
2020
|
+
): {
|
|
2021
|
+
readonly module: string | undefined
|
|
2022
|
+
readonly commonjs: string | undefined
|
|
2023
|
+
readonly browser: string | undefined
|
|
2024
|
+
} {
|
|
2022
2025
|
return {
|
|
2023
2026
|
module: resolveDeclaration(entry, DECLARATION_CONDITIONS.module, installed),
|
|
2024
2027
|
commonjs: resolveDeclaration(entry, DECLARATION_CONDITIONS.commonjs, installed),
|
|
@@ -2031,72 +2034,137 @@ function selectEntries(entries: readonly Entry[], conditions: readonly string[])
|
|
|
2031
2034
|
return entries.filter(
|
|
2032
2035
|
(entry) =>
|
|
2033
2036
|
resolveTarget(entry.mapping, conditions) !== undefined &&
|
|
2034
|
-
(!conditions.includes('require') || entry.
|
|
2037
|
+
(!conditions.includes('require') || entry.loadable),
|
|
2038
|
+
)
|
|
2039
|
+
}
|
|
2040
|
+
|
|
2041
|
+
// The compile drivers whose conditions reach one entry under one importing format.
|
|
2042
|
+
// A driver that resolves no target for that entry compiles nothing, so a consumer
|
|
2043
|
+
// written under it would report a resolution failure this package never made.
|
|
2044
|
+
function selectDrivers(entry: Entry, format: Format): readonly Resolution[] {
|
|
2045
|
+
return RESOLUTIONS.filter(
|
|
2046
|
+
(driver) => selectEntries([entry], driver.conditions[format]).length > 0,
|
|
2035
2047
|
)
|
|
2036
2048
|
}
|
|
2037
2049
|
|
|
2038
|
-
//
|
|
2039
|
-
//
|
|
2040
|
-
//
|
|
2050
|
+
// Requirable entries that declare CommonJS support but a typed CommonJS consumer
|
|
2051
|
+
// cannot compile against. A default branch resolving under the require condition
|
|
2052
|
+
// set makes no CommonJS claim.
|
|
2041
2053
|
function selectUntypable(entries: readonly Entry[], installed: string): readonly Entry[] {
|
|
2042
2054
|
return entries.filter(
|
|
2043
2055
|
(entry) =>
|
|
2044
|
-
entry.
|
|
2056
|
+
entry.requirable &&
|
|
2045
2057
|
isRecord(entry.mapping) &&
|
|
2046
2058
|
Object.hasOwn(entry.mapping, 'require') &&
|
|
2047
2059
|
!declaresCommonJS(entry.mapping, installed),
|
|
2048
2060
|
)
|
|
2049
2061
|
}
|
|
2050
2062
|
|
|
2051
|
-
//
|
|
2052
|
-
//
|
|
2053
|
-
//
|
|
2054
|
-
//
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2063
|
+
// One surface comparison, written as the consumer module that proves it: the
|
|
2064
|
+
// installed entry that consumer imports, the file extension fixing its importing
|
|
2065
|
+
// format, the names a real runtime published off it, and the driver whose scratch
|
|
2066
|
+
// project compiles it.
|
|
2067
|
+
interface Surface {
|
|
2068
|
+
readonly entry: Entry
|
|
2069
|
+
readonly extension: string
|
|
2070
|
+
readonly published: readonly string[]
|
|
2071
|
+
readonly driver: Resolution
|
|
2072
|
+
}
|
|
2073
|
+
|
|
2074
|
+
// A scratch project over named consumer modules, written beside them so their own
|
|
2075
|
+
// resolution reaches the installed package. Nothing is emitted and no ambient types
|
|
2076
|
+
// are pulled in, so what the check reads is the installed declarations alone.
|
|
2077
|
+
function writeProject(
|
|
2078
|
+
stage: Stage,
|
|
2079
|
+
name: string,
|
|
2080
|
+
driver: Resolution,
|
|
2081
|
+
files: readonly string[],
|
|
2082
|
+
): string {
|
|
2083
|
+
const path = join(stage.consumer, \`tsconfig.\${name}.json\`)
|
|
2084
|
+
const project = {
|
|
2085
|
+
compilerOptions: {
|
|
2086
|
+
module: driver.module,
|
|
2087
|
+
moduleResolution: driver.resolution,
|
|
2088
|
+
noEmit: true,
|
|
2089
|
+
skipLibCheck: true,
|
|
2090
|
+
strict: true,
|
|
2091
|
+
target: 'esnext',
|
|
2092
|
+
types: [],
|
|
2093
|
+
},
|
|
2094
|
+
files: [...files],
|
|
2073
2095
|
}
|
|
2074
|
-
|
|
2096
|
+
writeFile(path, \`\${JSON.stringify(project, undefined, '\\t')}\\n\`)
|
|
2097
|
+
return path
|
|
2075
2098
|
}
|
|
2076
2099
|
|
|
2077
|
-
// The diagnostics
|
|
2078
|
-
//
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
})
|
|
2092
|
-
|
|
2093
|
-
.
|
|
2094
|
-
|
|
2100
|
+
// The diagnostics the compiler this workspace installs reports for one scratch
|
|
2101
|
+
// project. The compiler runs as a command, so nothing here reaches an API that
|
|
2102
|
+
// moves between its majors, and the located lines it prints are the verdict rather
|
|
2103
|
+
// than the exit code, which moves between them. A line carrying no location, a line
|
|
2104
|
+
// naming the scratch project rather than a consumer module, and anything at all on
|
|
2105
|
+
// the error stream are faults of this proof rather than of the package under proof,
|
|
2106
|
+
// so each is raised where it happens instead of counted against the package.
|
|
2107
|
+
function checkProject(stage: Stage, project: string): readonly string[] {
|
|
2108
|
+
const result = runNode([TSC, '--noEmit', '--pretty', 'false', '-p', project], stage.consumer)
|
|
2109
|
+
const refused = \`\${result.stderr ?? ''}\`.trim()
|
|
2110
|
+
if (refused.length > 0) {
|
|
2111
|
+
throw new Error(\`The consumer compiler wrote \${refused} to its error stream\`)
|
|
2112
|
+
}
|
|
2113
|
+
const reported: string[] = []
|
|
2114
|
+
for (const line of \`\${result.stdout ?? ''}\`.split(/\\r\\n|\\n/u)) {
|
|
2115
|
+
if (line.trim().length === 0) continue
|
|
2116
|
+
const last = reported.at(-1)
|
|
2117
|
+
// An elaborated diagnostic prints its detail on indented lines under its own
|
|
2118
|
+
// first line, so each of those joins the diagnostic it elaborates.
|
|
2119
|
+
if (/^\\s/u.test(line) && last !== undefined) {
|
|
2120
|
+
reported[reported.length - 1] = \`\${last} \${line.trim()}\`
|
|
2121
|
+
continue
|
|
2122
|
+
}
|
|
2123
|
+
const located = DIAGNOSTIC_PATTERN.exec(line)?.[1]
|
|
2124
|
+
if (located === undefined) {
|
|
2125
|
+
throw new Error(\`The consumer compiler reported \${line}, which names no location\`)
|
|
2126
|
+
}
|
|
2127
|
+
if (resolve(stage.consumer, located) === project) {
|
|
2128
|
+
throw new Error(\`The scratch project is itself at fault: \${line}\`)
|
|
2129
|
+
}
|
|
2130
|
+
reported.push(line)
|
|
2131
|
+
}
|
|
2132
|
+
if (reported.length === 0 && result.status !== 0) {
|
|
2133
|
+
throw new Error(\`The consumer compiler refused the project: \${readOutput(result)}\`)
|
|
2134
|
+
}
|
|
2135
|
+
return reported
|
|
2136
|
+
}
|
|
2137
|
+
|
|
2138
|
+
// One installed entry's published names checked against its own declarations by
|
|
2139
|
+
// the compiler this workspace installs, in the direction each divergence surfaces
|
|
2140
|
+
// under. The runtime's key list is written into the consumer as a literal, so the
|
|
2141
|
+
// published side comes from a real process and the declared side from the
|
|
2142
|
+
// declarations that process's package ships, and the two can disagree. A name the
|
|
2143
|
+
// declarations carry and the runtime does not lands on \`declared\`. A name the
|
|
2144
|
+
// runtime carries and the declarations do not, and a name the declarations publish
|
|
2145
|
+
// as a type alone, land on \`surfaced\`: a variable widens into the type
|
|
2146
|
+
// \`declared\` annotates, and only \`surfaced\` reads the literal's own keys back.
|
|
2147
|
+
// Each names the member it is about, so the failure says which export moved.
|
|
2148
|
+
function checkSurface(stage: Stage, surface: Surface): readonly string[] {
|
|
2149
|
+
const slug = surface.entry.subpath.replaceAll(/[^\\w]+/gu, '-')
|
|
2150
|
+
const name = \`surface.\${surface.driver.label}\${slug}.\${surface.extension}\`
|
|
2151
|
+
const module = \`\${name}\`
|
|
2152
|
+
const keys = surface.published.map((key) => \`\${JSON.stringify(key)}: true\`).join(', ')
|
|
2153
|
+
writeFile(
|
|
2154
|
+
join(stage.consumer, module),
|
|
2155
|
+
\`import * as entry from \${JSON.stringify(surface.entry.specifier)}
|
|
2156
|
+
const published = {\${keys.length === 0 ? '' : \` \${keys} \`}} as const
|
|
2157
|
+
const declared: Record<keyof typeof entry, true> = published
|
|
2158
|
+
const surfaced: Record<keyof typeof published, true> = declared
|
|
2159
|
+
\`,
|
|
2160
|
+
)
|
|
2161
|
+
const project = writeProject(stage, name, surface.driver, [\`./\${module}\`])
|
|
2162
|
+
return checkProject(stage, project).map((line) => \`\${surface.driver.label}: \${line}\`)
|
|
2095
2163
|
}
|
|
2096
2164
|
|
|
2097
2165
|
// One consumer module importing every installed entry, written where its own
|
|
2098
2166
|
// resolution finds the installed package.
|
|
2099
|
-
function writeConsumerProbe(stage: Stage, path: string, specifiers: readonly string[]):
|
|
2167
|
+
function writeConsumerProbe(stage: Stage, path: string, specifiers: readonly string[]): void {
|
|
2100
2168
|
const names: string[] = []
|
|
2101
2169
|
const bindings: string[] = []
|
|
2102
2170
|
for (const [index, specifier] of specifiers.entries()) {
|
|
@@ -2104,9 +2172,8 @@ function writeConsumerProbe(stage: Stage, path: string, specifiers: readonly str
|
|
|
2104
2172
|
names.push(binding)
|
|
2105
2173
|
bindings.push(\`import * as \${binding} from \${JSON.stringify(specifier)}\`)
|
|
2106
2174
|
}
|
|
2107
|
-
const
|
|
2108
|
-
writeFile(
|
|
2109
|
-
return target
|
|
2175
|
+
const source = \`\${bindings.join('\\n')}\\nexport const surface = [\${names.join(', ')}]\\n\`
|
|
2176
|
+
writeFile(join(stage.consumer, path), source)
|
|
2110
2177
|
}
|
|
2111
2178
|
|
|
2112
2179
|
// The runtime key set a real process reads off one installed entry under one
|
|
@@ -2176,27 +2243,26 @@ function buildStage(): Stage {
|
|
|
2176
2243
|
else excluded.push(subpath)
|
|
2177
2244
|
continue
|
|
2178
2245
|
}
|
|
2179
|
-
const
|
|
2180
|
-
const
|
|
2246
|
+
const importTarget = resolveTarget(entry, RUNTIME_CONDITIONS.module)
|
|
2247
|
+
const requireTarget = resolveTarget(entry, RUNTIME_CONDITIONS.commonjs)
|
|
2181
2248
|
const browserTarget = resolveTarget(entry, RUNTIME_CONDITIONS.browser)
|
|
2182
|
-
const
|
|
2183
|
-
const
|
|
2184
|
-
const
|
|
2249
|
+
const browsable = resolvesBrowser(entry)
|
|
2250
|
+
const shadowed = browsable && requireTarget === browserTarget
|
|
2251
|
+
const requirable = requireTarget !== undefined && !shadowed
|
|
2252
|
+
const loadable = requirable && resolvesCommonJS(entry, installed)
|
|
2185
2253
|
entries.push({
|
|
2186
2254
|
subpath,
|
|
2187
2255
|
specifier: subpath === '.' ? name : \`\${name}\${subpath.slice(1)}\`,
|
|
2188
2256
|
mapping: entry,
|
|
2189
2257
|
declaration: {
|
|
2190
|
-
|
|
2191
|
-
commonjs
|
|
2192
|
-
|
|
2193
|
-
browser:
|
|
2194
|
-
declaration.browser === undefined ? undefined : join(installed, declaration.browser),
|
|
2258
|
+
importable: declaration.module !== undefined,
|
|
2259
|
+
requirable: declaration.commonjs !== undefined,
|
|
2260
|
+
browsable: declaration.browser !== undefined,
|
|
2195
2261
|
},
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2262
|
+
browsable,
|
|
2263
|
+
importable: importTarget !== undefined && !(browsable && importTarget === browserTarget),
|
|
2264
|
+
requirable,
|
|
2265
|
+
loadable,
|
|
2200
2266
|
})
|
|
2201
2267
|
}
|
|
2202
2268
|
return { consumer, installed, archives, entries, subpaths, undeclared, excluded, targets }
|
|
@@ -2347,7 +2413,7 @@ describe('installed package consumer', () => {
|
|
|
2347
2413
|
// loads it. Each later drive retires itself for that entry, so this assertion names
|
|
2348
2414
|
// the subpath rather than counting it as driven.
|
|
2349
2415
|
const unreachable = stage.entries.filter(
|
|
2350
|
-
(entry) => !entry.
|
|
2416
|
+
(entry) => !entry.importable && !entry.requirable && !entry.browsable,
|
|
2351
2417
|
)
|
|
2352
2418
|
expect(unreachable.map((entry) => entry.subpath)).toStrictEqual([])
|
|
2353
2419
|
const untypable = selectUntypable(stage.entries, stage.installed)
|
|
@@ -2376,16 +2442,18 @@ describe('installed package consumer', () => {
|
|
|
2376
2442
|
for (const [extension, format] of FORMATS) {
|
|
2377
2443
|
const written = selectEntries(stage.entries, driver.conditions[format])
|
|
2378
2444
|
if (written.length === 0) continue
|
|
2445
|
+
const label = \`\${driver.label}.\${extension}\`
|
|
2446
|
+
const probe = \`probe.\${label}\`
|
|
2379
2447
|
const specifiers = written.map((entry) => entry.specifier)
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
const absent = [\`\${name}\${ABSENT_SUBPATH}\`]
|
|
2385
|
-
const control = writeConsumerProbe(stage, \`control.\${driver.label}.\${extension}\`, absent)
|
|
2386
|
-
if (compileConsumer(control, driver.resolution, driver.module).length === 0) {
|
|
2387
|
-
silent.push(\`\${driver.label}.\${extension}\`)
|
|
2448
|
+
writeConsumerProbe(stage, probe, specifiers)
|
|
2449
|
+
const project = writeProject(stage, probe, driver, [\`./\${probe}\`])
|
|
2450
|
+
for (const message of checkProject(stage, project)) {
|
|
2451
|
+
reported.push(\`\${label}: \${message}\`)
|
|
2388
2452
|
}
|
|
2453
|
+
const control = \`control.\${label}\`
|
|
2454
|
+
writeConsumerProbe(stage, control, [\`\${name}\${ABSENT_SUBPATH}\`])
|
|
2455
|
+
const refused = writeProject(stage, control, driver, [\`./\${control}\`])
|
|
2456
|
+
if (checkProject(stage, refused).length === 0) silent.push(label)
|
|
2389
2457
|
}
|
|
2390
2458
|
}
|
|
2391
2459
|
expect(reported).toStrictEqual([])
|
|
@@ -2395,27 +2463,44 @@ describe('installed package consumer', () => {
|
|
|
2395
2463
|
|
|
2396
2464
|
for (const entry of STAGE?.entries ?? []) {
|
|
2397
2465
|
describe(\`installed entry \${entry.subpath}\`, () => {
|
|
2398
|
-
it.runIf(entry.
|
|
2466
|
+
it.runIf(entry.importable)(
|
|
2399
2467
|
'publishes what it declares to a Node import, and no more',
|
|
2400
2468
|
(context) => {
|
|
2401
|
-
const
|
|
2402
|
-
|
|
2469
|
+
const stage = requireStage(context)
|
|
2470
|
+
// The exports-map walk resolved a declaration a typed importer reads, so an
|
|
2471
|
+
// entry reaching this drive without one is reported for that rather than for
|
|
2472
|
+
// what a consumer of a missing declaration goes on to say.
|
|
2473
|
+
if (!entry.declaration.importable) {
|
|
2403
2474
|
throw new Error(\`\${entry.subpath} publishes no import declaration\`)
|
|
2404
2475
|
}
|
|
2405
|
-
const published = driveRuntime(
|
|
2406
|
-
|
|
2476
|
+
const published = driveRuntime(stage, entry.specifier, ESM_DRIVER)
|
|
2477
|
+
const drivers = selectDrivers(entry, 'module')
|
|
2478
|
+
expect(drivers).not.toStrictEqual([])
|
|
2479
|
+
const reported = drivers.flatMap((driver) =>
|
|
2480
|
+
checkSurface(stage, { entry, extension: 'ts', published, driver }),
|
|
2481
|
+
)
|
|
2482
|
+
expect(reported).toStrictEqual([])
|
|
2407
2483
|
},
|
|
2408
2484
|
)
|
|
2409
2485
|
|
|
2410
|
-
it.runIf(entry.
|
|
2486
|
+
it.runIf(entry.requirable)(
|
|
2411
2487
|
'publishes what it declares to a Node require, and no more',
|
|
2412
2488
|
(context) => {
|
|
2413
|
-
const
|
|
2414
|
-
if (declaration
|
|
2489
|
+
const stage = requireStage(context)
|
|
2490
|
+
if (!entry.declaration.requirable) {
|
|
2415
2491
|
throw new Error(\`\${entry.subpath} publishes no require declaration\`)
|
|
2416
2492
|
}
|
|
2417
|
-
const published = driveRuntime(
|
|
2418
|
-
|
|
2493
|
+
const published = driveRuntime(stage, entry.specifier, CJS_DRIVER)
|
|
2494
|
+
// A subpath whose \`require\` resolves to a module that no typed CommonJS
|
|
2495
|
+
// consumer can compile against carries no declared side to compare here, and
|
|
2496
|
+
// whether it may publish one at all is the untypable set's question rather
|
|
2497
|
+
// than this drive's. The preceding runtime drive ran either way.
|
|
2498
|
+
const drivers = selectDrivers(entry, 'commonjs')
|
|
2499
|
+
expect(drivers).not.toStrictEqual([])
|
|
2500
|
+
const reported = drivers.flatMap((driver) =>
|
|
2501
|
+
checkSurface(stage, { entry, extension: 'cts', published, driver }),
|
|
2502
|
+
)
|
|
2503
|
+
expect(reported).toStrictEqual([])
|
|
2419
2504
|
},
|
|
2420
2505
|
)
|
|
2421
2506
|
{{drive}} })
|
|
@@ -2528,12 +2613,11 @@ async function readBrowserExports(browser: Browser, bundle: string): Promise<rea
|
|
|
2528
2613
|
}
|
|
2529
2614
|
`,
|
|
2530
2615
|
drive: `
|
|
2531
|
-
it.runIf(entry.
|
|
2616
|
+
it.runIf(entry.browsable)(
|
|
2532
2617
|
'publishes what it declares to a real browser, and no more [requires a browser]',
|
|
2533
2618
|
async (context) => {
|
|
2534
2619
|
const stage = requireStage(context)
|
|
2535
|
-
|
|
2536
|
-
if (declaration === undefined) {
|
|
2620
|
+
if (!entry.declaration.browsable) {
|
|
2537
2621
|
throw new Error(\`\${entry.subpath} publishes no browser declaration\`)
|
|
2538
2622
|
}
|
|
2539
2623
|
const options = resolveBrowser(resolvePinnedBrowser(), process.platform, process.env)
|
|
@@ -2544,9 +2628,16 @@ async function readBrowserExports(browser: Browser, bundle: string): Promise<rea
|
|
|
2544
2628
|
})
|
|
2545
2629
|
try {
|
|
2546
2630
|
const bundle = await bundleEntry(stage, entry)
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2631
|
+
const published = await readBrowserExports(browser, bundle)
|
|
2632
|
+
// A browser consumer reads the installed declarations through a bundler, so
|
|
2633
|
+
// that is the one driver this face answers under.
|
|
2634
|
+
const reported = checkSurface(stage, {
|
|
2635
|
+
entry,
|
|
2636
|
+
extension: 'ts',
|
|
2637
|
+
published,
|
|
2638
|
+
driver: BROWSER_DRIVER,
|
|
2639
|
+
})
|
|
2640
|
+
expect(reported).toStrictEqual([])
|
|
2550
2641
|
} finally {
|
|
2551
2642
|
await browser.close()
|
|
2552
2643
|
}
|
|
@@ -2569,7 +2660,7 @@ async function readBrowserExports(browser: Browser, bundle: string): Promise<rea
|
|
|
2569
2660
|
// file and runs the \`repair\` verb, which writes the variant carrying that branch.
|
|
2570
2661
|
it('publishes no browser face this proof cannot drive [requires the registry]', (context) => {
|
|
2571
2662
|
const stage = requireStage(context)
|
|
2572
|
-
const faces = stage.entries.filter((entry) => entry.
|
|
2663
|
+
const faces = stage.entries.filter((entry) => entry.browsable)
|
|
2573
2664
|
expect(faces.map((entry) => entry.subpath)).toStrictEqual([])
|
|
2574
2665
|
})
|
|
2575
2666
|
`
|
|
@@ -2684,12 +2775,12 @@ printf '%s\\n' \\
|
|
|
2684
2775
|
*
|
|
2685
2776
|
* @example
|
|
2686
2777
|
* ```ts
|
|
2687
|
-
* import {
|
|
2778
|
+
* import { isScaffoldError, ScaffoldError } from '@orkestrel/scaffold'
|
|
2688
2779
|
*
|
|
2689
2780
|
* try {
|
|
2690
|
-
* throw new ScaffoldError('
|
|
2781
|
+
* throw new ScaffoldError('TARGET', 'The target carries no readable manifest.')
|
|
2691
2782
|
* } catch (error) {
|
|
2692
|
-
* if (isScaffoldError(error)) error.code // '
|
|
2783
|
+
* if (isScaffoldError(error)) error.code // 'TARGET'
|
|
2693
2784
|
* }
|
|
2694
2785
|
* ```
|
|
2695
2786
|
*/
|
|
@@ -3134,7 +3225,8 @@ var isCatalogEntry = unionOf(recordOf({
|
|
|
3134
3225
|
name: isDependencyName,
|
|
3135
3226
|
lookup: literalOf("found"),
|
|
3136
3227
|
version: isString,
|
|
3137
|
-
dependencies: andOf(isCollection, arrayOf(isDependency))
|
|
3228
|
+
dependencies: andOf(isCollection, arrayOf(isDependency)),
|
|
3229
|
+
peers: andOf(isCollection, arrayOf(isDependency))
|
|
3138
3230
|
}), recordOf({
|
|
3139
3231
|
name: isDependencyName,
|
|
3140
3232
|
lookup: literalOf("missing", "unmatched", "failed"),
|
|
@@ -3520,7 +3612,7 @@ function isCanonPath(path) {
|
|
|
3520
3612
|
return CANON_PATHS.some((canon) => path === canon || path.startsWith(`${canon}/`));
|
|
3521
3613
|
}
|
|
3522
3614
|
/**
|
|
3523
|
-
* Checks whether a target's present bytes at a path
|
|
3615
|
+
* Checks whether another surface owns a target's present bytes at a path.
|
|
3524
3616
|
*
|
|
3525
3617
|
* @param path - The target-relative path to test.
|
|
3526
3618
|
* @returns True if the path is a {@link WORKSPACE_OWNED_PATHS} member or a
|
|
@@ -3697,46 +3789,6 @@ function matchesPrintWidth(line) {
|
|
|
3697
3789
|
return line.replaceAll(" ", " ".repeat(2)).length <= 100;
|
|
3698
3790
|
}
|
|
3699
3791
|
/**
|
|
3700
|
-
* Derives the declaration rewrite a published face's `beforeWriteFile` applies.
|
|
3701
|
-
*
|
|
3702
|
-
* @param name - The workspace's own bare package name.
|
|
3703
|
-
* @returns The ternary consequent an emitted `vite.{browser,server}.config.ts`
|
|
3704
|
-
* fills its `{{replacement}}` span with, indented for that span.
|
|
3705
|
-
*
|
|
3706
|
-
* @remarks
|
|
3707
|
-
* `vite-plugin-dts` rolls a face into one declaration and keeps each source
|
|
3708
|
-
* module's own relative depth, so a nested module emits a path that escapes
|
|
3709
|
-
* `dist/src` and a flat one resolves only by luck. Both faces rewrite the same
|
|
3710
|
-
* relative core path to the package's published root export, so the branch is
|
|
3711
|
-
* derived once here. The extension alternation is what the permitted import
|
|
3712
|
-
* spellings produce: an `@src/core` alias resolves to the core source module and
|
|
3713
|
-
* prints `.ts`, while a relative import prints the `.js` specifier it was
|
|
3714
|
-
* written with. The formatter keeps the call on one line only while the line it
|
|
3715
|
-
* prints measures inside the vendored width, and the workspace name is what
|
|
3716
|
-
* varies, so the shape is chosen by measuring the candidate: a tab prints as the
|
|
3717
|
-
* vendored two columns, and the gate admits a name long enough to push the
|
|
3718
|
-
* joined call past 100.
|
|
3719
|
-
*
|
|
3720
|
-
* @example
|
|
3721
|
-
* ```ts
|
|
3722
|
-
* import { nameToRewrite } from '@orkestrel/scaffold'
|
|
3723
|
-
*
|
|
3724
|
-
* nameToRewrite('router').includes("'@orkestrel/router'") // true
|
|
3725
|
-
* ```
|
|
3726
|
-
*/
|
|
3727
|
-
function nameToRewrite(name) {
|
|
3728
|
-
const specifier = serializeTypeScriptString(`@orkestrel/${name}`);
|
|
3729
|
-
const pattern = "/(?:\\.\\.\\/)+core\\/index\\.[jt]s/g";
|
|
3730
|
-
const joined = `\t\t\t\t\t\t? content.replaceAll(${pattern}, ${specifier})`;
|
|
3731
|
-
if (matchesPrintWidth(joined)) return joined;
|
|
3732
|
-
return [
|
|
3733
|
-
" ? content.replaceAll(",
|
|
3734
|
-
`\t\t\t\t\t\t\t\t${pattern},`,
|
|
3735
|
-
`\t\t\t\t\t\t\t\t${specifier},`,
|
|
3736
|
-
" )"
|
|
3737
|
-
].join("\n");
|
|
3738
|
-
}
|
|
3739
|
-
/**
|
|
3740
3792
|
* Selects the single published environment a package root points at.
|
|
3741
3793
|
*
|
|
3742
3794
|
* @param src - The declared published environments.
|
|
@@ -3992,9 +4044,11 @@ function matchesDriftReachability(ownership, finding) {
|
|
|
3992
4044
|
* @remarks
|
|
3993
4045
|
* A layer is a deterministic function of the catalog's own edges, so it is
|
|
3994
4046
|
* computed here rather than stored on a row that could disagree with them.
|
|
3995
|
-
* Only RUNTIME edges between catalogued packages count: a development
|
|
4047
|
+
* Only RUNTIME and PEER edges between catalogued packages count: a development
|
|
3996
4048
|
* dependency reaches no consumer, so it constrains nothing about publish order,
|
|
3997
|
-
* and an edge leaving the fleet is a package this catalog does not publish.
|
|
4049
|
+
* and an edge leaving the fleet is a package this catalog does not publish. A
|
|
4050
|
+
* peer edge counts like a runtime edge, because a caret peer range at `0.0.x`
|
|
4051
|
+
* names one exact release the dependent cannot publish ahead of.
|
|
3998
4052
|
*
|
|
3999
4053
|
* The order matters because these packages are `0.0.x`, where a caret pins one
|
|
4000
4054
|
* exact release. Publishing a dependent before its dependency leaves the
|
|
@@ -4005,11 +4059,12 @@ function matchesDriftReachability(ownership, finding) {
|
|
|
4005
4059
|
* placed in an order that would be wrong. An absent name is the report: compare
|
|
4006
4060
|
* the returned names against the catalog to find one.
|
|
4007
4061
|
*
|
|
4008
|
-
* @example
|
|
4062
|
+
* @example Fleet catalog
|
|
4009
4063
|
* ```ts
|
|
4010
4064
|
* import { catalogToLayers } from '@orkestrel/scaffold'
|
|
4011
4065
|
*
|
|
4012
|
-
* catalogToLayers(entries)
|
|
4066
|
+
* const layers = catalogToLayers(entries)
|
|
4067
|
+
* layers[0] // the names that depend on nothing else in the fleet
|
|
4013
4068
|
* ```
|
|
4014
4069
|
*/
|
|
4015
4070
|
function catalogToLayers(entries) {
|
|
@@ -4017,7 +4072,7 @@ function catalogToLayers(entries) {
|
|
|
4017
4072
|
const pending = /* @__PURE__ */ new Map();
|
|
4018
4073
|
for (const entry of entries) {
|
|
4019
4074
|
if (entry.lookup !== "found") continue;
|
|
4020
|
-
const edges = entry.dependencies.map((dependency) => dependency.name);
|
|
4075
|
+
const edges = [...entry.dependencies, ...entry.peers].map((dependency) => dependency.name);
|
|
4021
4076
|
pending.set(entry.name, new Set(edges.filter((name) => published.has(name))));
|
|
4022
4077
|
}
|
|
4023
4078
|
const layers = [];
|
|
@@ -4594,7 +4649,7 @@ function blueprintToScripts(blueprint) {
|
|
|
4594
4649
|
scripts["test:policy"] = `${vitest} --project policy`;
|
|
4595
4650
|
scripts["test:config"] = `${vitest} --project config`;
|
|
4596
4651
|
if (blueprint.setup) scripts["test:setup"] = `${vitest} --project setup`;
|
|
4597
|
-
if (blueprint.guides) scripts["test:guides"] =
|
|
4652
|
+
if (blueprint.guides) scripts["test:guides"] = `node --experimental-strip-types ${GUIDES_TEST_PATH}`;
|
|
4598
4653
|
if (blueprint.conformance) scripts["test:conformance"] = `${vitest} --project conformance`;
|
|
4599
4654
|
scripts["test:probe"] = "vitest run --config vite.config.ts --no-cache --reporter=verbose --project probe";
|
|
4600
4655
|
scripts["test:bench"] = "vitest bench --config vite.config.ts --no-cache --project probe";
|
|
@@ -4648,13 +4703,16 @@ function blueprintToScripts(blueprint) {
|
|
|
4648
4703
|
*
|
|
4649
4704
|
* @remarks
|
|
4650
4705
|
* Every direct `test:<project>` script is writable, together with the probe and
|
|
4651
|
-
* benchmark workbench scripts.
|
|
4652
|
-
*
|
|
4653
|
-
*
|
|
4706
|
+
* benchmark workbench scripts. A workspace carrying guides adds `test:guides`,
|
|
4707
|
+
* whose package-owned entry runs the guides project and handles explicit parity
|
|
4708
|
+
* rewrites. Publishing adds the pack and publication lifecycle scripts.
|
|
4709
|
+
* Aggregate test scripts and
|
|
4710
|
+
* maintainer-owned gate chains stay outside the region.
|
|
4654
4711
|
*
|
|
4655
4712
|
* `accepted` carries each generated predecessor the region can replace. The
|
|
4656
|
-
*
|
|
4657
|
-
*
|
|
4713
|
+
* guides entry accepts the generated command that invoked the guides project
|
|
4714
|
+
* through Vitest alone. The pack hook accepts the build chain emitted before it
|
|
4715
|
+
* delegated to `build`. The publication hook accepts the same gate chain without
|
|
4658
4716
|
* {@link RELEASE_PROOF_COMMAND}. The value being written is always writable, so
|
|
4659
4717
|
* it is not repeated there. Any other value is a script the workspace author
|
|
4660
4718
|
* customized, and {@link replaceManifestScripts} retains it while writing the
|
|
@@ -4673,11 +4731,11 @@ function blueprintToWritableScripts(blueprint) {
|
|
|
4673
4731
|
const scripts = blueprintToScripts(blueprint);
|
|
4674
4732
|
const writable = [];
|
|
4675
4733
|
for (const [name, command] of Object.entries(scripts)) {
|
|
4676
|
-
if (!name.startsWith("test:")
|
|
4734
|
+
if (!(name.startsWith("test:") && name !== "test:src" && name !== "test:app")) continue;
|
|
4677
4735
|
writable.push({
|
|
4678
4736
|
name,
|
|
4679
4737
|
command,
|
|
4680
|
-
accepted: []
|
|
4738
|
+
accepted: name === "test:guides" ? ["vitest run --config vite.config.ts --no-cache --reporter=dot --project guides"] : []
|
|
4681
4739
|
});
|
|
4682
4740
|
}
|
|
4683
4741
|
const prepack = scripts.prepack;
|
|
@@ -4825,6 +4883,21 @@ function blueprintToMachinery(blueprint) {
|
|
|
4825
4883
|
* @param blueprint - The workspace specification.
|
|
4826
4884
|
* @returns Formatter-stable `tsconfig.json` text.
|
|
4827
4885
|
*
|
|
4886
|
+
* @remarks
|
|
4887
|
+
* `paths` carries the workspace's own published specifiers beside the `@src` and
|
|
4888
|
+
* `@app` aliases, mapped to source. The published set is what
|
|
4889
|
+
* {@link srcToExports} publishes, read the same way here so the two never name
|
|
4890
|
+
* different subpaths, and the `app` axis publishes nothing so it maps nothing.
|
|
4891
|
+
* A package's own name resolves inside its own checkout through that `exports`
|
|
4892
|
+
* map, to the built `dist/` entry, so a module importing it would make the root
|
|
4893
|
+
* typecheck depend on a build; mapping the specifier to source is what keeps
|
|
4894
|
+
* `npm run check` independent of `npm run build`. The root Vite configuration
|
|
4895
|
+
* derives its `alias` record from every `paths` entry, so the same specifiers
|
|
4896
|
+
* resolve to source under Vitest, and every subpath is emitted before the bare
|
|
4897
|
+
* specifier: an alias record is matched in declaration order and a bare pattern
|
|
4898
|
+
* also matches its own subpaths, so the reverse order would resolve
|
|
4899
|
+
* `@orkestrel/<name>/server` through the core entry.
|
|
4900
|
+
*
|
|
4828
4901
|
* @example
|
|
4829
4902
|
* ```ts
|
|
4830
4903
|
* import { blueprintToRootTsconfig, createBlueprint } from '@orkestrel/scaffold'
|
|
@@ -4836,9 +4909,21 @@ function blueprintToMachinery(blueprint) {
|
|
|
4836
4909
|
*/
|
|
4837
4910
|
function blueprintToRootTsconfig(blueprint) {
|
|
4838
4911
|
const aliases = [];
|
|
4839
|
-
for (const environment of ENVIRONMENTS) if (blueprint.src.includes(environment)) aliases.push(
|
|
4840
|
-
for (const environment of ENVIRONMENTS) if (blueprint.app.includes(environment)) aliases.push(
|
|
4841
|
-
const
|
|
4912
|
+
for (const environment of ENVIRONMENTS) if (blueprint.src.includes(environment)) aliases.push([`@src/${environment}`, `./src/${environment}/index.ts`]);
|
|
4913
|
+
for (const environment of ENVIRONMENTS) if (blueprint.app.includes(environment)) aliases.push([`@app/${environment}`, `./app/${environment}/index.ts`]);
|
|
4914
|
+
const root = srcToRoot(blueprint.src);
|
|
4915
|
+
if (root === void 0) for (const environment of ENVIRONMENTS) {
|
|
4916
|
+
if (environment === "core" || !blueprint.src.includes(environment)) continue;
|
|
4917
|
+
const subpath = SRC_MATRIX[environment].path.slice(1);
|
|
4918
|
+
aliases.push([`@orkestrel/${blueprint.name}${subpath}`, `./src/${environment}/index.ts`]);
|
|
4919
|
+
}
|
|
4920
|
+
if (blueprint.src.length > 0) aliases.push([`@orkestrel/${blueprint.name}`, `./src/${root ?? "core"}/index.ts`]);
|
|
4921
|
+
const paths = aliases.map(([specifier, target], index) => {
|
|
4922
|
+
const separator = index === aliases.length - 1 ? "" : ",";
|
|
4923
|
+
const line = `\t\t\t"${specifier}": ["${target}"]${separator}`;
|
|
4924
|
+
if (matchesPrintWidth(line)) return line;
|
|
4925
|
+
return `\t\t\t"${specifier}": [\n\t\t\t\t"${target}"\n\t\t\t]${separator}`;
|
|
4926
|
+
}).join("\n");
|
|
4842
4927
|
return fillTemplate(CONFIG_TEMPLATES.root.tsconfig, { paths });
|
|
4843
4928
|
}
|
|
4844
4929
|
/**
|
|
@@ -5071,9 +5156,9 @@ function blueprintToConfigArtifacts(blueprint) {
|
|
|
5071
5156
|
for (const environment of blueprint.src) for (const path of SRC_MATRIX[environment].configs) {
|
|
5072
5157
|
let content = CONFIG_TEMPLATES.vites.src.core;
|
|
5073
5158
|
if (path === "configs/src/tsconfig.core.json") content = CONFIG_TEMPLATES.tsconfigs.src.core;
|
|
5074
|
-
else if (path === "configs/src/vite.browser.config.ts") content =
|
|
5159
|
+
else if (path === "configs/src/vite.browser.config.ts") content = CONFIG_TEMPLATES.vites.src.browser;
|
|
5075
5160
|
else if (path === "configs/src/tsconfig.browser.json") content = CONFIG_TEMPLATES.tsconfigs.src.browser;
|
|
5076
|
-
else if (path === "configs/src/vite.server.config.ts") content =
|
|
5161
|
+
else if (path === "configs/src/vite.server.config.ts") content = CONFIG_TEMPLATES.vites.src.server;
|
|
5077
5162
|
else if (path === "configs/src/tsconfig.server.json") content = CONFIG_TEMPLATES.tsconfigs.src.server;
|
|
5078
5163
|
artifacts.push({
|
|
5079
5164
|
path,
|
|
@@ -5516,11 +5601,11 @@ function blueprintToOrchestrationArtifacts(blueprint) {
|
|
|
5516
5601
|
}];
|
|
5517
5602
|
}
|
|
5518
5603
|
/**
|
|
5519
|
-
* Compiles the vendored host artifacts a
|
|
5604
|
+
* Compiles the vendored host artifacts a workspace plans.
|
|
5520
5605
|
*
|
|
5521
|
-
* @param
|
|
5522
|
-
* @returns One artifact per vendored path in `HOST_PATHS` order, then
|
|
5523
|
-
* catalog file.
|
|
5606
|
+
* @param blueprint - The workspace specification.
|
|
5607
|
+
* @returns One artifact per selected vendored path in `HOST_PATHS` order, then
|
|
5608
|
+
* the catalog file.
|
|
5524
5609
|
*
|
|
5525
5610
|
* @remarks
|
|
5526
5611
|
* Every artifact is claimed by presence, which is the strongest claim a pure
|
|
@@ -5545,15 +5630,16 @@ function blueprintToOrchestrationArtifacts(blueprint) {
|
|
|
5545
5630
|
*
|
|
5546
5631
|
* @example
|
|
5547
5632
|
* ```ts
|
|
5548
|
-
* import {
|
|
5633
|
+
* import { blueprintToHostArtifacts, createBlueprint } from '@orkestrel/scaffold'
|
|
5549
5634
|
*
|
|
5550
|
-
*
|
|
5551
|
-
*
|
|
5552
|
-
*
|
|
5635
|
+
* const blueprint = createBlueprint('router')
|
|
5636
|
+
*
|
|
5637
|
+
* blueprintToHostArtifacts(blueprint).some((artifact) => artifact.path === 'tests/guides.test.ts') // false
|
|
5638
|
+
* blueprintToHostArtifacts(blueprint).some((artifact) => artifact.path === 'guides/router.md') // false
|
|
5553
5639
|
* ```
|
|
5554
5640
|
*/
|
|
5555
|
-
function
|
|
5556
|
-
return [...selectHostPaths(HOST_PATHS, name), CATALOG_AGENT_PATH].map((path) => ({
|
|
5641
|
+
function blueprintToHostArtifacts(blueprint) {
|
|
5642
|
+
return [...selectHostPaths(HOST_PATHS, blueprint.name), CATALOG_AGENT_PATH].map((path) => ({
|
|
5557
5643
|
path,
|
|
5558
5644
|
group: inferGroup(path),
|
|
5559
5645
|
ownership: "presence",
|
|
@@ -5596,7 +5682,8 @@ function applyOverrides(artifacts, overrides) {
|
|
|
5596
5682
|
});
|
|
5597
5683
|
}
|
|
5598
5684
|
/**
|
|
5599
|
-
* Replaces
|
|
5685
|
+
* Replaces the runtime and development dependency ranges in package manifest text, and never a
|
|
5686
|
+
* peer range.
|
|
5600
5687
|
*
|
|
5601
5688
|
* @param manifest - The manifest text to compile.
|
|
5602
5689
|
* @param pins - The runtime and development names and replacement ranges.
|
|
@@ -6482,12 +6569,18 @@ function overridesToQuestions(overrides, artifacts) {
|
|
|
6482
6569
|
* and let the answers disagree, so a blueprint the gate will
|
|
6483
6570
|
* refuse is still constructible.
|
|
6484
6571
|
*
|
|
6485
|
-
* @example
|
|
6572
|
+
* @example Blueprint
|
|
6486
6573
|
* ```ts
|
|
6487
6574
|
* import { createBlueprint } from '@orkestrel/scaffold'
|
|
6488
6575
|
*
|
|
6489
|
-
* createBlueprint('router', {
|
|
6490
|
-
*
|
|
6576
|
+
* const blueprint = createBlueprint('router', {
|
|
6577
|
+
* src: ['core', 'server'],
|
|
6578
|
+
* dependencies: [{ name: '@orkestrel/emitter', range: '^0.0.5' }],
|
|
6579
|
+
* bin: true,
|
|
6580
|
+
* })
|
|
6581
|
+
*
|
|
6582
|
+
* blueprint.version // '0.0.1'
|
|
6583
|
+
* blueprint.engines // '>=22.12.0'
|
|
6491
6584
|
* ```
|
|
6492
6585
|
*/
|
|
6493
6586
|
function createBlueprint(name, input) {
|
|
@@ -6551,11 +6644,13 @@ function createBlueprint(name, input) {
|
|
|
6551
6644
|
*
|
|
6552
6645
|
* @example
|
|
6553
6646
|
* ```ts
|
|
6554
|
-
* import {
|
|
6647
|
+
* import { Compiler, createBlueprint } from '@orkestrel/scaffold'
|
|
6555
6648
|
*
|
|
6556
6649
|
* const compiler = new Compiler()
|
|
6557
6650
|
* const scaffolding = compiler.compile(createBlueprint('router', { src: ['core'] }))
|
|
6558
|
-
*
|
|
6651
|
+
*
|
|
6652
|
+
* scaffolding.plan?.artifacts // every planned file, in group order
|
|
6653
|
+
* scaffolding.stages // one CompileRecord per stage that ran
|
|
6559
6654
|
* compiler.destroy()
|
|
6560
6655
|
* ```
|
|
6561
6656
|
*/
|
|
@@ -6787,7 +6882,7 @@ var Compiler = class {
|
|
|
6787
6882
|
...blueprintToGuideArtifacts(blueprint),
|
|
6788
6883
|
...blueprintToDocumentArtifacts(blueprint),
|
|
6789
6884
|
...blueprintToOrchestrationArtifacts(blueprint),
|
|
6790
|
-
...
|
|
6885
|
+
...blueprintToHostArtifacts(blueprint)
|
|
6791
6886
|
];
|
|
6792
6887
|
}
|
|
6793
6888
|
#gate(blueprint, draft, artifacts) {
|
|
@@ -6818,6 +6913,6 @@ var Compiler = class {
|
|
|
6818
6913
|
}
|
|
6819
6914
|
};
|
|
6820
6915
|
//#endregion
|
|
6821
|
-
export { APP_BROWSER_DEV_DEPENDENCIES, APP_DEV_DEPENDENCIES, APP_MATRIX, APP_SERVER_DEV_DEPENDENCIES, ARTIFACT_TEMPLATES, BASE_DEV_DEPENDENCIES, BIN_CONFIGS, BIN_ENTRY_PATH, CANON_PATHS, CATALOG_AGENT_PATH, CATALOG_CLOSING_MARKER, CATALOG_OPENING_MARKER, CONFIG_TEMPLATES, CONFORMANCE_TEST_PATH, CONTROL_CHARACTER_PATTERN, Compiler, DECLARATION_DEV_DEPENDENCIES, DEFAULT_ENGINES, DEFAULT_VERSION, DEPENDENCY_NAME_PATTERN, DISTRIBUTION_TEST_PATH, ENGINES_PATTERN, ENVIRONMENTS, EXECUTABLE_PATHS, EXTRA_RANGE_PATTERN, FLOOR_RANGE_PATTERN, FOREIGN_NAME_PATTERN, GLOBAL_SETUP_PATH, GROUPS, GUIDES_TEST_PATH, HEX_PATTERN, HOST_INVENTORY_PATH, HOST_PATHS, INTEGRATION_TEST_PATH, INVALID_PATH_CHARACTER_PATTERN, MANIFEST_PATH, MAX_ARTIFACT_BYTES, MAX_ARTIFACT_HEX_LENGTH, MAX_AUDIT_FINDINGS, MAX_COLLECTION_ITEMS, MAX_DEPENDENCY_NAME_LENGTH, MAX_MANIFEST_BYTES, MAX_NAME_LENGTH, MAX_PATH_LENGTH, MAX_RANGE_LENGTH, MAX_REGISTRY_BYTES, MAX_SCRIPT_LENGTH, MAX_TOTAL_ARTIFACT_BYTES, MAX_TOTAL_REGISTRY_BYTES, MINIMUM_NODE_VERSION, NAME_PATTERN, ORCHESTRATION_PATH_NAMES, ORCHESTRATION_PATH_PREFIXES, ORKESTREL_RANGE_PATTERN, PRINT_WIDTH, RELEASE_PROOF_COMMAND, SERVICE_SCRIPT_PATH, SERVICE_SETUP_PATH, SERVICE_TEST_INCLUDE, SHOWCASE_CONFIG_PATH, SHOWCASE_DEV_DEPENDENCIES, SOURCE_BROWSER_DEV_DEPENDENCIES, SRC_MATRIX, ScaffoldError, TAB_WIDTH, VERSION_PATTERN, WORKSPACE_OWNED_PATHS, applyOverrides, artifactToFinding, artifactToHex, artifactsToQuestions, blueprintToConfigArtifacts, blueprintToDevDependencies, blueprintToDocumentArtifacts, blueprintToGuideArtifacts, blueprintToMachinery, blueprintToManifest, blueprintToOrchestrationArtifacts, blueprintToQuestions, blueprintToRootTsconfig, blueprintToRootVite, blueprintToScripts, blueprintToSourceArtifacts, blueprintToTestArtifacts, blueprintToWritableScripts, bytesToHex, catalogToLayers, cloneValue, compareVersions, computeBytes, computeHash, contentToHex, createBlueprint, dependenciesToQuestions, extractRangeMajor, extractVersion, inferDrift, inferGroup, isArtifact, isAudit, isBlueprint, isCanonPath, isCatalogEntry, isCollection, isCompilerHooks, isCompilerOptions, isContent, isDeferredPath, isDependency, isDependencyName, isEnvironment, isFinding, isFloorPath, isGroup, isGroups, isHex, isManifestScript, isMirror, isOverride, isPath, isPlan, isQuestion, isRetainedPath, isScaffoldError, isSnapshot, manifestToDependencies, manifestToName, matchesDriftReachability, matchesEngines, matchesOrchestrationPath, matchesPrintWidth, matchesRange, nameToGuide,
|
|
6916
|
+
export { APP_BROWSER_DEV_DEPENDENCIES, APP_DEV_DEPENDENCIES, APP_MATRIX, APP_SERVER_DEV_DEPENDENCIES, ARTIFACT_TEMPLATES, BASE_DEV_DEPENDENCIES, BIN_CONFIGS, BIN_ENTRY_PATH, CANON_PATHS, CATALOG_AGENT_PATH, CATALOG_CLOSING_MARKER, CATALOG_OPENING_MARKER, CONFIG_TEMPLATES, CONFORMANCE_TEST_PATH, CONTROL_CHARACTER_PATTERN, Compiler, DECLARATION_DEV_DEPENDENCIES, DEFAULT_ENGINES, DEFAULT_VERSION, DEPENDENCY_NAME_PATTERN, DISTRIBUTION_TEST_PATH, ENGINES_PATTERN, ENVIRONMENTS, EXECUTABLE_PATHS, EXTRA_RANGE_PATTERN, FLOOR_RANGE_PATTERN, FOREIGN_NAME_PATTERN, GLOBAL_SETUP_PATH, GROUPS, GUIDES_TEST_PATH, HEX_PATTERN, HOST_INVENTORY_PATH, HOST_PATHS, INTEGRATION_TEST_PATH, INVALID_PATH_CHARACTER_PATTERN, MANIFEST_PATH, MAX_ARTIFACT_BYTES, MAX_ARTIFACT_HEX_LENGTH, MAX_AUDIT_FINDINGS, MAX_COLLECTION_ITEMS, MAX_DEPENDENCY_NAME_LENGTH, MAX_MANIFEST_BYTES, MAX_NAME_LENGTH, MAX_PATH_LENGTH, MAX_RANGE_LENGTH, MAX_REGISTRY_BYTES, MAX_SCRIPT_LENGTH, MAX_TOTAL_ARTIFACT_BYTES, MAX_TOTAL_REGISTRY_BYTES, MINIMUM_NODE_VERSION, NAME_PATTERN, ORCHESTRATION_PATH_NAMES, ORCHESTRATION_PATH_PREFIXES, ORKESTREL_RANGE_PATTERN, PRINT_WIDTH, RELEASE_PROOF_COMMAND, SERVICE_SCRIPT_PATH, SERVICE_SETUP_PATH, SERVICE_TEST_INCLUDE, SHOWCASE_CONFIG_PATH, SHOWCASE_DEV_DEPENDENCIES, SOURCE_BROWSER_DEV_DEPENDENCIES, SRC_MATRIX, ScaffoldError, TAB_WIDTH, VERSION_PATTERN, WORKSPACE_OWNED_PATHS, applyOverrides, artifactToFinding, artifactToHex, artifactsToQuestions, blueprintToConfigArtifacts, blueprintToDevDependencies, blueprintToDocumentArtifacts, blueprintToGuideArtifacts, blueprintToHostArtifacts, blueprintToMachinery, blueprintToManifest, blueprintToOrchestrationArtifacts, blueprintToQuestions, blueprintToRootTsconfig, blueprintToRootVite, blueprintToScripts, blueprintToSourceArtifacts, blueprintToTestArtifacts, blueprintToWritableScripts, bytesToHex, catalogToLayers, cloneValue, compareVersions, computeBytes, computeHash, contentToHex, createBlueprint, dependenciesToQuestions, extractRangeMajor, extractVersion, inferDrift, inferGroup, isArtifact, isAudit, isBlueprint, isCanonPath, isCatalogEntry, isCollection, isCompilerHooks, isCompilerOptions, isContent, isDeferredPath, isDependency, isDependencyName, isEnvironment, isFinding, isFloorPath, isGroup, isGroups, isHex, isManifestScript, isMirror, isOverride, isPath, isPlan, isQuestion, isRetainedPath, isScaffoldError, isSnapshot, manifestToDependencies, manifestToName, matchesDriftReachability, matchesEngines, matchesOrchestrationPath, matchesPrintWidth, matchesRange, nameToGuide, overridesToQuestions, parseBlueprint, parseCompilerOptions, parseGroups, parseSnapshot, pathToCondition, planToFindings, planToHash, planToSummary, replaceManifestRanges, replaceManifestScripts, replacePlanRanges, selectGroups, selectHostPaths, serializeTypeScriptString, srcToEntry, srcToExports, srcToRoot };
|
|
6822
6917
|
|
|
6823
6918
|
//# sourceMappingURL=index.js.map
|