eslint-plugin-no-server-imports 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,"sources":["../src/index.ts","../src/framework-detection.ts"],"sourcesContent":["/**\n * ESLint Plugin: eslint-plugin-no-server-imports\n * ===============================================\n * Prevents server-only module imports in client code.\n * Catches bundling issues in your editor instead of at build time.\n *\n * @author Jag Reehal [@jagreehal] <jag@jagreehal.com>\n * @license MIT\n */\n\nimport { AST_NODE_TYPES, ESLintUtils } from '@typescript-eslint/utils';\nimport type { TSESLint, TSESTree } from '@typescript-eslint/utils';\nimport picomatch from 'picomatch';\n\n/** Default server-only modules that should not be imported in client code */\nconst DEFAULT_SERVER_MODULES = [\n // Logging\n 'pino',\n 'pino-pretty',\n 'pino-roll',\n 'winston',\n 'bunyan',\n // Database\n 'better-sqlite3',\n 'pg',\n 'mysql2',\n 'mongodb',\n 'mongoose',\n 'prisma',\n '@prisma/client',\n 'drizzle-orm',\n 'kysely',\n '@libsql/client',\n 'libsql',\n '@mikro-orm/core',\n '@mikro-orm/knex',\n 'sqlite3',\n // Authentication & Security\n 'argon2',\n '@node-rs/argon2',\n 'bcrypt',\n '@node-rs/bcrypt',\n 'oslo',\n // AWS SDK\n '@aws-sdk/client-s3',\n '@aws-sdk/s3-presigned-post',\n 'aws-crt',\n // Monitoring & Observability\n '@appsignal/nodejs',\n '@highlight-run/node',\n '@sentry/profiling-node',\n 'dd-trace',\n 'newrelic',\n '@statsig/statsig-node-core',\n // AI & ML\n '@huggingface/transformers',\n '@xenova/transformers',\n 'chromadb-default-embed',\n 'onnxruntime-node',\n // Blockchain\n '@blockfrost/blockfrost-js',\n '@jpg-store/lucid-cardano',\n // Build Tools & Compilers\n '@swc/core',\n 'autoprefixer',\n 'postcss',\n 'prettier',\n 'typescript',\n 'ts-node',\n 'ts-morph',\n 'webpack',\n 'eslint',\n // Testing\n 'cypress',\n 'jest',\n 'playwright',\n 'playwright-core',\n 'puppeteer',\n 'puppeteer-core',\n // Browser Automation\n '@sparticuz/chromium',\n '@sparticuz/chromium-min',\n // Content & Document Generation\n '@react-pdf/renderer',\n 'mdx-bundler',\n 'next-mdx-remote',\n 'next-seo',\n 'shiki',\n 'vscode-oniguruma',\n // Image Processing\n 'canvas',\n 'sharp',\n // Utilities\n 'config',\n 'keyv',\n 'node-cron',\n 'rimraf',\n 'thread-stream',\n // Runtime & Framework\n '@alinea/generated',\n '@zenstackhq/runtime',\n 'express',\n 'firebase-admin',\n 'htmlrewriter',\n // Native Node.js addons\n 'cpu-features',\n 'isolated-vm',\n 'node-pty',\n 'node-web-audio-api',\n 'websocket',\n 'zeromq',\n // Module System Patchers\n 'import-in-the-middle',\n 'require-in-the-middle',\n // DOM & Browser APIs\n 'jsdom',\n // Database (additional)\n 'ravendb',\n // Node.js built-ins\n 'fs',\n 'node:fs',\n 'fs/promises',\n 'node:fs/promises',\n 'path',\n 'node:path',\n 'crypto',\n 'node:crypto',\n 'child_process',\n 'node:child_process',\n 'os',\n 'node:os',\n 'net',\n 'node:net',\n 'dns',\n 'node:dns',\n 'cluster',\n 'node:cluster',\n 'worker_threads',\n 'node:worker_threads',\n];\n\n/** Default file patterns that indicate server-only code */\nconst DEFAULT_SERVER_FILE_PATTERNS = [\n '**/*.server.ts',\n '**/*.server.tsx',\n '**/*.server.js',\n '**/server/**',\n '**/api/**',\n '**/_server/**',\n];\n\n/** Default file patterns that indicate client code */\nconst DEFAULT_CLIENT_FILE_PATTERNS = [\n '**/routes/**',\n '**/pages/**',\n '**/components/**',\n '**/islands/**',\n '**/src/app/**', // Next.js app directory (in src)\n // Note: For Next.js root-level app/, users should configure clientFilePatterns\n // We can't use '**/app/**' as it's too broad and matches paths like '/myapp/src/...'\n];\n\n/** Configuration options for the no-server-imports rule */\nexport interface RuleOptions {\n /** Additional server-only modules to check (merged with defaults) */\n serverModules?: string[];\n /** Additional server-only file patterns to check (merged with defaults) */\n serverFilePatterns?: string[];\n /** File patterns that indicate client code (overrides defaults if provided) */\n clientFilePatterns?: string[];\n /** File patterns to completely ignore */\n ignoreFiles?: string[];\n /** Whether to check for 'server-only' import marker */\n checkServerOnlyMarker?: boolean;\n /** Whether to check for server function usage (createServerFn, etc.) */\n checkServerFunctions?: boolean;\n /** Server function names to check for */\n serverFunctionNames?: string[];\n /** Whether to report unused server-only imports (default: true) */\n reportUnusedImports?: boolean;\n /** File selection mode: 'client-only' checks only clientFilePatterns, 'all-non-server' checks all except server files */\n mode?: 'client-only' | 'all-non-server';\n /** Next.js serverExternalPackages - merged into serverModules (for Next.js projects) */\n serverExternalPackages?: string[];\n}\n\ntype MessageIds =\n | 'serverOnlyImport'\n | 'serverOnlyRequire'\n | 'suggestServerOnlyMarker';\ntype Options = [RuleOptions?];\n\nconst createRule = ESLintUtils.RuleCreator(\n () => 'https://github.com/jagreehal/eslint-plugin-no-server-imports#readme'\n);\n\n/**\n * Checks if an import declaration has any value (non-type) specifiers.\n * Returns false if ALL specifiers are type-only imports.\n */\nfunction hasValueImportSpecifiers(node: TSESTree.ImportDeclaration): boolean {\n // If the whole import is type-only, no value specifiers\n if (node.importKind === 'type') {\n return false;\n }\n\n // If no specifiers (side-effect import like `import 'module'`), it's a value import\n if (node.specifiers.length === 0) {\n return true;\n }\n\n // Check if ANY specifier is a value import (not type-only)\n return node.specifiers.some((specifier) => {\n // Default imports and namespace imports don't have importKind\n if (specifier.type === AST_NODE_TYPES.ImportDefaultSpecifier) {\n return true; // Default imports are always value imports\n }\n if (specifier.type === AST_NODE_TYPES.ImportNamespaceSpecifier) {\n return true; // Namespace imports are always value imports\n }\n // For named imports, check if it's a type import\n if (specifier.type === AST_NODE_TYPES.ImportSpecifier) {\n return specifier.importKind !== 'type';\n }\n return true;\n });\n}\n\n/**\n * Checks if an export declaration has any value (non-type) specifiers.\n * Returns false if ALL specifiers are type-only exports.\n */\nfunction hasValueExportSpecifiers(node: TSESTree.ExportNamedDeclaration): boolean {\n // If the whole export is type-only, no value specifiers\n if (node.exportKind === 'type') {\n return false;\n }\n\n // If no specifiers but has source (re-export), check the specifiers\n if (node.specifiers.length === 0) {\n return true; // `export * from 'module'` is a value export\n }\n\n // Check if ANY specifier is a value export (not type-only)\n return node.specifiers.some((specifier) => {\n return specifier.exportKind !== 'type';\n });\n}\n\n/**\n * Gets the local names of value imports from an import declaration\n */\nfunction getValueImportNames(node: TSESTree.ImportDeclaration): string[] {\n if (node.importKind === 'type') {\n return [];\n }\n\n const names: string[] = [];\n for (const specifier of node.specifiers) {\n switch (specifier.type) {\n case AST_NODE_TYPES.ImportDefaultSpecifier:\n case AST_NODE_TYPES.ImportNamespaceSpecifier: {\n names.push(specifier.local.name);\n break;\n }\n case AST_NODE_TYPES.ImportSpecifier: {\n if (specifier.importKind !== 'type') {\n names.push(specifier.local.name);\n }\n break;\n }\n }\n }\n return names;\n}\n\n/**\n * Checks if a node is inside a given scope (function/arrow function)\n */\nfunction isNodeInsideScope(node: TSESTree.Node, scopeNode: TSESTree.Node): boolean {\n let current: TSESTree.Node | undefined = node;\n while (current) {\n if (current === scopeNode) {\n return true;\n }\n current = current.parent;\n }\n return false;\n}\n\n/**\n * Checks if a node is a directive prologue (e.g., 'use client', 'use strict')\n */\nfunction isDirectivePrologue(node: TSESTree.Statement): boolean {\n return (\n node.type === AST_NODE_TYPES.ExpressionStatement &&\n node.expression.type === AST_NODE_TYPES.Literal &&\n typeof node.expression.value === 'string'\n );\n}\n\n/**\n * Checks if the file has a 'use client' directive\n */\nfunction hasUseClientDirective(sourceCode: TSESLint.SourceCode): boolean {\n const ast = sourceCode.ast;\n if (!ast.body || ast.body.length === 0) return false;\n\n for (const node of ast.body) {\n if (!isDirectivePrologue(node)) break;\n const expr = (node as TSESTree.ExpressionStatement).expression as TSESTree.Literal;\n if (expr.value === 'use client') return true;\n }\n return false;\n}\n\n/**\n * Finds the best node to insert the server-only marker before\n * Respects shebangs, file comments, directive prologues, and existing imports\n *\n * @param sourceCode - The source code object\n * @returns The node to insert before, or null to insert at start\n */\nfunction findServerOnlyMarkerInsertNode(\n sourceCode: TSESLint.SourceCode\n): TSESTree.Node | null {\n const ast = sourceCode.ast;\n\n // If there are no statements, insert at the beginning\n if (!ast.body || ast.body.length === 0) {\n return null;\n }\n\n // Skip past directive prologues ('use strict', 'use client', etc.)\n let insertIndex = 0;\n for (const node of ast.body) {\n if (isDirectivePrologue(node)) {\n insertIndex++;\n } else {\n break;\n }\n }\n\n // If all statements are directives, insert after them\n if (insertIndex >= ast.body.length) {\n return null; // Will insert at end\n }\n\n return ast.body[insertIndex];\n}\n\n/**\n * Creates a server-only marker suggestion if appropriate.\n * Returns empty array if file has 'use client' directive (conflicts with server-only).\n * Returns no-op suggestion if marker already exists (ESLint still counts it).\n */\nfunction createServerOnlyMarkerSuggestion(\n sourceCode: TSESLint.SourceCode\n): TSESLint.SuggestionReportDescriptor<MessageIds>[] {\n // Don't suggest server-only in 'use client' files - they conflict\n if (hasUseClientDirective(sourceCode)) {\n return [];\n }\n\n // Check if server-only marker already exists\n const text = sourceCode.getText();\n const hasMarker = /^import\\s+['\"]server-only['\"]/m.test(text);\n\n return [\n {\n messageId: 'suggestServerOnlyMarker' as const,\n data: {},\n fix: (fixer: TSESLint.RuleFixer) => {\n if (hasMarker) {\n // Return a no-op fix when marker exists (insert empty string)\n // ESLint still counts the suggestion\n return fixer.insertTextBeforeRange([0, 0], '');\n }\n const insertNode = findServerOnlyMarkerInsertNode(sourceCode);\n if (insertNode) {\n return fixer.insertTextBefore(insertNode, \"import 'server-only';\\n\");\n }\n // Fallback: insert at the very beginning\n return fixer.insertTextBeforeRange([0, 0], \"import 'server-only';\\n\");\n },\n },\n ];\n}\n\n/**\n * Creates suggestion objects for import violations.\n * Note: Dynamic import suggestion was removed because it doesn't fix the issue -\n * it still executes server code in the client bundle.\n *\n * @param sourceCode - The source code object for finding insert positions\n * @returns Array of suggestion descriptors\n */\nfunction createImportSuggestions(\n sourceCode: TSESLint.SourceCode\n): TSESLint.SuggestionReportDescriptor<MessageIds>[] {\n return createServerOnlyMarkerSuggestion(sourceCode);\n}\n\n/**\n * Creates suggestion objects for side-effect import violations (import 'fs').\n * Only offers server-only marker since side-effect imports can't be converted.\n */\nfunction createSideEffectImportSuggestions(\n _moduleName: string,\n sourceCode: TSESLint.SourceCode\n): TSESLint.SuggestionReportDescriptor<MessageIds>[] {\n return createServerOnlyMarkerSuggestion(sourceCode);\n}\n\n/**\n * Creates suggestion objects for require violations.\n */\nfunction createRequireSuggestions(\n sourceCode: TSESLint.SourceCode\n): TSESLint.SuggestionReportDescriptor<MessageIds>[] {\n return createServerOnlyMarkerSuggestion(sourceCode);\n}\n\n/**\n * Creates suggestion objects for re-export violations.\n */\nfunction createReexportSuggestions(\n sourceCode: TSESLint.SourceCode\n): TSESLint.SuggestionReportDescriptor<MessageIds>[] {\n return createServerOnlyMarkerSuggestion(sourceCode);\n}\n\nexport const rule = createRule<Options, MessageIds>({\n name: 'no-server-imports',\n meta: {\n type: 'problem',\n docs: {\n description: 'Prevent server-only module imports in client code',\n },\n schema: [\n {\n type: 'object',\n properties: {\n serverModules: {\n type: 'array',\n items: { type: 'string' },\n description: 'Additional server-only modules to check',\n },\n serverFilePatterns: {\n type: 'array',\n items: { type: 'string' },\n description: 'Additional server-only file patterns',\n },\n clientFilePatterns: {\n type: 'array',\n items: { type: 'string' },\n description: 'File patterns that indicate client code',\n },\n ignoreFiles: {\n type: 'array',\n items: { type: 'string' },\n description: 'File patterns to ignore',\n },\n checkServerOnlyMarker: {\n type: 'boolean',\n description: \"Check for 'server-only' import marker\",\n },\n checkServerFunctions: {\n type: 'boolean',\n description: 'Check for server function usage',\n },\n serverFunctionNames: {\n type: 'array',\n items: { type: 'string' },\n description: 'Server function names to check for',\n },\n reportUnusedImports: {\n type: 'boolean',\n description: 'Whether to report unused server-only imports (default: true)',\n },\n mode: {\n type: 'string',\n enum: ['client-only', 'all-non-server'],\n description: 'File selection mode',\n },\n serverExternalPackages: {\n type: 'array',\n items: { type: 'string' },\n description: 'Next.js serverExternalPackages to treat as server-only',\n },\n },\n additionalProperties: false,\n },\n ],\n hasSuggestions: true,\n messages: {\n serverOnlyImport:\n 'Server-only module \"{{module}}\" imported in client code. Use dynamic import in a server function: const mod = await import(\"{{module}}\")',\n serverOnlyRequire:\n 'Server-only module \"{{module}}\" required in client code. Use dynamic import in a server function instead.',\n suggestServerOnlyMarker:\n \"Add import 'server-only' to mark this file as server-only\",\n },\n },\n defaultOptions: [{}],\n\n create(context: TSESLint.RuleContext<MessageIds, Options>, [options = {}]) {\n // Merge options with defaults\n const serverModules = [\n ...DEFAULT_SERVER_MODULES,\n ...(options.serverModules || []),\n ...(options.serverExternalPackages || []), // Next.js integration\n ];\n const serverFilePatterns = [\n ...DEFAULT_SERVER_FILE_PATTERNS,\n ...(options.serverFilePatterns || []),\n ];\n const clientFilePatterns =\n options.clientFilePatterns || DEFAULT_CLIENT_FILE_PATTERNS;\n const ignoreFiles = options.ignoreFiles || [];\n const checkServerOnlyMarker = options.checkServerOnlyMarker ?? true;\n const checkServerFunctions = options.checkServerFunctions ?? true;\n const serverFunctionNames = options.serverFunctionNames || [\n 'createServerFn',\n 'createIsomorphicFn',\n 'server$',\n 'action$',\n 'loader$',\n ];\n const reportUnusedImports = options.reportUnusedImports ?? true;\n const mode = options.mode || 'client-only';\n\n // Create Set for O(1) exact module lookups\n const serverModuleSet = new Set(serverModules);\n\n const rawFilename = context.getFilename();\n // Normalize Windows paths to POSIX for picomatch (backslashes are treated as escapes)\n const filename = rawFilename.replaceAll('\\\\', '/');\n const sourceCode = context.sourceCode ?? context.getSourceCode();\n\n // Track state\n let hasServerOnlyImport = false;\n\n type ServerImport = {\n module: string;\n node: TSESTree.ImportDeclaration;\n variables: TSESLint.Scope.Variable[];\n };\n\n const serverOnlyImports: ServerImport[] = [];\n\n // Track server function callback scopes (functions that run server-side)\n const serverFunctionScopes = new Set<TSESTree.Node>();\n\n /**\n * Checks if the current file should be ignored\n */\n function shouldIgnoreFile(): boolean {\n if (ignoreFiles.length > 0) {\n const isMatch = picomatch(ignoreFiles);\n if (isMatch(filename)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Checks if the file is a server-only file (based on patterns)\n */\n function isServerFile(): boolean {\n const isMatch = picomatch(serverFilePatterns);\n return isMatch(filename);\n }\n\n /**\n * Checks if the file is a client file (based on patterns)\n */\n function isClientFile(): boolean {\n const isMatch = picomatch(clientFilePatterns);\n return isMatch(filename);\n }\n\n /**\n * Checks if an import source is a server-only module\n */\n function isServerOnlyModule(importSource: string): boolean {\n // O(1) check for exact match\n if (serverModuleSet.has(importSource)) {\n return true;\n }\n // Check for subpath imports (e.g., 'fs/promises' matches 'fs')\n return serverModules.some(\n (mod) => importSource.startsWith(`${mod}/`)\n );\n }\n\n /**\n * Recursively finds the root server function call from a chained call\n * e.g., createServerFn().handler() -> finds createServerFn()\n */\n function findServerFunctionCall(node: TSESTree.CallExpression): TSESTree.CallExpression | null {\n // Check for direct call: createServerFn()\n if (\n node.callee.type === AST_NODE_TYPES.Identifier &&\n serverFunctionNames.includes(node.callee.name)\n ) {\n return node;\n }\n // Check for member call: createServerFn().handler()\n if (\n node.callee.type === AST_NODE_TYPES.MemberExpression &&\n node.callee.object.type === AST_NODE_TYPES.CallExpression\n ) {\n return findServerFunctionCall(node.callee.object);\n }\n return null;\n }\n\n /**\n * Extracts all function/arrow function arguments from a call expression chain\n */\n function extractCallbacksFromChain(node: TSESTree.CallExpression): TSESTree.Node[] {\n const callbacks: TSESTree.Node[] = [];\n\n // Walk up the call chain to collect all callbacks\n let current: TSESTree.Node = node;\n while (current.type === AST_NODE_TYPES.CallExpression) {\n // Check arguments for functions\n for (const arg of current.arguments) {\n if (\n arg.type === AST_NODE_TYPES.ArrowFunctionExpression ||\n arg.type === AST_NODE_TYPES.FunctionExpression\n ) {\n callbacks.push(arg);\n }\n }\n\n // Move to parent if it's a chained call\n if (\n current.parent?.type === AST_NODE_TYPES.MemberExpression &&\n current.parent.parent?.type === AST_NODE_TYPES.CallExpression\n ) {\n current = current.parent.parent;\n } else {\n break;\n }\n }\n\n return callbacks;\n }\n\n /**\n * Gets the string value from a require() call argument\n */\n function getRequireSource(node: TSESTree.CallExpression): string | null {\n if (\n node.callee.type === AST_NODE_TYPES.Identifier &&\n node.callee.name === 'require' &&\n node.arguments.length > 0\n ) {\n const arg = node.arguments[0];\n if (arg.type === AST_NODE_TYPES.Literal && typeof arg.value === 'string') {\n return arg.value;\n }\n }\n return null;\n }\n\n // Skip if file should be ignored\n if (shouldIgnoreFile()) {\n return {};\n }\n\n // Skip if this is a server file\n if (isServerFile()) {\n return {};\n }\n\n // File selection based on mode\n if (mode === 'client-only' && // Only check files matching clientFilePatterns\n !isClientFile()) {\n return {};\n }\n // mode === 'all-non-server': check all files except server files (already filtered above)\n\n // Track require() calls with their variables (like imports)\n type ServerRequire = {\n module: string;\n node: TSESTree.CallExpression;\n variables: readonly TSESLint.Scope.Variable[];\n };\n const serverOnlyRequires: ServerRequire[] = [];\n\n // Track require() calls that can't have their variables tracked (e.g., bare require calls)\n const bareRequireViolations: Array<{\n node: TSESTree.Node;\n module: string;\n }> = [];\n\n // Track side-effect imports (import 'fs') to report in Program:exit\n const sideEffectImportViolations: Array<{\n node: TSESTree.ImportDeclaration;\n module: string;\n }> = [];\n\n // Track re-export violations to report in Program:exit\n const reexportViolations: Array<{\n node: TSESTree.Node;\n module: string;\n }> = [];\n\n function isInsideServerScope(node: TSESTree.Node): boolean {\n for (const scope of serverFunctionScopes) {\n if (isNodeInsideScope(node, scope)) {\n return true;\n }\n }\n return false;\n }\n\n return {\n // Collect server-only imports and their local names\n ImportDeclaration(node) {\n const source = node.source.value;\n\n // Check for 'server-only' marker import\n if (checkServerOnlyMarker && source === 'server-only') {\n hasServerOnlyImport = true;\n return;\n }\n\n // Skip if not a server-only module\n if (typeof source !== 'string' || !isServerOnlyModule(source)) {\n return;\n }\n\n // Skip if all type-only\n if (!hasValueImportSpecifiers(node)) {\n return;\n }\n\n // Side-effect imports (import 'fs') have no specifiers - collect for reporting in Program:exit\n // They can't be conditionally used in server functions\n if (node.specifiers.length === 0) {\n sideEffectImportViolations.push({ node, module: source });\n return;\n }\n\n // Track this import with its declared variables\n const valueNames = new Set(getValueImportNames(node));\n const variables = sourceCode\n .getDeclaredVariables(node)\n .filter((variable) => valueNames.has(variable.name));\n\n if (variables.length > 0) {\n serverOnlyImports.push({\n module: source,\n node,\n variables,\n });\n }\n },\n\n CallExpression(node) {\n // Check for require() calls\n const requireSource = getRequireSource(node);\n if (requireSource) {\n // Check for require('server-only')\n if (checkServerOnlyMarker && requireSource === 'server-only') {\n hasServerOnlyImport = true;\n return;\n }\n\n // Check for server-only module require\n if (isServerOnlyModule(requireSource)) {\n // Try to find the variable declaration containing this require\n // Patterns: const fs = require('fs'), const { readFile } = require('fs')\n const parent = node.parent;\n if (parent?.type === AST_NODE_TYPES.VariableDeclarator) {\n const varDecl = parent.parent;\n if (varDecl?.type === AST_NODE_TYPES.VariableDeclaration) {\n const variables = sourceCode.getDeclaredVariables(varDecl);\n if (variables.length > 0) {\n serverOnlyRequires.push({\n module: requireSource,\n node,\n variables,\n });\n return;\n }\n }\n }\n // Bare require() call without variable assignment - flag immediately if outside server scope\n bareRequireViolations.push({\n node: node.arguments[0],\n module: requireSource,\n });\n }\n return;\n }\n\n // Check for server function calls\n if (!checkServerFunctions) {\n return;\n }\n\n const serverFnCall = findServerFunctionCall(node);\n if (serverFnCall) {\n // Collect all callbacks from this call chain\n const callbacks = extractCallbacksFromChain(node);\n for (const callback of callbacks) {\n serverFunctionScopes.add(callback);\n }\n }\n },\n\n // Check export declarations - collect for reporting in Program:exit\n ExportAllDeclaration(node) {\n const source = node.source.value;\n\n // ExportAllDeclaration can have exportKind for `export type * from`\n if (node.exportKind === 'type') {\n return;\n }\n\n if (typeof source === 'string' && isServerOnlyModule(source)) {\n // Collect for reporting in Program:exit\n reexportViolations.push({ node: node.source, module: source });\n }\n },\n\n ExportNamedDeclaration(node) {\n if (!node.source) return;\n const source = node.source.value;\n\n // Skip if not a server-only module\n if (typeof source !== 'string' || !isServerOnlyModule(source)) {\n return;\n }\n\n // Skip if ALL specifiers are type-only (no value exports)\n if (!hasValueExportSpecifiers(node)) {\n return;\n }\n\n // Collect for reporting in Program:exit\n reexportViolations.push({ node: node.source, module: source });\n },\n\n // Final analysis at end of file\n 'Program:exit'() {\n // Skip all violations if file has server-only marker\n if (hasServerOnlyImport) {\n return;\n }\n\n // Report side-effect import violations (import 'fs')\n for (const { node, module } of sideEffectImportViolations) {\n context.report({\n node,\n messageId: 'serverOnlyImport',\n data: { module },\n suggest: createSideEffectImportSuggestions(module, sourceCode),\n });\n }\n\n // Report re-export violations\n for (const { node, module } of reexportViolations) {\n context.report({\n node,\n messageId: 'serverOnlyImport',\n data: { module },\n suggest: createReexportSuggestions(sourceCode),\n });\n }\n\n // Report bare require violations (no variable declaration) that are outside server scopes\n for (const violation of bareRequireViolations) {\n if (!isInsideServerScope(violation.node)) {\n context.report({\n node: violation.node,\n messageId: 'serverOnlyRequire',\n data: { module: violation.module },\n suggest: createRequireSuggestions(sourceCode),\n });\n }\n }\n\n // Check each server-only require and ensure all usages stay inside server scopes\n for (const { module, node, variables } of serverOnlyRequires) {\n // If the require() call itself is inside a server scope, it's safe\n // (the variable is scoped to the server callback and can't escape)\n if (isInsideServerScope(node)) {\n continue;\n }\n\n let hasViolation = false;\n\n for (const variable of variables) {\n const valueReferences = variable.references.filter((reference) =>\n reference.isRead()\n );\n\n // If there are no reads, check reportUnusedImports option\n if (valueReferences.length === 0) {\n if (reportUnusedImports) {\n hasViolation = true;\n break;\n }\n // Skip - let no-unused-vars handle it\n continue;\n }\n\n const hasClientUsage = valueReferences.some((reference) => {\n return !isInsideServerScope(reference.identifier);\n });\n\n if (hasClientUsage) {\n hasViolation = true;\n break;\n }\n }\n\n if (hasViolation) {\n context.report({\n node: node.arguments[0],\n messageId: 'serverOnlyRequire',\n data: { module },\n suggest: createRequireSuggestions(sourceCode),\n });\n }\n }\n\n // Check each server-only import and ensure all usages stay inside server scopes\n for (const { module, node, variables } of serverOnlyImports) {\n let hasViolation = false;\n\n for (const variable of variables) {\n const valueReferences = variable.references.filter((reference) =>\n reference.isRead()\n );\n\n // If there are no reads, check reportUnusedImports option\n if (valueReferences.length === 0) {\n if (reportUnusedImports) {\n hasViolation = true;\n break;\n }\n // Skip - let no-unused-vars handle it\n continue;\n }\n\n const hasClientUsage = valueReferences.some((reference) => {\n return !isInsideServerScope(reference.identifier);\n });\n\n if (hasClientUsage) {\n hasViolation = true;\n break;\n }\n }\n\n if (hasViolation) {\n context.report({\n node: node.source,\n messageId: 'serverOnlyImport',\n data: { module },\n suggest: createImportSuggestions(sourceCode),\n });\n }\n }\n },\n };\n },\n});\n\n// Re-export framework detection utilities\nexport {\n detectFramework,\n getFrameworkDefaults,\n clearFrameworkCache,\n FRAMEWORK_DEFAULTS,\n} from './framework-detection';\nexport type { DetectedFramework, FrameworkDefaults } from './framework-detection';\n\nimport { FRAMEWORK_DEFAULTS } from './framework-detection';\n\n/** Plugin configuration */\nconst plugin = {\n rules: {\n 'no-server-imports': rule,\n },\n configs: {\n /**\n * Recommended config - uses sensible defaults that work across frameworks.\n * For framework-specific optimizations, use one of the framework presets.\n */\n recommended: {\n plugins: ['no-server-imports'],\n rules: {\n 'no-server-imports/no-server-imports': 'error',\n },\n },\n\n /**\n * Next.js optimized configuration.\n * Best for Next.js App Router and Pages Router projects.\n */\n 'recommended-next': {\n plugins: ['no-server-imports'],\n rules: {\n 'no-server-imports/no-server-imports': [\n 'error',\n {\n clientFilePatterns: FRAMEWORK_DEFAULTS.next.clientFilePatterns,\n serverFilePatterns: FRAMEWORK_DEFAULTS.next.serverFilePatterns,\n },\n ],\n },\n },\n\n /**\n * Astro optimized configuration.\n * Best for Astro projects with islands architecture.\n */\n 'recommended-astro': {\n plugins: ['no-server-imports'],\n rules: {\n 'no-server-imports/no-server-imports': [\n 'error',\n {\n clientFilePatterns: FRAMEWORK_DEFAULTS.astro.clientFilePatterns,\n serverFilePatterns: FRAMEWORK_DEFAULTS.astro.serverFilePatterns,\n },\n ],\n },\n },\n\n /**\n * SvelteKit optimized configuration.\n * Best for SvelteKit projects.\n */\n 'recommended-sveltekit': {\n plugins: ['no-server-imports'],\n rules: {\n 'no-server-imports/no-server-imports': [\n 'error',\n {\n clientFilePatterns: FRAMEWORK_DEFAULTS.sveltekit.clientFilePatterns,\n serverFilePatterns: FRAMEWORK_DEFAULTS.sveltekit.serverFilePatterns,\n },\n ],\n },\n },\n },\n meta: {\n name: 'eslint-plugin-no-server-imports',\n },\n} as const;\n\nexport default plugin;\n","/**\n * Framework Auto-Detection\n * ========================\n * Automatically detects the frontend framework being used and provides\n * optimal default configurations for the no-server-imports rule.\n */\n\nimport { existsSync, readFileSync, statSync } from 'node:fs';\nimport path from 'node:path';\n\nexport type DetectedFramework = 'next' | 'astro' | 'sveltekit' | 'unknown';\n\nexport interface FrameworkDefaults {\n clientFilePatterns: string[];\n serverFilePatterns: string[];\n}\n\n/**\n * Framework-specific default configurations\n */\nexport const FRAMEWORK_DEFAULTS: Record<DetectedFramework, FrameworkDefaults> = {\n next: {\n clientFilePatterns: [\n '**/app/**',\n '**/src/app/**',\n '**/pages/**',\n '**/components/**',\n ],\n serverFilePatterns: [\n '**/*.server.ts',\n '**/*.server.tsx',\n '**/api/**',\n '**/server/**',\n '**/actions/**',\n ],\n },\n astro: {\n clientFilePatterns: [\n '**/src/pages/**',\n '**/src/components/**',\n '**/src/islands/**',\n ],\n serverFilePatterns: [\n '**/*.server.ts',\n '**/*.server.tsx',\n '**/server/**',\n '**/api/**/*.ts',\n ],\n },\n sveltekit: {\n clientFilePatterns: [\n '**/src/routes/**',\n '**/src/lib/components/**',\n ],\n serverFilePatterns: [\n '**/*.server.ts',\n '**/*.server.js',\n '**/+server.ts',\n '**/+server.js',\n '**/+page.server.ts',\n '**/+layout.server.ts',\n ],\n },\n unknown: {\n clientFilePatterns: [\n '**/routes/**',\n '**/pages/**',\n '**/components/**',\n '**/islands/**',\n '**/src/app/**',\n ],\n serverFilePatterns: [\n '**/*.server.ts',\n '**/*.server.tsx',\n '**/*.server.js',\n '**/server/**',\n '**/api/**',\n '**/_server/**',\n ],\n },\n};\n\n/**\n * Finds the root directory of the project by looking for package.json\n */\nfunction findProjectRoot(startDir: string): string | null {\n let current = startDir;\n\n // Walk up the directory tree looking for package.json\n while (current !== path.dirname(current)) {\n if (existsSync(path.join(current, 'package.json'))) {\n return current;\n }\n current = path.dirname(current);\n }\n\n return null;\n}\n\n/**\n * Checks if a config file exists with any common extension\n */\nfunction configExists(dir: string, baseName: string): boolean {\n const extensions = ['.js', '.mjs', '.cjs', '.ts', '.mts'];\n return extensions.some(ext => existsSync(path.join(dir, `${baseName}${ext}`)));\n}\n\n/**\n * Package.json structure for dependency checking\n */\ninterface PackageJson {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n}\n\n/**\n * Reads package.json and checks for framework dependencies\n */\nfunction checkPackageJsonDependencies(projectRoot: string): DetectedFramework {\n const packageJsonPath = path.join(projectRoot, 'package.json');\n\n if (!existsSync(packageJsonPath)) {\n return 'unknown';\n }\n\n try {\n const content = readFileSync(packageJsonPath, 'utf8');\n const pkg = JSON.parse(content) as PackageJson;\n const allDeps: Record<string, string> = {\n ...pkg.dependencies,\n ...pkg.devDependencies,\n };\n\n // Check for framework dependencies (in order of specificity)\n if (allDeps['next']) {\n return 'next';\n }\n if (allDeps['@sveltejs/kit']) {\n return 'sveltekit';\n }\n if (allDeps['astro']) {\n return 'astro';\n }\n } catch {\n // Ignore parse errors\n }\n\n return 'unknown';\n}\n\n/**\n * Detects the framework by checking config files\n */\nfunction checkConfigFiles(projectRoot: string): DetectedFramework {\n // Check for framework-specific config files (most reliable)\n if (configExists(projectRoot, 'next.config')) {\n return 'next';\n }\n if (configExists(projectRoot, 'svelte.config')) {\n return 'sveltekit';\n }\n if (configExists(projectRoot, 'astro.config')) {\n return 'astro';\n }\n\n return 'unknown';\n}\n\n// Cache the detection result to avoid repeated file system checks\nlet cachedFramework: DetectedFramework | null = null;\nlet cachedProjectRoot: string | null = null;\n\n/**\n * Determines if a path is a directory\n */\nfunction isDirectory(filePath: string): boolean {\n try {\n return existsSync(filePath) && statSync(filePath).isDirectory();\n } catch {\n return false;\n }\n}\n\n/**\n * Detects the framework being used in the project.\n *\n * Detection priority:\n * 1. Config files (most reliable): next.config.*, astro.config.*, svelte.config.*\n * 2. Package.json dependencies: \"next\", \"astro\", \"@sveltejs/kit\"\n *\n * @param filePath - Path to a file or directory in the project (used to find project root)\n * @returns The detected framework or 'unknown'\n */\nexport function detectFramework(filePath?: string): DetectedFramework {\n // Try to find project root from the file path or cwd\n // If filePath is a directory, use it directly; if it's a file, use its parent\n let startDir: string;\n if (!filePath) {\n startDir = process.cwd();\n } else if (isDirectory(filePath)) {\n startDir = filePath;\n } else {\n startDir = path.dirname(filePath);\n }\n const projectRoot = findProjectRoot(startDir) || process.cwd();\n\n // Return cached result if same project\n if (cachedProjectRoot === projectRoot && cachedFramework !== null) {\n return cachedFramework;\n }\n\n // Try config files first (most reliable)\n let framework = checkConfigFiles(projectRoot);\n\n // Fall back to package.json\n if (framework === 'unknown') {\n framework = checkPackageJsonDependencies(projectRoot);\n }\n\n // Cache the result\n cachedProjectRoot = projectRoot;\n cachedFramework = framework;\n\n return framework;\n}\n\n/**\n * Gets the default configuration for the detected framework.\n *\n * @param filePath - Path to a file in the project (used for detection)\n * @returns Framework-specific defaults\n */\nexport function getFrameworkDefaults(filePath?: string): FrameworkDefaults {\n const framework = detectFramework(filePath);\n return FRAMEWORK_DEFAULTS[framework];\n}\n\n/**\n * Clears the cached framework detection (useful for testing)\n */\nexport function clearFrameworkCache(): void {\n cachedFramework = null;\n cachedProjectRoot = null;\n}\n"],"mappings":"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","names":["path","picomatch","module"]}