unguard 0.8.0 → 0.9.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/README.md +73 -19
- package/dist/{chunk-YYX4R25B.js → chunk-I4RZLVE2.js} +262 -63
- package/dist/chunk-I4RZLVE2.js.map +1 -0
- package/dist/cli.js +198 -50
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +28 -3
- package/dist/index.js +5 -1
- package/package.json +7 -3
- package/dist/chunk-YYX4R25B.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/rules/ts/no-empty-catch.ts","../src/rules/ts/no-non-null-assertion.ts","../src/rules/ts/no-double-negation-coercion.ts","../src/typecheck/utils.ts","../src/rules/ts/no-ts-ignore.ts","../src/rules/ts/no-nullish-coalescing.ts","../src/rules/ts/no-optional-call.ts","../src/rules/ts/no-optional-property-access.ts","../src/rules/ts/no-optional-element-access.ts","../src/rules/ts/no-logical-or-fallback.ts","../src/rules/ts/no-null-ternary-normalization.ts","../src/rules/ts/no-any-cast.ts","../src/rules/ts/no-explicit-any-annotation.ts","../src/rules/ts/no-inline-type-in-params.ts","../src/rules/ts/no-type-assertion.ts","../src/rules/ts/no-redundant-existence-guard.ts","../src/rules/ts/prefer-default-param-value.ts","../src/rules/ts/prefer-required-param-with-guard.ts","../src/rules/cross-file/duplicate-type-declaration.ts","../src/rules/cross-file/duplicate-function-declaration.ts","../src/rules/cross-file/optional-arg-always-used.ts","../src/rules/ts/no-catch-return.ts","../src/rules/ts/no-error-rewrap.ts","../src/rules/cross-file/explicit-null-arg.ts","../src/rules/cross-file/duplicate-function-name.ts","../src/rules/cross-file/duplicate-type-name.ts","../src/rules/ts/no-dynamic-import.ts","../src/rules/index.ts","../src/scan/config.ts","../src/scan/analyze.ts","../src/collect/index.ts","../src/utils/hash.ts","../src/collect/type-registry.ts","../src/collect/function-registry.ts","../src/rules/types.ts","../src/typecheck/program.ts","../src/typecheck/walk.ts","../src/scan/discover.ts","../src/scan/policy.ts","../src/engine.ts"],"sourcesContent":["import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\n\nexport const noEmptyCatch: TSRule = {\n kind: \"ts\",\n id: \"no-empty-catch\",\n severity: \"error\",\n message: \"Empty catch blocks hide failures; handle, annotate, or rethrow explicitly\",\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (!ts.isCatchClause(node)) return;\n const block = node.block;\n if (block.statements.length > 0) return;\n\n // Check for comments inside the block braces\n const blockStart = block.getStart(ctx.sourceFile);\n const blockEnd = block.getEnd();\n const inner = ctx.source.slice(blockStart + 1, blockEnd - 1);\n if (inner.includes(\"//\") || inner.includes(\"/*\")) return;\n\n ctx.report(node);\n },\n};\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\n\nexport const noNonNullAssertion: TSRule = {\n kind: \"ts\",\n id: \"no-non-null-assertion\",\n severity: \"warning\",\n message: \"Non-null assertion (!) overrides the type checker; narrow with a type guard or fix the type so it's not nullable\",\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (!ts.isNonNullExpression(node)) return;\n\n const inner = node.expression;\n\n // Type already non-nullable -> ! is redundant noise, not worth flagging\n if (!ctx.isNullable(inner)) return;\n\n // External library type gap -> suppress\n if (ctx.isExternal(inner)) return;\n\n // split(...)[n]! — always safe\n if (isSplitElementAccess(inner)) return;\n\n // filter(...)[n]! — safe pattern (narrowed array)\n if (isFilterElementAccess(inner)) return;\n\n // arr[n]! after a length guard — provably safe\n if (isLengthGuardedAccess(inner)) return;\n\n ctx.report(node);\n },\n};\n\nfunction isSplitElementAccess(node: ts.Node): boolean {\n if (!ts.isElementAccessExpression(node)) return false;\n const obj = node.expression;\n if (!ts.isCallExpression(obj)) return false;\n const callee = obj.expression;\n if (!ts.isPropertyAccessExpression(callee)) return false;\n return callee.name.text === \"split\";\n}\n\nfunction isFilterElementAccess(node: ts.Node): boolean {\n // Direct: items.filter(...)[n]!\n if (ts.isElementAccessExpression(node)) {\n const obj = node.expression;\n if (ts.isCallExpression(obj)) {\n const callee = obj.expression;\n if (ts.isPropertyAccessExpression(callee) && callee.name.text === \"filter\") return true;\n }\n // Indirect: const filtered = items.filter(...); filtered[n]!\n if (ts.isIdentifier(obj)) {\n const init = findVariableInit(obj);\n if (init && ts.isCallExpression(init)) {\n const callee = init.expression;\n if (ts.isPropertyAccessExpression(callee) && callee.name.text === \"filter\") return true;\n }\n }\n }\n return false;\n}\n\n/** Detect arr[n]! where arr.length is checked in a preceding guard or enclosing for-loop. */\nfunction isLengthGuardedAccess(node: ts.Node): boolean {\n if (!ts.isElementAccessExpression(node)) return false;\n const arr = node.expression;\n\n const arrName = getIdentifierName(arr);\n if (!arrName) return false;\n\n // Check for enclosing for-loop: for (let i = 0; i < arr.length; i++)\n if (isInsideForLoopBoundedBy(node, arrName)) return true;\n\n // Check for preceding length guard in same block\n return hasPrecedingLengthGuard(node, arrName);\n}\n\n/** Walk ancestors to find a for-loop whose condition bounds against arrName.length. */\nfunction isInsideForLoopBoundedBy(node: ts.Node, arrName: string): boolean {\n let current: ts.Node = node;\n while (current.parent) {\n current = current.parent;\n if (ts.isForStatement(current) && current.condition) {\n if (isLengthBoundCondition(current.condition, arrName)) return true;\n }\n }\n return false;\n}\n\n/** Check if a condition is `i < arr.length` or similar. */\nfunction isLengthBoundCondition(cond: ts.Expression, arrName: string): boolean {\n if (!ts.isBinaryExpression(cond)) return false;\n const op = cond.operatorToken.kind;\n // i < arr.length or i <= arr.length - 1\n if (op === ts.SyntaxKind.LessThanToken || op === ts.SyntaxKind.LessThanEqualsToken) {\n return isLengthAccess(cond.right, arrName);\n }\n // arr.length > i\n if (op === ts.SyntaxKind.GreaterThanToken || op === ts.SyntaxKind.GreaterThanEqualsToken) {\n return isLengthAccess(cond.left, arrName);\n }\n return false;\n}\n\n/** Check if node is `arrName.length`. */\nfunction isLengthAccess(node: ts.Node, arrName: string): boolean {\n if (!ts.isPropertyAccessExpression(node)) return false;\n if (node.name.text !== \"length\") return false;\n return getIdentifierName(node.expression) === arrName;\n}\n\n/**\n * Check if there's a preceding statement in the same block (or a parent block)\n * that guards on arrName.length, implying the array is non-empty.\n *\n * Patterns:\n * - if (arr.length === 0) return;\n * - if (arr.length < N) return; (where N >= 1)\n * - if (arr.length > 0) { ... arr[0]! ... }\n * - if (arr.length !== 0) { ... arr[0]! ... }\n * - if (arr.length >= 1) { ... arr[0]! ... }\n * - if (arr.length !== N) return; (where N >= 1)\n */\nfunction hasPrecedingLengthGuard(node: ts.Node, arrName: string): boolean {\n // Walk up to find the containing block/if-statement\n let current: ts.Node = node;\n while (current.parent) {\n const parent = current.parent;\n\n // Case 1: we're in a block and a preceding if-statement guards length with early return\n if (ts.isBlock(parent)) {\n for (const stmt of parent.statements) {\n if (stmt === current || stmt.pos >= current.pos) break;\n if (ts.isIfStatement(stmt) && isLengthGuardWithEarlyExit(stmt, arrName)) return true;\n }\n }\n\n // Case 2: we're inside the then-branch of an if that checks length > 0\n if (ts.isIfStatement(parent) && parent.thenStatement === current) {\n if (isPositiveLengthCheck(parent.expression, arrName)) return true;\n }\n // Also handle: if (...) { <block containing current> }\n if (ts.isBlock(current) && ts.isIfStatement(parent) && parent.thenStatement === current) {\n if (isPositiveLengthCheck(parent.expression, arrName)) return true;\n }\n\n current = parent;\n }\n return false;\n}\n\n/** if (arr.length === 0) return/throw; or if (arr.length < 1) return/throw; etc. */\nfunction isLengthGuardWithEarlyExit(stmt: ts.IfStatement, arrName: string): boolean {\n if (!isEarlyExit(stmt.thenStatement)) return false;\n return isZeroLengthCheck(stmt.expression, arrName);\n}\n\n/** Checks if condition means \"arr is empty\": arr.length === 0, arr.length < 1, arr.length !== N (N>=1) */\nfunction isZeroLengthCheck(expr: ts.Expression, arrName: string): boolean {\n if (!ts.isBinaryExpression(expr)) return false;\n const op = expr.operatorToken.kind;\n\n // arr.length === 0\n if ((op === ts.SyntaxKind.EqualsEqualsEqualsToken || op === ts.SyntaxKind.EqualsEqualsToken)) {\n if (isLengthAccess(expr.left, arrName) && isNumericLiteralValue(expr.right, 0)) return true;\n if (isLengthAccess(expr.right, arrName) && isNumericLiteralValue(expr.left, 0)) return true;\n }\n\n // arr.length < 1 (or any N >= 1)\n if (op === ts.SyntaxKind.LessThanToken) {\n if (isLengthAccess(expr.left, arrName) && isNumericLiteralGte(expr.right, 1)) return true;\n }\n\n // arr.length !== N where N >= 1 (e.g., if (arr.length !== 1) return; arr[0]!)\n if ((op === ts.SyntaxKind.ExclamationEqualsEqualsToken || op === ts.SyntaxKind.ExclamationEqualsToken)) {\n if (isLengthAccess(expr.left, arrName) && isNumericLiteralGte(expr.right, 1)) return true;\n }\n\n return false;\n}\n\n/** Checks if condition means \"arr is non-empty\": arr.length > 0, arr.length !== 0, arr.length >= 1 */\nfunction isPositiveLengthCheck(expr: ts.Expression, arrName: string): boolean {\n if (!ts.isBinaryExpression(expr)) return false;\n const op = expr.operatorToken.kind;\n\n // arr.length > 0\n if (op === ts.SyntaxKind.GreaterThanToken) {\n if (isLengthAccess(expr.left, arrName) && isNumericLiteralValue(expr.right, 0)) return true;\n }\n\n // arr.length >= 1\n if (op === ts.SyntaxKind.GreaterThanEqualsToken) {\n if (isLengthAccess(expr.left, arrName) && isNumericLiteralGte(expr.right, 1)) return true;\n }\n\n // arr.length !== 0\n if ((op === ts.SyntaxKind.ExclamationEqualsEqualsToken || op === ts.SyntaxKind.ExclamationEqualsToken)) {\n if (isLengthAccess(expr.left, arrName) && isNumericLiteralValue(expr.right, 0)) return true;\n }\n\n return false;\n}\n\nfunction isEarlyExit(stmt: ts.Statement): boolean {\n if (ts.isReturnStatement(stmt) || ts.isThrowStatement(stmt)) return true;\n if (ts.isBlock(stmt) && stmt.statements.length === 1) {\n const inner = stmt.statements[0];\n if (inner === undefined) return false;\n return ts.isReturnStatement(inner) || ts.isThrowStatement(inner);\n }\n return false;\n}\n\nfunction isNumericLiteralValue(node: ts.Node, value: number): boolean {\n return ts.isNumericLiteral(node) && node.text === String(value);\n}\n\nfunction isNumericLiteralGte(node: ts.Node, min: number): boolean {\n return ts.isNumericLiteral(node) && Number(node.text) >= min;\n}\n\nfunction getIdentifierName(node: ts.Node): string | null {\n if (ts.isIdentifier(node)) return node.text;\n return null;\n}\n\nfunction findVariableInit(id: ts.Identifier): ts.Expression | undefined {\n const sourceFile = id.getSourceFile();\n let result: ts.Expression | undefined;\n function visit(node: ts.Node): void {\n if (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name) && node.name.text === id.text && node.initializer) {\n result = node.initializer;\n }\n if (!result) ts.forEachChild(node, visit);\n }\n visit(sourceFile);\n return result;\n}\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\nimport { includesBooleanType } from \"../../typecheck/utils.ts\";\n\nexport const noDoubleNegationCoercion: TSRule = {\n kind: \"ts\",\n id: \"no-double-negation-coercion\",\n severity: \"info\",\n message: \"!! coercion hides intent; use an explicit check (!== null, !== undefined, .length > 0) so the condition documents what it tests\",\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (!ts.isPrefixUnaryExpression(node)) return;\n if (node.operator !== ts.SyntaxKind.ExclamationToken) return;\n const inner = node.operand;\n if (!ts.isPrefixUnaryExpression(inner)) return;\n if (inner.operator !== ts.SyntaxKind.ExclamationToken) return;\n\n const operand = inner.operand;\n\n // Already boolean -> !! is a no-op, promote severity\n const innerType = ctx.checker.getTypeAtLocation(operand);\n if (includesBooleanType(innerType) && !(innerType.flags & ts.TypeFlags.Union)) {\n ctx.report(node, \"!! on an already-boolean type is a no-op; remove the double negation\");\n return;\n }\n\n // Bitwise expression: !!(flags & MASK) is the standard idiom for flag testing\n if (isBitwiseExpression(operand)) return;\n\n ctx.report(node);\n },\n};\n\nconst BITWISE_OPS = new Set([\n ts.SyntaxKind.AmpersandToken,\n ts.SyntaxKind.BarToken,\n ts.SyntaxKind.CaretToken,\n ts.SyntaxKind.LessThanLessThanToken,\n ts.SyntaxKind.GreaterThanGreaterThanToken,\n ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken,\n]);\n\nfunction isBitwiseExpression(node: ts.Node): boolean {\n // Direct: !!(a & b)\n if (ts.isBinaryExpression(node) && BITWISE_OPS.has(node.operatorToken.kind)) return true;\n // Parenthesized: !!((a & b) | c)\n if (ts.isParenthesizedExpression(node)) return isBitwiseExpression(node.expression);\n return false;\n}\n","import * as ts from \"typescript\";\n\nfunction hasFlags(flags: number, mask: number): boolean {\n return (flags & mask) !== 0;\n}\n\nconst NULLISH_FLAGS = ts.TypeFlags.Null | ts.TypeFlags.Undefined | ts.TypeFlags.Void;\n\nexport function isNullableType(checker: ts.TypeChecker, type: ts.Type): boolean {\n if (type.isUnion()) {\n return type.types.some((t) => hasFlags(t.flags, NULLISH_FLAGS));\n }\n return hasFlags(type.flags, NULLISH_FLAGS);\n}\n\nexport function isFromNodeModules(node: ts.Node): boolean {\n const sourceFile = node.getSourceFile();\n return sourceFile.fileName.includes(\"/node_modules/\");\n}\n\nexport function includesNumberType(type: ts.Type): boolean {\n if (type.isUnion()) {\n return type.types.some((t) => hasFlags(t.flags, ts.TypeFlags.NumberLike));\n }\n return hasFlags(type.flags, ts.TypeFlags.NumberLike);\n}\n\nexport function includesBooleanType(type: ts.Type): boolean {\n if (type.isUnion()) {\n return type.types.some((t) => hasFlags(t.flags, ts.TypeFlags.BooleanLike));\n }\n return hasFlags(type.flags, ts.TypeFlags.BooleanLike);\n}\n\nexport function isNullishLiteral(node: ts.Node): boolean {\n if (node.kind === ts.SyntaxKind.NullKeyword) return true;\n if (ts.isIdentifier(node) && node.text === \"undefined\") return true;\n return false;\n}\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\n\nexport const noTsIgnore: TSRule = {\n kind: \"ts\",\n id: \"no-ts-ignore\",\n severity: \"error\",\n message: \"@ts-ignore / @ts-expect-error suppresses type checking; fix the underlying type issue\",\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n const ranges = ts.getLeadingCommentRanges(ctx.source, node.getFullStart());\n if (!ranges) return;\n for (const range of ranges) {\n const text = ctx.source.slice(range.pos, range.end);\n if (text.includes(\"@ts-ignore\") || text.includes(\"@ts-expect-error\")) {\n ctx.reportAtOffset(range.pos);\n }\n }\n },\n};\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\n\nexport const noNullishCoalescing: TSRule = {\n kind: \"ts\",\n id: \"no-nullish-coalescing\",\n severity: \"warning\",\n message: \"Nullish coalescing (??) on a non-nullable type is unreachable; remove the fallback or fix the type upstream\",\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (!ts.isBinaryExpression(node)) return;\n if (node.operatorToken.kind !== ts.SyntaxKind.QuestionQuestionToken) return;\n if (ctx.isNullable(node.left)) return;\n ctx.report(node);\n },\n};\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\n\nexport const noOptionalCall: TSRule = {\n kind: \"ts\",\n id: \"no-optional-call\",\n severity: \"warning\",\n message: \"Optional call (?.) on a non-nullable function is redundant; call directly or fix the type upstream\",\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (!ts.isCallExpression(node)) return;\n if (!node.questionDotToken) return;\n if (ctx.isNullable(node.expression)) return;\n ctx.report(node);\n },\n};\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\n\nexport const noOptionalPropertyAccess: TSRule = {\n kind: \"ts\",\n id: \"no-optional-property-access\",\n severity: \"warning\",\n message: \"Optional chaining (?.) on a non-nullable type is redundant; use direct access or fix the type upstream\",\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (!ts.isPropertyAccessExpression(node)) return;\n if (!node.questionDotToken) return;\n if (ctx.isNullable(node.expression)) return;\n ctx.report(node);\n },\n};\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\n\nexport const noOptionalElementAccess: TSRule = {\n kind: \"ts\",\n id: \"no-optional-element-access\",\n severity: \"warning\",\n message: \"Optional element access (?.[]) on a non-nullable type is redundant; use direct access or fix the type upstream\",\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (!ts.isElementAccessExpression(node)) return;\n if (!node.questionDotToken) return;\n if (ctx.isNullable(node.expression)) return;\n ctx.report(node);\n },\n};\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\nimport { includesNumberType, isNullableType } from \"../../typecheck/utils.ts\";\n\nexport const noLogicalOrFallback: TSRule = {\n kind: \"ts\",\n id: \"no-logical-or-fallback\",\n severity: \"warning\",\n message:\n '|| fallback on a data-structure lookup swallows valid falsy values (0, \"\"); use ?? to only catch null/undefined',\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (!ts.isBinaryExpression(node)) return;\n if (node.operatorToken.kind !== ts.SyntaxKind.BarBarToken) return;\n\n const right = node.right;\n if (!isLiteral(right)) return;\n\n const left = node.left;\n const lhsType = ctx.checker.getTypeAtLocation(left);\n\n // Number() / parseInt() — || catches NaN/0 intentionally, ?? would not help\n if (isNumericCoercionCall(left)) return;\n\n // String type without undefined: || catches \"\" intentionally — suppress\n // String | undefined: || swallows \"\" AND catches undefined — should use ??\n if (isStringNotNullable(lhsType, ctx.checker)) return;\n\n // LHS includes number and RHS is not 0 -> catches bugs like `seed || undefined`\n if (includesNumberType(lhsType) && !isZeroLiteral(right)) {\n ctx.report(node, '|| on a numeric type swallows 0; use ?? to only catch null/undefined');\n return;\n }\n\n // Data-structure lookups: .get(), .find(), x[key], optional chaining\n if (isDataStructureLookup(left)) {\n ctx.report(node);\n }\n },\n};\n\n/** LHS is string (or string-like) without null/undefined in the union. */\nfunction isStringNotNullable(type: ts.Type, checker: ts.TypeChecker): boolean {\n if (isNullableType(checker, type)) return false;\n if (type.isUnion()) {\n return type.types.every((t) => (t.flags & ts.TypeFlags.StringLike) !== 0);\n }\n return (type.flags & ts.TypeFlags.StringLike) !== 0;\n}\n\nfunction isLiteral(node: ts.Node): boolean {\n if (ts.isStringLiteral(node) || ts.isNumericLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node)) return true;\n if (ts.isTemplateExpression(node)) return true;\n if (ts.isArrayLiteralExpression(node) || ts.isObjectLiteralExpression(node)) return true;\n if (ts.isIdentifier(node) && node.text === \"undefined\") return true;\n if (node.kind === ts.SyntaxKind.NullKeyword) return true;\n if (node.kind === ts.SyntaxKind.TrueKeyword || node.kind === ts.SyntaxKind.FalseKeyword) return true;\n return false;\n}\n\n/** Number(...) or parseInt(...) — returns number, || catches NaN/0, ?? wouldn't help */\nfunction isNumericCoercionCall(node: ts.Node): boolean {\n if (!ts.isCallExpression(node)) return false;\n if (!ts.isIdentifier(node.expression)) return false;\n const name = node.expression.text;\n return name === \"Number\" || name === \"parseInt\" || name === \"parseFloat\";\n}\n\nfunction isZeroLiteral(node: ts.Node): boolean {\n return ts.isNumericLiteral(node) && node.text === \"0\";\n}\n\nfunction isDataStructureLookup(left: ts.Node): boolean {\n // Flag: LHS is .get(), .find(), .getStore() call\n if (ts.isCallExpression(left)) {\n const callee = left.expression;\n if (ts.isPropertyAccessExpression(callee)) {\n const methodName = callee.name.text;\n if (methodName === \"find\" || methodName === \"getStore\" || methodName === \"get\") return true;\n }\n }\n\n // Flag: LHS is computed member expression x[key]\n if (ts.isElementAccessExpression(left)) return true;\n\n // Flag: LHS contains optional chaining (?.)\n if (hasOptionalChaining(left)) return true;\n\n return false;\n}\n\nfunction hasOptionalChaining(node: ts.Node): boolean {\n if (ts.isPropertyAccessExpression(node) && node.questionDotToken) return true;\n if (ts.isElementAccessExpression(node) && node.questionDotToken) return true;\n if (ts.isCallExpression(node) && node.questionDotToken) return true;\n if (ts.isPropertyAccessExpression(node)) return hasOptionalChaining(node.expression);\n if (ts.isCallExpression(node)) return hasOptionalChaining(node.expression);\n if (ts.isElementAccessExpression(node)) return hasOptionalChaining(node.expression);\n return false;\n}\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\n\nexport const noNullTernaryNormalization: TSRule = {\n kind: \"ts\",\n id: \"no-null-ternary-normalization\",\n severity: \"warning\",\n message: \"Ternary null-normalization (x == null ? fallback : x); if the type guarantees non-null, remove the ternary; if not, fix the type upstream\",\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (!ts.isConditionalExpression(node)) return;\n const test = node.condition;\n if (!ts.isBinaryExpression(test)) return;\n\n const op = test.operatorToken.kind;\n if (\n op !== ts.SyntaxKind.EqualsEqualsEqualsToken &&\n op !== ts.SyntaxKind.ExclamationEqualsEqualsToken &&\n op !== ts.SyntaxKind.EqualsEqualsToken &&\n op !== ts.SyntaxKind.ExclamationEqualsToken\n ) return;\n\n const hasNullishComparand = isNullish(test.left) || isNullish(test.right);\n if (!hasNullishComparand) return;\n\n if (isNullish(node.whenTrue) || isNullish(node.whenFalse)) {\n // Non-nullable tested value -> this is dead code\n const tested = isNullish(test.left) ? test.right : test.left;\n if (!ctx.isNullable(tested)) {\n ctx.report(node, \"Ternary null-normalization on a non-nullable type is dead code; remove the ternary\");\n return;\n }\n ctx.report(node);\n }\n },\n};\n\nfunction isNullish(node: ts.Node): boolean {\n if (node.kind === ts.SyntaxKind.NullKeyword) return true;\n if (ts.isIdentifier(node) && node.text === \"undefined\") return true;\n // void 0\n if (ts.isVoidExpression(node)) return true;\n return false;\n}\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\n\nexport const noAnyCast: TSRule = {\n kind: \"ts\",\n id: \"no-any-cast\",\n severity: \"error\",\n message: \"Casting to `any` erases type safety; use a specific type or generic instead\",\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (!ts.isAsExpression(node)) return;\n if (node.type.kind !== ts.SyntaxKind.AnyKeyword) return;\n ctx.report(node);\n },\n};\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\n\nexport const noExplicitAnyAnnotation: TSRule = {\n kind: \"ts\",\n id: \"no-explicit-any-annotation\",\n severity: \"error\",\n message: \"Explicit `any` annotation erases type safety; use a specific type, `unknown`, or a generic\",\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (node.kind !== ts.SyntaxKind.AnyKeyword) return;\n if (node.parent && ts.isAsExpression(node.parent)) return;\n ctx.report(node);\n },\n};\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\n\nfunction isTopLevelFunctionParam(source: string, offset: number): boolean {\n let depth = 0;\n for (let i = offset - 1; i >= 0; i--) {\n if (source[i] === \"}\") depth++;\n if (source[i] === \"{\") {\n if (depth === 0) {\n const before = source.slice(Math.max(0, i - 150), i).trimEnd();\n if (/(\\)|\\bfunction\\b.*\\))\\s*$/.test(before)) {\n depth--;\n continue;\n }\n return false;\n }\n depth--;\n }\n }\n return true;\n}\n\nexport const noInlineTypeInParams: TSRule = {\n kind: \"ts\",\n id: \"no-inline-type-in-params\",\n severity: \"info\",\n message: \"Inline type literal in annotation; extract to a named type for reuse and clarity\",\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (!ts.isTypeLiteralNode(node)) return;\n // Parent should be a type annotation on a parameter\n const parent = node.parent;\n if (!parent || !ts.isParameter(parent)) return;\n if (parent.type !== node) return;\n\n const offset = node.getStart(ctx.sourceFile);\n if (!isTopLevelFunctionParam(ctx.source, offset)) return;\n ctx.report(node);\n },\n};\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\n\nexport const noTypeAssertion: TSRule = {\n kind: \"ts\",\n id: \"no-type-assertion\",\n severity: \"error\",\n message: \"Double type assertion (`as unknown as T`) circumvents the type system; fix the upstream type or use a type guard\",\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (!ts.isAsExpression(node)) return;\n if (!ts.isAsExpression(node.expression)) return;\n if (node.expression.type.kind !== ts.SyntaxKind.UnknownKeyword) return;\n ctx.report(node);\n },\n};\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\nimport { isNullishLiteral } from \"../../typecheck/utils.ts\";\n\nexport const noRedundantExistenceGuard: TSRule = {\n kind: \"ts\",\n id: \"no-redundant-existence-guard\",\n severity: \"warning\",\n message: \"Redundant existence guard (obj && obj.prop) on a non-nullable type; remove the guard or fix the type upstream\",\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (!ts.isBinaryExpression(node)) return;\n if (node.operatorToken.kind !== ts.SyntaxKind.AmpersandAmpersandToken) return;\n\n const left = node.left;\n const right = node.right;\n\n // Pattern 1: obj && obj.prop / obj.method() / obj[key]\n if (ts.isIdentifier(left) && accessesIdentifier(right, left.text)) {\n if (ctx.isNullable(left)) return;\n ctx.report(node);\n return;\n }\n\n // Pattern 2: obj != null && obj.prop (or !== null, !== undefined)\n if (ts.isBinaryExpression(left) && isNullCheck(left)) {\n const checked = getNullCheckedIdentifier(left);\n if (checked && accessesIdentifier(right, checked)) {\n // The null-check LHS is the identifier — check its type before the comparison\n // If the type is non-nullable, the entire guard is redundant\n const identNode = ts.isIdentifier(left.left) ? left.left : left.right;\n if (ts.isIdentifier(identNode) && identNode.text === checked && !ctx.isNullable(identNode)) {\n ctx.report(node);\n }\n }\n }\n },\n};\n\n/** Check if the root object of `expr` is identifier `name`. */\nfunction accessesIdentifier(expr: ts.Node, name: string): boolean {\n const root = getExpressionRoot(expr);\n return ts.isIdentifier(root) && root.text === name;\n}\n\n/** Walk through property access, element access, and call chains to find the root expression. */\nfunction getExpressionRoot(node: ts.Node): ts.Node {\n if (ts.isPropertyAccessExpression(node)) return getExpressionRoot(node.expression);\n if (ts.isElementAccessExpression(node)) return getExpressionRoot(node.expression);\n if (ts.isCallExpression(node)) return getExpressionRoot(node.expression);\n return node;\n}\n\n/** Check if expr is a null/undefined comparison: x != null, x !== null, x !== undefined */\nfunction isNullCheck(expr: ts.BinaryExpression): boolean {\n const op = expr.operatorToken.kind;\n if (op !== ts.SyntaxKind.ExclamationEqualsToken && op !== ts.SyntaxKind.ExclamationEqualsEqualsToken) return false;\n return isNullishLiteral(expr.right) || isNullishLiteral(expr.left);\n}\n\n/** Get the identifier name being null-checked. */\nfunction getNullCheckedIdentifier(expr: ts.BinaryExpression): string | null {\n if (ts.isIdentifier(expr.left) && isNullishLiteral(expr.right)) return expr.left.text;\n if (ts.isIdentifier(expr.right) && isNullishLiteral(expr.left)) return expr.right.text;\n return null;\n}\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\n\nexport const preferDefaultParamValue: TSRule = {\n kind: \"ts\",\n id: \"prefer-default-param-value\",\n severity: \"info\",\n message: \"Use a default parameter value instead of reassigning from nullish coalescing inside the body\",\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (!ts.isFunctionDeclaration(node) && !ts.isArrowFunction(node)) return;\n if (!node.body || !ts.isBlock(node.body)) return;\n const stmts = node.body.statements;\n if (stmts.length === 0) return;\n\n const firstStmt = stmts[0];\n if (firstStmt === undefined || !ts.isExpressionStatement(firstStmt)) return;\n const expr = firstStmt.expression;\n if (!ts.isBinaryExpression(expr) || expr.operatorToken.kind !== ts.SyntaxKind.EqualsToken) return;\n\n const right = expr.right;\n if (!ts.isBinaryExpression(right) || right.operatorToken.kind !== ts.SyntaxKind.QuestionQuestionToken) return;\n\n if (!ts.isIdentifier(expr.left) || !ts.isIdentifier(right.left)) return;\n if (expr.left.text !== right.left.text) return;\n\n const paramName = expr.left.text;\n const isParam = node.parameters.some((p) => ts.isIdentifier(p.name) && p.name.text === paramName);\n if (isParam) ctx.report(firstStmt);\n },\n};\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\n\nexport const preferRequiredParamWithGuard: TSRule = {\n kind: \"ts\",\n id: \"prefer-required-param-with-guard\",\n severity: \"info\",\n message: \"Optional param with immediate guard (if (!param) return/throw); make it required instead\",\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (!ts.isFunctionDeclaration(node) && !ts.isArrowFunction(node)) return;\n if (!node.body || !ts.isBlock(node.body)) return;\n const stmts = node.body.statements;\n if (stmts.length === 0) return;\n\n const firstStmt = stmts[0];\n if (firstStmt === undefined || !ts.isIfStatement(firstStmt)) return;\n\n const test = firstStmt.expression;\n let guardedName: string | null = null;\n\n // Pattern 1: if (!param)\n if (ts.isPrefixUnaryExpression(test) && test.operator === ts.SyntaxKind.ExclamationToken) {\n if (ts.isIdentifier(test.operand)) guardedName = test.operand.text;\n }\n // Pattern 2: if (param === undefined)\n if (ts.isBinaryExpression(test)) {\n const op = test.operatorToken.kind;\n if (op === ts.SyntaxKind.EqualsEqualsEqualsToken || op === ts.SyntaxKind.EqualsEqualsToken) {\n if (ts.isIdentifier(test.left) && ts.isIdentifier(test.right) && test.right.text === \"undefined\") {\n guardedName = test.left.text;\n }\n }\n }\n\n if (!guardedName) return;\n\n const consequent = firstStmt.thenStatement;\n const isGuard =\n ts.isReturnStatement(consequent) ||\n ts.isThrowStatement(consequent) ||\n (ts.isBlock(consequent) &&\n consequent.statements.length === 1 &&\n consequent.statements[0] !== undefined &&\n (ts.isReturnStatement(consequent.statements[0]) || ts.isThrowStatement(consequent.statements[0])));\n\n if (!isGuard) return;\n\n const isOptional = node.parameters.some(\n (p) => ts.isIdentifier(p.name) && p.name.text === guardedName && p.questionToken !== undefined,\n );\n if (isOptional) ctx.report(firstStmt);\n },\n};\n","import type { CrossFileRule, Diagnostic, ProjectIndex } from \"../types.ts\";\n\nexport const duplicateTypeDeclaration: CrossFileRule = {\n id: \"duplicate-type-declaration\",\n severity: \"warning\",\n message: \"Identical type shape declared in multiple files; consolidate to a single definition\",\n\n analyze(project: ProjectIndex): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n for (const group of project.types.getDuplicateGroups()) {\n // Only flag if types are in different files\n const files = new Set(group.map((e) => e.file));\n if (files.size < 2) continue;\n\n const sorted = [...group].sort((a, b) => a.file.localeCompare(b.file) || a.line - b.line);\n for (const entry of sorted.slice(1)) {\n const others = sorted\n .filter((e) => e !== entry)\n .map((e) => `${e.name} (${e.file}:${e.line})`)\n .join(\", \");\n diagnostics.push({\n ruleId: this.id,\n severity: this.severity,\n message: `Type \"${entry.name}\" has identical shape to: ${others}`,\n file: entry.file,\n line: entry.line,\n column: 1,\n });\n }\n }\n return diagnostics;\n },\n};\n","import * as ts from \"typescript\";\nimport type { CrossFileRule, Diagnostic, ProjectIndex } from \"../types.ts\";\n\nexport const duplicateFunctionDeclaration: CrossFileRule = {\n id: \"duplicate-function-declaration\",\n severity: \"warning\",\n message: \"Identical function body declared in multiple files; consolidate to a single definition\",\n\n analyze(project: ProjectIndex): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n for (const group of project.functions.getDuplicateGroups()) {\n const files = new Set(group.map((e) => e.file));\n if (files.size < 2) continue;\n\n // Skip setter pattern: single-assignment body (e.g. `botApi = api`)\n // These close over different module-scoped variables despite identical body text\n const first = group[0];\n if (first !== undefined && isSetter(first.node)) continue;\n\n const sorted = [...group].sort((a, b) => a.file.localeCompare(b.file) || a.line - b.line);\n for (const entry of sorted.slice(1)) {\n const others = sorted\n .filter((e) => e !== entry)\n .map((e) => `${e.name} (${e.file}:${e.line})`)\n .join(\", \");\n diagnostics.push({\n ruleId: this.id,\n severity: this.severity,\n message: `Function \"${entry.name}\" has identical body to: ${others}`,\n file: entry.file,\n line: entry.line,\n column: 1,\n });\n }\n }\n return diagnostics;\n },\n};\n\nfunction isSetter(node: ts.Node): boolean {\n let body: ts.Block | undefined;\n if (ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node)) {\n body = node.body;\n } else if (ts.isArrowFunction(node)) {\n body = ts.isBlock(node.body) ? node.body : undefined;\n }\n if (!body || body.statements.length !== 1) return false;\n const stmt = body.statements[0];\n if (stmt === undefined || !ts.isExpressionStatement(stmt)) return false;\n return ts.isBinaryExpression(stmt.expression) &&\n stmt.expression.operatorToken.kind === ts.SyntaxKind.EqualsToken;\n}\n","import type { CrossFileRule, Diagnostic, ProjectIndex } from \"../types.ts\";\n\nexport const optionalArgAlwaysUsed: CrossFileRule = {\n id: \"optional-arg-always-used\",\n severity: \"warning\",\n message: \"Optional parameter is always provided at every call site; make it required\",\n\n analyze(project: ProjectIndex): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n\n for (const fn of project.functions.getAll()) {\n // Find optional params (by index)\n for (let i = 0; i < fn.params.length; i++) {\n const param = fn.params[i];\n if (param === undefined) continue;\n if (!param.optional && !param.hasDefault) continue;\n\n // Find call sites for this function — use symbol matching when available\n const callSites = fn.symbol\n ? project.callSites.filter((c) => c.symbol === fn.symbol)\n : project.callSites.filter((c) => c.calleeName === fn.name);\n\n // Need at least 2 call sites to be meaningful\n if (callSites.length < 2) continue;\n\n // Check if every call site provides this positional argument\n const allProvide = callSites.every((c) => c.argCount > i);\n if (allProvide) {\n diagnostics.push({\n ruleId: this.id,\n severity: this.severity,\n message: `Optional parameter \"${param.name}\" is always provided at all ${callSites.length} call sites; make it required`,\n file: fn.file,\n line: fn.line,\n column: 1,\n });\n }\n }\n }\n\n return diagnostics;\n },\n};\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\n\nexport const noCatchReturn: TSRule = {\n kind: \"ts\",\n id: \"no-catch-return\",\n severity: \"warning\",\n message:\n \"Catch block silently returns a fallback value with no logging; rethrow, log the error, or let it propagate\",\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (!ts.isCatchClause(node)) return;\n const block = node.block;\n if (hasReturn(block) && !hasThrow(block) && !hasLogging(block)) {\n ctx.report(node);\n }\n },\n};\n\nfunction walkBlock(block: ts.Block, predicate: (node: ts.Node) => boolean): boolean {\n function visit(node: ts.Node): boolean {\n if (predicate(node)) return true;\n if (ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) || ts.isArrowFunction(node)) return false;\n return ts.forEachChild(node, visit) ?? false;\n }\n return ts.forEachChild(block, visit) ?? false;\n}\n\nfunction hasReturn(block: ts.Block): boolean {\n return walkBlock(block, (n) => ts.isReturnStatement(n));\n}\n\nfunction hasThrow(block: ts.Block): boolean {\n return walkBlock(block, (n) => ts.isThrowStatement(n));\n}\n\nconst LOG_OBJECTS = new Set([\"console\", \"logger\", \"log\"]);\n\nfunction hasLogging(block: ts.Block): boolean {\n return walkBlock(block, (n) => {\n if (!ts.isCallExpression(n)) return false;\n const callee = n.expression;\n if (!ts.isPropertyAccessExpression(callee)) return false;\n if (!ts.isIdentifier(callee.expression)) return false;\n return LOG_OBJECTS.has(callee.expression.text);\n });\n}\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\n\nexport const noErrorRewrap: TSRule = {\n kind: \"ts\",\n id: \"no-error-rewrap\",\n severity: \"error\",\n message:\n \"Re-wrapped error loses the original stack trace and type; use { cause: originalError } to preserve the error chain\",\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (!ts.isCatchClause(node)) return;\n if (!node.variableDeclaration) return;\n const param = node.variableDeclaration.name;\n if (!ts.isIdentifier(param)) return;\n const catchName = param.text;\n findRewraps(node.block, catchName, ctx);\n },\n};\n\nfunction findRewraps(block: ts.Block, catchName: string, ctx: TSVisitContext): void {\n function visit(node: ts.Node): void {\n if (ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) || ts.isArrowFunction(node)) return;\n if (ts.isThrowStatement(node) && node.expression && ts.isNewExpression(node.expression)) {\n const args = node.expression.arguments;\n if (args && args.length > 0 && referencesName(args, catchName) && !hasCauseArg(args)) {\n ctx.report(node);\n }\n return;\n }\n ts.forEachChild(node, visit);\n }\n ts.forEachChild(block, visit);\n}\n\nfunction referencesName(args: readonly ts.Expression[], name: string): boolean {\n for (const arg of args) {\n if (containsIdentifier(arg, name)) return true;\n }\n return false;\n}\n\nfunction containsIdentifier(node: ts.Node, name: string): boolean {\n if (ts.isIdentifier(node) && node.text === name) return true;\n return ts.forEachChild(node, (child) => containsIdentifier(child, name) || undefined) ?? false;\n}\n\nfunction hasCauseArg(args: readonly ts.Expression[]): boolean {\n for (const arg of args) {\n if (ts.isObjectLiteralExpression(arg)) {\n for (const prop of arg.properties) {\n if (ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name) && prop.name.text === \"cause\") return true;\n if (ts.isShorthandPropertyAssignment(prop) && prop.name.text === \"cause\") return true;\n }\n }\n }\n return false;\n}\n","import * as ts from \"typescript\";\nimport type { CrossFileRule, Diagnostic, ProjectIndex } from \"../types.ts\";\nimport { isNullishLiteral } from \"../../typecheck/utils.ts\";\n\nexport const explicitNullArg: CrossFileRule = {\n id: \"explicit-null-arg\",\n severity: \"warning\",\n message: \"Explicit null/undefined passed to a project function; consider redesigning the interface to not accept nullish values\",\n\n analyze(project: ProjectIndex): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n\n // Build lookup structures for known project functions\n const projectFnNames = new Set<string>();\n const projectFnSymbols = new Set<ts.Symbol>();\n for (const fn of project.functions.getAll()) {\n projectFnNames.add(fn.name);\n if (fn.symbol) projectFnSymbols.add(fn.symbol);\n }\n\n for (const site of project.callSites) {\n // Only flag calls to functions defined in the project — prefer symbol matching\n const isProjectFn = site.symbol\n ? projectFnSymbols.has(site.symbol)\n : projectFnNames.has(site.calleeName);\n if (!isProjectFn) continue;\n\n for (let i = 0; i < site.node.arguments.length; i++) {\n const arg = site.node.arguments[i];\n if (arg === undefined) continue;\n if (isNullishLiteral(arg)) {\n const val = arg.kind === ts.SyntaxKind.NullKeyword ? \"null\" : \"undefined\";\n diagnostics.push({\n ruleId: this.id,\n severity: this.severity,\n message: `Passing explicit ${val} to \"${site.calleeName}\" at argument ${i + 1}; consider redesigning the interface to not accept nullish values`,\n file: site.file,\n line: site.line,\n column: 1,\n });\n break; // one diagnostic per call site\n }\n }\n }\n\n return diagnostics;\n },\n};\n\n","import { dirname, resolve } from \"node:path\";\nimport type { CrossFileRule, Diagnostic, ProjectIndex } from \"../types.ts\";\n\nconst EXTENSIONS = [\".ts\", \".tsx\", \".mts\", \".cts\", \".js\", \".jsx\", \".mjs\", \".cjs\"];\n\nexport const duplicateFunctionName: CrossFileRule = {\n id: \"duplicate-function-name\",\n severity: \"warning\",\n message: \"Same function name exported from multiple files; consolidate or rename to avoid ambiguity\",\n\n analyze(project: ProjectIndex): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n for (const group of project.functions.getNameCollisionGroups()) {\n // Skip groups already caught by duplicate-function-declaration (identical bodies)\n const hashes = new Set(group.map((e) => e.hash));\n if (hashes.size === 1) continue;\n\n // Skip wrapper/facade pattern: one file imports the function from another file in the group\n // Also handles barrel re-exports (A imports from barrel, barrel re-exports from B in group)\n const groupFiles = new Set(group.map((e) => e.file));\n const first = group[0];\n if (first === undefined) continue;\n const funcName = first.name;\n const hasImportLink = project.imports.some((imp) => {\n if (!groupFiles.has(imp.file)) return false;\n if (imp.importedName !== funcName && imp.localName !== funcName) return false;\n if (!imp.source.startsWith(\".\")) return false;\n const candidates = resolveCandidates(imp.file, imp.source);\n // Direct link: import resolves to a file in the group\n if (candidates.some((c) => groupFiles.has(c))) return true;\n // Barrel link: import resolves to an intermediary that re-exports from a group file\n return candidates.some((c) =>\n project.imports.some((reExp) => {\n if (reExp.file !== c) return false;\n if (reExp.importedName !== funcName && reExp.localName !== funcName) return false;\n if (!reExp.source.startsWith(\".\")) return false;\n const innerCandidates = resolveCandidates(reExp.file, reExp.source);\n return innerCandidates.some((ic) => groupFiles.has(ic));\n }),\n );\n });\n if (hasImportLink) continue;\n\n const sorted = [...group].sort((a, b) => a.file.localeCompare(b.file) || a.line - b.line);\n for (const entry of sorted.slice(1)) {\n const others = sorted\n .filter((e) => e !== entry)\n .map((e) => `${e.file}:${e.line}`)\n .join(\", \");\n diagnostics.push({\n ruleId: this.id,\n severity: this.severity,\n message: `Exported function \"${entry.name}\" also defined in: ${others}`,\n file: entry.file,\n line: entry.line,\n column: 1,\n });\n }\n }\n return diagnostics;\n },\n};\n\nfunction resolveCandidates(fromFile: string, specifier: string): string[] {\n const base = resolve(dirname(fromFile), specifier);\n const candidates = [base];\n for (const ext of EXTENSIONS) {\n candidates.push(base + ext);\n candidates.push(resolve(base, `index${ext}`));\n }\n return candidates;\n}\n","import * as ts from \"typescript\";\nimport type { CrossFileRule, Diagnostic, ProjectIndex } from \"../types.ts\";\n\nexport const duplicateTypeName: CrossFileRule = {\n id: \"duplicate-type-name\",\n severity: \"warning\",\n message: \"Same type name exported from multiple files; consolidate or rename to avoid ambiguity\",\n\n analyze(project: ProjectIndex): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n for (const group of project.types.getNameCollisionGroups()) {\n // Skip groups already caught by duplicate-type-declaration (identical shapes)\n const hashes = new Set(group.map((e) => e.hash));\n if (hashes.size === 1) continue;\n\n // Skip if any entry is an inferred/reference type (Awaited<ReturnType<...>>, z.infer<...>, etc.)\n // rather than a structural definition — these are intentionally derived, not duplicated\n const hasInferredType = group.some(\n (e) => !ts.isTypeLiteralNode(e.node) && !ts.isInterfaceDeclaration(e.node),\n );\n if (hasInferredType) continue;\n\n const sorted = [...group].sort((a, b) => a.file.localeCompare(b.file) || a.line - b.line);\n for (const entry of sorted.slice(1)) {\n const others = sorted\n .filter((e) => e !== entry)\n .map((e) => `${e.file}:${e.line}`)\n .join(\", \");\n diagnostics.push({\n ruleId: this.id,\n severity: this.severity,\n message: `Exported type \"${entry.name}\" also defined in: ${others}`,\n file: entry.file,\n line: entry.line,\n column: 1,\n });\n }\n }\n return diagnostics;\n },\n};\n","import * as ts from \"typescript\";\nimport type { TSRule, TSVisitContext } from \"../types.ts\";\n\nexport const noDynamicImport: TSRule = {\n kind: \"ts\",\n id: \"no-dynamic-import\",\n severity: \"error\",\n message: \"Dynamic import() breaks static analysis and hides dependencies; use a static import instead\",\n\n visit(node: ts.Node, ctx: TSVisitContext) {\n if (!ts.isCallExpression(node)) return;\n if (node.expression.kind !== ts.SyntaxKind.ImportKeyword) return;\n ctx.report(node);\n },\n};\n","import type { Rule } from \"./types.ts\";\n\nimport { noEmptyCatch } from \"./ts/no-empty-catch.ts\";\nimport { noNonNullAssertion } from \"./ts/no-non-null-assertion.ts\";\nimport { noDoubleNegationCoercion } from \"./ts/no-double-negation-coercion.ts\";\nimport { noTsIgnore } from \"./ts/no-ts-ignore.ts\";\nimport { noNullishCoalescing } from \"./ts/no-nullish-coalescing.ts\";\nimport { noOptionalCall } from \"./ts/no-optional-call.ts\";\nimport { noOptionalPropertyAccess } from \"./ts/no-optional-property-access.ts\";\nimport { noOptionalElementAccess } from \"./ts/no-optional-element-access.ts\";\nimport { noLogicalOrFallback } from \"./ts/no-logical-or-fallback.ts\";\nimport { noNullTernaryNormalization } from \"./ts/no-null-ternary-normalization.ts\";\nimport { noAnyCast } from \"./ts/no-any-cast.ts\";\nimport { noExplicitAnyAnnotation } from \"./ts/no-explicit-any-annotation.ts\";\nimport { noInlineTypeInParams } from \"./ts/no-inline-type-in-params.ts\";\nimport { noTypeAssertion } from \"./ts/no-type-assertion.ts\";\nimport { noRedundantExistenceGuard } from \"./ts/no-redundant-existence-guard.ts\";\nimport { preferDefaultParamValue } from \"./ts/prefer-default-param-value.ts\";\nimport { preferRequiredParamWithGuard } from \"./ts/prefer-required-param-with-guard.ts\";\nimport { duplicateTypeDeclaration } from \"./cross-file/duplicate-type-declaration.ts\";\nimport { duplicateFunctionDeclaration } from \"./cross-file/duplicate-function-declaration.ts\";\nimport { optionalArgAlwaysUsed } from \"./cross-file/optional-arg-always-used.ts\";\nimport { noCatchReturn } from \"./ts/no-catch-return.ts\";\nimport { noErrorRewrap } from \"./ts/no-error-rewrap.ts\";\nimport { explicitNullArg } from \"./cross-file/explicit-null-arg.ts\";\nimport { duplicateFunctionName } from \"./cross-file/duplicate-function-name.ts\";\nimport { duplicateTypeName } from \"./cross-file/duplicate-type-name.ts\";\nimport { noDynamicImport } from \"./ts/no-dynamic-import.ts\";\n\nexport type RuleCategory =\n | \"type-evasion\"\n | \"defensive-code\"\n | \"error-handling\"\n | \"interface-design\"\n | \"cross-file\"\n | \"imports\";\n\nexport interface RuleMetadata {\n category: RuleCategory;\n tags: string[];\n}\n\nexport const allRules: Rule[] = [\n noEmptyCatch,\n noNonNullAssertion,\n noDoubleNegationCoercion,\n noTsIgnore,\n noNullishCoalescing,\n noOptionalCall,\n noOptionalPropertyAccess,\n noOptionalElementAccess,\n noLogicalOrFallback,\n noNullTernaryNormalization,\n noAnyCast,\n noExplicitAnyAnnotation,\n noInlineTypeInParams,\n noTypeAssertion,\n noRedundantExistenceGuard,\n preferDefaultParamValue,\n preferRequiredParamWithGuard,\n duplicateTypeDeclaration,\n duplicateFunctionDeclaration,\n optionalArgAlwaysUsed,\n noCatchReturn,\n noErrorRewrap,\n explicitNullArg,\n duplicateFunctionName,\n duplicateTypeName,\n noDynamicImport,\n];\n\nconst ruleMetadata: Record<string, RuleMetadata> = {\n \"no-any-cast\": { category: \"type-evasion\", tags: [\"safety\"] },\n \"no-explicit-any-annotation\": { category: \"type-evasion\", tags: [\"safety\"] },\n \"no-type-assertion\": { category: \"type-evasion\", tags: [\"safety\"] },\n \"no-ts-ignore\": { category: \"type-evasion\", tags: [\"safety\"] },\n\n \"no-optional-property-access\": { category: \"defensive-code\", tags: [\"type-aware\"] },\n \"no-optional-element-access\": { category: \"defensive-code\", tags: [\"type-aware\"] },\n \"no-optional-call\": { category: \"defensive-code\", tags: [\"type-aware\"] },\n \"no-nullish-coalescing\": { category: \"defensive-code\", tags: [\"type-aware\"] },\n \"no-logical-or-fallback\": { category: \"defensive-code\", tags: [\"type-aware\"] },\n \"no-null-ternary-normalization\": { category: \"defensive-code\", tags: [\"type-aware\"] },\n \"no-non-null-assertion\": { category: \"defensive-code\", tags: [\"type-aware\"] },\n \"no-double-negation-coercion\": { category: \"defensive-code\", tags: [\"readability\"] },\n \"no-redundant-existence-guard\": { category: \"defensive-code\", tags: [\"type-aware\"] },\n\n \"no-empty-catch\": { category: \"error-handling\", tags: [\"safety\"] },\n \"no-catch-return\": { category: \"error-handling\", tags: [\"safety\"] },\n \"no-error-rewrap\": { category: \"error-handling\", tags: [\"safety\"] },\n\n \"no-inline-type-in-params\": { category: \"interface-design\", tags: [\"api\"] },\n \"prefer-default-param-value\": { category: \"interface-design\", tags: [\"api\"] },\n \"prefer-required-param-with-guard\": { category: \"interface-design\", tags: [\"api\"] },\n\n \"duplicate-type-declaration\": { category: \"cross-file\", tags: [\"duplicate\"] },\n \"duplicate-type-name\": { category: \"cross-file\", tags: [\"duplicate\"] },\n \"duplicate-function-declaration\": { category: \"cross-file\", tags: [\"duplicate\"] },\n \"duplicate-function-name\": { category: \"cross-file\", tags: [\"duplicate\"] },\n \"optional-arg-always-used\": { category: \"cross-file\", tags: [\"api\"] },\n \"explicit-null-arg\": { category: \"cross-file\", tags: [\"api\"] },\n\n \"no-dynamic-import\": { category: \"imports\", tags: [\"safety\"] },\n};\n\nexport function getRuleMetadata(ruleId: string): RuleMetadata {\n const metadata = ruleMetadata[ruleId];\n if (metadata !== undefined) return metadata;\n return { category: \"cross-file\", tags: [] };\n}\n","import type {\n FailOn,\n ResolvedScanConfig,\n RulePolicy,\n RulePolicyEntry,\n RulePolicySeverity,\n ScanOptions,\n Severity,\n} from \"./types.ts\";\n\nconst BUILTIN_IGNORE = [\n \"**/node_modules/**\",\n \"**/dist/**\",\n \"**/.git/**\",\n \"**/*.d.ts\",\n \"**/*.d.cts\",\n \"**/*.d.mts\",\n];\n\nconst GENERATED_IGNORE = [\n \"**/*.gen.*\",\n \"**/*.generated.*\",\n];\n\nconst DEFAULT_FAIL_ON: FailOn = \"info\";\n\nexport function resolveScanConfig(options: ScanOptions): ResolvedScanConfig {\n const paths = options.paths.length > 0 ? options.paths : [\".\"];\n const ignore = [...BUILTIN_IGNORE, ...GENERATED_IGNORE, ...(options.ignore ?? [])];\n return {\n paths,\n strict: options.strict ?? false,\n rules: options.rules ? [...options.rules] : null,\n ignore,\n rulePolicy: toRulePolicyEntries(options.rulePolicy),\n showSeverities: normalizeSeveritySet(options.showSeverities),\n failOn: options.failOn ?? DEFAULT_FAIL_ON,\n useGitIgnore: options.useGitIgnore ?? true,\n };\n}\n\nexport function toRulePolicyEntries(policy: RulePolicy | undefined): RulePolicyEntry[] {\n if (policy === undefined) return [];\n if (Array.isArray(policy)) return [...policy];\n\n const entries: RulePolicyEntry[] = [];\n for (const [selector, severity] of Object.entries(policy)) {\n entries.push({ selector, severity });\n }\n return entries;\n}\n\nfunction normalizeSeveritySet(levels: Severity[] | undefined): Set<Severity> | null {\n if (levels === undefined || levels.length === 0) return null;\n return new Set(levels);\n}\n\nexport function isRulePolicySeverity(value: string): value is RulePolicySeverity {\n return value === \"off\" || value === \"info\" || value === \"warning\" || value === \"error\";\n}\n\nexport function isSeverity(value: string): value is Severity {\n return value === \"info\" || value === \"warning\" || value === \"error\";\n}\n\nexport function isFailOn(value: string): value is FailOn {\n return value === \"none\" || isSeverity(value);\n}\n","import { readFileSync } from \"node:fs\";\nimport { collectProject, type CommentInfo } from \"../collect/index.ts\";\nimport { isTSRule } from \"../rules/types.ts\";\nimport type { CrossFileRule, Diagnostic, Rule } from \"../rules/types.ts\";\nimport { createProgramFromFiles } from \"../typecheck/program.ts\";\nimport { runTSRules } from \"../typecheck/walk.ts\";\n\nexport function analyzeFiles(files: string[], rules: Rule[]): Diagnostic[] {\n const tsRules = rules.filter(isTSRule);\n const crossFileRules = rules.filter((r): r is CrossFileRule => !isTSRule(r));\n const diagnostics: Diagnostic[] = [];\n\n const program = files.length > 0 ? createProgramFromFiles(files) : null;\n if (!program) return diagnostics;\n\n if (tsRules.length > 0) {\n const checker = program.getTypeChecker();\n for (const file of files) {\n const source = readFileSync(file, \"utf8\");\n const sourceFile = program.getSourceFile(file);\n if (sourceFile) {\n diagnostics.push(...runTSRules(tsRules, sourceFile, checker, source, file));\n }\n }\n }\n\n if (crossFileRules.length > 0) {\n const projectIndex = collectProject(program);\n for (const rule of crossFileRules) {\n const crossDiagnostics = rule.analyze(projectIndex);\n for (const diagnostic of crossDiagnostics) {\n const fileData = projectIndex.files.get(diagnostic.file);\n if (fileData !== undefined) annotate([diagnostic], fileData.comments, fileData.source);\n }\n diagnostics.push(...crossDiagnostics);\n }\n }\n\n return dedupeDiagnostics(diagnostics);\n}\n\nfunction dedupeDiagnostics(diagnostics: Diagnostic[]): Diagnostic[] {\n const seen = new Set<string>();\n const deduped: Diagnostic[] = [];\n for (const diagnostic of diagnostics) {\n const key = `${diagnostic.file}:${diagnostic.line}:${diagnostic.ruleId}`;\n if (seen.has(key)) continue;\n seen.add(key);\n deduped.push(diagnostic);\n }\n return deduped;\n}\n\n/**\n * Attach annotations from comments to diagnostics.\n * A comment annotates a diagnostic if it ends on the line immediately above.\n * Consecutive line comments are joined into a single annotation.\n */\nfunction annotate(diagnostics: Diagnostic[], comments: CommentInfo[], source: string): void {\n if (comments.length === 0 || diagnostics.length === 0) return;\n\n const byEndLine = new Map<number, CommentInfo[]>();\n for (const comment of comments) {\n const endLine = lineAt(source, comment.end);\n let list = byEndLine.get(endLine);\n if (list === undefined) {\n list = [];\n byEndLine.set(endLine, list);\n }\n list.push(comment);\n }\n\n for (const diagnostic of diagnostics) {\n const inline = findInlineComment(diagnostic.line, byEndLine);\n if (inline !== null) {\n diagnostic.annotation = inline;\n continue;\n }\n const above = collectAnnotation(diagnostic.line - 1, byEndLine, source);\n if (above !== null) diagnostic.annotation = above;\n }\n}\n\nfunction findInlineComment(diagLine: number, byEndLine: Map<number, CommentInfo[]>): string | null {\n const commentsOnLine = byEndLine.get(diagLine);\n if (commentsOnLine === undefined || commentsOnLine.length === 0) return null;\n const comment = commentsOnLine.at(-1);\n if (comment === undefined) return null;\n if (comment.type !== \"Line\") return null;\n const text = comment.value.trim();\n if (text.startsWith(\"@expect\")) return null;\n return text;\n}\n\nfunction collectAnnotation(\n commentEndLine: number,\n byEndLine: Map<number, CommentInfo[]>,\n source: string,\n): string | null {\n const commentsOnLine = byEndLine.get(commentEndLine);\n if (commentsOnLine === undefined || commentsOnLine.length === 0) return null;\n const comment = commentsOnLine.at(-1);\n if (comment === undefined) return null;\n\n if (comment.type === \"Block\") return cleanBlockComment(comment.value);\n\n const lines: string[] = [comment.value.trim()];\n let prevLine = commentEndLine - 1;\n for (;;) {\n const prev = byEndLine.get(prevLine);\n if (prev === undefined || prev.length === 0) break;\n const prevComment = prev.at(-1);\n if (prevComment === undefined || prevComment.type !== \"Line\") break;\n if (lineAt(source, prevComment.start) !== prevLine) break;\n lines.unshift(prevComment.value.trim());\n prevLine--;\n }\n\n return lines.join(\"\\n\");\n}\n\nfunction cleanBlockComment(value: string): string {\n return value\n .split(\"\\n\")\n .map((line) => line.replace(/^\\s*\\*\\s?/, \"\").trim())\n .filter((line) => line.length > 0)\n .join(\"\\n\");\n}\n\nfunction lineAt(source: string, offset: number): number {\n let line = 1;\n for (let i = 0; i < offset && i < source.length; i++) {\n if (source[i] === \"\\n\") line++;\n }\n return line;\n}\n","import * as ts from \"typescript\";\nimport { readFileSync } from \"node:fs\";\nimport { TypeRegistry } from \"./type-registry.ts\";\nimport { FunctionRegistry, type ParamInfo } from \"./function-registry.ts\";\nimport { hashFunctionBody } from \"../utils/hash.ts\";\n\nexport interface CommentInfo {\n type: \"Line\" | \"Block\";\n value: string;\n start: number;\n end: number;\n}\n\nexport interface ProjectIndex {\n types: TypeRegistry;\n functions: FunctionRegistry;\n callSites: CallSite[];\n imports: ImportEntry[];\n files: Map<string, { source: string; sourceFile: ts.SourceFile; comments: CommentInfo[] }>;\n}\n\nexport interface CallSite {\n calleeName: string;\n file: string;\n line: number;\n argCount: number;\n node: ts.CallExpression;\n symbol?: ts.Symbol;\n}\n\nexport interface ImportEntry {\n file: string;\n localName: string;\n importedName: string;\n source: string;\n}\n\nexport function collectProject(program: ts.Program): ProjectIndex {\n const checker = program.getTypeChecker();\n const types = new TypeRegistry();\n const functions = new FunctionRegistry();\n const callSites: CallSite[] = [];\n const imports: ImportEntry[] = [];\n const fileMap = new Map<string, { source: string; sourceFile: ts.SourceFile; comments: CommentInfo[] }>();\n\n for (const sourceFile of program.getSourceFiles()) {\n const file = sourceFile.fileName;\n // Skip declaration files and node_modules\n if (sourceFile.isDeclarationFile) continue;\n if (file.includes(\"node_modules\")) continue;\n\n const source = sourceFile.getFullText();\n const comments = collectAllComments(sourceFile);\n fileMap.set(file, { source, sourceFile, comments });\n\n function visit(node: ts.Node): void {\n collectTypes(node, file, sourceFile, types);\n collectFunctions(node, file, sourceFile, checker, functions);\n collectCallSites(node, file, sourceFile, checker, callSites);\n collectImports(node, file, imports);\n ts.forEachChild(node, visit);\n }\n ts.forEachChild(sourceFile, visit);\n }\n\n return { types, functions, callSites, imports, files: fileMap };\n}\n\nfunction isExported(node: ts.Node): boolean {\n if (!ts.canHaveModifiers(node)) return false;\n const mods = ts.getModifiers(node);\n if (mods === undefined) return false;\n return mods.some((m) => m.kind === ts.SyntaxKind.ExportKeyword);\n}\n\nfunction collectTypes(node: ts.Node, file: string, sourceFile: ts.SourceFile, registry: TypeRegistry): void {\n if (ts.isTypeAliasDeclaration(node)) {\n const line = ts.getLineAndCharacterOfPosition(sourceFile, node.getStart(sourceFile)).line + 1;\n registry.add(node.name.text, file, line, node.type, sourceFile, isExported(node));\n }\n if (ts.isInterfaceDeclaration(node)) {\n const line = ts.getLineAndCharacterOfPosition(sourceFile, node.getStart(sourceFile)).line + 1;\n registry.add(node.name.text, file, line, node, sourceFile, isExported(node));\n }\n}\n\nfunction collectFunctions(node: ts.Node, file: string, sourceFile: ts.SourceFile, checker: ts.TypeChecker, registry: FunctionRegistry): void {\n if (ts.isFunctionDeclaration(node) && node.name && node.body) {\n const line = ts.getLineAndCharacterOfPosition(sourceFile, node.getStart(sourceFile)).line + 1;\n const params = extractParams(node.parameters, sourceFile);\n const hash = hashFunctionBody(node.body, sourceFile);\n const symbol = checker.getSymbolAtLocation(node.name);\n registry.add({ name: node.name.text, file, line, hash, params, node, exported: isExported(node), symbol });\n }\n\n // Arrow functions assigned to const: const foo = (...) => { ... }\n if (ts.isVariableStatement(node)) {\n const exported = isExported(node);\n for (const decl of node.declarationList.declarations) {\n if (decl.initializer && ts.isArrowFunction(decl.initializer) && ts.isIdentifier(decl.name)) {\n const arrow = decl.initializer;\n const body = ts.isBlock(arrow.body) ? arrow.body : arrow.body;\n const line = ts.getLineAndCharacterOfPosition(sourceFile, decl.getStart(sourceFile)).line + 1;\n const params = extractParams(arrow.parameters, sourceFile);\n const hash = hashFunctionBody(body, sourceFile);\n const symbol = checker.getSymbolAtLocation(decl.name);\n registry.add({ name: decl.name.text, file, line, hash, params, node: arrow, exported, symbol });\n }\n }\n }\n}\n\nfunction extractParams(parameters: ts.NodeArray<ts.ParameterDeclaration>, sourceFile: ts.SourceFile): ParamInfo[] {\n return parameters.map((p) => {\n const name = p.name.getText(sourceFile);\n const optional = p.questionToken !== undefined;\n const hasDefault = p.initializer !== undefined;\n const typeText = p.type ? p.type.getText(sourceFile) : null;\n return { name, optional, hasDefault, typeText };\n });\n}\n\nfunction collectImports(node: ts.Node, file: string, imports: ImportEntry[]): void {\n if (ts.isImportDeclaration(node) && ts.isStringLiteral(node.moduleSpecifier)) {\n const moduleSource = node.moduleSpecifier.text;\n const clause = node.importClause;\n if (!clause) return;\n\n // Default import\n if (clause.name) {\n imports.push({\n file,\n localName: clause.name.text,\n importedName: \"default\",\n source: moduleSource,\n });\n }\n\n // Named imports\n if (clause.namedBindings && ts.isNamedImports(clause.namedBindings)) {\n for (const el of clause.namedBindings.elements) {\n imports.push({\n file,\n localName: el.name.text,\n importedName: el.propertyName ? el.propertyName.text : el.name.text,\n source: moduleSource,\n });\n }\n }\n }\n\n // Re-exports: export { x } from \"./mod\"\n if (ts.isExportDeclaration(node) && node.moduleSpecifier && ts.isStringLiteral(node.moduleSpecifier)) {\n const moduleSource = node.moduleSpecifier.text;\n if (node.exportClause && ts.isNamedExports(node.exportClause)) {\n for (const el of node.exportClause.elements) {\n imports.push({\n file,\n localName: el.name.text,\n importedName: el.propertyName ? el.propertyName.text : el.name.text,\n source: moduleSource,\n });\n }\n }\n }\n}\n\nfunction collectCallSites(node: ts.Node, file: string, sourceFile: ts.SourceFile, checker: ts.TypeChecker, sites: CallSite[]): void {\n if (!ts.isCallExpression(node)) return;\n let calleeName: string | null = null;\n if (ts.isIdentifier(node.expression)) {\n calleeName = node.expression.text;\n } else if (ts.isPropertyAccessExpression(node.expression)) {\n calleeName = node.expression.name.text;\n }\n if (calleeName) {\n const line = ts.getLineAndCharacterOfPosition(sourceFile, node.getStart(sourceFile)).line + 1;\n // Resolve the symbol the call refers to (follows imports to the declaration)\n let symbol: ts.Symbol | undefined;\n try {\n symbol = checker.getSymbolAtLocation(node.expression);\n if (symbol && (symbol.flags & ts.SymbolFlags.Alias)) {\n symbol = checker.getAliasedSymbol(symbol);\n }\n } catch {\n // Symbol resolution can fail on synthetic nodes\n }\n sites.push({\n calleeName,\n file,\n line,\n argCount: node.arguments.length,\n node,\n symbol,\n });\n }\n}\n\n/** Collect all comments from a source file. */\nexport function collectAllComments(sourceFile: ts.SourceFile): CommentInfo[] {\n const comments: CommentInfo[] = [];\n const source = sourceFile.getFullText();\n const seen = new Set<number>();\n\n function visit(node: ts.Node): void {\n const leading = ts.getLeadingCommentRanges(source, node.getFullStart());\n if (leading) {\n for (const r of leading) {\n if (seen.has(r.pos)) continue;\n seen.add(r.pos);\n const isLine = r.kind === ts.SyntaxKind.SingleLineCommentTrivia;\n comments.push({\n type: isLine ? \"Line\" : \"Block\",\n value: source.slice(r.pos + 2, isLine ? r.end : r.end - 2),\n start: r.pos,\n end: r.end,\n });\n }\n }\n const trailing = ts.getTrailingCommentRanges(source, node.getEnd());\n if (trailing) {\n for (const r of trailing) {\n if (seen.has(r.pos)) continue;\n seen.add(r.pos);\n const isLine = r.kind === ts.SyntaxKind.SingleLineCommentTrivia;\n comments.push({\n type: isLine ? \"Line\" : \"Block\",\n value: source.slice(r.pos + 2, isLine ? r.end : r.end - 2),\n start: r.pos,\n end: r.end,\n });\n }\n }\n ts.forEachChild(node, visit);\n }\n visit(sourceFile);\n\n return comments;\n}\n","import { createHash } from \"node:crypto\";\nimport * as ts from \"typescript\";\n\n/**\n * Create a structural hash of a type node.\n * Normalizes by sorting property names and stripping locations.\n */\nexport function hashTypeShape(node: ts.Node, sourceFile: ts.SourceFile): string {\n const normalized = normalizeTypeNode(node, sourceFile);\n return createHash(\"sha256\").update(normalized).digest(\"hex\").slice(0, 16);\n}\n\nfunction normalizeTypeNode(node: ts.Node, sourceFile: ts.SourceFile): string {\n if (ts.isTypeLiteralNode(node)) {\n const normalized = node.members.map((m) => normalizeTypeNode(m, sourceFile)).sort().join(\";\");\n return `{${normalized}}`;\n }\n if (ts.isInterfaceDeclaration(node)) {\n const normalized = node.members.map((m) => normalizeTypeNode(m, sourceFile)).sort().join(\";\");\n return `{${normalized}}`;\n }\n if (ts.isPropertySignature(node)) {\n const keyName = node.name.getText(sourceFile);\n const optional = node.questionToken ? \"?\" : \"\";\n const type = node.type ? normalizeTypeNode(node.type, sourceFile) : \"any\";\n return `${keyName}${optional}:${type}`;\n }\n if (ts.isTypeAliasDeclaration(node)) {\n return normalizeTypeNode(node.type, sourceFile);\n }\n // Fallback: use source text with whitespace normalized\n return node.getText(sourceFile).replace(/\\s+/g, \" \").trim();\n}\n\n/**\n * Hash a function body for duplicate detection.\n * Normalizes whitespace.\n */\nexport function hashFunctionBody(node: ts.Node, sourceFile: ts.SourceFile): string {\n const bodyText = node.getText(sourceFile);\n const normalized = bodyText.replace(/\\s+/g, \" \").trim();\n return createHash(\"sha256\").update(normalized).digest(\"hex\").slice(0, 16);\n}\n","import type * as ts from \"typescript\";\nimport { hashTypeShape } from \"../utils/hash.ts\";\n\nexport interface TypeEntry {\n name: string;\n file: string;\n line: number;\n hash: string;\n node: ts.Node;\n exported: boolean;\n}\n\nexport class TypeRegistry {\n private entries: TypeEntry[] = [];\n private byHash = new Map<string, TypeEntry[]>();\n\n add(name: string, file: string, line: number, typeNode: ts.Node, sourceFile: ts.SourceFile, exported: boolean): void {\n const hash = hashTypeShape(typeNode, sourceFile);\n const entry: TypeEntry = { name, file, line, hash, node: typeNode, exported };\n this.entries.push(entry);\n let list = this.byHash.get(hash);\n if (list === undefined) {\n list = [];\n this.byHash.set(hash, list);\n }\n list.push(entry);\n }\n\n getDuplicateGroups(): TypeEntry[][] {\n return [...this.byHash.values()].filter((group) => group.length > 1);\n }\n\n getAll(): TypeEntry[] {\n return this.entries;\n }\n\n getNameCollisionGroups(): TypeEntry[][] {\n const byName = new Map<string, TypeEntry[]>();\n for (const entry of this.entries) {\n if (!entry.exported) continue;\n let list = byName.get(entry.name);\n if (list === undefined) {\n list = [];\n byName.set(entry.name, list);\n }\n list.push(entry);\n }\n return [...byName.values()].filter((group) => {\n if (group.length < 2) return false;\n const files = new Set(group.map((e) => e.file));\n return files.size > 1;\n });\n }\n}\n","import type * as ts from \"typescript\";\n\nexport interface ParamInfo {\n name: string;\n optional: boolean;\n hasDefault: boolean;\n typeText: string | null;\n}\n\nexport interface FunctionEntry {\n name: string;\n file: string;\n line: number;\n hash: string;\n params: ParamInfo[];\n node: ts.Node;\n exported: boolean;\n symbol?: ts.Symbol;\n}\n\nexport class FunctionRegistry {\n private entries: FunctionEntry[] = [];\n private byHash = new Map<string, FunctionEntry[]>();\n\n add(entry: FunctionEntry): void {\n this.entries.push(entry);\n let list = this.byHash.get(entry.hash);\n if (list === undefined) {\n list = [];\n this.byHash.set(entry.hash, list);\n }\n list.push(entry);\n }\n\n getDuplicateGroups(): FunctionEntry[][] {\n return [...this.byHash.values()].filter((group) => group.length > 1);\n }\n\n getAll(): FunctionEntry[] {\n return this.entries;\n }\n\n getByName(name: string): FunctionEntry[] {\n return this.entries.filter((e) => e.name === name);\n }\n\n getNameCollisionGroups(): FunctionEntry[][] {\n const byName = new Map<string, FunctionEntry[]>();\n for (const entry of this.entries) {\n if (!entry.exported) continue;\n let list = byName.get(entry.name);\n if (list === undefined) {\n list = [];\n byName.set(entry.name, list);\n }\n list.push(entry);\n }\n return [...byName.values()].filter((group) => {\n if (group.length < 2) return false;\n const files = new Set(group.map((e) => e.file));\n return files.size > 1;\n });\n }\n}\n","import type * as ts from \"typescript\";\n\nexport interface Diagnostic {\n ruleId: string;\n severity: \"info\" | \"warning\" | \"error\";\n message: string;\n file: string;\n line: number;\n column: number;\n annotation?: string;\n}\n\nexport interface TSVisitContext {\n report(node: ts.Node, message?: string): void;\n reportAtOffset(offset: number, message?: string): void;\n filename: string;\n source: string;\n sourceFile: ts.SourceFile;\n checker: ts.TypeChecker;\n isNullable(node: ts.Node): boolean;\n isExternal(node: ts.Node): boolean;\n}\n\nexport interface TSRule {\n kind: \"ts\";\n id: string;\n severity: \"info\" | \"warning\" | \"error\";\n message: string;\n visit(node: ts.Node, ctx: TSVisitContext): void;\n}\n\nimport type { ProjectIndex } from \"../collect/index.ts\";\nexport type { ProjectIndex };\n\nexport interface CrossFileRule {\n id: string;\n severity: \"info\" | \"warning\" | \"error\";\n message: string;\n analyze(project: ProjectIndex): Diagnostic[];\n}\n\nexport type Rule = CrossFileRule | TSRule;\n\nexport function isTSRule(r: Rule): r is TSRule {\n return \"kind\" in r && r.kind === \"ts\";\n}\n","import * as ts from \"typescript\";\nimport { dirname } from \"node:path\";\n\nexport function createProgramFromFiles(files: string[]): ts.Program {\n let configPath: string | undefined;\n if (files.length > 0) {\n configPath = ts.findConfigFile(dirname(files[0] as string), ts.sys.fileExists, \"tsconfig.json\");\n }\n\n if (configPath) {\n const configFile = ts.readConfigFile(configPath, ts.sys.readFile);\n const parsed = ts.parseJsonConfigFileContent(configFile.config, ts.sys, dirname(configPath));\n return ts.createProgram({\n rootNames: files,\n options: { ...parsed.options, skipLibCheck: true },\n });\n }\n\n return ts.createProgram({\n rootNames: files,\n options: {\n target: ts.ScriptTarget.ESNext,\n module: ts.ModuleKind.ESNext,\n moduleResolution: ts.ModuleResolutionKind.Bundler,\n strict: true,\n skipLibCheck: true,\n noEmit: true,\n },\n });\n}\n","import * as ts from \"typescript\";\nimport type { Diagnostic, TSRule, TSVisitContext } from \"../rules/types.ts\";\nimport { isNullableType, isFromNodeModules } from \"./utils.ts\";\n\nexport function runTSRules(\n rules: TSRule[],\n sourceFile: ts.SourceFile,\n checker: ts.TypeChecker,\n source: string,\n filename: string,\n): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n\n const contexts = rules.map((rule) => ({\n rule,\n ctx: buildContext(rule, sourceFile, checker, source, filename, diagnostics),\n }));\n\n function visit(node: ts.Node): void {\n for (const { rule, ctx } of contexts) {\n rule.visit(node, ctx);\n }\n ts.forEachChild(node, visit);\n }\n\n visit(sourceFile);\n return diagnostics;\n}\n\nfunction buildContext(\n rule: TSRule,\n sourceFile: ts.SourceFile,\n checker: ts.TypeChecker,\n source: string,\n filename: string,\n diagnostics: Diagnostic[],\n): TSVisitContext {\n return {\n filename,\n source,\n sourceFile,\n checker,\n\n report(node: ts.Node, message?: string) {\n const { line, character } = ts.getLineAndCharacterOfPosition(sourceFile, node.getStart(sourceFile));\n diagnostics.push({\n ruleId: rule.id,\n severity: rule.severity,\n message: message ?? rule.message,\n file: filename,\n line: line + 1,\n column: character + 1,\n });\n },\n\n reportAtOffset(offset: number, message?: string) {\n const { line, character } = ts.getLineAndCharacterOfPosition(sourceFile, offset);\n diagnostics.push({\n ruleId: rule.id,\n severity: rule.severity,\n message: message ?? rule.message,\n file: filename,\n line: line + 1,\n column: character + 1,\n });\n },\n\n isNullable(node: ts.Node): boolean {\n const type = checker.getTypeAtLocation(node);\n return isNullableType(checker, type);\n },\n\n isExternal(node: ts.Node): boolean {\n const type = checker.getTypeAtLocation(node);\n const symbol = type.getSymbol();\n if (!symbol) return false;\n const declarations = symbol.getDeclarations();\n if (!declarations || declarations.length === 0) return false;\n return declarations.some((d) => isFromNodeModules(d));\n },\n };\n}\n","import fg from \"fast-glob\";\nimport ignore from \"ignore\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { relative, resolve, sep } from \"node:path\";\nimport type { ResolvedScanConfig } from \"./types.ts\";\n\nexport async function discoverFiles(config: ResolvedScanConfig): Promise<string[]> {\n const globs = expandGlobs(config.paths);\n const discoveredFiles = await fg(globs, {\n ignore: config.ignore,\n absolute: true,\n });\n if (!config.useGitIgnore) return discoveredFiles;\n return applyGitIgnore(discoveredFiles);\n}\n\nfunction expandGlobs(paths: string[]): string[] {\n return paths.map((p) => {\n if (p === \".\") return \"./**/*.{ts,cts,mts,tsx}\";\n if (p.endsWith(\"/\")) return `${p}**/*.{ts,cts,mts,tsx}`;\n if (!p.includes(\"*\") && !p.endsWith(\".ts\") && !p.endsWith(\".tsx\") && !p.endsWith(\".cts\") && !p.endsWith(\".mts\")) {\n return `${p}/**/*.{ts,cts,mts,tsx}`;\n }\n return p;\n });\n}\n\nfunction applyGitIgnore(files: string[]): string[] {\n const gitIgnorePath = resolve(process.cwd(), \".gitignore\");\n if (!existsSync(gitIgnorePath)) return files;\n\n const matcher = ignore().add(readFileSync(gitIgnorePath, \"utf8\"));\n return files.filter((file) => {\n const rel = relative(process.cwd(), file);\n if (rel.startsWith(\"..\")) return true;\n const normalized = rel.split(sep).join(\"/\");\n return !matcher.ignores(normalized);\n });\n}\n","import type { Diagnostic, Rule } from \"../rules/types.ts\";\nimport { getRuleMetadata } from \"../rules/index.ts\";\nimport type {\n ResolvedScanConfig,\n RuleDescriptor,\n RulePolicySeverity,\n ScanExecutionResult,\n ScanResult,\n Severity,\n} from \"./types.ts\";\n\nexport function buildRuleDescriptors(rules: Rule[]): RuleDescriptor[] {\n return rules.map((rule) => {\n const metadata = getRuleMetadata(rule.id);\n return {\n rule,\n category: metadata.category,\n tags: metadata.tags,\n };\n });\n}\n\nexport function resolveActiveRules(\n descriptors: RuleDescriptor[],\n config: ResolvedScanConfig,\n): Rule[] {\n const selectedRules = config.rules ? new Set(config.rules) : null;\n const active: Rule[] = [];\n\n for (const descriptor of descriptors) {\n if (selectedRules && !selectedRules.has(descriptor.rule.id)) continue;\n const resolvedSeverity = resolveRuleSeverity(descriptor, config);\n if (resolvedSeverity === \"off\") continue;\n if (descriptor.rule.severity === resolvedSeverity) {\n active.push(descriptor.rule);\n continue;\n }\n active.push({ ...descriptor.rule, severity: resolvedSeverity });\n }\n\n return active;\n}\n\nfunction resolveRuleSeverity(descriptor: RuleDescriptor, config: ResolvedScanConfig): RulePolicySeverity {\n let severity: RulePolicySeverity = descriptor.rule.severity;\n for (const entry of config.rulePolicy) {\n if (!matchesSelector(descriptor, entry.selector)) continue;\n severity = entry.severity;\n }\n\n if (severity === \"off\") return \"off\";\n if (config.strict) return \"error\";\n return severity;\n}\n\nfunction matchesSelector(descriptor: RuleDescriptor, selector: string): boolean {\n if (selector.startsWith(\"category:\")) {\n return descriptor.category === selector.slice(\"category:\".length);\n }\n if (selector.startsWith(\"tag:\")) {\n return descriptor.tags.includes(selector.slice(\"tag:\".length));\n }\n if (selector === descriptor.rule.id) return true;\n if (!selector.includes(\"*\")) return false;\n const regex = new RegExp(`^${escapeRegex(selector).replaceAll(\"\\\\*\", \".*\")}$`);\n return regex.test(descriptor.rule.id);\n}\n\nfunction escapeRegex(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nexport function finalizeScanResult(\n diagnostics: Diagnostic[],\n fileCount: number,\n config: ResolvedScanConfig,\n): ScanExecutionResult {\n const visibleDiagnostics = config.showSeverities\n ? diagnostics.filter((d) => config.showSeverities?.has(d.severity))\n : diagnostics;\n\n return {\n diagnostics,\n visibleDiagnostics,\n fileCount,\n exitCode: computeExitCode(diagnostics, config.failOn),\n };\n}\n\nexport function toScanResult(execution: ScanExecutionResult): ScanResult {\n return {\n diagnostics: execution.diagnostics,\n fileCount: execution.fileCount,\n };\n}\n\nfunction computeExitCode(diagnostics: Diagnostic[], failOn: \"none\" | Severity): number {\n if (failOn === \"none\") return 0;\n\n const hasError = diagnostics.some((d) => d.severity === \"error\");\n const hasWarning = diagnostics.some((d) => d.severity === \"warning\");\n const hasInfo = diagnostics.some((d) => d.severity === \"info\");\n\n if (failOn === \"error\") return hasError ? 2 : 0;\n if (failOn === \"warning\") {\n if (hasError) return 2;\n return hasWarning ? 1 : 0;\n }\n\n if (hasError) return 2;\n if (hasWarning || hasInfo) return 1;\n return 0;\n}\n","import { allRules } from \"./rules/index.ts\";\nimport { analyzeFiles } from \"./scan/analyze.ts\";\nimport { resolveScanConfig } from \"./scan/config.ts\";\nimport { discoverFiles } from \"./scan/discover.ts\";\nimport { buildRuleDescriptors, finalizeScanResult, resolveActiveRules, toScanResult } from \"./scan/policy.ts\";\nimport type { ScanExecutionResult, ScanOptions, ScanResult } from \"./scan/types.ts\";\n\nexport type {\n FailOn,\n RulePolicy,\n RulePolicyEntry,\n RulePolicySeverity,\n ScanExecutionResult,\n ScanOptions,\n ScanResult,\n Severity,\n} from \"./scan/types.ts\";\n\nexport async function executeScan(options: ScanOptions): Promise<ScanExecutionResult> {\n const config = resolveScanConfig(options);\n const files = await discoverFiles(config);\n const descriptors = buildRuleDescriptors(allRules);\n const activeRules = resolveActiveRules(descriptors, config);\n const diagnostics = analyzeFiles(files, activeRules);\n return finalizeScanResult(diagnostics, files.length, config);\n}\n\nexport async function scan(options: ScanOptions): Promise<ScanResult> {\n const execution = await executeScan(options);\n return toScanResult(execution);\n}\n"],"mappings":"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","names":["ts","ts","ts","ts","ts","ts","ts","ts","ts","ts","ts","ts","ts","ts","ts","ts","ts","ts","ts","ts","ts","ts","ts","ignore","readFileSync","ts","ts","visit","ts","dirname","ts","readFileSync","readFileSync","resolve"]}
|