@aiou/eslint-config 3.1.1 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -4
- package/dist/index.mjs +67 -62
- package/dts/configs/perfectionist.d.ts +2 -0
- package/dts/configs/storybook.d.ts +2 -0
- package/dts/globs.d.ts +2 -0
- package/dts/index.d.ts +3 -2
- package/dts/typegen.d.ts +4571 -2475
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ Flat ESLint config with TypeScript, React, SSR, and more.
|
|
|
10
10
|
- TypeScript, YAML, JSONC, Markdown, TOML support
|
|
11
11
|
- Built-in React rules via `@eslint-react`, react-refresh, and SSR-safe linting
|
|
12
12
|
- Auto-detected framework support (Next.js, Tailwind CSS)
|
|
13
|
-
- Import sorting
|
|
13
|
+
- Import sorting and unused import removal via `eslint-plugin-perfectionist`
|
|
14
14
|
- Sorted keys for `package.json` and `tsconfig.json`
|
|
15
15
|
- Visual linting progress reporter
|
|
16
16
|
|
|
@@ -96,7 +96,7 @@ The following plugins are enabled automatically when their packages are found in
|
|
|
96
96
|
| Arrow parens | `as-needed` |
|
|
97
97
|
| Curly | `all` |
|
|
98
98
|
| File naming | `kebab-case` (via unicorn) |
|
|
99
|
-
| Import sorting |
|
|
99
|
+
| Import sorting | type-imports → builtins/externals → internal → relative → side-effects (via `perfectionist`) |
|
|
100
100
|
|
|
101
101
|
## Included Plugins
|
|
102
102
|
|
|
@@ -108,8 +108,7 @@ The following plugins are enabled automatically when their packages are found in
|
|
|
108
108
|
| `eslint-plugin-react-refresh` | React Refresh compatibility |
|
|
109
109
|
| `@stylistic/eslint-plugin` | Formatting rules |
|
|
110
110
|
| `eslint-plugin-import-x` | Import rules |
|
|
111
|
-
| `eslint-plugin-
|
|
112
|
-
| `eslint-plugin-import-newlines` | Multi-line import enforcement |
|
|
111
|
+
| `eslint-plugin-perfectionist` | Import sorting, type sorting (union/intersection/named imports) |
|
|
113
112
|
| `eslint-plugin-unused-imports` | Unused import/variable removal |
|
|
114
113
|
| `eslint-plugin-unicorn` | Best practice rules |
|
|
115
114
|
| `eslint-plugin-n` | Node.js rules |
|
package/dist/index.mjs
CHANGED
|
@@ -2,9 +2,7 @@ import { FlatConfigComposer } from 'eslint-flat-config-utils';
|
|
|
2
2
|
import { isPackageExists } from 'local-pkg';
|
|
3
3
|
import pluginComments from '@eslint-community/eslint-plugin-eslint-comments';
|
|
4
4
|
import ignoreGlobs from '@aiou/eslint-ignore';
|
|
5
|
-
import pluginImportNewlines from 'eslint-plugin-import-newlines';
|
|
6
5
|
import pluginImport from 'eslint-plugin-import-x';
|
|
7
|
-
import pluginSimpleImportSort from 'eslint-plugin-simple-import-sort';
|
|
8
6
|
import pluginUnsedImports from 'eslint-plugin-unused-imports';
|
|
9
7
|
import pluginN from 'eslint-plugin-n';
|
|
10
8
|
import pluginPromise from 'eslint-plugin-promise';
|
|
@@ -12,11 +10,13 @@ import globals from 'globals';
|
|
|
12
10
|
import pluginJsonc from 'eslint-plugin-jsonc';
|
|
13
11
|
import pluginMarkdown from '@eslint/markdown';
|
|
14
12
|
import pluginNext from '@next/eslint-plugin-next';
|
|
13
|
+
import pluginPerfectionist from 'eslint-plugin-perfectionist';
|
|
15
14
|
import pluginProgress from '@aiou/eslint-plugin-progress';
|
|
16
15
|
import pluginReact from '@eslint-react/eslint-plugin';
|
|
17
16
|
import pluginReactHooks from 'eslint-plugin-react-hooks';
|
|
18
17
|
import pluginReactRefresh from 'eslint-plugin-react-refresh';
|
|
19
18
|
import { configs } from 'eslint-plugin-regexp';
|
|
19
|
+
import storybookPlugin from 'eslint-plugin-storybook';
|
|
20
20
|
import pluginStylistic from '@stylistic/eslint-plugin';
|
|
21
21
|
import { createRequire } from 'node:module';
|
|
22
22
|
import pluginToml from 'eslint-plugin-toml';
|
|
@@ -76,8 +76,6 @@ const imports = () => {
|
|
|
76
76
|
{
|
|
77
77
|
plugins: {
|
|
78
78
|
import: pluginImport,
|
|
79
|
-
"simple-import-sort": pluginSimpleImportSort,
|
|
80
|
-
"import-newlines": pluginImportNewlines,
|
|
81
79
|
"unused-imports": pluginUnsedImports
|
|
82
80
|
},
|
|
83
81
|
rules: {
|
|
@@ -85,29 +83,6 @@ const imports = () => {
|
|
|
85
83
|
// off: controlled by import/order
|
|
86
84
|
"import/order": "off",
|
|
87
85
|
"sort-imports": "off",
|
|
88
|
-
"simple-import-sort/imports": [
|
|
89
|
-
"warn",
|
|
90
|
-
{
|
|
91
|
-
groups: [
|
|
92
|
-
// Side effect imports.
|
|
93
|
-
[String.raw`^\u0000`],
|
|
94
|
-
// Node.js builtins prefixed with `node:`.
|
|
95
|
-
["^node:"],
|
|
96
|
-
// Packages.
|
|
97
|
-
// Things that start with a letter (or digit or underscore), or `@` followed by a letter.
|
|
98
|
-
[String.raw`^@?\w`],
|
|
99
|
-
// Relative imports.
|
|
100
|
-
// Absolute imports and other imports such as `@/foo` or `~/foo`.
|
|
101
|
-
// Anything not matched in another group.
|
|
102
|
-
["^", String.raw`^\.`, String.raw`^@/\w`, String.raw`^~/\w`],
|
|
103
|
-
// Virtual modules prefixed with `virtual:` or `virtual-`, rollup & vite favor
|
|
104
|
-
["^virtual:", "^virtual-"],
|
|
105
|
-
// Types
|
|
106
|
-
["^[^/\\.].*\0$", "^\\..*\0$"]
|
|
107
|
-
]
|
|
108
|
-
}
|
|
109
|
-
],
|
|
110
|
-
"simple-import-sort/exports": "off",
|
|
111
86
|
"import/first": "error",
|
|
112
87
|
"import/newline-after-import": "error",
|
|
113
88
|
"import/no-duplicates": "error",
|
|
@@ -133,15 +108,6 @@ const imports = () => {
|
|
|
133
108
|
args: "after-used",
|
|
134
109
|
argsIgnorePattern: "^_"
|
|
135
110
|
}
|
|
136
|
-
],
|
|
137
|
-
// Enforce newlines inside named import
|
|
138
|
-
"import-newlines/enforce": [
|
|
139
|
-
"error",
|
|
140
|
-
{
|
|
141
|
-
items: 2,
|
|
142
|
-
"max-len": 120,
|
|
143
|
-
semi: false
|
|
144
|
-
}
|
|
145
111
|
]
|
|
146
112
|
}
|
|
147
113
|
},
|
|
@@ -193,7 +159,8 @@ const imports = () => {
|
|
|
193
159
|
// ignore require third packages in .eslintrc.* e.g. eslint-define-config
|
|
194
160
|
`**/.eslintrc.${GLOB_SCRIPT_EXT}`,
|
|
195
161
|
`**/**/eslint.config.${GLOB_SCRIPT_EXT}`,
|
|
196
|
-
"**/{vite,esbuild,rollup,webpack,rspack}.ts"
|
|
162
|
+
"**/{vite,esbuild,rollup,webpack,rspack}.ts",
|
|
163
|
+
"**/vitest.setup.*"
|
|
197
164
|
],
|
|
198
165
|
rules: {
|
|
199
166
|
"import/no-extraneous-dependencies": "off"
|
|
@@ -753,7 +720,8 @@ const markdown = () => {
|
|
|
753
720
|
"import/no-anonymous-default-export": "off",
|
|
754
721
|
"react-refresh/only-export-components": "off",
|
|
755
722
|
"react/jsx-no-undef": "off",
|
|
756
|
-
"unicorn/filename-case": "off"
|
|
723
|
+
"unicorn/filename-case": "off",
|
|
724
|
+
"perfectionist/sort-imports": "off"
|
|
757
725
|
}
|
|
758
726
|
}
|
|
759
727
|
];
|
|
@@ -775,6 +743,46 @@ const next = () => {
|
|
|
775
743
|
return config;
|
|
776
744
|
};
|
|
777
745
|
|
|
746
|
+
const perfectionist = () => {
|
|
747
|
+
return [
|
|
748
|
+
{
|
|
749
|
+
plugins: {
|
|
750
|
+
perfectionist: pluginPerfectionist
|
|
751
|
+
},
|
|
752
|
+
rules: {
|
|
753
|
+
"perfectionist/sort-imports": [
|
|
754
|
+
"warn",
|
|
755
|
+
{
|
|
756
|
+
type: "natural",
|
|
757
|
+
order: "asc",
|
|
758
|
+
newlinesBetween: "ignore",
|
|
759
|
+
groups: [
|
|
760
|
+
"type-import",
|
|
761
|
+
["value-builtin", "value-external"],
|
|
762
|
+
"type-internal",
|
|
763
|
+
"value-internal",
|
|
764
|
+
["type-parent", "type-sibling", "type-index"],
|
|
765
|
+
["value-parent", "value-sibling", "value-index"],
|
|
766
|
+
"side-effect",
|
|
767
|
+
"unknown"
|
|
768
|
+
],
|
|
769
|
+
customGroups: [
|
|
770
|
+
{
|
|
771
|
+
groupName: "virtual-modules",
|
|
772
|
+
elementNamePattern: ["^virtual:", "^virtual-"]
|
|
773
|
+
}
|
|
774
|
+
],
|
|
775
|
+
internalPattern: ["^~/.+", "^@/.+", "^#.+"]
|
|
776
|
+
}
|
|
777
|
+
],
|
|
778
|
+
"perfectionist/sort-union-types": ["error", { type: "natural", order: "asc" }],
|
|
779
|
+
"perfectionist/sort-intersection-types": ["error", { type: "natural", order: "asc" }],
|
|
780
|
+
"perfectionist/sort-named-imports": ["warn", { type: "natural", order: "asc" }]
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
];
|
|
784
|
+
};
|
|
785
|
+
|
|
778
786
|
const progress = () => {
|
|
779
787
|
const config = [
|
|
780
788
|
{
|
|
@@ -823,33 +831,28 @@ const react = () => {
|
|
|
823
831
|
react: pluginReact,
|
|
824
832
|
"react-dom": pluginReact,
|
|
825
833
|
"react-hooks": pluginReactHooks,
|
|
826
|
-
"react-hooks-extra": pluginReact,
|
|
827
834
|
"react-naming-convention": pluginReact,
|
|
828
835
|
"react-refresh": pluginReactRefresh,
|
|
829
836
|
"react-web-api": pluginReact
|
|
830
837
|
},
|
|
831
838
|
rules: {
|
|
832
839
|
...renameRules(pluginReact.configs["recommended-typescript"].rules, { "@eslint-react": "react" }),
|
|
833
|
-
...renameRules(pluginReact.configs.dom.rules, { "@eslint-react": "react-dom" }),
|
|
834
|
-
...renameRules(pluginReact.configs.x.rules, { "@eslint-react": "react-hooks-extra" }),
|
|
835
|
-
...renameRules(pluginReact.configs.x.rules, { "@eslint-react": "react-naming-convention" }),
|
|
836
|
-
...renameRules(pluginReact.configs["web-api"].rules, { "@eslint-react": "react-web-api" }),
|
|
837
840
|
...pluginReactHooks.configs.flat.recommended.rules,
|
|
838
841
|
"react/no-nested-component-definitions": "warn",
|
|
839
|
-
"react-dom/no-unknown-property": "off",
|
|
842
|
+
"react-dom/dom-no-unknown-property": "off",
|
|
840
843
|
"react-refresh/only-export-components": "warn"
|
|
841
844
|
}
|
|
842
845
|
},
|
|
843
846
|
{
|
|
844
847
|
files: ["src/components/**/*.{ts,tsx}"],
|
|
845
848
|
rules: {
|
|
846
|
-
"
|
|
849
|
+
"unicorn/filename-case": ["warn", { case: "pascalCase" }]
|
|
847
850
|
}
|
|
848
851
|
},
|
|
849
852
|
{
|
|
850
853
|
files: ["src/hooks/**/use*.{ts,tsx}"],
|
|
851
854
|
rules: {
|
|
852
|
-
"
|
|
855
|
+
"unicorn/filename-case": ["warn", { case: "kebabCase" }]
|
|
853
856
|
}
|
|
854
857
|
},
|
|
855
858
|
{
|
|
@@ -974,6 +977,13 @@ const regexp = () => {
|
|
|
974
977
|
return config;
|
|
975
978
|
};
|
|
976
979
|
|
|
980
|
+
const storybook = () => {
|
|
981
|
+
const config = [
|
|
982
|
+
...storybookPlugin.configs["flat/recommended"]
|
|
983
|
+
];
|
|
984
|
+
return config;
|
|
985
|
+
};
|
|
986
|
+
|
|
977
987
|
const stylistic = () => {
|
|
978
988
|
const config = pluginStylistic.configs.customize({
|
|
979
989
|
indent: 2,
|
|
@@ -1180,10 +1190,7 @@ const typescript = () => {
|
|
|
1180
1190
|
],
|
|
1181
1191
|
// Limit `interface` define object types, users could override with *.d.ts declare
|
|
1182
1192
|
"@typescript-eslint/consistent-type-definitions": ["error", "interface"],
|
|
1183
|
-
"@typescript-eslint/prefer-ts-expect-error": "warn",
|
|
1184
1193
|
"@typescript-eslint/default-param-last": "error",
|
|
1185
|
-
// Sort type S = A | B
|
|
1186
|
-
"@typescript-eslint/sort-type-constituents": "error",
|
|
1187
1194
|
"@typescript-eslint/unbound-method": "off",
|
|
1188
1195
|
"@typescript-eslint/prefer-for-of": "error",
|
|
1189
1196
|
// When .ts files compiled to .mjs, will throw require is not found
|
|
@@ -1227,8 +1234,7 @@ const typescript = () => {
|
|
|
1227
1234
|
"error",
|
|
1228
1235
|
{ functions: false, classes: false, variables: true }
|
|
1229
1236
|
],
|
|
1230
|
-
"no-loss-of-precision": "
|
|
1231
|
-
"@typescript-eslint/no-loss-of-precision": "error",
|
|
1237
|
+
"no-loss-of-precision": "error",
|
|
1232
1238
|
"no-unused-expressions": "off",
|
|
1233
1239
|
"@typescript-eslint/no-unused-expressions": ["error", {
|
|
1234
1240
|
allowShortCircuit: true,
|
|
@@ -1236,19 +1242,13 @@ const typescript = () => {
|
|
|
1236
1242
|
allowTaggedTemplates: true
|
|
1237
1243
|
}],
|
|
1238
1244
|
// off
|
|
1239
|
-
"@typescript-eslint/camelcase": "off",
|
|
1240
1245
|
"@typescript-eslint/explicit-function-return-type": "off",
|
|
1241
1246
|
"@typescript-eslint/explicit-member-accessibility": "off",
|
|
1242
1247
|
"@typescript-eslint/no-explicit-any": "off",
|
|
1243
|
-
"@typescript-eslint/no-parameter-properties": "off",
|
|
1244
|
-
"@typescript-eslint/no-empty-interface": "off",
|
|
1245
|
-
"@typescript-eslint/ban-ts-ignore": "off",
|
|
1246
1248
|
"@typescript-eslint/no-empty-function": "off",
|
|
1247
1249
|
"@typescript-eslint/no-non-null-assertion": "off",
|
|
1248
1250
|
"@typescript-eslint/explicit-module-boundary-types": "off",
|
|
1249
|
-
"@typescript-eslint/ban-types": "off",
|
|
1250
1251
|
"@typescript-eslint/no-namespace": "off",
|
|
1251
|
-
"@typescript-eslint/no-var-requires": "off",
|
|
1252
1252
|
// https://www.npmjs.com/package/eslint-plugin-unused-imports
|
|
1253
1253
|
"@typescript-eslint/no-unused-vars": "off",
|
|
1254
1254
|
"no-void": ["error", { allowAsStatement: true }],
|
|
@@ -1292,6 +1292,8 @@ const unicorn = () => {
|
|
|
1292
1292
|
"unicorn/prefer-string-starts-ends-with": "error",
|
|
1293
1293
|
"unicorn/prefer-type-error": "error",
|
|
1294
1294
|
"unicorn/throw-new-error": "error",
|
|
1295
|
+
"unicorn/prevent-abbreviations": "off",
|
|
1296
|
+
"unicorn/no-null": "off",
|
|
1295
1297
|
"unicorn/filename-case": ["error", {
|
|
1296
1298
|
case: "kebabCase",
|
|
1297
1299
|
ignore: [/^[A-Z]+\.md$/, /^[A-Z]+\.yml$/, /^\.?[A-Z]/, /^Dockerfile$/]
|
|
@@ -1328,7 +1330,8 @@ const presetJavascript = [
|
|
|
1328
1330
|
...javascript(),
|
|
1329
1331
|
...comments(),
|
|
1330
1332
|
...imports(),
|
|
1331
|
-
...unicorn()
|
|
1333
|
+
...unicorn(),
|
|
1334
|
+
...perfectionist()
|
|
1332
1335
|
];
|
|
1333
1336
|
const presetTypescript = [
|
|
1334
1337
|
...presetJavascript,
|
|
@@ -1345,18 +1348,20 @@ const presetDefault = [
|
|
|
1345
1348
|
...react(),
|
|
1346
1349
|
...stylistic(),
|
|
1347
1350
|
...presetLangsExtensions,
|
|
1348
|
-
...progress()
|
|
1351
|
+
...progress(),
|
|
1352
|
+
...storybook()
|
|
1349
1353
|
];
|
|
1350
1354
|
const all = [
|
|
1351
1355
|
...presetDefault,
|
|
1352
1356
|
...tailwindcss(),
|
|
1353
1357
|
...next(),
|
|
1354
1358
|
...ssrReact(),
|
|
1355
|
-
...regexp()
|
|
1359
|
+
...regexp(),
|
|
1360
|
+
...storybook()
|
|
1356
1361
|
];
|
|
1357
|
-
const aiou = ({ ssr = true, regexp: regexp$1 = true
|
|
1362
|
+
const aiou = ({ ssr = true, regexp: regexp$1 = true, tailwindcss: enableTailwindcss = true } = {}, ...userConfigs) => {
|
|
1358
1363
|
const configs = [...presetDefault];
|
|
1359
|
-
if (isPackageExists("tailwindcss")) {
|
|
1364
|
+
if (enableTailwindcss && isPackageExists("tailwindcss")) {
|
|
1360
1365
|
configs.push(...tailwindcss());
|
|
1361
1366
|
}
|
|
1362
1367
|
if (isPackageExists("next")) {
|
package/dts/globs.d.ts
CHANGED
|
@@ -17,3 +17,5 @@ export declare const GLOB_MARKDOWN = "**/*.md";
|
|
|
17
17
|
export declare const GLOB_VUE = "**/*.vue";
|
|
18
18
|
export declare const GLOB_YAML = "**/*.y?(a)ml";
|
|
19
19
|
export declare const GLOB_WORKFLOW_YAML = "**/.github/**/*.y?(a)ml";
|
|
20
|
+
export declare const GLOB_STORYBOOK_STORIES = "**/*.stories.@(ts|tsx|js|jsx|mjs|cjs)";
|
|
21
|
+
export declare const GLOB_STORYBOOK_MAIN = ".storybook/main.@(js|cjs|mjs|ts)";
|
package/dts/index.d.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { FlatConfigComposer } from 'eslint-flat-config-utils';
|
|
2
1
|
import type { Linter } from 'eslint';
|
|
3
2
|
import type { Arrayable, Awaitable } from 'eslint-flat-config-utils';
|
|
3
|
+
import { FlatConfigComposer } from 'eslint-flat-config-utils';
|
|
4
4
|
import type { Config } from './type';
|
|
5
5
|
import type { ConfigNames } from './typegen';
|
|
6
6
|
export declare const all: Config[];
|
|
7
7
|
interface Options {
|
|
8
8
|
ssr?: boolean;
|
|
9
9
|
regexp?: boolean;
|
|
10
|
+
tailwindcss?: boolean;
|
|
10
11
|
}
|
|
11
|
-
export declare const aiou: ({ ssr, regexp }?: Options, ...userConfigs: Awaitable<Arrayable<Config> | FlatConfigComposer<any, any> | Linter.Config[]>[]) => FlatConfigComposer<Config, ConfigNames>;
|
|
12
|
+
export declare const aiou: ({ ssr, regexp, tailwindcss: enableTailwindcss }?: Options, ...userConfigs: Awaitable<Arrayable<Config> | FlatConfigComposer<any, any> | Linter.Config[]>[]) => FlatConfigComposer<Config, ConfigNames>;
|
|
12
13
|
export {};
|