@w5s/eslint-config 1.0.0-alpha.1 → 1.0.0-alpha.5

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2021 Julien Polo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@w5s/eslint-config",
3
- "version": "1.0.0-alpha.1",
3
+ "version": "1.0.0-alpha.5",
4
4
  "description": "ESLint configuration presets",
5
5
  "keywords": [
6
6
  "eslint",
7
7
  "config",
8
8
  "lint"
9
9
  ],
10
- "homepage": "https://github.com/w5s/project-config/blob/master/packages/eslint-config#readme",
10
+ "homepage": "https://github.com/w5s/project-config/blob/main/packages/eslint-config#readme",
11
11
  "bugs": {
12
12
  "url": "https://github.com/w5s/project-config.git/issues"
13
13
  },
@@ -45,6 +45,7 @@
45
45
  "@babel/plugin-syntax-jsx": "^7.0.0",
46
46
  "@typescript-eslint/eslint-plugin": "^5.0.0",
47
47
  "@typescript-eslint/parser": "^5.0.0",
48
+ "eslint-config-airbnb-base": "^15.0.0",
48
49
  "eslint-config-prettier": "^8.0.0",
49
50
  "eslint-plugin-functional": "^4.2.0",
50
51
  "eslint-plugin-import": "^2.25.0",
@@ -62,8 +63,8 @@
62
63
  "@types/eslint-plugin-prettier": "^3.1.0",
63
64
  "@types/prettier": "2.4.4",
64
65
  "@types/react": "17.0.2",
65
- "@typescript-eslint/parser": "5.10.2",
66
- "eslint": "8.8.0",
66
+ "@typescript-eslint/parser": "5.11.0",
67
+ "eslint": "8.9.0",
67
68
  "eslint-config-prettier": "8.3.0",
68
69
  "eslint-index": "1.5.0",
69
70
  "prettier": "2.5.1",
@@ -71,9 +72,16 @@
71
72
  },
72
73
  "peerDependencies": {
73
74
  "eslint": "5.x || 6.x || 7.x || 8.x",
74
- "prettier": "2.x"
75
+ "prettier": "2.x",
76
+ "typescript": "4.x"
77
+ },
78
+ "peerDependenciesMeta": {
79
+ "typescript": {
80
+ "optional": true
81
+ }
75
82
  },
76
83
  "publishConfig": {
77
84
  "access": "public"
78
- }
85
+ },
86
+ "gitHead": "17d00b3e9ba103fd053aed2c06535d0b1526886a"
79
87
  }
package/rules/_rule.js CHANGED
@@ -7,8 +7,71 @@ const warn = 'warn';
7
7
  /** @type {'off'} */
8
8
  const off = 'off';
9
9
 
