eslint-plugin-rxjs-x 0.0.1

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 (49) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +89 -0
  3. package/dist/index.cjs +2936 -0
  4. package/dist/index.d.cts +121 -0
  5. package/dist/index.d.mts +121 -0
  6. package/dist/index.d.ts +121 -0
  7. package/dist/index.mjs +2916 -0
  8. package/docs/rules/ban-observables.md +22 -0
  9. package/docs/rules/ban-operators.md +21 -0
  10. package/docs/rules/finnish.md +54 -0
  11. package/docs/rules/just.md +11 -0
  12. package/docs/rules/macro.md +7 -0
  13. package/docs/rules/no-async-subscribe.md +27 -0
  14. package/docs/rules/no-compat.md +11 -0
  15. package/docs/rules/no-connectable.md +7 -0
  16. package/docs/rules/no-create.md +29 -0
  17. package/docs/rules/no-cyclic-action.md +62 -0
  18. package/docs/rules/no-explicit-generics.md +23 -0
  19. package/docs/rules/no-exposed-subjects.md +39 -0
  20. package/docs/rules/no-finnish.md +25 -0
  21. package/docs/rules/no-ignored-error.md +37 -0
  22. package/docs/rules/no-ignored-notifier.md +30 -0
  23. package/docs/rules/no-ignored-observable.md +23 -0
  24. package/docs/rules/no-ignored-replay-buffer.md +28 -0
  25. package/docs/rules/no-ignored-subscribe.md +28 -0
  26. package/docs/rules/no-ignored-subscription.md +33 -0
  27. package/docs/rules/no-ignored-takewhile-value.md +26 -0
  28. package/docs/rules/no-implicit-any-catch.md +78 -0
  29. package/docs/rules/no-index.md +21 -0
  30. package/docs/rules/no-internal.md +21 -0
  31. package/docs/rules/no-nested-subscribe.md +30 -0
  32. package/docs/rules/no-redundant-notify.md +32 -0
  33. package/docs/rules/no-sharereplay.md +22 -0
  34. package/docs/rules/no-subclass.md +7 -0
  35. package/docs/rules/no-subject-unsubscribe.md +11 -0
  36. package/docs/rules/no-subject-value.md +7 -0
  37. package/docs/rules/no-subscribe-handlers.md +39 -0
  38. package/docs/rules/no-tap.md +7 -0
  39. package/docs/rules/no-topromise.md +7 -0
  40. package/docs/rules/no-unbound-methods.md +47 -0
  41. package/docs/rules/no-unsafe-catch.md +50 -0
  42. package/docs/rules/no-unsafe-first.md +16 -0
  43. package/docs/rules/no-unsafe-subject-next.md +30 -0
  44. package/docs/rules/no-unsafe-switchmap.md +38 -0
  45. package/docs/rules/no-unsafe-takeuntil.md +46 -0
  46. package/docs/rules/prefer-observer.md +34 -0
  47. package/docs/rules/suffix-subjects.md +42 -0
  48. package/docs/rules/throw-error.md +49 -0
  49. package/package.json +82 -0
