eslint-plugin-rxjs-x 0.5.1 → 0.6.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.
package/README.md CHANGED
@@ -86,7 +86,7 @@ The package includes the following rules.
86
86
  | [no-connectable](docs/rules/no-connectable.md) | Disallow operators that return connectable observables. | | | | 💭 | |
87
87
  | [no-create](docs/rules/no-create.md) | Disallow the static `Observable.create` function. | ✅ 🔒 | | | 💭 | |
88
88
  | [no-cyclic-action](docs/rules/no-cyclic-action.md) | Disallow cyclic actions in effects and epics. | | | | 💭 | |
89
- | [no-explicit-generics](docs/rules/no-explicit-generics.md) | Disallow unnecessary explicit generic type arguments. | 🔒 | | | | |
89
+ | [no-explicit-generics](docs/rules/no-explicit-generics.md) | Disallow unnecessary explicit generic type arguments. | | | | | |
90
90
  | [no-exposed-subjects](docs/rules/no-exposed-subjects.md) | Disallow public and protected subjects. | 🔒 | | | 💭 | |
91
91
  | [no-finnish](docs/rules/no-finnish.md) | Disallow Finnish notation. | | | | 💭 | |
92
92
  | [no-floating-observables](docs/rules/no-floating-observables.md) | Require Observables to be handled appropriately. | 🔒 | | | 💭 | |
