@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,76 @@
1
+ ---
2
+ id: js/no-var
3
+ title: "let or const instead of var"
4
+ languages: [javascript, jsx, typescript, tsx]
5
+ fix: suggest
6
+ fix_reason: "`let` is block-scoped, so a `var` used outside its block or before its declaration changes meaning"
7
+ stability: preview
8
+ ported_from: [eslint/no-var]
9
+ since: 0.1.0
10
+ ---
11
+
12
+ Variables are declared with `let` or `const`, never `var`.
13
+
14
+ **Why:** `var` is function-scoped and hoisted, which causes bugs `let` and `const` rule out.
15
+
16
+ ```codelaw
17
+ native: js/no-var
18
+ ```
19
+
20
+ ## Examples
21
+
22
+ ### JavaScript
23
+
24
+ #### Don't
25
+
26
+ ```js
27
+ var total = 0;
28
+ ```
29
+
30
+ #### Do
31
+
32
+ ```js
33
+ let total = 0;
34
+ ```
35
+
36
+ ### JSX
37
+
38
+ #### Don't
39
+
40
+ ```jsx
41
+ var total = 0;
42
+ ```
43
+
44
+ #### Do
45
+
46
+ ```jsx
47
+ let total = 0;
48
+ ```
49
+
50
+ ### TypeScript
51
+
52
+ #### Don't
53
+
54
+ ```ts
55
+ var total = 0;
56
+ ```
57
+
58
+ #### Do
59
+
60
+ ```ts
61
+ let total = 0;
62
+ ```
63
+
64
+ ### TSX
65
+
66
+ #### Don't
67
+
68
+ ```tsx
69
+ var total = 0;
70
+ ```
71
+
72
+ #### Do
73
+
74
+ ```tsx
75
+ let total = 0;
76
+ ```
@@ -0,0 +1,60 @@
1
+ ---
2
+ id: js/no-with
3
+ title: "No with statements"
4
+ languages: [javascript, jsx]
5
+ fix: manual
6
+ fix_reason: "each name inside needs to be qualified by hand"
7
+ stability: preview
8
+ ported_from: [eslint/no-with]
9
+ since: 0.1.0
10
+ ---
11
+
12
+ Code doesn't use `with`.
13
+
14
+ **Why:** `with` makes it impossible to tell which names are properties and which are variables, and
15
+ is an error in strict code.
16
+
17
+ ```codelaw
18
+ match:
19
+ kind: with_statement
20
+ message: "`with` makes every name inside it ambiguous"
21
+ ```
22
+
23
+ ## How to fix
24
+
25
+ 1. Replace each property used inside `with` by `object.property`.
26
+ 2. Remove the `with`.
27
+
28
+ ## Examples
29
+
30
+ ### JavaScript
31
+
32
+ #### Don't
33
+
34
+ ```js
35
+ with (Math) {
36
+ area = PI * r * r;
37
+ }
38
+ ```
39
+
40
+ #### Do
41
+
42
+ ```js
43
+ area = Math.PI * r * r;
44
+ ```
45
+
46
+ ### JSX
47
+
48
+ #### Don't
49
+
50
+ ```jsx
51
+ with (Math) {
52
+ area = PI * r * r;
53
+ }
54
+ ```
55
+
56
+ #### Do
57
+
58
+ ```jsx
59
+ area = Math.PI * r * r;
60
+ ```
@@ -0,0 +1,83 @@
1
+ ---
2
+ id: js/prefer-const
3
+ title: "const for variables that are never reassigned"
4
+ languages: [javascript, jsx, typescript, tsx]
5
+ fix: auto
6
+ stability: preview
7
+ ported_from: [eslint/prefer-const]
8
+ since: 0.1.0
9
+ ---
10
+
11
+ A `let` whose names all get their value in the declaration and are never reassigned is a `const`.
12
+
13
+ **Why:** `const` tells the reader the binding won't change, and the engine enforces it.
14
+
15
+ ```codelaw
16
+ native: js/prefer-const
17
+ ```
18
+
19
+ ## Examples
20
+
21
+ ### JavaScript
22
+
23
+ #### Don't
24
+
25
+ ```js
26
+ let limit = 10;
27
+ use(limit);
28
+ ```
29
+
30
+ #### Do
31
+
32
+ ```js
33
+ const limit = 10;
34
+ use(limit);
35
+ ```
36
+
37
+ ### JSX
38
+
39
+ #### Don't
40
+
41
+ ```jsx
42
+ let limit = 10;
43
+ use(limit);
44
+ ```
45
+
46
+ #### Do
47
+
48
+ ```jsx
49
+ const limit = 10;
50
+ use(limit);
51
+ ```
52
+
53
+ ### TypeScript
54
+
55
+ #### Don't
56
+
57
+ ```ts
58
+ let limit = 10;
59
+ use(limit);
60
+ ```
61
+
62
+ #### Do
63
+
64
+ ```ts
65
+ const limit = 10;
66
+ use(limit);
67
+ ```
68
+
69
+ ### TSX
70
+
71
+ #### Don't
72
+
73
+ ```tsx
74
+ let limit = 10;
75
+ use(limit);
76
+ ```
77
+
78
+ #### Do
79
+
80
+ ```tsx
81
+ const limit = 10;
82
+ use(limit);
83
+ ```
@@ -0,0 +1,103 @@
1
+ ---
2
+ id: js/prefer-rest-params
3
+ title: "Rest parameters instead of arguments"
4
+ languages: [javascript, jsx, typescript, tsx]
5
+ fix: manual
6
+ fix_reason: "the parameter list has to be rewritten by hand"
7
+ stability: preview
8
+ ported_from: [eslint/prefer-rest-params]
9
+ since: 0.1.0
10
+ ---
11
+
12
+ Functions take a rest parameter `...args` instead of reading `arguments`.
13
+
14
+ **Why:** `arguments` is not a real array, isn't available in arrow functions, and hides how many
15
+ arguments a function takes.
16
+
17
+ ```codelaw
18
+ match:
19
+ kind: identifier
20
+ regex: ^arguments$
21
+ where:
22
+ $$MATCH: builtin
23
+ message: "Use a rest parameter (`...args`) instead of `arguments`"
24
+ ```
25
+
26
+ ## How to fix
27
+
28
+ 1. Add a rest parameter `...args` to the function.
29
+ 2. Replace each use of `arguments` with it.
30
+
31
+ ## Examples
32
+
33
+ ### JavaScript
34
+
35
+ #### Don't
36
+
37
+ ```js
38
+ function sum() {
39
+ return Array.from(arguments).reduce(add, 0);
40
+ }
41
+ ```
42
+
43
+ #### Do
44
+
45
+ ```js
46
+ function sum(...numbers) {
47
+ return numbers.reduce(add, 0);
48
+ }
49
+ ```
50
+
51
+ ### JSX
52
+
53
+ #### Don't
54
+
55
+ ```jsx
56
+ function sum() {
57
+ return Array.from(arguments).reduce(add, 0);
58
+ }
59
+ ```
60
+
61
+ #### Do
62
+
63
+ ```jsx
64
+ function sum(...numbers) {
65
+ return numbers.reduce(add, 0);
66
+ }
67
+ ```
68
+
69
+ ### TypeScript
70
+
71
+ #### Don't
72
+
73
+ ```ts
74
+ function sum() {
75
+ return Array.from(arguments).reduce(add, 0);
76
+ }
77
+ ```
78
+
79
+ #### Do
80
+
81
+ ```ts
82
+ function sum(...numbers) {
83
+ return numbers.reduce(add, 0);
84
+ }
85
+ ```
86
+
87
+ ### TSX
88
+
89
+ #### Don't
90
+
91
+ ```tsx
92
+ function sum() {
93
+ return Array.from(arguments).reduce(add, 0);
94
+ }
95
+ ```
96
+
97
+ #### Do
98
+
99
+ ```tsx
100
+ function sum(...numbers) {
101
+ return numbers.reduce(add, 0);
102
+ }
103
+ ```
@@ -0,0 +1,95 @@
1
+ ---
2
+ id: js/prefer-spread
3
+ title: "Spread instead of .apply()"
4
+ languages: [javascript, jsx, typescript, tsx]
5
+ fix: auto
6
+ stability: preview
7
+ ported_from: [eslint/prefer-spread]
8
+ since: 0.1.0
9
+ ---
10
+
11
+ A function is called with spread arguments, `f(...args)`, instead of `f.apply(null, args)`.
12
+
13
+ **Why:** Spread says the same thing more directly, and doesn't need a `this` value.
14
+
15
+ ```codelaw
16
+ match:
17
+ any:
18
+ - pattern: $F.apply(null, $ARGS)
19
+ - pattern: $F.apply(undefined, $ARGS)
20
+ constraints:
21
+ F: { kind: identifier }
22
+ message: "Use spread: `$F(...$ARGS)`"
23
+ fix: "$F(...$ARGS)"
24
+ ```
25
+
26
+ ## Examples
27
+
28
+ ### JavaScript
29
+
30
+ #### Don't
31
+
32
+ ```js
33
+ const max = Math.max.apply(null, values);
34
+ const min = least.apply(null, values);
35
+ ```
36
+
37
+ #### Do
38
+
39
+ ```js
40
+ const max = Math.max.apply(null, values);
41
+ const min = least(...values);
42
+ ```
43
+
44
+ ### JSX
45
+
46
+ #### Don't
47
+
48
+ ```jsx
49
+ const max = Math.max.apply(null, values);
50
+ const min = least.apply(null, values);
51
+ ```
52
+
53
+ #### Do
54
+
55
+ ```jsx
56
+ const max = Math.max.apply(null, values);
57
+ const min = least(...values);
58
+ ```
59
+
60
+ ### TypeScript
61
+
62
+ #### Don't
63
+
64
+ ```ts
65
+ const max = Math.max.apply(null, values);
66
+ const min = least.apply(null, values);
67
+ ```
68
+
69
+ #### Do
70
+
71
+ ```ts
72
+ const max = Math.max.apply(null, values);
73
+ const min = least(...values);
74
+ ```
75
+
76
+ ### TSX
77
+
78
+ #### Don't
79
+
80
+ ```tsx
81
+ const max = Math.max.apply(null, values);
82
+ const min = least.apply(null, values);
83
+ ```
84
+
85
+ #### Do
86
+
87
+ ```tsx
88
+ const max = Math.max.apply(null, values);
89
+ const min = least(...values);
90
+ ```
91
+
92
+ ## Differences from the source
93
+
94
+ Only `f.apply(null, args)` and `f.apply(undefined, args)` on a plain function name are checked;
95
+ method calls are left alone.
@@ -0,0 +1,122 @@
1
+ ---
2
+ id: js/preserve-caught-error
3
+ title: "A rethrown error keeps the caught one as its cause"
4
+ languages: [javascript, jsx, typescript, tsx]
5
+ fix: suggest
6
+ fix_reason: "the new error class must accept an options argument"
7
+ stability: preview
8
+ ported_from: [eslint/preserve-caught-error]
9
+ since: 0.1.0
10
+ ---
11
+
12
+ A built-in error (`Error`, `TypeError` and the rest) thrown from a `catch` block passes the caught
13
+ error as `{ cause }`.
14
+
15
+ **Why:** Without the cause, the original error and its stack are lost.
16
+
17
+ ```codelaw
18
+ match:
19
+ pattern: throw new $C($MSG);
20
+ inside:
21
+ kind: catch_clause
22
+ has: { field: parameter, pattern: $E }
23
+ stopBy:
24
+ any: [{kind: function_declaration}, {kind: function_expression}, {kind: arrow_function}, {kind: method_definition}, {kind: generator_function_declaration}, {kind: generator_function}]
25
+ constraints:
26
+ C: { regex: ^(Error|TypeError|RangeError|ReferenceError|SyntaxError|URIError|EvalError)$ }
27
+ MSG: { not: { kind: object } }
28
+ where:
29
+ $C: builtin
30
+ message: "Pass the caught error as the cause: `new $C($MSG, { cause: $E })`"
31
+ fix: "throw new $C($MSG, { cause: $E });"
32
+ ```
33
+
34
+ ## Examples
35
+
36
+ ### JavaScript
37
+
38
+ #### Don't
39
+
40
+ ```js
41
+ try {
42
+ load();
43
+ } catch (err) {
44
+ throw new Error("Load failed");
45
+ }
46
+ ```
47
+
48
+ #### Do
49
+
50
+ ```js
51
+ try {
52
+ load();
53
+ } catch (err) {
54
+ throw new Error("Load failed", { cause: err });
55
+ }
56
+ ```
57
+
58
+ ### JSX
59
+
60
+ #### Don't
61
+
62
+ ```jsx
63
+ try {
64
+ load();
65
+ } catch (err) {
66
+ throw new Error("Load failed");
67
+ }
68
+ ```
69
+
70
+ #### Do
71
+
72
+ ```jsx
73
+ try {
74
+ load();
75
+ } catch (err) {
76
+ throw new Error("Load failed", { cause: err });
77
+ }
78
+ ```
79
+
80
+ ### TypeScript
81
+
82
+ #### Don't
83
+
84
+ ```ts
85
+ try {
86
+ load();
87
+ } catch (err) {
88
+ throw new Error("Load failed");
89
+ }
90
+ ```
91
+
92
+ #### Do
93
+
94
+ ```ts
95
+ try {
96
+ load();
97
+ } catch (err) {
98
+ throw new Error("Load failed", { cause: err });
99
+ }
100
+ ```
101
+
102
+ ### TSX
103
+
104
+ #### Don't
105
+
106
+ ```tsx
107
+ try {
108
+ load();
109
+ } catch (err) {
110
+ throw new Error("Load failed");
111
+ }
112
+ ```
113
+
114
+ #### Do
115
+
116
+ ```tsx
117
+ try {
118
+ load();
119
+ } catch (err) {
120
+ throw new Error("Load failed", { cause: err });
121
+ }
122
+ ```
@@ -0,0 +1,107 @@
1
+ ---
2
+ id: js/require-yield
3
+ title: "A generator function yields"
4
+ languages: [javascript, jsx, typescript, tsx]
5
+ fix: manual
6
+ fix_reason: "whether to yield or to drop the `*` needs the author"
7
+ stability: preview
8
+ ported_from: [eslint/require-yield]
9
+ since: 0.1.0
10
+ ---
11
+
12
+ A non-empty generator function contains at least one `yield`.
13
+
14
+ **Why:** A generator without `yield` is either unfinished or should be a plain function.
15
+
16
+ ```codelaw
17
+ match:
18
+ any:
19
+ - kind: generator_function_declaration
20
+ - kind: generator_function
21
+ not:
22
+ any:
23
+ - has: { field: body, regex: '^\{\s*\}$' }
24
+ - has:
25
+ kind: yield_expression
26
+ stopBy:
27
+ any: [{kind: function_declaration}, {kind: function_expression}, {kind: arrow_function}, {kind: method_definition}, {kind: generator_function_declaration}, {kind: generator_function}]
28
+ message: "A generator that never yields is a plain function"
29
+ ```
30
+
31
+ ## How to fix
32
+
33
+ 1. Add the `yield` the generator was meant to have, or remove the `*`.
34
+
35
+ ## Examples
36
+
37
+ ### JavaScript
38
+
39
+ #### Don't
40
+
41
+ ```js
42
+ function* ids() {
43
+ return 1;
44
+ }
45
+ ```
46
+
47
+ #### Do
48
+
49
+ ```js
50
+ function* ids() {
51
+ yield 1;
52
+ }
53
+ ```
54
+
55
+ ### JSX
56
+
57
+ #### Don't
58
+
59
+ ```jsx
60
+ function* ids() {
61
+ return 1;
62
+ }
63
+ ```
64
+
65
+ #### Do
66
+
67
+ ```jsx
68
+ function* ids() {
69
+ yield 1;
70
+ }
71
+ ```
72
+
73
+ ### TypeScript
74
+
75
+ #### Don't
76
+
77
+ ```ts
78
+ function* ids() {
79
+ return 1;
80
+ }
81
+ ```
82
+
83
+ #### Do
84
+
85
+ ```ts
86
+ function* ids() {
87
+ yield 1;
88
+ }
89
+ ```
90
+
91
+ ### TSX
92
+
93
+ #### Don't
94
+
95
+ ```tsx
96
+ function* ids() {
97
+ return 1;
98
+ }
99
+ ```
100
+
101
+ #### Do
102
+
103
+ ```tsx
104
+ function* ids() {
105
+ yield 1;
106
+ }
107
+ ```