@telorun/analyzer 0.72.0 → 0.74.0
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/analyzer.d.ts.map +1 -1
- package/dist/analyzer.js +76 -20
- package/dist/artifact-axes.d.ts +14 -0
- package/dist/artifact-axes.d.ts.map +1 -0
- package/dist/artifact-axes.js +12 -0
- package/dist/artifact-layer-index.d.ts +2 -2
- package/dist/artifact-layer-index.d.ts.map +1 -1
- package/dist/artifact-layer-index.js +9 -4
- package/dist/artifact-selector.d.ts +47 -21
- package/dist/artifact-selector.d.ts.map +1 -1
- package/dist/artifact-selector.js +85 -16
- package/dist/builtins.d.ts.map +1 -1
- package/dist/builtins.js +144 -113
- package/dist/call-graph.d.ts +12 -1
- package/dist/call-graph.d.ts.map +1 -1
- package/dist/call-graph.js +22 -0
- package/dist/catch-scope.js +1 -1
- package/dist/cel-scope-query.d.ts.map +1 -1
- package/dist/cel-scope-query.js +32 -11
- package/dist/cel-scope.d.ts.map +1 -1
- package/dist/cel-scope.js +1 -0
- package/dist/eval-paths.d.ts +36 -5
- package/dist/eval-paths.d.ts.map +1 -1
- package/dist/eval-paths.js +47 -6
- package/dist/extends-resolution.d.ts +12 -0
- package/dist/extends-resolution.d.ts.map +1 -1
- package/dist/extends-resolution.js +23 -0
- package/dist/forwarded-declaration.d.ts +26 -0
- package/dist/forwarded-declaration.d.ts.map +1 -0
- package/dist/forwarded-declaration.js +31 -0
- package/dist/index.d.ts +10 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -2
- package/dist/kernel-globals.d.ts.map +1 -1
- package/dist/kernel-globals.js +21 -5
- package/dist/module-alias-scope.d.ts +11 -0
- package/dist/module-alias-scope.d.ts.map +1 -1
- package/dist/module-alias-scope.js +10 -0
- package/dist/module-file-claims.d.ts +17 -1
- package/dist/module-file-claims.d.ts.map +1 -1
- package/dist/module-file-claims.js +38 -3
- package/dist/module-named-files.d.ts +72 -0
- package/dist/module-named-files.d.ts.map +1 -0
- package/dist/module-named-files.js +115 -0
- package/dist/native-entries.d.ts +83 -0
- package/dist/native-entries.d.ts.map +1 -0
- package/dist/native-entries.js +169 -0
- package/dist/nearest-name.d.ts +22 -0
- package/dist/nearest-name.d.ts.map +1 -0
- package/dist/nearest-name.js +43 -0
- package/dist/normalize-inline-resources.d.ts +41 -13
- package/dist/normalize-inline-resources.d.ts.map +1 -1
- package/dist/normalize-inline-resources.js +236 -54
- package/dist/reference-field-map.d.ts +59 -1
- package/dist/reference-field-map.d.ts.map +1 -1
- package/dist/reference-field-map.js +200 -34
- package/dist/release/destinations.d.ts +59 -0
- package/dist/release/destinations.d.ts.map +1 -0
- package/dist/release/destinations.js +75 -0
- package/dist/release/index.d.ts +6 -2
- package/dist/release/index.d.ts.map +1 -1
- package/dist/release/index.js +3 -1
- package/dist/release/ledger.d.ts +20 -11
- package/dist/release/ledger.d.ts.map +1 -1
- package/dist/release/ledger.js +43 -14
- package/dist/release/payload-digest.d.ts +2 -1
- package/dist/release/payload-digest.d.ts.map +1 -1
- package/dist/release/payload-digest.js +2 -1
- package/dist/release/release-plan.d.ts +3 -2
- package/dist/release/release-plan.d.ts.map +1 -1
- package/dist/release/release-plan.js +12 -19
- package/dist/release/workspace-config.d.ts +114 -34
- package/dist/release/workspace-config.d.ts.map +1 -1
- package/dist/release/workspace-config.js +322 -38
- package/dist/release/workspace-schema.d.ts +41 -0
- package/dist/release/workspace-schema.d.ts.map +1 -0
- package/dist/release/workspace-schema.js +77 -0
- package/dist/resolve-ref-sentinels.d.ts.map +1 -1
- package/dist/resolve-ref-sentinels.js +8 -5
- package/dist/resolve-throws-union.d.ts +25 -4
- package/dist/resolve-throws-union.d.ts.map +1 -1
- package/dist/resolve-throws-union.js +62 -32
- package/dist/resolve-zone-requirements.d.ts.map +1 -1
- package/dist/resolve-zone-requirements.js +2 -1
- package/dist/rewrite-synthetic-origins.d.ts +6 -1
- package/dist/rewrite-synthetic-origins.d.ts.map +1 -1
- package/dist/rewrite-synthetic-origins.js +107 -13
- package/dist/schema-compat.d.ts.map +1 -1
- package/dist/schema-compat.js +18 -5
- package/dist/schema-error-report.d.ts +7 -0
- package/dist/schema-error-report.d.ts.map +1 -1
- package/dist/schema-error-report.js +9 -4
- package/dist/schema-walk.d.ts +47 -13
- package/dist/schema-walk.d.ts.map +1 -1
- package/dist/schema-walk.js +150 -30
- package/dist/scope-declarations.d.ts +59 -0
- package/dist/scope-declarations.d.ts.map +1 -0
- package/dist/scope-declarations.js +45 -0
- package/dist/source-entries.d.ts +119 -0
- package/dist/source-entries.d.ts.map +1 -0
- package/dist/source-entries.js +349 -0
- package/dist/step-bodies.d.ts +24 -0
- package/dist/step-bodies.d.ts.map +1 -0
- package/dist/step-bodies.js +28 -0
- package/dist/telo-version.d.ts +1 -1
- package/dist/telo-version.js +1 -1
- package/dist/template-body.d.ts +10 -0
- package/dist/template-body.d.ts.map +1 -1
- package/dist/template-body.js +25 -0
- package/dist/validate-cel-context.d.ts +23 -8
- package/dist/validate-cel-context.d.ts.map +1 -1
- package/dist/validate-cel-context.js +51 -18
- package/dist/validate-exports.d.ts +28 -0
- package/dist/validate-exports.d.ts.map +1 -0
- package/dist/validate-exports.js +146 -0
- package/dist/validate-extends.d.ts.map +1 -1
- package/dist/validate-extends.js +37 -1
- package/dist/validate-module-artifact.d.ts +4 -2
- package/dist/validate-module-artifact.d.ts.map +1 -1
- package/dist/validate-module-artifact.js +43 -4
- package/dist/validate-native-entries.d.ts +15 -0
- package/dist/validate-native-entries.d.ts.map +1 -0
- package/dist/validate-native-entries.js +103 -0
- package/dist/validate-observed-state.d.ts +7 -1
- package/dist/validate-observed-state.d.ts.map +1 -1
- package/dist/validate-observed-state.js +24 -6
- package/dist/validate-provider-coherence.d.ts +4 -8
- package/dist/validate-provider-coherence.d.ts.map +1 -1
- package/dist/validate-provider-coherence.js +12 -123
- package/dist/validate-reference-forms.d.ts.map +1 -1
- package/dist/validate-reference-forms.js +2 -2
- package/dist/validate-references.d.ts.map +1 -1
- package/dist/validate-references.js +152 -65
- package/dist/validate-scope-reach.d.ts +31 -0
- package/dist/validate-scope-reach.d.ts.map +1 -0
- package/dist/validate-scope-reach.js +180 -0
- package/dist/validate-source-entries.d.ts +16 -0
- package/dist/validate-source-entries.d.ts.map +1 -0
- package/dist/validate-source-entries.js +90 -0
- package/dist/validate-template-body.d.ts +36 -0
- package/dist/validate-template-body.d.ts.map +1 -0
- package/dist/validate-template-body.js +246 -0
- package/dist/validate-throws-coverage.d.ts.map +1 -1
- package/dist/validate-throws-coverage.js +21 -39
- package/dist/value-type-keyword.d.ts +22 -5
- package/dist/value-type-keyword.d.ts.map +1 -1
- package/dist/value-type-keyword.js +16 -7
- package/package.json +4 -3
- package/src/analyzer.ts +97 -20
- package/src/artifact-axes.ts +24 -0
- package/src/artifact-layer-index.ts +9 -6
- package/src/artifact-selector.ts +110 -35
- package/src/builtins.ts +160 -113
- package/src/call-graph.ts +30 -0
- package/src/catch-scope.ts +1 -1
- package/src/cel-scope-query.ts +28 -9
- package/src/cel-scope.ts +1 -0
- package/src/eval-paths.ts +53 -6
- package/src/extends-resolution.ts +24 -0
- package/src/forwarded-declaration.ts +32 -0
- package/src/index.ts +37 -1
- package/src/kernel-globals.ts +28 -5
- package/src/migrations/CLAUDE.md +35 -0
- package/src/module-alias-scope.ts +17 -0
- package/src/module-file-claims.ts +63 -4
- package/src/module-named-files.ts +162 -0
- package/src/native-entries.ts +227 -0
- package/src/nearest-name.ts +47 -0
- package/src/normalize-inline-resources.ts +326 -70
- package/src/reference-field-map.ts +257 -52
- package/src/release/CLAUDE.md +32 -0
- package/src/release/destinations.ts +105 -0
- package/src/release/index.ts +33 -2
- package/src/release/ledger.ts +51 -21
- package/src/release/payload-digest.ts +2 -1
- package/src/release/release-plan.ts +16 -26
- package/src/release/workspace-config.ts +483 -47
- package/src/release/workspace-schema.ts +99 -0
- package/src/resolve-ref-sentinels.ts +7 -6
- package/src/resolve-throws-union.ts +87 -32
- package/src/resolve-zone-requirements.ts +2 -1
- package/src/rewrite-synthetic-origins.ts +107 -16
- package/src/schema-compat.ts +18 -4
- package/src/schema-error-report.ts +16 -4
- package/src/schema-walk.ts +162 -34
- package/src/scope-declarations.ts +98 -0
- package/src/source-entries.ts +502 -0
- package/src/step-bodies.ts +55 -0
- package/src/telo-version.ts +1 -1
- package/src/template-body.ts +25 -0
- package/src/validate-cel-context.ts +60 -18
- package/src/validate-exports.ts +185 -0
- package/src/validate-extends.ts +43 -0
- package/src/validate-module-artifact.ts +46 -3
- package/src/validate-native-entries.ts +147 -0
- package/src/validate-observed-state.ts +36 -7
- package/src/validate-provider-coherence.ts +17 -127
- package/src/validate-reference-forms.ts +2 -3
- package/src/validate-references.ts +151 -66
- package/src/validate-scope-reach.ts +213 -0
- package/src/validate-source-entries.ts +120 -0
- package/src/validate-template-body.ts +274 -0
- package/src/validate-throws-coverage.ts +24 -31
- package/src/value-type-keyword.ts +35 -9
- package/dist/validate-template-dispatch.d.ts +0 -27
- package/dist/validate-template-dispatch.d.ts.map +0 -1
- package/dist/validate-template-dispatch.js +0 -95
- package/src/validate-template-dispatch.ts +0 -99
package/src/release/ledger.ts
CHANGED
|
@@ -14,10 +14,22 @@
|
|
|
14
14
|
* drift: it means nothing is published, which is the correct reading for a
|
|
15
15
|
* module that has never shipped.
|
|
16
16
|
*
|
|
17
|
-
* **
|
|
18
|
-
* source writes the destination into the manifest layer — so
|
|
19
|
-
*
|
|
20
|
-
* another
|
|
17
|
+
* **Every entry records its own registry base**, because canonicalizing a
|
|
18
|
+
* relative `imports:` source writes the destination into the manifest layer — so
|
|
19
|
+
* each digest is a digest *against that base*, and comparing it to one taken
|
|
20
|
+
* against another would be comparing two different artifacts.
|
|
21
|
+
*
|
|
22
|
+
* Per entry rather than one top-level base with per-entry deltas: a workspace
|
|
23
|
+
* whose `release.modules` entries each author a destination has no meaningful
|
|
24
|
+
* top-level base, an absent one already means *nothing has been published yet*,
|
|
25
|
+
* and the agreement check returns early on that — so the multi-destination
|
|
26
|
+
* workspace would be the one whose bases are never compared. The file is
|
|
27
|
+
* generated and never hand-maintained, so the redundancy costs nothing and it
|
|
28
|
+
* removes the "differs from what?" question and the absent-versus-unknown
|
|
29
|
+
* conflation together. A **top-level `registry:` is a legacy form the reader
|
|
30
|
+
* accepts and never writes**, applied to every entry: the credential-free PR
|
|
31
|
+
* gate reads whatever ledger is committed on the branch, and that stays in the
|
|
32
|
+
* old shape until a release regenerates it.
|
|
21
33
|
*/
|
|
22
34
|
|
|
23
35
|
import { Document, parseDocument } from "yaml";
|
|
@@ -31,17 +43,14 @@ export interface LedgerEntry {
|
|
|
31
43
|
/** The version these digests were taken at — the tag the artifact published
|
|
32
44
|
* under. */
|
|
33
45
|
readonly version: string;
|
|
46
|
+
/** The publish destination base these digests were taken against
|
|
47
|
+
* (`oci://ghcr.io/telorun`). Absent only in a ledger written before the base
|
|
48
|
+
* was recorded at all. */
|
|
49
|
+
readonly registry?: string;
|
|
34
50
|
readonly layers: LayerDigests;
|
|
35
51
|
}
|
|
36
52
|
|
|
37
53
|
export interface Ledger {
|
|
38
|
-
/**
|
|
39
|
-
* The publish destination base the digests were taken against
|
|
40
|
-
* (`oci://ghcr.io/telorun`). Absent in a workspace that has published nothing
|
|
41
|
-
* yet, which is why it is optional rather than required — but a `check` that
|
|
42
|
-
* has entries and no base cannot reproduce them, and says so.
|
|
43
|
-
*/
|
|
44
|
-
readonly registry?: string;
|
|
45
54
|
readonly modules: ReadonlyMap<ModuleKey, LedgerEntry>;
|
|
46
55
|
}
|
|
47
56
|
|
|
@@ -72,13 +81,14 @@ export function parseLedger(text: string, where: string): Ledger {
|
|
|
72
81
|
}
|
|
73
82
|
}
|
|
74
83
|
|
|
75
|
-
|
|
76
|
-
|
|
84
|
+
// The legacy top-level base: read and applied to every entry, never written.
|
|
85
|
+
const inherited = record.registry;
|
|
86
|
+
if (inherited !== undefined && typeof inherited !== "string") {
|
|
77
87
|
throw new LedgerError(`${where}: 'registry' must be the publish destination base, as a string.`);
|
|
78
88
|
}
|
|
79
89
|
|
|
80
90
|
const rawModules = record.modules;
|
|
81
|
-
if (rawModules === undefined || rawModules === null) return {
|
|
91
|
+
if (rawModules === undefined || rawModules === null) return { modules: new Map() };
|
|
82
92
|
if (typeof rawModules !== "object" || Array.isArray(rawModules)) {
|
|
83
93
|
throw new LedgerError(`${where}: 'modules' must be a mapping of module path to entry.`);
|
|
84
94
|
}
|
|
@@ -89,6 +99,20 @@ export function parseLedger(text: string, where: string): Ledger {
|
|
|
89
99
|
throw new LedgerError(`${where}: entry '${key}' must be a mapping.`);
|
|
90
100
|
}
|
|
91
101
|
const entry = raw as Record<string, unknown>;
|
|
102
|
+
for (const field of Object.keys(entry)) {
|
|
103
|
+
if (field !== "version" && field !== "registry" && field !== "layers") {
|
|
104
|
+
throw new LedgerError(
|
|
105
|
+
`${where}: entry '${key}' has unknown field '${field}'. An entry carries 'version:', ` +
|
|
106
|
+
`'registry:' and 'layers:'.`,
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
if (entry.registry !== undefined && typeof entry.registry !== "string") {
|
|
111
|
+
throw new LedgerError(
|
|
112
|
+
`${where}: entry '${key}' has a non-string 'registry'. It is the publish destination base ` +
|
|
113
|
+
`the digests beside it were taken against.`,
|
|
114
|
+
);
|
|
115
|
+
}
|
|
92
116
|
if (!isReleaseVersion(entry.version)) {
|
|
93
117
|
throw new LedgerError(
|
|
94
118
|
`${where}: entry '${key}' has no major.minor.patch 'version'. The ledger records the ` +
|
|
@@ -108,10 +132,15 @@ export function parseLedger(text: string, where: string): Ledger {
|
|
|
108
132
|
layers[layer] = digest;
|
|
109
133
|
}
|
|
110
134
|
}
|
|
111
|
-
|
|
135
|
+
const registry = (entry.registry as string | undefined) ?? inherited;
|
|
136
|
+
modules.set(normalizeModuleKey(key), {
|
|
137
|
+
version: entry.version,
|
|
138
|
+
...(registry ? { registry } : {}),
|
|
139
|
+
layers,
|
|
140
|
+
});
|
|
112
141
|
}
|
|
113
142
|
|
|
114
|
-
return {
|
|
143
|
+
return { modules };
|
|
115
144
|
}
|
|
116
145
|
|
|
117
146
|
/**
|
|
@@ -127,12 +156,13 @@ export function serializeLedger(ledger: Ledger): string {
|
|
|
127
156
|
const entry = ledger.modules.get(key)!;
|
|
128
157
|
const layers: Record<string, string> = {};
|
|
129
158
|
for (const layer of Object.keys(entry.layers).sort()) layers[layer] = entry.layers[layer];
|
|
130
|
-
modules[key] = {
|
|
159
|
+
modules[key] = {
|
|
160
|
+
version: entry.version,
|
|
161
|
+
...(entry.registry ? { registry: entry.registry } : {}),
|
|
162
|
+
layers,
|
|
163
|
+
};
|
|
131
164
|
}
|
|
132
|
-
const doc = new Document({
|
|
133
|
-
...(ledger.registry ? { registry: ledger.registry } : {}),
|
|
134
|
-
modules,
|
|
135
|
-
});
|
|
165
|
+
const doc = new Document({ modules });
|
|
136
166
|
return (
|
|
137
167
|
"# Generated by `telo release apply` — what each module looks like as published.\n" +
|
|
138
168
|
"# A cache of the registry's answer, so a PR gate needs no credentials.\n" +
|
|
@@ -54,7 +54,8 @@ export const LOCALLY_DERIVED_LAYERS: ReadonlySet<string> = new Set([MANIFEST_LAY
|
|
|
54
54
|
* `axis=value;…` form, because this string is read by a human in a ledger diff
|
|
55
55
|
* and written into a plain YAML key; the axis order is `PLATFORM_AXES`, so the
|
|
56
56
|
* rendering is deterministic rather than dependent on how the selector was
|
|
57
|
-
* built.
|
|
57
|
+
* built. An axis a selector omits renders nothing, so a new axis appended to the
|
|
58
|
+
* vocabulary leaves every existing key unchanged — reordering it would not.
|
|
58
59
|
*/
|
|
59
60
|
export function layerDigestKey(role: LayerRole | string, selector?: ArtifactSelector): string {
|
|
60
61
|
if (!selector) return role;
|
|
@@ -67,14 +67,15 @@ export interface ModuleEvidence {
|
|
|
67
67
|
/** Whether a file under this module's own directory that reaches the artifact
|
|
68
68
|
* changed. Decides only whether a changelog line is requested. */
|
|
69
69
|
readonly ownFilesChanged: boolean;
|
|
70
|
+
/** The publish destination base THIS module's payload was built against —
|
|
71
|
+
* per module, because a workspace may declare one per subtree. */
|
|
72
|
+
readonly registry: string;
|
|
70
73
|
}
|
|
71
74
|
|
|
72
75
|
export interface ReleaseEvidence {
|
|
73
76
|
readonly modules: readonly ModuleEvidence[];
|
|
74
77
|
readonly ledger: Ledger;
|
|
75
78
|
readonly fragments: readonly ReleaseFragment[];
|
|
76
|
-
/** The publish destination base the digests above were built against. */
|
|
77
|
-
readonly registry?: string;
|
|
78
79
|
}
|
|
79
80
|
|
|
80
81
|
/** Why a module is in the plan. A module usually carries several. */
|
|
@@ -123,14 +124,25 @@ export function planRelease(evidence: ReleaseEvidence): ReleasePlan {
|
|
|
123
124
|
const diagnostics: ReleaseDiagnostic[] = [];
|
|
124
125
|
const byKey = new Map(evidence.modules.map((module) => [module.key, module]));
|
|
125
126
|
|
|
126
|
-
checkRegistryAgreement(evidence, diagnostics);
|
|
127
|
-
|
|
128
127
|
// What the digest says, per module. A module with no ledger entry has never
|
|
129
128
|
// been published, which is not drift — there is nothing to differ from.
|
|
130
129
|
const drift = new Map<ModuleKey, LayerChange[]>();
|
|
131
130
|
for (const module of evidence.modules) {
|
|
132
131
|
const recorded = evidence.ledger.modules.get(module.key);
|
|
133
132
|
if (!recorded) continue;
|
|
133
|
+
if (recorded.registry && recorded.registry !== module.registry) {
|
|
134
|
+
diagnostics.push({
|
|
135
|
+
severity: "error",
|
|
136
|
+
code: "LEDGER_REGISTRY_MISMATCH",
|
|
137
|
+
message:
|
|
138
|
+
`${module.key}: its ledger digests were taken against '${recorded.registry}', but this ` +
|
|
139
|
+
`run built against '${module.registry}'. Publishing rewrites each relative import to ` +
|
|
140
|
+
`'<base>/<sibling>@<version>', so the manifest layers of the two are different bytes ` +
|
|
141
|
+
`and comparing them would report the module as changed. Publish to the recorded base, ` +
|
|
142
|
+
`or re-record with \`telo release verify --write\`.`,
|
|
143
|
+
});
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
134
146
|
if (recorded.version !== module.version) {
|
|
135
147
|
diagnostics.push({
|
|
136
148
|
severity: "error",
|
|
@@ -340,28 +352,6 @@ function requestMissingChangelogEntries(
|
|
|
340
352
|
});
|
|
341
353
|
}
|
|
342
354
|
|
|
343
|
-
/**
|
|
344
|
-
* The base the digests were built against has to be the base they were recorded
|
|
345
|
-
* against, or the manifest layers are not comparable: canonicalization writes
|
|
346
|
-
* the destination into them.
|
|
347
|
-
*/
|
|
348
|
-
function checkRegistryAgreement(
|
|
349
|
-
evidence: ReleaseEvidence,
|
|
350
|
-
diagnostics: ReleaseDiagnostic[],
|
|
351
|
-
): void {
|
|
352
|
-
const recorded = evidence.ledger.registry;
|
|
353
|
-
if (!recorded || !evidence.registry || recorded === evidence.registry) return;
|
|
354
|
-
diagnostics.push({
|
|
355
|
-
severity: "error",
|
|
356
|
-
code: "LEDGER_REGISTRY_MISMATCH",
|
|
357
|
-
message:
|
|
358
|
-
`The ledger's digests were taken against '${recorded}', but this run built against ` +
|
|
359
|
-
`'${evidence.registry}'. Publishing rewrites each relative import to ` +
|
|
360
|
-
`'<base>/<sibling>@<version>', so the manifest layers of the two are different bytes ` +
|
|
361
|
-
`and comparing them would report every module as changed.`,
|
|
362
|
-
});
|
|
363
|
-
}
|
|
364
|
-
|
|
365
355
|
/**
|
|
366
356
|
* Dependency order over in-repo imports — a dependency before its dependents.
|
|
367
357
|
*
|