@suss/adapter-typescript 0.12.0 → 0.13.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
@@ -33,6 +33,7 @@ __export(index_exports, {
33
33
  ADAPTER_VERSION: () => ADAPTER_VERSION,
34
34
  ResolutionStore: () => ResolutionStore,
35
35
  WhySession: () => WhySession,
36
+ accessContextFor: () => accessContextFor,
36
37
  callOpsFor: () => callOpsFor,
37
38
  collectAncestorBranches: () => collectAncestorBranches,
38
39
  collectClientFieldAccesses: () => collectClientFieldAccesses,
@@ -50,6 +51,7 @@ __export(index_exports, {
50
51
  findNearestTsconfig: () => findNearestTsconfig,
51
52
  findTerminals: () => findTerminals,
52
53
  formatPackHealth: () => formatPackHealth,
54
+ invocationContextFor: () => invocationContextFor,
53
55
  isImportedFrom: () => isImportedFrom,
54
56
  methodDeclaredIn: () => methodDeclaredIn,
55
57
  parseConditionExpression: () => parseConditionExpression,
@@ -66,8 +68,8 @@ module.exports = __toCommonJS(index_exports);
66
68
 
67
69
  // src/adapter.ts
68
70
  var import_node_path9 = __toESM(require("path"), 1);
69
- var import_ts_morph59 = require("ts-morph");
70
- var import_behavioral_ir7 = require("@suss/behavioral-ir");
71
+ var import_ts_morph60 = require("ts-morph");
72
+ var import_behavioral_ir8 = require("@suss/behavioral-ir");
71
73
  var import_datalog6 = require("@suss/datalog");
72
74
  var import_extractor5 = require("@suss/extractor");
73
75
 
@@ -296,14 +298,14 @@ function dedupe(shapes) {
296
298
  return out;
297
299
  }
298
300
  function isInformativeInitializer(node) {
299
- const unwrapped = peelSyntax(node);
300
- if (import_ts_morph2.Node.isStringLiteral(unwrapped) || import_ts_morph2.Node.isNoSubstitutionTemplateLiteral(unwrapped) || import_ts_morph2.Node.isNumericLiteral(unwrapped) || import_ts_morph2.Node.isBigIntLiteral(unwrapped) || import_ts_morph2.Node.isObjectLiteralExpression(unwrapped) || import_ts_morph2.Node.isArrayLiteralExpression(unwrapped) || import_ts_morph2.Node.isTemplateExpression(unwrapped) || import_ts_morph2.Node.isConditionalExpression(unwrapped) || import_ts_morph2.Node.isIdentifier(unwrapped) || import_ts_morph2.Node.isPropertyAccessExpression(unwrapped) || import_ts_morph2.Node.isElementAccessExpression(unwrapped)) {
301
+ const unwrapped2 = peelSyntax(node);
302
+ if (import_ts_morph2.Node.isStringLiteral(unwrapped2) || import_ts_morph2.Node.isNoSubstitutionTemplateLiteral(unwrapped2) || import_ts_morph2.Node.isNumericLiteral(unwrapped2) || import_ts_morph2.Node.isBigIntLiteral(unwrapped2) || import_ts_morph2.Node.isObjectLiteralExpression(unwrapped2) || import_ts_morph2.Node.isArrayLiteralExpression(unwrapped2) || import_ts_morph2.Node.isTemplateExpression(unwrapped2) || import_ts_morph2.Node.isConditionalExpression(unwrapped2) || import_ts_morph2.Node.isIdentifier(unwrapped2) || import_ts_morph2.Node.isPropertyAccessExpression(unwrapped2) || import_ts_morph2.Node.isElementAccessExpression(unwrapped2)) {
301
303
  return true;
302
304
  }
303
- if (import_ts_morph2.Node.isPrefixUnaryExpression(unwrapped)) {
304
- return isInformativeInitializer(unwrapped.getOperand());
305
+ if (import_ts_morph2.Node.isPrefixUnaryExpression(unwrapped2)) {
306
+ return isInformativeInitializer(unwrapped2.getOperand());
305
307
  }
306
- const kind = unwrapped.getKind();
308
+ const kind = unwrapped2.getKind();
307
309
  return kind === import_ts_morph2.SyntaxKind.TrueKeyword || kind === import_ts_morph2.SyntaxKind.FalseKeyword || kind === import_ts_morph2.SyntaxKind.NullKeyword;
308
310
  }
309
311
  function resolveCallableBody(callee) {
@@ -1612,8 +1614,8 @@ var ModuleGraph = class {
1612
1614
  * earlier walk settled stops it for the same reason.
1613
1615
  */
1614
1616
  settle(root, name) {
1615
- const settled = this.settledOf(name);
1616
- if (settled.has(root.getFilePath())) {
1617
+ const settled2 = this.settledOf(name);
1618
+ if (settled2.has(root.getFilePath())) {
1617
1619
  return;
1618
1620
  }
1619
1621
  const walked = /* @__PURE__ */ new Set();
@@ -1621,7 +1623,7 @@ var ModuleGraph = class {
1621
1623
  while (stack.length > 0) {
1622
1624
  const current2 = stack.pop();
1623
1625
  const currentPath = current2.getFilePath();
1624
- if (walked.has(currentPath) || settled.has(currentPath)) {
1626
+ if (walked.has(currentPath) || settled2.has(currentPath)) {
1625
1627
  continue;
1626
1628
  }
1627
1629
  walked.add(currentPath);
@@ -1632,7 +1634,7 @@ var ModuleGraph = class {
1632
1634
  stack.push(...this.importedFilesOf(current2));
1633
1635
  }
1634
1636
  for (const filePath of walked) {
1635
- settled.add(filePath);
1637
+ settled2.add(filePath);
1636
1638
  }
1637
1639
  }
1638
1640
  settledOf(name) {
@@ -2681,15 +2683,28 @@ function holeName(expr, ctx) {
2681
2683
  }
2682
2684
 
2683
2685
  // src/resolve/callOps.ts
2686
+ var MAX_WRITTEN_HOPS = 4;
2684
2687
  var ORIGIN = {
2685
- declaredBy: (origin, receiver) => origin.importedFrom.some(
2688
+ declaredBy: (origin, receiver) => receiver.callee !== null && origin.importedFrom.some(
2686
2689
  (module2) => methodDeclaredIn(receiver.callee, module2, receiver.resolve)
2687
2690
  ),
2688
2691
  constructed: (origin, receiver) => origin.importedFrom.some(
2689
2692
  (module2) => isImportedFrom(madeBy(receiver), module2)
2690
2693
  )
2691
2694
  };
2695
+ var CALL_ORIGIN = {
2696
+ declaredBy: ORIGIN.declaredBy,
2697
+ constructed: (origin, receiver) => origin.importedFrom.some(
2698
+ (module2) => isImportedFrom(
2699
+ rootIdentifier(receiver.expression) ?? receiver.expression,
2700
+ module2
2701
+ )
2702
+ )
2703
+ };
2692
2704
  function madeBy(receiver) {
2705
+ if (receiver.callee === null) {
2706
+ return rootIdentifier(receiver.expression) ?? receiver.expression;
2707
+ }
2693
2708
  const written = receiver.resolve(receiver.callee.getExpression());
2694
2709
  if (written === null || !import_ts_morph14.Node.isNewExpression(written) && !import_ts_morph14.Node.isCallExpression(written)) {
2695
2710
  return receiver.callee;
@@ -2698,30 +2713,217 @@ function madeBy(receiver) {
2698
2713
  }
2699
2714
  function callOpsFor(call, resolveWrittenValue) {
2700
2715
  const resolve2 = resolveWrittenValue ?? (() => null);
2701
- const expression = call.getExpression();
2716
+ const expression = calleeOf(call);
2702
2717
  const callee = import_ts_morph14.Node.isPropertyAccessExpression(expression) ? expression : null;
2703
2718
  let args = null;
2704
2719
  const argumentsOf = () => {
2705
- args ??= call.getArguments();
2720
+ args ??= argumentsIn(call);
2706
2721
  return args;
2707
2722
  };
2708
2723
  return {
2709
2724
  method: () => callee === null ? null : callee.getName(),
2710
- receiverIsFrom: (origin) => callee !== null && ORIGIN[origin.origin](origin, { callee, resolve: resolve2 }),
2725
+ receiverIsFrom: (origin) => ORIGIN[origin.origin](origin, { callee, expression, resolve: resolve2 }),
2726
+ isFrom: (origin) => CALL_ORIGIN[origin.origin](origin, { callee, expression, resolve: resolve2 }),
2711
2727
  argumentCount: () => argumentsOf().length,
2712
2728
  nameAt: (index, unsettled) => nameAt(argumentsOf()[index], unsettled, resolve2),
2713
2729
  calleeText: () => expression.getText(),
2730
+ receiver: () => callee === null ? null : opsOverCall(callee.getExpression(), resolve2),
2731
+ argument: (index) => opsOverCall(argumentsOf()[index], resolve2),
2732
+ callee: () => opsOverCall(expression, resolve2),
2733
+ propertyAt: (index, property, unsettled) => propertyAt(argumentsOf()[index], property, unsettled, resolve2),
2734
+ valueAt: (index) => {
2735
+ const argument = argumentsOf()[index];
2736
+ return argument === void 0 ? null : valueOpsFor(argument, resolve2);
2737
+ },
2714
2738
  ast: () => call
2715
2739
  };
2716
2740
  }
2741
+ function valueOpsFor(value, resolve2) {
2742
+ let settledValue;
2743
+ const written = () => {
2744
+ settledValue ??= settled(value, resolve2) ?? value;
2745
+ return settledValue;
2746
+ };
2747
+ return {
2748
+ text: () => literalText(written()),
2749
+ flag: () => literalFlag(written()),
2750
+ entries: (unsettled) => entriesOf(written(), unsettled, resolve2),
2751
+ items: () => itemsOf(written(), resolve2),
2752
+ property: (name) => {
2753
+ const object = written();
2754
+ const inside = import_ts_morph14.Node.isObjectLiteralExpression(object) ? initializerOf(object, name) : null;
2755
+ return inside === null ? null : valueOpsFor(inside, resolve2);
2756
+ },
2757
+ parts: () => literalParts(written()),
2758
+ holes: () => templateHoles(written(), resolve2)
2759
+ };
2760
+ }
2761
+ function literalParts(value) {
2762
+ const written = untagged(value);
2763
+ const whole = literalText(written);
2764
+ if (whole !== null) {
2765
+ return [whole];
2766
+ }
2767
+ if (!import_ts_morph14.Node.isTemplateExpression(written)) {
2768
+ return null;
2769
+ }
2770
+ return [
2771
+ written.getHead().getLiteralText(),
2772
+ ...written.getTemplateSpans().map((span) => span.getLiteral().getLiteralText())
2773
+ ];
2774
+ }
2775
+ function templateHoles(value, resolve2) {
2776
+ const written = untagged(value);
2777
+ if (!import_ts_morph14.Node.isTemplateExpression(written)) {
2778
+ return [];
2779
+ }
2780
+ return written.getTemplateSpans().map((span) => opsOverCall(span.getExpression(), resolve2));
2781
+ }
2782
+ function untagged(value) {
2783
+ return import_ts_morph14.Node.isTaggedTemplateExpression(value) ? value.getTemplate() : value;
2784
+ }
2785
+ function entriesOf(value, unsettled, resolve2) {
2786
+ if (!import_ts_morph14.Node.isObjectLiteralExpression(value)) {
2787
+ return [];
2788
+ }
2789
+ const found = [];
2790
+ for (const written of value.getProperties()) {
2791
+ if (import_ts_morph14.Node.isShorthandPropertyAssignment(written)) {
2792
+ const name = written.getNameNode();
2793
+ found.push({ key: name.getText(), value: valueOpsFor(name, resolve2) });
2794
+ continue;
2795
+ }
2796
+ if (!import_ts_morph14.Node.isPropertyAssignment(written)) {
2797
+ continue;
2798
+ }
2799
+ const stated = written.getInitializer();
2800
+ found.push({
2801
+ key: entryKey(written, unsettled, resolve2),
2802
+ value: valueOpsFor(stated ?? written, resolve2)
2803
+ });
2804
+ }
2805
+ return found;
2806
+ }
2807
+ function entryKey(written, unsettled, resolve2) {
2808
+ const name = written.getNameNode();
2809
+ if (import_ts_morph14.Node.isComputedPropertyName(name)) {
2810
+ return readName(name.getExpression(), { resolve: resolve2, unsettled });
2811
+ }
2812
+ return unquoted(written.getName());
2813
+ }
2814
+ function itemsOf(value, resolve2) {
2815
+ if (!import_ts_morph14.Node.isArrayLiteralExpression(value)) {
2816
+ return [];
2817
+ }
2818
+ return value.getElements().map((element) => valueOpsFor(element, resolve2));
2819
+ }
2820
+ function literalText(value) {
2821
+ return import_ts_morph14.Node.isStringLiteral(value) || import_ts_morph14.Node.isNoSubstitutionTemplateLiteral(value) ? value.getLiteralValue() : null;
2822
+ }
2823
+ function literalFlag(value) {
2824
+ if (import_ts_morph14.Node.isTrueLiteral(value) || import_ts_morph14.Node.isFalseLiteral(value)) {
2825
+ return import_ts_morph14.Node.isTrueLiteral(value);
2826
+ }
2827
+ return import_ts_morph14.Node.isNumericLiteral(value) ? value.getLiteralValue() !== 0 : null;
2828
+ }
2829
+ function unquoted(name) {
2830
+ return name.replace(/^["']|["']$/g, "");
2831
+ }
2832
+ function opsOverCall(value, resolve2) {
2833
+ const written = settled(value, resolve2);
2834
+ if (written === null || !isCalled(written)) {
2835
+ return null;
2836
+ }
2837
+ return callOpsFor(written, resolve2);
2838
+ }
2839
+ function isCalled(value) {
2840
+ return import_ts_morph14.Node.isCallExpression(value) || import_ts_morph14.Node.isNewExpression(value) || import_ts_morph14.Node.isTaggedTemplateExpression(value);
2841
+ }
2842
+ function calleeOf(call) {
2843
+ return import_ts_morph14.Node.isTaggedTemplateExpression(call) ? call.getTag() : call.getExpression();
2844
+ }
2845
+ function argumentsIn(call) {
2846
+ return import_ts_morph14.Node.isTaggedTemplateExpression(call) ? [call.getTemplate()] : call.getArguments();
2847
+ }
2848
+ function settled(value, resolve2) {
2849
+ let step = unwrapped(value ?? null);
2850
+ for (let hops = 0; hops < MAX_WRITTEN_HOPS; hops += 1) {
2851
+ if (step === null || !import_ts_morph14.Node.isIdentifier(step)) {
2852
+ return step;
2853
+ }
2854
+ const written = variableFor(step)?.getInitializer() ?? resolve2(step);
2855
+ if (written === null || written === step) {
2856
+ return null;
2857
+ }
2858
+ step = unwrapped(written);
2859
+ }
2860
+ return null;
2861
+ }
2862
+ function unwrapped(value) {
2863
+ let inside = value;
2864
+ while (inside !== null && (import_ts_morph14.Node.isAwaitExpression(inside) || import_ts_morph14.Node.isParenthesizedExpression(inside))) {
2865
+ inside = inside.getExpression();
2866
+ }
2867
+ return inside;
2868
+ }
2869
+ function variableFor(name) {
2870
+ if (!import_ts_morph14.Node.isIdentifier(name)) {
2871
+ return null;
2872
+ }
2873
+ for (const declaration of name.getSymbol()?.getDeclarations() ?? []) {
2874
+ if (import_ts_morph14.Node.isVariableDeclaration(declaration)) {
2875
+ return declaration;
2876
+ }
2877
+ }
2878
+ return null;
2879
+ }
2717
2880
  function nameAt(argument, unsettled, resolve2) {
2718
2881
  if (argument === void 0) {
2719
2882
  return null;
2720
2883
  }
2721
2884
  return readName(argument, { resolve: resolve2, unsettled });
2722
2885
  }
2886
+ function propertyAt(argument, property, unsettled, resolve2) {
2887
+ const stated = objectAt(argument, resolve2);
2888
+ const written = stated === null ? null : initializerOf(stated, property);
2889
+ return written === null ? null : readName(written, { resolve: resolve2, unsettled });
2890
+ }
2891
+ function objectAt(argument, resolve2) {
2892
+ const written = settled(argument, resolve2);
2893
+ if (written === null) {
2894
+ return null;
2895
+ }
2896
+ if (isCalled(written)) {
2897
+ return objectAt(argumentsIn(written)[0], resolve2);
2898
+ }
2899
+ return import_ts_morph14.Node.isObjectLiteralExpression(written) ? written : null;
2900
+ }
2901
+ function initializerOf(object, property) {
2902
+ for (const written of object.getProperties()) {
2903
+ if (import_ts_morph14.Node.isPropertyAssignment(written) && written.getName() === property) {
2904
+ return written.getInitializer() ?? null;
2905
+ }
2906
+ }
2907
+ return null;
2908
+ }
2723
2909
 
2724
2910
  // src/resolve/invocationEffects.ts
2911
+ function invocationContextFor(call, resolveWrittenValue) {
2912
+ let ops = null;
2913
+ return {
2914
+ call,
2915
+ sourceFile: call.getSourceFile(),
2916
+ extractArgs: () => extractArgs(call),
2917
+ isImportedFrom,
2918
+ // A context built without a store gives null, and the recognizer's
2919
+ // own pattern match runs on the raw node.
2920
+ resolveWrittenValue: resolveWrittenValue ?? (() => null),
2921
+ get ops() {
2922
+ ops ??= callOpsFor(call, resolveWrittenValue);
2923
+ return ops;
2924
+ }
2925
+ };
2926
+ }
2725
2927
  function isImportedFrom(identifier, expectedModule) {
2726
2928
  if (!import_ts_morph15.Node.isIdentifier(identifier)) {
2727
2929
  return false;
@@ -2930,20 +3132,7 @@ function runInvocationRecognizers(func, recognizers, barriers = NO_BARRIERS, res
2930
3132
  if (!import_ts_morph15.Node.isCallExpression(node)) {
2931
3133
  return;
2932
3134
  }
2933
- let ops = null;
2934
- const ctx = {
2935
- call: node,
2936
- sourceFile,
2937
- extractArgs: () => extractArgs(node),
2938
- isImportedFrom,
2939
- // A context built without a store gives null, and the recognizer's
2940
- // own pattern match runs on the raw node.
2941
- resolveWrittenValue: resolveWrittenValue ?? (() => null),
2942
- get ops() {
2943
- ops ??= callOpsFor(node, resolveWrittenValue);
2944
- return ops;
2945
- }
2946
- };
3135
+ const ctx = invocationContextFor(node, resolveWrittenValue);
2947
3136
  const line = enclosingStatementLine(node);
2948
3137
  for (const recognizer of recognizers) {
2949
3138
  let emitted = null;
@@ -2984,6 +3173,20 @@ function runAccessRecognizersAtModuleScope(sourceFile, recognizers, resolveWritt
2984
3173
  resolveWrittenValue
2985
3174
  );
2986
3175
  }
3176
+ function accessContextFor(node, sourceFile, resolveWrittenValue = () => null) {
3177
+ const given = { access: node, sourceFile, resolveWrittenValue };
3178
+ if (import_ts_morph15.Node.isPropertyAccessExpression(node)) {
3179
+ return given;
3180
+ }
3181
+ let ops;
3182
+ return {
3183
+ ...given,
3184
+ get ops() {
3185
+ ops ??= callOpsFor(node, resolveWrittenValue);
3186
+ return ops;
3187
+ }
3188
+ };
3189
+ }
2987
3190
  function dispatchAccessRecognizers(root, recognizers, isStop, resolveWrittenValue) {
2988
3191
  if (recognizers.length === 0) {
2989
3192
  return [];
@@ -2999,11 +3202,7 @@ function dispatchAccessRecognizers(root, recognizers, isStop, resolveWrittenValu
2999
3202
  if (!import_ts_morph15.Node.isPropertyAccessExpression(node) && !import_ts_morph15.Node.isCallExpression(node) && !import_ts_morph15.Node.isTaggedTemplateExpression(node)) {
3000
3203
  return;
3001
3204
  }
3002
- const ctx = {
3003
- access: node,
3004
- sourceFile,
3005
- resolveWrittenValue: resolveWrittenValue ?? (() => null)
3006
- };
3205
+ const ctx = accessContextFor(node, sourceFile, resolveWrittenValue);
3007
3206
  const line = enclosingStatementLine(node);
3008
3207
  for (const recognizer of recognizers) {
3009
3208
  let emitted = null;
@@ -3166,8 +3365,8 @@ function inlineModuleBinding(ident, depth) {
3166
3365
  if (init === void 0) {
3167
3366
  continue;
3168
3367
  }
3169
- const unwrapped = unwrapCasts(init);
3170
- const captured = extractArg(unwrapped, depth - 1);
3368
+ const unwrapped2 = unwrapCasts(init);
3369
+ const captured = extractArg(unwrapped2, depth - 1);
3171
3370
  if (captured !== null) {
3172
3371
  return captured;
3173
3372
  }
@@ -3872,35 +4071,35 @@ function extractShapeWithArguments(node, substitutions) {
3872
4071
  }
3873
4072
  }
3874
4073
  function extractShapeInner(node) {
3875
- const unwrapped = peelSyntax(node);
3876
- if (boundArguments !== null && import_ts_morph17.Node.isIdentifier(unwrapped)) {
3877
- const argument = boundArguments.get(unwrapped.getText());
3878
- if (argument !== void 0 && argument !== unwrapped) {
4074
+ const unwrapped2 = peelSyntax(node);
4075
+ if (boundArguments !== null && import_ts_morph17.Node.isIdentifier(unwrapped2)) {
4076
+ const argument = boundArguments.get(unwrapped2.getText());
4077
+ if (argument !== void 0 && argument !== unwrapped2) {
3879
4078
  return extractShape(argument);
3880
4079
  }
3881
4080
  }
3882
- if (import_ts_morph17.Node.isObjectLiteralExpression(unwrapped)) {
3883
- return shapeFromObjectLiteral(unwrapped);
4081
+ if (import_ts_morph17.Node.isObjectLiteralExpression(unwrapped2)) {
4082
+ return shapeFromObjectLiteral(unwrapped2);
3884
4083
  }
3885
- if (import_ts_morph17.Node.isArrayLiteralExpression(unwrapped)) {
3886
- return shapeFromArrayLiteral(unwrapped);
4084
+ if (import_ts_morph17.Node.isArrayLiteralExpression(unwrapped2)) {
4085
+ return shapeFromArrayLiteral(unwrapped2);
3887
4086
  }
3888
- if (import_ts_morph17.Node.isStringLiteral(unwrapped) || import_ts_morph17.Node.isNoSubstitutionTemplateLiteral(unwrapped)) {
3889
- return { type: "literal", value: unwrapped.getLiteralValue() };
4087
+ if (import_ts_morph17.Node.isStringLiteral(unwrapped2) || import_ts_morph17.Node.isNoSubstitutionTemplateLiteral(unwrapped2)) {
4088
+ return { type: "literal", value: unwrapped2.getLiteralValue() };
3890
4089
  }
3891
- if (import_ts_morph17.Node.isTemplateExpression(unwrapped)) {
4090
+ if (import_ts_morph17.Node.isTemplateExpression(unwrapped2)) {
3892
4091
  return { type: "text" };
3893
4092
  }
3894
- if (import_ts_morph17.Node.isNumericLiteral(unwrapped)) {
4093
+ if (import_ts_morph17.Node.isNumericLiteral(unwrapped2)) {
3895
4094
  return numericLiteralShape(
3896
- unwrapped.getLiteralValue(),
3897
- unwrapped.getText()
4095
+ unwrapped2.getLiteralValue(),
4096
+ unwrapped2.getText()
3898
4097
  );
3899
4098
  }
3900
- if (import_ts_morph17.Node.isPrefixUnaryExpression(unwrapped)) {
3901
- const op = unwrapped.getOperatorToken();
4099
+ if (import_ts_morph17.Node.isPrefixUnaryExpression(unwrapped2)) {
4100
+ const op = unwrapped2.getOperatorToken();
3902
4101
  if (op === import_ts_morph17.SyntaxKind.MinusToken || op === import_ts_morph17.SyntaxKind.PlusToken) {
3903
- const inner = unwrapped.getOperand();
4102
+ const inner = unwrapped2.getOperand();
3904
4103
  if (import_ts_morph17.Node.isNumericLiteral(inner)) {
3905
4104
  const v3 = inner.getLiteralValue();
3906
4105
  const signed = op === import_ts_morph17.SyntaxKind.MinusToken ? -v3 : v3;
@@ -3910,10 +4109,10 @@ function extractShapeInner(node) {
3910
4109
  }
3911
4110
  }
3912
4111
  }
3913
- if (import_ts_morph17.Node.isBigIntLiteral(unwrapped)) {
4112
+ if (import_ts_morph17.Node.isBigIntLiteral(unwrapped2)) {
3914
4113
  return { type: "ref", name: "bigint" };
3915
4114
  }
3916
- const kind = unwrapped.getKind();
4115
+ const kind = unwrapped2.getKind();
3917
4116
  if (kind === import_ts_morph17.SyntaxKind.TrueKeyword) {
3918
4117
  return { type: "literal", value: true };
3919
4118
  }
@@ -3923,12 +4122,12 @@ function extractShapeInner(node) {
3923
4122
  if (kind === import_ts_morph17.SyntaxKind.NullKeyword) {
3924
4123
  return { type: "null" };
3925
4124
  }
3926
- if (import_ts_morph17.Node.isIdentifier(unwrapped) && unwrapped.getText() === "undefined") {
4125
+ if (import_ts_morph17.Node.isIdentifier(unwrapped2) && unwrapped2.getText() === "undefined") {
3927
4126
  return { type: "undefined" };
3928
4127
  }
3929
- if (import_ts_morph17.Node.isConditionalExpression(unwrapped)) {
3930
- const whenTrue = extractShape(unwrapped.getWhenTrue());
3931
- const whenFalse = extractShape(unwrapped.getWhenFalse());
4128
+ if (import_ts_morph17.Node.isConditionalExpression(unwrapped2)) {
4129
+ const whenTrue = extractShape(unwrapped2.getWhenTrue());
4130
+ const whenFalse = extractShape(unwrapped2.getWhenFalse());
3932
4131
  const variants = [];
3933
4132
  if (whenTrue) {
3934
4133
  variants.push(whenTrue);
@@ -3937,15 +4136,15 @@ function extractShapeInner(node) {
3937
4136
  variants.push(whenFalse);
3938
4137
  }
3939
4138
  if (variants.length === 0) {
3940
- return shapeFromNodeType(unwrapped);
4139
+ return shapeFromNodeType(unwrapped2);
3941
4140
  }
3942
4141
  return collapseVariants2(variants);
3943
4142
  }
3944
- const astShape = resolveNodeFromAst(unwrapped, extractShape);
4143
+ const astShape = resolveNodeFromAst(unwrapped2, extractShape);
3945
4144
  if (astShape !== null) {
3946
4145
  return astShape;
3947
4146
  }
3948
- return shapeFromNodeType(unwrapped);
4147
+ return shapeFromNodeType(unwrapped2);
3949
4148
  }
3950
4149
  function numericLiteralShape(value, raw) {
3951
4150
  return { type: "literal", value, raw };
@@ -4103,15 +4302,15 @@ function matchConstructorCode(ctorText, codes) {
4103
4302
  return null;
4104
4303
  }
4105
4304
  function statusOf(value, ctx) {
4106
- const unwrapped = unwrapAs(value);
4107
- if (import_ts_morph18.Node.isNumericLiteral(unwrapped)) {
4108
- return { type: "literal", value: Number(unwrapped.getText()) };
4305
+ const unwrapped2 = unwrapAs(value);
4306
+ if (import_ts_morph18.Node.isNumericLiteral(unwrapped2)) {
4307
+ return { type: "literal", value: Number(unwrapped2.getText()) };
4109
4308
  }
4110
- const resolved = ctx.resolveWrittenValue?.(unwrapped) ?? null;
4309
+ const resolved = ctx.resolveWrittenValue?.(unwrapped2) ?? null;
4111
4310
  if (resolved !== null && import_ts_morph18.Node.isNumericLiteral(resolved)) {
4112
4311
  return { type: "literal", value: Number(resolved.getText()) };
4113
4312
  }
4114
- return { type: "dynamic", sourceText: unwrapped.getText() };
4313
+ return { type: "dynamic", sourceText: unwrapped2.getText() };
4115
4314
  }
4116
4315
  function statusFromProperty(obj, name, ctx) {
4117
4316
  const prop = obj.getProperty(name);
@@ -4494,9 +4693,9 @@ function returnedObjects(fn) {
4494
4693
  if (expression === void 0) {
4495
4694
  continue;
4496
4695
  }
4497
- const unwrapped = peelParens(expression);
4498
- if (import_ts_morph19.Node.isObjectLiteralExpression(unwrapped)) {
4499
- found.push(unwrapped);
4696
+ const unwrapped2 = peelParens(expression);
4697
+ if (import_ts_morph19.Node.isObjectLiteralExpression(unwrapped2)) {
4698
+ found.push(unwrapped2);
4500
4699
  }
4501
4700
  }
4502
4701
  return found;
@@ -7883,7 +8082,7 @@ function classDecoratorStandingFor(cls, names, modules, resolution) {
7883
8082
  return null;
7884
8083
  }
7885
8084
  for (const decorator of cls.getDecorators()) {
7886
- const applied = resolution.importedNamesOf(calleeOf(decorator), modules);
8085
+ const applied = resolution.importedNamesOf(calleeOf2(decorator), modules);
7887
8086
  const standsFor = names.find((name) => applied.includes(name));
7888
8087
  if (standsFor === void 0) {
7889
8088
  continue;
@@ -7901,7 +8100,7 @@ function frameworkArgs(decorator, standsFor, modules, resolution) {
7901
8100
  if (atClass.length > 0) {
7902
8101
  return atClass;
7903
8102
  }
7904
- const wrapper = resolution.resolveCallable(calleeOf(decorator));
8103
+ const wrapper = resolution.resolveCallable(calleeOf2(decorator));
7905
8104
  if (wrapper === null) {
7906
8105
  return atClass;
7907
8106
  }
@@ -7926,7 +8125,7 @@ function statesAValue(arg, wrapper) {
7926
8125
  function isWithin(node, container) {
7927
8126
  return node.getSourceFile() === container.getSourceFile() && node.getStart() >= container.getStart() && node.getEnd() <= container.getEnd();
7928
8127
  }
7929
- function calleeOf(decorator) {
8128
+ function calleeOf2(decorator) {
7930
8129
  const call = decorator.getCallExpression();
7931
8130
  if (call !== void 0) {
7932
8131
  return call.getExpression();
@@ -9127,9 +9326,9 @@ function attributeValueOf(node, name) {
9127
9326
  return null;
9128
9327
  }
9129
9328
  function literalStringOf(value) {
9130
- const unwrapped = import_ts_morph43.Node.isJsxExpression(value) ? value.getExpression() ?? value : value;
9131
- if (import_ts_morph43.Node.isStringLiteral(unwrapped) || import_ts_morph43.Node.isNoSubstitutionTemplateLiteral(unwrapped)) {
9132
- return unwrapped.getLiteralValue();
9329
+ const unwrapped2 = import_ts_morph43.Node.isJsxExpression(value) ? value.getExpression() ?? value : value;
9330
+ if (import_ts_morph43.Node.isStringLiteral(unwrapped2) || import_ts_morph43.Node.isNoSubstitutionTemplateLiteral(unwrapped2)) {
9331
+ return unwrapped2.getLiteralValue();
9133
9332
  }
9134
9333
  return null;
9135
9334
  }
@@ -9148,11 +9347,11 @@ function elementTargetOfValue(value) {
9148
9347
  if (value === null) {
9149
9348
  return { kind: "absent" };
9150
9349
  }
9151
- const unwrapped = import_ts_morph43.Node.isJsxExpression(value) ? value.getExpression() ?? value : value;
9152
- if (!import_ts_morph43.Node.isJsxSelfClosingElement(unwrapped) && !import_ts_morph43.Node.isJsxElement(unwrapped)) {
9350
+ const unwrapped2 = import_ts_morph43.Node.isJsxExpression(value) ? value.getExpression() ?? value : value;
9351
+ if (!import_ts_morph43.Node.isJsxSelfClosingElement(unwrapped2) && !import_ts_morph43.Node.isJsxElement(unwrapped2)) {
9153
9352
  return { kind: "unreadable" };
9154
9353
  }
9155
- const tag = tagNameOf(unwrapped);
9354
+ const tag = tagNameOf(unwrapped2);
9156
9355
  if (tag === null) {
9157
9356
  return { kind: "unreadable" };
9158
9357
  }
@@ -10016,7 +10215,146 @@ function discoverPackageImports(sourceFile, match, kind) {
10016
10215
  }
10017
10216
 
10018
10217
  // src/discovery/registrationCall.ts
10218
+ var import_ts_morph49 = require("ts-morph");
10219
+
10220
+ // src/resolve/routePath.ts
10019
10221
  var import_ts_morph48 = require("ts-morph");
10222
+ var import_behavioral_ir5 = require("@suss/behavioral-ir");
10223
+ var URL_SCHEME = /^[a-zA-Z][a-zA-Z\d+.-]*:\/\//;
10224
+ var URL_ORIGIN = /^[a-zA-Z][a-zA-Z\d+.-]*:\/\/[^/]*/;
10225
+ var PROTOCOL_RELATIVE = /^\/\//;
10226
+ var PROTOCOL_RELATIVE_ORIGIN = /^\/\/[^/]*/;
10227
+ function isAbsoluteUrlLiteral(text) {
10228
+ return URL_SCHEME.test(text) || PROTOCOL_RELATIVE.test(text);
10229
+ }
10230
+ function stripOriginManually(text) {
10231
+ if (URL_SCHEME.test(text)) {
10232
+ return text.replace(URL_ORIGIN, "");
10233
+ }
10234
+ if (PROTOCOL_RELATIVE.test(text)) {
10235
+ return text.replace(PROTOCOL_RELATIVE_ORIGIN, "");
10236
+ }
10237
+ return text;
10238
+ }
10239
+ function stripQueryAndFragment(text) {
10240
+ const idx = text.search(/[?#]/);
10241
+ return idx === -1 ? text : text.slice(0, idx);
10242
+ }
10243
+ var SUBSTITUTION = "\uFFFF";
10244
+ var AUTHORITY_OPENER = /^(?:[-+.\uFFFFa-zA-Z0-9]+:\/\/|\/\/)/;
10245
+ function originEndOf(flattened) {
10246
+ const opener = AUTHORITY_OPENER.exec(flattened);
10247
+ if (opener === null) {
10248
+ return 0;
10249
+ }
10250
+ const slash = flattened.indexOf("/", opener[0].length);
10251
+ return slash === -1 ? flattened.length : slash;
10252
+ }
10253
+ function appendPathText(path12, text) {
10254
+ const idx = text.search(/[?#]/);
10255
+ if (idx === -1) {
10256
+ return { path: path12 + text, stop: false };
10257
+ }
10258
+ return { path: path12 + text.slice(0, idx), stop: true };
10259
+ }
10260
+ function parseAbsoluteUrl(text) {
10261
+ try {
10262
+ return new URL(text);
10263
+ } catch {
10264
+ }
10265
+ if (!PROTOCOL_RELATIVE.test(text)) {
10266
+ return void 0;
10267
+ }
10268
+ try {
10269
+ return new URL(`https:${text}`);
10270
+ } catch {
10271
+ return void 0;
10272
+ }
10273
+ }
10274
+ function pathnameOfAbsoluteLiteral(text) {
10275
+ const parsed = parseAbsoluteUrl(text);
10276
+ if (parsed !== void 0) {
10277
+ return parsed.pathname;
10278
+ }
10279
+ return stripQueryAndFragment(stripOriginManually(text));
10280
+ }
10281
+ function pathFromLiteralUrl(text) {
10282
+ const path12 = isAbsoluteUrlLiteral(text) ? pathnameOfAbsoluteLiteral(text) : stripQueryAndFragment(text);
10283
+ return path12 === "" ? void 0 : path12;
10284
+ }
10285
+ function pathFromTemplateUrl(arg, resolution) {
10286
+ const headText = arg.getHead().getLiteralText();
10287
+ const spans = arg.getTemplateSpans();
10288
+ const tails = spans.map((span) => span.getLiteral().getLiteralText());
10289
+ const originEnd = originEndOf([headText, ...tails].join(SUBSTITUTION));
10290
+ const head = appendPathText("", headText.slice(originEnd));
10291
+ let path12 = head.path;
10292
+ let stop = head.stop;
10293
+ let at = headText.length;
10294
+ for (let i = 0; i < spans.length && !stop; i++) {
10295
+ const span = spans[i];
10296
+ const tailText = tails[i];
10297
+ if (span === void 0 || tailText === void 0) {
10298
+ continue;
10299
+ }
10300
+ if (at >= originEnd) {
10301
+ path12 += holeText(span.getExpression(), resolution);
10302
+ }
10303
+ at += SUBSTITUTION.length;
10304
+ const appended = appendPathText(
10305
+ path12,
10306
+ tailText.slice(Math.max(0, originEnd - at))
10307
+ );
10308
+ path12 = appended.path;
10309
+ stop = appended.stop;
10310
+ at += tailText.length;
10311
+ }
10312
+ return path12 === "" ? void 0 : path12;
10313
+ }
10314
+ function pathFromUrlNode(node, resolution) {
10315
+ if (import_ts_morph48.Node.isStringLiteral(node)) {
10316
+ return pathFromLiteralUrl(node.getLiteralValue());
10317
+ }
10318
+ if (import_ts_morph48.Node.isNoSubstitutionTemplateLiteral(node)) {
10319
+ return pathFromLiteralUrl(node.getLiteralValue());
10320
+ }
10321
+ if (import_ts_morph48.Node.isTemplateExpression(node)) {
10322
+ return pathFromTemplateUrl(node, resolution);
10323
+ }
10324
+ return void 0;
10325
+ }
10326
+ function placeholderName(expr) {
10327
+ if (import_ts_morph48.Node.isIdentifier(expr)) {
10328
+ return expr.getText();
10329
+ }
10330
+ if (import_ts_morph48.Node.isPropertyAccessExpression(expr)) {
10331
+ return expr.getName();
10332
+ }
10333
+ return "param";
10334
+ }
10335
+ function holeText(expr, resolution) {
10336
+ const written = resolution?.resolveWrittenValue(expr) ?? null;
10337
+ if (written === null) {
10338
+ return (0, import_behavioral_ir5.patternHole)(placeholderName(expr));
10339
+ }
10340
+ if (emptyStringLiteral(written)) {
10341
+ return "";
10342
+ }
10343
+ return pathFromUrlNode(written, resolution) ?? (0, import_behavioral_ir5.patternHole)(placeholderName(expr));
10344
+ }
10345
+ function emptyStringLiteral(node) {
10346
+ return (import_ts_morph48.Node.isStringLiteral(node) || import_ts_morph48.Node.isNoSubstitutionTemplateLiteral(node)) && node.getLiteralValue() === "";
10347
+ }
10348
+ function pathFromArgument(arg, resolution) {
10349
+ const written = pathFromUrlNode(arg, resolution);
10350
+ if (written !== void 0) {
10351
+ return written;
10352
+ }
10353
+ const resolved = resolution?.resolveWrittenValue(arg) ?? null;
10354
+ return resolved !== null ? pathFromUrlNode(resolved, resolution) : void 0;
10355
+ }
10356
+
10357
+ // src/discovery/registrationCall.ts
10020
10358
  function discoverRegistrationCalls(sourceFile, match, kind, bindingExtraction, resolution, mountPrefixes) {
10021
10359
  const results = [];
10022
10360
  const registrationSubjects = registrationSubjectsOf(
@@ -10031,11 +10369,11 @@ function discoverRegistrationCalls(sourceFile, match, kind, bindingExtraction, r
10031
10369
  (c) => c.startsWith(".") ? c.slice(1) : c
10032
10370
  );
10033
10371
  sourceFile.forEachDescendant((node) => {
10034
- if (!import_ts_morph48.Node.isCallExpression(node)) {
10372
+ if (!import_ts_morph49.Node.isCallExpression(node)) {
10035
10373
  return;
10036
10374
  }
10037
10375
  const callee = node.getExpression();
10038
- if (!import_ts_morph48.Node.isPropertyAccessExpression(callee)) {
10376
+ if (!import_ts_morph49.Node.isPropertyAccessExpression(callee)) {
10039
10377
  return;
10040
10378
  }
10041
10379
  const methodName = callee.getName();
@@ -10043,7 +10381,7 @@ function discoverRegistrationCalls(sourceFile, match, kind, bindingExtraction, r
10043
10381
  return;
10044
10382
  }
10045
10383
  const subject = callee.getExpression();
10046
- const subjectName = import_ts_morph48.Node.isIdentifier(subject) ? subject.getText() : null;
10384
+ const subjectName = import_ts_morph49.Node.isIdentifier(subject) ? subject.getText() : null;
10047
10385
  const subjectNode = subjectName === null ? void 0 : registrationSubjects.get(subjectName);
10048
10386
  if (subjectNode === void 0) {
10049
10387
  return;
@@ -10051,12 +10389,12 @@ function discoverRegistrationCalls(sourceFile, match, kind, bindingExtraction, r
10051
10389
  const args = node.getArguments();
10052
10390
  let foundObjectArg = false;
10053
10391
  for (const arg of args) {
10054
- if (!import_ts_morph48.Node.isObjectLiteralExpression(arg)) {
10392
+ if (!import_ts_morph49.Node.isObjectLiteralExpression(arg)) {
10055
10393
  continue;
10056
10394
  }
10057
10395
  foundObjectArg = true;
10058
10396
  for (const prop of arg.getProperties()) {
10059
- if (import_ts_morph48.Node.isMethodDeclaration(prop)) {
10397
+ if (import_ts_morph49.Node.isMethodDeclaration(prop)) {
10060
10398
  results.push({
10061
10399
  func: prop,
10062
10400
  kind,
@@ -10064,7 +10402,7 @@ function discoverRegistrationCalls(sourceFile, match, kind, bindingExtraction, r
10064
10402
  });
10065
10403
  continue;
10066
10404
  }
10067
- if (!import_ts_morph48.Node.isPropertyAssignment(prop)) {
10405
+ if (!import_ts_morph49.Node.isPropertyAssignment(prop)) {
10068
10406
  continue;
10069
10407
  }
10070
10408
  const propInit = prop.getInitializer();
@@ -10162,9 +10500,9 @@ function registrationSubjectsOf(sourceFile, importModule, importName) {
10162
10500
  continue;
10163
10501
  }
10164
10502
  let calleeText = null;
10165
- if (import_ts_morph48.Node.isCallExpression(init)) {
10503
+ if (import_ts_morph49.Node.isCallExpression(init)) {
10166
10504
  calleeText = init.getExpression().getText();
10167
- } else if (import_ts_morph48.Node.isNewExpression(init)) {
10505
+ } else if (import_ts_morph49.Node.isNewExpression(init)) {
10168
10506
  calleeText = init.getExpression().getText();
10169
10507
  }
10170
10508
  if (calleeText === importedLocalName) {
@@ -10172,7 +10510,7 @@ function registrationSubjectsOf(sourceFile, importModule, importName) {
10172
10510
  }
10173
10511
  }
10174
10512
  sourceFile.forEachDescendant((node) => {
10175
- if (!import_ts_morph48.Node.isParameterDeclaration(node)) {
10513
+ if (!import_ts_morph49.Node.isParameterDeclaration(node)) {
10176
10514
  return;
10177
10515
  }
10178
10516
  const typeNode = node.getTypeNode();
@@ -10216,21 +10554,21 @@ function discoverMountEdges(sourceFile, match, mount, knownSubjectIds, resolutio
10216
10554
  }
10217
10555
  const edges = [];
10218
10556
  sourceFile.forEachDescendant((node) => {
10219
- if (!import_ts_morph48.Node.isCallExpression(node)) {
10557
+ if (!import_ts_morph49.Node.isCallExpression(node)) {
10220
10558
  return;
10221
10559
  }
10222
10560
  const callee = node.getExpression();
10223
- if (!import_ts_morph48.Node.isPropertyAccessExpression(callee) || callee.getName() !== mount.method) {
10561
+ if (!import_ts_morph49.Node.isPropertyAccessExpression(callee) || callee.getName() !== mount.method) {
10224
10562
  return;
10225
10563
  }
10226
10564
  const subject = callee.getExpression();
10227
- const subjectNode = import_ts_morph48.Node.isIdentifier(subject) ? subjects.get(subject.getText()) : void 0;
10565
+ const subjectNode = import_ts_morph49.Node.isIdentifier(subject) ? subjects.get(subject.getText()) : void 0;
10228
10566
  if (subjectNode === void 0) {
10229
10567
  return;
10230
10568
  }
10231
10569
  const args = node.getArguments();
10232
10570
  const prefixArg = args[mount.prefixPosition];
10233
- if (prefixArg === void 0 || !(import_ts_morph48.Node.isStringLiteral(prefixArg) || import_ts_morph48.Node.isNoSubstitutionTemplateLiteral(prefixArg))) {
10571
+ if (prefixArg === void 0 || !(import_ts_morph49.Node.isStringLiteral(prefixArg) || import_ts_morph49.Node.isNoSubstitutionTemplateLiteral(prefixArg))) {
10234
10572
  return;
10235
10573
  }
10236
10574
  const targetNodes = mountTargetsAmong(
@@ -10264,15 +10602,15 @@ function mountTargetsAmong(args, targetPosition, knownSubjectIds, resolution) {
10264
10602
  return targets;
10265
10603
  }
10266
10604
  function stringProperty(obj, name) {
10267
- if (!import_ts_morph48.Node.isObjectLiteralExpression(obj)) {
10605
+ if (!import_ts_morph49.Node.isObjectLiteralExpression(obj)) {
10268
10606
  return null;
10269
10607
  }
10270
10608
  const property = obj.getProperty(name);
10271
- if (property === void 0 || !import_ts_morph48.Node.isPropertyAssignment(property)) {
10609
+ if (property === void 0 || !import_ts_morph49.Node.isPropertyAssignment(property)) {
10272
10610
  return null;
10273
10611
  }
10274
10612
  const value = property.getInitializer();
10275
- if (value !== void 0 && (import_ts_morph48.Node.isStringLiteral(value) || import_ts_morph48.Node.isNoSubstitutionTemplateLiteral(value))) {
10613
+ if (value !== void 0 && (import_ts_morph49.Node.isStringLiteral(value) || import_ts_morph49.Node.isNoSubstitutionTemplateLiteral(value))) {
10276
10614
  return value.getLiteralValue();
10277
10615
  }
10278
10616
  return null;
@@ -10288,40 +10626,37 @@ function extractRouteInfoFromBinding(call, methodName, binding, resolution) {
10288
10626
  return null;
10289
10627
  }
10290
10628
  const method2 = stringProperty(routeObject, binding.method.property);
10291
- const path12 = stringProperty(routeObject, binding.path.property);
10292
- if (method2 === null || path12 === null) {
10629
+ const path13 = stringProperty(routeObject, binding.path.property);
10630
+ if (method2 === null || path13 === null) {
10293
10631
  return null;
10294
10632
  }
10295
- return { method: method2.toUpperCase(), path: path12 };
10633
+ return { method: method2.toUpperCase(), path: path13 };
10296
10634
  }
10297
- if (binding.method.type !== "fromRegistration" || binding.path.type !== "fromRegistration") {
10635
+ if (binding.method.type !== "fromRegistration" || binding.path.type !== "fromArgument") {
10298
10636
  return null;
10299
10637
  }
10300
10638
  let method;
10301
10639
  if (binding.method.position === "methodName") {
10302
10640
  method = binding.method.nameMap?.[methodName] ?? methodName.toUpperCase();
10303
10641
  } else {
10304
- const args2 = call.getArguments();
10305
- const arg = args2[binding.method.position];
10306
- if (arg === void 0 || !(import_ts_morph48.Node.isStringLiteral(arg) || import_ts_morph48.Node.isNoSubstitutionTemplateLiteral(arg))) {
10642
+ const args = call.getArguments();
10643
+ const arg = args[binding.method.position];
10644
+ if (arg === void 0 || !(import_ts_morph49.Node.isStringLiteral(arg) || import_ts_morph49.Node.isNoSubstitutionTemplateLiteral(arg))) {
10307
10645
  return null;
10308
10646
  }
10309
10647
  method = arg.getLiteralValue().toUpperCase();
10310
10648
  }
10311
- const args = call.getArguments();
10312
- const pathArg = args[binding.path.position];
10313
- if (pathArg === void 0 || !(import_ts_morph48.Node.isStringLiteral(pathArg) || import_ts_morph48.Node.isNoSubstitutionTemplateLiteral(pathArg))) {
10314
- return null;
10315
- }
10316
- return { method, path: pathArg.getLiteralValue() };
10649
+ const pathArg = call.getArguments()[binding.path.position];
10650
+ const path12 = pathArg === void 0 ? void 0 : pathFromArgument(pathArg, resolution);
10651
+ return path12 === void 0 ? null : { method, path: path12 };
10317
10652
  }
10318
10653
 
10319
10654
  // src/discovery/registrationLoop.ts
10320
- var import_ts_morph49 = require("ts-morph");
10655
+ var import_ts_morph50 = require("ts-morph");
10321
10656
  function discoverRegistrationLoops(sourceFile, match, kind, resolution) {
10322
10657
  const results = [];
10323
10658
  sourceFile.forEachDescendant((node) => {
10324
- if (!import_ts_morph49.Node.isForOfStatement(node)) {
10659
+ if (!import_ts_morph50.Node.isForOfStatement(node)) {
10325
10660
  return;
10326
10661
  }
10327
10662
  const expanded = tryExpandLoop(node, match, kind, resolution);
@@ -10364,13 +10699,13 @@ function tryExpandLoop(loop, match, kind, resolution) {
10364
10699
  }
10365
10700
  function loopVariableName(loop) {
10366
10701
  const initializer = loop.getInitializer();
10367
- if (import_ts_morph49.Node.isVariableDeclarationList(initializer)) {
10702
+ if (import_ts_morph50.Node.isVariableDeclarationList(initializer)) {
10368
10703
  const decls = initializer.getDeclarations();
10369
10704
  if (decls.length !== 1) {
10370
10705
  return null;
10371
10706
  }
10372
10707
  const nameNode = decls[0]?.getNameNode();
10373
- if (nameNode !== void 0 && import_ts_morph49.Node.isIdentifier(nameNode)) {
10708
+ if (nameNode !== void 0 && import_ts_morph50.Node.isIdentifier(nameNode)) {
10374
10709
  return nameNode.getText();
10375
10710
  }
10376
10711
  }
@@ -10383,14 +10718,14 @@ function bodyReferencesLoopVar(loop, name) {
10383
10718
  if (referenced) {
10384
10719
  return;
10385
10720
  }
10386
- if (!import_ts_morph49.Node.isCallExpression(node)) {
10721
+ if (!import_ts_morph50.Node.isCallExpression(node)) {
10387
10722
  return;
10388
10723
  }
10389
10724
  node.forEachDescendant((inner) => {
10390
10725
  if (referenced) {
10391
10726
  return;
10392
10727
  }
10393
- if (import_ts_morph49.Node.isIdentifier(inner) && inner.getText() === name) {
10728
+ if (import_ts_morph50.Node.isIdentifier(inner) && inner.getText() === name) {
10394
10729
  referenced = true;
10395
10730
  }
10396
10731
  });
@@ -10402,11 +10737,11 @@ function readRouteSpec(element, shape, resolution) {
10402
10737
  let path12 = null;
10403
10738
  let handler = null;
10404
10739
  for (const prop of element.getProperties()) {
10405
- if (import_ts_morph49.Node.isMethodDeclaration(prop) && prop.getName() === shape.handlerKey) {
10740
+ if (import_ts_morph50.Node.isMethodDeclaration(prop) && prop.getName() === shape.handlerKey) {
10406
10741
  handler = { func: prop, name: shape.handlerKey };
10407
10742
  continue;
10408
10743
  }
10409
- if (!import_ts_morph49.Node.isPropertyAssignment(prop)) {
10744
+ if (!import_ts_morph50.Node.isPropertyAssignment(prop)) {
10410
10745
  continue;
10411
10746
  }
10412
10747
  const name = prop.getName();
@@ -10429,17 +10764,17 @@ function readRouteSpec(element, shape, resolution) {
10429
10764
  return { method, path: path12, handler: handler.func, handlerName: handler.name };
10430
10765
  }
10431
10766
  function readStringLiteralValue(node) {
10432
- if (import_ts_morph49.Node.isStringLiteral(node) || import_ts_morph49.Node.isNoSubstitutionTemplateLiteral(node)) {
10767
+ if (import_ts_morph50.Node.isStringLiteral(node) || import_ts_morph50.Node.isNoSubstitutionTemplateLiteral(node)) {
10433
10768
  return node.getLiteralValue();
10434
10769
  }
10435
10770
  return null;
10436
10771
  }
10437
10772
  function handlerName(value) {
10438
- return import_ts_morph49.Node.isIdentifier(value) ? value.getText() : value.getKindName();
10773
+ return import_ts_morph50.Node.isIdentifier(value) ? value.getText() : value.getKindName();
10439
10774
  }
10440
10775
 
10441
10776
  // src/discovery/registrationTemplate.ts
10442
- var import_ts_morph50 = require("ts-morph");
10777
+ var import_ts_morph51 = require("ts-morph");
10443
10778
  function discoverRegistrationTemplates(sourceFile, match, kind, resolution) {
10444
10779
  const localName = resolveImportedLocalName2(sourceFile, match);
10445
10780
  if (localName === null) {
@@ -10447,7 +10782,7 @@ function discoverRegistrationTemplates(sourceFile, match, kind, resolution) {
10447
10782
  }
10448
10783
  const results = [];
10449
10784
  sourceFile.forEachDescendant((node) => {
10450
- if (!import_ts_morph50.Node.isCallExpression(node)) {
10785
+ if (!import_ts_morph51.Node.isCallExpression(node)) {
10451
10786
  return;
10452
10787
  }
10453
10788
  if (!isCallToHelper(node, localName)) {
@@ -10498,7 +10833,7 @@ function resolveImportedLocalName2(sourceFile, match) {
10498
10833
  }
10499
10834
  function isCallToHelper(call, localName) {
10500
10835
  const callee = call.getExpression();
10501
- return import_ts_morph50.Node.isIdentifier(callee) && callee.getText() === localName;
10836
+ return import_ts_morph51.Node.isIdentifier(callee) && callee.getText() === localName;
10502
10837
  }
10503
10838
  function substitutePath(template, args) {
10504
10839
  const re = /\{(\d+)\}/g;
@@ -10524,7 +10859,7 @@ function substitutePath(template, args) {
10524
10859
  return result;
10525
10860
  }
10526
10861
  function readStringLiteral(node) {
10527
- if (import_ts_morph50.Node.isStringLiteral(node) || import_ts_morph50.Node.isNoSubstitutionTemplateLiteral(node)) {
10862
+ if (import_ts_morph51.Node.isStringLiteral(node) || import_ts_morph51.Node.isNoSubstitutionTemplateLiteral(node)) {
10528
10863
  return node.getLiteralValue();
10529
10864
  }
10530
10865
  return null;
@@ -10547,7 +10882,7 @@ function resolveHandler(template, args, resolution) {
10547
10882
  return readPropertyAsFunction(arg, prop, resolution);
10548
10883
  }
10549
10884
  function handlerName2(value) {
10550
- return import_ts_morph50.Node.isIdentifier(value) ? value.getText() : value.getKindName();
10885
+ return import_ts_morph51.Node.isIdentifier(value) ? value.getText() : value.getKindName();
10551
10886
  }
10552
10887
  function readPropertyAsFunction(arg, prop, resolution) {
10553
10888
  const obj = objectLiteralOf(arg, resolution);
@@ -10558,7 +10893,7 @@ function readPropertyAsFunction(arg, prop, resolution) {
10558
10893
  if (propertyName2(property) !== prop) {
10559
10894
  continue;
10560
10895
  }
10561
- if (import_ts_morph50.Node.isMethodDeclaration(property)) {
10896
+ if (import_ts_morph51.Node.isMethodDeclaration(property)) {
10562
10897
  return { func: property, name: prop };
10563
10898
  }
10564
10899
  const held = propertyValueOf(property);
@@ -10566,19 +10901,19 @@ function readPropertyAsFunction(arg, prop, resolution) {
10566
10901
  return null;
10567
10902
  }
10568
10903
  const func = functionValueOf(held, resolution);
10569
- return func === null ? null : { func, name: import_ts_morph50.Node.isIdentifier(held) ? held.getText() : prop };
10904
+ return func === null ? null : { func, name: import_ts_morph51.Node.isIdentifier(held) ? held.getText() : prop };
10570
10905
  }
10571
10906
  return null;
10572
10907
  }
10573
10908
  function propertyName2(property) {
10574
- if (import_ts_morph50.Node.isPropertyAssignment(property) || import_ts_morph50.Node.isShorthandPropertyAssignment(property) || import_ts_morph50.Node.isMethodDeclaration(property)) {
10909
+ if (import_ts_morph51.Node.isPropertyAssignment(property) || import_ts_morph51.Node.isShorthandPropertyAssignment(property) || import_ts_morph51.Node.isMethodDeclaration(property)) {
10575
10910
  return property.getName();
10576
10911
  }
10577
10912
  return null;
10578
10913
  }
10579
10914
 
10580
10915
  // src/discovery/resolverMap.ts
10581
- var import_ts_morph51 = require("ts-morph");
10916
+ var import_ts_morph52 = require("ts-morph");
10582
10917
  function discoverResolverMaps(sourceFile, match, kind, resolution) {
10583
10918
  const localName = resolveImportedLocalName(
10584
10919
  sourceFile,
@@ -10592,15 +10927,15 @@ function discoverResolverMaps(sourceFile, match, kind, resolution) {
10592
10927
  const excludeTypes = new Set(match.excludeTypes ?? []);
10593
10928
  const results = [];
10594
10929
  sourceFile.forEachDescendant((node) => {
10595
- if (!import_ts_morph51.Node.isCallExpression(node) && !import_ts_morph51.Node.isNewExpression(node)) {
10930
+ if (!import_ts_morph52.Node.isCallExpression(node) && !import_ts_morph52.Node.isNewExpression(node)) {
10596
10931
  return;
10597
10932
  }
10598
10933
  const callee = node.getExpression();
10599
- if (!import_ts_morph51.Node.isIdentifier(callee) || callee.getText() !== localName) {
10934
+ if (!import_ts_morph52.Node.isIdentifier(callee) || callee.getText() !== localName) {
10600
10935
  return;
10601
10936
  }
10602
10937
  const args = node.getArguments();
10603
- if (args.length === 0 || !import_ts_morph51.Node.isObjectLiteralExpression(args[0])) {
10938
+ if (args.length === 0 || !import_ts_morph52.Node.isObjectLiteralExpression(args[0])) {
10604
10939
  return;
10605
10940
  }
10606
10941
  const config = args[0];
@@ -10654,7 +10989,7 @@ function resolverMapObject(prop, resolution) {
10654
10989
  return held === null ? null : objectLiteralOf(held, resolution);
10655
10990
  }
10656
10991
  function extractTypeDefsSdl(config, resolution) {
10657
- if (!import_ts_morph51.Node.isObjectLiteralExpression(config)) {
10992
+ if (!import_ts_morph52.Node.isObjectLiteralExpression(config)) {
10658
10993
  return null;
10659
10994
  }
10660
10995
  const prop = config.getProperty("typeDefs");
@@ -10676,15 +11011,15 @@ function schemaSdlOf(expr, resolution) {
10676
11011
  return resolved === null ? null : writtenSdl(resolved);
10677
11012
  }
10678
11013
  function writtenSdl(expr) {
10679
- if (import_ts_morph51.Node.isStringLiteral(expr) || import_ts_morph51.Node.isNoSubstitutionTemplateLiteral(expr)) {
11014
+ if (import_ts_morph52.Node.isStringLiteral(expr) || import_ts_morph52.Node.isNoSubstitutionTemplateLiteral(expr)) {
10680
11015
  const value = expr.getLiteralValue();
10681
11016
  return value === "" ? null : value;
10682
11017
  }
10683
- if (import_ts_morph51.Node.isTaggedTemplateExpression(expr)) {
11018
+ if (import_ts_morph52.Node.isTaggedTemplateExpression(expr)) {
10684
11019
  const tag = expr.getTag();
10685
- if (import_ts_morph51.Node.isIdentifier(tag) && tag.getText() === "gql") {
11020
+ if (import_ts_morph52.Node.isIdentifier(tag) && tag.getText() === "gql") {
10686
11021
  const template = expr.getTemplate();
10687
- if (import_ts_morph51.Node.isNoSubstitutionTemplateLiteral(template)) {
11022
+ if (import_ts_morph52.Node.isNoSubstitutionTemplateLiteral(template)) {
10688
11023
  return template.getLiteralValue();
10689
11024
  }
10690
11025
  }
@@ -10692,16 +11027,16 @@ function writtenSdl(expr) {
10692
11027
  return null;
10693
11028
  }
10694
11029
  function resolverPropertyName(prop) {
10695
- if (import_ts_morph51.Node.isPropertyAssignment(prop) || import_ts_morph51.Node.isMethodDeclaration(prop)) {
11030
+ if (import_ts_morph52.Node.isPropertyAssignment(prop) || import_ts_morph52.Node.isMethodDeclaration(prop)) {
10696
11031
  return prop.getName();
10697
11032
  }
10698
- if (import_ts_morph51.Node.isShorthandPropertyAssignment(prop)) {
11033
+ if (import_ts_morph52.Node.isShorthandPropertyAssignment(prop)) {
10699
11034
  return prop.getName();
10700
11035
  }
10701
11036
  return null;
10702
11037
  }
10703
11038
  function resolverPropertyFunction(prop, resolution) {
10704
- if (import_ts_morph51.Node.isMethodDeclaration(prop)) {
11039
+ if (import_ts_morph52.Node.isMethodDeclaration(prop)) {
10705
11040
  return prop;
10706
11041
  }
10707
11042
  const held = propertyValueOf(prop);
@@ -10962,7 +11297,7 @@ function resolvePrefix(edgesByChild, memo, childId, visiting) {
10962
11297
  }
10963
11298
 
10964
11299
  // src/discoveryContext.ts
10965
- var import_ts_morph52 = require("ts-morph");
11300
+ var import_ts_morph53 = require("ts-morph");
10966
11301
  function createTsDiscoveryContext(resolution) {
10967
11302
  return {
10968
11303
  getFilePath,
@@ -10994,7 +11329,7 @@ function exportedFunctions(sourceFile, resolution) {
10994
11329
  return out;
10995
11330
  }
10996
11331
  function exportedFunction(decl, resolution) {
10997
- const writtenAgain = import_ts_morph52.Node.isVariableDeclaration(decl) && isWrittenAgain(decl);
11332
+ const writtenAgain = import_ts_morph53.Node.isVariableDeclaration(decl) && isWrittenAgain(decl);
10998
11333
  if (!writtenAgain) {
10999
11334
  const declared = resolveDeclarationToFunction(decl);
11000
11335
  if (declared !== null) {
@@ -11015,7 +11350,7 @@ function valueToAskAbout(decl, writtenAgain) {
11015
11350
  if (writtenAgain) {
11016
11351
  return decl;
11017
11352
  }
11018
- const value = import_ts_morph52.Node.isVariableDeclaration(decl) ? decl.getInitializer() ?? decl : decl;
11353
+ const value = import_ts_morph53.Node.isVariableDeclaration(decl) ? decl.getInitializer() ?? decl : decl;
11019
11354
  return couldStillNameAFunction(value) ? value : null;
11020
11355
  }
11021
11356
  function exportedCallConfigString(sourceFile, exportName, spec, resolution) {
@@ -11025,11 +11360,11 @@ function exportedCallConfigString(sourceFile, exportName, spec, resolution) {
11025
11360
  }
11026
11361
  const found = /* @__PURE__ */ new Set();
11027
11362
  for (const decl of declarations) {
11028
- if (!import_ts_morph52.Node.isVariableDeclaration(decl)) {
11363
+ if (!import_ts_morph53.Node.isVariableDeclaration(decl)) {
11029
11364
  continue;
11030
11365
  }
11031
11366
  const init = peelExpression(decl.getInitializer());
11032
- if (init === void 0 || !import_ts_morph52.Node.isCallExpression(init)) {
11367
+ if (init === void 0 || !import_ts_morph53.Node.isCallExpression(init)) {
11033
11368
  continue;
11034
11369
  }
11035
11370
  if (!calleeIsNamed(init.getExpression(), spec.callees)) {
@@ -11048,7 +11383,7 @@ function calleeIsNamed(callee, names) {
11048
11383
  if (names === void 0 || names.length === 0) {
11049
11384
  return true;
11050
11385
  }
11051
- return import_ts_morph52.Node.isIdentifier(callee) && names.includes(callee.getText());
11386
+ return import_ts_morph53.Node.isIdentifier(callee) && names.includes(callee.getText());
11052
11387
  }
11053
11388
  function configArguments(args, argIndex) {
11054
11389
  if (argIndex === void 0) {
@@ -11063,18 +11398,18 @@ function configString(arg, property, resolution) {
11063
11398
  return null;
11064
11399
  }
11065
11400
  const prop = config.getProperty(property);
11066
- if (prop === void 0 || !import_ts_morph52.Node.isPropertyAssignment(prop)) {
11401
+ if (prop === void 0 || !import_ts_morph53.Node.isPropertyAssignment(prop)) {
11067
11402
  return null;
11068
11403
  }
11069
11404
  const value = peelExpression(prop.getInitializer());
11070
- if (value !== void 0 && import_ts_morph52.Node.isStringLiteral(value)) {
11405
+ if (value !== void 0 && import_ts_morph53.Node.isStringLiteral(value)) {
11071
11406
  return value.getLiteralValue();
11072
11407
  }
11073
11408
  return null;
11074
11409
  }
11075
11410
  function peelExpression(node) {
11076
11411
  let current2 = node;
11077
- while (current2 !== void 0 && (import_ts_morph52.Node.isAsExpression(current2) || import_ts_morph52.Node.isSatisfiesExpression(current2) || import_ts_morph52.Node.isParenthesizedExpression(current2) || import_ts_morph52.Node.isNonNullExpression(current2))) {
11412
+ while (current2 !== void 0 && (import_ts_morph53.Node.isAsExpression(current2) || import_ts_morph53.Node.isSatisfiesExpression(current2) || import_ts_morph53.Node.isParenthesizedExpression(current2) || import_ts_morph53.Node.isNonNullExpression(current2))) {
11078
11413
  current2 = current2.getExpression();
11079
11414
  }
11080
11415
  return current2;
@@ -11084,14 +11419,14 @@ function toObjectLiteral(node, resolution) {
11084
11419
  if (peeled === void 0) {
11085
11420
  return null;
11086
11421
  }
11087
- if (import_ts_morph52.Node.isObjectLiteralExpression(peeled)) {
11422
+ if (import_ts_morph53.Node.isObjectLiteralExpression(peeled)) {
11088
11423
  return peeled;
11089
11424
  }
11090
11425
  if (resolution === void 0) {
11091
11426
  return null;
11092
11427
  }
11093
11428
  const resolved = resolution.resolveObject(peeled);
11094
- if (resolved !== null && import_ts_morph52.Node.isObjectLiteralExpression(resolved)) {
11429
+ if (resolved !== null && import_ts_morph53.Node.isObjectLiteralExpression(resolved)) {
11095
11430
  return resolved;
11096
11431
  }
11097
11432
  return null;
@@ -11101,18 +11436,18 @@ function resolveDeclarationToFunction(decl) {
11101
11436
  if (fn !== null) {
11102
11437
  return fn;
11103
11438
  }
11104
- if (import_ts_morph52.Node.isVariableDeclaration(decl)) {
11439
+ if (import_ts_morph53.Node.isVariableDeclaration(decl)) {
11105
11440
  const init = decl.getInitializer();
11106
- if (init !== void 0 && (import_ts_morph52.Node.isArrowFunction(init) || import_ts_morph52.Node.isFunctionExpression(init))) {
11441
+ if (init !== void 0 && (import_ts_morph53.Node.isArrowFunction(init) || import_ts_morph53.Node.isFunctionExpression(init))) {
11107
11442
  return init;
11108
11443
  }
11109
11444
  }
11110
11445
  return null;
11111
11446
  }
11112
11447
  function hasJsxReturn(func) {
11113
- if (import_ts_morph52.Node.isArrowFunction(func)) {
11448
+ if (import_ts_morph53.Node.isArrowFunction(func)) {
11114
11449
  const body2 = func.getBody();
11115
- if (import_ts_morph52.Node.isExpression(body2) && isJsxOrFragment(body2)) {
11450
+ if (import_ts_morph53.Node.isExpression(body2) && isJsxOrFragment(body2)) {
11116
11451
  return true;
11117
11452
  }
11118
11453
  }
@@ -11126,11 +11461,11 @@ function hasJsxReturn(func) {
11126
11461
  traversal.stop();
11127
11462
  return;
11128
11463
  }
11129
- if (node !== func && (import_ts_morph52.Node.isFunctionDeclaration(node) || import_ts_morph52.Node.isFunctionExpression(node) || import_ts_morph52.Node.isArrowFunction(node) || import_ts_morph52.Node.isMethodDeclaration(node))) {
11464
+ if (node !== func && (import_ts_morph53.Node.isFunctionDeclaration(node) || import_ts_morph53.Node.isFunctionExpression(node) || import_ts_morph53.Node.isArrowFunction(node) || import_ts_morph53.Node.isMethodDeclaration(node))) {
11130
11465
  traversal.skip();
11131
11466
  return;
11132
11467
  }
11133
- if (import_ts_morph52.Node.isReturnStatement(node)) {
11468
+ if (import_ts_morph53.Node.isReturnStatement(node)) {
11134
11469
  const expr = node.getExpression();
11135
11470
  if (expr !== void 0 && isJsxOrFragment(expr)) {
11136
11471
  found = true;
@@ -11141,14 +11476,14 @@ function hasJsxReturn(func) {
11141
11476
  }
11142
11477
  function isJsxOrFragment(node) {
11143
11478
  let current2 = node;
11144
- while (import_ts_morph52.Node.isParenthesizedExpression(current2)) {
11479
+ while (import_ts_morph53.Node.isParenthesizedExpression(current2)) {
11145
11480
  current2 = current2.getExpression();
11146
11481
  }
11147
- return import_ts_morph52.Node.isJsxElement(current2) || import_ts_morph52.Node.isJsxSelfClosingElement(current2) || import_ts_morph52.Node.isJsxFragment(current2);
11482
+ return import_ts_morph53.Node.isJsxElement(current2) || import_ts_morph53.Node.isJsxSelfClosingElement(current2) || import_ts_morph53.Node.isJsxFragment(current2);
11148
11483
  }
11149
11484
 
11150
11485
  // src/facts/store.ts
11151
- var import_ts_morph53 = require("ts-morph");
11486
+ var import_ts_morph54 = require("ts-morph");
11152
11487
  var import_datalog2 = require("@suss/datalog");
11153
11488
  var import_resolution = require("@suss/resolution");
11154
11489
  var JS_RULES = [
@@ -11393,7 +11728,7 @@ var ResolutionStore = class {
11393
11728
  * can be rooted anywhere, so the queried value gets its own facts.
11394
11729
  */
11395
11730
  seedValue(value) {
11396
- if (!import_ts_morph53.Node.isExpression(value)) {
11731
+ if (!import_ts_morph54.Node.isExpression(value)) {
11397
11732
  return;
11398
11733
  }
11399
11734
  const id = nodeId(value);
@@ -11423,13 +11758,16 @@ var ResolutionStore = class {
11423
11758
  * Two candidates give null, since ambiguity is nothing. The value
11424
11759
  * itself is never a result either, or an identifier whose chain went
11425
11760
  * nowhere would come back as itself.
11761
+ *
11762
+ * An answer has to be an expression, which leaves out the class a
11763
+ * construction makes an instance of. The README says why.
11426
11764
  */
11427
11765
  lookupWritten(value) {
11428
11766
  this.derive();
11429
11767
  const candidates = /* @__PURE__ */ new Set();
11430
11768
  for (const target of this.answersFor("wantedIsWrittenAs", nodeId(value))) {
11431
11769
  const node = this.table.byId.get(target);
11432
- if (node === void 0 || node === value) {
11770
+ if (node === void 0 || node === value || !import_ts_morph54.Node.isExpression(node)) {
11433
11771
  continue;
11434
11772
  }
11435
11773
  candidates.add(node);
@@ -11520,7 +11858,7 @@ function namesPackage2(moduleKey, packages) {
11520
11858
  );
11521
11859
  }
11522
11860
  function declarationOf2(value) {
11523
- const nameNode = import_ts_morph53.Node.isPropertyAccessExpression(value) ? value.getNameNode() : value;
11861
+ const nameNode = import_ts_morph54.Node.isPropertyAccessExpression(value) ? value.getNameNode() : value;
11524
11862
  return nameNode.getSymbol()?.getDeclarations()[0] ?? value;
11525
11863
  }
11526
11864
 
@@ -11766,14 +12104,14 @@ function deriveBoundaryEffects(summaries, facts) {
11766
12104
  }
11767
12105
  const closureByEntry = /* @__PURE__ */ new Map();
11768
12106
  for (const [entry, kind, target] of db.facts("boundaryEffect")) {
11769
- const entryKey = String(entry);
11770
- const bucket = closureByEntry.get(entryKey) ?? [];
12107
+ const entryKey2 = String(entry);
12108
+ const bucket = closureByEntry.get(entryKey2) ?? [];
11771
12109
  bucket.push({
11772
12110
  kind: String(kind),
11773
12111
  target: String(target),
11774
- transitive: !(ownByEntry.get(entryKey)?.has(`${kind}\0${target}`) ?? false)
12112
+ transitive: !(ownByEntry.get(entryKey2)?.has(`${kind}\0${target}`) ?? false)
11775
12113
  });
11776
- closureByEntry.set(entryKey, bucket);
12114
+ closureByEntry.set(entryKey2, bucket);
11777
12115
  }
11778
12116
  for (const summary of summaries) {
11779
12117
  const key = unitKeyBySummary.get(summary);
@@ -11793,13 +12131,13 @@ function deriveBoundaryEffects(summaries, facts) {
11793
12131
  }
11794
12132
 
11795
12133
  // src/resolve/reachableClosure.ts
11796
- var import_ts_morph55 = require("ts-morph");
11797
- var import_behavioral_ir5 = require("@suss/behavioral-ir");
12134
+ var import_ts_morph56 = require("ts-morph");
12135
+ var import_behavioral_ir6 = require("@suss/behavioral-ir");
11798
12136
  var import_datalog4 = require("@suss/datalog");
11799
12137
  var import_extractor4 = require("@suss/extractor");
11800
12138
 
11801
12139
  // src/resolve/unfollowedCall.ts
11802
- var import_ts_morph54 = require("ts-morph");
12140
+ var import_ts_morph55 = require("ts-morph");
11803
12141
  function isInExternalCode(sourceFile) {
11804
12142
  if (sourceFile.isDeclarationFile()) {
11805
12143
  return true;
@@ -11807,38 +12145,38 @@ function isInExternalCode(sourceFile) {
11807
12145
  return sourceFile.getFilePath().includes("/node_modules/");
11808
12146
  }
11809
12147
  function hasBody(fn) {
11810
- if (import_ts_morph54.Node.isFunctionDeclaration(fn) || import_ts_morph54.Node.isMethodDeclaration(fn) || import_ts_morph54.Node.isFunctionExpression(fn)) {
12148
+ if (import_ts_morph55.Node.isFunctionDeclaration(fn) || import_ts_morph55.Node.isMethodDeclaration(fn) || import_ts_morph55.Node.isFunctionExpression(fn)) {
11811
12149
  return fn.getBody?.() !== void 0;
11812
12150
  }
11813
12151
  return true;
11814
12152
  }
11815
12153
  function isDeclaredShape(declaration) {
11816
- return (import_ts_morph54.Node.isMethodSignature(declaration) || import_ts_morph54.Node.isPropertySignature(declaration)) && !isInExternalCode(declaration.getSourceFile());
12154
+ return (import_ts_morph55.Node.isMethodSignature(declaration) || import_ts_morph55.Node.isPropertySignature(declaration)) && !isInExternalCode(declaration.getSourceFile());
11817
12155
  }
11818
12156
  function isExternalDeclaration(declaration) {
11819
12157
  if (isInExternalCode(declaration.getSourceFile())) {
11820
12158
  return true;
11821
12159
  }
11822
- if (import_ts_morph54.Node.isImportSpecifier(declaration) || import_ts_morph54.Node.isImportClause(declaration) || import_ts_morph54.Node.isNamespaceImport(declaration)) {
11823
- const target = declaration.getFirstAncestorByKind(import_ts_morph54.SyntaxKind.ImportDeclaration)?.getModuleSpecifierSourceFile();
12160
+ if (import_ts_morph55.Node.isImportSpecifier(declaration) || import_ts_morph55.Node.isImportClause(declaration) || import_ts_morph55.Node.isNamespaceImport(declaration)) {
12161
+ const target = declaration.getFirstAncestorByKind(import_ts_morph55.SyntaxKind.ImportDeclaration)?.getModuleSpecifierSourceFile();
11824
12162
  return target === void 0 || isInExternalCode(target);
11825
12163
  }
11826
12164
  return declaresAnotherModule(declaration);
11827
12165
  }
11828
12166
  function declaresAnotherModule(declaration) {
11829
12167
  const module2 = declaration.getFirstAncestorByKind(
11830
- import_ts_morph54.SyntaxKind.ModuleDeclaration
12168
+ import_ts_morph55.SyntaxKind.ModuleDeclaration
11831
12169
  );
11832
- return module2 !== void 0 && import_ts_morph54.Node.isStringLiteral(module2.getNameNode());
12170
+ return module2 !== void 0 && import_ts_morph55.Node.isStringLiteral(module2.getNameNode());
11833
12171
  }
11834
12172
  function statesShapeOnly(declaration) {
11835
12173
  if (isExternalDeclaration(declaration)) {
11836
12174
  return false;
11837
12175
  }
11838
- if (import_ts_morph54.Node.isMethodSignature(declaration) || import_ts_morph54.Node.isPropertySignature(declaration)) {
12176
+ if (import_ts_morph55.Node.isMethodSignature(declaration) || import_ts_morph55.Node.isPropertySignature(declaration)) {
11839
12177
  return true;
11840
12178
  }
11841
- if (import_ts_morph54.Node.isFunctionDeclaration(declaration) || import_ts_morph54.Node.isMethodDeclaration(declaration)) {
12179
+ if (import_ts_morph55.Node.isFunctionDeclaration(declaration) || import_ts_morph55.Node.isMethodDeclaration(declaration)) {
11842
12180
  return declaration.getBody() === void 0;
11843
12181
  }
11844
12182
  return false;
@@ -11928,9 +12266,9 @@ function resolveDecl(decl, calleeName) {
11928
12266
  }
11929
12267
  return { func: fn, name: declName(decl) ?? calleeName };
11930
12268
  }
11931
- if (import_ts_morph55.Node.isVariableDeclaration(decl)) {
12269
+ if (import_ts_morph56.Node.isVariableDeclaration(decl)) {
11932
12270
  const init = decl.getInitializer();
11933
- if (init !== void 0 && (import_ts_morph55.Node.isArrowFunction(init) || import_ts_morph55.Node.isFunctionExpression(init))) {
12271
+ if (init !== void 0 && (import_ts_morph56.Node.isArrowFunction(init) || import_ts_morph56.Node.isFunctionExpression(init))) {
11934
12272
  return { func: init, name: decl.getName() };
11935
12273
  }
11936
12274
  return null;
@@ -11938,26 +12276,26 @@ function resolveDecl(decl, calleeName) {
11938
12276
  return null;
11939
12277
  }
11940
12278
  function declName(decl) {
11941
- if (import_ts_morph55.Node.isFunctionDeclaration(decl) || import_ts_morph55.Node.isMethodDeclaration(decl)) {
12279
+ if (import_ts_morph56.Node.isFunctionDeclaration(decl) || import_ts_morph56.Node.isMethodDeclaration(decl)) {
11942
12280
  const n = decl.getName?.();
11943
12281
  if (typeof n === "string" && n.length > 0) {
11944
12282
  return n;
11945
12283
  }
11946
12284
  }
11947
- if (import_ts_morph55.Node.isFunctionExpression(decl)) {
12285
+ if (import_ts_morph56.Node.isFunctionExpression(decl)) {
11948
12286
  const n = decl.getName();
11949
12287
  if (typeof n === "string" && n.length > 0) {
11950
12288
  return n;
11951
12289
  }
11952
12290
  }
11953
12291
  const parent = decl.getParent();
11954
- if (parent !== void 0 && import_ts_morph55.Node.isVariableDeclaration(parent)) {
12292
+ if (parent !== void 0 && import_ts_morph56.Node.isVariableDeclaration(parent)) {
11955
12293
  return parent.getName();
11956
12294
  }
11957
12295
  return null;
11958
12296
  }
11959
12297
  function resolveCallee(call, calleeName, scan) {
11960
- if (!import_ts_morph55.Node.isCallExpression(call)) {
12298
+ if (!import_ts_morph56.Node.isCallExpression(call)) {
11961
12299
  return null;
11962
12300
  }
11963
12301
  const callee = call.getExpression();
@@ -11970,7 +12308,7 @@ function resolveCallee(call, calleeName, scan) {
11970
12308
  }
11971
12309
  }
11972
12310
  const resolveSources = scan.resolveCallableSources;
11973
- if (resolveSources !== void 0 && import_ts_morph55.Node.isPropertyAccessExpression(callee) && declarations.some(isDeclaredShape)) {
12311
+ if (resolveSources !== void 0 && import_ts_morph56.Node.isPropertyAccessExpression(callee) && declarations.some(isDeclaredShape)) {
11974
12312
  const sources = resolveSources(callee, scan.reachedFrom);
11975
12313
  const only = sources.length === 1 ? sources[0] : void 0;
11976
12314
  const resolved = only === void 0 ? null : resolveDecl(only, calleeName);
@@ -11997,7 +12335,7 @@ function collectReachable(func, scan) {
11997
12335
  const stops = [];
11998
12336
  const seen = /* @__PURE__ */ new Set();
11999
12337
  func.forEachDescendant((node) => {
12000
- if (!import_ts_morph55.Node.isCallExpression(node)) {
12338
+ if (!import_ts_morph56.Node.isCallExpression(node)) {
12001
12339
  return;
12002
12340
  }
12003
12341
  const calleeText = normalizeCallee(node.getExpression().getText());
@@ -12039,7 +12377,7 @@ function extractReachableSummary(candidate, options, recognizers) {
12039
12377
  void 0,
12040
12378
  recognizers.resolveWrittenValue
12041
12379
  );
12042
- raw.boundaryBinding = (0, import_behavioral_ir5.functionCallBinding)({
12380
+ raw.boundaryBinding = (0, import_behavioral_ir6.functionCallBinding)({
12043
12381
  transport: "in-process",
12044
12382
  recognition: "reachable"
12045
12383
  });
@@ -12183,7 +12521,7 @@ function recordStops(stopsByKey, summariesByKey, options) {
12183
12521
  }
12184
12522
 
12185
12523
  // src/resolve/rethrowEnrichment.ts
12186
- var import_ts_morph56 = require("ts-morph");
12524
+ var import_ts_morph57 = require("ts-morph");
12187
12525
  var import_datalog5 = require("@suss/datalog");
12188
12526
  var RETHROW_RULES = [
12189
12527
  (0, import_datalog5.rule)(
@@ -12323,7 +12661,7 @@ function findBareRethrow(func, location) {
12323
12661
  traversal.stop();
12324
12662
  return;
12325
12663
  }
12326
- if (!import_ts_morph56.Node.isThrowStatement(node)) {
12664
+ if (!import_ts_morph57.Node.isThrowStatement(node)) {
12327
12665
  return;
12328
12666
  }
12329
12667
  if (startLineOf(node) !== location.start) {
@@ -12333,7 +12671,7 @@ function findBareRethrow(func, location) {
12333
12671
  return;
12334
12672
  }
12335
12673
  const thrown = node.getExpression();
12336
- if (thrown !== void 0 && import_ts_morph56.Node.isIdentifier(thrown)) {
12674
+ if (thrown !== void 0 && import_ts_morph57.Node.isIdentifier(thrown)) {
12337
12675
  found = node;
12338
12676
  }
12339
12677
  });
@@ -12343,13 +12681,13 @@ function enclosingTry(throwStmt) {
12343
12681
  let current2 = throwStmt.getParent();
12344
12682
  let sawCatchClause = false;
12345
12683
  while (current2 !== void 0) {
12346
- if (import_ts_morph56.Node.isCatchClause(current2)) {
12684
+ if (import_ts_morph57.Node.isCatchClause(current2)) {
12347
12685
  sawCatchClause = true;
12348
12686
  }
12349
- if (import_ts_morph56.Node.isTryStatement(current2)) {
12687
+ if (import_ts_morph57.Node.isTryStatement(current2)) {
12350
12688
  return sawCatchClause ? current2 : null;
12351
12689
  }
12352
- if (import_ts_morph56.Node.isFunctionDeclaration(current2) || import_ts_morph56.Node.isFunctionExpression(current2) || import_ts_morph56.Node.isArrowFunction(current2) || import_ts_morph56.Node.isMethodDeclaration(current2)) {
12690
+ if (import_ts_morph57.Node.isFunctionDeclaration(current2) || import_ts_morph57.Node.isFunctionExpression(current2) || import_ts_morph57.Node.isArrowFunction(current2) || import_ts_morph57.Node.isMethodDeclaration(current2)) {
12353
12691
  return null;
12354
12692
  }
12355
12693
  current2 = current2.getParent();
@@ -12357,14 +12695,14 @@ function enclosingTry(throwStmt) {
12357
12695
  return null;
12358
12696
  }
12359
12697
  function collectTryBodyCallees(tryStmt, index, keyFor) {
12360
- if (!import_ts_morph56.Node.isTryStatement(tryStmt)) {
12698
+ if (!import_ts_morph57.Node.isTryStatement(tryStmt)) {
12361
12699
  return [];
12362
12700
  }
12363
12701
  const tryBlock = tryStmt.getTryBlock();
12364
12702
  const callees = [];
12365
12703
  const seen = /* @__PURE__ */ new Set();
12366
12704
  tryBlock.forEachDescendant((node) => {
12367
- if (!import_ts_morph56.Node.isCallExpression(node)) {
12705
+ if (!import_ts_morph57.Node.isCallExpression(node)) {
12368
12706
  return;
12369
12707
  }
12370
12708
  const calleeSummary = resolveCalleeSummary(node, index);
@@ -12381,7 +12719,7 @@ function collectTryBodyCallees(tryStmt, index, keyFor) {
12381
12719
  return callees;
12382
12720
  }
12383
12721
  function resolveCalleeSummary(call, index) {
12384
- if (!import_ts_morph56.Node.isCallExpression(call)) {
12722
+ if (!import_ts_morph57.Node.isCallExpression(call)) {
12385
12723
  return null;
12386
12724
  }
12387
12725
  const callee = call.getExpression();
@@ -12407,12 +12745,12 @@ function resolveCalleeSummary(call, index) {
12407
12745
  return null;
12408
12746
  }
12409
12747
  function functionFromDecl(decl) {
12410
- if (import_ts_morph56.Node.isFunctionDeclaration(decl) || import_ts_morph56.Node.isFunctionExpression(decl) || import_ts_morph56.Node.isArrowFunction(decl) || import_ts_morph56.Node.isMethodDeclaration(decl)) {
12748
+ if (import_ts_morph57.Node.isFunctionDeclaration(decl) || import_ts_morph57.Node.isFunctionExpression(decl) || import_ts_morph57.Node.isArrowFunction(decl) || import_ts_morph57.Node.isMethodDeclaration(decl)) {
12411
12749
  return decl;
12412
12750
  }
12413
- if (import_ts_morph56.Node.isVariableDeclaration(decl)) {
12751
+ if (import_ts_morph57.Node.isVariableDeclaration(decl)) {
12414
12752
  const init = decl.getInitializer();
12415
- if (init !== void 0 && (import_ts_morph56.Node.isArrowFunction(init) || import_ts_morph56.Node.isFunctionExpression(init))) {
12753
+ if (init !== void 0 && (import_ts_morph57.Node.isArrowFunction(init) || import_ts_morph57.Node.isFunctionExpression(init))) {
12416
12754
  return init;
12417
12755
  }
12418
12756
  }
@@ -12420,22 +12758,22 @@ function functionFromDecl(decl) {
12420
12758
  }
12421
12759
 
12422
12760
  // src/shapes/fieldAccesses.ts
12423
- var import_ts_morph57 = require("ts-morph");
12761
+ var import_ts_morph58 = require("ts-morph");
12424
12762
  function findResponseAccessor(callExpr) {
12425
12763
  let current2 = callExpr;
12426
12764
  const parent1 = current2.getParent();
12427
- if (parent1 !== void 0 && import_ts_morph57.Node.isAwaitExpression(parent1)) {
12765
+ if (parent1 !== void 0 && import_ts_morph58.Node.isAwaitExpression(parent1)) {
12428
12766
  current2 = parent1;
12429
12767
  }
12430
12768
  const parent2 = current2.getParent();
12431
- if (parent2 === void 0 || !import_ts_morph57.Node.isVariableDeclaration(parent2)) {
12769
+ if (parent2 === void 0 || !import_ts_morph58.Node.isVariableDeclaration(parent2)) {
12432
12770
  return null;
12433
12771
  }
12434
12772
  const nameNode = parent2.getNameNode();
12435
- if (import_ts_morph57.Node.isIdentifier(nameNode)) {
12773
+ if (import_ts_morph58.Node.isIdentifier(nameNode)) {
12436
12774
  return { kind: "identifier", name: nameNode.getText() };
12437
12775
  }
12438
- if (import_ts_morph57.Node.isObjectBindingPattern(nameNode)) {
12776
+ if (import_ts_morph58.Node.isObjectBindingPattern(nameNode)) {
12439
12777
  const bindings = /* @__PURE__ */ new Map();
12440
12778
  for (const element of nameNode.getElements()) {
12441
12779
  if (element.getDotDotDotToken() !== void 0) {
@@ -12456,11 +12794,11 @@ function findResponseAccessor(callExpr) {
12456
12794
  function buildThenChainAccessor(callExpr, func) {
12457
12795
  const bindings = /* @__PURE__ */ new Map();
12458
12796
  func.forEachDescendant((node) => {
12459
- if (!import_ts_morph57.Node.isParameterDeclaration(node)) {
12797
+ if (!import_ts_morph58.Node.isParameterDeclaration(node)) {
12460
12798
  return;
12461
12799
  }
12462
12800
  const nameNode = node.getNameNode();
12463
- if (!import_ts_morph57.Node.isIdentifier(nameNode)) {
12801
+ if (!import_ts_morph58.Node.isIdentifier(nameNode)) {
12464
12802
  return;
12465
12803
  }
12466
12804
  const prefix = prefixOfThenParam(node, callExpr, 0);
@@ -12492,7 +12830,7 @@ function prefixOfExpr(expr, responseCall, depth) {
12492
12830
  if (node === responseCall) {
12493
12831
  return [];
12494
12832
  }
12495
- if (import_ts_morph57.Node.isCallExpression(node)) {
12833
+ if (import_ts_morph58.Node.isCallExpression(node)) {
12496
12834
  const hop = thenLikeCall(node);
12497
12835
  if (hop !== null) {
12498
12836
  if (hop.method === "catch") {
@@ -12524,14 +12862,14 @@ function prefixOfMemberExpr(expr, responseCall, depth) {
12524
12862
  return null;
12525
12863
  }
12526
12864
  const decl = chain.root.getSymbol()?.getDeclarations()?.[0];
12527
- if (decl === void 0 || !import_ts_morph57.Node.isParameterDeclaration(decl)) {
12865
+ if (decl === void 0 || !import_ts_morph58.Node.isParameterDeclaration(decl)) {
12528
12866
  return null;
12529
12867
  }
12530
12868
  const base = prefixOfThenParam(decl, responseCall, depth + 1);
12531
12869
  return base === null ? null : [...base, ...chain.segments];
12532
12870
  }
12533
12871
  function firstCallbackParamName(callback) {
12534
- if (callback === void 0 || !(import_ts_morph57.Node.isArrowFunction(callback) || import_ts_morph57.Node.isFunctionExpression(callback))) {
12872
+ if (callback === void 0 || !(import_ts_morph58.Node.isArrowFunction(callback) || import_ts_morph58.Node.isFunctionExpression(callback))) {
12535
12873
  return null;
12536
12874
  }
12537
12875
  const param = callback.getParameters()[0];
@@ -12539,11 +12877,11 @@ function firstCallbackParamName(callback) {
12539
12877
  return null;
12540
12878
  }
12541
12879
  const nameNode = param.getNameNode();
12542
- return import_ts_morph57.Node.isIdentifier(nameNode) ? nameNode.getText() : null;
12880
+ return import_ts_morph58.Node.isIdentifier(nameNode) ? nameNode.getText() : null;
12543
12881
  }
12544
12882
  function unwrap2(expr) {
12545
12883
  let node = expr;
12546
- while (import_ts_morph57.Node.isAwaitExpression(node) || import_ts_morph57.Node.isParenthesizedExpression(node) || import_ts_morph57.Node.isAsExpression(node)) {
12884
+ while (import_ts_morph58.Node.isAwaitExpression(node) || import_ts_morph58.Node.isParenthesizedExpression(node) || import_ts_morph58.Node.isAsExpression(node)) {
12547
12885
  node = node.getExpression();
12548
12886
  }
12549
12887
  return node;
@@ -12553,15 +12891,15 @@ function chainRootedAt(expr, rootName) {
12553
12891
  if (chain === null) {
12554
12892
  return null;
12555
12893
  }
12556
- return import_ts_morph57.Node.isIdentifier(chain.root) && chain.root.getText() === rootName ? chain.segments : null;
12894
+ return import_ts_morph58.Node.isIdentifier(chain.root) && chain.root.getText() === rootName ? chain.segments : null;
12557
12895
  }
12558
12896
  function memberChain(expr) {
12559
- let node = import_ts_morph57.Node.isExpression(expr) ? unwrap2(expr) : expr;
12560
- if (import_ts_morph57.Node.isCallExpression(node)) {
12897
+ let node = import_ts_morph58.Node.isExpression(expr) ? unwrap2(expr) : expr;
12898
+ if (import_ts_morph58.Node.isCallExpression(node)) {
12561
12899
  node = node.getExpression();
12562
12900
  }
12563
12901
  const segments = [];
12564
- while (import_ts_morph57.Node.isPropertyAccessExpression(node)) {
12902
+ while (import_ts_morph58.Node.isPropertyAccessExpression(node)) {
12565
12903
  segments.unshift(node.getName());
12566
12904
  node = node.getExpression();
12567
12905
  }
@@ -12580,16 +12918,16 @@ function collectPropertyAccesses(subtree, accessor) {
12580
12918
  if (accessor.kind === "identifier") {
12581
12919
  const varName = accessor.name;
12582
12920
  subtree.forEachDescendant((node) => {
12583
- if (!import_ts_morph57.Node.isPropertyAccessExpression(node)) {
12921
+ if (!import_ts_morph58.Node.isPropertyAccessExpression(node)) {
12584
12922
  return;
12585
12923
  }
12586
12924
  const chain = [];
12587
12925
  let current2 = node;
12588
- while (import_ts_morph57.Node.isPropertyAccessExpression(current2)) {
12926
+ while (import_ts_morph58.Node.isPropertyAccessExpression(current2)) {
12589
12927
  chain.unshift(current2.getName());
12590
12928
  current2 = current2.getExpression();
12591
12929
  }
12592
- if (import_ts_morph57.Node.isIdentifier(current2) && current2.getText() === varName) {
12930
+ if (import_ts_morph58.Node.isIdentifier(current2) && current2.getText() === varName) {
12593
12931
  pushChain(chain);
12594
12932
  }
12595
12933
  });
@@ -12600,7 +12938,7 @@ function collectPropertyAccesses(subtree, accessor) {
12600
12938
  return source === void 0 ? void 0 : [source];
12601
12939
  } : (name) => accessor.bindings.get(name);
12602
12940
  subtree.forEachDescendant((node) => {
12603
- if (!import_ts_morph57.Node.isIdentifier(node)) {
12941
+ if (!import_ts_morph58.Node.isIdentifier(node)) {
12604
12942
  return;
12605
12943
  }
12606
12944
  const prefix = prefixOf(node.getText());
@@ -12612,13 +12950,13 @@ function collectPropertyAccesses(subtree, accessor) {
12612
12950
  }
12613
12951
  let chainTop = node;
12614
12952
  let parent = chainTop.getParent();
12615
- while (parent !== void 0 && import_ts_morph57.Node.isPropertyAccessExpression(parent) && parent.getExpression() === chainTop) {
12953
+ while (parent !== void 0 && import_ts_morph58.Node.isPropertyAccessExpression(parent) && parent.getExpression() === chainTop) {
12616
12954
  chainTop = parent;
12617
12955
  parent = chainTop.getParent();
12618
12956
  }
12619
12957
  const segments = [];
12620
12958
  let current2 = chainTop;
12621
- while (import_ts_morph57.Node.isPropertyAccessExpression(current2)) {
12959
+ while (import_ts_morph58.Node.isPropertyAccessExpression(current2)) {
12622
12960
  segments.push(current2.getName());
12623
12961
  current2 = current2.getExpression();
12624
12962
  }
@@ -12632,15 +12970,15 @@ function isBindingDeclarationSite(node) {
12632
12970
  return true;
12633
12971
  }
12634
12972
  const parent = node.getParent();
12635
- return parent !== void 0 && import_ts_morph57.Node.isParameterDeclaration(parent) && parent.getNameNode() === node;
12973
+ return parent !== void 0 && import_ts_morph58.Node.isParameterDeclaration(parent) && parent.getNameNode() === node;
12636
12974
  }
12637
12975
  function isInsideObjectBindingPattern(node) {
12638
12976
  let current2 = node.getParent();
12639
12977
  while (current2 !== void 0) {
12640
- if (import_ts_morph57.Node.isObjectBindingPattern(current2)) {
12978
+ if (import_ts_morph58.Node.isObjectBindingPattern(current2)) {
12641
12979
  return true;
12642
12980
  }
12643
- if (import_ts_morph57.Node.isFunctionLikeDeclaration(current2) || import_ts_morph57.Node.isVariableStatement(current2)) {
12981
+ if (import_ts_morph58.Node.isFunctionLikeDeclaration(current2) || import_ts_morph58.Node.isVariableStatement(current2)) {
12644
12982
  break;
12645
12983
  }
12646
12984
  current2 = current2.getParent();
@@ -12703,7 +13041,7 @@ function findBranchSubtree(func, byLineRange, terminalStartLine, terminalEndLine
12703
13041
  if (parent === void 0) {
12704
13042
  break;
12705
13043
  }
12706
- if (import_ts_morph57.Node.isIfStatement(parent)) {
13044
+ if (import_ts_morph58.Node.isIfStatement(parent)) {
12707
13045
  const ifStmt = parent;
12708
13046
  const thenBlock = ifStmt.getThenStatement();
12709
13047
  const elseBlock = ifStmt.getElseStatement();
@@ -12765,7 +13103,7 @@ function buildNonBodyPropertySet(semantics) {
12765
13103
  }
12766
13104
 
12767
13105
  // src/subUnitContext.ts
12768
- var import_ts_morph58 = require("ts-morph");
13106
+ var import_ts_morph59 = require("ts-morph");
12769
13107
  function createTsSubUnitContext() {
12770
13108
  return {
12771
13109
  findJsxAttributes,
@@ -12778,7 +13116,7 @@ function createTsSubUnitContext() {
12778
13116
  }
12779
13117
  function skipNestedFunctions(parent) {
12780
13118
  return (node, traversal) => {
12781
- if (node !== parent && (import_ts_morph58.Node.isFunctionDeclaration(node) || import_ts_morph58.Node.isFunctionExpression(node) || import_ts_morph58.Node.isArrowFunction(node) || import_ts_morph58.Node.isMethodDeclaration(node))) {
13119
+ if (node !== parent && (import_ts_morph59.Node.isFunctionDeclaration(node) || import_ts_morph59.Node.isFunctionExpression(node) || import_ts_morph59.Node.isArrowFunction(node) || import_ts_morph59.Node.isMethodDeclaration(node))) {
12782
13120
  traversal.skip();
12783
13121
  return true;
12784
13122
  }
@@ -12792,18 +13130,18 @@ function findJsxAttributes(parent) {
12792
13130
  if (skip(node, traversal)) {
12793
13131
  return;
12794
13132
  }
12795
- if (!import_ts_morph58.Node.isJsxOpeningElement(node) && !import_ts_morph58.Node.isJsxSelfClosingElement(node)) {
13133
+ if (!import_ts_morph59.Node.isJsxOpeningElement(node) && !import_ts_morph59.Node.isJsxSelfClosingElement(node)) {
12796
13134
  return;
12797
13135
  }
12798
13136
  const tag = node.getTagNameNode().getText();
12799
13137
  for (const attr of node.getAttributes()) {
12800
- if (!import_ts_morph58.Node.isJsxAttribute(attr)) {
13138
+ if (!import_ts_morph59.Node.isJsxAttribute(attr)) {
12801
13139
  continue;
12802
13140
  }
12803
13141
  const initializer = attr.getInitializer();
12804
13142
  let valueExpression = null;
12805
13143
  if (initializer !== void 0) {
12806
- if (import_ts_morph58.Node.isJsxExpression(initializer)) {
13144
+ if (import_ts_morph59.Node.isJsxExpression(initializer)) {
12807
13145
  const inner = initializer.getExpression();
12808
13146
  valueExpression = inner ?? null;
12809
13147
  } else {
@@ -12826,11 +13164,11 @@ function findCallExpressionsByName(parent, name) {
12826
13164
  if (skip(node, traversal)) {
12827
13165
  return;
12828
13166
  }
12829
- if (!import_ts_morph58.Node.isCallExpression(node)) {
13167
+ if (!import_ts_morph59.Node.isCallExpression(node)) {
12830
13168
  return;
12831
13169
  }
12832
13170
  const callee = node.getExpression();
12833
- if (import_ts_morph58.Node.isIdentifier(callee) && callee.getText() === name) {
13171
+ if (import_ts_morph59.Node.isIdentifier(callee) && callee.getText() === name) {
12834
13172
  out.push(node);
12835
13173
  }
12836
13174
  });
@@ -12841,10 +13179,10 @@ function resolveAttributeValueFunction(attr, parent) {
12841
13179
  if (expr === null) {
12842
13180
  return null;
12843
13181
  }
12844
- if (import_ts_morph58.Node.isArrowFunction(expr) || import_ts_morph58.Node.isFunctionExpression(expr)) {
13182
+ if (import_ts_morph59.Node.isArrowFunction(expr) || import_ts_morph59.Node.isFunctionExpression(expr)) {
12845
13183
  return { func: expr, localName: null };
12846
13184
  }
12847
- if (import_ts_morph58.Node.isIdentifier(expr)) {
13185
+ if (import_ts_morph59.Node.isIdentifier(expr)) {
12848
13186
  const symbol = expr.getSymbol();
12849
13187
  if (symbol === void 0) {
12850
13188
  return null;
@@ -12863,15 +13201,15 @@ function resolveAttributeValueFunction(attr, parent) {
12863
13201
  return null;
12864
13202
  }
12865
13203
  function tryExtractFunction(decl) {
12866
- if (import_ts_morph58.Node.isFunctionDeclaration(decl)) {
13204
+ if (import_ts_morph59.Node.isFunctionDeclaration(decl)) {
12867
13205
  return decl;
12868
13206
  }
12869
- if (import_ts_morph58.Node.isVariableDeclaration(decl)) {
13207
+ if (import_ts_morph59.Node.isVariableDeclaration(decl)) {
12870
13208
  const init = decl.getInitializer();
12871
13209
  if (init === void 0) {
12872
13210
  return null;
12873
13211
  }
12874
- if (import_ts_morph58.Node.isArrowFunction(init) || import_ts_morph58.Node.isFunctionExpression(init)) {
13212
+ if (import_ts_morph59.Node.isArrowFunction(init) || import_ts_morph59.Node.isFunctionExpression(init)) {
12875
13213
  return init;
12876
13214
  }
12877
13215
  }
@@ -12892,7 +13230,7 @@ function getCallArgumentFunction(call, position) {
12892
13230
  if (arg === void 0) {
12893
13231
  return null;
12894
13232
  }
12895
- if (import_ts_morph58.Node.isArrowFunction(arg) || import_ts_morph58.Node.isFunctionExpression(arg)) {
13233
+ if (import_ts_morph59.Node.isArrowFunction(arg) || import_ts_morph59.Node.isFunctionExpression(arg)) {
12896
13234
  return arg;
12897
13235
  }
12898
13236
  return null;
@@ -12904,7 +13242,7 @@ function readArrayLiteralText(node) {
12904
13242
  if (node === null) {
12905
13243
  return null;
12906
13244
  }
12907
- if (import_ts_morph58.Node.isArrayLiteralExpression(node)) {
13245
+ if (import_ts_morph59.Node.isArrayLiteralExpression(node)) {
12908
13246
  return node.getElements().map((e) => e.getText());
12909
13247
  }
12910
13248
  return [node.getText()];
@@ -12913,7 +13251,7 @@ function readArrayLiteralText(node) {
12913
13251
  // src/summaryIdentity.ts
12914
13252
  var import_node_fs4 = __toESM(require("fs"), 1);
12915
13253
  var import_node_path7 = __toESM(require("path"), 1);
12916
- var import_behavioral_ir6 = require("@suss/behavioral-ir");
13254
+ var import_behavioral_ir7 = require("@suss/behavioral-ir");
12917
13255
  function workspaceRootFor(anchor) {
12918
13256
  return namedPackageDirAbove(anchor) ?? import_node_path7.default.resolve(anchor);
12919
13257
  }
@@ -12962,7 +13300,7 @@ function nameSummaries(summaries, args) {
12962
13300
  }
12963
13301
  summary.identity.id = idFor(args.workspace, file, summary);
12964
13302
  }
12965
- (0, import_behavioral_ir6.disambiguateSummaryIds)(summaries);
13303
+ (0, import_behavioral_ir7.disambiguateSummaryIds)(summaries);
12966
13304
  nameWhatEachCallReaches(summaries);
12967
13305
  }
12968
13306
  function relativeFile(file, projectRoot) {
@@ -12973,7 +13311,7 @@ function relativeFile(file, projectRoot) {
12973
13311
  return relative.startsWith("..") ? file : relative;
12974
13312
  }
12975
13313
  function idFor(workspace, file, summary) {
12976
- return (0, import_behavioral_ir6.summaryIdFromParts)({
13314
+ return (0, import_behavioral_ir7.summaryIdFromParts)({
12977
13315
  workspace: workspace ?? void 0,
12978
13316
  file,
12979
13317
  name: summary.identity.name,
@@ -13143,13 +13481,13 @@ var raise = (msg) => {
13143
13481
  throw new Error(msg);
13144
13482
  };
13145
13483
  function bindingPatternNames(nameNode) {
13146
- if (import_ts_morph59.Node.isObjectBindingPattern(nameNode)) {
13484
+ if (import_ts_morph60.Node.isObjectBindingPattern(nameNode)) {
13147
13485
  return nameNode.getElements().map((e) => e.getName());
13148
13486
  }
13149
- if (import_ts_morph59.Node.isArrayBindingPattern(nameNode)) {
13487
+ if (import_ts_morph60.Node.isArrayBindingPattern(nameNode)) {
13150
13488
  const names = [];
13151
13489
  for (const element of nameNode.getElements()) {
13152
- if (import_ts_morph59.Node.isOmittedExpression(element)) {
13490
+ if (import_ts_morph60.Node.isOmittedExpression(element)) {
13153
13491
  continue;
13154
13492
  }
13155
13493
  names.push(element.getName());
@@ -13158,9 +13496,28 @@ function bindingPatternNames(nameNode) {
13158
13496
  }
13159
13497
  return null;
13160
13498
  }
13499
+ function objectParamInputs(param, position, mapping) {
13500
+ const boundNames = bindingPatternNames(param.getNameNode());
13501
+ if (boundNames === null) {
13502
+ return [
13503
+ {
13504
+ name: param.getName(),
13505
+ position,
13506
+ role: mapping.wholeParamRole ?? "request",
13507
+ typeText: null
13508
+ }
13509
+ ];
13510
+ }
13511
+ return boundNames.map((name) => ({
13512
+ name,
13513
+ position,
13514
+ role: mapping.knownProperties[name] ?? name,
13515
+ typeText: null
13516
+ }));
13517
+ }
13161
13518
  function componentPropsParameters(param, mapping) {
13162
13519
  const nameNode = param.getNameNode();
13163
- if (!import_ts_morph59.Node.isObjectBindingPattern(nameNode)) {
13520
+ if (!import_ts_morph60.Node.isObjectBindingPattern(nameNode)) {
13164
13521
  const type = param.getType();
13165
13522
  return [
13166
13523
  {
@@ -13198,34 +13555,11 @@ function extractParameters(func, inputMapping) {
13198
13555
  typeText: null
13199
13556
  });
13200
13557
  }
13201
- } else if (inputMapping.type === "singleObjectParam") {
13202
- const param = params[inputMapping.paramPosition];
13558
+ } else if (inputMapping.type === "objectParam") {
13559
+ const position = inputMapping.paramPosition ?? 0;
13560
+ const param = params[position];
13203
13561
  if (param !== void 0) {
13204
- result.push({
13205
- name: param.getName(),
13206
- position: inputMapping.paramPosition,
13207
- role: "request",
13208
- typeText: null
13209
- });
13210
- }
13211
- } else if (inputMapping.type === "destructuredObject") {
13212
- const param = params[0];
13213
- if (param !== void 0) {
13214
- const nameNode = param.getNameNode();
13215
- const boundNames = bindingPatternNames(nameNode);
13216
- if (boundNames !== null) {
13217
- for (const name of boundNames) {
13218
- const role = inputMapping.knownProperties[name] ?? name;
13219
- result.push({ name, position: 0, role, typeText: null });
13220
- }
13221
- } else {
13222
- result.push({
13223
- name: param.getName(),
13224
- position: 0,
13225
- role: "request",
13226
- typeText: null
13227
- });
13228
- }
13562
+ result.push(...objectParamInputs(param, position, inputMapping));
13229
13563
  }
13230
13564
  } else if (inputMapping.type === "allPositional") {
13231
13565
  for (let i = 0; i < params.length; i++) {
@@ -13286,11 +13620,11 @@ function extractParameters(func, inputMapping) {
13286
13620
  function extractDependencyCalls(func) {
13287
13621
  const results = [];
13288
13622
  func.forEachDescendant((node, traversal) => {
13289
- if (node !== func && (import_ts_morph59.Node.isFunctionDeclaration(node) || import_ts_morph59.Node.isFunctionExpression(node) || import_ts_morph59.Node.isArrowFunction(node) || import_ts_morph59.Node.isMethodDeclaration(node))) {
13623
+ if (node !== func && (import_ts_morph60.Node.isFunctionDeclaration(node) || import_ts_morph60.Node.isFunctionExpression(node) || import_ts_morph60.Node.isArrowFunction(node) || import_ts_morph60.Node.isMethodDeclaration(node))) {
13290
13624
  traversal.skip();
13291
13625
  return;
13292
13626
  }
13293
- if (!import_ts_morph59.Node.isVariableDeclaration(node)) {
13627
+ if (!import_ts_morph60.Node.isVariableDeclaration(node)) {
13294
13628
  return;
13295
13629
  }
13296
13630
  const init = node.getInitializer();
@@ -13299,19 +13633,19 @@ function extractDependencyCalls(func) {
13299
13633
  }
13300
13634
  let isAsync = false;
13301
13635
  let callExpr = init;
13302
- if (import_ts_morph59.Node.isAwaitExpression(init)) {
13636
+ if (import_ts_morph60.Node.isAwaitExpression(init)) {
13303
13637
  isAsync = true;
13304
13638
  callExpr = init.getExpression();
13305
13639
  }
13306
- if (!import_ts_morph59.Node.isCallExpression(callExpr)) {
13640
+ if (!import_ts_morph60.Node.isCallExpression(callExpr)) {
13307
13641
  return;
13308
13642
  }
13309
13643
  const calleeName = callExpr.getExpression().getText();
13310
13644
  const nameNode = node.getNameNode();
13311
- const assignedTo = import_ts_morph59.Node.isIdentifier(nameNode) ? nameNode.getText() : null;
13645
+ const assignedTo = import_ts_morph60.Node.isIdentifier(nameNode) ? nameNode.getText() : null;
13312
13646
  const declList = node.getParent();
13313
13647
  const varStmt = declList?.getParent();
13314
- const locationNode = varStmt !== void 0 && import_ts_morph59.Node.isVariableStatement(varStmt) ? varStmt : node;
13648
+ const locationNode = varStmt !== void 0 && import_ts_morph60.Node.isVariableStatement(varStmt) ? varStmt : node;
13315
13649
  results.push({
13316
13650
  name: calleeName,
13317
13651
  assignedTo,
@@ -13553,7 +13887,7 @@ function extractConsumerBinding(unit, pattern, pack, resolution) {
13553
13887
  }
13554
13888
  const method = extractBindingMethod(binding, callSite, pack, resolution);
13555
13889
  const path12 = extractBindingPath(binding, callSite, pack, resolution);
13556
- return (0, import_behavioral_ir7.restBinding)({
13890
+ return (0, import_behavioral_ir8.restBinding)({
13557
13891
  transport: pack.protocol,
13558
13892
  method: method ?? null,
13559
13893
  path: path12 ?? null,
@@ -13572,7 +13906,7 @@ function fileRouteBinding(filePath, unit, binding, pack) {
13572
13906
  if (method === void 0) {
13573
13907
  return null;
13574
13908
  }
13575
- return (0, import_behavioral_ir7.restBinding)({
13909
+ return (0, import_behavioral_ir8.restBinding)({
13576
13910
  transport: pack.protocol,
13577
13911
  recognition: pack.name,
13578
13912
  method,
@@ -13596,9 +13930,9 @@ function extractBindingMethod(binding, callSite, pack, resolution) {
13596
13930
  if (m.type === "fromArgumentProperty") {
13597
13931
  const args = callSite.callExpression.getArguments();
13598
13932
  const arg = args[m.position];
13599
- if (arg !== void 0 && import_ts_morph59.Node.isObjectLiteralExpression(arg)) {
13933
+ if (arg !== void 0 && import_ts_morph60.Node.isObjectLiteralExpression(arg)) {
13600
13934
  const prop = arg.getProperty(m.property);
13601
- if (prop !== void 0 && import_ts_morph59.Node.isPropertyAssignment(prop)) {
13935
+ if (prop !== void 0 && import_ts_morph60.Node.isPropertyAssignment(prop)) {
13602
13936
  const init = prop.getInitializer();
13603
13937
  if (init !== void 0) {
13604
13938
  const value = stringValueOf(init, resolution);
@@ -13615,138 +13949,17 @@ function extractBindingMethod(binding, callSite, pack, resolution) {
13615
13949
  }
13616
13950
  return void 0;
13617
13951
  }
13618
- var URL_SCHEME = /^[a-zA-Z][a-zA-Z\d+.-]*:\/\//;
13619
- var URL_ORIGIN = /^[a-zA-Z][a-zA-Z\d+.-]*:\/\/[^/]*/;
13620
- var PROTOCOL_RELATIVE = /^\/\//;
13621
- var PROTOCOL_RELATIVE_ORIGIN = /^\/\/[^/]*/;
13622
- function isAbsoluteUrlLiteral(text) {
13623
- return URL_SCHEME.test(text) || PROTOCOL_RELATIVE.test(text);
13624
- }
13625
- function stripOriginManually(text) {
13626
- if (URL_SCHEME.test(text)) {
13627
- return text.replace(URL_ORIGIN, "");
13628
- }
13629
- if (PROTOCOL_RELATIVE.test(text)) {
13630
- return text.replace(PROTOCOL_RELATIVE_ORIGIN, "");
13631
- }
13632
- return text;
13633
- }
13634
- function stripQueryAndFragment(text) {
13635
- const idx = text.search(/[?#]/);
13636
- return idx === -1 ? text : text.slice(0, idx);
13637
- }
13638
- var SUBSTITUTION = "\uFFFF";
13639
- var AUTHORITY_OPENER = /^(?:[-+.\uFFFFa-zA-Z0-9]+:\/\/|\/\/)/;
13640
- function originEndOf(flattened) {
13641
- const opener = AUTHORITY_OPENER.exec(flattened);
13642
- if (opener === null) {
13643
- return 0;
13644
- }
13645
- const slash = flattened.indexOf("/", opener[0].length);
13646
- return slash === -1 ? flattened.length : slash;
13647
- }
13648
- function appendPathText(path12, text) {
13649
- const idx = text.search(/[?#]/);
13650
- if (idx === -1) {
13651
- return { path: path12 + text, stop: false };
13652
- }
13653
- return { path: path12 + text.slice(0, idx), stop: true };
13654
- }
13655
- function parseAbsoluteUrl(text) {
13656
- try {
13657
- return new URL(text);
13658
- } catch {
13659
- }
13660
- if (!PROTOCOL_RELATIVE.test(text)) {
13661
- return void 0;
13662
- }
13663
- try {
13664
- return new URL(`https:${text}`);
13665
- } catch {
13666
- return void 0;
13667
- }
13668
- }
13669
- function pathnameOfAbsoluteLiteral(text) {
13670
- const parsed = parseAbsoluteUrl(text);
13671
- if (parsed !== void 0) {
13672
- return parsed.pathname;
13673
- }
13674
- return stripQueryAndFragment(stripOriginManually(text));
13675
- }
13676
- function pathFromLiteralUrl(text) {
13677
- const path12 = isAbsoluteUrlLiteral(text) ? pathnameOfAbsoluteLiteral(text) : stripQueryAndFragment(text);
13678
- return path12 === "" ? void 0 : path12;
13679
- }
13680
- function pathFromTemplateUrl(arg) {
13681
- const headText = arg.getHead().getLiteralText();
13682
- const spans = arg.getTemplateSpans();
13683
- const tails = spans.map((span) => span.getLiteral().getLiteralText());
13684
- const originEnd = originEndOf([headText, ...tails].join(SUBSTITUTION));
13685
- const head = appendPathText("", headText.slice(originEnd));
13686
- let path12 = head.path;
13687
- let stop = head.stop;
13688
- let at = headText.length;
13689
- for (let i = 0; i < spans.length && !stop; i++) {
13690
- const span = spans[i];
13691
- const tailText = tails[i];
13692
- if (span === void 0 || tailText === void 0) {
13693
- continue;
13694
- }
13695
- if (at >= originEnd) {
13696
- path12 += `{${placeholderName(span.getExpression())}}`;
13697
- }
13698
- at += SUBSTITUTION.length;
13699
- const appended = appendPathText(
13700
- path12,
13701
- tailText.slice(Math.max(0, originEnd - at))
13702
- );
13703
- path12 = appended.path;
13704
- stop = appended.stop;
13705
- at += tailText.length;
13706
- }
13707
- return path12 === "" ? void 0 : path12;
13708
- }
13709
13952
  function extractBindingPath(binding, callSite, pack, resolution) {
13710
13953
  const p = binding.path;
13711
13954
  if (p.type === "fromClientMethod") {
13712
13955
  return resolveContractField(callSite, pack, "path");
13713
13956
  }
13714
- if (p.type === "fromArgumentLiteral") {
13715
- const args = callSite.callExpression.getArguments();
13716
- const arg = args[p.position];
13717
- if (arg === void 0) {
13718
- return void 0;
13719
- }
13720
- const written = pathFromUrlNode(arg);
13721
- if (written !== void 0) {
13722
- return written;
13723
- }
13724
- const resolved = resolution?.resolveWrittenValue(arg) ?? null;
13725
- return resolved !== null ? pathFromUrlNode(resolved) : void 0;
13726
- }
13727
- return void 0;
13728
- }
13729
- function pathFromUrlNode(node) {
13730
- if (import_ts_morph59.Node.isStringLiteral(node)) {
13731
- return pathFromLiteralUrl(node.getLiteralValue());
13732
- }
13733
- if (import_ts_morph59.Node.isNoSubstitutionTemplateLiteral(node)) {
13734
- return pathFromLiteralUrl(node.getLiteralValue());
13735
- }
13736
- if (import_ts_morph59.Node.isTemplateExpression(node)) {
13737
- return pathFromTemplateUrl(node);
13957
+ if (p.type === "fromArgument") {
13958
+ const arg = callSite.callExpression.getArguments()[p.position];
13959
+ return arg === void 0 ? void 0 : pathFromArgument(arg, resolution);
13738
13960
  }
13739
13961
  return void 0;
13740
13962
  }
13741
- function placeholderName(expr) {
13742
- if (import_ts_morph59.Node.isIdentifier(expr)) {
13743
- return expr.getText();
13744
- }
13745
- if (import_ts_morph59.Node.isPropertyAccessExpression(expr)) {
13746
- return expr.getName();
13747
- }
13748
- return "param";
13749
- }
13750
13963
  function resolveContractField(callSite, pack, field) {
13751
13964
  if (pack.contractReading === void 0 || callSite.methodName === null) {
13752
13965
  return void 0;
@@ -13934,7 +14147,7 @@ function extractFromSourceFile(sourceFile, frameworks, claimedUnits, options, ta
13934
14147
  }
13935
14148
  const matchedPattern = unit.pattern ?? pack.discovery.find((d) => d.kind === unit.kind);
13936
14149
  if (unit.resolverInfo !== void 0) {
13937
- raw.boundaryBinding = (0, import_behavioral_ir7.graphqlResolverBinding)({
14150
+ raw.boundaryBinding = (0, import_behavioral_ir8.graphqlResolverBinding)({
13938
14151
  transport: pack.protocol,
13939
14152
  recognition: pack.name,
13940
14153
  typeName: unit.resolverInfo.typeName,
@@ -13961,20 +14174,20 @@ function extractFromSourceFile(sourceFile, frameworks, claimedUnits, options, ta
13961
14174
  }
13962
14175
  }
13963
14176
  } else if (unit.routeInfo !== void 0) {
13964
- raw.boundaryBinding = (0, import_behavioral_ir7.restBinding)({
14177
+ raw.boundaryBinding = (0, import_behavioral_ir8.restBinding)({
13965
14178
  transport: pack.protocol,
13966
14179
  recognition: pack.name,
13967
14180
  method: unit.routeInfo.method,
13968
14181
  path: unit.routeInfo.path
13969
14182
  });
13970
14183
  } else if (unit.channelInfo !== void 0) {
13971
- raw.boundaryBinding = (0, import_behavioral_ir7.messageBusBinding)({
14184
+ raw.boundaryBinding = (0, import_behavioral_ir8.messageBusBinding)({
13972
14185
  recognition: pack.name,
13973
14186
  messageBus: unit.channelInfo.messageBus,
13974
14187
  channel: unit.channelInfo.channel
13975
14188
  });
13976
14189
  } else if (unit.operationInfo !== void 0) {
13977
- raw.boundaryBinding = (0, import_behavioral_ir7.graphqlOperationBinding)({
14190
+ raw.boundaryBinding = (0, import_behavioral_ir8.graphqlOperationBinding)({
13978
14191
  transport: pack.protocol,
13979
14192
  recognition: pack.name,
13980
14193
  operationType: unit.operationInfo.operationType,
@@ -14053,14 +14266,14 @@ function extractFromSourceFile(sourceFile, frameworks, claimedUnits, options, ta
14053
14266
  }
14054
14267
  if (raw.boundaryBinding === null) {
14055
14268
  if (unit.packageExportInfo !== void 0) {
14056
- raw.boundaryBinding = (0, import_behavioral_ir7.packageExportBinding)({
14269
+ raw.boundaryBinding = (0, import_behavioral_ir8.packageExportBinding)({
14057
14270
  transport: pack.protocol,
14058
14271
  recognition: pack.name,
14059
14272
  packageName: unit.packageExportInfo.packageName,
14060
14273
  exportPath: unit.packageExportInfo.exportPath
14061
14274
  });
14062
14275
  } else {
14063
- raw.boundaryBinding = (0, import_behavioral_ir7.functionCallBinding)({
14276
+ raw.boundaryBinding = (0, import_behavioral_ir8.functionCallBinding)({
14064
14277
  transport: pack.protocol,
14065
14278
  recognition: pack.name
14066
14279
  });
@@ -14142,14 +14355,14 @@ function fileImporting(project, modulePrefix) {
14142
14355
  function liftSchemasOntoDocuments(summaries) {
14143
14356
  const sdlByDocument = /* @__PURE__ */ new Map();
14144
14357
  for (const summary of summaries) {
14145
- const label = (0, import_behavioral_ir7.readSourceDocumentMetadata)(summary)?.label;
14146
- const graphql = (0, import_behavioral_ir7.readGraphqlMetadata)(summary);
14358
+ const label = (0, import_behavioral_ir8.readSourceDocumentMetadata)(summary)?.label;
14359
+ const graphql = (0, import_behavioral_ir8.readGraphqlMetadata)(summary);
14147
14360
  if (label === void 0 || graphql?.schemaSdl === void 0) {
14148
14361
  continue;
14149
14362
  }
14150
14363
  sdlByDocument.set(label, graphql.schemaSdl);
14151
14364
  const { schemaSdl: _movedToTheDocument, ...rest } = graphql;
14152
- summary.metadata = (0, import_behavioral_ir7.withGraphqlMetadata)(summary.metadata, rest);
14365
+ summary.metadata = (0, import_behavioral_ir8.withGraphqlMetadata)(summary.metadata, rest);
14153
14366
  }
14154
14367
  for (const [label, schemaSdl] of sdlByDocument) {
14155
14368
  summaries.push(schemaDocumentSummary(label, schemaSdl));
@@ -14164,8 +14377,8 @@ function schemaDocumentSummary(label, schemaSdl) {
14164
14377
  transitions: [],
14165
14378
  gaps: [],
14166
14379
  confidence: { source: "declared", level: "high" },
14167
- metadata: (0, import_behavioral_ir7.withGraphqlMetadata)(
14168
- (0, import_behavioral_ir7.withSourceDocumentMetadata)(void 0, { label }),
14380
+ metadata: (0, import_behavioral_ir8.withGraphqlMetadata)(
14381
+ (0, import_behavioral_ir8.withSourceDocumentMetadata)(void 0, { label }),
14169
14382
  { schemaSdl }
14170
14383
  )
14171
14384
  };
@@ -14177,7 +14390,7 @@ function libraryEnvReadMarker(pack, declared, importer) {
14177
14390
  identity: {
14178
14391
  name: `${declared.module} env reads`,
14179
14392
  exportPath: null,
14180
- boundaryBinding: (0, import_behavioral_ir7.functionCallBinding)({
14393
+ boundaryBinding: (0, import_behavioral_ir8.functionCallBinding)({
14181
14394
  transport: "in-process",
14182
14395
  recognition: pack.name
14183
14396
  })
@@ -14214,7 +14427,7 @@ function internalImportsOf(project, file) {
14214
14427
  }
14215
14428
  return [...targets].sort();
14216
14429
  }
14217
- function expandWrapperCallers(summaries, project, options) {
14430
+ function expandWrapperCallers(summaries, project, options, resolution) {
14218
14431
  const wrappers = [];
14219
14432
  let lookup = null;
14220
14433
  for (const s of summaries) {
@@ -14241,7 +14454,9 @@ function expandWrapperCallers(summaries, project, options) {
14241
14454
  }
14242
14455
  const derived = [];
14243
14456
  for (const wrapper of wrappers) {
14244
- derived.push(...synthesizeCallerSummaries(wrapper, project, options));
14457
+ derived.push(
14458
+ ...synthesizeCallerSummaries(wrapper, project, options, resolution)
14459
+ );
14245
14460
  }
14246
14461
  return [...summaries, ...derived];
14247
14462
  }
@@ -14254,9 +14469,9 @@ function findWrapperPathParam(summary, lookup) {
14254
14469
  if (names.length === 0) {
14255
14470
  return null;
14256
14471
  }
14257
- for (const call of func.getDescendantsOfKind(import_ts_morph59.SyntaxKind.CallExpression)) {
14472
+ for (const call of func.getDescendantsOfKind(import_ts_morph60.SyntaxKind.CallExpression)) {
14258
14473
  const first = call.getArguments()[0];
14259
- if (first === void 0 || !import_ts_morph59.Node.isIdentifier(first)) {
14474
+ if (first === void 0 || !import_ts_morph60.Node.isIdentifier(first)) {
14260
14475
  continue;
14261
14476
  }
14262
14477
  const at = names.indexOf(first.getText());
@@ -14266,7 +14481,7 @@ function findWrapperPathParam(summary, lookup) {
14266
14481
  }
14267
14482
  return null;
14268
14483
  }
14269
- function synthesizeCallerSummaries(wrapper, _project, options) {
14484
+ function synthesizeCallerSummaries(wrapper, _project, options, resolution) {
14270
14485
  const nameNode = wrapperNameNode(wrapper.func);
14271
14486
  if (nameNode === null) {
14272
14487
  return [];
@@ -14287,7 +14502,7 @@ function synthesizeCallerSummaries(wrapper, _project, options) {
14287
14502
  if (pathArg === void 0) {
14288
14503
  continue;
14289
14504
  }
14290
- const path12 = literalOrTemplate(pathArg);
14505
+ const path12 = pathFromArgument(pathArg, resolution);
14291
14506
  if (path12 === void 0) {
14292
14507
  continue;
14293
14508
  }
@@ -14305,16 +14520,16 @@ function synthesizeCallerSummaries(wrapper, _project, options) {
14305
14520
  return out;
14306
14521
  }
14307
14522
  function wrapperNameNode(func) {
14308
- if (import_ts_morph59.Node.isFunctionDeclaration(func) || import_ts_morph59.Node.isMethodDeclaration(func)) {
14523
+ if (import_ts_morph60.Node.isFunctionDeclaration(func) || import_ts_morph60.Node.isMethodDeclaration(func)) {
14309
14524
  const name = func.getNameNode();
14310
- if (name !== void 0 && import_ts_morph59.Node.isIdentifier(name)) {
14525
+ if (name !== void 0 && import_ts_morph60.Node.isIdentifier(name)) {
14311
14526
  return name;
14312
14527
  }
14313
14528
  }
14314
14529
  const parent = func.getParent();
14315
- if (parent !== void 0 && import_ts_morph59.Node.isVariableDeclaration(parent)) {
14530
+ if (parent !== void 0 && import_ts_morph60.Node.isVariableDeclaration(parent)) {
14316
14531
  const nameNode = parent.getNameNode();
14317
- if (import_ts_morph59.Node.isIdentifier(nameNode)) {
14532
+ if (import_ts_morph60.Node.isIdentifier(nameNode)) {
14318
14533
  return nameNode;
14319
14534
  }
14320
14535
  }
@@ -14323,10 +14538,10 @@ function wrapperNameNode(func) {
14323
14538
  function enclosingCall(node) {
14324
14539
  let current2 = node.getParent();
14325
14540
  while (current2 !== void 0) {
14326
- if (import_ts_morph59.Node.isCallExpression(current2)) {
14541
+ if (import_ts_morph60.Node.isCallExpression(current2)) {
14327
14542
  return current2;
14328
14543
  }
14329
- if (import_ts_morph59.Node.isPropertyAccessExpression(current2)) {
14544
+ if (import_ts_morph60.Node.isPropertyAccessExpression(current2)) {
14330
14545
  current2 = current2.getParent();
14331
14546
  continue;
14332
14547
  }
@@ -14337,38 +14552,21 @@ function enclosingCall(node) {
14337
14552
  function enclosingFunction(node) {
14338
14553
  let current2 = node.getParent();
14339
14554
  while (current2 !== void 0) {
14340
- if (import_ts_morph59.Node.isFunctionDeclaration(current2) || import_ts_morph59.Node.isFunctionExpression(current2) || import_ts_morph59.Node.isArrowFunction(current2) || import_ts_morph59.Node.isMethodDeclaration(current2)) {
14555
+ if (import_ts_morph60.Node.isFunctionDeclaration(current2) || import_ts_morph60.Node.isFunctionExpression(current2) || import_ts_morph60.Node.isArrowFunction(current2) || import_ts_morph60.Node.isMethodDeclaration(current2)) {
14341
14556
  return current2;
14342
14557
  }
14343
14558
  current2 = current2.getParent();
14344
14559
  }
14345
14560
  return null;
14346
14561
  }
14347
- function literalOrTemplate(arg) {
14348
- if (import_ts_morph59.Node.isStringLiteral(arg)) {
14349
- return arg.getLiteralValue();
14350
- }
14351
- if (import_ts_morph59.Node.isNoSubstitutionTemplateLiteral(arg)) {
14352
- return arg.getLiteralValue();
14353
- }
14354
- if (import_ts_morph59.Node.isTemplateExpression(arg)) {
14355
- let path12 = arg.getHead().getLiteralText();
14356
- for (const span of arg.getTemplateSpans()) {
14357
- path12 += `{${placeholderName(span.getExpression())}}`;
14358
- path12 += span.getLiteral().getLiteralText();
14359
- }
14360
- return path12;
14361
- }
14362
- return void 0;
14363
- }
14364
14562
  function callerName(func) {
14365
- if (import_ts_morph59.Node.isFunctionDeclaration(func) || import_ts_morph59.Node.isMethodDeclaration(func)) {
14563
+ if (import_ts_morph60.Node.isFunctionDeclaration(func) || import_ts_morph60.Node.isMethodDeclaration(func)) {
14366
14564
  return func.getName() ?? "anonymous";
14367
14565
  }
14368
14566
  const parent = func.getParent();
14369
- if (parent !== void 0 && import_ts_morph59.Node.isVariableDeclaration(parent)) {
14567
+ if (parent !== void 0 && import_ts_morph60.Node.isVariableDeclaration(parent)) {
14370
14568
  const nameNode = parent.getNameNode();
14371
- if (import_ts_morph59.Node.isIdentifier(nameNode)) {
14569
+ if (import_ts_morph60.Node.isIdentifier(nameNode)) {
14372
14570
  return nameNode.getText();
14373
14571
  }
14374
14572
  }
@@ -14403,7 +14601,7 @@ function buildCallerSummary(wrapper, callerFunc, callExpr, path12, options) {
14403
14601
  }
14404
14602
  };
14405
14603
  const raw = extractCodeStructure(unit, syntheticPack);
14406
- raw.boundaryBinding = (0, import_behavioral_ir7.restBinding)({
14604
+ raw.boundaryBinding = (0, import_behavioral_ir8.restBinding)({
14407
14605
  transport: wrapperBinding?.transport ?? "http",
14408
14606
  method: wrapperRest?.method ?? null,
14409
14607
  path: path12,
@@ -14473,7 +14671,7 @@ function loadRunFiles(project, candidatePaths, timer) {
14473
14671
  return { sourceFiles, deep };
14474
14672
  }
14475
14673
  function createTypeScriptAdapter(config) {
14476
- const project = config.project ?? new import_ts_morph59.Project(
14674
+ const project = config.project ?? new import_ts_morph60.Project(
14477
14675
  config.tsConfigFilePath !== void 0 ? {
14478
14676
  tsConfigFilePath: config.tsConfigFilePath,
14479
14677
  skipAddingFilesFromTsConfig: true
@@ -14678,7 +14876,12 @@ function createTypeScriptAdapter(config) {
14678
14876
  const wrapperInput = reused === null ? summaries : [...summaries, ...reused.summaries];
14679
14877
  const withWrappers = timer.time(
14680
14878
  "expandWrapperCallers",
14681
- () => expandWrapperCallers(wrapperInput, project, config.extractorOptions)
14879
+ () => expandWrapperCallers(
14880
+ wrapperInput,
14881
+ project,
14882
+ config.extractorOptions,
14883
+ resolution
14884
+ )
14682
14885
  );
14683
14886
  const pipeline = reused === null ? withWrappers : [...summaries, ...withWrappers.slice(wrapperInput.length)];
14684
14887
  const withSubUnits = timer.time(
@@ -14934,10 +15137,10 @@ function mergeWithReused(reused, fresh, ownersBySummary) {
14934
15137
  return { summaries: [...reusedKept, ...fresh], reusedKept, reusedOwners };
14935
15138
  }
14936
15139
  function readsRunLevelJoins(summary) {
14937
- if ((0, import_behavioral_ir7.readSourceDocumentMetadata)(summary) !== void 0) {
15140
+ if ((0, import_behavioral_ir8.readSourceDocumentMetadata)(summary) !== void 0) {
14938
15141
  return true;
14939
15142
  }
14940
- if ((0, import_behavioral_ir7.readGraphqlMetadata)(summary)?.client !== void 0) {
15143
+ if ((0, import_behavioral_ir8.readGraphqlMetadata)(summary)?.client !== void 0) {
14941
15144
  return true;
14942
15145
  }
14943
15146
  const semantics = summary.identity.boundaryBinding?.semantics;
@@ -15120,7 +15323,7 @@ function buildSubUnitSummary(subUnit, parent, invocationRecognizers, accessRecog
15120
15323
  // src/bootstrap/noTsconfigProject.ts
15121
15324
  var import_node_fs6 = __toESM(require("fs"), 1);
15122
15325
  var import_node_path10 = __toESM(require("path"), 1);
15123
- var import_ts_morph60 = require("ts-morph");
15326
+ var import_ts_morph61 = require("ts-morph");
15124
15327
  var SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([
15125
15328
  ".ts",
15126
15329
  ".tsx",
@@ -15168,12 +15371,12 @@ function findSourceFiles(rootDir, depth = 0) {
15168
15371
  return found;
15169
15372
  }
15170
15373
  function createProjectWithoutTsconfig(rootDir) {
15171
- const project = new import_ts_morph60.Project({
15374
+ const project = new import_ts_morph61.Project({
15172
15375
  skipAddingFilesFromTsConfig: true,
15173
15376
  compilerOptions: {
15174
- target: import_ts_morph60.ScriptTarget.ES2022,
15175
- module: import_ts_morph60.ModuleKind.ESNext,
15176
- moduleResolution: import_ts_morph60.ModuleResolutionKind.Bundler,
15377
+ target: import_ts_morph61.ScriptTarget.ES2022,
15378
+ module: import_ts_morph61.ModuleKind.ESNext,
15379
+ moduleResolution: import_ts_morph61.ModuleResolutionKind.Bundler,
15177
15380
  allowJs: true,
15178
15381
  checkJs: false,
15179
15382
  noEmit: true,
@@ -15214,7 +15417,7 @@ function findNearestTsconfig(startDir) {
15214
15417
 
15215
15418
  // src/facts/why.ts
15216
15419
  var import_node_path11 = __toESM(require("path"), 1);
15217
- var import_ts_morph61 = require("ts-morph");
15420
+ var import_ts_morph62 = require("ts-morph");
15218
15421
  var import_resolution2 = require("@suss/resolution");
15219
15422
  var JS_PHRASES = {
15220
15423
  bind: ({ tuple, describe }) => ({
@@ -15228,7 +15431,7 @@ var WhySession = class {
15228
15431
  constructor(options) {
15229
15432
  this.root = import_node_path11.default.resolve(options.dir);
15230
15433
  const tsconfig = findNearestTsconfig(this.root);
15231
- this.project = tsconfig === null ? createProjectWithoutTsconfig(this.root).project : new import_ts_morph61.Project({ tsConfigFilePath: tsconfig });
15434
+ this.project = tsconfig === null ? createProjectWithoutTsconfig(this.root).project : new import_ts_morph62.Project({ tsConfigFilePath: tsconfig });
15232
15435
  this.store = new ResolutionStore();
15233
15436
  }
15234
15437
  /**
@@ -15243,7 +15446,7 @@ var WhySession = class {
15243
15446
  }
15244
15447
  let found = null;
15245
15448
  sourceFile.forEachDescendant((node) => {
15246
- if (import_ts_morph61.Node.isExpression(node) && node.getStartLineNumber() === line && node.getText() === text && (found === null || node.getWidth() <= found.getWidth())) {
15449
+ if (import_ts_morph62.Node.isExpression(node) && node.getStartLineNumber() === line && node.getText() === text && (found === null || node.getWidth() <= found.getWidth())) {
15247
15450
  found = node;
15248
15451
  }
15249
15452
  });
@@ -15261,7 +15464,7 @@ var WhySession = class {
15261
15464
  return null;
15262
15465
  }
15263
15466
  for (const call of sourceFile.getDescendantsOfKind(
15264
- import_ts_morph61.SyntaxKind.CallExpression
15467
+ import_ts_morph62.SyntaxKind.CallExpression
15265
15468
  )) {
15266
15469
  const line = call.getStartLineNumber();
15267
15470
  if (line < startLine || line > endLine) {
@@ -15335,21 +15538,21 @@ var WhySession = class {
15335
15538
  }
15336
15539
  };
15337
15540
  function displayNameOf(node) {
15338
- if (import_ts_morph61.Node.isIdentifier(node) || import_ts_morph61.Node.isPropertyAccessExpression(node)) {
15541
+ if (import_ts_morph62.Node.isIdentifier(node) || import_ts_morph62.Node.isPropertyAccessExpression(node)) {
15339
15542
  return node.getText();
15340
15543
  }
15341
- if (import_ts_morph61.Node.isCallExpression(node) || import_ts_morph61.Node.isNewExpression(node)) {
15544
+ if (import_ts_morph62.Node.isCallExpression(node) || import_ts_morph62.Node.isNewExpression(node)) {
15342
15545
  return `${node.getExpression()?.getText() ?? "call"}(...)`;
15343
15546
  }
15344
- if (import_ts_morph61.Node.isFunctionDeclaration(node) || import_ts_morph61.Node.isClassDeclaration(node) || import_ts_morph61.Node.isMethodDeclaration(node) || import_ts_morph61.Node.isVariableDeclaration(node)) {
15547
+ if (import_ts_morph62.Node.isFunctionDeclaration(node) || import_ts_morph62.Node.isClassDeclaration(node) || import_ts_morph62.Node.isMethodDeclaration(node) || import_ts_morph62.Node.isVariableDeclaration(node)) {
15345
15548
  const name = node.getName();
15346
15549
  if (name !== void 0) {
15347
15550
  return name;
15348
15551
  }
15349
15552
  }
15350
- if (import_ts_morph61.Node.isArrowFunction(node) || import_ts_morph61.Node.isFunctionExpression(node)) {
15553
+ if (import_ts_morph62.Node.isArrowFunction(node) || import_ts_morph62.Node.isFunctionExpression(node)) {
15351
15554
  const parent = node.getParent();
15352
- if (parent !== void 0 && import_ts_morph61.Node.isVariableDeclaration(parent)) {
15555
+ if (parent !== void 0 && import_ts_morph62.Node.isVariableDeclaration(parent)) {
15353
15556
  return parent.getName();
15354
15557
  }
15355
15558
  }
@@ -15550,6 +15753,7 @@ function formatPackHealth(checks, audiences) {
15550
15753
  ADAPTER_VERSION,
15551
15754
  ResolutionStore,
15552
15755
  WhySession,
15756
+ accessContextFor,
15553
15757
  callOpsFor,
15554
15758
  collectAncestorBranches,
15555
15759
  collectClientFieldAccesses,
@@ -15567,6 +15771,7 @@ function formatPackHealth(checks, audiences) {
15567
15771
  findNearestTsconfig,
15568
15772
  findTerminals,
15569
15773
  formatPackHealth,
15774
+ invocationContextFor,
15570
15775
  isImportedFrom,
15571
15776
  methodDeclaredIn,
15572
15777
  parseConditionExpression,