@w5s/eslint-config 1.0.0-alpha.2 → 1.0.0-alpha.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@w5s/eslint-config",
3
- "version": "1.0.0-alpha.2",
3
+ "version": "1.0.0-alpha.6",
4
4
  "description": "ESLint configuration presets",
5
5
  "keywords": [
6
6
  "eslint",
@@ -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",
@@ -71,10 +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
  },
79
- "gitHead": "1fd5f03e6f071785cc5be4f9a57430485cf9d6fc"
86
+ "gitHead": "79cf1b971006e8a0255763db12dd46938d228c78"
80
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,476 +1,39 @@
1
- const { off, warn, error } = require('./_rule');
1
+ const { concatESConfig, off, error } = 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': [
16
- 'error',
17
- 'as-needed',
18
- {
19
- requireReturnForObjectLiteral: false,
20
- },
21
- ],
22
- 'arrow-parens': [error, 'always'],
23
- 'arrow-spacing': [error, { after: true, before: true }],
24
- 'block-scoped-var': error,
25
- 'block-spacing': [error, 'always'],
26
- 'brace-style': [error, '1tbs', { allowSingleLine: false }],
27
- camelcase: off,
28
- 'capitalized-comments': off,
29
- 'class-methods-use-this': off,
30
- 'comma-dangle': [error, 'always-multiline'],
31
- 'comma-spacing': [error, { after: true, before: false }],
32
- 'comma-style': [error, 'last'],
33
- complexity: [error, 20],
34
- 'computed-property-spacing': [error, 'never'],
35
- 'consistent-return': error,
36
- 'consistent-this': [error, 'self'],
37
- 'constructor-super': error,
38
- curly: error,
39
- 'default-case': [error, { commentPattern: '^no default$' }], // require default case in switch statements or ignore by adding `//no default`
40
- 'dot-location': [error, 'property'],
41
- 'dot-notation': error,
42
- 'eol-last': error,
43
- eqeqeq: [error, 'smart'],
44
- 'for-direction': error,
45
- 'func-call-spacing': [error, 'never'],
46
- 'func-name-matching': error,
47
- 'func-names': off,
48
- 'func-style': off,
49
- 'function-paren-newline': [error, 'consistent'],
50
- 'generator-star-spacing': [error, { after: false, before: true }],
51
- 'getter-return': [error, { allowImplicit: true }],
52
- 'guard-for-in': error,
53
- 'id-length': [error, { exceptions: ['t', '$', '_', 'x', 'y', 'z'], max: 50, min: 2, properties: 'never' }],
54
- 'id-match': off,
55
- 'implicit-arrow-linebreak': [error, 'beside'],
56
- indent: [error, 2],
57
- 'init-declarations': off,
58
- 'jsx-quotes': [error, 'prefer-double'],
59
- 'key-spacing': [
60
- error,
61
- {
62
- afterColon: true,
63
- beforeColon: false,
64
- },
65
- ],
66
- 'keyword-spacing': [
67
- error,
68
- {
69
- after: true,
70
- before: true,
71
- },
72
- ],
73
- 'line-comment-position': 0,
74
- 'linebreak-style': [error, 'unix'],
75
- 'lines-around-comment': [
76
- error,
77
- {
78
- allowArrayEnd: true,
79
- allowArrayStart: true,
80
- allowBlockEnd: true,
81
- allowBlockStart: true,
82
- allowObjectEnd: true,
83
- allowObjectStart: true,
84
- beforeBlockComment: true,
85
- beforeLineComment: true,
86
- },
87
- ],
88
- 'lines-around-directive': [error, 'always'],
89
- 'lines-between-class-members': [error, 'always', { exceptAfterSingleLine: true }],
90
- 'max-len': [
91
- warn,
92
- {
93
- code: 160,
94
- },
95
- ],
96
- 'max-nested-callbacks': [warn, { max: 5 }],
97
- 'max-statements-per-line': [
98
- error,
99
- {
100
- max: 1,
101
- },
102
- ],
103
- 'multiline-comment-style': off,
104
- 'multiline-ternary': off,
105
- 'new-cap': [
106
- off,
107
- {
108
- capIsNew: false,
109
- newIsCap: true,
110
- },
111
- ],
112
- 'new-parens': error,
113
- 'newline-after-var': off,
114
- 'newline-before-return': error,
115
- 'newline-per-chained-call': off,
116
- 'no-alert': error,
117
- 'no-array-constructor': error,
118
- 'no-async-promise-executor': error,
119
- 'no-await-in-loop': error,
120
- 'no-caller': error,
121
- 'no-case-declarations': error,
122
- 'no-catch-shadow': error,
123
- 'no-class-assign': error,
124
- 'no-compare-neg-zero': error,
125
- 'no-cond-assign': error,
126
- 'no-confusing-arrow': error,
127
- 'no-console': error,
128
- 'no-const-assign': error,
129
- 'no-constant-condition': warn,
130
- 'no-continue': off,
131
- 'no-control-regex': error,
132
- 'no-debugger': error,
133
- 'no-delete-var': error,
134
- 'no-div-regex': error,
135
- 'no-dupe-args': error,
136
- 'no-dupe-class-members': error,
137
- 'no-dupe-else-if': error,
138
- 'no-dupe-keys': error,
139
- 'no-duplicate-case': error,
140
- 'no-duplicate-imports': off,
141
- 'no-else-return': [error, { allowElseIf: false }],
142
- 'no-empty': error,
143
- 'no-empty-character-class': error,
144
- 'no-empty-function': [error, { allow: ['arrowFunctions', 'functions', 'methods'] }],
145
- 'no-empty-pattern': error,
146
- 'no-eq-null': off,
147
- 'no-eval': error,
148
- 'no-ex-assign': error,
149
- 'no-extend-native': error,
150
- 'no-extra-bind': error,
151
- 'no-extra-boolean-cast': error,
152
- 'no-extra-parens': error,
153
- 'no-extra-semi': error,
154
- 'no-fallthrough': error,
155
- 'no-floating-decimal': error,
156
- 'no-func-assign': error,
157
- 'no-global-assign': error,
158
- 'no-implicit-coercion': error,
159
- 'no-implicit-globals': off,
160
- 'no-implied-eval': error,
161
- 'no-import-assign': error,
162
- 'no-inline-comments': off,
163
- 'no-inner-declarations': error,
164
- 'no-invalid-regexp': error,
165
- 'no-invalid-this': off,
166
- 'no-irregular-whitespace': error,
167
- 'no-iterator': error,
168
- 'no-label-var': error,
169
- 'no-labels': error,
170
- 'no-lone-blocks': error,
171
- 'no-lonely-if': error,
172
- 'no-loop-func': error,
173
- 'no-loss-of-precision': error,
174
- 'no-magic-numbers': off,
175
- 'no-misleading-character-class': error,
176
- 'no-mixed-spaces-and-tabs': error,
177
- 'no-multi-spaces': [
178
- error,
179
- {
180
- ignoreEOLComments: false,
181
- },
182
- ],
183
- 'no-multi-str': error,
184
- 'no-multiple-empty-lines': [
185
- error,
186
- {
187
- max: 1,
188
- maxBOF: 0,
189
- maxEOF: 1,
190
- },
191
- ],
192
- 'no-native-reassign': error,
193
- 'no-negated-condition': off,
194
- 'no-negated-in-lhs': error,
195
- 'no-nested-ternary': off,
196
- 'no-new': error,
197
- 'no-new-func': error,
198
- 'no-new-object': error,
199
- 'no-new-require': error,
200
- 'no-new-symbol': error,
201
- 'no-new-wrappers': error,
202
- 'no-obj-calls': error,
203
- 'no-octal': error,
204
- 'no-octal-escape': error,
205
- 'no-param-reassign': [
206
- error,
207
- {
208
- props: false,
209
- },
210
- ],
211
- 'no-plusplus': error,
212
- 'no-promise-executor-return': error,
213
- 'no-proto': error,
214
- 'no-prototype-builtins': error,
215
- 'no-redeclare': [
216
- error,
217
- {
218
- builtinGlobals: true,
219
- },
220
- ],
221
- 'no-regex-spaces': error,
222
- 'no-restricted-globals': off,
223
- 'no-restricted-properties': [
224
- error,
225
- {
226
- message: 'arguments.callee is deprecated',
227
- object: 'arguments',
228
- property: 'callee',
229
- },
230
- {
231
- message: 'Please use Number.isFinite instead',
232
- object: 'global',
233
- property: 'isFinite',
234
- },
235
- {
236
- message: 'Please use Number.isFinite instead',
237
- object: 'self',
238
- property: 'isFinite',
239
- },
240
- {
241
- message: 'Please use Number.isFinite instead',
242
- object: 'window',
243
- property: 'isFinite',
244
- },
245
- {
246
- message: 'Please use Number.isNaN instead',
247
- object: 'global',
248
- property: 'isNaN',
249
- },
250
- {
251
- message: 'Please use Number.isNaN instead',
252
- object: 'self',
253
- property: 'isNaN',
254
- },
255
- {
256
- message: 'Please use Number.isNaN instead',
257
- object: 'window',
258
- property: 'isNaN',
259
- },
260
- {
261
- message: 'Please use Object.defineProperty instead.',
262
- property: '__defineGetter__',
263
- },
264
- {
265
- message: 'Please use Object.defineProperty instead.',
266
- property: '__defineSetter__',
267
- },
268
- {
269
- message: 'Use the exponentiation operator (**) instead.',
270
- object: 'Math',
271
- property: 'pow',
272
- },
273
- ],
274
- 'no-restricted-syntax': [
275
- error,
276
- {
277
- message:
278
- '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.',
279
- selector: 'ForInStatement',
280
- },
281
- {
282
- message: 'Labels are a form of GOTO; using them makes code confusing and hard to maintain and understand.',
283
- selector: 'LabeledStatement',
284
- },
285
- {
286
- message: '`with` is disallowed in strict mode because it makes code impossible to predict and optimize.',
287
- selector: 'WithStatement',
288
- },
289
- ],
290
- 'no-return-assign': error,
291
- 'no-return-await': error,
292
- 'no-script-url': error,
293
- 'no-self-assign': error,
294
- 'no-self-compare': error,
295
- 'no-sequences': error,
296
- 'no-setter-return': error,
297
- 'no-shadow': [
298
- error,
299
- {
300
- builtinGlobals: false,
301
- hoist: 'all',
302
- },
303
- ],
304
- 'no-shadow-restricted-names': error,
305
- 'no-spaced-func': error,
306
- 'no-sparse-arrays': error,
307
- 'no-sync': off,
308
- 'no-tabs': error,
309
- 'no-template-curly-in-string': error,
310
- 'no-ternary': off,
311
- 'no-this-before-super': error,
312
- 'no-throw-literal': error,
313
- 'no-trailing-spaces': error,
314
- 'no-undef': error,
315
- 'no-undef-init': error,
316
- 'no-undefined': off,
317
- 'no-underscore-dangle': off,
318
- 'no-unexpected-multiline': error,
319
- 'no-unmodified-loop-condition': error,
320
- 'no-unneeded-ternary': off, // error,
321
- 'no-unreachable': error,
322
- 'no-unreachable-loop': error,
323
- 'no-unsafe-finally': error,
324
- 'no-unsafe-negation': error,
325
- 'no-unsafe-optional-chaining': [error, { disallowArithmeticOperators: true }],
326
- 'no-unused-expressions': [
327
- error,
328
- {
329
- allowShortCircuit: false,
330
- allowTaggedTemplates: true,
331
- allowTernary: false,
332
- },
333
- ],
334
- 'no-unused-vars': [
335
- error,
336
- {
337
- args: 'none',
338
- ignoreRestSiblings: true,
339
- vars: 'all',
340
- },
341
- ],
342
- 'no-use-before-define': [
343
- error,
344
- {
345
- classes: false,
346
- functions: false,
347
- variables: false,
348
- },
349
- ],
350
- 'no-useless-backreference': error,
351
- 'no-useless-call': error,
352
- 'no-useless-catch': error,
353
- 'no-useless-computed-key': error,
354
- 'no-useless-concat': error,
355
- 'no-useless-constructor': error,
356
- 'no-useless-escape': error,
357
- 'no-useless-rename': [
358
- error,
359
- {
360
- ignoreDestructuring: false,
361
- ignoreExport: false,
362
- ignoreImport: false,
363
- },
364
- ],
365
- 'no-useless-return': error,
366
- 'no-var': error,
367
- 'no-void': error,
368
- 'no-warning-comments': [
369
- off,
370
- {
371
- location: 'start',
372
- terms: ['todo', '@todo'],
373
- },
374
- ],
375
- 'no-whitespace-before-property': error,
376
- 'no-with': error,
377
- 'nonblock-statement-body-position': [error, 'below'],
378
- 'object-curly-spacing': [off, 'never'],
379
- 'object-property-newline': [
380
- error,
381
- {
382
- allowMultiplePropertiesPerLine: false,
383
- },
384
- ],
385
- 'object-shorthand': [error, 'always'],
386
- 'one-var': [error, 'never'],
387
- 'one-var-declaration-per-line': error,
388
- 'operator-assignment': [error, 'always'],
389
- 'operator-linebreak': [error, 'after'],
390
- 'padded-blocks': [error, 'never'],
391
- 'padding-line-between-statements': off,
392
- 'prefer-arrow-callback': [
393
- error,
394
- {
395
- allowNamedFunctions: false,
396
- allowUnboundThis: true,
397
- },
398
- ],
399
- 'prefer-const': error,
400
- 'prefer-destructuring': off,
401
- 'prefer-named-capture-group': off,
402
- 'prefer-numeric-literals': error,
403
- 'prefer-promise-reject-errors': error,
404
- 'prefer-reflect': off,
405
- 'prefer-rest-params': error,
406
- 'prefer-spread': error,
407
- 'prefer-template': error,
408
- 'quote-props': [error, 'as-needed'],
409
- quotes: [error, 'single'],
410
- radix: error,
411
- 'require-await': off, // https://github.com/airbnb/javascript/issues/2013
412
- 'require-jsdoc': off,
413
- 'require-yield': error,
414
- semi: [error, 'always'],
415
- 'semi-spacing': [
416
- error,
417
- {
418
- after: true,
419
- before: false,
420
- },
421
- ],
422
- 'semi-style': [error, 'last'],
423
- 'sort-keys': off /* [
424
- error,
425
- 'asc',
426
- {
427
- caseSensitive: false,
428
- natural: true
429
- }
430
- ], */,
431
- 'sort-vars': error,
432
- 'space-before-blocks': [error, 'always'],
433
- 'space-before-function-paren': [error, 'always'],
434
- 'space-in-parens': [error, 'never'],
435
- 'space-infix-ops': error,
436
- 'space-unary-ops': [
437
- error,
438
- {
439
- nonwords: false,
440
- words: true,
441
- },
442
- ],
443
- 'spaced-comment': [
444
- error,
445
- 'always',
446
- {
447
- block: {
448
- balanced: true,
449
- exceptions: ['*'],
450
- markers: ['*package', '!', ',', ':', '::', 'flow-include'],
451
- },
452
- line: {
453
- markers: ['*package', '!', '/', ',', '='],
454
- },
455
- },
456
- ],
457
- strict: [error, 'never'],
458
- 'switch-colon-spacing': [
459
- error,
460
- {
461
- after: true,
462
- before: false,
463
- },
464
- ],
465
- 'symbol-description': error,
466
- 'template-tag-spacing': [error, 'never'],
467
- 'unicode-bom': [error, 'never'],
468
- 'use-isnan': error,
469
- 'valid-jsdoc': off,
470
- 'valid-typeof': [error, { requireStringLiterals: true }],
471
- 'vars-on-top': error,
472
- 'wrap-iife': [error, 'inside'],
473
- 'wrap-regex': off,
474
- yoda: off,
475
- },
476
- };
3
+ const baseConfig = 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
+
22
+ module.exports = concatESConfig(
23
+ baseConfig,
24
+ // overrides
25
+ {
26
+ rules: {
27
+ // Often useful in jsx
28
+ 'no-nested-ternary': off,
29
+ // Too strict, for pure code prefer the functional plugin
30
+ 'no-param-reassign': [error, { props: false }],
31
+ // Allow for-of syntax
32
+ // @ts-ignore
33
+ 'no-restricted-syntax': baseConfig.rules['no-restricted-syntax'].filter(
34
+ // @ts-ignore
35
+ ({ selector }) => selector !== 'ForOfStatement'
36
+ ),
37
+ },
38
+ }
39
+ );
package/rules/import.js CHANGED
@@ -1,4 +1,4 @@
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
@@ -7,110 +7,17 @@ const { off, warn, error } = require('./_rule');
7
7
  // eslint-disable-next-line no-unused-vars
