eslint-plugin-rxjs-x 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +126 -224
- package/package.json +56 -51
package/dist/index.js
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
|
+
import { AST_NODE_TYPES, ESLintUtils } from "@typescript-eslint/utils";
|
|
1
2
|
import ts from "typescript";
|
|
2
3
|
import * as tsutils from "ts-api-utils";
|
|
3
|
-
import { AST_NODE_TYPES, ESLintUtils } from "@typescript-eslint/utils";
|
|
4
4
|
import { getFunctionHeadLocation, isFunction } from "@typescript-eslint/utils/ast-utils";
|
|
5
5
|
import decamelize from "decamelize";
|
|
6
|
-
|
|
7
6
|
//#region package.json
|
|
8
7
|
var name = "eslint-plugin-rxjs-x";
|
|
9
|
-
var version = "1.0.
|
|
10
|
-
|
|
8
|
+
var version = "1.0.2";
|
|
11
9
|
//#endregion
|
|
12
10
|
//#region src/configs/recommended.ts
|
|
13
11
|
const createRecommendedConfig = (plugin) => ({
|
|
@@ -37,7 +35,6 @@ const baseConfig = { rules: {
|
|
|
37
35
|
"rxjs-x/prefer-root-operators": "error",
|
|
38
36
|
"rxjs-x/throw-error": "error"
|
|
39
37
|
} };
|
|
40
|
-
|
|
41
38
|
//#endregion
|
|
42
39
|
//#region src/configs/strict.ts
|
|
43
40
|
const createStrictConfig = (plugin) => ({
|
|
@@ -77,7 +74,6 @@ const createStrictConfig = (plugin) => ({
|
|
|
77
74
|
}]
|
|
78
75
|
}
|
|
79
76
|
});
|
|
80
|
-
|
|
81
77
|
//#endregion
|
|
82
78
|
//#region src/etc/could-be-type.ts
|
|
83
79
|
function couldBeType(type, name, qualified) {
|
|
@@ -92,7 +88,7 @@ function couldBeType(type, name, qualified) {
|
|
|
92
88
|
function isType(symbol, name, qualified) {
|
|
93
89
|
if (!symbol) return false;
|
|
94
90
|
if (qualified && !qualified.name.test(qualified.typeChecker.getFullyQualifiedName(symbol))) return false;
|
|
95
|
-
return typeof name === "string" ? symbol.name === name :
|
|
91
|
+
return typeof name === "string" ? symbol.name === name : name.test(symbol.name);
|
|
96
92
|
}
|
|
97
93
|
function couldImplement(type, name, qualified) {
|
|
98
94
|
const { symbol } = type;
|
|
@@ -117,20 +113,18 @@ function isMatchingNode(node, name, qualified) {
|
|
|
117
113
|
}
|
|
118
114
|
}
|
|
119
115
|
const text = expression.getText();
|
|
120
|
-
return typeof name === "string" ? text === name :
|
|
116
|
+
return typeof name === "string" ? text === name : name.test(text);
|
|
121
117
|
}
|
|
122
|
-
|
|
123
118
|
//#endregion
|
|
124
119
|
//#region src/etc/could-be-function.ts
|
|
125
120
|
function couldBeFunction(type) {
|
|
126
121
|
return type.getCallSignatures().length > 0 || couldBeType(type, "Function") || couldBeType(type, "ArrowFunction") || couldBeType(type, ts.InternalSymbolName.Function);
|
|
127
122
|
}
|
|
128
|
-
|
|
129
123
|
//#endregion
|
|
130
124
|
//#region src/etc/find-parent.ts
|
|
131
125
|
function findParent(node, ...args) {
|
|
132
126
|
const [arg] = args;
|
|
133
|
-
const predicate = typeof arg === "function" ? arg : (type) =>
|
|
127
|
+
const predicate = typeof arg === "function" ? arg : (type) => args.includes(type) ? "return" : "continue";
|
|
134
128
|
let parent = node.parent;
|
|
135
129
|
while (parent) {
|
|
136
130
|
switch (predicate(parent.type)) {
|
|
@@ -141,7 +135,6 @@ function findParent(node, ...args) {
|
|
|
141
135
|
parent = parent.parent;
|
|
142
136
|
}
|
|
143
137
|
}
|
|
144
|
-
|
|
145
138
|
//#endregion
|
|
146
139
|
//#region src/etc/get-loc.ts
|
|
147
140
|
function getLoc(node) {
|
|
@@ -159,7 +152,6 @@ function getLoc(node) {
|
|
|
159
152
|
}
|
|
160
153
|
};
|
|
161
154
|
}
|
|
162
|
-
|
|
163
155
|
//#endregion
|
|
164
156
|
//#region src/etc/is.ts
|
|
165
157
|
function hasTypeAnnotation(node) {
|
|
@@ -252,7 +244,6 @@ function isUnionType(node) {
|
|
|
252
244
|
function isVariableDeclarator(node) {
|
|
253
245
|
return node.type === AST_NODE_TYPES.VariableDeclarator;
|
|
254
246
|
}
|
|
255
|
-
|
|
256
247
|
//#endregion
|
|
257
248
|
//#region src/etc/get-type-services.ts
|
|
258
249
|
function getTypeServices(context) {
|
|
@@ -284,10 +275,10 @@ function getTypeServices(context) {
|
|
|
284
275
|
couldBeSubscription: (node) => couldBeType$1(node, "Subscription"),
|
|
285
276
|
couldBeType: couldBeType$1,
|
|
286
277
|
couldReturnObservable: (node) => couldReturnType(node, "Observable"),
|
|
278
|
+
couldReturnSubject: (node) => couldReturnType(node, "Subject"),
|
|
287
279
|
couldReturnType
|
|
288
280
|
};
|
|
289
281
|
}
|
|
290
|
-
|
|
291
282
|
//#endregion
|
|
292
283
|
//#region src/utils/create-regexp-for-words.ts
|
|
293
284
|
function createRegExpForWords(config) {
|
|
@@ -297,13 +288,11 @@ function createRegExpForWords(config) {
|
|
|
297
288
|
const joined = config.map((word) => String.raw`(\b|_)${word}(\b|_)`).join("|");
|
|
298
289
|
return new RegExp(`(${joined})`, flags);
|
|
299
290
|
}
|
|
300
|
-
|
|
301
291
|
//#endregion
|
|
302
292
|
//#region src/utils/escape-regexp.ts
|
|
303
293
|
function escapeRegExp(text) {
|
|
304
|
-
return text.
|
|
294
|
+
return text.replaceAll(/[-/\\^$*+?.()|[\]{}]/g, String.raw`\$&`);
|
|
305
295
|
}
|
|
306
|
-
|
|
307
296
|
//#endregion
|
|
308
297
|
//#region src/utils/find-is-last-operator-order-valid.ts
|
|
309
298
|
/**
|
|
@@ -342,12 +331,10 @@ function findIsLastOperatorOrderValid(pipeCallExpression, operatorsRegExp, allow
|
|
|
342
331
|
operatorNode
|
|
343
332
|
};
|
|
344
333
|
}
|
|
345
|
-
|
|
346
334
|
//#endregion
|
|
347
335
|
//#region src/utils/rule-creator.ts
|
|
348
336
|
const REPO_URL = "https://github.com/JasonWeinzierl/eslint-plugin-rxjs-x";
|
|
349
337
|
const ruleCreator = ESLintUtils.RuleCreator((name) => `${REPO_URL}/blob/v${version}/docs/rules/${name}.md`);
|
|
350
|
-
|
|
351
338
|
//#endregion
|
|
352
339
|
//#region src/rules/ban-observables.ts
|
|
353
340
|
const banObservablesRule = ruleCreator({
|
|
@@ -368,11 +355,9 @@ and values that are either booleans or strings containing the explanation for th
|
|
|
368
355
|
const bans = [];
|
|
369
356
|
const [config] = context.options;
|
|
370
357
|
if (!config || !Object.keys(config).length) return {};
|
|
371
|
-
Object.entries(config)
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
regExp: new RegExp(`^${key}$`)
|
|
375
|
-
});
|
|
358
|
+
for (const [key, value] of Object.entries(config)) if (value !== false) bans.push({
|
|
359
|
+
explanation: typeof value === "string" ? value : "",
|
|
360
|
+
regExp: new RegExp(`^${key}$`)
|
|
376
361
|
});
|
|
377
362
|
function getFailure(name) {
|
|
378
363
|
for (let b = 0, length = bans.length; b < length; ++b) {
|
|
@@ -396,7 +381,6 @@ and values that are either booleans or strings containing the explanation for th
|
|
|
396
381
|
} };
|
|
397
382
|
}
|
|
398
383
|
});
|
|
399
|
-
|
|
400
384
|
//#endregion
|
|
401
385
|
//#region src/rules/ban-operators.ts
|
|
402
386
|
const banOperatorsRule = ruleCreator({
|
|
@@ -421,11 +405,9 @@ and values that are either booleans or strings containing the explanation for th
|
|
|
421
405
|
const bans = [];
|
|
422
406
|
const [config] = context.options;
|
|
423
407
|
if (!config || !Object.keys(config).length) return {};
|
|
424
|
-
Object.entries(config)
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
explanation: typeof value === "string" ? value : ""
|
|
428
|
-
});
|
|
408
|
+
for (const [key, value] of Object.entries(config)) if (value !== false) bans.push({
|
|
409
|
+
name: key,
|
|
410
|
+
explanation: typeof value === "string" ? value : ""
|
|
429
411
|
});
|
|
430
412
|
function checkNode(node) {
|
|
431
413
|
for (const ban of bans) if (couldBeType(node, ban.name, { name: /[/\\]rxjs[/\\]/ })) {
|
|
@@ -452,7 +434,6 @@ and values that are either booleans or strings containing the explanation for th
|
|
|
452
434
|
};
|
|
453
435
|
}
|
|
454
436
|
});
|
|
455
|
-
|
|
456
437
|
//#endregion
|
|
457
438
|
//#region src/rules/finnish.ts
|
|
458
439
|
const baseShouldBeFinnish = "Finnish notation should be used here.";
|
|
@@ -528,18 +509,14 @@ const finnishRule = ruleCreator({
|
|
|
528
509
|
const [config] = context.options;
|
|
529
510
|
const { strict } = config;
|
|
530
511
|
const names = [];
|
|
531
|
-
if (config.names) Object.entries(config.names).
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
validate
|
|
535
|
-
});
|
|
512
|
+
if (config.names) for (const [key, validate] of Object.entries(config.names)) names.push({
|
|
513
|
+
regExp: new RegExp(key),
|
|
514
|
+
validate
|
|
536
515
|
});
|
|
537
516
|
const types = [];
|
|
538
|
-
if (config.types) Object.entries(config.types).
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
validate
|
|
542
|
-
});
|
|
517
|
+
if (config.types) for (const [key, validate] of Object.entries(config.types)) types.push({
|
|
518
|
+
regExp: new RegExp(key),
|
|
519
|
+
validate
|
|
543
520
|
});
|
|
544
521
|
function checkNode(nameNode, typeNode, shouldMessage = "shouldBeFinnish") {
|
|
545
522
|
const tsNode = esTreeNodeToTSNodeMap.get(nameNode);
|
|
@@ -631,9 +608,7 @@ const finnishRule = ruleCreator({
|
|
|
631
608
|
if (node.override) return;
|
|
632
609
|
if (config.methods && node.kind === "method") checkNode(node.key, node);
|
|
633
610
|
if (config.properties && (node.kind === "get" || node.kind === "set")) checkNode(node.key, node);
|
|
634
|
-
if (config.parameters) node.value.params
|
|
635
|
-
checkNode(param);
|
|
636
|
-
});
|
|
611
|
+
if (config.parameters) for (const param of node.value.params) checkNode(param);
|
|
637
612
|
},
|
|
638
613
|
"ObjectExpression > Property[computed=false] > Identifier": (node) => {
|
|
639
614
|
if (!config.objects) return;
|
|
@@ -660,9 +635,7 @@ const finnishRule = ruleCreator({
|
|
|
660
635
|
},
|
|
661
636
|
"TSMethodSignature[computed=false]": (node) => {
|
|
662
637
|
if (config.methods) checkNode(node.key, node);
|
|
663
|
-
if (config.parameters) node.params
|
|
664
|
-
checkNode(param);
|
|
665
|
-
});
|
|
638
|
+
if (config.parameters) for (const param of node.params) checkNode(param);
|
|
666
639
|
},
|
|
667
640
|
"TSParameterProperty > Identifier": (node) => {
|
|
668
641
|
if (config.parameters || config.properties) checkNode(node);
|
|
@@ -677,7 +650,6 @@ const finnishRule = ruleCreator({
|
|
|
677
650
|
};
|
|
678
651
|
}
|
|
679
652
|
});
|
|
680
|
-
|
|
681
653
|
//#endregion
|
|
682
654
|
//#region src/rules/just.ts
|
|
683
655
|
const justRule = ruleCreator({
|
|
@@ -698,17 +670,14 @@ const justRule = ruleCreator({
|
|
|
698
670
|
fix: (fixer) => fixer.replaceTextRange(node.range, "of as just")
|
|
699
671
|
});
|
|
700
672
|
const [ofImport] = context.sourceCode.getDeclaredVariables(node);
|
|
701
|
-
ofImport.references.
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
fix: (fixer) => fixer.replaceTextRange(ref.identifier.range, "just")
|
|
706
|
-
});
|
|
673
|
+
for (const ref of ofImport.references) context.report({
|
|
674
|
+
messageId: "forbidden",
|
|
675
|
+
node: ref.identifier,
|
|
676
|
+
fix: (fixer) => fixer.replaceTextRange(ref.identifier.range, "just")
|
|
707
677
|
});
|
|
708
678
|
} };
|
|
709
679
|
}
|
|
710
680
|
});
|
|
711
|
-
|
|
712
681
|
//#endregion
|
|
713
682
|
//#region src/rules/no-async-subscribe.ts
|
|
714
683
|
const noAsyncSubscribeRule = ruleCreator({
|
|
@@ -755,7 +724,6 @@ const noAsyncSubscribeRule = ruleCreator({
|
|
|
755
724
|
};
|
|
756
725
|
}
|
|
757
726
|
});
|
|
758
|
-
|
|
759
727
|
//#endregion
|
|
760
728
|
//#region src/rules/no-connectable.ts
|
|
761
729
|
const noConnectableRule = ruleCreator({
|
|
@@ -787,7 +755,6 @@ const noConnectableRule = ruleCreator({
|
|
|
787
755
|
};
|
|
788
756
|
}
|
|
789
757
|
});
|
|
790
|
-
|
|
791
758
|
//#endregion
|
|
792
759
|
//#region src/rules/no-create.ts
|
|
793
760
|
const noCreateRule = ruleCreator({
|
|
@@ -825,7 +792,6 @@ const noCreateRule = ruleCreator({
|
|
|
825
792
|
};
|
|
826
793
|
}
|
|
827
794
|
});
|
|
828
|
-
|
|
829
795
|
//#endregion
|
|
830
796
|
//#region src/constants.ts
|
|
831
797
|
const defaultObservable = String.raw`[Aa]ction(s|s\$|\$)$`;
|
|
@@ -877,7 +843,6 @@ const DEFAULT_VALID_POST_COMPLETION_OPERATORS = [
|
|
|
877
843
|
"throwIfEmpty",
|
|
878
844
|
"toArray"
|
|
879
845
|
];
|
|
880
|
-
|
|
881
846
|
//#endregion
|
|
882
847
|
//#region src/rules/no-cyclic-action.ts
|
|
883
848
|
const noCyclicActionRule = ruleCreator({
|
|
@@ -946,7 +911,6 @@ The property can be specified as a regular expression string and is used to iden
|
|
|
946
911
|
};
|
|
947
912
|
}
|
|
948
913
|
});
|
|
949
|
-
|
|
950
914
|
//#endregion
|
|
951
915
|
//#region src/rules/no-explicit-generics.ts
|
|
952
916
|
const noExplicitGenericsRule = ruleCreator({
|
|
@@ -999,7 +963,6 @@ const noExplicitGenericsRule = ruleCreator({
|
|
|
999
963
|
};
|
|
1000
964
|
}
|
|
1001
965
|
});
|
|
1002
|
-
|
|
1003
966
|
//#endregion
|
|
1004
967
|
//#region src/rules/no-exposed-subjects.ts
|
|
1005
968
|
const defaultAllowedTypesRegExp = /^EventEmitter$/;
|
|
@@ -1027,12 +990,15 @@ const noExposedSubjectsRule = ruleCreator({
|
|
|
1027
990
|
name: "no-exposed-subjects",
|
|
1028
991
|
create: (context) => {
|
|
1029
992
|
const [{ allowProtected }] = context.options;
|
|
1030
|
-
const { couldBeSubject, couldBeType } = getTypeServices(context);
|
|
993
|
+
const { couldBeSubject, couldReturnSubject, couldBeType, couldReturnType } = getTypeServices(context);
|
|
1031
994
|
const messageId = allowProtected ? "forbiddenAllowProtected" : "forbidden";
|
|
1032
995
|
const accessibilityRexExp = allowProtected ? /^(private|protected)$/ : /^private$/;
|
|
1033
996
|
function isSubject(node) {
|
|
1034
997
|
return couldBeSubject(node) && !couldBeType(node, defaultAllowedTypesRegExp);
|
|
1035
998
|
}
|
|
999
|
+
function isReturningSubject(node) {
|
|
1000
|
+
return couldReturnSubject(node) && !couldReturnType(node, defaultAllowedTypesRegExp);
|
|
1001
|
+
}
|
|
1036
1002
|
return {
|
|
1037
1003
|
[`PropertyDefinition[accessibility!=${accessibilityRexExp}]`]: (node) => {
|
|
1038
1004
|
if (isSubject(node)) {
|
|
@@ -1071,11 +1037,9 @@ const noExposedSubjectsRule = ruleCreator({
|
|
|
1071
1037
|
}
|
|
1072
1038
|
},
|
|
1073
1039
|
[`MethodDefinition[accessibility!=${accessibilityRexExp}][kind='method']`]: (node) => {
|
|
1074
|
-
const
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
if (!typeAnnotation) return;
|
|
1078
|
-
if (isSubject(typeAnnotation)) {
|
|
1040
|
+
const functionExpression = node.value;
|
|
1041
|
+
const typeAnnotation = functionExpression.returnType?.typeAnnotation;
|
|
1042
|
+
if (typeAnnotation && isSubject(typeAnnotation) || isReturningSubject(functionExpression)) {
|
|
1079
1043
|
const key = node.key;
|
|
1080
1044
|
context.report({
|
|
1081
1045
|
messageId,
|
|
@@ -1087,7 +1051,6 @@ const noExposedSubjectsRule = ruleCreator({
|
|
|
1087
1051
|
};
|
|
1088
1052
|
}
|
|
1089
1053
|
});
|
|
1090
|
-
|
|
1091
1054
|
//#endregion
|
|
1092
1055
|
//#region src/rules/no-finnish.ts
|
|
1093
1056
|
const noFinnishRule = ruleCreator({
|
|
@@ -1107,7 +1070,7 @@ const noFinnishRule = ruleCreator({
|
|
|
1107
1070
|
function checkNode(nameNode, typeNode) {
|
|
1108
1071
|
if (couldBeObservable(typeNode ?? nameNode) || couldReturnObservable(typeNode ?? nameNode)) {
|
|
1109
1072
|
const tsNode = esTreeNodeToTSNodeMap.get(nameNode);
|
|
1110
|
-
if (
|
|
1073
|
+
if (/\$+$/.test(tsNode.getText())) context.report({
|
|
1111
1074
|
loc: getLoc(tsNode),
|
|
1112
1075
|
messageId: "forbidden"
|
|
1113
1076
|
});
|
|
@@ -1165,11 +1128,6 @@ const noFinnishRule = ruleCreator({
|
|
|
1165
1128
|
};
|
|
1166
1129
|
}
|
|
1167
1130
|
});
|
|
1168
|
-
|
|
1169
|
-
//#endregion
|
|
1170
|
-
//#region src/rules/no-floating-observables.ts
|
|
1171
|
-
const messageBase = "Observables must be subscribed to, returned, converted to a promise and awaited, or be explicitly marked as ignored with the `void` operator.";
|
|
1172
|
-
const messageBaseNoVoid = "Observables must be subscribed to, returned, or converted to a promise and awaited.";
|
|
1173
1131
|
const noFloatingObservablesRule = ruleCreator({
|
|
1174
1132
|
meta: {
|
|
1175
1133
|
docs: {
|
|
@@ -1178,8 +1136,8 @@ const noFloatingObservablesRule = ruleCreator({
|
|
|
1178
1136
|
requiresTypeChecking: true
|
|
1179
1137
|
},
|
|
1180
1138
|
messages: {
|
|
1181
|
-
forbidden:
|
|
1182
|
-
forbiddenNoVoid:
|
|
1139
|
+
forbidden: "Observables must be subscribed to, returned, converted to a promise and awaited, or be explicitly marked as ignored with the `void` operator.",
|
|
1140
|
+
forbiddenNoVoid: "Observables must be subscribed to, returned, or converted to a promise and awaited."
|
|
1183
1141
|
},
|
|
1184
1142
|
schema: [{
|
|
1185
1143
|
properties: { ignoreVoid: {
|
|
@@ -1221,21 +1179,18 @@ const noFloatingObservablesRule = ruleCreator({
|
|
|
1221
1179
|
checkNode(node.expression);
|
|
1222
1180
|
},
|
|
1223
1181
|
"ExpressionStatement > SequenceExpression": (node) => {
|
|
1224
|
-
node.expressions
|
|
1225
|
-
if (isCallExpression(expression)) checkNode(expression);
|
|
1226
|
-
});
|
|
1182
|
+
for (const expression of node.expressions) if (isCallExpression(expression)) checkNode(expression);
|
|
1227
1183
|
},
|
|
1228
1184
|
"ExpressionStatement > ArrayExpression": (node) => {
|
|
1229
|
-
node.elements
|
|
1230
|
-
if (!expression)
|
|
1185
|
+
for (const expression of node.elements) {
|
|
1186
|
+
if (!expression) continue;
|
|
1231
1187
|
if (isCallExpression(expression)) checkNode(expression);
|
|
1232
1188
|
else if (isUnaryExpression(expression)) checkVoid(expression);
|
|
1233
|
-
}
|
|
1189
|
+
}
|
|
1234
1190
|
}
|
|
1235
1191
|
};
|
|
1236
1192
|
}
|
|
1237
1193
|
});
|
|
1238
|
-
|
|
1239
1194
|
//#endregion
|
|
1240
1195
|
//#region src/rules/no-ignored-default-value.ts
|
|
1241
1196
|
const noIgnoredDefaultValueRule = ruleCreator({
|
|
@@ -1320,7 +1275,6 @@ const noIgnoredDefaultValueRule = ruleCreator({
|
|
|
1320
1275
|
};
|
|
1321
1276
|
}
|
|
1322
1277
|
});
|
|
1323
|
-
|
|
1324
1278
|
//#endregion
|
|
1325
1279
|
//#region src/rules/no-ignored-error.ts
|
|
1326
1280
|
const noIgnoredErrorRule = ruleCreator({
|
|
@@ -1366,7 +1320,6 @@ const noIgnoredErrorRule = ruleCreator({
|
|
|
1366
1320
|
} };
|
|
1367
1321
|
}
|
|
1368
1322
|
});
|
|
1369
|
-
|
|
1370
1323
|
//#endregion
|
|
1371
1324
|
//#region src/rules/no-ignored-notifier.ts
|
|
1372
1325
|
const noIgnoredNotifierRule = ruleCreator({
|
|
@@ -1425,7 +1378,6 @@ const noIgnoredNotifierRule = ruleCreator({
|
|
|
1425
1378
|
};
|
|
1426
1379
|
}
|
|
1427
1380
|
});
|
|
1428
|
-
|
|
1429
1381
|
//#endregion
|
|
1430
1382
|
//#region src/rules/no-ignored-replay-buffer.ts
|
|
1431
1383
|
const noIgnoredReplayBufferRule = ruleCreator({
|
|
@@ -1476,7 +1428,6 @@ const noIgnoredReplayBufferRule = ruleCreator({
|
|
|
1476
1428
|
};
|
|
1477
1429
|
}
|
|
1478
1430
|
});
|
|
1479
|
-
|
|
1480
1431
|
//#endregion
|
|
1481
1432
|
//#region src/rules/no-ignored-subscribe.ts
|
|
1482
1433
|
const noIgnoredSubscribeRule = ruleCreator({
|
|
@@ -1501,7 +1452,6 @@ const noIgnoredSubscribeRule = ruleCreator({
|
|
|
1501
1452
|
} };
|
|
1502
1453
|
}
|
|
1503
1454
|
});
|
|
1504
|
-
|
|
1505
1455
|
//#endregion
|
|
1506
1456
|
//#region src/rules/no-ignored-subscription.ts
|
|
1507
1457
|
const noIgnoredSubscriptionRule = ruleCreator({
|
|
@@ -1567,7 +1517,6 @@ The \`postCompleters\` property is an array containing the names of the operator
|
|
|
1567
1517
|
} };
|
|
1568
1518
|
}
|
|
1569
1519
|
});
|
|
1570
|
-
|
|
1571
1520
|
//#endregion
|
|
1572
1521
|
//#region src/rules/no-ignored-takewhile-value.ts
|
|
1573
1522
|
const noIgnoredTakewhileValueRule = ruleCreator({
|
|
@@ -1608,7 +1557,6 @@ const noIgnoredTakewhileValueRule = ruleCreator({
|
|
|
1608
1557
|
};
|
|
1609
1558
|
}
|
|
1610
1559
|
});
|
|
1611
|
-
|
|
1612
1560
|
//#endregion
|
|
1613
1561
|
//#region src/rules/no-implicit-any-catch.ts
|
|
1614
1562
|
function isParenthesised(sourceCode, node) {
|
|
@@ -1751,7 +1699,6 @@ const noImplicitAnyCatchRule = ruleCreator({
|
|
|
1751
1699
|
};
|
|
1752
1700
|
}
|
|
1753
1701
|
});
|
|
1754
|
-
|
|
1755
1702
|
//#endregion
|
|
1756
1703
|
//#region src/rules/no-index.ts
|
|
1757
1704
|
const noIndexRule = ruleCreator({
|
|
@@ -1774,7 +1721,6 @@ const noIndexRule = ruleCreator({
|
|
|
1774
1721
|
} };
|
|
1775
1722
|
}
|
|
1776
1723
|
});
|
|
1777
|
-
|
|
1778
1724
|
//#endregion
|
|
1779
1725
|
//#region src/rules/no-internal.ts
|
|
1780
1726
|
const noInternalRule = ruleCreator({
|
|
@@ -1829,7 +1775,6 @@ const noInternalRule = ruleCreator({
|
|
|
1829
1775
|
} };
|
|
1830
1776
|
}
|
|
1831
1777
|
});
|
|
1832
|
-
|
|
1833
1778
|
//#endregion
|
|
1834
1779
|
//#region src/rules/no-misused-observables.ts
|
|
1835
1780
|
function parseChecksVoidReturn(checksVoidReturn) {
|
|
@@ -2093,7 +2038,7 @@ function getPropertyContextualType(checker, tsNode) {
|
|
|
2093
2038
|
if (!ts.isObjectLiteralExpression(obj)) return;
|
|
2094
2039
|
const objType = checker.getContextualType(obj);
|
|
2095
2040
|
if (objType == null) return;
|
|
2096
|
-
const propertySymbol = tsutils.unionConstituents(objType).map((t) => checker.getPropertyOfType(t, tsNode.name.getText())).find(
|
|
2041
|
+
const propertySymbol = tsutils.unionConstituents(objType).map((t) => checker.getPropertyOfType(t, tsNode.name.getText())).find(Boolean);
|
|
2097
2042
|
if (propertySymbol == null) return;
|
|
2098
2043
|
return checker.getTypeOfSymbolAtLocation(propertySymbol, tsNode.name);
|
|
2099
2044
|
} else return;
|
|
@@ -2150,7 +2095,6 @@ function isPossiblyFunctionType(node) {
|
|
|
2150
2095
|
case AST_NODE_TYPES.TSVoidKeyword: return false;
|
|
2151
2096
|
}
|
|
2152
2097
|
}
|
|
2153
|
-
|
|
2154
2098
|
//#endregion
|
|
2155
2099
|
//#region src/rules/no-nested-subscribe.ts
|
|
2156
2100
|
const noNestedSubscribeRule = ruleCreator({
|
|
@@ -2186,7 +2130,6 @@ const noNestedSubscribeRule = ruleCreator({
|
|
|
2186
2130
|
} };
|
|
2187
2131
|
}
|
|
2188
2132
|
});
|
|
2189
|
-
|
|
2190
2133
|
//#endregion
|
|
2191
2134
|
//#region src/rules/no-redundant-notify.ts
|
|
2192
2135
|
const noRedundantNotifyRule = ruleCreator({
|
|
@@ -2240,7 +2183,6 @@ function isExpressionObserver(expressionStatement, couldBeType) {
|
|
|
2240
2183
|
const { object } = callExpression.callee;
|
|
2241
2184
|
return couldBeType(object, /^(Subject|Subscriber)$/);
|
|
2242
2185
|
}
|
|
2243
|
-
|
|
2244
2186
|
//#endregion
|
|
2245
2187
|
//#region src/rules/no-sharereplay.ts
|
|
2246
2188
|
const noSharereplayRule = ruleCreator({
|
|
@@ -2276,7 +2218,6 @@ const noSharereplayRule = ruleCreator({
|
|
|
2276
2218
|
} };
|
|
2277
2219
|
}
|
|
2278
2220
|
});
|
|
2279
|
-
|
|
2280
2221
|
//#endregion
|
|
2281
2222
|
//#region src/rules/no-sharereplay-before-takeuntil.ts
|
|
2282
2223
|
const noSharereplayBeforeTakeuntilRule = ruleCreator({
|
|
@@ -2332,7 +2273,6 @@ const noSharereplayBeforeTakeuntilRule = ruleCreator({
|
|
|
2332
2273
|
};
|
|
2333
2274
|
}
|
|
2334
2275
|
});
|
|
2335
|
-
|
|
2336
2276
|
//#endregion
|
|
2337
2277
|
//#region src/rules/no-subclass.ts
|
|
2338
2278
|
const noSubclassRule = ruleCreator({
|
|
@@ -2366,7 +2306,6 @@ const noSubclassRule = ruleCreator({
|
|
|
2366
2306
|
} };
|
|
2367
2307
|
}
|
|
2368
2308
|
});
|
|
2369
|
-
|
|
2370
2309
|
//#endregion
|
|
2371
2310
|
//#region src/rules/no-subject-unsubscribe.ts
|
|
2372
2311
|
const noSubjectUnsubscribeRule = ruleCreator({
|
|
@@ -2403,7 +2342,6 @@ const noSubjectUnsubscribeRule = ruleCreator({
|
|
|
2403
2342
|
};
|
|
2404
2343
|
}
|
|
2405
2344
|
});
|
|
2406
|
-
|
|
2407
2345
|
//#endregion
|
|
2408
2346
|
//#region src/rules/no-subject-value.ts
|
|
2409
2347
|
const noSubjectValueRule = ruleCreator({
|
|
@@ -2429,7 +2367,6 @@ const noSubjectValueRule = ruleCreator({
|
|
|
2429
2367
|
} };
|
|
2430
2368
|
}
|
|
2431
2369
|
});
|
|
2432
|
-
|
|
2433
2370
|
//#endregion
|
|
2434
2371
|
//#region src/rules/no-subscribe-handlers.ts
|
|
2435
2372
|
const noSubscribeHandlersRule = ruleCreator({
|
|
@@ -2454,7 +2391,6 @@ const noSubscribeHandlersRule = ruleCreator({
|
|
|
2454
2391
|
} };
|
|
2455
2392
|
}
|
|
2456
2393
|
});
|
|
2457
|
-
|
|
2458
2394
|
//#endregion
|
|
2459
2395
|
//#region src/rules/no-subscribe-in-pipe.ts
|
|
2460
2396
|
const noSubscribeInPipeRule = ruleCreator({
|
|
@@ -2488,7 +2424,6 @@ const noSubscribeInPipeRule = ruleCreator({
|
|
|
2488
2424
|
} };
|
|
2489
2425
|
}
|
|
2490
2426
|
});
|
|
2491
|
-
|
|
2492
2427
|
//#endregion
|
|
2493
2428
|
//#region src/rules/no-topromise.ts
|
|
2494
2429
|
const noTopromiseRule = ruleCreator({
|
|
@@ -2528,13 +2463,13 @@ const noTopromiseRule = ruleCreator({
|
|
|
2528
2463
|
const existingSpecifier = specifiers.find((node) => (isIdentifier(node.imported) ? node.imported.name : node.imported.value) === functionName);
|
|
2529
2464
|
if (existingSpecifier) functionName = existingSpecifier.local.name;
|
|
2530
2465
|
else {
|
|
2531
|
-
const lastSpecifier = specifiers
|
|
2466
|
+
const lastSpecifier = specifiers.at(-1);
|
|
2532
2467
|
yield fixer.insertTextAfter(lastSpecifier, `, ${functionName}`);
|
|
2533
2468
|
}
|
|
2534
2469
|
} else if (importDeclarations.length) {
|
|
2535
|
-
const lastImport = importDeclarations
|
|
2470
|
+
const lastImport = importDeclarations.at(-1);
|
|
2536
2471
|
const quote = getQuote(lastImport.source.raw) ?? "\"";
|
|
2537
|
-
yield fixer.insertTextAfter(
|
|
2472
|
+
yield fixer.insertTextAfter(lastImport, `\nimport { ${functionName} } from ${quote}rxjs${quote};`);
|
|
2538
2473
|
} else {
|
|
2539
2474
|
console.warn("No import declarations found. Unable to suggest a fix.");
|
|
2540
2475
|
return;
|
|
@@ -2569,7 +2504,6 @@ const noTopromiseRule = ruleCreator({
|
|
|
2569
2504
|
} };
|
|
2570
2505
|
}
|
|
2571
2506
|
});
|
|
2572
|
-
|
|
2573
2507
|
//#endregion
|
|
2574
2508
|
//#region src/rules/no-unbound-methods.ts
|
|
2575
2509
|
const noUnboundMethodsRule = ruleCreator({
|
|
@@ -2598,11 +2532,11 @@ const noUnboundMethodsRule = ruleCreator({
|
|
|
2598
2532
|
const nodeMap = /* @__PURE__ */ new WeakMap();
|
|
2599
2533
|
const [{ allowTypes = [] }] = context.options;
|
|
2600
2534
|
function mapArguments(node) {
|
|
2601
|
-
node.arguments.filter(isMemberExpression)
|
|
2535
|
+
for (const arg of node.arguments.filter(isMemberExpression)) {
|
|
2602
2536
|
const argType = getTypeAtLocation(arg);
|
|
2603
|
-
if (allowTypes.some((t) => couldBeType(argType, t)))
|
|
2537
|
+
if (allowTypes.some((t) => couldBeType(argType, t))) continue;
|
|
2604
2538
|
if (argType.getCallSignatures().length > 0) nodeMap.set(arg);
|
|
2605
|
-
}
|
|
2539
|
+
}
|
|
2606
2540
|
}
|
|
2607
2541
|
function isObservableOrSubscription(node, action) {
|
|
2608
2542
|
if (!isMemberExpression(node.callee)) return;
|
|
@@ -2611,7 +2545,7 @@ const noUnboundMethodsRule = ruleCreator({
|
|
|
2611
2545
|
return {
|
|
2612
2546
|
"CallExpression[callee.property.name='pipe']": (node) => {
|
|
2613
2547
|
isObservableOrSubscription(node, ({ arguments: args }) => {
|
|
2614
|
-
args.filter(isCallExpression)
|
|
2548
|
+
for (const node of args.filter(isCallExpression)) mapArguments(node);
|
|
2615
2549
|
});
|
|
2616
2550
|
},
|
|
2617
2551
|
"CallExpression[callee.property.name=/^(add|subscribe)$/]": (node) => {
|
|
@@ -2634,7 +2568,6 @@ const noUnboundMethodsRule = ruleCreator({
|
|
|
2634
2568
|
};
|
|
2635
2569
|
}
|
|
2636
2570
|
});
|
|
2637
|
-
|
|
2638
2571
|
//#endregion
|
|
2639
2572
|
//#region src/rules/no-unnecessary-collection.ts
|
|
2640
2573
|
const noUnnecessaryCollectionRule = ruleCreator({
|
|
@@ -2704,7 +2637,6 @@ const noUnnecessaryCollectionRule = ruleCreator({
|
|
|
2704
2637
|
return callExpressionVisitors;
|
|
2705
2638
|
}
|
|
2706
2639
|
});
|
|
2707
|
-
|
|
2708
2640
|
//#endregion
|
|
2709
2641
|
//#region src/rules/no-unsafe-catch.ts
|
|
2710
2642
|
const noUnsafeCatchRule = ruleCreator({
|
|
@@ -2728,7 +2660,7 @@ The property can be specified as a regular expression string and is used to iden
|
|
|
2728
2660
|
},
|
|
2729
2661
|
name: "no-unsafe-catch",
|
|
2730
2662
|
create: (context) => {
|
|
2731
|
-
const invalidOperatorsRegExp = /^
|
|
2663
|
+
const invalidOperatorsRegExp = /^catchError$/;
|
|
2732
2664
|
const [{ observable = defaultObservable }] = context.options;
|
|
2733
2665
|
const observableRegExp = new RegExp(observable);
|
|
2734
2666
|
const { couldBeObservable } = getTypeServices(context);
|
|
@@ -2738,13 +2670,9 @@ The property can be specified as a regular expression string and is used to iden
|
|
|
2738
2670
|
}
|
|
2739
2671
|
function checkNode(node) {
|
|
2740
2672
|
if (!node.arguments || !couldBeObservable(node)) return;
|
|
2741
|
-
node.arguments.
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
messageId: "forbidden",
|
|
2745
|
-
node: arg.callee
|
|
2746
|
-
});
|
|
2747
|
-
}
|
|
2673
|
+
for (const arg of node.arguments) if (isCallExpression(arg) && isIdentifier(arg.callee) && invalidOperatorsRegExp.test(arg.callee.name) && isUnsafe(arg.arguments)) context.report({
|
|
2674
|
+
messageId: "forbidden",
|
|
2675
|
+
node: arg.callee
|
|
2748
2676
|
});
|
|
2749
2677
|
}
|
|
2750
2678
|
return {
|
|
@@ -2753,7 +2681,6 @@ The property can be specified as a regular expression string and is used to iden
|
|
|
2753
2681
|
};
|
|
2754
2682
|
}
|
|
2755
2683
|
});
|
|
2756
|
-
|
|
2757
2684
|
//#endregion
|
|
2758
2685
|
//#region src/rules/no-unsafe-first.ts
|
|
2759
2686
|
const noUnsafeFirstRule = ruleCreator({
|
|
@@ -2777,20 +2704,16 @@ The property can be specified as a regular expression string and is used to iden
|
|
|
2777
2704
|
},
|
|
2778
2705
|
name: "no-unsafe-first",
|
|
2779
2706
|
create: (context) => {
|
|
2780
|
-
const invalidOperatorsRegExp = /^(take|first)$/;
|
|
2707
|
+
const invalidOperatorsRegExp = /^(?:take|first)$/;
|
|
2781
2708
|
const [{ observable = defaultObservable }] = context.options;
|
|
2782
2709
|
const observableRegExp = new RegExp(observable);
|
|
2783
2710
|
const { couldBeObservable } = getTypeServices(context);
|
|
2784
2711
|
const nodes = [];
|
|
2785
2712
|
function checkNode(node) {
|
|
2786
2713
|
if (!node.arguments || !couldBeObservable(node)) return;
|
|
2787
|
-
node.arguments
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
messageId: "forbidden",
|
|
2791
|
-
node: arg.callee
|
|
2792
|
-
});
|
|
2793
|
-
}
|
|
2714
|
+
for (const arg of node.arguments) if (isCallExpression(arg) && isIdentifier(arg.callee) && invalidOperatorsRegExp.test(arg.callee.name)) context.report({
|
|
2715
|
+
messageId: "forbidden",
|
|
2716
|
+
node: arg.callee
|
|
2794
2717
|
});
|
|
2795
2718
|
}
|
|
2796
2719
|
return {
|
|
@@ -2809,7 +2732,6 @@ The property can be specified as a regular expression string and is used to iden
|
|
|
2809
2732
|
};
|
|
2810
2733
|
}
|
|
2811
2734
|
});
|
|
2812
|
-
|
|
2813
2735
|
//#endregion
|
|
2814
2736
|
//#region src/rules/no-unsafe-subject-next.ts
|
|
2815
2737
|
const noUnsafeSubjectNext = ruleCreator({
|
|
@@ -2845,19 +2767,6 @@ const noUnsafeSubjectNext = ruleCreator({
|
|
|
2845
2767
|
} };
|
|
2846
2768
|
}
|
|
2847
2769
|
});
|
|
2848
|
-
|
|
2849
|
-
//#endregion
|
|
2850
|
-
//#region src/rules/no-unsafe-switchmap.ts
|
|
2851
|
-
const DEFAULT_DISALLOW = [
|
|
2852
|
-
"add",
|
|
2853
|
-
"create",
|
|
2854
|
-
"delete",
|
|
2855
|
-
"post",
|
|
2856
|
-
"put",
|
|
2857
|
-
"remove",
|
|
2858
|
-
"set",
|
|
2859
|
-
"update"
|
|
2860
|
-
];
|
|
2861
2770
|
const noUnsafeSwitchmapRule = ruleCreator({
|
|
2862
2771
|
meta: {
|
|
2863
2772
|
docs: {
|
|
@@ -2903,14 +2812,23 @@ The \`observable\` property is used to identify the action observables from whic
|
|
|
2903
2812
|
}],
|
|
2904
2813
|
type: "problem",
|
|
2905
2814
|
defaultOptions: [{
|
|
2906
|
-
disallow:
|
|
2815
|
+
disallow: [
|
|
2816
|
+
"add",
|
|
2817
|
+
"create",
|
|
2818
|
+
"delete",
|
|
2819
|
+
"post",
|
|
2820
|
+
"put",
|
|
2821
|
+
"remove",
|
|
2822
|
+
"set",
|
|
2823
|
+
"update"
|
|
2824
|
+
],
|
|
2907
2825
|
observable: defaultObservable
|
|
2908
2826
|
}]
|
|
2909
2827
|
},
|
|
2910
2828
|
name: "no-unsafe-switchmap",
|
|
2911
2829
|
create: (context) => {
|
|
2912
|
-
let allowRegExp
|
|
2913
|
-
let disallowRegExp
|
|
2830
|
+
let allowRegExp;
|
|
2831
|
+
let disallowRegExp;
|
|
2914
2832
|
const [config] = context.options;
|
|
2915
2833
|
if (config.allow) allowRegExp = createRegExpForWords(config.allow ?? []);
|
|
2916
2834
|
else disallowRegExp = createRegExpForWords(config.disallow ?? []);
|
|
@@ -2933,11 +2851,9 @@ The \`observable\` property is used to identify the action observables from whic
|
|
|
2933
2851
|
if (isCallExpression(arg) && isIdentifier(arg.callee) && arg.callee.name === "ofType") return shouldDisallow(arg.arguments);
|
|
2934
2852
|
return false;
|
|
2935
2853
|
})) return;
|
|
2936
|
-
node.arguments
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
node: arg.callee
|
|
2940
|
-
});
|
|
2854
|
+
for (const arg of node.arguments) if (isCallExpression(arg) && isIdentifier(arg.callee) && arg.callee.name === "switchMap") context.report({
|
|
2855
|
+
messageId: "forbidden",
|
|
2856
|
+
node: arg.callee
|
|
2941
2857
|
});
|
|
2942
2858
|
}
|
|
2943
2859
|
return {
|
|
@@ -2946,7 +2862,6 @@ The \`observable\` property is used to identify the action observables from whic
|
|
|
2946
2862
|
};
|
|
2947
2863
|
}
|
|
2948
2864
|
});
|
|
2949
|
-
|
|
2950
2865
|
//#endregion
|
|
2951
2866
|
//#region src/rules/no-unsafe-takeuntil.ts
|
|
2952
2867
|
const noUnsafeTakeuntilRule = ruleCreator({
|
|
@@ -2999,7 +2914,6 @@ The \`allow\` property is an array containing the names of the operators that ar
|
|
|
2999
2914
|
};
|
|
3000
2915
|
}
|
|
3001
2916
|
});
|
|
3002
|
-
|
|
3003
2917
|
//#endregion
|
|
3004
2918
|
//#region src/rules/prefer-observer.ts
|
|
3005
2919
|
const preferObserverRule = ruleCreator({
|
|
@@ -3043,9 +2957,9 @@ const preferObserverRule = ruleCreator({
|
|
|
3043
2957
|
if (errorArgText && errorArgText !== "undefined" && errorArgText !== "null") observer += ` error: ${errorArgText}${isValidArgText(completeArgText) ? "," : ""}`;
|
|
3044
2958
|
if (completeArgText && completeArgText !== "undefined" && completeArgText !== "null") observer += ` complete: ${completeArgText}`;
|
|
3045
2959
|
observer += " }";
|
|
3046
|
-
yield fixer.replaceText(
|
|
3047
|
-
const [, start] =
|
|
3048
|
-
const [, end] =
|
|
2960
|
+
yield fixer.replaceText(args[0], observer);
|
|
2961
|
+
const [, start] = args[0].range;
|
|
2962
|
+
const [, end] = args.at(-1).range;
|
|
3049
2963
|
yield fixer.removeRange([start, end]);
|
|
3050
2964
|
}
|
|
3051
2965
|
if (args.length > 1) context.report({
|
|
@@ -3083,7 +2997,6 @@ const preferObserverRule = ruleCreator({
|
|
|
3083
2997
|
function isValidArgText(argText) {
|
|
3084
2998
|
return argText && argText !== "undefined" && argText !== "null";
|
|
3085
2999
|
}
|
|
3086
|
-
|
|
3087
3000
|
//#endregion
|
|
3088
3001
|
//#region src/rules/prefer-root-operators.ts
|
|
3089
3002
|
const RENAMED_OPERATORS = {
|
|
@@ -3094,7 +3007,7 @@ const RENAMED_OPERATORS = {
|
|
|
3094
3007
|
race: "raceWith",
|
|
3095
3008
|
zip: "zipWith"
|
|
3096
3009
|
};
|
|
3097
|
-
const DEPRECATED_OPERATORS = ["partition"];
|
|
3010
|
+
const DEPRECATED_OPERATORS = new Set(["partition"]);
|
|
3098
3011
|
const preferRootOperatorsRule = ruleCreator({
|
|
3099
3012
|
meta: {
|
|
3100
3013
|
docs: {
|
|
@@ -3125,7 +3038,7 @@ const preferRootOperatorsRule = ruleCreator({
|
|
|
3125
3038
|
if (/^['"]rxjs\/operators/.test(rawLocation)) return `${quote}rxjs${quote}`;
|
|
3126
3039
|
}
|
|
3127
3040
|
function hasDeprecatedOperators(specifiers) {
|
|
3128
|
-
return !!specifiers?.some((s) => DEPRECATED_OPERATORS.
|
|
3041
|
+
return !!specifiers?.some((s) => DEPRECATED_OPERATORS.has(getName(getOperatorNode(s))));
|
|
3129
3042
|
}
|
|
3130
3043
|
function getName(node) {
|
|
3131
3044
|
return isIdentifier(node) ? node.name : node.value;
|
|
@@ -3207,7 +3120,6 @@ const preferRootOperatorsRule = ruleCreator({
|
|
|
3207
3120
|
};
|
|
3208
3121
|
}
|
|
3209
3122
|
});
|
|
3210
|
-
|
|
3211
3123
|
//#endregion
|
|
3212
3124
|
//#region src/rules/suffix-subjects.ts
|
|
3213
3125
|
const baseShouldHaveSuffix = "Subject identifiers must end with \"{{suffix}}\".";
|
|
@@ -3266,11 +3178,9 @@ const suffixSubjectsRule = ruleCreator({
|
|
|
3266
3178
|
const { couldBeType } = getTypeServices(context);
|
|
3267
3179
|
const [config] = context.options;
|
|
3268
3180
|
const types = [];
|
|
3269
|
-
if (config.types) Object.entries(config.types).
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
validate
|
|
3273
|
-
});
|
|
3181
|
+
if (config.types) for (const [key, validate] of Object.entries(config.types)) types.push({
|
|
3182
|
+
regExp: new RegExp(key),
|
|
3183
|
+
validate
|
|
3274
3184
|
});
|
|
3275
3185
|
const { suffix = "Subject" } = config;
|
|
3276
3186
|
const suffixRegex = new RegExp(String.raw`${escapeRegExp(suffix)}\$?$`, "i");
|
|
@@ -3334,9 +3244,7 @@ const suffixSubjectsRule = ruleCreator({
|
|
|
3334
3244
|
"TSAbstractMethodDefinition[computed=false]": (node) => {
|
|
3335
3245
|
if (node.override) return;
|
|
3336
3246
|
if (config.properties && (node.kind === "get" || node.kind === "set")) checkNode(node.key, node);
|
|
3337
|
-
if (config.parameters) node.value.params
|
|
3338
|
-
checkNode(param);
|
|
3339
|
-
});
|
|
3247
|
+
if (config.parameters) for (const param of node.value.params) checkNode(param);
|
|
3340
3248
|
},
|
|
3341
3249
|
"ObjectExpression > Property[computed=false] > Identifier": (node) => {
|
|
3342
3250
|
if (!config.objects) return;
|
|
@@ -3378,7 +3286,6 @@ const suffixSubjectsRule = ruleCreator({
|
|
|
3378
3286
|
};
|
|
3379
3287
|
}
|
|
3380
3288
|
});
|
|
3381
|
-
|
|
3382
3289
|
//#endregion
|
|
3383
3290
|
//#region src/rules/throw-error.ts
|
|
3384
3291
|
const throwErrorRule = ruleCreator({
|
|
@@ -3468,62 +3375,58 @@ const throwErrorRule = ruleCreator({
|
|
|
3468
3375
|
};
|
|
3469
3376
|
}
|
|
3470
3377
|
});
|
|
3471
|
-
|
|
3472
|
-
//#endregion
|
|
3473
|
-
//#region src/index.ts
|
|
3474
|
-
const allRules = {
|
|
3475
|
-
"ban-observables": banObservablesRule,
|
|
3476
|
-
"ban-operators": banOperatorsRule,
|
|
3477
|
-
"finnish": finnishRule,
|
|
3478
|
-
"just": justRule,
|
|
3479
|
-
"no-async-subscribe": noAsyncSubscribeRule,
|
|
3480
|
-
"no-connectable": noConnectableRule,
|
|
3481
|
-
"no-create": noCreateRule,
|
|
3482
|
-
"no-cyclic-action": noCyclicActionRule,
|
|
3483
|
-
"no-explicit-generics": noExplicitGenericsRule,
|
|
3484
|
-
"no-exposed-subjects": noExposedSubjectsRule,
|
|
3485
|
-
"no-finnish": noFinnishRule,
|
|
3486
|
-
"no-floating-observables": noFloatingObservablesRule,
|
|
3487
|
-
"no-ignored-default-value": noIgnoredDefaultValueRule,
|
|
3488
|
-
"no-ignored-error": noIgnoredErrorRule,
|
|
3489
|
-
"no-ignored-notifier": noIgnoredNotifierRule,
|
|
3490
|
-
"no-ignored-replay-buffer": noIgnoredReplayBufferRule,
|
|
3491
|
-
"no-ignored-subscribe": noIgnoredSubscribeRule,
|
|
3492
|
-
"no-ignored-subscription": noIgnoredSubscriptionRule,
|
|
3493
|
-
"no-ignored-takewhile-value": noIgnoredTakewhileValueRule,
|
|
3494
|
-
"no-implicit-any-catch": noImplicitAnyCatchRule,
|
|
3495
|
-
"no-index": noIndexRule,
|
|
3496
|
-
"no-internal": noInternalRule,
|
|
3497
|
-
"no-misused-observables": noMisusedObservablesRule,
|
|
3498
|
-
"no-nested-subscribe": noNestedSubscribeRule,
|
|
3499
|
-
"no-redundant-notify": noRedundantNotifyRule,
|
|
3500
|
-
"no-sharereplay": noSharereplayRule,
|
|
3501
|
-
"no-sharereplay-before-takeuntil": noSharereplayBeforeTakeuntilRule,
|
|
3502
|
-
"no-subclass": noSubclassRule,
|
|
3503
|
-
"no-subject-unsubscribe": noSubjectUnsubscribeRule,
|
|
3504
|
-
"no-subject-value": noSubjectValueRule,
|
|
3505
|
-
"no-subscribe-handlers": noSubscribeHandlersRule,
|
|
3506
|
-
"no-subscribe-in-pipe": noSubscribeInPipeRule,
|
|
3507
|
-
"no-topromise": noTopromiseRule,
|
|
3508
|
-
"no-unbound-methods": noUnboundMethodsRule,
|
|
3509
|
-
"no-unnecessary-collection": noUnnecessaryCollectionRule,
|
|
3510
|
-
"no-unsafe-catch": noUnsafeCatchRule,
|
|
3511
|
-
"no-unsafe-first": noUnsafeFirstRule,
|
|
3512
|
-
"no-unsafe-subject-next": noUnsafeSubjectNext,
|
|
3513
|
-
"no-unsafe-switchmap": noUnsafeSwitchmapRule,
|
|
3514
|
-
"no-unsafe-takeuntil": noUnsafeTakeuntilRule,
|
|
3515
|
-
"prefer-observer": preferObserverRule,
|
|
3516
|
-
"prefer-root-operators": preferRootOperatorsRule,
|
|
3517
|
-
"suffix-subjects": suffixSubjectsRule,
|
|
3518
|
-
"throw-error": throwErrorRule
|
|
3519
|
-
};
|
|
3520
3378
|
const plugin = {
|
|
3521
3379
|
meta: {
|
|
3522
3380
|
name,
|
|
3523
3381
|
version,
|
|
3524
3382
|
namespace: "rxjs-x"
|
|
3525
3383
|
},
|
|
3526
|
-
rules:
|
|
3384
|
+
rules: {
|
|
3385
|
+
"ban-observables": banObservablesRule,
|
|
3386
|
+
"ban-operators": banOperatorsRule,
|
|
3387
|
+
"finnish": finnishRule,
|
|
3388
|
+
"just": justRule,
|
|
3389
|
+
"no-async-subscribe": noAsyncSubscribeRule,
|
|
3390
|
+
"no-connectable": noConnectableRule,
|
|
3391
|
+
"no-create": noCreateRule,
|
|
3392
|
+
"no-cyclic-action": noCyclicActionRule,
|
|
3393
|
+
"no-explicit-generics": noExplicitGenericsRule,
|
|
3394
|
+
"no-exposed-subjects": noExposedSubjectsRule,
|
|
3395
|
+
"no-finnish": noFinnishRule,
|
|
3396
|
+
"no-floating-observables": noFloatingObservablesRule,
|
|
3397
|
+
"no-ignored-default-value": noIgnoredDefaultValueRule,
|
|
3398
|
+
"no-ignored-error": noIgnoredErrorRule,
|
|
3399
|
+
"no-ignored-notifier": noIgnoredNotifierRule,
|
|
3400
|
+
"no-ignored-replay-buffer": noIgnoredReplayBufferRule,
|
|
3401
|
+
"no-ignored-subscribe": noIgnoredSubscribeRule,
|
|
3402
|
+
"no-ignored-subscription": noIgnoredSubscriptionRule,
|
|
3403
|
+
"no-ignored-takewhile-value": noIgnoredTakewhileValueRule,
|
|
3404
|
+
"no-implicit-any-catch": noImplicitAnyCatchRule,
|
|
3405
|
+
"no-index": noIndexRule,
|
|
3406
|
+
"no-internal": noInternalRule,
|
|
3407
|
+
"no-misused-observables": noMisusedObservablesRule,
|
|
3408
|
+
"no-nested-subscribe": noNestedSubscribeRule,
|
|
3409
|
+
"no-redundant-notify": noRedundantNotifyRule,
|
|
3410
|
+
"no-sharereplay": noSharereplayRule,
|
|
3411
|
+
"no-sharereplay-before-takeuntil": noSharereplayBeforeTakeuntilRule,
|
|
3412
|
+
"no-subclass": noSubclassRule,
|
|
3413
|
+
"no-subject-unsubscribe": noSubjectUnsubscribeRule,
|
|
3414
|
+
"no-subject-value": noSubjectValueRule,
|
|
3415
|
+
"no-subscribe-handlers": noSubscribeHandlersRule,
|
|
3416
|
+
"no-subscribe-in-pipe": noSubscribeInPipeRule,
|
|
3417
|
+
"no-topromise": noTopromiseRule,
|
|
3418
|
+
"no-unbound-methods": noUnboundMethodsRule,
|
|
3419
|
+
"no-unnecessary-collection": noUnnecessaryCollectionRule,
|
|
3420
|
+
"no-unsafe-catch": noUnsafeCatchRule,
|
|
3421
|
+
"no-unsafe-first": noUnsafeFirstRule,
|
|
3422
|
+
"no-unsafe-subject-next": noUnsafeSubjectNext,
|
|
3423
|
+
"no-unsafe-switchmap": noUnsafeSwitchmapRule,
|
|
3424
|
+
"no-unsafe-takeuntil": noUnsafeTakeuntilRule,
|
|
3425
|
+
"prefer-observer": preferObserverRule,
|
|
3426
|
+
"prefer-root-operators": preferRootOperatorsRule,
|
|
3427
|
+
"suffix-subjects": suffixSubjectsRule,
|
|
3428
|
+
"throw-error": throwErrorRule
|
|
3429
|
+
}
|
|
3527
3430
|
};
|
|
3528
3431
|
const rxjsX = {
|
|
3529
3432
|
...plugin,
|
|
@@ -3532,6 +3435,5 @@ const rxjsX = {
|
|
|
3532
3435
|
strict: createStrictConfig(plugin)
|
|
3533
3436
|
}
|
|
3534
3437
|
};
|
|
3535
|
-
|
|
3536
3438
|
//#endregion
|
|
3537
|
-
export { rxjsX as default };
|
|
3439
|
+
export { rxjsX as default };
|
package/package.json
CHANGED
|
@@ -1,23 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-rxjs-x",
|
|
3
|
-
"
|
|
4
|
-
"version": "1.0.0",
|
|
5
|
-
"packageManager": "yarn@4.12.0+sha512.f45ab632439a67f8bc759bf32ead036a1f413287b9042726b7cc4818b7b49e14e9423ba49b18f9e06ea4941c1ad062385b1d8760a8d5091a1a31e5f6219afca8",
|
|
3
|
+
"version": "1.0.2",
|
|
6
4
|
"description": "Modern ESLint plugin for RxJS",
|
|
7
|
-
"author": "Jason Weinzierl <weinzierljason@gmail.com>",
|
|
8
|
-
"license": "MIT",
|
|
9
|
-
"homepage": "https://github.com/JasonWeinzierl/eslint-plugin-rxjs-x",
|
|
10
|
-
"repository": {
|
|
11
|
-
"type": "git",
|
|
12
|
-
"url": "git+https://github.com/JasonWeinzierl/eslint-plugin-rxjs-x.git"
|
|
13
|
-
},
|
|
14
|
-
"publishConfig": {
|
|
15
|
-
"provenance": true,
|
|
16
|
-
"registry": "https://registry.npmjs.org"
|
|
17
|
-
},
|
|
18
|
-
"bugs": {
|
|
19
|
-
"url": "https://github.com/JasonWeinzierl/eslint-plugin-rxjs-x/issues"
|
|
20
|
-
},
|
|
21
5
|
"keywords": [
|
|
22
6
|
"lint",
|
|
23
7
|
"rules",
|
|
@@ -26,7 +10,18 @@
|
|
|
26
10
|
"eslint-plugin",
|
|
27
11
|
"rxjs"
|
|
28
12
|
],
|
|
13
|
+
"homepage": "https://github.com/JasonWeinzierl/eslint-plugin-rxjs-x",
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/JasonWeinzierl/eslint-plugin-rxjs-x/issues"
|
|
16
|
+
},
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/JasonWeinzierl/eslint-plugin-rxjs-x.git"
|
|
20
|
+
},
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"author": "Jason Weinzierl <weinzierljason@gmail.com>",
|
|
29
23
|
"sideEffects": false,
|
|
24
|
+
"type": "module",
|
|
30
25
|
"exports": {
|
|
31
26
|
".": {
|
|
32
27
|
"types": "./dist/index.d.ts",
|
|
@@ -41,61 +36,71 @@
|
|
|
41
36
|
],
|
|
42
37
|
"scripts": {
|
|
43
38
|
"build": "tsdown",
|
|
39
|
+
"coverage": "vitest run --coverage",
|
|
40
|
+
"docs": "eslint-doc-generator",
|
|
44
41
|
"lint": "yarn lint-js && yarn lint-docs && yarn lint-eslint-docs",
|
|
45
|
-
"lint-js": "eslint",
|
|
46
42
|
"lint-docs": "markdownlint-cli2 \"**/*.md\" \"#node_modules\"",
|
|
47
43
|
"lint-eslint-docs": "yarn build && eslint-doc-generator --check",
|
|
48
|
-
"
|
|
44
|
+
"lint-js": "eslint",
|
|
49
45
|
"release": "bumpp && echo \"Create a new release in GitHub to trigger the publish workflow.\"",
|
|
50
46
|
"test": "vitest",
|
|
51
|
-
"coverage": "vitest run --coverage",
|
|
52
47
|
"typecheck": "tsc --noEmit"
|
|
53
48
|
},
|
|
49
|
+
"resolutions": {
|
|
50
|
+
"rolldown": "^1.0.0-rc.12"
|
|
51
|
+
},
|
|
54
52
|
"dependencies": {
|
|
55
|
-
"@typescript-eslint/utils": "^8.
|
|
53
|
+
"@typescript-eslint/utils": "^8.58.0",
|
|
56
54
|
"decamelize": "^6.0.1",
|
|
57
|
-
"ts-api-utils": "^2.
|
|
58
|
-
},
|
|
59
|
-
"peerDependencies": {
|
|
60
|
-
"eslint": "^10.0.0",
|
|
61
|
-
"rxjs": "^7.2.0",
|
|
62
|
-
"typescript": ">=4.8.4 <6.0.0"
|
|
63
|
-
},
|
|
64
|
-
"peerDependenciesMeta": {
|
|
65
|
-
"rxjs": {
|
|
66
|
-
"optional": true
|
|
67
|
-
}
|
|
55
|
+
"ts-api-utils": "^2.5.0"
|
|
68
56
|
},
|
|
69
57
|
"devDependencies": {
|
|
70
58
|
"@eslint/js": "^10.0.1",
|
|
71
|
-
"@stylistic/eslint-plugin": "^5.
|
|
59
|
+
"@stylistic/eslint-plugin": "^5.10.0",
|
|
72
60
|
"@types/common-tags": "^1.8.4",
|
|
73
|
-
"@types/node": "~20.19.
|
|
74
|
-
"@typescript-eslint/rule-tester": "^8.
|
|
75
|
-
"@typescript/vfs": "^1.6.
|
|
76
|
-
"@vitest/coverage-v8": "^4.
|
|
77
|
-
"@vitest/eslint-plugin": "^1.6.
|
|
78
|
-
"bumpp": "^
|
|
61
|
+
"@types/node": "~20.19.37",
|
|
62
|
+
"@typescript-eslint/rule-tester": "^8.58.0",
|
|
63
|
+
"@typescript/vfs": "^1.6.4",
|
|
64
|
+
"@vitest/coverage-v8": "^4.1.2",
|
|
65
|
+
"@vitest/eslint-plugin": "^1.6.13",
|
|
66
|
+
"bumpp": "^11.0.1",
|
|
79
67
|
"common-tags": "^1.8.2",
|
|
80
|
-
"eslint": "^10.
|
|
81
|
-
"eslint-config-flat-gitignore": "^2.
|
|
82
|
-
"eslint-doc-generator": "^3.
|
|
68
|
+
"eslint": "^10.1.0",
|
|
69
|
+
"eslint-config-flat-gitignore": "^2.3.0",
|
|
70
|
+
"eslint-doc-generator": "^3.3.2",
|
|
83
71
|
"eslint-import-resolver-typescript": "^4.4.4",
|
|
84
72
|
"eslint-plugin-eslint-plugin": "patch:eslint-plugin-eslint-plugin@npm%3A7.3.1#~/.yarn/patches/eslint-plugin-eslint-plugin-npm-7.3.1-6b766f9a07.patch",
|
|
85
|
-
"eslint-plugin-import-x": "^4.16.
|
|
73
|
+
"eslint-plugin-import-x": "^4.16.2",
|
|
86
74
|
"eslint-plugin-n": "^17.24.0",
|
|
87
|
-
"
|
|
75
|
+
"eslint-plugin-package-json": "^0.91.1",
|
|
76
|
+
"eslint-plugin-perfectionist": "^5.7.0",
|
|
77
|
+
"eslint-plugin-regexp": "^3.1.0",
|
|
78
|
+
"eslint-plugin-unicorn": "^64.0.0",
|
|
79
|
+
"jsonc-eslint-parser": "^3.1.0",
|
|
80
|
+
"markdownlint-cli2": "~0.22.0",
|
|
88
81
|
"rxjs": "^7.8.2",
|
|
89
|
-
"tsdown": "^0.
|
|
90
|
-
"typescript": "~
|
|
91
|
-
"typescript-eslint": "^8.
|
|
92
|
-
"vite": "
|
|
93
|
-
"vitest": "^4.
|
|
82
|
+
"tsdown": "^0.21.7",
|
|
83
|
+
"typescript": "~6.0.2",
|
|
84
|
+
"typescript-eslint": "^8.58.0",
|
|
85
|
+
"vite": "^8.0.3",
|
|
86
|
+
"vitest": "^4.1.2"
|
|
94
87
|
},
|
|
95
|
-
"
|
|
96
|
-
"
|
|
88
|
+
"peerDependencies": {
|
|
89
|
+
"eslint": "^10.0.1",
|
|
90
|
+
"rxjs": "^7.2.0",
|
|
91
|
+
"typescript": ">=4.8.4 <6.1.0"
|
|
97
92
|
},
|
|
93
|
+
"peerDependenciesMeta": {
|
|
94
|
+
"rxjs": {
|
|
95
|
+
"optional": true
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
"packageManager": "yarn@4.13.0+sha512.5c20ba010c99815433e5c8453112165e673f1c7948d8d2b267f4b5e52097538658388ebc9f9580656d9b75c5cc996f990f611f99304a2197d4c56d21eea370e7",
|
|
98
99
|
"engines": {
|
|
99
100
|
"node": "^20.19.0 || ^22.13.0 || >=24"
|
|
101
|
+
},
|
|
102
|
+
"publishConfig": {
|
|
103
|
+
"provenance": true,
|
|
104
|
+
"registry": "https://registry.npmjs.org"
|
|
100
105
|
}
|
|
101
106
|
}
|