10
+ /**
11
+ * @typedef {{
12
+ * env?: Record<string, boolean>,
13
+ * extends?: string[]|string,
14
+ * plugins?: string[]|string,
15
+ * rules?: Record<string, unknown>,
16
+ * settings?: Record<string, unknown>,
17
+ * }} ESLintConfigInit
18
+ */
19
+ /**
20
+ * @typedef {{
21
+ * env: Record<string, boolean>,
22
+ * extends: string[],
23
+ * plugins: string[],
24
+ * rules: Record<string, unknown>,
25
+ * settings: Record<string, unknown>,
26
+ * }} ESLintConfig
27
+ */
28
+
29
+ /**
30
+ * @template T
31
+ * @type {(value: T[]|T|undefined) => T[]} */
32
+ function toArray(value) {
33
+ if (value == null) {
34
+ return [];
35
+ }
36
+ if (Array.isArray(value)) {
37
+ return value;
38
+ }
39
+ return [value];
40
+ }
41
+
42
+ /**
43
+ * @template T
44
+ * @type {(left: T[]|T|undefined, right:T[]|T|undefined) => T[]}
45
+ */
46
+ function concatArray(left, right) {
47
+ return toArray(left).concat(toArray(right));
48
+ }
49
+
50
+ /** @type {(...configs: ESLintConfigInit[]) => ESLintConfig} */
51
+ function concatESConfig(...configs) {
52
+ return configs.reduce(
53
+ (/** @type {ESLintConfig} */ returnValue, /** @type {ESLintConfigInit} */ config) =>
54
+ Object.assign({}, returnValue, config, {
55
+ env: Object.assign({}, returnValue.env, config.env),
56
+ extends: concatArray(returnValue.extends, config.extends),
57
+ plugins: concatArray(returnValue.plugins, config.plugins),
58
+ rules: Object.assign({}, returnValue.rules, config.rules),
59
+ settings: Object.assign({}, returnValue.settings, config.settings),
60
+ }),
61
+ {
62
+ env: {},
63
+ extends: [],
64
+ plugins: [],
65
+ rules: {},
66
+ settings: {},
67
+ }
68
+ );
69
+ }
70
+
10
71
  module.exports = {
72
+ concatESConfig,
11
73
  error,
74
+ // eslint-disable-next-line no-unused-vars
12
75
  fixme: (/** @type {'off'|'warn'|'error'} */ _status) => off,
13
76
  off,
14
77
  warn,
package/rules/base.js CHANGED
@@ -1,464 +1,28 @@
1
- const { off, warn, error } = require('./_rule');
1
+ const { concatESConfig, off } = require('./_rule');
2
2
 
3
- module.exports = {
4
- env: {
5
- es6: true,
6
- },
7
- extends: [require.resolve('./node')], // TODO: remove that extends and provide a standalone configuration
8
- plugins: [],
9
- rules: {
10
- 'accessor-pairs': error,
11
- 'array-bracket-newline': off,
12
- 'array-bracket-spacing': [error, 'never'],
13
- 'array-callback-return': error,
14
- 'array-element-newline': off,
15
- 'arrow-body-style': [error, 'always'],
16
- 'arrow-parens': [error, 'always'],
17
- 'arrow-spacing': [error, { after: true, before: true }],
18
- 'block-scoped-var': error,
19
- 'block-spacing': [error, 'always'],
20
- 'brace-style': [error, '1tbs', { allowSingleLine: false }],
21
- camelcase: off,
22
- 'capitalized-comments': off,
23
- 'class-methods-use-this': off,
24
- 'comma-dangle': [error, 'always-multiline'],
25
- 'comma-spacing': [error, { after: true, before: false }],
26
- 'comma-style': [error, 'last'],
27
- complexity: [error, 20],
28
- 'computed-property-spacing': [error, 'never'],
29
- 'consistent-return': error,
30
- 'consistent-this': [error, 'self'],
31
- 'constructor-super': error,
32
- curly: error,
33
- 'default-case': [error, { commentPattern: '^no default$' }], // require default case in switch statements or ignore by adding `//no default`
34
- 'dot-location': [error, 'property'],
35
- 'dot-notation': error,
36
- 'eol-last': error,
37
- eqeqeq: [error, 'smart'],
38
- 'for-direction': error,
39
- 'func-call-spacing': [error, 'never'],
40
- 'func-name-matching': error,
41
- 'func-names': off,
42
- 'func-style': off,
43
- 'function-paren-newline': [error, 'consistent'],
44
- 'generator-star-spacing': [error, { after: false, before: true }],
45
- 'getter-return': [error, { allowImplicit: true }],
46
- 'guard-for-in': error,
47
- 'id-length': [error, { exceptions: ['t', '$', '_', 'x', 'y', 'z'], max: 50, min: 2, properties: 'never' }],
48
- 'id-match': off,
49
- 'implicit-arrow-linebreak': [error, 'beside'],
50
- indent: [error, 2],
51
- 'init-declarations': off,
52
- 'jsx-quotes': [error, 'prefer-double'],
53
- 'key-spacing': [
54
- error,
55
- {
56
- afterColon: true,
57
- beforeColon: false,
58
- },
59
- ],
60
- 'keyword-spacing': [
61
- error,
62
- {
63
- after: true,
64
- before: true,
65
- },
66
- ],
67
- 'line-comment-position': 0,
68
- 'linebreak-style': [error, 'unix'],
69
- 'lines-around-comment': [
70
- error,
71
- {
72
- allowArrayEnd: true,
73
- allowArrayStart: true,
74
- allowBlockEnd: true,
75
- allowBlockStart: true,
76
- allowObjectEnd: true,
77
- allowObjectStart: true,
78
- beforeBlockComment: true,
79
- beforeLineComment: true,
80
- },
81
- ],
82
- 'lines-around-directive': [error, 'always'],
83
- 'lines-between-class-members': [error, 'always', { exceptAfterSingleLine: true }],
84
- 'max-len': [
85
- warn,
86
- {
87
- code: 160,
88
- },
89
- ],
90
- 'max-nested-callbacks': [warn, { max: 5 }],
91
- 'max-statements-per-line': [
92
- error,
93
- {
94
- max: 1,
95
- },
96
- ],
97
- 'multiline-comment-style': off,
98
- 'multiline-ternary': off,
99
- 'new-cap': [
100
- off,
101
- {
102
- capIsNew: false,
103
- newIsCap: true,
104
- },
105
- ],
106
- 'new-parens': error,
107
- 'newline-after-var': off,
108
- 'newline-before-return': error,
109
- 'newline-per-chained-call': off,
110
- 'no-alert': error,
111
- 'no-array-constructor': error,
112
- 'no-async-promise-executor': error,
113
- 'no-await-in-loop': error,
114
- 'no-caller': error,
115
- 'no-case-declarations': error,
116
- 'no-catch-shadow': error,
117
- 'no-class-assign': error,
118
- 'no-compare-neg-zero': error,
119
- 'no-cond-assign': error,
120
- 'no-confusing-arrow': error,
121
- 'no-console': error,
122
- 'no-const-assign': error,
123
- 'no-constant-condition': warn,
124
- 'no-continue': off,
125
- 'no-control-regex': error,
126
- 'no-debugger': error,
127
- 'no-delete-var': error,
128
- 'no-div-regex': error,
129
- 'no-dupe-args': error,
130
- 'no-dupe-class-members': error,
131
- 'no-dupe-else-if': error,
132
- 'no-dupe-keys': error,
133
- 'no-duplicate-case': error,
134
- 'no-duplicate-imports': off,
135
- 'no-else-return': [error, { allowElseIf: false }],
136
- 'no-empty': error,
137
- 'no-empty-character-class': error,
138
- 'no-empty-function': [error, { allow: ['arrowFunctions', 'functions', 'methods'] }],
139
- 'no-empty-pattern': error,
140
- 'no-eq-null': off,
141
- 'no-eval': error,
142
- 'no-ex-assign': error,
143
- 'no-extend-native': error,
144
- 'no-extra-bind': error,
145
- 'no-extra-boolean-cast': error,
146
- 'no-extra-parens': error,
147
- 'no-extra-semi': error,
148
- 'no-fallthrough': error,
149
- 'no-floating-decimal': error,
150
- 'no-func-assign': error,
151
- 'no-global-assign': error,
152
- 'no-implicit-coercion': error,
153
- 'no-implicit-globals': off,
154
- 'no-implied-eval': error,
155
- 'no-import-assign': error,
156
- 'no-inline-comments': off,
157
- 'no-inner-declarations': error,
158
- 'no-invalid-regexp': error,
159
- 'no-invalid-this': off,
160
- 'no-irregular-whitespace': error,
161
- 'no-iterator': error,
162
- 'no-label-var': error,
163
- 'no-labels': error,
164
- 'no-lone-blocks': error,
165
- 'no-lonely-if': error,
166
- 'no-loop-func': error,
167
- 'no-loss-of-precision': error,
168
- 'no-magic-numbers': off,
169
- 'no-misleading-character-class': error,
170
- 'no-mixed-spaces-and-tabs': error,
171
- 'no-multi-spaces': [
172
- error,
173
- {
174
- ignoreEOLComments: false,
175
- },
176
- ],
177
- 'no-multi-str': error,
178
- 'no-multiple-empty-lines': [
179
- error,
180
- {
181
- max: 1,
182
- maxBOF: 0,
183
- maxEOF: 1,
184
- },
185
- ],
186
- 'no-native-reassign': error,
187
- 'no-negated-condition': off,
188
- 'no-negated-in-lhs': error,
189
- 'no-nested-ternary': off,
190
- 'no-new': error,
191
- 'no-new-func': error,
192
- 'no-new-object': error,
193
- 'no-new-require': error,
194
- 'no-new-symbol': error,
195
- 'no-new-wrappers': error,
196
- 'no-obj-calls': error,
197
- 'no-octal': error,
198
- 'no-octal-escape': error,
199
- 'no-param-reassign': [
200
- error,
201
- {
202
- props: false,
203
- },
204
- ],
205
- 'no-plusplus': error,
206
- 'no-promise-executor-return': error,
207
- 'no-proto': error,
208
- 'no-prototype-builtins': error,
209
- 'no-redeclare': [
210
- error,
211
- {
212
- builtinGlobals: true,
213
- },
214
- ],
215
- 'no-regex-spaces': error,
216
- 'no-restricted-globals': off,
217
- 'no-restricted-properties': [
218
- error,
219
- {
220
- message: 'arguments.callee is deprecated',
221
- object: 'arguments',
222
- property: 'callee',
223
- },
224
- {
225
- message: 'Please use Number.isFinite instead',
226
- object: 'global',
227
- property: 'isFinite',
228
- },
229
- {
230
- message: 'Please use Number.isFinite instead',
231
- object: 'self',
232
- property: 'isFinite',
233
- },
234
- {
235
- message: 'Please use Number.isFinite instead',
236
- object: 'window',
237
- property: 'isFinite',
238
- },
239
- {
240
- message: 'Please use Number.isNaN instead',
241
- object: 'global',
242
- property: 'isNaN',
243
- },
244
- {
245
- message: 'Please use Number.isNaN instead',
246
- object: 'self',
247
- property: 'isNaN',
248
- },
249
- {
250
- message: 'Please use Number.isNaN instead',
251
- object: 'window',
252
- property: 'isNaN',
253
- },
254
- {
255
- message: 'Please use Object.defineProperty instead.',
256
- property: '__defineGetter__',
257
- },
258
- {
259
- message: 'Please use Object.defineProperty instead.',
260
- property: '__defineSetter__',
261
- },
262
- {
263
- message: 'Use the exponentiation operator (**) instead.',
264
- object: 'Math',
265
- property: 'pow',
266
- },
267
- ],
268
- 'no-restricted-syntax': [
269
- error,
270
- {
271
- message:
272
- 'for..in loops iterate over the entire prototype chain, which is virtually never what you want. Use Object.{keys,values,entries}, and iterate over the resulting array.',
273
- selector: 'ForInStatement',
274
- },
275
- {
276
- message: 'Labels are a form of GOTO; using them makes code confusing and hard to maintain and understand.',
277
- selector: 'LabeledStatement',
278
- },
279
- {
280
- message: '`with` is disallowed in strict mode because it makes code impossible to predict and optimize.',
281
- selector: 'WithStatement',
282
- },
283
- ],
284
- 'no-return-assign': error,
285
- 'no-return-await': error,
286
- 'no-script-url': error,
287
- 'no-self-assign': error,
288
- 'no-self-compare': error,
289
- 'no-sequences': error,
290
- 'no-setter-return': error,
291
- 'no-shadow': [
292
- error,
293
- {
294
- builtinGlobals: false,
295
- hoist: 'all',
296
- },
297
- ],
298
- 'no-shadow-restricted-names': error,
299
- 'no-spaced-func': error,
300
- 'no-sparse-arrays': error,
301
- 'no-sync': off,
302
- 'no-tabs': error,
303
- 'no-template-curly-in-string': error,
304
- 'no-ternary': off,
305
- 'no-this-before-super': error,
306
- 'no-throw-literal': error,
307
- 'no-trailing-spaces': error,
308
- 'no-undef': error,
309
- 'no-undef-init': error,
310
- 'no-undefined': off,
311
- 'no-underscore-dangle': off,
312
- 'no-unexpected-multiline': error,
313
- 'no-unmodified-loop-condition': error,
314
- 'no-unneeded-ternary': off, // error,
315
- 'no-unreachable': error,
316
- 'no-unreachable-loop': error,
317
- 'no-unsafe-finally': error,
318
- 'no-unsafe-negation': error,
319
- 'no-unsafe-optional-chaining': [error, { disallowArithmeticOperators: true }],
320
- 'no-unused-expressions': [
321
- error,
322
- {
323
- allowShortCircuit: false,
324
- allowTaggedTemplates: true,
325
- allowTernary: false,
326
- },
327
- ],
328
- 'no-unused-vars': [
329
- error,
330
- {
331
- args: 'none',
332
- ignoreRestSiblings: true,
333
- vars: 'all',
334
- },
335
- ],
336
- 'no-use-before-define': [
337
- error,
338
- {
339
- classes: false,
340
- functions: false,
341
- variables: false,
342
- },
343
- ],
344
- 'no-useless-backreference': error,
345
- 'no-useless-call': error,
346
- 'no-useless-catch': error,
347
- 'no-useless-computed-key': error,
348
- 'no-useless-concat': error,
349
- 'no-useless-constructor': error,
350
- 'no-useless-escape': error,
351
- 'no-useless-rename': [
352
- error,
353
- {
354
- ignoreDestructuring: false,
355
- ignoreExport: false,
356
- ignoreImport: false,
357
- },
358
- ],
359
- 'no-useless-return': error,
360
- 'no-var': error,
361
- 'no-void': error,
362
- 'no-warning-comments': [
363
- off,
364
- {
365
- location: 'start',
366
- terms: ['todo', '@todo'],
367
- },
368
- ],
369
- 'no-whitespace-before-property': error,
370
- 'no-with': error,
371
- 'nonblock-statement-body-position': [error, 'below'],
372
- 'object-curly-spacing': [off, 'never'],
373
- 'object-property-newline': [
374
- error,
375
- {
376
- allowMultiplePropertiesPerLine: false,
377
- },
378
- ],
379
- 'object-shorthand': [error, 'always'],
380
- 'one-var': [error, 'never'],
381
- 'one-var-declaration-per-line': error,
382
- 'operator-assignment': [error, 'always'],
383
- 'operator-linebreak': [error, 'after'],
384
- 'padded-blocks': [error, 'never'],
385
- 'padding-line-between-statements': off,
386
- 'prefer-arrow-callback': error,
387
- 'prefer-const': error,
388
- 'prefer-destructuring': off,
389
- 'prefer-named-capture-group': off,
390
- 'prefer-numeric-literals': error,
391
- 'prefer-promise-reject-errors': error,
392
- 'prefer-reflect': off,
393
- 'prefer-rest-params': error,
394
- 'prefer-spread': error,
395
- 'prefer-template': error,
396
- 'quote-props': [error, 'as-needed'],
397
- quotes: [error, 'single'],
398
- radix: error,
399
- 'require-await': off, // https://github.com/airbnb/javascript/issues/2013
400
- 'require-jsdoc': off,
401
- 'require-yield': error,
402
- semi: [error, 'always'],
403
- 'semi-spacing': [
404
- error,
405
- {
406
- after: true,
407
- before: false,
408
- },
409
- ],
410
- 'semi-style': [error, 'last'],
411
- 'sort-keys': off /* [
412
- error,
413
- 'asc',
414
- {
415
- caseSensitive: false,
416
- natural: true
417
- }
418
- ], */,
419
- 'sort-vars': error,
420
- 'space-before-blocks': [error, 'always'],
421
- 'space-before-function-paren': [error, 'always'],
422
- 'space-in-parens': [error, 'never'],
423
- 'space-infix-ops': error,
424
- 'space-unary-ops': [
425
- error,
426
- {
427
- nonwords: false,
428
- words: true,
429
- },
430
- ],
431
- 'spaced-comment': [
432
- error,
433
- 'always',
434
- {
435
- block: {
436
- balanced: true,
437
- exceptions: ['*'],
438
- markers: ['*package', '!', ',', ':', '::', 'flow-include'],
439
- },
440
- line: {
441
- markers: ['*package', '!', '/', ',', '='],
442
- },
443
- },
444
- ],
445
- strict: [error, 'never'],
446
- 'switch-colon-spacing': [
447
- error,
448
- {
449
- after: true,
450
- before: false,
451
- },
452
- ],
453
- 'symbol-description': error,
454
- 'template-tag-spacing': [error, 'never'],
455
- 'unicode-bom': [error, 'never'],
456
- 'use-isnan': error,
457
- 'valid-jsdoc': off,
458
- 'valid-typeof': [error, { requireStringLiterals: true }],
459
- 'vars-on-top': error,
460
- 'wrap-iife': [error, 'inside'],
461
- 'wrap-regex': off,
462
- yoda: off,
463
- },
464
- };
3
+ module.exports = concatESConfig(
4
+ // @ts-ignore
5
+ require('eslint-config-airbnb-base/rules/best-practices'),
6
+ // @ts-ignore
7
+ require('eslint-config-airbnb-base/rules/errors'),
8
+ // @ts-ignore
9
+ require('eslint-config-airbnb-base/rules/es6'),
10
+ /** {@link ./import.js} */
11
+ // require('eslint-config-airbnb-base/rules/imports'),
12
+ // @ts-ignore
13
+ require('eslint-config-airbnb-base/rules/node'),
14
+ // @ts-ignore
15
+ require('eslint-config-airbnb-base/rules/strict'),
16
+ // @ts-ignore
17
+ require('eslint-config-airbnb-base/rules/style'),
18
+ // @ts-ignore
19
+ require('eslint-config-airbnb-base/rules/variables'),
20
+
21
+ // overrides
22
+ {
23
+ rules: {
24
+ // Often useful in jsx
25
+ 'no-nested-ternary': off,
26
+ },
27
+ }
28
+ );
package/rules/import.js CHANGED
@@ -1,118 +1,23 @@
1
- const { off, warn, error } = require('./_rule');
1
+ const { off, warn, error, concatESConfig, fixme } = require('./_rule');
2
2
 
3
3
  /**
4
4
  * @see https://github.com/typescript-eslint/typescript-eslint/blob/master/docs/getting-started/linting/FAQ.md#eslint-plugin-import
5
5
  * @param {string} _status
6
6
  */
7
7
  // eslint-disable-next-line no-unused-vars
8
- const performanceIssue = (_status) => {
9
- return off;
10
- };
8
+ const performanceIssue = (_status) => off;
11
9
 
12
- module.exports = {
13
- plugins: ['import'],
14
- rules: {
15
- 'import/default': error,
16
- 'import/export': error,
17
- 'import/exports-last': off,
18
- 'import/extensions': [
19
- error,
20
- 'ignorePackages',
21
- {
22
- js: 'never',
23
- json: 'always',
24
- jsx: 'never',
25
- mjs: 'never',
26
- ts: 'never',
27
- tsx: 'never',
28
- },
29
- ],
30
- 'import/first': [error, 'absolute-first'],
31
- 'import/group-exports': off,
32
- 'import/max-dependencies': [
33
- off,
34
- {
35
- max: 10,
36
- },
37
- ],
38
- 'import/named': error,
39
- 'import/namespace': error,
40
- 'import/newline-after-import': error,
41
- 'import/no-absolute-path': error,
42
- 'import/no-amd': error,
43
- 'import/no-anonymous-default-export': off,
44
- 'import/no-commonjs': off, // Still used widely by nodejs programs
45
- 'import/no-cycle': [error, { maxDepth: Number.POSITIVE_INFINITY }], // Elm, ReasonML forbids circular dependency
46
- 'import/no-default-export': off,
47
- 'import/no-deprecated': performanceIssue(warn),
48
- 'import/no-duplicates': error,
49
- 'import/no-dynamic-require': error,
50
- 'import/no-extraneous-dependencies': [
51
- error,
52
- {
53
- // https://github.com/airbnb/javascript/blob/1eadb93e377da1e56c3f91f26610e5d0a00738a9/packages/eslint-config-airbnb-base/rules/imports.js#L71
54
- devDependencies: [
55
- 'test/**', // tape, common npm pattern
56
- 'tests/**', // also common npm pattern
57
- 'spec/**', // mocha, rspec-like pattern
58
- '**/__tests__/**', // jest pattern
59
- '**/__mocks__/**', // jest pattern
60
- 'test.{js,jsx,ts,tsx}', // repos with a single test file
61
- 'test-*.{js,jsx,ts,tsx}', // repos with multiple top-level test files
62
- '**/*{.,_}{test,spec}.{js,jsx,ts,tsx}', // tests where the extension or filename suffix denotes that it is a test
63
- '**/jest.config.{js,ts}', // jest config
64
- '**/jest.setup.{js,ts}', // jest setup
65
- '**/vue.config.{js,ts}', // vue-cli config
66
- '**/webpack.config.js', // webpack config
67
- '**/webpack.config.*.js', // webpack config
68
- '**/rollup.config.js', // rollup config
69
- '**/rollup.config.*.js', // rollup config
70
- '**/gulpfile.js', // gulp config
71
- '**/gulpfile.*.js', // gulp config
72
- '**/Gruntfile{,.js}', // grunt config
73
- '**/protractor.conf.js', // protractor config
74
- '**/protractor.conf.*.js', // protractor config
75
- '**/karma.conf.js', // karma config
76
- '**/.eslintrc.js', // eslint config,
77
- '**/markdown.config.js', // markdown magic config,
78
- ],
79
- optionalDependencies: false,
80
- },
81
- ],
82
- 'import/no-internal-modules': off,
83
- 'import/no-mutable-exports': error,
84
- 'import/no-named-as-default': performanceIssue(error),
85
- 'import/no-named-as-default-member': error,
86
- 'import/no-named-default': error,
87
- 'import/no-named-export': off,
88
- 'import/no-namespace': off,
89
- 'import/no-nodejs-modules': off,
90
- 'import/no-relative-parent-imports': off,
91
- 'import/no-restricted-paths': off,
92
- 'import/no-self-import': error,
93
- 'import/no-unassigned-import': off,
94
- 'import/no-unresolved': [error, { caseSensitive: true, commonjs: true }],
95
- 'import/no-unused-modules': [performanceIssue(error), { unusedExports: true }],
96
- 'import/no-useless-path-segments': error,
97
- 'import/no-webpack-loader-syntax': error,
98
- 'import/order': [
99
- error,
100
- {
101
- groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'],
102
- 'newlines-between': 'never',
103
- },
104
- ],
105
- 'import/prefer-default-export': off,
106
- 'import/unambiguous': off, // Disable because proposal still in progress
107
- },
108
- settings: {
109
- 'import/core-modules': [],
110
- 'import/extensions': ['.js', '.mjs', '.jsx'],
111
- 'import/ignore': ['node_modules', '\\.(coffee|scss|css|less|hbs|svg|json)$'],
112
- 'import/resolver': {
113
- node: {
114
- extensions: ['.mjs', '.js', '.json'],
115
- },
10
+ module.exports = concatESConfig(
11
+ // @ts-ignore
12
+ require('eslint-config-airbnb-base/rules/imports'),
13
+ // Overrides
14
+ {
15
+ rules: {
16
+ 'import/no-deprecated': performanceIssue(warn),
17
+ 'import/no-named-as-default': performanceIssue(error),
18
+ 'import/no-unused-modules': performanceIssue(error),
19
+ 'import/prefer-default-export': off, // Not aligned, default export does not bring sufficient semantic
20
+ 'import/unambiguous': fixme(off), // Disable because proposal still in progress
116
21
  },
117
- },
118
- };
22
+ }
23
+ );
package/rules/jest.js CHANGED
@@ -1,25 +1,13 @@
1
- const { off, error } = require('./_rule');
1
+ const { off, error, concatESConfig } = require('./_rule');
2
2
 
3
- /**
4
- * Typescript config is loose because we often have "hack", "mock" in tests
5
- */
6
- const tsDisabled = {
7
- '@typescript-eslint/no-unsafe-assignment': off,
8
- '@typescript-eslint/no-unsafe-call': off,
9
- '@typescript-eslint/no-unsafe-member-access': off,
10
- '@typescript-eslint/no-unsafe-return': off,
11
- '@typescript-eslint/restrict-template-expressions': off,
12
- '@typescript-eslint/unbound-method': off,
13
- };
14
-
15
- module.exports = {
16
- env: {
17
- jest: true,
18
- },
19
- extends: ['plugin:jest/recommended'],
20
- plugins: ['jest'],
21
- rules: Object.assign(
22
- {
3
+ module.exports = concatESConfig(
4
+ {
5
+ env: {
6
+ jest: true,
7
+ },
8
+ extends: ['plugin:jest/recommended'],
9
+ plugins: ['jest'],
10
+ rules: {
23
11
  'jest/expect-expect': off, // Disabled because it does not handle functions that does the expect
24
12
  'jest/no-alias-methods': error,
25
13
  'jest/no-commented-out-tests': error,
@@ -41,6 +29,18 @@ module.exports = {
41
29
  'jest/valid-expect': error,
42
30
  'jest/valid-title': [error, { ignoreTypeOfDescribeName: true }],
43
31
  },
44
- tsDisabled
45
- ),
46
- };
32
+ },
33
+ /**
34
+ * Typescript config is set to be less strict because we often have "hack", "mock" in tests
35
+ */
36
+ {
37
+ rules: {
38
+ '@typescript-eslint/no-unsafe-assignment': off,
39
+ '@typescript-eslint/no-unsafe-call': off,
40
+ '@typescript-eslint/no-unsafe-member-access': off,
41
+ '@typescript-eslint/no-unsafe-return': off,
42
+ '@typescript-eslint/restrict-template-expressions': off,
43
+ '@typescript-eslint/unbound-method': off,
44
+ },
45
+ }
46
+ );
package/rules/prettier.js CHANGED
@@ -1,10 +1,8 @@
1
- const { error, off } = require('./_rule');
1
+ const { error } = require('./_rule');
2
2
 
3
3
  module.exports = {
4
4
  plugins: ['prettier'],
5
5
  rules: {
6
- 'arrow-body-style': off,
7
- 'prefer-arrow-callback': off,
8
6
  'prettier/prettier': [
9
7
  error,
10
8
  {
@@ -1,53 +1,24 @@
1
- const { fixme, off, warn, error } = require('./_rule');
2
- const { rules: baseRules } = require('./base');
1
+ // Inspired by https://github.com/iamturns/eslint-config-airbnb-typescript/blob/master/lib/shared.js
3
2
 
4
- const duplicateTSC = off; // = "off because tsc already checks that"
3
+ const { fixme, off, warn, error, concatESConfig } = require('./_rule');
4
+ const { rules: _baseRules } = require('./base');
5
+ const { rules: _baseImportRules } = require('./import');
6
+
7
+ // Fix Hack : TS pluging seems to modify the rules
8
+ const deepClone = (/** @type {Record<string, unknown>} */ anyValue) => JSON.parse(JSON.stringify(anyValue));
9
+ const baseRules = deepClone(_baseRules);
10
+ const baseImportRules = deepClone(_baseImportRules);
5
11
 
6
- // https://github.com/typescript-eslint/typescript-eslint/blob/master/docs/getting-started/linting/FAQ.md#eslint-plugin-import
7
- const ruleDisabled = {
8
- camelcase: off,
9
- 'constructor-super': off,
10
- 'dot-notation': off,
11
- 'getter-return': off,
12
- 'import/default': duplicateTSC,
13
- 'import/export': fixme(error), // https://github.com/benmosher/eslint-plugin-import/issues/1964
14
- 'import/named': duplicateTSC,
15
- 'import/namespace': duplicateTSC,
16
- 'import/no-named-as-default-member': duplicateTSC,
17
- 'import/no-unresolved': duplicateTSC,
18
- 'no-array-constructor': off,
19
- 'no-const-assign': off,
20
- 'no-dupe-args': off,
21
- 'no-dupe-class-members': off,
22
- 'no-dupe-keys': off,
23
- 'no-empty-function': off,
24
- 'no-func-assign': off,
25
- 'no-import-assign': off,
26
- 'no-inner-declarations': fixme(error), // https://github.com/typescript-eslint/typescript-eslint/issues/239
27
- 'no-new-symbol': off,
28
- 'no-obj-calls': off,
29
- 'no-redeclare': off,
30
- 'no-setter-return': off,
31
- 'no-shadow': off, // https://github.com/typescript-eslint/typescript-eslint/issues/2483
32
- 'no-this-before-super': off,
33
- 'no-undef': off,
34
- 'no-unreachable': off,
35
- 'no-unsafe-negation': off,
36
- 'no-unused-vars': off,
37
- 'no-use-before-define': off,
38
- 'no-useless-constructor': off,
39
- 'no-var': error,
40
- 'prefer-const': error,
41
- 'prefer-rest-params': error,
42
- 'prefer-spread': error,
43
- 'valid-typeof': off,
44
- };
12
+ const duplicateTSC = off; // = "off because tsc already checks that"
45
13
 
46
- module.exports = {
47
- extends: ['plugin:@typescript-eslint/recommended-requiring-type-checking'],
48
- plugins: ['@typescript-eslint', 'import'],
49
- rules: Object.assign(
50
- {
14
+ module.exports = concatESConfig(
15
+ /**
16
+ * Plugin rules
17
+ */
18
+ {
19
+ extends: ['plugin:@typescript-eslint/recommended-requiring-type-checking'],
20
+ plugins: ['@typescript-eslint', 'import'],
21
+ rules: {
51
22
  '@typescript-eslint/adjacent-overload-signatures': error,
52
23
  '@typescript-eslint/ban-ts-comment': [
53
24
  warn,
@@ -60,13 +31,29 @@ module.exports = {
60
31
  },
61
32
  ],
62
33
  '@typescript-eslint/ban-types': error,
34
+ '@typescript-eslint/brace-style': baseRules['brace-style'],
35
+ '@typescript-eslint/comma-dangle': [
36
+ baseRules['comma-dangle'][0],
37
+ {
38
+ ...baseRules['comma-dangle'][1],
39
+ enums: baseRules['comma-dangle'][1].arrays,
40
+ generics: baseRules['comma-dangle'][1].arrays,
41
+ tuples: baseRules['comma-dangle'][1].arrays,
42
+ },
43
+ ],
44
+ '@typescript-eslint/comma-spacing': baseRules['comma-spacing'],
63
45
  '@typescript-eslint/consistent-type-assertions': [
64
46
  error,
65
47
  { assertionStyle: 'as', objectLiteralTypeAssertions: 'never' },
66
48
  ],
49
+ '@typescript-eslint/default-param-last': baseRules['default-param-last'],
67
50
  '@typescript-eslint/dot-notation': baseRules['dot-notation'],
68
51
  '@typescript-eslint/explicit-function-return-type': off,
69
52
  '@typescript-eslint/explicit-module-boundary-types': off,
53
+ '@typescript-eslint/func-call-spacing': baseRules['func-call-spacing'],
54
+ '@typescript-eslint/indent': baseRules.indent,
55
+ '@typescript-eslint/keyword-spacing': baseRules['keyword-spacing'],
56
+ '@typescript-eslint/lines-between-class-members': baseRules['lines-between-class-members'],
70
57
  '@typescript-eslint/member-delimiter-style': error,
71
58
  '@typescript-eslint/naming-convention': [
72
59
  error,
@@ -93,28 +80,43 @@ module.exports = {
93
80
  selector: 'typeLike',
94
81
  },
95
82
  ],
96
- '@typescript-eslint/no-array-constructor': error,
83
+ '@typescript-eslint/no-array-constructor': baseRules['no-array-constructor'],
97
84
  '@typescript-eslint/no-base-to-string': error,
85
+ '@typescript-eslint/no-dupe-class-members': baseRules['no-dupe-class-members'],
98
86
  '@typescript-eslint/no-empty-function': baseRules['no-empty-function'],
99
87
  '@typescript-eslint/no-empty-interface': [error, { allowSingleExtends: true }],
100
88
  '@typescript-eslint/no-explicit-any': off, // if any is explicit then it's wanted
89
+ '@typescript-eslint/no-extra-parens': baseRules['no-extra-parens'],
90
+ '@typescript-eslint/no-extra-semi': baseRules['no-extra-semi'],
101
91
  '@typescript-eslint/no-implicit-any-catch': error,
102
92
  '@typescript-eslint/no-inferrable-types': error,
93
+ '@typescript-eslint/no-loop-func': baseRules['no-loop-func'],
94
+ '@typescript-eslint/no-loss-of-precision': baseRules['no-loss-of-precision'],
95
+ '@typescript-eslint/no-magic-numbers': baseRules['no-magic-numbers'],
103
96
  '@typescript-eslint/no-misused-new': error,
104
97
  '@typescript-eslint/no-namespace': off, // We don't agree with community, namespaces are great and not deprecated
105
98
  '@typescript-eslint/no-non-null-assertion': error,
106
- '@typescript-eslint/no-redeclare': fixme(error /* baseRules['no-redeclare'] */), // Error level so it is strongly discouraged
99
+ '@typescript-eslint/no-redeclare': fixme(baseRules['no-redeclare']),
107
100
  '@typescript-eslint/no-require-imports': error,
108
- '@typescript-eslint/no-shadow': baseRules['no-shadow'], // Does not allow to declare type and const with same name
101
+ '@typescript-eslint/no-shadow': baseRules['no-shadow'],
109
102
  '@typescript-eslint/no-this-alias': error,
103
+ '@typescript-eslint/no-throw-literal': baseRules['no-throw-literal'],
110
104
  '@typescript-eslint/no-unnecessary-condition': error,
111
105
  '@typescript-eslint/no-unsafe-argument': error,
106
+ '@typescript-eslint/no-unused-expressions': baseRules['no-unused-expressions'],
112
107
  '@typescript-eslint/no-unused-vars': baseRules['no-unused-vars'],
113
108
  '@typescript-eslint/no-use-before-define': baseRules['no-use-before-define'],
114
109
  '@typescript-eslint/no-useless-constructor': baseRules['no-useless-constructor'],
115
110
  '@typescript-eslint/no-var-requires': error,
111
+ '@typescript-eslint/object-curly-spacing': baseRules['object-curly-spacing'],
116
112
  '@typescript-eslint/prefer-namespace-keyword': error,
117
113
  '@typescript-eslint/prefer-reduce-type-parameter': error,
114
+ '@typescript-eslint/quotes': baseRules.quotes,
115
+ '@typescript-eslint/require-await': baseRules['require-await'],
116
+ '@typescript-eslint/return-await': baseRules['no-return-await'],
117
+ '@typescript-eslint/semi': baseRules.semi,
118
+ '@typescript-eslint/space-before-function-paren': baseRules['space-before-function-paren'],
119
+ '@typescript-eslint/space-infix-ops': baseRules['space-infix-ops'],
118
120
  '@typescript-eslint/strict-boolean-expressions': [
119
121
  error,
120
122
  {
@@ -127,6 +129,106 @@ module.exports = {
127
129
  '@typescript-eslint/triple-slash-reference': error,
128
130
  '@typescript-eslint/type-annotation-spacing': error,
129
131
  },
130
- ruleDisabled
131
- ),
132
- };
132
+ },
133
+ /**
134
+ * Import overrides
135
+ */
136
+ {
137
+ rules: {
138
+ 'import/extensions': [
139
+ baseImportRules['import/extensions'][0],
140
+ baseImportRules['import/extensions'][1],
141
+ {
142
+ ...baseImportRules['import/extensions'][2],
143
+ ts: 'never',
144
+ tsx: 'never',
145
+ },
146
+ ],
147
+ 'import/no-extraneous-dependencies': [
148
+ baseImportRules['import/no-extraneous-dependencies'][0],
149
+ {
150
+ ...baseImportRules['import/no-extraneous-dependencies'][1],
151
+ devDependencies: baseImportRules['import/no-extraneous-dependencies'][1].devDependencies.reduce(
152
+ (/** @type {string[]} */ result, /** @type {string} */ devDep) => {
153
+ const toAppend = [devDep];
154
+ const devDepWithTs = devDep.replace(/\bjs(x?)\b/g, 'ts$1');
155
+ if (devDepWithTs !== devDep) {
156
+ toAppend.push(devDepWithTs);
157
+ }
158
+ return [...result, ...toAppend];
159
+ },
160
+ []
161
+ ),
162
+ },
163
+ ],
164
+ },
165
+ },
166
+ /**
167
+ * Disabled rules
168
+ */
169
+ {
170
+ // https://github.com/typescript-eslint/typescript-eslint/blob/master/docs/getting-started/linting/FAQ.md#eslint-plugin-import
171
+ rules: {
172
+ 'brace-style': off,
173
+ camelcase: off,
174
+ 'comma-dangle': off,
175
+ 'comma-spacing': off,
176
+ 'constructor-super': off,
177
+ 'default-param-last': off,
178
+ 'dot-notation': off,
179
+ 'func-call-spacing': off,
180
+ 'getter-return': off,
181
+ 'import/default': duplicateTSC,
182
+ 'import/export': fixme(error), // https://github.com/benmosher/eslint-plugin-import/issues/1964
183
+ 'import/named': duplicateTSC,
184
+ 'import/namespace': duplicateTSC,
185
+ 'import/no-named-as-default-member': duplicateTSC,
186
+ 'import/no-unresolved': duplicateTSC,
187
+ indent: off,
188
+ 'keyword-spacing': off,
189
+ 'lines-between-class-members': off,
190
+ 'no-array-constructor': off,
191
+ 'no-const-assign': off,
192
+ 'no-dupe-args': off,
193
+ 'no-dupe-class-members': off,
194
+ 'no-dupe-keys': off,
195
+ 'no-empty-function': off,
196
+ 'no-extra-parens': off,
197
+ 'no-extra-semi': off,
198
+ 'no-func-assign': off,
199
+ 'no-implied-eval': off,
200
+ 'no-import-assign': off,
201
+ 'no-inner-declarations': fixme(error), // https://github.com/typescript-eslint/typescript-eslint/issues/239
202
+ 'no-loop-func': off,
203
+ 'no-loss-of-precision': off,
204
+ 'no-magic-numbers': off,
205
+ 'no-new-func': off,
206
+ 'no-new-symbol': off,
207
+ 'no-obj-calls': off,
208
+ 'no-redeclare': off,
209
+ 'no-return-await': off,
210
+ 'no-setter-return': off,
211
+ 'no-shadow': off,
212
+ 'no-this-before-super': off,
213
+ 'no-throw-literal': off,
214
+ 'no-undef': off,
215
+ 'no-unreachable': off,
216
+ 'no-unsafe-negation': off,
217
+ 'no-unused-expression': off,
218
+ 'no-unused-vars': off,
219
+ 'no-use-before-define': off,
220
+ 'no-useless-constructor': off,
221
+ 'no-var': error,
222
+ 'object-curly-spacing': off,
223
+ 'prefer-const': error,
224
+ 'prefer-rest-params': error,
225
+ 'prefer-spread': error,
226
+ quotes: off,
227
+ 'require-await': off,
228
+ semi: off,
229
+ 'space-before-function-paren': off,
230
+ 'space-infix-ops': off,
231
+ 'valid-typeof': off,
232
+ },
233
+ }
234
+ );
package/rules/unicorn.js CHANGED
@@ -1,18 +1,10 @@
1
- const { off, warn, error } = require('./_rule');
1
+ const { off, warn, error, concatESConfig } = require('./_rule');
2
2
 
3
- const unsafeRules = {
4
- 'unicorn/consistent-destructuring': off,
5
- 'unicorn/no-array-for-each': off, // This rule could change browser compatibility
6
- 'unicorn/no-object-as-default-parameter': off,
7
- 'unicorn/prefer-default-parameters': off,
8
- 'unicorn/prevent-abbreviations': off, // This rule is so dangerous : it potentially break code while fixing in many cases !!
9
- };
10
-
11
- module.exports = {
12
- extends: ['plugin:unicorn/recommended'],
13
- plugins: ['unicorn'],
14
- rules: Object.assign(
15
- {
3
+ module.exports = concatESConfig(
4
+ {
5
+ extends: ['plugin:unicorn/recommended'],
6
+ plugins: ['unicorn'],
7
+ rules: {
16
8
  'unicode-bom': [error, 'never'],
17
9
  'unicorn/better-regex': error,
18
10
  'unicorn/catch-error-name': [error, { name: error }],
@@ -53,6 +45,14 @@ module.exports = {
53
45
  'unicorn/prefer-type-error': error,
54
46
  'unicorn/throw-new-error': error,
55
47
  },
56
- unsafeRules
57
- ),
58
- };
48
+ },
49
+ {
50
+ rules: {
51
+ 'unicorn/consistent-destructuring': off,
52
+ 'unicorn/no-array-for-each': off, // This rule could change browser compatibility
53
+ 'unicorn/no-object-as-default-parameter': off,
54
+ 'unicorn/prefer-default-parameters': off,
55
+ 'unicorn/prevent-abbreviations': off, // This rule is so dangerous : it potentially break code while fixing in many cases !!
56
+ },
57
+ }
58
+ );
package/ts.js CHANGED
@@ -14,4 +14,23 @@ module.exports = {
14
14
  parserOptions: {
15
15
  sourceType: 'module',
16
16
  },
17
+ settings: {
18
+ // Append 'ts' extensions to Airbnb 'import/extensions' setting
19
+ 'import/extensions': ['.js', '.mjs', '.jsx', '.ts', '.tsx', '.d.ts'],
20
+
21
+ // Resolve type definition packages
22
+ 'import/external-module-folders': ['node_modules', 'node_modules/@types'],
23
+
24
+ // Apply special parsing for TypeScript files
25
+ 'import/parsers': {
26
+ '@typescript-eslint/parser': ['.ts', '.tsx', '.d.ts'],
27
+ },
28
+
29
+ // Append 'ts' extensions to Airbnb 'import/resolver' setting
30
+ 'import/resolver': {
31
+ node: {
32
+ extensions: ['.mjs', '.js', '.json', '.ts', '.d.ts'],
33
+ },
34
+ },
35
+ },
17
36
  };
package/rules/node.js DELETED
@@ -1,21 +0,0 @@
1
- const { off, error } = require('./_rule');
2
-
3
- // @see https://eslint.org/blog/2020/02/whats-coming-in-eslint-7.0.0#deprecating-node-js-commonjs-specific-rules
4
- module.exports = {
5
- env: {
6
- node: true,
7
- },
8
- rules: {
9
- 'callback-return': off,
10
- 'global-require': error,
11
- 'handle-callback-err': off,
12
- 'no-buffer-constructor': error,
13
- 'no-mixed-requires': [off, false],
14
- 'no-new-require': error,
15
- 'no-path-concat': error,
16
- 'no-process-env': off,
17
- 'no-process-exit': off,
18
- 'no-restricted-modules': off,
19
- 'no-sync': off,
20
- },
21
- };