import tseslint from '@typescript-eslint/eslint-plugin' import tsparser from '@typescript-eslint/parser' import security from 'eslint-plugin-security' export default [ { ignores: ['**/dist/**', '**/node_modules/**', '**/*.js', '**/*.mjs', '**/*.cjs', '**/*.vue', '**/vite.config.ts', '**/vitest.config.ts', '**/vitest.workspace.ts', '**/drizzle.config.ts', 'server/scripts/**', 'e2e/**'], }, { files: ['**/*.ts'], languageOptions: { parser: tsparser, parserOptions: { projectService: true, }, }, plugins: { '@typescript-eslint': tseslint, security: security, }, rules: { '@typescript-eslint/no-floating-promises': 'error', 'no-console': ['warn', { allow: ['warn', 'error'] }], // Security rules (from eslint-plugin-security) 'security/detect-buffer-noassert': 'warn', 'security/detect-child-process': 'warn', 'security/detect-eval-with-expression': 'error', 'security/detect-new-buffer': 'warn', 'security/detect-non-literal-regexp': 'warn', 'security/detect-non-literal-require': 'warn', 'security/detect-possible-timing-attacks': 'warn', 'security/detect-pseudoRandomBytes': 'warn', 'security/detect-unsafe-regex': 'error', 'security/detect-bidi-characters': 'error', // detect-object-injection has too many false positives — skip // detect-non-literal-fs-filename too noisy for server code — skip }, }, // Frontend game engine: fire-and-forget async (audio, animations) is intentional { files: ['frontend/src/game/**/*.ts'], rules: { '@typescript-eslint/no-floating-promises': 'warn', }, }, ]