eslint-plugin-rxjs-x 0.5.0 → 0.6.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 +2 -0
- package/dist/index.d.mts +19 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.js +487 -26
- package/dist/index.mjs +501 -40
- package/docs/rules/no-floating-observables.md +1 -0
- package/docs/rules/no-misused-observables.md +85 -0
- package/docs/rules/no-subscribe-in-pipe.md +37 -0
- package/package.json +11 -9
package/dist/index.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
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.6.0";
|
|
4
4
|
|
|
5
5
|
// src/configs/recommended.ts
|
|
6
6
|
var createRecommendedConfig = (plugin2) => ({
|
|
7
|
+
name: "rxjs-x/recommended",
|
|
7
8
|
plugins: {
|
|
8
9
|
"rxjs-x": plugin2
|
|
9
10
|
},
|
|
@@ -20,6 +21,7 @@ var createRecommendedConfig = (plugin2) => ({
|
|
|
20
21
|
"rxjs-x/no-redundant-notify": "error",
|
|
21
22
|
"rxjs-x/no-sharereplay": "error",
|
|
22
23
|
"rxjs-x/no-subject-unsubscribe": "error",
|
|
24
|
+
"rxjs-x/no-subscribe-in-pipe": "error",
|
|
23
25
|
"rxjs-x/no-topromise": "error",
|
|
24
26
|
"rxjs-x/no-unbound-methods": "error",
|
|
25
27
|
"rxjs-x/no-unsafe-subject-next": "error",
|
|
@@ -32,6 +34,7 @@ var createRecommendedConfig = (plugin2) => ({
|
|
|
32
34
|
|
|
33
35
|
// src/configs/strict.ts
|
|
34
36
|
var createStrictConfig = (plugin2) => ({
|
|
37
|
+
name: "rxjs-x/strict",
|
|
35
38
|
plugins: {
|
|
36
39
|
"rxjs-x": plugin2
|
|
37
40
|
},
|
|
@@ -51,11 +54,13 @@ var createStrictConfig = (plugin2) => ({
|
|
|
51
54
|
}],
|
|
52
55
|
"rxjs-x/no-index": "error",
|
|
53
56
|
"rxjs-x/no-internal": "error",
|
|
57
|
+
"rxjs-x/no-misused-observables": "error",
|
|
54
58
|
"rxjs-x/no-nested-subscribe": "error",
|
|
55
59
|
"rxjs-x/no-redundant-notify": "error",
|
|
56
60
|
"rxjs-x/no-sharereplay": "error",
|
|
57
61
|
"rxjs-x/no-subclass": "error",
|
|
58
62
|
"rxjs-x/no-subject-unsubscribe": "error",
|
|
63
|
+
"rxjs-x/no-subscribe-in-pipe": "error",
|
|
59
64
|
"rxjs-x/no-topromise": "error",
|
|
60
65
|
"rxjs-x/no-unbound-methods": "error",
|
|
61
66
|
"rxjs-x/no-unsafe-subject-next": "error",
|
|
@@ -166,7 +171,7 @@ var banObservablesRule = ruleCreator({
|
|
|
166
171
|
var _typescript = require('typescript'); var _typescript2 = _interopRequireDefault(_typescript);
|
|
167
172
|
|
|
168
173
|
// src/etc/could-be-type.ts
|
|
169
|
-
var _tsapiutils = require('ts-api-utils'); var tsutils = _interopRequireWildcard(_tsapiutils); var tsutils2 = _interopRequireWildcard(_tsapiutils); var tsutils3 = _interopRequireWildcard(_tsapiutils);
|
|
174
|
+
var _tsapiutils = require('ts-api-utils'); var tsutils = _interopRequireWildcard(_tsapiutils); var tsutils2 = _interopRequireWildcard(_tsapiutils); var tsutils3 = _interopRequireWildcard(_tsapiutils); var tsutils4 = _interopRequireWildcard(_tsapiutils);
|
|
170
175
|
|
|
171
176
|
function couldBeType(type, name2, qualified) {
|
|
172
177
|
if (tsutils.isTypeReference(type)) {
|
|
@@ -320,12 +325,18 @@ function isImportNamespaceSpecifier(node) {
|
|
|
320
325
|
function isImportSpecifier(node) {
|
|
321
326
|
return node.type === _utils.AST_NODE_TYPES.ImportSpecifier;
|
|
322
327
|
}
|
|
328
|
+
function isJSXExpressionContainer(node) {
|
|
329
|
+
return node.type === _utils.AST_NODE_TYPES.JSXExpressionContainer;
|
|
330
|
+
}
|
|
323
331
|
function isLiteral(node) {
|
|
324
332
|
return node.type === _utils.AST_NODE_TYPES.Literal;
|
|
325
333
|
}
|
|
326
334
|
function isMemberExpression(node) {
|
|
327
335
|
return node.type === _utils.AST_NODE_TYPES.MemberExpression;
|
|
328
336
|
}
|
|
337
|
+
function isMethodDefinition(node) {
|
|
338
|
+
return node.type === _utils.AST_NODE_TYPES.MethodDefinition;
|
|
339
|
+
}
|
|
329
340
|
function isObjectExpression(node) {
|
|
330
341
|
return node.type === _utils.AST_NODE_TYPES.ObjectExpression;
|
|
331
342
|
}
|
|
@@ -338,6 +349,9 @@ function isProgram(node) {
|
|
|
338
349
|
function isProperty(node) {
|
|
339
350
|
return node.type === _utils.AST_NODE_TYPES.Property;
|
|
340
351
|
}
|
|
352
|
+
function isPropertyDefinition(node) {
|
|
353
|
+
return node.type === _utils.AST_NODE_TYPES.PropertyDefinition;
|
|
354
|
+
}
|
|
341
355
|
function isUnaryExpression(node) {
|
|
342
356
|
return node.type === _utils.AST_NODE_TYPES.UnaryExpression;
|
|
343
357
|
}
|
|
@@ -363,6 +377,7 @@ function getTypeServices(context) {
|
|
|
363
377
|
tsTypeNode = (_a = tsNode.type) != null ? _a : tsNode.body;
|
|
364
378
|
} else if (_typescript2.default.isCallSignatureDeclaration(tsNode) || _typescript2.default.isMethodSignature(tsNode)) {
|
|
365
379
|
tsTypeNode = tsNode.type;
|
|
380
|
+
} else if (_typescript2.default.isPropertySignature(tsNode)) {
|
|
366
381
|
}
|
|
367
382
|
return Boolean(
|
|
368
383
|
tsTypeNode && couldBeType(
|
|
@@ -2086,6 +2101,403 @@ var noInternalRule = ruleCreator({
|
|
|
2086
2101
|
}
|
|
2087
2102
|
});
|
|
2088
2103
|
|
|
2104
|
+
// src/rules/no-misused-observables.ts
|
|
2105
|
+
|
|
2106
|
+
|
|
2107
|
+
|
|
2108
|
+
function parseChecksVoidReturn(checksVoidReturn) {
|
|
2109
|
+
var _a, _b, _c, _d, _e, _f;
|
|
2110
|
+
switch (checksVoidReturn) {
|
|
2111
|
+
case false:
|
|
2112
|
+
return false;
|
|
2113
|
+
case true:
|
|
2114
|
+
case void 0:
|
|
2115
|
+
return {
|
|
2116
|
+
arguments: true,
|
|
2117
|
+
attributes: true,
|
|
2118
|
+
inheritedMethods: true,
|
|
2119
|
+
properties: true,
|
|
2120
|
+
returns: true,
|
|
2121
|
+
variables: true
|
|
2122
|
+
};
|
|
2123
|
+
default:
|
|
2124
|
+
return {
|
|
2125
|
+
arguments: (_a = checksVoidReturn.arguments) != null ? _a : true,
|
|
2126
|
+
attributes: (_b = checksVoidReturn.attributes) != null ? _b : true,
|
|
2127
|
+
inheritedMethods: (_c = checksVoidReturn.inheritedMethods) != null ? _c : true,
|
|
2128
|
+
properties: (_d = checksVoidReturn.properties) != null ? _d : true,
|
|
2129
|
+
returns: (_e = checksVoidReturn.returns) != null ? _e : true,
|
|
2130
|
+
variables: (_f = checksVoidReturn.variables) != null ? _f : true
|
|
2131
|
+
};
|
|
2132
|
+
}
|
|
2133
|
+
}
|
|
2134
|
+
var defaultOptions8 = [];
|
|
2135
|
+
var noMisusedObservablesRule = ruleCreator({
|
|
2136
|
+
defaultOptions: defaultOptions8,
|
|
2137
|
+
meta: {
|
|
2138
|
+
docs: {
|
|
2139
|
+
description: "Disallow Observables in places not designed to handle them.",
|
|
2140
|
+
recommended: "strict",
|
|
2141
|
+
requiresTypeChecking: true
|
|
2142
|
+
},
|
|
2143
|
+
messages: {
|
|
2144
|
+
forbiddenVoidReturnArgument: "Observable returned in function argument where a void return was expected.",
|
|
2145
|
+
forbiddenVoidReturnAttribute: "Observable-returning function provided to attribute where a void return was expected.",
|
|
2146
|
+
forbiddenVoidReturnInheritedMethod: "Observable-returning method provided where a void return was expected by extended/implemented type '{{heritageTypeName}}'.",
|
|
2147
|
+
forbiddenVoidReturnProperty: "Observable-returning function provided to property where a void return was expected.",
|
|
2148
|
+
forbiddenVoidReturnReturnValue: "Observable-returning function provided to return value where a void return was expected.",
|
|
2149
|
+
forbiddenVoidReturnVariable: "Observable-returning function provided to variable where a void return was expected.",
|
|
2150
|
+
forbiddenSpread: "Expected a non-Observable value to be spread into an object."
|
|
2151
|
+
},
|
|
2152
|
+
schema: [
|
|
2153
|
+
{
|
|
2154
|
+
properties: {
|
|
2155
|
+
checksVoidReturn: {
|
|
2156
|
+
default: true,
|
|
2157
|
+
description: "Disallow returning an Observable from a function typed as returning `void`.",
|
|
2158
|
+
oneOf: [
|
|
2159
|
+
{
|
|
2160
|
+
default: true,
|
|
2161
|
+
type: "boolean",
|
|
2162
|
+
description: "Disallow returning an Observable from all types of functions typed as returning `void`."
|
|
2163
|
+
},
|
|
2164
|
+
{
|
|
2165
|
+
type: "object",
|
|
2166
|
+
additionalProperties: false,
|
|
2167
|
+
description: "Which forms of functions may have checking disabled.",
|
|
2168
|
+
properties: {
|
|
2169
|
+
arguments: { type: "boolean", description: "Disallow passing an Observable-returning function as an argument where the parameter type expects a function that returns `void`." },
|
|
2170
|
+
attributes: { type: "boolean", description: "Disallow passing an Observable-returning function as a JSX attribute expected to be a function that returns `void`." },
|
|
2171
|
+
inheritedMethods: { type: "boolean", description: "Disallow providing an Observable-returning function where a function that returns `void` is expected by an extended or implemented type." },
|
|
2172
|
+
properties: { type: "boolean", description: "Disallow providing an Observable-returning function where a function that returns `void` is expected by a property." },
|
|
2173
|
+
returns: { type: "boolean", description: "Disallow returning an Observable-returning function where a function that returns `void` is expected." },
|
|
2174
|
+
variables: { type: "boolean", description: "Disallow assigning or declaring an Observable-returning function where a function that returns `void` is expected." }
|
|
2175
|
+
}
|
|
2176
|
+
}
|
|
2177
|
+
]
|
|
2178
|
+
},
|
|
2179
|
+
checksSpreads: { type: "boolean", default: true, description: "Disallow `...` spreading an Observable." }
|
|
2180
|
+
},
|
|
2181
|
+
type: "object"
|
|
2182
|
+
}
|
|
2183
|
+
],
|
|
2184
|
+
type: "problem"
|
|
2185
|
+
},
|
|
2186
|
+
name: "no-misused-observables",
|
|
2187
|
+
create: (context) => {
|
|
2188
|
+
const { program, esTreeNodeToTSNodeMap, getTypeAtLocation } = _utils.ESLintUtils.getParserServices(context);
|
|
2189
|
+
const checker = program.getTypeChecker();
|
|
2190
|
+
const { couldBeObservable, couldReturnObservable } = getTypeServices(context);
|
|
2191
|
+
const [config = {}] = context.options;
|
|
2192
|
+
const { checksVoidReturn = true, checksSpreads = true } = config;
|
|
2193
|
+
const parsedChecksVoidReturn = parseChecksVoidReturn(checksVoidReturn);
|
|
2194
|
+
const voidReturnChecks = parsedChecksVoidReturn ? {
|
|
2195
|
+
...parsedChecksVoidReturn.arguments && {
|
|
2196
|
+
CallExpression: checkArguments,
|
|
2197
|
+
NewExpression: checkArguments
|
|
2198
|
+
},
|
|
2199
|
+
...parsedChecksVoidReturn.attributes && {
|
|
2200
|
+
JSXAttribute: checkJSXAttribute
|
|
2201
|
+
},
|
|
2202
|
+
...parsedChecksVoidReturn.inheritedMethods && {
|
|
2203
|
+
ClassDeclaration: checkClassLikeOrInterfaceNode,
|
|
2204
|
+
ClassExpression: checkClassLikeOrInterfaceNode,
|
|
2205
|
+
TSInterfaceDeclaration: checkClassLikeOrInterfaceNode
|
|
2206
|
+
},
|
|
2207
|
+
...parsedChecksVoidReturn.properties && {
|
|
2208
|
+
Property: checkProperty
|
|
2209
|
+
},
|
|
2210
|
+
...parsedChecksVoidReturn.returns && {
|
|
2211
|
+
ReturnStatement: checkReturnStatement
|
|
2212
|
+
},
|
|
2213
|
+
...parsedChecksVoidReturn.variables && {
|
|
2214
|
+
AssignmentExpression: checkAssignment,
|
|
2215
|
+
VariableDeclarator: checkVariableDeclaration
|
|
2216
|
+
}
|
|
2217
|
+
} : {};
|
|
2218
|
+
const spreadChecks = {
|
|
2219
|
+
SpreadElement: (node) => {
|
|
2220
|
+
if (couldBeObservable(node.argument)) {
|
|
2221
|
+
context.report({
|
|
2222
|
+
messageId: "forbiddenSpread",
|
|
2223
|
+
node: node.argument
|
|
2224
|
+
});
|
|
2225
|
+
}
|
|
2226
|
+
}
|
|
2227
|
+
};
|
|
2228
|
+
function checkArguments(node) {
|
|
2229
|
+
const tsNode = esTreeNodeToTSNodeMap.get(node);
|
|
2230
|
+
const voidArgs = voidFunctionArguments(checker, tsNode);
|
|
2231
|
+
if (!voidArgs.size) {
|
|
2232
|
+
return;
|
|
2233
|
+
}
|
|
2234
|
+
for (const [index, argument] of node.arguments.entries()) {
|
|
2235
|
+
if (!voidArgs.has(index)) {
|
|
2236
|
+
continue;
|
|
2237
|
+
}
|
|
2238
|
+
if (couldReturnObservable(argument)) {
|
|
2239
|
+
context.report({
|
|
2240
|
+
messageId: "forbiddenVoidReturnArgument",
|
|
2241
|
+
node: argument
|
|
2242
|
+
});
|
|
2243
|
+
}
|
|
2244
|
+
}
|
|
2245
|
+
}
|
|
2246
|
+
function checkJSXAttribute(node) {
|
|
2247
|
+
if (!node.value || !isJSXExpressionContainer(node.value)) {
|
|
2248
|
+
return;
|
|
2249
|
+
}
|
|
2250
|
+
if (couldReturnObservable(node.value.expression)) {
|
|
2251
|
+
context.report({
|
|
2252
|
+
messageId: "forbiddenVoidReturnAttribute",
|
|
2253
|
+
node: node.value
|
|
2254
|
+
});
|
|
2255
|
+
}
|
|
2256
|
+
}
|
|
2257
|
+
function checkClassLikeOrInterfaceNode(node) {
|
|
2258
|
+
var _a;
|
|
2259
|
+
const tsNode = esTreeNodeToTSNodeMap.get(node);
|
|
2260
|
+
const heritageTypes = getHeritageTypes(checker, tsNode);
|
|
2261
|
+
if (!(heritageTypes == null ? void 0 : heritageTypes.length)) {
|
|
2262
|
+
return;
|
|
2263
|
+
}
|
|
2264
|
+
for (const element of node.body.body) {
|
|
2265
|
+
const tsElement = esTreeNodeToTSNodeMap.get(element);
|
|
2266
|
+
const memberName = (_a = tsElement == null ? void 0 : tsElement.name) == null ? void 0 : _a.getText();
|
|
2267
|
+
if (memberName === void 0) {
|
|
2268
|
+
continue;
|
|
2269
|
+
}
|
|
2270
|
+
if (!couldReturnObservable(element)) {
|
|
2271
|
+
continue;
|
|
2272
|
+
}
|
|
2273
|
+
if (isStaticMember(element)) {
|
|
2274
|
+
continue;
|
|
2275
|
+
}
|
|
2276
|
+
for (const heritageType of heritageTypes) {
|
|
2277
|
+
const heritageMember = getMemberIfExists(heritageType, memberName);
|
|
2278
|
+
if (heritageMember === void 0) {
|
|
2279
|
+
continue;
|
|
2280
|
+
}
|
|
2281
|
+
const memberType = checker.getTypeOfSymbolAtLocation(heritageMember, tsElement);
|
|
2282
|
+
if (!isVoidReturningFunctionType(memberType)) {
|
|
2283
|
+
continue;
|
|
2284
|
+
}
|
|
2285
|
+
context.report({
|
|
2286
|
+
messageId: "forbiddenVoidReturnInheritedMethod",
|
|
2287
|
+
node: element,
|
|
2288
|
+
data: { heritageTypeName: checker.typeToString(heritageType) }
|
|
2289
|
+
});
|
|
2290
|
+
}
|
|
2291
|
+
}
|
|
2292
|
+
}
|
|
2293
|
+
function checkProperty(node) {
|
|
2294
|
+
const tsNode = esTreeNodeToTSNodeMap.get(node);
|
|
2295
|
+
const contextualType = getPropertyContextualType(checker, tsNode);
|
|
2296
|
+
if (contextualType === void 0) {
|
|
2297
|
+
return;
|
|
2298
|
+
}
|
|
2299
|
+
if (!isVoidReturningFunctionType(contextualType)) {
|
|
2300
|
+
return;
|
|
2301
|
+
}
|
|
2302
|
+
if (!couldReturnObservable(node.value)) {
|
|
2303
|
+
return;
|
|
2304
|
+
}
|
|
2305
|
+
context.report({
|
|
2306
|
+
messageId: "forbiddenVoidReturnProperty",
|
|
2307
|
+
node: node.value
|
|
2308
|
+
});
|
|
2309
|
+
}
|
|
2310
|
+
function checkReturnStatement(node) {
|
|
2311
|
+
const tsNode = esTreeNodeToTSNodeMap.get(node);
|
|
2312
|
+
if (tsNode.expression === void 0 || !node.argument) {
|
|
2313
|
+
return;
|
|
2314
|
+
}
|
|
2315
|
+
function getFunctionNode() {
|
|
2316
|
+
let current = node.parent;
|
|
2317
|
+
while (current && !isArrowFunctionExpression(current) && !isFunctionExpression(current) && !isFunctionDeclaration(current)) {
|
|
2318
|
+
current = current.parent;
|
|
2319
|
+
}
|
|
2320
|
+
return current;
|
|
2321
|
+
}
|
|
2322
|
+
const functionNode = getFunctionNode();
|
|
2323
|
+
if ((functionNode == null ? void 0 : functionNode.returnType) && !isPossiblyFunctionType(functionNode.returnType)) {
|
|
2324
|
+
return;
|
|
2325
|
+
}
|
|
2326
|
+
const contextualType = checker.getContextualType(tsNode.expression);
|
|
2327
|
+
if (contextualType === void 0) {
|
|
2328
|
+
return;
|
|
2329
|
+
}
|
|
2330
|
+
if (!isVoidReturningFunctionType(contextualType)) {
|
|
2331
|
+
return;
|
|
2332
|
+
}
|
|
2333
|
+
if (!couldReturnObservable(node.argument)) {
|
|
2334
|
+
return;
|
|
2335
|
+
}
|
|
2336
|
+
context.report({
|
|
2337
|
+
node: node.argument,
|
|
2338
|
+
messageId: "forbiddenVoidReturnReturnValue"
|
|
2339
|
+
});
|
|
2340
|
+
}
|
|
2341
|
+
function checkAssignment(node) {
|
|
2342
|
+
const varType = getTypeAtLocation(node.left);
|
|
2343
|
+
if (!isVoidReturningFunctionType(varType)) {
|
|
2344
|
+
return;
|
|
2345
|
+
}
|
|
2346
|
+
if (couldReturnObservable(node.right)) {
|
|
2347
|
+
context.report({
|
|
2348
|
+
messageId: "forbiddenVoidReturnVariable",
|
|
2349
|
+
node: node.right
|
|
2350
|
+
});
|
|
2351
|
+
}
|
|
2352
|
+
}
|
|
2353
|
+
function checkVariableDeclaration(node) {
|
|
2354
|
+
const tsNode = esTreeNodeToTSNodeMap.get(node);
|
|
2355
|
+
if (tsNode.initializer === void 0 || !node.init || !node.id.typeAnnotation) {
|
|
2356
|
+
return;
|
|
2357
|
+
}
|
|
2358
|
+
if (!isPossiblyFunctionType(node.id.typeAnnotation)) {
|
|
2359
|
+
return;
|
|
2360
|
+
}
|
|
2361
|
+
const varType = getTypeAtLocation(node.id);
|
|
2362
|
+
if (!isVoidReturningFunctionType(varType)) {
|
|
2363
|
+
return;
|
|
2364
|
+
}
|
|
2365
|
+
if (couldReturnObservable(node.init)) {
|
|
2366
|
+
context.report({
|
|
2367
|
+
messageId: "forbiddenVoidReturnVariable",
|
|
2368
|
+
node: node.init
|
|
2369
|
+
});
|
|
2370
|
+
}
|
|
2371
|
+
}
|
|
2372
|
+
return {
|
|
2373
|
+
...checksVoidReturn ? voidReturnChecks : {},
|
|
2374
|
+
...checksSpreads ? spreadChecks : {}
|
|
2375
|
+
};
|
|
2376
|
+
}
|
|
2377
|
+
});
|
|
2378
|
+
function voidFunctionArguments(checker, tsNode) {
|
|
2379
|
+
if (!tsNode.arguments) {
|
|
2380
|
+
return /* @__PURE__ */ new Set();
|
|
2381
|
+
}
|
|
2382
|
+
const voidReturnIndices = /* @__PURE__ */ new Set();
|
|
2383
|
+
const type = checker.getTypeAtLocation(tsNode.expression);
|
|
2384
|
+
for (const subType of tsutils2.unionTypeParts(type)) {
|
|
2385
|
+
const signatures = _typescript2.default.isCallExpression(tsNode) ? subType.getCallSignatures() : subType.getConstructSignatures();
|
|
2386
|
+
for (const signature of signatures) {
|
|
2387
|
+
for (const [index, parameter] of signature.parameters.entries()) {
|
|
2388
|
+
const type2 = checker.getTypeOfSymbolAtLocation(parameter, tsNode.expression);
|
|
2389
|
+
if (isVoidReturningFunctionType(type2)) {
|
|
2390
|
+
voidReturnIndices.add(index);
|
|
2391
|
+
}
|
|
2392
|
+
}
|
|
2393
|
+
}
|
|
2394
|
+
}
|
|
2395
|
+
return voidReturnIndices;
|
|
2396
|
+
}
|
|
2397
|
+
function isVoidReturningFunctionType(type) {
|
|
2398
|
+
let hasVoidReturn = false;
|
|
2399
|
+
for (const subType of tsutils2.unionTypeParts(type)) {
|
|
2400
|
+
for (const signature of subType.getCallSignatures()) {
|
|
2401
|
+
const returnType = signature.getReturnType();
|
|
2402
|
+
hasVoidReturn || (hasVoidReturn = tsutils2.isTypeFlagSet(returnType, _typescript2.default.TypeFlags.Void));
|
|
2403
|
+
}
|
|
2404
|
+
}
|
|
2405
|
+
return hasVoidReturn;
|
|
2406
|
+
}
|
|
2407
|
+
function getHeritageTypes(checker, tsNode) {
|
|
2408
|
+
var _a;
|
|
2409
|
+
return (_a = tsNode.heritageClauses) == null ? void 0 : _a.flatMap((clause) => clause.types).map((typeExpressions) => checker.getTypeAtLocation(typeExpressions));
|
|
2410
|
+
}
|
|
2411
|
+
function getMemberIfExists(type, memberName) {
|
|
2412
|
+
var _a, _b;
|
|
2413
|
+
const escapedMemberName = _typescript2.default.escapeLeadingUnderscores(memberName);
|
|
2414
|
+
const symbolMemberMatch = (_b = (_a = type.getSymbol()) == null ? void 0 : _a.members) == null ? void 0 : _b.get(escapedMemberName);
|
|
2415
|
+
return symbolMemberMatch != null ? symbolMemberMatch : tsutils2.getPropertyOfType(type, escapedMemberName);
|
|
2416
|
+
}
|
|
2417
|
+
function isStaticMember(node) {
|
|
2418
|
+
return (isMethodDefinition(node) || isPropertyDefinition(node)) && node.static;
|
|
2419
|
+
}
|
|
2420
|
+
function getPropertyContextualType(checker, tsNode) {
|
|
2421
|
+
if (_typescript2.default.isPropertyAssignment(tsNode)) {
|
|
2422
|
+
return checker.getContextualType(tsNode.initializer);
|
|
2423
|
+
} else if (_typescript2.default.isShorthandPropertyAssignment(tsNode)) {
|
|
2424
|
+
return checker.getContextualType(tsNode.name);
|
|
2425
|
+
} else if (_typescript2.default.isMethodDeclaration(tsNode)) {
|
|
2426
|
+
if (_typescript2.default.isComputedPropertyName(tsNode.name)) {
|
|
2427
|
+
return;
|
|
2428
|
+
}
|
|
2429
|
+
const obj = tsNode.parent;
|
|
2430
|
+
if (!_typescript2.default.isObjectLiteralExpression(obj)) {
|
|
2431
|
+
return;
|
|
2432
|
+
}
|
|
2433
|
+
const objType = checker.getContextualType(obj);
|
|
2434
|
+
if (objType === void 0) {
|
|
2435
|
+
return;
|
|
2436
|
+
}
|
|
2437
|
+
const propertySymbol = checker.getPropertyOfType(objType, tsNode.name.text);
|
|
2438
|
+
if (propertySymbol === void 0) {
|
|
2439
|
+
return;
|
|
2440
|
+
}
|
|
2441
|
+
return checker.getTypeOfSymbolAtLocation(propertySymbol, tsNode.name);
|
|
2442
|
+
} else {
|
|
2443
|
+
return void 0;
|
|
2444
|
+
}
|
|
2445
|
+
}
|
|
2446
|
+
function isPossiblyFunctionType(node) {
|
|
2447
|
+
switch (node.typeAnnotation.type) {
|
|
2448
|
+
case _utils.AST_NODE_TYPES.TSConditionalType:
|
|
2449
|
+
case _utils.AST_NODE_TYPES.TSConstructorType:
|
|
2450
|
+
case _utils.AST_NODE_TYPES.TSFunctionType:
|
|
2451
|
+
case _utils.AST_NODE_TYPES.TSImportType:
|
|
2452
|
+
case _utils.AST_NODE_TYPES.TSIndexedAccessType:
|
|
2453
|
+
case _utils.AST_NODE_TYPES.TSInferType:
|
|
2454
|
+
case _utils.AST_NODE_TYPES.TSIntersectionType:
|
|
2455
|
+
case _utils.AST_NODE_TYPES.TSQualifiedName:
|
|
2456
|
+
case _utils.AST_NODE_TYPES.TSThisType:
|
|
2457
|
+
case _utils.AST_NODE_TYPES.TSTypeOperator:
|
|
2458
|
+
case _utils.AST_NODE_TYPES.TSTypeQuery:
|
|
2459
|
+
case _utils.AST_NODE_TYPES.TSTypeReference:
|
|
2460
|
+
case _utils.AST_NODE_TYPES.TSUnionType:
|
|
2461
|
+
return true;
|
|
2462
|
+
case _utils.AST_NODE_TYPES.TSTypeLiteral:
|
|
2463
|
+
return node.typeAnnotation.members.some(
|
|
2464
|
+
(member) => member.type === _utils.AST_NODE_TYPES.TSCallSignatureDeclaration || member.type === _utils.AST_NODE_TYPES.TSConstructSignatureDeclaration
|
|
2465
|
+
);
|
|
2466
|
+
case _utils.AST_NODE_TYPES.TSAbstractKeyword:
|
|
2467
|
+
case _utils.AST_NODE_TYPES.TSAnyKeyword:
|
|
2468
|
+
case _utils.AST_NODE_TYPES.TSArrayType:
|
|
2469
|
+
case _utils.AST_NODE_TYPES.TSAsyncKeyword:
|
|
2470
|
+
case _utils.AST_NODE_TYPES.TSBigIntKeyword:
|
|
2471
|
+
case _utils.AST_NODE_TYPES.TSBooleanKeyword:
|
|
2472
|
+
case _utils.AST_NODE_TYPES.TSDeclareKeyword:
|
|
2473
|
+
case _utils.AST_NODE_TYPES.TSExportKeyword:
|
|
2474
|
+
case _utils.AST_NODE_TYPES.TSIntrinsicKeyword:
|
|
2475
|
+
case _utils.AST_NODE_TYPES.TSLiteralType:
|
|
2476
|
+
case _utils.AST_NODE_TYPES.TSMappedType:
|
|
2477
|
+
case _utils.AST_NODE_TYPES.TSNamedTupleMember:
|
|
2478
|
+
case _utils.AST_NODE_TYPES.TSNeverKeyword:
|
|
2479
|
+
case _utils.AST_NODE_TYPES.TSNullKeyword:
|
|
2480
|
+
case _utils.AST_NODE_TYPES.TSNumberKeyword:
|
|
2481
|
+
case _utils.AST_NODE_TYPES.TSObjectKeyword:
|
|
2482
|
+
case _utils.AST_NODE_TYPES.TSOptionalType:
|
|
2483
|
+
case _utils.AST_NODE_TYPES.TSPrivateKeyword:
|
|
2484
|
+
case _utils.AST_NODE_TYPES.TSProtectedKeyword:
|
|
2485
|
+
case _utils.AST_NODE_TYPES.TSPublicKeyword:
|
|
2486
|
+
case _utils.AST_NODE_TYPES.TSReadonlyKeyword:
|
|
2487
|
+
case _utils.AST_NODE_TYPES.TSRestType:
|
|
2488
|
+
case _utils.AST_NODE_TYPES.TSStaticKeyword:
|
|
2489
|
+
case _utils.AST_NODE_TYPES.TSStringKeyword:
|
|
2490
|
+
case _utils.AST_NODE_TYPES.TSSymbolKeyword:
|
|
2491
|
+
case _utils.AST_NODE_TYPES.TSTemplateLiteralType:
|
|
2492
|
+
case _utils.AST_NODE_TYPES.TSTupleType:
|
|
2493
|
+
case _utils.AST_NODE_TYPES.TSTypePredicate:
|
|
2494
|
+
case _utils.AST_NODE_TYPES.TSUndefinedKeyword:
|
|
2495
|
+
case _utils.AST_NODE_TYPES.TSUnknownKeyword:
|
|
2496
|
+
case _utils.AST_NODE_TYPES.TSVoidKeyword:
|
|
2497
|
+
return false;
|
|
2498
|
+
}
|
|
2499
|
+
}
|
|
2500
|
+
|
|
2089
2501
|
// src/rules/no-nested-subscribe.ts
|
|
2090
2502
|
var noNestedSubscribeRule = ruleCreator({
|
|
2091
2503
|
defaultOptions: [],
|
|
@@ -2209,9 +2621,9 @@ function isExpressionObserver(expressionStatement, couldBeType2) {
|
|
|
2209
2621
|
|
|
2210
2622
|
// src/rules/no-sharereplay.ts
|
|
2211
2623
|
|
|
2212
|
-
var
|
|
2624
|
+
var defaultOptions9 = [];
|
|
2213
2625
|
var noSharereplayRule = ruleCreator({
|
|
2214
|
-
defaultOptions:
|
|
2626
|
+
defaultOptions: defaultOptions9,
|
|
2215
2627
|
meta: {
|
|
2216
2628
|
docs: {
|
|
2217
2629
|
description: "Disallow unsafe `shareReplay` usage.",
|
|
@@ -2404,6 +2816,53 @@ var noSubscribeHandlersRule = ruleCreator({
|
|
|
2404
2816
|
}
|
|
2405
2817
|
});
|
|
2406
2818
|
|
|
2819
|
+
// src/rules/no-subscribe-in-pipe.ts
|
|
2820
|
+
|
|
2821
|
+
var noSubscribeInPipeRule = ruleCreator({
|
|
2822
|
+
defaultOptions: [],
|
|
2823
|
+
meta: {
|
|
2824
|
+
docs: {
|
|
2825
|
+
description: "Disallow calling of `subscribe` within any RxJS operator inside a `pipe`.",
|
|
2826
|
+
recommended: "recommended",
|
|
2827
|
+
requiresTypeChecking: true
|
|
2828
|
+
},
|
|
2829
|
+
fixable: void 0,
|
|
2830
|
+
hasSuggestions: false,
|
|
2831
|
+
messages: {
|
|
2832
|
+
forbidden: "Subscribe calls within pipe operators are forbidden."
|
|
2833
|
+
},
|
|
2834
|
+
schema: [],
|
|
2835
|
+
type: "problem"
|
|
2836
|
+
},
|
|
2837
|
+
name: "no-subscribe-in-pipe",
|
|
2838
|
+
create: (context) => {
|
|
2839
|
+
const { couldBeObservable, couldBeType: couldBeType2 } = getTypeServices(context);
|
|
2840
|
+
function isWithinPipe(node) {
|
|
2841
|
+
let parent = node.parent;
|
|
2842
|
+
while (parent) {
|
|
2843
|
+
if (parent.type === _utils.AST_NODE_TYPES.CallExpression && parent.callee.type === _utils.AST_NODE_TYPES.MemberExpression && parent.callee.property.type === _utils.AST_NODE_TYPES.Identifier && parent.callee.property.name === "pipe") {
|
|
2844
|
+
return true;
|
|
2845
|
+
}
|
|
2846
|
+
parent = parent.parent;
|
|
2847
|
+
}
|
|
2848
|
+
return false;
|
|
2849
|
+
}
|
|
2850
|
+
return {
|
|
2851
|
+
"CallExpression > MemberExpression[property.name='subscribe']": (node) => {
|
|
2852
|
+
if (!couldBeObservable(node.object) && !couldBeType2(node.object, "Subscribable")) {
|
|
2853
|
+
return;
|
|
2854
|
+
}
|
|
2855
|
+
if (isWithinPipe(node)) {
|
|
2856
|
+
context.report({
|
|
2857
|
+
messageId: "forbidden",
|
|
2858
|
+
node: node.property
|
|
2859
|
+
});
|
|
2860
|
+
}
|
|
2861
|
+
}
|
|
2862
|
+
};
|
|
2863
|
+
}
|
|
2864
|
+
});
|
|
2865
|
+
|
|
2407
2866
|
// src/rules/no-tap.ts
|
|
2408
2867
|
var noTapRule = ruleCreator({
|
|
2409
2868
|
defaultOptions: [],
|
|
@@ -2599,9 +3058,9 @@ var noUnboundMethodsRule = ruleCreator({
|
|
|
2599
3058
|
|
|
2600
3059
|
// src/rules/no-unsafe-catch.ts
|
|
2601
3060
|
|
|
2602
|
-
var
|
|
3061
|
+
var defaultOptions10 = [];
|
|
2603
3062
|
var noUnsafeCatchRule = ruleCreator({
|
|
2604
|
-
defaultOptions:
|
|
3063
|
+
defaultOptions: defaultOptions10,
|
|
2605
3064
|
meta: {
|
|
2606
3065
|
docs: {
|
|
2607
3066
|
description: "Disallow unsafe `catchError` usage in effects and epics.",
|
|
@@ -2660,9 +3119,9 @@ var noUnsafeCatchRule = ruleCreator({
|
|
|
2660
3119
|
|
|
2661
3120
|
// src/rules/no-unsafe-first.ts
|
|
2662
3121
|
|
|
2663
|
-
var
|
|
3122
|
+
var defaultOptions11 = [];
|
|
2664
3123
|
var noUnsafeFirstRule = ruleCreator({
|
|
2665
|
-
defaultOptions:
|
|
3124
|
+
defaultOptions: defaultOptions11,
|
|
2666
3125
|
meta: {
|
|
2667
3126
|
docs: {
|
|
2668
3127
|
description: "Disallow unsafe `first`/`take` usage in effects and epics.",
|
|
@@ -2754,19 +3213,19 @@ var noUnsafeSubjectNext = ruleCreator({
|
|
|
2754
3213
|
[`CallExpression[callee.property.name='next']`]: (node) => {
|
|
2755
3214
|
if (node.arguments.length === 0 && isMemberExpression(node.callee)) {
|
|
2756
3215
|
const type = getTypeAtLocation(node.callee.object);
|
|
2757
|
-
if (
|
|
3216
|
+
if (tsutils3.isTypeReference(type) && couldBeType(type, "Subject")) {
|
|
2758
3217
|
const [typeArg] = typeChecker.getTypeArguments(type);
|
|
2759
|
-
if (
|
|
3218
|
+
if (tsutils3.isTypeFlagSet(typeArg, _typescript2.default.TypeFlags.Any)) {
|
|
2760
3219
|
return;
|
|
2761
3220
|
}
|
|
2762
|
-
if (
|
|
3221
|
+
if (tsutils3.isTypeFlagSet(typeArg, _typescript2.default.TypeFlags.Unknown)) {
|
|
2763
3222
|
return;
|
|
2764
3223
|
}
|
|
2765
|
-
if (
|
|
3224
|
+
if (tsutils3.isTypeFlagSet(typeArg, _typescript2.default.TypeFlags.Void)) {
|
|
2766
3225
|
return;
|
|
2767
3226
|
}
|
|
2768
|
-
if (
|
|
2769
|
-
(t) =>
|
|
3227
|
+
if (tsutils3.isUnionType(typeArg) && typeArg.types.some(
|
|
3228
|
+
(t) => tsutils3.isTypeFlagSet(t, _typescript2.default.TypeFlags.Void)
|
|
2770
3229
|
)) {
|
|
2771
3230
|
return;
|
|
2772
3231
|
}
|
|
@@ -2784,9 +3243,9 @@ var noUnsafeSubjectNext = ruleCreator({
|
|
|
2784
3243
|
// src/rules/no-unsafe-switchmap.ts
|
|
2785
3244
|
|
|
2786
3245
|
var _decamelize = require('decamelize'); var _decamelize2 = _interopRequireDefault(_decamelize);
|
|
2787
|
-
var
|
|
3246
|
+
var defaultOptions12 = [];
|
|
2788
3247
|
var noUnsafeSwitchmapRule = ruleCreator({
|
|
2789
|
-
defaultOptions:
|
|
3248
|
+
defaultOptions: defaultOptions12,
|
|
2790
3249
|
meta: {
|
|
2791
3250
|
docs: {
|
|
2792
3251
|
description: "Disallow unsafe `switchMap` usage in effects and epics.",
|
|
@@ -2909,7 +3368,7 @@ var noUnsafeSwitchmapRule = ruleCreator({
|
|
|
2909
3368
|
|
|
2910
3369
|
// src/rules/no-unsafe-takeuntil.ts
|
|
2911
3370
|
|
|
2912
|
-
var
|
|
3371
|
+
var defaultOptions13 = [];
|
|
2913
3372
|
var allowedOperators = [
|
|
2914
3373
|
"count",
|
|
2915
3374
|
"defaultIfEmpty",
|
|
@@ -2934,7 +3393,7 @@ var allowedOperators = [
|
|
|
2934
3393
|
"toArray"
|
|
2935
3394
|
];
|
|
2936
3395
|
var noUnsafeTakeuntilRule = ruleCreator({
|
|
2937
|
-
defaultOptions:
|
|
3396
|
+
defaultOptions: defaultOptions13,
|
|
2938
3397
|
meta: {
|
|
2939
3398
|
docs: {
|
|
2940
3399
|
description: "Disallow applying operators after `takeUntil`.",
|
|
@@ -3013,9 +3472,9 @@ var noUnsafeTakeuntilRule = ruleCreator({
|
|
|
3013
3472
|
});
|
|
3014
3473
|
|
|
3015
3474
|
// src/rules/prefer-observer.ts
|
|
3016
|
-
var
|
|
3475
|
+
var defaultOptions14 = [];
|
|
3017
3476
|
var preferObserverRule = ruleCreator({
|
|
3018
|
-
defaultOptions:
|
|
3477
|
+
defaultOptions: defaultOptions14,
|
|
3019
3478
|
meta: {
|
|
3020
3479
|
docs: {
|
|
3021
3480
|
description: "Disallow passing separate handlers to `subscribe` and `tap`.",
|
|
@@ -3251,9 +3710,9 @@ var preferRootOperatorsRule = ruleCreator({
|
|
|
3251
3710
|
|
|
3252
3711
|
// src/rules/suffix-subjects.ts
|
|
3253
3712
|
|
|
3254
|
-
var
|
|
3713
|
+
var defaultOptions15 = [];
|
|
3255
3714
|
var suffixSubjectsRule = ruleCreator({
|
|
3256
|
-
defaultOptions:
|
|
3715
|
+
defaultOptions: defaultOptions15,
|
|
3257
3716
|
meta: {
|
|
3258
3717
|
docs: {
|
|
3259
3718
|
description: "Enforce the use of a suffix in subject identifiers.",
|
|
@@ -3450,9 +3909,9 @@ var suffixSubjectsRule = ruleCreator({
|
|
|
3450
3909
|
// src/rules/throw-error.ts
|
|
3451
3910
|
|
|
3452
3911
|
|
|
3453
|
-
var
|
|
3912
|
+
var defaultOptions16 = [];
|
|
3454
3913
|
var throwErrorRule = ruleCreator({
|
|
3455
|
-
defaultOptions:
|
|
3914
|
+
defaultOptions: defaultOptions16,
|
|
3456
3915
|
meta: {
|
|
3457
3916
|
docs: {
|
|
3458
3917
|
description: "Enforce passing only `Error` values to `throwError`.",
|
|
@@ -3493,10 +3952,10 @@ var throwErrorRule = ruleCreator({
|
|
|
3493
3952
|
const body = tsNode.body;
|
|
3494
3953
|
type = program.getTypeChecker().getTypeAtLocation(annotation != null ? annotation : body);
|
|
3495
3954
|
}
|
|
3496
|
-
if (allowThrowingAny &&
|
|
3955
|
+
if (allowThrowingAny && tsutils4.isIntrinsicAnyType(type)) {
|
|
3497
3956
|
return;
|
|
3498
3957
|
}
|
|
3499
|
-
if (allowThrowingUnknown &&
|
|
3958
|
+
if (allowThrowingUnknown && tsutils4.isIntrinsicUnknownType(type)) {
|
|
3500
3959
|
return;
|
|
3501
3960
|
}
|
|
3502
3961
|
if (couldBeType(type, /^Error$/)) {
|
|
@@ -3554,6 +4013,7 @@ var plugin = {
|
|
|
3554
4013
|
"no-implicit-any-catch": noImplicitAnyCatchRule,
|
|
3555
4014
|
"no-index": noIndexRule,
|
|
3556
4015
|
"no-internal": noInternalRule,
|
|
4016
|
+
"no-misused-observables": noMisusedObservablesRule,
|
|
3557
4017
|
"no-nested-subscribe": noNestedSubscribeRule,
|
|
3558
4018
|
"no-redundant-notify": noRedundantNotifyRule,
|
|
3559
4019
|
"no-sharereplay": noSharereplayRule,
|
|
@@ -3561,6 +4021,7 @@ var plugin = {
|
|
|
3561
4021
|
"no-subject-unsubscribe": noSubjectUnsubscribeRule,
|
|
3562
4022
|
"no-subject-value": noSubjectValueRule,
|
|
3563
4023
|
"no-subscribe-handlers": noSubscribeHandlersRule,
|
|
4024
|
+
"no-subscribe-in-pipe": noSubscribeInPipeRule,
|
|
3564
4025
|
"no-tap": noTapRule,
|
|
3565
4026
|
"no-topromise": noTopromiseRule,
|
|
3566
4027
|
"no-unbound-methods": noUnboundMethodsRule,
|