Compare commits
21 Commits
553965243f
...
main
Author | SHA1 | Date | |
---|---|---|---|
c38449c759 | |||
d7e9b986c7 | |||
d06cd4937c | |||
a746e2fbc8 | |||
9b4a6cb498 | |||
d7990e5cf1 | |||
cddee19340 | |||
c2d582dea0 | |||
8824c2166d | |||
51df8a9a2c | |||
1e56001e78 | |||
2b4c3038b3 | |||
eb5f72a049 | |||
952914699b | |||
78ed00fd21 | |||
43d9cc294e | |||
235cf4101b | |||
f36e47f144 | |||
97eb90f6c6 | |||
a1ab2ad7f5 | |||
511652dd48 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -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
|
||||||
|
40
dist/config/index.d.ts
vendored
40
dist/config/index.d.ts
vendored
@ -7,6 +7,35 @@ export type Middleware =
|
|||||||
| (() => Promise<MiddlewareResult>)
|
| (() => Promise<MiddlewareResult>)
|
||||||
| (() => Promise<{ default: MiddlewareResult }>);
|
| (() => Promise<{ default: MiddlewareResult }>);
|
||||||
|
|
||||||
|
export type Environment =
|
||||||
|
| 'jsdoc'
|
||||||
|
| 'lingui'
|
||||||
|
| 'react'
|
||||||
|
| 'reactQuery'
|
||||||
|
| 'reactRefresh'
|
||||||
|
| 'storybook'
|
||||||
|
| 'tailwind'
|
||||||
|
| 'testingLibrary'
|
||||||
|
| 'vitest';
|
||||||
|
|
||||||
|
export interface NormalizedExtendConfigOptions {
|
||||||
|
auto?: boolean;
|
||||||
|
middlewares?: Middleware[];
|
||||||
|
configs: FlatESLintConfig[];
|
||||||
|
/**
|
||||||
|
* Use `.gitignore` file to exclude files from ESLint.
|
||||||
|
*/
|
||||||
|
gitignore?: boolean;
|
||||||
|
env?: {
|
||||||
|
[key in Environment]?: boolean;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ExtendConfigOptions =
|
||||||
|
| FlatESLintConfig
|
||||||
|
| FlatESLintConfig[]
|
||||||
|
| NormalizedExtendConfigOptions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a ESLint config object.
|
* Returns a ESLint config object.
|
||||||
*
|
*
|
||||||
@ -26,18 +55,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
5
dist/default.d.ts
vendored
Normal 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
3
dist/default.js
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import { extendConfig } from './config/index.js';
|
||||||
|
|
||||||
|
export default await extendConfig();
|
2
dist/eslint-init.sh
vendored
Normal file
2
dist/eslint-init.sh
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
echo 'export { default } from "@aet/eslint-rules/default";' > eslint.config.js
|
72
dist/package.json
vendored
72
dist/package.json
vendored
@ -1,62 +1,68 @@
|
|||||||
{
|
{
|
||||||
"name": "@aet/eslint-rules",
|
"name": "@aet/eslint-rules",
|
||||||
"version": "2.0.1-beta.8",
|
"version": "2.0.51",
|
||||||
"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.15",
|
||||||
|
"@antfu/install-pkg": "^1.1.0",
|
||||||
|
"@eslint-community/eslint-utils": "^4.7.0",
|
||||||
|
"@eslint-react/eslint-plugin": "1.51.3",
|
||||||
|
"@eslint/js": "^9.28.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": "^4.4.1",
|
||||||
"@eslint/js": "^9.12.0",
|
"@typescript-eslint/eslint-plugin": "^8.34.0",
|
||||||
"@eslint-community/eslint-utils": "^4.4.0",
|
"@typescript-eslint/parser": "^8.34.0",
|
||||||
"@types/eslint": "^9.6.1",
|
"@typescript-eslint/type-utils": "^8.34.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.10.0",
|
"@typescript-eslint/utils": "^8.34.0",
|
||||||
"@typescript-eslint/parser": "^8.10.0",
|
|
||||||
"@eslint-react/eslint-plugin": "1.15.0",
|
|
||||||
"@stylistic/eslint-plugin": "^2.9.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.3",
|
||||||
"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.1",
|
||||||
"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.18.1",
|
||||||
"typescript-eslint": "^8.10.0",
|
"eslint-config-prettier": "^10.1.5",
|
||||||
"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": "^4.4.3",
|
||||||
"eslint-module-utils": "^2.12.0",
|
"eslint-module-utils": "^2.12.0",
|
||||||
"eslint-plugin-es-x": "^8.0.0",
|
"eslint-plugin-import-x": "^4.15.1",
|
||||||
"eslint-plugin-import-x": "^4.3.1",
|
"eslint-plugin-regexp": "^2.9.0",
|
||||||
"eslint-plugin-unicorn": "^56.0.0",
|
"eslint-plugin-unicorn": "^59.0.1",
|
||||||
"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.3",
|
||||||
"get-tsconfig": "^4.8.1",
|
"get-tsconfig": "^4.10.1",
|
||||||
"globals": "^15.11.0",
|
"globals": "^16.2.0",
|
||||||
"ignore": "^6.0.2",
|
"ignore": "^7.0.5",
|
||||||
"is-bun-module": "^1.2.1",
|
"is-bun-module": "^2.0.0",
|
||||||
"is-glob": "^4.0.3",
|
"is-glob": "^4.0.3",
|
||||||
"language-tags": "^1.0.9",
|
"language-tags": "^2.1.0",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"minimatch": "^10.0.1",
|
"minimatch": "^10.0.1",
|
||||||
"semver": "^7.6.3"
|
"semver": "^7.7.2",
|
||||||
|
"typescript-eslint": "^8.34.0"
|
||||||
},
|
},
|
||||||
"pnpm": {
|
"pnpm": {
|
||||||
"overrides": {
|
"overrides": {
|
||||||
@ -72,4 +78,4 @@
|
|||||||
"**/is-core-module": "file:./overrides/is-core-module",
|
"**/is-core-module": "file:./overrides/is-core-module",
|
||||||
"**/supports-preserve-symlinks-flag": "file:./overrides/supports-preserve-symlinks-flag"
|
"**/supports-preserve-symlinks-flag": "file:./overrides/supports-preserve-symlinks-flag"
|
||||||
}
|
}
|
||||||
}
|
}
|
2267
dist/pnpm-lock.yaml
generated
vendored
2267
dist/pnpm-lock.yaml
generated
vendored
File diff suppressed because it is too large
Load Diff
19
dist/tsconfig.json
vendored
Normal file
19
dist/tsconfig.json
vendored
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"allowArbitraryExtensions": true,
|
||||||
|
"allowImportingTsExtensions": true,
|
||||||
|
"jsx": "react-jsx",
|
||||||
|
"module": "Preserve",
|
||||||
|
"moduleResolution": "Bundler",
|
||||||
|
"noEmit": true,
|
||||||
|
"noImplicitOverride": true,
|
||||||
|
"noImplicitReturns": true,
|
||||||
|
"noUnusedLocals": true,
|
||||||
|
"noUnusedParameters": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"strict": true,
|
||||||
|
"stripInternal": true,
|
||||||
|
"target": "ESNext",
|
||||||
|
"verbatimModuleSyntax": true
|
||||||
|
}
|
||||||
|
}
|
136
package.json
136
package.json
@ -1,74 +1,98 @@
|
|||||||
{
|
{
|
||||||
"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,
|
||||||
"devDependencies": {
|
"dependencies": {
|
||||||
"@aet/eslint-define-config": "^0.1.0-beta.29",
|
"@aet/eslint-define-config": "^0.1.16",
|
||||||
"@antfu/install-pkg": "^0.4.1",
|
"@antfu/install-pkg": "^1.1.0",
|
||||||
"@babel/core": "^7.25.8",
|
"@eslint-community/eslint-utils": "^4.7.0",
|
||||||
"@babel/plugin-transform-flow-strip-types": "^7.25.7",
|
"@eslint-react/eslint-plugin": "1.52.2",
|
||||||
"@babel/preset-env": "^7.25.8",
|
"@eslint/js": "^9.28.0",
|
||||||
"@eslint-react/eslint-plugin": "^1.15.0",
|
"@nolyfill/is-core-module": "^1.0.39",
|
||||||
"@eslint/js": "^9.13.0",
|
"@stylistic/eslint-plugin": "^4.4.1",
|
||||||
"@graphql-eslint/eslint-plugin": "^3.20.1",
|
"@typescript-eslint/eslint-plugin": "^8.34.0",
|
||||||
"@stylistic/eslint-plugin": "^2.9.0",
|
"@typescript-eslint/parser": "^8.34.0",
|
||||||
"@swc-node/register": "^1.10.9",
|
"@typescript-eslint/type-utils": "^8.34.0",
|
||||||
"@tanstack/eslint-plugin-query": "^5.59.7",
|
"@typescript-eslint/utils": "^8.34.0",
|
||||||
"@types/babel-plugin-macros": "^3.1.3",
|
"aria-query": "^5.3.2",
|
||||||
"@types/babel__core": "^7.20.5",
|
"axe-core": "^4.10.3",
|
||||||
"@types/eslint": "^9.6.1",
|
"axobject-query": "4.1.0",
|
||||||
"@types/eslint-plugin-tailwindcss": "^3.17.0",
|
"damerau-levenshtein": "1.0.8",
|
||||||
"@types/eslint__js": "^8.42.3",
|
"debug": "^4.4.1",
|
||||||
"@types/esprima": "^4.0.6",
|
"doctrine": "^3.0.0",
|
||||||
"@types/esquery": "^1.5.4",
|
"emoji-regex": "^10.4.0",
|
||||||
"@types/estree": "^1.0.6",
|
"enhanced-resolve": "^5.18.1",
|
||||||
"@types/estree-jsx": "^1.0.5",
|
"eslint-config-prettier": "^10.1.5",
|
||||||
"@types/lodash-es": "^4.17.12",
|
"eslint-import-resolver-node": "^0.3.9",
|
||||||
"@types/node": "^22.7.7",
|
"eslint-import-resolver-typescript": "^4.4.3",
|
||||||
"@types/react-refresh": "^0.14.6",
|
"eslint-module-utils": "^2.12.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.10.0",
|
"eslint-plugin-import-x": "^4.15.2",
|
||||||
"@typescript-eslint/parser": "^8.10.0",
|
"eslint-plugin-regexp": "^2.9.0",
|
||||||
"@typescript-eslint/type-utils": "^8.10.0",
|
"eslint-plugin-unicorn": "^59.0.1",
|
||||||
"@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",
|
|
||||||
"dts-bundle-generator": "9.5.1",
|
|
||||||
"esbuild": "0.24.0",
|
|
||||||
"esbuild-plugin-alias": "^0.2.1",
|
|
||||||
"eslint": "9.13.0",
|
|
||||||
"eslint-config-prettier": "^9.1.0",
|
|
||||||
"eslint-import-resolver-typescript": "^3.6.3",
|
|
||||||
"eslint-plugin-import-x": "^4.3.1",
|
|
||||||
"eslint-plugin-jsdoc": "^50.4.3",
|
|
||||||
"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",
|
"esprima": "^4.0.1",
|
||||||
"esquery": "^1.6.0",
|
"esquery": "^1.6.0",
|
||||||
"fast-glob": "^3.3.2",
|
"estraverse": "^5.3.0",
|
||||||
"find-cache-dir": "^5.0.0",
|
"fast-glob": "^3.3.3",
|
||||||
"globals": "^15.11.0",
|
"get-tsconfig": "^4.10.1",
|
||||||
"graphql": "^16.9.0",
|
"globals": "^16.2.0",
|
||||||
"json-schema-to-ts": "^3.1.1",
|
"ignore": "^7.0.5",
|
||||||
|
"is-bun-module": "^2.0.0",
|
||||||
|
"is-glob": "^4.0.3",
|
||||||
|
"language-tags": "^2.1.0",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"nolyfill": "^1.0.41",
|
"minimatch": "^10.0.3",
|
||||||
|
"semver": "^7.7.2",
|
||||||
|
"typescript-eslint": "^8.34.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@babel/core": "^7.27.4",
|
||||||
|
"@babel/plugin-transform-flow-strip-types": "^7.27.1",
|
||||||
|
"@babel/preset-env": "^7.27.2",
|
||||||
|
"@graphql-eslint/eslint-plugin": "^4.4.0",
|
||||||
|
"@swc-node/register": "^1.10.10",
|
||||||
|
"@tanstack/eslint-plugin-query": "^5.78.0",
|
||||||
|
"@types/babel-plugin-macros": "^3.1.3",
|
||||||
|
"@types/babel__core": "^7.20.5",
|
||||||
|
"@types/eslint-config-prettier": "^6.11.3",
|
||||||
|
"@types/eslint-plugin-tailwindcss": "^3.17.0",
|
||||||
|
"@types/esprima": "^4.0.6",
|
||||||
|
"@types/esquery": "^1.5.4",
|
||||||
|
"@types/estree": "^1.0.8",
|
||||||
|
"@types/estree-jsx": "^1.0.5",
|
||||||
|
"@types/lodash-es": "^4.17.12",
|
||||||
|
"@types/node": "^22.15.30",
|
||||||
|
"@types/react-refresh": "^0.14.6",
|
||||||
|
"@typescript-eslint/types": "^8.34.0",
|
||||||
|
"@typescript-eslint/typescript-estree": "^8.34.0",
|
||||||
|
"@vitest/eslint-plugin": "^1.2.4",
|
||||||
|
"babel-plugin-macros": "^3.1.0",
|
||||||
|
"dts-bundle-generator": "9.5.1",
|
||||||
|
"esbuild": "0.25.5",
|
||||||
|
"esbuild-plugin-alias": "^0.2.1",
|
||||||
|
"eslint": "^9.28.0",
|
||||||
|
"eslint-plugin-jsdoc": "^50.7.1",
|
||||||
|
"eslint-plugin-lingui": "^0.10.1",
|
||||||
|
"eslint-plugin-react-refresh": "^0.4.20",
|
||||||
|
"eslint-plugin-storybook": "^9.0.9",
|
||||||
|
"eslint-plugin-testing-library": "^7.5.2",
|
||||||
|
"graphql": "^16.11.0",
|
||||||
|
"json-schema-to-ts": "^3.1.1",
|
||||||
|
"nolyfill": "^1.0.44",
|
||||||
"patch-package": "^8.0.0",
|
"patch-package": "^8.0.0",
|
||||||
"picocolors": "^1.1.1",
|
"picocolors": "^1.1.1",
|
||||||
"prettier": "^3.3.3",
|
"prettier": "^3.5.3",
|
||||||
"prop-types": "^15.8.1",
|
"prop-types": "^15.8.1",
|
||||||
"terser": "^5.36.0",
|
"terser": "^5.42.0",
|
||||||
"type-fest": "^4.26.1",
|
"type-fest": "^4.41.0",
|
||||||
"typescript": "^5.6.3",
|
"typescript": "^5.8.3"
|
||||||
"typescript-eslint": "^8.10.0"
|
|
||||||
},
|
},
|
||||||
"prettier": {
|
"prettier": {
|
||||||
"arrowParens": "avoid",
|
"arrowParens": "avoid",
|
||||||
|
Submodule packages/eslint-import-resolver-typescript deleted from 3dfad602a0
Submodule packages/eslint-plugin-jsx-a11y updated: cca288b73a...a7d1a12a61
Submodule packages/eslint-plugin-n updated: 6744257b43...42464abe64
Submodule packages/jsx-ast-utils updated: 5943318eaf...a8ca8f7033
@ -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 d65abe9..22ecee7 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 @@
|
||||||
|
@ -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
|
||||||
|
5345
pnpm-lock.yaml
generated
5345
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -86,7 +86,6 @@ async function bundle(
|
|||||||
plugins,
|
plugins,
|
||||||
define: {},
|
define: {},
|
||||||
alias: {},
|
alias: {},
|
||||||
external: ['find-cache-dir'],
|
|
||||||
format: 'esm',
|
format: 'esm',
|
||||||
banner: {
|
banner: {
|
||||||
js: '/* eslint-disable */',
|
js: '/* eslint-disable */',
|
||||||
|
@ -20,7 +20,6 @@ pull() {
|
|||||||
echo
|
echo
|
||||||
}
|
}
|
||||||
|
|
||||||
pull import-js eslint-import-resolver-typescript
|
|
||||||
pull jsx-eslint eslint-plugin-jsx-a11y
|
pull jsx-eslint eslint-plugin-jsx-a11y
|
||||||
pull eslint-community eslint-plugin-n
|
pull eslint-community eslint-plugin-n
|
||||||
pull jsx-eslint jsx-ast-utils
|
pull jsx-eslint jsx-ast-utils
|
||||||
|
14
scripts/sync-deps.ts
Executable file
14
scripts/sync-deps.ts
Executable file
@ -0,0 +1,14 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
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));
|
@ -5,23 +5,17 @@
|
|||||||
"committer": "Jordan Harband",
|
"committer": "Jordan Harband",
|
||||||
"subject": "[meta] add `repository.directory` field"
|
"subject": "[meta] add `repository.directory` field"
|
||||||
},
|
},
|
||||||
"eslint-import-resolver-typescript": {
|
|
||||||
"hash": "5ee5879b4428f42edbc262d66e192c76202b7f47",
|
|
||||||
"date": "2024-10-01T03:12:28+00:00",
|
|
||||||
"committer": "GitHub",
|
|
||||||
"subject": "fix(deps): update dependency debug to ^4.3.7 (#316)"
|
|
||||||
},
|
|
||||||
"eslint-plugin-jsx-a11y": {
|
"eslint-plugin-jsx-a11y": {
|
||||||
"hash": "4925ba8d0bf80a4b1d8e8645d310590bf1b40b64",
|
"hash": "a7d1a12a6198d546c4a06477b385b4fde03b762e",
|
||||||
"date": "2024-09-20T14:09:27-07:00",
|
"date": "2025-06-05T12:28:53-07:00",
|
||||||
"committer": "Jordan Harband",
|
"committer": "Jordan Harband",
|
||||||
"subject": "[Fix] handle interactive/noninteractive changes from aria-query"
|
"subject": "[Tests] fix linting errors introduced in 2d9ad55"
|
||||||
},
|
},
|
||||||
"eslint-plugin-n": {
|
"eslint-plugin-n": {
|
||||||
"hash": "23d0e846e9dbfb68ccf7f410a83457514d432263",
|
"hash": "42464abe64c5cefb709e8e0a9072b6bb1cd7fcdc",
|
||||||
"date": "2024-10-09T13:49:20+02:00",
|
"date": "2025-06-13T01:37:54+08:00",
|
||||||
"committer": "GitHub",
|
"committer": "GitHub",
|
||||||
"subject": "chore(master): release 17.11.1 (#352)"
|
"subject": "chore(master): release 17.20.0 (#448)"
|
||||||
},
|
},
|
||||||
"eslint-plugin-react": {
|
"eslint-plugin-react": {
|
||||||
"hash": "983b88dd3cb5e07919517d3fde4085f60883ded7",
|
"hash": "983b88dd3cb5e07919517d3fde4085f60883ded7",
|
||||||
@ -30,9 +24,9 @@
|
|||||||
"subject": "[Tests] `no-array-index-key`: actually run valid tests"
|
"subject": "[Tests] `no-array-index-key`: actually run valid tests"
|
||||||
},
|
},
|
||||||
"jsx-ast-utils": {
|
"jsx-ast-utils": {
|
||||||
"hash": "5943318eaf23764eec3ff397ebb969613d728a95",
|
"hash": "a8ca8f70331b02db537b0b5cf72ea10e3d6c9377",
|
||||||
"date": "2023-07-28T18:34:04-07:00",
|
"date": "2025-02-20T08:51:06-08:00",
|
||||||
"committer": "Jordan Harband",
|
"committer": "Jordan Harband",
|
||||||
"subject": "v3.3.5"
|
"subject": "[Dev Deps] pin `psl` due to breaking change in a minor version"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
40
src/config.d.ts
vendored
40
src/config.d.ts
vendored
@ -7,6 +7,35 @@ export type Middleware =
|
|||||||
| (() => Promise<MiddlewareResult>)
|
| (() => Promise<MiddlewareResult>)
|
||||||
| (() => Promise<{ default: MiddlewareResult }>);
|
| (() => Promise<{ default: MiddlewareResult }>);
|
||||||
|
|
||||||
|
export type Environment =
|
||||||
|
| 'jsdoc'
|
||||||
|
| 'lingui'
|
||||||
|
| 'react'
|
||||||
|
| 'reactQuery'
|
||||||
|
| 'reactRefresh'
|
||||||
|
| 'storybook'
|
||||||
|
| 'tailwind'
|
||||||
|
| 'testingLibrary'
|
||||||
|
| 'vitest';
|
||||||
|
|
||||||
|
export interface NormalizedExtendConfigOptions {
|
||||||
|
auto?: boolean;
|
||||||
|
middlewares?: Middleware[];
|
||||||
|
configs: FlatESLintConfig[];
|
||||||
|
/**
|
||||||
|
* Use `.gitignore` file to exclude files from ESLint.
|
||||||
|
*/
|
||||||
|
gitignore?: boolean;
|
||||||
|
env?: {
|
||||||
|
[key in Environment]?: boolean;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ExtendConfigOptions =
|
||||||
|
| FlatESLintConfig
|
||||||
|
| FlatESLintConfig[]
|
||||||
|
| NormalizedExtendConfigOptions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a ESLint config object.
|
* Returns a ESLint config object.
|
||||||
*
|
*
|
||||||
@ -26,18 +55,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';
|
||||||
|
@ -3,6 +3,7 @@ import type { ESLint } from 'eslint';
|
|||||||
import noEmptyObjectLiteral from './no-empty-object-literal';
|
import noEmptyObjectLiteral from './no-empty-object-literal';
|
||||||
import noImportDot from './no-import-dot';
|
import noImportDot from './no-import-dot';
|
||||||
import noUselessImportAlias from './no-useless-import-alias';
|
import noUselessImportAlias from './no-useless-import-alias';
|
||||||
|
import requireImportAttribute from './require-import-attribute';
|
||||||
import restrictTemplateExpressions from './restrict-template-expressions';
|
import restrictTemplateExpressions from './restrict-template-expressions';
|
||||||
|
|
||||||
type RuleLevel = 'error' | 'warn' | 'off' | 0 | 1 | 2;
|
type RuleLevel = 'error' | 'warn' | 'off' | 0 | 1 | 2;
|
||||||
@ -10,29 +11,32 @@ type RuleEntry<Options> = RuleLevel | [RuleLevel, Partial<Options>];
|
|||||||
|
|
||||||
export interface LocalRuleOptions {
|
export interface LocalRuleOptions {
|
||||||
/** Bans import from the specifier '.' and '..' and replaces it with '.+/index' */
|
/** Bans import from the specifier '.' and '..' and replaces it with '.+/index' */
|
||||||
'custom/no-import-dot': RuleEntry<unknown>;
|
'aet/no-import-dot': RuleEntry<unknown>;
|
||||||
/**
|
/**
|
||||||
* Enforce template literal expressions to be of `string` type
|
* Enforce template literal expressions to be of `string` type
|
||||||
* @see [restrict-template-expressions](https://typescript-eslint.io/rules/restrict-template-expressions)
|
* @see [restrict-template-expressions](https://typescript-eslint.io/rules/restrict-template-expressions)
|
||||||
*/
|
*/
|
||||||
'typed-custom/restrict-template-expressions': RuleEntry<{ allow: string[] }>;
|
'typed-aet/restrict-template-expressions': RuleEntry<{ allow: string[] }>;
|
||||||
/** Ban assignment of empty object literals `{}` and replace them with `Object.create(null)` */
|
/** Ban assignment of empty object literals `{}` and replace them with `Object.create(null)` */
|
||||||
'custom/no-empty-object-literal': RuleEntry<unknown>;
|
'aet/no-empty-object-literal': RuleEntry<unknown>;
|
||||||
/** Ban useless import alias */
|
/** Ban useless import alias */
|
||||||
'custom/no-useless-import-alias': RuleEntry<unknown>;
|
'aet/no-useless-import-alias': RuleEntry<unknown>;
|
||||||
|
/** Require the use of `{ type: "json" }` for JSON imports. */
|
||||||
|
'aet/require-import-attribute': RuleEntry<unknown>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const plugin: ESLint.Plugin = {
|
export const plugin: ESLint.Plugin = {
|
||||||
name: 'custom',
|
name: 'aet',
|
||||||
rules: {
|
rules: {
|
||||||
'no-empty-object-literal': noEmptyObjectLiteral,
|
'no-empty-object-literal': noEmptyObjectLiteral,
|
||||||
'no-import-dot': noImportDot,
|
'no-import-dot': noImportDot,
|
||||||
'no-useless-import-alias': noUselessImportAlias,
|
'no-useless-import-alias': noUselessImportAlias,
|
||||||
|
'require-import-attribute': requireImportAttribute,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const typedPlugin: ESLint.Plugin = {
|
export const typedPlugin: ESLint.Plugin = {
|
||||||
name: 'typed-custom',
|
name: 'typed-aet',
|
||||||
rules: {
|
rules: {
|
||||||
// @ts-expect-error type mismatch
|
// @ts-expect-error type mismatch
|
||||||
'restrict-template-expressions': restrictTemplateExpressions,
|
'restrict-template-expressions': restrictTemplateExpressions,
|
||||||
|
61
src/custom/require-import-attribute.ts
Normal file
61
src/custom/require-import-attribute.ts
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
import type { Rule } from 'eslint';
|
||||||
|
import type { Identifier, SimpleLiteral } from 'estree';
|
||||||
|
|
||||||
|
interface ImportAttribute {
|
||||||
|
key: Identifier | SimpleLiteral;
|
||||||
|
value: SimpleLiteral;
|
||||||
|
}
|
||||||
|
|
||||||
|
const requireImportAttribute: Rule.RuleModule = {
|
||||||
|
meta: {
|
||||||
|
type: 'problem',
|
||||||
|
docs: {
|
||||||
|
description:
|
||||||
|
'Requires JSON imports to have a "with { type: \'json\' }" import attribute.',
|
||||||
|
category: 'Possible Errors',
|
||||||
|
recommended: false,
|
||||||
|
},
|
||||||
|
fixable: 'code',
|
||||||
|
schema: [],
|
||||||
|
messages: {
|
||||||
|
missingJsonTypeAttribute:
|
||||||
|
'JSON imports must have a "with { type: \'json\' }" import attribute.',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
create(context) {
|
||||||
|
return {
|
||||||
|
ImportDeclaration(node) {
|
||||||
|
// Only check modules that end with ".json"
|
||||||
|
if (
|
||||||
|
typeof node.source.value === 'string' &&
|
||||||
|
node.source.value.endsWith('.json')
|
||||||
|
) {
|
||||||
|
// Cast the node to our extended interface to access the assertions.
|
||||||
|
const importNode = node;
|
||||||
|
const assertions = (
|
||||||
|
importNode as {
|
||||||
|
assertions?: ImportAttribute[];
|
||||||
|
}
|
||||||
|
).assertions;
|
||||||
|
|
||||||
|
const hasJsonType = assertions?.some(attr => {
|
||||||
|
const keyName =
|
||||||
|
(attr.key as Identifier).name ?? (attr.key as SimpleLiteral).value;
|
||||||
|
return keyName === 'type' && attr.value.value === 'json';
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!hasJsonType) {
|
||||||
|
context.report({
|
||||||
|
node,
|
||||||
|
messageId: 'missingJsonTypeAttribute',
|
||||||
|
fix: fixer =>
|
||||||
|
fixer.insertTextAfterRange(node.source.range!, ' with { type: "json" }'),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default requireImportAttribute;
|
@ -1,63 +1,76 @@
|
|||||||
import fs from 'node:fs';
|
import fs from 'node:fs';
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
|
|
||||||
|
import type { Environment, NormalizedExtendConfigOptions } from './config';
|
||||||
import type { Middleware } from './middleware';
|
import type { Middleware } from './middleware';
|
||||||
import { reactQuery, storybook, vitest } from './presets/misc';
|
import { reactQuery, storybook, vitest } from './presets/misc';
|
||||||
import { react, reactRefresh } from './presets/react';
|
import { react, reactRefresh } from './presets/react';
|
||||||
|
|
||||||
const jsdoc = () => import('./presets/jsdoc');
|
type Pkg = typeof import('../package.json');
|
||||||
const tailwind = () => import('./presets/tailwind');
|
type Dependency = keyof Pkg['dependencies'] | RemoveType<keyof Pkg['devDependencies']>;
|
||||||
const testingLibrary = () => import('./presets/testing-library');
|
|
||||||
|
|
||||||
const middlewares = {
|
type RemoveType<T extends string> = T extends `@types/${infer U}__${infer V}`
|
||||||
|
? `@${U}/${V}`
|
||||||
|
: T extends `@types/${infer U}`
|
||||||
|
? U
|
||||||
|
: T;
|
||||||
|
|
||||||
|
export const middlewares = {
|
||||||
react,
|
react,
|
||||||
reactRefresh,
|
reactRefresh,
|
||||||
tailwind,
|
tailwind: () => import('./presets/tailwind'),
|
||||||
storybook,
|
storybook,
|
||||||
reactQuery,
|
reactQuery,
|
||||||
testingLibrary,
|
testingLibrary: () => import('./presets/testing-library'),
|
||||||
jsdoc,
|
jsdoc: () => import('./presets/jsdoc'),
|
||||||
vitest,
|
vitest,
|
||||||
|
lingui: () => import('./presets/lingui'),
|
||||||
} satisfies {
|
} satisfies {
|
||||||
[key: string]: Middleware;
|
[key in Environment]: Middleware;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const envs: {
|
export const envs: {
|
||||||
dependency: string;
|
dependency: string[];
|
||||||
eslintPlugin?: string;
|
eslintPlugin?: Dependency;
|
||||||
middleware: keyof typeof middlewares;
|
middleware: keyof typeof middlewares;
|
||||||
}[] = [
|
}[] = [
|
||||||
{
|
{
|
||||||
dependency: 'react',
|
dependency: ['react'],
|
||||||
middleware: 'react',
|
middleware: 'react',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
dependency: '@vitejs/plugin-react',
|
dependency: ['@vitejs/plugin-react', '@vitejs/plugin-react-swc'],
|
||||||
|
eslintPlugin: 'eslint-plugin-react-refresh',
|
||||||
middleware: 'reactRefresh',
|
middleware: 'reactRefresh',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
dependency: 'tailwindcss',
|
dependency: ['tailwindcss'],
|
||||||
eslintPlugin: 'eslint-plugin-tailwindcss',
|
eslintPlugin: 'eslint-plugin-tailwindcss',
|
||||||
middleware: 'tailwind',
|
middleware: 'tailwind',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
dependency: 'storybook',
|
dependency: ['storybook'],
|
||||||
eslintPlugin: 'eslint-plugin-storybook',
|
eslintPlugin: 'eslint-plugin-storybook',
|
||||||
middleware: 'storybook',
|
middleware: 'storybook',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
dependency: '@tanstack/react-query',
|
dependency: ['@lingui/core', '@lingui/react'],
|
||||||
|
eslintPlugin: 'eslint-plugin-lingui',
|
||||||
|
middleware: 'lingui',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dependency: ['@tanstack/react-query'],
|
||||||
eslintPlugin: '@tanstack/eslint-plugin-query',
|
eslintPlugin: '@tanstack/eslint-plugin-query',
|
||||||
middleware: 'reactQuery',
|
middleware: 'reactQuery',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
dependency: '@testing-library/react',
|
dependency: ['@testing-library/react'],
|
||||||
eslintPlugin: 'eslint-plugin-testing-library',
|
eslintPlugin: 'eslint-plugin-testing-library',
|
||||||
middleware: 'testingLibrary',
|
middleware: 'testingLibrary',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
dependency: 'vitest',
|
dependency: ['vitest'],
|
||||||
eslintPlugin: 'eslint-plugin-vitest',
|
eslintPlugin: '@vitest/eslint-plugin',
|
||||||
middleware: 'vitest',
|
middleware: 'vitest',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@ -87,8 +100,19 @@ export function* checkEnv(): Generator<Middleware> {
|
|||||||
const deps = getProjectDependencies();
|
const deps = getProjectDependencies();
|
||||||
|
|
||||||
for (const { dependency, eslintPlugin, middleware } of envs) {
|
for (const { dependency, eslintPlugin, middleware } of envs) {
|
||||||
if (deps.has(dependency) && (!eslintPlugin || deps.has(eslintPlugin))) {
|
if (
|
||||||
|
dependency.some(dep => deps.has(dep)) &&
|
||||||
|
(!eslintPlugin || deps.has(eslintPlugin))
|
||||||
|
) {
|
||||||
yield middlewares[middleware];
|
yield middlewares[middleware];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function* fromEnvironments(envs: NormalizedExtendConfigOptions['env']) {
|
||||||
|
for (const [env, enabled] of Object.entries(envs ?? {}) as [Environment, boolean][]) {
|
||||||
|
if (enabled) {
|
||||||
|
yield middlewares[env];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
94
src/index.ts
94
src/index.ts
@ -1,12 +1,18 @@
|
|||||||
|
/* eslint-disable import-x/no-named-as-default-member */
|
||||||
|
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 * as regexpPlugin from 'eslint-plugin-regexp';
|
||||||
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, fromEnvironments } from './environment';
|
||||||
import { Middleware } from './middleware';
|
import type { Middleware } from './middleware';
|
||||||
import { eslintRules } from './presets/eslint';
|
import { eslintRules } from './presets/eslint';
|
||||||
import stylistic from './presets/stylistic';
|
import stylistic from './presets/stylistic';
|
||||||
import { importRules, typescriptRules } from './presets/typescript';
|
import { importRules, typescriptRules } from './presets/typescript';
|
||||||
@ -14,21 +20,49 @@ import unicorn from './presets/unicorn';
|
|||||||
|
|
||||||
export { error, warn, off } from './constants';
|
export { error, warn, off } from './constants';
|
||||||
|
|
||||||
export async function extendConfig({
|
function normalizeExtendConfig(
|
||||||
auto = true,
|
options: ExtendConfigOptions,
|
||||||
middlewares: addMiddlewares = [],
|
): NormalizedExtendConfigOptions {
|
||||||
configs = [],
|
if (Array.isArray(options)) {
|
||||||
}: {
|
options = { configs: options };
|
||||||
auto?: boolean;
|
} else if ('rules' in options) {
|
||||||
middlewares?: Middleware[];
|
options = { configs: [options] };
|
||||||
configs: FlatESLintConfig[];
|
}
|
||||||
}): Promise<FlatESLintConfig[]> {
|
|
||||||
|
const {
|
||||||
|
auto = true,
|
||||||
|
middlewares = [],
|
||||||
|
configs = [],
|
||||||
|
gitignore = true,
|
||||||
|
env,
|
||||||
|
} = options as NormalizedExtendConfigOptions;
|
||||||
|
|
||||||
|
return {
|
||||||
|
auto,
|
||||||
|
middlewares,
|
||||||
|
configs,
|
||||||
|
gitignore,
|
||||||
|
env,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function extendConfig(
|
||||||
|
options: ExtendConfigOptions = [],
|
||||||
|
): Promise<FlatESLintConfig[]> {
|
||||||
|
const {
|
||||||
|
auto,
|
||||||
|
middlewares: addMiddlewares = [],
|
||||||
|
configs,
|
||||||
|
gitignore,
|
||||||
|
env,
|
||||||
|
} = normalizeExtendConfig(options);
|
||||||
|
|
||||||
const middlewares: Middleware[] = uniq([
|
const middlewares: Middleware[] = uniq([
|
||||||
() => import('./presets/custom'),
|
() => import('./presets/custom'),
|
||||||
...(auto ? checkEnv() : []),
|
...(auto ? checkEnv() : []),
|
||||||
|
...fromEnvironments(env),
|
||||||
...addMiddlewares,
|
...addMiddlewares,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const result: FlatESLintConfig[] = [
|
const result: FlatESLintConfig[] = [
|
||||||
{
|
{
|
||||||
name: 'eslint-rules/eslint',
|
name: 'eslint-rules/eslint',
|
||||||
@ -41,8 +75,19 @@ export async function extendConfig({
|
|||||||
...unicorn,
|
...unicorn,
|
||||||
stylistic,
|
stylistic,
|
||||||
{
|
{
|
||||||
name: 'eslint-rules: TypeScript and import-x',
|
plugins: { regexp: regexpPlugin },
|
||||||
files: ['**/*.{js,mjs,cjs,jsx,mjsx,ts,tsx,mtsx}'],
|
rules: {
|
||||||
|
...regexpPlugin.configs['flat/recommended'].rules,
|
||||||
|
// https://github.com/ota-meshi/eslint-plugin-regexp/issues/445
|
||||||
|
'regexp/strict': off,
|
||||||
|
'regexp/match-any': off,
|
||||||
|
// https://github.com/ota-meshi/eslint-plugin-regexp/issues/743
|
||||||
|
'regexp/letter-case': off,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'eslint-rules/typescript-and-import-x',
|
||||||
|
files: ['**/*.{js,mjs,cjs,jsx,ts,tsx,mts,cts}'],
|
||||||
languageOptions: {
|
languageOptions: {
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
parser: tsParser,
|
parser: tsParser,
|
||||||
@ -70,7 +115,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 +126,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 +147,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;
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,12 @@ import { envs, getProjectDependencies } from './environment';
|
|||||||
const deps = getProjectDependencies();
|
const deps = getProjectDependencies();
|
||||||
const packages = uniq(
|
const packages = uniq(
|
||||||
envs
|
envs
|
||||||
.filter(_ => deps.has(_.dependency) && _.eslintPlugin && !deps.has(_.eslintPlugin))
|
.filter(
|
||||||
|
_ =>
|
||||||
|
_.dependency.some(dep => deps.has(dep)) &&
|
||||||
|
_.eslintPlugin &&
|
||||||
|
!deps.has(_.eslintPlugin),
|
||||||
|
)
|
||||||
.map(_ => _.eslintPlugin!),
|
.map(_ => _.eslintPlugin!),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -6,5 +6,4 @@ export type Middleware =
|
|||||||
| (() => Promise<MiddlewareResult>)
|
| (() => Promise<MiddlewareResult>)
|
||||||
| (() => Promise<{ default: MiddlewareResult }>);
|
| (() => Promise<{ default: MiddlewareResult }>);
|
||||||
|
|
||||||
// eslint-disable-next-line unicorn/prevent-abbreviations
|
|
||||||
export const def = <T>(module: { default: T }): T => module.default;
|
export const def = <T>(module: { default: T }): T => module.default;
|
||||||
|
@ -4,20 +4,21 @@ import { defineConfig } from '../types';
|
|||||||
|
|
||||||
export default defineConfig([
|
export default defineConfig([
|
||||||
{
|
{
|
||||||
name: 'eslint-rules/custom',
|
name: 'eslint-rules/aet',
|
||||||
plugins: { custom: plugin },
|
plugins: { aet: plugin },
|
||||||
rules: {
|
rules: {
|
||||||
'custom/no-import-dot': error,
|
'aet/no-import-dot': error,
|
||||||
'custom/no-useless-import-alias': error,
|
'aet/no-useless-import-alias': error,
|
||||||
|
'aet/require-import-attribute': error,
|
||||||
} satisfies Partial<LocalRuleOptions>,
|
} satisfies Partial<LocalRuleOptions>,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'eslint-rules/typed-custom',
|
name: 'eslint-rules/typed-aet',
|
||||||
plugins: { 'typed-custom': typedPlugin },
|
plugins: { 'typed-aet': typedPlugin },
|
||||||
files: ['*.ts'],
|
files: ['**/*.ts'],
|
||||||
ignores: ['*.d.ts'],
|
ignores: ['**/*.d.ts'],
|
||||||
rules: {
|
rules: {
|
||||||
'typed-custom/restrict-template-expressions': error,
|
'typed-aet/restrict-template-expressions': error,
|
||||||
} satisfies Partial<LocalRuleOptions>,
|
} satisfies Partial<LocalRuleOptions>,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
12
src/presets/lingui.ts
Normal file
12
src/presets/lingui.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import type { LinguiRulesObject } from '@aet/eslint-define-config/src/rules/lingui';
|
||||||
|
import * as pluginLingui from 'eslint-plugin-lingui';
|
||||||
|
|
||||||
|
import { defineConfig } from '../types';
|
||||||
|
|
||||||
|
// https://the-guild.dev/graphql/eslint/rules
|
||||||
|
const linguiRules: Partial<LinguiRulesObject> = {};
|
||||||
|
|
||||||
|
export default defineConfig([
|
||||||
|
pluginLingui.configs['flat/recommended'],
|
||||||
|
{ rules: linguiRules },
|
||||||
|
]);
|
@ -12,6 +12,19 @@ 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,
|
||||||
|
{
|
||||||
|
rules: {
|
||||||
|
'vitest/expect-expect': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
assertFunctionNames: ['expect*', 'request.**.expect'],
|
||||||
|
additionalTestBlockFunctions: ['describe*'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,8 @@ 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,
|
||||||
|
'@eslint-react/hooks-extra/no-direct-set-state-in-use-effect': off,
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function react() {
|
export async function react() {
|
||||||
@ -23,9 +25,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,
|
||||||
|
},
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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)?)$/.source,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
@ -37,12 +37,17 @@ 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-floating-promises': [
|
||||||
|
'warn',
|
||||||
|
{
|
||||||
|
allowForKnownSafeCalls: [
|
||||||
|
{ from: 'package', name: ['it', 'describe', 'test'], package: 'node:test' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
'@typescript-eslint/no-misused-promises': [error, { checksVoidReturn: false }],
|
'@typescript-eslint/no-misused-promises': [error, { checksVoidReturn: false }],
|
||||||
'@typescript-eslint/no-namespace': off,
|
'@typescript-eslint/no-namespace': off,
|
||||||
'@typescript-eslint/no-unnecessary-type-assertion': error,
|
'@typescript-eslint/no-unnecessary-type-assertion': error,
|
||||||
|
@ -7,10 +7,12 @@ import { defineConfig } from '../types';
|
|||||||
|
|
||||||
const suggest = (suggest: string) => ({ suggest, fix: false });
|
const suggest = (suggest: string) => ({ suggest, fix: false });
|
||||||
|
|
||||||
// https://github.com/sindresorhus/eslint-plugin-unicorn/tree/28e7498ad06679bb92343db53bb40a7b5ba2990a
|
// https://github.com/sindresorhus/eslint-plugin-unicorn/tree/1774135a5ddbded2c89f82952e37a3e3bb01cdfa
|
||||||
const unicornRules: Partial<UnicornRulesObject> = {
|
const unicornRules: Partial<UnicornRulesObject> = {
|
||||||
'unicorn/better-regex': error,
|
'unicorn/better-regex': error,
|
||||||
'unicorn/consistent-destructuring': warn,
|
'unicorn/consistent-destructuring': warn,
|
||||||
|
'unicorn/consistent-empty-array-spread': error,
|
||||||
|
'unicorn/consistent-existence-index-check': error,
|
||||||
'unicorn/consistent-function-scoping': warn,
|
'unicorn/consistent-function-scoping': warn,
|
||||||
'unicorn/escape-case': error,
|
'unicorn/escape-case': error,
|
||||||
'unicorn/no-array-for-each': warn,
|
'unicorn/no-array-for-each': warn,
|
||||||
@ -22,6 +24,7 @@ const unicornRules: Partial<UnicornRulesObject> = {
|
|||||||
'unicorn/no-instanceof-array': error,
|
'unicorn/no-instanceof-array': error,
|
||||||
'unicorn/no-invalid-fetch-options': error,
|
'unicorn/no-invalid-fetch-options': error,
|
||||||
'unicorn/no-invalid-remove-event-listener': error,
|
'unicorn/no-invalid-remove-event-listener': error,
|
||||||
|
'unicorn/no-length-as-slice-end': error,
|
||||||
'unicorn/no-lonely-if': warn,
|
'unicorn/no-lonely-if': warn,
|
||||||
'unicorn/no-negation-in-equality-check': error,
|
'unicorn/no-negation-in-equality-check': error,
|
||||||
'unicorn/no-new-buffer': error,
|
'unicorn/no-new-buffer': error,
|
||||||
@ -38,6 +41,7 @@ const unicornRules: Partial<UnicornRulesObject> = {
|
|||||||
'unicorn/no-useless-undefined': error,
|
'unicorn/no-useless-undefined': error,
|
||||||
'unicorn/no-zero-fractions': error,
|
'unicorn/no-zero-fractions': error,
|
||||||
'unicorn/number-literal-case': error,
|
'unicorn/number-literal-case': error,
|
||||||
|
'unicorn/prefer-array-index-of': error,
|
||||||
'unicorn/prefer-array-find': error,
|
'unicorn/prefer-array-find': error,
|
||||||
'unicorn/prefer-array-flat': error,
|
'unicorn/prefer-array-flat': error,
|
||||||
'unicorn/prefer-array-flat-map': error,
|
'unicorn/prefer-array-flat-map': error,
|
||||||
@ -54,6 +58,7 @@ const unicornRules: Partial<UnicornRulesObject> = {
|
|||||||
'unicorn/prefer-json-parse-buffer': warn,
|
'unicorn/prefer-json-parse-buffer': warn,
|
||||||
'unicorn/prefer-keyboard-event-key': warn,
|
'unicorn/prefer-keyboard-event-key': warn,
|
||||||
'unicorn/prefer-logical-operator-over-ternary': warn,
|
'unicorn/prefer-logical-operator-over-ternary': warn,
|
||||||
|
'unicorn/prefer-math-min-max': error,
|
||||||
'unicorn/prefer-math-trunc': warn,
|
'unicorn/prefer-math-trunc': warn,
|
||||||
'unicorn/prefer-modern-dom-apis': error,
|
'unicorn/prefer-modern-dom-apis': error,
|
||||||
'unicorn/prefer-modern-math-apis': error,
|
'unicorn/prefer-modern-math-apis': error,
|
||||||
@ -66,14 +71,16 @@ const unicornRules: Partial<UnicornRulesObject> = {
|
|||||||
'unicorn/prefer-regexp-test': error,
|
'unicorn/prefer-regexp-test': error,
|
||||||
'unicorn/prefer-set-has': warn,
|
'unicorn/prefer-set-has': warn,
|
||||||
'unicorn/prefer-set-size': error,
|
'unicorn/prefer-set-size': error,
|
||||||
'unicorn/prefer-string-raw': error,
|
'unicorn/prefer-string-raw': warn,
|
||||||
'unicorn/prefer-string-slice': error,
|
'unicorn/prefer-string-slice': error,
|
||||||
'unicorn/prefer-string-starts-ends-with': warn,
|
'unicorn/prefer-string-starts-ends-with': warn,
|
||||||
'unicorn/prefer-string-trim-start-end': error,
|
'unicorn/prefer-string-trim-start-end': error,
|
||||||
'unicorn/prefer-switch': warn,
|
'unicorn/prefer-switch': warn,
|
||||||
'unicorn/prefer-ternary': warn,
|
'unicorn/prefer-ternary': warn,
|
||||||
|
'unicorn/prefer-type-error': warn,
|
||||||
'unicorn/relative-url-style': warn,
|
'unicorn/relative-url-style': warn,
|
||||||
'unicorn/require-number-to-fixed-digits-argument': error,
|
'unicorn/require-number-to-fixed-digits-argument': error,
|
||||||
|
'unicorn/require-post-message-target-origin': warn,
|
||||||
'unicorn/string-content': [
|
'unicorn/string-content': [
|
||||||
warn,
|
warn,
|
||||||
{
|
{
|
||||||
@ -100,17 +107,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 +120,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,
|
||||||
},
|
},
|
||||||
|
@ -10,28 +10,15 @@ const prettier: Config = {
|
|||||||
plugins: [],
|
plugins: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function defineConfig({
|
export default function defineConfig(
|
||||||
tailwind,
|
config: Partial<Config> & {
|
||||||
...config
|
tailwind?: boolean;
|
||||||
}: Partial<Config> & {
|
},
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Reference in New Issue
Block a user