@suss/extractor 0.34.0 → 0.35.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 +1101 -207
- package/dist/index.d.cts +323 -23
- package/dist/index.d.ts +323 -23
- package/dist/index.js +1085 -201
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -30,11 +30,13 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
|
+
CACHE_DIR_ENV: () => CACHE_DIR_ENV,
|
|
33
34
|
EnclosingNodes: () => EnclosingNodes,
|
|
34
35
|
IdMap: () => IdMap,
|
|
35
36
|
IdSet: () => IdSet,
|
|
36
37
|
KeptParses: () => KeptParses,
|
|
37
38
|
MAX_ENTRIES: () => MAX_ENTRIES,
|
|
39
|
+
MAX_HELPER_PATHS: () => MAX_HELPER_PATHS,
|
|
38
40
|
MAX_PATHS: () => MAX_PATHS,
|
|
39
41
|
MODULE_SURFACE_RECOGNITION: () => MODULE_SURFACE_RECOGNITION,
|
|
40
42
|
PathBudgetExceeded: () => PathBudgetExceeded,
|
|
@@ -46,6 +48,7 @@ __export(index_exports, {
|
|
|
46
48
|
assembleSummary: () => assembleSummary,
|
|
47
49
|
assessConfidence: () => assessConfidence,
|
|
48
50
|
buildUngatedExtractionReport: () => buildUngatedExtractionReport,
|
|
51
|
+
chosenCacheRoot: () => chosenCacheRoot,
|
|
49
52
|
commonDirectoryOf: () => commonDirectoryOf,
|
|
50
53
|
composeWrappers: () => composeWrappers,
|
|
51
54
|
computeContentHash: () => computeContentHash,
|
|
@@ -53,6 +56,7 @@ __export(index_exports, {
|
|
|
53
56
|
configuredCallOption: () => configuredCallOption,
|
|
54
57
|
createAdapterStamp: () => createAdapterStamp,
|
|
55
58
|
createCacheLayer: () => createCacheLayer,
|
|
59
|
+
createCodeHasher: () => createCodeHasher,
|
|
56
60
|
createPackTallies: () => createPackTallies,
|
|
57
61
|
createTimer: () => createTimer,
|
|
58
62
|
detectGaps: () => detectGaps,
|
|
@@ -61,24 +65,33 @@ __export(index_exports, {
|
|
|
61
65
|
enumerateOrDegrade: () => enumerateOrDegrade,
|
|
62
66
|
enumerateStructuredPaths: () => enumerateStructuredPaths,
|
|
63
67
|
evaluatePackHealth: () => evaluatePackHealth,
|
|
68
|
+
extractionCacheDirFor: () => extractionCacheDirFor,
|
|
64
69
|
extractionConfigStamp: () => extractionConfigStamp,
|
|
65
70
|
firstWrittenReading: () => firstWrittenReading,
|
|
66
71
|
formatPackHealth: () => formatPackHealth,
|
|
67
72
|
guardsHoldOn: () => guardsHoldOn,
|
|
73
|
+
helperPathsOnVariables: () => helperPathsOnVariables,
|
|
68
74
|
httpRouteDiscovery: () => httpRouteDiscovery,
|
|
69
75
|
isListedTestFile: () => isListedTestFile,
|
|
76
|
+
liveRecordFor: () => liveRecordFor,
|
|
77
|
+
makeIgnoredDirectory: () => makeIgnoredDirectory,
|
|
70
78
|
makeTransitionId: () => makeTransitionId,
|
|
71
79
|
mapReading: () => mapReading,
|
|
72
80
|
markReturnsAsExitCode: () => markReturnsAsExitCode,
|
|
73
81
|
matchesTestFileName: () => matchesTestFileName,
|
|
82
|
+
mergeReadShapes: () => mergeReadShapes,
|
|
74
83
|
moduleInitStructure: () => moduleInitStructure,
|
|
75
84
|
moduleOfFile: () => moduleOfFile,
|
|
76
85
|
noopTimer: () => noopTimer,
|
|
86
|
+
ownersWhereWritten: () => ownersWhereWritten,
|
|
87
|
+
packConfigCheck: () => packConfigCheck,
|
|
77
88
|
packGradients: () => packGradients,
|
|
78
89
|
paramToInput: () => paramToInput,
|
|
90
|
+
processCodeHasher: () => processCodeHasher,
|
|
79
91
|
projectFileStamp: () => projectFileStamp,
|
|
80
92
|
rawConditionToPredicate: () => rawConditionToPredicate,
|
|
81
93
|
recordPackFailure: () => recordPackFailure,
|
|
94
|
+
redirectDeliveryWhenSet: () => redirectDeliveryWhenSet,
|
|
82
95
|
registrationHelperDiscovery: () => registrationHelperDiscovery,
|
|
83
96
|
routeHelperIndex: () => routeHelperIndex,
|
|
84
97
|
runDigest: () => runDigest,
|
|
@@ -87,6 +100,7 @@ __export(index_exports, {
|
|
|
87
100
|
settleModules: () => settleModules,
|
|
88
101
|
sharedGatingConditions: () => sharedGatingConditions,
|
|
89
102
|
sourceRefsOf: () => sourceRefsOf,
|
|
103
|
+
splitAtHandOffs: () => splitAtHandOffs,
|
|
90
104
|
stampMayMissAWrite: () => stampMayMissAWrite,
|
|
91
105
|
stampModuleImports: () => stampModuleImports,
|
|
92
106
|
stampModules: () => stampModules,
|
|
@@ -94,6 +108,7 @@ __export(index_exports, {
|
|
|
94
108
|
summaryCountsByPack: () => summaryCountsByPack,
|
|
95
109
|
tallyUnit: () => tallyUnit,
|
|
96
110
|
terminalToOutput: () => terminalToOutput,
|
|
111
|
+
throughHelper: () => throughHelper,
|
|
97
112
|
unreadableReading: () => unreadableReading,
|
|
98
113
|
unwrapJsonStringify: () => unwrapJsonStringify,
|
|
99
114
|
valueToReadFurtherFrom: () => valueToReadFurtherFrom,
|
|
@@ -102,8 +117,8 @@ __export(index_exports, {
|
|
|
102
117
|
writtenReading: () => writtenReading
|
|
103
118
|
});
|
|
104
119
|
module.exports = __toCommonJS(index_exports);
|
|
105
|
-
var
|
|
106
|
-
var
|
|
120
|
+
var import_node_crypto7 = require("crypto");
|
|
121
|
+
var import_behavioral_ir8 = require("@suss/behavioral-ir");
|
|
107
122
|
|
|
108
123
|
// src/contractStatusGaps.ts
|
|
109
124
|
var import_behavioral_ir = require("@suss/behavioral-ir");
|
|
@@ -282,29 +297,82 @@ function composeOne(summary, chain, keepGaps) {
|
|
|
282
297
|
if (wrappers.length === 0) {
|
|
283
298
|
return narrowed;
|
|
284
299
|
}
|
|
285
|
-
const responses = respondedInstead(wrappers);
|
|
286
|
-
const
|
|
287
|
-
const
|
|
300
|
+
const responses = settledUncaught(respondedInstead(wrappers), wrappers);
|
|
301
|
+
const unitOwn = settledUncaught(summary.transitions, wrappers);
|
|
302
|
+
const own = [...responses, ...unitOwn];
|
|
303
|
+
const handled = handledThrows(wrappers, thrownBy(own));
|
|
304
|
+
const transitions = beside(summary, unitOwn, responses, handled);
|
|
288
305
|
if (!keepGaps) {
|
|
289
306
|
return transitions === summary.transitions ? narrowed : { ...narrowed, transitions };
|
|
290
307
|
}
|
|
291
308
|
const gaps = withContractStatusGaps(
|
|
292
309
|
summary,
|
|
293
|
-
|
|
294
|
-
|
|
310
|
+
own,
|
|
311
|
+
everyHandlerOutcome(wrappers)
|
|
295
312
|
);
|
|
296
313
|
if (transitions === summary.transitions && gaps === summary.gaps) {
|
|
297
314
|
return narrowed;
|
|
298
315
|
}
|
|
299
316
|
return { ...narrowed, transitions, gaps };
|
|
300
317
|
}
|
|
301
|
-
function beside(summary, responses, handled) {
|
|
302
|
-
|
|
303
|
-
const onThrow = throws ? handled : [];
|
|
304
|
-
if (responses.length === 0 && onThrow.length === 0) {
|
|
318
|
+
function beside(summary, unitOwn, responses, handled) {
|
|
319
|
+
if (responses.length === 0 && handled.length === 0 && unitOwn === summary.transitions) {
|
|
305
320
|
return summary.transitions;
|
|
306
321
|
}
|
|
307
|
-
return withDistinctIds([...responses, ...
|
|
322
|
+
return withDistinctIds([...responses, ...unitOwn, ...handled]);
|
|
323
|
+
}
|
|
324
|
+
function settledUncaught(transitions, wrappers) {
|
|
325
|
+
const handlers = wrappers.filter(
|
|
326
|
+
(wrapper) => wrapper.reference.onThrow === true
|
|
327
|
+
);
|
|
328
|
+
let changed = false;
|
|
329
|
+
const settled = transitions.flatMap((transition) => {
|
|
330
|
+
const { output } = transition;
|
|
331
|
+
if (output.type !== "throw") {
|
|
332
|
+
return [transition];
|
|
333
|
+
}
|
|
334
|
+
const caught = caughtOnRoute(handlers, output);
|
|
335
|
+
if (caught === "sure") {
|
|
336
|
+
changed = true;
|
|
337
|
+
return [markedCaught(transition)];
|
|
338
|
+
}
|
|
339
|
+
if (output.statusWhenUncaught === void 0) {
|
|
340
|
+
return [transition];
|
|
341
|
+
}
|
|
342
|
+
changed = true;
|
|
343
|
+
const response = {
|
|
344
|
+
...transition,
|
|
345
|
+
output: {
|
|
346
|
+
type: "response",
|
|
347
|
+
statusCode: { type: "literal", value: output.statusWhenUncaught },
|
|
348
|
+
body: null,
|
|
349
|
+
headers: {}
|
|
350
|
+
}
|
|
351
|
+
};
|
|
352
|
+
return caught === "uncertain" ? [transition, response] : [response];
|
|
353
|
+
});
|
|
354
|
+
return changed ? settled : transitions;
|
|
355
|
+
}
|
|
356
|
+
function markedCaught(transition) {
|
|
357
|
+
return {
|
|
358
|
+
...transition,
|
|
359
|
+
metadata: (0, import_behavioral_ir2.withWrapperMetadata)(transition.metadata, {
|
|
360
|
+
...(0, import_behavioral_ir2.readWrapperMetadata)(transition),
|
|
361
|
+
caught: true
|
|
362
|
+
})
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
function caughtOnRoute(handlers, thrown) {
|
|
366
|
+
if (handlers.some((handler) => handler.reference.catches === void 0)) {
|
|
367
|
+
return "sure";
|
|
368
|
+
}
|
|
369
|
+
const matches = handlers.map(
|
|
370
|
+
(handler) => catchMatch(handler.reference, thrown)
|
|
371
|
+
);
|
|
372
|
+
if (matches.includes("yes")) {
|
|
373
|
+
return "sure";
|
|
374
|
+
}
|
|
375
|
+
return matches.includes("maybe") ? "uncertain" : "no";
|
|
308
376
|
}
|
|
309
377
|
function respondedInstead(wrappers) {
|
|
310
378
|
return wrappers.flatMap(
|
|
@@ -316,11 +384,91 @@ function respondedInstead(wrappers) {
|
|
|
316
384
|
)
|
|
317
385
|
);
|
|
318
386
|
}
|
|
319
|
-
function
|
|
387
|
+
function thrownBy(transitions) {
|
|
388
|
+
return transitions.flatMap(
|
|
389
|
+
(t) => t.output.type === "throw" ? [t.output] : []
|
|
390
|
+
);
|
|
391
|
+
}
|
|
392
|
+
function everyHandlerOutcome(wrappers) {
|
|
320
393
|
return wrappers.flatMap(
|
|
321
394
|
(wrapper) => wrapper.reference.onThrow === true ? attribute(wrapper.summary.transitions, wrapper.reference) : []
|
|
322
395
|
);
|
|
323
396
|
}
|
|
397
|
+
function handledThrows(wrappers, thrown) {
|
|
398
|
+
const caught = catchesAny(wrappers, thrown);
|
|
399
|
+
return [...oncePerHandler(wrappers, caught)].flatMap(
|
|
400
|
+
([wrapper, how]) => attribute(
|
|
401
|
+
wrapper.summary.transitions,
|
|
402
|
+
wrapper.reference,
|
|
403
|
+
how === "uncertain"
|
|
404
|
+
)
|
|
405
|
+
);
|
|
406
|
+
}
|
|
407
|
+
function oncePerHandler(wrappers, caught) {
|
|
408
|
+
const byHandler = /* @__PURE__ */ new Map();
|
|
409
|
+
for (const wrapper of wrappers) {
|
|
410
|
+
const how = caught.get(wrapper);
|
|
411
|
+
if (how === void 0) {
|
|
412
|
+
continue;
|
|
413
|
+
}
|
|
414
|
+
const earlier = byHandler.get(wrapper.summary);
|
|
415
|
+
if (earlier === void 0 || earlier[1] === "uncertain" && how === "sure") {
|
|
416
|
+
byHandler.set(wrapper.summary, [wrapper, how]);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
return new Map(byHandler.values());
|
|
420
|
+
}
|
|
421
|
+
function catchesAny(wrappers, thrown) {
|
|
422
|
+
const caught = /* @__PURE__ */ new Map();
|
|
423
|
+
if (thrown.length === 0) {
|
|
424
|
+
return caught;
|
|
425
|
+
}
|
|
426
|
+
const handlers = wrappers.filter(
|
|
427
|
+
(wrapper) => wrapper.reference.onThrow === true
|
|
428
|
+
);
|
|
429
|
+
for (const handler of handlers) {
|
|
430
|
+
if (handler.reference.catches === void 0) {
|
|
431
|
+
caught.set(handler, "sure");
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
const listing = handlers.filter(
|
|
435
|
+
(handler) => handler.reference.catches !== void 0
|
|
436
|
+
);
|
|
437
|
+
for (const one of thrown) {
|
|
438
|
+
for (const [handler, how] of catchersOf(listing, one)) {
|
|
439
|
+
if (caught.get(handler) !== "sure") {
|
|
440
|
+
caught.set(handler, how);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
return caught;
|
|
445
|
+
}
|
|
446
|
+
function catchersOf(handlers, thrown) {
|
|
447
|
+
const found = [];
|
|
448
|
+
for (const handler of handlers) {
|
|
449
|
+
const match = catchMatch(handler.reference, thrown);
|
|
450
|
+
if (match === "yes") {
|
|
451
|
+
found.push([handler, found.length === 0 ? "sure" : "uncertain"]);
|
|
452
|
+
return found;
|
|
453
|
+
}
|
|
454
|
+
if (match === "maybe") {
|
|
455
|
+
found.push([handler, "uncertain"]);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
return found;
|
|
459
|
+
}
|
|
460
|
+
function catchMatch(reference, thrown) {
|
|
461
|
+
const ancestors = thrown.exceptionAncestors;
|
|
462
|
+
if (thrown.exceptionType === null || ancestors === void 0) {
|
|
463
|
+
return "maybe";
|
|
464
|
+
}
|
|
465
|
+
const classes = /* @__PURE__ */ new Set([thrown.exceptionType, ...ancestors]);
|
|
466
|
+
if ((reference.catches ?? []).some((name) => classes.has(name))) {
|
|
467
|
+
return "yes";
|
|
468
|
+
}
|
|
469
|
+
const unread = thrown.ancestryIncomplete === true && reference.mayCatchUnreadClasses === true;
|
|
470
|
+
return unread || reference.mayCatchAny === true ? "maybe" : "no";
|
|
471
|
+
}
|
|
324
472
|
function withContractStatusGaps(summary, composed, handled) {
|
|
325
473
|
const contract = (0, import_behavioral_ir2.readHttpMetadata)(summary)?.declaredContract;
|
|
326
474
|
const binding = summary.identity.boundaryBinding;
|
|
@@ -351,10 +499,13 @@ function coversUnit(reference, summary) {
|
|
|
351
499
|
const binding = summary.identity.boundaryBinding;
|
|
352
500
|
return binding !== null && (0, import_behavioral_ir2.withinScope)(binding, reference.scope);
|
|
353
501
|
}
|
|
354
|
-
function attribute(transitions, reference) {
|
|
502
|
+
function attribute(transitions, reference, catchUncertain = false) {
|
|
355
503
|
return transitions.map((transition) => ({
|
|
356
504
|
...transition,
|
|
357
|
-
metadata: (0, import_behavioral_ir2.withWrapperMetadata)(transition.metadata, {
|
|
505
|
+
metadata: (0, import_behavioral_ir2.withWrapperMetadata)(transition.metadata, {
|
|
506
|
+
from: reference,
|
|
507
|
+
...catchUncertain ? { catchUncertain } : {}
|
|
508
|
+
})
|
|
358
509
|
}));
|
|
359
510
|
}
|
|
360
511
|
function withDistinctIds(transitions) {
|
|
@@ -467,13 +618,111 @@ function markExitCodeFrom(summary, marked) {
|
|
|
467
618
|
summary.metadata = left;
|
|
468
619
|
}
|
|
469
620
|
|
|
621
|
+
// src/helperHandOff.ts
|
|
622
|
+
var import_behavioral_ir4 = require("@suss/behavioral-ir");
|
|
623
|
+
var MAX_HELPER_PATHS = 16;
|
|
624
|
+
function throughHelper(branch, at, helperBranches) {
|
|
625
|
+
return helperBranches.map((helper) => {
|
|
626
|
+
const conditions = [...branch.conditions, ...helper.conditions];
|
|
627
|
+
const expectedInput = mergeReadShapes(
|
|
628
|
+
branch.expectedInput ?? null,
|
|
629
|
+
helper.expectedInput ?? null
|
|
630
|
+
);
|
|
631
|
+
const reads = expectedInput === null ? {} : { expectedInput };
|
|
632
|
+
if (helper.terminal.kind !== "throw" && helper.terminal.kind !== "exit") {
|
|
633
|
+
return {
|
|
634
|
+
...branch,
|
|
635
|
+
...reads,
|
|
636
|
+
conditions,
|
|
637
|
+
isDefault: branch.isDefault && helper.isDefault
|
|
638
|
+
};
|
|
639
|
+
}
|
|
640
|
+
return {
|
|
641
|
+
...branch,
|
|
642
|
+
...reads,
|
|
643
|
+
conditions,
|
|
644
|
+
terminal: { ...helper.terminal, location: at },
|
|
645
|
+
location: at,
|
|
646
|
+
isDefault: false
|
|
647
|
+
};
|
|
648
|
+
});
|
|
649
|
+
}
|
|
650
|
+
function mergeReadShapes(a, b) {
|
|
651
|
+
if (a === null || b === null) {
|
|
652
|
+
return a ?? b;
|
|
653
|
+
}
|
|
654
|
+
if (a.type !== "record" || b.type !== "record") {
|
|
655
|
+
return a.type === "record" ? a : b;
|
|
656
|
+
}
|
|
657
|
+
const properties = { ...a.properties };
|
|
658
|
+
for (const [name, shape] of Object.entries(b.properties)) {
|
|
659
|
+
const known = properties[name];
|
|
660
|
+
properties[name] = known === void 0 ? shape : mergeReadShapes(known, shape) ?? shape;
|
|
661
|
+
}
|
|
662
|
+
return { ...a, properties };
|
|
663
|
+
}
|
|
664
|
+
function splitAtHandOffs(branch, sites, from = 0) {
|
|
665
|
+
for (let index = from; index < sites.length; index++) {
|
|
666
|
+
const site = sites[index];
|
|
667
|
+
const reached = site.alwaysRuns === true || runsBefore(site.line, branch.terminal.location.end);
|
|
668
|
+
if (!reached || !guardsHoldOn(site.preconditions, branch.conditions)) {
|
|
669
|
+
continue;
|
|
670
|
+
}
|
|
671
|
+
return throughHelper(branch, site.at, site.helper).flatMap(
|
|
672
|
+
(path10) => path10.terminal === branch.terminal ? splitAtHandOffs(path10, sites, index + 1) : [path10]
|
|
673
|
+
);
|
|
674
|
+
}
|
|
675
|
+
return [branch];
|
|
676
|
+
}
|
|
677
|
+
function helperPathsOnVariables(helperBranches, passed) {
|
|
678
|
+
const renamed = helperBranches.map((branch) => ({
|
|
679
|
+
...branch,
|
|
680
|
+
conditions: branch.conditions.map((condition) => ({
|
|
681
|
+
...condition,
|
|
682
|
+
structured: condition.structured === null ? null : onCallerVariables(condition.structured, passed)
|
|
683
|
+
}))
|
|
684
|
+
}));
|
|
685
|
+
const variables = new Set(passed.values());
|
|
686
|
+
const testsWhatItGot = renamed.some(
|
|
687
|
+
(branch) => branch.conditions.some(
|
|
688
|
+
(condition) => condition.structured !== null && (0, import_behavioral_ir4.predicateRefs)(condition.structured).some(
|
|
689
|
+
(ref) => variables.has(rootName(ref) ?? "")
|
|
690
|
+
)
|
|
691
|
+
)
|
|
692
|
+
);
|
|
693
|
+
return testsWhatItGot && renamed.length <= MAX_HELPER_PATHS ? renamed : null;
|
|
694
|
+
}
|
|
695
|
+
function onCallerVariables(predicate, passed) {
|
|
696
|
+
const rename = (ref) => {
|
|
697
|
+
if (ref.type === "derived") {
|
|
698
|
+
return { ...ref, from: rename(ref.from) };
|
|
699
|
+
}
|
|
700
|
+
if (ref.type === "input") {
|
|
701
|
+
const name = passed.get(ref.inputRef);
|
|
702
|
+
return name === void 0 ? ref : { type: "dependency", name, accessChain: ref.path };
|
|
703
|
+
}
|
|
704
|
+
if (ref.type === "dependency") {
|
|
705
|
+
const name = passed.get(ref.name);
|
|
706
|
+
return name === void 0 ? ref : { ...ref, name };
|
|
707
|
+
}
|
|
708
|
+
return ref;
|
|
709
|
+
};
|
|
710
|
+
return (0, import_behavioral_ir4.replacePredicateRefs)(predicate, rename);
|
|
711
|
+
}
|
|
712
|
+
function rootName(ref) {
|
|
713
|
+
if (ref.type === "derived") {
|
|
714
|
+
return rootName(ref.from);
|
|
715
|
+
}
|
|
716
|
+
return ref.type === "dependency" ? ref.name : null;
|
|
717
|
+
}
|
|
718
|
+
|
|
470
719
|
// src/moduleImports.ts
|
|
471
|
-
function stampModuleImports(summaries,
|
|
720
|
+
function stampModuleImports(summaries, importsOf2) {
|
|
472
721
|
const byFile = /* @__PURE__ */ new Map();
|
|
473
722
|
for (const summary of summaries) {
|
|
474
723
|
const file = summary.location.file;
|
|
475
724
|
if (!byFile.has(file)) {
|
|
476
|
-
const found =
|
|
725
|
+
const found = importsOf2(file);
|
|
477
726
|
byFile.set(
|
|
478
727
|
file,
|
|
479
728
|
found === void 0 ? void 0 : [...new Set(found)].sort()
|
|
@@ -720,7 +969,7 @@ var configuredCallOption = import_zod.z.object({
|
|
|
720
969
|
}).strict();
|
|
721
970
|
|
|
722
971
|
// src/paths/enumeratePaths.ts
|
|
723
|
-
var
|
|
972
|
+
var import_behavioral_ir5 = require("@suss/behavioral-ir");
|
|
724
973
|
var MAX_PATHS = 256;
|
|
725
974
|
var UnmodeledFlow = class extends Error {
|
|
726
975
|
};
|
|
@@ -764,12 +1013,12 @@ var loopCompletedCond = (headerText, exit) => fixedCond(
|
|
|
764
1013
|
exit === "throw" ? "earlyThrow" : "earlyReturn"
|
|
765
1014
|
);
|
|
766
1015
|
var catchEntryCond = () => fixedCond(
|
|
767
|
-
{ sourceText:
|
|
1016
|
+
{ sourceText: import_behavioral_ir5.CATCH_ENTRY_TEXT, expression: null },
|
|
768
1017
|
"positive",
|
|
769
1018
|
"catchBlock"
|
|
770
1019
|
);
|
|
771
|
-
function classify(
|
|
772
|
-
return
|
|
1020
|
+
function classify(path10, home, isAncestorOrSelf) {
|
|
1021
|
+
return path10.map((cond) => {
|
|
773
1022
|
if (cond.branchStmt === null) {
|
|
774
1023
|
return cond.info;
|
|
775
1024
|
}
|
|
@@ -834,9 +1083,16 @@ function chargeBudget(state) {
|
|
|
834
1083
|
);
|
|
835
1084
|
}
|
|
836
1085
|
}
|
|
837
|
-
function
|
|
1086
|
+
function limitOpenPaths(paths) {
|
|
1087
|
+
if (paths.length > MAX_PATHS) {
|
|
1088
|
+
throw new PathBudgetExceeded(
|
|
1089
|
+
`path budget exceeded, more than ${MAX_PATHS} paths`
|
|
1090
|
+
);
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1093
|
+
function recordTerminal(ctx, terminal, home, path10) {
|
|
838
1094
|
chargeBudget(ctx.state);
|
|
839
|
-
const info = classify(
|
|
1095
|
+
const info = classify(path10, home, ctx.isAncestorOrSelf);
|
|
840
1096
|
const existing = ctx.state.byTerminal.get(terminal) ?? [];
|
|
841
1097
|
existing.push(info);
|
|
842
1098
|
ctx.state.byTerminal.set(terminal, existing);
|
|
@@ -847,15 +1103,15 @@ function containsTerminal(ctx, stmt) {
|
|
|
847
1103
|
}
|
|
848
1104
|
return childrenOf(stmt).some((child) => containsTerminal(ctx, child));
|
|
849
1105
|
}
|
|
850
|
-
function stepIf(stmt,
|
|
1106
|
+
function stepIf(stmt, path10, ctx) {
|
|
851
1107
|
const thenExit = exitKindOfList(stmt.thenBody);
|
|
852
1108
|
const elseExit = stmt.elseBody === null ? null : exitKindOfList(stmt.elseBody);
|
|
853
1109
|
const thenPath = [
|
|
854
|
-
...
|
|
1110
|
+
...path10,
|
|
855
1111
|
branchCond(stmt, stmt.condition, "positive", elseExit)
|
|
856
1112
|
];
|
|
857
1113
|
const elsePath = [
|
|
858
|
-
...
|
|
1114
|
+
...path10,
|
|
859
1115
|
branchCond(
|
|
860
1116
|
stmt,
|
|
861
1117
|
stmt.condition,
|
|
@@ -872,7 +1128,7 @@ function stepIf(stmt, path6, ctx) {
|
|
|
872
1128
|
}
|
|
873
1129
|
return out;
|
|
874
1130
|
}
|
|
875
|
-
function stepSwitch(stmt,
|
|
1131
|
+
function stepSwitch(stmt, path10, ctx) {
|
|
876
1132
|
const out = [];
|
|
877
1133
|
const negations = [];
|
|
878
1134
|
let defaultRanBody = false;
|
|
@@ -882,7 +1138,7 @@ function stepSwitch(stmt, path6, ctx) {
|
|
|
882
1138
|
if (hasStrayBreak(group.body)) {
|
|
883
1139
|
throw new UnmodeledFlow("non-trailing break in switch clause");
|
|
884
1140
|
}
|
|
885
|
-
const groupPath = group.condition === null ? [...
|
|
1141
|
+
const groupPath = group.condition === null ? [...path10, ...negations] : [...path10, fixedCond(group.condition, "positive", "explicit")];
|
|
886
1142
|
const conts = enumerate(ctx, group.body, groupPath);
|
|
887
1143
|
if (conts.length > 0) {
|
|
888
1144
|
if (!group.hasTrailingBreak && !fallthroughSafe) {
|
|
@@ -899,24 +1155,24 @@ function stepSwitch(stmt, path6, ctx) {
|
|
|
899
1155
|
}
|
|
900
1156
|
}
|
|
901
1157
|
if (!defaultRanBody) {
|
|
902
|
-
out.push([...
|
|
1158
|
+
out.push([...path10, ...negations]);
|
|
903
1159
|
}
|
|
904
1160
|
return out;
|
|
905
1161
|
}
|
|
906
|
-
function stepLoop(stmt,
|
|
1162
|
+
function stepLoop(stmt, path10, ctx) {
|
|
907
1163
|
const bodyExit = exitKindOfList(stmt.body);
|
|
908
1164
|
if (containsTerminal(ctx, stmt)) {
|
|
909
1165
|
enumerate(ctx, stmt.body, [
|
|
910
|
-
...
|
|
1166
|
+
...path10,
|
|
911
1167
|
loopIterationCond(stmt.condition.sourceText)
|
|
912
1168
|
]);
|
|
913
1169
|
}
|
|
914
1170
|
if (bodyExit !== null) {
|
|
915
|
-
return [[...
|
|
1171
|
+
return [[...path10, loopCompletedCond(stmt.condition.sourceText, bodyExit)]];
|
|
916
1172
|
}
|
|
917
|
-
return [
|
|
1173
|
+
return [path10];
|
|
918
1174
|
}
|
|
919
|
-
function stepTry(stmt,
|
|
1175
|
+
function stepTry(stmt, path10, ctx) {
|
|
920
1176
|
if (stmt.finallyBody !== null) {
|
|
921
1177
|
const finallyHasTerminal = stmt.finallyBody.some(
|
|
922
1178
|
(s) => containsTerminal(ctx, s)
|
|
@@ -926,22 +1182,22 @@ function stepTry(stmt, path6, ctx) {
|
|
|
926
1182
|
}
|
|
927
1183
|
}
|
|
928
1184
|
const out = [];
|
|
929
|
-
out.push(...enumerate(ctx, stmt.tryBody,
|
|
1185
|
+
out.push(...enumerate(ctx, stmt.tryBody, path10));
|
|
930
1186
|
if (stmt.catchBody !== null) {
|
|
931
|
-
const catchPath = [...
|
|
1187
|
+
const catchPath = [...path10, catchEntryCond()];
|
|
932
1188
|
out.push(...enumerate(ctx, stmt.catchBody, catchPath));
|
|
933
1189
|
}
|
|
934
1190
|
return out;
|
|
935
1191
|
}
|
|
936
|
-
function stepExit(stmt,
|
|
1192
|
+
function stepExit(stmt, path10, ctx) {
|
|
937
1193
|
const collector = ctx.state.callbackExits[ctx.state.callbackExits.length - 1];
|
|
938
1194
|
if (collector !== void 0 && (stmt.exit === "return" || stmt.exit === "throw")) {
|
|
939
|
-
collector.push(
|
|
1195
|
+
collector.push(path10);
|
|
940
1196
|
}
|
|
941
1197
|
return [];
|
|
942
1198
|
}
|
|
943
|
-
function stepOpaque(_stmt,
|
|
944
|
-
return [
|
|
1199
|
+
function stepOpaque(_stmt, path10, _ctx) {
|
|
1200
|
+
return [path10];
|
|
945
1201
|
}
|
|
946
1202
|
var stepHandlers = {
|
|
947
1203
|
if: stepIf,
|
|
@@ -951,22 +1207,23 @@ var stepHandlers = {
|
|
|
951
1207
|
exit: stepExit,
|
|
952
1208
|
opaque: stepOpaque
|
|
953
1209
|
};
|
|
954
|
-
function stepCallback(ctx, body,
|
|
1210
|
+
function stepCallback(ctx, body, path10) {
|
|
955
1211
|
const exits = [];
|
|
956
1212
|
ctx.state.callbackExits.push(exits);
|
|
957
1213
|
let fellThrough;
|
|
958
1214
|
try {
|
|
959
|
-
fellThrough = enumerate(ctx, body,
|
|
1215
|
+
fellThrough = enumerate(ctx, body, path10);
|
|
960
1216
|
} finally {
|
|
961
1217
|
ctx.state.callbackExits.pop();
|
|
962
1218
|
}
|
|
963
1219
|
const out = [...fellThrough, ...exits];
|
|
964
|
-
return out.length === 0 ? [
|
|
1220
|
+
return out.length === 0 ? [path10] : out;
|
|
965
1221
|
}
|
|
966
|
-
function stepStatement(ctx, stmt,
|
|
967
|
-
let paths = [
|
|
1222
|
+
function stepStatement(ctx, stmt, path10) {
|
|
1223
|
+
let paths = [path10];
|
|
968
1224
|
for (const body of stmt.callbacks ?? []) {
|
|
969
1225
|
paths = paths.flatMap((each) => stepCallback(ctx, body, each));
|
|
1226
|
+
limitOpenPaths(paths);
|
|
970
1227
|
}
|
|
971
1228
|
const ownTerminals = ctx.terminalsByStmt.get(stmt) ?? [];
|
|
972
1229
|
for (const each of withRejoined(paths)) {
|
|
@@ -983,7 +1240,7 @@ function stepStatement(ctx, stmt, path6) {
|
|
|
983
1240
|
)
|
|
984
1241
|
);
|
|
985
1242
|
}
|
|
986
|
-
function soleDisagreement(left, right) {
|
|
1243
|
+
function soleDisagreement(left, right, keepsArms) {
|
|
987
1244
|
if (left.length !== right.length) {
|
|
988
1245
|
return null;
|
|
989
1246
|
}
|
|
@@ -1002,9 +1259,10 @@ function soleDisagreement(left, right) {
|
|
|
1002
1259
|
}
|
|
1003
1260
|
found = at;
|
|
1004
1261
|
}
|
|
1005
|
-
|
|
1262
|
+
const test = found === null ? null : left[found]?.info.expression ?? null;
|
|
1263
|
+
return test !== null && keepsArms(test) ? null : found;
|
|
1006
1264
|
}
|
|
1007
|
-
function mergeRejoined(paths) {
|
|
1265
|
+
function mergeRejoined(paths, keepsArms = KEEPS_NO_ARMS) {
|
|
1008
1266
|
let current = paths;
|
|
1009
1267
|
for (let round = 0; round < current.length; round++) {
|
|
1010
1268
|
const out = [];
|
|
@@ -1019,7 +1277,11 @@ function mergeRejoined(paths) {
|
|
|
1019
1277
|
if (taken.has(j)) {
|
|
1020
1278
|
continue;
|
|
1021
1279
|
}
|
|
1022
|
-
const at = soleDisagreement(
|
|
1280
|
+
const at = soleDisagreement(
|
|
1281
|
+
combined,
|
|
1282
|
+
current[j],
|
|
1283
|
+
keepsArms
|
|
1284
|
+
);
|
|
1023
1285
|
if (at === null) {
|
|
1024
1286
|
continue;
|
|
1025
1287
|
}
|
|
@@ -1045,21 +1307,18 @@ function enumerate(ctx, stmts, prefix) {
|
|
|
1045
1307
|
let frontiers = [[...prefix]];
|
|
1046
1308
|
for (const stmt of stmts) {
|
|
1047
1309
|
const nextFrontiers = [];
|
|
1048
|
-
for (const
|
|
1049
|
-
nextFrontiers.push(...stepStatement(ctx, stmt,
|
|
1310
|
+
for (const path10 of mergeRejoined(frontiers, ctx.keepsArms)) {
|
|
1311
|
+
nextFrontiers.push(...stepStatement(ctx, stmt, path10));
|
|
1050
1312
|
}
|
|
1051
1313
|
frontiers = nextFrontiers;
|
|
1052
|
-
|
|
1053
|
-
throw new PathBudgetExceeded(
|
|
1054
|
-
`path budget exceeded, more than ${MAX_PATHS} paths`
|
|
1055
|
-
);
|
|
1056
|
-
}
|
|
1314
|
+
limitOpenPaths(frontiers);
|
|
1057
1315
|
if (frontiers.length === 0) {
|
|
1058
1316
|
break;
|
|
1059
1317
|
}
|
|
1060
1318
|
}
|
|
1061
1319
|
return frontiers;
|
|
1062
1320
|
}
|
|
1321
|
+
var KEEPS_NO_ARMS = () => false;
|
|
1063
1322
|
function buildParentMap(statements) {
|
|
1064
1323
|
const parentOf = /* @__PURE__ */ new Map();
|
|
1065
1324
|
const visit = (stmt, parent) => {
|
|
@@ -1093,13 +1352,14 @@ function enumerateStructuredPaths(input) {
|
|
|
1093
1352
|
};
|
|
1094
1353
|
const ctx = {
|
|
1095
1354
|
terminalsByStmt: input.terminalsByStmt,
|
|
1355
|
+
keepsArms: input.keepsArms ?? KEEPS_NO_ARMS,
|
|
1096
1356
|
state,
|
|
1097
1357
|
isAncestorOrSelf
|
|
1098
1358
|
};
|
|
1099
1359
|
const continuations = withRejoined(enumerate(ctx, input.statements, []));
|
|
1100
|
-
for (const
|
|
1360
|
+
for (const path10 of continuations) {
|
|
1101
1361
|
chargeBudget(state);
|
|
1102
|
-
state.fallthrough.push(classify(
|
|
1362
|
+
state.fallthrough.push(classify(path10, null, isAncestorOrSelf));
|
|
1103
1363
|
}
|
|
1104
1364
|
return { byTerminal: state.byTerminal, fallthrough: state.fallthrough };
|
|
1105
1365
|
}
|
|
@@ -1142,8 +1402,8 @@ function sharedGatingConditions(paths, readPredicate) {
|
|
|
1142
1402
|
return [];
|
|
1143
1403
|
}
|
|
1144
1404
|
const shared = new Set(first.map(keyOf2));
|
|
1145
|
-
for (const
|
|
1146
|
-
const here = new Set(
|
|
1405
|
+
for (const path10 of rest) {
|
|
1406
|
+
const here = new Set(path10.map(keyOf2));
|
|
1147
1407
|
for (const value of shared) {
|
|
1148
1408
|
if (!here.has(value)) {
|
|
1149
1409
|
shared.delete(value);
|
|
@@ -1251,15 +1511,12 @@ var EnclosingNodes = class {
|
|
|
1251
1511
|
|
|
1252
1512
|
// src/paths/nodeWalk.ts
|
|
1253
1513
|
var SKIP_CHILDREN = /* @__PURE__ */ Symbol("skipChildren");
|
|
1254
|
-
function walkDescendants(root, carried, visitor) {
|
|
1255
|
-
for (const child of root
|
|
1256
|
-
if (child === null) {
|
|
1257
|
-
continue;
|
|
1258
|
-
}
|
|
1514
|
+
function walkDescendants(root, carried, childrenOf2, visitor) {
|
|
1515
|
+
for (const child of childrenOf2(root)) {
|
|
1259
1516
|
visitor.at(child, carried);
|
|
1260
1517
|
const inner = visitor.into(child, carried);
|
|
1261
1518
|
if (inner !== SKIP_CHILDREN) {
|
|
1262
|
-
walkDescendants(child, inner, visitor);
|
|
1519
|
+
walkDescendants(child, inner, childrenOf2, visitor);
|
|
1263
1520
|
}
|
|
1264
1521
|
}
|
|
1265
1522
|
}
|
|
@@ -1338,6 +1595,11 @@ function valueToReadFurtherFrom(reading) {
|
|
|
1338
1595
|
return reading.kind === "written" ? reading.value : null;
|
|
1339
1596
|
}
|
|
1340
1597
|
|
|
1598
|
+
// src/redirectOption.ts
|
|
1599
|
+
function redirectDeliveryWhenSet(option, value) {
|
|
1600
|
+
return option.handsBack.includes(value) ? "response" : "followed";
|
|
1601
|
+
}
|
|
1602
|
+
|
|
1341
1603
|
// src/testFiles.ts
|
|
1342
1604
|
function isListedTestFile(file, listed) {
|
|
1343
1605
|
if (listed === void 0) {
|
|
@@ -1407,18 +1669,179 @@ function quoted(text, key) {
|
|
|
1407
1669
|
}
|
|
1408
1670
|
|
|
1409
1671
|
// src/adapterStamp.ts
|
|
1672
|
+
var import_node_crypto2 = require("crypto");
|
|
1673
|
+
var import_node_fs3 = __toESM(require("fs"), 1);
|
|
1674
|
+
var import_node_path5 = __toESM(require("path"), 1);
|
|
1675
|
+
var import_node_url = require("url");
|
|
1676
|
+
|
|
1677
|
+
// src/codeHash.ts
|
|
1410
1678
|
var import_node_crypto = require("crypto");
|
|
1411
1679
|
var import_node_fs2 = __toESM(require("fs"), 1);
|
|
1412
1680
|
var import_node_module = require("module");
|
|
1413
1681
|
var import_node_path4 = __toESM(require("path"), 1);
|
|
1414
|
-
var
|
|
1415
|
-
var
|
|
1416
|
-
var
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1682
|
+
var SUSS_SCOPE = "@suss/";
|
|
1683
|
+
var IMPORT_FORMS = /\b(?:from|import)\s*\(?\s*["']([^"'\s]+)["']|require\s*\(\s*["']([^"'\s]+)["']/g;
|
|
1684
|
+
var CONDITIONS = {
|
|
1685
|
+
import: /* @__PURE__ */ new Set(["import", "node", "default"]),
|
|
1686
|
+
require: /* @__PURE__ */ new Set(["require", "node", "default"])
|
|
1687
|
+
};
|
|
1688
|
+
function createCodeHasher() {
|
|
1689
|
+
const read = /* @__PURE__ */ new Map();
|
|
1690
|
+
function readOnce(file) {
|
|
1691
|
+
const known = read.get(file);
|
|
1692
|
+
if (known !== void 0) {
|
|
1693
|
+
return known;
|
|
1694
|
+
}
|
|
1695
|
+
const found = readCodeFile(file);
|
|
1696
|
+
read.set(file, found);
|
|
1697
|
+
return found;
|
|
1698
|
+
}
|
|
1699
|
+
function codeFiles(entryFile) {
|
|
1700
|
+
const entry = realFile(entryFile);
|
|
1701
|
+
if (entry === null || readOnce(entry) === null) {
|
|
1702
|
+
return [];
|
|
1703
|
+
}
|
|
1704
|
+
const found = [entry];
|
|
1705
|
+
const seen = new Set(found);
|
|
1706
|
+
for (let at = 0; at < found.length; at++) {
|
|
1707
|
+
for (const next of readOnce(found[at])?.imports ?? []) {
|
|
1708
|
+
if (seen.has(next)) {
|
|
1709
|
+
continue;
|
|
1710
|
+
}
|
|
1711
|
+
seen.add(next);
|
|
1712
|
+
if (readOnce(next) !== null) {
|
|
1713
|
+
found.push(next);
|
|
1714
|
+
}
|
|
1715
|
+
}
|
|
1716
|
+
}
|
|
1717
|
+
return found;
|
|
1718
|
+
}
|
|
1719
|
+
function codeHash(entryFile) {
|
|
1720
|
+
const files = codeFiles(entryFile);
|
|
1721
|
+
if (files.length === 0) {
|
|
1722
|
+
return "";
|
|
1723
|
+
}
|
|
1724
|
+
const hash = (0, import_node_crypto.createHash)("sha256");
|
|
1725
|
+
for (const file of files) {
|
|
1726
|
+
hash.update(read.get(file)?.digest ?? "");
|
|
1727
|
+
}
|
|
1728
|
+
return hash.digest("hex").slice(0, 16);
|
|
1729
|
+
}
|
|
1730
|
+
return { codeFiles, codeHash };
|
|
1731
|
+
}
|
|
1732
|
+
var processCodeHasher = createCodeHasher();
|
|
1733
|
+
function readCodeFile(file) {
|
|
1734
|
+
let text;
|
|
1735
|
+
try {
|
|
1736
|
+
text = import_node_fs2.default.readFileSync(file);
|
|
1737
|
+
} catch {
|
|
1738
|
+
return null;
|
|
1739
|
+
}
|
|
1740
|
+
return {
|
|
1741
|
+
digest: (0, import_node_crypto.createHash)("sha256").update(text).digest("hex"),
|
|
1742
|
+
imports: importsOf(file, text.toString("utf8"))
|
|
1743
|
+
};
|
|
1744
|
+
}
|
|
1745
|
+
function importsOf(file, text) {
|
|
1746
|
+
const asked = /* @__PURE__ */ new Set();
|
|
1747
|
+
const found = [];
|
|
1748
|
+
for (const match of text.matchAll(IMPORT_FORMS)) {
|
|
1749
|
+
const kind = match[1] === void 0 ? "require" : "import";
|
|
1750
|
+
const specifier = match[1] ?? match[2] ?? "";
|
|
1751
|
+
if (asked.has(`${kind} ${specifier}`)) {
|
|
1752
|
+
continue;
|
|
1753
|
+
}
|
|
1754
|
+
asked.add(`${kind} ${specifier}`);
|
|
1755
|
+
const target = resolveImport(specifier, file, kind);
|
|
1756
|
+
if (target !== null) {
|
|
1757
|
+
found.push(target);
|
|
1758
|
+
}
|
|
1759
|
+
}
|
|
1760
|
+
return found;
|
|
1761
|
+
}
|
|
1762
|
+
function resolveImport(specifier, fromFile, kind) {
|
|
1763
|
+
if (specifier.startsWith("./") || specifier.startsWith("../")) {
|
|
1764
|
+
return realFile(import_node_path4.default.resolve(import_node_path4.default.dirname(fromFile), specifier));
|
|
1765
|
+
}
|
|
1766
|
+
if (specifier.startsWith(SUSS_SCOPE)) {
|
|
1767
|
+
return resolvePackageImport(specifier, fromFile, kind);
|
|
1768
|
+
}
|
|
1769
|
+
return null;
|
|
1770
|
+
}
|
|
1771
|
+
function resolvePackageImport(specifier, fromFile, kind) {
|
|
1772
|
+
const [scope = "", name = "", ...rest] = specifier.split("/");
|
|
1773
|
+
const packageName = `${scope}/${name}`;
|
|
1774
|
+
const subpath = rest.length === 0 ? "." : `./${rest.join("/")}`;
|
|
1775
|
+
const lookIn = (0, import_node_module.createRequire)(fromFile).resolve.paths(packageName) ?? [];
|
|
1776
|
+
for (const dir of lookIn) {
|
|
1777
|
+
const packageDir = import_node_path4.default.join(dir, packageName);
|
|
1778
|
+
const manifest = readManifest(packageDir);
|
|
1779
|
+
if (manifest === null) {
|
|
1780
|
+
continue;
|
|
1781
|
+
}
|
|
1782
|
+
const target = exportTarget(manifest, subpath, CONDITIONS[kind]);
|
|
1783
|
+
return target === null ? null : realFile(import_node_path4.default.join(packageDir, target));
|
|
1784
|
+
}
|
|
1785
|
+
return null;
|
|
1786
|
+
}
|
|
1787
|
+
function readManifest(packageDir) {
|
|
1788
|
+
try {
|
|
1789
|
+
return JSON.parse(
|
|
1790
|
+
import_node_fs2.default.readFileSync(import_node_path4.default.join(packageDir, "package.json"), "utf8")
|
|
1791
|
+
);
|
|
1792
|
+
} catch {
|
|
1793
|
+
return null;
|
|
1794
|
+
}
|
|
1795
|
+
}
|
|
1796
|
+
function exportTarget(manifest, subpath, conditions) {
|
|
1797
|
+
if (manifest.exports === void 0) {
|
|
1798
|
+
return subpath === "." ? manifest.main ?? "index.js" : subpath;
|
|
1799
|
+
}
|
|
1800
|
+
return conditionalTarget(subpathEntry(manifest.exports, subpath), conditions);
|
|
1801
|
+
}
|
|
1802
|
+
function subpathEntry(exportsField, subpath) {
|
|
1803
|
+
const isSubpathMap = typeof exportsField === "object" && exportsField !== null && !Array.isArray(exportsField) && Object.keys(exportsField).some((key) => key.startsWith("."));
|
|
1804
|
+
if (isSubpathMap) {
|
|
1805
|
+
return exportsField[subpath];
|
|
1806
|
+
}
|
|
1807
|
+
return subpath === "." ? exportsField : void 0;
|
|
1808
|
+
}
|
|
1809
|
+
function conditionalTarget(value, conditions) {
|
|
1810
|
+
if (typeof value === "string") {
|
|
1811
|
+
return value;
|
|
1812
|
+
}
|
|
1813
|
+
if (Array.isArray(value)) {
|
|
1814
|
+
for (const each of value) {
|
|
1815
|
+
const found = conditionalTarget(each, conditions);
|
|
1816
|
+
if (found !== null) {
|
|
1817
|
+
return found;
|
|
1818
|
+
}
|
|
1819
|
+
}
|
|
1820
|
+
return null;
|
|
1821
|
+
}
|
|
1822
|
+
if (value === null || typeof value !== "object") {
|
|
1823
|
+
return null;
|
|
1824
|
+
}
|
|
1825
|
+
for (const [condition, target] of Object.entries(value)) {
|
|
1826
|
+
if (!conditions.has(condition)) {
|
|
1827
|
+
continue;
|
|
1828
|
+
}
|
|
1829
|
+
const found = conditionalTarget(target, conditions);
|
|
1830
|
+
if (found !== null) {
|
|
1831
|
+
return found;
|
|
1832
|
+
}
|
|
1833
|
+
}
|
|
1834
|
+
return null;
|
|
1835
|
+
}
|
|
1836
|
+
function realFile(file) {
|
|
1837
|
+
try {
|
|
1838
|
+
return import_node_fs2.default.realpathSync(file);
|
|
1839
|
+
} catch {
|
|
1840
|
+
return null;
|
|
1841
|
+
}
|
|
1842
|
+
}
|
|
1843
|
+
|
|
1844
|
+
// src/adapterStamp.ts
|
|
1422
1845
|
var SOURCE_STAMP = { kind: "source" };
|
|
1423
1846
|
function createAdapterStamp(config) {
|
|
1424
1847
|
let cachedCodeStamp = null;
|
|
@@ -1453,19 +1876,19 @@ function createAdapterStamp(config) {
|
|
|
1453
1876
|
function readAdapterCodeStamp(moduleUrl) {
|
|
1454
1877
|
try {
|
|
1455
1878
|
const selfPath = (0, import_node_url.fileURLToPath)(moduleUrl);
|
|
1456
|
-
const hash = computeDistHashFrom(
|
|
1879
|
+
const hash = computeDistHashFrom(import_node_path5.default.dirname(selfPath), processCodeHasher);
|
|
1457
1880
|
return hash.length > 0 ? { kind: "bundle", hash } : SOURCE_STAMP;
|
|
1458
1881
|
} catch {
|
|
1459
1882
|
return SOURCE_STAMP;
|
|
1460
1883
|
}
|
|
1461
1884
|
}
|
|
1462
|
-
function computeDistHashFrom(dir) {
|
|
1463
|
-
const candidates = [
|
|
1885
|
+
function computeDistHashFrom(dir, hasher = createCodeHasher()) {
|
|
1886
|
+
const candidates = [import_node_path5.default.join(dir, "index.js"), import_node_path5.default.join(dir, "index.cjs")];
|
|
1464
1887
|
for (const candidate of candidates) {
|
|
1465
|
-
if (!
|
|
1888
|
+
if (!import_node_fs3.default.existsSync(candidate)) {
|
|
1466
1889
|
continue;
|
|
1467
1890
|
}
|
|
1468
|
-
return
|
|
1891
|
+
return hasher.codeHash(candidate);
|
|
1469
1892
|
}
|
|
1470
1893
|
return "";
|
|
1471
1894
|
}
|
|
@@ -1473,10 +1896,10 @@ function computeContentHash(paths) {
|
|
|
1473
1896
|
if (paths.length === 0) {
|
|
1474
1897
|
return "";
|
|
1475
1898
|
}
|
|
1476
|
-
const hash = (0,
|
|
1899
|
+
const hash = (0, import_node_crypto2.createHash)("sha256");
|
|
1477
1900
|
for (const file of paths) {
|
|
1478
1901
|
try {
|
|
1479
|
-
hash.update(
|
|
1902
|
+
hash.update(import_node_fs3.default.readFileSync(file));
|
|
1480
1903
|
} catch {
|
|
1481
1904
|
return "";
|
|
1482
1905
|
}
|
|
@@ -1487,12 +1910,12 @@ function projectFileStamp(paths) {
|
|
|
1487
1910
|
if (paths.length === 0) {
|
|
1488
1911
|
return "none";
|
|
1489
1912
|
}
|
|
1490
|
-
const hash = (0,
|
|
1913
|
+
const hash = (0, import_node_crypto2.createHash)("sha256");
|
|
1491
1914
|
for (const file of [...paths].sort()) {
|
|
1492
1915
|
hash.update(file);
|
|
1493
1916
|
hash.update("\0");
|
|
1494
1917
|
try {
|
|
1495
|
-
hash.update(
|
|
1918
|
+
hash.update(import_node_fs3.default.readFileSync(file));
|
|
1496
1919
|
} catch {
|
|
1497
1920
|
hash.update("absent");
|
|
1498
1921
|
}
|
|
@@ -1505,8 +1928,9 @@ function extractionConfigStamp(config) {
|
|
|
1505
1928
|
["includeReachable", optionalText(config.includeReachable)],
|
|
1506
1929
|
["workspaceRoot", config.workspaceRoot],
|
|
1507
1930
|
["projectRoot", config.projectRoot],
|
|
1508
|
-
["importRoots", config.importRoots?.join(
|
|
1509
|
-
["modules", modulesStamp(config.modules)]
|
|
1931
|
+
["importRoots", config.importRoots?.join(import_node_path5.default.delimiter)],
|
|
1932
|
+
["modules", modulesStamp(config.modules)],
|
|
1933
|
+
["walkedDirectory", config.walkedDirectory]
|
|
1510
1934
|
];
|
|
1511
1935
|
return parts.flatMap(
|
|
1512
1936
|
([name, value]) => value === void 0 ? [] : [`${name}=${value}`]
|
|
@@ -1519,25 +1943,283 @@ function runDigest(packsDigest, packs, files) {
|
|
|
1519
1943
|
const inputs = packs.flatMap((pack) => pack.discoveryInputs?.(files) ?? []);
|
|
1520
1944
|
return `${packsDigest}|reads:${projectFileStamp(inputs)}`;
|
|
1521
1945
|
}
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1946
|
+
|
|
1947
|
+
// src/cache.ts
|
|
1948
|
+
var import_node_crypto5 = require("crypto");
|
|
1949
|
+
var import_promises2 = __toESM(require("fs/promises"), 1);
|
|
1950
|
+
var import_node_path8 = __toESM(require("path"), 1);
|
|
1951
|
+
var import_files3 = require("@suss/behavioral-ir/files");
|
|
1952
|
+
|
|
1953
|
+
// src/cacheIndex.ts
|
|
1954
|
+
var import_behavioral_ir6 = require("@suss/behavioral-ir");
|
|
1955
|
+
var import_files = require("@suss/behavioral-ir/files");
|
|
1956
|
+
function entriesOf(units) {
|
|
1957
|
+
const boundaries = [];
|
|
1958
|
+
const callees = [];
|
|
1959
|
+
units.forEach((summary, unit) => {
|
|
1960
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1961
|
+
const add = (key, role) => {
|
|
1962
|
+
if (key !== null && !seen.has(`${role} ${key}`)) {
|
|
1963
|
+
seen.add(`${role} ${key}`);
|
|
1964
|
+
boundaries.push([key, unit, role]);
|
|
1965
|
+
}
|
|
1966
|
+
};
|
|
1967
|
+
const own = summary.identity?.boundaryBinding ?? null;
|
|
1968
|
+
if (own !== null) {
|
|
1969
|
+
add(
|
|
1970
|
+
keyOf3(own),
|
|
1971
|
+
import_behavioral_ir6.BOUNDARY_ROLE[summary.kind] === "provider" ? "serves" : "calls"
|
|
1972
|
+
);
|
|
1973
|
+
}
|
|
1974
|
+
const spellings = /* @__PURE__ */ new Set();
|
|
1975
|
+
for (const transition of summary.transitions ?? []) {
|
|
1976
|
+
for (const effect of transition.effects ?? []) {
|
|
1977
|
+
if (effect.type === "interaction") {
|
|
1978
|
+
add(keyOf3(effect.binding), "calls");
|
|
1979
|
+
}
|
|
1980
|
+
if (effect.type === "invocation") {
|
|
1981
|
+
spellings.add(effect.callee);
|
|
1982
|
+
}
|
|
1983
|
+
}
|
|
1984
|
+
}
|
|
1985
|
+
for (const spelling of spellings) {
|
|
1986
|
+
callees.push([spelling, unit]);
|
|
1987
|
+
}
|
|
1988
|
+
});
|
|
1989
|
+
return { boundaries, callees };
|
|
1990
|
+
}
|
|
1991
|
+
function indexOf(shards) {
|
|
1992
|
+
const boundaries = {};
|
|
1993
|
+
const callees = {};
|
|
1994
|
+
shards.forEach(({ entries }, file) => {
|
|
1995
|
+
for (const [key, unit, role] of entries.boundaries) {
|
|
1996
|
+
listAt(boundaries, key).push([file, unit, role]);
|
|
1997
|
+
}
|
|
1998
|
+
for (const [spelling, unit] of entries.callees) {
|
|
1999
|
+
listAt(callees, spelling).push([file, unit]);
|
|
2000
|
+
}
|
|
2001
|
+
});
|
|
2002
|
+
return {
|
|
2003
|
+
files: shards.map(({ file, id }) => [file, id]),
|
|
2004
|
+
boundaries,
|
|
2005
|
+
callees
|
|
2006
|
+
};
|
|
2007
|
+
}
|
|
2008
|
+
function listAt(record, key) {
|
|
2009
|
+
const existing = Object.hasOwn(record, key) ? record[key] : void 0;
|
|
2010
|
+
if (existing !== void 0) {
|
|
2011
|
+
return existing;
|
|
2012
|
+
}
|
|
2013
|
+
const created = [];
|
|
2014
|
+
record[key] = created;
|
|
2015
|
+
return created;
|
|
2016
|
+
}
|
|
2017
|
+
function entriesByShard(index) {
|
|
2018
|
+
const byShard = /* @__PURE__ */ new Map();
|
|
2019
|
+
const at = index.files.map(([, id]) => {
|
|
2020
|
+
const entries = { boundaries: [], callees: [] };
|
|
2021
|
+
byShard.set(id, entries);
|
|
2022
|
+
return entries;
|
|
2023
|
+
});
|
|
2024
|
+
for (const [key, units] of Object.entries(index.boundaries)) {
|
|
2025
|
+
for (const [file, unit, role] of units) {
|
|
2026
|
+
at[file]?.boundaries.push([key, unit, role]);
|
|
1529
2027
|
}
|
|
1530
2028
|
}
|
|
1531
|
-
|
|
2029
|
+
for (const [spelling, units] of Object.entries(index.callees)) {
|
|
2030
|
+
for (const [file, unit] of units) {
|
|
2031
|
+
at[file]?.callees.push([spelling, unit]);
|
|
2032
|
+
}
|
|
2033
|
+
}
|
|
2034
|
+
return byShard;
|
|
2035
|
+
}
|
|
2036
|
+
function readStoreIndex(file) {
|
|
2037
|
+
try {
|
|
2038
|
+
const index = (0, import_files.readJsonFile)(file);
|
|
2039
|
+
return Array.isArray(index.files) ? index : null;
|
|
2040
|
+
} catch {
|
|
2041
|
+
return null;
|
|
2042
|
+
}
|
|
2043
|
+
}
|
|
2044
|
+
function writeStoreIndex(file, index) {
|
|
2045
|
+
(0, import_files.writeDocumentFile)(file, index);
|
|
2046
|
+
}
|
|
2047
|
+
function keyOf3(binding) {
|
|
2048
|
+
try {
|
|
2049
|
+
return (0, import_behavioral_ir6.displayLabel)(binding);
|
|
2050
|
+
} catch {
|
|
2051
|
+
return null;
|
|
2052
|
+
}
|
|
1532
2053
|
}
|
|
1533
2054
|
|
|
1534
|
-
// src/
|
|
2055
|
+
// src/cacheShards.ts
|
|
1535
2056
|
var import_node_crypto3 = require("crypto");
|
|
1536
|
-
var
|
|
1537
|
-
var
|
|
2057
|
+
var import_node_fs4 = __toESM(require("fs"), 1);
|
|
2058
|
+
var import_node_path6 = __toESM(require("path"), 1);
|
|
2059
|
+
var import_files2 = require("@suss/behavioral-ir/files");
|
|
2060
|
+
var SHARDS_DIR = "shards";
|
|
2061
|
+
var RECORDS_DIR = "records";
|
|
2062
|
+
var STORED_ID = /^[0-9a-f]{32}\.json$/;
|
|
2063
|
+
function writeShard(entryDir, content) {
|
|
2064
|
+
return writeOnce(import_node_path6.default.join(entryDir, SHARDS_DIR), interned(content));
|
|
2065
|
+
}
|
|
2066
|
+
function readShard(entryDir, id, file) {
|
|
2067
|
+
const stored = readStored(import_node_path6.default.join(entryDir, SHARDS_DIR), id);
|
|
2068
|
+
if (stored?.file !== file || !Array.isArray(stored.units)) {
|
|
2069
|
+
return null;
|
|
2070
|
+
}
|
|
2071
|
+
const take = takerFor(stored.intern ?? []);
|
|
2072
|
+
return {
|
|
2073
|
+
file: stored.file,
|
|
2074
|
+
units: stored.units.map((unit) => expanded(unit, take))
|
|
2075
|
+
};
|
|
2076
|
+
}
|
|
2077
|
+
function writeRecord(entryDir, meta) {
|
|
2078
|
+
return writeOnce(import_node_path6.default.join(entryDir, RECORDS_DIR), { meta });
|
|
2079
|
+
}
|
|
2080
|
+
function readRecord(entryDir, id) {
|
|
2081
|
+
const stored = readStored(import_node_path6.default.join(entryDir, RECORDS_DIR), id);
|
|
2082
|
+
return typeof stored === "object" && stored !== null ? stored : null;
|
|
2083
|
+
}
|
|
2084
|
+
function recordReader(entryDir) {
|
|
2085
|
+
const opened = /* @__PURE__ */ new Map();
|
|
2086
|
+
return (id) => {
|
|
2087
|
+
if (!opened.has(id)) {
|
|
2088
|
+
const record2 = readRecord(entryDir, id);
|
|
2089
|
+
opened.set(id, record2);
|
|
2090
|
+
return record2;
|
|
2091
|
+
}
|
|
2092
|
+
const record = opened.get(id) ?? null;
|
|
2093
|
+
return record === null ? null : copyOfJson(record);
|
|
2094
|
+
};
|
|
2095
|
+
}
|
|
2096
|
+
function removeStoredOutside(entryDir, keep) {
|
|
2097
|
+
for (const kind of [SHARDS_DIR, RECORDS_DIR]) {
|
|
2098
|
+
const root = import_node_path6.default.join(entryDir, kind);
|
|
2099
|
+
for (const prefix of namesIn(root)) {
|
|
2100
|
+
const dir = import_node_path6.default.join(root, prefix);
|
|
2101
|
+
for (const name of namesIn(dir)) {
|
|
2102
|
+
if (STORED_ID.test(name) && !keep.has(name.slice(0, -".json".length))) {
|
|
2103
|
+
import_node_fs4.default.rmSync(import_node_path6.default.join(dir, name), { force: true });
|
|
2104
|
+
}
|
|
2105
|
+
}
|
|
2106
|
+
}
|
|
2107
|
+
}
|
|
2108
|
+
}
|
|
2109
|
+
function namesIn(dir) {
|
|
2110
|
+
try {
|
|
2111
|
+
return import_node_fs4.default.readdirSync(dir);
|
|
2112
|
+
} catch {
|
|
2113
|
+
return [];
|
|
2114
|
+
}
|
|
2115
|
+
}
|
|
2116
|
+
function writeOnce(root, value) {
|
|
2117
|
+
const pieces = [...(0, import_files2.documentPieces)(value)];
|
|
2118
|
+
const hash = (0, import_node_crypto3.createHash)("sha256");
|
|
2119
|
+
for (const piece of pieces) {
|
|
2120
|
+
hash.update(piece);
|
|
2121
|
+
}
|
|
2122
|
+
const id = hash.digest("hex").slice(0, 32);
|
|
2123
|
+
const file = storedPath(root, id);
|
|
2124
|
+
if (!import_node_fs4.default.existsSync(file)) {
|
|
2125
|
+
(0, import_files2.writeFileAtomically)(file, pieces);
|
|
2126
|
+
}
|
|
2127
|
+
return id;
|
|
2128
|
+
}
|
|
2129
|
+
function readStored(root, id) {
|
|
2130
|
+
try {
|
|
2131
|
+
return (0, import_files2.readJsonFile)(storedPath(root, id));
|
|
2132
|
+
} catch {
|
|
2133
|
+
return void 0;
|
|
2134
|
+
}
|
|
2135
|
+
}
|
|
2136
|
+
function storedPath(root, id) {
|
|
2137
|
+
return import_node_path6.default.join(root, id.slice(0, 2), `${id}.json`);
|
|
2138
|
+
}
|
|
2139
|
+
function interned(content) {
|
|
2140
|
+
const intern = [];
|
|
2141
|
+
const byText = /* @__PURE__ */ new Map();
|
|
2142
|
+
const byObject = /* @__PURE__ */ new Map();
|
|
2143
|
+
const positionOf = (value) => {
|
|
2144
|
+
const known = byObject.get(value);
|
|
2145
|
+
if (known !== void 0) {
|
|
2146
|
+
return known;
|
|
2147
|
+
}
|
|
2148
|
+
const text = JSON.stringify(value) ?? "null";
|
|
2149
|
+
let position = byText.get(text);
|
|
2150
|
+
if (position === void 0) {
|
|
2151
|
+
position = intern.length;
|
|
2152
|
+
intern.push(value);
|
|
2153
|
+
byText.set(text, position);
|
|
2154
|
+
}
|
|
2155
|
+
if (typeof value === "object" && value !== null) {
|
|
2156
|
+
byObject.set(value, position);
|
|
2157
|
+
}
|
|
2158
|
+
return position;
|
|
2159
|
+
};
|
|
2160
|
+
const positions = (values) => Array.isArray(values) ? values.map(positionOf) : values;
|
|
2161
|
+
const units = content.units.map((summary) => ({
|
|
2162
|
+
...summary,
|
|
2163
|
+
transitions: summary.transitions.map((transition) => ({
|
|
2164
|
+
...transition,
|
|
2165
|
+
conditions: positions(transition.conditions),
|
|
2166
|
+
effects: positions(transition.effects)
|
|
2167
|
+
})),
|
|
2168
|
+
gaps: summary.gaps.map((gap) => ({
|
|
2169
|
+
...gap,
|
|
2170
|
+
conditions: positions(gap.conditions)
|
|
2171
|
+
}))
|
|
2172
|
+
}));
|
|
2173
|
+
return {
|
|
2174
|
+
file: content.file,
|
|
2175
|
+
intern,
|
|
2176
|
+
units
|
|
2177
|
+
};
|
|
2178
|
+
}
|
|
2179
|
+
function expanded(unit, take) {
|
|
2180
|
+
const values = (positions) => Array.isArray(positions) ? positions.map((at) => take(at)) : positions;
|
|
2181
|
+
const transitions = Array.isArray(unit.transitions) ? unit.transitions : [];
|
|
2182
|
+
const gaps = Array.isArray(unit.gaps) ? unit.gaps : [];
|
|
2183
|
+
return {
|
|
2184
|
+
...unit,
|
|
2185
|
+
transitions: transitions.map((transition) => ({
|
|
2186
|
+
...transition,
|
|
2187
|
+
conditions: values(transition.conditions),
|
|
2188
|
+
effects: values(transition.effects)
|
|
2189
|
+
})),
|
|
2190
|
+
gaps: gaps.map((gap) => ({
|
|
2191
|
+
...gap,
|
|
2192
|
+
conditions: values(gap.conditions)
|
|
2193
|
+
}))
|
|
2194
|
+
};
|
|
2195
|
+
}
|
|
2196
|
+
function takerFor(intern) {
|
|
2197
|
+
const handedOut = /* @__PURE__ */ new Set();
|
|
2198
|
+
return (position) => {
|
|
2199
|
+
const value = intern[position];
|
|
2200
|
+
if (!handedOut.has(position)) {
|
|
2201
|
+
handedOut.add(position);
|
|
2202
|
+
return value;
|
|
2203
|
+
}
|
|
2204
|
+
return copyOfJson(value);
|
|
2205
|
+
};
|
|
2206
|
+
}
|
|
2207
|
+
function copyOfJson(value) {
|
|
2208
|
+
if (Array.isArray(value)) {
|
|
2209
|
+
return value.map(copyOfJson);
|
|
2210
|
+
}
|
|
2211
|
+
if (typeof value === "object" && value !== null) {
|
|
2212
|
+
const copy = {};
|
|
2213
|
+
for (const key of Object.keys(value)) {
|
|
2214
|
+
copy[key] = copyOfJson(value[key]);
|
|
2215
|
+
}
|
|
2216
|
+
return copy;
|
|
2217
|
+
}
|
|
2218
|
+
return value;
|
|
2219
|
+
}
|
|
1538
2220
|
|
|
1539
2221
|
// src/cacheStamps.ts
|
|
1540
|
-
var
|
|
2222
|
+
var import_node_crypto4 = require("crypto");
|
|
1541
2223
|
var import_promises = __toESM(require("fs/promises"), 1);
|
|
1542
2224
|
var RECENT_CHANGE_MS = 2e3;
|
|
1543
2225
|
function stampMayMissAWrite(stat, statAt) {
|
|
@@ -1627,7 +2309,7 @@ function reusableHash(prior, stamp) {
|
|
|
1627
2309
|
async function hashFile(filePath) {
|
|
1628
2310
|
try {
|
|
1629
2311
|
const content = await import_promises.default.readFile(filePath);
|
|
1630
|
-
return (0,
|
|
2312
|
+
return (0, import_node_crypto4.createHash)("sha256").update(content).digest("hex").slice(0, 16);
|
|
1631
2313
|
} catch {
|
|
1632
2314
|
return null;
|
|
1633
2315
|
}
|
|
@@ -1642,11 +2324,30 @@ function fileStampEquals(a, b) {
|
|
|
1642
2324
|
return a.path === b.path && a.mtimeMs === b.mtimeMs && a.size === b.size;
|
|
1643
2325
|
}
|
|
1644
2326
|
|
|
2327
|
+
// src/ignoredDirectory.ts
|
|
2328
|
+
var import_node_fs5 = __toESM(require("fs"), 1);
|
|
2329
|
+
var import_node_path7 = __toESM(require("path"), 1);
|
|
2330
|
+
function makeIgnoredDirectory(dir) {
|
|
2331
|
+
import_node_fs5.default.mkdirSync(dir, { recursive: true });
|
|
2332
|
+
const ignore = import_node_path7.default.join(dir, ".gitignore");
|
|
2333
|
+
if (!import_node_fs5.default.existsSync(ignore)) {
|
|
2334
|
+
import_node_fs5.default.writeFileSync(ignore, "*\n");
|
|
2335
|
+
}
|
|
2336
|
+
}
|
|
2337
|
+
|
|
1645
2338
|
// src/cache.ts
|
|
1646
|
-
var SCHEMA_VERSION = "
|
|
2339
|
+
var SCHEMA_VERSION = "10";
|
|
2340
|
+
var MANIFEST = "manifest.json";
|
|
2341
|
+
var INDEX = "index.json";
|
|
1647
2342
|
var MAX_ENTRIES = 2;
|
|
1648
2343
|
var ENTRY_PREFIX = "key-";
|
|
1649
2344
|
var ENTRY_DIR_NAME = new RegExp(`^${ENTRY_PREFIX}[0-9a-f]{16}$`);
|
|
2345
|
+
function ownersWhereWritten(summaries, walkedFileOf) {
|
|
2346
|
+
return summaries.map((summary) => {
|
|
2347
|
+
const walked = walkedFileOf(summary.location.file);
|
|
2348
|
+
return walked === void 0 ? [] : [walked];
|
|
2349
|
+
});
|
|
2350
|
+
}
|
|
1650
2351
|
function createCacheLayer(cacheDir) {
|
|
1651
2352
|
if (cacheDir === null) {
|
|
1652
2353
|
return {
|
|
@@ -1666,7 +2367,7 @@ function createCacheLayer(cacheDir) {
|
|
|
1666
2367
|
const lookupWith = async (input, run) => {
|
|
1667
2368
|
const entryDir = entryDirFor(cacheDir, input);
|
|
1668
2369
|
const manifest = await manifests.readAtRunStart(
|
|
1669
|
-
|
|
2370
|
+
import_node_path8.default.join(entryDir, MANIFEST)
|
|
1670
2371
|
);
|
|
1671
2372
|
if (manifest === null) {
|
|
1672
2373
|
return missDiag(await describeAbsentEntry(cacheDir));
|
|
@@ -1681,11 +2382,15 @@ function createCacheLayer(cacheDir) {
|
|
|
1681
2382
|
if (!await filesStillMatch(manifest.files, run)) {
|
|
1682
2383
|
return missDiag("files-changed");
|
|
1683
2384
|
}
|
|
2385
|
+
const summaries = storedSummaries(entryDir, manifest);
|
|
2386
|
+
if (summaries === null) {
|
|
2387
|
+
return missDiag("no-manifest");
|
|
2388
|
+
}
|
|
1684
2389
|
await markUsed(entryDir);
|
|
1685
2390
|
manifests.forget();
|
|
1686
2391
|
return {
|
|
1687
2392
|
kind: "hit",
|
|
1688
|
-
summaries
|
|
2393
|
+
summaries,
|
|
1689
2394
|
diagnostic: { kind: "hit" }
|
|
1690
2395
|
};
|
|
1691
2396
|
};
|
|
@@ -1705,10 +2410,8 @@ function createCacheLayer(cacheDir) {
|
|
|
1705
2410
|
},
|
|
1706
2411
|
async plan(input) {
|
|
1707
2412
|
const entryDir = entryDirFor(cacheDir, input);
|
|
1708
|
-
const manifest = await manifests.readAgain(
|
|
1709
|
-
|
|
1710
|
-
);
|
|
1711
|
-
if (manifest === null || manifest.roots === void 0 || manifest.rootMeta === void 0 || manifest.owners === void 0) {
|
|
2413
|
+
const manifest = await manifests.readAgain(import_node_path8.default.join(entryDir, MANIFEST));
|
|
2414
|
+
if (manifest === null || manifest.roots === void 0 || manifest.rootMeta === void 0) {
|
|
1712
2415
|
return null;
|
|
1713
2416
|
}
|
|
1714
2417
|
const run = await runFor(input);
|
|
@@ -1719,14 +2422,17 @@ function createCacheLayer(cacheDir) {
|
|
|
1719
2422
|
)) {
|
|
1720
2423
|
return null;
|
|
1721
2424
|
}
|
|
2425
|
+
const summaries = storedSummaries(entryDir, manifest);
|
|
2426
|
+
const records = storedRecords(entryDir, manifest);
|
|
2427
|
+
if (summaries === null || records === null) {
|
|
2428
|
+
return null;
|
|
2429
|
+
}
|
|
1722
2430
|
await markUsed(entryDir);
|
|
1723
|
-
return buildPlan(manifest, run);
|
|
2431
|
+
return buildPlan(manifest, records, summaries, run);
|
|
1724
2432
|
},
|
|
1725
2433
|
async write(input, summaries, attribution) {
|
|
1726
2434
|
const entryDir = entryDirFor(cacheDir, input);
|
|
1727
|
-
const previous = await manifests.readAgain(
|
|
1728
|
-
import_node_path5.default.join(entryDir, "manifest.json")
|
|
1729
|
-
);
|
|
2435
|
+
const previous = await manifests.readAgain(import_node_path8.default.join(entryDir, MANIFEST));
|
|
1730
2436
|
manifests.forget();
|
|
1731
2437
|
const known = runs.get(input);
|
|
1732
2438
|
const run = known ?? await runFor(input);
|
|
@@ -1742,58 +2448,119 @@ function createCacheLayer(cacheDir) {
|
|
|
1742
2448
|
)
|
|
1743
2449
|
);
|
|
1744
2450
|
const files = recorded.filter((stamp) => stamp !== null);
|
|
2451
|
+
const encoded = attribution === void 0 ? null : encodeAttribution(
|
|
2452
|
+
attribution,
|
|
2453
|
+
(meta) => writeRecord(entryDir, meta)
|
|
2454
|
+
);
|
|
2455
|
+
makeIgnoredDirectory(cacheDir);
|
|
2456
|
+
const shards = writeShards(entryDir, summaries, encoded);
|
|
1745
2457
|
const manifest = {
|
|
1746
2458
|
schemaVersion: SCHEMA_VERSION,
|
|
1747
2459
|
adapterPacksDigest: input.adapterPacksDigest,
|
|
1748
2460
|
configStamp,
|
|
1749
2461
|
files,
|
|
1750
|
-
summaries,
|
|
1751
|
-
|
|
2462
|
+
summaryCount: summaries.length,
|
|
2463
|
+
shards,
|
|
2464
|
+
...encoded === null ? {} : encoded.stored
|
|
1752
2465
|
};
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
2466
|
+
(0, import_files3.writeDocumentFile)(import_node_path8.default.join(entryDir, MANIFEST), manifest);
|
|
2467
|
+
removeStoredOutside(
|
|
2468
|
+
entryDir,
|
|
2469
|
+
/* @__PURE__ */ new Set([...storedIds(manifest), ...storedIds(previous)])
|
|
1757
2470
|
);
|
|
1758
2471
|
await evictOldEntries(cacheDir, entryDir);
|
|
1759
2472
|
}
|
|
1760
2473
|
};
|
|
1761
2474
|
}
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
2475
|
+
function storedIds(manifest) {
|
|
2476
|
+
return [
|
|
2477
|
+
...(manifest?.shards ?? []).map((shard) => shard.id),
|
|
2478
|
+
...(manifest?.rootMeta ?? []).flatMap(
|
|
2479
|
+
(root) => root.record === void 0 ? [] : [root.record]
|
|
2480
|
+
)
|
|
2481
|
+
];
|
|
2482
|
+
}
|
|
2483
|
+
function writeShards(entryDir, summaries, encoded) {
|
|
2484
|
+
const byFile = /* @__PURE__ */ new Map();
|
|
2485
|
+
summaries.forEach((summary, position) => {
|
|
2486
|
+
const file = summary.location?.file ?? "";
|
|
2487
|
+
const shard = byFile.get(file) ?? {
|
|
2488
|
+
content: { file, units: [] },
|
|
2489
|
+
order: [],
|
|
2490
|
+
owners: []
|
|
2491
|
+
};
|
|
2492
|
+
byFile.set(file, shard);
|
|
2493
|
+
shard.content.units.push(summary);
|
|
2494
|
+
shard.order.push(position);
|
|
2495
|
+
shard.owners.push(encoded?.owners[position] ?? []);
|
|
2496
|
+
});
|
|
2497
|
+
const indexFile = import_node_path8.default.join(entryDir, INDEX);
|
|
2498
|
+
const before = readStoreIndex(indexFile);
|
|
2499
|
+
const known = before === null ? /* @__PURE__ */ new Map() : entriesByShard(before);
|
|
2500
|
+
const sorted = [...byFile].sort(([a], [b]) => a < b ? -1 : 1);
|
|
2501
|
+
const written = sorted.map(([file, { content, order, owners }]) => {
|
|
2502
|
+
const id = writeShard(entryDir, content);
|
|
2503
|
+
return {
|
|
2504
|
+
shard: {
|
|
2505
|
+
file,
|
|
2506
|
+
id,
|
|
2507
|
+
order,
|
|
2508
|
+
...encoded === null ? {} : { owners }
|
|
2509
|
+
},
|
|
2510
|
+
entries: known.get(id) ?? entriesOf(content.units)
|
|
2511
|
+
};
|
|
2512
|
+
});
|
|
2513
|
+
writeStoreIndex(
|
|
2514
|
+
indexFile,
|
|
2515
|
+
indexOf(
|
|
2516
|
+
written.map(({ shard, entries }) => ({
|
|
2517
|
+
file: shard.file,
|
|
2518
|
+
id: shard.id,
|
|
2519
|
+
entries
|
|
2520
|
+
}))
|
|
2521
|
+
)
|
|
2522
|
+
);
|
|
2523
|
+
return written.map(({ shard }) => shard);
|
|
2524
|
+
}
|
|
2525
|
+
function storedSummaries(entryDir, manifest) {
|
|
2526
|
+
const summaries = new Array(
|
|
2527
|
+
manifest.summaryCount
|
|
2528
|
+
);
|
|
2529
|
+
for (const shard of manifest.shards) {
|
|
2530
|
+
const content = readShard(entryDir, shard.id, shard.file);
|
|
2531
|
+
if (content === null || content.units.length !== shard.order.length) {
|
|
2532
|
+
return null;
|
|
1771
2533
|
}
|
|
2534
|
+
shard.order.forEach((position, i) => {
|
|
2535
|
+
summaries[position] = content.units[i];
|
|
2536
|
+
});
|
|
1772
2537
|
}
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
if (before === void 0) {
|
|
1777
|
-
changed.add(p);
|
|
1778
|
-
added.add(p);
|
|
1779
|
-
} else if (!fileStampEquals(before, stamp)) {
|
|
1780
|
-
if (before.contentHash === void 0) {
|
|
1781
|
-
changed.add(p);
|
|
1782
|
-
} else {
|
|
1783
|
-
toVerify.push(p);
|
|
1784
|
-
}
|
|
1785
|
-
} else if (before.verifyHash === true) {
|
|
1786
|
-
toVerify.push(p);
|
|
2538
|
+
for (let position = 0; position < summaries.length; position++) {
|
|
2539
|
+
if (summaries[position] === void 0) {
|
|
2540
|
+
return null;
|
|
1787
2541
|
}
|
|
1788
2542
|
}
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
2543
|
+
return summaries;
|
|
2544
|
+
}
|
|
2545
|
+
function storedRecords(entryDir, manifest) {
|
|
2546
|
+
const records = /* @__PURE__ */ new Map();
|
|
2547
|
+
const roots = manifest.roots ?? [];
|
|
2548
|
+
const readRecord2 = recordReader(entryDir);
|
|
2549
|
+
for (const [i, root] of (manifest.rootMeta ?? []).entries()) {
|
|
2550
|
+
const rootPath = roots[i];
|
|
2551
|
+
if (rootPath === void 0 || root.record === void 0) {
|
|
2552
|
+
continue;
|
|
2553
|
+
}
|
|
2554
|
+
const record = readRecord2(root.record);
|
|
2555
|
+
if (record === null) {
|
|
2556
|
+
return null;
|
|
2557
|
+
}
|
|
2558
|
+
records.set(rootPath, record.meta);
|
|
2559
|
+
}
|
|
2560
|
+
return records;
|
|
2561
|
+
}
|
|
2562
|
+
async function buildPlan(manifest, records, stored, run) {
|
|
2563
|
+
const { changed, added, removed } = await changedSince(manifest, run);
|
|
1797
2564
|
const roots = /* @__PURE__ */ new Map();
|
|
1798
2565
|
const rootNames = manifest.roots ?? [];
|
|
1799
2566
|
const depPaths = manifest.depPaths ?? [];
|
|
@@ -1803,23 +2570,24 @@ async function buildPlan(manifest, run) {
|
|
|
1803
2570
|
});
|
|
1804
2571
|
let rootsDeclined = 0;
|
|
1805
2572
|
rootNames.forEach((rootPath, i) => {
|
|
1806
|
-
const
|
|
1807
|
-
if (
|
|
2573
|
+
const record = manifest.rootMeta?.[i];
|
|
2574
|
+
if (record === void 0) {
|
|
1808
2575
|
return;
|
|
1809
2576
|
}
|
|
1810
|
-
if (!
|
|
2577
|
+
if (!record.cacheable) {
|
|
1811
2578
|
rootsDeclined += 1;
|
|
1812
2579
|
}
|
|
1813
2580
|
roots.set(rootPath, {
|
|
1814
2581
|
path: rootPath,
|
|
1815
|
-
cacheable:
|
|
1816
|
-
deps: pathsOf(
|
|
1817
|
-
claims:
|
|
1818
|
-
meta:
|
|
1819
|
-
packs:
|
|
1820
|
-
...
|
|
2582
|
+
cacheable: record.cacheable,
|
|
2583
|
+
deps: pathsOf(record.deps),
|
|
2584
|
+
claims: record.claims,
|
|
2585
|
+
meta: records.get(rootPath),
|
|
2586
|
+
packs: record.packs,
|
|
2587
|
+
...record.imports === void 0 ? {} : { imports: pathsOf(record.imports) }
|
|
1821
2588
|
});
|
|
1822
2589
|
});
|
|
2590
|
+
const current = new Set(run.files.map((f) => f.stamp.path));
|
|
1823
2591
|
const unchanged = (filePath, deps) => current.has(filePath) && !changed.has(filePath) && !deps.some((d) => changed.has(d) || removed.has(d));
|
|
1824
2592
|
const validRoots = /* @__PURE__ */ new Set();
|
|
1825
2593
|
for (const [rootPath, record] of roots) {
|
|
@@ -1827,14 +2595,14 @@ async function buildPlan(manifest, run) {
|
|
|
1827
2595
|
validRoots.add(rootPath);
|
|
1828
2596
|
}
|
|
1829
2597
|
}
|
|
1830
|
-
const units = (manifest.units ?? []).flatMap((
|
|
1831
|
-
const file = depPaths[
|
|
2598
|
+
const units = (manifest.units ?? []).flatMap((unit) => {
|
|
2599
|
+
const file = depPaths[unit.file];
|
|
1832
2600
|
return file === void 0 ? [] : [
|
|
1833
2601
|
{
|
|
1834
|
-
key:
|
|
2602
|
+
key: unit.key,
|
|
1835
2603
|
file,
|
|
1836
|
-
deps: pathsOf(
|
|
1837
|
-
data:
|
|
2604
|
+
deps: pathsOf(unit.deps),
|
|
2605
|
+
data: unit.data
|
|
1838
2606
|
}
|
|
1839
2607
|
];
|
|
1840
2608
|
});
|
|
@@ -1852,7 +2620,7 @@ async function buildPlan(manifest, run) {
|
|
|
1852
2620
|
}
|
|
1853
2621
|
}
|
|
1854
2622
|
}
|
|
1855
|
-
const
|
|
2623
|
+
const ownerPaths = ownersInRunOrder(manifest);
|
|
1856
2624
|
return {
|
|
1857
2625
|
changed,
|
|
1858
2626
|
removed,
|
|
@@ -1864,36 +2632,81 @@ async function buildPlan(manifest, run) {
|
|
|
1864
2632
|
reuse(valid) {
|
|
1865
2633
|
const summaries = [];
|
|
1866
2634
|
const reusedOwners = [];
|
|
1867
|
-
|
|
1868
|
-
const
|
|
1869
|
-
|
|
1870
|
-
return p === void 0 ? [] : [p];
|
|
1871
|
-
});
|
|
1872
|
-
if (ownerPaths.some((p) => valid.has(p))) {
|
|
2635
|
+
stored.forEach((summary, i) => {
|
|
2636
|
+
const owners = ownerPaths[i] ?? [];
|
|
2637
|
+
if (owners.some((p) => valid.has(p))) {
|
|
1873
2638
|
summaries.push(summary);
|
|
1874
|
-
reusedOwners.push(
|
|
2639
|
+
reusedOwners.push(owners.filter((p) => valid.has(p)));
|
|
1875
2640
|
}
|
|
1876
2641
|
});
|
|
1877
2642
|
return { summaries, owners: reusedOwners };
|
|
1878
2643
|
},
|
|
1879
2644
|
allSummaries() {
|
|
1880
|
-
return
|
|
2645
|
+
return stored;
|
|
1881
2646
|
},
|
|
1882
2647
|
attribution() {
|
|
1883
2648
|
return {
|
|
1884
2649
|
roots: [...roots.values()],
|
|
1885
|
-
owners:
|
|
1886
|
-
(ownerIds) => ownerIds.flatMap((o) => {
|
|
1887
|
-
const p = rootNames[o];
|
|
1888
|
-
return p === void 0 ? [] : [p];
|
|
1889
|
-
})
|
|
1890
|
-
),
|
|
2650
|
+
owners: ownerPaths,
|
|
1891
2651
|
units
|
|
1892
2652
|
};
|
|
1893
2653
|
}
|
|
1894
2654
|
};
|
|
1895
2655
|
}
|
|
1896
|
-
function
|
|
2656
|
+
function ownersInRunOrder(manifest) {
|
|
2657
|
+
const rootNames = manifest.roots ?? [];
|
|
2658
|
+
const owners = Array.from(
|
|
2659
|
+
{ length: manifest.summaryCount },
|
|
2660
|
+
() => []
|
|
2661
|
+
);
|
|
2662
|
+
for (const shard of manifest.shards ?? []) {
|
|
2663
|
+
shard.order.forEach((position, i) => {
|
|
2664
|
+
owners[position] = (shard.owners?.[i] ?? []).flatMap((o) => {
|
|
2665
|
+
const p = rootNames[o];
|
|
2666
|
+
return p === void 0 ? [] : [p];
|
|
2667
|
+
});
|
|
2668
|
+
});
|
|
2669
|
+
}
|
|
2670
|
+
return owners;
|
|
2671
|
+
}
|
|
2672
|
+
async function changedSince(manifest, run) {
|
|
2673
|
+
const stored = new Map(manifest.files.map((f) => [f.path, f]));
|
|
2674
|
+
const current = new Map(run.files.map((f) => [f.stamp.path, f.stamp]));
|
|
2675
|
+
const changed = /* @__PURE__ */ new Set();
|
|
2676
|
+
const added = /* @__PURE__ */ new Set();
|
|
2677
|
+
const removed = /* @__PURE__ */ new Set();
|
|
2678
|
+
for (const p of stored.keys()) {
|
|
2679
|
+
if (!current.has(p)) {
|
|
2680
|
+
removed.add(p);
|
|
2681
|
+
}
|
|
2682
|
+
}
|
|
2683
|
+
const toVerify = [];
|
|
2684
|
+
for (const [p, stamp] of current) {
|
|
2685
|
+
const before = stored.get(p);
|
|
2686
|
+
if (before === void 0) {
|
|
2687
|
+
changed.add(p);
|
|
2688
|
+
added.add(p);
|
|
2689
|
+
} else if (!fileStampEquals(before, stamp)) {
|
|
2690
|
+
if (before.contentHash === void 0) {
|
|
2691
|
+
changed.add(p);
|
|
2692
|
+
} else {
|
|
2693
|
+
toVerify.push(p);
|
|
2694
|
+
}
|
|
2695
|
+
} else if (before.verifyHash === true) {
|
|
2696
|
+
toVerify.push(p);
|
|
2697
|
+
}
|
|
2698
|
+
}
|
|
2699
|
+
await Promise.all(
|
|
2700
|
+
toVerify.map(async (p) => {
|
|
2701
|
+
const hash = await hashOf(run, p);
|
|
2702
|
+
if (hash === null || hash !== stored.get(p)?.contentHash) {
|
|
2703
|
+
changed.add(p);
|
|
2704
|
+
}
|
|
2705
|
+
})
|
|
2706
|
+
);
|
|
2707
|
+
return { changed, added, removed };
|
|
2708
|
+
}
|
|
2709
|
+
function encodeAttribution(attribution, storeRecord) {
|
|
1897
2710
|
const roots = attribution.roots.map((r) => r.path);
|
|
1898
2711
|
const rootIndex = new Map(roots.map((p, i) => [p, i]));
|
|
1899
2712
|
const depIndex = /* @__PURE__ */ new Map();
|
|
@@ -1909,10 +2722,10 @@ function encodeAttribution(attribution) {
|
|
|
1909
2722
|
return id;
|
|
1910
2723
|
};
|
|
1911
2724
|
const rootMeta = attribution.roots.map((r) => ({
|
|
2725
|
+
...r.meta === void 0 ? {} : { record: storeRecord(r.meta) },
|
|
1912
2726
|
cacheable: r.cacheable,
|
|
1913
2727
|
deps: r.deps.map(depIdOf),
|
|
1914
2728
|
claims: r.claims,
|
|
1915
|
-
meta: r.meta,
|
|
1916
2729
|
packs: r.packs,
|
|
1917
2730
|
...r.imports === void 0 ? {} : { imports: r.imports.map(depIdOf) }
|
|
1918
2731
|
}));
|
|
@@ -1929,11 +2742,13 @@ function encodeAttribution(attribution) {
|
|
|
1929
2742
|
data: unit.data
|
|
1930
2743
|
}));
|
|
1931
2744
|
return {
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
2745
|
+
stored: {
|
|
2746
|
+
roots,
|
|
2747
|
+
rootMeta,
|
|
2748
|
+
depPaths,
|
|
2749
|
+
...units === void 0 ? {} : { units }
|
|
2750
|
+
},
|
|
2751
|
+
owners
|
|
1937
2752
|
};
|
|
1938
2753
|
}
|
|
1939
2754
|
async function describeAbsentEntry(cacheDir) {
|
|
@@ -1950,8 +2765,8 @@ function entryDirFor(cacheDir, input) {
|
|
|
1950
2765
|
input.adapterPacksDigest,
|
|
1951
2766
|
input.configPath ?? ""
|
|
1952
2767
|
].join(" ");
|
|
1953
|
-
const name = (0,
|
|
1954
|
-
return
|
|
2768
|
+
const name = (0, import_node_crypto5.createHash)("sha256").update(key).digest("hex").slice(0, 16);
|
|
2769
|
+
return import_node_path8.default.join(cacheDir, `${ENTRY_PREFIX}${name}`);
|
|
1955
2770
|
}
|
|
1956
2771
|
function isEntryDir(name) {
|
|
1957
2772
|
return ENTRY_DIR_NAME.test(name);
|
|
@@ -1965,11 +2780,11 @@ async function markUsed(entryDir) {
|
|
|
1965
2780
|
}
|
|
1966
2781
|
async function evictOldEntries(cacheDir, keepDir) {
|
|
1967
2782
|
try {
|
|
1968
|
-
await import_promises2.default.rm(
|
|
2783
|
+
await import_promises2.default.rm(import_node_path8.default.join(cacheDir, "manifest.json"), { force: true });
|
|
1969
2784
|
const entries = await import_promises2.default.readdir(cacheDir, { withFileTypes: true });
|
|
1970
2785
|
const dirs = await Promise.all(
|
|
1971
2786
|
entries.filter((e) => e.isDirectory() && isEntryDir(e.name)).map(async (e) => {
|
|
1972
|
-
const dir =
|
|
2787
|
+
const dir = import_node_path8.default.join(cacheDir, e.name);
|
|
1973
2788
|
const stat = await import_promises2.default.stat(dir);
|
|
1974
2789
|
return { dir, mtimeMs: stat.mtimeMs };
|
|
1975
2790
|
})
|
|
@@ -1991,7 +2806,7 @@ var ManifestReads = class {
|
|
|
1991
2806
|
last = null;
|
|
1992
2807
|
async readAtRunStart(manifestPath) {
|
|
1993
2808
|
const stamp = await manifestStamp(manifestPath);
|
|
1994
|
-
const manifest = await
|
|
2809
|
+
const manifest = await readManifest2(manifestPath);
|
|
1995
2810
|
this.last = { path: manifestPath, stamp, manifest };
|
|
1996
2811
|
return manifest;
|
|
1997
2812
|
}
|
|
@@ -2014,17 +2829,54 @@ async function manifestStamp(manifestPath) {
|
|
|
2014
2829
|
return null;
|
|
2015
2830
|
}
|
|
2016
2831
|
}
|
|
2017
|
-
async function
|
|
2832
|
+
async function readManifest2(manifestPath) {
|
|
2018
2833
|
try {
|
|
2019
|
-
const
|
|
2020
|
-
return
|
|
2834
|
+
const manifest = (0, import_files3.readJsonFile)(manifestPath);
|
|
2835
|
+
return Array.isArray(manifest.shards) ? manifest : null;
|
|
2021
2836
|
} catch {
|
|
2022
2837
|
return null;
|
|
2023
2838
|
}
|
|
2024
2839
|
}
|
|
2025
2840
|
|
|
2841
|
+
// src/cacheLocation.ts
|
|
2842
|
+
var import_node_crypto6 = require("crypto");
|
|
2843
|
+
var import_node_fs6 = __toESM(require("fs"), 1);
|
|
2844
|
+
var import_node_path9 = __toESM(require("path"), 1);
|
|
2845
|
+
var CACHE_DIR_ENV = "SUSS_CACHE_DIR";
|
|
2846
|
+
function chosenCacheRoot() {
|
|
2847
|
+
const chosen = process.env[CACHE_DIR_ENV];
|
|
2848
|
+
if (chosen === void 0 || chosen === "") {
|
|
2849
|
+
return null;
|
|
2850
|
+
}
|
|
2851
|
+
return import_node_path9.default.resolve(chosen);
|
|
2852
|
+
}
|
|
2853
|
+
function realPathOrSelf(dir) {
|
|
2854
|
+
try {
|
|
2855
|
+
return import_node_fs6.default.realpathSync(dir);
|
|
2856
|
+
} catch {
|
|
2857
|
+
return dir;
|
|
2858
|
+
}
|
|
2859
|
+
}
|
|
2860
|
+
function projectKey(projectDir) {
|
|
2861
|
+
return (0, import_node_crypto6.createHash)("sha256").update(realPathOrSelf(import_node_path9.default.resolve(projectDir))).digest("hex").slice(0, 16);
|
|
2862
|
+
}
|
|
2863
|
+
function extractionCacheDirFor(projectDir) {
|
|
2864
|
+
const root = chosenCacheRoot();
|
|
2865
|
+
if (root === null) {
|
|
2866
|
+
return import_node_path9.default.join(projectDir, ".suss", "cache");
|
|
2867
|
+
}
|
|
2868
|
+
return import_node_path9.default.join(root, "cache", projectKey(projectDir));
|
|
2869
|
+
}
|
|
2870
|
+
function liveRecordFor(projectDir) {
|
|
2871
|
+
const root = chosenCacheRoot();
|
|
2872
|
+
if (root === null) {
|
|
2873
|
+
return import_node_path9.default.join(projectDir, ".suss", "live", "server.json");
|
|
2874
|
+
}
|
|
2875
|
+
return import_node_path9.default.join(root, "live", `${projectKey(projectDir)}.json`);
|
|
2876
|
+
}
|
|
2877
|
+
|
|
2026
2878
|
// src/extractionReport.ts
|
|
2027
|
-
var
|
|
2879
|
+
var import_behavioral_ir7 = require("@suss/behavioral-ir");
|
|
2028
2880
|
var emptyTally = () => ({
|
|
2029
2881
|
candidateFiles: 0,
|
|
2030
2882
|
unitsDiscovered: 0,
|
|
@@ -2074,7 +2926,7 @@ function summaryCountsByPack(summaries) {
|
|
|
2074
2926
|
}
|
|
2075
2927
|
const entry = counts.get(recognition) ?? emptyCounts();
|
|
2076
2928
|
entry.bound += 1;
|
|
2077
|
-
if (
|
|
2929
|
+
if (import_behavioral_ir7.BOUNDARY_ROLE[summary.kind] === "provider") {
|
|
2078
2930
|
entry.providers += 1;
|
|
2079
2931
|
}
|
|
2080
2932
|
if (summary.transitions.length > 0) {
|
|
@@ -2299,6 +3151,17 @@ function undocumentedDeclarations(gradients) {
|
|
|
2299
3151
|
detail: gradient.withoutExample.join(", ")
|
|
2300
3152
|
}));
|
|
2301
3153
|
}
|
|
3154
|
+
function packConfigCheck(needs) {
|
|
3155
|
+
return {
|
|
3156
|
+
name: "every pack that needs an option was given it",
|
|
3157
|
+
code: "no-config",
|
|
3158
|
+
audience: "run",
|
|
3159
|
+
violations: needs.map((need) => ({
|
|
3160
|
+
label: need.pack,
|
|
3161
|
+
detail: `reads nothing until ${need.option} is set, for example ${need.example}. Write that to a JSON file and pass -f ${need.pack}=<config.json>.`
|
|
3162
|
+
}))
|
|
3163
|
+
};
|
|
3164
|
+
}
|
|
2302
3165
|
function evaluatePackHealth(report) {
|
|
2303
3166
|
const gradients = packGradients(report);
|
|
2304
3167
|
return [
|
|
@@ -2451,7 +3314,7 @@ function makeTransitionId(functionName, branch) {
|
|
|
2451
3314
|
const { terminal } = branch;
|
|
2452
3315
|
const statusKey = terminal.statusCode === null ? "none" : terminal.statusCode.type === "literal" ? String(terminal.statusCode.value) : `dyn:${terminal.statusCode.sourceText}`;
|
|
2453
3316
|
const conditionSig = branch.conditions.map((c) => `${c.polarity}:${c.sourceText}`).join(";");
|
|
2454
|
-
const conditionHash = (0,
|
|
3317
|
+
const conditionHash = (0, import_node_crypto7.createHash)("sha1").update(conditionSig).digest("hex").slice(0, 7);
|
|
2455
3318
|
return `${functionName}:${terminal.kind}:${statusKey}:${conditionHash}`;
|
|
2456
3319
|
}
|
|
2457
3320
|
function collapseReading(table, reading) {
|
|
@@ -2510,6 +3373,7 @@ function unreadSentences(raw) {
|
|
|
2510
3373
|
...raw.branches.flatMap(readingsOfBranch)
|
|
2511
3374
|
];
|
|
2512
3375
|
return [
|
|
3376
|
+
...raw.readFailure !== void 0 ? [raw.readFailure] : [],
|
|
2513
3377
|
...raw.unreadBinding !== void 0 ? [raw.unreadBinding] : [],
|
|
2514
3378
|
...handedOver.map(unreadReasonOf).filter((reason) => reason !== null)
|
|
2515
3379
|
];
|
|
@@ -2519,17 +3383,17 @@ function effectsOfBranch(branch) {
|
|
|
2519
3383
|
...branch.effects.map(effectToIR),
|
|
2520
3384
|
...branch.extraEffects ?? []
|
|
2521
3385
|
];
|
|
2522
|
-
return (0,
|
|
3386
|
+
return (0, import_behavioral_ir8.foldRepeatedEffects)(effects.map(withNormalizedCallee));
|
|
2523
3387
|
}
|
|
2524
3388
|
function provenanceOf(raw, effects) {
|
|
2525
3389
|
if (raw.length === 0) {
|
|
2526
3390
|
return [];
|
|
2527
3391
|
}
|
|
2528
|
-
const positionOf = new Map(effects.map((one, at) => [(0,
|
|
3392
|
+
const positionOf = new Map(effects.map((one, at) => [(0, import_behavioral_ir8.effectKey)(one), at]));
|
|
2529
3393
|
const bySlot = /* @__PURE__ */ new Map();
|
|
2530
3394
|
const said = /* @__PURE__ */ new Map();
|
|
2531
3395
|
for (const one of raw) {
|
|
2532
|
-
const effect = positionOf.get((0,
|
|
3396
|
+
const effect = positionOf.get((0, import_behavioral_ir8.effectKey)(withNormalizedCallee(one.effect)));
|
|
2533
3397
|
if (effect === void 0) {
|
|
2534
3398
|
continue;
|
|
2535
3399
|
}
|
|
@@ -2561,7 +3425,7 @@ function withNormalizedCallee(effect) {
|
|
|
2561
3425
|
if (effect.callee === void 0) {
|
|
2562
3426
|
return effect;
|
|
2563
3427
|
}
|
|
2564
|
-
return { ...effect, callee: (0,
|
|
3428
|
+
return { ...effect, callee: (0, import_behavioral_ir8.normalizeCalleeText)(effect.callee) };
|
|
2565
3429
|
}
|
|
2566
3430
|
function assembleSummary(raw, options = DEFAULT_OPTIONS) {
|
|
2567
3431
|
const transitions = raw.branches.map((rawBranch) => {
|
|
@@ -2626,28 +3490,28 @@ function buildMetadata(raw) {
|
|
|
2626
3490
|
let metadata = {};
|
|
2627
3491
|
const http = buildHttpMetadataValue(raw);
|
|
2628
3492
|
if (http !== null) {
|
|
2629
|
-
metadata = (0,
|
|
3493
|
+
metadata = (0, import_behavioral_ir8.withHttpMetadata)(metadata, http);
|
|
2630
3494
|
}
|
|
2631
3495
|
const graphql = buildGraphqlMetadataValue(raw);
|
|
2632
3496
|
if (graphql !== null) {
|
|
2633
|
-
metadata = (0,
|
|
3497
|
+
metadata = (0, import_behavioral_ir8.withGraphqlMetadata)(metadata, graphql);
|
|
2634
3498
|
}
|
|
2635
3499
|
if (raw.sourceDocumentLabel !== void 0) {
|
|
2636
|
-
metadata = (0,
|
|
3500
|
+
metadata = (0, import_behavioral_ir8.withSourceDocumentMetadata)(metadata, {
|
|
2637
3501
|
label: raw.sourceDocumentLabel
|
|
2638
3502
|
});
|
|
2639
3503
|
}
|
|
2640
3504
|
if (raw.mount !== void 0) {
|
|
2641
|
-
metadata = (0,
|
|
3505
|
+
metadata = (0, import_behavioral_ir8.withMountMetadata)(metadata, raw.mount);
|
|
2642
3506
|
}
|
|
2643
3507
|
if (raw.wrappers !== void 0 && raw.wrappers.length > 0) {
|
|
2644
|
-
metadata = (0,
|
|
3508
|
+
metadata = (0, import_behavioral_ir8.withWrapperMetadata)(metadata, { applied: raw.wrappers });
|
|
2645
3509
|
}
|
|
2646
3510
|
if (raw.requestSpelling !== void 0) {
|
|
2647
|
-
metadata = (0,
|
|
3511
|
+
metadata = (0, import_behavioral_ir8.withRequestSpellingMetadata)(metadata, raw.requestSpelling);
|
|
2648
3512
|
}
|
|
2649
3513
|
if (raw.test !== void 0) {
|
|
2650
|
-
metadata = (0,
|
|
3514
|
+
metadata = (0, import_behavioral_ir8.withTestMetadata)(metadata, raw.test);
|
|
2651
3515
|
}
|
|
2652
3516
|
return Object.keys(metadata).length > 0 ? metadata : null;
|
|
2653
3517
|
}
|
|
@@ -2672,6 +3536,12 @@ function buildHttpMetadataValue(raw) {
|
|
|
2672
3536
|
if (raw.failureDelivery !== void 0) {
|
|
2673
3537
|
http.failureDelivery = raw.failureDelivery;
|
|
2674
3538
|
}
|
|
3539
|
+
if (raw.redirectDelivery !== void 0) {
|
|
3540
|
+
http.redirectDelivery = raw.redirectDelivery;
|
|
3541
|
+
}
|
|
3542
|
+
if (raw.declaredStatuses !== void 0 && raw.declaredStatuses.length > 0) {
|
|
3543
|
+
http.declaredStatuses = raw.declaredStatuses;
|
|
3544
|
+
}
|
|
2675
3545
|
return Object.keys(http).length > 0 ? http : null;
|
|
2676
3546
|
}
|
|
2677
3547
|
function buildGraphqlMetadataValue(raw) {
|
|
@@ -2700,7 +3570,7 @@ function answersWithHttpResponses(raw) {
|
|
|
2700
3570
|
if (raw.boundaryBinding === null || raw.boundaryBinding === void 0) {
|
|
2701
3571
|
return true;
|
|
2702
3572
|
}
|
|
2703
|
-
return (0,
|
|
3573
|
+
return (0, import_behavioral_ir8.exchangesHttpResponses)(raw.boundaryBinding);
|
|
2704
3574
|
}
|
|
2705
3575
|
function detectGaps(raw, transitions, options) {
|
|
2706
3576
|
if (options.gapHandling === "silent") {
|
|
@@ -2739,13 +3609,16 @@ function detectGaps(raw, transitions, options) {
|
|
|
2739
3609
|
return gaps;
|
|
2740
3610
|
}
|
|
2741
3611
|
function bodyWentUnread(raw) {
|
|
3612
|
+
if (raw.readFailure !== void 0) {
|
|
3613
|
+
return true;
|
|
3614
|
+
}
|
|
2742
3615
|
if (raw.bodyContent === "absent" || raw.bodyContent === "elsewhere") {
|
|
2743
3616
|
return true;
|
|
2744
3617
|
}
|
|
2745
3618
|
return raw.bodyContent === "statements" && raw.branches.length === 0;
|
|
2746
3619
|
}
|
|
2747
3620
|
function describeUnreadBody(raw) {
|
|
2748
|
-
if (!bodyWentUnread(raw)) {
|
|
3621
|
+
if (!bodyWentUnread(raw) || raw.readFailure !== void 0) {
|
|
2749
3622
|
return null;
|
|
2750
3623
|
}
|
|
2751
3624
|
if (raw.bodyContent === "absent") {
|
|
@@ -2817,10 +3690,16 @@ var terminalConverters = {
|
|
|
2817
3690
|
headers: {}
|
|
2818
3691
|
};
|
|
2819
3692
|
}
|
|
3693
|
+
const ancestry = t.exceptionAncestry;
|
|
2820
3694
|
return {
|
|
2821
3695
|
type: "throw",
|
|
2822
3696
|
exceptionType: t.exceptionType,
|
|
2823
|
-
message: t.message
|
|
3697
|
+
message: t.message,
|
|
3698
|
+
...ancestry === void 0 ? {} : {
|
|
3699
|
+
exceptionAncestors: ancestry.ancestors,
|
|
3700
|
+
...ancestry.incomplete ? { ancestryIncomplete: true } : {}
|
|
3701
|
+
},
|
|
3702
|
+
...t.statusWhenUncaught === void 0 ? {} : { statusWhenUncaught: t.statusWhenUncaught }
|
|
2824
3703
|
};
|
|
2825
3704
|
},
|
|
2826
3705
|
render: (t) => ({
|
|
@@ -2890,11 +3769,13 @@ function paramToInput(param) {
|
|
|
2890
3769
|
}
|
|
2891
3770
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2892
3771
|
0 && (module.exports = {
|
|
3772
|
+
CACHE_DIR_ENV,
|
|
2893
3773
|
EnclosingNodes,
|
|
2894
3774
|
IdMap,
|
|
2895
3775
|
IdSet,
|
|
2896
3776
|
KeptParses,
|
|
2897
3777
|
MAX_ENTRIES,
|
|
3778
|
+
MAX_HELPER_PATHS,
|
|
2898
3779
|
MAX_PATHS,
|
|
2899
3780
|
MODULE_SURFACE_RECOGNITION,
|
|
2900
3781
|
PathBudgetExceeded,
|
|
@@ -2906,6 +3787,7 @@ function paramToInput(param) {
|
|
|
2906
3787
|
assembleSummary,
|
|
2907
3788
|
assessConfidence,
|
|
2908
3789
|
buildUngatedExtractionReport,
|
|
3790
|
+
chosenCacheRoot,
|
|
2909
3791
|
commonDirectoryOf,
|
|
2910
3792
|
composeWrappers,
|
|
2911
3793
|
computeContentHash,
|
|
@@ -2913,6 +3795,7 @@ function paramToInput(param) {
|
|
|
2913
3795
|
configuredCallOption,
|
|
2914
3796
|
createAdapterStamp,
|
|
2915
3797
|
createCacheLayer,
|
|
3798
|
+
createCodeHasher,
|
|
2916
3799
|
createPackTallies,
|
|
2917
3800
|
createTimer,
|
|
2918
3801
|
detectGaps,
|
|
@@ -2921,24 +3804,33 @@ function paramToInput(param) {
|
|
|
2921
3804
|
enumerateOrDegrade,
|
|
2922
3805
|
enumerateStructuredPaths,
|
|
2923
3806
|
evaluatePackHealth,
|
|
3807
|
+
extractionCacheDirFor,
|
|
2924
3808
|
extractionConfigStamp,
|
|
2925
3809
|
firstWrittenReading,
|
|
2926
3810
|
formatPackHealth,
|
|
2927
3811
|
guardsHoldOn,
|
|
3812
|
+
helperPathsOnVariables,
|
|
2928
3813
|
httpRouteDiscovery,
|
|
2929
3814
|
isListedTestFile,
|
|
3815
|
+
liveRecordFor,
|
|
3816
|
+
makeIgnoredDirectory,
|
|
2930
3817
|
makeTransitionId,
|
|
2931
3818
|
mapReading,
|
|
2932
3819
|
markReturnsAsExitCode,
|
|
2933
3820
|
matchesTestFileName,
|
|
3821
|
+
mergeReadShapes,
|
|
2934
3822
|
moduleInitStructure,
|
|
2935
3823
|
moduleOfFile,
|
|
2936
3824
|
noopTimer,
|
|
3825
|
+
ownersWhereWritten,
|
|
3826
|
+
packConfigCheck,
|
|
2937
3827
|
packGradients,
|
|
2938
3828
|
paramToInput,
|
|
3829
|
+
processCodeHasher,
|
|
2939
3830
|
projectFileStamp,
|
|
2940
3831
|
rawConditionToPredicate,
|
|
2941
3832
|
recordPackFailure,
|
|
3833
|
+
redirectDeliveryWhenSet,
|
|
2942
3834
|
registrationHelperDiscovery,
|
|
2943
3835
|
routeHelperIndex,
|
|
2944
3836
|
runDigest,
|
|
@@ -2947,6 +3839,7 @@ function paramToInput(param) {
|
|
|
2947
3839
|
settleModules,
|
|
2948
3840
|
sharedGatingConditions,
|
|
2949
3841
|
sourceRefsOf,
|
|
3842
|
+
splitAtHandOffs,
|
|
2950
3843
|
stampMayMissAWrite,
|
|
2951
3844
|
stampModuleImports,
|
|
2952
3845
|
stampModules,
|
|
@@ -2954,6 +3847,7 @@ function paramToInput(param) {
|
|
|
2954
3847
|
summaryCountsByPack,
|
|
2955
3848
|
tallyUnit,
|
|
2956
3849
|
terminalToOutput,
|
|
3850
|
+
throughHelper,
|
|
2957
3851
|
unreadableReading,
|
|
2958
3852
|
unwrapJsonStringify,
|
|
2959
3853
|
valueToReadFurtherFrom,
|