unguard 0.10.1 → 0.10.2

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.
@@ -636,6 +636,7 @@ var preferRequiredParamWithGuard = {
636
636
  };
637
637
 
638
638
  // src/rules/cross-file/duplicate-type-declaration.ts
639
+ import * as ts18 from "typescript";
639
640
  var duplicateTypeDeclaration = {
640
641
  id: "duplicate-type-declaration",
641
642
  severity: "warning",
@@ -645,6 +646,7 @@ var duplicateTypeDeclaration = {
645
646
  for (const group of project.types.getDuplicateGroups()) {
646
647
  const files = new Set(group.map((e) => e.file));
647
648
  if (files.size < 2) continue;
649
+ if (group.every((e) => isTrivialObjectShape(e.node))) continue;
648
650
  reportDuplicateGroup(
649
651
  group,
650
652
  this.id,
@@ -657,9 +659,14 @@ var duplicateTypeDeclaration = {
657
659
  return diagnostics;
658
660
  }
659
661
  };
662
+ function isTrivialObjectShape(node) {
663
+ if (ts18.isTypeLiteralNode(node)) return node.members.length <= 1;
664
+ if (ts18.isInterfaceDeclaration(node)) return node.members.length <= 1;
665
+ return false;
666
+ }
660
667
 
661
668
  // src/rules/cross-file/duplicate-function-declaration.ts
662
- import * as ts18 from "typescript";
669
+ import * as ts19 from "typescript";
663
670
  var duplicateFunctionDeclaration = {
664
671
  id: "duplicate-function-declaration",
665
672
  severity: "warning",
@@ -684,12 +691,13 @@ var duplicateFunctionDeclaration = {
684
691
  }
685
692
  };
686
693
  function getBodyBlock(node) {
687
- if (ts18.isFunctionDeclaration(node) || ts18.isFunctionExpression(node)) return node.body;
688
- if (ts18.isArrowFunction(node)) return ts18.isBlock(node.body) ? node.body : void 0;
689
- if (ts18.isMethodDeclaration(node)) return node.body;
694
+ if (ts19.isFunctionDeclaration(node) || ts19.isFunctionExpression(node)) return node.body;
695
+ if (ts19.isArrowFunction(node)) return ts19.isBlock(node.body) ? node.body : void 0;
696
+ if (ts19.isMethodDeclaration(node)) return node.body;
690
697
  return void 0;
691
698
  }
692
699
  function isSingleStatement(node) {
700
+ if (ts19.isArrowFunction(node) && !ts19.isBlock(node.body)) return true;
693
701
  const body = getBodyBlock(node);
694
702
  return body !== void 0 && body.statements.length <= 1;
695
703
  }
@@ -697,8 +705,8 @@ function isSetter(node) {
697
705
  const body = getBodyBlock(node);
698
706
  if (!body || body.statements.length !== 1) return false;
699
707
  const stmt = body.statements[0];
700
- if (stmt === void 0 || !ts18.isExpressionStatement(stmt)) return false;
701
- return ts18.isBinaryExpression(stmt.expression) && stmt.expression.operatorToken.kind === ts18.SyntaxKind.EqualsToken;
708
+ if (stmt === void 0 || !ts19.isExpressionStatement(stmt)) return false;
709
+ return ts19.isBinaryExpression(stmt.expression) && stmt.expression.operatorToken.kind === ts19.SyntaxKind.EqualsToken;
702
710
  }
703
711
 
704
712
  // src/rules/cross-file/optional-arg-always-used.ts
@@ -733,14 +741,14 @@ var optionalArgAlwaysUsed = {
733
741
  };
734
742
 
735
743
  // src/rules/ts/no-catch-return.ts
736
- import * as ts19 from "typescript";
744
+ import * as ts20 from "typescript";
737
745
  var noCatchReturn = {
738
746
  kind: "ts",
739
747
  id: "no-catch-return",
740
748
  severity: "warning",
741
749
  message: "Catch block silently returns a fallback value with no logging; rethrow, log the error, or let it propagate",
742
750
  visit(node, ctx) {
743
- if (!ts19.isCatchClause(node)) return;
751
+ if (!ts20.isCatchClause(node)) return;
744
752
  const block = node.block;
745
753
  if (hasReturn(block) && !hasThrow(block) && !hasLogging(block)) {
746
754
  ctx.report(node);
@@ -750,57 +758,57 @@ var noCatchReturn = {
750
758
  function walkBlock(block, predicate) {
751
759
  function visit(node) {
752
760
  if (predicate(node)) return true;
753
- if (ts19.isFunctionDeclaration(node) || ts19.isFunctionExpression(node) || ts19.isArrowFunction(node)) return false;
754
- return ts19.forEachChild(node, visit) ?? false;
761
+ if (ts20.isFunctionDeclaration(node) || ts20.isFunctionExpression(node) || ts20.isArrowFunction(node)) return false;
762
+ return ts20.forEachChild(node, visit) ?? false;
755
763
  }
756
- return ts19.forEachChild(block, visit) ?? false;
764
+ return ts20.forEachChild(block, visit) ?? false;
757
765
  }
758
766
  function hasReturn(block) {
759
- return walkBlock(block, (n) => ts19.isReturnStatement(n));
767
+ return walkBlock(block, (n) => ts20.isReturnStatement(n));
760
768
  }
761
769
  function hasThrow(block) {
762
- return walkBlock(block, (n) => ts19.isThrowStatement(n));
770
+ return walkBlock(block, (n) => ts20.isThrowStatement(n));
763
771
  }
764
772
  var LOG_OBJECTS = /* @__PURE__ */ new Set(["console", "logger", "log"]);
765
773
  function hasLogging(block) {
766
774
  return walkBlock(block, (n) => {
767
- if (!ts19.isCallExpression(n)) return false;
775
+ if (!ts20.isCallExpression(n)) return false;
768
776
  const callee = n.expression;
769
- if (!ts19.isPropertyAccessExpression(callee)) return false;
770
- if (!ts19.isIdentifier(callee.expression)) return false;
777
+ if (!ts20.isPropertyAccessExpression(callee)) return false;
778
+ if (!ts20.isIdentifier(callee.expression)) return false;
771
779
  return LOG_OBJECTS.has(callee.expression.text);
772
780
  });
773
781
  }
774
782
 
775
783
  // src/rules/ts/no-error-rewrap.ts
776
- import * as ts20 from "typescript";
784
+ import * as ts21 from "typescript";
777
785
  var noErrorRewrap = {
778
786
  kind: "ts",
779
787
  id: "no-error-rewrap",
780
788
  severity: "error",
781
789
  message: "Re-wrapped error loses the original stack trace and type; use { cause: originalError } to preserve the error chain",
782
790
  visit(node, ctx) {
783
- if (!ts20.isCatchClause(node)) return;
791
+ if (!ts21.isCatchClause(node)) return;
784
792
  if (!node.variableDeclaration) return;
785
793
  const param = node.variableDeclaration.name;
786
- if (!ts20.isIdentifier(param)) return;
794
+ if (!ts21.isIdentifier(param)) return;
787
795
  const catchName = param.text;
788
796
  findRewraps(node.block, catchName, ctx);
789
797
  }
790
798
  };
791
799
  function findRewraps(block, catchName, ctx) {
792
800
  function visit(node) {
793
- if (ts20.isFunctionDeclaration(node) || ts20.isFunctionExpression(node) || ts20.isArrowFunction(node)) return;
794
- if (ts20.isThrowStatement(node) && node.expression && ts20.isNewExpression(node.expression)) {
801
+ if (ts21.isFunctionDeclaration(node) || ts21.isFunctionExpression(node) || ts21.isArrowFunction(node)) return;
802
+ if (ts21.isThrowStatement(node) && node.expression && ts21.isNewExpression(node.expression)) {
795
803
  const args = node.expression.arguments;
796
804
  if (args && args.length > 0 && referencesName(args, catchName) && !hasCauseArg(args)) {
797
805
  ctx.report(node);
798
806
  }
799
807
  return;
800
808
  }
801
- ts20.forEachChild(node, visit);
809
+ ts21.forEachChild(node, visit);
802
810
  }
803
- ts20.forEachChild(block, visit);
811
+ ts21.forEachChild(block, visit);
804
812
  }
805
813
  function referencesName(args, name) {
806
814
  for (const arg of args) {
@@ -809,15 +817,15 @@ function referencesName(args, name) {
809
817
  return false;
810
818
  }
811
819
  function containsIdentifier(node, name) {
812
- if (ts20.isIdentifier(node) && node.text === name) return true;
813
- return ts20.forEachChild(node, (child) => containsIdentifier(child, name) || void 0) ?? false;
820
+ if (ts21.isIdentifier(node) && node.text === name) return true;
821
+ return ts21.forEachChild(node, (child) => containsIdentifier(child, name) || void 0) ?? false;
814
822
  }
815
823
  function hasCauseArg(args) {
816
824
  for (const arg of args) {
817
- if (ts20.isObjectLiteralExpression(arg)) {
825
+ if (ts21.isObjectLiteralExpression(arg)) {
818
826
  for (const prop of arg.properties) {
819
- if (ts20.isPropertyAssignment(prop) && ts20.isIdentifier(prop.name) && prop.name.text === "cause") return true;
820
- if (ts20.isShorthandPropertyAssignment(prop) && prop.name.text === "cause") return true;
827
+ if (ts21.isPropertyAssignment(prop) && ts21.isIdentifier(prop.name) && prop.name.text === "cause") return true;
828
+ if (ts21.isShorthandPropertyAssignment(prop) && prop.name.text === "cause") return true;
821
829
  }
822
830
  }
823
831
  }
@@ -825,7 +833,7 @@ function hasCauseArg(args) {
825
833
  }
826
834
 
827
835
  // src/rules/cross-file/explicit-null-arg.ts
828
- import * as ts21 from "typescript";
836
+ import * as ts22 from "typescript";
829
837
  var explicitNullArg = {
830
838
  id: "explicit-null-arg",
831
839
  severity: "warning",
@@ -845,7 +853,7 @@ var explicitNullArg = {
845
853
  const arg = site.node.arguments[i];
846
854
  if (arg === void 0) continue;
847
855
  if (isNullishLiteral(arg)) {
848
- const val = arg.kind === ts21.SyntaxKind.NullKeyword ? "null" : "undefined";
856
+ const val = arg.kind === ts22.SyntaxKind.NullKeyword ? "null" : "undefined";
849
857
  diagnostics.push({
850
858
  ruleId: this.id,
851
859
  severity: this.severity,
@@ -918,7 +926,7 @@ function resolveCandidates(fromFile, specifier) {
918
926
  }
919
927
 
920
928
  // src/rules/cross-file/duplicate-type-name.ts
921
- import * as ts22 from "typescript";
929
+ import * as ts23 from "typescript";
922
930
  var duplicateTypeName = {
923
931
  id: "duplicate-type-name",
924
932
  severity: "warning",
@@ -929,7 +937,7 @@ var duplicateTypeName = {
929
937
  const hashes = new Set(group.map((e) => e.hash));
930
938
  if (hashes.size === 1) continue;
931
939
  const hasInferredType = group.some(
932
- (e) => !ts22.isTypeLiteralNode(e.node) && !ts22.isInterfaceDeclaration(e.node)
940
+ (e) => !ts23.isTypeLiteralNode(e.node) && !ts23.isInterfaceDeclaration(e.node)
933
941
  );
934
942
  if (hasInferredType) continue;
935
943
  reportDuplicateGroup(
@@ -969,20 +977,21 @@ var duplicateConstantDeclaration = {
969
977
  };
970
978
 
971
979
  // src/rules/ts/no-dynamic-import.ts
972
- import * as ts23 from "typescript";
980
+ import * as ts24 from "typescript";
973
981
  var noDynamicImport = {
974
982
  kind: "ts",
975
983
  id: "no-dynamic-import",
976
984
  severity: "error",
977
985
  message: "Dynamic import() breaks static analysis and hides dependencies; use a static import instead",
978
986
  visit(node, ctx) {
979
- if (!ts23.isCallExpression(node)) return;
980
- if (node.expression.kind !== ts23.SyntaxKind.ImportKeyword) return;
987
+ if (!ts24.isCallExpression(node)) return;
988
+ if (node.expression.kind !== ts24.SyntaxKind.ImportKeyword) return;
981
989
  ctx.report(node);
982
990
  }
983
991
  };
984
992
 
985
993
  // src/rules/cross-file/near-duplicate-function.ts
994
+ import * as ts25 from "typescript";
986
995
  var nearDuplicateFunction = {
987
996
  id: "near-duplicate-function",
988
997
  severity: "warning",
@@ -992,6 +1001,7 @@ var nearDuplicateFunction = {
992
1001
  for (const group of project.functions.getNearDuplicateGroups()) {
993
1002
  const MIN_NORMALIZED_BODY = 32;
994
1003
  if (group.every((e) => e.normalizedBodyLength < MIN_NORMALIZED_BODY)) continue;
1004
+ if (group.every(isSimpleStructure)) continue;
995
1005
  reportDuplicateGroup(
996
1006
  group,
997
1007
  this.id,
@@ -1004,38 +1014,67 @@ var nearDuplicateFunction = {
1004
1014
  return diagnostics;
1005
1015
  }
1006
1016
  };
1017
+ function getFunctionBody(node) {
1018
+ if (ts25.isFunctionDeclaration(node) || ts25.isFunctionExpression(node)) return node.body;
1019
+ if (ts25.isArrowFunction(node)) return node.body;
1020
+ if (ts25.isMethodDeclaration(node)) return node.body;
1021
+ return void 0;
1022
+ }
1023
+ function getTopLevelStatementCount(body) {
1024
+ if (ts25.isBlock(body)) return body.statements.length;
1025
+ return 1;
1026
+ }
1027
+ function hasControlFlow(node) {
1028
+ let found = false;
1029
+ function visit(current) {
1030
+ if (found) return;
1031
+ if (ts25.isIfStatement(current) || ts25.isSwitchStatement(current) || ts25.isTryStatement(current) || ts25.isForStatement(current) || ts25.isForInStatement(current) || ts25.isForOfStatement(current) || ts25.isWhileStatement(current) || ts25.isDoStatement(current)) {
1032
+ found = true;
1033
+ return;
1034
+ }
1035
+ ts25.forEachChild(current, visit);
1036
+ }
1037
+ visit(node);
1038
+ return found;
1039
+ }
1040
+ function isSimpleStructure(entry) {
1041
+ const body = getFunctionBody(entry.node);
1042
+ if (!body) return false;
1043
+ if (hasControlFlow(body)) return false;
1044
+ return getTopLevelStatementCount(body) <= 2;
1045
+ }
1007
1046
 
1008
1047
  // src/rules/cross-file/trivial-wrapper.ts
1009
- import * as ts24 from "typescript";
1010
- function getFunctionBody(node) {
1011
- if (ts24.isFunctionDeclaration(node) || ts24.isFunctionExpression(node)) {
1048
+ import * as ts26 from "typescript";
1049
+ function getFunctionBody2(node) {
1050
+ if (ts26.isFunctionDeclaration(node) || ts26.isFunctionExpression(node)) {
1012
1051
  return node.body;
1013
1052
  }
1014
- if (ts24.isArrowFunction(node)) {
1053
+ if (ts26.isArrowFunction(node)) {
1015
1054
  return node.body;
1016
1055
  }
1017
- if (ts24.isMethodDeclaration(node)) {
1056
+ if (ts26.isMethodDeclaration(node)) {
1018
1057
  return node.body;
1019
1058
  }
1020
1059
  return void 0;
1021
1060
  }
1022
1061
  function getCalleeName(expr) {
1023
- if (ts24.isIdentifier(expr)) return expr.text;
1024
- if (ts24.isPropertyAccessExpression(expr)) return expr.name.text;
1062
+ if (ts26.isIdentifier(expr)) return expr.text;
1063
+ if (ts26.isPropertyAccessExpression(expr)) return expr.name.text;
1025
1064
  return void 0;
1026
1065
  }
1027
1066
  function getTrivialCallTarget(fn) {
1028
- const body = getFunctionBody(fn.node);
1067
+ const body = getFunctionBody2(fn.node);
1029
1068
  if (!body) return null;
1030
1069
  let callExpr;
1031
- if (ts24.isBlock(body)) {
1070
+ if (ts26.isBlock(body)) {
1032
1071
  if (body.statements.length !== 1) return null;
1033
1072
  const stmt = body.statements[0];
1034
- if (!stmt || !ts24.isReturnStatement(stmt) || !stmt.expression) return null;
1035
- if (!ts24.isCallExpression(stmt.expression)) return null;
1073
+ if (!stmt || !ts26.isReturnStatement(stmt) || !stmt.expression) return null;
1074
+ if (!ts26.isCallExpression(stmt.expression)) return null;
1036
1075
  callExpr = stmt.expression;
1037
1076
  } else {
1038
- if (!ts24.isCallExpression(body)) return null;
1077
+ if (!ts26.isCallExpression(body)) return null;
1039
1078
  callExpr = body;
1040
1079
  }
1041
1080
  const calleeName = getCalleeName(callExpr.expression);
@@ -1043,7 +1082,7 @@ function getTrivialCallTarget(fn) {
1043
1082
  const paramNames = fn.params.map((p) => p.name);
1044
1083
  const args = callExpr.arguments;
1045
1084
  for (const arg of args) {
1046
- if (!ts24.isIdentifier(arg)) return null;
1085
+ if (!ts26.isIdentifier(arg)) return null;
1047
1086
  if (!paramNames.includes(arg.text)) return null;
1048
1087
  }
1049
1088
  return { calleeName };
@@ -1340,32 +1379,32 @@ function isFailOn(value) {
1340
1379
  }
1341
1380
 
1342
1381
  // src/collect/index.ts
1343
- import * as ts27 from "typescript";
1382
+ import * as ts29 from "typescript";
1344
1383
  import { createHash as createHash2 } from "crypto";
1345
1384
 
1346
1385
  // src/utils/hash.ts
1347
1386
  import { createHash } from "crypto";
1348
- import * as ts25 from "typescript";
1387
+ import * as ts27 from "typescript";
1349
1388
  function hashTypeShape(node, sourceFile) {
1350
1389
  const normalized = normalizeTypeNode(node, sourceFile);
1351
1390
  return createHash("sha256").update(normalized).digest("hex").slice(0, 16);
1352
1391
  }
1353
1392
  function normalizeTypeNode(node, sourceFile) {
1354
- if (ts25.isTypeLiteralNode(node)) {
1393
+ if (ts27.isTypeLiteralNode(node)) {
1355
1394
  const normalized = node.members.map((m) => normalizeTypeNode(m, sourceFile)).sort().join(";");
1356
1395
  return `{${normalized}}`;
1357
1396
  }
1358
- if (ts25.isInterfaceDeclaration(node)) {
1397
+ if (ts27.isInterfaceDeclaration(node)) {
1359
1398
  const normalized = node.members.map((m) => normalizeTypeNode(m, sourceFile)).sort().join(";");
1360
1399
  return `{${normalized}}`;
1361
1400
  }
1362
- if (ts25.isPropertySignature(node)) {
1401
+ if (ts27.isPropertySignature(node)) {
1363
1402
  const keyName = node.name.getText(sourceFile);
1364
1403
  const optional = node.questionToken ? "?" : "";
1365
1404
  const type = node.type ? normalizeTypeNode(node.type, sourceFile) : "any";
1366
1405
  return `${keyName}${optional}:${type}`;
1367
1406
  }
1368
- if (ts25.isTypeAliasDeclaration(node)) {
1407
+ if (ts27.isTypeAliasDeclaration(node)) {
1369
1408
  return normalizeTypeNode(node.type, sourceFile);
1370
1409
  }
1371
1410
  return node.getText(sourceFile).replace(/\s+/g, " ").trim();
@@ -1531,7 +1570,7 @@ var InlineParamTypeRegistry = class extends BaseRegistry {
1531
1570
  };
1532
1571
 
1533
1572
  // src/typecheck/walk.ts
1534
- import * as ts26 from "typescript";
1573
+ import * as ts28 from "typescript";
1535
1574
  function buildContext(rule, sourceFile, checker, source, filename, diagnostics) {
1536
1575
  return {
1537
1576
  filename,
@@ -1539,7 +1578,7 @@ function buildContext(rule, sourceFile, checker, source, filename, diagnostics)
1539
1578
  sourceFile,
1540
1579
  checker,
1541
1580
  report(node, message) {
1542
- const { line, character } = ts26.getLineAndCharacterOfPosition(sourceFile, node.getStart(sourceFile));
1581
+ const { line, character } = ts28.getLineAndCharacterOfPosition(sourceFile, node.getStart(sourceFile));
1543
1582
  diagnostics.push({
1544
1583
  ruleId: rule.id,
1545
1584
  severity: rule.severity,
@@ -1550,7 +1589,7 @@ function buildContext(rule, sourceFile, checker, source, filename, diagnostics)
1550
1589
  });
1551
1590
  },
1552
1591
  reportAtOffset(offset, message) {
1553
- const { line, character } = ts26.getLineAndCharacterOfPosition(sourceFile, offset);
1592
+ const { line, character } = ts28.getLineAndCharacterOfPosition(sourceFile, offset);
1554
1593
  diagnostics.push({
1555
1594
  ruleId: rule.id,
1556
1595
  severity: rule.severity,
@@ -1601,7 +1640,7 @@ function collectProject(program, tsRules, allowedFiles) {
1601
1640
  rule.visit(node, ctx);
1602
1641
  }
1603
1642
  }
1604
- ts27.forEachChild(node, visit2);
1643
+ ts29.forEachChild(node, visit2);
1605
1644
  };
1606
1645
  var visit = visit2;
1607
1646
  const file = sourceFile.fileName;
@@ -1615,7 +1654,7 @@ function collectProject(program, tsRules, allowedFiles) {
1615
1654
  rule,
1616
1655
  ctx: buildContext(rule, sourceFile, checker, source, file, diagnostics)
1617
1656
  }));
1618
- ts27.forEachChild(sourceFile, visit2);
1657
+ ts29.forEachChild(sourceFile, visit2);
1619
1658
  }
1620
1659
  const fileHashes = /* @__PURE__ */ new Map();
1621
1660
  for (const [file, { source }] of fileMap) {
@@ -1631,52 +1670,52 @@ function collectProject(program, tsRules, allowedFiles) {
1631
1670
  return { index: { types, functions, constants, callSites, imports, files: fileMap, fileHashes, statementSequences, inlineParamTypes }, diagnostics };
1632
1671
  }
1633
1672
  function hasNonPublicModifier(node) {
1634
- if (!ts27.canHaveModifiers(node)) return false;
1635
- const mods = ts27.getModifiers(node);
1673
+ if (!ts29.canHaveModifiers(node)) return false;
1674
+ const mods = ts29.getModifiers(node);
1636
1675
  if (mods === void 0) return false;
1637
1676
  return mods.some(
1638
- (m) => m.kind === ts27.SyntaxKind.PrivateKeyword || m.kind === ts27.SyntaxKind.ProtectedKeyword
1677
+ (m) => m.kind === ts29.SyntaxKind.PrivateKeyword || m.kind === ts29.SyntaxKind.ProtectedKeyword
1639
1678
  );
1640
1679
  }
1641
1680
  function isExported(node) {
1642
- if (!ts27.canHaveModifiers(node)) return false;
1643
- const mods = ts27.getModifiers(node);
1681
+ if (!ts29.canHaveModifiers(node)) return false;
1682
+ const mods = ts29.getModifiers(node);
1644
1683
  if (mods === void 0) return false;
1645
- return mods.some((m) => m.kind === ts27.SyntaxKind.ExportKeyword);
1684
+ return mods.some((m) => m.kind === ts29.SyntaxKind.ExportKeyword);
1646
1685
  }
1647
1686
  function collectTypes(node, file, sourceFile, registry) {
1648
- if (ts27.isTypeAliasDeclaration(node)) {
1649
- const line = ts27.getLineAndCharacterOfPosition(sourceFile, node.getStart(sourceFile)).line + 1;
1687
+ if (ts29.isTypeAliasDeclaration(node)) {
1688
+ const line = ts29.getLineAndCharacterOfPosition(sourceFile, node.getStart(sourceFile)).line + 1;
1650
1689
  registry.add(node.name.text, file, line, node.type, sourceFile, isExported(node));
1651
1690
  }
1652
- if (ts27.isInterfaceDeclaration(node)) {
1653
- const line = ts27.getLineAndCharacterOfPosition(sourceFile, node.getStart(sourceFile)).line + 1;
1691
+ if (ts29.isInterfaceDeclaration(node)) {
1692
+ const line = ts29.getLineAndCharacterOfPosition(sourceFile, node.getStart(sourceFile)).line + 1;
1654
1693
  registry.add(node.name.text, file, line, node, sourceFile, isExported(node));
1655
1694
  }
1656
1695
  }
1657
1696
  function isConstantValue(node) {
1658
- if (ts27.isStringLiteral(node)) return true;
1659
- if (ts27.isNumericLiteral(node)) return true;
1660
- if (ts27.isNoSubstitutionTemplateLiteral(node)) return true;
1661
- if (ts27.isPrefixUnaryExpression(node)) return isConstantValue(node.operand);
1662
- if (ts27.isBinaryExpression(node)) return isConstantValue(node.left) && isConstantValue(node.right);
1697
+ if (ts29.isStringLiteral(node)) return true;
1698
+ if (ts29.isNumericLiteral(node)) return true;
1699
+ if (ts29.isNoSubstitutionTemplateLiteral(node)) return true;
1700
+ if (ts29.isPrefixUnaryExpression(node)) return isConstantValue(node.operand);
1701
+ if (ts29.isBinaryExpression(node)) return isConstantValue(node.left) && isConstantValue(node.right);
1663
1702
  return false;
1664
1703
  }
1665
1704
  function collectConstants(node, file, sourceFile, registry) {
1666
- if (!ts27.isVariableStatement(node)) return;
1667
- if (!(node.declarationList.flags & ts27.NodeFlags.Const)) return;
1705
+ if (!ts29.isVariableStatement(node)) return;
1706
+ if (!(node.declarationList.flags & ts29.NodeFlags.Const)) return;
1668
1707
  const exported = isExported(node);
1669
1708
  for (const decl of node.declarationList.declarations) {
1670
- if (!decl.initializer || !ts27.isIdentifier(decl.name)) continue;
1709
+ if (!decl.initializer || !ts29.isIdentifier(decl.name)) continue;
1671
1710
  if (!isConstantValue(decl.initializer)) continue;
1672
1711
  const valueText = decl.initializer.getText(sourceFile).replace(/\s+/g, " ").trim();
1673
1712
  const valueHash = createHash2("sha256").update(valueText).digest("hex").slice(0, 16);
1674
- const line = ts27.getLineAndCharacterOfPosition(sourceFile, decl.getStart(sourceFile)).line + 1;
1713
+ const line = ts29.getLineAndCharacterOfPosition(sourceFile, decl.getStart(sourceFile)).line + 1;
1675
1714
  registry.add({ name: decl.name.text, file, line, valueHash, valueText, exported });
1676
1715
  }
1677
1716
  }
1678
1717
  function buildFunctionEntry(body, parameters, sourceFile, file, lineNode, name, extra) {
1679
- const line = ts27.getLineAndCharacterOfPosition(sourceFile, lineNode.getStart(sourceFile)).line + 1;
1718
+ const line = ts29.getLineAndCharacterOfPosition(sourceFile, lineNode.getStart(sourceFile)).line + 1;
1680
1719
  const params = extractParams(parameters, sourceFile);
1681
1720
  const paramNames = params.map((p) => p.name);
1682
1721
  const hash = hashFunctionBody(body, sourceFile);
@@ -1698,17 +1737,17 @@ function buildFunctionEntry(body, parameters, sourceFile, file, lineNode, name,
1698
1737
  };
1699
1738
  }
1700
1739
  function collectFunctions(node, file, sourceFile, checker, registry) {
1701
- if (ts27.isFunctionDeclaration(node) && node.name && node.body) {
1740
+ if (ts29.isFunctionDeclaration(node) && node.name && node.body) {
1702
1741
  registry.add(buildFunctionEntry(node.body, node.parameters, sourceFile, file, node, node.name.text, {
1703
1742
  exported: isExported(node),
1704
1743
  symbol: checker.getSymbolAtLocation(node.name),
1705
1744
  node
1706
1745
  }));
1707
1746
  }
1708
- if (ts27.isVariableStatement(node)) {
1747
+ if (ts29.isVariableStatement(node)) {
1709
1748
  const exported = isExported(node);
1710
1749
  for (const decl of node.declarationList.declarations) {
1711
- if (decl.initializer && ts27.isArrowFunction(decl.initializer) && ts27.isIdentifier(decl.name)) {
1750
+ if (decl.initializer && ts29.isArrowFunction(decl.initializer) && ts29.isIdentifier(decl.name)) {
1712
1751
  const arrow = decl.initializer;
1713
1752
  registry.add(buildFunctionEntry(arrow.body, arrow.parameters, sourceFile, file, decl, decl.name.text, {
1714
1753
  exported,
@@ -1716,7 +1755,7 @@ function collectFunctions(node, file, sourceFile, checker, registry) {
1716
1755
  node: arrow
1717
1756
  }));
1718
1757
  }
1719
- if (decl.initializer && ts27.isFunctionExpression(decl.initializer) && ts27.isIdentifier(decl.name)) {
1758
+ if (decl.initializer && ts29.isFunctionExpression(decl.initializer) && ts29.isIdentifier(decl.name)) {
1720
1759
  const fn = decl.initializer;
1721
1760
  if (fn.body) {
1722
1761
  registry.add(buildFunctionEntry(fn.body, fn.parameters, sourceFile, file, decl, decl.name.text, {
@@ -1728,22 +1767,22 @@ function collectFunctions(node, file, sourceFile, checker, registry) {
1728
1767
  }
1729
1768
  }
1730
1769
  }
1731
- if (ts27.isPropertyAssignment(node) && (ts27.isIdentifier(node.name) || ts27.isStringLiteral(node.name))) {
1770
+ if (ts29.isPropertyAssignment(node) && (ts29.isIdentifier(node.name) || ts29.isStringLiteral(node.name))) {
1732
1771
  const init = node.initializer;
1733
1772
  const propName = node.name.text;
1734
- if (ts27.isArrowFunction(init)) {
1773
+ if (ts29.isArrowFunction(init)) {
1735
1774
  registry.add(buildFunctionEntry(init.body, init.parameters, sourceFile, file, node, propName, { node: init }));
1736
1775
  }
1737
- if (ts27.isFunctionExpression(init) && init.body) {
1776
+ if (ts29.isFunctionExpression(init) && init.body) {
1738
1777
  registry.add(buildFunctionEntry(init.body, init.parameters, sourceFile, file, node, propName, { node: init }));
1739
1778
  }
1740
1779
  }
1741
- if (ts27.isArrowFunction(node) || ts27.isFunctionExpression(node)) {
1780
+ if (ts29.isArrowFunction(node) || ts29.isFunctionExpression(node)) {
1742
1781
  const parent = node.parent;
1743
- if (ts27.isVariableDeclaration(parent) && ts27.isIdentifier(parent.name)) {
1744
- } else if (ts27.isPropertyAssignment(parent)) {
1782
+ if (ts29.isVariableDeclaration(parent) && ts29.isIdentifier(parent.name)) {
1783
+ } else if (ts29.isPropertyAssignment(parent)) {
1745
1784
  } else {
1746
- const body = ts27.isArrowFunction(node) ? node.body : node.body;
1785
+ const body = ts29.isArrowFunction(node) ? node.body : node.body;
1747
1786
  if (body) {
1748
1787
  const MIN_ANON_BODY = 64;
1749
1788
  if (bodyTextLength(body, sourceFile) >= MIN_ANON_BODY) {
@@ -1753,14 +1792,14 @@ function collectFunctions(node, file, sourceFile, checker, registry) {
1753
1792
  }
1754
1793
  }
1755
1794
  }
1756
- if (ts27.isMethodDeclaration(node) && node.body && ts27.isIdentifier(node.name)) {
1795
+ if (ts29.isMethodDeclaration(node) && node.body && ts29.isIdentifier(node.name)) {
1757
1796
  const parent = node.parent;
1758
- if (ts27.isClassDeclaration(parent)) {
1797
+ if (ts29.isClassDeclaration(parent)) {
1759
1798
  if (hasNonPublicModifier(node)) return;
1760
1799
  const className = parent.name ? parent.name.text : "<anonymous>";
1761
1800
  const name = `${className}.${node.name.text}`;
1762
1801
  const implementsInterface = parent.heritageClauses?.some(
1763
- (c) => c.token === ts27.SyntaxKind.ImplementsKeyword
1802
+ (c) => c.token === ts29.SyntaxKind.ImplementsKeyword
1764
1803
  ) ?? false;
1765
1804
  registry.add(buildFunctionEntry(node.body, node.parameters, sourceFile, file, node, name, {
1766
1805
  exported: isExported(parent),
@@ -1783,16 +1822,16 @@ function extractParams(parameters, sourceFile) {
1783
1822
  }
1784
1823
  function deriveAnonymousName(node, sourceFile) {
1785
1824
  const parent = node.parent;
1786
- const line = ts27.getLineAndCharacterOfPosition(sourceFile, node.getStart(sourceFile)).line + 1;
1787
- if (ts27.isCallExpression(parent)) {
1825
+ const line = ts29.getLineAndCharacterOfPosition(sourceFile, node.getStart(sourceFile)).line + 1;
1826
+ if (ts29.isCallExpression(parent)) {
1788
1827
  const grandparent = parent.parent;
1789
- if (ts27.isPropertyAssignment(grandparent) && ts27.isIdentifier(grandparent.name)) {
1828
+ if (ts29.isPropertyAssignment(grandparent) && ts29.isIdentifier(grandparent.name)) {
1790
1829
  return grandparent.name.text;
1791
1830
  }
1792
1831
  let calleeName = null;
1793
- if (ts27.isIdentifier(parent.expression)) {
1832
+ if (ts29.isIdentifier(parent.expression)) {
1794
1833
  calleeName = parent.expression.text;
1795
- } else if (ts27.isPropertyAccessExpression(parent.expression)) {
1834
+ } else if (ts29.isPropertyAccessExpression(parent.expression)) {
1796
1835
  calleeName = parent.expression.name.text;
1797
1836
  }
1798
1837
  if (calleeName) {
@@ -1803,7 +1842,7 @@ function deriveAnonymousName(node, sourceFile) {
1803
1842
  return `<anonymous>:${line}`;
1804
1843
  }
1805
1844
  function collectImports(node, file, imports) {
1806
- if (ts27.isImportDeclaration(node) && ts27.isStringLiteral(node.moduleSpecifier)) {
1845
+ if (ts29.isImportDeclaration(node) && ts29.isStringLiteral(node.moduleSpecifier)) {
1807
1846
  const moduleSource = node.moduleSpecifier.text;
1808
1847
  const clause = node.importClause;
1809
1848
  if (!clause) return;
@@ -1815,7 +1854,7 @@ function collectImports(node, file, imports) {
1815
1854
  source: moduleSource
1816
1855
  });
1817
1856
  }
1818
- if (clause.namedBindings && ts27.isNamedImports(clause.namedBindings)) {
1857
+ if (clause.namedBindings && ts29.isNamedImports(clause.namedBindings)) {
1819
1858
  for (const el of clause.namedBindings.elements) {
1820
1859
  imports.push({
1821
1860
  file,
@@ -1826,9 +1865,9 @@ function collectImports(node, file, imports) {
1826
1865
  }
1827
1866
  }
1828
1867
  }
1829
- if (ts27.isExportDeclaration(node) && node.moduleSpecifier && ts27.isStringLiteral(node.moduleSpecifier)) {
1868
+ if (ts29.isExportDeclaration(node) && node.moduleSpecifier && ts29.isStringLiteral(node.moduleSpecifier)) {
1830
1869
  const moduleSource = node.moduleSpecifier.text;
1831
- if (node.exportClause && ts27.isNamedExports(node.exportClause)) {
1870
+ if (node.exportClause && ts29.isNamedExports(node.exportClause)) {
1832
1871
  for (const el of node.exportClause.elements) {
1833
1872
  imports.push({
1834
1873
  file,
@@ -1841,7 +1880,7 @@ function collectImports(node, file, imports) {
1841
1880
  }
1842
1881
  }
1843
1882
  function collectStatementSequences(node, file, sourceFile, registry) {
1844
- if (!ts27.isBlock(node)) return;
1883
+ if (!ts29.isBlock(node)) return;
1845
1884
  const stmts = node.statements;
1846
1885
  const n = stmts.length;
1847
1886
  if (n < 3) return;
@@ -1858,34 +1897,34 @@ function collectStatementSequences(node, file, sourceFile, registry) {
1858
1897
  const firstStmt = window[0];
1859
1898
  const lastStmt = window[window.length - 1];
1860
1899
  if (firstStmt === void 0 || lastStmt === void 0) continue;
1861
- const line = ts27.getLineAndCharacterOfPosition(sourceFile, firstStmt.getStart(sourceFile)).line + 1;
1862
- const endLine = ts27.getLineAndCharacterOfPosition(sourceFile, lastStmt.getEnd()).line + 1;
1900
+ const line = ts29.getLineAndCharacterOfPosition(sourceFile, firstStmt.getStart(sourceFile)).line + 1;
1901
+ const endLine = ts29.getLineAndCharacterOfPosition(sourceFile, lastStmt.getEnd()).line + 1;
1863
1902
  registry.add({ file, line, endLine, hash, normalizedHash, statementCount: size, normalizedBodyLength: normalized.length });
1864
1903
  }
1865
1904
  }
1866
1905
  }
1867
1906
  function collectInlineParamTypes(node, file, sourceFile, registry) {
1868
- if (!ts27.isTypeLiteralNode(node)) return;
1907
+ if (!ts29.isTypeLiteralNode(node)) return;
1869
1908
  const parent = node.parent;
1870
- if (!parent || !ts27.isParameter(parent)) return;
1909
+ if (!parent || !ts29.isParameter(parent)) return;
1871
1910
  if (parent.type !== node) return;
1872
- const line = ts27.getLineAndCharacterOfPosition(sourceFile, node.getStart(sourceFile)).line + 1;
1911
+ const line = ts29.getLineAndCharacterOfPosition(sourceFile, node.getStart(sourceFile)).line + 1;
1873
1912
  registry.add(file, line, node, sourceFile);
1874
1913
  }
1875
1914
  function collectCallSites(node, file, sourceFile, checker, sites) {
1876
- if (!ts27.isCallExpression(node)) return;
1915
+ if (!ts29.isCallExpression(node)) return;
1877
1916
  let calleeName = null;
1878
- if (ts27.isIdentifier(node.expression)) {
1917
+ if (ts29.isIdentifier(node.expression)) {
1879
1918
  calleeName = node.expression.text;
1880
- } else if (ts27.isPropertyAccessExpression(node.expression)) {
1919
+ } else if (ts29.isPropertyAccessExpression(node.expression)) {
1881
1920
  calleeName = node.expression.name.text;
1882
1921
  }
1883
1922
  if (calleeName) {
1884
- const line = ts27.getLineAndCharacterOfPosition(sourceFile, node.getStart(sourceFile)).line + 1;
1923
+ const line = ts29.getLineAndCharacterOfPosition(sourceFile, node.getStart(sourceFile)).line + 1;
1885
1924
  let symbol;
1886
1925
  try {
1887
1926
  symbol = checker.getSymbolAtLocation(node.expression);
1888
- if (symbol && symbol.flags & ts27.SymbolFlags.Alias) {
1927
+ if (symbol && symbol.flags & ts29.SymbolFlags.Alias) {
1889
1928
  symbol = checker.getAliasedSymbol(symbol);
1890
1929
  }
1891
1930
  } catch {
@@ -1905,12 +1944,12 @@ function collectAllComments(sourceFile) {
1905
1944
  const source = sourceFile.getFullText();
1906
1945
  const seen = /* @__PURE__ */ new Set();
1907
1946
  function visit(node) {
1908
- const leading = ts27.getLeadingCommentRanges(source, node.getFullStart());
1947
+ const leading = ts29.getLeadingCommentRanges(source, node.getFullStart());
1909
1948
  if (leading) {
1910
1949
  for (const r of leading) {
1911
1950
  if (seen.has(r.pos)) continue;
1912
1951
  seen.add(r.pos);
1913
- const isLine = r.kind === ts27.SyntaxKind.SingleLineCommentTrivia;
1952
+ const isLine = r.kind === ts29.SyntaxKind.SingleLineCommentTrivia;
1914
1953
  comments.push({
1915
1954
  type: isLine ? "Line" : "Block",
1916
1955
  value: source.slice(r.pos + 2, isLine ? r.end : r.end - 2),
@@ -1919,12 +1958,12 @@ function collectAllComments(sourceFile) {
1919
1958
  });
1920
1959
  }
1921
1960
  }
1922
- const trailing = ts27.getTrailingCommentRanges(source, node.getEnd());
1961
+ const trailing = ts29.getTrailingCommentRanges(source, node.getEnd());
1923
1962
  if (trailing) {
1924
1963
  for (const r of trailing) {
1925
1964
  if (seen.has(r.pos)) continue;
1926
1965
  seen.add(r.pos);
1927
- const isLine = r.kind === ts27.SyntaxKind.SingleLineCommentTrivia;
1966
+ const isLine = r.kind === ts29.SyntaxKind.SingleLineCommentTrivia;
1928
1967
  comments.push({
1929
1968
  type: isLine ? "Line" : "Block",
1930
1969
  value: source.slice(r.pos + 2, isLine ? r.end : r.end - 2),
@@ -1933,34 +1972,34 @@ function collectAllComments(sourceFile) {
1933
1972
  });
1934
1973
  }
1935
1974
  }
1936
- ts27.forEachChild(node, visit);
1975
+ ts29.forEachChild(node, visit);
1937
1976
  }
1938
1977
  visit(sourceFile);
1939
1978
  return comments;
1940
1979
  }
1941
1980
 
1942
1981
  // src/typecheck/program.ts
1943
- import * as ts28 from "typescript";
1982
+ import * as ts30 from "typescript";
1944
1983
  import { dirname as dirname2 } from "path";
1945
1984
  function createProgramFromFiles(files) {
1946
1985
  let configPath;
1947
1986
  if (files.length > 0) {
1948
- configPath = ts28.findConfigFile(dirname2(files[0]), ts28.sys.fileExists, "tsconfig.json");
1987
+ configPath = ts30.findConfigFile(dirname2(files[0]), ts30.sys.fileExists, "tsconfig.json");
1949
1988
  }
1950
1989
  if (configPath) {
1951
- const configFile = ts28.readConfigFile(configPath, ts28.sys.readFile);
1952
- const parsed = ts28.parseJsonConfigFileContent(configFile.config, ts28.sys, dirname2(configPath));
1953
- return ts28.createProgram({
1990
+ const configFile = ts30.readConfigFile(configPath, ts30.sys.readFile);
1991
+ const parsed = ts30.parseJsonConfigFileContent(configFile.config, ts30.sys, dirname2(configPath));
1992
+ return ts30.createProgram({
1954
1993
  rootNames: files,
1955
1994
  options: { ...parsed.options, skipLibCheck: true }
1956
1995
  });
1957
1996
  }
1958
- return ts28.createProgram({
1997
+ return ts30.createProgram({
1959
1998
  rootNames: files,
1960
1999
  options: {
1961
- target: ts28.ScriptTarget.ESNext,
1962
- module: ts28.ModuleKind.ESNext,
1963
- moduleResolution: ts28.ModuleResolutionKind.Bundler,
2000
+ target: ts30.ScriptTarget.ESNext,
2001
+ module: ts30.ModuleKind.ESNext,
2002
+ moduleResolution: ts30.ModuleResolutionKind.Bundler,
1964
2003
  strict: true,
1965
2004
  skipLibCheck: true,
1966
2005
  noEmit: true
@@ -2200,4 +2239,4 @@ export {
2200
2239
  executeScan,
2201
2240
  scan
2202
2241
  };
2203
- //# sourceMappingURL=chunk-RV4V5VH5.js.map
2242
+ //# sourceMappingURL=chunk-NNUATKJZ.js.map