eslint-plugin-rxjs-x 0.4.1 → 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/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.4.1";
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
  },
@@ -20,14 +21,19 @@ 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-topromise": "error",
23
25
  "rxjs-x/no-unbound-methods": "error",
24
26
  "rxjs-x/no-unsafe-subject-next": "error",
25
- "rxjs-x/no-unsafe-takeuntil": "error"
27
+ "rxjs-x/no-unsafe-takeuntil": "error",
28
+ "rxjs-x/prefer-observer": "error",
29
+ "rxjs-x/prefer-root-operators": "error",
30
+ "rxjs-x/throw-error": "error"
26
31
  }
27
32
  });
28
33
 
29
34
  // src/configs/strict.ts
30
35
  var createStrictConfig = (plugin2) => ({
36
+ name: "rxjs-x/strict",
31
37
  plugins: {
32
38
  "rxjs-x": plugin2
33
39
  },
@@ -36,10 +42,10 @@ var createStrictConfig = (plugin2) => ({
36
42
  "rxjs-x/no-create": "error",
37
43
  "rxjs-x/no-explicit-generics": "error",
38
44
  "rxjs-x/no-exposed-subjects": "error",
45
+ "rxjs-x/no-floating-observables": "error",
39
46
  "rxjs-x/no-ignored-default-value": "error",
40
47
  "rxjs-x/no-ignored-error": "error",
41
48
  "rxjs-x/no-ignored-notifier": "error",
42
- "rxjs-x/no-ignored-observable": "error",
43
49
  "rxjs-x/no-ignored-replay-buffer": "error",
44
50
  "rxjs-x/no-ignored-takewhile-value": "error",
45
51
  "rxjs-x/no-implicit-any-catch": ["error", {
@@ -47,6 +53,7 @@ var createStrictConfig = (plugin2) => ({
47
53
  }],
48
54
  "rxjs-x/no-index": "error",
49
55
  "rxjs-x/no-internal": "error",
56
+ "rxjs-x/no-misused-observables": "error",
50
57
  "rxjs-x/no-nested-subscribe": "error",
51
58
  "rxjs-x/no-redundant-notify": "error",
52
59
  "rxjs-x/no-sharereplay": "error",
@@ -162,7 +169,7 @@ var banObservablesRule = ruleCreator({
162
169
  var _typescript = require('typescript'); var _typescript2 = _interopRequireDefault(_typescript);
163
170
 
164
171
  // src/etc/could-be-type.ts
165
- var _tsapiutils = require('ts-api-utils'); var tsutils = _interopRequireWildcard(_tsapiutils); var tsutils2 = _interopRequireWildcard(_tsapiutils); var tsutils3 = _interopRequireWildcard(_tsapiutils);
172
+ var _tsapiutils = require('ts-api-utils'); var tsutils = _interopRequireWildcard(_tsapiutils); var tsutils2 = _interopRequireWildcard(_tsapiutils); var tsutils3 = _interopRequireWildcard(_tsapiutils); var tsutils4 = _interopRequireWildcard(_tsapiutils);
166
173
 
167
174
  function couldBeType(type, name2, qualified) {
168
175
  if (tsutils.isTypeReference(type)) {
@@ -295,6 +302,9 @@ function isBlockStatement(node) {
295
302
  function isCallExpression(node) {
296
303
  return node.type === _utils.AST_NODE_TYPES.CallExpression;
297
304
  }
305
+ function isChainExpression(node) {
306
+ return node.type === _utils.AST_NODE_TYPES.ChainExpression;
307
+ }
298
308
  function isFunctionDeclaration(node) {
299
309
  return node.type === _utils.AST_NODE_TYPES.FunctionDeclaration;
300
310
  }
@@ -313,12 +323,18 @@ function isImportNamespaceSpecifier(node) {
313
323
  function isImportSpecifier(node) {
314
324
  return node.type === _utils.AST_NODE_TYPES.ImportSpecifier;
315
325
  }
326
+ function isJSXExpressionContainer(node) {
327
+ return node.type === _utils.AST_NODE_TYPES.JSXExpressionContainer;
328
+ }
316
329
  function isLiteral(node) {
317
330
  return node.type === _utils.AST_NODE_TYPES.Literal;
318
331
  }
319
332
  function isMemberExpression(node) {
320
333
  return node.type === _utils.AST_NODE_TYPES.MemberExpression;
321
334
  }
335
+ function isMethodDefinition(node) {
336
+ return node.type === _utils.AST_NODE_TYPES.MethodDefinition;
337
+ }
322
338
  function isObjectExpression(node) {
323
339
  return node.type === _utils.AST_NODE_TYPES.ObjectExpression;
324
340
  }
@@ -331,6 +347,12 @@ function isProgram(node) {
331
347
  function isProperty(node) {
332
348
  return node.type === _utils.AST_NODE_TYPES.Property;
333
349
  }
350
+ function isPropertyDefinition(node) {
351
+ return node.type === _utils.AST_NODE_TYPES.PropertyDefinition;
352
+ }
353
+ function isUnaryExpression(node) {
354
+ return node.type === _utils.AST_NODE_TYPES.UnaryExpression;
355
+ }
334
356
 
335
357
  // src/etc/get-type-services.ts
336
358
  function getTypeServices(context) {
@@ -353,6 +375,7 @@ function getTypeServices(context) {
353
375
  tsTypeNode = (_a = tsNode.type) != null ? _a : tsNode.body;
354
376
  } else if (_typescript2.default.isCallSignatureDeclaration(tsNode) || _typescript2.default.isMethodSignature(tsNode)) {
355
377
  tsTypeNode = tsNode.type;
378
+ } else if (_typescript2.default.isPropertySignature(tsNode)) {
356
379
  }
357
380
  return Boolean(
358
381
  tsTypeNode && couldBeType(
@@ -1318,6 +1341,87 @@ var noFinnishRule = ruleCreator({
1318
1341
  }
1319
1342
  });
1320
1343
 
1344
+ // src/rules/no-floating-observables.ts
1345
+ var defaultOptions6 = [];
1346
+ var messageBase = "Observables must be subscribed to, returned, converted to a promise and awaited, or be explicitly marked as ignored with the `void` operator.";
1347
+ var messageBaseNoVoid = "Observables must be subscribed to, returned, or converted to a promise and awaited.";
1348
+ var noFloatingObservablesRule = ruleCreator({
1349
+ defaultOptions: defaultOptions6,
1350
+ meta: {
1351
+ docs: {
1352
+ description: "Require Observables to be handled appropriately.",
1353
+ recommended: "strict",
1354
+ requiresTypeChecking: true
1355
+ },
1356
+ messages: {
1357
+ forbidden: messageBase,
1358
+ forbiddenNoVoid: messageBaseNoVoid
1359
+ },
1360
+ schema: [
1361
+ {
1362
+ properties: {
1363
+ ignoreVoid: { type: "boolean", default: true, description: "Whether to ignore `void` expressions." }
1364
+ },
1365
+ type: "object"
1366
+ }
1367
+ ],
1368
+ type: "problem"
1369
+ },
1370
+ name: "no-floating-observables",
1371
+ create: (context) => {
1372
+ const { couldBeObservable } = getTypeServices(context);
1373
+ const [config = {}] = context.options;
1374
+ const { ignoreVoid = true } = config;
1375
+ function checkNode(node) {
1376
+ if (couldBeObservable(node)) {
1377
+ context.report({
1378
+ messageId: ignoreVoid ? "forbidden" : "forbiddenNoVoid",
1379
+ node
1380
+ });
1381
+ }
1382
+ }
1383
+ function checkVoid(node) {
1384
+ if (ignoreVoid) return;
1385
+ if (node.operator !== "void") return;
1386
+ let expression = node.argument;
1387
+ if (isChainExpression(expression)) {
1388
+ expression = expression.expression;
1389
+ }
1390
+ if (!isCallExpression(expression)) return;
1391
+ checkNode(expression);
1392
+ }
1393
+ return {
1394
+ "ExpressionStatement > CallExpression": (node) => {
1395
+ checkNode(node);
1396
+ },
1397
+ "ExpressionStatement > UnaryExpression": (node) => {
1398
+ checkVoid(node);
1399
+ },
1400
+ "ExpressionStatement > ChainExpression": (node) => {
1401
+ if (!isCallExpression(node.expression)) return;
1402
+ checkNode(node.expression);
1403
+ },
1404
+ "ExpressionStatement > SequenceExpression": (node) => {
1405
+ node.expressions.forEach((expression) => {
1406
+ if (isCallExpression(expression)) {
1407
+ checkNode(expression);
1408
+ }
1409
+ });
1410
+ },
1411
+ "ExpressionStatement > ArrayExpression": (node) => {
1412
+ node.elements.forEach((expression) => {
1413
+ if (!expression) return;
1414
+ if (isCallExpression(expression)) {
1415
+ checkNode(expression);
1416
+ } else if (isUnaryExpression(expression)) {
1417
+ checkVoid(expression);
1418
+ }
1419
+ });
1420
+ }
1421
+ };
1422
+ }
1423
+ });
1424
+
1321
1425
  // src/rules/no-ignored-default-value.ts
1322
1426
 
1323
1427
  var noIgnoredDefaultValueRule = ruleCreator({
@@ -1559,37 +1663,6 @@ var noIgnoredNotifierRule = ruleCreator({
1559
1663
  }
1560
1664
  });
1561
1665
 
1562
- // src/rules/no-ignored-observable.ts
1563
- var noIgnoredObservableRule = ruleCreator({
1564
- defaultOptions: [],
1565
- meta: {
1566
- docs: {
1567
- description: "Disallow ignoring observables returned by functions.",
1568
- recommended: "strict",
1569
- requiresTypeChecking: true
1570
- },
1571
- messages: {
1572
- forbidden: "Ignoring a returned Observable is forbidden."
1573
- },
1574
- schema: [],
1575
- type: "problem"
1576
- },
1577
- name: "no-ignored-observable",
1578
- create: (context) => {
1579
- const { couldBeObservable } = getTypeServices(context);
1580
- return {
1581
- "ExpressionStatement > CallExpression": (node) => {
1582
- if (couldBeObservable(node)) {
1583
- context.report({
1584
- messageId: "forbidden",
1585
- node
1586
- });
1587
- }
1588
- }
1589
- };
1590
- }
1591
- });
1592
-
1593
1666
  // src/rules/no-ignored-replay-buffer.ts
1594
1667
  var noIgnoredReplayBufferRule = ruleCreator({
1595
1668
  defaultOptions: [],
@@ -1780,9 +1853,9 @@ function isParenthesised(sourceCode, node) {
1780
1853
  const after = sourceCode.getTokenAfter(node);
1781
1854
  return before && after && before.value === "(" && before.range[1] <= node.range[0] && after.value === ")" && after.range[0] >= node.range[1];
1782
1855
  }
1783
- var defaultOptions6 = [];
1856
+ var defaultOptions7 = [];
1784
1857
  var noImplicitAnyCatchRule = ruleCreator({
1785
- defaultOptions: defaultOptions6,
1858
+ defaultOptions: defaultOptions7,
1786
1859
  meta: {
1787
1860
  docs: {
1788
1861
  description: "Disallow implicit `any` error parameters in `catchError` operators.",
@@ -2026,6 +2099,403 @@ var noInternalRule = ruleCreator({
2026
2099
  }
2027
2100
  });
2028
2101
 
2102
+ // src/rules/no-misused-observables.ts
2103
+
2104
+
2105
+
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 } = _utils.ESLintUtils.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 = _typescript2.default.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, _typescript2.default.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 = _typescript2.default.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 (_typescript2.default.isPropertyAssignment(tsNode)) {
2420
+ return checker.getContextualType(tsNode.initializer);
2421
+ } else if (_typescript2.default.isShorthandPropertyAssignment(tsNode)) {
2422
+ return checker.getContextualType(tsNode.name);
2423
+ } else if (_typescript2.default.isMethodDeclaration(tsNode)) {
2424
+ if (_typescript2.default.isComputedPropertyName(tsNode.name)) {
2425
+ return;
2426
+ }
2427
+ const obj = tsNode.parent;
2428
+ if (!_typescript2.default.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 _utils.AST_NODE_TYPES.TSConditionalType:
2447
+ case _utils.AST_NODE_TYPES.TSConstructorType:
2448
+ case _utils.AST_NODE_TYPES.TSFunctionType:
2449
+ case _utils.AST_NODE_TYPES.TSImportType:
2450
+ case _utils.AST_NODE_TYPES.TSIndexedAccessType:
2451
+ case _utils.AST_NODE_TYPES.TSInferType:
2452
+ case _utils.AST_NODE_TYPES.TSIntersectionType:
2453
+ case _utils.AST_NODE_TYPES.TSQualifiedName:
2454
+ case _utils.AST_NODE_TYPES.TSThisType:
2455
+ case _utils.AST_NODE_TYPES.TSTypeOperator:
2456
+ case _utils.AST_NODE_TYPES.TSTypeQuery:
2457
+ case _utils.AST_NODE_TYPES.TSTypeReference:
2458
+ case _utils.AST_NODE_TYPES.TSUnionType:
2459
+ return true;
2460
+ case _utils.AST_NODE_TYPES.TSTypeLiteral:
2461
+ return node.typeAnnotation.members.some(
2462
+ (member) => member.type === _utils.AST_NODE_TYPES.TSCallSignatureDeclaration || member.type === _utils.AST_NODE_TYPES.TSConstructSignatureDeclaration
2463
+ );
2464
+ case _utils.AST_NODE_TYPES.TSAbstractKeyword:
2465
+ case _utils.AST_NODE_TYPES.TSAnyKeyword:
2466
+ case _utils.AST_NODE_TYPES.TSArrayType:
2467
+ case _utils.AST_NODE_TYPES.TSAsyncKeyword:
2468
+ case _utils.AST_NODE_TYPES.TSBigIntKeyword:
2469
+ case _utils.AST_NODE_TYPES.TSBooleanKeyword:
2470
+ case _utils.AST_NODE_TYPES.TSDeclareKeyword:
2471
+ case _utils.AST_NODE_TYPES.TSExportKeyword:
2472
+ case _utils.AST_NODE_TYPES.TSIntrinsicKeyword:
2473
+ case _utils.AST_NODE_TYPES.TSLiteralType:
2474
+ case _utils.AST_NODE_TYPES.TSMappedType:
2475
+ case _utils.AST_NODE_TYPES.TSNamedTupleMember:
2476
+ case _utils.AST_NODE_TYPES.TSNeverKeyword:
2477
+ case _utils.AST_NODE_TYPES.TSNullKeyword:
2478
+ case _utils.AST_NODE_TYPES.TSNumberKeyword:
2479
+ case _utils.AST_NODE_TYPES.TSObjectKeyword:
2480
+ case _utils.AST_NODE_TYPES.TSOptionalType:
2481
+ case _utils.AST_NODE_TYPES.TSPrivateKeyword:
2482
+ case _utils.AST_NODE_TYPES.TSProtectedKeyword:
2483
+ case _utils.AST_NODE_TYPES.TSPublicKeyword:
2484
+ case _utils.AST_NODE_TYPES.TSReadonlyKeyword:
2485
+ case _utils.AST_NODE_TYPES.TSRestType:
2486
+ case _utils.AST_NODE_TYPES.TSStaticKeyword:
2487
+ case _utils.AST_NODE_TYPES.TSStringKeyword:
2488
+ case _utils.AST_NODE_TYPES.TSSymbolKeyword:
2489
+ case _utils.AST_NODE_TYPES.TSTemplateLiteralType:
2490
+ case _utils.AST_NODE_TYPES.TSTupleType:
2491
+ case _utils.AST_NODE_TYPES.TSTypePredicate:
2492
+ case _utils.AST_NODE_TYPES.TSUndefinedKeyword:
2493
+ case _utils.AST_NODE_TYPES.TSUnknownKeyword:
2494
+ case _utils.AST_NODE_TYPES.TSVoidKeyword:
2495
+ return false;
2496
+ }
2497
+ }
2498
+
2029
2499
  // src/rules/no-nested-subscribe.ts
2030
2500
  var noNestedSubscribeRule = ruleCreator({
2031
2501
  defaultOptions: [],
@@ -2149,9 +2619,9 @@ function isExpressionObserver(expressionStatement, couldBeType2) {
2149
2619
 
2150
2620
  // src/rules/no-sharereplay.ts
2151
2621
 
2152
- var defaultOptions7 = [];
2622
+ var defaultOptions9 = [];
2153
2623
  var noSharereplayRule = ruleCreator({
2154
- defaultOptions: defaultOptions7,
2624
+ defaultOptions: defaultOptions9,
2155
2625
  meta: {
2156
2626
  docs: {
2157
2627
  description: "Disallow unsafe `shareReplay` usage.",
@@ -2385,7 +2855,7 @@ var noTopromiseRule = ruleCreator({
2385
2855
  meta: {
2386
2856
  docs: {
2387
2857
  description: "Disallow use of the `toPromise` method.",
2388
- recommended: "strict",
2858
+ recommended: "recommended",
2389
2859
  requiresTypeChecking: true
2390
2860
  },
2391
2861
  hasSuggestions: true,
@@ -2539,9 +3009,9 @@ var noUnboundMethodsRule = ruleCreator({
2539
3009
 
2540
3010
  // src/rules/no-unsafe-catch.ts
2541
3011
 
2542
- var defaultOptions8 = [];
3012
+ var defaultOptions10 = [];
2543
3013
  var noUnsafeCatchRule = ruleCreator({
2544
- defaultOptions: defaultOptions8,
3014
+ defaultOptions: defaultOptions10,
2545
3015
  meta: {
2546
3016
  docs: {
2547
3017
  description: "Disallow unsafe `catchError` usage in effects and epics.",
@@ -2600,9 +3070,9 @@ var noUnsafeCatchRule = ruleCreator({
2600
3070
 
2601
3071
  // src/rules/no-unsafe-first.ts
2602
3072
 
2603
- var defaultOptions9 = [];
3073
+ var defaultOptions11 = [];
2604
3074
  var noUnsafeFirstRule = ruleCreator({
2605
- defaultOptions: defaultOptions9,
3075
+ defaultOptions: defaultOptions11,
2606
3076
  meta: {
2607
3077
  docs: {
2608
3078
  description: "Disallow unsafe `first`/`take` usage in effects and epics.",
@@ -2694,19 +3164,19 @@ var noUnsafeSubjectNext = ruleCreator({
2694
3164
  [`CallExpression[callee.property.name='next']`]: (node) => {
2695
3165
  if (node.arguments.length === 0 && isMemberExpression(node.callee)) {
2696
3166
  const type = getTypeAtLocation(node.callee.object);
2697
- if (tsutils2.isTypeReference(type) && couldBeType(type, "Subject")) {
3167
+ if (tsutils3.isTypeReference(type) && couldBeType(type, "Subject")) {
2698
3168
  const [typeArg] = typeChecker.getTypeArguments(type);
2699
- if (tsutils2.isTypeFlagSet(typeArg, _typescript2.default.TypeFlags.Any)) {
3169
+ if (tsutils3.isTypeFlagSet(typeArg, _typescript2.default.TypeFlags.Any)) {
2700
3170
  return;
2701
3171
  }
2702
- if (tsutils2.isTypeFlagSet(typeArg, _typescript2.default.TypeFlags.Unknown)) {
3172
+ if (tsutils3.isTypeFlagSet(typeArg, _typescript2.default.TypeFlags.Unknown)) {
2703
3173
  return;
2704
3174
  }
2705
- if (tsutils2.isTypeFlagSet(typeArg, _typescript2.default.TypeFlags.Void)) {
3175
+ if (tsutils3.isTypeFlagSet(typeArg, _typescript2.default.TypeFlags.Void)) {
2706
3176
  return;
2707
3177
  }
2708
- if (tsutils2.isUnionType(typeArg) && typeArg.types.some(
2709
- (t) => tsutils2.isTypeFlagSet(t, _typescript2.default.TypeFlags.Void)
3178
+ if (tsutils3.isUnionType(typeArg) && typeArg.types.some(
3179
+ (t) => tsutils3.isTypeFlagSet(t, _typescript2.default.TypeFlags.Void)
2710
3180
  )) {
2711
3181
  return;
2712
3182
  }
@@ -2724,9 +3194,9 @@ var noUnsafeSubjectNext = ruleCreator({
2724
3194
  // src/rules/no-unsafe-switchmap.ts
2725
3195
 
2726
3196
  var _decamelize = require('decamelize'); var _decamelize2 = _interopRequireDefault(_decamelize);
2727
- var defaultOptions10 = [];
3197
+ var defaultOptions12 = [];
2728
3198
  var noUnsafeSwitchmapRule = ruleCreator({
2729
- defaultOptions: defaultOptions10,
3199
+ defaultOptions: defaultOptions12,
2730
3200
  meta: {
2731
3201
  docs: {
2732
3202
  description: "Disallow unsafe `switchMap` usage in effects and epics.",
@@ -2849,7 +3319,7 @@ var noUnsafeSwitchmapRule = ruleCreator({
2849
3319
 
2850
3320
  // src/rules/no-unsafe-takeuntil.ts
2851
3321
 
2852
- var defaultOptions11 = [];
3322
+ var defaultOptions13 = [];
2853
3323
  var allowedOperators = [
2854
3324
  "count",
2855
3325
  "defaultIfEmpty",
@@ -2874,7 +3344,7 @@ var allowedOperators = [
2874
3344
  "toArray"
2875
3345
  ];
2876
3346
  var noUnsafeTakeuntilRule = ruleCreator({
2877
- defaultOptions: defaultOptions11,
3347
+ defaultOptions: defaultOptions13,
2878
3348
  meta: {
2879
3349
  docs: {
2880
3350
  description: "Disallow applying operators after `takeUntil`.",
@@ -2953,13 +3423,13 @@ var noUnsafeTakeuntilRule = ruleCreator({
2953
3423
  });
2954
3424
 
2955
3425
  // src/rules/prefer-observer.ts
2956
- var defaultOptions12 = [];
3426
+ var defaultOptions14 = [];
2957
3427
  var preferObserverRule = ruleCreator({
2958
- defaultOptions: defaultOptions12,
3428
+ defaultOptions: defaultOptions14,
2959
3429
  meta: {
2960
3430
  docs: {
2961
3431
  description: "Disallow passing separate handlers to `subscribe` and `tap`.",
2962
- recommended: "strict",
3432
+ recommended: "recommended",
2963
3433
  requiresTypeChecking: true
2964
3434
  },
2965
3435
  fixable: "code",
@@ -3069,7 +3539,7 @@ var preferRootOperatorsRule = ruleCreator({
3069
3539
  meta: {
3070
3540
  docs: {
3071
3541
  description: "Disallow importing operators from `rxjs/operators`.",
3072
- recommended: "strict"
3542
+ recommended: "recommended"
3073
3543
  },
3074
3544
  fixable: "code",
3075
3545
  hasSuggestions: true,
@@ -3191,9 +3661,9 @@ var preferRootOperatorsRule = ruleCreator({
3191
3661
 
3192
3662
  // src/rules/suffix-subjects.ts
3193
3663
 
3194
- var defaultOptions13 = [];
3664
+ var defaultOptions15 = [];
3195
3665
  var suffixSubjectsRule = ruleCreator({
3196
- defaultOptions: defaultOptions13,
3666
+ defaultOptions: defaultOptions15,
3197
3667
  meta: {
3198
3668
  docs: {
3199
3669
  description: "Enforce the use of a suffix in subject identifiers.",
@@ -3390,13 +3860,14 @@ var suffixSubjectsRule = ruleCreator({
3390
3860
  // src/rules/throw-error.ts
3391
3861
 
3392
3862
 
3393
- var defaultOptions14 = [];
3863
+ var defaultOptions16 = [];
3394
3864
  var throwErrorRule = ruleCreator({
3395
- defaultOptions: defaultOptions14,
3865
+ defaultOptions: defaultOptions16,
3396
3866
  meta: {
3397
3867
  docs: {
3398
3868
  description: "Enforce passing only `Error` values to `throwError`.",
3399
3869
  recommended: {
3870
+ recommended: true,
3400
3871
  strict: [{ allowThrowingAny: false, allowThrowingUnknown: false }]
3401
3872
  },
3402
3873
  requiresTypeChecking: true
@@ -3432,10 +3903,10 @@ var throwErrorRule = ruleCreator({
3432
3903
  const body = tsNode.body;
3433
3904
  type = program.getTypeChecker().getTypeAtLocation(annotation != null ? annotation : body);
3434
3905
  }
3435
- if (allowThrowingAny && tsutils3.isIntrinsicAnyType(type)) {
3906
+ if (allowThrowingAny && tsutils4.isIntrinsicAnyType(type)) {
3436
3907
  return;
3437
3908
  }
3438
- if (allowThrowingUnknown && tsutils3.isIntrinsicUnknownType(type)) {
3909
+ if (allowThrowingUnknown && tsutils4.isIntrinsicUnknownType(type)) {
3439
3910
  return;
3440
3911
  }
3441
3912
  if (couldBeType(type, /^Error$/)) {
@@ -3482,10 +3953,10 @@ var plugin = {
3482
3953
  "no-explicit-generics": noExplicitGenericsRule,
3483
3954
  "no-exposed-subjects": noExposedSubjectsRule,
3484
3955
  "no-finnish": noFinnishRule,
3956
+ "no-floating-observables": noFloatingObservablesRule,
3485
3957
  "no-ignored-default-value": noIgnoredDefaultValueRule,
3486
3958
  "no-ignored-error": noIgnoredErrorRule,
3487
3959
  "no-ignored-notifier": noIgnoredNotifierRule,
3488
- "no-ignored-observable": noIgnoredObservableRule,
3489
3960
  "no-ignored-replay-buffer": noIgnoredReplayBufferRule,
3490
3961
  "no-ignored-subscribe": noIgnoredSubscribeRule,
3491
3962
  "no-ignored-subscription": noIgnoredSubscriptionRule,
@@ -3493,6 +3964,7 @@ var plugin = {
3493
3964
  "no-implicit-any-catch": noImplicitAnyCatchRule,
3494
3965
  "no-index": noIndexRule,
3495
3966
  "no-internal": noInternalRule,
3967
+ "no-misused-observables": noMisusedObservablesRule,
3496
3968
  "no-nested-subscribe": noNestedSubscribeRule,
3497
3969
  "no-redundant-notify": noRedundantNotifyRule,
3498
3970
  "no-sharereplay": noSharereplayRule,