@codelaw/rules-js 0.0.0-stage → 0.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.
Files changed (91) hide show
  1. package/LICENSE +23 -0
  2. package/NOTICE +10 -0
  3. package/README.md +57 -2
  4. package/codelaw-pack.toml +6 -0
  5. package/corpus.toml +76 -0
  6. package/data/globals/browser.json +1209 -0
  7. package/data/globals/commonjs.json +6 -0
  8. package/data/globals/jest.json +15 -0
  9. package/data/globals/mocha.json +22 -0
  10. package/data/globals/node.json +83 -0
  11. package/data/globals/serviceworker.json +328 -0
  12. package/data/globals/shared-node-browser.json +73 -0
  13. package/data/globals/vitest.json +19 -0
  14. package/data/globals/worker.json +349 -0
  15. package/package.json +14 -4
  16. package/presets/js/conventions.toml +6 -0
  17. package/presets/js/project.toml +4 -0
  18. package/presets/js/recommended.toml +67 -0
  19. package/presets/js/typescript.toml +7 -0
  20. package/rules/graph/no-unused-exports.md +135 -0
  21. package/rules/js/constructor-super.md +77 -0
  22. package/rules/js/exports-at-end.md +134 -0
  23. package/rules/js/for-direction.md +106 -0
  24. package/rules/js/getter-return.md +74 -0
  25. package/rules/js/import-groups.md +117 -0
  26. package/rules/js/no-async-promise-executor.md +95 -0
  27. package/rules/js/no-case-declarations.md +134 -0
  28. package/rules/js/no-class-assign.md +61 -0
  29. package/rules/js/no-compare-neg-zero.md +105 -0
  30. package/rules/js/no-cond-assign.md +135 -0
  31. package/rules/js/no-const-assign.md +61 -0
  32. package/rules/js/no-constant-binary-expression.md +83 -0
  33. package/rules/js/no-constant-condition.md +150 -0
  34. package/rules/js/no-control-regex.md +84 -0
  35. package/rules/js/no-debugger.md +99 -0
  36. package/rules/js/no-default-export.md +88 -0
  37. package/rules/js/no-delete-var.md +93 -0
  38. package/rules/js/no-dupe-args.md +61 -0
  39. package/rules/js/no-dupe-class-members.md +82 -0
  40. package/rules/js/no-dupe-else-if.md +113 -0
  41. package/rules/js/no-dupe-keys.md +66 -0
  42. package/rules/js/no-duplicate-case.md +137 -0
  43. package/rules/js/no-empty-character-class.md +98 -0
  44. package/rules/js/no-empty-pattern.md +86 -0
  45. package/rules/js/no-empty-static-block.md +99 -0
  46. package/rules/js/no-empty.md +116 -0
  47. package/rules/js/no-ex-assign.md +121 -0
  48. package/rules/js/no-extra-boolean-cast.md +107 -0
  49. package/rules/js/no-fallthrough.md +178 -0
  50. package/rules/js/no-func-assign.md +62 -0
  51. package/rules/js/no-global-assign.md +85 -0
  52. package/rules/js/no-import-assign.md +60 -0
  53. package/rules/js/no-invalid-regexp.md +86 -0
  54. package/rules/js/no-irregular-whitespace.md +87 -0
  55. package/rules/js/no-loss-of-precision.md +82 -0
  56. package/rules/js/no-misleading-character-class.md +83 -0
  57. package/rules/js/no-new-native-nonconstructor.md +55 -0
  58. package/rules/js/no-nonoctal-decimal-escape.md +84 -0
  59. package/rules/js/no-obj-calls.md +61 -0
  60. package/rules/js/no-octal.md +84 -0
  61. package/rules/js/no-prototype-builtins.md +99 -0
  62. package/rules/js/no-redeclare.md +61 -0
  63. package/rules/js/no-regex-spaces.md +75 -0
  64. package/rules/js/no-self-assign.md +91 -0
  65. package/rules/js/no-setter-return.md +69 -0
  66. package/rules/js/no-shadow-restricted-names.md +102 -0
  67. package/rules/js/no-sparse-arrays.md +82 -0
  68. package/rules/js/no-this-before-super.md +74 -0
  69. package/rules/js/no-unassigned-vars.md +102 -0
  70. package/rules/js/no-undef.md +76 -0
  71. package/rules/js/no-unexpected-multiline.md +91 -0
  72. package/rules/js/no-unreachable.md +59 -0
  73. package/rules/js/no-unsafe-finally.md +145 -0
  74. package/rules/js/no-unsafe-negation.md +71 -0
  75. package/rules/js/no-unsafe-optional-chaining.md +83 -0
  76. package/rules/js/no-unused-labels.md +102 -0
  77. package/rules/js/no-unused-private-class-members.md +126 -0
  78. package/rules/js/no-unused-vars.md +69 -0
  79. package/rules/js/no-useless-assignment.md +115 -0
  80. package/rules/js/no-useless-backreference.md +83 -0
  81. package/rules/js/no-useless-catch.md +105 -0
  82. package/rules/js/no-useless-escape.md +81 -0
  83. package/rules/js/no-var.md +76 -0
  84. package/rules/js/no-with.md +60 -0
  85. package/rules/js/prefer-const.md +83 -0
  86. package/rules/js/prefer-rest-params.md +103 -0
  87. package/rules/js/prefer-spread.md +95 -0
  88. package/rules/js/preserve-caught-error.md +122 -0
  89. package/rules/js/require-yield.md +107 -0
  90. package/rules/js/use-isnan.md +105 -0
  91. package/rules/js/valid-typeof.md +111 -0
