eslint-plugin-rxjs-x 0.3.1 → 0.4.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 +60 -50
- package/dist/index.d.mts +40 -4
- package/dist/index.d.ts +40 -4
- package/dist/index.js +295 -28
- package/dist/index.mjs +295 -28
- package/docs/rules/no-async-subscribe.md +1 -1
- package/docs/rules/no-compat.md +4 -0
- package/docs/rules/no-create.md +1 -1
- package/docs/rules/no-explicit-generics.md +2 -0
- package/docs/rules/no-exposed-subjects.md +2 -0
- package/docs/rules/no-ignored-default-value.md +2 -0
- package/docs/rules/no-ignored-error.md +2 -0
- package/docs/rules/no-ignored-notifier.md +1 -1
- package/docs/rules/no-ignored-observable.md +2 -0
- package/docs/rules/no-ignored-replay-buffer.md +1 -1
- package/docs/rules/no-ignored-takewhile-value.md +1 -1
- package/docs/rules/no-implicit-any-catch.md +3 -3
- package/docs/rules/no-index.md +1 -1
- package/docs/rules/no-internal.md +1 -1
- package/docs/rules/no-nested-subscribe.md +1 -1
- package/docs/rules/no-redundant-notify.md +1 -1
- package/docs/rules/no-sharereplay.md +1 -1
- package/docs/rules/no-subclass.md +2 -0
- package/docs/rules/no-subject-unsubscribe.md +1 -1
- package/docs/rules/no-topromise.md +8 -0
- package/docs/rules/no-unbound-methods.md +1 -1
- package/docs/rules/no-unsafe-subject-next.md +1 -1
- package/docs/rules/no-unsafe-takeuntil.md +1 -1
- package/docs/rules/prefer-observer.md +6 -0
- package/docs/rules/prefer-root-operators.md +34 -0
- package/docs/rules/throw-error.md +2 -0
- package/package.json +3 -3
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.4.0";
|
|
4
4
|
|
|
5
5
|
// src/configs/recommended.ts
|
|
6
6
|
var createRecommendedConfig = (plugin2) => ({
|
|
@@ -18,7 +18,7 @@ var createRecommendedConfig = (plugin2) => ({
|
|
|
18
18
|
"rxjs-x/no-internal": "error",
|
|
19
19
|
"rxjs-x/no-nested-subscribe": "error",
|
|
20
20
|
"rxjs-x/no-redundant-notify": "error",
|
|
21
|
-
"rxjs-x/no-sharereplay":
|
|
21
|
+
"rxjs-x/no-sharereplay": "error",
|
|
22
22
|
"rxjs-x/no-subject-unsubscribe": "error",
|
|
23
23
|
"rxjs-x/no-unbound-methods": "error",
|
|
24
24
|
"rxjs-x/no-unsafe-subject-next": "error",
|
|
@@ -26,6 +26,45 @@ var createRecommendedConfig = (plugin2) => ({
|
|
|
26
26
|
}
|
|
27
27
|
});
|
|
28
28
|
|
|
29
|
+
// src/configs/strict.ts
|
|
30
|
+
var createStrictConfig = (plugin2) => ({
|
|
31
|
+
plugins: {
|
|
32
|
+
"rxjs-x": plugin2
|
|
33
|
+
},
|
|
34
|
+
rules: {
|
|
35
|
+
"rxjs-x/no-async-subscribe": "error",
|
|
36
|
+
"rxjs-x/no-create": "error",
|
|
37
|
+
"rxjs-x/no-explicit-generics": "error",
|
|
38
|
+
"rxjs-x/no-exposed-subjects": "error",
|
|
39
|
+
"rxjs-x/no-ignored-default-value": "error",
|
|
40
|
+
"rxjs-x/no-ignored-error": "error",
|
|
41
|
+
"rxjs-x/no-ignored-notifier": "error",
|
|
42
|
+
"rxjs-x/no-ignored-observable": "error",
|
|
43
|
+
"rxjs-x/no-ignored-replay-buffer": "error",
|
|
44
|
+
"rxjs-x/no-ignored-takewhile-value": "error",
|
|
45
|
+
"rxjs-x/no-implicit-any-catch": ["error", {
|
|
46
|
+
allowExplicitAny: false
|
|
47
|
+
}],
|
|
48
|
+
"rxjs-x/no-index": "error",
|
|
49
|
+
"rxjs-x/no-internal": "error",
|
|
50
|
+
"rxjs-x/no-nested-subscribe": "error",
|
|
51
|
+
"rxjs-x/no-redundant-notify": "error",
|
|
52
|
+
"rxjs-x/no-sharereplay": "error",
|
|
53
|
+
"rxjs-x/no-subclass": "error",
|
|
54
|
+
"rxjs-x/no-subject-unsubscribe": "error",
|
|
55
|
+
"rxjs-x/no-topromise": "error",
|
|
56
|
+
"rxjs-x/no-unbound-methods": "error",
|
|
57
|
+
"rxjs-x/no-unsafe-subject-next": "error",
|
|
58
|
+
"rxjs-x/no-unsafe-takeuntil": "error",
|
|
59
|
+
"rxjs-x/prefer-observer": "error",
|
|
60
|
+
"rxjs-x/prefer-root-operators": "error",
|
|
61
|
+
"rxjs-x/throw-error": ["error", {
|
|
62
|
+
allowThrowingAny: false,
|
|
63
|
+
allowThrowingUnknown: false
|
|
64
|
+
}]
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
|
|
29
68
|
// src/rules/ban-observables.ts
|
|
30
69
|
import { AST_NODE_TYPES } from "@typescript-eslint/utils";
|
|
31
70
|
import { stripIndent } from "common-tags";
|
|
@@ -265,6 +304,15 @@ function isFunctionExpression(node) {
|
|
|
265
304
|
function isIdentifier(node) {
|
|
266
305
|
return node.type === AST_NODE_TYPES2.Identifier;
|
|
267
306
|
}
|
|
307
|
+
function isImportDeclaration(node) {
|
|
308
|
+
return node.type === AST_NODE_TYPES2.ImportDeclaration;
|
|
309
|
+
}
|
|
310
|
+
function isImportNamespaceSpecifier(node) {
|
|
311
|
+
return node.type === AST_NODE_TYPES2.ImportNamespaceSpecifier;
|
|
312
|
+
}
|
|
313
|
+
function isImportSpecifier(node) {
|
|
314
|
+
return node.type === AST_NODE_TYPES2.ImportSpecifier;
|
|
315
|
+
}
|
|
268
316
|
function isLiteral(node) {
|
|
269
317
|
return node.type === AST_NODE_TYPES2.Literal;
|
|
270
318
|
}
|
|
@@ -773,7 +821,7 @@ var noAsyncSubscribeRule = ruleCreator({
|
|
|
773
821
|
meta: {
|
|
774
822
|
docs: {
|
|
775
823
|
description: "Disallow passing `async` functions to `subscribe`.",
|
|
776
|
-
recommended:
|
|
824
|
+
recommended: "recommended",
|
|
777
825
|
requiresTypeChecking: true
|
|
778
826
|
},
|
|
779
827
|
messages: {
|
|
@@ -814,6 +862,7 @@ var noAsyncSubscribeRule = ruleCreator({
|
|
|
814
862
|
var noCompatRule = ruleCreator({
|
|
815
863
|
defaultOptions: [],
|
|
816
864
|
meta: {
|
|
865
|
+
deprecated: true,
|
|
817
866
|
docs: {
|
|
818
867
|
description: "Disallow the `rxjs-compat` package."
|
|
819
868
|
},
|
|
@@ -880,7 +929,7 @@ var noCreateRule = ruleCreator({
|
|
|
880
929
|
meta: {
|
|
881
930
|
docs: {
|
|
882
931
|
description: "Disallow the static `Observable.create` function.",
|
|
883
|
-
recommended:
|
|
932
|
+
recommended: "recommended",
|
|
884
933
|
requiresTypeChecking: true
|
|
885
934
|
},
|
|
886
935
|
messages: {
|
|
@@ -1022,7 +1071,8 @@ var noExplicitGenericsRule = ruleCreator({
|
|
|
1022
1071
|
defaultOptions: [],
|
|
1023
1072
|
meta: {
|
|
1024
1073
|
docs: {
|
|
1025
|
-
description: "Disallow unnecessary explicit generic type arguments."
|
|
1074
|
+
description: "Disallow unnecessary explicit generic type arguments.",
|
|
1075
|
+
recommended: "strict"
|
|
1026
1076
|
},
|
|
1027
1077
|
messages: {
|
|
1028
1078
|
forbidden: "Explicit generic type arguments are forbidden."
|
|
@@ -1075,6 +1125,7 @@ var noExposedSubjectsRule = ruleCreator({
|
|
|
1075
1125
|
meta: {
|
|
1076
1126
|
docs: {
|
|
1077
1127
|
description: "Disallow public and protected subjects.",
|
|
1128
|
+
recommended: "strict",
|
|
1078
1129
|
requiresTypeChecking: true
|
|
1079
1130
|
},
|
|
1080
1131
|
messages: {
|
|
@@ -1274,6 +1325,7 @@ var noIgnoredDefaultValueRule = ruleCreator({
|
|
|
1274
1325
|
meta: {
|
|
1275
1326
|
docs: {
|
|
1276
1327
|
description: "Disallow using `firstValueFrom`, `lastValueFrom`, `first`, and `last` without specifying a default value.",
|
|
1328
|
+
recommended: "strict",
|
|
1277
1329
|
requiresTypeChecking: true
|
|
1278
1330
|
},
|
|
1279
1331
|
messages: {
|
|
@@ -1376,6 +1428,7 @@ var noIgnoredErrorRule = ruleCreator({
|
|
|
1376
1428
|
meta: {
|
|
1377
1429
|
docs: {
|
|
1378
1430
|
description: "Disallow calling `subscribe` without specifying an error handler.",
|
|
1431
|
+
recommended: "strict",
|
|
1379
1432
|
requiresTypeChecking: true
|
|
1380
1433
|
},
|
|
1381
1434
|
messages: {
|
|
@@ -1440,7 +1493,7 @@ var noIgnoredNotifierRule = ruleCreator({
|
|
|
1440
1493
|
meta: {
|
|
1441
1494
|
docs: {
|
|
1442
1495
|
description: "Disallow observables not composed from the `repeatWhen` or `retryWhen` notifier.",
|
|
1443
|
-
recommended:
|
|
1496
|
+
recommended: "recommended",
|
|
1444
1497
|
requiresTypeChecking: true
|
|
1445
1498
|
},
|
|
1446
1499
|
messages: {
|
|
@@ -1512,6 +1565,7 @@ var noIgnoredObservableRule = ruleCreator({
|
|
|
1512
1565
|
meta: {
|
|
1513
1566
|
docs: {
|
|
1514
1567
|
description: "Disallow ignoring observables returned by functions.",
|
|
1568
|
+
recommended: "strict",
|
|
1515
1569
|
requiresTypeChecking: true
|
|
1516
1570
|
},
|
|
1517
1571
|
messages: {
|
|
@@ -1542,7 +1596,7 @@ var noIgnoredReplayBufferRule = ruleCreator({
|
|
|
1542
1596
|
meta: {
|
|
1543
1597
|
docs: {
|
|
1544
1598
|
description: "Disallow using `ReplaySubject`, `publishReplay` or `shareReplay` without specifying the buffer size.",
|
|
1545
|
-
recommended:
|
|
1599
|
+
recommended: "recommended"
|
|
1546
1600
|
},
|
|
1547
1601
|
messages: {
|
|
1548
1602
|
forbidden: "Ignoring the buffer size is forbidden."
|
|
@@ -1668,7 +1722,7 @@ var noIgnoredTakewhileValueRule = ruleCreator({
|
|
|
1668
1722
|
meta: {
|
|
1669
1723
|
docs: {
|
|
1670
1724
|
description: "Disallow ignoring the value within `takeWhile`.",
|
|
1671
|
-
recommended:
|
|
1725
|
+
recommended: "recommended"
|
|
1672
1726
|
},
|
|
1673
1727
|
messages: {
|
|
1674
1728
|
forbidden: "Ignoring the value within takeWhile is forbidden."
|
|
@@ -1732,7 +1786,12 @@ var noImplicitAnyCatchRule = ruleCreator({
|
|
|
1732
1786
|
meta: {
|
|
1733
1787
|
docs: {
|
|
1734
1788
|
description: "Disallow implicit `any` error parameters in `catchError` operators.",
|
|
1735
|
-
recommended:
|
|
1789
|
+
recommended: {
|
|
1790
|
+
recommended: true,
|
|
1791
|
+
strict: [{
|
|
1792
|
+
allowExplicitAny: false
|
|
1793
|
+
}]
|
|
1794
|
+
},
|
|
1736
1795
|
requiresTypeChecking: true
|
|
1737
1796
|
},
|
|
1738
1797
|
fixable: "code",
|
|
@@ -1750,7 +1809,7 @@ var noImplicitAnyCatchRule = ruleCreator({
|
|
|
1750
1809
|
allowExplicitAny: {
|
|
1751
1810
|
type: "boolean",
|
|
1752
1811
|
description: "Allow error variable to be explicitly typed as `any`.",
|
|
1753
|
-
default:
|
|
1812
|
+
default: true
|
|
1754
1813
|
}
|
|
1755
1814
|
},
|
|
1756
1815
|
type: "object"
|
|
@@ -1761,7 +1820,7 @@ var noImplicitAnyCatchRule = ruleCreator({
|
|
|
1761
1820
|
name: "no-implicit-any-catch",
|
|
1762
1821
|
create: (context) => {
|
|
1763
1822
|
const [config = {}] = context.options;
|
|
1764
|
-
const { allowExplicitAny =
|
|
1823
|
+
const { allowExplicitAny = true } = config;
|
|
1765
1824
|
const { couldBeObservable } = getTypeServices(context);
|
|
1766
1825
|
const sourceCode = context.sourceCode;
|
|
1767
1826
|
function checkCallback(callback) {
|
|
@@ -1870,7 +1929,7 @@ var noIndexRule = ruleCreator({
|
|
|
1870
1929
|
meta: {
|
|
1871
1930
|
docs: {
|
|
1872
1931
|
description: "Disallow importing index modules.",
|
|
1873
|
-
recommended:
|
|
1932
|
+
recommended: "recommended"
|
|
1874
1933
|
},
|
|
1875
1934
|
messages: {
|
|
1876
1935
|
forbidden: "RxJS imports from index modules are forbidden."
|
|
@@ -1897,7 +1956,7 @@ var noInternalRule = ruleCreator({
|
|
|
1897
1956
|
meta: {
|
|
1898
1957
|
docs: {
|
|
1899
1958
|
description: "Disallow importing internal modules.",
|
|
1900
|
-
recommended:
|
|
1959
|
+
recommended: "recommended"
|
|
1901
1960
|
},
|
|
1902
1961
|
fixable: "code",
|
|
1903
1962
|
hasSuggestions: true,
|
|
@@ -1973,7 +2032,7 @@ var noNestedSubscribeRule = ruleCreator({
|
|
|
1973
2032
|
meta: {
|
|
1974
2033
|
docs: {
|
|
1975
2034
|
description: "Disallow calling `subscribe` within a `subscribe` callback.",
|
|
1976
|
-
recommended:
|
|
2035
|
+
recommended: "recommended",
|
|
1977
2036
|
requiresTypeChecking: true
|
|
1978
2037
|
},
|
|
1979
2038
|
messages: {
|
|
@@ -2017,7 +2076,7 @@ var noRedundantNotifyRule = ruleCreator({
|
|
|
2017
2076
|
meta: {
|
|
2018
2077
|
docs: {
|
|
2019
2078
|
description: "Disallow sending redundant notifications from completed or errored observables.",
|
|
2020
|
-
recommended:
|
|
2079
|
+
recommended: "recommended",
|
|
2021
2080
|
requiresTypeChecking: true
|
|
2022
2081
|
},
|
|
2023
2082
|
messages: {
|
|
@@ -2096,7 +2155,7 @@ var noSharereplayRule = ruleCreator({
|
|
|
2096
2155
|
meta: {
|
|
2097
2156
|
docs: {
|
|
2098
2157
|
description: "Disallow unsafe `shareReplay` usage.",
|
|
2099
|
-
recommended:
|
|
2158
|
+
recommended: "recommended"
|
|
2100
2159
|
},
|
|
2101
2160
|
messages: {
|
|
2102
2161
|
forbidden: "shareReplay is forbidden.",
|
|
@@ -2139,6 +2198,7 @@ var noSubclassRule = ruleCreator({
|
|
|
2139
2198
|
meta: {
|
|
2140
2199
|
docs: {
|
|
2141
2200
|
description: "Disallow subclassing RxJS classes.",
|
|
2201
|
+
recommended: "strict",
|
|
2142
2202
|
requiresTypeChecking: true
|
|
2143
2203
|
},
|
|
2144
2204
|
messages: {
|
|
@@ -2182,7 +2242,7 @@ var noSubjectUnsubscribeRule = ruleCreator({
|
|
|
2182
2242
|
meta: {
|
|
2183
2243
|
docs: {
|
|
2184
2244
|
description: "Disallow calling the `unsubscribe` method of subjects.",
|
|
2185
|
-
recommended:
|
|
2245
|
+
recommended: "recommended",
|
|
2186
2246
|
requiresTypeChecking: true
|
|
2187
2247
|
},
|
|
2188
2248
|
messages: {
|
|
@@ -2325,10 +2385,14 @@ var noTopromiseRule = ruleCreator({
|
|
|
2325
2385
|
meta: {
|
|
2326
2386
|
docs: {
|
|
2327
2387
|
description: "Disallow use of the `toPromise` method.",
|
|
2388
|
+
recommended: "strict",
|
|
2328
2389
|
requiresTypeChecking: true
|
|
2329
2390
|
},
|
|
2391
|
+
hasSuggestions: true,
|
|
2330
2392
|
messages: {
|
|
2331
|
-
forbidden: "The toPromise method is forbidden."
|
|
2393
|
+
forbidden: "The toPromise method is forbidden.",
|
|
2394
|
+
suggestLastValueFrom: "Use lastValueFrom instead.",
|
|
2395
|
+
suggestFirstValueFrom: "Use firstValueFrom instead."
|
|
2332
2396
|
},
|
|
2333
2397
|
schema: [],
|
|
2334
2398
|
type: "problem"
|
|
@@ -2336,14 +2400,74 @@ var noTopromiseRule = ruleCreator({
|
|
|
2336
2400
|
name: "no-topromise",
|
|
2337
2401
|
create: (context) => {
|
|
2338
2402
|
const { couldBeObservable } = getTypeServices(context);
|
|
2403
|
+
function getQuote(raw) {
|
|
2404
|
+
const match = /^\s*('|")/.exec(raw);
|
|
2405
|
+
if (!match) {
|
|
2406
|
+
return void 0;
|
|
2407
|
+
}
|
|
2408
|
+
const [, quote] = match;
|
|
2409
|
+
return quote;
|
|
2410
|
+
}
|
|
2411
|
+
function createFix(conversion, callExpression, observableNode, importDeclarations) {
|
|
2412
|
+
return function* fix(fixer) {
|
|
2413
|
+
var _a, _b, _c;
|
|
2414
|
+
let namespace = "";
|
|
2415
|
+
let functionName = conversion;
|
|
2416
|
+
const rxjsImportDeclaration = importDeclarations.find((node) => node.source.value === "rxjs");
|
|
2417
|
+
if ((_a = rxjsImportDeclaration == null ? void 0 : rxjsImportDeclaration.specifiers) == null ? void 0 : _a.every(isImportNamespaceSpecifier)) {
|
|
2418
|
+
namespace = rxjsImportDeclaration.specifiers[0].local.name + ".";
|
|
2419
|
+
} else if ((_b = rxjsImportDeclaration == null ? void 0 : rxjsImportDeclaration.specifiers) == null ? void 0 : _b.every(isImportSpecifier)) {
|
|
2420
|
+
const { specifiers } = rxjsImportDeclaration;
|
|
2421
|
+
const existingSpecifier = specifiers.find((node) => (isIdentifier(node.imported) ? node.imported.name : node.imported.value) === functionName);
|
|
2422
|
+
if (existingSpecifier) {
|
|
2423
|
+
functionName = existingSpecifier.local.name;
|
|
2424
|
+
} else {
|
|
2425
|
+
const lastSpecifier = specifiers[specifiers.length - 1];
|
|
2426
|
+
yield fixer.insertTextAfter(lastSpecifier, `, ${functionName}`);
|
|
2427
|
+
}
|
|
2428
|
+
} else if (importDeclarations.length) {
|
|
2429
|
+
const lastImport = importDeclarations[importDeclarations.length - 1];
|
|
2430
|
+
const quote = (_c = getQuote(lastImport.source.raw)) != null ? _c : '"';
|
|
2431
|
+
yield fixer.insertTextAfter(
|
|
2432
|
+
importDeclarations[importDeclarations.length - 1],
|
|
2433
|
+
`
|
|
2434
|
+
import { ${functionName} } from ${quote}rxjs${quote};`
|
|
2435
|
+
);
|
|
2436
|
+
} else {
|
|
2437
|
+
console.warn("No import declarations found. Unable to suggest a fix.");
|
|
2438
|
+
return;
|
|
2439
|
+
}
|
|
2440
|
+
yield fixer.replaceText(
|
|
2441
|
+
callExpression,
|
|
2442
|
+
`${namespace}${functionName}(${context.sourceCode.getText(observableNode)})`
|
|
2443
|
+
);
|
|
2444
|
+
};
|
|
2445
|
+
}
|
|
2339
2446
|
return {
|
|
2340
|
-
[`
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2447
|
+
[`CallExpression[callee.property.name="toPromise"]`]: (node) => {
|
|
2448
|
+
const memberExpression = node.callee;
|
|
2449
|
+
if (!couldBeObservable(memberExpression.object)) {
|
|
2450
|
+
return;
|
|
2451
|
+
}
|
|
2452
|
+
const { body } = context.sourceCode.ast;
|
|
2453
|
+
const importDeclarations = body.filter(isImportDeclaration);
|
|
2454
|
+
if (!importDeclarations.length) {
|
|
2455
|
+
return;
|
|
2346
2456
|
}
|
|
2457
|
+
context.report({
|
|
2458
|
+
messageId: "forbidden",
|
|
2459
|
+
node: memberExpression.property,
|
|
2460
|
+
suggest: [
|
|
2461
|
+
{
|
|
2462
|
+
messageId: "suggestLastValueFrom",
|
|
2463
|
+
fix: createFix("lastValueFrom", node, memberExpression.object, importDeclarations)
|
|
2464
|
+
},
|
|
2465
|
+
{
|
|
2466
|
+
messageId: "suggestFirstValueFrom",
|
|
2467
|
+
fix: createFix("firstValueFrom", node, memberExpression.object, importDeclarations)
|
|
2468
|
+
}
|
|
2469
|
+
]
|
|
2470
|
+
});
|
|
2347
2471
|
}
|
|
2348
2472
|
};
|
|
2349
2473
|
}
|
|
@@ -2356,7 +2480,7 @@ var noUnboundMethodsRule = ruleCreator({
|
|
|
2356
2480
|
meta: {
|
|
2357
2481
|
docs: {
|
|
2358
2482
|
description: "Disallow passing unbound methods.",
|
|
2359
|
-
recommended:
|
|
2483
|
+
recommended: "recommended",
|
|
2360
2484
|
requiresTypeChecking: true
|
|
2361
2485
|
},
|
|
2362
2486
|
messages: {
|
|
@@ -2553,7 +2677,7 @@ var noUnsafeSubjectNext = ruleCreator({
|
|
|
2553
2677
|
meta: {
|
|
2554
2678
|
docs: {
|
|
2555
2679
|
description: "Disallow unsafe optional `next` calls.",
|
|
2556
|
-
recommended:
|
|
2680
|
+
recommended: "recommended",
|
|
2557
2681
|
requiresTypeChecking: true
|
|
2558
2682
|
},
|
|
2559
2683
|
messages: {
|
|
@@ -2754,7 +2878,7 @@ var noUnsafeTakeuntilRule = ruleCreator({
|
|
|
2754
2878
|
meta: {
|
|
2755
2879
|
docs: {
|
|
2756
2880
|
description: "Disallow applying operators after `takeUntil`.",
|
|
2757
|
-
recommended:
|
|
2881
|
+
recommended: "recommended",
|
|
2758
2882
|
requiresTypeChecking: true
|
|
2759
2883
|
},
|
|
2760
2884
|
messages: {
|
|
@@ -2835,6 +2959,7 @@ var preferObserverRule = ruleCreator({
|
|
|
2835
2959
|
meta: {
|
|
2836
2960
|
docs: {
|
|
2837
2961
|
description: "Disallow passing separate handlers to `subscribe` and `tap`.",
|
|
2962
|
+
recommended: "strict",
|
|
2838
2963
|
requiresTypeChecking: true
|
|
2839
2964
|
},
|
|
2840
2965
|
fixable: "code",
|
|
@@ -2927,6 +3052,143 @@ function isValidArgText(argText) {
|
|
|
2927
3052
|
return argText && argText !== "undefined" && argText !== "null";
|
|
2928
3053
|
}
|
|
2929
3054
|
|
|
3055
|
+
// src/rules/prefer-root-operators.ts
|
|
3056
|
+
var RENAMED_OPERATORS = {
|
|
3057
|
+
combineLatest: "combineLatestWith",
|
|
3058
|
+
concat: "concatWith",
|
|
3059
|
+
merge: "mergeWith",
|
|
3060
|
+
onErrorResumeNext: "onErrorResumeNextWith",
|
|
3061
|
+
race: "raceWith",
|
|
3062
|
+
zip: "zipWith"
|
|
3063
|
+
};
|
|
3064
|
+
var DEPRECATED_OPERATORS = [
|
|
3065
|
+
"partition"
|
|
3066
|
+
];
|
|
3067
|
+
var preferRootOperatorsRule = ruleCreator({
|
|
3068
|
+
defaultOptions: [],
|
|
3069
|
+
meta: {
|
|
3070
|
+
docs: {
|
|
3071
|
+
description: "Disallow importing operators from `rxjs/operators`.",
|
|
3072
|
+
recommended: "strict"
|
|
3073
|
+
},
|
|
3074
|
+
fixable: "code",
|
|
3075
|
+
hasSuggestions: true,
|
|
3076
|
+
messages: {
|
|
3077
|
+
forbidden: "RxJS imports from `rxjs/operators` are forbidden; import from `rxjs` instead.",
|
|
3078
|
+
forbiddenWithoutFix: "RxJS imports from `rxjs/operators` are forbidden; import from `rxjs` instead. Note some operators may have been renamed or deprecated.",
|
|
3079
|
+
suggest: "Replace with import from `rxjs`."
|
|
3080
|
+
},
|
|
3081
|
+
schema: [],
|
|
3082
|
+
type: "suggestion"
|
|
3083
|
+
},
|
|
3084
|
+
name: "prefer-root-operators",
|
|
3085
|
+
create: (context) => {
|
|
3086
|
+
function getQuote(raw) {
|
|
3087
|
+
const match = /^\s*('|")/.exec(raw);
|
|
3088
|
+
if (!match) {
|
|
3089
|
+
return void 0;
|
|
3090
|
+
}
|
|
3091
|
+
const [, quote] = match;
|
|
3092
|
+
return quote;
|
|
3093
|
+
}
|
|
3094
|
+
function getSourceReplacement(rawLocation) {
|
|
3095
|
+
const quote = getQuote(rawLocation);
|
|
3096
|
+
if (!quote) {
|
|
3097
|
+
return void 0;
|
|
3098
|
+
}
|
|
3099
|
+
if (/^['"]rxjs\/operators/.test(rawLocation)) {
|
|
3100
|
+
return `${quote}rxjs${quote}`;
|
|
3101
|
+
}
|
|
3102
|
+
return void 0;
|
|
3103
|
+
}
|
|
3104
|
+
function hasDeprecatedOperators(specifiers) {
|
|
3105
|
+
return !!(specifiers == null ? void 0 : specifiers.some((s) => DEPRECATED_OPERATORS.includes(getName(getOperatorNode(s)))));
|
|
3106
|
+
}
|
|
3107
|
+
function getName(node) {
|
|
3108
|
+
return isIdentifier(node) ? node.name : node.value;
|
|
3109
|
+
}
|
|
3110
|
+
function getOperatorNode(node) {
|
|
3111
|
+
return isImportSpecifier(node) ? node.imported : node.local;
|
|
3112
|
+
}
|
|
3113
|
+
function getAliasNode(node) {
|
|
3114
|
+
return isImportSpecifier(node) ? node.local : node.exported;
|
|
3115
|
+
}
|
|
3116
|
+
function getOperatorReplacement(name2) {
|
|
3117
|
+
return RENAMED_OPERATORS[name2];
|
|
3118
|
+
}
|
|
3119
|
+
function isNodesEqual(a, b) {
|
|
3120
|
+
return a.range[0] === b.range[0] && a.range[1] === b.range[1];
|
|
3121
|
+
}
|
|
3122
|
+
function createFix(source, replacement, specifiers) {
|
|
3123
|
+
return function* fix(fixer) {
|
|
3124
|
+
yield fixer.replaceText(source, replacement);
|
|
3125
|
+
for (const specifier of specifiers) {
|
|
3126
|
+
const operatorNode = getOperatorNode(specifier);
|
|
3127
|
+
const operatorName = getName(operatorNode);
|
|
3128
|
+
const operatorReplacement = getOperatorReplacement(operatorName);
|
|
3129
|
+
if (!operatorReplacement) {
|
|
3130
|
+
continue;
|
|
3131
|
+
}
|
|
3132
|
+
const aliasNode = getAliasNode(specifier);
|
|
3133
|
+
if (isNodesEqual(aliasNode, operatorNode)) {
|
|
3134
|
+
yield fixer.insertTextBefore(operatorNode, operatorReplacement + " as ");
|
|
3135
|
+
} else if (isIdentifier(operatorNode)) {
|
|
3136
|
+
yield fixer.replaceText(operatorNode, operatorReplacement);
|
|
3137
|
+
} else {
|
|
3138
|
+
const quote = getQuote(operatorNode.raw);
|
|
3139
|
+
if (!quote) {
|
|
3140
|
+
continue;
|
|
3141
|
+
}
|
|
3142
|
+
yield fixer.replaceText(operatorNode, quote + operatorReplacement + quote);
|
|
3143
|
+
}
|
|
3144
|
+
}
|
|
3145
|
+
};
|
|
3146
|
+
}
|
|
3147
|
+
function reportNode(source, specifiers) {
|
|
3148
|
+
const replacement = getSourceReplacement(source.raw);
|
|
3149
|
+
if (!replacement || hasDeprecatedOperators(specifiers)) {
|
|
3150
|
+
context.report({
|
|
3151
|
+
messageId: "forbiddenWithoutFix",
|
|
3152
|
+
node: source
|
|
3153
|
+
});
|
|
3154
|
+
return;
|
|
3155
|
+
}
|
|
3156
|
+
if (!specifiers) {
|
|
3157
|
+
context.report({
|
|
3158
|
+
messageId: "forbiddenWithoutFix",
|
|
3159
|
+
node: source,
|
|
3160
|
+
suggest: [{ messageId: "suggest", fix: (fixer) => fixer.replaceText(source, replacement) }]
|
|
3161
|
+
});
|
|
3162
|
+
return;
|
|
3163
|
+
}
|
|
3164
|
+
const fix = createFix(source, replacement, specifiers);
|
|
3165
|
+
context.report({
|
|
3166
|
+
fix,
|
|
3167
|
+
messageId: "forbidden",
|
|
3168
|
+
node: source,
|
|
3169
|
+
suggest: [{ messageId: "suggest", fix }]
|
|
3170
|
+
});
|
|
3171
|
+
}
|
|
3172
|
+
return {
|
|
3173
|
+
'ImportDeclaration[source.value="rxjs/operators"]': (node) => {
|
|
3174
|
+
const specifiers = node.specifiers.length && node.specifiers.every((importClause) => isImportSpecifier(importClause)) ? node.specifiers : void 0;
|
|
3175
|
+
reportNode(node.source, specifiers);
|
|
3176
|
+
},
|
|
3177
|
+
'ImportExpression[source.value="rxjs/operators"]': (node) => {
|
|
3178
|
+
if (isLiteral(node.source)) {
|
|
3179
|
+
reportNode(node.source);
|
|
3180
|
+
}
|
|
3181
|
+
},
|
|
3182
|
+
'ExportNamedDeclaration[source.value="rxjs/operators"]': (node) => {
|
|
3183
|
+
reportNode(node.source, node.specifiers);
|
|
3184
|
+
},
|
|
3185
|
+
'ExportAllDeclaration[source.value="rxjs/operators"]': (node) => {
|
|
3186
|
+
reportNode(node.source);
|
|
3187
|
+
}
|
|
3188
|
+
};
|
|
3189
|
+
}
|
|
3190
|
+
});
|
|
3191
|
+
|
|
2930
3192
|
// src/rules/suffix-subjects.ts
|
|
2931
3193
|
import { AST_NODE_TYPES as AST_NODE_TYPES7, ESLintUtils as ESLintUtils10 } from "@typescript-eslint/utils";
|
|
2932
3194
|
var defaultOptions13 = [];
|
|
@@ -3134,6 +3396,9 @@ var throwErrorRule = ruleCreator({
|
|
|
3134
3396
|
meta: {
|
|
3135
3397
|
docs: {
|
|
3136
3398
|
description: "Enforce passing only `Error` values to `throwError`.",
|
|
3399
|
+
recommended: {
|
|
3400
|
+
strict: [{ allowThrowingAny: false, allowThrowingUnknown: false }]
|
|
3401
|
+
},
|
|
3137
3402
|
requiresTypeChecking: true
|
|
3138
3403
|
},
|
|
3139
3404
|
messages: {
|
|
@@ -3244,6 +3509,7 @@ var plugin = {
|
|
|
3244
3509
|
"no-unsafe-switchmap": noUnsafeSwitchmapRule,
|
|
3245
3510
|
"no-unsafe-takeuntil": noUnsafeTakeuntilRule,
|
|
3246
3511
|
"prefer-observer": preferObserverRule,
|
|
3512
|
+
"prefer-root-operators": preferRootOperatorsRule,
|
|
3247
3513
|
"suffix-subjects": suffixSubjectsRule,
|
|
3248
3514
|
"throw-error": throwErrorRule
|
|
3249
3515
|
}
|
|
@@ -3251,7 +3517,8 @@ var plugin = {
|
|
|
3251
3517
|
var rxjsX = {
|
|
3252
3518
|
...plugin,
|
|
3253
3519
|
configs: {
|
|
3254
|
-
recommended: createRecommendedConfig(plugin)
|
|
3520
|
+
recommended: createRecommendedConfig(plugin),
|
|
3521
|
+
strict: createStrictConfig(plugin)
|
|
3255
3522
|
}
|
|
3256
3523
|
};
|
|
3257
3524
|
var src_default = rxjsX;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Disallow passing `async` functions to `subscribe` (`rxjs-x/no-async-subscribe`)
|
|
2
2
|
|
|
3
|
-
💼 This rule is enabled in the ✅ `recommended`
|
|
3
|
+
💼 This rule is enabled in the following configs: ✅ `recommended`, 🔒 `strict`.
|
|
4
4
|
|
|
5
5
|
💭 This rule requires [type information](https://typescript-eslint.io/linting/typed-linting).
|
|
6
6
|
|
package/docs/rules/no-compat.md
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
# Disallow the `rxjs-compat` package (`rxjs-x/no-compat`)
|
|
2
2
|
|
|
3
|
+
❌ This rule is deprecated.
|
|
4
|
+
|
|
3
5
|
<!-- end auto-generated rule header -->
|
|
4
6
|
|
|
5
7
|
This rule prevents importing from locations that depend upon the `rxjs-compat` package.
|
|
6
8
|
|
|
9
|
+
This rule is deprecated because RxJS v7+ no longer includes `rxjs-compat`.
|
|
10
|
+
|
|
7
11
|
## Further reading
|
|
8
12
|
|
|
9
13
|
- [Backwards compatibility](https://github.com/ReactiveX/rxjs/blob/a6590e971969c736a15b77154dabbc22275aa0d5/docs_app/content/guide/v6/migration.md#backwards-compatibility)
|
package/docs/rules/no-create.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Disallow the static `Observable.create` function (`rxjs-x/no-create`)
|
|
2
2
|
|
|
3
|
-
💼 This rule is enabled in the ✅ `recommended`
|
|
3
|
+
💼 This rule is enabled in the following configs: ✅ `recommended`, 🔒 `strict`.
|
|
4
4
|
|
|
5
5
|
💭 This rule requires [type information](https://typescript-eslint.io/linting/typed-linting).
|
|
6
6
|
|
|
@@ -1,5 +1,7 @@
|
|
|
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
|
+
|
|
3
5
|
<!-- end auto-generated rule header -->
|
|
4
6
|
|
|
5
7
|
This rule prevents the use of explicit type arguments when the type arguments can be inferred.
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Disallow using `firstValueFrom`, `lastValueFrom`, `first`, and `last` without specifying a default value (`rxjs-x/no-ignored-default-value`)
|
|
2
2
|
|
|
3
|
+
💼 This rule is enabled in the 🔒 `strict` config.
|
|
4
|
+
|
|
3
5
|
💭 This rule requires [type information](https://typescript-eslint.io/linting/typed-linting).
|
|
4
6
|
|
|
5
7
|
<!-- end auto-generated rule header -->
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Disallow calling `subscribe` without specifying an error handler (`rxjs-x/no-ignored-error`)
|
|
2
2
|
|
|
3
|
+
💼 This rule is enabled in the 🔒 `strict` config.
|
|
4
|
+
|
|
3
5
|
💭 This rule requires [type information](https://typescript-eslint.io/linting/typed-linting).
|
|
4
6
|
|
|
5
7
|
<!-- end auto-generated rule header -->
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Disallow observables not composed from the `repeatWhen` or `retryWhen` notifier (`rxjs-x/no-ignored-notifier`)
|
|
2
2
|
|
|
3
|
-
💼 This rule is enabled in the ✅ `recommended`
|
|
3
|
+
💼 This rule is enabled in the following configs: ✅ `recommended`, 🔒 `strict`.
|
|
4
4
|
|
|
5
5
|
💭 This rule requires [type information](https://typescript-eslint.io/linting/typed-linting).
|
|
6
6
|
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Disallow ignoring observables returned by functions (`rxjs-x/no-ignored-observable`)
|
|
2
2
|
|
|
3
|
+
💼 This rule is enabled in the 🔒 `strict` config.
|
|
4
|
+
|
|
3
5
|
💭 This rule requires [type information](https://typescript-eslint.io/linting/typed-linting).
|
|
4
6
|
|
|
5
7
|
<!-- end auto-generated rule header -->
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Disallow using `ReplaySubject`, `publishReplay` or `shareReplay` without specifying the buffer size (`rxjs-x/no-ignored-replay-buffer`)
|
|
2
2
|
|
|
3
|
-
💼 This rule is enabled in the ✅ `recommended`
|
|
3
|
+
💼 This rule is enabled in the following configs: ✅ `recommended`, 🔒 `strict`.
|
|
4
4
|
|
|
5
5
|
<!-- end auto-generated rule header -->
|
|
6
6
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Disallow ignoring the value within `takeWhile` (`rxjs-x/no-ignored-takewhile-value`)
|
|
2
2
|
|
|
3
|
-
💼 This rule is enabled in the ✅ `recommended`
|
|
3
|
+
💼 This rule is enabled in the following configs: ✅ `recommended`, 🔒 `strict`.
|
|
4
4
|
|
|
5
5
|
<!-- end auto-generated rule header -->
|
|
6
6
|
|