@suss/extractor 0.29.0 → 0.31.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/index.cjs +700 -790
- package/dist/index.d.cts +11 -7
- package/dist/index.d.ts +11 -7
- package/dist/index.js +703 -791
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -245,892 +245,799 @@ function mergeInputReads(derived, syntactic) {
|
|
|
245
245
|
}
|
|
246
246
|
|
|
247
247
|
// src/composeWrappers.ts
|
|
248
|
-
var import_behavioral_ir3 = require("@suss/behavioral-ir");
|
|
249
|
-
|
|
250
|
-
// src/paths/enumeratePaths.ts
|
|
251
248
|
var import_behavioral_ir2 = require("@suss/behavioral-ir");
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
};
|
|
257
|
-
function branchCond(branchStmt, condition, polarity, oppositeExit) {
|
|
258
|
-
return {
|
|
259
|
-
info: {
|
|
260
|
-
sourceText: condition.sourceText,
|
|
261
|
-
polarity,
|
|
262
|
-
source: "explicit",
|
|
263
|
-
expression: condition.expression
|
|
264
|
-
},
|
|
265
|
-
branchStmt,
|
|
266
|
-
oppositeExit
|
|
267
|
-
};
|
|
249
|
+
function composeWrappers(summaries, options = {}) {
|
|
250
|
+
const chain = (0, import_behavioral_ir2.wrapperIndex)(summaries);
|
|
251
|
+
const keepGaps = options.gapHandling !== "silent";
|
|
252
|
+
return summaries.map((summary) => composeOne(summary, chain, keepGaps));
|
|
268
253
|
}
|
|
269
|
-
function
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
254
|
+
function composeOne(summary, chain, keepGaps) {
|
|
255
|
+
const recorded = (0, import_behavioral_ir2.readWrapperMetadata)(summary);
|
|
256
|
+
const applied = recorded?.applied ?? [];
|
|
257
|
+
const covering = applied.filter(
|
|
258
|
+
(reference) => coversUnit(reference, summary)
|
|
259
|
+
);
|
|
260
|
+
const narrowed = covering.length === applied.length ? summary : {
|
|
261
|
+
...summary,
|
|
262
|
+
metadata: (0, import_behavioral_ir2.withWrapperMetadata)(summary.metadata, {
|
|
263
|
+
applied: covering
|
|
264
|
+
})
|
|
279
265
|
};
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
"positive",
|
|
284
|
-
"explicit"
|
|
285
|
-
);
|
|
286
|
-
var loopCompletedCond = (headerText, exit) => fixedCond(
|
|
287
|
-
{
|
|
288
|
-
sourceText: `loop exited via ${exit ?? "return"}: ${headerText}`,
|
|
289
|
-
expression: null
|
|
290
|
-
},
|
|
291
|
-
"negative",
|
|
292
|
-
exit === "throw" ? "earlyThrow" : "earlyReturn"
|
|
293
|
-
);
|
|
294
|
-
var catchEntryCond = () => fixedCond(
|
|
295
|
-
{ sourceText: import_behavioral_ir2.CATCH_ENTRY_TEXT, expression: null },
|
|
296
|
-
"positive",
|
|
297
|
-
"catchBlock"
|
|
298
|
-
);
|
|
299
|
-
function classify(path4, home, isAncestorOrSelf) {
|
|
300
|
-
return path4.map((cond) => {
|
|
301
|
-
if (cond.branchStmt === null) {
|
|
302
|
-
return cond.info;
|
|
303
|
-
}
|
|
304
|
-
const encloses = home !== null && isAncestorOrSelf(cond.branchStmt, home);
|
|
305
|
-
if (encloses || cond.info.polarity === "positive" || cond.oppositeExit === null) {
|
|
306
|
-
return { ...cond.info, source: "explicit" };
|
|
307
|
-
}
|
|
308
|
-
const source = cond.oppositeExit === "throw" ? "earlyThrow" : "earlyReturn";
|
|
309
|
-
return { ...cond.info, source };
|
|
266
|
+
const wrappers = covering.flatMap((reference) => {
|
|
267
|
+
const found = (0, import_behavioral_ir2.wrapperFor)(chain, reference);
|
|
268
|
+
return found === void 0 ? [] : [{ reference, summary: found }];
|
|
310
269
|
});
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
return [...ownBlocksOf(stmt), ...(stmt.callbacks ?? []).flat()];
|
|
314
|
-
}
|
|
315
|
-
function ownBlocksOf(stmt) {
|
|
316
|
-
if (stmt.kind === "if") {
|
|
317
|
-
return stmt.elseBody === null ? stmt.thenBody : [...stmt.thenBody, ...stmt.elseBody];
|
|
270
|
+
if (wrappers.length === 0) {
|
|
271
|
+
return narrowed;
|
|
318
272
|
}
|
|
319
|
-
|
|
320
|
-
|
|
273
|
+
const responses = respondedInstead(wrappers);
|
|
274
|
+
const handled = handledThrows(wrappers);
|
|
275
|
+
const transitions = beside(summary, responses, handled);
|
|
276
|
+
if (!keepGaps) {
|
|
277
|
+
return transitions === summary.transitions ? narrowed : { ...narrowed, transitions };
|
|
321
278
|
}
|
|
322
|
-
|
|
323
|
-
|
|
279
|
+
const gaps = withContractStatusGaps(
|
|
280
|
+
summary,
|
|
281
|
+
[...responses, ...summary.transitions],
|
|
282
|
+
handled
|
|
283
|
+
);
|
|
284
|
+
if (transitions === summary.transitions && gaps === summary.gaps) {
|
|
285
|
+
return narrowed;
|
|
324
286
|
}
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
287
|
+
return { ...narrowed, transitions, gaps };
|
|
288
|
+
}
|
|
289
|
+
function beside(summary, responses, handled) {
|
|
290
|
+
const throws = summary.transitions.some((t) => t.output.type === "throw");
|
|
291
|
+
const onThrow = throws ? handled : [];
|
|
292
|
+
if (responses.length === 0 && onThrow.length === 0) {
|
|
293
|
+
return summary.transitions;
|
|
331
294
|
}
|
|
332
|
-
return [];
|
|
295
|
+
return withDistinctIds([...responses, ...summary.transitions, ...onThrow]);
|
|
333
296
|
}
|
|
334
|
-
function
|
|
335
|
-
return
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
});
|
|
297
|
+
function respondedInstead(wrappers) {
|
|
298
|
+
return wrappers.flatMap(
|
|
299
|
+
(wrapper) => wrapper.reference.onThrow === true ? [] : attribute(
|
|
300
|
+
wrapper.summary.transitions.filter(
|
|
301
|
+
(t) => t.output.type !== "delegate"
|
|
302
|
+
),
|
|
303
|
+
wrapper.reference
|
|
304
|
+
)
|
|
305
|
+
);
|
|
344
306
|
}
|
|
345
|
-
function
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
return "throw";
|
|
350
|
-
}
|
|
351
|
-
if (stmt.exitKind === "return") {
|
|
352
|
-
sawReturn = true;
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
return sawReturn ? "return" : null;
|
|
307
|
+
function handledThrows(wrappers) {
|
|
308
|
+
return wrappers.flatMap(
|
|
309
|
+
(wrapper) => wrapper.reference.onThrow === true ? attribute(wrapper.summary.transitions, wrapper.reference) : []
|
|
310
|
+
);
|
|
356
311
|
}
|
|
357
|
-
function
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
);
|
|
312
|
+
function withContractStatusGaps(summary, composed, handled) {
|
|
313
|
+
const contract = (0, import_behavioral_ir2.readHttpMetadata)(summary)?.declaredContract;
|
|
314
|
+
const binding = summary.identity.boundaryBinding;
|
|
315
|
+
if (contract === void 0 || binding !== null && !(0, import_behavioral_ir2.exchangesHttpResponses)(binding)) {
|
|
316
|
+
return summary.gaps;
|
|
363
317
|
}
|
|
318
|
+
const declared = {
|
|
319
|
+
framework: contract.framework ?? "declared",
|
|
320
|
+
responses: contract.responses
|
|
321
|
+
};
|
|
322
|
+
const stale = new Set(
|
|
323
|
+
contractStatusGaps(declared, summary.transitions).map(gapKey)
|
|
324
|
+
);
|
|
325
|
+
const gaps = [
|
|
326
|
+
...summary.gaps.filter((gap) => !stale.has(gapKey(gap))),
|
|
327
|
+
...contractStatusGaps(declared, [...composed, ...handled])
|
|
328
|
+
];
|
|
329
|
+
const unchanged = gaps.length === summary.gaps.length && gaps.every((gap, i) => gapKey(gap) === gapKey(summary.gaps[i]));
|
|
330
|
+
return unchanged ? summary.gaps : gaps;
|
|
364
331
|
}
|
|
365
|
-
function
|
|
366
|
-
|
|
367
|
-
const info = classify(path4, home, ctx.isAncestorOrSelf);
|
|
368
|
-
const existing = ctx.state.byTerminal.get(terminal) ?? [];
|
|
369
|
-
existing.push(info);
|
|
370
|
-
ctx.state.byTerminal.set(terminal, existing);
|
|
332
|
+
function gapKey(gap) {
|
|
333
|
+
return `${gap.type}|${gap.description}`;
|
|
371
334
|
}
|
|
372
|
-
function
|
|
373
|
-
if (
|
|
335
|
+
function coversUnit(reference, summary) {
|
|
336
|
+
if (reference.scope === void 0) {
|
|
374
337
|
return true;
|
|
375
338
|
}
|
|
376
|
-
|
|
339
|
+
const binding = summary.identity.boundaryBinding;
|
|
340
|
+
return binding !== null && (0, import_behavioral_ir2.withinScope)(binding, reference.scope);
|
|
377
341
|
}
|
|
378
|
-
function
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
const
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
out.push(elsePath);
|
|
342
|
+
function attribute(transitions, reference) {
|
|
343
|
+
return transitions.map((transition) => ({
|
|
344
|
+
...transition,
|
|
345
|
+
metadata: (0, import_behavioral_ir2.withWrapperMetadata)(transition.metadata, { from: reference })
|
|
346
|
+
}));
|
|
347
|
+
}
|
|
348
|
+
function withDistinctIds(transitions) {
|
|
349
|
+
const seen = /* @__PURE__ */ new Map();
|
|
350
|
+
return transitions.map((transition) => {
|
|
351
|
+
const taken = seen.get(transition.id);
|
|
352
|
+
seen.set(transition.id, (taken ?? 0) + 1);
|
|
353
|
+
return taken === void 0 ? transition : { ...transition, id: `${transition.id}#${taken + 1}` };
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// src/effectGuards.ts
|
|
358
|
+
var keyOf = (condition) => `${condition.polarity}:${condition.sourceText}`;
|
|
359
|
+
var opposite = (condition) => `${condition.polarity === "positive" ? "negative" : "positive"}:${condition.sourceText}`;
|
|
360
|
+
function guardsHoldOn(preconditions, conditions) {
|
|
361
|
+
if (preconditions === void 0 || preconditions.length === 0) {
|
|
362
|
+
return true;
|
|
400
363
|
}
|
|
401
|
-
|
|
364
|
+
const onBranch = new Set(conditions.map(keyOf));
|
|
365
|
+
return preconditions.every(
|
|
366
|
+
(precondition) => !onBranch.has(opposite(precondition))
|
|
367
|
+
);
|
|
402
368
|
}
|
|
403
|
-
function
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
}
|
|
419
|
-
out.push(...conts);
|
|
369
|
+
function runsBefore(effectLine, terminalEndLine) {
|
|
370
|
+
return effectLine <= terminalEndLine;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// src/moduleImports.ts
|
|
374
|
+
function stampModuleImports(summaries, importsOf) {
|
|
375
|
+
const byFile = /* @__PURE__ */ new Map();
|
|
376
|
+
for (const summary of summaries) {
|
|
377
|
+
const file = summary.location.file;
|
|
378
|
+
if (!byFile.has(file)) {
|
|
379
|
+
const found = importsOf(file);
|
|
380
|
+
byFile.set(
|
|
381
|
+
file,
|
|
382
|
+
found === void 0 ? void 0 : [...new Set(found)].sort()
|
|
383
|
+
);
|
|
420
384
|
}
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
const exit = exitKindOfList(group.body);
|
|
425
|
-
const negationSource = exit === "throw" ? "earlyThrow" : exit === "return" ? "earlyReturn" : "explicit";
|
|
426
|
-
negations.push(fixedCond(group.condition, "negative", negationSource));
|
|
385
|
+
const imports = byFile.get(file);
|
|
386
|
+
if (imports === void 0) {
|
|
387
|
+
continue;
|
|
427
388
|
}
|
|
389
|
+
summary.metadata = {
|
|
390
|
+
...summary.metadata ?? {},
|
|
391
|
+
moduleImports: imports
|
|
392
|
+
};
|
|
428
393
|
}
|
|
429
|
-
if (!defaultRanBody) {
|
|
430
|
-
out.push([...path4, ...negations]);
|
|
431
|
-
}
|
|
432
|
-
return out;
|
|
433
394
|
}
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
395
|
+
|
|
396
|
+
// src/moduleInit.ts
|
|
397
|
+
function moduleInitStructure(options) {
|
|
398
|
+
const { name, file, range, effects } = options;
|
|
399
|
+
return {
|
|
400
|
+
identity: {
|
|
401
|
+
name,
|
|
402
|
+
kind: "module-init",
|
|
403
|
+
file,
|
|
404
|
+
range,
|
|
405
|
+
exportName: null,
|
|
406
|
+
exportPath: null
|
|
407
|
+
},
|
|
408
|
+
boundaryBinding: null,
|
|
409
|
+
parameters: [],
|
|
410
|
+
branches: [
|
|
411
|
+
{
|
|
412
|
+
conditions: [],
|
|
413
|
+
terminal: {
|
|
414
|
+
kind: "void",
|
|
415
|
+
statusCode: null,
|
|
416
|
+
body: null,
|
|
417
|
+
exceptionType: null,
|
|
418
|
+
message: null,
|
|
419
|
+
component: null,
|
|
420
|
+
renderTree: null,
|
|
421
|
+
delegateTarget: null,
|
|
422
|
+
emitEvent: null,
|
|
423
|
+
location: range
|
|
424
|
+
},
|
|
425
|
+
effects: [],
|
|
426
|
+
extraEffects: effects,
|
|
427
|
+
location: range,
|
|
428
|
+
isDefault: true
|
|
429
|
+
}
|
|
430
|
+
],
|
|
431
|
+
unmatchedReturns: 0,
|
|
432
|
+
dependencyCalls: [],
|
|
433
|
+
declaredContract: null
|
|
434
|
+
};
|
|
463
435
|
}
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
436
|
+
|
|
437
|
+
// src/packHelpers.ts
|
|
438
|
+
function httpRouteDiscovery(opts) {
|
|
439
|
+
const kind = opts.kind ?? "handler";
|
|
440
|
+
const calls = opts.importNames.map((importName) => ({
|
|
441
|
+
kind,
|
|
442
|
+
match: {
|
|
443
|
+
type: "registrationCall",
|
|
444
|
+
importModule: opts.importModule,
|
|
445
|
+
importName,
|
|
446
|
+
registrationChain: [...opts.methods]
|
|
447
|
+
},
|
|
448
|
+
bindingExtraction: {
|
|
449
|
+
// `.all` registers every method, so it records "*", which the pairing
|
|
450
|
+
// engine treats as agreeing with any method at all.
|
|
451
|
+
method: {
|
|
452
|
+
type: "fromRegistration",
|
|
453
|
+
position: "methodName",
|
|
454
|
+
nameMap: { all: "*" }
|
|
455
|
+
},
|
|
456
|
+
path: { type: "fromArgument", position: 0 }
|
|
457
|
+
},
|
|
458
|
+
...opts.mount !== void 0 ? { mount: opts.mount } : {},
|
|
459
|
+
requiresImport: [opts.importModule]
|
|
460
|
+
}));
|
|
461
|
+
if (opts.importNames.length === 0) {
|
|
462
|
+
return calls;
|
|
468
463
|
}
|
|
469
|
-
return [
|
|
464
|
+
return [
|
|
465
|
+
...calls,
|
|
466
|
+
// Routes registered in a loop over an array of specs, a shape
|
|
467
|
+
// registration-call discovery cannot see. The receiver comes from
|
|
468
|
+
// the same import declaration as the calls above, so a loop that
|
|
469
|
+
// never touches this library's routable is left alone.
|
|
470
|
+
{
|
|
471
|
+
kind,
|
|
472
|
+
match: {
|
|
473
|
+
type: "registrationLoop",
|
|
474
|
+
elementShape: LOOP_ELEMENT_SHAPE,
|
|
475
|
+
receiver: {
|
|
476
|
+
importModule: opts.importModule,
|
|
477
|
+
importNames: [...opts.importNames]
|
|
478
|
+
}
|
|
479
|
+
},
|
|
480
|
+
requiresImport: [opts.importModule]
|
|
481
|
+
}
|
|
482
|
+
];
|
|
470
483
|
}
|
|
471
|
-
function
|
|
472
|
-
return
|
|
484
|
+
function wrapperDiscovery(opts) {
|
|
485
|
+
return opts.importNames.flatMap(
|
|
486
|
+
(importName) => opts.wraps.map((wraps) => ({
|
|
487
|
+
kind: opts.kind ?? "middleware",
|
|
488
|
+
match: {
|
|
489
|
+
type: "registrationCall",
|
|
490
|
+
importModule: opts.importModule,
|
|
491
|
+
importName,
|
|
492
|
+
registrationChain: []
|
|
493
|
+
},
|
|
494
|
+
wraps: { ...wraps },
|
|
495
|
+
requiresImport: [opts.importModule]
|
|
496
|
+
}))
|
|
497
|
+
);
|
|
473
498
|
}
|
|
474
|
-
var
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
try: stepTry,
|
|
479
|
-
exit: stepExit,
|
|
480
|
-
opaque: stepOpaque
|
|
499
|
+
var LOOP_ELEMENT_SHAPE = {
|
|
500
|
+
methodKey: "method",
|
|
501
|
+
pathKey: "path",
|
|
502
|
+
handlerKey: "handler"
|
|
481
503
|
};
|
|
482
|
-
function
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
const out = [...fellThrough, ...exits];
|
|
492
|
-
return out.length === 0 ? [path4] : out;
|
|
493
|
-
}
|
|
494
|
-
function stepStatement(ctx, stmt, path4) {
|
|
495
|
-
let paths = [path4];
|
|
496
|
-
for (const body of stmt.callbacks ?? []) {
|
|
497
|
-
paths = paths.flatMap((each) => stepCallback(ctx, body, each));
|
|
498
|
-
}
|
|
499
|
-
const ownTerminals = ctx.terminalsByStmt.get(stmt) ?? [];
|
|
500
|
-
for (const each of withRejoined(paths)) {
|
|
501
|
-
for (const terminal of ownTerminals) {
|
|
502
|
-
recordTerminal(ctx, terminal, stmt, each);
|
|
504
|
+
function registrationHelperDiscovery(helpers, kind = "handler") {
|
|
505
|
+
return helpers.map((helper) => ({
|
|
506
|
+
kind,
|
|
507
|
+
match: {
|
|
508
|
+
type: "registrationTemplate",
|
|
509
|
+
helperName: helper.helperName,
|
|
510
|
+
...helper.importModule !== void 0 ? { importModule: helper.importModule } : {},
|
|
511
|
+
...helper.subject !== void 0 ? { subject: helper.subject } : {},
|
|
512
|
+
registrations: helper.registrations.map((one) => ({ ...one }))
|
|
503
513
|
}
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
ctx
|
|
514
|
+
}));
|
|
515
|
+
}
|
|
516
|
+
function routeHelperIndex(opts) {
|
|
517
|
+
const methods = new Set(
|
|
518
|
+
opts.methods.map(
|
|
519
|
+
(method) => method.startsWith(".") ? method.slice(1) : method
|
|
511
520
|
)
|
|
512
521
|
);
|
|
522
|
+
return {
|
|
523
|
+
find: { by: "subject" },
|
|
524
|
+
declare: (helpers) => ({
|
|
525
|
+
discovery: registrationHelperDiscovery(
|
|
526
|
+
helpers.flatMap((helper) => routesRegisteredBy(helper, methods, opts)),
|
|
527
|
+
opts.kind ?? "handler"
|
|
528
|
+
)
|
|
529
|
+
})
|
|
530
|
+
};
|
|
513
531
|
}
|
|
514
|
-
function
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
const one = left[at];
|
|
521
|
-
const other = right[at];
|
|
522
|
-
if (one === other) {
|
|
532
|
+
function routesRegisteredBy(helper, methods, opts) {
|
|
533
|
+
const registrations = [];
|
|
534
|
+
let subjectArgument;
|
|
535
|
+
for (const sink of helper.sinks) {
|
|
536
|
+
const registration = routeRegisteredBy(helper, sink, methods);
|
|
537
|
+
if (registration === null) {
|
|
523
538
|
continue;
|
|
524
539
|
}
|
|
525
|
-
|
|
526
|
-
|
|
540
|
+
registrations.push(registration);
|
|
541
|
+
if (sink.receiver.as === "parameter") {
|
|
542
|
+
subjectArgument = sink.receiver.position;
|
|
527
543
|
}
|
|
528
|
-
|
|
529
|
-
|
|
544
|
+
}
|
|
545
|
+
if (registrations.length === 0 || subjectArgument === void 0) {
|
|
546
|
+
return [];
|
|
547
|
+
}
|
|
548
|
+
return [
|
|
549
|
+
{
|
|
550
|
+
helperName: helper.name,
|
|
551
|
+
importModule: helper.file,
|
|
552
|
+
subject: {
|
|
553
|
+
argument: subjectArgument,
|
|
554
|
+
importModule: opts.importModule,
|
|
555
|
+
importNames: [...opts.importNames]
|
|
556
|
+
},
|
|
557
|
+
registrations
|
|
530
558
|
}
|
|
531
|
-
|
|
559
|
+
];
|
|
560
|
+
}
|
|
561
|
+
function routeRegisteredBy(helper, sink, methods) {
|
|
562
|
+
if (sink.method === null || !methods.has(sink.method)) {
|
|
563
|
+
return null;
|
|
532
564
|
}
|
|
533
|
-
|
|
565
|
+
const { receiver } = sink;
|
|
566
|
+
if (receiver.as !== "parameter" || receiver.property !== void 0 || !helper.subjectParameters.includes(receiver.position)) {
|
|
567
|
+
return null;
|
|
568
|
+
}
|
|
569
|
+
const pathTemplate = sink.arguments[0];
|
|
570
|
+
const handler = sink.arguments[sink.arguments.length - 1];
|
|
571
|
+
if (sink.arguments.length < 2 || pathTemplate === void 0 || pathTemplate.as !== "text" || handler === void 0) {
|
|
572
|
+
return null;
|
|
573
|
+
}
|
|
574
|
+
const handlerArg = handlerSlot(handler);
|
|
575
|
+
return handlerArg === null ? null : {
|
|
576
|
+
// `.all` registers every method, which the pairing engine
|
|
577
|
+
// spells as a wildcard.
|
|
578
|
+
method: sink.method === "all" ? "*" : sink.method.toUpperCase(),
|
|
579
|
+
pathTemplate: pathTemplate.text,
|
|
580
|
+
handlerArg
|
|
581
|
+
};
|
|
534
582
|
}
|
|
535
|
-
function
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
const out = [];
|
|
539
|
-
const taken = /* @__PURE__ */ new Set();
|
|
540
|
-
let mergedAny = false;
|
|
541
|
-
for (let i = 0; i < current.length; i++) {
|
|
542
|
-
if (taken.has(i)) {
|
|
543
|
-
continue;
|
|
544
|
-
}
|
|
545
|
-
let combined = current[i];
|
|
546
|
-
for (let j = i + 1; j < current.length; j++) {
|
|
547
|
-
if (taken.has(j)) {
|
|
548
|
-
continue;
|
|
549
|
-
}
|
|
550
|
-
const at = soleDisagreement(combined, current[j]);
|
|
551
|
-
if (at === null) {
|
|
552
|
-
continue;
|
|
553
|
-
}
|
|
554
|
-
combined = [...combined.slice(0, at), ...combined.slice(at + 1)];
|
|
555
|
-
taken.add(j);
|
|
556
|
-
mergedAny = true;
|
|
557
|
-
break;
|
|
558
|
-
}
|
|
559
|
-
out.push(combined);
|
|
560
|
-
}
|
|
561
|
-
current = out;
|
|
562
|
-
if (!mergedAny) {
|
|
563
|
-
break;
|
|
564
|
-
}
|
|
583
|
+
function handlerSlot(value) {
|
|
584
|
+
if (value.as !== "parameter") {
|
|
585
|
+
return null;
|
|
565
586
|
}
|
|
566
|
-
return
|
|
567
|
-
}
|
|
568
|
-
function withRejoined(paths) {
|
|
569
|
-
const merged = mergeRejoined(paths);
|
|
570
|
-
return merged.length === paths.length ? paths : [...merged, ...paths];
|
|
587
|
+
return value.property === void 0 ? `{${value.position}}` : `{${value.position}}.${value.property}`;
|
|
571
588
|
}
|
|
572
|
-
function
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
const nextFrontiers = [];
|
|
576
|
-
for (const path4 of mergeRejoined(frontiers)) {
|
|
577
|
-
nextFrontiers.push(...stepStatement(ctx, stmt, path4));
|
|
578
|
-
}
|
|
579
|
-
frontiers = nextFrontiers;
|
|
580
|
-
if (frontiers.length > MAX_PATHS) {
|
|
581
|
-
throw new PathBudgetExceeded(
|
|
582
|
-
`path budget exceeded, more than ${MAX_PATHS} paths`
|
|
583
|
-
);
|
|
584
|
-
}
|
|
585
|
-
if (frontiers.length === 0) {
|
|
586
|
-
break;
|
|
587
|
-
}
|
|
589
|
+
function unwrapJsonStringify(body) {
|
|
590
|
+
if (body === null || typeof body !== "object") {
|
|
591
|
+
return body;
|
|
588
592
|
}
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
const parentOf = /* @__PURE__ */ new Map();
|
|
593
|
-
const visit = (stmt, parent) => {
|
|
594
|
-
parentOf.set(stmt, parent);
|
|
595
|
-
for (const child of childrenOf(stmt)) {
|
|
596
|
-
visit(child, stmt);
|
|
597
|
-
}
|
|
598
|
-
};
|
|
599
|
-
for (const stmt of statements) {
|
|
600
|
-
visit(stmt, null);
|
|
593
|
+
const candidate = body;
|
|
594
|
+
if (candidate.kind !== "call" || candidate.callee !== "JSON.stringify") {
|
|
595
|
+
return body;
|
|
601
596
|
}
|
|
602
|
-
|
|
597
|
+
const inner = candidate.args?.[0];
|
|
598
|
+
return inner ?? body;
|
|
603
599
|
}
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
600
|
+
|
|
601
|
+
// src/packOptions.ts
|
|
602
|
+
var import_zod = require("zod");
|
|
603
|
+
var storageSystemOption = import_zod.z.enum([
|
|
604
|
+
"postgresql",
|
|
605
|
+
"mysql",
|
|
606
|
+
"sqlite"
|
|
607
|
+
]);
|
|
608
|
+
var scopeOption = import_zod.z.string();
|
|
609
|
+
var configuredCallOption = import_zod.z.object({
|
|
610
|
+
/** Module that declares the receiver's type. */
|
|
611
|
+
module: import_zod.z.string(),
|
|
612
|
+
/** Type name of the receiver, as exported from that module. */
|
|
613
|
+
receiver: import_zod.z.string(),
|
|
614
|
+
/** Method that performs the send. */
|
|
615
|
+
method: import_zod.z.string(),
|
|
616
|
+
/** Argument index carrying the subject. */
|
|
617
|
+
subjectArg: import_zod.z.number(),
|
|
618
|
+
/**
|
|
619
|
+
* Which argument the message body is. Left out when the method has no
|
|
620
|
+
* single body argument, as a batch method taking a list of entries
|
|
621
|
+
* does, and then no body is reported.
|
|
622
|
+
*/
|
|
623
|
+
bodyArg: import_zod.z.number().optional()
|
|
624
|
+
}).strict();
|
|
625
|
+
|
|
626
|
+
// src/paths/enumeratePaths.ts
|
|
627
|
+
var import_behavioral_ir3 = require("@suss/behavioral-ir");
|
|
628
|
+
var MAX_PATHS = 256;
|
|
629
|
+
var UnmodeledFlow = class extends Error {
|
|
630
|
+
};
|
|
631
|
+
var PathBudgetExceeded = class extends Error {
|
|
632
|
+
};
|
|
633
|
+
function branchCond(branchStmt, condition, polarity, oppositeExit) {
|
|
634
|
+
return {
|
|
635
|
+
info: {
|
|
636
|
+
sourceText: condition.sourceText,
|
|
637
|
+
polarity,
|
|
638
|
+
source: "explicit",
|
|
639
|
+
expression: condition.expression
|
|
640
|
+
},
|
|
641
|
+
branchStmt,
|
|
642
|
+
oppositeExit
|
|
621
643
|
};
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
644
|
+
}
|
|
645
|
+
function fixedCond(condition, polarity, source) {
|
|
646
|
+
return {
|
|
647
|
+
info: {
|
|
648
|
+
sourceText: condition.sourceText,
|
|
649
|
+
polarity,
|
|
650
|
+
source,
|
|
651
|
+
expression: condition.expression
|
|
652
|
+
},
|
|
653
|
+
branchStmt: null,
|
|
654
|
+
oppositeExit: null
|
|
626
655
|
};
|
|
627
|
-
const continuations = withRejoined(enumerate(ctx, input.statements, []));
|
|
628
|
-
for (const path4 of continuations) {
|
|
629
|
-
chargeBudget(state);
|
|
630
|
-
state.fallthrough.push(classify(path4, null, isAncestorOrSelf));
|
|
631
|
-
}
|
|
632
|
-
return { byTerminal: state.byTerminal, fallthrough: state.fallthrough };
|
|
633
656
|
}
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
657
|
+
var loopIterationCond = (headerText) => fixedCond(
|
|
658
|
+
{ sourceText: `some iteration of: ${headerText}`, expression: null },
|
|
659
|
+
"positive",
|
|
660
|
+
"explicit"
|
|
661
|
+
);
|
|
662
|
+
var loopCompletedCond = (headerText, exit) => fixedCond(
|
|
663
|
+
{
|
|
664
|
+
sourceText: `loop exited via ${exit ?? "return"}: ${headerText}`,
|
|
665
|
+
expression: null
|
|
666
|
+
},
|
|
667
|
+
"negative",
|
|
668
|
+
exit === "throw" ? "earlyThrow" : "earlyReturn"
|
|
669
|
+
);
|
|
670
|
+
var catchEntryCond = () => fixedCond(
|
|
671
|
+
{ sourceText: import_behavioral_ir3.CATCH_ENTRY_TEXT, expression: null },
|
|
672
|
+
"positive",
|
|
673
|
+
"catchBlock"
|
|
674
|
+
);
|
|
675
|
+
function classify(path4, home, isAncestorOrSelf) {
|
|
676
|
+
return path4.map((cond) => {
|
|
677
|
+
if (cond.branchStmt === null) {
|
|
678
|
+
return cond.info;
|
|
641
679
|
}
|
|
642
|
-
const
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
source: "explicit",
|
|
646
|
-
expression: null
|
|
647
|
-
};
|
|
648
|
-
const byTerminal = /* @__PURE__ */ new Map();
|
|
649
|
-
for (const terminal of terminals) {
|
|
650
|
-
byTerminal.set(terminal, [[marker]]);
|
|
680
|
+
const encloses = home !== null && isAncestorOrSelf(cond.branchStmt, home);
|
|
681
|
+
if (encloses || cond.info.polarity === "positive" || cond.oppositeExit === null) {
|
|
682
|
+
return { ...cond.info, source: "explicit" };
|
|
651
683
|
}
|
|
652
|
-
|
|
653
|
-
|
|
684
|
+
const source = cond.oppositeExit === "throw" ? "earlyThrow" : "earlyReturn";
|
|
685
|
+
return { ...cond.info, source };
|
|
686
|
+
});
|
|
654
687
|
}
|
|
655
|
-
function
|
|
656
|
-
|
|
657
|
-
|
|
688
|
+
function childrenOf(stmt) {
|
|
689
|
+
return [...ownBlocksOf(stmt), ...(stmt.callbacks ?? []).flat()];
|
|
690
|
+
}
|
|
691
|
+
function ownBlocksOf(stmt) {
|
|
692
|
+
if (stmt.kind === "if") {
|
|
693
|
+
return stmt.elseBody === null ? stmt.thenBody : [...stmt.thenBody, ...stmt.elseBody];
|
|
658
694
|
}
|
|
659
|
-
if (
|
|
660
|
-
return
|
|
695
|
+
if (stmt.kind === "switch") {
|
|
696
|
+
return stmt.groups.flatMap((g) => g.body);
|
|
661
697
|
}
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
// src/composeWrappers.ts
|
|
666
|
-
var BUDGET_GAP = {
|
|
667
|
-
type: "unreadOutcome",
|
|
668
|
-
conditions: [],
|
|
669
|
-
consequence: "unknown",
|
|
670
|
-
description: `Composing the wrappers registered around this unit would have gone past the path budget of ${MAX_PATHS}, so what each of them produces is reported beside this unit's own outcomes rather than under the conditions that reach it`
|
|
671
|
-
};
|
|
672
|
-
function composeWrappers(summaries, options = {}) {
|
|
673
|
-
const byKey = /* @__PURE__ */ new Map();
|
|
674
|
-
for (const summary of summaries) {
|
|
675
|
-
const key = summaryKey(summary.location.file, summary.identity.name);
|
|
676
|
-
const sharing = byKey.get(key);
|
|
677
|
-
if (sharing === void 0) {
|
|
678
|
-
byKey.set(key, [summary]);
|
|
679
|
-
continue;
|
|
680
|
-
}
|
|
681
|
-
sharing.push(summary);
|
|
698
|
+
if (stmt.kind === "loop") {
|
|
699
|
+
return stmt.body;
|
|
682
700
|
}
|
|
683
|
-
|
|
684
|
-
|
|
701
|
+
if (stmt.kind === "try") {
|
|
702
|
+
return [
|
|
703
|
+
...stmt.tryBody,
|
|
704
|
+
...stmt.catchBody ?? [],
|
|
705
|
+
...stmt.finallyBody ?? []
|
|
706
|
+
];
|
|
707
|
+
}
|
|
708
|
+
return [];
|
|
685
709
|
}
|
|
686
|
-
function
|
|
687
|
-
return
|
|
710
|
+
function hasStrayBreak(nodes) {
|
|
711
|
+
return nodes.some((node) => {
|
|
712
|
+
if (node.kind === "exit" && node.exit === "break") {
|
|
713
|
+
return true;
|
|
714
|
+
}
|
|
715
|
+
if (node.kind === "switch" || node.kind === "loop") {
|
|
716
|
+
return false;
|
|
717
|
+
}
|
|
718
|
+
return hasStrayBreak(ownBlocksOf(node));
|
|
719
|
+
});
|
|
688
720
|
}
|
|
689
|
-
function
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
721
|
+
function exitKindOfList(stmts) {
|
|
722
|
+
let sawReturn = false;
|
|
723
|
+
for (const stmt of stmts) {
|
|
724
|
+
if (stmt.exitKind === "throw") {
|
|
725
|
+
return "throw";
|
|
726
|
+
}
|
|
727
|
+
if (stmt.exitKind === "return") {
|
|
728
|
+
sawReturn = true;
|
|
729
|
+
}
|
|
693
730
|
}
|
|
694
|
-
return
|
|
731
|
+
return sawReturn ? "return" : null;
|
|
695
732
|
}
|
|
696
|
-
function
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
const narrowed = covering.length === applied.length ? summary : {
|
|
703
|
-
...summary,
|
|
704
|
-
metadata: (0, import_behavioral_ir3.withWrapperMetadata)(summary.metadata, {
|
|
705
|
-
applied: covering
|
|
706
|
-
})
|
|
707
|
-
};
|
|
708
|
-
const wrappers = covering.flatMap((reference) => {
|
|
709
|
-
const found = summaryOf(reference, byKey);
|
|
710
|
-
return found === void 0 ? [] : [{ reference, summary: found }];
|
|
711
|
-
});
|
|
712
|
-
if (wrappers.length === 0) {
|
|
713
|
-
return narrowed;
|
|
714
|
-
}
|
|
715
|
-
let composition = {
|
|
716
|
-
transitions: summary.transitions,
|
|
717
|
-
degraded: false
|
|
718
|
-
};
|
|
719
|
-
for (const wrapper of [...wrappers].reverse()) {
|
|
720
|
-
if (wrapper.reference.onThrow === true) {
|
|
721
|
-
continue;
|
|
722
|
-
}
|
|
723
|
-
composition = merge(composition, applyWrapper(wrapper, composition));
|
|
724
|
-
}
|
|
725
|
-
for (const wrapper of wrappers) {
|
|
726
|
-
if (wrapper.reference.onThrow !== true) {
|
|
727
|
-
continue;
|
|
728
|
-
}
|
|
729
|
-
composition = merge(composition, applyThrowWrapper(wrapper, composition));
|
|
730
|
-
}
|
|
731
|
-
const transitions = composition.transitions === summary.transitions ? summary.transitions : withDistinctIds(composition.transitions);
|
|
732
|
-
if (!keepGaps) {
|
|
733
|
-
return { ...narrowed, transitions };
|
|
734
|
-
}
|
|
735
|
-
const gaps = withContractStatusGaps(summary, transitions, wrappers);
|
|
736
|
-
if (transitions === summary.transitions && gaps === summary.gaps) {
|
|
737
|
-
return narrowed;
|
|
733
|
+
function chargeBudget(state) {
|
|
734
|
+
state.pathCount++;
|
|
735
|
+
if (state.pathCount > MAX_PATHS) {
|
|
736
|
+
throw new PathBudgetExceeded(
|
|
737
|
+
`path budget exceeded, more than ${MAX_PATHS} paths`
|
|
738
|
+
);
|
|
738
739
|
}
|
|
739
|
-
return {
|
|
740
|
-
...narrowed,
|
|
741
|
-
transitions,
|
|
742
|
-
gaps: composition.degraded ? [...gaps, BUDGET_GAP] : gaps
|
|
743
|
-
};
|
|
744
740
|
}
|
|
745
|
-
function
|
|
746
|
-
|
|
747
|
-
const
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
const declared = {
|
|
752
|
-
framework: contract.framework ?? "declared",
|
|
753
|
-
responses: contract.responses
|
|
754
|
-
};
|
|
755
|
-
const stale = new Set(
|
|
756
|
-
contractStatusGaps(declared, summary.transitions).map(gapKey)
|
|
757
|
-
);
|
|
758
|
-
const onThrow = wrappers.filter((wrapper) => wrapper.reference.onThrow === true).flatMap(
|
|
759
|
-
(wrapper) => attribute(wrapper.summary.transitions, wrapper.reference)
|
|
760
|
-
);
|
|
761
|
-
const gaps = [
|
|
762
|
-
...summary.gaps.filter((gap) => !stale.has(gapKey(gap))),
|
|
763
|
-
...contractStatusGaps(declared, [...composed, ...onThrow])
|
|
764
|
-
];
|
|
765
|
-
const unchanged = gaps.length === summary.gaps.length && gaps.every((gap, i) => gapKey(gap) === gapKey(summary.gaps[i]));
|
|
766
|
-
return unchanged ? summary.gaps : gaps;
|
|
767
|
-
}
|
|
768
|
-
function gapKey(gap) {
|
|
769
|
-
return `${gap.type}|${gap.description}`;
|
|
770
|
-
}
|
|
771
|
-
function merge(before, step) {
|
|
772
|
-
return {
|
|
773
|
-
transitions: step.transitions,
|
|
774
|
-
degraded: before.degraded || step.degraded
|
|
775
|
-
};
|
|
741
|
+
function recordTerminal(ctx, terminal, home, path4) {
|
|
742
|
+
chargeBudget(ctx.state);
|
|
743
|
+
const info = classify(path4, home, ctx.isAncestorOrSelf);
|
|
744
|
+
const existing = ctx.state.byTerminal.get(terminal) ?? [];
|
|
745
|
+
existing.push(info);
|
|
746
|
+
ctx.state.byTerminal.set(terminal, existing);
|
|
776
747
|
}
|
|
777
|
-
function
|
|
778
|
-
if (
|
|
748
|
+
function containsTerminal(ctx, stmt) {
|
|
749
|
+
if ((ctx.terminalsByStmt.get(stmt)?.length ?? 0) > 0) {
|
|
779
750
|
return true;
|
|
780
751
|
}
|
|
781
|
-
|
|
782
|
-
return binding !== null && (0, import_behavioral_ir3.withinScope)(binding, reference.scope);
|
|
783
|
-
}
|
|
784
|
-
function applyWrapper(wrapper, inner) {
|
|
785
|
-
const shortCircuits = attribute(
|
|
786
|
-
wrapper.summary.transitions.filter((t) => t.output.type !== "delegate"),
|
|
787
|
-
wrapper.reference
|
|
788
|
-
);
|
|
789
|
-
const passThroughs = withoutCoveredPassThroughs(
|
|
790
|
-
wrapper.summary.transitions.filter((t) => t.output.type === "delegate")
|
|
791
|
-
);
|
|
792
|
-
if (passThroughs.length === 0 || shortCircuits.length + passThroughs.length * inner.transitions.length > MAX_PATHS) {
|
|
793
|
-
return {
|
|
794
|
-
transitions: [...shortCircuits, ...inner.transitions],
|
|
795
|
-
degraded: passThroughs.length > 0
|
|
796
|
-
};
|
|
797
|
-
}
|
|
798
|
-
const continued = passThroughs.flatMap(
|
|
799
|
-
(passThrough) => inner.transitions.map((transition) => splice(passThrough, transition))
|
|
800
|
-
);
|
|
801
|
-
return { transitions: [...shortCircuits, ...continued], degraded: false };
|
|
752
|
+
return childrenOf(stmt).some((child) => containsTerminal(ctx, child));
|
|
802
753
|
}
|
|
803
|
-
function
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
754
|
+
function stepIf(stmt, path4, ctx) {
|
|
755
|
+
const thenExit = exitKindOfList(stmt.thenBody);
|
|
756
|
+
const elseExit = stmt.elseBody === null ? null : exitKindOfList(stmt.elseBody);
|
|
757
|
+
const thenPath = [
|
|
758
|
+
...path4,
|
|
759
|
+
branchCond(stmt, stmt.condition, "positive", elseExit)
|
|
760
|
+
];
|
|
761
|
+
const elsePath = [
|
|
762
|
+
...path4,
|
|
763
|
+
branchCond(
|
|
764
|
+
stmt,
|
|
765
|
+
stmt.condition,
|
|
766
|
+
"negative",
|
|
767
|
+
stmt.elseBody === null ? thenExit : null
|
|
807
768
|
)
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
if (
|
|
812
|
-
|
|
769
|
+
];
|
|
770
|
+
const out = [];
|
|
771
|
+
out.push(...enumerate(ctx, stmt.thenBody, thenPath));
|
|
772
|
+
if (stmt.elseBody !== null) {
|
|
773
|
+
out.push(...enumerate(ctx, stmt.elseBody, elsePath));
|
|
774
|
+
} else {
|
|
775
|
+
out.push(elsePath);
|
|
813
776
|
}
|
|
814
|
-
|
|
815
|
-
return wider.conditions.every((c) => required.has(JSON.stringify(c)));
|
|
777
|
+
return out;
|
|
816
778
|
}
|
|
817
|
-
function
|
|
818
|
-
const
|
|
819
|
-
|
|
820
|
-
|
|
779
|
+
function stepSwitch(stmt, path4, ctx) {
|
|
780
|
+
const out = [];
|
|
781
|
+
const negations = [];
|
|
782
|
+
let defaultRanBody = false;
|
|
783
|
+
for (let i = 0; i < stmt.groups.length; i++) {
|
|
784
|
+
const group = stmt.groups[i];
|
|
785
|
+
const fallthroughSafe = i === stmt.groups.length - 1;
|
|
786
|
+
if (hasStrayBreak(group.body)) {
|
|
787
|
+
throw new UnmodeledFlow("non-trailing break in switch clause");
|
|
788
|
+
}
|
|
789
|
+
const groupPath = group.condition === null ? [...path4, ...negations] : [...path4, fixedCond(group.condition, "positive", "explicit")];
|
|
790
|
+
const conts = enumerate(ctx, group.body, groupPath);
|
|
791
|
+
if (conts.length > 0) {
|
|
792
|
+
if (!group.hasTrailingBreak && !fallthroughSafe) {
|
|
793
|
+
throw new UnmodeledFlow("fallthrough into a non-empty switch clause");
|
|
794
|
+
}
|
|
795
|
+
out.push(...conts);
|
|
796
|
+
}
|
|
797
|
+
if (group.condition === null) {
|
|
798
|
+
defaultRanBody = true;
|
|
799
|
+
} else {
|
|
800
|
+
const exit = exitKindOfList(group.body);
|
|
801
|
+
const negationSource = exit === "throw" ? "earlyThrow" : exit === "return" ? "earlyReturn" : "explicit";
|
|
802
|
+
negations.push(fixedCond(group.condition, "negative", negationSource));
|
|
803
|
+
}
|
|
821
804
|
}
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
if (rest.length + thrown.length * handled.length > MAX_PATHS) {
|
|
825
|
-
return {
|
|
826
|
-
transitions: [
|
|
827
|
-
...inner.transitions,
|
|
828
|
-
...attribute(handled, wrapper.reference)
|
|
829
|
-
],
|
|
830
|
-
degraded: true
|
|
831
|
-
};
|
|
805
|
+
if (!defaultRanBody) {
|
|
806
|
+
out.push([...path4, ...negations]);
|
|
832
807
|
}
|
|
833
|
-
|
|
834
|
-
(transition) => attribute(
|
|
835
|
-
handled.map((handler) => splice(transition, handler)),
|
|
836
|
-
wrapper.reference
|
|
837
|
-
)
|
|
838
|
-
);
|
|
839
|
-
return { transitions: [...rest, ...composed], degraded: false };
|
|
840
|
-
}
|
|
841
|
-
function splice(outer, inner) {
|
|
842
|
-
return {
|
|
843
|
-
...inner,
|
|
844
|
-
id: `${inner.id}:via:${outer.id}`,
|
|
845
|
-
conditions: [...outer.conditions, ...inner.conditions],
|
|
846
|
-
effects: [...outer.effects, ...inner.effects],
|
|
847
|
-
isDefault: outer.isDefault && inner.isDefault
|
|
848
|
-
};
|
|
849
|
-
}
|
|
850
|
-
function attribute(transitions, reference) {
|
|
851
|
-
return transitions.map((transition) => ({
|
|
852
|
-
...transition,
|
|
853
|
-
metadata: (0, import_behavioral_ir3.withWrapperMetadata)(transition.metadata, { from: reference })
|
|
854
|
-
}));
|
|
855
|
-
}
|
|
856
|
-
function withDistinctIds(transitions) {
|
|
857
|
-
const seen = /* @__PURE__ */ new Map();
|
|
858
|
-
return transitions.map((transition) => {
|
|
859
|
-
const taken = seen.get(transition.id);
|
|
860
|
-
seen.set(transition.id, (taken ?? 0) + 1);
|
|
861
|
-
return taken === void 0 ? transition : { ...transition, id: `${transition.id}#${taken + 1}` };
|
|
862
|
-
});
|
|
808
|
+
return out;
|
|
863
809
|
}
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
810
|
+
function stepLoop(stmt, path4, ctx) {
|
|
811
|
+
const bodyExit = exitKindOfList(stmt.body);
|
|
812
|
+
if (containsTerminal(ctx, stmt)) {
|
|
813
|
+
enumerate(ctx, stmt.body, [
|
|
814
|
+
...path4,
|
|
815
|
+
loopIterationCond(stmt.condition.sourceText)
|
|
816
|
+
]);
|
|
871
817
|
}
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
}
|
|
877
|
-
function runsBefore(effectLine, terminalEndLine) {
|
|
878
|
-
return effectLine <= terminalEndLine;
|
|
818
|
+
if (bodyExit !== null) {
|
|
819
|
+
return [[...path4, loopCompletedCond(stmt.condition.sourceText, bodyExit)]];
|
|
820
|
+
}
|
|
821
|
+
return [path4];
|
|
879
822
|
}
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
const found = importsOf(file);
|
|
888
|
-
byFile.set(
|
|
889
|
-
file,
|
|
890
|
-
found === void 0 ? void 0 : [...new Set(found)].sort()
|
|
891
|
-
);
|
|
892
|
-
}
|
|
893
|
-
const imports = byFile.get(file);
|
|
894
|
-
if (imports === void 0) {
|
|
895
|
-
continue;
|
|
823
|
+
function stepTry(stmt, path4, ctx) {
|
|
824
|
+
if (stmt.finallyBody !== null) {
|
|
825
|
+
const finallyHasTerminal = stmt.finallyBody.some(
|
|
826
|
+
(s) => containsTerminal(ctx, s)
|
|
827
|
+
);
|
|
828
|
+
if (exitKindOfList(stmt.finallyBody) !== null || finallyHasTerminal) {
|
|
829
|
+
throw new UnmodeledFlow("finally block with exits or terminals");
|
|
896
830
|
}
|
|
897
|
-
summary.metadata = {
|
|
898
|
-
...summary.metadata ?? {},
|
|
899
|
-
moduleImports: imports
|
|
900
|
-
};
|
|
901
831
|
}
|
|
832
|
+
const out = [];
|
|
833
|
+
out.push(...enumerate(ctx, stmt.tryBody, path4));
|
|
834
|
+
if (stmt.catchBody !== null) {
|
|
835
|
+
const catchPath = [...path4, catchEntryCond()];
|
|
836
|
+
out.push(...enumerate(ctx, stmt.catchBody, catchPath));
|
|
837
|
+
}
|
|
838
|
+
return out;
|
|
902
839
|
}
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
return {
|
|
908
|
-
identity: {
|
|
909
|
-
name,
|
|
910
|
-
kind: "module-init",
|
|
911
|
-
file,
|
|
912
|
-
range,
|
|
913
|
-
exportName: null,
|
|
914
|
-
exportPath: null
|
|
915
|
-
},
|
|
916
|
-
boundaryBinding: null,
|
|
917
|
-
parameters: [],
|
|
918
|
-
branches: [
|
|
919
|
-
{
|
|
920
|
-
conditions: [],
|
|
921
|
-
terminal: {
|
|
922
|
-
kind: "void",
|
|
923
|
-
statusCode: null,
|
|
924
|
-
body: null,
|
|
925
|
-
exceptionType: null,
|
|
926
|
-
message: null,
|
|
927
|
-
component: null,
|
|
928
|
-
renderTree: null,
|
|
929
|
-
delegateTarget: null,
|
|
930
|
-
emitEvent: null,
|
|
931
|
-
location: range
|
|
932
|
-
},
|
|
933
|
-
effects: [],
|
|
934
|
-
extraEffects: effects,
|
|
935
|
-
location: range,
|
|
936
|
-
isDefault: true
|
|
937
|
-
}
|
|
938
|
-
],
|
|
939
|
-
unmatchedReturns: 0,
|
|
940
|
-
dependencyCalls: [],
|
|
941
|
-
declaredContract: null
|
|
942
|
-
};
|
|
943
|
-
}
|
|
944
|
-
|
|
945
|
-
// src/packHelpers.ts
|
|
946
|
-
function httpRouteDiscovery(opts) {
|
|
947
|
-
const kind = opts.kind ?? "handler";
|
|
948
|
-
const calls = opts.importNames.map((importName) => ({
|
|
949
|
-
kind,
|
|
950
|
-
match: {
|
|
951
|
-
type: "registrationCall",
|
|
952
|
-
importModule: opts.importModule,
|
|
953
|
-
importName,
|
|
954
|
-
registrationChain: [...opts.methods]
|
|
955
|
-
},
|
|
956
|
-
bindingExtraction: {
|
|
957
|
-
// `.all` registers every method, so it records "*", which the pairing
|
|
958
|
-
// engine treats as agreeing with any method at all.
|
|
959
|
-
method: {
|
|
960
|
-
type: "fromRegistration",
|
|
961
|
-
position: "methodName",
|
|
962
|
-
nameMap: { all: "*" }
|
|
963
|
-
},
|
|
964
|
-
path: { type: "fromArgument", position: 0 }
|
|
965
|
-
},
|
|
966
|
-
...opts.mount !== void 0 ? { mount: opts.mount } : {},
|
|
967
|
-
requiresImport: [opts.importModule]
|
|
968
|
-
}));
|
|
969
|
-
if (opts.importNames.length === 0) {
|
|
970
|
-
return calls;
|
|
840
|
+
function stepExit(stmt, path4, ctx) {
|
|
841
|
+
const collector = ctx.state.callbackExits[ctx.state.callbackExits.length - 1];
|
|
842
|
+
if (collector !== void 0 && (stmt.exit === "return" || stmt.exit === "throw")) {
|
|
843
|
+
collector.push(path4);
|
|
971
844
|
}
|
|
972
|
-
return [
|
|
973
|
-
...calls,
|
|
974
|
-
// Routes registered in a loop over an array of specs, a shape
|
|
975
|
-
// registration-call discovery cannot see. The receiver comes from
|
|
976
|
-
// the same import declaration as the calls above, so a loop that
|
|
977
|
-
// never touches this library's routable is left alone.
|
|
978
|
-
{
|
|
979
|
-
kind,
|
|
980
|
-
match: {
|
|
981
|
-
type: "registrationLoop",
|
|
982
|
-
elementShape: LOOP_ELEMENT_SHAPE,
|
|
983
|
-
receiver: {
|
|
984
|
-
importModule: opts.importModule,
|
|
985
|
-
importNames: [...opts.importNames]
|
|
986
|
-
}
|
|
987
|
-
},
|
|
988
|
-
requiresImport: [opts.importModule]
|
|
989
|
-
}
|
|
990
|
-
];
|
|
845
|
+
return [];
|
|
991
846
|
}
|
|
992
|
-
function
|
|
993
|
-
return
|
|
994
|
-
(importName) => opts.wraps.map((wraps) => ({
|
|
995
|
-
kind: opts.kind ?? "middleware",
|
|
996
|
-
match: {
|
|
997
|
-
type: "registrationCall",
|
|
998
|
-
importModule: opts.importModule,
|
|
999
|
-
importName,
|
|
1000
|
-
registrationChain: []
|
|
1001
|
-
},
|
|
1002
|
-
wraps: { ...wraps },
|
|
1003
|
-
requiresImport: [opts.importModule]
|
|
1004
|
-
}))
|
|
1005
|
-
);
|
|
847
|
+
function stepOpaque(_stmt, path4, _ctx) {
|
|
848
|
+
return [path4];
|
|
1006
849
|
}
|
|
1007
|
-
var
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
850
|
+
var stepHandlers = {
|
|
851
|
+
if: stepIf,
|
|
852
|
+
switch: stepSwitch,
|
|
853
|
+
loop: stepLoop,
|
|
854
|
+
try: stepTry,
|
|
855
|
+
exit: stepExit,
|
|
856
|
+
opaque: stepOpaque
|
|
857
|
+
};
|
|
858
|
+
function stepCallback(ctx, body, path4) {
|
|
859
|
+
const exits = [];
|
|
860
|
+
ctx.state.callbackExits.push(exits);
|
|
861
|
+
let fellThrough;
|
|
862
|
+
try {
|
|
863
|
+
fellThrough = enumerate(ctx, body, path4);
|
|
864
|
+
} finally {
|
|
865
|
+
ctx.state.callbackExits.pop();
|
|
866
|
+
}
|
|
867
|
+
const out = [...fellThrough, ...exits];
|
|
868
|
+
return out.length === 0 ? [path4] : out;
|
|
1023
869
|
}
|
|
1024
|
-
function
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
870
|
+
function stepStatement(ctx, stmt, path4) {
|
|
871
|
+
let paths = [path4];
|
|
872
|
+
for (const body of stmt.callbacks ?? []) {
|
|
873
|
+
paths = paths.flatMap((each) => stepCallback(ctx, body, each));
|
|
874
|
+
}
|
|
875
|
+
const ownTerminals = ctx.terminalsByStmt.get(stmt) ?? [];
|
|
876
|
+
for (const each of withRejoined(paths)) {
|
|
877
|
+
for (const terminal of ownTerminals) {
|
|
878
|
+
recordTerminal(ctx, terminal, stmt, each);
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
const handler = stepHandlers[stmt.kind];
|
|
882
|
+
return paths.flatMap(
|
|
883
|
+
(each) => handler(
|
|
884
|
+
stmt,
|
|
885
|
+
each,
|
|
886
|
+
ctx
|
|
1028
887
|
)
|
|
1029
888
|
);
|
|
1030
|
-
return {
|
|
1031
|
-
find: { by: "subject" },
|
|
1032
|
-
declare: (helpers) => ({
|
|
1033
|
-
discovery: registrationHelperDiscovery(
|
|
1034
|
-
helpers.flatMap((helper) => routesRegisteredBy(helper, methods, opts)),
|
|
1035
|
-
opts.kind ?? "handler"
|
|
1036
|
-
)
|
|
1037
|
-
})
|
|
1038
|
-
};
|
|
1039
889
|
}
|
|
1040
|
-
function
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
890
|
+
function soleDisagreement(left, right) {
|
|
891
|
+
if (left.length !== right.length) {
|
|
892
|
+
return null;
|
|
893
|
+
}
|
|
894
|
+
let found = null;
|
|
895
|
+
for (let at = 0; at < left.length; at++) {
|
|
896
|
+
const one = left[at];
|
|
897
|
+
const other = right[at];
|
|
898
|
+
if (one === other) {
|
|
1046
899
|
continue;
|
|
1047
900
|
}
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
subjectArgument = sink.receiver.position;
|
|
901
|
+
if (found !== null) {
|
|
902
|
+
return null;
|
|
1051
903
|
}
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
return [];
|
|
1055
|
-
}
|
|
1056
|
-
return [
|
|
1057
|
-
{
|
|
1058
|
-
helperName: helper.name,
|
|
1059
|
-
importModule: helper.file,
|
|
1060
|
-
subject: {
|
|
1061
|
-
argument: subjectArgument,
|
|
1062
|
-
importModule: opts.importModule,
|
|
1063
|
-
importNames: [...opts.importNames]
|
|
1064
|
-
},
|
|
1065
|
-
registrations
|
|
904
|
+
if (one === void 0 || other === void 0 || one.branchStmt === null || one.branchStmt !== other.branchStmt || one.info.polarity === other.info.polarity) {
|
|
905
|
+
return null;
|
|
1066
906
|
}
|
|
1067
|
-
|
|
907
|
+
found = at;
|
|
908
|
+
}
|
|
909
|
+
return found;
|
|
1068
910
|
}
|
|
1069
|
-
function
|
|
1070
|
-
|
|
1071
|
-
|
|
911
|
+
function mergeRejoined(paths) {
|
|
912
|
+
let current = paths;
|
|
913
|
+
for (let round = 0; round < current.length; round++) {
|
|
914
|
+
const out = [];
|
|
915
|
+
const taken = /* @__PURE__ */ new Set();
|
|
916
|
+
let mergedAny = false;
|
|
917
|
+
for (let i = 0; i < current.length; i++) {
|
|
918
|
+
if (taken.has(i)) {
|
|
919
|
+
continue;
|
|
920
|
+
}
|
|
921
|
+
let combined = current[i];
|
|
922
|
+
for (let j = i + 1; j < current.length; j++) {
|
|
923
|
+
if (taken.has(j)) {
|
|
924
|
+
continue;
|
|
925
|
+
}
|
|
926
|
+
const at = soleDisagreement(combined, current[j]);
|
|
927
|
+
if (at === null) {
|
|
928
|
+
continue;
|
|
929
|
+
}
|
|
930
|
+
combined = [...combined.slice(0, at), ...combined.slice(at + 1)];
|
|
931
|
+
taken.add(j);
|
|
932
|
+
mergedAny = true;
|
|
933
|
+
break;
|
|
934
|
+
}
|
|
935
|
+
out.push(combined);
|
|
936
|
+
}
|
|
937
|
+
current = out;
|
|
938
|
+
if (!mergedAny) {
|
|
939
|
+
break;
|
|
940
|
+
}
|
|
1072
941
|
}
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
942
|
+
return current;
|
|
943
|
+
}
|
|
944
|
+
function withRejoined(paths) {
|
|
945
|
+
const merged = mergeRejoined(paths);
|
|
946
|
+
return merged.length === paths.length ? paths : [...merged, ...paths];
|
|
947
|
+
}
|
|
948
|
+
function enumerate(ctx, stmts, prefix) {
|
|
949
|
+
let frontiers = [[...prefix]];
|
|
950
|
+
for (const stmt of stmts) {
|
|
951
|
+
const nextFrontiers = [];
|
|
952
|
+
for (const path4 of mergeRejoined(frontiers)) {
|
|
953
|
+
nextFrontiers.push(...stepStatement(ctx, stmt, path4));
|
|
954
|
+
}
|
|
955
|
+
frontiers = nextFrontiers;
|
|
956
|
+
if (frontiers.length > MAX_PATHS) {
|
|
957
|
+
throw new PathBudgetExceeded(
|
|
958
|
+
`path budget exceeded, more than ${MAX_PATHS} paths`
|
|
959
|
+
);
|
|
960
|
+
}
|
|
961
|
+
if (frontiers.length === 0) {
|
|
962
|
+
break;
|
|
963
|
+
}
|
|
1076
964
|
}
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
965
|
+
return frontiers;
|
|
966
|
+
}
|
|
967
|
+
function buildParentMap(statements) {
|
|
968
|
+
const parentOf = /* @__PURE__ */ new Map();
|
|
969
|
+
const visit = (stmt, parent) => {
|
|
970
|
+
parentOf.set(stmt, parent);
|
|
971
|
+
for (const child of childrenOf(stmt)) {
|
|
972
|
+
visit(child, stmt);
|
|
973
|
+
}
|
|
974
|
+
};
|
|
975
|
+
for (const stmt of statements) {
|
|
976
|
+
visit(stmt, null);
|
|
1081
977
|
}
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
978
|
+
return parentOf;
|
|
979
|
+
}
|
|
980
|
+
function enumerateStructuredPaths(input) {
|
|
981
|
+
const parentOf = buildParentMap(input.statements);
|
|
982
|
+
const isAncestorOrSelf = (a, b) => {
|
|
983
|
+
let current = b;
|
|
984
|
+
while (current !== null) {
|
|
985
|
+
if (current === a) {
|
|
986
|
+
return true;
|
|
987
|
+
}
|
|
988
|
+
current = parentOf.get(current) ?? null;
|
|
989
|
+
}
|
|
990
|
+
return false;
|
|
1089
991
|
};
|
|
992
|
+
const state = {
|
|
993
|
+
byTerminal: /* @__PURE__ */ new Map(),
|
|
994
|
+
fallthrough: [],
|
|
995
|
+
pathCount: 0,
|
|
996
|
+
callbackExits: []
|
|
997
|
+
};
|
|
998
|
+
const ctx = {
|
|
999
|
+
terminalsByStmt: input.terminalsByStmt,
|
|
1000
|
+
state,
|
|
1001
|
+
isAncestorOrSelf
|
|
1002
|
+
};
|
|
1003
|
+
const continuations = withRejoined(enumerate(ctx, input.statements, []));
|
|
1004
|
+
for (const path4 of continuations) {
|
|
1005
|
+
chargeBudget(state);
|
|
1006
|
+
state.fallthrough.push(classify(path4, null, isAncestorOrSelf));
|
|
1007
|
+
}
|
|
1008
|
+
return { byTerminal: state.byTerminal, fallthrough: state.fallthrough };
|
|
1090
1009
|
}
|
|
1091
|
-
function
|
|
1092
|
-
|
|
1093
|
-
return null;
|
|
1010
|
+
function enumerateOrDegrade(input, terminals) {
|
|
1011
|
+
try {
|
|
1012
|
+
return { ...enumerateStructuredPaths(input), degraded: null };
|
|
1013
|
+
} catch (error) {
|
|
1014
|
+
const reason = reasonToDegrade(error);
|
|
1015
|
+
if (reason === null) {
|
|
1016
|
+
throw error;
|
|
1017
|
+
}
|
|
1018
|
+
const marker = {
|
|
1019
|
+
sourceText: `unmodeled control flow (${reason})`,
|
|
1020
|
+
polarity: "positive",
|
|
1021
|
+
source: "explicit",
|
|
1022
|
+
expression: null
|
|
1023
|
+
};
|
|
1024
|
+
const byTerminal = /* @__PURE__ */ new Map();
|
|
1025
|
+
for (const terminal of terminals) {
|
|
1026
|
+
byTerminal.set(terminal, [[marker]]);
|
|
1027
|
+
}
|
|
1028
|
+
return { byTerminal, fallthrough: [[marker]], degraded: reason };
|
|
1094
1029
|
}
|
|
1095
|
-
return value.property === void 0 ? `{${value.position}}` : `{${value.position}}.${value.property}`;
|
|
1096
1030
|
}
|
|
1097
|
-
function
|
|
1098
|
-
if (
|
|
1099
|
-
return
|
|
1031
|
+
function reasonToDegrade(error) {
|
|
1032
|
+
if (error instanceof PathBudgetExceeded) {
|
|
1033
|
+
return error.message === "" ? "path budget exceeded" : error.message;
|
|
1100
1034
|
}
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
return body;
|
|
1035
|
+
if (error instanceof UnmodeledFlow) {
|
|
1036
|
+
return error.message;
|
|
1104
1037
|
}
|
|
1105
|
-
|
|
1106
|
-
return inner ?? body;
|
|
1038
|
+
return null;
|
|
1107
1039
|
}
|
|
1108
1040
|
|
|
1109
|
-
// src/packOptions.ts
|
|
1110
|
-
var import_zod = require("zod");
|
|
1111
|
-
var storageSystemOption = import_zod.z.enum([
|
|
1112
|
-
"postgresql",
|
|
1113
|
-
"mysql",
|
|
1114
|
-
"sqlite"
|
|
1115
|
-
]);
|
|
1116
|
-
var scopeOption = import_zod.z.string();
|
|
1117
|
-
var configuredCallOption = import_zod.z.object({
|
|
1118
|
-
/** Module that declares the receiver's type. */
|
|
1119
|
-
module: import_zod.z.string(),
|
|
1120
|
-
/** Type name of the receiver, as exported from that module. */
|
|
1121
|
-
receiver: import_zod.z.string(),
|
|
1122
|
-
/** Method that performs the send. */
|
|
1123
|
-
method: import_zod.z.string(),
|
|
1124
|
-
/** Argument index carrying the subject. */
|
|
1125
|
-
subjectArg: import_zod.z.number(),
|
|
1126
|
-
/**
|
|
1127
|
-
* Which argument the message body is. Left out when the method has no
|
|
1128
|
-
* single body argument, as a batch method taking a list of entries
|
|
1129
|
-
* does, and then no body is reported.
|
|
1130
|
-
*/
|
|
1131
|
-
bodyArg: import_zod.z.number().optional()
|
|
1132
|
-
}).strict();
|
|
1133
|
-
|
|
1134
1041
|
// src/paths/gatingConditions.ts
|
|
1135
1042
|
var keyOf2 = (condition) => `${condition.polarity}:${condition.sourceText}`;
|
|
1136
1043
|
function sharedGatingConditions(paths, readPredicate) {
|
|
@@ -2303,6 +2210,9 @@ function buildGraphqlMetadataValue(raw) {
|
|
|
2303
2210
|
if (raw.graphqlUnresolvedFragments !== void 0) {
|
|
2304
2211
|
graphql.unresolvedFragments = raw.graphqlUnresolvedFragments;
|
|
2305
2212
|
}
|
|
2213
|
+
if (raw.graphqlAmbiguousFragments !== void 0) {
|
|
2214
|
+
graphql.ambiguousFragments = raw.graphqlAmbiguousFragments;
|
|
2215
|
+
}
|
|
2306
2216
|
if (raw.graphqlUnresolvedDocument !== void 0) {
|
|
2307
2217
|
graphql.unresolvedDocument = raw.graphqlUnresolvedDocument;
|
|
2308
2218
|
}
|