eslint-plugin-rxjs-x 0.0.1 → 0.1.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 +3 -0
- package/dist/index.cjs +99 -33
- package/dist/index.d.cts +2 -2
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.mjs +97 -31
- package/package.json +16 -9
package/README.md
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# eslint-plugin-rxjs-x
|
|
2
2
|
|
|
3
|
+
[](https://github.com/JasonWeinzierl/eslint-plugin-rxjs-x/blob/master/LICENSE)
|
|
4
|
+
[](https://www.npmjs.com/package/eslint-plugin-rxjs-x)
|
|
5
|
+
|
|
3
6
|
This package contains a bunch of ESLint v9+ rules for RxJS.
|
|
4
7
|
It is a fork of [`eslint-plugin-rxjs`](https://github.com/cartant/eslint-plugin-rxjs)
|
|
5
8
|
initially started to support the new ESLint flat config format.
|
package/dist/index.cjs
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
'use strict';
|
|
1
|
+
'use strict';Object.defineProperty(exports, '__esModule', {value: true});
|
|
2
2
|
|
|
3
3
|
const utils = require('@typescript-eslint/utils');
|
|
4
4
|
const commonTags = require('common-tags');
|
|
5
|
-
const tsutils = require('
|
|
5
|
+
const tsutils = require('ts-api-utils');
|
|
6
6
|
const ts = require('typescript');
|
|
7
7
|
const scopeManager = require('@typescript-eslint/scope-manager');
|
|
8
|
-
const tsutils$1 = require('tsutils');
|
|
9
8
|
const decamelize = require('decamelize');
|
|
10
9
|
|
|
11
10
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
|
@@ -24,11 +23,10 @@ function _interopNamespaceCompat(e) {
|
|
|
24
23
|
|
|
25
24
|
const tsutils__namespace = /*#__PURE__*/_interopNamespaceCompat(tsutils);
|
|
26
25
|
const ts__namespace = /*#__PURE__*/_interopNamespaceCompat(ts);
|
|
27
|
-
const tsutils__namespace$1 = /*#__PURE__*/_interopNamespaceCompat(tsutils$1);
|
|
28
26
|
const decamelize__default = /*#__PURE__*/_interopDefaultCompat(decamelize);
|
|
29
27
|
|
|
30
28
|
const name = "eslint-plugin-rxjs-x";
|
|
31
|
-
const version = "0.0
|
|
29
|
+
const version = "0.1.0";
|
|
32
30
|
|
|
33
31
|
const createRecommendedConfig = (plugin) => ({
|
|
34
32
|
plugins: {
|
|
@@ -200,6 +198,75 @@ const banOperatorsRule = ruleCreator({
|
|
|
200
198
|
}
|
|
201
199
|
});
|
|
202
200
|
|
|
201
|
+
function couldBeType(type, name, qualified) {
|
|
202
|
+
if (tsutils__namespace.isTypeReference(type)) {
|
|
203
|
+
type = type.target;
|
|
204
|
+
}
|
|
205
|
+
if (isType(type, name, qualified)) {
|
|
206
|
+
return true;
|
|
207
|
+
}
|
|
208
|
+
if (tsutils__namespace.isUnionOrIntersectionType(type)) {
|
|
209
|
+
return type.types.some((t) => couldBeType(t, name, qualified));
|
|
210
|
+
}
|
|
211
|
+
const baseTypes = type.getBaseTypes();
|
|
212
|
+
if (baseTypes?.some((t) => couldBeType(t, name, qualified))) {
|
|
213
|
+
return true;
|
|
214
|
+
}
|
|
215
|
+
if (couldImplement(type, name, qualified)) {
|
|
216
|
+
return true;
|
|
217
|
+
}
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
function isType(type, name, qualified) {
|
|
221
|
+
if (!type.symbol) {
|
|
222
|
+
return false;
|
|
223
|
+
}
|
|
224
|
+
if (qualified && !qualified.name.test(
|
|
225
|
+
qualified.typeChecker.getFullyQualifiedName(type.symbol)
|
|
226
|
+
)) {
|
|
227
|
+
return false;
|
|
228
|
+
}
|
|
229
|
+
return typeof name === "string" ? type.symbol.name === name : Boolean(type.symbol.name.match(name));
|
|
230
|
+
}
|
|
231
|
+
function couldImplement(type, name, qualified) {
|
|
232
|
+
const { symbol } = type;
|
|
233
|
+
if (symbol) {
|
|
234
|
+
const { valueDeclaration } = symbol;
|
|
235
|
+
if (valueDeclaration && ts__namespace.isClassDeclaration(valueDeclaration)) {
|
|
236
|
+
const { heritageClauses } = valueDeclaration;
|
|
237
|
+
if (heritageClauses) {
|
|
238
|
+
const implemented = heritageClauses.some(
|
|
239
|
+
({ token, types }) => token === ts__namespace.SyntaxKind.ImplementsKeyword && types.some((node) => isMatchingNode(node, name, qualified))
|
|
240
|
+
);
|
|
241
|
+
if (implemented) {
|
|
242
|
+
return true;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return false;
|
|
248
|
+
}
|
|
249
|
+
function isMatchingNode(node, name, qualified) {
|
|
250
|
+
const { expression } = node;
|
|
251
|
+
if (qualified) {
|
|
252
|
+
const type = qualified.typeChecker.getTypeAtLocation(expression);
|
|
253
|
+
if (type) {
|
|
254
|
+
const qualifiedName = qualified.typeChecker.getFullyQualifiedName(
|
|
255
|
+
type.symbol
|
|
256
|
+
);
|
|
257
|
+
if (!qualified.name.test(qualifiedName)) {
|
|
258
|
+
return false;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
const text = expression.getText();
|
|
263
|
+
return typeof name === "string" ? text === name : Boolean(text.match(name));
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
function couldBeFunction(type) {
|
|
267
|
+
return type.getCallSignatures().length > 0 || couldBeType(type, "Function") || couldBeType(type, "ArrowFunction") || couldBeType(type, ts__namespace.InternalSymbolName.Function);
|
|
268
|
+
}
|
|
269
|
+
|
|
203
270
|
function findParent(node, ...args) {
|
|
204
271
|
const [arg] = args;
|
|
205
272
|
const predicate = typeof arg === "function" ? arg : (type) => !args.includes(type) ? "continue" : "return";
|
|
@@ -282,9 +349,9 @@ function getTypeServices(context) {
|
|
|
282
349
|
const services = utils.ESLintUtils.getParserServices(context);
|
|
283
350
|
const { esTreeNodeToTSNodeMap, program, getTypeAtLocation } = services;
|
|
284
351
|
const typeChecker = program.getTypeChecker();
|
|
285
|
-
const couldBeType = (node, name, qualified) => {
|
|
352
|
+
const couldBeType$1 = (node, name, qualified) => {
|
|
286
353
|
const type = getType(node);
|
|
287
|
-
return
|
|
354
|
+
return couldBeType(
|
|
288
355
|
type,
|
|
289
356
|
name,
|
|
290
357
|
qualified ? { ...qualified, typeChecker } : void 0
|
|
@@ -299,7 +366,7 @@ function getTypeServices(context) {
|
|
|
299
366
|
tsTypeNode = tsNode.type;
|
|
300
367
|
}
|
|
301
368
|
return Boolean(
|
|
302
|
-
tsTypeNode &&
|
|
369
|
+
tsTypeNode && couldBeType(
|
|
303
370
|
typeChecker.getTypeAtLocation(tsTypeNode),
|
|
304
371
|
name,
|
|
305
372
|
qualified ? { ...qualified, typeChecker } : void 0
|
|
@@ -310,25 +377,25 @@ function getTypeServices(context) {
|
|
|
310
377
|
return getTypeAtLocation(node);
|
|
311
378
|
};
|
|
312
379
|
return {
|
|
313
|
-
couldBeBehaviorSubject: (node) => couldBeType(node, "BehaviorSubject"),
|
|
314
|
-
couldBeError: (node) => couldBeType(node, "Error"),
|
|
380
|
+
couldBeBehaviorSubject: (node) => couldBeType$1(node, "BehaviorSubject"),
|
|
381
|
+
couldBeError: (node) => couldBeType$1(node, "Error"),
|
|
315
382
|
couldBeFunction: (node) => {
|
|
316
383
|
if (isArrowFunctionExpression(node) || isFunctionDeclaration(node)) {
|
|
317
384
|
return true;
|
|
318
385
|
}
|
|
319
|
-
return
|
|
386
|
+
return couldBeFunction(getType(node));
|
|
320
387
|
},
|
|
321
|
-
couldBeMonoTypeOperatorFunction: (node) => couldBeType(node, "MonoTypeOperatorFunction"),
|
|
322
|
-
couldBeObservable: (node) => couldBeType(node, "Observable"),
|
|
323
|
-
couldBeSubject: (node) => couldBeType(node, "Subject"),
|
|
324
|
-
couldBeSubscription: (node) => couldBeType(node, "Subscription"),
|
|
325
|
-
couldBeType,
|
|
388
|
+
couldBeMonoTypeOperatorFunction: (node) => couldBeType$1(node, "MonoTypeOperatorFunction"),
|
|
389
|
+
couldBeObservable: (node) => couldBeType$1(node, "Observable"),
|
|
390
|
+
couldBeSubject: (node) => couldBeType$1(node, "Subject"),
|
|
391
|
+
couldBeSubscription: (node) => couldBeType$1(node, "Subscription"),
|
|
392
|
+
couldBeType: couldBeType$1,
|
|
326
393
|
couldReturnObservable: (node) => couldReturnType(node, "Observable"),
|
|
327
394
|
couldReturnType,
|
|
328
395
|
getType,
|
|
329
|
-
isAny: (node) => tsutils__namespace.
|
|
330
|
-
isReferenceType: (node) => tsutils__namespace.
|
|
331
|
-
isUnknown: (node) => tsutils__namespace.
|
|
396
|
+
isAny: (node) => tsutils__namespace.isIntrinsicAnyType(getType(node)),
|
|
397
|
+
isReferenceType: (node) => tsutils__namespace.isTypeReference(getType(node)),
|
|
398
|
+
isUnknown: (node) => tsutils__namespace.isIntrinsicUnknownType(getType(node)),
|
|
332
399
|
typeChecker
|
|
333
400
|
};
|
|
334
401
|
}
|
|
@@ -2288,19 +2355,19 @@ const noUnsafeSubjectNext = ruleCreator({
|
|
|
2288
2355
|
[`CallExpression[callee.property.name='next']`]: (node) => {
|
|
2289
2356
|
if (node.arguments.length === 0 && isMemberExpression(node.callee)) {
|
|
2290
2357
|
const type = getType(node.callee.object);
|
|
2291
|
-
if (
|
|
2358
|
+
if (tsutils__namespace.isTypeReference(type) && couldBeType(type, "Subject")) {
|
|
2292
2359
|
const [typeArg] = typeChecker.getTypeArguments(type);
|
|
2293
|
-
if (tsutils__namespace
|
|
2360
|
+
if (tsutils__namespace.isTypeFlagSet(typeArg, ts__namespace.TypeFlags.Any)) {
|
|
2294
2361
|
return;
|
|
2295
2362
|
}
|
|
2296
|
-
if (tsutils__namespace
|
|
2363
|
+
if (tsutils__namespace.isTypeFlagSet(typeArg, ts__namespace.TypeFlags.Unknown)) {
|
|
2297
2364
|
return;
|
|
2298
2365
|
}
|
|
2299
|
-
if (tsutils__namespace
|
|
2366
|
+
if (tsutils__namespace.isTypeFlagSet(typeArg, ts__namespace.TypeFlags.Void)) {
|
|
2300
2367
|
return;
|
|
2301
2368
|
}
|
|
2302
|
-
if (
|
|
2303
|
-
(t) => tsutils__namespace
|
|
2369
|
+
if (tsutils__namespace.isUnionType(typeArg) && typeArg.types.some(
|
|
2370
|
+
(t) => tsutils__namespace.isTypeFlagSet(t, ts__namespace.TypeFlags.Void)
|
|
2304
2371
|
)) {
|
|
2305
2372
|
return;
|
|
2306
2373
|
}
|
|
@@ -2852,13 +2919,13 @@ const throwErrorRule = ruleCreator({
|
|
|
2852
2919
|
const { couldBeObservable, getType } = getTypeServices(context);
|
|
2853
2920
|
function checkNode(node) {
|
|
2854
2921
|
let type = getType(node);
|
|
2855
|
-
if (
|
|
2922
|
+
if (couldBeFunction(type)) {
|
|
2856
2923
|
const tsNode = esTreeNodeToTSNodeMap.get(node);
|
|
2857
2924
|
const annotation = tsNode.type;
|
|
2858
2925
|
const body = tsNode.body;
|
|
2859
2926
|
type = program.getTypeChecker().getTypeAtLocation(annotation ?? body);
|
|
2860
2927
|
}
|
|
2861
|
-
if (!
|
|
2928
|
+
if (!tsutils__namespace.isIntrinsicAnyType(type) && !tsutils__namespace.isIntrinsicUnknownType(type) && !couldBeType(type, /^(Error|DOMException)$/)) {
|
|
2862
2929
|
context.report({
|
|
2863
2930
|
messageId: "forbidden",
|
|
2864
2931
|
node
|
|
@@ -2925,12 +2992,11 @@ const plugin = {
|
|
|
2925
2992
|
"throw-error": throwErrorRule
|
|
2926
2993
|
}
|
|
2927
2994
|
};
|
|
2928
|
-
const
|
|
2929
|
-
recommended: createRecommendedConfig(plugin)
|
|
2930
|
-
};
|
|
2931
|
-
const index = {
|
|
2995
|
+
const rxjsX = {
|
|
2932
2996
|
...plugin,
|
|
2933
|
-
configs
|
|
2997
|
+
configs: {
|
|
2998
|
+
recommended: createRecommendedConfig(plugin)
|
|
2999
|
+
}
|
|
2934
3000
|
};
|
|
2935
3001
|
|
|
2936
|
-
|
|
3002
|
+
exports.default = rxjsX;
|
package/dist/index.d.cts
CHANGED
|
@@ -6,7 +6,7 @@ interface RxjsXRuleDocs {
|
|
|
6
6
|
requiresTypeChecking?: boolean;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
declare const
|
|
9
|
+
declare const rxjsX: {
|
|
10
10
|
configs: {
|
|
11
11
|
recommended: {
|
|
12
12
|
plugins: {
|
|
@@ -118,4 +118,4 @@ declare const _default: {
|
|
|
118
118
|
};
|
|
119
119
|
};
|
|
120
120
|
|
|
121
|
-
export {
|
|
121
|
+
export { rxjsX as default };
|
package/dist/index.d.mts
CHANGED
|
@@ -6,7 +6,7 @@ interface RxjsXRuleDocs {
|
|
|
6
6
|
requiresTypeChecking?: boolean;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
declare const
|
|
9
|
+
declare const rxjsX: {
|
|
10
10
|
configs: {
|
|
11
11
|
recommended: {
|
|
12
12
|
plugins: {
|
|
@@ -118,4 +118,4 @@ declare const _default: {
|
|
|
118
118
|
};
|
|
119
119
|
};
|
|
120
120
|
|
|
121
|
-
export {
|
|
121
|
+
export { rxjsX as default };
|
package/dist/index.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ interface RxjsXRuleDocs {
|
|
|
6
6
|
requiresTypeChecking?: boolean;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
declare const
|
|
9
|
+
declare const rxjsX: {
|
|
10
10
|
configs: {
|
|
11
11
|
recommended: {
|
|
12
12
|
plugins: {
|
|
@@ -118,4 +118,4 @@ declare const _default: {
|
|
|
118
118
|
};
|
|
119
119
|
};
|
|
120
120
|
|
|
121
|
-
export {
|
|
121
|
+
export { rxjsX as default };
|
package/dist/index.mjs
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import { ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';
|
|
2
2
|
import { stripIndent } from 'common-tags';
|
|
3
|
-
import * as tsutils from '
|
|
4
|
-
import { isReferenceType, couldBeType, isUnionType, couldBeFunction, isAny, isUnknown } from 'tsutils-etc';
|
|
3
|
+
import * as tsutils from 'ts-api-utils';
|
|
5
4
|
import * as ts from 'typescript';
|
|
6
5
|
import { DefinitionType } from '@typescript-eslint/scope-manager';
|
|
7
|
-
import * as tsutils$1 from 'tsutils';
|
|
8
6
|
import decamelize from 'decamelize';
|
|
9
7
|
|
|
10
8
|
const name = "eslint-plugin-rxjs-x";
|
|
11
|
-
const version = "0.0
|
|
9
|
+
const version = "0.1.0";
|
|
12
10
|
|
|
13
11
|
const createRecommendedConfig = (plugin) => ({
|
|
14
12
|
plugins: {
|
|
@@ -180,6 +178,75 @@ const banOperatorsRule = ruleCreator({
|
|
|
180
178
|
}
|
|
181
179
|
});
|
|
182
180
|
|
|
181
|
+
function couldBeType(type, name, qualified) {
|
|
182
|
+
if (tsutils.isTypeReference(type)) {
|
|
183
|
+
type = type.target;
|
|
184
|
+
}
|
|
185
|
+
if (isType(type, name, qualified)) {
|
|
186
|
+
return true;
|
|
187
|
+
}
|
|
188
|
+
if (tsutils.isUnionOrIntersectionType(type)) {
|
|
189
|
+
return type.types.some((t) => couldBeType(t, name, qualified));
|
|
190
|
+
}
|
|
191
|
+
const baseTypes = type.getBaseTypes();
|
|
192
|
+
if (baseTypes?.some((t) => couldBeType(t, name, qualified))) {
|
|
193
|
+
return true;
|
|
194
|
+
}
|
|
195
|
+
if (couldImplement(type, name, qualified)) {
|
|
196
|
+
return true;
|
|
197
|
+
}
|
|
198
|
+
return false;
|
|
199
|
+
}
|
|
200
|
+
function isType(type, name, qualified) {
|
|
201
|
+
if (!type.symbol) {
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
204
|
+
if (qualified && !qualified.name.test(
|
|
205
|
+
qualified.typeChecker.getFullyQualifiedName(type.symbol)
|
|
206
|
+
)) {
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
return typeof name === "string" ? type.symbol.name === name : Boolean(type.symbol.name.match(name));
|
|
210
|
+
}
|
|
211
|
+
function couldImplement(type, name, qualified) {
|
|
212
|
+
const { symbol } = type;
|
|
213
|
+
if (symbol) {
|
|
214
|
+
const { valueDeclaration } = symbol;
|
|
215
|
+
if (valueDeclaration && ts.isClassDeclaration(valueDeclaration)) {
|
|
216
|
+
const { heritageClauses } = valueDeclaration;
|
|
217
|
+
if (heritageClauses) {
|
|
218
|
+
const implemented = heritageClauses.some(
|
|
219
|
+
({ token, types }) => token === ts.SyntaxKind.ImplementsKeyword && types.some((node) => isMatchingNode(node, name, qualified))
|
|
220
|
+
);
|
|
221
|
+
if (implemented) {
|
|
222
|
+
return true;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
return false;
|
|
228
|
+
}
|
|
229
|
+
function isMatchingNode(node, name, qualified) {
|
|
230
|
+
const { expression } = node;
|
|
231
|
+
if (qualified) {
|
|
232
|
+
const type = qualified.typeChecker.getTypeAtLocation(expression);
|
|
233
|
+
if (type) {
|
|
234
|
+
const qualifiedName = qualified.typeChecker.getFullyQualifiedName(
|
|
235
|
+
type.symbol
|
|
236
|
+
);
|
|
237
|
+
if (!qualified.name.test(qualifiedName)) {
|
|
238
|
+
return false;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
const text = expression.getText();
|
|
243
|
+
return typeof name === "string" ? text === name : Boolean(text.match(name));
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
function couldBeFunction(type) {
|
|
247
|
+
return type.getCallSignatures().length > 0 || couldBeType(type, "Function") || couldBeType(type, "ArrowFunction") || couldBeType(type, ts.InternalSymbolName.Function);
|
|
248
|
+
}
|
|
249
|
+
|
|
183
250
|
function findParent(node, ...args) {
|
|
184
251
|
const [arg] = args;
|
|
185
252
|
const predicate = typeof arg === "function" ? arg : (type) => !args.includes(type) ? "continue" : "return";
|
|
@@ -262,9 +329,9 @@ function getTypeServices(context) {
|
|
|
262
329
|
const services = ESLintUtils.getParserServices(context);
|
|
263
330
|
const { esTreeNodeToTSNodeMap, program, getTypeAtLocation } = services;
|
|
264
331
|
const typeChecker = program.getTypeChecker();
|
|
265
|
-
const couldBeType = (node, name, qualified) => {
|
|
332
|
+
const couldBeType$1 = (node, name, qualified) => {
|
|
266
333
|
const type = getType(node);
|
|
267
|
-
return
|
|
334
|
+
return couldBeType(
|
|
268
335
|
type,
|
|
269
336
|
name,
|
|
270
337
|
qualified ? { ...qualified, typeChecker } : void 0
|
|
@@ -279,7 +346,7 @@ function getTypeServices(context) {
|
|
|
279
346
|
tsTypeNode = tsNode.type;
|
|
280
347
|
}
|
|
281
348
|
return Boolean(
|
|
282
|
-
tsTypeNode &&
|
|
349
|
+
tsTypeNode && couldBeType(
|
|
283
350
|
typeChecker.getTypeAtLocation(tsTypeNode),
|
|
284
351
|
name,
|
|
285
352
|
qualified ? { ...qualified, typeChecker } : void 0
|
|
@@ -290,25 +357,25 @@ function getTypeServices(context) {
|
|
|
290
357
|
return getTypeAtLocation(node);
|
|
291
358
|
};
|
|
292
359
|
return {
|
|
293
|
-
couldBeBehaviorSubject: (node) => couldBeType(node, "BehaviorSubject"),
|
|
294
|
-
couldBeError: (node) => couldBeType(node, "Error"),
|
|
360
|
+
couldBeBehaviorSubject: (node) => couldBeType$1(node, "BehaviorSubject"),
|
|
361
|
+
couldBeError: (node) => couldBeType$1(node, "Error"),
|
|
295
362
|
couldBeFunction: (node) => {
|
|
296
363
|
if (isArrowFunctionExpression(node) || isFunctionDeclaration(node)) {
|
|
297
364
|
return true;
|
|
298
365
|
}
|
|
299
|
-
return
|
|
366
|
+
return couldBeFunction(getType(node));
|
|
300
367
|
},
|
|
301
|
-
couldBeMonoTypeOperatorFunction: (node) => couldBeType(node, "MonoTypeOperatorFunction"),
|
|
302
|
-
couldBeObservable: (node) => couldBeType(node, "Observable"),
|
|
303
|
-
couldBeSubject: (node) => couldBeType(node, "Subject"),
|
|
304
|
-
couldBeSubscription: (node) => couldBeType(node, "Subscription"),
|
|
305
|
-
couldBeType,
|
|
368
|
+
couldBeMonoTypeOperatorFunction: (node) => couldBeType$1(node, "MonoTypeOperatorFunction"),
|
|
369
|
+
couldBeObservable: (node) => couldBeType$1(node, "Observable"),
|
|
370
|
+
couldBeSubject: (node) => couldBeType$1(node, "Subject"),
|
|
371
|
+
couldBeSubscription: (node) => couldBeType$1(node, "Subscription"),
|
|
372
|
+
couldBeType: couldBeType$1,
|
|
306
373
|
couldReturnObservable: (node) => couldReturnType(node, "Observable"),
|
|
307
374
|
couldReturnType,
|
|
308
375
|
getType,
|
|
309
|
-
isAny: (node) => tsutils.
|
|
310
|
-
isReferenceType: (node) => tsutils.
|
|
311
|
-
isUnknown: (node) => tsutils.
|
|
376
|
+
isAny: (node) => tsutils.isIntrinsicAnyType(getType(node)),
|
|
377
|
+
isReferenceType: (node) => tsutils.isTypeReference(getType(node)),
|
|
378
|
+
isUnknown: (node) => tsutils.isIntrinsicUnknownType(getType(node)),
|
|
312
379
|
typeChecker
|
|
313
380
|
};
|
|
314
381
|
}
|
|
@@ -2268,19 +2335,19 @@ const noUnsafeSubjectNext = ruleCreator({
|
|
|
2268
2335
|
[`CallExpression[callee.property.name='next']`]: (node) => {
|
|
2269
2336
|
if (node.arguments.length === 0 && isMemberExpression(node.callee)) {
|
|
2270
2337
|
const type = getType(node.callee.object);
|
|
2271
|
-
if (
|
|
2338
|
+
if (tsutils.isTypeReference(type) && couldBeType(type, "Subject")) {
|
|
2272
2339
|
const [typeArg] = typeChecker.getTypeArguments(type);
|
|
2273
|
-
if (tsutils
|
|
2340
|
+
if (tsutils.isTypeFlagSet(typeArg, ts.TypeFlags.Any)) {
|
|
2274
2341
|
return;
|
|
2275
2342
|
}
|
|
2276
|
-
if (tsutils
|
|
2343
|
+
if (tsutils.isTypeFlagSet(typeArg, ts.TypeFlags.Unknown)) {
|
|
2277
2344
|
return;
|
|
2278
2345
|
}
|
|
2279
|
-
if (tsutils
|
|
2346
|
+
if (tsutils.isTypeFlagSet(typeArg, ts.TypeFlags.Void)) {
|
|
2280
2347
|
return;
|
|
2281
2348
|
}
|
|
2282
|
-
if (isUnionType(typeArg) && typeArg.types.some(
|
|
2283
|
-
(t) => tsutils
|
|
2349
|
+
if (tsutils.isUnionType(typeArg) && typeArg.types.some(
|
|
2350
|
+
(t) => tsutils.isTypeFlagSet(t, ts.TypeFlags.Void)
|
|
2284
2351
|
)) {
|
|
2285
2352
|
return;
|
|
2286
2353
|
}
|
|
@@ -2838,7 +2905,7 @@ const throwErrorRule = ruleCreator({
|
|
|
2838
2905
|
const body = tsNode.body;
|
|
2839
2906
|
type = program.getTypeChecker().getTypeAtLocation(annotation ?? body);
|
|
2840
2907
|
}
|
|
2841
|
-
if (!
|
|
2908
|
+
if (!tsutils.isIntrinsicAnyType(type) && !tsutils.isIntrinsicUnknownType(type) && !couldBeType(type, /^(Error|DOMException)$/)) {
|
|
2842
2909
|
context.report({
|
|
2843
2910
|
messageId: "forbidden",
|
|
2844
2911
|
node
|
|
@@ -2905,12 +2972,11 @@ const plugin = {
|
|
|
2905
2972
|
"throw-error": throwErrorRule
|
|
2906
2973
|
}
|
|
2907
2974
|
};
|
|
2908
|
-
const
|
|
2909
|
-
recommended: createRecommendedConfig(plugin)
|
|
2910
|
-
};
|
|
2911
|
-
const index = {
|
|
2975
|
+
const rxjsX = {
|
|
2912
2976
|
...plugin,
|
|
2913
|
-
configs
|
|
2977
|
+
configs: {
|
|
2978
|
+
recommended: createRecommendedConfig(plugin)
|
|
2979
|
+
}
|
|
2914
2980
|
};
|
|
2915
2981
|
|
|
2916
|
-
export {
|
|
2982
|
+
export { rxjsX as default };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-rxjs-x",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0
|
|
4
|
+
"version": "0.1.0",
|
|
5
5
|
"packageManager": "yarn@4.5.1+sha512.341db9396b6e289fecc30cd7ab3af65060e05ebff4b3b47547b278b9e67b08f485ecd8c79006b405446262142c7a38154445ef7f17c1d5d1de7d90bf9ce7054d",
|
|
6
6
|
"description": "ESLint v9+ plugin for RxJS",
|
|
7
7
|
"author": "Jason Weinzierl <weinzierljason@gmail.com>",
|
|
@@ -23,9 +23,14 @@
|
|
|
23
23
|
"sideEffects": false,
|
|
24
24
|
"exports": {
|
|
25
25
|
".": {
|
|
26
|
-
"
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
"import": {
|
|
27
|
+
"types": "./dist/index.d.mts",
|
|
28
|
+
"default": "./dist/index.mjs"
|
|
29
|
+
},
|
|
30
|
+
"require": {
|
|
31
|
+
"types": "./dist/index.d.cts",
|
|
32
|
+
"default": "./dist/index.cjs"
|
|
33
|
+
}
|
|
29
34
|
}
|
|
30
35
|
},
|
|
31
36
|
"main": "./dist/index.mjs",
|
|
@@ -36,7 +41,7 @@
|
|
|
36
41
|
"docs"
|
|
37
42
|
],
|
|
38
43
|
"scripts": {
|
|
39
|
-
"build": "unbuild",
|
|
44
|
+
"build": "unbuild && tsx scripts/postbuild.ts",
|
|
40
45
|
"lint": "eslint",
|
|
41
46
|
"release": "bumpp && yarn run build",
|
|
42
47
|
"test": "vitest",
|
|
@@ -48,14 +53,13 @@
|
|
|
48
53
|
"@typescript-eslint/utils": "^8.12.2",
|
|
49
54
|
"common-tags": "^1.8.0",
|
|
50
55
|
"decamelize": "^5.0.0 || ^6.0.0",
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
"tsutils-etc": "^1.4.2"
|
|
56
|
+
"ts-api-utils": "^1.3.0",
|
|
57
|
+
"tslib": "^2.1.0"
|
|
54
58
|
},
|
|
55
59
|
"peerDependencies": {
|
|
56
60
|
"eslint": "^8.57.0 || ^9.0.0",
|
|
57
61
|
"rxjs": ">=7.0.0",
|
|
58
|
-
"typescript": ">=4.
|
|
62
|
+
"typescript": ">=4.2.0"
|
|
59
63
|
},
|
|
60
64
|
"devDependencies": {
|
|
61
65
|
"@eslint/js": "^9.13.0",
|
|
@@ -63,7 +67,9 @@
|
|
|
63
67
|
"@types/common-tags": "^1.8.4",
|
|
64
68
|
"@types/node": "^18.18.0",
|
|
65
69
|
"@typescript-eslint/rule-tester": "^8.12.2",
|
|
70
|
+
"@typescript/vfs": "^1.6.0",
|
|
66
71
|
"@vitest/coverage-v8": "^2.1.4",
|
|
72
|
+
"@vitest/eslint-plugin": "^1.1.7",
|
|
67
73
|
"bumpp": "^9.8.0",
|
|
68
74
|
"eslint": "^9.13.0",
|
|
69
75
|
"eslint-config-flat-gitignore": "^0.3.0",
|
|
@@ -71,6 +77,7 @@
|
|
|
71
77
|
"eslint-plugin-import-x": "^4.4.0",
|
|
72
78
|
"eslint-plugin-n": "^17.12.0",
|
|
73
79
|
"rxjs": "^7.0.0",
|
|
80
|
+
"tsx": "^4.19.2",
|
|
74
81
|
"typescript": "~5.6.3",
|
|
75
82
|
"typescript-eslint": "^8.12.2",
|
|
76
83
|
"unbuild": "^2.0.0",
|