eslint-plugin-rxjs-x 0.7.2 → 0.7.4
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.d.mts +4 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +229 -160
- package/dist/index.mjs +265 -196
- package/package.json +15 -15
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.7.
|
|
3
|
+
var version = "0.7.4";
|
|
4
4
|
|
|
5
5
|
// src/configs/recommended.ts
|
|
6
6
|
var createRecommendedConfig = (plugin2) => ({
|
|
@@ -74,11 +74,10 @@ var createStrictConfig = (plugin2) => ({
|
|
|
74
74
|
});
|
|
75
75
|
|
|
76
76
|
// src/rules/ban-observables.ts
|
|
77
|
-
import { AST_NODE_TYPES } from "@typescript-eslint/utils";
|
|
77
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES3 } from "@typescript-eslint/utils";
|
|
78
78
|
import { stripIndent } from "common-tags";
|
|
79
79
|
|
|
80
|
-
// src/utils.ts
|
|
81
|
-
import { ESLintUtils } from "@typescript-eslint/utils";
|
|
80
|
+
// src/utils/create-regexp-for-words.ts
|
|
82
81
|
function createRegExpForWords(config) {
|
|
83
82
|
if (!(config == null ? void 0 : config.length)) {
|
|
84
83
|
return void 0;
|
|
@@ -91,81 +90,11 @@ function createRegExpForWords(config) {
|
|
|
91
90
|
const joined = words.map((word) => String.raw`(\b|_)${word}(\b|_)`).join("|");
|
|
92
91
|
return new RegExp(`(${joined})`, flags);
|
|
93
92
|
}
|
|
93
|
+
|
|
94
|
+
// src/utils/escape-regexp.ts
|
|
94
95
|
function escapeRegExp(text) {
|
|
95
96
|
return text.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&");
|
|
96
97
|
}
|
|
97
|
-
var REPO_URL = "https://github.com/JasonWeinzierl/eslint-plugin-rxjs-x";
|
|
98
|
-
var ruleCreator = ESLintUtils.RuleCreator(
|
|
99
|
-
(name2) => `${REPO_URL}/blob/v${version}/docs/rules/${name2}.md`
|
|
100
|
-
);
|
|
101
|
-
|
|
102
|
-
// src/rules/ban-observables.ts
|
|
103
|
-
var defaultOptions = [];
|
|
104
|
-
var banObservablesRule = ruleCreator({
|
|
105
|
-
defaultOptions,
|
|
106
|
-
meta: {
|
|
107
|
-
docs: {
|
|
108
|
-
description: "Disallow banned observable creators."
|
|
109
|
-
},
|
|
110
|
-
messages: {
|
|
111
|
-
forbidden: "RxJS observable is banned: {{name}}{{explanation}}."
|
|
112
|
-
},
|
|
113
|
-
schema: [
|
|
114
|
-
{
|
|
115
|
-
type: "object",
|
|
116
|
-
description: stripIndent`
|
|
117
|
-
An object containing keys that are names of observable factory functions
|
|
118
|
-
and values that are either booleans or strings containing the explanation for the ban.`
|
|
119
|
-
}
|
|
120
|
-
],
|
|
121
|
-
type: "problem"
|
|
122
|
-
},
|
|
123
|
-
name: "ban-observables",
|
|
124
|
-
create: (context) => {
|
|
125
|
-
const bans = [];
|
|
126
|
-
const [config] = context.options;
|
|
127
|
-
if (!config) {
|
|
128
|
-
return {};
|
|
129
|
-
}
|
|
130
|
-
Object.entries(config).forEach(([key, value]) => {
|
|
131
|
-
if (value !== false) {
|
|
132
|
-
bans.push({
|
|
133
|
-
explanation: typeof value === "string" ? value : "",
|
|
134
|
-
regExp: new RegExp(`^${key}$`)
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
});
|
|
138
|
-
function getFailure(name2) {
|
|
139
|
-
for (let b = 0, length = bans.length; b < length; ++b) {
|
|
140
|
-
const ban = bans[b];
|
|
141
|
-
if (ban.regExp.test(name2)) {
|
|
142
|
-
const explanation = ban.explanation ? `: ${ban.explanation}` : "";
|
|
143
|
-
return {
|
|
144
|
-
messageId: "forbidden",
|
|
145
|
-
data: { name: name2, explanation }
|
|
146
|
-
};
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
return void 0;
|
|
150
|
-
}
|
|
151
|
-
return {
|
|
152
|
-
"ImportDeclaration[source.value='rxjs'] > ImportSpecifier": (node) => {
|
|
153
|
-
const identifier = node.imported;
|
|
154
|
-
const name2 = identifier.type === AST_NODE_TYPES.Identifier ? identifier.name : identifier.value;
|
|
155
|
-
const failure = getFailure(name2);
|
|
156
|
-
if (failure) {
|
|
157
|
-
context.report({
|
|
158
|
-
...failure,
|
|
159
|
-
node: identifier
|
|
160
|
-
});
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
};
|
|
164
|
-
}
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
// src/rules/ban-operators.ts
|
|
168
|
-
import { stripIndent as stripIndent2 } from "common-tags";
|
|
169
98
|
|
|
170
99
|
// src/etc/could-be-function.ts
|
|
171
100
|
import ts2 from "typescript";
|
|
@@ -281,84 +210,87 @@ function getLoc(node) {
|
|
|
281
210
|
}
|
|
282
211
|
|
|
283
212
|
// src/etc/get-type-services.ts
|
|
284
|
-
import { ESLintUtils
|
|
213
|
+
import { ESLintUtils } from "@typescript-eslint/utils";
|
|
285
214
|
import ts4 from "typescript";
|
|
286
215
|
|
|
287
216
|
// src/etc/is.ts
|
|
288
|
-
import { AST_NODE_TYPES
|
|
217
|
+
import { AST_NODE_TYPES } from "@typescript-eslint/utils";
|
|
289
218
|
function hasTypeAnnotation(node) {
|
|
290
219
|
return "typeAnnotation" in node && !!node.typeAnnotation;
|
|
291
220
|
}
|
|
292
221
|
function isArrayExpression(node) {
|
|
293
|
-
return node.type ===
|
|
222
|
+
return node.type === AST_NODE_TYPES.ArrayExpression;
|
|
294
223
|
}
|
|
295
224
|
function isArrayPattern(node) {
|
|
296
|
-
return node.type ===
|
|
225
|
+
return node.type === AST_NODE_TYPES.ArrayPattern;
|
|
297
226
|
}
|
|
298
227
|
function isArrowFunctionExpression(node) {
|
|
299
|
-
return node.type ===
|
|
228
|
+
return node.type === AST_NODE_TYPES.ArrowFunctionExpression;
|
|
300
229
|
}
|
|
301
230
|
function isBlockStatement(node) {
|
|
302
|
-
return node.type ===
|
|
231
|
+
return node.type === AST_NODE_TYPES.BlockStatement;
|
|
303
232
|
}
|
|
304
233
|
function isCallExpression(node) {
|
|
305
|
-
return node.type ===
|
|
234
|
+
return node.type === AST_NODE_TYPES.CallExpression;
|
|
306
235
|
}
|
|
307
236
|
function isChainExpression(node) {
|
|
308
|
-
return node.type ===
|
|
237
|
+
return node.type === AST_NODE_TYPES.ChainExpression;
|
|
309
238
|
}
|
|
310
239
|
function isFunctionDeclaration(node) {
|
|
311
|
-
return node.type ===
|
|
240
|
+
return node.type === AST_NODE_TYPES.FunctionDeclaration;
|
|
312
241
|
}
|
|
313
242
|
function isFunctionExpression(node) {
|
|
314
|
-
return node.type ===
|
|
243
|
+
return node.type === AST_NODE_TYPES.FunctionExpression;
|
|
315
244
|
}
|
|
316
245
|
function isIdentifier(node) {
|
|
317
|
-
return node.type ===
|
|
246
|
+
return node.type === AST_NODE_TYPES.Identifier;
|
|
318
247
|
}
|
|
319
248
|
function isImportDeclaration(node) {
|
|
320
|
-
return node.type ===
|
|
249
|
+
return node.type === AST_NODE_TYPES.ImportDeclaration;
|
|
321
250
|
}
|
|
322
251
|
function isImportNamespaceSpecifier(node) {
|
|
323
|
-
return node.type ===
|
|
252
|
+
return node.type === AST_NODE_TYPES.ImportNamespaceSpecifier;
|
|
324
253
|
}
|
|
325
254
|
function isImportSpecifier(node) {
|
|
326
|
-
return node.type ===
|
|
255
|
+
return node.type === AST_NODE_TYPES.ImportSpecifier;
|
|
327
256
|
}
|
|
328
257
|
function isJSXExpressionContainer(node) {
|
|
329
|
-
return node.type ===
|
|
258
|
+
return node.type === AST_NODE_TYPES.JSXExpressionContainer;
|
|
330
259
|
}
|
|
331
260
|
function isLiteral(node) {
|
|
332
|
-
return node.type ===
|
|
261
|
+
return node.type === AST_NODE_TYPES.Literal;
|
|
333
262
|
}
|
|
334
263
|
function isMemberExpression(node) {
|
|
335
|
-
return node.type ===
|
|
264
|
+
return node.type === AST_NODE_TYPES.MemberExpression;
|
|
336
265
|
}
|
|
337
266
|
function isMethodDefinition(node) {
|
|
338
|
-
return node.type ===
|
|
267
|
+
return node.type === AST_NODE_TYPES.MethodDefinition;
|
|
339
268
|
}
|
|
340
269
|
function isObjectExpression(node) {
|
|
341
|
-
return node.type ===
|
|
270
|
+
return node.type === AST_NODE_TYPES.ObjectExpression;
|
|
342
271
|
}
|
|
343
272
|
function isObjectPattern(node) {
|
|
344
|
-
return node.type ===
|
|
273
|
+
return node.type === AST_NODE_TYPES.ObjectPattern;
|
|
345
274
|
}
|
|
346
275
|
function isProgram(node) {
|
|
347
|
-
return node.type ===
|
|
276
|
+
return node.type === AST_NODE_TYPES.Program;
|
|
348
277
|
}
|
|
349
278
|
function isProperty(node) {
|
|
350
|
-
return node.type ===
|
|
279
|
+
return node.type === AST_NODE_TYPES.Property;
|
|
351
280
|
}
|
|
352
281
|
function isPropertyDefinition(node) {
|
|
353
|
-
return node.type ===
|
|
282
|
+
return node.type === AST_NODE_TYPES.PropertyDefinition;
|
|
354
283
|
}
|
|
355
284
|
function isUnaryExpression(node) {
|
|
356
|
-
return node.type ===
|
|
285
|
+
return node.type === AST_NODE_TYPES.UnaryExpression;
|
|
286
|
+
}
|
|
287
|
+
function isUnionType(node) {
|
|
288
|
+
return node.type === AST_NODE_TYPES.TSUnionType;
|
|
357
289
|
}
|
|
358
290
|
|
|
359
291
|
// src/etc/get-type-services.ts
|
|
360
292
|
function getTypeServices(context) {
|
|
361
|
-
const services =
|
|
293
|
+
const services = ESLintUtils.getParserServices(context);
|
|
362
294
|
const { esTreeNodeToTSNodeMap, program, getTypeAtLocation } = services;
|
|
363
295
|
const typeChecker = program.getTypeChecker();
|
|
364
296
|
const couldBeType2 = (node, name2, qualified) => {
|
|
@@ -415,18 +347,160 @@ function getTypeServices(context) {
|
|
|
415
347
|
|
|
416
348
|
// src/etc/is-import.ts
|
|
417
349
|
import { DefinitionType } from "@typescript-eslint/scope-manager";
|
|
418
|
-
import { AST_NODE_TYPES as
|
|
350
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES2 } from "@typescript-eslint/utils";
|
|
419
351
|
function isImport(scope, name2, source) {
|
|
420
352
|
const variable = scope.variables.find((variable2) => variable2.name === name2);
|
|
421
353
|
if (variable) {
|
|
422
354
|
return variable.defs.some(
|
|
423
|
-
(def) => def.type === DefinitionType.ImportBinding && def.parent.type ===
|
|
355
|
+
(def) => def.type === DefinitionType.ImportBinding && def.parent.type === AST_NODE_TYPES2.ImportDeclaration && (typeof source === "string" ? def.parent.source.value === source : source.test(def.parent.source.value))
|
|
424
356
|
);
|
|
425
357
|
}
|
|
426
358
|
return scope.upper ? isImport(scope.upper, name2, source) : false;
|
|
427
359
|
}
|
|
428
360
|
|
|
361
|
+
// src/utils/find-is-last-operator-order-valid.ts
|
|
362
|
+
function findIsLastOperatorOrderValid(pipeCallExpression, operatorsRegExp, allow) {
|
|
363
|
+
let isOrderValid = true;
|
|
364
|
+
let operatorNode;
|
|
365
|
+
for (let i = pipeCallExpression.arguments.length - 1; i >= 0; i--) {
|
|
366
|
+
const arg = pipeCallExpression.arguments[i];
|
|
367
|
+
if (operatorNode) {
|
|
368
|
+
break;
|
|
369
|
+
}
|
|
370
|
+
if (!isCallExpression(arg)) {
|
|
371
|
+
isOrderValid = false;
|
|
372
|
+
continue;
|
|
373
|
+
}
|
|
374
|
+
let operatorName;
|
|
375
|
+
if (isIdentifier(arg.callee)) {
|
|
376
|
+
operatorName = arg.callee.name;
|
|
377
|
+
} else if (isMemberExpression(arg.callee) && isIdentifier(arg.callee.property)) {
|
|
378
|
+
operatorName = arg.callee.property.name;
|
|
379
|
+
} else {
|
|
380
|
+
isOrderValid = false;
|
|
381
|
+
continue;
|
|
382
|
+
}
|
|
383
|
+
if (operatorsRegExp.test(operatorName)) {
|
|
384
|
+
operatorNode = arg.callee;
|
|
385
|
+
break;
|
|
386
|
+
}
|
|
387
|
+
if (!allow.includes(operatorName)) {
|
|
388
|
+
isOrderValid = false;
|
|
389
|
+
continue;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
return { isOrderValid, operatorNode };
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
// src/constants.ts
|
|
396
|
+
var defaultObservable = String.raw`[Aa]ction(s|s\$|\$)$`;
|
|
397
|
+
var SOURCES_OBJECT_ACCEPTING_STATIC_OBSERVABLE_CREATORS = [
|
|
398
|
+
"combineLatest",
|
|
399
|
+
"forkJoin"
|
|
400
|
+
];
|
|
401
|
+
var DEFAULT_VALID_POST_COMPLETION_OPERATORS = [
|
|
402
|
+
"count",
|
|
403
|
+
"defaultIfEmpty",
|
|
404
|
+
"endWith",
|
|
405
|
+
"every",
|
|
406
|
+
"finalize",
|
|
407
|
+
"finally",
|
|
408
|
+
"isEmpty",
|
|
409
|
+
"last",
|
|
410
|
+
"max",
|
|
411
|
+
"min",
|
|
412
|
+
"publish",
|
|
413
|
+
"publishBehavior",
|
|
414
|
+
"publishLast",
|
|
415
|
+
"publishReplay",
|
|
416
|
+
"reduce",
|
|
417
|
+
"share",
|
|
418
|
+
"shareReplay",
|
|
419
|
+
"skipLast",
|
|
420
|
+
"takeLast",
|
|
421
|
+
"throwIfEmpty",
|
|
422
|
+
"toArray"
|
|
423
|
+
];
|
|
424
|
+
|
|
425
|
+
// src/utils/is-sources-object-accepting-static-observable-creator.ts
|
|
426
|
+
function isSourcesObjectAcceptingStaticObservableCreator(expression) {
|
|
427
|
+
return isCallExpression(expression) && isIdentifier(expression.callee) && SOURCES_OBJECT_ACCEPTING_STATIC_OBSERVABLE_CREATORS.includes(expression.callee.name);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
// src/utils/rule-creator.ts
|
|
431
|
+
import { ESLintUtils as ESLintUtils2 } from "@typescript-eslint/utils";
|
|
432
|
+
var REPO_URL = "https://github.com/JasonWeinzierl/eslint-plugin-rxjs-x";
|
|
433
|
+
var ruleCreator = ESLintUtils2.RuleCreator(
|
|
434
|
+
(name2) => `${REPO_URL}/blob/v${version}/docs/rules/${name2}.md`
|
|
435
|
+
);
|
|
436
|
+
|
|
437
|
+
// src/rules/ban-observables.ts
|
|
438
|
+
var defaultOptions = [];
|
|
439
|
+
var banObservablesRule = ruleCreator({
|
|
440
|
+
defaultOptions,
|
|
441
|
+
meta: {
|
|
442
|
+
docs: {
|
|
443
|
+
description: "Disallow banned observable creators."
|
|
444
|
+
},
|
|
445
|
+
messages: {
|
|
446
|
+
forbidden: "RxJS observable is banned: {{name}}{{explanation}}."
|
|
447
|
+
},
|
|
448
|
+
schema: [
|
|
449
|
+
{
|
|
450
|
+
type: "object",
|
|
451
|
+
description: stripIndent`
|
|
452
|
+
An object containing keys that are names of observable factory functions
|
|
453
|
+
and values that are either booleans or strings containing the explanation for the ban.`
|
|
454
|
+
}
|
|
455
|
+
],
|
|
456
|
+
type: "problem"
|
|
457
|
+
},
|
|
458
|
+
name: "ban-observables",
|
|
459
|
+
create: (context) => {
|
|
460
|
+
const bans = [];
|
|
461
|
+
const [config] = context.options;
|
|
462
|
+
if (!config) {
|
|
463
|
+
return {};
|
|
464
|
+
}
|
|
465
|
+
Object.entries(config).forEach(([key, value]) => {
|
|
466
|
+
if (value !== false) {
|
|
467
|
+
bans.push({
|
|
468
|
+
explanation: typeof value === "string" ? value : "",
|
|
469
|
+
regExp: new RegExp(`^${key}$`)
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
});
|
|
473
|
+
function getFailure(name2) {
|
|
474
|
+
for (let b = 0, length = bans.length; b < length; ++b) {
|
|
475
|
+
const ban = bans[b];
|
|
476
|
+
if (ban.regExp.test(name2)) {
|
|
477
|
+
const explanation = ban.explanation ? `: ${ban.explanation}` : "";
|
|
478
|
+
return {
|
|
479
|
+
messageId: "forbidden",
|
|
480
|
+
data: { name: name2, explanation }
|
|
481
|
+
};
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
return void 0;
|
|
485
|
+
}
|
|
486
|
+
return {
|
|
487
|
+
"ImportDeclaration[source.value='rxjs'] > ImportSpecifier": (node) => {
|
|
488
|
+
const identifier = node.imported;
|
|
489
|
+
const name2 = identifier.type === AST_NODE_TYPES3.Identifier ? identifier.name : identifier.value;
|
|
490
|
+
const failure = getFailure(name2);
|
|
491
|
+
if (failure) {
|
|
492
|
+
context.report({
|
|
493
|
+
...failure,
|
|
494
|
+
node: identifier
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
};
|
|
499
|
+
}
|
|
500
|
+
});
|
|
501
|
+
|
|
429
502
|
// src/rules/ban-operators.ts
|
|
503
|
+
import { stripIndent as stripIndent2 } from "common-tags";
|
|
430
504
|
var defaultOptions2 = [];
|
|
431
505
|
var banOperatorsRule = ruleCreator({
|
|
432
506
|
defaultOptions: defaultOptions2,
|
|
@@ -681,7 +755,7 @@ var finnishRule = ruleCreator({
|
|
|
681
755
|
"ObjectExpression > Property[computed=false] > Identifier": (node) => {
|
|
682
756
|
if (validate.properties) {
|
|
683
757
|
const parent = node.parent;
|
|
684
|
-
if (node === parent.key) {
|
|
758
|
+
if (node === parent.key && !isSourcesObjectAcceptingStaticObservableCreator(parent.parent.parent)) {
|
|
685
759
|
checkNode(node);
|
|
686
760
|
}
|
|
687
761
|
}
|
|
@@ -992,11 +1066,6 @@ var noCreateRule = ruleCreator({
|
|
|
992
1066
|
import { ESLintUtils as ESLintUtils4 } from "@typescript-eslint/utils";
|
|
993
1067
|
import { stripIndent as stripIndent3 } from "common-tags";
|
|
994
1068
|
import ts5 from "typescript";
|
|
995
|
-
|
|
996
|
-
// src/constants.ts
|
|
997
|
-
var defaultObservable = String.raw`[Aa]ction(s|s\$|\$)$`;
|
|
998
|
-
|
|
999
|
-
// src/rules/no-cyclic-action.ts
|
|
1000
1069
|
function isTypeReference2(type) {
|
|
1001
1070
|
return Boolean(type.target);
|
|
1002
1071
|
}
|
|
@@ -1121,21 +1190,25 @@ var noExplicitGenericsRule = ruleCreator({
|
|
|
1121
1190
|
});
|
|
1122
1191
|
}
|
|
1123
1192
|
function checkBehaviorSubjects(node) {
|
|
1193
|
+
var _a;
|
|
1124
1194
|
const parent = node.parent;
|
|
1125
1195
|
const {
|
|
1126
1196
|
arguments: [value]
|
|
1127
1197
|
} = parent;
|
|
1128
|
-
|
|
1198
|
+
const typeArgs = (_a = parent.typeArguments) == null ? void 0 : _a.params[0];
|
|
1199
|
+
if (isArrayExpression(value) || isObjectExpression(value) || typeArgs && isUnionType(typeArgs)) {
|
|
1129
1200
|
return;
|
|
1130
1201
|
}
|
|
1131
1202
|
report(node);
|
|
1132
1203
|
}
|
|
1133
1204
|
function checkNotifications(node) {
|
|
1205
|
+
var _a;
|
|
1134
1206
|
const parent = node.parent;
|
|
1135
1207
|
const {
|
|
1136
1208
|
arguments: [, value]
|
|
1137
1209
|
} = parent;
|
|
1138
|
-
|
|
1210
|
+
const typeArgs = (_a = parent.typeArguments) == null ? void 0 : _a.params[0];
|
|
1211
|
+
if (isArrayExpression(value) || isObjectExpression(value) || typeArgs && isUnionType(typeArgs)) {
|
|
1139
1212
|
return;
|
|
1140
1213
|
}
|
|
1141
1214
|
report(node);
|
|
@@ -1765,8 +1838,10 @@ var noIgnoredSubscribeRule = ruleCreator({
|
|
|
1765
1838
|
});
|
|
1766
1839
|
|
|
1767
1840
|
// src/rules/no-ignored-subscription.ts
|
|
1841
|
+
import { stripIndent as stripIndent4 } from "common-tags";
|
|
1842
|
+
var defaultOptions7 = [];
|
|
1768
1843
|
var noIgnoredSubscriptionRule = ruleCreator({
|
|
1769
|
-
defaultOptions:
|
|
1844
|
+
defaultOptions: defaultOptions7,
|
|
1770
1845
|
meta: {
|
|
1771
1846
|
docs: {
|
|
1772
1847
|
description: "Disallow ignoring the subscription returned by `subscribe`.",
|
|
@@ -1775,12 +1850,44 @@ var noIgnoredSubscriptionRule = ruleCreator({
|
|
|
1775
1850
|
messages: {
|
|
1776
1851
|
forbidden: "Ignoring returned subscriptions is forbidden."
|
|
1777
1852
|
},
|
|
1778
|
-
schema: [
|
|
1853
|
+
schema: [
|
|
1854
|
+
{
|
|
1855
|
+
properties: {
|
|
1856
|
+
completers: { type: "array", items: { type: "string" }, description: "An array of operator names that will complete the observable and silence this rule.", default: ["takeUntil", "takeWhile", "take", "first", "last", "takeUntilDestroyed"] },
|
|
1857
|
+
postCompleters: { type: "array", items: { type: "string" }, description: "An array of operator names that are allowed to follow the completion operators.", default: DEFAULT_VALID_POST_COMPLETION_OPERATORS }
|
|
1858
|
+
},
|
|
1859
|
+
type: "object",
|
|
1860
|
+
description: stripIndent4`
|
|
1861
|
+
An object with optional \`completers\` and \`postCompleters\` properties.
|
|
1862
|
+
The \`completers\` property is an array containing the names of operators that will complete the observable and silence this rule.
|
|
1863
|
+
The \`postCompleters\` property is an array containing the names of the operators that are allowed to follow the completion operators.
|
|
1864
|
+
`
|
|
1865
|
+
}
|
|
1866
|
+
],
|
|
1779
1867
|
type: "problem"
|
|
1780
1868
|
},
|
|
1781
1869
|
name: "no-ignored-subscription",
|
|
1782
1870
|
create: (context) => {
|
|
1871
|
+
const [config = {}] = context.options;
|
|
1872
|
+
const {
|
|
1873
|
+
completers = ["takeUntil", "takeWhile", "take", "first", "last", "takeUntilDestroyed"],
|
|
1874
|
+
postCompleters = DEFAULT_VALID_POST_COMPLETION_OPERATORS
|
|
1875
|
+
} = config;
|
|
1876
|
+
const checkedOperatorsRegExp = new RegExp(
|
|
1877
|
+
`^(${completers.join("|")})$`
|
|
1878
|
+
);
|
|
1783
1879
|
const { couldBeObservable, couldBeType: couldBeType2 } = getTypeServices(context);
|
|
1880
|
+
function hasAllowedOperator(node) {
|
|
1881
|
+
if (isCallExpression(node) && isMemberExpression(node.callee) && isIdentifier(node.callee.property) && node.callee.property.name === "pipe") {
|
|
1882
|
+
const { isOrderValid, operatorNode } = findIsLastOperatorOrderValid(
|
|
1883
|
+
node,
|
|
1884
|
+
checkedOperatorsRegExp,
|
|
1885
|
+
postCompleters
|
|
1886
|
+
);
|
|
1887
|
+
return isOrderValid && !!operatorNode;
|
|
1888
|
+
}
|
|
1889
|
+
return false;
|
|
1890
|
+
}
|
|
1784
1891
|
return {
|
|
1785
1892
|
"ExpressionStatement > CallExpression > MemberExpression[property.name='subscribe']": (node) => {
|
|
1786
1893
|
if (couldBeObservable(node.object)) {
|
|
@@ -1788,6 +1895,9 @@ var noIgnoredSubscriptionRule = ruleCreator({
|
|
|
1788
1895
|
if (callExpression.arguments.length === 1 && couldBeType2(callExpression.arguments[0], "Subscriber")) {
|
|
1789
1896
|
return;
|
|
1790
1897
|
}
|
|
1898
|
+
if (hasAllowedOperator(node.object)) {
|
|
1899
|
+
return;
|
|
1900
|
+
}
|
|
1791
1901
|
context.report({
|
|
1792
1902
|
messageId: "forbidden",
|
|
1793
1903
|
node: node.property
|
|
@@ -1862,9 +1972,9 @@ function isParenthesised(sourceCode, node) {
|
|
|
1862
1972
|
const after = sourceCode.getTokenAfter(node);
|
|
1863
1973
|
return before && after && before.value === "(" && before.range[1] <= node.range[0] && after.value === ")" && after.range[0] >= node.range[1];
|
|
1864
1974
|
}
|
|
1865
|
-
var
|
|
1975
|
+
var defaultOptions8 = [];
|
|
1866
1976
|
var noImplicitAnyCatchRule = ruleCreator({
|
|
1867
|
-
defaultOptions:
|
|
1977
|
+
defaultOptions: defaultOptions8,
|
|
1868
1978
|
meta: {
|
|
1869
1979
|
docs: {
|
|
1870
1980
|
description: "Disallow implicit `any` error parameters in `catchError` operators.",
|
|
@@ -2138,9 +2248,9 @@ function parseChecksVoidReturn(checksVoidReturn) {
|
|
|
2138
2248
|
};
|
|
2139
2249
|
}
|
|
2140
2250
|
}
|
|
2141
|
-
var
|
|
2251
|
+
var defaultOptions9 = [];
|
|
2142
2252
|
var noMisusedObservablesRule = ruleCreator({
|
|
2143
|
-
defaultOptions:
|
|
2253
|
+
defaultOptions: defaultOptions9,
|
|
2144
2254
|
meta: {
|
|
2145
2255
|
docs: {
|
|
2146
2256
|
description: "Disallow Observables in places not designed to handle them.",
|
|
@@ -2628,9 +2738,9 @@ function isExpressionObserver(expressionStatement, couldBeType2) {
|
|
|
2628
2738
|
|
|
2629
2739
|
// src/rules/no-sharereplay.ts
|
|
2630
2740
|
import { AST_NODE_TYPES as AST_NODE_TYPES7 } from "@typescript-eslint/utils";
|
|
2631
|
-
var
|
|
2741
|
+
var defaultOptions10 = [];
|
|
2632
2742
|
var noSharereplayRule = ruleCreator({
|
|
2633
|
-
defaultOptions:
|
|
2743
|
+
defaultOptions: defaultOptions10,
|
|
2634
2744
|
meta: {
|
|
2635
2745
|
docs: {
|
|
2636
2746
|
description: "Disallow unsafe `shareReplay` usage.",
|
|
@@ -3069,10 +3179,10 @@ var noUnboundMethodsRule = ruleCreator({
|
|
|
3069
3179
|
});
|
|
3070
3180
|
|
|
3071
3181
|
// src/rules/no-unsafe-catch.ts
|
|
3072
|
-
import { stripIndent as
|
|
3073
|
-
var
|
|
3182
|
+
import { stripIndent as stripIndent5 } from "common-tags";
|
|
3183
|
+
var defaultOptions11 = [];
|
|
3074
3184
|
var noUnsafeCatchRule = ruleCreator({
|
|
3075
|
-
defaultOptions:
|
|
3185
|
+
defaultOptions: defaultOptions11,
|
|
3076
3186
|
meta: {
|
|
3077
3187
|
docs: {
|
|
3078
3188
|
description: "Disallow unsafe `catchError` usage in effects and epics.",
|
|
@@ -3087,7 +3197,7 @@ var noUnsafeCatchRule = ruleCreator({
|
|
|
3087
3197
|
observable: { type: "string", description: "A RegExp that matches an effect or epic's actions observable.", default: defaultObservable }
|
|
3088
3198
|
},
|
|
3089
3199
|
type: "object",
|
|
3090
|
-
description:
|
|
3200
|
+
description: stripIndent5`
|
|
3091
3201
|
An optional object with an optional \`observable\` property.
|
|
3092
3202
|
The property can be specified as a regular expression string and is used to identify the action observables from which effects and epics are composed.`
|
|
3093
3203
|
}
|
|
@@ -3130,10 +3240,10 @@ var noUnsafeCatchRule = ruleCreator({
|
|
|
3130
3240
|
});
|
|
3131
3241
|
|
|
3132
3242
|
// src/rules/no-unsafe-first.ts
|
|
3133
|
-
import { stripIndent as
|
|
3134
|
-
var
|
|
3243
|
+
import { stripIndent as stripIndent6 } from "common-tags";
|
|
3244
|
+
var defaultOptions12 = [];
|
|
3135
3245
|
var noUnsafeFirstRule = ruleCreator({
|
|
3136
|
-
defaultOptions:
|
|
3246
|
+
defaultOptions: defaultOptions12,
|
|
3137
3247
|
meta: {
|
|
3138
3248
|
docs: {
|
|
3139
3249
|
description: "Disallow unsafe `first`/`take` usage in effects and epics.",
|
|
@@ -3148,7 +3258,7 @@ var noUnsafeFirstRule = ruleCreator({
|
|
|
3148
3258
|
observable: { type: "string", description: "A RegExp that matches an effect or epic's actions observable.", default: defaultObservable }
|
|
3149
3259
|
},
|
|
3150
3260
|
type: "object",
|
|
3151
|
-
description:
|
|
3261
|
+
description: stripIndent6`
|
|
3152
3262
|
An optional object with an optional \`observable\` property.
|
|
3153
3263
|
The property can be specified as a regular expression string and is used to identify the action observables from which effects and epics are composed.`
|
|
3154
3264
|
}
|
|
@@ -3253,11 +3363,11 @@ var noUnsafeSubjectNext = ruleCreator({
|
|
|
3253
3363
|
});
|
|
3254
3364
|
|
|
3255
3365
|
// src/rules/no-unsafe-switchmap.ts
|
|
3256
|
-
import { stripIndent as
|
|
3366
|
+
import { stripIndent as stripIndent7 } from "common-tags";
|
|
3257
3367
|
import decamelize from "decamelize";
|
|
3258
|
-
var
|
|
3368
|
+
var defaultOptions13 = [];
|
|
3259
3369
|
var noUnsafeSwitchmapRule = ruleCreator({
|
|
3260
|
-
defaultOptions:
|
|
3370
|
+
defaultOptions: defaultOptions13,
|
|
3261
3371
|
meta: {
|
|
3262
3372
|
docs: {
|
|
3263
3373
|
description: "Disallow unsafe `switchMap` usage in effects and epics.",
|
|
@@ -3290,7 +3400,7 @@ var noUnsafeSwitchmapRule = ruleCreator({
|
|
|
3290
3400
|
}
|
|
3291
3401
|
},
|
|
3292
3402
|
type: "object",
|
|
3293
|
-
description:
|
|
3403
|
+
description: stripIndent7`
|
|
3294
3404
|
An optional object with optional \`allow\`, \`disallow\` and \`observable\` properties.
|
|
3295
3405
|
The properties can be specified as regular expression strings or as arrays of words.
|
|
3296
3406
|
The \`allow\` or \`disallow\` properties are mutually exclusive. Whether or not
|
|
@@ -3379,33 +3489,10 @@ var noUnsafeSwitchmapRule = ruleCreator({
|
|
|
3379
3489
|
});
|
|
3380
3490
|
|
|
3381
3491
|
// src/rules/no-unsafe-takeuntil.ts
|
|
3382
|
-
import { stripIndent as
|
|
3383
|
-
var
|
|
3384
|
-
var allowedOperators = [
|
|
3385
|
-
"count",
|
|
3386
|
-
"defaultIfEmpty",
|
|
3387
|
-
"endWith",
|
|
3388
|
-
"every",
|
|
3389
|
-
"finalize",
|
|
3390
|
-
"finally",
|
|
3391
|
-
"isEmpty",
|
|
3392
|
-
"last",
|
|
3393
|
-
"max",
|
|
3394
|
-
"min",
|
|
3395
|
-
"publish",
|
|
3396
|
-
"publishBehavior",
|
|
3397
|
-
"publishLast",
|
|
3398
|
-
"publishReplay",
|
|
3399
|
-
"reduce",
|
|
3400
|
-
"share",
|
|
3401
|
-
"shareReplay",
|
|
3402
|
-
"skipLast",
|
|
3403
|
-
"takeLast",
|
|
3404
|
-
"throwIfEmpty",
|
|
3405
|
-
"toArray"
|
|
3406
|
-
];
|
|
3492
|
+
import { stripIndent as stripIndent8 } from "common-tags";
|
|
3493
|
+
var defaultOptions14 = [];
|
|
3407
3494
|
var noUnsafeTakeuntilRule = ruleCreator({
|
|
3408
|
-
defaultOptions:
|
|
3495
|
+
defaultOptions: defaultOptions14,
|
|
3409
3496
|
meta: {
|
|
3410
3497
|
docs: {
|
|
3411
3498
|
description: "Disallow applying operators after `takeUntil`.",
|
|
@@ -3419,10 +3506,10 @@ var noUnsafeTakeuntilRule = ruleCreator({
|
|
|
3419
3506
|
{
|
|
3420
3507
|
properties: {
|
|
3421
3508
|
alias: { type: "array", items: { type: "string" }, description: "An array of operator names that should be treated similarly to `takeUntil`." },
|
|
3422
|
-
allow: { type: "array", items: { type: "string" }, description: "An array of operator names that are allowed to follow `takeUntil`.", default:
|
|
3509
|
+
allow: { type: "array", items: { type: "string" }, description: "An array of operator names that are allowed to follow `takeUntil`.", default: DEFAULT_VALID_POST_COMPLETION_OPERATORS }
|
|
3423
3510
|
},
|
|
3424
3511
|
type: "object",
|
|
3425
|
-
description:
|
|
3512
|
+
description: stripIndent8`
|
|
3426
3513
|
An optional object with optional \`alias\` and \`allow\` properties.
|
|
3427
3514
|
The \`alias\` property is an array containing the names of operators that aliases for \`takeUntil\`.
|
|
3428
3515
|
The \`allow\` property is an array containing the names of the operators that are allowed to follow \`takeUntil\`.`
|
|
@@ -3434,7 +3521,7 @@ var noUnsafeTakeuntilRule = ruleCreator({
|
|
|
3434
3521
|
create: (context) => {
|
|
3435
3522
|
let checkedOperatorsRegExp = /^takeUntil$/;
|
|
3436
3523
|
const [config = {}] = context.options;
|
|
3437
|
-
const { alias, allow =
|
|
3524
|
+
const { alias, allow = DEFAULT_VALID_POST_COMPLETION_OPERATORS } = config;
|
|
3438
3525
|
if (alias) {
|
|
3439
3526
|
checkedOperatorsRegExp = new RegExp(
|
|
3440
3527
|
`^(${alias.concat("takeUntil").join("|")})$`
|
|
@@ -3446,35 +3533,17 @@ var noUnsafeTakeuntilRule = ruleCreator({
|
|
|
3446
3533
|
if (!pipeCallExpression.arguments || !couldBeObservable(pipeCallExpression)) {
|
|
3447
3534
|
return;
|
|
3448
3535
|
}
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
operatorName = arg.callee.property.name;
|
|
3461
|
-
} else {
|
|
3462
|
-
return "disallowed";
|
|
3463
|
-
}
|
|
3464
|
-
if (checkedOperatorsRegExp.test(operatorName)) {
|
|
3465
|
-
if (state === "disallowed") {
|
|
3466
|
-
context.report({
|
|
3467
|
-
messageId: "forbidden",
|
|
3468
|
-
node: arg.callee
|
|
3469
|
-
});
|
|
3470
|
-
}
|
|
3471
|
-
return "taken";
|
|
3472
|
-
}
|
|
3473
|
-
if (!allow.includes(operatorName)) {
|
|
3474
|
-
return "disallowed";
|
|
3475
|
-
}
|
|
3476
|
-
return state;
|
|
3477
|
-
}, "allowed");
|
|
3536
|
+
const { isOrderValid, operatorNode } = findIsLastOperatorOrderValid(
|
|
3537
|
+
pipeCallExpression,
|
|
3538
|
+
checkedOperatorsRegExp,
|
|
3539
|
+
allow
|
|
3540
|
+
);
|
|
3541
|
+
if (!isOrderValid && operatorNode) {
|
|
3542
|
+
context.report({
|
|
3543
|
+
messageId: "forbidden",
|
|
3544
|
+
node: operatorNode
|
|
3545
|
+
});
|
|
3546
|
+
}
|
|
3478
3547
|
}
|
|
3479
3548
|
return {
|
|
3480
3549
|
[`CallExpression[callee.property.name='pipe'] > CallExpression[callee.name=${checkedOperatorsRegExp}]`]: checkNode,
|
|
@@ -3484,9 +3553,9 @@ var noUnsafeTakeuntilRule = ruleCreator({
|
|
|
3484
3553
|
});
|
|
3485
3554
|
|
|
3486
3555
|
// src/rules/prefer-observer.ts
|
|
3487
|
-
var
|
|
3556
|
+
var defaultOptions15 = [];
|
|
3488
3557
|
var preferObserverRule = ruleCreator({
|
|
3489
|
-
defaultOptions:
|
|
3558
|
+
defaultOptions: defaultOptions15,
|
|
3490
3559
|
meta: {
|
|
3491
3560
|
docs: {
|
|
3492
3561
|
description: "Disallow passing separate handlers to `subscribe` and `tap`.",
|
|
@@ -3722,9 +3791,9 @@ var preferRootOperatorsRule = ruleCreator({
|
|
|
3722
3791
|
|
|
3723
3792
|
// src/rules/suffix-subjects.ts
|
|
3724
3793
|
import { AST_NODE_TYPES as AST_NODE_TYPES9, ESLintUtils as ESLintUtils11 } from "@typescript-eslint/utils";
|
|
3725
|
-
var
|
|
3794
|
+
var defaultOptions16 = [];
|
|
3726
3795
|
var suffixSubjectsRule = ruleCreator({
|
|
3727
|
-
defaultOptions:
|
|
3796
|
+
defaultOptions: defaultOptions16,
|
|
3728
3797
|
meta: {
|
|
3729
3798
|
docs: {
|
|
3730
3799
|
description: "Enforce the use of a suffix in subject identifiers.",
|
|
@@ -3856,7 +3925,7 @@ var suffixSubjectsRule = ruleCreator({
|
|
|
3856
3925
|
"ObjectExpression > Property[computed=false] > Identifier": (node) => {
|
|
3857
3926
|
if (validate.properties) {
|
|
3858
3927
|
const parent = node.parent;
|
|
3859
|
-
if (node === parent.key) {
|
|
3928
|
+
if (node === parent.key && !isSourcesObjectAcceptingStaticObservableCreator(parent.parent.parent)) {
|
|
3860
3929
|
checkNode(node);
|
|
3861
3930
|
}
|
|
3862
3931
|
}
|
|
@@ -3921,9 +3990,9 @@ var suffixSubjectsRule = ruleCreator({
|
|
|
3921
3990
|
// src/rules/throw-error.ts
|
|
3922
3991
|
import { ESLintUtils as ESLintUtils12 } from "@typescript-eslint/utils";
|
|
3923
3992
|
import * as tsutils4 from "ts-api-utils";
|
|
3924
|
-
var
|
|
3993
|
+
var defaultOptions17 = [];
|
|
3925
3994
|
var throwErrorRule = ruleCreator({
|
|
3926
|
-
defaultOptions:
|
|
3995
|
+
defaultOptions: defaultOptions17,
|
|
3927
3996
|
meta: {
|
|
3928
3997
|
docs: {
|
|
3929
3998
|
description: "Enforce passing only `Error` values to `throwError`.",
|