eslint-rules/src/environment.ts
2025-02-05 18:55:12 -05:00

113 lines
2.9 KiB
TypeScript

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<keyof Pkg['devDependencies']>;
type RemoveType<T extends string> = 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<string, string>;
devDependencies?: Record<string, string>;
peerDependencies?: Record<string, string>;
})
: {};
return new Set(
Object.keys({
...pkgJson.dependencies,
...pkgJson.devDependencies,
...pkgJson.peerDependencies,
}),
);
}
export function* checkEnv(): Generator<Middleware> {
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];
}
}
}