@@ -0,0 +1,30 @@
1
+ # Avoid nested `subscribe` calls (`no-nested-subscribe`)
2
+
3
+ This rule effects failures if `subscribe` is called within a `subscribe` handler.
4
+
5
+ ## Rule details
6
+
7
+ Examples of **incorrect** code for this rule:
8
+
9
+ ```ts
10
+ import { of, timer } from "rxjs";
11
+
12
+ of(42, 54).subscribe((value) => {
13
+ timer(1e3).subscribe(() => console.log(value));
14
+ });
15
+ ```
16
+
17
+ Examples of **correct** code for this rule:
18
+
19
+ ```ts
20
+ import { of, timer } from "rxjs";
21
+ import { mapTo, mergeMap } from "rxjs/operators";
22
+
23
+ of(42, 54).pipe(
24
+ mergeMap((value) => timer(1e3).pipe(mapTo(value)))
25
+ ).subscribe((value) => console.log(value));
26
+ ```
27
+
28
+ ## Options
29
+
30
+ This rule has no options.
@@ -0,0 +1,32 @@
1
+ # Avoid sending redundant notifications (`no-redundant-notify`)
2
+
3
+ This rule effects failures if an attempt is made to send a notification to an observer after a `complete` or `error` notification has already been sent.
4
+
5
+ Note that the rule _does not perform extensive analysis_. It uses a straightforward and limited approach to catch obviously redundant notifications.
6
+
7
+ ## Rule details
8
+
9
+ Examples of **incorrect** code for this rule:
10
+
11
+ ```ts
12
+ import { Subject } from "rxjs";
13
+
14
+ const subject = new Subject<number>();
15
+ subject.next(42);
16
+ subject.error(new Error("Kaboom!"));
17
+ subject.complete();
18
+ ```
19
+
20
+ Examples of **correct** code for this rule:
21
+
22
+ ```ts
23
+ import { Subject } from "rxjs";
24
+
25
+ const subject = new Subject<number>();
26
+ subject.next(42);
27
+ subject.error(new Error("Kaboom!"));
28
+ ```
29
+
30
+ ## Options
31
+
32
+ This rule has no options.
@@ -0,0 +1,22 @@
1
+ # Avoid `shareReplay` (`no-sharereplay`)
2
+
3
+ This rule effects failures if the `shareReplay` operator is used - or if it is used without specifying a `config` argument.
4
+
5
+ The behaviour of `shareReplay` has changed several times - see the blog post linked below.
6
+
7
+ ## Options
8
+
9
+ This rule accepts a single option which is an object with an `allowConfig` property that that determines whether `shareReplay` is allow if a config argument is specified. By default, `allowConfig` is `true`.
10
+
11
+ ```json
12
+ {
13
+ "rxjs-x/no-sharereplay": [
14
+ "error",
15
+ { "allowConfig": true }
16
+ ]
17
+ }
18
+ ```
19
+
20
+ ## Further reading
21
+
22
+ - [What's changed with shareReplay](https://ncjamieson.com/whats-changed-with-sharereplay/)
@@ -0,0 +1,7 @@
1
+ # Avoid subclassing RxJS classes (`no-subclass`)
2
+
3
+ This rule effects failures if an RxJS class is subclassed. Developers are encouraged to avoid subclassing RxJS classes, as some public and protected implementation details might change in the future.
4
+
5
+ ## Options
6
+
7
+ This rule has no options.
@@ -0,0 +1,11 @@
1
+ # Avoid calling `unsubscribe` on subjects (`no-subject-unsubscribe`)
2
+
3
+ This rule effects failures if the `unsubscribe` method is called on subjects. The method behaves differently to the `unsubsribe` method on subscriptions and is often an error.
4
+
5
+ ## Options
6
+
7
+ This rule has no options.
8
+
9
+ ## Further reading
10
+
11
+ - [Closed Subjects](https://ncjamieson.com/closed-subjects/)
@@ -0,0 +1,7 @@
1
+ # Avoid using a behavior subject's value (`no-subject-value`)
2
+
3
+ This rule effects an error if the `value` property - or `getValue` method - of a `BehaviorSubject` is used.
4
+
5
+ ## Options
6
+
7
+ This rule has no options.
@@ -0,0 +1,39 @@
1
+ # Forbid the passing of handlers to `subscribe` (`no-subscribe-handlers`)
2
+
3
+ This rule effects failures whenever `subscribe` is called with handlers.
4
+
5
+ ## Rule details
6
+
7
+ Examples of **incorrect** code for this rule:
8
+
9
+ ```ts
10
+ import { of } from "rxjs";
11
+ import { tap } from "rxjs/operators";
12
+
13
+ of(42, 54).subscribe((value) => console.log(value));
14
+ ```
15
+
16
+ <!-- prettier-ignore -->
17
+ ```ts
18
+ import { of } from "rxjs";
19
+ import { tap } from "rxjs/operators";
20
+
21
+ of(42, 54).subscribe({
22
+ next: (value) => console.log(value),
23
+ });
24
+ ```
25
+
26
+ Examples of **correct** code for this rule:
27
+
28
+ <!-- prettier-ignore -->
29
+ ```ts
30
+ import { of } from "rxjs";
31
+
32
+ of(42, 54)
33
+ .pipe(tap((value) => console.log(value)))
34
+ .subscribe();
35
+ ```
36
+
37
+ ## Options
38
+
39
+ This rule has no options.
@@ -0,0 +1,7 @@
1
+ # Avoid `tap` (`no-tap`)
2
+
3
+ This rule effects failures if the `tap` operator is used.
4
+
5
+ ## Options
6
+
7
+ This rule has no options.
@@ -0,0 +1,7 @@
1
+ # Avoid `toPromise` (`no-topromise`)
2
+
3
+ This rule effects failures if the `toPromise` method is used.
4
+
5
+ ## Options
6
+
7
+ This rule has no options.
@@ -0,0 +1,47 @@
1
+ # Avoid using unbound methods as callbacks (`no-unbound-methods`)
2
+
3
+ This rule effects failures if unbound methods are passed as callbacks.
4
+
5
+ ## Rule details
6
+
7
+ Examples of **incorrect** code for this rule:
8
+
9
+ <!-- prettier-ignore -->
10
+ ```ts
11
+ return this.http
12
+ .get<Something>("https://api.some.com/things/1")
13
+ .pipe(
14
+ map(this.extractSomeProperty),
15
+ catchError(this.handleError)
16
+ );
17
+ ```
18
+
19
+ Examples of **correct** code for this rule:
20
+
21
+ <!-- prettier-ignore -->
22
+ ```ts
23
+ return this.http
24
+ .get<Something>("https://api.some.com/things/1")
25
+ .pipe(
26
+ map((s) => this.extractSomeProperty(s)),
27
+ catchError((e) => this.handleError(e))
28
+ );
29
+ ```
30
+
31
+ <!-- prettier-ignore -->
32
+ ```ts
33
+ return this.http
34
+ .get<Something>("https://api.some.com/things/1")
35
+ .pipe(
36
+ map(this.extractSomeProperty.bind(this)),
37
+ catchError(this.handleError.bind(this))
38
+ );
39
+ ```
40
+
41
+ ## Options
42
+
43
+ This rule has no options.
44
+
45
+ ## Further reading
46
+
47
+ - [Avoiding unbound methods](https://ncjamieson.com/avoiding-unbound-methods/)
@@ -0,0 +1,50 @@
1
+ # Avoid completing effects and epics (`no-unsafe-catch`)
2
+
3
+ This rule effects failures if `catchError` is used in an effect or epic in a manner that will complete the outermost observable.
4
+
5
+ ## Rule details
6
+
7
+ Examples of **incorrect** code for this rule:
8
+
9
+ ```ts
10
+ actions.pipe(
11
+ ofType("SOMETHING"),
12
+ switchMap((action) => something(action)),
13
+ catchError(handleError)
14
+ );
15
+ ```
16
+
17
+ Examples of **correct** code for this rule:
18
+
19
+ ```ts
20
+ actions.pipe(
21
+ ofType("SOMETHING"),
22
+ switchMap((action) => something(action).pipe(
23
+ catchError(handleError)
24
+ ))
25
+ );
26
+ ```
27
+
28
+ ```ts
29
+ actions.pipe(
30
+ ofType("SOMETHING"),
31
+ switchMap((action) => something(action)),
32
+ catchError((error, caught) => {
33
+ handleError(error);
34
+ return caught;
35
+ })
36
+ );
37
+ ```
38
+
39
+ ## Options
40
+
41
+ This rule accepts a single option which is an object with an `observable` property that is a regular expression used to match an effect or epic's actions observable. The default `observable` regular expression should match most effect and epic action sources.
42
+
43
+ ```json
44
+ {
45
+ "rxjs-x/no-unsafe-catch": [
46
+ "error",
47
+ { "observable": "[Aa]ction(s|s\\$|\\$)$" }
48
+ ]
49
+ }
50
+ ```
@@ -0,0 +1,16 @@
1
+ # Avoid completing effects and epics (`no-unsafe-first`)
2
+
3
+ This rule effects failures if `first` is used in an effect or epic in a manner that will complete the outermost observable.
4
+
5
+ ## Options
6
+
7
+ This rule accepts a single option which is an object with an `observable` property that is a regular expression used to match an effect or epic's actions observable. The default `observable` regular expression should match most effect and epic action sources.
8
+
9
+ ```json
10
+ {
11
+ "rxjs-x/no-unsafe-first": [
12
+ "error",
13
+ { "observable": "[Aa]ction(s|s\\$|\\$)$" }
14
+ ]
15
+ }
16
+ ```
@@ -0,0 +1,30 @@
1
+ # Avoid passing `undefined` to `next` (`no-unsafe-subject-next`)
2
+
3
+ This rule effects failures if `next` is called without an argument and the subject's value type is not `void`.
4
+
5
+ In RxJS version 6, the `next` method's `value` parameter is optional, but a value should always be specified for subjects with non-`void` element types.
6
+
7
+ ## Rule details
8
+
9
+ Examples of **incorrect** code for this rule:
10
+
11
+ ```ts
12
+ const subject = new Subject<number>();
13
+ subject.next();
14
+ ```
15
+
16
+ Examples of **correct** code for this rule:
17
+
18
+ ```ts
19
+ const subject = new Subject<void>();
20
+ subject.next();
21
+ ```
22
+
23
+ ```ts
24
+ const subject = new Subject<number>();
25
+ subject.next(0);
26
+ ```
27
+
28
+ ## Options
29
+
30
+ This rule has no options.
@@ -0,0 +1,38 @@
1
+ # Avoid `switchMap` bugs in effects and epics (`no-unsafe-switchmap`)
2
+
3
+ This rule effects failures if `switchMap` is used in effects or epics that perform actions other than reads. For a detailed explanation, see the blog post linked below.
4
+
5
+ ## Options
6
+
7
+ This rule accepts a single option which is an object with `allow`, `disallow` and `observable` properties.
8
+
9
+ The `observable` property is a regular expression used to match an effect or epic's actions observable. The default `observable` regular expression should match most effect and epic action sources.
10
+
11
+ The `allow` or `disallow` properties are mutually exclusive. Whether or not `switchMap` is allowed will depend upon the matching of action types with `allow` or `disallow`. The properties can be specified as regular expression strings or as arrays of words.
12
+
13
+ ```json
14
+ {
15
+ "rxjs-x/no-unsafe-switchmap": [
16
+ "error",
17
+ {
18
+ "disallow": [
19
+ "add",
20
+ "create",
21
+ "delete",
22
+ "post",
23
+ "put",
24
+ "remove",
25
+ "set",
26
+ "update"
27
+ ],
28
+ "observable": "[Aa]ction(s|s\\$|\\$)$"
29
+ }
30
+ ]
31
+ }
32
+ ```
33
+
34
+ The properties in the options object are themselves optional; they do not all have to be specified.
35
+
36
+ ## Further reading
37
+
38
+ - [Avoiding switchMap-related bugs](https://ncjamieson.com/avoiding-switchmap-related-bugs/)
@@ -0,0 +1,46 @@
1
+ # Avoid `takeUntil` subscription leaks (`no-unsafe-takeuntil`)
2
+
3
+ This rule effects failures whenever `takeUntil` is used in observable compositions that can leak subscriptions.
4
+
5
+ Although it's recommended that `takeUntil` be placed last - to ensure unsubscription from any inner observables - there are a number of operators that might _need_ to be placed after it - like `toArray` or any other operator that depends upon a `complete` notification. The rule is aware of these operators (see the rule's options, below) and will not effect failures if they are placed after `takeUntil`.
6
+
7
+ ## Rule details
8
+
9
+ Examples of **incorrect** code for this rule:
10
+
11
+ ```ts
12
+ const combined = source
13
+ .pipe(takeUntil(notifier), combineLatest(b))
14
+ .subscribe((value) => console.log(value));
15
+ ```
16
+
17
+ Examples of **correct** code for this rule:
18
+
19
+ ```ts
20
+ const combined = source
21
+ .pipe(combineLatest(b), takeUntil(notifier))
22
+ .subscribe((value) => console.log(value));
23
+ ```
24
+
25
+ ## Options
26
+
27
+ This rule accepts a single option which is an object with `alias` and `allow` properties. The `alias` property is an array of names of operators that should be treated similarly to `takeUntil` and the `allow` property is an array of names of operators that are safe to use after `takeUntil`.
28
+
29
+ By default, the `allow` property contains all of the built-in operators that are safe to use after `takeUntil`.
30
+
31
+ ```json
32
+ {
33
+ "rxjs-x/no-unsafe-takeuntil": [
34
+ "error",
35
+ {
36
+ "alias": ["untilDestroyed"]
37
+ }
38
+ ]
39
+ }
40
+ ```
41
+
42
+ The properties in the options object are themselves optional; they do not all have to be specified.
43
+
44
+ ## Further reading
45
+
46
+ - [Avoiding takeUntil leaks](https://ncjamieson.com/avoiding-takeuntil-leaks/)
@@ -0,0 +1,34 @@
1
+ # Avoid separate handlers (`prefer-observer`)
2
+
3
+ This rule effects failures if `subscribe` - or `tap` - is called with separate handlers instead of an observer.
4
+
5
+ ## Rule details
6
+
7
+ Examples of **incorrect** code for this rule:
8
+
9
+ ```ts
10
+ import { of } from "rxjs";
11
+ of(42, 54).subscribe((value) => console.log(value));
12
+ ```
13
+
14
+ Examples of **correct** code for this rule:
15
+
16
+ ```ts
17
+ import { of } from "rxjs";
18
+ of(42, 54).subscribe({
19
+ next: (value) => console.log(value)
20
+ });
21
+ ```
22
+
23
+ ## Options
24
+
25
+ This rule accepts a single option which is an object with an `allowNext` property that determines whether a single `next` callback is allowed. By default, `allowNext` is `true`.
26
+
27
+ ```json
28
+ {
29
+ "rxjs-x/prefer-observer": [
30
+ "error",
31
+ { "allowNext": false }
32
+ ]
33
+ }
34
+ ```
@@ -0,0 +1,42 @@
1
+ # Identify subjects (`suffix-subjects`)
2
+
3
+ This rule effects failures if subject variables, properties and parameters don't conform to a naming scheme that identifies them as subjects.
4
+
5
+ ## Rule details
6
+
7
+ Examples of **incorrect** code for this rule:
8
+
9
+ ```ts
10
+ const answers = new Subject<number>();
11
+ ```
12
+
13
+ Examples of **correct** code for this rule:
14
+
15
+ ```ts
16
+ const answersSubject = new Subject<number>();
17
+ ```
18
+
19
+ ## Options
20
+
21
+ This rule accepts a single option which is an object with properties that determine whether Finnish notation is enforced for `parameters`, `properties` and `variables`. It also contains a `types` property that determine whether of not the naming convention is to be enforced for specific types and a `suffix` property.
22
+
23
+ The default (Angular-friendly) configuration looks like this:
24
+
25
+ ```json
26
+ {
27
+ "rxjs-x/suffix-subjects": [
28
+ "error",
29
+ {
30
+ "parameters": true,
31
+ "properties": true,
32
+ "suffix": "Subject",
33
+ "types": {
34
+ "^EventEmitter$": false
35
+ },
36
+ "variables": true,
37
+ }
38
+ ]
39
+ }
40
+ ```
41
+
42
+ The properties in the options object are themselves optional; they do not all have to be specified.
@@ -0,0 +1,49 @@
1
+ # Avoid throwing non-Error values (`throw-error`)
2
+
3
+ This rule forbids throwing values that are neither `Error` nor `DOMException` instances.
4
+
5
+ ## Rule details
6
+
7
+ Examples of **incorrect** code for this rule:
8
+
9
+ ```ts
10
+ throw "Kaboom!";
11
+ ```
12
+
13
+ ```ts
14
+ import { throwError } from "rxjs";
15
+ throwError("Kaboom!");
16
+ ```
17
+
18
+ ```ts
19
+ import { throwError } from "rxjs";
20
+ throwError(() => "Kaboom!");
21
+ ```
22
+
23
+ Examples of **correct** code for this rule:
24
+
25
+ ```ts
26
+ throw new Error("Kaboom!");
27
+ ```
28
+
29
+ ```ts
30
+ throw new RangeError("Kaboom!");
31
+ ```
32
+
33
+ ```ts
34
+ throw new DOMException("Kaboom!");
35
+ ```
36
+
37
+ ```ts
38
+ import { throwError } from "rxjs";
39
+ throwError(new Error("Kaboom!"));
40
+ ```
41
+
42
+ ```ts
43
+ import { throwError } from "rxjs";
44
+ throwError(() => new Error("Kaboom!"));
45
+ ```
46
+
47
+ ## Options
48
+
49
+ This rule has no options.
package/package.json ADDED
@@ -0,0 +1,82 @@
1
+ {
2
+ "name": "eslint-plugin-rxjs-x",
3
+ "type": "module",
4
+ "version": "0.0.1",
5
+ "packageManager": "yarn@4.5.1+sha512.341db9396b6e289fecc30cd7ab3af65060e05ebff4b3b47547b278b9e67b08f485ecd8c79006b405446262142c7a38154445ef7f17c1d5d1de7d90bf9ce7054d",
6
+ "description": "ESLint v9+ plugin for RxJS",
7
+ "author": "Jason Weinzierl <weinzierljason@gmail.com>",
8
+ "license": "MIT",
9
+ "homepage": "https://github.com/JasonWeinzierl/eslint-plugin-rxjs-x",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/JasonWeinzierl/eslint-plugin-rxjs-x.git"
13
+ },
14
+ "bugs": {
15
+ "url": "https://github.com/JasonWeinzierl/eslint-plugin-rxjs-x/issues"
16
+ },
17
+ "keywords": [
18
+ "lint",
19
+ "rules",
20
+ "eslint",
21
+ "rxjs"
22
+ ],
23
+ "sideEffects": false,
24
+ "exports": {
25
+ ".": {
26
+ "types": "./dist/index.d.ts",
27
+ "import": "./dist/index.mjs",
28
+ "require": "./dist/index.cjs"
29
+ }
30
+ },
31
+ "main": "./dist/index.mjs",
32
+ "module": "./dist/index.mjs",
33
+ "types": "./dist/index.d.ts",
34
+ "files": [
35
+ "dist",
36
+ "docs"
37
+ ],
38
+ "scripts": {
39
+ "build": "unbuild",
40
+ "lint": "eslint",
41
+ "release": "bumpp && yarn run build",
42
+ "test": "vitest",
43
+ "coverage": "vitest run --coverage",
44
+ "typecheck": "tsc --noEmit"
45
+ },
46
+ "dependencies": {
47
+ "@typescript-eslint/scope-manager": "^8.12.2",
48
+ "@typescript-eslint/utils": "^8.12.2",
49
+ "common-tags": "^1.8.0",
50
+ "decamelize": "^5.0.0 || ^6.0.0",
51
+ "tslib": "^2.0.0",
52
+ "tsutils": "^3.0.0",
53
+ "tsutils-etc": "^1.4.2"
54
+ },
55
+ "peerDependencies": {
56
+ "eslint": "^8.57.0 || ^9.0.0",
57
+ "rxjs": ">=7.0.0",
58
+ "typescript": ">=4.0.0"
59
+ },
60
+ "devDependencies": {
61
+ "@eslint/js": "^9.13.0",
62
+ "@stylistic/eslint-plugin": "^2.10.1",
63
+ "@types/common-tags": "^1.8.4",
64
+ "@types/node": "^18.18.0",
65
+ "@typescript-eslint/rule-tester": "^8.12.2",
66
+ "@vitest/coverage-v8": "^2.1.4",
67
+ "bumpp": "^9.8.0",
68
+ "eslint": "^9.13.0",
69
+ "eslint-config-flat-gitignore": "^0.3.0",
70
+ "eslint-import-resolver-typescript": "^3.6.3",
71
+ "eslint-plugin-import-x": "^4.4.0",
72
+ "eslint-plugin-n": "^17.12.0",
73
+ "rxjs": "^7.0.0",
74
+ "typescript": "~5.6.3",
75
+ "typescript-eslint": "^8.12.2",
76
+ "unbuild": "^2.0.0",
77
+ "vitest": "^2.1.4"
78
+ },
79
+ "engines": {
80
+ "node": "^18.18.0 || ^20.9.0 || >= 21.1.0"
81
+ }
82
+ }