@geoql/doctor-rule-core 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["DOCS_URL","WHOLE_MESSAGE","SPECIFIER_MESSAGE","isAutoImportedValueSpecifier","MESSAGE","MESSAGE","MESSAGE","MESSAGE","MESSAGE","calleeName","MESSAGE","MESSAGE","MESSAGE","MESSAGE","isFunction","MESSAGE","coreRule","MESSAGE","calleeName","isToRefsCall","MESSAGE","calleeName","MESSAGE","calleeName","MESSAGE","calleeName","MESSAGE","MESSAGE","MESSAGE","calleeName","MESSAGE","calleeName","MESSAGE","MESSAGE","stringValue","MESSAGE","MESSAGE"],"sources":["../src/define-rule.ts","../src/shared/auto-imported-symbols.ts","../src/rules/nuxt/ai-slop/no-explicit-imports-of-auto-imported.ts","../src/rules/nuxt/ai-slop/no-fetch-in-setup.ts","../src/rules/nuxt/ai-slop/no-process-client-server.ts","../src/rules/nuxt/ai-slop/no-useState-for-server-data.ts","../src/rules/nuxt/data-fetching/useAsyncData-key-required-in-loop.ts","../src/rules/nuxt/security/no-user-input-in-fetch-url.ts","../src/rules/nuxt/hydration/clientOnly-for-browser-apis.ts","../src/rules/nuxt/hydration/no-document-in-setup.ts","../src/rules/nuxt/server-routes/createError-on-failure.ts","../src/rules/nuxt/server-routes/defineEventHandler-typed.ts","../src/rules/nuxt/server-routes/validate-body-with-h3-v2.ts","../src/rules/nuxt/index.ts","../src/rules/vue/ai-slop/no-destructure-props-without-toRefs.ts","../src/rules/vue/ai-slop/no-destructure-reactive-without-toRefs.ts","../src/rules/vue/ai-slop/no-em-dash-in-string.ts","../src/rules/vue/ai-slop/no-imports-from-vue-when-auto-imported.ts","../src/rules/vue/ai-slop/no-non-null-assertion-on-ref-value.ts","../src/rules/vue/composition/defineProps-typed.ts","../src/rules/vue/composition/prefer-script-setup-for-new-files.ts","../src/rules/vue/performance/prefer-defineAsyncComponent-on-route.ts","../src/rules/vue/reactivity/prefer-readonly-for-injected.ts","../src/rules/vue/reactivity/prefer-shallowRef-for-large-data.ts","../src/rules/vue/reactivity/watch-without-cleanup.ts","../src/rules/vue/security/no-auth-token-in-web-storage.ts","../src/rules/vue/security/no-eval-like.ts","../src/rules/vue/security/no-inner-html.ts","../src/rules/vue/security/no-secrets-in-source.ts","../src/rules/vue/index.ts"],"sourcesContent":["import type { Rule, RuleContext } from './types.js';\n\nexport function defineRule(rule: Rule): Rule {\n const userFix = rule.fix;\n if (!userFix) return rule;\n return {\n ...rule,\n meta: { ...rule.meta, fixable: 'code' },\n create(context: RuleContext) {\n const wrapped: RuleContext = {\n ...context,\n report(descriptor) {\n const replacement = userFix(descriptor.node);\n if (replacement === null) {\n context.report(descriptor);\n return;\n }\n context.report({\n ...descriptor,\n fix: (fixer) => fixer.replaceText(descriptor.node, replacement),\n });\n },\n };\n return rule.create(wrapped);\n },\n };\n}\n","export const VUE_AUTO_IMPORTED: ReadonlySet<string> = new Set([\n 'ref',\n 'shallowRef',\n 'computed',\n 'reactive',\n 'shallowReactive',\n 'readonly',\n 'shallowReadonly',\n 'toRef',\n 'toRefs',\n 'isRef',\n 'isReactive',\n 'isReadonly',\n 'isProxy',\n 'unref',\n 'triggerRef',\n 'customRef',\n 'markRaw',\n 'toRaw',\n 'watch',\n 'watchEffect',\n 'watchPostEffect',\n 'watchSyncEffect',\n 'effectScope',\n 'getCurrentScope',\n 'onScopeDispose',\n 'onMounted',\n 'onUpdated',\n 'onUnmounted',\n 'onBeforeMount',\n 'onBeforeUpdate',\n 'onBeforeUnmount',\n 'onErrorCaptured',\n 'onRenderTracked',\n 'onRenderTriggered',\n 'onActivated',\n 'onDeactivated',\n 'onServerPrefetch',\n 'provide',\n 'inject',\n 'hasInjectionContext',\n 'getCurrentInstance',\n 'nextTick',\n 'defineComponent',\n 'defineAsyncComponent',\n 'useTemplateRef',\n 'useId',\n 'useModel',\n]);\n\nexport const NUXT_AUTO_IMPORTED: ReadonlySet<string> = new Set([\n ...VUE_AUTO_IMPORTED,\n 'useRoute',\n 'useRouter',\n 'useFetch',\n 'useAsyncData',\n 'useState',\n 'useRuntimeConfig',\n 'useNuxtApp',\n 'navigateTo',\n 'definePageMeta',\n 'useSeoMeta',\n 'useHead',\n]);\n","import { defineRule } from '../../../define-rule.js';\nimport type { AstNode, RuleContext } from '../../../types.js';\nimport { NUXT_AUTO_IMPORTED } from '../../../shared/auto-imported-symbols.js';\n\nconst DOCS_URL = 'https://nuxt.com/docs/4.x/guide/concepts/auto-imports';\nconst WHOLE_MESSAGE = `These symbols are auto-imported in Nuxt projects. Remove the import entirely. See ${DOCS_URL}`;\nconst SPECIFIER_MESSAGE = `This symbol is auto-imported in Nuxt projects. Remove it from the import — it is dead weight. See ${DOCS_URL}`;\n\nconst AUTO_IMPORT_SOURCES = new Set(['vue', '#imports', 'vue-router', '#app']);\n\nfunction isAutoImportedValueSpecifier(spec: AstNode): boolean {\n if (spec.importKind === 'type') return false;\n const imported = spec.imported as AstNode;\n return NUXT_AUTO_IMPORTED.has(imported.name as string);\n}\n\nexport const noExplicitImportsOfAutoImported = defineRule({\n create(context: RuleContext) {\n return {\n ImportDeclaration(node: AstNode) {\n if (node.importKind === 'type') return;\n const source = node.source as AstNode;\n if (!AUTO_IMPORT_SOURCES.has(source.value as string)) return;\n const specifiers = node.specifiers as AstNode[];\n const named = specifiers.filter((s) => s.type === 'ImportSpecifier');\n if (named.length === 0) return;\n const offending = named.filter(isAutoImportedValueSpecifier);\n if (offending.length === 0) return;\n if (\n offending.length === named.length &&\n specifiers.length === named.length\n ) {\n context.report({ node, message: WHOLE_MESSAGE });\n return;\n }\n for (const spec of offending) {\n context.report({ node: spec, message: SPECIFIER_MESSAGE });\n }\n },\n };\n },\n});\n","import { defineRule } from '../../../define-rule.js';\nimport type { AstNode, RuleContext } from '../../../types.js';\n\nconst DOCS_URL = 'https://nuxt.com/docs/4.x/guide/data-fetching';\nconst MESSAGE = `Bare $fetch/fetch at the top level of <script setup> runs on both server and client without SSR deduplication. Use useFetch for automatic request deduplication and SSR hydration. See ${DOCS_URL}`;\n\nfunction isFetchCall(node: AstNode | undefined): boolean {\n if (!node || node.type !== 'CallExpression') return false;\n const callee = node.callee as AstNode | undefined;\n if (callee?.type === 'Identifier') {\n const name = callee.name as string;\n return name === '$fetch' || name === 'fetch';\n }\n return false;\n}\n\nexport const noFetchInSetup = defineRule({\n create(context: RuleContext) {\n const functionDepthStack: number[] = [];\n\n return {\n ArrowFunctionExpression() {\n functionDepthStack.push(\n functionDepthStack.length > 0\n ? functionDepthStack[functionDepthStack.length - 1]! + 1\n : 1,\n );\n },\n 'ArrowFunctionExpression:exit'() {\n functionDepthStack.pop();\n },\n FunctionExpression() {\n functionDepthStack.push(\n functionDepthStack.length > 0\n ? functionDepthStack[functionDepthStack.length - 1]! + 1\n : 1,\n );\n },\n 'FunctionExpression:exit'() {\n functionDepthStack.pop();\n },\n FunctionDeclaration() {\n functionDepthStack.push(\n functionDepthStack.length > 0\n ? functionDepthStack[functionDepthStack.length - 1]! + 1\n : 1,\n );\n },\n 'FunctionDeclaration:exit'() {\n functionDepthStack.pop();\n },\n CallExpression(node: AstNode) {\n if (functionDepthStack.length > 0) return;\n if (!isFetchCall(node)) return;\n const parent = (node as Record<string, unknown>)['parent'] as\n | AstNode\n | undefined;\n if (parent?.type === 'AwaitExpression') return;\n context.report({ node, message: MESSAGE });\n },\n AwaitExpression(node: AstNode) {\n if (functionDepthStack.length > 0) return;\n if (!isFetchCall(node.argument as AstNode | undefined)) return;\n context.report({ node, message: MESSAGE });\n },\n };\n },\n});\n","import { defineRule } from '../../../define-rule.js';\nimport type { AstNode, RuleContext } from '../../../types.js';\n\nconst LEGACY_PROPS = new Set(['client', 'server', 'browser']);\nconst DOCS_URL = 'https://nuxt.com/docs/4.x/guide/concepts/auto-imports';\nconst MESSAGE = `Use import.meta.client / import.meta.server / import.meta.browser instead of process.client / process.server / process.browser (Nuxt 4). See ${DOCS_URL}`;\n\nexport const noProcessClientServer = defineRule({\n create(context: RuleContext) {\n return {\n MemberExpression(node: AstNode) {\n const object = node.object as AstNode | undefined;\n if (object?.type !== 'Identifier') return;\n if ((object as AstNode & { name: string }).name !== 'process') return;\n const property = node.property as AstNode | undefined;\n if (property?.type !== 'Identifier') return;\n if (!LEGACY_PROPS.has(property.name as string)) return;\n context.report({ node, message: MESSAGE });\n },\n };\n },\n fix(node: AstNode) {\n const object = node.object as AstNode | undefined;\n if (object?.type !== 'Identifier') return null;\n if ((object as AstNode & { name: string }).name !== 'process') return null;\n const property = node.property as AstNode | undefined;\n if (property?.type !== 'Identifier') return null;\n const name = property.name as string;\n if (!LEGACY_PROPS.has(name)) return null;\n return `import.meta.${name}`;\n },\n});\n","import { defineRule } from '../../../define-rule.js';\nimport type { AstNode, RuleContext } from '../../../types.js';\n\nconst DOCS_URL = 'https://nuxt.com/docs/4.x/guide/data-fetching';\nconst MESSAGE = `useState with a fetch/await initializer suggests useFetch or useAsyncData for automatic SSR hydration and request deduplication. See ${DOCS_URL}`;\n\nfunction containsFetchOrAwait(\n node: AstNode | undefined,\n visited: Set<unknown>,\n): boolean {\n if (!node || visited.has(node)) return false;\n visited.add(node);\n if (node.type === 'AwaitExpression') return true;\n if (node.type === 'CallExpression') {\n const callee = node.callee as AstNode | undefined;\n if (callee?.type === 'Identifier') {\n const name = callee.name as string;\n if (name === '$fetch' || name === 'fetch') return true;\n }\n }\n for (const key of Object.keys(node)) {\n if (key === 'type' || key === 'loc' || key === 'range') continue;\n const value = (node as Record<string, unknown>)[key];\n if (Array.isArray(value)) {\n for (const child of value) {\n if (child && typeof child === 'object' && 'type' in child) {\n if (containsFetchOrAwait(child as AstNode, visited)) return true;\n }\n }\n } else if (value && typeof value === 'object' && 'type' in value) {\n if (containsFetchOrAwait(value as AstNode, visited)) return true;\n }\n }\n return false;\n}\n\nexport const noUseStateForServerData = defineRule({\n create(context: RuleContext) {\n return {\n CallExpression(node: AstNode) {\n const callee = node.callee as AstNode | undefined;\n if (callee?.type !== 'Identifier') return;\n if ((callee as AstNode & { name: string }).name !== 'useState') return;\n const args = node.arguments as AstNode[];\n if (args.length < 2) return;\n const initFn = args[1];\n if (\n initFn.type !== 'ArrowFunctionExpression' &&\n initFn.type !== 'FunctionExpression'\n )\n return;\n if (!containsFetchOrAwait(initFn.body as AstNode, new Set())) return;\n context.report({ node, message: MESSAGE });\n },\n };\n },\n});\n","import { defineRule } from '../../../define-rule.js';\nimport type { AstNode, RuleContext } from '../../../types.js';\n\nconst DOCS_URL = 'https://nuxt.com/docs/4.x/guide/data-fetching';\nconst MESSAGE = `useAsyncData/useFetch without an explicit string key inside a loop causes duplicate requests and cache fragmentation. Pass a unique string key as the first argument. See ${DOCS_URL}`;\n\nconst DATA_FETCHERS = new Set(['useAsyncData', 'useFetch']);\n\nfunction isMapCall(node: AstNode): boolean {\n const callee = node.callee as AstNode | undefined;\n if (callee?.type === 'Identifier') return callee.name === 'map';\n if (callee?.type === 'MemberExpression') {\n const prop = (callee as AstNode & { property?: AstNode }).property as\n | AstNode\n | undefined;\n return (\n prop?.type === 'Identifier' &&\n (prop as AstNode & { name: string }).name === 'map'\n );\n }\n return false;\n}\n\nexport const useAsyncDataKeyRequiredInLoop = defineRule({\n create(context: RuleContext) {\n let loopDepth = 0;\n\n return {\n ForStatement() {\n loopDepth++;\n },\n 'ForStatement:exit'() {\n loopDepth--;\n },\n ForOfStatement() {\n loopDepth++;\n },\n 'ForOfStatement:exit'() {\n loopDepth--;\n },\n ForInStatement() {\n loopDepth++;\n },\n 'ForInStatement:exit'() {\n loopDepth--;\n },\n WhileStatement() {\n loopDepth++;\n },\n 'WhileStatement:exit'() {\n loopDepth--;\n },\n CallExpression(node: AstNode) {\n if (isMapCall(node)) {\n loopDepth++;\n return;\n }\n if (loopDepth === 0) return;\n const callee = node.callee as AstNode | undefined;\n if (callee?.type !== 'Identifier') return;\n if (!DATA_FETCHERS.has(callee.name as string)) return;\n const args = node.arguments as AstNode[];\n if (args.length === 0) return;\n const firstArg = args[0];\n if (firstArg.type === 'Literal' && typeof firstArg.value === 'string')\n return;\n context.report({ node, message: MESSAGE });\n },\n 'CallExpression:exit'(node: AstNode) {\n if (isMapCall(node)) {\n loopDepth--;\n }\n },\n };\n },\n});\n","import { defineRule } from '../../../define-rule.js';\nimport type { AstNode, RuleContext } from '../../../types.js';\n\nconst DOCS_URL =\n 'https://owasp.org/www-community/attacks/Server_Side_Request_Forgery';\nconst MESSAGE = `Building a useFetch/$fetch URL from user input (route.query/route.params) lets an attacker control the request target — an SSRF risk during SSR. Use a fixed path and pass user input via the query/body options instead. See ${DOCS_URL}`;\n\nconst FETCH_CALLEES = new Set([\n 'useFetch',\n 'useLazyFetch',\n 'useAsyncData',\n 'useLazyAsyncData',\n '$fetch',\n]);\n\nconst USER_INPUT_ROOTS = new Set(['route', 'useRoute']);\nconst USER_INPUT_SEGMENTS = new Set(['query', 'params']);\n\nfunction calleeName(node: AstNode): string | undefined {\n const callee = node.callee as AstNode | undefined;\n if (callee?.type === 'Identifier') return callee.name as string;\n return undefined;\n}\n\n/** True when the expression reads from route.query.* or route.params.*. */\nfunction readsUserInput(node: AstNode): boolean {\n if (node.type !== 'MemberExpression') return false;\n const object = node.object as AstNode;\n const property = node.property as AstNode;\n if (\n object.type === 'Identifier' &&\n USER_INPUT_ROOTS.has(object.name as string) &&\n property.type === 'Identifier' &&\n USER_INPUT_SEGMENTS.has(property.name as string)\n ) {\n return true;\n }\n return readsUserInput(object);\n}\n\nfunction templateReadsUserInput(node: AstNode): boolean {\n const expressions = node.expressions as AstNode[];\n return expressions.some((expr) => readsUserInput(expr));\n}\n\nfunction urlArgIsTainted(arg: AstNode | undefined): boolean {\n if (!arg) return false;\n if (arg.type === 'TemplateLiteral') return templateReadsUserInput(arg);\n if (arg.type === 'MemberExpression') return readsUserInput(arg);\n return false;\n}\n\nexport const noUserInputInFetchUrl = defineRule({\n create(context: RuleContext) {\n return {\n CallExpression(node: AstNode) {\n const name = calleeName(node);\n if (name === undefined || !FETCH_CALLEES.has(name)) return;\n const urlArg = (node.arguments as AstNode[])[0];\n if (urlArgIsTainted(urlArg)) {\n context.report({ node, message: MESSAGE });\n }\n },\n };\n },\n});\n","import { defineRule } from '../../../define-rule.js';\nimport type { AstNode, RuleContext } from '../../../types.js';\n\nconst DOCS_URL = 'https://nuxt.com/docs/4.x/guide/components';\nconst MESSAGE = `Accessing window./document./navigator./localStorage./sessionStorage. without an import.meta.client or process.client guard causes SSR failures. Wrap with if (import.meta.client) { ... } or move to onMounted. See ${DOCS_URL}`;\n\nconst BROWSER_GLOBALS = new Set([\n 'window',\n 'document',\n 'navigator',\n 'localStorage',\n 'sessionStorage',\n]);\n\nfunction isImportMetaClientGuard(node: AstNode | undefined): boolean {\n if (!node || node.type !== 'MemberExpression') return false;\n const obj = node.object as AstNode | undefined;\n if (obj?.type !== 'MetaProperty') return false;\n const meta = obj.meta as AstNode | undefined;\n const prop = obj.property as AstNode | undefined;\n if (meta?.type !== 'Identifier') return false;\n if ((meta as AstNode & { name: string }).name !== 'import') return false;\n if (prop?.type !== 'Identifier') return false;\n if ((prop as AstNode & { name: string }).name !== 'meta') return false;\n const property = node.property as AstNode | undefined;\n if (property?.type !== 'Identifier') return false;\n return (property as AstNode & { name: string }).name === 'client';\n}\n\nfunction isProcessClientGuard(node: AstNode | undefined): boolean {\n if (!node || node.type !== 'MemberExpression') return false;\n const obj = node.object as AstNode | undefined;\n if (obj?.type !== 'Identifier') return false;\n if ((obj as AstNode & { name: string }).name !== 'process') return false;\n const property = node.property as AstNode | undefined;\n if (property?.type !== 'Identifier') return false;\n return (property as AstNode & { name: string }).name === 'client';\n}\n\nexport const clientOnlyForBrowserApis = defineRule({\n create(context: RuleContext) {\n const functionDepthStack: number[] = [];\n let isGuarded = false;\n\n return {\n ArrowFunctionExpression() {\n functionDepthStack.push(\n functionDepthStack.length > 0\n ? functionDepthStack[functionDepthStack.length - 1]! + 1\n : 1,\n );\n },\n 'ArrowFunctionExpression:exit'() {\n functionDepthStack.pop();\n },\n FunctionExpression() {\n functionDepthStack.push(\n functionDepthStack.length > 0\n ? functionDepthStack[functionDepthStack.length - 1]! + 1\n : 1,\n );\n },\n 'FunctionExpression:exit'() {\n functionDepthStack.pop();\n },\n FunctionDeclaration() {\n functionDepthStack.push(\n functionDepthStack.length > 0\n ? functionDepthStack[functionDepthStack.length - 1]! + 1\n : 1,\n );\n },\n 'FunctionDeclaration:exit'() {\n functionDepthStack.pop();\n },\n IfStatement(node: AstNode) {\n if (functionDepthStack.length > 0) return;\n const test = node.test as AstNode | undefined;\n if (isImportMetaClientGuard(test) || isProcessClientGuard(test)) {\n isGuarded = true;\n }\n },\n 'IfStatement:exit'(node: AstNode) {\n if (functionDepthStack.length > 0) return;\n const test = node.test as AstNode | undefined;\n if (isImportMetaClientGuard(test) || isProcessClientGuard(test)) {\n isGuarded = false;\n }\n },\n MemberExpression(node: AstNode) {\n if (functionDepthStack.length > 0) return;\n if (isGuarded) return;\n const obj = node.object as AstNode | undefined;\n if (obj?.type !== 'Identifier') return;\n if (!BROWSER_GLOBALS.has(obj.name as string)) return;\n context.report({ node, message: MESSAGE });\n },\n };\n },\n});\n","import { defineRule } from '../../../define-rule.js';\nimport type { AstNode, RuleContext } from '../../../types.js';\n\nconst DOCS_URL = 'https://nuxt.com/docs/4.x/guide/components';\nconst MESSAGE = `Accessing document/window/navigator/localStorage at the top level of <script setup> causes a server-side crash (SSR). These browser globals are undefined on the server. Move access inside onMounted or guard with import.meta.client. See ${DOCS_URL}`;\n\nconst SSR_UNSAFE_GLOBALS = new Set([\n 'document',\n 'window',\n 'navigator',\n 'localStorage',\n 'sessionStorage',\n]);\n\nexport const noDocumentInSetup = defineRule({\n create(context: RuleContext) {\n const functionDepthStack: number[] = [];\n\n return {\n ArrowFunctionExpression() {\n functionDepthStack.push(\n functionDepthStack.length > 0\n ? functionDepthStack[functionDepthStack.length - 1]! + 1\n : 1,\n );\n },\n 'ArrowFunctionExpression:exit'() {\n functionDepthStack.pop();\n },\n FunctionExpression() {\n functionDepthStack.push(\n functionDepthStack.length > 0\n ? functionDepthStack[functionDepthStack.length - 1]! + 1\n : 1,\n );\n },\n 'FunctionExpression:exit'() {\n functionDepthStack.pop();\n },\n FunctionDeclaration() {\n functionDepthStack.push(\n functionDepthStack.length > 0\n ? functionDepthStack[functionDepthStack.length - 1]! + 1\n : 1,\n );\n },\n 'FunctionDeclaration:exit'() {\n functionDepthStack.pop();\n },\n Identifier(node: AstNode) {\n if (functionDepthStack.length > 0) return;\n if (SSR_UNSAFE_GLOBALS.has(node.name as string)) {\n context.report({ node, message: MESSAGE });\n }\n },\n };\n },\n});\n","import { defineRule } from '../../../define-rule.js';\nimport type { AstNode, RuleContext } from '../../../types.js';\n\nconst DOCS_URL = 'https://h3.unjs.io/guide/throw';\nconst MESSAGE = `throw new Error() leaks the call stack and exposes internal details. Use throw createError() from h3 for proper HTTP errors with no stack leak. See ${DOCS_URL}`;\n\nexport const createErrorOnFailure = defineRule({\n create(context: RuleContext) {\n let handlerDepth = 0;\n\n return {\n CallExpression(node: AstNode) {\n const callee = node.callee as AstNode | undefined;\n if (callee?.type !== 'Identifier') return;\n if (\n (callee as AstNode & { name: string }).name !== 'defineEventHandler'\n )\n return;\n handlerDepth++;\n },\n 'CallExpression:exit'(node: AstNode) {\n const callee = node.callee as AstNode | undefined;\n if (callee?.type !== 'Identifier') return;\n if (\n (callee as AstNode & { name: string }).name !== 'defineEventHandler'\n )\n return;\n handlerDepth--;\n },\n ThrowStatement(node: AstNode) {\n if (handlerDepth === 0) return;\n const arg = node.argument as AstNode | undefined;\n if (!arg || arg.type !== 'NewExpression') return;\n const ctor = arg.callee as AstNode | undefined;\n if (ctor?.type !== 'Identifier') return;\n if ((ctor as AstNode & { name: string }).name !== 'Error') return;\n context.report({ node, message: MESSAGE });\n },\n };\n },\n});\n","import { defineRule } from '../../../define-rule.js';\nimport type { AstNode, RuleContext } from '../../../types.js';\n\nconst DOCS_URL = 'https://h3.unjs.io/guide/typed';\nconst MESSAGE = `defineEventHandler handler param event lacks a type annotation. Add a generic: defineEventHandler<H3Event>(...) or type the event parameter explicitly. See ${DOCS_URL}`;\n\nfunction isFunction(node: AstNode | undefined): boolean {\n return (\n node?.type === 'ArrowFunctionExpression' ||\n node?.type === 'FunctionExpression'\n );\n}\n\nexport const defineEventHandlerTyped = defineRule({\n create(context: RuleContext) {\n return {\n CallExpression(node: AstNode) {\n const callee = node.callee as AstNode | undefined;\n if (callee?.type !== 'Identifier') return;\n if (\n (callee as AstNode & { name: string }).name !== 'defineEventHandler'\n )\n return;\n if (node.typeArguments) return;\n const args = node.arguments as AstNode[];\n if (args.length === 0) return;\n const handler = args[0];\n if (!isFunction(handler)) return;\n const params = (handler as AstNode & { params: AstNode[] }).params;\n if (!params || params.length === 0) return;\n const eventParam = params[0] as AstNode;\n if (eventParam.typeAnnotation) return;\n context.report({ node, message: MESSAGE });\n },\n };\n },\n});\n","import { defineRule } from '../../../define-rule.js';\nimport type { AstNode, RuleContext } from '../../../types.js';\n\nconst DOCS_URL = 'https://nuxt.com/docs/4.x/guide/data-fetching';\nconst MESSAGE = `readBody() is the legacy H3 reader. In Nuxt 4 with h3 v2, use readValidatedBody to parse and validate the request body in one step. See ${DOCS_URL}`;\n\nexport const validateBodyWithH3V2 = defineRule({\n create(context: RuleContext) {\n return {\n CallExpression(node: AstNode) {\n const callee = node.callee as AstNode | undefined;\n if (callee?.type !== 'Identifier') return;\n if ((callee as AstNode & { name: string }).name !== 'readBody') return;\n context.report({ node, message: MESSAGE });\n },\n };\n },\n});\n","import { defineRule } from '../../define-rule.js';\nimport type { CoreRule } from '../../types.js';\nimport { noExplicitImportsOfAutoImported } from './ai-slop/no-explicit-imports-of-auto-imported.js';\nimport { noFetchInSetup } from './ai-slop/no-fetch-in-setup.js';\nimport { noProcessClientServer } from './ai-slop/no-process-client-server.js';\nimport { noUseStateForServerData } from './ai-slop/no-useState-for-server-data.js';\nimport { useAsyncDataKeyRequiredInLoop } from './data-fetching/useAsyncData-key-required-in-loop.js';\nimport { noUserInputInFetchUrl } from './security/no-user-input-in-fetch-url.js';\nimport { clientOnlyForBrowserApis } from './hydration/clientOnly-for-browser-apis.js';\nimport { noDocumentInSetup } from './hydration/no-document-in-setup.js';\nimport { createErrorOnFailure } from './server-routes/createError-on-failure.js';\nimport { defineEventHandlerTyped } from './server-routes/defineEventHandler-typed.js';\nimport { validateBodyWithH3V2 } from './server-routes/validate-body-with-h3-v2.js';\n\nfunction coreRule(\n id: string,\n category: CoreRule['category'],\n severity: CoreRule['severity'],\n recommended: boolean,\n rule: Omit<CoreRule, 'id' | 'category' | 'severity' | 'recommended'>,\n): CoreRule {\n return { id, category, severity, recommended, ...rule };\n}\n\nexport const NUXT_RULES: readonly CoreRule[] = [\n coreRule(\n 'ai-slop/no-process-client-server',\n 'ai-slop',\n 'error',\n true,\n defineRule(noProcessClientServer),\n ),\n coreRule(\n 'ai-slop/no-explicit-imports-of-auto-imported',\n 'ai-slop',\n 'warn',\n true,\n defineRule(noExplicitImportsOfAutoImported),\n ),\n coreRule(\n 'ai-slop/no-useState-for-server-data',\n 'ai-slop',\n 'warn',\n true,\n defineRule(noUseStateForServerData),\n ),\n coreRule(\n 'ai-slop/no-fetch-in-setup',\n 'ai-slop',\n 'warn',\n true,\n defineRule(noFetchInSetup),\n ),\n coreRule(\n 'data-fetching/useAsyncData-key-required-in-loop',\n 'data-fetching',\n 'error',\n true,\n defineRule(useAsyncDataKeyRequiredInLoop),\n ),\n coreRule(\n 'server-routes/defineEventHandler-typed',\n 'server-routes',\n 'warn',\n true,\n defineRule(defineEventHandlerTyped),\n ),\n coreRule(\n 'server-routes/validate-body-with-h3-v2',\n 'server-routes',\n 'warn',\n true,\n defineRule(validateBodyWithH3V2),\n ),\n coreRule(\n 'server-routes/createError-on-failure',\n 'server-routes',\n 'warn',\n true,\n defineRule(createErrorOnFailure),\n ),\n coreRule(\n 'hydration/no-document-in-setup',\n 'hydration',\n 'error',\n true,\n defineRule(noDocumentInSetup),\n ),\n coreRule(\n 'hydration/clientOnly-for-browser-apis',\n 'hydration',\n 'error',\n true,\n defineRule(clientOnlyForBrowserApis),\n ),\n coreRule(\n 'security/no-user-input-in-fetch-url',\n 'security',\n 'warn',\n true,\n defineRule(noUserInputInFetchUrl),\n ),\n];\n","import { defineRule } from '../../../define-rule.js';\nimport type { AstNode, RuleContext } from '../../../types.js';\n\nconst DOCS_URL =\n 'https://vuejs.org/guide/components/props.html#reactive-props-destructure';\nconst MESSAGE = `Destructuring props loses reactivity. Wrap with toRefs(...) to keep refs. See ${DOCS_URL}`;\n\nfunction calleeName(node: AstNode): string | undefined {\n const callee = node.callee as AstNode | undefined;\n if (callee?.type === 'Identifier') return callee.name as string;\n return undefined;\n}\n\nfunction isDefinePropsCall(node: AstNode | undefined): boolean {\n if (!node || node.type !== 'CallExpression') return false;\n const name = calleeName(node);\n if (name === 'defineProps') return true;\n if (name === 'withDefaults') {\n const args = node.arguments as AstNode[] | undefined;\n return isDefinePropsCall(args?.[0]);\n }\n return false;\n}\n\nfunction isToRefsCall(node: AstNode | undefined): boolean {\n return node?.type === 'CallExpression' && calleeName(node) === 'toRefs';\n}\n\nexport const noDestructurePropsWithoutToRefs = defineRule({\n create(context: RuleContext) {\n const propsSources = new Set<string>();\n\n function registerSetupParam(fn: AstNode | undefined): void {\n const params = fn?.params as AstNode[] | undefined;\n const first = params?.[0];\n if (first?.type === 'Identifier') propsSources.add(first.name as string);\n }\n\n return {\n VariableDeclarator(node: AstNode) {\n const id = node.id as AstNode;\n const init = node.init as AstNode | undefined;\n if (id.type === 'Identifier' && isDefinePropsCall(init)) {\n propsSources.add(id.name as string);\n return;\n }\n if (id.type !== 'ObjectPattern' || !init) return;\n if (isToRefsCall(init)) return;\n const fromProps =\n isDefinePropsCall(init) ||\n (init.type === 'Identifier' && propsSources.has(init.name as string));\n if (fromProps) context.report({ node, message: MESSAGE });\n },\n Property(node: AstNode) {\n const key = node.key as AstNode | undefined;\n if (key?.type === 'Identifier' && key.name === 'setup') {\n registerSetupParam(node.value as AstNode);\n }\n },\n };\n },\n});\n","import { defineRule } from '../../../define-rule.js';\nimport type { AstNode, RuleContext } from '../../../types.js';\n\nconst DOCS_URL =\n 'https://vuejs.org/guide/essentials/reactivity-fundamentals.html#destructuring-reactive-state';\nconst MESSAGE = `Destructuring reactive state loses reactivity. Wrap with toRefs(...) or read single keys via toRef(state, 'key'). See ${DOCS_URL}`;\n\nconst REACTIVE_FACTORIES = new Set(['reactive', 'shallowReactive']);\n\nfunction calleeName(node: AstNode): string | undefined {\n const callee = node.callee as AstNode | undefined;\n if (callee?.type === 'Identifier') return callee.name as string;\n return undefined;\n}\n\nfunction isReactiveCall(node: AstNode | undefined): boolean {\n if (!node || node.type !== 'CallExpression') return false;\n const name = calleeName(node);\n if (name && REACTIVE_FACTORIES.has(name)) return true;\n if (name === 'readonly') {\n const args = node.arguments as AstNode[] | undefined;\n return isReactiveCall(args?.[0]);\n }\n return false;\n}\n\nfunction isToRefsCall(node: AstNode | undefined): boolean {\n return node?.type === 'CallExpression' && calleeName(node) === 'toRefs';\n}\n\nexport const noDestructureReactiveWithoutToRefs = defineRule({\n create(context: RuleContext) {\n const reactiveSources = new Set<string>();\n return {\n VariableDeclarator(node: AstNode) {\n const id = node.id as AstNode;\n const init = node.init as AstNode | undefined;\n if (id.type === 'Identifier' && isReactiveCall(init)) {\n reactiveSources.add(id.name as string);\n return;\n }\n if (id.type !== 'ObjectPattern' || !init) return;\n if (isToRefsCall(init)) return;\n const fromReactive =\n isReactiveCall(init) ||\n (init.type === 'Identifier' &&\n reactiveSources.has(init.name as string));\n if (fromReactive) context.report({ node, message: MESSAGE });\n },\n };\n },\n});\n","import { defineRule } from '../../../define-rule.js';\nimport type { AstNode, RuleContext } from '../../../types.js';\n\nconst EM_DASH = '\\u2014';\n\ninterface LiteralNode extends AstNode {\n type: 'Literal';\n value: unknown;\n}\n\nexport const noEmDashInString = defineRule({\n create(context: RuleContext) {\n return {\n Literal(node: AstNode) {\n const literal = node as LiteralNode;\n if (typeof literal.value !== 'string') return;\n if (!literal.value.includes(EM_DASH)) return;\n context.report({\n node,\n message:\n 'Em dash in string literal reads as AI-generated output; use comma, colon, or parentheses.',\n });\n },\n };\n },\n fix(node: AstNode) {\n const literal = node as LiteralNode;\n if (typeof literal.value !== 'string') return null;\n const raw = literal.raw;\n if (typeof raw !== 'string') return null;\n if (!raw.includes(EM_DASH)) return null;\n return raw.split(EM_DASH).join('-');\n },\n});\n","import { defineRule } from '../../../define-rule.js';\nimport type { AstNode, RuleContext } from '../../../types.js';\nimport { VUE_AUTO_IMPORTED } from '../../../shared/auto-imported-symbols.js';\n\nconst DOCS_URL = 'https://nuxt.com/docs/4.x/guide/concepts/auto-imports';\nconst WHOLE_MESSAGE = `The entire import from 'vue' can be removed — these names are auto-imported in this project. See ${DOCS_URL}`;\nconst SPECIFIER_MESSAGE = `This symbol is auto-imported in your project. Remove it from the 'vue' import — it is dead weight in the diff. See ${DOCS_URL}`;\n\nfunction isAutoImportedValueSpecifier(spec: AstNode): boolean {\n if (spec.importKind === 'type') return false;\n const imported = spec.imported as AstNode;\n return VUE_AUTO_IMPORTED.has(imported.name as string);\n}\n\nexport const noImportsFromVueWhenAutoImported = defineRule({\n create(context: RuleContext) {\n let gated = false;\n return {\n Program() {\n gated = context.capabilities?.has('auto-imports:vue') !== true;\n },\n ImportDeclaration(node: AstNode) {\n if (gated) return;\n if (node.importKind === 'type') return;\n const source = node.source as AstNode;\n if (source.value !== 'vue') return;\n const specifiers = node.specifiers as AstNode[];\n const named = specifiers.filter((s) => s.type === 'ImportSpecifier');\n if (named.length === 0) return;\n const offending = named.filter(isAutoImportedValueSpecifier);\n if (offending.length === 0) return;\n if (\n offending.length === named.length &&\n specifiers.length === named.length\n ) {\n context.report({ node, message: WHOLE_MESSAGE });\n return;\n }\n for (const spec of offending) {\n context.report({ node: spec, message: SPECIFIER_MESSAGE });\n }\n },\n };\n },\n});\n","import { defineRule } from '../../../define-rule.js';\nimport type { AstNode, RuleContext } from '../../../types.js';\n\nconst DOCS_URL =\n 'https://vuejs.org/guide/typescript/composition-api.html#typing-ref';\nconst MESSAGE = `Non-null assertion on a ref's .value hides nullability. Add an explicit guard ('if (!r.value) return') or use optional chaining ('r.value?.x'). See ${DOCS_URL}`;\n\nconst REF_FACTORIES = new Set([\n 'ref',\n 'shallowRef',\n 'customRef',\n 'computed',\n 'useTemplateRef',\n]);\n\nfunction calleeName(node: AstNode): string | undefined {\n const callee = node.callee as AstNode | undefined;\n if (callee?.type === 'Identifier') return callee.name as string;\n return undefined;\n}\n\nfunction isRefFactoryCall(node: AstNode | undefined): boolean {\n if (!node || node.type !== 'CallExpression') return false;\n const name = calleeName(node);\n return name !== undefined && REF_FACTORIES.has(name);\n}\n\nfunction isDotValue(node: AstNode | undefined): node is AstNode {\n if (!node || node.type !== 'MemberExpression') return false;\n const property = node.property as AstNode | undefined;\n return (\n node.computed !== true &&\n property?.type === 'Identifier' &&\n property.name === 'value'\n );\n}\n\nexport const noNonNullAssertionOnRefValue = defineRule({\n create(context: RuleContext) {\n const refSources = new Set<string>();\n return {\n VariableDeclarator(node: AstNode) {\n const id = node.id as AstNode;\n if (\n id.type === 'Identifier' &&\n isRefFactoryCall(node.init as AstNode)\n ) {\n refSources.add(id.name as string);\n }\n },\n TSNonNullExpression(node: AstNode) {\n const arg = node.expression as AstNode | undefined;\n if (!isDotValue(arg)) return;\n const object = arg.object as AstNode | undefined;\n if (object?.type !== 'Identifier') return;\n if (!refSources.has(object.name as string)) return;\n context.report({ node, message: MESSAGE });\n },\n };\n },\n});\n","import { defineRule } from '../../../define-rule.js';\nimport type { AstNode, RuleContext } from '../../../types.js';\n\nconst DOCS_URL =\n 'https://vuejs.org/guide/typescript/composition-api.html#typing-component-props';\nconst MESSAGE = `This defineProps() call declares props with a runtime object, which discards static type information. Use the type-only generic form (defineProps<{ ... }>()) so props are fully typed. See ${DOCS_URL}`;\n\nfunction calleeName(node: AstNode): string | undefined {\n const callee = node.callee as AstNode | undefined;\n if (callee?.type === 'Identifier') return callee.name as string;\n return undefined;\n}\n\nexport const definePropsTyped = defineRule({\n create(context: RuleContext) {\n return {\n CallExpression(node: AstNode) {\n if (calleeName(node) !== 'defineProps') return;\n const firstArg = (node.arguments as AstNode[])[0];\n if (firstArg?.type === 'ObjectExpression') {\n context.report({ node, message: MESSAGE });\n }\n },\n };\n },\n});\n","import { defineRule } from '../../../define-rule.js';\nimport type { AstNode, RuleContext } from '../../../types.js';\n\nconst DOCS_URL = 'https://vuejs.org/api/sfc-script-setup.html';\nconst MESSAGE = `This component nests composition-API logic inside an options-object setup(). Use a <script setup> block instead — it removes the setup() boilerplate and exposes bindings to the template directly. See ${DOCS_URL}`;\n\nfunction isFunctionValue(node: AstNode | undefined): boolean {\n return (\n node?.type === 'ArrowFunctionExpression' ||\n node?.type === 'FunctionExpression'\n );\n}\n\nfunction isSetupProperty(prop: AstNode): boolean {\n if (prop.type !== 'Property' || prop.computed === true) return false;\n if (prop.shorthand === true) return false;\n const key = prop.key as AstNode;\n if (key.type !== 'Identifier' || key.name !== 'setup') return false;\n return isFunctionValue(prop.value as AstNode | undefined);\n}\n\nexport const preferScriptSetupForNewFiles = defineRule({\n create(context: RuleContext) {\n return {\n ExportDefaultDeclaration(node: AstNode) {\n const declaration = node.declaration as AstNode | undefined;\n if (declaration?.type !== 'ObjectExpression') return;\n const properties = declaration.properties as AstNode[];\n if (properties.some(isSetupProperty)) {\n context.report({ node, message: MESSAGE });\n }\n },\n };\n },\n});\n","import { defineRule } from '../../../define-rule.js';\nimport type { AstNode, RuleContext } from '../../../types.js';\n\nconst DOCS_URL = 'https://vuejs.org/guide/components/async.html';\nconst MESSAGE = `This route record's \\`component:\\` field references the imported component directly, which forces a synchronous import of the route bundle. Use \\`() => import('./Foo.vue')\\` or \\`defineAsyncComponent(() => import('./Foo.vue'))\\` to lazy-load the route. See ${DOCS_URL}`;\n\nfunction keyName(key: AstNode): unknown {\n return key.type === 'Identifier' ? key.name : key.value;\n}\n\nexport const preferDefineAsyncComponentOnRoute = defineRule({\n create(context: RuleContext) {\n return {\n Property(node: AstNode) {\n if (node.computed === true || node.shorthand === true) return;\n if (keyName(node.key as AstNode) !== 'component') return;\n const value = node.value as AstNode;\n if (value.type === 'Identifier') {\n context.report({ node, message: MESSAGE });\n }\n },\n };\n },\n});\n","import { defineRule } from '../../../define-rule.js';\nimport type { AstNode, RuleContext } from '../../../types.js';\n\nconst DOCS_URL =\n 'https://vuejs.org/guide/components/provide-inject.html#working-with-reactivity';\nconst MESSAGE = `Mutating an injected value from a consumer breaks one-way data flow and makes the source of changes hard to trace. Wrap the provided value in readonly() at the provide site and expose a dedicated mutator instead. See ${DOCS_URL}`;\n\nconst MUTATING_METHODS = new Set([\n 'push',\n 'pop',\n 'splice',\n 'shift',\n 'unshift',\n 'sort',\n 'reverse',\n]);\n\nfunction calleeName(node: AstNode): string | undefined {\n const callee = node.callee as AstNode | undefined;\n if (callee?.type === 'Identifier') return callee.name as string;\n return undefined;\n}\n\nfunction memberObjectName(node: AstNode | undefined): string | undefined {\n if (!node || node.type !== 'MemberExpression') return undefined;\n const object = node.object as AstNode;\n if (object.type !== 'Identifier') return undefined;\n return object.name as string;\n}\n\nexport const preferReadonlyForInjected = defineRule({\n create(context: RuleContext) {\n const injectedSources = new Set<string>();\n return {\n VariableDeclarator(node: AstNode) {\n const id = node.id as AstNode;\n const init = node.init as AstNode | undefined;\n if (\n id.type === 'Identifier' &&\n init?.type === 'CallExpression' &&\n calleeName(init) === 'inject'\n ) {\n injectedSources.add(id.name as string);\n }\n },\n AssignmentExpression(node: AstNode) {\n const name = memberObjectName(node.left as AstNode);\n if (name !== undefined && injectedSources.has(name)) {\n context.report({ node, message: MESSAGE });\n }\n },\n CallExpression(node: AstNode) {\n const callee = node.callee as AstNode | undefined;\n if (callee?.type !== 'MemberExpression' || callee.computed === true) {\n return;\n }\n const name = memberObjectName(callee);\n if (name === undefined || !injectedSources.has(name)) return;\n const property = callee.property as AstNode;\n if (MUTATING_METHODS.has(property.name as string)) {\n context.report({ node, message: MESSAGE });\n }\n },\n };\n },\n});\n","import { defineRule } from '../../../define-rule.js';\nimport type { AstNode, RuleContext } from '../../../types.js';\n\nconst DOCS_URL = 'https://vuejs.org/api/reactivity-advanced.html#shallowref';\nconst MESSAGE = `This ref holds large or fetched data, so deep reactivity tracks every nested property and wastes memory and CPU. Use shallowRef() (and triggerRef on replacement) for large arrays, big objects, or server payloads. See ${DOCS_URL}`;\n\nconst ARRAY_LIMIT = 100;\nconst OBJECT_LIMIT = 50;\nconst FETCH_IDENTIFIERS = new Set(['$fetch', 'useFetch']);\n\nfunction calleeName(node: AstNode): string | undefined {\n const callee = node.callee as AstNode | undefined;\n if (callee?.type === 'Identifier') return callee.name as string;\n return undefined;\n}\n\nfunction isAxiosGet(node: AstNode): boolean {\n const callee = node.callee as AstNode | undefined;\n if (callee?.type !== 'MemberExpression' || callee.computed === true) {\n return false;\n }\n const object = callee.object as AstNode;\n const property = callee.property as AstNode;\n return (\n object.type === 'Identifier' &&\n object.name === 'axios' &&\n property.name === 'get'\n );\n}\n\nfunction isFetchSource(node: AstNode): boolean {\n if (node.type !== 'CallExpression') return false;\n const name = calleeName(node);\n if (name !== undefined && FETCH_IDENTIFIERS.has(name)) return true;\n return isAxiosGet(node);\n}\n\nfunction isLargeData(node: AstNode | undefined): boolean {\n if (!node) return false;\n const value =\n node.type === 'AwaitExpression' ? (node.argument as AstNode) : node;\n if (value.type === 'ArrayExpression') {\n return (value.elements as AstNode[]).length > ARRAY_LIMIT;\n }\n if (value.type === 'ObjectExpression') {\n return (value.properties as AstNode[]).length > OBJECT_LIMIT;\n }\n return isFetchSource(value);\n}\n\nexport const preferShallowRefForLargeData = defineRule({\n create(context: RuleContext) {\n return {\n CallExpression(node: AstNode) {\n if (calleeName(node) !== 'ref') return;\n const init = (node.arguments as AstNode[])[0];\n if (isLargeData(init)) context.report({ node, message: MESSAGE });\n },\n };\n },\n});\n","import { defineRule } from '../../../define-rule.js';\nimport type { AstNode, RuleContext } from '../../../types.js';\n\nconst DOCS_URL =\n 'https://vuejs.org/guide/essentials/watchers.html#side-effect-cleanup';\nconst MESSAGE = `This watcher registers a listener, timer, or observer but never cleans it up, so it leaks across re-runs and hot reloads. Return a cleanup function (or call onWatcherCleanup) inside the watcher. See ${DOCS_URL}`;\n\nconst REGISTER_CALLS = new Set([\n 'addEventListener',\n 'setInterval',\n 'setTimeout',\n]);\nconst OBSERVERS = new Set([\n 'IntersectionObserver',\n 'MutationObserver',\n 'ResizeObserver',\n]);\nconst CLEANUP_CALLS = new Set(['onCleanup', 'onWatcherCleanup']);\n\ninterface WatchFrame {\n sourceCall: AstNode;\n isEffect: boolean;\n hasRegistration: boolean;\n hasCleanup: boolean;\n}\n\nfunction calleeIdentifierName(node: AstNode): string | undefined {\n const callee = node.callee as AstNode | undefined;\n if (callee?.type === 'Identifier') return callee.name as string;\n return undefined;\n}\n\nfunction calledMethodName(node: AstNode): string | undefined {\n const callee = node.callee as AstNode | undefined;\n if (callee?.type === 'Identifier') return callee.name as string;\n if (callee?.type === 'MemberExpression' && callee.computed !== true) {\n const property = callee.property as AstNode;\n return property.name as string;\n }\n return undefined;\n}\n\nfunction isFunction(node: AstNode | undefined): boolean {\n return (\n node?.type === 'ArrowFunctionExpression' ||\n node?.type === 'FunctionExpression'\n );\n}\n\nexport const watchWithoutCleanup = defineRule({\n create(context: RuleContext) {\n const watchStack: WatchFrame[] = [];\n\n return {\n CallExpression(node: AstNode) {\n const name = calleeIdentifierName(node);\n if (name === 'watch' || name === 'watchEffect') {\n const isEffect = name === 'watchEffect';\n const args = node.arguments as AstNode[];\n const callback = args[isEffect ? 0 : 1];\n if (!isFunction(callback)) return;\n watchStack.push({\n sourceCall: node,\n isEffect,\n hasRegistration: false,\n hasCleanup: false,\n });\n return;\n }\n if (watchStack.length === 0) return;\n const top = watchStack[watchStack.length - 1]!;\n const method = calledMethodName(node);\n if (method !== undefined && REGISTER_CALLS.has(method)) {\n top.hasRegistration = true;\n }\n if (method !== undefined && CLEANUP_CALLS.has(method) && top.isEffect) {\n top.hasCleanup = true;\n }\n },\n NewExpression(node: AstNode) {\n if (watchStack.length === 0) return;\n const callee = node.callee as AstNode | undefined;\n if (\n callee?.type === 'Identifier' &&\n OBSERVERS.has(callee.name as string)\n ) {\n watchStack[watchStack.length - 1]!.hasRegistration = true;\n }\n },\n ReturnStatement(node: AstNode) {\n if (watchStack.length === 0) return;\n if (isFunction(node.argument as AstNode | undefined)) {\n watchStack[watchStack.length - 1]!.hasCleanup = true;\n }\n },\n 'CallExpression:exit'(node: AstNode) {\n if (watchStack.length === 0) return;\n const top = watchStack[watchStack.length - 1]!;\n if (top.sourceCall !== node) return;\n watchStack.pop();\n if (top.hasRegistration && !top.hasCleanup) {\n context.report({ node, message: MESSAGE });\n }\n },\n };\n },\n});\n","import { defineRule } from '../../../define-rule.js';\nimport type { AstNode, RuleContext } from '../../../types.js';\n\nconst DOCS_URL =\n 'https://cheatsheetseries.owasp.org/cheatsheets/HTML5_Security_Cheat_Sheet.html#local-storage';\nconst MESSAGE = `Persisting auth tokens/secrets in localStorage or sessionStorage exposes them to any XSS payload. Store them in an HttpOnly, Secure, SameSite cookie set by the server instead. See ${DOCS_URL}`;\n\nconst STORAGES = new Set(['localStorage', 'sessionStorage']);\nconst SENSITIVE_KEY =\n /token|jwt|secret|password|passwd|credential|api[-_]?key|bearer|private[-_]?key|auth/i;\n\nfunction stringValue(node: AstNode | undefined): string | undefined {\n if (node?.type === 'Literal' && typeof node.value === 'string') {\n return node.value;\n }\n return undefined;\n}\n\nfunction isStorageObject(node: AstNode | undefined): boolean {\n return node?.type === 'Identifier' && STORAGES.has(node.name as string);\n}\n\nfunction memberKey(node: AstNode): string | undefined {\n const property = node.property as AstNode;\n if (node.computed === true) return stringValue(property);\n return property.name as string;\n}\n\nexport const noAuthTokenInWebStorage = defineRule({\n create(context: RuleContext) {\n return {\n CallExpression(node: AstNode) {\n const callee = node.callee as AstNode;\n if (callee.type !== 'MemberExpression') return;\n if (callee.computed === true) return;\n if (!isStorageObject(callee.object as AstNode | undefined)) return;\n const method = callee.property as AstNode;\n if (method.name !== 'setItem') return;\n const key = stringValue((node.arguments as AstNode[])[0]);\n if (key !== undefined && SENSITIVE_KEY.test(key)) {\n context.report({ node, message: MESSAGE });\n }\n },\n AssignmentExpression(node: AstNode) {\n const left = node.left as AstNode;\n if (left.type !== 'MemberExpression') return;\n if (!isStorageObject(left.object as AstNode | undefined)) return;\n const key = memberKey(left);\n if (key !== undefined && SENSITIVE_KEY.test(key)) {\n context.report({ node, message: MESSAGE });\n }\n },\n };\n },\n});\n","import { defineRule } from '../../../define-rule.js';\nimport type { AstNode, RuleContext } from '../../../types.js';\n\nconst DOCS_URL =\n 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval#never_use_eval!';\nconst MESSAGE = `eval, new Function, and string-argument setTimeout/setInterval execute arbitrary code and are XSS/RCE vectors. Replace with explicit logic or JSON.parse for data. See ${DOCS_URL}`;\n\nconst STRING_TIMER_CALLEES = new Set(['setTimeout', 'setInterval']);\n\nfunction calleeName(node: AstNode): string | undefined {\n const callee = node.callee as AstNode | undefined;\n if (callee?.type === 'Identifier') return callee.name as string;\n return undefined;\n}\n\nfunction isStringArg(node: AstNode | undefined): boolean {\n if (!node) return false;\n if (node.type === 'Literal') return typeof node.value === 'string';\n return node.type === 'TemplateLiteral';\n}\n\nexport const noEvalLike = defineRule({\n create(context: RuleContext) {\n return {\n CallExpression(node: AstNode) {\n const name = calleeName(node);\n if (name === undefined) return;\n if (name === 'eval') {\n context.report({ node, message: MESSAGE });\n return;\n }\n if (STRING_TIMER_CALLEES.has(name)) {\n const args = node.arguments as AstNode[] | undefined;\n if (isStringArg(args?.[0])) {\n context.report({ node, message: MESSAGE });\n }\n }\n },\n NewExpression(node: AstNode) {\n const callee = node.callee as AstNode | undefined;\n if (callee?.type === 'Identifier' && callee.name === 'Function') {\n context.report({ node, message: MESSAGE });\n }\n },\n };\n },\n});\n","import { defineRule } from '../../../define-rule.js';\nimport type { AstNode, RuleContext } from '../../../types.js';\n\nconst DOCS_URL =\n 'https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML#security_considerations';\nconst MESSAGE = `Assigning to innerHTML/outerHTML injects unsanitized markup and is a DOM-based XSS sink. Use textContent for text, or sanitize with DOMPurify before assigning. See ${DOCS_URL}`;\n\nconst HTML_SINKS = new Set(['innerHTML', 'outerHTML']);\n\nfunction isHtmlSinkTarget(node: AstNode): boolean {\n if (node.type !== 'MemberExpression') return false;\n if (node.computed === true) return false;\n const property = node.property as AstNode;\n return (\n property.type === 'Identifier' && HTML_SINKS.has(property.name as string)\n );\n}\n\nexport const noInnerHtml = defineRule({\n create(context: RuleContext) {\n return {\n AssignmentExpression(node: AstNode) {\n if (!isHtmlSinkTarget(node.left as AstNode)) return;\n context.report({ node, message: MESSAGE });\n },\n };\n },\n});\n","import { defineRule } from '../../../define-rule.js';\nimport type { AstNode, RuleContext } from '../../../types.js';\n\nconst DOCS_URL =\n 'https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html';\nconst MESSAGE = `Hardcoded secret in source. Committed secrets leak in the client bundle and git history. Move it to an environment variable or a server-only runtime config. See ${DOCS_URL}`;\n\n// High-signal secret token shapes. Conservative on purpose: each pattern is a\n// well-known credential prefix/format, not a generic \"looks long\" heuristic.\nconst SECRET_VALUE_PATTERNS: readonly RegExp[] = [\n /\\bsk-[A-Za-z0-9-]{10,}\\b/,\n /\\bghp_[A-Za-z0-9]{20,}\\b/,\n /\\bgithub_pat_[A-Za-z0-9_]{20,}\\b/,\n /\\bxox[baprs]-[A-Za-z0-9-]{10,}\\b/,\n /\\bAKIA[0-9A-Z]{16}\\b/,\n /\\bAIza[0-9A-Za-z_-]{20,}\\b/,\n];\n\n// Identifier names that strongly imply a secret. Paired with a long string\n// literal value to avoid flagging env reads or short non-secret strings.\nconst SECRET_NAME =\n /^(api[-_]?secret|api[-_]?key|secret[-_]?key|private[-_]?key|access[-_]?token|auth[-_]?token|client[-_]?secret|password|passwd|jwt[-_]?secret)$/i;\nconst MIN_NAMED_SECRET_LENGTH = 8;\n\nfunction stringValue(node: AstNode | undefined): string | undefined {\n if (node?.type === 'Literal' && typeof node.value === 'string') {\n return node.value;\n }\n return undefined;\n}\n\nfunction isHighSignalSecret(value: string): boolean {\n return SECRET_VALUE_PATTERNS.some((pattern) => pattern.test(value));\n}\n\nexport const noSecretsInSource = defineRule({\n create(context: RuleContext) {\n const reported = new Set<AstNode>();\n\n function report(node: AstNode): void {\n if (reported.has(node)) return;\n reported.add(node);\n context.report({ node, message: MESSAGE });\n }\n\n function checkNamedAssignment(\n name: string | undefined,\n valueNode: AstNode | undefined,\n ): void {\n if (name === undefined || !SECRET_NAME.test(name)) return;\n if (!valueNode) return;\n const value = stringValue(valueNode);\n if (value === undefined || value.length < MIN_NAMED_SECRET_LENGTH) return;\n report(valueNode);\n }\n\n return {\n Literal(node: AstNode) {\n if (typeof node.value !== 'string') return;\n if (isHighSignalSecret(node.value)) report(node);\n },\n VariableDeclarator(node: AstNode) {\n const id = node.id as AstNode;\n if (id.type !== 'Identifier') return;\n checkNamedAssignment(\n id.name as string,\n node.init as AstNode | undefined,\n );\n },\n Property(node: AstNode) {\n const key = node.key as AstNode;\n const name =\n key.type === 'Identifier' ? (key.name as string) : stringValue(key);\n checkNamedAssignment(name, node.value as AstNode | undefined);\n },\n };\n },\n});\n","import { defineRule } from '../../define-rule.js';\nimport type { CoreRule } from '../../types.js';\nimport { noDestructurePropsWithoutToRefs } from './ai-slop/no-destructure-props-without-toRefs.js';\nimport { noDestructureReactiveWithoutToRefs } from './ai-slop/no-destructure-reactive-without-toRefs.js';\nimport { noEmDashInString } from './ai-slop/no-em-dash-in-string.js';\nimport { noImportsFromVueWhenAutoImported } from './ai-slop/no-imports-from-vue-when-auto-imported.js';\nimport { noNonNullAssertionOnRefValue } from './ai-slop/no-non-null-assertion-on-ref-value.js';\nimport { definePropsTyped } from './composition/defineProps-typed.js';\nimport { preferScriptSetupForNewFiles } from './composition/prefer-script-setup-for-new-files.js';\nimport { preferDefineAsyncComponentOnRoute } from './performance/prefer-defineAsyncComponent-on-route.js';\nimport { preferReadonlyForInjected } from './reactivity/prefer-readonly-for-injected.js';\nimport { preferShallowRefForLargeData } from './reactivity/prefer-shallowRef-for-large-data.js';\nimport { watchWithoutCleanup } from './reactivity/watch-without-cleanup.js';\nimport { noAuthTokenInWebStorage } from './security/no-auth-token-in-web-storage.js';\nimport { noEvalLike } from './security/no-eval-like.js';\nimport { noInnerHtml } from './security/no-inner-html.js';\nimport { noSecretsInSource } from './security/no-secrets-in-source.js';\n\nfunction coreRule(\n id: string,\n category: CoreRule['category'],\n severity: CoreRule['severity'],\n recommended: boolean,\n rule: Omit<CoreRule, 'id' | 'category' | 'severity' | 'recommended'>,\n): CoreRule {\n return { id, category, severity, recommended, ...rule };\n}\n\nexport const VUE_RULES: readonly CoreRule[] = [\n coreRule(\n 'no-em-dash-in-string',\n 'ai-slop',\n 'warn',\n true,\n defineRule(noEmDashInString),\n ),\n coreRule(\n 'no-destructure-props-without-to-refs',\n 'ai-slop',\n 'error',\n true,\n defineRule(noDestructurePropsWithoutToRefs),\n ),\n coreRule(\n 'no-destructure-reactive-without-to-refs',\n 'ai-slop',\n 'error',\n true,\n defineRule(noDestructureReactiveWithoutToRefs),\n ),\n coreRule(\n 'no-non-null-assertion-on-ref-value',\n 'ai-slop',\n 'warn',\n true,\n defineRule(noNonNullAssertionOnRefValue),\n ),\n coreRule(\n 'no-imports-from-vue-when-auto-imported',\n 'ai-slop',\n 'warn',\n true,\n defineRule(noImportsFromVueWhenAutoImported),\n ),\n coreRule(\n 'reactivity/watch-without-cleanup',\n 'reactivity',\n 'warn',\n true,\n defineRule(watchWithoutCleanup),\n ),\n coreRule(\n 'reactivity/prefer-shallowRef-for-large-data',\n 'reactivity',\n 'info',\n false,\n defineRule(preferShallowRefForLargeData),\n ),\n coreRule(\n 'reactivity/prefer-readonly-for-injected',\n 'reactivity',\n 'info',\n false,\n defineRule(preferReadonlyForInjected),\n ),\n coreRule(\n 'composition/prefer-script-setup-for-new-files',\n 'composition',\n 'warn',\n true,\n defineRule(preferScriptSetupForNewFiles),\n ),\n coreRule(\n 'composition/defineProps-typed',\n 'composition',\n 'warn',\n true,\n defineRule(definePropsTyped),\n ),\n coreRule(\n 'performance/prefer-defineAsyncComponent-on-route',\n 'performance',\n 'info',\n false,\n defineRule(preferDefineAsyncComponentOnRoute),\n ),\n coreRule(\n 'security/no-inner-html',\n 'security',\n 'error',\n true,\n defineRule(noInnerHtml),\n ),\n coreRule(\n 'security/no-eval-like',\n 'security',\n 'error',\n true,\n defineRule(noEvalLike),\n ),\n coreRule(\n 'security/no-auth-token-in-web-storage',\n 'security',\n 'warn',\n true,\n defineRule(noAuthTokenInWebStorage),\n ),\n coreRule(\n 'security/no-secrets-in-source',\n 'security',\n 'warn',\n true,\n defineRule(noSecretsInSource),\n ),\n];\n"],"mappings":"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GAGjB,qBADE,IAAI,SAAS,eAAgB,IAAI,OAAkB,YAAY,GAAG,GACzC,KAAK,KAA4B;EAC9D;CACF;AACF,EACF,CAAC;;;AC3DD,SAAS,SACP,IACA,UACA,UACA,aACA,MACU;CACV,OAAO;EAAE;EAAI;EAAU;EAAU;EAAa,GAAG;CAAK;AACxD;AAEA,MAAa,YAAiC;CAC5C,SACE,wBACA,WACA,QACA,MACA,WAAW,gBAAgB,CAC7B;CACA,SACE,wCACA,WACA,SACA,MACA,WAAW,+BAA+B,CAC5C;CACA,SACE,2CACA,WACA,SACA,MACA,WAAW,kCAAkC,CAC/C;CACA,SACE,sCACA,WACA,QACA,MACA,WAAW,4BAA4B,CACzC;CACA,SACE,0CACA,WACA,QACA,MACA,WAAW,gCAAgC,CAC7C;CACA,SACE,oCACA,cACA,QACA,MACA,WAAW,mBAAmB,CAChC;CACA,SACE,+CACA,cACA,QACA,OACA,WAAW,4BAA4B,CACzC;CACA,SACE,2CACA,cACA,QACA,OACA,WAAW,yBAAyB,CACtC;CACA,SACE,iDACA,eACA,QACA,MACA,WAAW,4BAA4B,CACzC;CACA,SACE,iCACA,eACA,QACA,MACA,WAAW,gBAAgB,CAC7B;CACA,SACE,oDACA,eACA,QACA,OACA,WAAW,iCAAiC,CAC9C;CACA,SACE,0BACA,YACA,SACA,MACA,WAAW,WAAW,CACxB;CACA,SACE,yBACA,YACA,SACA,MACA,WAAW,UAAU,CACvB;CACA,SACE,yCACA,YACA,QACA,MACA,WAAW,uBAAuB,CACpC;CACA,SACE,iCACA,YACA,QACA,MACA,WAAW,iBAAiB,CAC9B;AACF"}
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "@geoql/doctor-rule-core",
3
+ "version": "1.0.0",
4
+ "private": false,
5
+ "description": "Linter-neutral rule cores shared by @geoql/oxlint-plugin-vue-doctor, @geoql/oxlint-plugin-nuxt-doctor, and the future ESLint plugin. ESTree/JS-AST only.",
6
+ "keywords": [
7
+ "doctor",
8
+ "geoql",
9
+ "lint",
10
+ "nuxt",
11
+ "rules",
12
+ "vue"
13
+ ],
14
+ "homepage": "https://github.com/geoql/doctor#readme",
15
+ "bugs": {
16
+ "url": "https://github.com/geoql/doctor/issues"
17
+ },
18
+ "license": "MIT",
19
+ "author": {
20
+ "name": "Vinayak Kulkarni",
21
+ "email": "inbox.vinayak@gmail.com",
22
+ "url": "https://vinayakkulkarni.dev"
23
+ },
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "git+https://github.com/geoql/doctor.git",
27
+ "directory": "packages/doctor-rule-core"
28
+ },
29
+ "files": [
30
+ "dist"
31
+ ],
32
+ "type": "module",
33
+ "types": "./dist/index.d.ts",
34
+ "exports": {
35
+ ".": {
36
+ "import": "./dist/index.js",
37
+ "types": "./dist/index.d.ts"
38
+ }
39
+ },
40
+ "publishConfig": {
41
+ "access": "public"
42
+ },
43
+ "devDependencies": {
44
+ "@types/node": "^25.9.3",
45
+ "oxc-parser": "0.133.0",
46
+ "typescript": "^6.0.3",
47
+ "vitest": "^4.1.9"
48
+ },
49
+ "engines": {
50
+ "node": ">=24"
51
+ },
52
+ "scripts": {
53
+ "lint": "vp lint src",
54
+ "lint:fix": "vp lint src --fix",
55
+ "format": "vp fmt",
56
+ "format:check": "vp fmt --check",
57
+ "build": "vp pack",
58
+ "test": "vitest run"
59
+ }
60
+ }