@slashnephy/eslint-config 2.3.203 → 3.0.1

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.
Files changed (62) hide show
  1. package/README.md +20 -6
  2. package/package.json +25 -41
  3. package/src/base/common.js +37 -0
  4. package/src/base/common.ts +42 -0
  5. package/src/base/graphql.js +41 -8
  6. package/src/base/graphql.ts +48 -15
  7. package/src/base/javascript.js +155 -70
  8. package/src/base/javascript.ts +218 -180
  9. package/src/base/package.json.js +15 -0
  10. package/src/base/package.json.ts +16 -0
  11. package/src/base/typescript.js +90 -46
  12. package/src/base/typescript.ts +229 -212
  13. package/src/base/yaml.js +20 -14
  14. package/src/base/yaml.ts +24 -16
  15. package/src/environments/cloudflareWorkers.js +9 -0
  16. package/src/environments/cloudflareWorkers.ts +10 -0
  17. package/src/environments/node.js +50 -0
  18. package/src/environments/node.ts +55 -0
  19. package/src/{presets → environments}/userscript.js +10 -5
  20. package/src/{presets → environments}/userscript.ts +10 -7
  21. package/src/frameworks/jest.js +10 -0
  22. package/src/frameworks/jest.ts +11 -0
  23. package/src/frameworks/next.js.js +24 -0
  24. package/src/frameworks/next.js.ts +25 -0
  25. package/src/frameworks/react.js +128 -0
  26. package/src/frameworks/react.ts +134 -0
  27. package/src/frameworks/relay.js +13 -0
  28. package/src/frameworks/relay.ts +14 -0
  29. package/src/frameworks/storybook.js +7 -0
  30. package/src/frameworks/storybook.ts +8 -0
  31. package/src/frameworks/vite.js +7 -0
  32. package/src/frameworks/vite.ts +8 -0
  33. package/src/frameworks/vitest.js +20 -0
  34. package/src/frameworks/vitest.ts +21 -0
  35. package/src/index.js +60 -102
  36. package/src/index.ts +65 -130
  37. package/src/framework/emotion.js +0 -17
  38. package/src/framework/emotion.ts +0 -20
  39. package/src/framework/jest.js +0 -14
  40. package/src/framework/jest.ts +0 -17
  41. package/src/framework/next.js.js +0 -14
  42. package/src/framework/next.js.ts +0 -13
  43. package/src/framework/react.js +0 -79
  44. package/src/framework/react.ts +0 -98
  45. package/src/framework/relay.js +0 -9
  46. package/src/framework/relay.ts +0 -10
  47. package/src/framework/vite.js +0 -8
  48. package/src/framework/vite.ts +0 -8
  49. package/src/framework/vitest.js +0 -6
  50. package/src/framework/vitest.ts +0 -9
  51. package/src/presets/a11y.js +0 -28
  52. package/src/presets/a11y.ts +0 -27
  53. package/src/presets/allow-default-export.js +0 -8
  54. package/src/presets/allow-default-export.ts +0 -9
  55. package/src/presets/build-configuration.js +0 -12
  56. package/src/presets/build-configuration.ts +0 -13
  57. package/src/presets/node.js +0 -7
  58. package/src/presets/node.ts +0 -8
  59. package/src/presets/package.json.js +0 -17
  60. package/src/presets/package.json.ts +0 -17
  61. package/src/presets/style.js +0 -23
  62. package/src/presets/style.ts +0 -39
@@ -1,187 +1,225 @@
1
- import standard from 'eslint-config-standard'
1
+ import eslint from '@eslint/js'
2
+ // @ts-expect-error 型定義ファイルがない
3
+ import eslintCommentsConfig from '@eslint-community/eslint-plugin-eslint-comments/configs'
4
+ import importXPlugin from 'eslint-plugin-import-x'
5
+ // @ts-expect-error 型定義ファイルがない
6
+ import promisePlugin from 'eslint-plugin-promise'
7
+ import unusedImportsPlugin from 'eslint-plugin-unused-imports'
8
+ import tseslint, { config } from 'typescript-eslint'
2
9
 
