@foray1010/eslint-config 9.2.0 → 10.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.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,36 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [10.0.1](https://github.com/foray1010/common-presets/compare/@foray1010/eslint-config@10.0.0...@foray1010/eslint-config@10.0.1) (2023-03-23)
7
+
8
+ ### Bug Fixes
9
+
10
+ - **eslint-config:** fix wrong assumption, `files` only does not filter ([661d0c6](https://github.com/foray1010/common-presets/commit/661d0c6bd05f688c8f6956fb26844e597c851dc4))
11
+ - **eslint-config:** should not use ignores in config, and allow user defined ignores ([05b0ca0](https://github.com/foray1010/common-presets/commit/05b0ca09a76ed677c903b654cef3eeef7773610e))
12
+
13
+ ## [10.0.0](https://github.com/foray1010/common-presets/compare/@foray1010/eslint-config@9.2.0...@foray1010/eslint-config@10.0.0) (2023-03-23)
14
+
15
+ ### ⚠ BREAKING CHANGES
16
+
17
+ - **eslint-config:** migrate to eslint flat config and mjs
18
+ - require node `^16.14.0 || >=18.12.0`
19
+
20
+ ### Features
21
+
22
+ - **eslint-config:** migrate to eslint flat config and mjs ([d435d01](https://github.com/foray1010/common-presets/commit/d435d012faf1574dda750917dbada56048eecd09))
23
+ - support ES2021 ([40a0e28](https://github.com/foray1010/common-presets/commit/40a0e282c937825dfca1969c30ffc26e5bd2a27c))
24
+ - **tsconfig:** split tsconfig to mutliple files for different scenarios ([fcaf3ae](https://github.com/foray1010/common-presets/commit/fcaf3aee3f9f1851439d01631c2e8584bde685ba))
25
+
26
+ ### Bug Fixes
27
+
28
+ - **deps:** update dependency eslint-plugin-functional to v5 ([169a5c4](https://github.com/foray1010/common-presets/commit/169a5c4f7f7d10c6d2f5206e71942063f1b710cc))
29
+ - **deps:** update dependency eslint-plugin-unicorn to v46 ([76621eb](https://github.com/foray1010/common-presets/commit/76621eb95fd7eb74fff3710ac739e4d12df1f768))
30
+ - **eslint-config:** migrate eslint-plugin-eslint-comments to eslint-community version ([9a1ce64](https://github.com/foray1010/common-presets/commit/9a1ce646462cffd091d58fbbb39b0a83138f0f3b))
31
+
32
+ ### Miscellaneous Chores
33
+
34
+ - require node `^16.14.0 || >=18.12.0` ([5baf6eb](https://github.com/foray1010/common-presets/commit/5baf6eba6d42958596c130724a502c59fe1a4e83))
35
+
6
36
  ## [9.2.0](https://github.com/foray1010/common-presets/compare/@foray1010/eslint-config@9.1.0...@foray1010/eslint-config@9.2.0) (2023-02-25)
7
37
 
8
38
  ### Features
package/README.md CHANGED
@@ -20,51 +20,79 @@ Z for looser rules
20
20
 
21
21
  1. `yarn add -DE @foray1010/eslint-config eslint prettier`
22
22
 
23
- 1. Create an `.eslintrc.cjs` in the project root
24
-
25
- For general purpose, support TypeScript
26
-
27
- ```js
28
- 'use strict'
29
-
30
- module.exports = {
31
- root: true,
32
- extends: ['@foray1010/eslint-config'],
33
- }
34
- ```
35
-
36
- For frontend React projects, support TypeScript
37
-
38
- ```js
39
- 'use strict'
40
-
41
- module.exports = {
42
- root: true,
43
- extends: ['@foray1010/eslint-config/react'],
44
- }
45
- ```
46
-
47
- For TS projects in monorepo, mark the `tsconfigRootDir` to use the correct `tsconfig.json`
48
-
49
- ```js
50
- 'use strict'
51
-
52
- module.exports = {
53
- root: true,
54
- extends: ['@foray1010/eslint-config'],
55
- parserOptions: {
56
- // Make sure the correct `tsconfig.json` is found in monorepo
57
- tsconfigRootDir: __dirname,
58
- },
59
- }
60
- ```
61
-
62
- 1. Use default eslintignore via npm script
23
+ 1. Create an `eslint.config.mjs` in the project root (It is not a standard config path, but we opts for `.mjs` extension to make it compatible with commonjs projects)
24
+
25
+ - For general purpose or Node.js project (support TypeScript)
26
+
27
+ ```js
28
+ import {
29
+ eslintIgnoresConfig,
30
+ eslintNodeConfig,
31
+ } from '@foray1010/eslint-config'
32
+
33
+ const config = [...eslintIgnoresConfig, ...eslintNodeConfig]
34
+ export default config
35
+ ```
36
+
37
+ - For general frontend projects (support TypeScript)
38
+
39
+ ```js
40
+ import {
41
+ eslintIgnoresConfig,
42
+ eslintBrowserConfig,
43
+ } from '@foray1010/eslint-config'
44
+
45
+ const config = [...eslintIgnoresConfig, ...eslintBrowserConfig]
46
+ export default config
47
+ ```
48
+
49
+ - For frontend React projects (support TypeScript)
50
+
51
+ ```js
52
+ import {
53
+ eslintIgnoresConfig,
54
+ eslintReactConfig,
55
+ } from '@foray1010/eslint-config'
56
+
57
+ const config = [...eslintIgnoresConfig, ...eslintReactConfig]
58
+ export default config
59
+ ```
60
+
61
+ - You can apply config per different directories
62
+
63
+ ```js
64
+ import {
65
+ applyConfig,
66
+ eslintIgnoresConfig,
67
+ eslintNodeConfig,
68
+ eslintReactConfig,
69
+ } from '@foray1010/eslint-config'
70
+
71
+ const config = [
72
+ ...eslintIgnoresConfig,
73
+ ...applyConfig(
74
+ {
75
+ filePrefixes: '.',
76
+ ignores: ['src/**'],
77
+ },
78
+ eslintNodeConfig,
79
+ ),
80
+ ...applyConfig(
81
+ {
82
+ filePrefixes: ['src'],
83
+ },
84
+ eslintReactConfig,
85
+ ),
86
+ ]
87
+ export default config
88
+ ```
89
+
90
+ 1. Add npm script
63
91
 
64
92
  ```json
65
93
  {
66
94
  "scripts": {
67
- "eslint": "eslint --ext=cjs,cts,js,mjs,mts,ts,tsx --ignore-path=node_modules/@foray1010/eslint-config/eslintignore"
95
+ "eslint": "ESLINT_USE_FLAT_CONFIG=true eslint --config eslint.config.mjs"
68
96
  }
69
97
  }
70
98
  ```
package/bases/base.mjs ADDED
@@ -0,0 +1,382 @@
1
+ import js from '@eslint/js'
2
+ import eslintPluginEslintComments from '@eslint-community/eslint-plugin-eslint-comments'
3
+ // @ts-expect-error
4
+ import { hasDep, isESM } from '@foray1010/common-presets-utils'
5
+ import eslintPluginTypescriptEslint from '@typescript-eslint/eslint-plugin'
6
+ import typescriptEslintParser from '@typescript-eslint/parser'
7
+ import eslintPluginDeprecation from 'eslint-plugin-deprecation'
8
+ import eslintPluginFunctional from 'eslint-plugin-functional'
9
+ import eslintPluginImport from 'eslint-plugin-import'
10
+ import eslintPluginJest from 'eslint-plugin-jest'
11
+ import eslintPluginSimpleImportSort from 'eslint-plugin-simple-import-sort'
12
+ import eslintPluginUnicorn from 'eslint-plugin-unicorn'
13
+ import globals from 'globals'
14
+
15
+ import {
16
+ testFileGlobs,
17
+ typeScriptFileGlobs,
18
+ typeScriptTestFileGlobs,
19
+ } from '../constants.mjs'
20
+
21
+ /** @type {import('eslint').Linter.FlatConfig} */
22
+ const cjsConfig = {
23
+ languageOptions: {
24
+ globals: globals.commonjs,
25
+ sourceType: 'script',
26
+ },
27
+ rules: {
28
+ // commonjs must use strict mode
29
+ strict: ['error', 'global'],
30
+ },
31
+ }
32
+
33
+ /** @type {import('eslint').Linter.FlatConfig} */
34
+ const esmConfig = {
35
+ languageOptions: {
36
+ sourceType: 'module',
37
+ },
38
+ plugins: {
39
+ 'simple-import-sort': eslintPluginSimpleImportSort,
40
+ },
41
+ rules: {
42
+ // auto sort export statements
43
+ 'simple-import-sort/exports': 'error',
44
+ // auto sort import statements
45
+ 'simple-import-sort/imports': 'error',
46
+ },
47
+ }
48
+
49
+ /** @type {readonly import('eslint').Linter.FlatConfig[]} */
50
+ const baseConfig = [
51
+ js.configs.recommended,
52
+ {
53
+ languageOptions: {
54
+ ecmaVersion: 2021,
55
+ globals: {
56
+ // should align with languageOptions.ecmaVersion
57
+ ...globals.es2021,
58
+ /* Not using `node` to explicitly import node.js only built-in modules, e.g.
59
+ * import { Buffer } from 'node:buffer'
60
+ * import process from 'node:process'
61
+ */
62
+ ...globals['shared-node-browser'],
63
+ },
64
+ },
65
+ plugins: {
66
+ '@eslint-community/eslint-comments': eslintPluginEslintComments,
67
+ import: eslintPluginImport,
68
+ unicorn: eslintPluginUnicorn,
69
+ },
70
+ rules: {
71
+ ...eslintPluginEslintComments.configs['recommended']?.rules,
72
+ ...eslintPluginImport.configs['recommended']?.rules,
73
+ // allow disable eslint rules for whole file without re-enable it in the end of the file
74
+ '@eslint-community/eslint-comments/disable-enable-pair': [
75
+ 'error',
76
+ { allowWholeFile: true },
77
+ ],
78
+ // make sure every eslint-disable comments are in use
79
+ '@eslint-community/eslint-comments/no-unused-disable': 'error',
80
+ // always use named function for easier to debug via stack trace
81
+ 'func-names': ['error', 'as-needed'],
82
+ // this rule doesn't support commonjs, some dependencies are using commonjs
83
+ 'import/default': 'off',
84
+ // enforce extensions for both cjs and esm
85
+ 'import/extensions': [
86
+ 'error',
87
+ // https://nodejs.org/docs/latest-v14.x/api/esm.html#esm_mandatory_file_extensions
88
+ 'always',
89
+ {
90
+ pattern: {
91
+ // eslint-plugin-import does not support checking es modules in typescript files
92
+ cts: 'never',
93
+ mts: 'never',
94
+ ts: 'never',
95
+ tsx: 'never',
96
+ },
97
+ },
98
+ ],
99
+ // make sure import statements above the others
100
+ 'import/first': 'error',
101
+ // separate import statements from the others
102
+ 'import/newline-after-import': 'error',
103
+ // avoid anonymous function or class for easier to debug via stack trace
104
+ // for other types, enforcing named data can improve autocomplete when importing
105
+ 'import/no-anonymous-default-export': [
106
+ 'error',
107
+ {
108
+ allowArray: false,
109
+ allowArrowFunction: false,
110
+ allowAnonymousClass: false,
111
+ allowAnonymousFunction: false,
112
+ allowCallExpression: false,
113
+ allowLiteral: false,
114
+ allowObject: false,
115
+ },
116
+ ],
117
+ // no circular dependency
118
+ 'import/no-cycle': [
119
+ 'error',
120
+ {
121
+ // speed up linting time
122
+ ignoreExternal: true,
123
+ },
124
+ ],
125
+ // do not allow import packages that are not listed in dependencies or peerDependencies
126
+ 'import/no-extraneous-dependencies': [
127
+ 'error',
128
+ {
129
+ devDependencies: [
130
+ '!**/src/**', // allow files outside of src/
131
+ '**/.*', // allow config rc files
132
+ ...testFileGlobs,
133
+ ],
134
+ },
135
+ ],
136
+ // forbid a module from importing itself
137
+ 'import/no-self-import': 'error',
138
+ // use the shortest path in import statement, but allow /index because it will be standard to omit index as default file in directory
139
+ 'import/no-useless-path-segments': [
140
+ 'error',
141
+ {
142
+ commonjs: true,
143
+ noUselessIndex: false,
144
+ },
145
+ ],
146
+ // prefer explicitly convert type for readability
147
+ 'no-implicit-coercion': 'error',
148
+ // make sure private class members are in-use
149
+ 'no-unused-private-class-members': 'error',
150
+ // avoid assigning anonymous function to object key which is harder to trace when debug
151
+ 'object-shorthand': ['error', 'always'],
152
+ // prefer `const` when the variable won't be reassigned
153
+ 'prefer-const': [
154
+ 'error',
155
+ {
156
+ // if one of the variables will be reassigned, do not enforce `const`
157
+ destructuring: 'all',
158
+ },
159
+ ],
160
+ // use with `unicorn/throw-new-error`
161
+ // disallow builtins to be created without `new` operator, to be consistent with es6 class syntax
162
+ 'unicorn/new-for-builtins': 'error',
163
+ // prefer `import from 'node:xxx'`
164
+ 'unicorn/prefer-node-protocol': 'error',
165
+ // prefer Number static properties over global ones
166
+ 'unicorn/prefer-number-properties': 'error',
167
+ // use with `unicorn/new-for-builtins`
168
+ 'unicorn/throw-new-error': 'error',
169
+ },
170
+ },
171
+ {
172
+ files: ['**/*.js'],
173
+ ...(isESM() ? esmConfig : cjsConfig),
174
+ },
175
+ {
176
+ files: ['**/*.cjs'],
177
+ ...cjsConfig,
178
+ },
179
+ {
180
+ files: ['**/*.mjs'],
181
+ ...esmConfig,
182
+ },
183
+ {
184
+ files: testFileGlobs,
185
+ languageOptions: {
186
+ globals: globals.jest,
187
+ },
188
+ plugins: {
189
+ jest: eslintPluginJest,
190
+ },
191
+ rules: {
192
+ ...eslintPluginJest.configs['recommended']?.rules,
193
+ ...eslintPluginJest.configs['style']?.rules,
194
+ // make sure lifecycle hooks on the top for readability
195
+ 'jest/prefer-hooks-on-top': 'error',
196
+ },
197
+ },
198
+ // typescript plugins are depended on `typescript` package
199
+ // @ts-expect-error
200
+ ...(hasDep('typescript')
201
+ ? [
202
+ {
203
+ files: typeScriptFileGlobs,
204
+ languageOptions: {
205
+ /** @type {any} */
206
+ parser: typescriptEslintParser,
207
+ parserOptions: {
208
+ // faster linting on cli
209
+ // https://github.com/typescript-eslint/typescript-eslint/issues/3528
210
+ // turned off because @typescript-eslint/no-unsafe-* rules will output wrong errors
211
+ // allowAutomaticSingleRunInference: true,
212
+ project: ['./tsconfig*.json', './packages/*/tsconfig*.json'],
213
+ },
214
+ },
215
+ settings: {
216
+ 'import/resolver': {
217
+ typescript: true,
218
+ },
219
+ },
220
+ plugins: {
221
+ '@typescript-eslint': eslintPluginTypescriptEslint,
222
+ deprecation: eslintPluginDeprecation,
223
+ functional: eslintPluginFunctional,
224
+ },
225
+ rules: {
226
+ ...eslintPluginTypescriptEslint.configs['eslint-recommended']
227
+ ?.rules,
228
+ ...eslintPluginTypescriptEslint.configs['recommended']?.rules,
229
+ ...eslintPluginTypescriptEslint.configs[
230
+ 'recommended-requiring-type-checking'
231
+ ]?.rules,
232
+ ...eslintPluginImport.configs['typescript']?.rules,
233
+ // extend existing rule
234
+ '@typescript-eslint/ban-types': [
235
+ 'error',
236
+ {
237
+ types: {
238
+ // TypeScript team suggests to use `<T extends {}>` https://devblogs.microsoft.com/typescript/announcing-typescript-4-8/#unconstrained-generics-no-longer-assignable-to
239
+ '{}': false,
240
+ },
241
+ extendDefaults: true,
242
+ },
243
+ ],
244
+ // separate type exports which allow certain optimizations within compilers
245
+ '@typescript-eslint/consistent-type-exports': 'error',
246
+ '@typescript-eslint/consistent-type-imports': [
247
+ 'error',
248
+ {
249
+ // separate type imports which allow certain optimizations within compilers
250
+ prefer: 'type-imports',
251
+ },
252
+ ],
253
+ // disable the base rule as it can report incorrect errors, use @typescript-eslint/dot-notation instead
254
+ 'dot-notation': 'off',
255
+ // only allow indexed syntax (e.g. `obj['key']`) for accessing undefined fields
256
+ '@typescript-eslint/dot-notation': [
257
+ 'error',
258
+ {
259
+ allowIndexSignaturePropertyAccess: true,
260
+ },
261
+ ],
262
+ // encourage to use private accessibility modifier
263
+ '@typescript-eslint/explicit-member-accessibility': [
264
+ 'error',
265
+ {
266
+ accessibility: 'explicit',
267
+ },
268
+ ],
269
+ // sometimes auto detect can provide a better and narrower type
270
+ '@typescript-eslint/explicit-module-boundary-types': 'off',
271
+ // disallow duplicated value in enum as it is error-prone
272
+ '@typescript-eslint/no-duplicate-enum-values': 'error',
273
+ // need empty function for react context default value
274
+ '@typescript-eslint/no-empty-function': 'off',
275
+ // encourage to check error type before use in catch clauses
276
+ '@typescript-eslint/no-implicit-any-catch': 'error',
277
+ // when using typescript 5.0 with verbatimModuleSyntax flag on, compiler will not remove import statements with only inline type imports which lead to side effects
278
+ '@typescript-eslint/no-import-type-side-effects': 'error',
279
+ // enforce correct usage of `void` type
280
+ '@typescript-eslint/no-invalid-void-type': 'error',
281
+ // allow using async function as event handler in frontend
282
+ '@typescript-eslint/no-misused-promises': [
283
+ 'error',
284
+ { checksVoidReturn: false },
285
+ ],
286
+ // declaration merging between classes and interfaces is unsafe
287
+ '@typescript-eslint/no-unsafe-declaration-merging': 'error',
288
+ // do not block functions referring to other functions
289
+ '@typescript-eslint/no-use-before-define': [
290
+ 'error',
291
+ {
292
+ /* options from eslint/no-use-before-define */
293
+ // allow use function before defined as they could be hoisted
294
+ functions: false,
295
+ classes: true,
296
+ variables: true,
297
+
298
+ /* options from @typescript-eslint/no-use-before-define */
299
+ enums: true,
300
+ // confusing option, it will disable `typedefs`
301
+ ignoreTypeReferences: false,
302
+ // tsc allows types to be used before define
303
+ typedefs: false,
304
+ },
305
+ ],
306
+ // use with functional/prefer-readonly-type
307
+ // mark class variables as readonly if it is not mutated
308
+ '@typescript-eslint/prefer-readonly': 'error',
309
+ // make sure functions which return a promise will just return a rejected promise instead of throwing an error
310
+ '@typescript-eslint/promise-function-async': 'error',
311
+ // allow primitive value in template string
312
+ '@typescript-eslint/restrict-template-expressions': [
313
+ 'error',
314
+ {
315
+ allowNumber: true,
316
+ allowBoolean: true,
317
+ allowAny: true, // mistakenly recognize string as any in 4.29.3
318
+ allowNullish: true,
319
+ allowRegExp: true,
320
+ },
321
+ ],
322
+ // avoid missed switch-case by requiring switch-case statements to be exhaustive with union type
323
+ '@typescript-eslint/switch-exhaustiveness-check': 'error',
324
+ // ignore static function as those are not supposed to use `this`
325
+ '@typescript-eslint/unbound-method': [
326
+ 'error',
327
+ { ignoreStatic: true },
328
+ ],
329
+ // do not allow usage of deprecated code
330
+ 'deprecation/deprecation': 'error',
331
+ // use with @typescript-eslint/prefer-readonly
332
+ 'functional/prefer-readonly-type': [
333
+ 'error',
334
+ {
335
+ // sometimes it is easier to mutate, it should be fine to mutate within local scope
336
+ allowLocalMutation: true,
337
+ // don't force library consumer to use readonly type
338
+ allowMutableReturnType: true,
339
+ // allow mutating class variables
340
+ ignoreClass: 'fieldsOnly',
341
+ },
342
+ ],
343
+ // forbid unnecessary callback wrapper
344
+ 'functional/prefer-tacit': 'error',
345
+ 'no-restricted-syntax': [
346
+ 'error',
347
+ {
348
+ // encourage to use JS standard #private over TS private accessibility modifier, but excluding constructor because it cannot be private in JS: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Private_class_fields#description
349
+ selector:
350
+ ':matches(PropertyDefinition, MethodDefinition, TSParameterProperty)[accessibility="private"]:not([kind="constructor"])',
351
+ message:
352
+ 'Use #private instead (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Private_class_fields)',
353
+ },
354
+ ],
355
+ // @typescript-eslint/eslint-plugin suggests to disable it: https://github.com/typescript-eslint/typescript-eslint/blob/2588e9ea55f78352fdd6ae92a306135aabb49a1a/docs/linting/TROUBLESHOOTING.md#i-get-errors-from-the-no-undef-rule-about-global-variables-not-being-defined-even-though-there-are-no-typescript-errors
356
+ // It is disabled in recommended config but re-enabled here to enforce a subset of global variables that supported by both node.js and browsers
357
+ 'no-undef': 'error',
358
+ },
359
+ },
360
+ {
361
+ files: typeScriptTestFileGlobs,
362
+ plugins: {
363
+ '@typescript-eslint': eslintPluginTypescriptEslint,
364
+ jest: eslintPluginJest,
365
+ },
366
+ rules: {
367
+ // doesn't work with jest.fn<void>()
368
+ '@typescript-eslint/no-invalid-void-type': 'off',
369
+ // replace by jest/unbound-method
370
+ '@typescript-eslint/unbound-method': 'off',
371
+ // allow passing an unbound method to `expect` calls
372
+ 'jest/unbound-method': ['error', { ignoreStatic: true }],
373
+ },
374
+ },
375
+ {
376
+ files: typeScriptFileGlobs,
377
+ ...esmConfig,
378
+ },
379
+ ]
380
+ : []),
381
+ ]
382
+ export default baseConfig
@@ -0,0 +1,47 @@
1
+ import restrictedGlobals from 'confusing-browser-globals'
2
+ import eslintPluginCompat from 'eslint-plugin-compat'
3
+ import eslintPluginImport from 'eslint-plugin-import'
4
+ import eslintPluginJestDom from 'eslint-plugin-jest-dom'
5
+ import eslintPluginTestingLibrary from 'eslint-plugin-testing-library'
6
+ import globals from 'globals'
7
+
8
+ import { testFileGlobs } from '../constants.mjs'
9
+
10
+ /** @type {import('eslint').Linter.FlatConfig[]} */
11
+ const browserConfig = [
12
+ {
13
+ languageOptions: {
14
+ globals: {
15
+ ...globals.browser,
16
+ ...globals.webextensions,
17
+ // keep it until webpack has an official way to define env: https://github.com/webpack/webpack/issues/15833
18
+ // @ts-expect-error
19
+ process: 'readonly',
20
+ },
21
+ },
22
+ plugins: {
23
+ compat: eslintPluginCompat,
24
+ import: eslintPluginImport,
25
+ },
26
+ rules: {
27
+ 'compat/compat': 'error',
28
+ // frontend environment doesn't support node.js modules
29
+ 'import/no-nodejs-modules': 'error',
30
+ 'no-restricted-globals': ['error', ...restrictedGlobals],
31
+ },
32
+ },
33
+ {
34
+ files: testFileGlobs,
35
+ plugins: {
36
+ 'jest-dom': eslintPluginJestDom,
37
+ 'testing-library': eslintPluginTestingLibrary,
38
+ },
39
+ rules: {
40
+ ...eslintPluginJestDom.configs['recommended']?.rules,
41
+ ...eslintPluginTestingLibrary.configs['dom']?.rules,
42
+ // allow to use nodejs modules in tests
43
+ 'import/no-nodejs-modules': 'off',
44
+ },
45
+ },
46
+ ]
47
+ export default browserConfig
@@ -0,0 +1,14 @@
1
+ /** @type {readonly import('eslint').Linter.FlatConfig[]} */
2
+ const ignoresConfig = [
3
+ {
4
+ // replace `.eslintignore`
5
+ ignores: [
6
+ '**/.yarn/**',
7
+ '**/build/**',
8
+ '**/coverage/**',
9
+ '**/dist/**',
10
+ '**/node_modules/**',
11
+ ],
12
+ },
13
+ ]
14
+ export default ignoresConfig
package/bases/node.mjs ADDED
@@ -0,0 +1,75 @@
1
+ // @ts-expect-error
2
+ import { isESM } from '@foray1010/common-presets-utils'
3
+ import eslintPluginN from 'eslint-plugin-n'
4
+
5
+ /** @type {import('eslint').Linter.FlatConfig} */
6
+ const cjsConfig = {
7
+ languageOptions: {
8
+ globals: {
9
+ // @ts-expect-error
10
+ __dirname: 'readonly',
11
+ // @ts-expect-error
12
+ __filename: 'readonly',
13
+ },
14
+ },
15
+ }
16
+
17
+ /** @type {import('eslint').Linter.FlatConfig[]} */
18
+ const nodeConfig = [
19
+ {
20
+ plugins: {
21
+ n: eslintPluginN,
22
+ },
23
+ languageOptions: {
24
+ globals: {
25
+ // hack to mute no-undef error, and show n/prefer-global/buffer error instead
26
+ // @ts-expect-error
27
+ Buffer: 'writable',
28
+ // hack to mute no-undef error, and show n/prefer-global/process error instead
29
+ // @ts-expect-error
30
+ process: 'writable',
31
+ },
32
+ },
33
+ rules: {
34
+ // disallow deprecated node APIs
35
+ 'n/no-deprecated-api': 'error',
36
+ // disallow the assignment to `exports`
37
+ 'n/no-exports-assign': 'error',
38
+ // disallow `bin` files that npm ignores
39
+ 'n/no-unpublished-bin': 'error',
40
+ // disallow unsupported Node.js built-in APIs on the specified version
41
+ 'n/no-unsupported-features/node-builtins': 'error',
42
+ // prefer `import { Buffer } from 'node:buffer'` as it is not isomorphic
43
+ 'n/prefer-global/buffer': ['error', 'never'],
44
+ // prefer global `console` to be isomorphic
45
+ 'n/prefer-global/console': ['error', 'always'],
46
+ // prefer `import process from 'node:process'` as it is not isomorphic
47
+ 'n/prefer-global/process': ['error', 'never'],
48
+ // prefer global `TextDecoder` to be isomorphic
49
+ 'n/prefer-global/text-decoder': ['error', 'always'],
50
+ // prefer global `TextEncoder` to be isomorphic
51
+ 'n/prefer-global/text-encoder': ['error', 'always'],
52
+ // prefer global `URL` to be isomorphic
53
+ 'n/prefer-global/url': ['error', 'always'],
54
+ // prefer global `URLSearchParams` to be isomorphic
55
+ 'n/prefer-global/url-search-params': ['error', 'always'],
56
+ // make `process.exit()` expressions the same code path as `throw`
57
+ 'n/process-exit-as-throw': 'error',
58
+ // enforce shebang on the entry bin file
59
+ 'n/shebang': 'error',
60
+ },
61
+ },
62
+ ...(isESM()
63
+ ? []
64
+ : [
65
+ {
66
+ files: ['**/*.js'],
67
+ ...cjsConfig,
68
+ },
69
+ ]),
70
+ {
71
+ files: ['**/*.{cjs,cts}'],
72
+ ...cjsConfig,
73
+ },
74
+ ]
75
+ export default nodeConfig