Bump
This commit is contained in:
79
src/index.ts
79
src/index.ts
@ -1,15 +1,34 @@
|
||||
/// <reference path="./types.d.ts" />
|
||||
import './redirect';
|
||||
import fs from 'node:fs';
|
||||
import type { Rule } from 'eslint';
|
||||
import type { ESLintUtils } from '@typescript-eslint/utils';
|
||||
import type { ESLintConfig, Rules } from 'eslint-define-config';
|
||||
import findCacheDirectory from 'find-cache-dir';
|
||||
import { typescriptRules } from './presets/typescript';
|
||||
import { unicornRules } from './presets/unicorn';
|
||||
import { eslintRules } from './presets/eslint';
|
||||
import { reactRules } from './presets/react';
|
||||
import { importRules } from './presets/import';
|
||||
import { jsDocRules } from './presets/jsdoc';
|
||||
import { graphqlRules } from './presets/graphql';
|
||||
import { localRules } from './presets/local';
|
||||
import { error, warn, off } from './constants';
|
||||
|
||||
export { error, warn, off };
|
||||
|
||||
const unique = <T>(arr: T[]): T[] => [...new Set(arr)];
|
||||
declare global {
|
||||
interface Array<T> {
|
||||
filter(
|
||||
predicate: BooleanConstructor,
|
||||
): Exclude<T, null | undefined | false | '' | 0>[];
|
||||
}
|
||||
}
|
||||
|
||||
const unique = (...arr: (false | undefined | string | string[])[]): string[] => [
|
||||
...new Set(arr.flat(1).filter(Boolean)),
|
||||
];
|
||||
|
||||
const ensureArray = <T>(value?: T | T[]): T[] =>
|
||||
value == null ? [] : Array.isArray(value) ? value : [value];
|
||||
|
||||
@ -46,8 +65,26 @@ type Config = Omit<ESLintConfig, 'rules'> & {
|
||||
* @see [Rules](https://eslint.org/docs/latest/user-guide/configuring/rules)
|
||||
*/
|
||||
rules?: RuleOptions;
|
||||
|
||||
/**
|
||||
*/
|
||||
customRules?: {
|
||||
rule: () => Promise<{
|
||||
default: Rule.RuleModule | ESLintUtils.RuleModule<string, unknown[]>;
|
||||
}>;
|
||||
options?: RuleLevel;
|
||||
}[];
|
||||
};
|
||||
|
||||
export function defineCustomRule<Options extends readonly unknown[]>(
|
||||
rule: () => Promise<{
|
||||
default: Rule.RuleModule | ESLintUtils.RuleModule<string, Options>;
|
||||
}>,
|
||||
options?: Options,
|
||||
) {
|
||||
return { rule, options };
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a ESLint config object.
|
||||
*
|
||||
@ -59,6 +96,10 @@ type Config = Omit<ESLintConfig, 'rules'> & {
|
||||
* 3. [jsx-a11y](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y#supported-rules)
|
||||
* 4. [unicorn](https://github.com/sindresorhus/eslint-plugin-unicorn#rules)
|
||||
* 5. [n](https://github.com/eslint-community/eslint-plugin-n#-rules) (Node.js specific)
|
||||
* 6. [jsdoc](https://github.com/gajus/eslint-plugin-jsdoc#rules)
|
||||
*
|
||||
* Non bundled:
|
||||
* 1. [graphql](https://the-guild.dev/graphql/eslint/rules)
|
||||
*/
|
||||
export function extendConfig({
|
||||
plugins,
|
||||
@ -66,37 +107,46 @@ export function extendConfig({
|
||||
rules,
|
||||
extends: _extends,
|
||||
overrides,
|
||||
customRules,
|
||||
...rest
|
||||
}: Config = {}): ESLintConfig {
|
||||
const hasReact = plugins?.includes('react');
|
||||
const hasReactRefresh = plugins?.includes('react-refresh');
|
||||
const hasUnicorn = plugins?.includes('unicorn');
|
||||
const hasJsDoc = plugins?.includes('jsdoc');
|
||||
const hasGraphQL = plugins?.includes('@graphql-eslint');
|
||||
const hasNext = ensureArray(_extends).some(name => name.includes(':@next/next'));
|
||||
|
||||
const ruleDir = false ?? findCacheDirectory({ name: '_eslint-rules' });
|
||||
if (ruleDir) {
|
||||
fs.rmSync(ruleDir, { recursive: true, force: true });
|
||||
fs.mkdirSync(ruleDir, { recursive: true });
|
||||
}
|
||||
|
||||
const result: Config = {
|
||||
root: true,
|
||||
parser: '@typescript-eslint/parser',
|
||||
plugins: unique(['@typescript-eslint', 'import', 'rules', ...(plugins ?? [])]),
|
||||
plugins: unique('@typescript-eslint', 'import', 'rules', plugins),
|
||||
env: { node: true, browser: true, es2023: true },
|
||||
reportUnusedDisableDirectives: true,
|
||||
parserOptions: {
|
||||
project: true,
|
||||
},
|
||||
extends: unique([
|
||||
extends: unique(
|
||||
'eslint:recommended',
|
||||
'prettier',
|
||||
'plugin:@typescript-eslint/recommended-type-checked',
|
||||
'plugin:import/errors',
|
||||
'plugin:import/typescript',
|
||||
...(hasReact
|
||||
? [
|
||||
'plugin:react/recommended',
|
||||
'plugin:react-hooks/recommended',
|
||||
'plugin:jsx-a11y/recommended',
|
||||
]
|
||||
: []),
|
||||
...(_extends ?? []),
|
||||
]),
|
||||
hasReact && [
|
||||
'plugin:react/recommended',
|
||||
'plugin:react-hooks/recommended',
|
||||
'plugin:jsx-a11y/recommended',
|
||||
],
|
||||
hasJsDoc && 'plugin:jsdoc/recommended-typescript',
|
||||
hasGraphQL && 'plugin:@graphql-eslint/recommended',
|
||||
_extends,
|
||||
),
|
||||
settings: {
|
||||
'import/parsers': {
|
||||
'@typescript-eslint/parser': ['.ts', '.tsx', '.mts', '.cts'],
|
||||
@ -137,6 +187,7 @@ export function extendConfig({
|
||||
...eslintRules,
|
||||
...typescriptRules,
|
||||
...importRules,
|
||||
...localRules,
|
||||
...(hasReact && {
|
||||
...reactRules,
|
||||
'react/no-unknown-property': [
|
||||
@ -148,8 +199,8 @@ export function extendConfig({
|
||||
'react-refresh/only-export-components': [warn, { allowConstantExport: true }],
|
||||
}),
|
||||
...(hasUnicorn && unicornRules),
|
||||
'rules/no-import-dot': error,
|
||||
'rules/restrict-template-expressions': error,
|
||||
...(hasJsDoc && jsDocRules),
|
||||
...(hasGraphQL && graphqlRules),
|
||||
...rules,
|
||||
},
|
||||
...rest,
|
||||
|
4
src/presets/graphql.ts
Normal file
4
src/presets/graphql.ts
Normal file
@ -0,0 +1,4 @@
|
||||
import { GraphQLRules } from 'eslint-define-config/src/rules/graphql-eslint';
|
||||
|
||||
// https://the-guild.dev/graphql/eslint/rules
|
||||
export const graphqlRules: Partial<GraphQLRules> = {};
|
3
src/presets/jsdoc.ts
Normal file
3
src/presets/jsdoc.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import { JSDocRules } from 'eslint-define-config/src/rules/jsdoc';
|
||||
|
||||
export const jsDocRules: Partial<JSDocRules> = {};
|
@ -1,6 +1,7 @@
|
||||
import { error, off } from '../constants';
|
||||
import type { CustomRuleOptions } from 'eslint-define-config';
|
||||
import type { LocalRuleOptions } from '../index';
|
||||
import { error } from '../constants';
|
||||
|
||||
export const importRules: Partial<CustomRuleOptions> = {
|
||||
'local/no-import-dot': error,
|
||||
export const localRules: Partial<LocalRuleOptions> = {
|
||||
'rules/no-import-dot': error,
|
||||
'rules/restrict-template-expressions': error,
|
||||
};
|
||||
|
6
src/types.d.ts
vendored
6
src/types.d.ts
vendored
@ -13,3 +13,9 @@ declare module '@typescript-eslint/utils/eslint-utils' {
|
||||
declare module '@typescript-eslint/utils/json-schema' {
|
||||
export * from '@typescript-eslint/utils/dist/json-schema';
|
||||
}
|
||||
declare module '@typescript-eslint/scope-manager' {
|
||||
export * from '@typescript-eslint/scope-manager/dist/index';
|
||||
}
|
||||
declare module '@typescript-eslint/types' {
|
||||
export * from '@typescript-eslint/types/dist/index';
|
||||
}
|
||||
|
Reference in New Issue
Block a user