eslint-plugin-rxjs-x 0.7.7 → 0.8.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 +100 -64
- package/dist/index.d.mts +272 -104
- package/dist/index.d.ts +272 -104
- package/dist/index.js +212 -48
- package/dist/index.mjs +212 -48
- package/package.json +16 -15
package/dist/index.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
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.8.1";
|
|
4
4
|
|
|
5
5
|
// src/configs/recommended.ts
|
|
6
6
|
var createRecommendedConfig = (plugin2) => ({
|
|
7
7
|
name: "rxjs-x/recommended",
|
|
8
8
|
plugins: {
|
|
9
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion -- "A type annotation is necessary."
|
|
9
10
|
"rxjs-x": plugin2
|
|
10
11
|
},
|
|
11
12
|
rules: {
|
|
@@ -36,6 +37,7 @@ var createRecommendedConfig = (plugin2) => ({
|
|
|
36
37
|
var createStrictConfig = (plugin2) => ({
|
|
37
38
|
name: "rxjs-x/strict",
|
|
38
39
|
plugins: {
|
|
40
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion -- "A type annotation is necessary."
|
|
39
41
|
"rxjs-x": plugin2
|
|
40
42
|
},
|
|
41
43
|
rules: {
|
|
@@ -56,12 +58,14 @@ var createStrictConfig = (plugin2) => ({
|
|
|
56
58
|
"rxjs-x/no-misused-observables": "error",
|
|
57
59
|
"rxjs-x/no-nested-subscribe": "error",
|
|
58
60
|
"rxjs-x/no-redundant-notify": "error",
|
|
61
|
+
"rxjs-x/no-sharereplay-before-takeuntil": "error",
|
|
59
62
|
"rxjs-x/no-sharereplay": "error",
|
|
60
63
|
"rxjs-x/no-subclass": "error",
|
|
61
64
|
"rxjs-x/no-subject-unsubscribe": "error",
|
|
62
65
|
"rxjs-x/no-subscribe-in-pipe": "error",
|
|
63
66
|
"rxjs-x/no-topromise": "error",
|
|
64
67
|
"rxjs-x/no-unbound-methods": "error",
|
|
68
|
+
"rxjs-x/no-unnecessary-collection": "error",
|
|
65
69
|
"rxjs-x/no-unsafe-subject-next": "error",
|
|
66
70
|
"rxjs-x/no-unsafe-takeuntil": "error",
|
|
67
71
|
"rxjs-x/prefer-observer": "error",
|
|
@@ -401,6 +405,14 @@ var SOURCES_OBJECT_ACCEPTING_STATIC_OBSERVABLE_CREATORS = [
|
|
|
401
405
|
"combineLatest",
|
|
402
406
|
"forkJoin"
|
|
403
407
|
];
|
|
408
|
+
var MULTIPLE_OBSERVABLE_ACCEPTING_STATIC_OBSERVABLE_CREATORS = [
|
|
409
|
+
"combineLatest",
|
|
410
|
+
"forkJoin",
|
|
411
|
+
"merge",
|
|
412
|
+
"zip",
|
|
413
|
+
"concat",
|
|
414
|
+
"race"
|
|
415
|
+
];
|
|
404
416
|
var DEFAULT_UNBOUND_ALLOWED_TYPES = [
|
|
405
417
|
"Signal"
|
|
406
418
|
];
|
|
@@ -438,6 +450,7 @@ function isSourcesObjectAcceptingStaticObservableCreator(expression) {
|
|
|
438
450
|
var REPO_URL = "https://github.com/JasonWeinzierl/eslint-plugin-rxjs-x";
|
|
439
451
|
var ruleCreator = _utils.ESLintUtils.RuleCreator(
|
|
440
452
|
(name2) => `${REPO_URL}/blob/v${version}/docs/rules/${name2}.md`
|
|
453
|
+
// Ensure the resulting types are narrowed to exactly what each rule declares.
|
|
441
454
|
);
|
|
442
455
|
|
|
443
456
|
// src/rules/ban-observables.ts
|
|
@@ -2822,6 +2835,65 @@ var noSharereplayRule = ruleCreator({
|
|
|
2822
2835
|
}
|
|
2823
2836
|
});
|
|
2824
2837
|
|
|
2838
|
+
// src/rules/no-sharereplay-before-takeuntil.ts
|
|
2839
|
+
var noSharereplayBeforeTakeuntilRule = ruleCreator({
|
|
2840
|
+
defaultOptions: [],
|
|
2841
|
+
meta: {
|
|
2842
|
+
docs: {
|
|
2843
|
+
description: "Disallow using `shareReplay({ refCount: false })` before `takeUntil`.",
|
|
2844
|
+
recommended: "strict"
|
|
2845
|
+
},
|
|
2846
|
+
messages: {
|
|
2847
|
+
forbidden: "shareReplay before takeUntil is forbidden unless 'refCount: true' is specified."
|
|
2848
|
+
},
|
|
2849
|
+
schema: [],
|
|
2850
|
+
type: "problem"
|
|
2851
|
+
},
|
|
2852
|
+
name: "no-sharereplay-before-takeuntil",
|
|
2853
|
+
create: (context) => {
|
|
2854
|
+
function checkCallExpression(node) {
|
|
2855
|
+
const pipeCallExpression = node.parent;
|
|
2856
|
+
if (!pipeCallExpression.arguments || !isMemberExpression(pipeCallExpression.callee) || !isIdentifier(pipeCallExpression.callee.property) || pipeCallExpression.callee.property.name !== "pipe") {
|
|
2857
|
+
return;
|
|
2858
|
+
}
|
|
2859
|
+
const { isOrderValid, operatorNode: takeUntilNode } = findIsLastOperatorOrderValid(
|
|
2860
|
+
pipeCallExpression,
|
|
2861
|
+
/^takeUntil$/,
|
|
2862
|
+
DEFAULT_VALID_POST_COMPLETION_OPERATORS
|
|
2863
|
+
);
|
|
2864
|
+
if (!isOrderValid || !takeUntilNode) {
|
|
2865
|
+
return;
|
|
2866
|
+
}
|
|
2867
|
+
if (takeUntilNode.range[0] < node.range[0]) {
|
|
2868
|
+
return;
|
|
2869
|
+
}
|
|
2870
|
+
const shareReplayConfig = node.arguments[0];
|
|
2871
|
+
if (!shareReplayConfig || !isObjectExpression(shareReplayConfig)) {
|
|
2872
|
+
context.report({
|
|
2873
|
+
messageId: "forbidden",
|
|
2874
|
+
node: node.callee
|
|
2875
|
+
});
|
|
2876
|
+
return;
|
|
2877
|
+
}
|
|
2878
|
+
const refCountElement = shareReplayConfig.properties.filter(isProperty).find((prop) => isIdentifier(prop.key) && prop.key.name === "refCount");
|
|
2879
|
+
if (!refCountElement || isLiteral(refCountElement.value) && refCountElement.value.value === false) {
|
|
2880
|
+
context.report({
|
|
2881
|
+
messageId: "forbidden",
|
|
2882
|
+
node: node.callee
|
|
2883
|
+
});
|
|
2884
|
+
}
|
|
2885
|
+
}
|
|
2886
|
+
return {
|
|
2887
|
+
'CallExpression[callee.name="shareReplay"]': (node) => {
|
|
2888
|
+
checkCallExpression(node);
|
|
2889
|
+
},
|
|
2890
|
+
'CallExpression[callee.property.name="shareReplay"]': (node) => {
|
|
2891
|
+
checkCallExpression(node);
|
|
2892
|
+
}
|
|
2893
|
+
};
|
|
2894
|
+
}
|
|
2895
|
+
});
|
|
2896
|
+
|
|
2825
2897
|
// src/rules/no-subclass.ts
|
|
2826
2898
|
var noSubclassRule = ruleCreator({
|
|
2827
2899
|
defaultOptions: [],
|
|
@@ -3232,6 +3304,94 @@ var noUnboundMethodsRule = ruleCreator({
|
|
|
3232
3304
|
}
|
|
3233
3305
|
});
|
|
3234
3306
|
|
|
3307
|
+
// src/rules/no-unnecessary-collection.ts
|
|
3308
|
+
var noUnnecessaryCollectionRule = ruleCreator({
|
|
3309
|
+
defaultOptions: [],
|
|
3310
|
+
meta: {
|
|
3311
|
+
docs: {
|
|
3312
|
+
description: "Disallow unnecessary usage of collection arguments with single values.",
|
|
3313
|
+
recommended: "strict",
|
|
3314
|
+
requiresTypeChecking: false
|
|
3315
|
+
},
|
|
3316
|
+
messages: {
|
|
3317
|
+
forbidden: "Unnecessary {{operator}} with {{inputType}}. Use the observable directly instead."
|
|
3318
|
+
},
|
|
3319
|
+
schema: [],
|
|
3320
|
+
type: "suggestion"
|
|
3321
|
+
},
|
|
3322
|
+
name: "no-unnecessary-collection",
|
|
3323
|
+
create: (context) => {
|
|
3324
|
+
const { couldBeType: couldBeType2, couldBeObservable } = getTypeServices(context);
|
|
3325
|
+
function couldBeFromRxjs(node, operatorName) {
|
|
3326
|
+
return couldBeType2(node, operatorName, { name: /[/\\]rxjs[/\\]/ });
|
|
3327
|
+
}
|
|
3328
|
+
function checkCallExpression(node, operatorName) {
|
|
3329
|
+
const args = node.arguments;
|
|
3330
|
+
if (args.length === 0) {
|
|
3331
|
+
return;
|
|
3332
|
+
}
|
|
3333
|
+
const firstArg = args[0];
|
|
3334
|
+
if (isArrayExpression(firstArg)) {
|
|
3335
|
+
const nonNullElements = firstArg.elements.filter((element) => element !== null);
|
|
3336
|
+
if (nonNullElements.length === 1 && couldBeObservable(nonNullElements[0])) {
|
|
3337
|
+
context.report({
|
|
3338
|
+
messageId: "forbidden",
|
|
3339
|
+
node: node.callee,
|
|
3340
|
+
data: {
|
|
3341
|
+
operator: operatorName,
|
|
3342
|
+
inputType: "single-valued array"
|
|
3343
|
+
}
|
|
3344
|
+
});
|
|
3345
|
+
}
|
|
3346
|
+
return;
|
|
3347
|
+
}
|
|
3348
|
+
if (isObjectExpression(firstArg) && SOURCES_OBJECT_ACCEPTING_STATIC_OBSERVABLE_CREATORS.includes(operatorName)) {
|
|
3349
|
+
if (firstArg.properties.length === 1 && isProperty(firstArg.properties[0])) {
|
|
3350
|
+
const property = firstArg.properties[0];
|
|
3351
|
+
if (property.value && couldBeObservable(property.value)) {
|
|
3352
|
+
context.report({
|
|
3353
|
+
messageId: "forbidden",
|
|
3354
|
+
node: node.callee,
|
|
3355
|
+
data: {
|
|
3356
|
+
operator: operatorName,
|
|
3357
|
+
inputType: "single-property object"
|
|
3358
|
+
}
|
|
3359
|
+
});
|
|
3360
|
+
}
|
|
3361
|
+
}
|
|
3362
|
+
return;
|
|
3363
|
+
}
|
|
3364
|
+
if (args.length === 1 && couldBeObservable(firstArg)) {
|
|
3365
|
+
context.report({
|
|
3366
|
+
messageId: "forbidden",
|
|
3367
|
+
node: node.callee,
|
|
3368
|
+
data: {
|
|
3369
|
+
operator: operatorName,
|
|
3370
|
+
inputType: "single argument"
|
|
3371
|
+
}
|
|
3372
|
+
});
|
|
3373
|
+
}
|
|
3374
|
+
}
|
|
3375
|
+
const callExpressionVisitors = {};
|
|
3376
|
+
for (const operator of MULTIPLE_OBSERVABLE_ACCEPTING_STATIC_OBSERVABLE_CREATORS) {
|
|
3377
|
+
callExpressionVisitors[`CallExpression[callee.name="${operator}"]`] = (node) => {
|
|
3378
|
+
if (couldBeFromRxjs(node.callee, operator)) {
|
|
3379
|
+
checkCallExpression(node, operator);
|
|
3380
|
+
}
|
|
3381
|
+
};
|
|
3382
|
+
}
|
|
3383
|
+
for (const operator of MULTIPLE_OBSERVABLE_ACCEPTING_STATIC_OBSERVABLE_CREATORS) {
|
|
3384
|
+
callExpressionVisitors[`CallExpression[callee.type="MemberExpression"][callee.property.name="${operator}"]`] = (node) => {
|
|
3385
|
+
const memberExpr = node.callee;
|
|
3386
|
+
if (couldBeFromRxjs(memberExpr.property, operator)) {
|
|
3387
|
+
checkCallExpression(node, operator);
|
|
3388
|
+
}
|
|
3389
|
+
};
|
|
3390
|
+
}
|
|
3391
|
+
return callExpressionVisitors;
|
|
3392
|
+
}
|
|
3393
|
+
});
|
|
3394
|
+
|
|
3235
3395
|
// src/rules/no-unsafe-catch.ts
|
|
3236
3396
|
|
|
3237
3397
|
var defaultOptions12 = [];
|
|
@@ -4126,55 +4286,59 @@ var throwErrorRule = ruleCreator({
|
|
|
4126
4286
|
});
|
|
4127
4287
|
|
|
4128
4288
|
// src/index.ts
|
|
4289
|
+
var allRules = {
|
|
4290
|
+
"ban-observables": banObservablesRule,
|
|
4291
|
+
"ban-operators": banOperatorsRule,
|
|
4292
|
+
"finnish": finnishRule,
|
|
4293
|
+
"just": justRule,
|
|
4294
|
+
"macro": macroRule,
|
|
4295
|
+
"no-async-subscribe": noAsyncSubscribeRule,
|
|
4296
|
+
"no-compat": noCompatRule,
|
|
4297
|
+
"no-connectable": noConnectableRule,
|
|
4298
|
+
"no-create": noCreateRule,
|
|
4299
|
+
"no-cyclic-action": noCyclicActionRule,
|
|
4300
|
+
"no-explicit-generics": noExplicitGenericsRule,
|
|
4301
|
+
"no-exposed-subjects": noExposedSubjectsRule,
|
|
4302
|
+
"no-finnish": noFinnishRule,
|
|
4303
|
+
"no-floating-observables": noFloatingObservablesRule,
|
|
4304
|
+
"no-ignored-default-value": noIgnoredDefaultValueRule,
|
|
4305
|
+
"no-ignored-error": noIgnoredErrorRule,
|
|
4306
|
+
"no-ignored-notifier": noIgnoredNotifierRule,
|
|
4307
|
+
"no-ignored-replay-buffer": noIgnoredReplayBufferRule,
|
|
4308
|
+
"no-ignored-subscribe": noIgnoredSubscribeRule,
|
|
4309
|
+
"no-ignored-subscription": noIgnoredSubscriptionRule,
|
|
4310
|
+
"no-ignored-takewhile-value": noIgnoredTakewhileValueRule,
|
|
4311
|
+
"no-implicit-any-catch": noImplicitAnyCatchRule,
|
|
4312
|
+
"no-index": noIndexRule,
|
|
4313
|
+
"no-internal": noInternalRule,
|
|
4314
|
+
"no-misused-observables": noMisusedObservablesRule,
|
|
4315
|
+
"no-nested-subscribe": noNestedSubscribeRule,
|
|
4316
|
+
"no-redundant-notify": noRedundantNotifyRule,
|
|
4317
|
+
"no-sharereplay": noSharereplayRule,
|
|
4318
|
+
"no-sharereplay-before-takeuntil": noSharereplayBeforeTakeuntilRule,
|
|
4319
|
+
"no-subclass": noSubclassRule,
|
|
4320
|
+
"no-subject-unsubscribe": noSubjectUnsubscribeRule,
|
|
4321
|
+
"no-subject-value": noSubjectValueRule,
|
|
4322
|
+
"no-subscribe-handlers": noSubscribeHandlersRule,
|
|
4323
|
+
"no-subscribe-in-pipe": noSubscribeInPipeRule,
|
|
4324
|
+
"no-tap": noTapRule,
|
|
4325
|
+
"no-topromise": noTopromiseRule,
|
|
4326
|
+
"no-unbound-methods": noUnboundMethodsRule,
|
|
4327
|
+
"no-unnecessary-collection": noUnnecessaryCollectionRule,
|
|
4328
|
+
"no-unsafe-catch": noUnsafeCatchRule,
|
|
4329
|
+
"no-unsafe-first": noUnsafeFirstRule,
|
|
4330
|
+
"no-unsafe-subject-next": noUnsafeSubjectNext,
|
|
4331
|
+
"no-unsafe-switchmap": noUnsafeSwitchmapRule,
|
|
4332
|
+
"no-unsafe-takeuntil": noUnsafeTakeuntilRule,
|
|
4333
|
+
"prefer-observer": preferObserverRule,
|
|
4334
|
+
"prefer-root-operators": preferRootOperatorsRule,
|
|
4335
|
+
"suffix-subjects": suffixSubjectsRule,
|
|
4336
|
+
"throw-error": throwErrorRule
|
|
4337
|
+
};
|
|
4129
4338
|
var plugin = {
|
|
4130
4339
|
meta: { name, version },
|
|
4131
|
-
|
|
4132
|
-
|
|
4133
|
-
"ban-operators": banOperatorsRule,
|
|
4134
|
-
"finnish": finnishRule,
|
|
4135
|
-
"just": justRule,
|
|
4136
|
-
"macro": macroRule,
|
|
4137
|
-
"no-async-subscribe": noAsyncSubscribeRule,
|
|
4138
|
-
"no-compat": noCompatRule,
|
|
4139
|
-
"no-connectable": noConnectableRule,
|
|
4140
|
-
"no-create": noCreateRule,
|
|
4141
|
-
"no-cyclic-action": noCyclicActionRule,
|
|
4142
|
-
"no-explicit-generics": noExplicitGenericsRule,
|
|
4143
|
-
"no-exposed-subjects": noExposedSubjectsRule,
|
|
4144
|
-
"no-finnish": noFinnishRule,
|
|
4145
|
-
"no-floating-observables": noFloatingObservablesRule,
|
|
4146
|
-
"no-ignored-default-value": noIgnoredDefaultValueRule,
|
|
4147
|
-
"no-ignored-error": noIgnoredErrorRule,
|
|
4148
|
-
"no-ignored-notifier": noIgnoredNotifierRule,
|
|
4149
|
-
"no-ignored-replay-buffer": noIgnoredReplayBufferRule,
|
|
4150
|
-
"no-ignored-subscribe": noIgnoredSubscribeRule,
|
|
4151
|
-
"no-ignored-subscription": noIgnoredSubscriptionRule,
|
|
4152
|
-
"no-ignored-takewhile-value": noIgnoredTakewhileValueRule,
|
|
4153
|
-
"no-implicit-any-catch": noImplicitAnyCatchRule,
|
|
4154
|
-
"no-index": noIndexRule,
|
|
4155
|
-
"no-internal": noInternalRule,
|
|
4156
|
-
"no-misused-observables": noMisusedObservablesRule,
|
|
4157
|
-
"no-nested-subscribe": noNestedSubscribeRule,
|
|
4158
|
-
"no-redundant-notify": noRedundantNotifyRule,
|
|
4159
|
-
"no-sharereplay": noSharereplayRule,
|
|
4160
|
-
"no-subclass": noSubclassRule,
|
|
4161
|
-
"no-subject-unsubscribe": noSubjectUnsubscribeRule,
|
|
4162
|
-
"no-subject-value": noSubjectValueRule,
|
|
4163
|
-
"no-subscribe-handlers": noSubscribeHandlersRule,
|
|
4164
|
-
"no-subscribe-in-pipe": noSubscribeInPipeRule,
|
|
4165
|
-
"no-tap": noTapRule,
|
|
4166
|
-
"no-topromise": noTopromiseRule,
|
|
4167
|
-
"no-unbound-methods": noUnboundMethodsRule,
|
|
4168
|
-
"no-unsafe-catch": noUnsafeCatchRule,
|
|
4169
|
-
"no-unsafe-first": noUnsafeFirstRule,
|
|
4170
|
-
"no-unsafe-subject-next": noUnsafeSubjectNext,
|
|
4171
|
-
"no-unsafe-switchmap": noUnsafeSwitchmapRule,
|
|
4172
|
-
"no-unsafe-takeuntil": noUnsafeTakeuntilRule,
|
|
4173
|
-
"prefer-observer": preferObserverRule,
|
|
4174
|
-
"prefer-root-operators": preferRootOperatorsRule,
|
|
4175
|
-
"suffix-subjects": suffixSubjectsRule,
|
|
4176
|
-
"throw-error": throwErrorRule
|
|
4177
|
-
}
|
|
4340
|
+
/** Compatibility with `defineConfig` until https://github.com/typescript-eslint/typescript-eslint/issues/11543 is addressed. */
|
|
4341
|
+
rules: allRules
|
|
4178
4342
|
};
|
|
4179
4343
|
var rxjsX = {
|
|
4180
4344
|
...plugin,
|
package/dist/index.mjs
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
// package.json
|
|
2
2
|
var name = "eslint-plugin-rxjs-x";
|
|
3
|
-
var version = "0.
|
|
3
|
+
var version = "0.8.1";
|
|
4
4
|
|
|
5
5
|
// src/configs/recommended.ts
|
|
6
6
|
var createRecommendedConfig = (plugin2) => ({
|
|
7
7
|
name: "rxjs-x/recommended",
|
|
8
8
|
plugins: {
|
|
9
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion -- "A type annotation is necessary."
|
|
9
10
|
"rxjs-x": plugin2
|
|
10
11
|
},
|
|
11
12
|
rules: {
|
|
@@ -36,6 +37,7 @@ var createRecommendedConfig = (plugin2) => ({
|
|
|
36
37
|
var createStrictConfig = (plugin2) => ({
|
|
37
38
|
name: "rxjs-x/strict",
|
|
38
39
|
plugins: {
|
|
40
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion -- "A type annotation is necessary."
|
|
39
41
|
"rxjs-x": plugin2
|
|
40
42
|
},
|
|
41
43
|
rules: {
|
|
@@ -56,12 +58,14 @@ var createStrictConfig = (plugin2) => ({
|
|
|
56
58
|
"rxjs-x/no-misused-observables": "error",
|
|
57
59
|
"rxjs-x/no-nested-subscribe": "error",
|
|
58
60
|
"rxjs-x/no-redundant-notify": "error",
|
|
61
|
+
"rxjs-x/no-sharereplay-before-takeuntil": "error",
|
|
59
62
|
"rxjs-x/no-sharereplay": "error",
|
|
60
63
|
"rxjs-x/no-subclass": "error",
|
|
61
64
|
"rxjs-x/no-subject-unsubscribe": "error",
|
|
62
65
|
"rxjs-x/no-subscribe-in-pipe": "error",
|
|
63
66
|
"rxjs-x/no-topromise": "error",
|
|
64
67
|
"rxjs-x/no-unbound-methods": "error",
|
|
68
|
+
"rxjs-x/no-unnecessary-collection": "error",
|
|
65
69
|
"rxjs-x/no-unsafe-subject-next": "error",
|
|
66
70
|
"rxjs-x/no-unsafe-takeuntil": "error",
|
|
67
71
|
"rxjs-x/prefer-observer": "error",
|
|
@@ -401,6 +405,14 @@ var SOURCES_OBJECT_ACCEPTING_STATIC_OBSERVABLE_CREATORS = [
|
|
|
401
405
|
"combineLatest",
|
|
402
406
|
"forkJoin"
|
|
403
407
|
];
|
|
408
|
+
var MULTIPLE_OBSERVABLE_ACCEPTING_STATIC_OBSERVABLE_CREATORS = [
|
|
409
|
+
"combineLatest",
|
|
410
|
+
"forkJoin",
|
|
411
|
+
"merge",
|
|
412
|
+
"zip",
|
|
413
|
+
"concat",
|
|
414
|
+
"race"
|
|
415
|
+
];
|
|
404
416
|
var DEFAULT_UNBOUND_ALLOWED_TYPES = [
|
|
405
417
|
"Signal"
|
|
406
418
|
];
|
|
@@ -438,6 +450,7 @@ import { ESLintUtils as ESLintUtils2 } from "@typescript-eslint/utils";
|
|
|
438
450
|
var REPO_URL = "https://github.com/JasonWeinzierl/eslint-plugin-rxjs-x";
|
|
439
451
|
var ruleCreator = ESLintUtils2.RuleCreator(
|
|
440
452
|
(name2) => `${REPO_URL}/blob/v${version}/docs/rules/${name2}.md`
|
|
453
|
+
// Ensure the resulting types are narrowed to exactly what each rule declares.
|
|
441
454
|
);
|
|
442
455
|
|
|
443
456
|
// src/rules/ban-observables.ts
|
|
@@ -2822,6 +2835,65 @@ var noSharereplayRule = ruleCreator({
|
|
|
2822
2835
|
}
|
|
2823
2836
|
});
|
|
2824
2837
|
|
|
2838
|
+
// src/rules/no-sharereplay-before-takeuntil.ts
|
|
2839
|
+
var noSharereplayBeforeTakeuntilRule = ruleCreator({
|
|
2840
|
+
defaultOptions: [],
|
|
2841
|
+
meta: {
|
|
2842
|
+
docs: {
|
|
2843
|
+
description: "Disallow using `shareReplay({ refCount: false })` before `takeUntil`.",
|
|
2844
|
+
recommended: "strict"
|
|
2845
|
+
},
|
|
2846
|
+
messages: {
|
|
2847
|
+
forbidden: "shareReplay before takeUntil is forbidden unless 'refCount: true' is specified."
|
|
2848
|
+
},
|
|
2849
|
+
schema: [],
|
|
2850
|
+
type: "problem"
|
|
2851
|
+
},
|
|
2852
|
+
name: "no-sharereplay-before-takeuntil",
|
|
2853
|
+
create: (context) => {
|
|
2854
|
+
function checkCallExpression(node) {
|
|
2855
|
+
const pipeCallExpression = node.parent;
|
|
2856
|
+
if (!pipeCallExpression.arguments || !isMemberExpression(pipeCallExpression.callee) || !isIdentifier(pipeCallExpression.callee.property) || pipeCallExpression.callee.property.name !== "pipe") {
|
|
2857
|
+
return;
|
|
2858
|
+
}
|
|
2859
|
+
const { isOrderValid, operatorNode: takeUntilNode } = findIsLastOperatorOrderValid(
|
|
2860
|
+
pipeCallExpression,
|
|
2861
|
+
/^takeUntil$/,
|
|
2862
|
+
DEFAULT_VALID_POST_COMPLETION_OPERATORS
|
|
2863
|
+
);
|
|
2864
|
+
if (!isOrderValid || !takeUntilNode) {
|
|
2865
|
+
return;
|
|
2866
|
+
}
|
|
2867
|
+
if (takeUntilNode.range[0] < node.range[0]) {
|
|
2868
|
+
return;
|
|
2869
|
+
}
|
|
2870
|
+
const shareReplayConfig = node.arguments[0];
|
|
2871
|
+
if (!shareReplayConfig || !isObjectExpression(shareReplayConfig)) {
|
|
2872
|
+
context.report({
|
|
2873
|
+
messageId: "forbidden",
|
|
2874
|
+
node: node.callee
|
|
2875
|
+
});
|
|
2876
|
+
return;
|
|
2877
|
+
}
|
|
2878
|
+
const refCountElement = shareReplayConfig.properties.filter(isProperty).find((prop) => isIdentifier(prop.key) && prop.key.name === "refCount");
|
|
2879
|
+
if (!refCountElement || isLiteral(refCountElement.value) && refCountElement.value.value === false) {
|
|
2880
|
+
context.report({
|
|
2881
|
+
messageId: "forbidden",
|
|
2882
|
+
node: node.callee
|
|
2883
|
+
});
|
|
2884
|
+
}
|
|
2885
|
+
}
|
|
2886
|
+
return {
|
|
2887
|
+
'CallExpression[callee.name="shareReplay"]': (node) => {
|
|
2888
|
+
checkCallExpression(node);
|
|
2889
|
+
},
|
|
2890
|
+
'CallExpression[callee.property.name="shareReplay"]': (node) => {
|
|
2891
|
+
checkCallExpression(node);
|
|
2892
|
+
}
|
|
2893
|
+
};
|
|
2894
|
+
}
|
|
2895
|
+
});
|
|
2896
|
+
|
|
2825
2897
|
// src/rules/no-subclass.ts
|
|
2826
2898
|
var noSubclassRule = ruleCreator({
|
|
2827
2899
|
defaultOptions: [],
|
|
@@ -3232,6 +3304,94 @@ var noUnboundMethodsRule = ruleCreator({
|
|
|
3232
3304
|
}
|
|
3233
3305
|
});
|
|
3234
3306
|
|
|
3307
|
+
// src/rules/no-unnecessary-collection.ts
|
|
3308
|
+
var noUnnecessaryCollectionRule = ruleCreator({
|
|
3309
|
+
defaultOptions: [],
|
|
3310
|
+
meta: {
|
|
3311
|
+
docs: {
|
|
3312
|
+
description: "Disallow unnecessary usage of collection arguments with single values.",
|
|
3313
|
+
recommended: "strict",
|
|
3314
|
+
requiresTypeChecking: false
|
|
3315
|
+
},
|
|
3316
|
+
messages: {
|
|
3317
|
+
forbidden: "Unnecessary {{operator}} with {{inputType}}. Use the observable directly instead."
|
|
3318
|
+
},
|
|
3319
|
+
schema: [],
|
|
3320
|
+
type: "suggestion"
|
|
3321
|
+
},
|
|
3322
|
+
name: "no-unnecessary-collection",
|
|
3323
|
+
create: (context) => {
|
|
3324
|
+
const { couldBeType: couldBeType2, couldBeObservable } = getTypeServices(context);
|
|
3325
|
+
function couldBeFromRxjs(node, operatorName) {
|
|
3326
|
+
return couldBeType2(node, operatorName, { name: /[/\\]rxjs[/\\]/ });
|
|
3327
|
+
}
|
|
3328
|
+
function checkCallExpression(node, operatorName) {
|
|
3329
|
+
const args = node.arguments;
|
|
3330
|
+
if (args.length === 0) {
|
|
3331
|
+
return;
|
|
3332
|
+
}
|
|
3333
|
+
const firstArg = args[0];
|
|
3334
|
+
if (isArrayExpression(firstArg)) {
|
|
3335
|
+
const nonNullElements = firstArg.elements.filter((element) => element !== null);
|
|
3336
|
+
if (nonNullElements.length === 1 && couldBeObservable(nonNullElements[0])) {
|
|
3337
|
+
context.report({
|
|
3338
|
+
messageId: "forbidden",
|
|
3339
|
+
node: node.callee,
|
|
3340
|
+
data: {
|
|
3341
|
+
operator: operatorName,
|
|
3342
|
+
inputType: "single-valued array"
|
|
3343
|
+
}
|
|
3344
|
+
});
|
|
3345
|
+
}
|
|
3346
|
+
return;
|
|
3347
|
+
}
|
|
3348
|
+
if (isObjectExpression(firstArg) && SOURCES_OBJECT_ACCEPTING_STATIC_OBSERVABLE_CREATORS.includes(operatorName)) {
|
|
3349
|
+
if (firstArg.properties.length === 1 && isProperty(firstArg.properties[0])) {
|
|
3350
|
+
const property = firstArg.properties[0];
|
|
3351
|
+
if (property.value && couldBeObservable(property.value)) {
|
|
3352
|
+
context.report({
|
|
3353
|
+
messageId: "forbidden",
|
|
3354
|
+
node: node.callee,
|
|
3355
|
+
data: {
|
|
3356
|
+
operator: operatorName,
|
|
3357
|
+
inputType: "single-property object"
|
|
3358
|
+
}
|
|
3359
|
+
});
|
|
3360
|
+
}
|
|
3361
|
+
}
|
|
3362
|
+
return;
|
|
3363
|
+
}
|
|
3364
|
+
if (args.length === 1 && couldBeObservable(firstArg)) {
|
|
3365
|
+
context.report({
|
|
3366
|
+
messageId: "forbidden",
|
|
3367
|
+
node: node.callee,
|
|
3368
|
+
data: {
|
|
3369
|
+
operator: operatorName,
|
|
3370
|
+
inputType: "single argument"
|
|
3371
|
+
}
|
|
3372
|
+
});
|
|
3373
|
+
}
|
|
3374
|
+
}
|
|
3375
|
+
const callExpressionVisitors = {};
|
|
3376
|
+
for (const operator of MULTIPLE_OBSERVABLE_ACCEPTING_STATIC_OBSERVABLE_CREATORS) {
|
|
3377
|
+
callExpressionVisitors[`CallExpression[callee.name="${operator}"]`] = (node) => {
|
|
3378
|
+
if (couldBeFromRxjs(node.callee, operator)) {
|
|
3379
|
+
checkCallExpression(node, operator);
|
|
3380
|
+
}
|
|
3381
|
+
};
|
|
3382
|
+
}
|
|
3383
|
+
for (const operator of MULTIPLE_OBSERVABLE_ACCEPTING_STATIC_OBSERVABLE_CREATORS) {
|
|
3384
|
+
callExpressionVisitors[`CallExpression[callee.type="MemberExpression"][callee.property.name="${operator}"]`] = (node) => {
|
|
3385
|
+
const memberExpr = node.callee;
|
|
3386
|
+
if (couldBeFromRxjs(memberExpr.property, operator)) {
|
|
3387
|
+
checkCallExpression(node, operator);
|
|
3388
|
+
}
|
|
3389
|
+
};
|
|
3390
|
+
}
|
|
3391
|
+
return callExpressionVisitors;
|
|
3392
|
+
}
|
|
3393
|
+
});
|
|
3394
|
+
|
|
3235
3395
|
// src/rules/no-unsafe-catch.ts
|
|
3236
3396
|
import { stripIndent as stripIndent5 } from "common-tags";
|
|
3237
3397
|
var defaultOptions12 = [];
|
|
@@ -4126,55 +4286,59 @@ var throwErrorRule = ruleCreator({
|
|
|
4126
4286
|
});
|
|
4127
4287
|
|
|
4128
4288
|
// src/index.ts
|
|
4289
|
+
var allRules = {
|
|
4290
|
+
"ban-observables": banObservablesRule,
|
|
4291
|
+
"ban-operators": banOperatorsRule,
|
|
4292
|
+
"finnish": finnishRule,
|
|
4293
|
+
"just": justRule,
|
|
4294
|
+
"macro": macroRule,
|
|
4295
|
+
"no-async-subscribe": noAsyncSubscribeRule,
|
|
4296
|
+
"no-compat": noCompatRule,
|
|
4297
|
+
"no-connectable": noConnectableRule,
|
|
4298
|
+
"no-create": noCreateRule,
|
|
4299
|
+
"no-cyclic-action": noCyclicActionRule,
|
|
4300
|
+
"no-explicit-generics": noExplicitGenericsRule,
|
|
4301
|
+
"no-exposed-subjects": noExposedSubjectsRule,
|
|
4302
|
+
"no-finnish": noFinnishRule,
|
|
4303
|
+
"no-floating-observables": noFloatingObservablesRule,
|
|
4304
|
+
"no-ignored-default-value": noIgnoredDefaultValueRule,
|
|
4305
|
+
"no-ignored-error": noIgnoredErrorRule,
|
|
4306
|
+
"no-ignored-notifier": noIgnoredNotifierRule,
|
|
4307
|
+
"no-ignored-replay-buffer": noIgnoredReplayBufferRule,
|
|
4308
|
+
"no-ignored-subscribe": noIgnoredSubscribeRule,
|
|
4309
|
+
"no-ignored-subscription": noIgnoredSubscriptionRule,
|
|
4310
|
+
"no-ignored-takewhile-value": noIgnoredTakewhileValueRule,
|
|
4311
|
+
"no-implicit-any-catch": noImplicitAnyCatchRule,
|
|
4312
|
+
"no-index": noIndexRule,
|
|
4313
|
+
"no-internal": noInternalRule,
|
|
4314
|
+
"no-misused-observables": noMisusedObservablesRule,
|
|
4315
|
+
"no-nested-subscribe": noNestedSubscribeRule,
|
|
4316
|
+
"no-redundant-notify": noRedundantNotifyRule,
|
|
4317
|
+
"no-sharereplay": noSharereplayRule,
|
|
4318
|
+
"no-sharereplay-before-takeuntil": noSharereplayBeforeTakeuntilRule,
|
|
4319
|
+
"no-subclass": noSubclassRule,
|
|
4320
|
+
"no-subject-unsubscribe": noSubjectUnsubscribeRule,
|
|
4321
|
+
"no-subject-value": noSubjectValueRule,
|
|
4322
|
+
"no-subscribe-handlers": noSubscribeHandlersRule,
|
|
4323
|
+
"no-subscribe-in-pipe": noSubscribeInPipeRule,
|
|
4324
|
+
"no-tap": noTapRule,
|
|
4325
|
+
"no-topromise": noTopromiseRule,
|
|
4326
|
+
"no-unbound-methods": noUnboundMethodsRule,
|
|
4327
|
+
"no-unnecessary-collection": noUnnecessaryCollectionRule,
|
|
4328
|
+
"no-unsafe-catch": noUnsafeCatchRule,
|
|
4329
|
+
"no-unsafe-first": noUnsafeFirstRule,
|
|
4330
|
+
"no-unsafe-subject-next": noUnsafeSubjectNext,
|
|
4331
|
+
"no-unsafe-switchmap": noUnsafeSwitchmapRule,
|
|
4332
|
+
"no-unsafe-takeuntil": noUnsafeTakeuntilRule,
|
|
4333
|
+
"prefer-observer": preferObserverRule,
|
|
4334
|
+
"prefer-root-operators": preferRootOperatorsRule,
|
|
4335
|
+
"suffix-subjects": suffixSubjectsRule,
|
|
4336
|
+
"throw-error": throwErrorRule
|
|
4337
|
+
};
|
|
4129
4338
|
var plugin = {
|
|
4130
4339
|
meta: { name, version },
|
|
4131
|
-
|
|
4132
|
-
|
|
4133
|
-
"ban-operators": banOperatorsRule,
|
|
4134
|
-
"finnish": finnishRule,
|
|
4135
|
-
"just": justRule,
|
|
4136
|
-
"macro": macroRule,
|
|
4137
|
-
"no-async-subscribe": noAsyncSubscribeRule,
|
|
4138
|
-
"no-compat": noCompatRule,
|
|
4139
|
-
"no-connectable": noConnectableRule,
|
|
4140
|
-
"no-create": noCreateRule,
|
|
4141
|
-
"no-cyclic-action": noCyclicActionRule,
|
|
4142
|
-
"no-explicit-generics": noExplicitGenericsRule,
|
|
4143
|
-
"no-exposed-subjects": noExposedSubjectsRule,
|
|
4144
|
-
"no-finnish": noFinnishRule,
|
|
4145
|
-
"no-floating-observables": noFloatingObservablesRule,
|
|
4146
|
-
"no-ignored-default-value": noIgnoredDefaultValueRule,
|
|
4147
|
-
"no-ignored-error": noIgnoredErrorRule,
|
|
4148
|
-
"no-ignored-notifier": noIgnoredNotifierRule,
|
|
4149
|
-
"no-ignored-replay-buffer": noIgnoredReplayBufferRule,
|
|
4150
|
-
"no-ignored-subscribe": noIgnoredSubscribeRule,
|
|
4151
|
-
"no-ignored-subscription": noIgnoredSubscriptionRule,
|
|
4152
|
-
"no-ignored-takewhile-value": noIgnoredTakewhileValueRule,
|
|
4153
|
-
"no-implicit-any-catch": noImplicitAnyCatchRule,
|
|
4154
|
-
"no-index": noIndexRule,
|
|
4155
|
-
"no-internal": noInternalRule,
|
|
4156
|
-
"no-misused-observables": noMisusedObservablesRule,
|
|
4157
|
-
"no-nested-subscribe": noNestedSubscribeRule,
|
|
4158
|
-
"no-redundant-notify": noRedundantNotifyRule,
|
|
4159
|
-
"no-sharereplay": noSharereplayRule,
|
|
4160
|
-
"no-subclass": noSubclassRule,
|
|
4161
|
-
"no-subject-unsubscribe": noSubjectUnsubscribeRule,
|
|
4162
|
-
"no-subject-value": noSubjectValueRule,
|
|
4163
|
-
"no-subscribe-handlers": noSubscribeHandlersRule,
|
|
4164
|
-
"no-subscribe-in-pipe": noSubscribeInPipeRule,
|
|
4165
|
-
"no-tap": noTapRule,
|
|
4166
|
-
"no-topromise": noTopromiseRule,
|
|
4167
|
-
"no-unbound-methods": noUnboundMethodsRule,
|
|
4168
|
-
"no-unsafe-catch": noUnsafeCatchRule,
|
|
4169
|
-
"no-unsafe-first": noUnsafeFirstRule,
|
|
4170
|
-
"no-unsafe-subject-next": noUnsafeSubjectNext,
|
|
4171
|
-
"no-unsafe-switchmap": noUnsafeSwitchmapRule,
|
|
4172
|
-
"no-unsafe-takeuntil": noUnsafeTakeuntilRule,
|
|
4173
|
-
"prefer-observer": preferObserverRule,
|
|
4174
|
-
"prefer-root-operators": preferRootOperatorsRule,
|
|
4175
|
-
"suffix-subjects": suffixSubjectsRule,
|
|
4176
|
-
"throw-error": throwErrorRule
|
|
4177
|
-
}
|
|
4340
|
+
/** Compatibility with `defineConfig` until https://github.com/typescript-eslint/typescript-eslint/issues/11543 is addressed. */
|
|
4341
|
+
rules: allRules
|
|
4178
4342
|
};
|
|
4179
4343
|
var rxjsX = {
|
|
4180
4344
|
...plugin,
|