@suss/adapter-typescript 0.25.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";
@@ -21,6 +21,7 @@ import {
21
21
  import { Database as Database5 } from "@suss/datalog";
22
22
  import {
23
23
  assembleSummary as assembleSummary3,
24
+ commonDirectoryOf as commonDirectoryOf2,
24
25
  composeWrappers,
25
26
  createCacheLayer,
26
27
  runDigest,
@@ -28,7 +29,7 @@ import {
28
29
  } from "@suss/extractor";
29
30
 
30
31
  // src/assembly.ts
31
- import { Node as Node52 } from "ts-morph";
32
+ import { Node as Node53 } from "ts-morph";
32
33
  import { guardsHoldOn, runsBefore } from "@suss/extractor";
33
34
 
34
35
  // src/conditions.ts
@@ -845,11 +846,11 @@ function tryExpandArrayIncludes(call) {
845
846
  return {
846
847
  type: "compound",
847
848
  op: "or",
848
- operands: literalValues.map((lit6) => ({
849
+ operands: literalValues.map((lit5) => ({
849
850
  type: "comparison",
850
851
  left: subject,
851
852
  op: "eq",
852
- right: lit6
853
+ right: lit5
853
854
  }))
854
855
  };
855
856
  }
@@ -1501,7 +1502,7 @@ function degradedResult(func, terminalNodes, reason) {
1501
1502
 
1502
1503
  // src/resolve/invocationEffects.ts
1503
1504
  import {
1504
- Node as Node41
1505
+ Node as Node42
1505
1506
  } from "ts-morph";
1506
1507
  import { rawConditionToPredicate } from "@suss/extractor";
1507
1508
 
@@ -1986,7 +1987,8 @@ function readFileText(project, filePath) {
1986
1987
  return null;
1987
1988
  }
1988
1989
  }
1989
- function parseTsconfig(tsConfigFilePath) {
1990
+ function parseTsconfig(tsConfigFilePath, seen = /* @__PURE__ */ new Set()) {
1991
+ seen.add(tsConfigFilePath);
1990
1992
  const configFile = ts.readConfigFile(tsConfigFilePath, ts.sys.readFile);
1991
1993
  if (configFile.error !== void 0) {
1992
1994
  return { fileNames: [], options: {} };
@@ -1999,7 +2001,18 @@ function parseTsconfig(tsConfigFilePath) {
1999
2001
  void 0,
2000
2002
  tsConfigFilePath
2001
2003
  );
2002
- 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 };
2003
2016
  }
2004
2017
  async function selectCandidateFiles(allFiles, packs, options) {
2005
2018
  const ungatedExists = packs.some(packIsUngated);
@@ -2360,7 +2373,7 @@ function reportUnreadableExports(file) {
2360
2373
  }
2361
2374
 
2362
2375
  // src/resolve/callOps.ts
2363
- import { Node as Node40 } from "ts-morph";
2376
+ import { Node as Node41 } from "ts-morph";
2364
2377
 
2365
2378
  // src/configuredCall.ts
2366
2379
  import { Node as Node11 } from "ts-morph";
@@ -2418,10 +2431,10 @@ function rootIdentifier(node) {
2418
2431
  }
2419
2432
 
2420
2433
  // src/parameterReads.ts
2421
- import { Node as Node38 } from "ts-morph";
2434
+ import { Node as Node39 } from "ts-morph";
2422
2435
 
2423
2436
  // src/resolve/functionBehind.ts
2424
- import { Node as Node37 } from "ts-morph";
2437
+ import { Node as Node38 } from "ts-morph";
2425
2438
 
2426
2439
  // src/facts/store.ts
2427
2440
  import { Node as Node15 } from "ts-morph";
@@ -4382,180 +4395,8 @@ function declarationOf(value) {
4382
4395
  import { Node as Node18 } from "ts-morph";
4383
4396
 
4384
4397
  // src/discovery/importScan.ts
4385
- import path3 from "path";
4386
-
4387
- // src/diagnostics.ts
4388
4398
  import path2 from "path";
4389
- import { ts as ts3 } from "ts-morph";
4390
- import {
4391
- createPackTallies,
4392
- emptyTally,
4393
- recordPackFailure,
4394
- summaryCountsByPack
4395
- } from "@suss/extractor";
4396
- function commonDirectoryOf(files) {
4397
- const absolute = files.filter((f) => path2.isAbsolute(f));
4398
- const first = absolute[0];
4399
- if (first === void 0) {
4400
- return void 0;
4401
- }
4402
- let shared = path2.dirname(first).split(path2.sep);
4403
- for (const file of absolute.slice(1)) {
4404
- const parts = path2.dirname(file).split(path2.sep);
4405
- let i = 0;
4406
- while (i < shared.length && i < parts.length && shared[i] === parts[i]) {
4407
- i += 1;
4408
- }
4409
- shared = shared.slice(0, i);
4410
- }
4411
- const joined2 = shared.join(path2.sep);
4412
- return joined2.length > 1 ? joined2 : void 0;
4413
- }
4414
- var DEFAULT_RESOLUTION = {
4415
- moduleResolution: ts3.ModuleResolutionKind.Bundler,
4416
- target: ts3.ScriptTarget.ESNext,
4417
- module: ts3.ModuleKind.ESNext
4418
- };
4419
- function resolutionContext(args) {
4420
- if (args.tsConfigFilePath !== void 0) {
4421
- const configFile = ts3.readConfigFile(
4422
- args.tsConfigFilePath,
4423
- ts3.sys.readFile
4424
- );
4425
- if (configFile.error !== void 0) {
4426
- return null;
4427
- }
4428
- const dir = path2.dirname(args.tsConfigFilePath);
4429
- const parsed = ts3.parseJsonConfigFileContent(
4430
- configFile.config,
4431
- ts3.sys,
4432
- dir,
4433
- /*existingOptions*/
4434
- void 0,
4435
- args.tsConfigFilePath
4436
- );
4437
- return {
4438
- containingFile: path2.join(dir, "index.ts"),
4439
- options: parsed.options
4440
- };
4441
- }
4442
- if (args.projectRoot === void 0 || !path2.isAbsolute(args.projectRoot)) {
4443
- return null;
4444
- }
4445
- return {
4446
- containingFile: path2.join(args.projectRoot, "index.ts"),
4447
- options: DEFAULT_RESOLUTION
4448
- };
4449
- }
4450
- function unresolvedGatesFor(gates, args) {
4451
- if (gates.length === 0) {
4452
- return [];
4453
- }
4454
- const context = resolutionContext(args);
4455
- if (context === null) {
4456
- return [];
4457
- }
4458
- const unresolved = [];
4459
- for (const gate of gates) {
4460
- const resolved = ts3.resolveModuleName(
4461
- gate,
4462
- context.containingFile,
4463
- context.options,
4464
- ts3.sys
4465
- );
4466
- if (resolved.resolvedModule === void 0) {
4467
- unresolved.push(gate);
4468
- }
4469
- }
4470
- return unresolved;
4471
- }
4472
- function helpersWithNoCall(patterns, matched, projectRoot) {
4473
- const missing = [];
4474
- for (const pattern of patterns) {
4475
- if (pattern.match.type !== "registrationTemplate" || matched.has(pattern.match.helperName)) {
4476
- continue;
4477
- }
4478
- const from = pattern.match.importModule;
4479
- missing.push(
4480
- from === void 0 ? pattern.match.helperName : `${pattern.match.helperName} from ${shortModule(from, projectRoot)}`
4481
- );
4482
- }
4483
- return missing;
4484
- }
4485
- function shortModule(module, projectRoot) {
4486
- if (projectRoot === void 0 || !path2.isAbsolute(module)) {
4487
- return module;
4488
- }
4489
- return path2.relative(projectRoot, module);
4490
- }
4491
- function buildExtractionReport(args) {
4492
- const bySummary = summaryCountsByPack(args.summaries);
4493
- const packFunnels = args.packs.map((pack) => {
4494
- const gates = packIsUngated(pack) ? [] : collectPackGates(pack);
4495
- const tally = args.tallies.get(pack.name) ?? emptyTally();
4496
- const counted = bySummary.get(pack.name) ?? {
4497
- bound: 0,
4498
- providers: 0,
4499
- withBehavior: 0
4500
- };
4501
- return {
4502
- pack: pack.name,
4503
- version: pack.version ?? null,
4504
- discovers: pack.discovery.length > 0 || pack.discoverUnits !== void 0,
4505
- recognizes: (pack.invocationRecognizers?.length ?? 0) > 0 || (pack.accessRecognizers?.length ?? 0) > 0,
4506
- gates,
4507
- unresolvedGates: unresolvedGatesFor(gates, {
4508
- tsConfigFilePath: args.tsConfigFilePath,
4509
- projectRoot: args.projectRoot
4510
- }),
4511
- candidateFiles: tally.candidateFiles,
4512
- unitsDiscovered: tally.unitsDiscovered,
4513
- unitsInGatedFiles: tally.unitsInGatedFiles,
4514
- effectsRecognized: tally.effectsRecognized,
4515
- unitsClaimed: tally.unitsClaimed,
4516
- summariesProduced: tally.summariesProduced,
4517
- failures: tally.failures,
4518
- helpersUnmatched: helpersWithNoCall(
4519
- [...pack.discovery, ...args.contributedPatterns?.(pack.name) ?? []],
4520
- tally.helpersMatched,
4521
- args.projectRoot
4522
- ),
4523
- summariesBound: counted.bound,
4524
- providerSummaries: counted.providers,
4525
- summariesWithBehavior: counted.withBehavior,
4526
- declarations: pack.declarations ?? null
4527
- };
4528
- });
4529
- return {
4530
- filesInProject: args.filesInProject,
4531
- filesWalked: args.filesWalked,
4532
- packs: packFunnels,
4533
- summaries: args.summaries.length,
4534
- filesWithUnreadableExports: [...args.filesWithUnreadableExports ?? []],
4535
- reassignedNamesUnstated: args.reassignedNamesUnstated ?? 0,
4536
- emptyStage: args.summaries.length === 0 ? firstEmptyStage(packFunnels, args) : null
4537
- };
4538
- }
4539
- function firstEmptyStage(packs, args) {
4540
- if (args.filesInProject === 0) {
4541
- return "tsconfig";
4542
- }
4543
- const gateFailed = packs.some(
4544
- (p) => p.unresolvedGates.length > 0 && p.candidateFiles > 0
4545
- );
4546
- if (gateFailed) {
4547
- return "gateResolution";
4548
- }
4549
- if (args.filesWalked === 0 || packs.every((p) => p.candidateFiles === 0)) {
4550
- return "candidateFiles";
4551
- }
4552
- if (packs.every((p) => p.unitsDiscovered === 0)) {
4553
- return "discovery";
4554
- }
4555
- return "assembly";
4556
- }
4557
-
4558
- // src/discovery/importScan.ts
4399
+ import { commonDirectoryOf } from "@suss/extractor";
4559
4400
  function specifierMatches(specifier, moduleName, subpaths) {
4560
4401
  if (specifier === moduleName) {
4561
4402
  return true;
@@ -4647,7 +4488,7 @@ function resolvedModuleFile(project, importModule, resolution) {
4647
4488
  function projectFileNamedBy(project, specifier) {
4648
4489
  const files = project.getSourceFiles().filter((sf) => !sf.isDeclarationFile());
4649
4490
  const root = commonDirectoryOf(files.map((sf) => sf.getFilePath())) ?? "/";
4650
- const target = withoutSourceExtension(path3.resolve(root, specifier));
4491
+ const target = withoutSourceExtension(path2.resolve(root, specifier));
4651
4492
  for (const candidate of files) {
4652
4493
  if (withoutSourceExtension(candidate.getFilePath()) === target) {
4653
4494
  return candidate;
@@ -5411,6 +5252,7 @@ function literalValueOf(value, resolution, isWanted) {
5411
5252
  }
5412
5253
 
5413
5254
  // src/discovery/clientCall.ts
5255
+ var GLOBAL_OBJECTS = /* @__PURE__ */ new Set(["globalThis", "window", "self", "global"]);
5414
5256
  function discoverClientCalls(sourceFile, match, kind, resolution) {
5415
5257
  const results = [];
5416
5258
  const isGlobal = match.importModule === "global";
@@ -5435,9 +5277,15 @@ function discoverClientCalls(sourceFile, match, kind, resolution) {
5435
5277
  if (callee.getText() === match.importName) {
5436
5278
  matched = true;
5437
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;
5438
5286
  } else if (Node18.isPropertyAccessExpression(callee)) {
5439
5287
  const subject = callee.getExpression();
5440
- if (Node18.isIdentifier(subject) && (isClientImport(subject, match, resolution, true) || clientVarNames.has(subject.getText())) || resolvesToKnownInstance(subject, match, resolution)) {
5288
+ if (isClientItself(subject, match, clientVarNames, resolution)) {
5441
5289
  methodName = callee.getName();
5442
5290
  if (methodFilter === null || methodFilter.has(methodName)) {
5443
5291
  matched = true;
@@ -5463,6 +5311,9 @@ function discoverClientCalls(sourceFile, match, kind, resolution) {
5463
5311
  });
5464
5312
  return results;
5465
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
+ }
5466
5317
  function clientReceiverCheckFor(sourceFile, match, resolution) {
5467
5318
  const localName = resolveImportedLocalName(
5468
5319
  sourceFile,
@@ -6106,7 +5957,7 @@ import { Node as Node26 } from "ts-morph";
6106
5957
 
6107
5958
  // src/discovery/graphqlShared.ts
6108
5959
  import fs2 from "fs";
6109
- import path4 from "path";
5960
+ import path3 from "path";
6110
5961
  import {
6111
5962
  Kind as GraphqlKind,
6112
5963
  parse as graphqlParse,
@@ -6649,8 +6500,8 @@ function resolveGraphqlFileImport(decl) {
6649
6500
  return null;
6650
6501
  }
6651
6502
  const sourceFile = importDecl.getSourceFile();
6652
- const baseDir = path4.dirname(sourceFile.getFilePath());
6653
- const absolute = path4.resolve(baseDir, specifier);
6503
+ const baseDir = path3.dirname(sourceFile.getFilePath());
6504
+ const absolute = path3.resolve(baseDir, specifier);
6654
6505
  try {
6655
6506
  return fs2.readFileSync(absolute, "utf8");
6656
6507
  } catch {
@@ -7257,13 +7108,13 @@ import { Node as Node30 } from "ts-morph";
7257
7108
 
7258
7109
  // src/packageExports.ts
7259
7110
  import fs3 from "fs";
7260
- import path5 from "path";
7111
+ import path4 from "path";
7261
7112
  function resolvePackageExports(packageJsonPath, opts = {}) {
7262
- const absPkgJson = path5.resolve(packageJsonPath);
7263
- const pkgDir = path5.dirname(absPkgJson);
7113
+ const absPkgJson = path4.resolve(packageJsonPath);
7114
+ const pkgDir = path4.dirname(absPkgJson);
7264
7115
  const raw = fs3.readFileSync(absPkgJson, "utf8");
7265
7116
  const pkg = JSON.parse(raw);
7266
- const packageName = pkg.name ?? path5.basename(pkgDir);
7117
+ const packageName = pkg.name ?? path4.basename(pkgDir);
7267
7118
  const warnings = [];
7268
7119
  const entries = [];
7269
7120
  const pushEntry = (subPath, distPath) => {
@@ -7282,7 +7133,7 @@ function resolvePackageExports(packageJsonPath, opts = {}) {
7282
7133
  subPath,
7283
7134
  exportPathPrefix: subPathToPrefix(subPath),
7284
7135
  sourceFile: src,
7285
- publishedFile: path5.resolve(pkgDir, distPath)
7136
+ publishedFile: path4.resolve(pkgDir, distPath)
7286
7137
  });
7287
7138
  };
7288
7139
  const exportsField = pkg.exports;
@@ -7324,12 +7175,12 @@ function resolvePackageExportsCached(packageJsonPath) {
7324
7175
  return fresh;
7325
7176
  }
7326
7177
  function namedPackageDirAbove(start) {
7327
- let at = path5.resolve(start);
7178
+ let at = path4.resolve(start);
7328
7179
  for (let up = 0; up < 12; up += 1) {
7329
7180
  if (packageNameAt(at) !== null) {
7330
7181
  return at;
7331
7182
  }
7332
- const parent = path5.dirname(at);
7183
+ const parent = path4.dirname(at);
7333
7184
  if (parent === at) {
7334
7185
  break;
7335
7186
  }
@@ -7340,7 +7191,7 @@ function namedPackageDirAbove(start) {
7340
7191
  function packageNameAt(dir) {
7341
7192
  try {
7342
7193
  const manifest = JSON.parse(
7343
- fs3.readFileSync(path5.join(dir, "package.json"), "utf8")
7194
+ fs3.readFileSync(path4.join(dir, "package.json"), "utf8")
7344
7195
  );
7345
7196
  if (typeof manifest.name === "string" && manifest.name.length > 0) {
7346
7197
  return manifest.name;
@@ -7390,7 +7241,7 @@ function resolveSourceFor(pkgDir, distPath, srcRoot) {
7390
7241
  const stem = withoutDist.replace(/\.d\.ts$/, "").replace(/\.js$/, "").replace(/\.cjs$/, "").replace(/\.mjs$/, "").replace(/\.ts$/, "");
7391
7242
  const candidates = [`${stem}.ts`, `${stem}.tsx`];
7392
7243
  for (const candidate of candidates) {
7393
- const abs = path5.resolve(pkgDir, candidate);
7244
+ const abs = path4.resolve(pkgDir, candidate);
7394
7245
  if (fs3.existsSync(abs)) {
7395
7246
  return abs;
7396
7247
  }
@@ -7399,20 +7250,20 @@ function resolveSourceFor(pkgDir, distPath, srcRoot) {
7399
7250
  }
7400
7251
 
7401
7252
  // src/resolve/sourceDeclaration.ts
7402
- import path6 from "path";
7253
+ import path5 from "path";
7403
7254
  function sourceDeclarationsBehind(decl, resolution, visited = /* @__PURE__ */ new Set()) {
7404
7255
  const file = decl.getSourceFile();
7405
7256
  if (!file.isDeclarationFile() || file.isInNodeModules()) {
7406
7257
  return [decl];
7407
7258
  }
7408
- const packageDir = namedPackageDirAbove(path6.dirname(file.getFilePath()));
7259
+ const packageDir = namedPackageDirAbove(path5.dirname(file.getFilePath()));
7409
7260
  if (packageDir === null || visited.has(packageDir)) {
7410
7261
  return [decl];
7411
7262
  }
7412
7263
  visited.add(packageDir);
7413
7264
  const project = file.getProject();
7414
7265
  const { entries } = resolvePackageExportsCached(
7415
- path6.join(packageDir, "package.json")
7266
+ path5.join(packageDir, "package.json")
7416
7267
  );
7417
7268
  const found = [];
7418
7269
  for (const entry of entries) {
@@ -7892,36 +7743,176 @@ function discoverPackageImports(sourceFile, match, kind, resolution) {
7892
7743
  }
7893
7744
 
7894
7745
  // src/discovery/registrationCall.ts
7895
- import { Node as Node32 } from "ts-morph";
7746
+ import { Node as Node34 } from "ts-morph";
7896
7747
  import { joinMountedPath } from "@suss/resolution";
7897
7748
 
7898
7749
  // src/resolve/routePath.ts
7899
- import { pathOf } from "@suss/values";
7750
+ import { force as force3, pathOf } from "@suss/values";
7900
7751
  function pathFromArgument(arg, resolution) {
7901
7752
  return pathOf(evaluatedValue(arg, resolution));
7902
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
+ }
7903
7762
 
7904
- // src/discovery/registrationCall.ts
7905
- function discoverRegistrationCalls(sourceFile, match, kind, bindingExtraction, resolution, mountPrefixes, expandedElsewhere) {
7906
- const results = [];
7907
- const registrationSubjects = registrationSubjectsOf(
7908
- sourceFile,
7909
- match.importModule,
7910
- match.importName,
7911
- resolution
7912
- );
7913
- const registrationMethods = match.registrationChain.map(
7914
- (c) => c.startsWith(".") ? c.slice(1) : c
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
7915
7803
  );
7916
- if (registrationSubjects.size === 0 && !storeCanFindSubjects(sourceFile, match, resolution, registrationMethods)) {
7917
- return results;
7804
+ return module !== void 0 && Node32.isStringLiteral(module.getNameNode());
7805
+ }
7806
+ function statesShapeOnly(declaration) {
7807
+ if (isExternalDeclaration(declaration)) {
7808
+ return false;
7918
7809
  }
7919
- sourceFile.forEachDescendant((node) => {
7920
- if (!Node32.isCallExpression(node)) {
7921
- return;
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;
7922
7837
  }
7923
- const callee = node.getExpression();
7924
- if (!Node32.isPropertyAccessExpression(callee)) {
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
+ }
7894
+
7895
+ // src/discovery/registrationCall.ts
7896
+ function discoverRegistrationCalls(sourceFile, match, kind, bindingExtraction, resolution, mountPrefixes, expandedElsewhere, routeWrapperPattern) {
7897
+ const results = [];
7898
+ const registrationSubjects = registrationSubjectsOf(
7899
+ sourceFile,
7900
+ match.importModule,
7901
+ match.importName,
7902
+ resolution
7903
+ );
7904
+ const registrationMethods = match.registrationChain.map(
7905
+ (c) => c.startsWith(".") ? c.slice(1) : c
7906
+ );
7907
+ if (registrationSubjects.size === 0 && !storeCanFindSubjects(sourceFile, match, resolution, registrationMethods)) {
7908
+ return results;
7909
+ }
7910
+ sourceFile.forEachDescendant((node) => {
7911
+ if (!Node34.isCallExpression(node)) {
7912
+ return;
7913
+ }
7914
+ const callee = node.getExpression();
7915
+ if (!Node34.isPropertyAccessExpression(callee)) {
7925
7916
  return;
7926
7917
  }
7927
7918
  const methodName = callee.getName();
@@ -7958,12 +7949,12 @@ function discoverRegistrationCalls(sourceFile, match, kind, bindingExtraction, r
7958
7949
  const registrationSubjectId = nodeId(subjectNode);
7959
7950
  let foundObjectArg = false;
7960
7951
  for (const arg of args) {
7961
- if (!Node32.isObjectLiteralExpression(arg)) {
7952
+ if (!Node34.isObjectLiteralExpression(arg)) {
7962
7953
  continue;
7963
7954
  }
7964
7955
  foundObjectArg = true;
7965
7956
  for (const prop of arg.getProperties()) {
7966
- if (Node32.isMethodDeclaration(prop)) {
7957
+ if (Node34.isMethodDeclaration(prop)) {
7967
7958
  results.push({
7968
7959
  func: prop,
7969
7960
  kind,
@@ -7972,7 +7963,7 @@ function discoverRegistrationCalls(sourceFile, match, kind, bindingExtraction, r
7972
7963
  });
7973
7964
  continue;
7974
7965
  }
7975
- if (!Node32.isPropertyAssignment(prop)) {
7966
+ if (!Node34.isPropertyAssignment(prop)) {
7976
7967
  continue;
7977
7968
  }
7978
7969
  const propInit = prop.getInitializer();
@@ -8004,6 +7995,13 @@ function discoverRegistrationCalls(sourceFile, match, kind, bindingExtraction, r
8004
7995
  mountPrefixes
8005
7996
  );
8006
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
+ );
8007
8005
  results.push({
8008
8006
  func: handler,
8009
8007
  kind,
@@ -8011,8 +8009,13 @@ function discoverRegistrationCalls(sourceFile, match, kind, bindingExtraction, r
8011
8009
  name: methodName,
8012
8010
  nameKind: "label",
8013
8011
  registrationSubjectId,
8014
- ...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 }
8015
8015
  });
8016
+ if (chain !== null) {
8017
+ results.push(...chain.units);
8018
+ }
8016
8019
  return;
8017
8020
  }
8018
8021
  if (routeInfo !== null && lastArg !== void 0 && namesAParameter(lastArg)) {
@@ -8058,6 +8061,47 @@ function declinedRegistration(call, callee, methodName, kind, receiver, resoluti
8058
8061
  }
8059
8062
  ];
8060
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
+ }
8061
8105
  function withMountPrefix(routeInfo, subjectNode, mountPrefixes) {
8062
8106
  if (routeInfo === null || mountPrefixes === void 0) {
8063
8107
  return routeInfo;
@@ -8085,13 +8129,13 @@ function subjectNodeFor(subject, subjects, match, resolution) {
8085
8129
  }
8086
8130
  var NOT_A_ROUTABLE = { kind: "none" };
8087
8131
  function receiverOf(subject, subjects, match, resolution) {
8088
- if (Node32.isIdentifier(subject)) {
8132
+ if (Node34.isIdentifier(subject)) {
8089
8133
  const known = subjects.get(subject.getText());
8090
8134
  if (known !== void 0) {
8091
8135
  return { kind: "routable", node: known };
8092
8136
  }
8093
8137
  }
8094
- if (resolution === void 0 || !(Node32.isIdentifier(subject) || Node32.isPropertyAccessExpression(subject))) {
8138
+ if (resolution === void 0 || !(Node34.isIdentifier(subject) || Node34.isPropertyAccessExpression(subject))) {
8095
8139
  return NOT_A_ROUTABLE;
8096
8140
  }
8097
8141
  const construction = resolution.subjectConstructionOf(
@@ -8131,18 +8175,18 @@ function collectMethodsCalledOnCallResults(sourceFile) {
8131
8175
  const setToCalls = /* @__PURE__ */ new Set();
8132
8176
  const calledOn = /* @__PURE__ */ new Map();
8133
8177
  sourceFile.forEachDescendant((node) => {
8134
- if (Node32.isVariableDeclaration(node)) {
8178
+ if (Node34.isVariableDeclaration(node)) {
8135
8179
  const init = node.getInitializer();
8136
- if (init !== void 0 && Node32.isCallExpression(init)) {
8180
+ if (init !== void 0 && Node34.isCallExpression(init)) {
8137
8181
  setToCalls.add(node.getName());
8138
8182
  }
8139
8183
  return;
8140
8184
  }
8141
- if (!Node32.isCallExpression(node)) {
8185
+ if (!Node34.isCallExpression(node)) {
8142
8186
  return;
8143
8187
  }
8144
8188
  const callee = node.getExpression();
8145
- if (!Node32.isPropertyAccessExpression(callee) || !Node32.isIdentifier(callee.getExpression())) {
8189
+ if (!Node34.isPropertyAccessExpression(callee) || !Node34.isIdentifier(callee.getExpression())) {
8146
8190
  return;
8147
8191
  }
8148
8192
  const receiver = callee.getExpression().getText();
@@ -8169,18 +8213,18 @@ function registrationSubjectsOf(sourceFile, importModule, importName, resolution
8169
8213
  return subjects;
8170
8214
  }
8171
8215
  sourceFile.forEachDescendant((node) => {
8172
- if (Node32.isVariableDeclaration(node)) {
8216
+ if (Node34.isVariableDeclaration(node)) {
8173
8217
  const init = node.getInitializer();
8174
8218
  if (init === void 0) {
8175
8219
  return;
8176
8220
  }
8177
- 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;
8178
8222
  if (calleeText !== null && spellings.includes(calleeText)) {
8179
8223
  subjects.set(node.getName(), init);
8180
8224
  }
8181
8225
  return;
8182
8226
  }
8183
- if (!Node32.isParameterDeclaration(node)) {
8227
+ if (!Node34.isParameterDeclaration(node)) {
8184
8228
  return;
8185
8229
  }
8186
8230
  const typeNode = node.getTypeNode();
@@ -8201,7 +8245,7 @@ function creationSiteBehind(parameter, resolution) {
8201
8245
  return parameter;
8202
8246
  }
8203
8247
  const written = resolution.resolveWrittenValue(parameter);
8204
- if (written === null || !(Node32.isCallExpression(written) || Node32.isNewExpression(written))) {
8248
+ if (written === null || !(Node34.isCallExpression(written) || Node34.isNewExpression(written))) {
8205
8249
  return parameter;
8206
8250
  }
8207
8251
  return written;
@@ -8244,7 +8288,7 @@ function unboundConstructionsOf(sourceFile, importModule, importName) {
8244
8288
  }
8245
8289
  const constructions = [];
8246
8290
  sourceFile.forEachDescendant((node) => {
8247
- 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())) {
8248
8292
  constructions.push(node);
8249
8293
  }
8250
8294
  });
@@ -8262,11 +8306,11 @@ function discoverMountEdges(sourceFile, match, mount, knownSubjectIds, resolutio
8262
8306
  }
8263
8307
  const edges = [];
8264
8308
  sourceFile.forEachDescendant((node) => {
8265
- if (!Node32.isCallExpression(node)) {
8309
+ if (!Node34.isCallExpression(node)) {
8266
8310
  return;
8267
8311
  }
8268
8312
  const callee = node.getExpression();
8269
- if (!Node32.isPropertyAccessExpression(callee) || callee.getName() !== mount.method) {
8313
+ if (!Node34.isPropertyAccessExpression(callee) || callee.getName() !== mount.method) {
8270
8314
  return;
8271
8315
  }
8272
8316
  const subjectNode = subjectNodeFor(
@@ -8280,7 +8324,7 @@ function discoverMountEdges(sourceFile, match, mount, knownSubjectIds, resolutio
8280
8324
  }
8281
8325
  const args = node.getArguments();
8282
8326
  const prefixArg = args[mount.prefixPosition];
8283
- if (prefixArg === void 0 || !(Node32.isStringLiteral(prefixArg) || Node32.isNoSubstitutionTemplateLiteral(prefixArg))) {
8327
+ if (prefixArg === void 0 || !(Node34.isStringLiteral(prefixArg) || Node34.isNoSubstitutionTemplateLiteral(prefixArg))) {
8284
8328
  return;
8285
8329
  }
8286
8330
  const targetNodes = mountTargetsAmong(
@@ -8335,7 +8379,7 @@ function extractRouteInfoFromBinding(call, methodName, binding, resolution) {
8335
8379
  } else {
8336
8380
  const args = call.getArguments();
8337
8381
  const arg = args[binding.method.position];
8338
- if (arg === void 0 || !(Node32.isStringLiteral(arg) || Node32.isNoSubstitutionTemplateLiteral(arg))) {
8382
+ if (arg === void 0 || !(Node34.isStringLiteral(arg) || Node34.isNoSubstitutionTemplateLiteral(arg))) {
8339
8383
  return null;
8340
8384
  }
8341
8385
  method = arg.getLiteralValue().toUpperCase();
@@ -8346,7 +8390,7 @@ function extractRouteInfoFromBinding(call, methodName, binding, resolution) {
8346
8390
  }
8347
8391
 
8348
8392
  // src/discovery/registrationLoop.ts
8349
- import { Node as Node33 } from "ts-morph";
8393
+ import { Node as Node35 } from "ts-morph";
8350
8394
  function discoverRegistrationLoops(sourceFile, match, kind, resolution) {
8351
8395
  const results = [];
8352
8396
  const guard = receiverGuard(sourceFile, match.receiver, resolution);
@@ -8354,7 +8398,7 @@ function discoverRegistrationLoops(sourceFile, match, kind, resolution) {
8354
8398
  return results;
8355
8399
  }
8356
8400
  sourceFile.forEachDescendant((node) => {
8357
- if (!Node33.isForOfStatement(node)) {
8401
+ if (!Node35.isForOfStatement(node)) {
8358
8402
  return;
8359
8403
  }
8360
8404
  const expanded = tryExpandLoop(node, match, kind, resolution, guard);
@@ -8417,13 +8461,13 @@ function tryExpandLoop(loop, match, kind, resolution, guard) {
8417
8461
  }
8418
8462
  function loopVariableName(loop) {
8419
8463
  const initializer = loop.getInitializer();
8420
- if (Node33.isVariableDeclarationList(initializer)) {
8464
+ if (Node35.isVariableDeclarationList(initializer)) {
8421
8465
  const decls = initializer.getDeclarations();
8422
8466
  if (decls.length !== 1) {
8423
8467
  return null;
8424
8468
  }
8425
8469
  const nameNode = decls[0]?.getNameNode();
8426
- if (nameNode !== void 0 && Node33.isIdentifier(nameNode)) {
8470
+ if (nameNode !== void 0 && Node35.isIdentifier(nameNode)) {
8427
8471
  return nameNode.getText();
8428
8472
  }
8429
8473
  }
@@ -8436,14 +8480,14 @@ function bodyReferencesLoopVar(loop, name) {
8436
8480
  if (referenced) {
8437
8481
  return;
8438
8482
  }
8439
- if (!Node33.isCallExpression(node)) {
8483
+ if (!Node35.isCallExpression(node)) {
8440
8484
  return;
8441
8485
  }
8442
8486
  node.forEachDescendant((inner) => {
8443
8487
  if (referenced) {
8444
8488
  return;
8445
8489
  }
8446
- if (Node33.isIdentifier(inner) && inner.getText() === name) {
8490
+ if (Node35.isIdentifier(inner) && inner.getText() === name) {
8447
8491
  referenced = true;
8448
8492
  }
8449
8493
  });
@@ -8453,11 +8497,11 @@ function bodyReferencesLoopVar(loop, name) {
8453
8497
  function bodyCallsOnRoutable(loop, guard, resolution) {
8454
8498
  let found = false;
8455
8499
  loop.getStatement().forEachDescendant((node) => {
8456
- if (found || !Node33.isCallExpression(node)) {
8500
+ if (found || !Node35.isCallExpression(node)) {
8457
8501
  return;
8458
8502
  }
8459
8503
  const callee = node.getExpression();
8460
- if (!Node33.isPropertyAccessExpression(callee) && !Node33.isElementAccessExpression(callee)) {
8504
+ if (!Node35.isPropertyAccessExpression(callee) && !Node35.isElementAccessExpression(callee)) {
8461
8505
  return;
8462
8506
  }
8463
8507
  const subject = callee.getExpression();
@@ -8477,11 +8521,11 @@ function readRouteSpec(element, shape, resolution) {
8477
8521
  let path15 = null;
8478
8522
  let handler = null;
8479
8523
  for (const prop of element.getProperties()) {
8480
- if (Node33.isMethodDeclaration(prop) && prop.getName() === shape.handlerKey) {
8524
+ if (Node35.isMethodDeclaration(prop) && prop.getName() === shape.handlerKey) {
8481
8525
  handler = { func: prop, name: shape.handlerKey };
8482
8526
  continue;
8483
8527
  }
8484
- if (!Node33.isPropertyAssignment(prop)) {
8528
+ if (!Node35.isPropertyAssignment(prop)) {
8485
8529
  continue;
8486
8530
  }
8487
8531
  const name = prop.getName();
@@ -8504,117 +8548,19 @@ function readRouteSpec(element, shape, resolution) {
8504
8548
  return { method, path: path15, handler: handler.func, handlerName: handler.name };
8505
8549
  }
8506
8550
  function readStringLiteralValue(node) {
8507
- if (Node33.isStringLiteral(node) || Node33.isNoSubstitutionTemplateLiteral(node)) {
8551
+ if (Node35.isStringLiteral(node) || Node35.isNoSubstitutionTemplateLiteral(node)) {
8508
8552
  return node.getLiteralValue();
8509
8553
  }
8510
8554
  return null;
8511
8555
  }
8512
8556
  function handlerName(value) {
8513
- return Node33.isIdentifier(value) ? value.getText() : value.getKindName();
8557
+ return Node35.isIdentifier(value) ? value.getText() : value.getKindName();
8514
8558
  }
8515
8559
 
8516
8560
  // src/discovery/registrationTemplate.ts
8517
- import path7 from "path";
8518
- import { Node as Node35 } from "ts-morph";
8561
+ import path6 from "path";
8562
+ import { Node as Node36 } from "ts-morph";
8519
8563
  import { joinMountedPath as joinMountedPath2 } from "@suss/resolution";
8520
-
8521
- // src/resolve/unfollowedCall.ts
8522
- import {
8523
- Node as Node34,
8524
- SyntaxKind as SyntaxKind8
8525
- } from "ts-morph";
8526
- import {
8527
- unfollowedCallGap,
8528
- worthRecording
8529
- } from "@suss/behavioral-ir";
8530
- function isInExternalCode(sourceFile) {
8531
- if (sourceFile.isDeclarationFile()) {
8532
- return true;
8533
- }
8534
- return sourceFile.getFilePath().includes("/node_modules/");
8535
- }
8536
- function hasBody(fn) {
8537
- if (Node34.isFunctionDeclaration(fn) || Node34.isMethodDeclaration(fn) || Node34.isFunctionExpression(fn)) {
8538
- return fn.getBody?.() !== void 0;
8539
- }
8540
- return true;
8541
- }
8542
- function isDeclaredShape(declaration) {
8543
- return (Node34.isMethodSignature(declaration) || Node34.isPropertySignature(declaration)) && !isInExternalCode(declaration.getSourceFile());
8544
- }
8545
- function isExternalDeclaration(declaration) {
8546
- if (isInExternalCode(declaration.getSourceFile())) {
8547
- return true;
8548
- }
8549
- if (Node34.isImportSpecifier(declaration) || Node34.isImportClause(declaration) || Node34.isNamespaceImport(declaration)) {
8550
- const target = declaration.getFirstAncestorByKind(SyntaxKind8.ImportDeclaration)?.getModuleSpecifierSourceFile();
8551
- return target === void 0 || isInExternalCode(target);
8552
- }
8553
- return declaresAnotherModule(declaration);
8554
- }
8555
- function declaresAnotherModule(declaration) {
8556
- const module = declaration.getFirstAncestorByKind(
8557
- SyntaxKind8.ModuleDeclaration
8558
- );
8559
- return module !== void 0 && Node34.isStringLiteral(module.getNameNode());
8560
- }
8561
- function statesShapeOnly(declaration) {
8562
- if (isExternalDeclaration(declaration)) {
8563
- return false;
8564
- }
8565
- if (Node34.isMethodSignature(declaration) || Node34.isPropertySignature(declaration)) {
8566
- return true;
8567
- }
8568
- if (Node34.isFunctionDeclaration(declaration) || Node34.isMethodDeclaration(declaration)) {
8569
- return declaration.getBody() === void 0;
8570
- }
8571
- return false;
8572
- }
8573
- function declarationsBehind(symbol) {
8574
- if (symbol === void 0) {
8575
- return [];
8576
- }
8577
- const behind = symbol.getAliasedSymbol()?.getDeclarations() ?? [];
8578
- return behind.length > 0 ? behind : symbol.getDeclarations();
8579
- }
8580
- function isParameterOf(declaration, scanning) {
8581
- return Node34.isParameterDeclaration(declaration) && declaration.getParent() === scanning;
8582
- }
8583
- function parameterIndexOf(declarations, scanning) {
8584
- if (scanning === void 0) {
8585
- return void 0;
8586
- }
8587
- const params = scanning.getParameters();
8588
- for (const declaration of declarations) {
8589
- const index = params.findIndex((param) => param === declaration);
8590
- if (index !== -1) {
8591
- return index;
8592
- }
8593
- }
8594
- return void 0;
8595
- }
8596
- function classifyStop(declarations, scanning) {
8597
- if (declarations.length === 0) {
8598
- return "noDeclaration";
8599
- }
8600
- for (const declaration of declarations) {
8601
- if (!isInExternalCode(declaration.getSourceFile())) {
8602
- recordFileDependency(declaration.getSourceFile().getFilePath());
8603
- }
8604
- }
8605
- if (scanning !== void 0 && declarations.some((declaration) => isParameterOf(declaration, scanning))) {
8606
- return "callerSupplied";
8607
- }
8608
- if (declarations.every(isExternalDeclaration)) {
8609
- return "outsideRun";
8610
- }
8611
- if (declarations.some(statesShapeOnly)) {
8612
- return "noBody";
8613
- }
8614
- return "unsettledValue";
8615
- }
8616
-
8617
- // src/discovery/registrationTemplate.ts
8618
8564
  function discoverRegistrationTemplates(sourceFile, match, kind, resolution, mountPrefixes) {
8619
8565
  const results = [];
8620
8566
  for (const node of helperCallsOf(sourceFile, match, resolution)) {
@@ -8670,20 +8616,20 @@ function subjectOfCall(sourceFile, args, match, resolution) {
8670
8616
  }
8671
8617
  function helperCallsOf(sourceFile, match, resolution) {
8672
8618
  const module = match.importModule;
8673
- if (module !== void 0 && !path7.isAbsolute(module)) {
8619
+ if (module !== void 0 && !path6.isAbsolute(module)) {
8674
8620
  const store = resolution ?? new ResolutionStore();
8675
8621
  return callsResolvingTo(sourceFile, store, {
8676
8622
  module,
8677
8623
  name: match.helperName
8678
- }).filter(Node35.isCallExpression);
8624
+ }).filter(Node36.isCallExpression);
8679
8625
  }
8680
8626
  const calls = [];
8681
8627
  sourceFile.forEachDescendant((node) => {
8682
- if (!Node35.isCallExpression(node)) {
8628
+ if (!Node36.isCallExpression(node)) {
8683
8629
  return;
8684
8630
  }
8685
8631
  const callee = node.getExpression();
8686
- if (!Node35.isIdentifier(callee) || callee.getText() !== match.helperName) {
8632
+ if (!Node36.isIdentifier(callee) || callee.getText() !== match.helperName) {
8687
8633
  return;
8688
8634
  }
8689
8635
  if (module === void 0 || declaredInModule(callee, module)) {
@@ -8727,7 +8673,7 @@ function substitutePath(template, args) {
8727
8673
  return result;
8728
8674
  }
8729
8675
  function readStringLiteral(node) {
8730
- if (Node35.isStringLiteral(node) || Node35.isNoSubstitutionTemplateLiteral(node)) {
8676
+ if (Node36.isStringLiteral(node) || Node36.isNoSubstitutionTemplateLiteral(node)) {
8731
8677
  return node.getLiteralValue();
8732
8678
  }
8733
8679
  return null;
@@ -8750,7 +8696,7 @@ function resolveHandler(template, args, resolution) {
8750
8696
  return readPropertyAsFunction(arg, prop, resolution);
8751
8697
  }
8752
8698
  function handlerName2(value) {
8753
- return Node35.isIdentifier(value) ? value.getText() : value.getKindName();
8699
+ return Node36.isIdentifier(value) ? value.getText() : value.getKindName();
8754
8700
  }
8755
8701
  function readPropertyAsFunction(arg, prop, resolution) {
8756
8702
  const obj = objectLiteralOf(arg, resolution);
@@ -8761,7 +8707,7 @@ function readPropertyAsFunction(arg, prop, resolution) {
8761
8707
  if (propertyName(property) !== prop) {
8762
8708
  continue;
8763
8709
  }
8764
- if (Node35.isMethodDeclaration(property)) {
8710
+ if (Node36.isMethodDeclaration(property)) {
8765
8711
  return { func: property, name: prop };
8766
8712
  }
8767
8713
  const held = propertyValueOf(property);
@@ -8769,19 +8715,19 @@ function readPropertyAsFunction(arg, prop, resolution) {
8769
8715
  return null;
8770
8716
  }
8771
8717
  const func = functionValueOf(held, resolution);
8772
- 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 };
8773
8719
  }
8774
8720
  return null;
8775
8721
  }
8776
8722
  function propertyName(property) {
8777
- if (Node35.isPropertyAssignment(property) || Node35.isShorthandPropertyAssignment(property) || Node35.isMethodDeclaration(property)) {
8723
+ if (Node36.isPropertyAssignment(property) || Node36.isShorthandPropertyAssignment(property) || Node36.isMethodDeclaration(property)) {
8778
8724
  return property.getName();
8779
8725
  }
8780
8726
  return null;
8781
8727
  }
8782
8728
 
8783
8729
  // src/discovery/resolverMap.ts
8784
- import { Node as Node36 } from "ts-morph";
8730
+ import { Node as Node37 } from "ts-morph";
8785
8731
  function discoverResolverMaps(sourceFile, match, kind, resolution) {
8786
8732
  const store = resolution ?? new ResolutionStore();
8787
8733
  const mapProperty = match.mapProperty;
@@ -8792,7 +8738,7 @@ function discoverResolverMaps(sourceFile, match, kind, resolution) {
8792
8738
  name: match.importName
8793
8739
  })) {
8794
8740
  const args = node.getArguments();
8795
- if (args.length === 0 || !Node36.isObjectLiteralExpression(args[0])) {
8741
+ if (args.length === 0 || !Node37.isObjectLiteralExpression(args[0])) {
8796
8742
  continue;
8797
8743
  }
8798
8744
  const config = args[0];
@@ -8846,7 +8792,7 @@ function resolverMapObject(prop, resolution) {
8846
8792
  return held === null ? null : objectLiteralOf(held, resolution);
8847
8793
  }
8848
8794
  function extractTypeDefsSdl(config, resolution) {
8849
- if (!Node36.isObjectLiteralExpression(config)) {
8795
+ if (!Node37.isObjectLiteralExpression(config)) {
8850
8796
  return null;
8851
8797
  }
8852
8798
  const prop = config.getProperty("typeDefs");
@@ -8868,15 +8814,15 @@ function schemaSdlOf(expr, resolution) {
8868
8814
  return resolved === null ? null : writtenSdl(resolved);
8869
8815
  }
8870
8816
  function writtenSdl(expr) {
8871
- if (Node36.isStringLiteral(expr) || Node36.isNoSubstitutionTemplateLiteral(expr)) {
8817
+ if (Node37.isStringLiteral(expr) || Node37.isNoSubstitutionTemplateLiteral(expr)) {
8872
8818
  const value = expr.getLiteralValue();
8873
8819
  return value === "" ? null : value;
8874
8820
  }
8875
- if (Node36.isTaggedTemplateExpression(expr)) {
8821
+ if (Node37.isTaggedTemplateExpression(expr)) {
8876
8822
  const tag = expr.getTag();
8877
- if (Node36.isIdentifier(tag) && tag.getText() === "gql") {
8823
+ if (Node37.isIdentifier(tag) && tag.getText() === "gql") {
8878
8824
  const template = expr.getTemplate();
8879
- if (Node36.isNoSubstitutionTemplateLiteral(template)) {
8825
+ if (Node37.isNoSubstitutionTemplateLiteral(template)) {
8880
8826
  return template.getLiteralValue();
8881
8827
  }
8882
8828
  }
@@ -8885,7 +8831,7 @@ function writtenSdl(expr) {
8885
8831
  }
8886
8832
 
8887
8833
  // src/discovery/index.ts
8888
- function runPattern(sourceFile, pattern, resolution, mountPrefixes, expandedElsewhere) {
8834
+ function runPattern(sourceFile, pattern, resolution, mountPrefixes, expandedElsewhere, routeWrapperPattern) {
8889
8835
  if (pattern.match.type === "namedExport") {
8890
8836
  return discoverNamedExports(
8891
8837
  sourceFile,
@@ -8902,7 +8848,8 @@ function runPattern(sourceFile, pattern, resolution, mountPrefixes, expandedElse
8902
8848
  pattern.bindingExtraction,
8903
8849
  resolution,
8904
8850
  mountPrefixes,
8905
- expandedElsewhere
8851
+ expandedElsewhere,
8852
+ routeWrapperPattern
8906
8853
  );
8907
8854
  }
8908
8855
  if (pattern.match.type === "registrationTemplate") {
@@ -9008,19 +8955,26 @@ function runPattern(sourceFile, pattern, resolution, mountPrefixes, expandedElse
9008
8955
  }
9009
8956
  return [];
9010
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
+ }
9011
8963
  function discoverUnits(sourceFile, patterns, resolution, mountPrefixes, expandedElsewhere) {
9012
8964
  const store = resolution ?? new ResolutionStore();
9013
8965
  const allResults = [];
8966
+ const routeWrapperPattern = routeWrapperPatternOf(patterns);
9014
8967
  for (const pattern of patterns) {
9015
8968
  const found = runPattern(
9016
8969
  sourceFile,
9017
8970
  pattern,
9018
8971
  store,
9019
8972
  mountPrefixes,
9020
- expandedElsewhere
8973
+ expandedElsewhere,
8974
+ routeWrapperPattern
9021
8975
  );
9022
8976
  for (const unit of found) {
9023
- unit.pattern = pattern;
8977
+ unit.pattern ??= pattern;
9024
8978
  }
9025
8979
  allResults.push(...found);
9026
8980
  }
@@ -9039,7 +8993,7 @@ function discoverUnits(sourceFile, patterns, resolution, mountPrefixes, expanded
9039
8993
  // src/resolve/functionBehind.ts
9040
8994
  function symbolBehind(node) {
9041
8995
  const parent = node.getParent();
9042
- if (parent !== void 0 && Node37.isShorthandPropertyAssignment(parent)) {
8996
+ if (parent !== void 0 && Node38.isShorthandPropertyAssignment(parent)) {
9043
8997
  return parent.getValueSymbol();
9044
8998
  }
9045
8999
  return node.getSymbol();
@@ -9069,9 +9023,9 @@ function resolveDecl(decl, calleeName) {
9069
9023
  }
9070
9024
  return { func: fn, name: declName(decl) ?? calleeName };
9071
9025
  }
9072
- if (Node37.isVariableDeclaration(decl)) {
9026
+ if (Node38.isVariableDeclaration(decl)) {
9073
9027
  const init = decl.getInitializer();
9074
- if (init !== void 0 && (Node37.isArrowFunction(init) || Node37.isFunctionExpression(init))) {
9028
+ if (init !== void 0 && (Node38.isArrowFunction(init) || Node38.isFunctionExpression(init))) {
9075
9029
  return { func: init, name: decl.getName() };
9076
9030
  }
9077
9031
  return null;
@@ -9079,20 +9033,20 @@ function resolveDecl(decl, calleeName) {
9079
9033
  return null;
9080
9034
  }
9081
9035
  function declName(decl) {
9082
- if (Node37.isFunctionDeclaration(decl) || Node37.isMethodDeclaration(decl)) {
9036
+ if (Node38.isFunctionDeclaration(decl) || Node38.isMethodDeclaration(decl)) {
9083
9037
  const n = decl.getName?.();
9084
9038
  if (typeof n === "string" && n.length > 0) {
9085
9039
  return n;
9086
9040
  }
9087
9041
  }
9088
- if (Node37.isFunctionExpression(decl)) {
9042
+ if (Node38.isFunctionExpression(decl)) {
9089
9043
  const n = decl.getName();
9090
9044
  if (typeof n === "string" && n.length > 0) {
9091
9045
  return n;
9092
9046
  }
9093
9047
  }
9094
9048
  const parent = decl.getParent();
9095
- if (parent !== void 0 && Node37.isVariableDeclaration(parent)) {
9049
+ if (parent !== void 0 && Node38.isVariableDeclaration(parent)) {
9096
9050
  return parent.getName();
9097
9051
  }
9098
9052
  return null;
@@ -9104,14 +9058,14 @@ function pathAbove(reference) {
9104
9058
  let current2 = reference;
9105
9059
  for (; ; ) {
9106
9060
  const parent = current2.getParent();
9107
- if (parent !== void 0 && Node38.isPropertyAccessExpression(parent) && parent.getExpression() === current2) {
9061
+ if (parent !== void 0 && Node39.isPropertyAccessExpression(parent) && parent.getExpression() === current2) {
9108
9062
  path15.push(parent.getName());
9109
9063
  current2 = parent;
9110
9064
  continue;
9111
9065
  }
9112
- if (parent !== void 0 && Node38.isElementAccessExpression(parent) && parent.getExpression() === current2) {
9066
+ if (parent !== void 0 && Node39.isElementAccessExpression(parent) && parent.getExpression() === current2) {
9113
9067
  const argument = parent.getArgumentExpression();
9114
- if (argument !== void 0 && Node38.isStringLiteral(argument)) {
9068
+ if (argument !== void 0 && Node39.isStringLiteral(argument)) {
9115
9069
  path15.push(argument.getLiteralValue());
9116
9070
  current2 = parent;
9117
9071
  continue;
@@ -9121,11 +9075,11 @@ function pathAbove(reference) {
9121
9075
  }
9122
9076
  }
9123
9077
  function declaresParameterOf(node, func) {
9124
- if (Node38.isParameterDeclaration(node)) {
9078
+ if (Node39.isParameterDeclaration(node)) {
9125
9079
  return node.getParent() === func;
9126
9080
  }
9127
- if (Node38.isBindingElement(node)) {
9128
- const parameter = node.getFirstAncestor(Node38.isParameterDeclaration);
9081
+ if (Node39.isBindingElement(node)) {
9082
+ const parameter = node.getFirstAncestor(Node39.isParameterDeclaration);
9129
9083
  return parameter !== void 0 && parameter.getParent() === func;
9130
9084
  }
9131
9085
  return false;
@@ -9141,7 +9095,7 @@ function parameterReads(func, parameterNames2, barriers = NO_BARRIERS) {
9141
9095
  traversal.skip();
9142
9096
  return;
9143
9097
  }
9144
- if (!Node38.isIdentifier(node) || !wanted.has(node.getText())) {
9098
+ if (!Node39.isIdentifier(node) || !wanted.has(node.getText())) {
9145
9099
  return;
9146
9100
  }
9147
9101
  const declarations = symbolBehind(node)?.getDeclarations() ?? [];
@@ -9164,7 +9118,7 @@ function parameterReads(func, parameterNames2, barriers = NO_BARRIERS) {
9164
9118
  }
9165
9119
 
9166
9120
  // src/resolve/readName.ts
9167
- import { Node as Node39, SyntaxKind as SyntaxKind9 } from "ts-morph";
9121
+ import { Node as Node40, SyntaxKind as SyntaxKind9 } from "ts-morph";
9168
9122
  import { patternHole, referenceName } from "@suss/behavioral-ir";
9169
9123
  var MAX_HELPER_HOPS = 2;
9170
9124
  var UNNAMED_HOLE = "param";
@@ -9199,11 +9153,11 @@ function referenceIn(expr) {
9199
9153
  function parameterPath(expr) {
9200
9154
  const fields = [];
9201
9155
  let step = expr;
9202
- while (Node39.isPropertyAccessExpression(step)) {
9156
+ while (Node40.isPropertyAccessExpression(step)) {
9203
9157
  fields.unshift(step.getName());
9204
9158
  step = step.getExpression();
9205
9159
  }
9206
- if (!Node39.isIdentifier(step) || !isParameter(step)) {
9160
+ if (!Node40.isIdentifier(step) || !isParameter(step)) {
9207
9161
  return null;
9208
9162
  }
9209
9163
  return { root: step.getText(), fields };
@@ -9211,7 +9165,7 @@ function parameterPath(expr) {
9211
9165
  function isParameter(identifier) {
9212
9166
  const declarations = identifier.getSymbol()?.getDeclarations() ?? [];
9213
9167
  return declarations.some(
9214
- (declaration) => Node39.isParameterDeclaration(declaration)
9168
+ (declaration) => Node40.isParameterDeclaration(declaration)
9215
9169
  );
9216
9170
  }
9217
9171
  function read(expr, ctx) {
@@ -9220,25 +9174,25 @@ function read(expr, ctx) {
9220
9174
  }
9221
9175
  const seen = new Set(ctx.seen).add(expr);
9222
9176
  const inner = { ...ctx, seen };
9223
- if (Node39.isStringLiteral(expr) || Node39.isNoSubstitutionTemplateLiteral(expr)) {
9177
+ if (Node40.isStringLiteral(expr) || Node40.isNoSubstitutionTemplateLiteral(expr)) {
9224
9178
  return expr.getLiteralValue();
9225
9179
  }
9226
- if (Node39.isNumericLiteral(expr)) {
9180
+ if (Node40.isNumericLiteral(expr)) {
9227
9181
  return expr.getLiteralText();
9228
9182
  }
9229
- if (Node39.isTemplateExpression(expr)) {
9183
+ if (Node40.isTemplateExpression(expr)) {
9230
9184
  return fromTemplate(expr, inner);
9231
9185
  }
9232
- if (Node39.isParenthesizedExpression(expr)) {
9186
+ if (Node40.isParenthesizedExpression(expr)) {
9233
9187
  return read(peelParens(expr), inner);
9234
9188
  }
9235
- if (Node39.isBinaryExpression(expr)) {
9189
+ if (Node40.isBinaryExpression(expr)) {
9236
9190
  return fromBinary(expr, inner);
9237
9191
  }
9238
- if (Node39.isCallExpression(expr)) {
9192
+ if (Node40.isCallExpression(expr)) {
9239
9193
  return fromCall(expr, inner);
9240
9194
  }
9241
- if (Node39.isIdentifier(expr)) {
9195
+ if (Node40.isIdentifier(expr)) {
9242
9196
  const only = boundOnce(expr, ctx);
9243
9197
  if (only !== null) {
9244
9198
  return read(only.node, { ...inner, bindings: only.scope });
@@ -9258,17 +9212,17 @@ function read(expr, ctx) {
9258
9212
  }
9259
9213
  function isFallbackBranch(node) {
9260
9214
  let step = node.getParent();
9261
- while (step !== void 0 && Node39.isParenthesizedExpression(step)) {
9215
+ while (step !== void 0 && Node40.isParenthesizedExpression(step)) {
9262
9216
  step = step.getParent();
9263
9217
  }
9264
- if (step === void 0 || !Node39.isBinaryExpression(step)) {
9218
+ if (step === void 0 || !Node40.isBinaryExpression(step)) {
9265
9219
  return false;
9266
9220
  }
9267
9221
  const operator = step.getOperatorToken().getKind();
9268
9222
  return operator === SyntaxKind9.BarBarToken || operator === SyntaxKind9.QuestionQuestionToken;
9269
9223
  }
9270
9224
  function fromTemplate(expr, ctx) {
9271
- if (!Node39.isTemplateExpression(expr)) {
9225
+ if (!Node40.isTemplateExpression(expr)) {
9272
9226
  return null;
9273
9227
  }
9274
9228
  let name = expr.getHead().getLiteralText();
@@ -9279,7 +9233,7 @@ function fromTemplate(expr, ctx) {
9279
9233
  return name;
9280
9234
  }
9281
9235
  function fromBinary(expr, ctx) {
9282
- if (!Node39.isBinaryExpression(expr)) {
9236
+ if (!Node40.isBinaryExpression(expr)) {
9283
9237
  return null;
9284
9238
  }
9285
9239
  const operator = expr.getOperatorToken().getKind();
@@ -9293,14 +9247,14 @@ function fromBinary(expr, ctx) {
9293
9247
  return readOrHole(expr.getLeft(), parts) + readOrHole(expr.getRight(), parts);
9294
9248
  }
9295
9249
  function fromCall(expr, ctx) {
9296
- if (!Node39.isCallExpression(expr)) {
9250
+ if (!Node40.isCallExpression(expr)) {
9297
9251
  return null;
9298
9252
  }
9299
9253
  const callee = expr.getExpression();
9300
- if (Node39.isPropertyAccessExpression(callee) && callee.getName() === "join") {
9254
+ if (Node40.isPropertyAccessExpression(callee) && callee.getName() === "join") {
9301
9255
  return fromJoin(callee.getExpression(), expr.getArguments(), ctx);
9302
9256
  }
9303
- if (Node39.isIdentifier(callee) && callee.getText() === "String") {
9257
+ if (Node40.isIdentifier(callee) && callee.getText() === "String") {
9304
9258
  const only = expr.getArguments()[0];
9305
9259
  return only === void 0 ? null : readOrHole(only, ctx);
9306
9260
  }
@@ -9319,7 +9273,7 @@ function fromCall(expr, ctx) {
9319
9273
  }
9320
9274
  function fromJoin(subject, args, ctx) {
9321
9275
  const separator = args[0];
9322
- if (separator === void 0 || !Node39.isStringLiteral(separator)) {
9276
+ if (separator === void 0 || !Node40.isStringLiteral(separator)) {
9323
9277
  return null;
9324
9278
  }
9325
9279
  const parts = elementsOf(subject, ctx);
@@ -9335,17 +9289,17 @@ function fromJoin(subject, args, ctx) {
9335
9289
  ).join(separator.getLiteralValue());
9336
9290
  }
9337
9291
  function elementsOf(subject, ctx) {
9338
- if (Node39.isArrayLiteralExpression(subject)) {
9292
+ if (Node40.isArrayLiteralExpression(subject)) {
9339
9293
  return subject.getElements().map((element) => here(element, ctx));
9340
9294
  }
9341
- if (Node39.isCallExpression(subject)) {
9295
+ if (Node40.isCallExpression(subject)) {
9342
9296
  const callee = subject.getExpression();
9343
- if (Node39.isPropertyAccessExpression(callee) && callee.getName() === "map") {
9297
+ if (Node40.isPropertyAccessExpression(callee) && callee.getName() === "map") {
9344
9298
  return elementsOf(callee.getExpression(), ctx);
9345
9299
  }
9346
9300
  return null;
9347
9301
  }
9348
- if (!Node39.isIdentifier(subject)) {
9302
+ if (!Node40.isIdentifier(subject)) {
9349
9303
  return null;
9350
9304
  }
9351
9305
  const bound = ctx.bindings.get(subject.getText());
@@ -9353,7 +9307,7 @@ function elementsOf(subject, ctx) {
9353
9307
  return null;
9354
9308
  }
9355
9309
  const only = bound.length === 1 ? bound[0] : void 0;
9356
- 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;
9357
9311
  }
9358
9312
  function singleReturnBody(callee, ctx) {
9359
9313
  const declaration = declarationOf2(callee, ctx);
@@ -9368,22 +9322,22 @@ function singleReturnBody(callee, ctx) {
9368
9322
  if (body === void 0) {
9369
9323
  return null;
9370
9324
  }
9371
- if (Node39.isExpression(body)) {
9325
+ if (Node40.isExpression(body)) {
9372
9326
  return { parameters, returned: body };
9373
9327
  }
9374
- if (!Node39.isBlock(body)) {
9328
+ if (!Node40.isBlock(body)) {
9375
9329
  return null;
9376
9330
  }
9377
9331
  const statements = body.getStatements();
9378
9332
  const only = statements[0];
9379
- if (statements.length !== 1 || only === void 0 || !Node39.isReturnStatement(only)) {
9333
+ if (statements.length !== 1 || only === void 0 || !Node40.isReturnStatement(only)) {
9380
9334
  return null;
9381
9335
  }
9382
9336
  const returned = only.getExpression();
9383
9337
  return returned === void 0 ? null : { parameters, returned };
9384
9338
  }
9385
9339
  function declarationOf2(callee, ctx) {
9386
- const symbol = Node39.isPropertyAccessExpression(callee) ? callee.getNameNode().getSymbol() : callee.getSymbol();
9340
+ const symbol = Node40.isPropertyAccessExpression(callee) ? callee.getNameNode().getSymbol() : callee.getSymbol();
9387
9341
  const declarations = symbol?.getAliasedSymbol()?.getDeclarations() ?? symbol?.getDeclarations() ?? [];
9388
9342
  for (const declaration of declarations) {
9389
9343
  const callable = asCallable(declaration);
@@ -9395,14 +9349,14 @@ function declarationOf2(callee, ctx) {
9395
9349
  return written === null || written === callee ? null : declarationOf2(written, { ...ctx, resolve: () => null });
9396
9350
  }
9397
9351
  function asCallable(declaration) {
9398
- 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)) {
9399
9353
  return declaration;
9400
9354
  }
9401
- if (!Node39.isVariableDeclaration(declaration)) {
9355
+ if (!Node40.isVariableDeclaration(declaration)) {
9402
9356
  return null;
9403
9357
  }
9404
9358
  const initializer = declaration.getInitializer();
9405
- if (initializer !== void 0 && (Node39.isArrowFunction(initializer) || Node39.isFunctionExpression(initializer))) {
9359
+ if (initializer !== void 0 && (Node40.isArrowFunction(initializer) || Node40.isFunctionExpression(initializer))) {
9406
9360
  return initializer;
9407
9361
  }
9408
9362
  return null;
@@ -9424,7 +9378,7 @@ function here(node, ctx) {
9424
9378
  return { node, scope: ctx.bindings };
9425
9379
  }
9426
9380
  function boundOnce(expr, ctx) {
9427
- 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;
9428
9382
  return bound !== void 0 && bound.length === 1 ? bound[0] : null;
9429
9383
  }
9430
9384
  function readOrHole(expr, ctx) {
@@ -9436,10 +9390,10 @@ function holeName(expr, ctx) {
9436
9390
  if (bound !== null) {
9437
9391
  return holeName(bound.node, { ...ctx, bindings: bound.scope });
9438
9392
  }
9439
- if (Node39.isIdentifier(expr)) {
9393
+ if (Node40.isIdentifier(expr)) {
9440
9394
  return expr.getText();
9441
9395
  }
9442
- if (Node39.isPropertyAccessExpression(expr)) {
9396
+ if (Node40.isPropertyAccessExpression(expr)) {
9443
9397
  return expr.getName();
9444
9398
  }
9445
9399
  return UNNAMED_HOLE;
@@ -9466,8 +9420,8 @@ function madeFromNamed(origin, made) {
9466
9420
  return origin.named.includes(constructorName(made));
9467
9421
  }
9468
9422
  function constructorName(made) {
9469
- const expression = Node40.isNewExpression(made) || Node40.isCallExpression(made) ? made.getExpression() : made;
9470
- 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();
9471
9425
  }
9472
9426
  var CALL_ORIGIN = {
9473
9427
  declaredBy: ORIGIN.declaredBy,
@@ -9481,7 +9435,7 @@ var CALL_ORIGIN = {
9481
9435
  };
9482
9436
  function madeBy(receiver) {
9483
9437
  const made = madeExpression(receiver);
9484
- const expression = Node40.isNewExpression(made) || Node40.isCallExpression(made) ? made.getExpression() : made;
9438
+ const expression = Node41.isNewExpression(made) || Node41.isCallExpression(made) ? made.getExpression() : made;
9485
9439
  return rootIdentifier(expression) ?? expression;
9486
9440
  }
9487
9441
  function madeExpression(receiver) {
@@ -9489,7 +9443,7 @@ function madeExpression(receiver) {
9489
9443
  return receiver.expression;
9490
9444
  }
9491
9445
  const written = receiver.resolve(receiver.callee.getExpression());
9492
- if (written === null || !Node40.isNewExpression(written) && !Node40.isCallExpression(written)) {
9446
+ if (written === null || !Node41.isNewExpression(written) && !Node41.isCallExpression(written)) {
9493
9447
  return receiver.callee;
9494
9448
  }
9495
9449
  return written;
@@ -9497,7 +9451,7 @@ function madeExpression(receiver) {
9497
9451
  function callOpsFor(call, resolveWrittenValue, originatesFrom, anchorCallsOf) {
9498
9452
  const resolve2 = resolveWrittenValue ?? (() => null);
9499
9453
  const expression = calleeOf3(call);
9500
- const callee = Node40.isPropertyAccessExpression(expression) ? expression : null;
9454
+ const callee = Node41.isPropertyAccessExpression(expression) ? expression : null;
9501
9455
  let args = null;
9502
9456
  const argumentsOf = () => {
9503
9457
  args ??= argumentsIn(call);
@@ -9520,7 +9474,7 @@ function callOpsFor(call, resolveWrittenValue, originatesFrom, anchorCallsOf) {
9520
9474
  argumentCount: () => argumentsOf().length,
9521
9475
  nameAt: (index, unsettled) => nameAt(argumentsOf()[index], unsettled, resolve2),
9522
9476
  calleeText: () => expression.getText(),
9523
- namedCallee: () => Node40.isIdentifier(expression),
9477
+ namedCallee: () => Node41.isIdentifier(expression),
9524
9478
  parameterReadsAt: (index) => selectorReadsOf(argumentsOf()[index]),
9525
9479
  receiver: () => callee === null ? null : opsOverCall(callee.getExpression(), resolve2),
9526
9480
  argument: (index) => opsOverCall(argumentsOf()[index], resolve2),
@@ -9545,7 +9499,7 @@ function anchorCallBehind(subject, origin, resolve2, originatesFrom, anchorCalls
9545
9499
  return null;
9546
9500
  }
9547
9501
  const found = anchorCallsOf(subject, (candidate) => {
9548
- if (!Node40.isCallExpression(candidate) && !Node40.isNewExpression(candidate)) {
9502
+ if (!Node41.isCallExpression(candidate) && !Node41.isNewExpression(candidate)) {
9549
9503
  return false;
9550
9504
  }
9551
9505
  const candidateCallee = calleeOf3(candidate);
@@ -9560,7 +9514,7 @@ function anchorCallBehind(subject, origin, resolve2, originatesFrom, anchorCalls
9560
9514
  if (distinct.length !== 1 || only === void 0) {
9561
9515
  return null;
9562
9516
  }
9563
- if (!Node40.isCallExpression(only) && !Node40.isNewExpression(only)) {
9517
+ if (!Node41.isCallExpression(only) && !Node41.isNewExpression(only)) {
9564
9518
  return null;
9565
9519
  }
9566
9520
  return callOpsFor(only, resolve2, originatesFrom, anchorCallsOf);
@@ -9580,7 +9534,7 @@ function valueOpsFor(value, resolve2) {
9580
9534
  asArg: () => effectArgOf(written()),
9581
9535
  property: (name) => {
9582
9536
  const object = written();
9583
- const inside = Node40.isObjectLiteralExpression(object) ? initializerOf(object, name) : null;
9537
+ const inside = Node41.isObjectLiteralExpression(object) ? initializerOf(object, name) : null;
9584
9538
  return inside === null ? null : valueOpsFor(inside, resolve2);
9585
9539
  },
9586
9540
  parts: () => literalParts(written()),
@@ -9593,7 +9547,7 @@ function literalParts(value) {
9593
9547
  if (whole !== null) {
9594
9548
  return [whole];
9595
9549
  }
9596
- if (!Node40.isTemplateExpression(written)) {
9550
+ if (!Node41.isTemplateExpression(written)) {
9597
9551
  return null;
9598
9552
  }
9599
9553
  return [
@@ -9603,26 +9557,26 @@ function literalParts(value) {
9603
9557
  }
9604
9558
  function templateHoles(value, resolve2) {
9605
9559
  const written = untagged(value);
9606
- if (!Node40.isTemplateExpression(written)) {
9560
+ if (!Node41.isTemplateExpression(written)) {
9607
9561
  return [];
9608
9562
  }
9609
9563
  return written.getTemplateSpans().map((span) => opsOverCall(span.getExpression(), resolve2));
9610
9564
  }
9611
9565
  function untagged(value) {
9612
- return Node40.isTaggedTemplateExpression(value) ? value.getTemplate() : value;
9566
+ return Node41.isTaggedTemplateExpression(value) ? value.getTemplate() : value;
9613
9567
  }
9614
9568
  function entriesOf(value, unsettled, resolve2) {
9615
- if (!Node40.isObjectLiteralExpression(value)) {
9569
+ if (!Node41.isObjectLiteralExpression(value)) {
9616
9570
  return [];
9617
9571
  }
9618
9572
  const found = [];
9619
9573
  for (const written of value.getProperties()) {
9620
- if (Node40.isShorthandPropertyAssignment(written)) {
9574
+ if (Node41.isShorthandPropertyAssignment(written)) {
9621
9575
  const name = written.getNameNode();
9622
9576
  found.push({ key: name.getText(), value: valueOpsFor(name, resolve2) });
9623
9577
  continue;
9624
9578
  }
9625
- if (!Node40.isPropertyAssignment(written)) {
9579
+ if (!Node41.isPropertyAssignment(written)) {
9626
9580
  continue;
9627
9581
  }
9628
9582
  const stated = written.getInitializer();
@@ -9635,35 +9589,35 @@ function entriesOf(value, unsettled, resolve2) {
9635
9589
  }
9636
9590
  function entryKey(written, unsettled, resolve2) {
9637
9591
  const name = written.getNameNode();
9638
- if (Node40.isComputedPropertyName(name)) {
9592
+ if (Node41.isComputedPropertyName(name)) {
9639
9593
  return readName(name.getExpression(), { resolve: resolve2, unsettled });
9640
9594
  }
9641
9595
  return unquoted(written.getName());
9642
9596
  }
9643
9597
  function itemsOf(value, resolve2) {
9644
- if (!Node40.isArrayLiteralExpression(value)) {
9598
+ if (!Node41.isArrayLiteralExpression(value)) {
9645
9599
  return [];
9646
9600
  }
9647
9601
  return value.getElements().map((element) => valueOpsFor(element, resolve2));
9648
9602
  }
9649
9603
  function literalText(value) {
9650
- return Node40.isStringLiteral(value) || Node40.isNoSubstitutionTemplateLiteral(value) ? value.getLiteralValue() : null;
9604
+ return Node41.isStringLiteral(value) || Node41.isNoSubstitutionTemplateLiteral(value) ? value.getLiteralValue() : null;
9651
9605
  }
9652
9606
  function literalFlag(value) {
9653
- if (Node40.isTrueLiteral(value) || Node40.isFalseLiteral(value)) {
9654
- return Node40.isTrueLiteral(value);
9607
+ if (Node41.isTrueLiteral(value) || Node41.isFalseLiteral(value)) {
9608
+ return Node41.isTrueLiteral(value);
9655
9609
  }
9656
- return Node40.isNumericLiteral(value) ? value.getLiteralValue() !== 0 : null;
9610
+ return Node41.isNumericLiteral(value) ? value.getLiteralValue() !== 0 : null;
9657
9611
  }
9658
9612
  function unquoted(name) {
9659
9613
  return name.replace(/^["']|["']$/g, "");
9660
9614
  }
9661
9615
  function selectorReadsOf(argument) {
9662
- if (argument === void 0 || !Node40.isArrowFunction(argument) && !Node40.isFunctionExpression(argument)) {
9616
+ if (argument === void 0 || !Node41.isArrowFunction(argument) && !Node41.isFunctionExpression(argument)) {
9663
9617
  return null;
9664
9618
  }
9665
9619
  const parameter = argument.getParameters()[0];
9666
- if (parameter === void 0 || !Node40.isIdentifier(parameter.getNameNode())) {
9620
+ if (parameter === void 0 || !Node41.isIdentifier(parameter.getNameNode())) {
9667
9621
  return null;
9668
9622
  }
9669
9623
  const names = /* @__PURE__ */ new Set();
@@ -9680,17 +9634,17 @@ function opsOverCall(value, resolve2) {
9680
9634
  return callOpsFor(written, resolve2);
9681
9635
  }
9682
9636
  function isCalled(value) {
9683
- return Node40.isCallExpression(value) || Node40.isNewExpression(value) || Node40.isTaggedTemplateExpression(value);
9637
+ return Node41.isCallExpression(value) || Node41.isNewExpression(value) || Node41.isTaggedTemplateExpression(value);
9684
9638
  }
9685
9639
  function calleeOf3(call) {
9686
- return Node40.isTaggedTemplateExpression(call) ? call.getTag() : call.getExpression();
9640
+ return Node41.isTaggedTemplateExpression(call) ? call.getTag() : call.getExpression();
9687
9641
  }
9688
9642
  function argumentsIn(call) {
9689
- return Node40.isTaggedTemplateExpression(call) ? [call.getTemplate()] : call.getArguments();
9643
+ return Node41.isTaggedTemplateExpression(call) ? [call.getTemplate()] : call.getArguments();
9690
9644
  }
9691
9645
  function settled(value, resolve2) {
9692
9646
  const step = unwrapped(value ?? null);
9693
- if (step === null || !Node40.isIdentifier(step)) {
9647
+ if (step === null || !Node41.isIdentifier(step)) {
9694
9648
  return step;
9695
9649
  }
9696
9650
  return unwrapped(resolve2(step));
@@ -9717,11 +9671,11 @@ function objectAt(argument, resolve2) {
9717
9671
  if (isCalled(written)) {
9718
9672
  return objectAt(argumentsIn(written)[0], resolve2);
9719
9673
  }
9720
- return Node40.isObjectLiteralExpression(written) ? written : null;
9674
+ return Node41.isObjectLiteralExpression(written) ? written : null;
9721
9675
  }
9722
9676
  function initializerOf(object, property) {
9723
9677
  for (const written of object.getProperties()) {
9724
- if (Node40.isPropertyAssignment(written) && written.getName() === property) {
9678
+ if (Node41.isPropertyAssignment(written) && written.getName() === property) {
9725
9679
  return written.getInitializer() ?? null;
9726
9680
  }
9727
9681
  }
@@ -9751,7 +9705,7 @@ function invocationContextFor(call, resolveWrittenValue, originatesFrom, anchorC
9751
9705
  };
9752
9706
  }
9753
9707
  function isImportedFrom(identifier, expectedModule, originatesFrom) {
9754
- if (!Node41.isIdentifier(identifier)) {
9708
+ if (!Node42.isIdentifier(identifier)) {
9755
9709
  return false;
9756
9710
  }
9757
9711
  const symbol = identifier.getSymbol();
@@ -9772,7 +9726,7 @@ function isImportedFrom(identifier, expectedModule, originatesFrom) {
9772
9726
  );
9773
9727
  }
9774
9728
  function methodDeclaredIn(callee, expectedModule, resolve2, originatesFrom) {
9775
- if (!Node41.isPropertyAccessExpression(callee)) {
9729
+ if (!Node42.isPropertyAccessExpression(callee)) {
9776
9730
  return false;
9777
9731
  }
9778
9732
  const declarations = callee.getNameNode().getSymbol()?.getDeclarations();
@@ -9792,37 +9746,37 @@ function maker(written) {
9792
9746
  if (written === null) {
9793
9747
  return null;
9794
9748
  }
9795
- if (Node41.isNewExpression(written) || Node41.isCallExpression(written)) {
9749
+ if (Node42.isNewExpression(written) || Node42.isCallExpression(written)) {
9796
9750
  return written.getExpression();
9797
9751
  }
9798
9752
  return null;
9799
9753
  }
9800
9754
  function rootIdentifier2(expression) {
9801
9755
  let root = expression;
9802
- while (Node41.isPropertyAccessExpression(root)) {
9756
+ while (Node42.isPropertyAccessExpression(root)) {
9803
9757
  root = root.getExpression();
9804
9758
  }
9805
9759
  return root;
9806
9760
  }
9807
9761
  function importSpecifierMatches(decl, expectedModule) {
9808
- if (Node41.isImportSpecifier(decl)) {
9762
+ if (Node42.isImportSpecifier(decl)) {
9809
9763
  return decl.getImportDeclaration().getModuleSpecifierValue() === expectedModule;
9810
9764
  }
9811
- const owner = Node41.isNamespaceImport(decl) ? decl.getParent() : decl;
9812
- if (!Node41.isImportClause(owner)) {
9765
+ const owner = Node42.isNamespaceImport(decl) ? decl.getParent() : decl;
9766
+ if (!Node42.isImportClause(owner)) {
9813
9767
  return false;
9814
9768
  }
9815
9769
  const importDecl = owner.getParent();
9816
- return Node41.isImportDeclaration(importDecl) && importDecl.getModuleSpecifierValue() === expectedModule;
9770
+ return Node42.isImportDeclaration(importDecl) && importDecl.getModuleSpecifierValue() === expectedModule;
9817
9771
  }
9818
9772
  function extractInvocationEffects(func, barriers = NO_BARRIERS) {
9819
9773
  const calls = [];
9820
9774
  func.forEachDescendant((node, traversal) => {
9821
- if (isDescentStop(node, func, barriers) || Node41.isDecorator(node)) {
9775
+ if (isDescentStop(node, func, barriers) || Node42.isDecorator(node)) {
9822
9776
  traversal.skip();
9823
9777
  return;
9824
9778
  }
9825
- if (Node41.isCallExpression(node)) {
9779
+ if (Node42.isCallExpression(node)) {
9826
9780
  calls.push(node);
9827
9781
  }
9828
9782
  });
@@ -9846,10 +9800,10 @@ function invocationAt(call, func) {
9846
9800
  }
9847
9801
  function isAwaited(call) {
9848
9802
  let current2 = call.getParent();
9849
- while (current2 !== void 0 && Node41.isParenthesizedExpression(current2)) {
9803
+ while (current2 !== void 0 && Node42.isParenthesizedExpression(current2)) {
9850
9804
  current2 = current2.getParent();
9851
9805
  }
9852
- return current2 !== void 0 && Node41.isAwaitExpression(current2);
9806
+ return current2 !== void 0 && Node42.isAwaitExpression(current2);
9853
9807
  }
9854
9808
  function runInvocationRecognizers(func, recognizers, barriers = NO_BARRIERS, resolveWrittenValue, originatesFrom, anchorCallsOf) {
9855
9809
  if (recognizers.length === 0) {
@@ -9862,7 +9816,7 @@ function runInvocationRecognizers(func, recognizers, barriers = NO_BARRIERS, res
9862
9816
  traversal.skip();
9863
9817
  return;
9864
9818
  }
9865
- if (!Node41.isCallExpression(node)) {
9819
+ if (!Node42.isCallExpression(node)) {
9866
9820
  return;
9867
9821
  }
9868
9822
  const ctx = invocationContextFor(
@@ -9924,7 +9878,7 @@ function runAccessRecognizersAtModuleScope(sourceFile, recognizers, resolveWritt
9924
9878
  }
9925
9879
  function accessContextFor(node, sourceFile, resolveWrittenValue = () => null, originatesFrom, anchorCallsOf) {
9926
9880
  const given = { access: node, sourceFile, resolveWrittenValue };
9927
- if (Node41.isPropertyAccessExpression(node)) {
9881
+ if (Node42.isPropertyAccessExpression(node)) {
9928
9882
  return given;
9929
9883
  }
9930
9884
  let ops;
@@ -9953,7 +9907,7 @@ function dispatchAccessRecognizers(root, recognizers, isStop, resolveWrittenValu
9953
9907
  traversal.skip();
9954
9908
  return;
9955
9909
  }
9956
- if (!Node41.isPropertyAccessExpression(node) && !Node41.isCallExpression(node) && !Node41.isTaggedTemplateExpression(node)) {
9910
+ if (!Node42.isPropertyAccessExpression(node) && !Node42.isCallExpression(node) && !Node42.isTaggedTemplateExpression(node)) {
9957
9911
  return;
9958
9912
  }
9959
9913
  const ctx = accessContextFor(
@@ -10009,35 +9963,35 @@ function extractArg(node, depth) {
10009
9963
  return extractArg(bare, depth);
10010
9964
  }
10011
9965
  }
10012
- if (Node41.isStringLiteral(node) || Node41.isNoSubstitutionTemplateLiteral(node)) {
9966
+ if (Node42.isStringLiteral(node) || Node42.isNoSubstitutionTemplateLiteral(node)) {
10013
9967
  return { kind: "string", value: node.getLiteralValue() };
10014
9968
  }
10015
- if (Node41.isNumericLiteral(node)) {
9969
+ if (Node42.isNumericLiteral(node)) {
10016
9970
  return { kind: "number", value: node.getLiteralValue() };
10017
9971
  }
10018
- if (Node41.isTrueLiteral(node)) {
9972
+ if (Node42.isTrueLiteral(node)) {
10019
9973
  return { kind: "boolean", value: true };
10020
9974
  }
10021
- if (Node41.isFalseLiteral(node)) {
9975
+ if (Node42.isFalseLiteral(node)) {
10022
9976
  return { kind: "boolean", value: false };
10023
9977
  }
10024
- if (Node41.isTemplateExpression(node)) {
9978
+ if (Node42.isTemplateExpression(node)) {
10025
9979
  return { kind: "template", sourceText: node.getText() };
10026
9980
  }
10027
- if (Node41.isIdentifier(node)) {
9981
+ if (Node42.isIdentifier(node)) {
10028
9982
  const inlined = inlineModuleBinding(node, depth);
10029
9983
  if (inlined !== null) {
10030
9984
  return inlined;
10031
9985
  }
10032
9986
  return { kind: "identifier", name: node.getText() };
10033
9987
  }
10034
- if (Node41.isPropertyAccessExpression(node) || Node41.isElementAccessExpression(node)) {
9988
+ if (Node42.isPropertyAccessExpression(node) || Node42.isElementAccessExpression(node)) {
10035
9989
  return { kind: "identifier", name: node.getText() };
10036
9990
  }
10037
9991
  if (depth <= 0) {
10038
9992
  return null;
10039
9993
  }
10040
- if (Node41.isCallExpression(node)) {
9994
+ if (Node42.isCallExpression(node)) {
10041
9995
  const element = mapCallbackReturn(node);
10042
9996
  if (element !== null) {
10043
9997
  return { kind: "array", items: [extractArg(element, depth - 1)] };
@@ -10048,19 +10002,19 @@ function extractArg(node, depth) {
10048
10002
  args: node.getArguments().map((a) => extractArg(a, depth - 1))
10049
10003
  };
10050
10004
  }
10051
- if (Node41.isNewExpression(node)) {
10005
+ if (Node42.isNewExpression(node)) {
10052
10006
  return {
10053
10007
  kind: "call",
10054
10008
  callee: node.getExpression().getText(),
10055
10009
  args: node.getArguments().map((a) => extractArg(a, depth - 1))
10056
10010
  };
10057
10011
  }
10058
- if (Node41.isObjectLiteralExpression(node)) {
10012
+ if (Node42.isObjectLiteralExpression(node)) {
10059
10013
  const fields = {};
10060
10014
  for (const prop of node.getProperties()) {
10061
- if (Node41.isShorthandPropertyAssignment(prop)) {
10015
+ if (Node42.isShorthandPropertyAssignment(prop)) {
10062
10016
  const nameNode2 = prop.getNameNode();
10063
- if (Node41.isIdentifier(nameNode2)) {
10017
+ if (Node42.isIdentifier(nameNode2)) {
10064
10018
  fields[nameNode2.getText()] = {
10065
10019
  kind: "identifier",
10066
10020
  name: nameNode2.getText()
@@ -10068,14 +10022,14 @@ function extractArg(node, depth) {
10068
10022
  }
10069
10023
  continue;
10070
10024
  }
10071
- if (!Node41.isPropertyAssignment(prop)) {
10025
+ if (!Node42.isPropertyAssignment(prop)) {
10072
10026
  continue;
10073
10027
  }
10074
10028
  const nameNode = prop.getNameNode();
10075
- if (!Node41.isIdentifier(nameNode) && !Node41.isStringLiteral(nameNode) && !Node41.isNoSubstitutionTemplateLiteral(nameNode)) {
10029
+ if (!Node42.isIdentifier(nameNode) && !Node42.isStringLiteral(nameNode) && !Node42.isNoSubstitutionTemplateLiteral(nameNode)) {
10076
10030
  continue;
10077
10031
  }
10078
- const name = Node41.isIdentifier(nameNode) ? nameNode.getText() : nameNode.getLiteralValue();
10032
+ const name = Node42.isIdentifier(nameNode) ? nameNode.getText() : nameNode.getLiteralValue();
10079
10033
  const initializer = prop.getInitializer();
10080
10034
  if (initializer === void 0) {
10081
10035
  continue;
@@ -10084,7 +10038,7 @@ function extractArg(node, depth) {
10084
10038
  }
10085
10039
  return { kind: "object", fields };
10086
10040
  }
10087
- if (Node41.isArrayLiteralExpression(node)) {
10041
+ if (Node42.isArrayLiteralExpression(node)) {
10088
10042
  const items = node.getElements().map((el) => extractArg(el, depth - 1));
10089
10043
  return { kind: "array", items };
10090
10044
  }
@@ -10092,20 +10046,20 @@ function extractArg(node, depth) {
10092
10046
  }
10093
10047
  function mapCallbackReturn(call) {
10094
10048
  const callee = call.getExpression();
10095
- if (!Node41.isPropertyAccessExpression(callee) || callee.getName() !== "map") {
10049
+ if (!Node42.isPropertyAccessExpression(callee) || callee.getName() !== "map") {
10096
10050
  return null;
10097
10051
  }
10098
10052
  const callback = call.getArguments()[0];
10099
- if (callback === void 0 || !(Node41.isArrowFunction(callback) || Node41.isFunctionExpression(callback))) {
10053
+ if (callback === void 0 || !(Node42.isArrowFunction(callback) || Node42.isFunctionExpression(callback))) {
10100
10054
  return null;
10101
10055
  }
10102
10056
  const body = callback.getBody();
10103
- if (!Node41.isBlock(body)) {
10057
+ if (!Node42.isBlock(body)) {
10104
10058
  return body;
10105
10059
  }
10106
10060
  const statements = body.getStatements();
10107
10061
  const only = statements.length === 1 ? statements[0] : void 0;
10108
- return only !== void 0 && Node41.isReturnStatement(only) ? only.getExpression() ?? null : null;
10062
+ return only !== void 0 && Node42.isReturnStatement(only) ? only.getExpression() ?? null : null;
10109
10063
  }
10110
10064
  function collectPreconditions(node, root) {
10111
10065
  return collectAncestorConditionInfosBelow(node, root).map(
@@ -10116,7 +10070,7 @@ function runsOnEveryPath(node, root) {
10116
10070
  let current2 = node;
10117
10071
  while (current2 !== void 0 && current2 !== root) {
10118
10072
  const parent = current2.getParent();
10119
- if (parent !== void 0 && Node41.isTryStatement(parent) && parent.getFinallyBlock() === current2) {
10073
+ if (parent !== void 0 && Node42.isTryStatement(parent) && parent.getFinallyBlock() === current2) {
10120
10074
  return true;
10121
10075
  }
10122
10076
  current2 = parent;
@@ -10139,7 +10093,7 @@ function withPreconditions(effect, preconditions) {
10139
10093
  };
10140
10094
  }
10141
10095
  function inlineModuleBinding(ident, depth) {
10142
- if (!Node41.isIdentifier(ident)) {
10096
+ if (!Node42.isIdentifier(ident)) {
10143
10097
  return null;
10144
10098
  }
10145
10099
  const symbol = ident.getSymbol();
@@ -10147,7 +10101,7 @@ function inlineModuleBinding(ident, depth) {
10147
10101
  return null;
10148
10102
  }
10149
10103
  for (const decl of symbol.getDeclarations()) {
10150
- if (!Node41.isVariableDeclaration(decl)) {
10104
+ if (!Node42.isVariableDeclaration(decl)) {
10151
10105
  continue;
10152
10106
  }
10153
10107
  if (!isModuleScoped(decl)) {
@@ -10168,10 +10122,10 @@ function inlineModuleBinding(ident, depth) {
10168
10122
  function isModuleScoped(decl) {
10169
10123
  let current2 = decl.getParent();
10170
10124
  while (current2 !== void 0) {
10171
- if (Node41.isSourceFile(current2)) {
10125
+ if (Node42.isSourceFile(current2)) {
10172
10126
  return true;
10173
10127
  }
10174
- if (Node41.isVariableDeclarationList(current2) || Node41.isVariableStatement(current2)) {
10128
+ if (Node42.isVariableDeclarationList(current2) || Node42.isVariableStatement(current2)) {
10175
10129
  current2 = current2.getParent();
10176
10130
  continue;
10177
10131
  }
@@ -10185,7 +10139,7 @@ function unwrapCasts(node) {
10185
10139
  function enclosingStatementLine(node) {
10186
10140
  let current2 = node;
10187
10141
  while (current2 !== void 0) {
10188
- if (Node41.isStatement(current2)) {
10142
+ if (Node42.isStatement(current2)) {
10189
10143
  return startLineOf(current2);
10190
10144
  }
10191
10145
  current2 = current2.getParent();
@@ -10194,19 +10148,19 @@ function enclosingStatementLine(node) {
10194
10148
  }
10195
10149
 
10196
10150
  // src/terminals/index.ts
10197
- import { Node as Node51 } from "ts-morph";
10151
+ import { Node as Node52 } from "ts-morph";
10198
10152
 
10199
10153
  // src/terminals/continuation.ts
10200
- import { Node as Node43 } from "ts-morph";
10154
+ import { Node as Node44 } from "ts-morph";
10201
10155
 
10202
10156
  // src/terminals/shared.ts
10203
- import { Node as Node42 } from "ts-morph";
10157
+ import { Node as Node43 } from "ts-morph";
10204
10158
  function parameterPositionOf(identifier, func) {
10205
- if (!Node42.isIdentifier(identifier)) {
10159
+ if (!Node43.isIdentifier(identifier)) {
10206
10160
  return null;
10207
10161
  }
10208
10162
  const declaration = identifier.getSymbol()?.getDeclarations()[0];
10209
- if (declaration === void 0 || !Node42.isParameterDeclaration(declaration)) {
10163
+ if (declaration === void 0 || !Node43.isParameterDeclaration(declaration)) {
10210
10164
  return null;
10211
10165
  }
10212
10166
  const params = func.getParameters();
@@ -10223,17 +10177,17 @@ function returnPositionOf(value) {
10223
10177
  if (parent === void 0) {
10224
10178
  return null;
10225
10179
  }
10226
- if (Node42.isReturnStatement(parent)) {
10180
+ if (Node43.isReturnStatement(parent)) {
10227
10181
  return parent;
10228
10182
  }
10229
- if (Node42.isArrowFunction(parent)) {
10183
+ if (Node43.isArrowFunction(parent)) {
10230
10184
  return parent.getBody() === current2 ? current2 : null;
10231
10185
  }
10232
10186
  if (passesValueThrough(parent)) {
10233
10187
  current2 = parent;
10234
10188
  continue;
10235
10189
  }
10236
- if (Node42.isConditionalExpression(parent) && (parent.getWhenTrue() === current2 || parent.getWhenFalse() === current2)) {
10190
+ if (Node43.isConditionalExpression(parent) && (parent.getWhenTrue() === current2 || parent.getWhenFalse() === current2)) {
10237
10191
  current2 = parent;
10238
10192
  continue;
10239
10193
  }
@@ -10243,7 +10197,7 @@ function returnPositionOf(value) {
10243
10197
 
10244
10198
  // src/terminals/continuation.ts
10245
10199
  function tryMatchParameterCall(node, func, pattern, match) {
10246
- if (!Node43.isCallExpression(node)) {
10200
+ if (!Node44.isCallExpression(node)) {
10247
10201
  return null;
10248
10202
  }
10249
10203
  const callee = node.getExpression();
@@ -10267,13 +10221,13 @@ function tryMatchParameterCall(node, func, pattern, match) {
10267
10221
 
10268
10222
  // src/terminals/extract.ts
10269
10223
  import {
10270
- Node as Node45
10224
+ Node as Node46
10271
10225
  } from "ts-morph";
10272
10226
  import { constantOf } from "@suss/values";
10273
10227
 
10274
10228
  // src/shapes/shapes.ts
10275
10229
  import {
10276
- Node as Node44,
10230
+ Node as Node45,
10277
10231
  SyntaxKind as SyntaxKind10
10278
10232
  } from "ts-morph";
10279
10233
 
@@ -10740,35 +10694,35 @@ function extractShapeWithArguments(node, substitutions) {
10740
10694
  }
10741
10695
  function extractShapeInner(node) {
10742
10696
  const unwrapped2 = peelSyntax(node);
10743
- if (boundArguments !== null && Node44.isIdentifier(unwrapped2)) {
10697
+ if (boundArguments !== null && Node45.isIdentifier(unwrapped2)) {
10744
10698
  const argument = boundArguments.get(unwrapped2.getText());
10745
10699
  if (argument !== void 0 && argument !== unwrapped2) {
10746
10700
  return extractShape(argument);
10747
10701
  }
10748
10702
  }
10749
- if (Node44.isObjectLiteralExpression(unwrapped2)) {
10703
+ if (Node45.isObjectLiteralExpression(unwrapped2)) {
10750
10704
  return shapeFromObjectLiteral(unwrapped2);
10751
10705
  }
10752
- if (Node44.isArrayLiteralExpression(unwrapped2)) {
10706
+ if (Node45.isArrayLiteralExpression(unwrapped2)) {
10753
10707
  return shapeFromArrayLiteral(unwrapped2);
10754
10708
  }
10755
- if (Node44.isStringLiteral(unwrapped2) || Node44.isNoSubstitutionTemplateLiteral(unwrapped2)) {
10709
+ if (Node45.isStringLiteral(unwrapped2) || Node45.isNoSubstitutionTemplateLiteral(unwrapped2)) {
10756
10710
  return { type: "literal", value: unwrapped2.getLiteralValue() };
10757
10711
  }
10758
- if (Node44.isTemplateExpression(unwrapped2)) {
10712
+ if (Node45.isTemplateExpression(unwrapped2)) {
10759
10713
  return { type: "text" };
10760
10714
  }
10761
- if (Node44.isNumericLiteral(unwrapped2)) {
10715
+ if (Node45.isNumericLiteral(unwrapped2)) {
10762
10716
  return numericLiteralShape(
10763
10717
  unwrapped2.getLiteralValue(),
10764
10718
  unwrapped2.getText()
10765
10719
  );
10766
10720
  }
10767
- if (Node44.isPrefixUnaryExpression(unwrapped2)) {
10721
+ if (Node45.isPrefixUnaryExpression(unwrapped2)) {
10768
10722
  const op = unwrapped2.getOperatorToken();
10769
10723
  if (op === SyntaxKind10.MinusToken || op === SyntaxKind10.PlusToken) {
10770
10724
  const inner = unwrapped2.getOperand();
10771
- if (Node44.isNumericLiteral(inner)) {
10725
+ if (Node45.isNumericLiteral(inner)) {
10772
10726
  const v3 = inner.getLiteralValue();
10773
10727
  const signed = op === SyntaxKind10.MinusToken ? -v3 : v3;
10774
10728
  const rawBody = inner.getText();
@@ -10777,7 +10731,7 @@ function extractShapeInner(node) {
10777
10731
  }
10778
10732
  }
10779
10733
  }
10780
- if (Node44.isBigIntLiteral(unwrapped2)) {
10734
+ if (Node45.isBigIntLiteral(unwrapped2)) {
10781
10735
  return { type: "ref", name: "bigint" };
10782
10736
  }
10783
10737
  const kind = unwrapped2.getKind();
@@ -10790,10 +10744,10 @@ function extractShapeInner(node) {
10790
10744
  if (kind === SyntaxKind10.NullKeyword) {
10791
10745
  return { type: "null" };
10792
10746
  }
10793
- if (Node44.isIdentifier(unwrapped2) && unwrapped2.getText() === "undefined") {
10747
+ if (Node45.isIdentifier(unwrapped2) && unwrapped2.getText() === "undefined") {
10794
10748
  return { type: "undefined" };
10795
10749
  }
10796
- if (Node44.isConditionalExpression(unwrapped2)) {
10750
+ if (Node45.isConditionalExpression(unwrapped2)) {
10797
10751
  const whenTrue = extractShape(unwrapped2.getWhenTrue());
10798
10752
  const whenFalse = extractShape(unwrapped2.getWhenFalse());
10799
10753
  const variants = [];
@@ -10824,7 +10778,7 @@ function shapeFromArrayLiteral(arr) {
10824
10778
  }
10825
10779
  const shapes = [];
10826
10780
  for (const el of elements) {
10827
- if (Node44.isSpreadElement(el)) {
10781
+ if (Node45.isSpreadElement(el)) {
10828
10782
  const inner = el.getExpression();
10829
10783
  const innerShape = extractShape(inner);
10830
10784
  if (innerShape?.type === "array") {
@@ -10843,7 +10797,7 @@ function shapeFromObjectLiteral(obj) {
10843
10797
  const properties = {};
10844
10798
  const unresolvedSpreads = [];
10845
10799
  for (const prop of obj.getProperties()) {
10846
- if (Node44.isPropertyAssignment(prop)) {
10800
+ if (Node45.isPropertyAssignment(prop)) {
10847
10801
  const name = propertyName2(prop);
10848
10802
  if (name === null) {
10849
10803
  continue;
@@ -10859,7 +10813,7 @@ function shapeFromObjectLiteral(obj) {
10859
10813
  };
10860
10814
  continue;
10861
10815
  }
10862
- if (Node44.isShorthandPropertyAssignment(prop)) {
10816
+ if (Node45.isShorthandPropertyAssignment(prop)) {
10863
10817
  const name = prop.getName();
10864
10818
  const valueExpr = prop.getNameNode();
10865
10819
  properties[name] = extractShape(valueExpr) ?? {
@@ -10868,7 +10822,7 @@ function shapeFromObjectLiteral(obj) {
10868
10822
  };
10869
10823
  continue;
10870
10824
  }
10871
- if (Node44.isSpreadAssignment(prop)) {
10825
+ if (Node45.isSpreadAssignment(prop)) {
10872
10826
  const expr = prop.getExpression();
10873
10827
  const spreadShape = extractShape(expr);
10874
10828
  if (spreadShape?.type === "record") {
@@ -10887,7 +10841,7 @@ function shapeFromObjectLiteral(obj) {
10887
10841
  }
10888
10842
  function propertyName2(prop) {
10889
10843
  const nameNode = prop.getNameNode();
10890
- 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)) {
10891
10845
  return nameNode.getText().replace(/^["']|["']$/g, "");
10892
10846
  }
10893
10847
  return null;
@@ -10918,15 +10872,15 @@ function unwrapAs(node) {
10918
10872
  }
10919
10873
  function unwrapJsonStringify(node) {
10920
10874
  const outer = unwrapAs(node);
10921
- if (!Node45.isCallExpression(outer)) {
10875
+ if (!Node46.isCallExpression(outer)) {
10922
10876
  return node;
10923
10877
  }
10924
10878
  const callee = outer.getExpression();
10925
- if (!Node45.isPropertyAccessExpression(callee) || callee.getName() !== "stringify") {
10879
+ if (!Node46.isPropertyAccessExpression(callee) || callee.getName() !== "stringify") {
10926
10880
  return node;
10927
10881
  }
10928
10882
  const receiver = callee.getExpression();
10929
- if (!Node45.isIdentifier(receiver) || receiver.getText() !== "JSON") {
10883
+ if (!Node46.isIdentifier(receiver) || receiver.getText() !== "JSON") {
10930
10884
  return node;
10931
10885
  }
10932
10886
  const args = outer.getArguments();
@@ -10936,7 +10890,7 @@ function unwrapJsonStringify(node) {
10936
10890
  return unwrapAs(args[0]);
10937
10891
  }
10938
10892
  function substituted(value, ctx) {
10939
- if (ctx.substitutions === void 0 || !Node45.isIdentifier(value)) {
10893
+ if (ctx.substitutions === void 0 || !Node46.isIdentifier(value)) {
10940
10894
  return value;
10941
10895
  }
10942
10896
  return ctx.substitutions.get(value.getText()) ?? value;
@@ -10980,10 +10934,10 @@ function statusFromProperty(obj, name, ctx) {
10980
10934
  if (prop === void 0) {
10981
10935
  return null;
10982
10936
  }
10983
- if (Node45.isShorthandPropertyAssignment(prop)) {
10937
+ if (Node46.isShorthandPropertyAssignment(prop)) {
10984
10938
  return { type: "dynamic", sourceText: prop.getName() };
10985
10939
  }
10986
- if (!Node45.isPropertyAssignment(prop)) {
10940
+ if (!Node46.isPropertyAssignment(prop)) {
10987
10941
  return null;
10988
10942
  }
10989
10943
  const value = prop.getInitializer();
@@ -11006,7 +10960,7 @@ function extractStatusCodeFromRule(ctx) {
11006
10960
  return null;
11007
10961
  }
11008
10962
  const first = ctx.throwCallArgs?.[0];
11009
- if (first !== void 0 && Node45.isNumericLiteral(first)) {
10963
+ if (first !== void 0 && Node46.isNumericLiteral(first)) {
11010
10964
  const value = first.getLiteralValue();
11011
10965
  if (value >= 100 && value <= 599) {
11012
10966
  return { type: "literal", value };
@@ -11019,7 +10973,7 @@ function extractStatusCodeFromRule(ctx) {
11019
10973
  return null;
11020
10974
  }
11021
10975
  const arg = ctx.throwCallArgs[sc.position];
11022
- if (arg === void 0 || !Node45.isNewExpression(arg)) {
10976
+ if (arg === void 0 || !Node46.isNewExpression(arg)) {
11023
10977
  return null;
11024
10978
  }
11025
10979
  const ctorText = arg.getExpression().getText();
@@ -11028,7 +10982,7 @@ function extractStatusCodeFromRule(ctx) {
11028
10982
  if (sc.from === "argumentProperty") {
11029
10983
  const args = ctx.throwCallArgs ?? ctx.calls?.[0]?.getArguments();
11030
10984
  const arg = args?.[sc.position];
11031
- if (arg === void 0 || !Node45.isObjectLiteralExpression(arg)) {
10985
+ if (arg === void 0 || !Node46.isObjectLiteralExpression(arg)) {
11032
10986
  return null;
11033
10987
  }
11034
10988
  return statusFromProperty(arg, sc.name, ctx);
@@ -11038,8 +10992,8 @@ function extractStatusCodeFromRule(ctx) {
11038
10992
  return null;
11039
10993
  }
11040
10994
  for (const prop of ctx.returnedObj.getProperties()) {
11041
- if (!Node45.isPropertyAssignment(prop)) {
11042
- if (Node45.isShorthandPropertyAssignment(prop)) {
10995
+ if (!Node46.isPropertyAssignment(prop)) {
10996
+ if (Node46.isShorthandPropertyAssignment(prop)) {
11043
10997
  if (prop.getName() === sc.name) {
11044
10998
  const resolved = ctx.substitutions?.get(prop.getName());
11045
10999
  if (resolved !== void 0) {
@@ -11097,8 +11051,8 @@ function extractBody(ctx) {
11097
11051
  return null;
11098
11052
  }
11099
11053
  for (const prop of ctx.returnedObj.getProperties()) {
11100
- if (!Node45.isPropertyAssignment(prop)) {
11101
- if (Node45.isShorthandPropertyAssignment(prop)) {
11054
+ if (!Node46.isPropertyAssignment(prop)) {
11055
+ if (Node46.isShorthandPropertyAssignment(prop)) {
11102
11056
  if (prop.getName() === b.name) {
11103
11057
  const resolved = ctx.substitutions?.get(prop.getName());
11104
11058
  if (resolved !== void 0) {
@@ -11153,16 +11107,16 @@ function extractBody(ctx) {
11153
11107
  }
11154
11108
 
11155
11109
  // src/terminals/jsx.ts
11156
- import { Node as Node46 } from "ts-morph";
11110
+ import { Node as Node47 } from "ts-morph";
11157
11111
  function tryMatchJsxReturn(node, pattern) {
11158
11112
  let expr;
11159
11113
  let source;
11160
- if (Node46.isReturnStatement(node)) {
11114
+ if (Node47.isReturnStatement(node)) {
11161
11115
  expr = node.getExpression();
11162
11116
  source = node;
11163
- } else if (Node46.isArrowFunction(node)) {
11117
+ } else if (Node47.isArrowFunction(node)) {
11164
11118
  const body = node.getBody();
11165
- if (body !== void 0 && !Node46.isBlock(body)) {
11119
+ if (body !== void 0 && !Node47.isBlock(body)) {
11166
11120
  expr = body;
11167
11121
  source = body;
11168
11122
  }
@@ -11193,14 +11147,14 @@ function tryMatchJsxReturn(node, pattern) {
11193
11147
  return { node, source, terminal };
11194
11148
  }
11195
11149
  function componentTargetOf(tagNode) {
11196
- if (!Node46.isIdentifier(tagNode) || !/^[A-Z]/.test(tagNode.getText())) {
11150
+ if (!Node47.isIdentifier(tagNode) || !/^[A-Z]/.test(tagNode.getText())) {
11197
11151
  return null;
11198
11152
  }
11199
11153
  const target = functionTargetOf(tagNode);
11200
11154
  return target === null ? null : { file: target.file, name: target.name };
11201
11155
  }
11202
11156
  function jsxToRenderNode(node) {
11203
- if (Node46.isJsxElement(node)) {
11157
+ if (Node47.isJsxElement(node)) {
11204
11158
  const opening = node.getOpeningElement();
11205
11159
  const tag = opening.getTagNameNode().getText();
11206
11160
  const attrs = collectJsxAttributes(opening);
@@ -11214,7 +11168,7 @@ function jsxToRenderNode(node) {
11214
11168
  ...target !== null ? { target } : {}
11215
11169
  };
11216
11170
  }
11217
- if (Node46.isJsxSelfClosingElement(node)) {
11171
+ if (Node47.isJsxSelfClosingElement(node)) {
11218
11172
  const tag = node.getTagNameNode().getText();
11219
11173
  const attrs = collectJsxAttributes(node);
11220
11174
  const target = componentTargetOf(node.getTagNameNode());
@@ -11226,11 +11180,11 @@ function jsxToRenderNode(node) {
11226
11180
  ...target !== null ? { target } : {}
11227
11181
  };
11228
11182
  }
11229
- if (Node46.isJsxFragment(node)) {
11183
+ if (Node47.isJsxFragment(node)) {
11230
11184
  const children = node.getJsxChildren().map(jsxChildToRenderNode).filter((n) => n !== null);
11231
11185
  return { type: "element", tag: "Fragment", children };
11232
11186
  }
11233
- if (Node46.isParenthesizedExpression(node)) {
11187
+ if (Node47.isParenthesizedExpression(node)) {
11234
11188
  return jsxToRenderNode(node.getExpression());
11235
11189
  }
11236
11190
  return null;
@@ -11238,12 +11192,12 @@ function jsxToRenderNode(node) {
11238
11192
  function collectJsxAttributes(opening) {
11239
11193
  const entries = {};
11240
11194
  for (const attr of opening.getAttributes()) {
11241
- if (Node46.isJsxSpreadAttribute(attr)) {
11195
+ if (Node47.isJsxSpreadAttribute(attr)) {
11242
11196
  const exprText = attr.getExpression().getText();
11243
11197
  entries[`...${exprText}`] = exprText;
11244
11198
  continue;
11245
11199
  }
11246
- if (!Node46.isJsxAttribute(attr)) {
11200
+ if (!Node47.isJsxAttribute(attr)) {
11247
11201
  continue;
11248
11202
  }
11249
11203
  const name = attr.getNameNode().getText();
@@ -11252,7 +11206,7 @@ function collectJsxAttributes(opening) {
11252
11206
  entries[name] = "";
11253
11207
  continue;
11254
11208
  }
11255
- if (Node46.isJsxExpression(initializer)) {
11209
+ if (Node47.isJsxExpression(initializer)) {
11256
11210
  const inner = initializer.getExpression();
11257
11211
  entries[name] = inner !== void 0 ? inner.getText() : "";
11258
11212
  continue;
@@ -11262,30 +11216,30 @@ function collectJsxAttributes(opening) {
11262
11216
  return Object.keys(entries).length > 0 ? entries : null;
11263
11217
  }
11264
11218
  function jsxChildToRenderNode(child) {
11265
- if (Node46.isJsxText(child)) {
11219
+ if (Node47.isJsxText(child)) {
11266
11220
  const text = child.getLiteralText().trim();
11267
11221
  if (text.length === 0) {
11268
11222
  return null;
11269
11223
  }
11270
11224
  return { type: "text", value: text };
11271
11225
  }
11272
- if (Node46.isJsxExpression(child)) {
11226
+ if (Node47.isJsxExpression(child)) {
11273
11227
  const inner = child.getExpression();
11274
11228
  if (inner === void 0) {
11275
11229
  return null;
11276
11230
  }
11277
11231
  return jsxExpressionToRenderNode(inner);
11278
11232
  }
11279
- if (Node46.isJsxElement(child) || Node46.isJsxSelfClosingElement(child) || Node46.isJsxFragment(child)) {
11233
+ if (Node47.isJsxElement(child) || Node47.isJsxSelfClosingElement(child) || Node47.isJsxFragment(child)) {
11280
11234
  return jsxToRenderNode(child);
11281
11235
  }
11282
11236
  return null;
11283
11237
  }
11284
11238
  function jsxExpressionToRenderNode(expr) {
11285
- if (Node46.isParenthesizedExpression(expr)) {
11239
+ if (Node47.isParenthesizedExpression(expr)) {
11286
11240
  return jsxExpressionToRenderNode(expr.getExpression());
11287
11241
  }
11288
- if (Node46.isBinaryExpression(expr)) {
11242
+ if (Node47.isBinaryExpression(expr)) {
11289
11243
  const op = expr.getOperatorToken().getText();
11290
11244
  if (op === "&&") {
11291
11245
  const right = renderAlternative(peelParens(expr.getRight()));
@@ -11299,7 +11253,7 @@ function jsxExpressionToRenderNode(expr) {
11299
11253
  }
11300
11254
  }
11301
11255
  }
11302
- if (Node46.isConditionalExpression(expr)) {
11256
+ if (Node47.isConditionalExpression(expr)) {
11303
11257
  const truthy = renderAlternative(peelParens(expr.getWhenTrue()));
11304
11258
  const falsy = renderAlternative(peelParens(expr.getWhenFalse()));
11305
11259
  if (truthy.kind === "jsx") {
@@ -11322,16 +11276,16 @@ function jsxExpressionToRenderNode(expr) {
11322
11276
  return { type: "expression", sourceText: expr.getText() };
11323
11277
  }
11324
11278
  function renderAlternative(node) {
11325
- if (Node46.isNullLiteral(node)) {
11279
+ if (Node47.isNullLiteral(node)) {
11326
11280
  return { kind: "noRender" };
11327
11281
  }
11328
- if (Node46.isFalseLiteral(node)) {
11282
+ if (Node47.isFalseLiteral(node)) {
11329
11283
  return { kind: "noRender" };
11330
11284
  }
11331
- if (Node46.isIdentifier(node) && node.getText() === "undefined") {
11285
+ if (Node47.isIdentifier(node) && node.getText() === "undefined") {
11332
11286
  return { kind: "noRender" };
11333
11287
  }
11334
- if (Node46.isJsxElement(node) || Node46.isJsxSelfClosingElement(node) || Node46.isJsxFragment(node)) {
11288
+ if (Node47.isJsxElement(node) || Node47.isJsxSelfClosingElement(node) || Node47.isJsxFragment(node)) {
11335
11289
  const tree = jsxToRenderNode(node);
11336
11290
  if (tree !== null) {
11337
11291
  return { kind: "jsx", node: tree };
@@ -11342,14 +11296,14 @@ function renderAlternative(node) {
11342
11296
 
11343
11297
  // src/terminals/returns.ts
11344
11298
  import {
11345
- Node as Node49
11299
+ Node as Node50
11346
11300
  } from "ts-morph";
11347
11301
 
11348
11302
  // src/terminals/helperResolution.ts
11349
- import { Node as Node47, SyntaxKind as SyntaxKind11 } from "ts-morph";
11303
+ import { Node as Node48, SyntaxKind as SyntaxKind11 } from "ts-morph";
11350
11304
  function resolveHelperReturn(call, resolveCallee2) {
11351
11305
  const callee = call.getExpression();
11352
- if (!Node47.isIdentifier(callee)) {
11306
+ if (!Node48.isIdentifier(callee)) {
11353
11307
  return { kind: "notLocal" };
11354
11308
  }
11355
11309
  const helper = memoizedLocalHelper(callee, resolveCallee2);
@@ -11379,16 +11333,16 @@ function guardsAbove(returnValue) {
11379
11333
  let child = returnValue;
11380
11334
  let current2 = returnValue.getParent();
11381
11335
  while (current2 !== void 0) {
11382
- if (Node47.isIfStatement(current2)) {
11336
+ if (Node48.isIfStatement(current2)) {
11383
11337
  guards.push({
11384
11338
  condition: current2.getExpression(),
11385
11339
  whenTrue: current2.getThenStatement() === child
11386
11340
  });
11387
11341
  }
11388
- if (Node47.isBlock(current2)) {
11342
+ if (Node48.isBlock(current2)) {
11389
11343
  guards.push(...earlyReturnGuardsBefore(current2, child));
11390
11344
  }
11391
- if (Node47.isFunctionDeclaration(current2) || Node47.isArrowFunction(current2) || Node47.isFunctionExpression(current2)) {
11345
+ if (Node48.isFunctionDeclaration(current2) || Node48.isArrowFunction(current2) || Node48.isFunctionExpression(current2)) {
11392
11346
  break;
11393
11347
  }
11394
11348
  child = current2;
@@ -11397,7 +11351,7 @@ function guardsAbove(returnValue) {
11397
11351
  return guards;
11398
11352
  }
11399
11353
  function earlyReturnGuardsBefore(block, child) {
11400
- if (!Node47.isBlock(block)) {
11354
+ if (!Node48.isBlock(block)) {
11401
11355
  return [];
11402
11356
  }
11403
11357
  const guards = [];
@@ -11405,7 +11359,7 @@ function earlyReturnGuardsBefore(block, child) {
11405
11359
  if (statement === child) {
11406
11360
  break;
11407
11361
  }
11408
- if (!Node47.isIfStatement(statement) || statement.getElseStatement()) {
11362
+ if (!Node48.isIfStatement(statement) || statement.getElseStatement()) {
11409
11363
  continue;
11410
11364
  }
11411
11365
  if (alwaysReturns(statement.getThenStatement())) {
@@ -11415,10 +11369,10 @@ function earlyReturnGuardsBefore(block, child) {
11415
11369
  return guards;
11416
11370
  }
11417
11371
  function alwaysReturns(statement) {
11418
- if (Node47.isReturnStatement(statement) || Node47.isThrowStatement(statement)) {
11372
+ if (Node48.isReturnStatement(statement) || Node48.isThrowStatement(statement)) {
11419
11373
  return true;
11420
11374
  }
11421
- if (!Node47.isBlock(statement)) {
11375
+ if (!Node48.isBlock(statement)) {
11422
11376
  return false;
11423
11377
  }
11424
11378
  const statements = statement.getStatements();
@@ -11436,7 +11390,7 @@ var COMPARISONS = {
11436
11390
  "!=": (a, b) => a !== b
11437
11391
  };
11438
11392
  function evaluateComparison(condition, substitutions) {
11439
- if (!Node47.isBinaryExpression(condition)) {
11393
+ if (!Node48.isBinaryExpression(condition)) {
11440
11394
  return null;
11441
11395
  }
11442
11396
  const left = numberFor(condition.getLeft(), substitutions);
@@ -11448,8 +11402,8 @@ function evaluateComparison(condition, substitutions) {
11448
11402
  return compare === void 0 ? null : compare(left, right);
11449
11403
  }
11450
11404
  function numberFor(node, substitutions) {
11451
- const resolved = Node47.isIdentifier(node) && substitutions.has(node.getText()) ? substitutions.get(node.getText()) : node;
11452
- 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;
11453
11407
  }
11454
11408
  var helperBySymbol = /* @__PURE__ */ new WeakMap();
11455
11409
  function memoizedLocalHelper(callee, resolveCallee2) {
@@ -11515,8 +11469,8 @@ function implementationBeside(declaration, name) {
11515
11469
  return candidate;
11516
11470
  }
11517
11471
  }
11518
- const variable4 = source.getVariableDeclaration(name);
11519
- const fn = variable4 === void 0 ? null : asFunctionLike(variable4);
11472
+ const variable3 = source.getVariableDeclaration(name);
11473
+ const fn = variable3 === void 0 ? null : asFunctionLike(variable3);
11520
11474
  if (fn !== null) {
11521
11475
  return fn;
11522
11476
  }
@@ -11536,12 +11490,12 @@ function declarationsFor(callee, resolveCallee2) {
11536
11490
  return (aliased ?? symbol).getDeclarations();
11537
11491
  }
11538
11492
  function asFunctionLike(declaration) {
11539
- if (Node47.isFunctionDeclaration(declaration) || Node47.isArrowFunction(declaration) || Node47.isFunctionExpression(declaration)) {
11493
+ if (Node48.isFunctionDeclaration(declaration) || Node48.isArrowFunction(declaration) || Node48.isFunctionExpression(declaration)) {
11540
11494
  return declaration;
11541
11495
  }
11542
- if (Node47.isVariableDeclaration(declaration)) {
11496
+ if (Node48.isVariableDeclaration(declaration)) {
11543
11497
  const initializer = declaration.getInitializer();
11544
- if (initializer !== void 0 && (Node47.isArrowFunction(initializer) || Node47.isFunctionExpression(initializer))) {
11498
+ if (initializer !== void 0 && (Node48.isArrowFunction(initializer) || Node48.isFunctionExpression(initializer))) {
11545
11499
  return initializer;
11546
11500
  }
11547
11501
  }
@@ -11552,9 +11506,9 @@ function returnedObjects(fn) {
11552
11506
  if (body === void 0) {
11553
11507
  return [];
11554
11508
  }
11555
- if (!Node47.isBlock(body)) {
11509
+ if (!Node48.isBlock(body)) {
11556
11510
  const expression = peelParens(body);
11557
- return Node47.isObjectLiteralExpression(expression) ? [expression] : [];
11511
+ return Node48.isObjectLiteralExpression(expression) ? [expression] : [];
11558
11512
  }
11559
11513
  const found = [];
11560
11514
  for (const statement of body.getDescendantsOfKind(
@@ -11568,7 +11522,7 @@ function returnedObjects(fn) {
11568
11522
  continue;
11569
11523
  }
11570
11524
  const unwrapped2 = peelParens(expression);
11571
- if (Node47.isObjectLiteralExpression(unwrapped2)) {
11525
+ if (Node48.isObjectLiteralExpression(unwrapped2)) {
11572
11526
  found.push(unwrapped2);
11573
11527
  }
11574
11528
  }
@@ -11577,7 +11531,7 @@ function returnedObjects(fn) {
11577
11531
  function enclosingFunctionOf(node) {
11578
11532
  let current2 = node.getParent();
11579
11533
  while (current2 !== void 0) {
11580
- 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)) {
11581
11535
  return current2.getBody();
11582
11536
  }
11583
11537
  current2 = current2.getParent();
@@ -11596,7 +11550,7 @@ function bindArguments(callArgs, params) {
11596
11550
  }
11597
11551
 
11598
11552
  // src/terminals/statusBranches.ts
11599
- import { Node as Node48 } from "ts-morph";
11553
+ import { Node as Node49 } from "ts-morph";
11600
11554
  import { constantOf as constantOf2 } from "@suss/values";
11601
11555
  function statusChoicesOf(argument, resolution) {
11602
11556
  const chosen = asConditional(argument);
@@ -11620,10 +11574,10 @@ function asConditional(node) {
11620
11574
  if (direct !== null) {
11621
11575
  return direct;
11622
11576
  }
11623
- if (!Node48.isIdentifier(node)) {
11577
+ if (!Node49.isIdentifier(node)) {
11624
11578
  return null;
11625
11579
  }
11626
- const declaration = node.getSymbol()?.getDeclarations().find(Node48.isVariableDeclaration);
11580
+ const declaration = node.getSymbol()?.getDeclarations().find(Node49.isVariableDeclaration);
11627
11581
  if (declaration === void 0) {
11628
11582
  return null;
11629
11583
  }
@@ -11634,7 +11588,7 @@ function asConditional(node) {
11634
11588
  const only = written.values[0];
11635
11589
  return only === void 0 ? null : toConditional(only);
11636
11590
  }
11637
- var toConditional = (node) => Node48.isConditionalExpression(node) ? node : null;
11591
+ var toConditional = (node) => Node49.isConditionalExpression(node) ? node : null;
11638
11592
  function numberOf(node, resolution) {
11639
11593
  const value = constantOf2(evaluatedValue(node, resolution));
11640
11594
  return typeof value === "number" && Number.isFinite(value) ? value : null;
@@ -11651,7 +11605,7 @@ function unwrapMethodChain(call, match, func) {
11651
11605
  for (let i = methodChain.length - 1; i >= 0; i--) {
11652
11606
  const expectedMethod = methodChain[i];
11653
11607
  const callee = current2.getExpression();
11654
- if (!Node49.isPropertyAccessExpression(callee)) {
11608
+ if (!Node50.isPropertyAccessExpression(callee)) {
11655
11609
  return null;
11656
11610
  }
11657
11611
  if (callee.getName() !== expectedMethod) {
@@ -11667,7 +11621,7 @@ function unwrapMethodChain(call, match, func) {
11667
11621
  return null;
11668
11622
  }
11669
11623
  } else {
11670
- if (!Node49.isCallExpression(subject)) {
11624
+ if (!Node50.isCallExpression(subject)) {
11671
11625
  return null;
11672
11626
  }
11673
11627
  current2 = subject;
@@ -11677,9 +11631,9 @@ function unwrapMethodChain(call, match, func) {
11677
11631
  }
11678
11632
  function withoutPassThroughCalls(subject, passThrough) {
11679
11633
  let current2 = subject;
11680
- while (Node49.isCallExpression(current2)) {
11634
+ while (Node50.isCallExpression(current2)) {
11681
11635
  const callee = current2.getExpression();
11682
- if (!Node49.isPropertyAccessExpression(callee) || !passThrough.includes(callee.getName())) {
11636
+ if (!Node50.isPropertyAccessExpression(callee) || !passThrough.includes(callee.getName())) {
11683
11637
  break;
11684
11638
  }
11685
11639
  current2 = callee.getExpression();
@@ -11691,12 +11645,12 @@ function returnedValueOf(returnStatement) {
11691
11645
  return written === void 0 ? null : unwrapValue(written);
11692
11646
  }
11693
11647
  function tryMatchReturnShape(node, pattern, match, resolution, resolveCallee2) {
11694
- if (Node49.isObjectLiteralExpression(node)) {
11648
+ if (Node50.isObjectLiteralExpression(node)) {
11695
11649
  const source = returnPositionOf(node);
11696
11650
  if (source === null) {
11697
11651
  return [];
11698
11652
  }
11699
- if (Node49.isReturnStatement(source) && returnedValueOf(source) === node) {
11653
+ if (Node50.isReturnStatement(source) && returnedValueOf(source) === node) {
11700
11654
  return [];
11701
11655
  }
11702
11656
  const terminal = terminalFromReturnedObject(
@@ -11709,14 +11663,14 @@ function tryMatchReturnShape(node, pattern, match, resolution, resolveCallee2) {
11709
11663
  );
11710
11664
  return terminal === null ? [] : [{ ...terminal, source }];
11711
11665
  }
11712
- if (!Node49.isReturnStatement(node)) {
11666
+ if (!Node50.isReturnStatement(node)) {
11713
11667
  return [];
11714
11668
  }
11715
11669
  const returned = returnedValueOf(node);
11716
11670
  if (returned === null) {
11717
11671
  return [];
11718
11672
  }
11719
- if (Node49.isObjectLiteralExpression(returned)) {
11673
+ if (Node50.isObjectLiteralExpression(returned)) {
11720
11674
  const terminal = terminalFromReturnedObject(
11721
11675
  returned,
11722
11676
  node,
@@ -11727,7 +11681,7 @@ function tryMatchReturnShape(node, pattern, match, resolution, resolveCallee2) {
11727
11681
  );
11728
11682
  return terminal === null ? [] : [terminal];
11729
11683
  }
11730
- if (!Node49.isCallExpression(returned)) {
11684
+ if (!Node50.isCallExpression(returned)) {
11731
11685
  return [];
11732
11686
  }
11733
11687
  const resolved = resolveHelperReturn(returned, resolveCallee2);
@@ -11764,7 +11718,7 @@ function terminalFromReturnedObject(obj, anchor, pattern, match, substitutions,
11764
11718
  if (required !== void 0 && required.length > 0) {
11765
11719
  const presentNames = /* @__PURE__ */ new Set();
11766
11720
  for (const prop of obj.getProperties()) {
11767
- if (Node49.isPropertyAssignment(prop) || Node49.isShorthandPropertyAssignment(prop)) {
11721
+ if (Node50.isPropertyAssignment(prop) || Node50.isShorthandPropertyAssignment(prop)) {
11768
11722
  presentNames.add(prop.getName());
11769
11723
  }
11770
11724
  }
@@ -11790,7 +11744,7 @@ function terminalFromReturnedObject(obj, anchor, pattern, match, substitutions,
11790
11744
  // When a helper built the value, the anchor is the caller's own
11791
11745
  // return, so it doubles as the provenance. A value reached any other
11792
11746
  // way leaves this unset and its caller fills it in.
11793
- ...Node49.isReturnStatement(anchor) ? { source: anchor } : {},
11747
+ ...Node50.isReturnStatement(anchor) ? { source: anchor } : {},
11794
11748
  terminal: {
11795
11749
  kind: pattern.kind,
11796
11750
  statusCode,
@@ -11809,7 +11763,7 @@ function terminalFromReturnedObject(obj, anchor, pattern, match, substitutions,
11809
11763
  };
11810
11764
  }
11811
11765
  function tryMatchParameterMethodCall(node, func, pattern, match, resolution) {
11812
- if (!Node49.isCallExpression(node)) {
11766
+ if (!Node50.isCallExpression(node)) {
11813
11767
  return [];
11814
11768
  }
11815
11769
  const result = unwrapMethodChain(node, match, func);
@@ -11869,7 +11823,7 @@ function statusArgument(calls, extraction) {
11869
11823
  }
11870
11824
  function returnCoveredByParameterMethodCall(expr, func, patterns) {
11871
11825
  const current2 = unwrapValue(expr);
11872
- if (!Node49.isCallExpression(current2)) {
11826
+ if (!Node50.isCallExpression(current2)) {
11873
11827
  return false;
11874
11828
  }
11875
11829
  for (const pattern of patterns) {
@@ -11885,7 +11839,7 @@ function returnCoveredByParameterMethodCall(expr, func, patterns) {
11885
11839
  }
11886
11840
  function tryMatchReturnStatement(node, pattern, func, allPatterns) {
11887
11841
  const match = pattern.match.type === "returnStatement" ? pattern.match : null;
11888
- if (Node49.isReturnStatement(node)) {
11842
+ if (Node50.isReturnStatement(node)) {
11889
11843
  const expr = node.getExpression();
11890
11844
  if (match?.excludeCallReturns === true) {
11891
11845
  if (expr === void 0) {
@@ -11904,9 +11858,9 @@ function tryMatchReturnStatement(node, pattern, func, allPatterns) {
11904
11858
  }
11905
11859
  return buildReturnTerminal(node, pattern, body);
11906
11860
  }
11907
- if (Node49.isArrowFunction(node)) {
11861
+ if (Node50.isArrowFunction(node)) {
11908
11862
  const body = node.getBody();
11909
- if (body === void 0 || Node49.isBlock(body)) {
11863
+ if (body === void 0 || Node50.isBlock(body)) {
11910
11864
  return null;
11911
11865
  }
11912
11866
  const shape = extractShape(body);
@@ -11964,20 +11918,20 @@ function unresolvedTerminal(kind, node) {
11964
11918
  };
11965
11919
  }
11966
11920
  function calleeSubject(callee) {
11967
- if (Node49.isIdentifier(callee)) {
11921
+ if (Node50.isIdentifier(callee)) {
11968
11922
  return callee;
11969
11923
  }
11970
- if (Node49.isPropertyAccessExpression(callee)) {
11924
+ if (Node50.isPropertyAccessExpression(callee)) {
11971
11925
  const subject = callee.getExpression();
11972
- return Node49.isIdentifier(subject) ? subject : null;
11926
+ return Node50.isIdentifier(subject) ? subject : null;
11973
11927
  }
11974
11928
  return null;
11975
11929
  }
11976
11930
  function tryMatchFunctionCall(node, pattern, match, resolution, originatesFrom) {
11977
- if (!Node49.isCallExpression(node) && !Node49.isNewExpression(node)) {
11931
+ if (!Node50.isCallExpression(node) && !Node50.isNewExpression(node)) {
11978
11932
  return null;
11979
11933
  }
11980
- if (Node49.isNewExpression(node) && returnPositionOf(node) === null) {
11934
+ if (Node50.isNewExpression(node) && returnPositionOf(node) === null) {
11981
11935
  return null;
11982
11936
  }
11983
11937
  const callee = node.getExpression();
@@ -12016,9 +11970,9 @@ function tryMatchFunctionCall(node, pattern, match, resolution, originatesFrom)
12016
11970
  }
12017
11971
 
12018
11972
  // src/terminals/throws.ts
12019
- import { Node as Node50 } from "ts-morph";
11973
+ import { Node as Node51 } from "ts-morph";
12020
11974
  function tryMatchThrowExpression(node, pattern, match, resolution) {
12021
- if (!Node50.isThrowStatement(node)) {
11975
+ if (!Node51.isThrowStatement(node)) {
12022
11976
  return null;
12023
11977
  }
12024
11978
  const thrownExpr = node.getExpression();
@@ -12060,17 +12014,17 @@ function extractThrowMessage(callArgs) {
12060
12014
  return null;
12061
12015
  }
12062
12016
  for (const arg of callArgs) {
12063
- if (Node50.isStringLiteral(arg) || Node50.isNoSubstitutionTemplateLiteral(arg)) {
12017
+ if (Node51.isStringLiteral(arg) || Node51.isNoSubstitutionTemplateLiteral(arg)) {
12064
12018
  return arg.getLiteralValue();
12065
12019
  }
12066
- if (Node50.isTemplateExpression(arg)) {
12020
+ if (Node51.isTemplateExpression(arg)) {
12067
12021
  return arg.getText();
12068
12022
  }
12069
12023
  }
12070
12024
  return null;
12071
12025
  }
12072
12026
  function classifyThrownExpression(thrown, constructorPattern) {
12073
- if (Node50.isCallExpression(thrown) || Node50.isNewExpression(thrown)) {
12027
+ if (Node51.isCallExpression(thrown) || Node51.isNewExpression(thrown)) {
12074
12028
  const calleeText = thrown.getExpression().getText();
12075
12029
  if (constructorPattern !== void 0 && !calleeText.startsWith(constructorPattern)) {
12076
12030
  return null;
@@ -12157,9 +12111,9 @@ function findTerminals(func, patterns, barriers = NO_BARRIERS, resolution, origi
12157
12111
  }
12158
12112
  }
12159
12113
  });
12160
- if (results.length === 0 && Node51.isArrowFunction(func)) {
12114
+ if (results.length === 0 && Node52.isArrowFunction(func)) {
12161
12115
  const body = func.getBody();
12162
- if (body !== void 0 && !Node51.isBlock(body)) {
12116
+ if (body !== void 0 && !Node52.isBlock(body)) {
12163
12117
  for (const pattern of patterns) {
12164
12118
  let found = null;
12165
12119
  if (pattern.match.type === "parameterMethodCall") {
@@ -12194,7 +12148,7 @@ function functionMayFallThrough(func) {
12194
12148
  if (body === void 0) {
12195
12149
  return false;
12196
12150
  }
12197
- if (!Node51.isBlock(body)) {
12151
+ if (!Node52.isBlock(body)) {
12198
12152
  return false;
12199
12153
  }
12200
12154
  const statements = body.getStatements();
@@ -12202,7 +12156,7 @@ function functionMayFallThrough(func) {
12202
12156
  return true;
12203
12157
  }
12204
12158
  const last = statements[statements.length - 1];
12205
- if (Node51.isReturnStatement(last) || Node51.isThrowStatement(last)) {
12159
+ if (Node52.isReturnStatement(last) || Node52.isThrowStatement(last)) {
12206
12160
  return false;
12207
12161
  }
12208
12162
  return true;
@@ -12250,7 +12204,7 @@ function writesTerminal(call, terminalNodes) {
12250
12204
  }
12251
12205
  }
12252
12206
  function isReceiverOf(node, parent) {
12253
- 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;
12254
12208
  }
12255
12209
  var isDefaultConditionList = (conditions) => conditions.length === 0 || conditions.every(
12256
12210
  (c) => c.source === "earlyReturn" || c.source === "earlyThrow"
@@ -12260,7 +12214,7 @@ function bodyContentOf(func) {
12260
12214
  if (body === void 0) {
12261
12215
  return "absent";
12262
12216
  }
12263
- if (!Node52.isBlock(body)) {
12217
+ if (!Node53.isBlock(body)) {
12264
12218
  return "statements";
12265
12219
  }
12266
12220
  return body.getStatements().length === 0 ? "empty" : "statements";
@@ -12276,7 +12230,7 @@ function countUnmatchedReturns(func, terminals, barriers = NO_BARRIERS) {
12276
12230
  claimed.add(source);
12277
12231
  }
12278
12232
  }
12279
- if (Node52.isArrowFunction(func) && Node52.isExpression(body)) {
12233
+ if (Node53.isArrowFunction(func) && Node53.isExpression(body)) {
12280
12234
  return claimed.has(body) ? 0 : 1;
12281
12235
  }
12282
12236
  let unmatched = 0;
@@ -12289,7 +12243,7 @@ function countUnmatchedReturns(func, terminals, barriers = NO_BARRIERS) {
12289
12243
  traversal.skip();
12290
12244
  return;
12291
12245
  }
12292
- if (!Node52.isReturnStatement(node)) {
12246
+ if (!Node53.isReturnStatement(node)) {
12293
12247
  return;
12294
12248
  }
12295
12249
  if (node.getExpression() === void 0) {
@@ -12442,7 +12396,7 @@ function accountFor(site, terminalNodes, branches) {
12442
12396
  }
12443
12397
 
12444
12398
  // src/bootstrap/sourceFileLookup.ts
12445
- import { Node as Node53 } from "ts-morph";
12399
+ import { Node as Node54 } from "ts-morph";
12446
12400
  function createSourceFileLookup(project) {
12447
12401
  const all = project.getSourceFiles();
12448
12402
  const byAbs = /* @__PURE__ */ new Map();
@@ -12504,7 +12458,7 @@ function spanKey(span) {
12504
12458
  function indexFunctions(sf) {
12505
12459
  const index = /* @__PURE__ */ new Map();
12506
12460
  sf.forEachDescendant((node) => {
12507
- 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)) {
12508
12462
  return;
12509
12463
  }
12510
12464
  const bySpan = spanKey({ start: node.getStart(), end: node.getEnd() });
@@ -12518,13 +12472,13 @@ function indexFunctions(sf) {
12518
12472
  }
12519
12473
 
12520
12474
  // src/contract.ts
12521
- import { Node as Node54 } from "ts-morph";
12475
+ import { Node as Node55 } from "ts-morph";
12522
12476
  import { restBinding } from "@suss/behavioral-ir";
12523
12477
  function extractDeclaredBody(node) {
12524
12478
  if (node === void 0) {
12525
12479
  return null;
12526
12480
  }
12527
- if (!Node54.isCallExpression(node)) {
12481
+ if (!Node55.isCallExpression(node)) {
12528
12482
  return null;
12529
12483
  }
12530
12484
  const typeArgs = node.getTypeArguments();
@@ -12538,10 +12492,10 @@ function resolveHandlerPropNode(func) {
12538
12492
  if (parent === void 0) {
12539
12493
  return null;
12540
12494
  }
12541
- if (Node54.isPropertyAssignment(parent)) {
12495
+ if (Node55.isPropertyAssignment(parent)) {
12542
12496
  return parent;
12543
12497
  }
12544
- if (Node54.isMethodDeclaration(func)) {
12498
+ if (Node55.isMethodDeclaration(func)) {
12545
12499
  return func;
12546
12500
  }
12547
12501
  return null;
@@ -12553,11 +12507,11 @@ function findRouterCall(unit) {
12553
12507
  return null;
12554
12508
  }
12555
12509
  const handlersObj = propNode.getParent();
12556
- if (handlersObj === void 0 || !Node54.isObjectLiteralExpression(handlersObj)) {
12510
+ if (handlersObj === void 0 || !Node55.isObjectLiteralExpression(handlersObj)) {
12557
12511
  return null;
12558
12512
  }
12559
12513
  const routerCall = handlersObj.getParent();
12560
- if (routerCall === void 0 || !Node54.isCallExpression(routerCall)) {
12514
+ if (routerCall === void 0 || !Node55.isCallExpression(routerCall)) {
12561
12515
  return null;
12562
12516
  }
12563
12517
  const args = routerCall.getArguments();
@@ -12570,17 +12524,17 @@ function findRouterCall(unit) {
12570
12524
  };
12571
12525
  }
12572
12526
  function resolveContractObject(contractArg, resolution) {
12573
- if (Node54.isObjectLiteralExpression(contractArg)) {
12527
+ if (Node55.isObjectLiteralExpression(contractArg)) {
12574
12528
  return contractArg;
12575
12529
  }
12576
- if (Node54.isPropertyAccessExpression(contractArg)) {
12530
+ if (Node55.isPropertyAccessExpression(contractArg)) {
12577
12531
  const base = resolveContractObject(contractArg.getExpression(), resolution);
12578
- if (base === null || !Node54.isObjectLiteralExpression(base)) {
12532
+ if (base === null || !Node55.isObjectLiteralExpression(base)) {
12579
12533
  return null;
12580
12534
  }
12581
12535
  const propName = contractArg.getName();
12582
12536
  for (const prop of base.getProperties()) {
12583
- if (!Node54.isPropertyAssignment(prop)) {
12537
+ if (!Node55.isPropertyAssignment(prop)) {
12584
12538
  continue;
12585
12539
  }
12586
12540
  if (prop.getName() !== propName) {
@@ -12590,20 +12544,20 @@ function resolveContractObject(contractArg, resolution) {
12590
12544
  if (value === void 0) {
12591
12545
  return null;
12592
12546
  }
12593
- if (Node54.isObjectLiteralExpression(value)) {
12547
+ if (Node55.isObjectLiteralExpression(value)) {
12594
12548
  return value;
12595
12549
  }
12596
- if (Node54.isIdentifier(value) || Node54.isPropertyAccessExpression(value)) {
12550
+ if (Node55.isIdentifier(value) || Node55.isPropertyAccessExpression(value)) {
12597
12551
  return resolveContractObject(value, resolution);
12598
12552
  }
12599
- if (Node54.isCallExpression(value)) {
12553
+ if (Node55.isCallExpression(value)) {
12600
12554
  return unwrapContractInit(value);
12601
12555
  }
12602
12556
  return null;
12603
12557
  }
12604
12558
  return null;
12605
12559
  }
12606
- if (!Node54.isIdentifier(contractArg)) {
12560
+ if (!Node55.isIdentifier(contractArg)) {
12607
12561
  return null;
12608
12562
  }
12609
12563
  const symbol = contractArg.getSymbol();
@@ -12615,7 +12569,7 @@ function resolveContractObject(contractArg, resolution) {
12615
12569
  return null;
12616
12570
  }
12617
12571
  const decl = decls[0];
12618
- if (Node54.isImportSpecifier(decl)) {
12572
+ if (Node55.isImportSpecifier(decl)) {
12619
12573
  const importDecl = decl.getImportDeclaration();
12620
12574
  const sourceFile = importDecl.getModuleSpecifierSourceFile();
12621
12575
  if (sourceFile !== void 0 && resolution !== void 0) {
@@ -12624,14 +12578,14 @@ function resolveContractObject(contractArg, resolution) {
12624
12578
  );
12625
12579
  if (exported !== void 0 && exported.length > 0) {
12626
12580
  const exportedDecl = exported[0];
12627
- if (Node54.isVariableDeclaration(exportedDecl)) {
12581
+ if (Node55.isVariableDeclaration(exportedDecl)) {
12628
12582
  return unwrapContractInit(exportedDecl.getInitializer());
12629
12583
  }
12630
12584
  }
12631
12585
  }
12632
12586
  return null;
12633
12587
  }
12634
- if (Node54.isVariableDeclaration(decl)) {
12588
+ if (Node55.isVariableDeclaration(decl)) {
12635
12589
  return unwrapContractInit(decl.getInitializer());
12636
12590
  }
12637
12591
  return null;
@@ -12641,39 +12595,39 @@ function unwrapContractInit(init) {
12641
12595
  return null;
12642
12596
  }
12643
12597
  const node = peelSyntax(init);
12644
- if (Node54.isCallExpression(node)) {
12598
+ if (Node55.isCallExpression(node)) {
12645
12599
  const args = node.getArguments();
12646
- if (args.length > 0 && Node54.isObjectLiteralExpression(args[0])) {
12600
+ if (args.length > 0 && Node55.isObjectLiteralExpression(args[0])) {
12647
12601
  return args[0];
12648
12602
  }
12649
12603
  return null;
12650
12604
  }
12651
- if (Node54.isObjectLiteralExpression(node)) {
12605
+ if (Node55.isObjectLiteralExpression(node)) {
12652
12606
  return node;
12653
12607
  }
12654
12608
  return null;
12655
12609
  }
12656
12610
  function extractEndpointContract(endpointNode, pattern, framework, resolution) {
12657
- if (!Node54.isObjectLiteralExpression(endpointNode)) {
12611
+ if (!Node55.isObjectLiteralExpression(endpointNode)) {
12658
12612
  return null;
12659
12613
  }
12660
12614
  const responses = [];
12661
12615
  let method;
12662
12616
  let path15;
12663
12617
  for (const prop of endpointNode.getProperties()) {
12664
- if (!Node54.isPropertyAssignment(prop)) {
12618
+ if (!Node55.isPropertyAssignment(prop)) {
12665
12619
  continue;
12666
12620
  }
12667
12621
  const propName = prop.getName();
12668
12622
  if (propName === pattern.methodProperty) {
12669
12623
  const val = prop.getInitializer();
12670
- if (val !== void 0 && Node54.isStringLiteral(val)) {
12624
+ if (val !== void 0 && Node55.isStringLiteral(val)) {
12671
12625
  method = val.getLiteralValue();
12672
12626
  }
12673
12627
  }
12674
12628
  if (propName === pattern.pathProperty) {
12675
12629
  const val = prop.getInitializer();
12676
- if (val !== void 0 && Node54.isStringLiteral(val)) {
12630
+ if (val !== void 0 && Node55.isStringLiteral(val)) {
12677
12631
  path15 = val.getLiteralValue();
12678
12632
  }
12679
12633
  }
@@ -12682,7 +12636,7 @@ function extractEndpointContract(endpointNode, pattern, framework, resolution) {
12682
12636
  const val = written === void 0 ? null : objectLiteralOf(written, resolution);
12683
12637
  if (val !== null) {
12684
12638
  for (const respProp of propertiesOf(val, resolution)) {
12685
- if (!Node54.isPropertyAssignment(respProp)) {
12639
+ if (!Node55.isPropertyAssignment(respProp)) {
12686
12640
  continue;
12687
12641
  }
12688
12642
  const statusStr = respProp.getName();
@@ -12732,11 +12686,11 @@ function readContract(unit, pattern, framework, resolution) {
12732
12686
  return null;
12733
12687
  }
12734
12688
  const contractObj = resolveContractObject(routerInfo.contractArg, resolution);
12735
- if (contractObj === null || !Node54.isObjectLiteralExpression(contractObj)) {
12689
+ if (contractObj === null || !Node55.isObjectLiteralExpression(contractObj)) {
12736
12690
  return null;
12737
12691
  }
12738
12692
  for (const prop of contractObj.getProperties()) {
12739
- if (!Node54.isPropertyAssignment(prop)) {
12693
+ if (!Node55.isPropertyAssignment(prop)) {
12740
12694
  continue;
12741
12695
  }
12742
12696
  if (prop.getName() !== routerInfo.handlerName) {
@@ -12761,7 +12715,7 @@ function endpointFromRegistrationArgument(unit, position, resolution) {
12761
12715
  return null;
12762
12716
  }
12763
12717
  const call = func.getParent();
12764
- if (call === void 0 || !Node54.isCallExpression(call)) {
12718
+ if (call === void 0 || !Node55.isCallExpression(call)) {
12765
12719
  return null;
12766
12720
  }
12767
12721
  const args = call.getArguments();
@@ -12773,24 +12727,24 @@ function endpointFromRegistrationArgument(unit, position, resolution) {
12773
12727
  return null;
12774
12728
  }
12775
12729
  let node = arg;
12776
- while (Node54.isAsExpression(node)) {
12730
+ while (Node55.isAsExpression(node)) {
12777
12731
  node = node.getExpression();
12778
12732
  }
12779
- if (Node54.isObjectLiteralExpression(node)) {
12733
+ if (Node55.isObjectLiteralExpression(node)) {
12780
12734
  return node;
12781
12735
  }
12782
- if (Node54.isCallExpression(node)) {
12736
+ if (Node55.isCallExpression(node)) {
12783
12737
  return unwrapContractInit(node);
12784
12738
  }
12785
12739
  return resolveContractObject(node, resolution);
12786
12740
  }
12787
12741
  function readContractForClientCall(callExpression, methodName, pattern, framework, resolution) {
12788
- const callee = Node54.isCallExpression(callExpression) ? callExpression.getExpression() : null;
12789
- if (callee === null || !Node54.isPropertyAccessExpression(callee)) {
12742
+ const callee = Node55.isCallExpression(callExpression) ? callExpression.getExpression() : null;
12743
+ if (callee === null || !Node55.isPropertyAccessExpression(callee)) {
12790
12744
  return null;
12791
12745
  }
12792
12746
  const clientIdentifier = callee.getExpression();
12793
- if (!Node54.isIdentifier(clientIdentifier)) {
12747
+ if (!Node55.isIdentifier(clientIdentifier)) {
12794
12748
  return null;
12795
12749
  }
12796
12750
  const symbol = clientIdentifier.getSymbol();
@@ -12802,11 +12756,11 @@ function readContractForClientCall(callExpression, methodName, pattern, framewor
12802
12756
  return null;
12803
12757
  }
12804
12758
  const decl = decls[0];
12805
- if (!Node54.isVariableDeclaration(decl)) {
12759
+ if (!Node55.isVariableDeclaration(decl)) {
12806
12760
  return null;
12807
12761
  }
12808
12762
  const init = decl.getInitializer();
12809
- if (init === void 0 || !Node54.isCallExpression(init)) {
12763
+ if (init === void 0 || !Node55.isCallExpression(init)) {
12810
12764
  return null;
12811
12765
  }
12812
12766
  const args = init.getArguments();
@@ -12814,11 +12768,11 @@ function readContractForClientCall(callExpression, methodName, pattern, framewor
12814
12768
  return null;
12815
12769
  }
12816
12770
  const contractObj = resolveContractObject(args[0], resolution);
12817
- if (contractObj === null || !Node54.isObjectLiteralExpression(contractObj)) {
12771
+ if (contractObj === null || !Node55.isObjectLiteralExpression(contractObj)) {
12818
12772
  return null;
12819
12773
  }
12820
12774
  for (const prop of contractObj.getProperties()) {
12821
- if (!Node54.isPropertyAssignment(prop)) {
12775
+ if (!Node55.isPropertyAssignment(prop)) {
12822
12776
  continue;
12823
12777
  }
12824
12778
  if (prop.getName() !== methodName) {
@@ -12838,6 +12792,159 @@ function readContractForClientCall(callExpression, methodName, pattern, framewor
12838
12792
  return null;
12839
12793
  }
12840
12794
 
12795
+ // src/diagnostics.ts
12796
+ import path7 from "path";
12797
+ import { ts as ts3 } from "ts-morph";
12798
+ import {
12799
+ createPackTallies,
12800
+ emptyTally,
12801
+ recordPackFailure,
12802
+ summaryCountsByPack
12803
+ } from "@suss/extractor";
12804
+ var DEFAULT_RESOLUTION = {
12805
+ moduleResolution: ts3.ModuleResolutionKind.Bundler,
12806
+ target: ts3.ScriptTarget.ESNext,
12807
+ module: ts3.ModuleKind.ESNext
12808
+ };
12809
+ function resolutionContext(args) {
12810
+ if (args.tsConfigFilePath !== void 0) {
12811
+ const configFile = ts3.readConfigFile(
12812
+ args.tsConfigFilePath,
12813
+ ts3.sys.readFile
12814
+ );
12815
+ if (configFile.error !== void 0) {
12816
+ return null;
12817
+ }
12818
+ const dir = path7.dirname(args.tsConfigFilePath);
12819
+ const parsed = ts3.parseJsonConfigFileContent(
12820
+ configFile.config,
12821
+ ts3.sys,
12822
+ dir,
12823
+ /*existingOptions*/
12824
+ void 0,
12825
+ args.tsConfigFilePath
12826
+ );
12827
+ return {
12828
+ containingFile: path7.join(dir, "index.ts"),
12829
+ options: parsed.options
12830
+ };
12831
+ }
12832
+ if (args.projectRoot === void 0 || !path7.isAbsolute(args.projectRoot)) {
12833
+ return null;
12834
+ }
12835
+ return {
12836
+ containingFile: path7.join(args.projectRoot, "index.ts"),
12837
+ options: DEFAULT_RESOLUTION
12838
+ };
12839
+ }
12840
+ function unresolvedGatesFor(gates, args) {
12841
+ if (gates.length === 0) {
12842
+ return [];
12843
+ }
12844
+ const context = resolutionContext(args);
12845
+ if (context === null) {
12846
+ return [];
12847
+ }
12848
+ const unresolved = [];
12849
+ for (const gate of gates) {
12850
+ const resolved = ts3.resolveModuleName(
12851
+ gate,
12852
+ context.containingFile,
12853
+ context.options,
12854
+ ts3.sys
12855
+ );
12856
+ if (resolved.resolvedModule === void 0) {
12857
+ unresolved.push(gate);
12858
+ }
12859
+ }
12860
+ return unresolved;
12861
+ }
12862
+ function helpersWithNoCall(patterns, matched, projectRoot) {
12863
+ const missing = [];
12864
+ for (const pattern of patterns) {
12865
+ if (pattern.match.type !== "registrationTemplate" || matched.has(pattern.match.helperName)) {
12866
+ continue;
12867
+ }
12868
+ const from = pattern.match.importModule;
12869
+ missing.push(
12870
+ from === void 0 ? pattern.match.helperName : `${pattern.match.helperName} from ${shortModule(from, projectRoot)}`
12871
+ );
12872
+ }
12873
+ return missing;
12874
+ }
12875
+ function shortModule(module, projectRoot) {
12876
+ if (projectRoot === void 0 || !path7.isAbsolute(module)) {
12877
+ return module;
12878
+ }
12879
+ return path7.relative(projectRoot, module);
12880
+ }
12881
+ function buildExtractionReport(args) {
12882
+ const bySummary = summaryCountsByPack(args.summaries);
12883
+ const packFunnels = args.packs.map((pack) => {
12884
+ const gates = packIsUngated(pack) ? [] : collectPackGates(pack);
12885
+ const tally = args.tallies.get(pack.name) ?? emptyTally();
12886
+ const counted = bySummary.get(pack.name) ?? {
12887
+ bound: 0,
12888
+ providers: 0,
12889
+ withBehavior: 0
12890
+ };
12891
+ return {
12892
+ pack: pack.name,
12893
+ version: pack.version ?? null,
12894
+ discovers: pack.discovery.length > 0 || pack.discoverUnits !== void 0,
12895
+ recognizes: (pack.invocationRecognizers?.length ?? 0) > 0 || (pack.accessRecognizers?.length ?? 0) > 0,
12896
+ gates,
12897
+ unresolvedGates: unresolvedGatesFor(gates, {
12898
+ tsConfigFilePath: args.tsConfigFilePath,
12899
+ projectRoot: args.projectRoot
12900
+ }),
12901
+ candidateFiles: tally.candidateFiles,
12902
+ unitsDiscovered: tally.unitsDiscovered,
12903
+ unitsInGatedFiles: tally.unitsInGatedFiles,
12904
+ effectsRecognized: tally.effectsRecognized,
12905
+ unitsClaimed: tally.unitsClaimed,
12906
+ summariesProduced: tally.summariesProduced,
12907
+ failures: tally.failures,
12908
+ helpersUnmatched: helpersWithNoCall(
12909
+ [...pack.discovery, ...args.contributedPatterns?.(pack.name) ?? []],
12910
+ tally.helpersMatched,
12911
+ args.projectRoot
12912
+ ),
12913
+ summariesBound: counted.bound,
12914
+ providerSummaries: counted.providers,
12915
+ summariesWithBehavior: counted.withBehavior,
12916
+ declarations: pack.declarations ?? null
12917
+ };
12918
+ });
12919
+ return {
12920
+ filesInProject: args.filesInProject,
12921
+ filesWalked: args.filesWalked,
12922
+ packs: packFunnels,
12923
+ summaries: args.summaries.length,
12924
+ filesWithUnreadableExports: [...args.filesWithUnreadableExports ?? []],
12925
+ reassignedNamesUnstated: args.reassignedNamesUnstated ?? 0,
12926
+ emptyStage: args.summaries.length === 0 ? firstEmptyStage(packFunnels, args) : null
12927
+ };
12928
+ }
12929
+ function firstEmptyStage(packs, args) {
12930
+ if (args.filesInProject === 0) {
12931
+ return "tsconfig";
12932
+ }
12933
+ const gateFailed = packs.some(
12934
+ (p) => p.unresolvedGates.length > 0 && p.candidateFiles > 0
12935
+ );
12936
+ if (gateFailed) {
12937
+ return "gateResolution";
12938
+ }
12939
+ if (args.filesWalked === 0 || packs.every((p) => p.candidateFiles === 0)) {
12940
+ return "candidateFiles";
12941
+ }
12942
+ if (packs.every((p) => p.unitsDiscovered === 0)) {
12943
+ return "discovery";
12944
+ }
12945
+ return "assembly";
12946
+ }
12947
+
12841
12948
  // src/discovery/filenameRoute.ts
12842
12949
  function routePathFromFile(filePath, convention) {
12843
12950
  const belowRoot = segmentsBelowRoot(filePath, convention.root);
@@ -12920,7 +13027,7 @@ import {
12920
13027
  } from "graphql";
12921
13028
  import picomatch2 from "picomatch";
12922
13029
  import {
12923
- Node as Node55
13030
+ Node as Node56
12924
13031
  } from "ts-morph";
12925
13032
  import {
12926
13033
  isGraphqlOperationBinding,
@@ -12965,11 +13072,11 @@ function fragmentsRegisteredIn(sourceFiles) {
12965
13072
  const registered = /* @__PURE__ */ new Set();
12966
13073
  for (const sourceFile of sourceFiles) {
12967
13074
  sourceFile.forEachDescendant((node) => {
12968
- if (!Node55.isCallExpression(node)) {
13075
+ if (!Node56.isCallExpression(node)) {
12969
13076
  return;
12970
13077
  }
12971
13078
  const argument = node.getArguments()[0];
12972
- if (argument === void 0 || !Node55.isNoSubstitutionTemplateLiteral(argument)) {
13079
+ if (argument === void 0 || !Node56.isNoSubstitutionTemplateLiteral(argument)) {
12973
13080
  return;
12974
13081
  }
12975
13082
  for (const name of fragmentOnlyDocumentNames(argument.getLiteralText())) {
@@ -13156,7 +13263,7 @@ function constructionRegistryStatus(construction, spec) {
13156
13263
  if (cacheConstruction === null) {
13157
13264
  return "unknown";
13158
13265
  }
13159
- if (!Node55.isNewExpression(cacheConstruction) && !Node55.isCallExpression(cacheConstruction)) {
13266
+ if (!Node56.isNewExpression(cacheConstruction) && !Node56.isCallExpression(cacheConstruction)) {
13160
13267
  return "unknown";
13161
13268
  }
13162
13269
  const args = cacheConstruction.getArguments();
@@ -13170,15 +13277,15 @@ function constructionRegistryStatus(construction, spec) {
13170
13277
  if (cacheOptions.getProperty(spec.registryProperty) !== void 0) {
13171
13278
  return "configured";
13172
13279
  }
13173
- const hasSpread = cacheOptions.getProperties().some((property) => Node55.isSpreadAssignment(property));
13280
+ const hasSpread = cacheOptions.getProperties().some((property) => Node56.isSpreadAssignment(property));
13174
13281
  return hasSpread ? "unknown" : "absent";
13175
13282
  }
13176
13283
  function firstArgumentObjectLiteral(construction) {
13177
- if (!Node55.isNewExpression(construction) && !Node55.isCallExpression(construction)) {
13284
+ if (!Node56.isNewExpression(construction) && !Node56.isCallExpression(construction)) {
13178
13285
  return null;
13179
13286
  }
13180
13287
  const arg = construction.getArguments()[0];
13181
- if (arg === void 0 || !Node55.isObjectLiteralExpression(arg)) {
13288
+ if (arg === void 0 || !Node56.isObjectLiteralExpression(arg)) {
13182
13289
  return null;
13183
13290
  }
13184
13291
  return arg;
@@ -13188,10 +13295,10 @@ function propertyValueOf2(options, name) {
13188
13295
  if (property === void 0) {
13189
13296
  return null;
13190
13297
  }
13191
- if (Node55.isPropertyAssignment(property)) {
13298
+ if (Node56.isPropertyAssignment(property)) {
13192
13299
  return property.getInitializer() ?? null;
13193
13300
  }
13194
- if (Node55.isShorthandPropertyAssignment(property)) {
13301
+ if (Node56.isShorthandPropertyAssignment(property)) {
13195
13302
  const symbol = property.getProject().getTypeChecker().getShorthandAssignmentValueSymbol(property);
13196
13303
  return symbol?.getValueDeclaration() ?? null;
13197
13304
  }
@@ -13201,13 +13308,13 @@ function resolveToConstructionOf(expression, cacheClass) {
13201
13308
  let current2 = expression;
13202
13309
  for (let hop = 0; hop < 4 && current2 !== void 0; hop += 1) {
13203
13310
  current2 = unwrapExpression2(current2);
13204
- if (Node55.isVariableDeclaration(current2)) {
13311
+ if (Node56.isVariableDeclaration(current2)) {
13205
13312
  current2 = current2.getInitializer();
13206
13313
  continue;
13207
13314
  }
13208
- if (Node55.isNewExpression(current2) || Node55.isCallExpression(current2)) {
13315
+ if (Node56.isNewExpression(current2) || Node56.isCallExpression(current2)) {
13209
13316
  const callee = current2.getExpression();
13210
- if (callee === void 0 || !Node55.isIdentifier(callee)) {
13317
+ if (callee === void 0 || !Node56.isIdentifier(callee)) {
13211
13318
  return null;
13212
13319
  }
13213
13320
  const local = localImportName(
@@ -13217,11 +13324,11 @@ function resolveToConstructionOf(expression, cacheClass) {
13217
13324
  );
13218
13325
  return local !== null && callee.getText() === local ? current2 : null;
13219
13326
  }
13220
- if (!Node55.isIdentifier(current2)) {
13327
+ if (!Node56.isIdentifier(current2)) {
13221
13328
  return null;
13222
13329
  }
13223
13330
  const declaration = current2.getSymbol()?.getValueDeclaration();
13224
- if (declaration === void 0 || !Node55.isVariableDeclaration(declaration)) {
13331
+ if (declaration === void 0 || !Node56.isVariableDeclaration(declaration)) {
13225
13332
  return null;
13226
13333
  }
13227
13334
  current2 = declaration.getInitializer();
@@ -13232,11 +13339,11 @@ function unwrapExpression2(node) {
13232
13339
  return peelSyntax(node);
13233
13340
  }
13234
13341
  function isConstructionNamed(node, localName) {
13235
- if (!Node55.isNewExpression(node) && !Node55.isCallExpression(node)) {
13342
+ if (!Node56.isNewExpression(node) && !Node56.isCallExpression(node)) {
13236
13343
  return false;
13237
13344
  }
13238
13345
  const callee = node.getExpression();
13239
- return callee !== void 0 && Node55.isIdentifier(callee) && callee.getText() === localName;
13346
+ return callee !== void 0 && Node56.isIdentifier(callee) && callee.getText() === localName;
13240
13347
  }
13241
13348
  function localImportName(sourceFile, importModule, importName) {
13242
13349
  for (const one of namedImportsOf(sourceFile, [importModule], {
@@ -13250,11 +13357,11 @@ function localImportName(sourceFile, importModule, importName) {
13250
13357
  }
13251
13358
  function constructionRef(node, uriProperty, resolution) {
13252
13359
  const optionsArg = node.getArguments()[0];
13253
- if (optionsArg === void 0 || !Node55.isObjectLiteralExpression(optionsArg)) {
13360
+ if (optionsArg === void 0 || !Node56.isObjectLiteralExpression(optionsArg)) {
13254
13361
  return null;
13255
13362
  }
13256
13363
  const property = optionsArg.getProperty(uriProperty);
13257
- if (property === void 0 || !Node55.isPropertyAssignment(property)) {
13364
+ if (property === void 0 || !Node56.isPropertyAssignment(property)) {
13258
13365
  return null;
13259
13366
  }
13260
13367
  const value = property.getInitializer();
@@ -13269,10 +13376,10 @@ function constructionRef(node, uriProperty, resolution) {
13269
13376
  }
13270
13377
 
13271
13378
  // src/discovery/helperIndex.ts
13272
- import { Node as Node57 } from "ts-morph";
13379
+ import { Node as Node58 } from "ts-morph";
13273
13380
 
13274
13381
  // src/discovery/helperReading.ts
13275
- import { Node as Node56 } from "ts-morph";
13382
+ import { Node as Node57 } from "ts-morph";
13276
13383
  var UNREAD = { as: "unread" };
13277
13384
  function readHelperSinks(helper) {
13278
13385
  const positions = parameterPositions(helper);
@@ -13282,11 +13389,11 @@ function readHelperSinks(helper) {
13282
13389
  return sinks;
13283
13390
  }
13284
13391
  body.forEachDescendant((node) => {
13285
- if (!Node56.isCallExpression(node)) {
13392
+ if (!Node57.isCallExpression(node)) {
13286
13393
  return;
13287
13394
  }
13288
13395
  const callee = node.getExpression();
13289
- 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];
13290
13397
  sinks.push({
13291
13398
  method,
13292
13399
  receiver,
@@ -13306,25 +13413,25 @@ function parameterPositions(helper) {
13306
13413
  return positions;
13307
13414
  }
13308
13415
  function readValue(node, positions) {
13309
- if (Node56.isStringLiteral(node) || Node56.isNoSubstitutionTemplateLiteral(node)) {
13416
+ if (Node57.isStringLiteral(node) || Node57.isNoSubstitutionTemplateLiteral(node)) {
13310
13417
  return { as: "text", text: node.getLiteralValue() };
13311
13418
  }
13312
- if (Node56.isTemplateExpression(node)) {
13419
+ if (Node57.isTemplateExpression(node)) {
13313
13420
  return templateText(node, positions);
13314
13421
  }
13315
- if (Node56.isIdentifier(node)) {
13422
+ if (Node57.isIdentifier(node)) {
13316
13423
  const position = positions.get(node.getText());
13317
13424
  return position === void 0 ? UNREAD : { as: "parameter", position };
13318
13425
  }
13319
- if (Node56.isPropertyAccessExpression(node)) {
13426
+ if (Node57.isPropertyAccessExpression(node)) {
13320
13427
  const target = node.getExpression();
13321
- const position = Node56.isIdentifier(target) ? positions.get(target.getText()) : void 0;
13428
+ const position = Node57.isIdentifier(target) ? positions.get(target.getText()) : void 0;
13322
13429
  return position === void 0 ? UNREAD : { as: "parameter", position, property: node.getName() };
13323
13430
  }
13324
- if (Node56.isObjectLiteralExpression(node)) {
13431
+ if (Node57.isObjectLiteralExpression(node)) {
13325
13432
  return objectValue(node, positions);
13326
13433
  }
13327
- if (Node56.isCallExpression(node)) {
13434
+ if (Node57.isCallExpression(node)) {
13328
13435
  return {
13329
13436
  as: "call",
13330
13437
  callee: node.getExpression().getText(),
@@ -13334,13 +13441,13 @@ function readValue(node, positions) {
13334
13441
  return UNREAD;
13335
13442
  }
13336
13443
  function templateText(node, positions) {
13337
- if (!Node56.isTemplateExpression(node)) {
13444
+ if (!Node57.isTemplateExpression(node)) {
13338
13445
  return UNREAD;
13339
13446
  }
13340
13447
  let text = node.getHead().getLiteralText();
13341
13448
  for (const span of node.getTemplateSpans()) {
13342
13449
  const expression = span.getExpression();
13343
- const position = Node56.isIdentifier(expression) ? positions.get(expression.getText()) : void 0;
13450
+ const position = Node57.isIdentifier(expression) ? positions.get(expression.getText()) : void 0;
13344
13451
  if (position === void 0) {
13345
13452
  return UNREAD;
13346
13453
  }
@@ -13349,12 +13456,12 @@ function templateText(node, positions) {
13349
13456
  return { as: "text", text };
13350
13457
  }
13351
13458
  function objectValue(node, positions) {
13352
- if (!Node56.isObjectLiteralExpression(node)) {
13459
+ if (!Node57.isObjectLiteralExpression(node)) {
13353
13460
  return UNREAD;
13354
13461
  }
13355
13462
  const properties = {};
13356
13463
  for (const property of node.getProperties()) {
13357
- if (!Node56.isPropertyAssignment(property)) {
13464
+ if (!Node57.isPropertyAssignment(property)) {
13358
13465
  continue;
13359
13466
  }
13360
13467
  const initializer = property.getInitializer();
@@ -13369,7 +13476,7 @@ function objectValue(node, positions) {
13369
13476
  return { as: "object", properties };
13370
13477
  }
13371
13478
  function propertyKey(name) {
13372
- return Node56.isStringLiteral(name) ? name.getLiteralValue() : name.getText();
13479
+ return Node57.isStringLiteral(name) ? name.getLiteralValue() : name.getText();
13373
13480
  }
13374
13481
 
13375
13482
  // src/discovery/helperIndex.ts
@@ -13499,11 +13606,11 @@ function registrationMatchesOf(pack) {
13499
13606
  }
13500
13607
  function collectHandOffs(sourceFile, subjects, match, resolution, found) {
13501
13608
  sourceFile.forEachDescendant((node) => {
13502
- if (!Node57.isCallExpression(node)) {
13609
+ if (!Node58.isCallExpression(node)) {
13503
13610
  return;
13504
13611
  }
13505
13612
  const callee = node.getExpression();
13506
- if (!Node57.isIdentifier(callee)) {
13613
+ if (!Node58.isIdentifier(callee)) {
13507
13614
  return;
13508
13615
  }
13509
13616
  const handedOver = subjectArgument(node, subjects, match, resolution);
@@ -13518,12 +13625,12 @@ function collectHandOffs(sourceFile, subjects, match, resolution, found) {
13518
13625
  });
13519
13626
  }
13520
13627
  function subjectArgument(call, subjects, match, resolution) {
13521
- if (!Node57.isCallExpression(call)) {
13628
+ if (!Node58.isCallExpression(call)) {
13522
13629
  return -1;
13523
13630
  }
13524
13631
  const args = call.getArguments();
13525
13632
  for (const [position, argument] of args.entries()) {
13526
- if (!Node57.isIdentifier(argument) && !Node57.isPropertyAccessExpression(argument)) {
13633
+ if (!Node58.isIdentifier(argument) && !Node58.isPropertyAccessExpression(argument)) {
13527
13634
  continue;
13528
13635
  }
13529
13636
  if (subjectNodeFor(argument, subjects, match, resolution) !== void 0) {
@@ -13582,10 +13689,10 @@ function declaredFunctions(sourceFile) {
13582
13689
  found.push([name, declaration]);
13583
13690
  }
13584
13691
  }
13585
- for (const variable4 of sourceFile.getVariableDeclarations()) {
13586
- const initializer = variable4.getInitializer();
13587
- if (initializer !== void 0 && (Node57.isArrowFunction(initializer) || Node57.isFunctionExpression(initializer))) {
13588
- 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]);
13589
13696
  }
13590
13697
  }
13591
13698
  return found;
@@ -13679,7 +13786,7 @@ function recordEdge(edgesByChild, candidate) {
13679
13786
  }
13680
13787
 
13681
13788
  // src/discovery/wrapperIndex.ts
13682
- import { Node as Node58 } from "ts-morph";
13789
+ import { Node as Node59 } from "ts-morph";
13683
13790
  import { joinMountedPath as joinMountedPath3 } from "@suss/resolution";
13684
13791
  var NO_WRAPPERS = {
13685
13792
  wrappersFor: () => [],
@@ -13803,11 +13910,11 @@ function discoverWrapperRegistrations(sourceFile, pattern, match, wraps, resolut
13803
13910
  const candidates = [];
13804
13911
  const unresolved = [];
13805
13912
  sourceFile.forEachDescendant((node) => {
13806
- if (!Node58.isCallExpression(node)) {
13913
+ if (!Node59.isCallExpression(node)) {
13807
13914
  return;
13808
13915
  }
13809
13916
  const callee = node.getExpression();
13810
- if (!Node58.isPropertyAccessExpression(callee) || callee.getName() !== wraps.method) {
13917
+ if (!Node59.isPropertyAccessExpression(callee) || callee.getName() !== wraps.method) {
13811
13918
  return;
13812
13919
  }
13813
13920
  const subjectNode = subjectNodeFor(
@@ -13902,7 +14009,7 @@ function discoverConstructorOptions(sourceFile, pattern, wraps, subjects, resolu
13902
14009
  return { candidates, unresolved };
13903
14010
  }
13904
14011
  function constructorOptionOf(construction, wraps, resolution) {
13905
- if (!(Node58.isNewExpression(construction) || Node58.isCallExpression(construction))) {
14012
+ if (!(Node59.isNewExpression(construction) || Node59.isCallExpression(construction))) {
13906
14013
  return void 0;
13907
14014
  }
13908
14015
  const optionsArg = construction.getArguments()[wraps.targetPosition];
@@ -13932,6 +14039,7 @@ function candidateOf(registration, pattern, sourceFile) {
13932
14039
  reference: {
13933
14040
  file: target.getSourceFile().getFilePath(),
13934
14041
  name: named2 ? functionNameOrAnon(target) : label,
14042
+ ...named2 ? {} : { line: target.getStartLineNumber() },
13935
14043
  ...onThrow ? { onThrow: true } : {},
13936
14044
  ...scope === void 0 ? {} : { scope }
13937
14045
  }
@@ -13940,37 +14048,6 @@ function candidateOf(registration, pattern, sourceFile) {
13940
14048
  function labelFor(targetArg, wraps) {
13941
14049
  return factoryNameOf(targetArg) ?? wraps.method;
13942
14050
  }
13943
- function factoryNameOf(targetArg) {
13944
- const written = factKeyOf(targetArg);
13945
- if (!Node58.isCallExpression(written)) {
13946
- return void 0;
13947
- }
13948
- const callee = written.getExpression();
13949
- if (Node58.isIdentifier(callee)) {
13950
- return callee.getText();
13951
- }
13952
- if (Node58.isPropertyAccessExpression(callee)) {
13953
- return callee.getName();
13954
- }
13955
- return void 0;
13956
- }
13957
- function factoryStopOf(targetArg) {
13958
- const written = factKeyOf(targetArg);
13959
- if (!Node58.isCallExpression(written)) {
13960
- return null;
13961
- }
13962
- const callee = factoryNameOf(targetArg);
13963
- if (callee === void 0) {
13964
- return null;
13965
- }
13966
- const reason = classifyStop(
13967
- declarationsBehind(written.getExpression().getSymbol())
13968
- );
13969
- if (!worthRecording(reason)) {
13970
- return null;
13971
- }
13972
- return { callee, reason: "unresolvedWrapper" };
13973
- }
13974
14051
  function mountedAt(subjectId, mountPrefixes, scope) {
13975
14052
  const prefix = mountPrefixes?.prefixForId?.(subjectId) ?? "";
13976
14053
  return joinMountedPath3(prefix, scope);
@@ -13987,7 +14064,7 @@ function scopeOf(args, wraps, resolution) {
13987
14064
  }
13988
14065
 
13989
14066
  // src/discoveryContext.ts
13990
- import { Node as Node59 } from "ts-morph";
14067
+ import { Node as Node60 } from "ts-morph";
13991
14068
  function createTsDiscoveryContext(resolution) {
13992
14069
  const store = resolution ?? new ResolutionStore();
13993
14070
  return {
@@ -14022,7 +14099,7 @@ function exportedFunctions(sourceFile, resolution) {
14022
14099
  return out;
14023
14100
  }
14024
14101
  function exportedFunction(decl, resolution) {
14025
- const writtenAgain = Node59.isVariableDeclaration(decl) && isWrittenAgain(decl);
14102
+ const writtenAgain = Node60.isVariableDeclaration(decl) && isWrittenAgain(decl);
14026
14103
  if (!writtenAgain) {
14027
14104
  const declared = resolveDeclarationToFunction(decl);
14028
14105
  if (declared !== null) {
@@ -14043,7 +14120,7 @@ function valueToAskAbout(decl, writtenAgain) {
14043
14120
  if (writtenAgain) {
14044
14121
  return decl;
14045
14122
  }
14046
- const value = Node59.isVariableDeclaration(decl) ? decl.getInitializer() ?? decl : decl;
14123
+ const value = Node60.isVariableDeclaration(decl) ? decl.getInitializer() ?? decl : decl;
14047
14124
  return couldStillNameAFunction(value) ? value : null;
14048
14125
  }
14049
14126
  function resolveDeclarationToFunction(decl) {
@@ -14051,18 +14128,18 @@ function resolveDeclarationToFunction(decl) {
14051
14128
  if (fn !== null) {
14052
14129
  return fn;
14053
14130
  }
14054
- if (Node59.isVariableDeclaration(decl)) {
14131
+ if (Node60.isVariableDeclaration(decl)) {
14055
14132
  const init = decl.getInitializer();
14056
- if (init !== void 0 && (Node59.isArrowFunction(init) || Node59.isFunctionExpression(init))) {
14133
+ if (init !== void 0 && (Node60.isArrowFunction(init) || Node60.isFunctionExpression(init))) {
14057
14134
  return init;
14058
14135
  }
14059
14136
  }
14060
14137
  return null;
14061
14138
  }
14062
14139
  function hasJsxReturn(func) {
14063
- if (Node59.isArrowFunction(func)) {
14140
+ if (Node60.isArrowFunction(func)) {
14064
14141
  const body2 = func.getBody();
14065
- if (Node59.isExpression(body2) && isJsxOrFragment(body2)) {
14142
+ if (Node60.isExpression(body2) && isJsxOrFragment(body2)) {
14066
14143
  return true;
14067
14144
  }
14068
14145
  }
@@ -14076,11 +14153,11 @@ function hasJsxReturn(func) {
14076
14153
  traversal.stop();
14077
14154
  return;
14078
14155
  }
14079
- 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))) {
14080
14157
  traversal.skip();
14081
14158
  return;
14082
14159
  }
14083
- if (Node59.isReturnStatement(node)) {
14160
+ if (Node60.isReturnStatement(node)) {
14084
14161
  const expr = node.getExpression();
14085
14162
  if (expr !== void 0 && isJsxOrFragment(expr)) {
14086
14163
  found = true;
@@ -14091,7 +14168,7 @@ function hasJsxReturn(func) {
14091
14168
  }
14092
14169
  function isJsxOrFragment(node) {
14093
14170
  const current2 = peelParens(node);
14094
- return Node59.isJsxElement(current2) || Node59.isJsxSelfClosingElement(current2) || Node59.isJsxFragment(current2);
14171
+ return Node60.isJsxElement(current2) || Node60.isJsxSelfClosingElement(current2) || Node60.isJsxFragment(current2);
14095
14172
  }
14096
14173
 
14097
14174
  // src/graphqlContract.ts
@@ -14217,132 +14294,10 @@ function createReferenceIndex(sourceFiles) {
14217
14294
  };
14218
14295
  }
14219
14296
 
14220
- // src/resolve/boundaryEffects.ts
14221
- import { evaluate as evaluate3, lit as lit3, rule as rule3, variable } from "@suss/datalog";
14222
- var EFFECT_RULES = [
14223
- rule3(
14224
- "reachFrom",
14225
- [variable("e"), variable("e")],
14226
- [lit3("entry", variable("e"))]
14227
- ),
14228
- rule3(
14229
- "reachFrom",
14230
- [variable("e"), variable("v")],
14231
- [
14232
- lit3("reachFrom", variable("e"), variable("u")),
14233
- lit3("calls", variable("u"), variable("v"))
14234
- ]
14235
- ),
14236
- rule3(
14237
- "boundaryEffect",
14238
- [variable("e"), variable("kind"), variable("target")],
14239
- [
14240
- lit3("reachFrom", variable("e"), variable("u")),
14241
- lit3("unitEffect", variable("u"), variable("kind"), variable("target"))
14242
- ]
14243
- )
14244
- ];
14245
- function bindingLabel(binding) {
14246
- const semantics = binding.semantics;
14247
- if (semantics.name === "rest") {
14248
- return `${semantics.method} ${semantics.path}`;
14249
- }
14250
- if (semantics.name === "storage") {
14251
- return `${semantics.storageSystem}:${semantics.container}`;
14252
- }
14253
- if (semantics.name === "message-bus") {
14254
- return `${semantics.messageBus}:${semantics.channel}`;
14255
- }
14256
- if (semantics.name === "runtime-config") {
14257
- return semantics.instanceName;
14258
- }
14259
- if (semantics.name === "graphql-resolver") {
14260
- return `${semantics.typeName}.${semantics.fieldName}`;
14261
- }
14262
- if (semantics.name === "graphql-operation") {
14263
- return `${semantics.operationType} ${semantics.operationName ?? ""}`.trim();
14264
- }
14265
- if ("exportName" in semantics || "module" in semantics) {
14266
- return semantics.exportName ?? semantics.module ?? binding.recognition;
14267
- }
14268
- if ("instanceName" in semantics && semantics.instanceName !== null) {
14269
- return `${semantics.deploymentTarget}:${semantics.instanceName}`;
14270
- }
14271
- return binding.recognition;
14272
- }
14273
- function effectFact(effect) {
14274
- if (effect.type === "invocation") {
14275
- return { kind: "invocation", target: effect.callee };
14276
- }
14277
- if (effect.type === "mutation") {
14278
- return { kind: "mutation", target: `${effect.operation}:${effect.target}` };
14279
- }
14280
- if (effect.type === "emission") {
14281
- return { kind: "emission", target: effect.event };
14282
- }
14283
- if (effect.type === "stateChange") {
14284
- return { kind: "stateChange", target: effect.variable };
14285
- }
14286
- if (effect.type === "interaction") {
14287
- return { kind: "interaction", target: bindingLabel(effect.binding) };
14288
- }
14289
- return null;
14290
- }
14291
- function deriveBoundaryEffects(summaries, facts) {
14292
- const { db, unitKeyBySummary } = facts;
14293
- for (const summary of summaries) {
14294
- const key = unitKeyBySummary.get(summary);
14295
- if (key === void 0) {
14296
- continue;
14297
- }
14298
- for (const transition of summary.transitions) {
14299
- for (const effect of transition.effects) {
14300
- const fact2 = effectFact(effect);
14301
- if (fact2 !== null) {
14302
- db.add("unitEffect", [key, fact2.kind, fact2.target]);
14303
- }
14304
- }
14305
- }
14306
- }
14307
- evaluate3(db, EFFECT_RULES);
14308
- const ownByEntry = /* @__PURE__ */ new Map();
14309
- for (const [unit, kind, target] of db.facts("unitEffect")) {
14310
- const bucket = ownByEntry.get(String(unit)) ?? /* @__PURE__ */ new Set();
14311
- bucket.add(`${kind}\0${target}`);
14312
- ownByEntry.set(String(unit), bucket);
14313
- }
14314
- const closureByEntry = /* @__PURE__ */ new Map();
14315
- for (const [entry, kind, target] of db.facts("boundaryEffect")) {
14316
- const entryKey2 = String(entry);
14317
- const bucket = closureByEntry.get(entryKey2) ?? [];
14318
- bucket.push({
14319
- kind: String(kind),
14320
- target: String(target),
14321
- transitive: !(ownByEntry.get(entryKey2)?.has(`${kind}\0${target}`) ?? false)
14322
- });
14323
- closureByEntry.set(entryKey2, bucket);
14324
- }
14325
- for (const summary of summaries) {
14326
- const key = unitKeyBySummary.get(summary);
14327
- if (key === void 0 || !db.has("entry", [key])) {
14328
- continue;
14329
- }
14330
- const effects = closureByEntry.get(key);
14331
- if (effects === void 0 || effects.length === 0) {
14332
- continue;
14333
- }
14334
- const sorted = [...effects].sort(
14335
- (a, b) => `${a.kind}:${a.target}`.localeCompare(`${b.kind}:${b.target}`)
14336
- );
14337
- summary.metadata = { ...summary.metadata, effectsClosure: sorted };
14338
- }
14339
- return summaries;
14340
- }
14341
-
14342
14297
  // src/resolve/reachableClosure.ts
14343
- import { Node as Node60 } from "ts-morph";
14298
+ import { Node as Node61 } from "ts-morph";
14344
14299
  import { functionCallBinding, TargetPlacements } from "@suss/behavioral-ir";
14345
- 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";
14346
14301
  import { assembleSummary as assembleSummary2 } from "@suss/extractor";
14347
14302
  var GENERIC_TERMINALS = [
14348
14303
  { kind: "return", match: { type: "returnStatement" }, extraction: {} },
@@ -14373,7 +14328,7 @@ function targetOf(node) {
14373
14328
  };
14374
14329
  }
14375
14330
  function resolveCallee(call, calleeName, scan) {
14376
- if (!Node60.isCallExpression(call)) {
14331
+ if (!Node61.isCallExpression(call)) {
14377
14332
  return null;
14378
14333
  }
14379
14334
  const callee = call.getExpression();
@@ -14386,7 +14341,7 @@ function resolveCallee(call, calleeName, scan) {
14386
14341
  }
14387
14342
  }
14388
14343
  const resolveSources = scan.resolveCallableSources;
14389
- if (resolveSources !== void 0 && Node60.isPropertyAccessExpression(callee) && declarations.some(isDeclaredShape)) {
14344
+ if (resolveSources !== void 0 && Node61.isPropertyAccessExpression(callee) && declarations.some(isDeclaredShape)) {
14390
14345
  const sources = resolveSources(callee, scan.reachedFrom);
14391
14346
  const only = sources.length === 1 ? sources[0] : void 0;
14392
14347
  const resolved = only === void 0 ? null : resolveDecl(only, calleeName);
@@ -14432,11 +14387,11 @@ function passedPositionKey(target, position) {
14432
14387
  return `${offsetKeyFor(target.file, target.span)}#${position}`;
14433
14388
  }
14434
14389
  function resolveJsxReference(node, scan) {
14435
- if (!Node60.isJsxOpeningElement(node) && !Node60.isJsxSelfClosingElement(node)) {
14390
+ if (!Node61.isJsxOpeningElement(node) && !Node61.isJsxSelfClosingElement(node)) {
14436
14391
  return null;
14437
14392
  }
14438
14393
  const tag = node.getTagNameNode();
14439
- if (!Node60.isIdentifier(tag) || !/^[A-Z]/.test(tag.getText())) {
14394
+ if (!Node61.isIdentifier(tag) || !/^[A-Z]/.test(tag.getText())) {
14440
14395
  return null;
14441
14396
  }
14442
14397
  const name = tag.getText();
@@ -14482,12 +14437,12 @@ function collectReachable(func, scan) {
14482
14437
  candidates.push(outcome.candidate);
14483
14438
  };
14484
14439
  const recordPassedArgs = (call, calleeText, calleeOutcome) => {
14485
- if (!Node60.isCallExpression(call)) {
14440
+ if (!Node61.isCallExpression(call)) {
14486
14441
  return;
14487
14442
  }
14488
14443
  const calleeTarget = declaredAtOf(calleeOutcome);
14489
14444
  call.getArguments().forEach((arg, position) => {
14490
- if (!Node60.isIdentifier(arg)) {
14445
+ if (!Node61.isIdentifier(arg)) {
14491
14446
  return;
14492
14447
  }
14493
14448
  const resolved = functionTargetOf(arg);
@@ -14507,7 +14462,7 @@ function collectReachable(func, scan) {
14507
14462
  record2(jsx.outcome);
14508
14463
  return;
14509
14464
  }
14510
- if (!Node60.isCallExpression(node)) {
14465
+ if (!Node61.isCallExpression(node)) {
14511
14466
  return;
14512
14467
  }
14513
14468
  const calleeText = normalizeCallee(node.getExpression().getText());
@@ -14559,13 +14514,13 @@ function extractReachableSummary(candidate, options, recognizers) {
14559
14514
  return assembleSummary2(raw, options);
14560
14515
  }
14561
14516
  var REACHABLE_RULES = [
14562
- rule4("reachable", [variable2("f")], [lit4("entry", variable2("f"))]),
14563
- rule4(
14517
+ rule3("reachable", [variable("f")], [lit3("entry", variable("f"))]),
14518
+ rule3(
14564
14519
  "reachable",
14565
- [variable2("g")],
14520
+ [variable("g")],
14566
14521
  [
14567
- lit4("reachable", variable2("f")),
14568
- lit4("calls", variable2("f"), variable2("g"))
14522
+ lit3("reachable", variable("f")),
14523
+ lit3("calls", variable("f"), variable("g"))
14569
14524
  ]
14570
14525
  )
14571
14526
  ];
@@ -14593,7 +14548,7 @@ function recognizerOnlyRoots(packsByFile) {
14593
14548
  }
14594
14549
  for (const declaration of variableStatement.getDeclarations()) {
14595
14550
  const init = declaration.getInitializer();
14596
- 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)) {
14597
14552
  roots.push({ func: init, name: declaration.getName() });
14598
14553
  }
14599
14554
  }
@@ -14642,7 +14597,7 @@ function expandReachableClosure(seeds, project, options, projectFileSet, facts,
14642
14597
  }
14643
14598
  }
14644
14599
  for (; ; ) {
14645
- evaluate4(db, REACHABLE_RULES);
14600
+ evaluate3(db, REACHABLE_RULES);
14646
14601
  const frontier = db.facts("reachable").map(([key]) => String(key)).filter((key) => !scanned.has(key));
14647
14602
  if (frontier.length === 0) {
14648
14603
  break;
@@ -14847,21 +14802,21 @@ function recordParameterGaps(parameterCallsByKey, summariesByKey, passedPosition
14847
14802
  }
14848
14803
 
14849
14804
  // src/resolve/rethrowEnrichment.ts
14850
- import { Node as Node61 } from "ts-morph";
14851
- 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";
14852
14807
  var RETHROW_RULES = [
14853
- rule5(
14808
+ rule4(
14854
14809
  "contributes",
14855
- [variable3("u"), variable3("s")],
14856
- [lit5("throwsDirect", variable3("u"), variable3("s"))]
14810
+ [variable2("u"), variable2("s")],
14811
+ [lit4("throwsDirect", variable2("u"), variable2("s"))]
14857
14812
  ),
14858
- rule5(
14813
+ rule4(
14859
14814
  "contributes",
14860
- [variable3("u"), variable3("s")],
14815
+ [variable2("u"), variable2("s")],
14861
14816
  [
14862
- lit5("rethrowSite", variable3("u"), variable3("site")),
14863
- lit5("siteCalls", variable3("site"), variable3("c")),
14864
- 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"))
14865
14820
  ]
14866
14821
  )
14867
14822
  ];
@@ -14923,7 +14878,7 @@ function enrichRethrows(summaries, project, facts) {
14923
14878
  }
14924
14879
  }
14925
14880
  }
14926
- evaluate5(db, RETHROW_RULES);
14881
+ evaluate4(db, RETHROW_RULES);
14927
14882
  const contributesByUnit = /* @__PURE__ */ new Map();
14928
14883
  for (const [unit, sourceId] of db.facts("contributes")) {
14929
14884
  const bucket = contributesByUnit.get(String(unit));
@@ -14984,7 +14939,7 @@ function findBareRethrow(func, location) {
14984
14939
  traversal.stop();
14985
14940
  return;
14986
14941
  }
14987
- if (!Node61.isThrowStatement(node)) {
14942
+ if (!Node62.isThrowStatement(node)) {
14988
14943
  return;
14989
14944
  }
14990
14945
  if (startLineOf(node) !== location.start) {
@@ -14994,7 +14949,7 @@ function findBareRethrow(func, location) {
14994
14949
  return;
14995
14950
  }
14996
14951
  const thrown = node.getExpression();
14997
- if (thrown !== void 0 && Node61.isIdentifier(thrown)) {
14952
+ if (thrown !== void 0 && Node62.isIdentifier(thrown)) {
14998
14953
  found = node;
14999
14954
  }
15000
14955
  });
@@ -15004,13 +14959,13 @@ function enclosingTry(throwStmt) {
15004
14959
  let current2 = throwStmt.getParent();
15005
14960
  let sawCatchClause = false;
15006
14961
  while (current2 !== void 0) {
15007
- if (Node61.isCatchClause(current2)) {
14962
+ if (Node62.isCatchClause(current2)) {
15008
14963
  sawCatchClause = true;
15009
14964
  }
15010
- if (Node61.isTryStatement(current2)) {
14965
+ if (Node62.isTryStatement(current2)) {
15011
14966
  return sawCatchClause ? current2 : null;
15012
14967
  }
15013
- 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)) {
15014
14969
  return null;
15015
14970
  }
15016
14971
  current2 = current2.getParent();
@@ -15018,14 +14973,14 @@ function enclosingTry(throwStmt) {
15018
14973
  return null;
15019
14974
  }
15020
14975
  function collectTryBodyCallees(tryStmt, index, keyFor) {
15021
- if (!Node61.isTryStatement(tryStmt)) {
14976
+ if (!Node62.isTryStatement(tryStmt)) {
15022
14977
  return [];
15023
14978
  }
15024
14979
  const tryBlock = tryStmt.getTryBlock();
15025
14980
  const callees = [];
15026
14981
  const seen = /* @__PURE__ */ new Set();
15027
14982
  tryBlock.forEachDescendant((node) => {
15028
- if (!Node61.isCallExpression(node)) {
14983
+ if (!Node62.isCallExpression(node)) {
15029
14984
  return;
15030
14985
  }
15031
14986
  const calleeSummary = resolveCalleeSummary(node, index);
@@ -15042,7 +14997,7 @@ function collectTryBodyCallees(tryStmt, index, keyFor) {
15042
14997
  return callees;
15043
14998
  }
15044
14999
  function resolveCalleeSummary(call, index) {
15045
- if (!Node61.isCallExpression(call)) {
15000
+ if (!Node62.isCallExpression(call)) {
15046
15001
  return null;
15047
15002
  }
15048
15003
  const callee = call.getExpression();
@@ -15072,12 +15027,12 @@ function resolveCalleeSummary(call, index) {
15072
15027
  return null;
15073
15028
  }
15074
15029
  function functionFromDecl(decl) {
15075
- 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)) {
15076
15031
  return decl;
15077
15032
  }
15078
- if (Node61.isVariableDeclaration(decl)) {
15033
+ if (Node62.isVariableDeclaration(decl)) {
15079
15034
  const init = decl.getInitializer();
15080
- if (init !== void 0 && (Node61.isArrowFunction(init) || Node61.isFunctionExpression(init))) {
15035
+ if (init !== void 0 && (Node62.isArrowFunction(init) || Node62.isFunctionExpression(init))) {
15081
15036
  return init;
15082
15037
  }
15083
15038
  }
@@ -15086,23 +15041,23 @@ function functionFromDecl(decl) {
15086
15041
 
15087
15042
  // src/shapes/fieldAccesses.ts
15088
15043
  import {
15089
- Node as Node62
15044
+ Node as Node63
15090
15045
  } from "ts-morph";
15091
15046
  function findResponseAccessor(callExpr) {
15092
15047
  let current2 = callExpr;
15093
15048
  const parent1 = current2.getParent();
15094
- if (parent1 !== void 0 && Node62.isAwaitExpression(parent1)) {
15049
+ if (parent1 !== void 0 && Node63.isAwaitExpression(parent1)) {
15095
15050
  current2 = parent1;
15096
15051
  }
15097
15052
  const parent2 = current2.getParent();
15098
- if (parent2 === void 0 || !Node62.isVariableDeclaration(parent2)) {
15053
+ if (parent2 === void 0 || !Node63.isVariableDeclaration(parent2)) {
15099
15054
  return null;
15100
15055
  }
15101
15056
  const nameNode = parent2.getNameNode();
15102
- if (Node62.isIdentifier(nameNode)) {
15057
+ if (Node63.isIdentifier(nameNode)) {
15103
15058
  return { kind: "identifier", name: nameNode.getText() };
15104
15059
  }
15105
- if (Node62.isObjectBindingPattern(nameNode)) {
15060
+ if (Node63.isObjectBindingPattern(nameNode)) {
15106
15061
  const bindings = /* @__PURE__ */ new Map();
15107
15062
  for (const element of nameNode.getElements()) {
15108
15063
  if (element.getDotDotDotToken() !== void 0) {
@@ -15123,11 +15078,11 @@ function findResponseAccessor(callExpr) {
15123
15078
  function buildThenChainAccessor(callExpr, func) {
15124
15079
  const bindings = /* @__PURE__ */ new Map();
15125
15080
  func.forEachDescendant((node) => {
15126
- if (!Node62.isParameterDeclaration(node)) {
15081
+ if (!Node63.isParameterDeclaration(node)) {
15127
15082
  return;
15128
15083
  }
15129
15084
  const nameNode = node.getNameNode();
15130
- if (!Node62.isIdentifier(nameNode)) {
15085
+ if (!Node63.isIdentifier(nameNode)) {
15131
15086
  return;
15132
15087
  }
15133
15088
  const prefix = prefixOfThenParam(node, callExpr, 0);
@@ -15159,7 +15114,7 @@ function prefixOfExpr(expr, responseCall, depth) {
15159
15114
  if (node === responseCall) {
15160
15115
  return [];
15161
15116
  }
15162
- if (Node62.isCallExpression(node)) {
15117
+ if (Node63.isCallExpression(node)) {
15163
15118
  const hop = thenLikeCall(node);
15164
15119
  if (hop !== null) {
15165
15120
  if (hop.method === "catch") {
@@ -15191,14 +15146,14 @@ function prefixOfMemberExpr(expr, responseCall, depth) {
15191
15146
  return null;
15192
15147
  }
15193
15148
  const decl = chain.root.getSymbol()?.getDeclarations()?.[0];
15194
- if (decl === void 0 || !Node62.isParameterDeclaration(decl)) {
15149
+ if (decl === void 0 || !Node63.isParameterDeclaration(decl)) {
15195
15150
  return null;
15196
15151
  }
15197
15152
  const base = prefixOfThenParam(decl, responseCall, depth + 1);
15198
15153
  return base === null ? null : [...base, ...chain.segments];
15199
15154
  }
15200
15155
  function firstCallbackParamName(callback) {
15201
- if (callback === void 0 || !(Node62.isArrowFunction(callback) || Node62.isFunctionExpression(callback))) {
15156
+ if (callback === void 0 || !(Node63.isArrowFunction(callback) || Node63.isFunctionExpression(callback))) {
15202
15157
  return null;
15203
15158
  }
15204
15159
  const param = callback.getParameters()[0];
@@ -15206,11 +15161,11 @@ function firstCallbackParamName(callback) {
15206
15161
  return null;
15207
15162
  }
15208
15163
  const nameNode = param.getNameNode();
15209
- return Node62.isIdentifier(nameNode) ? nameNode.getText() : null;
15164
+ return Node63.isIdentifier(nameNode) ? nameNode.getText() : null;
15210
15165
  }
15211
15166
  function unwrap(expr) {
15212
15167
  let node = expr;
15213
- while (Node62.isAwaitExpression(node) || Node62.isParenthesizedExpression(node) || Node62.isAsExpression(node)) {
15168
+ while (Node63.isAwaitExpression(node) || Node63.isParenthesizedExpression(node) || Node63.isAsExpression(node)) {
15214
15169
  node = node.getExpression();
15215
15170
  }
15216
15171
  return node;
@@ -15220,15 +15175,15 @@ function chainRootedAt(expr, rootName) {
15220
15175
  if (chain === null) {
15221
15176
  return null;
15222
15177
  }
15223
- 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;
15224
15179
  }
15225
15180
  function memberChain(expr) {
15226
- let node = Node62.isExpression(expr) ? unwrap(expr) : expr;
15227
- if (Node62.isCallExpression(node)) {
15181
+ let node = Node63.isExpression(expr) ? unwrap(expr) : expr;
15182
+ if (Node63.isCallExpression(node)) {
15228
15183
  node = node.getExpression();
15229
15184
  }
15230
15185
  const segments = [];
15231
- while (Node62.isPropertyAccessExpression(node)) {
15186
+ while (Node63.isPropertyAccessExpression(node)) {
15232
15187
  segments.unshift(node.getName());
15233
15188
  node = node.getExpression();
15234
15189
  }
@@ -15247,16 +15202,16 @@ function collectPropertyAccesses(subtree, accessor) {
15247
15202
  if (accessor.kind === "identifier") {
15248
15203
  const varName = accessor.name;
15249
15204
  subtree.forEachDescendant((node) => {
15250
- if (!Node62.isPropertyAccessExpression(node)) {
15205
+ if (!Node63.isPropertyAccessExpression(node)) {
15251
15206
  return;
15252
15207
  }
15253
15208
  const chain = [];
15254
15209
  let current2 = node;
15255
- while (Node62.isPropertyAccessExpression(current2)) {
15210
+ while (Node63.isPropertyAccessExpression(current2)) {
15256
15211
  chain.unshift(current2.getName());
15257
15212
  current2 = current2.getExpression();
15258
15213
  }
15259
- if (Node62.isIdentifier(current2) && current2.getText() === varName) {
15214
+ if (Node63.isIdentifier(current2) && current2.getText() === varName) {
15260
15215
  pushChain(chain);
15261
15216
  }
15262
15217
  });
@@ -15267,7 +15222,7 @@ function collectPropertyAccesses(subtree, accessor) {
15267
15222
  return source === void 0 ? void 0 : [source];
15268
15223
  } : (name) => accessor.bindings.get(name);
15269
15224
  subtree.forEachDescendant((node) => {
15270
- if (!Node62.isIdentifier(node)) {
15225
+ if (!Node63.isIdentifier(node)) {
15271
15226
  return;
15272
15227
  }
15273
15228
  const prefix = prefixOf(node.getText());
@@ -15279,13 +15234,13 @@ function collectPropertyAccesses(subtree, accessor) {
15279
15234
  }
15280
15235
  let chainTop = node;
15281
15236
  let parent = chainTop.getParent();
15282
- while (parent !== void 0 && Node62.isPropertyAccessExpression(parent) && parent.getExpression() === chainTop) {
15237
+ while (parent !== void 0 && Node63.isPropertyAccessExpression(parent) && parent.getExpression() === chainTop) {
15283
15238
  chainTop = parent;
15284
15239
  parent = chainTop.getParent();
15285
15240
  }
15286
15241
  const segments = [];
15287
15242
  let current2 = chainTop;
15288
- while (Node62.isPropertyAccessExpression(current2)) {
15243
+ while (Node63.isPropertyAccessExpression(current2)) {
15289
15244
  segments.push(current2.getName());
15290
15245
  current2 = current2.getExpression();
15291
15246
  }
@@ -15299,15 +15254,15 @@ function isBindingDeclarationSite(node) {
15299
15254
  return true;
15300
15255
  }
15301
15256
  const parent = node.getParent();
15302
- return parent !== void 0 && Node62.isParameterDeclaration(parent) && parent.getNameNode() === node;
15257
+ return parent !== void 0 && Node63.isParameterDeclaration(parent) && parent.getNameNode() === node;
15303
15258
  }
15304
15259
  function isInsideObjectBindingPattern(node) {
15305
15260
  let current2 = node.getParent();
15306
15261
  while (current2 !== void 0) {
15307
- if (Node62.isObjectBindingPattern(current2)) {
15262
+ if (Node63.isObjectBindingPattern(current2)) {
15308
15263
  return true;
15309
15264
  }
15310
- if (Node62.isFunctionLikeDeclaration(current2) || Node62.isVariableStatement(current2)) {
15265
+ if (Node63.isFunctionLikeDeclaration(current2) || Node63.isVariableStatement(current2)) {
15311
15266
  break;
15312
15267
  }
15313
15268
  current2 = current2.getParent();
@@ -15370,7 +15325,7 @@ function findBranchSubtree(func, byLineRange, terminalStartLine, terminalEndLine
15370
15325
  if (parent === void 0) {
15371
15326
  break;
15372
15327
  }
15373
- if (Node62.isIfStatement(parent)) {
15328
+ if (Node63.isIfStatement(parent)) {
15374
15329
  const ifStmt = parent;
15375
15330
  const thenBlock = ifStmt.getThenStatement();
15376
15331
  const elseBlock = ifStmt.getElseStatement();
@@ -15433,7 +15388,7 @@ function buildNonBodyPropertySet(semantics) {
15433
15388
 
15434
15389
  // src/subUnitContext.ts
15435
15390
  import {
15436
- Node as Node63
15391
+ Node as Node64
15437
15392
  } from "ts-morph";
15438
15393
  function createTsSubUnitContext() {
15439
15394
  return {
@@ -15461,18 +15416,18 @@ function findJsxAttributes(parent) {
15461
15416
  if (skip(node, traversal)) {
15462
15417
  return;
15463
15418
  }
15464
- if (!Node63.isJsxOpeningElement(node) && !Node63.isJsxSelfClosingElement(node)) {
15419
+ if (!Node64.isJsxOpeningElement(node) && !Node64.isJsxSelfClosingElement(node)) {
15465
15420
  return;
15466
15421
  }
15467
15422
  const tag = node.getTagNameNode().getText();
15468
15423
  for (const attr of node.getAttributes()) {
15469
- if (!Node63.isJsxAttribute(attr)) {
15424
+ if (!Node64.isJsxAttribute(attr)) {
15470
15425
  continue;
15471
15426
  }
15472
15427
  const initializer = attr.getInitializer();
15473
15428
  let valueExpression = null;
15474
15429
  if (initializer !== void 0) {
15475
- if (Node63.isJsxExpression(initializer)) {
15430
+ if (Node64.isJsxExpression(initializer)) {
15476
15431
  const inner = initializer.getExpression();
15477
15432
  valueExpression = inner ?? null;
15478
15433
  } else {
@@ -15495,11 +15450,11 @@ function findCallExpressionsByName(parent, name) {
15495
15450
  if (skip(node, traversal)) {
15496
15451
  return;
15497
15452
  }
15498
- if (!Node63.isCallExpression(node)) {
15453
+ if (!Node64.isCallExpression(node)) {
15499
15454
  return;
15500
15455
  }
15501
15456
  const callee = node.getExpression();
15502
- if (Node63.isIdentifier(callee) && callee.getText() === name) {
15457
+ if (Node64.isIdentifier(callee) && callee.getText() === name) {
15503
15458
  out.push(node);
15504
15459
  }
15505
15460
  });
@@ -15510,10 +15465,10 @@ function resolveAttributeValueFunction(attr, parent) {
15510
15465
  if (expr === null) {
15511
15466
  return null;
15512
15467
  }
15513
- if (Node63.isArrowFunction(expr) || Node63.isFunctionExpression(expr)) {
15468
+ if (Node64.isArrowFunction(expr) || Node64.isFunctionExpression(expr)) {
15514
15469
  return { func: expr, localName: null };
15515
15470
  }
15516
- if (Node63.isIdentifier(expr)) {
15471
+ if (Node64.isIdentifier(expr)) {
15517
15472
  const symbol = expr.getSymbol();
15518
15473
  if (symbol === void 0) {
15519
15474
  return null;
@@ -15532,15 +15487,15 @@ function resolveAttributeValueFunction(attr, parent) {
15532
15487
  return null;
15533
15488
  }
15534
15489
  function tryExtractFunction(decl) {
15535
- if (Node63.isFunctionDeclaration(decl)) {
15490
+ if (Node64.isFunctionDeclaration(decl)) {
15536
15491
  return decl;
15537
15492
  }
15538
- if (Node63.isVariableDeclaration(decl)) {
15493
+ if (Node64.isVariableDeclaration(decl)) {
15539
15494
  const init = decl.getInitializer();
15540
15495
  if (init === void 0) {
15541
15496
  return null;
15542
15497
  }
15543
- if (Node63.isArrowFunction(init) || Node63.isFunctionExpression(init)) {
15498
+ if (Node64.isArrowFunction(init) || Node64.isFunctionExpression(init)) {
15544
15499
  return init;
15545
15500
  }
15546
15501
  }
@@ -15561,7 +15516,7 @@ function getCallArgumentFunction(call, position) {
15561
15516
  if (arg === void 0) {
15562
15517
  return null;
15563
15518
  }
15564
- if (Node63.isArrowFunction(arg) || Node63.isFunctionExpression(arg)) {
15519
+ if (Node64.isArrowFunction(arg) || Node64.isFunctionExpression(arg)) {
15565
15520
  return arg;
15566
15521
  }
15567
15522
  return null;
@@ -15573,7 +15528,7 @@ function readArrayLiteralText(node) {
15573
15528
  if (node === null) {
15574
15529
  return null;
15575
15530
  }
15576
- if (Node63.isArrayLiteralExpression(node)) {
15531
+ if (Node64.isArrayLiteralExpression(node)) {
15577
15532
  return node.getElements().map((e) => e.getText());
15578
15533
  }
15579
15534
  return [node.getText()];
@@ -15829,13 +15784,13 @@ var raise = (msg) => {
15829
15784
  throw new Error(msg);
15830
15785
  };
15831
15786
  function bindingPatternNames(nameNode) {
15832
- if (Node64.isObjectBindingPattern(nameNode)) {
15787
+ if (Node65.isObjectBindingPattern(nameNode)) {
15833
15788
  return nameNode.getElements().map((e) => e.getName());
15834
15789
  }
15835
- if (Node64.isArrayBindingPattern(nameNode)) {
15790
+ if (Node65.isArrayBindingPattern(nameNode)) {
15836
15791
  const names = [];
15837
15792
  for (const element of nameNode.getElements()) {
15838
- if (Node64.isOmittedExpression(element)) {
15793
+ if (Node65.isOmittedExpression(element)) {
15839
15794
  continue;
15840
15795
  }
15841
15796
  names.push(element.getName());
@@ -15865,7 +15820,7 @@ function objectParamInputs(param, position, mapping) {
15865
15820
  }
15866
15821
  function componentPropsParameters(param, mapping) {
15867
15822
  const nameNode = param.getNameNode();
15868
- if (!Node64.isObjectBindingPattern(nameNode)) {
15823
+ if (!Node65.isObjectBindingPattern(nameNode)) {
15869
15824
  const type = param.getType();
15870
15825
  return [
15871
15826
  {
@@ -15895,7 +15850,7 @@ function bindingRole(element, name) {
15895
15850
  if (property === void 0) {
15896
15851
  return name;
15897
15852
  }
15898
- if (Node64.isStringLiteral(property)) {
15853
+ if (Node65.isStringLiteral(property)) {
15899
15854
  return property.getLiteralValue();
15900
15855
  }
15901
15856
  return property.getText();
@@ -15927,7 +15882,7 @@ function extractParameters(func, inputMapping) {
15927
15882
  const param = params[i];
15928
15883
  const nameNode = param.getNameNode();
15929
15884
  const boundNames = bindingPatternNames(nameNode);
15930
- if (Node64.isObjectBindingPattern(nameNode)) {
15885
+ if (Node65.isObjectBindingPattern(nameNode)) {
15931
15886
  for (const element of nameNode.getElements()) {
15932
15887
  result.push({
15933
15888
  name: element.getName(),
@@ -15994,7 +15949,7 @@ function extractDependencyCalls(func, barriers = NO_BARRIERS) {
15994
15949
  traversal.skip();
15995
15950
  return;
15996
15951
  }
15997
- if (!Node64.isVariableDeclaration(node)) {
15952
+ if (!Node65.isVariableDeclaration(node)) {
15998
15953
  return;
15999
15954
  }
16000
15955
  const init = node.getInitializer();
@@ -16003,19 +15958,19 @@ function extractDependencyCalls(func, barriers = NO_BARRIERS) {
16003
15958
  }
16004
15959
  let isAsync = false;
16005
15960
  let callExpr = init;
16006
- if (Node64.isAwaitExpression(init)) {
15961
+ if (Node65.isAwaitExpression(init)) {
16007
15962
  isAsync = true;
16008
15963
  callExpr = init.getExpression();
16009
15964
  }
16010
- if (!Node64.isCallExpression(callExpr)) {
15965
+ if (!Node65.isCallExpression(callExpr)) {
16011
15966
  return;
16012
15967
  }
16013
15968
  const calleeName = callExpr.getExpression().getText();
16014
15969
  const nameNode = node.getNameNode();
16015
- const assignedTo = Node64.isIdentifier(nameNode) ? nameNode.getText() : null;
15970
+ const assignedTo = Node65.isIdentifier(nameNode) ? nameNode.getText() : null;
16016
15971
  const declList = node.getParent();
16017
15972
  const varStmt = declList?.getParent();
16018
- const locationNode = varStmt !== void 0 && Node64.isVariableStatement(varStmt) ? varStmt : node;
15973
+ const locationNode = varStmt !== void 0 && Node65.isVariableStatement(varStmt) ? varStmt : node;
16019
15974
  results.push({
16020
15975
  name: calleeName,
16021
15976
  assignedTo,
@@ -16374,6 +16329,10 @@ function extractBindingPath(binding, callSite, pack, resolution) {
16374
16329
  const arg = callSite.callExpression.getArguments()[p.position];
16375
16330
  return arg === void 0 ? void 0 : pathFromArgument(arg, resolution);
16376
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
+ }
16377
16336
  return void 0;
16378
16337
  }
16379
16338
  function resolveContractField(callSite, pack, field, resolution) {
@@ -16769,20 +16728,23 @@ function extractFromSourceFile(sourceFile, frameworks, claimedUnits, options, ta
16769
16728
  return summaries;
16770
16729
  }
16771
16730
  function stampWrappers(raw, unit, wrappers) {
16772
- if (wrappers === void 0 || unit.registrationSubjectId === void 0) {
16773
- return;
16774
- }
16775
- 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
+ ];
16776
16735
  if (applied.length === 0) {
16777
16736
  return;
16778
16737
  }
16779
- raw.wrappers = [...applied];
16738
+ raw.wrappers = applied;
16780
16739
  for (const wrapper of applied) {
16781
16740
  recordFileDependency(wrapper.file);
16782
16741
  }
16783
16742
  }
16784
16743
  function unfollowedStopsOf(unit, wrappers) {
16785
- const stops = unit.unfollowed === void 0 ? [] : [unit.unfollowed];
16744
+ const stops = [
16745
+ ...unit.unfollowed === void 0 ? [] : [unit.unfollowed],
16746
+ ...unit.routeUnfollowed ?? []
16747
+ ];
16786
16748
  if (wrappers === void 0 || unit.registrationSubjectId === void 0) {
16787
16749
  return stops;
16788
16750
  }
@@ -16931,7 +16893,7 @@ function findWrapperPathParam(summary, lookup) {
16931
16893
  }
16932
16894
  for (const call of func.getDescendantsOfKind(SyntaxKind12.CallExpression)) {
16933
16895
  const first = call.getArguments()[0];
16934
- if (first === void 0 || !Node64.isIdentifier(first)) {
16896
+ if (first === void 0 || !Node65.isIdentifier(first)) {
16935
16897
  continue;
16936
16898
  }
16937
16899
  const at = names.indexOf(first.getText());
@@ -16980,16 +16942,16 @@ function synthesizeCallerSummaries(wrapper, _project, options, resolution) {
16980
16942
  return out;
16981
16943
  }
16982
16944
  function wrapperNameNode(func) {
16983
- if (Node64.isFunctionDeclaration(func) || Node64.isMethodDeclaration(func)) {
16945
+ if (Node65.isFunctionDeclaration(func) || Node65.isMethodDeclaration(func)) {
16984
16946
  const name = func.getNameNode();
16985
- if (name !== void 0 && Node64.isIdentifier(name)) {
16947
+ if (name !== void 0 && Node65.isIdentifier(name)) {
16986
16948
  return name;
16987
16949
  }
16988
16950
  }
16989
16951
  const parent = func.getParent();
16990
- if (parent !== void 0 && Node64.isVariableDeclaration(parent)) {
16952
+ if (parent !== void 0 && Node65.isVariableDeclaration(parent)) {
16991
16953
  const nameNode = parent.getNameNode();
16992
- if (Node64.isIdentifier(nameNode)) {
16954
+ if (Node65.isIdentifier(nameNode)) {
16993
16955
  return nameNode;
16994
16956
  }
16995
16957
  }
@@ -16998,10 +16960,10 @@ function wrapperNameNode(func) {
16998
16960
  function enclosingCall(node) {
16999
16961
  let current2 = node.getParent();
17000
16962
  while (current2 !== void 0) {
17001
- if (Node64.isCallExpression(current2)) {
16963
+ if (Node65.isCallExpression(current2)) {
17002
16964
  return current2;
17003
16965
  }
17004
- if (Node64.isPropertyAccessExpression(current2)) {
16966
+ if (Node65.isPropertyAccessExpression(current2)) {
17005
16967
  current2 = current2.getParent();
17006
16968
  continue;
17007
16969
  }
@@ -17012,7 +16974,7 @@ function enclosingCall(node) {
17012
16974
  function enclosingFunction(node) {
17013
16975
  let current2 = node.getParent();
17014
16976
  while (current2 !== void 0) {
17015
- 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)) {
17016
16978
  return current2;
17017
16979
  }
17018
16980
  current2 = current2.getParent();
@@ -17020,13 +16982,13 @@ function enclosingFunction(node) {
17020
16982
  return null;
17021
16983
  }
17022
16984
  function callerName(func) {
17023
- if (Node64.isFunctionDeclaration(func) || Node64.isMethodDeclaration(func)) {
16985
+ if (Node65.isFunctionDeclaration(func) || Node65.isMethodDeclaration(func)) {
17024
16986
  return func.getName() ?? "anonymous";
17025
16987
  }
17026
16988
  const parent = func.getParent();
17027
- if (parent !== void 0 && Node64.isVariableDeclaration(parent)) {
16989
+ if (parent !== void 0 && Node65.isVariableDeclaration(parent)) {
17028
16990
  const nameNode = parent.getNameNode();
17029
- if (Node64.isIdentifier(nameNode)) {
16991
+ if (Node65.isIdentifier(nameNode)) {
17030
16992
  return nameNode.getText();
17031
16993
  }
17032
16994
  }
@@ -17079,7 +17041,7 @@ function buildCallerSummary(wrapper, callerFunc, callExpr, path15, options) {
17079
17041
  return summary;
17080
17042
  }
17081
17043
  function named(summaries, workspace, runRoot) {
17082
- const projectRoot = runRoot ?? commonDirectoryOf(summaries.map((s) => s.location.file));
17044
+ const projectRoot = runRoot ?? commonDirectoryOf2(summaries.map((s) => s.location.file));
17083
17045
  nameSummaries(summaries, {
17084
17046
  workspace: workspace ?? workspaceNameFor(projectRoot),
17085
17047
  projectRoot
@@ -17172,7 +17134,11 @@ function createTypeScriptAdapter(suppliedConfig) {
17172
17134
  )
17173
17135
  );
17174
17136
  }
17175
- return named(summaries, config.workspace, runRoot);
17137
+ return named(
17138
+ composeWrappers(summaries, config.extractorOptions ?? {}),
17139
+ config.workspace,
17140
+ runRoot
17141
+ );
17176
17142
  },
17177
17143
  async extractAll() {
17178
17144
  const timer = createTimer();
@@ -17432,12 +17398,6 @@ function createTypeScriptAdapter(suppliedConfig) {
17432
17398
  "enrichRethrows",
17433
17399
  () => enrichRethrows(merged.summaries, project, closureFacts)
17434
17400
  );
17435
- if (config.includeReachable !== false) {
17436
- timer.time(
17437
- "deriveBoundaryEffects",
17438
- () => deriveBoundaryEffects(enriched, closureFacts)
17439
- );
17440
- }
17441
17401
  timer.time(
17442
17402
  "stampModuleImports",
17443
17403
  () => stampModuleImports(enriched, (file) => {
@@ -17516,7 +17476,7 @@ function createTypeScriptAdapter(suppliedConfig) {
17516
17476
  filesWalked: walkList.length,
17517
17477
  summaries: composed,
17518
17478
  tsConfigFilePath: config.tsConfigFilePath,
17519
- projectRoot: commonDirectoryOf(
17479
+ projectRoot: commonDirectoryOf2(
17520
17480
  sourceFiles.map((f) => f.getFilePath())
17521
17481
  ),
17522
17482
  filesWithUnreadableExports: unreadableExportFiles(),
@@ -17528,7 +17488,7 @@ function createTypeScriptAdapter(suppliedConfig) {
17528
17488
  return named(
17529
17489
  composed,
17530
17490
  config.workspace,
17531
- runRoot ?? commonDirectoryOf(sourceFiles.map((f) => f.getFilePath()))
17491
+ runRoot ?? commonDirectoryOf2(sourceFiles.map((f) => f.getFilePath()))
17532
17492
  );
17533
17493
  }
17534
17494
  };
@@ -17921,10 +17881,18 @@ function createProjectWithoutTsconfig(rootDir) {
17921
17881
  }
17922
17882
  return { project, files };
17923
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"];
17924
17890
  function findNearestTsconfig(startDir) {
17925
- let dir = path12.resolve(startDir);
17891
+ const start = path12.resolve(startDir);
17892
+ let dir = start;
17926
17893
  while (true) {
17927
- 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) {
17928
17896
  const candidate = path12.join(dir, name);
17929
17897
  if (fs6.existsSync(candidate)) {
17930
17898
  return candidate;
@@ -17940,7 +17908,7 @@ function findNearestTsconfig(startDir) {
17940
17908
 
17941
17909
  // src/facts/why.ts
17942
17910
  import path13 from "path";
17943
- 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";
17944
17912
  import { explainResolutionProof, renderExplanation } from "@suss/resolution";
17945
17913
  var JS_PHRASES = {
17946
17914
  bind: ({ tuple, describe }) => ({
@@ -17969,7 +17937,7 @@ var TypeScriptWhySession = class {
17969
17937
  }
17970
17938
  let found = null;
17971
17939
  sourceFile.forEachDescendant((node) => {
17972
- 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())) {
17973
17941
  found = node;
17974
17942
  }
17975
17943
  });
@@ -18061,21 +18029,21 @@ var TypeScriptWhySession = class {
18061
18029
  }
18062
18030
  };
18063
18031
  function displayNameOf(node) {
18064
- if (Node65.isIdentifier(node) || Node65.isPropertyAccessExpression(node)) {
18032
+ if (Node66.isIdentifier(node) || Node66.isPropertyAccessExpression(node)) {
18065
18033
  return node.getText();
18066
18034
  }
18067
- if (Node65.isCallExpression(node) || Node65.isNewExpression(node)) {
18035
+ if (Node66.isCallExpression(node) || Node66.isNewExpression(node)) {
18068
18036
  return `${node.getExpression()?.getText() ?? "call"}(...)`;
18069
18037
  }
18070
- 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)) {
18071
18039
  const name = node.getName();
18072
18040
  if (name !== void 0) {
18073
18041
  return name;
18074
18042
  }
18075
18043
  }
18076
- if (Node65.isArrowFunction(node) || Node65.isFunctionExpression(node)) {
18044
+ if (Node66.isArrowFunction(node) || Node66.isFunctionExpression(node)) {
18077
18045
  const parent = node.getParent();
18078
- if (parent !== void 0 && Node65.isVariableDeclaration(parent)) {
18046
+ if (parent !== void 0 && Node66.isVariableDeclaration(parent)) {
18079
18047
  return parent.getName();
18080
18048
  }
18081
18049
  }
@@ -18129,6 +18097,7 @@ export {
18129
18097
  GENERIC_TERMINALS,
18130
18098
  NO_BARRIERS,
18131
18099
  ResolutionStore,
18100
+ TSCONFIG_NAMES,
18132
18101
  TypeScriptWhySession,
18133
18102
  accessContextFor,
18134
18103
  buildProjectHelperIndex,