eslint-config-jc 4.0.0 → 4.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js CHANGED
@@ -3,9 +3,15 @@ module.exports = {
3
3
  extends: [
4
4
  "prettier",
5
5
  "./rules/base.js",
6
+ "./rules/regex.js",
6
7
  "./rules/typescript.js",
7
8
  "./rules/import.js",
8
9
  "./rules/react.js",
9
10
  "./rules/jsx.js",
11
+ // Not included by default:
12
+ // "./rules/typescript-typecheck.js",
13
+ // "./rules/node.js",
14
+ // "./rules/react-class-comps.js",
15
+ // "./rules/react-prop-types.js",
10
16
  ],
11
17
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-config-jc",
3
- "version": "4.0.0",
3
+ "version": "4.2.0",
4
4
  "description": "Josh-Cena's personal coding style",
5
5
  "main": "index.js",
6
6
  "repository": {
@@ -25,9 +25,13 @@
25
25
  "exports": {
26
26
  ".": "./index.js",
27
27
  "./base": "./rules/base.js",
28
+ "./regex": "./rules/regex.js",
28
29
  "./import": "./rules/import.js",
30
+ "./node": "./rules/node.js",
29
31
  "./jsx": "./rules/jsx.js",
30
32
  "./react": "./rules/react.js",
33
+ "./react-class-comps": "./rules/react-class-comps.js",
34
+ "./react-prop-types": "./rules/react-prop-types.js",
31
35
  "./typescript": "./rules/typescript.js",
32
36
  "./typescript-typecheck": "./rules/typescript-typecheck.js"
33
37
  },
@@ -42,7 +46,8 @@
42
46
  "eslint-plugin-import": "^2.29.0",
43
47
  "eslint-plugin-jsx-a11y": "^6.8.0",
44
48
  "eslint-plugin-react": "^7.33.2",
45
- "eslint-plugin-react-hooks": "^4.6.0"
49
+ "eslint-plugin-react-hooks": "^4.6.0",
50
+ "eslint-plugin-regexp": "^2.1.1"
46
51
  },
47
52
  "peerDependenciesMeta": {
48
53
  "eslint-plugin-header": {
package/rules/jsx.js CHANGED
@@ -1,5 +1,5 @@
1
1
  module.exports = {
2
- plugins: ["jsx-a11y"],
2
+ plugins: ["jsx-a11y", "react"],
3
3
  rules: {
4
4
  // JSX a11y rules are taken from airbnb, not adjusted yet
5
5
  "jsx-a11y/alt-text": [
@@ -13,7 +13,22 @@ module.exports = {
13
13
  },
14
14
  ],
15
15
 
16
- "jsx-a11y/anchor-has-content": ["error", { components: [] }],
16
+ "jsx-a11y/anchor-ambiguous-text": [
17
+ "warn",
18
+ {
19
+ // Default
20
+ words: ["click here", "here", "link", "a link", "learn more"],
21
+ },
22
+ ],
23
+
24
+ "jsx-a11y/anchor-has-content": [
25
+ "error",
26
+ {
27
+ aspects: ["noHref", "invalidHref", "preferButton"],
28
+ components: ["Link"],
29
+ specialLink: ["to"],
30
+ },
31
+ ],
17
32
 
18
33
  "jsx-a11y/anchor-is-valid": [
19
34
  "error",
@@ -34,12 +49,7 @@ module.exports = {
34
49
 
35
50
  "jsx-a11y/aria-unsupported-elements": "error",
36
51
 
37
- "jsx-a11y/autocomplete-valid": [
38
- "off",
39
- {
40
- inputComponents: [],
41
- },
42
- ],
52
+ "jsx-a11y/autocomplete-valid": ["off", { inputComponents: [] }],
43
53
 
44
54
  "jsx-a11y/click-events-have-key-events": "error",
45
55
 
@@ -73,7 +83,7 @@ module.exports = {
73
83
  },
74
84
  ],
75
85
 
76
- "jsx-a11y/heading-has-content": ["error", { components: [""] }],
86
+ "jsx-a11y/heading-has-content": ["error", { components: [] }],
77
87
 
78
88
  "jsx-a11y/html-has-lang": "error",
79
89
 
@@ -81,7 +91,20 @@ module.exports = {
81
91
 
82
92
  "jsx-a11y/img-redundant-alt": "error",
83
93
 
84
- "jsx-a11y/interactive-supports-focus": "error",
94
+ "jsx-a11y/interactive-supports-focus": [
95
+ "error",
96
+ {
97
+ tabbable: [
98
+ "button",
99
+ "checkbox",
100
+ "link",
101
+ "searchbox",
102
+ "spinbutton",
103
+ "switch",
104
+ "textbox",
105
+ ],
106
+ },
107
+ ],
85
108
 
86
109
  "jsx-a11y/label-has-associated-control": [
87
110
  "error",
@@ -105,24 +128,38 @@ module.exports = {
105
128
  },
106
129
  ],
107
130
 
108
- "jsx-a11y/mouse-events-have-key-events": "error",
131
+ "jsx-a11y/mouse-events-have-key-events": [
132
+ "error",
133
+ {
134
+ hoverInHandlers: [
135
+ "onMouseOver",
136
+ "onMouseEnter",
137
+ "onPointerOver",
138
+ "onPointerEnter",
139
+ ],
140
+ hoverOutHandlers: [
141
+ "onMouseOut",
142
+ "onMouseLeave",
143
+ "onPointerOut",
144
+ "onPointerLeave",
145
+ ],
146
+ },
147
+ ],
109
148
 
110
149
  "jsx-a11y/no-access-key": "error",
111
150
 
112
- "jsx-a11y/no-autofocus": ["error", { ignoreNonDOM: true }],
151
+ "jsx-a11y/no-aria-hidden-on-focusable": "error",
152
+
153
+ "jsx-a11y/no-autofocus": ["error", { ignoreNonDOM: false }],
113
154
 
114
155
  "jsx-a11y/no-distracting-elements": [
115
156
  "error",
116
- {
117
- elements: ["marquee", "blink"],
118
- },
157
+ { elements: ["marquee", "blink"] },
119
158
  ],
120
159
 
121
160
  "jsx-a11y/no-interactive-element-to-noninteractive-role": [
122
161
  "error",
123
- {
124
- tr: ["none", "presentation"],
125
- },
162
+ { tr: ["none", "presentation"] },
126
163
  ],
127
164
 
128
165
  "jsx-a11y/no-noninteractive-element-interactions": [
@@ -169,6 +206,7 @@ module.exports = {
169
206
  "jsx-a11y/no-noninteractive-tabindex": [
170
207
  "error",
171
208
  {
209
+ allowExpressionValues: true,
172
210
  roles: ["tabpanel"],
173
211
  tags: [],
174
212
  },
@@ -176,11 +214,17 @@ module.exports = {
176
214
 
177
215
  "jsx-a11y/no-onchange": "off",
178
216
 
179
- "jsx-a11y/no-redundant-roles": "error",
217
+ "jsx-a11y/no-redundant-roles": [
218
+ "error",
219
+ {
220
+ nav: ["navigation"],
221
+ },
222
+ ],
180
223
 
181
224
  "jsx-a11y/no-static-element-interactions": [
182
225
  "error",
183
226
  {
227
+ allowExpressionValues: true,
184
228
  handlers: [
185
229
  "onClick",
186
230
  "onMouseDown",
@@ -192,6 +236,8 @@ module.exports = {
192
236
  },
193
237
  ],
194
238
 
239
+ "jsx-a11y/prefer-tag-over-role": "error",
240
+
195
241
  "jsx-a11y/role-has-required-aria-props": "error",
196
242
 
197
243
  "jsx-a11y/role-supports-aria-props": "error",
@@ -200,29 +246,69 @@ module.exports = {
200
246
 
201
247
  "jsx-a11y/tabindex-no-positive": "error",
202
248
 
249
+ "react/button-has-type": [
250
+ "error",
251
+ {
252
+ button: true,
253
+ reset: false, // MDN: This behavior tends to annoy users
254
+ submit: true,
255
+ },
256
+ ],
257
+
258
+ "react/iframe-missing-sandbox": "error",
259
+
203
260
  "react/jsx-boolean-value": ["error", "never"],
204
261
 
205
- "react/jsx-curly-brace-presence": "error",
262
+ "react/jsx-child-element-spacing": "warn",
263
+
264
+ // Formatting
265
+ "react/jsx-closing-bracket-location": "off",
266
+
267
+ // Formatting
268
+ "react/jsx-closing-tag-location": "off",
269
+
270
+ "react/jsx-curly-brace-presence": [
271
+ "error",
272
+ // Maybe one day we can use propElementValues: "never"...
273
+ { children: "never", propElementValues: "ignore", props: "never" },
274
+ ],
275
+
276
+ // Formatting
277
+ "react/jsx-curly-newline": "off",
278
+
279
+ // Formatting
280
+ "react/jsx-curly-spacing": "off",
206
281
 
207
- // Js, jsx, tsx are all acceptable
282
+ // Formatting
283
+ "react/jsx-equals-spacing": "off",
284
+
285
+ // .js, .jsx, .tsx are all acceptable
208
286
  "react/jsx-filename-extension": "off",
209
287
 
210
- "react/jsx-fragments": "error",
288
+ // Formatting
289
+ "react/jsx-first-prop-new-line": "off",
211
290
 
291
+ // Too stylistic
212
292
  "react/jsx-handler-names": "off",
213
293
 
214
- // Airbnb says there can be false positives
215
- "react/jsx-key": "error",
294
+ // Formatting
295
+ "react/jsx-indent": "off",
296
+
297
+ // Formatting
298
+ "react/jsx-indent-props": "off",
216
299
 
300
+ // Too stylistic
217
301
  "react/jsx-max-depth": "off",
218
302
 
219
- "react/jsx-no-bind": ["warn", { ignoreDOMComponents: true }],
303
+ // Formatting
304
+ "react/jsx-max-props-per-line": "off",
220
305
 
221
- "react/jsx-no-comment-textnodes": "error",
306
+ // Formatting
307
+ "react/jsx-newline": "off",
222
308
 
223
- "react/jsx-no-constructed-context-values": "error",
309
+ "react/jsx-no-comment-textnodes": "error",
224
310
 
225
- "react/jsx-no-duplicate-props": "error",
311
+ "react/jsx-no-duplicate-props": ["error", { ignoreCase: false }],
226
312
 
227
313
  // We'll use strict-boolean-expressions instead
228
314
  "react/jsx-no-leaked-render": "off",
@@ -231,23 +317,69 @@ module.exports = {
231
317
 
232
318
  "react/jsx-no-script-url": "error",
233
319
 
234
- "react/jsx-no-target-blank": "error",
320
+ "react/jsx-no-target-blank": [
321
+ "error",
322
+ {
323
+ allowReferrer: false,
324
+ enforceDynamicLinks: "always",
325
+ forms: true,
326
+ links: true,
327
+ warnOnSpreadAttributes: true,
328
+ },
329
+ ],
235
330
 
236
331
  // Also checked by TypeScript
237
- "react/jsx-no-undef": "error",
332
+ "react/jsx-no-undef": ["error", { allowGlobals: true }],
238
333
 
239
334
  "react/jsx-no-useless-fragment": ["error", { allowExpressions: true }],
240
335
 
241
- "react/jsx-pascal-case": ["error", { allowAllCaps: true }],
336
+ // Formatting
337
+ "react/jsx-one-expression-per-line": "off",
242
338
 
243
- "react/jsx-props-no-spreading": "off",
339
+ "react/jsx-pascal-case": [
340
+ "error",
341
+ {
342
+ allowAllCaps: true,
343
+ allowLeadingUnderscore: false,
344
+ allowNamespace: true,
345
+ },
346
+ ],
244
347
 
245
- "react/jsx-sort-default-props": "off",
348
+ // Formatting
349
+ "react/jsx-props-no-multi-spaces": "off",
246
350
 
247
- "react/jsx-sort-props": "off",
351
+ // We like spreading
352
+ "react/jsx-props-no-spreading": "off",
248
353
 
249
- "react/jsx-uses-react": "warn",
354
+ "react/jsx-sort-props": 0,
355
+
356
+ // Formatting
357
+ "react/jsx-tag-spacing": "off",
250
358
 
251
359
  "react/jsx-uses-vars": "warn",
360
+
361
+ // Formatting
362
+ "react/jsx-wrap-multilines": "off",
363
+
364
+ // Too stylistic
365
+ "react/no-adjacent-inline-elements": "off",
366
+
367
+ "react/no-children-prop": ["error", { allowFunctions: false }],
368
+
369
+ "react/no-invalid-html-attribute": "error",
370
+
371
+ // The original text allows for things like spellchecking and searching
372
+ "react/no-unescaped-entities": "off",
373
+
374
+ "react/no-unknown-property": [
375
+ "error",
376
+ {
377
+ // TODO: not released: requireDataLowercase: true,
378
+ },
379
+ ],
380
+
381
+ "react/self-closing-comp": ["error", { component: true, html: true }],
382
+
383
+ "react/void-dom-elements-no-children": "error",
252
384
  },
253
385
  };
package/rules/node.js ADDED
@@ -0,0 +1,84 @@
1
+ module.exports = {
2
+ plugins: ["n"],
3
+ rules: {
4
+ // Callback-related
5
+ "n/callback-return": "off",
6
+
7
+ "n/exports-style": ["error", "module.exports", { allowBatchAssign: false }],
8
+
9
+ // Checked by TypeScript
10
+ "n/file-extension-in-import": "off",
11
+
12
+ // On-demand loading is useful
13
+ "n/global-require": "off",
14
+
15
+ // Callback-related
16
+ "n/handle-callback-err": "off",
17
+
18
+ // Callback-related
19
+ "n/no-callback-literal": "off",
20
+
21
+ "n/no-deprecated-api": "error",
22
+
23
+ "n/no-exports-assign": "error",
24
+
25
+ // Shadowed by import/no-extraneous-dependencies
26
+ "n/no-extraneous-import": "off",
27
+
28
+ // Shadowed by import/no-extraneous-dependencies
29
+ "n/no-extraneous-require": "off",
30
+
31
+ // Checked by TypeScript
32
+ "n/no-missing-import": "off",
33
+
34
+ // Checked by TypeScript
35
+ "n/no-missing-require": "off",
36
+
37
+ // Not helpful
38
+ "n/no-mixed-requires": "off",
39
+
40
+ "n/no-new-require": "error",
41
+
42
+ "n/no-path-concat": "warn",
43
+
44
+ "n/no-process-env": "off",
45
+
46
+ // Useful in theory, but too noisy
47
+ "n/no-process-exit": "off",
48
+
49
+ "n/no-restricted-import": "off",
50
+
51
+ "n/no-restricted-require": "off",
52
+
53
+ "n/no-sync": ["warn", { allowAtRootLevel: false }],
54
+
55
+ "n/no-unpublished-bin": "error",
56
+
57
+ "n/no-unpublished-import": "off",
58
+
59
+ "n/no-unpublished-require": "off",
60
+
61
+ "n/prefer-global/buffer": ["error", "always"],
62
+
63
+ "n/prefer-global/console": ["error", "always"],
64
+
65
+ "n/prefer-global/process": ["error", "always"],
66
+
67
+ "n/prefer-global/text-decoder": ["error", "always"],
68
+
69
+ "n/prefer-global/text-encoder": ["error", "always"],
70
+
71
+ "n/prefer-global/url": ["error", "always"],
72
+
73
+ "n/prefer-global/url-search-params": ["error", "always"],
74
+
75
+ "n/prefer-promises/dns": "error",
76
+
77
+ "n/prefer-promises/fs": "error",
78
+
79
+ "n/process-exit-as-throw": "warn",
80
+
81
+ // Errors on TypeScript bin
82
+ "n/shebang": "off",
83
+ },
84
+ };
@@ -0,0 +1,41 @@
1
+ module.exports = {
2
+ rules: {
3
+ "react/no-access-state-in-setstate": "error",
4
+
5
+ "react/no-arrow-function-lifecycle": "error",
6
+
7
+ "react/no-did-mount-set-state": "error",
8
+
9
+ "react/no-did-update-set-state": "error",
10
+
11
+ "react/no-direct-mutation-state": "error",
12
+
13
+ "react/no-redundant-should-component-update": "error",
14
+
15
+ // ???
16
+ "react/no-set-state": "off",
17
+
18
+ "react/no-unsafe": "error",
19
+
20
+ "react/no-unused-class-component-methods": "error",
21
+
22
+ "react/no-unused-state": "error",
23
+
24
+ "react/no-will-update-set-state": "error",
25
+
26
+ "react/prefer-es6-class": "error",
27
+
28
+ "react/prefer-stateless-function": "error",
29
+
30
+ // We mostly use function components, and this optimization is not critical
31
+ "react/require-optimization": "off",
32
+
33
+ "react/require-render-return": "error",
34
+
35
+ "react/sort-comp": 0,
36
+
37
+ "react/state-in-constructor": ["error", "never"],
38
+
39
+ "react/static-property-placement": ["error", "static public field"],
40
+ },
41
+ };
@@ -0,0 +1,21 @@
1
+ module.exports = {
2
+ rules: {
3
+ "react/default-props-match-prop-types": "off",
4
+
5
+ "react/forbid-foreign-prop-types": "off",
6
+
7
+ "react/forbid-prop-types": "off",
8
+
9
+ "react/no-unused-prop-types": "off",
10
+
11
+ "react/prefer-exact-props": "off",
12
+
13
+ "react/prop-types": "off",
14
+
15
+ "react/require-default-props": "off",
16
+
17
+ "react/sort-default-props": "off",
18
+
19
+ "react/sort-prop-types": "off",
20
+ },
21
+ };
package/rules/react.js CHANGED
@@ -12,29 +12,17 @@ module.exports = {
12
12
 
13
13
  "react/boolean-prop-naming": "off",
14
14
 
15
- "react/button-has-type": [
16
- "error",
17
- {
18
- button: true,
19
- reset: false, // MDN: This behavior tends to annoy users
20
- submit: true,
21
- },
22
- ],
23
-
24
- // Checked by TypeScript
25
- "react/default-props-match-prop-types": "off",
26
-
27
15
  // Sometimes we do need `props` as a whole, e.g. for spreading
28
16
  "react/destructuring-assignment": "off",
29
17
 
30
18
  // Isn't useful
31
- "react/display-name": ["off", { ignoreTranspilerName: false }],
19
+ "react/display-name": "off",
20
+
21
+ "react/forbid-component-props": 0,
32
22
 
33
- // Checked by TypeScript
34
- "react/forbid-foreign-prop-types": "error",
23
+ "react/forbid-dom-props": 0,
35
24
 
36
- // Checked by TypeScript
37
- "react/forbid-prop-types": "off",
25
+ "react/forbid-elements": 0,
38
26
 
39
27
  // Note that it false-positives for `const Foo: Comp = () => <></>`
40
28
  "react/function-component-definition": [
@@ -45,23 +33,40 @@ module.exports = {
45
33
  },
46
34
  ],
47
35
 
48
- // TODO unreleased feature
49
- // 'react/hook-use-state': 'warn',
36
+ "react/hook-use-state": ["error", { allowDestructuredState: true }],
50
37
 
51
- // 'react/iframe-missing-sandbox': 'error',
38
+ "react/jsx-fragments": ["error", "syntax"],
52
39
 
53
- // We don't use class components much.
54
- "react/no-access-state-in-setstate": "error",
40
+ // There can be false positives, such as an array that's not used as a
41
+ // single child
42
+ "react/jsx-key": [
43
+ "error",
44
+ {
45
+ checkFragmentShorthand: true,
46
+ // https://github.com/jsx-eslint/eslint-plugin-react/issues/2830
47
+ checkKeyMustBeforeSpread: true,
48
+ warnOnDuplicates: true,
49
+ },
50
+ ],
55
51
 
56
- // Enforced by Prettier
57
- "react/no-adjacent-inline-elements": "off",
52
+ "react/jsx-no-bind": [
53
+ "warn",
54
+ {
55
+ allowArrowFunctions: false,
56
+ allowBind: false,
57
+ allowFunctions: false,
58
+ ignoreDOMComponents: true,
59
+ ignoreRefs: true,
60
+ },
61
+ ],
58
62
 
59
- // In some cases this is fine (e.g. static websites)
60
- "react/no-array-index-key": "error",
63
+ "react/jsx-no-constructed-context-values": "error",
61
64
 
62
- "react/no-arrow-function-lifecycle": "error",
65
+ // We usually use automatic runtime
66
+ "react/jsx-uses-react": 0,
63
67
 
64
- "react/no-children-prop": "error",
68
+ // In some cases this is fine (e.g. static websites)
69
+ "react/no-array-index-key": "warn",
65
70
 
66
71
  "react/no-danger": "warn",
67
72
 
@@ -69,16 +74,10 @@ module.exports = {
69
74
 
70
75
  "react/no-deprecated": "error",
71
76
 
72
- "react/no-did-mount-set-state": "error",
73
-
74
- "react/no-did-update-set-state": "error",
75
-
76
- "react/no-direct-mutation-state": "error",
77
-
77
+ // Deprecated API
78
78
  "react/no-find-dom-node": "error",
79
79
 
80
- "react/no-invalid-html-attribute": "error",
81
-
80
+ // Deprecated API
82
81
  "react/no-is-mounted": "error",
83
82
 
84
83
  // It's useful for encapsulation.
@@ -86,77 +85,35 @@ module.exports = {
86
85
 
87
86
  "react/no-namespace": "error",
88
87
 
89
- "react/no-redundant-should-component-update": "error",
88
+ "react/no-object-type-as-default-prop": "warn",
90
89
 
90
+ // ReactDOM.render itself is deprecated
91
91
  "react/no-render-return-value": "error",
92
92
 
93
- "react/no-set-state": "off",
94
-
95
- "react/no-string-refs": "error",
93
+ "react/no-string-refs": ["error", { noTemplateLiterals: true }],
96
94
 
97
95
  "react/no-this-in-sfc": "error",
98
96
 
99
97
  "react/no-typos": "error",
100
98
 
101
- // The original text allows for things like spellchecking and searching
102
- "react/no-unescaped-entities": "off",
103
-
104
- "react/no-unknown-property": "error",
105
-
106
- "react/no-unsafe": "error",
107
-
108
- "react/no-unstable-nested-components": ["error", { allowAsProps: true }],
109
-
110
- "react/no-unused-class-component-methods": "error",
111
-
112
- // Checked by TypeScript
113
- "react/no-unused-prop-types": "off",
114
-
115
- "react/no-unused-state": "error",
116
-
117
- "react/no-will-update-set-state": "error",
118
-
119
- "react/prefer-es6-class": "error",
120
-
121
- // Checked by TypeScript
122
- "react/prefer-exact-props": "off",
99
+ "react/no-unstable-nested-components": ["warn", { allowAsProps: true }],
123
100
 
124
101
  "react/prefer-read-only-props": "warn",
125
102
 
126
- "react/prefer-stateless-function": "error",
127
-
128
- // Checked by TypeScript
129
- "react/prop-types": "off",
130
-
131
103
  // Checked by TypeScript; we may also use JSX runtime
132
104
  "react/react-in-jsx-scope": "off",
133
105
 
134
- // Checked by TypeScript
135
- "react/require-default-props": "off",
136
-
137
- // We mostly use function components, and this optimization is not critical
138
- "react/require-optimization": "off",
139
-
140
- "react/require-render-return": "error",
141
-
142
- "react/self-closing-comp": "error",
143
-
144
- "react/sort-comp": "off",
145
-
146
- "react/sort-prop-types": "off",
147
-
148
106
  "react/state-in-constructor": "error",
149
107
 
150
108
  "react/static-property-placement": "off",
151
109
 
110
+ // Also checked by TypeScript
152
111
  "react/style-prop-object": "error",
153
-
154
- "react/void-dom-elements-no-children": "error",
155
112
  },
156
113
  settings: {
157
114
  react: {
158
115
  pragma: "React",
159
- version: "17",
116
+ version: "18",
160
117
  },
161
118
  },
162
119
  };
package/rules/regex.js ADDED
@@ -0,0 +1,206 @@
1
+ module.exports = {
2
+ plugins: ["regexp"],
3
+ rules: {
4
+ "regexp/confusing-quantifier": "error",
5
+
6
+ "regexp/control-character-escape": "error",
7
+
8
+ "regexp/grapheme-string-literal": "error",
9
+
10
+ "regexp/hexadecimal-escape": ["error", "never"],
11
+
12
+ "regexp/letter-case": [
13
+ "error",
14
+ {
15
+ caseInsensitive: "lowercase",
16
+ controlEscape: "uppercase",
17
+ hexadecimalEscape: "lowercase",
18
+ unicodeEscape: "lowercase",
19
+ },
20
+ ],
21
+
22
+ "regexp/match-any": ["warn", { allows: ["dotAll", "[\\s\\S]"] }],
23
+
24
+ "regexp/negation": "error",
25
+
26
+ "regexp/no-contradiction-with-assertion": "error",
27
+
28
+ "regexp/no-control-character": "error",
29
+
30
+ "regexp/no-dupe-characters-character-class": "error",
31
+
32
+ "regexp/no-dupe-disjunctions": [
33
+ "warn",
34
+ {
35
+ report: "all",
36
+ reportExponentialBacktracking: "potential",
37
+ reportUnreachable: "potential",
38
+ },
39
+ ],
40
+
41
+ "regexp/no-empty-alternative": "error",
42
+
43
+ "regexp/no-empty-capturing-group": "error",
44
+
45
+ // eslint-disable-next-line sort-keys
46
+ "no-empty-character-class": "off",
47
+ "regexp/no-empty-character-class": "error",
48
+
49
+ "regexp/no-empty-group": "error",
50
+
51
+ "regexp/no-empty-lookarounds-assertion": "error",
52
+
53
+ "regexp/no-empty-string-literal": "error",
54
+
55
+ "regexp/no-escape-backspace": "warn",
56
+
57
+ "regexp/no-extra-lookaround-assertions": "error",
58
+
59
+ // eslint-disable-next-line sort-keys
60
+ "no-invalid-regexp": "off",
61
+ "regexp/no-invalid-regexp": "error",
62
+
63
+ "regexp/no-invisible-character": "error",
64
+
65
+ "regexp/no-lazy-ends": ["error", { ignorePartial: false }],
66
+
67
+ "regexp/no-legacy-features": "error",
68
+
69
+ "regexp/no-misleading-capturing-group": [
70
+ "warn",
71
+ { reportBacktrackingEnds: true },
72
+ ],
73
+
74
+ // eslint-disable-next-line sort-keys
75
+ "no-misleading-character-class": "off",
76
+ "regexp/no-misleading-unicode-character": ["error", { fixable: false }],
77
+
78
+ "regexp/no-missing-g-flag": ["error", { strictTypes: true }],
79
+
80
+ "regexp/no-non-standard-flag": "error",
81
+
82
+ // This probably can be enabled, but it seems too disruptive
83
+ "regexp/no-obscure-range": "off",
84
+
85
+ "regexp/no-octal": "error",
86
+
87
+ "regexp/no-optional-assertion": "error",
88
+
89
+ "regexp/no-potentially-useless-backreference": "warn",
90
+
91
+ "regexp/no-standalone-backslash": "error",
92
+
93
+ "regexp/no-super-linear-backtracking": ["warn", { report: "potential" }],
94
+
95
+ "regexp/no-super-linear-move": [
96
+ "warn",
97
+ { ignorePartial: false, ignoreSticky: false, report: "potential" },
98
+ ],
99
+
100
+ "regexp/no-trivially-nested-assertion": "error",
101
+
102
+ "regexp/no-trivially-nested-quantifier": "error",
103
+
104
+ "regexp/no-unused-capturing-group": "warn",
105
+
106
+ "regexp/no-useless-assertions": "error",
107
+
108
+ // eslint-disable-next-line sort-keys
109
+ "no-useless-backreference": "off",
110
+ "regexp/no-useless-backreference": "error",
111
+
112
+ "regexp/no-useless-character-class": ["error", { ignores: [] }],
113
+
114
+ "regexp/no-useless-dollar-replacements": "error",
115
+
116
+ "regexp/no-useless-escape": "error",
117
+
118
+ "regexp/no-useless-flag": "error",
119
+
120
+ "regexp/no-useless-lazy": "error",
121
+
122
+ "regexp/no-useless-non-capturing-group": ["error", { allowTop: "never" }],
123
+
124
+ "regexp/no-useless-quantifier": "error",
125
+
126
+ "regexp/no-useless-range": "error",
127
+
128
+ "regexp/no-useless-set-operand": "error",
129
+
130
+ "regexp/no-useless-string-literal": "error",
131
+
132
+ "regexp/no-useless-two-nums-quantifier": "error",
133
+
134
+ "regexp/no-zero-quantifier": "error",
135
+
136
+ "regexp/optimal-lookaround-quantifier": "error",
137
+
138
+ "regexp/optimal-quantifier-concatenation": [
139
+ "error",
140
+ { capturingGroups: "report" },
141
+ ],
142
+
143
+ "regexp/prefer-character-class": ["error", { minAlternatives: 2 }],
144
+
145
+ "regexp/prefer-d": ["error", { insideCharacterClass: "d" }],
146
+
147
+ "regexp/prefer-escape-replacement-dollar-char": "error",
148
+
149
+ "regexp/prefer-lookaround": ["error", { lookbehind: true }],
150
+
151
+ "regexp/prefer-named-backreference": "error",
152
+
153
+ // eslint-disable-next-line sort-keys
154
+ "prefer-named-capture-group": "off",
155
+ "regexp/prefer-named-capture-group": "error",
156
+
157
+ "regexp/prefer-named-replacement": "error",
158
+
159
+ "regexp/prefer-plus-quantifier": "error",
160
+
161
+ "regexp/prefer-predefined-assertion": "error",
162
+
163
+ // We disable no-regex-spaces too
164
+ "regexp/prefer-quantifier": "off",
165
+
166
+ "regexp/prefer-question-quantifier": "error",
167
+
168
+ "regexp/prefer-range": "error",
169
+
170
+ // Shadowed by @typescript-eslint/prefer-regexp-exec
171
+ "regexp/prefer-regexp-exec": "off",
172
+
173
+ "regexp/prefer-regexp-test": "warn",
174
+
175
+ "regexp/prefer-result-array-groups": "warn",
176
+
177
+ "regexp/prefer-set-operation": "error",
178
+
179
+ "regexp/prefer-star-quantifier": "error",
180
+
181
+ "regexp/prefer-unicode-codepoint-escapes": "error",
182
+
183
+ "regexp/prefer-w": "error",
184
+
185
+ "require-unicode-regexp": "off",
186
+ // eslint-disable-next-line sort-keys
187
+ "regexp/require-unicode-regexp": "error",
188
+
189
+ // Maybe in the future?
190
+ "regexp/require-unicode-sets-regexp": "off",
191
+
192
+ "regexp/simplify-set-operations": "error",
193
+
194
+ "regexp/sort-alternatives": 0,
195
+
196
+ "regexp/sort-character-class-elements": 0,
197
+
198
+ "regexp/sort-flags": "error",
199
+
200
+ "regexp/strict": "error",
201
+
202
+ "regexp/unicode-escape": ["error", "unicodeEscape"],
203
+
204
+ "regexp/use-ignore-case": "error",
205
+ },
206
+ };