@slashnephy/eslint-config 2.3.204 → 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 +24 -40
  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
package/README.md CHANGED
@@ -9,12 +9,26 @@
9
9
  $ yarn add @slashnephy/eslint-config
10
10
  ```
11
11
 
12
- ## Usage
12
+ ## Usage (for Flat Configs)
13
13
 
14
- `.eslintrc.json`
14
+ `eslint.config.js` or `eslint.config.mjs`
15
+
16
+ ```javascript
17
+ import { defineConfig } from 'eslint/config'
18
+ import config from '@slashnephy/eslint-config'
19
+
20
+ export default defineConfig([
21
+ ...config,
22
+ {
23
+ languageOptions: {
24
+ parserOptions: {
25
+ tsconfigRootDir: import.meta.dirname,
26
+ },
27
+ },
28
+ },
29
+ {
30
+ // your custom config
31
+ },
32
+ ])
15
33
 
16
- ```json
17
- {
18
- "extends": ["@slashnephy/eslint-config"]
19
- }
20
34
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@slashnephy/eslint-config",
3
- "version": "2.3.204",
3
+ "version": "3.0.1",
4
4
  "keywords": [
5
5
  "eslint",
6
6
  "eslintconfig"
@@ -11,7 +11,7 @@
11
11
  },
12
12
  "license": "MIT",
13
13
  "author": "SlashNephy <spica@starry.blue> (https://spica.starry.blue/)",
14
- "type": "commonjs",
14
+ "type": "module",
15
15
  "main": "./src/index.js",
16
16
  "files": [
17
17
  "./package.json",
@@ -21,48 +21,29 @@
21
21
  ],
22
22
  "scripts": {
23
23
  "build": "tsc",
24
- "bump-version": "ts-node bin/bump-version.ts",
24
+ "bump-version": "tsx bin/bump-version.ts",
25
25
  "clean": "rm -rf src/**/*.js",
26
- "format": "concurrently -m 1 -n format: 'yarn:format:*'",
27
- "format:eslint": "yarn build && yarn lint:eslint --fix",
28
- "format:prettier": "yarn lint:prettier --write",
29
- "lint": "concurrently -n lint: 'yarn:lint:*'",
30
- "lint:eslint": "yarn build && eslint .",
31
- "lint:prettier": "prettier --check .",
26
+ "format": "eslint --fix",
27
+ "lint": "eslint",
32
28
  "publish": "yarn build && yarn npm publish"
33
29
  },
34
- "eslintConfig": {
35
- "extends": "./src"
36
- },
37
30
  "dependencies": {
38
- "@emotion/eslint-plugin": "11.12.0",
39
- "@graphql-eslint/eslint-plugin": "3.20.1",
40
- "@next/eslint-plugin-next": "14.2.25",
41
- "@rushstack/eslint-patch": "1.11.0",
31
+ "@eslint-community/eslint-plugin-eslint-comments": "4.4.1",
32
+ "@eslint/js": "9.23.0",
33
+ "@graphql-eslint/eslint-plugin": "4.3.0",
34
+ "@next/eslint-plugin-next": "15.2.3",
42
35
  "@stylistic/eslint-plugin": "4.2.0",
43
- "@susisu/eslint-plugin-safe-typescript": "0.9.0",
44
- "@typescript-eslint/eslint-plugin": "8.27.0",
45
- "@typescript-eslint/parser": "8.27.0",
36
+ "@susisu/eslint-plugin-safe-typescript": "0.9.3",
37
+ "@typescript-eslint/utils": "8.27.0",
46
38
  "@vitest/eslint-plugin": "1.1.38",
47
- "eslint-config-airbnb": "19.0.4",
48
- "eslint-config-next": "14.2.25",
49
- "eslint-config-prettier": "10.1.1",
50
- "eslint-config-standard": "17.1.0",
51
- "eslint-gitignore": "0.1.0",
39
+ "eslint-config-flat-gitignore": "2.1.0",
52
40
  "eslint-import-resolver-node": "0.3.9",
53
41
  "eslint-import-resolver-typescript": "4.2.2",
54
- "eslint-plugin-css-reorder": "0.5.1",
55
- "eslint-plugin-deprecation": "3.0.0",
56
- "eslint-plugin-editorconfig": "4.0.3",
57
- "eslint-plugin-eslint-comments": "3.2.0",
58
- "eslint-plugin-import": "2.31.0",
42
+ "eslint-plugin-import-x": "4.9.1",
59
43
  "eslint-plugin-jest": "28.11.0",
60
- "eslint-plugin-jest-formatting": "3.1.0",
61
44
  "eslint-plugin-jsx-a11y": "6.10.2",
62
45
  "eslint-plugin-n": "17.16.2",
63
- "eslint-plugin-no-void-return-type": "1.0.2",
64
- "eslint-plugin-node": "11.1.0",
65
- "eslint-plugin-package-json": "0.2.0",
46
+ "eslint-plugin-package-json": "0.29.0",
66
47
  "eslint-plugin-promise": "7.2.1",
67
48
  "eslint-plugin-react": "7.37.4",
68
49
  "eslint-plugin-react-hooks": "5.2.0",
@@ -74,21 +55,24 @@
74
55
  "eslint-plugin-userscripts": "0.5.6",
75
56
  "eslint-plugin-xss": "0.1.12",
76
57
  "eslint-plugin-yml": "1.17.0",
58
+ "globals": "16.0.0",
77
59
  "graphql": "16.10.0",
60
+ "jsonc-eslint-parser": "2.4.0",
78
61
  "typescript": "5.8.2",
62
+ "typescript-eslint": "8.27.0",
79
63
  "yaml-eslint-parser": "1.3.0"
80
64
  },
81
65
  "devDependencies": {
82
- "@slashnephy/prettier-config": "1.0.73",
83
- "@types/eslint": "8.56.12",
84
- "@types/node": "22.13.10",
66
+ "@eslint/config-inspector": "1.0.2",
67
+ "@types/eslint": "9.6.1",
68
+ "@types/node": "22.13.11",
85
69
  "concurrently": "9.1.2",
86
- "eslint": "8.57.1",
87
- "prettier": "3.5.3",
88
- "ts-node": "10.9.2"
70
+ "eslint": "9.23.0",
71
+ "jiti": "2.4.2",
72
+ "tsx": "4.19.3"
89
73
  },
90
74
  "peerDependencies": {
91
- "eslint": "^8"
75
+ "eslint": "^9"
92
76
  },
93
77
  "packageManager": "yarn@4.7.0",
94
78
  "publishConfig": {
@@ -0,0 +1,37 @@
1
+ import stylisticPlugin from '@stylistic/eslint-plugin';
2
+ import { globalIgnores } from 'eslint/config';
3
+ import gitignore from 'eslint-config-flat-gitignore';
4
+ import { config } from 'typescript-eslint';
5
+ export const common = config(globalIgnores([
6
+ '**/.git/**',
7
+ '**/node_modules/**',
8
+ '**/.yarn/**',
9
+ '**/dist/**',
10
+ '**/.idea/**',
11
+ ]), gitignore({ name: 'eslint-config-flat-gitignore', strict: false }), {
12
+ name: '@stylistic/eslint-plugin',
13
+ files: ['**/*.{js,cjs,mjs,jsx,ts,cts,mts,tsx}'],
14
+ extends: [
15
+ stylisticPlugin.configs.customize({
16
+ indent: 2,
17
+ quotes: 'single',
18
+ semi: false,
19
+ jsx: true,
20
+ arrowParens: true,
21
+ blockSpacing: true,
22
+ quoteProps: 'consistent-as-needed',
23
+ commaDangle: 'always-multiline',
24
+ }),
25
+ ],
26
+ rules: {
27
+ // UTF-8 BOM を禁止
28
+ 'unicode-bom': ['error', 'never'],
29
+ // 最終行に改行を挿入
30
+ '@stylistic/eol-last': ['error', 'always'],
31
+ // 行末のスペースを禁止
32
+ '@stylistic/no-trailing-spaces': ['error'],
33
+ // 型名の前後のスペースを揃える
34
+ // e.g. const foo: string = 'bar'
35
+ '@stylistic/type-annotation-spacing': 'error',
36
+ },
37
+ });
@@ -0,0 +1,42 @@
1
+ import stylisticPlugin from '@stylistic/eslint-plugin'
2
+ import { globalIgnores } from 'eslint/config'
3
+ import gitignore from 'eslint-config-flat-gitignore'
4
+ import { config } from 'typescript-eslint'
5
+
6
+ export const common = config(
7
+ globalIgnores([
8
+ '**/.git/**',
9
+ '**/node_modules/**',
10
+ '**/.yarn/**',
11
+ '**/dist/**',
12
+ '**/.idea/**',
13
+ ]),
14
+ gitignore({ name: 'eslint-config-flat-gitignore', strict: false }),
15
+ {
16
+ name: '@stylistic/eslint-plugin',
17
+ files: ['**/*.{js,cjs,mjs,jsx,ts,cts,mts,tsx}'],
18
+ extends: [
19
+ stylisticPlugin.configs.customize({
20
+ indent: 2,
21
+ quotes: 'single',
22
+ semi: false,
23
+ jsx: true,
24
+ arrowParens: true,
25
+ blockSpacing: true,
26
+ quoteProps: 'consistent-as-needed',
27
+ commaDangle: 'always-multiline',
28
+ }),
29
+ ],
30
+ rules: {
31
+ // UTF-8 BOM を禁止
32
+ 'unicode-bom': ['error', 'never'],
33
+ // 最終行に改行を挿入
34
+ '@stylistic/eol-last': ['error', 'always'],
35
+ // 行末のスペースを禁止
36
+ '@stylistic/no-trailing-spaces': ['error'],
37
+ // 型名の前後のスペースを揃える
38
+ // e.g. const foo: string = 'bar'
39
+ '@stylistic/type-annotation-spacing': 'error',
40
+ },
41
+ },
42
+ )
@@ -1,9 +1,42 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- module.exports = {
4
- plugins: ['@graphql-eslint'],
5
- parser: '@graphql-eslint/eslint-plugin',
6
- parserOptions: {
7
- schema: '**/schema.graphql',
1
+ import graphqlPlugin from '@graphql-eslint/eslint-plugin';
2
+ import { config } from 'typescript-eslint';
3
+ export const graphql = config(
4
+ // GraphQL を解釈できるようにする
5
+ {
6
+ name: '@graphql-eslint/eslint-plugin (parser)',
7
+ files: ['**/*.{graphql,graphqls,gql}'],
8
+ languageOptions: {
9
+ parser: graphqlPlugin.parser,
8
10
  },
9
- };
11
+ plugins: {
12
+ '@graphql-eslint': graphqlPlugin,
13
+ },
14
+ },
15
+ // コード中に含まれる GraphQL を解釈して lint できるようにする
16
+ {
17
+ name: '@graphql-eslint/eslint-plugin (code)',
18
+ files: ['**/*.{js,cjs,mjs,jsx,ts,cts,mts,tsx}'],
19
+ processor: graphqlPlugin.processor,
20
+ },
21
+ // GraphQL schema
22
+ {
23
+ name: '@graphql-eslint/eslint-plugin (GraphQL schema)',
24
+ files: [
25
+ '**/schema.{graphql,graphqls,gql}',
26
+ // gqlgen
27
+ '**/graph/*.{graphql,graphqls,gql}',
28
+ ],
29
+ extends: [
30
+ graphqlPlugin.configs['flat/schema-recommended'],
31
+ graphqlPlugin.configs['flat/schema-relay'],
32
+ ],
33
+ },
34
+ // GraphQL operations
35
+ {
36
+ name: '@graphql-eslint/eslint-plugin (GraphQL operations)',
37
+ files: [
38
+ '**/documents/*.{graphql,graphqls,gql}',
39
+ '**/frontend/**/*.{graphql,graphqls,gql}',
40
+ ],
41
+ extends: [graphqlPlugin.configs['flat/operations-recommended']],
42
+ });
@@ -1,15 +1,48 @@
1
- import type { Linter } from 'eslint'
2
-
3
- module.exports = {
4
- plugins: ['@graphql-eslint'],
5
- // XXX: 上手く動いていないので一時的に無効化
6
- // extends: [
7
- // 'plugin:@graphql-eslint/schema-recommended',
8
- // 'plugin:@graphql-eslint/operations-all',
9
- // 'plugin:@graphql-eslint/relay',
10
- // ],
11
- parser: '@graphql-eslint/eslint-plugin',
12
- parserOptions: {
13
- schema: '**/schema.graphql',
14
- },
15
- } satisfies Linter.Config
1
+ import graphqlPlugin from '@graphql-eslint/eslint-plugin'
2
+ import { config } from 'typescript-eslint'
3
+
4
+ export const graphql = config(
5
+ // GraphQL を解釈できるようにする
6
+ {
7
+ name: '@graphql-eslint/eslint-plugin (parser)',
8
+ files: ['**/*.{graphql,graphqls,gql}'],
9
+ languageOptions: {
10
+ parser: graphqlPlugin.parser,
11
+ },
12
+ plugins: {
13
+ '@graphql-eslint': graphqlPlugin,
14
+ },
15
+ },
16
+
17
+ // コード中に含まれる GraphQL を解釈して lint できるようにする
18
+ {
19
+ name: '@graphql-eslint/eslint-plugin (code)',
20
+ files: ['**/*.{js,cjs,mjs,jsx,ts,cts,mts,tsx}'],
21
+ processor: graphqlPlugin.processor,
22
+ },
23
+
24
+ // GraphQL schema
25
+ {
26
+ name: '@graphql-eslint/eslint-plugin (GraphQL schema)',
27
+ files: [
28
+ '**/schema.{graphql,graphqls,gql}',
29
+
30
+ // gqlgen
31
+ '**/graph/*.{graphql,graphqls,gql}',
32
+ ],
33
+ extends: [
34
+ graphqlPlugin.configs['flat/schema-recommended'],
35
+ graphqlPlugin.configs['flat/schema-relay'],
36
+ ],
37
+ },
38
+
39
+ // GraphQL operations
40
+ {
41
+ name: '@graphql-eslint/eslint-plugin (GraphQL operations)',
42
+ files: [
43
+ '**/documents/*.{graphql,graphqls,gql}',
44
+ '**/frontend/**/*.{graphql,graphqls,gql}',
45
+ ],
46
+ extends: [graphqlPlugin.configs['flat/operations-recommended']],
47
+ },
48
+ )
@@ -1,123 +1,197 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const eslint_config_standard_1 = __importDefault(require("eslint-config-standard"));
7
- module.exports = {
8
- extends: [
9
- 'plugin:eslint-comments/recommended',
10
- 'plugin:node/recommended',
11
- 'plugin:import/recommended',
12
- 'plugin:xss/recommended',
13
- ],
14
- plugins: ['import', 'promise', 'n', 'unused-imports'],
15
- env: {
16
- node: true,
17
- es2022: true,
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';
9
+ export const javaScript = config({
10
+ files: ['**/*.cjs'],
11
+ languageOptions: {
12
+ sourceType: 'commonjs',
18
13
  },
19
- parserOptions: {
20
- ecmaVersion: 'latest',
14
+ }, {
15
+ files: ['**/*.{js,mjs,jsx}'],
16
+ languageOptions: {
17
+ sourceType: 'module',
21
18
  },
22
- globals: {
23
- document: 'readonly',
24
- navigator: 'readonly',
25
- window: 'readonly',
19
+ }, {
20
+ name: '@eslint/js',
21
+ files: ['**/*.{js,cjs,mjs,jsx,ts,cts,mts,tsx}'],
22
+ extends: [eslint.configs.recommended],
23
+ languageOptions: {
24
+ ecmaVersion: 'latest',
25
+ parser: tseslint.parser,
26
26
  },
27
27
  rules: {
28
- ...eslint_config_standard_1.default.rules,
29
- 'eslint-comments/no-unused-disable': 'error',
30
- 'import/no-default-export': 'error',
28
+ // アロー関数を優先
31
29
  'prefer-arrow-callback': 'error',
30
+ // 関数宣言は function xxx() {} にする
32
31
  'func-style': ['error', 'declaration', { allowArrowFunctions: true }],
33
- curly: 'error',
32
+ // 中括弧の省略を禁止
33
+ 'curly': 'error',
34
+ // テンプレート文字列を優先
34
35
  'prefer-template': 'error',
35
- eqeqeq: 'error',
36
- strict: ['error', 'global'],
37
- 'import/order': [
38
- 'warn',
39
- {
40
- groups: [
41
- 'builtin',
42
- 'external',
43
- ['parent', 'sibling', 'index'],
44
- 'object',
45
- 'type',
46
- 'unknown',
47
- ],
48
- 'newlines-between': 'always',
49
- alphabetize: {
50
- order: 'asc',
51
- caseInsensitive: true,
52
- },
53
- pathGroups: [
54
- {
55
- pattern: '**.css',
56
- group: 'type',
57
- position: 'after',
58
- },
59
- ],
60
- warnOnUnassignedImports: true,
61
- },
62
- ],
63
- 'unused-imports/no-unused-imports': 'error',
36
+ // == 比較 👉 === 比較
37
+ 'eqeqeq': 'error',
38
+ // *.js で 'use strict'; を強制
39
+ 'strict': ['error', 'global'],
40
+ // 特定の構文を禁止
64
41
  'no-restricted-syntax': [
65
42
  'error',
43
+ // 数値リテラル以外での Array#at() の使用を禁止
44
+ // https://qiita.com/printf_moriken/items/da03f55cb626617c1958
66
45
  {
67
- selector: "CallExpression[callee.property.name='at']:not([arguments.0.type='Literal'],[arguments.0.type='UnaryExpression'][arguments.0.argument.type='Literal'])",
46
+ selector:
47
+ // eslint-disable-next-line @stylistic/quotes -- prettier と競合している
48
+ "CallExpression[callee.property.name='at']:not([arguments.0.type='Literal'],[arguments.0.type='UnaryExpression'][arguments.0.argument.type='Literal'])",
68
49
  message: 'at method accepts only a literal argument',
69
50
  },
70
51
  ],
71
- 'node/prefer-promises/dns': 'error',
72
- 'node/prefer-promises/fs': 'error',
73
- 'node/no-unsupported-features/es-syntax': 'off',
74
- 'node/no-missing-import': 'off',
75
- 'node/no-extraneous-import': 'off',
76
- 'node/no-unpublished-import': 'off',
77
- 'import/no-import-module-exports': 'off',
78
- 'import/no-extraneous-dependencies': 'off',
52
+ // foo["bar"] 👉 foo.bar
79
53
  'dot-notation': 'error',
54
+ // {foo: foo} 👉 {foo}
80
55
  'object-shorthand': ['error', 'always'],
56
+ // Array 系メソッドで return を強制
81
57
  'array-callback-return': ['error'],
58
+ // ループ内では await を禁止
82
59
  'no-await-in-loop': 'error',
60
+ // 操作が値に影響しない式を禁止
83
61
  'no-constant-binary-expression': 'error',
62
+ // コンストラクター内で return を禁止
84
63
  'no-constructor-return': 'error',
64
+ // 関数の返り値としての Promise executor を禁止
85
65
  'no-promise-executor-return': 'error',
66
+ // 自身との比較 (e.g. foo === foo) を禁止
86
67
  'no-self-compare': 'error',
68
+ // 非テンプレート文字列で ${foo} を禁止
69
+ // "Hello, ${name}" 👉 `Hello, ${name}`
87
70
  'no-template-curly-in-string': 'error',
71
+ // 更新されないループ条件を禁止
88
72
  'no-unmodified-loop-condition': 'error',
73
+ // 到達できないループを禁止
89
74
  'no-unreachable-loop': 'error',
75
+ // 未使用の private メンバーを禁止
90
76
  'no-unused-private-class-members': 'error',
77
+ // スレッドセーフで安全に更新されないコードを禁止
91
78
  'require-atomic-updates': 'error',
79
+ // func () 👉 func()
92
80
  'func-call-spacing': ['error', 'never'],
81
+ // ペアになっていない setter を禁止
93
82
  'accessor-pairs': 'error',
94
- camelcase: 'off',
83
+ // キャメルケースに強制しない
84
+ 'camelcase': 'off',
85
+ // switch 文で default を強制しない
95
86
  'default-case': 'off',
96
- 'import/prefer-default-export': 'off',
97
- 'import/no-cycle': 'error',
87
+ // continue 文を許可
98
88
  'no-continue': 'off',
89
+ // _ で始まるメンバー名を許可
99
90
  'no-underscore-dangle': 'off',
91
+ // 自身より後に宣言されたメンバーの使用を許可
100
92
  'no-use-before-define': 'off',
93
+ // console.* の使用を許可
101
94
  'no-console': 'off',
95
+ // 深い三項演算子を許可
102
96
  'no-nested-ternary': 'off',
97
+ // i++ インクリメントを許可
103
98
  'no-plusplus': 'off',
99
+ // return の省略などを許可
104
100
  'consistent-return': 'off',
101
+ // 空行を挟む
105
102
  'padding-line-between-statements': [
106
103
  'warn',
104
+ // return 前に空行
107
105
  { blankLine: 'always', prev: '*', next: 'return' },
106
+ // ディレクティブ後に空行
108
107
  { blankLine: 'always', prev: 'directive', next: '*' },
109
108
  { blankLine: 'any', prev: 'directive', next: 'directive' },
110
109
  ],
110
+ // void Promise を許可
111
111
  'no-void': 'off',
112
- yoda: [
112
+ // 1 <= x < 10 を許可
113
+ 'yoda': [
113
114
  'error',
114
115
  'never',
115
116
  {
116
117
  exceptRange: true,
117
118
  },
118
119
  ],
120
+ },
121
+ }, {
122
+ name: '@eslint-community/eslint-plugin-eslint-comments',
123
+ extends: [eslintCommentsConfig.recommended],
124
+ }, {
125
+ name: 'eslint-plugin-import-x',
126
+ files: ['**/*.{js,cjs,mjs,jsx,ts,cts,mts,tsx}'],
127
+ extends: [importXPlugin.flatConfigs.recommended],
128
+ settings: {
129
+ 'import-x/resolver': {
130
+ node: {
131
+ extensions: ['.js', '.cjs', '.mjs', '.jsx', '.ts', '.cts', '.mts', '.tsx', '.json'],
132
+ },
133
+ typescript: {
134
+ alwaysTryTypes: true,
135
+ },
136
+ },
137
+ },
138
+ rules: {
139
+ 'import-x/no-import-module-exports': 'off',
140
+ 'import-x/no-extraneous-dependencies': 'off',
141
+ // 循環 import を禁止
142
+ 'import-x/no-cycle': 'error',
143
+ // default export を優先しない
144
+ 'import-x/prefer-default-export': 'off',
145
+ // default export を禁止
146
+ 'import-x/no-default-export': 'error',
147
+ // import 順を並び替える
148
+ 'import-x/order': [
149
+ 'warn',
150
+ {
151
+ // 組み込み → 外部依存 → 内部依存 → object → type の順にする
152
+ 'groups': [
153
+ 'builtin',
154
+ 'external',
155
+ ['parent', 'sibling', 'index'],
156
+ 'object',
157
+ 'type',
158
+ 'unknown',
159
+ ],
160
+ // カテゴリー間に改行を入れる
161
+ 'newlines-between': 'always',
162
+ // 大文字小文字区別なしで ABC 順にする
163
+ 'alphabetize': {
164
+ order: 'asc',
165
+ caseInsensitive: true,
166
+ },
167
+ 'pathGroups': [
168
+ // **.css は最後に配置する
169
+ {
170
+ pattern: '**.css',
171
+ group: 'type',
172
+ position: 'after',
173
+ },
174
+ ],
175
+ // **.css が import 順最後ではないときに警告
176
+ 'warnOnUnassignedImports': true,
177
+ },
178
+ ],
179
+ },
180
+ }, {
181
+ name: 'eslint-plugin-unused-imports',
182
+ files: ['**/*.{js,cjs,mjs,jsx,ts,cts,mts,tsx}'],
183
+ plugins: {
184
+ 'unused-imports': unusedImportsPlugin,
185
+ },
186
+ rules: {
187
+ // 不要 import 文を禁止
188
+ 'unused-imports/no-unused-imports': 'error',
189
+ // 不要な変数を禁止
190
+ 'no-unused-vars': 'off',
191
+ '@typescript-eslint/no-unused-vars': 'off',
119
192
  'unused-imports/no-unused-vars': [
120
193
  'warn',
194
+ // '_' で始まる変数を許可
121
195
  {
122
196
  vars: 'all',
123
197
  varsIgnorePattern: '^_',
@@ -126,4 +200,15 @@ module.exports = {
126
200
  },
127
201
  ],
128
202
  },
129
- };
203
+ }, {
204
+ name: 'eslint-plugin-promise',
205
+ files: ['**/*.{js,cjs,mjs,jsx,ts,cts,mts,tsx}'],
206
+ extends: [promisePlugin.configs['flat/recommended']],
207
+ }, {
208
+ name: 'eslint-plugin-xss',
209
+ files: ['**/*.{js,cjs,mjs,jsx,ts,cts,mts,tsx}'],
210
+ // TODO: eslint-plugin-xss が Flat Configs に対応したら移行する
211
+ // https://github.com/Rantanen/eslint-plugin-xss/issues/15
212
+ // extends: ['plugin:xss/recommended'],
213
+ extends: [],
214
+ });