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 +35 -2
- package/dist/index.mjs +43 -10
- package/docs/rules/no-async-subscribe.md +15 -2
- package/package.json +1 -2
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.
|
|
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
|
|
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.
|
|
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
|
|
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
|
|
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 } =
|
|
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
|
|
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 } =
|
|
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
|
|
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 } =
|
|
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
|
|
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 } =
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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"
|