@suss/adapter-typescript 0.12.0 → 0.13.1

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.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // src/adapter.ts
2
2
  import path9 from "path";
3
3
  import {
4
- Node as Node57,
4
+ Node as Node58,
5
5
  Project,
6
6
  SyntaxKind as SyntaxKind12
7
7
  } from "ts-morph";
@@ -249,14 +249,14 @@ function dedupe(shapes) {
249
249
  return out;
250
250
  }
251
251
  function isInformativeInitializer(node) {
252
- const unwrapped = peelSyntax(node);
253
- if (Node2.isStringLiteral(unwrapped) || Node2.isNoSubstitutionTemplateLiteral(unwrapped) || Node2.isNumericLiteral(unwrapped) || Node2.isBigIntLiteral(unwrapped) || Node2.isObjectLiteralExpression(unwrapped) || Node2.isArrayLiteralExpression(unwrapped) || Node2.isTemplateExpression(unwrapped) || Node2.isConditionalExpression(unwrapped) || Node2.isIdentifier(unwrapped) || Node2.isPropertyAccessExpression(unwrapped) || Node2.isElementAccessExpression(unwrapped)) {
252
+ const unwrapped2 = peelSyntax(node);
253
+ if (Node2.isStringLiteral(unwrapped2) || Node2.isNoSubstitutionTemplateLiteral(unwrapped2) || Node2.isNumericLiteral(unwrapped2) || Node2.isBigIntLiteral(unwrapped2) || Node2.isObjectLiteralExpression(unwrapped2) || Node2.isArrayLiteralExpression(unwrapped2) || Node2.isTemplateExpression(unwrapped2) || Node2.isConditionalExpression(unwrapped2) || Node2.isIdentifier(unwrapped2) || Node2.isPropertyAccessExpression(unwrapped2) || Node2.isElementAccessExpression(unwrapped2)) {
254
254
  return true;
255
255
  }
256
- if (Node2.isPrefixUnaryExpression(unwrapped)) {
257
- return isInformativeInitializer(unwrapped.getOperand());
256
+ if (Node2.isPrefixUnaryExpression(unwrapped2)) {
257
+ return isInformativeInitializer(unwrapped2.getOperand());
258
258
  }
259
- const kind = unwrapped.getKind();
259
+ const kind = unwrapped2.getKind();
260
260
  return kind === SyntaxKind.TrueKeyword || kind === SyntaxKind.FalseKeyword || kind === SyntaxKind.NullKeyword;
261
261
  }
262
262
  function resolveCallableBody(callee) {
@@ -1461,7 +1461,9 @@ function degradedResult(func, terminalNodes, reason) {
1461
1461
  }
1462
1462
 
1463
1463
  // src/resolve/invocationEffects.ts
1464
- import { Node as Node14 } from "ts-morph";
1464
+ import {
1465
+ Node as Node14
1466
+ } from "ts-morph";
1465
1467
 
1466
1468
  // src/lines.ts
1467
1469
  function startLineOf(node) {
@@ -1575,8 +1577,8 @@ var ModuleGraph = class {
1575
1577
  * earlier walk settled stops it for the same reason.
1576
1578
  */
1577
1579
  settle(root, name) {
1578
- const settled = this.settledOf(name);
1579
- if (settled.has(root.getFilePath())) {
1580
+ const settled2 = this.settledOf(name);
1581
+ if (settled2.has(root.getFilePath())) {
1580
1582
  return;
1581
1583
  }
1582
1584
  const walked = /* @__PURE__ */ new Set();
@@ -1584,7 +1586,7 @@ var ModuleGraph = class {
1584
1586
  while (stack.length > 0) {
1585
1587
  const current2 = stack.pop();
1586
1588
  const currentPath = current2.getFilePath();
1587
- if (walked.has(currentPath) || settled.has(currentPath)) {
1589
+ if (walked.has(currentPath) || settled2.has(currentPath)) {
1588
1590
  continue;
1589
1591
  }
1590
1592
  walked.add(currentPath);
@@ -1595,7 +1597,7 @@ var ModuleGraph = class {
1595
1597
  stack.push(...this.importedFilesOf(current2));
1596
1598
  }
1597
1599
  for (const filePath of walked) {
1598
- settled.add(filePath);
1600
+ settled2.add(filePath);
1599
1601
  }
1600
1602
  }
1601
1603
  settledOf(name) {
@@ -2644,15 +2646,28 @@ function holeName(expr, ctx) {
2644
2646
  }
2645
2647
 
2646
2648
  // src/resolve/callOps.ts
2649
+ var MAX_WRITTEN_HOPS = 4;
2647
2650
  var ORIGIN = {
2648
- declaredBy: (origin, receiver) => origin.importedFrom.some(
2651
+ declaredBy: (origin, receiver) => receiver.callee !== null && origin.importedFrom.some(
2649
2652
  (module) => methodDeclaredIn(receiver.callee, module, receiver.resolve)
2650
2653
  ),
2651
2654
  constructed: (origin, receiver) => origin.importedFrom.some(
2652
2655
  (module) => isImportedFrom(madeBy(receiver), module)
2653
2656
  )
2654
2657
  };
2658
+ var CALL_ORIGIN = {
2659
+ declaredBy: ORIGIN.declaredBy,
2660
+ constructed: (origin, receiver) => origin.importedFrom.some(
2661
+ (module) => isImportedFrom(
2662
+ rootIdentifier(receiver.expression) ?? receiver.expression,
2663
+ module
2664
+ )
2665
+ )
2666
+ };
2655
2667
  function madeBy(receiver) {
2668
+ if (receiver.callee === null) {
2669
+ return rootIdentifier(receiver.expression) ?? receiver.expression;
2670
+ }
2656
2671
  const written = receiver.resolve(receiver.callee.getExpression());
2657
2672
  if (written === null || !Node13.isNewExpression(written) && !Node13.isCallExpression(written)) {
2658
2673
  return receiver.callee;
@@ -2661,30 +2676,217 @@ function madeBy(receiver) {
2661
2676
  }
2662
2677
  function callOpsFor(call, resolveWrittenValue) {
2663
2678
  const resolve2 = resolveWrittenValue ?? (() => null);
2664
- const expression = call.getExpression();
2679
+ const expression = calleeOf(call);
2665
2680
  const callee = Node13.isPropertyAccessExpression(expression) ? expression : null;
2666
2681
  let args = null;
2667
2682
  const argumentsOf = () => {
2668
- args ??= call.getArguments();
2683
+ args ??= argumentsIn(call);
2669
2684
  return args;
2670
2685
  };
2671
2686
  return {
2672
2687
  method: () => callee === null ? null : callee.getName(),
2673
- receiverIsFrom: (origin) => callee !== null && ORIGIN[origin.origin](origin, { callee, resolve: resolve2 }),
2688
+ receiverIsFrom: (origin) => ORIGIN[origin.origin](origin, { callee, expression, resolve: resolve2 }),
2689
+ isFrom: (origin) => CALL_ORIGIN[origin.origin](origin, { callee, expression, resolve: resolve2 }),
2674
2690
  argumentCount: () => argumentsOf().length,
2675
2691
  nameAt: (index, unsettled) => nameAt(argumentsOf()[index], unsettled, resolve2),
2676
2692
  calleeText: () => expression.getText(),
2693
+ receiver: () => callee === null ? null : opsOverCall(callee.getExpression(), resolve2),
2694
+ argument: (index) => opsOverCall(argumentsOf()[index], resolve2),
2695
+ callee: () => opsOverCall(expression, resolve2),
2696
+ propertyAt: (index, property, unsettled) => propertyAt(argumentsOf()[index], property, unsettled, resolve2),
2697
+ valueAt: (index) => {
2698
+ const argument = argumentsOf()[index];
2699
+ return argument === void 0 ? null : valueOpsFor(argument, resolve2);
2700
+ },
2677
2701
  ast: () => call
2678
2702
  };
2679
2703
  }
2704
+ function valueOpsFor(value, resolve2) {
2705
+ let settledValue;
2706
+ const written = () => {
2707
+ settledValue ??= settled(value, resolve2) ?? value;
2708
+ return settledValue;
2709
+ };
2710
+ return {
2711
+ text: () => literalText(written()),
2712
+ flag: () => literalFlag(written()),
2713
+ entries: (unsettled) => entriesOf(written(), unsettled, resolve2),
2714
+ items: () => itemsOf(written(), resolve2),
2715
+ property: (name) => {
2716
+ const object = written();
2717
+ const inside = Node13.isObjectLiteralExpression(object) ? initializerOf(object, name) : null;
2718
+ return inside === null ? null : valueOpsFor(inside, resolve2);
2719
+ },
2720
+ parts: () => literalParts(written()),
2721
+ holes: () => templateHoles(written(), resolve2)
2722
+ };
2723
+ }
2724
+ function literalParts(value) {
2725
+ const written = untagged(value);
2726
+ const whole = literalText(written);
2727
+ if (whole !== null) {
2728
+ return [whole];
2729
+ }
2730
+ if (!Node13.isTemplateExpression(written)) {
2731
+ return null;
2732
+ }
2733
+ return [
2734
+ written.getHead().getLiteralText(),
2735
+ ...written.getTemplateSpans().map((span) => span.getLiteral().getLiteralText())
2736
+ ];
2737
+ }
2738
+ function templateHoles(value, resolve2) {
2739
+ const written = untagged(value);
2740
+ if (!Node13.isTemplateExpression(written)) {
2741
+ return [];
2742
+ }
2743
+ return written.getTemplateSpans().map((span) => opsOverCall(span.getExpression(), resolve2));
2744
+ }
2745
+ function untagged(value) {
2746
+ return Node13.isTaggedTemplateExpression(value) ? value.getTemplate() : value;
2747
+ }
2748
+ function entriesOf(value, unsettled, resolve2) {
2749
+ if (!Node13.isObjectLiteralExpression(value)) {
2750
+ return [];
2751
+ }
2752
+ const found = [];
2753
+ for (const written of value.getProperties()) {
2754
+ if (Node13.isShorthandPropertyAssignment(written)) {
2755
+ const name = written.getNameNode();
2756
+ found.push({ key: name.getText(), value: valueOpsFor(name, resolve2) });
2757
+ continue;
2758
+ }
2759
+ if (!Node13.isPropertyAssignment(written)) {
2760
+ continue;
2761
+ }
2762
+ const stated = written.getInitializer();
2763
+ found.push({
2764
+ key: entryKey(written, unsettled, resolve2),
2765
+ value: valueOpsFor(stated ?? written, resolve2)
2766
+ });
2767
+ }
2768
+ return found;
2769
+ }
2770
+ function entryKey(written, unsettled, resolve2) {
2771
+ const name = written.getNameNode();
2772
+ if (Node13.isComputedPropertyName(name)) {
2773
+ return readName(name.getExpression(), { resolve: resolve2, unsettled });
2774
+ }
2775
+ return unquoted(written.getName());
2776
+ }
2777
+ function itemsOf(value, resolve2) {
2778
+ if (!Node13.isArrayLiteralExpression(value)) {
2779
+ return [];
2780
+ }
2781
+ return value.getElements().map((element) => valueOpsFor(element, resolve2));
2782
+ }
2783
+ function literalText(value) {
2784
+ return Node13.isStringLiteral(value) || Node13.isNoSubstitutionTemplateLiteral(value) ? value.getLiteralValue() : null;
2785
+ }
2786
+ function literalFlag(value) {
2787
+ if (Node13.isTrueLiteral(value) || Node13.isFalseLiteral(value)) {
2788
+ return Node13.isTrueLiteral(value);
2789
+ }
2790
+ return Node13.isNumericLiteral(value) ? value.getLiteralValue() !== 0 : null;
2791
+ }
2792
+ function unquoted(name) {
2793
+ return name.replace(/^["']|["']$/g, "");
2794
+ }
2795
+ function opsOverCall(value, resolve2) {
2796
+ const written = settled(value, resolve2);
2797
+ if (written === null || !isCalled(written)) {
2798
+ return null;
2799
+ }
2800
+ return callOpsFor(written, resolve2);
2801
+ }
2802
+ function isCalled(value) {
2803
+ return Node13.isCallExpression(value) || Node13.isNewExpression(value) || Node13.isTaggedTemplateExpression(value);
2804
+ }
2805
+ function calleeOf(call) {
2806
+ return Node13.isTaggedTemplateExpression(call) ? call.getTag() : call.getExpression();
2807
+ }
2808
+ function argumentsIn(call) {
2809
+ return Node13.isTaggedTemplateExpression(call) ? [call.getTemplate()] : call.getArguments();
2810
+ }
2811
+ function settled(value, resolve2) {
2812
+ let step = unwrapped(value ?? null);
2813
+ for (let hops = 0; hops < MAX_WRITTEN_HOPS; hops += 1) {
2814
+ if (step === null || !Node13.isIdentifier(step)) {
2815
+ return step;
2816
+ }
2817
+ const written = variableFor(step)?.getInitializer() ?? resolve2(step);
2818
+ if (written === null || written === step) {
2819
+ return null;
2820
+ }
2821
+ step = unwrapped(written);
2822
+ }
2823
+ return null;
2824
+ }
2825
+ function unwrapped(value) {
2826
+ let inside = value;
2827
+ while (inside !== null && (Node13.isAwaitExpression(inside) || Node13.isParenthesizedExpression(inside))) {
2828
+ inside = inside.getExpression();
2829
+ }
2830
+ return inside;
2831
+ }
2832
+ function variableFor(name) {
2833
+ if (!Node13.isIdentifier(name)) {
2834
+ return null;
2835
+ }
2836
+ for (const declaration of name.getSymbol()?.getDeclarations() ?? []) {
2837
+ if (Node13.isVariableDeclaration(declaration)) {
2838
+ return declaration;
2839
+ }
2840
+ }
2841
+ return null;
2842
+ }
2680
2843
  function nameAt(argument, unsettled, resolve2) {
2681
2844
  if (argument === void 0) {
2682
2845
  return null;
2683
2846
  }
2684
2847
  return readName(argument, { resolve: resolve2, unsettled });
2685
2848
  }
2849
+ function propertyAt(argument, property, unsettled, resolve2) {
2850
+ const stated = objectAt(argument, resolve2);
2851
+ const written = stated === null ? null : initializerOf(stated, property);
2852
+ return written === null ? null : readName(written, { resolve: resolve2, unsettled });
2853
+ }
2854
+ function objectAt(argument, resolve2) {
2855
+ const written = settled(argument, resolve2);
2856
+ if (written === null) {
2857
+ return null;
2858
+ }
2859
+ if (isCalled(written)) {
2860
+ return objectAt(argumentsIn(written)[0], resolve2);
2861
+ }
2862
+ return Node13.isObjectLiteralExpression(written) ? written : null;
2863
+ }
2864
+ function initializerOf(object, property) {
2865
+ for (const written of object.getProperties()) {
2866
+ if (Node13.isPropertyAssignment(written) && written.getName() === property) {
2867
+ return written.getInitializer() ?? null;
2868
+ }
2869
+ }
2870
+ return null;
2871
+ }
2686
2872
 
2687
2873
  // src/resolve/invocationEffects.ts
2874
+ function invocationContextFor(call, resolveWrittenValue) {
2875
+ let ops = null;
2876
+ return {
2877
+ call,
2878
+ sourceFile: call.getSourceFile(),
2879
+ extractArgs: () => extractArgs(call),
2880
+ isImportedFrom,
2881
+ // A context built without a store gives null, and the recognizer's
2882
+ // own pattern match runs on the raw node.
2883
+ resolveWrittenValue: resolveWrittenValue ?? (() => null),
2884
+ get ops() {
2885
+ ops ??= callOpsFor(call, resolveWrittenValue);
2886
+ return ops;
2887
+ }
2888
+ };
2889
+ }
2688
2890
  function isImportedFrom(identifier, expectedModule) {
2689
2891
  if (!Node14.isIdentifier(identifier)) {
2690
2892
  return false;
@@ -2893,20 +3095,7 @@ function runInvocationRecognizers(func, recognizers, barriers = NO_BARRIERS, res
2893
3095
  if (!Node14.isCallExpression(node)) {
2894
3096
  return;
2895
3097
  }
2896
- let ops = null;
2897
- const ctx = {
2898
- call: node,
2899
- sourceFile,
2900
- extractArgs: () => extractArgs(node),
2901
- isImportedFrom,
2902
- // A context built without a store gives null, and the recognizer's
2903
- // own pattern match runs on the raw node.
2904
- resolveWrittenValue: resolveWrittenValue ?? (() => null),
2905
- get ops() {
2906
- ops ??= callOpsFor(node, resolveWrittenValue);
2907
- return ops;
2908
- }
2909
- };
3098
+ const ctx = invocationContextFor(node, resolveWrittenValue);
2910
3099
  const line = enclosingStatementLine(node);
2911
3100
  for (const recognizer of recognizers) {
2912
3101
  let emitted = null;
@@ -2947,6 +3136,20 @@ function runAccessRecognizersAtModuleScope(sourceFile, recognizers, resolveWritt
2947
3136
  resolveWrittenValue
2948
3137
  );
2949
3138
  }
3139
+ function accessContextFor(node, sourceFile, resolveWrittenValue = () => null) {
3140
+ const given = { access: node, sourceFile, resolveWrittenValue };
3141
+ if (Node14.isPropertyAccessExpression(node)) {
3142
+ return given;
3143
+ }
3144
+ let ops;
3145
+ return {
3146
+ ...given,
3147
+ get ops() {
3148
+ ops ??= callOpsFor(node, resolveWrittenValue);
3149
+ return ops;
3150
+ }
3151
+ };
3152
+ }
2950
3153
  function dispatchAccessRecognizers(root, recognizers, isStop, resolveWrittenValue) {
2951
3154
  if (recognizers.length === 0) {
2952
3155
  return [];
@@ -2962,11 +3165,7 @@ function dispatchAccessRecognizers(root, recognizers, isStop, resolveWrittenValu
2962
3165
  if (!Node14.isPropertyAccessExpression(node) && !Node14.isCallExpression(node) && !Node14.isTaggedTemplateExpression(node)) {
2963
3166
  return;
2964
3167
  }
2965
- const ctx = {
2966
- access: node,
2967
- sourceFile,
2968
- resolveWrittenValue: resolveWrittenValue ?? (() => null)
2969
- };
3168
+ const ctx = accessContextFor(node, sourceFile, resolveWrittenValue);
2970
3169
  const line = enclosingStatementLine(node);
2971
3170
  for (const recognizer of recognizers) {
2972
3171
  let emitted = null;
@@ -3129,8 +3328,8 @@ function inlineModuleBinding(ident, depth) {
3129
3328
  if (init === void 0) {
3130
3329
  continue;
3131
3330
  }
3132
- const unwrapped = unwrapCasts(init);
3133
- const captured = extractArg(unwrapped, depth - 1);
3331
+ const unwrapped2 = unwrapCasts(init);
3332
+ const captured = extractArg(unwrapped2, depth - 1);
3134
3333
  if (captured !== null) {
3135
3334
  return captured;
3136
3335
  }
@@ -3840,35 +4039,35 @@ function extractShapeWithArguments(node, substitutions) {
3840
4039
  }
3841
4040
  }
3842
4041
  function extractShapeInner(node) {
3843
- const unwrapped = peelSyntax(node);
3844
- if (boundArguments !== null && Node16.isIdentifier(unwrapped)) {
3845
- const argument = boundArguments.get(unwrapped.getText());
3846
- if (argument !== void 0 && argument !== unwrapped) {
4042
+ const unwrapped2 = peelSyntax(node);
4043
+ if (boundArguments !== null && Node16.isIdentifier(unwrapped2)) {
4044
+ const argument = boundArguments.get(unwrapped2.getText());
4045
+ if (argument !== void 0 && argument !== unwrapped2) {
3847
4046
  return extractShape(argument);
3848
4047
  }
3849
4048
  }
3850
- if (Node16.isObjectLiteralExpression(unwrapped)) {
3851
- return shapeFromObjectLiteral(unwrapped);
4049
+ if (Node16.isObjectLiteralExpression(unwrapped2)) {
4050
+ return shapeFromObjectLiteral(unwrapped2);
3852
4051
  }
3853
- if (Node16.isArrayLiteralExpression(unwrapped)) {
3854
- return shapeFromArrayLiteral(unwrapped);
4052
+ if (Node16.isArrayLiteralExpression(unwrapped2)) {
4053
+ return shapeFromArrayLiteral(unwrapped2);
3855
4054
  }
3856
- if (Node16.isStringLiteral(unwrapped) || Node16.isNoSubstitutionTemplateLiteral(unwrapped)) {
3857
- return { type: "literal", value: unwrapped.getLiteralValue() };
4055
+ if (Node16.isStringLiteral(unwrapped2) || Node16.isNoSubstitutionTemplateLiteral(unwrapped2)) {
4056
+ return { type: "literal", value: unwrapped2.getLiteralValue() };
3858
4057
  }
3859
- if (Node16.isTemplateExpression(unwrapped)) {
4058
+ if (Node16.isTemplateExpression(unwrapped2)) {
3860
4059
  return { type: "text" };
3861
4060
  }
3862
- if (Node16.isNumericLiteral(unwrapped)) {
4061
+ if (Node16.isNumericLiteral(unwrapped2)) {
3863
4062
  return numericLiteralShape(
3864
- unwrapped.getLiteralValue(),
3865
- unwrapped.getText()
4063
+ unwrapped2.getLiteralValue(),
4064
+ unwrapped2.getText()
3866
4065
  );
3867
4066
  }
3868
- if (Node16.isPrefixUnaryExpression(unwrapped)) {
3869
- const op = unwrapped.getOperatorToken();
4067
+ if (Node16.isPrefixUnaryExpression(unwrapped2)) {
4068
+ const op = unwrapped2.getOperatorToken();
3870
4069
  if (op === SyntaxKind4.MinusToken || op === SyntaxKind4.PlusToken) {
3871
- const inner = unwrapped.getOperand();
4070
+ const inner = unwrapped2.getOperand();
3872
4071
  if (Node16.isNumericLiteral(inner)) {
3873
4072
  const v3 = inner.getLiteralValue();
3874
4073
  const signed = op === SyntaxKind4.MinusToken ? -v3 : v3;
@@ -3878,10 +4077,10 @@ function extractShapeInner(node) {
3878
4077
  }
3879
4078
  }
3880
4079
  }
3881
- if (Node16.isBigIntLiteral(unwrapped)) {
4080
+ if (Node16.isBigIntLiteral(unwrapped2)) {
3882
4081
  return { type: "ref", name: "bigint" };
3883
4082
  }
3884
- const kind = unwrapped.getKind();
4083
+ const kind = unwrapped2.getKind();
3885
4084
  if (kind === SyntaxKind4.TrueKeyword) {
3886
4085
  return { type: "literal", value: true };
3887
4086
  }
@@ -3891,12 +4090,12 @@ function extractShapeInner(node) {
3891
4090
  if (kind === SyntaxKind4.NullKeyword) {
3892
4091
  return { type: "null" };
3893
4092
  }
3894
- if (Node16.isIdentifier(unwrapped) && unwrapped.getText() === "undefined") {
4093
+ if (Node16.isIdentifier(unwrapped2) && unwrapped2.getText() === "undefined") {
3895
4094
  return { type: "undefined" };
3896
4095
  }
3897
- if (Node16.isConditionalExpression(unwrapped)) {
3898
- const whenTrue = extractShape(unwrapped.getWhenTrue());
3899
- const whenFalse = extractShape(unwrapped.getWhenFalse());
4096
+ if (Node16.isConditionalExpression(unwrapped2)) {
4097
+ const whenTrue = extractShape(unwrapped2.getWhenTrue());
4098
+ const whenFalse = extractShape(unwrapped2.getWhenFalse());
3900
4099
  const variants = [];
3901
4100
  if (whenTrue) {
3902
4101
  variants.push(whenTrue);
@@ -3905,15 +4104,15 @@ function extractShapeInner(node) {
3905
4104
  variants.push(whenFalse);
3906
4105
  }
3907
4106
  if (variants.length === 0) {
3908
- return shapeFromNodeType(unwrapped);
4107
+ return shapeFromNodeType(unwrapped2);
3909
4108
  }
3910
4109
  return collapseVariants2(variants);
3911
4110
  }
3912
- const astShape = resolveNodeFromAst(unwrapped, extractShape);
4111
+ const astShape = resolveNodeFromAst(unwrapped2, extractShape);
3913
4112
  if (astShape !== null) {
3914
4113
  return astShape;
3915
4114
  }
3916
- return shapeFromNodeType(unwrapped);
4115
+ return shapeFromNodeType(unwrapped2);
3917
4116
  }
3918
4117
  function numericLiteralShape(value, raw) {
3919
4118
  return { type: "literal", value, raw };
@@ -4073,15 +4272,15 @@ function matchConstructorCode(ctorText, codes) {
4073
4272
  return null;
4074
4273
  }
4075
4274
  function statusOf(value, ctx) {
4076
- const unwrapped = unwrapAs(value);
4077
- if (Node17.isNumericLiteral(unwrapped)) {
4078
- return { type: "literal", value: Number(unwrapped.getText()) };
4275
+ const unwrapped2 = unwrapAs(value);
4276
+ if (Node17.isNumericLiteral(unwrapped2)) {
4277
+ return { type: "literal", value: Number(unwrapped2.getText()) };
4079
4278
  }
4080
- const resolved = ctx.resolveWrittenValue?.(unwrapped) ?? null;
4279
+ const resolved = ctx.resolveWrittenValue?.(unwrapped2) ?? null;
4081
4280
  if (resolved !== null && Node17.isNumericLiteral(resolved)) {
4082
4281
  return { type: "literal", value: Number(resolved.getText()) };
4083
4282
  }
4084
- return { type: "dynamic", sourceText: unwrapped.getText() };
4283
+ return { type: "dynamic", sourceText: unwrapped2.getText() };
4085
4284
  }
4086
4285
  function statusFromProperty(obj, name, ctx) {
4087
4286
  const prop = obj.getProperty(name);
@@ -4464,9 +4663,9 @@ function returnedObjects(fn) {
4464
4663
  if (expression === void 0) {
4465
4664
  continue;
4466
4665
  }
4467
- const unwrapped = peelParens(expression);
4468
- if (Node18.isObjectLiteralExpression(unwrapped)) {
4469
- found.push(unwrapped);
4666
+ const unwrapped2 = peelParens(expression);
4667
+ if (Node18.isObjectLiteralExpression(unwrapped2)) {
4668
+ found.push(unwrapped2);
4470
4669
  }
4471
4670
  }
4472
4671
  return found;
@@ -7860,7 +8059,7 @@ function classDecoratorStandingFor(cls, names, modules, resolution) {
7860
8059
  return null;
7861
8060
  }
7862
8061
  for (const decorator of cls.getDecorators()) {
7863
- const applied = resolution.importedNamesOf(calleeOf(decorator), modules);
8062
+ const applied = resolution.importedNamesOf(calleeOf2(decorator), modules);
7864
8063
  const standsFor = names.find((name) => applied.includes(name));
7865
8064
  if (standsFor === void 0) {
7866
8065
  continue;
@@ -7878,7 +8077,7 @@ function frameworkArgs(decorator, standsFor, modules, resolution) {
7878
8077
  if (atClass.length > 0) {
7879
8078
  return atClass;
7880
8079
  }
7881
- const wrapper = resolution.resolveCallable(calleeOf(decorator));
8080
+ const wrapper = resolution.resolveCallable(calleeOf2(decorator));
7882
8081
  if (wrapper === null) {
7883
8082
  return atClass;
7884
8083
  }
@@ -7903,7 +8102,7 @@ function statesAValue(arg, wrapper) {
7903
8102
  function isWithin(node, container) {
7904
8103
  return node.getSourceFile() === container.getSourceFile() && node.getStart() >= container.getStart() && node.getEnd() <= container.getEnd();
7905
8104
  }
7906
- function calleeOf(decorator) {
8105
+ function calleeOf2(decorator) {
7907
8106
  const call = decorator.getCallExpression();
7908
8107
  if (call !== void 0) {
7909
8108
  return call.getExpression();
@@ -9110,9 +9309,9 @@ function attributeValueOf(node, name) {
9110
9309
  return null;
9111
9310
  }
9112
9311
  function literalStringOf(value) {
9113
- const unwrapped = Node41.isJsxExpression(value) ? value.getExpression() ?? value : value;
9114
- if (Node41.isStringLiteral(unwrapped) || Node41.isNoSubstitutionTemplateLiteral(unwrapped)) {
9115
- return unwrapped.getLiteralValue();
9312
+ const unwrapped2 = Node41.isJsxExpression(value) ? value.getExpression() ?? value : value;
9313
+ if (Node41.isStringLiteral(unwrapped2) || Node41.isNoSubstitutionTemplateLiteral(unwrapped2)) {
9314
+ return unwrapped2.getLiteralValue();
9116
9315
  }
9117
9316
  return null;
9118
9317
  }
@@ -9131,11 +9330,11 @@ function elementTargetOfValue(value) {
9131
9330
  if (value === null) {
9132
9331
  return { kind: "absent" };
9133
9332
  }
9134
- const unwrapped = Node41.isJsxExpression(value) ? value.getExpression() ?? value : value;
9135
- if (!Node41.isJsxSelfClosingElement(unwrapped) && !Node41.isJsxElement(unwrapped)) {
9333
+ const unwrapped2 = Node41.isJsxExpression(value) ? value.getExpression() ?? value : value;
9334
+ if (!Node41.isJsxSelfClosingElement(unwrapped2) && !Node41.isJsxElement(unwrapped2)) {
9136
9335
  return { kind: "unreadable" };
9137
9336
  }
9138
- const tag = tagNameOf(unwrapped);
9337
+ const tag = tagNameOf(unwrapped2);
9139
9338
  if (tag === null) {
9140
9339
  return { kind: "unreadable" };
9141
9340
  }
@@ -9999,7 +10198,146 @@ function discoverPackageImports(sourceFile, match, kind) {
9999
10198
  }
10000
10199
 
10001
10200
  // src/discovery/registrationCall.ts
10201
+ import { Node as Node47 } from "ts-morph";
10202
+
10203
+ // src/resolve/routePath.ts
10002
10204
  import { Node as Node46 } from "ts-morph";
10205
+ import { patternHole as patternHole2 } from "@suss/behavioral-ir";
10206
+ var URL_SCHEME = /^[a-zA-Z][a-zA-Z\d+.-]*:\/\//;
10207
+ var URL_ORIGIN = /^[a-zA-Z][a-zA-Z\d+.-]*:\/\/[^/]*/;
10208
+ var PROTOCOL_RELATIVE = /^\/\//;
10209
+ var PROTOCOL_RELATIVE_ORIGIN = /^\/\/[^/]*/;
10210
+ function isAbsoluteUrlLiteral(text) {
10211
+ return URL_SCHEME.test(text) || PROTOCOL_RELATIVE.test(text);
10212
+ }
10213
+ function stripOriginManually(text) {
10214
+ if (URL_SCHEME.test(text)) {
10215
+ return text.replace(URL_ORIGIN, "");
10216
+ }
10217
+ if (PROTOCOL_RELATIVE.test(text)) {
10218
+ return text.replace(PROTOCOL_RELATIVE_ORIGIN, "");
10219
+ }
10220
+ return text;
10221
+ }
10222
+ function stripQueryAndFragment(text) {
10223
+ const idx = text.search(/[?#]/);
10224
+ return idx === -1 ? text : text.slice(0, idx);
10225
+ }
10226
+ var SUBSTITUTION = "\uFFFF";
10227
+ var AUTHORITY_OPENER = /^(?:[-+.\uFFFFa-zA-Z0-9]+:\/\/|\/\/)/;
10228
+ function originEndOf(flattened) {
10229
+ const opener = AUTHORITY_OPENER.exec(flattened);
10230
+ if (opener === null) {
10231
+ return 0;
10232
+ }
10233
+ const slash = flattened.indexOf("/", opener[0].length);
10234
+ return slash === -1 ? flattened.length : slash;
10235
+ }
10236
+ function appendPathText(path12, text) {
10237
+ const idx = text.search(/[?#]/);
10238
+ if (idx === -1) {
10239
+ return { path: path12 + text, stop: false };
10240
+ }
10241
+ return { path: path12 + text.slice(0, idx), stop: true };
10242
+ }
10243
+ function parseAbsoluteUrl(text) {
10244
+ try {
10245
+ return new URL(text);
10246
+ } catch {
10247
+ }
10248
+ if (!PROTOCOL_RELATIVE.test(text)) {
10249
+ return void 0;
10250
+ }
10251
+ try {
10252
+ return new URL(`https:${text}`);
10253
+ } catch {
10254
+ return void 0;
10255
+ }
10256
+ }
10257
+ function pathnameOfAbsoluteLiteral(text) {
10258
+ const parsed = parseAbsoluteUrl(text);
10259
+ if (parsed !== void 0) {
10260
+ return parsed.pathname;
10261
+ }
10262
+ return stripQueryAndFragment(stripOriginManually(text));
10263
+ }
10264
+ function pathFromLiteralUrl(text) {
10265
+ const path12 = isAbsoluteUrlLiteral(text) ? pathnameOfAbsoluteLiteral(text) : stripQueryAndFragment(text);
10266
+ return path12 === "" ? void 0 : path12;
10267
+ }
10268
+ function pathFromTemplateUrl(arg, resolution) {
10269
+ const headText = arg.getHead().getLiteralText();
10270
+ const spans = arg.getTemplateSpans();
10271
+ const tails = spans.map((span) => span.getLiteral().getLiteralText());
10272
+ const originEnd = originEndOf([headText, ...tails].join(SUBSTITUTION));
10273
+ const head = appendPathText("", headText.slice(originEnd));
10274
+ let path12 = head.path;
10275
+ let stop = head.stop;
10276
+ let at = headText.length;
10277
+ for (let i = 0; i < spans.length && !stop; i++) {
10278
+ const span = spans[i];
10279
+ const tailText = tails[i];
10280
+ if (span === void 0 || tailText === void 0) {
10281
+ continue;
10282
+ }
10283
+ if (at >= originEnd) {
10284
+ path12 += holeText(span.getExpression(), resolution);
10285
+ }
10286
+ at += SUBSTITUTION.length;
10287
+ const appended = appendPathText(
10288
+ path12,
10289
+ tailText.slice(Math.max(0, originEnd - at))
10290
+ );
10291
+ path12 = appended.path;
10292
+ stop = appended.stop;
10293
+ at += tailText.length;
10294
+ }
10295
+ return path12 === "" ? void 0 : path12;
10296
+ }
10297
+ function pathFromUrlNode(node, resolution) {
10298
+ if (Node46.isStringLiteral(node)) {
10299
+ return pathFromLiteralUrl(node.getLiteralValue());
10300
+ }
10301
+ if (Node46.isNoSubstitutionTemplateLiteral(node)) {
10302
+ return pathFromLiteralUrl(node.getLiteralValue());
10303
+ }
10304
+ if (Node46.isTemplateExpression(node)) {
10305
+ return pathFromTemplateUrl(node, resolution);
10306
+ }
10307
+ return void 0;
10308
+ }
10309
+ function placeholderName(expr) {
10310
+ if (Node46.isIdentifier(expr)) {
10311
+ return expr.getText();
10312
+ }
10313
+ if (Node46.isPropertyAccessExpression(expr)) {
10314
+ return expr.getName();
10315
+ }
10316
+ return "param";
10317
+ }
10318
+ function holeText(expr, resolution) {
10319
+ const written = resolution?.resolveWrittenValue(expr) ?? null;
10320
+ if (written === null) {
10321
+ return patternHole2(placeholderName(expr));
10322
+ }
10323
+ if (emptyStringLiteral(written)) {
10324
+ return "";
10325
+ }
10326
+ return pathFromUrlNode(written, resolution) ?? patternHole2(placeholderName(expr));
10327
+ }
10328
+ function emptyStringLiteral(node) {
10329
+ return (Node46.isStringLiteral(node) || Node46.isNoSubstitutionTemplateLiteral(node)) && node.getLiteralValue() === "";
10330
+ }
10331
+ function pathFromArgument(arg, resolution) {
10332
+ const written = pathFromUrlNode(arg, resolution);
10333
+ if (written !== void 0) {
10334
+ return written;
10335
+ }
10336
+ const resolved = resolution?.resolveWrittenValue(arg) ?? null;
10337
+ return resolved !== null ? pathFromUrlNode(resolved, resolution) : void 0;
10338
+ }
10339
+
10340
+ // src/discovery/registrationCall.ts
10003
10341
  function discoverRegistrationCalls(sourceFile, match, kind, bindingExtraction, resolution, mountPrefixes) {
10004
10342
  const results = [];
10005
10343
  const registrationSubjects = registrationSubjectsOf(
@@ -10014,11 +10352,11 @@ function discoverRegistrationCalls(sourceFile, match, kind, bindingExtraction, r
10014
10352
  (c) => c.startsWith(".") ? c.slice(1) : c
10015
10353
  );
10016
10354
  sourceFile.forEachDescendant((node) => {
10017
- if (!Node46.isCallExpression(node)) {
10355
+ if (!Node47.isCallExpression(node)) {
10018
10356
  return;
10019
10357
  }
10020
10358
  const callee = node.getExpression();
10021
- if (!Node46.isPropertyAccessExpression(callee)) {
10359
+ if (!Node47.isPropertyAccessExpression(callee)) {
10022
10360
  return;
10023
10361
  }
10024
10362
  const methodName = callee.getName();
@@ -10026,7 +10364,7 @@ function discoverRegistrationCalls(sourceFile, match, kind, bindingExtraction, r
10026
10364
  return;
10027
10365
  }
10028
10366
  const subject = callee.getExpression();
10029
- const subjectName = Node46.isIdentifier(subject) ? subject.getText() : null;
10367
+ const subjectName = Node47.isIdentifier(subject) ? subject.getText() : null;
10030
10368
  const subjectNode = subjectName === null ? void 0 : registrationSubjects.get(subjectName);
10031
10369
  if (subjectNode === void 0) {
10032
10370
  return;
@@ -10034,12 +10372,12 @@ function discoverRegistrationCalls(sourceFile, match, kind, bindingExtraction, r
10034
10372
  const args = node.getArguments();
10035
10373
  let foundObjectArg = false;
10036
10374
  for (const arg of args) {
10037
- if (!Node46.isObjectLiteralExpression(arg)) {
10375
+ if (!Node47.isObjectLiteralExpression(arg)) {
10038
10376
  continue;
10039
10377
  }
10040
10378
  foundObjectArg = true;
10041
10379
  for (const prop of arg.getProperties()) {
10042
- if (Node46.isMethodDeclaration(prop)) {
10380
+ if (Node47.isMethodDeclaration(prop)) {
10043
10381
  results.push({
10044
10382
  func: prop,
10045
10383
  kind,
@@ -10047,7 +10385,7 @@ function discoverRegistrationCalls(sourceFile, match, kind, bindingExtraction, r
10047
10385
  });
10048
10386
  continue;
10049
10387
  }
10050
- if (!Node46.isPropertyAssignment(prop)) {
10388
+ if (!Node47.isPropertyAssignment(prop)) {
10051
10389
  continue;
10052
10390
  }
10053
10391
  const propInit = prop.getInitializer();
@@ -10145,9 +10483,9 @@ function registrationSubjectsOf(sourceFile, importModule, importName) {
10145
10483
  continue;
10146
10484
  }
10147
10485
  let calleeText = null;
10148
- if (Node46.isCallExpression(init)) {
10486
+ if (Node47.isCallExpression(init)) {
10149
10487
  calleeText = init.getExpression().getText();
10150
- } else if (Node46.isNewExpression(init)) {
10488
+ } else if (Node47.isNewExpression(init)) {
10151
10489
  calleeText = init.getExpression().getText();
10152
10490
  }
10153
10491
  if (calleeText === importedLocalName) {
@@ -10155,7 +10493,7 @@ function registrationSubjectsOf(sourceFile, importModule, importName) {
10155
10493
  }
10156
10494
  }
10157
10495
  sourceFile.forEachDescendant((node) => {
10158
- if (!Node46.isParameterDeclaration(node)) {
10496
+ if (!Node47.isParameterDeclaration(node)) {
10159
10497
  return;
10160
10498
  }
10161
10499
  const typeNode = node.getTypeNode();
@@ -10199,21 +10537,21 @@ function discoverMountEdges(sourceFile, match, mount, knownSubjectIds, resolutio
10199
10537
  }
10200
10538
  const edges = [];
10201
10539
  sourceFile.forEachDescendant((node) => {
10202
- if (!Node46.isCallExpression(node)) {
10540
+ if (!Node47.isCallExpression(node)) {
10203
10541
  return;
10204
10542
  }
10205
10543
  const callee = node.getExpression();
10206
- if (!Node46.isPropertyAccessExpression(callee) || callee.getName() !== mount.method) {
10544
+ if (!Node47.isPropertyAccessExpression(callee) || callee.getName() !== mount.method) {
10207
10545
  return;
10208
10546
  }
10209
10547
  const subject = callee.getExpression();
10210
- const subjectNode = Node46.isIdentifier(subject) ? subjects.get(subject.getText()) : void 0;
10548
+ const subjectNode = Node47.isIdentifier(subject) ? subjects.get(subject.getText()) : void 0;
10211
10549
  if (subjectNode === void 0) {
10212
10550
  return;
10213
10551
  }
10214
10552
  const args = node.getArguments();
10215
10553
  const prefixArg = args[mount.prefixPosition];
10216
- if (prefixArg === void 0 || !(Node46.isStringLiteral(prefixArg) || Node46.isNoSubstitutionTemplateLiteral(prefixArg))) {
10554
+ if (prefixArg === void 0 || !(Node47.isStringLiteral(prefixArg) || Node47.isNoSubstitutionTemplateLiteral(prefixArg))) {
10217
10555
  return;
10218
10556
  }
10219
10557
  const targetNodes = mountTargetsAmong(
@@ -10247,15 +10585,15 @@ function mountTargetsAmong(args, targetPosition, knownSubjectIds, resolution) {
10247
10585
  return targets;
10248
10586
  }
10249
10587
  function stringProperty(obj, name) {
10250
- if (!Node46.isObjectLiteralExpression(obj)) {
10588
+ if (!Node47.isObjectLiteralExpression(obj)) {
10251
10589
  return null;
10252
10590
  }
10253
10591
  const property = obj.getProperty(name);
10254
- if (property === void 0 || !Node46.isPropertyAssignment(property)) {
10592
+ if (property === void 0 || !Node47.isPropertyAssignment(property)) {
10255
10593
  return null;
10256
10594
  }
10257
10595
  const value = property.getInitializer();
10258
- if (value !== void 0 && (Node46.isStringLiteral(value) || Node46.isNoSubstitutionTemplateLiteral(value))) {
10596
+ if (value !== void 0 && (Node47.isStringLiteral(value) || Node47.isNoSubstitutionTemplateLiteral(value))) {
10259
10597
  return value.getLiteralValue();
10260
10598
  }
10261
10599
  return null;
@@ -10271,40 +10609,37 @@ function extractRouteInfoFromBinding(call, methodName, binding, resolution) {
10271
10609
  return null;
10272
10610
  }
10273
10611
  const method2 = stringProperty(routeObject, binding.method.property);
10274
- const path12 = stringProperty(routeObject, binding.path.property);
10275
- if (method2 === null || path12 === null) {
10612
+ const path13 = stringProperty(routeObject, binding.path.property);
10613
+ if (method2 === null || path13 === null) {
10276
10614
  return null;
10277
10615
  }
10278
- return { method: method2.toUpperCase(), path: path12 };
10616
+ return { method: method2.toUpperCase(), path: path13 };
10279
10617
  }
10280
- if (binding.method.type !== "fromRegistration" || binding.path.type !== "fromRegistration") {
10618
+ if (binding.method.type !== "fromRegistration" || binding.path.type !== "fromArgument") {
10281
10619
  return null;
10282
10620
  }
10283
10621
  let method;
10284
10622
  if (binding.method.position === "methodName") {
10285
10623
  method = binding.method.nameMap?.[methodName] ?? methodName.toUpperCase();
10286
10624
  } else {
10287
- const args2 = call.getArguments();
10288
- const arg = args2[binding.method.position];
10289
- if (arg === void 0 || !(Node46.isStringLiteral(arg) || Node46.isNoSubstitutionTemplateLiteral(arg))) {
10625
+ const args = call.getArguments();
10626
+ const arg = args[binding.method.position];
10627
+ if (arg === void 0 || !(Node47.isStringLiteral(arg) || Node47.isNoSubstitutionTemplateLiteral(arg))) {
10290
10628
  return null;
10291
10629
  }
10292
10630
  method = arg.getLiteralValue().toUpperCase();
10293
10631
  }
10294
- const args = call.getArguments();
10295
- const pathArg = args[binding.path.position];
10296
- if (pathArg === void 0 || !(Node46.isStringLiteral(pathArg) || Node46.isNoSubstitutionTemplateLiteral(pathArg))) {
10297
- return null;
10298
- }
10299
- return { method, path: pathArg.getLiteralValue() };
10632
+ const pathArg = call.getArguments()[binding.path.position];
10633
+ const path12 = pathArg === void 0 ? void 0 : pathFromArgument(pathArg, resolution);
10634
+ return path12 === void 0 ? null : { method, path: path12 };
10300
10635
  }
10301
10636
 
10302
10637
  // src/discovery/registrationLoop.ts
10303
- import { Node as Node47 } from "ts-morph";
10638
+ import { Node as Node48 } from "ts-morph";
10304
10639
  function discoverRegistrationLoops(sourceFile, match, kind, resolution) {
10305
10640
  const results = [];
10306
10641
  sourceFile.forEachDescendant((node) => {
10307
- if (!Node47.isForOfStatement(node)) {
10642
+ if (!Node48.isForOfStatement(node)) {
10308
10643
  return;
10309
10644
  }
10310
10645
  const expanded = tryExpandLoop(node, match, kind, resolution);
@@ -10347,13 +10682,13 @@ function tryExpandLoop(loop, match, kind, resolution) {
10347
10682
  }
10348
10683
  function loopVariableName(loop) {
10349
10684
  const initializer = loop.getInitializer();
10350
- if (Node47.isVariableDeclarationList(initializer)) {
10685
+ if (Node48.isVariableDeclarationList(initializer)) {
10351
10686
  const decls = initializer.getDeclarations();
10352
10687
  if (decls.length !== 1) {
10353
10688
  return null;
10354
10689
  }
10355
10690
  const nameNode = decls[0]?.getNameNode();
10356
- if (nameNode !== void 0 && Node47.isIdentifier(nameNode)) {
10691
+ if (nameNode !== void 0 && Node48.isIdentifier(nameNode)) {
10357
10692
  return nameNode.getText();
10358
10693
  }
10359
10694
  }
@@ -10366,14 +10701,14 @@ function bodyReferencesLoopVar(loop, name) {
10366
10701
  if (referenced) {
10367
10702
  return;
10368
10703
  }
10369
- if (!Node47.isCallExpression(node)) {
10704
+ if (!Node48.isCallExpression(node)) {
10370
10705
  return;
10371
10706
  }
10372
10707
  node.forEachDescendant((inner) => {
10373
10708
  if (referenced) {
10374
10709
  return;
10375
10710
  }
10376
- if (Node47.isIdentifier(inner) && inner.getText() === name) {
10711
+ if (Node48.isIdentifier(inner) && inner.getText() === name) {
10377
10712
  referenced = true;
10378
10713
  }
10379
10714
  });
@@ -10385,11 +10720,11 @@ function readRouteSpec(element, shape, resolution) {
10385
10720
  let path12 = null;
10386
10721
  let handler = null;
10387
10722
  for (const prop of element.getProperties()) {
10388
- if (Node47.isMethodDeclaration(prop) && prop.getName() === shape.handlerKey) {
10723
+ if (Node48.isMethodDeclaration(prop) && prop.getName() === shape.handlerKey) {
10389
10724
  handler = { func: prop, name: shape.handlerKey };
10390
10725
  continue;
10391
10726
  }
10392
- if (!Node47.isPropertyAssignment(prop)) {
10727
+ if (!Node48.isPropertyAssignment(prop)) {
10393
10728
  continue;
10394
10729
  }
10395
10730
  const name = prop.getName();
@@ -10412,17 +10747,17 @@ function readRouteSpec(element, shape, resolution) {
10412
10747
  return { method, path: path12, handler: handler.func, handlerName: handler.name };
10413
10748
  }
10414
10749
  function readStringLiteralValue(node) {
10415
- if (Node47.isStringLiteral(node) || Node47.isNoSubstitutionTemplateLiteral(node)) {
10750
+ if (Node48.isStringLiteral(node) || Node48.isNoSubstitutionTemplateLiteral(node)) {
10416
10751
  return node.getLiteralValue();
10417
10752
  }
10418
10753
  return null;
10419
10754
  }
10420
10755
  function handlerName(value) {
10421
- return Node47.isIdentifier(value) ? value.getText() : value.getKindName();
10756
+ return Node48.isIdentifier(value) ? value.getText() : value.getKindName();
10422
10757
  }
10423
10758
 
10424
10759
  // src/discovery/registrationTemplate.ts
10425
- import { Node as Node48 } from "ts-morph";
10760
+ import { Node as Node49 } from "ts-morph";
10426
10761
  function discoverRegistrationTemplates(sourceFile, match, kind, resolution) {
10427
10762
  const localName = resolveImportedLocalName2(sourceFile, match);
10428
10763
  if (localName === null) {
@@ -10430,7 +10765,7 @@ function discoverRegistrationTemplates(sourceFile, match, kind, resolution) {
10430
10765
  }
10431
10766
  const results = [];
10432
10767
  sourceFile.forEachDescendant((node) => {
10433
- if (!Node48.isCallExpression(node)) {
10768
+ if (!Node49.isCallExpression(node)) {
10434
10769
  return;
10435
10770
  }
10436
10771
  if (!isCallToHelper(node, localName)) {
@@ -10481,7 +10816,7 @@ function resolveImportedLocalName2(sourceFile, match) {
10481
10816
  }
10482
10817
  function isCallToHelper(call, localName) {
10483
10818
  const callee = call.getExpression();
10484
- return Node48.isIdentifier(callee) && callee.getText() === localName;
10819
+ return Node49.isIdentifier(callee) && callee.getText() === localName;
10485
10820
  }
10486
10821
  function substitutePath(template, args) {
10487
10822
  const re = /\{(\d+)\}/g;
@@ -10507,7 +10842,7 @@ function substitutePath(template, args) {
10507
10842
  return result;
10508
10843
  }
10509
10844
  function readStringLiteral(node) {
10510
- if (Node48.isStringLiteral(node) || Node48.isNoSubstitutionTemplateLiteral(node)) {
10845
+ if (Node49.isStringLiteral(node) || Node49.isNoSubstitutionTemplateLiteral(node)) {
10511
10846
  return node.getLiteralValue();
10512
10847
  }
10513
10848
  return null;
@@ -10530,7 +10865,7 @@ function resolveHandler(template, args, resolution) {
10530
10865
  return readPropertyAsFunction(arg, prop, resolution);
10531
10866
  }
10532
10867
  function handlerName2(value) {
10533
- return Node48.isIdentifier(value) ? value.getText() : value.getKindName();
10868
+ return Node49.isIdentifier(value) ? value.getText() : value.getKindName();
10534
10869
  }
10535
10870
  function readPropertyAsFunction(arg, prop, resolution) {
10536
10871
  const obj = objectLiteralOf(arg, resolution);
@@ -10541,7 +10876,7 @@ function readPropertyAsFunction(arg, prop, resolution) {
10541
10876
  if (propertyName2(property) !== prop) {
10542
10877
  continue;
10543
10878
  }
10544
- if (Node48.isMethodDeclaration(property)) {
10879
+ if (Node49.isMethodDeclaration(property)) {
10545
10880
  return { func: property, name: prop };
10546
10881
  }
10547
10882
  const held = propertyValueOf(property);
@@ -10549,19 +10884,19 @@ function readPropertyAsFunction(arg, prop, resolution) {
10549
10884
  return null;
10550
10885
  }
10551
10886
  const func = functionValueOf(held, resolution);
10552
- return func === null ? null : { func, name: Node48.isIdentifier(held) ? held.getText() : prop };
10887
+ return func === null ? null : { func, name: Node49.isIdentifier(held) ? held.getText() : prop };
10553
10888
  }
10554
10889
  return null;
10555
10890
  }
10556
10891
  function propertyName2(property) {
10557
- if (Node48.isPropertyAssignment(property) || Node48.isShorthandPropertyAssignment(property) || Node48.isMethodDeclaration(property)) {
10892
+ if (Node49.isPropertyAssignment(property) || Node49.isShorthandPropertyAssignment(property) || Node49.isMethodDeclaration(property)) {
10558
10893
  return property.getName();
10559
10894
  }
10560
10895
  return null;
10561
10896
  }
10562
10897
 
10563
10898
  // src/discovery/resolverMap.ts
10564
- import { Node as Node49 } from "ts-morph";
10899
+ import { Node as Node50 } from "ts-morph";
10565
10900
  function discoverResolverMaps(sourceFile, match, kind, resolution) {
10566
10901
  const localName = resolveImportedLocalName(
10567
10902
  sourceFile,
@@ -10575,15 +10910,15 @@ function discoverResolverMaps(sourceFile, match, kind, resolution) {
10575
10910
  const excludeTypes = new Set(match.excludeTypes ?? []);
10576
10911
  const results = [];
10577
10912
  sourceFile.forEachDescendant((node) => {
10578
- if (!Node49.isCallExpression(node) && !Node49.isNewExpression(node)) {
10913
+ if (!Node50.isCallExpression(node) && !Node50.isNewExpression(node)) {
10579
10914
  return;
10580
10915
  }
10581
10916
  const callee = node.getExpression();
10582
- if (!Node49.isIdentifier(callee) || callee.getText() !== localName) {
10917
+ if (!Node50.isIdentifier(callee) || callee.getText() !== localName) {
10583
10918
  return;
10584
10919
  }
10585
10920
  const args = node.getArguments();
10586
- if (args.length === 0 || !Node49.isObjectLiteralExpression(args[0])) {
10921
+ if (args.length === 0 || !Node50.isObjectLiteralExpression(args[0])) {
10587
10922
  return;
10588
10923
  }
10589
10924
  const config = args[0];
@@ -10637,7 +10972,7 @@ function resolverMapObject(prop, resolution) {
10637
10972
  return held === null ? null : objectLiteralOf(held, resolution);
10638
10973
  }
10639
10974
  function extractTypeDefsSdl(config, resolution) {
10640
- if (!Node49.isObjectLiteralExpression(config)) {
10975
+ if (!Node50.isObjectLiteralExpression(config)) {
10641
10976
  return null;
10642
10977
  }
10643
10978
  const prop = config.getProperty("typeDefs");
@@ -10659,15 +10994,15 @@ function schemaSdlOf(expr, resolution) {
10659
10994
  return resolved === null ? null : writtenSdl(resolved);
10660
10995
  }
10661
10996
  function writtenSdl(expr) {
10662
- if (Node49.isStringLiteral(expr) || Node49.isNoSubstitutionTemplateLiteral(expr)) {
10997
+ if (Node50.isStringLiteral(expr) || Node50.isNoSubstitutionTemplateLiteral(expr)) {
10663
10998
  const value = expr.getLiteralValue();
10664
10999
  return value === "" ? null : value;
10665
11000
  }
10666
- if (Node49.isTaggedTemplateExpression(expr)) {
11001
+ if (Node50.isTaggedTemplateExpression(expr)) {
10667
11002
  const tag = expr.getTag();
10668
- if (Node49.isIdentifier(tag) && tag.getText() === "gql") {
11003
+ if (Node50.isIdentifier(tag) && tag.getText() === "gql") {
10669
11004
  const template = expr.getTemplate();
10670
- if (Node49.isNoSubstitutionTemplateLiteral(template)) {
11005
+ if (Node50.isNoSubstitutionTemplateLiteral(template)) {
10671
11006
  return template.getLiteralValue();
10672
11007
  }
10673
11008
  }
@@ -10675,16 +11010,16 @@ function writtenSdl(expr) {
10675
11010
  return null;
10676
11011
  }
10677
11012
  function resolverPropertyName(prop) {
10678
- if (Node49.isPropertyAssignment(prop) || Node49.isMethodDeclaration(prop)) {
11013
+ if (Node50.isPropertyAssignment(prop) || Node50.isMethodDeclaration(prop)) {
10679
11014
  return prop.getName();
10680
11015
  }
10681
- if (Node49.isShorthandPropertyAssignment(prop)) {
11016
+ if (Node50.isShorthandPropertyAssignment(prop)) {
10682
11017
  return prop.getName();
10683
11018
  }
10684
11019
  return null;
10685
11020
  }
10686
11021
  function resolverPropertyFunction(prop, resolution) {
10687
- if (Node49.isMethodDeclaration(prop)) {
11022
+ if (Node50.isMethodDeclaration(prop)) {
10688
11023
  return prop;
10689
11024
  }
10690
11025
  const held = propertyValueOf(prop);
@@ -10945,7 +11280,7 @@ function resolvePrefix(edgesByChild, memo, childId, visiting) {
10945
11280
  }
10946
11281
 
10947
11282
  // src/discoveryContext.ts
10948
- import { Node as Node50 } from "ts-morph";
11283
+ import { Node as Node51 } from "ts-morph";
10949
11284
  function createTsDiscoveryContext(resolution) {
10950
11285
  return {
10951
11286
  getFilePath,
@@ -10977,7 +11312,7 @@ function exportedFunctions(sourceFile, resolution) {
10977
11312
  return out;
10978
11313
  }
10979
11314
  function exportedFunction(decl, resolution) {
10980
- const writtenAgain = Node50.isVariableDeclaration(decl) && isWrittenAgain(decl);
11315
+ const writtenAgain = Node51.isVariableDeclaration(decl) && isWrittenAgain(decl);
10981
11316
  if (!writtenAgain) {
10982
11317
  const declared = resolveDeclarationToFunction(decl);
10983
11318
  if (declared !== null) {
@@ -10998,7 +11333,7 @@ function valueToAskAbout(decl, writtenAgain) {
10998
11333
  if (writtenAgain) {
10999
11334
  return decl;
11000
11335
  }
11001
- const value = Node50.isVariableDeclaration(decl) ? decl.getInitializer() ?? decl : decl;
11336
+ const value = Node51.isVariableDeclaration(decl) ? decl.getInitializer() ?? decl : decl;
11002
11337
  return couldStillNameAFunction(value) ? value : null;
11003
11338
  }
11004
11339
  function exportedCallConfigString(sourceFile, exportName, spec, resolution) {
@@ -11008,11 +11343,11 @@ function exportedCallConfigString(sourceFile, exportName, spec, resolution) {
11008
11343
  }
11009
11344
  const found = /* @__PURE__ */ new Set();
11010
11345
  for (const decl of declarations) {
11011
- if (!Node50.isVariableDeclaration(decl)) {
11346
+ if (!Node51.isVariableDeclaration(decl)) {
11012
11347
  continue;
11013
11348
  }
11014
11349
  const init = peelExpression(decl.getInitializer());
11015
- if (init === void 0 || !Node50.isCallExpression(init)) {
11350
+ if (init === void 0 || !Node51.isCallExpression(init)) {
11016
11351
  continue;
11017
11352
  }
11018
11353
  if (!calleeIsNamed(init.getExpression(), spec.callees)) {
@@ -11031,7 +11366,7 @@ function calleeIsNamed(callee, names) {
11031
11366
  if (names === void 0 || names.length === 0) {
11032
11367
  return true;
11033
11368
  }
11034
- return Node50.isIdentifier(callee) && names.includes(callee.getText());
11369
+ return Node51.isIdentifier(callee) && names.includes(callee.getText());
11035
11370
  }
11036
11371
  function configArguments(args, argIndex) {
11037
11372
  if (argIndex === void 0) {
@@ -11046,18 +11381,18 @@ function configString(arg, property, resolution) {
11046
11381
  return null;
11047
11382
  }
11048
11383
  const prop = config.getProperty(property);
11049
- if (prop === void 0 || !Node50.isPropertyAssignment(prop)) {
11384
+ if (prop === void 0 || !Node51.isPropertyAssignment(prop)) {
11050
11385
  return null;
11051
11386
  }
11052
11387
  const value = peelExpression(prop.getInitializer());
11053
- if (value !== void 0 && Node50.isStringLiteral(value)) {
11388
+ if (value !== void 0 && Node51.isStringLiteral(value)) {
11054
11389
  return value.getLiteralValue();
11055
11390
  }
11056
11391
  return null;
11057
11392
  }
11058
11393
  function peelExpression(node) {
11059
11394
  let current2 = node;
11060
- while (current2 !== void 0 && (Node50.isAsExpression(current2) || Node50.isSatisfiesExpression(current2) || Node50.isParenthesizedExpression(current2) || Node50.isNonNullExpression(current2))) {
11395
+ while (current2 !== void 0 && (Node51.isAsExpression(current2) || Node51.isSatisfiesExpression(current2) || Node51.isParenthesizedExpression(current2) || Node51.isNonNullExpression(current2))) {
11061
11396
  current2 = current2.getExpression();
11062
11397
  }
11063
11398
  return current2;
@@ -11067,14 +11402,14 @@ function toObjectLiteral(node, resolution) {
11067
11402
  if (peeled === void 0) {
11068
11403
  return null;
11069
11404
  }
11070
- if (Node50.isObjectLiteralExpression(peeled)) {
11405
+ if (Node51.isObjectLiteralExpression(peeled)) {
11071
11406
  return peeled;
11072
11407
  }
11073
11408
  if (resolution === void 0) {
11074
11409
  return null;
11075
11410
  }
11076
11411
  const resolved = resolution.resolveObject(peeled);
11077
- if (resolved !== null && Node50.isObjectLiteralExpression(resolved)) {
11412
+ if (resolved !== null && Node51.isObjectLiteralExpression(resolved)) {
11078
11413
  return resolved;
11079
11414
  }
11080
11415
  return null;
@@ -11084,18 +11419,18 @@ function resolveDeclarationToFunction(decl) {
11084
11419
  if (fn !== null) {
11085
11420
  return fn;
11086
11421
  }
11087
- if (Node50.isVariableDeclaration(decl)) {
11422
+ if (Node51.isVariableDeclaration(decl)) {
11088
11423
  const init = decl.getInitializer();
11089
- if (init !== void 0 && (Node50.isArrowFunction(init) || Node50.isFunctionExpression(init))) {
11424
+ if (init !== void 0 && (Node51.isArrowFunction(init) || Node51.isFunctionExpression(init))) {
11090
11425
  return init;
11091
11426
  }
11092
11427
  }
11093
11428
  return null;
11094
11429
  }
11095
11430
  function hasJsxReturn(func) {
11096
- if (Node50.isArrowFunction(func)) {
11431
+ if (Node51.isArrowFunction(func)) {
11097
11432
  const body2 = func.getBody();
11098
- if (Node50.isExpression(body2) && isJsxOrFragment(body2)) {
11433
+ if (Node51.isExpression(body2) && isJsxOrFragment(body2)) {
11099
11434
  return true;
11100
11435
  }
11101
11436
  }
@@ -11109,11 +11444,11 @@ function hasJsxReturn(func) {
11109
11444
  traversal.stop();
11110
11445
  return;
11111
11446
  }
11112
- if (node !== func && (Node50.isFunctionDeclaration(node) || Node50.isFunctionExpression(node) || Node50.isArrowFunction(node) || Node50.isMethodDeclaration(node))) {
11447
+ if (node !== func && (Node51.isFunctionDeclaration(node) || Node51.isFunctionExpression(node) || Node51.isArrowFunction(node) || Node51.isMethodDeclaration(node))) {
11113
11448
  traversal.skip();
11114
11449
  return;
11115
11450
  }
11116
- if (Node50.isReturnStatement(node)) {
11451
+ if (Node51.isReturnStatement(node)) {
11117
11452
  const expr = node.getExpression();
11118
11453
  if (expr !== void 0 && isJsxOrFragment(expr)) {
11119
11454
  found = true;
@@ -11124,14 +11459,14 @@ function hasJsxReturn(func) {
11124
11459
  }
11125
11460
  function isJsxOrFragment(node) {
11126
11461
  let current2 = node;
11127
- while (Node50.isParenthesizedExpression(current2)) {
11462
+ while (Node51.isParenthesizedExpression(current2)) {
11128
11463
  current2 = current2.getExpression();
11129
11464
  }
11130
- return Node50.isJsxElement(current2) || Node50.isJsxSelfClosingElement(current2) || Node50.isJsxFragment(current2);
11465
+ return Node51.isJsxElement(current2) || Node51.isJsxSelfClosingElement(current2) || Node51.isJsxFragment(current2);
11131
11466
  }
11132
11467
 
11133
11468
  // src/facts/store.ts
11134
- import { Node as Node51 } from "ts-morph";
11469
+ import { Node as Node52 } from "ts-morph";
11135
11470
  import {
11136
11471
  clearRelations,
11137
11472
  Database as Database2,
@@ -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 (!Node51.isExpression(value)) {
11731
+ if (!Node52.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 || !Node52.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 = Node51.isPropertyAccessExpression(value) ? value.getNameNode() : value;
11861
+ const nameNode = Node52.isPropertyAccessExpression(value) ? value.getNameNode() : value;
11524
11862
  return nameNode.getSymbol()?.getDeclarations()[0] ?? value;
11525
11863
  }
11526
11864
 
@@ -11769,14 +12107,14 @@ function deriveBoundaryEffects(summaries, facts) {
11769
12107
  }
11770
12108
  const closureByEntry = /* @__PURE__ */ new Map();
11771
12109
  for (const [entry, kind, target] of db.facts("boundaryEffect")) {
11772
- const entryKey = String(entry);
11773
- const bucket = closureByEntry.get(entryKey) ?? [];
12110
+ const entryKey2 = String(entry);
12111
+ const bucket = closureByEntry.get(entryKey2) ?? [];
11774
12112
  bucket.push({
11775
12113
  kind: String(kind),
11776
12114
  target: String(target),
11777
- transitive: !(ownByEntry.get(entryKey)?.has(`${kind}\0${target}`) ?? false)
12115
+ transitive: !(ownByEntry.get(entryKey2)?.has(`${kind}\0${target}`) ?? false)
11778
12116
  });
11779
- closureByEntry.set(entryKey, bucket);
12117
+ closureByEntry.set(entryKey2, bucket);
11780
12118
  }
11781
12119
  for (const summary of summaries) {
11782
12120
  const key = unitKeyBySummary.get(summary);
@@ -11796,14 +12134,14 @@ function deriveBoundaryEffects(summaries, facts) {
11796
12134
  }
11797
12135
 
11798
12136
  // src/resolve/reachableClosure.ts
11799
- import { Node as Node53 } from "ts-morph";
12137
+ import { Node as Node54 } from "ts-morph";
11800
12138
  import { functionCallBinding } from "@suss/behavioral-ir";
11801
12139
  import { Database as Database3, evaluate as evaluate4, lit as lit4, rule as rule4, variable as variable2 } from "@suss/datalog";
11802
12140
  import { assembleSummary as assembleSummary2 } from "@suss/extractor";
11803
12141
 
11804
12142
  // src/resolve/unfollowedCall.ts
11805
12143
  import {
11806
- Node as Node52,
12144
+ Node as Node53,
11807
12145
  SyntaxKind as SyntaxKind11
11808
12146
  } from "ts-morph";
11809
12147
  function isInExternalCode(sourceFile) {
@@ -11813,19 +12151,19 @@ function isInExternalCode(sourceFile) {
11813
12151
  return sourceFile.getFilePath().includes("/node_modules/");
11814
12152
  }
11815
12153
  function hasBody(fn) {
11816
- if (Node52.isFunctionDeclaration(fn) || Node52.isMethodDeclaration(fn) || Node52.isFunctionExpression(fn)) {
12154
+ if (Node53.isFunctionDeclaration(fn) || Node53.isMethodDeclaration(fn) || Node53.isFunctionExpression(fn)) {
11817
12155
  return fn.getBody?.() !== void 0;
11818
12156
  }
11819
12157
  return true;
11820
12158
  }
11821
12159
  function isDeclaredShape(declaration) {
11822
- return (Node52.isMethodSignature(declaration) || Node52.isPropertySignature(declaration)) && !isInExternalCode(declaration.getSourceFile());
12160
+ return (Node53.isMethodSignature(declaration) || Node53.isPropertySignature(declaration)) && !isInExternalCode(declaration.getSourceFile());
11823
12161
  }
11824
12162
  function isExternalDeclaration(declaration) {
11825
12163
  if (isInExternalCode(declaration.getSourceFile())) {
11826
12164
  return true;
11827
12165
  }
11828
- if (Node52.isImportSpecifier(declaration) || Node52.isImportClause(declaration) || Node52.isNamespaceImport(declaration)) {
12166
+ if (Node53.isImportSpecifier(declaration) || Node53.isImportClause(declaration) || Node53.isNamespaceImport(declaration)) {
11829
12167
  const target = declaration.getFirstAncestorByKind(SyntaxKind11.ImportDeclaration)?.getModuleSpecifierSourceFile();
11830
12168
  return target === void 0 || isInExternalCode(target);
11831
12169
  }
@@ -11835,16 +12173,16 @@ function declaresAnotherModule(declaration) {
11835
12173
  const module = declaration.getFirstAncestorByKind(
11836
12174
  SyntaxKind11.ModuleDeclaration
11837
12175
  );
11838
- return module !== void 0 && Node52.isStringLiteral(module.getNameNode());
12176
+ return module !== void 0 && Node53.isStringLiteral(module.getNameNode());
11839
12177
  }
11840
12178
  function statesShapeOnly(declaration) {
11841
12179
  if (isExternalDeclaration(declaration)) {
11842
12180
  return false;
11843
12181
  }
11844
- if (Node52.isMethodSignature(declaration) || Node52.isPropertySignature(declaration)) {
12182
+ if (Node53.isMethodSignature(declaration) || Node53.isPropertySignature(declaration)) {
11845
12183
  return true;
11846
12184
  }
11847
- if (Node52.isFunctionDeclaration(declaration) || Node52.isMethodDeclaration(declaration)) {
12185
+ if (Node53.isFunctionDeclaration(declaration) || Node53.isMethodDeclaration(declaration)) {
11848
12186
  return declaration.getBody() === void 0;
11849
12187
  }
11850
12188
  return false;
@@ -11934,9 +12272,9 @@ function resolveDecl(decl, calleeName) {
11934
12272
  }
11935
12273
  return { func: fn, name: declName(decl) ?? calleeName };
11936
12274
  }
11937
- if (Node53.isVariableDeclaration(decl)) {
12275
+ if (Node54.isVariableDeclaration(decl)) {
11938
12276
  const init = decl.getInitializer();
11939
- if (init !== void 0 && (Node53.isArrowFunction(init) || Node53.isFunctionExpression(init))) {
12277
+ if (init !== void 0 && (Node54.isArrowFunction(init) || Node54.isFunctionExpression(init))) {
11940
12278
  return { func: init, name: decl.getName() };
11941
12279
  }
11942
12280
  return null;
@@ -11944,26 +12282,26 @@ function resolveDecl(decl, calleeName) {
11944
12282
  return null;
11945
12283
  }
11946
12284
  function declName(decl) {
11947
- if (Node53.isFunctionDeclaration(decl) || Node53.isMethodDeclaration(decl)) {
12285
+ if (Node54.isFunctionDeclaration(decl) || Node54.isMethodDeclaration(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
- if (Node53.isFunctionExpression(decl)) {
12291
+ if (Node54.isFunctionExpression(decl)) {
11954
12292
  const n = decl.getName();
11955
12293
  if (typeof n === "string" && n.length > 0) {
11956
12294
  return n;
11957
12295
  }
11958
12296
  }
11959
12297
  const parent = decl.getParent();
11960
- if (parent !== void 0 && Node53.isVariableDeclaration(parent)) {
12298
+ if (parent !== void 0 && Node54.isVariableDeclaration(parent)) {
11961
12299
  return parent.getName();
11962
12300
  }
11963
12301
  return null;
11964
12302
  }
11965
12303
  function resolveCallee(call, calleeName, scan) {
11966
- if (!Node53.isCallExpression(call)) {
12304
+ if (!Node54.isCallExpression(call)) {
11967
12305
  return null;
11968
12306
  }
11969
12307
  const callee = call.getExpression();
@@ -11976,7 +12314,7 @@ function resolveCallee(call, calleeName, scan) {
11976
12314
  }
11977
12315
  }
11978
12316
  const resolveSources = scan.resolveCallableSources;
11979
- if (resolveSources !== void 0 && Node53.isPropertyAccessExpression(callee) && declarations.some(isDeclaredShape)) {
12317
+ if (resolveSources !== void 0 && Node54.isPropertyAccessExpression(callee) && declarations.some(isDeclaredShape)) {
11980
12318
  const sources = resolveSources(callee, scan.reachedFrom);
11981
12319
  const only = sources.length === 1 ? sources[0] : void 0;
11982
12320
  const resolved = only === void 0 ? null : resolveDecl(only, calleeName);
@@ -12003,7 +12341,7 @@ function collectReachable(func, scan) {
12003
12341
  const stops = [];
12004
12342
  const seen = /* @__PURE__ */ new Set();
12005
12343
  func.forEachDescendant((node) => {
12006
- if (!Node53.isCallExpression(node)) {
12344
+ if (!Node54.isCallExpression(node)) {
12007
12345
  return;
12008
12346
  }
12009
12347
  const calleeText = normalizeCallee(node.getExpression().getText());
@@ -12189,7 +12527,7 @@ function recordStops(stopsByKey, summariesByKey, options) {
12189
12527
  }
12190
12528
 
12191
12529
  // src/resolve/rethrowEnrichment.ts
12192
- import { Node as Node54 } from "ts-morph";
12530
+ import { Node as Node55 } from "ts-morph";
12193
12531
  import { Database as Database4, evaluate as evaluate5, lit as lit5, rule as rule5, variable as variable3 } from "@suss/datalog";
12194
12532
  var RETHROW_RULES = [
12195
12533
  rule5(
@@ -12329,7 +12667,7 @@ function findBareRethrow(func, location) {
12329
12667
  traversal.stop();
12330
12668
  return;
12331
12669
  }
12332
- if (!Node54.isThrowStatement(node)) {
12670
+ if (!Node55.isThrowStatement(node)) {
12333
12671
  return;
12334
12672
  }
12335
12673
  if (startLineOf(node) !== location.start) {
@@ -12339,7 +12677,7 @@ function findBareRethrow(func, location) {
12339
12677
  return;
12340
12678
  }
12341
12679
  const thrown = node.getExpression();
12342
- if (thrown !== void 0 && Node54.isIdentifier(thrown)) {
12680
+ if (thrown !== void 0 && Node55.isIdentifier(thrown)) {
12343
12681
  found = node;
12344
12682
  }
12345
12683
  });
@@ -12349,13 +12687,13 @@ function enclosingTry(throwStmt) {
12349
12687
  let current2 = throwStmt.getParent();
12350
12688
  let sawCatchClause = false;
12351
12689
  while (current2 !== void 0) {
12352
- if (Node54.isCatchClause(current2)) {
12690
+ if (Node55.isCatchClause(current2)) {
12353
12691
  sawCatchClause = true;
12354
12692
  }
12355
- if (Node54.isTryStatement(current2)) {
12693
+ if (Node55.isTryStatement(current2)) {
12356
12694
  return sawCatchClause ? current2 : null;
12357
12695
  }
12358
- if (Node54.isFunctionDeclaration(current2) || Node54.isFunctionExpression(current2) || Node54.isArrowFunction(current2) || Node54.isMethodDeclaration(current2)) {
12696
+ if (Node55.isFunctionDeclaration(current2) || Node55.isFunctionExpression(current2) || Node55.isArrowFunction(current2) || Node55.isMethodDeclaration(current2)) {
12359
12697
  return null;
12360
12698
  }
12361
12699
  current2 = current2.getParent();
@@ -12363,14 +12701,14 @@ function enclosingTry(throwStmt) {
12363
12701
  return null;
12364
12702
  }
12365
12703
  function collectTryBodyCallees(tryStmt, index, keyFor) {
12366
- if (!Node54.isTryStatement(tryStmt)) {
12704
+ if (!Node55.isTryStatement(tryStmt)) {
12367
12705
  return [];
12368
12706
  }
12369
12707
  const tryBlock = tryStmt.getTryBlock();
12370
12708
  const callees = [];
12371
12709
  const seen = /* @__PURE__ */ new Set();
12372
12710
  tryBlock.forEachDescendant((node) => {
12373
- if (!Node54.isCallExpression(node)) {
12711
+ if (!Node55.isCallExpression(node)) {
12374
12712
  return;
12375
12713
  }
12376
12714
  const calleeSummary = resolveCalleeSummary(node, index);
@@ -12387,7 +12725,7 @@ function collectTryBodyCallees(tryStmt, index, keyFor) {
12387
12725
  return callees;
12388
12726
  }
12389
12727
  function resolveCalleeSummary(call, index) {
12390
- if (!Node54.isCallExpression(call)) {
12728
+ if (!Node55.isCallExpression(call)) {
12391
12729
  return null;
12392
12730
  }
12393
12731
  const callee = call.getExpression();
@@ -12413,12 +12751,12 @@ function resolveCalleeSummary(call, index) {
12413
12751
  return null;
12414
12752
  }
12415
12753
  function functionFromDecl(decl) {
12416
- if (Node54.isFunctionDeclaration(decl) || Node54.isFunctionExpression(decl) || Node54.isArrowFunction(decl) || Node54.isMethodDeclaration(decl)) {
12754
+ if (Node55.isFunctionDeclaration(decl) || Node55.isFunctionExpression(decl) || Node55.isArrowFunction(decl) || Node55.isMethodDeclaration(decl)) {
12417
12755
  return decl;
12418
12756
  }
12419
- if (Node54.isVariableDeclaration(decl)) {
12757
+ if (Node55.isVariableDeclaration(decl)) {
12420
12758
  const init = decl.getInitializer();
12421
- if (init !== void 0 && (Node54.isArrowFunction(init) || Node54.isFunctionExpression(init))) {
12759
+ if (init !== void 0 && (Node55.isArrowFunction(init) || Node55.isFunctionExpression(init))) {
12422
12760
  return init;
12423
12761
  }
12424
12762
  }
@@ -12427,23 +12765,23 @@ function functionFromDecl(decl) {
12427
12765
 
12428
12766
  // src/shapes/fieldAccesses.ts
12429
12767
  import {
12430
- Node as Node55
12768
+ Node as Node56
12431
12769
  } from "ts-morph";
12432
12770
  function findResponseAccessor(callExpr) {
12433
12771
  let current2 = callExpr;
12434
12772
  const parent1 = current2.getParent();
12435
- if (parent1 !== void 0 && Node55.isAwaitExpression(parent1)) {
12773
+ if (parent1 !== void 0 && Node56.isAwaitExpression(parent1)) {
12436
12774
  current2 = parent1;
12437
12775
  }
12438
12776
  const parent2 = current2.getParent();
12439
- if (parent2 === void 0 || !Node55.isVariableDeclaration(parent2)) {
12777
+ if (parent2 === void 0 || !Node56.isVariableDeclaration(parent2)) {
12440
12778
  return null;
12441
12779
  }
12442
12780
  const nameNode = parent2.getNameNode();
12443
- if (Node55.isIdentifier(nameNode)) {
12781
+ if (Node56.isIdentifier(nameNode)) {
12444
12782
  return { kind: "identifier", name: nameNode.getText() };
12445
12783
  }
12446
- if (Node55.isObjectBindingPattern(nameNode)) {
12784
+ if (Node56.isObjectBindingPattern(nameNode)) {
12447
12785
  const bindings = /* @__PURE__ */ new Map();
12448
12786
  for (const element of nameNode.getElements()) {
12449
12787
  if (element.getDotDotDotToken() !== void 0) {
@@ -12464,11 +12802,11 @@ function findResponseAccessor(callExpr) {
12464
12802
  function buildThenChainAccessor(callExpr, func) {
12465
12803
  const bindings = /* @__PURE__ */ new Map();
12466
12804
  func.forEachDescendant((node) => {
12467
- if (!Node55.isParameterDeclaration(node)) {
12805
+ if (!Node56.isParameterDeclaration(node)) {
12468
12806
  return;
12469
12807
  }
12470
12808
  const nameNode = node.getNameNode();
12471
- if (!Node55.isIdentifier(nameNode)) {
12809
+ if (!Node56.isIdentifier(nameNode)) {
12472
12810
  return;
12473
12811
  }
12474
12812
  const prefix = prefixOfThenParam(node, callExpr, 0);
@@ -12500,7 +12838,7 @@ function prefixOfExpr(expr, responseCall, depth) {
12500
12838
  if (node === responseCall) {
12501
12839
  return [];
12502
12840
  }
12503
- if (Node55.isCallExpression(node)) {
12841
+ if (Node56.isCallExpression(node)) {
12504
12842
  const hop = thenLikeCall(node);
12505
12843
  if (hop !== null) {
12506
12844
  if (hop.method === "catch") {
@@ -12532,14 +12870,14 @@ function prefixOfMemberExpr(expr, responseCall, depth) {
12532
12870
  return null;
12533
12871
  }
12534
12872
  const decl = chain.root.getSymbol()?.getDeclarations()?.[0];
12535
- if (decl === void 0 || !Node55.isParameterDeclaration(decl)) {
12873
+ if (decl === void 0 || !Node56.isParameterDeclaration(decl)) {
12536
12874
  return null;
12537
12875
  }
12538
12876
  const base = prefixOfThenParam(decl, responseCall, depth + 1);
12539
12877
  return base === null ? null : [...base, ...chain.segments];
12540
12878
  }
12541
12879
  function firstCallbackParamName(callback) {
12542
- if (callback === void 0 || !(Node55.isArrowFunction(callback) || Node55.isFunctionExpression(callback))) {
12880
+ if (callback === void 0 || !(Node56.isArrowFunction(callback) || Node56.isFunctionExpression(callback))) {
12543
12881
  return null;
12544
12882
  }
12545
12883
  const param = callback.getParameters()[0];
@@ -12547,11 +12885,11 @@ function firstCallbackParamName(callback) {
12547
12885
  return null;
12548
12886
  }
12549
12887
  const nameNode = param.getNameNode();
12550
- return Node55.isIdentifier(nameNode) ? nameNode.getText() : null;
12888
+ return Node56.isIdentifier(nameNode) ? nameNode.getText() : null;
12551
12889
  }
12552
12890
  function unwrap2(expr) {
12553
12891
  let node = expr;
12554
- while (Node55.isAwaitExpression(node) || Node55.isParenthesizedExpression(node) || Node55.isAsExpression(node)) {
12892
+ while (Node56.isAwaitExpression(node) || Node56.isParenthesizedExpression(node) || Node56.isAsExpression(node)) {
12555
12893
  node = node.getExpression();
12556
12894
  }
12557
12895
  return node;
@@ -12561,15 +12899,15 @@ function chainRootedAt(expr, rootName) {
12561
12899
  if (chain === null) {
12562
12900
  return null;
12563
12901
  }
12564
- return Node55.isIdentifier(chain.root) && chain.root.getText() === rootName ? chain.segments : null;
12902
+ return Node56.isIdentifier(chain.root) && chain.root.getText() === rootName ? chain.segments : null;
12565
12903
  }
12566
12904
  function memberChain(expr) {
12567
- let node = Node55.isExpression(expr) ? unwrap2(expr) : expr;
12568
- if (Node55.isCallExpression(node)) {
12905
+ let node = Node56.isExpression(expr) ? unwrap2(expr) : expr;
12906
+ if (Node56.isCallExpression(node)) {
12569
12907
  node = node.getExpression();
12570
12908
  }
12571
12909
  const segments = [];
12572
- while (Node55.isPropertyAccessExpression(node)) {
12910
+ while (Node56.isPropertyAccessExpression(node)) {
12573
12911
  segments.unshift(node.getName());
12574
12912
  node = node.getExpression();
12575
12913
  }
@@ -12588,16 +12926,16 @@ function collectPropertyAccesses(subtree, accessor) {
12588
12926
  if (accessor.kind === "identifier") {
12589
12927
  const varName = accessor.name;
12590
12928
  subtree.forEachDescendant((node) => {
12591
- if (!Node55.isPropertyAccessExpression(node)) {
12929
+ if (!Node56.isPropertyAccessExpression(node)) {
12592
12930
  return;
12593
12931
  }
12594
12932
  const chain = [];
12595
12933
  let current2 = node;
12596
- while (Node55.isPropertyAccessExpression(current2)) {
12934
+ while (Node56.isPropertyAccessExpression(current2)) {
12597
12935
  chain.unshift(current2.getName());
12598
12936
  current2 = current2.getExpression();
12599
12937
  }
12600
- if (Node55.isIdentifier(current2) && current2.getText() === varName) {
12938
+ if (Node56.isIdentifier(current2) && current2.getText() === varName) {
12601
12939
  pushChain(chain);
12602
12940
  }
12603
12941
  });
@@ -12608,7 +12946,7 @@ function collectPropertyAccesses(subtree, accessor) {
12608
12946
  return source === void 0 ? void 0 : [source];
12609
12947
  } : (name) => accessor.bindings.get(name);
12610
12948
  subtree.forEachDescendant((node) => {
12611
- if (!Node55.isIdentifier(node)) {
12949
+ if (!Node56.isIdentifier(node)) {
12612
12950
  return;
12613
12951
  }
12614
12952
  const prefix = prefixOf(node.getText());
@@ -12620,13 +12958,13 @@ function collectPropertyAccesses(subtree, accessor) {
12620
12958
  }
12621
12959
  let chainTop = node;
12622
12960
  let parent = chainTop.getParent();
12623
- while (parent !== void 0 && Node55.isPropertyAccessExpression(parent) && parent.getExpression() === chainTop) {
12961
+ while (parent !== void 0 && Node56.isPropertyAccessExpression(parent) && parent.getExpression() === chainTop) {
12624
12962
  chainTop = parent;
12625
12963
  parent = chainTop.getParent();
12626
12964
  }
12627
12965
  const segments = [];
12628
12966
  let current2 = chainTop;
12629
- while (Node55.isPropertyAccessExpression(current2)) {
12967
+ while (Node56.isPropertyAccessExpression(current2)) {
12630
12968
  segments.push(current2.getName());
12631
12969
  current2 = current2.getExpression();
12632
12970
  }
@@ -12640,15 +12978,15 @@ function isBindingDeclarationSite(node) {
12640
12978
  return true;
12641
12979
  }
12642
12980
  const parent = node.getParent();
12643
- return parent !== void 0 && Node55.isParameterDeclaration(parent) && parent.getNameNode() === node;
12981
+ return parent !== void 0 && Node56.isParameterDeclaration(parent) && parent.getNameNode() === node;
12644
12982
  }
12645
12983
  function isInsideObjectBindingPattern(node) {
12646
12984
  let current2 = node.getParent();
12647
12985
  while (current2 !== void 0) {
12648
- if (Node55.isObjectBindingPattern(current2)) {
12986
+ if (Node56.isObjectBindingPattern(current2)) {
12649
12987
  return true;
12650
12988
  }
12651
- if (Node55.isFunctionLikeDeclaration(current2) || Node55.isVariableStatement(current2)) {
12989
+ if (Node56.isFunctionLikeDeclaration(current2) || Node56.isVariableStatement(current2)) {
12652
12990
  break;
12653
12991
  }
12654
12992
  current2 = current2.getParent();
@@ -12711,7 +13049,7 @@ function findBranchSubtree(func, byLineRange, terminalStartLine, terminalEndLine
12711
13049
  if (parent === void 0) {
12712
13050
  break;
12713
13051
  }
12714
- if (Node55.isIfStatement(parent)) {
13052
+ if (Node56.isIfStatement(parent)) {
12715
13053
  const ifStmt = parent;
12716
13054
  const thenBlock = ifStmt.getThenStatement();
12717
13055
  const elseBlock = ifStmt.getElseStatement();
@@ -12774,7 +13112,7 @@ function buildNonBodyPropertySet(semantics) {
12774
13112
 
12775
13113
  // src/subUnitContext.ts
12776
13114
  import {
12777
- Node as Node56
13115
+ Node as Node57
12778
13116
  } from "ts-morph";
12779
13117
  function createTsSubUnitContext() {
12780
13118
  return {
@@ -12788,7 +13126,7 @@ function createTsSubUnitContext() {
12788
13126
  }
12789
13127
  function skipNestedFunctions(parent) {
12790
13128
  return (node, traversal) => {
12791
- if (node !== parent && (Node56.isFunctionDeclaration(node) || Node56.isFunctionExpression(node) || Node56.isArrowFunction(node) || Node56.isMethodDeclaration(node))) {
13129
+ if (node !== parent && (Node57.isFunctionDeclaration(node) || Node57.isFunctionExpression(node) || Node57.isArrowFunction(node) || Node57.isMethodDeclaration(node))) {
12792
13130
  traversal.skip();
12793
13131
  return true;
12794
13132
  }
@@ -12802,18 +13140,18 @@ function findJsxAttributes(parent) {
12802
13140
  if (skip(node, traversal)) {
12803
13141
  return;
12804
13142
  }
12805
- if (!Node56.isJsxOpeningElement(node) && !Node56.isJsxSelfClosingElement(node)) {
13143
+ if (!Node57.isJsxOpeningElement(node) && !Node57.isJsxSelfClosingElement(node)) {
12806
13144
  return;
12807
13145
  }
12808
13146
  const tag = node.getTagNameNode().getText();
12809
13147
  for (const attr of node.getAttributes()) {
12810
- if (!Node56.isJsxAttribute(attr)) {
13148
+ if (!Node57.isJsxAttribute(attr)) {
12811
13149
  continue;
12812
13150
  }
12813
13151
  const initializer = attr.getInitializer();
12814
13152
  let valueExpression = null;
12815
13153
  if (initializer !== void 0) {
12816
- if (Node56.isJsxExpression(initializer)) {
13154
+ if (Node57.isJsxExpression(initializer)) {
12817
13155
  const inner = initializer.getExpression();
12818
13156
  valueExpression = inner ?? null;
12819
13157
  } else {
@@ -12836,11 +13174,11 @@ function findCallExpressionsByName(parent, name) {
12836
13174
  if (skip(node, traversal)) {
12837
13175
  return;
12838
13176
  }
12839
- if (!Node56.isCallExpression(node)) {
13177
+ if (!Node57.isCallExpression(node)) {
12840
13178
  return;
12841
13179
  }
12842
13180
  const callee = node.getExpression();
12843
- if (Node56.isIdentifier(callee) && callee.getText() === name) {
13181
+ if (Node57.isIdentifier(callee) && callee.getText() === name) {
12844
13182
  out.push(node);
12845
13183
  }
12846
13184
  });
@@ -12851,10 +13189,10 @@ function resolveAttributeValueFunction(attr, parent) {
12851
13189
  if (expr === null) {
12852
13190
  return null;
12853
13191
  }
12854
- if (Node56.isArrowFunction(expr) || Node56.isFunctionExpression(expr)) {
13192
+ if (Node57.isArrowFunction(expr) || Node57.isFunctionExpression(expr)) {
12855
13193
  return { func: expr, localName: null };
12856
13194
  }
12857
- if (Node56.isIdentifier(expr)) {
13195
+ if (Node57.isIdentifier(expr)) {
12858
13196
  const symbol = expr.getSymbol();
12859
13197
  if (symbol === void 0) {
12860
13198
  return null;
@@ -12873,15 +13211,15 @@ function resolveAttributeValueFunction(attr, parent) {
12873
13211
  return null;
12874
13212
  }
12875
13213
  function tryExtractFunction(decl) {
12876
- if (Node56.isFunctionDeclaration(decl)) {
13214
+ if (Node57.isFunctionDeclaration(decl)) {
12877
13215
  return decl;
12878
13216
  }
12879
- if (Node56.isVariableDeclaration(decl)) {
13217
+ if (Node57.isVariableDeclaration(decl)) {
12880
13218
  const init = decl.getInitializer();
12881
13219
  if (init === void 0) {
12882
13220
  return null;
12883
13221
  }
12884
- if (Node56.isArrowFunction(init) || Node56.isFunctionExpression(init)) {
13222
+ if (Node57.isArrowFunction(init) || Node57.isFunctionExpression(init)) {
12885
13223
  return init;
12886
13224
  }
12887
13225
  }
@@ -12902,7 +13240,7 @@ function getCallArgumentFunction(call, position) {
12902
13240
  if (arg === void 0) {
12903
13241
  return null;
12904
13242
  }
12905
- if (Node56.isArrowFunction(arg) || Node56.isFunctionExpression(arg)) {
13243
+ if (Node57.isArrowFunction(arg) || Node57.isFunctionExpression(arg)) {
12906
13244
  return arg;
12907
13245
  }
12908
13246
  return null;
@@ -12914,7 +13252,7 @@ function readArrayLiteralText(node) {
12914
13252
  if (node === null) {
12915
13253
  return null;
12916
13254
  }
12917
- if (Node56.isArrayLiteralExpression(node)) {
13255
+ if (Node57.isArrayLiteralExpression(node)) {
12918
13256
  return node.getElements().map((e) => e.getText());
12919
13257
  }
12920
13258
  return [node.getText()];
@@ -13155,13 +13493,13 @@ var raise = (msg) => {
13155
13493
  throw new Error(msg);
13156
13494
  };
13157
13495
  function bindingPatternNames(nameNode) {
13158
- if (Node57.isObjectBindingPattern(nameNode)) {
13496
+ if (Node58.isObjectBindingPattern(nameNode)) {
13159
13497
  return nameNode.getElements().map((e) => e.getName());
13160
13498
  }
13161
- if (Node57.isArrayBindingPattern(nameNode)) {
13499
+ if (Node58.isArrayBindingPattern(nameNode)) {
13162
13500
  const names = [];
13163
13501
  for (const element of nameNode.getElements()) {
13164
- if (Node57.isOmittedExpression(element)) {
13502
+ if (Node58.isOmittedExpression(element)) {
13165
13503
  continue;
13166
13504
  }
13167
13505
  names.push(element.getName());
@@ -13170,9 +13508,28 @@ function bindingPatternNames(nameNode) {
13170
13508
  }
13171
13509
  return null;
13172
13510
  }
13511
+ function objectParamInputs(param, position, mapping) {
13512
+ const boundNames = bindingPatternNames(param.getNameNode());
13513
+ if (boundNames === null) {
13514
+ return [
13515
+ {
13516
+ name: param.getName(),
13517
+ position,
13518
+ role: mapping.wholeParamRole ?? "request",
13519
+ typeText: null
13520
+ }
13521
+ ];
13522
+ }
13523
+ return boundNames.map((name) => ({
13524
+ name,
13525
+ position,
13526
+ role: mapping.knownProperties[name] ?? name,
13527
+ typeText: null
13528
+ }));
13529
+ }
13173
13530
  function componentPropsParameters(param, mapping) {
13174
13531
  const nameNode = param.getNameNode();
13175
- if (!Node57.isObjectBindingPattern(nameNode)) {
13532
+ if (!Node58.isObjectBindingPattern(nameNode)) {
13176
13533
  const type = param.getType();
13177
13534
  return [
13178
13535
  {
@@ -13210,34 +13567,11 @@ function extractParameters(func, inputMapping) {
13210
13567
  typeText: null
13211
13568
  });
13212
13569
  }
13213
- } else if (inputMapping.type === "singleObjectParam") {
13214
- const param = params[inputMapping.paramPosition];
13215
- if (param !== void 0) {
13216
- result.push({
13217
- name: param.getName(),
13218
- position: inputMapping.paramPosition,
13219
- role: "request",
13220
- typeText: null
13221
- });
13222
- }
13223
- } else if (inputMapping.type === "destructuredObject") {
13224
- const param = params[0];
13570
+ } else if (inputMapping.type === "objectParam") {
13571
+ const position = inputMapping.paramPosition ?? 0;
13572
+ const param = params[position];
13225
13573
  if (param !== void 0) {
13226
- const nameNode = param.getNameNode();
13227
- const boundNames = bindingPatternNames(nameNode);
13228
- if (boundNames !== null) {
13229
- for (const name of boundNames) {
13230
- const role = inputMapping.knownProperties[name] ?? name;
13231
- result.push({ name, position: 0, role, typeText: null });
13232
- }
13233
- } else {
13234
- result.push({
13235
- name: param.getName(),
13236
- position: 0,
13237
- role: "request",
13238
- typeText: null
13239
- });
13240
- }
13574
+ result.push(...objectParamInputs(param, position, inputMapping));
13241
13575
  }
13242
13576
  } else if (inputMapping.type === "allPositional") {
13243
13577
  for (let i = 0; i < params.length; i++) {
@@ -13298,11 +13632,11 @@ function extractParameters(func, inputMapping) {
13298
13632
  function extractDependencyCalls(func) {
13299
13633
  const results = [];
13300
13634
  func.forEachDescendant((node, traversal) => {
13301
- if (node !== func && (Node57.isFunctionDeclaration(node) || Node57.isFunctionExpression(node) || Node57.isArrowFunction(node) || Node57.isMethodDeclaration(node))) {
13635
+ if (node !== func && (Node58.isFunctionDeclaration(node) || Node58.isFunctionExpression(node) || Node58.isArrowFunction(node) || Node58.isMethodDeclaration(node))) {
13302
13636
  traversal.skip();
13303
13637
  return;
13304
13638
  }
13305
- if (!Node57.isVariableDeclaration(node)) {
13639
+ if (!Node58.isVariableDeclaration(node)) {
13306
13640
  return;
13307
13641
  }
13308
13642
  const init = node.getInitializer();
@@ -13311,19 +13645,19 @@ function extractDependencyCalls(func) {
13311
13645
  }
13312
13646
  let isAsync = false;
13313
13647
  let callExpr = init;
13314
- if (Node57.isAwaitExpression(init)) {
13648
+ if (Node58.isAwaitExpression(init)) {
13315
13649
  isAsync = true;
13316
13650
  callExpr = init.getExpression();
13317
13651
  }
13318
- if (!Node57.isCallExpression(callExpr)) {
13652
+ if (!Node58.isCallExpression(callExpr)) {
13319
13653
  return;
13320
13654
  }
13321
13655
  const calleeName = callExpr.getExpression().getText();
13322
13656
  const nameNode = node.getNameNode();
13323
- const assignedTo = Node57.isIdentifier(nameNode) ? nameNode.getText() : null;
13657
+ const assignedTo = Node58.isIdentifier(nameNode) ? nameNode.getText() : null;
13324
13658
  const declList = node.getParent();
13325
13659
  const varStmt = declList?.getParent();
13326
- const locationNode = varStmt !== void 0 && Node57.isVariableStatement(varStmt) ? varStmt : node;
13660
+ const locationNode = varStmt !== void 0 && Node58.isVariableStatement(varStmt) ? varStmt : node;
13327
13661
  results.push({
13328
13662
  name: calleeName,
13329
13663
  assignedTo,
@@ -13608,9 +13942,9 @@ function extractBindingMethod(binding, callSite, pack, resolution) {
13608
13942
  if (m.type === "fromArgumentProperty") {
13609
13943
  const args = callSite.callExpression.getArguments();
13610
13944
  const arg = args[m.position];
13611
- if (arg !== void 0 && Node57.isObjectLiteralExpression(arg)) {
13945
+ if (arg !== void 0 && Node58.isObjectLiteralExpression(arg)) {
13612
13946
  const prop = arg.getProperty(m.property);
13613
- if (prop !== void 0 && Node57.isPropertyAssignment(prop)) {
13947
+ if (prop !== void 0 && Node58.isPropertyAssignment(prop)) {
13614
13948
  const init = prop.getInitializer();
13615
13949
  if (init !== void 0) {
13616
13950
  const value = stringValueOf(init, resolution);
@@ -13627,138 +13961,17 @@ function extractBindingMethod(binding, callSite, pack, resolution) {
13627
13961
  }
13628
13962
  return void 0;
13629
13963
  }
13630
- var URL_SCHEME = /^[a-zA-Z][a-zA-Z\d+.-]*:\/\//;
13631
- var URL_ORIGIN = /^[a-zA-Z][a-zA-Z\d+.-]*:\/\/[^/]*/;
13632
- var PROTOCOL_RELATIVE = /^\/\//;
13633
- var PROTOCOL_RELATIVE_ORIGIN = /^\/\/[^/]*/;
13634
- function isAbsoluteUrlLiteral(text) {
13635
- return URL_SCHEME.test(text) || PROTOCOL_RELATIVE.test(text);
13636
- }
13637
- function stripOriginManually(text) {
13638
- if (URL_SCHEME.test(text)) {
13639
- return text.replace(URL_ORIGIN, "");
13640
- }
13641
- if (PROTOCOL_RELATIVE.test(text)) {
13642
- return text.replace(PROTOCOL_RELATIVE_ORIGIN, "");
13643
- }
13644
- return text;
13645
- }
13646
- function stripQueryAndFragment(text) {
13647
- const idx = text.search(/[?#]/);
13648
- return idx === -1 ? text : text.slice(0, idx);
13649
- }
13650
- var SUBSTITUTION = "\uFFFF";
13651
- var AUTHORITY_OPENER = /^(?:[-+.\uFFFFa-zA-Z0-9]+:\/\/|\/\/)/;
13652
- function originEndOf(flattened) {
13653
- const opener = AUTHORITY_OPENER.exec(flattened);
13654
- if (opener === null) {
13655
- return 0;
13656
- }
13657
- const slash = flattened.indexOf("/", opener[0].length);
13658
- return slash === -1 ? flattened.length : slash;
13659
- }
13660
- function appendPathText(path12, text) {
13661
- const idx = text.search(/[?#]/);
13662
- if (idx === -1) {
13663
- return { path: path12 + text, stop: false };
13664
- }
13665
- return { path: path12 + text.slice(0, idx), stop: true };
13666
- }
13667
- function parseAbsoluteUrl(text) {
13668
- try {
13669
- return new URL(text);
13670
- } catch {
13671
- }
13672
- if (!PROTOCOL_RELATIVE.test(text)) {
13673
- return void 0;
13674
- }
13675
- try {
13676
- return new URL(`https:${text}`);
13677
- } catch {
13678
- return void 0;
13679
- }
13680
- }
13681
- function pathnameOfAbsoluteLiteral(text) {
13682
- const parsed = parseAbsoluteUrl(text);
13683
- if (parsed !== void 0) {
13684
- return parsed.pathname;
13685
- }
13686
- return stripQueryAndFragment(stripOriginManually(text));
13687
- }
13688
- function pathFromLiteralUrl(text) {
13689
- const path12 = isAbsoluteUrlLiteral(text) ? pathnameOfAbsoluteLiteral(text) : stripQueryAndFragment(text);
13690
- return path12 === "" ? void 0 : path12;
13691
- }
13692
- function pathFromTemplateUrl(arg) {
13693
- const headText = arg.getHead().getLiteralText();
13694
- const spans = arg.getTemplateSpans();
13695
- const tails = spans.map((span) => span.getLiteral().getLiteralText());
13696
- const originEnd = originEndOf([headText, ...tails].join(SUBSTITUTION));
13697
- const head = appendPathText("", headText.slice(originEnd));
13698
- let path12 = head.path;
13699
- let stop = head.stop;
13700
- let at = headText.length;
13701
- for (let i = 0; i < spans.length && !stop; i++) {
13702
- const span = spans[i];
13703
- const tailText = tails[i];
13704
- if (span === void 0 || tailText === void 0) {
13705
- continue;
13706
- }
13707
- if (at >= originEnd) {
13708
- path12 += `{${placeholderName(span.getExpression())}}`;
13709
- }
13710
- at += SUBSTITUTION.length;
13711
- const appended = appendPathText(
13712
- path12,
13713
- tailText.slice(Math.max(0, originEnd - at))
13714
- );
13715
- path12 = appended.path;
13716
- stop = appended.stop;
13717
- at += tailText.length;
13718
- }
13719
- return path12 === "" ? void 0 : path12;
13720
- }
13721
13964
  function extractBindingPath(binding, callSite, pack, resolution) {
13722
13965
  const p = binding.path;
13723
13966
  if (p.type === "fromClientMethod") {
13724
13967
  return resolveContractField(callSite, pack, "path");
13725
13968
  }
13726
- if (p.type === "fromArgumentLiteral") {
13727
- const args = callSite.callExpression.getArguments();
13728
- const arg = args[p.position];
13729
- if (arg === void 0) {
13730
- return void 0;
13731
- }
13732
- const written = pathFromUrlNode(arg);
13733
- if (written !== void 0) {
13734
- return written;
13735
- }
13736
- const resolved = resolution?.resolveWrittenValue(arg) ?? null;
13737
- return resolved !== null ? pathFromUrlNode(resolved) : void 0;
13738
- }
13739
- return void 0;
13740
- }
13741
- function pathFromUrlNode(node) {
13742
- if (Node57.isStringLiteral(node)) {
13743
- return pathFromLiteralUrl(node.getLiteralValue());
13744
- }
13745
- if (Node57.isNoSubstitutionTemplateLiteral(node)) {
13746
- return pathFromLiteralUrl(node.getLiteralValue());
13747
- }
13748
- if (Node57.isTemplateExpression(node)) {
13749
- return pathFromTemplateUrl(node);
13969
+ if (p.type === "fromArgument") {
13970
+ const arg = callSite.callExpression.getArguments()[p.position];
13971
+ return arg === void 0 ? void 0 : pathFromArgument(arg, resolution);
13750
13972
  }
13751
13973
  return void 0;
13752
13974
  }
13753
- function placeholderName(expr) {
13754
- if (Node57.isIdentifier(expr)) {
13755
- return expr.getText();
13756
- }
13757
- if (Node57.isPropertyAccessExpression(expr)) {
13758
- return expr.getName();
13759
- }
13760
- return "param";
13761
- }
13762
13975
  function resolveContractField(callSite, pack, field) {
13763
13976
  if (pack.contractReading === void 0 || callSite.methodName === null) {
13764
13977
  return void 0;
@@ -14226,7 +14439,7 @@ function internalImportsOf(project, file) {
14226
14439
  }
14227
14440
  return [...targets].sort();
14228
14441
  }
14229
- function expandWrapperCallers(summaries, project, options) {
14442
+ function expandWrapperCallers(summaries, project, options, resolution) {
14230
14443
  const wrappers = [];
14231
14444
  let lookup = null;
14232
14445
  for (const s of summaries) {
@@ -14253,7 +14466,9 @@ function expandWrapperCallers(summaries, project, options) {
14253
14466
  }
14254
14467
  const derived = [];
14255
14468
  for (const wrapper of wrappers) {
14256
- derived.push(...synthesizeCallerSummaries(wrapper, project, options));
14469
+ derived.push(
14470
+ ...synthesizeCallerSummaries(wrapper, project, options, resolution)
14471
+ );
14257
14472
  }
14258
14473
  return [...summaries, ...derived];
14259
14474
  }
@@ -14268,7 +14483,7 @@ function findWrapperPathParam(summary, lookup) {
14268
14483
  }
14269
14484
  for (const call of func.getDescendantsOfKind(SyntaxKind12.CallExpression)) {
14270
14485
  const first = call.getArguments()[0];
14271
- if (first === void 0 || !Node57.isIdentifier(first)) {
14486
+ if (first === void 0 || !Node58.isIdentifier(first)) {
14272
14487
  continue;
14273
14488
  }
14274
14489
  const at = names.indexOf(first.getText());
@@ -14278,7 +14493,7 @@ function findWrapperPathParam(summary, lookup) {
14278
14493
  }
14279
14494
  return null;
14280
14495
  }
14281
- function synthesizeCallerSummaries(wrapper, _project, options) {
14496
+ function synthesizeCallerSummaries(wrapper, _project, options, resolution) {
14282
14497
  const nameNode = wrapperNameNode(wrapper.func);
14283
14498
  if (nameNode === null) {
14284
14499
  return [];
@@ -14299,7 +14514,7 @@ function synthesizeCallerSummaries(wrapper, _project, options) {
14299
14514
  if (pathArg === void 0) {
14300
14515
  continue;
14301
14516
  }
14302
- const path12 = literalOrTemplate(pathArg);
14517
+ const path12 = pathFromArgument(pathArg, resolution);
14303
14518
  if (path12 === void 0) {
14304
14519
  continue;
14305
14520
  }
@@ -14317,16 +14532,16 @@ function synthesizeCallerSummaries(wrapper, _project, options) {
14317
14532
  return out;
14318
14533
  }
14319
14534
  function wrapperNameNode(func) {
14320
- if (Node57.isFunctionDeclaration(func) || Node57.isMethodDeclaration(func)) {
14535
+ if (Node58.isFunctionDeclaration(func) || Node58.isMethodDeclaration(func)) {
14321
14536
  const name = func.getNameNode();
14322
- if (name !== void 0 && Node57.isIdentifier(name)) {
14537
+ if (name !== void 0 && Node58.isIdentifier(name)) {
14323
14538
  return name;
14324
14539
  }
14325
14540
  }
14326
14541
  const parent = func.getParent();
14327
- if (parent !== void 0 && Node57.isVariableDeclaration(parent)) {
14542
+ if (parent !== void 0 && Node58.isVariableDeclaration(parent)) {
14328
14543
  const nameNode = parent.getNameNode();
14329
- if (Node57.isIdentifier(nameNode)) {
14544
+ if (Node58.isIdentifier(nameNode)) {
14330
14545
  return nameNode;
14331
14546
  }
14332
14547
  }
@@ -14335,10 +14550,10 @@ function wrapperNameNode(func) {
14335
14550
  function enclosingCall(node) {
14336
14551
  let current2 = node.getParent();
14337
14552
  while (current2 !== void 0) {
14338
- if (Node57.isCallExpression(current2)) {
14553
+ if (Node58.isCallExpression(current2)) {
14339
14554
  return current2;
14340
14555
  }
14341
- if (Node57.isPropertyAccessExpression(current2)) {
14556
+ if (Node58.isPropertyAccessExpression(current2)) {
14342
14557
  current2 = current2.getParent();
14343
14558
  continue;
14344
14559
  }
@@ -14349,38 +14564,21 @@ function enclosingCall(node) {
14349
14564
  function enclosingFunction(node) {
14350
14565
  let current2 = node.getParent();
14351
14566
  while (current2 !== void 0) {
14352
- if (Node57.isFunctionDeclaration(current2) || Node57.isFunctionExpression(current2) || Node57.isArrowFunction(current2) || Node57.isMethodDeclaration(current2)) {
14567
+ if (Node58.isFunctionDeclaration(current2) || Node58.isFunctionExpression(current2) || Node58.isArrowFunction(current2) || Node58.isMethodDeclaration(current2)) {
14353
14568
  return current2;
14354
14569
  }
14355
14570
  current2 = current2.getParent();
14356
14571
  }
14357
14572
  return null;
14358
14573
  }
14359
- function literalOrTemplate(arg) {
14360
- if (Node57.isStringLiteral(arg)) {
14361
- return arg.getLiteralValue();
14362
- }
14363
- if (Node57.isNoSubstitutionTemplateLiteral(arg)) {
14364
- return arg.getLiteralValue();
14365
- }
14366
- if (Node57.isTemplateExpression(arg)) {
14367
- let path12 = arg.getHead().getLiteralText();
14368
- for (const span of arg.getTemplateSpans()) {
14369
- path12 += `{${placeholderName(span.getExpression())}}`;
14370
- path12 += span.getLiteral().getLiteralText();
14371
- }
14372
- return path12;
14373
- }
14374
- return void 0;
14375
- }
14376
14574
  function callerName(func) {
14377
- if (Node57.isFunctionDeclaration(func) || Node57.isMethodDeclaration(func)) {
14575
+ if (Node58.isFunctionDeclaration(func) || Node58.isMethodDeclaration(func)) {
14378
14576
  return func.getName() ?? "anonymous";
14379
14577
  }
14380
14578
  const parent = func.getParent();
14381
- if (parent !== void 0 && Node57.isVariableDeclaration(parent)) {
14579
+ if (parent !== void 0 && Node58.isVariableDeclaration(parent)) {
14382
14580
  const nameNode = parent.getNameNode();
14383
- if (Node57.isIdentifier(nameNode)) {
14581
+ if (Node58.isIdentifier(nameNode)) {
14384
14582
  return nameNode.getText();
14385
14583
  }
14386
14584
  }
@@ -14690,7 +14888,12 @@ function createTypeScriptAdapter(config) {
14690
14888
  const wrapperInput = reused === null ? summaries : [...summaries, ...reused.summaries];
14691
14889
  const withWrappers = timer.time(
14692
14890
  "expandWrapperCallers",
14693
- () => expandWrapperCallers(wrapperInput, project, config.extractorOptions)
14891
+ () => expandWrapperCallers(
14892
+ wrapperInput,
14893
+ project,
14894
+ config.extractorOptions,
14895
+ resolution
14896
+ )
14694
14897
  );
14695
14898
  const pipeline = reused === null ? withWrappers : [...summaries, ...withWrappers.slice(wrapperInput.length)];
14696
14899
  const withSubUnits = timer.time(
@@ -15231,7 +15434,7 @@ function findNearestTsconfig(startDir) {
15231
15434
 
15232
15435
  // src/facts/why.ts
15233
15436
  import path11 from "path";
15234
- import { Node as Node58, Project as Project3, SyntaxKind as SyntaxKind13 } from "ts-morph";
15437
+ import { Node as Node59, Project as Project3, SyntaxKind as SyntaxKind13 } from "ts-morph";
15235
15438
  import { explainResolutionProof, renderExplanation } from "@suss/resolution";
15236
15439
  var JS_PHRASES = {
15237
15440
  bind: ({ tuple, describe }) => ({
@@ -15260,7 +15463,7 @@ var WhySession = class {
15260
15463
  }
15261
15464
  let found = null;
15262
15465
  sourceFile.forEachDescendant((node) => {
15263
- if (Node58.isExpression(node) && node.getStartLineNumber() === line && node.getText() === text && (found === null || node.getWidth() <= found.getWidth())) {
15466
+ if (Node59.isExpression(node) && node.getStartLineNumber() === line && node.getText() === text && (found === null || node.getWidth() <= found.getWidth())) {
15264
15467
  found = node;
15265
15468
  }
15266
15469
  });
@@ -15352,21 +15555,21 @@ var WhySession = class {
15352
15555
  }
15353
15556
  };
15354
15557
  function displayNameOf(node) {
15355
- if (Node58.isIdentifier(node) || Node58.isPropertyAccessExpression(node)) {
15558
+ if (Node59.isIdentifier(node) || Node59.isPropertyAccessExpression(node)) {
15356
15559
  return node.getText();
15357
15560
  }
15358
- if (Node58.isCallExpression(node) || Node58.isNewExpression(node)) {
15561
+ if (Node59.isCallExpression(node) || Node59.isNewExpression(node)) {
15359
15562
  return `${node.getExpression()?.getText() ?? "call"}(...)`;
15360
15563
  }
15361
- if (Node58.isFunctionDeclaration(node) || Node58.isClassDeclaration(node) || Node58.isMethodDeclaration(node) || Node58.isVariableDeclaration(node)) {
15564
+ if (Node59.isFunctionDeclaration(node) || Node59.isClassDeclaration(node) || Node59.isMethodDeclaration(node) || Node59.isVariableDeclaration(node)) {
15362
15565
  const name = node.getName();
15363
15566
  if (name !== void 0) {
15364
15567
  return name;
15365
15568
  }
15366
15569
  }
15367
- if (Node58.isArrowFunction(node) || Node58.isFunctionExpression(node)) {
15570
+ if (Node59.isArrowFunction(node) || Node59.isFunctionExpression(node)) {
15368
15571
  const parent = node.getParent();
15369
- if (parent !== void 0 && Node58.isVariableDeclaration(parent)) {
15572
+ if (parent !== void 0 && Node59.isVariableDeclaration(parent)) {
15370
15573
  return parent.getName();
15371
15574
  }
15372
15575
  }
@@ -15566,6 +15769,7 @@ export {
15566
15769
  ADAPTER_VERSION,
15567
15770
  ResolutionStore,
15568
15771
  WhySession,
15772
+ accessContextFor,
15569
15773
  callOpsFor,
15570
15774
  collectAncestorBranches,
15571
15775
  collectClientFieldAccesses,
@@ -15583,6 +15787,7 @@ export {
15583
15787
  findNearestTsconfig,
15584
15788
  findTerminals,
15585
15789
  formatPackHealth,
15790
+ invocationContextFor,
15586
15791
  isImportedFrom,
15587
15792
  methodDeclaredIn,
15588
15793
  parseConditionExpression,