UNPKG

@shayanthenerd/eslint-config

Version:

A modern, flexible ESLint configuration for enforcing best practices and maintaining a consistent coding style

360 lines (332 loc) 13.7 kB
import { DeepNonNullable } from "./helpers.js"; import { CSSOptions } from "./configOptions/css.js"; import { VueOptions } from "./configOptions/vue.js"; import { BaseOptions } from "./configOptions/base.js"; import { HTMLOptions } from "./configOptions/html.js"; import { NuxtOptions } from "./configOptions/nuxt.js"; import { TestOptions } from "./configOptions/test.js"; import { ImportXOptions } from "./configOptions/importX.js"; import { TailwindOptions } from "./configOptions/tailwind.js"; import { StylisticOptions } from "./configOptions/stylistic.js"; import { TypeScriptOptions } from "./configOptions/typescript.js"; import { PerfectionistOptions } from "./configOptions/perfectionist.js"; import { ConfigWithExtends } from "typescript-eslint"; import { Linter } from "eslint"; //#region src/types/index.d.ts type ConfigObject = ConfigWithExtends & { rules?: Linter.RulesRecord; }; type ConfigOverrides = Pick<ConfigObject, 'name' | 'files' | 'rules' | 'ignores' | 'plugins' | 'settings'>; interface ConfigWithOverrides { /** * Override the configuration. * * The properties of this object are merged with and take precedence over the default configuration. * * There is no guarantee that the resulting configuration works correctly — it depends on the options you provide. * * @see [eslint-flat-config-utils: `mergeConfigs`](https://jsr.io/@antfu/eslint-flat-config-utils/doc/~/mergeConfigs) */ overrides?: ConfigOverrides & { rules?: Linter.RulesRecord; languageOptions?: { parser?: DeepNonNullable<ConfigObject>['languageOptions']['parser']; globals?: DeepNonNullable<ConfigObject>['languageOptions']['globals']; }; }; } /** The options passed to the `defineConfig` function. */ interface Options { /** * Automatically enable configurations based on the detected dependencies, dev-dependencies, etc. in the _package.json_ file. * * Set to `'verbose'` to log the detected dependencies. * * Use the `packageDir` option to specify the path to the _package.json_ file. * * @default true */ autoDetectDeps?: boolean | 'verbose'; /** * Path to the _.gitignore_ file (relative to the current working directory). * * ESLint will ignore files and directories found in your _.gitignore_ file. Set to `false` to disable this behavior. * * It will fall back to the default value if set to an empty string (`''`). * * @default '.gitignore' * * @see [ESLint Ignore: Including GitIgnore Files](https://eslint.org/docs/latest/use/configure/ignore#including-gitignore-files) */ gitignore?: false | string; /** * Path to directory of the _package.json_ file (relative to the current working directory). * * This is used by * - `autoDetectDeps` option * - [import-x/no-extraneous-dependencies: `packageDir` option](https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-extraneous-dependencies.md#packagedir) * - [storybook/no-uninstalled-addons: `packageJsonLocation` option](https://github.com/storybookjs/storybook/blob/next/code/lib/eslint-plugin/docs/rules/no-uninstalled-addons.md#packagejsonlocation) * * It will fall back to the default value if set to an empty string (`''`). * * @default '.' */ packageDir?: string; /** * Specify the runtime environment to correctly resolve its built-in modules * * This is used by * [perfectionist/sort-imports: `env` option](https://perfectionist.dev/rules/sort-imports#environment) * to recognize the environment’s built-in modules when sorting the imports. * * @default 'node' */ env?: 'bun' | 'node'; /** * The path and the name of the root TypeScript config file. * * If you don't use TypeScript, provide the path and the name of the root JavaScript config file. * * This is used by * - [better-tailwindcss: `tsconfig` option](https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/settings/settings.md#tsconfig) * - [perfectionist/sort-imports: `tsconfig` option](https://perfectionist.dev/rules/sort-imports#tsconfig) * * @default undefined // `{ rootDir: '.', filename: 'tsconfig.json' }` if "typescript" is detected in the package.json file when `autoDetectDeps` is enabled */ tsConfig?: false | { /** * The directory of the root TypeScript config file. * * If you don't use TypeScript, provide the directory of the root JavaScript config file. * * It will fall back to the default value if set to an empty string (`''`). * * @default '.' */ rootDir: string; /** * The name of the root TypeScript config file. * * If you don't use TypeScript, provide the name of the root JavaScript config file. * * It will fall back to the default value if set to an empty string (`''`). * * @default 'tsconfig.json' */ filename?: string; }; /*** Global ***/ /** * Global configuration options applied to all files. Individual configurations will override these. * * @default * { * name: 'shayanthenerd/eslint-config', * basePath: '.', * linterOptions: { * noInlineConfig: true, * reportUnusedInlineConfigs: 'warn', * reportUnusedDisableDirectives: 'warn' * } * languageOptions: { * parserOptions: {}, * sourceType: 'module', * ecmaVersion: 'latest', * }, * } */ global?: { /** * A name for the configuration object. This is used in error messages and [config inspector](https://github.com/eslint/config-inspector) to help identify which configuration object is being used. * * It will fall back to the default value if set to an empty string (`''`). * * @default 'shayanthenerd/eslint-config' * * @see [ESLint Configuration: Naming Conventions](https://eslint.org/docs/latest/use/configure/configuration-files#configuration-naming-conventions) */ name?: string; /** * The base path for resolving `files` and `ignores` patterns. * * Glob patterns in the configuration objects will be resolved relative to this path. * * It will fall back to the default value if set to an empty string (`''`). * * @default '.' * * @see [ESLint Configuration: Specifying Base Path](https://eslint.org/docs/latest/use/configure/configuration-files#specifying-base-path) */ basePath?: string; /** * Patterns that ESLint should ignore globally. These patterns are resolved relative to the current working directory. * * @see [ESLint Configuration: Globally Ignoring Files](https://eslint.org/docs/latest/use/configure/configuration-files#globally-ignoring-files-with-ignores) */ ignores?: string[]; /** * Specify global variables. * * @default * { * node: true, * commonjs: false, * browser: true, * worker: true, * serviceworker: false, * webextension: false, * custom: {}, * } * * @see [Language Options: Specifying Globals: Using Configuration Files](https://eslint.org/docs/latest/use/configure/language-options#using-configuration-files) */ globals?: { node?: boolean; commonjs?: boolean; browser?: boolean; worker?: boolean; serviceworker?: boolean; webextension?: boolean; custom?: Linter.LanguageOptions['globals']; }; /** * Specify the linting process. * * @see [ESLint Configuration: Linter Options](https://eslint.org/docs/latest/use/configure/configuration-files#configuring-linter-options) */ linterOptions?: { /** * Disallow inline (comment) configurations and disable-directives. * * @default false * * @see [ESLint Configuration: Disabling Inline Configuration](https://eslint.org/docs/latest/use/configure/configuration-files#disabling-inline-configuration) */ noInlineConfig?: Linter.LintOptions['allowInlineConfig']; /** * A severity string indicating if and how unused inline configs should be tracked and reported. * * @default 'warn' * * @see [ESLint Configuration: Reporting Unused Inline Configs](https://eslint.org/docs/latest/use/configure/configuration-files#reporting-unused-inline-configs) */ reportUnusedInlineConfigs?: Linter.StringSeverity; /** * A severity string indicating if and how unused disable and enable directives should be tracked and reported. * * @default 'warn' * * @see [ESLint Configuration: Reporting Unused Disable Directives](https://eslint.org/docs/latest/use/configure/configuration-files#reporting-unused-disable-directives) */ reportUnusedDisableDirectives?: Linter.StringSeverity; }; /** * Settings shared across all rules. Use this to specify information that should be available to every rule. * * @see [ESLint Configuration: Shared Settings](https://eslint.org/docs/latest/use/configure/configuration-files#configuring-shared-settings) */ settings?: ConfigObject['settings']; /** * The available rules. * * @see [ESLint Configuration: Rules](https://eslint.org/docs/latest/use/configure/configuration-files#configuring-rules) */ rules?: Linter.RulesRecord; }; /*** Configs ***/ /** * Enable, disable, or customize the configurations. * * `autoDetectDeps` can enable configurations that are disabled by default. However, explicitly enabling or disabling a configuration takes precedence over `autoDetectDeps`. */ configs?: { /** * Use [eslint-plugin-oxlint](https://github.com/oxc-project/eslint-plugin-oxlint) to disable rules that are already handled by OXLint. * * Provide the path to your OXLint configuration file (relative to the current working directory) or set to `false` to disable it. * * Enabling this improves performance and feedback loops when using OXLint. * * It will fall back to the default value if set to an empty string (`''`). * * @default false // `'.oxlintrc.json'` if "oxlint" is detected in the package.json file when `autoDetectDeps` is enabled */ oxlint?: false | string; /** * Customize some of the JavaScript (core) rules. * * JavaScript rules cannot be turned off. */ base?: BaseOptions; /** * Use [@stylistic/eslint-plugin](https://eslint.style) to enforce stylistic rules such as indentation, line length, spacing, quotes, semicolons, etc. * * @default true */ stylistic?: boolean | StylisticOptions; /** * Use [@html-eslint/eslint-plugin](https://html-eslint.org) to enforce SEO and accessibility best practices, as well as some stylistic rules. * * @default false */ html?: boolean | HTMLOptions; /** * Use [@eslint/css](https://github.com/eslint/css) to enforce CSS best practices and identify mistakes. * * @default false // `true` if "tailwindcss" is detected in the package.json file when `autoDetectDeps` is enabled */ css?: boolean | CSSOptions; /** * Use [eslint-plugin-better-tailwindcss](https://github.com/schoero/eslint-plugin-better-tailwindcss) to sort Tailwind classes, check for unused or conflicting ones, and enforce best practices. * * @default false */ tailwind?: false | (TailwindOptions & ConfigWithOverrides); /** * Use [typescript-eslint](https://typescript-eslint.io) to enforce TypeScript-specific rules. * * Setting this to `false` doesn't prevent ESLint from linting TypeScript files. * * This enables * - [eslint-plugin-import-x](https://github.com/un-ts/eslint-plugin-import-x) to better understand imports from TypeScript files such as ".ts", ".tsx", etc. * - [eslint-plugin-vue](https://eslint.vuejs.org) to enforce TypeScript-specific rules in the `<script setup lang="ts">` of Vue SFCs. * * @default false // `true` if "typescript" is detected in the package.json file when `autoDetectDeps` is enabled */ typescript?: boolean | TypeScriptOptions; /** * Use [eslint-plugin-import-x](https://github.com/un-ts/eslint-plugin-import-x) to organize imports and exports, and detect related issues. * * @default true */ importX?: boolean | ImportXOptions; /** * Use [eslint-plugin-perfectionist](https://perfectionist.dev) to sort imports, exports, maps, union types, etc. * * @default true */ perfectionist?: boolean | PerfectionistOptions; /** * Use [eslint-plugin-vue](https://eslint.vuejs.org) to enforce Vue best practices, accessibility guidelines, stylistic rules, and identify mistakes. * * @default false // `true` if "vue" is detected in the package.json file when `autoDetectDeps` is enabled */ vue?: boolean | VueOptions; /** * Whether [Nuxt](https://nuxt.com) is used in the project. * * Enforce best practices and the use of Nuxt-specific components over their standard counterparts. For example, `<NuxtLink>` must be used instead of `<a>`, and `<NuxtTime>` instead of `<time>`. * * **This configuration requires `configs.vue` to be enabled.** * * @default false // `true` if "nuxt" is detected in the package.json file when `autoDetectDeps` is enabled */ nuxt?: boolean | NuxtOptions; /** * Configuration options for the testing tools. */ test?: TestOptions; }; } //#endregion export { type ConfigObject, type ConfigWithOverrides, type Options };