@suss/adapter-typescript 0.26.0 → 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // src/adapter.ts
2
2
  import path11 from "path";
3
3
  import {
4
- Node as Node64,
4
+ Node as Node65,
5
5
  Project,
6
6
  SyntaxKind as SyntaxKind12
7
7
  } from "ts-morph";
@@ -29,7 +29,7 @@ import {
29
29
  } from "@suss/extractor";
30
30
 
31
31
  // src/assembly.ts
32
- import { Node as Node52 } from "ts-morph";
32
+ import { Node as Node53 } from "ts-morph";
33
33
  import { guardsHoldOn, runsBefore } from "@suss/extractor";
34
34
 
35
35
  // src/conditions.ts
@@ -846,11 +846,11 @@ function tryExpandArrayIncludes(call) {
846
846
  return {
847
847
  type: "compound",
848
848
  op: "or",
849
- operands: literalValues.map((lit6) => ({
849
+ operands: literalValues.map((lit5) => ({
850
850
  type: "comparison",
851
851
  left: subject,
852
852
  op: "eq",
853
- right: lit6
853
+ right: lit5
854
854
  }))
855
855
  };
856
856
  }
@@ -1502,7 +1502,7 @@ function degradedResult(func, terminalNodes, reason) {
1502
1502
 
1503
1503
  // src/resolve/invocationEffects.ts
1504
1504
  import {
1505
- Node as Node41
1505
+ Node as Node42
1506
1506
  } from "ts-morph";
1507
1507
  import { rawConditionToPredicate } from "@suss/extractor";
1508
1508
 
@@ -1987,7 +1987,8 @@ function readFileText(project, filePath) {
1987
1987
  return null;
1988
1988
  }
1989
1989
  }
1990
- function parseTsconfig(tsConfigFilePath) {
1990
+ function parseTsconfig(tsConfigFilePath, seen = /* @__PURE__ */ new Set()) {
1991
+ seen.add(tsConfigFilePath);
1991
1992
  const configFile = ts.readConfigFile(tsConfigFilePath, ts.sys.readFile);
1992
1993
  if (configFile.error !== void 0) {
1993
1994
  return { fileNames: [], options: {} };
@@ -2000,7 +2001,18 @@ function parseTsconfig(tsConfigFilePath) {
2000
2001
  void 0,
2001
2002
  tsConfigFilePath
2002
2003
  );
2003
- return { fileNames: parsed.fileNames, options: parsed.options };
2004
+ if (parsed.fileNames.length > 0) {
2005
+ return { fileNames: parsed.fileNames, options: parsed.options };
2006
+ }
2007
+ const referenced = (parsed.projectReferences ?? []).map((reference) => ts.resolveProjectReferencePath(reference)).filter((referencePath) => !seen.has(referencePath));
2008
+ const fileNames = [
2009
+ ...new Set(
2010
+ referenced.flatMap(
2011
+ (referencePath) => parseTsconfig(referencePath, seen).fileNames
2012
+ )
2013
+ )
2014
+ ];
2015
+ return { fileNames, options: parsed.options };
2004
2016
  }
2005
2017
  async function selectCandidateFiles(allFiles, packs, options) {
2006
2018
  const ungatedExists = packs.some(packIsUngated);
@@ -2361,7 +2373,7 @@ function reportUnreadableExports(file) {
2361
2373
  }
2362
2374
 
2363
2375
  // src/resolve/callOps.ts
2364
- import { Node as Node40 } from "ts-morph";
2376
+ import { Node as Node41 } from "ts-morph";
2365
2377
 
2366
2378
  // src/configuredCall.ts
2367
2379
  import { Node as Node11 } from "ts-morph";
@@ -2419,10 +2431,10 @@ function rootIdentifier(node) {
2419
2431
  }
2420
2432
 
2421
2433
  // src/parameterReads.ts
2422
- import { Node as Node38 } from "ts-morph";
2434
+ import { Node as Node39 } from "ts-morph";
2423
2435
 
2424
2436
  // src/resolve/functionBehind.ts
2425
- import { Node as Node37 } from "ts-morph";
2437
+ import { Node as Node38 } from "ts-morph";
2426
2438
 
2427
2439
  // src/facts/store.ts
2428
2440
  import { Node as Node15 } from "ts-morph";
@@ -5240,6 +5252,7 @@ function literalValueOf(value, resolution, isWanted) {
5240
5252
  }
5241
5253
 
5242
5254
  // src/discovery/clientCall.ts
5255
+ var GLOBAL_OBJECTS = /* @__PURE__ */ new Set(["globalThis", "window", "self", "global"]);
5243
5256
  function discoverClientCalls(sourceFile, match, kind, resolution) {
5244
5257
  const results = [];
5245
5258
  const isGlobal = match.importModule === "global";
@@ -5264,9 +5277,15 @@ function discoverClientCalls(sourceFile, match, kind, resolution) {
5264
5277
  if (callee.getText() === match.importName) {
5265
5278
  matched = true;
5266
5279
  }
5280
+ } else if (isGlobal && Node18.isPropertyAccessExpression(callee)) {
5281
+ if (callee.getName() === match.importName && GLOBAL_OBJECTS.has(callee.getExpression().getText())) {
5282
+ matched = true;
5283
+ }
5284
+ } else if (match.callable === true && isClientItself(callee, match, clientVarNames, resolution)) {
5285
+ matched = true;
5267
5286
  } else if (Node18.isPropertyAccessExpression(callee)) {
5268
5287
  const subject = callee.getExpression();
5269
- if (Node18.isIdentifier(subject) && (isClientImport(subject, match, resolution, true) || clientVarNames.has(subject.getText())) || resolvesToKnownInstance(subject, match, resolution)) {
5288
+ if (isClientItself(subject, match, clientVarNames, resolution)) {
5270
5289
  methodName = callee.getName();
5271
5290
  if (methodFilter === null || methodFilter.has(methodName)) {
5272
5291
  matched = true;
@@ -5292,6 +5311,9 @@ function discoverClientCalls(sourceFile, match, kind, resolution) {
5292
5311
  });
5293
5312
  return results;
5294
5313
  }
5314
+ function isClientItself(subject, match, clientVarNames, resolution) {
5315
+ return Node18.isIdentifier(subject) && (isClientImport(subject, match, resolution, true) || clientVarNames.has(subject.getText())) || resolvesToKnownInstance(subject, match, resolution);
5316
+ }
5295
5317
  function clientReceiverCheckFor(sourceFile, match, resolution) {
5296
5318
  const localName = resolveImportedLocalName(
5297
5319
  sourceFile,
@@ -7721,17 +7743,157 @@ function discoverPackageImports(sourceFile, match, kind, resolution) {
7721
7743
  }
7722
7744
 
7723
7745
  // src/discovery/registrationCall.ts
7724
- import { Node as Node32 } from "ts-morph";
7746
+ import { Node as Node34 } from "ts-morph";
7725
7747
  import { joinMountedPath } from "@suss/resolution";
7726
7748
 
7727
7749
  // src/resolve/routePath.ts
7728
- import { pathOf } from "@suss/values";
7750
+ import { force as force3, pathOf } from "@suss/values";
7729
7751
  function pathFromArgument(arg, resolution) {
7730
7752
  return pathOf(evaluatedValue(arg, resolution));
7731
7753
  }
7754
+ function pathFromProperty(arg, property, resolution) {
7755
+ const record2 = evaluatedValue(arg, resolution);
7756
+ if (record2.kind !== "record") {
7757
+ return void 0;
7758
+ }
7759
+ const field = record2.fields.get(property);
7760
+ return field === void 0 ? void 0 : pathOf(force3(field.value));
7761
+ }
7762
+
7763
+ // src/discovery/wrapperFactory.ts
7764
+ import { Node as Node33 } from "ts-morph";
7765
+
7766
+ // src/resolve/unfollowedCall.ts
7767
+ import {
7768
+ Node as Node32,
7769
+ SyntaxKind as SyntaxKind8
7770
+ } from "ts-morph";
7771
+ import {
7772
+ unfollowedCallGap,
7773
+ worthRecording
7774
+ } from "@suss/behavioral-ir";
7775
+ function isInExternalCode(sourceFile) {
7776
+ if (sourceFile.isDeclarationFile()) {
7777
+ return true;
7778
+ }
7779
+ return sourceFile.getFilePath().includes("/node_modules/");
7780
+ }
7781
+ function hasBody(fn) {
7782
+ if (Node32.isFunctionDeclaration(fn) || Node32.isMethodDeclaration(fn) || Node32.isFunctionExpression(fn)) {
7783
+ return fn.getBody?.() !== void 0;
7784
+ }
7785
+ return true;
7786
+ }
7787
+ function isDeclaredShape(declaration) {
7788
+ return (Node32.isMethodSignature(declaration) || Node32.isPropertySignature(declaration)) && !isInExternalCode(declaration.getSourceFile());
7789
+ }
7790
+ function isExternalDeclaration(declaration) {
7791
+ if (isInExternalCode(declaration.getSourceFile())) {
7792
+ return true;
7793
+ }
7794
+ if (Node32.isImportSpecifier(declaration) || Node32.isImportClause(declaration) || Node32.isNamespaceImport(declaration)) {
7795
+ const target = declaration.getFirstAncestorByKind(SyntaxKind8.ImportDeclaration)?.getModuleSpecifierSourceFile();
7796
+ return target === void 0 || isInExternalCode(target);
7797
+ }
7798
+ return declaresAnotherModule(declaration);
7799
+ }
7800
+ function declaresAnotherModule(declaration) {
7801
+ const module = declaration.getFirstAncestorByKind(
7802
+ SyntaxKind8.ModuleDeclaration
7803
+ );
7804
+ return module !== void 0 && Node32.isStringLiteral(module.getNameNode());
7805
+ }
7806
+ function statesShapeOnly(declaration) {
7807
+ if (isExternalDeclaration(declaration)) {
7808
+ return false;
7809
+ }
7810
+ if (Node32.isMethodSignature(declaration) || Node32.isPropertySignature(declaration)) {
7811
+ return true;
7812
+ }
7813
+ if (Node32.isFunctionDeclaration(declaration) || Node32.isMethodDeclaration(declaration)) {
7814
+ return declaration.getBody() === void 0;
7815
+ }
7816
+ return false;
7817
+ }
7818
+ function declarationsBehind(symbol) {
7819
+ if (symbol === void 0) {
7820
+ return [];
7821
+ }
7822
+ const behind = symbol.getAliasedSymbol()?.getDeclarations() ?? [];
7823
+ return behind.length > 0 ? behind : symbol.getDeclarations();
7824
+ }
7825
+ function isParameterOf(declaration, scanning) {
7826
+ return Node32.isParameterDeclaration(declaration) && declaration.getParent() === scanning;
7827
+ }
7828
+ function parameterIndexOf(declarations, scanning) {
7829
+ if (scanning === void 0) {
7830
+ return void 0;
7831
+ }
7832
+ const params = scanning.getParameters();
7833
+ for (const declaration of declarations) {
7834
+ const index = params.findIndex((param) => param === declaration);
7835
+ if (index !== -1) {
7836
+ return index;
7837
+ }
7838
+ }
7839
+ return void 0;
7840
+ }
7841
+ function classifyStop(declarations, scanning) {
7842
+ if (declarations.length === 0) {
7843
+ return "noDeclaration";
7844
+ }
7845
+ for (const declaration of declarations) {
7846
+ if (!isInExternalCode(declaration.getSourceFile())) {
7847
+ recordFileDependency(declaration.getSourceFile().getFilePath());
7848
+ }
7849
+ }
7850
+ if (scanning !== void 0 && declarations.some((declaration) => isParameterOf(declaration, scanning))) {
7851
+ return "callerSupplied";
7852
+ }
7853
+ if (declarations.every(isExternalDeclaration)) {
7854
+ return "outsideRun";
7855
+ }
7856
+ if (declarations.some(statesShapeOnly)) {
7857
+ return "noBody";
7858
+ }
7859
+ return "unsettledValue";
7860
+ }
7861
+
7862
+ // src/discovery/wrapperFactory.ts
7863
+ function factoryNameOf(targetArg) {
7864
+ const written = factKeyOf(targetArg);
7865
+ if (!Node33.isCallExpression(written)) {
7866
+ return void 0;
7867
+ }
7868
+ const callee = written.getExpression();
7869
+ if (Node33.isIdentifier(callee)) {
7870
+ return callee.getText();
7871
+ }
7872
+ if (Node33.isPropertyAccessExpression(callee)) {
7873
+ return callee.getName();
7874
+ }
7875
+ return void 0;
7876
+ }
7877
+ function factoryStopOf(targetArg) {
7878
+ const written = factKeyOf(targetArg);
7879
+ if (!Node33.isCallExpression(written)) {
7880
+ return null;
7881
+ }
7882
+ const callee = factoryNameOf(targetArg);
7883
+ if (callee === void 0) {
7884
+ return null;
7885
+ }
7886
+ const reason = classifyStop(
7887
+ declarationsBehind(written.getExpression().getSymbol())
7888
+ );
7889
+ if (!worthRecording(reason)) {
7890
+ return null;
7891
+ }
7892
+ return { callee, reason: "unresolvedWrapper" };
7893
+ }
7732
7894
 
7733
7895
  // src/discovery/registrationCall.ts
7734
- function discoverRegistrationCalls(sourceFile, match, kind, bindingExtraction, resolution, mountPrefixes, expandedElsewhere) {
7896
+ function discoverRegistrationCalls(sourceFile, match, kind, bindingExtraction, resolution, mountPrefixes, expandedElsewhere, routeWrapperPattern) {
7735
7897
  const results = [];
7736
7898
  const registrationSubjects = registrationSubjectsOf(
7737
7899
  sourceFile,
@@ -7746,11 +7908,11 @@ function discoverRegistrationCalls(sourceFile, match, kind, bindingExtraction, r
7746
7908
  return results;
7747
7909
  }
7748
7910
  sourceFile.forEachDescendant((node) => {
7749
- if (!Node32.isCallExpression(node)) {
7911
+ if (!Node34.isCallExpression(node)) {
7750
7912
  return;
7751
7913
  }
7752
7914
  const callee = node.getExpression();
7753
- if (!Node32.isPropertyAccessExpression(callee)) {
7915
+ if (!Node34.isPropertyAccessExpression(callee)) {
7754
7916
  return;
7755
7917
  }
7756
7918
  const methodName = callee.getName();
@@ -7787,12 +7949,12 @@ function discoverRegistrationCalls(sourceFile, match, kind, bindingExtraction, r
7787
7949
  const registrationSubjectId = nodeId(subjectNode);
7788
7950
  let foundObjectArg = false;
7789
7951
  for (const arg of args) {
7790
- if (!Node32.isObjectLiteralExpression(arg)) {
7952
+ if (!Node34.isObjectLiteralExpression(arg)) {
7791
7953
  continue;
7792
7954
  }
7793
7955
  foundObjectArg = true;
7794
7956
  for (const prop of arg.getProperties()) {
7795
- if (Node32.isMethodDeclaration(prop)) {
7957
+ if (Node34.isMethodDeclaration(prop)) {
7796
7958
  results.push({
7797
7959
  func: prop,
7798
7960
  kind,
@@ -7801,7 +7963,7 @@ function discoverRegistrationCalls(sourceFile, match, kind, bindingExtraction, r
7801
7963
  });
7802
7964
  continue;
7803
7965
  }
7804
- if (!Node32.isPropertyAssignment(prop)) {
7966
+ if (!Node34.isPropertyAssignment(prop)) {
7805
7967
  continue;
7806
7968
  }
7807
7969
  const propInit = prop.getInitializer();
@@ -7833,6 +7995,13 @@ function discoverRegistrationCalls(sourceFile, match, kind, bindingExtraction, r
7833
7995
  mountPrefixes
7834
7996
  );
7835
7997
  if (handler !== null) {
7998
+ const chain = routeWrapperPattern === void 0 ? null : routeChainOf(
7999
+ args.slice(0, -1),
8000
+ routeWrapperPattern,
8001
+ methodName,
8002
+ routeInfo,
8003
+ resolution
8004
+ );
7836
8005
  results.push({
7837
8006
  func: handler,
7838
8007
  kind,
@@ -7840,8 +8009,13 @@ function discoverRegistrationCalls(sourceFile, match, kind, bindingExtraction, r
7840
8009
  name: methodName,
7841
8010
  nameKind: "label",
7842
8011
  registrationSubjectId,
7843
- ...routeInfo !== null ? { routeInfo } : {}
8012
+ ...routeInfo !== null ? { routeInfo } : {},
8013
+ ...chain === null || chain.references.length === 0 ? {} : { routeWrappers: chain.references },
8014
+ ...chain === null || chain.unfollowed.length === 0 ? {} : { routeUnfollowed: chain.unfollowed }
7844
8015
  });
8016
+ if (chain !== null) {
8017
+ results.push(...chain.units);
8018
+ }
7845
8019
  return;
7846
8020
  }
7847
8021
  if (routeInfo !== null && lastArg !== void 0 && namesAParameter(lastArg)) {
@@ -7887,6 +8061,47 @@ function declinedRegistration(call, callee, methodName, kind, receiver, resoluti
7887
8061
  }
7888
8062
  ];
7889
8063
  }
8064
+ function routeChainOf(listed, pattern, methodName, routeInfo, resolution) {
8065
+ const chain = { units: [], references: [], unfollowed: [] };
8066
+ const anonymousLabels = /* @__PURE__ */ new Map();
8067
+ for (const arg of listed) {
8068
+ const elements = Node34.isArrayLiteralExpression(arg) ? arg.getElements() : [arg];
8069
+ for (const element of elements) {
8070
+ const target = functionValueOf(element, resolution);
8071
+ if (target === null) {
8072
+ const stop = factoryStopOf(element);
8073
+ if (stop !== null) {
8074
+ chain.unfollowed.push(stop);
8075
+ }
8076
+ continue;
8077
+ }
8078
+ const ownName = functionNameOrAnon(target);
8079
+ const named2 = ownName !== "<anon>";
8080
+ const label = factoryNameOf(element) ?? methodName;
8081
+ const seen = anonymousLabels.get(label) ?? 0;
8082
+ if (!named2) {
8083
+ anonymousLabels.set(label, seen + 1);
8084
+ }
8085
+ const name = named2 ? ownName : routeWrapperLabel(label, routeInfo, element, seen);
8086
+ chain.units.push({
8087
+ func: target,
8088
+ kind: pattern.kind,
8089
+ name,
8090
+ pattern,
8091
+ ...named2 ? {} : { nameKind: "label" }
8092
+ });
8093
+ chain.references.push({
8094
+ file: target.getSourceFile().getFilePath(),
8095
+ name
8096
+ });
8097
+ }
8098
+ }
8099
+ return chain;
8100
+ }
8101
+ function routeWrapperLabel(label, routeInfo, element, seen) {
8102
+ const where = routeInfo === null ? `L${element.getStartLineNumber()}` : `${routeInfo.method} ${routeInfo.path}`;
8103
+ return seen === 0 ? `${label}@${where}` : `${label}@${where}#${seen + 1}`;
8104
+ }
7890
8105
  function withMountPrefix(routeInfo, subjectNode, mountPrefixes) {
7891
8106
  if (routeInfo === null || mountPrefixes === void 0) {
7892
8107
  return routeInfo;
@@ -7914,13 +8129,13 @@ function subjectNodeFor(subject, subjects, match, resolution) {
7914
8129
  }
7915
8130
  var NOT_A_ROUTABLE = { kind: "none" };
7916
8131
  function receiverOf(subject, subjects, match, resolution) {
7917
- if (Node32.isIdentifier(subject)) {
8132
+ if (Node34.isIdentifier(subject)) {
7918
8133
  const known = subjects.get(subject.getText());
7919
8134
  if (known !== void 0) {
7920
8135
  return { kind: "routable", node: known };
7921
8136
  }
7922
8137
  }
7923
- if (resolution === void 0 || !(Node32.isIdentifier(subject) || Node32.isPropertyAccessExpression(subject))) {
8138
+ if (resolution === void 0 || !(Node34.isIdentifier(subject) || Node34.isPropertyAccessExpression(subject))) {
7924
8139
  return NOT_A_ROUTABLE;
7925
8140
  }
7926
8141
  const construction = resolution.subjectConstructionOf(
@@ -7960,18 +8175,18 @@ function collectMethodsCalledOnCallResults(sourceFile) {
7960
8175
  const setToCalls = /* @__PURE__ */ new Set();
7961
8176
  const calledOn = /* @__PURE__ */ new Map();
7962
8177
  sourceFile.forEachDescendant((node) => {
7963
- if (Node32.isVariableDeclaration(node)) {
8178
+ if (Node34.isVariableDeclaration(node)) {
7964
8179
  const init = node.getInitializer();
7965
- if (init !== void 0 && Node32.isCallExpression(init)) {
8180
+ if (init !== void 0 && Node34.isCallExpression(init)) {
7966
8181
  setToCalls.add(node.getName());
7967
8182
  }
7968
8183
  return;
7969
8184
  }
7970
- if (!Node32.isCallExpression(node)) {
8185
+ if (!Node34.isCallExpression(node)) {
7971
8186
  return;
7972
8187
  }
7973
8188
  const callee = node.getExpression();
7974
- if (!Node32.isPropertyAccessExpression(callee) || !Node32.isIdentifier(callee.getExpression())) {
8189
+ if (!Node34.isPropertyAccessExpression(callee) || !Node34.isIdentifier(callee.getExpression())) {
7975
8190
  return;
7976
8191
  }
7977
8192
  const receiver = callee.getExpression().getText();
@@ -7998,18 +8213,18 @@ function registrationSubjectsOf(sourceFile, importModule, importName, resolution
7998
8213
  return subjects;
7999
8214
  }
8000
8215
  sourceFile.forEachDescendant((node) => {
8001
- if (Node32.isVariableDeclaration(node)) {
8216
+ if (Node34.isVariableDeclaration(node)) {
8002
8217
  const init = node.getInitializer();
8003
8218
  if (init === void 0) {
8004
8219
  return;
8005
8220
  }
8006
- const calleeText = Node32.isCallExpression(init) || Node32.isNewExpression(init) ? init.getExpression().getText() : null;
8221
+ const calleeText = Node34.isCallExpression(init) || Node34.isNewExpression(init) ? init.getExpression().getText() : null;
8007
8222
  if (calleeText !== null && spellings.includes(calleeText)) {
8008
8223
  subjects.set(node.getName(), init);
8009
8224
  }
8010
8225
  return;
8011
8226
  }
8012
- if (!Node32.isParameterDeclaration(node)) {
8227
+ if (!Node34.isParameterDeclaration(node)) {
8013
8228
  return;
8014
8229
  }
8015
8230
  const typeNode = node.getTypeNode();
@@ -8030,7 +8245,7 @@ function creationSiteBehind(parameter, resolution) {
8030
8245
  return parameter;
8031
8246
  }
8032
8247
  const written = resolution.resolveWrittenValue(parameter);
8033
- if (written === null || !(Node32.isCallExpression(written) || Node32.isNewExpression(written))) {
8248
+ if (written === null || !(Node34.isCallExpression(written) || Node34.isNewExpression(written))) {
8034
8249
  return parameter;
8035
8250
  }
8036
8251
  return written;
@@ -8073,7 +8288,7 @@ function unboundConstructionsOf(sourceFile, importModule, importName) {
8073
8288
  }
8074
8289
  const constructions = [];
8075
8290
  sourceFile.forEachDescendant((node) => {
8076
- if ((Node32.isCallExpression(node) || Node32.isNewExpression(node)) && spellings.includes(node.getExpression().getText()) && !Node32.isVariableDeclaration(node.getParent())) {
8291
+ if ((Node34.isCallExpression(node) || Node34.isNewExpression(node)) && spellings.includes(node.getExpression().getText()) && !Node34.isVariableDeclaration(node.getParent())) {
8077
8292
  constructions.push(node);
8078
8293
  }
8079
8294
  });
@@ -8091,11 +8306,11 @@ function discoverMountEdges(sourceFile, match, mount, knownSubjectIds, resolutio
8091
8306
  }
8092
8307
  const edges = [];
8093
8308
  sourceFile.forEachDescendant((node) => {
8094
- if (!Node32.isCallExpression(node)) {
8309
+ if (!Node34.isCallExpression(node)) {
8095
8310
  return;
8096
8311
  }
8097
8312
  const callee = node.getExpression();
8098
- if (!Node32.isPropertyAccessExpression(callee) || callee.getName() !== mount.method) {
8313
+ if (!Node34.isPropertyAccessExpression(callee) || callee.getName() !== mount.method) {
8099
8314
  return;
8100
8315
  }
8101
8316
  const subjectNode = subjectNodeFor(
@@ -8109,7 +8324,7 @@ function discoverMountEdges(sourceFile, match, mount, knownSubjectIds, resolutio
8109
8324
  }
8110
8325
  const args = node.getArguments();
8111
8326
  const prefixArg = args[mount.prefixPosition];
8112
- if (prefixArg === void 0 || !(Node32.isStringLiteral(prefixArg) || Node32.isNoSubstitutionTemplateLiteral(prefixArg))) {
8327
+ if (prefixArg === void 0 || !(Node34.isStringLiteral(prefixArg) || Node34.isNoSubstitutionTemplateLiteral(prefixArg))) {
8113
8328
  return;
8114
8329
  }
8115
8330
  const targetNodes = mountTargetsAmong(
@@ -8164,7 +8379,7 @@ function extractRouteInfoFromBinding(call, methodName, binding, resolution) {
8164
8379
  } else {
8165
8380
  const args = call.getArguments();
8166
8381
  const arg = args[binding.method.position];
8167
- if (arg === void 0 || !(Node32.isStringLiteral(arg) || Node32.isNoSubstitutionTemplateLiteral(arg))) {
8382
+ if (arg === void 0 || !(Node34.isStringLiteral(arg) || Node34.isNoSubstitutionTemplateLiteral(arg))) {
8168
8383
  return null;
8169
8384
  }
8170
8385
  method = arg.getLiteralValue().toUpperCase();
@@ -8175,7 +8390,7 @@ function extractRouteInfoFromBinding(call, methodName, binding, resolution) {
8175
8390
  }
8176
8391
 
8177
8392
  // src/discovery/registrationLoop.ts
8178
- import { Node as Node33 } from "ts-morph";
8393
+ import { Node as Node35 } from "ts-morph";
8179
8394
  function discoverRegistrationLoops(sourceFile, match, kind, resolution) {
8180
8395
  const results = [];
8181
8396
  const guard = receiverGuard(sourceFile, match.receiver, resolution);
@@ -8183,7 +8398,7 @@ function discoverRegistrationLoops(sourceFile, match, kind, resolution) {
8183
8398
  return results;
8184
8399
  }
8185
8400
  sourceFile.forEachDescendant((node) => {
8186
- if (!Node33.isForOfStatement(node)) {
8401
+ if (!Node35.isForOfStatement(node)) {
8187
8402
  return;
8188
8403
  }
8189
8404
  const expanded = tryExpandLoop(node, match, kind, resolution, guard);
@@ -8246,13 +8461,13 @@ function tryExpandLoop(loop, match, kind, resolution, guard) {
8246
8461
  }
8247
8462
  function loopVariableName(loop) {
8248
8463
  const initializer = loop.getInitializer();
8249
- if (Node33.isVariableDeclarationList(initializer)) {
8464
+ if (Node35.isVariableDeclarationList(initializer)) {
8250
8465
  const decls = initializer.getDeclarations();
8251
8466
  if (decls.length !== 1) {
8252
8467
  return null;
8253
8468
  }
8254
8469
  const nameNode = decls[0]?.getNameNode();
8255
- if (nameNode !== void 0 && Node33.isIdentifier(nameNode)) {
8470
+ if (nameNode !== void 0 && Node35.isIdentifier(nameNode)) {
8256
8471
  return nameNode.getText();
8257
8472
  }
8258
8473
  }
@@ -8265,14 +8480,14 @@ function bodyReferencesLoopVar(loop, name) {
8265
8480
  if (referenced) {
8266
8481
  return;
8267
8482
  }
8268
- if (!Node33.isCallExpression(node)) {
8483
+ if (!Node35.isCallExpression(node)) {
8269
8484
  return;
8270
8485
  }
8271
8486
  node.forEachDescendant((inner) => {
8272
8487
  if (referenced) {
8273
8488
  return;
8274
8489
  }
8275
- if (Node33.isIdentifier(inner) && inner.getText() === name) {
8490
+ if (Node35.isIdentifier(inner) && inner.getText() === name) {
8276
8491
  referenced = true;
8277
8492
  }
8278
8493
  });
@@ -8282,11 +8497,11 @@ function bodyReferencesLoopVar(loop, name) {
8282
8497
  function bodyCallsOnRoutable(loop, guard, resolution) {
8283
8498
  let found = false;
8284
8499
  loop.getStatement().forEachDescendant((node) => {
8285
- if (found || !Node33.isCallExpression(node)) {
8500
+ if (found || !Node35.isCallExpression(node)) {
8286
8501
  return;
8287
8502
  }
8288
8503
  const callee = node.getExpression();
8289
- if (!Node33.isPropertyAccessExpression(callee) && !Node33.isElementAccessExpression(callee)) {
8504
+ if (!Node35.isPropertyAccessExpression(callee) && !Node35.isElementAccessExpression(callee)) {
8290
8505
  return;
8291
8506
  }
8292
8507
  const subject = callee.getExpression();
@@ -8306,11 +8521,11 @@ function readRouteSpec(element, shape, resolution) {
8306
8521
  let path15 = null;
8307
8522
  let handler = null;
8308
8523
  for (const prop of element.getProperties()) {
8309
- if (Node33.isMethodDeclaration(prop) && prop.getName() === shape.handlerKey) {
8524
+ if (Node35.isMethodDeclaration(prop) && prop.getName() === shape.handlerKey) {
8310
8525
  handler = { func: prop, name: shape.handlerKey };
8311
8526
  continue;
8312
8527
  }
8313
- if (!Node33.isPropertyAssignment(prop)) {
8528
+ if (!Node35.isPropertyAssignment(prop)) {
8314
8529
  continue;
8315
8530
  }
8316
8531
  const name = prop.getName();
@@ -8333,117 +8548,19 @@ function readRouteSpec(element, shape, resolution) {
8333
8548
  return { method, path: path15, handler: handler.func, handlerName: handler.name };
8334
8549
  }
8335
8550
  function readStringLiteralValue(node) {
8336
- if (Node33.isStringLiteral(node) || Node33.isNoSubstitutionTemplateLiteral(node)) {
8551
+ if (Node35.isStringLiteral(node) || Node35.isNoSubstitutionTemplateLiteral(node)) {
8337
8552
  return node.getLiteralValue();
8338
8553
  }
8339
8554
  return null;
8340
8555
  }
8341
8556
  function handlerName(value) {
8342
- return Node33.isIdentifier(value) ? value.getText() : value.getKindName();
8557
+ return Node35.isIdentifier(value) ? value.getText() : value.getKindName();
8343
8558
  }
8344
8559
 
8345
8560
  // src/discovery/registrationTemplate.ts
8346
8561
  import path6 from "path";
8347
- import { Node as Node35 } from "ts-morph";
8562
+ import { Node as Node36 } from "ts-morph";
8348
8563
  import { joinMountedPath as joinMountedPath2 } from "@suss/resolution";
8349
-
8350
- // src/resolve/unfollowedCall.ts
8351
- import {
8352
- Node as Node34,
8353
- SyntaxKind as SyntaxKind8
8354
- } from "ts-morph";
8355
- import {
8356
- unfollowedCallGap,
8357
- worthRecording
8358
- } from "@suss/behavioral-ir";
8359
- function isInExternalCode(sourceFile) {
8360
- if (sourceFile.isDeclarationFile()) {
8361
- return true;
8362
- }
8363
- return sourceFile.getFilePath().includes("/node_modules/");
8364
- }
8365
- function hasBody(fn) {
8366
- if (Node34.isFunctionDeclaration(fn) || Node34.isMethodDeclaration(fn) || Node34.isFunctionExpression(fn)) {
8367
- return fn.getBody?.() !== void 0;
8368
- }
8369
- return true;
8370
- }
8371
- function isDeclaredShape(declaration) {
8372
- return (Node34.isMethodSignature(declaration) || Node34.isPropertySignature(declaration)) && !isInExternalCode(declaration.getSourceFile());
8373
- }
8374
- function isExternalDeclaration(declaration) {
8375
- if (isInExternalCode(declaration.getSourceFile())) {
8376
- return true;
8377
- }
8378
- if (Node34.isImportSpecifier(declaration) || Node34.isImportClause(declaration) || Node34.isNamespaceImport(declaration)) {
8379
- const target = declaration.getFirstAncestorByKind(SyntaxKind8.ImportDeclaration)?.getModuleSpecifierSourceFile();
8380
- return target === void 0 || isInExternalCode(target);
8381
- }
8382
- return declaresAnotherModule(declaration);
8383
- }
8384
- function declaresAnotherModule(declaration) {
8385
- const module = declaration.getFirstAncestorByKind(
8386
- SyntaxKind8.ModuleDeclaration
8387
- );
8388
- return module !== void 0 && Node34.isStringLiteral(module.getNameNode());
8389
- }
8390
- function statesShapeOnly(declaration) {
8391
- if (isExternalDeclaration(declaration)) {
8392
- return false;
8393
- }
8394
- if (Node34.isMethodSignature(declaration) || Node34.isPropertySignature(declaration)) {
8395
- return true;
8396
- }
8397
- if (Node34.isFunctionDeclaration(declaration) || Node34.isMethodDeclaration(declaration)) {
8398
- return declaration.getBody() === void 0;
8399
- }
8400
- return false;
8401
- }
8402
- function declarationsBehind(symbol) {
8403
- if (symbol === void 0) {
8404
- return [];
8405
- }
8406
- const behind = symbol.getAliasedSymbol()?.getDeclarations() ?? [];
8407
- return behind.length > 0 ? behind : symbol.getDeclarations();
8408
- }
8409
- function isParameterOf(declaration, scanning) {
8410
- return Node34.isParameterDeclaration(declaration) && declaration.getParent() === scanning;
8411
- }
8412
- function parameterIndexOf(declarations, scanning) {
8413
- if (scanning === void 0) {
8414
- return void 0;
8415
- }
8416
- const params = scanning.getParameters();
8417
- for (const declaration of declarations) {
8418
- const index = params.findIndex((param) => param === declaration);
8419
- if (index !== -1) {
8420
- return index;
8421
- }
8422
- }
8423
- return void 0;
8424
- }
8425
- function classifyStop(declarations, scanning) {
8426
- if (declarations.length === 0) {
8427
- return "noDeclaration";
8428
- }
8429
- for (const declaration of declarations) {
8430
- if (!isInExternalCode(declaration.getSourceFile())) {
8431
- recordFileDependency(declaration.getSourceFile().getFilePath());
8432
- }
8433
- }
8434
- if (scanning !== void 0 && declarations.some((declaration) => isParameterOf(declaration, scanning))) {
8435
- return "callerSupplied";
8436
- }
8437
- if (declarations.every(isExternalDeclaration)) {
8438
- return "outsideRun";
8439
- }
8440
- if (declarations.some(statesShapeOnly)) {
8441
- return "noBody";
8442
- }
8443
- return "unsettledValue";
8444
- }
8445
-
8446
- // src/discovery/registrationTemplate.ts
8447
8564
  function discoverRegistrationTemplates(sourceFile, match, kind, resolution, mountPrefixes) {
8448
8565
  const results = [];
8449
8566
  for (const node of helperCallsOf(sourceFile, match, resolution)) {
@@ -8504,15 +8621,15 @@ function helperCallsOf(sourceFile, match, resolution) {
8504
8621
  return callsResolvingTo(sourceFile, store, {
8505
8622
  module,
8506
8623
  name: match.helperName
8507
- }).filter(Node35.isCallExpression);
8624
+ }).filter(Node36.isCallExpression);
8508
8625
  }
8509
8626
  const calls = [];
8510
8627
  sourceFile.forEachDescendant((node) => {
8511
- if (!Node35.isCallExpression(node)) {
8628
+ if (!Node36.isCallExpression(node)) {
8512
8629
  return;
8513
8630
  }
8514
8631
  const callee = node.getExpression();
8515
- if (!Node35.isIdentifier(callee) || callee.getText() !== match.helperName) {
8632
+ if (!Node36.isIdentifier(callee) || callee.getText() !== match.helperName) {
8516
8633
  return;
8517
8634
  }
8518
8635
  if (module === void 0 || declaredInModule(callee, module)) {
@@ -8556,7 +8673,7 @@ function substitutePath(template, args) {
8556
8673
  return result;
8557
8674
  }
8558
8675
  function readStringLiteral(node) {
8559
- if (Node35.isStringLiteral(node) || Node35.isNoSubstitutionTemplateLiteral(node)) {
8676
+ if (Node36.isStringLiteral(node) || Node36.isNoSubstitutionTemplateLiteral(node)) {
8560
8677
  return node.getLiteralValue();
8561
8678
  }
8562
8679
  return null;
@@ -8579,7 +8696,7 @@ function resolveHandler(template, args, resolution) {
8579
8696
  return readPropertyAsFunction(arg, prop, resolution);
8580
8697
  }
8581
8698
  function handlerName2(value) {
8582
- return Node35.isIdentifier(value) ? value.getText() : value.getKindName();
8699
+ return Node36.isIdentifier(value) ? value.getText() : value.getKindName();
8583
8700
  }
8584
8701
  function readPropertyAsFunction(arg, prop, resolution) {
8585
8702
  const obj = objectLiteralOf(arg, resolution);
@@ -8590,7 +8707,7 @@ function readPropertyAsFunction(arg, prop, resolution) {
8590
8707
  if (propertyName(property) !== prop) {
8591
8708
  continue;
8592
8709
  }
8593
- if (Node35.isMethodDeclaration(property)) {
8710
+ if (Node36.isMethodDeclaration(property)) {
8594
8711
  return { func: property, name: prop };
8595
8712
  }
8596
8713
  const held = propertyValueOf(property);
@@ -8598,19 +8715,19 @@ function readPropertyAsFunction(arg, prop, resolution) {
8598
8715
  return null;
8599
8716
  }
8600
8717
  const func = functionValueOf(held, resolution);
8601
- return func === null ? null : { func, name: Node35.isIdentifier(held) ? held.getText() : prop };
8718
+ return func === null ? null : { func, name: Node36.isIdentifier(held) ? held.getText() : prop };
8602
8719
  }
8603
8720
  return null;
8604
8721
  }
8605
8722
  function propertyName(property) {
8606
- if (Node35.isPropertyAssignment(property) || Node35.isShorthandPropertyAssignment(property) || Node35.isMethodDeclaration(property)) {
8723
+ if (Node36.isPropertyAssignment(property) || Node36.isShorthandPropertyAssignment(property) || Node36.isMethodDeclaration(property)) {
8607
8724
  return property.getName();
8608
8725
  }
8609
8726
  return null;
8610
8727
  }
8611
8728
 
8612
8729
  // src/discovery/resolverMap.ts
8613
- import { Node as Node36 } from "ts-morph";
8730
+ import { Node as Node37 } from "ts-morph";
8614
8731
  function discoverResolverMaps(sourceFile, match, kind, resolution) {
8615
8732
  const store = resolution ?? new ResolutionStore();
8616
8733
  const mapProperty = match.mapProperty;
@@ -8621,7 +8738,7 @@ function discoverResolverMaps(sourceFile, match, kind, resolution) {
8621
8738
  name: match.importName
8622
8739
  })) {
8623
8740
  const args = node.getArguments();
8624
- if (args.length === 0 || !Node36.isObjectLiteralExpression(args[0])) {
8741
+ if (args.length === 0 || !Node37.isObjectLiteralExpression(args[0])) {
8625
8742
  continue;
8626
8743
  }
8627
8744
  const config = args[0];
@@ -8675,7 +8792,7 @@ function resolverMapObject(prop, resolution) {
8675
8792
  return held === null ? null : objectLiteralOf(held, resolution);
8676
8793
  }
8677
8794
  function extractTypeDefsSdl(config, resolution) {
8678
- if (!Node36.isObjectLiteralExpression(config)) {
8795
+ if (!Node37.isObjectLiteralExpression(config)) {
8679
8796
  return null;
8680
8797
  }
8681
8798
  const prop = config.getProperty("typeDefs");
@@ -8697,15 +8814,15 @@ function schemaSdlOf(expr, resolution) {
8697
8814
  return resolved === null ? null : writtenSdl(resolved);
8698
8815
  }
8699
8816
  function writtenSdl(expr) {
8700
- if (Node36.isStringLiteral(expr) || Node36.isNoSubstitutionTemplateLiteral(expr)) {
8817
+ if (Node37.isStringLiteral(expr) || Node37.isNoSubstitutionTemplateLiteral(expr)) {
8701
8818
  const value = expr.getLiteralValue();
8702
8819
  return value === "" ? null : value;
8703
8820
  }
8704
- if (Node36.isTaggedTemplateExpression(expr)) {
8821
+ if (Node37.isTaggedTemplateExpression(expr)) {
8705
8822
  const tag = expr.getTag();
8706
- if (Node36.isIdentifier(tag) && tag.getText() === "gql") {
8823
+ if (Node37.isIdentifier(tag) && tag.getText() === "gql") {
8707
8824
  const template = expr.getTemplate();
8708
- if (Node36.isNoSubstitutionTemplateLiteral(template)) {
8825
+ if (Node37.isNoSubstitutionTemplateLiteral(template)) {
8709
8826
  return template.getLiteralValue();
8710
8827
  }
8711
8828
  }
@@ -8714,7 +8831,7 @@ function writtenSdl(expr) {
8714
8831
  }
8715
8832
 
8716
8833
  // src/discovery/index.ts
8717
- function runPattern(sourceFile, pattern, resolution, mountPrefixes, expandedElsewhere) {
8834
+ function runPattern(sourceFile, pattern, resolution, mountPrefixes, expandedElsewhere, routeWrapperPattern) {
8718
8835
  if (pattern.match.type === "namedExport") {
8719
8836
  return discoverNamedExports(
8720
8837
  sourceFile,
@@ -8731,7 +8848,8 @@ function runPattern(sourceFile, pattern, resolution, mountPrefixes, expandedElse
8731
8848
  pattern.bindingExtraction,
8732
8849
  resolution,
8733
8850
  mountPrefixes,
8734
- expandedElsewhere
8851
+ expandedElsewhere,
8852
+ routeWrapperPattern
8735
8853
  );
8736
8854
  }
8737
8855
  if (pattern.match.type === "registrationTemplate") {
@@ -8837,19 +8955,26 @@ function runPattern(sourceFile, pattern, resolution, mountPrefixes, expandedElse
8837
8955
  }
8838
8956
  return [];
8839
8957
  }
8958
+ function routeWrapperPatternOf(patterns) {
8959
+ return patterns.find(
8960
+ (pattern) => pattern.wraps !== void 0 && "method" in pattern.wraps && pattern.wraps.continuationParam !== void 0 && pattern.wraps.throwParam === void 0 && pattern.wraps.arity === void 0 && pattern.wraps.scopePosition === void 0
8961
+ );
8962
+ }
8840
8963
  function discoverUnits(sourceFile, patterns, resolution, mountPrefixes, expandedElsewhere) {
8841
8964
  const store = resolution ?? new ResolutionStore();
8842
8965
  const allResults = [];
8966
+ const routeWrapperPattern = routeWrapperPatternOf(patterns);
8843
8967
  for (const pattern of patterns) {
8844
8968
  const found = runPattern(
8845
8969
  sourceFile,
8846
8970
  pattern,
8847
8971
  store,
8848
8972
  mountPrefixes,
8849
- expandedElsewhere
8973
+ expandedElsewhere,
8974
+ routeWrapperPattern
8850
8975
  );
8851
8976
  for (const unit of found) {
8852
- unit.pattern = pattern;
8977
+ unit.pattern ??= pattern;
8853
8978
  }
8854
8979
  allResults.push(...found);
8855
8980
  }
@@ -8868,7 +8993,7 @@ function discoverUnits(sourceFile, patterns, resolution, mountPrefixes, expanded
8868
8993
  // src/resolve/functionBehind.ts
8869
8994
  function symbolBehind(node) {
8870
8995
  const parent = node.getParent();
8871
- if (parent !== void 0 && Node37.isShorthandPropertyAssignment(parent)) {
8996
+ if (parent !== void 0 && Node38.isShorthandPropertyAssignment(parent)) {
8872
8997
  return parent.getValueSymbol();
8873
8998
  }
8874
8999
  return node.getSymbol();
@@ -8898,9 +9023,9 @@ function resolveDecl(decl, calleeName) {
8898
9023
  }
8899
9024
  return { func: fn, name: declName(decl) ?? calleeName };
8900
9025
  }
8901
- if (Node37.isVariableDeclaration(decl)) {
9026
+ if (Node38.isVariableDeclaration(decl)) {
8902
9027
  const init = decl.getInitializer();
8903
- if (init !== void 0 && (Node37.isArrowFunction(init) || Node37.isFunctionExpression(init))) {
9028
+ if (init !== void 0 && (Node38.isArrowFunction(init) || Node38.isFunctionExpression(init))) {
8904
9029
  return { func: init, name: decl.getName() };
8905
9030
  }
8906
9031
  return null;
@@ -8908,20 +9033,20 @@ function resolveDecl(decl, calleeName) {
8908
9033
  return null;
8909
9034
  }
8910
9035
  function declName(decl) {
8911
- if (Node37.isFunctionDeclaration(decl) || Node37.isMethodDeclaration(decl)) {
9036
+ if (Node38.isFunctionDeclaration(decl) || Node38.isMethodDeclaration(decl)) {
8912
9037
  const n = decl.getName?.();
8913
9038
  if (typeof n === "string" && n.length > 0) {
8914
9039
  return n;
8915
9040
  }
8916
9041
  }
8917
- if (Node37.isFunctionExpression(decl)) {
9042
+ if (Node38.isFunctionExpression(decl)) {
8918
9043
  const n = decl.getName();
8919
9044
  if (typeof n === "string" && n.length > 0) {
8920
9045
  return n;
8921
9046
  }
8922
9047
  }
8923
9048
  const parent = decl.getParent();
8924
- if (parent !== void 0 && Node37.isVariableDeclaration(parent)) {
9049
+ if (parent !== void 0 && Node38.isVariableDeclaration(parent)) {
8925
9050
  return parent.getName();
8926
9051
  }
8927
9052
  return null;
@@ -8933,14 +9058,14 @@ function pathAbove(reference) {
8933
9058
  let current2 = reference;
8934
9059
  for (; ; ) {
8935
9060
  const parent = current2.getParent();
8936
- if (parent !== void 0 && Node38.isPropertyAccessExpression(parent) && parent.getExpression() === current2) {
9061
+ if (parent !== void 0 && Node39.isPropertyAccessExpression(parent) && parent.getExpression() === current2) {
8937
9062
  path15.push(parent.getName());
8938
9063
  current2 = parent;
8939
9064
  continue;
8940
9065
  }
8941
- if (parent !== void 0 && Node38.isElementAccessExpression(parent) && parent.getExpression() === current2) {
9066
+ if (parent !== void 0 && Node39.isElementAccessExpression(parent) && parent.getExpression() === current2) {
8942
9067
  const argument = parent.getArgumentExpression();
8943
- if (argument !== void 0 && Node38.isStringLiteral(argument)) {
9068
+ if (argument !== void 0 && Node39.isStringLiteral(argument)) {
8944
9069
  path15.push(argument.getLiteralValue());
8945
9070
  current2 = parent;
8946
9071
  continue;
@@ -8950,11 +9075,11 @@ function pathAbove(reference) {
8950
9075
  }
8951
9076
  }
8952
9077
  function declaresParameterOf(node, func) {
8953
- if (Node38.isParameterDeclaration(node)) {
9078
+ if (Node39.isParameterDeclaration(node)) {
8954
9079
  return node.getParent() === func;
8955
9080
  }
8956
- if (Node38.isBindingElement(node)) {
8957
- const parameter = node.getFirstAncestor(Node38.isParameterDeclaration);
9081
+ if (Node39.isBindingElement(node)) {
9082
+ const parameter = node.getFirstAncestor(Node39.isParameterDeclaration);
8958
9083
  return parameter !== void 0 && parameter.getParent() === func;
8959
9084
  }
8960
9085
  return false;
@@ -8970,7 +9095,7 @@ function parameterReads(func, parameterNames2, barriers = NO_BARRIERS) {
8970
9095
  traversal.skip();
8971
9096
  return;
8972
9097
  }
8973
- if (!Node38.isIdentifier(node) || !wanted.has(node.getText())) {
9098
+ if (!Node39.isIdentifier(node) || !wanted.has(node.getText())) {
8974
9099
  return;
8975
9100
  }
8976
9101
  const declarations = symbolBehind(node)?.getDeclarations() ?? [];
@@ -8993,7 +9118,7 @@ function parameterReads(func, parameterNames2, barriers = NO_BARRIERS) {
8993
9118
  }
8994
9119
 
8995
9120
  // src/resolve/readName.ts
8996
- import { Node as Node39, SyntaxKind as SyntaxKind9 } from "ts-morph";
9121
+ import { Node as Node40, SyntaxKind as SyntaxKind9 } from "ts-morph";
8997
9122
  import { patternHole, referenceName } from "@suss/behavioral-ir";
8998
9123
  var MAX_HELPER_HOPS = 2;
8999
9124
  var UNNAMED_HOLE = "param";
@@ -9028,11 +9153,11 @@ function referenceIn(expr) {
9028
9153
  function parameterPath(expr) {
9029
9154
  const fields = [];
9030
9155
  let step = expr;
9031
- while (Node39.isPropertyAccessExpression(step)) {
9156
+ while (Node40.isPropertyAccessExpression(step)) {
9032
9157
  fields.unshift(step.getName());
9033
9158
  step = step.getExpression();
9034
9159
  }
9035
- if (!Node39.isIdentifier(step) || !isParameter(step)) {
9160
+ if (!Node40.isIdentifier(step) || !isParameter(step)) {
9036
9161
  return null;
9037
9162
  }
9038
9163
  return { root: step.getText(), fields };
@@ -9040,7 +9165,7 @@ function parameterPath(expr) {
9040
9165
  function isParameter(identifier) {
9041
9166
  const declarations = identifier.getSymbol()?.getDeclarations() ?? [];
9042
9167
  return declarations.some(
9043
- (declaration) => Node39.isParameterDeclaration(declaration)
9168
+ (declaration) => Node40.isParameterDeclaration(declaration)
9044
9169
  );
9045
9170
  }
9046
9171
  function read(expr, ctx) {
@@ -9049,25 +9174,25 @@ function read(expr, ctx) {
9049
9174
  }
9050
9175
  const seen = new Set(ctx.seen).add(expr);
9051
9176
  const inner = { ...ctx, seen };
9052
- if (Node39.isStringLiteral(expr) || Node39.isNoSubstitutionTemplateLiteral(expr)) {
9177
+ if (Node40.isStringLiteral(expr) || Node40.isNoSubstitutionTemplateLiteral(expr)) {
9053
9178
  return expr.getLiteralValue();
9054
9179
  }
9055
- if (Node39.isNumericLiteral(expr)) {
9180
+ if (Node40.isNumericLiteral(expr)) {
9056
9181
  return expr.getLiteralText();
9057
9182
  }
9058
- if (Node39.isTemplateExpression(expr)) {
9183
+ if (Node40.isTemplateExpression(expr)) {
9059
9184
  return fromTemplate(expr, inner);
9060
9185
  }
9061
- if (Node39.isParenthesizedExpression(expr)) {
9186
+ if (Node40.isParenthesizedExpression(expr)) {
9062
9187
  return read(peelParens(expr), inner);
9063
9188
  }
9064
- if (Node39.isBinaryExpression(expr)) {
9189
+ if (Node40.isBinaryExpression(expr)) {
9065
9190
  return fromBinary(expr, inner);
9066
9191
  }
9067
- if (Node39.isCallExpression(expr)) {
9192
+ if (Node40.isCallExpression(expr)) {
9068
9193
  return fromCall(expr, inner);
9069
9194
  }
9070
- if (Node39.isIdentifier(expr)) {
9195
+ if (Node40.isIdentifier(expr)) {
9071
9196
  const only = boundOnce(expr, ctx);
9072
9197
  if (only !== null) {
9073
9198
  return read(only.node, { ...inner, bindings: only.scope });
@@ -9087,17 +9212,17 @@ function read(expr, ctx) {
9087
9212
  }
9088
9213
  function isFallbackBranch(node) {
9089
9214
  let step = node.getParent();
9090
- while (step !== void 0 && Node39.isParenthesizedExpression(step)) {
9215
+ while (step !== void 0 && Node40.isParenthesizedExpression(step)) {
9091
9216
  step = step.getParent();
9092
9217
  }
9093
- if (step === void 0 || !Node39.isBinaryExpression(step)) {
9218
+ if (step === void 0 || !Node40.isBinaryExpression(step)) {
9094
9219
  return false;
9095
9220
  }
9096
9221
  const operator = step.getOperatorToken().getKind();
9097
9222
  return operator === SyntaxKind9.BarBarToken || operator === SyntaxKind9.QuestionQuestionToken;
9098
9223
  }
9099
9224
  function fromTemplate(expr, ctx) {
9100
- if (!Node39.isTemplateExpression(expr)) {
9225
+ if (!Node40.isTemplateExpression(expr)) {
9101
9226
  return null;
9102
9227
  }
9103
9228
  let name = expr.getHead().getLiteralText();
@@ -9108,7 +9233,7 @@ function fromTemplate(expr, ctx) {
9108
9233
  return name;
9109
9234
  }
9110
9235
  function fromBinary(expr, ctx) {
9111
- if (!Node39.isBinaryExpression(expr)) {
9236
+ if (!Node40.isBinaryExpression(expr)) {
9112
9237
  return null;
9113
9238
  }
9114
9239
  const operator = expr.getOperatorToken().getKind();
@@ -9122,14 +9247,14 @@ function fromBinary(expr, ctx) {
9122
9247
  return readOrHole(expr.getLeft(), parts) + readOrHole(expr.getRight(), parts);
9123
9248
  }
9124
9249
  function fromCall(expr, ctx) {
9125
- if (!Node39.isCallExpression(expr)) {
9250
+ if (!Node40.isCallExpression(expr)) {
9126
9251
  return null;
9127
9252
  }
9128
9253
  const callee = expr.getExpression();
9129
- if (Node39.isPropertyAccessExpression(callee) && callee.getName() === "join") {
9254
+ if (Node40.isPropertyAccessExpression(callee) && callee.getName() === "join") {
9130
9255
  return fromJoin(callee.getExpression(), expr.getArguments(), ctx);
9131
9256
  }
9132
- if (Node39.isIdentifier(callee) && callee.getText() === "String") {
9257
+ if (Node40.isIdentifier(callee) && callee.getText() === "String") {
9133
9258
  const only = expr.getArguments()[0];
9134
9259
  return only === void 0 ? null : readOrHole(only, ctx);
9135
9260
  }
@@ -9148,7 +9273,7 @@ function fromCall(expr, ctx) {
9148
9273
  }
9149
9274
  function fromJoin(subject, args, ctx) {
9150
9275
  const separator = args[0];
9151
- if (separator === void 0 || !Node39.isStringLiteral(separator)) {
9276
+ if (separator === void 0 || !Node40.isStringLiteral(separator)) {
9152
9277
  return null;
9153
9278
  }
9154
9279
  const parts = elementsOf(subject, ctx);
@@ -9164,17 +9289,17 @@ function fromJoin(subject, args, ctx) {
9164
9289
  ).join(separator.getLiteralValue());
9165
9290
  }
9166
9291
  function elementsOf(subject, ctx) {
9167
- if (Node39.isArrayLiteralExpression(subject)) {
9292
+ if (Node40.isArrayLiteralExpression(subject)) {
9168
9293
  return subject.getElements().map((element) => here(element, ctx));
9169
9294
  }
9170
- if (Node39.isCallExpression(subject)) {
9295
+ if (Node40.isCallExpression(subject)) {
9171
9296
  const callee = subject.getExpression();
9172
- if (Node39.isPropertyAccessExpression(callee) && callee.getName() === "map") {
9297
+ if (Node40.isPropertyAccessExpression(callee) && callee.getName() === "map") {
9173
9298
  return elementsOf(callee.getExpression(), ctx);
9174
9299
  }
9175
9300
  return null;
9176
9301
  }
9177
- if (!Node39.isIdentifier(subject)) {
9302
+ if (!Node40.isIdentifier(subject)) {
9178
9303
  return null;
9179
9304
  }
9180
9305
  const bound = ctx.bindings.get(subject.getText());
@@ -9182,7 +9307,7 @@ function elementsOf(subject, ctx) {
9182
9307
  return null;
9183
9308
  }
9184
9309
  const only = bound.length === 1 ? bound[0] : void 0;
9185
- return only !== void 0 && Node39.isArrayLiteralExpression(only.node) ? only.node.getElements().map((element) => here(element, ctx)) : bound;
9310
+ return only !== void 0 && Node40.isArrayLiteralExpression(only.node) ? only.node.getElements().map((element) => here(element, ctx)) : bound;
9186
9311
  }
9187
9312
  function singleReturnBody(callee, ctx) {
9188
9313
  const declaration = declarationOf2(callee, ctx);
@@ -9197,22 +9322,22 @@ function singleReturnBody(callee, ctx) {
9197
9322
  if (body === void 0) {
9198
9323
  return null;
9199
9324
  }
9200
- if (Node39.isExpression(body)) {
9325
+ if (Node40.isExpression(body)) {
9201
9326
  return { parameters, returned: body };
9202
9327
  }
9203
- if (!Node39.isBlock(body)) {
9328
+ if (!Node40.isBlock(body)) {
9204
9329
  return null;
9205
9330
  }
9206
9331
  const statements = body.getStatements();
9207
9332
  const only = statements[0];
9208
- if (statements.length !== 1 || only === void 0 || !Node39.isReturnStatement(only)) {
9333
+ if (statements.length !== 1 || only === void 0 || !Node40.isReturnStatement(only)) {
9209
9334
  return null;
9210
9335
  }
9211
9336
  const returned = only.getExpression();
9212
9337
  return returned === void 0 ? null : { parameters, returned };
9213
9338
  }
9214
9339
  function declarationOf2(callee, ctx) {
9215
- const symbol = Node39.isPropertyAccessExpression(callee) ? callee.getNameNode().getSymbol() : callee.getSymbol();
9340
+ const symbol = Node40.isPropertyAccessExpression(callee) ? callee.getNameNode().getSymbol() : callee.getSymbol();
9216
9341
  const declarations = symbol?.getAliasedSymbol()?.getDeclarations() ?? symbol?.getDeclarations() ?? [];
9217
9342
  for (const declaration of declarations) {
9218
9343
  const callable = asCallable(declaration);
@@ -9224,14 +9349,14 @@ function declarationOf2(callee, ctx) {
9224
9349
  return written === null || written === callee ? null : declarationOf2(written, { ...ctx, resolve: () => null });
9225
9350
  }
9226
9351
  function asCallable(declaration) {
9227
- if (Node39.isFunctionDeclaration(declaration) || Node39.isMethodDeclaration(declaration) || Node39.isArrowFunction(declaration) || Node39.isFunctionExpression(declaration)) {
9352
+ if (Node40.isFunctionDeclaration(declaration) || Node40.isMethodDeclaration(declaration) || Node40.isArrowFunction(declaration) || Node40.isFunctionExpression(declaration)) {
9228
9353
  return declaration;
9229
9354
  }
9230
- if (!Node39.isVariableDeclaration(declaration)) {
9355
+ if (!Node40.isVariableDeclaration(declaration)) {
9231
9356
  return null;
9232
9357
  }
9233
9358
  const initializer = declaration.getInitializer();
9234
- if (initializer !== void 0 && (Node39.isArrowFunction(initializer) || Node39.isFunctionExpression(initializer))) {
9359
+ if (initializer !== void 0 && (Node40.isArrowFunction(initializer) || Node40.isFunctionExpression(initializer))) {
9235
9360
  return initializer;
9236
9361
  }
9237
9362
  return null;
@@ -9253,7 +9378,7 @@ function here(node, ctx) {
9253
9378
  return { node, scope: ctx.bindings };
9254
9379
  }
9255
9380
  function boundOnce(expr, ctx) {
9256
- const bound = Node39.isIdentifier(expr) ? ctx.bindings.get(expr.getText()) : void 0;
9381
+ const bound = Node40.isIdentifier(expr) ? ctx.bindings.get(expr.getText()) : void 0;
9257
9382
  return bound !== void 0 && bound.length === 1 ? bound[0] : null;
9258
9383
  }
9259
9384
  function readOrHole(expr, ctx) {
@@ -9265,10 +9390,10 @@ function holeName(expr, ctx) {
9265
9390
  if (bound !== null) {
9266
9391
  return holeName(bound.node, { ...ctx, bindings: bound.scope });
9267
9392
  }
9268
- if (Node39.isIdentifier(expr)) {
9393
+ if (Node40.isIdentifier(expr)) {
9269
9394
  return expr.getText();
9270
9395
  }
9271
- if (Node39.isPropertyAccessExpression(expr)) {
9396
+ if (Node40.isPropertyAccessExpression(expr)) {
9272
9397
  return expr.getName();
9273
9398
  }
9274
9399
  return UNNAMED_HOLE;
@@ -9295,8 +9420,8 @@ function madeFromNamed(origin, made) {
9295
9420
  return origin.named.includes(constructorName(made));
9296
9421
  }
9297
9422
  function constructorName(made) {
9298
- const expression = Node40.isNewExpression(made) || Node40.isCallExpression(made) ? made.getExpression() : made;
9299
- return Node40.isPropertyAccessExpression(expression) ? expression.getName() : expression.getText();
9423
+ const expression = Node41.isNewExpression(made) || Node41.isCallExpression(made) ? made.getExpression() : made;
9424
+ return Node41.isPropertyAccessExpression(expression) ? expression.getName() : expression.getText();
9300
9425
  }
9301
9426
  var CALL_ORIGIN = {
9302
9427
  declaredBy: ORIGIN.declaredBy,
@@ -9310,7 +9435,7 @@ var CALL_ORIGIN = {
9310
9435
  };
9311
9436
  function madeBy(receiver) {
9312
9437
  const made = madeExpression(receiver);
9313
- const expression = Node40.isNewExpression(made) || Node40.isCallExpression(made) ? made.getExpression() : made;
9438
+ const expression = Node41.isNewExpression(made) || Node41.isCallExpression(made) ? made.getExpression() : made;
9314
9439
  return rootIdentifier(expression) ?? expression;
9315
9440
  }
9316
9441
  function madeExpression(receiver) {
@@ -9318,7 +9443,7 @@ function madeExpression(receiver) {
9318
9443
  return receiver.expression;
9319
9444
  }
9320
9445
  const written = receiver.resolve(receiver.callee.getExpression());
9321
- if (written === null || !Node40.isNewExpression(written) && !Node40.isCallExpression(written)) {
9446
+ if (written === null || !Node41.isNewExpression(written) && !Node41.isCallExpression(written)) {
9322
9447
  return receiver.callee;
9323
9448
  }
9324
9449
  return written;
@@ -9326,7 +9451,7 @@ function madeExpression(receiver) {
9326
9451
  function callOpsFor(call, resolveWrittenValue, originatesFrom, anchorCallsOf) {
9327
9452
  const resolve2 = resolveWrittenValue ?? (() => null);
9328
9453
  const expression = calleeOf3(call);
9329
- const callee = Node40.isPropertyAccessExpression(expression) ? expression : null;
9454
+ const callee = Node41.isPropertyAccessExpression(expression) ? expression : null;
9330
9455
  let args = null;
9331
9456
  const argumentsOf = () => {
9332
9457
  args ??= argumentsIn(call);
@@ -9349,7 +9474,7 @@ function callOpsFor(call, resolveWrittenValue, originatesFrom, anchorCallsOf) {
9349
9474
  argumentCount: () => argumentsOf().length,
9350
9475
  nameAt: (index, unsettled) => nameAt(argumentsOf()[index], unsettled, resolve2),
9351
9476
  calleeText: () => expression.getText(),
9352
- namedCallee: () => Node40.isIdentifier(expression),
9477
+ namedCallee: () => Node41.isIdentifier(expression),
9353
9478
  parameterReadsAt: (index) => selectorReadsOf(argumentsOf()[index]),
9354
9479
  receiver: () => callee === null ? null : opsOverCall(callee.getExpression(), resolve2),
9355
9480
  argument: (index) => opsOverCall(argumentsOf()[index], resolve2),
@@ -9374,7 +9499,7 @@ function anchorCallBehind(subject, origin, resolve2, originatesFrom, anchorCalls
9374
9499
  return null;
9375
9500
  }
9376
9501
  const found = anchorCallsOf(subject, (candidate) => {
9377
- if (!Node40.isCallExpression(candidate) && !Node40.isNewExpression(candidate)) {
9502
+ if (!Node41.isCallExpression(candidate) && !Node41.isNewExpression(candidate)) {
9378
9503
  return false;
9379
9504
  }
9380
9505
  const candidateCallee = calleeOf3(candidate);
@@ -9389,7 +9514,7 @@ function anchorCallBehind(subject, origin, resolve2, originatesFrom, anchorCalls
9389
9514
  if (distinct.length !== 1 || only === void 0) {
9390
9515
  return null;
9391
9516
  }
9392
- if (!Node40.isCallExpression(only) && !Node40.isNewExpression(only)) {
9517
+ if (!Node41.isCallExpression(only) && !Node41.isNewExpression(only)) {
9393
9518
  return null;
9394
9519
  }
9395
9520
  return callOpsFor(only, resolve2, originatesFrom, anchorCallsOf);
@@ -9409,7 +9534,7 @@ function valueOpsFor(value, resolve2) {
9409
9534
  asArg: () => effectArgOf(written()),
9410
9535
  property: (name) => {
9411
9536
  const object = written();
9412
- const inside = Node40.isObjectLiteralExpression(object) ? initializerOf(object, name) : null;
9537
+ const inside = Node41.isObjectLiteralExpression(object) ? initializerOf(object, name) : null;
9413
9538
  return inside === null ? null : valueOpsFor(inside, resolve2);
9414
9539
  },
9415
9540
  parts: () => literalParts(written()),
@@ -9422,7 +9547,7 @@ function literalParts(value) {
9422
9547
  if (whole !== null) {
9423
9548
  return [whole];
9424
9549
  }
9425
- if (!Node40.isTemplateExpression(written)) {
9550
+ if (!Node41.isTemplateExpression(written)) {
9426
9551
  return null;
9427
9552
  }
9428
9553
  return [
@@ -9432,26 +9557,26 @@ function literalParts(value) {
9432
9557
  }
9433
9558
  function templateHoles(value, resolve2) {
9434
9559
  const written = untagged(value);
9435
- if (!Node40.isTemplateExpression(written)) {
9560
+ if (!Node41.isTemplateExpression(written)) {
9436
9561
  return [];
9437
9562
  }
9438
9563
  return written.getTemplateSpans().map((span) => opsOverCall(span.getExpression(), resolve2));
9439
9564
  }
9440
9565
  function untagged(value) {
9441
- return Node40.isTaggedTemplateExpression(value) ? value.getTemplate() : value;
9566
+ return Node41.isTaggedTemplateExpression(value) ? value.getTemplate() : value;
9442
9567
  }
9443
9568
  function entriesOf(value, unsettled, resolve2) {
9444
- if (!Node40.isObjectLiteralExpression(value)) {
9569
+ if (!Node41.isObjectLiteralExpression(value)) {
9445
9570
  return [];
9446
9571
  }
9447
9572
  const found = [];
9448
9573
  for (const written of value.getProperties()) {
9449
- if (Node40.isShorthandPropertyAssignment(written)) {
9574
+ if (Node41.isShorthandPropertyAssignment(written)) {
9450
9575
  const name = written.getNameNode();
9451
9576
  found.push({ key: name.getText(), value: valueOpsFor(name, resolve2) });
9452
9577
  continue;
9453
9578
  }
9454
- if (!Node40.isPropertyAssignment(written)) {
9579
+ if (!Node41.isPropertyAssignment(written)) {
9455
9580
  continue;
9456
9581
  }
9457
9582
  const stated = written.getInitializer();
@@ -9464,35 +9589,35 @@ function entriesOf(value, unsettled, resolve2) {
9464
9589
  }
9465
9590
  function entryKey(written, unsettled, resolve2) {
9466
9591
  const name = written.getNameNode();
9467
- if (Node40.isComputedPropertyName(name)) {
9592
+ if (Node41.isComputedPropertyName(name)) {
9468
9593
  return readName(name.getExpression(), { resolve: resolve2, unsettled });
9469
9594
  }
9470
9595
  return unquoted(written.getName());
9471
9596
  }
9472
9597
  function itemsOf(value, resolve2) {
9473
- if (!Node40.isArrayLiteralExpression(value)) {
9598
+ if (!Node41.isArrayLiteralExpression(value)) {
9474
9599
  return [];
9475
9600
  }
9476
9601
  return value.getElements().map((element) => valueOpsFor(element, resolve2));
9477
9602
  }
9478
9603
  function literalText(value) {
9479
- return Node40.isStringLiteral(value) || Node40.isNoSubstitutionTemplateLiteral(value) ? value.getLiteralValue() : null;
9604
+ return Node41.isStringLiteral(value) || Node41.isNoSubstitutionTemplateLiteral(value) ? value.getLiteralValue() : null;
9480
9605
  }
9481
9606
  function literalFlag(value) {
9482
- if (Node40.isTrueLiteral(value) || Node40.isFalseLiteral(value)) {
9483
- return Node40.isTrueLiteral(value);
9607
+ if (Node41.isTrueLiteral(value) || Node41.isFalseLiteral(value)) {
9608
+ return Node41.isTrueLiteral(value);
9484
9609
  }
9485
- return Node40.isNumericLiteral(value) ? value.getLiteralValue() !== 0 : null;
9610
+ return Node41.isNumericLiteral(value) ? value.getLiteralValue() !== 0 : null;
9486
9611
  }
9487
9612
  function unquoted(name) {
9488
9613
  return name.replace(/^["']|["']$/g, "");
9489
9614
  }
9490
9615
  function selectorReadsOf(argument) {
9491
- if (argument === void 0 || !Node40.isArrowFunction(argument) && !Node40.isFunctionExpression(argument)) {
9616
+ if (argument === void 0 || !Node41.isArrowFunction(argument) && !Node41.isFunctionExpression(argument)) {
9492
9617
  return null;
9493
9618
  }
9494
9619
  const parameter = argument.getParameters()[0];
9495
- if (parameter === void 0 || !Node40.isIdentifier(parameter.getNameNode())) {
9620
+ if (parameter === void 0 || !Node41.isIdentifier(parameter.getNameNode())) {
9496
9621
  return null;
9497
9622
  }
9498
9623
  const names = /* @__PURE__ */ new Set();
@@ -9509,17 +9634,17 @@ function opsOverCall(value, resolve2) {
9509
9634
  return callOpsFor(written, resolve2);
9510
9635
  }
9511
9636
  function isCalled(value) {
9512
- return Node40.isCallExpression(value) || Node40.isNewExpression(value) || Node40.isTaggedTemplateExpression(value);
9637
+ return Node41.isCallExpression(value) || Node41.isNewExpression(value) || Node41.isTaggedTemplateExpression(value);
9513
9638
  }
9514
9639
  function calleeOf3(call) {
9515
- return Node40.isTaggedTemplateExpression(call) ? call.getTag() : call.getExpression();
9640
+ return Node41.isTaggedTemplateExpression(call) ? call.getTag() : call.getExpression();
9516
9641
  }
9517
9642
  function argumentsIn(call) {
9518
- return Node40.isTaggedTemplateExpression(call) ? [call.getTemplate()] : call.getArguments();
9643
+ return Node41.isTaggedTemplateExpression(call) ? [call.getTemplate()] : call.getArguments();
9519
9644
  }
9520
9645
  function settled(value, resolve2) {
9521
9646
  const step = unwrapped(value ?? null);
9522
- if (step === null || !Node40.isIdentifier(step)) {
9647
+ if (step === null || !Node41.isIdentifier(step)) {
9523
9648
  return step;
9524
9649
  }
9525
9650
  return unwrapped(resolve2(step));
@@ -9546,11 +9671,11 @@ function objectAt(argument, resolve2) {
9546
9671
  if (isCalled(written)) {
9547
9672
  return objectAt(argumentsIn(written)[0], resolve2);
9548
9673
  }
9549
- return Node40.isObjectLiteralExpression(written) ? written : null;
9674
+ return Node41.isObjectLiteralExpression(written) ? written : null;
9550
9675
  }
9551
9676
  function initializerOf(object, property) {
9552
9677
  for (const written of object.getProperties()) {
9553
- if (Node40.isPropertyAssignment(written) && written.getName() === property) {
9678
+ if (Node41.isPropertyAssignment(written) && written.getName() === property) {
9554
9679
  return written.getInitializer() ?? null;
9555
9680
  }
9556
9681
  }
@@ -9580,7 +9705,7 @@ function invocationContextFor(call, resolveWrittenValue, originatesFrom, anchorC
9580
9705
  };
9581
9706
  }
9582
9707
  function isImportedFrom(identifier, expectedModule, originatesFrom) {
9583
- if (!Node41.isIdentifier(identifier)) {
9708
+ if (!Node42.isIdentifier(identifier)) {
9584
9709
  return false;
9585
9710
  }
9586
9711
  const symbol = identifier.getSymbol();
@@ -9601,7 +9726,7 @@ function isImportedFrom(identifier, expectedModule, originatesFrom) {
9601
9726
  );
9602
9727
  }
9603
9728
  function methodDeclaredIn(callee, expectedModule, resolve2, originatesFrom) {
9604
- if (!Node41.isPropertyAccessExpression(callee)) {
9729
+ if (!Node42.isPropertyAccessExpression(callee)) {
9605
9730
  return false;
9606
9731
  }
9607
9732
  const declarations = callee.getNameNode().getSymbol()?.getDeclarations();
@@ -9621,37 +9746,37 @@ function maker(written) {
9621
9746
  if (written === null) {
9622
9747
  return null;
9623
9748
  }
9624
- if (Node41.isNewExpression(written) || Node41.isCallExpression(written)) {
9749
+ if (Node42.isNewExpression(written) || Node42.isCallExpression(written)) {
9625
9750
  return written.getExpression();
9626
9751
  }
9627
9752
  return null;
9628
9753
  }
9629
9754
  function rootIdentifier2(expression) {
9630
9755
  let root = expression;
9631
- while (Node41.isPropertyAccessExpression(root)) {
9756
+ while (Node42.isPropertyAccessExpression(root)) {
9632
9757
  root = root.getExpression();
9633
9758
  }
9634
9759
  return root;
9635
9760
  }
9636
9761
  function importSpecifierMatches(decl, expectedModule) {
9637
- if (Node41.isImportSpecifier(decl)) {
9762
+ if (Node42.isImportSpecifier(decl)) {
9638
9763
  return decl.getImportDeclaration().getModuleSpecifierValue() === expectedModule;
9639
9764
  }
9640
- const owner = Node41.isNamespaceImport(decl) ? decl.getParent() : decl;
9641
- if (!Node41.isImportClause(owner)) {
9765
+ const owner = Node42.isNamespaceImport(decl) ? decl.getParent() : decl;
9766
+ if (!Node42.isImportClause(owner)) {
9642
9767
  return false;
9643
9768
  }
9644
9769
  const importDecl = owner.getParent();
9645
- return Node41.isImportDeclaration(importDecl) && importDecl.getModuleSpecifierValue() === expectedModule;
9770
+ return Node42.isImportDeclaration(importDecl) && importDecl.getModuleSpecifierValue() === expectedModule;
9646
9771
  }
9647
9772
  function extractInvocationEffects(func, barriers = NO_BARRIERS) {
9648
9773
  const calls = [];
9649
9774
  func.forEachDescendant((node, traversal) => {
9650
- if (isDescentStop(node, func, barriers) || Node41.isDecorator(node)) {
9775
+ if (isDescentStop(node, func, barriers) || Node42.isDecorator(node)) {
9651
9776
  traversal.skip();
9652
9777
  return;
9653
9778
  }
9654
- if (Node41.isCallExpression(node)) {
9779
+ if (Node42.isCallExpression(node)) {
9655
9780
  calls.push(node);
9656
9781
  }
9657
9782
  });
@@ -9675,10 +9800,10 @@ function invocationAt(call, func) {
9675
9800
  }
9676
9801
  function isAwaited(call) {
9677
9802
  let current2 = call.getParent();
9678
- while (current2 !== void 0 && Node41.isParenthesizedExpression(current2)) {
9803
+ while (current2 !== void 0 && Node42.isParenthesizedExpression(current2)) {
9679
9804
  current2 = current2.getParent();
9680
9805
  }
9681
- return current2 !== void 0 && Node41.isAwaitExpression(current2);
9806
+ return current2 !== void 0 && Node42.isAwaitExpression(current2);
9682
9807
  }
9683
9808
  function runInvocationRecognizers(func, recognizers, barriers = NO_BARRIERS, resolveWrittenValue, originatesFrom, anchorCallsOf) {
9684
9809
  if (recognizers.length === 0) {
@@ -9691,7 +9816,7 @@ function runInvocationRecognizers(func, recognizers, barriers = NO_BARRIERS, res
9691
9816
  traversal.skip();
9692
9817
  return;
9693
9818
  }
9694
- if (!Node41.isCallExpression(node)) {
9819
+ if (!Node42.isCallExpression(node)) {
9695
9820
  return;
9696
9821
  }
9697
9822
  const ctx = invocationContextFor(
@@ -9753,7 +9878,7 @@ function runAccessRecognizersAtModuleScope(sourceFile, recognizers, resolveWritt
9753
9878
  }
9754
9879
  function accessContextFor(node, sourceFile, resolveWrittenValue = () => null, originatesFrom, anchorCallsOf) {
9755
9880
  const given = { access: node, sourceFile, resolveWrittenValue };
9756
- if (Node41.isPropertyAccessExpression(node)) {
9881
+ if (Node42.isPropertyAccessExpression(node)) {
9757
9882
  return given;
9758
9883
  }
9759
9884
  let ops;
@@ -9782,7 +9907,7 @@ function dispatchAccessRecognizers(root, recognizers, isStop, resolveWrittenValu
9782
9907
  traversal.skip();
9783
9908
  return;
9784
9909
  }
9785
- if (!Node41.isPropertyAccessExpression(node) && !Node41.isCallExpression(node) && !Node41.isTaggedTemplateExpression(node)) {
9910
+ if (!Node42.isPropertyAccessExpression(node) && !Node42.isCallExpression(node) && !Node42.isTaggedTemplateExpression(node)) {
9786
9911
  return;
9787
9912
  }
9788
9913
  const ctx = accessContextFor(
@@ -9838,35 +9963,35 @@ function extractArg(node, depth) {
9838
9963
  return extractArg(bare, depth);
9839
9964
  }
9840
9965
  }
9841
- if (Node41.isStringLiteral(node) || Node41.isNoSubstitutionTemplateLiteral(node)) {
9966
+ if (Node42.isStringLiteral(node) || Node42.isNoSubstitutionTemplateLiteral(node)) {
9842
9967
  return { kind: "string", value: node.getLiteralValue() };
9843
9968
  }
9844
- if (Node41.isNumericLiteral(node)) {
9969
+ if (Node42.isNumericLiteral(node)) {
9845
9970
  return { kind: "number", value: node.getLiteralValue() };
9846
9971
  }
9847
- if (Node41.isTrueLiteral(node)) {
9972
+ if (Node42.isTrueLiteral(node)) {
9848
9973
  return { kind: "boolean", value: true };
9849
9974
  }
9850
- if (Node41.isFalseLiteral(node)) {
9975
+ if (Node42.isFalseLiteral(node)) {
9851
9976
  return { kind: "boolean", value: false };
9852
9977
  }
9853
- if (Node41.isTemplateExpression(node)) {
9978
+ if (Node42.isTemplateExpression(node)) {
9854
9979
  return { kind: "template", sourceText: node.getText() };
9855
9980
  }
9856
- if (Node41.isIdentifier(node)) {
9981
+ if (Node42.isIdentifier(node)) {
9857
9982
  const inlined = inlineModuleBinding(node, depth);
9858
9983
  if (inlined !== null) {
9859
9984
  return inlined;
9860
9985
  }
9861
9986
  return { kind: "identifier", name: node.getText() };
9862
9987
  }
9863
- if (Node41.isPropertyAccessExpression(node) || Node41.isElementAccessExpression(node)) {
9988
+ if (Node42.isPropertyAccessExpression(node) || Node42.isElementAccessExpression(node)) {
9864
9989
  return { kind: "identifier", name: node.getText() };
9865
9990
  }
9866
9991
  if (depth <= 0) {
9867
9992
  return null;
9868
9993
  }
9869
- if (Node41.isCallExpression(node)) {
9994
+ if (Node42.isCallExpression(node)) {
9870
9995
  const element = mapCallbackReturn(node);
9871
9996
  if (element !== null) {
9872
9997
  return { kind: "array", items: [extractArg(element, depth - 1)] };
@@ -9877,19 +10002,19 @@ function extractArg(node, depth) {
9877
10002
  args: node.getArguments().map((a) => extractArg(a, depth - 1))
9878
10003
  };
9879
10004
  }
9880
- if (Node41.isNewExpression(node)) {
10005
+ if (Node42.isNewExpression(node)) {
9881
10006
  return {
9882
10007
  kind: "call",
9883
10008
  callee: node.getExpression().getText(),
9884
10009
  args: node.getArguments().map((a) => extractArg(a, depth - 1))
9885
10010
  };
9886
10011
  }
9887
- if (Node41.isObjectLiteralExpression(node)) {
10012
+ if (Node42.isObjectLiteralExpression(node)) {
9888
10013
  const fields = {};
9889
10014
  for (const prop of node.getProperties()) {
9890
- if (Node41.isShorthandPropertyAssignment(prop)) {
10015
+ if (Node42.isShorthandPropertyAssignment(prop)) {
9891
10016
  const nameNode2 = prop.getNameNode();
9892
- if (Node41.isIdentifier(nameNode2)) {
10017
+ if (Node42.isIdentifier(nameNode2)) {
9893
10018
  fields[nameNode2.getText()] = {
9894
10019
  kind: "identifier",
9895
10020
  name: nameNode2.getText()
@@ -9897,14 +10022,14 @@ function extractArg(node, depth) {
9897
10022
  }
9898
10023
  continue;
9899
10024
  }
9900
- if (!Node41.isPropertyAssignment(prop)) {
10025
+ if (!Node42.isPropertyAssignment(prop)) {
9901
10026
  continue;
9902
10027
  }
9903
10028
  const nameNode = prop.getNameNode();
9904
- if (!Node41.isIdentifier(nameNode) && !Node41.isStringLiteral(nameNode) && !Node41.isNoSubstitutionTemplateLiteral(nameNode)) {
10029
+ if (!Node42.isIdentifier(nameNode) && !Node42.isStringLiteral(nameNode) && !Node42.isNoSubstitutionTemplateLiteral(nameNode)) {
9905
10030
  continue;
9906
10031
  }
9907
- const name = Node41.isIdentifier(nameNode) ? nameNode.getText() : nameNode.getLiteralValue();
10032
+ const name = Node42.isIdentifier(nameNode) ? nameNode.getText() : nameNode.getLiteralValue();
9908
10033
  const initializer = prop.getInitializer();
9909
10034
  if (initializer === void 0) {
9910
10035
  continue;
@@ -9913,7 +10038,7 @@ function extractArg(node, depth) {
9913
10038
  }
9914
10039
  return { kind: "object", fields };
9915
10040
  }
9916
- if (Node41.isArrayLiteralExpression(node)) {
10041
+ if (Node42.isArrayLiteralExpression(node)) {
9917
10042
  const items = node.getElements().map((el) => extractArg(el, depth - 1));
9918
10043
  return { kind: "array", items };
9919
10044
  }
@@ -9921,20 +10046,20 @@ function extractArg(node, depth) {
9921
10046
  }
9922
10047
  function mapCallbackReturn(call) {
9923
10048
  const callee = call.getExpression();
9924
- if (!Node41.isPropertyAccessExpression(callee) || callee.getName() !== "map") {
10049
+ if (!Node42.isPropertyAccessExpression(callee) || callee.getName() !== "map") {
9925
10050
  return null;
9926
10051
  }
9927
10052
  const callback = call.getArguments()[0];
9928
- if (callback === void 0 || !(Node41.isArrowFunction(callback) || Node41.isFunctionExpression(callback))) {
10053
+ if (callback === void 0 || !(Node42.isArrowFunction(callback) || Node42.isFunctionExpression(callback))) {
9929
10054
  return null;
9930
10055
  }
9931
10056
  const body = callback.getBody();
9932
- if (!Node41.isBlock(body)) {
10057
+ if (!Node42.isBlock(body)) {
9933
10058
  return body;
9934
10059
  }
9935
10060
  const statements = body.getStatements();
9936
10061
  const only = statements.length === 1 ? statements[0] : void 0;
9937
- return only !== void 0 && Node41.isReturnStatement(only) ? only.getExpression() ?? null : null;
10062
+ return only !== void 0 && Node42.isReturnStatement(only) ? only.getExpression() ?? null : null;
9938
10063
  }
9939
10064
  function collectPreconditions(node, root) {
9940
10065
  return collectAncestorConditionInfosBelow(node, root).map(
@@ -9945,7 +10070,7 @@ function runsOnEveryPath(node, root) {
9945
10070
  let current2 = node;
9946
10071
  while (current2 !== void 0 && current2 !== root) {
9947
10072
  const parent = current2.getParent();
9948
- if (parent !== void 0 && Node41.isTryStatement(parent) && parent.getFinallyBlock() === current2) {
10073
+ if (parent !== void 0 && Node42.isTryStatement(parent) && parent.getFinallyBlock() === current2) {
9949
10074
  return true;
9950
10075
  }
9951
10076
  current2 = parent;
@@ -9968,7 +10093,7 @@ function withPreconditions(effect, preconditions) {
9968
10093
  };
9969
10094
  }
9970
10095
  function inlineModuleBinding(ident, depth) {
9971
- if (!Node41.isIdentifier(ident)) {
10096
+ if (!Node42.isIdentifier(ident)) {
9972
10097
  return null;
9973
10098
  }
9974
10099
  const symbol = ident.getSymbol();
@@ -9976,7 +10101,7 @@ function inlineModuleBinding(ident, depth) {
9976
10101
  return null;
9977
10102
  }
9978
10103
  for (const decl of symbol.getDeclarations()) {
9979
- if (!Node41.isVariableDeclaration(decl)) {
10104
+ if (!Node42.isVariableDeclaration(decl)) {
9980
10105
  continue;
9981
10106
  }
9982
10107
  if (!isModuleScoped(decl)) {
@@ -9997,10 +10122,10 @@ function inlineModuleBinding(ident, depth) {
9997
10122
  function isModuleScoped(decl) {
9998
10123
  let current2 = decl.getParent();
9999
10124
  while (current2 !== void 0) {
10000
- if (Node41.isSourceFile(current2)) {
10125
+ if (Node42.isSourceFile(current2)) {
10001
10126
  return true;
10002
10127
  }
10003
- if (Node41.isVariableDeclarationList(current2) || Node41.isVariableStatement(current2)) {
10128
+ if (Node42.isVariableDeclarationList(current2) || Node42.isVariableStatement(current2)) {
10004
10129
  current2 = current2.getParent();
10005
10130
  continue;
10006
10131
  }
@@ -10014,7 +10139,7 @@ function unwrapCasts(node) {
10014
10139
  function enclosingStatementLine(node) {
10015
10140
  let current2 = node;
10016
10141
  while (current2 !== void 0) {
10017
- if (Node41.isStatement(current2)) {
10142
+ if (Node42.isStatement(current2)) {
10018
10143
  return startLineOf(current2);
10019
10144
  }
10020
10145
  current2 = current2.getParent();
@@ -10023,19 +10148,19 @@ function enclosingStatementLine(node) {
10023
10148
  }
10024
10149
 
10025
10150
  // src/terminals/index.ts
10026
- import { Node as Node51 } from "ts-morph";
10151
+ import { Node as Node52 } from "ts-morph";
10027
10152
 
10028
10153
  // src/terminals/continuation.ts
10029
- import { Node as Node43 } from "ts-morph";
10154
+ import { Node as Node44 } from "ts-morph";
10030
10155
 
10031
10156
  // src/terminals/shared.ts
10032
- import { Node as Node42 } from "ts-morph";
10157
+ import { Node as Node43 } from "ts-morph";
10033
10158
  function parameterPositionOf(identifier, func) {
10034
- if (!Node42.isIdentifier(identifier)) {
10159
+ if (!Node43.isIdentifier(identifier)) {
10035
10160
  return null;
10036
10161
  }
10037
10162
  const declaration = identifier.getSymbol()?.getDeclarations()[0];
10038
- if (declaration === void 0 || !Node42.isParameterDeclaration(declaration)) {
10163
+ if (declaration === void 0 || !Node43.isParameterDeclaration(declaration)) {
10039
10164
  return null;
10040
10165
  }
10041
10166
  const params = func.getParameters();
@@ -10052,17 +10177,17 @@ function returnPositionOf(value) {
10052
10177
  if (parent === void 0) {
10053
10178
  return null;
10054
10179
  }
10055
- if (Node42.isReturnStatement(parent)) {
10180
+ if (Node43.isReturnStatement(parent)) {
10056
10181
  return parent;
10057
10182
  }
10058
- if (Node42.isArrowFunction(parent)) {
10183
+ if (Node43.isArrowFunction(parent)) {
10059
10184
  return parent.getBody() === current2 ? current2 : null;
10060
10185
  }
10061
10186
  if (passesValueThrough(parent)) {
10062
10187
  current2 = parent;
10063
10188
  continue;
10064
10189
  }
10065
- if (Node42.isConditionalExpression(parent) && (parent.getWhenTrue() === current2 || parent.getWhenFalse() === current2)) {
10190
+ if (Node43.isConditionalExpression(parent) && (parent.getWhenTrue() === current2 || parent.getWhenFalse() === current2)) {
10066
10191
  current2 = parent;
10067
10192
  continue;
10068
10193
  }
@@ -10072,7 +10197,7 @@ function returnPositionOf(value) {
10072
10197
 
10073
10198
  // src/terminals/continuation.ts
10074
10199
  function tryMatchParameterCall(node, func, pattern, match) {
10075
- if (!Node43.isCallExpression(node)) {
10200
+ if (!Node44.isCallExpression(node)) {
10076
10201
  return null;
10077
10202
  }
10078
10203
  const callee = node.getExpression();
@@ -10096,13 +10221,13 @@ function tryMatchParameterCall(node, func, pattern, match) {
10096
10221
 
10097
10222
  // src/terminals/extract.ts
10098
10223
  import {
10099
- Node as Node45
10224
+ Node as Node46
10100
10225
  } from "ts-morph";
10101
10226
  import { constantOf } from "@suss/values";
10102
10227
 
10103
10228
  // src/shapes/shapes.ts
10104
10229
  import {
10105
- Node as Node44,
10230
+ Node as Node45,
10106
10231
  SyntaxKind as SyntaxKind10
10107
10232
  } from "ts-morph";
10108
10233
 
@@ -10569,35 +10694,35 @@ function extractShapeWithArguments(node, substitutions) {
10569
10694
  }
10570
10695
  function extractShapeInner(node) {
10571
10696
  const unwrapped2 = peelSyntax(node);
10572
- if (boundArguments !== null && Node44.isIdentifier(unwrapped2)) {
10697
+ if (boundArguments !== null && Node45.isIdentifier(unwrapped2)) {
10573
10698
  const argument = boundArguments.get(unwrapped2.getText());
10574
10699
  if (argument !== void 0 && argument !== unwrapped2) {
10575
10700
  return extractShape(argument);
10576
10701
  }
10577
10702
  }
10578
- if (Node44.isObjectLiteralExpression(unwrapped2)) {
10703
+ if (Node45.isObjectLiteralExpression(unwrapped2)) {
10579
10704
  return shapeFromObjectLiteral(unwrapped2);
10580
10705
  }
10581
- if (Node44.isArrayLiteralExpression(unwrapped2)) {
10706
+ if (Node45.isArrayLiteralExpression(unwrapped2)) {
10582
10707
  return shapeFromArrayLiteral(unwrapped2);
10583
10708
  }
10584
- if (Node44.isStringLiteral(unwrapped2) || Node44.isNoSubstitutionTemplateLiteral(unwrapped2)) {
10709
+ if (Node45.isStringLiteral(unwrapped2) || Node45.isNoSubstitutionTemplateLiteral(unwrapped2)) {
10585
10710
  return { type: "literal", value: unwrapped2.getLiteralValue() };
10586
10711
  }
10587
- if (Node44.isTemplateExpression(unwrapped2)) {
10712
+ if (Node45.isTemplateExpression(unwrapped2)) {
10588
10713
  return { type: "text" };
10589
10714
  }
10590
- if (Node44.isNumericLiteral(unwrapped2)) {
10715
+ if (Node45.isNumericLiteral(unwrapped2)) {
10591
10716
  return numericLiteralShape(
10592
10717
  unwrapped2.getLiteralValue(),
10593
10718
  unwrapped2.getText()
10594
10719
  );
10595
10720
  }
10596
- if (Node44.isPrefixUnaryExpression(unwrapped2)) {
10721
+ if (Node45.isPrefixUnaryExpression(unwrapped2)) {
10597
10722
  const op = unwrapped2.getOperatorToken();
10598
10723
  if (op === SyntaxKind10.MinusToken || op === SyntaxKind10.PlusToken) {
10599
10724
  const inner = unwrapped2.getOperand();
10600
- if (Node44.isNumericLiteral(inner)) {
10725
+ if (Node45.isNumericLiteral(inner)) {
10601
10726
  const v3 = inner.getLiteralValue();
10602
10727
  const signed = op === SyntaxKind10.MinusToken ? -v3 : v3;
10603
10728
  const rawBody = inner.getText();
@@ -10606,7 +10731,7 @@ function extractShapeInner(node) {
10606
10731
  }
10607
10732
  }
10608
10733
  }
10609
- if (Node44.isBigIntLiteral(unwrapped2)) {
10734
+ if (Node45.isBigIntLiteral(unwrapped2)) {
10610
10735
  return { type: "ref", name: "bigint" };
10611
10736
  }
10612
10737
  const kind = unwrapped2.getKind();
@@ -10619,10 +10744,10 @@ function extractShapeInner(node) {
10619
10744
  if (kind === SyntaxKind10.NullKeyword) {
10620
10745
  return { type: "null" };
10621
10746
  }
10622
- if (Node44.isIdentifier(unwrapped2) && unwrapped2.getText() === "undefined") {
10747
+ if (Node45.isIdentifier(unwrapped2) && unwrapped2.getText() === "undefined") {
10623
10748
  return { type: "undefined" };
10624
10749
  }
10625
- if (Node44.isConditionalExpression(unwrapped2)) {
10750
+ if (Node45.isConditionalExpression(unwrapped2)) {
10626
10751
  const whenTrue = extractShape(unwrapped2.getWhenTrue());
10627
10752
  const whenFalse = extractShape(unwrapped2.getWhenFalse());
10628
10753
  const variants = [];
@@ -10653,7 +10778,7 @@ function shapeFromArrayLiteral(arr) {
10653
10778
  }
10654
10779
  const shapes = [];
10655
10780
  for (const el of elements) {
10656
- if (Node44.isSpreadElement(el)) {
10781
+ if (Node45.isSpreadElement(el)) {
10657
10782
  const inner = el.getExpression();
10658
10783
  const innerShape = extractShape(inner);
10659
10784
  if (innerShape?.type === "array") {
@@ -10672,7 +10797,7 @@ function shapeFromObjectLiteral(obj) {
10672
10797
  const properties = {};
10673
10798
  const unresolvedSpreads = [];
10674
10799
  for (const prop of obj.getProperties()) {
10675
- if (Node44.isPropertyAssignment(prop)) {
10800
+ if (Node45.isPropertyAssignment(prop)) {
10676
10801
  const name = propertyName2(prop);
10677
10802
  if (name === null) {
10678
10803
  continue;
@@ -10688,7 +10813,7 @@ function shapeFromObjectLiteral(obj) {
10688
10813
  };
10689
10814
  continue;
10690
10815
  }
10691
- if (Node44.isShorthandPropertyAssignment(prop)) {
10816
+ if (Node45.isShorthandPropertyAssignment(prop)) {
10692
10817
  const name = prop.getName();
10693
10818
  const valueExpr = prop.getNameNode();
10694
10819
  properties[name] = extractShape(valueExpr) ?? {
@@ -10697,7 +10822,7 @@ function shapeFromObjectLiteral(obj) {
10697
10822
  };
10698
10823
  continue;
10699
10824
  }
10700
- if (Node44.isSpreadAssignment(prop)) {
10825
+ if (Node45.isSpreadAssignment(prop)) {
10701
10826
  const expr = prop.getExpression();
10702
10827
  const spreadShape = extractShape(expr);
10703
10828
  if (spreadShape?.type === "record") {
@@ -10716,7 +10841,7 @@ function shapeFromObjectLiteral(obj) {
10716
10841
  }
10717
10842
  function propertyName2(prop) {
10718
10843
  const nameNode = prop.getNameNode();
10719
- if (Node44.isIdentifier(nameNode) || Node44.isStringLiteral(nameNode) || Node44.isNoSubstitutionTemplateLiteral(nameNode) || Node44.isNumericLiteral(nameNode)) {
10844
+ if (Node45.isIdentifier(nameNode) || Node45.isStringLiteral(nameNode) || Node45.isNoSubstitutionTemplateLiteral(nameNode) || Node45.isNumericLiteral(nameNode)) {
10720
10845
  return nameNode.getText().replace(/^["']|["']$/g, "");
10721
10846
  }
10722
10847
  return null;
@@ -10747,15 +10872,15 @@ function unwrapAs(node) {
10747
10872
  }
10748
10873
  function unwrapJsonStringify(node) {
10749
10874
  const outer = unwrapAs(node);
10750
- if (!Node45.isCallExpression(outer)) {
10875
+ if (!Node46.isCallExpression(outer)) {
10751
10876
  return node;
10752
10877
  }
10753
10878
  const callee = outer.getExpression();
10754
- if (!Node45.isPropertyAccessExpression(callee) || callee.getName() !== "stringify") {
10879
+ if (!Node46.isPropertyAccessExpression(callee) || callee.getName() !== "stringify") {
10755
10880
  return node;
10756
10881
  }
10757
10882
  const receiver = callee.getExpression();
10758
- if (!Node45.isIdentifier(receiver) || receiver.getText() !== "JSON") {
10883
+ if (!Node46.isIdentifier(receiver) || receiver.getText() !== "JSON") {
10759
10884
  return node;
10760
10885
  }
10761
10886
  const args = outer.getArguments();
@@ -10765,7 +10890,7 @@ function unwrapJsonStringify(node) {
10765
10890
  return unwrapAs(args[0]);
10766
10891
  }
10767
10892
  function substituted(value, ctx) {
10768
- if (ctx.substitutions === void 0 || !Node45.isIdentifier(value)) {
10893
+ if (ctx.substitutions === void 0 || !Node46.isIdentifier(value)) {
10769
10894
  return value;
10770
10895
  }
10771
10896
  return ctx.substitutions.get(value.getText()) ?? value;
@@ -10809,10 +10934,10 @@ function statusFromProperty(obj, name, ctx) {
10809
10934
  if (prop === void 0) {
10810
10935
  return null;
10811
10936
  }
10812
- if (Node45.isShorthandPropertyAssignment(prop)) {
10937
+ if (Node46.isShorthandPropertyAssignment(prop)) {
10813
10938
  return { type: "dynamic", sourceText: prop.getName() };
10814
10939
  }
10815
- if (!Node45.isPropertyAssignment(prop)) {
10940
+ if (!Node46.isPropertyAssignment(prop)) {
10816
10941
  return null;
10817
10942
  }
10818
10943
  const value = prop.getInitializer();
@@ -10835,7 +10960,7 @@ function extractStatusCodeFromRule(ctx) {
10835
10960
  return null;
10836
10961
  }
10837
10962
  const first = ctx.throwCallArgs?.[0];
10838
- if (first !== void 0 && Node45.isNumericLiteral(first)) {
10963
+ if (first !== void 0 && Node46.isNumericLiteral(first)) {
10839
10964
  const value = first.getLiteralValue();
10840
10965
  if (value >= 100 && value <= 599) {
10841
10966
  return { type: "literal", value };
@@ -10848,7 +10973,7 @@ function extractStatusCodeFromRule(ctx) {
10848
10973
  return null;
10849
10974
  }
10850
10975
  const arg = ctx.throwCallArgs[sc.position];
10851
- if (arg === void 0 || !Node45.isNewExpression(arg)) {
10976
+ if (arg === void 0 || !Node46.isNewExpression(arg)) {
10852
10977
  return null;
10853
10978
  }
10854
10979
  const ctorText = arg.getExpression().getText();
@@ -10857,7 +10982,7 @@ function extractStatusCodeFromRule(ctx) {
10857
10982
  if (sc.from === "argumentProperty") {
10858
10983
  const args = ctx.throwCallArgs ?? ctx.calls?.[0]?.getArguments();
10859
10984
  const arg = args?.[sc.position];
10860
- if (arg === void 0 || !Node45.isObjectLiteralExpression(arg)) {
10985
+ if (arg === void 0 || !Node46.isObjectLiteralExpression(arg)) {
10861
10986
  return null;
10862
10987
  }
10863
10988
  return statusFromProperty(arg, sc.name, ctx);
@@ -10867,8 +10992,8 @@ function extractStatusCodeFromRule(ctx) {
10867
10992
  return null;
10868
10993
  }
10869
10994
  for (const prop of ctx.returnedObj.getProperties()) {
10870
- if (!Node45.isPropertyAssignment(prop)) {
10871
- if (Node45.isShorthandPropertyAssignment(prop)) {
10995
+ if (!Node46.isPropertyAssignment(prop)) {
10996
+ if (Node46.isShorthandPropertyAssignment(prop)) {
10872
10997
  if (prop.getName() === sc.name) {
10873
10998
  const resolved = ctx.substitutions?.get(prop.getName());
10874
10999
  if (resolved !== void 0) {
@@ -10926,8 +11051,8 @@ function extractBody(ctx) {
10926
11051
  return null;
10927
11052
  }
10928
11053
  for (const prop of ctx.returnedObj.getProperties()) {
10929
- if (!Node45.isPropertyAssignment(prop)) {
10930
- if (Node45.isShorthandPropertyAssignment(prop)) {
11054
+ if (!Node46.isPropertyAssignment(prop)) {
11055
+ if (Node46.isShorthandPropertyAssignment(prop)) {
10931
11056
  if (prop.getName() === b.name) {
10932
11057
  const resolved = ctx.substitutions?.get(prop.getName());
10933
11058
  if (resolved !== void 0) {
@@ -10982,16 +11107,16 @@ function extractBody(ctx) {
10982
11107
  }
10983
11108
 
10984
11109
  // src/terminals/jsx.ts
10985
- import { Node as Node46 } from "ts-morph";
11110
+ import { Node as Node47 } from "ts-morph";
10986
11111
  function tryMatchJsxReturn(node, pattern) {
10987
11112
  let expr;
10988
11113
  let source;
10989
- if (Node46.isReturnStatement(node)) {
11114
+ if (Node47.isReturnStatement(node)) {
10990
11115
  expr = node.getExpression();
10991
11116
  source = node;
10992
- } else if (Node46.isArrowFunction(node)) {
11117
+ } else if (Node47.isArrowFunction(node)) {
10993
11118
  const body = node.getBody();
10994
- if (body !== void 0 && !Node46.isBlock(body)) {
11119
+ if (body !== void 0 && !Node47.isBlock(body)) {
10995
11120
  expr = body;
10996
11121
  source = body;
10997
11122
  }
@@ -11022,14 +11147,14 @@ function tryMatchJsxReturn(node, pattern) {
11022
11147
  return { node, source, terminal };
11023
11148
  }
11024
11149
  function componentTargetOf(tagNode) {
11025
- if (!Node46.isIdentifier(tagNode) || !/^[A-Z]/.test(tagNode.getText())) {
11150
+ if (!Node47.isIdentifier(tagNode) || !/^[A-Z]/.test(tagNode.getText())) {
11026
11151
  return null;
11027
11152
  }
11028
11153
  const target = functionTargetOf(tagNode);
11029
11154
  return target === null ? null : { file: target.file, name: target.name };
11030
11155
  }
11031
11156
  function jsxToRenderNode(node) {
11032
- if (Node46.isJsxElement(node)) {
11157
+ if (Node47.isJsxElement(node)) {
11033
11158
  const opening = node.getOpeningElement();
11034
11159
  const tag = opening.getTagNameNode().getText();
11035
11160
  const attrs = collectJsxAttributes(opening);
@@ -11043,7 +11168,7 @@ function jsxToRenderNode(node) {
11043
11168
  ...target !== null ? { target } : {}
11044
11169
  };
11045
11170
  }
11046
- if (Node46.isJsxSelfClosingElement(node)) {
11171
+ if (Node47.isJsxSelfClosingElement(node)) {
11047
11172
  const tag = node.getTagNameNode().getText();
11048
11173
  const attrs = collectJsxAttributes(node);
11049
11174
  const target = componentTargetOf(node.getTagNameNode());
@@ -11055,11 +11180,11 @@ function jsxToRenderNode(node) {
11055
11180
  ...target !== null ? { target } : {}
11056
11181
  };
11057
11182
  }
11058
- if (Node46.isJsxFragment(node)) {
11183
+ if (Node47.isJsxFragment(node)) {
11059
11184
  const children = node.getJsxChildren().map(jsxChildToRenderNode).filter((n) => n !== null);
11060
11185
  return { type: "element", tag: "Fragment", children };
11061
11186
  }
11062
- if (Node46.isParenthesizedExpression(node)) {
11187
+ if (Node47.isParenthesizedExpression(node)) {
11063
11188
  return jsxToRenderNode(node.getExpression());
11064
11189
  }
11065
11190
  return null;
@@ -11067,12 +11192,12 @@ function jsxToRenderNode(node) {
11067
11192
  function collectJsxAttributes(opening) {
11068
11193
  const entries = {};
11069
11194
  for (const attr of opening.getAttributes()) {
11070
- if (Node46.isJsxSpreadAttribute(attr)) {
11195
+ if (Node47.isJsxSpreadAttribute(attr)) {
11071
11196
  const exprText = attr.getExpression().getText();
11072
11197
  entries[`...${exprText}`] = exprText;
11073
11198
  continue;
11074
11199
  }
11075
- if (!Node46.isJsxAttribute(attr)) {
11200
+ if (!Node47.isJsxAttribute(attr)) {
11076
11201
  continue;
11077
11202
  }
11078
11203
  const name = attr.getNameNode().getText();
@@ -11081,7 +11206,7 @@ function collectJsxAttributes(opening) {
11081
11206
  entries[name] = "";
11082
11207
  continue;
11083
11208
  }
11084
- if (Node46.isJsxExpression(initializer)) {
11209
+ if (Node47.isJsxExpression(initializer)) {
11085
11210
  const inner = initializer.getExpression();
11086
11211
  entries[name] = inner !== void 0 ? inner.getText() : "";
11087
11212
  continue;
@@ -11091,30 +11216,30 @@ function collectJsxAttributes(opening) {
11091
11216
  return Object.keys(entries).length > 0 ? entries : null;
11092
11217
  }
11093
11218
  function jsxChildToRenderNode(child) {
11094
- if (Node46.isJsxText(child)) {
11219
+ if (Node47.isJsxText(child)) {
11095
11220
  const text = child.getLiteralText().trim();
11096
11221
  if (text.length === 0) {
11097
11222
  return null;
11098
11223
  }
11099
11224
  return { type: "text", value: text };
11100
11225
  }
11101
- if (Node46.isJsxExpression(child)) {
11226
+ if (Node47.isJsxExpression(child)) {
11102
11227
  const inner = child.getExpression();
11103
11228
  if (inner === void 0) {
11104
11229
  return null;
11105
11230
  }
11106
11231
  return jsxExpressionToRenderNode(inner);
11107
11232
  }
11108
- if (Node46.isJsxElement(child) || Node46.isJsxSelfClosingElement(child) || Node46.isJsxFragment(child)) {
11233
+ if (Node47.isJsxElement(child) || Node47.isJsxSelfClosingElement(child) || Node47.isJsxFragment(child)) {
11109
11234
  return jsxToRenderNode(child);
11110
11235
  }
11111
11236
  return null;
11112
11237
  }
11113
11238
  function jsxExpressionToRenderNode(expr) {
11114
- if (Node46.isParenthesizedExpression(expr)) {
11239
+ if (Node47.isParenthesizedExpression(expr)) {
11115
11240
  return jsxExpressionToRenderNode(expr.getExpression());
11116
11241
  }
11117
- if (Node46.isBinaryExpression(expr)) {
11242
+ if (Node47.isBinaryExpression(expr)) {
11118
11243
  const op = expr.getOperatorToken().getText();
11119
11244
  if (op === "&&") {
11120
11245
  const right = renderAlternative(peelParens(expr.getRight()));
@@ -11128,7 +11253,7 @@ function jsxExpressionToRenderNode(expr) {
11128
11253
  }
11129
11254
  }
11130
11255
  }
11131
- if (Node46.isConditionalExpression(expr)) {
11256
+ if (Node47.isConditionalExpression(expr)) {
11132
11257
  const truthy = renderAlternative(peelParens(expr.getWhenTrue()));
11133
11258
  const falsy = renderAlternative(peelParens(expr.getWhenFalse()));
11134
11259
  if (truthy.kind === "jsx") {
@@ -11151,16 +11276,16 @@ function jsxExpressionToRenderNode(expr) {
11151
11276
  return { type: "expression", sourceText: expr.getText() };
11152
11277
  }
11153
11278
  function renderAlternative(node) {
11154
- if (Node46.isNullLiteral(node)) {
11279
+ if (Node47.isNullLiteral(node)) {
11155
11280
  return { kind: "noRender" };
11156
11281
  }
11157
- if (Node46.isFalseLiteral(node)) {
11282
+ if (Node47.isFalseLiteral(node)) {
11158
11283
  return { kind: "noRender" };
11159
11284
  }
11160
- if (Node46.isIdentifier(node) && node.getText() === "undefined") {
11285
+ if (Node47.isIdentifier(node) && node.getText() === "undefined") {
11161
11286
  return { kind: "noRender" };
11162
11287
  }
11163
- if (Node46.isJsxElement(node) || Node46.isJsxSelfClosingElement(node) || Node46.isJsxFragment(node)) {
11288
+ if (Node47.isJsxElement(node) || Node47.isJsxSelfClosingElement(node) || Node47.isJsxFragment(node)) {
11164
11289
  const tree = jsxToRenderNode(node);
11165
11290
  if (tree !== null) {
11166
11291
  return { kind: "jsx", node: tree };
@@ -11171,14 +11296,14 @@ function renderAlternative(node) {
11171
11296
 
11172
11297
  // src/terminals/returns.ts
11173
11298
  import {
11174
- Node as Node49
11299
+ Node as Node50
11175
11300
  } from "ts-morph";
11176
11301
 
11177
11302
  // src/terminals/helperResolution.ts
11178
- import { Node as Node47, SyntaxKind as SyntaxKind11 } from "ts-morph";
11303
+ import { Node as Node48, SyntaxKind as SyntaxKind11 } from "ts-morph";
11179
11304
  function resolveHelperReturn(call, resolveCallee2) {
11180
11305
  const callee = call.getExpression();
11181
- if (!Node47.isIdentifier(callee)) {
11306
+ if (!Node48.isIdentifier(callee)) {
11182
11307
  return { kind: "notLocal" };
11183
11308
  }
11184
11309
  const helper = memoizedLocalHelper(callee, resolveCallee2);
@@ -11208,16 +11333,16 @@ function guardsAbove(returnValue) {
11208
11333
  let child = returnValue;
11209
11334
  let current2 = returnValue.getParent();
11210
11335
  while (current2 !== void 0) {
11211
- if (Node47.isIfStatement(current2)) {
11336
+ if (Node48.isIfStatement(current2)) {
11212
11337
  guards.push({
11213
11338
  condition: current2.getExpression(),
11214
11339
  whenTrue: current2.getThenStatement() === child
11215
11340
  });
11216
11341
  }
11217
- if (Node47.isBlock(current2)) {
11342
+ if (Node48.isBlock(current2)) {
11218
11343
  guards.push(...earlyReturnGuardsBefore(current2, child));
11219
11344
  }
11220
- if (Node47.isFunctionDeclaration(current2) || Node47.isArrowFunction(current2) || Node47.isFunctionExpression(current2)) {
11345
+ if (Node48.isFunctionDeclaration(current2) || Node48.isArrowFunction(current2) || Node48.isFunctionExpression(current2)) {
11221
11346
  break;
11222
11347
  }
11223
11348
  child = current2;
@@ -11226,7 +11351,7 @@ function guardsAbove(returnValue) {
11226
11351
  return guards;
11227
11352
  }
11228
11353
  function earlyReturnGuardsBefore(block, child) {
11229
- if (!Node47.isBlock(block)) {
11354
+ if (!Node48.isBlock(block)) {
11230
11355
  return [];
11231
11356
  }
11232
11357
  const guards = [];
@@ -11234,7 +11359,7 @@ function earlyReturnGuardsBefore(block, child) {
11234
11359
  if (statement === child) {
11235
11360
  break;
11236
11361
  }
11237
- if (!Node47.isIfStatement(statement) || statement.getElseStatement()) {
11362
+ if (!Node48.isIfStatement(statement) || statement.getElseStatement()) {
11238
11363
  continue;
11239
11364
  }
11240
11365
  if (alwaysReturns(statement.getThenStatement())) {
@@ -11244,10 +11369,10 @@ function earlyReturnGuardsBefore(block, child) {
11244
11369
  return guards;
11245
11370
  }
11246
11371
  function alwaysReturns(statement) {
11247
- if (Node47.isReturnStatement(statement) || Node47.isThrowStatement(statement)) {
11372
+ if (Node48.isReturnStatement(statement) || Node48.isThrowStatement(statement)) {
11248
11373
  return true;
11249
11374
  }
11250
- if (!Node47.isBlock(statement)) {
11375
+ if (!Node48.isBlock(statement)) {
11251
11376
  return false;
11252
11377
  }
11253
11378
  const statements = statement.getStatements();
@@ -11265,7 +11390,7 @@ var COMPARISONS = {
11265
11390
  "!=": (a, b) => a !== b
11266
11391
  };
11267
11392
  function evaluateComparison(condition, substitutions) {
11268
- if (!Node47.isBinaryExpression(condition)) {
11393
+ if (!Node48.isBinaryExpression(condition)) {
11269
11394
  return null;
11270
11395
  }
11271
11396
  const left = numberFor(condition.getLeft(), substitutions);
@@ -11277,8 +11402,8 @@ function evaluateComparison(condition, substitutions) {
11277
11402
  return compare === void 0 ? null : compare(left, right);
11278
11403
  }
11279
11404
  function numberFor(node, substitutions) {
11280
- const resolved = Node47.isIdentifier(node) && substitutions.has(node.getText()) ? substitutions.get(node.getText()) : node;
11281
- return Node47.isNumericLiteral(resolved) ? Number(resolved.getText()) : null;
11405
+ const resolved = Node48.isIdentifier(node) && substitutions.has(node.getText()) ? substitutions.get(node.getText()) : node;
11406
+ return Node48.isNumericLiteral(resolved) ? Number(resolved.getText()) : null;
11282
11407
  }
11283
11408
  var helperBySymbol = /* @__PURE__ */ new WeakMap();
11284
11409
  function memoizedLocalHelper(callee, resolveCallee2) {
@@ -11344,8 +11469,8 @@ function implementationBeside(declaration, name) {
11344
11469
  return candidate;
11345
11470
  }
11346
11471
  }
11347
- const variable4 = source.getVariableDeclaration(name);
11348
- const fn = variable4 === void 0 ? null : asFunctionLike(variable4);
11472
+ const variable3 = source.getVariableDeclaration(name);
11473
+ const fn = variable3 === void 0 ? null : asFunctionLike(variable3);
11349
11474
  if (fn !== null) {
11350
11475
  return fn;
11351
11476
  }
@@ -11365,12 +11490,12 @@ function declarationsFor(callee, resolveCallee2) {
11365
11490
  return (aliased ?? symbol).getDeclarations();
11366
11491
  }
11367
11492
  function asFunctionLike(declaration) {
11368
- if (Node47.isFunctionDeclaration(declaration) || Node47.isArrowFunction(declaration) || Node47.isFunctionExpression(declaration)) {
11493
+ if (Node48.isFunctionDeclaration(declaration) || Node48.isArrowFunction(declaration) || Node48.isFunctionExpression(declaration)) {
11369
11494
  return declaration;
11370
11495
  }
11371
- if (Node47.isVariableDeclaration(declaration)) {
11496
+ if (Node48.isVariableDeclaration(declaration)) {
11372
11497
  const initializer = declaration.getInitializer();
11373
- if (initializer !== void 0 && (Node47.isArrowFunction(initializer) || Node47.isFunctionExpression(initializer))) {
11498
+ if (initializer !== void 0 && (Node48.isArrowFunction(initializer) || Node48.isFunctionExpression(initializer))) {
11374
11499
  return initializer;
11375
11500
  }
11376
11501
  }
@@ -11381,9 +11506,9 @@ function returnedObjects(fn) {
11381
11506
  if (body === void 0) {
11382
11507
  return [];
11383
11508
  }
11384
- if (!Node47.isBlock(body)) {
11509
+ if (!Node48.isBlock(body)) {
11385
11510
  const expression = peelParens(body);
11386
- return Node47.isObjectLiteralExpression(expression) ? [expression] : [];
11511
+ return Node48.isObjectLiteralExpression(expression) ? [expression] : [];
11387
11512
  }
11388
11513
  const found = [];
11389
11514
  for (const statement of body.getDescendantsOfKind(
@@ -11397,7 +11522,7 @@ function returnedObjects(fn) {
11397
11522
  continue;
11398
11523
  }
11399
11524
  const unwrapped2 = peelParens(expression);
11400
- if (Node47.isObjectLiteralExpression(unwrapped2)) {
11525
+ if (Node48.isObjectLiteralExpression(unwrapped2)) {
11401
11526
  found.push(unwrapped2);
11402
11527
  }
11403
11528
  }
@@ -11406,7 +11531,7 @@ function returnedObjects(fn) {
11406
11531
  function enclosingFunctionOf(node) {
11407
11532
  let current2 = node.getParent();
11408
11533
  while (current2 !== void 0) {
11409
- if (Node47.isFunctionDeclaration(current2) || Node47.isArrowFunction(current2) || Node47.isFunctionExpression(current2) || Node47.isMethodDeclaration(current2)) {
11534
+ if (Node48.isFunctionDeclaration(current2) || Node48.isArrowFunction(current2) || Node48.isFunctionExpression(current2) || Node48.isMethodDeclaration(current2)) {
11410
11535
  return current2.getBody();
11411
11536
  }
11412
11537
  current2 = current2.getParent();
@@ -11425,7 +11550,7 @@ function bindArguments(callArgs, params) {
11425
11550
  }
11426
11551
 
11427
11552
  // src/terminals/statusBranches.ts
11428
- import { Node as Node48 } from "ts-morph";
11553
+ import { Node as Node49 } from "ts-morph";
11429
11554
  import { constantOf as constantOf2 } from "@suss/values";
11430
11555
  function statusChoicesOf(argument, resolution) {
11431
11556
  const chosen = asConditional(argument);
@@ -11449,10 +11574,10 @@ function asConditional(node) {
11449
11574
  if (direct !== null) {
11450
11575
  return direct;
11451
11576
  }
11452
- if (!Node48.isIdentifier(node)) {
11577
+ if (!Node49.isIdentifier(node)) {
11453
11578
  return null;
11454
11579
  }
11455
- const declaration = node.getSymbol()?.getDeclarations().find(Node48.isVariableDeclaration);
11580
+ const declaration = node.getSymbol()?.getDeclarations().find(Node49.isVariableDeclaration);
11456
11581
  if (declaration === void 0) {
11457
11582
  return null;
11458
11583
  }
@@ -11463,7 +11588,7 @@ function asConditional(node) {
11463
11588
  const only = written.values[0];
11464
11589
  return only === void 0 ? null : toConditional(only);
11465
11590
  }
11466
- var toConditional = (node) => Node48.isConditionalExpression(node) ? node : null;
11591
+ var toConditional = (node) => Node49.isConditionalExpression(node) ? node : null;
11467
11592
  function numberOf(node, resolution) {
11468
11593
  const value = constantOf2(evaluatedValue(node, resolution));
11469
11594
  return typeof value === "number" && Number.isFinite(value) ? value : null;
@@ -11480,7 +11605,7 @@ function unwrapMethodChain(call, match, func) {
11480
11605
  for (let i = methodChain.length - 1; i >= 0; i--) {
11481
11606
  const expectedMethod = methodChain[i];
11482
11607
  const callee = current2.getExpression();
11483
- if (!Node49.isPropertyAccessExpression(callee)) {
11608
+ if (!Node50.isPropertyAccessExpression(callee)) {
11484
11609
  return null;
11485
11610
  }
11486
11611
  if (callee.getName() !== expectedMethod) {
@@ -11496,7 +11621,7 @@ function unwrapMethodChain(call, match, func) {
11496
11621
  return null;
11497
11622
  }
11498
11623
  } else {
11499
- if (!Node49.isCallExpression(subject)) {
11624
+ if (!Node50.isCallExpression(subject)) {
11500
11625
  return null;
11501
11626
  }
11502
11627
  current2 = subject;
@@ -11506,9 +11631,9 @@ function unwrapMethodChain(call, match, func) {
11506
11631
  }
11507
11632
  function withoutPassThroughCalls(subject, passThrough) {
11508
11633
  let current2 = subject;
11509
- while (Node49.isCallExpression(current2)) {
11634
+ while (Node50.isCallExpression(current2)) {
11510
11635
  const callee = current2.getExpression();
11511
- if (!Node49.isPropertyAccessExpression(callee) || !passThrough.includes(callee.getName())) {
11636
+ if (!Node50.isPropertyAccessExpression(callee) || !passThrough.includes(callee.getName())) {
11512
11637
  break;
11513
11638
  }
11514
11639
  current2 = callee.getExpression();
@@ -11520,12 +11645,12 @@ function returnedValueOf(returnStatement) {
11520
11645
  return written === void 0 ? null : unwrapValue(written);
11521
11646
  }
11522
11647
  function tryMatchReturnShape(node, pattern, match, resolution, resolveCallee2) {
11523
- if (Node49.isObjectLiteralExpression(node)) {
11648
+ if (Node50.isObjectLiteralExpression(node)) {
11524
11649
  const source = returnPositionOf(node);
11525
11650
  if (source === null) {
11526
11651
  return [];
11527
11652
  }
11528
- if (Node49.isReturnStatement(source) && returnedValueOf(source) === node) {
11653
+ if (Node50.isReturnStatement(source) && returnedValueOf(source) === node) {
11529
11654
  return [];
11530
11655
  }
11531
11656
  const terminal = terminalFromReturnedObject(
@@ -11538,14 +11663,14 @@ function tryMatchReturnShape(node, pattern, match, resolution, resolveCallee2) {
11538
11663
  );
11539
11664
  return terminal === null ? [] : [{ ...terminal, source }];
11540
11665
  }
11541
- if (!Node49.isReturnStatement(node)) {
11666
+ if (!Node50.isReturnStatement(node)) {
11542
11667
  return [];
11543
11668
  }
11544
11669
  const returned = returnedValueOf(node);
11545
11670
  if (returned === null) {
11546
11671
  return [];
11547
11672
  }
11548
- if (Node49.isObjectLiteralExpression(returned)) {
11673
+ if (Node50.isObjectLiteralExpression(returned)) {
11549
11674
  const terminal = terminalFromReturnedObject(
11550
11675
  returned,
11551
11676
  node,
@@ -11556,7 +11681,7 @@ function tryMatchReturnShape(node, pattern, match, resolution, resolveCallee2) {
11556
11681
  );
11557
11682
  return terminal === null ? [] : [terminal];
11558
11683
  }
11559
- if (!Node49.isCallExpression(returned)) {
11684
+ if (!Node50.isCallExpression(returned)) {
11560
11685
  return [];
11561
11686
  }
11562
11687
  const resolved = resolveHelperReturn(returned, resolveCallee2);
@@ -11593,7 +11718,7 @@ function terminalFromReturnedObject(obj, anchor, pattern, match, substitutions,
11593
11718
  if (required !== void 0 && required.length > 0) {
11594
11719
  const presentNames = /* @__PURE__ */ new Set();
11595
11720
  for (const prop of obj.getProperties()) {
11596
- if (Node49.isPropertyAssignment(prop) || Node49.isShorthandPropertyAssignment(prop)) {
11721
+ if (Node50.isPropertyAssignment(prop) || Node50.isShorthandPropertyAssignment(prop)) {
11597
11722
  presentNames.add(prop.getName());
11598
11723
  }
11599
11724
  }
@@ -11619,7 +11744,7 @@ function terminalFromReturnedObject(obj, anchor, pattern, match, substitutions,
11619
11744
  // When a helper built the value, the anchor is the caller's own
11620
11745
  // return, so it doubles as the provenance. A value reached any other
11621
11746
  // way leaves this unset and its caller fills it in.
11622
- ...Node49.isReturnStatement(anchor) ? { source: anchor } : {},
11747
+ ...Node50.isReturnStatement(anchor) ? { source: anchor } : {},
11623
11748
  terminal: {
11624
11749
  kind: pattern.kind,
11625
11750
  statusCode,
@@ -11638,7 +11763,7 @@ function terminalFromReturnedObject(obj, anchor, pattern, match, substitutions,
11638
11763
  };
11639
11764
  }
11640
11765
  function tryMatchParameterMethodCall(node, func, pattern, match, resolution) {
11641
- if (!Node49.isCallExpression(node)) {
11766
+ if (!Node50.isCallExpression(node)) {
11642
11767
  return [];
11643
11768
  }
11644
11769
  const result = unwrapMethodChain(node, match, func);
@@ -11698,7 +11823,7 @@ function statusArgument(calls, extraction) {
11698
11823
  }
11699
11824
  function returnCoveredByParameterMethodCall(expr, func, patterns) {
11700
11825
  const current2 = unwrapValue(expr);
11701
- if (!Node49.isCallExpression(current2)) {
11826
+ if (!Node50.isCallExpression(current2)) {
11702
11827
  return false;
11703
11828
  }
11704
11829
  for (const pattern of patterns) {
@@ -11714,7 +11839,7 @@ function returnCoveredByParameterMethodCall(expr, func, patterns) {
11714
11839
  }
11715
11840
  function tryMatchReturnStatement(node, pattern, func, allPatterns) {
11716
11841
  const match = pattern.match.type === "returnStatement" ? pattern.match : null;
11717
- if (Node49.isReturnStatement(node)) {
11842
+ if (Node50.isReturnStatement(node)) {
11718
11843
  const expr = node.getExpression();
11719
11844
  if (match?.excludeCallReturns === true) {
11720
11845
  if (expr === void 0) {
@@ -11733,9 +11858,9 @@ function tryMatchReturnStatement(node, pattern, func, allPatterns) {
11733
11858
  }
11734
11859
  return buildReturnTerminal(node, pattern, body);
11735
11860
  }
11736
- if (Node49.isArrowFunction(node)) {
11861
+ if (Node50.isArrowFunction(node)) {
11737
11862
  const body = node.getBody();
11738
- if (body === void 0 || Node49.isBlock(body)) {
11863
+ if (body === void 0 || Node50.isBlock(body)) {
11739
11864
  return null;
11740
11865
  }
11741
11866
  const shape = extractShape(body);
@@ -11793,20 +11918,20 @@ function unresolvedTerminal(kind, node) {
11793
11918
  };
11794
11919
  }
11795
11920
  function calleeSubject(callee) {
11796
- if (Node49.isIdentifier(callee)) {
11921
+ if (Node50.isIdentifier(callee)) {
11797
11922
  return callee;
11798
11923
  }
11799
- if (Node49.isPropertyAccessExpression(callee)) {
11924
+ if (Node50.isPropertyAccessExpression(callee)) {
11800
11925
  const subject = callee.getExpression();
11801
- return Node49.isIdentifier(subject) ? subject : null;
11926
+ return Node50.isIdentifier(subject) ? subject : null;
11802
11927
  }
11803
11928
  return null;
11804
11929
  }
11805
11930
  function tryMatchFunctionCall(node, pattern, match, resolution, originatesFrom) {
11806
- if (!Node49.isCallExpression(node) && !Node49.isNewExpression(node)) {
11931
+ if (!Node50.isCallExpression(node) && !Node50.isNewExpression(node)) {
11807
11932
  return null;
11808
11933
  }
11809
- if (Node49.isNewExpression(node) && returnPositionOf(node) === null) {
11934
+ if (Node50.isNewExpression(node) && returnPositionOf(node) === null) {
11810
11935
  return null;
11811
11936
  }
11812
11937
  const callee = node.getExpression();
@@ -11845,9 +11970,9 @@ function tryMatchFunctionCall(node, pattern, match, resolution, originatesFrom)
11845
11970
  }
11846
11971
 
11847
11972
  // src/terminals/throws.ts
11848
- import { Node as Node50 } from "ts-morph";
11973
+ import { Node as Node51 } from "ts-morph";
11849
11974
  function tryMatchThrowExpression(node, pattern, match, resolution) {
11850
- if (!Node50.isThrowStatement(node)) {
11975
+ if (!Node51.isThrowStatement(node)) {
11851
11976
  return null;
11852
11977
  }
11853
11978
  const thrownExpr = node.getExpression();
@@ -11889,17 +12014,17 @@ function extractThrowMessage(callArgs) {
11889
12014
  return null;
11890
12015
  }
11891
12016
  for (const arg of callArgs) {
11892
- if (Node50.isStringLiteral(arg) || Node50.isNoSubstitutionTemplateLiteral(arg)) {
12017
+ if (Node51.isStringLiteral(arg) || Node51.isNoSubstitutionTemplateLiteral(arg)) {
11893
12018
  return arg.getLiteralValue();
11894
12019
  }
11895
- if (Node50.isTemplateExpression(arg)) {
12020
+ if (Node51.isTemplateExpression(arg)) {
11896
12021
  return arg.getText();
11897
12022
  }
11898
12023
  }
11899
12024
  return null;
11900
12025
  }
11901
12026
  function classifyThrownExpression(thrown, constructorPattern) {
11902
- if (Node50.isCallExpression(thrown) || Node50.isNewExpression(thrown)) {
12027
+ if (Node51.isCallExpression(thrown) || Node51.isNewExpression(thrown)) {
11903
12028
  const calleeText = thrown.getExpression().getText();
11904
12029
  if (constructorPattern !== void 0 && !calleeText.startsWith(constructorPattern)) {
11905
12030
  return null;
@@ -11986,9 +12111,9 @@ function findTerminals(func, patterns, barriers = NO_BARRIERS, resolution, origi
11986
12111
  }
11987
12112
  }
11988
12113
  });
11989
- if (results.length === 0 && Node51.isArrowFunction(func)) {
12114
+ if (results.length === 0 && Node52.isArrowFunction(func)) {
11990
12115
  const body = func.getBody();
11991
- if (body !== void 0 && !Node51.isBlock(body)) {
12116
+ if (body !== void 0 && !Node52.isBlock(body)) {
11992
12117
  for (const pattern of patterns) {
11993
12118
  let found = null;
11994
12119
  if (pattern.match.type === "parameterMethodCall") {
@@ -12023,7 +12148,7 @@ function functionMayFallThrough(func) {
12023
12148
  if (body === void 0) {
12024
12149
  return false;
12025
12150
  }
12026
- if (!Node51.isBlock(body)) {
12151
+ if (!Node52.isBlock(body)) {
12027
12152
  return false;
12028
12153
  }
12029
12154
  const statements = body.getStatements();
@@ -12031,7 +12156,7 @@ function functionMayFallThrough(func) {
12031
12156
  return true;
12032
12157
  }
12033
12158
  const last = statements[statements.length - 1];
12034
- if (Node51.isReturnStatement(last) || Node51.isThrowStatement(last)) {
12159
+ if (Node52.isReturnStatement(last) || Node52.isThrowStatement(last)) {
12035
12160
  return false;
12036
12161
  }
12037
12162
  return true;
@@ -12079,7 +12204,7 @@ function writesTerminal(call, terminalNodes) {
12079
12204
  }
12080
12205
  }
12081
12206
  function isReceiverOf(node, parent) {
12082
- return (Node52.isPropertyAccessExpression(parent) || Node52.isElementAccessExpression(parent) || Node52.isCallExpression(parent)) && parent.getExpression() === node;
12207
+ return (Node53.isPropertyAccessExpression(parent) || Node53.isElementAccessExpression(parent) || Node53.isCallExpression(parent)) && parent.getExpression() === node;
12083
12208
  }
12084
12209
  var isDefaultConditionList = (conditions) => conditions.length === 0 || conditions.every(
12085
12210
  (c) => c.source === "earlyReturn" || c.source === "earlyThrow"
@@ -12089,7 +12214,7 @@ function bodyContentOf(func) {
12089
12214
  if (body === void 0) {
12090
12215
  return "absent";
12091
12216
  }
12092
- if (!Node52.isBlock(body)) {
12217
+ if (!Node53.isBlock(body)) {
12093
12218
  return "statements";
12094
12219
  }
12095
12220
  return body.getStatements().length === 0 ? "empty" : "statements";
@@ -12105,7 +12230,7 @@ function countUnmatchedReturns(func, terminals, barriers = NO_BARRIERS) {
12105
12230
  claimed.add(source);
12106
12231
  }
12107
12232
  }
12108
- if (Node52.isArrowFunction(func) && Node52.isExpression(body)) {
12233
+ if (Node53.isArrowFunction(func) && Node53.isExpression(body)) {
12109
12234
  return claimed.has(body) ? 0 : 1;
12110
12235
  }
12111
12236
  let unmatched = 0;
@@ -12118,7 +12243,7 @@ function countUnmatchedReturns(func, terminals, barriers = NO_BARRIERS) {
12118
12243
  traversal.skip();
12119
12244
  return;
12120
12245
  }
12121
- if (!Node52.isReturnStatement(node)) {
12246
+ if (!Node53.isReturnStatement(node)) {
12122
12247
  return;
12123
12248
  }
12124
12249
  if (node.getExpression() === void 0) {
@@ -12271,7 +12396,7 @@ function accountFor(site, terminalNodes, branches) {
12271
12396
  }
12272
12397
 
12273
12398
  // src/bootstrap/sourceFileLookup.ts
12274
- import { Node as Node53 } from "ts-morph";
12399
+ import { Node as Node54 } from "ts-morph";
12275
12400
  function createSourceFileLookup(project) {
12276
12401
  const all = project.getSourceFiles();
12277
12402
  const byAbs = /* @__PURE__ */ new Map();
@@ -12333,7 +12458,7 @@ function spanKey(span) {
12333
12458
  function indexFunctions(sf) {
12334
12459
  const index = /* @__PURE__ */ new Map();
12335
12460
  sf.forEachDescendant((node) => {
12336
- if (!Node53.isFunctionDeclaration(node) && !Node53.isFunctionExpression(node) && !Node53.isArrowFunction(node) && !Node53.isMethodDeclaration(node)) {
12461
+ if (!Node54.isFunctionDeclaration(node) && !Node54.isFunctionExpression(node) && !Node54.isArrowFunction(node) && !Node54.isMethodDeclaration(node)) {
12337
12462
  return;
12338
12463
  }
12339
12464
  const bySpan = spanKey({ start: node.getStart(), end: node.getEnd() });
@@ -12347,13 +12472,13 @@ function indexFunctions(sf) {
12347
12472
  }
12348
12473
 
12349
12474
  // src/contract.ts
12350
- import { Node as Node54 } from "ts-morph";
12475
+ import { Node as Node55 } from "ts-morph";
12351
12476
  import { restBinding } from "@suss/behavioral-ir";
12352
12477
  function extractDeclaredBody(node) {
12353
12478
  if (node === void 0) {
12354
12479
  return null;
12355
12480
  }
12356
- if (!Node54.isCallExpression(node)) {
12481
+ if (!Node55.isCallExpression(node)) {
12357
12482
  return null;
12358
12483
  }
12359
12484
  const typeArgs = node.getTypeArguments();
@@ -12367,10 +12492,10 @@ function resolveHandlerPropNode(func) {
12367
12492
  if (parent === void 0) {
12368
12493
  return null;
12369
12494
  }
12370
- if (Node54.isPropertyAssignment(parent)) {
12495
+ if (Node55.isPropertyAssignment(parent)) {
12371
12496
  return parent;
12372
12497
  }
12373
- if (Node54.isMethodDeclaration(func)) {
12498
+ if (Node55.isMethodDeclaration(func)) {
12374
12499
  return func;
12375
12500
  }
12376
12501
  return null;
@@ -12382,11 +12507,11 @@ function findRouterCall(unit) {
12382
12507
  return null;
12383
12508
  }
12384
12509
  const handlersObj = propNode.getParent();
12385
- if (handlersObj === void 0 || !Node54.isObjectLiteralExpression(handlersObj)) {
12510
+ if (handlersObj === void 0 || !Node55.isObjectLiteralExpression(handlersObj)) {
12386
12511
  return null;
12387
12512
  }
12388
12513
  const routerCall = handlersObj.getParent();
12389
- if (routerCall === void 0 || !Node54.isCallExpression(routerCall)) {
12514
+ if (routerCall === void 0 || !Node55.isCallExpression(routerCall)) {
12390
12515
  return null;
12391
12516
  }
12392
12517
  const args = routerCall.getArguments();
@@ -12399,17 +12524,17 @@ function findRouterCall(unit) {
12399
12524
  };
12400
12525
  }
12401
12526
  function resolveContractObject(contractArg, resolution) {
12402
- if (Node54.isObjectLiteralExpression(contractArg)) {
12527
+ if (Node55.isObjectLiteralExpression(contractArg)) {
12403
12528
  return contractArg;
12404
12529
  }
12405
- if (Node54.isPropertyAccessExpression(contractArg)) {
12530
+ if (Node55.isPropertyAccessExpression(contractArg)) {
12406
12531
  const base = resolveContractObject(contractArg.getExpression(), resolution);
12407
- if (base === null || !Node54.isObjectLiteralExpression(base)) {
12532
+ if (base === null || !Node55.isObjectLiteralExpression(base)) {
12408
12533
  return null;
12409
12534
  }
12410
12535
  const propName = contractArg.getName();
12411
12536
  for (const prop of base.getProperties()) {
12412
- if (!Node54.isPropertyAssignment(prop)) {
12537
+ if (!Node55.isPropertyAssignment(prop)) {
12413
12538
  continue;
12414
12539
  }
12415
12540
  if (prop.getName() !== propName) {
@@ -12419,20 +12544,20 @@ function resolveContractObject(contractArg, resolution) {
12419
12544
  if (value === void 0) {
12420
12545
  return null;
12421
12546
  }
12422
- if (Node54.isObjectLiteralExpression(value)) {
12547
+ if (Node55.isObjectLiteralExpression(value)) {
12423
12548
  return value;
12424
12549
  }
12425
- if (Node54.isIdentifier(value) || Node54.isPropertyAccessExpression(value)) {
12550
+ if (Node55.isIdentifier(value) || Node55.isPropertyAccessExpression(value)) {
12426
12551
  return resolveContractObject(value, resolution);
12427
12552
  }
12428
- if (Node54.isCallExpression(value)) {
12553
+ if (Node55.isCallExpression(value)) {
12429
12554
  return unwrapContractInit(value);
12430
12555
  }
12431
12556
  return null;
12432
12557
  }
12433
12558
  return null;
12434
12559
  }
12435
- if (!Node54.isIdentifier(contractArg)) {
12560
+ if (!Node55.isIdentifier(contractArg)) {
12436
12561
  return null;
12437
12562
  }
12438
12563
  const symbol = contractArg.getSymbol();
@@ -12444,7 +12569,7 @@ function resolveContractObject(contractArg, resolution) {
12444
12569
  return null;
12445
12570
  }
12446
12571
  const decl = decls[0];
12447
- if (Node54.isImportSpecifier(decl)) {
12572
+ if (Node55.isImportSpecifier(decl)) {
12448
12573
  const importDecl = decl.getImportDeclaration();
12449
12574
  const sourceFile = importDecl.getModuleSpecifierSourceFile();
12450
12575
  if (sourceFile !== void 0 && resolution !== void 0) {
@@ -12453,14 +12578,14 @@ function resolveContractObject(contractArg, resolution) {
12453
12578
  );
12454
12579
  if (exported !== void 0 && exported.length > 0) {
12455
12580
  const exportedDecl = exported[0];
12456
- if (Node54.isVariableDeclaration(exportedDecl)) {
12581
+ if (Node55.isVariableDeclaration(exportedDecl)) {
12457
12582
  return unwrapContractInit(exportedDecl.getInitializer());
12458
12583
  }
12459
12584
  }
12460
12585
  }
12461
12586
  return null;
12462
12587
  }
12463
- if (Node54.isVariableDeclaration(decl)) {
12588
+ if (Node55.isVariableDeclaration(decl)) {
12464
12589
  return unwrapContractInit(decl.getInitializer());
12465
12590
  }
12466
12591
  return null;
@@ -12470,39 +12595,39 @@ function unwrapContractInit(init) {
12470
12595
  return null;
12471
12596
  }
12472
12597
  const node = peelSyntax(init);
12473
- if (Node54.isCallExpression(node)) {
12598
+ if (Node55.isCallExpression(node)) {
12474
12599
  const args = node.getArguments();
12475
- if (args.length > 0 && Node54.isObjectLiteralExpression(args[0])) {
12600
+ if (args.length > 0 && Node55.isObjectLiteralExpression(args[0])) {
12476
12601
  return args[0];
12477
12602
  }
12478
12603
  return null;
12479
12604
  }
12480
- if (Node54.isObjectLiteralExpression(node)) {
12605
+ if (Node55.isObjectLiteralExpression(node)) {
12481
12606
  return node;
12482
12607
  }
12483
12608
  return null;
12484
12609
  }
12485
12610
  function extractEndpointContract(endpointNode, pattern, framework, resolution) {
12486
- if (!Node54.isObjectLiteralExpression(endpointNode)) {
12611
+ if (!Node55.isObjectLiteralExpression(endpointNode)) {
12487
12612
  return null;
12488
12613
  }
12489
12614
  const responses = [];
12490
12615
  let method;
12491
12616
  let path15;
12492
12617
  for (const prop of endpointNode.getProperties()) {
12493
- if (!Node54.isPropertyAssignment(prop)) {
12618
+ if (!Node55.isPropertyAssignment(prop)) {
12494
12619
  continue;
12495
12620
  }
12496
12621
  const propName = prop.getName();
12497
12622
  if (propName === pattern.methodProperty) {
12498
12623
  const val = prop.getInitializer();
12499
- if (val !== void 0 && Node54.isStringLiteral(val)) {
12624
+ if (val !== void 0 && Node55.isStringLiteral(val)) {
12500
12625
  method = val.getLiteralValue();
12501
12626
  }
12502
12627
  }
12503
12628
  if (propName === pattern.pathProperty) {
12504
12629
  const val = prop.getInitializer();
12505
- if (val !== void 0 && Node54.isStringLiteral(val)) {
12630
+ if (val !== void 0 && Node55.isStringLiteral(val)) {
12506
12631
  path15 = val.getLiteralValue();
12507
12632
  }
12508
12633
  }
@@ -12511,7 +12636,7 @@ function extractEndpointContract(endpointNode, pattern, framework, resolution) {
12511
12636
  const val = written === void 0 ? null : objectLiteralOf(written, resolution);
12512
12637
  if (val !== null) {
12513
12638
  for (const respProp of propertiesOf(val, resolution)) {
12514
- if (!Node54.isPropertyAssignment(respProp)) {
12639
+ if (!Node55.isPropertyAssignment(respProp)) {
12515
12640
  continue;
12516
12641
  }
12517
12642
  const statusStr = respProp.getName();
@@ -12561,11 +12686,11 @@ function readContract(unit, pattern, framework, resolution) {
12561
12686
  return null;
12562
12687
  }
12563
12688
  const contractObj = resolveContractObject(routerInfo.contractArg, resolution);
12564
- if (contractObj === null || !Node54.isObjectLiteralExpression(contractObj)) {
12689
+ if (contractObj === null || !Node55.isObjectLiteralExpression(contractObj)) {
12565
12690
  return null;
12566
12691
  }
12567
12692
  for (const prop of contractObj.getProperties()) {
12568
- if (!Node54.isPropertyAssignment(prop)) {
12693
+ if (!Node55.isPropertyAssignment(prop)) {
12569
12694
  continue;
12570
12695
  }
12571
12696
  if (prop.getName() !== routerInfo.handlerName) {
@@ -12590,7 +12715,7 @@ function endpointFromRegistrationArgument(unit, position, resolution) {
12590
12715
  return null;
12591
12716
  }
12592
12717
  const call = func.getParent();
12593
- if (call === void 0 || !Node54.isCallExpression(call)) {
12718
+ if (call === void 0 || !Node55.isCallExpression(call)) {
12594
12719
  return null;
12595
12720
  }
12596
12721
  const args = call.getArguments();
@@ -12602,24 +12727,24 @@ function endpointFromRegistrationArgument(unit, position, resolution) {
12602
12727
  return null;
12603
12728
  }
12604
12729
  let node = arg;
12605
- while (Node54.isAsExpression(node)) {
12730
+ while (Node55.isAsExpression(node)) {
12606
12731
  node = node.getExpression();
12607
12732
  }
12608
- if (Node54.isObjectLiteralExpression(node)) {
12733
+ if (Node55.isObjectLiteralExpression(node)) {
12609
12734
  return node;
12610
12735
  }
12611
- if (Node54.isCallExpression(node)) {
12736
+ if (Node55.isCallExpression(node)) {
12612
12737
  return unwrapContractInit(node);
12613
12738
  }
12614
12739
  return resolveContractObject(node, resolution);
12615
12740
  }
12616
12741
  function readContractForClientCall(callExpression, methodName, pattern, framework, resolution) {
12617
- const callee = Node54.isCallExpression(callExpression) ? callExpression.getExpression() : null;
12618
- if (callee === null || !Node54.isPropertyAccessExpression(callee)) {
12742
+ const callee = Node55.isCallExpression(callExpression) ? callExpression.getExpression() : null;
12743
+ if (callee === null || !Node55.isPropertyAccessExpression(callee)) {
12619
12744
  return null;
12620
12745
  }
12621
12746
  const clientIdentifier = callee.getExpression();
12622
- if (!Node54.isIdentifier(clientIdentifier)) {
12747
+ if (!Node55.isIdentifier(clientIdentifier)) {
12623
12748
  return null;
12624
12749
  }
12625
12750
  const symbol = clientIdentifier.getSymbol();
@@ -12631,11 +12756,11 @@ function readContractForClientCall(callExpression, methodName, pattern, framewor
12631
12756
  return null;
12632
12757
  }
12633
12758
  const decl = decls[0];
12634
- if (!Node54.isVariableDeclaration(decl)) {
12759
+ if (!Node55.isVariableDeclaration(decl)) {
12635
12760
  return null;
12636
12761
  }
12637
12762
  const init = decl.getInitializer();
12638
- if (init === void 0 || !Node54.isCallExpression(init)) {
12763
+ if (init === void 0 || !Node55.isCallExpression(init)) {
12639
12764
  return null;
12640
12765
  }
12641
12766
  const args = init.getArguments();
@@ -12643,11 +12768,11 @@ function readContractForClientCall(callExpression, methodName, pattern, framewor
12643
12768
  return null;
12644
12769
  }
12645
12770
  const contractObj = resolveContractObject(args[0], resolution);
12646
- if (contractObj === null || !Node54.isObjectLiteralExpression(contractObj)) {
12771
+ if (contractObj === null || !Node55.isObjectLiteralExpression(contractObj)) {
12647
12772
  return null;
12648
12773
  }
12649
12774
  for (const prop of contractObj.getProperties()) {
12650
- if (!Node54.isPropertyAssignment(prop)) {
12775
+ if (!Node55.isPropertyAssignment(prop)) {
12651
12776
  continue;
12652
12777
  }
12653
12778
  if (prop.getName() !== methodName) {
@@ -12902,7 +13027,7 @@ import {
12902
13027
  } from "graphql";
12903
13028
  import picomatch2 from "picomatch";
12904
13029
  import {
12905
- Node as Node55
13030
+ Node as Node56
12906
13031
  } from "ts-morph";
12907
13032
  import {
12908
13033
  isGraphqlOperationBinding,
@@ -12947,11 +13072,11 @@ function fragmentsRegisteredIn(sourceFiles) {
12947
13072
  const registered = /* @__PURE__ */ new Set();
12948
13073
  for (const sourceFile of sourceFiles) {
12949
13074
  sourceFile.forEachDescendant((node) => {
12950
- if (!Node55.isCallExpression(node)) {
13075
+ if (!Node56.isCallExpression(node)) {
12951
13076
  return;
12952
13077
  }
12953
13078
  const argument = node.getArguments()[0];
12954
- if (argument === void 0 || !Node55.isNoSubstitutionTemplateLiteral(argument)) {
13079
+ if (argument === void 0 || !Node56.isNoSubstitutionTemplateLiteral(argument)) {
12955
13080
  return;
12956
13081
  }
12957
13082
  for (const name of fragmentOnlyDocumentNames(argument.getLiteralText())) {
@@ -13138,7 +13263,7 @@ function constructionRegistryStatus(construction, spec) {
13138
13263
  if (cacheConstruction === null) {
13139
13264
  return "unknown";
13140
13265
  }
13141
- if (!Node55.isNewExpression(cacheConstruction) && !Node55.isCallExpression(cacheConstruction)) {
13266
+ if (!Node56.isNewExpression(cacheConstruction) && !Node56.isCallExpression(cacheConstruction)) {
13142
13267
  return "unknown";
13143
13268
  }
13144
13269
  const args = cacheConstruction.getArguments();
@@ -13152,15 +13277,15 @@ function constructionRegistryStatus(construction, spec) {
13152
13277
  if (cacheOptions.getProperty(spec.registryProperty) !== void 0) {
13153
13278
  return "configured";
13154
13279
  }
13155
- const hasSpread = cacheOptions.getProperties().some((property) => Node55.isSpreadAssignment(property));
13280
+ const hasSpread = cacheOptions.getProperties().some((property) => Node56.isSpreadAssignment(property));
13156
13281
  return hasSpread ? "unknown" : "absent";
13157
13282
  }
13158
13283
  function firstArgumentObjectLiteral(construction) {
13159
- if (!Node55.isNewExpression(construction) && !Node55.isCallExpression(construction)) {
13284
+ if (!Node56.isNewExpression(construction) && !Node56.isCallExpression(construction)) {
13160
13285
  return null;
13161
13286
  }
13162
13287
  const arg = construction.getArguments()[0];
13163
- if (arg === void 0 || !Node55.isObjectLiteralExpression(arg)) {
13288
+ if (arg === void 0 || !Node56.isObjectLiteralExpression(arg)) {
13164
13289
  return null;
13165
13290
  }
13166
13291
  return arg;
@@ -13170,10 +13295,10 @@ function propertyValueOf2(options, name) {
13170
13295
  if (property === void 0) {
13171
13296
  return null;
13172
13297
  }
13173
- if (Node55.isPropertyAssignment(property)) {
13298
+ if (Node56.isPropertyAssignment(property)) {
13174
13299
  return property.getInitializer() ?? null;
13175
13300
  }
13176
- if (Node55.isShorthandPropertyAssignment(property)) {
13301
+ if (Node56.isShorthandPropertyAssignment(property)) {
13177
13302
  const symbol = property.getProject().getTypeChecker().getShorthandAssignmentValueSymbol(property);
13178
13303
  return symbol?.getValueDeclaration() ?? null;
13179
13304
  }
@@ -13183,13 +13308,13 @@ function resolveToConstructionOf(expression, cacheClass) {
13183
13308
  let current2 = expression;
13184
13309
  for (let hop = 0; hop < 4 && current2 !== void 0; hop += 1) {
13185
13310
  current2 = unwrapExpression2(current2);
13186
- if (Node55.isVariableDeclaration(current2)) {
13311
+ if (Node56.isVariableDeclaration(current2)) {
13187
13312
  current2 = current2.getInitializer();
13188
13313
  continue;
13189
13314
  }
13190
- if (Node55.isNewExpression(current2) || Node55.isCallExpression(current2)) {
13315
+ if (Node56.isNewExpression(current2) || Node56.isCallExpression(current2)) {
13191
13316
  const callee = current2.getExpression();
13192
- if (callee === void 0 || !Node55.isIdentifier(callee)) {
13317
+ if (callee === void 0 || !Node56.isIdentifier(callee)) {
13193
13318
  return null;
13194
13319
  }
13195
13320
  const local = localImportName(
@@ -13199,11 +13324,11 @@ function resolveToConstructionOf(expression, cacheClass) {
13199
13324
  );
13200
13325
  return local !== null && callee.getText() === local ? current2 : null;
13201
13326
  }
13202
- if (!Node55.isIdentifier(current2)) {
13327
+ if (!Node56.isIdentifier(current2)) {
13203
13328
  return null;
13204
13329
  }
13205
13330
  const declaration = current2.getSymbol()?.getValueDeclaration();
13206
- if (declaration === void 0 || !Node55.isVariableDeclaration(declaration)) {
13331
+ if (declaration === void 0 || !Node56.isVariableDeclaration(declaration)) {
13207
13332
  return null;
13208
13333
  }
13209
13334
  current2 = declaration.getInitializer();
@@ -13214,11 +13339,11 @@ function unwrapExpression2(node) {
13214
13339
  return peelSyntax(node);
13215
13340
  }
13216
13341
  function isConstructionNamed(node, localName) {
13217
- if (!Node55.isNewExpression(node) && !Node55.isCallExpression(node)) {
13342
+ if (!Node56.isNewExpression(node) && !Node56.isCallExpression(node)) {
13218
13343
  return false;
13219
13344
  }
13220
13345
  const callee = node.getExpression();
13221
- return callee !== void 0 && Node55.isIdentifier(callee) && callee.getText() === localName;
13346
+ return callee !== void 0 && Node56.isIdentifier(callee) && callee.getText() === localName;
13222
13347
  }
13223
13348
  function localImportName(sourceFile, importModule, importName) {
13224
13349
  for (const one of namedImportsOf(sourceFile, [importModule], {
@@ -13232,11 +13357,11 @@ function localImportName(sourceFile, importModule, importName) {
13232
13357
  }
13233
13358
  function constructionRef(node, uriProperty, resolution) {
13234
13359
  const optionsArg = node.getArguments()[0];
13235
- if (optionsArg === void 0 || !Node55.isObjectLiteralExpression(optionsArg)) {
13360
+ if (optionsArg === void 0 || !Node56.isObjectLiteralExpression(optionsArg)) {
13236
13361
  return null;
13237
13362
  }
13238
13363
  const property = optionsArg.getProperty(uriProperty);
13239
- if (property === void 0 || !Node55.isPropertyAssignment(property)) {
13364
+ if (property === void 0 || !Node56.isPropertyAssignment(property)) {
13240
13365
  return null;
13241
13366
  }
13242
13367
  const value = property.getInitializer();
@@ -13251,10 +13376,10 @@ function constructionRef(node, uriProperty, resolution) {
13251
13376
  }
13252
13377
 
13253
13378
  // src/discovery/helperIndex.ts
13254
- import { Node as Node57 } from "ts-morph";
13379
+ import { Node as Node58 } from "ts-morph";
13255
13380
 
13256
13381
  // src/discovery/helperReading.ts
13257
- import { Node as Node56 } from "ts-morph";
13382
+ import { Node as Node57 } from "ts-morph";
13258
13383
  var UNREAD = { as: "unread" };
13259
13384
  function readHelperSinks(helper) {
13260
13385
  const positions = parameterPositions(helper);
@@ -13264,11 +13389,11 @@ function readHelperSinks(helper) {
13264
13389
  return sinks;
13265
13390
  }
13266
13391
  body.forEachDescendant((node) => {
13267
- if (!Node56.isCallExpression(node)) {
13392
+ if (!Node57.isCallExpression(node)) {
13268
13393
  return;
13269
13394
  }
13270
13395
  const callee = node.getExpression();
13271
- const [method, receiver] = Node56.isPropertyAccessExpression(callee) ? [callee.getName(), readValue(callee.getExpression(), positions)] : [null, UNREAD];
13396
+ const [method, receiver] = Node57.isPropertyAccessExpression(callee) ? [callee.getName(), readValue(callee.getExpression(), positions)] : [null, UNREAD];
13272
13397
  sinks.push({
13273
13398
  method,
13274
13399
  receiver,
@@ -13288,25 +13413,25 @@ function parameterPositions(helper) {
13288
13413
  return positions;
13289
13414
  }
13290
13415
  function readValue(node, positions) {
13291
- if (Node56.isStringLiteral(node) || Node56.isNoSubstitutionTemplateLiteral(node)) {
13416
+ if (Node57.isStringLiteral(node) || Node57.isNoSubstitutionTemplateLiteral(node)) {
13292
13417
  return { as: "text", text: node.getLiteralValue() };
13293
13418
  }
13294
- if (Node56.isTemplateExpression(node)) {
13419
+ if (Node57.isTemplateExpression(node)) {
13295
13420
  return templateText(node, positions);
13296
13421
  }
13297
- if (Node56.isIdentifier(node)) {
13422
+ if (Node57.isIdentifier(node)) {
13298
13423
  const position = positions.get(node.getText());
13299
13424
  return position === void 0 ? UNREAD : { as: "parameter", position };
13300
13425
  }
13301
- if (Node56.isPropertyAccessExpression(node)) {
13426
+ if (Node57.isPropertyAccessExpression(node)) {
13302
13427
  const target = node.getExpression();
13303
- const position = Node56.isIdentifier(target) ? positions.get(target.getText()) : void 0;
13428
+ const position = Node57.isIdentifier(target) ? positions.get(target.getText()) : void 0;
13304
13429
  return position === void 0 ? UNREAD : { as: "parameter", position, property: node.getName() };
13305
13430
  }
13306
- if (Node56.isObjectLiteralExpression(node)) {
13431
+ if (Node57.isObjectLiteralExpression(node)) {
13307
13432
  return objectValue(node, positions);
13308
13433
  }
13309
- if (Node56.isCallExpression(node)) {
13434
+ if (Node57.isCallExpression(node)) {
13310
13435
  return {
13311
13436
  as: "call",
13312
13437
  callee: node.getExpression().getText(),
@@ -13316,13 +13441,13 @@ function readValue(node, positions) {
13316
13441
  return UNREAD;
13317
13442
  }
13318
13443
  function templateText(node, positions) {
13319
- if (!Node56.isTemplateExpression(node)) {
13444
+ if (!Node57.isTemplateExpression(node)) {
13320
13445
  return UNREAD;
13321
13446
  }
13322
13447
  let text = node.getHead().getLiteralText();
13323
13448
  for (const span of node.getTemplateSpans()) {
13324
13449
  const expression = span.getExpression();
13325
- const position = Node56.isIdentifier(expression) ? positions.get(expression.getText()) : void 0;
13450
+ const position = Node57.isIdentifier(expression) ? positions.get(expression.getText()) : void 0;
13326
13451
  if (position === void 0) {
13327
13452
  return UNREAD;
13328
13453
  }
@@ -13331,12 +13456,12 @@ function templateText(node, positions) {
13331
13456
  return { as: "text", text };
13332
13457
  }
13333
13458
  function objectValue(node, positions) {
13334
- if (!Node56.isObjectLiteralExpression(node)) {
13459
+ if (!Node57.isObjectLiteralExpression(node)) {
13335
13460
  return UNREAD;
13336
13461
  }
13337
13462
  const properties = {};
13338
13463
  for (const property of node.getProperties()) {
13339
- if (!Node56.isPropertyAssignment(property)) {
13464
+ if (!Node57.isPropertyAssignment(property)) {
13340
13465
  continue;
13341
13466
  }
13342
13467
  const initializer = property.getInitializer();
@@ -13351,7 +13476,7 @@ function objectValue(node, positions) {
13351
13476
  return { as: "object", properties };
13352
13477
  }
13353
13478
  function propertyKey(name) {
13354
- return Node56.isStringLiteral(name) ? name.getLiteralValue() : name.getText();
13479
+ return Node57.isStringLiteral(name) ? name.getLiteralValue() : name.getText();
13355
13480
  }
13356
13481
 
13357
13482
  // src/discovery/helperIndex.ts
@@ -13481,11 +13606,11 @@ function registrationMatchesOf(pack) {
13481
13606
  }
13482
13607
  function collectHandOffs(sourceFile, subjects, match, resolution, found) {
13483
13608
  sourceFile.forEachDescendant((node) => {
13484
- if (!Node57.isCallExpression(node)) {
13609
+ if (!Node58.isCallExpression(node)) {
13485
13610
  return;
13486
13611
  }
13487
13612
  const callee = node.getExpression();
13488
- if (!Node57.isIdentifier(callee)) {
13613
+ if (!Node58.isIdentifier(callee)) {
13489
13614
  return;
13490
13615
  }
13491
13616
  const handedOver = subjectArgument(node, subjects, match, resolution);
@@ -13500,12 +13625,12 @@ function collectHandOffs(sourceFile, subjects, match, resolution, found) {
13500
13625
  });
13501
13626
  }
13502
13627
  function subjectArgument(call, subjects, match, resolution) {
13503
- if (!Node57.isCallExpression(call)) {
13628
+ if (!Node58.isCallExpression(call)) {
13504
13629
  return -1;
13505
13630
  }
13506
13631
  const args = call.getArguments();
13507
13632
  for (const [position, argument] of args.entries()) {
13508
- if (!Node57.isIdentifier(argument) && !Node57.isPropertyAccessExpression(argument)) {
13633
+ if (!Node58.isIdentifier(argument) && !Node58.isPropertyAccessExpression(argument)) {
13509
13634
  continue;
13510
13635
  }
13511
13636
  if (subjectNodeFor(argument, subjects, match, resolution) !== void 0) {
@@ -13564,10 +13689,10 @@ function declaredFunctions(sourceFile) {
13564
13689
  found.push([name, declaration]);
13565
13690
  }
13566
13691
  }
13567
- for (const variable4 of sourceFile.getVariableDeclarations()) {
13568
- const initializer = variable4.getInitializer();
13569
- if (initializer !== void 0 && (Node57.isArrowFunction(initializer) || Node57.isFunctionExpression(initializer))) {
13570
- found.push([variable4.getName(), initializer]);
13692
+ for (const variable3 of sourceFile.getVariableDeclarations()) {
13693
+ const initializer = variable3.getInitializer();
13694
+ if (initializer !== void 0 && (Node58.isArrowFunction(initializer) || Node58.isFunctionExpression(initializer))) {
13695
+ found.push([variable3.getName(), initializer]);
13571
13696
  }
13572
13697
  }
13573
13698
  return found;
@@ -13661,7 +13786,7 @@ function recordEdge(edgesByChild, candidate) {
13661
13786
  }
13662
13787
 
13663
13788
  // src/discovery/wrapperIndex.ts
13664
- import { Node as Node58 } from "ts-morph";
13789
+ import { Node as Node59 } from "ts-morph";
13665
13790
  import { joinMountedPath as joinMountedPath3 } from "@suss/resolution";
13666
13791
  var NO_WRAPPERS = {
13667
13792
  wrappersFor: () => [],
@@ -13785,11 +13910,11 @@ function discoverWrapperRegistrations(sourceFile, pattern, match, wraps, resolut
13785
13910
  const candidates = [];
13786
13911
  const unresolved = [];
13787
13912
  sourceFile.forEachDescendant((node) => {
13788
- if (!Node58.isCallExpression(node)) {
13913
+ if (!Node59.isCallExpression(node)) {
13789
13914
  return;
13790
13915
  }
13791
13916
  const callee = node.getExpression();
13792
- if (!Node58.isPropertyAccessExpression(callee) || callee.getName() !== wraps.method) {
13917
+ if (!Node59.isPropertyAccessExpression(callee) || callee.getName() !== wraps.method) {
13793
13918
  return;
13794
13919
  }
13795
13920
  const subjectNode = subjectNodeFor(
@@ -13884,7 +14009,7 @@ function discoverConstructorOptions(sourceFile, pattern, wraps, subjects, resolu
13884
14009
  return { candidates, unresolved };
13885
14010
  }
13886
14011
  function constructorOptionOf(construction, wraps, resolution) {
13887
- if (!(Node58.isNewExpression(construction) || Node58.isCallExpression(construction))) {
14012
+ if (!(Node59.isNewExpression(construction) || Node59.isCallExpression(construction))) {
13888
14013
  return void 0;
13889
14014
  }
13890
14015
  const optionsArg = construction.getArguments()[wraps.targetPosition];
@@ -13914,6 +14039,7 @@ function candidateOf(registration, pattern, sourceFile) {
13914
14039
  reference: {
13915
14040
  file: target.getSourceFile().getFilePath(),
13916
14041
  name: named2 ? functionNameOrAnon(target) : label,
14042
+ ...named2 ? {} : { line: target.getStartLineNumber() },
13917
14043
  ...onThrow ? { onThrow: true } : {},
13918
14044
  ...scope === void 0 ? {} : { scope }
13919
14045
  }
@@ -13922,37 +14048,6 @@ function candidateOf(registration, pattern, sourceFile) {
13922
14048
  function labelFor(targetArg, wraps) {
13923
14049
  return factoryNameOf(targetArg) ?? wraps.method;
13924
14050
  }
13925
- function factoryNameOf(targetArg) {
13926
- const written = factKeyOf(targetArg);
13927
- if (!Node58.isCallExpression(written)) {
13928
- return void 0;
13929
- }
13930
- const callee = written.getExpression();
13931
- if (Node58.isIdentifier(callee)) {
13932
- return callee.getText();
13933
- }
13934
- if (Node58.isPropertyAccessExpression(callee)) {
13935
- return callee.getName();
13936
- }
13937
- return void 0;
13938
- }
13939
- function factoryStopOf(targetArg) {
13940
- const written = factKeyOf(targetArg);
13941
- if (!Node58.isCallExpression(written)) {
13942
- return null;
13943
- }
13944
- const callee = factoryNameOf(targetArg);
13945
- if (callee === void 0) {
13946
- return null;
13947
- }
13948
- const reason = classifyStop(
13949
- declarationsBehind(written.getExpression().getSymbol())
13950
- );
13951
- if (!worthRecording(reason)) {
13952
- return null;
13953
- }
13954
- return { callee, reason: "unresolvedWrapper" };
13955
- }
13956
14051
  function mountedAt(subjectId, mountPrefixes, scope) {
13957
14052
  const prefix = mountPrefixes?.prefixForId?.(subjectId) ?? "";
13958
14053
  return joinMountedPath3(prefix, scope);
@@ -13969,7 +14064,7 @@ function scopeOf(args, wraps, resolution) {
13969
14064
  }
13970
14065
 
13971
14066
  // src/discoveryContext.ts
13972
- import { Node as Node59 } from "ts-morph";
14067
+ import { Node as Node60 } from "ts-morph";
13973
14068
  function createTsDiscoveryContext(resolution) {
13974
14069
  const store = resolution ?? new ResolutionStore();
13975
14070
  return {
@@ -14004,7 +14099,7 @@ function exportedFunctions(sourceFile, resolution) {
14004
14099
  return out;
14005
14100
  }
14006
14101
  function exportedFunction(decl, resolution) {
14007
- const writtenAgain = Node59.isVariableDeclaration(decl) && isWrittenAgain(decl);
14102
+ const writtenAgain = Node60.isVariableDeclaration(decl) && isWrittenAgain(decl);
14008
14103
  if (!writtenAgain) {
14009
14104
  const declared = resolveDeclarationToFunction(decl);
14010
14105
  if (declared !== null) {
@@ -14025,7 +14120,7 @@ function valueToAskAbout(decl, writtenAgain) {
14025
14120
  if (writtenAgain) {
14026
14121
  return decl;
14027
14122
  }
14028
- const value = Node59.isVariableDeclaration(decl) ? decl.getInitializer() ?? decl : decl;
14123
+ const value = Node60.isVariableDeclaration(decl) ? decl.getInitializer() ?? decl : decl;
14029
14124
  return couldStillNameAFunction(value) ? value : null;
14030
14125
  }
14031
14126
  function resolveDeclarationToFunction(decl) {
@@ -14033,18 +14128,18 @@ function resolveDeclarationToFunction(decl) {
14033
14128
  if (fn !== null) {
14034
14129
  return fn;
14035
14130
  }
14036
- if (Node59.isVariableDeclaration(decl)) {
14131
+ if (Node60.isVariableDeclaration(decl)) {
14037
14132
  const init = decl.getInitializer();
14038
- if (init !== void 0 && (Node59.isArrowFunction(init) || Node59.isFunctionExpression(init))) {
14133
+ if (init !== void 0 && (Node60.isArrowFunction(init) || Node60.isFunctionExpression(init))) {
14039
14134
  return init;
14040
14135
  }
14041
14136
  }
14042
14137
  return null;
14043
14138
  }
14044
14139
  function hasJsxReturn(func) {
14045
- if (Node59.isArrowFunction(func)) {
14140
+ if (Node60.isArrowFunction(func)) {
14046
14141
  const body2 = func.getBody();
14047
- if (Node59.isExpression(body2) && isJsxOrFragment(body2)) {
14142
+ if (Node60.isExpression(body2) && isJsxOrFragment(body2)) {
14048
14143
  return true;
14049
14144
  }
14050
14145
  }
@@ -14058,11 +14153,11 @@ function hasJsxReturn(func) {
14058
14153
  traversal.stop();
14059
14154
  return;
14060
14155
  }
14061
- if (node !== func && (Node59.isFunctionDeclaration(node) || Node59.isFunctionExpression(node) || Node59.isArrowFunction(node) || Node59.isMethodDeclaration(node))) {
14156
+ if (node !== func && (Node60.isFunctionDeclaration(node) || Node60.isFunctionExpression(node) || Node60.isArrowFunction(node) || Node60.isMethodDeclaration(node))) {
14062
14157
  traversal.skip();
14063
14158
  return;
14064
14159
  }
14065
- if (Node59.isReturnStatement(node)) {
14160
+ if (Node60.isReturnStatement(node)) {
14066
14161
  const expr = node.getExpression();
14067
14162
  if (expr !== void 0 && isJsxOrFragment(expr)) {
14068
14163
  found = true;
@@ -14073,7 +14168,7 @@ function hasJsxReturn(func) {
14073
14168
  }
14074
14169
  function isJsxOrFragment(node) {
14075
14170
  const current2 = peelParens(node);
14076
- return Node59.isJsxElement(current2) || Node59.isJsxSelfClosingElement(current2) || Node59.isJsxFragment(current2);
14171
+ return Node60.isJsxElement(current2) || Node60.isJsxSelfClosingElement(current2) || Node60.isJsxFragment(current2);
14077
14172
  }
14078
14173
 
14079
14174
  // src/graphqlContract.ts
@@ -14199,132 +14294,10 @@ function createReferenceIndex(sourceFiles) {
14199
14294
  };
14200
14295
  }
14201
14296
 
14202
- // src/resolve/boundaryEffects.ts
14203
- import { evaluate as evaluate3, lit as lit3, rule as rule3, variable } from "@suss/datalog";
14204
- var EFFECT_RULES = [
14205
- rule3(
14206
- "reachFrom",
14207
- [variable("e"), variable("e")],
14208
- [lit3("entry", variable("e"))]
14209
- ),
14210
- rule3(
14211
- "reachFrom",
14212
- [variable("e"), variable("v")],
14213
- [
14214
- lit3("reachFrom", variable("e"), variable("u")),
14215
- lit3("calls", variable("u"), variable("v"))
14216
- ]
14217
- ),
14218
- rule3(
14219
- "boundaryEffect",
14220
- [variable("e"), variable("kind"), variable("target")],
14221
- [
14222
- lit3("reachFrom", variable("e"), variable("u")),
14223
- lit3("unitEffect", variable("u"), variable("kind"), variable("target"))
14224
- ]
14225
- )
14226
- ];
14227
- function bindingLabel(binding) {
14228
- const semantics = binding.semantics;
14229
- if (semantics.name === "rest") {
14230
- return `${semantics.method} ${semantics.path}`;
14231
- }
14232
- if (semantics.name === "storage") {
14233
- return `${semantics.storageSystem}:${semantics.container}`;
14234
- }
14235
- if (semantics.name === "message-bus") {
14236
- return `${semantics.messageBus}:${semantics.channel}`;
14237
- }
14238
- if (semantics.name === "runtime-config") {
14239
- return semantics.instanceName;
14240
- }
14241
- if (semantics.name === "graphql-resolver") {
14242
- return `${semantics.typeName}.${semantics.fieldName}`;
14243
- }
14244
- if (semantics.name === "graphql-operation") {
14245
- return `${semantics.operationType} ${semantics.operationName ?? ""}`.trim();
14246
- }
14247
- if ("exportName" in semantics || "module" in semantics) {
14248
- return semantics.exportName ?? semantics.module ?? binding.recognition;
14249
- }
14250
- if ("instanceName" in semantics && semantics.instanceName !== null) {
14251
- return `${semantics.deploymentTarget}:${semantics.instanceName}`;
14252
- }
14253
- return binding.recognition;
14254
- }
14255
- function effectFact(effect) {
14256
- if (effect.type === "invocation") {
14257
- return { kind: "invocation", target: effect.callee };
14258
- }
14259
- if (effect.type === "mutation") {
14260
- return { kind: "mutation", target: `${effect.operation}:${effect.target}` };
14261
- }
14262
- if (effect.type === "emission") {
14263
- return { kind: "emission", target: effect.event };
14264
- }
14265
- if (effect.type === "stateChange") {
14266
- return { kind: "stateChange", target: effect.variable };
14267
- }
14268
- if (effect.type === "interaction") {
14269
- return { kind: "interaction", target: bindingLabel(effect.binding) };
14270
- }
14271
- return null;
14272
- }
14273
- function deriveBoundaryEffects(summaries, facts) {
14274
- const { db, unitKeyBySummary } = facts;
14275
- for (const summary of summaries) {
14276
- const key = unitKeyBySummary.get(summary);
14277
- if (key === void 0) {
14278
- continue;
14279
- }
14280
- for (const transition of summary.transitions) {
14281
- for (const effect of transition.effects) {
14282
- const fact2 = effectFact(effect);
14283
- if (fact2 !== null) {
14284
- db.add("unitEffect", [key, fact2.kind, fact2.target]);
14285
- }
14286
- }
14287
- }
14288
- }
14289
- evaluate3(db, EFFECT_RULES);
14290
- const ownByEntry = /* @__PURE__ */ new Map();
14291
- for (const [unit, kind, target] of db.facts("unitEffect")) {
14292
- const bucket = ownByEntry.get(String(unit)) ?? /* @__PURE__ */ new Set();
14293
- bucket.add(`${kind}\0${target}`);
14294
- ownByEntry.set(String(unit), bucket);
14295
- }
14296
- const closureByEntry = /* @__PURE__ */ new Map();
14297
- for (const [entry, kind, target] of db.facts("boundaryEffect")) {
14298
- const entryKey2 = String(entry);
14299
- const bucket = closureByEntry.get(entryKey2) ?? [];
14300
- bucket.push({
14301
- kind: String(kind),
14302
- target: String(target),
14303
- transitive: !(ownByEntry.get(entryKey2)?.has(`${kind}\0${target}`) ?? false)
14304
- });
14305
- closureByEntry.set(entryKey2, bucket);
14306
- }
14307
- for (const summary of summaries) {
14308
- const key = unitKeyBySummary.get(summary);
14309
- if (key === void 0 || !db.has("entry", [key])) {
14310
- continue;
14311
- }
14312
- const effects = closureByEntry.get(key);
14313
- if (effects === void 0 || effects.length === 0) {
14314
- continue;
14315
- }
14316
- const sorted = [...effects].sort(
14317
- (a, b) => `${a.kind}:${a.target}`.localeCompare(`${b.kind}:${b.target}`)
14318
- );
14319
- summary.metadata = { ...summary.metadata, effectsClosure: sorted };
14320
- }
14321
- return summaries;
14322
- }
14323
-
14324
14297
  // src/resolve/reachableClosure.ts
14325
- import { Node as Node60 } from "ts-morph";
14298
+ import { Node as Node61 } from "ts-morph";
14326
14299
  import { functionCallBinding, TargetPlacements } from "@suss/behavioral-ir";
14327
- import { Database as Database3, evaluate as evaluate4, lit as lit4, rule as rule4, variable as variable2 } from "@suss/datalog";
14300
+ import { Database as Database3, evaluate as evaluate3, lit as lit3, rule as rule3, variable } from "@suss/datalog";
14328
14301
  import { assembleSummary as assembleSummary2 } from "@suss/extractor";
14329
14302
  var GENERIC_TERMINALS = [
14330
14303
  { kind: "return", match: { type: "returnStatement" }, extraction: {} },
@@ -14355,7 +14328,7 @@ function targetOf(node) {
14355
14328
  };
14356
14329
  }
14357
14330
  function resolveCallee(call, calleeName, scan) {
14358
- if (!Node60.isCallExpression(call)) {
14331
+ if (!Node61.isCallExpression(call)) {
14359
14332
  return null;
14360
14333
  }
14361
14334
  const callee = call.getExpression();
@@ -14368,7 +14341,7 @@ function resolveCallee(call, calleeName, scan) {
14368
14341
  }
14369
14342
  }
14370
14343
  const resolveSources = scan.resolveCallableSources;
14371
- if (resolveSources !== void 0 && Node60.isPropertyAccessExpression(callee) && declarations.some(isDeclaredShape)) {
14344
+ if (resolveSources !== void 0 && Node61.isPropertyAccessExpression(callee) && declarations.some(isDeclaredShape)) {
14372
14345
  const sources = resolveSources(callee, scan.reachedFrom);
14373
14346
  const only = sources.length === 1 ? sources[0] : void 0;
14374
14347
  const resolved = only === void 0 ? null : resolveDecl(only, calleeName);
@@ -14414,11 +14387,11 @@ function passedPositionKey(target, position) {
14414
14387
  return `${offsetKeyFor(target.file, target.span)}#${position}`;
14415
14388
  }
14416
14389
  function resolveJsxReference(node, scan) {
14417
- if (!Node60.isJsxOpeningElement(node) && !Node60.isJsxSelfClosingElement(node)) {
14390
+ if (!Node61.isJsxOpeningElement(node) && !Node61.isJsxSelfClosingElement(node)) {
14418
14391
  return null;
14419
14392
  }
14420
14393
  const tag = node.getTagNameNode();
14421
- if (!Node60.isIdentifier(tag) || !/^[A-Z]/.test(tag.getText())) {
14394
+ if (!Node61.isIdentifier(tag) || !/^[A-Z]/.test(tag.getText())) {
14422
14395
  return null;
14423
14396
  }
14424
14397
  const name = tag.getText();
@@ -14464,12 +14437,12 @@ function collectReachable(func, scan) {
14464
14437
  candidates.push(outcome.candidate);
14465
14438
  };
14466
14439
  const recordPassedArgs = (call, calleeText, calleeOutcome) => {
14467
- if (!Node60.isCallExpression(call)) {
14440
+ if (!Node61.isCallExpression(call)) {
14468
14441
  return;
14469
14442
  }
14470
14443
  const calleeTarget = declaredAtOf(calleeOutcome);
14471
14444
  call.getArguments().forEach((arg, position) => {
14472
- if (!Node60.isIdentifier(arg)) {
14445
+ if (!Node61.isIdentifier(arg)) {
14473
14446
  return;
14474
14447
  }
14475
14448
  const resolved = functionTargetOf(arg);
@@ -14489,7 +14462,7 @@ function collectReachable(func, scan) {
14489
14462
  record2(jsx.outcome);
14490
14463
  return;
14491
14464
  }
14492
- if (!Node60.isCallExpression(node)) {
14465
+ if (!Node61.isCallExpression(node)) {
14493
14466
  return;
14494
14467
  }
14495
14468
  const calleeText = normalizeCallee(node.getExpression().getText());
@@ -14541,13 +14514,13 @@ function extractReachableSummary(candidate, options, recognizers) {
14541
14514
  return assembleSummary2(raw, options);
14542
14515
  }
14543
14516
  var REACHABLE_RULES = [
14544
- rule4("reachable", [variable2("f")], [lit4("entry", variable2("f"))]),
14545
- rule4(
14517
+ rule3("reachable", [variable("f")], [lit3("entry", variable("f"))]),
14518
+ rule3(
14546
14519
  "reachable",
14547
- [variable2("g")],
14520
+ [variable("g")],
14548
14521
  [
14549
- lit4("reachable", variable2("f")),
14550
- lit4("calls", variable2("f"), variable2("g"))
14522
+ lit3("reachable", variable("f")),
14523
+ lit3("calls", variable("f"), variable("g"))
14551
14524
  ]
14552
14525
  )
14553
14526
  ];
@@ -14575,7 +14548,7 @@ function recognizerOnlyRoots(packsByFile) {
14575
14548
  }
14576
14549
  for (const declaration of variableStatement.getDeclarations()) {
14577
14550
  const init = declaration.getInitializer();
14578
- if (init !== void 0 && (Node60.isArrowFunction(init) || Node60.isFunctionExpression(init)) && hasBody(init)) {
14551
+ if (init !== void 0 && (Node61.isArrowFunction(init) || Node61.isFunctionExpression(init)) && hasBody(init)) {
14579
14552
  roots.push({ func: init, name: declaration.getName() });
14580
14553
  }
14581
14554
  }
@@ -14624,7 +14597,7 @@ function expandReachableClosure(seeds, project, options, projectFileSet, facts,
14624
14597
  }
14625
14598
  }
14626
14599
  for (; ; ) {
14627
- evaluate4(db, REACHABLE_RULES);
14600
+ evaluate3(db, REACHABLE_RULES);
14628
14601
  const frontier = db.facts("reachable").map(([key]) => String(key)).filter((key) => !scanned.has(key));
14629
14602
  if (frontier.length === 0) {
14630
14603
  break;
@@ -14829,21 +14802,21 @@ function recordParameterGaps(parameterCallsByKey, summariesByKey, passedPosition
14829
14802
  }
14830
14803
 
14831
14804
  // src/resolve/rethrowEnrichment.ts
14832
- import { Node as Node61 } from "ts-morph";
14833
- import { Database as Database4, evaluate as evaluate5, lit as lit5, rule as rule5, variable as variable3 } from "@suss/datalog";
14805
+ import { Node as Node62 } from "ts-morph";
14806
+ import { Database as Database4, evaluate as evaluate4, lit as lit4, rule as rule4, variable as variable2 } from "@suss/datalog";
14834
14807
  var RETHROW_RULES = [
14835
- rule5(
14808
+ rule4(
14836
14809
  "contributes",
14837
- [variable3("u"), variable3("s")],
14838
- [lit5("throwsDirect", variable3("u"), variable3("s"))]
14810
+ [variable2("u"), variable2("s")],
14811
+ [lit4("throwsDirect", variable2("u"), variable2("s"))]
14839
14812
  ),
14840
- rule5(
14813
+ rule4(
14841
14814
  "contributes",
14842
- [variable3("u"), variable3("s")],
14815
+ [variable2("u"), variable2("s")],
14843
14816
  [
14844
- lit5("rethrowSite", variable3("u"), variable3("site")),
14845
- lit5("siteCalls", variable3("site"), variable3("c")),
14846
- lit5("contributes", variable3("c"), variable3("s"))
14817
+ lit4("rethrowSite", variable2("u"), variable2("site")),
14818
+ lit4("siteCalls", variable2("site"), variable2("c")),
14819
+ lit4("contributes", variable2("c"), variable2("s"))
14847
14820
  ]
14848
14821
  )
14849
14822
  ];
@@ -14905,7 +14878,7 @@ function enrichRethrows(summaries, project, facts) {
14905
14878
  }
14906
14879
  }
14907
14880
  }
14908
- evaluate5(db, RETHROW_RULES);
14881
+ evaluate4(db, RETHROW_RULES);
14909
14882
  const contributesByUnit = /* @__PURE__ */ new Map();
14910
14883
  for (const [unit, sourceId] of db.facts("contributes")) {
14911
14884
  const bucket = contributesByUnit.get(String(unit));
@@ -14966,7 +14939,7 @@ function findBareRethrow(func, location) {
14966
14939
  traversal.stop();
14967
14940
  return;
14968
14941
  }
14969
- if (!Node61.isThrowStatement(node)) {
14942
+ if (!Node62.isThrowStatement(node)) {
14970
14943
  return;
14971
14944
  }
14972
14945
  if (startLineOf(node) !== location.start) {
@@ -14976,7 +14949,7 @@ function findBareRethrow(func, location) {
14976
14949
  return;
14977
14950
  }
14978
14951
  const thrown = node.getExpression();
14979
- if (thrown !== void 0 && Node61.isIdentifier(thrown)) {
14952
+ if (thrown !== void 0 && Node62.isIdentifier(thrown)) {
14980
14953
  found = node;
14981
14954
  }
14982
14955
  });
@@ -14986,13 +14959,13 @@ function enclosingTry(throwStmt) {
14986
14959
  let current2 = throwStmt.getParent();
14987
14960
  let sawCatchClause = false;
14988
14961
  while (current2 !== void 0) {
14989
- if (Node61.isCatchClause(current2)) {
14962
+ if (Node62.isCatchClause(current2)) {
14990
14963
  sawCatchClause = true;
14991
14964
  }
14992
- if (Node61.isTryStatement(current2)) {
14965
+ if (Node62.isTryStatement(current2)) {
14993
14966
  return sawCatchClause ? current2 : null;
14994
14967
  }
14995
- if (Node61.isFunctionDeclaration(current2) || Node61.isFunctionExpression(current2) || Node61.isArrowFunction(current2) || Node61.isMethodDeclaration(current2)) {
14968
+ if (Node62.isFunctionDeclaration(current2) || Node62.isFunctionExpression(current2) || Node62.isArrowFunction(current2) || Node62.isMethodDeclaration(current2)) {
14996
14969
  return null;
14997
14970
  }
14998
14971
  current2 = current2.getParent();
@@ -15000,14 +14973,14 @@ function enclosingTry(throwStmt) {
15000
14973
  return null;
15001
14974
  }
15002
14975
  function collectTryBodyCallees(tryStmt, index, keyFor) {
15003
- if (!Node61.isTryStatement(tryStmt)) {
14976
+ if (!Node62.isTryStatement(tryStmt)) {
15004
14977
  return [];
15005
14978
  }
15006
14979
  const tryBlock = tryStmt.getTryBlock();
15007
14980
  const callees = [];
15008
14981
  const seen = /* @__PURE__ */ new Set();
15009
14982
  tryBlock.forEachDescendant((node) => {
15010
- if (!Node61.isCallExpression(node)) {
14983
+ if (!Node62.isCallExpression(node)) {
15011
14984
  return;
15012
14985
  }
15013
14986
  const calleeSummary = resolveCalleeSummary(node, index);
@@ -15024,7 +14997,7 @@ function collectTryBodyCallees(tryStmt, index, keyFor) {
15024
14997
  return callees;
15025
14998
  }
15026
14999
  function resolveCalleeSummary(call, index) {
15027
- if (!Node61.isCallExpression(call)) {
15000
+ if (!Node62.isCallExpression(call)) {
15028
15001
  return null;
15029
15002
  }
15030
15003
  const callee = call.getExpression();
@@ -15054,12 +15027,12 @@ function resolveCalleeSummary(call, index) {
15054
15027
  return null;
15055
15028
  }
15056
15029
  function functionFromDecl(decl) {
15057
- if (Node61.isFunctionDeclaration(decl) || Node61.isFunctionExpression(decl) || Node61.isArrowFunction(decl) || Node61.isMethodDeclaration(decl)) {
15030
+ if (Node62.isFunctionDeclaration(decl) || Node62.isFunctionExpression(decl) || Node62.isArrowFunction(decl) || Node62.isMethodDeclaration(decl)) {
15058
15031
  return decl;
15059
15032
  }
15060
- if (Node61.isVariableDeclaration(decl)) {
15033
+ if (Node62.isVariableDeclaration(decl)) {
15061
15034
  const init = decl.getInitializer();
15062
- if (init !== void 0 && (Node61.isArrowFunction(init) || Node61.isFunctionExpression(init))) {
15035
+ if (init !== void 0 && (Node62.isArrowFunction(init) || Node62.isFunctionExpression(init))) {
15063
15036
  return init;
15064
15037
  }
15065
15038
  }
@@ -15068,23 +15041,23 @@ function functionFromDecl(decl) {
15068
15041
 
15069
15042
  // src/shapes/fieldAccesses.ts
15070
15043
  import {
15071
- Node as Node62
15044
+ Node as Node63
15072
15045
  } from "ts-morph";
15073
15046
  function findResponseAccessor(callExpr) {
15074
15047
  let current2 = callExpr;
15075
15048
  const parent1 = current2.getParent();
15076
- if (parent1 !== void 0 && Node62.isAwaitExpression(parent1)) {
15049
+ if (parent1 !== void 0 && Node63.isAwaitExpression(parent1)) {
15077
15050
  current2 = parent1;
15078
15051
  }
15079
15052
  const parent2 = current2.getParent();
15080
- if (parent2 === void 0 || !Node62.isVariableDeclaration(parent2)) {
15053
+ if (parent2 === void 0 || !Node63.isVariableDeclaration(parent2)) {
15081
15054
  return null;
15082
15055
  }
15083
15056
  const nameNode = parent2.getNameNode();
15084
- if (Node62.isIdentifier(nameNode)) {
15057
+ if (Node63.isIdentifier(nameNode)) {
15085
15058
  return { kind: "identifier", name: nameNode.getText() };
15086
15059
  }
15087
- if (Node62.isObjectBindingPattern(nameNode)) {
15060
+ if (Node63.isObjectBindingPattern(nameNode)) {
15088
15061
  const bindings = /* @__PURE__ */ new Map();
15089
15062
  for (const element of nameNode.getElements()) {
15090
15063
  if (element.getDotDotDotToken() !== void 0) {
@@ -15105,11 +15078,11 @@ function findResponseAccessor(callExpr) {
15105
15078
  function buildThenChainAccessor(callExpr, func) {
15106
15079
  const bindings = /* @__PURE__ */ new Map();
15107
15080
  func.forEachDescendant((node) => {
15108
- if (!Node62.isParameterDeclaration(node)) {
15081
+ if (!Node63.isParameterDeclaration(node)) {
15109
15082
  return;
15110
15083
  }
15111
15084
  const nameNode = node.getNameNode();
15112
- if (!Node62.isIdentifier(nameNode)) {
15085
+ if (!Node63.isIdentifier(nameNode)) {
15113
15086
  return;
15114
15087
  }
15115
15088
  const prefix = prefixOfThenParam(node, callExpr, 0);
@@ -15141,7 +15114,7 @@ function prefixOfExpr(expr, responseCall, depth) {
15141
15114
  if (node === responseCall) {
15142
15115
  return [];
15143
15116
  }
15144
- if (Node62.isCallExpression(node)) {
15117
+ if (Node63.isCallExpression(node)) {
15145
15118
  const hop = thenLikeCall(node);
15146
15119
  if (hop !== null) {
15147
15120
  if (hop.method === "catch") {
@@ -15173,14 +15146,14 @@ function prefixOfMemberExpr(expr, responseCall, depth) {
15173
15146
  return null;
15174
15147
  }
15175
15148
  const decl = chain.root.getSymbol()?.getDeclarations()?.[0];
15176
- if (decl === void 0 || !Node62.isParameterDeclaration(decl)) {
15149
+ if (decl === void 0 || !Node63.isParameterDeclaration(decl)) {
15177
15150
  return null;
15178
15151
  }
15179
15152
  const base = prefixOfThenParam(decl, responseCall, depth + 1);
15180
15153
  return base === null ? null : [...base, ...chain.segments];
15181
15154
  }
15182
15155
  function firstCallbackParamName(callback) {
15183
- if (callback === void 0 || !(Node62.isArrowFunction(callback) || Node62.isFunctionExpression(callback))) {
15156
+ if (callback === void 0 || !(Node63.isArrowFunction(callback) || Node63.isFunctionExpression(callback))) {
15184
15157
  return null;
15185
15158
  }
15186
15159
  const param = callback.getParameters()[0];
@@ -15188,11 +15161,11 @@ function firstCallbackParamName(callback) {
15188
15161
  return null;
15189
15162
  }
15190
15163
  const nameNode = param.getNameNode();
15191
- return Node62.isIdentifier(nameNode) ? nameNode.getText() : null;
15164
+ return Node63.isIdentifier(nameNode) ? nameNode.getText() : null;
15192
15165
  }
15193
15166
  function unwrap(expr) {
15194
15167
  let node = expr;
15195
- while (Node62.isAwaitExpression(node) || Node62.isParenthesizedExpression(node) || Node62.isAsExpression(node)) {
15168
+ while (Node63.isAwaitExpression(node) || Node63.isParenthesizedExpression(node) || Node63.isAsExpression(node)) {
15196
15169
  node = node.getExpression();
15197
15170
  }
15198
15171
  return node;
@@ -15202,15 +15175,15 @@ function chainRootedAt(expr, rootName) {
15202
15175
  if (chain === null) {
15203
15176
  return null;
15204
15177
  }
15205
- return Node62.isIdentifier(chain.root) && chain.root.getText() === rootName ? chain.segments : null;
15178
+ return Node63.isIdentifier(chain.root) && chain.root.getText() === rootName ? chain.segments : null;
15206
15179
  }
15207
15180
  function memberChain(expr) {
15208
- let node = Node62.isExpression(expr) ? unwrap(expr) : expr;
15209
- if (Node62.isCallExpression(node)) {
15181
+ let node = Node63.isExpression(expr) ? unwrap(expr) : expr;
15182
+ if (Node63.isCallExpression(node)) {
15210
15183
  node = node.getExpression();
15211
15184
  }
15212
15185
  const segments = [];
15213
- while (Node62.isPropertyAccessExpression(node)) {
15186
+ while (Node63.isPropertyAccessExpression(node)) {
15214
15187
  segments.unshift(node.getName());
15215
15188
  node = node.getExpression();
15216
15189
  }
@@ -15229,16 +15202,16 @@ function collectPropertyAccesses(subtree, accessor) {
15229
15202
  if (accessor.kind === "identifier") {
15230
15203
  const varName = accessor.name;
15231
15204
  subtree.forEachDescendant((node) => {
15232
- if (!Node62.isPropertyAccessExpression(node)) {
15205
+ if (!Node63.isPropertyAccessExpression(node)) {
15233
15206
  return;
15234
15207
  }
15235
15208
  const chain = [];
15236
15209
  let current2 = node;
15237
- while (Node62.isPropertyAccessExpression(current2)) {
15210
+ while (Node63.isPropertyAccessExpression(current2)) {
15238
15211
  chain.unshift(current2.getName());
15239
15212
  current2 = current2.getExpression();
15240
15213
  }
15241
- if (Node62.isIdentifier(current2) && current2.getText() === varName) {
15214
+ if (Node63.isIdentifier(current2) && current2.getText() === varName) {
15242
15215
  pushChain(chain);
15243
15216
  }
15244
15217
  });
@@ -15249,7 +15222,7 @@ function collectPropertyAccesses(subtree, accessor) {
15249
15222
  return source === void 0 ? void 0 : [source];
15250
15223
  } : (name) => accessor.bindings.get(name);
15251
15224
  subtree.forEachDescendant((node) => {
15252
- if (!Node62.isIdentifier(node)) {
15225
+ if (!Node63.isIdentifier(node)) {
15253
15226
  return;
15254
15227
  }
15255
15228
  const prefix = prefixOf(node.getText());
@@ -15261,13 +15234,13 @@ function collectPropertyAccesses(subtree, accessor) {
15261
15234
  }
15262
15235
  let chainTop = node;
15263
15236
  let parent = chainTop.getParent();
15264
- while (parent !== void 0 && Node62.isPropertyAccessExpression(parent) && parent.getExpression() === chainTop) {
15237
+ while (parent !== void 0 && Node63.isPropertyAccessExpression(parent) && parent.getExpression() === chainTop) {
15265
15238
  chainTop = parent;
15266
15239
  parent = chainTop.getParent();
15267
15240
  }
15268
15241
  const segments = [];
15269
15242
  let current2 = chainTop;
15270
- while (Node62.isPropertyAccessExpression(current2)) {
15243
+ while (Node63.isPropertyAccessExpression(current2)) {
15271
15244
  segments.push(current2.getName());
15272
15245
  current2 = current2.getExpression();
15273
15246
  }
@@ -15281,15 +15254,15 @@ function isBindingDeclarationSite(node) {
15281
15254
  return true;
15282
15255
  }
15283
15256
  const parent = node.getParent();
15284
- return parent !== void 0 && Node62.isParameterDeclaration(parent) && parent.getNameNode() === node;
15257
+ return parent !== void 0 && Node63.isParameterDeclaration(parent) && parent.getNameNode() === node;
15285
15258
  }
15286
15259
  function isInsideObjectBindingPattern(node) {
15287
15260
  let current2 = node.getParent();
15288
15261
  while (current2 !== void 0) {
15289
- if (Node62.isObjectBindingPattern(current2)) {
15262
+ if (Node63.isObjectBindingPattern(current2)) {
15290
15263
  return true;
15291
15264
  }
15292
- if (Node62.isFunctionLikeDeclaration(current2) || Node62.isVariableStatement(current2)) {
15265
+ if (Node63.isFunctionLikeDeclaration(current2) || Node63.isVariableStatement(current2)) {
15293
15266
  break;
15294
15267
  }
15295
15268
  current2 = current2.getParent();
@@ -15352,7 +15325,7 @@ function findBranchSubtree(func, byLineRange, terminalStartLine, terminalEndLine
15352
15325
  if (parent === void 0) {
15353
15326
  break;
15354
15327
  }
15355
- if (Node62.isIfStatement(parent)) {
15328
+ if (Node63.isIfStatement(parent)) {
15356
15329
  const ifStmt = parent;
15357
15330
  const thenBlock = ifStmt.getThenStatement();
15358
15331
  const elseBlock = ifStmt.getElseStatement();
@@ -15415,7 +15388,7 @@ function buildNonBodyPropertySet(semantics) {
15415
15388
 
15416
15389
  // src/subUnitContext.ts
15417
15390
  import {
15418
- Node as Node63
15391
+ Node as Node64
15419
15392
  } from "ts-morph";
15420
15393
  function createTsSubUnitContext() {
15421
15394
  return {
@@ -15443,18 +15416,18 @@ function findJsxAttributes(parent) {
15443
15416
  if (skip(node, traversal)) {
15444
15417
  return;
15445
15418
  }
15446
- if (!Node63.isJsxOpeningElement(node) && !Node63.isJsxSelfClosingElement(node)) {
15419
+ if (!Node64.isJsxOpeningElement(node) && !Node64.isJsxSelfClosingElement(node)) {
15447
15420
  return;
15448
15421
  }
15449
15422
  const tag = node.getTagNameNode().getText();
15450
15423
  for (const attr of node.getAttributes()) {
15451
- if (!Node63.isJsxAttribute(attr)) {
15424
+ if (!Node64.isJsxAttribute(attr)) {
15452
15425
  continue;
15453
15426
  }
15454
15427
  const initializer = attr.getInitializer();
15455
15428
  let valueExpression = null;
15456
15429
  if (initializer !== void 0) {
15457
- if (Node63.isJsxExpression(initializer)) {
15430
+ if (Node64.isJsxExpression(initializer)) {
15458
15431
  const inner = initializer.getExpression();
15459
15432
  valueExpression = inner ?? null;
15460
15433
  } else {
@@ -15477,11 +15450,11 @@ function findCallExpressionsByName(parent, name) {
15477
15450
  if (skip(node, traversal)) {
15478
15451
  return;
15479
15452
  }
15480
- if (!Node63.isCallExpression(node)) {
15453
+ if (!Node64.isCallExpression(node)) {
15481
15454
  return;
15482
15455
  }
15483
15456
  const callee = node.getExpression();
15484
- if (Node63.isIdentifier(callee) && callee.getText() === name) {
15457
+ if (Node64.isIdentifier(callee) && callee.getText() === name) {
15485
15458
  out.push(node);
15486
15459
  }
15487
15460
  });
@@ -15492,10 +15465,10 @@ function resolveAttributeValueFunction(attr, parent) {
15492
15465
  if (expr === null) {
15493
15466
  return null;
15494
15467
  }
15495
- if (Node63.isArrowFunction(expr) || Node63.isFunctionExpression(expr)) {
15468
+ if (Node64.isArrowFunction(expr) || Node64.isFunctionExpression(expr)) {
15496
15469
  return { func: expr, localName: null };
15497
15470
  }
15498
- if (Node63.isIdentifier(expr)) {
15471
+ if (Node64.isIdentifier(expr)) {
15499
15472
  const symbol = expr.getSymbol();
15500
15473
  if (symbol === void 0) {
15501
15474
  return null;
@@ -15514,15 +15487,15 @@ function resolveAttributeValueFunction(attr, parent) {
15514
15487
  return null;
15515
15488
  }
15516
15489
  function tryExtractFunction(decl) {
15517
- if (Node63.isFunctionDeclaration(decl)) {
15490
+ if (Node64.isFunctionDeclaration(decl)) {
15518
15491
  return decl;
15519
15492
  }
15520
- if (Node63.isVariableDeclaration(decl)) {
15493
+ if (Node64.isVariableDeclaration(decl)) {
15521
15494
  const init = decl.getInitializer();
15522
15495
  if (init === void 0) {
15523
15496
  return null;
15524
15497
  }
15525
- if (Node63.isArrowFunction(init) || Node63.isFunctionExpression(init)) {
15498
+ if (Node64.isArrowFunction(init) || Node64.isFunctionExpression(init)) {
15526
15499
  return init;
15527
15500
  }
15528
15501
  }
@@ -15543,7 +15516,7 @@ function getCallArgumentFunction(call, position) {
15543
15516
  if (arg === void 0) {
15544
15517
  return null;
15545
15518
  }
15546
- if (Node63.isArrowFunction(arg) || Node63.isFunctionExpression(arg)) {
15519
+ if (Node64.isArrowFunction(arg) || Node64.isFunctionExpression(arg)) {
15547
15520
  return arg;
15548
15521
  }
15549
15522
  return null;
@@ -15555,7 +15528,7 @@ function readArrayLiteralText(node) {
15555
15528
  if (node === null) {
15556
15529
  return null;
15557
15530
  }
15558
- if (Node63.isArrayLiteralExpression(node)) {
15531
+ if (Node64.isArrayLiteralExpression(node)) {
15559
15532
  return node.getElements().map((e) => e.getText());
15560
15533
  }
15561
15534
  return [node.getText()];
@@ -15811,13 +15784,13 @@ var raise = (msg) => {
15811
15784
  throw new Error(msg);
15812
15785
  };
15813
15786
  function bindingPatternNames(nameNode) {
15814
- if (Node64.isObjectBindingPattern(nameNode)) {
15787
+ if (Node65.isObjectBindingPattern(nameNode)) {
15815
15788
  return nameNode.getElements().map((e) => e.getName());
15816
15789
  }
15817
- if (Node64.isArrayBindingPattern(nameNode)) {
15790
+ if (Node65.isArrayBindingPattern(nameNode)) {
15818
15791
  const names = [];
15819
15792
  for (const element of nameNode.getElements()) {
15820
- if (Node64.isOmittedExpression(element)) {
15793
+ if (Node65.isOmittedExpression(element)) {
15821
15794
  continue;
15822
15795
  }
15823
15796
  names.push(element.getName());
@@ -15847,7 +15820,7 @@ function objectParamInputs(param, position, mapping) {
15847
15820
  }
15848
15821
  function componentPropsParameters(param, mapping) {
15849
15822
  const nameNode = param.getNameNode();
15850
- if (!Node64.isObjectBindingPattern(nameNode)) {
15823
+ if (!Node65.isObjectBindingPattern(nameNode)) {
15851
15824
  const type = param.getType();
15852
15825
  return [
15853
15826
  {
@@ -15877,7 +15850,7 @@ function bindingRole(element, name) {
15877
15850
  if (property === void 0) {
15878
15851
  return name;
15879
15852
  }
15880
- if (Node64.isStringLiteral(property)) {
15853
+ if (Node65.isStringLiteral(property)) {
15881
15854
  return property.getLiteralValue();
15882
15855
  }
15883
15856
  return property.getText();
@@ -15909,7 +15882,7 @@ function extractParameters(func, inputMapping) {
15909
15882
  const param = params[i];
15910
15883
  const nameNode = param.getNameNode();
15911
15884
  const boundNames = bindingPatternNames(nameNode);
15912
- if (Node64.isObjectBindingPattern(nameNode)) {
15885
+ if (Node65.isObjectBindingPattern(nameNode)) {
15913
15886
  for (const element of nameNode.getElements()) {
15914
15887
  result.push({
15915
15888
  name: element.getName(),
@@ -15976,7 +15949,7 @@ function extractDependencyCalls(func, barriers = NO_BARRIERS) {
15976
15949
  traversal.skip();
15977
15950
  return;
15978
15951
  }
15979
- if (!Node64.isVariableDeclaration(node)) {
15952
+ if (!Node65.isVariableDeclaration(node)) {
15980
15953
  return;
15981
15954
  }
15982
15955
  const init = node.getInitializer();
@@ -15985,19 +15958,19 @@ function extractDependencyCalls(func, barriers = NO_BARRIERS) {
15985
15958
  }
15986
15959
  let isAsync = false;
15987
15960
  let callExpr = init;
15988
- if (Node64.isAwaitExpression(init)) {
15961
+ if (Node65.isAwaitExpression(init)) {
15989
15962
  isAsync = true;
15990
15963
  callExpr = init.getExpression();
15991
15964
  }
15992
- if (!Node64.isCallExpression(callExpr)) {
15965
+ if (!Node65.isCallExpression(callExpr)) {
15993
15966
  return;
15994
15967
  }
15995
15968
  const calleeName = callExpr.getExpression().getText();
15996
15969
  const nameNode = node.getNameNode();
15997
- const assignedTo = Node64.isIdentifier(nameNode) ? nameNode.getText() : null;
15970
+ const assignedTo = Node65.isIdentifier(nameNode) ? nameNode.getText() : null;
15998
15971
  const declList = node.getParent();
15999
15972
  const varStmt = declList?.getParent();
16000
- const locationNode = varStmt !== void 0 && Node64.isVariableStatement(varStmt) ? varStmt : node;
15973
+ const locationNode = varStmt !== void 0 && Node65.isVariableStatement(varStmt) ? varStmt : node;
16001
15974
  results.push({
16002
15975
  name: calleeName,
16003
15976
  assignedTo,
@@ -16356,6 +16329,10 @@ function extractBindingPath(binding, callSite, pack, resolution) {
16356
16329
  const arg = callSite.callExpression.getArguments()[p.position];
16357
16330
  return arg === void 0 ? void 0 : pathFromArgument(arg, resolution);
16358
16331
  }
16332
+ if (p.type === "fromArgumentProperty") {
16333
+ const arg = callSite.callExpression.getArguments()[p.position];
16334
+ return arg === void 0 ? void 0 : pathFromProperty(arg, p.property, resolution);
16335
+ }
16359
16336
  return void 0;
16360
16337
  }
16361
16338
  function resolveContractField(callSite, pack, field, resolution) {
@@ -16751,20 +16728,23 @@ function extractFromSourceFile(sourceFile, frameworks, claimedUnits, options, ta
16751
16728
  return summaries;
16752
16729
  }
16753
16730
  function stampWrappers(raw, unit, wrappers) {
16754
- if (wrappers === void 0 || unit.registrationSubjectId === void 0) {
16755
- return;
16756
- }
16757
- const applied = wrappers.wrappersFor(unit.registrationSubjectId);
16731
+ const applied = [
16732
+ ...wrappers === void 0 || unit.registrationSubjectId === void 0 ? [] : wrappers.wrappersFor(unit.registrationSubjectId),
16733
+ ...unit.routeWrappers ?? []
16734
+ ];
16758
16735
  if (applied.length === 0) {
16759
16736
  return;
16760
16737
  }
16761
- raw.wrappers = [...applied];
16738
+ raw.wrappers = applied;
16762
16739
  for (const wrapper of applied) {
16763
16740
  recordFileDependency(wrapper.file);
16764
16741
  }
16765
16742
  }
16766
16743
  function unfollowedStopsOf(unit, wrappers) {
16767
- const stops = unit.unfollowed === void 0 ? [] : [unit.unfollowed];
16744
+ const stops = [
16745
+ ...unit.unfollowed === void 0 ? [] : [unit.unfollowed],
16746
+ ...unit.routeUnfollowed ?? []
16747
+ ];
16768
16748
  if (wrappers === void 0 || unit.registrationSubjectId === void 0) {
16769
16749
  return stops;
16770
16750
  }
@@ -16913,7 +16893,7 @@ function findWrapperPathParam(summary, lookup) {
16913
16893
  }
16914
16894
  for (const call of func.getDescendantsOfKind(SyntaxKind12.CallExpression)) {
16915
16895
  const first = call.getArguments()[0];
16916
- if (first === void 0 || !Node64.isIdentifier(first)) {
16896
+ if (first === void 0 || !Node65.isIdentifier(first)) {
16917
16897
  continue;
16918
16898
  }
16919
16899
  const at = names.indexOf(first.getText());
@@ -16962,16 +16942,16 @@ function synthesizeCallerSummaries(wrapper, _project, options, resolution) {
16962
16942
  return out;
16963
16943
  }
16964
16944
  function wrapperNameNode(func) {
16965
- if (Node64.isFunctionDeclaration(func) || Node64.isMethodDeclaration(func)) {
16945
+ if (Node65.isFunctionDeclaration(func) || Node65.isMethodDeclaration(func)) {
16966
16946
  const name = func.getNameNode();
16967
- if (name !== void 0 && Node64.isIdentifier(name)) {
16947
+ if (name !== void 0 && Node65.isIdentifier(name)) {
16968
16948
  return name;
16969
16949
  }
16970
16950
  }
16971
16951
  const parent = func.getParent();
16972
- if (parent !== void 0 && Node64.isVariableDeclaration(parent)) {
16952
+ if (parent !== void 0 && Node65.isVariableDeclaration(parent)) {
16973
16953
  const nameNode = parent.getNameNode();
16974
- if (Node64.isIdentifier(nameNode)) {
16954
+ if (Node65.isIdentifier(nameNode)) {
16975
16955
  return nameNode;
16976
16956
  }
16977
16957
  }
@@ -16980,10 +16960,10 @@ function wrapperNameNode(func) {
16980
16960
  function enclosingCall(node) {
16981
16961
  let current2 = node.getParent();
16982
16962
  while (current2 !== void 0) {
16983
- if (Node64.isCallExpression(current2)) {
16963
+ if (Node65.isCallExpression(current2)) {
16984
16964
  return current2;
16985
16965
  }
16986
- if (Node64.isPropertyAccessExpression(current2)) {
16966
+ if (Node65.isPropertyAccessExpression(current2)) {
16987
16967
  current2 = current2.getParent();
16988
16968
  continue;
16989
16969
  }
@@ -16994,7 +16974,7 @@ function enclosingCall(node) {
16994
16974
  function enclosingFunction(node) {
16995
16975
  let current2 = node.getParent();
16996
16976
  while (current2 !== void 0) {
16997
- if (Node64.isFunctionDeclaration(current2) || Node64.isFunctionExpression(current2) || Node64.isArrowFunction(current2) || Node64.isMethodDeclaration(current2)) {
16977
+ if (Node65.isFunctionDeclaration(current2) || Node65.isFunctionExpression(current2) || Node65.isArrowFunction(current2) || Node65.isMethodDeclaration(current2)) {
16998
16978
  return current2;
16999
16979
  }
17000
16980
  current2 = current2.getParent();
@@ -17002,13 +16982,13 @@ function enclosingFunction(node) {
17002
16982
  return null;
17003
16983
  }
17004
16984
  function callerName(func) {
17005
- if (Node64.isFunctionDeclaration(func) || Node64.isMethodDeclaration(func)) {
16985
+ if (Node65.isFunctionDeclaration(func) || Node65.isMethodDeclaration(func)) {
17006
16986
  return func.getName() ?? "anonymous";
17007
16987
  }
17008
16988
  const parent = func.getParent();
17009
- if (parent !== void 0 && Node64.isVariableDeclaration(parent)) {
16989
+ if (parent !== void 0 && Node65.isVariableDeclaration(parent)) {
17010
16990
  const nameNode = parent.getNameNode();
17011
- if (Node64.isIdentifier(nameNode)) {
16991
+ if (Node65.isIdentifier(nameNode)) {
17012
16992
  return nameNode.getText();
17013
16993
  }
17014
16994
  }
@@ -17154,7 +17134,11 @@ function createTypeScriptAdapter(suppliedConfig) {
17154
17134
  )
17155
17135
  );
17156
17136
  }
17157
- return named(summaries, config.workspace, runRoot);
17137
+ return named(
17138
+ composeWrappers(summaries, config.extractorOptions ?? {}),
17139
+ config.workspace,
17140
+ runRoot
17141
+ );
17158
17142
  },
17159
17143
  async extractAll() {
17160
17144
  const timer = createTimer();
@@ -17414,12 +17398,6 @@ function createTypeScriptAdapter(suppliedConfig) {
17414
17398
  "enrichRethrows",
17415
17399
  () => enrichRethrows(merged.summaries, project, closureFacts)
17416
17400
  );
17417
- if (config.includeReachable !== false) {
17418
- timer.time(
17419
- "deriveBoundaryEffects",
17420
- () => deriveBoundaryEffects(enriched, closureFacts)
17421
- );
17422
- }
17423
17401
  timer.time(
17424
17402
  "stampModuleImports",
17425
17403
  () => stampModuleImports(enriched, (file) => {
@@ -17903,10 +17881,18 @@ function createProjectWithoutTsconfig(rootDir) {
17903
17881
  }
17904
17882
  return { project, files };
17905
17883
  }
17884
+ var TSCONFIG_NAMES = [
17885
+ "tsconfig.json",
17886
+ "jsconfig.json",
17887
+ "tsconfig.base.json"
17888
+ ];
17889
+ var WALK_UP_TSCONFIG_NAMES = ["tsconfig.json", "jsconfig.json"];
17906
17890
  function findNearestTsconfig(startDir) {
17907
- let dir = path12.resolve(startDir);
17891
+ const start = path12.resolve(startDir);
17892
+ let dir = start;
17908
17893
  while (true) {
17909
- for (const name of ["tsconfig.json", "jsconfig.json"]) {
17894
+ const names = dir === start ? TSCONFIG_NAMES : WALK_UP_TSCONFIG_NAMES;
17895
+ for (const name of names) {
17910
17896
  const candidate = path12.join(dir, name);
17911
17897
  if (fs6.existsSync(candidate)) {
17912
17898
  return candidate;
@@ -17922,7 +17908,7 @@ function findNearestTsconfig(startDir) {
17922
17908
 
17923
17909
  // src/facts/why.ts
17924
17910
  import path13 from "path";
17925
- import { Node as Node65, Project as Project3, SyntaxKind as SyntaxKind13 } from "ts-morph";
17911
+ import { Node as Node66, Project as Project3, SyntaxKind as SyntaxKind13 } from "ts-morph";
17926
17912
  import { explainResolutionProof, renderExplanation } from "@suss/resolution";
17927
17913
  var JS_PHRASES = {
17928
17914
  bind: ({ tuple, describe }) => ({
@@ -17951,7 +17937,7 @@ var TypeScriptWhySession = class {
17951
17937
  }
17952
17938
  let found = null;
17953
17939
  sourceFile.forEachDescendant((node) => {
17954
- if (Node65.isExpression(node) && node.getStartLineNumber() === line && node.getText() === text && (found === null || node.getWidth() <= found.getWidth())) {
17940
+ if (Node66.isExpression(node) && node.getStartLineNumber() === line && node.getText() === text && (found === null || node.getWidth() <= found.getWidth())) {
17955
17941
  found = node;
17956
17942
  }
17957
17943
  });
@@ -18043,21 +18029,21 @@ var TypeScriptWhySession = class {
18043
18029
  }
18044
18030
  };
18045
18031
  function displayNameOf(node) {
18046
- if (Node65.isIdentifier(node) || Node65.isPropertyAccessExpression(node)) {
18032
+ if (Node66.isIdentifier(node) || Node66.isPropertyAccessExpression(node)) {
18047
18033
  return node.getText();
18048
18034
  }
18049
- if (Node65.isCallExpression(node) || Node65.isNewExpression(node)) {
18035
+ if (Node66.isCallExpression(node) || Node66.isNewExpression(node)) {
18050
18036
  return `${node.getExpression()?.getText() ?? "call"}(...)`;
18051
18037
  }
18052
- if (Node65.isFunctionDeclaration(node) || Node65.isClassDeclaration(node) || Node65.isMethodDeclaration(node) || Node65.isVariableDeclaration(node)) {
18038
+ if (Node66.isFunctionDeclaration(node) || Node66.isClassDeclaration(node) || Node66.isMethodDeclaration(node) || Node66.isVariableDeclaration(node)) {
18053
18039
  const name = node.getName();
18054
18040
  if (name !== void 0) {
18055
18041
  return name;
18056
18042
  }
18057
18043
  }
18058
- if (Node65.isArrowFunction(node) || Node65.isFunctionExpression(node)) {
18044
+ if (Node66.isArrowFunction(node) || Node66.isFunctionExpression(node)) {
18059
18045
  const parent = node.getParent();
18060
- if (parent !== void 0 && Node65.isVariableDeclaration(parent)) {
18046
+ if (parent !== void 0 && Node66.isVariableDeclaration(parent)) {
18061
18047
  return parent.getName();
18062
18048
  }
18063
18049
  }
@@ -18111,6 +18097,7 @@ export {
18111
18097
  GENERIC_TERMINALS,
18112
18098
  NO_BARRIERS,
18113
18099
  ResolutionStore,
18100
+ TSCONFIG_NAMES,
18114
18101
  TypeScriptWhySession,
18115
18102
  accessContextFor,
18116
18103
  buildProjectHelperIndex,