@jchiam/eslint-config 5.0.2 → 5.1.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/.gitattributes ADDED
@@ -0,0 +1 @@
1
+ * text=auto eol=lf
@@ -1,38 +1,38 @@
1
- name: CI
2
-
3
- on:
4
- push:
5
- branches: [master]
6
- pull_request:
7
- branches: [master]
8
-
9
- jobs:
10
- test:
11
- name: Node.js ${{ matrix.node-version }}
12
- runs-on: ubuntu-latest
13
- strategy:
14
- matrix:
15
- node-version: [20, 22, 24]
16
-
17
- steps:
18
- - uses: actions/checkout@v6
19
-
20
- - name: Set up Node.js
21
- uses: actions/setup-node@v6
22
- with:
23
- node-version: ${{ matrix.node-version }}
24
- cache: npm
25
-
26
- - name: Install dependencies
27
- run: npm ci
28
-
29
- - name: Validate configs load
30
- run: |
31
- node --input-type=module --eval "
32
- import recommended from './recommended.js';
33
- import react from './react.js';
34
- if (!Array.isArray(recommended)) throw new Error('recommended.js must export an array');
35
- if (!Array.isArray(react)) throw new Error('react.js must export an array');
36
- console.log('recommended.js: ok (' + recommended.length + ' config objects)');
37
- console.log('react.js: ok (' + react.length + ' config objects)');
38
- "
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [master]
6
+ pull_request:
7
+ branches: [master]
8
+
9
+ jobs:
10
+ test:
11
+ name: Node.js ${{ matrix.node-version }}
12
+ runs-on: ubuntu-latest
13
+ strategy:
14
+ matrix:
15
+ node-version: [20, 22, 24]
16
+
17
+ steps:
18
+ - uses: actions/checkout@v6
19
+
20
+ - name: Set up Node.js
21
+ uses: actions/setup-node@v6
22
+ with:
23
+ node-version: ${{ matrix.node-version }}
24
+ cache: npm
25
+
26
+ - name: Install dependencies
27
+ run: npm ci
28
+
29
+ - name: Validate configs load
30
+ run: |
31
+ node --input-type=module --eval "
32
+ import recommended from './recommended.js';
33
+ import react from './react.js';
34
+ if (!Array.isArray(recommended)) throw new Error('recommended.js must export an array');
35
+ if (!Array.isArray(react)) throw new Error('react.js must export an array');
36
+ console.log('recommended.js: ok (' + recommended.length + ' config objects)');
37
+ console.log('react.js: ok (' + react.length + ' config objects)');
38
+ "
@@ -1,26 +1,26 @@
1
- name: Publish
2
-
3
- on:
4
- release:
5
- types: [published]
6
-
7
- jobs:
8
- publish:
9
- runs-on: ubuntu-latest
10
- permissions:
11
- id-token: write
12
-
13
- steps:
14
- - uses: actions/checkout@v6
15
-
16
- - name: Set up Node.js
17
- uses: actions/setup-node@v6
18
- with:
19
- node-version: 24
20
- registry-url: https://registry.npmjs.org
21
-
22
- - name: Install dependencies
23
- run: npm ci
24
-
25
- - name: Publish to npm
26
- run: npm publish --access public --provenance
1
+ name: Publish
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ jobs:
8
+ publish:
9
+ runs-on: ubuntu-latest
10
+ permissions:
11
+ id-token: write
12
+
13
+ steps:
14
+ - uses: actions/checkout@v6
15
+
16
+ - name: Set up Node.js
17
+ uses: actions/setup-node@v6
18
+ with:
19
+ node-version: 24
20
+ registry-url: https://registry.npmjs.org
21
+
22
+ - name: Install dependencies
23
+ run: npm ci
24
+
25
+ - name: Publish to npm
26
+ run: npm publish --access public --provenance
package/README.md CHANGED
@@ -1,125 +1,125 @@
1
- # ESLint Config
2
-
3
- [![npm](https://img.shields.io/npm/v/@jchiam/eslint-config.svg)](https://npmjs.org/package/@jchiam/eslint-config)
4
-
5
- My personal shareable ESLint config. Targets TypeScript projects, with an optional React extension.
6
-
7
- ## Requirements
8
-
9
- - ESLint 9 (ESLint 10 not yet supported due to `eslint-plugin-import` peer dep constraints)
10
- - `typescript-eslint` ^8
11
- - `eslint-plugin-import` ^2.29
12
-
13
- React projects additionally need:
14
- - `eslint-plugin-react` ^7.32
15
- - `eslint-plugin-react-hooks` ^5
16
-
17
- ## Usage
18
-
19
- ```sh
20
- npm i -D @jchiam/eslint-config eslint typescript-eslint eslint-plugin-import
21
- ```
22
-
23
- Create `eslint.config.js` in your project root:
24
-
25
- ```js
26
- // eslint.config.js — TypeScript project
27
- import jchiamConfig from '@jchiam/eslint-config';
28
-
29
- export default [...jchiamConfig];
30
- ```
31
-
32
- ```js
33
- // eslint.config.js — React + TypeScript project
34
- import jchiamConfig from '@jchiam/eslint-config';
35
- import jchiamReact from '@jchiam/eslint-config/react';
36
-
37
- export default [...jchiamConfig, ...jchiamReact];
38
- ```
39
-
40
- Override rules by appending a config object to the array:
41
-
42
- ```js
43
- import jchiamConfig from '@jchiam/eslint-config';
44
-
45
- export default [
46
- ...jchiamConfig,
47
- {
48
- rules: {
49
- 'prefer-const': 'warn', // override to warn instead of error
50
- },
51
- },
52
- ];
53
- ```
54
-
55
- ## What's included
56
-
57
- ### `recommended.js`
58
-
59
- - [`eslint:recommended`](https://eslint.org/docs/rules/) — ESLint core rules
60
- - [`typescript-eslint`](https://typescript-eslint.io/) recommended rules
61
- - [`eslint-plugin-import`](https://github.com/import-js/eslint-plugin-import) recommended + TypeScript resolver
62
- - [`@stylistic/eslint-plugin`](https://eslint.style/) for formatting (indent, spacing, quotes, semi, etc.)
63
- - Additional opinionated rules for best practices and ES6+
64
-
65
- ### `react.js`
66
-
67
- Extends `recommended.js` intent with:
68
- - [`eslint-plugin-react`](https://github.com/jsx-eslint/eslint-plugin-react) recommended (with `react/prop-types` off for TypeScript)
69
- - [`eslint-plugin-react-hooks`](https://github.com/facebook/react) rules of hooks + exhaustive deps
70
-
71
- ## Breaking Changes
72
-
73
- ### v4 to v5
74
-
75
- Migrated to [ESLint flat config](https://eslint.org/docs/latest/use/configure/configuration-files) (required for ESLint 9+). The `.eslintrc` format is no longer supported.
76
-
77
- **Note:** delete your existing `node_modules` and `package-lock.json` before reinstalling — the old lockfile pins conflicting major versions and will cause resolution errors.
78
-
79
- Install the new peer dependencies:
80
-
81
- ```sh
82
- npm i -D typescript-eslint
83
- ```
84
-
85
- Remove the old peer dependencies (now bundled or renamed):
86
-
87
- ```sh
88
- npm uninstall @typescript-eslint/eslint-plugin @typescript-eslint/parser
89
- ```
90
-
91
- Config format changes from `.eslintrc.js`:
92
-
93
- ```js
94
- // Before (.eslintrc.js)
95
- module.exports = {
96
- extends: ['@jchiam/eslint-config/recommended'],
97
- };
98
- ```
99
-
100
- To `eslint.config.js`:
101
-
102
- ```js
103
- // After
104
- import jchiamConfig from '@jchiam/eslint-config';
105
- export default [...jchiamConfig];
106
- ```
107
-
108
- **Rule changes:**
109
- - Formatting rules moved from ESLint core to `@stylistic/eslint-plugin` (same rules, prefixed with `@stylistic/`)
110
- - `no-shadow` / `no-use-before-define` replaced by their `@typescript-eslint/*` equivalents (TS-aware, no false positives on type declarations)
111
- - `no-new-object` renamed to `no-object-constructor`
112
- - `vars-on-top` removed (redundant — `no-var` is enforced and `@typescript-eslint/no-use-before-define` covers the intent)
113
- - `@typescript-eslint/indent` removed (was deprecated and broken; `@stylistic/indent` is used instead)
114
-
115
- ### v3 to v4
116
-
117
- The original config file was split from `index.js` into `recommended.js` and `react.js` to allow non-React projects to use only the base config.
118
-
119
- ```js
120
- // Before
121
- { "extends": "@jchiam" }
122
-
123
- // After
124
- { "extends": ["@jchiam/eslint-config/recommended", "@jchiam/eslint-config/react"] }
125
- ```
1
+ # ESLint Config
2
+
3
+ [![npm](https://img.shields.io/npm/v/@jchiam/eslint-config.svg)](https://npmjs.org/package/@jchiam/eslint-config)
4
+
5
+ My personal shareable ESLint config. Targets TypeScript projects, with an optional React extension.
6
+
7
+ ## Requirements
8
+
9
+ - ESLint 9 (ESLint 10 not yet supported due to `eslint-plugin-import` peer dep constraints)
10
+ - `typescript-eslint` ^8
11
+ - `eslint-plugin-import` ^2.29
12
+
13
+ React projects additionally need:
14
+ - `eslint-plugin-react` ^7.32
15
+ - `eslint-plugin-react-hooks` ^5
16
+
17
+ ## Usage
18
+
19
+ ```sh
20
+ npm i -D @jchiam/eslint-config eslint typescript-eslint eslint-plugin-import
21
+ ```
22
+
23
+ Create `eslint.config.js` in your project root:
24
+
25
+ ```js
26
+ // eslint.config.js — TypeScript project
27
+ import jchiamConfig from '@jchiam/eslint-config';
28
+
29
+ export default [...jchiamConfig];
30
+ ```
31
+
32
+ ```js
33
+ // eslint.config.js — React + TypeScript project
34
+ import jchiamConfig from '@jchiam/eslint-config';
35
+ import jchiamReact from '@jchiam/eslint-config/react';
36
+
37
+ export default [...jchiamConfig, ...jchiamReact];
38
+ ```
39
+
40
+ Override rules by appending a config object to the array:
41
+
42
+ ```js
43
+ import jchiamConfig from '@jchiam/eslint-config';
44
+
45
+ export default [
46
+ ...jchiamConfig,
47
+ {
48
+ rules: {
49
+ 'prefer-const': 'warn', // override to warn instead of error
50
+ },
51
+ },
52
+ ];
53
+ ```
54
+
55
+ ## What's included
56
+
57
+ ### `recommended.js`
58
+
59
+ - [`eslint:recommended`](https://eslint.org/docs/rules/) — ESLint core rules
60
+ - [`typescript-eslint`](https://typescript-eslint.io/) recommended rules
61
+ - [`eslint-plugin-import`](https://github.com/import-js/eslint-plugin-import) recommended + TypeScript resolver
62
+ - [`@stylistic/eslint-plugin`](https://eslint.style/) for formatting (indent, spacing, quotes, semi, etc.)
63
+ - Additional opinionated rules for best practices and ES6+
64
+
65
+ ### `react.js`
66
+
67
+ Extends `recommended.js` intent with:
68
+ - [`eslint-plugin-react`](https://github.com/jsx-eslint/eslint-plugin-react) recommended (with `react/prop-types` off for TypeScript)
69
+ - [`eslint-plugin-react-hooks`](https://github.com/facebook/react) rules of hooks + exhaustive deps
70
+
71
+ ## Breaking Changes
72
+
73
+ ### v4 to v5
74
+
75
+ Migrated to [ESLint flat config](https://eslint.org/docs/latest/use/configure/configuration-files) (required for ESLint 9+). The `.eslintrc` format is no longer supported.
76
+
77
+ **Note:** delete your existing `node_modules` and `package-lock.json` before reinstalling — the old lockfile pins conflicting major versions and will cause resolution errors.
78
+
79
+ Install the new peer dependencies:
80
+
81
+ ```sh
82
+ npm i -D typescript-eslint
83
+ ```
84
+
85
+ Remove the old peer dependencies (now bundled or renamed):
86
+
87
+ ```sh
88
+ npm uninstall @typescript-eslint/eslint-plugin @typescript-eslint/parser
89
+ ```
90
+
91
+ Config format changes from `.eslintrc.js`:
92
+
93
+ ```js
94
+ // Before (.eslintrc.js)
95
+ module.exports = {
96
+ extends: ['@jchiam/eslint-config/recommended'],
97
+ };
98
+ ```
99
+
100
+ To `eslint.config.js`:
101
+
102
+ ```js
103
+ // After
104
+ import jchiamConfig from '@jchiam/eslint-config';
105
+ export default [...jchiamConfig];
106
+ ```
107
+
108
+ **Rule changes:**
109
+ - Formatting rules moved from ESLint core to `@stylistic/eslint-plugin` (same rules, prefixed with `@stylistic/`)
110
+ - `no-shadow` / `no-use-before-define` replaced by their `@typescript-eslint/*` equivalents (TS-aware, no false positives on type declarations)
111
+ - `no-new-object` renamed to `no-object-constructor`
112
+ - `vars-on-top` removed (redundant — `no-var` is enforced and `@typescript-eslint/no-use-before-define` covers the intent)
113
+ - `@typescript-eslint/indent` removed (was deprecated and broken; `@stylistic/indent` is used instead)
114
+
115
+ ### v3 to v4
116
+
117
+ The original config file was split from `index.js` into `recommended.js` and `react.js` to allow non-React projects to use only the base config.
118
+
119
+ ```js
120
+ // Before
121
+ { "extends": "@jchiam" }
122
+
123
+ // After
124
+ { "extends": ["@jchiam/eslint-config/recommended", "@jchiam/eslint-config/react"] }
125
+ ```
package/package.json CHANGED
@@ -1,47 +1,43 @@
1
- {
2
- "name": "@jchiam/eslint-config",
3
- "version": "5.0.2",
4
- "description": "my personal ESLint rules",
5
- "type": "module",
6
- "main": "recommended.js",
7
- "scripts": {
8
- "test": "echo \"Error: no test specified\" && exit 1"
9
- },
10
- "repository": {
11
- "type": "git",
12
- "url": "git+https://github.com/jchiam/eslint-config.git"
13
- },
14
- "author": "Jonathan Chiam",
15
- "dependencies": {
16
- "@eslint/js": "^9.0.0",
17
- "@stylistic/eslint-plugin": "^5.0.0",
18
- "globals": "^17.0.0"
19
- },
20
- "peerDependencies": {
21
- "eslint": "^9.0.0 || ^10.0.0",
22
- "typescript-eslint": "^8.0.0",
23
- "eslint-plugin-import": "^2.29.0",
24
- "eslint-plugin-jest": "^29.0.0",
25
- "eslint-plugin-react": "^7.32.0",
26
- "eslint-plugin-react-hooks": "^7.0.0"
27
- },
28
- "peerDependenciesMeta": {
29
- "eslint-plugin-jest": {
30
- "optional": true
31
- },
32
- "eslint-plugin-react": {
33
- "optional": true
34
- },
35
- "eslint-plugin-react-hooks": {
36
- "optional": true
37
- }
38
- },
39
- "devDependencies": {
40
- "eslint": "^9.0.0",
41
- "eslint-plugin-import": "^2.32.0",
42
- "eslint-plugin-react": "^7.37.5",
43
- "eslint-plugin-react-hooks": "^7.0.0",
44
- "typescript": "^5.0.0",
45
- "typescript-eslint": "^8.0.0"
46
- }
47
- }
1
+ {
2
+ "name": "@jchiam/eslint-config",
3
+ "version": "5.1.0",
4
+ "description": "my personal ESLint rules",
5
+ "type": "module",
6
+ "main": "recommended.js",
7
+ "scripts": {
8
+ "test": "echo \"Error: no test specified\" && exit 1"
9
+ },
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/jchiam/eslint-config.git"
13
+ },
14
+ "author": "Jonathan Chiam",
15
+ "dependencies": {
16
+ "@eslint-react/eslint-plugin": "^1.0.0",
17
+ "@eslint/js": "^9.0.0",
18
+ "@stylistic/eslint-plugin": "^5.0.0",
19
+ "globals": "^17.0.0"
20
+ },
21
+ "peerDependencies": {
22
+ "eslint": "^9.0.0 || ^10.0.0",
23
+ "typescript-eslint": "^8.0.0",
24
+ "eslint-plugin-import": "^2.29.0",
25
+ "eslint-plugin-jest": "^29.0.0",
26
+ "eslint-plugin-react-hooks": "^7.0.0"
27
+ },
28
+ "peerDependenciesMeta": {
29
+ "eslint-plugin-jest": {
30
+ "optional": true
31
+ },
32
+ "eslint-plugin-react-hooks": {
33
+ "optional": true
34
+ }
35
+ },
36
+ "devDependencies": {
37
+ "eslint": "^9.0.0",
38
+ "eslint-plugin-import": "^2.32.0",
39
+ "eslint-plugin-react-hooks": "^7.0.0",
40
+ "typescript": "^5.0.0",
41
+ "typescript-eslint": "^8.0.0"
42
+ }
43
+ }
package/react.js CHANGED
@@ -1,37 +1,25 @@
1
- import reactPlugin from 'eslint-plugin-react';
2
- import reactHooksPlugin from 'eslint-plugin-react-hooks';
3
- import stylistic from '@stylistic/eslint-plugin';
4
-
5
- export default [
6
- reactPlugin.configs.flat.recommended,
7
- {
8
- plugins: {
9
- '@stylistic': stylistic,
10
- 'react-hooks': reactHooksPlugin,
11
- },
12
- languageOptions: {
13
- parserOptions: {
14
- ecmaFeatures: {
15
- jsx: true,
16
- },
17
- },
18
- },
19
- rules: {
20
- 'react/prop-types': 'off',
21
- 'react-hooks/rules-of-hooks': 'error',
22
- 'react-hooks/exhaustive-deps': 'warn',
23
- '@stylistic/jsx-quotes': 'error',
24
- },
25
- settings: {
26
- 'import/resolver': {
27
- node: {
28
- extensions: ['.js', '.jsx', '.ts', '.tsx', '.d.ts'],
29
- moduleDirectory: ['node_modules', 'src'],
30
- },
31
- },
32
- react: {
33
- version: 'detect',
34
- },
35
- },
36
- },
37
- ];
1
+ import eslintReact from '@eslint-react/eslint-plugin';
2
+ import reactHooksPlugin from 'eslint-plugin-react-hooks';
3
+ import stylistic from '@stylistic/eslint-plugin';
4
+
5
+ export default [
6
+ eslintReact.configs.recommended,
7
+ {
8
+ plugins: {
9
+ '@stylistic': stylistic,
10
+ 'react-hooks': reactHooksPlugin,
11
+ },
12
+ languageOptions: {
13
+ parserOptions: {
14
+ ecmaFeatures: {
15
+ jsx: true,
16
+ },
17
+ },
18
+ },
19
+ rules: {
20
+ 'react-hooks/rules-of-hooks': 'error',
21
+ 'react-hooks/exhaustive-deps': 'warn',
22
+ '@stylistic/jsx-quotes': 'error',
23
+ },
24
+ },
25
+ ];
package/recommended.js CHANGED
@@ -1,111 +1,111 @@
1
- import js from '@eslint/js';
2
- import tseslint from 'typescript-eslint';
3
- import importPlugin from 'eslint-plugin-import';
4
- import stylistic from '@stylistic/eslint-plugin';
5
- import globals from 'globals';
6
-
7
- export default [
8
- js.configs.recommended,
9
- ...tseslint.configs.recommended,
10
- importPlugin.flatConfigs.recommended,
11
- importPlugin.flatConfigs.typescript,
12
- {
13
- plugins: {
14
- '@stylistic': stylistic,
15
- },
16
- languageOptions: {
17
- globals: {
18
- ...globals.es2020,
19
- ...globals.node,
20
- ...globals.browser,
21
- },
22
- parserOptions: {
23
- ecmaVersion: 'latest',
24
- },
25
- },
26
- rules: {
27
- // TypeScript rules
28
- '@typescript-eslint/array-type': ['error', { default: 'generic' }],
29
- '@typescript-eslint/explicit-function-return-type': 'off',
30
- '@typescript-eslint/no-explicit-any': 'off',
31
- '@typescript-eslint/no-shadow': 'error',
32
- '@typescript-eslint/no-use-before-define': 'error',
33
-
34
- // Disable base rules superseded by TypeScript equivalents
35
- 'no-shadow': 'off',
36
- 'no-use-before-define': 'off',
37
-
38
- // Best practice rules
39
- 'camelcase': 'error',
40
- 'eqeqeq': ['error', 'smart'],
41
- 'func-style': ['error', 'declaration', { allowArrowFunctions: true }],
42
- 'max-depth': 'warn',
43
- 'max-lines': ['warn', { skipBlankLines: true, skipComments: true }],
44
- 'no-bitwise': 'error',
45
- 'no-continue': 'error',
46
- 'no-else-return': 'warn',
47
- 'no-lonely-if': 'error',
48
- 'no-nested-ternary': 'error',
49
- 'no-object-constructor': 'error',
50
- 'no-unneeded-ternary': 'error',
51
- 'operator-assignment': 'error',
52
- 'prefer-object-spread': 'error',
53
-
54
- // ES6+ rules
55
- 'no-duplicate-imports': 'error',
56
- 'no-useless-computed-key': 'error',
57
- 'no-var': 'error',
58
- 'object-shorthand': 'error',
59
- 'prefer-const': 'error',
60
- 'prefer-destructuring': ['error', { array: false, object: true }],
61
- 'prefer-numeric-literals': 'error',
62
- 'prefer-template': 'error',
63
-
64
- // Formatting (via @stylistic/eslint-plugin)
65
- '@stylistic/array-bracket-spacing': 'error',
66
- '@stylistic/arrow-parens': ['error', 'as-needed'],
67
- '@stylistic/arrow-spacing': 'error',
68
- '@stylistic/block-spacing': 'error',
69
- '@stylistic/brace-style': ['error', '1tbs', { allowSingleLine: true }],
70
- '@stylistic/comma-dangle': 'error',
71
- '@stylistic/comma-spacing': 'error',
72
- '@stylistic/comma-style': 'error',
73
- '@stylistic/computed-property-spacing': 'error',
74
- '@stylistic/eol-last': 'error',
75
- '@stylistic/function-call-spacing': 'error',
76
- '@stylistic/indent': ['error', 2, { SwitchCase: 1 }],
77
- '@stylistic/key-spacing': 'error',
78
- '@stylistic/keyword-spacing': 'error',
79
- '@stylistic/lines-around-comment': ['error', { beforeBlockComment: true, allowBlockStart: true }],
80
- '@stylistic/lines-between-class-members': ['error', 'always', { exceptAfterSingleLine: true }],
81
- '@stylistic/newline-per-chained-call': ['error', { ignoreChainWithDepth: 2 }],
82
- '@stylistic/no-multi-spaces': ['error', { ignoreEOLComments: true }],
83
- '@stylistic/no-multiple-empty-lines': 'error',
84
- '@stylistic/no-tabs': 'error',
85
- '@stylistic/no-trailing-spaces': 'error',
86
- '@stylistic/no-whitespace-before-property': 'error',
87
- '@stylistic/nonblock-statement-body-position': 'error',
88
- '@stylistic/object-curly-spacing': ['error', 'always'],
89
- '@stylistic/object-property-newline': ['error', { allowAllPropertiesOnSameLine: true }],
90
- '@stylistic/operator-linebreak': ['error', 'after'],
91
- '@stylistic/quote-props': ['error', 'consistent-as-needed'],
92
- '@stylistic/quotes': ['error', 'single'],
93
- '@stylistic/rest-spread-spacing': 'error',
94
- '@stylistic/semi': 'error',
95
- '@stylistic/semi-style': 'error',
96
- '@stylistic/space-before-blocks': 'error',
97
- '@stylistic/space-before-function-paren': ['error', { anonymous: 'always', named: 'never', asyncArrow: 'always' }],
98
- '@stylistic/space-in-parens': 'error',
99
- '@stylistic/switch-colon-spacing': 'error',
100
- '@stylistic/template-curly-spacing': 'error',
101
- },
102
- settings: {
103
- 'import/resolver': {
104
- node: {
105
- extensions: ['.js', '.ts', '.d.ts'],
106
- moduleDirectory: ['node_modules', 'src'],
107
- },
108
- },
109
- },
110
- },
111
- ];
1
+ import js from '@eslint/js';
2
+ import tseslint from 'typescript-eslint';
3
+ import importPlugin from 'eslint-plugin-import';
4
+ import stylistic from '@stylistic/eslint-plugin';
5
+ import globals from 'globals';
6
+
7
+ export default [
8
+ js.configs.recommended,
9
+ ...tseslint.configs.recommended,
10
+ importPlugin.flatConfigs.recommended,
11
+ importPlugin.flatConfigs.typescript,
12
+ {
13
+ plugins: {
14
+ '@stylistic': stylistic,
15
+ },
16
+ languageOptions: {
17
+ globals: {
18
+ ...globals.es2020,
19
+ ...globals.node,
20
+ ...globals.browser,
21
+ },
22
+ parserOptions: {
23
+ ecmaVersion: 'latest',
24
+ },
25
+ },
26
+ rules: {
27
+ // TypeScript rules
28
+ '@typescript-eslint/array-type': ['error', { default: 'generic' }],
29
+ '@typescript-eslint/explicit-function-return-type': 'off',
30
+ '@typescript-eslint/no-explicit-any': 'off',
31
+ '@typescript-eslint/no-shadow': 'error',
32
+ '@typescript-eslint/no-use-before-define': 'error',
33
+
34
+ // Disable base rules superseded by TypeScript equivalents
35
+ 'no-shadow': 'off',
36
+ 'no-use-before-define': 'off',
37
+
38
+ // Best practice rules
39
+ 'camelcase': 'error',
40
+ 'eqeqeq': ['error', 'smart'],
41
+ 'func-style': ['error', 'declaration', { allowArrowFunctions: true }],
42
+ 'max-depth': 'warn',
43
+ 'max-lines': ['warn', { skipBlankLines: true, skipComments: true }],
44
+ 'no-bitwise': 'error',
45
+ 'no-continue': 'error',
46
+ 'no-else-return': 'warn',
47
+ 'no-lonely-if': 'error',
48
+ 'no-nested-ternary': 'error',
49
+ 'no-object-constructor': 'error',
50
+ 'no-unneeded-ternary': 'error',
51
+ 'operator-assignment': 'error',
52
+ 'prefer-object-spread': 'error',
53
+
54
+ // ES6+ rules
55
+ 'no-duplicate-imports': 'error',
56
+ 'no-useless-computed-key': 'error',
57
+ 'no-var': 'error',
58
+ 'object-shorthand': 'error',
59
+ 'prefer-const': 'error',
60
+ 'prefer-destructuring': ['error', { array: false, object: true }],
61
+ 'prefer-numeric-literals': 'error',
62
+ 'prefer-template': 'error',
63
+
64
+ // Formatting (via @stylistic/eslint-plugin)
65
+ '@stylistic/array-bracket-spacing': 'error',
66
+ '@stylistic/arrow-parens': ['error', 'as-needed'],
67
+ '@stylistic/arrow-spacing': 'error',
68
+ '@stylistic/block-spacing': 'error',
69
+ '@stylistic/brace-style': ['error', '1tbs', { allowSingleLine: true }],
70
+ '@stylistic/comma-dangle': 'error',
71
+ '@stylistic/comma-spacing': 'error',
72
+ '@stylistic/comma-style': 'error',
73
+ '@stylistic/computed-property-spacing': 'error',
74
+ '@stylistic/eol-last': 'error',
75
+ '@stylistic/function-call-spacing': 'error',
76
+ '@stylistic/indent': ['error', 2, { SwitchCase: 1 }],
77
+ '@stylistic/key-spacing': 'error',
78
+ '@stylistic/keyword-spacing': 'error',
79
+ '@stylistic/lines-around-comment': ['error', { beforeBlockComment: true, allowBlockStart: true }],
80
+ '@stylistic/lines-between-class-members': ['error', 'always', { exceptAfterSingleLine: true }],
81
+ '@stylistic/newline-per-chained-call': ['error', { ignoreChainWithDepth: 2 }],
82
+ '@stylistic/no-multi-spaces': ['error', { ignoreEOLComments: true }],
83
+ '@stylistic/no-multiple-empty-lines': 'error',
84
+ '@stylistic/no-tabs': 'error',
85
+ '@stylistic/no-trailing-spaces': 'error',
86
+ '@stylistic/no-whitespace-before-property': 'error',
87
+ '@stylistic/nonblock-statement-body-position': 'error',
88
+ '@stylistic/object-curly-spacing': ['error', 'always'],
89
+ '@stylistic/object-property-newline': ['error', { allowAllPropertiesOnSameLine: true }],
90
+ '@stylistic/operator-linebreak': ['error', 'after'],
91
+ '@stylistic/quote-props': ['error', 'consistent-as-needed'],
92
+ '@stylistic/quotes': ['error', 'single'],
93
+ '@stylistic/rest-spread-spacing': 'error',
94
+ '@stylistic/semi': 'error',
95
+ '@stylistic/semi-style': 'error',
96
+ '@stylistic/space-before-blocks': 'error',
97
+ '@stylistic/space-before-function-paren': ['error', { anonymous: 'always', named: 'never', asyncArrow: 'always' }],
98
+ '@stylistic/space-in-parens': 'error',
99
+ '@stylistic/switch-colon-spacing': 'error',
100
+ '@stylistic/template-curly-spacing': 'error',
101
+ },
102
+ settings: {
103
+ 'import/resolver': {
104
+ node: {
105
+ extensions: ['.js', '.jsx', '.ts', '.tsx', '.d.ts'],
106
+ moduleDirectory: ['node_modules', 'src'],
107
+ },
108
+ },
109
+ },
110
+ },
111
+ ];