@telorun/analyzer 0.65.0 → 0.67.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 +1 -1
- package/dist/analyzer.d.ts.map +1 -1
- package/dist/analyzer.js +194 -65
- package/dist/builtins.d.ts.map +1 -1
- package/dist/builtins.js +67 -16
- package/dist/call-graph.d.ts.map +1 -1
- package/dist/call-graph.js +7 -1
- package/dist/cel-environment.d.ts +12 -0
- package/dist/cel-environment.d.ts.map +1 -1
- package/dist/cel-environment.js +35 -19
- package/dist/cel-scope.d.ts +8 -0
- package/dist/cel-scope.d.ts.map +1 -1
- package/dist/cel-scope.js +89 -11
- package/dist/definition-registry.d.ts +41 -0
- package/dist/definition-registry.d.ts.map +1 -1
- package/dist/definition-registry.js +76 -0
- package/dist/dependency-graph.d.ts.map +1 -1
- package/dist/dependency-graph.js +65 -0
- package/dist/eval-paths.d.ts +68 -0
- package/dist/eval-paths.d.ts.map +1 -1
- package/dist/eval-paths.js +138 -0
- package/dist/flatten-for-analyzer.d.ts +37 -1
- package/dist/flatten-for-analyzer.d.ts.map +1 -1
- package/dist/flatten-for-analyzer.js +104 -5
- package/dist/import-resolution-diagnostics.d.ts +1 -1
- package/dist/import-resolution-diagnostics.js +1 -1
- package/dist/index.d.ts +12 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -6
- package/dist/inline-imports.d.ts.map +1 -1
- package/dist/inline-imports.js +1 -0
- package/dist/manifest-visitor.d.ts +4 -0
- package/dist/manifest-visitor.d.ts.map +1 -1
- package/dist/manifest-visitor.js +36 -1
- package/dist/migrations/entries/index.d.ts.map +1 -1
- package/dist/migrations/entries/index.js +2 -0
- package/dist/migrations/entries/schema-prepare-bucket.json +27 -0
- package/dist/peer-binding.d.ts +232 -0
- package/dist/peer-binding.d.ts.map +1 -0
- package/dist/peer-binding.js +418 -0
- package/dist/precompile.d.ts.map +1 -1
- package/dist/precompile.js +8 -0
- package/dist/ref-slot.d.ts +13 -0
- package/dist/ref-slot.d.ts.map +1 -1
- package/dist/ref-slot.js +26 -0
- package/dist/reference-field-map.d.ts +28 -0
- package/dist/reference-field-map.d.ts.map +1 -1
- package/dist/reference-field-map.js +25 -0
- package/dist/referrer-rule.d.ts +17 -0
- package/dist/referrer-rule.d.ts.map +1 -1
- package/dist/referrer-rule.js +4 -1
- package/dist/release/index.d.ts +1 -1
- package/dist/release/index.js +1 -1
- package/dist/resolve-ref-sentinels.d.ts.map +1 -1
- package/dist/resolve-ref-sentinels.js +14 -1
- package/dist/resource-input.d.ts +75 -0
- package/dist/resource-input.d.ts.map +1 -0
- package/dist/resource-input.js +90 -0
- package/dist/resource-rule.d.ts +40 -27
- package/dist/resource-rule.d.ts.map +1 -1
- package/dist/resource-rule.js +61 -7
- package/dist/rule-condition.d.ts +11 -0
- package/dist/rule-condition.d.ts.map +1 -1
- package/dist/rule-condition.js +13 -0
- package/dist/schema-projection.d.ts +119 -4
- package/dist/schema-projection.d.ts.map +1 -1
- package/dist/schema-projection.js +213 -18
- package/dist/system-kinds.d.ts +7 -2
- package/dist/system-kinds.d.ts.map +1 -1
- package/dist/system-kinds.js +7 -2
- package/dist/telo-version.d.ts +1 -1
- package/dist/telo-version.js +1 -1
- package/dist/template-body.d.ts +50 -0
- package/dist/template-body.d.ts.map +1 -0
- package/dist/template-body.js +58 -0
- package/dist/validate-cel-context.d.ts +1 -17
- package/dist/validate-cel-context.d.ts.map +1 -1
- package/dist/validate-cel-context.js +73 -78
- package/dist/validate-identifier-names.d.ts.map +1 -1
- package/dist/validate-identifier-names.js +17 -2
- package/dist/validate-reference-forms.d.ts +10 -0
- package/dist/validate-reference-forms.d.ts.map +1 -1
- package/dist/validate-reference-forms.js +23 -0
- package/dist/validate-references.d.ts +17 -0
- package/dist/validate-references.d.ts.map +1 -1
- package/dist/validate-references.js +77 -18
- package/dist/validate-referrer-rules.d.ts +38 -4
- package/dist/validate-referrer-rules.d.ts.map +1 -1
- package/dist/validate-referrer-rules.js +139 -31
- package/dist/validate-resource-inputs.d.ts +35 -0
- package/dist/validate-resource-inputs.d.ts.map +1 -0
- package/dist/validate-resource-inputs.js +319 -0
- package/dist/validate-resource-rules.d.ts +11 -2
- package/dist/validate-resource-rules.d.ts.map +1 -1
- package/dist/validate-resource-rules.js +18 -12
- package/dist/validate-schema-projection.d.ts.map +1 -1
- package/dist/validate-schema-projection.js +33 -2
- package/dist/validate-template-dispatch.d.ts +27 -0
- package/dist/validate-template-dispatch.d.ts.map +1 -0
- package/dist/validate-template-dispatch.js +95 -0
- package/dist/with-synthetic-positions.d.ts +1 -1
- package/dist/with-synthetic-positions.js +1 -1
- package/package.json +3 -3
- package/src/analyzer.ts +236 -70
- package/src/builtins.ts +69 -16
- package/src/call-graph.ts +7 -1
- package/src/cel-environment.ts +48 -19
- package/src/cel-scope.ts +113 -19
- package/src/definition-registry.ts +78 -0
- package/src/dependency-graph.ts +66 -0
- package/src/eval-paths.ts +152 -0
- package/src/flatten-for-analyzer.ts +117 -4
- package/src/import-resolution-diagnostics.ts +1 -1
- package/src/index.ts +57 -4
- package/src/inline-imports.ts +1 -0
- package/src/manifest-visitor.ts +41 -1
- package/src/migrations/entries/index.ts +2 -0
- package/src/migrations/entries/schema-prepare-bucket.json +27 -0
- package/src/peer-binding.ts +641 -0
- package/src/precompile.ts +8 -0
- package/src/ref-slot.ts +36 -0
- package/src/reference-field-map.ts +42 -0
- package/src/referrer-rule.ts +20 -1
- package/src/release/index.ts +1 -1
- package/src/resolve-ref-sentinels.ts +12 -1
- package/src/resource-input.ts +132 -0
- package/src/resource-rule.ts +69 -7
- package/src/rule-condition.ts +15 -0
- package/src/schema-projection.ts +302 -20
- package/src/system-kinds.ts +7 -2
- package/src/telo-version.ts +1 -1
- package/src/template-body.ts +104 -0
- package/src/validate-cel-context.ts +73 -78
- package/src/validate-identifier-names.ts +18 -3
- package/src/validate-reference-forms.ts +22 -0
- package/src/validate-references.ts +85 -16
- package/src/validate-referrer-rules.ts +215 -28
- package/src/validate-resource-inputs.ts +367 -0
- package/src/validate-resource-rules.ts +26 -12
- package/src/validate-schema-projection.ts +50 -1
- package/src/validate-template-dispatch.ts +99 -0
- package/src/with-synthetic-positions.ts +1 -1
package/dist/analyzer.d.ts
CHANGED
|
@@ -33,7 +33,7 @@ export declare class StaticAnalyzer {
|
|
|
33
33
|
* `DUPLICATE_RESOURCE_NAME` reads those fields to tell a pipeline echo
|
|
34
34
|
* apart from a genuine collision, and downstream diagnostic positioning
|
|
35
35
|
* depends on them too. Real callers stamp positions already (the `Loader`,
|
|
36
|
-
* `flattenForAnalyzer`,
|
|
36
|
+
* `flattenForAnalyzer`, telo studio's `emitDocsFor`, the VSCode
|
|
37
37
|
* extension). Programmatic callers — tests, ad-hoc scripts — should pass
|
|
38
38
|
* their inputs through `withSyntheticPositions(...)` before calling
|
|
39
39
|
* `analyze()`. A missing position throws a clear error rather than
|
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,EAAsB,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAiBzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,
|
|
1
|
+
{"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAsB,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAiBzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAKL,KAAK,WAAW,EACjB,MAAM,sBAAsB,CAAC;AA8B9B,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAWvF,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACzF,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAwDjE,OAAO,EAAsB,KAAK,kBAAkB,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AAkG/F;0CAC0C;AAC1C,eAAO,MAAM,eAAe,GAAI,OAAO;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,KAAG,OACT,CAAC;AAErD;8EAC8E;AAC9E,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGhD;AAqUD,8DAA8D;AAC9D,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CACtC;AA6DD,MAAM,WAAW,qBAAqB;IACpC,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAkFD,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;gBAEzB,OAAO,GAAE,qBAA0B;IAI/C;;;;;;;;;;;;;;OAcG;IACH,OAAO,CACL,SAAS,EAAE,gBAAgB,EAAE,EAC7B,OAAO,CAAC,EAAE,eAAe,EACzB,QAAQ,CAAC,EAAE,gBAAgB,EAC3B,eAAe,CAAC,EAAE,eAAe,GAChC,kBAAkB,EAAE;IA+6DvB,aAAa,CACX,SAAS,EAAE,gBAAgB,EAAE,EAC7B,OAAO,CAAC,EAAE,eAAe,EACzB,QAAQ,CAAC,EAAE,gBAAgB,EAC3B,eAAe,CAAC,EAAE,eAAe,GAChC,kBAAkB,EAAE;IAMvB,SAAS,CACP,SAAS,EAAE,gBAAgB,EAAE,EAC7B,QAAQ,EAAE,gBAAgB,EAI1B,kBAAkB,CAAC,EAAE,gBAAgB,EAAE,GACtC,gBAAgB,EAAE;IAyBrB,OAAO,CACL,SAAS,EAAE,gBAAgB,EAAE,EAC7B,QAAQ,EAAE,gBAAgB,GACzB;QAAE,WAAW,EAAE,kBAAkB,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE;CAsB5F"}
|
package/dist/analyzer.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { canonicalTypeSchemaId, OBSERVED_STATE_KEY } from "@telorun/sdk";
|
|
2
2
|
import { defaultRegistry, isRefSentinel, isTaggedSentinel, plainChainOf, } from "@telorun/templating";
|
|
3
3
|
import { AliasResolver, scopeResolverForModule, } from "./alias-resolver.js";
|
|
4
|
-
import { buildCelEnvironment, } from "./cel-environment.js";
|
|
4
|
+
import { buildCelEnvironment, isKindDocument, } from "./cel-environment.js";
|
|
5
5
|
import { DefinitionRegistry } from "./definition-registry.js";
|
|
6
6
|
import { effectiveAuthorSchema } from "./extends-resolution.js";
|
|
7
7
|
import { analyzerContractScope, resolveContract, } from "./invocation-contract.js";
|
|
@@ -30,10 +30,11 @@ export { analyzerContractScope } from "./invocation-contract.js";
|
|
|
30
30
|
import { validateZoneSlotDeclarations } from "./validate-zone-slots.js";
|
|
31
31
|
import { validateSchemaProjection, } from "./validate-schema-projection.js";
|
|
32
32
|
import { evaluateResourceRules, reportResourceRules, reportUnexercisedRule, ruleExercised, validateResourceRuleDeclarations, } from "./validate-resource-rules.js";
|
|
33
|
-
import { readResourceRules } from "./resource-rule.js";
|
|
33
|
+
import { pointerToPath, readResourceRules } from "./resource-rule.js";
|
|
34
34
|
import { readReferrerRules } from "./referrer-rule.js";
|
|
35
35
|
import { evaluateReferrerRules, referrerRuleExercised, reportReferrerRules, reportUnexercisedReferrerRule, validateReferrerRuleDeclarations, } from "./validate-referrer-rules.js";
|
|
36
|
-
import {
|
|
36
|
+
import { analyzerPeerBinder, analyzerPeersTarget } from "./peer-binding.js";
|
|
37
|
+
import { describeProjectionFailure, manifestListScope, resolveSchemaProjections, } from "./schema-projection.js";
|
|
37
38
|
import { validateDynamicSelectors, validateRefSlotDeclarations, } from "./validate-ref-slots.js";
|
|
38
39
|
import { validateValueTypeSlots, } from "./validate-value-type-slots.js";
|
|
39
40
|
import { resolveSchemaTypeRefs } from "./resolve-schema-type-refs.js";
|
|
@@ -42,8 +43,8 @@ import { rewriteSyntheticOrigins } from "./rewrite-synthetic-origins.js";
|
|
|
42
43
|
import { celTypeSatisfiesJsonSchema, checkSchemaCompatibility, navigateSchemaToExprPath, substituteCelFields, validateAgainstSchema, } from "./schema-compat.js";
|
|
43
44
|
import { collectValueSchemaIssues } from "./validate-value-schema.js";
|
|
44
45
|
import { DiagnosticSeverity } from "./types.js";
|
|
45
|
-
import { extractAccessChains,
|
|
46
|
-
import {
|
|
46
|
+
import { extractAccessChains, } from "./validate-cel-context.js";
|
|
47
|
+
import { celEvalModeAt, celEvalSites, mergeCelEvalSites, NO_CEL_EVAL_SITES, } from "./eval-paths.js";
|
|
47
48
|
import { BINDINGS_ANNOTATION, findBindingSites, resolveBindingOrder, } from "./cel-bindings.js";
|
|
48
49
|
import { CEL_RESERVED_WORDS, checkName } from "./identifier-name.js";
|
|
49
50
|
import { validateIdentifierNames } from "./validate-identifier-names.js";
|
|
@@ -58,8 +59,11 @@ import { validateInvocationContract } from "./validate-invocation-contract.js";
|
|
|
58
59
|
import { collectRefInputIssues, collectStepInputIssues } from "./validate-step-inputs.js";
|
|
59
60
|
import { validateNestedInlineResources } from "./validate-nested-inline.js";
|
|
60
61
|
import { validateProviderCoherence } from "./validate-provider-coherence.js";
|
|
61
|
-
import { validateReferences } from "./validate-references.js";
|
|
62
|
+
import { kindSatisfies, validateReferences } from "./validate-references.js";
|
|
62
63
|
import { validateReferenceForms } from "./validate-reference-forms.js";
|
|
64
|
+
import { isInjectedDeclaration } from "./resource-input.js";
|
|
65
|
+
import { validateResourceInputs } from "./validate-resource-inputs.js";
|
|
66
|
+
import { validateTemplateDispatch } from "./validate-template-dispatch.js";
|
|
63
67
|
import { validateUnusedDeclarations } from "./validate-unused-declarations.js";
|
|
64
68
|
import { validateThrowsCoverage } from "./validate-throws-coverage.js";
|
|
65
69
|
import { readStepSlot } from "./step-slot.js";
|
|
@@ -554,7 +558,7 @@ export class StaticAnalyzer {
|
|
|
554
558
|
* `DUPLICATE_RESOURCE_NAME` reads those fields to tell a pipeline echo
|
|
555
559
|
* apart from a genuine collision, and downstream diagnostic positioning
|
|
556
560
|
* depends on them too. Real callers stamp positions already (the `Loader`,
|
|
557
|
-
* `flattenForAnalyzer`,
|
|
561
|
+
* `flattenForAnalyzer`, telo studio's `emitDocsFor`, the VSCode
|
|
558
562
|
* extension). Programmatic callers — tests, ad-hoc scripts — should pass
|
|
559
563
|
* their inputs through `withSyntheticPositions(...)` before calling
|
|
560
564
|
* `analyze()`. A missing position throws a clear error rather than
|
|
@@ -776,6 +780,11 @@ export class StaticAnalyzer {
|
|
|
776
780
|
const projectionIssues = [];
|
|
777
781
|
const resourceRuleIssues = [];
|
|
778
782
|
const referrerRuleIssues = [];
|
|
783
|
+
/** Definition docs of the entry's own modules that may declare rules. Their
|
|
784
|
+
* referrer-rule declarations are checked after every kind is registered,
|
|
785
|
+
* because a `peers:` pointer is checked against the REFERRER kind's schema
|
|
786
|
+
* and that kind may be declared later in the same file. */
|
|
787
|
+
const ownRuleDeclarers = [];
|
|
779
788
|
// A rule that never had anything to iterate is never proven — the second way
|
|
780
789
|
// coverage varies invisibly, beside the dynamic-leaf skip. Tracked across the
|
|
781
790
|
// whole run and reported once, since "empty on every resource" is not a fact
|
|
@@ -822,7 +831,10 @@ export class StaticAnalyzer {
|
|
|
822
831
|
// inherited field resolves — which is what lets a rule shared by every
|
|
823
832
|
// backend be declared once on the abstract they extend.
|
|
824
833
|
resourceRuleIssues.push(...validateResourceRuleDeclarations(m, effectiveAuthorSchema(m, (k) => defs.resolve(aliases.resolveKind(k) ?? k) ?? defs.resolve(k))));
|
|
825
|
-
|
|
834
|
+
// Deferred to after the registration loop: the `peers:` half is checked
|
|
835
|
+
// against the REFERRER kind's schema, and a rule may name a kind
|
|
836
|
+
// declared later in the same file.
|
|
837
|
+
ownRuleDeclarers.push(m);
|
|
826
838
|
for (const rule of readReferrerRules(m.schema)) {
|
|
827
839
|
referrerRuleExercise.set(`${m.metadata?.module}.${m.metadata?.name}#${rule.code}`, {
|
|
828
840
|
manifest: m,
|
|
@@ -873,6 +885,23 @@ export class StaticAnalyzer {
|
|
|
873
885
|
: def;
|
|
874
886
|
defs.register(normalized);
|
|
875
887
|
}
|
|
888
|
+
/**
|
|
889
|
+
* What a peer rule's `peers:` pointer names in the kind its `referrer:`
|
|
890
|
+
* filters to.
|
|
891
|
+
*
|
|
892
|
+
* Liskov in BOTH directions, which is what the check has to be: the filter
|
|
893
|
+
* is usually an abstract (`Sql.Schema`, so one rule serves every backend)
|
|
894
|
+
* while the collection is declared by the backends that implement it, so a
|
|
895
|
+
* pointer resolving on any candidate resolves the rule. Reported only when
|
|
896
|
+
* NO candidate declares it, or when every candidate that does holds plain
|
|
897
|
+
* data — the two shapes where the rule would see no declaration at all.
|
|
898
|
+
*/
|
|
899
|
+
const peersTarget = analyzerPeersTarget(defs);
|
|
900
|
+
if (!options?.skipValidation) {
|
|
901
|
+
for (const declarer of ownRuleDeclarers) {
|
|
902
|
+
referrerRuleIssues.push(...validateReferrerRuleDeclarations(declarer, { peersTarget }));
|
|
903
|
+
}
|
|
904
|
+
}
|
|
876
905
|
// Reference-form validation — enforce `!ref` as the only reference shape.
|
|
877
906
|
// Runs on the RAW manifests, BEFORE inline extraction and sentinel
|
|
878
907
|
// resolution, while an author-written `{kind, name}` is still
|
|
@@ -1277,13 +1306,12 @@ export class StaticAnalyzer {
|
|
|
1277
1306
|
if (options?.skipValidation) {
|
|
1278
1307
|
return suppressUnreadableModuleDiagnostics(diagnostics, unreadableFiles);
|
|
1279
1308
|
}
|
|
1280
|
-
//
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
}
|
|
1309
|
+
// ONE binder for the whole run, built beside the binding it serves: it caches
|
|
1310
|
+
// each referrer's resolved collection, which is what keeps a rule over an
|
|
1311
|
+
// n-entry collection from re-resolving that collection once per entry.
|
|
1312
|
+
const referrerRuleContext = {
|
|
1313
|
+
peerBinder: analyzerPeerBinder(defs, aliases, allManifests),
|
|
1314
|
+
};
|
|
1287
1315
|
// Fail loud on definition schemas AJV cannot compile. `validateAgainstSchema`
|
|
1288
1316
|
// and `validateWithRefs` swallow compile failures (returning no issues),
|
|
1289
1317
|
// which would silently skip schema validation for every resource of that
|
|
@@ -1374,6 +1402,17 @@ export class StaticAnalyzer {
|
|
|
1374
1402
|
const runReachable = reportsObservedState
|
|
1375
1403
|
? collectRunReachableNames(getCallGraph())
|
|
1376
1404
|
: new Set();
|
|
1405
|
+
// "Nothing starts this" is DECLARATION-derived, and a library does not
|
|
1406
|
+
// declare its injected inputs — whether the application starts the instance
|
|
1407
|
+
// it hands down is answerable only where that instance is declared. Inside
|
|
1408
|
+
// the library the question has no answer, so the name is treated as
|
|
1409
|
+
// reachable rather than reported on a `targets:` list the author cannot
|
|
1410
|
+
// write. The check still runs at the injection site, against the real
|
|
1411
|
+
// declaration.
|
|
1412
|
+
for (const m of allManifests) {
|
|
1413
|
+
if (isInjectedDeclaration(m))
|
|
1414
|
+
runReachable.add(m.metadata?.name);
|
|
1415
|
+
}
|
|
1377
1416
|
// Build typed kernel globals schema so x-telo-context chain validation
|
|
1378
1417
|
// recognises variables, secrets, resources, env automatically
|
|
1379
1418
|
const kernelGlobals = buildKernelGlobalsIndex(allManifests, observedState);
|
|
@@ -1420,6 +1459,44 @@ export class StaticAnalyzer {
|
|
|
1420
1459
|
moduleManifest,
|
|
1421
1460
|
observedStateContext,
|
|
1422
1461
|
});
|
|
1462
|
+
/**
|
|
1463
|
+
* The schema a resource of this kind is validated against, per DEFINITION.
|
|
1464
|
+
*
|
|
1465
|
+
* Both halves derive a fresh object — `effectiveAuthorSchema` merges along
|
|
1466
|
+
* `extends`, and the closed-schema branch spreads `kind` / `metadata` in —
|
|
1467
|
+
* so asking per resource handed `validateResourceConfig` a schema object it
|
|
1468
|
+
* had never seen. That registry memoizes its compiled AJV validator by
|
|
1469
|
+
* object IDENTITY, precisely because every resource of a kind is checked
|
|
1470
|
+
* against the same one at keystroke time, so a fresh object per resource
|
|
1471
|
+
* recompiled the whole kind schema per resource. Keyed on the definition,
|
|
1472
|
+
* which is stable for the run.
|
|
1473
|
+
*/
|
|
1474
|
+
const authorSchemaCache = new WeakMap();
|
|
1475
|
+
const validationSchemaFor = (def) => {
|
|
1476
|
+
const cached = authorSchemaCache.get(def);
|
|
1477
|
+
if (cached)
|
|
1478
|
+
return cached;
|
|
1479
|
+
const authorSchema = effectiveAuthorSchema(def, (k) => defs.resolve(aliases.resolveKind(k) ?? k) ?? defs.resolve(k));
|
|
1480
|
+
// `kind` and `metadata` are implicit on every resource — inject them so
|
|
1481
|
+
// module authors don't have to repeat them under `additionalProperties:
|
|
1482
|
+
// false`.
|
|
1483
|
+
const schema = authorSchema.additionalProperties === false
|
|
1484
|
+
? {
|
|
1485
|
+
...authorSchema,
|
|
1486
|
+
properties: {
|
|
1487
|
+
kind: { type: "string" },
|
|
1488
|
+
metadata: { type: "object" },
|
|
1489
|
+
...authorSchema.properties,
|
|
1490
|
+
},
|
|
1491
|
+
}
|
|
1492
|
+
: authorSchema;
|
|
1493
|
+
authorSchemaCache.set(def, schema);
|
|
1494
|
+
return schema;
|
|
1495
|
+
};
|
|
1496
|
+
// One scope for the whole run: it closes over the manifest list and the
|
|
1497
|
+
// registry, neither of which changes per resource, and it is asked once per
|
|
1498
|
+
// schema-valued slot that carries a projection.
|
|
1499
|
+
const resourceProjectionScope = manifestListScope(allManifests, (kind) => (defs.resolve(kind) ?? defs.resolve(aliases.resolveKind(kind) ?? kind)));
|
|
1423
1500
|
// Validate each non-definition, non-system resource
|
|
1424
1501
|
for (const m of allManifests) {
|
|
1425
1502
|
const filePath = m.metadata?.source;
|
|
@@ -1448,6 +1525,15 @@ export class StaticAnalyzer {
|
|
|
1448
1525
|
if (m.metadata?.forwardedExport === true) {
|
|
1449
1526
|
continue;
|
|
1450
1527
|
}
|
|
1528
|
+
// A kind-only stand-in for a `resources:` entry is a DECLARATION, not an
|
|
1529
|
+
// instantiation: its kind is routinely an abstract and its configuration
|
|
1530
|
+
// is the importer's to supply, so validating it here would report a
|
|
1531
|
+
// non-instantiable kind and a page of missing required fields against a
|
|
1532
|
+
// block that is correct. Its kind is checked where it was written, by
|
|
1533
|
+
// `validate-resource-inputs`; it participates here only as a resolution
|
|
1534
|
+
// target and as a CEL type.
|
|
1535
|
+
if (isInjectedDeclaration(m))
|
|
1536
|
+
continue;
|
|
1451
1537
|
const resource = { kind: m.kind, name: m.metadata?.name };
|
|
1452
1538
|
// Resolve kind through alias if needed; direct lookup takes priority so that
|
|
1453
1539
|
// aliases whose name matches the module name (the common case) work without
|
|
@@ -1510,34 +1596,53 @@ export class StaticAnalyzer {
|
|
|
1510
1596
|
continue;
|
|
1511
1597
|
}
|
|
1512
1598
|
// Validate resource config against the definition's AUTHOR-FACING schema —
|
|
1513
|
-
// inheritance-resolved
|
|
1514
|
-
//
|
|
1515
|
-
//
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
// authors don't have to repeat them when using additionalProperties: false.
|
|
1519
|
-
const authorSchema = effectiveAuthorSchema(definition, (k) => defs.resolve(aliases.resolveKind(k) ?? k) ?? defs.resolve(k));
|
|
1520
|
-
if (authorSchema && Object.keys(authorSchema).length > 0) {
|
|
1521
|
-
const schema = authorSchema.additionalProperties === false
|
|
1522
|
-
? {
|
|
1523
|
-
...authorSchema,
|
|
1524
|
-
properties: {
|
|
1525
|
-
kind: { type: "string" },
|
|
1526
|
-
metadata: { type: "object" },
|
|
1527
|
-
...authorSchema.properties,
|
|
1528
|
-
},
|
|
1529
|
-
}
|
|
1530
|
-
: authorSchema;
|
|
1599
|
+
// inheritance-resolved, with `kind` / `metadata` injected. See
|
|
1600
|
+
// `validationSchemaFor`, which is where both derivations and the reason
|
|
1601
|
+
// they are memoized per definition live.
|
|
1602
|
+
const schema = validationSchemaFor(definition);
|
|
1603
|
+
if (Object.keys(schema).length > 0) {
|
|
1531
1604
|
// Phase 1: collect the pure-CEL leaves and the schema of the slot each
|
|
1532
1605
|
// flows into. The expression's own type is resolved later, by the
|
|
1533
1606
|
// engine walk that owns type-checking; this half only knows the target.
|
|
1534
1607
|
for (const slot of collectCelValueSlots(m, schema, "")) {
|
|
1535
1608
|
celReturnSlots.push({ manifest: m, resource, filePath, ...slot });
|
|
1536
1609
|
}
|
|
1610
|
+
// A kind's own schema may point a slot at a PROJECTION — of a resource it
|
|
1611
|
+
// references, or (the empty pointer) of this very declaration, which is
|
|
1612
|
+
// what types a table's seed rows against its own `columns:`. Resolved
|
|
1613
|
+
// PER RESOURCE, because a projection is declaration-derived: the same
|
|
1614
|
+
// kind schema yields a different row shape for every table.
|
|
1615
|
+
//
|
|
1616
|
+
// A failure here is REPORTED, never dropped. An entry that could not be
|
|
1617
|
+
// read vanishes from the projected shape, so the slot typed from it then
|
|
1618
|
+
// rejects a field the author did declare ("'status' is not allowed") with
|
|
1619
|
+
// nothing saying why — the projection's own failure mode, blaming the
|
|
1620
|
+
// wrong line. Entry-module-scoped, like every other schema issue.
|
|
1621
|
+
const projectionFailures = [];
|
|
1622
|
+
const projected = resolveSchemaProjections(schema, m, resourceProjectionScope, projectionFailures);
|
|
1623
|
+
if (!ownModule || rootModules.has(ownModule)) {
|
|
1624
|
+
for (const failure of projectionFailures) {
|
|
1625
|
+
// A projection through a library's own resource INPUT is
|
|
1626
|
+
// unanswerable here — the entries belong to the declaration the
|
|
1627
|
+
// importer supplies — so it is not a defect in the block that named
|
|
1628
|
+
// it. The check runs at the injection site instead.
|
|
1629
|
+
if (failure.reason === "injected")
|
|
1630
|
+
continue;
|
|
1631
|
+
diagnostics.push({
|
|
1632
|
+
severity: DiagnosticSeverity.Error,
|
|
1633
|
+
code: "SCHEMA_PROJECTION_FROM_UNRESOLVED",
|
|
1634
|
+
source: SOURCE,
|
|
1635
|
+
message: `${m.kind}/${resource.name}: ${describeProjectionFailure(failure)}`,
|
|
1636
|
+
data: { resource, filePath, path: pointerToPath(failure.pointer) },
|
|
1637
|
+
});
|
|
1638
|
+
}
|
|
1639
|
+
}
|
|
1537
1640
|
// Phase 2+3: AJV on substituted data — CEL fields replaced with typed
|
|
1538
1641
|
// placeholders. Through the REGISTRY, so a kind whose schema references
|
|
1539
1642
|
// a shape declared elsewhere is checked on the instance that holds it.
|
|
1540
|
-
const ajvIssues = defs.validateResourceConfig(substituteCelFields(m,
|
|
1643
|
+
const ajvIssues = defs.validateResourceConfig(substituteCelFields(m, projected, undefined, {
|
|
1644
|
+
external: (ref) => defs.schemaForId(ref),
|
|
1645
|
+
}), projected);
|
|
1541
1646
|
// Phase 4: value slots that must satisfy a type declared elsewhere on
|
|
1542
1647
|
// the resource (`x-telo-value-schema-from`) — e.g. every row of a
|
|
1543
1648
|
// decision table against its declared `outputType`, so a mistyped branch
|
|
@@ -1563,10 +1668,10 @@ export class StaticAnalyzer {
|
|
|
1563
1668
|
// `validate-resource-rules.ts`, the shape every neighbouring pass uses:
|
|
1564
1669
|
// issues out, one emit here.
|
|
1565
1670
|
const ruleDeclarer = definition.metadata?.module;
|
|
1566
|
-
for (const report of reportResourceRules(m, definition, evaluateResourceRules(m,
|
|
1671
|
+
for (const report of reportResourceRules(m, definition, evaluateResourceRules(m, schema), !ruleDeclarer || rootModules.has(ruleDeclarer))) {
|
|
1567
1672
|
diagnostics.push(resourceRuleDiagnostic(report));
|
|
1568
1673
|
}
|
|
1569
|
-
for (const rule of readResourceRules(
|
|
1674
|
+
for (const rule of readResourceRules(schema)) {
|
|
1570
1675
|
const key = `${definition.metadata?.module}.${definition.metadata?.name}#${rule.code}`;
|
|
1571
1676
|
const tracked = ruleExercise.get(key);
|
|
1572
1677
|
if (!tracked)
|
|
@@ -1581,10 +1686,10 @@ export class StaticAnalyzer {
|
|
|
1581
1686
|
// literal appears on the referring side, where the spelling would be the
|
|
1582
1687
|
// consumer's import alias rather than anything the rule's author controls.
|
|
1583
1688
|
// A consumer of the shared call graph, never a second traversal.
|
|
1584
|
-
const referrerRules = readReferrerRules(
|
|
1689
|
+
const referrerRules = readReferrerRules(schema);
|
|
1585
1690
|
if (referrerRules.length > 0) {
|
|
1586
1691
|
const referrers = referrersOf(m, getCallGraph());
|
|
1587
|
-
for (const report of reportReferrerRules(m, definition, evaluateReferrerRules(m,
|
|
1692
|
+
for (const report of reportReferrerRules(m, definition, evaluateReferrerRules(m, schema, referrers, kindMatches, referrerRuleContext), !ruleDeclarer || rootModules.has(ruleDeclarer))) {
|
|
1588
1693
|
// A VIOLATION is the referrer's data, so it is reported only when that
|
|
1589
1694
|
// manifest is the entry's own — the same direction a resource-rule
|
|
1590
1695
|
// violation takes, one hop further out.
|
|
@@ -1593,6 +1698,15 @@ export class StaticAnalyzer {
|
|
|
1593
1698
|
continue;
|
|
1594
1699
|
}
|
|
1595
1700
|
diagnostics.push(referrerRuleDiagnostic(report));
|
|
1701
|
+
// A rule that VIOLATED plainly ran, whatever its peer set held. The
|
|
1702
|
+
// unexercised report exists to catch silence — a `peers:` naming
|
|
1703
|
+
// nothing makes every `!peers.exists(…)` pass vacuously — so a finding
|
|
1704
|
+
// is exactly the evidence it asks for.
|
|
1705
|
+
if (report.code === "REFERRER_RULE_VIOLATED") {
|
|
1706
|
+
const violated = referrerRuleExercise.get(`${definition.metadata?.module}.${definition.metadata?.name}#${report.rule}`);
|
|
1707
|
+
if (violated)
|
|
1708
|
+
violated.exercised = true;
|
|
1709
|
+
}
|
|
1596
1710
|
}
|
|
1597
1711
|
for (const rule of referrerRules) {
|
|
1598
1712
|
const key = `${definition.metadata?.module}.${definition.metadata?.name}#${rule.code}`;
|
|
@@ -1600,8 +1714,9 @@ export class StaticAnalyzer {
|
|
|
1600
1714
|
if (!tracked)
|
|
1601
1715
|
continue;
|
|
1602
1716
|
tracked.seen = true;
|
|
1603
|
-
if (referrerRuleExercised(rule, referrers, kindMatches))
|
|
1717
|
+
if (referrerRuleExercised(rule, referrers, kindMatches, referrerRuleContext)) {
|
|
1604
1718
|
tracked.exercised = true;
|
|
1719
|
+
}
|
|
1605
1720
|
}
|
|
1606
1721
|
}
|
|
1607
1722
|
// Validate inline resources nested inside this resource's body (e.g. a
|
|
@@ -1769,18 +1884,15 @@ export class StaticAnalyzer {
|
|
|
1769
1884
|
// same schema an expression is typed against.
|
|
1770
1885
|
let celStepContextSchema;
|
|
1771
1886
|
let celErrorScopes = new Map();
|
|
1772
|
-
//
|
|
1773
|
-
//
|
|
1774
|
-
//
|
|
1775
|
-
//
|
|
1776
|
-
|
|
1887
|
+
// Where this kind says its values are evaluated — `x-telo-eval` paths (own +
|
|
1888
|
+
// capability) and the regions covering their contents. A `!cel` outside every
|
|
1889
|
+
// one of them is read as a literal, and one under a compile path resolves at
|
|
1890
|
+
// startup, where observed state cannot exist yet. Both questions are
|
|
1891
|
+
// `celEvalModeAt`, which the editor asks of the same sites.
|
|
1892
|
+
let celSites = NO_CEL_EVAL_SITES;
|
|
1777
1893
|
// The bindings field this kind declares (if any), read by the CEL sites that
|
|
1778
1894
|
// see the names it introduces.
|
|
1779
1895
|
let celBindingSites;
|
|
1780
|
-
// The compile half alone: a field that resolves at startup, where observed
|
|
1781
|
-
// state cannot exist yet.
|
|
1782
|
-
let celCompilePaths = [];
|
|
1783
|
-
let celRegionScopes = [];
|
|
1784
1896
|
let celRuleApplies = false;
|
|
1785
1897
|
visitManifest(allManifests, defs, {
|
|
1786
1898
|
onResourceEnter: (e) => {
|
|
@@ -1912,23 +2024,23 @@ export class StaticAnalyzer {
|
|
|
1912
2024
|
celRuleApplies =
|
|
1913
2025
|
!!e.definition?.schema && capability !== undefined && capability !== "Telo.Template";
|
|
1914
2026
|
if (celRuleApplies) {
|
|
1915
|
-
|
|
1916
|
-
|
|
2027
|
+
// The INHERITANCE-RESOLVED schema, not the kind's own: without
|
|
2028
|
+
// `base:`, an `extends` child is authored against merge(parent, own),
|
|
2029
|
+
// so a CEL-bearing field the parent declares is a legal field on the
|
|
2030
|
+
// child and the kernel expands it — it stamps the merged schema at
|
|
2031
|
+
// definition registration and builds eval paths from that. Reading
|
|
2032
|
+
// the own schema here reported `CEL_IN_NON_EVAL_FIELD` for an
|
|
2033
|
+
// expression the runtime evaluates correctly, which is the two halves
|
|
2034
|
+
// disagreeing about what the manifest means.
|
|
2035
|
+
const ownSchema = effectiveAuthorSchema(e.definition, (k) => defs.resolve(aliases.resolveKind(k) ?? k) ?? defs.resolve(k));
|
|
1917
2036
|
const capabilityDef = capability ? defs.resolve(capability) : undefined;
|
|
1918
|
-
const parent = capabilityDef?.schema
|
|
1919
|
-
? buildEvalPaths(capabilityDef.schema)
|
|
1920
|
-
: { compile: [], runtime: [] };
|
|
1921
|
-
celEvalPaths = [...own.compile, ...own.runtime, ...parent.compile, ...parent.runtime];
|
|
1922
2037
|
// A `Telo.Provider`'s fields are implicitly compile-eval — the
|
|
1923
2038
|
// capability abstract carries the root annotation — so its reads are
|
|
1924
2039
|
// covered here without the provider restating anything.
|
|
1925
|
-
|
|
1926
|
-
celRegionScopes = extractCelRegionScopes(ownSchema);
|
|
2040
|
+
celSites = mergeCelEvalSites(celEvalSites(ownSchema), celEvalSites(capabilityDef?.schema));
|
|
1927
2041
|
}
|
|
1928
2042
|
else {
|
|
1929
|
-
|
|
1930
|
-
celCompilePaths = [];
|
|
1931
|
-
celRegionScopes = [];
|
|
2043
|
+
celSites = NO_CEL_EVAL_SITES;
|
|
1932
2044
|
}
|
|
1933
2045
|
},
|
|
1934
2046
|
onCel: (e) => {
|
|
@@ -1944,8 +2056,7 @@ export class StaticAnalyzer {
|
|
|
1944
2056
|
if (celRuleApplies &&
|
|
1945
2057
|
engineName === "cel" &&
|
|
1946
2058
|
celScope.invocationContextSchema === undefined &&
|
|
1947
|
-
|
|
1948
|
-
!celRegionScopes.some((scope) => pathMatchesScope(path, scope)) &&
|
|
2059
|
+
celEvalModeAt(celSites, path) === null &&
|
|
1949
2060
|
!pathCrossesNestedResource(m, path)) {
|
|
1950
2061
|
diagnostics.push({
|
|
1951
2062
|
severity: DiagnosticSeverity.Error,
|
|
@@ -1969,7 +2080,7 @@ export class StaticAnalyzer {
|
|
|
1969
2080
|
// the two-level shape it publishes under, so a cross-module read
|
|
1970
2081
|
// is checked exactly like a local one.
|
|
1971
2082
|
const reported = observedState.get(read.alias ? `${read.alias}.${read.name}` : read.name);
|
|
1972
|
-
if (celRuleApplies &&
|
|
2083
|
+
if (celRuleApplies && celEvalModeAt(celSites, path) === "compile") {
|
|
1973
2084
|
diagnostics.push({
|
|
1974
2085
|
severity: DiagnosticSeverity.Error,
|
|
1975
2086
|
code: "OBSERVED_STATE_IN_STARTUP_FIELD",
|
|
@@ -2013,7 +2124,19 @@ export class StaticAnalyzer {
|
|
|
2013
2124
|
contextSchema: e.contextSchema,
|
|
2014
2125
|
matchedScope,
|
|
2015
2126
|
});
|
|
2016
|
-
const result = engine.analyze(expr, {
|
|
2127
|
+
const result = engine.analyze(expr, {
|
|
2128
|
+
celEnv: typedEnv,
|
|
2129
|
+
contextSchema: effectiveContext,
|
|
2130
|
+
// `scopeFor` registers every kernel global and every name the site's
|
|
2131
|
+
// context declares, so a root this environment does not know is one
|
|
2132
|
+
// nothing puts in scope. Two places where the CEL belongs to another
|
|
2133
|
+
// scope, both already recognised by the non-eval-field check: a kind
|
|
2134
|
+
// document, whose CEL is written for whoever instantiates the kind,
|
|
2135
|
+
// and anything below a nested inline `{ kind }`, whose CEL the
|
|
2136
|
+
// nested kind evaluates — and which is analyzed again, in its own
|
|
2137
|
+
// scope, as the resource it was extracted into.
|
|
2138
|
+
rootsDeclared: !isKindDocument(m) && !pathCrossesNestedResource(m, path),
|
|
2139
|
+
});
|
|
2017
2140
|
if (result.type !== undefined) {
|
|
2018
2141
|
let byPath = celTypeByPath.get(m);
|
|
2019
2142
|
if (!byPath)
|
|
@@ -2049,7 +2172,7 @@ export class StaticAnalyzer {
|
|
|
2049
2172
|
// intent (a boot timestamp, a run id), so it warns rather than
|
|
2050
2173
|
// blocking. The engine reports which calls re-evaluate; the eval mode
|
|
2051
2174
|
// is manifest policy and stays here.
|
|
2052
|
-
if (celRuleApplies &&
|
|
2175
|
+
if (celRuleApplies && celEvalModeAt(celSites, path) === "compile") {
|
|
2053
2176
|
const volatile = [
|
|
2054
2177
|
...new Set(result.calls.filter((c) => c.deterministic === false).map((c) => c.name)),
|
|
2055
2178
|
].sort();
|
|
@@ -2105,7 +2228,7 @@ export class StaticAnalyzer {
|
|
|
2105
2228
|
}
|
|
2106
2229
|
}
|
|
2107
2230
|
},
|
|
2108
|
-
}, { aliases });
|
|
2231
|
+
}, { aliases, aliasesByModule, rootModules });
|
|
2109
2232
|
// The two halves of "does this expression fit the slot it flows into" meet
|
|
2110
2233
|
// here: the engine resolved the expression's type during the walk above,
|
|
2111
2234
|
// and the schema walk recorded the slot. An expression that failed to check
|
|
@@ -2175,6 +2298,12 @@ export class StaticAnalyzer {
|
|
|
2175
2298
|
diagnostics.push(...validateThrowsCoverage(allManifests, defs, aliases, this.celEnv, aliasesByModule, rootModules));
|
|
2176
2299
|
// Warn about declared variables / secrets / ports that no CEL references.
|
|
2177
2300
|
diagnostics.push(...validateUnusedDeclarations(allManifests, this.celEnv));
|
|
2301
|
+
// A `!ref` at a definition's dispatch slot must name a sibling `resources:`
|
|
2302
|
+
// entry — the slot no reference pass reaches, so the tag would otherwise
|
|
2303
|
+
// advertise a resolution nothing performs.
|
|
2304
|
+
diagnostics.push(...validateTemplateDispatch(allManifests, rootModules));
|
|
2305
|
+
// A library's declared resource inputs, and every import that supplies them.
|
|
2306
|
+
diagnostics.push(...validateResourceInputs(allManifests, defs, aliases, rootModules, (supplied, required) => kindSatisfies(supplied, required, defs)));
|
|
2178
2307
|
// Reroute diagnostics on synthetic (inline-extracted) resources back to
|
|
2179
2308
|
// the chain root so position-index lookups land on the parent doc.
|
|
2180
2309
|
return rewriteSyntheticOrigins(suppressUnreadableModuleDiagnostics(diagnostics, unreadableFiles), allManifests);
|
package/dist/builtins.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builtins.d.ts","sourceRoot":"","sources":["../src/builtins.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"builtins.d.ts","sourceRoot":"","sources":["../src/builtins.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AA8OvD,eAAO,MAAM,eAAe,EAAE,kBAAkB,EA+tB/C,CAAC"}
|
package/dist/builtins.js
CHANGED
|
@@ -215,6 +215,33 @@ const ROOT_LOGGING_SCHEMA = {
|
|
|
215
215
|
},
|
|
216
216
|
additionalProperties: false,
|
|
217
217
|
};
|
|
218
|
+
/** A `Telo.Library`'s declared resource inputs — the instances it requires from
|
|
219
|
+
* whoever imports it, the inward half of the symmetry `exports.resources`
|
|
220
|
+
* already had outward. Each entry is constrained by KIND ONLY, through the same
|
|
221
|
+
* alias-qualified grammar `extends:` and `x-telo-ref` use; there is no `use:`,
|
|
222
|
+
* because the boundary is a dependency edge for init order whatever the library
|
|
223
|
+
* does with the instance. See `analyzer/nodejs/src/resource-input.ts`. */
|
|
224
|
+
const LIBRARY_RESOURCE_INPUTS_SCHEMA = {
|
|
225
|
+
type: "object",
|
|
226
|
+
additionalProperties: {
|
|
227
|
+
type: "object",
|
|
228
|
+
required: ["kind"],
|
|
229
|
+
properties: {
|
|
230
|
+
kind: { type: "string" },
|
|
231
|
+
description: { type: "string" },
|
|
232
|
+
},
|
|
233
|
+
additionalProperties: false,
|
|
234
|
+
},
|
|
235
|
+
};
|
|
236
|
+
/** The importer's side of the same block: entry name → `!ref` to the instance
|
|
237
|
+
* supplied for it. Left open because the accepted KIND is declared by the
|
|
238
|
+
* target library, not by this schema — the constraint is checked by
|
|
239
|
+
* `validate-resource-inputs.ts`, which reads the target's declared block off
|
|
240
|
+
* the `metadata.requiredResources` stamp. */
|
|
241
|
+
const IMPORT_RESOURCE_INPUTS_SCHEMA = {
|
|
242
|
+
type: "object",
|
|
243
|
+
additionalProperties: {},
|
|
244
|
+
};
|
|
218
245
|
export const KERNEL_BUILTINS = [
|
|
219
246
|
{ kind: "Telo.Abstract", metadata: { name: "Template", module: "Telo" } },
|
|
220
247
|
// "Control can be transferred to this" — the parent of Invocable and Runnable,
|
|
@@ -408,28 +435,26 @@ export const KERNEL_BUILTINS = [
|
|
|
408
435
|
items: {
|
|
409
436
|
type: "object",
|
|
410
437
|
additionalProperties: true,
|
|
411
|
-
//
|
|
412
|
-
//
|
|
413
|
-
//
|
|
414
|
-
//
|
|
415
|
-
//
|
|
438
|
+
// A `resources:` entry is a DECLARATION of another kind, so the
|
|
439
|
+
// CEL inside it belongs to THAT kind: its `x-telo-context` regions
|
|
440
|
+
// are rebased under this entry's path and take precedence (they are
|
|
441
|
+
// deeper), which is what puts `inputs`, `item`, `request`, `steps`
|
|
442
|
+
// and a `catch:`'s `error` in scope exactly where the nested kind
|
|
443
|
+
// declares them — see `analyzer/nodejs/src/template-body.ts`.
|
|
416
444
|
//
|
|
417
|
-
//
|
|
418
|
-
//
|
|
419
|
-
//
|
|
420
|
-
//
|
|
421
|
-
//
|
|
422
|
-
//
|
|
423
|
-
//
|
|
445
|
+
// What stays here is `self` alone, in force throughout the entry:
|
|
446
|
+
// it is how a body reaches the configuration its enclosing template
|
|
447
|
+
// was given, and no nested kind knows about it. The four names that
|
|
448
|
+
// used to sit beside it (`request` / `result` / `steps` / `error`)
|
|
449
|
+
// were a fixed permissive stand-in for the nested kind's own
|
|
450
|
+
// regions — which is why `error` was offered outside every `catch:`
|
|
451
|
+
// while `inputs` and `item` were undefined wherever a body actually
|
|
452
|
+
// reads them.
|
|
424
453
|
"x-telo-context": {
|
|
425
454
|
type: "object",
|
|
426
455
|
additionalProperties: false,
|
|
427
456
|
properties: {
|
|
428
457
|
self: { "x-telo-context-from-root": "schema" },
|
|
429
|
-
request: {},
|
|
430
|
-
result: {},
|
|
431
|
-
steps: {},
|
|
432
|
-
error: {},
|
|
433
458
|
},
|
|
434
459
|
},
|
|
435
460
|
},
|
|
@@ -592,6 +617,7 @@ export const KERNEL_BUILTINS = [
|
|
|
592
617
|
integrity: { type: "string" },
|
|
593
618
|
variables: { type: "object" },
|
|
594
619
|
secrets: { type: "object" },
|
|
620
|
+
resources: IMPORT_RESOURCE_INPUTS_SCHEMA,
|
|
595
621
|
runtime: {
|
|
596
622
|
oneOf: [
|
|
597
623
|
{ type: "string" },
|
|
@@ -738,6 +764,7 @@ export const KERNEL_BUILTINS = [
|
|
|
738
764
|
integrity: { type: "string" },
|
|
739
765
|
variables: { type: "object" },
|
|
740
766
|
secrets: { type: "object" },
|
|
767
|
+
resources: IMPORT_RESOURCE_INPUTS_SCHEMA,
|
|
741
768
|
runtime: {
|
|
742
769
|
oneOf: [
|
|
743
770
|
{ type: "string" },
|
|
@@ -853,6 +880,29 @@ export const KERNEL_BUILTINS = [
|
|
|
853
880
|
},
|
|
854
881
|
variables: { type: "object" },
|
|
855
882
|
secrets: { type: "object" },
|
|
883
|
+
// How many times this library is instantiated in one application.
|
|
884
|
+
//
|
|
885
|
+
// `isolated` (the default) is what every published module was written
|
|
886
|
+
// against: each import declaration builds its own child scope with its
|
|
887
|
+
// own instances, so two libraries importing a third get two of
|
|
888
|
+
// everything in it. `shared` makes the library a SINGLETON — every
|
|
889
|
+
// import of it resolves to one instantiation, owned by the root and
|
|
890
|
+
// torn down after everything that borrowed it.
|
|
891
|
+
//
|
|
892
|
+
// Default `isolated` rather than `shared` — the opposite of the
|
|
893
|
+
// Application field's — because flipping it would silently collapse
|
|
894
|
+
// every existing app's resource graph and turn per-import `variables:`
|
|
895
|
+
// into a conflict. The `exports.kinds` precedent: private-by-default is
|
|
896
|
+
// the better end state and still needs the ecosystem republished first.
|
|
897
|
+
lifecycle: {
|
|
898
|
+
type: "string",
|
|
899
|
+
enum: ["shared", "isolated"],
|
|
900
|
+
default: "isolated",
|
|
901
|
+
},
|
|
902
|
+
// The inward half of `exports.resources`: instances this library
|
|
903
|
+
// requires from whoever imports it. Library-only — an Application is a
|
|
904
|
+
// root with no importer, so it owns its instances outright.
|
|
905
|
+
resources: LIBRARY_RESOURCE_INPUTS_SCHEMA,
|
|
856
906
|
include: {
|
|
857
907
|
type: "array",
|
|
858
908
|
items: { type: "string" },
|
|
@@ -883,6 +933,7 @@ export const KERNEL_BUILTINS = [
|
|
|
883
933
|
integrity: { type: "string" },
|
|
884
934
|
variables: { type: "object" },
|
|
885
935
|
secrets: { type: "object" },
|
|
936
|
+
resources: IMPORT_RESOURCE_INPUTS_SCHEMA,
|
|
886
937
|
runtime: {
|
|
887
938
|
oneOf: [
|
|
888
939
|
{ type: "string" },
|
package/dist/call-graph.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"call-graph.d.ts","sourceRoot":"","sources":["../src/call-graph.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"call-graph.d.ts","sourceRoot":"","sources":["../src/call-graph.ts"],"names":[],"mappings":"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"}
|