@intentius/chant 0.124.14 → 0.124.16
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/build.d.ts +6 -0
- package/dist/build.d.ts.map +1 -1
- package/dist/build.js +1 -0
- package/dist/change-set.d.ts +24 -2
- package/dist/change-set.d.ts.map +1 -1
- package/dist/change-set.js +50 -1
- package/dist/ci-jobs.d.ts +227 -0
- package/dist/ci-jobs.d.ts.map +1 -0
- package/dist/ci-jobs.js +448 -0
- package/dist/cli/flush.d.ts +16 -0
- package/dist/cli/flush.d.ts.map +1 -0
- package/dist/cli/flush.js +42 -0
- package/dist/cli/handlers/approve.d.ts +98 -0
- package/dist/cli/handlers/approve.d.ts.map +1 -0
- package/dist/cli/handlers/approve.js +495 -0
- package/dist/cli/handlers/operator.d.ts +1 -95
- package/dist/cli/handlers/operator.d.ts.map +1 -1
- package/dist/cli/handlers/operator.js +4 -488
- package/dist/cli/handlers/override-approve.js +1 -1
- package/dist/cli/main.d.ts +4 -15
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +4 -1062
- package/dist/cli/parse-args.d.ts +6 -0
- package/dist/cli/parse-args.d.ts.map +1 -0
- package/dist/cli/parse-args.js +1028 -0
- package/dist/components/fan-out-record.d.ts +1 -1
- package/dist/components/fan-out-record.d.ts.map +1 -1
- package/dist/components/fan-out-record.js +3 -7
- package/dist/components/fan-out-run.d.ts +5 -3
- package/dist/components/fan-out-run.d.ts.map +1 -1
- package/dist/components/fan-out-run.js +7 -5
- package/dist/components/pr-pipeline.d.ts.map +1 -1
- package/dist/components/pr-pipeline.js +3 -2
- package/dist/composite.d.ts +10 -2
- package/dist/composite.d.ts.map +1 -1
- package/dist/composite.js +8 -0
- package/dist/discovery/collect.d.ts +2 -1
- package/dist/discovery/collect.d.ts.map +1 -1
- package/dist/discovery/collect.js +16 -1
- package/dist/discovery/fold-import.d.ts.map +1 -1
- package/dist/discovery/fold-import.js +2 -107
- package/dist/discovery/host-composite.d.ts +35 -0
- package/dist/discovery/host-composite.d.ts.map +1 -0
- package/dist/discovery/host-composite.js +93 -0
- package/dist/discovery/index.d.ts +9 -0
- package/dist/discovery/index.d.ts.map +1 -1
- package/dist/discovery/index.js +1 -1
- package/dist/gate-decision.d.ts +20 -9
- package/dist/gate-decision.d.ts.map +1 -1
- package/dist/gate-decision.js +72 -19
- package/dist/gated-waves.d.ts +25 -6
- package/dist/gated-waves.d.ts.map +1 -1
- package/dist/gated-waves.js +21 -6
- package/dist/lifecycle/gate-audit.d.ts +69 -2
- package/dist/lifecycle/gate-audit.d.ts.map +1 -1
- package/dist/lifecycle/gate-audit.js +76 -2
- package/dist/lifecycle/gate-ledger.d.ts +24 -0
- package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
- package/dist/lifecycle/gate-ledger.js +9 -1
- package/dist/op/activities/activity-contracts.d.ts +5 -5
- package/dist/op/activities/activity-contracts.js +1 -1
- package/dist/op/activities/change-set.d.ts +8 -3
- package/dist/op/activities/change-set.d.ts.map +1 -1
- package/dist/op/activities/change-set.js +5 -2
- package/dist/op/activities/reconcile.d.ts +28 -16
- package/dist/op/activities/reconcile.d.ts.map +1 -1
- package/dist/op/activities/reconcile.js +34 -20
- package/dist/op/builders.d.ts +1 -1
- package/dist/op/builders.d.ts.map +1 -1
- package/dist/op/builders.js +1 -1
- package/dist/op/op-waves-run.d.ts +2 -2
- package/dist/op/op-waves-run.d.ts.map +1 -1
- package/dist/op/op-waves-run.js +8 -9
- package/dist/op/op-waves.d.ts.map +1 -1
- package/dist/op/op-waves.js +4 -8
- package/dist/package-version.d.ts +2 -0
- package/dist/package-version.d.ts.map +1 -0
- package/dist/package-version.js +10 -0
- package/dist/wave-engine.d.ts +62 -0
- package/dist/wave-engine.d.ts.map +1 -0
- package/dist/wave-engine.js +59 -0
- package/dist/wave-layout.d.ts +29 -0
- package/dist/wave-layout.d.ts.map +1 -0
- package/dist/wave-layout.js +41 -0
- package/dist/wave-runtime.d.ts +29 -0
- package/dist/wave-runtime.d.ts.map +1 -0
- package/dist/wave-runtime.js +103 -0
- package/dist/wave-runtime.mjs +331 -0
- package/dist/workspace/__fixtures__/contract-repo.d.ts +7 -0
- package/dist/workspace/__fixtures__/contract-repo.d.ts.map +1 -1
- package/dist/workspace/__fixtures__/contract-repo.js +17 -1
- package/dist/workspace/__fixtures__/sessions.d.ts +1 -1
- package/dist/workspace/__fixtures__/sessions.d.ts.map +1 -1
- package/dist/workspace/__fixtures__/sessions.js +3 -3
- package/dist/workspace/ajv2020.d.ts +5 -0
- package/dist/workspace/ajv2020.d.ts.map +1 -0
- package/dist/workspace/ajv2020.js +14 -0
- package/dist/workspace/change-set.schema.json +5 -3
- package/dist/workspace/ci-green-workflow.d.ts +3 -1
- package/dist/workspace/ci-green-workflow.d.ts.map +1 -1
- package/dist/workspace/ci-green-workflow.js +5 -2
- package/dist/workspace/class-data.d.ts +84 -0
- package/dist/workspace/class-data.d.ts.map +1 -0
- package/dist/workspace/class-data.js +238 -0
- package/dist/workspace/declaration.d.ts.map +1 -1
- package/dist/workspace/declaration.js +4 -8
- package/dist/workspace/kinds.d.ts +3 -7
- package/dist/workspace/kinds.d.ts.map +1 -1
- package/dist/workspace/kinds.js +8 -45
- package/dist/workspace/points.d.ts.map +1 -1
- package/dist/workspace/points.js +2 -5
- package/dist/workspace/principal-classes.d.ts +4 -11
- package/dist/workspace/principal-classes.d.ts.map +1 -1
- package/dist/workspace/principal-classes.js +13 -99
- package/package.json +5 -3
- package/src/build.ts +8 -0
- package/src/change-set.test.ts +48 -0
- package/src/change-set.ts +52 -2
- package/src/ci-jobs.test.ts +49 -0
- package/src/ci-jobs.ts +515 -0
- package/src/cli/flush.ts +44 -0
- package/src/cli/handlers/approve.ts +618 -0
- package/src/cli/handlers/operator.ts +10 -608
- package/src/cli/handlers/override-approve.test.ts +1 -1
- package/src/cli/handlers/override-approve.ts +1 -1
- package/src/cli/main.ts +5 -816
- package/src/cli/parse-args.ts +781 -0
- package/src/components/fan-out-record.ts +3 -7
- package/src/components/fan-out-run.ts +7 -5
- package/src/components/pr-pipeline.ts +3 -2
- package/src/composite.ts +15 -3
- package/src/discovery/collect.ts +15 -1
- package/src/discovery/fold-build-parity.test.ts +71 -0
- package/src/discovery/fold-import.ts +2 -113
- package/src/discovery/fold-project-provenance.test.ts +21 -4
- package/src/discovery/host-composite.ts +101 -0
- package/src/discovery/index.ts +11 -1
- package/src/gate-decision-bundle.test.ts +6 -4
- package/src/gate-decision-identity.test.ts +59 -6
- package/src/gate-decision.ts +81 -21
- package/src/gated-waves.ts +28 -6
- package/src/lifecycle/gate-audit.test.ts +55 -1
- package/src/lifecycle/gate-audit.ts +116 -3
- package/src/lifecycle/gate-ledger.test.ts +20 -1
- package/src/lifecycle/gate-ledger.ts +33 -1
- package/src/op/activities/activity-contracts.ts +1 -1
- package/src/op/activities/change-set.ts +11 -3
- package/src/op/activities/lexicon-upgrade.test.ts +2 -0
- package/src/op/activities/reconcile.test.ts +62 -2
- package/src/op/activities/reconcile.ts +46 -22
- package/src/op/builders.ts +1 -1
- package/src/op/op-waves-run.ts +9 -9
- package/src/op/op-waves.test.ts +2 -0
- package/src/op/op-waves.ts +4 -8
- package/src/op/work-lease-run.test.ts +12 -4
- package/src/package-version.ts +11 -0
- package/src/wave-engine.test.ts +107 -0
- package/src/wave-engine.ts +98 -0
- package/src/wave-layout.ts +44 -0
- package/src/wave-runtime-bundle.test.ts +70 -0
- package/src/wave-runtime.e2e.test.ts +177 -0
- package/src/wave-runtime.ts +104 -0
- package/src/workspace/__fixtures__/contract-repo.ts +17 -1
- package/src/workspace/__fixtures__/sessions.ts +3 -3
- package/src/workspace/ajv2020.ts +17 -0
- package/src/workspace/change-set.schema.json +5 -3
- package/src/workspace/ci-green-workflow.test.ts +4 -4
- package/src/workspace/ci-green-workflow.ts +5 -2
- package/src/workspace/class-data.test.ts +64 -0
- package/src/workspace/class-data.ts +236 -0
- package/src/workspace/declaration.ts +4 -10
- package/src/workspace/kinds.ts +8 -40
- package/src/workspace/points.ts +2 -5
- package/src/workspace/principal-classes.ts +13 -99
- package/src/workspace/records-formats.test.ts +7 -2
- package/src/workspace/records-sessions-write.test.ts +3 -3
- package/src/workspace/status-contract.e2e.test.ts +37 -0
- package/src/workspace/status-contract.test.ts +23 -21
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
* fails ({@link resolveKind}).
|
|
18
18
|
*/
|
|
19
19
|
import type { WorkspaceTree } from "./tree.js";
|
|
20
|
+
import { findInstalledPackage } from "./class-data.js";
|
|
20
21
|
export declare const KINDS_SCHEMA_ID: string;
|
|
21
22
|
/** The subpath a package publishes its kinds at. */
|
|
22
23
|
export declare const KINDS_SUBPATH = "./workspace-kinds";
|
|
@@ -212,13 +213,8 @@ export interface GraphPlaceholders {
|
|
|
212
213
|
* in every string key and value. Other braces are left as they are.
|
|
213
214
|
*/
|
|
214
215
|
export declare function substituteGraphConfig(config: Record<string, unknown>, at: GraphPlaceholders): Record<string, unknown>;
|
|
215
|
-
/**
|
|
216
|
-
|
|
217
|
-
* bare import: `node_modules/<name>` in `fromDir` and each directory above it.
|
|
218
|
-
* It looks for the directory, not for an entry point, so it works for a
|
|
219
|
-
* package whose `exports` don't expose `package.json`.
|
|
220
|
-
*/
|
|
221
|
-
export declare function findInstalledPackage(name: string, fromDir: string): string | undefined;
|
|
216
|
+
/** Where an installed package is, as Node finds a bare import (`./class-data.ts`, so the gate-decision bundle shares it). */
|
|
217
|
+
export { findInstalledPackage };
|
|
222
218
|
export interface PinLike {
|
|
223
219
|
package: string | null;
|
|
224
220
|
version: string | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kinds.d.ts","sourceRoot":"","sources":["../../src/workspace/kinds.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;
|
|
1
|
+
{"version":3,"file":"kinds.d.ts","sourceRoot":"","sources":["../../src/workspace/kinds.ts"],"names":[],"mappings":"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"}
|
package/dist/workspace/kinds.js
CHANGED
|
@@ -16,12 +16,13 @@
|
|
|
16
16
|
* kinds claim one directory, the highest precedence decides, and a tie
|
|
17
17
|
* fails ({@link resolveKind}).
|
|
18
18
|
*/
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import { dirname, isAbsolute, join, relative, resolve } from "node:path";
|
|
19
|
+
import { readFileSync } from "node:fs";
|
|
20
|
+
import { isAbsolute, join, relative, resolve } from "node:path";
|
|
22
21
|
import schema from "./workspace-kinds.schema.json" with { type: "json" };
|
|
23
22
|
import { joinPath, skippedDir } from "./tree.js";
|
|
24
23
|
import { checkPinIntegrity } from "./pin-integrity.js";
|
|
24
|
+
import { dataExportTarget, findInstalledPackage } from "./class-data.js";
|
|
25
|
+
import { loadAjv2020 } from "./ajv2020.js";
|
|
25
26
|
export const KINDS_SCHEMA_ID = schema.$id;
|
|
26
27
|
/** The subpath a package publishes its kinds at. */
|
|
27
28
|
export const KINDS_SUBPATH = "./workspace-kinds";
|
|
@@ -224,10 +225,7 @@ let compiled;
|
|
|
224
225
|
function validator() {
|
|
225
226
|
if (compiled)
|
|
226
227
|
return compiled;
|
|
227
|
-
const
|
|
228
|
-
// ajv is CommonJS; its class is the default export, or that export's own default.
|
|
229
|
-
const mod = require("ajv/dist/2020");
|
|
230
|
-
const Ajv = (mod.default ?? mod);
|
|
228
|
+
const Ajv = loadAjv2020();
|
|
231
229
|
compiled = new Ajv({ allErrors: true, strict: true }).compile(schema);
|
|
232
230
|
return compiled;
|
|
233
231
|
}
|
|
@@ -289,24 +287,7 @@ export function parseKindData(text, source) {
|
|
|
289
287
|
* subpath to code, which chant never runs for plugin data.
|
|
290
288
|
*/
|
|
291
289
|
export function kindsExportTarget(pkg, subpath = KINDS_SUBPATH) {
|
|
292
|
-
|
|
293
|
-
if (!exports || typeof exports !== "object" || Array.isArray(exports))
|
|
294
|
-
return undefined;
|
|
295
|
-
const entry = exports[subpath];
|
|
296
|
-
if (entry === undefined)
|
|
297
|
-
return undefined;
|
|
298
|
-
let target = entry;
|
|
299
|
-
if (target && typeof target === "object" && !Array.isArray(target)) {
|
|
300
|
-
const conditions = target;
|
|
301
|
-
target = conditions.default ?? conditions.import ?? conditions.require;
|
|
302
|
-
}
|
|
303
|
-
if (typeof target !== "string") {
|
|
304
|
-
return { problem: `exports["${subpath}"] must name one file, as a string or a "default" condition` };
|
|
305
|
-
}
|
|
306
|
-
if (!target.startsWith("./") || !target.endsWith(".json")) {
|
|
307
|
-
return { problem: `exports["${subpath}"] is ${target}; it must name a .json file inside the package, since chant reads plugin data as data and never runs a package's code` };
|
|
308
|
-
}
|
|
309
|
-
return target;
|
|
290
|
+
return dataExportTarget(pkg, subpath);
|
|
310
291
|
}
|
|
311
292
|
/** Read the kinds a package directory publishes. Reads files only; imports nothing. */
|
|
312
293
|
export function readPackageKinds(packageDir, source) {
|
|
@@ -369,26 +350,8 @@ export function substituteGraphConfig(config, at) {
|
|
|
369
350
|
};
|
|
370
351
|
return walk(config);
|
|
371
352
|
}
|
|
372
|
-
/**
|
|
373
|
-
|
|
374
|
-
* bare import: `node_modules/<name>` in `fromDir` and each directory above it.
|
|
375
|
-
* It looks for the directory, not for an entry point, so it works for a
|
|
376
|
-
* package whose `exports` don't expose `package.json`.
|
|
377
|
-
*/
|
|
378
|
-
export function findInstalledPackage(name, fromDir) {
|
|
379
|
-
for (let dir = resolve(fromDir);; dir = dirname(dir)) {
|
|
380
|
-
const candidate = join(dir, "node_modules", ...name.split("/"));
|
|
381
|
-
try {
|
|
382
|
-
if (statSync(candidate).isDirectory() && existsSync(join(candidate, "package.json")))
|
|
383
|
-
return candidate;
|
|
384
|
-
}
|
|
385
|
-
catch {
|
|
386
|
-
// Not here; keep walking.
|
|
387
|
-
}
|
|
388
|
-
if (dirname(dir) === dir)
|
|
389
|
-
return undefined;
|
|
390
|
-
}
|
|
391
|
-
}
|
|
353
|
+
/** Where an installed package is, as Node finds a bare import (`./class-data.ts`, so the gate-decision bundle shares it). */
|
|
354
|
+
export { findInstalledPackage };
|
|
392
355
|
/**
|
|
393
356
|
* The directory a pin's plugin data is read from: an installed package at
|
|
394
357
|
* the pinned version, looked up from `workspaceRoot`, or a path pin's
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"points.d.ts","sourceRoot":"","sources":["../../src/workspace/points.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;
|
|
1
|
+
{"version":3,"file":"points.d.ts","sourceRoot":"","sources":["../../src/workspace/points.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAMH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAGnF,eAAO,MAAM,yBAAyB,QAAa,CAAC;AAIpD;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB;aAC9B,MAAM;iBAAI,MAAM,EAAE,SAAS;iBAAE,GAAG,EAAE,QAAQ;iBAAE,WAAW,EAAE,kDAAkD;;aAC3G,QAAQ;iBAAI,MAAM,EAAE,SAAS;iBAAE,GAAG,EAAE,QAAQ;iBAAE,WAAW,EAAE,+CAA+C;;aAC1G,WAAW;iBAAI,MAAM,EAAE,SAAS;iBAAE,GAAG,EAAE,QAAQ;iBAAE,WAAW,EAAE,wDAAwD;;aACtH,OAAO;iBAAI,MAAM,EAAE,QAAQ;iBAAE,GAAG,EAAE,SAAS;iBAAE,WAAW,EAAE,4DAA4D;;aACtH,MAAM;iBAAI,MAAM,EAAE,QAAQ;iBAAE,GAAG,EAAE,QAAQ;iBAAE,WAAW,EAAE,mCAAmC;;aAC3F,MAAM;iBAAI,MAAM,EAAE,QAAQ;iBAAE,GAAG,EAAE,QAAQ;iBAAE,WAAW,EAAE,sCAAsC;;aAC9F,IAAI;iBAAI,MAAM,EAAE,QAAQ;iBAAE,GAAG,EAAE,MAAM;iBAAE,WAAW,EAAE,gJAAgJ;;aACpM,GAAG;iBAAI,MAAM,EAAE,QAAQ;iBAAE,GAAG,EAAE,UAAU;iBAAE,WAAW,EAAE,mJAAmJ;;aAC1M,MAAM;iBAAI,MAAM,EAAE,IAAI;iBAAE,GAAG,EAAE,QAAQ;iBAAE,WAAW,EAAE,0BAA0B;;aAC9E,IAAI;iBAAI,MAAM,EAAE,QAAQ;iBAAE,GAAG,EAAE,MAAM;iBAAE,WAAW,EAAE,4BAA4B;;aAChF,OAAO;iBAAI,MAAM,EAAE,QAAQ;iBAAE,GAAG,EAAE,SAAS;iBAAE,WAAW,EAAE,uGAAuG;;aACjK,WAAW;iBAAI,MAAM,EAAE,QAAQ;iBAAE,GAAG,EAAE,aAAa;iBAAE,WAAW,EAAE,oCAAoC;;aACtG,SAAS;iBAAI,MAAM,EAAE,YAAY;iBAAE,GAAG,EAAE,WAAW;iBAAE,WAAW,EAAE,6CAA6C;;CACvG,CAAC;AACX,MAAM,MAAM,gBAAgB,GAAG,MAAM,OAAO,mBAAmB,CAAC;AAChE,eAAO,MAAM,wBAAwB,EAAuC,gBAAgB,EAAE,CAAC;AAE/F,qEAAqE;AACrE,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGhD;AAID,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEvD,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,YAAY,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,uIAAuI;IACvI,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,EAAE,CAAC;CAC9C;AAED,MAAM,MAAM,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;AACtD,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAEnI,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAChC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,OAAO,GACf;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,QAAQ,EAAE,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAClD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GACtH;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvE,MAAM,WAAW,KAAK;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,0FAA0F;IAC1F,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,QAAQ,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB;AAED,2GAA2G;AAC3G,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,WAAY,SAAQ,KAAK;IAElC,QAAQ,CAAC,IAAI,EAAE,MAAM;IACrB,QAAQ,CAAC,QAAQ,EAAE,YAAY,EAAE;IAFnC,YACW,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,YAAY,EAAE,EAIlC;CACF;AAED,+FAA+F;AAC/F,wBAAgB,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,CAAC,MAAM,GAAG,OAAO,CAAC,EAAE,CAInE;AA8ED,wDAAwD;AACxD,wBAAgB,cAAc,CAAC,IAAI,EAAE,OAAO,GAAG,YAAY,EAAE,CAyB5D;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAa7E;AAED,uCAAuC;AACvC,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAEtF;AAED,oGAAoG;AACpG,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAWhD;AAID,6GAA6G;AAC7G,eAAO,MAAM,YAAY,UAAW,KAAK,KAAG,MAAkC,CAAC;AAE/E;;;GAGG;AACH,eAAO,MAAM,UAAU,SAAU,MAAM,WAAW,MAAM,UAAU,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,UAAU,KAAK,KAAG,MAAoE,CAAC;AAIhL,wHAAwH;AACxH,MAAM,WAAW,KAAK;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,EAAE,CAAC;CAC7C;AAED,iGAAiG;AACjG,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,GAAG,SAAS,GAAG,QAAQ,CAE9E;AAID;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,GAAG;IAAE,KAAK,EAAE,KAAK,CAAA;CAAE,GAAG;IAAE,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CA0BlG;AAED,mDAAmD;AACnD,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,KAAK,GAAG,SAAS,CAOxE;AAED,gHAAgH;AAChH,eAAO,MAAM,QAAQ,SAAU,MAAM,QAAQ,MAAM,KAAG,MAAwC,CAAC;AAE/F,kCAAkC;AAClC,wBAAgB,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CAG1E;AA4BD,gHAAgH;AAChH,eAAO,MAAM,OAAO,SAAU,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,UAAU,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,OAC2C,CAAC;AAEvI,wEAAwE;AACxE,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,YAAY,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,EAAE,CAAC;CAC7C;AAED;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/C;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAChH;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GACjI;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,CAAC;AAE5B,0FAA0F;AAC1F,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAK/E;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,QAAQ,GAAG,YAAY,CAE7D;AAED,qCAAqC;AACrC,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,2BAA2B;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,YAAY,CAAC;IACvB,gCAAgC;IAChC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED;;;;;GAKG;AACH,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,EAAE,YAAY,KAAK,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,UAAU,CAAA;CAAE,CAAC,CAAC;AAIjG,MAAM,MAAM,WAAW,GACnB;IAAE,QAAQ,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GACvG;IAAE,QAAQ,EAAE,KAAK,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvI;;;;;;;;;;;GAWG;AACH,wBAAgB,OAAO,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,GAAG,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,WAAW,CA2B1G;AAED;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;IACjC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,WAAW,GACnB;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IAAC,OAAO,EAAE;QAAE,IAAI,EAAE,OAAO,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,UAAU,EAAE,CAAA;CAAE,GACnI;IACE,MAAM,EAAE,UAAU,CAAC;IACnB,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IACzB,OAAO,EAAE;QAAE,IAAI,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3D,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,gFAAgF;IAChF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,UAAU,EAAE,CAAC;CAC3B,GACD;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAAC,WAAW,EAAE,UAAU,EAAE,CAAA;CAAE,CAAC;AAErH,gHAAgH;AAChH,qBAAa,aAAc,SAAQ,KAAK;IACtC,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF;AAED;;;;;GAKG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC,CA0DhI;AAID,qFAAqF;AACrF,eAAO,MAAM,oBAAoB,uFAOS,CAAC;AAC3C,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtE,2EAA2E;AAC3E,wBAAgB,YAAY,CAAC,MAAM,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAG3E;AAED,yGAAyG;AACzG,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,YAAY,EAAE,CAAA;CAAE,CAkBrJ;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,gBAAgB,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,OAAO,EAAE,kBAAkB,GAAG,IAAI,CAoBhH"}
|
package/dist/workspace/points.js
CHANGED
|
@@ -32,9 +32,9 @@
|
|
|
32
32
|
* about them on read.
|
|
33
33
|
*/
|
|
34
34
|
import { createHash } from "node:crypto";
|
|
35
|
-
import { createRequire } from "node:module";
|
|
36
35
|
import { dirname, posix, relative, resolve, sep } from "node:path";
|
|
37
36
|
import schema from "./decision-points.schema.json" with { type: "json" };
|
|
37
|
+
import { loadAjv2020 } from "./ajv2020.js";
|
|
38
38
|
export const DECISION_POINTS_SCHEMA_ID = schema.$id;
|
|
39
39
|
// ── The read-contract outputs an input may name ─────────────────────────────
|
|
40
40
|
/**
|
|
@@ -143,10 +143,7 @@ let compiled;
|
|
|
143
143
|
function validator() {
|
|
144
144
|
if (compiled)
|
|
145
145
|
return compiled;
|
|
146
|
-
const
|
|
147
|
-
// ajv is CommonJS; its class is the default export, or that export's own default.
|
|
148
|
-
const mod = require("ajv/dist/2020");
|
|
149
|
-
const Ajv = (mod.default ?? mod);
|
|
146
|
+
const Ajv = loadAjv2020();
|
|
150
147
|
compiled = new Ajv({ allErrors: true, strict: false }).compile(schema);
|
|
151
148
|
return compiled;
|
|
152
149
|
}
|
|
@@ -21,13 +21,13 @@
|
|
|
21
21
|
* editing its own copy of the plugin. A package pin is read from the
|
|
22
22
|
* installed package, which must be at the version the base pins.
|
|
23
23
|
*/
|
|
24
|
+
import { type ClassData, type PackageFiles } from "./class-data.js";
|
|
24
25
|
import { type KindLoadProblem, type PinLike } from "./kinds.js";
|
|
25
26
|
import type { TrustPolicy } from "./trust/policy.js";
|
|
26
27
|
import { type WorkspaceTree } from "./tree.js";
|
|
27
28
|
import { type PrincipalClass } from "./identity-gate-rule.js";
|
|
28
29
|
export declare const PRINCIPALS_SCHEMA_ID: string;
|
|
29
|
-
|
|
30
|
-
export declare const PRINCIPALS_SUBPATH = "./workspace-principals";
|
|
30
|
+
export { PRINCIPALS_SUBPATH } from "./class-data.js";
|
|
31
31
|
export { CORE_CLASSES, CORE_PRINCIPAL_CLASSES, type CorePrincipalClass, type PrincipalClass } from "./identity-gate-rule.js";
|
|
32
32
|
/** A class name: a core class, or a domain class a pinned package supplies. */
|
|
33
33
|
export type PrincipalClassName = string;
|
|
@@ -57,11 +57,8 @@ export declare function roleGrants(policy: TrustPolicy): Record<string, string[]
|
|
|
57
57
|
export declare function classesOf(classes: ClassRegistry, policy: TrustPolicy, principal: string | null): string[];
|
|
58
58
|
/** The class write scope judges `principal` as: the first class its grants put it in, or `human`. */
|
|
59
59
|
export declare function principalClass(policy: TrustPolicy, principal: string | null, classes?: ClassRegistry): string;
|
|
60
|
-
export
|
|
61
|
-
|
|
62
|
-
/** Why some of the data can't be used, one line each. Empty when all of it can. */
|
|
63
|
-
problems: string[];
|
|
64
|
-
}
|
|
60
|
+
export type { ClassData, PackageFiles } from "./class-data.js";
|
|
61
|
+
export { diskFiles } from "./class-data.js";
|
|
65
62
|
/**
|
|
66
63
|
* Check the text of a principals file against
|
|
67
64
|
* `workspace-principals.schema.json` and the rules the schema can't say: no
|
|
@@ -69,10 +66,6 @@ export interface ClassData {
|
|
|
69
66
|
* in the classes and in the messages.
|
|
70
67
|
*/
|
|
71
68
|
export declare function parseClassData(text: string, source: string): ClassData;
|
|
72
|
-
/** A package's files, by a `/`-separated path inside it, or undefined when one is not there. */
|
|
73
|
-
export type PackageFiles = (path: string) => string | undefined;
|
|
74
|
-
/** A package directory on disk. */
|
|
75
|
-
export declare function diskFiles(dir: string): PackageFiles;
|
|
76
69
|
/** A package directory at `dir` in `tree`, such as the workspace at the base revision. */
|
|
77
70
|
export declare function treeFiles(tree: WorkspaceTree, dir: string): PackageFiles;
|
|
78
71
|
/** Read the classes a package publishes at `./workspace-principals`. Reads files only; imports nothing. A package that publishes none supplies none. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"principal-classes.d.ts","sourceRoot":"","sources":["../../src/workspace/principal-classes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;
|
|
1
|
+
{"version":3,"file":"principal-classes.d.ts","sourceRoot":"","sources":["../../src/workspace/principal-classes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAA8D,KAAK,SAAS,EAAE,KAAK,YAAY,EAAqB,MAAM,cAAc,CAAC;AAChJ,OAAO,EAAoB,KAAK,eAAe,EAAE,KAAK,OAAO,EAAE,MAAM,SAAS,CAAC;AAE/E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAY,KAAK,aAAa,EAAE,MAAM,QAAQ,CAAC;AACtD,OAAO,EAAwD,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGjH,eAAO,MAAM,oBAAoB,QAAa,CAAC;AAE/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAElD,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAE,KAAK,kBAAkB,EAAE,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE1H,+EAA+E;AAC/E,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAExC,uHAAuH;AACvH,eAAO,MAAM,UAAU,QAAiC,CAAC;AAEzD,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAAC;IAC9C,kEAAkE;IAClE,KAAK,IAAI,MAAM,EAAE,CAAC;IAClB,oFAAoF;IACpF,GAAG,IAAI,SAAS,cAAc,EAAE,CAAC;CAClC;AAED,wBAAgB,mBAAmB,CAAC,KAAK,GAAE,SAAS,cAAc,EAAO,GAAG,aAAa,CAQxF;AAED,+FAA+F;AAC/F,wBAAgB,iBAAiB,IAAI,aAAa,CAEjD;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAExE;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,EAAE,CAEzG;AAED,qGAAqG;AACrG,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,OAAO,GAAE,aAAmC,GAAG,MAAM,CAElI;AAkBD,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,CAatE;AAED,0FAA0F;AAC1F,wBAAgB,SAAS,CAAC,IAAI,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,GAAG,YAAY,CAUxE;AAED,wJAAwJ;AACxJ,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,CAEjF;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,aAAa,CAAC;IACxB,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,OAAO,EAAE,EAAE,aAAa,EAAE,MAAM,EAAE,IAAI,GAAE;IAAE,IAAI,CAAC,EAAE,aAAa,CAAA;CAAO,GAAG,aAAa,CAuBrI;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,aAAa,GAAG,MAAM,EAAE,CAEhH"}
|
|
@@ -21,20 +21,17 @@
|
|
|
21
21
|
* editing its own copy of the plugin. A package pin is read from the
|
|
22
22
|
* installed package, which must be at the version the base pins.
|
|
23
23
|
*/
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
26
|
-
import { join, posix } from "node:path";
|
|
27
|
-
import { kindsExportTarget, pinnedPackageDir } from "./kinds.js";
|
|
24
|
+
import { checkClassData, diskFiles, mergePinClasses, readClassFiles } from "./class-data.js";
|
|
25
|
+
import { pinnedPackageDir } from "./kinds.js";
|
|
28
26
|
import schema from "./workspace-principals.schema.json" with { type: "json" };
|
|
29
27
|
import { joinPath } from "./tree.js";
|
|
30
|
-
import { CORE_CLASSES,
|
|
28
|
+
import { CORE_CLASSES, grantedClasses } from "./identity-gate-rule.js";
|
|
29
|
+
import { loadAjv2020 } from "./ajv2020.js";
|
|
31
30
|
export const PRINCIPALS_SCHEMA_ID = schema.$id;
|
|
32
|
-
|
|
33
|
-
export const PRINCIPALS_SUBPATH = "./workspace-principals";
|
|
31
|
+
export { PRINCIPALS_SUBPATH } from "./class-data.js";
|
|
34
32
|
export { CORE_CLASSES, CORE_PRINCIPAL_CLASSES } from "./identity-gate-rule.js";
|
|
35
33
|
/** The grammar of a class name, as `workspace-principals.schema.json` and the declaration's writeScope keys say it. */
|
|
36
34
|
export const CLASS_NAME = /^(?!x-)[a-z][a-z0-9-]{0,39}$/;
|
|
37
|
-
const CORE_ROLES = new Set(CORE_CLASSES.map((c) => c.role).filter((r) => r !== null));
|
|
38
35
|
export function createClassRegistry(extra = []) {
|
|
39
36
|
const all = [...CORE_CLASSES, ...extra];
|
|
40
37
|
const byName = new Map(all.map((c) => [c.name, c]));
|
|
@@ -72,13 +69,11 @@ let compiled;
|
|
|
72
69
|
function validator() {
|
|
73
70
|
if (compiled)
|
|
74
71
|
return compiled;
|
|
75
|
-
const
|
|
76
|
-
// ajv is CommonJS; its class is the default export, or that export's own default.
|
|
77
|
-
const mod = require("ajv/dist/2020");
|
|
78
|
-
const Ajv = (mod.default ?? mod);
|
|
72
|
+
const Ajv = loadAjv2020();
|
|
79
73
|
compiled = new Ajv({ allErrors: true, strict: true }).compile(schema);
|
|
80
74
|
return compiled;
|
|
81
75
|
}
|
|
76
|
+
export { diskFiles } from "./class-data.js";
|
|
82
77
|
/**
|
|
83
78
|
* Check the text of a principals file against
|
|
84
79
|
* `workspace-principals.schema.json` and the rules the schema can't say: no
|
|
@@ -98,43 +93,7 @@ export function parseClassData(text, source) {
|
|
|
98
93
|
const problems = (validate.errors ?? []).map((e) => `${source}: ${e.instancePath || "the principals file"} ${e.message ?? "is invalid"}`);
|
|
99
94
|
return { classes: [], problems: [...new Set(problems)] };
|
|
100
95
|
}
|
|
101
|
-
|
|
102
|
-
const classes = [];
|
|
103
|
-
const names = new Set();
|
|
104
|
-
const roles = new Set();
|
|
105
|
-
for (const c of raw.classes) {
|
|
106
|
-
if (CORE_PRINCIPAL_CLASSES.includes(c.name)) {
|
|
107
|
-
problems.push(`${source}: class ${c.name} is a core class and can't be supplied by a package`);
|
|
108
|
-
continue;
|
|
109
|
-
}
|
|
110
|
-
if (CORE_ROLES.has(c.role)) {
|
|
111
|
-
problems.push(`${source}: class ${c.name} names the role ${c.role}, which puts a principal in the core ${c.role} class`);
|
|
112
|
-
continue;
|
|
113
|
-
}
|
|
114
|
-
if (names.has(c.name)) {
|
|
115
|
-
problems.push(`${source}: class ${c.name} is listed twice`);
|
|
116
|
-
continue;
|
|
117
|
-
}
|
|
118
|
-
if (roles.has(c.role)) {
|
|
119
|
-
problems.push(`${source}: class ${c.name} names the role ${c.role}, which another class in the file names; a role puts a principal in one class`);
|
|
120
|
-
continue;
|
|
121
|
-
}
|
|
122
|
-
names.add(c.name);
|
|
123
|
-
roles.add(c.role);
|
|
124
|
-
classes.push({ name: c.name, description: c.description, role: c.role, source });
|
|
125
|
-
}
|
|
126
|
-
return { classes, problems };
|
|
127
|
-
}
|
|
128
|
-
/** A package directory on disk. */
|
|
129
|
-
export function diskFiles(dir) {
|
|
130
|
-
return (path) => {
|
|
131
|
-
try {
|
|
132
|
-
return readFileSync(join(dir, ...path.split("/")), "utf-8");
|
|
133
|
-
}
|
|
134
|
-
catch {
|
|
135
|
-
return undefined;
|
|
136
|
-
}
|
|
137
|
-
};
|
|
96
|
+
return checkClassData(raw, source);
|
|
138
97
|
}
|
|
139
98
|
/** A package directory at `dir` in `tree`, such as the workspace at the base revision. */
|
|
140
99
|
export function treeFiles(tree, dir) {
|
|
@@ -152,28 +111,7 @@ export function treeFiles(tree, dir) {
|
|
|
152
111
|
}
|
|
153
112
|
/** Read the classes a package publishes at `./workspace-principals`. Reads files only; imports nothing. A package that publishes none supplies none. */
|
|
154
113
|
export function readPackageClasses(files, source) {
|
|
155
|
-
|
|
156
|
-
if (manifest === undefined)
|
|
157
|
-
return { classes: [], problems: [`${source}: no readable package.json`] };
|
|
158
|
-
let pkg;
|
|
159
|
-
try {
|
|
160
|
-
pkg = JSON.parse(manifest);
|
|
161
|
-
}
|
|
162
|
-
catch {
|
|
163
|
-
return { classes: [], problems: [`${source}: package.json is not JSON`] };
|
|
164
|
-
}
|
|
165
|
-
const target = kindsExportTarget(pkg, PRINCIPALS_SUBPATH);
|
|
166
|
-
if (target === undefined)
|
|
167
|
-
return { classes: [], problems: [] };
|
|
168
|
-
if (typeof target !== "string")
|
|
169
|
-
return { classes: [], problems: [`${source}: ${target.problem}`] };
|
|
170
|
-
const inside = posix.normalize(target.slice(2));
|
|
171
|
-
if (inside.startsWith("../") || inside === "..")
|
|
172
|
-
return { classes: [], problems: [`${source}: exports["${PRINCIPALS_SUBPATH}"] points outside the package`] };
|
|
173
|
-
const text = files(inside);
|
|
174
|
-
if (text === undefined)
|
|
175
|
-
return { classes: [], problems: [`${source}: exports["${PRINCIPALS_SUBPATH}"] names ${target}, which does not exist`] };
|
|
176
|
-
return parseClassData(text, source);
|
|
114
|
+
return readClassFiles(files, source, parseClassData);
|
|
177
115
|
}
|
|
178
116
|
/**
|
|
179
117
|
* The classes a workspace knows: the core four plus every class its pins
|
|
@@ -187,10 +125,7 @@ export function readPackageClasses(files, source) {
|
|
|
187
125
|
*/
|
|
188
126
|
export function loadClassRegistry(pins, workspaceRoot, opts = {}) {
|
|
189
127
|
const problems = [];
|
|
190
|
-
const
|
|
191
|
-
const byName = new Map();
|
|
192
|
-
const byRole = new Map();
|
|
193
|
-
const clashing = new Set();
|
|
128
|
+
const reads = [];
|
|
194
129
|
pins.forEach((pin, i) => {
|
|
195
130
|
let files;
|
|
196
131
|
let source;
|
|
@@ -209,31 +144,10 @@ export function loadClassRegistry(pins, workspaceRoot, opts = {}) {
|
|
|
209
144
|
files = diskFiles(found.dir);
|
|
210
145
|
source = found.source;
|
|
211
146
|
}
|
|
212
|
-
|
|
213
|
-
for (const p of read.problems)
|
|
214
|
-
problems.push({ pin: i, message: p });
|
|
215
|
-
for (const c of read.classes) {
|
|
216
|
-
const named = byName.get(c.name);
|
|
217
|
-
const roled = byRole.get(c.role);
|
|
218
|
-
if (named !== undefined || roled !== undefined) {
|
|
219
|
-
clashing.add(c.name);
|
|
220
|
-
if (named !== undefined) {
|
|
221
|
-
problems.push({ pin: i, message: `class ${c.name} is supplied by both ${named} and ${source}; a class name has one source` });
|
|
222
|
-
}
|
|
223
|
-
else {
|
|
224
|
-
const other = extra.find((e) => e.role === c.role);
|
|
225
|
-
clashing.add(other.name);
|
|
226
|
-
problems.push({ pin: i, message: `class ${c.name} (${source}) names the role ${c.role}, which class ${other.name} (${roled}) names; a role puts a principal in one class` });
|
|
227
|
-
}
|
|
228
|
-
continue;
|
|
229
|
-
}
|
|
230
|
-
byName.set(c.name, source);
|
|
231
|
-
byRole.set(c.role, source);
|
|
232
|
-
extra.push(c);
|
|
233
|
-
}
|
|
147
|
+
reads.push({ pin: i, source, read: readPackageClasses(files, source) });
|
|
234
148
|
});
|
|
235
|
-
|
|
236
|
-
return { registry: createClassRegistry(
|
|
149
|
+
const merged = mergePinClasses(reads);
|
|
150
|
+
return { registry: createClassRegistry(merged.classes), problems: [...problems, ...merged.problems].sort((a, b) => a.pin - b.pin) };
|
|
237
151
|
}
|
|
238
152
|
/**
|
|
239
153
|
* The writeScope keys no class in `classes` has, in file order. A writer
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intentius/chant",
|
|
3
|
-
"version": "0.124.
|
|
3
|
+
"version": "0.124.16",
|
|
4
4
|
"description": "Declarative infrastructure-as-code toolkit — TypeScript on Node.js",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://intentius.io/chant",
|
|
@@ -31,7 +31,8 @@
|
|
|
31
31
|
"access": "public"
|
|
32
32
|
},
|
|
33
33
|
"bin": {
|
|
34
|
-
"chant": "./bin/chant"
|
|
34
|
+
"chant": "./bin/chant",
|
|
35
|
+
"chant-wave": "./dist/wave-runtime.mjs"
|
|
35
36
|
},
|
|
36
37
|
"exports": {
|
|
37
38
|
".": {
|
|
@@ -108,6 +109,7 @@
|
|
|
108
109
|
"import": "./dist/notify.js",
|
|
109
110
|
"default": "./src/notify.ts"
|
|
110
111
|
},
|
|
112
|
+
"./wave-runtime.mjs": "./dist/wave-runtime.mjs",
|
|
111
113
|
"./*": {
|
|
112
114
|
"development": "./src/*.ts",
|
|
113
115
|
"types": "./dist/*.d.ts",
|
|
@@ -115,7 +117,7 @@
|
|
|
115
117
|
}
|
|
116
118
|
},
|
|
117
119
|
"scripts": {
|
|
118
|
-
"build": "../../scripts/tsc7.sh -p tsconfig.build.json --sourceMap false && tsc-alias -p tsconfig.build.json && node scripts/copy-assets.mjs",
|
|
120
|
+
"build": "../../scripts/tsc7.sh -p tsconfig.build.json --sourceMap false && tsc-alias -p tsconfig.build.json && node scripts/copy-assets.mjs && node scripts/build-wave-runtime.mjs",
|
|
119
121
|
"prepack": "npm run build"
|
|
120
122
|
},
|
|
121
123
|
"dependencies": {
|
package/src/build.ts
CHANGED
|
@@ -232,6 +232,13 @@ export interface BuildOptions {
|
|
|
232
232
|
*/
|
|
233
233
|
lexicons?: readonly string[];
|
|
234
234
|
|
|
235
|
+
/**
|
|
236
|
+
* chant#3612 — host package specifiers to follow a bare import into. Passed
|
|
237
|
+
* straight through to {@link DiscoveryOptions.lexiconPackages}; ignored
|
|
238
|
+
* unless {@link fold} is set. Never needed for a chant project.
|
|
239
|
+
*/
|
|
240
|
+
lexiconPackages?: readonly string[];
|
|
241
|
+
|
|
235
242
|
/**
|
|
236
243
|
* chant #1442 — lexicon name → the version of the plugin that served it.
|
|
237
244
|
* Recorded on {@link BuildResult.lexiconVersions} so a build digest can say
|
|
@@ -723,6 +730,7 @@ export async function build(
|
|
|
723
730
|
fold: options?.fold,
|
|
724
731
|
intrinsics: options?.intrinsics,
|
|
725
732
|
lexicons: options?.lexicons,
|
|
733
|
+
lexiconPackages: options?.lexiconPackages,
|
|
726
734
|
sandbox: options?.sandbox,
|
|
727
735
|
executing: options?.executing,
|
|
728
736
|
buildParams: options?.buildParams,
|
package/src/change-set.test.ts
CHANGED
|
@@ -23,11 +23,13 @@ import { readdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
|
23
23
|
import { join } from "node:path";
|
|
24
24
|
import { describe, expect, test } from "vitest";
|
|
25
25
|
import {
|
|
26
|
+
CHANGE_SET_PLANNERS,
|
|
26
27
|
CHANGE_SET_SCHEMA_ID,
|
|
27
28
|
changeSetDigest,
|
|
28
29
|
changeSetDocumentDigest,
|
|
29
30
|
composeChangeSet,
|
|
30
31
|
lifecyclePlanPart,
|
|
32
|
+
readChangeSetPartFile,
|
|
31
33
|
reconcilePlanPart,
|
|
32
34
|
verifyChangeSetDigest,
|
|
33
35
|
type ChangeSetPart,
|
|
@@ -243,3 +245,49 @@ describe("the digest", () => {
|
|
|
243
245
|
expect(doc.summary.replacements.map((d) => `${d.member}:${d.address}`)).toEqual(["estate:terraform_data.worker"]);
|
|
244
246
|
});
|
|
245
247
|
});
|
|
248
|
+
|
|
249
|
+
describe("readChangeSetPartFile (#3767)", () => {
|
|
250
|
+
/** A part as the sql lexicon's adapter writes it; `lexicons/sql/src/change-set.test.ts` pins the adapter itself. */
|
|
251
|
+
const sqlPart = (): ChangeSetPart => ({
|
|
252
|
+
member: { member: "written-as", lexicon: "sql", planner: "sql", scope: "prod", status: "planned", planDigest: computePlanDigest("sql-versioned-plan", { id: "0002" }), holes: [] },
|
|
253
|
+
entries: [
|
|
254
|
+
{ member: "written-as", lexicon: "sql", planner: "sql", address: "analytics.events", type: "ClickHouse::Table", action: "update", disruption: "rolling", scope: "prod", attributes: [{ path: "sql", after: ["ALTER TABLE analytics.events ADD COLUMN region String"] }] },
|
|
255
|
+
],
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
test("the schema lists every planner, sql included", () => {
|
|
259
|
+
const planners = (schema as { $defs: { member: { properties: { planner: { enum: string[] } } }; entry: { properties: { planner: { enum: string[] } } } } }).$defs;
|
|
260
|
+
expect(planners.member.properties.planner.enum).toEqual([...CHANGE_SET_PLANNERS]);
|
|
261
|
+
expect(planners.entry.properties.planner.enum).toEqual([...CHANGE_SET_PLANNERS]);
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
test("reads a written part back as the run's member, through JSON, and composes it", () => {
|
|
265
|
+
const part = readChangeSetPartFile(JSON.parse(JSON.stringify(sqlPart())), "sql", "warehouse");
|
|
266
|
+
expect(part.member.member).toBe("warehouse");
|
|
267
|
+
expect(part.entries.map((e) => e.member)).toEqual(["warehouse"]);
|
|
268
|
+
expect(part.member.planDigest).toBe(sqlPart().member.planDigest);
|
|
269
|
+
expect(readChangeSetPartFile(sqlPart(), "sql", "warehouse", "clickhouse").entries[0].lexicon).toBe("clickhouse");
|
|
270
|
+
const doc = composeChangeSet([part, reconcilePlanPart({ member: "warden", plan: wardenPlan() })]);
|
|
271
|
+
expectValid(doc);
|
|
272
|
+
expect(doc.summary.byMember.warehouse).toEqual({ update: 1 });
|
|
273
|
+
// The name the run gives it is what the set digest pairs with the writer's plan digest.
|
|
274
|
+
expect(composeChangeSet([readChangeSetPartFile(sqlPart(), "sql", "other")]).digest).not.toBe(composeChangeSet([part]).digest);
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
test("refuses what is not a part of that planner", () => {
|
|
278
|
+
const p = sqlPart();
|
|
279
|
+
expect(() => readChangeSetPartFile([], "sql", "w")).toThrow(/not a change-set part/);
|
|
280
|
+
expect(() => readChangeSetPartFile({ ...p, member: { ...p.member, planner: "chant" } }, "sql", "w")).toThrow(/names planner chant, not sql/);
|
|
281
|
+
expect(() => readChangeSetPartFile({ ...p, member: { ...p.member, planDigest: null } }, "sql", "w")).toThrow(/planned but has no planDigest/);
|
|
282
|
+
expect(() => readChangeSetPartFile({ ...p, member: { ...p.member, holes: undefined } }, "sql", "w")).toThrow(/no holes array/);
|
|
283
|
+
expect(() => readChangeSetPartFile({ ...p, entries: [{ ...p.entries[0], planner: "terraform" }] }, "sql", "w")).toThrow(/entries\[0\] names planner terraform/);
|
|
284
|
+
expect(() => readChangeSetPartFile({ ...p, entries: [{ ...p.entries[0], action: "upsert" }] }, "sql", "w")).toThrow(/entries\[0\] has action upsert/);
|
|
285
|
+
expect(() => readChangeSetPartFile({ ...p, entries: [{ address: "x" }] }, "sql", "w")).toThrow(/entries\[0\] needs address/);
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
test("a failed member keeps a null digest", () => {
|
|
289
|
+
const p = sqlPart();
|
|
290
|
+
const failed = readChangeSetPartFile({ ...p, member: { ...p.member, status: "failed", error: "out of order", planDigest: null } }, "sql", "w");
|
|
291
|
+
expect(failed.member).toMatchObject({ status: "failed", error: "out of order", planDigest: null });
|
|
292
|
+
});
|
|
293
|
+
});
|
package/src/change-set.ts
CHANGED
|
@@ -11,7 +11,9 @@
|
|
|
11
11
|
* Each planner reaches it through an adapter that returns a
|
|
12
12
|
* {@link ChangeSetPart}: one member and its entries. The lifecycle and
|
|
13
13
|
* reconcile adapters are here; the terraform-family ones live in the
|
|
14
|
-
* terraform lexicon's `change-set` subpath
|
|
14
|
+
* terraform lexicon's `change-set` subpath and the SQL ones in the sql
|
|
15
|
+
* lexicon's. A part another process wrote to a file reads back through
|
|
16
|
+
* {@link readChangeSetPartFile}. {@link composeChangeSet} joins
|
|
15
17
|
* the parts.
|
|
16
18
|
*
|
|
17
19
|
* ## The digest
|
|
@@ -60,7 +62,15 @@ export const CHANGE_SET_ACTIONS: readonly ChangeSetAction[] = ["create", "update
|
|
|
60
62
|
export type ChangeSetDisruption = "in-place" | "rolling" | "replace" | "destroy" | "unknown";
|
|
61
63
|
|
|
62
64
|
/** Which tool produced a member's plan. */
|
|
63
|
-
|
|
65
|
+
/**
|
|
66
|
+
* Which tool produced a member's plan. `sql` is a SQL schema change: a
|
|
67
|
+
* versioned plan (a product's migrations) or one of the sql lexicon's
|
|
68
|
+
* migration Ops' plans, through `@intentius/chant-lexicon-sql/change-set`.
|
|
69
|
+
*/
|
|
70
|
+
export type ChangeSetPlanner = "terraform" | "tofu" | "choudoufu" | "chant" | "warden" | "sql";
|
|
71
|
+
|
|
72
|
+
/** Every planner, in the order the schema lists them. */
|
|
73
|
+
export const CHANGE_SET_PLANNERS: readonly ChangeSetPlanner[] = ["terraform", "tofu", "choudoufu", "chant", "warden", "sql"];
|
|
64
74
|
|
|
65
75
|
/** One attribute a change writes, at top-level granularity. */
|
|
66
76
|
export interface ChangeSetAttribute {
|
|
@@ -482,3 +492,43 @@ export function reconcilePlanPart(input: ReconcilePlanPartInput): ChangeSetPart
|
|
|
482
492
|
entries,
|
|
483
493
|
};
|
|
484
494
|
}
|
|
495
|
+
|
|
496
|
+
// ── a part written to a file ───────────────────────────────────────────────────
|
|
497
|
+
|
|
498
|
+
const isRecord = (v: unknown): v is Record<string, unknown> => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
499
|
+
|
|
500
|
+
/**
|
|
501
|
+
* A part an adapter in another process wrote as JSON, read back as `member`'s
|
|
502
|
+
* part. The `sql` planner's plans arrive this way: the sql lexicon's
|
|
503
|
+
* `change-set` adapters, or a product that fills them, write the part, and
|
|
504
|
+
* `readChangeSetPart` with `planner: "sql"` reads it.
|
|
505
|
+
*
|
|
506
|
+
* The part must name `planner` on its member and on every entry, and say
|
|
507
|
+
* `status`, `planDigest` and `holes`. Its member and entries are renamed to
|
|
508
|
+
* `member`, so the file need not know the name the run gives it; a `lexicon`
|
|
509
|
+
* given here replaces the part's. Nothing is recomputed: the plan digest is
|
|
510
|
+
* the one the writer took, over a plan this process never sees.
|
|
511
|
+
*/
|
|
512
|
+
export function readChangeSetPartFile(part: unknown, planner: ChangeSetPlanner, member: string, lexicon?: string): ChangeSetPart {
|
|
513
|
+
const where = `the ${planner} part for ${member}`;
|
|
514
|
+
if (!isRecord(part) || !isRecord(part.member) || !Array.isArray(part.entries)) throw new Error(`${where} is not a change-set part: it needs member and entries`);
|
|
515
|
+
const m = part.member;
|
|
516
|
+
if (m.planner !== planner) throw new Error(`${where} names planner ${String(m.planner)}, not ${planner}`);
|
|
517
|
+
if (m.status !== "planned" && m.status !== "failed") throw new Error(`${where} has no status`);
|
|
518
|
+
if (m.planDigest !== null && typeof m.planDigest !== "string") throw new Error(`${where} has no planDigest`);
|
|
519
|
+
if (m.status === "planned" && m.planDigest === null) throw new Error(`${where} planned but has no planDigest`);
|
|
520
|
+
if (!Array.isArray(m.holes)) throw new Error(`${where} has no holes array`);
|
|
521
|
+
const entries = part.entries.map((e, i) => {
|
|
522
|
+
if (!isRecord(e) || typeof e.address !== "string" || typeof e.type !== "string" || typeof e.action !== "string" || !Array.isArray(e.attributes)) {
|
|
523
|
+
throw new Error(`${where}: entries[${i}] needs address, type, action and attributes`);
|
|
524
|
+
}
|
|
525
|
+
if (!(CHANGE_SET_ACTIONS as readonly string[]).includes(e.action)) throw new Error(`${where}: entries[${i}] has action ${e.action}`);
|
|
526
|
+
if (e.planner !== planner) throw new Error(`${where}: entries[${i}] names planner ${String(e.planner)}, not ${planner}`);
|
|
527
|
+
return { ...(e as unknown as ChangeSetEntry), member, ...(lexicon !== undefined ? { lexicon } : {}) };
|
|
528
|
+
});
|
|
529
|
+
return {
|
|
530
|
+
member: { ...(m as unknown as ChangeSetMember), member, ...(lexicon !== undefined ? { lexicon } : {}) },
|
|
531
|
+
entries,
|
|
532
|
+
...(Array.isArray(part.sideEffects) ? { sideEffects: part.sideEffects as ChangeSetPart["sideEffects"] } : {}),
|
|
533
|
+
};
|
|
534
|
+
}
|