Helper functions for configuration manipulation, plugin management, and environment detection.
Utilities for combining and manipulating ESLint configurations.
/**
* Combine array and non-array configs into a single array
* @param configs - Configuration items or arrays to combine
* @returns Promise resolving to flattened config array
*/
function combine(
...configs: Awaitable<TypedFlatConfigItem | TypedFlatConfigItem[]>[]
): Promise<TypedFlatConfigItem[]>;Usage Examples:
import { combine, javascript, typescript, vue } from "@antfu/eslint-config";
// Combine multiple configurations
const combinedConfig = await combine(
await javascript(),
await typescript(),
await vue(),
{
name: 'custom-rules',
rules: {
'no-console': 'warn',
},
}
);Functions for renaming plugins and rules to use shorter, more convenient names.
/**
* Rename plugin prefixes in a rule object
* @param rules - Record of rules to rename
* @param map - Mapping of old prefixes to new prefixes
* @returns Record with renamed rule keys
*/
function renameRules(
rules: Record<string, any>,
map: Record<string, string>
): Record<string, any>;
/**
* Rename plugin names in flat configs array
* @param configs - Array of flat config items
* @param map - Mapping of old plugin names to new names
* @returns Array with renamed plugins and rules
*/
function renamePluginInConfigs(
configs: TypedFlatConfigItem[],
map: Record<string, string>
): TypedFlatConfigItem[];Usage Examples:
import { renameRules, renamePluginInConfigs } from "@antfu/eslint-config";
// Rename rules
const renamedRules = renameRules(
{
'@typescript-eslint/no-unused-vars': 'error',
'@stylistic/indent': ['error', 2],
},
{
'@typescript-eslint': 'ts',
'@stylistic': 'style',
}
);
// Result: { 'ts/no-unused-vars': 'error', 'style/indent': ['error', 2] }
// Rename plugins in configs
const configsWithRenamedPlugins = renamePluginInConfigs(
someConfigs,
{
'@typescript-eslint': 'ts',
'@stylistic': 'style',
}
);Functions for detecting the runtime environment and adjusting behavior accordingly.
/**
* Detect if running in editor environment
* @returns Boolean indicating if in editor (VS Code, JetBrains, Vim, etc.)
*/
function isInEditorEnv(): boolean;
/**
* Detect if running in git hooks or lint-staged context
* @returns Boolean indicating if in git hooks/lint-staged
*/
function isInGitHooksOrLintStaged(): boolean;Usage Examples:
import { isInEditorEnv, isInGitHooksOrLintStaged } from "@antfu/eslint-config";
// Conditional rule configuration based on environment
const isEditor = isInEditorEnv();
const isGitHook = isInGitHooksOrLintStaged();
const config = {
rules: {
// Disable certain rules in editor for better DX
'no-console': isEditor ? 'off' : 'warn',
// More strict in git hooks
'unused-imports/no-unused-imports': isGitHook ? 'error' : 'warn',
},
};Functions for checking and managing package dependencies.
/**
* Check if package exists in scope
* @param name - Package name to check
* @returns Boolean indicating if package exists
*/
function isPackageInScope(name: string): boolean;
/**
* Ensure required packages are installed, with interactive prompts
* @param packages - Array of package names (undefined entries ignored)
* @returns Promise that resolves when packages are confirmed/installed
*/
function ensurePackages(packages: (string | undefined)[]): Promise<void>;Usage Examples:
import { isPackageInScope, ensurePackages } from "@antfu/eslint-config";
// Check if TypeScript is available
const hasTypeScript = isPackageInScope('typescript');
// Ensure required packages for React config
await ensurePackages([
'@eslint-react/eslint-plugin',
'eslint-plugin-react-hooks',
'eslint-plugin-react-refresh',
]);Generic utility functions for data manipulation and type handling.
/**
* Convert value to array if not already an array
* @param value - Value to convert to array
* @returns Array containing the value(s)
*/
function toArray<T>(value: T | T[]): T[];
/**
* Handle default export interop for dynamic imports
* @param m - Module or promise resolving to module
* @returns Promise resolving to default export or module itself
*/
function interopDefault<T>(m: Awaitable<T>): Promise<T extends { default: infer U } ? U : T>;Usage Examples:
import { toArray, interopDefault } from "@antfu/eslint-config";
// Normalize to array
const files = toArray('src/**/*.ts'); // ['src/**/*.ts']
const multipleFiles = toArray(['src/**/*.ts', 'test/**/*.ts']); // unchanged
// Handle dynamic import with default export
const plugin = await interopDefault(import('some-eslint-plugin'));Utility parser for non-JavaScript files in ESLint contexts.
/**
* Plain text parser for ESLint
* Provides minimal AST for non-JavaScript files
*/
const parserPlain: {
meta: { name: string };
parseForESLint: (code: string) => {
ast: {
body: any[];
comments: any[];
loc: { end: number; start: number };
range: [number, number];
tokens: any[];
type: 'Program';
};
scopeManager: null;
services: { isPlain: true };
visitorKeys: { Program: never[] };
};
};Usage Examples:
import { parserPlain } from "@antfu/eslint-config";
// Use plain parser for non-JS files
const config = {
files: ['**/*.md', '**/*.txt'],
languageOptions: {
parser: parserPlain,
},
rules: {
// Rules that work with plain text
},
};Supporting type definitions for utility functions.
type Awaitable<T> = T | Promise<T>;
interface TypedFlatConfigItem extends Omit<Linter.Config, 'plugins' | 'rules'> {
plugins?: Record<string, any>;
rules?: Rules;
}
type Rules = Record<string, Linter.RuleEntry<any> | undefined> & RuleOptions;