3
- import type { Linter } from 'eslint'
4
-
5
- /**
6
- * JavaScript 関連の eslint プリセット
7
- */
8
- module.exports = {
9
- extends: [
10
- 'plugin:eslint-comments/recommended',
11
- 'plugin:node/recommended',
12
- 'plugin:import/recommended',
13
- 'plugin:xss/recommended',
14
- ],
15
- plugins: ['import', 'promise', 'n', 'unused-imports'],
16
- env: {
17
- node: true,
18
- es2022: true,
10
+ export const javaScript = config(
11
+ {
12
+ files: ['**/*.cjs'],
13
+ languageOptions: {
14
+ sourceType: 'commonjs',
15
+ },
16
+ },
17
+ {
18
+ files: ['**/*.{js,mjs,jsx}'],
19
+ languageOptions: {
20
+ sourceType: 'module',
21
+ },
19
22
  },
20
- parserOptions: {
21
- ecmaVersion: 'latest',
23
+
24
+ {
25
+ name: '@eslint/js',
26
+ files: ['**/*.{js,cjs,mjs,jsx,ts,cts,mts,tsx}'],
27
+ extends: [eslint.configs.recommended],
28
+ languageOptions: {
29
+ ecmaVersion: 'latest',
30
+ parser: tseslint.parser,
31
+ },
32
+ rules: {
33
+ // アロー関数を優先
34
+ 'prefer-arrow-callback': 'error',
35
+ // 関数宣言は function xxx() {} にする
36
+ 'func-style': ['error', 'declaration', { allowArrowFunctions: true }],
37
+ // 中括弧の省略を禁止
38
+ 'curly': 'error',
39
+ // テンプレート文字列を優先
40
+ 'prefer-template': 'error',
41
+ // == 比較 👉 === 比較
42
+ 'eqeqeq': 'error',
43
+ // *.js で 'use strict'; を強制
44
+ 'strict': ['error', 'global'],
45
+ // 特定の構文を禁止
46
+ 'no-restricted-syntax': [
47
+ 'error',
48
+ // 数値リテラル以外での Array#at() の使用を禁止
49
+ // https://qiita.com/printf_moriken/items/da03f55cb626617c1958
50
+ {
51
+ selector:
52
+ // eslint-disable-next-line @stylistic/quotes -- prettier と競合している
53
+ "CallExpression[callee.property.name='at']:not([arguments.0.type='Literal'],[arguments.0.type='UnaryExpression'][arguments.0.argument.type='Literal'])",
54
+ message: 'at method accepts only a literal argument',
55
+ },
56
+ ],
57
+ // foo["bar"] 👉 foo.bar
58
+ 'dot-notation': 'error',
59
+ // {foo: foo} 👉 {foo}
60
+ 'object-shorthand': ['error', 'always'],
61
+ // Array 系メソッドで return を強制
62
+ 'array-callback-return': ['error'],
63
+ // ループ内では await を禁止
64
+ 'no-await-in-loop': 'error',
65
+ // 操作が値に影響しない式を禁止
66
+ 'no-constant-binary-expression': 'error',
67
+ // コンストラクター内で return を禁止
68
+ 'no-constructor-return': 'error',
69
+ // 関数の返り値としての Promise executor を禁止
70
+ 'no-promise-executor-return': 'error',
71
+ // 自身との比較 (e.g. foo === foo) を禁止
72
+ 'no-self-compare': 'error',
73
+ // 非テンプレート文字列で ${foo} を禁止
74
+ // "Hello, ${name}" 👉 `Hello, ${name}`
75
+ 'no-template-curly-in-string': 'error',
76
+ // 更新されないループ条件を禁止
77
+ 'no-unmodified-loop-condition': 'error',
78
+ // 到達できないループを禁止
79
+ 'no-unreachable-loop': 'error',
80
+ // 未使用の private メンバーを禁止
81
+ 'no-unused-private-class-members': 'error',
82
+ // スレッドセーフで安全に更新されないコードを禁止
83
+ 'require-atomic-updates': 'error',
84
+ // func () 👉 func()
85
+ 'func-call-spacing': ['error', 'never'],
86
+ // ペアになっていない setter を禁止
87
+ 'accessor-pairs': 'error',
88
+ // キャメルケースに強制しない
89
+ 'camelcase': 'off',
90
+ // switch 文で default を強制しない
91
+ 'default-case': 'off',
92
+ // continue 文を許可
93
+ 'no-continue': 'off',
94
+ // _ で始まるメンバー名を許可
95
+ 'no-underscore-dangle': 'off',
96
+ // 自身より後に宣言されたメンバーの使用を許可
97
+ 'no-use-before-define': 'off',
98
+ // console.* の使用を許可
99
+ 'no-console': 'off',
100
+ // 深い三項演算子を許可
101
+ 'no-nested-ternary': 'off',
102
+ // i++ インクリメントを許可
103
+ 'no-plusplus': 'off',
104
+ // return の省略などを許可
105
+ 'consistent-return': 'off',
106
+ // 空行を挟む
107
+ 'padding-line-between-statements': [
108
+ 'warn',
109
+ // return 前に空行
110
+ { blankLine: 'always', prev: '*', next: 'return' },
111
+ // ディレクティブ後に空行
112
+ { blankLine: 'always', prev: 'directive', next: '*' },
113
+ { blankLine: 'any', prev: 'directive', next: 'directive' },
114
+ ],
115
+ // void Promise を許可
116
+ 'no-void': 'off',
117
+ // 1 <= x < 10 を許可
118
+ 'yoda': [
119
+ 'error',
120
+ 'never',
121
+ {
122
+ exceptRange: true,
123
+ },
124
+ ],
125
+ },
22
126
  },
23
- globals: {
24
- document: 'readonly',
25
- navigator: 'readonly',
26
- window: 'readonly',
127
+ {
128
+ name: '@eslint-community/eslint-plugin-eslint-comments',
129
+ extends: [eslintCommentsConfig.recommended],
27
130
  },
28
- rules: {
29
- ...standard.rules,
30
- // 不要なルール無効化コメントを報告
31
- 'eslint-comments/no-unused-disable': 'error',
32
- // default export を禁止
33
- 'import/no-default-export': 'error',
34
- // アロー関数を優先
35
- 'prefer-arrow-callback': 'error',
36
- // 関数宣言は function xxx() {} にする
37
- 'func-style': ['error', 'declaration', { allowArrowFunctions: true }],
38
- // 中括弧の省略を禁止
39
- curly: 'error',
40
- // テンプレート文字列を優先
41
- 'prefer-template': 'error',
42
- // == 比較 👉 === 比較
43
- eqeqeq: 'error',
44
- // *.js で 'use strict'; を強制
45
- strict: ['error', 'global'],
46
- // import 順を並び替える
47
- 'import/order': [
48
- 'warn',
49
- {
50
- // 組み込み → 外部依存 → 内部依存 → object → type の順にする
51
- groups: [
52
- 'builtin',
53
- 'external',
54
- ['parent', 'sibling', 'index'],
55
- 'object',
56
- 'type',
57
- 'unknown',
58
- ],
59
- // カテゴリー間に改行を入れる
60
- 'newlines-between': 'always',
61
- // 大文字小文字区別なしで ABC 順にする
62
- alphabetize: {
63
- order: 'asc',
64
- caseInsensitive: true,
131
+ {
132
+ name: 'eslint-plugin-import-x',
133
+ files: ['**/*.{js,cjs,mjs,jsx,ts,cts,mts,tsx}'],
134
+ extends: [importXPlugin.flatConfigs.recommended],
135
+ settings: {
136
+ 'import-x/resolver': {
137
+ node: {
138
+ extensions: ['.js', '.cjs', '.mjs', '.jsx', '.ts', '.cts', '.mts', '.tsx', '.json'],
139
+ },
140
+ typescript: {
141
+ alwaysTryTypes: true,
65
142
  },
66
- pathGroups: [
67
- // **.css は最後に配置する
68
- {
69
- pattern: '**.css',
70
- group: 'type',
71
- position: 'after',
72
- },
73
- ],
74
- // **.css が import 順最後ではないときに警告
75
- warnOnUnassignedImports: true,
76
- },
77
- ],
78
- // 不要 import 文を禁止
79
- 'unused-imports/no-unused-imports': 'error',
80
- // 特定の構文を禁止
81
- 'no-restricted-syntax': [
82
- 'error',
83
- // 数値リテラル以外での Array#at() の使用を禁止
84
- // https://qiita.com/printf_moriken/items/da03f55cb626617c1958
85
- {
86
- selector:
87
- // eslint-disable-next-line @stylistic/quotes -- prettier と競合している
88
- "CallExpression[callee.property.name='at']:not([arguments.0.type='Literal'],[arguments.0.type='UnaryExpression'][arguments.0.argument.type='Literal'])",
89
- message: 'at method accepts only a literal argument',
90
- },
91
- ],
92
- // 非同期メソッドを優先
93
- 'node/prefer-promises/dns': 'error',
94
- 'node/prefer-promises/fs': 'error',
95
- // 構文のバージョンチェックを無効化
96
- 'node/no-unsupported-features/es-syntax': 'off',
97
- // 不正確な import チェックを無効化
98
- 'node/no-missing-import': 'off',
99
- 'node/no-extraneous-import': 'off',
100
- 'node/no-unpublished-import': 'off',
101
- 'import/no-import-module-exports': 'off',
102
- 'import/no-extraneous-dependencies': 'off',
103
- // foo["bar"] 👉 foo.bar
104
- 'dot-notation': 'error',
105
- // {foo: foo} 👉 {foo}
106
- 'object-shorthand': ['error', 'always'],
107
- // Array 系メソッドで return を強制
108
- 'array-callback-return': ['error'],
109
- // ループ内では await を禁止
110
- 'no-await-in-loop': 'error',
111
- // 操作が値に影響しない式を禁止
112
- 'no-constant-binary-expression': 'error',
113
- // コンストラクター内で return を禁止
114
- 'no-constructor-return': 'error',
115
- // 関数の返り値としての Promise executor を禁止
116
- 'no-promise-executor-return': 'error',
117
- // 自身との比較 (e.g. foo === foo) を禁止
118
- 'no-self-compare': 'error',
119
- // 非テンプレート文字列で ${foo} を禁止
120
- // "Hello, ${name}" 👉 `Hello, ${name}`
121
- 'no-template-curly-in-string': 'error',
122
- // 更新されないループ条件を禁止
123
- 'no-unmodified-loop-condition': 'error',
124
- // 到達できないループを禁止
125
- 'no-unreachable-loop': 'error',
126
- // 未使用の private メンバーを禁止
127
- 'no-unused-private-class-members': 'error',
128
- // スレッドセーフで安全に更新されないコードを禁止
129
- 'require-atomic-updates': 'error',
130
- // func () 👉 func()
131
- 'func-call-spacing': ['error', 'never'],
132
- // ペアになっていない setter を禁止
133
- 'accessor-pairs': 'error',
134
- // キャメルケースに強制しない
135
- camelcase: 'off',
136
- // switch 文で default を強制しない
137
- 'default-case': 'off',
138
- // default export を優先しない
139
- 'import/prefer-default-export': 'off',
140
- // 循環 import を禁止
141
- 'import/no-cycle': 'error',
142
- // continue 文を許可
143
- 'no-continue': 'off',
144
- // _ で始まるメンバー名を許可
145
- 'no-underscore-dangle': 'off',
146
- // 自身より後に宣言されたメンバーの使用を許可
147
- 'no-use-before-define': 'off',
148
- // console.* の使用を許可
149
- 'no-console': 'off',
150
- // 深い三項演算子を許可
151
- 'no-nested-ternary': 'off',
152
- // i++ インクリメントを許可
153
- 'no-plusplus': 'off',
154
- // return の省略などを許可
155
- 'consistent-return': 'off',
156
- // 空行を挟む
157
- 'padding-line-between-statements': [
158
- 'warn',
159
- // return 前に空行
160
- { blankLine: 'always', prev: '*', next: 'return' },
161
- // ディレクティブ後に空行
162
- { blankLine: 'always', prev: 'directive', next: '*' },
163
- { blankLine: 'any', prev: 'directive', next: 'directive' },
164
- ],
165
- // void Promise を許可
166
- 'no-void': 'off',
167
- // 1 <= x < 10 を許可
168
- yoda: [
169
- 'error',
170
- 'never',
171
- {
172
- exceptRange: true,
173
- },
174
- ],
175
- // 不要な変数を禁止
176
- 'unused-imports/no-unused-vars': [
177
- 'warn',
178
- // '_' で始まる変数を許可
179
- {
180
- vars: 'all',
181
- varsIgnorePattern: '^_',
182
- args: 'after-used',
183
- argsIgnorePattern: '^_',
184
143
  },
185
- ],
144
+ },
145
+ rules: {
146
+ 'import-x/no-import-module-exports': 'off',
147
+ 'import-x/no-extraneous-dependencies': 'off',
148
+ // 循環 import を禁止
149
+ 'import-x/no-cycle': 'error',
150
+ // default export を優先しない
151
+ 'import-x/prefer-default-export': 'off',
152
+ // default export を禁止
153
+ 'import-x/no-default-export': 'error',
154
+ // import 順を並び替える
155
+ 'import-x/order': [
156
+ 'warn',
157
+ {
158
+ // 組み込み → 外部依存 → 内部依存 → object → type の順にする
159
+ 'groups': [
160
+ 'builtin',
161
+ 'external',
162
+ ['parent', 'sibling', 'index'],
163
+ 'object',
164
+ 'type',
165
+ 'unknown',
166
+ ],
167
+ // カテゴリー間に改行を入れる
168
+ 'newlines-between': 'always',
169
+ // 大文字小文字区別なしで ABC 順にする
170
+ 'alphabetize': {
171
+ order: 'asc',
172
+ caseInsensitive: true,
173
+ },
174
+ 'pathGroups': [
175
+ // **.css は最後に配置する
176
+ {
177
+ pattern: '**.css',
178
+ group: 'type',
179
+ position: 'after',
180
+ },
181
+ ],
182
+ // **.css が import 順最後ではないときに警告
183
+ 'warnOnUnassignedImports': true,
184
+ },
185
+ ],
186
+ },
187
+ },
188
+ {
189
+ name: 'eslint-plugin-unused-imports',
190
+ files: ['**/*.{js,cjs,mjs,jsx,ts,cts,mts,tsx}'],
191
+ plugins: {
192
+ 'unused-imports': unusedImportsPlugin,
193
+ },
194
+ rules: {
195
+ // 不要 import 文を禁止
196
+ 'unused-imports/no-unused-imports': 'error',
197
+ // 不要な変数を禁止
198
+ 'no-unused-vars': 'off',
199
+ '@typescript-eslint/no-unused-vars': 'off',
200
+ 'unused-imports/no-unused-vars': [
201
+ 'warn',
202
+ // '_' で始まる変数を許可
203
+ {
204
+ vars: 'all',
205
+ varsIgnorePattern: '^_',
206
+ args: 'after-used',
207
+ argsIgnorePattern: '^_',
208
+ },
209
+ ],
210
+ },
211
+ },
212
+ {
213
+ name: 'eslint-plugin-promise',
214
+ files: ['**/*.{js,cjs,mjs,jsx,ts,cts,mts,tsx}'],
215
+ extends: [promisePlugin.configs['flat/recommended']],
216
+ },
217
+ {
218
+ name: 'eslint-plugin-xss',
219
+ files: ['**/*.{js,cjs,mjs,jsx,ts,cts,mts,tsx}'],
220
+ // TODO: eslint-plugin-xss が Flat Configs に対応したら移行する
221
+ // https://github.com/Rantanen/eslint-plugin-xss/issues/15
222
+ // extends: ['plugin:xss/recommended'],
223
+ extends: [],
186
224
  },
187
- } satisfies Linter.Config
225
+ )
@@ -0,0 +1,15 @@
1
+ import packageJsonPlugin from 'eslint-plugin-package-json';
2
+ import { config } from 'typescript-eslint';
3
+ export const packageJson = config({
4
+ name: 'eslint-plugin-package-json',
5
+ files: ['**/package.json'],
6
+ extends: [packageJsonPlugin.configs.recommended],
7
+ rules: {
8
+ 'package-json/order-properties': [
9
+ 'error',
10
+ {
11
+ order: 'sort-package-json',
12
+ },
13
+ ],
14
+ },
15
+ });
@@ -0,0 +1,16 @@
1
+ import packageJsonPlugin from 'eslint-plugin-package-json'
2
+ import { config } from 'typescript-eslint'
3
+
4
+ export const packageJson = config({
5
+ name: 'eslint-plugin-package-json',
6
+ files: ['**/package.json'],
7
+ extends: [packageJsonPlugin.configs.recommended],
8
+ rules: {
9
+ 'package-json/order-properties': [
10
+ 'error',
11
+ {
12
+ order: 'sort-package-json',
13
+ },
14
+ ],
15
+ },
16
+ })
@@ -1,79 +1,85 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- module.exports = {
1
+ import safeTypeScriptPlugin from '@susisu/eslint-plugin-safe-typescript';
2
+ import importXPlugin from 'eslint-plugin-import-x';
3
+ import tsdocPlugin from 'eslint-plugin-tsdoc';
4
+ import tseslint, { config } from 'typescript-eslint';
5
+ export const typeScript = config({
6
+ files: ['**/*.cts'],
7
+ languageOptions: {
8
+ sourceType: 'commonjs',
9
+ },
10
+ }, {
11
+ files: ['**/*.{ts,mts,tsx}'],
12
+ languageOptions: {
13
+ sourceType: 'module',
14
+ },
15
+ }, {
16
+ name: 'typescript-eslint',
17
+ files: ['**/*.{ts,cts,mts,tsx}'],
4
18
  extends: [
5
- 'plugin:@typescript-eslint/strict-type-checked',
6
- 'plugin:@typescript-eslint/stylistic-type-checked',
7
- 'plugin:@susisu/safe-typescript/recommended',
8
- 'plugin:import/typescript',
9
- 'plugin:no-void-return-type/recommended',
10
- 'plugin:storybook/recommended',
11
- ],
12
- plugins: [
13
- '@typescript-eslint',
14
- '@susisu/safe-typescript',
15
- 'tsdoc',
16
- 'deprecation',
19
+ tseslint.configs.recommendedTypeChecked,
20
+ tseslint.configs.stylisticTypeChecked,
17
21
  ],
18
- parser: '@typescript-eslint/parser',
19
- parserOptions: {
20
- sourceType: 'module',
22
+ languageOptions: {
21
23
  ecmaVersion: 'latest',
22
- lib: ['esnext'],
23
- project: './tsconfig.json',
24
- warnOnUnsupportedTypeScriptVersion: true,
25
- },
26
- settings: {
27
- 'import/parsers': {
28
- '@typescript-eslint/parser': ['.ts', '.mts', '.cts', '.tsx', '.d.ts'],
29
- },
30
- 'import/resolver': {
31
- node: {
32
- extensions: ['.js', '.jsx', '.ts', '.tsx'],
33
- },
34
- typescript: {
35
- alwaysTryTypes: true,
36
- },
24
+ parser: tseslint.parser,
25
+ parserOptions: {
26
+ projectService: true,
27
+ // tsconfigRootDir は利用側で定義する必要がある
28
+ // tsconfigRootDir: import.meta.dirname,
37
29
  },
38
30
  },
39
31
  rules: {
32
+ /**
33
+ * Automatically fixable は error にする
34
+ */
35
+ // interface 👉 type
40
36
  '@typescript-eslint/consistent-type-definitions': ['error', 'type'],
37
+ // export type を優先
41
38
  '@typescript-eslint/consistent-type-exports': [
42
39
  'error',
43
40
  {
44
41
  fixMixedExportsWithInlineTypeSpecifier: true,
45
42
  },
46
43
  ],
44
+ // import type を優先
47
45
  '@typescript-eslint/consistent-type-imports': 'error',
46
+ // クラスのアクセス修飾子を強制
48
47
  '@typescript-eslint/explicit-member-accessibility': 'error',
48
+ // export されているメンバーや public メンバーは型を明示させる
49
49
  '@typescript-eslint/explicit-module-boundary-types': 'warn',
50
- '@typescript-eslint/member-delimiter-style': 'error',
51
50
  '@typescript-eslint/member-ordering': 'warn',
52
51
  '@typescript-eslint/method-signature-style': ['warn', 'method'],
52
+ // 命名規則を強制
53
53
  '@typescript-eslint/naming-convention': [
54
54
  'warn',
55
+ // デフォルトは camelCase
55
56
  {
56
57
  selector: ['default'],
57
58
  format: ['strictCamelCase'],
58
59
  },
60
+ // 型名 / 列挙型のメンバーは PascalCase
59
61
  {
60
62
  selector: ['typeLike', 'enumMember'],
61
63
  format: ['StrictPascalCase'],
62
64
  },
65
+ // 変数名は camelCase
63
66
  {
64
67
  selector: ['variableLike'],
65
68
  format: ['strictCamelCase', 'StrictPascalCase'],
66
69
  leadingUnderscore: 'allow',
67
70
  },
71
+ // インポート名は camelCase / PascalCase
68
72
  {
69
73
  selector: ['import'],
70
74
  format: ['camelCase', 'PascalCase'],
71
75
  },
76
+ // export された定数は UPPER_CASE を許容
72
77
  {
73
78
  selector: ['variable'],
74
79
  modifiers: ['const', 'global', 'exported'],
75
80
  format: ['strictCamelCase', 'StrictPascalCase', 'UPPER_CASE'],
76
81
  },
82
+ // プロパティーに snake_case / UPPER_CASE を許容
77
83
  {
78
84
  selector: ['property'],
79
85
  format: [
@@ -83,6 +89,7 @@ module.exports = {
83
89
  'StrictPascalCase',
84
90
  ],
85
91
  },
92
+ // Boolean は特定のプレフィックスを強制
86
93
  {
87
94
  selector: ['variable'],
88
95
  types: ['boolean'],
@@ -104,28 +111,36 @@ module.exports = {
104
111
  'hide',
105
112
  ],
106
113
  },
114
+ // プライベートメンバーは _ で始める
107
115
  {
108
116
  selector: ['memberLike'],
109
117
  modifiers: ['private'],
110
118
  format: ['strictCamelCase'],
111
119
  leadingUnderscore: 'require',
112
120
  },
121
+ // deconstruct で宣言された変数は許容
113
122
  {
114
123
  selector: ['variableLike'],
115
124
  modifiers: ['destructured'],
116
125
  format: null,
117
126
  },
127
+ // オブジェクトのキーなど '' 付きの宣言は許容
118
128
  {
119
129
  selector: ['memberLike', 'property'],
120
130
  modifiers: ['requiresQuotes'],
121
131
  format: null,
122
132
  },
123
133
  ],
134
+ // void を式の値として禁止
124
135
  '@typescript-eslint/no-confusing-void-expression': 'error',
136
+ // 重複した型定義を禁止
137
+ // boolean | false 👉 boolean
125
138
  '@typescript-eslint/no-redundant-type-constituents': 'warn',
139
+ // require() を禁止
126
140
  '@typescript-eslint/no-require-imports': 'warn',
127
141
  '@typescript-eslint/no-unnecessary-qualifier': 'error',
128
142
  '@typescript-eslint/no-useless-empty-export': 'error',
143
+ // パラメーターでのプロパティ宣言を強制
129
144
  '@typescript-eslint/parameter-properties': [
130
145
  'warn',
131
146
  {
@@ -144,11 +159,11 @@ module.exports = {
144
159
  '@typescript-eslint/prefer-enum-initializers': 'warn',
145
160
  '@typescript-eslint/prefer-readonly': 'error',
146
161
  '@typescript-eslint/prefer-regexp-exec': 'error',
162
+ // Promise<T> を返す関数では async のマークを強制
147
163
  '@typescript-eslint/promise-function-async': 'error',
148
164
  '@typescript-eslint/switch-exhaustiveness-check': 'error',
149
- '@typescript-eslint/type-annotation-spacing': 'error',
150
165
  '@typescript-eslint/unbound-method': 'off',
151
- '@typescript-eslint/no-unused-vars': 'off',
166
+ // 過激なルールを無効化
152
167
  '@typescript-eslint/no-unsafe-assignment': 'off',
153
168
  '@typescript-eslint/no-unsafe-call': 'off',
154
169
  '@typescript-eslint/no-unsafe-member-access': 'off',
@@ -157,27 +172,56 @@ module.exports = {
157
172
  '@typescript-eslint/no-unsafe-enum-comparison': 'off',
158
173
  '@typescript-eslint/restrict-template-expressions': 'off',
159
174
  '@typescript-eslint/strict-boolean-expressions': 'off',
160
- 'import/extensions': [
161
- 'warn',
162
- 'always',
163
- {
164
- ignorePackages: true,
165
- },
166
- ],
167
- 'tsdoc/syntax': 'warn',
175
+ // enum のメンバーでビット演算を許可する
168
176
  '@typescript-eslint/prefer-literal-enum-member': [
169
177
  'error',
170
178
  {
171
179
  allowBitwiseExpressions: true,
172
180
  },
173
181
  ],
174
- 'deprecation/deprecation': 'error',
182
+ // '1' + 2 を禁止
175
183
  '@typescript-eslint/restrict-plus-operands': 'error',
184
+ // 数値型の配列の sort() を禁止
176
185
  '@typescript-eslint/require-array-sort-compare': [
177
186
  'error',
178
187
  {
179
188
  ignoreStringArrays: true,
180
189
  },
181
190
  ],
191
+ // Deprecated されたコードの使用を禁止
192
+ '@typescript-eslint/no-deprecated': 'error',
193
+ // 関数の返り値としての void 以外を禁止
194
+ '@typescript-eslint/no-invalid-void-type': 'error',
195
+ },
196
+ }, {
197
+ name: 'eslint-plugin-import-x',
198
+ files: ['**/*.{ts,cts,mts,tsx}'],
199
+ extends: [importXPlugin.flatConfigs.typescript],
200
+ rules: {
201
+ // import に拡張子を推奨
202
+ 'import-x/extensions': [
203
+ 'warn',
204
+ 'always',
205
+ {
206
+ ignorePackages: true,
207
+ },
208
+ ],
209
+ },
210
+ }, {
211
+ name: '@susisu/eslint-plugin-safe-typescript',
212
+ files: ['**/*.{ts,cts,mts,tsx}'],
213
+ plugins: {
214
+ '@susisu/safe-typescript': safeTypeScriptPlugin,
215
+ },
216
+ rules: safeTypeScriptPlugin.configs.recommended.rules,
217
+ }, {
218
+ name: 'eslint-plugin-tsdoc',
219
+ files: ['**/*.{ts,cts,mts,tsx}'],
220
+ plugins: {
221
+ tsdoc: tsdocPlugin,
222
+ },
223
+ rules: {
224
+ // TSDoc
225
+ 'tsdoc/syntax': 'warn',
182
226
  },
183
- };
227
+ });