react-doctor 0.0.42 → 0.0.44
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +169 -41
- package/bin/react-doctor.js +13 -0
- package/dist/{process-browser-diagnostics-BHiLPUJT.js → browser-BOxs7MrK.js} +35 -21
- package/dist/{browser-DFbjNpPb.d.ts → browser-Dcq3yn-p.d.ts} +18 -3
- package/dist/browser.d.ts +1 -1
- package/dist/browser.js +1 -1
- package/dist/cli.d.ts +0 -1
- package/dist/cli.js +1391 -426
- package/dist/index.d.ts +119 -12
- package/dist/index.js +1136 -327
- package/dist/react-doctor-plugin.js +2335 -127
- package/dist/worker.d.ts +2 -2
- package/dist/worker.js +2 -2
- package/package.json +35 -13
- package/dist/browser-DFbjNpPb.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/process-browser-diagnostics-BHiLPUJT.js.map +0 -1
- package/dist/react-doctor-plugin.d.ts.map +0 -1
- package/dist/react-doctor-plugin.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"react-doctor-plugin.js","names":[],"sources":["../src/plugin/constants.ts","../src/plugin/helpers.ts","../src/plugin/rules/architecture.ts","../src/plugin/rules/bundle-size.ts","../src/plugin/rules/client.ts","../src/plugin/rules/design.ts","../src/plugin/rules/correctness.ts","../src/plugin/rules/js-performance.ts","../src/plugin/rules/nextjs.ts","../src/plugin/rules/performance.ts","../src/plugin/rules/react-native.ts","../src/plugin/rules/tanstack-query.ts","../src/plugin/rules/security.ts","../src/plugin/rules/server.ts","../src/plugin/rules/tanstack-start.ts","../src/plugin/rules/state-and-effects.ts","../src/plugin/index.ts"],"sourcesContent":["export const GIANT_COMPONENT_LINE_THRESHOLD = 300;\nexport const CASCADING_SET_STATE_THRESHOLD = 3;\nexport const RELATED_USE_STATE_THRESHOLD = 5;\nexport const DEEP_NESTING_THRESHOLD = 3;\nexport const DUPLICATE_STORAGE_READ_THRESHOLD = 2;\nexport const SEQUENTIAL_AWAIT_THRESHOLD = 3;\nexport const SECRET_MIN_LENGTH_CHARS = 8;\nexport const AUTH_CHECK_LOOKAHEAD_STATEMENTS = 3;\n\nexport const LAYOUT_PROPERTIES = new Set([\n \"width\",\n \"height\",\n \"top\",\n \"left\",\n \"right\",\n \"bottom\",\n \"padding\",\n \"paddingTop\",\n \"paddingRight\",\n \"paddingBottom\",\n \"paddingLeft\",\n \"margin\",\n \"marginTop\",\n \"marginRight\",\n \"marginBottom\",\n \"marginLeft\",\n \"borderWidth\",\n \"fontSize\",\n \"lineHeight\",\n \"gap\",\n]);\n\nexport const MOTION_ANIMATE_PROPS = new Set([\n \"animate\",\n \"initial\",\n \"exit\",\n \"whileHover\",\n \"whileTap\",\n \"whileFocus\",\n \"whileDrag\",\n \"whileInView\",\n]);\n\nexport const HEAVY_LIBRARIES = new Set([\n \"@monaco-editor/react\",\n \"monaco-editor\",\n \"recharts\",\n \"@react-pdf/renderer\",\n \"react-quill\",\n \"@codemirror/view\",\n \"@codemirror/state\",\n \"chart.js\",\n \"react-chartjs-2\",\n \"@toast-ui/editor\",\n \"draft-js\",\n]);\n\nexport const FETCH_CALLEE_NAMES = new Set([\"fetch\"]);\nexport const FETCH_MEMBER_OBJECTS = new Set([\"axios\", \"ky\", \"got\"]);\nexport const INDEX_PARAMETER_NAMES = new Set([\"index\", \"idx\", \"i\"]);\nexport const BARREL_INDEX_SUFFIXES = [\n \"/index\",\n \"/index.js\",\n \"/index.ts\",\n \"/index.tsx\",\n \"/index.mjs\",\n];\nexport const PASSIVE_EVENT_NAMES = new Set([\n \"scroll\",\n \"wheel\",\n \"touchstart\",\n \"touchmove\",\n \"touchend\",\n]);\n\nexport const LOOP_TYPES = [\n \"ForStatement\",\n \"ForInStatement\",\n \"ForOfStatement\",\n \"WhileStatement\",\n \"DoWhileStatement\",\n];\n\nexport const AUTH_FUNCTION_NAMES = new Set([\n \"auth\",\n \"getSession\",\n \"getServerSession\",\n \"getUser\",\n \"requireAuth\",\n \"checkAuth\",\n \"verifyAuth\",\n \"authenticate\",\n \"currentUser\",\n \"getAuth\",\n \"validateSession\",\n]);\n\nexport const SECRET_PATTERNS = [\n /^sk_live_/,\n /^sk_test_/,\n /^AKIA[0-9A-Z]{16}$/,\n /^ghp_[a-zA-Z0-9]{36}$/,\n /^gho_[a-zA-Z0-9]{36}$/,\n /^github_pat_/,\n /^glpat-/,\n /^xox[bporas]-/,\n /^sk-[a-zA-Z0-9]{32,}$/,\n];\n\nexport const SECRET_VARIABLE_PATTERN = /(?:api_?key|secret|token|password|credential|auth)/i;\n\nexport const SECRET_FALSE_POSITIVE_SUFFIXES = new Set([\n \"modal\",\n \"label\",\n \"text\",\n \"title\",\n \"name\",\n \"id\",\n \"key\",\n \"url\",\n \"path\",\n \"route\",\n \"page\",\n \"param\",\n \"field\",\n \"column\",\n \"header\",\n \"placeholder\",\n \"description\",\n \"type\",\n \"icon\",\n \"class\",\n \"style\",\n \"variant\",\n \"event\",\n \"action\",\n \"status\",\n \"state\",\n \"mode\",\n \"flag\",\n \"option\",\n \"config\",\n \"message\",\n \"error\",\n \"display\",\n \"view\",\n \"component\",\n \"element\",\n \"container\",\n \"wrapper\",\n \"button\",\n \"link\",\n \"input\",\n \"select\",\n \"dialog\",\n \"menu\",\n \"form\",\n \"step\",\n \"index\",\n \"count\",\n \"length\",\n \"role\",\n \"scope\",\n \"context\",\n \"provider\",\n \"ref\",\n \"handler\",\n \"query\",\n \"schema\",\n \"constant\",\n]);\n\nexport const LOADING_STATE_PATTERN = /^(?:isLoading|isPending)$/;\n\nexport const TANSTACK_ROUTE_FILE_PATTERN = /\\/routes\\//;\nexport const TANSTACK_ROOT_ROUTE_FILE_PATTERN = /__root\\.(tsx?|jsx?)$/;\n\nexport const TANSTACK_ROUTE_PROPERTY_ORDER = [\n \"params\",\n \"validateSearch\",\n \"loaderDeps\",\n \"search.middlewares\",\n \"ssr\",\n \"context\",\n \"beforeLoad\",\n \"loader\",\n \"onEnter\",\n \"onStay\",\n \"onLeave\",\n \"head\",\n \"scripts\",\n \"headers\",\n \"remountDeps\",\n];\n\nexport const TANSTACK_ROUTE_CREATION_FUNCTIONS = new Set([\n \"createFileRoute\",\n \"createRoute\",\n \"createRootRoute\",\n \"createRootRouteWithContext\",\n]);\n\nexport const TANSTACK_SERVER_FN_NAMES = new Set([\"createServerFn\"]);\n\nexport const TANSTACK_MIDDLEWARE_METHOD_ORDER = [\n \"middleware\",\n \"inputValidator\",\n \"client\",\n \"server\",\n \"handler\",\n];\n\nexport const TANSTACK_REDIRECT_FUNCTIONS = new Set([\"redirect\", \"notFound\"]);\n\nexport const TANSTACK_SERVER_FN_FILE_PATTERN = /\\.functions(\\.[jt]sx?)?$/;\n\nexport const SEQUENTIAL_AWAIT_THRESHOLD_FOR_LOADER = 2;\n\nexport const TANSTACK_QUERY_HOOKS = new Set([\n \"useQuery\",\n \"useInfiniteQuery\",\n \"useSuspenseQuery\",\n \"useSuspenseInfiniteQuery\",\n]);\n\nexport const TANSTACK_MUTATION_HOOKS = new Set([\"useMutation\"]);\n\nexport const TANSTACK_QUERY_CLIENT_CLASS = \"QueryClient\";\n\nexport const STABLE_HOOK_WRAPPERS = new Set([\"useState\", \"useMemo\", \"useRef\"]);\n\nexport const SCRIPT_LOADING_ATTRIBUTES = new Set([\"defer\", \"async\"]);\n\nexport const GENERIC_EVENT_SUFFIXES = new Set([\"Click\", \"Change\", \"Input\", \"Blur\", \"Focus\"]);\n\nexport const TRIVIAL_INITIALIZER_NAMES = new Set([\n \"Boolean\",\n \"String\",\n \"Number\",\n \"Array\",\n \"Object\",\n \"parseInt\",\n \"parseFloat\",\n]);\n\nexport const SETTER_PATTERN = /^set[A-Z]/;\nexport const RENDER_FUNCTION_PATTERN = /^render[A-Z]/;\nexport const UPPERCASE_PATTERN = /^[A-Z]/;\nexport const PAGE_FILE_PATTERN = /\\/page\\.(tsx?|jsx?)$/;\nexport const PAGE_OR_LAYOUT_FILE_PATTERN = /\\/(page|layout)\\.(tsx?|jsx?)$/;\n\nexport const INTERNAL_PAGE_PATH_PATTERN =\n /\\/(?:(?:\\((?:dashboard|admin|settings|account|internal|manage|console|portal|auth|onboarding|app|ee|protected)\\))|(?:dashboard|admin|settings|account|internal|manage|console|portal))\\//i;\n\nexport const TEST_FILE_PATTERN = /\\.(?:test|spec|stories)\\.[tj]sx?$/;\nexport const OG_ROUTE_PATTERN = /\\/og\\b/i;\n\nexport const PAGES_DIRECTORY_PATTERN = /\\/pages\\//;\nexport const SERVER_ACTION_FILE_PATTERN = /actions?\\.(tsx?|jsx?)$/;\nexport const SERVER_ACTION_DIRECTORY_PATTERN = /\\/actions\\//;\n\nexport const NEXTJS_NAVIGATION_FUNCTIONS = new Set([\n \"redirect\",\n \"permanentRedirect\",\n \"notFound\",\n \"forbidden\",\n \"unauthorized\",\n]);\n\nexport const GOOGLE_FONTS_PATTERN = /fonts\\.googleapis\\.com/;\n\nexport const POLYFILL_SCRIPT_PATTERN = /polyfill\\.io|polyfill\\.min\\.js|cdn\\.polyfill/;\n\nexport const EXECUTABLE_SCRIPT_TYPES = new Set([\n \"text/javascript\",\n \"application/javascript\",\n \"module\",\n]);\n\nexport const APP_DIRECTORY_PATTERN = /\\/app\\//;\n\nexport const ROUTE_HANDLER_FILE_PATTERN = /\\/route\\.(tsx?|jsx?)$/;\n\nexport const MUTATION_METHOD_NAMES = new Set([\n \"create\",\n \"insert\",\n \"insertInto\",\n \"update\",\n \"upsert\",\n \"delete\",\n \"remove\",\n \"destroy\",\n \"set\",\n \"append\",\n]);\n\nexport const MUTATING_HTTP_METHODS = new Set([\"POST\", \"PUT\", \"DELETE\", \"PATCH\"]);\n\nexport const MUTATING_ROUTE_SEGMENTS = new Set([\n \"logout\",\n \"log-out\",\n \"signout\",\n \"sign-out\",\n \"unsubscribe\",\n \"delete\",\n \"remove\",\n \"revoke\",\n \"cancel\",\n \"deactivate\",\n]);\n\nexport const EFFECT_HOOK_NAMES = new Set([\"useEffect\", \"useLayoutEffect\"]);\nexport const HOOKS_WITH_DEPS = new Set([\"useEffect\", \"useLayoutEffect\", \"useMemo\", \"useCallback\"]);\nexport const CHAINABLE_ITERATION_METHODS = new Set([\"map\", \"filter\", \"forEach\", \"flatMap\"]);\nexport const STORAGE_OBJECTS = new Set([\"localStorage\", \"sessionStorage\"]);\n\nexport const LARGE_BLUR_THRESHOLD_PX = 10;\nexport const BLUR_VALUE_PATTERN = /blur\\((\\d+(?:\\.\\d+)?)px\\)/;\nexport const ANIMATION_CALLBACK_NAMES = new Set([\"requestAnimationFrame\", \"setInterval\"]);\nexport const MOTION_LIBRARY_PACKAGES = new Set([\"framer-motion\", \"motion\"]);\n\nexport const RAW_TEXT_PREVIEW_MAX_CHARS = 30;\n\nexport const REACT_NATIVE_TEXT_COMPONENTS = new Set([\n \"Text\",\n \"TextInput\",\n \"Typography\",\n \"Paragraph\",\n \"Span\",\n \"H1\",\n \"H2\",\n \"H3\",\n \"H4\",\n \"H5\",\n \"H6\",\n]);\n\nexport const REACT_NATIVE_TEXT_COMPONENT_KEYWORDS = new Set([\n \"Text\",\n \"Title\",\n \"Label\",\n \"Heading\",\n \"Caption\",\n \"Subtitle\",\n \"Typography\",\n \"Paragraph\",\n \"Description\",\n \"Body\",\n]);\n\nexport const DEPRECATED_RN_MODULE_REPLACEMENTS: Record<string, string> = {\n AsyncStorage: \"@react-native-async-storage/async-storage\",\n Picker: \"@react-native-picker/picker\",\n PickerIOS: \"@react-native-picker/picker\",\n DatePickerIOS: \"@react-native-community/datetimepicker\",\n DatePickerAndroid: \"@react-native-community/datetimepicker\",\n ProgressBarAndroid: \"a community alternative\",\n ProgressViewIOS: \"a community alternative\",\n SafeAreaView: \"react-native-safe-area-context\",\n Slider: \"@react-native-community/slider\",\n ViewPagerAndroid: \"react-native-pager-view\",\n WebView: \"react-native-webview\",\n NetInfo: \"@react-native-community/netinfo\",\n CameraRoll: \"@react-native-camera-roll/camera-roll\",\n Clipboard: \"@react-native-clipboard/clipboard\",\n ImageEditor: \"@react-native-community/image-editor\",\n MaskedViewIOS: \"@react-native-masked-view/masked-view\",\n};\n\nexport const LEGACY_EXPO_PACKAGE_REPLACEMENTS: Record<string, string> = {\n \"expo-av\": \"expo-audio for audio and expo-video for video\",\n \"expo-permissions\": \"the permissions API in each module (e.g. Camera.requestPermissionsAsync())\",\n \"@expo/vector-icons\":\n \"expo-symbols or expo-image (see https://docs.expo.dev/versions/latest/sdk/symbols/)\",\n};\n\nexport const REACT_NATIVE_LIST_COMPONENTS = new Set([\n \"FlatList\",\n \"SectionList\",\n \"VirtualizedList\",\n \"FlashList\",\n]);\n\nexport const LEGACY_SHADOW_STYLE_PROPERTIES = new Set([\n \"shadowColor\",\n \"shadowOffset\",\n \"shadowOpacity\",\n \"shadowRadius\",\n \"elevation\",\n]);\n\nexport const BOUNCE_ANIMATION_NAMES = new Set([\"bounce\", \"elastic\", \"wobble\", \"jiggle\", \"spring\"]);\n\nexport const Z_INDEX_ABSURD_THRESHOLD = 100;\n\nexport const INLINE_STYLE_PROPERTY_THRESHOLD = 8;\n\nexport const SIDE_TAB_BORDER_WIDTH_WITHOUT_RADIUS_PX = 3;\n\nexport const SIDE_TAB_BORDER_WIDTH_WITH_RADIUS_PX = 1;\n\nexport const SIDE_TAB_TAILWIND_WIDTH_WITHOUT_RADIUS = 4;\n\nexport const DARK_GLOW_BLUR_THRESHOLD_PX = 4;\n\nexport const DARK_BACKGROUND_CHANNEL_MAX = 35;\n\nexport const COLOR_CHROMA_THRESHOLD = 30;\n\nexport const TINY_TEXT_THRESHOLD_PX = 12;\n\nexport const WIDE_TRACKING_THRESHOLD_EM = 0.05;\n\nexport const LONG_TRANSITION_DURATION_THRESHOLD_MS = 1000;\n","import {\n FETCH_CALLEE_NAMES,\n FETCH_MEMBER_OBJECTS,\n LOOP_TYPES,\n MUTATING_HTTP_METHODS,\n MUTATION_METHOD_NAMES,\n SETTER_PATTERN,\n UPPERCASE_PATTERN,\n} from \"./constants.js\";\nimport type { EsTreeNode, RuleVisitors } from \"./types.js\";\n\nexport const walkAst = (node: EsTreeNode, visitor: (child: EsTreeNode) => void): void => {\n if (!node || typeof node !== \"object\") return;\n visitor(node);\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 (item && typeof item === \"object\" && item.type) {\n walkAst(item, visitor);\n }\n }\n } else if (child && typeof child === \"object\" && child.type) {\n walkAst(child, visitor);\n }\n }\n};\n\nexport const isSetterIdentifier = (name: string): boolean => SETTER_PATTERN.test(name);\n\nexport const isSetterCall = (node: EsTreeNode): boolean =>\n node.type === \"CallExpression\" &&\n node.callee?.type === \"Identifier\" &&\n isSetterIdentifier(node.callee.name);\n\nexport const isUppercaseName = (name: string): boolean => UPPERCASE_PATTERN.test(name);\n\nexport const isMemberProperty = (node: EsTreeNode, propertyName: string): boolean =>\n node.type === \"MemberExpression\" &&\n node.property?.type === \"Identifier\" &&\n node.property.name === propertyName;\n\nexport const getEffectCallback = (node: EsTreeNode): EsTreeNode | null => {\n if (!node.arguments?.length) return null;\n const callback = node.arguments[0];\n if (callback.type === \"ArrowFunctionExpression\" || callback.type === \"FunctionExpression\") {\n return callback;\n }\n return null;\n};\n\nexport const getCallbackStatements = (callback: EsTreeNode): EsTreeNode[] => {\n if (callback.body?.type === \"BlockStatement\") {\n return callback.body.body ?? [];\n }\n return callback.body ? [callback.body] : [];\n};\n\nexport const countSetStateCalls = (node: EsTreeNode): number => {\n let setStateCallCount = 0;\n walkAst(node, (child) => {\n if (isSetterCall(child)) setStateCallCount++;\n });\n return setStateCallCount;\n};\n\nexport const isSimpleExpression = (node: EsTreeNode | null): boolean => {\n if (!node) return false;\n switch (node.type) {\n case \"Identifier\":\n case \"Literal\":\n case \"TemplateLiteral\":\n return true;\n case \"BinaryExpression\":\n return isSimpleExpression(node.left) && isSimpleExpression(node.right);\n case \"UnaryExpression\":\n return isSimpleExpression(node.argument);\n case \"MemberExpression\":\n return !node.computed && isSimpleExpression(node.object);\n case \"ConditionalExpression\":\n return (\n isSimpleExpression(node.test) &&\n isSimpleExpression(node.consequent) &&\n isSimpleExpression(node.alternate)\n );\n default:\n return false;\n }\n};\n\nexport const isComponentDeclaration = (node: EsTreeNode): boolean =>\n node.type === \"FunctionDeclaration\" && Boolean(node.id?.name) && isUppercaseName(node.id.name);\n\nexport const isComponentAssignment = (node: EsTreeNode): boolean =>\n node.type === \"VariableDeclarator\" &&\n node.id?.type === \"Identifier\" &&\n isUppercaseName(node.id.name) &&\n Boolean(node.init) &&\n (node.init.type === \"ArrowFunctionExpression\" || node.init.type === \"FunctionExpression\");\n\nexport const getCalleeName = (node: EsTreeNode): string | null => {\n if (node.callee?.type === \"Identifier\") return node.callee.name;\n if (node.callee?.type === \"MemberExpression\" && node.callee.property?.type === \"Identifier\") {\n return node.callee.property.name;\n }\n return null;\n};\n\nexport const isHookCall = (node: EsTreeNode, hookName: string | Set<string>): boolean => {\n if (node.type !== \"CallExpression\") return false;\n const calleeName = getCalleeName(node);\n if (!calleeName) return false;\n return typeof hookName === \"string\" ? calleeName === hookName : hookName.has(calleeName);\n};\n\nexport const hasDirective = (programNode: EsTreeNode, directive: string): boolean =>\n Boolean(\n programNode.body?.some(\n (statement: EsTreeNode) =>\n statement.type === \"ExpressionStatement\" &&\n statement.expression?.type === \"Literal\" &&\n statement.expression.value === directive,\n ),\n );\n\nexport const hasUseServerDirective = (node: EsTreeNode): boolean => {\n if (node.body?.type !== \"BlockStatement\") return false;\n return Boolean(\n node.body.body?.some(\n (statement: EsTreeNode) =>\n statement.type === \"ExpressionStatement\" && statement.directive === \"use server\",\n ),\n );\n};\n\nexport const containsFetchCall = (node: EsTreeNode): boolean => {\n let didFindFetchCall = false;\n walkAst(node, (child) => {\n if (didFindFetchCall || child.type !== \"CallExpression\") return;\n if (child.callee?.type === \"Identifier\" && FETCH_CALLEE_NAMES.has(child.callee.name)) {\n didFindFetchCall = true;\n }\n if (\n child.callee?.type === \"MemberExpression\" &&\n child.callee.object?.type === \"Identifier\" &&\n FETCH_MEMBER_OBJECTS.has(child.callee.object.name)\n ) {\n didFindFetchCall = true;\n }\n });\n return didFindFetchCall;\n};\n\nexport const findJsxAttribute = (\n attributes: EsTreeNode[],\n attributeName: string,\n): EsTreeNode | undefined =>\n attributes?.find(\n (attr: EsTreeNode) =>\n attr.type === \"JSXAttribute\" &&\n attr.name?.type === \"JSXIdentifier\" &&\n attr.name.name === attributeName,\n );\n\nexport const hasJsxAttribute = (attributes: EsTreeNode[], attributeName: string): boolean =>\n Boolean(findJsxAttribute(attributes, attributeName));\n\nexport const createLoopAwareVisitors = (\n innerVisitors: Record<string, (node: EsTreeNode) => void>,\n): RuleVisitors => {\n let loopDepth = 0;\n const incrementLoopDepth = (): void => {\n loopDepth++;\n };\n const decrementLoopDepth = (): void => {\n loopDepth--;\n };\n\n const visitors: RuleVisitors = {};\n\n for (const loopType of LOOP_TYPES) {\n visitors[loopType] = incrementLoopDepth;\n visitors[`${loopType}:exit`] = decrementLoopDepth;\n }\n\n for (const [nodeType, handler] of Object.entries(innerVisitors)) {\n visitors[nodeType] = (node: EsTreeNode) => {\n if (loopDepth > 0) handler(node);\n };\n }\n\n return visitors;\n};\n\nconst isCookiesOrHeadersCall = (node: EsTreeNode, methodName: string): boolean => {\n if (node.type !== \"CallExpression\" || node.callee?.type !== \"MemberExpression\") return false;\n const { object, property } = node.callee;\n if (property?.type !== \"Identifier\" || !MUTATION_METHOD_NAMES.has(property.name)) return false;\n if (object?.type !== \"CallExpression\" || object.callee?.type !== \"Identifier\") return false;\n return object.callee.name === methodName;\n};\n\nconst isMutatingDbCall = (node: EsTreeNode): boolean => {\n if (node.type !== \"CallExpression\" || node.callee?.type !== \"MemberExpression\") return false;\n const { property } = node.callee;\n return property?.type === \"Identifier\" && MUTATION_METHOD_NAMES.has(property.name);\n};\n\nconst isMutatingFetchCall = (node: EsTreeNode): boolean => {\n if (node.type !== \"CallExpression\") return false;\n if (node.callee?.type !== \"Identifier\" || node.callee.name !== \"fetch\") return false;\n const optionsArgument = node.arguments?.[1];\n if (!optionsArgument || optionsArgument.type !== \"ObjectExpression\") return false;\n return optionsArgument.properties?.some(\n (property: EsTreeNode) =>\n property.type === \"Property\" &&\n property.key?.type === \"Identifier\" &&\n property.key.name === \"method\" &&\n property.value?.type === \"Literal\" &&\n typeof property.value.value === \"string\" &&\n MUTATING_HTTP_METHODS.has(property.value.value.toUpperCase()),\n );\n};\n\nexport const findSideEffect = (node: EsTreeNode): string | null => {\n let sideEffectDescription: string | null = null;\n walkAst(node, (child: EsTreeNode) => {\n if (sideEffectDescription) return;\n if (isCookiesOrHeadersCall(child, \"cookies\")) {\n const methodName = child.callee.property.name;\n sideEffectDescription = `cookies().${methodName}()`;\n } else if (isCookiesOrHeadersCall(child, \"headers\")) {\n const methodName = child.callee.property.name;\n sideEffectDescription = `headers().${methodName}()`;\n } else if (isMutatingFetchCall(child)) {\n const methodProperty = child.arguments[1].properties.find(\n (property: EsTreeNode) =>\n property.key?.type === \"Identifier\" && property.key.name === \"method\",\n );\n sideEffectDescription = `fetch() with method ${methodProperty.value.value}`;\n } else if (isMutatingDbCall(child)) {\n const methodName = child.callee.property.name;\n const objectName =\n child.callee.object?.type === \"Identifier\" ? child.callee.object.name : null;\n sideEffectDescription = objectName ? `${objectName}.${methodName}()` : `.${methodName}()`;\n }\n });\n return sideEffectDescription;\n};\n\nexport const extractDestructuredPropNames = (params: EsTreeNode[]): Set<string> => {\n const propNames = new Set<string>();\n for (const param of params) {\n if (param.type === \"ObjectPattern\") {\n for (const property of param.properties ?? []) {\n if (property.type === \"Property\" && property.key?.type === \"Identifier\") {\n propNames.add(property.key.name);\n }\n }\n } else if (param.type === \"Identifier\") {\n propNames.add(param.name);\n }\n }\n return propNames;\n};\n","import {\n GENERIC_EVENT_SUFFIXES,\n GIANT_COMPONENT_LINE_THRESHOLD,\n RENDER_FUNCTION_PATTERN,\n} from \"../constants.js\";\nimport { isComponentAssignment, isComponentDeclaration, isUppercaseName } from \"../helpers.js\";\nimport type { EsTreeNode, Rule, RuleContext } from \"../types.js\";\n\nexport const noGenericHandlerNames: Rule = {\n create: (context: RuleContext) => ({\n JSXAttribute(node: EsTreeNode) {\n if (node.name?.type !== \"JSXIdentifier\" || !node.name.name.startsWith(\"on\")) return;\n if (!node.value || node.value.type !== \"JSXExpressionContainer\") return;\n\n const eventSuffix = node.name.name.slice(2);\n if (!GENERIC_EVENT_SUFFIXES.has(eventSuffix)) return;\n\n const mirroredHandlerName = `handle${eventSuffix}`;\n const expression = node.value.expression;\n if (expression?.type === \"Identifier\" && expression.name === mirroredHandlerName) {\n context.report({\n node,\n message: `Non-descriptive handler name \"${expression.name}\" — name should describe what it does, not when it runs`,\n });\n }\n },\n }),\n};\n\nexport const noGiantComponent: Rule = {\n create: (context: RuleContext) => {\n const reportOversizedComponent = (\n nameNode: EsTreeNode,\n componentName: string,\n bodyNode: EsTreeNode,\n ): void => {\n if (!bodyNode.loc) return;\n const lineCount = bodyNode.loc.end.line - bodyNode.loc.start.line + 1;\n if (lineCount > GIANT_COMPONENT_LINE_THRESHOLD) {\n context.report({\n node: nameNode,\n message: `Component \"${componentName}\" is ${lineCount} lines — consider breaking it into smaller focused components`,\n });\n }\n };\n\n return {\n FunctionDeclaration(node: EsTreeNode) {\n if (!node.id?.name || !isUppercaseName(node.id.name)) return;\n reportOversizedComponent(node.id, node.id.name, node);\n },\n VariableDeclarator(node: EsTreeNode) {\n if (!isComponentAssignment(node)) return;\n reportOversizedComponent(node.id, node.id.name, node.init);\n },\n };\n },\n};\n\nexport const noRenderInRender: Rule = {\n create: (context: RuleContext) => ({\n JSXExpressionContainer(node: EsTreeNode) {\n const expression = node.expression;\n if (expression?.type !== \"CallExpression\") return;\n\n let calleeName: string | null = null;\n if (expression.callee?.type === \"Identifier\") {\n calleeName = expression.callee.name;\n } else if (\n expression.callee?.type === \"MemberExpression\" &&\n expression.callee.property?.type === \"Identifier\"\n ) {\n calleeName = expression.callee.property.name;\n }\n\n if (calleeName && RENDER_FUNCTION_PATTERN.test(calleeName)) {\n context.report({\n node: expression,\n message: `Inline render function \"${calleeName}()\" — extract to a separate component for proper reconciliation`,\n });\n }\n },\n }),\n};\n\nexport const noNestedComponentDefinition: Rule = {\n create: (context: RuleContext) => {\n const componentStack: string[] = [];\n\n return {\n FunctionDeclaration(node: EsTreeNode) {\n if (!isComponentDeclaration(node)) return;\n if (componentStack.length > 0) {\n context.report({\n node: node.id,\n message: `Component \"${node.id.name}\" defined inside \"${componentStack[componentStack.length - 1]}\" — creates new instance every render, destroying state`,\n });\n }\n componentStack.push(node.id.name);\n },\n \"FunctionDeclaration:exit\"(node: EsTreeNode) {\n if (isComponentDeclaration(node)) componentStack.pop();\n },\n VariableDeclarator(node: EsTreeNode) {\n if (!isComponentAssignment(node)) return;\n if (componentStack.length > 0) {\n context.report({\n node: node.id,\n message: `Component \"${node.id.name}\" defined inside \"${componentStack[componentStack.length - 1]}\" — creates new instance every render, destroying state`,\n });\n }\n componentStack.push(node.id.name);\n },\n \"VariableDeclarator:exit\"(node: EsTreeNode) {\n if (isComponentAssignment(node)) componentStack.pop();\n },\n };\n },\n};\n","import { BARREL_INDEX_SUFFIXES, HEAVY_LIBRARIES } from \"../constants.js\";\nimport { findJsxAttribute, hasJsxAttribute } from \"../helpers.js\";\nimport type { EsTreeNode, Rule, RuleContext } from \"../types.js\";\n\nexport const noBarrelImport: Rule = {\n create: (context: RuleContext) => {\n let didReportForFile = false;\n\n return {\n ImportDeclaration(node: EsTreeNode) {\n if (didReportForFile) return;\n\n const source = node.source?.value;\n if (typeof source !== \"string\" || !source.startsWith(\".\")) return;\n\n if (BARREL_INDEX_SUFFIXES.some((suffix) => source.endsWith(suffix))) {\n didReportForFile = true;\n context.report({\n node,\n message:\n \"Import from barrel/index file — import directly from the source module for better tree-shaking\",\n });\n }\n },\n };\n },\n};\n\nexport const noFullLodashImport: Rule = {\n create: (context: RuleContext) => ({\n ImportDeclaration(node: EsTreeNode) {\n const source = node.source?.value;\n if (source === \"lodash\" || source === \"lodash-es\") {\n context.report({\n node,\n message: \"Importing entire lodash library — import from 'lodash/functionName' instead\",\n });\n }\n },\n }),\n};\n\nexport const noMoment: Rule = {\n create: (context: RuleContext) => ({\n ImportDeclaration(node: EsTreeNode) {\n if (node.source?.value === \"moment\") {\n context.report({\n node,\n message: 'moment.js is 300kb+ — use \"date-fns\" or \"dayjs\" instead',\n });\n }\n },\n }),\n};\n\nexport const preferDynamicImport: Rule = {\n create: (context: RuleContext) => ({\n ImportDeclaration(node: EsTreeNode) {\n const source = node.source?.value;\n if (typeof source === \"string\" && HEAVY_LIBRARIES.has(source)) {\n context.report({\n node,\n message: `\"${source}\" is a heavy library — use React.lazy() or next/dynamic for code splitting`,\n });\n }\n },\n }),\n};\n\nexport const useLazyMotion: Rule = {\n create: (context: RuleContext) => ({\n ImportDeclaration(node: EsTreeNode) {\n const source = node.source?.value;\n if (source !== \"framer-motion\" && source !== \"motion/react\") return;\n\n const hasFullMotionImport = node.specifiers?.some(\n (specifier: EsTreeNode) =>\n specifier.type === \"ImportSpecifier\" && specifier.imported?.name === \"motion\",\n );\n\n if (hasFullMotionImport) {\n context.report({\n node,\n message: 'Import \"m\" with LazyMotion instead of \"motion\" — saves ~30kb in bundle size',\n });\n }\n },\n }),\n};\n\nexport const noUndeferredThirdParty: Rule = {\n create: (context: RuleContext) => ({\n JSXOpeningElement(node: EsTreeNode) {\n if (node.name?.type !== \"JSXIdentifier\" || node.name.name !== \"script\") return;\n const attributes = node.attributes ?? [];\n if (!findJsxAttribute(attributes, \"src\")) return;\n\n if (!hasJsxAttribute(attributes, \"defer\") && !hasJsxAttribute(attributes, \"async\")) {\n context.report({\n node,\n message:\n \"Synchronous <script> with src — add defer or async to avoid blocking first paint\",\n });\n }\n },\n }),\n};\n","import { PASSIVE_EVENT_NAMES } from \"../constants.js\";\nimport { isMemberProperty } from \"../helpers.js\";\nimport type { EsTreeNode, Rule, RuleContext } from \"../types.js\";\n\nexport const clientPassiveEventListeners: Rule = {\n create: (context: RuleContext) => ({\n CallExpression(node: EsTreeNode) {\n if (!isMemberProperty(node.callee, \"addEventListener\")) return;\n if (node.arguments?.length < 2) return;\n\n const eventNameNode = node.arguments[0];\n if (eventNameNode.type !== \"Literal\" || !PASSIVE_EVENT_NAMES.has(eventNameNode.value)) return;\n\n const eventName = eventNameNode.value;\n const optionsArgument = node.arguments[2];\n\n if (!optionsArgument) {\n context.report({\n node,\n message: `\"${eventName}\" listener without { passive: true } — blocks scrolling performance`,\n });\n return;\n }\n\n if (optionsArgument.type !== \"ObjectExpression\") return;\n\n const hasPassiveTrue = optionsArgument.properties?.some(\n (property: EsTreeNode) =>\n property.type === \"Property\" &&\n property.key?.type === \"Identifier\" &&\n property.key.name === \"passive\" &&\n property.value?.type === \"Literal\" &&\n property.value.value === true,\n );\n\n if (!hasPassiveTrue) {\n context.report({\n node,\n message: `\"${eventName}\" listener without { passive: true } — blocks scrolling performance`,\n });\n }\n },\n }),\n};\n","import {\n BOUNCE_ANIMATION_NAMES,\n COLOR_CHROMA_THRESHOLD,\n DARK_BACKGROUND_CHANNEL_MAX,\n DARK_GLOW_BLUR_THRESHOLD_PX,\n INLINE_STYLE_PROPERTY_THRESHOLD,\n LONG_TRANSITION_DURATION_THRESHOLD_MS,\n SIDE_TAB_BORDER_WIDTH_WITH_RADIUS_PX,\n SIDE_TAB_BORDER_WIDTH_WITHOUT_RADIUS_PX,\n SIDE_TAB_TAILWIND_WIDTH_WITHOUT_RADIUS,\n TINY_TEXT_THRESHOLD_PX,\n WIDE_TRACKING_THRESHOLD_EM,\n Z_INDEX_ABSURD_THRESHOLD,\n} from \"../constants.js\";\nimport { findJsxAttribute, walkAst } from \"../helpers.js\";\nimport type { EsTreeNode, ParsedRgb, Rule, RuleContext } from \"../types.js\";\n\nconst isOvershootCubicBezier = (value: string): boolean => {\n const match = value.match(\n /cubic-bezier\\(\\s*([\\d.-]+)\\s*,\\s*([\\d.-]+)\\s*,\\s*([\\d.-]+)\\s*,\\s*([\\d.-]+)\\s*\\)/,\n );\n if (!match) return false;\n const controlY1 = parseFloat(match[2]);\n const controlY2 = parseFloat(match[4]);\n return controlY1 < -0.1 || controlY1 > 1.1 || controlY2 < -0.1 || controlY2 > 1.1;\n};\n\nconst hasBounceAnimationName = (value: string): boolean => {\n const lowerValue = value.toLowerCase();\n for (const name of BOUNCE_ANIMATION_NAMES) {\n if (lowerValue.includes(name)) return true;\n }\n return false;\n};\n\nconst getStringFromClassNameAttr = (node: EsTreeNode): string | null => {\n const classAttr = findJsxAttribute(node.attributes ?? [], \"className\");\n if (!classAttr?.value) return null;\n if (classAttr.value.type === \"Literal\" && typeof classAttr.value.value === \"string\") {\n return classAttr.value.value;\n }\n if (\n classAttr.value.type === \"JSXExpressionContainer\" &&\n classAttr.value.expression?.type === \"Literal\" &&\n typeof classAttr.value.expression.value === \"string\"\n ) {\n return classAttr.value.expression.value;\n }\n if (\n classAttr.value.type === \"JSXExpressionContainer\" &&\n classAttr.value.expression?.type === \"TemplateLiteral\" &&\n classAttr.value.expression.quasis?.length === 1\n ) {\n return classAttr.value.expression.quasis[0].value?.raw ?? null;\n }\n return null;\n};\n\nconst getInlineStyleExpression = (node: EsTreeNode): EsTreeNode | null => {\n if (node.name?.type !== \"JSXIdentifier\" || node.name.name !== \"style\") return null;\n if (node.value?.type !== \"JSXExpressionContainer\") return null;\n const expression = node.value.expression;\n if (expression?.type !== \"ObjectExpression\") return null;\n return expression;\n};\n\nconst getStylePropertyStringValue = (property: EsTreeNode): string | null => {\n if (property.value?.type === \"Literal\" && typeof property.value.value === \"string\") {\n return property.value.value;\n }\n return null;\n};\n\nconst getStylePropertyNumberValue = (property: EsTreeNode): number | null => {\n if (property.value?.type === \"Literal\" && typeof property.value.value === \"number\") {\n return property.value.value;\n }\n if (\n property.value?.type === \"UnaryExpression\" &&\n property.value.operator === \"-\" &&\n property.value.argument?.type === \"Literal\" &&\n typeof property.value.argument.value === \"number\"\n ) {\n return -property.value.argument.value;\n }\n return null;\n};\n\nconst getStylePropertyKey = (property: EsTreeNode): string | null => {\n if (property.type !== \"Property\") return null;\n if (property.key?.type === \"Identifier\") return property.key.name;\n if (property.key?.type === \"Literal\" && typeof property.key.value === \"string\")\n return property.key.value;\n return null;\n};\n\nconst parseColorToRgb = (value: string): ParsedRgb | null => {\n const trimmed = value.trim().toLowerCase();\n\n const hex6Match = trimmed.match(/^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/);\n if (hex6Match) {\n return {\n red: parseInt(hex6Match[1], 16),\n green: parseInt(hex6Match[2], 16),\n blue: parseInt(hex6Match[3], 16),\n };\n }\n\n const hex3Match = trimmed.match(/^#([0-9a-f])([0-9a-f])([0-9a-f])$/);\n if (hex3Match) {\n return {\n red: parseInt(hex3Match[1] + hex3Match[1], 16),\n green: parseInt(hex3Match[2] + hex3Match[2], 16),\n blue: parseInt(hex3Match[3] + hex3Match[3], 16),\n };\n }\n\n const rgbMatch = trimmed.match(/rgba?\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)/);\n if (rgbMatch) {\n return {\n red: parseInt(rgbMatch[1], 10),\n green: parseInt(rgbMatch[2], 10),\n blue: parseInt(rgbMatch[3], 10),\n };\n }\n\n return null;\n};\n\nconst hasColorChroma = (parsed: ParsedRgb): boolean =>\n Math.max(parsed.red, parsed.green, parsed.blue) -\n Math.min(parsed.red, parsed.green, parsed.blue) >=\n COLOR_CHROMA_THRESHOLD;\n\nconst isNeutralBorderColor = (value: string): boolean => {\n const trimmed = value.trim().toLowerCase();\n if ([\"gray\", \"grey\", \"silver\", \"white\", \"black\", \"transparent\", \"currentcolor\"].includes(trimmed))\n return true;\n\n const parsed = parseColorToRgb(trimmed);\n if (parsed) return !hasColorChroma(parsed);\n\n return false;\n};\n\nconst extractBorderColorFromShorthand = (shorthandValue: string): string | null => {\n const afterSolid = shorthandValue.match(/solid\\s+(.+)$/i);\n if (!afterSolid) return null;\n return afterSolid[1].trim();\n};\n\nconst isPureBlackColor = (value: string): boolean => {\n const trimmed = value.trim().toLowerCase();\n if (trimmed === \"#000\" || trimmed === \"#000000\") return true;\n if (/^rgb\\(\\s*0\\s*,\\s*0\\s*,\\s*0\\s*\\)$/.test(trimmed)) return true;\n return false;\n};\n\nconst splitShadowLayers = (shadowValue: string): string[] => shadowValue.split(/,(?![^(]*\\))/);\n\nconst extractColorFromShadowLayer = (layer: string): ParsedRgb | null => {\n const rgbMatch = layer.match(/rgba?\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)/);\n if (rgbMatch) {\n return {\n red: parseInt(rgbMatch[1], 10),\n green: parseInt(rgbMatch[2], 10),\n blue: parseInt(rgbMatch[3], 10),\n };\n }\n\n const hexMatch = layer.match(/#([0-9a-f]{3,6})\\b/i);\n if (hexMatch) return parseColorToRgb(`#${hexMatch[1]}`);\n\n return null;\n};\n\nconst parseShadowLayerBlur = (layer: string): number => {\n const withoutColors = layer.replace(/rgba?\\([^)]*\\)/g, \"\").replace(/#[0-9a-f]{3,8}\\b/gi, \"\");\n const numericTokens = [...withoutColors.matchAll(/(\\d+(?:\\.\\d+)?)(px)?/g)].map((match) =>\n parseFloat(match[1]),\n );\n return numericTokens.length >= 3 ? numericTokens[2] : 0;\n};\n\nconst hasColoredGlowShadow = (shadowValue: string): boolean => {\n for (const layer of splitShadowLayers(shadowValue)) {\n const color = extractColorFromShadowLayer(layer);\n if (\n color &&\n hasColorChroma(color) &&\n parseShadowLayerBlur(layer) > DARK_GLOW_BLUR_THRESHOLD_PX\n ) {\n return true;\n }\n }\n return false;\n};\n\nconst isBackgroundDark = (bgValue: string): boolean => {\n const trimmed = bgValue.trim().toLowerCase();\n if (isPureBlackColor(trimmed)) return true;\n\n const parsed = parseColorToRgb(trimmed);\n if (!parsed) return false;\n\n return (\n parsed.red <= DARK_BACKGROUND_CHANNEL_MAX &&\n parsed.green <= DARK_BACKGROUND_CHANNEL_MAX &&\n parsed.blue <= DARK_BACKGROUND_CHANNEL_MAX\n );\n};\n\nconst BORDER_SIDE_KEYS: Record<string, string> = {\n borderLeft: \"left\",\n borderRight: \"right\",\n borderInlineStart: \"left\",\n borderInlineEnd: \"right\",\n};\n\nconst BORDER_SIDE_WIDTH_KEYS = new Set([\n \"borderLeftWidth\",\n \"borderRightWidth\",\n \"borderInlineStartWidth\",\n \"borderInlineEndWidth\",\n]);\n\nexport const noInlineBounceEasing: Rule = {\n create: (context: RuleContext) => ({\n JSXAttribute(node: EsTreeNode) {\n const expression = getInlineStyleExpression(node);\n if (!expression) return;\n\n for (const property of expression.properties ?? []) {\n const key = getStylePropertyKey(property);\n if (!key) continue;\n\n const value = getStylePropertyStringValue(property);\n if (!value) continue;\n\n if (\n (key === \"transition\" ||\n key === \"transitionTimingFunction\" ||\n key === \"animation\" ||\n key === \"animationTimingFunction\") &&\n isOvershootCubicBezier(value)\n ) {\n context.report({\n node: property,\n message:\n \"Bounce/elastic easing feels dated — real objects decelerate smoothly. Use ease-out or cubic-bezier(0.16, 1, 0.3, 1) instead\",\n });\n }\n\n if ((key === \"animation\" || key === \"animationName\") && hasBounceAnimationName(value)) {\n context.report({\n node: property,\n message:\n \"Bounce/elastic animation name detected — these feel tacky. Use exponential easing (ease-out-quart/expo) for natural deceleration\",\n });\n }\n }\n },\n JSXOpeningElement(node: EsTreeNode) {\n const classStr = getStringFromClassNameAttr(node);\n if (!classStr) return;\n\n if (/\\banimate-bounce\\b/.test(classStr)) {\n context.report({\n node,\n message:\n \"animate-bounce feels dated and tacky — use a subtle ease-out transform for natural deceleration\",\n });\n }\n },\n }),\n};\n\nexport const noZIndex9999: Rule = {\n create: (context: RuleContext) => ({\n JSXAttribute(node: EsTreeNode) {\n const expression = getInlineStyleExpression(node);\n if (!expression) return;\n\n for (const property of expression.properties ?? []) {\n const key = getStylePropertyKey(property);\n if (key !== \"zIndex\") continue;\n\n const zValue = getStylePropertyNumberValue(property);\n if (zValue !== null && Math.abs(zValue) >= Z_INDEX_ABSURD_THRESHOLD) {\n context.report({\n node: property,\n message: `z-index: ${zValue} is arbitrarily high — use a deliberate z-index scale (1–50). Extreme values signal a stacking context problem, not a fix`,\n });\n }\n }\n },\n CallExpression(node: EsTreeNode) {\n if (node.callee?.type !== \"MemberExpression\") return;\n if (node.callee.property?.type !== \"Identifier\" || node.callee.property.name !== \"create\")\n return;\n if (node.callee.object?.type !== \"Identifier\" || node.callee.object.name !== \"StyleSheet\")\n return;\n\n const argument = node.arguments?.[0];\n if (!argument || argument.type !== \"ObjectExpression\") return;\n\n walkAst(argument, (child: EsTreeNode) => {\n if (child.type !== \"Property\") return;\n const key = getStylePropertyKey(child);\n if (key !== \"zIndex\") return;\n\n if (child.value?.type === \"Literal\" && typeof child.value.value === \"number\") {\n const zValue = child.value.value;\n if (Math.abs(zValue) >= Z_INDEX_ABSURD_THRESHOLD) {\n context.report({\n node: child,\n message: `z-index: ${zValue} is arbitrarily high — use a deliberate z-index scale (1–50). Extreme values signal a stacking context problem, not a fix`,\n });\n }\n }\n });\n },\n }),\n};\n\nexport const noInlineExhaustiveStyle: Rule = {\n create: (context: RuleContext) => ({\n JSXAttribute(node: EsTreeNode) {\n const expression = getInlineStyleExpression(node);\n if (!expression) return;\n\n const propertyCount =\n expression.properties?.filter((property: EsTreeNode) => property.type === \"Property\")\n .length ?? 0;\n\n if (propertyCount >= INLINE_STYLE_PROPERTY_THRESHOLD) {\n context.report({\n node: expression,\n message: `${propertyCount} inline style properties — extract to a CSS class, CSS module, or styled component for maintainability and reuse`,\n });\n }\n },\n }),\n};\n\nexport const noSideTabBorder: Rule = {\n create: (context: RuleContext) => ({\n JSXAttribute(node: EsTreeNode) {\n const expression = getInlineStyleExpression(node);\n if (!expression) return;\n\n let hasBorderRadius = false;\n for (const property of expression.properties ?? []) {\n const key = getStylePropertyKey(property);\n if (key === \"borderRadius\") {\n const numValue = getStylePropertyNumberValue(property);\n const strValue = getStylePropertyStringValue(property);\n if (\n (numValue !== null && numValue > 0) ||\n (strValue !== null && parseFloat(strValue) > 0)\n ) {\n hasBorderRadius = true;\n }\n }\n }\n\n const threshold = hasBorderRadius\n ? SIDE_TAB_BORDER_WIDTH_WITH_RADIUS_PX\n : SIDE_TAB_BORDER_WIDTH_WITHOUT_RADIUS_PX;\n\n for (const property of expression.properties ?? []) {\n const key = getStylePropertyKey(property);\n if (!key) continue;\n\n if (key in BORDER_SIDE_KEYS) {\n const value = getStylePropertyStringValue(property);\n if (!value) continue;\n const widthMatch = value.match(/^(\\d+)px\\s+solid/);\n if (!widthMatch) continue;\n\n const borderColor = extractBorderColorFromShorthand(value);\n if (borderColor && isNeutralBorderColor(borderColor)) continue;\n\n const width = parseInt(widthMatch[1], 10);\n if (width >= threshold) {\n context.report({\n node: property,\n message: `Thick one-sided border (${BORDER_SIDE_KEYS[key]}: ${width}px) — the most recognizable tell of AI-generated UIs. Use a subtler accent or remove it`,\n });\n }\n }\n\n if (BORDER_SIDE_WIDTH_KEYS.has(key)) {\n const numValue = getStylePropertyNumberValue(property);\n const strValue = getStylePropertyStringValue(property);\n const width = numValue ?? (strValue !== null ? parseFloat(strValue) : NaN);\n if (isNaN(width)) continue;\n\n const colorKey = key.replace(\"Width\", \"Color\");\n const hasColoredBorder = expression.properties?.some((colorProperty: EsTreeNode) => {\n const colorPropertyKey = getStylePropertyKey(colorProperty);\n if (colorPropertyKey !== colorKey) return false;\n const colorValue = getStylePropertyStringValue(colorProperty);\n return colorValue !== null && !isNeutralBorderColor(colorValue);\n });\n if (!hasColoredBorder) continue;\n\n if (width >= threshold) {\n context.report({\n node: property,\n message: `Thick one-sided border (${width}px) — the most recognizable tell of AI-generated UIs. Use a subtler accent or remove it`,\n });\n }\n }\n }\n },\n JSXOpeningElement(node: EsTreeNode) {\n const classStr = getStringFromClassNameAttr(node);\n if (!classStr) return;\n\n const sideMatch = classStr.match(/\\bborder-[lrse]-(\\d+)\\b/);\n if (!sideMatch) return;\n\n const hasNeutralBorderColor =\n /\\bborder-(?:(?:gray|slate|zinc|neutral|stone)-\\d+|white|black|transparent)\\b/.test(\n classStr,\n );\n if (hasNeutralBorderColor) return;\n\n const width = parseInt(sideMatch[1], 10);\n const hasRounded =\n /\\brounded(?:-(?!none\\b)\\w+)?\\b/.test(classStr) && !/\\brounded-none\\b/.test(classStr);\n const tailwindThreshold = hasRounded\n ? SIDE_TAB_BORDER_WIDTH_WITH_RADIUS_PX\n : SIDE_TAB_TAILWIND_WIDTH_WITHOUT_RADIUS;\n\n if (width >= tailwindThreshold) {\n context.report({\n node,\n message: `Thick one-sided border (${sideMatch[0]}) — the most recognizable tell of AI-generated UIs. Use a subtler accent or remove it`,\n });\n }\n },\n }),\n};\n\nexport const noPureBlackBackground: Rule = {\n create: (context: RuleContext) => ({\n JSXAttribute(node: EsTreeNode) {\n const expression = getInlineStyleExpression(node);\n if (!expression) return;\n\n for (const property of expression.properties ?? []) {\n const key = getStylePropertyKey(property);\n if (key !== \"backgroundColor\" && key !== \"background\") continue;\n\n const value = getStylePropertyStringValue(property);\n if (value && isPureBlackColor(value)) {\n context.report({\n node: property,\n message:\n \"Pure #000 background looks harsh — tint slightly toward your brand hue for a more refined feel (e.g. #0a0a0f)\",\n });\n }\n }\n },\n JSXOpeningElement(node: EsTreeNode) {\n const classStr = getStringFromClassNameAttr(node);\n if (!classStr) return;\n\n if (/\\bbg-black\\b(?!\\/)/.test(classStr)) {\n context.report({\n node,\n message:\n \"Pure black background (bg-black) looks harsh — use a near-black tinted toward your brand hue (e.g. bg-gray-950)\",\n });\n }\n },\n }),\n};\n\nexport const noGradientText: Rule = {\n create: (context: RuleContext) => ({\n JSXAttribute(node: EsTreeNode) {\n const expression = getInlineStyleExpression(node);\n if (!expression) return;\n\n let hasBackgroundClipText = false;\n let hasGradientBackground = false;\n\n for (const property of expression.properties ?? []) {\n const key = getStylePropertyKey(property);\n const value = getStylePropertyStringValue(property);\n if (!key || !value) continue;\n\n if ((key === \"backgroundClip\" || key === \"WebkitBackgroundClip\") && value === \"text\") {\n hasBackgroundClipText = true;\n }\n if ((key === \"backgroundImage\" || key === \"background\") && value.includes(\"gradient\")) {\n hasGradientBackground = true;\n }\n }\n\n if (hasBackgroundClipText && hasGradientBackground) {\n context.report({\n node,\n message:\n \"Gradient text (background-clip: text) is decorative rather than meaningful — a common AI tell. Use solid colors for text\",\n });\n }\n },\n JSXOpeningElement(node: EsTreeNode) {\n const classStr = getStringFromClassNameAttr(node);\n if (!classStr) return;\n\n if (/\\bbg-clip-text\\b/.test(classStr) && /\\bbg-gradient-to-/.test(classStr)) {\n context.report({\n node,\n message:\n \"Gradient text (bg-clip-text + bg-gradient) is decorative rather than meaningful — a common AI tell. Use solid colors for text\",\n });\n }\n },\n }),\n};\n\nexport const noDarkModeGlow: Rule = {\n create: (context: RuleContext) => ({\n JSXAttribute(node: EsTreeNode) {\n const expression = getInlineStyleExpression(node);\n if (!expression) return;\n\n let hasDarkBackground = false;\n let shadowProperty: EsTreeNode | null = null;\n let shadowValue: string | null = null;\n\n for (const property of expression.properties ?? []) {\n const key = getStylePropertyKey(property);\n if (!key) continue;\n\n if (key === \"backgroundColor\" || key === \"background\") {\n const value = getStylePropertyStringValue(property);\n if (value && isBackgroundDark(value)) {\n hasDarkBackground = true;\n }\n }\n\n if (key === \"boxShadow\") {\n shadowProperty = property;\n shadowValue = getStylePropertyStringValue(property);\n }\n }\n\n if (!hasDarkBackground || !shadowValue || !shadowProperty) return;\n\n if (hasColoredGlowShadow(shadowValue)) {\n context.report({\n node: shadowProperty,\n message:\n \"Colored glow on dark background — the default AI-generated 'cool' look. Use subtle, purposeful lighting instead\",\n });\n }\n },\n }),\n};\n\nexport const noJustifiedText: Rule = {\n create: (context: RuleContext) => ({\n JSXAttribute(node: EsTreeNode) {\n const expression = getInlineStyleExpression(node);\n if (!expression) return;\n\n let isJustified = false;\n let hasHyphens = false;\n\n for (const property of expression.properties ?? []) {\n const key = getStylePropertyKey(property);\n const value = getStylePropertyStringValue(property);\n if (!key || !value) continue;\n\n if (key === \"textAlign\" && value === \"justify\") isJustified = true;\n if ((key === \"hyphens\" || key === \"WebkitHyphens\") && value === \"auto\") hasHyphens = true;\n }\n\n if (isJustified && !hasHyphens) {\n context.report({\n node,\n message:\n 'Justified text without hyphens creates uneven word spacing (\"rivers of white\"). Use text-align: left, or add hyphens: auto',\n });\n }\n },\n }),\n};\n\nexport const noTinyText: Rule = {\n create: (context: RuleContext) => ({\n JSXAttribute(node: EsTreeNode) {\n const expression = getInlineStyleExpression(node);\n if (!expression) return;\n\n for (const property of expression.properties ?? []) {\n const key = getStylePropertyKey(property);\n if (key !== \"fontSize\") continue;\n\n let pxValue: number | null = null;\n const numValue = getStylePropertyNumberValue(property);\n const strValue = getStylePropertyStringValue(property);\n\n if (numValue !== null) {\n pxValue = numValue;\n } else if (strValue !== null) {\n const pxMatch = strValue.match(/^([\\d.]+)px$/);\n if (pxMatch) pxValue = parseFloat(pxMatch[1]);\n const remMatch = strValue.match(/^([\\d.]+)rem$/);\n if (remMatch) pxValue = parseFloat(remMatch[1]) * 16;\n }\n\n if (pxValue !== null && pxValue > 0 && pxValue < TINY_TEXT_THRESHOLD_PX) {\n context.report({\n node: property,\n message: `Font size ${pxValue}px is too small — body text should be at least ${TINY_TEXT_THRESHOLD_PX}px for readability, 16px is ideal`,\n });\n }\n }\n },\n }),\n};\n\nexport const noWideLetterSpacing: Rule = {\n create: (context: RuleContext) => ({\n JSXAttribute(node: EsTreeNode) {\n const expression = getInlineStyleExpression(node);\n if (!expression) return;\n\n let isUppercase = false;\n let letterSpacingProperty: EsTreeNode | null = null;\n let letterSpacingEm: number | null = null;\n\n for (const property of expression.properties ?? []) {\n const key = getStylePropertyKey(property);\n if (!key) continue;\n\n if (key === \"textTransform\") {\n const value = getStylePropertyStringValue(property);\n if (value === \"uppercase\") isUppercase = true;\n }\n\n if (key === \"letterSpacing\") {\n letterSpacingProperty = property;\n const strValue = getStylePropertyStringValue(property);\n const numValue = getStylePropertyNumberValue(property);\n if (strValue) {\n const emMatch = strValue.match(/^([\\d.]+)em$/);\n if (emMatch) letterSpacingEm = parseFloat(emMatch[1]);\n const pxMatch = strValue.match(/^([\\d.]+)px$/);\n if (pxMatch) letterSpacingEm = parseFloat(pxMatch[1]) / 16;\n }\n if (numValue !== null && numValue > 0) {\n letterSpacingEm = numValue / 16;\n }\n }\n }\n\n if (\n !isUppercase &&\n letterSpacingProperty &&\n letterSpacingEm !== null &&\n letterSpacingEm > WIDE_TRACKING_THRESHOLD_EM\n ) {\n context.report({\n node: letterSpacingProperty,\n message: `Letter spacing ${letterSpacingEm.toFixed(2)}em on body text disrupts natural character groupings. Reserve wide tracking for short uppercase labels only`,\n });\n }\n },\n }),\n};\n\nexport const noGrayOnColoredBackground: Rule = {\n create: (context: RuleContext) => ({\n JSXOpeningElement(node: EsTreeNode) {\n const classStr = getStringFromClassNameAttr(node);\n if (!classStr) return;\n\n const grayTextMatch = classStr.match(/\\btext-(?:gray|slate|zinc|neutral|stone)-\\d+\\b/);\n const coloredBgMatch = classStr.match(\n /\\bbg-(?:red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-\\d+\\b/,\n );\n\n if (grayTextMatch && coloredBgMatch) {\n context.report({\n node,\n message: `Gray text (${grayTextMatch[0]}) on colored background (${coloredBgMatch[0]}) looks washed out — use a darker shade of the background color or white`,\n });\n }\n },\n }),\n};\n\nexport const noLayoutTransitionInline: Rule = {\n create: (context: RuleContext) => ({\n JSXAttribute(node: EsTreeNode) {\n const expression = getInlineStyleExpression(node);\n if (!expression) return;\n\n for (const property of expression.properties ?? []) {\n const key = getStylePropertyKey(property);\n if (key !== \"transition\" && key !== \"transitionProperty\") continue;\n\n const value = getStylePropertyStringValue(property);\n if (!value) continue;\n\n const lower = value.toLowerCase();\n if (/\\ball\\b/.test(lower)) continue;\n\n const layoutMatch = lower.match(\n /\\b(?:(?:max|min)-)?(?:width|height)\\b|\\bpadding(?:-(?:top|right|bottom|left))?\\b|\\bmargin(?:-(?:top|right|bottom|left))?\\b/,\n );\n if (layoutMatch) {\n context.report({\n node: property,\n message: `Transitioning layout property \"${layoutMatch[0]}\" causes layout thrash every frame — use transform and opacity instead`,\n });\n }\n }\n },\n }),\n};\n\nexport const noDisabledZoom: Rule = {\n create: (context: RuleContext) => ({\n JSXOpeningElement(node: EsTreeNode) {\n if (node.name?.type !== \"JSXIdentifier\" || node.name.name !== \"meta\") return;\n\n const nameAttr = findJsxAttribute(node.attributes ?? [], \"name\");\n if (!nameAttr?.value) return;\n const nameValue = nameAttr.value.type === \"Literal\" ? nameAttr.value.value : null;\n if (nameValue !== \"viewport\") return;\n\n const contentAttr = findJsxAttribute(node.attributes ?? [], \"content\");\n if (!contentAttr?.value) return;\n const contentValue =\n contentAttr.value.type === \"Literal\" && typeof contentAttr.value.value === \"string\"\n ? contentAttr.value.value\n : null;\n if (!contentValue) return;\n\n const hasUserScalableNo = /user-scalable\\s*=\\s*no/i.test(contentValue);\n const maxScaleMatch = contentValue.match(/maximum-scale\\s*=\\s*([\\d.]+)/i);\n const hasRestrictiveMaxScale = maxScaleMatch !== null && parseFloat(maxScaleMatch[1]) < 2;\n\n if (hasUserScalableNo && hasRestrictiveMaxScale) {\n context.report({\n node,\n message: `user-scalable=no and maximum-scale=${maxScaleMatch[1]} disable pinch-to-zoom — this is an accessibility violation (WCAG 1.4.4). Remove both and fix layout if it breaks at 200% zoom`,\n });\n } else if (hasUserScalableNo) {\n context.report({\n node,\n message:\n \"user-scalable=no disables pinch-to-zoom — this is an accessibility violation (WCAG 1.4.4). Remove it and fix layout if it breaks at 200% zoom\",\n });\n } else if (hasRestrictiveMaxScale) {\n context.report({\n node,\n message: `maximum-scale=${maxScaleMatch[1]} restricts zoom below 200% — this is an accessibility violation (WCAG 1.4.4). Use maximum-scale=5 or remove it`,\n });\n }\n },\n }),\n};\n\nexport const noOutlineNone: Rule = {\n create: (context: RuleContext) => ({\n JSXAttribute(node: EsTreeNode) {\n const expression = getInlineStyleExpression(node);\n if (!expression) return;\n\n let hasOutlineNone = false;\n let outlineProperty: EsTreeNode | null = null;\n\n for (const property of expression.properties ?? []) {\n const key = getStylePropertyKey(property);\n if (key !== \"outline\") continue;\n\n const strValue = getStylePropertyStringValue(property);\n const numValue = getStylePropertyNumberValue(property);\n\n if (strValue === \"none\" || strValue === \"0\" || numValue === 0) {\n hasOutlineNone = true;\n outlineProperty = property;\n }\n }\n\n if (!hasOutlineNone || !outlineProperty) return;\n\n const hasCustomFocusRing = expression.properties?.some((property: EsTreeNode) => {\n const key = getStylePropertyKey(property);\n return key === \"boxShadow\";\n });\n\n if (!hasCustomFocusRing) {\n context.report({\n node: outlineProperty,\n message:\n \"outline: none removes keyboard focus visibility — use :focus-visible styling instead, or provide a box-shadow focus ring\",\n });\n }\n },\n }),\n};\n\nexport const noLongTransitionDuration: Rule = {\n create: (context: RuleContext) => ({\n JSXAttribute(node: EsTreeNode) {\n const expression = getInlineStyleExpression(node);\n if (!expression) return;\n\n for (const property of expression.properties ?? []) {\n const key = getStylePropertyKey(property);\n if (!key) continue;\n\n const value = getStylePropertyStringValue(property);\n if (!value) continue;\n\n let durationMs: number | null = null;\n\n if (key === \"transitionDuration\" || key === \"animationDuration\") {\n let longestDurationPropertyMs = 0;\n for (const segment of value.split(\",\")) {\n const trimmedSegment = segment.trim();\n const msMatch = trimmedSegment.match(/^([\\d.]+)ms$/);\n const secondsMatch = trimmedSegment.match(/^([\\d.]+)s$/);\n if (msMatch)\n longestDurationPropertyMs = Math.max(\n longestDurationPropertyMs,\n parseFloat(msMatch[1]),\n );\n else if (secondsMatch)\n longestDurationPropertyMs = Math.max(\n longestDurationPropertyMs,\n parseFloat(secondsMatch[1]) * 1000,\n );\n }\n if (longestDurationPropertyMs > 0) durationMs = longestDurationPropertyMs;\n }\n\n if (key === \"transition\" || key === \"animation\") {\n let longestDurationMs = 0;\n const segments = value.split(\",\");\n for (const segment of segments) {\n const firstTimeMatch = segment.match(/(?<![a-zA-Z\\d])([\\d.]+)(m?s)(?![a-zA-Z\\d-])/);\n if (!firstTimeMatch) continue;\n const segmentDurationMs =\n firstTimeMatch[2] === \"ms\"\n ? parseFloat(firstTimeMatch[1])\n : parseFloat(firstTimeMatch[1]) * 1000;\n longestDurationMs = Math.max(longestDurationMs, segmentDurationMs);\n }\n if (longestDurationMs > 0) durationMs = longestDurationMs;\n }\n\n if (durationMs !== null && durationMs > LONG_TRANSITION_DURATION_THRESHOLD_MS) {\n context.report({\n node: property,\n message: `${durationMs}ms transition is too slow for UI feedback — keep transitions under ${LONG_TRANSITION_DURATION_THRESHOLD_MS}ms. Use longer durations only for page-load hero animations`,\n });\n }\n }\n },\n }),\n};\n","import { INDEX_PARAMETER_NAMES } from \"../constants.js\";\nimport { findJsxAttribute, walkAst } from \"../helpers.js\";\nimport type { EsTreeNode, Rule, RuleContext } from \"../types.js\";\n\nconst extractIndexName = (node: EsTreeNode): string | null => {\n if (node.type === \"Identifier\" && INDEX_PARAMETER_NAMES.has(node.name)) return node.name;\n\n if (node.type === \"TemplateLiteral\") {\n const indexExpression = node.expressions?.find(\n (expression: EsTreeNode) =>\n expression.type === \"Identifier\" && INDEX_PARAMETER_NAMES.has(expression.name),\n );\n if (indexExpression) return indexExpression.name;\n }\n\n if (\n node.type === \"CallExpression\" &&\n node.callee?.type === \"MemberExpression\" &&\n node.callee.object?.type === \"Identifier\" &&\n INDEX_PARAMETER_NAMES.has(node.callee.object.name) &&\n node.callee.property?.type === \"Identifier\" &&\n node.callee.property.name === \"toString\"\n )\n return node.callee.object.name;\n\n if (\n node.type === \"CallExpression\" &&\n node.callee?.type === \"Identifier\" &&\n node.callee.name === \"String\" &&\n node.arguments?.[0]?.type === \"Identifier\" &&\n INDEX_PARAMETER_NAMES.has(node.arguments[0].name)\n )\n return node.arguments[0].name;\n\n return null;\n};\n\nconst isInsideStaticPlaceholderMap = (node: EsTreeNode): boolean => {\n let current = node;\n while (current.parent) {\n current = current.parent;\n if (\n current.type === \"CallExpression\" &&\n current.callee?.type === \"MemberExpression\" &&\n current.callee.property?.name === \"map\"\n ) {\n const receiver = current.callee.object;\n if (receiver?.type === \"CallExpression\") {\n const callee = receiver.callee;\n if (\n callee?.type === \"MemberExpression\" &&\n callee.object?.type === \"Identifier\" &&\n callee.object.name === \"Array\" &&\n callee.property?.name === \"from\"\n )\n return true;\n }\n if (\n receiver?.type === \"NewExpression\" &&\n receiver.callee?.type === \"Identifier\" &&\n receiver.callee.name === \"Array\"\n )\n return true;\n }\n }\n return false;\n};\n\nexport const noArrayIndexAsKey: Rule = {\n create: (context: RuleContext) => ({\n JSXAttribute(node: EsTreeNode) {\n if (node.name?.type !== \"JSXIdentifier\" || node.name.name !== \"key\") return;\n if (!node.value || node.value.type !== \"JSXExpressionContainer\") return;\n\n const indexName = extractIndexName(node.value.expression);\n if (!indexName) return;\n if (isInsideStaticPlaceholderMap(node)) return;\n\n context.report({\n node,\n message: `Array index \"${indexName}\" used as key — causes bugs when list is reordered or filtered`,\n });\n },\n }),\n};\n\nconst PREVENT_DEFAULT_ELEMENTS: Record<string, string> = {\n form: \"onSubmit\",\n a: \"onClick\",\n};\n\nconst containsPreventDefaultCall = (node: EsTreeNode): boolean => {\n let didFindPreventDefault = false;\n walkAst(node, (child) => {\n if (didFindPreventDefault) return;\n if (\n child.type === \"CallExpression\" &&\n child.callee?.type === \"MemberExpression\" &&\n child.callee.property?.type === \"Identifier\" &&\n child.callee.property.name === \"preventDefault\"\n ) {\n didFindPreventDefault = true;\n }\n });\n return didFindPreventDefault;\n};\n\nexport const noPreventDefault: Rule = {\n create: (context: RuleContext) => ({\n JSXOpeningElement(node: EsTreeNode) {\n const elementName = node.name?.type === \"JSXIdentifier\" ? node.name.name : null;\n if (!elementName) return;\n\n const targetEventProp = PREVENT_DEFAULT_ELEMENTS[elementName];\n if (!targetEventProp) return;\n\n const eventAttribute = findJsxAttribute(node.attributes ?? [], targetEventProp);\n if (!eventAttribute?.value || eventAttribute.value.type !== \"JSXExpressionContainer\") return;\n\n const expression = eventAttribute.value.expression;\n if (\n expression?.type !== \"ArrowFunctionExpression\" &&\n expression?.type !== \"FunctionExpression\"\n )\n return;\n\n if (!containsPreventDefaultCall(expression)) return;\n\n const message =\n elementName === \"form\"\n ? \"preventDefault() on <form> onSubmit — form won't work without JavaScript. Consider using a server action for progressive enhancement\"\n : \"preventDefault() on <a> onClick — use a <button> or routing component instead\";\n\n context.report({ node, message });\n },\n }),\n};\n\nexport const renderingConditionalRender: Rule = {\n create: (context: RuleContext) => ({\n LogicalExpression(node: EsTreeNode) {\n if (node.operator !== \"&&\") return;\n\n const isRightJsx = node.right?.type === \"JSXElement\" || node.right?.type === \"JSXFragment\";\n if (!isRightJsx) return;\n\n if (\n node.left?.type === \"MemberExpression\" &&\n node.left.property?.type === \"Identifier\" &&\n node.left.property.name === \"length\"\n ) {\n context.report({\n node,\n message:\n \"Conditional rendering with .length can render '0' — use .length > 0 or Boolean(.length)\",\n });\n }\n },\n }),\n};\n","import {\n CHAINABLE_ITERATION_METHODS,\n DEEP_NESTING_THRESHOLD,\n DUPLICATE_STORAGE_READ_THRESHOLD,\n SEQUENTIAL_AWAIT_THRESHOLD,\n STORAGE_OBJECTS,\n TEST_FILE_PATTERN,\n} from \"../constants.js\";\nimport { createLoopAwareVisitors, isMemberProperty, walkAst } from \"../helpers.js\";\nimport type { EsTreeNode, Rule, RuleContext } from \"../types.js\";\n\nexport const jsCombineIterations: Rule = {\n create: (context: RuleContext) => ({\n CallExpression(node: EsTreeNode) {\n if (node.callee?.type !== \"MemberExpression\" || node.callee.property?.type !== \"Identifier\")\n return;\n\n const outerMethod = node.callee.property.name;\n if (!CHAINABLE_ITERATION_METHODS.has(outerMethod)) return;\n\n const innerCall = node.callee.object;\n if (\n innerCall?.type !== \"CallExpression\" ||\n innerCall.callee?.type !== \"MemberExpression\" ||\n innerCall.callee.property?.type !== \"Identifier\"\n )\n return;\n\n const innerMethod = innerCall.callee.property.name;\n if (!CHAINABLE_ITERATION_METHODS.has(innerMethod)) return;\n\n if (innerMethod === \"map\" && outerMethod === \"filter\") {\n const filterArgument = node.arguments?.[0];\n const isBooleanOrIdentityFilter =\n (filterArgument?.type === \"Identifier\" && filterArgument.name === \"Boolean\") ||\n (filterArgument?.type === \"ArrowFunctionExpression\" &&\n filterArgument.params?.length === 1 &&\n filterArgument.body?.type === \"Identifier\" &&\n filterArgument.params[0]?.type === \"Identifier\" &&\n filterArgument.body.name === filterArgument.params[0].name);\n if (isBooleanOrIdentityFilter) return;\n }\n\n context.report({\n node,\n message: `.${innerMethod}().${outerMethod}() iterates the array twice — combine into a single loop with .reduce() or for...of`,\n });\n },\n }),\n};\n\nexport const jsTosortedImmutable: Rule = {\n create: (context: RuleContext) => ({\n CallExpression(node: EsTreeNode) {\n if (!isMemberProperty(node.callee, \"sort\")) return;\n\n const receiver = node.callee.object;\n if (\n receiver?.type === \"ArrayExpression\" &&\n receiver.elements?.length === 1 &&\n receiver.elements[0]?.type === \"SpreadElement\"\n ) {\n context.report({\n node,\n message: \"[...array].sort() — use array.toSorted() for immutable sorting (ES2023)\",\n });\n }\n },\n }),\n};\n\nexport const jsHoistRegexp: Rule = {\n create: (context: RuleContext) =>\n createLoopAwareVisitors({\n NewExpression(node: EsTreeNode) {\n if (node.callee?.type === \"Identifier\" && node.callee.name === \"RegExp\") {\n context.report({\n node,\n message: \"new RegExp() inside a loop — hoist to a module-level constant\",\n });\n }\n },\n }),\n};\n\nexport const jsMinMaxLoop: Rule = {\n create: (context: RuleContext) => ({\n MemberExpression(node: EsTreeNode) {\n if (!node.computed) return;\n\n const object = node.object;\n if (object?.type !== \"CallExpression\" || !isMemberProperty(object.callee, \"sort\")) return;\n\n const isFirstElement = node.property?.type === \"Literal\" && node.property.value === 0;\n const isLastElement =\n node.property?.type === \"BinaryExpression\" &&\n node.property.operator === \"-\" &&\n node.property.right?.type === \"Literal\" &&\n node.property.right.value === 1;\n\n if (isFirstElement || isLastElement) {\n const targetFunction = isFirstElement ? \"min\" : \"max\";\n context.report({\n node,\n message: `array.sort()[${isFirstElement ? \"0\" : \"length-1\"}] for min/max — use Math.${targetFunction}(...array) instead (O(n) vs O(n log n))`,\n });\n }\n },\n }),\n};\n\nexport const jsSetMapLookups: Rule = {\n create: (context: RuleContext) =>\n createLoopAwareVisitors({\n CallExpression(node: EsTreeNode) {\n if (node.callee?.type !== \"MemberExpression\" || node.callee.property?.type !== \"Identifier\")\n return;\n const methodName = node.callee.property.name;\n if (methodName === \"includes\" || methodName === \"indexOf\") {\n context.report({\n node,\n message: `array.${methodName}() in a loop is O(n) per call — convert to a Set for O(1) lookups`,\n });\n }\n },\n }),\n};\n\nexport const jsBatchDomCss: Rule = {\n create: (context: RuleContext) => {\n const isStyleAssignment = (node: EsTreeNode): boolean =>\n node.type === \"ExpressionStatement\" &&\n node.expression?.type === \"AssignmentExpression\" &&\n node.expression.left?.type === \"MemberExpression\" &&\n node.expression.left.object?.type === \"MemberExpression\" &&\n node.expression.left.object.property?.type === \"Identifier\" &&\n node.expression.left.object.property.name === \"style\";\n\n return {\n BlockStatement(node: EsTreeNode) {\n const statements = node.body ?? [];\n for (let statementIndex = 1; statementIndex < statements.length; statementIndex++) {\n if (\n isStyleAssignment(statements[statementIndex]) &&\n isStyleAssignment(statements[statementIndex - 1])\n ) {\n context.report({\n node: statements[statementIndex],\n message:\n \"Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows\",\n });\n }\n }\n },\n };\n },\n};\n\nexport const jsIndexMaps: Rule = {\n create: (context: RuleContext) =>\n createLoopAwareVisitors({\n CallExpression(node: EsTreeNode) {\n if (node.callee?.type !== \"MemberExpression\" || node.callee.property?.type !== \"Identifier\")\n return;\n const methodName = node.callee.property.name;\n if (methodName === \"find\" || methodName === \"findIndex\") {\n context.report({\n node,\n message: `array.${methodName}() in a loop is O(n*m) — build a Map for O(1) lookups`,\n });\n }\n },\n }),\n};\n\nexport const jsCacheStorage: Rule = {\n create: (context: RuleContext) => {\n const storageReadCounts = new Map<string, number>();\n\n return {\n CallExpression(node: EsTreeNode) {\n if (!isMemberProperty(node.callee, \"getItem\")) return;\n if (\n node.callee.object?.type !== \"Identifier\" ||\n !STORAGE_OBJECTS.has(node.callee.object.name)\n )\n return;\n if (node.arguments?.[0]?.type !== \"Literal\") return;\n\n const storageKey = String(node.arguments[0].value);\n const readCount = (storageReadCounts.get(storageKey) ?? 0) + 1;\n storageReadCounts.set(storageKey, readCount);\n\n if (readCount === DUPLICATE_STORAGE_READ_THRESHOLD) {\n const storageName = node.callee.object.name;\n context.report({\n node,\n message: `${storageName}.getItem(\"${storageKey}\") called multiple times — cache the result in a variable`,\n });\n }\n },\n };\n },\n};\n\nexport const jsEarlyExit: Rule = {\n create: (context: RuleContext) => ({\n IfStatement(node: EsTreeNode) {\n if (node.consequent?.type !== \"BlockStatement\" || !node.consequent.body) return;\n\n let nestingDepth = 0;\n let currentBlock = node.consequent;\n while (currentBlock?.type === \"BlockStatement\" && currentBlock.body?.length === 1) {\n const innerStatement = currentBlock.body[0];\n if (innerStatement.type !== \"IfStatement\") break;\n nestingDepth++;\n currentBlock = innerStatement.consequent;\n }\n\n if (nestingDepth >= DEEP_NESTING_THRESHOLD) {\n context.report({\n node,\n message: `${nestingDepth + 1} levels of nested if statements — use early returns to flatten`,\n });\n }\n },\n }),\n};\n\nexport const asyncParallel: Rule = {\n create: (context: RuleContext) => {\n const filename = context.getFilename?.() ?? \"\";\n const isTestFile = TEST_FILE_PATTERN.test(filename);\n\n return {\n BlockStatement(node: EsTreeNode) {\n if (isTestFile) return;\n const consecutiveAwaitStatements: EsTreeNode[] = [];\n\n const flushConsecutiveAwaits = (): void => {\n if (consecutiveAwaitStatements.length >= SEQUENTIAL_AWAIT_THRESHOLD) {\n reportIfIndependent(consecutiveAwaitStatements, context);\n }\n consecutiveAwaitStatements.length = 0;\n };\n\n for (const statement of node.body ?? []) {\n const isAwaitStatement =\n (statement.type === \"VariableDeclaration\" &&\n statement.declarations?.length === 1 &&\n statement.declarations[0].init?.type === \"AwaitExpression\") ||\n (statement.type === \"ExpressionStatement\" &&\n statement.expression?.type === \"AwaitExpression\");\n\n if (isAwaitStatement) {\n consecutiveAwaitStatements.push(statement);\n } else {\n flushConsecutiveAwaits();\n }\n }\n flushConsecutiveAwaits();\n },\n };\n },\n};\n\nconst reportIfIndependent = (statements: EsTreeNode[], context: RuleContext): void => {\n const declaredNames = new Set<string>();\n\n for (const statement of statements) {\n if (statement.type !== \"VariableDeclaration\") continue;\n const declarator = statement.declarations[0];\n const awaitArgument = declarator.init?.argument;\n\n let referencesEarlierResult = false;\n walkAst(awaitArgument, (child: EsTreeNode) => {\n if (child.type === \"Identifier\" && declaredNames.has(child.name)) {\n referencesEarlierResult = true;\n }\n });\n\n if (referencesEarlierResult) return;\n\n if (declarator.id?.type === \"Identifier\") {\n declaredNames.add(declarator.id.name);\n }\n }\n\n context.report({\n node: statements[0],\n message: `${statements.length} sequential await statements that appear independent — use Promise.all() for parallel execution`,\n });\n};\n\nexport const jsFlatmapFilter: Rule = {\n create: (context: RuleContext) => ({\n CallExpression(node: EsTreeNode) {\n if (node.callee?.type !== \"MemberExpression\" || node.callee.property?.type !== \"Identifier\")\n return;\n\n const outerMethod = node.callee.property.name;\n if (outerMethod !== \"filter\") return;\n\n const filterArgument = node.arguments?.[0];\n if (!filterArgument) return;\n\n const isIdentityArrow =\n filterArgument.type === \"ArrowFunctionExpression\" &&\n filterArgument.params?.length === 1 &&\n filterArgument.body?.type === \"Identifier\" &&\n filterArgument.params[0]?.type === \"Identifier\" &&\n filterArgument.body.name === filterArgument.params[0].name;\n\n const isFilterBoolean =\n (filterArgument.type === \"Identifier\" && filterArgument.name === \"Boolean\") ||\n isIdentityArrow;\n\n if (!isFilterBoolean) return;\n\n const innerCall = node.callee.object;\n if (\n innerCall?.type !== \"CallExpression\" ||\n innerCall.callee?.type !== \"MemberExpression\" ||\n innerCall.callee.property?.type !== \"Identifier\"\n )\n return;\n\n const innerMethod = innerCall.callee.property.name;\n if (innerMethod !== \"map\") return;\n\n context.report({\n node,\n message:\n \".map().filter(Boolean) iterates twice — use .flatMap() to transform and filter in a single pass\",\n });\n },\n }),\n};\n","import {\n APP_DIRECTORY_PATTERN,\n EFFECT_HOOK_NAMES,\n EXECUTABLE_SCRIPT_TYPES,\n GOOGLE_FONTS_PATTERN,\n INTERNAL_PAGE_PATH_PATTERN,\n MUTATING_ROUTE_SEGMENTS,\n NEXTJS_NAVIGATION_FUNCTIONS,\n OG_ROUTE_PATTERN,\n PAGE_FILE_PATTERN,\n PAGE_OR_LAYOUT_FILE_PATTERN,\n PAGES_DIRECTORY_PATTERN,\n POLYFILL_SCRIPT_PATTERN,\n ROUTE_HANDLER_FILE_PATTERN,\n} from \"../constants.js\";\nimport {\n containsFetchCall,\n findJsxAttribute,\n findSideEffect,\n getEffectCallback,\n hasDirective,\n hasJsxAttribute,\n isComponentAssignment,\n isHookCall,\n isMemberProperty,\n isUppercaseName,\n walkAst,\n} from \"../helpers.js\";\nimport type { EsTreeNode, Rule, RuleContext } from \"../types.js\";\n\nexport const nextjsNoImgElement: Rule = {\n create: (context: RuleContext) => {\n const filename = context.getFilename?.() ?? \"\";\n const isOgRoute = OG_ROUTE_PATTERN.test(filename);\n\n return {\n JSXOpeningElement(node: EsTreeNode) {\n if (isOgRoute) return;\n if (node.name?.type === \"JSXIdentifier\" && node.name.name === \"img\") {\n context.report({\n node,\n message:\n \"Use next/image instead of <img> — provides automatic optimization, lazy loading, and responsive srcset\",\n });\n }\n },\n };\n },\n};\n\nexport const nextjsAsyncClientComponent: Rule = {\n create: (context: RuleContext) => {\n let fileHasUseClient = false;\n\n return {\n Program(programNode: EsTreeNode) {\n fileHasUseClient = hasDirective(programNode, \"use client\");\n },\n FunctionDeclaration(node: EsTreeNode) {\n if (!fileHasUseClient || !node.async) return;\n if (!node.id?.name || !isUppercaseName(node.id.name)) return;\n context.report({\n node,\n message: `Async client component \"${node.id.name}\" — client components cannot be async`,\n });\n },\n VariableDeclarator(node: EsTreeNode) {\n if (!fileHasUseClient) return;\n if (!isComponentAssignment(node) || !node.init?.async) return;\n context.report({\n node,\n message: `Async client component \"${node.id.name}\" — client components cannot be async`,\n });\n },\n };\n },\n};\n\nexport const nextjsNoAElement: Rule = {\n create: (context: RuleContext) => ({\n JSXOpeningElement(node: EsTreeNode) {\n if (node.name?.type !== \"JSXIdentifier\" || node.name.name !== \"a\") return;\n\n const hrefAttribute = findJsxAttribute(node.attributes ?? [], \"href\");\n if (!hrefAttribute?.value) return;\n\n let hrefValue = null;\n if (hrefAttribute.value.type === \"Literal\") {\n hrefValue = hrefAttribute.value.value;\n } else if (\n hrefAttribute.value.type === \"JSXExpressionContainer\" &&\n hrefAttribute.value.expression?.type === \"Literal\"\n ) {\n hrefValue = hrefAttribute.value.expression.value;\n }\n\n if (typeof hrefValue === \"string\" && hrefValue.startsWith(\"/\")) {\n context.report({\n node,\n message:\n \"Use next/link instead of <a> for internal links — enables client-side navigation and prefetching\",\n });\n }\n },\n }),\n};\n\nexport const nextjsNoUseSearchParamsWithoutSuspense: Rule = {\n create: (context: RuleContext) => ({\n CallExpression(node: EsTreeNode) {\n if (!isHookCall(node, \"useSearchParams\")) return;\n context.report({\n node,\n message:\n \"useSearchParams() requires a <Suspense> boundary — without one, the entire page bails out to client-side rendering\",\n });\n },\n }),\n};\n\nexport const nextjsNoClientFetchForServerData: Rule = {\n create: (context: RuleContext) => {\n let fileHasUseClient = false;\n\n return {\n Program(programNode: EsTreeNode) {\n fileHasUseClient = hasDirective(programNode, \"use client\");\n },\n CallExpression(node: EsTreeNode) {\n if (!fileHasUseClient || !isHookCall(node, EFFECT_HOOK_NAMES)) return;\n\n const callback = getEffectCallback(node);\n if (!callback || !containsFetchCall(callback)) return;\n\n const filename = context.getFilename?.() ?? \"\";\n const isPageOrLayoutFile =\n PAGE_OR_LAYOUT_FILE_PATTERN.test(filename) || PAGES_DIRECTORY_PATTERN.test(filename);\n\n if (isPageOrLayoutFile) {\n context.report({\n node,\n message:\n \"useEffect + fetch in a page/layout — fetch data server-side with a server component instead\",\n });\n }\n },\n };\n },\n};\n\nexport const nextjsMissingMetadata: Rule = {\n create: (context: RuleContext) => ({\n Program(programNode: EsTreeNode) {\n const filename = context.getFilename?.() ?? \"\";\n if (!PAGE_FILE_PATTERN.test(filename)) return;\n if (INTERNAL_PAGE_PATH_PATTERN.test(filename)) return;\n\n const hasMetadataExport = programNode.body?.some((statement: EsTreeNode) => {\n if (statement.type !== \"ExportNamedDeclaration\") return false;\n const declaration = statement.declaration;\n if (declaration?.type === \"VariableDeclaration\") {\n return declaration.declarations?.some(\n (declarator: EsTreeNode) =>\n declarator.id?.type === \"Identifier\" &&\n (declarator.id.name === \"metadata\" || declarator.id.name === \"generateMetadata\"),\n );\n }\n if (declaration?.type === \"FunctionDeclaration\") {\n return declaration.id?.name === \"generateMetadata\";\n }\n return false;\n });\n\n if (!hasMetadataExport) {\n context.report({\n node: programNode,\n message: \"Page without metadata or generateMetadata export — hurts SEO\",\n });\n }\n },\n }),\n};\n\nconst describeClientSideNavigation = (\n node: EsTreeNode,\n isPagesRouterFile: boolean,\n): string | null => {\n const redirectGuidance = isPagesRouterFile\n ? \"handle navigation in an event handler, getServerSideProps redirect, or middleware\"\n : \"use redirect() from next/navigation or handle navigation in an event handler\";\n\n if (node.type === \"CallExpression\" && node.callee?.type === \"MemberExpression\") {\n const objectName = node.callee.object?.type === \"Identifier\" ? node.callee.object.name : null;\n const methodName =\n node.callee.property?.type === \"Identifier\" ? node.callee.property.name : null;\n if (objectName === \"router\" && (methodName === \"push\" || methodName === \"replace\")) {\n return `router.${methodName}() in useEffect — ${redirectGuidance}`;\n }\n }\n\n if (node.type === \"AssignmentExpression\" && node.left?.type === \"MemberExpression\") {\n const objectName = node.left.object?.type === \"Identifier\" ? node.left.object.name : null;\n const propertyName = node.left.property?.type === \"Identifier\" ? node.left.property.name : null;\n if (objectName === \"window\" && propertyName === \"location\") {\n return `window.location assignment in useEffect — ${redirectGuidance}`;\n }\n if (objectName === \"location\" && propertyName === \"href\") {\n return `location.href assignment in useEffect — ${redirectGuidance}`;\n }\n }\n\n return null;\n};\n\nexport const nextjsNoClientSideRedirect: Rule = {\n create: (context: RuleContext) => {\n const filename = context.getFilename?.() ?? \"\";\n const isPagesRouterFile = PAGES_DIRECTORY_PATTERN.test(filename);\n\n return {\n CallExpression(node: EsTreeNode) {\n if (!isHookCall(node, EFFECT_HOOK_NAMES)) return;\n const callback = getEffectCallback(node);\n if (!callback) return;\n\n walkAst(callback, (child: EsTreeNode) => {\n const navigationDescription = describeClientSideNavigation(child, isPagesRouterFile);\n if (navigationDescription) {\n context.report({\n node: child,\n message: navigationDescription,\n });\n }\n });\n },\n };\n },\n};\n\nexport const nextjsNoRedirectInTryCatch: Rule = {\n create: (context: RuleContext) => {\n let tryCatchDepth = 0;\n\n return {\n TryStatement() {\n tryCatchDepth++;\n },\n \"TryStatement:exit\"() {\n tryCatchDepth--;\n },\n CallExpression(node: EsTreeNode) {\n if (tryCatchDepth === 0) return;\n if (node.callee?.type !== \"Identifier\") return;\n if (!NEXTJS_NAVIGATION_FUNCTIONS.has(node.callee.name)) return;\n\n context.report({\n node,\n message: `${node.callee.name}() inside try-catch — this throws a special error Next.js handles internally. Move it outside the try block or use unstable_rethrow() in the catch`,\n });\n },\n };\n },\n};\n\nexport const nextjsImageMissingSizes: Rule = {\n create: (context: RuleContext) => ({\n JSXOpeningElement(node: EsTreeNode) {\n if (node.name?.type !== \"JSXIdentifier\" || node.name.name !== \"Image\") return;\n const attributes = node.attributes ?? [];\n if (!hasJsxAttribute(attributes, \"fill\")) return;\n if (hasJsxAttribute(attributes, \"sizes\")) return;\n\n context.report({\n node,\n message:\n \"next/image with fill but no sizes — the browser downloads the largest image. Add a sizes attribute for responsive behavior\",\n });\n },\n }),\n};\n\nexport const nextjsNoNativeScript: Rule = {\n create: (context: RuleContext) => ({\n JSXOpeningElement(node: EsTreeNode) {\n if (node.name?.type !== \"JSXIdentifier\" || node.name.name !== \"script\") return;\n\n const typeAttribute = findJsxAttribute(node.attributes ?? [], \"type\");\n const typeValue = typeAttribute?.value?.type === \"Literal\" ? typeAttribute.value.value : null;\n if (typeof typeValue === \"string\" && !EXECUTABLE_SCRIPT_TYPES.has(typeValue)) return;\n\n context.report({\n node,\n message:\n \"Use next/script <Script> instead of <script> — provides loading strategy optimization and deferred loading\",\n });\n },\n }),\n};\n\nexport const nextjsInlineScriptMissingId: Rule = {\n create: (context: RuleContext) => ({\n JSXOpeningElement(node: EsTreeNode) {\n if (node.name?.type !== \"JSXIdentifier\" || node.name.name !== \"Script\") return;\n const attributes = node.attributes ?? [];\n\n if (hasJsxAttribute(attributes, \"src\")) return;\n if (hasJsxAttribute(attributes, \"id\")) return;\n\n context.report({\n node,\n message:\n \"Inline <Script> without id — Next.js requires an id attribute to track inline scripts\",\n });\n },\n }),\n};\n\nexport const nextjsNoFontLink: Rule = {\n create: (context: RuleContext) => ({\n JSXOpeningElement(node: EsTreeNode) {\n if (node.name?.type !== \"JSXIdentifier\" || node.name.name !== \"link\") return;\n const attributes = node.attributes ?? [];\n\n const hrefAttribute = findJsxAttribute(attributes, \"href\");\n if (!hrefAttribute?.value) return;\n\n const hrefValue = hrefAttribute.value.type === \"Literal\" ? hrefAttribute.value.value : null;\n\n if (typeof hrefValue === \"string\" && GOOGLE_FONTS_PATTERN.test(hrefValue)) {\n context.report({\n node,\n message:\n \"Loading Google Fonts via <link> — use next/font instead for self-hosting, zero layout shift, and no render-blocking requests\",\n });\n }\n },\n }),\n};\n\nexport const nextjsNoCssLink: Rule = {\n create: (context: RuleContext) => ({\n JSXOpeningElement(node: EsTreeNode) {\n if (node.name?.type !== \"JSXIdentifier\" || node.name.name !== \"link\") return;\n const attributes = node.attributes ?? [];\n\n const relAttribute = findJsxAttribute(attributes, \"rel\");\n if (!relAttribute?.value) return;\n const relValue = relAttribute.value.type === \"Literal\" ? relAttribute.value.value : null;\n if (relValue !== \"stylesheet\") return;\n\n const hrefAttribute = findJsxAttribute(attributes, \"href\");\n if (!hrefAttribute?.value) return;\n const hrefValue = hrefAttribute.value.type === \"Literal\" ? hrefAttribute.value.value : null;\n if (typeof hrefValue === \"string\" && GOOGLE_FONTS_PATTERN.test(hrefValue)) return;\n\n context.report({\n node,\n message: '<link rel=\"stylesheet\"> tag — import CSS directly for bundling and optimization',\n });\n },\n }),\n};\n\nexport const nextjsNoPolyfillScript: Rule = {\n create: (context: RuleContext) => ({\n JSXOpeningElement(node: EsTreeNode) {\n if (node.name?.type !== \"JSXIdentifier\") return;\n if (node.name.name !== \"script\" && node.name.name !== \"Script\") return;\n\n const srcAttribute = findJsxAttribute(node.attributes ?? [], \"src\");\n if (!srcAttribute?.value) return;\n\n const srcValue = srcAttribute.value.type === \"Literal\" ? srcAttribute.value.value : null;\n\n if (typeof srcValue === \"string\" && POLYFILL_SCRIPT_PATTERN.test(srcValue)) {\n context.report({\n node,\n message:\n \"Polyfill CDN script — Next.js includes polyfills for fetch, Promise, Object.assign, and 50+ others automatically\",\n });\n }\n },\n }),\n};\n\nexport const nextjsNoHeadImport: Rule = {\n create: (context: RuleContext) => ({\n ImportDeclaration(node: EsTreeNode) {\n if (node.source?.value !== \"next/head\") return;\n\n const filename = context.getFilename?.() ?? \"\";\n if (!APP_DIRECTORY_PATTERN.test(filename)) return;\n\n context.report({\n node,\n message: \"next/head is not supported in the App Router — use the Metadata API instead\",\n });\n },\n }),\n};\n\nconst extractMutatingRouteSegment = (filename: string): string | null => {\n const segments = filename.split(\"/\");\n for (const segment of segments) {\n const cleaned = segment.replace(/^\\[.*\\]$/, \"\");\n if (MUTATING_ROUTE_SEGMENTS.has(cleaned)) return cleaned;\n }\n return null;\n};\n\nconst getExportedGetHandlerBody = (node: EsTreeNode): EsTreeNode | null => {\n if (node.type !== \"ExportNamedDeclaration\") return null;\n const declaration = node.declaration;\n if (!declaration) return null;\n\n if (declaration.type === \"FunctionDeclaration\" && declaration.id?.name === \"GET\") {\n return declaration.body;\n }\n\n if (declaration.type === \"VariableDeclaration\") {\n const declarator = declaration.declarations?.[0];\n if (\n declarator?.id?.type === \"Identifier\" &&\n declarator.id.name === \"GET\" &&\n declarator.init &&\n (declarator.init.type === \"ArrowFunctionExpression\" ||\n declarator.init.type === \"FunctionExpression\")\n ) {\n return declarator.init.body;\n }\n }\n\n return null;\n};\n\nexport const nextjsNoSideEffectInGetHandler: Rule = {\n create: (context: RuleContext) => ({\n ExportNamedDeclaration(node: EsTreeNode) {\n const filename = context.getFilename?.() ?? \"\";\n if (!ROUTE_HANDLER_FILE_PATTERN.test(filename)) return;\n\n const handlerBody = getExportedGetHandlerBody(node);\n if (!handlerBody) return;\n\n const mutatingSegment = extractMutatingRouteSegment(filename);\n if (mutatingSegment) {\n context.report({\n node,\n message: `GET handler on \"/${mutatingSegment}\" route — use POST to prevent CSRF and unintended prefetch triggers`,\n });\n return;\n }\n\n const sideEffect = findSideEffect(handlerBody);\n if (sideEffect) {\n context.report({\n node,\n message: `GET handler has side effects (${sideEffect}) — use POST to prevent CSRF and unintended prefetch triggers`,\n });\n }\n },\n }),\n};\n","import {\n ANIMATION_CALLBACK_NAMES,\n BLUR_VALUE_PATTERN,\n EFFECT_HOOK_NAMES,\n EXECUTABLE_SCRIPT_TYPES,\n LARGE_BLUR_THRESHOLD_PX,\n LAYOUT_PROPERTIES,\n LOADING_STATE_PATTERN,\n MOTION_ANIMATE_PROPS,\n SCRIPT_LOADING_ATTRIBUTES,\n} from \"../constants.js\";\nimport {\n getEffectCallback,\n isComponentAssignment,\n isHookCall,\n isMemberProperty,\n isSetterCall,\n isSimpleExpression,\n isUppercaseName,\n walkAst,\n} from \"../helpers.js\";\nimport type { EsTreeNode, Rule, RuleContext } from \"../types.js\";\n\nconst isMemoCall = (node: EsTreeNode): boolean => {\n if (node.type !== \"CallExpression\") return false;\n if (node.callee?.type === \"Identifier\" && node.callee.name === \"memo\") return true;\n if (\n node.callee?.type === \"MemberExpression\" &&\n node.callee.object?.type === \"Identifier\" &&\n node.callee.object.name === \"React\" &&\n node.callee.property?.type === \"Identifier\" &&\n node.callee.property.name === \"memo\"\n )\n return true;\n return false;\n};\n\nconst isInlineReference = (node: EsTreeNode): string | null => {\n if (\n node.type === \"ArrowFunctionExpression\" ||\n node.type === \"FunctionExpression\" ||\n (node.type === \"CallExpression\" &&\n node.callee?.type === \"MemberExpression\" &&\n node.callee.property?.name === \"bind\")\n )\n return \"functions\";\n\n if (node.type === \"ObjectExpression\") return \"objects\";\n if (node.type === \"ArrayExpression\") return \"Arrays\";\n if (node.type === \"JSXElement\" || node.type === \"JSXFragment\") return \"JSX\";\n\n return null;\n};\n\nexport const noInlinePropOnMemoComponent: Rule = {\n create: (context: RuleContext) => {\n const memoizedComponentNames = new Set<string>();\n\n return {\n VariableDeclarator(node: EsTreeNode) {\n if (node.id?.type !== \"Identifier\" || !node.init) return;\n if (isMemoCall(node.init)) {\n memoizedComponentNames.add(node.id.name);\n }\n },\n ExportDefaultDeclaration(node: EsTreeNode) {\n if (node.declaration && isMemoCall(node.declaration)) {\n const innerArgument = node.declaration.arguments?.[0];\n if (innerArgument?.type === \"Identifier\") {\n memoizedComponentNames.add(innerArgument.name);\n }\n }\n },\n JSXAttribute(node: EsTreeNode) {\n if (!node.value || node.value.type !== \"JSXExpressionContainer\") return;\n\n const openingElement = node.parent;\n if (!openingElement || openingElement.type !== \"JSXOpeningElement\") return;\n\n let elementName: string | null = null;\n if (openingElement.name?.type === \"JSXIdentifier\") {\n elementName = openingElement.name.name;\n }\n if (!elementName || !memoizedComponentNames.has(elementName)) return;\n\n const propType = isInlineReference(node.value.expression);\n if (propType) {\n context.report({\n node: node.value.expression,\n message: `JSX attribute values should not contain ${propType} created in the same scope — ${elementName} is wrapped in memo(), so new references cause unnecessary re-renders`,\n });\n }\n },\n };\n },\n};\n\nexport const noUsememoSimpleExpression: Rule = {\n create: (context: RuleContext) => ({\n CallExpression(node: EsTreeNode) {\n if (!isHookCall(node, \"useMemo\")) return;\n\n const callback = node.arguments?.[0];\n if (!callback) return;\n if (callback.type !== \"ArrowFunctionExpression\" && callback.type !== \"FunctionExpression\")\n return;\n\n let returnExpression = null;\n if (callback.body?.type !== \"BlockStatement\") {\n returnExpression = callback.body;\n } else if (\n callback.body.body?.length === 1 &&\n callback.body.body[0].type === \"ReturnStatement\"\n ) {\n returnExpression = callback.body.body[0].argument;\n }\n\n if (returnExpression && isSimpleExpression(returnExpression)) {\n context.report({\n node,\n message:\n \"useMemo wrapping a trivially cheap expression — memo overhead exceeds the computation\",\n });\n }\n },\n }),\n};\n\nconst isMotionElement = (attributeNode: EsTreeNode): boolean => {\n const openingElement = attributeNode.parent;\n if (!openingElement || openingElement.type !== \"JSXOpeningElement\") return false;\n\n const elementName = openingElement.name;\n if (\n elementName?.type === \"JSXMemberExpression\" &&\n elementName.object?.type === \"JSXIdentifier\" &&\n (elementName.object.name === \"motion\" || elementName.object.name === \"m\")\n )\n return true;\n\n if (elementName?.type === \"JSXIdentifier\" && elementName.name.startsWith(\"Motion\")) return true;\n\n return false;\n};\n\nexport const noLayoutPropertyAnimation: Rule = {\n create: (context: RuleContext) => ({\n JSXAttribute(node: EsTreeNode) {\n if (node.name?.type !== \"JSXIdentifier\" || !MOTION_ANIMATE_PROPS.has(node.name.name)) return;\n if (!node.value || node.value.type !== \"JSXExpressionContainer\") return;\n if (isMotionElement(node)) return;\n\n const expression = node.value.expression;\n if (expression?.type !== \"ObjectExpression\") return;\n\n for (const property of expression.properties ?? []) {\n if (property.type !== \"Property\") continue;\n let propertyName = null;\n if (property.key?.type === \"Identifier\") {\n propertyName = property.key.name;\n } else if (property.key?.type === \"Literal\") {\n propertyName = property.key.value;\n }\n\n if (propertyName && LAYOUT_PROPERTIES.has(propertyName)) {\n context.report({\n node: property,\n message: `Animating layout property \"${propertyName}\" triggers layout recalculation every frame — use transform/scale or the layout prop`,\n });\n }\n }\n },\n }),\n};\n\nexport const noTransitionAll: Rule = {\n create: (context: RuleContext) => ({\n JSXAttribute(node: EsTreeNode) {\n if (node.name?.type !== \"JSXIdentifier\" || node.name.name !== \"style\") return;\n if (node.value?.type !== \"JSXExpressionContainer\") return;\n\n const expression = node.value.expression;\n if (expression?.type !== \"ObjectExpression\") return;\n\n for (const property of expression.properties ?? []) {\n if (property.type !== \"Property\") continue;\n const key = property.key?.type === \"Identifier\" ? property.key.name : null;\n if (key !== \"transition\") continue;\n\n if (\n property.value?.type === \"Literal\" &&\n typeof property.value.value === \"string\" &&\n property.value.value.startsWith(\"all\")\n ) {\n context.report({\n node: property,\n message:\n 'transition: \"all\" animates every property including layout — list only the properties you animate',\n });\n }\n }\n },\n }),\n};\n\nexport const noGlobalCssVariableAnimation: Rule = {\n create: (context: RuleContext) => ({\n CallExpression(node: EsTreeNode) {\n if (node.callee?.type !== \"Identifier\") return;\n if (!ANIMATION_CALLBACK_NAMES.has(node.callee.name)) return;\n\n const callback = node.arguments?.[0];\n if (!callback) return;\n\n const calleeName = node.callee.name;\n walkAst(callback, (child: EsTreeNode) => {\n if (child.type !== \"CallExpression\") return;\n if (!isMemberProperty(child.callee, \"setProperty\")) return;\n if (child.arguments?.[0]?.type !== \"Literal\") return;\n\n const variableName = child.arguments[0].value;\n if (typeof variableName !== \"string\" || !variableName.startsWith(\"--\")) return;\n\n context.report({\n node: child,\n message: `CSS variable \"${variableName}\" updated in ${calleeName} — forces style recalculation on all inheriting elements every frame`,\n });\n });\n },\n }),\n};\n\nexport const noLargeAnimatedBlur: Rule = {\n create: (context: RuleContext) => ({\n JSXAttribute(node: EsTreeNode) {\n if (node.name?.type !== \"JSXIdentifier\") return;\n if (node.name.name !== \"style\" && !MOTION_ANIMATE_PROPS.has(node.name.name)) return;\n if (node.value?.type !== \"JSXExpressionContainer\") return;\n\n const expression = node.value.expression;\n if (expression?.type !== \"ObjectExpression\") return;\n\n for (const property of expression.properties ?? []) {\n if (property.type !== \"Property\") continue;\n const key = property.key?.type === \"Identifier\" ? property.key.name : null;\n if (key !== \"filter\" && key !== \"backdropFilter\" && key !== \"WebkitBackdropFilter\")\n continue;\n if (property.value?.type !== \"Literal\" || typeof property.value.value !== \"string\")\n continue;\n\n const match = BLUR_VALUE_PATTERN.exec(property.value.value);\n if (!match) continue;\n\n const blurRadius = Number.parseFloat(match[1]);\n if (blurRadius > LARGE_BLUR_THRESHOLD_PX) {\n context.report({\n node: property,\n message: `blur(${blurRadius}px) is expensive — cost escalates with radius and layer size, can exceed GPU memory on mobile`,\n });\n }\n }\n },\n }),\n};\n\nexport const noScaleFromZero: Rule = {\n create: (context: RuleContext) => ({\n JSXAttribute(node: EsTreeNode) {\n if (node.name?.type !== \"JSXIdentifier\") return;\n if (node.name.name !== \"initial\" && node.name.name !== \"exit\") return;\n if (node.value?.type !== \"JSXExpressionContainer\") return;\n\n const expression = node.value.expression;\n if (expression?.type !== \"ObjectExpression\") return;\n\n for (const property of expression.properties ?? []) {\n if (property.type !== \"Property\") continue;\n const key = property.key?.type === \"Identifier\" ? property.key.name : null;\n if (key !== \"scale\") continue;\n\n if (property.value?.type === \"Literal\" && property.value.value === 0) {\n context.report({\n node: property,\n message:\n \"scale: 0 makes elements appear from nowhere — use scale: 0.95 with opacity: 0 for natural entrance\",\n });\n }\n }\n },\n }),\n};\n\nexport const noPermanentWillChange: Rule = {\n create: (context: RuleContext) => ({\n JSXAttribute(node: EsTreeNode) {\n if (node.name?.type !== \"JSXIdentifier\" || node.name.name !== \"style\") return;\n if (node.value?.type !== \"JSXExpressionContainer\") return;\n\n const expression = node.value.expression;\n if (expression?.type !== \"ObjectExpression\") return;\n\n for (const property of expression.properties ?? []) {\n if (property.type !== \"Property\") continue;\n const key = property.key?.type === \"Identifier\" ? property.key.name : null;\n if (key !== \"willChange\") continue;\n\n context.report({\n node: property,\n message:\n \"Permanent will-change wastes GPU memory — apply only during active animation and remove after\",\n });\n }\n },\n }),\n};\n\nexport const rerenderMemoWithDefaultValue: Rule = {\n create: (context: RuleContext) => {\n const checkDefaultProps = (params: EsTreeNode[]): void => {\n for (const param of params) {\n if (param.type !== \"ObjectPattern\") continue;\n for (const property of param.properties ?? []) {\n if (property.type !== \"Property\" || property.value?.type !== \"AssignmentPattern\")\n continue;\n const defaultValue = property.value.right;\n if (defaultValue?.type === \"ObjectExpression\" && defaultValue.properties?.length === 0) {\n context.report({\n node: defaultValue,\n message:\n \"Default prop value {} creates a new object reference every render — extract to a module-level constant\",\n });\n }\n if (defaultValue?.type === \"ArrayExpression\" && defaultValue.elements?.length === 0) {\n context.report({\n node: defaultValue,\n message:\n \"Default prop value [] creates a new array reference every render — extract to a module-level constant\",\n });\n }\n }\n }\n };\n\n return {\n FunctionDeclaration(node: EsTreeNode) {\n if (!node.id?.name || !isUppercaseName(node.id.name)) return;\n checkDefaultProps(node.params ?? []);\n },\n VariableDeclarator(node: EsTreeNode) {\n if (!isComponentAssignment(node)) return;\n checkDefaultProps(node.init.params ?? []);\n },\n };\n },\n};\n\nexport const renderingAnimateSvgWrapper: Rule = {\n create: (context: RuleContext) => ({\n JSXOpeningElement(node: EsTreeNode) {\n if (node.name?.type !== \"JSXIdentifier\" || node.name.name !== \"svg\") return;\n\n const hasAnimationProp = node.attributes?.some(\n (attribute: EsTreeNode) =>\n attribute.type === \"JSXAttribute\" &&\n attribute.name?.type === \"JSXIdentifier\" &&\n MOTION_ANIMATE_PROPS.has(attribute.name.name),\n );\n\n if (hasAnimationProp) {\n context.report({\n node,\n message:\n \"Animation props directly on <svg> — wrap in a <div> or <motion.div> for better rendering performance\",\n });\n }\n },\n }),\n};\n\nexport const renderingUsetransitionLoading: Rule = {\n create: (context: RuleContext) => ({\n VariableDeclarator(node: EsTreeNode) {\n if (node.id?.type !== \"ArrayPattern\" || !node.id.elements?.length) return;\n if (!node.init || !isHookCall(node.init, \"useState\")) return;\n if (!node.init.arguments?.length) return;\n\n const initializer = node.init.arguments[0];\n if (initializer.type !== \"Literal\" || initializer.value !== false) return;\n\n const stateVariableName = node.id.elements[0]?.name;\n if (!stateVariableName || !LOADING_STATE_PATTERN.test(stateVariableName)) return;\n\n context.report({\n node: node.init,\n message: `useState for \"${stateVariableName}\" — if this guards a state transition (not an async fetch), consider useTransition instead`,\n });\n },\n }),\n};\n\nexport const renderingHydrationNoFlicker: Rule = {\n create: (context: RuleContext) => ({\n CallExpression(node: EsTreeNode) {\n if (!isHookCall(node, EFFECT_HOOK_NAMES) || node.arguments?.length < 2) return;\n\n const depsNode = node.arguments[1];\n if (depsNode.type !== \"ArrayExpression\" || depsNode.elements?.length !== 0) return;\n\n const callback = getEffectCallback(node);\n if (!callback) return;\n\n const bodyStatements =\n callback.body?.type === \"BlockStatement\" ? callback.body.body : [callback.body];\n if (!bodyStatements || bodyStatements.length !== 1) return;\n\n const soleStatement = bodyStatements[0];\n if (soleStatement?.type === \"ExpressionStatement\" && isSetterCall(soleStatement.expression)) {\n context.report({\n node,\n message:\n \"useEffect(setState, []) on mount causes a flash — consider useSyncExternalStore or suppressHydrationWarning\",\n });\n }\n },\n }),\n};\n\nexport const renderingScriptDeferAsync: Rule = {\n create: (context: RuleContext) => ({\n JSXOpeningElement(node: EsTreeNode) {\n if (node.name?.type !== \"JSXIdentifier\" || node.name.name !== \"script\") return;\n\n const attributes = node.attributes ?? [];\n const hasSrc = attributes.some(\n (attr: EsTreeNode) =>\n attr.type === \"JSXAttribute\" &&\n attr.name?.type === \"JSXIdentifier\" &&\n attr.name.name === \"src\",\n );\n\n if (!hasSrc) return;\n\n const typeAttribute = attributes.find(\n (attr: EsTreeNode) =>\n attr.type === \"JSXAttribute\" &&\n attr.name?.type === \"JSXIdentifier\" &&\n attr.name.name === \"type\",\n );\n const typeValue = typeAttribute?.value?.type === \"Literal\" ? typeAttribute.value.value : null;\n if (typeof typeValue === \"string\" && !EXECUTABLE_SCRIPT_TYPES.has(typeValue)) return;\n if (typeValue === \"module\") return;\n\n const hasLoadingStrategy = attributes.some(\n (attr: EsTreeNode) =>\n attr.type === \"JSXAttribute\" &&\n attr.name?.type === \"JSXIdentifier\" &&\n SCRIPT_LOADING_ATTRIBUTES.has(attr.name.name),\n );\n\n if (!hasLoadingStrategy) {\n context.report({\n node,\n message:\n \"<script src> without defer or async — blocks HTML parsing and delays First Contentful Paint. Add defer for DOM-dependent scripts or async for independent ones\",\n });\n }\n },\n }),\n};\n","import {\n DEPRECATED_RN_MODULE_REPLACEMENTS,\n LEGACY_EXPO_PACKAGE_REPLACEMENTS,\n LEGACY_SHADOW_STYLE_PROPERTIES,\n RAW_TEXT_PREVIEW_MAX_CHARS,\n REACT_NATIVE_LIST_COMPONENTS,\n REACT_NATIVE_TEXT_COMPONENTS,\n REACT_NATIVE_TEXT_COMPONENT_KEYWORDS,\n} from \"../constants.js\";\nimport { hasDirective, isMemberProperty } from \"../helpers.js\";\nimport type { EsTreeNode, Rule, RuleContext } from \"../types.js\";\n\nconst resolveJsxElementName = (openingElement: EsTreeNode): string | null => {\n const elementName = openingElement?.name;\n if (!elementName) return null;\n if (elementName.type === \"JSXIdentifier\") return elementName.name;\n if (elementName.type === \"JSXMemberExpression\") return elementName.property?.name ?? null;\n return null;\n};\n\nconst truncateText = (text: string): string =>\n text.length > RAW_TEXT_PREVIEW_MAX_CHARS\n ? `${text.slice(0, RAW_TEXT_PREVIEW_MAX_CHARS)}...`\n : text;\n\nconst isRawTextContent = (child: EsTreeNode): boolean => {\n if (child.type === \"JSXText\") return Boolean(child.value?.trim());\n if (child.type !== \"JSXExpressionContainer\" || !child.expression) return false;\n\n const expression = child.expression;\n return (\n (expression.type === \"Literal\" &&\n (typeof expression.value === \"string\" || typeof expression.value === \"number\")) ||\n expression.type === \"TemplateLiteral\"\n );\n};\n\nconst getRawTextDescription = (child: EsTreeNode): string => {\n if (child.type === \"JSXText\") {\n return `\"${truncateText(child.value.trim())}\"`;\n }\n\n if (child.type === \"JSXExpressionContainer\" && child.expression) {\n const expression = child.expression;\n if (expression.type === \"Literal\" && typeof expression.value === \"string\") {\n return `\"${truncateText(expression.value)}\"`;\n }\n if (expression.type === \"Literal\" && typeof expression.value === \"number\") {\n return `{${expression.value}}`;\n }\n if (expression.type === \"TemplateLiteral\") return \"template literal\";\n }\n\n return \"text content\";\n};\n\nconst isTextHandlingComponent = (elementName: string): boolean => {\n if (REACT_NATIVE_TEXT_COMPONENTS.has(elementName)) return true;\n return [...REACT_NATIVE_TEXT_COMPONENT_KEYWORDS].some((keyword) => elementName.includes(keyword));\n};\n\nexport const rnNoRawText: Rule = {\n create: (context: RuleContext) => {\n let isDomComponentFile = false;\n\n return {\n Program(programNode: EsTreeNode) {\n isDomComponentFile = hasDirective(programNode, \"use dom\");\n },\n JSXElement(node: EsTreeNode) {\n if (isDomComponentFile) return;\n\n const elementName = resolveJsxElementName(node.openingElement);\n if (elementName && isTextHandlingComponent(elementName)) return;\n\n for (const child of node.children ?? []) {\n if (!isRawTextContent(child)) continue;\n\n context.report({\n node: child,\n message: `Raw ${getRawTextDescription(child)} outside a <Text> component — this will crash on React Native`,\n });\n }\n },\n };\n },\n};\n\nexport const rnNoDeprecatedModules: Rule = {\n create: (context: RuleContext) => ({\n ImportDeclaration(node: EsTreeNode) {\n if (node.source?.value !== \"react-native\") return;\n\n for (const specifier of node.specifiers ?? []) {\n if (specifier.type !== \"ImportSpecifier\") continue;\n const importedName = specifier.imported?.name;\n if (!importedName) continue;\n\n const replacement = DEPRECATED_RN_MODULE_REPLACEMENTS[importedName];\n if (!replacement) continue;\n\n context.report({\n node: specifier,\n message: `\"${importedName}\" was removed from react-native — use ${replacement} instead`,\n });\n }\n },\n }),\n};\n\nexport const rnNoLegacyExpoPackages: Rule = {\n create: (context: RuleContext) => ({\n ImportDeclaration(node: EsTreeNode) {\n const source = node.source?.value;\n if (typeof source !== \"string\") return;\n\n for (const [packageName, replacement] of Object.entries(LEGACY_EXPO_PACKAGE_REPLACEMENTS)) {\n if (source === packageName || source.startsWith(`${packageName}/`)) {\n context.report({\n node,\n message: `\"${packageName}\" is deprecated — use ${replacement}`,\n });\n return;\n }\n }\n },\n }),\n};\n\nexport const rnNoDimensionsGet: Rule = {\n create: (context: RuleContext) => ({\n CallExpression(node: EsTreeNode) {\n if (node.callee?.type !== \"MemberExpression\") return;\n if (node.callee.object?.type !== \"Identifier\" || node.callee.object.name !== \"Dimensions\")\n return;\n\n if (isMemberProperty(node.callee, \"get\")) {\n context.report({\n node,\n message:\n \"Dimensions.get() does not update on screen rotation or resize — use useWindowDimensions() for reactive layout\",\n });\n }\n\n if (isMemberProperty(node.callee, \"addEventListener\")) {\n context.report({\n node,\n message:\n \"Dimensions.addEventListener() was removed in React Native 0.72 — use useWindowDimensions() instead\",\n });\n }\n },\n }),\n};\n\nexport const rnNoInlineFlatlistRenderitem: Rule = {\n create: (context: RuleContext) => ({\n JSXAttribute(node: EsTreeNode) {\n if (node.name?.type !== \"JSXIdentifier\" || node.name.name !== \"renderItem\") return;\n if (!node.value || node.value.type !== \"JSXExpressionContainer\") return;\n\n const openingElement = node.parent;\n if (!openingElement || openingElement.type !== \"JSXOpeningElement\") return;\n\n const listComponentName = resolveJsxElementName(openingElement);\n if (!listComponentName || !REACT_NATIVE_LIST_COMPONENTS.has(listComponentName)) return;\n\n const expression = node.value.expression;\n if (\n expression?.type !== \"ArrowFunctionExpression\" &&\n expression?.type !== \"FunctionExpression\"\n )\n return;\n\n context.report({\n node: expression,\n message: `Inline renderItem on <${listComponentName}> creates a new function reference every render — extract to a named function or wrap in useCallback`,\n });\n },\n }),\n};\n\nconst reportLegacyShadowProperties = (objectExpression: EsTreeNode, context: RuleContext): void => {\n const legacyShadowPropertyNames: string[] = [];\n\n for (const property of objectExpression.properties ?? []) {\n if (property.type !== \"Property\") continue;\n const propertyName = property.key?.type === \"Identifier\" ? property.key.name : null;\n if (propertyName && LEGACY_SHADOW_STYLE_PROPERTIES.has(propertyName)) {\n legacyShadowPropertyNames.push(propertyName);\n }\n }\n\n if (legacyShadowPropertyNames.length === 0) return;\n\n const quotedPropertyNames = legacyShadowPropertyNames.map((name) => `\"${name}\"`).join(\", \");\n context.report({\n node: objectExpression,\n message: `Legacy shadow style${legacyShadowPropertyNames.length > 1 ? \"s\" : \"\"} ${quotedPropertyNames} — use boxShadow for cross-platform shadows on the new architecture`,\n });\n};\n\nexport const rnNoLegacyShadowStyles: Rule = {\n create: (context: RuleContext) => ({\n JSXAttribute(node: EsTreeNode) {\n if (node.name?.type !== \"JSXIdentifier\" || node.name.name !== \"style\") return;\n if (node.value?.type !== \"JSXExpressionContainer\") return;\n\n const expression = node.value.expression;\n\n if (expression?.type === \"ObjectExpression\") {\n reportLegacyShadowProperties(expression, context);\n } else if (expression?.type === \"ArrayExpression\") {\n for (const element of expression.elements ?? []) {\n if (element?.type === \"ObjectExpression\") {\n reportLegacyShadowProperties(element, context);\n }\n }\n }\n },\n CallExpression(node: EsTreeNode) {\n if (node.callee?.type !== \"MemberExpression\") return;\n if (node.callee.object?.type !== \"Identifier\" || node.callee.object.name !== \"StyleSheet\")\n return;\n if (!isMemberProperty(node.callee, \"create\")) return;\n\n const stylesArgument = node.arguments?.[0];\n if (stylesArgument?.type !== \"ObjectExpression\") return;\n\n for (const styleDefinition of stylesArgument.properties ?? []) {\n if (styleDefinition.type !== \"Property\") continue;\n if (styleDefinition.value?.type !== \"ObjectExpression\") continue;\n reportLegacyShadowProperties(styleDefinition.value, context);\n }\n },\n }),\n};\n\nexport const rnPreferReanimated: Rule = {\n create: (context: RuleContext) => ({\n ImportDeclaration(node: EsTreeNode) {\n if (node.source?.value !== \"react-native\") return;\n\n for (const specifier of node.specifiers ?? []) {\n if (specifier.type !== \"ImportSpecifier\") continue;\n if (specifier.imported?.name !== \"Animated\") continue;\n\n context.report({\n node: specifier,\n message:\n \"Animated from react-native runs animations on the JS thread — use react-native-reanimated for performant UI-thread animations\",\n });\n }\n },\n }),\n};\n\nexport const rnNoSingleElementStyleArray: Rule = {\n create: (context: RuleContext) => ({\n JSXAttribute(node: EsTreeNode) {\n const propName = node.name?.type === \"JSXIdentifier\" ? node.name.name : null;\n if (!propName) return;\n if (propName !== \"style\" && !propName.endsWith(\"Style\")) return;\n if (node.value?.type !== \"JSXExpressionContainer\") return;\n\n const expression = node.value.expression;\n if (expression?.type !== \"ArrayExpression\") return;\n if (expression.elements?.length !== 1) return;\n\n context.report({\n node: expression,\n message: `Single-element style array on \"${propName}\" — use ${propName}={value} instead of ${propName}={[value]} to avoid unnecessary array allocation`,\n });\n },\n }),\n};\n","import {\n EFFECT_HOOK_NAMES,\n MUTATING_HTTP_METHODS,\n STABLE_HOOK_WRAPPERS,\n TANSTACK_MUTATION_HOOKS,\n TANSTACK_QUERY_CLIENT_CLASS,\n TANSTACK_QUERY_HOOKS,\n UPPERCASE_PATTERN,\n} from \"../constants.js\";\nimport { getEffectCallback, isHookCall, walkAst } from \"../helpers.js\";\nimport type { EsTreeNode, Rule, RuleContext } from \"../types.js\";\n\nexport const queryStableQueryClient: Rule = {\n create: (context: RuleContext) => {\n let componentDepth = 0;\n let stableHookDepth = 0;\n\n return {\n FunctionDeclaration(node: EsTreeNode) {\n if (node.id?.name && UPPERCASE_PATTERN.test(node.id.name)) {\n componentDepth++;\n }\n },\n \"FunctionDeclaration:exit\"(node: EsTreeNode) {\n if (node.id?.name && UPPERCASE_PATTERN.test(node.id.name)) {\n componentDepth--;\n }\n },\n VariableDeclarator(node: EsTreeNode) {\n if (\n node.id?.type === \"Identifier\" &&\n UPPERCASE_PATTERN.test(node.id.name) &&\n (node.init?.type === \"ArrowFunctionExpression\" ||\n node.init?.type === \"FunctionExpression\")\n ) {\n componentDepth++;\n }\n },\n \"VariableDeclarator:exit\"(node: EsTreeNode) {\n if (\n node.id?.type === \"Identifier\" &&\n UPPERCASE_PATTERN.test(node.id.name) &&\n (node.init?.type === \"ArrowFunctionExpression\" ||\n node.init?.type === \"FunctionExpression\")\n ) {\n componentDepth--;\n }\n },\n CallExpression(node: EsTreeNode) {\n if (node.callee?.type === \"Identifier\" && STABLE_HOOK_WRAPPERS.has(node.callee.name)) {\n stableHookDepth++;\n }\n },\n \"CallExpression:exit\"(node: EsTreeNode) {\n if (node.callee?.type === \"Identifier\" && STABLE_HOOK_WRAPPERS.has(node.callee.name)) {\n stableHookDepth--;\n }\n },\n NewExpression(node: EsTreeNode) {\n if (componentDepth <= 0) return;\n if (stableHookDepth > 0) return;\n if (node.callee?.type !== \"Identifier\" || node.callee.name !== TANSTACK_QUERY_CLIENT_CLASS)\n return;\n\n context.report({\n node,\n message:\n \"new QueryClient() inside a component — creates a new cache on every render. Move to module scope or wrap in useState(() => new QueryClient())\",\n });\n },\n };\n },\n};\n\nexport const queryNoRestDestructuring: Rule = {\n create: (context: RuleContext) => ({\n VariableDeclarator(node: EsTreeNode) {\n if (node.id?.type !== \"ObjectPattern\") return;\n if (!node.init || node.init.type !== \"CallExpression\") return;\n\n const calleeName = node.init.callee?.type === \"Identifier\" ? node.init.callee.name : null;\n\n if (!calleeName || !TANSTACK_QUERY_HOOKS.has(calleeName)) return;\n\n const hasRestElement = node.id.properties?.some(\n (property: EsTreeNode) => property.type === \"RestElement\",\n );\n\n if (hasRestElement) {\n context.report({\n node: node.id,\n message: `Rest destructuring on ${calleeName}() result — subscribes to all fields and causes unnecessary re-renders. Destructure only the fields you need`,\n });\n }\n },\n }),\n};\n\nexport const queryNoVoidQueryFn: Rule = {\n create: (context: RuleContext) => ({\n CallExpression(node: EsTreeNode) {\n const calleeName = node.callee?.type === \"Identifier\" ? node.callee.name : null;\n\n if (!calleeName || !TANSTACK_QUERY_HOOKS.has(calleeName)) return;\n\n const optionsArgument = node.arguments?.[0];\n if (!optionsArgument || optionsArgument.type !== \"ObjectExpression\") return;\n\n const queryFnProperty = optionsArgument.properties?.find(\n (property: EsTreeNode) =>\n property.type === \"Property\" &&\n property.key?.type === \"Identifier\" &&\n property.key.name === \"queryFn\",\n );\n\n if (!queryFnProperty?.value) return;\n\n const queryFnValue = queryFnProperty.value;\n\n if (\n queryFnValue.type === \"ArrowFunctionExpression\" &&\n queryFnValue.body?.type !== \"BlockStatement\"\n ) {\n return;\n }\n\n if (\n queryFnValue.type === \"ArrowFunctionExpression\" ||\n queryFnValue.type === \"FunctionExpression\"\n ) {\n const body = queryFnValue.body;\n if (body?.type !== \"BlockStatement\") return;\n\n const statements = body.body ?? [];\n if (statements.length === 0) {\n context.report({\n node: queryFnProperty,\n message:\n \"Empty queryFn — query functions must return a value. Use the enabled option to conditionally disable the query instead\",\n });\n }\n }\n },\n }),\n};\n\nexport const queryNoQueryInEffect: Rule = {\n create: (context: RuleContext) => ({\n CallExpression(node: EsTreeNode) {\n if (!isHookCall(node, EFFECT_HOOK_NAMES)) return;\n\n const callback = getEffectCallback(node);\n if (!callback) return;\n\n walkAst(callback, (child: EsTreeNode) => {\n if (child.type !== \"CallExpression\") return;\n\n const calleeName = child.callee?.type === \"Identifier\" ? child.callee.name : null;\n\n if (calleeName === \"refetch\") {\n context.report({\n node: child,\n message:\n \"refetch() inside useEffect — React Query manages refetching automatically. Use queryKey dependencies or the enabled option instead\",\n });\n }\n });\n },\n }),\n};\n\nexport const queryMutationMissingInvalidation: Rule = {\n create: (context: RuleContext) => ({\n CallExpression(node: EsTreeNode) {\n const calleeName = node.callee?.type === \"Identifier\" ? node.callee.name : null;\n\n if (!calleeName || !TANSTACK_MUTATION_HOOKS.has(calleeName)) return;\n\n const optionsArgument = node.arguments?.[0];\n if (!optionsArgument || optionsArgument.type !== \"ObjectExpression\") return;\n\n const hasMutationFn = optionsArgument.properties?.some(\n (property: EsTreeNode) =>\n property.type === \"Property\" &&\n property.key?.type === \"Identifier\" &&\n property.key.name === \"mutationFn\",\n );\n\n if (!hasMutationFn) return;\n\n let hasInvalidation = false;\n walkAst(optionsArgument, (child: EsTreeNode) => {\n if (hasInvalidation) return;\n if (\n child.type === \"CallExpression\" &&\n child.callee?.type === \"MemberExpression\" &&\n child.callee.property?.type === \"Identifier\" &&\n child.callee.property.name === \"invalidateQueries\"\n ) {\n hasInvalidation = true;\n }\n });\n\n if (!hasInvalidation) {\n context.report({\n node,\n message:\n \"useMutation without invalidateQueries — stale data may remain cached after the mutation. Add onSuccess with queryClient.invalidateQueries()\",\n });\n }\n },\n }),\n};\n\nexport const queryNoUseQueryForMutation: Rule = {\n create: (context: RuleContext) => ({\n CallExpression(node: EsTreeNode) {\n const calleeName = node.callee?.type === \"Identifier\" ? node.callee.name : null;\n\n if (!calleeName || !TANSTACK_QUERY_HOOKS.has(calleeName)) return;\n\n const optionsArgument = node.arguments?.[0];\n if (!optionsArgument || optionsArgument.type !== \"ObjectExpression\") return;\n\n const queryFnProperty = optionsArgument.properties?.find(\n (property: EsTreeNode) =>\n property.type === \"Property\" &&\n property.key?.type === \"Identifier\" &&\n property.key.name === \"queryFn\",\n );\n\n if (!queryFnProperty?.value) return;\n\n let hasMutatingFetch = false;\n walkAst(queryFnProperty.value, (child: EsTreeNode) => {\n if (hasMutatingFetch) return;\n if (child.type !== \"CallExpression\") return;\n if (child.callee?.type !== \"Identifier\" || child.callee.name !== \"fetch\") return;\n\n const optionsArg = child.arguments?.[1];\n if (!optionsArg || optionsArg.type !== \"ObjectExpression\") return;\n\n const methodProperty = optionsArg.properties?.find(\n (property: EsTreeNode) =>\n property.type === \"Property\" &&\n property.key?.type === \"Identifier\" &&\n property.key.name === \"method\" &&\n property.value?.type === \"Literal\" &&\n typeof property.value.value === \"string\" &&\n MUTATING_HTTP_METHODS.has(property.value.value.toUpperCase()),\n );\n\n if (methodProperty) hasMutatingFetch = true;\n });\n\n if (hasMutatingFetch) {\n context.report({\n node,\n message: `${calleeName}() with a mutating fetch (POST/PUT/DELETE) — use useMutation() instead, which provides onSuccess/onError callbacks and doesn't auto-refetch`,\n });\n }\n },\n }),\n};\n","import {\n SECRET_FALSE_POSITIVE_SUFFIXES,\n SECRET_MIN_LENGTH_CHARS,\n SECRET_PATTERNS,\n SECRET_VARIABLE_PATTERN,\n} from \"../constants.js\";\nimport type { EsTreeNode, Rule, RuleContext } from \"../types.js\";\n\nexport const noEval: Rule = {\n create: (context: RuleContext) => ({\n CallExpression(node: EsTreeNode) {\n if (node.callee?.type === \"Identifier\" && node.callee.name === \"eval\") {\n context.report({\n node,\n message: \"eval() is a code injection risk — avoid dynamic code execution\",\n });\n return;\n }\n\n if (\n node.callee?.type === \"Identifier\" &&\n (node.callee.name === \"setTimeout\" || node.callee.name === \"setInterval\") &&\n node.arguments?.[0]?.type === \"Literal\" &&\n typeof node.arguments[0].value === \"string\"\n ) {\n context.report({\n node,\n message: `${node.callee.name}() with string argument executes code dynamically — use a function instead`,\n });\n }\n },\n NewExpression(node: EsTreeNode) {\n if (node.callee?.type === \"Identifier\" && node.callee.name === \"Function\") {\n context.report({\n node,\n message: \"new Function() is a code injection risk — avoid dynamic code execution\",\n });\n }\n },\n }),\n};\n\nexport const noSecretsInClientCode: Rule = {\n create: (context: RuleContext) => ({\n VariableDeclarator(node: EsTreeNode) {\n if (node.id?.type !== \"Identifier\") return;\n if (node.init?.type !== \"Literal\" || typeof node.init.value !== \"string\") return;\n\n const variableName = node.id.name;\n const literalValue = node.init.value;\n\n const trailingSuffix = variableName.split(\"_\").pop()?.toLowerCase() ?? \"\";\n const isUiConstant = SECRET_FALSE_POSITIVE_SUFFIXES.has(trailingSuffix);\n\n if (\n SECRET_VARIABLE_PATTERN.test(variableName) &&\n !isUiConstant &&\n literalValue.length > SECRET_MIN_LENGTH_CHARS\n ) {\n context.report({\n node,\n message: `Possible hardcoded secret in \"${variableName}\" — use environment variables instead`,\n });\n return;\n }\n\n if (SECRET_PATTERNS.some((pattern) => pattern.test(literalValue))) {\n context.report({\n node,\n message: \"Hardcoded secret detected — use environment variables instead\",\n });\n }\n },\n }),\n};\n","import {\n AUTH_CHECK_LOOKAHEAD_STATEMENTS,\n AUTH_FUNCTION_NAMES,\n SERVER_ACTION_DIRECTORY_PATTERN,\n SERVER_ACTION_FILE_PATTERN,\n} from \"../constants.js\";\nimport { hasDirective, hasUseServerDirective, walkAst } from \"../helpers.js\";\nimport type { EsTreeNode, Rule, RuleContext } from \"../types.js\";\n\nconst containsAuthCheck = (statements: EsTreeNode[]): boolean => {\n let foundAuthCall = false;\n for (const statement of statements) {\n walkAst(statement, (child: EsTreeNode) => {\n if (foundAuthCall) return;\n let callNode: EsTreeNode | null = null;\n if (child.type === \"CallExpression\") {\n callNode = child;\n } else if (child.type === \"AwaitExpression\" && child.argument?.type === \"CallExpression\") {\n callNode = child.argument;\n }\n\n if (\n callNode?.callee?.type === \"Identifier\" &&\n AUTH_FUNCTION_NAMES.has(callNode.callee.name)\n ) {\n foundAuthCall = true;\n }\n });\n }\n return foundAuthCall;\n};\n\nexport const serverAuthActions: Rule = {\n create: (context: RuleContext) => {\n let fileHasUseServerDirective = false;\n\n return {\n Program(programNode: EsTreeNode) {\n fileHasUseServerDirective = hasDirective(programNode, \"use server\");\n },\n ExportNamedDeclaration(node: EsTreeNode) {\n const declaration = node.declaration;\n if (declaration?.type !== \"FunctionDeclaration\" || !declaration?.async) return;\n\n const isServerAction = fileHasUseServerDirective || hasUseServerDirective(declaration);\n if (!isServerAction) return;\n\n const firstStatements = (declaration.body?.body ?? []).slice(\n 0,\n AUTH_CHECK_LOOKAHEAD_STATEMENTS,\n );\n if (!containsAuthCheck(firstStatements)) {\n const functionName = declaration.id?.name ?? \"anonymous\";\n context.report({\n node: declaration.id ?? node,\n message: `Server action \"${functionName}\" — add auth check (auth(), getSession(), etc.) at the top`,\n });\n }\n },\n };\n },\n};\n\nexport const serverAfterNonblocking: Rule = {\n create: (context: RuleContext) => {\n let fileHasUseServerDirective = false;\n\n return {\n Program(programNode: EsTreeNode) {\n fileHasUseServerDirective = hasDirective(programNode, \"use server\");\n },\n CallExpression(node: EsTreeNode) {\n if (!fileHasUseServerDirective) return;\n if (node.callee?.type !== \"MemberExpression\") return;\n if (node.callee.property?.type !== \"Identifier\") return;\n\n const objectName =\n node.callee.object?.type === \"Identifier\" ? node.callee.object.name : null;\n if (!objectName) return;\n\n const methodName = node.callee.property.name;\n const isLoggingCall =\n (objectName === \"console\" &&\n (methodName === \"log\" || methodName === \"info\" || methodName === \"warn\")) ||\n (objectName === \"analytics\" &&\n (methodName === \"track\" || methodName === \"identify\" || methodName === \"page\"));\n if (!isLoggingCall) return;\n\n context.report({\n node,\n message: `${objectName}.${methodName}() in server action — use after() for non-blocking logging/analytics`,\n });\n },\n };\n },\n};\n","import {\n MUTATING_HTTP_METHODS,\n SEQUENTIAL_AWAIT_THRESHOLD_FOR_LOADER,\n TANSTACK_MIDDLEWARE_METHOD_ORDER,\n TANSTACK_REDIRECT_FUNCTIONS,\n TANSTACK_ROUTE_CREATION_FUNCTIONS,\n TANSTACK_ROUTE_FILE_PATTERN,\n TANSTACK_ROUTE_PROPERTY_ORDER,\n TANSTACK_ROOT_ROUTE_FILE_PATTERN,\n TANSTACK_SERVER_FN_FILE_PATTERN,\n TANSTACK_SERVER_FN_NAMES,\n UPPERCASE_PATTERN,\n} from \"../constants.js\";\nimport { findSideEffect, getCalleeName, walkAst } from \"../helpers.js\";\nimport type { EsTreeNode, Rule, RuleContext } from \"../types.js\";\n\nconst getRouteOptionsObject = (node: EsTreeNode): EsTreeNode | null => {\n if (node.type !== \"CallExpression\") return null;\n\n const callee = node.callee;\n\n if (callee?.type === \"CallExpression\" && callee.callee?.type === \"Identifier\") {\n if (!TANSTACK_ROUTE_CREATION_FUNCTIONS.has(callee.callee.name)) return null;\n const optionsArgument = node.arguments?.[0];\n if (optionsArgument?.type === \"ObjectExpression\") return optionsArgument;\n return null;\n }\n\n if (callee?.type === \"Identifier\") {\n if (!TANSTACK_ROUTE_CREATION_FUNCTIONS.has(callee.name)) return null;\n const optionsArgument = node.arguments?.[0];\n if (optionsArgument?.type === \"ObjectExpression\") return optionsArgument;\n return null;\n }\n\n return null;\n};\n\nconst getPropertyKeyName = (property: EsTreeNode): string | null => {\n if (property.type !== \"Property\" && property.type !== \"MethodDefinition\") return null;\n if (property.key?.type === \"Identifier\") return property.key.name;\n if (property.key?.type === \"Literal\") return String(property.key.value);\n return null;\n};\n\ninterface ServerFnChainInfo {\n isServerFnChain: boolean;\n specifiedMethod: string | null;\n hasInputValidator: boolean;\n}\n\nconst walkServerFnChain = (outerNode: EsTreeNode): ServerFnChainInfo => {\n const result: ServerFnChainInfo = {\n isServerFnChain: false,\n specifiedMethod: null,\n hasInputValidator: false,\n };\n\n let currentNode: EsTreeNode = outerNode.callee?.object;\n\n while (currentNode?.type === \"CallExpression\") {\n const calleeName = getCalleeName(currentNode);\n\n if (calleeName && TANSTACK_SERVER_FN_NAMES.has(calleeName)) {\n result.isServerFnChain = true;\n\n const optionsArgument = currentNode.arguments?.[0];\n if (optionsArgument?.type === \"ObjectExpression\") {\n for (const property of optionsArgument.properties ?? []) {\n if (\n property.key?.type === \"Identifier\" &&\n property.key.name === \"method\" &&\n property.value?.type === \"Literal\" &&\n typeof property.value.value === \"string\"\n ) {\n result.specifiedMethod = property.value.value;\n }\n }\n }\n }\n\n if (calleeName === \"inputValidator\") {\n result.hasInputValidator = true;\n }\n\n if (currentNode.callee?.type === \"MemberExpression\") {\n currentNode = currentNode.callee.object;\n } else {\n break;\n }\n }\n\n return result;\n};\n\nexport const tanstackStartRoutePropertyOrder: Rule = {\n create: (context: RuleContext) => ({\n CallExpression(node: EsTreeNode) {\n const optionsObject = getRouteOptionsObject(node);\n if (!optionsObject) return;\n\n const properties: EsTreeNode[] = optionsObject.properties ?? [];\n const orderedPropertyNames: string[] = [];\n for (const property of properties) {\n const propertyName = getPropertyKeyName(property);\n if (propertyName !== null) {\n orderedPropertyNames.push(propertyName);\n }\n }\n\n const sensitiveProperties = orderedPropertyNames.filter((propertyName) =>\n TANSTACK_ROUTE_PROPERTY_ORDER.includes(propertyName),\n );\n\n let lastIndex = -1;\n for (const propertyName of sensitiveProperties) {\n const currentIndex = TANSTACK_ROUTE_PROPERTY_ORDER.indexOf(propertyName);\n if (currentIndex < lastIndex) {\n const expectedBefore = TANSTACK_ROUTE_PROPERTY_ORDER[lastIndex];\n context.report({\n node: optionsObject,\n message: `Route property \"${propertyName}\" must come before \"${expectedBefore}\" — wrong order breaks TypeScript type inference`,\n });\n return;\n }\n lastIndex = currentIndex;\n }\n },\n }),\n};\n\nexport const tanstackStartNoDirectFetchInLoader: Rule = {\n create: (context: RuleContext) => ({\n CallExpression(node: EsTreeNode) {\n const optionsObject = getRouteOptionsObject(node);\n if (!optionsObject) return;\n\n const properties = optionsObject.properties ?? [];\n for (const property of properties) {\n const keyName = getPropertyKeyName(property);\n if (keyName !== \"loader\") continue;\n\n const loaderValue = property.value ?? property;\n walkAst(loaderValue, (child: EsTreeNode) => {\n if (child.type !== \"CallExpression\") return;\n if (child.callee?.type === \"Identifier\" && child.callee.name === \"fetch\") {\n context.report({\n node: child,\n message:\n \"Direct fetch() in route loader — use createServerFn() for type-safe server logic with automatic RPC\",\n });\n }\n });\n }\n },\n }),\n};\n\nexport const tanstackStartServerFnValidateInput: Rule = {\n create: (context: RuleContext) => ({\n CallExpression(node: EsTreeNode) {\n if (node.callee?.type !== \"MemberExpression\") return;\n if (node.callee.property?.type !== \"Identifier\") return;\n if (node.callee.property.name !== \"handler\") return;\n\n const chainInfo = walkServerFnChain(node);\n if (!chainInfo.isServerFnChain) return;\n\n const handlerFunction = node.arguments?.[0];\n if (!handlerFunction) return;\n\n let accessesData = false;\n walkAst(handlerFunction, (child: EsTreeNode) => {\n if (\n child.type === \"MemberExpression\" &&\n child.property?.type === \"Identifier\" &&\n child.property.name === \"data\"\n ) {\n accessesData = true;\n }\n if (\n child.type === \"ObjectPattern\" &&\n child.properties?.some(\n (property: EsTreeNode) =>\n property.key?.type === \"Identifier\" && property.key.name === \"data\",\n )\n ) {\n accessesData = true;\n }\n });\n\n if (accessesData && !chainInfo.hasInputValidator) {\n context.report({\n node,\n message:\n \"Server function handler accesses data without inputValidator() — validate inputs crossing the network boundary\",\n });\n }\n },\n }),\n};\n\nexport const tanstackStartNoUseEffectFetch: Rule = {\n create: (context: RuleContext) => ({\n CallExpression(node: EsTreeNode) {\n const filename = context.getFilename?.() ?? \"\";\n const isRouteFile = TANSTACK_ROUTE_FILE_PATTERN.test(filename);\n if (!isRouteFile) return;\n\n if (node.callee?.type !== \"Identifier\") return;\n if (node.callee.name !== \"useEffect\" && node.callee.name !== \"useLayoutEffect\") return;\n\n const callback = node.arguments?.[0];\n if (!callback) return;\n\n let hasFetchCall = false;\n walkAst(callback, (child: EsTreeNode) => {\n if (hasFetchCall) return;\n if (\n child.type === \"CallExpression\" &&\n child.callee?.type === \"Identifier\" &&\n child.callee.name === \"fetch\"\n ) {\n hasFetchCall = true;\n }\n });\n\n if (hasFetchCall) {\n context.report({\n node,\n message:\n \"fetch() inside useEffect in a route file — use the route loader or createServerFn() instead\",\n });\n }\n },\n }),\n};\n\nexport const tanstackStartMissingHeadContent: Rule = {\n create: (context: RuleContext) => {\n let hasHeadContentElement = false;\n\n return {\n JSXOpeningElement(node: EsTreeNode) {\n const filename = context.getFilename?.() ?? \"\";\n const isRootRouteFile = TANSTACK_ROOT_ROUTE_FILE_PATTERN.test(filename);\n if (!isRootRouteFile) return;\n\n if (node.name?.type === \"JSXIdentifier\" && node.name.name === \"HeadContent\") {\n hasHeadContentElement = true;\n }\n },\n \"Program:exit\"(programNode: EsTreeNode) {\n const filename = context.getFilename?.() ?? \"\";\n const isRootRouteFile = TANSTACK_ROOT_ROUTE_FILE_PATTERN.test(filename);\n if (!isRootRouteFile) return;\n\n if (!hasHeadContentElement) {\n context.report({\n node: programNode,\n message:\n \"Root route (__root) without <HeadContent /> — route head() meta tags won't render\",\n });\n }\n },\n };\n },\n};\n\nexport const tanstackStartNoAnchorElement: Rule = {\n create: (context: RuleContext) => ({\n JSXOpeningElement(node: EsTreeNode) {\n const filename = context.getFilename?.() ?? \"\";\n const isRouteFile = TANSTACK_ROUTE_FILE_PATTERN.test(filename);\n if (!isRouteFile) return;\n\n if (node.name?.type !== \"JSXIdentifier\" || node.name.name !== \"a\") return;\n\n const attributes = node.attributes ?? [];\n const hrefAttribute = attributes.find(\n (attribute: EsTreeNode) =>\n attribute.type === \"JSXAttribute\" &&\n attribute.name?.type === \"JSXIdentifier\" &&\n attribute.name.name === \"href\",\n );\n\n if (!hrefAttribute?.value) return;\n\n let hrefValue: string | null = null;\n if (hrefAttribute.value.type === \"Literal\") {\n hrefValue = hrefAttribute.value.value;\n } else if (\n hrefAttribute.value.type === \"JSXExpressionContainer\" &&\n hrefAttribute.value.expression?.type === \"Literal\"\n ) {\n hrefValue = hrefAttribute.value.expression.value;\n }\n\n if (typeof hrefValue === \"string\" && hrefValue.startsWith(\"/\")) {\n context.report({\n node,\n message:\n \"Use <Link> from @tanstack/react-router instead of <a> for internal navigation — enables type-safe routing and preloading\",\n });\n }\n },\n }),\n};\n\nexport const tanstackStartServerFnMethodOrder: Rule = {\n create: (context: RuleContext) => ({\n CallExpression(node: EsTreeNode) {\n if (node.callee?.type !== \"MemberExpression\") return;\n\n const methodNames: string[] = [];\n let currentNode: EsTreeNode = node;\n\n while (\n currentNode?.type === \"CallExpression\" &&\n currentNode.callee?.type === \"MemberExpression\"\n ) {\n const methodName =\n currentNode.callee.property?.type === \"Identifier\"\n ? currentNode.callee.property.name\n : null;\n if (methodName) methodNames.unshift(methodName);\n currentNode = currentNode.callee.object;\n }\n\n if (currentNode?.type === \"CallExpression\" && currentNode.callee?.type === \"Identifier\") {\n if (!TANSTACK_SERVER_FN_NAMES.has(currentNode.callee.name)) return;\n } else {\n return;\n }\n\n const ownMethodName =\n node.callee.property?.type === \"Identifier\" ? node.callee.property.name : null;\n if (methodNames[methodNames.length - 1] !== ownMethodName) return;\n\n const orderSensitiveMethods = methodNames.filter((name) =>\n TANSTACK_MIDDLEWARE_METHOD_ORDER.includes(name),\n );\n\n let lastIndex = -1;\n for (const methodName of orderSensitiveMethods) {\n const currentIndex = TANSTACK_MIDDLEWARE_METHOD_ORDER.indexOf(methodName);\n if (currentIndex < lastIndex) {\n const expectedBefore = TANSTACK_MIDDLEWARE_METHOD_ORDER[lastIndex];\n context.report({\n node,\n message: `Server function method .${methodName}() must come before .${expectedBefore}() — wrong order breaks type inference`,\n });\n return;\n }\n lastIndex = currentIndex;\n }\n },\n }),\n};\n\nexport const tanstackStartNoNavigateInRender: Rule = {\n create: (context: RuleContext) => {\n let effectDepth = 0;\n let eventHandlerDepth = 0;\n\n return {\n CallExpression(node: EsTreeNode) {\n const filename = context.getFilename?.() ?? \"\";\n const isRouteFile = TANSTACK_ROUTE_FILE_PATTERN.test(filename);\n if (!isRouteFile) return;\n\n if (\n node.callee?.type === \"Identifier\" &&\n (node.callee.name === \"useEffect\" || node.callee.name === \"useLayoutEffect\")\n ) {\n effectDepth++;\n }\n\n if (effectDepth > 0 || eventHandlerDepth > 0) return;\n\n if (\n node.callee?.type === \"Identifier\" &&\n node.callee.name === \"navigate\" &&\n node.arguments?.length > 0\n ) {\n context.report({\n node,\n message:\n \"navigate() called during render — use redirect() in beforeLoad/loader for route-level redirects\",\n });\n }\n },\n \"CallExpression:exit\"(node: EsTreeNode) {\n const filename = context.getFilename?.() ?? \"\";\n const isRouteFile = TANSTACK_ROUTE_FILE_PATTERN.test(filename);\n if (!isRouteFile) return;\n\n if (\n node.callee?.type === \"Identifier\" &&\n (node.callee.name === \"useEffect\" || node.callee.name === \"useLayoutEffect\")\n ) {\n effectDepth--;\n }\n },\n JSXAttribute(node: EsTreeNode) {\n const filename = context.getFilename?.() ?? \"\";\n const isRouteFile = TANSTACK_ROUTE_FILE_PATTERN.test(filename);\n if (!isRouteFile) return;\n\n if (\n node.name?.type === \"JSXIdentifier\" &&\n node.name.name.startsWith(\"on\") &&\n UPPERCASE_PATTERN.test(node.name.name.charAt(2))\n ) {\n eventHandlerDepth++;\n }\n },\n \"JSXAttribute:exit\"(node: EsTreeNode) {\n const filename = context.getFilename?.() ?? \"\";\n const isRouteFile = TANSTACK_ROUTE_FILE_PATTERN.test(filename);\n if (!isRouteFile) return;\n\n if (\n node.name?.type === \"JSXIdentifier\" &&\n node.name.name.startsWith(\"on\") &&\n UPPERCASE_PATTERN.test(node.name.name.charAt(2))\n ) {\n eventHandlerDepth--;\n }\n },\n };\n },\n};\n\nexport const tanstackStartNoDynamicServerFnImport: Rule = {\n create: (context: RuleContext) => ({\n ImportExpression(node: EsTreeNode) {\n const source = node.source;\n if (!source) return;\n\n let importPath: string | null = null;\n if (source.type === \"Literal\" && typeof source.value === \"string\") {\n importPath = source.value;\n } else if (source.type === \"TemplateLiteral\" && source.quasis?.length === 1) {\n importPath = source.quasis[0].value?.raw ?? null;\n }\n\n if (importPath && TANSTACK_SERVER_FN_FILE_PATTERN.test(importPath)) {\n context.report({\n node,\n message:\n \"Dynamic import of server functions file — use static imports so the bundler can replace server code with RPC stubs\",\n });\n }\n },\n }),\n};\n\nexport const tanstackStartNoUseServerInHandler: Rule = {\n create: (context: RuleContext) => ({\n CallExpression(node: EsTreeNode) {\n if (node.callee?.type !== \"MemberExpression\") return;\n if (node.callee.property?.type !== \"Identifier\" || node.callee.property.name !== \"handler\")\n return;\n\n const handlerFunction = node.arguments?.[0];\n if (\n !handlerFunction ||\n (handlerFunction.type !== \"ArrowFunctionExpression\" &&\n handlerFunction.type !== \"FunctionExpression\")\n )\n return;\n\n const body = handlerFunction.body;\n if (body?.type !== \"BlockStatement\") return;\n\n const hasUseServerDirective = body.body?.some(\n (statement: EsTreeNode) =>\n statement.type === \"ExpressionStatement\" &&\n (statement.directive === \"use server\" ||\n (statement.expression?.type === \"Literal\" &&\n statement.expression.value === \"use server\")),\n );\n\n if (hasUseServerDirective) {\n context.report({\n node: handlerFunction,\n message:\n '\"use server\" inside createServerFn handler — TanStack Start handles this automatically, remove the directive',\n });\n }\n },\n }),\n};\n\nexport const tanstackStartNoSecretsInLoader: Rule = {\n create: (context: RuleContext) => ({\n CallExpression(node: EsTreeNode) {\n const optionsObject = getRouteOptionsObject(node);\n if (!optionsObject) return;\n\n const properties = optionsObject.properties ?? [];\n for (const property of properties) {\n const keyName = getPropertyKeyName(property);\n if (keyName !== \"loader\" && keyName !== \"beforeLoad\") continue;\n\n const loaderValue = property.value ?? property;\n walkAst(loaderValue, (child: EsTreeNode) => {\n if (child.type !== \"MemberExpression\") return;\n if (\n child.object?.type === \"MemberExpression\" &&\n child.object.object?.type === \"Identifier\" &&\n child.object.object.name === \"process\" &&\n child.object.property?.type === \"Identifier\" &&\n child.object.property.name === \"env\"\n ) {\n const envVarName = child.property?.type === \"Identifier\" ? child.property.name : null;\n if (envVarName && !envVarName.startsWith(\"VITE_\")) {\n context.report({\n node: child,\n message: `process.env.${envVarName} in ${keyName} — loaders are isomorphic and may leak secrets to the client. Move to a createServerFn()`,\n });\n }\n }\n });\n }\n },\n }),\n};\n\nexport const tanstackStartGetMutation: Rule = {\n create: (context: RuleContext) => ({\n CallExpression(node: EsTreeNode) {\n if (node.callee?.type !== \"MemberExpression\") return;\n if (node.callee.property?.type !== \"Identifier\" || node.callee.property.name !== \"handler\")\n return;\n\n const chainInfo = walkServerFnChain(node);\n if (!chainInfo.isServerFnChain) return;\n if (\n chainInfo.specifiedMethod &&\n MUTATING_HTTP_METHODS.has(chainInfo.specifiedMethod.toUpperCase())\n )\n return;\n\n const handlerFunction = node.arguments?.[0];\n if (!handlerFunction) return;\n\n const sideEffect = findSideEffect(handlerFunction);\n if (sideEffect) {\n context.report({\n node,\n message: `GET server function has side effects (${sideEffect}) — use createServerFn({ method: 'POST' }) for mutations`,\n });\n }\n },\n }),\n};\n\nexport const tanstackStartRedirectInTryCatch: Rule = {\n create: (context: RuleContext) => {\n let tryBlockDepth = 0;\n let catchClauseDepth = 0;\n\n return {\n TryStatement() {\n tryBlockDepth++;\n },\n \"TryStatement:exit\"() {\n tryBlockDepth--;\n },\n CatchClause() {\n catchClauseDepth++;\n },\n \"CatchClause:exit\"() {\n catchClauseDepth--;\n },\n ThrowStatement(node: EsTreeNode) {\n if (tryBlockDepth === 0) return;\n if (catchClauseDepth > 0) return;\n\n const argument = node.argument;\n if (argument?.type !== \"CallExpression\") return;\n if (argument.callee?.type !== \"Identifier\") return;\n if (!TANSTACK_REDIRECT_FUNCTIONS.has(argument.callee.name)) return;\n\n context.report({\n node,\n message: `throw ${argument.callee.name}() inside try block — the router catches this internally. Move it outside the try block or re-throw in the catch`,\n });\n },\n };\n },\n};\n\nconst hasTopLevelAwait = (statement: EsTreeNode): boolean => {\n if (statement.type === \"VariableDeclaration\") {\n return statement.declarations?.some(\n (declarator: EsTreeNode) => declarator.init?.type === \"AwaitExpression\",\n );\n }\n if (statement.type === \"ExpressionStatement\") {\n return (\n statement.expression?.type === \"AwaitExpression\" ||\n (statement.expression?.type === \"AssignmentExpression\" &&\n statement.expression.right?.type === \"AwaitExpression\")\n );\n }\n if (statement.type === \"ReturnStatement\") {\n return statement.argument?.type === \"AwaitExpression\";\n }\n return false;\n};\n\nexport const tanstackStartLoaderParallelFetch: Rule = {\n create: (context: RuleContext) => ({\n CallExpression(node: EsTreeNode) {\n const optionsObject = getRouteOptionsObject(node);\n if (!optionsObject) return;\n\n const properties = optionsObject.properties ?? [];\n for (const property of properties) {\n const keyName = getPropertyKeyName(property);\n if (keyName !== \"loader\") continue;\n\n const loaderValue = property.value;\n if (\n !loaderValue ||\n (loaderValue.type !== \"ArrowFunctionExpression\" &&\n loaderValue.type !== \"FunctionExpression\")\n )\n continue;\n\n const functionBody = loaderValue.body;\n if (!functionBody || functionBody.type !== \"BlockStatement\") continue;\n\n let sequentialAwaitCount = 0;\n for (const statement of functionBody.body ?? []) {\n if (hasTopLevelAwait(statement)) {\n sequentialAwaitCount++;\n }\n\n if (sequentialAwaitCount >= SEQUENTIAL_AWAIT_THRESHOLD_FOR_LOADER) {\n context.report({\n node: property,\n message:\n \"Multiple sequential awaits in loader — use Promise.all() to fetch data in parallel and avoid waterfalls\",\n });\n break;\n }\n }\n }\n },\n }),\n};\n","import {\n CASCADING_SET_STATE_THRESHOLD,\n EFFECT_HOOK_NAMES,\n HOOKS_WITH_DEPS,\n RELATED_USE_STATE_THRESHOLD,\n TRIVIAL_INITIALIZER_NAMES,\n} from \"../constants.js\";\nimport {\n containsFetchCall,\n countSetStateCalls,\n extractDestructuredPropNames,\n getCallbackStatements,\n getEffectCallback,\n isComponentAssignment,\n isHookCall,\n isSetterCall,\n isSetterIdentifier,\n isUppercaseName,\n walkAst,\n} from \"../helpers.js\";\nimport type { EsTreeNode, Rule, RuleContext } from \"../types.js\";\n\nexport const noDerivedStateEffect: Rule = {\n create: (context: RuleContext) => ({\n CallExpression(node: EsTreeNode) {\n if (!isHookCall(node, EFFECT_HOOK_NAMES) || node.arguments.length < 2) return;\n\n const callback = getEffectCallback(node);\n if (!callback) return;\n\n const depsNode = node.arguments[1];\n if (depsNode.type !== \"ArrayExpression\" || !depsNode.elements?.length) return;\n\n const dependencyNames = new Set(\n depsNode.elements\n .filter((element: EsTreeNode) => element?.type === \"Identifier\")\n .map((element: EsTreeNode) => element.name),\n );\n if (dependencyNames.size === 0) return;\n\n const statements = getCallbackStatements(callback);\n if (statements.length === 0) return;\n\n const containsOnlySetStateCalls = statements.every((statement: EsTreeNode) => {\n if (statement.type !== \"ExpressionStatement\") return false;\n return isSetterCall(statement.expression);\n });\n if (!containsOnlySetStateCalls) return;\n\n let allArgumentsDeriveFromDeps = true;\n let hasAnyDependencyReference = false;\n for (const statement of statements) {\n const setStateArguments = statement.expression.arguments;\n if (!setStateArguments?.length) continue;\n\n const referencedIdentifiers: string[] = [];\n walkAst(setStateArguments[0], (child: EsTreeNode) => {\n if (child.type === \"Identifier\") referencedIdentifiers.push(child.name);\n });\n\n const nonSetterIdentifiers = referencedIdentifiers.filter(\n (name) => !isSetterIdentifier(name),\n );\n\n if (nonSetterIdentifiers.some((name) => dependencyNames.has(name))) {\n hasAnyDependencyReference = true;\n }\n\n if (nonSetterIdentifiers.some((name) => !dependencyNames.has(name))) {\n allArgumentsDeriveFromDeps = false;\n break;\n }\n }\n\n if (allArgumentsDeriveFromDeps) {\n context.report({\n node,\n message: hasAnyDependencyReference\n ? \"Derived state in useEffect — compute during render instead\"\n : \"State reset in useEffect — use a key prop to reset component state when props change\",\n });\n }\n },\n }),\n};\n\nexport const noFetchInEffect: Rule = {\n create: (context: RuleContext) => ({\n CallExpression(node: EsTreeNode) {\n if (!isHookCall(node, EFFECT_HOOK_NAMES)) return;\n const callback = getEffectCallback(node);\n if (!callback) return;\n\n if (containsFetchCall(callback)) {\n context.report({\n node,\n message:\n \"fetch() inside useEffect — use a data fetching library (react-query, SWR) or server component\",\n });\n }\n },\n }),\n};\n\nexport const noCascadingSetState: Rule = {\n create: (context: RuleContext) => ({\n CallExpression(node: EsTreeNode) {\n if (!isHookCall(node, EFFECT_HOOK_NAMES)) return;\n const callback = getEffectCallback(node);\n if (!callback) return;\n\n const setStateCallCount = countSetStateCalls(callback);\n if (setStateCallCount >= CASCADING_SET_STATE_THRESHOLD) {\n context.report({\n node,\n message: `${setStateCallCount} setState calls in a single useEffect — consider using useReducer or deriving state`,\n });\n }\n },\n }),\n};\n\nexport const noEffectEventHandler: Rule = {\n create: (context: RuleContext) => ({\n CallExpression(node: EsTreeNode) {\n if (!isHookCall(node, EFFECT_HOOK_NAMES) || node.arguments.length < 2) return;\n\n const callback = getEffectCallback(node);\n if (!callback) return;\n\n const depsNode = node.arguments[1];\n if (depsNode.type !== \"ArrayExpression\" || !depsNode.elements?.length) return;\n\n const dependencyNames = new Set(\n depsNode.elements\n .filter((element: EsTreeNode) => element?.type === \"Identifier\")\n .map((element: EsTreeNode) => element.name),\n );\n\n const statements = getCallbackStatements(callback);\n if (statements.length !== 1) return;\n\n const soleStatement = statements[0];\n if (\n soleStatement.type === \"IfStatement\" &&\n soleStatement.test?.type === \"Identifier\" &&\n dependencyNames.has(soleStatement.test.name)\n ) {\n context.report({\n node,\n message:\n \"useEffect simulating an event handler — move logic to an actual event handler instead\",\n });\n }\n },\n }),\n};\n\nexport const noDerivedUseState: Rule = {\n create: (context: RuleContext) => {\n const componentPropNames = new Set<string>();\n\n return {\n FunctionDeclaration(node: EsTreeNode) {\n if (!node.id?.name || !isUppercaseName(node.id.name)) return;\n for (const name of extractDestructuredPropNames(node.params ?? [])) {\n componentPropNames.add(name);\n }\n },\n VariableDeclarator(node: EsTreeNode) {\n if (!isComponentAssignment(node)) return;\n for (const name of extractDestructuredPropNames(node.init?.params ?? [])) {\n componentPropNames.add(name);\n }\n },\n CallExpression(node: EsTreeNode) {\n if (!isHookCall(node, \"useState\") || !node.arguments?.length) return;\n const initializer = node.arguments[0];\n if (initializer.type !== \"Identifier\") return;\n\n if (componentPropNames.has(initializer.name)) {\n context.report({\n node,\n message: `useState initialized from prop \"${initializer.name}\" — if this value should stay in sync with the prop, derive it during render instead`,\n });\n }\n },\n };\n },\n};\n\nexport const preferUseReducer: Rule = {\n create: (context: RuleContext) => {\n const reportExcessiveUseState = (body: EsTreeNode, componentName: string): void => {\n if (body.type !== \"BlockStatement\") return;\n let useStateCount = 0;\n for (const statement of body.body ?? []) {\n if (statement.type !== \"VariableDeclaration\") continue;\n for (const declarator of statement.declarations ?? []) {\n if (isHookCall(declarator.init, \"useState\")) useStateCount++;\n }\n }\n if (useStateCount >= RELATED_USE_STATE_THRESHOLD) {\n context.report({\n node: body,\n message: `Component \"${componentName}\" has ${useStateCount} useState calls — consider useReducer for related state`,\n });\n }\n };\n\n return {\n FunctionDeclaration(node: EsTreeNode) {\n if (!node.id?.name || !isUppercaseName(node.id.name)) return;\n reportExcessiveUseState(node.body, node.id.name);\n },\n VariableDeclarator(node: EsTreeNode) {\n if (!isComponentAssignment(node)) return;\n reportExcessiveUseState(node.init.body, node.id.name);\n },\n };\n },\n};\n\nexport const rerenderLazyStateInit: Rule = {\n create: (context: RuleContext) => ({\n CallExpression(node: EsTreeNode) {\n if (!isHookCall(node, \"useState\") || !node.arguments?.length) return;\n const initializer = node.arguments[0];\n if (initializer.type !== \"CallExpression\") return;\n\n const calleeName =\n initializer.callee?.type === \"Identifier\"\n ? initializer.callee.name\n : (initializer.callee?.property?.name ?? \"fn\");\n\n if (TRIVIAL_INITIALIZER_NAMES.has(calleeName)) return;\n\n context.report({\n node: initializer,\n message: `useState(${calleeName}()) calls initializer on every render — use useState(() => ${calleeName}()) for lazy initialization`,\n });\n },\n }),\n};\n\nexport const rerenderFunctionalSetstate: Rule = {\n create: (context: RuleContext) => ({\n CallExpression(node: EsTreeNode) {\n if (!isSetterCall(node)) return;\n if (!node.arguments?.length) return;\n\n const calleeName = node.callee.name;\n const argument = node.arguments[0];\n if (\n argument.type === \"BinaryExpression\" &&\n (argument.operator === \"+\" || argument.operator === \"-\") &&\n argument.left?.type === \"Identifier\"\n ) {\n context.report({\n node,\n message: `${calleeName}(${argument.left.name} ${argument.operator} ...) — use functional update to avoid stale closures`,\n });\n }\n },\n }),\n};\n\nexport const rerenderDependencies: Rule = {\n create: (context: RuleContext) => ({\n CallExpression(node: EsTreeNode) {\n if (!isHookCall(node, HOOKS_WITH_DEPS) || node.arguments.length < 2) return;\n const depsNode = node.arguments[1];\n if (depsNode.type !== \"ArrayExpression\") return;\n\n for (const element of depsNode.elements ?? []) {\n if (!element) continue;\n if (element.type === \"ObjectExpression\") {\n context.report({\n node: element,\n message:\n \"Object literal in useEffect deps — creates new reference every render, causing infinite re-runs\",\n });\n }\n if (element.type === \"ArrayExpression\") {\n context.report({\n node: element,\n message:\n \"Array literal in useEffect deps — creates new reference every render, causing infinite re-runs\",\n });\n }\n }\n },\n }),\n};\n","import {\n noGiantComponent,\n noNestedComponentDefinition,\n noRenderInRender,\n} from \"./rules/architecture.js\";\nimport {\n noBarrelImport,\n noFullLodashImport,\n noMoment,\n noUndeferredThirdParty,\n preferDynamicImport,\n useLazyMotion,\n} from \"./rules/bundle-size.js\";\nimport { clientPassiveEventListeners } from \"./rules/client.js\";\nimport {\n noDarkModeGlow,\n noDisabledZoom,\n noGradientText,\n noGrayOnColoredBackground,\n noInlineBounceEasing,\n noInlineExhaustiveStyle,\n noJustifiedText,\n noLayoutTransitionInline,\n noLongTransitionDuration,\n noOutlineNone,\n noPureBlackBackground,\n noSideTabBorder,\n noTinyText,\n noWideLetterSpacing,\n noZIndex9999,\n} from \"./rules/design.js\";\nimport {\n noArrayIndexAsKey,\n noPreventDefault,\n renderingConditionalRender,\n} from \"./rules/correctness.js\";\nimport {\n asyncParallel,\n jsBatchDomCss,\n jsCacheStorage,\n jsCombineIterations,\n jsEarlyExit,\n jsHoistRegexp,\n jsIndexMaps,\n jsMinMaxLoop,\n jsSetMapLookups,\n jsTosortedImmutable,\n jsFlatmapFilter,\n} from \"./rules/js-performance.js\";\nimport {\n nextjsAsyncClientComponent,\n nextjsImageMissingSizes,\n nextjsInlineScriptMissingId,\n nextjsMissingMetadata,\n nextjsNoAElement,\n nextjsNoClientFetchForServerData,\n nextjsNoClientSideRedirect,\n nextjsNoCssLink,\n nextjsNoFontLink,\n nextjsNoHeadImport,\n nextjsNoImgElement,\n nextjsNoNativeScript,\n nextjsNoPolyfillScript,\n nextjsNoRedirectInTryCatch,\n nextjsNoSideEffectInGetHandler,\n nextjsNoUseSearchParamsWithoutSuspense,\n} from \"./rules/nextjs.js\";\nimport {\n noGlobalCssVariableAnimation,\n noLargeAnimatedBlur,\n noLayoutPropertyAnimation,\n noPermanentWillChange,\n noScaleFromZero,\n noTransitionAll,\n noUsememoSimpleExpression,\n renderingAnimateSvgWrapper,\n noInlinePropOnMemoComponent,\n renderingHydrationNoFlicker,\n renderingScriptDeferAsync,\n rerenderMemoWithDefaultValue,\n} from \"./rules/performance.js\";\nimport {\n rnNoRawText,\n rnNoDeprecatedModules,\n rnNoLegacyExpoPackages,\n rnNoDimensionsGet,\n rnNoInlineFlatlistRenderitem,\n rnNoLegacyShadowStyles,\n rnPreferReanimated,\n rnNoSingleElementStyleArray,\n} from \"./rules/react-native.js\";\nimport {\n queryMutationMissingInvalidation,\n queryNoQueryInEffect,\n queryNoRestDestructuring,\n queryNoUseQueryForMutation,\n queryNoVoidQueryFn,\n queryStableQueryClient,\n} from \"./rules/tanstack-query.js\";\nimport { noEval, noSecretsInClientCode } from \"./rules/security.js\";\nimport { serverAfterNonblocking, serverAuthActions } from \"./rules/server.js\";\nimport {\n tanstackStartGetMutation,\n tanstackStartLoaderParallelFetch,\n tanstackStartMissingHeadContent,\n tanstackStartNoAnchorElement,\n tanstackStartNoDirectFetchInLoader,\n tanstackStartNoDynamicServerFnImport,\n tanstackStartNoNavigateInRender,\n tanstackStartNoSecretsInLoader,\n tanstackStartNoUseEffectFetch,\n tanstackStartNoUseServerInHandler,\n tanstackStartRedirectInTryCatch,\n tanstackStartRoutePropertyOrder,\n tanstackStartServerFnMethodOrder,\n tanstackStartServerFnValidateInput,\n} from \"./rules/tanstack-start.js\";\nimport {\n noCascadingSetState,\n noDerivedStateEffect,\n noDerivedUseState,\n noEffectEventHandler,\n noFetchInEffect,\n preferUseReducer,\n rerenderDependencies,\n rerenderFunctionalSetstate,\n rerenderLazyStateInit,\n} from \"./rules/state-and-effects.js\";\nimport type { RulePlugin } from \"./types.js\";\n\nconst plugin: RulePlugin = {\n meta: { name: \"react-doctor\" },\n rules: {\n \"no-derived-state-effect\": noDerivedStateEffect,\n \"no-fetch-in-effect\": noFetchInEffect,\n \"no-cascading-set-state\": noCascadingSetState,\n \"no-effect-event-handler\": noEffectEventHandler,\n \"no-derived-useState\": noDerivedUseState,\n \"prefer-useReducer\": preferUseReducer,\n \"rerender-lazy-state-init\": rerenderLazyStateInit,\n \"rerender-functional-setstate\": rerenderFunctionalSetstate,\n \"rerender-dependencies\": rerenderDependencies,\n\n \"no-giant-component\": noGiantComponent,\n \"no-render-in-render\": noRenderInRender,\n \"no-nested-component-definition\": noNestedComponentDefinition,\n\n \"no-usememo-simple-expression\": noUsememoSimpleExpression,\n \"no-layout-property-animation\": noLayoutPropertyAnimation,\n \"rerender-memo-with-default-value\": rerenderMemoWithDefaultValue,\n \"rendering-animate-svg-wrapper\": renderingAnimateSvgWrapper,\n \"no-inline-prop-on-memo-component\": noInlinePropOnMemoComponent,\n \"rendering-hydration-no-flicker\": renderingHydrationNoFlicker,\n \"rendering-script-defer-async\": renderingScriptDeferAsync,\n\n \"no-transition-all\": noTransitionAll,\n \"no-global-css-variable-animation\": noGlobalCssVariableAnimation,\n \"no-large-animated-blur\": noLargeAnimatedBlur,\n \"no-scale-from-zero\": noScaleFromZero,\n \"no-permanent-will-change\": noPermanentWillChange,\n\n \"no-eval\": noEval,\n \"no-secrets-in-client-code\": noSecretsInClientCode,\n\n \"no-barrel-import\": noBarrelImport,\n \"no-full-lodash-import\": noFullLodashImport,\n \"no-moment\": noMoment,\n \"prefer-dynamic-import\": preferDynamicImport,\n \"use-lazy-motion\": useLazyMotion,\n \"no-undeferred-third-party\": noUndeferredThirdParty,\n\n \"no-array-index-as-key\": noArrayIndexAsKey,\n \"rendering-conditional-render\": renderingConditionalRender,\n \"no-prevent-default\": noPreventDefault,\n\n \"nextjs-no-img-element\": nextjsNoImgElement,\n \"nextjs-async-client-component\": nextjsAsyncClientComponent,\n \"nextjs-no-a-element\": nextjsNoAElement,\n \"nextjs-no-use-search-params-without-suspense\": nextjsNoUseSearchParamsWithoutSuspense,\n \"nextjs-no-client-fetch-for-server-data\": nextjsNoClientFetchForServerData,\n \"nextjs-missing-metadata\": nextjsMissingMetadata,\n \"nextjs-no-client-side-redirect\": nextjsNoClientSideRedirect,\n \"nextjs-no-redirect-in-try-catch\": nextjsNoRedirectInTryCatch,\n \"nextjs-image-missing-sizes\": nextjsImageMissingSizes,\n \"nextjs-no-native-script\": nextjsNoNativeScript,\n \"nextjs-inline-script-missing-id\": nextjsInlineScriptMissingId,\n \"nextjs-no-font-link\": nextjsNoFontLink,\n \"nextjs-no-css-link\": nextjsNoCssLink,\n \"nextjs-no-polyfill-script\": nextjsNoPolyfillScript,\n \"nextjs-no-head-import\": nextjsNoHeadImport,\n \"nextjs-no-side-effect-in-get-handler\": nextjsNoSideEffectInGetHandler,\n\n \"server-auth-actions\": serverAuthActions,\n \"server-after-nonblocking\": serverAfterNonblocking,\n\n \"client-passive-event-listeners\": clientPassiveEventListeners,\n\n \"js-combine-iterations\": jsCombineIterations,\n \"js-tosorted-immutable\": jsTosortedImmutable,\n \"js-hoist-regexp\": jsHoistRegexp,\n \"js-min-max-loop\": jsMinMaxLoop,\n \"js-set-map-lookups\": jsSetMapLookups,\n \"js-batch-dom-css\": jsBatchDomCss,\n \"js-index-maps\": jsIndexMaps,\n \"js-cache-storage\": jsCacheStorage,\n \"js-early-exit\": jsEarlyExit,\n \"js-flatmap-filter\": jsFlatmapFilter,\n \"async-parallel\": asyncParallel,\n\n \"rn-no-raw-text\": rnNoRawText,\n \"rn-no-deprecated-modules\": rnNoDeprecatedModules,\n \"rn-no-legacy-expo-packages\": rnNoLegacyExpoPackages,\n \"rn-no-dimensions-get\": rnNoDimensionsGet,\n \"rn-no-inline-flatlist-renderitem\": rnNoInlineFlatlistRenderitem,\n \"rn-no-legacy-shadow-styles\": rnNoLegacyShadowStyles,\n \"rn-prefer-reanimated\": rnPreferReanimated,\n \"rn-no-single-element-style-array\": rnNoSingleElementStyleArray,\n\n \"tanstack-start-route-property-order\": tanstackStartRoutePropertyOrder,\n \"tanstack-start-no-direct-fetch-in-loader\": tanstackStartNoDirectFetchInLoader,\n \"tanstack-start-server-fn-validate-input\": tanstackStartServerFnValidateInput,\n \"tanstack-start-no-useeffect-fetch\": tanstackStartNoUseEffectFetch,\n \"tanstack-start-missing-head-content\": tanstackStartMissingHeadContent,\n \"tanstack-start-no-anchor-element\": tanstackStartNoAnchorElement,\n \"tanstack-start-server-fn-method-order\": tanstackStartServerFnMethodOrder,\n \"tanstack-start-no-navigate-in-render\": tanstackStartNoNavigateInRender,\n \"tanstack-start-no-dynamic-server-fn-import\": tanstackStartNoDynamicServerFnImport,\n \"tanstack-start-no-use-server-in-handler\": tanstackStartNoUseServerInHandler,\n \"tanstack-start-no-secrets-in-loader\": tanstackStartNoSecretsInLoader,\n \"tanstack-start-get-mutation\": tanstackStartGetMutation,\n \"tanstack-start-redirect-in-try-catch\": tanstackStartRedirectInTryCatch,\n \"tanstack-start-loader-parallel-fetch\": tanstackStartLoaderParallelFetch,\n\n \"query-stable-query-client\": queryStableQueryClient,\n \"query-no-rest-destructuring\": queryNoRestDestructuring,\n \"query-no-void-query-fn\": queryNoVoidQueryFn,\n \"query-no-query-in-effect\": queryNoQueryInEffect,\n \"query-mutation-missing-invalidation\": queryMutationMissingInvalidation,\n \"query-no-usequery-for-mutation\": queryNoUseQueryForMutation,\n\n \"no-inline-bounce-easing\": noInlineBounceEasing,\n \"no-z-index-9999\": noZIndex9999,\n \"no-inline-exhaustive-style\": noInlineExhaustiveStyle,\n \"no-side-tab-border\": noSideTabBorder,\n \"no-pure-black-background\": noPureBlackBackground,\n \"no-gradient-text\": noGradientText,\n \"no-dark-mode-glow\": noDarkModeGlow,\n \"no-justified-text\": noJustifiedText,\n \"no-tiny-text\": noTinyText,\n \"no-wide-letter-spacing\": noWideLetterSpacing,\n \"no-gray-on-colored-background\": noGrayOnColoredBackground,\n \"no-layout-transition-inline\": noLayoutTransitionInline,\n \"no-disabled-zoom\": noDisabledZoom,\n \"no-outline-none\": noOutlineNone,\n \"no-long-transition-duration\": noLongTransitionDuration,\n },\n};\n\nexport default plugin;\n"],"mappings":";AASA,MAAa,oBAAoB,IAAI,IAAI;CACvC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;AAEF,MAAa,uBAAuB,IAAI,IAAI;CAC1C;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;AAEF,MAAa,kBAAkB,IAAI,IAAI;CACrC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;AAEF,MAAa,qBAAqB,IAAI,IAAI,CAAC,QAAQ,CAAC;AACpD,MAAa,uBAAuB,IAAI,IAAI;CAAC;CAAS;CAAM;CAAM,CAAC;AACnE,MAAa,wBAAwB,IAAI,IAAI;CAAC;CAAS;CAAO;CAAI,CAAC;AACnE,MAAa,wBAAwB;CACnC;CACA;CACA;CACA;CACA;CACD;AACD,MAAa,sBAAsB,IAAI,IAAI;CACzC;CACA;CACA;CACA;CACA;CACD,CAAC;AAEF,MAAa,aAAa;CACxB;CACA;CACA;CACA;CACA;CACD;AAED,MAAa,sBAAsB,IAAI,IAAI;CACzC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;AAEF,MAAa,kBAAkB;CAC7B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;AAED,MAAa,0BAA0B;AAEvC,MAAa,iCAAiC,IAAI,IAAI;CACpD;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;AAIF,MAAa,8BAA8B;AAC3C,MAAa,mCAAmC;AAEhD,MAAa,gCAAgC;CAC3C;CACA;CACA;CACA;CAC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"}
|