eslint-plugin-rxjs-x 0.2.3 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -43
- package/dist/index.d.mts +5 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +244 -122
- package/dist/index.mjs +276 -154
- package/docs/rules/ban-operators.md +2 -0
- package/docs/rules/macro.md +4 -0
- package/docs/rules/no-exposed-subjects.md +2 -2
- package/docs/rules/no-ignored-default-value.md +29 -0
- package/docs/rules/no-nested-subscribe.md +2 -2
- package/docs/rules/throw-error.md +14 -25
- package/package.json +9 -9
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }// package.json
|
|
2
2
|
var name = "eslint-plugin-rxjs-x";
|
|
3
|
-
var version = "0.
|
|
3
|
+
var version = "0.3.0";
|
|
4
4
|
|
|
5
5
|
// src/configs/recommended.ts
|
|
6
6
|
var createRecommendedConfig = (plugin2) => ({
|
|
@@ -119,78 +119,11 @@ var banObservablesRule = ruleCreator({
|
|
|
119
119
|
// src/rules/ban-operators.ts
|
|
120
120
|
|
|
121
121
|
|
|
122
|
-
var defaultOptions2 = [];
|
|
123
|
-
var banOperatorsRule = ruleCreator({
|
|
124
|
-
defaultOptions: defaultOptions2,
|
|
125
|
-
meta: {
|
|
126
|
-
docs: {
|
|
127
|
-
description: "Disallow banned operators."
|
|
128
|
-
},
|
|
129
|
-
messages: {
|
|
130
|
-
forbidden: "RxJS operator is banned: {{name}}{{explanation}}."
|
|
131
|
-
},
|
|
132
|
-
schema: [
|
|
133
|
-
{
|
|
134
|
-
type: "object",
|
|
135
|
-
description: _commontags.stripIndent`
|
|
136
|
-
An object containing keys that are names of operators
|
|
137
|
-
and values that are either booleans or strings containing the explanation for the ban.`
|
|
138
|
-
}
|
|
139
|
-
],
|
|
140
|
-
type: "problem"
|
|
141
|
-
},
|
|
142
|
-
name: "ban-operators",
|
|
143
|
-
create: (context) => {
|
|
144
|
-
const bans = [];
|
|
145
|
-
const [config] = context.options;
|
|
146
|
-
if (!config) {
|
|
147
|
-
return {};
|
|
148
|
-
}
|
|
149
|
-
Object.entries(config).forEach(([key, value]) => {
|
|
150
|
-
if (value !== false) {
|
|
151
|
-
bans.push({
|
|
152
|
-
explanation: typeof value === "string" ? value : "",
|
|
153
|
-
regExp: new RegExp(`^${key}$`)
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
});
|
|
157
|
-
function getFailure(name2) {
|
|
158
|
-
for (let b = 0, length = bans.length; b < length; ++b) {
|
|
159
|
-
const ban = bans[b];
|
|
160
|
-
if (ban.regExp.test(name2)) {
|
|
161
|
-
const explanation = ban.explanation ? `: ${ban.explanation}` : "";
|
|
162
|
-
return {
|
|
163
|
-
messageId: "forbidden",
|
|
164
|
-
data: { name: name2, explanation }
|
|
165
|
-
};
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
return void 0;
|
|
169
|
-
}
|
|
170
|
-
return {
|
|
171
|
-
[String.raw`ImportDeclaration[source.value=/^rxjs\u002foperators$/] > ImportSpecifier`]: (node) => {
|
|
172
|
-
const identifier = node.imported;
|
|
173
|
-
const name2 = identifier.type === _utils.AST_NODE_TYPES.Identifier ? identifier.name : identifier.value;
|
|
174
|
-
const failure = getFailure(name2);
|
|
175
|
-
if (failure) {
|
|
176
|
-
context.report({
|
|
177
|
-
...failure,
|
|
178
|
-
node: identifier
|
|
179
|
-
});
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
};
|
|
183
|
-
}
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
// src/rules/finnish.ts
|
|
187
|
-
|
|
188
|
-
|
|
189
122
|
// src/etc/could-be-function.ts
|
|
190
123
|
var _typescript = require('typescript'); var _typescript2 = _interopRequireDefault(_typescript);
|
|
191
124
|
|
|
192
125
|
// src/etc/could-be-type.ts
|
|
193
|
-
var _tsapiutils = require('ts-api-utils'); var tsutils = _interopRequireWildcard(_tsapiutils); var tsutils2 = _interopRequireWildcard(_tsapiutils); var tsutils3 = _interopRequireWildcard(_tsapiutils);
|
|
126
|
+
var _tsapiutils = require('ts-api-utils'); var tsutils = _interopRequireWildcard(_tsapiutils); var tsutils2 = _interopRequireWildcard(_tsapiutils); var tsutils3 = _interopRequireWildcard(_tsapiutils);
|
|
194
127
|
|
|
195
128
|
function couldBeType(type, name2, qualified) {
|
|
196
129
|
if (tsutils.isTypeReference(type)) {
|
|
@@ -303,7 +236,6 @@ function getLoc(node) {
|
|
|
303
236
|
|
|
304
237
|
|
|
305
238
|
|
|
306
|
-
|
|
307
239
|
// src/etc/is.ts
|
|
308
240
|
|
|
309
241
|
function hasTypeAnnotation(node) {
|
|
@@ -358,7 +290,7 @@ function getTypeServices(context) {
|
|
|
358
290
|
const { esTreeNodeToTSNodeMap, program, getTypeAtLocation } = services;
|
|
359
291
|
const typeChecker = program.getTypeChecker();
|
|
360
292
|
const couldBeType2 = (node, name2, qualified) => {
|
|
361
|
-
const type =
|
|
293
|
+
const type = getTypeAtLocation(node);
|
|
362
294
|
return couldBeType(
|
|
363
295
|
type,
|
|
364
296
|
name2,
|
|
@@ -382,17 +314,13 @@ function getTypeServices(context) {
|
|
|
382
314
|
)
|
|
383
315
|
);
|
|
384
316
|
};
|
|
385
|
-
const getType = (node) => {
|
|
386
|
-
return getTypeAtLocation(node);
|
|
387
|
-
};
|
|
388
317
|
return {
|
|
389
318
|
couldBeBehaviorSubject: (node) => couldBeType2(node, "BehaviorSubject"),
|
|
390
|
-
couldBeError: (node) => couldBeType2(node, "Error"),
|
|
391
319
|
couldBeFunction: (node) => {
|
|
392
320
|
if (isArrowFunctionExpression(node) || isFunctionDeclaration(node)) {
|
|
393
321
|
return true;
|
|
394
322
|
}
|
|
395
|
-
return couldBeFunction(
|
|
323
|
+
return couldBeFunction(getTypeAtLocation(node));
|
|
396
324
|
},
|
|
397
325
|
couldBeMonoTypeOperatorFunction: (node) => couldBeType2(node, "MonoTypeOperatorFunction"),
|
|
398
326
|
couldBeObservable: (node) => couldBeType2(node, "Observable"),
|
|
@@ -400,12 +328,7 @@ function getTypeServices(context) {
|
|
|
400
328
|
couldBeSubscription: (node) => couldBeType2(node, "Subscription"),
|
|
401
329
|
couldBeType: couldBeType2,
|
|
402
330
|
couldReturnObservable: (node) => couldReturnType(node, "Observable"),
|
|
403
|
-
couldReturnType
|
|
404
|
-
getType,
|
|
405
|
-
isAny: (node) => tsutils2.isIntrinsicAnyType(getType(node)),
|
|
406
|
-
isReferenceType: (node) => tsutils2.isTypeReference(getType(node)),
|
|
407
|
-
isUnknown: (node) => tsutils2.isIntrinsicUnknownType(getType(node)),
|
|
408
|
-
typeChecker
|
|
331
|
+
couldReturnType
|
|
409
332
|
};
|
|
410
333
|
}
|
|
411
334
|
|
|
@@ -422,7 +345,71 @@ function isImport(scope, name2, source) {
|
|
|
422
345
|
return scope.upper ? isImport(scope.upper, name2, source) : false;
|
|
423
346
|
}
|
|
424
347
|
|
|
348
|
+
// src/rules/ban-operators.ts
|
|
349
|
+
var defaultOptions2 = [];
|
|
350
|
+
var banOperatorsRule = ruleCreator({
|
|
351
|
+
defaultOptions: defaultOptions2,
|
|
352
|
+
meta: {
|
|
353
|
+
docs: {
|
|
354
|
+
description: "Disallow banned operators.",
|
|
355
|
+
requiresTypeChecking: true
|
|
356
|
+
},
|
|
357
|
+
messages: {
|
|
358
|
+
forbidden: "RxJS operator is banned: {{name}}{{explanation}}."
|
|
359
|
+
},
|
|
360
|
+
schema: [
|
|
361
|
+
{
|
|
362
|
+
type: "object",
|
|
363
|
+
description: _commontags.stripIndent`
|
|
364
|
+
An object containing keys that are names of operators
|
|
365
|
+
and values that are either booleans or strings containing the explanation for the ban.`
|
|
366
|
+
}
|
|
367
|
+
],
|
|
368
|
+
type: "problem"
|
|
369
|
+
},
|
|
370
|
+
name: "ban-operators",
|
|
371
|
+
create: (context) => {
|
|
372
|
+
const { couldBeType: couldBeType2 } = getTypeServices(context);
|
|
373
|
+
const bans = [];
|
|
374
|
+
const [config] = context.options;
|
|
375
|
+
if (!config) {
|
|
376
|
+
return {};
|
|
377
|
+
}
|
|
378
|
+
Object.entries(config).forEach(([key, value]) => {
|
|
379
|
+
if (value !== false) {
|
|
380
|
+
bans.push({
|
|
381
|
+
name: key,
|
|
382
|
+
explanation: typeof value === "string" ? value : ""
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
});
|
|
386
|
+
function checkNode(node) {
|
|
387
|
+
for (const ban of bans) {
|
|
388
|
+
if (couldBeType2(node, ban.name, { name: /[/\\]rxjs[/\\]/ })) {
|
|
389
|
+
const explanation = ban.explanation ? `: ${ban.explanation}` : "";
|
|
390
|
+
context.report({
|
|
391
|
+
messageId: "forbidden",
|
|
392
|
+
data: { name: ban.name, explanation },
|
|
393
|
+
node
|
|
394
|
+
});
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
return {
|
|
400
|
+
"CallExpression[callee.property.name='pipe'] > CallExpression[callee.name]": (node) => {
|
|
401
|
+
checkNode(node.callee);
|
|
402
|
+
},
|
|
403
|
+
"CallExpression[callee.property.name='pipe'] > CallExpression[callee.type=\"MemberExpression\"]": (node) => {
|
|
404
|
+
const callee = node.callee;
|
|
405
|
+
checkNode(callee.property);
|
|
406
|
+
}
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
});
|
|
410
|
+
|
|
425
411
|
// src/rules/finnish.ts
|
|
412
|
+
|
|
426
413
|
var defaultOptions3 = [];
|
|
427
414
|
var finnishRule = ruleCreator({
|
|
428
415
|
defaultOptions: defaultOptions3,
|
|
@@ -723,6 +710,7 @@ var justRule = ruleCreator({
|
|
|
723
710
|
var macroRule = ruleCreator({
|
|
724
711
|
defaultOptions: [],
|
|
725
712
|
meta: {
|
|
713
|
+
deprecated: true,
|
|
726
714
|
docs: {
|
|
727
715
|
description: "Require the use of the RxJS Tools Babel macro."
|
|
728
716
|
},
|
|
@@ -922,11 +910,12 @@ var noCreateRule = ruleCreator({
|
|
|
922
910
|
|
|
923
911
|
|
|
924
912
|
|
|
913
|
+
|
|
925
914
|
// src/constants.ts
|
|
926
915
|
var defaultObservable = String.raw`[Aa]ction(s|s\$|\$)$`;
|
|
927
916
|
|
|
928
917
|
// src/rules/no-cyclic-action.ts
|
|
929
|
-
function
|
|
918
|
+
function isTypeReference2(type) {
|
|
930
919
|
return Boolean(type.target);
|
|
931
920
|
}
|
|
932
921
|
var defaultOptions4 = [];
|
|
@@ -958,7 +947,8 @@ var noCyclicActionRule = ruleCreator({
|
|
|
958
947
|
const [config = {}] = context.options;
|
|
959
948
|
const { observable = defaultObservable } = config;
|
|
960
949
|
const observableRegExp = new RegExp(observable);
|
|
961
|
-
const {
|
|
950
|
+
const { getTypeAtLocation, program } = _utils.ESLintUtils.getParserServices(context);
|
|
951
|
+
const typeChecker = program.getTypeChecker();
|
|
962
952
|
function checkNode(pipeCallExpression) {
|
|
963
953
|
const operatorCallExpression = pipeCallExpression.arguments.find(
|
|
964
954
|
(arg) => isCallExpression(arg) && isIdentifier(arg.callee) && arg.callee.name === "ofType"
|
|
@@ -966,7 +956,7 @@ var noCyclicActionRule = ruleCreator({
|
|
|
966
956
|
if (!operatorCallExpression) {
|
|
967
957
|
return;
|
|
968
958
|
}
|
|
969
|
-
const operatorType =
|
|
959
|
+
const operatorType = getTypeAtLocation(operatorCallExpression);
|
|
970
960
|
const [signature] = typeChecker.getSignaturesOfType(
|
|
971
961
|
operatorType,
|
|
972
962
|
_typescript2.default.SignatureKind.Call
|
|
@@ -975,15 +965,15 @@ var noCyclicActionRule = ruleCreator({
|
|
|
975
965
|
return;
|
|
976
966
|
}
|
|
977
967
|
const operatorReturnType = typeChecker.getReturnTypeOfSignature(signature);
|
|
978
|
-
if (!
|
|
968
|
+
if (!isTypeReference2(operatorReturnType)) {
|
|
979
969
|
return;
|
|
980
970
|
}
|
|
981
971
|
const [operatorElementType] = typeChecker.getTypeArguments(operatorReturnType);
|
|
982
972
|
if (!operatorElementType) {
|
|
983
973
|
return;
|
|
984
974
|
}
|
|
985
|
-
const pipeType =
|
|
986
|
-
if (!
|
|
975
|
+
const pipeType = getTypeAtLocation(pipeCallExpression);
|
|
976
|
+
if (!isTypeReference2(pipeType)) {
|
|
987
977
|
return;
|
|
988
978
|
}
|
|
989
979
|
const [pipeElementType] = typeChecker.getTypeArguments(pipeType);
|
|
@@ -1277,6 +1267,108 @@ var noFinnishRule = ruleCreator({
|
|
|
1277
1267
|
}
|
|
1278
1268
|
});
|
|
1279
1269
|
|
|
1270
|
+
// src/rules/no-ignored-default-value.ts
|
|
1271
|
+
|
|
1272
|
+
var noIgnoredDefaultValueRule = ruleCreator({
|
|
1273
|
+
defaultOptions: [],
|
|
1274
|
+
meta: {
|
|
1275
|
+
docs: {
|
|
1276
|
+
description: "Disallow using `firstValueFrom`, `lastValueFrom`, `first`, and `last` without specifying a default value.",
|
|
1277
|
+
requiresTypeChecking: true
|
|
1278
|
+
},
|
|
1279
|
+
messages: {
|
|
1280
|
+
forbidden: "Not specifying a default value is forbidden."
|
|
1281
|
+
},
|
|
1282
|
+
schema: [],
|
|
1283
|
+
type: "problem"
|
|
1284
|
+
},
|
|
1285
|
+
name: "no-ignored-default-value",
|
|
1286
|
+
create: (context) => {
|
|
1287
|
+
const { getTypeAtLocation } = _utils.ESLintUtils.getParserServices(context);
|
|
1288
|
+
const { couldBeObservable, couldBeType: couldBeType2 } = getTypeServices(context);
|
|
1289
|
+
function checkConfigObj(configArg) {
|
|
1290
|
+
if (!configArg.properties.some((p) => isProperty(p) && isIdentifier(p.key) && p.key.name === "defaultValue")) {
|
|
1291
|
+
context.report({
|
|
1292
|
+
messageId: "forbidden",
|
|
1293
|
+
node: configArg
|
|
1294
|
+
});
|
|
1295
|
+
}
|
|
1296
|
+
}
|
|
1297
|
+
function checkConfigType(configArg) {
|
|
1298
|
+
const configArgType = getTypeAtLocation(configArg);
|
|
1299
|
+
if (!(configArgType == null ? void 0 : configArgType.getProperties().some((p) => p.name === "defaultValue"))) {
|
|
1300
|
+
context.report({
|
|
1301
|
+
messageId: "forbidden",
|
|
1302
|
+
node: configArg
|
|
1303
|
+
});
|
|
1304
|
+
}
|
|
1305
|
+
}
|
|
1306
|
+
function checkArg(arg) {
|
|
1307
|
+
if (isIdentifier(arg)) {
|
|
1308
|
+
checkConfigType(arg);
|
|
1309
|
+
return;
|
|
1310
|
+
} else if (isMemberExpression(arg) && isIdentifier(arg.property)) {
|
|
1311
|
+
checkConfigType(arg.property);
|
|
1312
|
+
return;
|
|
1313
|
+
}
|
|
1314
|
+
if (!isObjectExpression(arg)) {
|
|
1315
|
+
return;
|
|
1316
|
+
}
|
|
1317
|
+
checkConfigObj(arg);
|
|
1318
|
+
}
|
|
1319
|
+
function checkFunctionArgs(node, args) {
|
|
1320
|
+
if (!couldBeType2(node, "firstValueFrom", { name: /[/\\]rxjs[/\\]/ }) && !couldBeType2(node, "lastValueFrom", { name: /[/\\]rxjs[/\\]/ })) {
|
|
1321
|
+
return;
|
|
1322
|
+
}
|
|
1323
|
+
if (!args || args.length <= 0) {
|
|
1324
|
+
return;
|
|
1325
|
+
}
|
|
1326
|
+
const [observableArg, configArg] = args;
|
|
1327
|
+
if (!couldBeObservable(observableArg)) {
|
|
1328
|
+
return;
|
|
1329
|
+
}
|
|
1330
|
+
if (!configArg) {
|
|
1331
|
+
context.report({
|
|
1332
|
+
messageId: "forbidden",
|
|
1333
|
+
node
|
|
1334
|
+
});
|
|
1335
|
+
return;
|
|
1336
|
+
}
|
|
1337
|
+
checkArg(configArg);
|
|
1338
|
+
}
|
|
1339
|
+
function checkOperatorArgs(node, args) {
|
|
1340
|
+
if (!couldBeType2(node, "first", { name: /[/\\]rxjs[/\\]/ }) && !couldBeType2(node, "last", { name: /[/\\]rxjs[/\\]/ })) {
|
|
1341
|
+
return;
|
|
1342
|
+
}
|
|
1343
|
+
if (!args || args.length <= 0) {
|
|
1344
|
+
context.report({
|
|
1345
|
+
messageId: "forbidden",
|
|
1346
|
+
node
|
|
1347
|
+
});
|
|
1348
|
+
return;
|
|
1349
|
+
}
|
|
1350
|
+
const [arg] = args;
|
|
1351
|
+
checkArg(arg);
|
|
1352
|
+
}
|
|
1353
|
+
return {
|
|
1354
|
+
"CallExpression[callee.name=/^(firstValueFrom|lastValueFrom)$/]": (node) => {
|
|
1355
|
+
checkFunctionArgs(node.callee, node.arguments);
|
|
1356
|
+
},
|
|
1357
|
+
"CallExpression[callee.property.name=/^(firstValueFrom|lastValueFrom)$/]": (node) => {
|
|
1358
|
+
const memberExpression = node.callee;
|
|
1359
|
+
checkFunctionArgs(memberExpression.property, node.arguments);
|
|
1360
|
+
},
|
|
1361
|
+
"CallExpression[callee.property.name='pipe'] > CallExpression[callee.name=/^(first|last)$/]": (node) => {
|
|
1362
|
+
checkOperatorArgs(node.callee, node.arguments);
|
|
1363
|
+
},
|
|
1364
|
+
"CallExpression[callee.property.name='pipe'] > CallExpression[callee.property.name=/^(first|last)$/]": (node) => {
|
|
1365
|
+
const memberExpression = node.callee;
|
|
1366
|
+
checkOperatorArgs(memberExpression.property, node.arguments);
|
|
1367
|
+
}
|
|
1368
|
+
};
|
|
1369
|
+
}
|
|
1370
|
+
});
|
|
1371
|
+
|
|
1280
1372
|
// src/rules/no-ignored-error.ts
|
|
1281
1373
|
var noIgnoredErrorRule = ruleCreator({
|
|
1282
1374
|
defaultOptions: [],
|
|
@@ -1412,7 +1504,6 @@ var noIgnoredObservableRule = ruleCreator({
|
|
|
1412
1504
|
});
|
|
1413
1505
|
|
|
1414
1506
|
// src/rules/no-ignored-replay-buffer.ts
|
|
1415
|
-
|
|
1416
1507
|
var noIgnoredReplayBufferRule = ruleCreator({
|
|
1417
1508
|
defaultOptions: [],
|
|
1418
1509
|
meta: {
|
|
@@ -1429,7 +1520,7 @@ var noIgnoredReplayBufferRule = ruleCreator({
|
|
|
1429
1520
|
name: "no-ignored-replay-buffer",
|
|
1430
1521
|
create: (context) => {
|
|
1431
1522
|
function checkShareReplayConfig(node, shareReplayConfigArg) {
|
|
1432
|
-
if (!shareReplayConfigArg.properties.some((p) => p
|
|
1523
|
+
if (!shareReplayConfigArg.properties.some((p) => isProperty(p) && isIdentifier(p.key) && p.key.name === "bufferSize")) {
|
|
1433
1524
|
context.report({
|
|
1434
1525
|
messageId: "forbidden",
|
|
1435
1526
|
node
|
|
@@ -1444,8 +1535,8 @@ var noIgnoredReplayBufferRule = ruleCreator({
|
|
|
1444
1535
|
});
|
|
1445
1536
|
}
|
|
1446
1537
|
if (node.name === "shareReplay" && (args == null ? void 0 : args.length) === 1) {
|
|
1447
|
-
const arg = args
|
|
1448
|
-
if (arg
|
|
1538
|
+
const [arg] = args;
|
|
1539
|
+
if (isObjectExpression(arg)) {
|
|
1449
1540
|
checkShareReplayConfig(node, arg);
|
|
1450
1541
|
}
|
|
1451
1542
|
}
|
|
@@ -2226,6 +2317,7 @@ var noTopromiseRule = ruleCreator({
|
|
|
2226
2317
|
});
|
|
2227
2318
|
|
|
2228
2319
|
// src/rules/no-unbound-methods.ts
|
|
2320
|
+
|
|
2229
2321
|
var noUnboundMethodsRule = ruleCreator({
|
|
2230
2322
|
defaultOptions: [],
|
|
2231
2323
|
meta: {
|
|
@@ -2242,11 +2334,12 @@ var noUnboundMethodsRule = ruleCreator({
|
|
|
2242
2334
|
},
|
|
2243
2335
|
name: "no-unbound-methods",
|
|
2244
2336
|
create: (context) => {
|
|
2245
|
-
const {
|
|
2337
|
+
const { getTypeAtLocation } = _utils.ESLintUtils.getParserServices(context);
|
|
2338
|
+
const { couldBeObservable, couldBeSubscription } = getTypeServices(context);
|
|
2246
2339
|
const nodeMap = /* @__PURE__ */ new WeakMap();
|
|
2247
2340
|
function mapArguments(node) {
|
|
2248
2341
|
node.arguments.filter(isMemberExpression).forEach((arg) => {
|
|
2249
|
-
const argType =
|
|
2342
|
+
const argType = getTypeAtLocation(arg);
|
|
2250
2343
|
if (argType.getCallSignatures().length > 0) {
|
|
2251
2344
|
nodeMap.set(arg);
|
|
2252
2345
|
}
|
|
@@ -2421,6 +2514,7 @@ var noUnsafeFirstRule = ruleCreator({
|
|
|
2421
2514
|
// src/rules/no-unsafe-subject-next.ts
|
|
2422
2515
|
|
|
2423
2516
|
|
|
2517
|
+
|
|
2424
2518
|
var noUnsafeSubjectNext = ruleCreator({
|
|
2425
2519
|
defaultOptions: [],
|
|
2426
2520
|
meta: {
|
|
@@ -2437,24 +2531,25 @@ var noUnsafeSubjectNext = ruleCreator({
|
|
|
2437
2531
|
},
|
|
2438
2532
|
name: "no-unsafe-subject-next",
|
|
2439
2533
|
create: (context) => {
|
|
2440
|
-
const {
|
|
2534
|
+
const { getTypeAtLocation, program } = _utils.ESLintUtils.getParserServices(context);
|
|
2535
|
+
const typeChecker = program.getTypeChecker();
|
|
2441
2536
|
return {
|
|
2442
2537
|
[`CallExpression[callee.property.name='next']`]: (node) => {
|
|
2443
2538
|
if (node.arguments.length === 0 && isMemberExpression(node.callee)) {
|
|
2444
|
-
const type =
|
|
2445
|
-
if (
|
|
2539
|
+
const type = getTypeAtLocation(node.callee.object);
|
|
2540
|
+
if (tsutils2.isTypeReference(type) && couldBeType(type, "Subject")) {
|
|
2446
2541
|
const [typeArg] = typeChecker.getTypeArguments(type);
|
|
2447
|
-
if (
|
|
2542
|
+
if (tsutils2.isTypeFlagSet(typeArg, _typescript2.default.TypeFlags.Any)) {
|
|
2448
2543
|
return;
|
|
2449
2544
|
}
|
|
2450
|
-
if (
|
|
2545
|
+
if (tsutils2.isTypeFlagSet(typeArg, _typescript2.default.TypeFlags.Unknown)) {
|
|
2451
2546
|
return;
|
|
2452
2547
|
}
|
|
2453
|
-
if (
|
|
2548
|
+
if (tsutils2.isTypeFlagSet(typeArg, _typescript2.default.TypeFlags.Void)) {
|
|
2454
2549
|
return;
|
|
2455
2550
|
}
|
|
2456
|
-
if (
|
|
2457
|
-
(t) =>
|
|
2551
|
+
if (tsutils2.isUnionType(typeArg) && typeArg.types.some(
|
|
2552
|
+
(t) => tsutils2.isTypeFlagSet(t, _typescript2.default.TypeFlags.Void)
|
|
2458
2553
|
)) {
|
|
2459
2554
|
return;
|
|
2460
2555
|
}
|
|
@@ -3000,47 +3095,73 @@ var suffixSubjectsRule = ruleCreator({
|
|
|
3000
3095
|
// src/rules/throw-error.ts
|
|
3001
3096
|
|
|
3002
3097
|
|
|
3098
|
+
var defaultOptions14 = [];
|
|
3003
3099
|
var throwErrorRule = ruleCreator({
|
|
3004
|
-
defaultOptions:
|
|
3100
|
+
defaultOptions: defaultOptions14,
|
|
3005
3101
|
meta: {
|
|
3006
3102
|
docs: {
|
|
3007
|
-
description: "Enforce passing only `Error` values to
|
|
3103
|
+
description: "Enforce passing only `Error` values to `throwError`.",
|
|
3008
3104
|
requiresTypeChecking: true
|
|
3009
3105
|
},
|
|
3010
3106
|
messages: {
|
|
3011
|
-
forbidden: "Passing non-Error values
|
|
3107
|
+
forbidden: "Passing non-Error values is forbidden."
|
|
3012
3108
|
},
|
|
3013
|
-
schema: [
|
|
3109
|
+
schema: [
|
|
3110
|
+
{
|
|
3111
|
+
properties: {
|
|
3112
|
+
allowThrowingAny: { type: "boolean", default: true, description: "Whether to always allow throwing values typed as `any`." },
|
|
3113
|
+
allowThrowingUnknown: { type: "boolean", default: true, description: "Whether to always allow throwing values typed as `unknown`." }
|
|
3114
|
+
},
|
|
3115
|
+
type: "object"
|
|
3116
|
+
}
|
|
3117
|
+
],
|
|
3014
3118
|
type: "problem"
|
|
3015
3119
|
},
|
|
3016
3120
|
name: "throw-error",
|
|
3017
3121
|
create: (context) => {
|
|
3018
|
-
const { esTreeNodeToTSNodeMap, program } = _utils.ESLintUtils.getParserServices(context);
|
|
3019
|
-
const { couldBeObservable
|
|
3020
|
-
|
|
3021
|
-
|
|
3122
|
+
const { esTreeNodeToTSNodeMap, program, getTypeAtLocation } = _utils.ESLintUtils.getParserServices(context);
|
|
3123
|
+
const { couldBeObservable } = getTypeServices(context);
|
|
3124
|
+
const [config = {}] = context.options;
|
|
3125
|
+
const { allowThrowingAny = true, allowThrowingUnknown = true } = config;
|
|
3126
|
+
function checkThrowArgument(node) {
|
|
3127
|
+
var _a;
|
|
3128
|
+
let type = getTypeAtLocation(node);
|
|
3129
|
+
let reportNode = node;
|
|
3022
3130
|
if (couldBeFunction(type)) {
|
|
3131
|
+
reportNode = (_a = node.body) != null ? _a : node;
|
|
3023
3132
|
const tsNode = esTreeNodeToTSNodeMap.get(node);
|
|
3024
3133
|
const annotation = tsNode.type;
|
|
3025
3134
|
const body = tsNode.body;
|
|
3026
3135
|
type = program.getTypeChecker().getTypeAtLocation(annotation != null ? annotation : body);
|
|
3027
3136
|
}
|
|
3028
|
-
if (
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3137
|
+
if (allowThrowingAny && tsutils3.isIntrinsicAnyType(type)) {
|
|
3138
|
+
return;
|
|
3139
|
+
}
|
|
3140
|
+
if (allowThrowingUnknown && tsutils3.isIntrinsicUnknownType(type)) {
|
|
3141
|
+
return;
|
|
3142
|
+
}
|
|
3143
|
+
if (couldBeType(type, /^Error$/)) {
|
|
3144
|
+
return;
|
|
3145
|
+
}
|
|
3146
|
+
context.report({
|
|
3147
|
+
messageId: "forbidden",
|
|
3148
|
+
node: reportNode
|
|
3149
|
+
});
|
|
3150
|
+
}
|
|
3151
|
+
function checkNode(node) {
|
|
3152
|
+
if (couldBeObservable(node)) {
|
|
3153
|
+
const [arg] = node.arguments;
|
|
3154
|
+
if (arg) {
|
|
3155
|
+
checkThrowArgument(arg);
|
|
3156
|
+
}
|
|
3033
3157
|
}
|
|
3034
3158
|
}
|
|
3035
3159
|
return {
|
|
3036
|
-
"ThrowStatement > *": checkNode,
|
|
3037
3160
|
"CallExpression[callee.name='throwError']": (node) => {
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
}
|
|
3043
|
-
}
|
|
3161
|
+
checkNode(node);
|
|
3162
|
+
},
|
|
3163
|
+
"CallExpression[callee.property.name='throwError']": (node) => {
|
|
3164
|
+
checkNode(node);
|
|
3044
3165
|
}
|
|
3045
3166
|
};
|
|
3046
3167
|
}
|
|
@@ -3063,6 +3184,7 @@ var plugin = {
|
|
|
3063
3184
|
"no-explicit-generics": noExplicitGenericsRule,
|
|
3064
3185
|
"no-exposed-subjects": noExposedSubjectsRule,
|
|
3065
3186
|
"no-finnish": noFinnishRule,
|
|
3187
|
+
"no-ignored-default-value": noIgnoredDefaultValueRule,
|
|
3066
3188
|
"no-ignored-error": noIgnoredErrorRule,
|
|
3067
3189
|
"no-ignored-notifier": noIgnoredNotifierRule,
|
|
3068
3190
|
"no-ignored-observable": noIgnoredObservableRule,
|