eslint-plugin-rxjs-x 0.5.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/index.d.mts +16 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +437 -26
- package/dist/index.mjs +451 -40
- package/docs/rules/no-floating-observables.md +1 -0
- package/docs/rules/no-misused-observables.md +85 -0
- package/package.json +10 -8
package/dist/index.mjs
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
// package.json
|
|
2
2
|
var name = "eslint-plugin-rxjs-x";
|
|
3
|
-
var version = "0.5.
|
|
3
|
+
var version = "0.5.1";
|
|
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
|
},
|
|
@@ -32,6 +33,7 @@ var createRecommendedConfig = (plugin2) => ({
|
|
|
32
33
|
|
|
33
34
|
// src/configs/strict.ts
|
|
34
35
|
var createStrictConfig = (plugin2) => ({
|
|
36
|
+
name: "rxjs-x/strict",
|
|
35
37
|
plugins: {
|
|
36
38
|
"rxjs-x": plugin2
|
|
37
39
|
},
|
|
@@ -51,6 +53,7 @@ var createStrictConfig = (plugin2) => ({
|
|
|
51
53
|
}],
|
|
52
54
|
"rxjs-x/no-index": "error",
|
|
53
55
|
"rxjs-x/no-internal": "error",
|
|
56
|
+
"rxjs-x/no-misused-observables": "error",
|
|
54
57
|
"rxjs-x/no-nested-subscribe": "error",
|
|
55
58
|
"rxjs-x/no-redundant-notify": "error",
|
|
56
59
|
"rxjs-x/no-sharereplay": "error",
|
|
@@ -320,12 +323,18 @@ function isImportNamespaceSpecifier(node) {
|
|
|
320
323
|
function isImportSpecifier(node) {
|
|
321
324
|
return node.type === AST_NODE_TYPES2.ImportSpecifier;
|
|
322
325
|
}
|
|
326
|
+
function isJSXExpressionContainer(node) {
|
|
327
|
+
return node.type === AST_NODE_TYPES2.JSXExpressionContainer;
|
|
328
|
+
}
|
|
323
329
|
function isLiteral(node) {
|
|
324
330
|
return node.type === AST_NODE_TYPES2.Literal;
|
|
325
331
|
}
|
|
326
332
|
function isMemberExpression(node) {
|
|
327
333
|
return node.type === AST_NODE_TYPES2.MemberExpression;
|
|
328
334
|
}
|
|
335
|
+
function isMethodDefinition(node) {
|
|
336
|
+
return node.type === AST_NODE_TYPES2.MethodDefinition;
|
|
337
|
+
}
|
|
329
338
|
function isObjectExpression(node) {
|
|
330
339
|
return node.type === AST_NODE_TYPES2.ObjectExpression;
|
|
331
340
|
}
|
|
@@ -338,6 +347,9 @@ function isProgram(node) {
|
|
|
338
347
|
function isProperty(node) {
|
|
339
348
|
return node.type === AST_NODE_TYPES2.Property;
|
|
340
349
|
}
|
|
350
|
+
function isPropertyDefinition(node) {
|
|
351
|
+
return node.type === AST_NODE_TYPES2.PropertyDefinition;
|
|
352
|
+
}
|
|
341
353
|
function isUnaryExpression(node) {
|
|
342
354
|
return node.type === AST_NODE_TYPES2.UnaryExpression;
|
|
343
355
|
}
|
|
@@ -363,6 +375,7 @@ function getTypeServices(context) {
|
|
|
363
375
|
tsTypeNode = (_a = tsNode.type) != null ? _a : tsNode.body;
|
|
364
376
|
} else if (ts4.isCallSignatureDeclaration(tsNode) || ts4.isMethodSignature(tsNode)) {
|
|
365
377
|
tsTypeNode = tsNode.type;
|
|
378
|
+
} else if (ts4.isPropertySignature(tsNode)) {
|
|
366
379
|
}
|
|
367
380
|
return Boolean(
|
|
368
381
|
tsTypeNode && couldBeType(
|
|
@@ -2086,6 +2099,403 @@ var noInternalRule = ruleCreator({
|
|
|
2086
2099
|
}
|
|
2087
2100
|
});
|
|
2088
2101
|
|
|
2102
|
+
// src/rules/no-misused-observables.ts
|
|
2103
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES6, ESLintUtils as ESLintUtils8 } from "@typescript-eslint/utils";
|
|
2104
|
+
import * as tsutils2 from "ts-api-utils";
|
|
2105
|
+
import ts6 from "typescript";
|
|
2106
|
+
function parseChecksVoidReturn(checksVoidReturn) {
|
|
2107
|
+
var _a, _b, _c, _d, _e, _f;
|
|
2108
|
+
switch (checksVoidReturn) {
|
|
2109
|
+
case false:
|
|
2110
|
+
return false;
|
|
2111
|
+
case true:
|
|
2112
|
+
case void 0:
|
|
2113
|
+
return {
|
|
2114
|
+
arguments: true,
|
|
2115
|
+
attributes: true,
|
|
2116
|
+
inheritedMethods: true,
|
|
2117
|
+
properties: true,
|
|
2118
|
+
returns: true,
|
|
2119
|
+
variables: true
|
|
2120
|
+
};
|
|
2121
|
+
default:
|
|
2122
|
+
return {
|
|
2123
|
+
arguments: (_a = checksVoidReturn.arguments) != null ? _a : true,
|
|
2124
|
+
attributes: (_b = checksVoidReturn.attributes) != null ? _b : true,
|
|
2125
|
+
inheritedMethods: (_c = checksVoidReturn.inheritedMethods) != null ? _c : true,
|
|
2126
|
+
properties: (_d = checksVoidReturn.properties) != null ? _d : true,
|
|
2127
|
+
returns: (_e = checksVoidReturn.returns) != null ? _e : true,
|
|
2128
|
+
variables: (_f = checksVoidReturn.variables) != null ? _f : true
|
|
2129
|
+
};
|
|
2130
|
+
}
|
|
2131
|
+
}
|
|
2132
|
+
var defaultOptions8 = [];
|
|
2133
|
+
var noMisusedObservablesRule = ruleCreator({
|
|
2134
|
+
defaultOptions: defaultOptions8,
|
|
2135
|
+
meta: {
|
|
2136
|
+
docs: {
|
|
2137
|
+
description: "Disallow Observables in places not designed to handle them.",
|
|
2138
|
+
recommended: "strict",
|
|
2139
|
+
requiresTypeChecking: true
|
|
2140
|
+
},
|
|
2141
|
+
messages: {
|
|
2142
|
+
forbiddenVoidReturnArgument: "Observable returned in function argument where a void return was expected.",
|
|
2143
|
+
forbiddenVoidReturnAttribute: "Observable-returning function provided to attribute where a void return was expected.",
|
|
2144
|
+
forbiddenVoidReturnInheritedMethod: "Observable-returning method provided where a void return was expected by extended/implemented type '{{heritageTypeName}}'.",
|
|
2145
|
+
forbiddenVoidReturnProperty: "Observable-returning function provided to property where a void return was expected.",
|
|
2146
|
+
forbiddenVoidReturnReturnValue: "Observable-returning function provided to return value where a void return was expected.",
|
|
2147
|
+
forbiddenVoidReturnVariable: "Observable-returning function provided to variable where a void return was expected.",
|
|
2148
|
+
forbiddenSpread: "Expected a non-Observable value to be spread into an object."
|
|
2149
|
+
},
|
|
2150
|
+
schema: [
|
|
2151
|
+
{
|
|
2152
|
+
properties: {
|
|
2153
|
+
checksVoidReturn: {
|
|
2154
|
+
default: true,
|
|
2155
|
+
description: "Disallow returning an Observable from a function typed as returning `void`.",
|
|
2156
|
+
oneOf: [
|
|
2157
|
+
{
|
|
2158
|
+
default: true,
|
|
2159
|
+
type: "boolean",
|
|
2160
|
+
description: "Disallow returning an Observable from all types of functions typed as returning `void`."
|
|
2161
|
+
},
|
|
2162
|
+
{
|
|
2163
|
+
type: "object",
|
|
2164
|
+
additionalProperties: false,
|
|
2165
|
+
description: "Which forms of functions may have checking disabled.",
|
|
2166
|
+
properties: {
|
|
2167
|
+
arguments: { type: "boolean", description: "Disallow passing an Observable-returning function as an argument where the parameter type expects a function that returns `void`." },
|
|
2168
|
+
attributes: { type: "boolean", description: "Disallow passing an Observable-returning function as a JSX attribute expected to be a function that returns `void`." },
|
|
2169
|
+
inheritedMethods: { type: "boolean", description: "Disallow providing an Observable-returning function where a function that returns `void` is expected by an extended or implemented type." },
|
|
2170
|
+
properties: { type: "boolean", description: "Disallow providing an Observable-returning function where a function that returns `void` is expected by a property." },
|
|
2171
|
+
returns: { type: "boolean", description: "Disallow returning an Observable-returning function where a function that returns `void` is expected." },
|
|
2172
|
+
variables: { type: "boolean", description: "Disallow assigning or declaring an Observable-returning function where a function that returns `void` is expected." }
|
|
2173
|
+
}
|
|
2174
|
+
}
|
|
2175
|
+
]
|
|
2176
|
+
},
|
|
2177
|
+
checksSpreads: { type: "boolean", default: true, description: "Disallow `...` spreading an Observable." }
|
|
2178
|
+
},
|
|
2179
|
+
type: "object"
|
|
2180
|
+
}
|
|
2181
|
+
],
|
|
2182
|
+
type: "problem"
|
|
2183
|
+
},
|
|
2184
|
+
name: "no-misused-observables",
|
|
2185
|
+
create: (context) => {
|
|
2186
|
+
const { program, esTreeNodeToTSNodeMap, getTypeAtLocation } = ESLintUtils8.getParserServices(context);
|
|
2187
|
+
const checker = program.getTypeChecker();
|
|
2188
|
+
const { couldBeObservable, couldReturnObservable } = getTypeServices(context);
|
|
2189
|
+
const [config = {}] = context.options;
|
|
2190
|
+
const { checksVoidReturn = true, checksSpreads = true } = config;
|
|
2191
|
+
const parsedChecksVoidReturn = parseChecksVoidReturn(checksVoidReturn);
|
|
2192
|
+
const voidReturnChecks = parsedChecksVoidReturn ? {
|
|
2193
|
+
...parsedChecksVoidReturn.arguments && {
|
|
2194
|
+
CallExpression: checkArguments,
|
|
2195
|
+
NewExpression: checkArguments
|
|
2196
|
+
},
|
|
2197
|
+
...parsedChecksVoidReturn.attributes && {
|
|
2198
|
+
JSXAttribute: checkJSXAttribute
|
|
2199
|
+
},
|
|
2200
|
+
...parsedChecksVoidReturn.inheritedMethods && {
|
|
2201
|
+
ClassDeclaration: checkClassLikeOrInterfaceNode,
|
|
2202
|
+
ClassExpression: checkClassLikeOrInterfaceNode,
|
|
2203
|
+
TSInterfaceDeclaration: checkClassLikeOrInterfaceNode
|
|
2204
|
+
},
|
|
2205
|
+
...parsedChecksVoidReturn.properties && {
|
|
2206
|
+
Property: checkProperty
|
|
2207
|
+
},
|
|
2208
|
+
...parsedChecksVoidReturn.returns && {
|
|
2209
|
+
ReturnStatement: checkReturnStatement
|
|
2210
|
+
},
|
|
2211
|
+
...parsedChecksVoidReturn.variables && {
|
|
2212
|
+
AssignmentExpression: checkAssignment,
|
|
2213
|
+
VariableDeclarator: checkVariableDeclaration
|
|
2214
|
+
}
|
|
2215
|
+
} : {};
|
|
2216
|
+
const spreadChecks = {
|
|
2217
|
+
SpreadElement: (node) => {
|
|
2218
|
+
if (couldBeObservable(node.argument)) {
|
|
2219
|
+
context.report({
|
|
2220
|
+
messageId: "forbiddenSpread",
|
|
2221
|
+
node: node.argument
|
|
2222
|
+
});
|
|
2223
|
+
}
|
|
2224
|
+
}
|
|
2225
|
+
};
|
|
2226
|
+
function checkArguments(node) {
|
|
2227
|
+
const tsNode = esTreeNodeToTSNodeMap.get(node);
|
|
2228
|
+
const voidArgs = voidFunctionArguments(checker, tsNode);
|
|
2229
|
+
if (!voidArgs.size) {
|
|
2230
|
+
return;
|
|
2231
|
+
}
|
|
2232
|
+
for (const [index, argument] of node.arguments.entries()) {
|
|
2233
|
+
if (!voidArgs.has(index)) {
|
|
2234
|
+
continue;
|
|
2235
|
+
}
|
|
2236
|
+
if (couldReturnObservable(argument)) {
|
|
2237
|
+
context.report({
|
|
2238
|
+
messageId: "forbiddenVoidReturnArgument",
|
|
2239
|
+
node: argument
|
|
2240
|
+
});
|
|
2241
|
+
}
|
|
2242
|
+
}
|
|
2243
|
+
}
|
|
2244
|
+
function checkJSXAttribute(node) {
|
|
2245
|
+
if (!node.value || !isJSXExpressionContainer(node.value)) {
|
|
2246
|
+
return;
|
|
2247
|
+
}
|
|
2248
|
+
if (couldReturnObservable(node.value.expression)) {
|
|
2249
|
+
context.report({
|
|
2250
|
+
messageId: "forbiddenVoidReturnAttribute",
|
|
2251
|
+
node: node.value
|
|
2252
|
+
});
|
|
2253
|
+
}
|
|
2254
|
+
}
|
|
2255
|
+
function checkClassLikeOrInterfaceNode(node) {
|
|
2256
|
+
var _a;
|
|
2257
|
+
const tsNode = esTreeNodeToTSNodeMap.get(node);
|
|
2258
|
+
const heritageTypes = getHeritageTypes(checker, tsNode);
|
|
2259
|
+
if (!(heritageTypes == null ? void 0 : heritageTypes.length)) {
|
|
2260
|
+
return;
|
|
2261
|
+
}
|
|
2262
|
+
for (const element of node.body.body) {
|
|
2263
|
+
const tsElement = esTreeNodeToTSNodeMap.get(element);
|
|
2264
|
+
const memberName = (_a = tsElement == null ? void 0 : tsElement.name) == null ? void 0 : _a.getText();
|
|
2265
|
+
if (memberName === void 0) {
|
|
2266
|
+
continue;
|
|
2267
|
+
}
|
|
2268
|
+
if (!couldReturnObservable(element)) {
|
|
2269
|
+
continue;
|
|
2270
|
+
}
|
|
2271
|
+
if (isStaticMember(element)) {
|
|
2272
|
+
continue;
|
|
2273
|
+
}
|
|
2274
|
+
for (const heritageType of heritageTypes) {
|
|
2275
|
+
const heritageMember = getMemberIfExists(heritageType, memberName);
|
|
2276
|
+
if (heritageMember === void 0) {
|
|
2277
|
+
continue;
|
|
2278
|
+
}
|
|
2279
|
+
const memberType = checker.getTypeOfSymbolAtLocation(heritageMember, tsElement);
|
|
2280
|
+
if (!isVoidReturningFunctionType(memberType)) {
|
|
2281
|
+
continue;
|
|
2282
|
+
}
|
|
2283
|
+
context.report({
|
|
2284
|
+
messageId: "forbiddenVoidReturnInheritedMethod",
|
|
2285
|
+
node: element,
|
|
2286
|
+
data: { heritageTypeName: checker.typeToString(heritageType) }
|
|
2287
|
+
});
|
|
2288
|
+
}
|
|
2289
|
+
}
|
|
2290
|
+
}
|
|
2291
|
+
function checkProperty(node) {
|
|
2292
|
+
const tsNode = esTreeNodeToTSNodeMap.get(node);
|
|
2293
|
+
const contextualType = getPropertyContextualType(checker, tsNode);
|
|
2294
|
+
if (contextualType === void 0) {
|
|
2295
|
+
return;
|
|
2296
|
+
}
|
|
2297
|
+
if (!isVoidReturningFunctionType(contextualType)) {
|
|
2298
|
+
return;
|
|
2299
|
+
}
|
|
2300
|
+
if (!couldReturnObservable(node.value)) {
|
|
2301
|
+
return;
|
|
2302
|
+
}
|
|
2303
|
+
context.report({
|
|
2304
|
+
messageId: "forbiddenVoidReturnProperty",
|
|
2305
|
+
node: node.value
|
|
2306
|
+
});
|
|
2307
|
+
}
|
|
2308
|
+
function checkReturnStatement(node) {
|
|
2309
|
+
const tsNode = esTreeNodeToTSNodeMap.get(node);
|
|
2310
|
+
if (tsNode.expression === void 0 || !node.argument) {
|
|
2311
|
+
return;
|
|
2312
|
+
}
|
|
2313
|
+
function getFunctionNode() {
|
|
2314
|
+
let current = node.parent;
|
|
2315
|
+
while (current && !isArrowFunctionExpression(current) && !isFunctionExpression(current) && !isFunctionDeclaration(current)) {
|
|
2316
|
+
current = current.parent;
|
|
2317
|
+
}
|
|
2318
|
+
return current;
|
|
2319
|
+
}
|
|
2320
|
+
const functionNode = getFunctionNode();
|
|
2321
|
+
if ((functionNode == null ? void 0 : functionNode.returnType) && !isPossiblyFunctionType(functionNode.returnType)) {
|
|
2322
|
+
return;
|
|
2323
|
+
}
|
|
2324
|
+
const contextualType = checker.getContextualType(tsNode.expression);
|
|
2325
|
+
if (contextualType === void 0) {
|
|
2326
|
+
return;
|
|
2327
|
+
}
|
|
2328
|
+
if (!isVoidReturningFunctionType(contextualType)) {
|
|
2329
|
+
return;
|
|
2330
|
+
}
|
|
2331
|
+
if (!couldReturnObservable(node.argument)) {
|
|
2332
|
+
return;
|
|
2333
|
+
}
|
|
2334
|
+
context.report({
|
|
2335
|
+
node: node.argument,
|
|
2336
|
+
messageId: "forbiddenVoidReturnReturnValue"
|
|
2337
|
+
});
|
|
2338
|
+
}
|
|
2339
|
+
function checkAssignment(node) {
|
|
2340
|
+
const varType = getTypeAtLocation(node.left);
|
|
2341
|
+
if (!isVoidReturningFunctionType(varType)) {
|
|
2342
|
+
return;
|
|
2343
|
+
}
|
|
2344
|
+
if (couldReturnObservable(node.right)) {
|
|
2345
|
+
context.report({
|
|
2346
|
+
messageId: "forbiddenVoidReturnVariable",
|
|
2347
|
+
node: node.right
|
|
2348
|
+
});
|
|
2349
|
+
}
|
|
2350
|
+
}
|
|
2351
|
+
function checkVariableDeclaration(node) {
|
|
2352
|
+
const tsNode = esTreeNodeToTSNodeMap.get(node);
|
|
2353
|
+
if (tsNode.initializer === void 0 || !node.init || !node.id.typeAnnotation) {
|
|
2354
|
+
return;
|
|
2355
|
+
}
|
|
2356
|
+
if (!isPossiblyFunctionType(node.id.typeAnnotation)) {
|
|
2357
|
+
return;
|
|
2358
|
+
}
|
|
2359
|
+
const varType = getTypeAtLocation(node.id);
|
|
2360
|
+
if (!isVoidReturningFunctionType(varType)) {
|
|
2361
|
+
return;
|
|
2362
|
+
}
|
|
2363
|
+
if (couldReturnObservable(node.init)) {
|
|
2364
|
+
context.report({
|
|
2365
|
+
messageId: "forbiddenVoidReturnVariable",
|
|
2366
|
+
node: node.init
|
|
2367
|
+
});
|
|
2368
|
+
}
|
|
2369
|
+
}
|
|
2370
|
+
return {
|
|
2371
|
+
...checksVoidReturn ? voidReturnChecks : {},
|
|
2372
|
+
...checksSpreads ? spreadChecks : {}
|
|
2373
|
+
};
|
|
2374
|
+
}
|
|
2375
|
+
});
|
|
2376
|
+
function voidFunctionArguments(checker, tsNode) {
|
|
2377
|
+
if (!tsNode.arguments) {
|
|
2378
|
+
return /* @__PURE__ */ new Set();
|
|
2379
|
+
}
|
|
2380
|
+
const voidReturnIndices = /* @__PURE__ */ new Set();
|
|
2381
|
+
const type = checker.getTypeAtLocation(tsNode.expression);
|
|
2382
|
+
for (const subType of tsutils2.unionTypeParts(type)) {
|
|
2383
|
+
const signatures = ts6.isCallExpression(tsNode) ? subType.getCallSignatures() : subType.getConstructSignatures();
|
|
2384
|
+
for (const signature of signatures) {
|
|
2385
|
+
for (const [index, parameter] of signature.parameters.entries()) {
|
|
2386
|
+
const type2 = checker.getTypeOfSymbolAtLocation(parameter, tsNode.expression);
|
|
2387
|
+
if (isVoidReturningFunctionType(type2)) {
|
|
2388
|
+
voidReturnIndices.add(index);
|
|
2389
|
+
}
|
|
2390
|
+
}
|
|
2391
|
+
}
|
|
2392
|
+
}
|
|
2393
|
+
return voidReturnIndices;
|
|
2394
|
+
}
|
|
2395
|
+
function isVoidReturningFunctionType(type) {
|
|
2396
|
+
let hasVoidReturn = false;
|
|
2397
|
+
for (const subType of tsutils2.unionTypeParts(type)) {
|
|
2398
|
+
for (const signature of subType.getCallSignatures()) {
|
|
2399
|
+
const returnType = signature.getReturnType();
|
|
2400
|
+
hasVoidReturn || (hasVoidReturn = tsutils2.isTypeFlagSet(returnType, ts6.TypeFlags.Void));
|
|
2401
|
+
}
|
|
2402
|
+
}
|
|
2403
|
+
return hasVoidReturn;
|
|
2404
|
+
}
|
|
2405
|
+
function getHeritageTypes(checker, tsNode) {
|
|
2406
|
+
var _a;
|
|
2407
|
+
return (_a = tsNode.heritageClauses) == null ? void 0 : _a.flatMap((clause) => clause.types).map((typeExpressions) => checker.getTypeAtLocation(typeExpressions));
|
|
2408
|
+
}
|
|
2409
|
+
function getMemberIfExists(type, memberName) {
|
|
2410
|
+
var _a, _b;
|
|
2411
|
+
const escapedMemberName = ts6.escapeLeadingUnderscores(memberName);
|
|
2412
|
+
const symbolMemberMatch = (_b = (_a = type.getSymbol()) == null ? void 0 : _a.members) == null ? void 0 : _b.get(escapedMemberName);
|
|
2413
|
+
return symbolMemberMatch != null ? symbolMemberMatch : tsutils2.getPropertyOfType(type, escapedMemberName);
|
|
2414
|
+
}
|
|
2415
|
+
function isStaticMember(node) {
|
|
2416
|
+
return (isMethodDefinition(node) || isPropertyDefinition(node)) && node.static;
|
|
2417
|
+
}
|
|
2418
|
+
function getPropertyContextualType(checker, tsNode) {
|
|
2419
|
+
if (ts6.isPropertyAssignment(tsNode)) {
|
|
2420
|
+
return checker.getContextualType(tsNode.initializer);
|
|
2421
|
+
} else if (ts6.isShorthandPropertyAssignment(tsNode)) {
|
|
2422
|
+
return checker.getContextualType(tsNode.name);
|
|
2423
|
+
} else if (ts6.isMethodDeclaration(tsNode)) {
|
|
2424
|
+
if (ts6.isComputedPropertyName(tsNode.name)) {
|
|
2425
|
+
return;
|
|
2426
|
+
}
|
|
2427
|
+
const obj = tsNode.parent;
|
|
2428
|
+
if (!ts6.isObjectLiteralExpression(obj)) {
|
|
2429
|
+
return;
|
|
2430
|
+
}
|
|
2431
|
+
const objType = checker.getContextualType(obj);
|
|
2432
|
+
if (objType === void 0) {
|
|
2433
|
+
return;
|
|
2434
|
+
}
|
|
2435
|
+
const propertySymbol = checker.getPropertyOfType(objType, tsNode.name.text);
|
|
2436
|
+
if (propertySymbol === void 0) {
|
|
2437
|
+
return;
|
|
2438
|
+
}
|
|
2439
|
+
return checker.getTypeOfSymbolAtLocation(propertySymbol, tsNode.name);
|
|
2440
|
+
} else {
|
|
2441
|
+
return void 0;
|
|
2442
|
+
}
|
|
2443
|
+
}
|
|
2444
|
+
function isPossiblyFunctionType(node) {
|
|
2445
|
+
switch (node.typeAnnotation.type) {
|
|
2446
|
+
case AST_NODE_TYPES6.TSConditionalType:
|
|
2447
|
+
case AST_NODE_TYPES6.TSConstructorType:
|
|
2448
|
+
case AST_NODE_TYPES6.TSFunctionType:
|
|
2449
|
+
case AST_NODE_TYPES6.TSImportType:
|
|
2450
|
+
case AST_NODE_TYPES6.TSIndexedAccessType:
|
|
2451
|
+
case AST_NODE_TYPES6.TSInferType:
|
|
2452
|
+
case AST_NODE_TYPES6.TSIntersectionType:
|
|
2453
|
+
case AST_NODE_TYPES6.TSQualifiedName:
|
|
2454
|
+
case AST_NODE_TYPES6.TSThisType:
|
|
2455
|
+
case AST_NODE_TYPES6.TSTypeOperator:
|
|
2456
|
+
case AST_NODE_TYPES6.TSTypeQuery:
|
|
2457
|
+
case AST_NODE_TYPES6.TSTypeReference:
|
|
2458
|
+
case AST_NODE_TYPES6.TSUnionType:
|
|
2459
|
+
return true;
|
|
2460
|
+
case AST_NODE_TYPES6.TSTypeLiteral:
|
|
2461
|
+
return node.typeAnnotation.members.some(
|
|
2462
|
+
(member) => member.type === AST_NODE_TYPES6.TSCallSignatureDeclaration || member.type === AST_NODE_TYPES6.TSConstructSignatureDeclaration
|
|
2463
|
+
);
|
|
2464
|
+
case AST_NODE_TYPES6.TSAbstractKeyword:
|
|
2465
|
+
case AST_NODE_TYPES6.TSAnyKeyword:
|
|
2466
|
+
case AST_NODE_TYPES6.TSArrayType:
|
|
2467
|
+
case AST_NODE_TYPES6.TSAsyncKeyword:
|
|
2468
|
+
case AST_NODE_TYPES6.TSBigIntKeyword:
|
|
2469
|
+
case AST_NODE_TYPES6.TSBooleanKeyword:
|
|
2470
|
+
case AST_NODE_TYPES6.TSDeclareKeyword:
|
|
2471
|
+
case AST_NODE_TYPES6.TSExportKeyword:
|
|
2472
|
+
case AST_NODE_TYPES6.TSIntrinsicKeyword:
|
|
2473
|
+
case AST_NODE_TYPES6.TSLiteralType:
|
|
2474
|
+
case AST_NODE_TYPES6.TSMappedType:
|
|
2475
|
+
case AST_NODE_TYPES6.TSNamedTupleMember:
|
|
2476
|
+
case AST_NODE_TYPES6.TSNeverKeyword:
|
|
2477
|
+
case AST_NODE_TYPES6.TSNullKeyword:
|
|
2478
|
+
case AST_NODE_TYPES6.TSNumberKeyword:
|
|
2479
|
+
case AST_NODE_TYPES6.TSObjectKeyword:
|
|
2480
|
+
case AST_NODE_TYPES6.TSOptionalType:
|
|
2481
|
+
case AST_NODE_TYPES6.TSPrivateKeyword:
|
|
2482
|
+
case AST_NODE_TYPES6.TSProtectedKeyword:
|
|
2483
|
+
case AST_NODE_TYPES6.TSPublicKeyword:
|
|
2484
|
+
case AST_NODE_TYPES6.TSReadonlyKeyword:
|
|
2485
|
+
case AST_NODE_TYPES6.TSRestType:
|
|
2486
|
+
case AST_NODE_TYPES6.TSStaticKeyword:
|
|
2487
|
+
case AST_NODE_TYPES6.TSStringKeyword:
|
|
2488
|
+
case AST_NODE_TYPES6.TSSymbolKeyword:
|
|
2489
|
+
case AST_NODE_TYPES6.TSTemplateLiteralType:
|
|
2490
|
+
case AST_NODE_TYPES6.TSTupleType:
|
|
2491
|
+
case AST_NODE_TYPES6.TSTypePredicate:
|
|
2492
|
+
case AST_NODE_TYPES6.TSUndefinedKeyword:
|
|
2493
|
+
case AST_NODE_TYPES6.TSUnknownKeyword:
|
|
2494
|
+
case AST_NODE_TYPES6.TSVoidKeyword:
|
|
2495
|
+
return false;
|
|
2496
|
+
}
|
|
2497
|
+
}
|
|
2498
|
+
|
|
2089
2499
|
// src/rules/no-nested-subscribe.ts
|
|
2090
2500
|
var noNestedSubscribeRule = ruleCreator({
|
|
2091
2501
|
defaultOptions: [],
|
|
@@ -2208,10 +2618,10 @@ function isExpressionObserver(expressionStatement, couldBeType2) {
|
|
|
2208
2618
|
}
|
|
2209
2619
|
|
|
2210
2620
|
// src/rules/no-sharereplay.ts
|
|
2211
|
-
import { AST_NODE_TYPES as
|
|
2212
|
-
var
|
|
2621
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES7 } from "@typescript-eslint/utils";
|
|
2622
|
+
var defaultOptions9 = [];
|
|
2213
2623
|
var noSharereplayRule = ruleCreator({
|
|
2214
|
-
defaultOptions:
|
|
2624
|
+
defaultOptions: defaultOptions9,
|
|
2215
2625
|
meta: {
|
|
2216
2626
|
docs: {
|
|
2217
2627
|
description: "Disallow unsafe `shareReplay` usage.",
|
|
@@ -2239,7 +2649,7 @@ var noSharereplayRule = ruleCreator({
|
|
|
2239
2649
|
"CallExpression[callee.name='shareReplay']": (node) => {
|
|
2240
2650
|
let report = true;
|
|
2241
2651
|
if (allowConfig) {
|
|
2242
|
-
report = node.arguments.length !== 1 || node.arguments[0].type !==
|
|
2652
|
+
report = node.arguments.length !== 1 || node.arguments[0].type !== AST_NODE_TYPES7.ObjectExpression;
|
|
2243
2653
|
}
|
|
2244
2654
|
if (report) {
|
|
2245
2655
|
context.report({
|
|
@@ -2534,7 +2944,7 @@ import { ${functionName} } from ${quote}rxjs${quote};`
|
|
|
2534
2944
|
});
|
|
2535
2945
|
|
|
2536
2946
|
// src/rules/no-unbound-methods.ts
|
|
2537
|
-
import { ESLintUtils as
|
|
2947
|
+
import { ESLintUtils as ESLintUtils9 } from "@typescript-eslint/utils";
|
|
2538
2948
|
var noUnboundMethodsRule = ruleCreator({
|
|
2539
2949
|
defaultOptions: [],
|
|
2540
2950
|
meta: {
|
|
@@ -2551,7 +2961,7 @@ var noUnboundMethodsRule = ruleCreator({
|
|
|
2551
2961
|
},
|
|
2552
2962
|
name: "no-unbound-methods",
|
|
2553
2963
|
create: (context) => {
|
|
2554
|
-
const { getTypeAtLocation } =
|
|
2964
|
+
const { getTypeAtLocation } = ESLintUtils9.getParserServices(context);
|
|
2555
2965
|
const { couldBeObservable, couldBeSubscription } = getTypeServices(context);
|
|
2556
2966
|
const nodeMap = /* @__PURE__ */ new WeakMap();
|
|
2557
2967
|
function mapArguments(node) {
|
|
@@ -2599,9 +3009,9 @@ var noUnboundMethodsRule = ruleCreator({
|
|
|
2599
3009
|
|
|
2600
3010
|
// src/rules/no-unsafe-catch.ts
|
|
2601
3011
|
import { stripIndent as stripIndent4 } from "common-tags";
|
|
2602
|
-
var
|
|
3012
|
+
var defaultOptions10 = [];
|
|
2603
3013
|
var noUnsafeCatchRule = ruleCreator({
|
|
2604
|
-
defaultOptions:
|
|
3014
|
+
defaultOptions: defaultOptions10,
|
|
2605
3015
|
meta: {
|
|
2606
3016
|
docs: {
|
|
2607
3017
|
description: "Disallow unsafe `catchError` usage in effects and epics.",
|
|
@@ -2660,9 +3070,9 @@ var noUnsafeCatchRule = ruleCreator({
|
|
|
2660
3070
|
|
|
2661
3071
|
// src/rules/no-unsafe-first.ts
|
|
2662
3072
|
import { stripIndent as stripIndent5 } from "common-tags";
|
|
2663
|
-
var
|
|
3073
|
+
var defaultOptions11 = [];
|
|
2664
3074
|
var noUnsafeFirstRule = ruleCreator({
|
|
2665
|
-
defaultOptions:
|
|
3075
|
+
defaultOptions: defaultOptions11,
|
|
2666
3076
|
meta: {
|
|
2667
3077
|
docs: {
|
|
2668
3078
|
description: "Disallow unsafe `first`/`take` usage in effects and epics.",
|
|
@@ -2729,9 +3139,9 @@ var noUnsafeFirstRule = ruleCreator({
|
|
|
2729
3139
|
});
|
|
2730
3140
|
|
|
2731
3141
|
// src/rules/no-unsafe-subject-next.ts
|
|
2732
|
-
import { ESLintUtils as
|
|
2733
|
-
import * as
|
|
2734
|
-
import
|
|
3142
|
+
import { ESLintUtils as ESLintUtils10 } from "@typescript-eslint/utils";
|
|
3143
|
+
import * as tsutils3 from "ts-api-utils";
|
|
3144
|
+
import ts7 from "typescript";
|
|
2735
3145
|
var noUnsafeSubjectNext = ruleCreator({
|
|
2736
3146
|
defaultOptions: [],
|
|
2737
3147
|
meta: {
|
|
@@ -2748,25 +3158,25 @@ var noUnsafeSubjectNext = ruleCreator({
|
|
|
2748
3158
|
},
|
|
2749
3159
|
name: "no-unsafe-subject-next",
|
|
2750
3160
|
create: (context) => {
|
|
2751
|
-
const { getTypeAtLocation, program } =
|
|
3161
|
+
const { getTypeAtLocation, program } = ESLintUtils10.getParserServices(context);
|
|
2752
3162
|
const typeChecker = program.getTypeChecker();
|
|
2753
3163
|
return {
|
|
2754
3164
|
[`CallExpression[callee.property.name='next']`]: (node) => {
|
|
2755
3165
|
if (node.arguments.length === 0 && isMemberExpression(node.callee)) {
|
|
2756
3166
|
const type = getTypeAtLocation(node.callee.object);
|
|
2757
|
-
if (
|
|
3167
|
+
if (tsutils3.isTypeReference(type) && couldBeType(type, "Subject")) {
|
|
2758
3168
|
const [typeArg] = typeChecker.getTypeArguments(type);
|
|
2759
|
-
if (
|
|
3169
|
+
if (tsutils3.isTypeFlagSet(typeArg, ts7.TypeFlags.Any)) {
|
|
2760
3170
|
return;
|
|
2761
3171
|
}
|
|
2762
|
-
if (
|
|
3172
|
+
if (tsutils3.isTypeFlagSet(typeArg, ts7.TypeFlags.Unknown)) {
|
|
2763
3173
|
return;
|
|
2764
3174
|
}
|
|
2765
|
-
if (
|
|
3175
|
+
if (tsutils3.isTypeFlagSet(typeArg, ts7.TypeFlags.Void)) {
|
|
2766
3176
|
return;
|
|
2767
3177
|
}
|
|
2768
|
-
if (
|
|
2769
|
-
(t) =>
|
|
3178
|
+
if (tsutils3.isUnionType(typeArg) && typeArg.types.some(
|
|
3179
|
+
(t) => tsutils3.isTypeFlagSet(t, ts7.TypeFlags.Void)
|
|
2770
3180
|
)) {
|
|
2771
3181
|
return;
|
|
2772
3182
|
}
|
|
@@ -2784,9 +3194,9 @@ var noUnsafeSubjectNext = ruleCreator({
|
|
|
2784
3194
|
// src/rules/no-unsafe-switchmap.ts
|
|
2785
3195
|
import { stripIndent as stripIndent6 } from "common-tags";
|
|
2786
3196
|
import decamelize from "decamelize";
|
|
2787
|
-
var
|
|
3197
|
+
var defaultOptions12 = [];
|
|
2788
3198
|
var noUnsafeSwitchmapRule = ruleCreator({
|
|
2789
|
-
defaultOptions:
|
|
3199
|
+
defaultOptions: defaultOptions12,
|
|
2790
3200
|
meta: {
|
|
2791
3201
|
docs: {
|
|
2792
3202
|
description: "Disallow unsafe `switchMap` usage in effects and epics.",
|
|
@@ -2909,7 +3319,7 @@ var noUnsafeSwitchmapRule = ruleCreator({
|
|
|
2909
3319
|
|
|
2910
3320
|
// src/rules/no-unsafe-takeuntil.ts
|
|
2911
3321
|
import { stripIndent as stripIndent7 } from "common-tags";
|
|
2912
|
-
var
|
|
3322
|
+
var defaultOptions13 = [];
|
|
2913
3323
|
var allowedOperators = [
|
|
2914
3324
|
"count",
|
|
2915
3325
|
"defaultIfEmpty",
|
|
@@ -2934,7 +3344,7 @@ var allowedOperators = [
|
|
|
2934
3344
|
"toArray"
|
|
2935
3345
|
];
|
|
2936
3346
|
var noUnsafeTakeuntilRule = ruleCreator({
|
|
2937
|
-
defaultOptions:
|
|
3347
|
+
defaultOptions: defaultOptions13,
|
|
2938
3348
|
meta: {
|
|
2939
3349
|
docs: {
|
|
2940
3350
|
description: "Disallow applying operators after `takeUntil`.",
|
|
@@ -3013,9 +3423,9 @@ var noUnsafeTakeuntilRule = ruleCreator({
|
|
|
3013
3423
|
});
|
|
3014
3424
|
|
|
3015
3425
|
// src/rules/prefer-observer.ts
|
|
3016
|
-
var
|
|
3426
|
+
var defaultOptions14 = [];
|
|
3017
3427
|
var preferObserverRule = ruleCreator({
|
|
3018
|
-
defaultOptions:
|
|
3428
|
+
defaultOptions: defaultOptions14,
|
|
3019
3429
|
meta: {
|
|
3020
3430
|
docs: {
|
|
3021
3431
|
description: "Disallow passing separate handlers to `subscribe` and `tap`.",
|
|
@@ -3250,10 +3660,10 @@ var preferRootOperatorsRule = ruleCreator({
|
|
|
3250
3660
|
});
|
|
3251
3661
|
|
|
3252
3662
|
// src/rules/suffix-subjects.ts
|
|
3253
|
-
import { AST_NODE_TYPES as
|
|
3254
|
-
var
|
|
3663
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES8, ESLintUtils as ESLintUtils11 } from "@typescript-eslint/utils";
|
|
3664
|
+
var defaultOptions15 = [];
|
|
3255
3665
|
var suffixSubjectsRule = ruleCreator({
|
|
3256
|
-
defaultOptions:
|
|
3666
|
+
defaultOptions: defaultOptions15,
|
|
3257
3667
|
meta: {
|
|
3258
3668
|
docs: {
|
|
3259
3669
|
description: "Enforce the use of a suffix in subject identifiers.",
|
|
@@ -3278,7 +3688,7 @@ var suffixSubjectsRule = ruleCreator({
|
|
|
3278
3688
|
},
|
|
3279
3689
|
name: "suffix-subjects",
|
|
3280
3690
|
create: (context) => {
|
|
3281
|
-
const { esTreeNodeToTSNodeMap } =
|
|
3691
|
+
const { esTreeNodeToTSNodeMap } = ESLintUtils11.getParserServices(context);
|
|
3282
3692
|
const { couldBeType: couldBeType2 } = getTypeServices(context);
|
|
3283
3693
|
const [config = {}] = context.options;
|
|
3284
3694
|
const validate = {
|
|
@@ -3334,7 +3744,7 @@ var suffixSubjectsRule = ruleCreator({
|
|
|
3334
3744
|
if (!found) {
|
|
3335
3745
|
return;
|
|
3336
3746
|
}
|
|
3337
|
-
if (!validate.variables && found.type ===
|
|
3747
|
+
if (!validate.variables && found.type === AST_NODE_TYPES8.VariableDeclarator) {
|
|
3338
3748
|
return;
|
|
3339
3749
|
}
|
|
3340
3750
|
if (!validate.parameters) {
|
|
@@ -3401,7 +3811,7 @@ var suffixSubjectsRule = ruleCreator({
|
|
|
3401
3811
|
if (!found) {
|
|
3402
3812
|
return;
|
|
3403
3813
|
}
|
|
3404
|
-
if (!validate.variables && found.type ===
|
|
3814
|
+
if (!validate.variables && found.type === AST_NODE_TYPES8.VariableDeclarator) {
|
|
3405
3815
|
return;
|
|
3406
3816
|
}
|
|
3407
3817
|
if (!validate.parameters) {
|
|
@@ -3448,11 +3858,11 @@ var suffixSubjectsRule = ruleCreator({
|
|
|
3448
3858
|
});
|
|
3449
3859
|
|
|
3450
3860
|
// src/rules/throw-error.ts
|
|
3451
|
-
import { ESLintUtils as
|
|
3452
|
-
import * as
|
|
3453
|
-
var
|
|
3861
|
+
import { ESLintUtils as ESLintUtils12 } from "@typescript-eslint/utils";
|
|
3862
|
+
import * as tsutils4 from "ts-api-utils";
|
|
3863
|
+
var defaultOptions16 = [];
|
|
3454
3864
|
var throwErrorRule = ruleCreator({
|
|
3455
|
-
defaultOptions:
|
|
3865
|
+
defaultOptions: defaultOptions16,
|
|
3456
3866
|
meta: {
|
|
3457
3867
|
docs: {
|
|
3458
3868
|
description: "Enforce passing only `Error` values to `throwError`.",
|
|
@@ -3478,7 +3888,7 @@ var throwErrorRule = ruleCreator({
|
|
|
3478
3888
|
},
|
|
3479
3889
|
name: "throw-error",
|
|
3480
3890
|
create: (context) => {
|
|
3481
|
-
const { esTreeNodeToTSNodeMap, program, getTypeAtLocation } =
|
|
3891
|
+
const { esTreeNodeToTSNodeMap, program, getTypeAtLocation } = ESLintUtils12.getParserServices(context);
|
|
3482
3892
|
const { couldBeObservable } = getTypeServices(context);
|
|
3483
3893
|
const [config = {}] = context.options;
|
|
3484
3894
|
const { allowThrowingAny = true, allowThrowingUnknown = true } = config;
|
|
@@ -3493,10 +3903,10 @@ var throwErrorRule = ruleCreator({
|
|
|
3493
3903
|
const body = tsNode.body;
|
|
3494
3904
|
type = program.getTypeChecker().getTypeAtLocation(annotation != null ? annotation : body);
|
|
3495
3905
|
}
|
|
3496
|
-
if (allowThrowingAny &&
|
|
3906
|
+
if (allowThrowingAny && tsutils4.isIntrinsicAnyType(type)) {
|
|
3497
3907
|
return;
|
|
3498
3908
|
}
|
|
3499
|
-
if (allowThrowingUnknown &&
|
|
3909
|
+
if (allowThrowingUnknown && tsutils4.isIntrinsicUnknownType(type)) {
|
|
3500
3910
|
return;
|
|
3501
3911
|
}
|
|
3502
3912
|
if (couldBeType(type, /^Error$/)) {
|
|
@@ -3554,6 +3964,7 @@ var plugin = {
|
|
|
3554
3964
|
"no-implicit-any-catch": noImplicitAnyCatchRule,
|
|
3555
3965
|
"no-index": noIndexRule,
|
|
3556
3966
|
"no-internal": noInternalRule,
|
|
3967
|
+
"no-misused-observables": noMisusedObservablesRule,
|
|
3557
3968
|
"no-nested-subscribe": noNestedSubscribeRule,
|
|
3558
3969
|
"no-redundant-notify": noRedundantNotifyRule,
|
|
3559
3970
|
"no-sharereplay": noSharereplayRule,
|