@codelaw/rules-js 0.1.0 → 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 (82) hide show
  1. package/NOTICE +0 -9
  2. package/README.md +14 -47
  3. package/codelaw-pack.toml +3 -3
  4. package/corpus.toml +76 -0
  5. package/package.json +2 -2
  6. package/presets/js/conventions.toml +0 -4
  7. package/presets/js/project.toml +4 -0
  8. package/presets/js/typescript.toml +7 -0
  9. package/data/node/deprecated-api.json +0 -83
  10. package/data/react/dom-property-aliases.json +0 -131
  11. package/presets/node/recommended.toml +0 -13
  12. package/presets/react/recommended.toml +0 -22
  13. package/presets/stencil/recommended.toml +0 -18
  14. package/presets/ts/recommended.toml +0 -27
  15. package/rules/node/hashbang.md +0 -71
  16. package/rules/node/no-deprecated-api.md +0 -91
  17. package/rules/node/no-exports-assign.md +0 -92
  18. package/rules/node/no-extraneous-import.md +0 -118
  19. package/rules/node/no-extraneous-require.md +0 -117
  20. package/rules/node/no-missing-import.md +0 -118
  21. package/rules/node/no-missing-require.md +0 -117
  22. package/rules/node/no-process-exit.md +0 -99
  23. package/rules/node/no-unpublished-import.md +0 -134
  24. package/rules/node/no-unpublished-require.md +0 -133
  25. package/rules/react/display-name.md +0 -91
  26. package/rules/react/exhaustive-deps.md +0 -116
  27. package/rules/react/hook-prefix.md +0 -108
  28. package/rules/react/jsx-key.md +0 -99
  29. package/rules/react/jsx-no-comment-textnodes.md +0 -87
  30. package/rules/react/jsx-no-duplicate-props.md +0 -66
  31. package/rules/react/jsx-no-target-blank.md +0 -78
  32. package/rules/react/jsx-no-undef.md +0 -78
  33. package/rules/react/no-children-prop.md +0 -80
  34. package/rules/react/no-danger-with-children.md +0 -83
  35. package/rules/react/no-deprecated.md +0 -84
  36. package/rules/react/no-direct-mutation-state.md +0 -102
  37. package/rules/react/no-find-dom-node.md +0 -72
  38. package/rules/react/no-is-mounted.md +0 -109
  39. package/rules/react/no-render-return-value.md +0 -75
  40. package/rules/react/no-string-refs.md +0 -72
  41. package/rules/react/no-unescaped-entities.md +0 -69
  42. package/rules/react/no-unknown-property.md +0 -69
  43. package/rules/react/props-type-name.md +0 -43
  44. package/rules/react/require-render-return.md +0 -91
  45. package/rules/react/rules-of-hooks.md +0 -128
  46. package/rules/stencil/ban-default-true.md +0 -70
  47. package/rules/stencil/ban-exported-const-enums.md +0 -60
  48. package/rules/stencil/ban-prefix.md +0 -76
  49. package/rules/stencil/decorators-context.md +0 -61
  50. package/rules/stencil/host-data-deprecated.md +0 -73
  51. package/rules/stencil/methods-must-be-public.md +0 -69
  52. package/rules/stencil/no-unused-watch.md +0 -68
  53. package/rules/stencil/own-methods-must-be-private.md +0 -68
  54. package/rules/stencil/own-props-must-be-private.md +0 -60
  55. package/rules/stencil/prefer-vdom-listener.md +0 -67
  56. package/rules/stencil/prop-readonly.md +0 -63
  57. package/rules/stencil/props-must-be-public.md +0 -68
  58. package/rules/stencil/required-jsdoc.md +0 -66
  59. package/rules/stencil/reserved-member-names.md +0 -70
  60. package/rules/stencil/strict-mutable.md +0 -75
  61. package/rules/stencil/tag-prefix.md +0 -75
  62. package/rules/ts/ban-ts-comment.md +0 -64
  63. package/rules/ts/no-array-constructor.md +0 -58
  64. package/rules/ts/no-duplicate-enum-values.md +0 -65
  65. package/rules/ts/no-empty-object-type.md +0 -65
  66. package/rules/ts/no-explicit-any.md +0 -61
  67. package/rules/ts/no-extra-non-null-assertion.md +0 -50
  68. package/rules/ts/no-misused-new.md +0 -70
  69. package/rules/ts/no-namespace.md +0 -65
  70. package/rules/ts/no-non-null-asserted-optional-chain.md +0 -55
  71. package/rules/ts/no-require-imports.md +0 -54
  72. package/rules/ts/no-this-alias.md +0 -68
  73. package/rules/ts/no-unnecessary-type-constraint.md +0 -64
  74. package/rules/ts/no-unsafe-declaration-merging.md +0 -73
  75. package/rules/ts/no-unsafe-function-type.md +0 -57
  76. package/rules/ts/no-unused-expressions.md +0 -61
  77. package/rules/ts/no-unused-vars.md +0 -68
  78. package/rules/ts/no-wrapper-object-types.md +0 -49
  79. package/rules/ts/prefer-as-const.md +0 -47
  80. package/rules/ts/prefer-namespace-keyword.md +0 -63
  81. package/rules/ts/triple-slash-reference.md +0 -60
  82. package/rules/ts/type-only-imports.md +0 -57
