@telorun/analyzer 0.73.0 → 0.74.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/analyzer.d.ts.map +1 -1
- package/dist/analyzer.js +26 -7
- package/dist/artifact-axes.d.ts +14 -0
- package/dist/artifact-axes.d.ts.map +1 -0
- package/dist/artifact-axes.js +12 -0
- package/dist/artifact-layer-index.d.ts +2 -2
- package/dist/artifact-layer-index.d.ts.map +1 -1
- package/dist/artifact-layer-index.js +9 -4
- package/dist/artifact-selector.d.ts +47 -21
- package/dist/artifact-selector.d.ts.map +1 -1
- package/dist/artifact-selector.js +85 -16
- package/dist/builtins.d.ts.map +1 -1
- package/dist/builtins.js +73 -16
- package/dist/call-graph.d.ts +12 -1
- package/dist/call-graph.d.ts.map +1 -1
- package/dist/call-graph.js +22 -0
- package/dist/catch-scope.js +1 -1
- package/dist/forwarded-declaration.d.ts +26 -0
- package/dist/forwarded-declaration.d.ts.map +1 -0
- package/dist/forwarded-declaration.js +31 -0
- package/dist/index.d.ts +9 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/kernel-globals.d.ts.map +1 -1
- package/dist/kernel-globals.js +21 -5
- package/dist/module-alias-scope.d.ts +11 -0
- package/dist/module-alias-scope.d.ts.map +1 -1
- package/dist/module-alias-scope.js +10 -0
- package/dist/module-file-claims.d.ts +17 -1
- package/dist/module-file-claims.d.ts.map +1 -1
- package/dist/module-file-claims.js +38 -3
- package/dist/module-named-files.d.ts +72 -0
- package/dist/module-named-files.d.ts.map +1 -0
- package/dist/module-named-files.js +115 -0
- package/dist/native-entries.d.ts +83 -0
- package/dist/native-entries.d.ts.map +1 -0
- package/dist/native-entries.js +169 -0
- package/dist/normalize-inline-resources.d.ts +41 -13
- package/dist/normalize-inline-resources.d.ts.map +1 -1
- package/dist/normalize-inline-resources.js +236 -54
- package/dist/reference-field-map.d.ts +59 -1
- package/dist/reference-field-map.d.ts.map +1 -1
- package/dist/reference-field-map.js +200 -34
- package/dist/release/payload-digest.d.ts +2 -1
- package/dist/release/payload-digest.d.ts.map +1 -1
- package/dist/release/payload-digest.js +2 -1
- package/dist/resolve-ref-sentinels.d.ts.map +1 -1
- package/dist/resolve-ref-sentinels.js +8 -5
- package/dist/resolve-throws-union.d.ts +25 -4
- package/dist/resolve-throws-union.d.ts.map +1 -1
- package/dist/resolve-throws-union.js +62 -32
- package/dist/resolve-zone-requirements.d.ts.map +1 -1
- package/dist/resolve-zone-requirements.js +2 -1
- package/dist/rewrite-synthetic-origins.d.ts +6 -1
- package/dist/rewrite-synthetic-origins.d.ts.map +1 -1
- package/dist/rewrite-synthetic-origins.js +107 -13
- package/dist/schema-compat.d.ts.map +1 -1
- package/dist/schema-compat.js +18 -5
- package/dist/schema-walk.d.ts +47 -13
- package/dist/schema-walk.d.ts.map +1 -1
- package/dist/schema-walk.js +150 -30
- package/dist/scope-declarations.d.ts +59 -0
- package/dist/scope-declarations.d.ts.map +1 -0
- package/dist/scope-declarations.js +45 -0
- package/dist/source-entries.d.ts +119 -0
- package/dist/source-entries.d.ts.map +1 -0
- package/dist/source-entries.js +349 -0
- package/dist/step-bodies.d.ts +24 -0
- package/dist/step-bodies.d.ts.map +1 -0
- package/dist/step-bodies.js +28 -0
- package/dist/telo-version.d.ts +1 -1
- package/dist/telo-version.js +1 -1
- package/dist/validate-cel-context.d.ts.map +1 -1
- package/dist/validate-cel-context.js +3 -2
- package/dist/validate-module-artifact.d.ts +4 -2
- package/dist/validate-module-artifact.d.ts.map +1 -1
- package/dist/validate-module-artifact.js +43 -4
- package/dist/validate-native-entries.d.ts +15 -0
- package/dist/validate-native-entries.d.ts.map +1 -0
- package/dist/validate-native-entries.js +103 -0
- package/dist/validate-observed-state.d.ts +7 -1
- package/dist/validate-observed-state.d.ts.map +1 -1
- package/dist/validate-observed-state.js +24 -6
- package/dist/validate-reference-forms.d.ts.map +1 -1
- package/dist/validate-reference-forms.js +2 -2
- package/dist/validate-references.d.ts.map +1 -1
- package/dist/validate-references.js +11 -5
- package/dist/validate-scope-reach.d.ts +31 -0
- package/dist/validate-scope-reach.d.ts.map +1 -0
- package/dist/validate-scope-reach.js +180 -0
- package/dist/validate-source-entries.d.ts +16 -0
- package/dist/validate-source-entries.d.ts.map +1 -0
- package/dist/validate-source-entries.js +90 -0
- package/dist/validate-throws-coverage.d.ts.map +1 -1
- package/dist/validate-throws-coverage.js +21 -39
- package/dist/value-type-keyword.d.ts +22 -5
- package/dist/value-type-keyword.d.ts.map +1 -1
- package/dist/value-type-keyword.js +16 -7
- package/package.json +3 -3
- package/src/analyzer.ts +33 -9
- package/src/artifact-axes.ts +24 -0
- package/src/artifact-layer-index.ts +9 -6
- package/src/artifact-selector.ts +110 -35
- package/src/builtins.ts +75 -16
- package/src/call-graph.ts +30 -0
- package/src/catch-scope.ts +1 -1
- package/src/forwarded-declaration.ts +32 -0
- package/src/index.ts +36 -1
- package/src/kernel-globals.ts +28 -5
- package/src/migrations/CLAUDE.md +35 -0
- package/src/module-alias-scope.ts +17 -0
- package/src/module-file-claims.ts +63 -4
- package/src/module-named-files.ts +162 -0
- package/src/native-entries.ts +227 -0
- package/src/normalize-inline-resources.ts +326 -70
- package/src/reference-field-map.ts +257 -52
- package/src/release/CLAUDE.md +32 -0
- package/src/release/payload-digest.ts +2 -1
- package/src/resolve-ref-sentinels.ts +7 -6
- package/src/resolve-throws-union.ts +87 -32
- package/src/resolve-zone-requirements.ts +2 -1
- package/src/rewrite-synthetic-origins.ts +107 -16
- package/src/schema-compat.ts +18 -4
- package/src/schema-walk.ts +162 -34
- package/src/scope-declarations.ts +98 -0
- package/src/source-entries.ts +502 -0
- package/src/step-bodies.ts +55 -0
- package/src/telo-version.ts +1 -1
- package/src/validate-cel-context.ts +3 -2
- package/src/validate-module-artifact.ts +46 -3
- package/src/validate-native-entries.ts +147 -0
- package/src/validate-observed-state.ts +36 -7
- package/src/validate-reference-forms.ts +2 -3
- package/src/validate-references.ts +10 -6
- package/src/validate-scope-reach.ts +213 -0
- package/src/validate-source-entries.ts +120 -0
- package/src/validate-throws-coverage.ts +24 -31
- package/src/value-type-keyword.ts +35 -9
|
@@ -1,5 +1,23 @@
|
|
|
1
|
+
import { resolveLocalRef } from "./manifest-navigation.js";
|
|
1
2
|
import { readRefSlot } from "./ref-slot.js";
|
|
3
|
+
import { readStepSlot } from "./step-slot.js";
|
|
2
4
|
export { readRefSlot, isRefSlot, hasDeclaredUse } from "./ref-slot.js";
|
|
5
|
+
/** The slot an entry records, as `readRefSlot` read it. */
|
|
6
|
+
export function refSlotOfEntry(entry) {
|
|
7
|
+
const slot = {
|
|
8
|
+
kinds: entry.refs,
|
|
9
|
+
uses: entry.uses,
|
|
10
|
+
inline: entry.inline === true,
|
|
11
|
+
valueBranches: entry.valueBranches ?? [],
|
|
12
|
+
};
|
|
13
|
+
if (entry.useCases)
|
|
14
|
+
slot.useCases = entry.useCases;
|
|
15
|
+
if (entry.inputs !== undefined)
|
|
16
|
+
slot.inputs = entry.inputs;
|
|
17
|
+
if (entry.throwsThrough)
|
|
18
|
+
slot.throwsThrough = true;
|
|
19
|
+
return slot;
|
|
20
|
+
}
|
|
3
21
|
export function isRefEntry(entry) {
|
|
4
22
|
return "refs" in entry;
|
|
5
23
|
}
|
|
@@ -121,9 +139,10 @@ export function resolveFieldValues(obj, path) {
|
|
|
121
139
|
*/
|
|
122
140
|
export function buildReferenceFieldMap(schema) {
|
|
123
141
|
const map = new Map();
|
|
142
|
+
const sink = injectionSink(map);
|
|
124
143
|
if (schema.properties) {
|
|
125
144
|
for (const [key, propSchema] of Object.entries(schema.properties)) {
|
|
126
|
-
traverseNode(propSchema, key,
|
|
145
|
+
traverseNode(propSchema, key, sink, schema);
|
|
127
146
|
}
|
|
128
147
|
}
|
|
129
148
|
return map;
|
|
@@ -140,32 +159,175 @@ export function collectRefs(node) {
|
|
|
140
159
|
* hid behind the schema-from indirection. */
|
|
141
160
|
export function buildFieldMapAtPath(schema, pathPrefix) {
|
|
142
161
|
const map = new Map();
|
|
143
|
-
traverseNode(schema, pathPrefix, map, schema);
|
|
162
|
+
traverseNode(schema, pathPrefix, injectionSink(map), schema);
|
|
144
163
|
return map;
|
|
145
164
|
}
|
|
146
|
-
|
|
147
|
-
|
|
165
|
+
const drivenSlotMaps = new WeakMap();
|
|
166
|
+
/** The resource envelope: present on every resource document, and never
|
|
167
|
+
* configuration a kind's root `additionalProperties` describes. */
|
|
168
|
+
const RESOURCE_ENVELOPE_KEYS = ["kind", "metadata"];
|
|
169
|
+
/**
|
|
170
|
+
* Every slot through which a resource of this schema DRIVES another — the
|
|
171
|
+
* reference field map's own traversal, plus what a dispatch analysis needs and
|
|
172
|
+
* the injection surface must not have:
|
|
173
|
+
*
|
|
174
|
+
* - local `$ref` is followed, resolved against the root. The injection map
|
|
175
|
+
* stops there so a step's `invoke` never becomes an injection site; this map
|
|
176
|
+
* stops AT a step body instead, which removes that reason. A reference back
|
|
177
|
+
* to a node already on the descent is recorded as a back-edge rather than
|
|
178
|
+
* unrolled, so a recursive shape stays finite here and is followed as deep as
|
|
179
|
+
* the data goes by `forEachDrivenSlot`;
|
|
180
|
+
* - a step body is recorded and not descended — the step traversal owns
|
|
181
|
+
* everything below it;
|
|
182
|
+
* - the root's own variant branches and `additionalProperties` are walked, not
|
|
183
|
+
* only its `properties`;
|
|
184
|
+
* - a path keeps EVERY slot any branch declares there, where the injection map
|
|
185
|
+
* keeps the last one written (see {@link DrivenPath.refs});
|
|
186
|
+
* - each `{}` path records the keys its `additionalProperties` does not cover.
|
|
187
|
+
*
|
|
188
|
+
* Shared by every throws question (a kind's `inherit` union, a scope list's
|
|
189
|
+
* denominator, catch-scope enclosure, and whether `inherit` is legal at all),
|
|
190
|
+
* so none can reach a slot another cannot. Memoized per schema object.
|
|
191
|
+
*/
|
|
192
|
+
export function buildDrivenSlotMap(schema) {
|
|
193
|
+
const cached = drivenSlotMaps.get(schema);
|
|
194
|
+
if (cached)
|
|
195
|
+
return cached;
|
|
196
|
+
const slots = { paths: new Map(), declaredKeys: new Map(), drives: false };
|
|
197
|
+
traverseNode(schema, "", drivenSink(slots), schema);
|
|
198
|
+
drivenSlotMaps.set(schema, slots);
|
|
199
|
+
return slots;
|
|
200
|
+
}
|
|
201
|
+
const joinPath = (path, key) => (path ? `${path}.${key}` : key);
|
|
202
|
+
/** The injection map: one entry per path, the last one written. Step bodies,
|
|
203
|
+
* back-edges and map-value keys are the driven map's alone. */
|
|
204
|
+
function injectionSink(map) {
|
|
205
|
+
return {
|
|
206
|
+
driven: false,
|
|
207
|
+
ref: (path, entry) => {
|
|
208
|
+
map.set(path, entry);
|
|
209
|
+
},
|
|
210
|
+
stop: (path, entry) => {
|
|
211
|
+
map.set(path, entry);
|
|
212
|
+
},
|
|
213
|
+
step: () => { },
|
|
214
|
+
recurse: () => { },
|
|
215
|
+
mapValue: () => { },
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
function drivenSink(slots) {
|
|
219
|
+
const recorded = new Map();
|
|
220
|
+
const at = (path) => {
|
|
221
|
+
let entry = slots.paths.get(path);
|
|
222
|
+
if (!entry) {
|
|
223
|
+
entry = { refs: [], steps: [], recurse: [] };
|
|
224
|
+
slots.paths.set(path, entry);
|
|
225
|
+
}
|
|
226
|
+
return entry;
|
|
227
|
+
};
|
|
228
|
+
// One schema node reached twice at one path (two branches `$ref`-ing one
|
|
229
|
+
// definition) is one slot.
|
|
230
|
+
const firstTime = (path, node) => {
|
|
231
|
+
let nodes = recorded.get(path);
|
|
232
|
+
if (!nodes)
|
|
233
|
+
recorded.set(path, (nodes = new Set()));
|
|
234
|
+
if (nodes.has(node))
|
|
235
|
+
return false;
|
|
236
|
+
nodes.add(node);
|
|
237
|
+
return true;
|
|
238
|
+
};
|
|
239
|
+
return {
|
|
240
|
+
driven: true,
|
|
241
|
+
ref: (path, entry, node) => {
|
|
242
|
+
if (!firstTime(path, node))
|
|
243
|
+
return;
|
|
244
|
+
at(path).refs.push(entry);
|
|
245
|
+
slots.drives = true;
|
|
246
|
+
},
|
|
247
|
+
stop: () => { },
|
|
248
|
+
step: (path, step, node) => {
|
|
249
|
+
if (!firstTime(path, node))
|
|
250
|
+
return;
|
|
251
|
+
at(path).steps.push(step);
|
|
252
|
+
slots.drives = true;
|
|
253
|
+
},
|
|
254
|
+
recurse: (path, to) => {
|
|
255
|
+
const entry = at(path);
|
|
256
|
+
if (!entry.recurse.includes(to))
|
|
257
|
+
entry.recurse.push(to);
|
|
258
|
+
},
|
|
259
|
+
mapValue: (mapPath, declared) => {
|
|
260
|
+
const previous = slots.declaredKeys.get(mapPath);
|
|
261
|
+
slots.declaredKeys.set(mapPath, new Set(previous ? declared.filter((key) => previous.has(key)) : declared));
|
|
262
|
+
},
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
/** Follow a local `$ref` in driven mode. `onStack` maps each node on the
|
|
266
|
+
* current descent to the path it was entered at: re-entering one records a
|
|
267
|
+
* back-edge to that path, and a cycle that made no structural progress (same
|
|
268
|
+
* path) records nothing, since its body is already recorded there. */
|
|
269
|
+
function followLocalRef(node, path, sink, root, onStack) {
|
|
270
|
+
if (!root)
|
|
271
|
+
return;
|
|
272
|
+
const target = resolveLocalRef(node, root);
|
|
273
|
+
if (!target || target === node)
|
|
274
|
+
return;
|
|
275
|
+
const entered = onStack.get(target);
|
|
276
|
+
if (entered !== undefined) {
|
|
277
|
+
if (entered !== path)
|
|
278
|
+
sink.recurse(path, entered);
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
onStack.set(target, path);
|
|
282
|
+
try {
|
|
283
|
+
traverseNode(target, path, sink, root, onStack);
|
|
284
|
+
}
|
|
285
|
+
finally {
|
|
286
|
+
onStack.delete(target);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
/** `owner.additionalProperties`, the schema of every value in an open-keyed
|
|
290
|
+
* object. JSON Schema applies it only to keys `owner` does not declare, which
|
|
291
|
+
* the driven map records so a walk skips them. */
|
|
292
|
+
function traverseMapValue(owner, path, sink, root, onStack) {
|
|
293
|
+
const valueSchema = owner.additionalProperties;
|
|
294
|
+
if (!valueSchema || typeof valueSchema !== "object" || Array.isArray(valueSchema))
|
|
295
|
+
return;
|
|
296
|
+
const mapPath = joinPath(path, "{}");
|
|
297
|
+
const declared = owner.properties && typeof owner.properties === "object" ? Object.keys(owner.properties) : [];
|
|
298
|
+
sink.mapValue(mapPath, path === "" ? [...declared, ...RESOURCE_ENVELOPE_KEYS] : declared);
|
|
299
|
+
traverseNode(valueSchema, mapPath, sink, root, onStack);
|
|
300
|
+
}
|
|
301
|
+
function traverseNode(node, path, sink, root, onStack = new Map()) {
|
|
302
|
+
const driven = sink.driven;
|
|
303
|
+
// Local `$ref` is intentionally NOT followed here. This map is the kernel's
|
|
148
304
|
// Phase-5 injection surface: descending into shared `$defs` (notably
|
|
149
305
|
// `Run.Sequence`'s `step` definition) would make every step's `invoke` an
|
|
150
306
|
// injection site, and step slots resolve at dispatch — injecting there is
|
|
151
307
|
// unwanted regardless of tracing (the original dispatcher-bypass blocker
|
|
152
308
|
// has since shipped via the `REF_IDENTITY` stamp). Static analysis is NOT
|
|
153
309
|
// limited by this stop: the call graph (`call-graph.ts`) reads step slots
|
|
154
|
-
// from the item schema itself and scans the value tree,
|
|
155
|
-
//
|
|
156
|
-
|
|
157
|
-
if (typeof node?.$ref === "string")
|
|
310
|
+
// from the item schema itself and scans the value tree, and the driven-slot
|
|
311
|
+
// mode (`buildDrivenSlotMap`) follows the reference.
|
|
312
|
+
if (typeof node?.$ref === "string" && !driven)
|
|
158
313
|
return;
|
|
159
314
|
// Scope slot — record and stop; do not recurse into scope contents
|
|
160
315
|
if ("x-telo-scope" in node) {
|
|
161
|
-
|
|
316
|
+
sink.stop(path, { scope: node["x-telo-scope"] });
|
|
162
317
|
return;
|
|
163
318
|
}
|
|
164
319
|
// Schema-from slot — record and stop; no further traversal needed
|
|
165
320
|
if ("x-telo-schema-from" in node) {
|
|
166
|
-
|
|
321
|
+
sink.stop(path, { schemaFrom: node["x-telo-schema-from"] });
|
|
167
322
|
return;
|
|
168
323
|
}
|
|
324
|
+
if (driven) {
|
|
325
|
+
const step = readStepSlot(node);
|
|
326
|
+
if (step) {
|
|
327
|
+
sink.step(path, step, node);
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
169
331
|
// Reference slot (direct, via a `kind:` list, or via anyOf)
|
|
170
332
|
const slot = readRefSlot(node);
|
|
171
333
|
if (slot && slot.kinds.length > 0) {
|
|
@@ -184,7 +346,9 @@ function traverseNode(node, path, map, root, visitedRefs = new Set()) {
|
|
|
184
346
|
entry.context = node["x-telo-context"];
|
|
185
347
|
if (slot.inline)
|
|
186
348
|
entry.inline = true;
|
|
187
|
-
|
|
349
|
+
if (slot.throwsThrough)
|
|
350
|
+
entry.throwsThrough = true;
|
|
351
|
+
sink.ref(path, entry, node);
|
|
188
352
|
// A node can mix item-level ref branches (a bare string / `{kind, name}`)
|
|
189
353
|
// with object branches that carry their OWN nested refs — e.g. Application
|
|
190
354
|
// `targets`: a bare ref vs inline `{ invoke }` vs gated `{ ref }`. Descend
|
|
@@ -198,21 +362,24 @@ function traverseNode(node, path, map, root, visitedRefs = new Set()) {
|
|
|
198
362
|
for (const variant of variants) {
|
|
199
363
|
if (!variant || typeof variant !== "object")
|
|
200
364
|
continue;
|
|
201
|
-
traverseVariant(variant, path,
|
|
365
|
+
traverseVariant(variant, path, sink, root, onStack);
|
|
202
366
|
}
|
|
203
367
|
}
|
|
204
368
|
return;
|
|
205
369
|
}
|
|
206
|
-
|
|
370
|
+
// Reached only in driven mode — the injection map stopped at the top.
|
|
371
|
+
if (typeof node?.$ref === "string") {
|
|
372
|
+
followLocalRef(node, path, sink, root, onStack);
|
|
207
373
|
return;
|
|
374
|
+
}
|
|
208
375
|
// Array — recurse into items
|
|
209
376
|
if (node.type === "array" && node.items) {
|
|
210
|
-
traverseNode(node.items, path + "[]",
|
|
377
|
+
traverseNode(node.items, path + "[]", sink, root, onStack);
|
|
211
378
|
}
|
|
212
379
|
// Object — recurse into properties
|
|
213
380
|
if (node.properties) {
|
|
214
381
|
for (const [key, propSchema] of Object.entries(node.properties)) {
|
|
215
|
-
traverseNode(propSchema,
|
|
382
|
+
traverseNode(propSchema, joinPath(path, key), sink, root, onStack);
|
|
216
383
|
}
|
|
217
384
|
}
|
|
218
385
|
// Variant branches — descend into every alternative's properties / items.
|
|
@@ -221,10 +388,11 @@ function traverseNode(node, path, map, root, visitedRefs = new Set()) {
|
|
|
221
388
|
// slots inside the branch. Walking each branch surfaces those slots into
|
|
222
389
|
// the field map so downstream passes (ref validation, sentinel
|
|
223
390
|
// resolution, dependency graph) cover them without a runtime fallback.
|
|
224
|
-
// The same field path may be added by multiple branches
|
|
225
|
-
// assignment
|
|
226
|
-
// share the same ref/context configuration
|
|
227
|
-
//
|
|
391
|
+
// The same field path may be added by multiple branches. The injection map
|
|
392
|
+
// keeps the later assignment, which is fine for injection — branches with
|
|
393
|
+
// the same field path share the same ref/context configuration. The driven
|
|
394
|
+
// map keeps every one, because which branch applies decides what a
|
|
395
|
+
// dispatch can throw.
|
|
228
396
|
for (const variantKey of ["oneOf", "anyOf", "allOf"]) {
|
|
229
397
|
const variants = node[variantKey];
|
|
230
398
|
if (!Array.isArray(variants))
|
|
@@ -232,34 +400,32 @@ function traverseNode(node, path, map, root, visitedRefs = new Set()) {
|
|
|
232
400
|
for (const variant of variants) {
|
|
233
401
|
if (!variant || typeof variant !== "object")
|
|
234
402
|
continue;
|
|
235
|
-
traverseVariant(variant, path,
|
|
403
|
+
traverseVariant(variant, path, sink, root, onStack);
|
|
236
404
|
}
|
|
237
405
|
}
|
|
238
406
|
// Map — `additionalProperties: { ... }` describes every value in an
|
|
239
407
|
// open-keyed object. Encoder refs nested inside `content[mime]` map
|
|
240
408
|
// entries reach Phase 5 through this branch.
|
|
241
|
-
|
|
242
|
-
typeof node.additionalProperties === "object" &&
|
|
243
|
-
!Array.isArray(node.additionalProperties)) {
|
|
244
|
-
traverseNode(node.additionalProperties, `${path}.{}`, map, root, visitedRefs);
|
|
245
|
-
}
|
|
409
|
+
traverseMapValue(node, path, sink, root, onStack);
|
|
246
410
|
}
|
|
247
411
|
/** Walk a single variant of a `oneOf` / `anyOf` / `allOf` branch. Only
|
|
248
412
|
* the properties / items / map slots are followed — collectRefs at the
|
|
249
413
|
* variant root is handled by the parent's `collectRefs(node)` already
|
|
250
|
-
* (anyOf of x-telo-ref branches is the canonical multi-ref shape).
|
|
251
|
-
|
|
414
|
+
* (anyOf of x-telo-ref branches is the canonical multi-ref shape). In
|
|
415
|
+
* driven mode a `$ref` branch is followed as a node in its own right, since
|
|
416
|
+
* `readRefSlot` does not look through one. */
|
|
417
|
+
function traverseVariant(variant, path, sink, root, onStack = new Map()) {
|
|
418
|
+
if (sink.driven && typeof variant.$ref === "string") {
|
|
419
|
+
followLocalRef(variant, path, sink, root, onStack);
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
252
422
|
if (variant.properties) {
|
|
253
423
|
for (const [key, propSchema] of Object.entries(variant.properties)) {
|
|
254
|
-
traverseNode(propSchema,
|
|
424
|
+
traverseNode(propSchema, joinPath(path, key), sink, root, onStack);
|
|
255
425
|
}
|
|
256
426
|
}
|
|
257
427
|
if (variant.type === "array" && variant.items) {
|
|
258
|
-
traverseNode(variant.items, path + "[]",
|
|
259
|
-
}
|
|
260
|
-
if (variant.additionalProperties &&
|
|
261
|
-
typeof variant.additionalProperties === "object" &&
|
|
262
|
-
!Array.isArray(variant.additionalProperties)) {
|
|
263
|
-
traverseNode(variant.additionalProperties, `${path}.{}`, map, root, visitedRefs);
|
|
428
|
+
traverseNode(variant.items, path + "[]", sink, root, onStack);
|
|
264
429
|
}
|
|
430
|
+
traverseMapValue(variant, path, sink, root, onStack);
|
|
265
431
|
}
|
|
@@ -49,7 +49,8 @@ export declare const LOCALLY_DERIVED_LAYERS: ReadonlySet<string>;
|
|
|
49
49
|
* `axis=value;…` form, because this string is read by a human in a ledger diff
|
|
50
50
|
* and written into a plain YAML key; the axis order is `PLATFORM_AXES`, so the
|
|
51
51
|
* rendering is deterministic rather than dependent on how the selector was
|
|
52
|
-
* built.
|
|
52
|
+
* built. An axis a selector omits renders nothing, so a new axis appended to the
|
|
53
|
+
* vocabulary leaves every existing key unchanged — reordering it would not.
|
|
53
54
|
*/
|
|
54
55
|
export declare function layerDigestKey(role: LayerRole | string, selector?: ArtifactSelector): string;
|
|
55
56
|
/** A layer whose digest differs between two readings, or that exists in only
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"payload-digest.d.ts","sourceRoot":"","sources":["../../src/release/payload-digest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAiB,KAAK,gBAAgB,EAAE,KAAK,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAE/F,sDAAsD;AACtD,MAAM,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAE5D,yDAAyD;AACzD,eAAO,MAAM,cAAc,aAAa,CAAC;AAEzC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,sBAAsB,EAAE,WAAW,CAAC,MAAM,CAA6B,CAAC;AAErF
|
|
1
|
+
{"version":3,"file":"payload-digest.d.ts","sourceRoot":"","sources":["../../src/release/payload-digest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAiB,KAAK,gBAAgB,EAAE,KAAK,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAE/F,sDAAsD;AACtD,MAAM,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAE5D,yDAAyD;AACzD,eAAO,MAAM,cAAc,aAAa,CAAC;AAEzC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,sBAAsB,EAAE,WAAW,CAAC,MAAM,CAA6B,CAAC;AAErF;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,EAAE,QAAQ,CAAC,EAAE,gBAAgB,GAAG,MAAM,CAM5F;AAED;;;mBAGmB;AACnB,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;mCACmC;AACnC,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,GAAG,WAAW,EAAE,CAQzF"}
|
|
@@ -47,7 +47,8 @@ export const LOCALLY_DERIVED_LAYERS = new Set([MANIFEST_LAYER]);
|
|
|
47
47
|
* `axis=value;…` form, because this string is read by a human in a ledger diff
|
|
48
48
|
* and written into a plain YAML key; the axis order is `PLATFORM_AXES`, so the
|
|
49
49
|
* rendering is deterministic rather than dependent on how the selector was
|
|
50
|
-
* built.
|
|
50
|
+
* built. An axis a selector omits renders nothing, so a new axis appended to the
|
|
51
|
+
* vocabulary leaves every existing key unchanged — reordering it would not.
|
|
51
52
|
*/
|
|
52
53
|
export function layerDigestKey(role, selector) {
|
|
53
54
|
if (!selector)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-ref-sentinels.d.ts","sourceRoot":"","sources":["../src/resolve-ref-sentinels.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"resolve-ref-sentinels.d.ts","sourceRoot":"","sources":["../src/resolve-ref-sentinels.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,0BAA0B,CAAC;AAIlC;+CAC+C;AAC/C,MAAM,WAAW,mBAAmB;IAClC,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,CAAC;CAClC;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,gBAAgB,EAAE,EAC7B,OAAO,CAAC,EAAE,aAAa,EACvB,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,EAK5C,kBAAkB,GAAE,gBAAgB,EAAO;AAC3C;;+CAE+C;AAC/C,IAAI,CAAC,EAAE,mBAAmB,GACzB,IAAI,CAyIN"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { isRefSentinel, isTaggedSentinel } from "@telorun/templating";
|
|
2
2
|
import { isScopeEntry, resolveFieldEntries, } from "./reference-field-map.js";
|
|
3
3
|
import { REF_RESOLUTION_SKIP_KINDS as SYSTEM_KINDS } from "./system-kinds.js";
|
|
4
|
+
import { isForwardedDeclaration, isForwardedExport } from "./forwarded-declaration.js";
|
|
4
5
|
/**
|
|
5
6
|
* Rewrites every `!ref <name>` sentinel in each non-system resource's value tree
|
|
6
7
|
* to `{kind, name}` (local) or `{kind, name, alias}` (cross-module), in place.
|
|
@@ -48,9 +49,10 @@ crossModuleTargets = [],
|
|
|
48
49
|
* it shadows — so both call sites pass it. */
|
|
49
50
|
defs) {
|
|
50
51
|
const moduleOf = (r) => r.metadata?.module;
|
|
51
|
-
//
|
|
52
|
-
//
|
|
53
|
-
|
|
52
|
+
// A dependency's code — a forwarded export, or what extraction pulled out of one — is
|
|
53
|
+
// never walked as a local ref source here and never a local name; only an EXPORT is a
|
|
54
|
+
// cross-module resolution target.
|
|
55
|
+
const isForeign = isForwardedDeclaration;
|
|
54
56
|
// Local resources resolve a bare / `Self.`-qualified name; forwarded foreign exports
|
|
55
57
|
// resolve an `Alias.`-qualified name keyed by (module, name).
|
|
56
58
|
const byName = new Map();
|
|
@@ -60,14 +62,15 @@ defs) {
|
|
|
60
62
|
continue;
|
|
61
63
|
const name = r.metadata.name;
|
|
62
64
|
if (isForeign(r)) {
|
|
63
|
-
|
|
65
|
+
if (isForwardedExport(r))
|
|
66
|
+
byModuleName.set(`${moduleOf(r)}\0${name}`, r);
|
|
64
67
|
}
|
|
65
68
|
else {
|
|
66
69
|
byName.set(name, r);
|
|
67
70
|
}
|
|
68
71
|
}
|
|
69
72
|
for (const r of crossModuleTargets) {
|
|
70
|
-
if (!r.metadata?.name || SYSTEM_KINDS.has(r.kind) || !
|
|
73
|
+
if (!r.metadata?.name || SYSTEM_KINDS.has(r.kind) || !isForwardedExport(r))
|
|
71
74
|
continue;
|
|
72
75
|
byModuleName.set(`${moduleOf(r)}\0${r.metadata.name}`, r);
|
|
73
76
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ResourceDefinition, ResourceManifest } from "@telorun/sdk";
|
|
2
2
|
import { type AliasResolver } from "./alias-resolver.js";
|
|
3
3
|
import type { DefinitionRegistry } from "./definition-registry.js";
|
|
4
|
+
import { type RefSlot, type RefUse } from "./ref-slot.js";
|
|
4
5
|
export interface ThrowsCodeMeta {
|
|
5
6
|
data?: Record<string, any>;
|
|
6
7
|
}
|
|
@@ -56,11 +57,31 @@ export interface ResolveCtx {
|
|
|
56
57
|
}
|
|
57
58
|
export declare function createResolveCtx(allManifests: ResourceManifest[], defs: DefinitionRegistry, aliases: AliasResolver, aliasesByModule?: Map<string, AliasResolver>, rootModules?: Set<string>, moduleManifests?: Map<string, ResourceManifest[]>): ResolveCtx;
|
|
58
59
|
/** Resolve the effective throw union for a named manifest. The result combines
|
|
59
|
-
* explicit `throws.codes`, `throws.inherit: true` dataflow (step
|
|
60
|
-
*
|
|
61
|
-
* unresolvable passthrough call sites. Cycles
|
|
62
|
-
* result so resolution always terminates. */
|
|
60
|
+
* explicit `throws.codes`, `throws.inherit: true` dataflow (step bodies with
|
|
61
|
+
* try/catch subtraction, plus reference slots that hand a failure back), and
|
|
62
|
+
* unbounded markers for unresolvable passthrough call sites. Cycles
|
|
63
|
+
* short-circuit to an empty result so resolution always terminates. */
|
|
63
64
|
export declare function resolveThrowsUnion(manifest: ResourceManifest, ctx: ResolveCtx): ThrowsUnion;
|
|
65
|
+
/**
|
|
66
|
+
* True for a use through which a target's failure reaches the declaring
|
|
67
|
+
* resource's CALLER: `call` returns into my invocation, and `trigger.consumer`
|
|
68
|
+
* rejects the value my caller drains. `detached` and `trigger.inbound` run where
|
|
69
|
+
* no caller of mine awaits them; `dependency` and `schema` dispatch nothing.
|
|
70
|
+
*
|
|
71
|
+
* The reduction `inherit` is read through — by the resolver and by the check
|
|
72
|
+
* that a definition declaring it has something to inherit from.
|
|
73
|
+
*/
|
|
74
|
+
export declare function handsFailureBack(use: RefUse): boolean;
|
|
75
|
+
/**
|
|
76
|
+
* The uses a throws consumer reads off a slot. A slot that declares no use —
|
|
77
|
+
* the legacy bare-string form — reads as `call`: the throws union must assume
|
|
78
|
+
* `call` to keep an error path, the direction the call graph takes for the same
|
|
79
|
+
* slot. The zone projection reads it the opposite way, deliberately.
|
|
80
|
+
*
|
|
81
|
+
* `uses` defaults to every use the slot can take; a consumer that resolved the
|
|
82
|
+
* slot's case map for one instance passes that answer instead.
|
|
83
|
+
*/
|
|
84
|
+
export declare function throwsUses(slot: RefSlot, uses?: readonly RefUse[]): readonly RefUse[];
|
|
64
85
|
/**
|
|
65
86
|
* The union a SCOPE-LEVEL `catches:` list can be asked to render — everything
|
|
66
87
|
* the resource it is written on drives, transitively.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-throws-union.d.ts","sourceRoot":"","sources":["../src/resolve-throws-union.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEzE,OAAO,EAA0B,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGjF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"resolve-throws-union.d.ts","sourceRoot":"","sources":["../src/resolve-throws-union.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEzE,OAAO,EAA0B,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGjF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EAIL,KAAK,OAAO,EACZ,KAAK,MAAM,EACZ,MAAM,eAAe,CAAC;AAIvB,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC5B;AAED;;gFAEgF;AAChF,eAAO,MAAM,gBAAgB,mBAAmB,CAAC;AAEjD,MAAM,WAAW,WAAW;IAC1B,gFAAgF;IAChF,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACnC;;;8EAG0E;IAC1E,SAAS,EAAE,OAAO,CAAC;IACnB;;;;gDAI4C;IAC5C,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,UAAU;IACzB,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,IAAI,EAAE,kBAAkB,CAAC;IACzB,OAAO,EAAE,aAAa,CAAC;IACvB;;;wFAGoF;IACpF,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAC5C,0FAA0F;IAC1F,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACzB;;;;;;;;;;;;;OAaG;IACH,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,EAAE,CAAC,CAAC;IACjD;uEACmE;IACnE,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAC/B,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACzB;AAED,wBAAgB,gBAAgB,CAC9B,YAAY,EAAE,gBAAgB,EAAE,EAChC,IAAI,EAAE,kBAAkB,EACxB,OAAO,EAAE,aAAa,EACtB,eAAe,GAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAa,EACvD,WAAW,GAAE,GAAG,CAAC,MAAM,CAAa,EACpC,eAAe,GAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,EAAE,CAAa,GAC3D,UAAU,CAWZ;AA2HD;;;;wEAIwE;AACxE,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,gBAAgB,EAC1B,GAAG,EAAE,UAAU,GACd,WAAW,CAiDb;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAErD;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,OAAO,EACb,IAAI,GAAE,SAAS,MAAM,EAAuB,GAC3C,SAAS,MAAM,EAAE,CAEnB;AAuCD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,gBAAgB,EAC1B,UAAU,EAAE,kBAAkB,EAC9B,GAAG,EAAE,UAAU,EACf,IAAI,GAAE,GAAG,CAAC,gBAAgB,CAAa,GACtC,WAAW,CAkCb;AAiND;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,OAAO,EACjB,GAAG,EAAE,UAAU,EACf,WAAW,EAAE,MAAM,GAAG,SAAS,GAC9B,gBAAgB,GAAG,SAAS,CAsB9B"}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { isTaggedSentinel } from "@telorun/templating";
|
|
2
2
|
import { scopeResolverForModule } from "./alias-resolver.js";
|
|
3
|
-
import { resolveScopedName } from "./call-graph.js";
|
|
3
|
+
import { resolveScopedName, resolveSlotUseAt } from "./call-graph.js";
|
|
4
4
|
import { refSentinelTarget } from "./ref-sentinel-target.js";
|
|
5
|
-
import { possibleUses, transfersControl } from "./ref-slot.js";
|
|
6
|
-
import { readStepSlot } from "./step-slot.js";
|
|
5
|
+
import { hasDeclaredUse, possibleUses, transfersControl, } from "./ref-slot.js";
|
|
7
6
|
import { forEachDrivenSlot } from "./schema-walk.js";
|
|
8
7
|
/** Code a non-`InvokeError` failure surfaces as inside a `catch` block. Mirrors
|
|
9
8
|
* `PLAIN_ERROR_CODE` in `@telorun/run`'s `toSequenceError`: any invoke can throw
|
|
@@ -127,10 +126,10 @@ function codesFromDefinition(definition) {
|
|
|
127
126
|
return out;
|
|
128
127
|
}
|
|
129
128
|
/** Resolve the effective throw union for a named manifest. The result combines
|
|
130
|
-
* explicit `throws.codes`, `throws.inherit: true` dataflow (step
|
|
131
|
-
*
|
|
132
|
-
* unresolvable passthrough call sites. Cycles
|
|
133
|
-
* result so resolution always terminates. */
|
|
129
|
+
* explicit `throws.codes`, `throws.inherit: true` dataflow (step bodies with
|
|
130
|
+
* try/catch subtraction, plus reference slots that hand a failure back), and
|
|
131
|
+
* unbounded markers for unresolvable passthrough call sites. Cycles
|
|
132
|
+
* short-circuit to an empty result so resolution always terminates. */
|
|
134
133
|
export function resolveThrowsUnion(manifest, ctx) {
|
|
135
134
|
const name = memoKey(manifest);
|
|
136
135
|
if (name) {
|
|
@@ -182,29 +181,52 @@ export function resolveThrowsUnion(manifest, ctx) {
|
|
|
182
181
|
}
|
|
183
182
|
}
|
|
184
183
|
/**
|
|
185
|
-
*
|
|
184
|
+
* True for a use through which a target's failure reaches the declaring
|
|
185
|
+
* resource's CALLER: `call` returns into my invocation, and `trigger.consumer`
|
|
186
|
+
* rejects the value my caller drains. `detached` and `trigger.inbound` run where
|
|
187
|
+
* no caller of mine awaits them; `dependency` and `schema` dispatch nothing.
|
|
186
188
|
*
|
|
187
|
-
*
|
|
188
|
-
*
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
189
|
+
* The reduction `inherit` is read through — by the resolver and by the check
|
|
190
|
+
* that a definition declaring it has something to inherit from.
|
|
191
|
+
*/
|
|
192
|
+
export function handsFailureBack(use) {
|
|
193
|
+
return use === "call" || use === "trigger.consumer";
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* The uses a throws consumer reads off a slot. A slot that declares no use —
|
|
197
|
+
* the legacy bare-string form — reads as `call`: the throws union must assume
|
|
198
|
+
* `call` to keep an error path, the direction the call graph takes for the same
|
|
199
|
+
* slot. The zone projection reads it the opposite way, deliberately.
|
|
200
|
+
*
|
|
201
|
+
* `uses` defaults to every use the slot can take; a consumer that resolved the
|
|
202
|
+
* slot's case map for one instance passes that answer instead.
|
|
203
|
+
*/
|
|
204
|
+
export function throwsUses(slot, uses = possibleUses(slot)) {
|
|
205
|
+
return hasDeclaredUse(slot) ? uses : ["call"];
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* `throws.inherit: true` — the union of what the resource dispatches: its step
|
|
209
|
+
* bodies (try/catch subtraction included) and every reference slot whose use,
|
|
210
|
+
* resolved for THIS instance, hands a failure back ({@link handsFailureBack}).
|
|
211
|
+
*
|
|
212
|
+
* Only on a kind that DECLARES `inherit`: it is a claim that the kind lets what
|
|
213
|
+
* it dispatches escape, and a kind catching a slot internally does not make it.
|
|
214
|
+
* What a CATCH SCOPE encloses is a different question, answered below.
|
|
193
215
|
*/
|
|
194
216
|
function resolveInherited(manifest, definition, ctx, ownerModule) {
|
|
195
217
|
const result = { codes: new Map(), unbounded: false };
|
|
196
|
-
const
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
}
|
|
218
|
+
const schema = definition.schema;
|
|
219
|
+
forEachDrivenSlot(schema, manifest, (driven) => {
|
|
220
|
+
if (driven.kind === "step") {
|
|
221
|
+
unionInto(result, stepSiteThrows(driven.data, driven.slots, ctx, ownerModule));
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
// Several slots at one site are the branches declaring it; any one that
|
|
225
|
+
// hands a failure back counts, since a branch not applying can only add codes.
|
|
226
|
+
const handsBack = driven.slots.some(({ slot, fieldPath }) => throwsUses(slot, resolveSlotUseAt(slot, manifest, schema, driven.path, fieldPath).use).some(handsFailureBack));
|
|
227
|
+
if (handsBack)
|
|
228
|
+
unionInto(result, resolveRefTargetThrows(driven.data, ctx, ownerModule));
|
|
229
|
+
});
|
|
208
230
|
return result;
|
|
209
231
|
}
|
|
210
232
|
/**
|
|
@@ -233,10 +255,13 @@ export function resolveScopeUnion(manifest, definition, ctx, seen = new Set()) {
|
|
|
233
255
|
const ownerModule = manifest.metadata?.module;
|
|
234
256
|
forEachDrivenSlot(definition.schema, manifest, (driven) => {
|
|
235
257
|
if (driven.kind === "step") {
|
|
236
|
-
unionInto(result,
|
|
258
|
+
unionInto(result, stepSiteThrows(driven.data, driven.slots, ctx, ownerModule));
|
|
237
259
|
return;
|
|
238
260
|
}
|
|
239
|
-
if (driven.slot.throwsThrough) {
|
|
261
|
+
if (driven.slots.some(({ slot }) => !slot.throwsThrough && throwsUses(slot).some(transfersControl))) {
|
|
262
|
+
unionInto(result, resolveRefTargetThrows(driven.data, ctx, ownerModule));
|
|
263
|
+
}
|
|
264
|
+
if (driven.slots.some(({ slot }) => slot.throwsThrough)) {
|
|
240
265
|
const target = resolveRefManifest(driven.data, ctx, ownerModule);
|
|
241
266
|
const targetDef = target
|
|
242
267
|
? definitionFor(target.kind, ctx.defs, ctx.aliases, scopeResolverFor(ctx, target.metadata?.module))
|
|
@@ -247,14 +272,19 @@ export function resolveScopeUnion(manifest, definition, ctx, seen = new Set()) {
|
|
|
247
272
|
// the scope's union is no longer enumerable.
|
|
248
273
|
else
|
|
249
274
|
result.unbounded = true;
|
|
250
|
-
return;
|
|
251
275
|
}
|
|
252
|
-
if (!possibleUses(driven.slot).some(transfersControl))
|
|
253
|
-
return;
|
|
254
|
-
unionInto(result, resolveRefTargetThrows(driven.data, ctx, ownerModule));
|
|
255
276
|
});
|
|
256
277
|
return result;
|
|
257
278
|
}
|
|
279
|
+
/** The union a step-body site reaches — once per distinct invoke field, since
|
|
280
|
+
* several branches may declare a body at one site. */
|
|
281
|
+
function stepSiteThrows(steps, slots, ctx, ownerModule) {
|
|
282
|
+
const result = emptyUnion();
|
|
283
|
+
for (const invoke of new Set(slots.map((slot) => slot.invoke))) {
|
|
284
|
+
unionInto(result, collectStepArrayThrows(steps, invoke, undefined, ctx, ownerModule));
|
|
285
|
+
}
|
|
286
|
+
return result;
|
|
287
|
+
}
|
|
258
288
|
function collectStepArrayThrows(steps, invokeField, enclosingTryCodes, ctx, ownerModule) {
|
|
259
289
|
const result = emptyUnion();
|
|
260
290
|
for (const step of steps) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-zone-requirements.d.ts","sourceRoot":"","sources":["../src/resolve-zone-requirements.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAsB,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAEL,KAAK,SAAS,EAEd,KAAK,iBAAiB,EACvB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAMnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,OAAO,EAAsB,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"resolve-zone-requirements.d.ts","sourceRoot":"","sources":["../src/resolve-zone-requirements.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAsB,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAEL,KAAK,SAAS,EAEd,KAAK,iBAAiB,EACvB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAMnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,OAAO,EAAsB,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAMzE;;uCAEuC;AACvC,MAAM,WAAW,mBAAmB;IAClC,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;IACb;;wBAEoB;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+EAA+E;IAC/E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;sDACkD;IAClD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;gCAG4B;IAC5B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,gEAAgE;IAChE,MAAM,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,GAAG,EAAE,MAAM,EAAE,CAAC;CACf;AAED,6EAA6E;AAC7E,MAAM,MAAM,sBAAsB,GAAG,GAAG,CAAC,MAAM,EAAE,mBAAmB,EAAE,CAAC,CAAC;AAExE,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,sBAAsB,CAAC;CACjC;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,eAAe,GAAG,GAAG,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;AAkBhE,UAAU,cAAc;IACtB,KAAK,EAAE,SAAS,CAAC;IACjB,IAAI,EAAE,kBAAkB,CAAC;IACzB,OAAO,EAAE,aAAa,CAAC;IACvB,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAC5C;qEACiE;IACjE,aAAa,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACnC;0EACsE;IACtE,KAAK,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,mBAAmB,EAAE,CAAC,CAAC;IAC3C;2CACuC;IACvC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,MAAM,GAAG,SAAS,CAAC;CAC5D;AAED,UAAU,gBAAgB;IACxB,WAAW,EAAE,kBAAkB,EAAE,CAAC;IAClC,WAAW,EAAE,sBAAsB,CAAC;CACrC;AAuKD,yCAAyC;AACzC,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,cAAc,GAAG,gBAAgB,CAoZ9E;AAED;;;;iEAIiE;AACjE,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,SAAS,gBAAgB,EAAE,GAAG,MAAM,CAUrF;AAED;;;;GAIG;AACH,wBAAgB,+BAA+B,CAC7C,IAAI,EAAE,eAAe,EACrB,IAAI,EAAE,kBAAkB,EACxB,OAAO,EAAE,aAAa,EACtB,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,EAC3C,KAAK,CAAC,EAAE,eAAe,GACtB,sBAAsB,CAkBxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,gFAAgF;IAChF,SAAS,EAAE,gBAAgB,EAAE,CAAC;IAC9B,KAAK,EAAE,SAAS,CAAC;IACjB,IAAI,EAAE,kBAAkB,CAAC;IACzB,OAAO,EAAE,aAAa,CAAC;IACvB,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAC5C,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACjC,eAAe,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IAC7C,KAAK,CAAC,EAAE,eAAe,CAAC;CACzB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,gBAAgB,GAAG,kBAAkB,EAAE,CAwF5E"}
|
|
@@ -4,6 +4,7 @@ import { enclosingOf, propertySchemas, resolveLocalRef, } from "./manifest-navig
|
|
|
4
4
|
import { readProvidesZone, readRequiresZone } from "./zone-slot.js";
|
|
5
5
|
import { DiagnosticSeverity } from "./types.js";
|
|
6
6
|
import { moduleAliasScope } from "./module-alias-scope.js";
|
|
7
|
+
import { isForwardedDeclaration } from "./forwarded-declaration.js";
|
|
7
8
|
const SOURCE = "telo-analyzer";
|
|
8
9
|
/** Resolve a possibly alias-form kind to its definition in the DECLARING
|
|
9
10
|
* module's scope — the same layering `AnalysisRegistry.resolveDefinitionIn`
|
|
@@ -379,7 +380,7 @@ export function projectZoneRequirements(args) {
|
|
|
379
380
|
// (with the internal graph in hand) and seeded below — deriving them here
|
|
380
381
|
// against the flattened view would resolve correlation against a graph
|
|
381
382
|
// that no longer holds the library's internals.
|
|
382
|
-
if (
|
|
383
|
+
if (isForwardedDeclaration(node.manifest))
|
|
383
384
|
continue;
|
|
384
385
|
const def = resolveDef(node.kind, meta?.module);
|
|
385
386
|
const schema = def?.schema;
|
|
@@ -5,6 +5,11 @@ import type { AnalysisDiagnostic } from "./types.js";
|
|
|
5
5
|
* `data.resource`, which has no YAML source. Rewrite each such diagnostic
|
|
6
6
|
* back to the chain root: walk up `metadata.xTeloOrigin` until a manifest
|
|
7
7
|
* with no origin is reached, and prepend each hop's `pathFromParent` to
|
|
8
|
-
* `data.path` so position-index lookups against the root doc resolve.
|
|
8
|
+
* `data.path` so position-index lookups against the root doc resolve.
|
|
9
|
+
*
|
|
10
|
+
* An extraction from a scope member lives INSIDE the scope array rather than at
|
|
11
|
+
* the top level, so a diagnostic about it names the top-level owner and a path
|
|
12
|
+
* through an array index the author never wrote (`with[3]`). That prefix is
|
|
13
|
+
* unfolded the same way, into the position the declaration was written at. */
|
|
9
14
|
export declare function rewriteSyntheticOrigins(diagnostics: AnalysisDiagnostic[], manifests: ResourceManifest[]): AnalysisDiagnostic[];
|
|
10
15
|
//# sourceMappingURL=rewrite-synthetic-origins.d.ts.map
|