eslint-plugin-rxjs-x 0.8.4 → 0.9.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.
- package/LICENSE +1 -1
- package/README.md +62 -51
- package/dist/index.d.mts +31 -2
- package/dist/index.d.ts +31 -2
- package/dist/index.js +146 -89
- package/dist/index.mjs +176 -119
- package/package.json +11 -11
package/LICENSE
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
3
|
Copyright (c) 2019 Nicholas Jamieson and contributors
|
|
4
|
-
Copyright (c) 2024-
|
|
4
|
+
Copyright (c) 2024-2026 Jason Weinzierl and contributors
|
|
5
5
|
|
|
6
6
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
7
|
of this software and associated documentation files (the "Software"), to deal
|
package/README.md
CHANGED
|
@@ -2,87 +2,97 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://github.com/JasonWeinzierl/eslint-plugin-rxjs-x/blob/master/LICENSE)
|
|
4
4
|
[](https://www.npmjs.com/package/eslint-plugin-rxjs-x)
|
|
5
|
+
[](https://scorecard.dev/viewer/?uri=github.com/JasonWeinzierl/eslint-plugin-rxjs-x)
|
|
5
6
|
|
|
6
7
|
This ESLint plugin is intended to prevent issues with [RxJS](https://github.com/ReactiveX/rxjs).
|
|
7
8
|
|
|
8
9
|
Most of these rules require TypeScript typed linting and are indicated as such below.
|
|
9
10
|
|
|
10
|
-
##
|
|
11
|
+
## Installation Guide (Flat Configuration)
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
but has since introduced new features which involve breaking changes.
|
|
13
|
+
See [typescript-eslint's Getting Started](https://typescript-eslint.io/getting-started) for a full ESLint setup guide.
|
|
14
14
|
|
|
15
|
-
1.
|
|
16
|
-
|
|
17
|
-
-
|
|
18
|
-
|
|
15
|
+
1. Install `eslint-plugin-rxjs-x` using your preferred package manager.
|
|
16
|
+
2. Enable typed linting.
|
|
17
|
+
- See [Linting with Type Information](https://typescript-eslint.io/getting-started/typed-linting/) for more information.
|
|
18
|
+
3. Import this plugin into your config.
|
|
19
|
+
Add the `rxjsX.configs.recommended` shared config to your configuration like so:
|
|
19
20
|
|
|
20
21
|
```diff
|
|
22
|
+
// @ts-check
|
|
23
|
+
import { defineConfig } from 'eslint/config';
|
|
24
|
+
import tseslint from 'typescript-eslint';
|
|
21
25
|
+ import rxjsX from 'eslint-plugin-rxjs-x';
|
|
26
|
+
|
|
27
|
+
export default defineConfig({
|
|
28
|
+
extends: [
|
|
29
|
+
tseslint.configs.recommended,
|
|
30
|
+
+ rxjsX.configs.recommended,
|
|
31
|
+
],
|
|
32
|
+
languageOptions: {
|
|
33
|
+
parserOptions: {
|
|
34
|
+
projectService: true,
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
});
|
|
22
38
|
```
|
|
23
39
|
|
|
24
|
-
|
|
40
|
+
Additionally, consider if the `rxjsX.configs.strict` shared config is right for your project.
|
|
41
|
+
|
|
42
|
+
## Legacy Migration Guide from `eslint-plugin-rxjs`
|
|
43
|
+
|
|
44
|
+
> [!TIP]
|
|
45
|
+
> A complete description of all changes from `eslint-plugin-rxjs` are documented in the [CHANGELOG](CHANGELOG.md) file.
|
|
46
|
+
|
|
47
|
+
This project started as a fork of [`eslint-plugin-rxjs`](https://github.com/cartant/eslint-plugin-rxjs)
|
|
48
|
+
but is still compatible with the eslintrc configuration format.
|
|
49
|
+
|
|
50
|
+
> [!WARNING]
|
|
51
|
+
> eslintrc compatibility will be removed in v1.
|
|
52
|
+
> Users are highly encouraged to upgrade to ESLint's flat configuration format.
|
|
53
|
+
> See: [https://eslint.org/docs/latest/use/configure/migration-guide]
|
|
54
|
+
|
|
55
|
+
1. Install `eslint-plugin-rxjs-x` using your preferred package manager.
|
|
56
|
+
2. If you previously used the `plugin:rxjs/recommended` shared config,
|
|
57
|
+
replace it with `plugin:rxjs-x/recommended-legacy`:
|
|
25
58
|
|
|
26
59
|
```diff
|
|
27
|
-
extends: [
|
|
28
|
-
|
|
60
|
+
"extends": [
|
|
61
|
+
"plugin:@typescript-eslint/recommended",
|
|
62
|
+
- "plugin:rxjs/recommended",
|
|
63
|
+
+ "plugin:rxjs-x/recommended-legacy",
|
|
29
64
|
],
|
|
30
65
|
```
|
|
31
66
|
|
|
32
|
-
|
|
33
|
-
|
|
67
|
+
3. If you previously did _not_ use a shared config,
|
|
68
|
+
then replace the `rxjs` plugin to your `plugins` block:
|
|
34
69
|
|
|
35
70
|
```diff
|
|
36
|
-
plugins:
|
|
37
|
-
|
|
38
|
-
|
|
71
|
+
"plugins": [
|
|
72
|
+
"@typescript-eslint",
|
|
73
|
+
- "rxjs",
|
|
74
|
+
+ "rxjs-x",
|
|
75
|
+
],
|
|
39
76
|
```
|
|
40
77
|
|
|
41
|
-
- Note: this is unnecessary if you are using
|
|
42
|
-
|
|
78
|
+
- Note: this is unnecessary if you are using the `recommended-legacy` shared config.
|
|
79
|
+
4. In your `rules` blocks, replace the namespace `rxjs` with `rxjs-x` for all rules:
|
|
43
80
|
|
|
44
81
|
```diff
|
|
45
|
-
|
|
46
|
-
|
|
82
|
+
"rules": {
|
|
83
|
+
- "rxjs/no-subject-value": "error",
|
|
84
|
+
+ "rxjs-x/no-subject-value": "error",
|
|
85
|
+
},
|
|
47
86
|
```
|
|
48
87
|
|
|
49
|
-
|
|
88
|
+
- Note: if your project has inline comments (e.g. `eslint-disable-next-line`) referencing `rxjs` rules, you must update the namespace there too.
|
|
89
|
+
5. If you previously used `rxjs/no-ignored-observable`, consider replacing it with `rxjs-x/no-floating-observables`. `no-ignored-observable` will be removed in v1.
|
|
50
90
|
|
|
51
91
|
```diff
|
|
52
92
|
- 'rxjs/no-ignored-observable': 'error',
|
|
53
93
|
+ 'rxjs-x/no-floating-observables': 'error',
|
|
54
94
|
```
|
|
55
95
|
|
|
56
|
-
> [!TIP]
|
|
57
|
-
> A complete description of all changes are documented in the [CHANGELOG](CHANGELOG.md) file.
|
|
58
|
-
|
|
59
|
-
## Installation Guide
|
|
60
|
-
|
|
61
|
-
See [typescript-eslint's Getting Started](https://typescript-eslint.io/getting-started) for a full ESLint setup guide.
|
|
62
|
-
|
|
63
|
-
1. Enable typed linting.
|
|
64
|
-
- See [Linting with Type Information](https://typescript-eslint.io/getting-started/typed-linting/) for more information.
|
|
65
|
-
2. Start with the `recommended` shared config in your `eslint.config.mjs`.
|
|
66
|
-
|
|
67
|
-
```js
|
|
68
|
-
// @ts-check
|
|
69
|
-
import { defineConfig } from 'eslint/config';
|
|
70
|
-
import tseslint from 'typescript-eslint';
|
|
71
|
-
import rxjsX from 'eslint-plugin-rxjs-x';
|
|
72
|
-
|
|
73
|
-
export default defineConfig({
|
|
74
|
-
extends: [
|
|
75
|
-
...tseslint.configs.recommended,
|
|
76
|
-
rxjsX.configs.recommended,
|
|
77
|
-
],
|
|
78
|
-
languageOptions: {
|
|
79
|
-
parserOptions: {
|
|
80
|
-
projectService: true,
|
|
81
|
-
},
|
|
82
|
-
},
|
|
83
|
-
});
|
|
84
|
-
```
|
|
85
|
-
|
|
86
96
|
## Configs
|
|
87
97
|
|
|
88
98
|
<!-- begin auto-generated configs list -->
|
|
@@ -120,13 +130,14 @@ The package includes the following rules.
|
|
|
120
130
|
| [no-connectable](docs/rules/no-connectable.md) | Disallow operators that return connectable observables. | | | | 💭 | |
|
|
121
131
|
| [no-create](docs/rules/no-create.md) | Disallow the static `Observable.create` function. | ✅ 🔒 | | | 💭 | |
|
|
122
132
|
| [no-cyclic-action](docs/rules/no-cyclic-action.md) | Disallow cyclic actions in effects and epics. | | | | 💭 | |
|
|
123
|
-
| [no-explicit-generics](docs/rules/no-explicit-generics.md) | Disallow unnecessary explicit generic type arguments. | | | |
|
|
133
|
+
| [no-explicit-generics](docs/rules/no-explicit-generics.md) | Disallow unnecessary explicit generic type arguments. | | | | 💭 | |
|
|
124
134
|
| [no-exposed-subjects](docs/rules/no-exposed-subjects.md) | Disallow public and protected subjects. | 🔒 | | | 💭 | |
|
|
125
135
|
| [no-finnish](docs/rules/no-finnish.md) | Disallow Finnish notation. | | | | 💭 | |
|
|
126
136
|
| [no-floating-observables](docs/rules/no-floating-observables.md) | Require Observables to be handled appropriately. | 🔒 | | | 💭 | |
|
|
127
137
|
| [no-ignored-default-value](docs/rules/no-ignored-default-value.md) | Disallow using `firstValueFrom`, `lastValueFrom`, `first`, and `last` without specifying a default value. | 🔒 | | | 💭 | |
|
|
128
138
|
| [no-ignored-error](docs/rules/no-ignored-error.md) | Disallow calling `subscribe` without specifying an error handler. | 🔒 | | | 💭 | |
|
|
129
139
|
| [no-ignored-notifier](docs/rules/no-ignored-notifier.md) | Disallow observables not composed from the `repeatWhen` or `retryWhen` notifier. | ✅ 🔒 | | | 💭 | |
|
|
140
|
+
| [no-ignored-observable](docs/rules/no-ignored-observable.md) | Disallow ignoring of observables returned by functions. | | | | | ❌ |
|
|
130
141
|
| [no-ignored-replay-buffer](docs/rules/no-ignored-replay-buffer.md) | Disallow using `ReplaySubject`, `publishReplay` or `shareReplay` without specifying the buffer size. | ✅ 🔒 | | | | |
|
|
131
142
|
| [no-ignored-subscribe](docs/rules/no-ignored-subscribe.md) | Disallow calling `subscribe` without specifying arguments. | | | | 💭 | |
|
|
132
143
|
| [no-ignored-subscription](docs/rules/no-ignored-subscription.md) | Disallow ignoring the subscription returned by `subscribe`. | | | | 💭 | |
|
package/dist/index.d.mts
CHANGED
|
@@ -62,6 +62,7 @@ declare const allRules: {
|
|
|
62
62
|
}, TSESLint.RuleListener>;
|
|
63
63
|
'no-explicit-generics': TSESLint.RuleModule<"forbidden", [], {
|
|
64
64
|
description: "Disallow unnecessary explicit generic type arguments.";
|
|
65
|
+
requiresTypeChecking: true;
|
|
65
66
|
}, TSESLint.RuleListener>;
|
|
66
67
|
'no-exposed-subjects': TSESLint.RuleModule<"forbidden" | "forbiddenAllowProtected", readonly {
|
|
67
68
|
allowProtected?: boolean;
|
|
@@ -96,6 +97,9 @@ declare const allRules: {
|
|
|
96
97
|
recommended: "recommended";
|
|
97
98
|
requiresTypeChecking: true;
|
|
98
99
|
}, TSESLint.RuleListener>;
|
|
100
|
+
'no-ignored-observable': TSESLint.RuleModule<"forbidden", [], {
|
|
101
|
+
description: "Disallow ignoring of observables returned by functions.";
|
|
102
|
+
}, TSESLint.RuleListener>;
|
|
99
103
|
'no-ignored-replay-buffer': TSESLint.RuleModule<"forbidden", [], {
|
|
100
104
|
description: "Disallow using `ReplaySubject`, `publishReplay` or `shareReplay` without specifying the buffer size.";
|
|
101
105
|
recommended: "recommended";
|
|
@@ -115,7 +119,7 @@ declare const allRules: {
|
|
|
115
119
|
description: "Disallow ignoring the value within `takeWhile`.";
|
|
116
120
|
recommended: "recommended";
|
|
117
121
|
}, TSESLint.RuleListener>;
|
|
118
|
-
'no-implicit-any-catch': TSESLint.RuleModule<"explicitAny" | "implicitAny" | "narrowed" | "suggestExplicitUnknown", readonly {
|
|
122
|
+
'no-implicit-any-catch': TSESLint.RuleModule<"explicitAny" | "implicitAny" | "narrowed" | "suggestExplicitUnknown" | "suggestExplicitAny", readonly {
|
|
119
123
|
allowExplicitAny?: boolean;
|
|
120
124
|
}[], {
|
|
121
125
|
description: "Disallow implicit `any` error parameters in `catchError` operators.";
|
|
@@ -241,7 +245,7 @@ declare const allRules: {
|
|
|
241
245
|
recommended: "recommended";
|
|
242
246
|
requiresTypeChecking: true;
|
|
243
247
|
}, TSESLint.RuleListener>;
|
|
244
|
-
'prefer-observer': TSESLint.RuleModule<"forbidden", readonly {
|
|
248
|
+
'prefer-observer': TSESLint.RuleModule<"forbidden" | "suggest", readonly {
|
|
245
249
|
allowNext?: boolean;
|
|
246
250
|
}[], {
|
|
247
251
|
description: "Disallow passing separate handlers to `subscribe` and `tap`.";
|
|
@@ -348,6 +352,31 @@ declare const rxjsX: {
|
|
|
348
352
|
}];
|
|
349
353
|
};
|
|
350
354
|
};
|
|
355
|
+
'recommended-legacy': {
|
|
356
|
+
plugins: ["rxjs-x"];
|
|
357
|
+
rules: {
|
|
358
|
+
'rxjs-x/no-async-subscribe': "error";
|
|
359
|
+
'rxjs-x/no-create': "error";
|
|
360
|
+
'rxjs-x/no-ignored-notifier': "error";
|
|
361
|
+
'rxjs-x/no-ignored-replay-buffer': "error";
|
|
362
|
+
'rxjs-x/no-ignored-takewhile-value': "error";
|
|
363
|
+
'rxjs-x/no-implicit-any-catch': "error";
|
|
364
|
+
'rxjs-x/no-index': "error";
|
|
365
|
+
'rxjs-x/no-internal': "error";
|
|
366
|
+
'rxjs-x/no-nested-subscribe': "error";
|
|
367
|
+
'rxjs-x/no-redundant-notify': "error";
|
|
368
|
+
'rxjs-x/no-sharereplay': "error";
|
|
369
|
+
'rxjs-x/no-subject-unsubscribe': "error";
|
|
370
|
+
'rxjs-x/no-subscribe-in-pipe': "error";
|
|
371
|
+
'rxjs-x/no-topromise': "error";
|
|
372
|
+
'rxjs-x/no-unbound-methods': "error";
|
|
373
|
+
'rxjs-x/no-unsafe-subject-next': "error";
|
|
374
|
+
'rxjs-x/no-unsafe-takeuntil': "error";
|
|
375
|
+
'rxjs-x/prefer-observer': "error";
|
|
376
|
+
'rxjs-x/prefer-root-operators': "error";
|
|
377
|
+
'rxjs-x/throw-error': "error";
|
|
378
|
+
};
|
|
379
|
+
};
|
|
351
380
|
};
|
|
352
381
|
meta: {
|
|
353
382
|
name: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -62,6 +62,7 @@ declare const allRules: {
|
|
|
62
62
|
}, TSESLint.RuleListener>;
|
|
63
63
|
'no-explicit-generics': TSESLint.RuleModule<"forbidden", [], {
|
|
64
64
|
description: "Disallow unnecessary explicit generic type arguments.";
|
|
65
|
+
requiresTypeChecking: true;
|
|
65
66
|
}, TSESLint.RuleListener>;
|
|
66
67
|
'no-exposed-subjects': TSESLint.RuleModule<"forbidden" | "forbiddenAllowProtected", readonly {
|
|
67
68
|
allowProtected?: boolean;
|
|
@@ -96,6 +97,9 @@ declare const allRules: {
|
|
|
96
97
|
recommended: "recommended";
|
|
97
98
|
requiresTypeChecking: true;
|
|
98
99
|
}, TSESLint.RuleListener>;
|
|
100
|
+
'no-ignored-observable': TSESLint.RuleModule<"forbidden", [], {
|
|
101
|
+
description: "Disallow ignoring of observables returned by functions.";
|
|
102
|
+
}, TSESLint.RuleListener>;
|
|
99
103
|
'no-ignored-replay-buffer': TSESLint.RuleModule<"forbidden", [], {
|
|
100
104
|
description: "Disallow using `ReplaySubject`, `publishReplay` or `shareReplay` without specifying the buffer size.";
|
|
101
105
|
recommended: "recommended";
|
|
@@ -115,7 +119,7 @@ declare const allRules: {
|
|
|
115
119
|
description: "Disallow ignoring the value within `takeWhile`.";
|
|
116
120
|
recommended: "recommended";
|
|
117
121
|
}, TSESLint.RuleListener>;
|
|
118
|
-
'no-implicit-any-catch': TSESLint.RuleModule<"explicitAny" | "implicitAny" | "narrowed" | "suggestExplicitUnknown", readonly {
|
|
122
|
+
'no-implicit-any-catch': TSESLint.RuleModule<"explicitAny" | "implicitAny" | "narrowed" | "suggestExplicitUnknown" | "suggestExplicitAny", readonly {
|
|
119
123
|
allowExplicitAny?: boolean;
|
|
120
124
|
}[], {
|
|
121
125
|
description: "Disallow implicit `any` error parameters in `catchError` operators.";
|
|
@@ -241,7 +245,7 @@ declare const allRules: {
|
|
|
241
245
|
recommended: "recommended";
|
|
242
246
|
requiresTypeChecking: true;
|
|
243
247
|
}, TSESLint.RuleListener>;
|
|
244
|
-
'prefer-observer': TSESLint.RuleModule<"forbidden", readonly {
|
|
248
|
+
'prefer-observer': TSESLint.RuleModule<"forbidden" | "suggest", readonly {
|
|
245
249
|
allowNext?: boolean;
|
|
246
250
|
}[], {
|
|
247
251
|
description: "Disallow passing separate handlers to `subscribe` and `tap`.";
|
|
@@ -348,6 +352,31 @@ declare const rxjsX: {
|
|
|
348
352
|
}];
|
|
349
353
|
};
|
|
350
354
|
};
|
|
355
|
+
'recommended-legacy': {
|
|
356
|
+
plugins: ["rxjs-x"];
|
|
357
|
+
rules: {
|
|
358
|
+
'rxjs-x/no-async-subscribe': "error";
|
|
359
|
+
'rxjs-x/no-create': "error";
|
|
360
|
+
'rxjs-x/no-ignored-notifier': "error";
|
|
361
|
+
'rxjs-x/no-ignored-replay-buffer': "error";
|
|
362
|
+
'rxjs-x/no-ignored-takewhile-value': "error";
|
|
363
|
+
'rxjs-x/no-implicit-any-catch': "error";
|
|
364
|
+
'rxjs-x/no-index': "error";
|
|
365
|
+
'rxjs-x/no-internal': "error";
|
|
366
|
+
'rxjs-x/no-nested-subscribe': "error";
|
|
367
|
+
'rxjs-x/no-redundant-notify': "error";
|
|
368
|
+
'rxjs-x/no-sharereplay': "error";
|
|
369
|
+
'rxjs-x/no-subject-unsubscribe': "error";
|
|
370
|
+
'rxjs-x/no-subscribe-in-pipe': "error";
|
|
371
|
+
'rxjs-x/no-topromise': "error";
|
|
372
|
+
'rxjs-x/no-unbound-methods': "error";
|
|
373
|
+
'rxjs-x/no-unsafe-subject-next': "error";
|
|
374
|
+
'rxjs-x/no-unsafe-takeuntil': "error";
|
|
375
|
+
'rxjs-x/prefer-observer': "error";
|
|
376
|
+
'rxjs-x/prefer-root-operators': "error";
|
|
377
|
+
'rxjs-x/throw-error': "error";
|
|
378
|
+
};
|
|
379
|
+
};
|
|
351
380
|
};
|
|
352
381
|
meta: {
|
|
353
382
|
name: string;
|