Compare commits

..

12 Commits

Author SHA1 Message Date
1e56001e78 New version 2024-12-15 02:30:34 -05:00
2b4c3038b3 Update 2024-12-12 19:48:39 -05:00
eb5f72a049 Bump 2024-12-08 19:14:11 -05:00
952914699b Bump version and fix glob 2024-12-01 17:51:52 -05:00
78ed00fd21 Bump version 2024-11-28 23:27:52 -05:00
43d9cc294e add default 2024-11-23 17:04:14 -05:00
235cf4101b Bump 2024-11-23 16:50:52 -05:00
f36e47f144 Update 2024-11-17 19:58:37 -05:00
97eb90f6c6 Bump 2024-11-09 21:39:15 -05:00
a1ab2ad7f5 Update 2024-11-03 20:11:26 -05:00
511652dd48 read gitignore 2024-10-20 01:55:55 -04:00
553965243f Merge pull request 'Merge flat into main' (#1) from flat into main
Reviewed-on: #1
2024-10-19 22:51:03 +00:00
24 changed files with 1892 additions and 4044 deletions

1
.gitignore vendored
View File

@ -8,6 +8,7 @@ src/types/rules
dist2 dist2
dist/**/*.js dist/**/*.js
dist/**/*.js.map dist/**/*.js.map
!dist/default.js
# Logs # Logs
logs logs

View File

@ -7,6 +7,21 @@ export type Middleware =
| (() => Promise<MiddlewareResult>) | (() => Promise<MiddlewareResult>)
| (() => Promise<{ default: MiddlewareResult }>); | (() => Promise<{ default: MiddlewareResult }>);
export interface NormalizedExtendConfigOptions {
auto?: boolean;
middlewares?: Middleware[];
configs: FlatESLintConfig[];
/**
* Use `.gitignore` file to exclude files from ESLint.
*/
gitignore?: boolean;
}
export type ExtendConfigOptions =
| FlatESLintConfig
| FlatESLintConfig[]
| NormalizedExtendConfigOptions;
/** /**
* Returns a ESLint config object. * Returns a ESLint config object.
* *
@ -26,18 +41,9 @@ export type Middleware =
* Non bundled: * Non bundled:
* 1. [`graphql`](https://the-guild.dev/graphql/eslint/rules) * 1. [`graphql`](https://the-guild.dev/graphql/eslint/rules)
* *
* @param of Configuration options.
* @returns ESLint configuration object. * @returns ESLint configuration object.
*/ */
export function extendConfig({ export function extendConfig(options?: ExtendConfigOptions): Promise<FlatESLintConfig[]>;
auto,
middlewares: addMiddlewares,
configs,
}: {
auto?: boolean;
middlewares?: Middleware[];
configs: FlatESLintConfig[];
}): Promise<FlatESLintConfig[]>;
export const error = 'error'; export const error = 'error';
export const warn = 'warn'; export const warn = 'warn';

5
dist/default.d.ts vendored Normal file
View File

@ -0,0 +1,5 @@
import type { FlatESLintConfig } from '@aet/eslint-define-config';
declare const _default: FlatESLintConfig[];
export default _default;

3
dist/default.js vendored Normal file
View File

@ -0,0 +1,3 @@
import { extendConfig } from './config/index.js';
export default await extendConfig();

2
dist/eslint-init.sh vendored Normal file
View File

@ -0,0 +1,2 @@
#!/bin/bash
echo 'export { default } from "@aet/eslint-rules/default";' > eslint.config.js

56
dist/package.json vendored
View File

@ -1,62 +1,68 @@
{ {
"name": "@aet/eslint-rules", "name": "@aet/eslint-rules",
"version": "2.0.1-beta.8", "version": "2.0.23",
"license": "UNLICENSED", "license": "UNLICENSED",
"type": "module", "type": "module",
"bin": { "bin": {
"eslint-init": "eslint-init.sh",
"eslint-install": "install.js", "eslint-install": "install.js",
"eslint-print": "print-config.sh" "eslint-print": "print-config.sh"
}, },
"main": "./config/index.js",
"peerDependencies": { "peerDependencies": {
"eslint": "^9.12.0", "eslint": "^9.15.0",
"typescript": "^5.4.4" "typescript": "^5.7.2"
},
"exports": {
".": "./config/index.js",
"./default": "./default.js",
"./prettier": "./prettier.js",
"./tsconfig": "./tsconfig.json",
"./types": "./types.js"
}, },
"optionalDependencies": { "optionalDependencies": {
"@tanstack/eslint-plugin-query": "^5.52.0" "@tanstack/eslint-plugin-query": "^5.62.1"
}, },
"dependencies": { "dependencies": {
"@antfu/install-pkg": "^0.4.1", "@aet/eslint-define-config": "^0.1.0-beta.40",
"@antfu/install-pkg": "^0.5.0",
"@eslint-community/eslint-utils": "^4.4.1",
"@eslint-react/eslint-plugin": "1.19.0",
"@eslint/js": "^9.16.0",
"@nolyfill/is-core-module": "^1.0.39", "@nolyfill/is-core-module": "^1.0.39",
"@aet/eslint-define-config": "^0.1.0-beta.28", "@stylistic/eslint-plugin": "^2.12.1",
"@eslint/js": "^9.12.0",
"@eslint-community/eslint-utils": "^4.4.0",
"@types/eslint": "^9.6.1", "@types/eslint": "^9.6.1",
"@typescript-eslint/eslint-plugin": "^8.10.0", "@typescript-eslint/eslint-plugin": "^8.18.0",
"@typescript-eslint/parser": "^8.10.0", "@typescript-eslint/parser": "^8.18.0",
"@eslint-react/eslint-plugin": "1.15.0", "@typescript-eslint/type-utils": "^8.18.0",
"@stylistic/eslint-plugin": "^2.9.0", "@typescript-eslint/utils": "^8.18.0",
"@typescript-eslint/type-utils": "^8.10.0",
"@typescript-eslint/utils": "^8.10.0",
"aria-query": "^5.3.2", "aria-query": "^5.3.2",
"axe-core": "^4.10.1", "axe-core": "^4.10.2",
"axobject-query": "4.1.0", "axobject-query": "4.1.0",
"damerau-levenshtein": "1.0.8", "damerau-levenshtein": "1.0.8",
"debug": "^4.3.7", "debug": "^4.4.0",
"doctrine": "^3.0.0", "doctrine": "^3.0.0",
"emoji-regex": "^10.4.0", "emoji-regex": "^10.4.0",
"enhanced-resolve": "^5.17.1", "enhanced-resolve": "^5.17.1",
"typescript-eslint": "^8.10.0",
"eslint-config-prettier": "^9.1.0", "eslint-config-prettier": "^9.1.0",
"eslint-import-resolver-node": "^0.3.9", "eslint-import-resolver-node": "^0.3.9",
"eslint-import-resolver-typescript": "^3.6.3", "eslint-import-resolver-typescript": "^3.7.0",
"eslint-module-utils": "^2.12.0", "eslint-module-utils": "^2.12.0",
"eslint-plugin-es-x": "^8.0.0", "eslint-plugin-import-x": "^4.5.0",
"eslint-plugin-import-x": "^4.3.1", "eslint-plugin-unicorn": "^56.0.1",
"eslint-plugin-unicorn": "^56.0.0",
"esprima": "^4.0.1", "esprima": "^4.0.1",
"esquery": "^1.6.0", "esquery": "^1.6.0",
"estraverse": "^5.3.0", "estraverse": "^5.3.0",
"fast-glob": "^3.3.2", "fast-glob": "^3.3.2",
"get-tsconfig": "^4.8.1", "get-tsconfig": "^4.8.1",
"globals": "^15.11.0", "globals": "^15.13.0",
"ignore": "^6.0.2", "ignore": "^6.0.2",
"is-bun-module": "^1.2.1", "is-bun-module": "^1.3.0",
"is-glob": "^4.0.3", "is-glob": "^4.0.3",
"language-tags": "^1.0.9", "language-tags": "^1.0.9",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"minimatch": "^10.0.1", "minimatch": "^10.0.1",
"semver": "^7.6.3" "semver": "^7.6.3",
"typescript-eslint": "^8.18.0"
}, },
"pnpm": { "pnpm": {
"overrides": { "overrides": {

2267
dist/pnpm-lock.yaml generated vendored

File diff suppressed because it is too large Load Diff

18
dist/tsconfig.json vendored Normal file
View File

@ -0,0 +1,18 @@
{
"compilerOptions": {
"allowArbitraryExtensions": true,
"allowImportingTsExtensions": true,
"jsx": "react-jsx",
"module": "Preserve",
"moduleResolution": "Bundler",
"noImplicitOverride": true,
"noImplicitReturns": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"resolveJsonModule": true,
"strict": true,
"stripInternal": true,
"target": "ESNext",
"verbatimModuleSyntax": true
}
}

View File

@ -1,28 +1,67 @@
{ {
"name": "@aet/eslint-configs", "name": "@aet/eslint-configs",
"type": "module", "type": "module",
"version": "0.0.0",
"scripts": { "scripts": {
"build": "./scripts/build.ts", "build": "./scripts/build.ts",
"check-import": "./scripts/check-imports.ts", "check-import": "./scripts/check-imports.ts",
"define": "/usr/local/bin/codium ./packages/eslint-define-config", "define": "/usr/local/bin/codium ./packages/eslint-define-config",
"do": "yarn build; (cd dist && ver bump && npm publish && ver unpub)" "sync": "./scripts/sync-deps.ts",
"do": "(cd dist && ver bump && npm publish && ver unpub)"
}, },
"private": true, "private": true,
"dependencies": {
"@aet/eslint-define-config": "^0.1.0-beta.40",
"@antfu/install-pkg": "^0.5.0",
"@eslint-community/eslint-utils": "^4.4.1",
"@eslint-react/eslint-plugin": "1.19.0",
"@eslint/js": "^9.16.0",
"@nolyfill/is-core-module": "^1.0.39",
"@stylistic/eslint-plugin": "^2.12.1",
"@types/eslint": "^9.6.1",
"@typescript-eslint/eslint-plugin": "^8.18.0",
"@typescript-eslint/parser": "^8.18.0",
"@typescript-eslint/type-utils": "^8.18.0",
"@typescript-eslint/utils": "^8.18.0",
"aria-query": "^5.3.2",
"axe-core": "^4.10.2",
"axobject-query": "4.1.0",
"damerau-levenshtein": "1.0.8",
"debug": "^4.4.0",
"doctrine": "^3.0.0",
"emoji-regex": "^10.4.0",
"enhanced-resolve": "^5.17.1",
"eslint-config-prettier": "^9.1.0",
"eslint-import-resolver-node": "^0.3.9",
"eslint-import-resolver-typescript": "^3.7.0",
"eslint-module-utils": "^2.12.0",
"eslint-plugin-import-x": "^4.5.0",
"eslint-plugin-unicorn": "^56.0.1",
"esprima": "^4.0.1",
"esquery": "^1.6.0",
"estraverse": "^5.3.0",
"fast-glob": "^3.3.2",
"get-tsconfig": "^4.8.1",
"globals": "^15.13.0",
"ignore": "^6.0.2",
"is-bun-module": "^1.3.0",
"is-glob": "^4.0.3",
"language-tags": "^1.0.9",
"lodash-es": "^4.17.21",
"minimatch": "^10.0.1",
"semver": "^7.6.3",
"typescript-eslint": "^8.18.0"
},
"devDependencies": { "devDependencies": {
"@aet/eslint-define-config": "^0.1.0-beta.29", "@babel/core": "^7.26.0",
"@antfu/install-pkg": "^0.4.1", "@babel/plugin-transform-flow-strip-types": "^7.25.9",
"@babel/core": "^7.25.8", "@babel/preset-env": "^7.26.0",
"@babel/plugin-transform-flow-strip-types": "^7.25.7", "@graphql-eslint/eslint-plugin": "^4.3.0",
"@babel/preset-env": "^7.25.8",
"@eslint-react/eslint-plugin": "^1.15.0",
"@eslint/js": "^9.13.0",
"@graphql-eslint/eslint-plugin": "^3.20.1",
"@stylistic/eslint-plugin": "^2.9.0",
"@swc-node/register": "^1.10.9", "@swc-node/register": "^1.10.9",
"@tanstack/eslint-plugin-query": "^5.59.7", "@tanstack/eslint-plugin-query": "^5.62.1",
"@types/babel-plugin-macros": "^3.1.3", "@types/babel-plugin-macros": "^3.1.3",
"@types/babel__core": "^7.20.5", "@types/babel__core": "^7.20.5",
"@types/eslint": "^9.6.1", "@types/eslint-config-prettier": "^6.11.3",
"@types/eslint-plugin-tailwindcss": "^3.17.0", "@types/eslint-plugin-tailwindcss": "^3.17.0",
"@types/eslint__js": "^8.42.3", "@types/eslint__js": "^8.42.3",
"@types/esprima": "^4.0.6", "@types/esprima": "^4.0.6",
@ -30,45 +69,31 @@
"@types/estree": "^1.0.6", "@types/estree": "^1.0.6",
"@types/estree-jsx": "^1.0.5", "@types/estree-jsx": "^1.0.5",
"@types/lodash-es": "^4.17.12", "@types/lodash-es": "^4.17.12",
"@types/node": "^22.7.7", "@types/node": "^22.10.2",
"@types/react-refresh": "^0.14.6", "@types/react-refresh": "^0.14.6",
"@typescript-eslint/eslint-plugin": "^8.10.0", "@typescript-eslint/types": "^8.18.0",
"@typescript-eslint/parser": "^8.10.0", "@typescript-eslint/typescript-estree": "^8.18.0",
"@typescript-eslint/type-utils": "^8.10.0", "@vitest/eslint-plugin": "^1.1.16",
"@typescript-eslint/types": "^8.10.0",
"@typescript-eslint/typescript-estree": "^8.10.0",
"@typescript-eslint/utils": "^8.10.0",
"babel-plugin-macros": "^3.1.0", "babel-plugin-macros": "^3.1.0",
"dts-bundle-generator": "9.5.1", "dts-bundle-generator": "9.5.1",
"esbuild": "0.24.0", "esbuild": "0.24.0",
"esbuild-plugin-alias": "^0.2.1", "esbuild-plugin-alias": "^0.2.1",
"eslint": "9.13.0", "eslint": "^9.17.0",
"eslint-config-prettier": "^9.1.0", "eslint-plugin-jsdoc": "^50.6.1",
"eslint-import-resolver-typescript": "^3.6.3", "eslint-plugin-react-refresh": "^0.4.16",
"eslint-plugin-import-x": "^4.3.1", "eslint-plugin-storybook": "^0.11.1",
"eslint-plugin-jsdoc": "^50.4.3", "eslint-plugin-testing-library": "^7.1.1",
"eslint-plugin-react-refresh": "^0.4.12",
"eslint-plugin-storybook": "canary",
"eslint-plugin-testing-library": "^6.4.0",
"eslint-plugin-unicorn": "^56.0.0",
"eslint-plugin-vitest": "^0.5.4",
"esprima": "^4.0.1",
"esquery": "^1.6.0",
"fast-glob": "^3.3.2",
"find-cache-dir": "^5.0.0", "find-cache-dir": "^5.0.0",
"globals": "^15.11.0",
"graphql": "^16.9.0", "graphql": "^16.9.0",
"json-schema-to-ts": "^3.1.1", "json-schema-to-ts": "^3.1.1",
"lodash-es": "^4.17.21", "nolyfill": "^1.0.43",
"nolyfill": "^1.0.41",
"patch-package": "^8.0.0", "patch-package": "^8.0.0",
"picocolors": "^1.1.1", "picocolors": "^1.1.1",
"prettier": "^3.3.3", "prettier": "^3.4.2",
"prop-types": "^15.8.1", "prop-types": "^15.8.1",
"terser": "^5.36.0", "terser": "^5.37.0",
"type-fest": "^4.26.1", "type-fest": "^4.30.1",
"typescript": "^5.6.3", "typescript": "^5.7.2"
"typescript-eslint": "^8.10.0"
}, },
"prettier": { "prettier": {
"arrowParens": "avoid", "arrowParens": "avoid",

View File

@ -1,5 +1,5 @@
diff --git a/src/index.js b/src/index.js diff --git a/src/index.js b/src/index.js
index 2fa185f..3cf8018 100644 index 980081e..3cf8018 100644
--- a/src/index.js --- a/src/index.js
+++ b/src/index.js +++ b/src/index.js
@@ -1,48 +1,90 @@ @@ -1,48 +1,90 @@
@ -160,7 +160,7 @@ index 2fa185f..3cf8018 100644
strict: createConfig(strictRules, 'strict'), strict: createConfig(strictRules, 'strict'),
}; };
-module.exports = { ...jsxA11y, configs, flatConfigs }; -module.exports = Object.assign(jsxA11y, { configs, flatConfigs });
+export default { ...jsxA11y, configs, flatConfigs }; +export default { ...jsxA11y, configs, flatConfigs };
diff --git a/src/rules/autocomplete-valid.js b/src/rules/autocomplete-valid.js diff --git a/src/rules/autocomplete-valid.js b/src/rules/autocomplete-valid.js
index df7b6b8..c4d0da1 100644 index df7b6b8..c4d0da1 100644
@ -205,8 +205,21 @@ index df7b6b8..c4d0da1 100644
nodeName: 'input', nodeName: 'input',
attributes: { attributes: {
autocomplete, autocomplete,
diff --git a/src/rules/label-has-associated-control.js b/src/rules/label-has-associated-control.js
index dd6b199..184199e 100644
--- a/src/rules/label-has-associated-control.js
+++ b/src/rules/label-has-associated-control.js
@@ -11,7 +11,7 @@
import { hasProp, getProp, getPropValue } from 'jsx-ast-utils';
import type { JSXElement } from 'ast-types-flow';
-import minimatch from 'minimatch';
+import { minimatch } from 'minimatch';
import { generateObjSchema, arraySchema } from '../util/schemas';
import type { ESLintConfig, ESLintContext, ESLintVisitorSelectorConfig } from '../../flow/eslint';
import getElementType from '../util/getElementType';
diff --git a/src/util/mayContainChildComponent.js b/src/util/mayContainChildComponent.js diff --git a/src/util/mayContainChildComponent.js b/src/util/mayContainChildComponent.js
index 43a03ef..5e1035e 100644 index 65000a0..09b199a 100644
--- a/src/util/mayContainChildComponent.js --- a/src/util/mayContainChildComponent.js
+++ b/src/util/mayContainChildComponent.js +++ b/src/util/mayContainChildComponent.js
@@ -9,7 +9,7 @@ @@ -9,7 +9,7 @@

View File

@ -1,8 +1,8 @@
diff --git a/lib/index.js b/lib/index.js diff --git a/lib/index.js b/lib/index.js
index 49fd4c7..a0fdd81 100644 index de95218..e30a3df 100644
--- a/lib/index.js --- a/lib/index.js
+++ b/lib/index.js +++ b/lib/index.js
@@ -1,9 +1,9 @@ @@ -1,17 +1,17 @@
"use strict" "use strict"
-const pkg = require("../package.json") -const pkg = require("../package.json")
@ -14,18 +14,17 @@ index 49fd4c7..a0fdd81 100644
+import cjsConfig from "./configs/recommended-script" +import cjsConfig from "./configs/recommended-script"
+import recommendedConfig from "./configs/recommended" +import recommendedConfig from "./configs/recommended"
/** /** @import { ESLint, Linter } from 'eslint' */
* @typedef {{
@@ -20,8 +20,8 @@ const recommendedConfig = require("./configs/recommended") /** @type {ESLint.Plugin} */
/** @type {import('eslint').ESLint.Plugin & { configs: Configs }} */ const base = {
const plugin = {
meta: { meta: {
- name: pkg.name, - name: pkg.name,
- version: pkg.version, - version: pkg.version,
+ name, + name,
+ version, + version,
}, },
rules: /** @type {Record<string, import('eslint').Rule.RuleModule>} */ ({ rules: {
"callback-return": require("./rules/callback-return"), "callback-return": require("./rules/callback-return"),
diff --git a/tests/fixtures/no-extraneous/dependencies/node_modules/@bbb/aaa.js b/tests/fixtures/no-extraneous/dependencies/node_modules/@bbb/aaa.js diff --git a/tests/fixtures/no-extraneous/dependencies/node_modules/@bbb/aaa.js b/tests/fixtures/no-extraneous/dependencies/node_modules/@bbb/aaa.js
deleted file mode 100644 deleted file mode 100644

3220
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

14
scripts/sync-deps.ts Executable file
View File

@ -0,0 +1,14 @@
#!/usr/bin/env node --experimental-strip-types
import fs from 'node:fs';
const up = JSON.parse(
fs.readFileSync('package.json', 'utf8'),
) as typeof import('../package.json');
const down = JSON.parse(
fs.readFileSync('dist/package.json', 'utf8'),
) as typeof import('../dist/package.json');
down.dependencies = up.dependencies;
fs.writeFileSync('dist/package.json', JSON.stringify(down, null, 2));

View File

@ -6,22 +6,22 @@
"subject": "[meta] add `repository.directory` field" "subject": "[meta] add `repository.directory` field"
}, },
"eslint-import-resolver-typescript": { "eslint-import-resolver-typescript": {
"hash": "5ee5879b4428f42edbc262d66e192c76202b7f47", "hash": "d1807bd97b41bf17d9254a768baa8a1e51b2962a",
"date": "2024-10-01T03:12:28+00:00", "date": "2024-12-05T17:55:16+09:00",
"committer": "GitHub", "committer": "GitHub",
"subject": "fix(deps): update dependency debug to ^4.3.7 (#316)" "subject": "import/resolvers -> import/resolver (#328)"
}, },
"eslint-plugin-jsx-a11y": { "eslint-plugin-jsx-a11y": {
"hash": "4925ba8d0bf80a4b1d8e8645d310590bf1b40b64", "hash": "7566e13531f09a040daee4c16d0cba0c28d321c4",
"date": "2024-09-20T14:09:27-07:00", "date": "2024-11-17T09:51:03-08:00",
"committer": "Jordan Harband", "committer": "Jordan Harband",
"subject": "[Fix] handle interactive/noninteractive changes from aria-query" "subject": "[Deps] update `axe-core`"
}, },
"eslint-plugin-n": { "eslint-plugin-n": {
"hash": "23d0e846e9dbfb68ccf7f410a83457514d432263", "hash": "308c80c60490484a9d27c0ab32e1d8d6652807cd",
"date": "2024-10-09T13:49:20+02:00", "date": "2024-12-10T10:59:09+08:00",
"committer": "GitHub", "committer": "GitHub",
"subject": "chore(master): release 17.11.1 (#352)" "subject": "chore(master): release 17.15.0 (#394)"
}, },
"eslint-plugin-react": { "eslint-plugin-react": {
"hash": "983b88dd3cb5e07919517d3fde4085f60883ded7", "hash": "983b88dd3cb5e07919517d3fde4085f60883ded7",

26
src/config.d.ts vendored
View File

@ -7,6 +7,21 @@ export type Middleware =
| (() => Promise<MiddlewareResult>) | (() => Promise<MiddlewareResult>)
| (() => Promise<{ default: MiddlewareResult }>); | (() => Promise<{ default: MiddlewareResult }>);
export interface NormalizedExtendConfigOptions {
auto?: boolean;
middlewares?: Middleware[];
configs: FlatESLintConfig[];
/**
* Use `.gitignore` file to exclude files from ESLint.
*/
gitignore?: boolean;
}
export type ExtendConfigOptions =
| FlatESLintConfig
| FlatESLintConfig[]
| NormalizedExtendConfigOptions;
/** /**
* Returns a ESLint config object. * Returns a ESLint config object.
* *
@ -26,18 +41,9 @@ export type Middleware =
* Non bundled: * Non bundled:
* 1. [`graphql`](https://the-guild.dev/graphql/eslint/rules) * 1. [`graphql`](https://the-guild.dev/graphql/eslint/rules)
* *
* @param of Configuration options.
* @returns ESLint configuration object. * @returns ESLint configuration object.
*/ */
export function extendConfig({ export function extendConfig(options?: ExtendConfigOptions): Promise<FlatESLintConfig[]>;
auto,
middlewares: addMiddlewares,
configs,
}: {
auto?: boolean;
middlewares?: Middleware[];
configs: FlatESLintConfig[];
}): Promise<FlatESLintConfig[]>;
export const error = 'error'; export const error = 'error';
export const warn = 'warn'; export const warn = 'warn';

View File

@ -1,9 +1,13 @@
import fs from 'node:fs';
import type { FlatESLintConfig } from '@aet/eslint-define-config'; import type { FlatESLintConfig } from '@aet/eslint-define-config';
import * as tsParser from '@typescript-eslint/parser'; import * as tsParser from '@typescript-eslint/parser';
import prettier from 'eslint-config-prettier';
import importPlugin from 'eslint-plugin-import-x'; import importPlugin from 'eslint-plugin-import-x';
import { uniq } from 'lodash-es'; import { uniq } from 'lodash-es';
import tseslint from 'typescript-eslint'; import tseslint from 'typescript-eslint';
import type { ExtendConfigOptions, NormalizedExtendConfigOptions } from './config';
import { off } from './constants'; import { off } from './constants';
import { checkEnv } from './environment'; import { checkEnv } from './environment';
import { Middleware } from './middleware'; import { Middleware } from './middleware';
@ -14,15 +18,40 @@ import unicorn from './presets/unicorn';
export { error, warn, off } from './constants'; export { error, warn, off } from './constants';
export async function extendConfig({ function normalizeExtendConfig(
options: ExtendConfigOptions,
): NormalizedExtendConfigOptions {
if (Array.isArray(options)) {
options = { configs: options };
} else if ('rules' in options) {
options = { configs: [options] };
}
const {
auto = true, auto = true,
middlewares: addMiddlewares = [], middlewares = [],
configs = [], configs = [],
}: { gitignore = true,
auto?: boolean; } = options as NormalizedExtendConfigOptions;
middlewares?: Middleware[];
configs: FlatESLintConfig[]; return {
}): Promise<FlatESLintConfig[]> { auto,
middlewares,
configs,
gitignore,
};
}
export async function extendConfig(
options: ExtendConfigOptions = [],
): Promise<FlatESLintConfig[]> {
const {
auto,
middlewares: addMiddlewares = [],
configs,
gitignore,
} = normalizeExtendConfig(options);
const middlewares: Middleware[] = uniq([ const middlewares: Middleware[] = uniq([
() => import('./presets/custom'), () => import('./presets/custom'),
...(auto ? checkEnv() : []), ...(auto ? checkEnv() : []),
@ -41,8 +70,8 @@ export async function extendConfig({
...unicorn, ...unicorn,
stylistic, stylistic,
{ {
name: 'eslint-rules: TypeScript and import-x', name: 'eslint-rules/typescript-and-import-x',
files: ['**/*.{js,mjs,cjs,jsx,mjsx,ts,tsx,mtsx}'], files: ['**/*.{js,mjs,cjs,jsx,ts,tsx,mts,cts}'],
languageOptions: { languageOptions: {
parserOptions: { parserOptions: {
parser: tsParser, parser: tsParser,
@ -70,7 +99,7 @@ export async function extendConfig({
}, },
{ {
name: 'eslint-rules: Disable type checking', name: 'eslint-rules: Disable type checking',
files: ['*.js', '*.mjs', '*.cjs', '*.jsx'], files: ['**/*.js', '**/*.mjs', '**/*.cjs', '**/*.jsx'],
...tseslint.configs.disableTypeChecked, ...tseslint.configs.disableTypeChecked,
rules: { rules: {
'import-x/no-commonjs': off, 'import-x/no-commonjs': off,
@ -81,8 +110,8 @@ export async function extendConfig({
}, },
}, },
{ {
name: 'eslint-rules: .d.ts files', name: 'eslint-rules/.d.ts-files',
files: ['*.d.ts'], files: ['**/*.d.ts'],
rules: { rules: {
'@typescript-eslint/consistent-type-imports': off, '@typescript-eslint/consistent-type-imports': off,
'import-x/unambiguous': off, 'import-x/unambiguous': off,
@ -102,9 +131,22 @@ export async function extendConfig({
} }
} }
if (configs) { if (configs?.length) {
result.push(...configs); result.push(...configs);
} }
result.push(prettier);
if (gitignore && fs.existsSync('.gitignore')) {
const ignores = fs
.readFileSync('.gitignore', 'utf8')
.trim()
.split('\n')
.map(line => line.trim())
.filter(line => line && !line.startsWith('#'));
result.push({ ignores });
}
return result; return result;
} }

View File

@ -14,8 +14,8 @@ export default defineConfig([
{ {
name: 'eslint-rules/typed-custom', name: 'eslint-rules/typed-custom',
plugins: { 'typed-custom': typedPlugin }, plugins: { 'typed-custom': typedPlugin },
files: ['*.ts'], files: ['**/*.ts'],
ignores: ['*.d.ts'], ignores: ['**/*.d.ts'],
rules: { rules: {
'typed-custom/restrict-template-expressions': error, 'typed-custom/restrict-template-expressions': error,
} satisfies Partial<LocalRuleOptions>, } satisfies Partial<LocalRuleOptions>,

View File

@ -12,6 +12,6 @@ export async function reactQuery() {
} }
export async function vitest() { export async function vitest() {
const { configs } = def(await import('eslint-plugin-vitest')); const { configs } = def(await import('@vitest/eslint-plugin'));
return defineConfig([configs.recommended]); return defineConfig([configs.recommended]);
} }

View File

@ -10,6 +10,7 @@ const reactRules: Partial<ReactRulesObject> = {
'@eslint-react/no-missing-component-display-name': off, '@eslint-react/no-missing-component-display-name': off,
'@eslint-react/no-children-prop': error, '@eslint-react/no-children-prop': error,
'@eslint-react/no-leaked-conditional-rendering': error, '@eslint-react/no-leaked-conditional-rendering': error,
'@eslint-react/prefer-read-only-props': off,
}; };
export async function react() { export async function react() {
@ -23,9 +24,17 @@ export async function react() {
a11y.flatConfigs.recommended, a11y.flatConfigs.recommended,
{ {
name: 'eslint-rules/react', name: 'eslint-rules/react',
files: ['*.tsx'], files: ['**/*.tsx'],
rules: reactRules, rules: reactRules,
}, },
{
name: 'eslint-rules/react/test-files',
files: ['**/*.test.tsx'],
rules: {
'@eslint-react/no-clone-element': off,
'@eslint-react/no-create-ref': off,
},
},
]); ]);
} }

View File

@ -8,8 +8,7 @@ const stylisticRules: Partial<StylisticRulesObject> = {
'stylistic/spaced-comment': [ 'stylistic/spaced-comment': [
error, error,
'always', 'always',
// allow /*@__PURE__*/ { block: { exceptions: ['@__PURE__', '#__PURE__'] } },
{ markers: ['/', '#', '@'], block: { exceptions: ['@'] } },
], ],
'stylistic/jsx-sort-props': [ 'stylistic/jsx-sort-props': [
error, error,

View File

@ -13,5 +13,11 @@ export default defineConfig([
{ {
name: 'eslint-rules/tailwind', name: 'eslint-rules/tailwind',
rules: tailwindRules, rules: tailwindRules,
settings: {
tailwindcss: {
callees: ['classnames', 'clsx', 'tw', 'twx'],
classRegex: '^(css|class(Name)?)$',
},
},
}, },
]); ]);

View File

@ -37,10 +37,7 @@ export const typescriptRules: Partial<TypeScriptRulesObject> = {
warn, warn,
{ accessibility: 'no-public' }, { accessibility: 'no-public' },
], ],
'@typescript-eslint/no-empty-object-type': [ '@typescript-eslint/no-empty-object-type': off,
error,
{ allowInterfaces: 'with-single-extends' },
],
'@typescript-eslint/no-empty-interface': [error, { allowSingleExtends: true }], '@typescript-eslint/no-empty-interface': [error, { allowSingleExtends: true }],
'@typescript-eslint/no-explicit-any': off, '@typescript-eslint/no-explicit-any': off,
'@typescript-eslint/no-misused-promises': [error, { checksVoidReturn: false }], '@typescript-eslint/no-misused-promises': [error, { checksVoidReturn: false }],

View File

@ -100,17 +100,6 @@ const unicornRules: Partial<UnicornRulesObject> = {
'unicorn/template-indent': warn, 'unicorn/template-indent': warn,
}; };
// export const unicorn = defineMiddleware((config, { addRules }) => {
// config.plugins.push('unicorn');
// addRules(unicornRules);
// config.overrides.push({
// files: ['*.test.ts', '*.test.tsx'],
// rules: {
// 'unicorn/no-useless-undefined': off,
// },
// });
// });
export default defineConfig([ export default defineConfig([
{ {
name: 'eslint-rules/unicorn', name: 'eslint-rules/unicorn',
@ -124,7 +113,7 @@ export default defineConfig([
}, },
{ {
name: 'eslint-rules/unicorn/tests', name: 'eslint-rules/unicorn/tests',
files: ['*.test.ts', '*.test.tsx'], files: ['**/*.test.ts', '**/*.test.tsx'],
rules: { rules: {
'unicorn/no-useless-undefined': off, 'unicorn/no-useless-undefined': off,
}, },

View File

@ -10,28 +10,15 @@ const prettier: Config = {
plugins: [], plugins: [],
}; };
export default function defineConfig({ export default function defineConfig(
tailwind, config: Partial<Config> & {
...config
}: Partial<Config> & {
tailwind?: boolean; tailwind?: boolean;
}) { },
) {
const result: Config = { const result: Config = {
...prettier, ...prettier,
...config, ...config,
}; };
if (tailwind) {
ensureHas(result.plugins!, 'prettier-plugin-tailwindcss');
result.tailwindAttributes ??= ['css'];
result.tailwindFunctions ??= ['tw'];
}
return result; return result;
} }
function ensureHas<T>(list: T[], item: T) {
if (!list.includes(item)) {
list.push(item);
}
}