@@ -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";
@@ -52,7 +53,6 @@ declare const rxjsX: {
52
53
  rules: {
53
54
  'rxjs-x/no-async-subscribe': "error";
54
55
  'rxjs-x/no-create': "error";
55
- 'rxjs-x/no-explicit-generics': "error";
56
56
  'rxjs-x/no-exposed-subjects': "error";
57
57
  'rxjs-x/no-floating-observables': "error";
58
58
  'rxjs-x/no-ignored-default-value': "error";
@@ -71,6 +71,7 @@ declare const rxjsX: {
71
71
  'rxjs-x/no-sharereplay': "error";
72
72
  'rxjs-x/no-subclass': "error";
73
73
  'rxjs-x/no-subject-unsubscribe': "error";
74
+ 'rxjs-x/no-subscribe-in-pipe': "error";
74
75
  'rxjs-x/no-topromise': "error";
75
76
  'rxjs-x/no-unbound-methods': "error";
76
77
  'rxjs-x/no-unsafe-subject-next': "error";
@@ -143,6 +144,7 @@ declare const rxjsX: {
143
144
  'no-subject-unsubscribe': TSESLint.RuleModule<"forbidden", [], RxjsXRuleDocs, TSESLint.RuleListener>;
144
145
  'no-subject-value': TSESLint.RuleModule<"forbidden", [], RxjsXRuleDocs, TSESLint.RuleListener>;
145
146
  'no-subscribe-handlers': TSESLint.RuleModule<"forbidden", [], RxjsXRuleDocs, TSESLint.RuleListener>;
147
+ 'no-subscribe-in-pipe': TSESLint.RuleModule<"forbidden", [], RxjsXRuleDocs, TSESLint.RuleListener>;
146
148
  'no-tap': TSESLint.RuleModule<"forbidden", [], RxjsXRuleDocs, TSESLint.RuleListener>;
147
149
  'no-topromise': TSESLint.RuleModule<"forbidden" | "suggestLastValueFrom" | "suggestFirstValueFrom", [], RxjsXRuleDocs, TSESLint.RuleListener>;
148
150
  '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";
@@ -52,7 +53,6 @@ declare const rxjsX: {
52
53
  rules: {
53
54
  'rxjs-x/no-async-subscribe': "error";
54
55
  'rxjs-x/no-create': "error";
55
- 'rxjs-x/no-explicit-generics': "error";
56
56
  'rxjs-x/no-exposed-subjects': "error";
57
57
  'rxjs-x/no-floating-observables': "error";
58
58
  'rxjs-x/no-ignored-default-value': "error";
@@ -71,6 +71,7 @@ declare const rxjsX: {
71
71
  'rxjs-x/no-sharereplay': "error";
72
72
  'rxjs-x/no-subclass': "error";
73
73
  'rxjs-x/no-subject-unsubscribe': "error";
74
+ 'rxjs-x/no-subscribe-in-pipe': "error";
74
75
  'rxjs-x/no-topromise': "error";
75
76
  'rxjs-x/no-unbound-methods': "error";
76
77
  'rxjs-x/no-unsafe-subject-next': "error";
@@ -143,6 +144,7 @@ declare const rxjsX: {
143
144
  'no-subject-unsubscribe': TSESLint.RuleModule<"forbidden", [], RxjsXRuleDocs, TSESLint.RuleListener>;
144
145
  'no-subject-value': TSESLint.RuleModule<"forbidden", [], RxjsXRuleDocs, TSESLint.RuleListener>;
145
146
  'no-subscribe-handlers': TSESLint.RuleModule<"forbidden", [], RxjsXRuleDocs, TSESLint.RuleListener>;
147
+ 'no-subscribe-in-pipe': TSESLint.RuleModule<"forbidden", [], RxjsXRuleDocs, TSESLint.RuleListener>;
146
148
  'no-tap': TSESLint.RuleModule<"forbidden", [], RxjsXRuleDocs, TSESLint.RuleListener>;
147
149
  'no-topromise': TSESLint.RuleModule<"forbidden" | "suggestLastValueFrom" | "suggestFirstValueFrom", [], RxjsXRuleDocs, TSESLint.RuleListener>;
148
150
  '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.5.1";
3
+ var version = "0.6.1";
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",
@@ -40,7 +41,6 @@ var createStrictConfig = (plugin2) => ({
40
41
  rules: {
41
42
  "rxjs-x/no-async-subscribe": "error",
42
43
  "rxjs-x/no-create": "error",
43
- "rxjs-x/no-explicit-generics": "error",
44
44
  "rxjs-x/no-exposed-subjects": "error",
45
45
  "rxjs-x/no-floating-observables": "error",
46
46
  "rxjs-x/no-ignored-default-value": "error",
@@ -59,6 +59,7 @@ var createStrictConfig = (plugin2) => ({
59
59
  "rxjs-x/no-sharereplay": "error",
60
60
  "rxjs-x/no-subclass": "error",
61
61
  "rxjs-x/no-subject-unsubscribe": "error",
62
+ "rxjs-x/no-subscribe-in-pipe": "error",
62
63
  "rxjs-x/no-topromise": "error",
63
64
  "rxjs-x/no-unbound-methods": "error",
64
65
  "rxjs-x/no-unsafe-subject-next": "error",
@@ -1094,8 +1095,7 @@ var noExplicitGenericsRule = ruleCreator({
1094
1095
  defaultOptions: [],
1095
1096
  meta: {
1096
1097
  docs: {
1097
- description: "Disallow unnecessary explicit generic type arguments.",
1098
- recommended: "strict"
1098
+ description: "Disallow unnecessary explicit generic type arguments."
1099
1099
  },
1100
1100
  messages: {
1101
1101
  forbidden: "Explicit generic type arguments are forbidden."
@@ -2814,6 +2814,53 @@ var noSubscribeHandlersRule = ruleCreator({
2814
2814
  }
2815
2815
  });
2816
2816
 
2817
+ // src/rules/no-subscribe-in-pipe.ts
2818
+
2819
+ var noSubscribeInPipeRule = ruleCreator({
2820
+ defaultOptions: [],
2821
+ meta: {
2822
+ docs: {
2823
+ description: "Disallow calling of `subscribe` within any RxJS operator inside a `pipe`.",
2824
+ recommended: "recommended",
2825
+ requiresTypeChecking: true
2826
+ },
2827
+ fixable: void 0,
2828
+ hasSuggestions: false,
2829
+ messages: {
2830
+ forbidden: "Subscribe calls within pipe operators are forbidden."
2831
+ },
2832
+ schema: [],
2833
+ type: "problem"
2834
+ },
2835
+ name: "no-subscribe-in-pipe",
2836
+ create: (context) => {
2837
+ const { couldBeObservable, couldBeType: couldBeType2 } = getTypeServices(context);
2838
+ function isWithinPipe(node) {
2839
+ let parent = node.parent;
2840
+ while (parent) {
2841
+ 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") {
2842
+ return true;
2843
+ }
2844
+ parent = parent.parent;
2845
+ }
2846
+ return false;
2847
+ }
2848
+ return {
2849
+ "CallExpression > MemberExpression[property.name='subscribe']": (node) => {
2850
+ if (!couldBeObservable(node.object) && !couldBeType2(node.object, "Subscribable")) {
2851
+ return;
2852
+ }
2853
+ if (isWithinPipe(node)) {
2854
+ context.report({
2855
+ messageId: "forbidden",
2856
+ node: node.property
2857
+ });
2858
+ }
2859
+ }
2860
+ };
2861
+ }
2862
+ });
2863
+
2817
2864
  // src/rules/no-tap.ts
2818
2865
  var noTapRule = ruleCreator({
2819
2866
  defaultOptions: [],
@@ -3972,6 +4019,7 @@ var plugin = {
3972
4019
  "no-subject-unsubscribe": noSubjectUnsubscribeRule,
3973
4020
  "no-subject-value": noSubjectValueRule,
3974
4021
  "no-subscribe-handlers": noSubscribeHandlersRule,
4022
+ "no-subscribe-in-pipe": noSubscribeInPipeRule,
3975
4023
  "no-tap": noTapRule,
3976
4024
  "no-topromise": noTopromiseRule,
3977
4025
  "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.5.1";
3
+ var version = "0.6.1";
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",
@@ -40,7 +41,6 @@ var createStrictConfig = (plugin2) => ({
40
41
  rules: {
41
42
  "rxjs-x/no-async-subscribe": "error",
42
43
  "rxjs-x/no-create": "error",
43
- "rxjs-x/no-explicit-generics": "error",
44
44
  "rxjs-x/no-exposed-subjects": "error",
45
45
  "rxjs-x/no-floating-observables": "error",
46
46
  "rxjs-x/no-ignored-default-value": "error",
@@ -59,6 +59,7 @@ var createStrictConfig = (plugin2) => ({
59
59
  "rxjs-x/no-sharereplay": "error",
60
60
  "rxjs-x/no-subclass": "error",
61
61
  "rxjs-x/no-subject-unsubscribe": "error",
62
+ "rxjs-x/no-subscribe-in-pipe": "error",
62
63
  "rxjs-x/no-topromise": "error",
63
64
  "rxjs-x/no-unbound-methods": "error",
64
65
  "rxjs-x/no-unsafe-subject-next": "error",
@@ -1094,8 +1095,7 @@ var noExplicitGenericsRule = ruleCreator({
1094
1095
  defaultOptions: [],
1095
1096
  meta: {
1096
1097
  docs: {
1097
- description: "Disallow unnecessary explicit generic type arguments.",
1098
- recommended: "strict"
1098
+ description: "Disallow unnecessary explicit generic type arguments."
1099
1099
  },
1100
1100
  messages: {
1101
1101
  forbidden: "Explicit generic type arguments are forbidden."
@@ -2814,6 +2814,53 @@ var noSubscribeHandlersRule = ruleCreator({
2814
2814
  }
2815
2815
  });
2816
2816
 
2817
+ // src/rules/no-subscribe-in-pipe.ts
2818
+ import { AST_NODE_TYPES as AST_NODE_TYPES8 } from "@typescript-eslint/utils";
2819
+ var noSubscribeInPipeRule = ruleCreator({
2820
+ defaultOptions: [],
2821
+ meta: {
2822
+ docs: {
2823
+ description: "Disallow calling of `subscribe` within any RxJS operator inside a `pipe`.",
2824
+ recommended: "recommended",
2825
+ requiresTypeChecking: true
2826
+ },
2827
+ fixable: void 0,
2828
+ hasSuggestions: false,
2829
+ messages: {
2830
+ forbidden: "Subscribe calls within pipe operators are forbidden."
2831
+ },
2832
+ schema: [],
2833
+ type: "problem"
2834
+ },
2835
+ name: "no-subscribe-in-pipe",
2836
+ create: (context) => {
2837
+ const { couldBeObservable, couldBeType: couldBeType2 } = getTypeServices(context);
2838
+ function isWithinPipe(node) {
2839
+ let parent = node.parent;
2840
+ while (parent) {
2841
+ 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") {
2842
+ return true;
2843
+ }
2844
+ parent = parent.parent;
2845
+ }
2846
+ return false;
2847
+ }
2848
+ return {
2849
+ "CallExpression > MemberExpression[property.name='subscribe']": (node) => {
2850
+ if (!couldBeObservable(node.object) && !couldBeType2(node.object, "Subscribable")) {
2851
+ return;
2852
+ }
2853
+ if (isWithinPipe(node)) {
2854
+ context.report({
2855
+ messageId: "forbidden",
2856
+ node: node.property
2857
+ });
2858
+ }
2859
+ }
2860
+ };
2861
+ }
2862
+ });
2863
+
2817
2864
  // src/rules/no-tap.ts
2818
2865
  var noTapRule = ruleCreator({
2819
2866
  defaultOptions: [],
@@ -3660,7 +3707,7 @@ var preferRootOperatorsRule = ruleCreator({
3660
3707
  });
3661
3708
 
3662
3709
  // src/rules/suffix-subjects.ts
3663
- import { AST_NODE_TYPES as AST_NODE_TYPES8, ESLintUtils as ESLintUtils11 } from "@typescript-eslint/utils";
3710
+ import { AST_NODE_TYPES as AST_NODE_TYPES9, ESLintUtils as ESLintUtils11 } from "@typescript-eslint/utils";
3664
3711
  var defaultOptions15 = [];
3665
3712
  var suffixSubjectsRule = ruleCreator({
3666
3713
  defaultOptions: defaultOptions15,
@@ -3744,7 +3791,7 @@ var suffixSubjectsRule = ruleCreator({
3744
3791
  if (!found) {
3745
3792
  return;
3746
3793
  }
3747
- if (!validate.variables && found.type === AST_NODE_TYPES8.VariableDeclarator) {
3794
+ if (!validate.variables && found.type === AST_NODE_TYPES9.VariableDeclarator) {
3748
3795
  return;
3749
3796
  }
3750
3797
  if (!validate.parameters) {
@@ -3811,7 +3858,7 @@ var suffixSubjectsRule = ruleCreator({
3811
3858
  if (!found) {
3812
3859
  return;
3813
3860
  }
3814
- if (!validate.variables && found.type === AST_NODE_TYPES8.VariableDeclarator) {
3861
+ if (!validate.variables && found.type === AST_NODE_TYPES9.VariableDeclarator) {
3815
3862
  return;
3816
3863
  }
3817
3864
  if (!validate.parameters) {
@@ -3972,6 +4019,7 @@ var plugin = {
3972
4019
  "no-subject-unsubscribe": noSubjectUnsubscribeRule,
3973
4020
  "no-subject-value": noSubjectValueRule,
3974
4021
  "no-subscribe-handlers": noSubscribeHandlersRule,
4022
+ "no-subscribe-in-pipe": noSubscribeInPipeRule,
3975
4023
  "no-tap": noTapRule,
3976
4024
  "no-topromise": noTopromiseRule,
3977
4025
  "no-unbound-methods": noUnboundMethodsRule,
@@ -1,7 +1,5 @@
1
1
  # Disallow unnecessary explicit generic type arguments (`rxjs-x/no-explicit-generics`)
2
2
 
3
- 💼 This rule is enabled in the 🔒 `strict` config.
4
-
5
3
  <!-- end auto-generated rule header -->
6
4
 
7
5
  This rule prevents the use of explicit type arguments when the type arguments can be inferred.
@@ -21,3 +19,7 @@ Examples of **correct** code for this rule:
21
19
  import { BehaviorSubject } from "rxjs";
22
20
  const subject = new BehaviorSubject(42);
23
21
  ```
22
+
23
+ ## Known problems
24
+
25
+ - ([#77](https://github.com/JasonWeinzierl/eslint-plugin-rxjs-x/issues/77)) Type unions cause false positives e.g. `new BehaviorSubject<number | null>(null)` will be incorrectly caught by this rule.
@@ -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.5.1",
4
+ "version": "0.6.1",
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.7.4"
68
+ "typescript": ">=4.8.4"
69
69
  },
70
70
  "peerDependenciesMeta": {
71
71
  "rxjs": {