@suss/adapter-typescript 0.22.3 → 0.23.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 CHANGED
@@ -31,6 +31,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
33
  ADAPTER_VERSION: () => ADAPTER_VERSION,
34
+ GENERIC_TERMINALS: () => GENERIC_TERMINALS,
35
+ NO_BARRIERS: () => NO_BARRIERS,
34
36
  ResolutionStore: () => ResolutionStore,
35
37
  TypeScriptWhySession: () => TypeScriptWhySession,
36
38
  accessContextFor: () => accessContextFor,
@@ -51,6 +53,7 @@ __export(index_exports, {
51
53
  findNearestTsconfig: () => findNearestTsconfig,
52
54
  findTerminals: () => findTerminals,
53
55
  functionTargetOf: () => functionTargetOf,
56
+ hasBody: () => hasBody,
54
57
  importDeclarationsOf: () => importDeclarationsOf,
55
58
  importedNamesOf: () => importedNamesOf,
56
59
  importedRootsOf: () => importedRootsOf,
@@ -66,6 +69,7 @@ __export(index_exports, {
66
69
  resolveAliasedSymbol: () => resolveAliasedSymbol,
67
70
  resolveSubject: () => resolveSubject,
68
71
  rootIdentifier: () => rootIdentifier,
72
+ startsItsOwnScope: () => startsItsOwnScope,
69
73
  stubEvidence: () => stubEvidence,
70
74
  stubEvidenceIn: () => stubEvidenceIn,
71
75
  workspaceRootFor: () => workspaceRootFor
@@ -74,13 +78,13 @@ module.exports = __toCommonJS(index_exports);
74
78
 
75
79
  // src/adapter.ts
76
80
  var import_node_path10 = __toESM(require("path"), 1);
77
- var import_ts_morph66 = require("ts-morph");
81
+ var import_ts_morph67 = require("ts-morph");
78
82
  var import_behavioral_ir8 = require("@suss/behavioral-ir");
79
83
  var import_datalog6 = require("@suss/datalog");
80
84
  var import_extractor11 = require("@suss/extractor");
81
85
 
82
86
  // src/assembly.ts
83
- var import_ts_morph54 = require("ts-morph");
87
+ var import_ts_morph55 = require("ts-morph");
84
88
  var import_extractor5 = require("@suss/extractor");
85
89
 
86
90
  // src/conditions.ts
@@ -3732,6 +3736,18 @@ var ResolutionStore = class {
3732
3736
  const target = factKeyOf(value);
3733
3737
  return this.askAbout(target, "wanted", () => this.lookupObject(target));
3734
3738
  }
3739
+ /**
3740
+ * The function a call returns: `app.use(requireCaller(config))`
3741
+ * registers what the factory gives back. A separate question from
3742
+ * `resolveCallable`, which keeps a call unresolved on purpose so an
3743
+ * unwrapping answer wins; this one is asked only after that has
3744
+ * declined. Two returned functions give null, like every other
3745
+ * single-answer question here.
3746
+ */
3747
+ resolveReturnedCallable(call) {
3748
+ const target = factKeyOf(call);
3749
+ return this.askAbout(target, "wanted", () => this.lookupReturned(target));
3750
+ }
3735
3751
  /**
3736
3752
  * For a value that is neither a function nor an object, such as a
3737
3753
  * GraphQL document kept in a constant in another file.
@@ -4175,6 +4191,21 @@ var ResolutionStore = class {
4175
4191
  }
4176
4192
  return [...candidates][0];
4177
4193
  }
4194
+ lookupReturned(call) {
4195
+ this.derive();
4196
+ const candidates = /* @__PURE__ */ new Set();
4197
+ for (const target of this.answersFor("wantedGivesBack", nodeId(call))) {
4198
+ const node = this.table.byId.get(target);
4199
+ if (node === void 0 || !isFunctionRoot(node)) {
4200
+ continue;
4201
+ }
4202
+ candidates.add(node);
4203
+ }
4204
+ if (candidates.size !== 1) {
4205
+ return null;
4206
+ }
4207
+ return [...candidates][0];
4208
+ }
4178
4209
  /**
4179
4210
  * Two candidates give null, since ambiguity is nothing. The value
4180
4211
  * itself is never a result either, or an identifier whose chain went
@@ -5282,7 +5313,27 @@ function functionValueOf(value, resolution) {
5282
5313
  return null;
5283
5314
  }
5284
5315
  const resolved = resolution.resolveCallable(written);
5285
- return resolved === null ? null : toFunctionRoot(resolved);
5316
+ if (resolved !== null) {
5317
+ return toFunctionRoot(resolved);
5318
+ }
5319
+ if (!import_ts_morph19.Node.isCallExpression(written)) {
5320
+ return null;
5321
+ }
5322
+ const returned = resolution.resolveReturnedCallable(written);
5323
+ return returned === null ? null : toFunctionRoot(returned);
5324
+ }
5325
+ function propertyNameOf(property) {
5326
+ if (import_ts_morph19.Node.isPropertyAssignment(property) || import_ts_morph19.Node.isShorthandPropertyAssignment(property) || import_ts_morph19.Node.isMethodDeclaration(property)) {
5327
+ return property.getName();
5328
+ }
5329
+ return null;
5330
+ }
5331
+ function propertyFunctionOf(property, resolution) {
5332
+ if (import_ts_morph19.Node.isMethodDeclaration(property)) {
5333
+ return property;
5334
+ }
5335
+ const held = propertyValueOf(property);
5336
+ return held === null ? null : functionValueOf(held, resolution);
5286
5337
  }
5287
5338
  function objectLiteralOf(value, resolution) {
5288
5339
  return literalValueOf(
@@ -8742,7 +8793,7 @@ function discoverResolverMaps(sourceFile, match, kind, resolution) {
8742
8793
  }
8743
8794
  const schemaSdl = extractTypeDefsSdl(config, store);
8744
8795
  for (const typeProp of propertiesOf(resolversObj, store)) {
8745
- const typeName = resolverPropertyName(typeProp);
8796
+ const typeName = propertyNameOf(typeProp);
8746
8797
  if (typeName === null || excludeTypes.has(typeName)) {
8747
8798
  continue;
8748
8799
  }
@@ -8751,11 +8802,11 @@ function discoverResolverMaps(sourceFile, match, kind, resolution) {
8751
8802
  continue;
8752
8803
  }
8753
8804
  for (const fieldProp of propertiesOf(typeObj, store)) {
8754
- const fieldName = resolverPropertyName(fieldProp);
8805
+ const fieldName = propertyNameOf(fieldProp);
8755
8806
  if (fieldName === null) {
8756
8807
  continue;
8757
8808
  }
8758
- const fn = resolverPropertyFunction(fieldProp, store);
8809
+ const fn = propertyFunctionOf(fieldProp, store);
8759
8810
  if (fn === null) {
8760
8811
  continue;
8761
8812
  }
@@ -8819,22 +8870,6 @@ function writtenSdl(expr) {
8819
8870
  }
8820
8871
  return null;
8821
8872
  }
8822
- function resolverPropertyName(prop) {
8823
- if (import_ts_morph38.Node.isPropertyAssignment(prop) || import_ts_morph38.Node.isMethodDeclaration(prop)) {
8824
- return prop.getName();
8825
- }
8826
- if (import_ts_morph38.Node.isShorthandPropertyAssignment(prop)) {
8827
- return prop.getName();
8828
- }
8829
- return null;
8830
- }
8831
- function resolverPropertyFunction(prop, resolution) {
8832
- if (import_ts_morph38.Node.isMethodDeclaration(prop)) {
8833
- return prop;
8834
- }
8835
- const held = propertyValueOf(prop);
8836
- return held === null ? null : functionValueOf(held, resolution);
8837
- }
8838
8873
 
8839
8874
  // src/discovery/index.ts
8840
8875
  function runPattern(sourceFile, pattern, resolution, mountPrefixes, expandedElsewhere) {
@@ -10146,7 +10181,7 @@ function enclosingStatementLine(node) {
10146
10181
  }
10147
10182
 
10148
10183
  // src/terminals/index.ts
10149
- var import_ts_morph53 = require("ts-morph");
10184
+ var import_ts_morph54 = require("ts-morph");
10150
10185
 
10151
10186
  // src/terminals/continuation.ts
10152
10187
  var import_ts_morph45 = require("ts-morph");
@@ -10218,14 +10253,15 @@ function tryMatchParameterCall(node, func, pattern, match) {
10218
10253
  }
10219
10254
 
10220
10255
  // src/terminals/extract.ts
10221
- var import_ts_morph47 = require("ts-morph");
10256
+ var import_ts_morph48 = require("ts-morph");
10222
10257
  var import_values5 = require("@suss/values");
10223
10258
 
10224
10259
  // src/shapes/shapes.ts
10225
- var import_ts_morph46 = require("ts-morph");
10260
+ var import_ts_morph47 = require("ts-morph");
10226
10261
 
10227
10262
  // src/shapes/typeShapes.ts
10228
10263
  var import_node_crypto = require("crypto");
10264
+ var import_ts_morph46 = require("ts-morph");
10229
10265
 
10230
10266
  // src/shapes/definitions.ts
10231
10267
  var current = null;
@@ -10387,7 +10423,7 @@ function typeToShape(type, ctx) {
10387
10423
  if (type.isEnum() || type.isEnumLiteral()) {
10388
10424
  return enumToShape(type, ctx);
10389
10425
  }
10390
- const text = type.getText(ctx.enclosing);
10426
+ const text = printedTypeName(type, ctx);
10391
10427
  if (text && text.length > 0 && text !== "__type") {
10392
10428
  return { type: "ref", name: text };
10393
10429
  }
@@ -10435,8 +10471,7 @@ function intersectionToShape(type, ctx) {
10435
10471
  if (nonRecords.length === 1 && records.length === 0) {
10436
10472
  return nonRecords[0];
10437
10473
  }
10438
- const text = type.getText(ctx.enclosing);
10439
- return { type: "ref", name: text };
10474
+ return { type: "ref", name: printedTypeName(type, ctx) };
10440
10475
  }
10441
10476
  function objectToShape(type, ctx) {
10442
10477
  const key = typeKey(type, ctx.enclosing);
@@ -10496,7 +10531,7 @@ function opaqueNamedRef(type, ctx) {
10496
10531
  if (!OPAQUE_NAMED_TYPES.has(name)) {
10497
10532
  return null;
10498
10533
  }
10499
- const text = type.getText(ctx.enclosing);
10534
+ const text = printedTypeName(type, ctx);
10500
10535
  return { type: "ref", name: text && text.length > 0 ? text : name };
10501
10536
  }
10502
10537
  function outsideProjectRef(type, ctx) {
@@ -10577,6 +10612,12 @@ function refFromType(type, ctx) {
10577
10612
  }
10578
10613
  return { type: "ref", name: withoutImportQualifiers(type.getText()) };
10579
10614
  }
10615
+ var PRINTED_NAME_FLAGS = import_ts_morph46.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope | import_ts_morph46.TypeFormatFlags.UseTypeOfFunction | import_ts_morph46.TypeFormatFlags.NoTruncation | import_ts_morph46.TypeFormatFlags.WriteTypeArgumentsOfSignature;
10616
+ function printedTypeName(type, ctx) {
10617
+ return withoutImportQualifiers(
10618
+ type.getText(ctx.enclosing, PRINTED_NAME_FLAGS)
10619
+ );
10620
+ }
10580
10621
  var IMPORT_QUALIFIER = /import\("[^"]*"\)\./g;
10581
10622
  var withoutImportQualifiers = (text) => text.replace(IMPORT_QUALIFIER, "");
10582
10623
  function declaringFileOf(symbol) {
@@ -10681,60 +10722,60 @@ function extractShapeWithArguments(node, substitutions) {
10681
10722
  }
10682
10723
  function extractShapeInner(node) {
10683
10724
  const unwrapped2 = peelSyntax(node);
10684
- if (boundArguments !== null && import_ts_morph46.Node.isIdentifier(unwrapped2)) {
10725
+ if (boundArguments !== null && import_ts_morph47.Node.isIdentifier(unwrapped2)) {
10685
10726
  const argument = boundArguments.get(unwrapped2.getText());
10686
10727
  if (argument !== void 0 && argument !== unwrapped2) {
10687
10728
  return extractShape(argument);
10688
10729
  }
10689
10730
  }
10690
- if (import_ts_morph46.Node.isObjectLiteralExpression(unwrapped2)) {
10731
+ if (import_ts_morph47.Node.isObjectLiteralExpression(unwrapped2)) {
10691
10732
  return shapeFromObjectLiteral(unwrapped2);
10692
10733
  }
10693
- if (import_ts_morph46.Node.isArrayLiteralExpression(unwrapped2)) {
10734
+ if (import_ts_morph47.Node.isArrayLiteralExpression(unwrapped2)) {
10694
10735
  return shapeFromArrayLiteral(unwrapped2);
10695
10736
  }
10696
- if (import_ts_morph46.Node.isStringLiteral(unwrapped2) || import_ts_morph46.Node.isNoSubstitutionTemplateLiteral(unwrapped2)) {
10737
+ if (import_ts_morph47.Node.isStringLiteral(unwrapped2) || import_ts_morph47.Node.isNoSubstitutionTemplateLiteral(unwrapped2)) {
10697
10738
  return { type: "literal", value: unwrapped2.getLiteralValue() };
10698
10739
  }
10699
- if (import_ts_morph46.Node.isTemplateExpression(unwrapped2)) {
10740
+ if (import_ts_morph47.Node.isTemplateExpression(unwrapped2)) {
10700
10741
  return { type: "text" };
10701
10742
  }
10702
- if (import_ts_morph46.Node.isNumericLiteral(unwrapped2)) {
10743
+ if (import_ts_morph47.Node.isNumericLiteral(unwrapped2)) {
10703
10744
  return numericLiteralShape(
10704
10745
  unwrapped2.getLiteralValue(),
10705
10746
  unwrapped2.getText()
10706
10747
  );
10707
10748
  }
10708
- if (import_ts_morph46.Node.isPrefixUnaryExpression(unwrapped2)) {
10749
+ if (import_ts_morph47.Node.isPrefixUnaryExpression(unwrapped2)) {
10709
10750
  const op = unwrapped2.getOperatorToken();
10710
- if (op === import_ts_morph46.SyntaxKind.MinusToken || op === import_ts_morph46.SyntaxKind.PlusToken) {
10751
+ if (op === import_ts_morph47.SyntaxKind.MinusToken || op === import_ts_morph47.SyntaxKind.PlusToken) {
10711
10752
  const inner = unwrapped2.getOperand();
10712
- if (import_ts_morph46.Node.isNumericLiteral(inner)) {
10753
+ if (import_ts_morph47.Node.isNumericLiteral(inner)) {
10713
10754
  const v3 = inner.getLiteralValue();
10714
- const signed = op === import_ts_morph46.SyntaxKind.MinusToken ? -v3 : v3;
10755
+ const signed = op === import_ts_morph47.SyntaxKind.MinusToken ? -v3 : v3;
10715
10756
  const rawBody = inner.getText();
10716
- const raw = op === import_ts_morph46.SyntaxKind.MinusToken ? `-${rawBody}` : rawBody;
10757
+ const raw = op === import_ts_morph47.SyntaxKind.MinusToken ? `-${rawBody}` : rawBody;
10717
10758
  return numericLiteralShape(signed, raw);
10718
10759
  }
10719
10760
  }
10720
10761
  }
10721
- if (import_ts_morph46.Node.isBigIntLiteral(unwrapped2)) {
10762
+ if (import_ts_morph47.Node.isBigIntLiteral(unwrapped2)) {
10722
10763
  return { type: "ref", name: "bigint" };
10723
10764
  }
10724
10765
  const kind = unwrapped2.getKind();
10725
- if (kind === import_ts_morph46.SyntaxKind.TrueKeyword) {
10766
+ if (kind === import_ts_morph47.SyntaxKind.TrueKeyword) {
10726
10767
  return { type: "literal", value: true };
10727
10768
  }
10728
- if (kind === import_ts_morph46.SyntaxKind.FalseKeyword) {
10769
+ if (kind === import_ts_morph47.SyntaxKind.FalseKeyword) {
10729
10770
  return { type: "literal", value: false };
10730
10771
  }
10731
- if (kind === import_ts_morph46.SyntaxKind.NullKeyword) {
10772
+ if (kind === import_ts_morph47.SyntaxKind.NullKeyword) {
10732
10773
  return { type: "null" };
10733
10774
  }
10734
- if (import_ts_morph46.Node.isIdentifier(unwrapped2) && unwrapped2.getText() === "undefined") {
10775
+ if (import_ts_morph47.Node.isIdentifier(unwrapped2) && unwrapped2.getText() === "undefined") {
10735
10776
  return { type: "undefined" };
10736
10777
  }
10737
- if (import_ts_morph46.Node.isConditionalExpression(unwrapped2)) {
10778
+ if (import_ts_morph47.Node.isConditionalExpression(unwrapped2)) {
10738
10779
  const whenTrue = extractShape(unwrapped2.getWhenTrue());
10739
10780
  const whenFalse = extractShape(unwrapped2.getWhenFalse());
10740
10781
  const variants = [];
@@ -10765,7 +10806,7 @@ function shapeFromArrayLiteral(arr) {
10765
10806
  }
10766
10807
  const shapes = [];
10767
10808
  for (const el of elements) {
10768
- if (import_ts_morph46.Node.isSpreadElement(el)) {
10809
+ if (import_ts_morph47.Node.isSpreadElement(el)) {
10769
10810
  const inner = el.getExpression();
10770
10811
  const innerShape = extractShape(inner);
10771
10812
  if (innerShape?.type === "array") {
@@ -10784,7 +10825,7 @@ function shapeFromObjectLiteral(obj) {
10784
10825
  const properties = {};
10785
10826
  const unresolvedSpreads = [];
10786
10827
  for (const prop of obj.getProperties()) {
10787
- if (import_ts_morph46.Node.isPropertyAssignment(prop)) {
10828
+ if (import_ts_morph47.Node.isPropertyAssignment(prop)) {
10788
10829
  const name = propertyName2(prop);
10789
10830
  if (name === null) {
10790
10831
  continue;
@@ -10800,7 +10841,7 @@ function shapeFromObjectLiteral(obj) {
10800
10841
  };
10801
10842
  continue;
10802
10843
  }
10803
- if (import_ts_morph46.Node.isShorthandPropertyAssignment(prop)) {
10844
+ if (import_ts_morph47.Node.isShorthandPropertyAssignment(prop)) {
10804
10845
  const name = prop.getName();
10805
10846
  const valueExpr = prop.getNameNode();
10806
10847
  properties[name] = extractShape(valueExpr) ?? {
@@ -10809,7 +10850,7 @@ function shapeFromObjectLiteral(obj) {
10809
10850
  };
10810
10851
  continue;
10811
10852
  }
10812
- if (import_ts_morph46.Node.isSpreadAssignment(prop)) {
10853
+ if (import_ts_morph47.Node.isSpreadAssignment(prop)) {
10813
10854
  const expr = prop.getExpression();
10814
10855
  const spreadShape = extractShape(expr);
10815
10856
  if (spreadShape?.type === "record") {
@@ -10828,7 +10869,7 @@ function shapeFromObjectLiteral(obj) {
10828
10869
  }
10829
10870
  function propertyName2(prop) {
10830
10871
  const nameNode = prop.getNameNode();
10831
- if (import_ts_morph46.Node.isIdentifier(nameNode) || import_ts_morph46.Node.isStringLiteral(nameNode) || import_ts_morph46.Node.isNoSubstitutionTemplateLiteral(nameNode) || import_ts_morph46.Node.isNumericLiteral(nameNode)) {
10872
+ if (import_ts_morph47.Node.isIdentifier(nameNode) || import_ts_morph47.Node.isStringLiteral(nameNode) || import_ts_morph47.Node.isNoSubstitutionTemplateLiteral(nameNode) || import_ts_morph47.Node.isNumericLiteral(nameNode)) {
10832
10873
  return nameNode.getText().replace(/^["']|["']$/g, "");
10833
10874
  }
10834
10875
  return null;
@@ -10859,15 +10900,15 @@ function unwrapAs(node) {
10859
10900
  }
10860
10901
  function unwrapJsonStringify(node) {
10861
10902
  const outer = unwrapAs(node);
10862
- if (!import_ts_morph47.Node.isCallExpression(outer)) {
10903
+ if (!import_ts_morph48.Node.isCallExpression(outer)) {
10863
10904
  return node;
10864
10905
  }
10865
10906
  const callee = outer.getExpression();
10866
- if (!import_ts_morph47.Node.isPropertyAccessExpression(callee) || callee.getName() !== "stringify") {
10907
+ if (!import_ts_morph48.Node.isPropertyAccessExpression(callee) || callee.getName() !== "stringify") {
10867
10908
  return node;
10868
10909
  }
10869
10910
  const receiver = callee.getExpression();
10870
- if (!import_ts_morph47.Node.isIdentifier(receiver) || receiver.getText() !== "JSON") {
10911
+ if (!import_ts_morph48.Node.isIdentifier(receiver) || receiver.getText() !== "JSON") {
10871
10912
  return node;
10872
10913
  }
10873
10914
  const args = outer.getArguments();
@@ -10877,7 +10918,7 @@ function unwrapJsonStringify(node) {
10877
10918
  return unwrapAs(args[0]);
10878
10919
  }
10879
10920
  function substituted(value, ctx) {
10880
- if (ctx.substitutions === void 0 || !import_ts_morph47.Node.isIdentifier(value)) {
10921
+ if (ctx.substitutions === void 0 || !import_ts_morph48.Node.isIdentifier(value)) {
10881
10922
  return value;
10882
10923
  }
10883
10924
  return ctx.substitutions.get(value.getText()) ?? value;
@@ -10921,10 +10962,10 @@ function statusFromProperty(obj, name, ctx) {
10921
10962
  if (prop === void 0) {
10922
10963
  return null;
10923
10964
  }
10924
- if (import_ts_morph47.Node.isShorthandPropertyAssignment(prop)) {
10965
+ if (import_ts_morph48.Node.isShorthandPropertyAssignment(prop)) {
10925
10966
  return { type: "dynamic", sourceText: prop.getName() };
10926
10967
  }
10927
- if (!import_ts_morph47.Node.isPropertyAssignment(prop)) {
10968
+ if (!import_ts_morph48.Node.isPropertyAssignment(prop)) {
10928
10969
  return null;
10929
10970
  }
10930
10971
  const value = prop.getInitializer();
@@ -10947,7 +10988,7 @@ function extractStatusCodeFromRule(ctx) {
10947
10988
  return null;
10948
10989
  }
10949
10990
  const first = ctx.throwCallArgs?.[0];
10950
- if (first !== void 0 && import_ts_morph47.Node.isNumericLiteral(first)) {
10991
+ if (first !== void 0 && import_ts_morph48.Node.isNumericLiteral(first)) {
10951
10992
  const value = first.getLiteralValue();
10952
10993
  if (value >= 100 && value <= 599) {
10953
10994
  return { type: "literal", value };
@@ -10960,7 +11001,7 @@ function extractStatusCodeFromRule(ctx) {
10960
11001
  return null;
10961
11002
  }
10962
11003
  const arg = ctx.throwCallArgs[sc.position];
10963
- if (arg === void 0 || !import_ts_morph47.Node.isNewExpression(arg)) {
11004
+ if (arg === void 0 || !import_ts_morph48.Node.isNewExpression(arg)) {
10964
11005
  return null;
10965
11006
  }
10966
11007
  const ctorText = arg.getExpression().getText();
@@ -10969,7 +11010,7 @@ function extractStatusCodeFromRule(ctx) {
10969
11010
  if (sc.from === "argumentProperty") {
10970
11011
  const args = ctx.throwCallArgs ?? ctx.calls?.[0]?.getArguments();
10971
11012
  const arg = args?.[sc.position];
10972
- if (arg === void 0 || !import_ts_morph47.Node.isObjectLiteralExpression(arg)) {
11013
+ if (arg === void 0 || !import_ts_morph48.Node.isObjectLiteralExpression(arg)) {
10973
11014
  return null;
10974
11015
  }
10975
11016
  return statusFromProperty(arg, sc.name, ctx);
@@ -10979,8 +11020,8 @@ function extractStatusCodeFromRule(ctx) {
10979
11020
  return null;
10980
11021
  }
10981
11022
  for (const prop of ctx.returnedObj.getProperties()) {
10982
- if (!import_ts_morph47.Node.isPropertyAssignment(prop)) {
10983
- if (import_ts_morph47.Node.isShorthandPropertyAssignment(prop)) {
11023
+ if (!import_ts_morph48.Node.isPropertyAssignment(prop)) {
11024
+ if (import_ts_morph48.Node.isShorthandPropertyAssignment(prop)) {
10984
11025
  if (prop.getName() === sc.name) {
10985
11026
  const resolved = ctx.substitutions?.get(prop.getName());
10986
11027
  if (resolved !== void 0) {
@@ -11038,8 +11079,8 @@ function extractBody(ctx) {
11038
11079
  return null;
11039
11080
  }
11040
11081
  for (const prop of ctx.returnedObj.getProperties()) {
11041
- if (!import_ts_morph47.Node.isPropertyAssignment(prop)) {
11042
- if (import_ts_morph47.Node.isShorthandPropertyAssignment(prop)) {
11082
+ if (!import_ts_morph48.Node.isPropertyAssignment(prop)) {
11083
+ if (import_ts_morph48.Node.isShorthandPropertyAssignment(prop)) {
11043
11084
  if (prop.getName() === b.name) {
11044
11085
  const resolved = ctx.substitutions?.get(prop.getName());
11045
11086
  if (resolved !== void 0) {
@@ -11094,16 +11135,16 @@ function extractBody(ctx) {
11094
11135
  }
11095
11136
 
11096
11137
  // src/terminals/jsx.ts
11097
- var import_ts_morph48 = require("ts-morph");
11138
+ var import_ts_morph49 = require("ts-morph");
11098
11139
  function tryMatchJsxReturn(node, pattern) {
11099
11140
  let expr;
11100
11141
  let source;
11101
- if (import_ts_morph48.Node.isReturnStatement(node)) {
11142
+ if (import_ts_morph49.Node.isReturnStatement(node)) {
11102
11143
  expr = node.getExpression();
11103
11144
  source = node;
11104
- } else if (import_ts_morph48.Node.isArrowFunction(node)) {
11145
+ } else if (import_ts_morph49.Node.isArrowFunction(node)) {
11105
11146
  const body = node.getBody();
11106
- if (body !== void 0 && !import_ts_morph48.Node.isBlock(body)) {
11147
+ if (body !== void 0 && !import_ts_morph49.Node.isBlock(body)) {
11107
11148
  expr = body;
11108
11149
  source = body;
11109
11150
  }
@@ -11134,14 +11175,14 @@ function tryMatchJsxReturn(node, pattern) {
11134
11175
  return { node, source, terminal };
11135
11176
  }
11136
11177
  function componentTargetOf(tagNode) {
11137
- if (!import_ts_morph48.Node.isIdentifier(tagNode) || !/^[A-Z]/.test(tagNode.getText())) {
11178
+ if (!import_ts_morph49.Node.isIdentifier(tagNode) || !/^[A-Z]/.test(tagNode.getText())) {
11138
11179
  return null;
11139
11180
  }
11140
11181
  const target = functionTargetOf(tagNode);
11141
11182
  return target === null ? null : { file: target.file, name: target.name };
11142
11183
  }
11143
11184
  function jsxToRenderNode(node) {
11144
- if (import_ts_morph48.Node.isJsxElement(node)) {
11185
+ if (import_ts_morph49.Node.isJsxElement(node)) {
11145
11186
  const opening = node.getOpeningElement();
11146
11187
  const tag = opening.getTagNameNode().getText();
11147
11188
  const attrs = collectJsxAttributes(opening);
@@ -11155,7 +11196,7 @@ function jsxToRenderNode(node) {
11155
11196
  ...target !== null ? { target } : {}
11156
11197
  };
11157
11198
  }
11158
- if (import_ts_morph48.Node.isJsxSelfClosingElement(node)) {
11199
+ if (import_ts_morph49.Node.isJsxSelfClosingElement(node)) {
11159
11200
  const tag = node.getTagNameNode().getText();
11160
11201
  const attrs = collectJsxAttributes(node);
11161
11202
  const target = componentTargetOf(node.getTagNameNode());
@@ -11167,11 +11208,11 @@ function jsxToRenderNode(node) {
11167
11208
  ...target !== null ? { target } : {}
11168
11209
  };
11169
11210
  }
11170
- if (import_ts_morph48.Node.isJsxFragment(node)) {
11211
+ if (import_ts_morph49.Node.isJsxFragment(node)) {
11171
11212
  const children = node.getJsxChildren().map(jsxChildToRenderNode).filter((n) => n !== null);
11172
11213
  return { type: "element", tag: "Fragment", children };
11173
11214
  }
11174
- if (import_ts_morph48.Node.isParenthesizedExpression(node)) {
11215
+ if (import_ts_morph49.Node.isParenthesizedExpression(node)) {
11175
11216
  return jsxToRenderNode(node.getExpression());
11176
11217
  }
11177
11218
  return null;
@@ -11179,12 +11220,12 @@ function jsxToRenderNode(node) {
11179
11220
  function collectJsxAttributes(opening) {
11180
11221
  const entries = {};
11181
11222
  for (const attr of opening.getAttributes()) {
11182
- if (import_ts_morph48.Node.isJsxSpreadAttribute(attr)) {
11223
+ if (import_ts_morph49.Node.isJsxSpreadAttribute(attr)) {
11183
11224
  const exprText = attr.getExpression().getText();
11184
11225
  entries[`...${exprText}`] = exprText;
11185
11226
  continue;
11186
11227
  }
11187
- if (!import_ts_morph48.Node.isJsxAttribute(attr)) {
11228
+ if (!import_ts_morph49.Node.isJsxAttribute(attr)) {
11188
11229
  continue;
11189
11230
  }
11190
11231
  const name = attr.getNameNode().getText();
@@ -11193,7 +11234,7 @@ function collectJsxAttributes(opening) {
11193
11234
  entries[name] = "";
11194
11235
  continue;
11195
11236
  }
11196
- if (import_ts_morph48.Node.isJsxExpression(initializer)) {
11237
+ if (import_ts_morph49.Node.isJsxExpression(initializer)) {
11197
11238
  const inner = initializer.getExpression();
11198
11239
  entries[name] = inner !== void 0 ? inner.getText() : "";
11199
11240
  continue;
@@ -11203,30 +11244,30 @@ function collectJsxAttributes(opening) {
11203
11244
  return Object.keys(entries).length > 0 ? entries : null;
11204
11245
  }
11205
11246
  function jsxChildToRenderNode(child) {
11206
- if (import_ts_morph48.Node.isJsxText(child)) {
11247
+ if (import_ts_morph49.Node.isJsxText(child)) {
11207
11248
  const text = child.getLiteralText().trim();
11208
11249
  if (text.length === 0) {
11209
11250
  return null;
11210
11251
  }
11211
11252
  return { type: "text", value: text };
11212
11253
  }
11213
- if (import_ts_morph48.Node.isJsxExpression(child)) {
11254
+ if (import_ts_morph49.Node.isJsxExpression(child)) {
11214
11255
  const inner = child.getExpression();
11215
11256
  if (inner === void 0) {
11216
11257
  return null;
11217
11258
  }
11218
11259
  return jsxExpressionToRenderNode(inner);
11219
11260
  }
11220
- if (import_ts_morph48.Node.isJsxElement(child) || import_ts_morph48.Node.isJsxSelfClosingElement(child) || import_ts_morph48.Node.isJsxFragment(child)) {
11261
+ if (import_ts_morph49.Node.isJsxElement(child) || import_ts_morph49.Node.isJsxSelfClosingElement(child) || import_ts_morph49.Node.isJsxFragment(child)) {
11221
11262
  return jsxToRenderNode(child);
11222
11263
  }
11223
11264
  return null;
11224
11265
  }
11225
11266
  function jsxExpressionToRenderNode(expr) {
11226
- if (import_ts_morph48.Node.isParenthesizedExpression(expr)) {
11267
+ if (import_ts_morph49.Node.isParenthesizedExpression(expr)) {
11227
11268
  return jsxExpressionToRenderNode(expr.getExpression());
11228
11269
  }
11229
- if (import_ts_morph48.Node.isBinaryExpression(expr)) {
11270
+ if (import_ts_morph49.Node.isBinaryExpression(expr)) {
11230
11271
  const op = expr.getOperatorToken().getText();
11231
11272
  if (op === "&&") {
11232
11273
  const right = renderAlternative(peelParens(expr.getRight()));
@@ -11240,7 +11281,7 @@ function jsxExpressionToRenderNode(expr) {
11240
11281
  }
11241
11282
  }
11242
11283
  }
11243
- if (import_ts_morph48.Node.isConditionalExpression(expr)) {
11284
+ if (import_ts_morph49.Node.isConditionalExpression(expr)) {
11244
11285
  const truthy = renderAlternative(peelParens(expr.getWhenTrue()));
11245
11286
  const falsy = renderAlternative(peelParens(expr.getWhenFalse()));
11246
11287
  if (truthy.kind === "jsx") {
@@ -11263,16 +11304,16 @@ function jsxExpressionToRenderNode(expr) {
11263
11304
  return { type: "expression", sourceText: expr.getText() };
11264
11305
  }
11265
11306
  function renderAlternative(node) {
11266
- if (import_ts_morph48.Node.isNullLiteral(node)) {
11307
+ if (import_ts_morph49.Node.isNullLiteral(node)) {
11267
11308
  return { kind: "noRender" };
11268
11309
  }
11269
- if (import_ts_morph48.Node.isFalseLiteral(node)) {
11310
+ if (import_ts_morph49.Node.isFalseLiteral(node)) {
11270
11311
  return { kind: "noRender" };
11271
11312
  }
11272
- if (import_ts_morph48.Node.isIdentifier(node) && node.getText() === "undefined") {
11313
+ if (import_ts_morph49.Node.isIdentifier(node) && node.getText() === "undefined") {
11273
11314
  return { kind: "noRender" };
11274
11315
  }
11275
- if (import_ts_morph48.Node.isJsxElement(node) || import_ts_morph48.Node.isJsxSelfClosingElement(node) || import_ts_morph48.Node.isJsxFragment(node)) {
11316
+ if (import_ts_morph49.Node.isJsxElement(node) || import_ts_morph49.Node.isJsxSelfClosingElement(node) || import_ts_morph49.Node.isJsxFragment(node)) {
11276
11317
  const tree = jsxToRenderNode(node);
11277
11318
  if (tree !== null) {
11278
11319
  return { kind: "jsx", node: tree };
@@ -11282,13 +11323,13 @@ function renderAlternative(node) {
11282
11323
  }
11283
11324
 
11284
11325
  // src/terminals/returns.ts
11285
- var import_ts_morph51 = require("ts-morph");
11326
+ var import_ts_morph52 = require("ts-morph");
11286
11327
 
11287
11328
  // src/terminals/helperResolution.ts
11288
- var import_ts_morph49 = require("ts-morph");
11329
+ var import_ts_morph50 = require("ts-morph");
11289
11330
  function resolveHelperReturn(call, resolveCallee2) {
11290
11331
  const callee = call.getExpression();
11291
- if (!import_ts_morph49.Node.isIdentifier(callee)) {
11332
+ if (!import_ts_morph50.Node.isIdentifier(callee)) {
11292
11333
  return { kind: "notLocal" };
11293
11334
  }
11294
11335
  const helper = memoizedLocalHelper(callee, resolveCallee2);
@@ -11318,16 +11359,16 @@ function guardsAbove(returnValue) {
11318
11359
  let child = returnValue;
11319
11360
  let current2 = returnValue.getParent();
11320
11361
  while (current2 !== void 0) {
11321
- if (import_ts_morph49.Node.isIfStatement(current2)) {
11362
+ if (import_ts_morph50.Node.isIfStatement(current2)) {
11322
11363
  guards.push({
11323
11364
  condition: current2.getExpression(),
11324
11365
  whenTrue: current2.getThenStatement() === child
11325
11366
  });
11326
11367
  }
11327
- if (import_ts_morph49.Node.isBlock(current2)) {
11368
+ if (import_ts_morph50.Node.isBlock(current2)) {
11328
11369
  guards.push(...earlyReturnGuardsBefore(current2, child));
11329
11370
  }
11330
- if (import_ts_morph49.Node.isFunctionDeclaration(current2) || import_ts_morph49.Node.isArrowFunction(current2) || import_ts_morph49.Node.isFunctionExpression(current2)) {
11371
+ if (import_ts_morph50.Node.isFunctionDeclaration(current2) || import_ts_morph50.Node.isArrowFunction(current2) || import_ts_morph50.Node.isFunctionExpression(current2)) {
11331
11372
  break;
11332
11373
  }
11333
11374
  child = current2;
@@ -11336,7 +11377,7 @@ function guardsAbove(returnValue) {
11336
11377
  return guards;
11337
11378
  }
11338
11379
  function earlyReturnGuardsBefore(block, child) {
11339
- if (!import_ts_morph49.Node.isBlock(block)) {
11380
+ if (!import_ts_morph50.Node.isBlock(block)) {
11340
11381
  return [];
11341
11382
  }
11342
11383
  const guards = [];
@@ -11344,7 +11385,7 @@ function earlyReturnGuardsBefore(block, child) {
11344
11385
  if (statement === child) {
11345
11386
  break;
11346
11387
  }
11347
- if (!import_ts_morph49.Node.isIfStatement(statement) || statement.getElseStatement()) {
11388
+ if (!import_ts_morph50.Node.isIfStatement(statement) || statement.getElseStatement()) {
11348
11389
  continue;
11349
11390
  }
11350
11391
  if (alwaysReturns(statement.getThenStatement())) {
@@ -11354,10 +11395,10 @@ function earlyReturnGuardsBefore(block, child) {
11354
11395
  return guards;
11355
11396
  }
11356
11397
  function alwaysReturns(statement) {
11357
- if (import_ts_morph49.Node.isReturnStatement(statement) || import_ts_morph49.Node.isThrowStatement(statement)) {
11398
+ if (import_ts_morph50.Node.isReturnStatement(statement) || import_ts_morph50.Node.isThrowStatement(statement)) {
11358
11399
  return true;
11359
11400
  }
11360
- if (!import_ts_morph49.Node.isBlock(statement)) {
11401
+ if (!import_ts_morph50.Node.isBlock(statement)) {
11361
11402
  return false;
11362
11403
  }
11363
11404
  const statements = statement.getStatements();
@@ -11375,7 +11416,7 @@ var COMPARISONS = {
11375
11416
  "!=": (a, b) => a !== b
11376
11417
  };
11377
11418
  function evaluateComparison(condition, substitutions) {
11378
- if (!import_ts_morph49.Node.isBinaryExpression(condition)) {
11419
+ if (!import_ts_morph50.Node.isBinaryExpression(condition)) {
11379
11420
  return null;
11380
11421
  }
11381
11422
  const left = numberFor(condition.getLeft(), substitutions);
@@ -11387,8 +11428,8 @@ function evaluateComparison(condition, substitutions) {
11387
11428
  return compare === void 0 ? null : compare(left, right);
11388
11429
  }
11389
11430
  function numberFor(node, substitutions) {
11390
- const resolved = import_ts_morph49.Node.isIdentifier(node) && substitutions.has(node.getText()) ? substitutions.get(node.getText()) : node;
11391
- return import_ts_morph49.Node.isNumericLiteral(resolved) ? Number(resolved.getText()) : null;
11431
+ const resolved = import_ts_morph50.Node.isIdentifier(node) && substitutions.has(node.getText()) ? substitutions.get(node.getText()) : node;
11432
+ return import_ts_morph50.Node.isNumericLiteral(resolved) ? Number(resolved.getText()) : null;
11392
11433
  }
11393
11434
  var helperBySymbol = /* @__PURE__ */ new WeakMap();
11394
11435
  function memoizedLocalHelper(callee, resolveCallee2) {
@@ -11475,12 +11516,12 @@ function declarationsFor(callee, resolveCallee2) {
11475
11516
  return (aliased ?? symbol).getDeclarations();
11476
11517
  }
11477
11518
  function asFunctionLike(declaration) {
11478
- if (import_ts_morph49.Node.isFunctionDeclaration(declaration) || import_ts_morph49.Node.isArrowFunction(declaration) || import_ts_morph49.Node.isFunctionExpression(declaration)) {
11519
+ if (import_ts_morph50.Node.isFunctionDeclaration(declaration) || import_ts_morph50.Node.isArrowFunction(declaration) || import_ts_morph50.Node.isFunctionExpression(declaration)) {
11479
11520
  return declaration;
11480
11521
  }
11481
- if (import_ts_morph49.Node.isVariableDeclaration(declaration)) {
11522
+ if (import_ts_morph50.Node.isVariableDeclaration(declaration)) {
11482
11523
  const initializer = declaration.getInitializer();
11483
- if (initializer !== void 0 && (import_ts_morph49.Node.isArrowFunction(initializer) || import_ts_morph49.Node.isFunctionExpression(initializer))) {
11524
+ if (initializer !== void 0 && (import_ts_morph50.Node.isArrowFunction(initializer) || import_ts_morph50.Node.isFunctionExpression(initializer))) {
11484
11525
  return initializer;
11485
11526
  }
11486
11527
  }
@@ -11491,13 +11532,13 @@ function returnedObjects(fn) {
11491
11532
  if (body === void 0) {
11492
11533
  return [];
11493
11534
  }
11494
- if (!import_ts_morph49.Node.isBlock(body)) {
11535
+ if (!import_ts_morph50.Node.isBlock(body)) {
11495
11536
  const expression = peelParens(body);
11496
- return import_ts_morph49.Node.isObjectLiteralExpression(expression) ? [expression] : [];
11537
+ return import_ts_morph50.Node.isObjectLiteralExpression(expression) ? [expression] : [];
11497
11538
  }
11498
11539
  const found = [];
11499
11540
  for (const statement of body.getDescendantsOfKind(
11500
- import_ts_morph49.SyntaxKind.ReturnStatement
11541
+ import_ts_morph50.SyntaxKind.ReturnStatement
11501
11542
  )) {
11502
11543
  if (enclosingFunctionOf(statement) !== body) {
11503
11544
  continue;
@@ -11507,7 +11548,7 @@ function returnedObjects(fn) {
11507
11548
  continue;
11508
11549
  }
11509
11550
  const unwrapped2 = peelParens(expression);
11510
- if (import_ts_morph49.Node.isObjectLiteralExpression(unwrapped2)) {
11551
+ if (import_ts_morph50.Node.isObjectLiteralExpression(unwrapped2)) {
11511
11552
  found.push(unwrapped2);
11512
11553
  }
11513
11554
  }
@@ -11516,7 +11557,7 @@ function returnedObjects(fn) {
11516
11557
  function enclosingFunctionOf(node) {
11517
11558
  let current2 = node.getParent();
11518
11559
  while (current2 !== void 0) {
11519
- if (import_ts_morph49.Node.isFunctionDeclaration(current2) || import_ts_morph49.Node.isArrowFunction(current2) || import_ts_morph49.Node.isFunctionExpression(current2) || import_ts_morph49.Node.isMethodDeclaration(current2)) {
11560
+ if (import_ts_morph50.Node.isFunctionDeclaration(current2) || import_ts_morph50.Node.isArrowFunction(current2) || import_ts_morph50.Node.isFunctionExpression(current2) || import_ts_morph50.Node.isMethodDeclaration(current2)) {
11520
11561
  return current2.getBody();
11521
11562
  }
11522
11563
  current2 = current2.getParent();
@@ -11535,7 +11576,7 @@ function bindArguments(callArgs, params) {
11535
11576
  }
11536
11577
 
11537
11578
  // src/terminals/statusBranches.ts
11538
- var import_ts_morph50 = require("ts-morph");
11579
+ var import_ts_morph51 = require("ts-morph");
11539
11580
  var import_values6 = require("@suss/values");
11540
11581
  function statusChoicesOf(argument, resolution) {
11541
11582
  const chosen = asConditional(argument);
@@ -11559,10 +11600,10 @@ function asConditional(node) {
11559
11600
  if (direct !== null) {
11560
11601
  return direct;
11561
11602
  }
11562
- if (!import_ts_morph50.Node.isIdentifier(node)) {
11603
+ if (!import_ts_morph51.Node.isIdentifier(node)) {
11563
11604
  return null;
11564
11605
  }
11565
- const declaration = node.getSymbol()?.getDeclarations().find(import_ts_morph50.Node.isVariableDeclaration);
11606
+ const declaration = node.getSymbol()?.getDeclarations().find(import_ts_morph51.Node.isVariableDeclaration);
11566
11607
  if (declaration === void 0) {
11567
11608
  return null;
11568
11609
  }
@@ -11573,7 +11614,7 @@ function asConditional(node) {
11573
11614
  const only = written.values[0];
11574
11615
  return only === void 0 ? null : toConditional(only);
11575
11616
  }
11576
- var toConditional = (node) => import_ts_morph50.Node.isConditionalExpression(node) ? node : null;
11617
+ var toConditional = (node) => import_ts_morph51.Node.isConditionalExpression(node) ? node : null;
11577
11618
  function numberOf(node, resolution) {
11578
11619
  const value = (0, import_values6.constantOf)(evaluatedValue(node, resolution));
11579
11620
  return typeof value === "number" && Number.isFinite(value) ? value : null;
@@ -11590,7 +11631,7 @@ function unwrapMethodChain(call, match, func) {
11590
11631
  for (let i = methodChain.length - 1; i >= 0; i--) {
11591
11632
  const expectedMethod = methodChain[i];
11592
11633
  const callee = current2.getExpression();
11593
- if (!import_ts_morph51.Node.isPropertyAccessExpression(callee)) {
11634
+ if (!import_ts_morph52.Node.isPropertyAccessExpression(callee)) {
11594
11635
  return null;
11595
11636
  }
11596
11637
  if (callee.getName() !== expectedMethod) {
@@ -11606,7 +11647,7 @@ function unwrapMethodChain(call, match, func) {
11606
11647
  return null;
11607
11648
  }
11608
11649
  } else {
11609
- if (!import_ts_morph51.Node.isCallExpression(subject)) {
11650
+ if (!import_ts_morph52.Node.isCallExpression(subject)) {
11610
11651
  return null;
11611
11652
  }
11612
11653
  current2 = subject;
@@ -11616,9 +11657,9 @@ function unwrapMethodChain(call, match, func) {
11616
11657
  }
11617
11658
  function withoutPassThroughCalls(subject, passThrough) {
11618
11659
  let current2 = subject;
11619
- while (import_ts_morph51.Node.isCallExpression(current2)) {
11660
+ while (import_ts_morph52.Node.isCallExpression(current2)) {
11620
11661
  const callee = current2.getExpression();
11621
- if (!import_ts_morph51.Node.isPropertyAccessExpression(callee) || !passThrough.includes(callee.getName())) {
11662
+ if (!import_ts_morph52.Node.isPropertyAccessExpression(callee) || !passThrough.includes(callee.getName())) {
11622
11663
  break;
11623
11664
  }
11624
11665
  current2 = callee.getExpression();
@@ -11630,12 +11671,12 @@ function returnedValueOf(returnStatement) {
11630
11671
  return written === void 0 ? null : unwrapValue(written);
11631
11672
  }
11632
11673
  function tryMatchReturnShape(node, pattern, match, resolution, resolveCallee2) {
11633
- if (import_ts_morph51.Node.isObjectLiteralExpression(node)) {
11674
+ if (import_ts_morph52.Node.isObjectLiteralExpression(node)) {
11634
11675
  const source = returnPositionOf(node);
11635
11676
  if (source === null) {
11636
11677
  return [];
11637
11678
  }
11638
- if (import_ts_morph51.Node.isReturnStatement(source) && returnedValueOf(source) === node) {
11679
+ if (import_ts_morph52.Node.isReturnStatement(source) && returnedValueOf(source) === node) {
11639
11680
  return [];
11640
11681
  }
11641
11682
  const terminal = terminalFromReturnedObject(
@@ -11648,14 +11689,14 @@ function tryMatchReturnShape(node, pattern, match, resolution, resolveCallee2) {
11648
11689
  );
11649
11690
  return terminal === null ? [] : [{ ...terminal, source }];
11650
11691
  }
11651
- if (!import_ts_morph51.Node.isReturnStatement(node)) {
11692
+ if (!import_ts_morph52.Node.isReturnStatement(node)) {
11652
11693
  return [];
11653
11694
  }
11654
11695
  const returned = returnedValueOf(node);
11655
11696
  if (returned === null) {
11656
11697
  return [];
11657
11698
  }
11658
- if (import_ts_morph51.Node.isObjectLiteralExpression(returned)) {
11699
+ if (import_ts_morph52.Node.isObjectLiteralExpression(returned)) {
11659
11700
  const terminal = terminalFromReturnedObject(
11660
11701
  returned,
11661
11702
  node,
@@ -11666,7 +11707,7 @@ function tryMatchReturnShape(node, pattern, match, resolution, resolveCallee2) {
11666
11707
  );
11667
11708
  return terminal === null ? [] : [terminal];
11668
11709
  }
11669
- if (!import_ts_morph51.Node.isCallExpression(returned)) {
11710
+ if (!import_ts_morph52.Node.isCallExpression(returned)) {
11670
11711
  return [];
11671
11712
  }
11672
11713
  const resolved = resolveHelperReturn(returned, resolveCallee2);
@@ -11703,7 +11744,7 @@ function terminalFromReturnedObject(obj, anchor, pattern, match, substitutions,
11703
11744
  if (required !== void 0 && required.length > 0) {
11704
11745
  const presentNames = /* @__PURE__ */ new Set();
11705
11746
  for (const prop of obj.getProperties()) {
11706
- if (import_ts_morph51.Node.isPropertyAssignment(prop) || import_ts_morph51.Node.isShorthandPropertyAssignment(prop)) {
11747
+ if (import_ts_morph52.Node.isPropertyAssignment(prop) || import_ts_morph52.Node.isShorthandPropertyAssignment(prop)) {
11707
11748
  presentNames.add(prop.getName());
11708
11749
  }
11709
11750
  }
@@ -11729,7 +11770,7 @@ function terminalFromReturnedObject(obj, anchor, pattern, match, substitutions,
11729
11770
  // When a helper built the value, the anchor is the caller's own
11730
11771
  // return, so it doubles as the provenance. A value reached any other
11731
11772
  // way leaves this unset and its caller fills it in.
11732
- ...import_ts_morph51.Node.isReturnStatement(anchor) ? { source: anchor } : {},
11773
+ ...import_ts_morph52.Node.isReturnStatement(anchor) ? { source: anchor } : {},
11733
11774
  terminal: {
11734
11775
  kind: pattern.kind,
11735
11776
  statusCode,
@@ -11748,7 +11789,7 @@ function terminalFromReturnedObject(obj, anchor, pattern, match, substitutions,
11748
11789
  };
11749
11790
  }
11750
11791
  function tryMatchParameterMethodCall(node, func, pattern, match, resolution) {
11751
- if (!import_ts_morph51.Node.isCallExpression(node)) {
11792
+ if (!import_ts_morph52.Node.isCallExpression(node)) {
11752
11793
  return [];
11753
11794
  }
11754
11795
  const result = unwrapMethodChain(node, match, func);
@@ -11808,7 +11849,7 @@ function statusArgument(calls, extraction) {
11808
11849
  }
11809
11850
  function returnCoveredByParameterMethodCall(expr, func, patterns) {
11810
11851
  const current2 = unwrapValue(expr);
11811
- if (!import_ts_morph51.Node.isCallExpression(current2)) {
11852
+ if (!import_ts_morph52.Node.isCallExpression(current2)) {
11812
11853
  return false;
11813
11854
  }
11814
11855
  for (const pattern of patterns) {
@@ -11824,7 +11865,7 @@ function returnCoveredByParameterMethodCall(expr, func, patterns) {
11824
11865
  }
11825
11866
  function tryMatchReturnStatement(node, pattern, func, allPatterns) {
11826
11867
  const match = pattern.match.type === "returnStatement" ? pattern.match : null;
11827
- if (import_ts_morph51.Node.isReturnStatement(node)) {
11868
+ if (import_ts_morph52.Node.isReturnStatement(node)) {
11828
11869
  const expr = node.getExpression();
11829
11870
  if (match?.excludeCallReturns === true) {
11830
11871
  if (expr === void 0) {
@@ -11843,9 +11884,9 @@ function tryMatchReturnStatement(node, pattern, func, allPatterns) {
11843
11884
  }
11844
11885
  return buildReturnTerminal(node, pattern, body);
11845
11886
  }
11846
- if (import_ts_morph51.Node.isArrowFunction(node)) {
11887
+ if (import_ts_morph52.Node.isArrowFunction(node)) {
11847
11888
  const body = node.getBody();
11848
- if (body === void 0 || import_ts_morph51.Node.isBlock(body)) {
11889
+ if (body === void 0 || import_ts_morph52.Node.isBlock(body)) {
11849
11890
  return null;
11850
11891
  }
11851
11892
  const shape = extractShape(body);
@@ -11903,20 +11944,20 @@ function unresolvedTerminal(kind, node) {
11903
11944
  };
11904
11945
  }
11905
11946
  function calleeSubject(callee) {
11906
- if (import_ts_morph51.Node.isIdentifier(callee)) {
11947
+ if (import_ts_morph52.Node.isIdentifier(callee)) {
11907
11948
  return callee;
11908
11949
  }
11909
- if (import_ts_morph51.Node.isPropertyAccessExpression(callee)) {
11950
+ if (import_ts_morph52.Node.isPropertyAccessExpression(callee)) {
11910
11951
  const subject = callee.getExpression();
11911
- return import_ts_morph51.Node.isIdentifier(subject) ? subject : null;
11952
+ return import_ts_morph52.Node.isIdentifier(subject) ? subject : null;
11912
11953
  }
11913
11954
  return null;
11914
11955
  }
11915
11956
  function tryMatchFunctionCall(node, pattern, match, resolution, originatesFrom) {
11916
- if (!import_ts_morph51.Node.isCallExpression(node) && !import_ts_morph51.Node.isNewExpression(node)) {
11957
+ if (!import_ts_morph52.Node.isCallExpression(node) && !import_ts_morph52.Node.isNewExpression(node)) {
11917
11958
  return null;
11918
11959
  }
11919
- if (import_ts_morph51.Node.isNewExpression(node) && returnPositionOf(node) === null) {
11960
+ if (import_ts_morph52.Node.isNewExpression(node) && returnPositionOf(node) === null) {
11920
11961
  return null;
11921
11962
  }
11922
11963
  const callee = node.getExpression();
@@ -11955,9 +11996,9 @@ function tryMatchFunctionCall(node, pattern, match, resolution, originatesFrom)
11955
11996
  }
11956
11997
 
11957
11998
  // src/terminals/throws.ts
11958
- var import_ts_morph52 = require("ts-morph");
11999
+ var import_ts_morph53 = require("ts-morph");
11959
12000
  function tryMatchThrowExpression(node, pattern, match, resolution) {
11960
- if (!import_ts_morph52.Node.isThrowStatement(node)) {
12001
+ if (!import_ts_morph53.Node.isThrowStatement(node)) {
11961
12002
  return null;
11962
12003
  }
11963
12004
  const thrownExpr = node.getExpression();
@@ -11999,17 +12040,17 @@ function extractThrowMessage(callArgs) {
11999
12040
  return null;
12000
12041
  }
12001
12042
  for (const arg of callArgs) {
12002
- if (import_ts_morph52.Node.isStringLiteral(arg) || import_ts_morph52.Node.isNoSubstitutionTemplateLiteral(arg)) {
12043
+ if (import_ts_morph53.Node.isStringLiteral(arg) || import_ts_morph53.Node.isNoSubstitutionTemplateLiteral(arg)) {
12003
12044
  return arg.getLiteralValue();
12004
12045
  }
12005
- if (import_ts_morph52.Node.isTemplateExpression(arg)) {
12046
+ if (import_ts_morph53.Node.isTemplateExpression(arg)) {
12006
12047
  return arg.getText();
12007
12048
  }
12008
12049
  }
12009
12050
  return null;
12010
12051
  }
12011
12052
  function classifyThrownExpression(thrown, constructorPattern) {
12012
- if (import_ts_morph52.Node.isCallExpression(thrown) || import_ts_morph52.Node.isNewExpression(thrown)) {
12053
+ if (import_ts_morph53.Node.isCallExpression(thrown) || import_ts_morph53.Node.isNewExpression(thrown)) {
12013
12054
  const calleeText = thrown.getExpression().getText();
12014
12055
  if (constructorPattern !== void 0 && !calleeText.startsWith(constructorPattern)) {
12015
12056
  return null;
@@ -12096,9 +12137,9 @@ function findTerminals(func, patterns, barriers = NO_BARRIERS, resolution, origi
12096
12137
  }
12097
12138
  }
12098
12139
  });
12099
- if (results.length === 0 && import_ts_morph53.Node.isArrowFunction(func)) {
12140
+ if (results.length === 0 && import_ts_morph54.Node.isArrowFunction(func)) {
12100
12141
  const body = func.getBody();
12101
- if (body !== void 0 && !import_ts_morph53.Node.isBlock(body)) {
12142
+ if (body !== void 0 && !import_ts_morph54.Node.isBlock(body)) {
12102
12143
  for (const pattern of patterns) {
12103
12144
  let found = null;
12104
12145
  if (pattern.match.type === "parameterMethodCall") {
@@ -12133,7 +12174,7 @@ function functionMayFallThrough(func) {
12133
12174
  if (body === void 0) {
12134
12175
  return false;
12135
12176
  }
12136
- if (!import_ts_morph53.Node.isBlock(body)) {
12177
+ if (!import_ts_morph54.Node.isBlock(body)) {
12137
12178
  return false;
12138
12179
  }
12139
12180
  const statements = body.getStatements();
@@ -12141,7 +12182,7 @@ function functionMayFallThrough(func) {
12141
12182
  return true;
12142
12183
  }
12143
12184
  const last = statements[statements.length - 1];
12144
- if (import_ts_morph53.Node.isReturnStatement(last) || import_ts_morph53.Node.isThrowStatement(last)) {
12185
+ if (import_ts_morph54.Node.isReturnStatement(last) || import_ts_morph54.Node.isThrowStatement(last)) {
12145
12186
  return false;
12146
12187
  }
12147
12188
  return true;
@@ -12189,7 +12230,7 @@ function writesTerminal(call, terminalNodes) {
12189
12230
  }
12190
12231
  }
12191
12232
  function isReceiverOf(node, parent) {
12192
- return (import_ts_morph54.Node.isPropertyAccessExpression(parent) || import_ts_morph54.Node.isElementAccessExpression(parent) || import_ts_morph54.Node.isCallExpression(parent)) && parent.getExpression() === node;
12233
+ return (import_ts_morph55.Node.isPropertyAccessExpression(parent) || import_ts_morph55.Node.isElementAccessExpression(parent) || import_ts_morph55.Node.isCallExpression(parent)) && parent.getExpression() === node;
12193
12234
  }
12194
12235
  var isDefaultConditionList = (conditions) => conditions.length === 0 || conditions.every(
12195
12236
  (c) => c.source === "earlyReturn" || c.source === "earlyThrow"
@@ -12199,7 +12240,7 @@ function bodyContentOf(func) {
12199
12240
  if (body === void 0) {
12200
12241
  return "absent";
12201
12242
  }
12202
- if (!import_ts_morph54.Node.isBlock(body)) {
12243
+ if (!import_ts_morph55.Node.isBlock(body)) {
12203
12244
  return "statements";
12204
12245
  }
12205
12246
  return body.getStatements().length === 0 ? "empty" : "statements";
@@ -12215,7 +12256,7 @@ function countUnmatchedReturns(func, terminals, barriers = NO_BARRIERS) {
12215
12256
  claimed.add(source);
12216
12257
  }
12217
12258
  }
12218
- if (import_ts_morph54.Node.isArrowFunction(func) && import_ts_morph54.Node.isExpression(body)) {
12259
+ if (import_ts_morph55.Node.isArrowFunction(func) && import_ts_morph55.Node.isExpression(body)) {
12219
12260
  return claimed.has(body) ? 0 : 1;
12220
12261
  }
12221
12262
  let unmatched = 0;
@@ -12228,7 +12269,7 @@ function countUnmatchedReturns(func, terminals, barriers = NO_BARRIERS) {
12228
12269
  traversal.skip();
12229
12270
  return;
12230
12271
  }
12231
- if (!import_ts_morph54.Node.isReturnStatement(node)) {
12272
+ if (!import_ts_morph55.Node.isReturnStatement(node)) {
12232
12273
  return;
12233
12274
  }
12234
12275
  if (node.getExpression() === void 0) {
@@ -12240,7 +12281,7 @@ function countUnmatchedReturns(func, terminals, barriers = NO_BARRIERS) {
12240
12281
  });
12241
12282
  return unmatched;
12242
12283
  }
12243
- function extractRawBranches(func, terminalPatterns, invocationRecognizers = [], accessRecognizers = [], barriers = NO_BARRIERS, resolution, originatesFrom, anchorCallsOf, resolveCallee2) {
12284
+ function extractRawBranches(func, terminalPatterns, invocationRecognizers = [], accessRecognizers = [], barriers = NO_BARRIERS, resolution, originatesFrom, anchorCallsOf, resolveCallee2, collectCallAccounting = false) {
12244
12285
  const terminals = findTerminals(
12245
12286
  func,
12246
12287
  terminalPatterns,
@@ -12328,8 +12369,8 @@ function extractRawBranches(func, terminalPatterns, invocationRecognizers = [],
12328
12369
  seenBranches.add(key);
12329
12370
  return true;
12330
12371
  });
12372
+ const terminalNodes = new Set(terminals.map(({ node }) => node));
12331
12373
  if (invocations.length > 0) {
12332
- const terminalNodes = new Set(terminals.map(({ node }) => node));
12333
12374
  const sideEffects = invocations.filter(
12334
12375
  (i) => !writesTerminal(i.node, terminalNodes)
12335
12376
  );
@@ -12345,11 +12386,43 @@ function extractRawBranches(func, terminalPatterns, invocationRecognizers = [],
12345
12386
  branch.extraEffects = [...branch.extraEffects ?? [], ...extra];
12346
12387
  }
12347
12388
  }
12348
- return { branches: distinctBranches, terminals };
12389
+ return {
12390
+ branches: distinctBranches,
12391
+ terminals,
12392
+ ...collectCallAccounting ? {
12393
+ callAccounting: invocations.map(
12394
+ (site) => accountFor(site, terminalNodes, distinctBranches)
12395
+ )
12396
+ } : {}
12397
+ };
12398
+ }
12399
+ function accountFor(site, terminalNodes, branches) {
12400
+ const { node, line } = site;
12401
+ const callee = node.getExpression().getText();
12402
+ if (writesTerminal(node, terminalNodes)) {
12403
+ return { node, callee, line, outcome: "terminal" };
12404
+ }
12405
+ const call = {
12406
+ line,
12407
+ alwaysRuns: site.alwaysRuns,
12408
+ preconditions: preconditionsOf(site.effect)
12409
+ };
12410
+ if (branches.some((branch) => firesOn(call, branch))) {
12411
+ return { node, callee, line, outcome: "invocation" };
12412
+ }
12413
+ const reachable = branches.some(
12414
+ (branch) => site.alwaysRuns || (0, import_extractor5.runsBefore)(line, branch.terminal.location.end)
12415
+ );
12416
+ return {
12417
+ node,
12418
+ callee,
12419
+ line,
12420
+ outcome: reachable ? "unrecorded" : "unreachable"
12421
+ };
12349
12422
  }
12350
12423
 
12351
12424
  // src/bootstrap/sourceFileLookup.ts
12352
- var import_ts_morph55 = require("ts-morph");
12425
+ var import_ts_morph56 = require("ts-morph");
12353
12426
  function createSourceFileLookup(project) {
12354
12427
  const all = project.getSourceFiles();
12355
12428
  const byAbs = /* @__PURE__ */ new Map();
@@ -12411,7 +12484,7 @@ function spanKey(span) {
12411
12484
  function indexFunctions(sf) {
12412
12485
  const index = /* @__PURE__ */ new Map();
12413
12486
  sf.forEachDescendant((node) => {
12414
- if (!import_ts_morph55.Node.isFunctionDeclaration(node) && !import_ts_morph55.Node.isFunctionExpression(node) && !import_ts_morph55.Node.isArrowFunction(node) && !import_ts_morph55.Node.isMethodDeclaration(node)) {
12487
+ if (!import_ts_morph56.Node.isFunctionDeclaration(node) && !import_ts_morph56.Node.isFunctionExpression(node) && !import_ts_morph56.Node.isArrowFunction(node) && !import_ts_morph56.Node.isMethodDeclaration(node)) {
12415
12488
  return;
12416
12489
  }
12417
12490
  const bySpan = spanKey({ start: node.getStart(), end: node.getEnd() });
@@ -12425,13 +12498,13 @@ function indexFunctions(sf) {
12425
12498
  }
12426
12499
 
12427
12500
  // src/contract.ts
12428
- var import_ts_morph56 = require("ts-morph");
12501
+ var import_ts_morph57 = require("ts-morph");
12429
12502
  var import_behavioral_ir4 = require("@suss/behavioral-ir");
12430
12503
  function extractDeclaredBody(node) {
12431
12504
  if (node === void 0) {
12432
12505
  return null;
12433
12506
  }
12434
- if (!import_ts_morph56.Node.isCallExpression(node)) {
12507
+ if (!import_ts_morph57.Node.isCallExpression(node)) {
12435
12508
  return null;
12436
12509
  }
12437
12510
  const typeArgs = node.getTypeArguments();
@@ -12445,10 +12518,10 @@ function resolveHandlerPropNode(func) {
12445
12518
  if (parent === void 0) {
12446
12519
  return null;
12447
12520
  }
12448
- if (import_ts_morph56.Node.isPropertyAssignment(parent)) {
12521
+ if (import_ts_morph57.Node.isPropertyAssignment(parent)) {
12449
12522
  return parent;
12450
12523
  }
12451
- if (import_ts_morph56.Node.isMethodDeclaration(func)) {
12524
+ if (import_ts_morph57.Node.isMethodDeclaration(func)) {
12452
12525
  return func;
12453
12526
  }
12454
12527
  return null;
@@ -12460,11 +12533,11 @@ function findRouterCall(unit) {
12460
12533
  return null;
12461
12534
  }
12462
12535
  const handlersObj = propNode.getParent();
12463
- if (handlersObj === void 0 || !import_ts_morph56.Node.isObjectLiteralExpression(handlersObj)) {
12536
+ if (handlersObj === void 0 || !import_ts_morph57.Node.isObjectLiteralExpression(handlersObj)) {
12464
12537
  return null;
12465
12538
  }
12466
12539
  const routerCall = handlersObj.getParent();
12467
- if (routerCall === void 0 || !import_ts_morph56.Node.isCallExpression(routerCall)) {
12540
+ if (routerCall === void 0 || !import_ts_morph57.Node.isCallExpression(routerCall)) {
12468
12541
  return null;
12469
12542
  }
12470
12543
  const args = routerCall.getArguments();
@@ -12477,17 +12550,17 @@ function findRouterCall(unit) {
12477
12550
  };
12478
12551
  }
12479
12552
  function resolveContractObject(contractArg, resolution) {
12480
- if (import_ts_morph56.Node.isObjectLiteralExpression(contractArg)) {
12553
+ if (import_ts_morph57.Node.isObjectLiteralExpression(contractArg)) {
12481
12554
  return contractArg;
12482
12555
  }
12483
- if (import_ts_morph56.Node.isPropertyAccessExpression(contractArg)) {
12556
+ if (import_ts_morph57.Node.isPropertyAccessExpression(contractArg)) {
12484
12557
  const base = resolveContractObject(contractArg.getExpression(), resolution);
12485
- if (base === null || !import_ts_morph56.Node.isObjectLiteralExpression(base)) {
12558
+ if (base === null || !import_ts_morph57.Node.isObjectLiteralExpression(base)) {
12486
12559
  return null;
12487
12560
  }
12488
12561
  const propName = contractArg.getName();
12489
12562
  for (const prop of base.getProperties()) {
12490
- if (!import_ts_morph56.Node.isPropertyAssignment(prop)) {
12563
+ if (!import_ts_morph57.Node.isPropertyAssignment(prop)) {
12491
12564
  continue;
12492
12565
  }
12493
12566
  if (prop.getName() !== propName) {
@@ -12497,20 +12570,20 @@ function resolveContractObject(contractArg, resolution) {
12497
12570
  if (value === void 0) {
12498
12571
  return null;
12499
12572
  }
12500
- if (import_ts_morph56.Node.isObjectLiteralExpression(value)) {
12573
+ if (import_ts_morph57.Node.isObjectLiteralExpression(value)) {
12501
12574
  return value;
12502
12575
  }
12503
- if (import_ts_morph56.Node.isIdentifier(value) || import_ts_morph56.Node.isPropertyAccessExpression(value)) {
12576
+ if (import_ts_morph57.Node.isIdentifier(value) || import_ts_morph57.Node.isPropertyAccessExpression(value)) {
12504
12577
  return resolveContractObject(value, resolution);
12505
12578
  }
12506
- if (import_ts_morph56.Node.isCallExpression(value)) {
12579
+ if (import_ts_morph57.Node.isCallExpression(value)) {
12507
12580
  return unwrapContractInit(value);
12508
12581
  }
12509
12582
  return null;
12510
12583
  }
12511
12584
  return null;
12512
12585
  }
12513
- if (!import_ts_morph56.Node.isIdentifier(contractArg)) {
12586
+ if (!import_ts_morph57.Node.isIdentifier(contractArg)) {
12514
12587
  return null;
12515
12588
  }
12516
12589
  const symbol = contractArg.getSymbol();
@@ -12522,7 +12595,7 @@ function resolveContractObject(contractArg, resolution) {
12522
12595
  return null;
12523
12596
  }
12524
12597
  const decl = decls[0];
12525
- if (import_ts_morph56.Node.isImportSpecifier(decl)) {
12598
+ if (import_ts_morph57.Node.isImportSpecifier(decl)) {
12526
12599
  const importDecl = decl.getImportDeclaration();
12527
12600
  const sourceFile = importDecl.getModuleSpecifierSourceFile();
12528
12601
  if (sourceFile !== void 0 && resolution !== void 0) {
@@ -12531,14 +12604,14 @@ function resolveContractObject(contractArg, resolution) {
12531
12604
  );
12532
12605
  if (exported !== void 0 && exported.length > 0) {
12533
12606
  const exportedDecl = exported[0];
12534
- if (import_ts_morph56.Node.isVariableDeclaration(exportedDecl)) {
12607
+ if (import_ts_morph57.Node.isVariableDeclaration(exportedDecl)) {
12535
12608
  return unwrapContractInit(exportedDecl.getInitializer());
12536
12609
  }
12537
12610
  }
12538
12611
  }
12539
12612
  return null;
12540
12613
  }
12541
- if (import_ts_morph56.Node.isVariableDeclaration(decl)) {
12614
+ if (import_ts_morph57.Node.isVariableDeclaration(decl)) {
12542
12615
  return unwrapContractInit(decl.getInitializer());
12543
12616
  }
12544
12617
  return null;
@@ -12548,47 +12621,48 @@ function unwrapContractInit(init) {
12548
12621
  return null;
12549
12622
  }
12550
12623
  const node = peelSyntax(init);
12551
- if (import_ts_morph56.Node.isCallExpression(node)) {
12624
+ if (import_ts_morph57.Node.isCallExpression(node)) {
12552
12625
  const args = node.getArguments();
12553
- if (args.length > 0 && import_ts_morph56.Node.isObjectLiteralExpression(args[0])) {
12626
+ if (args.length > 0 && import_ts_morph57.Node.isObjectLiteralExpression(args[0])) {
12554
12627
  return args[0];
12555
12628
  }
12556
12629
  return null;
12557
12630
  }
12558
- if (import_ts_morph56.Node.isObjectLiteralExpression(node)) {
12631
+ if (import_ts_morph57.Node.isObjectLiteralExpression(node)) {
12559
12632
  return node;
12560
12633
  }
12561
12634
  return null;
12562
12635
  }
12563
- function extractEndpointContract(endpointNode, pattern, framework) {
12564
- if (!import_ts_morph56.Node.isObjectLiteralExpression(endpointNode)) {
12636
+ function extractEndpointContract(endpointNode, pattern, framework, resolution) {
12637
+ if (!import_ts_morph57.Node.isObjectLiteralExpression(endpointNode)) {
12565
12638
  return null;
12566
12639
  }
12567
12640
  const responses = [];
12568
12641
  let method;
12569
12642
  let path14;
12570
12643
  for (const prop of endpointNode.getProperties()) {
12571
- if (!import_ts_morph56.Node.isPropertyAssignment(prop)) {
12644
+ if (!import_ts_morph57.Node.isPropertyAssignment(prop)) {
12572
12645
  continue;
12573
12646
  }
12574
12647
  const propName = prop.getName();
12575
12648
  if (propName === pattern.methodProperty) {
12576
12649
  const val = prop.getInitializer();
12577
- if (val !== void 0 && import_ts_morph56.Node.isStringLiteral(val)) {
12650
+ if (val !== void 0 && import_ts_morph57.Node.isStringLiteral(val)) {
12578
12651
  method = val.getLiteralValue();
12579
12652
  }
12580
12653
  }
12581
12654
  if (propName === pattern.pathProperty) {
12582
12655
  const val = prop.getInitializer();
12583
- if (val !== void 0 && import_ts_morph56.Node.isStringLiteral(val)) {
12656
+ if (val !== void 0 && import_ts_morph57.Node.isStringLiteral(val)) {
12584
12657
  path14 = val.getLiteralValue();
12585
12658
  }
12586
12659
  }
12587
12660
  if (propName === pattern.responseExtraction.property) {
12588
- const val = prop.getInitializer();
12589
- if (val !== void 0 && import_ts_morph56.Node.isObjectLiteralExpression(val)) {
12590
- for (const respProp of val.getProperties()) {
12591
- if (!import_ts_morph56.Node.isPropertyAssignment(respProp)) {
12661
+ const written = prop.getInitializer();
12662
+ const val = written === void 0 ? null : objectLiteralOf(written, resolution);
12663
+ if (val !== null) {
12664
+ for (const respProp of propertiesOf(val, resolution)) {
12665
+ if (!import_ts_morph57.Node.isPropertyAssignment(respProp)) {
12592
12666
  continue;
12593
12667
  }
12594
12668
  const statusStr = respProp.getName();
@@ -12626,18 +12700,23 @@ function readContract(unit, pattern, framework, resolution) {
12626
12700
  if (endpointNode === null) {
12627
12701
  return null;
12628
12702
  }
12629
- return extractEndpointContract(endpointNode, pattern, framework);
12703
+ return extractEndpointContract(
12704
+ endpointNode,
12705
+ pattern,
12706
+ framework,
12707
+ resolution
12708
+ );
12630
12709
  }
12631
12710
  const routerInfo = findRouterCall(unit);
12632
12711
  if (routerInfo === null) {
12633
12712
  return null;
12634
12713
  }
12635
12714
  const contractObj = resolveContractObject(routerInfo.contractArg, resolution);
12636
- if (contractObj === null || !import_ts_morph56.Node.isObjectLiteralExpression(contractObj)) {
12715
+ if (contractObj === null || !import_ts_morph57.Node.isObjectLiteralExpression(contractObj)) {
12637
12716
  return null;
12638
12717
  }
12639
12718
  for (const prop of contractObj.getProperties()) {
12640
- if (!import_ts_morph56.Node.isPropertyAssignment(prop)) {
12719
+ if (!import_ts_morph57.Node.isPropertyAssignment(prop)) {
12641
12720
  continue;
12642
12721
  }
12643
12722
  if (prop.getName() !== routerInfo.handlerName) {
@@ -12647,7 +12726,12 @@ function readContract(unit, pattern, framework, resolution) {
12647
12726
  if (endpointInit === void 0) {
12648
12727
  continue;
12649
12728
  }
12650
- return extractEndpointContract(endpointInit, pattern, framework);
12729
+ return extractEndpointContract(
12730
+ endpointInit,
12731
+ pattern,
12732
+ framework,
12733
+ resolution
12734
+ );
12651
12735
  }
12652
12736
  return null;
12653
12737
  }
@@ -12657,7 +12741,7 @@ function endpointFromRegistrationArgument(unit, position, resolution) {
12657
12741
  return null;
12658
12742
  }
12659
12743
  const call = func.getParent();
12660
- if (call === void 0 || !import_ts_morph56.Node.isCallExpression(call)) {
12744
+ if (call === void 0 || !import_ts_morph57.Node.isCallExpression(call)) {
12661
12745
  return null;
12662
12746
  }
12663
12747
  const args = call.getArguments();
@@ -12669,24 +12753,24 @@ function endpointFromRegistrationArgument(unit, position, resolution) {
12669
12753
  return null;
12670
12754
  }
12671
12755
  let node = arg;
12672
- while (import_ts_morph56.Node.isAsExpression(node)) {
12756
+ while (import_ts_morph57.Node.isAsExpression(node)) {
12673
12757
  node = node.getExpression();
12674
12758
  }
12675
- if (import_ts_morph56.Node.isObjectLiteralExpression(node)) {
12759
+ if (import_ts_morph57.Node.isObjectLiteralExpression(node)) {
12676
12760
  return node;
12677
12761
  }
12678
- if (import_ts_morph56.Node.isCallExpression(node)) {
12762
+ if (import_ts_morph57.Node.isCallExpression(node)) {
12679
12763
  return unwrapContractInit(node);
12680
12764
  }
12681
12765
  return resolveContractObject(node, resolution);
12682
12766
  }
12683
12767
  function readContractForClientCall(callExpression, methodName, pattern, framework, resolution) {
12684
- const callee = import_ts_morph56.Node.isCallExpression(callExpression) ? callExpression.getExpression() : null;
12685
- if (callee === null || !import_ts_morph56.Node.isPropertyAccessExpression(callee)) {
12768
+ const callee = import_ts_morph57.Node.isCallExpression(callExpression) ? callExpression.getExpression() : null;
12769
+ if (callee === null || !import_ts_morph57.Node.isPropertyAccessExpression(callee)) {
12686
12770
  return null;
12687
12771
  }
12688
12772
  const clientIdentifier = callee.getExpression();
12689
- if (!import_ts_morph56.Node.isIdentifier(clientIdentifier)) {
12773
+ if (!import_ts_morph57.Node.isIdentifier(clientIdentifier)) {
12690
12774
  return null;
12691
12775
  }
12692
12776
  const symbol = clientIdentifier.getSymbol();
@@ -12698,11 +12782,11 @@ function readContractForClientCall(callExpression, methodName, pattern, framewor
12698
12782
  return null;
12699
12783
  }
12700
12784
  const decl = decls[0];
12701
- if (!import_ts_morph56.Node.isVariableDeclaration(decl)) {
12785
+ if (!import_ts_morph57.Node.isVariableDeclaration(decl)) {
12702
12786
  return null;
12703
12787
  }
12704
12788
  const init = decl.getInitializer();
12705
- if (init === void 0 || !import_ts_morph56.Node.isCallExpression(init)) {
12789
+ if (init === void 0 || !import_ts_morph57.Node.isCallExpression(init)) {
12706
12790
  return null;
12707
12791
  }
12708
12792
  const args = init.getArguments();
@@ -12710,11 +12794,11 @@ function readContractForClientCall(callExpression, methodName, pattern, framewor
12710
12794
  return null;
12711
12795
  }
12712
12796
  const contractObj = resolveContractObject(args[0], resolution);
12713
- if (contractObj === null || !import_ts_morph56.Node.isObjectLiteralExpression(contractObj)) {
12797
+ if (contractObj === null || !import_ts_morph57.Node.isObjectLiteralExpression(contractObj)) {
12714
12798
  return null;
12715
12799
  }
12716
12800
  for (const prop of contractObj.getProperties()) {
12717
- if (!import_ts_morph56.Node.isPropertyAssignment(prop)) {
12801
+ if (!import_ts_morph57.Node.isPropertyAssignment(prop)) {
12718
12802
  continue;
12719
12803
  }
12720
12804
  if (prop.getName() !== methodName) {
@@ -12724,7 +12808,12 @@ function readContractForClientCall(callExpression, methodName, pattern, framewor
12724
12808
  if (endpointInit === void 0) {
12725
12809
  continue;
12726
12810
  }
12727
- return extractEndpointContract(endpointInit, pattern, framework);
12811
+ return extractEndpointContract(
12812
+ endpointInit,
12813
+ pattern,
12814
+ framework,
12815
+ resolution
12816
+ );
12728
12817
  }
12729
12818
  return null;
12730
12819
  }
@@ -12805,7 +12894,7 @@ function parameterName(segment, convention) {
12805
12894
 
12806
12895
  // src/discovery/graphqlClientConstruction.ts
12807
12896
  var import_picomatch2 = __toESM(require("picomatch"), 1);
12808
- var import_ts_morph57 = require("ts-morph");
12897
+ var import_ts_morph58 = require("ts-morph");
12809
12898
  var import_behavioral_ir5 = require("@suss/behavioral-ir");
12810
12899
  function stampGraphqlClientRefs(summaries, sourceFiles, packs, resolution) {
12811
12900
  const scopes = compileOperationScopes(packs);
@@ -12953,7 +13042,7 @@ function constructionRegistryStatus(construction, spec) {
12953
13042
  if (cacheConstruction === null) {
12954
13043
  return "unknown";
12955
13044
  }
12956
- if (!import_ts_morph57.Node.isNewExpression(cacheConstruction) && !import_ts_morph57.Node.isCallExpression(cacheConstruction)) {
13045
+ if (!import_ts_morph58.Node.isNewExpression(cacheConstruction) && !import_ts_morph58.Node.isCallExpression(cacheConstruction)) {
12957
13046
  return "unknown";
12958
13047
  }
12959
13048
  const args = cacheConstruction.getArguments();
@@ -12967,15 +13056,15 @@ function constructionRegistryStatus(construction, spec) {
12967
13056
  if (cacheOptions.getProperty(spec.registryProperty) !== void 0) {
12968
13057
  return "configured";
12969
13058
  }
12970
- const hasSpread = cacheOptions.getProperties().some((property) => import_ts_morph57.Node.isSpreadAssignment(property));
13059
+ const hasSpread = cacheOptions.getProperties().some((property) => import_ts_morph58.Node.isSpreadAssignment(property));
12971
13060
  return hasSpread ? "unknown" : "absent";
12972
13061
  }
12973
13062
  function firstArgumentObjectLiteral(construction) {
12974
- if (!import_ts_morph57.Node.isNewExpression(construction) && !import_ts_morph57.Node.isCallExpression(construction)) {
13063
+ if (!import_ts_morph58.Node.isNewExpression(construction) && !import_ts_morph58.Node.isCallExpression(construction)) {
12975
13064
  return null;
12976
13065
  }
12977
13066
  const arg = construction.getArguments()[0];
12978
- if (arg === void 0 || !import_ts_morph57.Node.isObjectLiteralExpression(arg)) {
13067
+ if (arg === void 0 || !import_ts_morph58.Node.isObjectLiteralExpression(arg)) {
12979
13068
  return null;
12980
13069
  }
12981
13070
  return arg;
@@ -12985,10 +13074,10 @@ function propertyValueOf2(options, name) {
12985
13074
  if (property === void 0) {
12986
13075
  return null;
12987
13076
  }
12988
- if (import_ts_morph57.Node.isPropertyAssignment(property)) {
13077
+ if (import_ts_morph58.Node.isPropertyAssignment(property)) {
12989
13078
  return property.getInitializer() ?? null;
12990
13079
  }
12991
- if (import_ts_morph57.Node.isShorthandPropertyAssignment(property)) {
13080
+ if (import_ts_morph58.Node.isShorthandPropertyAssignment(property)) {
12992
13081
  const symbol = property.getProject().getTypeChecker().getShorthandAssignmentValueSymbol(property);
12993
13082
  return symbol?.getValueDeclaration() ?? null;
12994
13083
  }
@@ -12998,13 +13087,13 @@ function resolveToConstructionOf(expression, cacheClass) {
12998
13087
  let current2 = expression;
12999
13088
  for (let hop = 0; hop < 4 && current2 !== void 0; hop += 1) {
13000
13089
  current2 = unwrapExpression2(current2);
13001
- if (import_ts_morph57.Node.isVariableDeclaration(current2)) {
13090
+ if (import_ts_morph58.Node.isVariableDeclaration(current2)) {
13002
13091
  current2 = current2.getInitializer();
13003
13092
  continue;
13004
13093
  }
13005
- if (import_ts_morph57.Node.isNewExpression(current2) || import_ts_morph57.Node.isCallExpression(current2)) {
13094
+ if (import_ts_morph58.Node.isNewExpression(current2) || import_ts_morph58.Node.isCallExpression(current2)) {
13006
13095
  const callee = current2.getExpression();
13007
- if (callee === void 0 || !import_ts_morph57.Node.isIdentifier(callee)) {
13096
+ if (callee === void 0 || !import_ts_morph58.Node.isIdentifier(callee)) {
13008
13097
  return null;
13009
13098
  }
13010
13099
  const local = localImportName(
@@ -13014,11 +13103,11 @@ function resolveToConstructionOf(expression, cacheClass) {
13014
13103
  );
13015
13104
  return local !== null && callee.getText() === local ? current2 : null;
13016
13105
  }
13017
- if (!import_ts_morph57.Node.isIdentifier(current2)) {
13106
+ if (!import_ts_morph58.Node.isIdentifier(current2)) {
13018
13107
  return null;
13019
13108
  }
13020
13109
  const declaration = current2.getSymbol()?.getValueDeclaration();
13021
- if (declaration === void 0 || !import_ts_morph57.Node.isVariableDeclaration(declaration)) {
13110
+ if (declaration === void 0 || !import_ts_morph58.Node.isVariableDeclaration(declaration)) {
13022
13111
  return null;
13023
13112
  }
13024
13113
  current2 = declaration.getInitializer();
@@ -13029,11 +13118,11 @@ function unwrapExpression2(node) {
13029
13118
  return peelSyntax(node);
13030
13119
  }
13031
13120
  function isConstructionNamed(node, localName) {
13032
- if (!import_ts_morph57.Node.isNewExpression(node) && !import_ts_morph57.Node.isCallExpression(node)) {
13121
+ if (!import_ts_morph58.Node.isNewExpression(node) && !import_ts_morph58.Node.isCallExpression(node)) {
13033
13122
  return false;
13034
13123
  }
13035
13124
  const callee = node.getExpression();
13036
- return callee !== void 0 && import_ts_morph57.Node.isIdentifier(callee) && callee.getText() === localName;
13125
+ return callee !== void 0 && import_ts_morph58.Node.isIdentifier(callee) && callee.getText() === localName;
13037
13126
  }
13038
13127
  function localImportName(sourceFile, importModule, importName) {
13039
13128
  for (const one of namedImportsOf(sourceFile, [importModule], {
@@ -13047,11 +13136,11 @@ function localImportName(sourceFile, importModule, importName) {
13047
13136
  }
13048
13137
  function constructionRef(node, uriProperty, resolution) {
13049
13138
  const optionsArg = node.getArguments()[0];
13050
- if (optionsArg === void 0 || !import_ts_morph57.Node.isObjectLiteralExpression(optionsArg)) {
13139
+ if (optionsArg === void 0 || !import_ts_morph58.Node.isObjectLiteralExpression(optionsArg)) {
13051
13140
  return null;
13052
13141
  }
13053
13142
  const property = optionsArg.getProperty(uriProperty);
13054
- if (property === void 0 || !import_ts_morph57.Node.isPropertyAssignment(property)) {
13143
+ if (property === void 0 || !import_ts_morph58.Node.isPropertyAssignment(property)) {
13055
13144
  return null;
13056
13145
  }
13057
13146
  const value = property.getInitializer();
@@ -13066,10 +13155,10 @@ function constructionRef(node, uriProperty, resolution) {
13066
13155
  }
13067
13156
 
13068
13157
  // src/discovery/helperIndex.ts
13069
- var import_ts_morph59 = require("ts-morph");
13158
+ var import_ts_morph60 = require("ts-morph");
13070
13159
 
13071
13160
  // src/discovery/helperReading.ts
13072
- var import_ts_morph58 = require("ts-morph");
13161
+ var import_ts_morph59 = require("ts-morph");
13073
13162
  var UNREAD = { as: "unread" };
13074
13163
  function readHelperSinks(helper) {
13075
13164
  const positions = parameterPositions(helper);
@@ -13079,11 +13168,11 @@ function readHelperSinks(helper) {
13079
13168
  return sinks;
13080
13169
  }
13081
13170
  body.forEachDescendant((node) => {
13082
- if (!import_ts_morph58.Node.isCallExpression(node)) {
13171
+ if (!import_ts_morph59.Node.isCallExpression(node)) {
13083
13172
  return;
13084
13173
  }
13085
13174
  const callee = node.getExpression();
13086
- const [method, receiver] = import_ts_morph58.Node.isPropertyAccessExpression(callee) ? [callee.getName(), readValue(callee.getExpression(), positions)] : [null, UNREAD];
13175
+ const [method, receiver] = import_ts_morph59.Node.isPropertyAccessExpression(callee) ? [callee.getName(), readValue(callee.getExpression(), positions)] : [null, UNREAD];
13087
13176
  sinks.push({
13088
13177
  method,
13089
13178
  receiver,
@@ -13103,25 +13192,25 @@ function parameterPositions(helper) {
13103
13192
  return positions;
13104
13193
  }
13105
13194
  function readValue(node, positions) {
13106
- if (import_ts_morph58.Node.isStringLiteral(node) || import_ts_morph58.Node.isNoSubstitutionTemplateLiteral(node)) {
13195
+ if (import_ts_morph59.Node.isStringLiteral(node) || import_ts_morph59.Node.isNoSubstitutionTemplateLiteral(node)) {
13107
13196
  return { as: "text", text: node.getLiteralValue() };
13108
13197
  }
13109
- if (import_ts_morph58.Node.isTemplateExpression(node)) {
13198
+ if (import_ts_morph59.Node.isTemplateExpression(node)) {
13110
13199
  return templateText(node, positions);
13111
13200
  }
13112
- if (import_ts_morph58.Node.isIdentifier(node)) {
13201
+ if (import_ts_morph59.Node.isIdentifier(node)) {
13113
13202
  const position = positions.get(node.getText());
13114
13203
  return position === void 0 ? UNREAD : { as: "parameter", position };
13115
13204
  }
13116
- if (import_ts_morph58.Node.isPropertyAccessExpression(node)) {
13205
+ if (import_ts_morph59.Node.isPropertyAccessExpression(node)) {
13117
13206
  const target = node.getExpression();
13118
- const position = import_ts_morph58.Node.isIdentifier(target) ? positions.get(target.getText()) : void 0;
13207
+ const position = import_ts_morph59.Node.isIdentifier(target) ? positions.get(target.getText()) : void 0;
13119
13208
  return position === void 0 ? UNREAD : { as: "parameter", position, property: node.getName() };
13120
13209
  }
13121
- if (import_ts_morph58.Node.isObjectLiteralExpression(node)) {
13210
+ if (import_ts_morph59.Node.isObjectLiteralExpression(node)) {
13122
13211
  return objectValue(node, positions);
13123
13212
  }
13124
- if (import_ts_morph58.Node.isCallExpression(node)) {
13213
+ if (import_ts_morph59.Node.isCallExpression(node)) {
13125
13214
  return {
13126
13215
  as: "call",
13127
13216
  callee: node.getExpression().getText(),
@@ -13131,13 +13220,13 @@ function readValue(node, positions) {
13131
13220
  return UNREAD;
13132
13221
  }
13133
13222
  function templateText(node, positions) {
13134
- if (!import_ts_morph58.Node.isTemplateExpression(node)) {
13223
+ if (!import_ts_morph59.Node.isTemplateExpression(node)) {
13135
13224
  return UNREAD;
13136
13225
  }
13137
13226
  let text = node.getHead().getLiteralText();
13138
13227
  for (const span of node.getTemplateSpans()) {
13139
13228
  const expression = span.getExpression();
13140
- const position = import_ts_morph58.Node.isIdentifier(expression) ? positions.get(expression.getText()) : void 0;
13229
+ const position = import_ts_morph59.Node.isIdentifier(expression) ? positions.get(expression.getText()) : void 0;
13141
13230
  if (position === void 0) {
13142
13231
  return UNREAD;
13143
13232
  }
@@ -13146,12 +13235,12 @@ function templateText(node, positions) {
13146
13235
  return { as: "text", text };
13147
13236
  }
13148
13237
  function objectValue(node, positions) {
13149
- if (!import_ts_morph58.Node.isObjectLiteralExpression(node)) {
13238
+ if (!import_ts_morph59.Node.isObjectLiteralExpression(node)) {
13150
13239
  return UNREAD;
13151
13240
  }
13152
13241
  const properties = {};
13153
13242
  for (const property of node.getProperties()) {
13154
- if (!import_ts_morph58.Node.isPropertyAssignment(property)) {
13243
+ if (!import_ts_morph59.Node.isPropertyAssignment(property)) {
13155
13244
  continue;
13156
13245
  }
13157
13246
  const initializer = property.getInitializer();
@@ -13166,7 +13255,7 @@ function objectValue(node, positions) {
13166
13255
  return { as: "object", properties };
13167
13256
  }
13168
13257
  function propertyKey(name) {
13169
- return import_ts_morph58.Node.isStringLiteral(name) ? name.getLiteralValue() : name.getText();
13258
+ return import_ts_morph59.Node.isStringLiteral(name) ? name.getLiteralValue() : name.getText();
13170
13259
  }
13171
13260
 
13172
13261
  // src/discovery/helperIndex.ts
@@ -13296,11 +13385,11 @@ function registrationMatchesOf(pack) {
13296
13385
  }
13297
13386
  function collectHandOffs(sourceFile, subjects, match, resolution, found) {
13298
13387
  sourceFile.forEachDescendant((node) => {
13299
- if (!import_ts_morph59.Node.isCallExpression(node)) {
13388
+ if (!import_ts_morph60.Node.isCallExpression(node)) {
13300
13389
  return;
13301
13390
  }
13302
13391
  const callee = node.getExpression();
13303
- if (!import_ts_morph59.Node.isIdentifier(callee)) {
13392
+ if (!import_ts_morph60.Node.isIdentifier(callee)) {
13304
13393
  return;
13305
13394
  }
13306
13395
  const handedOver = subjectArgument(node, subjects, match, resolution);
@@ -13315,12 +13404,12 @@ function collectHandOffs(sourceFile, subjects, match, resolution, found) {
13315
13404
  });
13316
13405
  }
13317
13406
  function subjectArgument(call, subjects, match, resolution) {
13318
- if (!import_ts_morph59.Node.isCallExpression(call)) {
13407
+ if (!import_ts_morph60.Node.isCallExpression(call)) {
13319
13408
  return -1;
13320
13409
  }
13321
13410
  const args = call.getArguments();
13322
13411
  for (const [position, argument] of args.entries()) {
13323
- if (!import_ts_morph59.Node.isIdentifier(argument) && !import_ts_morph59.Node.isPropertyAccessExpression(argument)) {
13412
+ if (!import_ts_morph60.Node.isIdentifier(argument) && !import_ts_morph60.Node.isPropertyAccessExpression(argument)) {
13324
13413
  continue;
13325
13414
  }
13326
13415
  if (subjectNodeFor(argument, subjects, match, resolution) !== void 0) {
@@ -13381,7 +13470,7 @@ function declaredFunctions(sourceFile) {
13381
13470
  }
13382
13471
  for (const variable4 of sourceFile.getVariableDeclarations()) {
13383
13472
  const initializer = variable4.getInitializer();
13384
- if (initializer !== void 0 && (import_ts_morph59.Node.isArrowFunction(initializer) || import_ts_morph59.Node.isFunctionExpression(initializer))) {
13473
+ if (initializer !== void 0 && (import_ts_morph60.Node.isArrowFunction(initializer) || import_ts_morph60.Node.isFunctionExpression(initializer))) {
13385
13474
  found.push([variable4.getName(), initializer]);
13386
13475
  }
13387
13476
  }
@@ -13474,9 +13563,13 @@ function recordEdge(edgesByChild, candidate) {
13474
13563
  }
13475
13564
 
13476
13565
  // src/discovery/wrapperIndex.ts
13477
- var import_ts_morph60 = require("ts-morph");
13566
+ var import_ts_morph61 = require("ts-morph");
13478
13567
  var import_resolution6 = require("@suss/resolution");
13479
- var NO_WRAPPERS = { wrappersFor: () => [], unitsIn: () => [] };
13568
+ var NO_WRAPPERS = {
13569
+ wrappersFor: () => [],
13570
+ unfollowedFor: () => [],
13571
+ unitsIn: () => []
13572
+ };
13480
13573
  var ANONYMOUS = "<anon>";
13481
13574
  function buildWrapperIndex(packsByFile, resolution, mountPrefixes) {
13482
13575
  const workByPack = /* @__PURE__ */ new Map();
@@ -13502,21 +13595,32 @@ function buildWrapperIndex(packsByFile, resolution, mountPrefixes) {
13502
13595
  }
13503
13596
  }
13504
13597
  const bySubject = /* @__PURE__ */ new Map();
13598
+ const unfollowedBySubject = /* @__PURE__ */ new Map();
13505
13599
  const unitsByFile = /* @__PURE__ */ new Map();
13600
+ const stopsSeen = /* @__PURE__ */ new Set();
13506
13601
  let found = false;
13507
13602
  for (const [packName, work] of workByPack) {
13508
13603
  const candidates = [];
13509
13604
  for (const { sourceFile, pattern, match, wraps } of work) {
13510
- candidates.push(
13511
- ...discoverWrapperRegistrations(
13512
- sourceFile,
13513
- pattern,
13514
- match,
13515
- wraps,
13516
- resolution,
13517
- mountPrefixes
13518
- )
13605
+ const scan = discoverWrapperRegistrations(
13606
+ sourceFile,
13607
+ pattern,
13608
+ match,
13609
+ wraps,
13610
+ resolution,
13611
+ mountPrefixes
13519
13612
  );
13613
+ candidates.push(...scan.candidates);
13614
+ for (const { subjectId, callId, stop } of scan.unresolved) {
13615
+ if (stopsSeen.has(callId)) {
13616
+ continue;
13617
+ }
13618
+ stopsSeen.add(callId);
13619
+ found = true;
13620
+ const stops = unfollowedBySubject.get(subjectId) ?? [];
13621
+ stops.push(stop);
13622
+ unfollowedBySubject.set(subjectId, stops);
13623
+ }
13520
13624
  }
13521
13625
  for (const candidate of mostSpecific(candidates)) {
13522
13626
  found = true;
@@ -13534,6 +13638,7 @@ function buildWrapperIndex(packsByFile, resolution, mountPrefixes) {
13534
13638
  }
13535
13639
  return {
13536
13640
  wrappersFor: (subjectId) => bySubject.get(subjectId) ?? [],
13641
+ unfollowedFor: (subjectId) => unfollowedBySubject.get(subjectId) ?? [],
13537
13642
  unitsIn: (file, pack) => unitsByFile.get(unitKey(file, pack)) ?? []
13538
13643
  };
13539
13644
  }
@@ -13567,16 +13672,26 @@ function discoverWrapperRegistrations(sourceFile, pattern, match, wraps, resolut
13567
13672
  match.importName,
13568
13673
  resolution
13569
13674
  );
13675
+ if ("constructorOption" in wraps) {
13676
+ return discoverConstructorOptions(
13677
+ sourceFile,
13678
+ pattern,
13679
+ wraps,
13680
+ subjects,
13681
+ resolution
13682
+ );
13683
+ }
13570
13684
  if (subjects.size === 0 && !storeCanFindSubjects(sourceFile, match, resolution)) {
13571
- return [];
13685
+ return { candidates: [], unresolved: [] };
13572
13686
  }
13573
13687
  const candidates = [];
13688
+ const unresolved = [];
13574
13689
  sourceFile.forEachDescendant((node) => {
13575
- if (!import_ts_morph60.Node.isCallExpression(node)) {
13690
+ if (!import_ts_morph61.Node.isCallExpression(node)) {
13576
13691
  return;
13577
13692
  }
13578
13693
  const callee = node.getExpression();
13579
- if (!import_ts_morph60.Node.isPropertyAccessExpression(callee) || callee.getName() !== wraps.method) {
13694
+ if (!import_ts_morph61.Node.isPropertyAccessExpression(callee) || callee.getName() !== wraps.method) {
13580
13695
  return;
13581
13696
  }
13582
13697
  const subjectNode = subjectNodeFor(
@@ -13593,8 +13708,13 @@ function discoverWrapperRegistrations(sourceFile, pattern, match, wraps, resolut
13593
13708
  if (targetArg === void 0) {
13594
13709
  return;
13595
13710
  }
13711
+ const subjectId = nodeId(subjectNode);
13596
13712
  const target = functionValueOf(targetArg, resolution);
13597
13713
  if (target === null) {
13714
+ const stop = factoryStopOf(targetArg);
13715
+ if (stop !== null) {
13716
+ unresolved.push({ subjectId, callId: nodeId(node), stop });
13717
+ }
13598
13718
  return;
13599
13719
  }
13600
13720
  if (wraps.arity !== void 0 && target.getParameters().length !== wraps.arity) {
@@ -13604,29 +13724,136 @@ function discoverWrapperRegistrations(sourceFile, pattern, match, wraps, resolut
13604
13724
  if (scope === null) {
13605
13725
  return;
13606
13726
  }
13607
- const subjectId = nodeId(subjectNode);
13608
13727
  const mountedScope = scope === void 0 ? void 0 : mountedAt(subjectId, mountPrefixes, scope);
13609
- const named2 = functionNameOrAnon(target) !== ANONYMOUS;
13610
- candidates.push({
13611
- subjectId,
13612
- callId: nodeId(node),
13613
- targetId: nodeId(target),
13614
- byArity: wraps.arity !== void 0,
13615
- target,
13616
- pattern,
13617
- registeredIn: sourceFile.getFilePath(),
13618
- named: named2,
13619
- reference: {
13620
- file: target.getSourceFile().getFilePath(),
13621
- // A function written out at the registration call has no name
13622
- // of its own, so it goes by the method that registered it.
13623
- name: named2 ? functionNameOrAnon(target) : wraps.method,
13624
- ...wraps.throwParam === void 0 ? {} : { onThrow: true },
13625
- ...mountedScope === void 0 ? {} : { scope: mountedScope }
13626
- }
13627
- });
13728
+ candidates.push(
13729
+ candidateOf(
13730
+ {
13731
+ subjectId,
13732
+ callId: nodeId(node),
13733
+ target,
13734
+ label: labelFor(targetArg, wraps),
13735
+ byArity: wraps.arity !== void 0,
13736
+ onThrow: wraps.throwParam !== void 0,
13737
+ scope: mountedScope
13738
+ },
13739
+ pattern,
13740
+ sourceFile
13741
+ )
13742
+ );
13628
13743
  });
13629
- return candidates;
13744
+ return { candidates, unresolved };
13745
+ }
13746
+ function discoverConstructorOptions(sourceFile, pattern, wraps, subjects, resolution) {
13747
+ const candidates = [];
13748
+ const unresolved = [];
13749
+ const seen = /* @__PURE__ */ new Set();
13750
+ for (const construction of subjects.values()) {
13751
+ const subjectId = nodeId(construction);
13752
+ if (seen.has(subjectId) || construction.getSourceFile() !== sourceFile) {
13753
+ continue;
13754
+ }
13755
+ seen.add(subjectId);
13756
+ const option = constructorOptionOf(construction, wraps, resolution);
13757
+ if (option === void 0) {
13758
+ continue;
13759
+ }
13760
+ const callId = nodeId(option);
13761
+ const written = propertyValueOf(option);
13762
+ const target = propertyFunctionOf(option, resolution);
13763
+ if (target === null) {
13764
+ const stop = written === null ? null : factoryStopOf(written);
13765
+ if (stop !== null) {
13766
+ unresolved.push({ subjectId, callId, stop });
13767
+ }
13768
+ continue;
13769
+ }
13770
+ candidates.push(
13771
+ candidateOf(
13772
+ {
13773
+ subjectId,
13774
+ callId,
13775
+ target,
13776
+ label: (written === null ? void 0 : factoryNameOf(written)) ?? wraps.constructorOption,
13777
+ byArity: false,
13778
+ onThrow: wraps.throwParam !== void 0,
13779
+ scope: void 0
13780
+ },
13781
+ pattern,
13782
+ sourceFile
13783
+ )
13784
+ );
13785
+ }
13786
+ return { candidates, unresolved };
13787
+ }
13788
+ function constructorOptionOf(construction, wraps, resolution) {
13789
+ if (!(import_ts_morph61.Node.isNewExpression(construction) || import_ts_morph61.Node.isCallExpression(construction))) {
13790
+ return void 0;
13791
+ }
13792
+ const optionsArg = construction.getArguments()[wraps.targetPosition];
13793
+ if (optionsArg === void 0) {
13794
+ return void 0;
13795
+ }
13796
+ const options = objectLiteralOf(optionsArg, resolution);
13797
+ if (options === null) {
13798
+ return void 0;
13799
+ }
13800
+ return propertiesOf(options, resolution).find(
13801
+ (property) => propertyNameOf(property) === wraps.constructorOption
13802
+ );
13803
+ }
13804
+ function candidateOf(registration, pattern, sourceFile) {
13805
+ const { target, label, onThrow, scope } = registration;
13806
+ const named2 = functionNameOrAnon(target) !== ANONYMOUS;
13807
+ return {
13808
+ subjectId: registration.subjectId,
13809
+ callId: registration.callId,
13810
+ targetId: nodeId(target),
13811
+ byArity: registration.byArity,
13812
+ target,
13813
+ pattern,
13814
+ registeredIn: sourceFile.getFilePath(),
13815
+ named: named2,
13816
+ reference: {
13817
+ file: target.getSourceFile().getFilePath(),
13818
+ name: named2 ? functionNameOrAnon(target) : label,
13819
+ ...onThrow ? { onThrow: true } : {},
13820
+ ...scope === void 0 ? {} : { scope }
13821
+ }
13822
+ };
13823
+ }
13824
+ function labelFor(targetArg, wraps) {
13825
+ return factoryNameOf(targetArg) ?? wraps.method;
13826
+ }
13827
+ function factoryNameOf(targetArg) {
13828
+ const written = factKeyOf(targetArg);
13829
+ if (!import_ts_morph61.Node.isCallExpression(written)) {
13830
+ return void 0;
13831
+ }
13832
+ const callee = written.getExpression();
13833
+ if (import_ts_morph61.Node.isIdentifier(callee)) {
13834
+ return callee.getText();
13835
+ }
13836
+ if (import_ts_morph61.Node.isPropertyAccessExpression(callee)) {
13837
+ return callee.getName();
13838
+ }
13839
+ return void 0;
13840
+ }
13841
+ function factoryStopOf(targetArg) {
13842
+ const written = factKeyOf(targetArg);
13843
+ if (!import_ts_morph61.Node.isCallExpression(written)) {
13844
+ return null;
13845
+ }
13846
+ const callee = factoryNameOf(targetArg);
13847
+ if (callee === void 0) {
13848
+ return null;
13849
+ }
13850
+ const reason = classifyStop(
13851
+ declarationsBehind(written.getExpression().getSymbol())
13852
+ );
13853
+ if (!(0, import_behavioral_ir2.worthRecording)(reason)) {
13854
+ return null;
13855
+ }
13856
+ return { callee, reason: "unresolvedWrapper" };
13630
13857
  }
13631
13858
  function mountedAt(subjectId, mountPrefixes, scope) {
13632
13859
  const prefix = mountPrefixes?.prefixForId?.(subjectId) ?? "";
@@ -13644,7 +13871,7 @@ function scopeOf(args, wraps, resolution) {
13644
13871
  }
13645
13872
 
13646
13873
  // src/discoveryContext.ts
13647
- var import_ts_morph61 = require("ts-morph");
13874
+ var import_ts_morph62 = require("ts-morph");
13648
13875
  function createTsDiscoveryContext(resolution) {
13649
13876
  const store = resolution ?? new ResolutionStore();
13650
13877
  return {
@@ -13679,7 +13906,7 @@ function exportedFunctions(sourceFile, resolution) {
13679
13906
  return out;
13680
13907
  }
13681
13908
  function exportedFunction(decl, resolution) {
13682
- const writtenAgain = import_ts_morph61.Node.isVariableDeclaration(decl) && isWrittenAgain(decl);
13909
+ const writtenAgain = import_ts_morph62.Node.isVariableDeclaration(decl) && isWrittenAgain(decl);
13683
13910
  if (!writtenAgain) {
13684
13911
  const declared = resolveDeclarationToFunction(decl);
13685
13912
  if (declared !== null) {
@@ -13700,7 +13927,7 @@ function valueToAskAbout(decl, writtenAgain) {
13700
13927
  if (writtenAgain) {
13701
13928
  return decl;
13702
13929
  }
13703
- const value = import_ts_morph61.Node.isVariableDeclaration(decl) ? decl.getInitializer() ?? decl : decl;
13930
+ const value = import_ts_morph62.Node.isVariableDeclaration(decl) ? decl.getInitializer() ?? decl : decl;
13704
13931
  return couldStillNameAFunction(value) ? value : null;
13705
13932
  }
13706
13933
  function resolveDeclarationToFunction(decl) {
@@ -13708,18 +13935,18 @@ function resolveDeclarationToFunction(decl) {
13708
13935
  if (fn !== null) {
13709
13936
  return fn;
13710
13937
  }
13711
- if (import_ts_morph61.Node.isVariableDeclaration(decl)) {
13938
+ if (import_ts_morph62.Node.isVariableDeclaration(decl)) {
13712
13939
  const init = decl.getInitializer();
13713
- if (init !== void 0 && (import_ts_morph61.Node.isArrowFunction(init) || import_ts_morph61.Node.isFunctionExpression(init))) {
13940
+ if (init !== void 0 && (import_ts_morph62.Node.isArrowFunction(init) || import_ts_morph62.Node.isFunctionExpression(init))) {
13714
13941
  return init;
13715
13942
  }
13716
13943
  }
13717
13944
  return null;
13718
13945
  }
13719
13946
  function hasJsxReturn(func) {
13720
- if (import_ts_morph61.Node.isArrowFunction(func)) {
13947
+ if (import_ts_morph62.Node.isArrowFunction(func)) {
13721
13948
  const body2 = func.getBody();
13722
- if (import_ts_morph61.Node.isExpression(body2) && isJsxOrFragment(body2)) {
13949
+ if (import_ts_morph62.Node.isExpression(body2) && isJsxOrFragment(body2)) {
13723
13950
  return true;
13724
13951
  }
13725
13952
  }
@@ -13733,11 +13960,11 @@ function hasJsxReturn(func) {
13733
13960
  traversal.stop();
13734
13961
  return;
13735
13962
  }
13736
- if (node !== func && (import_ts_morph61.Node.isFunctionDeclaration(node) || import_ts_morph61.Node.isFunctionExpression(node) || import_ts_morph61.Node.isArrowFunction(node) || import_ts_morph61.Node.isMethodDeclaration(node))) {
13963
+ if (node !== func && (import_ts_morph62.Node.isFunctionDeclaration(node) || import_ts_morph62.Node.isFunctionExpression(node) || import_ts_morph62.Node.isArrowFunction(node) || import_ts_morph62.Node.isMethodDeclaration(node))) {
13737
13964
  traversal.skip();
13738
13965
  return;
13739
13966
  }
13740
- if (import_ts_morph61.Node.isReturnStatement(node)) {
13967
+ if (import_ts_morph62.Node.isReturnStatement(node)) {
13741
13968
  const expr = node.getExpression();
13742
13969
  if (expr !== void 0 && isJsxOrFragment(expr)) {
13743
13970
  found = true;
@@ -13748,7 +13975,7 @@ function hasJsxReturn(func) {
13748
13975
  }
13749
13976
  function isJsxOrFragment(node) {
13750
13977
  const current2 = peelParens(node);
13751
- return import_ts_morph61.Node.isJsxElement(current2) || import_ts_morph61.Node.isJsxSelfClosingElement(current2) || import_ts_morph61.Node.isJsxFragment(current2);
13978
+ return import_ts_morph62.Node.isJsxElement(current2) || import_ts_morph62.Node.isJsxSelfClosingElement(current2) || import_ts_morph62.Node.isJsxFragment(current2);
13752
13979
  }
13753
13980
 
13754
13981
  // src/graphqlContract.ts
@@ -13994,26 +14221,27 @@ function deriveBoundaryEffects(summaries, facts) {
13994
14221
  }
13995
14222
 
13996
14223
  // src/resolve/reachableClosure.ts
13997
- var import_ts_morph62 = require("ts-morph");
14224
+ var import_ts_morph63 = require("ts-morph");
13998
14225
  var import_behavioral_ir6 = require("@suss/behavioral-ir");
13999
14226
  var import_datalog4 = require("@suss/datalog");
14000
14227
  var import_extractor7 = require("@suss/extractor");
14228
+ var GENERIC_TERMINALS = [
14229
+ { kind: "return", match: { type: "returnStatement" }, extraction: {} },
14230
+ { kind: "throw", match: { type: "throwExpression" }, extraction: {} },
14231
+ {
14232
+ // Implicit fall-through at the end of a function body: covers
14233
+ // void-returning orchestrators that never write `return`.
14234
+ kind: "return",
14235
+ match: { type: "functionFallthrough" },
14236
+ extraction: {}
14237
+ }
14238
+ ];
14001
14239
  var reachablePack = {
14002
14240
  name: "reachable",
14003
14241
  languages: ["typescript"],
14004
14242
  protocol: "in-process",
14005
14243
  discovery: [],
14006
- terminals: [
14007
- { kind: "return", match: { type: "returnStatement" }, extraction: {} },
14008
- { kind: "throw", match: { type: "throwExpression" }, extraction: {} },
14009
- {
14010
- // Implicit fall-through at the end of a function body: covers
14011
- // void-returning orchestrators that never write `return`.
14012
- kind: "return",
14013
- match: { type: "functionFallthrough" },
14014
- extraction: {}
14015
- }
14016
- ],
14244
+ terminals: GENERIC_TERMINALS,
14017
14245
  inputMapping: { type: "allPositional" }
14018
14246
  };
14019
14247
  function nodeKey(func) {
@@ -14026,7 +14254,7 @@ function targetOf(node) {
14026
14254
  };
14027
14255
  }
14028
14256
  function resolveCallee(call, calleeName, scan) {
14029
- if (!import_ts_morph62.Node.isCallExpression(call)) {
14257
+ if (!import_ts_morph63.Node.isCallExpression(call)) {
14030
14258
  return null;
14031
14259
  }
14032
14260
  const callee = call.getExpression();
@@ -14039,7 +14267,7 @@ function resolveCallee(call, calleeName, scan) {
14039
14267
  }
14040
14268
  }
14041
14269
  const resolveSources = scan.resolveCallableSources;
14042
- if (resolveSources !== void 0 && import_ts_morph62.Node.isPropertyAccessExpression(callee) && declarations.some(isDeclaredShape)) {
14270
+ if (resolveSources !== void 0 && import_ts_morph63.Node.isPropertyAccessExpression(callee) && declarations.some(isDeclaredShape)) {
14043
14271
  const sources = resolveSources(callee, scan.reachedFrom);
14044
14272
  const only = sources.length === 1 ? sources[0] : void 0;
14045
14273
  const resolved = only === void 0 ? null : resolveDecl(only, calleeName);
@@ -14085,11 +14313,11 @@ function passedPositionKey(target, position) {
14085
14313
  return `${offsetKeyFor(target.file, target.span)}#${position}`;
14086
14314
  }
14087
14315
  function resolveJsxReference(node, scan) {
14088
- if (!import_ts_morph62.Node.isJsxOpeningElement(node) && !import_ts_morph62.Node.isJsxSelfClosingElement(node)) {
14316
+ if (!import_ts_morph63.Node.isJsxOpeningElement(node) && !import_ts_morph63.Node.isJsxSelfClosingElement(node)) {
14089
14317
  return null;
14090
14318
  }
14091
14319
  const tag = node.getTagNameNode();
14092
- if (!import_ts_morph62.Node.isIdentifier(tag) || !/^[A-Z]/.test(tag.getText())) {
14320
+ if (!import_ts_morph63.Node.isIdentifier(tag) || !/^[A-Z]/.test(tag.getText())) {
14093
14321
  return null;
14094
14322
  }
14095
14323
  const name = tag.getText();
@@ -14135,12 +14363,12 @@ function collectReachable(func, scan) {
14135
14363
  candidates.push(outcome.candidate);
14136
14364
  };
14137
14365
  const recordPassedArgs = (call, calleeText, calleeOutcome) => {
14138
- if (!import_ts_morph62.Node.isCallExpression(call)) {
14366
+ if (!import_ts_morph63.Node.isCallExpression(call)) {
14139
14367
  return;
14140
14368
  }
14141
14369
  const calleeTarget = declaredAtOf(calleeOutcome);
14142
14370
  call.getArguments().forEach((arg, position) => {
14143
- if (!import_ts_morph62.Node.isIdentifier(arg)) {
14371
+ if (!import_ts_morph63.Node.isIdentifier(arg)) {
14144
14372
  return;
14145
14373
  }
14146
14374
  const resolved = functionTargetOf(arg);
@@ -14160,7 +14388,7 @@ function collectReachable(func, scan) {
14160
14388
  record2(jsx.outcome);
14161
14389
  return;
14162
14390
  }
14163
- if (!import_ts_morph62.Node.isCallExpression(node)) {
14391
+ if (!import_ts_morph63.Node.isCallExpression(node)) {
14164
14392
  return;
14165
14393
  }
14166
14394
  const calleeText = normalizeCallee(node.getExpression().getText());
@@ -14246,7 +14474,7 @@ function recognizerOnlyRoots(packsByFile) {
14246
14474
  }
14247
14475
  for (const declaration of variableStatement.getDeclarations()) {
14248
14476
  const init = declaration.getInitializer();
14249
- if (init !== void 0 && (import_ts_morph62.Node.isArrowFunction(init) || import_ts_morph62.Node.isFunctionExpression(init)) && hasBody(init)) {
14477
+ if (init !== void 0 && (import_ts_morph63.Node.isArrowFunction(init) || import_ts_morph63.Node.isFunctionExpression(init)) && hasBody(init)) {
14250
14478
  roots.push({ func: init, name: declaration.getName() });
14251
14479
  }
14252
14480
  }
@@ -14500,7 +14728,7 @@ function recordParameterGaps(parameterCallsByKey, summariesByKey, passedPosition
14500
14728
  }
14501
14729
 
14502
14730
  // src/resolve/rethrowEnrichment.ts
14503
- var import_ts_morph63 = require("ts-morph");
14731
+ var import_ts_morph64 = require("ts-morph");
14504
14732
  var import_datalog5 = require("@suss/datalog");
14505
14733
  var RETHROW_RULES = [
14506
14734
  (0, import_datalog5.rule)(
@@ -14637,7 +14865,7 @@ function findBareRethrow(func, location) {
14637
14865
  traversal.stop();
14638
14866
  return;
14639
14867
  }
14640
- if (!import_ts_morph63.Node.isThrowStatement(node)) {
14868
+ if (!import_ts_morph64.Node.isThrowStatement(node)) {
14641
14869
  return;
14642
14870
  }
14643
14871
  if (startLineOf(node) !== location.start) {
@@ -14647,7 +14875,7 @@ function findBareRethrow(func, location) {
14647
14875
  return;
14648
14876
  }
14649
14877
  const thrown = node.getExpression();
14650
- if (thrown !== void 0 && import_ts_morph63.Node.isIdentifier(thrown)) {
14878
+ if (thrown !== void 0 && import_ts_morph64.Node.isIdentifier(thrown)) {
14651
14879
  found = node;
14652
14880
  }
14653
14881
  });
@@ -14657,13 +14885,13 @@ function enclosingTry(throwStmt) {
14657
14885
  let current2 = throwStmt.getParent();
14658
14886
  let sawCatchClause = false;
14659
14887
  while (current2 !== void 0) {
14660
- if (import_ts_morph63.Node.isCatchClause(current2)) {
14888
+ if (import_ts_morph64.Node.isCatchClause(current2)) {
14661
14889
  sawCatchClause = true;
14662
14890
  }
14663
- if (import_ts_morph63.Node.isTryStatement(current2)) {
14891
+ if (import_ts_morph64.Node.isTryStatement(current2)) {
14664
14892
  return sawCatchClause ? current2 : null;
14665
14893
  }
14666
- if (import_ts_morph63.Node.isFunctionDeclaration(current2) || import_ts_morph63.Node.isFunctionExpression(current2) || import_ts_morph63.Node.isArrowFunction(current2) || import_ts_morph63.Node.isMethodDeclaration(current2)) {
14894
+ if (import_ts_morph64.Node.isFunctionDeclaration(current2) || import_ts_morph64.Node.isFunctionExpression(current2) || import_ts_morph64.Node.isArrowFunction(current2) || import_ts_morph64.Node.isMethodDeclaration(current2)) {
14667
14895
  return null;
14668
14896
  }
14669
14897
  current2 = current2.getParent();
@@ -14671,14 +14899,14 @@ function enclosingTry(throwStmt) {
14671
14899
  return null;
14672
14900
  }
14673
14901
  function collectTryBodyCallees(tryStmt, index, keyFor) {
14674
- if (!import_ts_morph63.Node.isTryStatement(tryStmt)) {
14902
+ if (!import_ts_morph64.Node.isTryStatement(tryStmt)) {
14675
14903
  return [];
14676
14904
  }
14677
14905
  const tryBlock = tryStmt.getTryBlock();
14678
14906
  const callees = [];
14679
14907
  const seen = /* @__PURE__ */ new Set();
14680
14908
  tryBlock.forEachDescendant((node) => {
14681
- if (!import_ts_morph63.Node.isCallExpression(node)) {
14909
+ if (!import_ts_morph64.Node.isCallExpression(node)) {
14682
14910
  return;
14683
14911
  }
14684
14912
  const calleeSummary = resolveCalleeSummary(node, index);
@@ -14695,7 +14923,7 @@ function collectTryBodyCallees(tryStmt, index, keyFor) {
14695
14923
  return callees;
14696
14924
  }
14697
14925
  function resolveCalleeSummary(call, index) {
14698
- if (!import_ts_morph63.Node.isCallExpression(call)) {
14926
+ if (!import_ts_morph64.Node.isCallExpression(call)) {
14699
14927
  return null;
14700
14928
  }
14701
14929
  const callee = call.getExpression();
@@ -14725,12 +14953,12 @@ function resolveCalleeSummary(call, index) {
14725
14953
  return null;
14726
14954
  }
14727
14955
  function functionFromDecl(decl) {
14728
- if (import_ts_morph63.Node.isFunctionDeclaration(decl) || import_ts_morph63.Node.isFunctionExpression(decl) || import_ts_morph63.Node.isArrowFunction(decl) || import_ts_morph63.Node.isMethodDeclaration(decl)) {
14956
+ if (import_ts_morph64.Node.isFunctionDeclaration(decl) || import_ts_morph64.Node.isFunctionExpression(decl) || import_ts_morph64.Node.isArrowFunction(decl) || import_ts_morph64.Node.isMethodDeclaration(decl)) {
14729
14957
  return decl;
14730
14958
  }
14731
- if (import_ts_morph63.Node.isVariableDeclaration(decl)) {
14959
+ if (import_ts_morph64.Node.isVariableDeclaration(decl)) {
14732
14960
  const init = decl.getInitializer();
14733
- if (init !== void 0 && (import_ts_morph63.Node.isArrowFunction(init) || import_ts_morph63.Node.isFunctionExpression(init))) {
14961
+ if (init !== void 0 && (import_ts_morph64.Node.isArrowFunction(init) || import_ts_morph64.Node.isFunctionExpression(init))) {
14734
14962
  return init;
14735
14963
  }
14736
14964
  }
@@ -14738,22 +14966,22 @@ function functionFromDecl(decl) {
14738
14966
  }
14739
14967
 
14740
14968
  // src/shapes/fieldAccesses.ts
14741
- var import_ts_morph64 = require("ts-morph");
14969
+ var import_ts_morph65 = require("ts-morph");
14742
14970
  function findResponseAccessor(callExpr) {
14743
14971
  let current2 = callExpr;
14744
14972
  const parent1 = current2.getParent();
14745
- if (parent1 !== void 0 && import_ts_morph64.Node.isAwaitExpression(parent1)) {
14973
+ if (parent1 !== void 0 && import_ts_morph65.Node.isAwaitExpression(parent1)) {
14746
14974
  current2 = parent1;
14747
14975
  }
14748
14976
  const parent2 = current2.getParent();
14749
- if (parent2 === void 0 || !import_ts_morph64.Node.isVariableDeclaration(parent2)) {
14977
+ if (parent2 === void 0 || !import_ts_morph65.Node.isVariableDeclaration(parent2)) {
14750
14978
  return null;
14751
14979
  }
14752
14980
  const nameNode = parent2.getNameNode();
14753
- if (import_ts_morph64.Node.isIdentifier(nameNode)) {
14981
+ if (import_ts_morph65.Node.isIdentifier(nameNode)) {
14754
14982
  return { kind: "identifier", name: nameNode.getText() };
14755
14983
  }
14756
- if (import_ts_morph64.Node.isObjectBindingPattern(nameNode)) {
14984
+ if (import_ts_morph65.Node.isObjectBindingPattern(nameNode)) {
14757
14985
  const bindings = /* @__PURE__ */ new Map();
14758
14986
  for (const element of nameNode.getElements()) {
14759
14987
  if (element.getDotDotDotToken() !== void 0) {
@@ -14774,11 +15002,11 @@ function findResponseAccessor(callExpr) {
14774
15002
  function buildThenChainAccessor(callExpr, func) {
14775
15003
  const bindings = /* @__PURE__ */ new Map();
14776
15004
  func.forEachDescendant((node) => {
14777
- if (!import_ts_morph64.Node.isParameterDeclaration(node)) {
15005
+ if (!import_ts_morph65.Node.isParameterDeclaration(node)) {
14778
15006
  return;
14779
15007
  }
14780
15008
  const nameNode = node.getNameNode();
14781
- if (!import_ts_morph64.Node.isIdentifier(nameNode)) {
15009
+ if (!import_ts_morph65.Node.isIdentifier(nameNode)) {
14782
15010
  return;
14783
15011
  }
14784
15012
  const prefix = prefixOfThenParam(node, callExpr, 0);
@@ -14810,7 +15038,7 @@ function prefixOfExpr(expr, responseCall, depth) {
14810
15038
  if (node === responseCall) {
14811
15039
  return [];
14812
15040
  }
14813
- if (import_ts_morph64.Node.isCallExpression(node)) {
15041
+ if (import_ts_morph65.Node.isCallExpression(node)) {
14814
15042
  const hop = thenLikeCall(node);
14815
15043
  if (hop !== null) {
14816
15044
  if (hop.method === "catch") {
@@ -14842,14 +15070,14 @@ function prefixOfMemberExpr(expr, responseCall, depth) {
14842
15070
  return null;
14843
15071
  }
14844
15072
  const decl = chain.root.getSymbol()?.getDeclarations()?.[0];
14845
- if (decl === void 0 || !import_ts_morph64.Node.isParameterDeclaration(decl)) {
15073
+ if (decl === void 0 || !import_ts_morph65.Node.isParameterDeclaration(decl)) {
14846
15074
  return null;
14847
15075
  }
14848
15076
  const base = prefixOfThenParam(decl, responseCall, depth + 1);
14849
15077
  return base === null ? null : [...base, ...chain.segments];
14850
15078
  }
14851
15079
  function firstCallbackParamName(callback) {
14852
- if (callback === void 0 || !(import_ts_morph64.Node.isArrowFunction(callback) || import_ts_morph64.Node.isFunctionExpression(callback))) {
15080
+ if (callback === void 0 || !(import_ts_morph65.Node.isArrowFunction(callback) || import_ts_morph65.Node.isFunctionExpression(callback))) {
14853
15081
  return null;
14854
15082
  }
14855
15083
  const param = callback.getParameters()[0];
@@ -14857,11 +15085,11 @@ function firstCallbackParamName(callback) {
14857
15085
  return null;
14858
15086
  }
14859
15087
  const nameNode = param.getNameNode();
14860
- return import_ts_morph64.Node.isIdentifier(nameNode) ? nameNode.getText() : null;
15088
+ return import_ts_morph65.Node.isIdentifier(nameNode) ? nameNode.getText() : null;
14861
15089
  }
14862
15090
  function unwrap(expr) {
14863
15091
  let node = expr;
14864
- while (import_ts_morph64.Node.isAwaitExpression(node) || import_ts_morph64.Node.isParenthesizedExpression(node) || import_ts_morph64.Node.isAsExpression(node)) {
15092
+ while (import_ts_morph65.Node.isAwaitExpression(node) || import_ts_morph65.Node.isParenthesizedExpression(node) || import_ts_morph65.Node.isAsExpression(node)) {
14865
15093
  node = node.getExpression();
14866
15094
  }
14867
15095
  return node;
@@ -14871,15 +15099,15 @@ function chainRootedAt(expr, rootName) {
14871
15099
  if (chain === null) {
14872
15100
  return null;
14873
15101
  }
14874
- return import_ts_morph64.Node.isIdentifier(chain.root) && chain.root.getText() === rootName ? chain.segments : null;
15102
+ return import_ts_morph65.Node.isIdentifier(chain.root) && chain.root.getText() === rootName ? chain.segments : null;
14875
15103
  }
14876
15104
  function memberChain(expr) {
14877
- let node = import_ts_morph64.Node.isExpression(expr) ? unwrap(expr) : expr;
14878
- if (import_ts_morph64.Node.isCallExpression(node)) {
15105
+ let node = import_ts_morph65.Node.isExpression(expr) ? unwrap(expr) : expr;
15106
+ if (import_ts_morph65.Node.isCallExpression(node)) {
14879
15107
  node = node.getExpression();
14880
15108
  }
14881
15109
  const segments = [];
14882
- while (import_ts_morph64.Node.isPropertyAccessExpression(node)) {
15110
+ while (import_ts_morph65.Node.isPropertyAccessExpression(node)) {
14883
15111
  segments.unshift(node.getName());
14884
15112
  node = node.getExpression();
14885
15113
  }
@@ -14898,16 +15126,16 @@ function collectPropertyAccesses(subtree, accessor) {
14898
15126
  if (accessor.kind === "identifier") {
14899
15127
  const varName = accessor.name;
14900
15128
  subtree.forEachDescendant((node) => {
14901
- if (!import_ts_morph64.Node.isPropertyAccessExpression(node)) {
15129
+ if (!import_ts_morph65.Node.isPropertyAccessExpression(node)) {
14902
15130
  return;
14903
15131
  }
14904
15132
  const chain = [];
14905
15133
  let current2 = node;
14906
- while (import_ts_morph64.Node.isPropertyAccessExpression(current2)) {
15134
+ while (import_ts_morph65.Node.isPropertyAccessExpression(current2)) {
14907
15135
  chain.unshift(current2.getName());
14908
15136
  current2 = current2.getExpression();
14909
15137
  }
14910
- if (import_ts_morph64.Node.isIdentifier(current2) && current2.getText() === varName) {
15138
+ if (import_ts_morph65.Node.isIdentifier(current2) && current2.getText() === varName) {
14911
15139
  pushChain(chain);
14912
15140
  }
14913
15141
  });
@@ -14918,7 +15146,7 @@ function collectPropertyAccesses(subtree, accessor) {
14918
15146
  return source === void 0 ? void 0 : [source];
14919
15147
  } : (name) => accessor.bindings.get(name);
14920
15148
  subtree.forEachDescendant((node) => {
14921
- if (!import_ts_morph64.Node.isIdentifier(node)) {
15149
+ if (!import_ts_morph65.Node.isIdentifier(node)) {
14922
15150
  return;
14923
15151
  }
14924
15152
  const prefix = prefixOf(node.getText());
@@ -14930,13 +15158,13 @@ function collectPropertyAccesses(subtree, accessor) {
14930
15158
  }
14931
15159
  let chainTop = node;
14932
15160
  let parent = chainTop.getParent();
14933
- while (parent !== void 0 && import_ts_morph64.Node.isPropertyAccessExpression(parent) && parent.getExpression() === chainTop) {
15161
+ while (parent !== void 0 && import_ts_morph65.Node.isPropertyAccessExpression(parent) && parent.getExpression() === chainTop) {
14934
15162
  chainTop = parent;
14935
15163
  parent = chainTop.getParent();
14936
15164
  }
14937
15165
  const segments = [];
14938
15166
  let current2 = chainTop;
14939
- while (import_ts_morph64.Node.isPropertyAccessExpression(current2)) {
15167
+ while (import_ts_morph65.Node.isPropertyAccessExpression(current2)) {
14940
15168
  segments.push(current2.getName());
14941
15169
  current2 = current2.getExpression();
14942
15170
  }
@@ -14950,15 +15178,15 @@ function isBindingDeclarationSite(node) {
14950
15178
  return true;
14951
15179
  }
14952
15180
  const parent = node.getParent();
14953
- return parent !== void 0 && import_ts_morph64.Node.isParameterDeclaration(parent) && parent.getNameNode() === node;
15181
+ return parent !== void 0 && import_ts_morph65.Node.isParameterDeclaration(parent) && parent.getNameNode() === node;
14954
15182
  }
14955
15183
  function isInsideObjectBindingPattern(node) {
14956
15184
  let current2 = node.getParent();
14957
15185
  while (current2 !== void 0) {
14958
- if (import_ts_morph64.Node.isObjectBindingPattern(current2)) {
15186
+ if (import_ts_morph65.Node.isObjectBindingPattern(current2)) {
14959
15187
  return true;
14960
15188
  }
14961
- if (import_ts_morph64.Node.isFunctionLikeDeclaration(current2) || import_ts_morph64.Node.isVariableStatement(current2)) {
15189
+ if (import_ts_morph65.Node.isFunctionLikeDeclaration(current2) || import_ts_morph65.Node.isVariableStatement(current2)) {
14962
15190
  break;
14963
15191
  }
14964
15192
  current2 = current2.getParent();
@@ -15021,7 +15249,7 @@ function findBranchSubtree(func, byLineRange, terminalStartLine, terminalEndLine
15021
15249
  if (parent === void 0) {
15022
15250
  break;
15023
15251
  }
15024
- if (import_ts_morph64.Node.isIfStatement(parent)) {
15252
+ if (import_ts_morph65.Node.isIfStatement(parent)) {
15025
15253
  const ifStmt = parent;
15026
15254
  const thenBlock = ifStmt.getThenStatement();
15027
15255
  const elseBlock = ifStmt.getElseStatement();
@@ -15083,7 +15311,7 @@ function buildNonBodyPropertySet(semantics) {
15083
15311
  }
15084
15312
 
15085
15313
  // src/subUnitContext.ts
15086
- var import_ts_morph65 = require("ts-morph");
15314
+ var import_ts_morph66 = require("ts-morph");
15087
15315
  function createTsSubUnitContext() {
15088
15316
  return {
15089
15317
  findJsxAttributes,
@@ -15110,18 +15338,18 @@ function findJsxAttributes(parent) {
15110
15338
  if (skip(node, traversal)) {
15111
15339
  return;
15112
15340
  }
15113
- if (!import_ts_morph65.Node.isJsxOpeningElement(node) && !import_ts_morph65.Node.isJsxSelfClosingElement(node)) {
15341
+ if (!import_ts_morph66.Node.isJsxOpeningElement(node) && !import_ts_morph66.Node.isJsxSelfClosingElement(node)) {
15114
15342
  return;
15115
15343
  }
15116
15344
  const tag = node.getTagNameNode().getText();
15117
15345
  for (const attr of node.getAttributes()) {
15118
- if (!import_ts_morph65.Node.isJsxAttribute(attr)) {
15346
+ if (!import_ts_morph66.Node.isJsxAttribute(attr)) {
15119
15347
  continue;
15120
15348
  }
15121
15349
  const initializer = attr.getInitializer();
15122
15350
  let valueExpression = null;
15123
15351
  if (initializer !== void 0) {
15124
- if (import_ts_morph65.Node.isJsxExpression(initializer)) {
15352
+ if (import_ts_morph66.Node.isJsxExpression(initializer)) {
15125
15353
  const inner = initializer.getExpression();
15126
15354
  valueExpression = inner ?? null;
15127
15355
  } else {
@@ -15144,11 +15372,11 @@ function findCallExpressionsByName(parent, name) {
15144
15372
  if (skip(node, traversal)) {
15145
15373
  return;
15146
15374
  }
15147
- if (!import_ts_morph65.Node.isCallExpression(node)) {
15375
+ if (!import_ts_morph66.Node.isCallExpression(node)) {
15148
15376
  return;
15149
15377
  }
15150
15378
  const callee = node.getExpression();
15151
- if (import_ts_morph65.Node.isIdentifier(callee) && callee.getText() === name) {
15379
+ if (import_ts_morph66.Node.isIdentifier(callee) && callee.getText() === name) {
15152
15380
  out.push(node);
15153
15381
  }
15154
15382
  });
@@ -15159,10 +15387,10 @@ function resolveAttributeValueFunction(attr, parent) {
15159
15387
  if (expr === null) {
15160
15388
  return null;
15161
15389
  }
15162
- if (import_ts_morph65.Node.isArrowFunction(expr) || import_ts_morph65.Node.isFunctionExpression(expr)) {
15390
+ if (import_ts_morph66.Node.isArrowFunction(expr) || import_ts_morph66.Node.isFunctionExpression(expr)) {
15163
15391
  return { func: expr, localName: null };
15164
15392
  }
15165
- if (import_ts_morph65.Node.isIdentifier(expr)) {
15393
+ if (import_ts_morph66.Node.isIdentifier(expr)) {
15166
15394
  const symbol = expr.getSymbol();
15167
15395
  if (symbol === void 0) {
15168
15396
  return null;
@@ -15181,15 +15409,15 @@ function resolveAttributeValueFunction(attr, parent) {
15181
15409
  return null;
15182
15410
  }
15183
15411
  function tryExtractFunction(decl) {
15184
- if (import_ts_morph65.Node.isFunctionDeclaration(decl)) {
15412
+ if (import_ts_morph66.Node.isFunctionDeclaration(decl)) {
15185
15413
  return decl;
15186
15414
  }
15187
- if (import_ts_morph65.Node.isVariableDeclaration(decl)) {
15415
+ if (import_ts_morph66.Node.isVariableDeclaration(decl)) {
15188
15416
  const init = decl.getInitializer();
15189
15417
  if (init === void 0) {
15190
15418
  return null;
15191
15419
  }
15192
- if (import_ts_morph65.Node.isArrowFunction(init) || import_ts_morph65.Node.isFunctionExpression(init)) {
15420
+ if (import_ts_morph66.Node.isArrowFunction(init) || import_ts_morph66.Node.isFunctionExpression(init)) {
15193
15421
  return init;
15194
15422
  }
15195
15423
  }
@@ -15210,7 +15438,7 @@ function getCallArgumentFunction(call, position) {
15210
15438
  if (arg === void 0) {
15211
15439
  return null;
15212
15440
  }
15213
- if (import_ts_morph65.Node.isArrowFunction(arg) || import_ts_morph65.Node.isFunctionExpression(arg)) {
15441
+ if (import_ts_morph66.Node.isArrowFunction(arg) || import_ts_morph66.Node.isFunctionExpression(arg)) {
15214
15442
  return arg;
15215
15443
  }
15216
15444
  return null;
@@ -15222,7 +15450,7 @@ function readArrayLiteralText(node) {
15222
15450
  if (node === null) {
15223
15451
  return null;
15224
15452
  }
15225
- if (import_ts_morph65.Node.isArrayLiteralExpression(node)) {
15453
+ if (import_ts_morph66.Node.isArrayLiteralExpression(node)) {
15226
15454
  return node.getElements().map((e) => e.getText());
15227
15455
  }
15228
15456
  return [node.getText()];
@@ -15471,13 +15699,13 @@ var raise = (msg) => {
15471
15699
  throw new Error(msg);
15472
15700
  };
15473
15701
  function bindingPatternNames(nameNode) {
15474
- if (import_ts_morph66.Node.isObjectBindingPattern(nameNode)) {
15702
+ if (import_ts_morph67.Node.isObjectBindingPattern(nameNode)) {
15475
15703
  return nameNode.getElements().map((e) => e.getName());
15476
15704
  }
15477
- if (import_ts_morph66.Node.isArrayBindingPattern(nameNode)) {
15705
+ if (import_ts_morph67.Node.isArrayBindingPattern(nameNode)) {
15478
15706
  const names = [];
15479
15707
  for (const element of nameNode.getElements()) {
15480
- if (import_ts_morph66.Node.isOmittedExpression(element)) {
15708
+ if (import_ts_morph67.Node.isOmittedExpression(element)) {
15481
15709
  continue;
15482
15710
  }
15483
15711
  names.push(element.getName());
@@ -15507,7 +15735,7 @@ function objectParamInputs(param, position, mapping) {
15507
15735
  }
15508
15736
  function componentPropsParameters(param, mapping) {
15509
15737
  const nameNode = param.getNameNode();
15510
- if (!import_ts_morph66.Node.isObjectBindingPattern(nameNode)) {
15738
+ if (!import_ts_morph67.Node.isObjectBindingPattern(nameNode)) {
15511
15739
  const type = param.getType();
15512
15740
  return [
15513
15741
  {
@@ -15537,7 +15765,7 @@ function bindingRole(element, name) {
15537
15765
  if (property === void 0) {
15538
15766
  return name;
15539
15767
  }
15540
- if (import_ts_morph66.Node.isStringLiteral(property)) {
15768
+ if (import_ts_morph67.Node.isStringLiteral(property)) {
15541
15769
  return property.getLiteralValue();
15542
15770
  }
15543
15771
  return property.getText();
@@ -15569,7 +15797,7 @@ function extractParameters(func, inputMapping) {
15569
15797
  const param = params[i];
15570
15798
  const nameNode = param.getNameNode();
15571
15799
  const boundNames = bindingPatternNames(nameNode);
15572
- if (import_ts_morph66.Node.isObjectBindingPattern(nameNode)) {
15800
+ if (import_ts_morph67.Node.isObjectBindingPattern(nameNode)) {
15573
15801
  for (const element of nameNode.getElements()) {
15574
15802
  result.push({
15575
15803
  name: element.getName(),
@@ -15636,7 +15864,7 @@ function extractDependencyCalls(func, barriers = NO_BARRIERS) {
15636
15864
  traversal.skip();
15637
15865
  return;
15638
15866
  }
15639
- if (!import_ts_morph66.Node.isVariableDeclaration(node)) {
15867
+ if (!import_ts_morph67.Node.isVariableDeclaration(node)) {
15640
15868
  return;
15641
15869
  }
15642
15870
  const init = node.getInitializer();
@@ -15645,19 +15873,19 @@ function extractDependencyCalls(func, barriers = NO_BARRIERS) {
15645
15873
  }
15646
15874
  let isAsync = false;
15647
15875
  let callExpr = init;
15648
- if (import_ts_morph66.Node.isAwaitExpression(init)) {
15876
+ if (import_ts_morph67.Node.isAwaitExpression(init)) {
15649
15877
  isAsync = true;
15650
15878
  callExpr = init.getExpression();
15651
15879
  }
15652
- if (!import_ts_morph66.Node.isCallExpression(callExpr)) {
15880
+ if (!import_ts_morph67.Node.isCallExpression(callExpr)) {
15653
15881
  return;
15654
15882
  }
15655
15883
  const calleeName = callExpr.getExpression().getText();
15656
15884
  const nameNode = node.getNameNode();
15657
- const assignedTo = import_ts_morph66.Node.isIdentifier(nameNode) ? nameNode.getText() : null;
15885
+ const assignedTo = import_ts_morph67.Node.isIdentifier(nameNode) ? nameNode.getText() : null;
15658
15886
  const declList = node.getParent();
15659
15887
  const varStmt = declList?.getParent();
15660
- const locationNode = varStmt !== void 0 && import_ts_morph66.Node.isVariableStatement(varStmt) ? varStmt : node;
15888
+ const locationNode = varStmt !== void 0 && import_ts_morph67.Node.isVariableStatement(varStmt) ? varStmt : node;
15661
15889
  results.push({
15662
15890
  name: calleeName,
15663
15891
  assignedTo,
@@ -15807,10 +16035,10 @@ var FUNCTION_FALLTHROUGH_TERMINAL = {
15807
16035
  match: { type: "functionFallthrough" },
15808
16036
  extraction: {}
15809
16037
  };
15810
- function thrownValueAt(unit) {
15811
- return unit.pattern?.wraps?.throwParam;
16038
+ function frameworkValueAt(unit) {
16039
+ return unit.pattern?.wraps?.throwParam ?? unit.pattern?.wraps?.resultParam;
15812
16040
  }
15813
- function pastThrownValue(terminals, at) {
16041
+ function pastFrameworkValue(terminals, at) {
15814
16042
  if (at === void 0) {
15815
16043
  return terminals;
15816
16044
  }
@@ -15824,7 +16052,7 @@ function pastThrownValue(terminals, at) {
15824
16052
  } : pattern
15825
16053
  );
15826
16054
  }
15827
- function rolesPastThrownValue(mapping, at) {
16055
+ function rolesPastFrameworkValue(mapping, at) {
15828
16056
  if (at === void 0 || mapping.type !== "positionalParams") {
15829
16057
  return mapping;
15830
16058
  }
@@ -15850,7 +16078,7 @@ function continuationTerminal(unit) {
15850
16078
  }
15851
16079
  function terminalsFor(unit, pack) {
15852
16080
  const declared = [
15853
- ...unit.terminals ?? pastThrownValue(pack.terminals, thrownValueAt(unit)),
16081
+ ...unit.terminals ?? pastFrameworkValue(pack.terminals, frameworkValueAt(unit)),
15854
16082
  ...continuationTerminal(unit)
15855
16083
  ];
15856
16084
  if (unit.callSite === void 0) {
@@ -15868,7 +16096,7 @@ function readCodeStructure(unit, pack, invocationRecognizers, accessRecognizers,
15868
16096
  }
15869
16097
  const params = extractParameters(
15870
16098
  func,
15871
- unit.inputMapping ?? rolesPastThrownValue(pack.inputMapping, thrownValueAt(unit))
16099
+ unit.inputMapping ?? rolesPastFrameworkValue(pack.inputMapping, frameworkValueAt(unit))
15872
16100
  );
15873
16101
  const extracted = extractRawBranches(
15874
16102
  func,
@@ -16370,8 +16598,10 @@ function extractFromSourceFile(sourceFile, frameworks, claimedUnits, options, ta
16370
16598
  }
16371
16599
  }
16372
16600
  const summary = (0, import_extractor11.assembleSummary)(raw, options);
16373
- if (unit.unfollowed !== void 0 && options?.gapHandling !== "silent") {
16374
- summary.gaps.push((0, import_behavioral_ir2.unfollowedCallGap)(unit.unfollowed));
16601
+ if (options?.gapHandling !== "silent") {
16602
+ for (const stop of unfollowedStopsOf(unit, wrappers)) {
16603
+ summary.gaps.push((0, import_behavioral_ir2.unfollowedCallGap)(stop));
16604
+ }
16375
16605
  }
16376
16606
  if (unit.metadata !== void 0 && Object.keys(unit.metadata).length > 0) {
16377
16607
  summary.metadata = {
@@ -16424,6 +16654,13 @@ function stampWrappers(raw, unit, wrappers) {
16424
16654
  recordFileDependency(wrapper.file);
16425
16655
  }
16426
16656
  }
16657
+ function unfollowedStopsOf(unit, wrappers) {
16658
+ const stops = unit.unfollowed === void 0 ? [] : [unit.unfollowed];
16659
+ if (wrappers === void 0 || unit.registrationSubjectId === void 0) {
16660
+ return stops;
16661
+ }
16662
+ return [...stops, ...wrappers.unfollowedFor(unit.registrationSubjectId)];
16663
+ }
16427
16664
  function emitLibraryEnvReadMarkers(summaries, project, frameworks) {
16428
16665
  for (const pack of frameworks) {
16429
16666
  for (const declared of pack.libraryEnvVars ?? []) {
@@ -16565,9 +16802,9 @@ function findWrapperPathParam(summary, lookup) {
16565
16802
  if (names.length === 0) {
16566
16803
  return null;
16567
16804
  }
16568
- for (const call of func.getDescendantsOfKind(import_ts_morph66.SyntaxKind.CallExpression)) {
16805
+ for (const call of func.getDescendantsOfKind(import_ts_morph67.SyntaxKind.CallExpression)) {
16569
16806
  const first = call.getArguments()[0];
16570
- if (first === void 0 || !import_ts_morph66.Node.isIdentifier(first)) {
16807
+ if (first === void 0 || !import_ts_morph67.Node.isIdentifier(first)) {
16571
16808
  continue;
16572
16809
  }
16573
16810
  const at = names.indexOf(first.getText());
@@ -16616,16 +16853,16 @@ function synthesizeCallerSummaries(wrapper, _project, options, resolution) {
16616
16853
  return out;
16617
16854
  }
16618
16855
  function wrapperNameNode(func) {
16619
- if (import_ts_morph66.Node.isFunctionDeclaration(func) || import_ts_morph66.Node.isMethodDeclaration(func)) {
16856
+ if (import_ts_morph67.Node.isFunctionDeclaration(func) || import_ts_morph67.Node.isMethodDeclaration(func)) {
16620
16857
  const name = func.getNameNode();
16621
- if (name !== void 0 && import_ts_morph66.Node.isIdentifier(name)) {
16858
+ if (name !== void 0 && import_ts_morph67.Node.isIdentifier(name)) {
16622
16859
  return name;
16623
16860
  }
16624
16861
  }
16625
16862
  const parent = func.getParent();
16626
- if (parent !== void 0 && import_ts_morph66.Node.isVariableDeclaration(parent)) {
16863
+ if (parent !== void 0 && import_ts_morph67.Node.isVariableDeclaration(parent)) {
16627
16864
  const nameNode = parent.getNameNode();
16628
- if (import_ts_morph66.Node.isIdentifier(nameNode)) {
16865
+ if (import_ts_morph67.Node.isIdentifier(nameNode)) {
16629
16866
  return nameNode;
16630
16867
  }
16631
16868
  }
@@ -16634,10 +16871,10 @@ function wrapperNameNode(func) {
16634
16871
  function enclosingCall(node) {
16635
16872
  let current2 = node.getParent();
16636
16873
  while (current2 !== void 0) {
16637
- if (import_ts_morph66.Node.isCallExpression(current2)) {
16874
+ if (import_ts_morph67.Node.isCallExpression(current2)) {
16638
16875
  return current2;
16639
16876
  }
16640
- if (import_ts_morph66.Node.isPropertyAccessExpression(current2)) {
16877
+ if (import_ts_morph67.Node.isPropertyAccessExpression(current2)) {
16641
16878
  current2 = current2.getParent();
16642
16879
  continue;
16643
16880
  }
@@ -16648,7 +16885,7 @@ function enclosingCall(node) {
16648
16885
  function enclosingFunction(node) {
16649
16886
  let current2 = node.getParent();
16650
16887
  while (current2 !== void 0) {
16651
- if (import_ts_morph66.Node.isFunctionDeclaration(current2) || import_ts_morph66.Node.isFunctionExpression(current2) || import_ts_morph66.Node.isArrowFunction(current2) || import_ts_morph66.Node.isMethodDeclaration(current2)) {
16888
+ if (import_ts_morph67.Node.isFunctionDeclaration(current2) || import_ts_morph67.Node.isFunctionExpression(current2) || import_ts_morph67.Node.isArrowFunction(current2) || import_ts_morph67.Node.isMethodDeclaration(current2)) {
16652
16889
  return current2;
16653
16890
  }
16654
16891
  current2 = current2.getParent();
@@ -16656,13 +16893,13 @@ function enclosingFunction(node) {
16656
16893
  return null;
16657
16894
  }
16658
16895
  function callerName(func) {
16659
- if (import_ts_morph66.Node.isFunctionDeclaration(func) || import_ts_morph66.Node.isMethodDeclaration(func)) {
16896
+ if (import_ts_morph67.Node.isFunctionDeclaration(func) || import_ts_morph67.Node.isMethodDeclaration(func)) {
16660
16897
  return func.getName() ?? "anonymous";
16661
16898
  }
16662
16899
  const parent = func.getParent();
16663
- if (parent !== void 0 && import_ts_morph66.Node.isVariableDeclaration(parent)) {
16900
+ if (parent !== void 0 && import_ts_morph67.Node.isVariableDeclaration(parent)) {
16664
16901
  const nameNode = parent.getNameNode();
16665
- if (import_ts_morph66.Node.isIdentifier(nameNode)) {
16902
+ if (import_ts_morph67.Node.isIdentifier(nameNode)) {
16666
16903
  return nameNode.getText();
16667
16904
  }
16668
16905
  }
@@ -16761,7 +16998,7 @@ function createTypeScriptAdapter(suppliedConfig) {
16761
16998
  suppliedConfig.projectRoot ?? (suppliedConfig.tsConfigFilePath !== void 0 ? import_node_path10.default.dirname(suppliedConfig.tsConfigFilePath) : void 0)
16762
16999
  )
16763
17000
  };
16764
- const project = config.project ?? new import_ts_morph66.Project(
17001
+ const project = config.project ?? new import_ts_morph67.Project(
16765
17002
  config.tsConfigFilePath !== void 0 ? {
16766
17003
  tsConfigFilePath: config.tsConfigFilePath,
16767
17004
  skipAddingFilesFromTsConfig: true
@@ -17138,7 +17375,7 @@ function createTypeScriptAdapter(suppliedConfig) {
17138
17375
  });
17139
17376
  const composed = timer.time(
17140
17377
  "composeWrappers",
17141
- () => (0, import_extractor11.composeWrappers)(enriched)
17378
+ () => (0, import_extractor11.composeWrappers)(enriched, config.extractorOptions ?? {})
17142
17379
  );
17143
17380
  if (config.onTiming !== void 0) {
17144
17381
  config.onTiming(timer.report());
@@ -17477,7 +17714,7 @@ function buildSubUnitSummary(subUnit, parent, invocationRecognizers, accessRecog
17477
17714
  // src/bootstrap/noTsconfigProject.ts
17478
17715
  var import_node_fs4 = __toESM(require("fs"), 1);
17479
17716
  var import_node_path11 = __toESM(require("path"), 1);
17480
- var import_ts_morph67 = require("ts-morph");
17717
+ var import_ts_morph68 = require("ts-morph");
17481
17718
  var SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([
17482
17719
  ".ts",
17483
17720
  ".tsx",
@@ -17525,12 +17762,12 @@ function findSourceFiles(rootDir, depth = 0) {
17525
17762
  return found;
17526
17763
  }
17527
17764
  function createProjectWithoutTsconfig(rootDir) {
17528
- const project = new import_ts_morph67.Project({
17765
+ const project = new import_ts_morph68.Project({
17529
17766
  skipAddingFilesFromTsConfig: true,
17530
17767
  compilerOptions: {
17531
- target: import_ts_morph67.ScriptTarget.ES2022,
17532
- module: import_ts_morph67.ModuleKind.ESNext,
17533
- moduleResolution: import_ts_morph67.ModuleResolutionKind.Bundler,
17768
+ target: import_ts_morph68.ScriptTarget.ES2022,
17769
+ module: import_ts_morph68.ModuleKind.ESNext,
17770
+ moduleResolution: import_ts_morph68.ModuleResolutionKind.Bundler,
17534
17771
  allowJs: true,
17535
17772
  checkJs: false,
17536
17773
  noEmit: true,
@@ -17571,7 +17808,7 @@ function findNearestTsconfig(startDir) {
17571
17808
 
17572
17809
  // src/facts/why.ts
17573
17810
  var import_node_path12 = __toESM(require("path"), 1);
17574
- var import_ts_morph68 = require("ts-morph");
17811
+ var import_ts_morph69 = require("ts-morph");
17575
17812
  var import_resolution7 = require("@suss/resolution");
17576
17813
  var JS_PHRASES = {
17577
17814
  bind: ({ tuple, describe }) => ({
@@ -17585,7 +17822,7 @@ var TypeScriptWhySession = class {
17585
17822
  constructor(options) {
17586
17823
  this.root = import_node_path12.default.resolve(options.dir);
17587
17824
  const tsconfig = findNearestTsconfig(this.root);
17588
- this.project = tsconfig === null ? createProjectWithoutTsconfig(this.root).project : new import_ts_morph68.Project({ tsConfigFilePath: tsconfig });
17825
+ this.project = tsconfig === null ? createProjectWithoutTsconfig(this.root).project : new import_ts_morph69.Project({ tsConfigFilePath: tsconfig });
17589
17826
  this.store = new ResolutionStore();
17590
17827
  }
17591
17828
  /**
@@ -17600,7 +17837,7 @@ var TypeScriptWhySession = class {
17600
17837
  }
17601
17838
  let found = null;
17602
17839
  sourceFile.forEachDescendant((node) => {
17603
- if (import_ts_morph68.Node.isExpression(node) && node.getStartLineNumber() === line && node.getText() === text && (found === null || node.getWidth() <= found.getWidth())) {
17840
+ if (import_ts_morph69.Node.isExpression(node) && node.getStartLineNumber() === line && node.getText() === text && (found === null || node.getWidth() <= found.getWidth())) {
17604
17841
  found = node;
17605
17842
  }
17606
17843
  });
@@ -17618,7 +17855,7 @@ var TypeScriptWhySession = class {
17618
17855
  return null;
17619
17856
  }
17620
17857
  for (const call of sourceFile.getDescendantsOfKind(
17621
- import_ts_morph68.SyntaxKind.CallExpression
17858
+ import_ts_morph69.SyntaxKind.CallExpression
17622
17859
  )) {
17623
17860
  const line = call.getStartLineNumber();
17624
17861
  if (line < startLine || line > endLine) {
@@ -17692,21 +17929,21 @@ var TypeScriptWhySession = class {
17692
17929
  }
17693
17930
  };
17694
17931
  function displayNameOf(node) {
17695
- if (import_ts_morph68.Node.isIdentifier(node) || import_ts_morph68.Node.isPropertyAccessExpression(node)) {
17932
+ if (import_ts_morph69.Node.isIdentifier(node) || import_ts_morph69.Node.isPropertyAccessExpression(node)) {
17696
17933
  return node.getText();
17697
17934
  }
17698
- if (import_ts_morph68.Node.isCallExpression(node) || import_ts_morph68.Node.isNewExpression(node)) {
17935
+ if (import_ts_morph69.Node.isCallExpression(node) || import_ts_morph69.Node.isNewExpression(node)) {
17699
17936
  return `${node.getExpression()?.getText() ?? "call"}(...)`;
17700
17937
  }
17701
- if (import_ts_morph68.Node.isFunctionDeclaration(node) || import_ts_morph68.Node.isClassDeclaration(node) || import_ts_morph68.Node.isMethodDeclaration(node) || import_ts_morph68.Node.isVariableDeclaration(node)) {
17938
+ if (import_ts_morph69.Node.isFunctionDeclaration(node) || import_ts_morph69.Node.isClassDeclaration(node) || import_ts_morph69.Node.isMethodDeclaration(node) || import_ts_morph69.Node.isVariableDeclaration(node)) {
17702
17939
  const name = node.getName();
17703
17940
  if (name !== void 0) {
17704
17941
  return name;
17705
17942
  }
17706
17943
  }
17707
- if (import_ts_morph68.Node.isArrowFunction(node) || import_ts_morph68.Node.isFunctionExpression(node)) {
17944
+ if (import_ts_morph69.Node.isArrowFunction(node) || import_ts_morph69.Node.isFunctionExpression(node)) {
17708
17945
  const parent = node.getParent();
17709
- if (parent !== void 0 && import_ts_morph68.Node.isVariableDeclaration(parent)) {
17946
+ if (parent !== void 0 && import_ts_morph69.Node.isVariableDeclaration(parent)) {
17710
17947
  return parent.getName();
17711
17948
  }
17712
17949
  }
@@ -17716,7 +17953,7 @@ function displayNameOf(node) {
17716
17953
 
17717
17954
  // src/stubEvidence.ts
17718
17955
  var import_node_path13 = __toESM(require("path"), 1);
17719
- var import_ts_morph69 = require("ts-morph");
17956
+ var import_ts_morph70 = require("ts-morph");
17720
17957
  function stubEvidenceIn(project, packageName, root) {
17721
17958
  const resolution = new ResolutionStore();
17722
17959
  const byExport = /* @__PURE__ */ new Map();
@@ -17743,7 +17980,7 @@ function stubEvidenceIn(project, packageName, root) {
17743
17980
  );
17744
17981
  }
17745
17982
  function stubEvidence(options) {
17746
- const project = new import_ts_morph69.Project(
17983
+ const project = new import_ts_morph70.Project(
17747
17984
  options.tsConfigFilePath !== void 0 ? { tsConfigFilePath: options.tsConfigFilePath } : { compilerOptions: { allowJs: true } }
17748
17985
  );
17749
17986
  const root = options.tsConfigFilePath !== void 0 ? import_node_path13.default.dirname(options.tsConfigFilePath) : import_node_path13.default.resolve(options.directory ?? process.cwd());
@@ -17758,6 +17995,8 @@ function stubEvidence(options) {
17758
17995
  // Annotate the CommonJS export names for ESM import in node:
17759
17996
  0 && (module.exports = {
17760
17997
  ADAPTER_VERSION,
17998
+ GENERIC_TERMINALS,
17999
+ NO_BARRIERS,
17761
18000
  ResolutionStore,
17762
18001
  TypeScriptWhySession,
17763
18002
  accessContextFor,
@@ -17778,6 +18017,7 @@ function stubEvidence(options) {
17778
18017
  findNearestTsconfig,
17779
18018
  findTerminals,
17780
18019
  functionTargetOf,
18020
+ hasBody,
17781
18021
  importDeclarationsOf,
17782
18022
  importedNamesOf,
17783
18023
  importedRootsOf,
@@ -17793,6 +18033,7 @@ function stubEvidence(options) {
17793
18033
  resolveAliasedSymbol,
17794
18034
  resolveSubject,
17795
18035
  rootIdentifier,
18036
+ startsItsOwnScope,
17796
18037
  stubEvidence,
17797
18038
  stubEvidenceIn,
17798
18039
  workspaceRootFor