import fs from 'node:fs'; import path from 'node:path'; import type { Environment, NormalizedExtendConfigOptions } from './config'; import type { Middleware } from './middleware'; import { reactQuery, storybook, vitest } from './presets/misc'; import { react, reactRefresh } from './presets/react'; type Pkg = typeof import('../package.json'); type Dependency = keyof Pkg['dependencies'] | RemoveType; type RemoveType = T extends `@types/${infer U}__${infer V}` ? `@${U}/${V}` : T extends `@types/${infer U}` ? U : T; export const middlewares = { react, reactRefresh, tailwind: () => import('./presets/tailwind'), storybook, reactQuery, testingLibrary: () => import('./presets/testing-library'), jsdoc: () => import('./presets/jsdoc'), vitest, } satisfies { [key in Environment]: Middleware; }; export const envs: { dependency: string[]; eslintPlugin?: Dependency; middleware: keyof typeof middlewares; }[] = [ { dependency: ['react'], middleware: 'react', }, { dependency: ['@vitejs/plugin-react', '@vitejs/plugin-react-swc'], eslintPlugin: 'eslint-plugin-react-refresh', middleware: 'reactRefresh', }, { dependency: ['tailwindcss'], eslintPlugin: 'eslint-plugin-tailwindcss', middleware: 'tailwind', }, { dependency: ['storybook'], eslintPlugin: 'eslint-plugin-storybook', middleware: 'storybook', }, { dependency: ['@tanstack/react-query'], eslintPlugin: '@tanstack/eslint-plugin-query', middleware: 'reactQuery', }, { dependency: ['@testing-library/react'], eslintPlugin: 'eslint-plugin-testing-library', middleware: 'testingLibrary', }, { dependency: ['vitest'], eslintPlugin: '@vitest/eslint-plugin', middleware: 'vitest', }, ]; export function getProjectDependencies() { const rootDir = process.cwd(); const pkgJsonPath = path.resolve(rootDir, 'package.json'); const pkgJson = fs.existsSync(pkgJsonPath) ? (JSON.parse(fs.readFileSync(pkgJsonPath, 'utf8')) as { dependencies?: Record; devDependencies?: Record; peerDependencies?: Record; }) : {}; return new Set( Object.keys({ ...pkgJson.dependencies, ...pkgJson.devDependencies, ...pkgJson.peerDependencies, }), ); } export function* checkEnv(): Generator { const deps = getProjectDependencies(); for (const { dependency, eslintPlugin, middleware } of envs) { if ( dependency.some(dep => deps.has(dep)) && (!eslintPlugin || deps.has(eslintPlugin)) ) { yield middlewares[middleware]; } } } export function* fromEnvironments(envs: NormalizedExtendConfigOptions['env']) { for (const [env, enabled] of Object.entries(envs ?? {}) as [Environment, boolean][]) { if (enabled) { yield middlewares[env]; } } }