@telorun/analyzer 0.66.0 → 0.68.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.
Files changed (99) hide show
  1. package/dist/analyzer.d.ts.map +1 -1
  2. package/dist/analyzer.js +60 -2
  3. package/dist/builtins.d.ts.map +1 -1
  4. package/dist/builtins.js +67 -16
  5. package/dist/cel-scope.d.ts +8 -0
  6. package/dist/cel-scope.d.ts.map +1 -1
  7. package/dist/cel-scope.js +66 -8
  8. package/dist/definition-registry.d.ts +17 -0
  9. package/dist/definition-registry.d.ts.map +1 -1
  10. package/dist/definition-registry.js +35 -0
  11. package/dist/dependency-graph.d.ts.map +1 -1
  12. package/dist/dependency-graph.js +65 -0
  13. package/dist/extends-resolution.d.ts +20 -0
  14. package/dist/extends-resolution.d.ts.map +1 -1
  15. package/dist/extends-resolution.js +29 -0
  16. package/dist/flatten-for-analyzer.d.ts +36 -0
  17. package/dist/flatten-for-analyzer.d.ts.map +1 -1
  18. package/dist/flatten-for-analyzer.js +103 -4
  19. package/dist/index.d.ts +8 -4
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +6 -4
  22. package/dist/inline-imports.d.ts.map +1 -1
  23. package/dist/inline-imports.js +1 -0
  24. package/dist/invocation-contract.d.ts +20 -0
  25. package/dist/invocation-contract.d.ts.map +1 -1
  26. package/dist/invocation-contract.js +74 -0
  27. package/dist/manifest-visitor.d.ts +4 -0
  28. package/dist/manifest-visitor.d.ts.map +1 -1
  29. package/dist/manifest-visitor.js +28 -0
  30. package/dist/precompile.d.ts.map +1 -1
  31. package/dist/precompile.js +8 -0
  32. package/dist/resolve-ref-sentinels.d.ts.map +1 -1
  33. package/dist/resolve-ref-sentinels.js +14 -1
  34. package/dist/resource-input.d.ts +75 -0
  35. package/dist/resource-input.d.ts.map +1 -0
  36. package/dist/resource-input.js +90 -0
  37. package/dist/schema-keywords.d.ts +16 -1
  38. package/dist/schema-keywords.d.ts.map +1 -1
  39. package/dist/schema-keywords.js +20 -0
  40. package/dist/schema-projection.d.ts +13 -0
  41. package/dist/schema-projection.d.ts.map +1 -1
  42. package/dist/schema-projection.js +7 -0
  43. package/dist/system-kinds.d.ts +7 -2
  44. package/dist/system-kinds.d.ts.map +1 -1
  45. package/dist/system-kinds.js +7 -2
  46. package/dist/telo-version.d.ts +1 -1
  47. package/dist/telo-version.js +1 -1
  48. package/dist/template-body.d.ts +50 -0
  49. package/dist/template-body.d.ts.map +1 -0
  50. package/dist/template-body.js +58 -0
  51. package/dist/validate-cel-context.d.ts.map +1 -1
  52. package/dist/validate-cel-context.js +68 -8
  53. package/dist/validate-extends.d.ts.map +1 -1
  54. package/dist/validate-extends.js +42 -1
  55. package/dist/validate-identifier-names.d.ts.map +1 -1
  56. package/dist/validate-identifier-names.js +17 -2
  57. package/dist/validate-references.d.ts +17 -0
  58. package/dist/validate-references.d.ts.map +1 -1
  59. package/dist/validate-references.js +68 -16
  60. package/dist/validate-resource-inputs.d.ts +35 -0
  61. package/dist/validate-resource-inputs.d.ts.map +1 -0
  62. package/dist/validate-resource-inputs.js +319 -0
  63. package/dist/validate-sensitive-slots.d.ts +28 -0
  64. package/dist/validate-sensitive-slots.d.ts.map +1 -0
  65. package/dist/validate-sensitive-slots.js +75 -0
  66. package/dist/validate-template-dispatch.d.ts +27 -0
  67. package/dist/validate-template-dispatch.d.ts.map +1 -0
  68. package/dist/validate-template-dispatch.js +95 -0
  69. package/dist/value-type-keyword.d.ts +1 -1
  70. package/dist/value-type-keyword.d.ts.map +1 -1
  71. package/dist/value-type-keyword.js +1 -0
  72. package/package.json +3 -3
  73. package/src/analyzer.ts +71 -2
  74. package/src/builtins.ts +69 -16
  75. package/src/cel-scope.ts +90 -14
  76. package/src/definition-registry.ts +36 -0
  77. package/src/dependency-graph.ts +66 -0
  78. package/src/extends-resolution.ts +33 -0
  79. package/src/flatten-for-analyzer.ts +116 -3
  80. package/src/index.ts +16 -0
  81. package/src/inline-imports.ts +1 -0
  82. package/src/invocation-contract.ts +71 -0
  83. package/src/manifest-visitor.ts +33 -0
  84. package/src/precompile.ts +8 -0
  85. package/src/resolve-ref-sentinels.ts +12 -1
  86. package/src/resource-input.ts +132 -0
  87. package/src/schema-keywords.ts +33 -1
  88. package/src/schema-projection.ts +19 -0
  89. package/src/system-kinds.ts +7 -2
  90. package/src/telo-version.ts +1 -1
  91. package/src/template-body.ts +104 -0
  92. package/src/validate-cel-context.ts +67 -7
  93. package/src/validate-extends.ts +51 -1
  94. package/src/validate-identifier-names.ts +18 -3
  95. package/src/validate-references.ts +70 -14
  96. package/src/validate-resource-inputs.ts +367 -0
  97. package/src/validate-sensitive-slots.ts +109 -0
  98. package/src/validate-template-dispatch.ts +99 -0
  99. package/src/value-type-keyword.ts +1 -0
