@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,88 @@
1
+ ---
2
+ id: js/no-default-export
3
+ title: "No default exports"
4
+ languages: [javascript, jsx, typescript, tsx]
5
+ fix: manual
6
+ fix_reason: "every importer of the default export must change"
7
+ stability: preview
8
+ since: 0.1.0
9
+ ---
10
+
11
+ Modules export by name; `export default` is not used.
12
+
13
+ **Why:** A named export has one name everywhere, so it can be found, renamed and auto-imported
14
+ reliably.
15
+
16
+ ```codelaw
17
+ match:
18
+ kind: export_statement
19
+ has: { regex: ^default$ }
20
+ message: "Export this by name instead of as the default"
21
+ ```
22
+
23
+ ## How to fix
24
+
25
+ 1. Give the exported value a name and export it with `export { name }`.
26
+ 2. Change every `import x from` of this module to `import { name } from`.
27
+
28
+ ## Examples
29
+
30
+ ### JavaScript
31
+
32
+ #### Don't
33
+
34
+ ```js
35
+ export default function load() {}
36
+ ```
37
+
38
+ #### Do
39
+
40
+ ```js
41
+ function load() {}
42
+ export { load };
43
+ ```
44
+
45
+ ### JSX
46
+
47
+ #### Don't
48
+
49
+ ```jsx
50
+ export default function load() {}
51
+ ```
52
+
53
+ #### Do
54
+
55
+ ```jsx
56
+ function load() {}
57
+ export { load };
58
+ ```
59
+
60
+ ### TypeScript
61
+
62
+ #### Don't
63
+
64
+ ```ts
65
+ export default function load() {}
66
+ ```
67
+
68
+ #### Do
69
+
70
+ ```ts
71
+ function load() {}
72
+ export { load };
73
+ ```
74
+
75
+ ### TSX
76
+
77
+ #### Don't
78
+
79
+ ```tsx
80
+ export default function load() {}
81
+ ```
82
+
83
+ #### Do
84
+
85
+ ```tsx
86
+ function load() {}
87
+ export { load };
88
+ ```
@@ -0,0 +1,93 @@
1
+ ---
2
+ id: js/no-delete-var
3
+ title: "No delete on a variable"
4
+ languages: [javascript, jsx, typescript, tsx]
5
+ fix: manual
6
+ fix_reason: "what the code meant to clear is a decision"
7
+ stability: preview
8
+ ported_from: [eslint/no-delete-var]
9
+ since: 0.1.0
10
+ ---
11
+
12
+ `delete` is applied to object properties, never to a variable.
13
+
14
+ **Why:** Deleting a variable does nothing in sloppy mode and is a syntax error in strict mode.
15
+
16
+ ```codelaw
17
+ match:
18
+ pattern: delete $X
19
+ constraints:
20
+ X: { kind: identifier }
21
+ message: "`delete` works on properties, not on the variable `$X`"
22
+ ```
23
+
24
+ ## How to fix
25
+
26
+ 1. To clear the value, assign `undefined` or a fresh value.
27
+ 2. To remove a property, `delete obj.key`.
28
+
29
+ ## Examples
30
+
31
+ ### JavaScript
32
+
33
+ #### Don't
34
+
35
+ ```js
36
+ let cache = {};
37
+ delete cache;
38
+ ```
39
+
40
+ #### Do
41
+
42
+ ```js
43
+ let cache = {};
44
+ cache = {};
45
+ ```
46
+
47
+ ### JSX
48
+
49
+ #### Don't
50
+
51
+ ```jsx
52
+ let cache = {};
53
+ delete cache;
54
+ ```
55
+
56
+ #### Do
57
+
58
+ ```jsx
59
+ let cache = {};
60
+ cache = {};
61
+ ```
62
+
63
+ ### TypeScript
64
+
65
+ #### Don't
66
+
67
+ ```ts
68
+ let cache = {};
69
+ delete cache;
70
+ ```
71
+
72
+ #### Do
73
+
74
+ ```ts
75
+ let cache = {};
76
+ cache = {};
77
+ ```
78
+
79
+ ### TSX
80
+
81
+ #### Don't
82
+
83
+ ```tsx
84
+ let cache = {};
85
+ delete cache;
86
+ ```
87
+
88
+ #### Do
89
+
90
+ ```tsx
91
+ let cache = {};
92
+ cache = {};
93
+ ```
@@ -0,0 +1,61 @@
1
+ ---
2
+ id: js/no-dupe-args
3
+ title: "No two parameters share a name"
4
+ languages: [javascript, jsx]
5
+ fix: manual
6
+ fix_reason: "which parameter was meant can't be known from the code"
7
+ stability: preview
8
+ ported_from: [eslint/no-dupe-args]
9
+ since: 0.1.0
10
+ ---
11
+
12
+ A function's parameters, destructured ones included, all have different names.
13
+
14
+ **Why:** The later parameter silently hides the earlier one, so one argument can never be read.
15
+
16
+ ```codelaw
17
+ native: js/no-dupe-args
18
+ ```
19
+
20
+ ## How to fix
21
+
22
+ 1. Rename the duplicate parameter.
23
+ 2. Update the body to read the parameter it meant.
24
+
25
+ ## Examples
26
+
27
+ ### JavaScript
28
+
29
+ #### Don't
30
+
31
+ ```js
32
+ function add(a, b, a) {
33
+ return a + b;
34
+ }
35
+ ```
36
+
37
+ #### Do
38
+
39
+ ```js
40
+ function add(a, b, c) {
41
+ return a + b + c;
42
+ }
43
+ ```
44
+
45
+ ### JSX
46
+
47
+ #### Don't
48
+
49
+ ```jsx
50
+ function add(a, b, a) {
51
+ return a + b;
52
+ }
53
+ ```
54
+
55
+ #### Do
56
+
57
+ ```jsx
58
+ function add(a, b, c) {
59
+ return a + b + c;
60
+ }
61
+ ```
@@ -0,0 +1,82 @@
1
+ ---
2
+ id: js/no-dupe-class-members
3
+ title: "No two class members share a name"
4
+ languages: [javascript, jsx]
5
+ fix: manual
6
+ fix_reason: "which of the two members to keep is a decision"
7
+ stability: preview
8
+ ported_from: [eslint/no-dupe-class-members]
9
+ since: 0.1.0
10
+ ---
11
+
12
+ A class declares each method and field name once, separately for static and instance members; a
13
+ getter and a setter may share a name.
14
+
15
+ **Why:** The later declaration replaces the earlier one, so one of them is dead code.
16
+
17
+ ```codelaw
18
+ native: js/no-dupe-class-members
19
+ ```
20
+
21
+ ## How to fix
22
+
23
+ 1. Decide which declaration is right.
24
+ 2. Remove or rename the other.
25
+
26
+ ## Examples
27
+
28
+ ### JavaScript
29
+
30
+ #### Don't
31
+
32
+ ```js
33
+ class Cart {
34
+ total() {
35
+ return 1;
36
+ }
37
+ total() {
38
+ return 2;
39
+ }
40
+ }
41
+ ```
42
+
43
+ #### Do
44
+
45
+ ```js
46
+ class Cart {
47
+ total() {
48
+ return 1;
49
+ }
50
+ subtotal() {
51
+ return 2;
52
+ }
53
+ }
54
+ ```
55
+
56
+ ### JSX
57
+
58
+ #### Don't
59
+
60
+ ```jsx
61
+ class Cart {
62
+ total() {
63
+ return 1;
64
+ }
65
+ total() {
66
+ return 2;
67
+ }
68
+ }
69
+ ```
70
+
71
+ #### Do
72
+
73
+ ```jsx
74
+ class Cart {
75
+ total() {
76
+ return 1;
77
+ }
78
+ subtotal() {
79
+ return 2;
80
+ }
81
+ }
82
+ ```
@@ -0,0 +1,113 @@
1
+ ---
2
+ id: js/no-dupe-else-if
3
+ title: "No two conditions in an if/else-if chain are the same"
4
+ languages: [javascript, jsx, typescript, tsx]
5
+ fix: manual
6
+ fix_reason: "what the second condition should have been is a decision"
7
+ stability: preview
8
+ ported_from: [eslint/no-dupe-else-if]
9
+ since: 0.1.0
10
+ ---
11
+
12
+ Each condition in an `if … else if …` chain is different from the ones before it.
13
+
14
+ **Why:** A repeated condition's branch can never run, because the earlier one already took it.
15
+
16
+ ```codelaw
17
+ native: js/no-dupe-else-if
18
+ ```
19
+
20
+ ## How to fix
21
+
22
+ 1. Find the repeated condition.
23
+ 2. Correct it to the case it was meant to handle, or remove the dead branch.
24
+
25
+ ## Examples
26
+
27
+ ### JavaScript
28
+
29
+ #### Don't
30
+
31
+ ```js
32
+ if (isAdmin) {
33
+ grant();
34
+ } else if (isAdmin) {
35
+ audit();
36
+ }
37
+ ```
38
+
39
+ #### Do
40
+
41
+ ```js
42
+ if (isAdmin) {
43
+ grant();
44
+ } else if (isAuditor) {
45
+ audit();
46
+ }
47
+ ```
48
+
49
+ ### JSX
50
+
51
+ #### Don't
52
+
53
+ ```jsx
54
+ if (isAdmin) {
55
+ grant();
56
+ } else if (isAdmin) {
57
+ audit();
58
+ }
59
+ ```
60
+
61
+ #### Do
62
+
63
+ ```jsx
64
+ if (isAdmin) {
65
+ grant();
66
+ } else if (isAuditor) {
67
+ audit();
68
+ }
69
+ ```
70
+
71
+ ### TypeScript
72
+
73
+ #### Don't
74
+
75
+ ```ts
76
+ if (isAdmin) {
77
+ grant();
78
+ } else if (isAdmin) {
79
+ audit();
80
+ }
81
+ ```
82
+
83
+ #### Do
84
+
85
+ ```ts
86
+ if (isAdmin) {
87
+ grant();
88
+ } else if (isAuditor) {
89
+ audit();
90
+ }
91
+ ```
92
+
93
+ ### TSX
94
+
95
+ #### Don't
96
+
97
+ ```tsx
98
+ if (isAdmin) {
99
+ grant();
100
+ } else if (isAdmin) {
101
+ audit();
102
+ }
103
+ ```
104
+
105
+ #### Do
106
+
107
+ ```tsx
108
+ if (isAdmin) {
109
+ grant();
110
+ } else if (isAuditor) {
111
+ audit();
112
+ }
113
+ ```
@@ -0,0 +1,66 @@
1
+ ---
2
+ id: js/no-dupe-keys
3
+ title: "No two keys in an object literal are the same"
4
+ languages: [javascript, jsx]
5
+ fix: manual
6
+ fix_reason: "which value should win can't be known from the code"
7
+ stability: preview
8
+ ported_from: [eslint/no-dupe-keys]
9
+ since: 0.1.0
10
+ ---
11
+
12
+ An object literal names each key once; `a`, `'a'` and `["a"]` are the same key, as are `1` and
13
+ `0x1`.
14
+
15
+ **Why:** The later value silently replaces the earlier one.
16
+
17
+ ```codelaw
18
+ native: js/no-dupe-keys
19
+ ```
20
+
21
+ ## How to fix
22
+
23
+ 1. Decide which value the key should have.
24
+ 2. Remove the other entry, or give it its own key.
25
+
26
+ ## Examples
27
+
28
+ ### JavaScript
29
+
30
+ #### Don't
31
+
32
+ ```js
33
+ const user = {
34
+ name: "Ada",
35
+ name: "Grace",
36
+ };
37
+ ```
38
+
39
+ #### Do
40
+
41
+ ```js
42
+ const user = {
43
+ name: "Ada",
44
+ nickname: "Grace",
45
+ };
46
+ ```
47
+
48
+ ### JSX
49
+
50
+ #### Don't
51
+
52
+ ```jsx
53
+ const user = {
54
+ name: "Ada",
55
+ name: "Grace",
56
+ };
57
+ ```
58
+
59
+ #### Do
60
+
61
+ ```jsx
62
+ const user = {
63
+ name: "Ada",
64
+ nickname: "Grace",
65
+ };
66
+ ```
@@ -0,0 +1,137 @@
1
+ ---
2
+ id: js/no-duplicate-case
3
+ title: "No two case labels in a switch are the same"
4
+ languages: [javascript, jsx, typescript, tsx]
5
+ fix: manual
6
+ fix_reason: "which label was meant is a decision"
7
+ stability: preview
8
+ ported_from: [eslint/no-duplicate-case]
9
+ since: 0.1.0
10
+ ---
11
+
12
+ Each `case` in a `switch` tests a different expression.
13
+
14
+ **Why:** A repeated case can never match: the first one always wins.
15
+
16
+ ```codelaw
17
+ native: js/no-duplicate-case
18
+ ```
19
+
20
+ ## How to fix
21
+
22
+ 1. Find the label that was meant to test something else.
23
+ 2. Correct it, or merge the two bodies.
24
+
25
+ ## Examples
26
+
27
+ ### JavaScript
28
+
29
+ #### Don't
30
+
31
+ ```js
32
+ switch (status) {
33
+ case 200:
34
+ ok();
35
+ break;
36
+ case 200:
37
+ retry();
38
+ break;
39
+ }
40
+ ```
41
+
42
+ #### Do
43
+
44
+ ```js
45
+ switch (status) {
46
+ case 200:
47
+ ok();
48
+ break;
49
+ case 503:
50
+ retry();
51
+ break;
52
+ }
53
+ ```
54
+
55
+ ### JSX
56
+
57
+ #### Don't
58
+
59
+ ```jsx
60
+ switch (status) {
61
+ case 200:
62
+ ok();
63
+ break;
64
+ case 200:
65
+ retry();
66
+ break;
67
+ }
68
+ ```
69
+
70
+ #### Do
71
+
72
+ ```jsx
73
+ switch (status) {
74
+ case 200:
75
+ ok();
76
+ break;
77
+ case 503:
78
+ retry();
79
+ break;
80
+ }
81
+ ```
82
+
83
+ ### TypeScript
84
+
85
+ #### Don't
86
+
87
+ ```ts
88
+ switch (status) {
89
+ case 200:
90
+ ok();
91
+ break;
92
+ case 200:
93
+ retry();
94
+ break;
95
+ }
96
+ ```
97
+
98
+ #### Do
99
+
100
+ ```ts
101
+ switch (status) {
102
+ case 200:
103
+ ok();
104
+ break;
105
+ case 503:
106
+ retry();
107
+ break;
108
+ }
109
+ ```
110
+
111
+ ### TSX
112
+
113
+ #### Don't
114
+
115
+ ```tsx
116
+ switch (status) {
117
+ case 200:
118
+ ok();
119
+ break;
120
+ case 200:
121
+ retry();
122
+ break;
123
+ }
124
+ ```
125
+
126
+ #### Do
127
+
128
+ ```tsx
129
+ switch (status) {
130
+ case 200:
131
+ ok();
132
+ break;
133
+ case 503:
134
+ retry();
135
+ break;
136
+ }
137
+ ```
@@ -0,0 +1,98 @@
1
+ ---
2
+ id: js/no-empty-character-class
3
+ title: "No empty character classes in regular expressions"
4
+ languages: [javascript, jsx, typescript, tsx]
5
+ fix: manual
6
+ fix_reason: "which characters the class should hold needs the author"
7
+ stability: preview
8
+ ported_from: [eslint/no-empty-character-class]
9
+ since: 0.1.0
10
+ ---
11
+
12
+ A regular expression contains no empty character class `[]`; `[^]`, which matches any character, is
13
+ fine.
14
+
15
+ **Why:** `[]` matches no character at all, so the whole pattern can never match.
16
+
17
+ ```codelaw
18
+ native: js/no-empty-character-class
19
+ ```
20
+
21
+ ## How to fix
22
+
23
+ 1. Put the characters the class should match inside it.
24
+ 2. If `[]` was meant literally, escape it: `\[\]`.
25
+
26
+ ## Examples
27
+
28
+ ### JavaScript
29
+
30
+ #### Don't
31
+
32
+ ```js
33
+ const re = /^abc[]/;
34
+ ```
35
+
36
+ #### Do
37
+
38
+ ```js
39
+ const re = /^abc[a-z]/;
40
+ ```
41
+
42
+ ```js
43
+ const brackets = /^\s*[{[]/;
44
+ ```
45
+
46
+ ### JSX
47
+
48
+ #### Don't
49
+
50
+ ```jsx
51
+ const re = /^abc[]/;
52
+ ```
53
+
54
+ #### Do
55
+
56
+ ```jsx
57
+ const re = /^abc[a-z]/;
58
+ ```
59
+
60
+ ```jsx
61
+ const brackets = /^\s*[{[]/;
62
+ ```
63
+
64
+ ### TypeScript
65
+
66
+ #### Don't
67
+
68
+ ```ts
69
+ const re = /^abc[]/;
70
+ ```
71
+
72
+ #### Do
73
+
74
+ ```ts
75
+ const re = /^abc[a-z]/;
76
+ ```
77
+
78
+ ```ts
79
+ const brackets = /^\s*[{[]/;
80
+ ```
81
+
82
+ ### TSX
83
+
84
+ #### Don't
85
+
86
+ ```tsx
87
+ const re = /^abc[]/;
88
+ ```
89
+
90
+ #### Do
91
+
92
+ ```tsx
93
+ const re = /^abc[a-z]/;
94
+ ```
95
+
96
+ ```tsx
97
+ const brackets = /^\s*[{[]/;
98
+ ```