eslint-plugin-ai-guard 1.2.0 → 1.2.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.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/rules/reliability/no-empty-catch.ts","../src/rules/reliability/no-broad-exception.ts","../src/rules/reliability/no-catch-log-rethrow.ts","../src/rules/reliability/no-catch-without-use.ts","../src/rules/async/no-async-array-callback.ts","../src/rules/async/no-floating-promise.ts","../src/rules/async/no-await-in-loop.ts","../src/rules/async/no-async-without-await.ts","../src/rules/async/no-redundant-await.ts","../src/rules/security/no-hardcoded-secret.ts","../src/rules/security/no-eval-dynamic.ts","../src/rules/security/no-sql-string-concat.ts","../src/rules/security/no-unsafe-deserialize.ts","../src/rules/security/require-auth-middleware.ts","../src/rules/security/require-authz-check.ts","../src/rules/ai-patterns/no-console-in-handler.ts","../src/rules/ai-patterns/no-duplicate-logic-block.ts","../src/rules/ai-patterns/no-dead-branch.ts","../src/rules/index.ts","../src/configs/recommended.ts","../src/configs/strict.ts","../src/configs/security.ts"],"sourcesContent":["import { allRules } from './rules';\r\nimport recommended from './configs/recommended';\r\nimport strict from './configs/strict';\r\nimport security from './configs/security';\r\n\r\nconst plugin = {\r\n meta: {\r\n name: 'eslint-plugin-ai-guard',\r\n version: '1.2.0',\r\n },\r\n rules: allRules,\r\n configs: {\r\n recommended,\r\n strict,\r\n security,\r\n },\r\n};\r\n\r\nexport default plugin;\r\nexport { allRules as rules };\r\nexport { recommended, strict, security };\r\n","import { ESLintUtils } from '@typescript-eslint/utils';\r\n\r\nconst createRule = ESLintUtils.RuleCreator(\r\n (name) => `https://github.com/YashJadhav21/eslint-plugin-ai-guard/blob/main/docs/rules/${name}.md`\r\n);\r\n\r\nexport const noEmptyCatch = createRule({\r\n name: 'no-empty-catch',\r\n meta: {\r\n type: 'problem',\r\n docs: {\r\n description:\r\n 'Disallow empty catch blocks. AI tools frequently generate try/catch with empty catch bodies that silently swallow errors, hiding failures in production. Includes a safe autofix that inserts an explicit placeholder comment.',\r\n },\r\n fixable: 'code',\r\n hasSuggestions: true,\r\n schema: [],\r\n messages: {\r\n emptyCatch:\r\n 'Catch block is empty. AI tools frequently generate empty catch blocks that silently swallow errors. Handle the error (log, rethrow, or recover), or add a comment explaining why it is intentionally empty.',\r\n addTodoHandler:\r\n 'Add a minimal placeholder so this catch block is not silently swallowing errors.',\r\n },\r\n },\r\n defaultOptions: [],\r\n create(context) {\r\n return {\r\n CatchClause(node) {\r\n // Flag catch clauses where the body block has zero statements\r\n if (node.body.body.length === 0) {\r\n // Check if there is a comment inside the catch block — if so, the developer\r\n // intentionally left it empty with a reason, so we don't flag it.\r\n const sourceCode = context.sourceCode;\r\n const comments = sourceCode.getCommentsInside(node.body);\r\n if (comments.length > 0) {\r\n return;\r\n }\r\n\r\n context.report({\r\n node,\r\n messageId: 'emptyCatch',\r\n fix: (fixer) => fixer.replaceText(node.body, '{ /* TODO: handle error */ }'),\r\n suggest: [\r\n {\r\n messageId: 'addTodoHandler',\r\n fix: (fixer) => fixer.replaceText(node.body, '{ /* TODO: handle error */ }'),\r\n },\r\n ],\r\n });\r\n }\r\n },\r\n };\r\n },\r\n});\r\n\r\nexport default noEmptyCatch;\r\n","import { ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';\n\nconst createRule = ESLintUtils.RuleCreator(\n (name) => `https://github.com/YashJadhav21/eslint-plugin-ai-guard/blob/main/docs/rules/${name}.md`\n);\n\nexport const noBroadException = createRule({\n name: 'no-broad-exception',\n meta: {\n type: 'suggestion',\n docs: {\n description:\n 'Disallow overly broad catch clause types such as `catch (e: any)` or `catch (e: unknown)` without narrowing. AI tools frequently use `any` type annotations on catch parameters, hiding the actual error type and preventing proper error handling.',\n },\n fixable: undefined,\n schema: [],\n messages: {\n broadException:\n 'Catch parameter has an overly broad type annotation `{{type}}`. AI tools frequently generate `catch (e: any)` which hides the real error type. Use a specific error type or narrow with `instanceof` checks inside the catch block.',\n },\n },\n defaultOptions: [],\n create(context) {\n return {\n CatchClause(node) {\n const param = node.param;\n if (!param) return;\n\n // Check for explicit type annotation: catch (e: any), catch (e: unknown)\n if (\n param.type === AST_NODE_TYPES.Identifier &&\n param.typeAnnotation &&\n param.typeAnnotation.typeAnnotation\n ) {\n const typeAnnotation = param.typeAnnotation.typeAnnotation;\n\n // catch (e: any)\n if (typeAnnotation.type === AST_NODE_TYPES.TSAnyKeyword) {\n context.report({\n node: param,\n messageId: 'broadException',\n data: { type: 'any' },\n });\n return;\n }\n\n // catch (e: unknown) — only flag if the parameter is never narrowed in the body\n if (typeAnnotation.type === AST_NODE_TYPES.TSUnknownKeyword) {\n // Check if the catch body contains instanceof checks or type guards\n const hasNarrowing = checkForNarrowing(node, param.name);\n if (!hasNarrowing) {\n context.report({\n node: param,\n messageId: 'broadException',\n data: { type: 'unknown' },\n });\n }\n }\n }\n },\n };\n },\n});\n\n/**\n * Check if the catch block body contains instanceof checks or other narrowing\n * patterns for the given parameter name.\n */\nfunction checkForNarrowing(\n catchClause: { body: { body: readonly { type: string; [key: string]: any }[] } },\n paramName: string\n): boolean {\n const bodyStatements = catchClause.body.body;\n\n for (const stmt of bodyStatements) {\n if (containsInstanceofCheck(stmt, paramName)) {\n return true;\n }\n }\n return false;\n}\n\nfunction containsInstanceofCheck(node: any, paramName: string): boolean {\n if (!node || typeof node !== 'object') return false;\n\n // Check for: e instanceof SomeError\n if (\n node.type === AST_NODE_TYPES.BinaryExpression &&\n node.operator === 'instanceof' &&\n node.left?.type === AST_NODE_TYPES.Identifier &&\n node.left.name === paramName\n ) {\n return true;\n }\n\n // Recurse into child nodes\n for (const key of Object.keys(node)) {\n if (key === 'parent') continue;\n const child = node[key];\n if (Array.isArray(child)) {\n for (const item of child) {\n if (containsInstanceofCheck(item, paramName)) return true;\n }\n } else if (child && typeof child === 'object' && child.type) {\n if (containsInstanceofCheck(child, paramName)) return true;\n }\n }\n return false;\n}\n\nexport default noBroadException;\n","import { ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';\r\nimport type { TSESTree } from '@typescript-eslint/utils';\r\n\r\nconst createRule = ESLintUtils.RuleCreator(\r\n (name) => `https://github.com/YashJadhav21/eslint-plugin-ai-guard/blob/main/docs/rules/${name}.md`\r\n);\r\n\r\nfunction isConsoleCallStatement(statement: TSESTree.Statement): boolean {\r\n if (statement.type !== AST_NODE_TYPES.ExpressionStatement) {\r\n return false;\r\n }\r\n\r\n const expression = statement.expression;\r\n if (expression.type !== AST_NODE_TYPES.CallExpression) {\r\n return false;\r\n }\r\n\r\n if (expression.callee.type !== AST_NODE_TYPES.MemberExpression) {\r\n return false;\r\n }\r\n\r\n return (\r\n expression.callee.object.type === AST_NODE_TYPES.Identifier &&\r\n expression.callee.object.name === 'console' &&\r\n expression.callee.property.type === AST_NODE_TYPES.Identifier &&\r\n ['log', 'error', 'warn', 'info', 'debug'].includes(expression.callee.property.name)\r\n );\r\n}\r\n\r\nfunction isRethrowOfCatchParam(\r\n statement: TSESTree.Statement,\r\n catchParamName: string\r\n): boolean {\r\n return (\r\n statement.type === AST_NODE_TYPES.ThrowStatement &&\r\n statement.argument !== null &&\r\n statement.argument.type === AST_NODE_TYPES.Identifier &&\r\n statement.argument.name === catchParamName\r\n );\r\n}\r\n\r\nexport const noCatchLogRethrow = createRule({\r\n name: 'no-catch-log-rethrow',\r\n meta: {\r\n type: 'suggestion',\r\n docs: {\r\n description:\r\n 'Disallow catch blocks that only log and rethrow the same error. AI tools frequently generate catch-log-rethrow patterns that add noise without recovery or context.',\r\n },\r\n fixable: undefined,\r\n schema: [],\r\n messages: {\r\n catchLogRethrow:\r\n 'This catch block only logs and rethrows the same error. AI tools frequently generate this noisy pattern without adding recovery. Either remove the catch block or add meaningful handling/context.',\r\n },\r\n },\r\n defaultOptions: [],\r\n create(context) {\r\n return {\r\n CatchClause(node) {\r\n if (!node.param || node.param.type !== AST_NODE_TYPES.Identifier) {\r\n return;\r\n }\r\n\r\n const bodyStatements = node.body.body;\r\n if (bodyStatements.length < 2) {\r\n return;\r\n }\r\n\r\n const lastStatement = bodyStatements[bodyStatements.length - 1];\r\n if (!isRethrowOfCatchParam(lastStatement, node.param.name)) {\r\n return;\r\n }\r\n\r\n const leadingStatements = bodyStatements.slice(0, -1);\r\n const allConsoleCalls = leadingStatements.every(isConsoleCallStatement);\r\n\r\n if (allConsoleCalls) {\r\n context.report({\r\n node,\r\n messageId: 'catchLogRethrow',\r\n });\r\n }\r\n },\r\n };\r\n },\r\n});\r\n\r\nexport default noCatchLogRethrow;\r\n","import { ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';\r\n\r\nconst createRule = ESLintUtils.RuleCreator(\r\n (name) => `https://github.com/YashJadhav21/eslint-plugin-ai-guard/blob/main/docs/rules/${name}.md`\r\n);\r\n\r\nexport const noCatchWithoutUse = createRule({\r\n name: 'no-catch-without-use',\r\n meta: {\r\n type: 'suggestion',\r\n docs: {\r\n description:\r\n 'Disallow catch parameters that are never used. AI tools frequently generate `catch (e)` while ignoring the error entirely, which hides actionable debugging context.',\r\n },\r\n fixable: undefined,\r\n schema: [],\r\n messages: {\r\n unusedCatchParam:\r\n 'Catch parameter `{{name}}` is never used. AI-generated catch blocks often include an unused error variable that hides missing error handling. Use it, remove it, or add explicit intent.',\r\n },\r\n },\r\n defaultOptions: [],\r\n create(context) {\r\n return {\r\n CatchClause(node) {\r\n if (!node.param || node.param.type !== AST_NODE_TYPES.Identifier) {\r\n return;\r\n }\r\n\r\n const catchParamName = node.param.name;\r\n\r\n // `_error` naming is a common convention to intentionally ignore values.\r\n if (catchParamName.startsWith('_')) {\r\n return;\r\n }\r\n\r\n // Token-based check is intentionally conservative: if the identifier appears\r\n // anywhere in the catch body, we treat it as used to avoid false positives.\r\n const tokens = context.sourceCode.getTokens(node.body);\r\n const hasUsage = tokens.some(\r\n (token) => token.type === 'Identifier' && token.value === catchParamName\r\n );\r\n\r\n if (!hasUsage) {\r\n context.report({\r\n node: node.param,\r\n messageId: 'unusedCatchParam',\r\n data: { name: catchParamName },\r\n });\r\n }\r\n },\r\n };\r\n },\r\n});\r\n\r\nexport default noCatchWithoutUse;\r\n","import { ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';\r\nimport type { TSESTree } from '@typescript-eslint/utils';\r\n\r\nconst createRule = ESLintUtils.RuleCreator(\r\n (name) => `https://github.com/YashJadhav21/eslint-plugin-ai-guard/blob/main/docs/rules/${name}.md`\r\n);\r\n\r\nconst ARRAY_CALLBACK_METHODS = ['map', 'filter', 'forEach', 'reduce', 'flatMap', 'find', 'findIndex', 'some', 'every'] as const;\r\n\r\nconst PROMISE_COMBINATORS = ['all', 'allSettled', 'race', 'any'] as const;\r\nconst METHODS_ALLOWING_PROMISE_COLLECTION = new Set(['map', 'flatMap']);\r\n\r\nfunction isNode(value: unknown): value is TSESTree.Node {\r\n return typeof value === 'object' && value !== null && 'type' in value;\r\n}\r\n\r\nfunction getChildNodes(node: TSESTree.Node): TSESTree.Node[] {\r\n const children: TSESTree.Node[] = [];\r\n for (const [key, value] of Object.entries(node as unknown as Record<string, unknown>)) {\r\n if (key === 'parent') continue;\r\n\r\n if (!value) continue;\r\n if (Array.isArray(value)) {\r\n for (const item of value) {\r\n if (isNode(item)) {\r\n children.push(item);\r\n }\r\n }\r\n continue;\r\n }\r\n\r\n if (isNode(value)) {\r\n children.push(value);\r\n }\r\n }\r\n return children;\r\n}\r\n\r\nfunction isPromiseCombinatorCall(node: TSESTree.CallExpression): boolean {\r\n return (\r\n node.callee.type === AST_NODE_TYPES.MemberExpression &&\r\n node.callee.object.type === AST_NODE_TYPES.Identifier &&\r\n node.callee.object.name === 'Promise' &&\r\n node.callee.property.type === AST_NODE_TYPES.Identifier &&\r\n PROMISE_COMBINATORS.includes(\r\n node.callee.property.name as (typeof PROMISE_COMBINATORS)[number],\r\n )\r\n );\r\n}\r\n\r\n/**\r\n * Checks if the given CallExpression (e.g., arr.map(...)) is used as an argument\r\n * to Promise.all(), Promise.allSettled(), Promise.race(), or Promise.any().\r\n */\r\nfunction isWrappedInPromiseCombinator(\r\n node: TSESTree.CallExpression,\r\n context: Readonly<Parameters<ReturnType<typeof createRule>['create']>[0]>\r\n): boolean {\r\n const ancestors = context.sourceCode.getAncestors(node);\r\n\r\n const directParent = node.parent;\r\n if (\r\n directParent &&\r\n directParent.type === AST_NODE_TYPES.CallExpression &&\r\n isPromiseCombinatorCall(directParent)\r\n ) {\r\n return true;\r\n }\r\n\r\n for (let i = ancestors.length - 1; i >= 0; i--) {\r\n const ancestor = ancestors[i];\r\n if (ancestor.type === AST_NODE_TYPES.CallExpression && isPromiseCombinatorCall(ancestor)) {\r\n return true;\r\n }\r\n\r\n if (ancestor.type === AST_NODE_TYPES.CallExpression) {\r\n break;\r\n }\r\n }\r\n return false;\r\n}\r\n\r\nfunction isIdentifierConsumedByPromiseCombinator(\r\n node: TSESTree.Node,\r\n identifierName: string,\r\n): boolean {\r\n let found = false;\r\n\r\n const visit = (current: TSESTree.Node): void => {\r\n if (found) return;\r\n\r\n if (\r\n current.type === AST_NODE_TYPES.CallExpression &&\r\n isPromiseCombinatorCall(current)\r\n ) {\r\n for (const arg of current.arguments) {\r\n if (arg.type === AST_NODE_TYPES.Identifier && arg.name === identifierName) {\r\n found = true;\r\n return;\r\n }\r\n }\r\n }\r\n\r\n for (const child of getChildNodes(current)) {\r\n visit(child);\r\n if (found) return;\r\n }\r\n };\r\n\r\n visit(node);\r\n return found;\r\n}\r\n\r\nfunction isAssignedAndConsumedByPromiseCombinator(\r\n node: TSESTree.CallExpression,\r\n): boolean {\r\n if (\r\n !node.parent ||\r\n node.parent.type !== AST_NODE_TYPES.VariableDeclarator ||\r\n node.parent.id.type !== AST_NODE_TYPES.Identifier\r\n ) {\r\n return false;\r\n }\r\n\r\n const variableName = node.parent.id.name;\r\n const declaration = node.parent.parent;\r\n if (!declaration || declaration.type !== AST_NODE_TYPES.VariableDeclaration) {\r\n return false;\r\n }\r\n\r\n const container = declaration.parent;\r\n if (!container || (container.type !== AST_NODE_TYPES.Program && container.type !== AST_NODE_TYPES.BlockStatement)) {\r\n return false;\r\n }\r\n\r\n const body = container.body;\r\n const declarationIndex = body.findIndex((statement) => statement === declaration);\r\n if (declarationIndex === -1) {\r\n return false;\r\n }\r\n\r\n for (let i = declarationIndex + 1; i < body.length; i++) {\r\n const statement = body[i];\r\n if (isIdentifierConsumedByPromiseCombinator(statement, variableName)) {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n}\r\n\r\n/**\r\n * Checks if a node is an async function expression or arrow function.\r\n */\r\nfunction isAsyncCallback(node: TSESTree.Node): boolean {\r\n return (\r\n (node.type === AST_NODE_TYPES.FunctionExpression ||\r\n node.type === AST_NODE_TYPES.ArrowFunctionExpression) &&\r\n node.async\r\n );\r\n}\r\n\r\nexport const noAsyncArrayCallback = createRule({\r\n name: 'no-async-array-callback',\r\n meta: {\r\n type: 'problem',\r\n docs: {\r\n description:\r\n 'Disallow async callbacks in array iteration methods (map, filter, forEach, reduce). AI tools generate `array.map(async ...)` which returns `Promise[]` instead of resolved values — a silent bug.',\r\n },\r\n fixable: undefined,\r\n schema: [],\r\n messages: {\r\n asyncArrayCallback:\r\n 'Async callback passed to Array.{{method}}(). This returns an array of Promises, not resolved values. AI tools frequently generate this pattern. Wrap with `await Promise.all(array.{{method}}(...))` or use a for...of loop.',\r\n },\r\n },\r\n defaultOptions: [],\r\n create(context) {\r\n return {\r\n CallExpression(node) {\r\n // Check if this is a method call like something.map(...), something.filter(...), etc.\r\n if (\r\n node.callee.type !== AST_NODE_TYPES.MemberExpression ||\r\n node.callee.property.type !== AST_NODE_TYPES.Identifier\r\n ) {\r\n return;\r\n }\r\n\r\n const methodName = node.callee.property.name;\r\n\r\n if (\r\n !ARRAY_CALLBACK_METHODS.includes(\r\n methodName as (typeof ARRAY_CALLBACK_METHODS)[number]\r\n )\r\n ) {\r\n return;\r\n }\r\n\r\n // The callback is the first argument for all methods except reduce where it's also the first\r\n const callback = node.arguments[0];\r\n if (!callback) {\r\n return;\r\n }\r\n\r\n if (isAsyncCallback(callback)) {\r\n // Don't flag if the array method call is already wrapped in Promise.all/allSettled/race/any\r\n // e.g., Promise.all(arr.map(async ...)) — this is the correct pattern\r\n if (isWrappedInPromiseCombinator(node, context)) {\r\n return;\r\n }\r\n\r\n if (\r\n METHODS_ALLOWING_PROMISE_COLLECTION.has(methodName) &&\r\n isAssignedAndConsumedByPromiseCombinator(node)\r\n ) {\r\n return;\r\n }\r\n\r\n context.report({\r\n node: callback,\r\n messageId: 'asyncArrayCallback',\r\n data: {\r\n method: methodName,\r\n },\r\n });\r\n }\r\n },\r\n };\r\n },\r\n});\r\n\r\nexport default noAsyncArrayCallback;\r\n","import { ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';\r\nimport type { TSESTree } from '@typescript-eslint/utils';\r\n\r\nconst createRule = ESLintUtils.RuleCreator(\r\n (name) => `https://github.com/YashJadhav21/eslint-plugin-ai-guard/blob/main/docs/rules/${name}.md`\r\n);\r\n\r\nconst KNOWN_PROMISE_FACTORIES = new Set([\r\n 'fetch',\r\n]);\r\n\r\nconst PROMISE_STATIC_METHODS = new Set([\r\n 'resolve',\r\n 'reject',\r\n 'all',\r\n 'allSettled',\r\n 'race',\r\n 'any',\r\n]);\r\n\r\ninterface TypeCheckerLike {\r\n getTypeAtLocation(node: unknown): unknown;\r\n typeToString(type: unknown): string;\r\n getPromisedTypeOfPromise?(type: unknown): unknown;\r\n}\r\n\r\ninterface ProgramLike {\r\n getTypeChecker(): TypeCheckerLike;\r\n}\r\n\r\ninterface ParserServicesLike {\r\n program?: ProgramLike;\r\n esTreeNodeToTSNodeMap?: {\r\n get(node: TSESTree.Node): unknown;\r\n };\r\n}\r\n\r\ninterface VariableLike {\r\n name: string;\r\n defs?: Array<{ node?: TSESTree.Node }>;\r\n}\r\n\r\ninterface ScopeLike {\r\n upper: ScopeLike | null;\r\n set?: Map<string, VariableLike>;\r\n variables?: VariableLike[];\r\n}\r\n\r\ninterface AsyncBindingInfo {\r\n isAsync: boolean;\r\n hasInternalErrorHandling: boolean;\r\n}\r\n\r\nfunction isAstNode(value: unknown): value is TSESTree.Node {\r\n return typeof value === 'object' && value !== null && 'type' in value;\r\n}\r\n\r\nfunction nodeHasCatchClause(node: TSESTree.Node): boolean {\r\n if (node.type === AST_NODE_TYPES.TryStatement && !!node.handler) {\r\n return true;\r\n }\r\n\r\n for (const [key, value] of Object.entries(node as unknown as Record<string, unknown>)) {\r\n if (key === 'parent') continue;\r\n\r\n if (Array.isArray(value)) {\r\n for (const item of value) {\r\n if (isAstNode(item) && nodeHasCatchClause(item)) {\r\n return true;\r\n }\r\n }\r\n continue;\r\n }\r\n\r\n if (isAstNode(value) && nodeHasCatchClause(value)) {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n}\r\n\r\n/**\r\n * Check if a CallExpression's callee is known async via local declarations.\r\n */\r\nfunction isAsyncFunctionLike(node: TSESTree.Node | undefined): boolean {\r\n if (!node) return false;\r\n if (node.type === AST_NODE_TYPES.FunctionDeclaration) {\r\n return node.async;\r\n }\r\n if (\r\n node.type === AST_NODE_TYPES.FunctionExpression ||\r\n node.type === AST_NODE_TYPES.ArrowFunctionExpression\r\n ) {\r\n return node.async;\r\n }\r\n if (\r\n node.type === AST_NODE_TYPES.VariableDeclarator &&\r\n node.init &&\r\n (node.init.type === AST_NODE_TYPES.FunctionExpression ||\r\n node.init.type === AST_NODE_TYPES.ArrowFunctionExpression)\r\n ) {\r\n return node.init.async;\r\n }\r\n return false;\r\n}\r\n\r\nfunction getAsyncBindingInfo(node: TSESTree.Node | undefined): AsyncBindingInfo {\r\n if (!node) {\r\n return { isAsync: false, hasInternalErrorHandling: false };\r\n }\r\n\r\n if (node.type === AST_NODE_TYPES.FunctionDeclaration) {\r\n return {\r\n isAsync: node.async,\r\n hasInternalErrorHandling: node.body ? nodeHasCatchClause(node.body) : false,\r\n };\r\n }\r\n\r\n if (\r\n node.type === AST_NODE_TYPES.FunctionExpression ||\r\n node.type === AST_NODE_TYPES.ArrowFunctionExpression\r\n ) {\r\n return {\r\n isAsync: node.async,\r\n hasInternalErrorHandling:\r\n node.body.type === AST_NODE_TYPES.BlockStatement\r\n ? nodeHasCatchClause(node.body)\r\n : false,\r\n };\r\n }\r\n\r\n if (\r\n node.type === AST_NODE_TYPES.VariableDeclarator &&\r\n node.init &&\r\n (node.init.type === AST_NODE_TYPES.FunctionExpression ||\r\n node.init.type === AST_NODE_TYPES.ArrowFunctionExpression)\r\n ) {\r\n return {\r\n isAsync: node.init.async,\r\n hasInternalErrorHandling:\r\n node.init.body.type === AST_NODE_TYPES.BlockStatement\r\n ? nodeHasCatchClause(node.init.body)\r\n : false,\r\n };\r\n }\r\n\r\n return { isAsync: false, hasInternalErrorHandling: false };\r\n}\r\n\r\nfunction findVariableInScope(scope: ScopeLike, name: string): VariableLike | null {\r\n const fromMap = scope.set?.get(name);\r\n if (fromMap) {\r\n return fromMap;\r\n }\r\n\r\n if (scope.variables) {\r\n const fromArray = scope.variables.find((v) => v.name === name);\r\n if (fromArray) {\r\n return fromArray;\r\n }\r\n }\r\n\r\n return null;\r\n}\r\n\r\nfunction isIdentifierBoundToAsyncFunction(\r\n identifier: TSESTree.Identifier,\r\n context: Readonly<Parameters<ReturnType<typeof createRule>['create']>[0]>,\r\n): AsyncBindingInfo {\r\n let scope = context.sourceCode.getScope(identifier) as unknown as ScopeLike | null;\r\n\r\n while (scope) {\r\n const variable = findVariableInScope(scope, identifier.name);\r\n if (variable) {\r\n const defs = variable.defs ?? [];\r\n for (const def of defs) {\r\n const info = getAsyncBindingInfo(def.node);\r\n if (info.isAsync) {\r\n return info;\r\n }\r\n }\r\n\r\n if (defs.length === 0 && isAsyncFunctionLike(variable as unknown as TSESTree.Node)) {\r\n return getAsyncBindingInfo(variable as unknown as TSESTree.Node);\r\n }\r\n\r\n return { isAsync: false, hasInternalErrorHandling: false };\r\n }\r\n scope = scope.upper;\r\n }\r\n\r\n return { isAsync: false, hasInternalErrorHandling: false };\r\n}\r\n\r\nfunction isLocallyAsyncCallee(\r\n node: TSESTree.CallExpression,\r\n context: Readonly<Parameters<ReturnType<typeof createRule>['create']>[0]>,\r\n): AsyncBindingInfo {\r\n if (node.callee.type === AST_NODE_TYPES.Identifier) {\r\n const info = isIdentifierBoundToAsyncFunction(node.callee, context);\r\n if (info.isAsync) {\r\n return info;\r\n }\r\n }\r\n\r\n if (\r\n (node.callee.type === AST_NODE_TYPES.FunctionExpression ||\r\n node.callee.type === AST_NODE_TYPES.ArrowFunctionExpression) &&\r\n node.callee.async\r\n ) {\r\n return {\r\n isAsync: true,\r\n hasInternalErrorHandling:\r\n node.callee.body.type === AST_NODE_TYPES.BlockStatement\r\n ? nodeHasCatchClause(node.callee.body)\r\n : false,\r\n };\r\n }\r\n\r\n return { isAsync: false, hasInternalErrorHandling: false };\r\n}\r\n\r\nfunction isKnownPromiseFactoryCall(node: TSESTree.CallExpression): boolean {\r\n if (node.callee.type === AST_NODE_TYPES.Identifier) {\r\n return KNOWN_PROMISE_FACTORIES.has(node.callee.name);\r\n }\r\n\r\n if (\r\n node.callee.type === AST_NODE_TYPES.MemberExpression &&\r\n node.callee.object.type === AST_NODE_TYPES.Identifier &&\r\n node.callee.object.name === 'Promise' &&\r\n node.callee.property.type === AST_NODE_TYPES.Identifier\r\n ) {\r\n return PROMISE_STATIC_METHODS.has(node.callee.property.name);\r\n }\r\n\r\n return false;\r\n}\r\n\r\nfunction getParserServices(\r\n context: Readonly<Parameters<ReturnType<typeof createRule>['create']>[0]>,\r\n): ParserServicesLike | null {\r\n const services = context.sourceCode.parserServices as unknown;\r\n if (!services || typeof services !== 'object') {\r\n return null;\r\n }\r\n\r\n return services as ParserServicesLike;\r\n}\r\n\r\nfunction isPromiseLikeByTypeInfo(\r\n node: TSESTree.CallExpression,\r\n context: Readonly<Parameters<ReturnType<typeof createRule>['create']>[0]>,\r\n): boolean {\r\n const services = getParserServices(context);\r\n if (!services?.program || !services.esTreeNodeToTSNodeMap) {\r\n return false;\r\n }\r\n\r\n try {\r\n const tsNode = services.esTreeNodeToTSNodeMap.get(node);\r\n if (!tsNode) {\r\n return false;\r\n }\r\n\r\n const checker = services.program.getTypeChecker();\r\n const type = checker.getTypeAtLocation(tsNode);\r\n\r\n if (typeof checker.getPromisedTypeOfPromise === 'function') {\r\n if (checker.getPromisedTypeOfPromise(type)) {\r\n return true;\r\n }\r\n }\r\n\r\n const text = checker.typeToString(type).toLowerCase();\r\n return (\r\n text === 'promise' ||\r\n text.includes('promise<') ||\r\n text.includes('promiselike<') ||\r\n text.includes('thenable')\r\n );\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Check if the ExpressionStatement is already handled:\r\n * - Used as argument to .then() or .catch()\r\n * - Inside an await\r\n * - Piped to void\r\n * - Result is assigned\r\n */\r\nfunction isExpressionHandled(node: TSESTree.ExpressionStatement): boolean {\r\n const expr = node.expression;\r\n\r\n // Check if the expression is a call chained with .then() or .catch()\r\n if (expr.type === AST_NODE_TYPES.CallExpression) {\r\n if (expr.callee.type === AST_NODE_TYPES.MemberExpression) {\r\n const prop = expr.callee.property;\r\n if (prop.type === AST_NODE_TYPES.Identifier) {\r\n if (prop.name === 'then' || prop.name === 'catch' || prop.name === 'finally') {\r\n return true;\r\n }\r\n }\r\n }\r\n }\r\n\r\n // void operator suppresses the warning intentionally\r\n if (expr.type === AST_NODE_TYPES.UnaryExpression && expr.operator === 'void') {\r\n return true;\r\n }\r\n\r\n return false;\r\n}\r\n\r\nexport const noFloatingPromise = createRule({\r\n name: 'no-floating-promise',\r\n meta: {\r\n type: 'problem',\r\n docs: {\r\n description:\r\n 'Disallow calling an async function or Promise-returning function without awaiting or handling the result. AI tools frequently generate floating promises where errors disappear silently. Includes a safe autofix that marks intentional fire-and-forget calls with void.',\r\n },\r\n fixable: 'code',\r\n schema: [],\r\n messages: {\r\n floatingPromise:\r\n 'This async call is not awaited, returned, or error-handled (.catch). AI tools frequently generate floating promises, causing errors to be silently lost. Add `await`, `.catch()`, or assign the result.',\r\n },\r\n },\r\n defaultOptions: [],\r\n create(context) {\r\n return {\r\n // Check ExpressionStatements — standalone call expressions\r\n ExpressionStatement(node) {\r\n if (\r\n node.expression.type === AST_NODE_TYPES.NewExpression &&\r\n node.expression.callee.type === AST_NODE_TYPES.Identifier &&\r\n node.expression.callee.name === 'Promise'\r\n ) {\r\n context.report({\r\n node,\r\n messageId: 'floatingPromise',\r\n fix: (fixer) =>\r\n fixer.replaceText(\r\n node.expression,\r\n `void ${context.sourceCode.getText(node.expression)}`\r\n ),\r\n });\r\n return;\r\n }\r\n\r\n // We only care about bare CallExpression statements\r\n if (node.expression.type !== AST_NODE_TYPES.CallExpression) {\r\n return;\r\n }\r\n\r\n // If it's already chained with .then()/.catch() or wrapped in void, skip\r\n if (isExpressionHandled(node)) {\r\n return;\r\n }\r\n\r\n const callExpr = node.expression;\r\n const localAsyncInfo = isLocallyAsyncCallee(callExpr, context);\r\n\r\n // If a local async helper already contains its own try/catch,\r\n // calling it fire-and-forget is often intentional in UI effects.\r\n if (localAsyncInfo.isAsync && localAsyncInfo.hasInternalErrorHandling) {\r\n return;\r\n }\r\n\r\n if (\r\n localAsyncInfo.isAsync ||\r\n isKnownPromiseFactoryCall(callExpr) ||\r\n isPromiseLikeByTypeInfo(callExpr, context)\r\n ) {\r\n context.report({\r\n node,\r\n messageId: 'floatingPromise',\r\n fix: (fixer) =>\r\n fixer.replaceText(\r\n node.expression,\r\n `void ${context.sourceCode.getText(node.expression)}`\r\n ),\r\n });\r\n }\r\n },\r\n };\r\n },\r\n});\r\n\r\nexport default noFloatingPromise;\r\n","import { ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';\nimport type { TSESTree, TSESLint } from '@typescript-eslint/utils';\nimport path from 'path';\n\nconst createRule = ESLintUtils.RuleCreator(\n (name) => `https://github.com/YashJadhav21/eslint-plugin-ai-guard/blob/main/docs/rules/${name}.md`\n);\n\nconst LOOP_TYPES = new Set([\n AST_NODE_TYPES.ForStatement,\n AST_NODE_TYPES.ForInStatement,\n AST_NODE_TYPES.ForOfStatement,\n AST_NODE_TYPES.WhileStatement,\n AST_NODE_TYPES.DoWhileStatement,\n]);\n\nconst SUPPRESSION_REGEX = /ai-guard-disable\\s+no-await-in-loop\\b/i;\n\nconst RETRY_NAME_REGEX = /(retry|retries|attempt|attempts|fallback|tryagain|recovery)/i;\nconst SEQUENTIAL_DEPENDENCY_NAME_REGEX = /(previous|prev|last|carry|accumulator|stateful)/i;\n// Simulation, animation, and step-by-step patterns — sequential await is intentional\nconst SIMULATION_NAME_REGEX = /(simulat|animat|demo|visuali|step|scene|frame|render|tick|sequence|tutorial|lesson|walk)/i;\n\nconst ERROR_CODE_HINTS = [\n 'access-denied',\n 'timeout',\n 'rate-limit',\n 'not-found',\n];\n\nconst CONTROL_AWAIT_HINTS = [\n 'sleep',\n 'delay',\n 'wait',\n 'throttle',\n 'ratelimit',\n 'backoff',\n];\n\n// Timer calls inside a loop indicate intentional sequencing (animation/polling)\nconst TIMER_FUNCTION_NAMES = new Set([\n 'setinterval',\n 'settimeout',\n 'requestanimationframe',\n 'queuemicrotask',\n 'sleep',\n 'delay',\n 'wait',\n]);\n\nconst MUTATION_METHOD_NAMES = new Set([\n 'push',\n 'pop',\n 'shift',\n 'unshift',\n 'splice',\n 'set',\n 'add',\n 'delete',\n 'clear',\n]);\n\ntype LoopNode =\n | TSESTree.ForStatement\n | TSESTree.ForInStatement\n | TSESTree.ForOfStatement\n | TSESTree.WhileStatement\n | TSESTree.DoWhileStatement;\n\ninterface IntentAnalysis {\n isIndependent: boolean;\n}\n\nfunction isFunctionNode(node: TSESTree.Node): boolean {\n return (\n node.type === AST_NODE_TYPES.FunctionDeclaration ||\n node.type === AST_NODE_TYPES.FunctionExpression ||\n node.type === AST_NODE_TYPES.ArrowFunctionExpression\n );\n}\n\nfunction isNodeLike(value: unknown): value is TSESTree.Node {\n return typeof value === 'object' && value !== null && 'type' in value;\n}\n\nfunction walkNode(\n node: TSESTree.Node,\n visitor: (current: TSESTree.Node) => void,\n skipNestedFunctions: boolean,\n isRoot = true,\n): void {\n visitor(node);\n\n for (const [key, value] of Object.entries(node as unknown as Record<string, unknown>)) {\n if (key === 'parent' || !value) continue;\n\n if (Array.isArray(value)) {\n for (const item of value) {\n if (!isNodeLike(item)) continue;\n if (skipNestedFunctions && !isRoot && isFunctionNode(item)) continue;\n walkNode(item, visitor, skipNestedFunctions, false);\n }\n continue;\n }\n\n if (!isNodeLike(value)) continue;\n if (skipNestedFunctions && !isRoot && isFunctionNode(value)) continue;\n walkNode(value, visitor, skipNestedFunctions, false);\n }\n}\n\nfunction collectPatternNames(pattern: TSESTree.Node, bucket: Set<string>): void {\n if (pattern.type === AST_NODE_TYPES.Identifier) {\n bucket.add(pattern.name);\n return;\n }\n\n if (pattern.type === AST_NODE_TYPES.AssignmentPattern) {\n collectPatternNames(pattern.left, bucket);\n return;\n }\n\n if (pattern.type === AST_NODE_TYPES.RestElement) {\n collectPatternNames(pattern.argument, bucket);\n return;\n }\n\n if (pattern.type === AST_NODE_TYPES.ArrayPattern) {\n for (const element of pattern.elements) {\n if (!element) continue;\n if (element.type === AST_NODE_TYPES.RestElement) {\n collectPatternNames(element.argument, bucket);\n continue;\n }\n collectPatternNames(element, bucket);\n }\n return;\n }\n\n if (pattern.type === AST_NODE_TYPES.ObjectPattern) {\n for (const prop of pattern.properties) {\n if (prop.type === AST_NODE_TYPES.RestElement) {\n collectPatternNames(prop.argument, bucket);\n continue;\n }\n collectPatternNames(prop.value, bucket);\n }\n }\n}\n\nfunction getLoopNodeName(type: AST_NODE_TYPES): string {\n switch (type) {\n case AST_NODE_TYPES.ForStatement:\n return 'for loop';\n case AST_NODE_TYPES.ForInStatement:\n return 'for...in loop';\n case AST_NODE_TYPES.ForOfStatement:\n return 'for...of loop';\n case AST_NODE_TYPES.WhileStatement:\n return 'while loop';\n case AST_NODE_TYPES.DoWhileStatement:\n return 'do...while loop';\n default:\n return 'loop';\n }\n}\n\nfunction hasSuppressionComment(comments: readonly TSESTree.Comment[]): boolean {\n return comments.some((comment) => SUPPRESSION_REGEX.test(comment.value));\n}\n\nfunction hasFileSuppression(sourceCode: Readonly<TSESLint.SourceCode>): boolean {\n return hasSuppressionComment(sourceCode.getAllComments());\n}\n\nfunction hasLoopSuppression(\n loopNode: LoopNode,\n sourceCode: Readonly<TSESLint.SourceCode>,\n): boolean {\n const commentsBefore = sourceCode.getCommentsBefore(loopNode);\n if (hasSuppressionComment(commentsBefore)) {\n return true;\n }\n\n const allComments = sourceCode.getAllComments();\n const nearComments = allComments.filter((comment) => {\n if (!comment.range || !loopNode.range) {\n return false;\n }\n\n const [, commentEnd] = comment.range;\n const [loopStart] = loopNode.range;\n return commentEnd <= loopStart && loopStart - commentEnd < 160;\n });\n\n return hasSuppressionComment(nearComments);\n}\n\nfunction getCalleeName(callee: TSESTree.Node): string | null {\n if (callee.type === AST_NODE_TYPES.Identifier) {\n return callee.name;\n }\n\n if (\n callee.type === AST_NODE_TYPES.MemberExpression &&\n callee.property.type === AST_NODE_TYPES.Identifier\n ) {\n return callee.property.name;\n }\n\n return null;\n}\n\nfunction getRootIdentifierName(node: TSESTree.Node): string | null {\n if (node.type === AST_NODE_TYPES.Identifier) {\n return node.name;\n }\n\n if (node.type === AST_NODE_TYPES.MemberExpression) {\n return getRootIdentifierName(node.object);\n }\n\n return null;\n}\n\nfunction collectLocalBindings(loopNode: LoopNode): Set<string> {\n const bindings = new Set<string>();\n\n if (loopNode.type === AST_NODE_TYPES.ForStatement && loopNode.init?.type === AST_NODE_TYPES.VariableDeclaration) {\n for (const decl of loopNode.init.declarations) {\n collectPatternNames(decl.id, bindings);\n }\n }\n\n if (\n (loopNode.type === AST_NODE_TYPES.ForOfStatement || loopNode.type === AST_NODE_TYPES.ForInStatement) &&\n loopNode.left.type === AST_NODE_TYPES.VariableDeclaration\n ) {\n for (const decl of loopNode.left.declarations) {\n collectPatternNames(decl.id, bindings);\n }\n }\n\n walkNode(\n loopNode.body,\n (node) => {\n if (node.type === AST_NODE_TYPES.VariableDeclarator) {\n collectPatternNames(node.id, bindings);\n }\n\n if (node.type === AST_NODE_TYPES.FunctionDeclaration && node.id) {\n bindings.add(node.id.name);\n }\n },\n true,\n );\n\n return bindings;\n}\n\nfunction collectSiblingStatements(loopNode: LoopNode): TSESTree.Statement[] {\n if (!loopNode.parent || loopNode.parent.type !== AST_NODE_TYPES.BlockStatement) {\n return [];\n }\n\n const siblings = loopNode.parent.body;\n const idx = siblings.findIndex((stmt) => stmt === loopNode);\n if (idx === -1) return [];\n\n const result: TSESTree.Statement[] = [];\n if (idx > 0) result.push(siblings[idx - 1]);\n if (idx < siblings.length - 1) result.push(siblings[idx + 1]);\n return result;\n}\n\nfunction nodeContainsErrorCodeHint(node: TSESTree.Node): boolean {\n let found = false;\n\n walkNode(\n node,\n (current) => {\n if (found) return;\n if (current.type !== AST_NODE_TYPES.Literal || typeof current.value !== 'string') {\n return;\n }\n\n const lower = current.value.toLowerCase();\n if (ERROR_CODE_HINTS.some((hint) => lower.includes(hint))) {\n found = true;\n }\n },\n true,\n );\n\n return found;\n}\n\nfunction analyzeIntent(loopNode: LoopNode): IntentAnalysis {\n if (loopNode.type === AST_NODE_TYPES.ForOfStatement && loopNode.await) {\n return { isIndependent: false };\n }\n\n const localBindings = collectLocalBindings(loopNode);\n const siblingStatements = collectSiblingStatements(loopNode);\n\n let hasRetryNameHint = false;\n let hasCounterIncrement = false;\n let hasEarlyExit = false;\n let hasCatchContinue = false;\n let hasErrorCodeHint = false;\n let hasSequentialDependency = false;\n let hasControlAwait = false;\n\n const checkIdentifierName = (name: string): void => {\n if (RETRY_NAME_REGEX.test(name)) {\n hasRetryNameHint = true;\n }\n\n if (SEQUENTIAL_DEPENDENCY_NAME_REGEX.test(name)) {\n hasSequentialDependency = true;\n }\n\n // Simulation/animation/step names indicate intentional sequential behavior\n if (SIMULATION_NAME_REGEX.test(name)) {\n hasSequentialDependency = true;\n }\n };\n\n walkNode(\n loopNode,\n (node) => {\n if (node.type === AST_NODE_TYPES.Identifier) {\n checkIdentifierName(node.name);\n }\n\n if (node.type === AST_NODE_TYPES.AwaitExpression &&\n node.argument.type === AST_NODE_TYPES.CallExpression\n ) {\n const calleeName = getCalleeName(node.argument.callee);\n if (calleeName) {\n const lower = calleeName.toLowerCase();\n if (CONTROL_AWAIT_HINTS.some((hint) => lower.includes(hint))) {\n hasControlAwait = true;\n }\n // Awaiting a timer function = intentional sequencing\n if (TIMER_FUNCTION_NAMES.has(lower)) {\n hasControlAwait = true;\n }\n }\n }\n\n if (node.type === AST_NODE_TYPES.UpdateExpression) {\n const target = node.argument;\n if (target.type === AST_NODE_TYPES.Identifier) {\n checkIdentifierName(target.name);\n if (RETRY_NAME_REGEX.test(target.name)) {\n hasCounterIncrement = true;\n }\n if (!localBindings.has(target.name)) {\n hasSequentialDependency = true;\n }\n }\n }\n\n if (node.type === AST_NODE_TYPES.AssignmentExpression) {\n if (node.left.type === AST_NODE_TYPES.Identifier) {\n checkIdentifierName(node.left.name);\n if (RETRY_NAME_REGEX.test(node.left.name)) {\n hasCounterIncrement = true;\n }\n if (!localBindings.has(node.left.name)) {\n hasSequentialDependency = true;\n }\n }\n\n if (node.left.type === AST_NODE_TYPES.MemberExpression) {\n const root = getRootIdentifierName(node.left.object);\n if (root && !localBindings.has(root)) {\n hasSequentialDependency = true;\n }\n }\n }\n\n if (\n node.type === AST_NODE_TYPES.ReturnStatement ||\n node.type === AST_NODE_TYPES.BreakStatement ||\n node.type === AST_NODE_TYPES.ContinueStatement\n ) {\n hasEarlyExit = true;\n }\n\n if (node.type === AST_NODE_TYPES.TryStatement && node.handler) {\n let catchHasContinue = false;\n walkNode(\n node.handler.body,\n (catchNode) => {\n if (catchNode.type === AST_NODE_TYPES.ContinueStatement) {\n catchHasContinue = true;\n }\n },\n true,\n );\n\n if (catchHasContinue) {\n hasCatchContinue = true;\n }\n }\n\n if (node.type === AST_NODE_TYPES.CallExpression) {\n if (\n node.callee.type === AST_NODE_TYPES.MemberExpression &&\n node.callee.property.type === AST_NODE_TYPES.Identifier\n ) {\n const method = node.callee.property.name.toLowerCase();\n if (MUTATION_METHOD_NAMES.has(method)) {\n const root = getRootIdentifierName(node.callee.object);\n if (root && !localBindings.has(root)) {\n hasSequentialDependency = true;\n }\n }\n }\n }\n\n if (node.type === AST_NODE_TYPES.Literal && typeof node.value === 'string') {\n const lower = node.value.toLowerCase();\n if (ERROR_CODE_HINTS.some((hint) => lower.includes(hint))) {\n hasErrorCodeHint = true;\n }\n }\n },\n true,\n );\n\n if (!hasRetryNameHint && siblingStatements.length > 0) {\n for (const sibling of siblingStatements) {\n if (nodeContainsErrorCodeHint(sibling)) {\n hasErrorCodeHint = true;\n }\n\n walkNode(\n sibling,\n (node) => {\n if (node.type === AST_NODE_TYPES.Identifier) {\n checkIdentifierName(node.name);\n }\n },\n true,\n );\n }\n }\n\n const hasRetryOrFallbackIntent =\n hasRetryNameHint ||\n hasCounterIncrement ||\n hasEarlyExit ||\n hasCatchContinue ||\n hasErrorCodeHint ||\n hasSequentialDependency ||\n hasControlAwait;\n\n return {\n isIndependent: !hasRetryOrFallbackIntent,\n };\n}\n\nfunction getLoopBodyStatements(loopNode: LoopNode): TSESTree.Statement[] {\n return loopNode.body.type === AST_NODE_TYPES.BlockStatement\n ? loopNode.body.body\n : [loopNode.body];\n}\n\nfunction getForOfParamName(loopNode: TSESTree.ForOfStatement): string | null {\n if (loopNode.left.type === AST_NODE_TYPES.Identifier) {\n return loopNode.left.name;\n }\n\n if (loopNode.left.type === AST_NODE_TYPES.VariableDeclaration) {\n if (loopNode.left.declarations.length !== 1) return null;\n const id = loopNode.left.declarations[0].id;\n if (id.type !== AST_NODE_TYPES.Identifier) return null;\n return id.name;\n }\n\n return null;\n}\n\nfunction buildSafeAutofix(\n loopNode: LoopNode,\n awaitNode: TSESTree.AwaitExpression,\n sourceCode: Readonly<TSESLint.SourceCode>,\n): string | null {\n if (\n !loopNode.parent ||\n loopNode.parent.type !== AST_NODE_TYPES.BlockStatement ||\n !loopNode.parent.parent ||\n !isFunctionNode(loopNode.parent.parent)\n ) {\n return null;\n }\n\n if (loopNode.type !== AST_NODE_TYPES.ForOfStatement || loopNode.await) {\n return null;\n }\n\n const loopStatements = getLoopBodyStatements(loopNode);\n if (loopStatements.length !== 1) {\n return null;\n }\n\n const onlyStatement = loopStatements[0];\n if (\n onlyStatement.type !== AST_NODE_TYPES.ExpressionStatement ||\n onlyStatement.expression.type !== AST_NODE_TYPES.AwaitExpression ||\n onlyStatement.expression !== awaitNode ||\n onlyStatement.expression.argument.type !== AST_NODE_TYPES.CallExpression\n ) {\n return null;\n }\n\n const paramName = getForOfParamName(loopNode);\n if (!paramName) {\n return null;\n }\n\n const iterableText = sourceCode.getText(loopNode.right);\n const awaitedCallText = sourceCode.getText(onlyStatement.expression.argument);\n\n return `await Promise.all(${iterableText}.map(async (${paramName}) => await ${awaitedCallText}));`;\n}\n\nexport const noAwaitInLoop = createRule({\n name: 'no-await-in-loop',\n meta: {\n type: 'suggestion',\n docs: {\n description:\n 'Disallow independent `await` usage inside loops, while allowing intentional retry/fallback/sequential workflows. AI tools frequently generate accidental sequential awaits where Promise.all would be safer and faster. Includes a safe autofix for simple independent loops.',\n },\n fixable: 'code',\n schema: [\n {\n type: 'object',\n properties: {\n allowPatterns: {\n type: 'array',\n items: { type: 'string' },\n description: 'File glob patterns to skip (e.g., **/*.test.ts, **/simulation/**)',\n },\n },\n additionalProperties: false,\n },\n ],\n messages: {\n awaitInLoop:\n 'Sequential `await` inside a {{loopType}} — if these items are independent, consider `Promise.all()` for parallel execution. If sequential order matters, this may be intentional.',\n },\n },\n defaultOptions: [{}],\n create(context, [options]) {\n if (hasFileSuppression(context.sourceCode)) {\n return {};\n }\n\n // File-level suppression: test files and simulation/demo files use sequential await intentionally\n const filename = context.filename ?? context.getFilename?.() ?? '';\n const fileBasename = path.basename(filename).toLowerCase();\n const filePath = filename.toLowerCase();\n\n const isTestFile =\n fileBasename.includes('.test.') ||\n fileBasename.includes('.spec.') ||\n filePath.includes('/__tests__/') ||\n filePath.includes('/test/') ||\n filePath.includes('/tests/');\n\n const isSimulationFile =\n SIMULATION_NAME_REGEX.test(fileBasename) ||\n filePath.includes('/simulation/') ||\n filePath.includes('/demo/') ||\n filePath.includes('/animation/') ||\n filePath.includes('/fixtures/');\n\n // Suppress entirely for test and simulation files\n if (isTestFile || isSimulationFile) {\n return {};\n }\n\n // Check user-provided allowPatterns (basic suffix/substring matching)\n const { allowPatterns = [] } = options as { allowPatterns?: string[] };\n for (const pattern of allowPatterns) {\n // Simple pattern: if file path contains the non-glob part\n const cleaned = pattern.replace(/\\*\\*/g, '').replace(/\\*/g, '').replace(/\\//g, path.sep);\n if (cleaned && filePath.includes(cleaned.toLowerCase())) {\n return {};\n }\n }\n\n const loopIntentCache = new WeakMap<LoopNode, IntentAnalysis>();\n const reportedLoops = new WeakSet<LoopNode>();\n\n /**\n * Track ancestor scope boundaries (functions) so we don't flag await\n * expressions inside a nested async function that happens to be inside a loop.\n */\n const functionBoundary: TSESTree.Node[] = [];\n\n function enterFunction(node: TSESTree.Node) {\n functionBoundary.push(node);\n }\n function exitFunction() {\n functionBoundary.pop();\n }\n\n return {\n FunctionDeclaration: enterFunction,\n FunctionExpression: enterFunction,\n ArrowFunctionExpression: enterFunction,\n 'FunctionDeclaration:exit': exitFunction,\n 'FunctionExpression:exit': exitFunction,\n 'ArrowFunctionExpression:exit': exitFunction,\n\n AwaitExpression(node) {\n // Walk up ancestors looking for a loop, but stop at any function boundary\n const ancestors = context.sourceCode.getAncestors(node);\n const currentFunction = functionBoundary[functionBoundary.length - 1];\n\n let enclosingLoop: LoopNode | null = null;\n for (let i = ancestors.length - 1; i >= 0; i--) {\n const ancestor = ancestors[i];\n\n // Stop if we hit the current function boundary\n if (ancestor === currentFunction) {\n break;\n }\n\n if (LOOP_TYPES.has(ancestor.type as AST_NODE_TYPES)) {\n enclosingLoop = ancestor as LoopNode;\n break;\n }\n }\n\n if (!enclosingLoop) {\n return;\n }\n\n if (reportedLoops.has(enclosingLoop)) {\n return;\n }\n\n if (hasLoopSuppression(enclosingLoop, context.sourceCode)) {\n return;\n }\n\n const intent = loopIntentCache.get(enclosingLoop) ?? analyzeIntent(enclosingLoop);\n loopIntentCache.set(enclosingLoop, intent);\n\n // Intent-aware behavior:\n // retry/fallback/sequential loops are suppressed (no report).\n if (!intent.isIndependent) {\n return;\n }\n\n const fixText = buildSafeAutofix(enclosingLoop, node, context.sourceCode);\n const loopName = getLoopNodeName(enclosingLoop.type as AST_NODE_TYPES);\n\n context.report({\n node,\n messageId: 'awaitInLoop',\n data: { loopType: loopName },\n fix:\n fixText === null\n ? undefined\n : (fixer) => fixer.replaceText(enclosingLoop as unknown as TSESTree.Node, fixText),\n });\n\n reportedLoops.add(enclosingLoop);\n },\n };\n },\n});\n\nexport default noAwaitInLoop;\n","import { ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';\nimport type { TSESTree, TSESLint } from '@typescript-eslint/utils';\nimport path from 'path';\n\nconst createRule = ESLintUtils.RuleCreator(\n (name) => `https://github.com/YashJadhav21/eslint-plugin-ai-guard/blob/main/docs/rules/${name}.md`\n);\n\n// ─── Framework file patterns ────────────────────────────────────────────────\n// Files where async-without-await is a framework convention, not a mistake.\n// Next.js App Router, middleware, and page conventions.\n\nconst FRAMEWORK_FILE_PATTERNS = [\n // Next.js App Router\n /[/\\\\]route\\.(ts|js|tsx|jsx)$/,\n /[/\\\\]middleware\\.(ts|js)$/,\n /[/\\\\]layout\\.(tsx|jsx|ts|js)$/,\n /[/\\\\]page\\.(tsx|jsx|ts|js)$/,\n /[/\\\\]loading\\.(tsx|jsx|ts|js)$/,\n /[/\\\\]error\\.(tsx|jsx|ts|js)$/,\n /[/\\\\]not-found\\.(tsx|jsx|ts|js)$/,\n /[/\\\\]template\\.(tsx|jsx|ts|js)$/,\n // Next.js Pages Router conventions\n /[/\\\\]_app\\.(tsx|jsx)$/,\n /[/\\\\]_document\\.(tsx|jsx)$/,\n];\n\n// HTTP method export names — always valid async in route files\nconst HTTP_METHOD_EXPORTS = new Set([\n 'GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS',\n]);\n\n// React UI file extensions — handle* functions are conventionally async\nconst REACT_FILE_EXTENSIONS = new Set(['.tsx', '.jsx']);\n\n// Names that strongly suggest the function is an event handler by convention\nconst HANDLER_NAME_REGEX = /^(handle|on[A-Z])/;\n\n// Names that suggest the function is middleware or a lifecycle hook\nconst MIDDLEWARE_NAME_REGEX = /^(use[A-Z]|middleware|interceptor|guard|beforeEach|afterEach)/;\n\n// ─── Heuristics ─────────────────────────────────────────────────────────────\n\nfunction containsAwaitExpression(node: TSESTree.Node): boolean {\n if (node.type === AST_NODE_TYPES.AwaitExpression) {\n return true;\n }\n\n if (node.type === AST_NODE_TYPES.ForOfStatement && node.await) {\n return true;\n }\n\n // Do not count await expressions inside nested functions.\n if (\n node.type === AST_NODE_TYPES.FunctionDeclaration ||\n node.type === AST_NODE_TYPES.FunctionExpression ||\n node.type === AST_NODE_TYPES.ArrowFunctionExpression\n ) {\n return false;\n }\n\n const entries = Object.entries(node) as Array<[string, unknown]>;\n for (const [key, value] of entries) {\n if (key === 'parent') {\n continue;\n }\n\n if (Array.isArray(value)) {\n for (const child of value) {\n if (child && typeof child === 'object' && 'type' in child) {\n if (containsAwaitExpression(child as TSESTree.Node)) {\n return true;\n }\n }\n }\n continue;\n }\n\n if (value && typeof value === 'object' && 'type' in value) {\n if (containsAwaitExpression(value as TSESTree.Node)) {\n return true;\n }\n }\n }\n\n return false;\n}\n\n/**\n * Returns true if the function body is a single return statement that directly\n * calls a function (pass-through wrapper pattern).\n * Example: async function wrap() { return someApi(); }\n * These are intentionally async for Promise propagation — low-confidence finding.\n */\nfunction isPassThroughWrapper(\n node:\n | TSESTree.FunctionDeclaration\n | TSESTree.FunctionExpression\n | TSESTree.ArrowFunctionExpression,\n): boolean {\n if (node.body.type !== AST_NODE_TYPES.BlockStatement) {\n // Arrow with expression body: async () => foo() — pass-through\n const body = node.body;\n if (\n body.type === AST_NODE_TYPES.CallExpression ||\n body.type === AST_NODE_TYPES.MemberExpression\n ) {\n return true;\n }\n return false;\n }\n\n if (node.body.body.length !== 1) return false;\n const only = node.body.body[0];\n if (only.type !== AST_NODE_TYPES.ReturnStatement) return false;\n if (!only.argument) return false;\n\n // Return of a call expression — likely pass-through\n return only.argument.type === AST_NODE_TYPES.CallExpression;\n}\n\n/**\n * Check if this is a framework-required async export.\n * Next.js App Router requires GET/POST/etc handlers to be async even if they\n * use synchronous APIs internally.\n */\nfunction isFunctionExportedWithHttpMethodName(\n node:\n | TSESTree.FunctionDeclaration\n | TSESTree.FunctionExpression\n | TSESTree.ArrowFunctionExpression,\n): boolean {\n // Named function declaration: export async function GET() {}\n if (node.type === AST_NODE_TYPES.FunctionDeclaration && node.id) {\n return HTTP_METHOD_EXPORTS.has(node.id.name);\n }\n\n // Variable declaration: export const GET = async () => {}\n if (node.parent?.type === AST_NODE_TYPES.VariableDeclarator) {\n const declarator = node.parent;\n if (\n declarator.id.type === AST_NODE_TYPES.Identifier &&\n HTTP_METHOD_EXPORTS.has(declarator.id.name)\n ) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Get the function name for heuristic checks.\n */\nfunction getFunctionName(\n node:\n | TSESTree.FunctionDeclaration\n | TSESTree.FunctionExpression\n | TSESTree.ArrowFunctionExpression,\n): string | null {\n if (node.type === AST_NODE_TYPES.FunctionDeclaration && node.id) {\n return node.id.name;\n }\n\n if (node.parent?.type === AST_NODE_TYPES.VariableDeclarator) {\n const declarator = node.parent;\n if (declarator.id.type === AST_NODE_TYPES.Identifier) {\n return declarator.id.name;\n }\n }\n\n if (\n node.parent?.type === AST_NODE_TYPES.Property ||\n node.parent?.type === AST_NODE_TYPES.MethodDefinition\n ) {\n const parent = node.parent;\n if (\n 'key' in parent &&\n parent.key.type === AST_NODE_TYPES.Identifier\n ) {\n return parent.key.name;\n }\n }\n\n return null;\n}\n\n// ─── Schema options ───────────────────────────────────────────────────────────\n\nexport interface RuleOptions {\n allowedFunctionNames?: string[];\n frameworkFiles?: string[];\n ignorePassThroughWrappers?: boolean;\n ignoreHandlerFunctions?: boolean;\n}\n\nexport const noAsyncWithoutAwait = createRule<[RuleOptions], 'asyncWithoutAwait' | 'asyncPassThrough'>({\n name: 'no-async-without-await',\n meta: {\n type: 'suggestion',\n docs: {\n description:\n 'Disallow async functions that never use await. AI tools frequently add async by default, creating misleading signatures and unnecessary Promise wrappers. Framework-specific async conventions (Next.js route handlers, React event handlers) are excluded.',\n },\n fixable: 'code',\n schema: [\n {\n type: 'object',\n properties: {\n allowedFunctionNames: {\n type: 'array',\n items: { type: 'string' },\n description: 'Additional function names to skip (on top of HTTP methods)',\n },\n frameworkFiles: {\n type: 'array',\n items: { type: 'string' },\n description: 'Additional file glob patterns where async-without-await is allowed',\n },\n ignorePassThroughWrappers: {\n type: 'boolean',\n description: 'Downgrade (not suppress) pass-through wrappers. Default: true.',\n },\n ignoreHandlerFunctions: {\n type: 'boolean',\n description: 'Skip functions named handle* or on* in .tsx/.jsx files. Default: true.',\n },\n },\n additionalProperties: false,\n },\n ],\n messages: {\n asyncWithoutAwait:\n 'Async function does not contain `await`. AI tools frequently add `async` unnecessarily, which can mislead callers and mask intent. Remove `async` or add proper await logic.',\n asyncPassThrough:\n 'Async pass-through wrapper — this may be intentional for Promise propagation. Consider whether `async` is needed here.',\n },\n },\n defaultOptions: [{}],\n create(context, [options]) {\n const {\n allowedFunctionNames = [],\n ignorePassThroughWrappers = true,\n ignoreHandlerFunctions = true,\n } = options;\n\n // All HTTP methods + user-provided names are always skipped\n const skipNames = new Set([...HTTP_METHOD_EXPORTS, ...allowedFunctionNames]);\n\n // Check if we're in a framework file (suppress entirely)\n const filename = context.filename ?? context.getFilename?.() ?? '';\n const fileExt = path.extname(filename).toLowerCase();\n\n const isFrameworkFile = FRAMEWORK_FILE_PATTERNS.some((pattern) => pattern.test(filename));\n const isReactFile = REACT_FILE_EXTENSIONS.has(fileExt);\n\n function buildSafeAutofix(\n node:\n | TSESTree.FunctionDeclaration\n | TSESTree.FunctionExpression\n | TSESTree.ArrowFunctionExpression,\n ): ((fixer: TSESLint.RuleFixer) => TSESLint.RuleFix | null) | undefined {\n const sourceCode = context.sourceCode;\n\n if (node.body.type !== AST_NODE_TYPES.BlockStatement) {\n const exprText = sourceCode.getText(node.body);\n return (fixer) => fixer.replaceText(node.body, `await (${exprText})`);\n }\n\n if (node.body.body.length !== 1) {\n return undefined;\n }\n\n const onlyStatement = node.body.body[0];\n\n if (\n onlyStatement.type === AST_NODE_TYPES.ReturnStatement &&\n onlyStatement.argument &&\n onlyStatement.argument.type !== AST_NODE_TYPES.AwaitExpression\n ) {\n const returnValueText = sourceCode.getText(onlyStatement.argument);\n return (fixer) =>\n fixer.replaceText(onlyStatement.argument as TSESTree.Node, `await (${returnValueText})`);\n }\n\n if (onlyStatement.type === AST_NODE_TYPES.ExpressionStatement) {\n const exprText = sourceCode.getText(onlyStatement.expression);\n return (fixer) =>\n fixer.replaceText(onlyStatement.expression as TSESTree.Node, `await (${exprText})`);\n }\n\n return undefined;\n }\n\n function reportIfNeeded(\n node:\n | TSESTree.FunctionDeclaration\n | TSESTree.FunctionExpression\n | TSESTree.ArrowFunctionExpression\n ): void {\n if (!node.async) {\n return;\n }\n\n // 1. Framework file suppression — entirely skip\n if (isFrameworkFile) {\n return;\n }\n\n // 2. HTTP method export suppression — GET/POST/etc are always async by convention\n if (isFunctionExportedWithHttpMethodName(node)) {\n return;\n }\n\n // 3. Function name suppression\n const funcName = getFunctionName(node);\n if (funcName && skipNames.has(funcName)) {\n return;\n }\n\n // 4. Middleware/lifecycle names — often async by convention\n if (funcName && MIDDLEWARE_NAME_REGEX.test(funcName)) {\n return;\n }\n\n // 5. React handler functions in .tsx/.jsx — handle* and on* are async by convention\n if (ignoreHandlerFunctions && isReactFile && funcName && HANDLER_NAME_REGEX.test(funcName)) {\n return;\n }\n\n // Check for await\n const bodyHasAwait =\n node.body.type === AST_NODE_TYPES.BlockStatement\n ? containsAwaitExpression(node.body)\n : node.body.type === AST_NODE_TYPES.AwaitExpression;\n\n if (bodyHasAwait) {\n return;\n }\n\n // 6. Pass-through wrapper — downgrade severity to informational, not a full error\n if (ignorePassThroughWrappers && isPassThroughWrapper(node)) {\n context.report({\n node,\n messageId: 'asyncPassThrough',\n // No autofix for pass-through — it's intentional\n });\n return;\n }\n\n // Arrow with non-block body that is not an AwaitExpression\n if (node.body.type !== AST_NODE_TYPES.BlockStatement) {\n if (node.body.type !== AST_NODE_TYPES.AwaitExpression) {\n const fix = buildSafeAutofix(node);\n context.report({\n node,\n messageId: 'asyncWithoutAwait',\n fix,\n });\n }\n return;\n }\n\n // Block body with no await\n const fix = buildSafeAutofix(node);\n context.report({\n node,\n messageId: 'asyncWithoutAwait',\n fix,\n });\n }\n\n return {\n FunctionDeclaration: reportIfNeeded,\n FunctionExpression: reportIfNeeded,\n ArrowFunctionExpression: reportIfNeeded,\n };\n },\n});\n\nexport default noAsyncWithoutAwait;\n","import { ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';\r\nimport type { TSESTree } from '@typescript-eslint/utils';\r\n\r\nconst createRule = ESLintUtils.RuleCreator(\r\n (name) => `https://github.com/YashJadhav21/eslint-plugin-ai-guard/blob/main/docs/rules/${name}.md`\r\n);\r\n\r\nfunction isInsideTryLikeBlock(\r\n returnNode: TSESTree.ReturnStatement,\r\n context: Readonly<Parameters<ReturnType<typeof createRule>['create']>[0]>\r\n): boolean {\r\n const ancestors = context.sourceCode.getAncestors(returnNode);\r\n\r\n for (let i = ancestors.length - 1; i >= 0; i -= 1) {\r\n const ancestor = ancestors[i];\r\n\r\n if (\r\n ancestor.type === AST_NODE_TYPES.FunctionDeclaration ||\r\n ancestor.type === AST_NODE_TYPES.FunctionExpression ||\r\n ancestor.type === AST_NODE_TYPES.ArrowFunctionExpression\r\n ) {\r\n break;\r\n }\r\n\r\n if (ancestor.type === AST_NODE_TYPES.TryStatement) {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n}\r\n\r\nfunction isInsideAsyncFunction(\r\n returnNode: TSESTree.ReturnStatement,\r\n context: Readonly<Parameters<ReturnType<typeof createRule>['create']>[0]>\r\n): boolean {\r\n const ancestors = context.sourceCode.getAncestors(returnNode);\r\n\r\n for (let i = ancestors.length - 1; i >= 0; i -= 1) {\r\n const ancestor = ancestors[i];\r\n if (\r\n ancestor.type === AST_NODE_TYPES.FunctionDeclaration ||\r\n ancestor.type === AST_NODE_TYPES.FunctionExpression ||\r\n ancestor.type === AST_NODE_TYPES.ArrowFunctionExpression\r\n ) {\r\n return ancestor.async;\r\n }\r\n }\r\n\r\n return false;\r\n}\r\n\r\nexport const noRedundantAwait = createRule({\r\n name: 'no-redundant-await',\r\n meta: {\r\n type: 'suggestion',\r\n docs: {\r\n description:\r\n 'Disallow `return await` in async functions when not inside try/catch/finally. AI tools frequently emit this pattern even when it adds no behavioral value and extra microtask overhead.',\r\n },\r\n fixable: undefined,\r\n schema: [],\r\n messages: {\r\n redundantAwait:\r\n 'Redundant `return await` detected. AI tools frequently generate this pattern. Return the Promise directly unless you need await for try/catch behavior.',\r\n },\r\n },\r\n defaultOptions: [],\r\n create(context) {\r\n return {\r\n ReturnStatement(node) {\r\n if (!node.argument || node.argument.type !== AST_NODE_TYPES.AwaitExpression) {\r\n return;\r\n }\r\n\r\n if (!isInsideAsyncFunction(node, context)) {\r\n return;\r\n }\r\n\r\n if (isInsideTryLikeBlock(node, context)) {\r\n return;\r\n }\r\n\r\n context.report({\r\n node: node.argument,\r\n messageId: 'redundantAwait',\r\n });\r\n },\r\n\r\n ArrowFunctionExpression(node) {\r\n if (!node.async || node.body.type !== AST_NODE_TYPES.AwaitExpression) {\r\n return;\r\n }\r\n\r\n context.report({\r\n node: node.body,\r\n messageId: 'redundantAwait',\r\n });\r\n },\r\n };\r\n },\r\n});\r\n\r\nexport default noRedundantAwait;\r\n","import { ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';\nimport type { TSESTree } from '@typescript-eslint/utils';\n\nconst createRule = ESLintUtils.RuleCreator(\n (name) => `https://github.com/YashJadhav21/eslint-plugin-ai-guard/blob/main/docs/rules/${name}.md`\n);\n\n\n\n/**\n * Variable name patterns that suggest secrets.\n */\nconst SECRET_NAME_PATTERN = /(?:secret|password|passwd|api[_-]?key|auth[_-]?token|access[_-]?token|private[_-]?key|client[_-]?secret|jwt[_-]?secret|encryption[_-]?key|signing[_-]?key)/i;\n\n/**\n * Patterns that are definitely NOT secrets — common false positives.\n */\nconst FALSE_POSITIVE_VALUES = new Set([\n 'password',\n 'secret',\n 'token',\n 'key',\n 'api_key',\n 'apikey',\n '',\n 'undefined',\n 'null',\n 'test',\n 'example',\n 'placeholder',\n 'changeme',\n 'your-api-key',\n 'your-secret',\n 'YOUR_API_KEY',\n 'YOUR_SECRET',\n 'xxx',\n 'TODO',\n]);\n\nexport const noHardcodedSecret = createRule({\n name: 'no-hardcoded-secret',\n meta: {\n type: 'problem',\n docs: {\n description:\n 'Disallow hardcoded secrets, API keys, passwords, and tokens in source code. AI tools frequently generate placeholder credentials that get committed to version control, creating security vulnerabilities. Includes a safe autofix that replaces literals with process.env lookups.',\n },\n fixable: 'code',\n schema: [],\n messages: {\n hardcodedSecret:\n 'Possible hardcoded secret in variable `{{name}}`. AI tools frequently generate placeholder credentials that get committed to version control. Use environment variables (e.g., `process.env.{{envName}}`) instead.',\n },\n },\n defaultOptions: [],\n create(context) {\n return {\n VariableDeclarator(node) {\n // Only check: const SECRET = 'literal_value'\n if (!node.init) return;\n if (!node.id || node.id.type !== AST_NODE_TYPES.Identifier) return;\n\n const initNode = node.init;\n\n const varName = node.id.name;\n\n // Check if variable name suggests a secret\n if (!SECRET_NAME_PATTERN.test(varName)) return;\n\n // Only flag string literals and template literals with no expressions\n const value = getStringValue(initNode);\n if (value === null) return;\n\n // Skip obviously fake/placeholder values\n if (FALSE_POSITIVE_VALUES.has(value)) return;\n if (value.length < 8) return;\n\n // Skip process.env references (already using env vars)\n if (isProcessEnvAccess(initNode)) return;\n\n context.report({\n node: initNode,\n messageId: 'hardcodedSecret',\n data: {\n name: varName,\n envName: toEnvVarName(varName),\n },\n fix: (fixer) =>\n fixer.replaceText(\n initNode,\n getProcessEnvAccessText(toEnvVarName(varName))\n ),\n });\n },\n\n // Also check: obj.secret = 'literal_value'\n AssignmentExpression(node) {\n if (node.left.type !== AST_NODE_TYPES.MemberExpression) return;\n if (node.left.property.type !== AST_NODE_TYPES.Identifier) return;\n\n const propName = node.left.property.name;\n if (!SECRET_NAME_PATTERN.test(propName)) return;\n\n const value = getStringValue(node.right);\n if (value === null) return;\n if (FALSE_POSITIVE_VALUES.has(value)) return;\n if (value.length < 8) return;\n if (isProcessEnvAccess(node.right)) return;\n\n context.report({\n node: node.right,\n messageId: 'hardcodedSecret',\n data: {\n name: propName,\n envName: toEnvVarName(propName),\n },\n fix: (fixer) =>\n fixer.replaceText(\n node.right,\n getProcessEnvAccessText(toEnvVarName(propName))\n ),\n });\n },\n\n // Check property assignments in object literals: { secret: 'value' }\n Property(node) {\n if (node.key.type !== AST_NODE_TYPES.Identifier) return;\n if (isRuleMetaMessagesProperty(node)) return;\n\n const propName = node.key.name;\n if (!SECRET_NAME_PATTERN.test(propName)) return;\n\n const valueNode = node.value as TSESTree.Expression;\n const value = getStringValue(valueNode);\n if (value === null) return;\n if (FALSE_POSITIVE_VALUES.has(value)) return;\n if (value.length < 8) return;\n if (isProcessEnvAccess(valueNode)) return;\n\n context.report({\n node: valueNode,\n messageId: 'hardcodedSecret',\n data: {\n name: propName,\n envName: toEnvVarName(propName),\n },\n fix: (fixer) =>\n fixer.replaceText(\n valueNode,\n getProcessEnvAccessText(toEnvVarName(propName))\n ),\n });\n },\n };\n },\n});\n\nfunction getStringValue(node: TSESTree.Expression): string | null {\n if (node.type === AST_NODE_TYPES.Literal && typeof node.value === 'string') {\n return node.value;\n }\n if (\n node.type === AST_NODE_TYPES.TemplateLiteral &&\n node.expressions.length === 0 &&\n node.quasis.length === 1\n ) {\n return node.quasis[0].value.cooked ?? null;\n }\n return null;\n}\n\nfunction isRuleMetaMessagesProperty(node: TSESTree.Property): boolean {\n if (!node.parent || node.parent.type !== AST_NODE_TYPES.ObjectExpression) {\n return false;\n }\n\n const parentProperty = node.parent.parent;\n if (!parentProperty || parentProperty.type !== AST_NODE_TYPES.Property) {\n return false;\n }\n\n return (\n parentProperty.key.type === AST_NODE_TYPES.Identifier &&\n parentProperty.key.name === 'messages'\n );\n}\n\nfunction isProcessEnvAccess(node: TSESTree.Expression): boolean {\n return (\n node.type === AST_NODE_TYPES.MemberExpression &&\n node.object.type === AST_NODE_TYPES.MemberExpression &&\n node.object.object.type === AST_NODE_TYPES.Identifier &&\n node.object.object.name === 'process' &&\n node.object.property.type === AST_NODE_TYPES.Identifier &&\n node.object.property.name === 'env'\n );\n}\n\nfunction toEnvVarName(name: string): string {\n // Convert camelCase/PascalCase to UPPER_SNAKE_CASE\n return name\n .replace(/([a-z])([A-Z])/g, '$1_$2')\n .replace(/[-\\s]/g, '_')\n .toUpperCase();\n}\n\nfunction getProcessEnvAccessText(envName: string): string {\n if (/^[A-Z_$][A-Z0-9_$]*$/.test(envName)) {\n return `process.env.${envName}`;\n }\n\n return `process.env['${envName.replace(/'/g, \"\\\\'\")}']`;\n}\n\nexport default noHardcodedSecret;\n","import { ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';\r\nimport type { TSESTree } from '@typescript-eslint/utils';\r\n\r\nconst createRule = ESLintUtils.RuleCreator(\r\n (name) => `https://github.com/YashJadhav21/eslint-plugin-ai-guard/blob/main/docs/rules/${name}.md`\r\n);\r\n\r\nexport const noEvalDynamic = createRule({\r\n name: 'no-eval-dynamic',\r\n meta: {\r\n type: 'problem',\r\n docs: {\r\n description:\r\n 'Disallow `eval()` and `new Function()` with non-literal arguments. AI tools frequently generate dynamic code evaluation patterns that create serious security vulnerabilities including code injection and XSS.',\r\n },\r\n fixable: undefined,\r\n schema: [],\r\n messages: {\r\n evalDynamic:\r\n 'Dangerous use of `{{callee}}` with a dynamic argument. AI tools frequently generate `eval()` or `new Function()` patterns that enable code injection attacks. Use safer alternatives like JSON.parse(), a lookup table, or a sandboxed evaluator.',\r\n newFunctionDynamic:\r\n 'Dangerous use of `new Function()` with a dynamic argument. AI tools frequently generate this pattern which enables arbitrary code execution. Use safer alternatives like a lookup table or pre-defined functions.',\r\n },\r\n },\r\n defaultOptions: [],\r\n create(context) {\r\n return {\r\n CallExpression(node) {\r\n // Check for eval(...)\r\n if (\r\n node.callee.type === AST_NODE_TYPES.Identifier &&\r\n node.callee.name === 'eval'\r\n ) {\r\n // Allow eval() with no args (no-op) or with only literal string args\r\n if (node.arguments.length === 0) return;\r\n\r\n const firstArg = node.arguments[0];\r\n if (isLiteral(firstArg)) return;\r\n\r\n context.report({\r\n node,\r\n messageId: 'evalDynamic',\r\n data: { callee: 'eval()' },\r\n });\r\n return;\r\n }\r\n\r\n // Check for window.eval(...) or globalThis.eval(...)\r\n if (\r\n node.callee.type === AST_NODE_TYPES.MemberExpression &&\r\n node.callee.property.type === AST_NODE_TYPES.Identifier &&\r\n node.callee.property.name === 'eval' &&\r\n node.callee.object.type === AST_NODE_TYPES.Identifier &&\r\n (node.callee.object.name === 'window' || node.callee.object.name === 'globalThis')\r\n ) {\r\n if (node.arguments.length === 0) return;\r\n const firstArg = node.arguments[0];\r\n if (isLiteral(firstArg)) return;\r\n\r\n context.report({\r\n node,\r\n messageId: 'evalDynamic',\r\n data: { callee: `${node.callee.object.name}.eval()` },\r\n });\r\n return;\r\n }\r\n\r\n // Function(...) invoked WITHOUT `new` is semantically identical to\r\n // new Function(...) per ECMA-262 and MDN — `Function('a','return a')(1)`\r\n // executes the body string as code. AI-generated examples sometimes\r\n // drop the `new` because both forms \"work\"; the rule previously hooked\r\n // only NewExpression, letting bare calls through as a code-injection\r\n // FN. Cover Identifier `Function(...)` plus `window.Function(...)` /\r\n // `globalThis.Function(...)`.\r\n if (isFunctionConstructorCallee(node.callee)) {\r\n if (node.arguments.length === 0) return;\r\n const allLiteral = node.arguments.every(isLiteral);\r\n if (allLiteral) return;\r\n\r\n context.report({\r\n node,\r\n messageId: 'newFunctionDynamic',\r\n });\r\n }\r\n },\r\n\r\n NewExpression(node) {\r\n // Check for new Function(...) / new window.Function(...) / new globalThis.Function(...)\r\n if (isFunctionConstructorCallee(node.callee)) {\r\n if (node.arguments.length === 0) return;\r\n\r\n // All arguments must be literals to be safe\r\n const allLiteral = node.arguments.every(isLiteral);\r\n if (allLiteral) return;\r\n\r\n context.report({\r\n node,\r\n messageId: 'newFunctionDynamic',\r\n });\r\n }\r\n },\r\n };\r\n },\r\n});\r\n\r\n/**\r\n * Match the `Function` constructor callee in any of its reachable forms:\r\n * - bare identifier `Function`\r\n * - `window.Function`\r\n * - `globalThis.Function`\r\n * Used for both `new Function(...)` and bare `Function(...)` calls, which are\r\n * semantically identical for the code-injection risk the rule targets.\r\n */\r\nfunction isFunctionConstructorCallee(callee: TSESTree.Node): boolean {\r\n if (callee.type === AST_NODE_TYPES.Identifier && callee.name === 'Function') {\r\n return true;\r\n }\r\n if (\r\n callee.type === AST_NODE_TYPES.MemberExpression &&\r\n callee.property.type === AST_NODE_TYPES.Identifier &&\r\n callee.property.name === 'Function' &&\r\n callee.object.type === AST_NODE_TYPES.Identifier &&\r\n (callee.object.name === 'window' || callee.object.name === 'globalThis')\r\n ) {\r\n return true;\r\n }\r\n return false;\r\n}\r\n\r\n/**\r\n * Check if a node is a static literal (string, number, boolean, null, template literal with no expressions).\r\n */\r\nfunction isLiteral(node: TSESTree.Node): boolean {\r\n if (node.type === AST_NODE_TYPES.Literal) return true;\r\n if (\r\n node.type === AST_NODE_TYPES.TemplateLiteral &&\r\n node.expressions.length === 0\r\n ) {\r\n return true;\r\n }\r\n return false;\r\n}\r\n\r\nexport default noEvalDynamic;\r\n","import { ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';\nimport type { TSESTree } from '@typescript-eslint/utils';\n\nconst createRule = ESLintUtils.RuleCreator(\n (name) => `https://github.com/YashJadhav21/eslint-plugin-ai-guard/blob/main/docs/rules/${name}.md`\n);\n\n/**\n * SQL statement signatures. We intentionally require query-like combinations\n * to avoid false positives for normal app strings (e.g., \"create\", \"from\").\n */\nconst SQL_STATEMENT_PATTERN =\n /\\b(select\\s+[\\s\\S]*\\s+from|insert\\s+into|update\\s+\\S+\\s+set|delete\\s+from|drop\\s+table|create\\s+(table|database)|alter\\s+table|truncate\\s+table|exec(?:ute)?\\s+\\S+|union\\s+select)\\b/i;\n\nconst SQL_SINK_METHODS = new Set([\n 'query',\n 'execute',\n 'queryraw',\n 'queryrawunsafe',\n 'executeraw',\n 'executerawunsafe',\n 'raw',\n 'run',\n 'all',\n 'get',\n 'prepare',\n]);\n\nconst SQL_SINK_FUNCTIONS = new Set(['query', 'execute']);\n\nconst KNOWN_QUERY_BUILDERS = new Set([\n 'knex',\n 'drizzle',\n 'prisma',\n 'kysely',\n 'sequelize',\n 'typeorm',\n 'mikroorm',\n]);\n\nconst QUERY_BUILDER_METHOD_HINTS = new Set([\n 'raw',\n 'query',\n 'execute',\n 'from',\n 'where',\n 'whereraw',\n 'queryraw',\n 'queryrawunsafe',\n 'executeraw',\n 'executerawunsafe',\n 'select',\n 'selectfrom',\n 'insert',\n 'update',\n 'delete',\n 'join',\n 'orderby',\n 'groupby',\n 'having',\n]);\n\nfunction getIdentifierName(node: TSESTree.Node): string | null {\n if (node.type === AST_NODE_TYPES.Identifier) {\n return node.name;\n }\n return null;\n}\n\nfunction isSqlSinkCall(node: TSESTree.CallExpression): boolean {\n if (node.callee.type === AST_NODE_TYPES.Identifier) {\n return SQL_SINK_FUNCTIONS.has(node.callee.name.toLowerCase());\n }\n\n if (\n node.callee.type === AST_NODE_TYPES.MemberExpression &&\n node.callee.property.type === AST_NODE_TYPES.Identifier\n ) {\n const methodName = node.callee.property.name.toLowerCase().replace(/^\\$/, '');\n return SQL_SINK_METHODS.has(methodName);\n }\n\n return false;\n}\n\nfunction normalizeToken(value: string): string {\n return value.toLowerCase().replace(/[^a-z0-9]/g, '');\n}\n\nfunction getMemberPropertyName(\n property: TSESTree.Expression | TSESTree.PrivateIdentifier,\n computed: boolean,\n): string | null {\n if (!computed && property.type === AST_NODE_TYPES.Identifier) {\n return property.name;\n }\n\n if (computed && property.type === AST_NODE_TYPES.Literal && typeof property.value === 'string') {\n return property.value;\n }\n\n return null;\n}\n\nfunction getExpressionPathParts(node: TSESTree.Node): string[] {\n if (node.type === AST_NODE_TYPES.Identifier) {\n return [node.name];\n }\n\n if (node.type === AST_NODE_TYPES.ThisExpression) {\n return ['this'];\n }\n\n if (node.type === AST_NODE_TYPES.CallExpression) {\n return getExpressionPathParts(node.callee);\n }\n\n if (node.type === AST_NODE_TYPES.MemberExpression) {\n const objectParts = getExpressionPathParts(node.object);\n const propertyName = getMemberPropertyName(node.property, node.computed);\n return propertyName ? [...objectParts, propertyName] : objectParts;\n }\n\n if (\n node.type === AST_NODE_TYPES.NewExpression &&\n (node.callee.type === AST_NODE_TYPES.Identifier ||\n node.callee.type === AST_NODE_TYPES.MemberExpression)\n ) {\n return getExpressionPathParts(node.callee);\n }\n\n return [];\n}\n\nfunction isKnownBuilderName(name: string): boolean {\n return KNOWN_QUERY_BUILDERS.has(normalizeToken(name));\n}\n\nfunction isBuilderMethodHint(name: string): boolean {\n return QUERY_BUILDER_METHOD_HINTS.has(normalizeToken(name));\n}\n\nfunction isKnownBuilderBinding(name: string, builderBindings: Set<string>): boolean {\n if (builderBindings.has(name)) {\n return true;\n }\n\n return builderBindings.has(normalizeToken(name));\n}\n\nfunction isKnownBuilderExpression(\n node: TSESTree.Expression,\n builderBindings: Set<string>,\n): boolean {\n if (node.type === AST_NODE_TYPES.Identifier) {\n return isKnownBuilderName(node.name) || isKnownBuilderBinding(node.name, builderBindings);\n }\n\n if (node.type === AST_NODE_TYPES.CallExpression || node.type === AST_NODE_TYPES.NewExpression) {\n const pathParts =\n node.type === AST_NODE_TYPES.CallExpression\n ? getExpressionPathParts(node.callee)\n : getExpressionPathParts(node.callee);\n\n return pathParts.some(\n (part) => isKnownBuilderName(part) || isKnownBuilderBinding(part, builderBindings),\n );\n }\n\n if (node.type === AST_NODE_TYPES.MemberExpression) {\n const pathParts = getExpressionPathParts(node);\n return pathParts.some(\n (part) => isKnownBuilderName(part) || isKnownBuilderBinding(part, builderBindings),\n );\n }\n\n return false;\n}\n\nfunction isKnownQueryBuilderContext(\n node: TSESTree.CallExpression,\n builderBindings: Set<string>,\n): boolean {\n const pathParts = getExpressionPathParts(node.callee);\n if (pathParts.length === 0) {\n return false;\n }\n\n const hasBuilderIdentity = pathParts.some(\n (part) => isKnownBuilderName(part) || isKnownBuilderBinding(part, builderBindings),\n );\n\n if (!hasBuilderIdentity) {\n const rootPart = pathParts[0];\n if (!rootPart || !isKnownBuilderBinding(rootPart, builderBindings)) {\n return false;\n }\n }\n\n return pathParts.some((part) => isBuilderMethodHint(part));\n}\n\nfunction resolveExpression(\n node: TSESTree.Expression,\n variableMap: Map<string, TSESTree.Expression>,\n): TSESTree.Expression {\n const identifier = getIdentifierName(node);\n if (identifier && variableMap.has(identifier)) {\n return variableMap.get(identifier)!;\n }\n return node;\n}\n\nfunction isDynamicSqlExpression(node: TSESTree.Expression): boolean {\n if (node.type === AST_NODE_TYPES.TemplateLiteral) {\n if (node.expressions.length === 0) {\n return false;\n }\n const staticText = node.quasis.map((q) => q.value.raw).join(' ');\n return SQL_STATEMENT_PATTERN.test(staticText);\n }\n\n if (node.type === AST_NODE_TYPES.BinaryExpression && node.operator === '+') {\n const staticText = collectStaticText(node);\n if (!SQL_STATEMENT_PATTERN.test(staticText)) {\n return false;\n }\n return hasDynamicParts(node);\n }\n\n return false;\n}\n\nexport const noSqlStringConcat = createRule({\n name: 'no-sql-string-concat',\n meta: {\n type: 'problem',\n docs: {\n description:\n 'Disallow string concatenation or interpolation with variables in SQL query contexts. AI tools frequently generate SQL queries using template literals or string concatenation with user input, creating SQL injection vulnerabilities.',\n },\n fixable: undefined,\n schema: [],\n messages: {\n sqlStringConcat:\n 'Potential SQL injection: string concatenation or interpolation detected in a SQL query. AI tools frequently generate this pattern. Use parameterized queries (e.g., `db.query(\"SELECT * FROM users WHERE id = $1\", [id])`) instead.',\n },\n },\n defaultOptions: [],\n create(context) {\n const variableMap = new Map<string, TSESTree.Expression>();\n const builderBindings = new Set<string>();\n\n return {\n VariableDeclarator(node) {\n if (node.id.type !== AST_NODE_TYPES.Identifier || !node.init) {\n return;\n }\n\n if (node.init.type === AST_NODE_TYPES.AwaitExpression) {\n builderBindings.delete(node.id.name);\n builderBindings.delete(normalizeToken(node.id.name));\n return;\n }\n\n variableMap.set(node.id.name, node.init);\n\n if (isKnownBuilderExpression(node.init, builderBindings)) {\n builderBindings.add(node.id.name);\n builderBindings.add(normalizeToken(node.id.name));\n return;\n }\n\n builderBindings.delete(node.id.name);\n builderBindings.delete(normalizeToken(node.id.name));\n },\n\n AssignmentExpression(node) {\n if (node.left.type !== AST_NODE_TYPES.Identifier) {\n return;\n }\n\n if (node.right.type === AST_NODE_TYPES.AwaitExpression) {\n builderBindings.delete(node.left.name);\n builderBindings.delete(normalizeToken(node.left.name));\n return;\n }\n\n variableMap.set(node.left.name, node.right);\n\n if (isKnownBuilderExpression(node.right, builderBindings)) {\n builderBindings.add(node.left.name);\n builderBindings.add(normalizeToken(node.left.name));\n return;\n }\n\n builderBindings.delete(node.left.name);\n builderBindings.delete(normalizeToken(node.left.name));\n },\n\n CallExpression(node) {\n if (!isSqlSinkCall(node)) {\n return;\n }\n\n // Avoid false positives for known query-builder chains.\n if (isKnownQueryBuilderContext(node, builderBindings)) {\n return;\n }\n\n const firstArg = node.arguments[0];\n if (!firstArg || firstArg.type === AST_NODE_TYPES.SpreadElement) {\n return;\n }\n\n const resolved = resolveExpression(firstArg, variableMap);\n if (!isDynamicSqlExpression(resolved)) {\n return;\n }\n\n context.report({\n node: firstArg,\n messageId: 'sqlStringConcat',\n });\n },\n };\n },\n});\n\nfunction collectStaticText(node: TSESTree.Expression | TSESTree.PrivateIdentifier): string {\n if (node.type === AST_NODE_TYPES.BinaryExpression && node.operator === '+') {\n return `${collectStaticText(node.left)} ${collectStaticText(node.right)}`;\n }\n\n const literalValue = getStringLiteralValue(node);\n return literalValue ?? '';\n}\n\nfunction hasDynamicParts(node: TSESTree.Expression | TSESTree.PrivateIdentifier): boolean {\n if (node.type === AST_NODE_TYPES.BinaryExpression && node.operator === '+') {\n return hasDynamicParts(node.left) || hasDynamicParts(node.right);\n }\n\n return !isStaticString(node);\n}\n\nfunction getStringLiteralValue(node: TSESTree.Expression | TSESTree.PrivateIdentifier): string | null {\n if (node.type === AST_NODE_TYPES.Literal && typeof node.value === 'string') {\n return node.value;\n }\n return null;\n}\n\nfunction isStaticString(node: TSESTree.Expression | TSESTree.PrivateIdentifier): boolean {\n if (node.type === AST_NODE_TYPES.Literal && typeof node.value === 'string') {\n return true;\n }\n if (\n node.type === AST_NODE_TYPES.TemplateLiteral &&\n node.expressions.length === 0\n ) {\n return true;\n }\n return false;\n}\n\nexport default noSqlStringConcat;\n","import { ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';\r\nimport type { TSESTree } from '@typescript-eslint/utils';\r\n\r\nconst createRule = ESLintUtils.RuleCreator(\r\n (name) => `https://github.com/YashJadhav21/eslint-plugin-ai-guard/blob/main/docs/rules/${name}.md`\r\n);\r\n\r\nconst UNTRUSTED_IDENTIFIER_NAMES = [\r\n 'input',\r\n 'userInput',\r\n 'rawBody',\r\n 'payload',\r\n 'body',\r\n 'query',\r\n 'param',\r\n 'params',\r\n 'data',\r\n 'requestBody',\r\n] as const;\r\n\r\nfunction isJsonParseCall(node: TSESTree.CallExpression): boolean {\r\n return (\r\n node.callee.type === AST_NODE_TYPES.MemberExpression &&\r\n node.callee.object.type === AST_NODE_TYPES.Identifier &&\r\n node.callee.object.name === 'JSON' &&\r\n node.callee.property.type === AST_NODE_TYPES.Identifier &&\r\n node.callee.property.name === 'parse'\r\n );\r\n}\r\n\r\nfunction isLikelyUntrustedSource(node: TSESTree.Node): boolean {\r\n if (node.type === AST_NODE_TYPES.Identifier) {\r\n return UNTRUSTED_IDENTIFIER_NAMES.includes(\r\n node.name as (typeof UNTRUSTED_IDENTIFIER_NAMES)[number]\r\n );\r\n }\r\n\r\n if (node.type === AST_NODE_TYPES.MemberExpression) {\r\n // req.body, req.query, req.params, request.body\r\n if (\r\n node.object.type === AST_NODE_TYPES.Identifier &&\r\n ['req', 'request'].includes(node.object.name) &&\r\n node.property.type === AST_NODE_TYPES.Identifier &&\r\n ['body', 'query', 'params'].includes(node.property.name)\r\n ) {\r\n return true;\r\n }\r\n\r\n // window.location.hash/search\r\n if (\r\n node.object.type === AST_NODE_TYPES.MemberExpression &&\r\n node.object.object.type === AST_NODE_TYPES.Identifier &&\r\n node.object.object.name === 'window' &&\r\n node.object.property.type === AST_NODE_TYPES.Identifier &&\r\n node.object.property.name === 'location' &&\r\n node.property.type === AST_NODE_TYPES.Identifier &&\r\n ['hash', 'search'].includes(node.property.name)\r\n ) {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n}\r\n\r\nexport const noUnsafeDeserialize = createRule({\r\n name: 'no-unsafe-deserialize',\r\n meta: {\r\n type: 'suggestion',\r\n docs: {\r\n description:\r\n 'Disallow JSON.parse() on likely untrusted input without visible validation. AI tools frequently parse request/user payloads directly, which can introduce unsafe deserialization and downstream injection risks.',\r\n },\r\n fixable: undefined,\r\n schema: [],\r\n messages: {\r\n unsafeDeserialize:\r\n 'Potential unsafe deserialization: JSON.parse() is used on likely untrusted input without visible schema validation. AI tools frequently generate this shortcut. Validate input before parsing.',\r\n },\r\n },\r\n defaultOptions: [],\r\n create(context) {\r\n return {\r\n CallExpression(node) {\r\n if (!isJsonParseCall(node)) {\r\n return;\r\n }\r\n\r\n const inputArg = node.arguments[0];\r\n if (!inputArg) {\r\n return;\r\n }\r\n\r\n if (isLikelyUntrustedSource(inputArg)) {\r\n context.report({\r\n node,\r\n messageId: 'unsafeDeserialize',\r\n });\r\n }\r\n },\r\n };\r\n },\r\n});\r\n\r\nexport default noUnsafeDeserialize;\r\n","import { ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';\nimport type { TSESTree } from '@typescript-eslint/utils';\n\nconst createRule = ESLintUtils.RuleCreator(\n (name) => `https://github.com/YashJadhav21/eslint-plugin-ai-guard/blob/main/docs/rules/${name}.md`\n);\n\n/**\n * HTTP methods that define routes in Express/Fastify.\n */\nconst HTTP_METHODS = new Set([\n 'get', 'post', 'put', 'patch', 'delete', 'all', 'options', 'head',\n]);\n\n/**\n * Default authentication middleware names to look for.\n */\nconst DEFAULT_AUTH_MIDDLEWARE_NAMES = new Set([\n 'authenticate',\n 'requireAuth',\n 'isAuthenticated',\n 'verifyToken',\n 'protect',\n 'authorized',\n 'authorize',\n 'isAdmin',\n 'ensureAuthenticated',\n 'ensureLoggedIn',\n 'auth',\n 'authMiddleware',\n 'requireLogin',\n 'checkAuth',\n 'validateToken',\n 'passport.authenticate',\n 'jwt',\n 'requireSession',\n]);\n\n/**\n * Route paths that are commonly public and should not require auth.\n */\nconst PUBLIC_ROUTE_PATTERNS = [\n /^\\/?$/, // '/' root\n /^\\*$/, // '*' SPA fallback\n /^\\/\\*$/, // '/*' SPA fallback\n /^\\/health/, // health checks\n /^\\/ping/, // ping\n /^\\/status/, // status\n /^\\/api\\/v\\d+\\/auth/, // auth routes\n /^\\/auth/, // auth routes\n /^\\/login/, // login\n /^\\/register/, // register\n /^\\/signup/, // signup\n /^\\/forgot/, // forgot password\n /^\\/reset/, // reset password\n /^\\/webhook/, // webhooks\n /^\\/callback/, // OAuth callback\n /^\\/public/, // explicitly public\n /^\\/assets/, // static assets\n /^\\/static/, // static files\n /^\\/favicon/, // favicon\n /^\\/robots/, // robots.txt\n /^\\/sitemap/, // sitemap\n /^\\/api\\/docs/, // API documentation (Swagger, etc.)\n /^\\/docs/, // documentation\n];\n\nexport const requireAuthMiddleware = createRule({\n name: 'require-auth-middleware',\n meta: {\n type: 'suggestion',\n docs: {\n description:\n 'Require authentication middleware on Express/Fastify route definitions. AI tools frequently generate route handlers without auth middleware, creating unprotected endpoints that expose sensitive data or operations.',\n },\n fixable: undefined,\n schema: [\n {\n type: 'object',\n properties: {\n authMiddlewareNames: {\n type: 'array',\n items: { type: 'string' },\n description: 'Additional custom middleware names to recognize as authentication middleware.',\n },\n },\n additionalProperties: false,\n },\n ],\n messages: {\n missingAuth:\n 'Route `{{method}} {{path}}` appears to have no authentication middleware. AI tools frequently generate routes without auth checks, creating unprotected endpoints. Add authentication middleware (e.g., `protect`, `authenticate`) to the handler chain.',\n },\n },\n defaultOptions: [{}] as [{ authMiddlewareNames?: string[] }],\n create(context, [options]) {\n const customNames = new Set(options.authMiddlewareNames ?? []);\n const allAuthNames = new Set([...DEFAULT_AUTH_MIDDLEWARE_NAMES, ...customNames]);\n\n // Track if router.use(protect) is applied (route-level auth covers all subsequent routes)\n let hasRouterUseAuth = false;\n\n return {\n CallExpression(node) {\n // Detect router.use(protect) or app.use(protect) — blanket auth\n if (isRouterUseAuth(node, allAuthNames)) {\n hasRouterUseAuth = true;\n return;\n }\n\n // Check for: router.get('/path', handler) or app.post('/path', handler)\n if (!isRouteDefinition(node)) return;\n\n // If a blanket router.use(auth) was already applied, skip\n if (hasRouterUseAuth) return;\n\n const callee = node.callee as TSESTree.MemberExpression;\n const method = (callee.property as TSESTree.Identifier).name;\n const args = node.arguments;\n\n // First argument should be the route path\n if (args.length < 2) return;\n const pathArg = args[0];\n const pathStr = getPathString(pathArg);\n\n // Skip public routes\n if (pathStr && isPublicRoute(pathStr)) return;\n\n // Check if any argument (between path and final handler) is an auth middleware\n const middlewareArgs = args.slice(1, -1); // Exclude path and final handler\n\n // If only path + handler (no middleware at all)\n if (middlewareArgs.length === 0 && args.length === 2) {\n context.report({\n node,\n messageId: 'missingAuth',\n data: {\n method: method.toUpperCase(),\n path: pathStr || '<dynamic>',\n },\n });\n return;\n }\n\n // Check if any middleware in the chain is an auth middleware\n const hasAuth = middlewareArgs.some((arg) => isAuthMiddleware(arg, allAuthNames));\n\n if (!hasAuth) {\n context.report({\n node,\n messageId: 'missingAuth',\n data: {\n method: method.toUpperCase(),\n path: pathStr || '<dynamic>',\n },\n });\n }\n },\n };\n },\n});\n\nfunction isRouteDefinition(node: TSESTree.CallExpression): boolean {\n if (node.callee.type !== AST_NODE_TYPES.MemberExpression) return false;\n if (node.callee.property.type !== AST_NODE_TYPES.Identifier) return false;\n\n const methodName = node.callee.property.name;\n if (!HTTP_METHODS.has(methodName)) return false;\n\n // The object should be a router/app-like identifier\n const obj = node.callee.object;\n if (obj.type === AST_NODE_TYPES.Identifier) {\n const name = obj.name.toLowerCase();\n return name === 'router' || name === 'app' || name.includes('router');\n }\n // Also handle: express.Router() chains\n if (obj.type === AST_NODE_TYPES.CallExpression) return true;\n\n return false;\n}\n\nfunction isRouterUseAuth(node: TSESTree.CallExpression, authNames: Set<string>): boolean {\n if (node.callee.type !== AST_NODE_TYPES.MemberExpression) return false;\n if (node.callee.property.type !== AST_NODE_TYPES.Identifier) return false;\n if (node.callee.property.name !== 'use') return false;\n\n // Check if any argument is an auth middleware\n return node.arguments.some((arg) => isAuthMiddleware(arg, authNames));\n}\n\nfunction isAuthMiddleware(node: TSESTree.Node, authNames: Set<string>): boolean {\n // Direct identifier: protect, authenticate, etc.\n if (node.type === AST_NODE_TYPES.Identifier) {\n return authNames.has(node.name);\n }\n\n // Fastify-style options object: { preHandler: authenticate, onRequest: verifyToken }\n if (node.type === AST_NODE_TYPES.ObjectExpression) {\n for (const prop of node.properties) {\n if (\n prop.type === AST_NODE_TYPES.Property &&\n prop.key.type === AST_NODE_TYPES.Identifier &&\n (prop.key.name === 'preHandler' || prop.key.name === 'onRequest')\n ) {\n if (isAuthMiddleware(prop.value, authNames)) return true;\n }\n }\n }\n\n // Call expression: authenticate('jwt'), authorize('admin')\n if (node.type === AST_NODE_TYPES.CallExpression) {\n if (node.callee.type === AST_NODE_TYPES.Identifier) {\n return authNames.has(node.callee.name);\n }\n // passport.authenticate(...)\n if (\n node.callee.type === AST_NODE_TYPES.MemberExpression &&\n node.callee.object.type === AST_NODE_TYPES.Identifier &&\n node.callee.property.type === AST_NODE_TYPES.Identifier\n ) {\n const fullName = `${node.callee.object.name}.${node.callee.property.name}`;\n return authNames.has(fullName) || authNames.has(node.callee.property.name);\n }\n }\n\n return false;\n}\n\nfunction getPathString(node: TSESTree.Node): string | null {\n if (node.type === AST_NODE_TYPES.Literal && typeof node.value === 'string') {\n return node.value;\n }\n if (node.type === AST_NODE_TYPES.TemplateLiteral) {\n // If it has no expressions, just return the only quasi\n if (node.expressions.length === 0 && node.quasis.length === 1) {\n return node.quasis[0].value.cooked ?? null;\n }\n // If it has expressions (e.g., `/webhook/${dynamic}`), return the first literal part\n if (node.quasis.length > 0) {\n return node.quasis[0].value.cooked ?? null;\n }\n }\n return null;\n}\n\nfunction isPublicRoute(pathStr: string): boolean {\n return PUBLIC_ROUTE_PATTERNS.some((pattern) => pattern.test(pathStr));\n}\n\nexport default requireAuthMiddleware;\n","import { ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';\r\nimport type { TSESTree } from '@typescript-eslint/utils';\r\n\r\nconst createRule = ESLintUtils.RuleCreator(\r\n (name) => `https://github.com/YashJadhav21/eslint-plugin-ai-guard/blob/main/docs/rules/${name}.md`\r\n);\r\n\r\nconst ROUTE_METHODS = ['get', 'post', 'put', 'patch', 'delete'] as const;\r\nconst AUTHZ_HELPER_NAMES = [\r\n 'authorize',\r\n 'authorise',\r\n 'checkOwnership',\r\n 'ensureOwner',\r\n 'isOwner',\r\n 'canAccess',\r\n 'canModify',\r\n 'hasAccess',\r\n] as const;\r\n\r\nfunction isRouteRegistrationCall(node: TSESTree.CallExpression): boolean {\r\n if (\r\n node.callee.type !== AST_NODE_TYPES.MemberExpression ||\r\n node.callee.property.type !== AST_NODE_TYPES.Identifier\r\n ) {\r\n return false;\r\n }\r\n\r\n if (!ROUTE_METHODS.includes(node.callee.property.name as (typeof ROUTE_METHODS)[number])) {\r\n return false;\r\n }\r\n\r\n const firstArg = node.arguments[0];\r\n if (!firstArg) {\r\n return false;\r\n }\r\n\r\n return (\r\n (firstArg.type === AST_NODE_TYPES.Literal && typeof firstArg.value === 'string') ||\r\n (firstArg.type === AST_NODE_TYPES.TemplateLiteral && firstArg.expressions.length === 0)\r\n );\r\n}\r\n\r\nfunction getStaticPathArg(node: TSESTree.CallExpression): string | null {\r\n const firstArg = node.arguments[0];\r\n if (!firstArg) return null;\r\n\r\n if (firstArg.type === AST_NODE_TYPES.Literal && typeof firstArg.value === 'string') {\r\n return firstArg.value;\r\n }\r\n\r\n if (firstArg.type === AST_NODE_TYPES.TemplateLiteral && firstArg.expressions.length === 0) {\r\n return firstArg.quasis[0]?.value.cooked ?? null;\r\n }\r\n\r\n return null;\r\n}\r\n\r\nfunction getMemberPath(node: TSESTree.Node): string[] | null {\r\n if (node.type === AST_NODE_TYPES.Identifier) {\r\n return [node.name];\r\n }\r\n\r\n if (node.type !== AST_NODE_TYPES.MemberExpression || node.computed) {\r\n return null;\r\n }\r\n\r\n const objectPath = getMemberPath(node.object);\r\n if (!objectPath) {\r\n return null;\r\n }\r\n\r\n if (node.property.type !== AST_NODE_TYPES.Identifier) {\r\n return null;\r\n }\r\n\r\n return [...objectPath, node.property.name];\r\n}\r\n\r\nfunction hasPathPrefix(path: string[] | null, prefix: readonly string[]): boolean {\r\n if (!path || path.length < prefix.length) {\r\n return false;\r\n }\r\n\r\n for (let i = 0; i < prefix.length; i += 1) {\r\n if (path[i] !== prefix[i]) {\r\n return false;\r\n }\r\n }\r\n\r\n return true;\r\n}\r\n\r\nfunction isLikelyResourceIdPath(path: string[] | null): boolean {\r\n if (!path || path.length < 3) {\r\n return false;\r\n }\r\n\r\n if (!hasPathPrefix(path, ['req', 'params']) && !hasPathPrefix(path, ['req', 'body']) && !hasPathPrefix(path, ['req', 'query'])) {\r\n return false;\r\n }\r\n\r\n const last = path[path.length - 1].toLowerCase();\r\n return last === 'id' || last.endsWith('id');\r\n}\r\n\r\nfunction isReqUserPath(path: string[] | null): boolean {\r\n return hasPathPrefix(path, ['req', 'user']);\r\n}\r\n\r\nfunction containsAuthorizationHelper(node: TSESTree.Node): boolean {\r\n if (\r\n node.type === AST_NODE_TYPES.CallExpression &&\r\n ((node.callee.type === AST_NODE_TYPES.Identifier &&\r\n AUTHZ_HELPER_NAMES.includes(node.callee.name as (typeof AUTHZ_HELPER_NAMES)[number])) ||\r\n (node.callee.type === AST_NODE_TYPES.MemberExpression &&\r\n node.callee.property.type === AST_NODE_TYPES.Identifier &&\r\n AUTHZ_HELPER_NAMES.includes(node.callee.property.name as (typeof AUTHZ_HELPER_NAMES)[number])))\r\n ) {\r\n return true;\r\n }\r\n\r\n const entries = Object.entries(node) as Array<[string, unknown]>;\r\n for (const [key, value] of entries) {\r\n if (key === 'parent') continue;\r\n\r\n if (Array.isArray(value)) {\r\n for (const child of value) {\r\n if (child && typeof child === 'object' && 'type' in child) {\r\n if (containsAuthorizationHelper(child as TSESTree.Node)) return true;\r\n }\r\n }\r\n continue;\r\n }\r\n\r\n if (value && typeof value === 'object' && 'type' in value) {\r\n if (containsAuthorizationHelper(value as TSESTree.Node)) return true;\r\n }\r\n }\r\n\r\n return false;\r\n}\r\n\r\nfunction collectBodySignals(node: TSESTree.Node): { hasResourceIdAccess: boolean; hasOwnershipCheck: boolean } {\r\n let hasResourceIdAccess = false;\r\n let hasOwnershipCheck = false;\r\n\r\n const walk = (current: TSESTree.Node): void => {\r\n if (\r\n current.type === AST_NODE_TYPES.BinaryExpression &&\r\n ['===', '==', '!==', '!='].includes(current.operator)\r\n ) {\r\n const leftPath = getMemberPath(current.left);\r\n const rightPath = getMemberPath(current.right);\r\n\r\n const leftIsUser = isReqUserPath(leftPath);\r\n const rightIsUser = isReqUserPath(rightPath);\r\n const leftIsResource = isLikelyResourceIdPath(leftPath);\r\n const rightIsResource = isLikelyResourceIdPath(rightPath);\r\n\r\n if ((leftIsUser && rightIsResource) || (rightIsUser && leftIsResource)) {\r\n hasOwnershipCheck = true;\r\n }\r\n }\r\n\r\n if (current.type === AST_NODE_TYPES.MemberExpression) {\r\n const path = getMemberPath(current);\r\n if (isLikelyResourceIdPath(path)) {\r\n hasResourceIdAccess = true;\r\n }\r\n }\r\n\r\n if (containsAuthorizationHelper(current)) {\r\n hasOwnershipCheck = true;\r\n }\r\n\r\n const entries = Object.entries(current) as Array<[string, unknown]>;\r\n for (const [key, value] of entries) {\r\n if (key === 'parent') continue;\r\n\r\n if (Array.isArray(value)) {\r\n for (const child of value) {\r\n if (child && typeof child === 'object' && 'type' in child) {\r\n walk(child as TSESTree.Node);\r\n }\r\n }\r\n continue;\r\n }\r\n\r\n if (value && typeof value === 'object' && 'type' in value) {\r\n walk(value as TSESTree.Node);\r\n }\r\n }\r\n };\r\n\r\n walk(node);\r\n\r\n return { hasResourceIdAccess, hasOwnershipCheck };\r\n}\r\n\r\nexport const requireAuthzCheck = createRule({\r\n name: 'require-authz-check',\r\n meta: {\r\n type: 'suggestion',\r\n docs: {\r\n description:\r\n 'Require a visible authorization/ownership check when route handlers access resource identifiers (e.g., req.params.id). AI tools often add auth middleware but forget per-resource authorization checks.',\r\n },\r\n fixable: undefined,\r\n schema: [],\r\n messages: {\r\n missingAuthz:\r\n 'Potential missing authorization check. This handler uses resource identifiers (like req.params.id) but no visible ownership/authorization guard was found. AI tools frequently miss authz after auth.',\r\n },\r\n },\r\n defaultOptions: [],\r\n create(context) {\r\n return {\r\n CallExpression(node) {\r\n if (!isRouteRegistrationCall(node)) {\r\n return;\r\n }\r\n\r\n const routePath = getStaticPathArg(node);\r\n const hasRouteIdParam = typeof routePath === 'string' && routePath.includes(':');\r\n\r\n for (const arg of node.arguments) {\r\n if (\r\n arg.type !== AST_NODE_TYPES.FunctionExpression &&\r\n arg.type !== AST_NODE_TYPES.ArrowFunctionExpression\r\n ) {\r\n continue;\r\n }\r\n\r\n if (arg.body.type !== AST_NODE_TYPES.BlockStatement) {\r\n continue;\r\n }\r\n\r\n const signals = collectBodySignals(arg.body);\r\n const isSensitive = hasRouteIdParam && signals.hasResourceIdAccess;\r\n\r\n if (isSensitive && !signals.hasOwnershipCheck) {\r\n context.report({\r\n node: arg,\r\n messageId: 'missingAuthz',\r\n });\r\n }\r\n }\r\n },\r\n };\r\n },\r\n});\r\n\r\nexport default requireAuthzCheck;\r\n","import { ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';\r\nimport type { TSESTree } from '@typescript-eslint/utils';\r\n\r\nconst createRule = ESLintUtils.RuleCreator(\r\n (name) => `https://github.com/YashJadhav21/eslint-plugin-ai-guard/blob/main/docs/rules/${name}.md`\r\n);\r\n\r\nconst ROUTE_METHODS = [\r\n 'get',\r\n 'post',\r\n 'put',\r\n 'patch',\r\n 'delete',\r\n 'options',\r\n 'all',\r\n] as const;\r\n\r\nfunction isRouteRegistrationCall(node: TSESTree.CallExpression): boolean {\r\n if (\r\n node.callee.type !== AST_NODE_TYPES.MemberExpression ||\r\n node.callee.property.type !== AST_NODE_TYPES.Identifier\r\n ) {\r\n return false;\r\n }\r\n\r\n const methodName = node.callee.property.name;\r\n if (!ROUTE_METHODS.includes(methodName as (typeof ROUTE_METHODS)[number])) {\r\n return false;\r\n }\r\n\r\n if (node.arguments.length === 0) {\r\n return false;\r\n }\r\n\r\n const firstArg = node.arguments[0];\r\n\r\n // Keep matching conservative to avoid false positives on non-routing APIs.\r\n if (\r\n firstArg.type === AST_NODE_TYPES.Literal &&\r\n typeof firstArg.value === 'string' &&\r\n firstArg.value.startsWith('/')\r\n ) {\r\n return true;\r\n }\r\n\r\n if (\r\n firstArg.type === AST_NODE_TYPES.TemplateLiteral &&\r\n firstArg.expressions.length === 0 &&\r\n firstArg.quasis[0]?.value.raw.startsWith('/')\r\n ) {\r\n return true;\r\n }\r\n\r\n return false;\r\n}\r\n\r\nfunction traverseForConsoleCalls(\r\n node: TSESTree.Node,\r\n onConsoleCall: (callNode: TSESTree.CallExpression) => void\r\n): void {\r\n if (\r\n node.type === AST_NODE_TYPES.CallExpression &&\r\n node.callee.type === AST_NODE_TYPES.MemberExpression &&\r\n node.callee.object.type === AST_NODE_TYPES.Identifier &&\r\n node.callee.object.name === 'console' &&\r\n node.callee.property.type === AST_NODE_TYPES.Identifier\r\n ) {\r\n onConsoleCall(node);\r\n }\r\n\r\n // Do not recurse into nested function bodies to avoid double-reporting on unrelated closures.\r\n if (\r\n node.type === AST_NODE_TYPES.FunctionDeclaration ||\r\n node.type === AST_NODE_TYPES.FunctionExpression ||\r\n node.type === AST_NODE_TYPES.ArrowFunctionExpression\r\n ) {\r\n return;\r\n }\r\n\r\n const entries = Object.entries(node) as Array<[string, unknown]>;\r\n for (const [key, value] of entries) {\r\n if (key === 'parent') {\r\n continue;\r\n }\r\n\r\n if (Array.isArray(value)) {\r\n for (const child of value) {\r\n if (child && typeof child === 'object' && 'type' in child) {\r\n traverseForConsoleCalls(child as TSESTree.Node, onConsoleCall);\r\n }\r\n }\r\n continue;\r\n }\r\n\r\n if (value && typeof value === 'object' && 'type' in value) {\r\n traverseForConsoleCalls(value as TSESTree.Node, onConsoleCall);\r\n }\r\n }\r\n}\r\n\r\nexport const noConsoleInHandler = createRule({\r\n name: 'no-console-in-handler',\r\n meta: {\r\n type: 'suggestion',\r\n docs: {\r\n description:\r\n 'Disallow console logging inside route handlers. AI tools frequently leave debug logs in request handlers, which can leak operational data and create noisy production logs.',\r\n },\r\n fixable: undefined,\r\n hasSuggestions: true,\r\n schema: [],\r\n messages: {\r\n noConsoleInHandler:\r\n 'Avoid console logging inside route handlers. AI tools frequently leave debug statements in handlers. Use structured application logging instead.',\r\n removeConsoleCall:\r\n 'Remove this console statement from the route handler.',\r\n },\r\n },\r\n defaultOptions: [],\r\n create(context) {\r\n return {\r\n CallExpression(node) {\r\n if (!isRouteRegistrationCall(node)) {\r\n return;\r\n }\r\n\r\n for (const argument of node.arguments) {\r\n if (\r\n argument.type !== AST_NODE_TYPES.FunctionExpression &&\r\n argument.type !== AST_NODE_TYPES.ArrowFunctionExpression\r\n ) {\r\n continue;\r\n }\r\n\r\n if (argument.body.type !== AST_NODE_TYPES.BlockStatement) {\r\n continue;\r\n }\r\n\r\n for (const statement of argument.body.body) {\r\n traverseForConsoleCalls(statement, (callNode) => {\r\n const parent = callNode.parent;\r\n const canSuggestRemoval = parent?.type === AST_NODE_TYPES.ExpressionStatement;\r\n\r\n context.report({\r\n node: callNode,\r\n messageId: 'noConsoleInHandler',\r\n suggest: canSuggestRemoval\r\n ? [\r\n {\r\n messageId: 'removeConsoleCall',\r\n fix: (fixer) => fixer.remove(parent),\r\n },\r\n ]\r\n : undefined,\r\n });\r\n });\r\n }\r\n }\r\n },\r\n };\r\n },\r\n});\r\n\r\nexport default noConsoleInHandler;\r\n","import { ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';\r\nimport type { TSESTree } from '@typescript-eslint/utils';\r\n\r\nconst createRule = ESLintUtils.RuleCreator(\r\n (name) => `https://github.com/YashJadhav21/eslint-plugin-ai-guard/blob/main/docs/rules/${name}.md`\r\n);\r\n\r\nfunction normalizeStatementText(source: string): string {\r\n return source.replace(/\\s+/g, ' ').trim();\r\n}\r\n\r\nfunction isLikelyMeaningfulStatement(node: TSESTree.Statement, sourceCodeText: string): boolean {\r\n if (\r\n node.type === AST_NODE_TYPES.EmptyStatement ||\r\n node.type === AST_NODE_TYPES.BreakStatement ||\r\n node.type === AST_NODE_TYPES.ContinueStatement\r\n ) {\r\n return false;\r\n }\r\n\r\n return sourceCodeText.length >= 30;\r\n}\r\n\r\nexport const noDuplicateLogicBlock = createRule({\r\n name: 'no-duplicate-logic-block',\r\n meta: {\r\n type: 'suggestion',\r\n docs: {\r\n description:\r\n 'Disallow consecutive duplicated logic statements. AI tools often copy-paste the same logic block with minimal or no changes, which should usually be extracted or consolidated.',\r\n },\r\n fixable: undefined,\r\n schema: [],\r\n messages: {\r\n duplicateLogic:\r\n 'Duplicate consecutive logic block detected. AI-generated code often repeats the same block. Consider extracting shared logic into a function or removing duplication.',\r\n },\r\n },\r\n defaultOptions: [],\r\n create(context) {\r\n const checkStatementList = (statements: TSESTree.Statement[]): void => {\r\n if (statements.length < 2) {\r\n return;\r\n }\r\n\r\n for (let i = 0; i < statements.length - 1; i += 1) {\r\n const current = statements[i];\r\n const next = statements[i + 1];\r\n\r\n const currentTextRaw = context.sourceCode.getText(current);\r\n const nextTextRaw = context.sourceCode.getText(next);\r\n\r\n if (!isLikelyMeaningfulStatement(current, currentTextRaw)) {\r\n continue;\r\n }\r\n\r\n if (!isLikelyMeaningfulStatement(next, nextTextRaw)) {\r\n continue;\r\n }\r\n\r\n const currentText = normalizeStatementText(currentTextRaw);\r\n const nextText = normalizeStatementText(nextTextRaw);\r\n\r\n if (currentText === nextText) {\r\n context.report({\r\n node: next,\r\n messageId: 'duplicateLogic',\r\n });\r\n }\r\n }\r\n };\r\n\r\n return {\r\n Program(node) {\r\n checkStatementList(node.body);\r\n },\r\n\r\n BlockStatement(node) {\r\n checkStatementList(node.body);\r\n },\r\n };\r\n },\r\n});\r\n\r\nexport default noDuplicateLogicBlock;\r\n","import { ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';\nimport type { TSESTree } from '@typescript-eslint/utils';\n\nconst createRule = ESLintUtils.RuleCreator(\n (name) => `https://github.com/YashJadhav21/eslint-plugin-ai-guard/blob/main/docs/rules/${name}.md`\n);\n\n/**\n * Checks if a node is the boolean literal `true` or `false`.\n */\nfunction isBooleanLiteral(node: TSESTree.Node, value: boolean): boolean {\n return (\n node.type === AST_NODE_TYPES.Literal &&\n typeof node.value === 'boolean' &&\n node.value === value\n );\n}\n\n/**\n * Checks if a node is a numeric literal equal to zero.\n */\nfunction isZeroLiteral(node: TSESTree.Node): boolean {\n return (\n node.type === AST_NODE_TYPES.Literal &&\n typeof node.value === 'number' &&\n node.value === 0\n );\n}\n\n/**\n * Checks if a node is the string literal `\"\"` or `''`.\n */\nfunction isEmptyStringLiteral(node: TSESTree.Node): boolean {\n return (\n node.type === AST_NODE_TYPES.Literal &&\n typeof node.value === 'string' &&\n node.value === ''\n );\n}\n\n/**\n * Returns true if the condition is statically always-true or always-false.\n * Handles:\n * - `if (true)` / `if (false)`\n * - `if (1)` / `if (0)`\n * - `while (true)` (intentional infinite loops are common, so we exempt them)\n * - `if (x && !x)` / `if (x || !x)` — self-contradictory / self-tautological\n * - `x === x` when x is an identifier (trivially true)\n */\nfunction isAlwaysTrue(node: TSESTree.Node): boolean {\n if (isBooleanLiteral(node, true)) return true;\n\n // x || !x is always true\n if (\n node.type === AST_NODE_TYPES.LogicalExpression &&\n node.operator === '||'\n ) {\n const { left, right } = node;\n if (\n left.type === AST_NODE_TYPES.Identifier &&\n right.type === AST_NODE_TYPES.UnaryExpression &&\n right.operator === '!' &&\n right.argument.type === AST_NODE_TYPES.Identifier &&\n left.name === right.argument.name\n ) {\n return true;\n }\n }\n\n // x === x (same identifier compared to itself)\n if (\n node.type === AST_NODE_TYPES.BinaryExpression &&\n (node.operator === '===' || node.operator === '==') &&\n node.left.type === AST_NODE_TYPES.Identifier &&\n node.right.type === AST_NODE_TYPES.Identifier &&\n node.left.name === node.right.name\n ) {\n return true;\n }\n\n return false;\n}\n\nfunction isAlwaysFalse(node: TSESTree.Node): boolean {\n if (isBooleanLiteral(node, false)) return true;\n if (isZeroLiteral(node)) return true;\n if (isEmptyStringLiteral(node)) return true;\n\n // x && !x is always false\n if (\n node.type === AST_NODE_TYPES.LogicalExpression &&\n node.operator === '&&'\n ) {\n const { left, right } = node;\n if (\n left.type === AST_NODE_TYPES.Identifier &&\n right.type === AST_NODE_TYPES.UnaryExpression &&\n right.operator === '!' &&\n right.argument.type === AST_NODE_TYPES.Identifier &&\n left.name === right.argument.name\n ) {\n return true;\n }\n }\n\n // x !== x (same identifier compared to itself with strict inequality)\n if (\n node.type === AST_NODE_TYPES.BinaryExpression &&\n (node.operator === '!==' || node.operator === '!=') &&\n node.left.type === AST_NODE_TYPES.Identifier &&\n node.right.type === AST_NODE_TYPES.Identifier &&\n node.left.name === node.right.name\n ) {\n return true;\n }\n\n return false;\n}\n\nexport const noDeadBranch = createRule({\n name: 'no-dead-branch',\n meta: {\n type: 'suggestion',\n docs: {\n description:\n 'Disallow conditions that are statically always-true or always-false. AI tools frequently generate dead branches like `if (true)`, `if (false)`, `if (x && !x)`, or `x === x` — leftover scaffolding that clutters the code and hides logical errors.',\n },\n fixable: undefined,\n schema: [],\n messages: {\n alwaysTrue:\n 'This condition is always `true` — the branch is never skipped. AI tools often generate this as leftover scaffolding. Remove the condition or replace it with the intended logic.',\n alwaysFalse:\n 'This condition is always `false` — this branch is dead and never executed. AI tools often generate this as leftover scaffolding. Remove the dead branch entirely.',\n whileFalse:\n 'This `while (false)` loop never executes. AI tools sometimes generate this as a placeholder. Remove it or replace with the intended loop condition.',\n },\n },\n defaultOptions: [],\n create(context) {\n function checkCondition(\n testNode: TSESTree.Expression | null,\n reportNode: TSESTree.Node,\n isBranchStatement: boolean,\n ): void {\n if (!testNode) return;\n\n if (isAlwaysFalse(testNode)) {\n context.report({\n node: reportNode,\n messageId: isBranchStatement ? 'alwaysFalse' : 'whileFalse',\n });\n return;\n }\n\n if (isAlwaysTrue(testNode)) {\n // while (true) is a common and intentional pattern for event loops\n // and retry mechanisms — don't flag it.\n if (reportNode.type === AST_NODE_TYPES.WhileStatement) return;\n\n context.report({\n node: reportNode,\n messageId: 'alwaysTrue',\n });\n }\n }\n\n return {\n IfStatement(node) {\n checkCondition(node.test, node, true);\n },\n\n WhileStatement(node) {\n // while (false) is always dead\n if (isAlwaysFalse(node.test)) {\n context.report({ node, messageId: 'whileFalse' });\n }\n // while (true) is intentional — skip\n },\n\n DoWhileStatement(node) {\n // do { ... } while (false) is a common C trick but AI tools\n // sometimes generate it erroneously in JS\n if (isAlwaysFalse(node.test)) {\n context.report({ node, messageId: 'whileFalse' });\n }\n },\n\n ConditionalExpression(node) {\n checkCondition(node.test, node, true);\n },\n };\n },\n});\n\nexport default noDeadBranch;\n","// ── Reliability (was: error-handling) ─────────────────────────────────────────\nimport { noEmptyCatch } from './reliability/no-empty-catch';\nimport { noBroadException } from './reliability/no-broad-exception';\nimport { noCatchLogRethrow } from './reliability/no-catch-log-rethrow';\nimport { noCatchWithoutUse } from './reliability/no-catch-without-use';\n\n// ── Async ──────────────────────────────────────────────────────────────────────\nimport { noAsyncArrayCallback } from './async/no-async-array-callback';\nimport { noFloatingPromise } from './async/no-floating-promise';\nimport { noAwaitInLoop } from './async/no-await-in-loop';\nimport { noAsyncWithoutAwait } from './async/no-async-without-await';\nimport { noRedundantAwait } from './async/no-redundant-await';\n\n// ── Security ───────────────────────────────────────────────────────────────────\nimport { noHardcodedSecret } from './security/no-hardcoded-secret';\nimport { noEvalDynamic } from './security/no-eval-dynamic';\nimport { noSqlStringConcat } from './security/no-sql-string-concat';\nimport { noUnsafeDeserialize } from './security/no-unsafe-deserialize';\nimport { requireAuthMiddleware } from './security/require-auth-middleware';\nimport { requireAuthzCheck } from './security/require-authz-check';\n\n// ── AI Patterns (was: quality + logic) ────────────────────────────────────────\nimport { noConsoleInHandler } from './ai-patterns/no-console-in-handler';\nimport { noDuplicateLogicBlock } from './ai-patterns/no-duplicate-logic-block';\nimport { noDeadBranch } from './ai-patterns/no-dead-branch';\n\n/**\n * All rules exported by the plugin.\n * Each key is the rule name (without the plugin prefix).\n *\n * Categories (internal source directories):\n * reliability/ — error handling & exception patterns\n * async/ — async/await & promise patterns\n * security/ — secrets, injection, auth gaps\n * ai-patterns/ — AI-specific code slop: dead code, quality issues\n */\nexport const allRules = {\n // Reliability\n 'no-empty-catch': noEmptyCatch,\n 'no-broad-exception': noBroadException,\n 'no-catch-log-rethrow': noCatchLogRethrow,\n 'no-catch-without-use': noCatchWithoutUse,\n // Async\n 'no-async-array-callback': noAsyncArrayCallback,\n 'no-floating-promise': noFloatingPromise,\n 'no-await-in-loop': noAwaitInLoop,\n 'no-async-without-await': noAsyncWithoutAwait,\n 'no-redundant-await': noRedundantAwait,\n // Security\n 'no-hardcoded-secret': noHardcodedSecret,\n 'no-eval-dynamic': noEvalDynamic,\n 'no-sql-string-concat': noSqlStringConcat,\n 'no-unsafe-deserialize': noUnsafeDeserialize,\n 'require-auth-middleware': requireAuthMiddleware,\n 'require-authz-check': requireAuthzCheck,\n // AI Patterns\n 'no-console-in-handler': noConsoleInHandler,\n 'no-duplicate-logic-block': noDuplicateLogicBlock,\n 'no-dead-branch': noDeadBranch,\n} as const;\n\nexport type RuleKey = keyof typeof allRules;\n","import type { TSESLint } from '@typescript-eslint/utils';\n\nconst recommended: TSESLint.ClassicConfig.Config = {\n plugins: ['ai-guard'],\n rules: {\n // Adoption-first default:\n // Keep only high-confidence, high-impact rules at error so first run is actionable,\n // not overwhelming. Context-sensitive rules are warn/off by design.\n\n // ── Reliability ────────────────────────────────────────────────────────────\n // Critical (error): low-noise, high-impact correctness failures.\n 'ai-guard/no-empty-catch': 'error',\n\n // Important but context-dependent (warn).\n 'ai-guard/no-broad-exception': 'warn',\n\n // Off in recommended — too noisy in mixed codebases.\n 'ai-guard/no-catch-without-use': 'off',\n 'ai-guard/no-catch-log-rethrow': 'off',\n\n // ── Async ──────────────────────────────────────────────────────────────────\n 'ai-guard/no-floating-promise': 'error',\n 'ai-guard/no-await-in-loop': 'warn',\n 'ai-guard/no-async-without-await': 'warn',\n 'ai-guard/no-async-array-callback': 'warn',\n\n // Off in recommended — reduces noise in common patterns.\n 'ai-guard/no-redundant-await': 'off',\n\n // ── Security ───────────────────────────────────────────────────────────────\n // Critical (error): direct security vulnerabilities.\n 'ai-guard/no-hardcoded-secret': 'error',\n 'ai-guard/no-eval-dynamic': 'error',\n\n // Context-sensitive (warn): useful but require project context.\n 'ai-guard/no-sql-string-concat': 'warn',\n 'ai-guard/no-unsafe-deserialize': 'warn',\n 'ai-guard/require-auth-middleware': 'warn',\n 'ai-guard/require-authz-check': 'warn',\n\n // ── AI Patterns ────────────────────────────────────────────────────────────\n // Warn: useful signal, but may fire in intentional dead-code removal flows.\n 'ai-guard/no-dead-branch': 'warn',\n\n // Off in recommended — contextual rules for teams opting into stricter checks.\n 'ai-guard/no-console-in-handler': 'off',\n 'ai-guard/no-duplicate-logic-block': 'off',\n },\n};\n\nexport default recommended;\n","import type { TSESLint } from '@typescript-eslint/utils';\n\nconst strict: TSESLint.ClassicConfig.Config = {\n plugins: ['ai-guard'],\n rules: {\n // Strict preset: enforce every ai-guard rule at error for mature teams\n // that want maximum coverage and are ready to tune exceptions locally.\n\n // Error Handling - all at error\n 'ai-guard/no-empty-catch': 'error',\n 'ai-guard/no-broad-exception': 'error',\n 'ai-guard/no-catch-log-rethrow': 'error',\n 'ai-guard/no-catch-without-use': 'error',\n // Async - all at error\n 'ai-guard/no-async-array-callback': 'error',\n 'ai-guard/no-floating-promise': 'error',\n 'ai-guard/no-await-in-loop': 'error',\n 'ai-guard/no-async-without-await': 'error',\n 'ai-guard/no-redundant-await': 'error',\n // Security - all at error\n 'ai-guard/no-hardcoded-secret': 'error',\n 'ai-guard/no-eval-dynamic': 'error',\n 'ai-guard/no-sql-string-concat': 'error',\n 'ai-guard/no-unsafe-deserialize': 'error',\n 'ai-guard/require-auth-middleware': 'error',\n 'ai-guard/require-authz-check': 'error',\n // AI Patterns - all at error\n 'ai-guard/no-console-in-handler': 'error',\n 'ai-guard/no-duplicate-logic-block': 'error',\n 'ai-guard/no-dead-branch': 'error',\n },\n};\n\nexport default strict;\n","import type { TSESLint } from '@typescript-eslint/utils';\n\nconst security: TSESLint.ClassicConfig.Config = {\n plugins: ['ai-guard'],\n rules: {\n // Security-only preset:\n // Error = direct high-risk patterns. Warn = security-relevant but context-sensitive.\n 'ai-guard/no-hardcoded-secret': 'error',\n 'ai-guard/no-eval-dynamic': 'error',\n 'ai-guard/no-sql-string-concat': 'error',\n 'ai-guard/no-unsafe-deserialize': 'warn',\n 'ai-guard/require-auth-middleware': 'warn',\n 'ai-guard/require-authz-check': 'warn',\n },\n};\n\nexport default security;\n"],"mappings":"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","names":["import_utils","createRule","import_utils","createRule","import_utils","createRule","import_utils","createRule","import_utils","createRule","import_utils","createRule","path","import_utils","import_path","createRule","path","buildSafeAutofix","fix","import_utils","createRule","import_utils","createRule","import_utils","createRule","import_utils","createRule","import_utils","createRule","import_utils","createRule","import_utils","createRule","path","import_utils","createRule","ROUTE_METHODS","isRouteRegistrationCall","import_utils","createRule","import_utils","createRule"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/rules/reliability/no-empty-catch.ts","../src/rules/reliability/no-broad-exception.ts","../src/rules/reliability/no-catch-log-rethrow.ts","../src/rules/reliability/no-catch-without-use.ts","../src/rules/async/no-async-array-callback.ts","../src/rules/async/no-floating-promise.ts","../src/rules/async/no-await-in-loop.ts","../src/rules/async/no-async-without-await.ts","../src/rules/async/no-redundant-await.ts","../src/rules/security/no-hardcoded-secret.ts","../src/rules/security/no-eval-dynamic.ts","../src/rules/security/no-sql-string-concat.ts","../src/rules/security/no-unsafe-deserialize.ts","../src/rules/security/require-auth-middleware.ts","../src/rules/security/require-authz-check.ts","../src/rules/ai-patterns/no-console-in-handler.ts","../src/rules/ai-patterns/no-duplicate-logic-block.ts","../src/rules/ai-patterns/no-dead-branch.ts","../src/rules/index.ts","../src/configs/recommended.ts","../src/configs/strict.ts","../src/configs/security.ts"],"sourcesContent":["import { allRules } from './rules';\r\nimport recommended from './configs/recommended';\r\nimport strict from './configs/strict';\r\nimport security from './configs/security';\r\nimport { createRequire } from 'module';\r\nimport { fileURLToPath } from 'url';\r\nimport path from 'path';\r\n\r\n// Safely read version in both CJS and ESM environments\r\nlet pkgVersion = '1.2.2'; // Fallback\r\ntry {\r\n // Use createRequire combined with import.meta.url for ESM compatibility\r\n const require_ = typeof require !== 'undefined' ? require : createRequire(import.meta.url);\r\n \r\n // Calculate path relative to the current file\r\n const isESM = typeof __dirname === 'undefined';\r\n const dirname = isESM ? path.dirname(fileURLToPath(import.meta.url)) : __dirname;\r\n \r\n // Find package.json (works for both src/index.ts and dist/index.js/mjs)\r\n const pkgPath = path.resolve(dirname, dirname.endsWith('src') ? '../package.json' : '../../package.json');\r\n \r\n const pkg = require_(pkgPath);\r\n if (pkg && pkg.version) pkgVersion = pkg.version;\r\n} catch {\r\n // Ignore and use fallback\r\n}\r\n\r\nconst plugin = {\r\n meta: {\r\n name: 'eslint-plugin-ai-guard',\r\n version: pkgVersion,\r\n },\r\n rules: allRules,\r\n configs: {\r\n recommended,\r\n strict,\r\n security,\r\n },\r\n};\r\n\r\nexport default plugin;\r\nexport { allRules as rules };\r\nexport { recommended, strict, security };\r\n","import { ESLintUtils } from '@typescript-eslint/utils';\r\n\r\nconst createRule = ESLintUtils.RuleCreator(\r\n (name) => `https://github.com/YashJadhav21/eslint-plugin-ai-guard/blob/main/docs/rules/${name}.md`\r\n);\r\n\r\nexport const noEmptyCatch = createRule({\r\n name: 'no-empty-catch',\r\n meta: {\r\n type: 'problem',\r\n docs: {\r\n description:\r\n 'Disallow empty catch blocks. AI tools frequently generate try/catch with empty catch bodies that silently swallow errors, hiding failures in production. Includes a safe autofix that inserts an explicit placeholder comment.',\r\n },\r\n fixable: 'code',\r\n hasSuggestions: true,\r\n schema: [],\r\n messages: {\r\n emptyCatch:\r\n 'Catch block is empty. AI tools frequently generate empty catch blocks that silently swallow errors. Handle the error (log, rethrow, or recover), or add a comment explaining why it is intentionally empty.',\r\n addTodoHandler:\r\n 'Add a minimal placeholder so this catch block is not silently swallowing errors.',\r\n },\r\n },\r\n defaultOptions: [],\r\n create(context) {\r\n return {\r\n CatchClause(node) {\r\n // Flag catch clauses where the body block has zero statements\r\n if (node.body.body.length === 0) {\r\n // Check if there is a comment inside the catch block — if so, the developer\r\n // intentionally left it empty with a reason, so we don't flag it.\r\n const sourceCode = context.sourceCode;\r\n const comments = sourceCode.getCommentsInside(node.body);\r\n if (comments.length > 0) {\r\n return;\r\n }\r\n\r\n context.report({\r\n node,\r\n messageId: 'emptyCatch',\r\n fix: (fixer) => fixer.replaceText(node.body, '{ /* TODO: handle error */ }'),\r\n suggest: [\r\n {\r\n messageId: 'addTodoHandler',\r\n fix: (fixer) => fixer.replaceText(node.body, '{ /* TODO: handle error */ }'),\r\n },\r\n ],\r\n });\r\n }\r\n },\r\n };\r\n },\r\n});\r\n\r\nexport default noEmptyCatch;\r\n","import { ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';\n\nconst createRule = ESLintUtils.RuleCreator(\n (name) => `https://github.com/YashJadhav21/eslint-plugin-ai-guard/blob/main/docs/rules/${name}.md`\n);\n\nexport const noBroadException = createRule({\n name: 'no-broad-exception',\n meta: {\n type: 'suggestion',\n docs: {\n description:\n 'Disallow overly broad catch clause types such as `catch (e: any)` or `catch (e: unknown)` without narrowing. AI tools frequently use `any` type annotations on catch parameters, hiding the actual error type and preventing proper error handling.',\n },\n fixable: undefined,\n schema: [],\n messages: {\n broadException:\n 'Catch parameter has an overly broad type annotation `{{type}}`. AI tools frequently generate `catch (e: any)` which hides the real error type. Use a specific error type or narrow with `instanceof` checks inside the catch block.',\n },\n },\n defaultOptions: [],\n create(context) {\n return {\n CatchClause(node) {\n const param = node.param;\n if (!param) return;\n\n // Check for explicit type annotation: catch (e: any), catch (e: unknown)\n if (\n param.type === AST_NODE_TYPES.Identifier &&\n param.typeAnnotation &&\n param.typeAnnotation.typeAnnotation\n ) {\n const typeAnnotation = param.typeAnnotation.typeAnnotation;\n\n // catch (e: any)\n if (typeAnnotation.type === AST_NODE_TYPES.TSAnyKeyword) {\n context.report({\n node: param,\n messageId: 'broadException',\n data: { type: 'any' },\n });\n return;\n }\n\n // catch (e: unknown) — only flag if the parameter is never narrowed in the body\n if (typeAnnotation.type === AST_NODE_TYPES.TSUnknownKeyword) {\n // Check if the catch body contains instanceof checks or type guards\n const hasNarrowing = checkForNarrowing(node, param.name);\n if (!hasNarrowing) {\n context.report({\n node: param,\n messageId: 'broadException',\n data: { type: 'unknown' },\n });\n }\n }\n }\n },\n };\n },\n});\n\n/**\n * Check if the catch block body contains instanceof checks or other narrowing\n * patterns for the given parameter name.\n */\nfunction checkForNarrowing(\n catchClause: { body: { body: readonly { type: string; [key: string]: any }[] } },\n paramName: string\n): boolean {\n const bodyStatements = catchClause.body.body;\n\n for (const stmt of bodyStatements) {\n if (containsInstanceofCheck(stmt, paramName)) {\n return true;\n }\n }\n return false;\n}\n\nfunction containsInstanceofCheck(node: any, paramName: string): boolean {\n if (!node || typeof node !== 'object') return false;\n\n // Check for: e instanceof SomeError\n if (\n node.type === AST_NODE_TYPES.BinaryExpression &&\n node.operator === 'instanceof' &&\n node.left?.type === AST_NODE_TYPES.Identifier &&\n node.left.name === paramName\n ) {\n return true;\n }\n\n // Recurse into child nodes\n for (const key of Object.keys(node)) {\n if (key === 'parent') continue;\n const child = node[key];\n if (Array.isArray(child)) {\n for (const item of child) {\n if (containsInstanceofCheck(item, paramName)) return true;\n }\n } else if (child && typeof child === 'object' && child.type) {\n if (containsInstanceofCheck(child, paramName)) return true;\n }\n }\n return false;\n}\n\nexport default noBroadException;\n","import { ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';\r\nimport type { TSESTree } from '@typescript-eslint/utils';\r\n\r\nconst createRule = ESLintUtils.RuleCreator(\r\n (name) => `https://github.com/YashJadhav21/eslint-plugin-ai-guard/blob/main/docs/rules/${name}.md`\r\n);\r\n\r\nfunction isConsoleCallStatement(statement: TSESTree.Statement): boolean {\r\n if (statement.type !== AST_NODE_TYPES.ExpressionStatement) {\r\n return false;\r\n }\r\n\r\n const expression = statement.expression;\r\n if (expression.type !== AST_NODE_TYPES.CallExpression) {\r\n return false;\r\n }\r\n\r\n if (expression.callee.type !== AST_NODE_TYPES.MemberExpression) {\r\n return false;\r\n }\r\n\r\n return (\r\n expression.callee.object.type === AST_NODE_TYPES.Identifier &&\r\n expression.callee.object.name === 'console' &&\r\n expression.callee.property.type === AST_NODE_TYPES.Identifier &&\r\n ['log', 'error', 'warn', 'info', 'debug'].includes(expression.callee.property.name)\r\n );\r\n}\r\n\r\nfunction isRethrowOfCatchParam(\r\n statement: TSESTree.Statement,\r\n catchParamName: string\r\n): boolean {\r\n return (\r\n statement.type === AST_NODE_TYPES.ThrowStatement &&\r\n statement.argument !== null &&\r\n statement.argument.type === AST_NODE_TYPES.Identifier &&\r\n statement.argument.name === catchParamName\r\n );\r\n}\r\n\r\nexport const noCatchLogRethrow = createRule({\r\n name: 'no-catch-log-rethrow',\r\n meta: {\r\n type: 'suggestion',\r\n docs: {\r\n description:\r\n 'Disallow catch blocks that only log and rethrow the same error. AI tools frequently generate catch-log-rethrow patterns that add noise without recovery or context.',\r\n },\r\n fixable: undefined,\r\n schema: [],\r\n messages: {\r\n catchLogRethrow:\r\n 'This catch block only logs and rethrows the same error. AI tools frequently generate this noisy pattern without adding recovery. Either remove the catch block or add meaningful handling/context.',\r\n },\r\n },\r\n defaultOptions: [],\r\n create(context) {\r\n return {\r\n CatchClause(node) {\r\n if (!node.param || node.param.type !== AST_NODE_TYPES.Identifier) {\r\n return;\r\n }\r\n\r\n const bodyStatements = node.body.body;\r\n if (bodyStatements.length < 2) {\r\n return;\r\n }\r\n\r\n const lastStatement = bodyStatements[bodyStatements.length - 1];\r\n if (!isRethrowOfCatchParam(lastStatement, node.param.name)) {\r\n return;\r\n }\r\n\r\n const leadingStatements = bodyStatements.slice(0, -1);\r\n const allConsoleCalls = leadingStatements.every(isConsoleCallStatement);\r\n\r\n if (allConsoleCalls) {\r\n context.report({\r\n node,\r\n messageId: 'catchLogRethrow',\r\n });\r\n }\r\n },\r\n };\r\n },\r\n});\r\n\r\nexport default noCatchLogRethrow;\r\n","import { ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';\r\n\r\nconst createRule = ESLintUtils.RuleCreator(\r\n (name) => `https://github.com/YashJadhav21/eslint-plugin-ai-guard/blob/main/docs/rules/${name}.md`\r\n);\r\n\r\nexport const noCatchWithoutUse = createRule({\r\n name: 'no-catch-without-use',\r\n meta: {\r\n type: 'suggestion',\r\n docs: {\r\n description:\r\n 'Disallow catch parameters that are never used. AI tools frequently generate `catch (e)` while ignoring the error entirely, which hides actionable debugging context.',\r\n },\r\n fixable: undefined,\r\n schema: [],\r\n messages: {\r\n unusedCatchParam:\r\n 'Catch parameter `{{name}}` is never used. AI-generated catch blocks often include an unused error variable that hides missing error handling. Use it, remove it, or add explicit intent.',\r\n },\r\n },\r\n defaultOptions: [],\r\n create(context) {\r\n return {\r\n CatchClause(node) {\r\n if (!node.param || node.param.type !== AST_NODE_TYPES.Identifier) {\r\n return;\r\n }\r\n\r\n const catchParamName = node.param.name;\r\n\r\n // `_error` naming is a common convention to intentionally ignore values.\r\n if (catchParamName.startsWith('_')) {\r\n return;\r\n }\r\n\r\n // Token-based check is intentionally conservative: if the identifier appears\r\n // anywhere in the catch body, we treat it as used to avoid false positives.\r\n const tokens = context.sourceCode.getTokens(node.body);\r\n const hasUsage = tokens.some(\r\n (token) => token.type === 'Identifier' && token.value === catchParamName\r\n );\r\n\r\n if (!hasUsage) {\r\n context.report({\r\n node: node.param,\r\n messageId: 'unusedCatchParam',\r\n data: { name: catchParamName },\r\n });\r\n }\r\n },\r\n };\r\n },\r\n});\r\n\r\nexport default noCatchWithoutUse;\r\n","import { ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';\r\nimport type { TSESTree } from '@typescript-eslint/utils';\r\n\r\nconst createRule = ESLintUtils.RuleCreator(\r\n (name) => `https://github.com/YashJadhav21/eslint-plugin-ai-guard/blob/main/docs/rules/${name}.md`\r\n);\r\n\r\nconst ARRAY_CALLBACK_METHODS = ['map', 'filter', 'forEach', 'reduce', 'flatMap', 'find', 'findIndex', 'some', 'every'] as const;\r\n\r\nconst PROMISE_COMBINATORS = ['all', 'allSettled', 'race', 'any'] as const;\r\nconst METHODS_ALLOWING_PROMISE_COLLECTION = new Set(['map', 'flatMap']);\r\n\r\nfunction isNode(value: unknown): value is TSESTree.Node {\r\n return typeof value === 'object' && value !== null && 'type' in value;\r\n}\r\n\r\nfunction getChildNodes(node: TSESTree.Node): TSESTree.Node[] {\r\n const children: TSESTree.Node[] = [];\r\n for (const [key, value] of Object.entries(node as unknown as Record<string, unknown>)) {\r\n if (key === 'parent') continue;\r\n\r\n if (!value) continue;\r\n if (Array.isArray(value)) {\r\n for (const item of value) {\r\n if (isNode(item)) {\r\n children.push(item);\r\n }\r\n }\r\n continue;\r\n }\r\n\r\n if (isNode(value)) {\r\n children.push(value);\r\n }\r\n }\r\n return children;\r\n}\r\n\r\nfunction isPromiseCombinatorCall(node: TSESTree.CallExpression): boolean {\r\n return (\r\n node.callee.type === AST_NODE_TYPES.MemberExpression &&\r\n node.callee.object.type === AST_NODE_TYPES.Identifier &&\r\n node.callee.object.name === 'Promise' &&\r\n node.callee.property.type === AST_NODE_TYPES.Identifier &&\r\n PROMISE_COMBINATORS.includes(\r\n node.callee.property.name as (typeof PROMISE_COMBINATORS)[number],\r\n )\r\n );\r\n}\r\n\r\n/**\r\n * Checks if the given CallExpression (e.g., arr.map(...)) is used as an argument\r\n * to Promise.all(), Promise.allSettled(), Promise.race(), or Promise.any().\r\n */\r\nfunction isWrappedInPromiseCombinator(\r\n node: TSESTree.CallExpression,\r\n context: Readonly<Parameters<ReturnType<typeof createRule>['create']>[0]>\r\n): boolean {\r\n const ancestors = context.sourceCode.getAncestors(node);\r\n\r\n const directParent = node.parent;\r\n if (\r\n directParent &&\r\n directParent.type === AST_NODE_TYPES.CallExpression &&\r\n isPromiseCombinatorCall(directParent)\r\n ) {\r\n return true;\r\n }\r\n\r\n for (let i = ancestors.length - 1; i >= 0; i--) {\r\n const ancestor = ancestors[i];\r\n if (ancestor.type === AST_NODE_TYPES.CallExpression && isPromiseCombinatorCall(ancestor)) {\r\n return true;\r\n }\r\n\r\n if (ancestor.type === AST_NODE_TYPES.CallExpression) {\r\n break;\r\n }\r\n }\r\n return false;\r\n}\r\n\r\nfunction isIdentifierConsumedByPromiseCombinator(\r\n node: TSESTree.Node,\r\n identifierName: string,\r\n): boolean {\r\n let found = false;\r\n\r\n const visit = (current: TSESTree.Node): void => {\r\n if (found) return;\r\n\r\n if (\r\n current.type === AST_NODE_TYPES.CallExpression &&\r\n isPromiseCombinatorCall(current)\r\n ) {\r\n for (const arg of current.arguments) {\r\n if (arg.type === AST_NODE_TYPES.Identifier && arg.name === identifierName) {\r\n found = true;\r\n return;\r\n }\r\n }\r\n }\r\n\r\n for (const child of getChildNodes(current)) {\r\n visit(child);\r\n if (found) return;\r\n }\r\n };\r\n\r\n visit(node);\r\n return found;\r\n}\r\n\r\nfunction isAssignedAndConsumedByPromiseCombinator(\r\n node: TSESTree.CallExpression,\r\n): boolean {\r\n if (\r\n !node.parent ||\r\n node.parent.type !== AST_NODE_TYPES.VariableDeclarator ||\r\n node.parent.id.type !== AST_NODE_TYPES.Identifier\r\n ) {\r\n return false;\r\n }\r\n\r\n const variableName = node.parent.id.name;\r\n const declaration = node.parent.parent;\r\n if (!declaration || declaration.type !== AST_NODE_TYPES.VariableDeclaration) {\r\n return false;\r\n }\r\n\r\n const container = declaration.parent;\r\n if (!container || (container.type !== AST_NODE_TYPES.Program && container.type !== AST_NODE_TYPES.BlockStatement)) {\r\n return false;\r\n }\r\n\r\n const body = container.body;\r\n const declarationIndex = body.findIndex((statement) => statement === declaration);\r\n if (declarationIndex === -1) {\r\n return false;\r\n }\r\n\r\n for (let i = declarationIndex + 1; i < body.length; i++) {\r\n const statement = body[i];\r\n if (isIdentifierConsumedByPromiseCombinator(statement, variableName)) {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n}\r\n\r\n/**\r\n * Checks if a node is an async function expression or arrow function.\r\n */\r\nfunction isAsyncCallback(node: TSESTree.Node): boolean {\r\n return (\r\n (node.type === AST_NODE_TYPES.FunctionExpression ||\r\n node.type === AST_NODE_TYPES.ArrowFunctionExpression) &&\r\n node.async\r\n );\r\n}\r\n\r\nexport const noAsyncArrayCallback = createRule({\r\n name: 'no-async-array-callback',\r\n meta: {\r\n type: 'problem',\r\n docs: {\r\n description:\r\n 'Disallow async callbacks in array iteration methods (map, filter, forEach, reduce). AI tools generate `array.map(async ...)` which returns `Promise[]` instead of resolved values — a silent bug.',\r\n },\r\n fixable: undefined,\r\n schema: [],\r\n messages: {\r\n asyncArrayCallback:\r\n 'Async callback passed to Array.{{method}}(). This returns an array of Promises, not resolved values. AI tools frequently generate this pattern. Wrap with `await Promise.all(array.{{method}}(...))` or use a for...of loop.',\r\n },\r\n },\r\n defaultOptions: [],\r\n create(context) {\r\n return {\r\n CallExpression(node) {\r\n // Check if this is a method call like something.map(...), something.filter(...), etc.\r\n if (\r\n node.callee.type !== AST_NODE_TYPES.MemberExpression ||\r\n node.callee.property.type !== AST_NODE_TYPES.Identifier\r\n ) {\r\n return;\r\n }\r\n\r\n const methodName = node.callee.property.name;\r\n\r\n if (\r\n !ARRAY_CALLBACK_METHODS.includes(\r\n methodName as (typeof ARRAY_CALLBACK_METHODS)[number]\r\n )\r\n ) {\r\n return;\r\n }\r\n\r\n // The callback is the first argument for all methods except reduce where it's also the first\r\n const callback = node.arguments[0];\r\n if (!callback) {\r\n return;\r\n }\r\n\r\n if (isAsyncCallback(callback)) {\r\n // Don't flag if the array method call is already wrapped in Promise.all/allSettled/race/any\r\n // e.g., Promise.all(arr.map(async ...)) — this is the correct pattern\r\n if (isWrappedInPromiseCombinator(node, context)) {\r\n return;\r\n }\r\n\r\n if (\r\n METHODS_ALLOWING_PROMISE_COLLECTION.has(methodName) &&\r\n isAssignedAndConsumedByPromiseCombinator(node)\r\n ) {\r\n return;\r\n }\r\n\r\n context.report({\r\n node: callback,\r\n messageId: 'asyncArrayCallback',\r\n data: {\r\n method: methodName,\r\n },\r\n });\r\n }\r\n },\r\n };\r\n },\r\n});\r\n\r\nexport default noAsyncArrayCallback;\r\n","import { ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';\r\nimport type { TSESTree } from '@typescript-eslint/utils';\r\n\r\nconst createRule = ESLintUtils.RuleCreator(\r\n (name) => `https://github.com/YashJadhav21/eslint-plugin-ai-guard/blob/main/docs/rules/${name}.md`\r\n);\r\n\r\nconst KNOWN_PROMISE_FACTORIES = new Set([\r\n 'fetch',\r\n]);\r\n\r\nconst PROMISE_STATIC_METHODS = new Set([\r\n 'resolve',\r\n 'reject',\r\n 'all',\r\n 'allSettled',\r\n 'race',\r\n 'any',\r\n]);\r\n\r\ninterface TypeCheckerLike {\r\n getTypeAtLocation(node: unknown): unknown;\r\n typeToString(type: unknown): string;\r\n getPromisedTypeOfPromise?(type: unknown): unknown;\r\n}\r\n\r\ninterface ProgramLike {\r\n getTypeChecker(): TypeCheckerLike;\r\n}\r\n\r\ninterface ParserServicesLike {\r\n program?: ProgramLike;\r\n esTreeNodeToTSNodeMap?: {\r\n get(node: TSESTree.Node): unknown;\r\n };\r\n}\r\n\r\ninterface VariableLike {\r\n name: string;\r\n defs?: Array<{ node?: TSESTree.Node }>;\r\n}\r\n\r\ninterface ScopeLike {\r\n upper: ScopeLike | null;\r\n set?: Map<string, VariableLike>;\r\n variables?: VariableLike[];\r\n}\r\n\r\ninterface AsyncBindingInfo {\r\n isAsync: boolean;\r\n hasInternalErrorHandling: boolean;\r\n}\r\n\r\nfunction isAstNode(value: unknown): value is TSESTree.Node {\r\n return typeof value === 'object' && value !== null && 'type' in value;\r\n}\r\n\r\nfunction nodeHasCatchClause(node: TSESTree.Node): boolean {\r\n if (node.type === AST_NODE_TYPES.TryStatement && !!node.handler) {\r\n return true;\r\n }\r\n\r\n for (const [key, value] of Object.entries(node as unknown as Record<string, unknown>)) {\r\n if (key === 'parent') continue;\r\n\r\n if (Array.isArray(value)) {\r\n for (const item of value) {\r\n if (isAstNode(item) && nodeHasCatchClause(item)) {\r\n return true;\r\n }\r\n }\r\n continue;\r\n }\r\n\r\n if (isAstNode(value) && nodeHasCatchClause(value)) {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n}\r\n\r\n/**\r\n * Check if a CallExpression's callee is known async via local declarations.\r\n */\r\nfunction isAsyncFunctionLike(node: TSESTree.Node | undefined): boolean {\r\n if (!node) return false;\r\n if (node.type === AST_NODE_TYPES.FunctionDeclaration) {\r\n return node.async;\r\n }\r\n if (\r\n node.type === AST_NODE_TYPES.FunctionExpression ||\r\n node.type === AST_NODE_TYPES.ArrowFunctionExpression\r\n ) {\r\n return node.async;\r\n }\r\n if (\r\n node.type === AST_NODE_TYPES.VariableDeclarator &&\r\n node.init &&\r\n (node.init.type === AST_NODE_TYPES.FunctionExpression ||\r\n node.init.type === AST_NODE_TYPES.ArrowFunctionExpression)\r\n ) {\r\n return node.init.async;\r\n }\r\n return false;\r\n}\r\n\r\nfunction getAsyncBindingInfo(node: TSESTree.Node | undefined): AsyncBindingInfo {\r\n if (!node) {\r\n return { isAsync: false, hasInternalErrorHandling: false };\r\n }\r\n\r\n if (node.type === AST_NODE_TYPES.FunctionDeclaration) {\r\n return {\r\n isAsync: node.async,\r\n hasInternalErrorHandling: node.body ? nodeHasCatchClause(node.body) : false,\r\n };\r\n }\r\n\r\n if (\r\n node.type === AST_NODE_TYPES.FunctionExpression ||\r\n node.type === AST_NODE_TYPES.ArrowFunctionExpression\r\n ) {\r\n return {\r\n isAsync: node.async,\r\n hasInternalErrorHandling:\r\n node.body.type === AST_NODE_TYPES.BlockStatement\r\n ? nodeHasCatchClause(node.body)\r\n : false,\r\n };\r\n }\r\n\r\n if (\r\n node.type === AST_NODE_TYPES.VariableDeclarator &&\r\n node.init &&\r\n (node.init.type === AST_NODE_TYPES.FunctionExpression ||\r\n node.init.type === AST_NODE_TYPES.ArrowFunctionExpression)\r\n ) {\r\n return {\r\n isAsync: node.init.async,\r\n hasInternalErrorHandling:\r\n node.init.body.type === AST_NODE_TYPES.BlockStatement\r\n ? nodeHasCatchClause(node.init.body)\r\n : false,\r\n };\r\n }\r\n\r\n return { isAsync: false, hasInternalErrorHandling: false };\r\n}\r\n\r\nfunction findVariableInScope(scope: ScopeLike, name: string): VariableLike | null {\r\n const fromMap = scope.set?.get(name);\r\n if (fromMap) {\r\n return fromMap;\r\n }\r\n\r\n if (scope.variables) {\r\n const fromArray = scope.variables.find((v) => v.name === name);\r\n if (fromArray) {\r\n return fromArray;\r\n }\r\n }\r\n\r\n return null;\r\n}\r\n\r\nfunction isIdentifierBoundToAsyncFunction(\r\n identifier: TSESTree.Identifier,\r\n context: Readonly<Parameters<ReturnType<typeof createRule>['create']>[0]>,\r\n): AsyncBindingInfo {\r\n let scope = context.sourceCode.getScope(identifier) as unknown as ScopeLike | null;\r\n\r\n while (scope) {\r\n const variable = findVariableInScope(scope, identifier.name);\r\n if (variable) {\r\n const defs = variable.defs ?? [];\r\n for (const def of defs) {\r\n const info = getAsyncBindingInfo(def.node);\r\n if (info.isAsync) {\r\n return info;\r\n }\r\n }\r\n\r\n if (defs.length === 0 && isAsyncFunctionLike(variable as unknown as TSESTree.Node)) {\r\n return getAsyncBindingInfo(variable as unknown as TSESTree.Node);\r\n }\r\n\r\n return { isAsync: false, hasInternalErrorHandling: false };\r\n }\r\n scope = scope.upper;\r\n }\r\n\r\n return { isAsync: false, hasInternalErrorHandling: false };\r\n}\r\n\r\nfunction isLocallyAsyncCallee(\r\n node: TSESTree.CallExpression,\r\n context: Readonly<Parameters<ReturnType<typeof createRule>['create']>[0]>,\r\n): AsyncBindingInfo {\r\n if (node.callee.type === AST_NODE_TYPES.Identifier) {\r\n const info = isIdentifierBoundToAsyncFunction(node.callee, context);\r\n if (info.isAsync) {\r\n return info;\r\n }\r\n }\r\n\r\n if (\r\n (node.callee.type === AST_NODE_TYPES.FunctionExpression ||\r\n node.callee.type === AST_NODE_TYPES.ArrowFunctionExpression) &&\r\n node.callee.async\r\n ) {\r\n return {\r\n isAsync: true,\r\n hasInternalErrorHandling:\r\n node.callee.body.type === AST_NODE_TYPES.BlockStatement\r\n ? nodeHasCatchClause(node.callee.body)\r\n : false,\r\n };\r\n }\r\n\r\n return { isAsync: false, hasInternalErrorHandling: false };\r\n}\r\n\r\nfunction isKnownPromiseFactoryCall(node: TSESTree.CallExpression): boolean {\r\n if (node.callee.type === AST_NODE_TYPES.Identifier) {\r\n return KNOWN_PROMISE_FACTORIES.has(node.callee.name);\r\n }\r\n\r\n if (\r\n node.callee.type === AST_NODE_TYPES.MemberExpression &&\r\n node.callee.object.type === AST_NODE_TYPES.Identifier &&\r\n node.callee.object.name === 'Promise' &&\r\n node.callee.property.type === AST_NODE_TYPES.Identifier\r\n ) {\r\n return PROMISE_STATIC_METHODS.has(node.callee.property.name);\r\n }\r\n\r\n return false;\r\n}\r\n\r\nfunction getParserServices(\r\n context: Readonly<Parameters<ReturnType<typeof createRule>['create']>[0]>,\r\n): ParserServicesLike | null {\r\n const services = context.sourceCode.parserServices as unknown;\r\n if (!services || typeof services !== 'object') {\r\n return null;\r\n }\r\n\r\n return services as ParserServicesLike;\r\n}\r\n\r\nfunction isPromiseLikeByTypeInfo(\r\n node: TSESTree.CallExpression,\r\n context: Readonly<Parameters<ReturnType<typeof createRule>['create']>[0]>,\r\n): boolean {\r\n const services = getParserServices(context);\r\n if (!services?.program || !services.esTreeNodeToTSNodeMap) {\r\n return false;\r\n }\r\n\r\n try {\r\n const tsNode = services.esTreeNodeToTSNodeMap.get(node);\r\n if (!tsNode) {\r\n return false;\r\n }\r\n\r\n const checker = services.program.getTypeChecker();\r\n const type = checker.getTypeAtLocation(tsNode);\r\n\r\n if (typeof checker.getPromisedTypeOfPromise === 'function') {\r\n if (checker.getPromisedTypeOfPromise(type)) {\r\n return true;\r\n }\r\n }\r\n\r\n const text = checker.typeToString(type).toLowerCase();\r\n return (\r\n text === 'promise' ||\r\n text.includes('promise<') ||\r\n text.includes('promiselike<') ||\r\n text.includes('thenable')\r\n );\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Check if the ExpressionStatement is already handled:\r\n * - Used as argument to .then() or .catch()\r\n * - Inside an await\r\n * - Piped to void\r\n * - Result is assigned\r\n */\r\nfunction isExpressionHandled(node: TSESTree.ExpressionStatement): boolean {\r\n const expr = node.expression;\r\n\r\n // Check if the expression is a call chained with .then() or .catch()\r\n if (expr.type === AST_NODE_TYPES.CallExpression) {\r\n if (expr.callee.type === AST_NODE_TYPES.MemberExpression) {\r\n const prop = expr.callee.property;\r\n if (prop.type === AST_NODE_TYPES.Identifier) {\r\n if (prop.name === 'then' || prop.name === 'catch' || prop.name === 'finally') {\r\n return true;\r\n }\r\n }\r\n }\r\n }\r\n\r\n // void operator suppresses the warning intentionally\r\n if (expr.type === AST_NODE_TYPES.UnaryExpression && expr.operator === 'void') {\r\n return true;\r\n }\r\n\r\n return false;\r\n}\r\n\r\nexport const noFloatingPromise = createRule({\r\n name: 'no-floating-promise',\r\n meta: {\r\n type: 'problem',\r\n docs: {\r\n description:\r\n 'Disallow calling an async function or Promise-returning function without awaiting or handling the result. AI tools frequently generate floating promises where errors disappear silently. Includes a safe autofix that marks intentional fire-and-forget calls with void.',\r\n },\r\n fixable: 'code',\r\n schema: [],\r\n messages: {\r\n floatingPromise:\r\n 'This async call is not awaited, returned, or error-handled (.catch). AI tools frequently generate floating promises, causing errors to be silently lost. Add `await`, `.catch()`, or assign the result.',\r\n },\r\n },\r\n defaultOptions: [],\r\n create(context) {\r\n return {\r\n // Check ExpressionStatements — standalone call expressions\r\n ExpressionStatement(node) {\r\n if (\r\n node.expression.type === AST_NODE_TYPES.NewExpression &&\r\n node.expression.callee.type === AST_NODE_TYPES.Identifier &&\r\n node.expression.callee.name === 'Promise'\r\n ) {\r\n context.report({\r\n node,\r\n messageId: 'floatingPromise',\r\n fix: (fixer) =>\r\n fixer.replaceText(\r\n node.expression,\r\n `void ${context.sourceCode.getText(node.expression)}`\r\n ),\r\n });\r\n return;\r\n }\r\n\r\n // We only care about bare CallExpression statements\r\n if (node.expression.type !== AST_NODE_TYPES.CallExpression) {\r\n return;\r\n }\r\n\r\n // If it's already chained with .then()/.catch() or wrapped in void, skip\r\n if (isExpressionHandled(node)) {\r\n return;\r\n }\r\n\r\n const callExpr = node.expression;\r\n const localAsyncInfo = isLocallyAsyncCallee(callExpr, context);\r\n\r\n // If a local async helper already contains its own try/catch,\r\n // calling it fire-and-forget is often intentional in UI effects.\r\n if (localAsyncInfo.isAsync && localAsyncInfo.hasInternalErrorHandling) {\r\n return;\r\n }\r\n\r\n if (\r\n localAsyncInfo.isAsync ||\r\n isKnownPromiseFactoryCall(callExpr) ||\r\n isPromiseLikeByTypeInfo(callExpr, context)\r\n ) {\r\n context.report({\r\n node,\r\n messageId: 'floatingPromise',\r\n fix: (fixer) =>\r\n fixer.replaceText(\r\n node.expression,\r\n `void ${context.sourceCode.getText(node.expression)}`\r\n ),\r\n });\r\n }\r\n },\r\n };\r\n },\r\n});\r\n\r\nexport default noFloatingPromise;\r\n","import { ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';\nimport type { TSESTree, TSESLint } from '@typescript-eslint/utils';\nimport path from 'path';\n\nconst createRule = ESLintUtils.RuleCreator(\n (name) => `https://github.com/YashJadhav21/eslint-plugin-ai-guard/blob/main/docs/rules/${name}.md`\n);\n\nconst LOOP_TYPES = new Set([\n AST_NODE_TYPES.ForStatement,\n AST_NODE_TYPES.ForInStatement,\n AST_NODE_TYPES.ForOfStatement,\n AST_NODE_TYPES.WhileStatement,\n AST_NODE_TYPES.DoWhileStatement,\n]);\n\nconst SUPPRESSION_REGEX = /ai-guard-disable\\s+no-await-in-loop\\b/i;\n\nconst RETRY_NAME_REGEX = /(retry|retries|attempt|attempts|fallback|tryagain|recovery)/i;\nconst SEQUENTIAL_DEPENDENCY_NAME_REGEX = /(previous|prev|last|carry|accumulator|stateful)/i;\n// Simulation, animation, and step-by-step patterns — sequential await is intentional\nconst SIMULATION_NAME_REGEX = /(simulat|animat|demo|visuali|step|scene|frame|render|tick|sequence|tutorial|lesson|walk)/i;\n\nconst ERROR_CODE_HINTS = [\n 'access-denied',\n 'timeout',\n 'rate-limit',\n 'not-found',\n];\n\nconst CONTROL_AWAIT_HINTS = [\n 'sleep',\n 'delay',\n 'wait',\n 'throttle',\n 'ratelimit',\n 'backoff',\n];\n\n// Timer calls inside a loop indicate intentional sequencing (animation/polling)\nconst TIMER_FUNCTION_NAMES = new Set([\n 'setinterval',\n 'settimeout',\n 'requestanimationframe',\n 'queuemicrotask',\n 'sleep',\n 'delay',\n 'wait',\n]);\n\nconst MUTATION_METHOD_NAMES = new Set([\n 'push',\n 'pop',\n 'shift',\n 'unshift',\n 'splice',\n 'set',\n 'add',\n 'delete',\n 'clear',\n]);\n\ntype LoopNode =\n | TSESTree.ForStatement\n | TSESTree.ForInStatement\n | TSESTree.ForOfStatement\n | TSESTree.WhileStatement\n | TSESTree.DoWhileStatement;\n\ninterface IntentAnalysis {\n isIndependent: boolean;\n}\n\nfunction isFunctionNode(node: TSESTree.Node): boolean {\n return (\n node.type === AST_NODE_TYPES.FunctionDeclaration ||\n node.type === AST_NODE_TYPES.FunctionExpression ||\n node.type === AST_NODE_TYPES.ArrowFunctionExpression\n );\n}\n\nfunction isNodeLike(value: unknown): value is TSESTree.Node {\n return typeof value === 'object' && value !== null && 'type' in value;\n}\n\nfunction walkNode(\n node: TSESTree.Node,\n visitor: (current: TSESTree.Node) => void,\n skipNestedFunctions: boolean,\n isRoot = true,\n): void {\n visitor(node);\n\n for (const [key, value] of Object.entries(node as unknown as Record<string, unknown>)) {\n if (key === 'parent' || !value) continue;\n\n if (Array.isArray(value)) {\n for (const item of value) {\n if (!isNodeLike(item)) continue;\n if (skipNestedFunctions && !isRoot && isFunctionNode(item)) continue;\n walkNode(item, visitor, skipNestedFunctions, false);\n }\n continue;\n }\n\n if (!isNodeLike(value)) continue;\n if (skipNestedFunctions && !isRoot && isFunctionNode(value)) continue;\n walkNode(value, visitor, skipNestedFunctions, false);\n }\n}\n\nfunction collectPatternNames(pattern: TSESTree.Node, bucket: Set<string>): void {\n if (pattern.type === AST_NODE_TYPES.Identifier) {\n bucket.add(pattern.name);\n return;\n }\n\n if (pattern.type === AST_NODE_TYPES.AssignmentPattern) {\n collectPatternNames(pattern.left, bucket);\n return;\n }\n\n if (pattern.type === AST_NODE_TYPES.RestElement) {\n collectPatternNames(pattern.argument, bucket);\n return;\n }\n\n if (pattern.type === AST_NODE_TYPES.ArrayPattern) {\n for (const element of pattern.elements) {\n if (!element) continue;\n if (element.type === AST_NODE_TYPES.RestElement) {\n collectPatternNames(element.argument, bucket);\n continue;\n }\n collectPatternNames(element, bucket);\n }\n return;\n }\n\n if (pattern.type === AST_NODE_TYPES.ObjectPattern) {\n for (const prop of pattern.properties) {\n if (prop.type === AST_NODE_TYPES.RestElement) {\n collectPatternNames(prop.argument, bucket);\n continue;\n }\n collectPatternNames(prop.value, bucket);\n }\n }\n}\n\nfunction getLoopNodeName(type: AST_NODE_TYPES): string {\n switch (type) {\n case AST_NODE_TYPES.ForStatement:\n return 'for loop';\n case AST_NODE_TYPES.ForInStatement:\n return 'for...in loop';\n case AST_NODE_TYPES.ForOfStatement:\n return 'for...of loop';\n case AST_NODE_TYPES.WhileStatement:\n return 'while loop';\n case AST_NODE_TYPES.DoWhileStatement:\n return 'do...while loop';\n default:\n return 'loop';\n }\n}\n\nfunction hasSuppressionComment(comments: readonly TSESTree.Comment[]): boolean {\n return comments.some((comment) => SUPPRESSION_REGEX.test(comment.value));\n}\n\nfunction hasFileSuppression(sourceCode: Readonly<TSESLint.SourceCode>): boolean {\n return hasSuppressionComment(sourceCode.getAllComments());\n}\n\nfunction hasLoopSuppression(\n loopNode: LoopNode,\n sourceCode: Readonly<TSESLint.SourceCode>,\n): boolean {\n const commentsBefore = sourceCode.getCommentsBefore(loopNode);\n if (hasSuppressionComment(commentsBefore)) {\n return true;\n }\n\n const allComments = sourceCode.getAllComments();\n const nearComments = allComments.filter((comment) => {\n if (!comment.range || !loopNode.range) {\n return false;\n }\n\n const [, commentEnd] = comment.range;\n const [loopStart] = loopNode.range;\n return commentEnd <= loopStart && loopStart - commentEnd < 160;\n });\n\n return hasSuppressionComment(nearComments);\n}\n\nfunction getCalleeName(callee: TSESTree.Node): string | null {\n if (callee.type === AST_NODE_TYPES.Identifier) {\n return callee.name;\n }\n\n if (\n callee.type === AST_NODE_TYPES.MemberExpression &&\n callee.property.type === AST_NODE_TYPES.Identifier\n ) {\n return callee.property.name;\n }\n\n return null;\n}\n\nfunction getRootIdentifierName(node: TSESTree.Node): string | null {\n if (node.type === AST_NODE_TYPES.Identifier) {\n return node.name;\n }\n\n if (node.type === AST_NODE_TYPES.MemberExpression) {\n return getRootIdentifierName(node.object);\n }\n\n return null;\n}\n\nfunction collectLocalBindings(loopNode: LoopNode): Set<string> {\n const bindings = new Set<string>();\n\n if (loopNode.type === AST_NODE_TYPES.ForStatement && loopNode.init?.type === AST_NODE_TYPES.VariableDeclaration) {\n for (const decl of loopNode.init.declarations) {\n collectPatternNames(decl.id, bindings);\n }\n }\n\n if (\n (loopNode.type === AST_NODE_TYPES.ForOfStatement || loopNode.type === AST_NODE_TYPES.ForInStatement) &&\n loopNode.left.type === AST_NODE_TYPES.VariableDeclaration\n ) {\n for (const decl of loopNode.left.declarations) {\n collectPatternNames(decl.id, bindings);\n }\n }\n\n walkNode(\n loopNode.body,\n (node) => {\n if (node.type === AST_NODE_TYPES.VariableDeclarator) {\n collectPatternNames(node.id, bindings);\n }\n\n if (node.type === AST_NODE_TYPES.FunctionDeclaration && node.id) {\n bindings.add(node.id.name);\n }\n },\n true,\n );\n\n return bindings;\n}\n\nfunction collectSiblingStatements(loopNode: LoopNode): TSESTree.Statement[] {\n if (!loopNode.parent || loopNode.parent.type !== AST_NODE_TYPES.BlockStatement) {\n return [];\n }\n\n const siblings = loopNode.parent.body;\n const idx = siblings.findIndex((stmt) => stmt === loopNode);\n if (idx === -1) return [];\n\n const result: TSESTree.Statement[] = [];\n if (idx > 0) result.push(siblings[idx - 1]);\n if (idx < siblings.length - 1) result.push(siblings[idx + 1]);\n return result;\n}\n\nfunction nodeContainsErrorCodeHint(node: TSESTree.Node): boolean {\n let found = false;\n\n walkNode(\n node,\n (current) => {\n if (found) return;\n if (current.type !== AST_NODE_TYPES.Literal || typeof current.value !== 'string') {\n return;\n }\n\n const lower = current.value.toLowerCase();\n if (ERROR_CODE_HINTS.some((hint) => lower.includes(hint))) {\n found = true;\n }\n },\n true,\n );\n\n return found;\n}\n\nfunction analyzeIntent(loopNode: LoopNode): IntentAnalysis {\n if (loopNode.type === AST_NODE_TYPES.ForOfStatement && loopNode.await) {\n return { isIndependent: false };\n }\n\n const localBindings = collectLocalBindings(loopNode);\n const siblingStatements = collectSiblingStatements(loopNode);\n\n let hasRetryNameHint = false;\n let hasCounterIncrement = false;\n let hasEarlyExit = false;\n let hasCatchContinue = false;\n let hasErrorCodeHint = false;\n let hasSequentialDependency = false;\n let hasControlAwait = false;\n\n const checkIdentifierName = (name: string): void => {\n if (RETRY_NAME_REGEX.test(name)) {\n hasRetryNameHint = true;\n }\n\n if (SEQUENTIAL_DEPENDENCY_NAME_REGEX.test(name)) {\n hasSequentialDependency = true;\n }\n\n // Simulation/animation/step names indicate intentional sequential behavior\n if (SIMULATION_NAME_REGEX.test(name)) {\n hasSequentialDependency = true;\n }\n };\n\n walkNode(\n loopNode,\n (node) => {\n if (node.type === AST_NODE_TYPES.Identifier) {\n checkIdentifierName(node.name);\n }\n\n if (node.type === AST_NODE_TYPES.AwaitExpression &&\n node.argument.type === AST_NODE_TYPES.CallExpression\n ) {\n const calleeName = getCalleeName(node.argument.callee);\n if (calleeName) {\n const lower = calleeName.toLowerCase();\n if (CONTROL_AWAIT_HINTS.some((hint) => lower.includes(hint))) {\n hasControlAwait = true;\n }\n // Awaiting a timer function = intentional sequencing\n if (TIMER_FUNCTION_NAMES.has(lower)) {\n hasControlAwait = true;\n }\n }\n }\n\n if (node.type === AST_NODE_TYPES.UpdateExpression) {\n const target = node.argument;\n if (target.type === AST_NODE_TYPES.Identifier) {\n checkIdentifierName(target.name);\n if (RETRY_NAME_REGEX.test(target.name)) {\n hasCounterIncrement = true;\n }\n if (!localBindings.has(target.name)) {\n hasSequentialDependency = true;\n }\n }\n }\n\n if (node.type === AST_NODE_TYPES.AssignmentExpression) {\n if (node.left.type === AST_NODE_TYPES.Identifier) {\n checkIdentifierName(node.left.name);\n if (RETRY_NAME_REGEX.test(node.left.name)) {\n hasCounterIncrement = true;\n }\n if (!localBindings.has(node.left.name)) {\n hasSequentialDependency = true;\n }\n }\n\n if (node.left.type === AST_NODE_TYPES.MemberExpression) {\n const root = getRootIdentifierName(node.left.object);\n if (root && !localBindings.has(root)) {\n hasSequentialDependency = true;\n }\n }\n }\n\n if (\n node.type === AST_NODE_TYPES.ReturnStatement ||\n node.type === AST_NODE_TYPES.BreakStatement ||\n node.type === AST_NODE_TYPES.ContinueStatement\n ) {\n hasEarlyExit = true;\n }\n\n if (node.type === AST_NODE_TYPES.TryStatement && node.handler) {\n let catchHasContinue = false;\n walkNode(\n node.handler.body,\n (catchNode) => {\n if (catchNode.type === AST_NODE_TYPES.ContinueStatement) {\n catchHasContinue = true;\n }\n },\n true,\n );\n\n if (catchHasContinue) {\n hasCatchContinue = true;\n }\n }\n\n if (node.type === AST_NODE_TYPES.CallExpression) {\n if (\n node.callee.type === AST_NODE_TYPES.MemberExpression &&\n node.callee.property.type === AST_NODE_TYPES.Identifier\n ) {\n const method = node.callee.property.name.toLowerCase();\n if (MUTATION_METHOD_NAMES.has(method)) {\n const root = getRootIdentifierName(node.callee.object);\n if (root && !localBindings.has(root)) {\n hasSequentialDependency = true;\n }\n }\n }\n }\n\n if (node.type === AST_NODE_TYPES.Literal && typeof node.value === 'string') {\n const lower = node.value.toLowerCase();\n if (ERROR_CODE_HINTS.some((hint) => lower.includes(hint))) {\n hasErrorCodeHint = true;\n }\n }\n },\n true,\n );\n\n if (!hasRetryNameHint && siblingStatements.length > 0) {\n for (const sibling of siblingStatements) {\n if (nodeContainsErrorCodeHint(sibling)) {\n hasErrorCodeHint = true;\n }\n\n walkNode(\n sibling,\n (node) => {\n if (node.type === AST_NODE_TYPES.Identifier) {\n checkIdentifierName(node.name);\n }\n },\n true,\n );\n }\n }\n\n const hasRetryOrFallbackIntent =\n hasRetryNameHint ||\n hasCounterIncrement ||\n hasEarlyExit ||\n hasCatchContinue ||\n hasErrorCodeHint ||\n hasSequentialDependency ||\n hasControlAwait;\n\n return {\n isIndependent: !hasRetryOrFallbackIntent,\n };\n}\n\nfunction getLoopBodyStatements(loopNode: LoopNode): TSESTree.Statement[] {\n return loopNode.body.type === AST_NODE_TYPES.BlockStatement\n ? loopNode.body.body\n : [loopNode.body];\n}\n\nfunction getForOfParamName(loopNode: TSESTree.ForOfStatement): string | null {\n if (loopNode.left.type === AST_NODE_TYPES.Identifier) {\n return loopNode.left.name;\n }\n\n if (loopNode.left.type === AST_NODE_TYPES.VariableDeclaration) {\n if (loopNode.left.declarations.length !== 1) return null;\n const id = loopNode.left.declarations[0].id;\n if (id.type !== AST_NODE_TYPES.Identifier) return null;\n return id.name;\n }\n\n return null;\n}\n\nfunction buildSafeAutofix(\n loopNode: LoopNode,\n awaitNode: TSESTree.AwaitExpression,\n sourceCode: Readonly<TSESLint.SourceCode>,\n): string | null {\n if (\n !loopNode.parent ||\n loopNode.parent.type !== AST_NODE_TYPES.BlockStatement ||\n !loopNode.parent.parent ||\n !isFunctionNode(loopNode.parent.parent)\n ) {\n return null;\n }\n\n if (loopNode.type !== AST_NODE_TYPES.ForOfStatement || loopNode.await) {\n return null;\n }\n\n const loopStatements = getLoopBodyStatements(loopNode);\n if (loopStatements.length !== 1) {\n return null;\n }\n\n const onlyStatement = loopStatements[0];\n if (\n onlyStatement.type !== AST_NODE_TYPES.ExpressionStatement ||\n onlyStatement.expression.type !== AST_NODE_TYPES.AwaitExpression ||\n onlyStatement.expression !== awaitNode ||\n onlyStatement.expression.argument.type !== AST_NODE_TYPES.CallExpression\n ) {\n return null;\n }\n\n const paramName = getForOfParamName(loopNode);\n if (!paramName) {\n return null;\n }\n\n const iterableText = sourceCode.getText(loopNode.right);\n const awaitedCallText = sourceCode.getText(onlyStatement.expression.argument);\n\n return `await Promise.all(${iterableText}.map(async (${paramName}) => await ${awaitedCallText}));`;\n}\n\nexport const noAwaitInLoop = createRule({\n name: 'no-await-in-loop',\n meta: {\n type: 'suggestion',\n docs: {\n description:\n 'Disallow independent `await` usage inside loops, while allowing intentional retry/fallback/sequential workflows. AI tools frequently generate accidental sequential awaits where Promise.all would be safer and faster. Includes a safe autofix for simple independent loops.',\n },\n fixable: 'code',\n schema: [\n {\n type: 'object',\n properties: {\n allowPatterns: {\n type: 'array',\n items: { type: 'string' },\n description: 'File glob patterns to skip (e.g., **/*.test.ts, **/simulation/**)',\n },\n },\n additionalProperties: false,\n },\n ],\n messages: {\n awaitInLoop:\n 'Sequential `await` inside a {{loopType}} — if these items are independent, consider `Promise.all()` for parallel execution. If sequential order matters, this may be intentional.',\n },\n },\n defaultOptions: [{}],\n create(context, [options]) {\n if (hasFileSuppression(context.sourceCode)) {\n return {};\n }\n\n // File-level suppression: test files and simulation/demo files use sequential await intentionally\n const filename = context.filename ?? context.getFilename?.() ?? '';\n const fileBasename = path.basename(filename).toLowerCase();\n const filePath = filename.toLowerCase();\n\n const isTestFile =\n fileBasename.includes('.test.') ||\n fileBasename.includes('.spec.') ||\n filePath.includes('/__tests__/') ||\n filePath.includes('/test/') ||\n filePath.includes('/tests/');\n\n const isSimulationFile =\n SIMULATION_NAME_REGEX.test(fileBasename) ||\n filePath.includes('/simulation/') ||\n filePath.includes('/demo/') ||\n filePath.includes('/animation/') ||\n filePath.includes('/fixtures/');\n\n // Suppress entirely for test and simulation files\n if (isTestFile || isSimulationFile) {\n return {};\n }\n\n // Check user-provided allowPatterns (basic suffix/substring matching)\n const { allowPatterns = [] } = options as { allowPatterns?: string[] };\n for (const pattern of allowPatterns) {\n // Simple pattern: if file path contains the non-glob part\n const cleaned = pattern.replace(/\\*\\*/g, '').replace(/\\*/g, '').replace(/\\//g, path.sep);\n if (cleaned && filePath.includes(cleaned.toLowerCase())) {\n return {};\n }\n }\n\n const loopIntentCache = new WeakMap<LoopNode, IntentAnalysis>();\n const reportedLoops = new WeakSet<LoopNode>();\n\n /**\n * Track ancestor scope boundaries (functions) so we don't flag await\n * expressions inside a nested async function that happens to be inside a loop.\n */\n const functionBoundary: TSESTree.Node[] = [];\n\n function enterFunction(node: TSESTree.Node) {\n functionBoundary.push(node);\n }\n function exitFunction() {\n functionBoundary.pop();\n }\n\n return {\n FunctionDeclaration: enterFunction,\n FunctionExpression: enterFunction,\n ArrowFunctionExpression: enterFunction,\n 'FunctionDeclaration:exit': exitFunction,\n 'FunctionExpression:exit': exitFunction,\n 'ArrowFunctionExpression:exit': exitFunction,\n\n AwaitExpression(node) {\n // Walk up ancestors looking for a loop, but stop at any function boundary\n const ancestors = context.sourceCode.getAncestors(node);\n const currentFunction = functionBoundary[functionBoundary.length - 1];\n\n let enclosingLoop: LoopNode | null = null;\n for (let i = ancestors.length - 1; i >= 0; i--) {\n const ancestor = ancestors[i];\n\n // Stop if we hit the current function boundary\n if (ancestor === currentFunction) {\n break;\n }\n\n if (LOOP_TYPES.has(ancestor.type as AST_NODE_TYPES)) {\n enclosingLoop = ancestor as LoopNode;\n break;\n }\n }\n\n if (!enclosingLoop) {\n return;\n }\n\n if (reportedLoops.has(enclosingLoop)) {\n return;\n }\n\n if (hasLoopSuppression(enclosingLoop, context.sourceCode)) {\n return;\n }\n\n const intent = loopIntentCache.get(enclosingLoop) ?? analyzeIntent(enclosingLoop);\n loopIntentCache.set(enclosingLoop, intent);\n\n // Intent-aware behavior:\n // retry/fallback/sequential loops are suppressed (no report).\n if (!intent.isIndependent) {\n return;\n }\n\n const fixText = buildSafeAutofix(enclosingLoop, node, context.sourceCode);\n const loopName = getLoopNodeName(enclosingLoop.type as AST_NODE_TYPES);\n\n context.report({\n node,\n messageId: 'awaitInLoop',\n data: { loopType: loopName },\n fix:\n fixText === null\n ? undefined\n : (fixer) => fixer.replaceText(enclosingLoop as unknown as TSESTree.Node, fixText),\n });\n\n reportedLoops.add(enclosingLoop);\n },\n };\n },\n});\n\nexport default noAwaitInLoop;\n","import { ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';\nimport type { TSESTree, TSESLint } from '@typescript-eslint/utils';\nimport path from 'path';\n\nconst createRule = ESLintUtils.RuleCreator(\n (name) => `https://github.com/YashJadhav21/eslint-plugin-ai-guard/blob/main/docs/rules/${name}.md`\n);\n\n// ─── Framework file patterns ────────────────────────────────────────────────\n// Files where async-without-await is a framework convention, not a mistake.\n// Next.js App Router, middleware, and page conventions.\n\nconst FRAMEWORK_FILE_PATTERNS = [\n // Next.js App Router\n /[/\\\\]route\\.(ts|js|tsx|jsx)$/,\n /[/\\\\]middleware\\.(ts|js)$/,\n /[/\\\\]layout\\.(tsx|jsx|ts|js)$/,\n /[/\\\\]page\\.(tsx|jsx|ts|js)$/,\n /[/\\\\]loading\\.(tsx|jsx|ts|js)$/,\n /[/\\\\]error\\.(tsx|jsx|ts|js)$/,\n /[/\\\\]not-found\\.(tsx|jsx|ts|js)$/,\n /[/\\\\]template\\.(tsx|jsx|ts|js)$/,\n // Next.js Pages Router conventions\n /[/\\\\]_app\\.(tsx|jsx)$/,\n /[/\\\\]_document\\.(tsx|jsx)$/,\n];\n\n// HTTP method export names — always valid async in route files\nconst HTTP_METHOD_EXPORTS = new Set([\n 'GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS',\n]);\n\n// React UI file extensions — handle* functions are conventionally async\nconst REACT_FILE_EXTENSIONS = new Set(['.tsx', '.jsx']);\n\n// Names that strongly suggest the function is an event handler by convention\nconst HANDLER_NAME_REGEX = /^(handle|on[A-Z])/;\n\n// Names that suggest the function is middleware or a lifecycle hook\nconst MIDDLEWARE_NAME_REGEX = /^(use[A-Z]|middleware|interceptor|guard|beforeEach|afterEach)/;\n\n// ─── Heuristics ─────────────────────────────────────────────────────────────\n\nfunction containsAwaitExpression(node: TSESTree.Node): boolean {\n if (node.type === AST_NODE_TYPES.AwaitExpression) {\n return true;\n }\n\n if (node.type === AST_NODE_TYPES.ForOfStatement && node.await) {\n return true;\n }\n\n // Do not count await expressions inside nested functions.\n if (\n node.type === AST_NODE_TYPES.FunctionDeclaration ||\n node.type === AST_NODE_TYPES.FunctionExpression ||\n node.type === AST_NODE_TYPES.ArrowFunctionExpression\n ) {\n return false;\n }\n\n const entries = Object.entries(node) as Array<[string, unknown]>;\n for (const [key, value] of entries) {\n if (key === 'parent') {\n continue;\n }\n\n if (Array.isArray(value)) {\n for (const child of value) {\n if (child && typeof child === 'object' && 'type' in child) {\n if (containsAwaitExpression(child as TSESTree.Node)) {\n return true;\n }\n }\n }\n continue;\n }\n\n if (value && typeof value === 'object' && 'type' in value) {\n if (containsAwaitExpression(value as TSESTree.Node)) {\n return true;\n }\n }\n }\n\n return false;\n}\n\n/**\n * Returns true if the function body is a single return statement that directly\n * calls a function (pass-through wrapper pattern).\n * Example: async function wrap() { return someApi(); }\n * These are intentionally async for Promise propagation — low-confidence finding.\n */\nfunction isPassThroughWrapper(\n node:\n | TSESTree.FunctionDeclaration\n | TSESTree.FunctionExpression\n | TSESTree.ArrowFunctionExpression,\n): boolean {\n if (node.body.type !== AST_NODE_TYPES.BlockStatement) {\n // Arrow with expression body: async () => foo() — pass-through\n const body = node.body;\n if (\n body.type === AST_NODE_TYPES.CallExpression ||\n body.type === AST_NODE_TYPES.MemberExpression\n ) {\n return true;\n }\n return false;\n }\n\n if (node.body.body.length !== 1) return false;\n const only = node.body.body[0];\n if (only.type !== AST_NODE_TYPES.ReturnStatement) return false;\n if (!only.argument) return false;\n\n // Return of a call expression — likely pass-through\n return only.argument.type === AST_NODE_TYPES.CallExpression;\n}\n\n/**\n * Check if this is a framework-required async export.\n * Next.js App Router requires GET/POST/etc handlers to be async even if they\n * use synchronous APIs internally.\n */\nfunction isFunctionExportedWithHttpMethodName(\n node:\n | TSESTree.FunctionDeclaration\n | TSESTree.FunctionExpression\n | TSESTree.ArrowFunctionExpression,\n): boolean {\n // Named function declaration: export async function GET() {}\n if (node.type === AST_NODE_TYPES.FunctionDeclaration && node.id) {\n return HTTP_METHOD_EXPORTS.has(node.id.name);\n }\n\n // Variable declaration: export const GET = async () => {}\n if (node.parent?.type === AST_NODE_TYPES.VariableDeclarator) {\n const declarator = node.parent;\n if (\n declarator.id.type === AST_NODE_TYPES.Identifier &&\n HTTP_METHOD_EXPORTS.has(declarator.id.name)\n ) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Get the function name for heuristic checks.\n */\nfunction getFunctionName(\n node:\n | TSESTree.FunctionDeclaration\n | TSESTree.FunctionExpression\n | TSESTree.ArrowFunctionExpression,\n): string | null {\n if (node.type === AST_NODE_TYPES.FunctionDeclaration && node.id) {\n return node.id.name;\n }\n\n if (node.parent?.type === AST_NODE_TYPES.VariableDeclarator) {\n const declarator = node.parent;\n if (declarator.id.type === AST_NODE_TYPES.Identifier) {\n return declarator.id.name;\n }\n }\n\n if (\n node.parent?.type === AST_NODE_TYPES.Property ||\n node.parent?.type === AST_NODE_TYPES.MethodDefinition\n ) {\n const parent = node.parent;\n if (\n 'key' in parent &&\n parent.key.type === AST_NODE_TYPES.Identifier\n ) {\n return parent.key.name;\n }\n }\n\n return null;\n}\n\n// ─── Schema options ───────────────────────────────────────────────────────────\n\nexport interface RuleOptions {\n allowedFunctionNames?: string[];\n frameworkFiles?: string[];\n ignorePassThroughWrappers?: boolean;\n ignoreHandlerFunctions?: boolean;\n}\n\nexport const noAsyncWithoutAwait = createRule<[RuleOptions], 'asyncWithoutAwait' | 'asyncPassThrough'>({\n name: 'no-async-without-await',\n meta: {\n type: 'suggestion',\n docs: {\n description:\n 'Disallow async functions that never use await. AI tools frequently add async by default, creating misleading signatures and unnecessary Promise wrappers. Framework-specific async conventions (Next.js route handlers, React event handlers) are excluded.',\n },\n fixable: 'code',\n schema: [\n {\n type: 'object',\n properties: {\n allowedFunctionNames: {\n type: 'array',\n items: { type: 'string' },\n description: 'Additional function names to skip (on top of HTTP methods)',\n },\n frameworkFiles: {\n type: 'array',\n items: { type: 'string' },\n description: 'Additional file glob patterns where async-without-await is allowed',\n },\n ignorePassThroughWrappers: {\n type: 'boolean',\n description: 'Downgrade (not suppress) pass-through wrappers. Default: true.',\n },\n ignoreHandlerFunctions: {\n type: 'boolean',\n description: 'Skip functions named handle* or on* in .tsx/.jsx files. Default: true.',\n },\n },\n additionalProperties: false,\n },\n ],\n messages: {\n asyncWithoutAwait:\n 'Async function does not contain `await`. AI tools frequently add `async` unnecessarily, which can mislead callers and mask intent. Remove `async` or add proper await logic.',\n asyncPassThrough:\n 'Async pass-through wrapper — this may be intentional for Promise propagation. Consider whether `async` is needed here.',\n },\n },\n defaultOptions: [{}],\n create(context, [options]) {\n const {\n allowedFunctionNames = [],\n ignorePassThroughWrappers = true,\n ignoreHandlerFunctions = true,\n } = options;\n\n // All HTTP methods + user-provided names are always skipped\n const skipNames = new Set([...HTTP_METHOD_EXPORTS, ...allowedFunctionNames]);\n\n // Check if we're in a framework file (suppress entirely)\n const filename = context.filename ?? context.getFilename?.() ?? '';\n const fileExt = path.extname(filename).toLowerCase();\n\n const isFrameworkFile = FRAMEWORK_FILE_PATTERNS.some((pattern) => pattern.test(filename));\n const isReactFile = REACT_FILE_EXTENSIONS.has(fileExt);\n\n function buildSafeAutofix(\n node:\n | TSESTree.FunctionDeclaration\n | TSESTree.FunctionExpression\n | TSESTree.ArrowFunctionExpression,\n ): ((fixer: TSESLint.RuleFixer) => TSESLint.RuleFix | null) | undefined {\n const sourceCode = context.sourceCode;\n\n if (node.body.type !== AST_NODE_TYPES.BlockStatement) {\n const exprText = sourceCode.getText(node.body);\n return (fixer) => fixer.replaceText(node.body, `await (${exprText})`);\n }\n\n if (node.body.body.length !== 1) {\n return undefined;\n }\n\n const onlyStatement = node.body.body[0];\n\n if (\n onlyStatement.type === AST_NODE_TYPES.ReturnStatement &&\n onlyStatement.argument &&\n onlyStatement.argument.type !== AST_NODE_TYPES.AwaitExpression\n ) {\n const returnValueText = sourceCode.getText(onlyStatement.argument);\n return (fixer) =>\n fixer.replaceText(onlyStatement.argument as TSESTree.Node, `await (${returnValueText})`);\n }\n\n if (onlyStatement.type === AST_NODE_TYPES.ExpressionStatement) {\n const exprText = sourceCode.getText(onlyStatement.expression);\n return (fixer) =>\n fixer.replaceText(onlyStatement.expression as TSESTree.Node, `await (${exprText})`);\n }\n\n return undefined;\n }\n\n function reportIfNeeded(\n node:\n | TSESTree.FunctionDeclaration\n | TSESTree.FunctionExpression\n | TSESTree.ArrowFunctionExpression\n ): void {\n if (!node.async) {\n return;\n }\n\n // 1. Framework file suppression — entirely skip\n if (isFrameworkFile) {\n return;\n }\n\n // 2. HTTP method export suppression — GET/POST/etc are always async by convention\n if (isFunctionExportedWithHttpMethodName(node)) {\n return;\n }\n\n // 3. Function name suppression\n const funcName = getFunctionName(node);\n if (funcName && skipNames.has(funcName)) {\n return;\n }\n\n // 4. Middleware/lifecycle names — often async by convention\n if (funcName && MIDDLEWARE_NAME_REGEX.test(funcName)) {\n return;\n }\n\n // 5. React handler functions in .tsx/.jsx — handle* and on* are async by convention\n if (ignoreHandlerFunctions && isReactFile && funcName && HANDLER_NAME_REGEX.test(funcName)) {\n return;\n }\n\n // Check for await\n const bodyHasAwait =\n node.body.type === AST_NODE_TYPES.BlockStatement\n ? containsAwaitExpression(node.body)\n : node.body.type === AST_NODE_TYPES.AwaitExpression;\n\n if (bodyHasAwait) {\n return;\n }\n\n // 6. Pass-through wrapper — downgrade severity to informational, not a full error\n if (ignorePassThroughWrappers && isPassThroughWrapper(node)) {\n context.report({\n node,\n messageId: 'asyncPassThrough',\n // No autofix for pass-through — it's intentional\n });\n return;\n }\n\n // Arrow with non-block body that is not an AwaitExpression\n if (node.body.type !== AST_NODE_TYPES.BlockStatement) {\n if (node.body.type !== AST_NODE_TYPES.AwaitExpression) {\n const fix = buildSafeAutofix(node);\n context.report({\n node,\n messageId: 'asyncWithoutAwait',\n fix,\n });\n }\n return;\n }\n\n // Block body with no await\n const fix = buildSafeAutofix(node);\n context.report({\n node,\n messageId: 'asyncWithoutAwait',\n fix,\n });\n }\n\n return {\n FunctionDeclaration: reportIfNeeded,\n FunctionExpression: reportIfNeeded,\n ArrowFunctionExpression: reportIfNeeded,\n };\n },\n});\n\nexport default noAsyncWithoutAwait;\n","import { ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';\r\nimport type { TSESTree } from '@typescript-eslint/utils';\r\n\r\nconst createRule = ESLintUtils.RuleCreator(\r\n (name) => `https://github.com/YashJadhav21/eslint-plugin-ai-guard/blob/main/docs/rules/${name}.md`\r\n);\r\n\r\nfunction isInsideTryLikeBlock(\r\n returnNode: TSESTree.ReturnStatement,\r\n context: Readonly<Parameters<ReturnType<typeof createRule>['create']>[0]>\r\n): boolean {\r\n const ancestors = context.sourceCode.getAncestors(returnNode);\r\n\r\n for (let i = ancestors.length - 1; i >= 0; i -= 1) {\r\n const ancestor = ancestors[i];\r\n\r\n if (\r\n ancestor.type === AST_NODE_TYPES.FunctionDeclaration ||\r\n ancestor.type === AST_NODE_TYPES.FunctionExpression ||\r\n ancestor.type === AST_NODE_TYPES.ArrowFunctionExpression\r\n ) {\r\n break;\r\n }\r\n\r\n if (ancestor.type === AST_NODE_TYPES.TryStatement) {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n}\r\n\r\nfunction isInsideAsyncFunction(\r\n returnNode: TSESTree.ReturnStatement,\r\n context: Readonly<Parameters<ReturnType<typeof createRule>['create']>[0]>\r\n): boolean {\r\n const ancestors = context.sourceCode.getAncestors(returnNode);\r\n\r\n for (let i = ancestors.length - 1; i >= 0; i -= 1) {\r\n const ancestor = ancestors[i];\r\n if (\r\n ancestor.type === AST_NODE_TYPES.FunctionDeclaration ||\r\n ancestor.type === AST_NODE_TYPES.FunctionExpression ||\r\n ancestor.type === AST_NODE_TYPES.ArrowFunctionExpression\r\n ) {\r\n return ancestor.async;\r\n }\r\n }\r\n\r\n return false;\r\n}\r\n\r\nexport const noRedundantAwait = createRule({\r\n name: 'no-redundant-await',\r\n meta: {\r\n type: 'suggestion',\r\n docs: {\r\n description:\r\n 'Disallow `return await` in async functions when not inside try/catch/finally. AI tools frequently emit this pattern even when it adds no behavioral value and extra microtask overhead.',\r\n },\r\n fixable: undefined,\r\n schema: [],\r\n messages: {\r\n redundantAwait:\r\n 'Redundant `return await` detected. AI tools frequently generate this pattern. Return the Promise directly unless you need await for try/catch behavior.',\r\n },\r\n },\r\n defaultOptions: [],\r\n create(context) {\r\n return {\r\n ReturnStatement(node) {\r\n if (!node.argument || node.argument.type !== AST_NODE_TYPES.AwaitExpression) {\r\n return;\r\n }\r\n\r\n if (!isInsideAsyncFunction(node, context)) {\r\n return;\r\n }\r\n\r\n if (isInsideTryLikeBlock(node, context)) {\r\n return;\r\n }\r\n\r\n context.report({\r\n node: node.argument,\r\n messageId: 'redundantAwait',\r\n });\r\n },\r\n\r\n ArrowFunctionExpression(node) {\r\n if (!node.async || node.body.type !== AST_NODE_TYPES.AwaitExpression) {\r\n return;\r\n }\r\n\r\n context.report({\r\n node: node.body,\r\n messageId: 'redundantAwait',\r\n });\r\n },\r\n };\r\n },\r\n});\r\n\r\nexport default noRedundantAwait;\r\n","import { ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';\nimport type { TSESTree } from '@typescript-eslint/utils';\n\nconst createRule = ESLintUtils.RuleCreator(\n (name) => `https://github.com/YashJadhav21/eslint-plugin-ai-guard/blob/main/docs/rules/${name}.md`\n);\n\n\n\n/**\n * Variable name patterns that suggest secrets.\n */\nconst SECRET_NAME_PATTERN = /(?:secret|password|passwd|api[_-]?key|auth[_-]?token|access[_-]?token|private[_-]?key|client[_-]?secret|jwt[_-]?secret|encryption[_-]?key|signing[_-]?key)/i;\n\n/**\n * Patterns that are definitely NOT secrets — common false positives.\n */\nconst FALSE_POSITIVE_VALUES = new Set([\n 'password',\n 'secret',\n 'token',\n 'key',\n 'api_key',\n 'apikey',\n '',\n 'undefined',\n 'null',\n 'test',\n 'example',\n 'placeholder',\n 'changeme',\n 'your-api-key',\n 'your-secret',\n 'YOUR_API_KEY',\n 'YOUR_SECRET',\n 'xxx',\n 'TODO',\n]);\n\nexport const noHardcodedSecret = createRule({\n name: 'no-hardcoded-secret',\n meta: {\n type: 'problem',\n docs: {\n description:\n 'Disallow hardcoded secrets, API keys, passwords, and tokens in source code. AI tools frequently generate placeholder credentials that get committed to version control, creating security vulnerabilities. Includes a safe autofix that replaces literals with process.env lookups.',\n },\n fixable: 'code',\n schema: [],\n messages: {\n hardcodedSecret:\n 'Possible hardcoded secret in variable `{{name}}`. AI tools frequently generate placeholder credentials that get committed to version control. Use environment variables (e.g., `process.env.{{envName}}`) instead.',\n },\n },\n defaultOptions: [],\n create(context) {\n return {\n VariableDeclarator(node) {\n // Only check: const SECRET = 'literal_value'\n if (!node.init) return;\n if (!node.id || node.id.type !== AST_NODE_TYPES.Identifier) return;\n\n const initNode = node.init;\n\n const varName = node.id.name;\n\n // Check if variable name suggests a secret\n if (!SECRET_NAME_PATTERN.test(varName)) return;\n\n // Only flag string literals and template literals with no expressions\n const value = getStringValue(initNode);\n if (value === null) return;\n\n // Skip obviously fake/placeholder values\n if (FALSE_POSITIVE_VALUES.has(value)) return;\n if (value.length < 8) return;\n\n // Skip process.env references (already using env vars)\n if (isProcessEnvAccess(initNode)) return;\n\n context.report({\n node: initNode,\n messageId: 'hardcodedSecret',\n data: {\n name: varName,\n envName: toEnvVarName(varName),\n },\n fix: (fixer) =>\n fixer.replaceText(\n initNode,\n getProcessEnvAccessText(toEnvVarName(varName))\n ),\n });\n },\n\n // Also check: obj.secret = 'literal_value'\n AssignmentExpression(node) {\n if (node.left.type !== AST_NODE_TYPES.MemberExpression) return;\n if (node.left.property.type !== AST_NODE_TYPES.Identifier) return;\n\n const propName = node.left.property.name;\n if (!SECRET_NAME_PATTERN.test(propName)) return;\n\n const value = getStringValue(node.right);\n if (value === null) return;\n if (FALSE_POSITIVE_VALUES.has(value)) return;\n if (value.length < 8) return;\n if (isProcessEnvAccess(node.right)) return;\n\n context.report({\n node: node.right,\n messageId: 'hardcodedSecret',\n data: {\n name: propName,\n envName: toEnvVarName(propName),\n },\n fix: (fixer) =>\n fixer.replaceText(\n node.right,\n getProcessEnvAccessText(toEnvVarName(propName))\n ),\n });\n },\n\n // Check property assignments in object literals: { secret: 'value' }\n Property(node) {\n if (node.key.type !== AST_NODE_TYPES.Identifier) return;\n if (isRuleMetaMessagesProperty(node)) return;\n\n const propName = node.key.name;\n if (!SECRET_NAME_PATTERN.test(propName)) return;\n\n const valueNode = node.value as TSESTree.Expression;\n const value = getStringValue(valueNode);\n if (value === null) return;\n if (FALSE_POSITIVE_VALUES.has(value)) return;\n if (value.length < 8) return;\n if (isProcessEnvAccess(valueNode)) return;\n\n context.report({\n node: valueNode,\n messageId: 'hardcodedSecret',\n data: {\n name: propName,\n envName: toEnvVarName(propName),\n },\n fix: (fixer) =>\n fixer.replaceText(\n valueNode,\n getProcessEnvAccessText(toEnvVarName(propName))\n ),\n });\n },\n };\n },\n});\n\nfunction getStringValue(node: TSESTree.Expression): string | null {\n if (node.type === AST_NODE_TYPES.Literal && typeof node.value === 'string') {\n return node.value;\n }\n if (\n node.type === AST_NODE_TYPES.TemplateLiteral &&\n node.expressions.length === 0 &&\n node.quasis.length === 1\n ) {\n return node.quasis[0].value.cooked ?? null;\n }\n return null;\n}\n\nfunction isRuleMetaMessagesProperty(node: TSESTree.Property): boolean {\n if (!node.parent || node.parent.type !== AST_NODE_TYPES.ObjectExpression) {\n return false;\n }\n\n const parentProperty = node.parent.parent;\n if (!parentProperty || parentProperty.type !== AST_NODE_TYPES.Property) {\n return false;\n }\n\n return (\n parentProperty.key.type === AST_NODE_TYPES.Identifier &&\n parentProperty.key.name === 'messages'\n );\n}\n\nfunction isProcessEnvAccess(node: TSESTree.Expression): boolean {\n return (\n node.type === AST_NODE_TYPES.MemberExpression &&\n node.object.type === AST_NODE_TYPES.MemberExpression &&\n node.object.object.type === AST_NODE_TYPES.Identifier &&\n node.object.object.name === 'process' &&\n node.object.property.type === AST_NODE_TYPES.Identifier &&\n node.object.property.name === 'env'\n );\n}\n\nfunction toEnvVarName(name: string): string {\n // Convert camelCase/PascalCase to UPPER_SNAKE_CASE\n return name\n .replace(/([a-z])([A-Z])/g, '$1_$2')\n .replace(/[-\\s]/g, '_')\n .toUpperCase();\n}\n\nfunction getProcessEnvAccessText(envName: string): string {\n if (/^[A-Z_$][A-Z0-9_$]*$/.test(envName)) {\n return `process.env.${envName}`;\n }\n\n return `process.env['${envName.replace(/'/g, \"\\\\'\")}']`;\n}\n\nexport default noHardcodedSecret;\n","import { ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';\r\nimport type { TSESTree } from '@typescript-eslint/utils';\r\n\r\nconst createRule = ESLintUtils.RuleCreator(\r\n (name) => `https://github.com/YashJadhav21/eslint-plugin-ai-guard/blob/main/docs/rules/${name}.md`\r\n);\r\n\r\nexport const noEvalDynamic = createRule({\r\n name: 'no-eval-dynamic',\r\n meta: {\r\n type: 'problem',\r\n docs: {\r\n description:\r\n 'Disallow `eval()` and `new Function()` with non-literal arguments. AI tools frequently generate dynamic code evaluation patterns that create serious security vulnerabilities including code injection and XSS.',\r\n },\r\n fixable: undefined,\r\n schema: [],\r\n messages: {\r\n evalDynamic:\r\n 'Dangerous use of `{{callee}}` with a dynamic argument. AI tools frequently generate `eval()` or `new Function()` patterns that enable code injection attacks. Use safer alternatives like JSON.parse(), a lookup table, or a sandboxed evaluator.',\r\n newFunctionDynamic:\r\n 'Dangerous use of `new Function()` with a dynamic argument. AI tools frequently generate this pattern which enables arbitrary code execution. Use safer alternatives like a lookup table or pre-defined functions.',\r\n },\r\n },\r\n defaultOptions: [],\r\n create(context) {\r\n return {\r\n CallExpression(node) {\r\n // Check for eval(...)\r\n if (\r\n node.callee.type === AST_NODE_TYPES.Identifier &&\r\n node.callee.name === 'eval'\r\n ) {\r\n // Allow eval() with no args (no-op) or with only literal string args\r\n if (node.arguments.length === 0) return;\r\n\r\n const firstArg = node.arguments[0];\r\n if (isLiteral(firstArg)) return;\r\n\r\n context.report({\r\n node,\r\n messageId: 'evalDynamic',\r\n data: { callee: 'eval()' },\r\n });\r\n return;\r\n }\r\n\r\n // Check for window.eval(...) or globalThis.eval(...)\r\n if (\r\n node.callee.type === AST_NODE_TYPES.MemberExpression &&\r\n node.callee.property.type === AST_NODE_TYPES.Identifier &&\r\n node.callee.property.name === 'eval' &&\r\n node.callee.object.type === AST_NODE_TYPES.Identifier &&\r\n (node.callee.object.name === 'window' || node.callee.object.name === 'globalThis')\r\n ) {\r\n if (node.arguments.length === 0) return;\r\n const firstArg = node.arguments[0];\r\n if (isLiteral(firstArg)) return;\r\n\r\n context.report({\r\n node,\r\n messageId: 'evalDynamic',\r\n data: { callee: `${node.callee.object.name}.eval()` },\r\n });\r\n return;\r\n }\r\n\r\n // Function(...) invoked WITHOUT `new` is semantically identical to\r\n // new Function(...) per ECMA-262 and MDN — `Function('a','return a')(1)`\r\n // executes the body string as code. AI-generated examples sometimes\r\n // drop the `new` because both forms \"work\"; the rule previously hooked\r\n // only NewExpression, letting bare calls through as a code-injection\r\n // FN. Cover Identifier `Function(...)` plus `window.Function(...)` /\r\n // `globalThis.Function(...)`.\r\n if (isFunctionConstructorCallee(node.callee)) {\r\n if (node.arguments.length === 0) return;\r\n const allLiteral = node.arguments.every(isLiteral);\r\n if (allLiteral) return;\r\n\r\n context.report({\r\n node,\r\n messageId: 'newFunctionDynamic',\r\n });\r\n }\r\n },\r\n\r\n NewExpression(node) {\r\n // Check for new Function(...) / new window.Function(...) / new globalThis.Function(...)\r\n if (isFunctionConstructorCallee(node.callee)) {\r\n if (node.arguments.length === 0) return;\r\n\r\n // All arguments must be literals to be safe\r\n const allLiteral = node.arguments.every(isLiteral);\r\n if (allLiteral) return;\r\n\r\n context.report({\r\n node,\r\n messageId: 'newFunctionDynamic',\r\n });\r\n }\r\n },\r\n };\r\n },\r\n});\r\n\r\n/**\r\n * Match the `Function` constructor callee in any of its reachable forms:\r\n * - bare identifier `Function`\r\n * - `window.Function`\r\n * - `globalThis.Function`\r\n * Used for both `new Function(...)` and bare `Function(...)` calls, which are\r\n * semantically identical for the code-injection risk the rule targets.\r\n */\r\nfunction isFunctionConstructorCallee(callee: TSESTree.Node): boolean {\r\n if (callee.type === AST_NODE_TYPES.Identifier && callee.name === 'Function') {\r\n return true;\r\n }\r\n if (\r\n callee.type === AST_NODE_TYPES.MemberExpression &&\r\n callee.property.type === AST_NODE_TYPES.Identifier &&\r\n callee.property.name === 'Function' &&\r\n callee.object.type === AST_NODE_TYPES.Identifier &&\r\n (callee.object.name === 'window' || callee.object.name === 'globalThis')\r\n ) {\r\n return true;\r\n }\r\n return false;\r\n}\r\n\r\n/**\r\n * Check if a node is a static literal (string, number, boolean, null, template literal with no expressions).\r\n */\r\nfunction isLiteral(node: TSESTree.Node): boolean {\r\n if (node.type === AST_NODE_TYPES.Literal) return true;\r\n if (\r\n node.type === AST_NODE_TYPES.TemplateLiteral &&\r\n node.expressions.length === 0\r\n ) {\r\n return true;\r\n }\r\n return false;\r\n}\r\n\r\nexport default noEvalDynamic;\r\n","import { ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';\nimport type { TSESTree } from '@typescript-eslint/utils';\n\nconst createRule = ESLintUtils.RuleCreator(\n (name) => `https://github.com/YashJadhav21/eslint-plugin-ai-guard/blob/main/docs/rules/${name}.md`\n);\n\n/**\n * SQL statement signatures. We intentionally require query-like combinations\n * to avoid false positives for normal app strings (e.g., \"create\", \"from\").\n */\nconst SQL_STATEMENT_PATTERN =\n /\\b(select\\s+[\\s\\S]*\\s+from|insert\\s+into|update\\s+\\S+\\s+set|delete\\s+from|drop\\s+table|create\\s+(table|database)|alter\\s+table|truncate\\s+table|exec(?:ute)?\\s+\\S+|union\\s+select)\\b/i;\n\nconst SQL_SINK_METHODS = new Set([\n 'query',\n 'execute',\n 'queryraw',\n 'queryrawunsafe',\n 'executeraw',\n 'executerawunsafe',\n 'raw',\n 'run',\n 'all',\n 'get',\n 'prepare',\n]);\n\nconst SQL_SINK_FUNCTIONS = new Set(['query', 'execute']);\n\nconst KNOWN_QUERY_BUILDERS = new Set([\n 'knex',\n 'drizzle',\n 'prisma',\n 'kysely',\n 'sequelize',\n 'typeorm',\n 'mikroorm',\n]);\n\nconst QUERY_BUILDER_METHOD_HINTS = new Set([\n 'raw',\n 'query',\n 'execute',\n 'from',\n 'where',\n 'whereraw',\n 'queryraw',\n 'queryrawunsafe',\n 'executeraw',\n 'executerawunsafe',\n 'select',\n 'selectfrom',\n 'insert',\n 'update',\n 'delete',\n 'join',\n 'orderby',\n 'groupby',\n 'having',\n]);\n\nfunction getIdentifierName(node: TSESTree.Node): string | null {\n if (node.type === AST_NODE_TYPES.Identifier) {\n return node.name;\n }\n return null;\n}\n\nfunction isSqlSinkCall(node: TSESTree.CallExpression): boolean {\n if (node.callee.type === AST_NODE_TYPES.Identifier) {\n return SQL_SINK_FUNCTIONS.has(node.callee.name.toLowerCase());\n }\n\n if (\n node.callee.type === AST_NODE_TYPES.MemberExpression &&\n node.callee.property.type === AST_NODE_TYPES.Identifier\n ) {\n const methodName = node.callee.property.name.toLowerCase().replace(/^\\$/, '');\n return SQL_SINK_METHODS.has(methodName);\n }\n\n return false;\n}\n\nfunction normalizeToken(value: string): string {\n return value.toLowerCase().replace(/[^a-z0-9]/g, '');\n}\n\nfunction getMemberPropertyName(\n property: TSESTree.Expression | TSESTree.PrivateIdentifier,\n computed: boolean,\n): string | null {\n if (!computed && property.type === AST_NODE_TYPES.Identifier) {\n return property.name;\n }\n\n if (computed && property.type === AST_NODE_TYPES.Literal && typeof property.value === 'string') {\n return property.value;\n }\n\n return null;\n}\n\nfunction getExpressionPathParts(node: TSESTree.Node): string[] {\n if (node.type === AST_NODE_TYPES.Identifier) {\n return [node.name];\n }\n\n if (node.type === AST_NODE_TYPES.ThisExpression) {\n return ['this'];\n }\n\n if (node.type === AST_NODE_TYPES.CallExpression) {\n return getExpressionPathParts(node.callee);\n }\n\n if (node.type === AST_NODE_TYPES.MemberExpression) {\n const objectParts = getExpressionPathParts(node.object);\n const propertyName = getMemberPropertyName(node.property, node.computed);\n return propertyName ? [...objectParts, propertyName] : objectParts;\n }\n\n if (\n node.type === AST_NODE_TYPES.NewExpression &&\n (node.callee.type === AST_NODE_TYPES.Identifier ||\n node.callee.type === AST_NODE_TYPES.MemberExpression)\n ) {\n return getExpressionPathParts(node.callee);\n }\n\n return [];\n}\n\nfunction isKnownBuilderName(name: string): boolean {\n return KNOWN_QUERY_BUILDERS.has(normalizeToken(name));\n}\n\nfunction isBuilderMethodHint(name: string): boolean {\n return QUERY_BUILDER_METHOD_HINTS.has(normalizeToken(name));\n}\n\nfunction isKnownBuilderBinding(name: string, builderBindings: Set<string>): boolean {\n if (builderBindings.has(name)) {\n return true;\n }\n\n return builderBindings.has(normalizeToken(name));\n}\n\nfunction isKnownBuilderExpression(\n node: TSESTree.Expression,\n builderBindings: Set<string>,\n): boolean {\n if (node.type === AST_NODE_TYPES.Identifier) {\n return isKnownBuilderName(node.name) || isKnownBuilderBinding(node.name, builderBindings);\n }\n\n if (node.type === AST_NODE_TYPES.CallExpression || node.type === AST_NODE_TYPES.NewExpression) {\n const pathParts =\n node.type === AST_NODE_TYPES.CallExpression\n ? getExpressionPathParts(node.callee)\n : getExpressionPathParts(node.callee);\n\n return pathParts.some(\n (part) => isKnownBuilderName(part) || isKnownBuilderBinding(part, builderBindings),\n );\n }\n\n if (node.type === AST_NODE_TYPES.MemberExpression) {\n const pathParts = getExpressionPathParts(node);\n return pathParts.some(\n (part) => isKnownBuilderName(part) || isKnownBuilderBinding(part, builderBindings),\n );\n }\n\n return false;\n}\n\nfunction isKnownQueryBuilderContext(\n node: TSESTree.CallExpression,\n builderBindings: Set<string>,\n): boolean {\n const pathParts = getExpressionPathParts(node.callee);\n if (pathParts.length === 0) {\n return false;\n }\n\n const hasBuilderIdentity = pathParts.some(\n (part) => isKnownBuilderName(part) || isKnownBuilderBinding(part, builderBindings),\n );\n\n if (!hasBuilderIdentity) {\n const rootPart = pathParts[0];\n if (!rootPart || !isKnownBuilderBinding(rootPart, builderBindings)) {\n return false;\n }\n }\n\n return pathParts.some((part) => isBuilderMethodHint(part));\n}\n\nfunction resolveExpression(\n node: TSESTree.Expression,\n variableMap: Map<string, TSESTree.Expression>,\n): TSESTree.Expression {\n const identifier = getIdentifierName(node);\n if (identifier && variableMap.has(identifier)) {\n return variableMap.get(identifier)!;\n }\n return node;\n}\n\nfunction isDynamicSqlExpression(node: TSESTree.Expression): boolean {\n if (node.type === AST_NODE_TYPES.TemplateLiteral) {\n if (node.expressions.length === 0) {\n return false;\n }\n const staticText = node.quasis.map((q) => q.value.raw).join(' ');\n return SQL_STATEMENT_PATTERN.test(staticText);\n }\n\n if (node.type === AST_NODE_TYPES.BinaryExpression && node.operator === '+') {\n const staticText = collectStaticText(node);\n if (!SQL_STATEMENT_PATTERN.test(staticText)) {\n return false;\n }\n return hasDynamicParts(node);\n }\n\n return false;\n}\n\nexport const noSqlStringConcat = createRule({\n name: 'no-sql-string-concat',\n meta: {\n type: 'problem',\n docs: {\n description:\n 'Disallow string concatenation or interpolation with variables in SQL query contexts. AI tools frequently generate SQL queries using template literals or string concatenation with user input, creating SQL injection vulnerabilities.',\n },\n fixable: undefined,\n schema: [],\n messages: {\n sqlStringConcat:\n 'Potential SQL injection: string concatenation or interpolation detected in a SQL query. AI tools frequently generate this pattern. Use parameterized queries (e.g., `db.query(\"SELECT * FROM users WHERE id = $1\", [id])`) instead.',\n },\n },\n defaultOptions: [],\n create(context) {\n const variableMap = new Map<string, TSESTree.Expression>();\n const builderBindings = new Set<string>();\n\n return {\n VariableDeclarator(node) {\n if (node.id.type !== AST_NODE_TYPES.Identifier || !node.init) {\n return;\n }\n\n if (node.init.type === AST_NODE_TYPES.AwaitExpression) {\n builderBindings.delete(node.id.name);\n builderBindings.delete(normalizeToken(node.id.name));\n return;\n }\n\n variableMap.set(node.id.name, node.init);\n\n if (isKnownBuilderExpression(node.init, builderBindings)) {\n builderBindings.add(node.id.name);\n builderBindings.add(normalizeToken(node.id.name));\n return;\n }\n\n builderBindings.delete(node.id.name);\n builderBindings.delete(normalizeToken(node.id.name));\n },\n\n AssignmentExpression(node) {\n if (node.left.type !== AST_NODE_TYPES.Identifier) {\n return;\n }\n\n if (node.right.type === AST_NODE_TYPES.AwaitExpression) {\n builderBindings.delete(node.left.name);\n builderBindings.delete(normalizeToken(node.left.name));\n return;\n }\n\n variableMap.set(node.left.name, node.right);\n\n if (isKnownBuilderExpression(node.right, builderBindings)) {\n builderBindings.add(node.left.name);\n builderBindings.add(normalizeToken(node.left.name));\n return;\n }\n\n builderBindings.delete(node.left.name);\n builderBindings.delete(normalizeToken(node.left.name));\n },\n\n CallExpression(node) {\n if (!isSqlSinkCall(node)) {\n return;\n }\n\n // Avoid false positives for known query-builder chains.\n if (isKnownQueryBuilderContext(node, builderBindings)) {\n return;\n }\n\n const firstArg = node.arguments[0];\n if (!firstArg || firstArg.type === AST_NODE_TYPES.SpreadElement) {\n return;\n }\n\n const resolved = resolveExpression(firstArg, variableMap);\n if (!isDynamicSqlExpression(resolved)) {\n return;\n }\n\n context.report({\n node: firstArg,\n messageId: 'sqlStringConcat',\n });\n },\n };\n },\n});\n\nfunction collectStaticText(node: TSESTree.Expression | TSESTree.PrivateIdentifier): string {\n if (node.type === AST_NODE_TYPES.BinaryExpression && node.operator === '+') {\n return `${collectStaticText(node.left)} ${collectStaticText(node.right)}`;\n }\n\n const literalValue = getStringLiteralValue(node);\n return literalValue ?? '';\n}\n\nfunction hasDynamicParts(node: TSESTree.Expression | TSESTree.PrivateIdentifier): boolean {\n if (node.type === AST_NODE_TYPES.BinaryExpression && node.operator === '+') {\n return hasDynamicParts(node.left) || hasDynamicParts(node.right);\n }\n\n return !isStaticString(node);\n}\n\nfunction getStringLiteralValue(node: TSESTree.Expression | TSESTree.PrivateIdentifier): string | null {\n if (node.type === AST_NODE_TYPES.Literal && typeof node.value === 'string') {\n return node.value;\n }\n return null;\n}\n\nfunction isStaticString(node: TSESTree.Expression | TSESTree.PrivateIdentifier): boolean {\n if (node.type === AST_NODE_TYPES.Literal && typeof node.value === 'string') {\n return true;\n }\n if (\n node.type === AST_NODE_TYPES.TemplateLiteral &&\n node.expressions.length === 0\n ) {\n return true;\n }\n return false;\n}\n\nexport default noSqlStringConcat;\n","import { ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';\r\nimport type { TSESTree } from '@typescript-eslint/utils';\r\n\r\nconst createRule = ESLintUtils.RuleCreator(\r\n (name) => `https://github.com/YashJadhav21/eslint-plugin-ai-guard/blob/main/docs/rules/${name}.md`\r\n);\r\n\r\n// Files where JSON.parse on internal data is expected and safe\r\nconst INTERNAL_FILE_PATTERNS = [\r\n /[\\\\/]debug[\\\\/]/i,\r\n /[\\\\/]scripts[\\\\/]/i,\r\n /[\\\\/]tools[\\\\/]/i,\r\n /[\\\\/]migrations?[\\\\/]/i,\r\n /[\\\\/]seeds?[\\\\/]/i,\r\n /[\\\\/]fixtures[\\\\/]/i,\r\n /\bcheck[-_]server/i,\r\n /\bdebug[-_]server/i,\r\n /\bdiagnostics/i,\r\n /\bseed\\./i,\r\n /\bmigrate?\\./i,\r\n /\bsetup\\./i,\r\n /\bscaffold\\./i,\r\n /\btest[-_].*\\.js$/i,\r\n];\r\n\r\nfunction isInternalToolingFile(filePath: string): boolean {\r\n return INTERNAL_FILE_PATTERNS.some((p) => p.test(filePath));\r\n}\r\n\r\nconst UNTRUSTED_IDENTIFIER_NAMES = [\r\n 'input',\r\n 'userInput',\r\n 'rawBody',\r\n 'payload',\r\n 'body',\r\n 'query',\r\n 'param',\r\n 'params',\r\n 'data',\r\n 'requestBody',\r\n] as const;\r\n\r\nfunction isJsonParseCall(node: TSESTree.CallExpression): boolean {\r\n return (\r\n node.callee.type === AST_NODE_TYPES.MemberExpression &&\r\n node.callee.object.type === AST_NODE_TYPES.Identifier &&\r\n node.callee.object.name === 'JSON' &&\r\n node.callee.property.type === AST_NODE_TYPES.Identifier &&\r\n node.callee.property.name === 'parse'\r\n );\r\n}\r\n\r\nfunction isLikelyUntrustedSource(node: TSESTree.Node): boolean {\r\n if (node.type === AST_NODE_TYPES.Identifier) {\r\n return UNTRUSTED_IDENTIFIER_NAMES.includes(\r\n node.name as (typeof UNTRUSTED_IDENTIFIER_NAMES)[number]\r\n );\r\n }\r\n\r\n if (node.type === AST_NODE_TYPES.MemberExpression) {\r\n // req.body, req.query, req.params, request.body\r\n if (\r\n node.object.type === AST_NODE_TYPES.Identifier &&\r\n ['req', 'request'].includes(node.object.name) &&\r\n node.property.type === AST_NODE_TYPES.Identifier &&\r\n ['body', 'query', 'params'].includes(node.property.name)\r\n ) {\r\n return true;\r\n }\r\n\r\n // window.location.hash/search\r\n if (\r\n node.object.type === AST_NODE_TYPES.MemberExpression &&\r\n node.object.object.type === AST_NODE_TYPES.Identifier &&\r\n node.object.object.name === 'window' &&\r\n node.object.property.type === AST_NODE_TYPES.Identifier &&\r\n node.object.property.name === 'location' &&\r\n node.property.type === AST_NODE_TYPES.Identifier &&\r\n ['hash', 'search'].includes(node.property.name)\r\n ) {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n}\r\n\r\nexport const noUnsafeDeserialize = createRule({\r\n name: 'no-unsafe-deserialize',\r\n meta: {\r\n type: 'suggestion',\r\n docs: {\r\n description:\r\n 'Disallow JSON.parse() on likely untrusted input without visible validation. AI tools frequently parse request/user payloads directly, which can introduce unsafe deserialization and downstream injection risks.',\r\n },\r\n fixable: undefined,\r\n schema: [],\r\n messages: {\r\n unsafeDeserialize:\r\n 'JSON.parse() on likely untrusted input without visible schema validation. Validate or sanitize the input before parsing to prevent deserialization of unexpected data.',\r\n },\r\n },\r\n defaultOptions: [],\r\n create(context) {\r\n // Suppress in internal tooling files where JSON.parse on internal data is expected\r\n const filePath = context.filename ?? context.getFilename?.() ?? '';\r\n if (isInternalToolingFile(filePath)) return {};\r\n\r\n return {\r\n CallExpression(node) {\r\n if (!isJsonParseCall(node)) {\r\n return;\r\n }\r\n\r\n const inputArg = node.arguments[0];\r\n if (!inputArg) {\r\n return;\r\n }\r\n\r\n if (isLikelyUntrustedSource(inputArg)) {\r\n context.report({\r\n node,\r\n messageId: 'unsafeDeserialize',\r\n });\r\n }\r\n },\r\n };\r\n },\r\n});\r\n\r\nexport default noUnsafeDeserialize;\r\n","import { ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';\nimport type { TSESTree } from '@typescript-eslint/utils';\n\nconst createRule = ESLintUtils.RuleCreator(\n (name) => `https://github.com/YashJadhav21/eslint-plugin-ai-guard/blob/main/docs/rules/${name}.md`\n);\n\n/**\n * HTTP methods that define routes in Express/Fastify.\n */\nconst HTTP_METHODS = new Set([\n 'get', 'post', 'put', 'patch', 'delete', 'all', 'options', 'head',\n]);\n\n/**\n * Default authentication middleware names to look for.\n */\nconst DEFAULT_AUTH_MIDDLEWARE_NAMES = new Set([\n 'authenticate',\n 'requireAuth',\n 'isAuthenticated',\n 'verifyToken',\n 'protect',\n 'authorized',\n 'authorize',\n 'isAdmin',\n 'ensureAuthenticated',\n 'ensureLoggedIn',\n 'auth',\n 'authMiddleware',\n 'requireLogin',\n 'checkAuth',\n 'validateToken',\n 'passport.authenticate',\n 'jwt',\n 'requireSession',\n]);\n\n/**\n * Route paths that are commonly public and should not require auth.\n */\nconst PUBLIC_ROUTE_PATTERNS = [\n /^\\/?\\s*$/, // '/' root or empty\n /^\\*$/, // '*' SPA fallback\n /^\\/\\*$/, // '/*' SPA fallback\n /^\\/health/, // health checks\n /^\\/ping/, // ping\n /^\\/status/, // status\n /^\\/metrics/, // Prometheus metrics\n /^\\/ready/, // readiness probe\n /^\\/live/, // liveness probe\n /^\\/api\\/v\\d+\\/auth/, // versioned auth routes\n /^\\/auth/, // auth routes\n /^\\/login/, // login\n /^\\/logout/, // logout\n /^\\/register/, // register\n /^\\/signup/, // signup\n /^\\/forgot/, // forgot password\n /^\\/reset/, // reset password\n /^\\/verify/, // email verification\n /^\\/webhook/, // webhooks (typically verified by signature)\n /^\\/callback/, // OAuth callback\n /^\\/public/, // explicitly public\n /^\\/assets/, // static assets\n /^\\/static/, // static files\n /^\\/favicon/, // favicon\n /^\\/robots/, // robots.txt\n /^\\/sitemap/, // sitemap\n /^\\/api\\/docs/, // API documentation (Swagger, etc.)\n /^\\/docs/, // documentation\n /^\\/swagger/, // Swagger UI\n /^\\/graphql/, // GraphQL (handles own auth)\n /^\\/debug/, // debug endpoints\n /^\\/diagnostics/, // diagnostics endpoints\n /^\\/internal/, // internal routes\n /^\\/dev/, // dev-only routes\n];\n\n// ─── Context detection helpers ─────────────────────────────────────────────────\n//\n// These heuristics determine whether the current file is likely an internal\n// or localhost-only service where auth requirements are different from a\n// production API. False positives in these contexts erode trust.\n\n/**\n * Path segments that suggest an Electron app main/preload/renderer process.\n * In Electron apps, localhost routes serve the renderer — auth is unnecessary.\n */\nconst ELECTRON_PATH_PATTERNS = [\n /[\\\\/]electron[\\\\/]/i,\n /[\\\\/]electron-main/i,\n /[\\\\/]electron-preload/i,\n /\\bmain\\.js$/,\n /\\bpreload\\.js$/,\n /\\bbackground\\.js$/,\n /\\belectron\\.js$/,\n];\n\n/**\n * File name patterns for internal tooling, scripts, and dev utilities.\n * These files are never exposed in production — auth is not relevant.\n */\nconst INTERNAL_SCRIPT_PATTERNS = [\n /[\\\\/]scripts[\\\\/]/i,\n /[\\\\/]tools[\\\\/]/i,\n /[\\\\/]migrations?[\\\\/]/i,\n /[\\\\/]seeds?[\\\\/]/i,\n /[\\\\/]fixtures[\\\\/]/i,\n /[\\\\/]dev[\\\\/]/i,\n /[\\\\/]debug[\\\\/]/i,\n /[\\\\/]diagnostics[\\\\/]/i,\n /\\bdebug[-_]server/i,\n /\\bdev[-_]server/i,\n /\\bcheck[-_]server/i,\n /\\blocal[-_]server/i,\n /\\bseed\\./i,\n /\\bmigrate?\\./i,\n /\\bsetup\\./i,\n /\\bscaffold\\./i,\n /\\binit\\./i,\n /\\bbootstrap\\./i,\n];\n\nfunction isElectronFile(filePath: string): boolean {\n return ELECTRON_PATH_PATTERNS.some((p) => p.test(filePath));\n}\n\nfunction isInternalScript(filePath: string): boolean {\n return INTERNAL_SCRIPT_PATTERNS.some((p) => p.test(filePath));\n}\n\n// ─── Rule ─────────────────────────────────────────────────────────────────────\n\nexport const requireAuthMiddleware = createRule({\n name: 'require-auth-middleware',\n meta: {\n type: 'suggestion',\n docs: {\n description:\n 'Require authentication middleware on Express/Fastify route definitions. AI tools frequently generate route handlers without auth middleware, creating unprotected endpoints.',\n },\n fixable: undefined,\n schema: [\n {\n type: 'object',\n properties: {\n authMiddlewareNames: {\n type: 'array',\n items: { type: 'string' },\n description: 'Additional custom middleware names to recognize as authentication middleware.',\n },\n allowElectronApps: {\n type: 'boolean',\n description: 'Suppress findings in Electron main/preload files (default: true). Electron localhost routes do not need web auth middleware.',\n },\n allowInternalScripts: {\n type: 'boolean',\n description: 'Suppress findings in internal tooling files (migration, seed, debug, dev-server). These are never production-exposed (default: true).',\n },\n internalPathPatterns: {\n type: 'array',\n items: { type: 'string' },\n description: 'Additional file path patterns to treat as internal (suppressed).',\n },\n },\n additionalProperties: false,\n },\n ],\n messages: {\n missingAuth:\n 'Route `{{method}} {{path}}` appears to lack authentication middleware. Verify that auth is applied at the router level, or add middleware (e.g., `protect`, `authenticate`) to the handler chain.',\n },\n },\n defaultOptions: [{}] as [\n {\n authMiddlewareNames?: string[];\n allowElectronApps?: boolean;\n allowInternalScripts?: boolean;\n internalPathPatterns?: string[];\n }\n ],\n create(context, [options]) {\n const allowElectronApps = options.allowElectronApps !== false; // default true\n const allowInternalScripts = options.allowInternalScripts !== false; // default true\n const customNames = new Set(options.authMiddlewareNames ?? []);\n const allAuthNames = new Set([...DEFAULT_AUTH_MIDDLEWARE_NAMES, ...customNames]);\n const extraPatterns = (options.internalPathPatterns ?? []).map((p) => new RegExp(p, 'i'));\n\n const filePath = context.filename ?? context.getFilename?.() ?? '';\n\n // ── File-level context suppression ─────────────────────────────────────\n // Suppress entirely for files that are known non-production contexts.\n // This eliminates the most common false-positive sources without any\n // AST analysis overhead.\n\n if (allowElectronApps && isElectronFile(filePath)) {\n return {}; // Electron main/preload — localhost routes don't need web auth\n }\n\n if (allowInternalScripts && isInternalScript(filePath)) {\n return {}; // Internal tooling — not production-exposed\n }\n\n if (extraPatterns.some((p) => p.test(filePath))) {\n return {}; // User-defined internal path\n }\n\n // ── Route analysis ────────────────────────────────────────────────────\n\n // Track if router.use(protect) is applied (blanket auth covers all subsequent routes)\n let hasRouterUseAuth = false;\n\n return {\n CallExpression(node) {\n // Detect router.use(protect) or app.use(protect) — blanket auth\n if (isRouterUseAuth(node, allAuthNames)) {\n hasRouterUseAuth = true;\n return;\n }\n\n // Check for: router.get('/path', handler) or app.post('/path', handler)\n if (!isRouteDefinition(node)) return;\n\n // If a blanket router.use(auth) was already applied, skip\n if (hasRouterUseAuth) return;\n\n const callee = node.callee as TSESTree.MemberExpression;\n const method = (callee.property as TSESTree.Identifier).name;\n const args = node.arguments;\n\n // First argument should be the route path\n if (args.length < 2) return;\n const pathArg = args[0];\n const pathStr = getPathString(pathArg);\n\n // Skip public routes\n if (pathStr && isPublicRoute(pathStr)) return;\n\n // Check if any argument (between path and final handler) is an auth middleware\n const middlewareArgs = args.slice(1, -1); // Exclude path and final handler\n\n // If only path + handler (no middleware at all)\n if (middlewareArgs.length === 0 && args.length === 2) {\n context.report({\n node,\n messageId: 'missingAuth',\n data: {\n method: method.toUpperCase(),\n path: pathStr || '<dynamic>',\n },\n });\n return;\n }\n\n // Check if any middleware in the chain is an auth middleware\n const hasAuth = middlewareArgs.some((arg) => isAuthMiddleware(arg, allAuthNames));\n\n if (!hasAuth) {\n context.report({\n node,\n messageId: 'missingAuth',\n data: {\n method: method.toUpperCase(),\n path: pathStr || '<dynamic>',\n },\n });\n }\n },\n };\n },\n});\n\nfunction isRouteDefinition(node: TSESTree.CallExpression): boolean {\n if (node.callee.type !== AST_NODE_TYPES.MemberExpression) return false;\n if (node.callee.property.type !== AST_NODE_TYPES.Identifier) return false;\n\n const methodName = node.callee.property.name;\n if (!HTTP_METHODS.has(methodName)) return false;\n\n // The object should be a router/app-like identifier\n const obj = node.callee.object;\n if (obj.type === AST_NODE_TYPES.Identifier) {\n const name = obj.name.toLowerCase();\n return name === 'router' || name === 'app' || name.includes('router');\n }\n // Also handle: express.Router() chains\n if (obj.type === AST_NODE_TYPES.CallExpression) return true;\n\n return false;\n}\n\nfunction isRouterUseAuth(node: TSESTree.CallExpression, authNames: Set<string>): boolean {\n if (node.callee.type !== AST_NODE_TYPES.MemberExpression) return false;\n if (node.callee.property.type !== AST_NODE_TYPES.Identifier) return false;\n if (node.callee.property.name !== 'use') return false;\n\n // Check if any argument is an auth middleware\n return node.arguments.some((arg) => isAuthMiddleware(arg, authNames));\n}\n\nfunction isAuthMiddleware(node: TSESTree.Node, authNames: Set<string>): boolean {\n // Direct identifier: protect, authenticate, etc.\n if (node.type === AST_NODE_TYPES.Identifier) {\n return authNames.has(node.name);\n }\n\n // Fastify-style options object: { preHandler: authenticate, onRequest: verifyToken }\n if (node.type === AST_NODE_TYPES.ObjectExpression) {\n for (const prop of node.properties) {\n if (\n prop.type === AST_NODE_TYPES.Property &&\n prop.key.type === AST_NODE_TYPES.Identifier &&\n (prop.key.name === 'preHandler' || prop.key.name === 'onRequest')\n ) {\n if (isAuthMiddleware(prop.value, authNames)) return true;\n }\n }\n }\n\n // Call expression: authenticate('jwt'), authorize('admin')\n if (node.type === AST_NODE_TYPES.CallExpression) {\n if (node.callee.type === AST_NODE_TYPES.Identifier) {\n return authNames.has(node.callee.name);\n }\n // passport.authenticate(...)\n if (\n node.callee.type === AST_NODE_TYPES.MemberExpression &&\n node.callee.object.type === AST_NODE_TYPES.Identifier &&\n node.callee.property.type === AST_NODE_TYPES.Identifier\n ) {\n const fullName = `${node.callee.object.name}.${node.callee.property.name}`;\n return authNames.has(fullName) || authNames.has(node.callee.property.name);\n }\n }\n\n return false;\n}\n\nfunction getPathString(node: TSESTree.Node): string | null {\n if (node.type === AST_NODE_TYPES.Literal && typeof node.value === 'string') {\n return node.value;\n }\n if (node.type === AST_NODE_TYPES.TemplateLiteral) {\n if (node.expressions.length === 0 && node.quasis.length === 1) {\n return node.quasis[0].value.cooked ?? null;\n }\n if (node.quasis.length > 0) {\n return node.quasis[0].value.cooked ?? null;\n }\n }\n return null;\n}\n\nfunction isPublicRoute(pathStr: string): boolean {\n return PUBLIC_ROUTE_PATTERNS.some((pattern) => pattern.test(pathStr));\n}\n\nexport default requireAuthMiddleware;\n","import { ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';\r\nimport type { TSESTree } from '@typescript-eslint/utils';\r\n\r\nconst createRule = ESLintUtils.RuleCreator(\r\n (name) => `https://github.com/YashJadhav21/eslint-plugin-ai-guard/blob/main/docs/rules/${name}.md`\r\n);\r\n\r\nconst ROUTE_METHODS = ['get', 'post', 'put', 'patch', 'delete'] as const;\r\nconst AUTHZ_HELPER_NAMES = [\r\n 'authorize',\r\n 'authorise',\r\n 'checkOwnership',\r\n 'ensureOwner',\r\n 'isOwner',\r\n 'canAccess',\r\n 'canModify',\r\n 'hasAccess',\r\n] as const;\r\n\r\n// ─── Context detection (shared with require-auth-middleware) ──────────────────\r\nconst ELECTRON_PATH_PATTERNS = [\r\n /[\\\\/]electron[\\\\/]/i, /[\\\\/]electron-main/i, /\bpreload\\.js$/, /\bbackground\\.js$/,\r\n];\r\nconst INTERNAL_SCRIPT_PATTERNS = [\r\n /[\\\\/]scripts[\\\\/]/i, /[\\\\/]migrations?[\\\\/]/i, /[\\\\/]seeds?[\\\\/]/i,\r\n /[\\\\/]debug[\\\\/]/i, /\bseed\\./i, /\bmigrate?\\./i, /\bsetup\\./i,\r\n];\r\nfunction isElectronOrInternalFile(filePath: string): boolean {\r\n return (\r\n ELECTRON_PATH_PATTERNS.some((p) => p.test(filePath)) ||\r\n INTERNAL_SCRIPT_PATTERNS.some((p) => p.test(filePath))\r\n );\r\n}\r\n\r\nfunction isRouteRegistrationCall(node: TSESTree.CallExpression): boolean {\r\n if (\r\n node.callee.type !== AST_NODE_TYPES.MemberExpression ||\r\n node.callee.property.type !== AST_NODE_TYPES.Identifier\r\n ) {\r\n return false;\r\n }\r\n\r\n if (!ROUTE_METHODS.includes(node.callee.property.name as (typeof ROUTE_METHODS)[number])) {\r\n return false;\r\n }\r\n\r\n const firstArg = node.arguments[0];\r\n if (!firstArg) {\r\n return false;\r\n }\r\n\r\n return (\r\n (firstArg.type === AST_NODE_TYPES.Literal && typeof firstArg.value === 'string') ||\r\n (firstArg.type === AST_NODE_TYPES.TemplateLiteral && firstArg.expressions.length === 0)\r\n );\r\n}\r\n\r\nfunction getStaticPathArg(node: TSESTree.CallExpression): string | null {\r\n const firstArg = node.arguments[0];\r\n if (!firstArg) return null;\r\n\r\n if (firstArg.type === AST_NODE_TYPES.Literal && typeof firstArg.value === 'string') {\r\n return firstArg.value;\r\n }\r\n\r\n if (firstArg.type === AST_NODE_TYPES.TemplateLiteral && firstArg.expressions.length === 0) {\r\n return firstArg.quasis[0]?.value.cooked ?? null;\r\n }\r\n\r\n return null;\r\n}\r\n\r\nfunction getMemberPath(node: TSESTree.Node): string[] | null {\r\n if (node.type === AST_NODE_TYPES.Identifier) {\r\n return [node.name];\r\n }\r\n\r\n if (node.type !== AST_NODE_TYPES.MemberExpression || node.computed) {\r\n return null;\r\n }\r\n\r\n const objectPath = getMemberPath(node.object);\r\n if (!objectPath) {\r\n return null;\r\n }\r\n\r\n if (node.property.type !== AST_NODE_TYPES.Identifier) {\r\n return null;\r\n }\r\n\r\n return [...objectPath, node.property.name];\r\n}\r\n\r\nfunction hasPathPrefix(path: string[] | null, prefix: readonly string[]): boolean {\r\n if (!path || path.length < prefix.length) {\r\n return false;\r\n }\r\n\r\n for (let i = 0; i < prefix.length; i += 1) {\r\n if (path[i] !== prefix[i]) {\r\n return false;\r\n }\r\n }\r\n\r\n return true;\r\n}\r\n\r\nfunction isLikelyResourceIdPath(path: string[] | null): boolean {\r\n if (!path || path.length < 3) {\r\n return false;\r\n }\r\n\r\n if (!hasPathPrefix(path, ['req', 'params']) && !hasPathPrefix(path, ['req', 'body']) && !hasPathPrefix(path, ['req', 'query'])) {\r\n return false;\r\n }\r\n\r\n const last = path[path.length - 1].toLowerCase();\r\n return last === 'id' || last.endsWith('id');\r\n}\r\n\r\nfunction isReqUserPath(path: string[] | null): boolean {\r\n return hasPathPrefix(path, ['req', 'user']);\r\n}\r\n\r\nfunction containsAuthorizationHelper(node: TSESTree.Node): boolean {\r\n if (\r\n node.type === AST_NODE_TYPES.CallExpression &&\r\n ((node.callee.type === AST_NODE_TYPES.Identifier &&\r\n AUTHZ_HELPER_NAMES.includes(node.callee.name as (typeof AUTHZ_HELPER_NAMES)[number])) ||\r\n (node.callee.type === AST_NODE_TYPES.MemberExpression &&\r\n node.callee.property.type === AST_NODE_TYPES.Identifier &&\r\n AUTHZ_HELPER_NAMES.includes(node.callee.property.name as (typeof AUTHZ_HELPER_NAMES)[number])))\r\n ) {\r\n return true;\r\n }\r\n\r\n const entries = Object.entries(node) as Array<[string, unknown]>;\r\n for (const [key, value] of entries) {\r\n if (key === 'parent') continue;\r\n\r\n if (Array.isArray(value)) {\r\n for (const child of value) {\r\n if (child && typeof child === 'object' && 'type' in child) {\r\n if (containsAuthorizationHelper(child as TSESTree.Node)) return true;\r\n }\r\n }\r\n continue;\r\n }\r\n\r\n if (value && typeof value === 'object' && 'type' in value) {\r\n if (containsAuthorizationHelper(value as TSESTree.Node)) return true;\r\n }\r\n }\r\n\r\n return false;\r\n}\r\n\r\nfunction collectBodySignals(node: TSESTree.Node): { hasResourceIdAccess: boolean; hasOwnershipCheck: boolean } {\r\n let hasResourceIdAccess = false;\r\n let hasOwnershipCheck = false;\r\n\r\n const walk = (current: TSESTree.Node): void => {\r\n if (\r\n current.type === AST_NODE_TYPES.BinaryExpression &&\r\n ['===', '==', '!==', '!='].includes(current.operator)\r\n ) {\r\n const leftPath = getMemberPath(current.left);\r\n const rightPath = getMemberPath(current.right);\r\n\r\n const leftIsUser = isReqUserPath(leftPath);\r\n const rightIsUser = isReqUserPath(rightPath);\r\n const leftIsResource = isLikelyResourceIdPath(leftPath);\r\n const rightIsResource = isLikelyResourceIdPath(rightPath);\r\n\r\n if ((leftIsUser && rightIsResource) || (rightIsUser && leftIsResource)) {\r\n hasOwnershipCheck = true;\r\n }\r\n }\r\n\r\n if (current.type === AST_NODE_TYPES.MemberExpression) {\r\n const path = getMemberPath(current);\r\n if (isLikelyResourceIdPath(path)) {\r\n hasResourceIdAccess = true;\r\n }\r\n }\r\n\r\n if (containsAuthorizationHelper(current)) {\r\n hasOwnershipCheck = true;\r\n }\r\n\r\n const entries = Object.entries(current) as Array<[string, unknown]>;\r\n for (const [key, value] of entries) {\r\n if (key === 'parent') continue;\r\n\r\n if (Array.isArray(value)) {\r\n for (const child of value) {\r\n if (child && typeof child === 'object' && 'type' in child) {\r\n walk(child as TSESTree.Node);\r\n }\r\n }\r\n continue;\r\n }\r\n\r\n if (value && typeof value === 'object' && 'type' in value) {\r\n walk(value as TSESTree.Node);\r\n }\r\n }\r\n };\r\n\r\n walk(node);\r\n\r\n return { hasResourceIdAccess, hasOwnershipCheck };\r\n}\r\n\r\nexport const requireAuthzCheck = createRule({\r\n name: 'require-authz-check',\r\n meta: {\r\n type: 'suggestion',\r\n docs: {\r\n description:\r\n 'Require a visible authorization/ownership check when route handlers access resource identifiers (e.g., req.params.id). AI tools often add auth middleware but forget per-resource authorization checks.',\r\n },\r\n fixable: undefined,\r\n schema: [],\r\n messages: {\r\n missingAuthz:\r\n 'Handler accesses resource identifiers (e.g., req.params.id) without a visible authorization check. Verify ownership or permission is enforced before the resource is returned or modified.',\r\n },\r\n },\r\n defaultOptions: [],\r\n create(context) {\r\n // Suppress in Electron/internal files — auth is not relevant in these contexts\r\n const filePath = context.filename ?? context.getFilename?.() ?? '';\r\n if (isElectronOrInternalFile(filePath)) return {};\r\n\r\n return {\r\n CallExpression(node) {\r\n if (!isRouteRegistrationCall(node)) {\r\n return;\r\n }\r\n\r\n const routePath = getStaticPathArg(node);\r\n const hasRouteIdParam = typeof routePath === 'string' && routePath.includes(':');\r\n\r\n for (const arg of node.arguments) {\r\n if (\r\n arg.type !== AST_NODE_TYPES.FunctionExpression &&\r\n arg.type !== AST_NODE_TYPES.ArrowFunctionExpression\r\n ) {\r\n continue;\r\n }\r\n\r\n if (arg.body.type !== AST_NODE_TYPES.BlockStatement) {\r\n continue;\r\n }\r\n\r\n const signals = collectBodySignals(arg.body);\r\n const isSensitive = hasRouteIdParam && signals.hasResourceIdAccess;\r\n\r\n if (isSensitive && !signals.hasOwnershipCheck) {\r\n context.report({\r\n node: arg,\r\n messageId: 'missingAuthz',\r\n });\r\n }\r\n }\r\n },\r\n };\r\n },\r\n});\r\n\r\nexport default requireAuthzCheck;\r\n","import { ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';\r\nimport type { TSESTree } from '@typescript-eslint/utils';\r\n\r\nconst createRule = ESLintUtils.RuleCreator(\r\n (name) => `https://github.com/YashJadhav21/eslint-plugin-ai-guard/blob/main/docs/rules/${name}.md`\r\n);\r\n\r\nconst ROUTE_METHODS = [\r\n 'get',\r\n 'post',\r\n 'put',\r\n 'patch',\r\n 'delete',\r\n 'options',\r\n 'all',\r\n] as const;\r\n\r\nfunction isRouteRegistrationCall(node: TSESTree.CallExpression): boolean {\r\n if (\r\n node.callee.type !== AST_NODE_TYPES.MemberExpression ||\r\n node.callee.property.type !== AST_NODE_TYPES.Identifier\r\n ) {\r\n return false;\r\n }\r\n\r\n const methodName = node.callee.property.name;\r\n if (!ROUTE_METHODS.includes(methodName as (typeof ROUTE_METHODS)[number])) {\r\n return false;\r\n }\r\n\r\n if (node.arguments.length === 0) {\r\n return false;\r\n }\r\n\r\n const firstArg = node.arguments[0];\r\n\r\n // Keep matching conservative to avoid false positives on non-routing APIs.\r\n if (\r\n firstArg.type === AST_NODE_TYPES.Literal &&\r\n typeof firstArg.value === 'string' &&\r\n firstArg.value.startsWith('/')\r\n ) {\r\n return true;\r\n }\r\n\r\n if (\r\n firstArg.type === AST_NODE_TYPES.TemplateLiteral &&\r\n firstArg.expressions.length === 0 &&\r\n firstArg.quasis[0]?.value.raw.startsWith('/')\r\n ) {\r\n return true;\r\n }\r\n\r\n return false;\r\n}\r\n\r\nfunction traverseForConsoleCalls(\r\n node: TSESTree.Node,\r\n onConsoleCall: (callNode: TSESTree.CallExpression) => void\r\n): void {\r\n if (\r\n node.type === AST_NODE_TYPES.CallExpression &&\r\n node.callee.type === AST_NODE_TYPES.MemberExpression &&\r\n node.callee.object.type === AST_NODE_TYPES.Identifier &&\r\n node.callee.object.name === 'console' &&\r\n node.callee.property.type === AST_NODE_TYPES.Identifier\r\n ) {\r\n onConsoleCall(node);\r\n }\r\n\r\n // Do not recurse into nested function bodies to avoid double-reporting on unrelated closures.\r\n if (\r\n node.type === AST_NODE_TYPES.FunctionDeclaration ||\r\n node.type === AST_NODE_TYPES.FunctionExpression ||\r\n node.type === AST_NODE_TYPES.ArrowFunctionExpression\r\n ) {\r\n return;\r\n }\r\n\r\n const entries = Object.entries(node) as Array<[string, unknown]>;\r\n for (const [key, value] of entries) {\r\n if (key === 'parent') {\r\n continue;\r\n }\r\n\r\n if (Array.isArray(value)) {\r\n for (const child of value) {\r\n if (child && typeof child === 'object' && 'type' in child) {\r\n traverseForConsoleCalls(child as TSESTree.Node, onConsoleCall);\r\n }\r\n }\r\n continue;\r\n }\r\n\r\n if (value && typeof value === 'object' && 'type' in value) {\r\n traverseForConsoleCalls(value as TSESTree.Node, onConsoleCall);\r\n }\r\n }\r\n}\r\n\r\nexport const noConsoleInHandler = createRule({\r\n name: 'no-console-in-handler',\r\n meta: {\r\n type: 'suggestion',\r\n docs: {\r\n description:\r\n 'Disallow console logging inside route handlers. AI tools frequently leave debug logs in request handlers, which can leak operational data and create noisy production logs.',\r\n },\r\n fixable: undefined,\r\n hasSuggestions: true,\r\n schema: [],\r\n messages: {\r\n noConsoleInHandler:\r\n 'Avoid console logging inside route handlers. AI tools frequently leave debug statements in handlers. Use structured application logging instead.',\r\n removeConsoleCall:\r\n 'Remove this console statement from the route handler.',\r\n },\r\n },\r\n defaultOptions: [],\r\n create(context) {\r\n return {\r\n CallExpression(node) {\r\n if (!isRouteRegistrationCall(node)) {\r\n return;\r\n }\r\n\r\n for (const argument of node.arguments) {\r\n if (\r\n argument.type !== AST_NODE_TYPES.FunctionExpression &&\r\n argument.type !== AST_NODE_TYPES.ArrowFunctionExpression\r\n ) {\r\n continue;\r\n }\r\n\r\n if (argument.body.type !== AST_NODE_TYPES.BlockStatement) {\r\n continue;\r\n }\r\n\r\n for (const statement of argument.body.body) {\r\n traverseForConsoleCalls(statement, (callNode) => {\r\n const parent = callNode.parent;\r\n const canSuggestRemoval = parent?.type === AST_NODE_TYPES.ExpressionStatement;\r\n\r\n context.report({\r\n node: callNode,\r\n messageId: 'noConsoleInHandler',\r\n suggest: canSuggestRemoval\r\n ? [\r\n {\r\n messageId: 'removeConsoleCall',\r\n fix: (fixer) => fixer.remove(parent),\r\n },\r\n ]\r\n : undefined,\r\n });\r\n });\r\n }\r\n }\r\n },\r\n };\r\n },\r\n});\r\n\r\nexport default noConsoleInHandler;\r\n","import { ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';\r\nimport type { TSESTree } from '@typescript-eslint/utils';\r\n\r\nconst createRule = ESLintUtils.RuleCreator(\r\n (name) => `https://github.com/YashJadhav21/eslint-plugin-ai-guard/blob/main/docs/rules/${name}.md`\r\n);\r\n\r\nfunction normalizeStatementText(source: string): string {\r\n return source.replace(/\\s+/g, ' ').trim();\r\n}\r\n\r\nfunction isLikelyMeaningfulStatement(node: TSESTree.Statement, sourceCodeText: string): boolean {\r\n if (\r\n node.type === AST_NODE_TYPES.EmptyStatement ||\r\n node.type === AST_NODE_TYPES.BreakStatement ||\r\n node.type === AST_NODE_TYPES.ContinueStatement\r\n ) {\r\n return false;\r\n }\r\n\r\n return sourceCodeText.length >= 30;\r\n}\r\n\r\nexport const noDuplicateLogicBlock = createRule({\r\n name: 'no-duplicate-logic-block',\r\n meta: {\r\n type: 'suggestion',\r\n docs: {\r\n description:\r\n 'Disallow consecutive duplicated logic statements. AI tools often copy-paste the same logic block with minimal or no changes, which should usually be extracted or consolidated.',\r\n },\r\n fixable: undefined,\r\n schema: [],\r\n messages: {\r\n duplicateLogic:\r\n 'Duplicate consecutive logic block detected. AI-generated code often repeats the same block. Consider extracting shared logic into a function or removing duplication.',\r\n },\r\n },\r\n defaultOptions: [],\r\n create(context) {\r\n const checkStatementList = (statements: TSESTree.Statement[]): void => {\r\n if (statements.length < 2) {\r\n return;\r\n }\r\n\r\n for (let i = 0; i < statements.length - 1; i += 1) {\r\n const current = statements[i];\r\n const next = statements[i + 1];\r\n\r\n const currentTextRaw = context.sourceCode.getText(current);\r\n const nextTextRaw = context.sourceCode.getText(next);\r\n\r\n if (!isLikelyMeaningfulStatement(current, currentTextRaw)) {\r\n continue;\r\n }\r\n\r\n if (!isLikelyMeaningfulStatement(next, nextTextRaw)) {\r\n continue;\r\n }\r\n\r\n const currentText = normalizeStatementText(currentTextRaw);\r\n const nextText = normalizeStatementText(nextTextRaw);\r\n\r\n if (currentText === nextText) {\r\n context.report({\r\n node: next,\r\n messageId: 'duplicateLogic',\r\n });\r\n }\r\n }\r\n };\r\n\r\n return {\r\n Program(node) {\r\n checkStatementList(node.body);\r\n },\r\n\r\n BlockStatement(node) {\r\n checkStatementList(node.body);\r\n },\r\n };\r\n },\r\n});\r\n\r\nexport default noDuplicateLogicBlock;\r\n","import { ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';\nimport type { TSESTree } from '@typescript-eslint/utils';\n\nconst createRule = ESLintUtils.RuleCreator(\n (name) => `https://github.com/YashJadhav21/eslint-plugin-ai-guard/blob/main/docs/rules/${name}.md`\n);\n\n/**\n * Checks if a node is the boolean literal `true` or `false`.\n */\nfunction isBooleanLiteral(node: TSESTree.Node, value: boolean): boolean {\n return (\n node.type === AST_NODE_TYPES.Literal &&\n typeof node.value === 'boolean' &&\n node.value === value\n );\n}\n\n/**\n * Checks if a node is a numeric literal equal to zero.\n */\nfunction isZeroLiteral(node: TSESTree.Node): boolean {\n return (\n node.type === AST_NODE_TYPES.Literal &&\n typeof node.value === 'number' &&\n node.value === 0\n );\n}\n\n/**\n * Checks if a node is the string literal `\"\"` or `''`.\n */\nfunction isEmptyStringLiteral(node: TSESTree.Node): boolean {\n return (\n node.type === AST_NODE_TYPES.Literal &&\n typeof node.value === 'string' &&\n node.value === ''\n );\n}\n\n/**\n * Returns true if the condition is statically always-true or always-false.\n * Handles:\n * - `if (true)` / `if (false)`\n * - `if (1)` / `if (0)`\n * - `while (true)` (intentional infinite loops are common, so we exempt them)\n * - `if (x && !x)` / `if (x || !x)` — self-contradictory / self-tautological\n * - `x === x` when x is an identifier (trivially true)\n */\nfunction isAlwaysTrue(node: TSESTree.Node): boolean {\n if (isBooleanLiteral(node, true)) return true;\n\n // x || !x is always true\n if (\n node.type === AST_NODE_TYPES.LogicalExpression &&\n node.operator === '||'\n ) {\n const { left, right } = node;\n if (\n left.type === AST_NODE_TYPES.Identifier &&\n right.type === AST_NODE_TYPES.UnaryExpression &&\n right.operator === '!' &&\n right.argument.type === AST_NODE_TYPES.Identifier &&\n left.name === right.argument.name\n ) {\n return true;\n }\n }\n\n // x === x (same identifier compared to itself)\n if (\n node.type === AST_NODE_TYPES.BinaryExpression &&\n (node.operator === '===' || node.operator === '==') &&\n node.left.type === AST_NODE_TYPES.Identifier &&\n node.right.type === AST_NODE_TYPES.Identifier &&\n node.left.name === node.right.name\n ) {\n return true;\n }\n\n return false;\n}\n\nfunction isAlwaysFalse(node: TSESTree.Node): boolean {\n if (isBooleanLiteral(node, false)) return true;\n if (isZeroLiteral(node)) return true;\n if (isEmptyStringLiteral(node)) return true;\n\n // x && !x is always false\n if (\n node.type === AST_NODE_TYPES.LogicalExpression &&\n node.operator === '&&'\n ) {\n const { left, right } = node;\n if (\n left.type === AST_NODE_TYPES.Identifier &&\n right.type === AST_NODE_TYPES.UnaryExpression &&\n right.operator === '!' &&\n right.argument.type === AST_NODE_TYPES.Identifier &&\n left.name === right.argument.name\n ) {\n return true;\n }\n }\n\n // x !== x (same identifier compared to itself with strict inequality)\n if (\n node.type === AST_NODE_TYPES.BinaryExpression &&\n (node.operator === '!==' || node.operator === '!=') &&\n node.left.type === AST_NODE_TYPES.Identifier &&\n node.right.type === AST_NODE_TYPES.Identifier &&\n node.left.name === node.right.name\n ) {\n return true;\n }\n\n return false;\n}\n\nexport const noDeadBranch = createRule({\n name: 'no-dead-branch',\n meta: {\n type: 'suggestion',\n docs: {\n description:\n 'Disallow conditions that are statically always-true or always-false. AI tools frequently generate dead branches like `if (true)`, `if (false)`, `if (x && !x)`, or `x === x` — leftover scaffolding that clutters the code and hides logical errors.',\n },\n fixable: undefined,\n schema: [],\n messages: {\n alwaysTrue:\n 'This condition is always `true` — the branch is never skipped. AI tools often generate this as leftover scaffolding. Remove the condition or replace it with the intended logic.',\n alwaysFalse:\n 'This condition is always `false` — this branch is dead and never executed. AI tools often generate this as leftover scaffolding. Remove the dead branch entirely.',\n whileFalse:\n 'This `while (false)` loop never executes. AI tools sometimes generate this as a placeholder. Remove it or replace with the intended loop condition.',\n },\n },\n defaultOptions: [],\n create(context) {\n function checkCondition(\n testNode: TSESTree.Expression | null,\n reportNode: TSESTree.Node,\n isBranchStatement: boolean,\n ): void {\n if (!testNode) return;\n\n if (isAlwaysFalse(testNode)) {\n context.report({\n node: reportNode,\n messageId: isBranchStatement ? 'alwaysFalse' : 'whileFalse',\n });\n return;\n }\n\n if (isAlwaysTrue(testNode)) {\n // while (true) is a common and intentional pattern for event loops\n // and retry mechanisms — don't flag it.\n if (reportNode.type === AST_NODE_TYPES.WhileStatement) return;\n\n context.report({\n node: reportNode,\n messageId: 'alwaysTrue',\n });\n }\n }\n\n return {\n IfStatement(node) {\n checkCondition(node.test, node, true);\n },\n\n WhileStatement(node) {\n // while (false) is always dead\n if (isAlwaysFalse(node.test)) {\n context.report({ node, messageId: 'whileFalse' });\n }\n // while (true) is intentional — skip\n },\n\n DoWhileStatement(node) {\n // do { ... } while (false) is a common C trick but AI tools\n // sometimes generate it erroneously in JS\n if (isAlwaysFalse(node.test)) {\n context.report({ node, messageId: 'whileFalse' });\n }\n },\n\n ConditionalExpression(node) {\n checkCondition(node.test, node, true);\n },\n };\n },\n});\n\nexport default noDeadBranch;\n","// ── Reliability (was: error-handling) ─────────────────────────────────────────\nimport { noEmptyCatch } from './reliability/no-empty-catch';\nimport { noBroadException } from './reliability/no-broad-exception';\nimport { noCatchLogRethrow } from './reliability/no-catch-log-rethrow';\nimport { noCatchWithoutUse } from './reliability/no-catch-without-use';\n\n// ── Async ──────────────────────────────────────────────────────────────────────\nimport { noAsyncArrayCallback } from './async/no-async-array-callback';\nimport { noFloatingPromise } from './async/no-floating-promise';\nimport { noAwaitInLoop } from './async/no-await-in-loop';\nimport { noAsyncWithoutAwait } from './async/no-async-without-await';\nimport { noRedundantAwait } from './async/no-redundant-await';\n\n// ── Security ───────────────────────────────────────────────────────────────────\nimport { noHardcodedSecret } from './security/no-hardcoded-secret';\nimport { noEvalDynamic } from './security/no-eval-dynamic';\nimport { noSqlStringConcat } from './security/no-sql-string-concat';\nimport { noUnsafeDeserialize } from './security/no-unsafe-deserialize';\nimport { requireAuthMiddleware } from './security/require-auth-middleware';\nimport { requireAuthzCheck } from './security/require-authz-check';\n\n// ── AI Patterns (was: quality + logic) ────────────────────────────────────────\nimport { noConsoleInHandler } from './ai-patterns/no-console-in-handler';\nimport { noDuplicateLogicBlock } from './ai-patterns/no-duplicate-logic-block';\nimport { noDeadBranch } from './ai-patterns/no-dead-branch';\n\n/**\n * All rules exported by the plugin.\n * Each key is the rule name (without the plugin prefix).\n *\n * Categories (internal source directories):\n * reliability/ — error handling & exception patterns\n * async/ — async/await & promise patterns\n * security/ — secrets, injection, auth gaps\n * ai-patterns/ — AI-specific code slop: dead code, quality issues\n */\nexport const allRules = {\n // Reliability\n 'no-empty-catch': noEmptyCatch,\n 'no-broad-exception': noBroadException,\n 'no-catch-log-rethrow': noCatchLogRethrow,\n 'no-catch-without-use': noCatchWithoutUse,\n // Async\n 'no-async-array-callback': noAsyncArrayCallback,\n 'no-floating-promise': noFloatingPromise,\n 'no-await-in-loop': noAwaitInLoop,\n 'no-async-without-await': noAsyncWithoutAwait,\n 'no-redundant-await': noRedundantAwait,\n // Security\n 'no-hardcoded-secret': noHardcodedSecret,\n 'no-eval-dynamic': noEvalDynamic,\n 'no-sql-string-concat': noSqlStringConcat,\n 'no-unsafe-deserialize': noUnsafeDeserialize,\n 'require-auth-middleware': requireAuthMiddleware,\n 'require-authz-check': requireAuthzCheck,\n // AI Patterns\n 'no-console-in-handler': noConsoleInHandler,\n 'no-duplicate-logic-block': noDuplicateLogicBlock,\n 'no-dead-branch': noDeadBranch,\n} as const;\n\nexport type RuleKey = keyof typeof allRules;\n","import type { TSESLint } from '@typescript-eslint/utils';\n\nconst recommended: TSESLint.ClassicConfig.Config = {\n plugins: ['ai-guard'],\n rules: {\n // Adoption-first default:\n // Keep only high-confidence, high-impact rules at error so first run is actionable,\n // not overwhelming. Context-sensitive rules are warn/off by design.\n\n // ── Reliability ────────────────────────────────────────────────────────────\n // Critical (error): low-noise, high-impact correctness failures.\n 'ai-guard/no-empty-catch': 'error',\n\n // Important but context-dependent (warn).\n 'ai-guard/no-broad-exception': 'warn',\n\n // Off in recommended — too noisy in mixed codebases.\n 'ai-guard/no-catch-without-use': 'off',\n 'ai-guard/no-catch-log-rethrow': 'off',\n\n // ── Async ──────────────────────────────────────────────────────────────────\n 'ai-guard/no-floating-promise': 'error',\n 'ai-guard/no-await-in-loop': 'warn',\n 'ai-guard/no-async-without-await': 'warn',\n 'ai-guard/no-async-array-callback': 'warn',\n\n // Off in recommended — reduces noise in common patterns.\n 'ai-guard/no-redundant-await': 'off',\n\n // ── Security ───────────────────────────────────────────────────────────────\n // Critical (error): direct security vulnerabilities.\n 'ai-guard/no-hardcoded-secret': 'error',\n 'ai-guard/no-eval-dynamic': 'error',\n\n // Context-sensitive (warn): useful but require project context.\n 'ai-guard/no-sql-string-concat': 'warn',\n 'ai-guard/no-unsafe-deserialize': 'warn',\n 'ai-guard/require-auth-middleware': 'warn',\n 'ai-guard/require-authz-check': 'warn',\n\n // ── AI Patterns ────────────────────────────────────────────────────────────\n // Warn: useful signal, but may fire in intentional dead-code removal flows.\n 'ai-guard/no-dead-branch': 'warn',\n\n // Off in recommended — contextual rules for teams opting into stricter checks.\n 'ai-guard/no-console-in-handler': 'off',\n 'ai-guard/no-duplicate-logic-block': 'off',\n },\n};\n\nexport default recommended;\n","import type { TSESLint } from '@typescript-eslint/utils';\n\nconst strict: TSESLint.ClassicConfig.Config = {\n plugins: ['ai-guard'],\n rules: {\n // Strict preset: enforce every ai-guard rule at error for mature teams\n // that want maximum coverage and are ready to tune exceptions locally.\n\n // Error Handling - all at error\n 'ai-guard/no-empty-catch': 'error',\n 'ai-guard/no-broad-exception': 'error',\n 'ai-guard/no-catch-log-rethrow': 'error',\n 'ai-guard/no-catch-without-use': 'error',\n // Async - all at error\n 'ai-guard/no-async-array-callback': 'error',\n 'ai-guard/no-floating-promise': 'error',\n 'ai-guard/no-await-in-loop': 'error',\n 'ai-guard/no-async-without-await': 'error',\n 'ai-guard/no-redundant-await': 'error',\n // Security - all at error\n 'ai-guard/no-hardcoded-secret': 'error',\n 'ai-guard/no-eval-dynamic': 'error',\n 'ai-guard/no-sql-string-concat': 'error',\n 'ai-guard/no-unsafe-deserialize': 'error',\n 'ai-guard/require-auth-middleware': 'error',\n 'ai-guard/require-authz-check': 'error',\n // AI Patterns - all at error\n 'ai-guard/no-console-in-handler': 'error',\n 'ai-guard/no-duplicate-logic-block': 'error',\n 'ai-guard/no-dead-branch': 'error',\n },\n};\n\nexport default strict;\n","import type { TSESLint } from '@typescript-eslint/utils';\n\nconst security: TSESLint.ClassicConfig.Config = {\n plugins: ['ai-guard'],\n rules: {\n // Security-only preset:\n // Error = direct high-risk patterns. Warn = security-relevant but context-sensitive.\n 'ai-guard/no-hardcoded-secret': 'error',\n 'ai-guard/no-eval-dynamic': 'error',\n 'ai-guard/no-sql-string-concat': 'error',\n 'ai-guard/no-unsafe-deserialize': 'warn',\n 'ai-guard/require-auth-middleware': 'warn',\n 'ai-guard/require-authz-check': 'warn',\n },\n};\n\nexport default security;\n"],"mappings":"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","names":["import_utils","createRule","import_utils","createRule","import_utils","createRule","import_utils","createRule","import_utils","createRule","import_utils","createRule","path","import_utils","import_path","createRule","path","buildSafeAutofix","fix","import_utils","createRule","import_utils","createRule","import_utils","createRule","import_utils","createRule","import_utils","createRule","import_utils","createRule","import_utils","createRule","ELECTRON_PATH_PATTERNS","INTERNAL_SCRIPT_PATTERNS","path","import_utils","createRule","ROUTE_METHODS","isRouteRegistrationCall","import_utils","createRule","import_utils","createRule","import_path","path"]}