@orkestrel/scaffold 0.0.45 → 0.0.47
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/bin/main.js +179 -44
- package/dist/bin/main.js.map +1 -1
- package/dist/host/AGENTS.md +1 -0
- package/dist/host/agents/orchestration.md +3 -1
- package/dist/host/claude/agents/codex.md +4 -4
- package/dist/host/claude/agents/orkestrel.md +6 -5
- package/dist/host/claude/rules/documentation.md +2 -1
- package/dist/host/claude/rules/quality.md +3 -0
- package/dist/host/claude/rules/tests.md +19 -0
- package/dist/host/claude/rules/workspace.md +28 -21
- package/dist/host/claude/settings.json +781 -2
- package/dist/host/codex/config.toml +4 -0
- package/dist/host/configs/policy.ts +167 -10
- package/dist/host/cursor/mcp.json +4 -0
- package/dist/host/dotfiles/mcp.json +4 -0
- package/dist/host/dotfiles/oxlintrc.json +9 -0
- package/dist/host/guides/scaffold.md +143 -44
- 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 +126 -11
- package/dist/host/tests/policy.test.ts +7 -0
- package/dist/host/tests/setupPolicy.ts +222 -8
- package/dist/src/core/index.cjs +420 -23
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +102 -9
- package/dist/src/core/index.d.ts +102 -9
- package/dist/src/core/index.js +416 -24
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/server/index.cjs +41 -49
- package/dist/src/server/index.cjs.map +1 -1
- package/dist/src/server/index.d.cts +9 -8
- package/dist/src/server/index.d.ts +9 -8
- package/dist/src/server/index.js +42 -50
- package/dist/src/server/index.js.map +1 -1
- package/package.json +8 -5
package/dist/src/core/index.cjs
CHANGED
|
@@ -2,6 +2,118 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
|
2
2
|
let _orkestrel_contract = require("@orkestrel/contract");
|
|
3
3
|
let _orkestrel_template = require("@orkestrel/template");
|
|
4
4
|
let _orkestrel_emitter = require("@orkestrel/emitter");
|
|
5
|
+
var package_default = {
|
|
6
|
+
name: "@orkestrel/scaffold",
|
|
7
|
+
version: "0.0.47",
|
|
8
|
+
description: "Scaffold workspaces with five commands: new, audit, repair, catalog, and overwrite.",
|
|
9
|
+
keywords: [
|
|
10
|
+
"audit",
|
|
11
|
+
"catalog",
|
|
12
|
+
"new",
|
|
13
|
+
"overwrite",
|
|
14
|
+
"repair"
|
|
15
|
+
],
|
|
16
|
+
homepage: "https://github.com/orkestrel/scaffold#readme",
|
|
17
|
+
bugs: "https://github.com/orkestrel/scaffold/issues",
|
|
18
|
+
license: "MIT",
|
|
19
|
+
repository: {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "git+https://github.com/orkestrel/scaffold.git"
|
|
22
|
+
},
|
|
23
|
+
bin: { "scaffold": "dist/bin/main.js" },
|
|
24
|
+
files: [
|
|
25
|
+
"dist/src",
|
|
26
|
+
"dist/bin",
|
|
27
|
+
"dist/host",
|
|
28
|
+
"README.md"
|
|
29
|
+
],
|
|
30
|
+
type: "module",
|
|
31
|
+
sideEffects: ["./src/bin/main.ts", "./dist/bin/main.js"],
|
|
32
|
+
main: "./dist/src/core/index.cjs",
|
|
33
|
+
module: "./dist/src/core/index.js",
|
|
34
|
+
exports: {
|
|
35
|
+
".": {
|
|
36
|
+
"import": {
|
|
37
|
+
"types": "./dist/src/core/index.d.ts",
|
|
38
|
+
"default": "./dist/src/core/index.js"
|
|
39
|
+
},
|
|
40
|
+
"require": {
|
|
41
|
+
"types": "./dist/src/core/index.d.cts",
|
|
42
|
+
"default": "./dist/src/core/index.cjs"
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"./server": {
|
|
46
|
+
"import": {
|
|
47
|
+
"types": "./dist/src/server/index.d.ts",
|
|
48
|
+
"default": "./dist/src/server/index.js"
|
|
49
|
+
},
|
|
50
|
+
"require": {
|
|
51
|
+
"types": "./dist/src/server/index.d.cts",
|
|
52
|
+
"default": "./dist/src/server/index.cjs"
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"./package.json": "./package.json"
|
|
56
|
+
},
|
|
57
|
+
publishConfig: { "access": "public" },
|
|
58
|
+
scripts: {
|
|
59
|
+
"clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
|
|
60
|
+
"copy": "node -e \"const fs=require('node:fs'),p=require('node:path'),a=process.argv[1],b=process.argv[2];fs.mkdirSync(p.dirname(b),{recursive:true});fs.cpSync(a,b,{force:true});console.log('Copied: '+a+' to '+b)\"",
|
|
61
|
+
"scaffold": "node ./dist/bin/main.js",
|
|
62
|
+
"lint": "oxlint --config .oxlintrc.json --fix --deny-warnings .",
|
|
63
|
+
"check": "tsc --noEmit --project tsconfig.json && npm run check:src",
|
|
64
|
+
"check:src": "npm run check:src:core && npm run check:src:server && npm run check:src:bin",
|
|
65
|
+
"check:src:core": "tsc --noEmit -p configs/src/tsconfig.core.json",
|
|
66
|
+
"check:src:server": "tsc --noEmit -p configs/src/tsconfig.server.json",
|
|
67
|
+
"check:src:bin": "tsc --noEmit -p configs/src/tsconfig.bin.json",
|
|
68
|
+
"format": "oxfmt --config .oxfmtrc.json --write .",
|
|
69
|
+
"format:check": "oxfmt --config .oxfmtrc.json --check .",
|
|
70
|
+
"lint:check": "oxlint --config .oxlintrc.json --deny-warnings .",
|
|
71
|
+
"test": "npm run test:src:core && npm run test:src:server && npm run test:src:bin && npm run test:policy && npm run test:config && npm run test:guides",
|
|
72
|
+
"test:src:core": "vitest run --config vite.config.ts --no-cache --reporter=dot --project src:core",
|
|
73
|
+
"test:src:server": "vitest run --config vite.config.ts --no-cache --reporter=dot --project src:server",
|
|
74
|
+
"test:src:bin": "vitest run --config vite.config.ts --no-cache --reporter=dot --project src:bin",
|
|
75
|
+
"test:policy": "vitest run --config vite.config.ts --no-cache --reporter=dot --project policy",
|
|
76
|
+
"test:config": "vitest run --config vite.config.ts --no-cache --reporter=dot --project config",
|
|
77
|
+
"test:guides": "vitest run --config vite.config.ts --no-cache --reporter=dot --project guides",
|
|
78
|
+
"test:distribution": "vitest run --config vite.config.ts --no-cache --reporter=dot --project distribution",
|
|
79
|
+
"test:probe": "vitest run --config vite.config.ts --no-cache --reporter=verbose --project probe",
|
|
80
|
+
"test:bench": "vitest bench --config vite.config.ts --no-cache --project probe",
|
|
81
|
+
"build": "npm run clean && npm run build:src && npm run build:host",
|
|
82
|
+
"build:src": "npm run build:src:core && npm run build:src:server && npm run build:src:bin",
|
|
83
|
+
"build:src:core": "vite build --config configs/src/vite.core.config.ts && npm run copy dist/src/core/index.d.ts dist/src/core/index.d.cts",
|
|
84
|
+
"build:src:server": "vite build --config configs/src/vite.server.config.ts && npm run copy dist/src/server/index.d.ts dist/src/server/index.d.cts",
|
|
85
|
+
"build:src:bin": "vite build --config configs/src/vite.bin.config.ts",
|
|
86
|
+
"build:host": "node -e \"import('./dist/src/server/index.js').then((m)=>{const n=m.stageHost(process.cwd(),'dist/host').length;console.log('build-host: staged '+n+' file(s) into dist/host')})\"",
|
|
87
|
+
"prepack": "npm run build",
|
|
88
|
+
"prepublishOnly": "npm run format:check && npm run lint:check && npm run check && npm run build && npm test && npm run test:distribution -- --mode release"
|
|
89
|
+
},
|
|
90
|
+
dependencies: {
|
|
91
|
+
"@orkestrel/console": "^0.0.9",
|
|
92
|
+
"@orkestrel/contract": "^0.0.13",
|
|
93
|
+
"@orkestrel/emitter": "^0.0.7",
|
|
94
|
+
"@orkestrel/markdown": "^0.0.9",
|
|
95
|
+
"@orkestrel/process": "^0.0.4",
|
|
96
|
+
"@orkestrel/template": "^0.0.4"
|
|
97
|
+
},
|
|
98
|
+
devDependencies: {
|
|
99
|
+
"@microsoft/api-extractor": "^7.59.0",
|
|
100
|
+
"@orkestrel/guide": "^0.0.12",
|
|
101
|
+
"@orkestrel/html": "^0.0.4",
|
|
102
|
+
"@orkestrel/probe": "^0.0.2",
|
|
103
|
+
"@orkestrel/test": "^0.0.8",
|
|
104
|
+
"@types/node": "^26.2.0",
|
|
105
|
+
"@vitest/browser-playwright": "^4.1.11",
|
|
106
|
+
"oxfmt": "^0.64.0",
|
|
107
|
+
"oxlint": "^1.79.0",
|
|
108
|
+
"playwright": "^1.62.1",
|
|
109
|
+
"typescript": "^6.0.3",
|
|
110
|
+
"vite": "^8.2.2",
|
|
111
|
+
"vite-plugin-dts": "^5.0.3",
|
|
112
|
+
"vitest": "^4.1.11"
|
|
113
|
+
},
|
|
114
|
+
engines: { "node": ">=22.12.0" }
|
|
115
|
+
};
|
|
116
|
+
//#endregion
|
|
5
117
|
//#region src/core/constants.ts
|
|
6
118
|
/**
|
|
7
119
|
* The `Environment` values, frozen.
|
|
@@ -302,6 +414,24 @@ var MAX_AUDIT_FINDINGS = MAX_COLLECTION_ITEMS * 2;
|
|
|
302
414
|
var MAX_ARTIFACT_BYTES = 5242880;
|
|
303
415
|
/** Maximum length of the hexadecimal string carrying one artifact's bytes. */
|
|
304
416
|
var MAX_ARTIFACT_HEX_LENGTH = MAX_ARTIFACT_BYTES * 2;
|
|
417
|
+
/**
|
|
418
|
+
* Maximum decoded bytes accepted from one registry response.
|
|
419
|
+
*
|
|
420
|
+
* @remarks
|
|
421
|
+
* The 2026-08-21 abbreviated-packument measurements were 8,647,138 bytes for
|
|
422
|
+
* TypeScript, 8,077,438 for Playwright, 2,315,360 for `@types/node`, 2,298,256
|
|
423
|
+
* for Vite, and 1,272,652 for Vitest. The bound leaves headroom above those
|
|
424
|
+
* registry answers.
|
|
425
|
+
*/
|
|
426
|
+
var MAX_REGISTRY_BYTES = 33554432;
|
|
427
|
+
/**
|
|
428
|
+
* Maximum decoded bytes accepted across one registry-reading call.
|
|
429
|
+
*
|
|
430
|
+
* @remarks
|
|
431
|
+
* The 2026-08-21 browser-workspace registry set measured about 24 MiB. The
|
|
432
|
+
* bound leaves headroom for that set to grow without making a call unbounded.
|
|
433
|
+
*/
|
|
434
|
+
var MAX_TOTAL_REGISTRY_BYTES = 100663296;
|
|
305
435
|
/** Maximum bytes accepted for one package or vendored-host manifest. */
|
|
306
436
|
var MAX_MANIFEST_BYTES = 1048576;
|
|
307
437
|
/** Maximum bytes retained across one whole plan or audit. */
|
|
@@ -314,32 +444,33 @@ var DEFAULT_VERSION = "0.0.1";
|
|
|
314
444
|
var DEFAULT_ENGINES = `>=${MINIMUM_NODE_VERSION}`;
|
|
315
445
|
/** The tooling versions scaffold and every generated workspace share. */
|
|
316
446
|
var BASE_DEV_DEPENDENCIES = Object.freeze({
|
|
317
|
-
"@orkestrel/guide":
|
|
318
|
-
"@orkestrel/
|
|
319
|
-
"@orkestrel/
|
|
320
|
-
"@
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
447
|
+
"@orkestrel/guide": package_default.devDependencies["@orkestrel/guide"],
|
|
448
|
+
"@orkestrel/probe": package_default.devDependencies["@orkestrel/probe"],
|
|
449
|
+
"@orkestrel/scaffold": `^${package_default.version}`,
|
|
450
|
+
"@orkestrel/test": package_default.devDependencies["@orkestrel/test"],
|
|
451
|
+
"@types/node": package_default.devDependencies["@types/node"],
|
|
452
|
+
oxfmt: package_default.devDependencies.oxfmt,
|
|
453
|
+
oxlint: package_default.devDependencies.oxlint,
|
|
454
|
+
typescript: package_default.devDependencies.typescript,
|
|
455
|
+
vite: package_default.devDependencies.vite,
|
|
456
|
+
vitest: package_default.devDependencies.vitest
|
|
326
457
|
});
|
|
327
458
|
/** The development dependencies that emit declarations for published source or an executable. */
|
|
328
459
|
var DECLARATION_DEV_DEPENDENCIES = Object.freeze({
|
|
329
|
-
"@microsoft/api-extractor":
|
|
330
|
-
"vite-plugin-dts":
|
|
460
|
+
"@microsoft/api-extractor": package_default.devDependencies["@microsoft/api-extractor"],
|
|
461
|
+
"vite-plugin-dts": package_default.devDependencies["vite-plugin-dts"]
|
|
331
462
|
});
|
|
332
463
|
/** The development dependencies a published browser `src` environment adds. */
|
|
333
464
|
var SOURCE_BROWSER_DEV_DEPENDENCIES = Object.freeze({
|
|
334
|
-
"@vitest/browser-playwright":
|
|
335
|
-
playwright:
|
|
465
|
+
"@vitest/browser-playwright": package_default.devDependencies["@vitest/browser-playwright"],
|
|
466
|
+
playwright: package_default.devDependencies.playwright
|
|
336
467
|
});
|
|
337
468
|
/** The development dependency every private `app` environment adds. */
|
|
338
|
-
var APP_DEV_DEPENDENCIES = Object.freeze({ "@orkestrel/contract":
|
|
469
|
+
var APP_DEV_DEPENDENCIES = Object.freeze({ "@orkestrel/contract": package_default.dependencies["@orkestrel/contract"] });
|
|
339
470
|
/** The development dependencies a private Vue browser application adds. */
|
|
340
471
|
var APP_BROWSER_DEV_DEPENDENCIES = Object.freeze({
|
|
341
472
|
...SOURCE_BROWSER_DEV_DEPENDENCIES,
|
|
342
|
-
"@orkestrel/html":
|
|
473
|
+
"@orkestrel/html": package_default.devDependencies["@orkestrel/html"],
|
|
343
474
|
"@vitejs/plugin-vue": "^6.0.8",
|
|
344
475
|
vue: "^3.5.40",
|
|
345
476
|
"vue-tsc": "^3.3.7"
|
|
@@ -351,13 +482,13 @@ var APP_BROWSER_DEV_DEPENDENCIES = Object.freeze({
|
|
|
351
482
|
* ```ts
|
|
352
483
|
* import { SHOWCASE_DEV_DEPENDENCIES } from '@orkestrel/scaffold'
|
|
353
484
|
*
|
|
354
|
-
* SHOWCASE_DEV_DEPENDENCIES['vite-plugin-singlefile'] //
|
|
485
|
+
* SHOWCASE_DEV_DEPENDENCIES['vite-plugin-singlefile'] // the showcase plugin range
|
|
355
486
|
* ```
|
|
356
487
|
*/
|
|
357
488
|
var SHOWCASE_DEV_DEPENDENCIES = Object.freeze({ "vite-plugin-singlefile": "^2.3.3" });
|
|
358
489
|
/** The development dependencies a private server application adds. */
|
|
359
490
|
var APP_SERVER_DEV_DEPENDENCIES = Object.freeze({
|
|
360
|
-
"@orkestrel/emitter":
|
|
491
|
+
"@orkestrel/emitter": package_default.dependencies["@orkestrel/emitter"],
|
|
361
492
|
"@orkestrel/middleware": "^0.0.16",
|
|
362
493
|
"@orkestrel/router": "^0.0.10",
|
|
363
494
|
"@orkestrel/server": "^0.0.14"
|
|
@@ -793,7 +924,11 @@ export const service = (options?: UserConfig): UserConfig =>
|
|
|
793
924
|
options ?? {},
|
|
794
925
|
)
|
|
795
926
|
`,
|
|
796
|
-
probe: `// A workbench, not a proof. No gate selects this project.
|
|
927
|
+
probe: `// A workbench, not a proof. No gate selects this project. Run in test mode by the
|
|
928
|
+
// \`test:probe\` script, it collects \`tmp/probe/**/*.test.ts\`. Run in benchmark mode by the
|
|
929
|
+
// \`test:bench\` script, the same workbench also collects \`tests/**/*.test.ts\` for a \`bench\` block,
|
|
930
|
+
// so a suite may carry a bench beside its ordinary tests without a second project. The mode
|
|
931
|
+
// guard around each \`bench\` call keeps it out of test mode, so it never executes there.
|
|
797
932
|
export const probe = (options?: UserConfig): UserConfig =>
|
|
798
933
|
mergeConfig(
|
|
799
934
|
{
|
|
@@ -804,6 +939,9 @@ export const probe = (options?: UserConfig): UserConfig =>
|
|
|
804
939
|
setupFiles: ['./tests/setup.ts'],
|
|
805
940
|
environment: 'node',
|
|
806
941
|
browser: { enabled: false },
|
|
942
|
+
fileParallelism: false,
|
|
943
|
+
pool: 'threads',
|
|
944
|
+
benchmark: { include: ['tmp/probe/**/*.test.ts', 'tests/**/*.test.ts'] },
|
|
807
945
|
},
|
|
808
946
|
},
|
|
809
947
|
options ?? {},
|
|
@@ -2691,6 +2829,32 @@ function extractVersion(version) {
|
|
|
2691
2829
|
];
|
|
2692
2830
|
}
|
|
2693
2831
|
/**
|
|
2832
|
+
* Extract the major component of an admitted dependency range.
|
|
2833
|
+
*
|
|
2834
|
+
* @param range - The candidate range text.
|
|
2835
|
+
* @returns The major number, or `undefined` when the text is not a canonical
|
|
2836
|
+
* major caret or an admitted full-version form.
|
|
2837
|
+
*
|
|
2838
|
+
* @remarks
|
|
2839
|
+
* A canonical toolchain range is `^MAJOR`. Existing consumer declarations may
|
|
2840
|
+
* instead carry an exact `major.minor.patch` version or that version under a
|
|
2841
|
+
* caret or tilde. The projection reads those forms without deciding whether a
|
|
2842
|
+
* version satisfies them; {@link matchesRange} owns that separate question.
|
|
2843
|
+
*
|
|
2844
|
+
* @example
|
|
2845
|
+
* ```ts
|
|
2846
|
+
* import { extractRangeMajor } from '@orkestrel/scaffold'
|
|
2847
|
+
*
|
|
2848
|
+
* extractRangeMajor('^6') // the declared major
|
|
2849
|
+
* extractRangeMajor('>=6.0.0') // undefined
|
|
2850
|
+
* ```
|
|
2851
|
+
*/
|
|
2852
|
+
function extractRangeMajor(range) {
|
|
2853
|
+
const match = /^(?:\^(0|[1-9]\d*)|(?:\^|~)?(0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)(?:-(?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*)(?:\.(?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*))*)?)$/.exec(range);
|
|
2854
|
+
const major = match?.[1] ?? match?.[2];
|
|
2855
|
+
return major === void 0 ? void 0 : Number(major);
|
|
2856
|
+
}
|
|
2857
|
+
/**
|
|
2694
2858
|
* Compare two versions by their numeric components.
|
|
2695
2859
|
*
|
|
2696
2860
|
* @param left - The version ordered first when it compares lower.
|
|
@@ -3170,6 +3334,7 @@ function blueprintToScripts(blueprint) {
|
|
|
3170
3334
|
if (blueprint.guides) scripts["test:guides"] = `${vitest} --project guides`;
|
|
3171
3335
|
if (blueprint.conformance) scripts["test:conformance"] = `${vitest} --project conformance`;
|
|
3172
3336
|
scripts["test:probe"] = "vitest run --config vite.config.ts --no-cache --reporter=verbose --project probe";
|
|
3337
|
+
scripts["test:bench"] = "vitest bench --config vite.config.ts --no-cache --project probe";
|
|
3173
3338
|
if (distributes) scripts["test:distribution"] = `${vitest} --project distribution`;
|
|
3174
3339
|
if (integrates) scripts["test:integration"] = `${vitest} --project integration`;
|
|
3175
3340
|
if (blueprint.service) scripts["test:service"] = `${vitest} --project service`;
|
|
@@ -3202,11 +3367,14 @@ function blueprintToScripts(blueprint) {
|
|
|
3202
3367
|
scripts.serve = "node dist/app/server/main.cjs";
|
|
3203
3368
|
scripts["serve:build"] = "npm run build:app:server && npm run serve";
|
|
3204
3369
|
}
|
|
3205
|
-
if (publishes)
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
|
|
3370
|
+
if (publishes) {
|
|
3371
|
+
scripts.prepack = scripts.build;
|
|
3372
|
+
scripts.prepublishOnly = [
|
|
3373
|
+
"npm run format:check && npm run lint:check && npm run check && npm run build && npm test",
|
|
3374
|
+
...distributes ? ["npm run test:distribution -- --mode release"] : [],
|
|
3375
|
+
...blueprint.service ? ["npm run test:service"] : []
|
|
3376
|
+
].join(" && ");
|
|
3377
|
+
}
|
|
3210
3378
|
return scripts;
|
|
3211
3379
|
}
|
|
3212
3380
|
/**
|
|
@@ -4013,6 +4181,230 @@ function applyOverrides(artifacts, overrides) {
|
|
|
4013
4181
|
});
|
|
4014
4182
|
}
|
|
4015
4183
|
/**
|
|
4184
|
+
* Replace declared dependency ranges in package manifest text.
|
|
4185
|
+
*
|
|
4186
|
+
* @param manifest - The manifest text to compile.
|
|
4187
|
+
* @param dependencies - The declared names and replacement ranges.
|
|
4188
|
+
* @returns The manifest with every matching dependency-section value replaced,
|
|
4189
|
+
* or `undefined` when any name has no quoted declaration in those sections.
|
|
4190
|
+
*
|
|
4191
|
+
* @remarks
|
|
4192
|
+
* The compiler replaces values in place instead of serializing the manifest,
|
|
4193
|
+
* so description, keywords, scripts, key order, indentation, and every byte
|
|
4194
|
+
* outside the named ranges survive. Every occurrence in `dependencies`,
|
|
4195
|
+
* `devDependencies`, and `peerDependencies` moves, which keeps duplicate
|
|
4196
|
+
* declarations aligned until the manifest's own validation reports the
|
|
4197
|
+
* duplicate. An override or resolution with the same name stays untouched.
|
|
4198
|
+
*
|
|
4199
|
+
* @example
|
|
4200
|
+
* ```ts
|
|
4201
|
+
* import { replaceManifestRanges } from '@orkestrel/scaffold'
|
|
4202
|
+
*
|
|
4203
|
+
* const manifest = '{"devDependencies":{"typescript":"^6"}}\n'
|
|
4204
|
+
* replaceManifestRanges(manifest, [{ name: 'typescript', range: '^7' }])
|
|
4205
|
+
* // the manifest with the declared range replaced
|
|
4206
|
+
* ```
|
|
4207
|
+
*/
|
|
4208
|
+
function replaceManifestRanges(manifest, dependencies) {
|
|
4209
|
+
if (dependencies.length === 0) return manifest;
|
|
4210
|
+
const sectionNames = /* @__PURE__ */ new Set([
|
|
4211
|
+
"dependencies",
|
|
4212
|
+
"devDependencies",
|
|
4213
|
+
"peerDependencies"
|
|
4214
|
+
]);
|
|
4215
|
+
const sections = [];
|
|
4216
|
+
let depth = 0;
|
|
4217
|
+
let cursor = 0;
|
|
4218
|
+
while (cursor < manifest.length) {
|
|
4219
|
+
const character = manifest.charAt(cursor);
|
|
4220
|
+
if (character === "{") {
|
|
4221
|
+
depth += 1;
|
|
4222
|
+
cursor += 1;
|
|
4223
|
+
continue;
|
|
4224
|
+
}
|
|
4225
|
+
if (character === "}") {
|
|
4226
|
+
depth -= 1;
|
|
4227
|
+
cursor += 1;
|
|
4228
|
+
continue;
|
|
4229
|
+
}
|
|
4230
|
+
if (character !== "\"") {
|
|
4231
|
+
cursor += 1;
|
|
4232
|
+
continue;
|
|
4233
|
+
}
|
|
4234
|
+
const start = cursor;
|
|
4235
|
+
cursor += 1;
|
|
4236
|
+
while (cursor < manifest.length) {
|
|
4237
|
+
if (manifest.charAt(cursor) === "\\") {
|
|
4238
|
+
cursor += 2;
|
|
4239
|
+
continue;
|
|
4240
|
+
}
|
|
4241
|
+
if (manifest.charAt(cursor) === "\"") break;
|
|
4242
|
+
cursor += 1;
|
|
4243
|
+
}
|
|
4244
|
+
if (cursor >= manifest.length) return void 0;
|
|
4245
|
+
const end = cursor + 1;
|
|
4246
|
+
if (depth === 1) {
|
|
4247
|
+
const key = (0, _orkestrel_contract.parseJSON)(manifest.slice(start, end));
|
|
4248
|
+
let value = end;
|
|
4249
|
+
while (value < manifest.length && /\s/u.test(manifest.charAt(value))) value += 1;
|
|
4250
|
+
if (manifest.charAt(value) === ":") {
|
|
4251
|
+
value += 1;
|
|
4252
|
+
while (value < manifest.length && /\s/u.test(manifest.charAt(value))) value += 1;
|
|
4253
|
+
if (typeof key === "string" && sectionNames.has(key) && manifest.charAt(value) === "{") {
|
|
4254
|
+
let sectionDepth = 0;
|
|
4255
|
+
let sectionCursor = value;
|
|
4256
|
+
while (sectionCursor < manifest.length) {
|
|
4257
|
+
const sectionCharacter = manifest.charAt(sectionCursor);
|
|
4258
|
+
if (sectionCharacter === "\"") {
|
|
4259
|
+
sectionCursor += 1;
|
|
4260
|
+
while (sectionCursor < manifest.length) {
|
|
4261
|
+
if (manifest.charAt(sectionCursor) === "\\") {
|
|
4262
|
+
sectionCursor += 2;
|
|
4263
|
+
continue;
|
|
4264
|
+
}
|
|
4265
|
+
if (manifest.charAt(sectionCursor) === "\"") break;
|
|
4266
|
+
sectionCursor += 1;
|
|
4267
|
+
}
|
|
4268
|
+
if (sectionCursor >= manifest.length) return void 0;
|
|
4269
|
+
} else if (sectionCharacter === "{") sectionDepth += 1;
|
|
4270
|
+
else if (sectionCharacter === "}") {
|
|
4271
|
+
sectionDepth -= 1;
|
|
4272
|
+
if (sectionDepth === 0) {
|
|
4273
|
+
sections.push({
|
|
4274
|
+
start: value,
|
|
4275
|
+
end: sectionCursor + 1
|
|
4276
|
+
});
|
|
4277
|
+
break;
|
|
4278
|
+
}
|
|
4279
|
+
}
|
|
4280
|
+
sectionCursor += 1;
|
|
4281
|
+
}
|
|
4282
|
+
}
|
|
4283
|
+
}
|
|
4284
|
+
}
|
|
4285
|
+
cursor = end;
|
|
4286
|
+
}
|
|
4287
|
+
const replacements = new Map(dependencies.map(({ name, range }) => [name, range]));
|
|
4288
|
+
const declared = /* @__PURE__ */ new Set();
|
|
4289
|
+
let compiled = manifest;
|
|
4290
|
+
for (const bounds of sections.reverse()) {
|
|
4291
|
+
let section = compiled.slice(bounds.start, bounds.end);
|
|
4292
|
+
let sectionDepth = 0;
|
|
4293
|
+
let sectionCursor = 0;
|
|
4294
|
+
while (sectionCursor < section.length) {
|
|
4295
|
+
const character = section.charAt(sectionCursor);
|
|
4296
|
+
if (character === "{") {
|
|
4297
|
+
sectionDepth += 1;
|
|
4298
|
+
sectionCursor += 1;
|
|
4299
|
+
continue;
|
|
4300
|
+
}
|
|
4301
|
+
if (character === "}") {
|
|
4302
|
+
sectionDepth -= 1;
|
|
4303
|
+
sectionCursor += 1;
|
|
4304
|
+
continue;
|
|
4305
|
+
}
|
|
4306
|
+
if (character !== "\"") {
|
|
4307
|
+
sectionCursor += 1;
|
|
4308
|
+
continue;
|
|
4309
|
+
}
|
|
4310
|
+
const keyStart = sectionCursor;
|
|
4311
|
+
sectionCursor += 1;
|
|
4312
|
+
while (sectionCursor < section.length) {
|
|
4313
|
+
if (section.charAt(sectionCursor) === "\\") {
|
|
4314
|
+
sectionCursor += 2;
|
|
4315
|
+
continue;
|
|
4316
|
+
}
|
|
4317
|
+
if (section.charAt(sectionCursor) === "\"") break;
|
|
4318
|
+
sectionCursor += 1;
|
|
4319
|
+
}
|
|
4320
|
+
if (sectionCursor >= section.length) return void 0;
|
|
4321
|
+
const keyEnd = sectionCursor + 1;
|
|
4322
|
+
const key = (0, _orkestrel_contract.parseJSON)(section.slice(keyStart, keyEnd));
|
|
4323
|
+
let valueStart = keyEnd;
|
|
4324
|
+
while (valueStart < section.length && /\s/u.test(section.charAt(valueStart))) valueStart += 1;
|
|
4325
|
+
if (sectionDepth !== 1 || section.charAt(valueStart) !== ":") {
|
|
4326
|
+
sectionCursor = keyEnd;
|
|
4327
|
+
continue;
|
|
4328
|
+
}
|
|
4329
|
+
valueStart += 1;
|
|
4330
|
+
while (valueStart < section.length && /\s/u.test(section.charAt(valueStart))) valueStart += 1;
|
|
4331
|
+
if (typeof key !== "string" || section.charAt(valueStart) !== "\"") {
|
|
4332
|
+
sectionCursor = keyEnd;
|
|
4333
|
+
continue;
|
|
4334
|
+
}
|
|
4335
|
+
const replacement = replacements.get(key);
|
|
4336
|
+
if (replacement === void 0) {
|
|
4337
|
+
sectionCursor = keyEnd;
|
|
4338
|
+
continue;
|
|
4339
|
+
}
|
|
4340
|
+
let valueEnd = valueStart + 1;
|
|
4341
|
+
while (valueEnd < section.length) {
|
|
4342
|
+
if (section.charAt(valueEnd) === "\\") {
|
|
4343
|
+
valueEnd += 2;
|
|
4344
|
+
continue;
|
|
4345
|
+
}
|
|
4346
|
+
if (section.charAt(valueEnd) === "\"") break;
|
|
4347
|
+
valueEnd += 1;
|
|
4348
|
+
}
|
|
4349
|
+
if (valueEnd >= section.length) return void 0;
|
|
4350
|
+
const range = JSON.stringify(replacement);
|
|
4351
|
+
section = section.slice(0, valueStart) + range + section.slice(valueEnd + 1);
|
|
4352
|
+
declared.add(key);
|
|
4353
|
+
sectionCursor = valueStart + range.length;
|
|
4354
|
+
}
|
|
4355
|
+
compiled = compiled.slice(0, bounds.start) + section + compiled.slice(bounds.end);
|
|
4356
|
+
}
|
|
4357
|
+
return dependencies.every(({ name }) => declared.has(name)) ? compiled : void 0;
|
|
4358
|
+
}
|
|
4359
|
+
/**
|
|
4360
|
+
* Replace dependency ranges in a plan's manifest and recompute its identity.
|
|
4361
|
+
*
|
|
4362
|
+
* @param plan - The plan carrying the manifest artifact to compile.
|
|
4363
|
+
* @param dependencies - The declared names and replacement ranges.
|
|
4364
|
+
* @returns A plan with replaced manifest ranges and a matching hash, or
|
|
4365
|
+
* `undefined` when the manifest or its identity cannot be compiled.
|
|
4366
|
+
*
|
|
4367
|
+
* @remarks
|
|
4368
|
+
* The blueprint remains the workspace specification that produced the plan.
|
|
4369
|
+
* Registry answers alter only the manifest artifact that materialization will
|
|
4370
|
+
* write. Recomputing the hash in the same compiler keeps the plan's identity
|
|
4371
|
+
* tied to those final bytes rather than to the unresolved floor.
|
|
4372
|
+
*
|
|
4373
|
+
* @example
|
|
4374
|
+
* ```ts
|
|
4375
|
+
* import { replacePlanRanges } from '@orkestrel/scaffold'
|
|
4376
|
+
*
|
|
4377
|
+
* replacePlanRanges(plan, releases) // the plan carrying the resolved manifest ranges
|
|
4378
|
+
* ```
|
|
4379
|
+
*/
|
|
4380
|
+
function replacePlanRanges(plan, dependencies) {
|
|
4381
|
+
let replaced = false;
|
|
4382
|
+
let refused = false;
|
|
4383
|
+
const artifacts = plan.artifacts.map((artifact) => {
|
|
4384
|
+
if (artifact.path !== "package.json" || artifact.origin === "host") return artifact;
|
|
4385
|
+
const content = replaceManifestRanges(artifact.content, dependencies);
|
|
4386
|
+
if (content === void 0) {
|
|
4387
|
+
refused = true;
|
|
4388
|
+
return artifact;
|
|
4389
|
+
}
|
|
4390
|
+
replaced = true;
|
|
4391
|
+
return {
|
|
4392
|
+
...artifact,
|
|
4393
|
+
content
|
|
4394
|
+
};
|
|
4395
|
+
});
|
|
4396
|
+
if (!replaced || refused) return void 0;
|
|
4397
|
+
const compiled = {
|
|
4398
|
+
...plan,
|
|
4399
|
+
artifacts
|
|
4400
|
+
};
|
|
4401
|
+
const hash = planToHash(compiled);
|
|
4402
|
+
return hash === void 0 ? void 0 : {
|
|
4403
|
+
...compiled,
|
|
4404
|
+
hash
|
|
4405
|
+
};
|
|
4406
|
+
}
|
|
4407
|
+
/**
|
|
4016
4408
|
* Compute a plan's content identity.
|
|
4017
4409
|
*
|
|
4018
4410
|
* @param plan - The plan to identify.
|
|
@@ -4883,7 +5275,9 @@ exports.MAX_MANIFEST_BYTES = MAX_MANIFEST_BYTES;
|
|
|
4883
5275
|
exports.MAX_NAME_LENGTH = MAX_NAME_LENGTH;
|
|
4884
5276
|
exports.MAX_PATH_LENGTH = MAX_PATH_LENGTH;
|
|
4885
5277
|
exports.MAX_RANGE_LENGTH = MAX_RANGE_LENGTH;
|
|
5278
|
+
exports.MAX_REGISTRY_BYTES = MAX_REGISTRY_BYTES;
|
|
4886
5279
|
exports.MAX_TOTAL_ARTIFACT_BYTES = MAX_TOTAL_ARTIFACT_BYTES;
|
|
5280
|
+
exports.MAX_TOTAL_REGISTRY_BYTES = MAX_TOTAL_REGISTRY_BYTES;
|
|
4887
5281
|
exports.MINIMUM_NODE_VERSION = MINIMUM_NODE_VERSION;
|
|
4888
5282
|
exports.NAME_PATTERN = NAME_PATTERN;
|
|
4889
5283
|
exports.ORCHESTRATION_PATH_NAMES = ORCHESTRATION_PATH_NAMES;
|
|
@@ -4927,6 +5321,7 @@ exports.computeHash = computeHash;
|
|
|
4927
5321
|
exports.contentToHex = contentToHex;
|
|
4928
5322
|
exports.createBlueprint = createBlueprint;
|
|
4929
5323
|
exports.dependenciesToQuestions = dependenciesToQuestions;
|
|
5324
|
+
exports.extractRangeMajor = extractRangeMajor;
|
|
4930
5325
|
exports.extractVersion = extractVersion;
|
|
4931
5326
|
exports.inferDrift = inferDrift;
|
|
4932
5327
|
exports.inferGroup = inferGroup;
|
|
@@ -4971,6 +5366,8 @@ exports.pathToCondition = pathToCondition;
|
|
|
4971
5366
|
exports.planToFindings = planToFindings;
|
|
4972
5367
|
exports.planToHash = planToHash;
|
|
4973
5368
|
exports.planToSummary = planToSummary;
|
|
5369
|
+
exports.replaceManifestRanges = replaceManifestRanges;
|
|
5370
|
+
exports.replacePlanRanges = replacePlanRanges;
|
|
4974
5371
|
exports.selectGroups = selectGroups;
|
|
4975
5372
|
exports.selectHostPaths = selectHostPaths;
|
|
4976
5373
|
exports.serializeTypeScriptString = serializeTypeScriptString;
|