@suss/extractor 0.25.0 → 0.26.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 +66 -43
- package/dist/index.d.cts +11 -1
- package/dist/index.d.ts +11 -1
- package/dist/index.js +65 -43
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -43,6 +43,7 @@ __export(index_exports, {
|
|
|
43
43
|
assembleSummary: () => assembleSummary,
|
|
44
44
|
assessConfidence: () => assessConfidence,
|
|
45
45
|
buildUngatedExtractionReport: () => buildUngatedExtractionReport,
|
|
46
|
+
commonDirectoryOf: () => commonDirectoryOf,
|
|
46
47
|
composeWrappers: () => composeWrappers,
|
|
47
48
|
computeContentHash: () => computeContentHash,
|
|
48
49
|
computeDistHashFrom: () => computeDistHashFrom,
|
|
@@ -295,8 +296,8 @@ var catchEntryCond = () => fixedCond(
|
|
|
295
296
|
"positive",
|
|
296
297
|
"catchBlock"
|
|
297
298
|
);
|
|
298
|
-
function classify(
|
|
299
|
-
return
|
|
299
|
+
function classify(path4, home, isAncestorOrSelf) {
|
|
300
|
+
return path4.map((cond) => {
|
|
300
301
|
if (cond.branchStmt === null) {
|
|
301
302
|
return cond.info;
|
|
302
303
|
}
|
|
@@ -361,9 +362,9 @@ function chargeBudget(state) {
|
|
|
361
362
|
);
|
|
362
363
|
}
|
|
363
364
|
}
|
|
364
|
-
function recordTerminal(ctx, terminal, home,
|
|
365
|
+
function recordTerminal(ctx, terminal, home, path4) {
|
|
365
366
|
chargeBudget(ctx.state);
|
|
366
|
-
const info = classify(
|
|
367
|
+
const info = classify(path4, home, ctx.isAncestorOrSelf);
|
|
367
368
|
const existing = ctx.state.byTerminal.get(terminal) ?? [];
|
|
368
369
|
existing.push(info);
|
|
369
370
|
ctx.state.byTerminal.set(terminal, existing);
|
|
@@ -374,15 +375,15 @@ function containsTerminal(ctx, stmt) {
|
|
|
374
375
|
}
|
|
375
376
|
return childrenOf(stmt).some((child) => containsTerminal(ctx, child));
|
|
376
377
|
}
|
|
377
|
-
function stepIf(stmt,
|
|
378
|
+
function stepIf(stmt, path4, ctx) {
|
|
378
379
|
const thenExit = exitKindOfList(stmt.thenBody);
|
|
379
380
|
const elseExit = stmt.elseBody === null ? null : exitKindOfList(stmt.elseBody);
|
|
380
381
|
const thenPath = [
|
|
381
|
-
...
|
|
382
|
+
...path4,
|
|
382
383
|
branchCond(stmt, stmt.condition, "positive", elseExit)
|
|
383
384
|
];
|
|
384
385
|
const elsePath = [
|
|
385
|
-
...
|
|
386
|
+
...path4,
|
|
386
387
|
branchCond(
|
|
387
388
|
stmt,
|
|
388
389
|
stmt.condition,
|
|
@@ -399,7 +400,7 @@ function stepIf(stmt, path3, ctx) {
|
|
|
399
400
|
}
|
|
400
401
|
return out;
|
|
401
402
|
}
|
|
402
|
-
function stepSwitch(stmt,
|
|
403
|
+
function stepSwitch(stmt, path4, ctx) {
|
|
403
404
|
const out = [];
|
|
404
405
|
const negations = [];
|
|
405
406
|
let defaultRanBody = false;
|
|
@@ -409,7 +410,7 @@ function stepSwitch(stmt, path3, ctx) {
|
|
|
409
410
|
if (hasStrayBreak(group.body)) {
|
|
410
411
|
throw new UnmodeledFlow("non-trailing break in switch clause");
|
|
411
412
|
}
|
|
412
|
-
const groupPath = group.condition === null ? [...
|
|
413
|
+
const groupPath = group.condition === null ? [...path4, ...negations] : [...path4, fixedCond(group.condition, "positive", "explicit")];
|
|
413
414
|
const conts = enumerate(ctx, group.body, groupPath);
|
|
414
415
|
if (conts.length > 0) {
|
|
415
416
|
if (!group.hasTrailingBreak && !fallthroughSafe) {
|
|
@@ -426,24 +427,24 @@ function stepSwitch(stmt, path3, ctx) {
|
|
|
426
427
|
}
|
|
427
428
|
}
|
|
428
429
|
if (!defaultRanBody) {
|
|
429
|
-
out.push([...
|
|
430
|
+
out.push([...path4, ...negations]);
|
|
430
431
|
}
|
|
431
432
|
return out;
|
|
432
433
|
}
|
|
433
|
-
function stepLoop(stmt,
|
|
434
|
+
function stepLoop(stmt, path4, ctx) {
|
|
434
435
|
const bodyExit = exitKindOfList(stmt.body);
|
|
435
436
|
if (containsTerminal(ctx, stmt)) {
|
|
436
437
|
enumerate(ctx, stmt.body, [
|
|
437
|
-
...
|
|
438
|
+
...path4,
|
|
438
439
|
loopIterationCond(stmt.condition.sourceText)
|
|
439
440
|
]);
|
|
440
441
|
}
|
|
441
442
|
if (bodyExit !== null) {
|
|
442
|
-
return [[...
|
|
443
|
+
return [[...path4, loopCompletedCond(stmt.condition.sourceText, bodyExit)]];
|
|
443
444
|
}
|
|
444
|
-
return [
|
|
445
|
+
return [path4];
|
|
445
446
|
}
|
|
446
|
-
function stepTry(stmt,
|
|
447
|
+
function stepTry(stmt, path4, ctx) {
|
|
447
448
|
if (stmt.finallyBody !== null) {
|
|
448
449
|
const finallyHasTerminal = stmt.finallyBody.some(
|
|
449
450
|
(s) => containsTerminal(ctx, s)
|
|
@@ -453,22 +454,22 @@ function stepTry(stmt, path3, ctx) {
|
|
|
453
454
|
}
|
|
454
455
|
}
|
|
455
456
|
const out = [];
|
|
456
|
-
out.push(...enumerate(ctx, stmt.tryBody,
|
|
457
|
+
out.push(...enumerate(ctx, stmt.tryBody, path4));
|
|
457
458
|
if (stmt.catchBody !== null) {
|
|
458
|
-
const catchPath = [...
|
|
459
|
+
const catchPath = [...path4, catchEntryCond()];
|
|
459
460
|
out.push(...enumerate(ctx, stmt.catchBody, catchPath));
|
|
460
461
|
}
|
|
461
462
|
return out;
|
|
462
463
|
}
|
|
463
|
-
function stepExit(stmt,
|
|
464
|
+
function stepExit(stmt, path4, ctx) {
|
|
464
465
|
const collector = ctx.state.callbackExits[ctx.state.callbackExits.length - 1];
|
|
465
466
|
if (collector !== void 0 && (stmt.exit === "return" || stmt.exit === "throw")) {
|
|
466
|
-
collector.push(
|
|
467
|
+
collector.push(path4);
|
|
467
468
|
}
|
|
468
469
|
return [];
|
|
469
470
|
}
|
|
470
|
-
function stepOpaque(_stmt,
|
|
471
|
-
return [
|
|
471
|
+
function stepOpaque(_stmt, path4, _ctx) {
|
|
472
|
+
return [path4];
|
|
472
473
|
}
|
|
473
474
|
var stepHandlers = {
|
|
474
475
|
if: stepIf,
|
|
@@ -478,20 +479,20 @@ var stepHandlers = {
|
|
|
478
479
|
exit: stepExit,
|
|
479
480
|
opaque: stepOpaque
|
|
480
481
|
};
|
|
481
|
-
function stepCallback(ctx, body,
|
|
482
|
+
function stepCallback(ctx, body, path4) {
|
|
482
483
|
const exits = [];
|
|
483
484
|
ctx.state.callbackExits.push(exits);
|
|
484
485
|
let fellThrough;
|
|
485
486
|
try {
|
|
486
|
-
fellThrough = enumerate(ctx, body,
|
|
487
|
+
fellThrough = enumerate(ctx, body, path4);
|
|
487
488
|
} finally {
|
|
488
489
|
ctx.state.callbackExits.pop();
|
|
489
490
|
}
|
|
490
491
|
const out = [...fellThrough, ...exits];
|
|
491
|
-
return out.length === 0 ? [
|
|
492
|
+
return out.length === 0 ? [path4] : out;
|
|
492
493
|
}
|
|
493
|
-
function stepStatement(ctx, stmt,
|
|
494
|
-
let paths = [
|
|
494
|
+
function stepStatement(ctx, stmt, path4) {
|
|
495
|
+
let paths = [path4];
|
|
495
496
|
for (const body of stmt.callbacks ?? []) {
|
|
496
497
|
paths = paths.flatMap((each) => stepCallback(ctx, body, each));
|
|
497
498
|
}
|
|
@@ -572,8 +573,8 @@ function enumerate(ctx, stmts, prefix) {
|
|
|
572
573
|
let frontiers = [[...prefix]];
|
|
573
574
|
for (const stmt of stmts) {
|
|
574
575
|
const nextFrontiers = [];
|
|
575
|
-
for (const
|
|
576
|
-
nextFrontiers.push(...stepStatement(ctx, stmt,
|
|
576
|
+
for (const path4 of mergeRejoined(frontiers)) {
|
|
577
|
+
nextFrontiers.push(...stepStatement(ctx, stmt, path4));
|
|
577
578
|
}
|
|
578
579
|
frontiers = nextFrontiers;
|
|
579
580
|
if (frontiers.length > MAX_PATHS) {
|
|
@@ -624,9 +625,9 @@ function enumerateStructuredPaths(input) {
|
|
|
624
625
|
isAncestorOrSelf
|
|
625
626
|
};
|
|
626
627
|
const continuations = withRejoined(enumerate(ctx, input.statements, []));
|
|
627
|
-
for (const
|
|
628
|
+
for (const path4 of continuations) {
|
|
628
629
|
chargeBudget(state);
|
|
629
|
-
state.fallthrough.push(classify(
|
|
630
|
+
state.fallthrough.push(classify(path4, null, isAncestorOrSelf));
|
|
630
631
|
}
|
|
631
632
|
return { byTerminal: state.byTerminal, fallthrough: state.fallthrough };
|
|
632
633
|
}
|
|
@@ -1114,8 +1115,8 @@ function sharedGatingConditions(paths, readPredicate) {
|
|
|
1114
1115
|
return [];
|
|
1115
1116
|
}
|
|
1116
1117
|
const shared = new Set(first.map(keyOf2));
|
|
1117
|
-
for (const
|
|
1118
|
-
const here = new Set(
|
|
1118
|
+
for (const path4 of rest) {
|
|
1119
|
+
const here = new Set(path4.map(keyOf2));
|
|
1119
1120
|
for (const value of shared) {
|
|
1120
1121
|
if (!here.has(value)) {
|
|
1121
1122
|
shared.delete(value);
|
|
@@ -1191,6 +1192,27 @@ function walkDescendants(root, carried, visitor) {
|
|
|
1191
1192
|
}
|
|
1192
1193
|
}
|
|
1193
1194
|
|
|
1195
|
+
// src/projectRoot.ts
|
|
1196
|
+
var import_node_path = __toESM(require("path"), 1);
|
|
1197
|
+
function commonDirectoryOf(files) {
|
|
1198
|
+
const absolute = files.filter((f) => import_node_path.default.isAbsolute(f));
|
|
1199
|
+
const first = absolute[0];
|
|
1200
|
+
if (first === void 0) {
|
|
1201
|
+
return void 0;
|
|
1202
|
+
}
|
|
1203
|
+
let shared = import_node_path.default.dirname(first).split(import_node_path.default.sep);
|
|
1204
|
+
for (const file of absolute.slice(1)) {
|
|
1205
|
+
const parts = import_node_path.default.dirname(file).split(import_node_path.default.sep);
|
|
1206
|
+
let i = 0;
|
|
1207
|
+
while (i < shared.length && i < parts.length && shared[i] === parts[i]) {
|
|
1208
|
+
i += 1;
|
|
1209
|
+
}
|
|
1210
|
+
shared = shared.slice(0, i);
|
|
1211
|
+
}
|
|
1212
|
+
const joined = shared.join(import_node_path.default.sep);
|
|
1213
|
+
return joined.length > 1 ? joined : void 0;
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1194
1216
|
// src/reading.ts
|
|
1195
1217
|
function writtenReading(value, range) {
|
|
1196
1218
|
return { kind: "written", value, range };
|
|
@@ -1248,7 +1270,7 @@ function valueToReadFurtherFrom(reading) {
|
|
|
1248
1270
|
var import_node_crypto = require("crypto");
|
|
1249
1271
|
var import_node_fs = __toESM(require("fs"), 1);
|
|
1250
1272
|
var import_node_module = require("module");
|
|
1251
|
-
var
|
|
1273
|
+
var import_node_path2 = __toESM(require("path"), 1);
|
|
1252
1274
|
var import_node_url = require("url");
|
|
1253
1275
|
var import_meta = {};
|
|
1254
1276
|
var ANALYSIS_PACKAGES = [
|
|
@@ -1291,14 +1313,14 @@ function createAdapterStamp(config) {
|
|
|
1291
1313
|
function readAdapterCodeStamp(moduleUrl) {
|
|
1292
1314
|
try {
|
|
1293
1315
|
const selfPath = (0, import_node_url.fileURLToPath)(moduleUrl);
|
|
1294
|
-
const hash = computeDistHashFrom(
|
|
1316
|
+
const hash = computeDistHashFrom(import_node_path2.default.dirname(selfPath));
|
|
1295
1317
|
return hash.length > 0 ? { kind: "bundle", hash } : SOURCE_STAMP;
|
|
1296
1318
|
} catch {
|
|
1297
1319
|
return SOURCE_STAMP;
|
|
1298
1320
|
}
|
|
1299
1321
|
}
|
|
1300
1322
|
function computeDistHashFrom(dir) {
|
|
1301
|
-
const candidates = [
|
|
1323
|
+
const candidates = [import_node_path2.default.join(dir, "index.js"), import_node_path2.default.join(dir, "index.cjs")];
|
|
1302
1324
|
for (const candidate of candidates) {
|
|
1303
1325
|
if (!import_node_fs.default.existsSync(candidate)) {
|
|
1304
1326
|
continue;
|
|
@@ -1356,7 +1378,7 @@ function analysisBundles() {
|
|
|
1356
1378
|
// src/cache.ts
|
|
1357
1379
|
var import_node_crypto2 = require("crypto");
|
|
1358
1380
|
var import_promises = __toESM(require("fs/promises"), 1);
|
|
1359
|
-
var
|
|
1381
|
+
var import_node_path3 = __toESM(require("path"), 1);
|
|
1360
1382
|
var SCHEMA_VERSION = "7";
|
|
1361
1383
|
var MAX_ENTRIES = 2;
|
|
1362
1384
|
var ENTRY_PREFIX = "key-";
|
|
@@ -1382,7 +1404,7 @@ function createCacheLayer(cacheDir) {
|
|
|
1382
1404
|
async lookup(input) {
|
|
1383
1405
|
const entryDir = entryDirFor(cacheDir, input);
|
|
1384
1406
|
const manifest = await readManifest(
|
|
1385
|
-
|
|
1407
|
+
import_node_path3.default.join(entryDir, "manifest.json")
|
|
1386
1408
|
);
|
|
1387
1409
|
if (manifest === null) {
|
|
1388
1410
|
return missDiag(await describeAbsentEntry(cacheDir));
|
|
@@ -1405,7 +1427,7 @@ function createCacheLayer(cacheDir) {
|
|
|
1405
1427
|
async plan(input) {
|
|
1406
1428
|
const entryDir = entryDirFor(cacheDir, input);
|
|
1407
1429
|
const manifest = await readManifest(
|
|
1408
|
-
|
|
1430
|
+
import_node_path3.default.join(entryDir, "manifest.json")
|
|
1409
1431
|
);
|
|
1410
1432
|
if (manifest === null || manifest.roots === void 0 || manifest.rootMeta === void 0 || manifest.owners === void 0) {
|
|
1411
1433
|
return null;
|
|
@@ -1420,7 +1442,7 @@ function createCacheLayer(cacheDir) {
|
|
|
1420
1442
|
async write(input, summaries, attribution) {
|
|
1421
1443
|
const entryDir = entryDirFor(cacheDir, input);
|
|
1422
1444
|
const previous = await readManifest(
|
|
1423
|
-
|
|
1445
|
+
import_node_path3.default.join(entryDir, "manifest.json")
|
|
1424
1446
|
);
|
|
1425
1447
|
const configStamp = await stampConfigFile(input.configPath);
|
|
1426
1448
|
const files = await hashStamps(await resolveFileStamps(input), previous);
|
|
@@ -1434,7 +1456,7 @@ function createCacheLayer(cacheDir) {
|
|
|
1434
1456
|
};
|
|
1435
1457
|
await import_promises.default.mkdir(entryDir, { recursive: true });
|
|
1436
1458
|
await import_promises.default.writeFile(
|
|
1437
|
-
|
|
1459
|
+
import_node_path3.default.join(entryDir, "manifest.json"),
|
|
1438
1460
|
JSON.stringify(manifest)
|
|
1439
1461
|
);
|
|
1440
1462
|
await evictOldEntries(cacheDir, entryDir);
|
|
@@ -1613,7 +1635,7 @@ function entryDirFor(cacheDir, input) {
|
|
|
1613
1635
|
input.configPath ?? ""
|
|
1614
1636
|
].join(" ");
|
|
1615
1637
|
const name = (0, import_node_crypto2.createHash)("sha256").update(key).digest("hex").slice(0, 16);
|
|
1616
|
-
return
|
|
1638
|
+
return import_node_path3.default.join(cacheDir, `${ENTRY_PREFIX}${name}`);
|
|
1617
1639
|
}
|
|
1618
1640
|
function isEntryDir(name) {
|
|
1619
1641
|
return ENTRY_DIR_NAME.test(name);
|
|
@@ -1627,11 +1649,11 @@ async function markUsed(entryDir) {
|
|
|
1627
1649
|
}
|
|
1628
1650
|
async function evictOldEntries(cacheDir, keepDir) {
|
|
1629
1651
|
try {
|
|
1630
|
-
await import_promises.default.rm(
|
|
1652
|
+
await import_promises.default.rm(import_node_path3.default.join(cacheDir, "manifest.json"), { force: true });
|
|
1631
1653
|
const entries = await import_promises.default.readdir(cacheDir, { withFileTypes: true });
|
|
1632
1654
|
const dirs = await Promise.all(
|
|
1633
1655
|
entries.filter((e) => e.isDirectory() && isEntryDir(e.name)).map(async (e) => {
|
|
1634
|
-
const dir =
|
|
1656
|
+
const dir = import_node_path3.default.join(cacheDir, e.name);
|
|
1635
1657
|
const stat = await import_promises.default.stat(dir);
|
|
1636
1658
|
return { dir, mtimeMs: stat.mtimeMs };
|
|
1637
1659
|
})
|
|
@@ -2458,6 +2480,7 @@ function paramToInput(param) {
|
|
|
2458
2480
|
assembleSummary,
|
|
2459
2481
|
assessConfidence,
|
|
2460
2482
|
buildUngatedExtractionReport,
|
|
2483
|
+
commonDirectoryOf,
|
|
2461
2484
|
composeWrappers,
|
|
2462
2485
|
computeContentHash,
|
|
2463
2486
|
computeDistHashFrom,
|
package/dist/index.d.cts
CHANGED
|
@@ -2272,6 +2272,16 @@ interface NodeVisitor<T, C> {
|
|
|
2272
2272
|
*/
|
|
2273
2273
|
declare function walkDescendants<T extends WalkableNode<T>, C>(root: T, carried: C, visitor: NodeVisitor<T, C>): void;
|
|
2274
2274
|
|
|
2275
|
+
/**
|
|
2276
|
+
* The project root when nothing declares one.
|
|
2277
|
+
*
|
|
2278
|
+
* Resolution from anywhere inside a tree finds the same `node_modules`,
|
|
2279
|
+
* and a recursive reader pointed at the directory every file shares
|
|
2280
|
+
* reaches all of them, so the deepest common directory serves both.
|
|
2281
|
+
*/
|
|
2282
|
+
/** The deepest directory containing every file, or undefined when they share no absolute root. */
|
|
2283
|
+
declare function commonDirectoryOf(files: ReadonlyArray<string>): string | undefined;
|
|
2284
|
+
|
|
2275
2285
|
/**
|
|
2276
2286
|
* The small surface every language adapter implements, whatever that
|
|
2277
2287
|
* language's own tooling looks like underneath.
|
|
@@ -3434,4 +3444,4 @@ declare function rawConditionToPredicate(c: RawCondition): Predicate;
|
|
|
3434
3444
|
declare function effectToIR(effect: RawEffect): Effect;
|
|
3435
3445
|
declare function paramToInput(param: RawParameter): Input;
|
|
3436
3446
|
|
|
3437
|
-
export { type AccessRecognizer, type AdapterCodeStamp, type AdapterStamp, type AstCapableOps, type BindingExtraction, type BodyContent, type CacheAttribution, type CacheDiagnostic, type CacheInput, type CacheLayer, type CacheLookup, type CallOps, type CaseGroup, type ChannelSource, type ChosenReading, type ConditionHandle, type ConditionInfo, type ConditionSource, type ConstructedFrom, type ContractPattern, type DeclaredBinding, type DeclaredBy, type DeclaredMatch, type DefaultedReading, type DiscoveredCustomUnit, type DiscoveredSubUnit, type DiscoveredSubUnitParent, type DiscoveryMatch, type DiscoveryPattern, type EffectArg, type EmptyStage, type ExitKind, type ExtractionReport, type ExtractorOptions, type FailureDelivery, type HealthCheck, type HealthViolation, type HelperDeclarations, type HelperSearch, type HelperSink, type HelperValue, IdMap, IdSet, type Identified, type InputMappingPattern, type InputRead, type InvocationRecognizer, type LanguageAdapter, type LoweredStatementParts, MAX_ENTRIES, MAX_PATHS, type ModuleInitOptions, type NodeVisitor, type OpsCarrier, type PackDeclarations, type PackFailure, type PackFunnel, type PackGradient, type PackTally, type PartialPlan, PathBudgetExceeded, type PatternPack, type ProjectHelper, type ProjectHelpers, type RawBranch, type RawCodeStructure, type RawCondition, type RawDeclaredContract, type RawDependencyCall, type RawEffect, type RawParameter, type RawTerminal, type Reading, type ReceiverOrigin, type RegistrationHelper, type ResponsePropertyMapping, type ResponsePropertyMeaning, type RootRecord, SKIP_CHILDREN, type SourceRange, type StatementBlock, type StructuredPathConditionsInput, type StructuredPathConditionsResult, type StructuredStatement, type TerminalExtraction, type TerminalMatch, type TerminalPattern, type Timer, type TimingReport, type TransparentWrapper, UnmodeledFlow, type UnsettledName, type ValueEntry, type ValueOps, type WalkableNode, type WrapperMethodRegistration, type WrapperOptionRegistration, type WrapperRegistration, absentReading, ambiguousReading, andThenReading, assembleSummary, assessConfidence, buildUngatedExtractionReport, composeWrappers, computeContentHash, computeDistHashFrom, configuredCallOption, createAdapterStamp, createCacheLayer, createPackTallies, createTimer, detectGaps, effectToIR, emptyTally, enumerateOrDegrade, enumerateStructuredPaths, evaluatePackHealth, firstWrittenReading, formatPackHealth, guardsHoldOn, httpRouteDiscovery, makeTransitionId, mapReading, moduleInitStructure, noopTimer, packGradients, paramToInput, projectFileStamp, rawConditionToPredicate, recordPackFailure, registrationHelperDiscovery, routeHelperIndex, runDigest, runsBefore, scopeOption, sharedGatingConditions, stampModuleImports, storageSystemOption, summaryCountsByPack, tallyUnit, terminalToOutput, unreadableReading, unwrapJsonStringify, valueToReadFurtherFrom, walkDescendants, wrapperDiscovery, writtenReading };
|
|
3447
|
+
export { type AccessRecognizer, type AdapterCodeStamp, type AdapterStamp, type AstCapableOps, type BindingExtraction, type BodyContent, type CacheAttribution, type CacheDiagnostic, type CacheInput, type CacheLayer, type CacheLookup, type CallOps, type CaseGroup, type ChannelSource, type ChosenReading, type ConditionHandle, type ConditionInfo, type ConditionSource, type ConstructedFrom, type ContractPattern, type DeclaredBinding, type DeclaredBy, type DeclaredMatch, type DefaultedReading, type DiscoveredCustomUnit, type DiscoveredSubUnit, type DiscoveredSubUnitParent, type DiscoveryMatch, type DiscoveryPattern, type EffectArg, type EmptyStage, type ExitKind, type ExtractionReport, type ExtractorOptions, type FailureDelivery, type HealthCheck, type HealthViolation, type HelperDeclarations, type HelperSearch, type HelperSink, type HelperValue, IdMap, IdSet, type Identified, type InputMappingPattern, type InputRead, type InvocationRecognizer, type LanguageAdapter, type LoweredStatementParts, MAX_ENTRIES, MAX_PATHS, type ModuleInitOptions, type NodeVisitor, type OpsCarrier, type PackDeclarations, type PackFailure, type PackFunnel, type PackGradient, type PackTally, type PartialPlan, PathBudgetExceeded, type PatternPack, type ProjectHelper, type ProjectHelpers, type RawBranch, type RawCodeStructure, type RawCondition, type RawDeclaredContract, type RawDependencyCall, type RawEffect, type RawParameter, type RawTerminal, type Reading, type ReceiverOrigin, type RegistrationHelper, type ResponsePropertyMapping, type ResponsePropertyMeaning, type RootRecord, SKIP_CHILDREN, type SourceRange, type StatementBlock, type StructuredPathConditionsInput, type StructuredPathConditionsResult, type StructuredStatement, type TerminalExtraction, type TerminalMatch, type TerminalPattern, type Timer, type TimingReport, type TransparentWrapper, UnmodeledFlow, type UnsettledName, type ValueEntry, type ValueOps, type WalkableNode, type WrapperMethodRegistration, type WrapperOptionRegistration, type WrapperRegistration, absentReading, ambiguousReading, andThenReading, assembleSummary, assessConfidence, buildUngatedExtractionReport, commonDirectoryOf, composeWrappers, computeContentHash, computeDistHashFrom, configuredCallOption, createAdapterStamp, createCacheLayer, createPackTallies, createTimer, detectGaps, effectToIR, emptyTally, enumerateOrDegrade, enumerateStructuredPaths, evaluatePackHealth, firstWrittenReading, formatPackHealth, guardsHoldOn, httpRouteDiscovery, makeTransitionId, mapReading, moduleInitStructure, noopTimer, packGradients, paramToInput, projectFileStamp, rawConditionToPredicate, recordPackFailure, registrationHelperDiscovery, routeHelperIndex, runDigest, runsBefore, scopeOption, sharedGatingConditions, stampModuleImports, storageSystemOption, summaryCountsByPack, tallyUnit, terminalToOutput, unreadableReading, unwrapJsonStringify, valueToReadFurtherFrom, walkDescendants, wrapperDiscovery, writtenReading };
|
package/dist/index.d.ts
CHANGED
|
@@ -2272,6 +2272,16 @@ interface NodeVisitor<T, C> {
|
|
|
2272
2272
|
*/
|
|
2273
2273
|
declare function walkDescendants<T extends WalkableNode<T>, C>(root: T, carried: C, visitor: NodeVisitor<T, C>): void;
|
|
2274
2274
|
|
|
2275
|
+
/**
|
|
2276
|
+
* The project root when nothing declares one.
|
|
2277
|
+
*
|
|
2278
|
+
* Resolution from anywhere inside a tree finds the same `node_modules`,
|
|
2279
|
+
* and a recursive reader pointed at the directory every file shares
|
|
2280
|
+
* reaches all of them, so the deepest common directory serves both.
|
|
2281
|
+
*/
|
|
2282
|
+
/** The deepest directory containing every file, or undefined when they share no absolute root. */
|
|
2283
|
+
declare function commonDirectoryOf(files: ReadonlyArray<string>): string | undefined;
|
|
2284
|
+
|
|
2275
2285
|
/**
|
|
2276
2286
|
* The small surface every language adapter implements, whatever that
|
|
2277
2287
|
* language's own tooling looks like underneath.
|
|
@@ -3434,4 +3444,4 @@ declare function rawConditionToPredicate(c: RawCondition): Predicate;
|
|
|
3434
3444
|
declare function effectToIR(effect: RawEffect): Effect;
|
|
3435
3445
|
declare function paramToInput(param: RawParameter): Input;
|
|
3436
3446
|
|
|
3437
|
-
export { type AccessRecognizer, type AdapterCodeStamp, type AdapterStamp, type AstCapableOps, type BindingExtraction, type BodyContent, type CacheAttribution, type CacheDiagnostic, type CacheInput, type CacheLayer, type CacheLookup, type CallOps, type CaseGroup, type ChannelSource, type ChosenReading, type ConditionHandle, type ConditionInfo, type ConditionSource, type ConstructedFrom, type ContractPattern, type DeclaredBinding, type DeclaredBy, type DeclaredMatch, type DefaultedReading, type DiscoveredCustomUnit, type DiscoveredSubUnit, type DiscoveredSubUnitParent, type DiscoveryMatch, type DiscoveryPattern, type EffectArg, type EmptyStage, type ExitKind, type ExtractionReport, type ExtractorOptions, type FailureDelivery, type HealthCheck, type HealthViolation, type HelperDeclarations, type HelperSearch, type HelperSink, type HelperValue, IdMap, IdSet, type Identified, type InputMappingPattern, type InputRead, type InvocationRecognizer, type LanguageAdapter, type LoweredStatementParts, MAX_ENTRIES, MAX_PATHS, type ModuleInitOptions, type NodeVisitor, type OpsCarrier, type PackDeclarations, type PackFailure, type PackFunnel, type PackGradient, type PackTally, type PartialPlan, PathBudgetExceeded, type PatternPack, type ProjectHelper, type ProjectHelpers, type RawBranch, type RawCodeStructure, type RawCondition, type RawDeclaredContract, type RawDependencyCall, type RawEffect, type RawParameter, type RawTerminal, type Reading, type ReceiverOrigin, type RegistrationHelper, type ResponsePropertyMapping, type ResponsePropertyMeaning, type RootRecord, SKIP_CHILDREN, type SourceRange, type StatementBlock, type StructuredPathConditionsInput, type StructuredPathConditionsResult, type StructuredStatement, type TerminalExtraction, type TerminalMatch, type TerminalPattern, type Timer, type TimingReport, type TransparentWrapper, UnmodeledFlow, type UnsettledName, type ValueEntry, type ValueOps, type WalkableNode, type WrapperMethodRegistration, type WrapperOptionRegistration, type WrapperRegistration, absentReading, ambiguousReading, andThenReading, assembleSummary, assessConfidence, buildUngatedExtractionReport, composeWrappers, computeContentHash, computeDistHashFrom, configuredCallOption, createAdapterStamp, createCacheLayer, createPackTallies, createTimer, detectGaps, effectToIR, emptyTally, enumerateOrDegrade, enumerateStructuredPaths, evaluatePackHealth, firstWrittenReading, formatPackHealth, guardsHoldOn, httpRouteDiscovery, makeTransitionId, mapReading, moduleInitStructure, noopTimer, packGradients, paramToInput, projectFileStamp, rawConditionToPredicate, recordPackFailure, registrationHelperDiscovery, routeHelperIndex, runDigest, runsBefore, scopeOption, sharedGatingConditions, stampModuleImports, storageSystemOption, summaryCountsByPack, tallyUnit, terminalToOutput, unreadableReading, unwrapJsonStringify, valueToReadFurtherFrom, walkDescendants, wrapperDiscovery, writtenReading };
|
|
3447
|
+
export { type AccessRecognizer, type AdapterCodeStamp, type AdapterStamp, type AstCapableOps, type BindingExtraction, type BodyContent, type CacheAttribution, type CacheDiagnostic, type CacheInput, type CacheLayer, type CacheLookup, type CallOps, type CaseGroup, type ChannelSource, type ChosenReading, type ConditionHandle, type ConditionInfo, type ConditionSource, type ConstructedFrom, type ContractPattern, type DeclaredBinding, type DeclaredBy, type DeclaredMatch, type DefaultedReading, type DiscoveredCustomUnit, type DiscoveredSubUnit, type DiscoveredSubUnitParent, type DiscoveryMatch, type DiscoveryPattern, type EffectArg, type EmptyStage, type ExitKind, type ExtractionReport, type ExtractorOptions, type FailureDelivery, type HealthCheck, type HealthViolation, type HelperDeclarations, type HelperSearch, type HelperSink, type HelperValue, IdMap, IdSet, type Identified, type InputMappingPattern, type InputRead, type InvocationRecognizer, type LanguageAdapter, type LoweredStatementParts, MAX_ENTRIES, MAX_PATHS, type ModuleInitOptions, type NodeVisitor, type OpsCarrier, type PackDeclarations, type PackFailure, type PackFunnel, type PackGradient, type PackTally, type PartialPlan, PathBudgetExceeded, type PatternPack, type ProjectHelper, type ProjectHelpers, type RawBranch, type RawCodeStructure, type RawCondition, type RawDeclaredContract, type RawDependencyCall, type RawEffect, type RawParameter, type RawTerminal, type Reading, type ReceiverOrigin, type RegistrationHelper, type ResponsePropertyMapping, type ResponsePropertyMeaning, type RootRecord, SKIP_CHILDREN, type SourceRange, type StatementBlock, type StructuredPathConditionsInput, type StructuredPathConditionsResult, type StructuredStatement, type TerminalExtraction, type TerminalMatch, type TerminalPattern, type Timer, type TimingReport, type TransparentWrapper, UnmodeledFlow, type UnsettledName, type ValueEntry, type ValueOps, type WalkableNode, type WrapperMethodRegistration, type WrapperOptionRegistration, type WrapperRegistration, absentReading, ambiguousReading, andThenReading, assembleSummary, assessConfidence, buildUngatedExtractionReport, commonDirectoryOf, composeWrappers, computeContentHash, computeDistHashFrom, configuredCallOption, createAdapterStamp, createCacheLayer, createPackTallies, createTimer, detectGaps, effectToIR, emptyTally, enumerateOrDegrade, enumerateStructuredPaths, evaluatePackHealth, firstWrittenReading, formatPackHealth, guardsHoldOn, httpRouteDiscovery, makeTransitionId, mapReading, moduleInitStructure, noopTimer, packGradients, paramToInput, projectFileStamp, rawConditionToPredicate, recordPackFailure, registrationHelperDiscovery, routeHelperIndex, runDigest, runsBefore, scopeOption, sharedGatingConditions, stampModuleImports, storageSystemOption, summaryCountsByPack, tallyUnit, terminalToOutput, unreadableReading, unwrapJsonStringify, valueToReadFurtherFrom, walkDescendants, wrapperDiscovery, writtenReading };
|
package/dist/index.js
CHANGED
|
@@ -218,8 +218,8 @@ var catchEntryCond = () => fixedCond(
|
|
|
218
218
|
"positive",
|
|
219
219
|
"catchBlock"
|
|
220
220
|
);
|
|
221
|
-
function classify(
|
|
222
|
-
return
|
|
221
|
+
function classify(path4, home, isAncestorOrSelf) {
|
|
222
|
+
return path4.map((cond) => {
|
|
223
223
|
if (cond.branchStmt === null) {
|
|
224
224
|
return cond.info;
|
|
225
225
|
}
|
|
@@ -284,9 +284,9 @@ function chargeBudget(state) {
|
|
|
284
284
|
);
|
|
285
285
|
}
|
|
286
286
|
}
|
|
287
|
-
function recordTerminal(ctx, terminal, home,
|
|
287
|
+
function recordTerminal(ctx, terminal, home, path4) {
|
|
288
288
|
chargeBudget(ctx.state);
|
|
289
|
-
const info = classify(
|
|
289
|
+
const info = classify(path4, home, ctx.isAncestorOrSelf);
|
|
290
290
|
const existing = ctx.state.byTerminal.get(terminal) ?? [];
|
|
291
291
|
existing.push(info);
|
|
292
292
|
ctx.state.byTerminal.set(terminal, existing);
|
|
@@ -297,15 +297,15 @@ function containsTerminal(ctx, stmt) {
|
|
|
297
297
|
}
|
|
298
298
|
return childrenOf(stmt).some((child) => containsTerminal(ctx, child));
|
|
299
299
|
}
|
|
300
|
-
function stepIf(stmt,
|
|
300
|
+
function stepIf(stmt, path4, ctx) {
|
|
301
301
|
const thenExit = exitKindOfList(stmt.thenBody);
|
|
302
302
|
const elseExit = stmt.elseBody === null ? null : exitKindOfList(stmt.elseBody);
|
|
303
303
|
const thenPath = [
|
|
304
|
-
...
|
|
304
|
+
...path4,
|
|
305
305
|
branchCond(stmt, stmt.condition, "positive", elseExit)
|
|
306
306
|
];
|
|
307
307
|
const elsePath = [
|
|
308
|
-
...
|
|
308
|
+
...path4,
|
|
309
309
|
branchCond(
|
|
310
310
|
stmt,
|
|
311
311
|
stmt.condition,
|
|
@@ -322,7 +322,7 @@ function stepIf(stmt, path3, ctx) {
|
|
|
322
322
|
}
|
|
323
323
|
return out;
|
|
324
324
|
}
|
|
325
|
-
function stepSwitch(stmt,
|
|
325
|
+
function stepSwitch(stmt, path4, ctx) {
|
|
326
326
|
const out = [];
|
|
327
327
|
const negations = [];
|
|
328
328
|
let defaultRanBody = false;
|
|
@@ -332,7 +332,7 @@ function stepSwitch(stmt, path3, ctx) {
|
|
|
332
332
|
if (hasStrayBreak(group.body)) {
|
|
333
333
|
throw new UnmodeledFlow("non-trailing break in switch clause");
|
|
334
334
|
}
|
|
335
|
-
const groupPath = group.condition === null ? [...
|
|
335
|
+
const groupPath = group.condition === null ? [...path4, ...negations] : [...path4, fixedCond(group.condition, "positive", "explicit")];
|
|
336
336
|
const conts = enumerate(ctx, group.body, groupPath);
|
|
337
337
|
if (conts.length > 0) {
|
|
338
338
|
if (!group.hasTrailingBreak && !fallthroughSafe) {
|
|
@@ -349,24 +349,24 @@ function stepSwitch(stmt, path3, ctx) {
|
|
|
349
349
|
}
|
|
350
350
|
}
|
|
351
351
|
if (!defaultRanBody) {
|
|
352
|
-
out.push([...
|
|
352
|
+
out.push([...path4, ...negations]);
|
|
353
353
|
}
|
|
354
354
|
return out;
|
|
355
355
|
}
|
|
356
|
-
function stepLoop(stmt,
|
|
356
|
+
function stepLoop(stmt, path4, ctx) {
|
|
357
357
|
const bodyExit = exitKindOfList(stmt.body);
|
|
358
358
|
if (containsTerminal(ctx, stmt)) {
|
|
359
359
|
enumerate(ctx, stmt.body, [
|
|
360
|
-
...
|
|
360
|
+
...path4,
|
|
361
361
|
loopIterationCond(stmt.condition.sourceText)
|
|
362
362
|
]);
|
|
363
363
|
}
|
|
364
364
|
if (bodyExit !== null) {
|
|
365
|
-
return [[...
|
|
365
|
+
return [[...path4, loopCompletedCond(stmt.condition.sourceText, bodyExit)]];
|
|
366
366
|
}
|
|
367
|
-
return [
|
|
367
|
+
return [path4];
|
|
368
368
|
}
|
|
369
|
-
function stepTry(stmt,
|
|
369
|
+
function stepTry(stmt, path4, ctx) {
|
|
370
370
|
if (stmt.finallyBody !== null) {
|
|
371
371
|
const finallyHasTerminal = stmt.finallyBody.some(
|
|
372
372
|
(s) => containsTerminal(ctx, s)
|
|
@@ -376,22 +376,22 @@ function stepTry(stmt, path3, ctx) {
|
|
|
376
376
|
}
|
|
377
377
|
}
|
|
378
378
|
const out = [];
|
|
379
|
-
out.push(...enumerate(ctx, stmt.tryBody,
|
|
379
|
+
out.push(...enumerate(ctx, stmt.tryBody, path4));
|
|
380
380
|
if (stmt.catchBody !== null) {
|
|
381
|
-
const catchPath = [...
|
|
381
|
+
const catchPath = [...path4, catchEntryCond()];
|
|
382
382
|
out.push(...enumerate(ctx, stmt.catchBody, catchPath));
|
|
383
383
|
}
|
|
384
384
|
return out;
|
|
385
385
|
}
|
|
386
|
-
function stepExit(stmt,
|
|
386
|
+
function stepExit(stmt, path4, ctx) {
|
|
387
387
|
const collector = ctx.state.callbackExits[ctx.state.callbackExits.length - 1];
|
|
388
388
|
if (collector !== void 0 && (stmt.exit === "return" || stmt.exit === "throw")) {
|
|
389
|
-
collector.push(
|
|
389
|
+
collector.push(path4);
|
|
390
390
|
}
|
|
391
391
|
return [];
|
|
392
392
|
}
|
|
393
|
-
function stepOpaque(_stmt,
|
|
394
|
-
return [
|
|
393
|
+
function stepOpaque(_stmt, path4, _ctx) {
|
|
394
|
+
return [path4];
|
|
395
395
|
}
|
|
396
396
|
var stepHandlers = {
|
|
397
397
|
if: stepIf,
|
|
@@ -401,20 +401,20 @@ var stepHandlers = {
|
|
|
401
401
|
exit: stepExit,
|
|
402
402
|
opaque: stepOpaque
|
|
403
403
|
};
|
|
404
|
-
function stepCallback(ctx, body,
|
|
404
|
+
function stepCallback(ctx, body, path4) {
|
|
405
405
|
const exits = [];
|
|
406
406
|
ctx.state.callbackExits.push(exits);
|
|
407
407
|
let fellThrough;
|
|
408
408
|
try {
|
|
409
|
-
fellThrough = enumerate(ctx, body,
|
|
409
|
+
fellThrough = enumerate(ctx, body, path4);
|
|
410
410
|
} finally {
|
|
411
411
|
ctx.state.callbackExits.pop();
|
|
412
412
|
}
|
|
413
413
|
const out = [...fellThrough, ...exits];
|
|
414
|
-
return out.length === 0 ? [
|
|
414
|
+
return out.length === 0 ? [path4] : out;
|
|
415
415
|
}
|
|
416
|
-
function stepStatement(ctx, stmt,
|
|
417
|
-
let paths = [
|
|
416
|
+
function stepStatement(ctx, stmt, path4) {
|
|
417
|
+
let paths = [path4];
|
|
418
418
|
for (const body of stmt.callbacks ?? []) {
|
|
419
419
|
paths = paths.flatMap((each) => stepCallback(ctx, body, each));
|
|
420
420
|
}
|
|
@@ -495,8 +495,8 @@ function enumerate(ctx, stmts, prefix) {
|
|
|
495
495
|
let frontiers = [[...prefix]];
|
|
496
496
|
for (const stmt of stmts) {
|
|
497
497
|
const nextFrontiers = [];
|
|
498
|
-
for (const
|
|
499
|
-
nextFrontiers.push(...stepStatement(ctx, stmt,
|
|
498
|
+
for (const path4 of mergeRejoined(frontiers)) {
|
|
499
|
+
nextFrontiers.push(...stepStatement(ctx, stmt, path4));
|
|
500
500
|
}
|
|
501
501
|
frontiers = nextFrontiers;
|
|
502
502
|
if (frontiers.length > MAX_PATHS) {
|
|
@@ -547,9 +547,9 @@ function enumerateStructuredPaths(input) {
|
|
|
547
547
|
isAncestorOrSelf
|
|
548
548
|
};
|
|
549
549
|
const continuations = withRejoined(enumerate(ctx, input.statements, []));
|
|
550
|
-
for (const
|
|
550
|
+
for (const path4 of continuations) {
|
|
551
551
|
chargeBudget(state);
|
|
552
|
-
state.fallthrough.push(classify(
|
|
552
|
+
state.fallthrough.push(classify(path4, null, isAncestorOrSelf));
|
|
553
553
|
}
|
|
554
554
|
return { byTerminal: state.byTerminal, fallthrough: state.fallthrough };
|
|
555
555
|
}
|
|
@@ -1037,8 +1037,8 @@ function sharedGatingConditions(paths, readPredicate) {
|
|
|
1037
1037
|
return [];
|
|
1038
1038
|
}
|
|
1039
1039
|
const shared = new Set(first.map(keyOf2));
|
|
1040
|
-
for (const
|
|
1041
|
-
const here = new Set(
|
|
1040
|
+
for (const path4 of rest) {
|
|
1041
|
+
const here = new Set(path4.map(keyOf2));
|
|
1042
1042
|
for (const value of shared) {
|
|
1043
1043
|
if (!here.has(value)) {
|
|
1044
1044
|
shared.delete(value);
|
|
@@ -1114,6 +1114,27 @@ function walkDescendants(root, carried, visitor) {
|
|
|
1114
1114
|
}
|
|
1115
1115
|
}
|
|
1116
1116
|
|
|
1117
|
+
// src/projectRoot.ts
|
|
1118
|
+
import path from "path";
|
|
1119
|
+
function commonDirectoryOf(files) {
|
|
1120
|
+
const absolute = files.filter((f) => path.isAbsolute(f));
|
|
1121
|
+
const first = absolute[0];
|
|
1122
|
+
if (first === void 0) {
|
|
1123
|
+
return void 0;
|
|
1124
|
+
}
|
|
1125
|
+
let shared = path.dirname(first).split(path.sep);
|
|
1126
|
+
for (const file of absolute.slice(1)) {
|
|
1127
|
+
const parts = path.dirname(file).split(path.sep);
|
|
1128
|
+
let i = 0;
|
|
1129
|
+
while (i < shared.length && i < parts.length && shared[i] === parts[i]) {
|
|
1130
|
+
i += 1;
|
|
1131
|
+
}
|
|
1132
|
+
shared = shared.slice(0, i);
|
|
1133
|
+
}
|
|
1134
|
+
const joined = shared.join(path.sep);
|
|
1135
|
+
return joined.length > 1 ? joined : void 0;
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1117
1138
|
// src/reading.ts
|
|
1118
1139
|
function writtenReading(value, range) {
|
|
1119
1140
|
return { kind: "written", value, range };
|
|
@@ -1171,7 +1192,7 @@ function valueToReadFurtherFrom(reading) {
|
|
|
1171
1192
|
import { createHash } from "crypto";
|
|
1172
1193
|
import fs from "fs";
|
|
1173
1194
|
import { createRequire } from "module";
|
|
1174
|
-
import
|
|
1195
|
+
import path2 from "path";
|
|
1175
1196
|
import { fileURLToPath } from "url";
|
|
1176
1197
|
var ANALYSIS_PACKAGES = [
|
|
1177
1198
|
"@suss/extractor",
|
|
@@ -1213,14 +1234,14 @@ function createAdapterStamp(config) {
|
|
|
1213
1234
|
function readAdapterCodeStamp(moduleUrl) {
|
|
1214
1235
|
try {
|
|
1215
1236
|
const selfPath = fileURLToPath(moduleUrl);
|
|
1216
|
-
const hash = computeDistHashFrom(
|
|
1237
|
+
const hash = computeDistHashFrom(path2.dirname(selfPath));
|
|
1217
1238
|
return hash.length > 0 ? { kind: "bundle", hash } : SOURCE_STAMP;
|
|
1218
1239
|
} catch {
|
|
1219
1240
|
return SOURCE_STAMP;
|
|
1220
1241
|
}
|
|
1221
1242
|
}
|
|
1222
1243
|
function computeDistHashFrom(dir) {
|
|
1223
|
-
const candidates = [
|
|
1244
|
+
const candidates = [path2.join(dir, "index.js"), path2.join(dir, "index.cjs")];
|
|
1224
1245
|
for (const candidate of candidates) {
|
|
1225
1246
|
if (!fs.existsSync(candidate)) {
|
|
1226
1247
|
continue;
|
|
@@ -1278,7 +1299,7 @@ function analysisBundles() {
|
|
|
1278
1299
|
// src/cache.ts
|
|
1279
1300
|
import { createHash as createHash2 } from "crypto";
|
|
1280
1301
|
import fs2 from "fs/promises";
|
|
1281
|
-
import
|
|
1302
|
+
import path3 from "path";
|
|
1282
1303
|
var SCHEMA_VERSION = "7";
|
|
1283
1304
|
var MAX_ENTRIES = 2;
|
|
1284
1305
|
var ENTRY_PREFIX = "key-";
|
|
@@ -1304,7 +1325,7 @@ function createCacheLayer(cacheDir) {
|
|
|
1304
1325
|
async lookup(input) {
|
|
1305
1326
|
const entryDir = entryDirFor(cacheDir, input);
|
|
1306
1327
|
const manifest = await readManifest(
|
|
1307
|
-
|
|
1328
|
+
path3.join(entryDir, "manifest.json")
|
|
1308
1329
|
);
|
|
1309
1330
|
if (manifest === null) {
|
|
1310
1331
|
return missDiag(await describeAbsentEntry(cacheDir));
|
|
@@ -1327,7 +1348,7 @@ function createCacheLayer(cacheDir) {
|
|
|
1327
1348
|
async plan(input) {
|
|
1328
1349
|
const entryDir = entryDirFor(cacheDir, input);
|
|
1329
1350
|
const manifest = await readManifest(
|
|
1330
|
-
|
|
1351
|
+
path3.join(entryDir, "manifest.json")
|
|
1331
1352
|
);
|
|
1332
1353
|
if (manifest === null || manifest.roots === void 0 || manifest.rootMeta === void 0 || manifest.owners === void 0) {
|
|
1333
1354
|
return null;
|
|
@@ -1342,7 +1363,7 @@ function createCacheLayer(cacheDir) {
|
|
|
1342
1363
|
async write(input, summaries, attribution) {
|
|
1343
1364
|
const entryDir = entryDirFor(cacheDir, input);
|
|
1344
1365
|
const previous = await readManifest(
|
|
1345
|
-
|
|
1366
|
+
path3.join(entryDir, "manifest.json")
|
|
1346
1367
|
);
|
|
1347
1368
|
const configStamp = await stampConfigFile(input.configPath);
|
|
1348
1369
|
const files = await hashStamps(await resolveFileStamps(input), previous);
|
|
@@ -1356,7 +1377,7 @@ function createCacheLayer(cacheDir) {
|
|
|
1356
1377
|
};
|
|
1357
1378
|
await fs2.mkdir(entryDir, { recursive: true });
|
|
1358
1379
|
await fs2.writeFile(
|
|
1359
|
-
|
|
1380
|
+
path3.join(entryDir, "manifest.json"),
|
|
1360
1381
|
JSON.stringify(manifest)
|
|
1361
1382
|
);
|
|
1362
1383
|
await evictOldEntries(cacheDir, entryDir);
|
|
@@ -1535,7 +1556,7 @@ function entryDirFor(cacheDir, input) {
|
|
|
1535
1556
|
input.configPath ?? ""
|
|
1536
1557
|
].join(" ");
|
|
1537
1558
|
const name = createHash2("sha256").update(key).digest("hex").slice(0, 16);
|
|
1538
|
-
return
|
|
1559
|
+
return path3.join(cacheDir, `${ENTRY_PREFIX}${name}`);
|
|
1539
1560
|
}
|
|
1540
1561
|
function isEntryDir(name) {
|
|
1541
1562
|
return ENTRY_DIR_NAME.test(name);
|
|
@@ -1549,11 +1570,11 @@ async function markUsed(entryDir) {
|
|
|
1549
1570
|
}
|
|
1550
1571
|
async function evictOldEntries(cacheDir, keepDir) {
|
|
1551
1572
|
try {
|
|
1552
|
-
await fs2.rm(
|
|
1573
|
+
await fs2.rm(path3.join(cacheDir, "manifest.json"), { force: true });
|
|
1553
1574
|
const entries = await fs2.readdir(cacheDir, { withFileTypes: true });
|
|
1554
1575
|
const dirs = await Promise.all(
|
|
1555
1576
|
entries.filter((e) => e.isDirectory() && isEntryDir(e.name)).map(async (e) => {
|
|
1556
|
-
const dir =
|
|
1577
|
+
const dir = path3.join(cacheDir, e.name);
|
|
1557
1578
|
const stat = await fs2.stat(dir);
|
|
1558
1579
|
return { dir, mtimeMs: stat.mtimeMs };
|
|
1559
1580
|
})
|
|
@@ -2379,6 +2400,7 @@ export {
|
|
|
2379
2400
|
assembleSummary,
|
|
2380
2401
|
assessConfidence,
|
|
2381
2402
|
buildUngatedExtractionReport,
|
|
2403
|
+
commonDirectoryOf,
|
|
2382
2404
|
composeWrappers,
|
|
2383
2405
|
computeContentHash,
|
|
2384
2406
|
computeDistHashFrom,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@suss/extractor",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.26.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "The suss extraction pipeline, which turns what a language adapter read into the summaries the checker pairs across a boundary.",
|
|
6
6
|
"keywords": [
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"typecheck": "tsc --noEmit"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@suss/behavioral-ir": "0.
|
|
49
|
+
"@suss/behavioral-ir": "0.26.0",
|
|
50
50
|
"zod": "^4.0.0"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|