@telorun/analyzer 0.60.0 → 0.62.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 +130 -9
- package/dist/artifact-layer-index.d.ts +13 -5
- package/dist/artifact-layer-index.d.ts.map +1 -1
- package/dist/artifact-layer-index.js +37 -13
- package/dist/artifact-selector.d.ts +10 -3
- package/dist/artifact-selector.d.ts.map +1 -1
- package/dist/artifact-selector.js +10 -1
- package/dist/builtins.d.ts.map +1 -1
- package/dist/builtins.js +97 -13
- package/dist/cel-bindings.d.ts +0 -6
- package/dist/cel-bindings.d.ts.map +1 -1
- package/dist/cel-bindings.js +3 -28
- package/dist/definition-registry.d.ts +17 -0
- package/dist/definition-registry.d.ts.map +1 -1
- package/dist/definition-registry.js +31 -2
- package/dist/identifier-name.d.ts +114 -0
- package/dist/identifier-name.d.ts.map +1 -0
- package/dist/identifier-name.js +183 -0
- package/dist/index.d.ts +14 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -2
- package/dist/manifest-schemas.d.ts +81 -0
- package/dist/manifest-schemas.d.ts.map +1 -1
- package/dist/manifest-schemas.js +208 -6
- package/dist/module-file-claims.d.ts +7 -0
- package/dist/module-file-claims.d.ts.map +1 -1
- package/dist/module-file-claims.js +22 -2
- package/dist/module-library.d.ts +97 -0
- package/dist/module-library.d.ts.map +1 -0
- package/dist/module-library.js +162 -0
- package/dist/requires-block.d.ts +125 -0
- package/dist/requires-block.d.ts.map +1 -0
- package/dist/requires-block.js +182 -0
- package/dist/schema-keywords.d.ts +68 -0
- package/dist/schema-keywords.d.ts.map +1 -0
- package/dist/schema-keywords.js +324 -0
- package/dist/schema-region.d.ts +12 -1
- package/dist/schema-region.d.ts.map +1 -1
- package/dist/schema-region.js +12 -1
- package/dist/telo-version.d.ts +3 -0
- package/dist/telo-version.d.ts.map +1 -0
- package/dist/telo-version.js +8 -0
- package/dist/types.d.ts +31 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/validate-identifier-names.d.ts +31 -0
- package/dist/validate-identifier-names.d.ts.map +1 -0
- package/dist/validate-identifier-names.js +144 -0
- package/dist/validate-module-artifact.d.ts.map +1 -1
- package/dist/validate-module-artifact.js +53 -1
- package/dist/validate-observed-state.d.ts +9 -2
- package/dist/validate-observed-state.d.ts.map +1 -1
- package/dist/validate-observed-state.js +9 -2
- package/dist/validate-references.d.ts.map +1 -1
- package/dist/validate-references.js +5 -26
- package/dist/validate-requires.d.ts +49 -0
- package/dist/validate-requires.d.ts.map +1 -0
- package/dist/validate-requires.js +99 -0
- package/dist/value-type-keyword.d.ts +1 -1
- package/dist/value-type-keyword.d.ts.map +1 -1
- package/dist/value-type-keyword.js +1 -0
- package/dist/version-range.d.ts +88 -0
- package/dist/version-range.d.ts.map +1 -0
- package/dist/version-range.js +173 -0
- package/package.json +2 -2
- package/src/analyzer.ts +146 -10
- package/src/artifact-layer-index.ts +47 -14
- package/src/artifact-selector.ts +15 -4
- package/src/builtins.ts +102 -13
- package/src/cel-bindings.ts +3 -28
- package/src/definition-registry.ts +30 -2
- package/src/identifier-name.ts +228 -0
- package/src/index.ts +44 -1
- package/src/manifest-schemas.ts +223 -4
- package/src/module-file-claims.ts +32 -2
- package/src/module-library.ts +208 -0
- package/src/requires-block.ts +253 -0
- package/src/schema-keywords.ts +359 -0
- package/src/schema-region.ts +12 -1
- package/src/telo-version.ts +9 -0
- package/src/types.ts +32 -0
- package/src/validate-identifier-names.ts +173 -0
- package/src/validate-module-artifact.ts +56 -0
- package/src/validate-observed-state.ts +9 -2
- package/src/validate-references.ts +5 -26
- package/src/validate-requires.ts +129 -0
- package/src/value-type-keyword.ts +1 -0
- package/src/version-range.ts +238 -0
package/dist/analyzer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAWzE,OAAO,EACL,aAAa,EAEb,KAAK,YAAY,EAElB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAIL,KAAK,WAAW,EACjB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAE9D,OAAO,EACL,KAAK,aAAa,EAGnB,MAAM,0BAA0B,CAAC;AAsBlC,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAwBvF,OAAO,EAAsB,KAAK,kBAAkB,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"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"}
|
package/dist/analyzer.js
CHANGED
|
@@ -29,12 +29,15 @@ import { collectValueSchemaIssues } from "./validate-value-schema.js";
|
|
|
29
29
|
import { DiagnosticSeverity } from "./types.js";
|
|
30
30
|
import { extractAccessChains, extractCelRegionScopes, getManifestItem, pathMatchesScope, resolveContextAnnotations, resolveTypeFieldToSchema, } from "./validate-cel-context.js";
|
|
31
31
|
import { buildEvalPaths, evalPathsCover } from "./eval-paths.js";
|
|
32
|
-
import { BINDINGS_ANNOTATION, bindingContextProperties, bindingPathChain,
|
|
32
|
+
import { BINDINGS_ANNOTATION, bindingContextProperties, bindingPathChain, findBindingSites, resolveBindingOrder, schemaAtChain, } from "./cel-bindings.js";
|
|
33
|
+
import { CEL_RESERVED_WORDS, checkName } from "./identifier-name.js";
|
|
34
|
+
import { validateIdentifierNames } from "./validate-identifier-names.js";
|
|
33
35
|
import { validateExtends } from "./validate-extends.js";
|
|
34
36
|
import { validateLogging } from "./validate-logging.js";
|
|
35
37
|
import { validateModuleArtifact } from "./validate-module-artifact.js";
|
|
36
38
|
import { validateIncludePlacement } from "./validate-include-placement.js";
|
|
37
39
|
import { validateModuleMetadata } from "./validate-module-metadata.js";
|
|
40
|
+
import { validateRequires } from "./validate-requires.js";
|
|
38
41
|
import { validateBaseMapping } from "./validate-base-mapping.js";
|
|
39
42
|
import { validateInvocationContract } from "./validate-invocation-contract.js";
|
|
40
43
|
import { collectStepInputIssues } from "./validate-step-inputs.js";
|
|
@@ -819,6 +822,85 @@ function collectCelValueSlots(data, schema, path) {
|
|
|
819
822
|
}
|
|
820
823
|
return slots;
|
|
821
824
|
}
|
|
825
|
+
/**
|
|
826
|
+
* Files belonging to a module this runtime declared itself unable to read.
|
|
827
|
+
*
|
|
828
|
+
* Attribution is by FILE rather than by resource identity, the same choice
|
|
829
|
+
* `remapMigratedPaths` makes and for the same reason: a diagnostic carries at
|
|
830
|
+
* most two routing facts and routinely only one, so indexing by resource would
|
|
831
|
+
* leave every diagnostic without `data.resource` unreachable.
|
|
832
|
+
*
|
|
833
|
+
* **A module NAME is not a graph-unique key.** Names are module-scoped, so two
|
|
834
|
+
* libraries may both be called `Store` — CLAUDE.md names this exact hazard for
|
|
835
|
+
* migration provenance ("two libraries declaring a Store would share one
|
|
836
|
+
* bucket"), where the answer is to narrow or not remap at all. Same answer here:
|
|
837
|
+
* the gated doc's own `metadata.source` is always suppressed, and a name is used
|
|
838
|
+
* to reach its `include:` partials only when that name identifies exactly ONE
|
|
839
|
+
* module doc in the set. Where it does not, the partials keep their diagnostics
|
|
840
|
+
* rather than risk silencing an unrelated library's — a stray extra diagnostic is
|
|
841
|
+
* a far cheaper failure than a hidden one.
|
|
842
|
+
*
|
|
843
|
+
* A module doc with no `source` contributes nothing — suppressing on a guess
|
|
844
|
+
* would hide diagnostics belonging to files nobody named.
|
|
845
|
+
*/
|
|
846
|
+
function filesOfUnreadableModules(manifests, requiresDiagnostics) {
|
|
847
|
+
const files = new Set();
|
|
848
|
+
const gatedNames = new Set();
|
|
849
|
+
for (const d of requiresDiagnostics) {
|
|
850
|
+
if (d.code !== "MODULE_REQUIRES_NEWER_RUNTIME")
|
|
851
|
+
continue;
|
|
852
|
+
const data = d.data;
|
|
853
|
+
// The gated document itself, addressed by the file it was declared in.
|
|
854
|
+
if (typeof data?.filePath === "string" && data.filePath)
|
|
855
|
+
files.add(data.filePath);
|
|
856
|
+
const name = data?.resource?.name;
|
|
857
|
+
if (typeof name === "string")
|
|
858
|
+
gatedNames.add(name);
|
|
859
|
+
}
|
|
860
|
+
if (files.size === 0 && gatedNames.size === 0)
|
|
861
|
+
return files;
|
|
862
|
+
// How many module docs answer to each gated name — the ambiguity test.
|
|
863
|
+
const docsPerName = new Map();
|
|
864
|
+
for (const m of manifests) {
|
|
865
|
+
if (m.kind !== "Telo.Application" && m.kind !== "Telo.Library")
|
|
866
|
+
continue;
|
|
867
|
+
const name = m.metadata?.name;
|
|
868
|
+
if (typeof name === "string" && gatedNames.has(name)) {
|
|
869
|
+
docsPerName.set(name, (docsPerName.get(name) ?? 0) + 1);
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
for (const m of manifests) {
|
|
873
|
+
const metadata = (m.metadata ?? {});
|
|
874
|
+
const owner = metadata.module;
|
|
875
|
+
if (typeof owner !== "string" || !gatedNames.has(owner))
|
|
876
|
+
continue;
|
|
877
|
+
if (docsPerName.get(owner) !== 1)
|
|
878
|
+
continue; // ambiguous — do not guess
|
|
879
|
+
if (typeof metadata.source === "string" && metadata.source)
|
|
880
|
+
files.add(metadata.source);
|
|
881
|
+
}
|
|
882
|
+
return files;
|
|
883
|
+
}
|
|
884
|
+
/**
|
|
885
|
+
* Drop every diagnostic anchored in a file whose module this runtime cannot
|
|
886
|
+
* read, except the gate diagnostic itself.
|
|
887
|
+
*
|
|
888
|
+
* A filter rather than a guard on each validator: threading "skip this module"
|
|
889
|
+
* through thirty validators would make each one responsible for a rule none of
|
|
890
|
+
* them owns, and a validator added later would silently opt out of it. A
|
|
891
|
+
* diagnostic with no `filePath` is KEPT — suppression must never be the default
|
|
892
|
+
* for something it cannot attribute.
|
|
893
|
+
*/
|
|
894
|
+
function suppressUnreadableModuleDiagnostics(diagnostics, unreadableFiles) {
|
|
895
|
+
if (unreadableFiles.size === 0)
|
|
896
|
+
return diagnostics;
|
|
897
|
+
return diagnostics.filter((d) => {
|
|
898
|
+
if (d.code === "MODULE_REQUIRES_NEWER_RUNTIME")
|
|
899
|
+
return true;
|
|
900
|
+
const filePath = d.data?.filePath;
|
|
901
|
+
return typeof filePath !== "string" || !unreadableFiles.has(filePath);
|
|
902
|
+
});
|
|
903
|
+
}
|
|
822
904
|
export class StaticAnalyzer {
|
|
823
905
|
celEnv;
|
|
824
906
|
constructor(options = {}) {
|
|
@@ -1278,6 +1360,21 @@ export class StaticAnalyzer {
|
|
|
1278
1360
|
});
|
|
1279
1361
|
}
|
|
1280
1362
|
}
|
|
1363
|
+
// Declared runtime requirements, FIRST among the validators and suppressing
|
|
1364
|
+
// the rest for any module this runtime cannot read. A module that adopted
|
|
1365
|
+
// newer syntax also produces the vocabulary errors that syntax causes here —
|
|
1366
|
+
// an unknown `use` token, an object where a zone annotation expects a
|
|
1367
|
+
// pointer, an `additionalProperties` violation against a kernel-owned
|
|
1368
|
+
// schema — every one of which is true and blames the module's author for a
|
|
1369
|
+
// version skew. Reporting them beside the gate would bury the one message
|
|
1370
|
+
// that names the actual cause and the actual fix.
|
|
1371
|
+
const requiresDiagnostics = validateRequires(allManifests, {
|
|
1372
|
+
teloVersion: options?.teloVersion,
|
|
1373
|
+
hostVersions: options?.hostVersions,
|
|
1374
|
+
entryModules: rootModules,
|
|
1375
|
+
});
|
|
1376
|
+
const unreadableFiles = filesOfUnreadableModules(allManifests, requiresDiagnostics);
|
|
1377
|
+
diagnostics.push(...requiresDiagnostics);
|
|
1281
1378
|
if (!options?.skipValidation) {
|
|
1282
1379
|
diagnostics.push(...validateSchemaTypeRefs(allManifests, defs, aliases, aliasesByModule, rootModules));
|
|
1283
1380
|
// §14.1 / §10.3: redaction paths and `on_full: block` are statically
|
|
@@ -1292,6 +1389,11 @@ export class StaticAnalyzer {
|
|
|
1292
1389
|
// these fields, which is precisely why they need a check: a mistyped one
|
|
1293
1390
|
// has no runtime failure mode that would ever surface it.
|
|
1294
1391
|
diagnostics.push(...validateModuleMetadata(allManifests, defs, aliases));
|
|
1392
|
+
// Every author-written name. Telo has no lexer, so a name's shape is
|
|
1393
|
+
// unchecked where it is declared and its consequences land at whichever
|
|
1394
|
+
// CEL site reads it — for a hyphen, sometimes as silent arithmetic. Takes
|
|
1395
|
+
// the call graph for step names rather than re-walking the step arrays.
|
|
1396
|
+
diagnostics.push(...validateIdentifierNames(allManifests, defs, aliases, rootModules, getCallGraph()));
|
|
1295
1397
|
// A file embed resolves at resource creation, so one written on a doc that
|
|
1296
1398
|
// is never instantiated is read by nothing and would ship silently.
|
|
1297
1399
|
diagnostics.push(...validateIncludePlacement(allManifests));
|
|
@@ -1304,7 +1406,7 @@ export class StaticAnalyzer {
|
|
|
1304
1406
|
// normalisation have already run above; that's all downstream
|
|
1305
1407
|
// consumers (prepare, init loop) require.
|
|
1306
1408
|
if (options?.skipValidation) {
|
|
1307
|
-
return diagnostics;
|
|
1409
|
+
return suppressUnreadableModuleDiagnostics(diagnostics, unreadableFiles);
|
|
1308
1410
|
}
|
|
1309
1411
|
// Build a name→manifest map for looking up referenced resources
|
|
1310
1412
|
const byName = new Map();
|
|
@@ -1769,15 +1871,34 @@ export class StaticAnalyzer {
|
|
|
1769
1871
|
const keywords = new Set(CEL_RESERVED_WORDS);
|
|
1770
1872
|
for (const name of Object.keys(declared)) {
|
|
1771
1873
|
const shadows = inScope.has(name);
|
|
1772
|
-
if (
|
|
1874
|
+
if (shadows || keywords.has(name)) {
|
|
1875
|
+
diagnostics.push({
|
|
1876
|
+
severity: DiagnosticSeverity.Error,
|
|
1877
|
+
code: "BINDING_NAME_RESERVED",
|
|
1878
|
+
source: SOURCE,
|
|
1879
|
+
message: shadows
|
|
1880
|
+
? `${m.kind}/${bindingsName}: binding '${name}' shadows a variable already in scope here (${[...inScope].sort().join(", ")}). Rename the binding — a scope variable always wins, so this one would never be read.`
|
|
1881
|
+
: `${m.kind}/${bindingsName}: binding '${name}' is a CEL keyword, so no expression can read it as a reference. Rename the binding.`,
|
|
1882
|
+
data: {
|
|
1883
|
+
resource: resourceRef,
|
|
1884
|
+
filePath: bindingsFile,
|
|
1885
|
+
path: `${celBindingSites.field}.${name}`,
|
|
1886
|
+
},
|
|
1887
|
+
});
|
|
1888
|
+
continue;
|
|
1889
|
+
}
|
|
1890
|
+
// A binding is read by bare name, so it lives in the same
|
|
1891
|
+
// identifier space as a resource or step name and breaks the
|
|
1892
|
+
// same way. The keyword tier is unreachable here — the check
|
|
1893
|
+
// above owns it, and can also say what is being shadowed.
|
|
1894
|
+
const violation = checkName(name, "value", "binding name");
|
|
1895
|
+
if (!violation)
|
|
1773
1896
|
continue;
|
|
1774
1897
|
diagnostics.push({
|
|
1775
|
-
severity:
|
|
1776
|
-
code:
|
|
1898
|
+
severity: violation.severity,
|
|
1899
|
+
code: violation.code,
|
|
1777
1900
|
source: SOURCE,
|
|
1778
|
-
message:
|
|
1779
|
-
? `${m.kind}/${bindingsName}: binding '${name}' shadows a variable already in scope here (${[...inScope].sort().join(", ")}). Rename the binding — a scope variable always wins, so this one would never be read.`
|
|
1780
|
-
: `${m.kind}/${bindingsName}: binding '${name}' is a CEL keyword, so no expression can read it as a reference. Rename the binding.`,
|
|
1901
|
+
message: `${m.kind}/${bindingsName}: ${violation.message}`,
|
|
1781
1902
|
data: {
|
|
1782
1903
|
resource: resourceRef,
|
|
1783
1904
|
filePath: bindingsFile,
|
|
@@ -2120,7 +2241,7 @@ export class StaticAnalyzer {
|
|
|
2120
2241
|
diagnostics.push(...validateUnusedDeclarations(allManifests, this.celEnv));
|
|
2121
2242
|
// Reroute diagnostics on synthetic (inline-extracted) resources back to
|
|
2122
2243
|
// the chain root so position-index lookups land on the parent doc.
|
|
2123
|
-
return rewriteSyntheticOrigins(diagnostics, allManifests);
|
|
2244
|
+
return rewriteSyntheticOrigins(suppressUnreadableModuleDiagnostics(diagnostics, unreadableFiles), allManifests);
|
|
2124
2245
|
}
|
|
2125
2246
|
analyzeErrors(manifests, options, registry, zoneExportCache) {
|
|
2126
2247
|
return this.analyze(manifests, options, registry, zoneExportCache).filter((d) => d.severity === DiagnosticSeverity.Error);
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
import { type ArtifactSelector, type LayerRole, type PlatformTarget } from "./artifact-selector.js";
|
|
31
31
|
export interface ArtifactLayer {
|
|
32
32
|
role: LayerRole;
|
|
33
|
-
/** Present on `controller`
|
|
33
|
+
/** Present on the code-bearing roles (`controller`, `library`) only. */
|
|
34
34
|
selector?: ArtifactSelector;
|
|
35
35
|
/** OCI blob digest — addresses the layer and verifies the transfer. */
|
|
36
36
|
blob: string;
|
|
@@ -48,8 +48,16 @@ export declare class LayerIndexError extends Error {
|
|
|
48
48
|
*/
|
|
49
49
|
export declare function parseLayerIndex(value: unknown, describe?: string): ArtifactLayer[];
|
|
50
50
|
/** The singleton layer for a role, or undefined when the artifact has none. */
|
|
51
|
-
export declare function singletonLayer(layers: readonly ArtifactLayer[], role: Exclude<LayerRole, "controller">): ArtifactLayer | undefined;
|
|
52
|
-
/**
|
|
53
|
-
*
|
|
54
|
-
|
|
51
|
+
export declare function singletonLayer(layers: readonly ArtifactLayer[], role: Exclude<LayerRole, "controller" | "library">): ArtifactLayer | undefined;
|
|
52
|
+
/** The layer of one code role carrying exactly `selector`, or undefined.
|
|
53
|
+
*
|
|
54
|
+
* By exact key rather than by re-matching a host: the candidate being resolved
|
|
55
|
+
* already *is* one selector, and it is by construction the key of the layer
|
|
56
|
+
* that carries it. */
|
|
57
|
+
export declare function codeLayerFor(layers: readonly ArtifactLayer[], role: Extract<LayerRole, "controller" | "library">, selector: ArtifactSelector): ArtifactLayer | undefined;
|
|
58
|
+
/** Every code layer — controller and library alike — matching `target`, in
|
|
59
|
+
* declaration order. Used by `telo install` to warm a cache for one platform:
|
|
60
|
+
* a library layer is as much a prerequisite of an offline run as the controller
|
|
61
|
+
* layer that imports it. */
|
|
62
|
+
export declare function matchCodeLayers(layers: readonly ArtifactLayer[], target: PlatformTarget): ArtifactLayer[];
|
|
55
63
|
//# sourceMappingURL=artifact-layer-index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"artifact-layer-index.d.ts","sourceRoot":"","sources":["../src/artifact-layer-index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"artifact-layer-index.d.ts","sourceRoot":"","sources":["../src/artifact-layer-index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAOL,KAAK,gBAAgB,EACrB,KAAK,SAAS,EACd,KAAK,cAAc,EACpB,MAAM,wBAAwB,CAAC;AAQhC,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,SAAS,CAAC;IAChB,wEAAwE;IACxE,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,uEAAuE;IACvE,IAAI,EAAE,MAAM,CAAC;IACb,wEAAwE;IACxE,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,eAAgB,SAAQ,KAAK;IACxC,QAAQ,CAAC,IAAI,yBAAyB;gBAE1B,MAAM,EAAE,MAAM;CAI3B;AAiBD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,SAAW,GAAG,aAAa,EAAE,CAmEpF;AAED,+EAA+E;AAC/E,wBAAgB,cAAc,CAC5B,MAAM,EAAE,SAAS,aAAa,EAAE,EAChC,IAAI,EAAE,OAAO,CAAC,SAAS,EAAE,YAAY,GAAG,SAAS,CAAC,GACjD,aAAa,GAAG,SAAS,CAE3B;AAED;;;;uBAIuB;AACvB,wBAAgB,YAAY,CAC1B,MAAM,EAAE,SAAS,aAAa,EAAE,EAChC,IAAI,EAAE,OAAO,CAAC,SAAS,EAAE,YAAY,GAAG,SAAS,CAAC,EAClD,QAAQ,EAAE,gBAAgB,GACzB,aAAa,GAAG,SAAS,CAK3B;AAED;;;6BAG6B;AAC7B,wBAAgB,eAAe,CAC7B,MAAM,EAAE,SAAS,aAAa,EAAE,EAChC,MAAM,EAAE,cAAc,GACrB,aAAa,EAAE,CAOjB"}
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
* Browser-safe: `telo check`, the editor and the hub validate an index through
|
|
28
28
|
* this module; only the kernel fetches and extracts.
|
|
29
29
|
*/
|
|
30
|
-
import { isLayerRole, normalizeSelector, selectorKey, selectorMatches, } from "./artifact-selector.js";
|
|
30
|
+
import { LAYER_ROLES, isLayerRole, normalizeSelector, roleCarriesSelector, selectorKey, selectorMatches, } from "./artifact-selector.js";
|
|
31
31
|
/** OCI content digest: `sha256:` + 64 lowercase hex. */
|
|
32
32
|
const BLOB_DIGEST = /^sha256:[0-9a-f]{64}$/;
|
|
33
33
|
/** Telo content digest: `sha256-` + unpadded base64url of 32 bytes. */
|
|
@@ -69,21 +69,32 @@ export function parseLayerIndex(value, describe = "layers") {
|
|
|
69
69
|
throw new LayerIndexError(`${where}: expected an object.`);
|
|
70
70
|
}
|
|
71
71
|
const entry = raw;
|
|
72
|
-
if (
|
|
73
|
-
throw new LayerIndexError(`${where}: role must be one of
|
|
74
|
-
|
|
72
|
+
if (typeof entry.role !== "string" || entry.role === "") {
|
|
73
|
+
throw new LayerIndexError(`${where}: role is required and must be one of ${LAYER_ROLES.map((r) => `'${r}'`).join(", ")}; ` +
|
|
74
|
+
`got ${entry.role === undefined ? "nothing" : `'${String(entry.role)}'`}.`);
|
|
75
75
|
}
|
|
76
|
+
// A role this runtime does not know is SKIPPED, never rejected. Roles are
|
|
77
|
+
// added over time, and a runtime that cannot name one cannot need it — while
|
|
78
|
+
// throwing would make the whole manifest unreadable, so a module gaining a
|
|
79
|
+
// layer for a newer runtime would stop loading on an older one entirely
|
|
80
|
+
// rather than merely lacking that layer. The error stays for a structurally
|
|
81
|
+
// invalid entry, which is a malformed index rather than a newer one.
|
|
82
|
+
if (!isLayerRole(entry.role))
|
|
83
|
+
return;
|
|
76
84
|
const role = entry.role;
|
|
77
85
|
let selector;
|
|
78
|
-
if (role
|
|
86
|
+
if (roleCarriesSelector(role)) {
|
|
79
87
|
if (entry.selector === undefined) {
|
|
80
|
-
throw new LayerIndexError(`${where}: a
|
|
88
|
+
throw new LayerIndexError(`${where}: a ${role} layer must declare a selector.`);
|
|
81
89
|
}
|
|
82
90
|
selector = normalizeSelector(entry.selector, where);
|
|
83
|
-
|
|
91
|
+
// Scoped by role: a module's `js` controller layer and its `js` library
|
|
92
|
+
// layer are different layers with the same selector, and only a collision
|
|
93
|
+
// *within* one role means two layers claim one address.
|
|
94
|
+
const key = `${role}\0${selectorKey(selector)}`;
|
|
84
95
|
if (seenSelectors.has(key)) {
|
|
85
|
-
throw new LayerIndexError(`${where}: a second
|
|
86
|
-
`Each selector addresses exactly one layer.`);
|
|
96
|
+
throw new LayerIndexError(`${where}: a second ${role} layer claims the selector ${selectorKey(selector)}. ` +
|
|
97
|
+
`Each selector addresses exactly one layer of a role.`);
|
|
87
98
|
}
|
|
88
99
|
seenSelectors.add(key);
|
|
89
100
|
}
|
|
@@ -109,8 +120,21 @@ export function parseLayerIndex(value, describe = "layers") {
|
|
|
109
120
|
export function singletonLayer(layers, role) {
|
|
110
121
|
return layers.find((l) => l.role === role);
|
|
111
122
|
}
|
|
112
|
-
/**
|
|
113
|
-
*
|
|
114
|
-
|
|
115
|
-
|
|
123
|
+
/** The layer of one code role carrying exactly `selector`, or undefined.
|
|
124
|
+
*
|
|
125
|
+
* By exact key rather than by re-matching a host: the candidate being resolved
|
|
126
|
+
* already *is* one selector, and it is by construction the key of the layer
|
|
127
|
+
* that carries it. */
|
|
128
|
+
export function codeLayerFor(layers, role, selector) {
|
|
129
|
+
const key = selectorKey(selector);
|
|
130
|
+
return layers.find((l) => l.role === role && l.selector !== undefined && selectorKey(l.selector) === key);
|
|
131
|
+
}
|
|
132
|
+
/** Every code layer — controller and library alike — matching `target`, in
|
|
133
|
+
* declaration order. Used by `telo install` to warm a cache for one platform:
|
|
134
|
+
* a library layer is as much a prerequisite of an offline run as the controller
|
|
135
|
+
* layer that imports it. */
|
|
136
|
+
export function matchCodeLayers(layers, target) {
|
|
137
|
+
return layers.filter((l) => (l.role === "controller" || l.role === "library") &&
|
|
138
|
+
l.selector !== undefined &&
|
|
139
|
+
selectorMatches(l.selector, target));
|
|
116
140
|
}
|
|
@@ -24,11 +24,18 @@
|
|
|
24
24
|
* canonical OCI/GOOS names at the kernel boundary, since these values are
|
|
25
25
|
* published into OCI descriptors.
|
|
26
26
|
*/
|
|
27
|
-
/** The role a layer plays in a module artifact. `controller`
|
|
28
|
-
* selector; `assets` and `common` are singletons and carry none. */
|
|
29
|
-
export type LayerRole = "controller" | "assets" | "common";
|
|
27
|
+
/** The role a layer plays in a module artifact. `controller` and `library` layers
|
|
28
|
+
* carry a selector; `assets` and `common` are singletons and carry none. */
|
|
29
|
+
export type LayerRole = "controller" | "library" | "assets" | "common";
|
|
30
30
|
export declare const LAYER_ROLES: readonly LayerRole[];
|
|
31
31
|
export declare function isLayerRole(value: unknown): value is LayerRole;
|
|
32
|
+
/** The roles that hold executable code, and are therefore per format rather than
|
|
33
|
+
* singletons. A `library` layer is per selector for the same reason a
|
|
34
|
+
* `controller` layer is: a module's JS entry point and its future Rust one are
|
|
35
|
+
* different files, and a consumer resolves the one its own runtime can import.
|
|
36
|
+
* A singleton would be wrong the moment a second runtime ships. */
|
|
37
|
+
export declare const CODE_LAYER_ROLES: readonly LayerRole[];
|
|
38
|
+
export declare function roleCarriesSelector(role: LayerRole): boolean;
|
|
32
39
|
/** The platform axes, in canonical order. Not a closed vocabulary of *values* —
|
|
33
40
|
* new architectures appear without a Telo release — only of axis names. */
|
|
34
41
|
export declare const PLATFORM_AXES: readonly ["os", "arch", "libc"];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"artifact-selector.d.ts","sourceRoot":"","sources":["../src/artifact-selector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH;
|
|
1
|
+
{"version":3,"file":"artifact-selector.d.ts","sourceRoot":"","sources":["../src/artifact-selector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH;6EAC6E;AAC7E,MAAM,MAAM,SAAS,GAAG,YAAY,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEvE,eAAO,MAAM,WAAW,EAAE,SAAS,SAAS,EAAkD,CAAC;AAE/F,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,SAAS,CAE9D;AAED;;;;oEAIoE;AACpE,eAAO,MAAM,gBAAgB,EAAE,SAAS,SAAS,EAA8B,CAAC;AAEhF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAE5D;AAED;4EAC4E;AAC5E,eAAO,MAAM,aAAa,iCAAkC,CAAC;AAE7D,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1D,MAAM,WAAW,gBAAgB;IAC/B,kFAAkF;IAClF,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;kFAGkF;AAClF,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,QAAQ,CAAC,IAAI,+BAA+B;gBAEhC,MAAM,EAAE,MAAM;CAI3B;AAsBD;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,OAAO,EACf,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,SAAS,EACzD,QAAQ,SAAwB,GAC/B,gBAAgB,CAUlB;AAED,0EAA0E;AAC1E,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,OAAO,EACd,QAAQ,SAAmB,GAC1B,gBAAgB,CAelB;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,gBAAgB,GAAG,MAAM,CAO9D;AAED,iFAAiF;AACjF,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,MAAM,CAKnE;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,gBAAgB,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,CAQ3F"}
|
|
@@ -24,10 +24,19 @@
|
|
|
24
24
|
* canonical OCI/GOOS names at the kernel boundary, since these values are
|
|
25
25
|
* published into OCI descriptors.
|
|
26
26
|
*/
|
|
27
|
-
export const LAYER_ROLES = ["controller", "assets", "common"];
|
|
27
|
+
export const LAYER_ROLES = ["controller", "library", "assets", "common"];
|
|
28
28
|
export function isLayerRole(value) {
|
|
29
29
|
return typeof value === "string" && LAYER_ROLES.includes(value);
|
|
30
30
|
}
|
|
31
|
+
/** The roles that hold executable code, and are therefore per format rather than
|
|
32
|
+
* singletons. A `library` layer is per selector for the same reason a
|
|
33
|
+
* `controller` layer is: a module's JS entry point and its future Rust one are
|
|
34
|
+
* different files, and a consumer resolves the one its own runtime can import.
|
|
35
|
+
* A singleton would be wrong the moment a second runtime ships. */
|
|
36
|
+
export const CODE_LAYER_ROLES = ["controller", "library"];
|
|
37
|
+
export function roleCarriesSelector(role) {
|
|
38
|
+
return CODE_LAYER_ROLES.includes(role);
|
|
39
|
+
}
|
|
31
40
|
/** The platform axes, in canonical order. Not a closed vocabulary of *values* —
|
|
32
41
|
* new architectures appear without a Telo release — only of axis names. */
|
|
33
42
|
export const PLATFORM_AXES = ["os", "arch", "libc"];
|
package/dist/builtins.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builtins.d.ts","sourceRoot":"","sources":["../src/builtins.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"builtins.d.ts","sourceRoot":"","sources":["../src/builtins.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAiNvD,eAAO,MAAM,eAAe,EAAE,kBAAkB,EAusB/C,CAAC"}
|
package/dist/builtins.js
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
|
-
import { manifestFragment } from "./manifest-schemas.js";
|
|
2
|
-
|
|
1
|
+
import { manifestFragment, manifestFragmentRef, withSchemaFragments } from "./manifest-schemas.js";
|
|
2
|
+
/** A slot holding author-written JSON Schema. Localized and hoisted by
|
|
3
|
+
* {@link withSchemaFragments} on the enclosing schema, which is what makes the
|
|
4
|
+
* `#/$defs` pointer resolve inside whatever AJV compiles.
|
|
5
|
+
*
|
|
6
|
+
* `KindSchema` and `JsonSchema7` share a body; the name is the discriminator
|
|
7
|
+
* the IDE reads off the `x-telo-fragment` stamp to decide whether the
|
|
8
|
+
* `x-telo-*` vocabulary belongs here. A kind's own `schema:` is where it does;
|
|
9
|
+
* a `status:` block or an `inputType:` describes plain data, where it does not. */
|
|
10
|
+
const kindSchemaSlot = {
|
|
11
|
+
title: "Schema",
|
|
12
|
+
description: "Configuration this kind accepts, as JSON Schema plus `x-telo-*` annotations.",
|
|
13
|
+
$ref: manifestFragmentRef("KindSchema"),
|
|
14
|
+
};
|
|
15
|
+
/** Observed state a kind reports while running, as a data schema. `required:` is
|
|
16
|
+
* rejected separately by `validateObservedStateDeclarations`, which can say why
|
|
17
|
+
* and what to write instead. */
|
|
18
|
+
const observedStateSlot = {
|
|
19
|
+
title: "Observed state",
|
|
20
|
+
description: "What a resource of this kind reports while running, published at `resources.<name>.status.<field>`.",
|
|
21
|
+
$ref: manifestFragmentRef("JsonSchema7"),
|
|
22
|
+
};
|
|
3
23
|
/** Descriptive provenance a module declares about itself, shared by
|
|
4
24
|
* `Telo.Application` and `Telo.Library`.
|
|
5
25
|
*
|
|
@@ -21,6 +41,31 @@ const PROVENANCE_METADATA = {
|
|
|
21
41
|
license: { type: "string" },
|
|
22
42
|
documentation: { type: "string" },
|
|
23
43
|
};
|
|
44
|
+
/** The declared runtime requirements block, shared by `Telo.Application` and
|
|
45
|
+
* `Telo.Library` — the two module kinds, whose schemas are otherwise
|
|
46
|
+
* independent and would drift.
|
|
47
|
+
*
|
|
48
|
+
* **Deliberately says only "these are objects", and nothing about the values.**
|
|
49
|
+
* The grammar belongs to `requires-block.ts`, which is the single reader, and
|
|
50
|
+
* every rule that matters — `^` and `~` refused, a bare version refused, bounds
|
|
51
|
+
* that must not exclude each other, an upper bound that must name a version that
|
|
52
|
+
* exists — needs a parse and a comparison, not a schema. Adding `type: "string"`
|
|
53
|
+
* here bought nothing and cost a duplicate: `telo: 80` then produced BOTH a
|
|
54
|
+
* `SCHEMA_VIOLATION` and a `REQUIRES_INVALID` for one node, one of them phrased
|
|
55
|
+
* by a layer that does not know what the value is for.
|
|
56
|
+
*
|
|
57
|
+
* Left open at both tiers for the same reason. An unrecognized axis is reported
|
|
58
|
+
* by the reader with the vocabulary it knows — a far better message than AJV's —
|
|
59
|
+
* and, critically, is SUPPRESSED while the `telo` requirement is itself unmet,
|
|
60
|
+
* since an older runtime not knowing a newer axis is a consequence of the
|
|
61
|
+
* version skew rather than a second defect. AJV cannot express that ordering. */
|
|
62
|
+
const REQUIRES_SCHEMA = {
|
|
63
|
+
type: "object",
|
|
64
|
+
properties: {
|
|
65
|
+
host: { type: "object" },
|
|
66
|
+
},
|
|
67
|
+
additionalProperties: true,
|
|
68
|
+
};
|
|
24
69
|
/** Author-declared subset of `files:` that ships in the artifact's lazily
|
|
25
70
|
* materialized `assets` layer. Optional: an unclaimed file joins the `common`
|
|
26
71
|
* layer, which is pulled alongside any controller layer, so omitting this costs
|
|
@@ -29,6 +74,32 @@ const ASSETS_FILES_SCHEMA = {
|
|
|
29
74
|
type: "array",
|
|
30
75
|
items: { type: "string" },
|
|
31
76
|
};
|
|
77
|
+
/** `exports.code` — the entry point a sibling module's controller bundle resolves
|
|
78
|
+
* this library's bare specifier to, one per format.
|
|
79
|
+
*
|
|
80
|
+
* Data rather than a package URL: `controllers:` needs a PURL because it can name
|
|
81
|
+
* an ecosystem fetch (`pkg:npm`, `pkg:cargo`), while this always names a file the
|
|
82
|
+
* module already ships, so the type/namespace segments would be constant noise —
|
|
83
|
+
* and a query string is one opaque box to the visual editor. `format` plus the
|
|
84
|
+
* platform axes build the same `ArtifactSelector` a controller candidate does.
|
|
85
|
+
* Semantics and diagnostics live in `analyzer/nodejs/src/module-library.ts`. */
|
|
86
|
+
const LIBRARY_CANDIDATES_SCHEMA = {
|
|
87
|
+
type: "array",
|
|
88
|
+
items: {
|
|
89
|
+
type: "object",
|
|
90
|
+
required: ["specifier", "format", "path"],
|
|
91
|
+
properties: {
|
|
92
|
+
specifier: { type: "string" },
|
|
93
|
+
format: { type: "string" },
|
|
94
|
+
path: { type: "string" },
|
|
95
|
+
source: { type: "string" },
|
|
96
|
+
os: { type: "string" },
|
|
97
|
+
arch: { type: "string" },
|
|
98
|
+
libc: { type: "string" },
|
|
99
|
+
},
|
|
100
|
+
additionalProperties: false,
|
|
101
|
+
},
|
|
102
|
+
};
|
|
32
103
|
/** The published layer index, written by `telo publish` (never hand-authored).
|
|
33
104
|
* One entry per layer except the manifest layer, which cannot list its own hash
|
|
34
105
|
* inside itself and is pinned by the importer's `#sha256-...` instead. Shape and
|
|
@@ -40,7 +111,7 @@ const LAYER_INDEX_SCHEMA = {
|
|
|
40
111
|
type: "object",
|
|
41
112
|
required: ["role", "blob", "integrity"],
|
|
42
113
|
properties: {
|
|
43
|
-
role: { type: "string", enum: ["controller", "assets", "common"] },
|
|
114
|
+
role: { type: "string", enum: ["controller", "library", "assets", "common"] },
|
|
44
115
|
selector: {
|
|
45
116
|
type: "object",
|
|
46
117
|
required: ["format"],
|
|
@@ -239,13 +310,13 @@ export const KERNEL_BUILTINS = [
|
|
|
239
310
|
// kernel registers this controller directly at boot, before any lazy
|
|
240
311
|
// resolution — it states truthfully who provides it.
|
|
241
312
|
controllers: [{ runtime: "kernel", entry: "Telo.JsonSchema" }],
|
|
242
|
-
schema: {
|
|
313
|
+
schema: withSchemaFragments({
|
|
243
314
|
type: "object",
|
|
244
315
|
properties: {
|
|
245
316
|
schema: {
|
|
246
317
|
title: "Schema",
|
|
247
318
|
description: "JSON Schema definition for the declared data type.",
|
|
248
|
-
|
|
319
|
+
$ref: manifestFragmentRef("JsonSchema7"),
|
|
249
320
|
},
|
|
250
321
|
extends: {
|
|
251
322
|
title: "Extends",
|
|
@@ -278,13 +349,13 @@ export const KERNEL_BUILTINS = [
|
|
|
278
349
|
},
|
|
279
350
|
required: ["schema"],
|
|
280
351
|
additionalProperties: false,
|
|
281
|
-
},
|
|
352
|
+
}),
|
|
282
353
|
},
|
|
283
354
|
{
|
|
284
355
|
kind: "Telo.Definition",
|
|
285
356
|
metadata: { name: "Abstract", module: "Telo" },
|
|
286
357
|
capability: "Telo.Template",
|
|
287
|
-
schema: {
|
|
358
|
+
schema: withSchemaFragments({
|
|
288
359
|
type: "object",
|
|
289
360
|
properties: {
|
|
290
361
|
kind: { type: "string" },
|
|
@@ -295,15 +366,15 @@ export const KERNEL_BUILTINS = [
|
|
|
295
366
|
additionalProperties: true,
|
|
296
367
|
},
|
|
297
368
|
capability: { type: "string" },
|
|
298
|
-
schema:
|
|
299
|
-
status:
|
|
369
|
+
schema: kindSchemaSlot,
|
|
370
|
+
status: observedStateSlot,
|
|
300
371
|
},
|
|
301
372
|
required: ["metadata"],
|
|
302
373
|
// Telo.Abstract is an extension point by design — it must accept forward-compatible
|
|
303
374
|
// fields (e.g. inputType/outputType from the typed-abstracts plan) without requiring
|
|
304
375
|
// the analyzer to enumerate them here.
|
|
305
376
|
additionalProperties: true,
|
|
306
|
-
},
|
|
377
|
+
}),
|
|
307
378
|
},
|
|
308
379
|
{
|
|
309
380
|
kind: "Telo.Definition",
|
|
@@ -321,11 +392,17 @@ export const KERNEL_BUILTINS = [
|
|
|
321
392
|
// matching how Run.Sequence steps factor dispatch from data. The dispatch
|
|
322
393
|
// entry-point (`invoke` / `provide` / `run`) determines how `inputs`/`result`
|
|
323
394
|
// are interpreted at runtime. See analyzer/nodejs/plans/template-internal-cel-validation.md.
|
|
324
|
-
schema: {
|
|
395
|
+
schema: withSchemaFragments({
|
|
325
396
|
type: "object",
|
|
326
397
|
additionalProperties: true,
|
|
327
398
|
properties: {
|
|
328
|
-
|
|
399
|
+
// The kind's own configuration contract. Declared as a slot for the
|
|
400
|
+
// first time here: it was reachable only as an unnamed extra property,
|
|
401
|
+
// so nothing could say what belonged in it — no completion inside a
|
|
402
|
+
// `schema:` block, and a misspelled keyword surviving to a runtime
|
|
403
|
+
// failure that named a different field.
|
|
404
|
+
schema: kindSchemaSlot,
|
|
405
|
+
status: observedStateSlot,
|
|
329
406
|
resources: {
|
|
330
407
|
type: "array",
|
|
331
408
|
items: {
|
|
@@ -495,7 +572,7 @@ export const KERNEL_BUILTINS = [
|
|
|
495
572
|
},
|
|
496
573
|
},
|
|
497
574
|
},
|
|
498
|
-
},
|
|
575
|
+
}),
|
|
499
576
|
},
|
|
500
577
|
{
|
|
501
578
|
kind: "Telo.Definition",
|
|
@@ -746,6 +823,9 @@ export const KERNEL_BUILTINS = [
|
|
|
746
823
|
// CLI flag — so a level derived from the host environment goes through a
|
|
747
824
|
// `variables:` entry read with `!cel`. See kernel/specs/logging.md §12.
|
|
748
825
|
logging: ROOT_LOGGING_SCHEMA,
|
|
826
|
+
// The runtime range this module is verified against. See
|
|
827
|
+
// `analyzer/nodejs/src/requires-block.ts`.
|
|
828
|
+
requires: REQUIRES_SCHEMA,
|
|
749
829
|
},
|
|
750
830
|
required: ["metadata"],
|
|
751
831
|
additionalProperties: false,
|
|
@@ -832,9 +912,13 @@ export const KERNEL_BUILTINS = [
|
|
|
832
912
|
type: "array",
|
|
833
913
|
items: { type: "string", not: { enum: ["variables", "secrets"] } },
|
|
834
914
|
},
|
|
915
|
+
code: LIBRARY_CANDIDATES_SCHEMA,
|
|
835
916
|
},
|
|
836
917
|
additionalProperties: true,
|
|
837
918
|
},
|
|
919
|
+
// The runtime range this module is verified against. See
|
|
920
|
+
// `analyzer/nodejs/src/requires-block.ts`.
|
|
921
|
+
requires: REQUIRES_SCHEMA,
|
|
838
922
|
},
|
|
839
923
|
required: ["metadata"],
|
|
840
924
|
additionalProperties: false,
|
package/dist/cel-bindings.d.ts
CHANGED
|
@@ -14,12 +14,6 @@ export interface BindingSites {
|
|
|
14
14
|
/** Variable names the annotated contexts declare — a binding may not shadow one. */
|
|
15
15
|
scopeNames: Set<string>;
|
|
16
16
|
}
|
|
17
|
-
/**
|
|
18
|
-
* CEL keywords. A binding named after one is unreachable — `true` lexes as a
|
|
19
|
-
* literal, `in` as an operator — so it is reserved alongside the scope names,
|
|
20
|
-
* which turns silence into a diagnostic.
|
|
21
|
-
*/
|
|
22
|
-
export declare const CEL_RESERVED_WORDS: readonly string[];
|
|
23
17
|
/** Locate a kind's bindings field and the scope names its annotated contexts
|
|
24
18
|
* declare. Returns undefined for a kind that declares no bindings region. */
|
|
25
19
|
export declare function findBindingSites(definitionSchema: Record<string, any> | undefined): BindingSites | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cel-bindings.d.ts","sourceRoot":"","sources":["../src/cel-bindings.ts"],"names":[],"mappings":"AAIA;;;;gCAIgC;AAChC,eAAO,MAAM,mBAAmB,yBAAyB,CAAC;AAE1D,MAAM,WAAW,YAAY;IAC3B,+CAA+C;IAC/C,KAAK,EAAE,MAAM,CAAC;IACd;;gCAE4B;IAC5B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,oFAAoF;IACpF,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACzB;
|
|
1
|
+
{"version":3,"file":"cel-bindings.d.ts","sourceRoot":"","sources":["../src/cel-bindings.ts"],"names":[],"mappings":"AAIA;;;;gCAIgC;AAChC,eAAO,MAAM,mBAAmB,yBAAyB,CAAC;AAE1D,MAAM,WAAW,YAAY;IAC3B,+CAA+C;IAC/C,KAAK,EAAE,MAAM,CAAC;IACd;;gCAE4B;IAC5B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,oFAAoF;IACpF,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACzB;AAMD;8EAC8E;AAC9E,wBAAgB,gBAAgB,CAC9B,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,GAChD,YAAY,GAAG,SAAS,CAW1B;AAuDD;uEACuE;AACvE,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAW1B;AAED;;mFAEmF;AACnF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,GAAG,IAAI,CAQhE;AAED;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GACjC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAMrB;AAED;oEACoE;AACpE,wBAAgB,aAAa,CAC3B,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,EACtB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GACxB,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,CASjC;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IACtE,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC;CACpB,CAwBA"}
|