@@ -0,0 +1,86 @@
1
+ ---
2
+ id: js/no-empty-pattern
3
+ title: "No empty destructuring patterns"
4
+ languages: [javascript, jsx, typescript, tsx]
5
+ fix: manual
6
+ fix_reason: "what the pattern was meant to bind needs the author"
7
+ stability: preview
8
+ ported_from: [eslint/no-empty-pattern]
9
+ since: 0.1.0
10
+ ---
11
+
12
+ A destructuring pattern names at least one binding.
13
+
14
+ **Why:** `const {} = obj` binds nothing; it's usually a mistyped default such as `{ a = {} }`.
15
+
16
+ ```codelaw
17
+ match:
18
+ any:
19
+ - kind: object_pattern
20
+ regex: ^\{\s*\}$
21
+ - kind: array_pattern
22
+ regex: ^\[\s*\]$
23
+ message: "This destructuring pattern binds nothing"
24
+ ```
25
+
26
+ ## How to fix
27
+
28
+ 1. Name the properties to bind inside the pattern, or remove it.
29
+
30
+ ## Examples
31
+
32
+ ### JavaScript
33
+
34
+ #### Don't
35
+
36
+ ```js
37
+ const { a: {} } = options;
38
+ ```
39
+
40
+ #### Do
41
+
42
+ ```js
43
+ const { a = {} } = options;
44
+ ```
45
+
46
+ ### JSX
47
+
48
+ #### Don't
49
+
50
+ ```jsx
51
+ const { a: {} } = options;
52
+ ```
53
+
54
+ #### Do
55
+
56
+ ```jsx
57
+ const { a = {} } = options;
58
+ ```
59
+
60
+ ### TypeScript
61
+
62
+ #### Don't
63
+
64
+ ```ts
65
+ const { a: {} } = options;
66
+ ```
67
+
68
+ #### Do
69
+
70
+ ```ts
71
+ const { a = {} } = options;
72
+ ```
73
+
74
+ ### TSX
75
+
76
+ #### Don't
77
+
78
+ ```tsx
79
+ const { a: {} } = options;
80
+ ```
81
+
82
+ #### Do
83
+
84
+ ```tsx
85
+ const { a = {} } = options;
86
+ ```
@@ -0,0 +1,99 @@
1
+ ---
2
+ id: js/no-empty-static-block
3
+ title: "No empty static blocks"
4
+ languages: [javascript, jsx, typescript, tsx]
5
+ fix: auto
6
+ stability: preview
7
+ ported_from: [eslint/no-empty-static-block]
8
+ since: 0.1.0
9
+ ---
10
+
11
+ A class has no empty `static { }` block.
12
+
13
+ **Why:** An empty static block does nothing; it is leftover or unfinished code.
14
+
15
+ ```codelaw
16
+ match:
17
+ kind: class_static_block
18
+ regex: ^static\s*\{\s*\}$
19
+ message: "Empty static block"
20
+ fix: [remove]
21
+ ```
22
+
23
+ ## Examples
24
+
25
+ ### JavaScript
26
+
27
+ #### Don't
28
+
29
+ ```js
30
+ class Config {
31
+ static {}
32
+ load() {}
33
+ }
34
+ ```
35
+
36
+ #### Do
37
+
38
+ ```js
39
+ class Config {
40
+ load() {}
41
+ }
42
+ ```
43
+
44
+ ### JSX
45
+
46
+ #### Don't
47
+
48
+ ```jsx
49
+ class Config {
50
+ static {}
51
+ load() {}
52
+ }
53
+ ```
54
+
55
+ #### Do
56
+
57
+ ```jsx
58
+ class Config {
59
+ load() {}
60
+ }
61
+ ```
62
+
63
+ ### TypeScript
64
+
65
+ #### Don't
66
+
67
+ ```ts
68
+ class Config {
69
+ static {}
70
+ load() {}
71
+ }
72
+ ```
73
+
74
+ #### Do
75
+
76
+ ```ts
77
+ class Config {
78
+ load() {}
79
+ }
80
+ ```
81
+
82
+ ### TSX
83
+
84
+ #### Don't
85
+
86
+ ```tsx
87
+ class Config {
88
+ static {}
89
+ load() {}
90
+ }
91
+ ```
92
+
93
+ #### Do
94
+
95
+ ```tsx
96
+ class Config {
97
+ load() {}
98
+ }
99
+ ```
@@ -0,0 +1,116 @@
1
+ ---
2
+ id: js/no-empty
3
+ title: "No empty blocks"
4
+ languages: [javascript, jsx, typescript, tsx]
5
+ fix: manual
6
+ fix_reason: "whether to fill the block, remove it or document it needs the author"
7
+ stability: preview
8
+ ported_from: [eslint/no-empty]
9
+ since: 0.1.0
10
+ ---
11
+
12
+ A block or `switch` has at least one statement, or a comment saying why it is empty. Function bodies
13
+ may be empty.
14
+
15
+ **Why:** An empty block is usually unfinished code, and an empty `catch` hides errors.
16
+
17
+ ```codelaw
18
+ match:
19
+ any:
20
+ - kind: statement_block
21
+ regex: ^\{\s*\}$
22
+ not:
23
+ inside:
24
+ stopBy: neighbor
25
+ any: [{kind: function_declaration}, {kind: function_expression}, {kind: arrow_function}, {kind: method_definition}, {kind: generator_function_declaration}, {kind: generator_function}, { kind: class_static_block }]
26
+ - kind: switch_statement
27
+ has: { field: body, regex: '^\{\s*\}$' }
28
+ message: "Empty block; remove it or say why it's empty"
29
+ ```
30
+
31
+ ## How to fix
32
+
33
+ 1. If the block is unfinished, write its code.
34
+ 2. If it's meant to be empty, put a comment in it saying why.
35
+
36
+ ## Examples
37
+
38
+ ### JavaScript
39
+
40
+ #### Don't
41
+
42
+ ```js
43
+ try {
44
+ load();
45
+ } catch (e) {}
46
+ ```
47
+
48
+ #### Do
49
+
50
+ ```js
51
+ try {
52
+ load();
53
+ } catch (e) {
54
+ // The cache is optional: a failed load is not an error.
55
+ }
56
+ ```
57
+
58
+ ### JSX
59
+
60
+ #### Don't
61
+
62
+ ```jsx
63
+ try {
64
+ load();
65
+ } catch (e) {}
66
+ ```
67
+
68
+ #### Do
69
+
70
+ ```jsx
71
+ try {
72
+ load();
73
+ } catch (e) {
74
+ // The cache is optional: a failed load is not an error.
75
+ }
76
+ ```
77
+
78
+ ### TypeScript
79
+
80
+ #### Don't
81
+
82
+ ```ts
83
+ try {
84
+ load();
85
+ } catch (e) {}
86
+ ```
87
+
88
+ #### Do
89
+
90
+ ```ts
91
+ try {
92
+ load();
93
+ } catch (e) {
94
+ // The cache is optional: a failed load is not an error.
95
+ }
96
+ ```
97
+
98
+ ### TSX
99
+
100
+ #### Don't
101
+
102
+ ```tsx
103
+ try {
104
+ load();
105
+ } catch (e) {}
106
+ ```
107
+
108
+ #### Do
109
+
110
+ ```tsx
111
+ try {
112
+ load();
113
+ } catch (e) {
114
+ // The cache is optional: a failed load is not an error.
115
+ }
116
+ ```
@@ -0,0 +1,121 @@
1
+ ---
2
+ id: js/no-ex-assign
3
+ title: "A caught error is not reassigned"
4
+ languages: [javascript, jsx, typescript, tsx]
5
+ fix: manual
6
+ fix_reason: "where the original error should go is a decision"
7
+ stability: preview
8
+ ported_from: [eslint/no-ex-assign]
9
+ since: 0.1.0
10
+ ---
11
+
12
+ Code doesn't assign a new value to the parameter of a `catch` clause.
13
+
14
+ **Why:** Reassigning the caught error discards it, so nothing can report or rethrow it.
15
+
16
+ ```codelaw
17
+ match:
18
+ kind: identifier
19
+ where:
20
+ $$MATCH: [write, { binding: catch-param }]
21
+ message: "Assigning to the caught error `$$MATCH` loses it"
22
+ ```
23
+
24
+ ## How to fix
25
+
26
+ 1. Use a new variable for the new value.
27
+ 2. Keep the original error, e.g. as `{ cause: err }`.
28
+
29
+ ## Examples
30
+
31
+ ### JavaScript
32
+
33
+ #### Don't
34
+
35
+ ```js
36
+ try {
37
+ load();
38
+ } catch (err) {
39
+ err = new Error("failed");
40
+ throw err;
41
+ }
42
+ ```
43
+
44
+ #### Do
45
+
46
+ ```js
47
+ try {
48
+ load();
49
+ } catch (err) {
50
+ throw new Error("failed", { cause: err });
51
+ }
52
+ ```
53
+
54
+ ### JSX
55
+
56
+ #### Don't
57
+
58
+ ```jsx
59
+ try {
60
+ load();
61
+ } catch (err) {
62
+ err = new Error("failed");
63
+ throw err;
64
+ }
65
+ ```
66
+
67
+ #### Do
68
+
69
+ ```jsx
70
+ try {
71
+ load();
72
+ } catch (err) {
73
+ throw new Error("failed", { cause: err });
74
+ }
75
+ ```
76
+
77
+ ### TypeScript
78
+
79
+ #### Don't
80
+
81
+ ```ts
82
+ try {
83
+ load();
84
+ } catch (err) {
85
+ err = new Error("failed");
86
+ throw err;
87
+ }
88
+ ```
89
+
90
+ #### Do
91
+
92
+ ```ts
93
+ try {
94
+ load();
95
+ } catch (err) {
96
+ throw new Error("failed", { cause: err });
97
+ }
98
+ ```
99
+
100
+ ### TSX
101
+
102
+ #### Don't
103
+
104
+ ```tsx
105
+ try {
106
+ load();
107
+ } catch (err) {
108
+ err = new Error("failed");
109
+ throw err;
110
+ }
111
+ ```
112
+
113
+ #### Do
114
+
115
+ ```tsx
116
+ try {
117
+ load();
118
+ } catch (err) {
119
+ throw new Error("failed", { cause: err });
120
+ }
121
+ ```
@@ -0,0 +1,107 @@
1
+ ---
2
+ id: js/no-extra-boolean-cast
3
+ title: "No needless !! or Boolean() in a condition"
4
+ languages: [javascript, jsx, typescript, tsx]
5
+ fix: auto
6
+ stability: preview
7
+ ported_from: [eslint/no-extra-boolean-cast]
8
+ since: 0.1.0
9
+ ---
10
+
11
+ A condition (`if`, `while`, `do … while`, `? :`) doesn't convert its value with `!!`.
12
+
13
+ **Why:** A condition is already evaluated as a boolean, so `!!` only adds noise.
14
+
15
+ ```codelaw
16
+ match:
17
+ pattern: "!!$X"
18
+ any:
19
+ - inside:
20
+ stopBy: neighbor
21
+ kind: parenthesized_expression
22
+ inside:
23
+ stopBy: neighbor
24
+ any: [{ kind: if_statement }, { kind: while_statement }, { kind: do_statement }]
25
+ field: condition
26
+ - inside: { stopBy: neighbor, kind: ternary_expression, field: condition }
27
+ message: "A condition already converts to boolean; `!!` is redundant"
28
+ fix: "$X"
29
+ ```
30
+
31
+ ## Examples
32
+
33
+ ### JavaScript
34
+
35
+ #### Don't
36
+
37
+ ```js
38
+ if (!!user) {
39
+ greet();
40
+ }
41
+ ```
42
+
43
+ #### Do
44
+
45
+ ```js
46
+ if (user) {
47
+ greet();
48
+ }
49
+ ```
50
+
51
+ ### JSX
52
+
53
+ #### Don't
54
+
55
+ ```jsx
56
+ if (!!user) {
57
+ greet();
58
+ }
59
+ ```
60
+
61
+ #### Do
62
+
63
+ ```jsx
64
+ if (user) {
65
+ greet();
66
+ }
67
+ ```
68
+
69
+ ### TypeScript
70
+
71
+ #### Don't
72
+
73
+ ```ts
74
+ if (!!user) {
75
+ greet();
76
+ }
77
+ ```
78
+
79
+ #### Do
80
+
81
+ ```ts
82
+ if (user) {
83
+ greet();
84
+ }
85
+ ```
86
+
87
+ ### TSX
88
+
89
+ #### Don't
90
+
91
+ ```tsx
92
+ if (!!user) {
93
+ greet();
94
+ }
95
+ ```
96
+
97
+ #### Do
98
+
99
+ ```tsx
100
+ if (user) {
101
+ greet();
102
+ }
103
+ ```
104
+
105
+ ## Differences from the source
106
+
107
+ `Boolean(x)` in a condition is not checked yet.
@@ -0,0 +1,178 @@
1
+ ---
2
+ id: js/no-fallthrough
3
+ title: "A switch case does not fall through into the next by accident"
4
+ languages: [javascript, jsx, typescript, tsx]
5
+ fix: manual
6
+ fix_reason: "whether the fall-through is intended needs the author"
7
+ stability: preview
8
+ ported_from: [eslint/no-fallthrough]
9
+ since: 0.1.0
10
+ ---
11
+
12
+ A `case` with statements ends in `break`, `return`, `throw` or `continue`, or says `// falls
13
+ through` before the next case.
14
+
15
+ **Why:** Falling through is easy to do by accident and hard to see in review.
16
+
17
+ ```codelaw
18
+ native: js/no-fallthrough
19
+ ```
20
+
21
+ ## How to fix
22
+
23
+ 1. If the case should stop, end it with `break` (or `return`).
24
+ 2. If it should fall through, say so with a `// falls through` comment before the next case.
25
+
26
+ ## Examples
27
+
28
+ ### JavaScript
29
+
30
+ #### Don't
31
+
32
+ ```js
33
+ switch (kind) {
34
+ case "a":
35
+ first();
36
+ case "b":
37
+ second();
38
+ break;
39
+ }
40
+ ```
41
+
42
+ #### Do
43
+
44
+ ```js
45
+ switch (kind) {
46
+ case "a":
47
+ first();
48
+ break;
49
+ case "b":
50
+ second();
51
+ break;
52
+ }
53
+ ```
54
+
55
+ ```js
56
+ switch (kind) {
57
+ case "a":
58
+ first();
59
+ // falls through
60
+ case "b":
61
+ second();
62
+ break;
63
+ }
64
+ ```
65
+
66
+ ### JSX
67
+
68
+ #### Don't
69
+
70
+ ```jsx
71
+ switch (kind) {
72
+ case "a":
73
+ first();
74
+ case "b":
75
+ second();
76
+ break;
77
+ }
78
+ ```
79
+
80
+ #### Do
81
+
82
+ ```jsx
83
+ switch (kind) {
84
+ case "a":
85
+ first();
86
+ break;
87
+ case "b":
88
+ second();
89
+ break;
90
+ }
91
+ ```
92
+
93
+ ```jsx
94
+ switch (kind) {
95
+ case "a":
96
+ first();
97
+ // falls through
98
+ case "b":
99
+ second();
100
+ break;
101
+ }
102
+ ```
103
+
104
+ ### TypeScript
105
+
106
+ #### Don't
107
+
108
+ ```ts
109
+ switch (kind) {
110
+ case "a":
111
+ first();
112
+ case "b":
113
+ second();
114
+ break;
115
+ }
116
+ ```
117
+
118
+ #### Do
119
+
120
+ ```ts
121
+ switch (kind) {
122
+ case "a":
123
+ first();
124
+ break;
125
+ case "b":
126
+ second();
127
+ break;
128
+ }
129
+ ```
130
+
131
+ ```ts
132
+ switch (kind) {
133
+ case "a":
134
+ first();
135
+ // falls through
136
+ case "b":
137
+ second();
138
+ break;
139
+ }
140
+ ```
141
+
142
+ ### TSX
143
+
144
+ #### Don't
145
+
146
+ ```tsx
147
+ switch (kind) {
148
+ case "a":
149
+ first();
150
+ case "b":
151
+ second();
152
+ break;
153
+ }
154
+ ```
155
+
156
+ #### Do
157
+
158
+ ```tsx
159
+ switch (kind) {
160
+ case "a":
161
+ first();
162
+ break;
163
+ case "b":
164
+ second();
165
+ break;
166
+ }
167
+ ```
168
+
169
+ ```tsx
170
+ switch (kind) {
171
+ case "a":
172
+ first();
173
+ // falls through
174
+ case "b":
175
+ second();
176
+ break;
177
+ }
178
+ ```