@telorun/analyzer 0.56.1 → 0.58.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 +5 -0
- package/dist/analyzer.d.ts.map +1 -1
- package/dist/analyzer.js +232 -94
- package/dist/cel-environment.d.ts.map +1 -1
- package/dist/cel-environment.js +6 -3
- package/dist/definition-registry.d.ts +5 -0
- package/dist/definition-registry.d.ts.map +1 -1
- package/dist/definition-registry.js +9 -0
- package/dist/index.d.ts +14 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -3
- package/dist/invocation-contract.d.ts +21 -13
- package/dist/invocation-contract.d.ts.map +1 -1
- package/dist/invocation-contract.js +43 -46
- package/dist/loaded-types.d.ts +13 -0
- package/dist/loaded-types.d.ts.map +1 -1
- package/dist/manifest-loader.d.ts +8 -1
- package/dist/manifest-loader.d.ts.map +1 -1
- package/dist/manifest-loader.js +33 -6
- package/dist/manifest-visitor.d.ts +4 -0
- package/dist/manifest-visitor.d.ts.map +1 -1
- package/dist/manifest-visitor.js +3 -3
- package/dist/migrations/driver.d.ts +69 -0
- package/dist/migrations/driver.d.ts.map +1 -0
- package/dist/migrations/driver.js +200 -0
- package/dist/migrations/entries/index.d.ts +3 -0
- package/dist/migrations/entries/index.d.ts.map +1 -0
- package/dist/migrations/entries/index.js +9 -0
- package/dist/migrations/entries/normalize-value-types.json +48 -0
- package/dist/migrations/entries/ref-slot-scalar-type.json +20 -0
- package/dist/migrations/entry-data.d.ts +25 -0
- package/dist/migrations/entry-data.d.ts.map +1 -0
- package/dist/migrations/entry-data.js +171 -0
- package/dist/migrations/index.d.ts +22 -0
- package/dist/migrations/index.d.ts.map +1 -0
- package/dist/migrations/index.js +19 -0
- package/dist/migrations/match.d.ts +162 -0
- package/dist/migrations/match.d.ts.map +1 -0
- package/dist/migrations/match.js +295 -0
- package/dist/migrations/patch.d.ts +68 -0
- package/dist/migrations/patch.d.ts.map +1 -0
- package/dist/migrations/patch.js +236 -0
- package/dist/migrations/provenance.d.ts +25 -0
- package/dist/migrations/provenance.d.ts.map +1 -0
- package/dist/migrations/provenance.js +118 -0
- package/dist/migrations/registry.d.ts +35 -0
- package/dist/migrations/registry.d.ts.map +1 -0
- package/dist/migrations/registry.js +35 -0
- package/dist/migrations/report.d.ts +28 -0
- package/dist/migrations/report.d.ts.map +1 -0
- package/dist/migrations/report.js +144 -0
- package/dist/migrations/types.d.ts +115 -0
- package/dist/migrations/types.d.ts.map +1 -0
- package/dist/migrations/types.js +24 -0
- package/dist/migrations/yaml-edit.d.ts +21 -0
- package/dist/migrations/yaml-edit.d.ts.map +1 -0
- package/dist/migrations/yaml-edit.js +245 -0
- package/dist/module-file-claims.d.ts +65 -0
- package/dist/module-file-claims.d.ts.map +1 -0
- package/dist/module-file-claims.js +106 -0
- package/dist/parse-loaded-file.d.ts +8 -0
- package/dist/parse-loaded-file.d.ts.map +1 -1
- package/dist/parse-loaded-file.js +22 -13
- package/dist/resolve-schema-type-refs.d.ts +29 -12
- package/dist/resolve-schema-type-refs.d.ts.map +1 -1
- package/dist/resolve-schema-type-refs.js +89 -16
- package/dist/schema-compat.d.ts +35 -9
- package/dist/schema-compat.d.ts.map +1 -1
- package/dist/schema-compat.js +181 -54
- package/dist/schema-region.d.ts +33 -0
- package/dist/schema-region.d.ts.map +1 -0
- package/dist/schema-region.js +45 -0
- package/dist/types.d.ts +51 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +6 -0
- package/dist/validate-cel-context.d.ts.map +1 -1
- package/dist/validate-cel-context.js +29 -3
- package/dist/validate-include-placement.d.ts +26 -0
- package/dist/validate-include-placement.d.ts.map +1 -0
- package/dist/validate-include-placement.js +67 -0
- package/dist/validate-step-inputs.d.ts +8 -1
- package/dist/validate-step-inputs.d.ts.map +1 -1
- package/dist/validate-step-inputs.js +47 -2
- package/dist/validate-throws-coverage.d.ts.map +1 -1
- package/dist/validate-throws-coverage.js +15 -12
- package/dist/validate-value-type-slots.d.ts +43 -0
- package/dist/validate-value-type-slots.d.ts.map +1 -0
- package/dist/validate-value-type-slots.js +142 -0
- package/dist/value-type-keyword.d.ts +60 -0
- package/dist/value-type-keyword.d.ts.map +1 -0
- package/dist/value-type-keyword.js +119 -0
- package/dist/yaml-source-edit.d.ts +56 -0
- package/dist/yaml-source-edit.d.ts.map +1 -0
- package/dist/yaml-source-edit.js +93 -0
- package/package.json +4 -3
- package/src/analyzer.ts +276 -129
- package/src/cel-environment.ts +6 -3
- package/src/definition-registry.ts +10 -0
- package/src/index.ts +31 -3
- package/src/invocation-contract.ts +43 -48
- package/src/loaded-types.ts +13 -0
- package/src/manifest-loader.ts +37 -6
- package/src/manifest-visitor.ts +11 -3
- package/src/migrations/driver.ts +262 -0
- package/src/migrations/entries/index.ts +10 -0
- package/src/migrations/entries/normalize-value-types.json +48 -0
- package/src/migrations/entries/ref-slot-scalar-type.json +20 -0
- package/src/migrations/entry-data.ts +207 -0
- package/src/migrations/index.ts +22 -0
- package/src/migrations/match.ts +382 -0
- package/src/migrations/patch.ts +265 -0
- package/src/migrations/provenance.ts +167 -0
- package/src/migrations/registry.ts +40 -0
- package/src/migrations/report.ts +169 -0
- package/src/migrations/types.ts +144 -0
- package/src/migrations/yaml-edit.ts +260 -0
- package/src/module-file-claims.ts +168 -0
- package/src/parse-loaded-file.ts +31 -12
- package/src/resolve-schema-type-refs.ts +93 -16
- package/src/schema-compat.ts +218 -62
- package/src/schema-region.ts +46 -0
- package/src/types.ts +54 -0
- package/src/validate-cel-context.ts +36 -3
- package/src/validate-include-placement.ts +70 -0
- package/src/validate-step-inputs.ts +56 -1
- package/src/validate-throws-coverage.ts +16 -11
- package/src/validate-value-type-slots.ts +182 -0
- package/src/value-type-keyword.ts +135 -0
- package/src/yaml-source-edit.ts +106 -0
- package/dist/binary-slot.d.ts +0 -39
- package/dist/binary-slot.d.ts.map +0 -1
- package/dist/binary-slot.js +0 -58
- package/src/binary-slot.ts +0 -71
package/dist/analyzer.d.ts
CHANGED
|
@@ -40,6 +40,11 @@ export declare function gatherPropertySchemas(schema: Record<string, any>): Arra
|
|
|
40
40
|
* hardcoded; recursion is driven entirely by the schema annotations.
|
|
41
41
|
*/
|
|
42
42
|
export declare function walkStepArray(steps: unknown[], stepItemSchema: Record<string, any> | undefined, rootSchema: Record<string, any>, basePath: string, visit: (step: Record<string, any>, stepPath: string) => void): void;
|
|
43
|
+
/** A pure-CEL leaf and the schema of the field it sits in. */
|
|
44
|
+
export interface CelValueSlot {
|
|
45
|
+
readonly path: string;
|
|
46
|
+
readonly schema: Record<string, any>;
|
|
47
|
+
}
|
|
43
48
|
export interface StaticAnalyzerOptions {
|
|
44
49
|
celHandlers?: CelHandlers;
|
|
45
50
|
}
|
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;
|
|
1
|
+
{"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"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"}
|
package/dist/analyzer.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { canonicalTypeSchemaId, OBSERVED_STATE_KEY } from "@telorun/sdk";
|
|
2
|
-
import { defaultRegistry, isRefSentinel, isTaggedSentinel } from "@telorun/templating";
|
|
2
|
+
import { defaultRegistry, isRefSentinel, isTaggedSentinel, plainChainOf, } from "@telorun/templating";
|
|
3
3
|
import { AliasResolver, moduleScopedDefResolver, scopeResolverForModule, } from "./alias-resolver.js";
|
|
4
4
|
import { buildCelEnvironment, buildImportInputCelEnvironment, buildTypedCelEnvironment, } from "./cel-environment.js";
|
|
5
5
|
import { DefinitionRegistry } from "./definition-registry.js";
|
|
@@ -19,18 +19,20 @@ import { resolveSchemaRefKinds } from "./resolve-schema-ref-kinds.js";
|
|
|
19
19
|
import { runZoneAnalysis } from "./resolve-zone-requirements.js";
|
|
20
20
|
import { validateZoneSlotDeclarations } from "./validate-zone-slots.js";
|
|
21
21
|
import { validateDynamicSelectors, validateRefSlotDeclarations, } from "./validate-ref-slots.js";
|
|
22
|
+
import { validateValueTypeSlots, } from "./validate-value-type-slots.js";
|
|
22
23
|
import { resolveSchemaTypeRefs } from "./resolve-schema-type-refs.js";
|
|
23
24
|
import { validateSchemaTypeRefs } from "./validate-schema-type-refs.js";
|
|
24
25
|
import { rewriteSyntheticOrigins } from "./rewrite-synthetic-origins.js";
|
|
25
|
-
import { celTypeSatisfiesJsonSchema, substituteCelFields, validateAgainstSchema, } from "./schema-compat.js";
|
|
26
|
+
import { celTypeSatisfiesJsonSchema, checkSchemaCompatibility, navigateSchemaToExprPath, substituteCelFields, validateAgainstSchema, } from "./schema-compat.js";
|
|
26
27
|
import { collectValueSchemaIssues } from "./validate-value-schema.js";
|
|
27
28
|
import { DiagnosticSeverity } from "./types.js";
|
|
28
|
-
import { extractAccessChains, extractCelRegionScopes,
|
|
29
|
+
import { extractAccessChains, extractCelRegionScopes, getManifestItem, pathMatchesScope, resolveContextAnnotations, resolveTypeFieldToSchema, } from "./validate-cel-context.js";
|
|
29
30
|
import { buildEvalPaths, evalPathsCover } from "./eval-paths.js";
|
|
30
31
|
import { BINDINGS_ANNOTATION, bindingContextProperties, bindingPathChain, CEL_RESERVED_WORDS, findBindingSites, resolveBindingOrder, schemaAtChain, } from "./cel-bindings.js";
|
|
31
32
|
import { validateExtends } from "./validate-extends.js";
|
|
32
33
|
import { validateLogging } from "./validate-logging.js";
|
|
33
34
|
import { validateModuleArtifact } from "./validate-module-artifact.js";
|
|
35
|
+
import { validateIncludePlacement } from "./validate-include-placement.js";
|
|
34
36
|
import { validateModuleMetadata } from "./validate-module-metadata.js";
|
|
35
37
|
import { validateBaseMapping } from "./validate-base-mapping.js";
|
|
36
38
|
import { validateInvocationContract } from "./validate-invocation-contract.js";
|
|
@@ -735,68 +737,49 @@ function celAccessChains(env, expr) {
|
|
|
735
737
|
}
|
|
736
738
|
const CEL_PURE_RE = /^\s*\$\{\{[^}]*\}\}\s*$/;
|
|
737
739
|
const CEL_EXPR_RE = /\$\{\{\s*([^}]+?)\s*\}\}/;
|
|
738
|
-
/**
|
|
739
|
-
*
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
740
|
+
/** Restore the delimiters an engine's fix was computed without, so the
|
|
741
|
+
* replacement is the whole scalar rather than a bare expression that would be
|
|
742
|
+
* read back as literal text. A tagged scalar carries no wrapper and passes
|
|
743
|
+
* through untouched. */
|
|
744
|
+
function rewrapFix(fix, wrapper) {
|
|
745
|
+
if (!fix || !wrapper)
|
|
746
|
+
return fix;
|
|
747
|
+
return { replacement: wrapper.prefix + fix.replacement + wrapper.suffix };
|
|
748
|
+
}
|
|
749
|
+
/** Recursively walk `data`+`schema` together, collecting every pure CEL leaf
|
|
750
|
+
* with the schema of the field holding it.
|
|
751
|
+
*
|
|
752
|
+
* Type *checking* is deliberately not done here. It belongs to the templating
|
|
753
|
+
* engine, which owns the expression's syntax and now runs it once against the
|
|
754
|
+
* environment typed for that path; checking again here would mean two verdicts
|
|
755
|
+
* from two environments about one expression — which is exactly how an opaque
|
|
756
|
+
* "no matching overload" used to survive next to the diagnostic that explained
|
|
757
|
+
* it. What this walk supplies is the half the engine cannot know: the declared
|
|
758
|
+
* type of the slot the value flows into. The comparison happens once both are
|
|
759
|
+
* in hand (`reportCelReturnMismatches`). */
|
|
760
|
+
function collectCelValueSlots(data, schema, path) {
|
|
761
|
+
const slots = [];
|
|
762
|
+
// A pure CEL value behaves the same regardless of surface form: a
|
|
763
|
+
// `${{ … }}` string and a `!cel`-tagged sentinel are the same expression.
|
|
744
764
|
let celExpr;
|
|
745
765
|
if (isTaggedSentinel(data)) {
|
|
746
766
|
// Non-CEL engines (e.g. `!literal`) are analyzed by their own engine pass.
|
|
747
767
|
if (data.engine !== "cel")
|
|
748
|
-
return
|
|
768
|
+
return slots;
|
|
749
769
|
celExpr = data.source;
|
|
750
770
|
}
|
|
751
771
|
else if (typeof data === "string" && CEL_PURE_RE.test(data)) {
|
|
752
772
|
celExpr = data.match(CEL_EXPR_RE)?.[1]?.trim();
|
|
753
773
|
}
|
|
754
774
|
if (celExpr !== undefined) {
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
let typedEnv = baseTypedEnv;
|
|
759
|
-
if (definition.schema) {
|
|
760
|
-
for (const ctx of extractContextsFromSchema(definition.schema)) {
|
|
761
|
-
if (!pathMatchesScope(path, ctx.scope))
|
|
762
|
-
continue;
|
|
763
|
-
typedEnv = buildTypedCelEnvironment(rootEnv, manifest, ctx.schema, rootModuleManifest);
|
|
764
|
-
break;
|
|
765
|
-
}
|
|
766
|
-
}
|
|
767
|
-
let checkResult;
|
|
768
|
-
try {
|
|
769
|
-
checkResult = typedEnv.check(expr);
|
|
770
|
-
}
|
|
771
|
-
catch {
|
|
772
|
-
/* degrade gracefully */
|
|
773
|
-
}
|
|
774
|
-
if (checkResult?.valid === false && checkResult.error) {
|
|
775
|
-
// env.check() rejected the expression itself — e.g. wrong method, wrong
|
|
776
|
-
// argument types, wrong operator overload. Surface the first line of the
|
|
777
|
-
// error message; the tail is a source-code caret diagram we don't need.
|
|
778
|
-
const message = String(checkResult.error.message ?? checkResult.error)
|
|
779
|
-
.split("\n")[0]
|
|
780
|
-
.trim();
|
|
781
|
-
issues.push({ message: `CEL type error: ${message}`, path });
|
|
782
|
-
}
|
|
783
|
-
else if (checkResult?.valid && checkResult.type && schema) {
|
|
784
|
-
const celType = checkResult.type.split("<")[0];
|
|
785
|
-
if (!celTypeSatisfiesJsonSchema(celType, schema)) {
|
|
786
|
-
const expected = schema["x-telo-type"] ?? schema.type ?? "unknown";
|
|
787
|
-
issues.push({
|
|
788
|
-
message: `CEL returns '${checkResult.type}' but field expects '${expected}'`,
|
|
789
|
-
path,
|
|
790
|
-
});
|
|
791
|
-
}
|
|
792
|
-
}
|
|
793
|
-
}
|
|
794
|
-
return issues;
|
|
775
|
+
if (schema)
|
|
776
|
+
slots.push({ path, schema });
|
|
777
|
+
return slots;
|
|
795
778
|
}
|
|
796
779
|
if (Array.isArray(data)) {
|
|
797
780
|
const itemSchema = (schema.items ?? {});
|
|
798
781
|
for (let i = 0; i < data.length; i++) {
|
|
799
|
-
|
|
782
|
+
slots.push(...collectCelValueSlots(data[i], itemSchema, `${path}[${i}]`));
|
|
800
783
|
}
|
|
801
784
|
}
|
|
802
785
|
else if (data !== null && typeof data === "object") {
|
|
@@ -805,10 +788,10 @@ function collectCelTypeIssues(data, schema, path, definition, manifest, baseType
|
|
|
805
788
|
? schema.additionalProperties
|
|
806
789
|
: {};
|
|
807
790
|
for (const [k, v] of Object.entries(data)) {
|
|
808
|
-
|
|
791
|
+
slots.push(...collectCelValueSlots(v, (props[k] ?? mapValueSchema), path ? `${path}.${k}` : k));
|
|
809
792
|
}
|
|
810
793
|
}
|
|
811
|
-
return
|
|
794
|
+
return slots;
|
|
812
795
|
}
|
|
813
796
|
export class StaticAnalyzer {
|
|
814
797
|
celEnv;
|
|
@@ -1001,6 +984,18 @@ export class StaticAnalyzer {
|
|
|
1001
984
|
const refConstraintIssues = [];
|
|
1002
985
|
const refSlotIssues = [];
|
|
1003
986
|
const zoneSlotIssues = [];
|
|
987
|
+
// `x-telo-type` is checked on EVERY manifest, not only on definition docs: a
|
|
988
|
+
// schema fragment is written wherever a kind declares a schema-valued field,
|
|
989
|
+
// so an inline `inputType:` on an ordinary resource carries one just as a
|
|
990
|
+
// definition's `schema:` does. Same scoping as every other schema issue —
|
|
991
|
+
// the entry's own modules, since a dependency is not the consumer's to fix.
|
|
992
|
+
const valueTypeSlotIssues = [];
|
|
993
|
+
for (const m of manifests) {
|
|
994
|
+
const declaringModule = m.metadata?.module;
|
|
995
|
+
if (!declaringModule || rootModules.has(declaringModule)) {
|
|
996
|
+
valueTypeSlotIssues.push(...validateValueTypeSlots(m));
|
|
997
|
+
}
|
|
998
|
+
}
|
|
1004
999
|
for (const m of manifests) {
|
|
1005
1000
|
if (m.kind !== "Telo.Definition" && m.kind !== "Telo.Abstract")
|
|
1006
1001
|
continue;
|
|
@@ -1135,6 +1130,26 @@ export class StaticAnalyzer {
|
|
|
1135
1130
|
// mid-migration, and this reports what leniency would silently absorb.
|
|
1136
1131
|
for (const issue of refSlotIssues)
|
|
1137
1132
|
diagnostics.push(refSlotIssueDiagnostic(issue));
|
|
1133
|
+
// The same split for `x-telo-type`. Its reader returns a slot with no
|
|
1134
|
+
// entry for a name it does not know, which is what an unrecognized brand
|
|
1135
|
+
// used to do SILENTLY — the slot simply lost its identity.
|
|
1136
|
+
for (const issue of valueTypeSlotIssues) {
|
|
1137
|
+
diagnostics.push({
|
|
1138
|
+
severity: DiagnosticSeverity.Error,
|
|
1139
|
+
code: issue.code,
|
|
1140
|
+
source: SOURCE,
|
|
1141
|
+
message: issue.message,
|
|
1142
|
+
data: {
|
|
1143
|
+
resource: {
|
|
1144
|
+
kind: issue.manifest.kind,
|
|
1145
|
+
name: issue.manifest.metadata?.name,
|
|
1146
|
+
},
|
|
1147
|
+
filePath: issue.manifest.metadata?.source,
|
|
1148
|
+
path: issue.path,
|
|
1149
|
+
...(issue.fix ? { fix: issue.fix } : {}),
|
|
1150
|
+
},
|
|
1151
|
+
});
|
|
1152
|
+
}
|
|
1138
1153
|
// Same split for the two zone annotations. Unreadable ones fail in
|
|
1139
1154
|
// OPPOSITE directions — a dropped requirement is silently unenforced, a
|
|
1140
1155
|
// dropped provision invents failures — so neither can be left to
|
|
@@ -1251,6 +1266,9 @@ export class StaticAnalyzer {
|
|
|
1251
1266
|
// these fields, which is precisely why they need a check: a mistyped one
|
|
1252
1267
|
// has no runtime failure mode that would ever surface it.
|
|
1253
1268
|
diagnostics.push(...validateModuleMetadata(allManifests, defs, aliases));
|
|
1269
|
+
// A file embed resolves at resource creation, so one written on a doc that
|
|
1270
|
+
// is never instantiated is read by nothing and would ship silently.
|
|
1271
|
+
diagnostics.push(...validateIncludePlacement(allManifests));
|
|
1254
1272
|
}
|
|
1255
1273
|
resolveSchemaTypeRefs(allManifests, aliases, aliasesByModule);
|
|
1256
1274
|
// Trusted-input fast path: when the caller has already attested that
|
|
@@ -1381,6 +1399,19 @@ export class StaticAnalyzer {
|
|
|
1381
1399
|
// the entry's; see `buildKernelGlobalsSchema`.
|
|
1382
1400
|
const moduleManifest = allManifests.find((mm) => mm.kind === "Telo.Application") ??
|
|
1383
1401
|
allManifests.find((mm) => mm.kind === "Telo.Library");
|
|
1402
|
+
// Every pure-CEL leaf, with the slot it flows into. Compared against the
|
|
1403
|
+
// type the engine walk resolves, once both halves exist — see
|
|
1404
|
+
// `collectCelValueSlots`.
|
|
1405
|
+
const celReturnSlots = [];
|
|
1406
|
+
const celTypeByPath = new Map();
|
|
1407
|
+
// The schema an expression RESOLVES TO, beside the CEL type it carries. Both
|
|
1408
|
+
// are needed and neither replaces the other: the CEL type answers "does this
|
|
1409
|
+
// fit the slot at all", the schema answers "do their type arguments agree",
|
|
1410
|
+
// which cel-js cannot express because it types by constructor identity.
|
|
1411
|
+
const celSourceSchemaByPath = new Map();
|
|
1412
|
+
// Context-free typed environments, one per manifest. Reused across every
|
|
1413
|
+
// expression in it — see the build site for why a matched context opts out.
|
|
1414
|
+
const typedEnvByManifest = new Map();
|
|
1384
1415
|
// Validate each non-definition, non-system resource
|
|
1385
1416
|
for (const m of allManifests) {
|
|
1386
1417
|
const filePath = m.metadata?.source;
|
|
@@ -1458,7 +1489,15 @@ export class StaticAnalyzer {
|
|
|
1458
1489
|
code: "UNDEFINED_KIND",
|
|
1459
1490
|
source: SOURCE,
|
|
1460
1491
|
message: `No Telo.Definition found for kind '${m.kind}'.${hint}`,
|
|
1461
|
-
|
|
1492
|
+
// `suggestedKind` is kept beside the generic `fix` because it names
|
|
1493
|
+
// what the replacement IS; the fix is how to apply it.
|
|
1494
|
+
data: {
|
|
1495
|
+
resource,
|
|
1496
|
+
filePath,
|
|
1497
|
+
path: "kind",
|
|
1498
|
+
suggestedKind,
|
|
1499
|
+
...(suggestedKind ? { fix: { replacement: suggestedKind } } : {}),
|
|
1500
|
+
},
|
|
1462
1501
|
});
|
|
1463
1502
|
continue;
|
|
1464
1503
|
}
|
|
@@ -1481,23 +1520,12 @@ export class StaticAnalyzer {
|
|
|
1481
1520
|
},
|
|
1482
1521
|
}
|
|
1483
1522
|
: authorSchema;
|
|
1484
|
-
// Phase 1: CEL
|
|
1485
|
-
//
|
|
1486
|
-
//
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
// importer is undefined here and variables/secrets fall back to a permissive `map`
|
|
1491
|
-
// (no false positives) while resources/env stay rejected.
|
|
1492
|
-
const importerModule = m.kind === "Telo.Import"
|
|
1493
|
-
? allManifests.find((mm) => (mm.kind === "Telo.Application" || mm.kind === "Telo.Library") &&
|
|
1494
|
-
mm.metadata?.name ===
|
|
1495
|
-
m.metadata?.module)
|
|
1496
|
-
: undefined;
|
|
1497
|
-
const baseTypedEnv = m.kind === "Telo.Import"
|
|
1498
|
-
? buildImportInputCelEnvironment(this.celEnv, importerModule)
|
|
1499
|
-
: buildTypedCelEnvironment(this.celEnv, m, undefined, moduleManifest);
|
|
1500
|
-
const celIssues = collectCelTypeIssues(m, schema, "", definition, m, baseTypedEnv, this.celEnv, moduleManifest);
|
|
1523
|
+
// Phase 1: collect the pure-CEL leaves and the schema of the slot each
|
|
1524
|
+
// flows into. The expression's own type is resolved later, by the
|
|
1525
|
+
// engine walk that owns type-checking; this half only knows the target.
|
|
1526
|
+
for (const slot of collectCelValueSlots(m, schema, "")) {
|
|
1527
|
+
celReturnSlots.push({ manifest: m, resource, filePath, ...slot });
|
|
1528
|
+
}
|
|
1501
1529
|
// Phase 2+3: AJV on substituted data — CEL fields replaced with typed placeholders
|
|
1502
1530
|
const ajvIssues = validateAgainstSchema(substituteCelFields(m, schema), schema);
|
|
1503
1531
|
// Phase 4: value slots that must satisfy a type declared elsewhere on
|
|
@@ -1505,7 +1533,7 @@ export class StaticAnalyzer {
|
|
|
1505
1533
|
// decision table against its declared `outputType`, so a mistyped branch
|
|
1506
1534
|
// is caught here rather than on the one input that selects it.
|
|
1507
1535
|
const valueSchemaIssues = collectValueSchemaIssues(m, schema, allManifests);
|
|
1508
|
-
const issues = [...
|
|
1536
|
+
const issues = [...ajvIssues, ...valueSchemaIssues];
|
|
1509
1537
|
for (const issue of issues) {
|
|
1510
1538
|
diagnostics.push({
|
|
1511
1539
|
severity: DiagnosticSeverity.Error,
|
|
@@ -1648,12 +1676,14 @@ export class StaticAnalyzer {
|
|
|
1648
1676
|
if (e.definition?.schema) {
|
|
1649
1677
|
const stepName = m.metadata?.name;
|
|
1650
1678
|
const stepFile = m.metadata?.source;
|
|
1651
|
-
for (const issue of collectStepInputIssues(m, e.definition.schema, allManifests, defs, aliases, { aliasesByModule, rootModules })) {
|
|
1679
|
+
for (const issue of collectStepInputIssues(m, e.definition.schema, allManifests, defs, aliases, { aliasesByModule, rootModules }, celStepContextSchema)) {
|
|
1652
1680
|
diagnostics.push({
|
|
1653
1681
|
severity: DiagnosticSeverity.Error,
|
|
1654
|
-
code: "CONTRACT_INPUTS_MISMATCH",
|
|
1682
|
+
code: issue.code ?? "CONTRACT_INPUTS_MISMATCH",
|
|
1655
1683
|
source: SOURCE,
|
|
1656
|
-
message:
|
|
1684
|
+
message: issue.code
|
|
1685
|
+
? `${m.kind}/${stepName}: inputs at '${issue.path}' flow into ${issue.targetLabel} with disagreeing type arguments: ${issue.message}`
|
|
1686
|
+
: `${m.kind}/${stepName}: inputs at '${issue.path}' do not satisfy ${issue.targetLabel}'s declared inputType: ${issue.message}`,
|
|
1657
1687
|
data: {
|
|
1658
1688
|
resource: { kind: m.kind, name: stepName ?? "" },
|
|
1659
1689
|
filePath: stepFile,
|
|
@@ -1876,50 +1906,158 @@ export class StaticAnalyzer {
|
|
|
1876
1906
|
});
|
|
1877
1907
|
return;
|
|
1878
1908
|
}
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1909
|
+
// The engine type-checks, so it gets the environment typed for THIS
|
|
1910
|
+
// path — not the bare base one. A `Telo.Import`'s variables/secrets
|
|
1911
|
+
// are a config-only contract evaluated in the IMPORTING module's
|
|
1912
|
+
// scope, so they type from the owning module doc and drop
|
|
1913
|
+
// `resources`/`env`, making a reference to either an error.
|
|
1914
|
+
//
|
|
1915
|
+
// Cached per manifest when no `x-telo-context` applied, which is most
|
|
1916
|
+
// expressions: the environment then depends only on the manifest, so
|
|
1917
|
+
// rebuilding it per expression is pure waste — a clone plus a
|
|
1918
|
+
// re-registration of every variable, on every keystroke in the IDE.
|
|
1919
|
+
// A matched context makes the environment path-specific (its schema is
|
|
1920
|
+
// resolved against the enclosing array item), so those still build
|
|
1921
|
+
// fresh rather than risk one item's types leaking into another's.
|
|
1922
|
+
const cached = effectiveContext === null ? typedEnvByManifest.get(m) : undefined;
|
|
1923
|
+
const typedEnv = cached ??
|
|
1924
|
+
(m.kind === "Telo.Import"
|
|
1925
|
+
? buildImportInputCelEnvironment(this.celEnv, allManifests.find((mm) => (mm.kind === "Telo.Application" || mm.kind === "Telo.Library") &&
|
|
1926
|
+
mm.metadata?.name ===
|
|
1927
|
+
m.metadata?.module))
|
|
1928
|
+
: buildTypedCelEnvironment(this.celEnv, m, effectiveContext ?? undefined, moduleManifest));
|
|
1929
|
+
if (effectiveContext === null && !cached)
|
|
1930
|
+
typedEnvByManifest.set(m, typedEnv);
|
|
1931
|
+
const result = engine.analyze(expr, { celEnv: typedEnv, contextSchema: effectiveContext });
|
|
1932
|
+
if (result.type !== undefined) {
|
|
1933
|
+
let byPath = celTypeByPath.get(m);
|
|
1934
|
+
if (!byPath)
|
|
1935
|
+
celTypeByPath.set(m, (byPath = new Map()));
|
|
1936
|
+
byPath.set(path, result.type);
|
|
1937
|
+
}
|
|
1938
|
+
// The producer half of the type-argument check. A CEL type is a bare
|
|
1939
|
+
// name — cel-js types by constructor identity, so a byte stream and a
|
|
1940
|
+
// string stream are one CEL type and always will be — so the argument
|
|
1941
|
+
// comparison is a parallel pass over the SCHEMAS the analyzer already
|
|
1942
|
+
// walks. This is where the producer's schema is in hand: navigating
|
|
1943
|
+
// the expression's chain into its context schema is exactly "the
|
|
1944
|
+
// producer's outputType at the expression's tail".
|
|
1945
|
+
//
|
|
1946
|
+
// Only a PLAIN CHAIN is navigated — `steps.encode.result.output`, the
|
|
1947
|
+
// shape a wiring site actually takes. An expression that computes
|
|
1948
|
+
// rather than names has no schema to read off the context, so it
|
|
1949
|
+
// records nothing and no argument check fires: silence where the
|
|
1950
|
+
// analyzer knows least is the conservative direction, and the same one
|
|
1951
|
+
// `x-telo-step-context`'s pure-`value` typing takes.
|
|
1952
|
+
const chain = effectiveContext ? plainChainOf(`\${{${expr}}}`) : undefined;
|
|
1953
|
+
if (chain) {
|
|
1954
|
+
const produced = navigateSchemaToExprPath(effectiveContext, chain);
|
|
1955
|
+
if (produced) {
|
|
1956
|
+
let byPath = celSourceSchemaByPath.get(m);
|
|
1957
|
+
if (!byPath)
|
|
1958
|
+
celSourceSchemaByPath.set(m, (byPath = new Map()));
|
|
1959
|
+
byPath.set(path, produced);
|
|
1960
|
+
}
|
|
1961
|
+
}
|
|
1962
|
+
// A non-deterministic call in a compile-eval field is baked once at
|
|
1963
|
+
// load: `nowIso()` there freezes at boot. Sometimes that is the
|
|
1964
|
+
// intent (a boot timestamp, a run id), so it warns rather than
|
|
1965
|
+
// blocking. The engine reports which calls re-evaluate; the eval mode
|
|
1966
|
+
// is manifest policy and stays here.
|
|
1967
|
+
if (celRuleApplies && evalPathsCover(celCompilePaths, path)) {
|
|
1968
|
+
const volatile = [
|
|
1969
|
+
...new Set(result.calls.filter((c) => c.deterministic === false).map((c) => c.name)),
|
|
1970
|
+
].sort();
|
|
1971
|
+
if (volatile.length > 0) {
|
|
1882
1972
|
diagnostics.push({
|
|
1883
|
-
severity: DiagnosticSeverity.
|
|
1884
|
-
code: "
|
|
1973
|
+
severity: DiagnosticSeverity.Warning,
|
|
1974
|
+
code: "CEL_NONDETERMINISTIC_IN_COMPILE_FIELD",
|
|
1885
1975
|
source: SOURCE,
|
|
1886
|
-
message:
|
|
1976
|
+
message: `${m.kind}/${resource.name}: '${path}' is evaluated once at startup, so ${volatile.map((n) => `\`${n}()\``).join(", ")} ${volatile.length === 1 ? "is" : "are"} baked in at load and never re-evaluated. Move the expression to a field evaluated per call (x-telo-eval: runtime) if it should change over time.`,
|
|
1887
1977
|
data: { resource, filePath, path },
|
|
1888
1978
|
});
|
|
1889
1979
|
}
|
|
1890
|
-
|
|
1980
|
+
}
|
|
1981
|
+
for (const f of result.diagnostics) {
|
|
1982
|
+
// A repair is applicable only when the analyzed expression covers
|
|
1983
|
+
// the whole scalar. For one `${{ }}` among literal text, replacing
|
|
1984
|
+
// the node would drop the text around it, so the correction stays
|
|
1985
|
+
// in the message and no fix is stamped.
|
|
1986
|
+
const fix = e.surface.whole ? rewrapFix(f.fix, e.surface.wrapper) : undefined;
|
|
1987
|
+
const data = { resource, filePath, path, ...(fix ? { fix } : {}) };
|
|
1988
|
+
if (f.code === "CEL_SYNTAX_ERROR") {
|
|
1891
1989
|
diagnostics.push({
|
|
1892
1990
|
severity: DiagnosticSeverity.Error,
|
|
1893
|
-
code: "
|
|
1991
|
+
code: "CEL_SYNTAX_ERROR",
|
|
1894
1992
|
source: SOURCE,
|
|
1895
|
-
message:
|
|
1896
|
-
data
|
|
1993
|
+
message: `CEL syntax error at ${path}: ${f.message}`,
|
|
1994
|
+
data,
|
|
1897
1995
|
});
|
|
1898
1996
|
}
|
|
1899
|
-
else if (f.code ===
|
|
1997
|
+
else if (f.code === undefined) {
|
|
1998
|
+
// No code from a future engine — pass the message through, tagged
|
|
1999
|
+
// with a generic ENGINE_DIAGNOSTIC code so downstream filters can
|
|
2000
|
+
// still bucket it.
|
|
1900
2001
|
diagnostics.push({
|
|
1901
2002
|
severity: DiagnosticSeverity.Error,
|
|
1902
|
-
code: "
|
|
2003
|
+
code: "ENGINE_DIAGNOSTIC",
|
|
1903
2004
|
source: SOURCE,
|
|
1904
|
-
message: `${m.kind}/${resource.name}:
|
|
1905
|
-
data
|
|
2005
|
+
message: `${m.kind}/${resource.name}: !${engineName} at '${path}': ${f.message}`,
|
|
2006
|
+
data,
|
|
1906
2007
|
});
|
|
1907
2008
|
}
|
|
1908
2009
|
else {
|
|
1909
|
-
//
|
|
1910
|
-
//
|
|
1911
|
-
//
|
|
2010
|
+
// Named by ENGINE, not hardcoded to CEL: the seam exists so a
|
|
2011
|
+
// second engine can produce coded findings, and labelling them
|
|
2012
|
+
// `CEL` would misattribute the first one that does.
|
|
1912
2013
|
diagnostics.push({
|
|
1913
2014
|
severity: DiagnosticSeverity.Error,
|
|
1914
|
-
code: f.code
|
|
2015
|
+
code: f.code,
|
|
1915
2016
|
source: SOURCE,
|
|
1916
2017
|
message: `${m.kind}/${resource.name}: !${engineName} at '${path}': ${f.message}`,
|
|
1917
|
-
data
|
|
2018
|
+
data,
|
|
1918
2019
|
});
|
|
1919
2020
|
}
|
|
1920
2021
|
}
|
|
1921
2022
|
},
|
|
1922
2023
|
}, { aliases });
|
|
2024
|
+
// The two halves of "does this expression fit the slot it flows into" meet
|
|
2025
|
+
// here: the engine resolved the expression's type during the walk above,
|
|
2026
|
+
// and the schema walk recorded the slot. An expression that failed to check
|
|
2027
|
+
// recorded no type and is already reported by its own diagnostic.
|
|
2028
|
+
for (const slot of celReturnSlots) {
|
|
2029
|
+
const type = celTypeByPath.get(slot.manifest)?.get(slot.path);
|
|
2030
|
+
if (type === undefined)
|
|
2031
|
+
continue;
|
|
2032
|
+
if (!celTypeSatisfiesJsonSchema(type.split("<")[0], slot.schema)) {
|
|
2033
|
+
const expected = slot.schema["x-telo-type"] ?? slot.schema.type ?? "unknown";
|
|
2034
|
+
diagnostics.push({
|
|
2035
|
+
severity: DiagnosticSeverity.Error,
|
|
2036
|
+
code: "CEL_TYPE_ERROR",
|
|
2037
|
+
source: SOURCE,
|
|
2038
|
+
message: `${slot.resource.kind}/${slot.resource.name}: CEL at '${slot.path}' returns '${type}' but the field expects '${expected}'.`,
|
|
2039
|
+
data: { resource: slot.resource, filePath: slot.filePath, path: slot.path },
|
|
2040
|
+
});
|
|
2041
|
+
continue;
|
|
2042
|
+
}
|
|
2043
|
+
// The type fits; do its ARGUMENTS agree? Covariant and gradual — an
|
|
2044
|
+
// omitted argument is *any* in both directions, so an unmigrated producer
|
|
2045
|
+
// or consumer is never reported, and only a definite conflict is.
|
|
2046
|
+
const produced = celSourceSchemaByPath.get(slot.manifest)?.get(slot.path);
|
|
2047
|
+
if (!produced)
|
|
2048
|
+
continue;
|
|
2049
|
+
const { compatible, issues } = checkSchemaCompatibility(produced, slot.schema, (ref) => defs.schemaForId(ref));
|
|
2050
|
+
if (compatible)
|
|
2051
|
+
continue;
|
|
2052
|
+
diagnostics.push({
|
|
2053
|
+
severity: DiagnosticSeverity.Error,
|
|
2054
|
+
code: "CEL_TYPE_ARGUMENT_MISMATCH",
|
|
2055
|
+
source: SOURCE,
|
|
2056
|
+
message: `${slot.resource.kind}/${slot.resource.name}: CEL at '${slot.path}' produces a value ` +
|
|
2057
|
+
`whose type arguments disagree with the field's: ${issues.join("; ")}.`,
|
|
2058
|
+
data: { resource: slot.resource, filePath: slot.filePath, path: slot.path },
|
|
2059
|
+
});
|
|
2060
|
+
}
|
|
1923
2061
|
// Validate resource references (Phase 3)
|
|
1924
2062
|
diagnostics.push(...validateReferences(allManifests, { aliases, definitions: defs, aliasesByModule }));
|
|
1925
2063
|
// Validate step `invoke` references — the slots the reference field map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cel-environment.d.ts","sourceRoot":"","sources":["../src/cel-environment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"cel-environment.d.ts","sourceRoot":"","sources":["../src/cel-environment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAarD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD;;;;;;;;;uEASuE;AACvE,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,WAAW,EACpB,QAAQ,EAAE,gBAAgB,EAC1B,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,EAI/C,kBAAkB,CAAC,EAAE,gBAAgB,GACpC,WAAW,CAsEb;AAuBD;;;;;;8DAM8D;AAC9D,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,WAAW,EACpB,cAAc,EAAE,gBAAgB,GAAG,SAAS,GAC3C,WAAW,CAwBb"}
|
package/dist/cel-environment.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { jsonSchemaToCelType, VALUE_BRAND_BASE } from "./schema-compat.js";
|
|
2
2
|
/** Transport protocol on a `ports` entry → the nominal CEL brand its resolved
|
|
3
|
-
* value carries. Mirrors the `protocol` enum in the Application schema
|
|
3
|
+
* value carries. Mirrors the `protocol` enum in the Application schema, and
|
|
4
|
+
* names the value types by their canonical `Telo.`-qualified names — the same
|
|
5
|
+
* spelling an author writes at `x-telo-type`, so a branded port and a branded
|
|
6
|
+
* field are comparable by name with nothing in between to translate. */
|
|
4
7
|
const PORT_PROTOCOL_BRAND = {
|
|
5
|
-
tcp: "TcpPort",
|
|
6
|
-
udp: "UdpPort",
|
|
8
|
+
tcp: "Telo.TcpPort",
|
|
9
|
+
udp: "Telo.UdpPort",
|
|
7
10
|
};
|
|
8
11
|
export { buildCelEnvironment } from "@telorun/templating";
|
|
9
12
|
/** Clone `baseEnv` and register typed variable declarations so that
|
|
@@ -55,6 +55,11 @@ export declare class DefinitionRegistry {
|
|
|
55
55
|
/** True when a schema is registered under `id` (a canonical `telo://` type id
|
|
56
56
|
* or a definition `$id`). Used to flag schema `$ref`s that resolve to nothing. */
|
|
57
57
|
hasSchemaId(id: string): boolean;
|
|
58
|
+
/** The schema registered under `id`, for a structural comparison that must see
|
|
59
|
+
* THROUGH a named shape. Declaring a shape once and referencing it is the
|
|
60
|
+
* sanctioned way to reuse one, so a comparator that cannot follow the
|
|
61
|
+
* reference judges two opaque nodes and learns nothing. */
|
|
62
|
+
schemaForId(id: string): Record<string, any> | undefined;
|
|
58
63
|
/** Validates data against a schema using this registry's AJV instance, which has all
|
|
59
64
|
* registered definition schemas loaded — enabling cross-module $ref resolution.
|
|
60
65
|
* A compile failure returns `[]` here; it is surfaced loudly (once, on the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definition-registry.d.ts","sourceRoot":"","sources":["../src/definition-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,OAAO,EAIL,KAAK,iBAAiB,EACvB,MAAM,0BAA0B,CAAC;AAIlC,+EAA+E;AAC/E,qBAAa,kBAAkB;;IAK7B;;sFAEkF;IAClF,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAqB;IACzD;;mFAE+E;IAC/E,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAqB;IAEzD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAyC;IAC9D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAwC;IAClE,mEAAmE;IACnE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA+B;IAC1D;;;;wEAIoE;IACpE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA6B;IAEzD,QAAQ,CAAC,UAAU,EAAE,kBAAkB,GAAG,IAAI;IAoC9C,OAAO,CAAC,aAAa;IASrB;;;;;;;;;;;;;2FAauF;IACvF,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;IAK1E;;;;;;;;;;gFAU4E;IAC5E,uBAAuB,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO;IAQzE;uFACmF;IACnF,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAIhC;;;;oFAIgF;IAChF,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,EAAE;IAWtE;;;;;;iCAM6B;IAC7B,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,GAAG,SAAS;IASnE;;;;4EAIwE;IACxE,OAAO,CAAC,iBAAiB;IAkBzB;;;;;;;;;;;;;;4BAcwB;IACxB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAShD,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAIrD;;;uCAGmC;IACnC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS;IAWxD,gGAAgG;IAChG,kBAAkB,CAChB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;QAAE,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;KAAE,GACvD,iBAAiB,GAAG,SAAS;IAOhC;;;;;;;;qFAQiF;IACjF,2BAA2B,CACzB,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,EAAE,aAAa,EACtB,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,GAC1C,iBAAiB,GAAG,SAAS;IAkChC,OAAO,CAAC,uBAAuB;IA+B/B;;qEAEiE;IACjE,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,kBAAkB,EAAE;IAgBxD,KAAK,IAAI,MAAM,EAAE;CAGlB"}
|
|
1
|
+
{"version":3,"file":"definition-registry.d.ts","sourceRoot":"","sources":["../src/definition-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,OAAO,EAIL,KAAK,iBAAiB,EACvB,MAAM,0BAA0B,CAAC;AAIlC,+EAA+E;AAC/E,qBAAa,kBAAkB;;IAK7B;;sFAEkF;IAClF,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAqB;IACzD;;mFAE+E;IAC/E,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAqB;IAEzD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAyC;IAC9D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAwC;IAClE,mEAAmE;IACnE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA+B;IAC1D;;;;wEAIoE;IACpE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA6B;IAEzD,QAAQ,CAAC,UAAU,EAAE,kBAAkB,GAAG,IAAI;IAoC9C,OAAO,CAAC,aAAa;IASrB;;;;;;;;;;;;;2FAauF;IACvF,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;IAK1E;;;;;;;;;;gFAU4E;IAC5E,uBAAuB,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO;IAQzE;uFACmF;IACnF,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAIhC;;;gEAG4D;IAC5D,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS;IAMxD;;;;oFAIgF;IAChF,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,EAAE;IAWtE;;;;;;iCAM6B;IAC7B,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,GAAG,SAAS;IASnE;;;;4EAIwE;IACxE,OAAO,CAAC,iBAAiB;IAkBzB;;;;;;;;;;;;;;4BAcwB;IACxB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAShD,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAIrD;;;uCAGmC;IACnC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS;IAWxD,gGAAgG;IAChG,kBAAkB,CAChB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;QAAE,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;KAAE,GACvD,iBAAiB,GAAG,SAAS;IAOhC;;;;;;;;qFAQiF;IACjF,2BAA2B,CACzB,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,EAAE,aAAa,EACtB,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,GAC1C,iBAAiB,GAAG,SAAS;IAkChC,OAAO,CAAC,uBAAuB;IA+B/B;;qEAEiE;IACjE,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,kBAAkB,EAAE;IAgBxD,KAAK,IAAI,MAAM,EAAE;CAGlB"}
|
|
@@ -117,6 +117,15 @@ export class DefinitionRegistry {
|
|
|
117
117
|
hasSchemaId(id) {
|
|
118
118
|
return this.registeredSchemaIds.has(id) || this.ajv.getSchema(id) !== undefined;
|
|
119
119
|
}
|
|
120
|
+
/** The schema registered under `id`, for a structural comparison that must see
|
|
121
|
+
* THROUGH a named shape. Declaring a shape once and referencing it is the
|
|
122
|
+
* sanctioned way to reuse one, so a comparator that cannot follow the
|
|
123
|
+
* reference judges two opaque nodes and learns nothing. */
|
|
124
|
+
schemaForId(id) {
|
|
125
|
+
const compiled = this.ajv.getSchema(id);
|
|
126
|
+
const schema = compiled?.schema;
|
|
127
|
+
return schema && typeof schema === "object" ? schema : undefined;
|
|
128
|
+
}
|
|
120
129
|
/** Validates data against a schema using this registry's AJV instance, which has all
|
|
121
130
|
* registered definition schemas loaded — enabling cross-module $ref resolution.
|
|
122
131
|
* A compile failure returns `[]` here; it is surfaced loudly (once, on the
|
package/dist/index.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ export { moduleScopedDefResolver, scopeResolverForModule } from "./alias-resolve
|
|
|
13
13
|
export type { ModuleScopes } from "./alias-resolver.js";
|
|
14
14
|
export { ancestorChain, contractDeclarer, controllerBearingAncestor, effectiveAuthorSchema, effectiveContractField, effectiveStatusSchema, hasOwnControllerOrTemplate, inheritedCapability, isInheritedDelegation, mappingFieldFor, needsContractMapping, resolveParent, } from "./extends-resolution.js";
|
|
15
15
|
export type { ContractDirection, DefResolver } from "./extends-resolution.js";
|
|
16
|
-
export { defaultBearingPaths, PERMISSIVE_CONTRACT, resolveContract, resolveContractSchema,
|
|
16
|
+
export { defaultBearingPaths, PERMISSIVE_CONTRACT, resolveContract, resolveContractSchema, withLiveValuesSkipped, } from "./invocation-contract.js";
|
|
17
17
|
export type { ContractOrigin, ContractScope, ResolvedContract } from "./invocation-contract.js";
|
|
18
18
|
export { hasIntermediateWildcard, parseRedactionPath, RedactionPathError, } from "./redaction-path.js";
|
|
19
19
|
export type { RedactionSegment } from "./redaction-path.js";
|
|
@@ -23,7 +23,9 @@ export { buildReferenceFieldMap, isRefEntry, isScopeEntry } from "./reference-fi
|
|
|
23
23
|
export type { ReferenceFieldMap, RefFieldEntry } from "./reference-field-map.js";
|
|
24
24
|
export { hasDeclaredUse, isRefSlot, isRefUse, possibleUses, readRefSlot, REF_USES, refSlotAnnotation, rewriteRefSlotKinds, transfersControl, } from "./ref-slot.js";
|
|
25
25
|
export type { RefSlot, RefUse, RefUseCases } from "./ref-slot.js";
|
|
26
|
-
export {
|
|
26
|
+
export { ANNOTATION_KEYWORDS, registerTeloKeywords, valueTypeKeyword, } from "./value-type-keyword.js";
|
|
27
|
+
export { applyTextEdits, isPlainSafe, quoteStyleOf, renderFixReplacement, } from "./yaml-source-edit.js";
|
|
28
|
+
export type { QuoteStyle, TextEdit } from "./yaml-source-edit.js";
|
|
27
29
|
export { hasProvidesZone, hasRequiresZone, readProvidesZone, readRequiresZone, rewriteRequiresZoneKind, } from "./zone-slot.js";
|
|
28
30
|
export type { ProvidesZoneSlot, RequiresZoneSlot } from "./zone-slot.js";
|
|
29
31
|
export { deriveLibraryExportRequirements, projectZoneRequirements, runZoneAnalysis, zoneDocumentsSignature, } from "./resolve-zone-requirements.js";
|
|
@@ -33,6 +35,10 @@ export { validateZoneSlotDeclarations } from "./validate-zone-slots.js";
|
|
|
33
35
|
export type { ZoneSlotIssue } from "./validate-zone-slots.js";
|
|
34
36
|
export { validateDynamicSelectors, validateRefSlotDeclarations } from "./validate-ref-slots.js";
|
|
35
37
|
export type { RefSlotIssue } from "./validate-ref-slots.js";
|
|
38
|
+
export { validateValueTypeSlots } from "./validate-value-type-slots.js";
|
|
39
|
+
export type { ValueTypeSlotIssue } from "./validate-value-type-slots.js";
|
|
40
|
+
export { checkSchemaCompatibility } from "./schema-compat.js";
|
|
41
|
+
export type { CompatibilityResult } from "./schema-compat.js";
|
|
36
42
|
export { visitManifest } from "./manifest-visitor.js";
|
|
37
43
|
export type { CelSiteEvent, ManifestVisitor, RefSiteEvent, ResourceEnterEvent, ResourceExitEvent, ScopeBoundaryEvent, SchemaFromSiteEvent, VisitOptions, } from "./manifest-visitor.js";
|
|
38
44
|
export { Loader } from "./manifest-loader.js";
|
|
@@ -40,6 +46,8 @@ export { isModuleKind, MODULE_KINDS } from "./module-kinds.js";
|
|
|
40
46
|
export type { ModuleKind } from "./module-kinds.js";
|
|
41
47
|
export { parseLoadedFile } from "./parse-loaded-file.js";
|
|
42
48
|
export type { ParseOptions } from "./parse-loaded-file.js";
|
|
49
|
+
export { CORE_MIGRATIONS, migrateFileText, migrateManifests, NO_MIGRATIONS, parseMigrationEntry, remapMigratedPaths, } from "./migrations/index.js";
|
|
50
|
+
export type { FileMigrations, MigrationEntry, MigrationRewrite } from "./migrations/index.js";
|
|
43
51
|
export { desugarLoadedFile, inlineImportManifests } from "./inline-imports.js";
|
|
44
52
|
export type { SyntheticImport } from "./inline-imports.js";
|
|
45
53
|
export { compareModuleVersions, compareParsedModuleVersions, isNewerModuleVersion, isSameModuleVersion, newestModuleVersion, parseModuleVersion, } from "./module-version-order.js";
|
|
@@ -64,6 +72,8 @@ export { MANIFEST_CACHE_BASE_URL, ManifestCacheSource, isHttpsModuleRef, manifes
|
|
|
64
72
|
export type { ManifestCacheCoords } from "./sources/manifest-cache.js";
|
|
65
73
|
export { LAYER_ROLES, PLATFORM_AXES, ArtifactSelectorError, describeSelector, isLayerRole, normalizeSelector, selectorFromQualifiers, selectorKey, selectorMatches, } from "./artifact-selector.js";
|
|
66
74
|
export type { ArtifactSelector, LayerRole, PlatformAxis, PlatformTarget, } from "./artifact-selector.js";
|
|
75
|
+
export { collectModuleFileClaims } from "./module-file-claims.js";
|
|
76
|
+
export type { ModuleFileClaim } from "./module-file-claims.js";
|
|
67
77
|
export { LayerIndexError, matchControllerLayers, parseLayerIndex, singletonLayer, } from "./artifact-layer-index.js";
|
|
68
78
|
export type { ArtifactLayer } from "./artifact-layer-index.js";
|
|
69
79
|
export { validateModuleArtifact } from "./validate-module-artifact.js";
|
|
@@ -73,6 +83,6 @@ export { documentToAst, parseToAst } from "./yaml-ast.js";
|
|
|
73
83
|
export type { AstDocument, AstMap, AstNode, AstPair, AstScalar, AstSeq } from "./yaml-ast.js";
|
|
74
84
|
export { CelParseError, buildCelSegments, wrapCelAst } from "./cel-ast.js";
|
|
75
85
|
export type { CelNode, CelSegment } from "./cel-ast.js";
|
|
76
|
-
export { DEFAULT_MANIFEST_FILENAME, DiagnosticSeverity } from "./types.js";
|
|
77
|
-
export type { AnalysisDiagnostic, AnalysisOptions, LoaderInitOptions, LoadOptions, ManifestSource, Position, PositionIndex, Range } from "./types.js";
|
|
86
|
+
export { DEFAULT_MANIFEST_FILENAME, DiagnosticSeverity, diagnosticFix } from "./types.js";
|
|
87
|
+
export type { AnalysisDiagnostic, AnalysisOptions, DiagnosticData, DiagnosticFix, LoaderInitOptions, LoadOptions, ManifestSource, Position, PositionIndex, Range } from "./types.js";
|
|
78
88
|
//# sourceMappingURL=index.d.ts.map
|