@suss/adapter-typescript 0.24.2 → 0.24.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/index.cjs +177 -91
  2. package/dist/index.js +173 -85
  3. package/package.json +6 -6
package/dist/index.cjs CHANGED
@@ -77,7 +77,7 @@ __export(index_exports, {
77
77
  module.exports = __toCommonJS(index_exports);
78
78
 
79
79
  // src/adapter.ts
80
- var import_node_path10 = __toESM(require("path"), 1);
80
+ var import_node_path11 = __toESM(require("path"), 1);
81
81
  var import_ts_morph67 = require("ts-morph");
82
82
  var import_behavioral_ir8 = require("@suss/behavioral-ir");
83
83
  var import_datalog6 = require("@suss/datalog");
@@ -1913,8 +1913,8 @@ function loadImportGraphsDepthFirstFromPaths(project, rootPaths) {
1913
1913
  stack.pop();
1914
1914
  loadOrder.push(top.path);
1915
1915
  let deepest = 0;
1916
- for (const path14 of top.deps) {
1917
- deepest = Math.max(deepest, chainDepth.get(path14) ?? 0);
1916
+ for (const path15 of top.deps) {
1917
+ deepest = Math.max(deepest, chainDepth.get(path15) ?? 0);
1918
1918
  }
1919
1919
  chainDepth.set(top.path, deepest + 1);
1920
1920
  }
@@ -2266,11 +2266,11 @@ function walkAndWarm(root, reach) {
2266
2266
  if (warmedFiles.get(target) !== void 0) {
2267
2267
  continue;
2268
2268
  }
2269
- const path14 = target.getFilePath();
2270
- if (visited.has(path14)) {
2269
+ const path15 = target.getFilePath();
2270
+ if (visited.has(path15)) {
2271
2271
  continue;
2272
2272
  }
2273
- visited.add(path14);
2273
+ visited.add(path15);
2274
2274
  stack.push(frameOf(target, reach));
2275
2275
  continue;
2276
2276
  }
@@ -2287,7 +2287,7 @@ function sitsOnWarmChains(file) {
2287
2287
  return false;
2288
2288
  }
2289
2289
  const imported = importedFilePathsOf(project, file.getFilePath());
2290
- return imported.length > 0 && imported.every((path14) => warmed.has(path14));
2290
+ return imported.length > 0 && imported.every((path15) => warmed.has(path15));
2291
2291
  }
2292
2292
  function markWarmed(file) {
2293
2293
  warmedFiles.set(file, true);
@@ -5039,7 +5039,7 @@ function isPathStatement(node) {
5039
5039
  return import_ts_morph18.Node.isStatement(node) && !import_ts_morph18.Node.isFunctionDeclaration(node);
5040
5040
  }
5041
5041
  function siteOf(node) {
5042
- const path14 = [];
5042
+ const path15 = [];
5043
5043
  let current2 = node;
5044
5044
  for (; ; ) {
5045
5045
  const parent = current2.getParent();
@@ -5047,10 +5047,10 @@ function siteOf(node) {
5047
5047
  return null;
5048
5048
  }
5049
5049
  if (isPathStatement(current2)) {
5050
- path14.unshift(current2);
5050
+ path15.unshift(current2);
5051
5051
  }
5052
5052
  if (isRoot(parent)) {
5053
- return { root: parent, path: path14 };
5053
+ return { root: parent, path: path15 };
5054
5054
  }
5055
5055
  current2 = parent;
5056
5056
  }
@@ -7042,14 +7042,14 @@ function unitForJsxRoute(node, match, routeNames, kind, resolution) {
7042
7042
  }
7043
7043
  return routeUnit(node, kind, match.method, resolved.path, target, resolution);
7044
7044
  }
7045
- function routeUnit(at, kind, method, path14, target, resolution) {
7046
- const routeInfo = { method, path: path14 };
7045
+ function routeUnit(at, kind, method, path15, target, resolution) {
7046
+ const routeInfo = { method, path: path15 };
7047
7047
  if (target.kind === "unreadable") {
7048
7048
  return {
7049
7049
  func: null,
7050
7050
  announcedAt: at,
7051
7051
  kind,
7052
- name: path14,
7052
+ name: path15,
7053
7053
  nameKind: "label",
7054
7054
  routeInfo
7055
7055
  };
@@ -8313,11 +8313,11 @@ function extractRouteInfoFromBinding(call, methodName, binding, resolution) {
8313
8313
  return null;
8314
8314
  }
8315
8315
  const method2 = stringPropertyOf(arg, binding.method.property, resolution);
8316
- const path15 = stringPropertyOf(arg, binding.path.property, resolution);
8317
- if (method2 === null || path15 === null) {
8316
+ const path16 = stringPropertyOf(arg, binding.path.property, resolution);
8317
+ if (method2 === null || path16 === null) {
8318
8318
  return null;
8319
8319
  }
8320
- return { method: method2.toUpperCase(), path: path15 };
8320
+ return { method: method2.toUpperCase(), path: path16 };
8321
8321
  }
8322
8322
  if (binding.method.type !== "fromRegistration" || binding.path.type !== "fromArgument") {
8323
8323
  return null;
@@ -8334,8 +8334,8 @@ function extractRouteInfoFromBinding(call, methodName, binding, resolution) {
8334
8334
  method = arg.getLiteralValue().toUpperCase();
8335
8335
  }
8336
8336
  const pathArg = call.getArguments()[binding.path.position];
8337
- const path14 = pathArg === void 0 ? void 0 : pathFromArgument(pathArg, resolution);
8338
- return path14 === void 0 ? null : { method, path: path14 };
8337
+ const path15 = pathArg === void 0 ? void 0 : pathFromArgument(pathArg, resolution);
8338
+ return path15 === void 0 ? null : { method, path: path15 };
8339
8339
  }
8340
8340
 
8341
8341
  // src/discovery/registrationLoop.ts
@@ -8467,7 +8467,7 @@ function bodyCallsOnRoutable(loop, guard, resolution) {
8467
8467
  }
8468
8468
  function readRouteSpec(element, shape, resolution) {
8469
8469
  let method = null;
8470
- let path14 = null;
8470
+ let path15 = null;
8471
8471
  let handler = null;
8472
8472
  for (const prop of element.getProperties()) {
8473
8473
  if (import_ts_morph35.Node.isMethodDeclaration(prop) && prop.getName() === shape.handlerKey) {
@@ -8485,16 +8485,16 @@ function readRouteSpec(element, shape, resolution) {
8485
8485
  if (name === shape.methodKey) {
8486
8486
  method = readStringLiteralValue(init);
8487
8487
  } else if (name === shape.pathKey) {
8488
- path14 = readStringLiteralValue(init);
8488
+ path15 = readStringLiteralValue(init);
8489
8489
  } else if (name === shape.handlerKey) {
8490
8490
  const func = functionValueOf(init, resolution);
8491
8491
  handler = func === null ? null : { func, name: handlerName(init) };
8492
8492
  }
8493
8493
  }
8494
- if (method === null || path14 === null || handler === null) {
8494
+ if (method === null || path15 === null || handler === null) {
8495
8495
  return null;
8496
8496
  }
8497
- return { method, path: path14, handler: handler.func, handlerName: handler.name };
8497
+ return { method, path: path15, handler: handler.func, handlerName: handler.name };
8498
8498
  }
8499
8499
  function readStringLiteralValue(node) {
8500
8500
  if (import_ts_morph35.Node.isStringLiteral(node) || import_ts_morph35.Node.isNoSubstitutionTemplateLiteral(node)) {
@@ -8609,8 +8609,8 @@ function discoverRegistrationTemplates(sourceFile, match, kind, resolution, moun
8609
8609
  const subject = subjectOfCall(sourceFile, args, match, resolution);
8610
8610
  const prefix = subject === void 0 ? "" : mountPrefixes?.effectivePrefixFor(subject) ?? "";
8611
8611
  for (const reg of match.registrations) {
8612
- const path14 = substitutePath(reg.pathTemplate, args);
8613
- if (path14 === null) {
8612
+ const path15 = substitutePath(reg.pathTemplate, args);
8613
+ if (path15 === null) {
8614
8614
  continue;
8615
8615
  }
8616
8616
  const handler = resolveHandler(reg.handlerArg, args, resolution);
@@ -8624,7 +8624,7 @@ function discoverRegistrationTemplates(sourceFile, match, kind, resolution, moun
8624
8624
  ...subject === void 0 ? {} : { registrationSubjectId: nodeId(subject) },
8625
8625
  routeInfo: {
8626
8626
  method: reg.method.toUpperCase(),
8627
- path: prefix === "" ? path14 : (0, import_resolution4.joinMountedPath)(prefix, path14)
8627
+ path: prefix === "" ? path15 : (0, import_resolution4.joinMountedPath)(prefix, path15)
8628
8628
  }
8629
8629
  });
8630
8630
  }
@@ -9087,24 +9087,24 @@ function declName(decl) {
9087
9087
 
9088
9088
  // src/parameterReads.ts
9089
9089
  function pathAbove(reference) {
9090
- const path14 = [];
9090
+ const path15 = [];
9091
9091
  let current2 = reference;
9092
9092
  for (; ; ) {
9093
9093
  const parent = current2.getParent();
9094
9094
  if (parent !== void 0 && import_ts_morph40.Node.isPropertyAccessExpression(parent) && parent.getExpression() === current2) {
9095
- path14.push(parent.getName());
9095
+ path15.push(parent.getName());
9096
9096
  current2 = parent;
9097
9097
  continue;
9098
9098
  }
9099
9099
  if (parent !== void 0 && import_ts_morph40.Node.isElementAccessExpression(parent) && parent.getExpression() === current2) {
9100
9100
  const argument = parent.getArgumentExpression();
9101
9101
  if (argument !== void 0 && import_ts_morph40.Node.isStringLiteral(argument)) {
9102
- path14.push(argument.getLiteralValue());
9102
+ path15.push(argument.getLiteralValue());
9103
9103
  current2 = parent;
9104
9104
  continue;
9105
9105
  }
9106
9106
  }
9107
- return path14;
9107
+ return path15;
9108
9108
  }
9109
9109
  }
9110
9110
  function declaresParameterOf(node, func) {
@@ -12450,9 +12450,9 @@ function createSourceFileLookup(project) {
12450
12450
  if (sf === null) {
12451
12451
  return null;
12452
12452
  }
12453
- const path14 = sf.getFilePath();
12454
- const index = functionsByFile.get(path14) ?? indexFunctions(sf);
12455
- functionsByFile.set(path14, index);
12453
+ const path15 = sf.getFilePath();
12454
+ const index = functionsByFile.get(path15) ?? indexFunctions(sf);
12455
+ functionsByFile.set(path15, index);
12456
12456
  if (location.span !== void 0) {
12457
12457
  const bySpan = index.get(spanKey(location.span));
12458
12458
  if (bySpan !== void 0) {
@@ -12639,7 +12639,7 @@ function extractEndpointContract(endpointNode, pattern, framework, resolution) {
12639
12639
  }
12640
12640
  const responses = [];
12641
12641
  let method;
12642
- let path14;
12642
+ let path15;
12643
12643
  for (const prop of endpointNode.getProperties()) {
12644
12644
  if (!import_ts_morph57.Node.isPropertyAssignment(prop)) {
12645
12645
  continue;
@@ -12654,7 +12654,7 @@ function extractEndpointContract(endpointNode, pattern, framework, resolution) {
12654
12654
  if (propName === pattern.pathProperty) {
12655
12655
  const val = prop.getInitializer();
12656
12656
  if (val !== void 0 && import_ts_morph57.Node.isStringLiteral(val)) {
12657
- path14 = val.getLiteralValue();
12657
+ path15 = val.getLiteralValue();
12658
12658
  }
12659
12659
  }
12660
12660
  if (propName === pattern.responseExtraction.property) {
@@ -12679,10 +12679,10 @@ function extractEndpointContract(endpointNode, pattern, framework, resolution) {
12679
12679
  if (responses.length === 0) {
12680
12680
  return null;
12681
12681
  }
12682
- const boundaryBinding = method !== void 0 || path14 !== void 0 ? (0, import_behavioral_ir4.restBinding)({
12682
+ const boundaryBinding = method !== void 0 || path15 !== void 0 ? (0, import_behavioral_ir4.restBinding)({
12683
12683
  transport: "http",
12684
12684
  method: method ?? null,
12685
- path: path14 ?? null,
12685
+ path: path15 ?? null,
12686
12686
  recognition: framework
12687
12687
  }) : null;
12688
12688
  return {
@@ -12893,6 +12893,9 @@ function parameterName(segment, convention) {
12893
12893
  }
12894
12894
 
12895
12895
  // src/discovery/graphqlClientConstruction.ts
12896
+ var import_node_fs3 = __toESM(require("fs"), 1);
12897
+ var import_node_path8 = __toESM(require("path"), 1);
12898
+ var import_graphql2 = require("graphql");
12896
12899
  var import_picomatch2 = __toESM(require("picomatch"), 1);
12897
12900
  var import_ts_morph58 = require("ts-morph");
12898
12901
  var import_behavioral_ir5 = require("@suss/behavioral-ir");
@@ -12904,15 +12907,20 @@ function stampGraphqlClientRefs(summaries, sourceFiles, packs, resolution) {
12904
12907
  const workspace = sole !== null ? boundWorkspaceFor(sole, packs) : null;
12905
12908
  const soleClient = sole !== null ? workspace !== null ? { ...sole, workspace } : sole : null;
12906
12909
  let registry = null;
12910
+ let defined = null;
12907
12911
  for (const summary of summaries) {
12908
12912
  if (!(0, import_behavioral_ir5.isGraphqlOperationBinding)(summary.identity.boundaryBinding)) {
12909
12913
  continue;
12910
12914
  }
12911
- const existing = (0, import_behavioral_ir5.readGraphqlMetadata)(summary) ?? {};
12915
+ const found = (0, import_behavioral_ir5.readGraphqlMetadata)(summary) ?? {};
12916
+ const existing = withoutFragmentsDefinedElsewhere(found, () => {
12917
+ defined ??= fragmentsRegisteredIn(sourceFiles);
12918
+ return defined;
12919
+ });
12912
12920
  const scoped = scopedWorkspaceFor(summary.location.file, scopes);
12913
12921
  const client = scoped !== null ? { uri: null, uriRef: null, workspace: scoped } : soleClient;
12914
12922
  const dangling = (existing.unresolvedFragments?.length ?? 0) > 0;
12915
- if (client === null && !dangling) {
12923
+ if (client === null && !dangling && existing === found) {
12916
12924
  continue;
12917
12925
  }
12918
12926
  if (dangling && registry === null) {
@@ -12925,6 +12933,84 @@ function stampGraphqlClientRefs(summaries, sourceFiles, packs, resolution) {
12925
12933
  });
12926
12934
  }
12927
12935
  }
12936
+ function fragmentsRegisteredIn(sourceFiles) {
12937
+ const registered = /* @__PURE__ */ new Set();
12938
+ for (const sourceFile of sourceFiles) {
12939
+ sourceFile.forEachDescendant((node) => {
12940
+ if (!import_ts_morph58.Node.isCallExpression(node)) {
12941
+ return;
12942
+ }
12943
+ const argument = node.getArguments()[0];
12944
+ if (argument === void 0 || !import_ts_morph58.Node.isNoSubstitutionTemplateLiteral(argument)) {
12945
+ return;
12946
+ }
12947
+ for (const name of fragmentOnlyDocumentNames(argument.getLiteralText())) {
12948
+ registered.add(name);
12949
+ }
12950
+ });
12951
+ }
12952
+ for (const text of graphqlFileTextsNear(sourceFiles)) {
12953
+ for (const name of fragmentOnlyDocumentNames(text)) {
12954
+ registered.add(name);
12955
+ }
12956
+ }
12957
+ return registered;
12958
+ }
12959
+ function graphqlFileTextsNear(sourceFiles) {
12960
+ const roots = new Set(
12961
+ sourceFiles.map((sourceFile) => import_node_path8.default.dirname(sourceFile.getFilePath()))
12962
+ );
12963
+ const texts = [];
12964
+ for (const root of roots) {
12965
+ let entries;
12966
+ try {
12967
+ entries = import_node_fs3.default.readdirSync(root, { withFileTypes: true });
12968
+ } catch {
12969
+ continue;
12970
+ }
12971
+ for (const entry of entries) {
12972
+ if (entry.isFile() && /\.(graphql|gql)$/.test(entry.name)) {
12973
+ try {
12974
+ texts.push(import_node_fs3.default.readFileSync(import_node_path8.default.join(root, entry.name), "utf8"));
12975
+ } catch {
12976
+ }
12977
+ }
12978
+ }
12979
+ }
12980
+ return texts;
12981
+ }
12982
+ function fragmentOnlyDocumentNames(text) {
12983
+ if (!text.includes("fragment")) {
12984
+ return [];
12985
+ }
12986
+ let parsed;
12987
+ try {
12988
+ parsed = (0, import_graphql2.parse)(text);
12989
+ } catch {
12990
+ return [];
12991
+ }
12992
+ const names = [];
12993
+ for (const definition of parsed.definitions) {
12994
+ if (definition.kind !== "FragmentDefinition") {
12995
+ return [];
12996
+ }
12997
+ names.push(definition.name.value);
12998
+ }
12999
+ return names;
13000
+ }
13001
+ function withoutFragmentsDefinedElsewhere(metadata, definedInProject) {
13002
+ const unresolved = metadata.unresolvedFragments ?? [];
13003
+ if (unresolved.length === 0) {
13004
+ return metadata;
13005
+ }
13006
+ const defined = definedInProject();
13007
+ const left = unresolved.filter((name) => !defined.has(name));
13008
+ if (left.length === unresolved.length) {
13009
+ return metadata;
13010
+ }
13011
+ const { unresolvedFragments: _dropped, ...rest } = metadata;
13012
+ return left.length === 0 ? rest : { ...rest, unresolvedFragments: left };
13013
+ }
12928
13014
  function compileOperationScopes(packs) {
12929
13015
  return packs.flatMap((pack) => pack.graphqlOperationScopes ?? []).map((scope) => {
12930
13016
  const matchers2 = scope.files.map(
@@ -13330,8 +13416,8 @@ function noteExpanded(expanded, readings, discovery) {
13330
13416
  const paths = new Set(match.registrations.map((one) => one.pathTemplate));
13331
13417
  const methods = expanded.get(reading.declarationId) ?? /* @__PURE__ */ new Set();
13332
13418
  for (const sink of reading.helper.sinks) {
13333
- const path14 = sink.arguments[0];
13334
- if (sink.method !== null && path14?.as === "text" && paths.has(path14.text)) {
13419
+ const path15 = sink.arguments[0];
13420
+ if (sink.method !== null && path15?.as === "text" && paths.has(path15.text)) {
13335
13421
  methods.add(sink.method);
13336
13422
  }
13337
13423
  }
@@ -13979,7 +14065,7 @@ function isJsxOrFragment(node) {
13979
14065
  }
13980
14066
 
13981
14067
  // src/graphqlContract.ts
13982
- var import_graphql2 = require("graphql");
14068
+ var import_graphql3 = require("graphql");
13983
14069
  var parseCache = /* @__PURE__ */ new Map();
13984
14070
  function parseSchema(sdl) {
13985
14071
  const cached = parseCache.get(sdl);
@@ -13987,7 +14073,7 @@ function parseSchema(sdl) {
13987
14073
  return cached;
13988
14074
  }
13989
14075
  try {
13990
- const doc = (0, import_graphql2.parse)(sdl);
14076
+ const doc = (0, import_graphql3.parse)(sdl);
13991
14077
  parseCache.set(sdl, doc);
13992
14078
  return doc;
13993
14079
  } catch (_err) {
@@ -14009,7 +14095,7 @@ function deriveGraphqlContract(sdl, typeName, fieldName, framework) {
14009
14095
  args: (field.arguments ?? []).map((arg) => ({
14010
14096
  name: arg.name.value,
14011
14097
  type: typeNodeToShape(arg.type),
14012
- required: arg.type.kind === import_graphql2.Kind.NON_NULL_TYPE
14098
+ required: arg.type.kind === import_graphql3.Kind.NON_NULL_TYPE
14013
14099
  })),
14014
14100
  provenance: "derived",
14015
14101
  framework
@@ -14017,7 +14103,7 @@ function deriveGraphqlContract(sdl, typeName, fieldName, framework) {
14017
14103
  }
14018
14104
  function findField(doc, typeName, fieldName) {
14019
14105
  for (const def of doc.definitions) {
14020
- if (def.kind !== import_graphql2.Kind.OBJECT_TYPE_DEFINITION && def.kind !== import_graphql2.Kind.OBJECT_TYPE_EXTENSION) {
14106
+ if (def.kind !== import_graphql3.Kind.OBJECT_TYPE_DEFINITION && def.kind !== import_graphql3.Kind.OBJECT_TYPE_EXTENSION) {
14021
14107
  continue;
14022
14108
  }
14023
14109
  const node = def;
@@ -14033,10 +14119,10 @@ function findField(doc, typeName, fieldName) {
14033
14119
  return null;
14034
14120
  }
14035
14121
  function typeNodeToShape(node) {
14036
- if (node.kind === import_graphql2.Kind.NON_NULL_TYPE) {
14122
+ if (node.kind === import_graphql3.Kind.NON_NULL_TYPE) {
14037
14123
  return typeNodeToShape(node.type);
14038
14124
  }
14039
- if (node.kind === import_graphql2.Kind.LIST_TYPE) {
14125
+ if (node.kind === import_graphql3.Kind.LIST_TYPE) {
14040
14126
  return { type: "array", items: typeNodeToShape(node.type) };
14041
14127
  }
14042
14128
  return scalarOrRef(node);
@@ -15457,10 +15543,10 @@ function readArrayLiteralText(node) {
15457
15543
  }
15458
15544
 
15459
15545
  // src/summaryIdentity.ts
15460
- var import_node_path8 = __toESM(require("path"), 1);
15546
+ var import_node_path9 = __toESM(require("path"), 1);
15461
15547
  var import_behavioral_ir7 = require("@suss/behavioral-ir");
15462
15548
  function workspaceRootFor(anchor) {
15463
- return namedPackageDirAbove(anchor) ?? import_node_path8.default.resolve(anchor);
15549
+ return namedPackageDirAbove(anchor) ?? import_node_path9.default.resolve(anchor);
15464
15550
  }
15465
15551
  function workspaceNameFor(root) {
15466
15552
  if (root === void 0) {
@@ -15470,7 +15556,7 @@ function workspaceNameFor(root) {
15470
15556
  if (dir !== null) {
15471
15557
  return packageNameAt(dir);
15472
15558
  }
15473
- const folder = import_node_path8.default.basename(import_node_path8.default.resolve(root));
15559
+ const folder = import_node_path9.default.basename(import_node_path9.default.resolve(root));
15474
15560
  return folder.length > 0 ? folder : null;
15475
15561
  }
15476
15562
  function nameSummaries(summaries, args) {
@@ -15485,10 +15571,10 @@ function nameSummaries(summaries, args) {
15485
15571
  (0, import_behavioral_ir7.linkCallsToSummaries)(summaries);
15486
15572
  }
15487
15573
  function relativeFile(file, projectRoot) {
15488
- if (projectRoot === void 0 || !import_node_path8.default.isAbsolute(file)) {
15574
+ if (projectRoot === void 0 || !import_node_path9.default.isAbsolute(file)) {
15489
15575
  return file;
15490
15576
  }
15491
- const relative = import_node_path8.default.relative(projectRoot, file);
15577
+ const relative = import_node_path9.default.relative(projectRoot, file);
15492
15578
  return relative.startsWith("..") ? file : relative;
15493
15579
  }
15494
15580
  function idFor(workspace, file, summary) {
@@ -15520,11 +15606,11 @@ function declineWhenRunFromSource(cacheDir) {
15520
15606
  }
15521
15607
 
15522
15608
  // src/workspacePatterns.ts
15523
- var import_node_fs3 = __toESM(require("fs"), 1);
15524
- var import_node_path9 = __toESM(require("path"), 1);
15609
+ var import_node_fs4 = __toESM(require("fs"), 1);
15610
+ var import_node_path10 = __toESM(require("path"), 1);
15525
15611
  function readJson(filePath) {
15526
15612
  try {
15527
- return JSON.parse(import_node_fs3.default.readFileSync(filePath, "utf8"));
15613
+ return JSON.parse(import_node_fs4.default.readFileSync(filePath, "utf8"));
15528
15614
  } catch {
15529
15615
  return void 0;
15530
15616
  }
@@ -15551,7 +15637,7 @@ function pnpmWorkspaceGlobs(yamlText) {
15551
15637
  return globs;
15552
15638
  }
15553
15639
  function workspaceGlobsAt(dir) {
15554
- const pkg = readJson(import_node_path9.default.join(dir, "package.json"));
15640
+ const pkg = readJson(import_node_path10.default.join(dir, "package.json"));
15555
15641
  if (typeof pkg === "object" && pkg !== null && "workspaces" in pkg) {
15556
15642
  const ws = pkg.workspaces;
15557
15643
  if (Array.isArray(ws)) {
@@ -15563,10 +15649,10 @@ function workspaceGlobsAt(dir) {
15563
15649
  );
15564
15650
  }
15565
15651
  }
15566
- const pnpmPath = import_node_path9.default.join(dir, "pnpm-workspace.yaml");
15567
- if (import_node_fs3.default.existsSync(pnpmPath)) {
15652
+ const pnpmPath = import_node_path10.default.join(dir, "pnpm-workspace.yaml");
15653
+ if (import_node_fs4.default.existsSync(pnpmPath)) {
15568
15654
  try {
15569
- return pnpmWorkspaceGlobs(import_node_fs3.default.readFileSync(pnpmPath, "utf8"));
15655
+ return pnpmWorkspaceGlobs(import_node_fs4.default.readFileSync(pnpmPath, "utf8"));
15570
15656
  } catch {
15571
15657
  return null;
15572
15658
  }
@@ -15575,14 +15661,14 @@ function workspaceGlobsAt(dir) {
15575
15661
  }
15576
15662
  function isDirectory(candidate) {
15577
15663
  try {
15578
- return import_node_fs3.default.statSync(candidate).isDirectory();
15664
+ return import_node_fs4.default.statSync(candidate).isDirectory();
15579
15665
  } catch {
15580
15666
  return false;
15581
15667
  }
15582
15668
  }
15583
15669
  function subdirectoriesOf(dir) {
15584
15670
  try {
15585
- return import_node_fs3.default.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name).filter((name) => !name.startsWith(".") && name !== "node_modules");
15671
+ return import_node_fs4.default.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name).filter((name) => !name.startsWith(".") && name !== "node_modules");
15586
15672
  } catch {
15587
15673
  return [];
15588
15674
  }
@@ -15600,13 +15686,13 @@ function directoriesMatchingGlob(root, glob) {
15600
15686
  for (const dir of current2) {
15601
15687
  for (const entry of subdirectoriesOf(dir)) {
15602
15688
  if (pattern.test(entry)) {
15603
- next.push(import_node_path9.default.join(dir, entry));
15689
+ next.push(import_node_path10.default.join(dir, entry));
15604
15690
  }
15605
15691
  }
15606
15692
  }
15607
15693
  } else {
15608
15694
  for (const dir of current2) {
15609
- next.push(import_node_path9.default.join(dir, segment));
15695
+ next.push(import_node_path10.default.join(dir, segment));
15610
15696
  }
15611
15697
  }
15612
15698
  current2 = next.filter(isDirectory);
@@ -15614,7 +15700,7 @@ function directoriesMatchingGlob(root, glob) {
15614
15700
  return current2;
15615
15701
  }
15616
15702
  function packageAt(dir) {
15617
- const packageJsonPath = import_node_path9.default.join(dir, "package.json");
15703
+ const packageJsonPath = import_node_path10.default.join(dir, "package.json");
15618
15704
  const pkg = readJson(packageJsonPath);
15619
15705
  if (typeof pkg === "object" && pkg !== null && typeof pkg.name === "string") {
15620
15706
  return { name: pkg.name, packageJsonPath };
@@ -15622,7 +15708,7 @@ function packageAt(dir) {
15622
15708
  return null;
15623
15709
  }
15624
15710
  function workspacePackagesFrom(anchor) {
15625
- let dir = import_node_path9.default.resolve(anchor);
15711
+ let dir = import_node_path10.default.resolve(anchor);
15626
15712
  for (; ; ) {
15627
15713
  const globs = workspaceGlobsAt(dir);
15628
15714
  if (globs !== null) {
@@ -15642,7 +15728,7 @@ function workspacePackagesFrom(anchor) {
15642
15728
  (a, b) => a.packageJsonPath.localeCompare(b.packageJsonPath)
15643
15729
  );
15644
15730
  }
15645
- const parent = import_node_path9.default.dirname(dir);
15731
+ const parent = import_node_path10.default.dirname(dir);
15646
15732
  if (parent === dir) {
15647
15733
  return [];
15648
15734
  }
@@ -16184,11 +16270,11 @@ function extractConsumerBinding(unit, pattern, pack, resolution) {
16184
16270
  return null;
16185
16271
  }
16186
16272
  const method = extractBindingMethod(binding, callSite, pack, resolution);
16187
- const path14 = extractBindingPath(binding, callSite, pack, resolution);
16273
+ const path15 = extractBindingPath(binding, callSite, pack, resolution);
16188
16274
  return (0, import_behavioral_ir8.restBinding)({
16189
16275
  transport: pack.protocol,
16190
16276
  method: method ?? null,
16191
- path: path14 ?? null,
16277
+ path: path15 ?? null,
16192
16278
  recognition: pack.name
16193
16279
  });
16194
16280
  }
@@ -16835,8 +16921,8 @@ function synthesizeCallerSummaries(wrapper, _project, options, resolution) {
16835
16921
  if (pathArg === void 0) {
16836
16922
  continue;
16837
16923
  }
16838
- const path14 = pathFromArgument(pathArg, resolution);
16839
- if (path14 === void 0) {
16924
+ const path15 = pathFromArgument(pathArg, resolution);
16925
+ if (path15 === void 0) {
16840
16926
  continue;
16841
16927
  }
16842
16928
  const callerFunc = enclosingFunction(callExpr);
@@ -16848,7 +16934,7 @@ function synthesizeCallerSummaries(wrapper, _project, options, resolution) {
16848
16934
  continue;
16849
16935
  }
16850
16936
  seen.add(dedupKey);
16851
- out.push(buildCallerSummary(wrapper, callerFunc, callExpr, path14, options));
16937
+ out.push(buildCallerSummary(wrapper, callerFunc, callExpr, path15, options));
16852
16938
  }
16853
16939
  return out;
16854
16940
  }
@@ -16905,7 +16991,7 @@ function callerName(func) {
16905
16991
  }
16906
16992
  return "anonymous";
16907
16993
  }
16908
- function buildCallerSummary(wrapper, callerFunc, callExpr, path14, options) {
16994
+ function buildCallerSummary(wrapper, callerFunc, callExpr, path15, options) {
16909
16995
  const wrapperBinding = wrapper.summary.identity.boundaryBinding;
16910
16996
  const wrapperRest = wrapperBinding?.semantics.name === "rest" ? wrapperBinding.semantics : null;
16911
16997
  const syntheticPack = {
@@ -16937,7 +17023,7 @@ function buildCallerSummary(wrapper, callerFunc, callExpr, path14, options) {
16937
17023
  raw.boundaryBinding = (0, import_behavioral_ir8.restBinding)({
16938
17024
  transport: wrapperBinding?.transport ?? "http",
16939
17025
  method: wrapperRest?.method ?? null,
16940
- path: path14,
17026
+ path: path15,
16941
17027
  recognition: wrapperBinding?.recognition ?? "unknown"
16942
17028
  });
16943
17029
  const summary = (0, import_extractor11.assembleSummary)(raw, options);
@@ -16995,7 +17081,7 @@ function createTypeScriptAdapter(suppliedConfig) {
16995
17081
  ...suppliedConfig,
16996
17082
  frameworks: expandWorkspacePatterns(
16997
17083
  suppliedConfig.frameworks,
16998
- suppliedConfig.projectRoot ?? (suppliedConfig.tsConfigFilePath !== void 0 ? import_node_path10.default.dirname(suppliedConfig.tsConfigFilePath) : void 0)
17084
+ suppliedConfig.projectRoot ?? (suppliedConfig.tsConfigFilePath !== void 0 ? import_node_path11.default.dirname(suppliedConfig.tsConfigFilePath) : void 0)
16999
17085
  )
17000
17086
  };
17001
17087
  const project = config.project ?? new import_ts_morph67.Project(
@@ -17004,11 +17090,11 @@ function createTypeScriptAdapter(suppliedConfig) {
17004
17090
  skipAddingFilesFromTsConfig: true
17005
17091
  } : { skipAddingFilesFromTsConfig: true }
17006
17092
  );
17007
- const runRoot = config.projectRoot ?? (config.tsConfigFilePath !== void 0 ? workspaceRootFor(import_node_path10.default.dirname(config.tsConfigFilePath)) : void 0);
17093
+ const runRoot = config.projectRoot ?? (config.tsConfigFilePath !== void 0 ? workspaceRootFor(import_node_path11.default.dirname(config.tsConfigFilePath)) : void 0);
17008
17094
  let lazyBootstrapped = false;
17009
17095
  let projectFileSet;
17010
17096
  const cacheDir = declineWhenRunFromSource(
17011
- config.cacheDir === null ? null : config.cacheDir ?? (config.tsConfigFilePath !== void 0 ? import_node_path10.default.join(import_node_path10.default.dirname(config.tsConfigFilePath), ".suss", "cache") : null)
17097
+ config.cacheDir === null ? null : config.cacheDir ?? (config.tsConfigFilePath !== void 0 ? import_node_path11.default.join(import_node_path11.default.dirname(config.tsConfigFilePath), ".suss", "cache") : null)
17012
17098
  );
17013
17099
  const cache = (0, import_extractor11.createCacheLayer)(cacheDir);
17014
17100
  const packsDigest = `${computeAdapterPacksDigest(
@@ -17712,8 +17798,8 @@ function buildSubUnitSummary(subUnit, parent, invocationRecognizers, accessRecog
17712
17798
  }
17713
17799
 
17714
17800
  // src/bootstrap/noTsconfigProject.ts
17715
- var import_node_fs4 = __toESM(require("fs"), 1);
17716
- var import_node_path11 = __toESM(require("path"), 1);
17801
+ var import_node_fs5 = __toESM(require("fs"), 1);
17802
+ var import_node_path12 = __toESM(require("path"), 1);
17717
17803
  var import_ts_morph68 = require("ts-morph");
17718
17804
  var SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([
17719
17805
  ".ts",
@@ -17744,7 +17830,7 @@ function findSourceFiles(rootDir, depth = 0) {
17744
17830
  const found = [];
17745
17831
  let entries;
17746
17832
  try {
17747
- entries = import_node_fs4.default.readdirSync(rootDir, { withFileTypes: true });
17833
+ entries = import_node_fs5.default.readdirSync(rootDir, { withFileTypes: true });
17748
17834
  } catch {
17749
17835
  return [];
17750
17836
  }
@@ -17752,10 +17838,10 @@ function findSourceFiles(rootDir, depth = 0) {
17752
17838
  if (entry.name.startsWith(".") || SKIP_DIRECTORIES.has(entry.name)) {
17753
17839
  continue;
17754
17840
  }
17755
- const full = import_node_path11.default.join(rootDir, entry.name);
17841
+ const full = import_node_path12.default.join(rootDir, entry.name);
17756
17842
  if (entry.isDirectory()) {
17757
17843
  found.push(...findSourceFiles(full, depth + 1));
17758
- } else if (SOURCE_EXTENSIONS.has(import_node_path11.default.extname(entry.name)) && !entry.name.endsWith(".d.ts")) {
17844
+ } else if (SOURCE_EXTENSIONS.has(import_node_path12.default.extname(entry.name)) && !entry.name.endsWith(".d.ts")) {
17759
17845
  found.push(full);
17760
17846
  }
17761
17847
  }
@@ -17790,15 +17876,15 @@ function createProjectWithoutTsconfig(rootDir) {
17790
17876
  return { project, files };
17791
17877
  }
17792
17878
  function findNearestTsconfig(startDir) {
17793
- let dir = import_node_path11.default.resolve(startDir);
17879
+ let dir = import_node_path12.default.resolve(startDir);
17794
17880
  while (true) {
17795
17881
  for (const name of ["tsconfig.json", "jsconfig.json"]) {
17796
- const candidate = import_node_path11.default.join(dir, name);
17797
- if (import_node_fs4.default.existsSync(candidate)) {
17882
+ const candidate = import_node_path12.default.join(dir, name);
17883
+ if (import_node_fs5.default.existsSync(candidate)) {
17798
17884
  return candidate;
17799
17885
  }
17800
17886
  }
17801
- const parent = import_node_path11.default.dirname(dir);
17887
+ const parent = import_node_path12.default.dirname(dir);
17802
17888
  if (parent === dir) {
17803
17889
  return null;
17804
17890
  }
@@ -17807,7 +17893,7 @@ function findNearestTsconfig(startDir) {
17807
17893
  }
17808
17894
 
17809
17895
  // src/facts/why.ts
17810
- var import_node_path12 = __toESM(require("path"), 1);
17896
+ var import_node_path13 = __toESM(require("path"), 1);
17811
17897
  var import_ts_morph69 = require("ts-morph");
17812
17898
  var import_resolution7 = require("@suss/resolution");
17813
17899
  var JS_PHRASES = {
@@ -17820,7 +17906,7 @@ var TypeScriptWhySession = class {
17820
17906
  store;
17821
17907
  root;
17822
17908
  constructor(options) {
17823
- this.root = import_node_path12.default.resolve(options.dir);
17909
+ this.root = import_node_path13.default.resolve(options.dir);
17824
17910
  const tsconfig = findNearestTsconfig(this.root);
17825
17911
  this.project = tsconfig === null ? createProjectWithoutTsconfig(this.root).project : new import_ts_morph69.Project({ tsConfigFilePath: tsconfig });
17826
17912
  this.store = new ResolutionStore();
@@ -17909,7 +17995,7 @@ var TypeScriptWhySession = class {
17909
17995
  };
17910
17996
  }
17911
17997
  sourceFileAt(file) {
17912
- const absolute = import_node_path12.default.resolve(this.root, file);
17998
+ const absolute = import_node_path13.default.resolve(this.root, file);
17913
17999
  const loaded = this.project.getSourceFile(absolute);
17914
18000
  if (loaded !== void 0) {
17915
18001
  return loaded;
@@ -17923,7 +18009,7 @@ var TypeScriptWhySession = class {
17923
18009
  /** A module key: a file path said relative to the root, or a package name. */
17924
18010
  displayPath(key) {
17925
18011
  if (key.startsWith(this.root)) {
17926
- return import_node_path12.default.relative(this.root, key);
18012
+ return import_node_path13.default.relative(this.root, key);
17927
18013
  }
17928
18014
  return key;
17929
18015
  }
@@ -17952,7 +18038,7 @@ function displayNameOf(node) {
17952
18038
  }
17953
18039
 
17954
18040
  // src/stubEvidence.ts
17955
- var import_node_path13 = __toESM(require("path"), 1);
18041
+ var import_node_path14 = __toESM(require("path"), 1);
17956
18042
  var import_ts_morph70 = require("ts-morph");
17957
18043
  function stubEvidenceIn(project, packageName, root) {
17958
18044
  const resolution = new ResolutionStore();
@@ -17968,7 +18054,7 @@ function stubEvidenceIn(project, packageName, root) {
17968
18054
  calls: []
17969
18055
  };
17970
18056
  entry.calls.push({
17971
- file: import_node_path13.default.relative(root, sourceFile.getFilePath()).split(import_node_path13.default.sep).join("/"),
18057
+ file: import_node_path14.default.relative(root, sourceFile.getFilePath()).split(import_node_path14.default.sep).join("/"),
17972
18058
  line: one.call.getStartLineNumber(),
17973
18059
  args: one.call.getArguments().map((arg) => effectArgOf(arg))
17974
18060
  });
@@ -17983,7 +18069,7 @@ function stubEvidence(options) {
17983
18069
  const project = new import_ts_morph70.Project(
17984
18070
  options.tsConfigFilePath !== void 0 ? { tsConfigFilePath: options.tsConfigFilePath } : { compilerOptions: { allowJs: true } }
17985
18071
  );
17986
- const root = options.tsConfigFilePath !== void 0 ? import_node_path13.default.dirname(options.tsConfigFilePath) : import_node_path13.default.resolve(options.directory ?? process.cwd());
18072
+ const root = options.tsConfigFilePath !== void 0 ? import_node_path14.default.dirname(options.tsConfigFilePath) : import_node_path14.default.resolve(options.directory ?? process.cwd());
17987
18073
  if (options.tsConfigFilePath === void 0) {
17988
18074
  project.addSourceFilesAtPaths([
17989
18075
  `${root}/**/*.{ts,tsx,js,jsx}`,