eslint-plugin-rxjs-x 0.5.1 → 0.6.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/README.md +1 -0
- package/dist/index.d.mts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +51 -1
- package/dist/index.mjs +54 -4
- package/docs/rules/no-subscribe-in-pipe.md +37 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -108,6 +108,7 @@ The package includes the following rules.
|
|
|
108
108
|
| [no-subject-unsubscribe](docs/rules/no-subject-unsubscribe.md) | Disallow calling the `unsubscribe` method of subjects. | ✅ 🔒 | | | 💭 | |
|
|
109
109
|
| [no-subject-value](docs/rules/no-subject-value.md) | Disallow accessing the `value` property of a `BehaviorSubject` instance. | | | | 💭 | |
|
|
110
110
|
| [no-subscribe-handlers](docs/rules/no-subscribe-handlers.md) | Disallow passing handlers to `subscribe`. | | | | 💭 | |
|
|
111
|
+
| [no-subscribe-in-pipe](docs/rules/no-subscribe-in-pipe.md) | Disallow calling of `subscribe` within any RxJS operator inside a `pipe`. | ✅ 🔒 | | | 💭 | |
|
|
111
112
|
| [no-tap](docs/rules/no-tap.md) | Disallow the `tap` operator. | | | | | ❌ |
|
|
112
113
|
| [no-topromise](docs/rules/no-topromise.md) | Disallow use of the `toPromise` method. | ✅ 🔒 | | 💡 | 💭 | |
|
|
113
114
|
| [no-unbound-methods](docs/rules/no-unbound-methods.md) | Disallow passing unbound methods. | ✅ 🔒 | | | 💭 | |
|
package/dist/index.d.mts
CHANGED
|
@@ -35,6 +35,7 @@ declare const rxjsX: {
|
|
|
35
35
|
'rxjs-x/no-redundant-notify': "error";
|
|
36
36
|
'rxjs-x/no-sharereplay': "error";
|
|
37
37
|
'rxjs-x/no-subject-unsubscribe': "error";
|
|
38
|
+
'rxjs-x/no-subscribe-in-pipe': "error";
|
|
38
39
|
'rxjs-x/no-topromise': "error";
|
|
39
40
|
'rxjs-x/no-unbound-methods': "error";
|
|
40
41
|
'rxjs-x/no-unsafe-subject-next': "error";
|
|
@@ -71,6 +72,7 @@ declare const rxjsX: {
|
|
|
71
72
|
'rxjs-x/no-sharereplay': "error";
|
|
72
73
|
'rxjs-x/no-subclass': "error";
|
|
73
74
|
'rxjs-x/no-subject-unsubscribe': "error";
|
|
75
|
+
'rxjs-x/no-subscribe-in-pipe': "error";
|
|
74
76
|
'rxjs-x/no-topromise': "error";
|
|
75
77
|
'rxjs-x/no-unbound-methods': "error";
|
|
76
78
|
'rxjs-x/no-unsafe-subject-next': "error";
|
|
@@ -143,6 +145,7 @@ declare const rxjsX: {
|
|
|
143
145
|
'no-subject-unsubscribe': TSESLint.RuleModule<"forbidden", [], RxjsXRuleDocs, TSESLint.RuleListener>;
|
|
144
146
|
'no-subject-value': TSESLint.RuleModule<"forbidden", [], RxjsXRuleDocs, TSESLint.RuleListener>;
|
|
145
147
|
'no-subscribe-handlers': TSESLint.RuleModule<"forbidden", [], RxjsXRuleDocs, TSESLint.RuleListener>;
|
|
148
|
+
'no-subscribe-in-pipe': TSESLint.RuleModule<"forbidden", [], RxjsXRuleDocs, TSESLint.RuleListener>;
|
|
146
149
|
'no-tap': TSESLint.RuleModule<"forbidden", [], RxjsXRuleDocs, TSESLint.RuleListener>;
|
|
147
150
|
'no-topromise': TSESLint.RuleModule<"forbidden" | "suggestLastValueFrom" | "suggestFirstValueFrom", [], RxjsXRuleDocs, TSESLint.RuleListener>;
|
|
148
151
|
'no-unbound-methods': TSESLint.RuleModule<"forbidden", [], RxjsXRuleDocs, TSESLint.RuleListener>;
|
package/dist/index.d.ts
CHANGED
|
@@ -35,6 +35,7 @@ declare const rxjsX: {
|
|
|
35
35
|
'rxjs-x/no-redundant-notify': "error";
|
|
36
36
|
'rxjs-x/no-sharereplay': "error";
|
|
37
37
|
'rxjs-x/no-subject-unsubscribe': "error";
|
|
38
|
+
'rxjs-x/no-subscribe-in-pipe': "error";
|
|
38
39
|
'rxjs-x/no-topromise': "error";
|
|
39
40
|
'rxjs-x/no-unbound-methods': "error";
|
|
40
41
|
'rxjs-x/no-unsafe-subject-next': "error";
|
|
@@ -71,6 +72,7 @@ declare const rxjsX: {
|
|
|
71
72
|
'rxjs-x/no-sharereplay': "error";
|
|
72
73
|
'rxjs-x/no-subclass': "error";
|
|
73
74
|
'rxjs-x/no-subject-unsubscribe': "error";
|
|
75
|
+
'rxjs-x/no-subscribe-in-pipe': "error";
|
|
74
76
|
'rxjs-x/no-topromise': "error";
|
|
75
77
|
'rxjs-x/no-unbound-methods': "error";
|
|
76
78
|
'rxjs-x/no-unsafe-subject-next': "error";
|
|
@@ -143,6 +145,7 @@ declare const rxjsX: {
|
|
|
143
145
|
'no-subject-unsubscribe': TSESLint.RuleModule<"forbidden", [], RxjsXRuleDocs, TSESLint.RuleListener>;
|
|
144
146
|
'no-subject-value': TSESLint.RuleModule<"forbidden", [], RxjsXRuleDocs, TSESLint.RuleListener>;
|
|
145
147
|
'no-subscribe-handlers': TSESLint.RuleModule<"forbidden", [], RxjsXRuleDocs, TSESLint.RuleListener>;
|
|
148
|
+
'no-subscribe-in-pipe': TSESLint.RuleModule<"forbidden", [], RxjsXRuleDocs, TSESLint.RuleListener>;
|
|
146
149
|
'no-tap': TSESLint.RuleModule<"forbidden", [], RxjsXRuleDocs, TSESLint.RuleListener>;
|
|
147
150
|
'no-topromise': TSESLint.RuleModule<"forbidden" | "suggestLastValueFrom" | "suggestFirstValueFrom", [], RxjsXRuleDocs, TSESLint.RuleListener>;
|
|
148
151
|
'no-unbound-methods': TSESLint.RuleModule<"forbidden", [], RxjsXRuleDocs, TSESLint.RuleListener>;
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }// package.json
|
|
2
2
|
var name = "eslint-plugin-rxjs-x";
|
|
3
|
-
var version = "0.
|
|
3
|
+
var version = "0.6.0";
|
|
4
4
|
|
|
5
5
|
// src/configs/recommended.ts
|
|
6
6
|
var createRecommendedConfig = (plugin2) => ({
|
|
@@ -21,6 +21,7 @@ var createRecommendedConfig = (plugin2) => ({
|
|
|
21
21
|
"rxjs-x/no-redundant-notify": "error",
|
|
22
22
|
"rxjs-x/no-sharereplay": "error",
|
|
23
23
|
"rxjs-x/no-subject-unsubscribe": "error",
|
|
24
|
+
"rxjs-x/no-subscribe-in-pipe": "error",
|
|
24
25
|
"rxjs-x/no-topromise": "error",
|
|
25
26
|
"rxjs-x/no-unbound-methods": "error",
|
|
26
27
|
"rxjs-x/no-unsafe-subject-next": "error",
|
|
@@ -59,6 +60,7 @@ var createStrictConfig = (plugin2) => ({
|
|
|
59
60
|
"rxjs-x/no-sharereplay": "error",
|
|
60
61
|
"rxjs-x/no-subclass": "error",
|
|
61
62
|
"rxjs-x/no-subject-unsubscribe": "error",
|
|
63
|
+
"rxjs-x/no-subscribe-in-pipe": "error",
|
|
62
64
|
"rxjs-x/no-topromise": "error",
|
|
63
65
|
"rxjs-x/no-unbound-methods": "error",
|
|
64
66
|
"rxjs-x/no-unsafe-subject-next": "error",
|
|
@@ -2814,6 +2816,53 @@ var noSubscribeHandlersRule = ruleCreator({
|
|
|
2814
2816
|
}
|
|
2815
2817
|
});
|
|
2816
2818
|
|
|
2819
|
+
// src/rules/no-subscribe-in-pipe.ts
|
|
2820
|
+
|
|
2821
|
+
var noSubscribeInPipeRule = ruleCreator({
|
|
2822
|
+
defaultOptions: [],
|
|
2823
|
+
meta: {
|
|
2824
|
+
docs: {
|
|
2825
|
+
description: "Disallow calling of `subscribe` within any RxJS operator inside a `pipe`.",
|
|
2826
|
+
recommended: "recommended",
|
|
2827
|
+
requiresTypeChecking: true
|
|
2828
|
+
},
|
|
2829
|
+
fixable: void 0,
|
|
2830
|
+
hasSuggestions: false,
|
|
2831
|
+
messages: {
|
|
2832
|
+
forbidden: "Subscribe calls within pipe operators are forbidden."
|
|
2833
|
+
},
|
|
2834
|
+
schema: [],
|
|
2835
|
+
type: "problem"
|
|
2836
|
+
},
|
|
2837
|
+
name: "no-subscribe-in-pipe",
|
|
2838
|
+
create: (context) => {
|
|
2839
|
+
const { couldBeObservable, couldBeType: couldBeType2 } = getTypeServices(context);
|
|
2840
|
+
function isWithinPipe(node) {
|
|
2841
|
+
let parent = node.parent;
|
|
2842
|
+
while (parent) {
|
|
2843
|
+
if (parent.type === _utils.AST_NODE_TYPES.CallExpression && parent.callee.type === _utils.AST_NODE_TYPES.MemberExpression && parent.callee.property.type === _utils.AST_NODE_TYPES.Identifier && parent.callee.property.name === "pipe") {
|
|
2844
|
+
return true;
|
|
2845
|
+
}
|
|
2846
|
+
parent = parent.parent;
|
|
2847
|
+
}
|
|
2848
|
+
return false;
|
|
2849
|
+
}
|
|
2850
|
+
return {
|
|
2851
|
+
"CallExpression > MemberExpression[property.name='subscribe']": (node) => {
|
|
2852
|
+
if (!couldBeObservable(node.object) && !couldBeType2(node.object, "Subscribable")) {
|
|
2853
|
+
return;
|
|
2854
|
+
}
|
|
2855
|
+
if (isWithinPipe(node)) {
|
|
2856
|
+
context.report({
|
|
2857
|
+
messageId: "forbidden",
|
|
2858
|
+
node: node.property
|
|
2859
|
+
});
|
|
2860
|
+
}
|
|
2861
|
+
}
|
|
2862
|
+
};
|
|
2863
|
+
}
|
|
2864
|
+
});
|
|
2865
|
+
|
|
2817
2866
|
// src/rules/no-tap.ts
|
|
2818
2867
|
var noTapRule = ruleCreator({
|
|
2819
2868
|
defaultOptions: [],
|
|
@@ -3972,6 +4021,7 @@ var plugin = {
|
|
|
3972
4021
|
"no-subject-unsubscribe": noSubjectUnsubscribeRule,
|
|
3973
4022
|
"no-subject-value": noSubjectValueRule,
|
|
3974
4023
|
"no-subscribe-handlers": noSubscribeHandlersRule,
|
|
4024
|
+
"no-subscribe-in-pipe": noSubscribeInPipeRule,
|
|
3975
4025
|
"no-tap": noTapRule,
|
|
3976
4026
|
"no-topromise": noTopromiseRule,
|
|
3977
4027
|
"no-unbound-methods": noUnboundMethodsRule,
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// package.json
|
|
2
2
|
var name = "eslint-plugin-rxjs-x";
|
|
3
|
-
var version = "0.
|
|
3
|
+
var version = "0.6.0";
|
|
4
4
|
|
|
5
5
|
// src/configs/recommended.ts
|
|
6
6
|
var createRecommendedConfig = (plugin2) => ({
|
|
@@ -21,6 +21,7 @@ var createRecommendedConfig = (plugin2) => ({
|
|
|
21
21
|
"rxjs-x/no-redundant-notify": "error",
|
|
22
22
|
"rxjs-x/no-sharereplay": "error",
|
|
23
23
|
"rxjs-x/no-subject-unsubscribe": "error",
|
|
24
|
+
"rxjs-x/no-subscribe-in-pipe": "error",
|
|
24
25
|
"rxjs-x/no-topromise": "error",
|
|
25
26
|
"rxjs-x/no-unbound-methods": "error",
|
|
26
27
|
"rxjs-x/no-unsafe-subject-next": "error",
|
|
@@ -59,6 +60,7 @@ var createStrictConfig = (plugin2) => ({
|
|
|
59
60
|
"rxjs-x/no-sharereplay": "error",
|
|
60
61
|
"rxjs-x/no-subclass": "error",
|
|
61
62
|
"rxjs-x/no-subject-unsubscribe": "error",
|
|
63
|
+
"rxjs-x/no-subscribe-in-pipe": "error",
|
|
62
64
|
"rxjs-x/no-topromise": "error",
|
|
63
65
|
"rxjs-x/no-unbound-methods": "error",
|
|
64
66
|
"rxjs-x/no-unsafe-subject-next": "error",
|
|
@@ -2814,6 +2816,53 @@ var noSubscribeHandlersRule = ruleCreator({
|
|
|
2814
2816
|
}
|
|
2815
2817
|
});
|
|
2816
2818
|
|
|
2819
|
+
// src/rules/no-subscribe-in-pipe.ts
|
|
2820
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES8 } from "@typescript-eslint/utils";
|
|
2821
|
+
var noSubscribeInPipeRule = ruleCreator({
|
|
2822
|
+
defaultOptions: [],
|
|
2823
|
+
meta: {
|
|
2824
|
+
docs: {
|
|
2825
|
+
description: "Disallow calling of `subscribe` within any RxJS operator inside a `pipe`.",
|
|
2826
|
+
recommended: "recommended",
|
|
2827
|
+
requiresTypeChecking: true
|
|
2828
|
+
},
|
|
2829
|
+
fixable: void 0,
|
|
2830
|
+
hasSuggestions: false,
|
|
2831
|
+
messages: {
|
|
2832
|
+
forbidden: "Subscribe calls within pipe operators are forbidden."
|
|
2833
|
+
},
|
|
2834
|
+
schema: [],
|
|
2835
|
+
type: "problem"
|
|
2836
|
+
},
|
|
2837
|
+
name: "no-subscribe-in-pipe",
|
|
2838
|
+
create: (context) => {
|
|
2839
|
+
const { couldBeObservable, couldBeType: couldBeType2 } = getTypeServices(context);
|
|
2840
|
+
function isWithinPipe(node) {
|
|
2841
|
+
let parent = node.parent;
|
|
2842
|
+
while (parent) {
|
|
2843
|
+
if (parent.type === AST_NODE_TYPES8.CallExpression && parent.callee.type === AST_NODE_TYPES8.MemberExpression && parent.callee.property.type === AST_NODE_TYPES8.Identifier && parent.callee.property.name === "pipe") {
|
|
2844
|
+
return true;
|
|
2845
|
+
}
|
|
2846
|
+
parent = parent.parent;
|
|
2847
|
+
}
|
|
2848
|
+
return false;
|
|
2849
|
+
}
|
|
2850
|
+
return {
|
|
2851
|
+
"CallExpression > MemberExpression[property.name='subscribe']": (node) => {
|
|
2852
|
+
if (!couldBeObservable(node.object) && !couldBeType2(node.object, "Subscribable")) {
|
|
2853
|
+
return;
|
|
2854
|
+
}
|
|
2855
|
+
if (isWithinPipe(node)) {
|
|
2856
|
+
context.report({
|
|
2857
|
+
messageId: "forbidden",
|
|
2858
|
+
node: node.property
|
|
2859
|
+
});
|
|
2860
|
+
}
|
|
2861
|
+
}
|
|
2862
|
+
};
|
|
2863
|
+
}
|
|
2864
|
+
});
|
|
2865
|
+
|
|
2817
2866
|
// src/rules/no-tap.ts
|
|
2818
2867
|
var noTapRule = ruleCreator({
|
|
2819
2868
|
defaultOptions: [],
|
|
@@ -3660,7 +3709,7 @@ var preferRootOperatorsRule = ruleCreator({
|
|
|
3660
3709
|
});
|
|
3661
3710
|
|
|
3662
3711
|
// src/rules/suffix-subjects.ts
|
|
3663
|
-
import { AST_NODE_TYPES as
|
|
3712
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES9, ESLintUtils as ESLintUtils11 } from "@typescript-eslint/utils";
|
|
3664
3713
|
var defaultOptions15 = [];
|
|
3665
3714
|
var suffixSubjectsRule = ruleCreator({
|
|
3666
3715
|
defaultOptions: defaultOptions15,
|
|
@@ -3744,7 +3793,7 @@ var suffixSubjectsRule = ruleCreator({
|
|
|
3744
3793
|
if (!found) {
|
|
3745
3794
|
return;
|
|
3746
3795
|
}
|
|
3747
|
-
if (!validate.variables && found.type ===
|
|
3796
|
+
if (!validate.variables && found.type === AST_NODE_TYPES9.VariableDeclarator) {
|
|
3748
3797
|
return;
|
|
3749
3798
|
}
|
|
3750
3799
|
if (!validate.parameters) {
|
|
@@ -3811,7 +3860,7 @@ var suffixSubjectsRule = ruleCreator({
|
|
|
3811
3860
|
if (!found) {
|
|
3812
3861
|
return;
|
|
3813
3862
|
}
|
|
3814
|
-
if (!validate.variables && found.type ===
|
|
3863
|
+
if (!validate.variables && found.type === AST_NODE_TYPES9.VariableDeclarator) {
|
|
3815
3864
|
return;
|
|
3816
3865
|
}
|
|
3817
3866
|
if (!validate.parameters) {
|
|
@@ -3972,6 +4021,7 @@ var plugin = {
|
|
|
3972
4021
|
"no-subject-unsubscribe": noSubjectUnsubscribeRule,
|
|
3973
4022
|
"no-subject-value": noSubjectValueRule,
|
|
3974
4023
|
"no-subscribe-handlers": noSubscribeHandlersRule,
|
|
4024
|
+
"no-subscribe-in-pipe": noSubscribeInPipeRule,
|
|
3975
4025
|
"no-tap": noTapRule,
|
|
3976
4026
|
"no-topromise": noTopromiseRule,
|
|
3977
4027
|
"no-unbound-methods": noUnboundMethodsRule,
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Disallow calling of `subscribe` within any RxJS operator inside a `pipe` (`rxjs-x/no-subscribe-in-pipe`)
|
|
2
|
+
|
|
3
|
+
💼 This rule is enabled in the following configs: ✅ `recommended`, 🔒 `strict`.
|
|
4
|
+
|
|
5
|
+
💭 This rule requires [type information](https://typescript-eslint.io/linting/typed-linting).
|
|
6
|
+
|
|
7
|
+
<!-- end auto-generated rule header -->
|
|
8
|
+
|
|
9
|
+
This rule effects failures if `subscribe` is called within any operator inside a `pipe` operation.
|
|
10
|
+
|
|
11
|
+
## Rule details
|
|
12
|
+
|
|
13
|
+
Examples of **incorrect** code for this rule:
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { of } from "rxjs";
|
|
17
|
+
import { map } from "rxjs/operators";
|
|
18
|
+
|
|
19
|
+
of(42, 54).pipe(
|
|
20
|
+
map(value => {
|
|
21
|
+
of(value).subscribe(console.log); // This will trigger the rule
|
|
22
|
+
return value * 2;
|
|
23
|
+
})
|
|
24
|
+
).subscribe(result => console.log(result));
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Examples of **correct** code for this rule:
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
import { of } from "rxjs";
|
|
31
|
+
import { map, tap } from "rxjs/operators";
|
|
32
|
+
|
|
33
|
+
of(42, 54).pipe(
|
|
34
|
+
tap(value => console.log(value)),
|
|
35
|
+
map(value => value * 2)
|
|
36
|
+
).subscribe(result => console.log(result));
|
|
37
|
+
```
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-rxjs-x",
|
|
3
3
|
"type": "commonjs",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.6.0",
|
|
5
5
|
"packageManager": "yarn@4.5.3+sha512.3003a14012e2987072d244c720506549c1aab73ee728208f1b2580a9fd67b92d61ba6b08fe93f6dce68fd771e3af1e59a0afa28dd242dd0940d73b95fedd4e90",
|
|
6
6
|
"description": "ESLint v9+ plugin for RxJS",
|
|
7
7
|
"author": "Jason Weinzierl <weinzierljason@gmail.com>",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"peerDependencies": {
|
|
66
66
|
"eslint": "^8.57.0 || ^9.0.0",
|
|
67
67
|
"rxjs": ">=7.2.0",
|
|
68
|
-
"typescript": ">=4.
|
|
68
|
+
"typescript": ">=4.8.4"
|
|
69
69
|
},
|
|
70
70
|
"peerDependenciesMeta": {
|
|
71
71
|
"rxjs": {
|