UNPKG

@bfra.me/eslint-config

Version:
86 lines (78 loc) 2.7 kB
import type {Config} from '../config' import type {Flatten, OptionsFiles, OptionsOverrides} from '../options' import {GLOB_SRC} from '../globs' import {anyParser} from '../parsers/any-parser' import {requireOf} from '../require-of' import {interopDefault} from '../utils' import {fallback} from './fallback' /** * Configuration options for Next.js ESLint rules. * * Extends the base configuration options with file pattern matching * and rule override capabilities specifically tailored for Next.js projects. * * @extends `Flatten<OptionsFiles & OptionsOverrides>` */ export interface NextjsOptions extends Flatten<OptionsFiles & OptionsOverrides> {} function normalizeRules(rules: Record<string, any>): Record<string, any> { return Object.fromEntries( Object.entries(rules).map(([key, value]) => [key, typeof value === 'string' ? [value] : value]), ) } /** * Creates ESLint configuration for Next.js projects. * * @param options - Configuration options for the Next.js ESLint setup * @param options.files - File patterns to apply the configuration to (defaults to GLOB_SRC) * @param options.overrides - Rule overrides to apply on top of the default Next.js rules * @returns Promise resolving to an array of ESLint configurations including plugin setup and rules */ export async function nextjs(options: NextjsOptions = {}): Promise<Config[]> { const {files = [GLOB_SRC], overrides = {}} = options return requireOf( ['@next/eslint-plugin-next'], async (): Promise<Config[]> => { const pluginNextJs = await interopDefault(import('@next/eslint-plugin-next')) function getRules(name: keyof typeof pluginNextJs.configs) { const rules = pluginNextJs.configs?.[name]?.rules if (!rules) { throw new Error( `[@bfra.me/eslint-config] No rules found for @next/eslint-plugin-next config: ${name}`, ) } return normalizeRules(rules) } return [ { name: '@bfra.me/nextjs/setup', plugins: {'@next/next': pluginNextJs}, }, { name: '@bfra.me/nextjs/rules', files, languageOptions: { parserOptions: { ecmaFeatures: {jsx: true}, }, sourceType: 'module', }, rules: { ...getRules('recommended'), ...getRules('core-web-vitals'), ...overrides, }, settings: { react: {version: 'detect'}, }, }, ] }, async missingList => fallback(missingList, { files, languageOptions: { parser: anyParser, }, }), ) }