@@ -172,7 +172,20 @@ defs) {
172
172
  for (const r of resources) {
173
173
  if (isForeign(r))
174
174
  continue;
175
- if (!r.metadata?.name || !r.kind || SYSTEM_KINDS.has(r.kind))
175
+ if (!r.metadata?.name || !r.kind)
176
+ continue;
177
+ // A `Telo.Import` is import-time metadata, not a resource instance — except
178
+ // for its `resources:` block, which supplies the instances the target
179
+ // library declared it needs. Those are `!ref`s to the importer's OWN
180
+ // resources and resolve exactly like any other reference; nothing else on
181
+ // the document is a reference slot, so only that subtree is walked.
182
+ if (r.kind === "Telo.Import") {
183
+ const supplied = r.resources;
184
+ if (supplied)
185
+ r.resources = walk(supplied);
186
+ continue;
187
+ }
188
+ if (SYSTEM_KINDS.has(r.kind))
176
189
  continue;
177
190
  walk(r);
178
191
  }
@@ -0,0 +1,75 @@
1
+ import type { ResourceManifest } from "@telorun/sdk";
2
+ /**
3
+ * The `resources:` block on a `Telo.Library` — the instances a library requires
4
+ * from whoever imports it, beside the scalar `variables:` / `secrets:` blocks.
5
+ * Instances used to flow up only (`exports.resources`); this is the inward half.
6
+ *
7
+ * THE SINGLE READER of the block, in both halves (the analyzer's passes and the
8
+ * kernel's import controller), on the `ref-slot.ts` precedent: a boundary whose
9
+ * shape two runtimes must agree about is read in one place, so the next shape
10
+ * change is a one-file edit rather than four surfaces recognising a block by
11
+ * pattern-matching it.
12
+ *
13
+ * Browser-safe — no I/O, no Node built-ins.
14
+ */
15
+ /** One declared input. */
16
+ export interface ResourceInput {
17
+ /** The entry key. Inside the library the instance is named exactly as a
18
+ * locally declared resource: `!ref <name>` at a ref slot, `resources.<name>`
19
+ * in CEL. */
20
+ name: string;
21
+ /** The alias-qualified kind constraint, as written in the DECLARING library's
22
+ * own scope (`Sql.Connection`, `Self.Store`, `Telo.LogSink`). There is no
23
+ * `use:` here: the boundary is a dependency edge for init order whatever the
24
+ * library does with the instance, and the flattened application analysis
25
+ * drops the library doc, so an app-level claim about internal call sites is
26
+ * one nothing could check. */
27
+ kind: string;
28
+ description?: string;
29
+ }
30
+ /** Read a module document's `resources:` block. Returns `[]` for an
31
+ * `Telo.Application` (which has no such block), for a library that declares
32
+ * none, and for a malformed entry — the document's own schema validation
33
+ * reports the shape against the precise `resources.<name>` path. */
34
+ export declare function readResourceInputs(moduleDoc: unknown): ResourceInput[];
35
+ /** The values an import supplies for a target library's declared inputs, keyed
36
+ * by entry name. Read off a `Telo.Import` (authored or desugared from an
37
+ * `imports:` entry). Values are `!ref` sentinels before Phase 2.5 and
38
+ * `{kind, name}` after it — this reader does not interpret them. */
39
+ export declare function readSuppliedResources(importDoc: unknown): Record<string, unknown>;
40
+ /** True when `manifest` is a synthesized kind-only declaration standing in for a
41
+ * library's `resources:` entry rather than a resource the author declared. */
42
+ export declare function isInjectedDeclaration(manifest: ResourceManifest | undefined): boolean;
43
+ /**
44
+ * Synthesize a kind-only declaration per `resources:` entry, in the declaring
45
+ * library's own scope.
46
+ *
47
+ * That model has to exist because a library's internals are validated in the
48
+ * library's own pass — the flattened application analysis drops the library doc
49
+ * — so with nothing behind `connection`, `!ref connection` would have nothing to
50
+ * resolve against.
51
+ *
52
+ * Kind-only is enough because it is already what a ref slot gets: a reading
53
+ * types its `status:` half from the kind, closed so a typo below it is
54
+ * `CEL_UNKNOWN_FIELD`, and leaves the flat half open, since no manifest declares
55
+ * what `snapshot()` returned. So `!ref connection` at a ref slot and
56
+ * `resources.connection.<field>` in CEL answer exactly as they do for a locally
57
+ * declared resource.
58
+ *
59
+ * The declaration is a stand-in, never an instantiation: the per-resource
60
+ * validation loop skips it (its kind is routinely an abstract, and its config is
61
+ * the importer's to supply), and the kernel's import controller filters it out
62
+ * of the manifests it registers, binding the borrowed instance under the name
63
+ * instead.
64
+ */
65
+ export declare function injectedDeclarations(moduleDoc: ResourceManifest, ownModule: string | undefined): ResourceManifest[];
66
+ /** How many times a library is instantiated in one application. `isolated` —
67
+ * the default, and what every published module was written against — gives
68
+ * each import declaration its own child scope with its own instances;
69
+ * `shared` makes the library a singleton every import resolves to. */
70
+ export type LibraryLifecycle = "isolated" | "shared";
71
+ /** Read a module document's `lifecycle:`. `Telo.Application` has a field of the
72
+ * same name with a different default and no reader; this is the LIBRARY
73
+ * question only, so it answers `isolated` for anything else. */
74
+ export declare function readLibraryLifecycle(moduleDoc: unknown): LibraryLifecycle;
75
+ //# sourceMappingURL=resource-input.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource-input.d.ts","sourceRoot":"","sources":["../src/resource-input.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD;;;;;;;;;;;;GAYG;AAEH,0BAA0B;AAC1B,MAAM,WAAW,aAAa;IAC5B;;kBAEc;IACd,IAAI,EAAE,MAAM,CAAC;IACb;;;;;mCAK+B;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAOD;;;qEAGqE;AACrE,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,OAAO,GAAG,aAAa,EAAE,CAgBtE;AAED;;;qEAGqE;AACrE,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAIjF;AAED;+EAC+E;AAC/E,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,SAAS,GAAG,OAAO,CAErF;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,gBAAgB,EAC3B,SAAS,EAAE,MAAM,GAAG,SAAS,GAC5B,gBAAgB,EAAE,CAgBpB;AAED;;;uEAGuE;AACvE,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG,QAAQ,CAAC;AAErD;;iEAEiE;AACjE,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,OAAO,GAAG,gBAAgB,CAIzE"}
@@ -0,0 +1,90 @@
1
+ /** Marker stamped on a synthesized kind-only declaration (see
2
+ * {@link injectedDeclarations}). Read through {@link isInjectedDeclaration} —
3
+ * never by testing the field. */
4
+ const INJECTED = "xTeloInjected";
5
+ /** Read a module document's `resources:` block. Returns `[]` for an
6
+ * `Telo.Application` (which has no such block), for a library that declares
7
+ * none, and for a malformed entry — the document's own schema validation
8
+ * reports the shape against the precise `resources.<name>` path. */
9
+ export function readResourceInputs(moduleDoc) {
10
+ const raw = moduleDoc?.resources;
11
+ if (!raw || typeof raw !== "object" || Array.isArray(raw))
12
+ return [];
13
+ const out = [];
14
+ for (const [name, value] of Object.entries(raw)) {
15
+ if (!value || typeof value !== "object" || Array.isArray(value))
16
+ continue;
17
+ const kind = value.kind;
18
+ if (typeof kind !== "string" || kind.length === 0)
19
+ continue;
20
+ const description = value.description;
21
+ out.push({
22
+ name,
23
+ kind,
24
+ ...(typeof description === "string" ? { description } : {}),
25
+ });
26
+ }
27
+ return out;
28
+ }
29
+ /** The values an import supplies for a target library's declared inputs, keyed
30
+ * by entry name. Read off a `Telo.Import` (authored or desugared from an
31
+ * `imports:` entry). Values are `!ref` sentinels before Phase 2.5 and
32
+ * `{kind, name}` after it — this reader does not interpret them. */
33
+ export function readSuppliedResources(importDoc) {
34
+ const raw = importDoc?.resources;
35
+ if (!raw || typeof raw !== "object" || Array.isArray(raw))
36
+ return {};
37
+ return raw;
38
+ }
39
+ /** True when `manifest` is a synthesized kind-only declaration standing in for a
40
+ * library's `resources:` entry rather than a resource the author declared. */
41
+ export function isInjectedDeclaration(manifest) {
42
+ return manifest?.metadata?.[INJECTED] === true;
43
+ }
44
+ /**
45
+ * Synthesize a kind-only declaration per `resources:` entry, in the declaring
46
+ * library's own scope.
47
+ *
48
+ * That model has to exist because a library's internals are validated in the
49
+ * library's own pass — the flattened application analysis drops the library doc
50
+ * — so with nothing behind `connection`, `!ref connection` would have nothing to
51
+ * resolve against.
52
+ *
53
+ * Kind-only is enough because it is already what a ref slot gets: a reading
54
+ * types its `status:` half from the kind, closed so a typo below it is
55
+ * `CEL_UNKNOWN_FIELD`, and leaves the flat half open, since no manifest declares
56
+ * what `snapshot()` returned. So `!ref connection` at a ref slot and
57
+ * `resources.connection.<field>` in CEL answer exactly as they do for a locally
58
+ * declared resource.
59
+ *
60
+ * The declaration is a stand-in, never an instantiation: the per-resource
61
+ * validation loop skips it (its kind is routinely an abstract, and its config is
62
+ * the importer's to supply), and the kernel's import controller filters it out
63
+ * of the manifests it registers, binding the borrowed instance under the name
64
+ * instead.
65
+ */
66
+ export function injectedDeclarations(moduleDoc, ownModule) {
67
+ const inputs = readResourceInputs(moduleDoc);
68
+ if (inputs.length === 0)
69
+ return [];
70
+ const meta = moduleDoc.metadata;
71
+ return inputs.map((input) => ({
72
+ kind: input.kind,
73
+ metadata: {
74
+ name: input.name,
75
+ ...(ownModule ? { module: ownModule } : {}),
76
+ source: meta?.source ?? "",
77
+ sourceLine: meta?.sourceLine ?? 0,
78
+ [INJECTED]: true,
79
+ },
80
+ }));
81
+ }
82
+ /** Read a module document's `lifecycle:`. `Telo.Application` has a field of the
83
+ * same name with a different default and no reader; this is the LIBRARY
84
+ * question only, so it answers `isolated` for anything else. */
85
+ export function readLibraryLifecycle(moduleDoc) {
86
+ const doc = moduleDoc;
87
+ if (doc?.kind !== "Telo.Library")
88
+ return "isolated";
89
+ return doc.lifecycle === "shared" ? "shared" : "isolated";
90
+ }
@@ -26,6 +26,8 @@
26
26
  * Browser-safe: no Node built-ins.
27
27
  */
28
28
  import { X_TELO_TYPE } from "@telorun/sdk";
29
+ /** The one annotation read from a DATA schema rather than a kind schema. */
30
+ declare const X_TELO_SENSITIVE: "x-telo-sensitive";
29
31
  import { ANNOTATION_KEYWORDS } from "./value-type-keyword.js";
30
32
  /** A keyword entry: the JSON Schema its VALUE must satisfy, carrying the title
31
33
  * and description completion and hover show. */
@@ -64,5 +66,18 @@ export declare function jsonSchemaKeywords(self: string): SchemaKeywords;
64
66
  * neither validation nor completion. Closing it needs the walkers to distinguish
65
67
  * a schema describing an annotation from an annotation, which nothing does yet.
66
68
  */
67
- export declare const TELO_SCHEMA_ANNOTATIONS: Record<(typeof ANNOTATION_KEYWORDS)[number] | typeof X_TELO_TYPE, Record<string, unknown>>;
69
+ export declare const TELO_SCHEMA_ANNOTATIONS: Record<Exclude<(typeof ANNOTATION_KEYWORDS)[number], typeof X_TELO_SENSITIVE> | typeof X_TELO_TYPE, Record<string, unknown>>;
70
+ /**
71
+ * Annotations that belong on a DATA schema — an `inputType` / `outputType`
72
+ * contract — rather than on a kind's own `schema:`.
73
+ *
74
+ * Split out because {@link TELO_SCHEMA_ANNOTATIONS} is offered only where the
75
+ * fragment is `KindSchema`, which is a kind's CONFIGURATION. `x-telo-sensitive`
76
+ * is read from the opposite place: the kernel resolves it off a bound contract,
77
+ * which stamps `JsonSchema7`. Offering it from the kind vocabulary alone put it
78
+ * on the one schema where nothing reads it and withheld it from the two where it
79
+ * is the whole mechanism.
80
+ */
81
+ export declare const TELO_DATA_SCHEMA_ANNOTATIONS: Record<typeof X_TELO_SENSITIVE, Record<string, unknown>>;
82
+ export {};
68
83
  //# sourceMappingURL=schema-keywords.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"schema-keywords.d.ts","sourceRoot":"","sources":["../src/schema-keywords.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAE9D;iDACiD;AACjD,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AASrE;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,CAuJ/D;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,uBAAuB,EAAE,MAAM,CAC1C,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,GAAG,OAAO,WAAW,EACzD,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAwJxB,CAAC"}
1
+ {"version":3,"file":"schema-keywords.d.ts","sourceRoot":"","sources":["../src/schema-keywords.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,4EAA4E;AAC5E,QAAA,MAAM,gBAAgB,EAAG,kBAA2B,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAE9D;iDACiD;AACjD,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AASrE;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,CAuJ/D;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,uBAAuB,EAAE,MAAM,CAMxC,OAAO,CAAC,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,EAAE,OAAO,gBAAgB,CAAC,GACtE,OAAO,WAAW,EACpB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAwJxB,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,4BAA4B,EAAE,MAAM,CAC/C,OAAO,gBAAgB,EACvB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAQxB,CAAC"}
@@ -25,6 +25,8 @@
25
25
  *
26
26
  * Browser-safe: no Node built-ins.
27
27
  */
28
+ /** The one annotation read from a DATA schema rather than a kind schema. */
29
+ const X_TELO_SENSITIVE = "x-telo-sensitive";
28
30
  /** A JSON type name, as `type:` accepts it — one, or a list (`[string, "null"]`,
29
31
  * the spelling `CEL_NULLABLE_ACCESS` guards). */
30
32
  const TYPE_NAME = {
@@ -342,3 +344,21 @@ export const TELO_SCHEMA_ANNOTATIONS = {
342
344
  type: "string",
343
345
  },
344
346
  };
347
+ /**
348
+ * Annotations that belong on a DATA schema — an `inputType` / `outputType`
349
+ * contract — rather than on a kind's own `schema:`.
350
+ *
351
+ * Split out because {@link TELO_SCHEMA_ANNOTATIONS} is offered only where the
352
+ * fragment is `KindSchema`, which is a kind's CONFIGURATION. `x-telo-sensitive`
353
+ * is read from the opposite place: the kernel resolves it off a bound contract,
354
+ * which stamps `JsonSchema7`. Offering it from the kind vocabulary alone put it
355
+ * on the one schema where nothing reads it and withheld it from the two where it
356
+ * is the whole mechanism.
357
+ */
358
+ export const TELO_DATA_SCHEMA_ANNOTATIONS = {
359
+ [X_TELO_SENSITIVE]: {
360
+ title: "Sensitive",
361
+ description: "This value is auth material or equivalent: carry it as `[redacted]` in trace payloads and on the debug wire rather than verbatim. Read only from a resource's declared `inputType` / `outputType`.",
362
+ type: "boolean",
363
+ },
364
+ };
@@ -237,6 +237,19 @@ export type ProjectionFailure = {
237
237
  readonly kind: string;
238
238
  readonly entries: string;
239
239
  }
240
+ /** The slot names a resource the module does not DECLARE — a library's
241
+ * `resources:` input, standing in for an instance its importer supplies. A
242
+ * projection is DECLARATION-derived, so it cannot be answered here at all;
243
+ * the stand-in has no entries, and reporting that would tell the library
244
+ * author their block is wrong when it is correct. Resolution moves to the
245
+ * injection site, where the real declaration is. Carried as its own reason
246
+ * rather than as `no-entries` so a consumer can tell "unanswerable here"
247
+ * from "answered, and empty". */
248
+ | {
249
+ readonly reason: "injected";
250
+ readonly pointer: string;
251
+ readonly name: string;
252
+ }
240
253
  /** An ENTRY of the projected declaration references a shape that could not be
241
254
  * read. Reported rather than dropped: the entry would silently vanish from
242
255
  * the projected row, so a consumer naming it would be told the property does
@@ -1 +1 @@
1
- {"version":3,"file":"schema-projection.d.ts","sourceRoot":"","sources":["../src/schema-projection.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schema-projection.d.ts","sourceRoot":"","sources":["../src/schema-projection.ts"],"names":[],"mappings":"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"}
@@ -35,6 +35,7 @@
35
35
  * derivation can reach.
36
36
  */
37
37
  import { isRefSentinel } from "@telorun/templating";
38
+ import { isInjectedDeclaration } from "./resource-input.js";
38
39
  function isObject(value) {
39
40
  return !!value && typeof value === "object" && !Array.isArray(value);
40
41
  }
@@ -378,6 +379,9 @@ function refTarget(value, scope, pointer) {
378
379
  if ("ambiguous" in found)
379
380
  return { reason: "ambiguous", pointer, name };
380
381
  const manifest = found.manifest;
382
+ if (isInjectedDeclaration(manifest)) {
383
+ return { reason: "injected", pointer, name };
384
+ }
381
385
  if (typeof manifest.kind !== "string")
382
386
  return { reason: "unresolved", pointer, name };
383
387
  const definition = scope.resolveDefinition(manifest.kind);
@@ -403,6 +407,9 @@ export function describeProjectionFailure(failure) {
403
407
  : `'${failure.pointer}' does not hold a reference, so there is no declaration to project.`;
404
408
  case "unresolved":
405
409
  return `'${failure.pointer}' references '${failure.name}', which resolves to no resource.`;
410
+ case "injected":
411
+ return (`'${failure.pointer}' references '${failure.name}', a resource input this module does ` +
412
+ `not declare — its entries belong to whoever supplies it.`);
406
413
  case "ambiguous":
407
414
  return (`'${failure.pointer}' references '${failure.name}', which matches more than one resource ` +
408
415
  `in scope. Rename one of them so the reference names exactly one declaration.`);
@@ -19,7 +19,12 @@ export declare const DEPENDENCY_GRAPH_SKIP_KINDS: ReadonlySet<string>;
19
19
  /** Skipped by `!ref` sentinel resolution: kinds whose bodies are
20
20
  * blueprints or import-time metadata, not resource instances with
21
21
  * user-referenced ref slots. Mirrors `REF_VALIDATION_SKIP_KINDS` but
22
- * also drops Telo.Import (its `source` isn't a ref slot, and walking
23
- * the field map on it is pointless since there's no registered kind). */
22
+ * also lists Telo.Import, because walking its field map is pointless
23
+ * there is no registered kind behind it.
24
+ *
25
+ * `resolveRefSentinels` reaches Telo.Import's `resources:` block AHEAD of this
26
+ * set, deliberately: those are the references an importer supplies for a
27
+ * library's declared inputs, and they resolve exactly like any other. Nothing
28
+ * else on the document is a reference slot, so only that subtree is walked. */
24
29
  export declare const REF_RESOLUTION_SKIP_KINDS: ReadonlySet<string>;
25
30
  //# sourceMappingURL=system-kinds.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"system-kinds.d.ts","sourceRoot":"","sources":["../src/system-kinds.ts"],"names":[],"mappings":"AAAA;;;;sEAIsE;AAEtE;;;;;;0CAM0C;AAC1C,eAAO,MAAM,yBAAyB,EAAE,WAAW,CAAC,MAAM,CAGxD,CAAC;AAEH;;;4CAG4C;AAC5C,eAAO,MAAM,2BAA2B,EAAE,WAAW,CAAC,MAAM,CAG1D,CAAC;AAEH;;;;0EAI0E;AAC1E,eAAO,MAAM,yBAAyB,EAAE,WAAW,CAAC,MAAM,CAIxD,CAAC"}
1
+ {"version":3,"file":"system-kinds.d.ts","sourceRoot":"","sources":["../src/system-kinds.ts"],"names":[],"mappings":"AAAA;;;;sEAIsE;AAEtE;;;;;;0CAM0C;AAC1C,eAAO,MAAM,yBAAyB,EAAE,WAAW,CAAC,MAAM,CAGxD,CAAC;AAEH;;;4CAG4C;AAC5C,eAAO,MAAM,2BAA2B,EAAE,WAAW,CAAC,MAAM,CAG1D,CAAC;AAEH;;;;;;;;;gFASgF;AAChF,eAAO,MAAM,yBAAyB,EAAE,WAAW,CAAC,MAAM,CAIxD,CAAC"}
@@ -25,8 +25,13 @@ export const DEPENDENCY_GRAPH_SKIP_KINDS = new Set([
25
25
  /** Skipped by `!ref` sentinel resolution: kinds whose bodies are
26
26
  * blueprints or import-time metadata, not resource instances with
27
27
  * user-referenced ref slots. Mirrors `REF_VALIDATION_SKIP_KINDS` but
28
- * also drops Telo.Import (its `source` isn't a ref slot, and walking
29
- * the field map on it is pointless since there's no registered kind). */
28
+ * also lists Telo.Import, because walking its field map is pointless
29
+ * there is no registered kind behind it.
30
+ *
31
+ * `resolveRefSentinels` reaches Telo.Import's `resources:` block AHEAD of this
32
+ * set, deliberately: those are the references an importer supplies for a
33
+ * library's declared inputs, and they resolve exactly like any other. Nothing
34
+ * else on the document is a reference slot, so only that subtree is walked. */
30
35
  export const REF_RESOLUTION_SKIP_KINDS = new Set([
31
36
  "Telo.Definition",
32
37
  "Telo.Abstract",
@@ -1,3 +1,3 @@
1
1
  /** The surface generation this analyzer implements. */
2
- export declare const TELO_SURFACE_VERSION = "0.82.1";
2
+ export declare const TELO_SURFACE_VERSION = "0.84.0";
3
3
  //# sourceMappingURL=telo-version.d.ts.map
@@ -5,4 +5,4 @@
5
5
  // its release identity, this is the scale a module's `requires.telo` range is
6
6
  // written against, and every kernel in every language reports the same scale.
7
7
  /** The surface generation this analyzer implements. */
8
- export const TELO_SURFACE_VERSION = "0.82.1";
8
+ export const TELO_SURFACE_VERSION = "0.84.0";
@@ -0,0 +1,50 @@
1
+ import type { ResourceDefinition, ResourceManifest } from "@telorun/sdk";
2
+ import type { AliasResolver } from "./alias-resolver.js";
3
+ import type { DefinitionRegistry } from "./definition-registry.js";
4
+ import type { ModuleScopes } from "./alias-resolver.js";
5
+ /**
6
+ * A `Telo.Definition`'s `resources:` entries — the bodies a kind writes for
7
+ * ANOTHER kind — read as what they are: declarations of that other kind.
8
+ *
9
+ * The consequence is the whole point. CEL inside such a body used to be typed in
10
+ * the ENCLOSING definition's scope, against one fixed permissive context
11
+ * (`self`, plus open `request` / `result` / `steps` / `error`). So `inputs` and
12
+ * `item` were undefined wherever the nested kind declares them, while `error`
13
+ * was offered everywhere regardless of whether a `catch:` was in scope — a body
14
+ * of more than one dispatch was unwritable, which is why no standard-library
15
+ * template has one.
16
+ *
17
+ * Resolving through the nested kind's OWN annotations — its `x-telo-context`
18
+ * regions, its step body, its error branches — makes a nested declaration answer
19
+ * exactly as the same declaration written at the top level does, with `self`
20
+ * merged in from the enclosing definition's `schema:`.
21
+ *
22
+ * Browser-safe.
23
+ */
24
+ export interface TemplateBody {
25
+ /** Concrete path prefix of this entry (`resources[0]`), as CEL sites are
26
+ * addressed. */
27
+ prefix: string;
28
+ /** JSONPath prefix for context scopes (`$.resources[0]`). */
29
+ scopePrefix: string;
30
+ manifest: ResourceManifest;
31
+ definition: ResourceDefinition | undefined;
32
+ }
33
+ /** The template bodies a manifest declares — empty for anything that is not a
34
+ * `Telo.Definition` with a `resources:` array. */
35
+ export declare function templateBodies(m: ResourceManifest, registry: DefinitionRegistry, aliases: AliasResolver | undefined, scopes: ModuleScopes | undefined): TemplateBody[];
36
+ /** True when a CEL path lies at or inside a body's own subtree. */
37
+ export declare function pathInBody(path: string, prefix: string): boolean;
38
+ /** The body a CEL path belongs to, or undefined for a path in the definition's
39
+ * own fields. Generic over what the caller keyed to each body — the resolver
40
+ * carries a step context and an error map, the visitor carries the schema. */
41
+ export declare function bodyForPath<T extends {
42
+ prefix: string;
43
+ }>(bodies: readonly T[], path: string): T | undefined;
44
+ /** `self` is in scope throughout a template body — it is how the body reaches
45
+ * the configuration its enclosing kind was given — so it is merged into every
46
+ * context the nested kind declares, which knows nothing about it. Merged UNDER
47
+ * the nested kind's own properties: a name the nested kind declares wins, since
48
+ * that is what its controller will bind. */
49
+ export declare function withTemplateSelf(contextSchema: Record<string, any>): Record<string, any>;
50
+ //# sourceMappingURL=template-body.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template-body.d.ts","sourceRoot":"","sources":["../src/template-body.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,YAAY;IAC3B;qBACiB;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,6DAA6D;IAC7D,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,UAAU,EAAE,kBAAkB,GAAG,SAAS,CAAC;CAC5C;AAED;mDACmD;AACnD,wBAAgB,cAAc,CAC5B,CAAC,EAAE,gBAAgB,EACnB,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,EAAE,aAAa,GAAG,SAAS,EAClC,MAAM,EAAE,YAAY,GAAG,SAAS,GAC/B,YAAY,EAAE,CA8BhB;AAED,mEAAmE;AACnE,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAIhE;AAED;;+EAE+E;AAC/E,wBAAgB,WAAW,CAAC,CAAC,SAAS;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,EACtD,MAAM,EAAE,SAAS,CAAC,EAAE,EACpB,IAAI,EAAE,MAAM,GACX,CAAC,GAAG,SAAS,CAEf;AAED;;;;6CAI6C;AAC7C,wBAAgB,gBAAgB,CAAC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAQxF"}
@@ -0,0 +1,58 @@
1
+ /** The template bodies a manifest declares — empty for anything that is not a
2
+ * `Telo.Definition` with a `resources:` array. */
3
+ export function templateBodies(m, registry, aliases, scopes) {
4
+ if (m.kind !== "Telo.Definition")
5
+ return [];
6
+ const bodies = m.resources;
7
+ if (!Array.isArray(bodies))
8
+ return [];
9
+ // A nested kind is written through the alias scope of the module that DECLARED
10
+ // the definition, never the consumer's — the same rule every other kind
11
+ // resolution in a forwarded manifest follows.
12
+ const ownModule = m.metadata?.module;
13
+ const scope = (ownModule && scopes && !scopes.rootModules.has(ownModule)
14
+ ? scopes.aliasesByModule.get(ownModule)
15
+ : undefined) ?? aliases;
16
+ const out = [];
17
+ for (let i = 0; i < bodies.length; i++) {
18
+ const body = bodies[i];
19
+ if (!body || typeof body !== "object" || Array.isArray(body))
20
+ continue;
21
+ const kind = body.kind;
22
+ if (typeof kind !== "string")
23
+ continue;
24
+ const canonical = scope?.resolveKind(kind);
25
+ const definition = registry.resolve(kind) ?? (canonical ? registry.resolve(canonical) : undefined);
26
+ out.push({
27
+ prefix: `resources[${i}]`,
28
+ scopePrefix: `$.resources[${i}]`,
29
+ manifest: body,
30
+ definition,
31
+ });
32
+ }
33
+ return out;
34
+ }
35
+ /** True when a CEL path lies at or inside a body's own subtree. */
36
+ export function pathInBody(path, prefix) {
37
+ return (path === prefix || path.startsWith(`${prefix}.`) || path.startsWith(`${prefix}[`));
38
+ }
39
+ /** The body a CEL path belongs to, or undefined for a path in the definition's
40
+ * own fields. Generic over what the caller keyed to each body — the resolver
41
+ * carries a step context and an error map, the visitor carries the schema. */
42
+ export function bodyForPath(bodies, path) {
43
+ return bodies.find((b) => pathInBody(path, b.prefix));
44
+ }
45
+ /** `self` is in scope throughout a template body — it is how the body reaches
46
+ * the configuration its enclosing kind was given — so it is merged into every
47
+ * context the nested kind declares, which knows nothing about it. Merged UNDER
48
+ * the nested kind's own properties: a name the nested kind declares wins, since
49
+ * that is what its controller will bind. */
50
+ export function withTemplateSelf(contextSchema) {
51
+ return {
52
+ ...contextSchema,
53
+ properties: {
54
+ self: { "x-telo-context-from-root": "schema" },
55
+ ...(contextSchema.properties ?? {}),
56
+ },
57
+ };
58
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"validate-cel-context.d.ts","sourceRoot":"","sources":["../src/validate-cel-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AAatF,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAG3E,MAAM,WAAW,kBAAkB;IACjC;mEAC+D;IAC/D,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACnC;;kDAE8C;IAC9C,IAAI,CAAC,EAAE;QACL,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,CAAC;KACxD,CAAC;IACF,OAAO,CAAC,EAAE;QACR,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;KAC/C,CAAC;IACF,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC;CACtC;AA4CD,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,OAAO,EACd,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,EACnC,QAAQ,GAAE,WAAW,CAAC,MAAM,CAAa,GACxC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,CA0EjC;AAyID;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACjC,IAAI,CAAC,EAAE,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,GAChD,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAyKrB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC5B,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAQrB;AAWD;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,IAAI,SAAM,GACT,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAAE,CAAC,CAGvD"}
1
+ {"version":3,"file":"validate-cel-context.d.ts","sourceRoot":"","sources":["../src/validate-cel-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AAatF,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AA2B3E,MAAM,WAAW,kBAAkB;IACjC;mEAC+D;IAC/D,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACnC;;kDAE8C;IAC9C,IAAI,CAAC,EAAE;QACL,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,CAAC;KACxD,CAAC;IACF,OAAO,CAAC,EAAE;QACR,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;KAC/C,CAAC;IACF,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC;CACtC;AA4CD,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,OAAO,EACd,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,EACnC,QAAQ,GAAE,WAAW,CAAC,MAAM,CAAa,GACxC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,CA0EjC;AAyID;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACjC,IAAI,CAAC,EAAE,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,GAChD,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAoLrB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC5B,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAuBrB;AAqBD;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,IAAI,SAAM,GACT,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAAE,CAAC,CAGvD"}
@@ -7,6 +7,29 @@ import { withRefSlotsAsReadings } from "./ref-slot-reading.js";
7
7
  // question in one place. Re-exported: this module is where every existing
8
8
  // consumer imports them from.
9
9
  export { extractCelRegionScopes, pathMatchesScope } from "./eval-paths.js";
10
+ /** True when a node's value is decided at load or dispatch rather than written
11
+ * — a tagged sentinel (`!cel`, `!sql`, an embed) or an already-compiled value.
12
+ * A schema position holding one declares a shape nothing static can read. */
13
+ function isDynamicNode(value) {
14
+ if (!value || typeof value !== "object")
15
+ return false;
16
+ const node = value;
17
+ return node.__tagged === true || node.__compiled !== undefined;
18
+ }
19
+ /** Replace every dynamically-valued property with an OPEN schema, so the name is
20
+ * in scope with its members unconstrained. */
21
+ function openDynamicProperties(props) {
22
+ if (!props || typeof props !== "object")
23
+ return props;
24
+ let out;
25
+ for (const [key, value] of Object.entries(props)) {
26
+ if (!isDynamicNode(value))
27
+ continue;
28
+ out ??= { ...props };
29
+ out[key] = {};
30
+ }
31
+ return out ?? props;
32
+ }
10
33
  /**
11
34
  * Resolve a type field value (string name, inline type, or raw schema) to a JSON Schema.
12
35
  * - String: look up the named type in allManifests (Type.JsonSchema resources)
@@ -298,8 +321,19 @@ export function resolveContextAnnotations(schema, manifestItem, opts) {
298
321
  // to be resolved first: the standard library writes it as the inline
299
322
  // `{ kind: Type.JsonSchema, schema: … }` wrapper, so merging it verbatim
300
323
  // would type the variable as `{ kind, schema }` instead of its properties.
324
+ // The navigated node — or one of the properties in it — may itself be an
325
+ // expression: a route whose `request.schema.body` is `!cel "self.model.schema"`
326
+ // declares a body whose SHAPE is only known once the template is
327
+ // instantiated. Such a name types as OPEN rather than as nothing, and a
328
+ // wholly dynamic map leaves the whole node open. Resolving it to nothing
329
+ // reports `request.body` as undefined, which blames the reader for the
330
+ // writer's dynamism — the same posture a rule takes when a value it reads
331
+ // is dynamic: skip the judgement, never invert it.
332
+ if (isDynamicNode(navigated)) {
333
+ return { ...schema, properties: { ...(schema.properties ?? {}) }, additionalProperties: true };
334
+ }
301
335
  const asType = resolveTypeFieldToSchema(navigated, allManifests ?? []);
302
- const resolved = asType?.properties ?? navigated;
336
+ const resolved = openDynamicProperties(asType?.properties ?? navigated);
303
337
  const required = Array.isArray(asType?.required) ? asType.required : undefined;
304
338
  return {
305
339
  ...schema,
@@ -438,14 +472,40 @@ export function resolveContextAnnotations(schema, manifestItem, opts) {
438
472
  */
439
473
  export function getManifestItem(exprPath, scope, manifest) {
440
474
  const stripped = scope.startsWith("$.") ? scope.slice(2) : scope;
441
- const wildcardIdx = stripped.indexOf("[*]");
442
- if (wildcardIdx === -1)
443
- return manifest;
444
- const arrayProp = stripped.slice(0, wildcardIdx); // e.g. "routes"
445
- const m = exprPath.match(new RegExp(`^${arrayProp}\\[(\\d+)\\]`));
446
- if (!m)
475
+ const parts = stripped.split("[*]");
476
+ if (parts.length === 1)
447
477
  return manifest;
448
- return manifest[arrayProp]?.[Number(m[1])] ?? manifest;
478
+ // Resolve each `[*]` against the concrete index the expression path carries at
479
+ // the same position, accumulating up to the LAST wildcard: that node is the
480
+ // per-scope item (`routes[2]`), which is what `x-telo-context-from` navigates
481
+ // from. Built by walking the pattern rather than by a regex over the scope —
482
+ // a scope is a path, not a pattern, and its own `[4]` segments are regex
483
+ // character classes, which is what silently made every nested scope resolve
484
+ // to the whole document instead of the item.
485
+ let remaining = exprPath;
486
+ let concrete = "";
487
+ for (let i = 0; i < parts.length - 1; i++) {
488
+ const part = parts[i];
489
+ if (!remaining.startsWith(part))
490
+ return manifest;
491
+ remaining = remaining.slice(part.length);
492
+ const index = remaining.match(/^\[(\d+)\]/);
493
+ if (!index)
494
+ return manifest;
495
+ remaining = remaining.slice(index[0].length);
496
+ concrete += `${part}${index[0]}`;
497
+ }
498
+ return navigateConcretePath(manifest, concrete) ?? manifest;
499
+ }
500
+ /** Walk a concrete dotted path with `[N]` indices (`resources[4].routes[2]`). */
501
+ function navigateConcretePath(root, path) {
502
+ let cur = root;
503
+ for (const segment of path.match(/[^.[\]]+/g) ?? []) {
504
+ if (cur === null || typeof cur !== "object")
505
+ return undefined;
506
+ cur = cur[segment];
507
+ }
508
+ return cur;
449
509
  }
450
510
  function navigatePath(obj, segments) {
451
511
  let cur = obj;
@@ -1 +1 @@
1
- {"version":3,"file":"validate-extends.d.ts","sourceRoot":"","sources":["../src/validate-extends.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAsB,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAEnE,OAAO,EAAsB,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAC;AA8BzE,wBAAgB,eAAe,CAC7B,SAAS,EAAE,gBAAgB,EAAE,EAC7B,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,EAAE,aAAa,GACrB,kBAAkB,EAAE,CA4JtB"}
1
+ {"version":3,"file":"validate-extends.d.ts","sourceRoot":"","sources":["../src/validate-extends.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAsB,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAQnE,OAAO,EAAsB,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAiCzE,wBAAgB,eAAe,CAC7B,SAAS,EAAE,gBAAgB,EAAE,EAC7B,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,EAAE,aAAa,GACrB,kBAAkB,EAAE,CAqMtB"}