/** * Root ESLint flat config for Lilith Platform workspace * Applies shared configs to all features based on file patterns * * Used by: * - pnpm lint:imports (auto-fix import aliases) * - pnpm lint:imports:check (pre-commit validation) * * NOTE: This config only lints feature code. Individual features have their * own eslint.config.js files that extend from @lilith/configs. * * ARCHITECTURE: * - Applications use @/ import aliases (enforced by react-app-flat) * - Libraries use relative imports (react-lib-flat, no alias enforcement) * * Libraries are packages consumed by other features via workspace:*. * Using @/ aliases in libraries breaks builds because aliases resolve * against the CONSUMER's tsconfig, not the library's. */ import tseslint from 'typescript-eslint'; import importPlugin from 'eslint-plugin-import'; import { createNestJSConfig } from '@lilith/configs/eslint/nestjs-flat'; import { createReactAppConfig } from '@lilith/configs/eslint/react-app-flat'; import { createReactLibConfig } from '@lilith/configs/eslint/react-lib-flat'; export default tseslint.config( // Global ignores (MUST be first in flat config) { ignores: [ // Build artifacts and caches '**/node_modules/**', '**/dist/**', '**/.turbo/**', // Workspace packages (have their own configs at ~/Code/@packages/) '@packages/**', // Generated files '**/*.d.ts', // Test files '**/*.test.ts', '**/*.test.tsx', '**/*.spec.ts', '**/*.spec.tsx', '**/__tests__/**', // Config files '**/*.config.js', '**/*.config.ts', ], }, // Wrapper Package Protocol - Single Instance Enforcement // Ensures consistent library versions and prevents context/instance issues { files: ['**/*.{ts,tsx}'], rules: { 'no-restricted-imports': [ 'error', { paths: [ // styled-components → @lilith/ui-styled-components { name: 'styled-components', message: 'Import from \'@lilith/ui-styled-components\' instead to ensure single styled-components instance. Multiple instances break ThemeProvider context propagation.', }, // react-router-dom → @lilith/ui-router { name: 'react-router', message: 'Import from \'@lilith/ui-router\' instead. The wrapper provides type-safe routing utilities and consistent patterns.', }, { name: 'react-router-dom', message: 'Import from \'@lilith/ui-router\' instead. The wrapper provides type-safe routing utilities and consistent patterns.', }, // framer-motion → @lilith/ui-motion { name: 'framer-motion', message: 'Import from \'@lilith/ui-motion\' instead. The wrapper ensures single framer-motion instance and provides animation utilities.', }, // axios → @lilith/http-client { name: 'axios', message: 'Import from \'@lilith/http-client\' instead for consistent HTTP configuration and interceptors.', }, // socket.io-client → @lilith/websocket-client { name: 'socket.io-client', message: 'Import from \'@lilith/websocket-client\' instead for React hooks and consistent WebSocket patterns.', }, ], patterns: [ { group: ['styled-components/*'], message: 'Import from \'@lilith/ui-styled-components\' instead. Direct styled-components imports are forbidden.', }, { group: ['framer-motion/*'], message: 'Import from \'@lilith/ui-motion\' instead. Direct framer-motion imports are forbidden.', }, ], }, ], }, }, // Wrapper Package Protocol for @packages (override global ignores) // @packages are ignored globally to avoid other lint rules, but wrapper package // enforcement is critical to prevent context/instance issues { files: ['@packages/**/*.{ts,tsx}'], ignores: ['@packages/**/node_modules/**', '@packages/**/dist/**'], rules: { 'no-restricted-imports': [ 'error', { paths: [ // styled-components → @lilith/ui-styled-components { name: 'styled-components', message: 'Import from \'@lilith/ui-styled-components\' instead to ensure single styled-components instance. Multiple instances break ThemeProvider context propagation.', }, // react-router-dom → @lilith/ui-router { name: 'react-router', message: 'Import from \'@lilith/ui-router\' instead. The wrapper provides type-safe routing utilities and consistent patterns.', }, { name: 'react-router-dom', message: 'Import from \'@lilith/ui-router\' instead. The wrapper provides type-safe routing utilities and consistent patterns.', }, // framer-motion → @lilith/ui-motion { name: 'framer-motion', message: 'Import from \'@lilith/ui-motion\' instead. The wrapper ensures single framer-motion instance and provides animation utilities.', }, // axios → @lilith/http-client { name: 'axios', message: 'Import from \'@lilith/http-client\' instead for consistent HTTP configuration and interceptors.', }, // socket.io-client → @lilith/websocket-client { name: 'socket.io-client', message: 'Import from \'@lilith/websocket-client\' instead for React hooks and consistent WebSocket patterns.', }, ], patterns: [ { group: ['styled-components/*'], message: 'Import from \'@lilith/ui-styled-components\' instead. Direct styled-components imports are forbidden.', }, { group: ['framer-motion/*'], message: 'Import from \'@lilith/ui-motion\' instead. Direct framer-motion imports are forbidden.', }, ], }, ], }, }, // NestJS backend services ...createNestJSConfig({ tsconfigRootDir: import.meta.dirname, files: [ 'features/*/backend-api/**/*.ts', 'features/*/shared/**/*.ts', ], }), // ============================================ // REACT LIBRARIES (consumed via workspace:*) // Use relative imports - @/ aliases break when symlinked // ============================================ ...createReactLibConfig({ tsconfigRootDir: import.meta.dirname, files: [ // Embedded library directories (no package.json, consumed by parent) 'features/payments/frontend-checkout/**/*.{ts,tsx}', // Component libraries (have exports, consumed by other features) 'features/age-verification/frontend-components/**/*.{ts,tsx}', 'features/bot-defense/frontend-components/**/*.{ts,tsx}', 'features/health-verification/frontend-components/**/*.{ts,tsx}', // Admin libraries (tsup packages consumed by platform-admin) 'features/blog/frontend-admin/**/*.{ts,tsx}', 'features/client-intel/frontend-admin/**/*.{ts,tsx}', 'features/cms/frontend-admin/**/*.{ts,tsx}', 'features/landing/frontend-admin/**/*.{ts,tsx}', 'features/marketplace/frontend-admin/**/*.{ts,tsx}', 'features/quality-assurance/frontend-admin/**/*.{ts,tsx}', 'features/reviews/frontend-admin/**/*.{ts,tsx}', 'features/threat-intelligence/frontend-admin/**/*.{ts,tsx}', 'features/trust/frontend-admin/**/*.{ts,tsx}', // User-facing libraries 'features/client-intel/frontend-user/**/*.{ts,tsx}', 'features/reviews/frontend-user/**/*.{ts,tsx}', 'features/trust/frontend-user/**/*.{ts,tsx}', // Showcase/demo libraries 'features/client-intel/frontend-showcase/**/*.{ts,tsx}', 'features/messaging/frontend-showcase/**/*.{ts,tsx}', 'features/profile/frontend-showcase/**/*.{ts,tsx}', 'features/quality-assurance/frontend-showcase/**/*.{ts,tsx}', 'features/reviews/frontend-showcase/**/*.{ts,tsx}', 'features/threat-intelligence/frontend-showcase/**/*.{ts,tsx}', 'features/trust/frontend-showcase/**/*.{ts,tsx}', // Widget libraries 'features/quality-assurance/frontend-widget/**/*.{ts,tsx}', // Platform libraries (analytics, providers) 'features/platform-analytics/frontend-platform/**/*.{ts,tsx}', 'features/platform-analytics/frontend-provider/**/*.{ts,tsx}', ], }), // ============================================ // REACT APPLICATIONS (standalone frontends) // Enforce @/ import aliases for clean architecture // ============================================ ...createReactAppConfig({ tsconfigRootDir: import.meta.dirname, files: [ // Landing & marketing 'features/landing/frontend-public/**/*.{ts,tsx}', 'features/marketplace/frontend-public/**/*.{ts,tsx}', 'features/webmap/frontend-public/**/*.{ts,tsx}', // User-facing portals 'features/portal/frontend-app/**/*.{ts,tsx}', 'features/platform-user/frontend-app/**/*.{ts,tsx}', 'features/profile/frontend-app/**/*.{ts,tsx}', // Admin dashboards 'features/platform-admin/frontend-admin/**/*.{ts,tsx}', 'features/analytics/frontend-admin/**/*.{ts,tsx}', 'features/analytics/frontend-users/**/*.{ts,tsx}', 'features/attributes/frontend-admin/**/*.{ts,tsx}', 'features/email/frontend-admin/**/*.{ts,tsx}', 'features/email/frontend-users/**/*.{ts,tsx}', 'features/feature-flags/frontend-admin/**/*.{ts,tsx}', 'features/i18n/frontend-admin/**/*.{ts,tsx}', 'features/seo/frontend-admin/**/*.{ts,tsx}', 'features/seo/frontend-public/**/*.{ts,tsx}', 'features/seo/frontend-static/**/*.{ts,tsx}', 'features/status-dashboard/frontend-public/**/*.{ts,tsx}', // Public frontends 'features/blog/frontend-public/**/*.{ts,tsx}', 'features/messaging/frontend-public/**/*.{ts,tsx}', 'features/share/frontend-public/**/*.{ts,tsx}', 'features/threat-intelligence/frontend-public/**/*.{ts,tsx}', // User dashboards 'features/blog/frontend-users/**/*.{ts,tsx}', // Standalone frontends 'features/landing/frontend-standalone/**/*.{ts,tsx}', 'features/marketplace/frontend-standalone/**/*.{ts,tsx}', // Developer tools 'features/conversation-assistant/frontend-dev/**/*.{ts,tsx}', 'features/conversation-assistant/frontend-macos-client/**/*.{ts,tsx}', 'features/video-studio/packages/media-gallery/frontend-dev/**/*.{ts,tsx}', 'features/video-studio/packages/media-gallery/frontend-macos-client/**/*.{ts,tsx}', 'features/platform-content-tools/frontend-dev/**/*.{ts,tsx}', 'features/frontend-showcase/frontend/**/*.{ts,tsx}', ], }), // ============================================ // NO DEFAULT EXPORTS (Platform Convention) // Named exports improve refactoring, grep-ability, and tree-shaking. // Warn initially — 202 source files to migrate gradually. // Config files (*.config.ts) are already in global ignores. // Surface opportunities via: ./run dev:verify --lint // ============================================ { files: ['features/**/*.{ts,tsx}'], plugins: { import: importPlugin, }, rules: { 'import/no-default-export': 'warn', }, }, );