8
8
  const performanceIssue = (_status) => off;
9
9
 
10
- module.exports = {
11
- plugins: ['import'],
12
- rules: {
13
- 'import/default': error,
14
- 'import/export': error,
15
- 'import/exports-last': off,
16
- 'import/extensions': [
17
- error,
18
- 'ignorePackages',
19
- {
20
- js: 'never',
21
- json: 'always',
22
- jsx: 'never',
23
- mjs: 'never',
24
- ts: 'never',
25
- tsx: 'never',
26
- },
27
- ],
28
- 'import/first': [error, 'absolute-first'],
29
- 'import/group-exports': off,
30
- 'import/max-dependencies': [
31
- off,
32
- {
33
- max: 10,
34
- },
35
- ],
36
- 'import/named': error,
37
- 'import/namespace': error,
38
- 'import/newline-after-import': error,
39
- 'import/no-absolute-path': error,
40
- 'import/no-amd': error,
41
- 'import/no-anonymous-default-export': off,
42
- 'import/no-commonjs': off, // Still used widely by nodejs programs
43
- 'import/no-cycle': [error, { maxDepth: Number.POSITIVE_INFINITY }], // Elm, ReasonML forbids circular dependency
44
- 'import/no-default-export': off,
45
- 'import/no-deprecated': performanceIssue(warn),
46
- 'import/no-duplicates': error,
47
- 'import/no-dynamic-require': error,
48
- 'import/no-extraneous-dependencies': [
49
- error,
50
- {
51
- // https://github.com/airbnb/javascript/blob/1eadb93e377da1e56c3f91f26610e5d0a00738a9/packages/eslint-config-airbnb-base/rules/imports.js#L71
52
- devDependencies: [
53
- 'test/**', // tape, common npm pattern
54
- 'tests/**', // also common npm pattern
55
- 'spec/**', // mocha, rspec-like pattern
56
- '**/__tests__/**', // jest pattern
57
- '**/__mocks__/**', // jest pattern
58
- 'test.{js,jsx,ts,tsx}', // repos with a single test file
59
- 'test-*.{js,jsx,ts,tsx}', // repos with multiple top-level test files
60
- '**/*{.,_}{test,spec}.{js,jsx,ts,tsx}', // tests where the extension or filename suffix denotes that it is a test
61
- '**/jest.config.{js,ts}', // jest config
62
- '**/jest.setup.{js,ts}', // jest setup
63
- '**/vue.config.{js,ts}', // vue-cli config
64
- '**/webpack.config.js', // webpack config
65
- '**/webpack.config.*.js', // webpack config
66
- '**/rollup.config.js', // rollup config
67
- '**/rollup.config.*.js', // rollup config
68
- '**/gulpfile.js', // gulp config
69
- '**/gulpfile.*.js', // gulp config
70
- '**/Gruntfile{,.js}', // grunt config
71
- '**/protractor.conf.js', // protractor config
72
- '**/protractor.conf.*.js', // protractor config
73
- '**/karma.conf.js', // karma config
74
- '**/.eslintrc.js', // eslint config,
75
- '**/markdown.config.js', // markdown magic config,
76
- ],
77
- optionalDependencies: false,
78
- },
79
- ],
80
- 'import/no-internal-modules': off,
81
- 'import/no-mutable-exports': error,
82
- 'import/no-named-as-default': performanceIssue(error),
83
- 'import/no-named-as-default-member': error,
84
- 'import/no-named-default': error,
85
- 'import/no-named-export': off,
86
- 'import/no-namespace': off,
87
- 'import/no-nodejs-modules': off,
88
- 'import/no-relative-parent-imports': off,
89
- 'import/no-restricted-paths': off,
90
- 'import/no-self-import': error,
91
- 'import/no-unassigned-import': off,
92
- 'import/no-unresolved': [error, { caseSensitive: true, commonjs: true }],
93
- 'import/no-unused-modules': [performanceIssue(error), { unusedExports: true }],
94
- 'import/no-useless-path-segments': error,
95
- 'import/no-webpack-loader-syntax': error,
96
- 'import/order': [
97
- error,
98
- {
99
- groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'],
100
- 'newlines-between': 'never',
101
- },
102
- ],
103
- 'import/prefer-default-export': off,
104
- 'import/unambiguous': off, // Disable because proposal still in progress
105
- },
106
- settings: {
107
- 'import/core-modules': [],
108
- 'import/extensions': ['.js', '.mjs', '.jsx'],
109
- 'import/ignore': ['node_modules', '\\.(coffee|scss|css|less|hbs|svg|json)$'],
110
- 'import/resolver': {
111
- node: {
112
- extensions: ['.mjs', '.js', '.json'],
113
- },
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
114
21
  },
115
- },
116
- };
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
+ );
@@ -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
- };