@@ -1,65 +0,0 @@
1
- ---
2
- id: ts/no-duplicate-enum-values
3
- title: "No two enum members share a value"
4
- languages: [typescript, tsx]
5
- fix: manual
6
- fix_reason: "which value is right needs the author"
7
- stability: preview
8
- ported_from: [typescript-eslint/no-duplicate-enum-values]
9
- since: 0.1.0
10
- ---
11
-
12
- Each member of an enum given a literal value has a different value.
13
-
14
- **Why:** Two members with one value are indistinguishable at run time, which is usually a copy-paste
15
- slip.
16
-
17
- ```codelaw
18
- native: ts/no-duplicate-enum-values
19
- ```
20
-
21
- ## How to fix
22
-
23
- 1. Give each member its own value.
24
-
25
- ## Examples
26
-
27
- ### TypeScript
28
-
29
- #### Don't
30
-
31
- ```ts
32
- enum Color {
33
- Red = 1,
34
- Green = 1,
35
- }
36
- ```
37
-
38
- #### Do
39
-
40
- ```ts
41
- enum Color {
42
- Red = 1,
43
- Green = 2,
44
- }
45
- ```
46
-
47
- ### TSX
48
-
49
- #### Don't
50
-
51
- ```tsx
52
- enum Color {
53
- Red = 1,
54
- Green = 1,
55
- }
56
- ```
57
-
58
- #### Do
59
-
60
- ```tsx
61
- enum Color {
62
- Red = 1,
63
- Green = 2,
64
- }
65
- ```
@@ -1,65 +0,0 @@
1
- ---
2
- id: ts/no-empty-object-type
3
- title: "No empty interfaces or {} types"
4
- languages: [typescript, tsx]
5
- fix: manual
6
- fix_reason: "the right replacement — `object`, `unknown` or `Record<string, never>` — depends on intent"
7
- stability: preview
8
- ported_from: [typescript-eslint/no-empty-object-type]
9
- since: 0.1.0
10
- ---
11
-
12
- Code doesn't declare an empty interface or use the type `{}`.
13
-
14
- **Why:** `{}` accepts every value except `null` and `undefined`, which is almost never what an
15
- empty-looking type was meant to say.
16
-
17
- ```codelaw
18
- match:
19
- any:
20
- - kind: interface_declaration
21
- has: { field: body, regex: '^\{\s*\}$' }
22
- - kind: object_type
23
- regex: '^\{\s*\}$'
24
- message: "`{}` means any non-null value, not an empty object; say what you mean"
25
- ```
26
-
27
- ## How to fix
28
-
29
- 1. For any object, use `object`.
30
- 2. For any value, use `unknown`.
31
- 3. For an object with no keys, use `Record<string, never>`.
32
-
33
- ## Examples
34
-
35
- ### TypeScript
36
-
37
- #### Don't
38
-
39
- ```ts
40
- interface Options {}
41
- type Empty = {};
42
- ```
43
-
44
- #### Do
45
-
46
- ```ts
47
- type Options = Record<string, never>;
48
- type Anything = unknown;
49
- ```
50
-
51
- ### TSX
52
-
53
- #### Don't
54
-
55
- ```tsx
56
- interface Options {}
57
- type Empty = {};
58
- ```
59
-
60
- #### Do
61
-
62
- ```tsx
63
- type Options = Record<string, never>;
64
- type Anything = unknown;
65
- ```
@@ -1,61 +0,0 @@
1
- ---
2
- id: ts/no-explicit-any
3
- title: "No explicit any"
4
- languages: [typescript, tsx]
5
- fix: suggest
6
- fix_reason: "`unknown` may need narrowing code where the value is used"
7
- stability: preview
8
- ported_from: [typescript-eslint/no-explicit-any]
9
- since: 0.1.0
10
- ---
11
-
12
- Types are not written as `any`.
13
-
14
- **Why:** `any` silently disables checking for everything it touches; `unknown` keeps the checks and
15
- forces a narrowing.
16
-
17
- ```codelaw
18
- match:
19
- kind: predefined_type
20
- regex: ^any$
21
- message: "`any` turns off type-checking here; use `unknown` and narrow it"
22
- fix: "unknown"
23
- ```
24
-
25
- ## Examples
26
-
27
- ### TypeScript
28
-
29
- #### Don't
30
-
31
- ```ts
32
- function parse(input: any) {
33
- return input;
34
- }
35
- ```
36
-
37
- #### Do
38
-
39
- ```ts
40
- function parse(input: unknown) {
41
- return input;
42
- }
43
- ```
44
-
45
- ### TSX
46
-
47
- #### Don't
48
-
49
- ```tsx
50
- function parse(input: any) {
51
- return input;
52
- }
53
- ```
54
-
55
- #### Do
56
-
57
- ```tsx
58
- function parse(input: unknown) {
59
- return input;
60
- }
61
- ```
@@ -1,50 +0,0 @@
1
- ---
2
- id: ts/no-extra-non-null-assertion
3
- title: "No repeated non-null assertions"
4
- languages: [typescript, tsx]
5
- fix: auto
6
- stability: preview
7
- ported_from: [typescript-eslint/no-extra-non-null-assertion]
8
- since: 0.1.0
9
- ---
10
-
11
- A non-null assertion `!` is not repeated.
12
-
13
- **Why:** `x!!` means the same as `x!`; the second `!` is a typo.
14
-
15
- ```codelaw
16
- match:
17
- pattern: $X!!
18
- message: "One `!` is enough"
19
- fix: "$X!"
20
- ```
21
-
22
- ## Examples
23
-
24
- ### TypeScript
25
-
26
- #### Don't
27
-
28
- ```ts
29
- const n = value!!;
30
- ```
31
-
32
- #### Do
33
-
34
- ```ts
35
- const n = value!;
36
- ```
37
-
38
- ### TSX
39
-
40
- #### Don't
41
-
42
- ```tsx
43
- const n = value!!;
44
- ```
45
-
46
- #### Do
47
-
48
- ```tsx
49
- const n = value!;
50
- ```
@@ -1,70 +0,0 @@
1
- ---
2
- id: ts/no-misused-new
3
- title: "No constructors declared in interfaces, and no `new` methods in classes"
4
- languages: [typescript, tsx]
5
- fix: manual
6
- fix_reason: "the intended constructor signature needs the author"
7
- stability: preview
8
- ported_from: [typescript-eslint/no-misused-new]
9
- since: 0.1.0
10
- ---
11
-
12
- An interface doesn't declare a method named `constructor`, and a class doesn't declare a method
13
- named `new`.
14
-
15
- **Why:** Both look like constructors but are ordinary methods; constructors in types are written
16
- `new (): T`.
17
-
18
- ```codelaw
19
- match:
20
- any:
21
- - kind: method_signature
22
- has: { field: name, regex: ^constructor$ }
23
- inside: { kind: interface_body, stopBy: neighbor }
24
- - kind: method_definition
25
- has: { field: name, regex: ^new$ }
26
- message: "This declares a constructor where TypeScript reads a plain method"
27
- ```
28
-
29
- ## How to fix
30
-
31
- 1. In an interface, describe a constructor with `new (…): T`.
32
- 2. In a class, use `constructor(…)`.
33
-
34
- ## Examples
35
-
36
- ### TypeScript
37
-
38
- #### Don't
39
-
40
- ```ts
41
- interface Point {
42
- constructor(): void;
43
- }
44
- ```
45
-
46
- #### Do
47
-
48
- ```ts
49
- interface PointConstructor {
50
- new (): object;
51
- }
52
- ```
53
-
54
- ### TSX
55
-
56
- #### Don't
57
-
58
- ```tsx
59
- interface Point {
60
- constructor(): void;
61
- }
62
- ```
63
-
64
- #### Do
65
-
66
- ```tsx
67
- interface PointConstructor {
68
- new (): object;
69
- }
70
- ```
@@ -1,65 +0,0 @@
1
- ---
2
- id: ts/no-namespace
3
- title: "No TypeScript namespaces"
4
- languages: [typescript, tsx]
5
- fix: manual
6
- fix_reason: "moving a namespace's members into a module changes every import"
7
- stability: preview
8
- ported_from: [typescript-eslint/no-namespace]
9
- since: 0.1.0
10
- ---
11
-
12
- Code is organised with ES modules, not `namespace` or `module` blocks; `declare module "x"` and
13
- `declare global` are allowed.
14
-
15
- **Why:** Namespaces predate ES modules and don't work with modern bundlers and tooling as well.
16
-
17
- ```codelaw
18
- match:
19
- any:
20
- - kind: internal_module
21
- - kind: module
22
- has: { field: name, kind: identifier }
23
- not:
24
- inside: { kind: ambient_declaration, stopBy: end }
25
- message: "Use ES modules instead of a namespace"
26
- ```
27
-
28
- ## How to fix
29
-
30
- 1. Move the namespace's members to a module of their own.
31
- 2. Export them, and import them where the namespace was used.
32
-
33
- ## Examples
34
-
35
- ### TypeScript
36
-
37
- #### Don't
38
-
39
- ```ts
40
- namespace Geometry {
41
- export const pi = 3.14;
42
- }
43
- ```
44
-
45
- #### Do
46
-
47
- ```ts
48
- export const pi = 3.14;
49
- ```
50
-
51
- ### TSX
52
-
53
- #### Don't
54
-
55
- ```tsx
56
- namespace Geometry {
57
- export const pi = 3.14;
58
- }
59
- ```
60
-
61
- #### Do
62
-
63
- ```tsx
64
- export const pi = 3.14;
65
- ```
@@ -1,55 +0,0 @@
1
- ---
2
- id: ts/no-non-null-asserted-optional-chain
3
- title: "No non-null assertion after an optional chain"
4
- languages: [typescript, tsx]
5
- fix: suggest
6
- fix_reason: "removing `!` widens the type to include `undefined`, which later code may not handle"
7
- stability: preview
8
- ported_from: [typescript-eslint/no-non-null-asserted-optional-chain]
9
- since: 0.1.0
10
- ---
11
-
12
- An optional chain (`a?.b`) is not followed by a non-null assertion (`!`).
13
-
14
- **Why:** The two contradict each other: `?.` allows `undefined`, and `!` asserts it never happens.
15
-
16
- ```codelaw
17
- match:
18
- pattern: $X!
19
- has:
20
- stopBy: neighbor
21
- any: [{ kind: member_expression }, { kind: call_expression }, { kind: subscript_expression }]
22
- has: { kind: optional_chain, stopBy: neighbor }
23
- message: "`?.` says this can be undefined; `!` says it can't"
24
- fix: "$X"
25
- ```
26
-
27
- ## Examples
28
-
29
- ### TypeScript
30
-
31
- #### Don't
32
-
33
- ```ts
34
- const name = user?.name!;
35
- ```
36
-
37
- #### Do
38
-
39
- ```ts
40
- const name = user?.name;
41
- ```
42
-
43
- ### TSX
44
-
45
- #### Don't
46
-
47
- ```tsx
48
- const name = user?.name!;
49
- ```
50
-
51
- #### Do
52
-
53
- ```tsx
54
- const name = user?.name;
55
- ```
@@ -1,54 +0,0 @@
1
- ---
2
- id: ts/no-require-imports
3
- title: "No require() calls"
4
- languages: [typescript, tsx]
5
- fix: manual
6
- fix_reason: "an import may need the module's default or named exports chosen by hand"
7
- stability: preview
8
- ported_from: [typescript-eslint/no-require-imports]
9
- since: 0.1.0
10
- ---
11
-
12
- Modules are loaded with `import`, not `require()`.
13
-
14
- **Why:** `require()` is untyped and invisible to TypeScript's module checks.
15
-
16
- ```codelaw
17
- match:
18
- pattern: require($$$ARGS)
19
- message: "Use `import` instead of `require()`"
20
- ```
21
-
22
- ## How to fix
23
-
24
- 1. Replace the call with an `import` of the names the code uses.
25
-
26
- ## Examples
27
-
28
- ### TypeScript
29
-
30
- #### Don't
31
-
32
- ```ts
33
- const fs = require("node:fs");
34
- ```
35
-
36
- #### Do
37
-
38
- ```ts
39
- import fs from "node:fs";
40
- ```
41
-
42
- ### TSX
43
-
44
- #### Don't
45
-
46
- ```tsx
47
- const fs = require("node:fs");
48
- ```
49
-
50
- #### Do
51
-
52
- ```tsx
53
- import fs from "node:fs";
54
- ```
@@ -1,68 +0,0 @@
1
- ---
2
- id: ts/no-this-alias
3
- title: "No aliasing this to a variable"
4
- languages: [typescript, tsx]
5
- fix: manual
6
- fix_reason: "the callbacks that use the alias must become arrow functions by hand"
7
- stability: preview
8
- ported_from: [typescript-eslint/no-this-alias]
9
- since: 0.1.0
10
- ---
11
-
12
- `this` is not stored in a variable such as `self` or `that`; destructuring it is fine.
13
-
14
- **Why:** Arrow functions keep the outer `this`, so an alias only adds a name to keep track of.
15
-
16
- ```codelaw
17
- match:
18
- kind: variable_declarator
19
- all:
20
- - has: { field: name, kind: identifier }
21
- - has: { field: value, kind: this }
22
- message: "Use an arrow function instead of aliasing `this`"
23
- ```
24
-
25
- ## How to fix
26
-
27
- 1. Turn the callbacks that use the alias into arrow functions.
28
- 2. Use `this` directly and remove the alias.
29
-
30
- ## Examples
31
-
32
- ### TypeScript
33
-
34
- #### Don't
35
-
36
- ```ts
37
- const self = this;
38
- button.onclick = function () {
39
- self.save();
40
- };
41
- ```
42
-
43
- #### Do
44
-
45
- ```ts
46
- button.onclick = () => {
47
- this.save();
48
- };
49
- ```
50
-
51
- ### TSX
52
-
53
- #### Don't
54
-
55
- ```tsx
56
- const self = this;
57
- button.onclick = function () {
58
- self.save();
59
- };
60
- ```
61
-
62
- #### Do
63
-
64
- ```tsx
65
- button.onclick = () => {
66
- this.save();
67
- };
68
- ```
@@ -1,64 +0,0 @@
1
- ---
2
- id: ts/no-unnecessary-type-constraint
3
- title: "No extends any or extends unknown on a type parameter"
4
- languages: [typescript, tsx]
5
- fix: suggest
6
- fix_reason: "in a .tsx arrow function `<T>` alone parses as JSX and needs `<T,>`"
7
- stability: preview
8
- ported_from: [typescript-eslint/no-unnecessary-type-constraint]
9
- since: 0.1.0
10
- ---
11
-
12
- A type parameter isn't constrained to `any` or `unknown`.
13
-
14
- **Why:** Every type extends both, so the constraint says nothing.
15
-
16
- ```codelaw
17
- match:
18
- kind: type_parameter
19
- all:
20
- - has: { field: name, pattern: $NAME }
21
- - has:
22
- field: constraint
23
- has: { kind: predefined_type, regex: ^(any|unknown)$ }
24
- message: "Every type already extends `any` and `unknown`; drop the constraint"
25
- fix: "$NAME"
26
- ```
27
-
28
- ## Examples
29
-
30
- ### TypeScript
31
-
32
- #### Don't
33
-
34
- ```ts
35
- function id<T extends unknown>(x: T) {
36
- return x;
37
- }
38
- ```
39
-
40
- #### Do
41
-
42
- ```ts
43
- function id<T>(x: T) {
44
- return x;
45
- }
46
- ```
47
-
48
- ### TSX
49
-
50
- #### Don't
51
-
52
- ```tsx
53
- function id<T extends unknown>(x: T) {
54
- return x;
55
- }
56
- ```
57
-
58
- #### Do
59
-
60
- ```tsx
61
- function id<T>(x: T) {
62
- return x;
63
- }
64
- ```
@@ -1,73 +0,0 @@
1
- ---
2
- id: ts/no-unsafe-declaration-merging
3
- title: "No interface that merges with a class of the same name"
4
- languages: [typescript, tsx]
5
- fix: manual
6
- fix_reason: "whether to rename or to move the members into the class needs the author"
7
- stability: preview
8
- ported_from: [typescript-eslint/no-unsafe-declaration-merging]
9
- since: 0.1.0
10
- ---
11
-
12
- An interface doesn't share its name with a class in the same scope.
13
-
14
- **Why:** The merged interface adds members to the class's type that the class never initialises, and
15
- the compiler can't tell.
16
-
17
- ```codelaw
18
- native: ts/no-unsafe-declaration-merging
19
- ```
20
-
21
- ## How to fix
22
-
23
- 1. Move the interface's members into the class, or rename the interface.
24
-
25
- ## Examples
26
-
27
- ### TypeScript
28
-
29
- #### Don't
30
-
31
- ```ts
32
- interface Point {
33
- z: number;
34
- }
35
- class Point {
36
- x = 0;
37
- }
38
- ```
39
-
40
- #### Do
41
-
42
- ```ts
43
- interface PointLike {
44
- z: number;
45
- }
46
- class Point {
47
- x = 0;
48
- }
49
- ```
50
-
51
- ### TSX
52
-
53
- #### Don't
54
-
55
- ```tsx
56
- interface Point {
57
- z: number;
58
- }
59
- class Point {
60
- x = 0;
61
- }
62
- ```
63
-
64
- #### Do
65
-
66
- ```tsx
67
- interface PointLike {
68
- z: number;
69
- }
70
- class Point {
71
- x = 0;
72
- }
73
- ```