eslint-plugin-rxjs-x 0.3.0 → 0.3.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/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.0";
3
+ var version = "0.3.1";
4
4
 
5
5
  // src/configs/recommended.ts
6
6
  var createRecommendedConfig = (plugin2) => ({
@@ -1370,6 +1370,7 @@ var noIgnoredDefaultValueRule = ruleCreator({
1370
1370
  });
1371
1371
 
1372
1372
  // src/rules/no-ignored-error.ts
1373
+
1373
1374
  var noIgnoredErrorRule = ruleCreator({
1374
1375
  defaultOptions: [],
1375
1376
  meta: {
@@ -1385,12 +1386,44 @@ var noIgnoredErrorRule = ruleCreator({
1385
1386
  },
1386
1387
  name: "no-ignored-error",
1387
1388
  create: (context) => {
1389
+ const { getTypeAtLocation } = _utils.ESLintUtils.getParserServices(context);
1388
1390
  const { couldBeObservable, couldBeFunction: couldBeFunction2 } = getTypeServices(context);
1391
+ function isMissingErrorCallback(callExpression) {
1392
+ if (callExpression.arguments.length >= 2) {
1393
+ return false;
1394
+ }
1395
+ return couldBeFunction2(callExpression.arguments[0]);
1396
+ }
1397
+ function isObjMissingError(arg) {
1398
+ return !arg.properties.some(
1399
+ (property) => isProperty(property) && isIdentifier(property.key) && property.key.name === "error"
1400
+ );
1401
+ }
1402
+ function isTypeMissingError(arg) {
1403
+ const argType = getTypeAtLocation(arg);
1404
+ return !(argType == null ? void 0 : argType.getProperties().some((p) => p.name === "error"));
1405
+ }
1406
+ function isMissingErrorProperty(callExpression) {
1407
+ if (callExpression.arguments.length !== 1) {
1408
+ return false;
1409
+ }
1410
+ const [arg] = callExpression.arguments;
1411
+ if (isObjectExpression(arg)) {
1412
+ return isObjMissingError(arg);
1413
+ }
1414
+ if (isIdentifier(arg)) {
1415
+ return isTypeMissingError(arg);
1416
+ }
1417
+ if (isMemberExpression(arg) && isIdentifier(arg.property)) {
1418
+ return isTypeMissingError(arg.property);
1419
+ }
1420
+ return false;
1421
+ }
1389
1422
  return {
1390
1423
  "CallExpression[arguments.length > 0] > MemberExpression > Identifier[name='subscribe']": (node) => {
1391
1424
  const memberExpression = node.parent;
1392
1425
  const callExpression = memberExpression.parent;
1393
- if (callExpression.arguments.length < 2 && couldBeObservable(memberExpression.object) && couldBeFunction2(callExpression.arguments[0])) {
1426
+ if ((isMissingErrorCallback(callExpression) || isMissingErrorProperty(callExpression)) && couldBeObservable(memberExpression.object)) {
1394
1427
  context.report({
1395
1428
  messageId: "forbidden",
1396
1429
  node
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.0";
3
+ var version = "0.3.1";
4
4
 
5
5
  // src/configs/recommended.ts
6
6
  var createRecommendedConfig = (plugin2) => ({
@@ -1370,6 +1370,7 @@ var noIgnoredDefaultValueRule = ruleCreator({
1370
1370
  });
1371
1371
 
1372
1372
  // src/rules/no-ignored-error.ts
1373
+ import { ESLintUtils as ESLintUtils7 } from "@typescript-eslint/utils";
1373
1374
  var noIgnoredErrorRule = ruleCreator({
1374
1375
  defaultOptions: [],
1375
1376
  meta: {
@@ -1385,12 +1386,44 @@ var noIgnoredErrorRule = ruleCreator({
1385
1386
  },
1386
1387
  name: "no-ignored-error",
1387
1388
  create: (context) => {
1389
+ const { getTypeAtLocation } = ESLintUtils7.getParserServices(context);
1388
1390
  const { couldBeObservable, couldBeFunction: couldBeFunction2 } = getTypeServices(context);
1391
+ function isMissingErrorCallback(callExpression) {
1392
+ if (callExpression.arguments.length >= 2) {
1393
+ return false;
1394
+ }
1395
+ return couldBeFunction2(callExpression.arguments[0]);
1396
+ }
1397
+ function isObjMissingError(arg) {
1398
+ return !arg.properties.some(
1399
+ (property) => isProperty(property) && isIdentifier(property.key) && property.key.name === "error"
1400
+ );
1401
+ }
1402
+ function isTypeMissingError(arg) {
1403
+ const argType = getTypeAtLocation(arg);
1404
+ return !(argType == null ? void 0 : argType.getProperties().some((p) => p.name === "error"));
1405
+ }
1406
+ function isMissingErrorProperty(callExpression) {
1407
+ if (callExpression.arguments.length !== 1) {
1408
+ return false;
1409
+ }
1410
+ const [arg] = callExpression.arguments;
1411
+ if (isObjectExpression(arg)) {
1412
+ return isObjMissingError(arg);
1413
+ }
1414
+ if (isIdentifier(arg)) {
1415
+ return isTypeMissingError(arg);
1416
+ }
1417
+ if (isMemberExpression(arg) && isIdentifier(arg.property)) {
1418
+ return isTypeMissingError(arg.property);
1419
+ }
1420
+ return false;
1421
+ }
1389
1422
  return {
1390
1423
  "CallExpression[arguments.length > 0] > MemberExpression > Identifier[name='subscribe']": (node) => {
1391
1424
  const memberExpression = node.parent;
1392
1425
  const callExpression = memberExpression.parent;
1393
- if (callExpression.arguments.length < 2 && couldBeObservable(memberExpression.object) && couldBeFunction2(callExpression.arguments[0])) {
1426
+ if ((isMissingErrorCallback(callExpression) || isMissingErrorProperty(callExpression)) && couldBeObservable(memberExpression.object)) {
1394
1427
  context.report({
1395
1428
  messageId: "forbidden",
1396
1429
  node
@@ -2317,7 +2350,7 @@ var noTopromiseRule = ruleCreator({
2317
2350
  });
2318
2351
 
2319
2352
  // src/rules/no-unbound-methods.ts
2320
- import { ESLintUtils as ESLintUtils7 } from "@typescript-eslint/utils";
2353
+ import { ESLintUtils as ESLintUtils8 } from "@typescript-eslint/utils";
2321
2354
  var noUnboundMethodsRule = ruleCreator({
2322
2355
  defaultOptions: [],
2323
2356
  meta: {
@@ -2334,7 +2367,7 @@ var noUnboundMethodsRule = ruleCreator({
2334
2367
  },
2335
2368
  name: "no-unbound-methods",
2336
2369
  create: (context) => {
2337
- const { getTypeAtLocation } = ESLintUtils7.getParserServices(context);
2370
+ const { getTypeAtLocation } = ESLintUtils8.getParserServices(context);
2338
2371
  const { couldBeObservable, couldBeSubscription } = getTypeServices(context);
2339
2372
  const nodeMap = /* @__PURE__ */ new WeakMap();
2340
2373
  function mapArguments(node) {
@@ -2512,7 +2545,7 @@ var noUnsafeFirstRule = ruleCreator({
2512
2545
  });
2513
2546
 
2514
2547
  // src/rules/no-unsafe-subject-next.ts
2515
- import { ESLintUtils as ESLintUtils8 } from "@typescript-eslint/utils";
2548
+ import { ESLintUtils as ESLintUtils9 } from "@typescript-eslint/utils";
2516
2549
  import * as tsutils2 from "ts-api-utils";
2517
2550
  import ts6 from "typescript";
2518
2551
  var noUnsafeSubjectNext = ruleCreator({
@@ -2531,7 +2564,7 @@ var noUnsafeSubjectNext = ruleCreator({
2531
2564
  },
2532
2565
  name: "no-unsafe-subject-next",
2533
2566
  create: (context) => {
2534
- const { getTypeAtLocation, program } = ESLintUtils8.getParserServices(context);
2567
+ const { getTypeAtLocation, program } = ESLintUtils9.getParserServices(context);
2535
2568
  const typeChecker = program.getTypeChecker();
2536
2569
  return {
2537
2570
  [`CallExpression[callee.property.name='next']`]: (node) => {
@@ -2895,7 +2928,7 @@ function isValidArgText(argText) {
2895
2928
  }
2896
2929
 
2897
2930
  // src/rules/suffix-subjects.ts
2898
- import { AST_NODE_TYPES as AST_NODE_TYPES7, ESLintUtils as ESLintUtils9 } from "@typescript-eslint/utils";
2931
+ import { AST_NODE_TYPES as AST_NODE_TYPES7, ESLintUtils as ESLintUtils10 } from "@typescript-eslint/utils";
2899
2932
  var defaultOptions13 = [];
2900
2933
  var suffixSubjectsRule = ruleCreator({
2901
2934
  defaultOptions: defaultOptions13,
@@ -2923,7 +2956,7 @@ var suffixSubjectsRule = ruleCreator({
2923
2956
  },
2924
2957
  name: "suffix-subjects",
2925
2958
  create: (context) => {
2926
- const { esTreeNodeToTSNodeMap } = ESLintUtils9.getParserServices(context);
2959
+ const { esTreeNodeToTSNodeMap } = ESLintUtils10.getParserServices(context);
2927
2960
  const { couldBeType: couldBeType2 } = getTypeServices(context);
2928
2961
  const [config = {}] = context.options;
2929
2962
  const validate = {
@@ -3093,7 +3126,7 @@ var suffixSubjectsRule = ruleCreator({
3093
3126
  });
3094
3127
 
3095
3128
  // src/rules/throw-error.ts
3096
- import { ESLintUtils as ESLintUtils10 } from "@typescript-eslint/utils";
3129
+ import { ESLintUtils as ESLintUtils11 } from "@typescript-eslint/utils";
3097
3130
  import * as tsutils3 from "ts-api-utils";
3098
3131
  var defaultOptions14 = [];
3099
3132
  var throwErrorRule = ruleCreator({
@@ -3119,7 +3152,7 @@ var throwErrorRule = ruleCreator({
3119
3152
  },
3120
3153
  name: "throw-error",
3121
3154
  create: (context) => {
3122
- const { esTreeNodeToTSNodeMap, program, getTypeAtLocation } = ESLintUtils10.getParserServices(context);
3155
+ const { esTreeNodeToTSNodeMap, program, getTypeAtLocation } = ESLintUtils11.getParserServices(context);
3123
3156
  const { couldBeObservable } = getTypeServices(context);
3124
3157
  const [config = {}] = context.options;
3125
3158
  const { allowThrowingAny = true, allowThrowingUnknown = true } = config;
@@ -7,6 +7,9 @@
7
7
  <!-- end auto-generated rule header -->
8
8
 
9
9
  This rule effects failures if async functions are passed to `subscribe`.
10
+ Developers are encouraged to avoid race conditions
11
+ by instead using RxJS operators which can handle both Promises and Observables
12
+ (e.g. `concatMap`, `switchMap`, `mergeMap`, `exhaustMap`).
10
13
 
11
14
  ## Rule details
12
15
 
@@ -14,16 +17,26 @@ Examples of **incorrect** code for this rule:
14
17
 
15
18
  ```ts
16
19
  import { of } from "rxjs";
17
- of(42).subscribe(async () => console.log(value));
20
+
21
+ of(42).subscribe(async value => {
22
+ const data1 = await fetch(`https://api.some.com/things/${value}`);
23
+ const data2 = await fetch(`https://api.some.com/things/${data1.id}`);
24
+ console.log(data2);
25
+ });
18
26
  ```
19
27
 
20
28
  Examples of **correct** code for this rule:
21
29
 
22
30
  ```ts
23
31
  import { of } from "rxjs";
24
- of(42).subscribe(() => console.log(value));
32
+
33
+ of(42).pipe(
34
+ switchMap(value => fetch(`http://api.some.com/things/${value}`)),
35
+ switchMap(data1 => fetch(`http://api.some.com/things/${data1.id}`)),
36
+ ).subscribe(data2 => console.log(data2));
25
37
  ```
26
38
 
27
39
  ## Further reading
28
40
 
29
41
  - [Why does this rule exist?](https://stackoverflow.com/q/71559135)
42
+ - [Higher-order Observables](https://rxjs.dev/guide/higher-order-observables)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "eslint-plugin-rxjs-x",
3
3
  "type": "commonjs",
4
- "version": "0.3.0",
4
+ "version": "0.3.1",
5
5
  "packageManager": "yarn@4.5.1+sha512.341db9396b6e289fecc30cd7ab3af65060e05ebff4b3b47547b278b9e67b08f485ecd8c79006b405446262142c7a38154445ef7f17c1d5d1de7d90bf9ce7054d",
6
6
  "description": "ESLint v9+ plugin for RxJS",
7
7
  "author": "Jason Weinzierl <weinzierljason@gmail.com>",
@@ -90,7 +90,6 @@
90
90
  "markdownlint-cli2": "^0.15.0",
91
91
  "rxjs": "^7.8.1",
92
92
  "tsup": "^8.3.5",
93
- "tsx": "^4.19.2",
94
93
  "typescript": "~5.6.3",
95
94
  "typescript-eslint": "^8.14.0",
96
95
  "vitest": "^2.1.5"