eslint-plugin-rxjs-x 0.7.4 → 0.7.5
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 -1
- package/dist/index.d.mts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +78 -45
- package/dist/index.mjs +78 -45
- package/package.json +11 -10
package/README.md
CHANGED
|
@@ -120,6 +120,6 @@ The package includes the following rules.
|
|
|
120
120
|
| [prefer-observer](docs/rules/prefer-observer.md) | Disallow passing separate handlers to `subscribe` and `tap`. | ✅ 🔒 | 🔧 | 💡 | 💭 | |
|
|
121
121
|
| [prefer-root-operators](docs/rules/prefer-root-operators.md) | Disallow importing operators from `rxjs/operators`. | ✅ 🔒 | 🔧 | 💡 | | |
|
|
122
122
|
| [suffix-subjects](docs/rules/suffix-subjects.md) | Enforce the use of a suffix in subject identifiers. | | | | 💭 | |
|
|
123
|
-
| [throw-error](docs/rules/throw-error.md) | Enforce passing only `Error` values to `throwError`.
|
|
123
|
+
| [throw-error](docs/rules/throw-error.md) | Enforce passing only `Error` values to `throwError` or `Subject.error`. | ✅ 🔒 | | | 💭 | |
|
|
124
124
|
|
|
125
125
|
<!-- end auto-generated rules list -->
|
package/dist/index.d.mts
CHANGED
|
@@ -150,7 +150,9 @@ declare const rxjsX: {
|
|
|
150
150
|
'no-subscribe-in-pipe': TSESLint.RuleModule<"forbidden", [], RxjsXRuleDocs, TSESLint.RuleListener>;
|
|
151
151
|
'no-tap': TSESLint.RuleModule<"forbidden", [], RxjsXRuleDocs, TSESLint.RuleListener>;
|
|
152
152
|
'no-topromise': TSESLint.RuleModule<"forbidden" | "suggestLastValueFromWithDefault" | "suggestLastValueFrom" | "suggestFirstValueFrom", [], RxjsXRuleDocs, TSESLint.RuleListener>;
|
|
153
|
-
'no-unbound-methods': TSESLint.RuleModule<"forbidden",
|
|
153
|
+
'no-unbound-methods': TSESLint.RuleModule<"forbidden", readonly {
|
|
154
|
+
allowTypes?: string[];
|
|
155
|
+
}[], RxjsXRuleDocs, TSESLint.RuleListener>;
|
|
154
156
|
'no-unsafe-catch': TSESLint.RuleModule<"forbidden", readonly {
|
|
155
157
|
observable?: string;
|
|
156
158
|
}[], RxjsXRuleDocs, TSESLint.RuleListener>;
|
package/dist/index.d.ts
CHANGED
|
@@ -150,7 +150,9 @@ declare const rxjsX: {
|
|
|
150
150
|
'no-subscribe-in-pipe': TSESLint.RuleModule<"forbidden", [], RxjsXRuleDocs, TSESLint.RuleListener>;
|
|
151
151
|
'no-tap': TSESLint.RuleModule<"forbidden", [], RxjsXRuleDocs, TSESLint.RuleListener>;
|
|
152
152
|
'no-topromise': TSESLint.RuleModule<"forbidden" | "suggestLastValueFromWithDefault" | "suggestLastValueFrom" | "suggestFirstValueFrom", [], RxjsXRuleDocs, TSESLint.RuleListener>;
|
|
153
|
-
'no-unbound-methods': TSESLint.RuleModule<"forbidden",
|
|
153
|
+
'no-unbound-methods': TSESLint.RuleModule<"forbidden", readonly {
|
|
154
|
+
allowTypes?: string[];
|
|
155
|
+
}[], RxjsXRuleDocs, TSESLint.RuleListener>;
|
|
154
156
|
'no-unsafe-catch': TSESLint.RuleModule<"forbidden", readonly {
|
|
155
157
|
observable?: string;
|
|
156
158
|
}[], RxjsXRuleDocs, TSESLint.RuleListener>;
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }// package.json
|
|
2
2
|
var name = "eslint-plugin-rxjs-x";
|
|
3
|
-
var version = "0.7.
|
|
3
|
+
var version = "0.7.5";
|
|
4
4
|
|
|
5
5
|
// src/configs/recommended.ts
|
|
6
6
|
var createRecommendedConfig = (plugin2) => ({
|
|
@@ -398,6 +398,9 @@ var SOURCES_OBJECT_ACCEPTING_STATIC_OBSERVABLE_CREATORS = [
|
|
|
398
398
|
"combineLatest",
|
|
399
399
|
"forkJoin"
|
|
400
400
|
];
|
|
401
|
+
var DEFAULT_UNBOUND_ALLOWED_TYPES = [
|
|
402
|
+
"Signal"
|
|
403
|
+
];
|
|
401
404
|
var DEFAULT_VALID_POST_COMPLETION_OPERATORS = [
|
|
402
405
|
"count",
|
|
403
406
|
"defaultIfEmpty",
|
|
@@ -932,7 +935,7 @@ var noAsyncSubscribeRule = ruleCreator({
|
|
|
932
935
|
requiresTypeChecking: true
|
|
933
936
|
},
|
|
934
937
|
messages: {
|
|
935
|
-
forbidden: "Passing async functions to subscribe is forbidden."
|
|
938
|
+
forbidden: "Passing async functions to subscribe is forbidden. Use operators like `concatMap` or `switchMap` to avoid race conditions."
|
|
936
939
|
},
|
|
937
940
|
schema: [],
|
|
938
941
|
type: "problem"
|
|
@@ -940,27 +943,39 @@ var noAsyncSubscribeRule = ruleCreator({
|
|
|
940
943
|
name: "no-async-subscribe",
|
|
941
944
|
create: (context) => {
|
|
942
945
|
const { couldBeObservable } = getTypeServices(context);
|
|
943
|
-
function
|
|
944
|
-
const
|
|
946
|
+
function report(node) {
|
|
947
|
+
const { loc } = node;
|
|
948
|
+
const asyncLoc = {
|
|
949
|
+
...loc,
|
|
950
|
+
end: {
|
|
951
|
+
...loc.start,
|
|
952
|
+
column: loc.start.column + 5
|
|
953
|
+
}
|
|
954
|
+
};
|
|
955
|
+
context.report({
|
|
956
|
+
messageId: "forbidden",
|
|
957
|
+
loc: asyncLoc
|
|
958
|
+
});
|
|
959
|
+
}
|
|
960
|
+
function checkSingleNext(funcNode) {
|
|
961
|
+
const parentNode = funcNode.parent;
|
|
945
962
|
const callee = parentNode.callee;
|
|
946
963
|
if (couldBeObservable(callee.object)) {
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
context.report({
|
|
956
|
-
messageId: "forbidden",
|
|
957
|
-
loc: asyncLoc
|
|
958
|
-
});
|
|
964
|
+
report(funcNode);
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
function checkObserverObjectProp(propNode) {
|
|
968
|
+
const parentNode = propNode.parent.parent;
|
|
969
|
+
const callee = parentNode.callee;
|
|
970
|
+
if (couldBeObservable(callee.object) && (isArrowFunctionExpression(propNode.value) || isFunctionExpression(propNode.value))) {
|
|
971
|
+
report(propNode.value);
|
|
959
972
|
}
|
|
960
973
|
}
|
|
961
974
|
return {
|
|
962
|
-
"CallExpression[callee.property.name='subscribe'] > FunctionExpression[async=true]":
|
|
963
|
-
"CallExpression[callee.property.name='subscribe'] > ArrowFunctionExpression[async=true]":
|
|
975
|
+
"CallExpression[callee.property.name='subscribe'] > FunctionExpression[async=true]": checkSingleNext,
|
|
976
|
+
"CallExpression[callee.property.name='subscribe'] > ArrowFunctionExpression[async=true]": checkSingleNext,
|
|
977
|
+
"CallExpression[callee.property.name='subscribe'] > ObjectExpression > Property[key.name='next'][value.type=\"ArrowFunctionExpression\"][value.async=true]": checkObserverObjectProp,
|
|
978
|
+
"CallExpression[callee.property.name='subscribe'] > ObjectExpression > Property[key.name='next'][value.type=\"FunctionExpression\"][value.async=true]": checkObserverObjectProp
|
|
964
979
|
};
|
|
965
980
|
}
|
|
966
981
|
});
|
|
@@ -3116,8 +3131,9 @@ import { ${functionName} } from ${quote}rxjs${quote};`
|
|
|
3116
3131
|
|
|
3117
3132
|
// src/rules/no-unbound-methods.ts
|
|
3118
3133
|
|
|
3134
|
+
var defaultOptions11 = [];
|
|
3119
3135
|
var noUnboundMethodsRule = ruleCreator({
|
|
3120
|
-
defaultOptions:
|
|
3136
|
+
defaultOptions: defaultOptions11,
|
|
3121
3137
|
meta: {
|
|
3122
3138
|
docs: {
|
|
3123
3139
|
description: "Disallow passing unbound methods.",
|
|
@@ -3127,7 +3143,14 @@ var noUnboundMethodsRule = ruleCreator({
|
|
|
3127
3143
|
messages: {
|
|
3128
3144
|
forbidden: "Unbound methods are forbidden."
|
|
3129
3145
|
},
|
|
3130
|
-
schema: [
|
|
3146
|
+
schema: [
|
|
3147
|
+
{
|
|
3148
|
+
properties: {
|
|
3149
|
+
allowTypes: { type: "array", items: { type: "string" }, description: "An array of function types that are allowed to be passed unbound.", default: DEFAULT_UNBOUND_ALLOWED_TYPES }
|
|
3150
|
+
},
|
|
3151
|
+
type: "object"
|
|
3152
|
+
}
|
|
3153
|
+
],
|
|
3131
3154
|
type: "problem"
|
|
3132
3155
|
},
|
|
3133
3156
|
name: "no-unbound-methods",
|
|
@@ -3135,9 +3158,14 @@ var noUnboundMethodsRule = ruleCreator({
|
|
|
3135
3158
|
const { getTypeAtLocation } = _utils.ESLintUtils.getParserServices(context);
|
|
3136
3159
|
const { couldBeObservable, couldBeSubscription } = getTypeServices(context);
|
|
3137
3160
|
const nodeMap = /* @__PURE__ */ new WeakMap();
|
|
3161
|
+
const [config = {}] = context.options;
|
|
3162
|
+
const { allowTypes = [] } = config;
|
|
3138
3163
|
function mapArguments(node) {
|
|
3139
3164
|
node.arguments.filter(isMemberExpression).forEach((arg) => {
|
|
3140
3165
|
const argType = getTypeAtLocation(arg);
|
|
3166
|
+
if (allowTypes.some((t) => couldBeType(argType, t))) {
|
|
3167
|
+
return;
|
|
3168
|
+
}
|
|
3141
3169
|
if (argType.getCallSignatures().length > 0) {
|
|
3142
3170
|
nodeMap.set(arg);
|
|
3143
3171
|
}
|
|
@@ -3180,9 +3208,9 @@ var noUnboundMethodsRule = ruleCreator({
|
|
|
3180
3208
|
|
|
3181
3209
|
// src/rules/no-unsafe-catch.ts
|
|
3182
3210
|
|
|
3183
|
-
var
|
|
3211
|
+
var defaultOptions12 = [];
|
|
3184
3212
|
var noUnsafeCatchRule = ruleCreator({
|
|
3185
|
-
defaultOptions:
|
|
3213
|
+
defaultOptions: defaultOptions12,
|
|
3186
3214
|
meta: {
|
|
3187
3215
|
docs: {
|
|
3188
3216
|
description: "Disallow unsafe `catchError` usage in effects and epics.",
|
|
@@ -3241,9 +3269,9 @@ var noUnsafeCatchRule = ruleCreator({
|
|
|
3241
3269
|
|
|
3242
3270
|
// src/rules/no-unsafe-first.ts
|
|
3243
3271
|
|
|
3244
|
-
var
|
|
3272
|
+
var defaultOptions13 = [];
|
|
3245
3273
|
var noUnsafeFirstRule = ruleCreator({
|
|
3246
|
-
defaultOptions:
|
|
3274
|
+
defaultOptions: defaultOptions13,
|
|
3247
3275
|
meta: {
|
|
3248
3276
|
docs: {
|
|
3249
3277
|
description: "Disallow unsafe `first`/`take` usage in effects and epics.",
|
|
@@ -3365,9 +3393,9 @@ var noUnsafeSubjectNext = ruleCreator({
|
|
|
3365
3393
|
// src/rules/no-unsafe-switchmap.ts
|
|
3366
3394
|
|
|
3367
3395
|
var _decamelize = require('decamelize'); var _decamelize2 = _interopRequireDefault(_decamelize);
|
|
3368
|
-
var
|
|
3396
|
+
var defaultOptions14 = [];
|
|
3369
3397
|
var noUnsafeSwitchmapRule = ruleCreator({
|
|
3370
|
-
defaultOptions:
|
|
3398
|
+
defaultOptions: defaultOptions14,
|
|
3371
3399
|
meta: {
|
|
3372
3400
|
docs: {
|
|
3373
3401
|
description: "Disallow unsafe `switchMap` usage in effects and epics.",
|
|
@@ -3490,9 +3518,9 @@ var noUnsafeSwitchmapRule = ruleCreator({
|
|
|
3490
3518
|
|
|
3491
3519
|
// src/rules/no-unsafe-takeuntil.ts
|
|
3492
3520
|
|
|
3493
|
-
var
|
|
3521
|
+
var defaultOptions15 = [];
|
|
3494
3522
|
var noUnsafeTakeuntilRule = ruleCreator({
|
|
3495
|
-
defaultOptions:
|
|
3523
|
+
defaultOptions: defaultOptions15,
|
|
3496
3524
|
meta: {
|
|
3497
3525
|
docs: {
|
|
3498
3526
|
description: "Disallow applying operators after `takeUntil`.",
|
|
@@ -3553,9 +3581,9 @@ var noUnsafeTakeuntilRule = ruleCreator({
|
|
|
3553
3581
|
});
|
|
3554
3582
|
|
|
3555
3583
|
// src/rules/prefer-observer.ts
|
|
3556
|
-
var
|
|
3584
|
+
var defaultOptions16 = [];
|
|
3557
3585
|
var preferObserverRule = ruleCreator({
|
|
3558
|
-
defaultOptions:
|
|
3586
|
+
defaultOptions: defaultOptions16,
|
|
3559
3587
|
meta: {
|
|
3560
3588
|
docs: {
|
|
3561
3589
|
description: "Disallow passing separate handlers to `subscribe` and `tap`.",
|
|
@@ -3791,9 +3819,9 @@ var preferRootOperatorsRule = ruleCreator({
|
|
|
3791
3819
|
|
|
3792
3820
|
// src/rules/suffix-subjects.ts
|
|
3793
3821
|
|
|
3794
|
-
var
|
|
3822
|
+
var defaultOptions17 = [];
|
|
3795
3823
|
var suffixSubjectsRule = ruleCreator({
|
|
3796
|
-
defaultOptions:
|
|
3824
|
+
defaultOptions: defaultOptions17,
|
|
3797
3825
|
meta: {
|
|
3798
3826
|
docs: {
|
|
3799
3827
|
description: "Enforce the use of a suffix in subject identifiers.",
|
|
@@ -3990,12 +4018,12 @@ var suffixSubjectsRule = ruleCreator({
|
|
|
3990
4018
|
// src/rules/throw-error.ts
|
|
3991
4019
|
|
|
3992
4020
|
|
|
3993
|
-
var
|
|
4021
|
+
var defaultOptions18 = [];
|
|
3994
4022
|
var throwErrorRule = ruleCreator({
|
|
3995
|
-
defaultOptions:
|
|
4023
|
+
defaultOptions: defaultOptions18,
|
|
3996
4024
|
meta: {
|
|
3997
4025
|
docs: {
|
|
3998
|
-
description: "Enforce passing only `Error` values to `throwError`.",
|
|
4026
|
+
description: "Enforce passing only `Error` values to `throwError` or `Subject.error`.",
|
|
3999
4027
|
recommended: {
|
|
4000
4028
|
recommended: true,
|
|
4001
4029
|
strict: [{ allowThrowingAny: false, allowThrowingUnknown: false }]
|
|
@@ -4019,14 +4047,14 @@ var throwErrorRule = ruleCreator({
|
|
|
4019
4047
|
name: "throw-error",
|
|
4020
4048
|
create: (context) => {
|
|
4021
4049
|
const { esTreeNodeToTSNodeMap, program, getTypeAtLocation } = _utils.ESLintUtils.getParserServices(context);
|
|
4022
|
-
const { couldBeObservable } = getTypeServices(context);
|
|
4050
|
+
const { couldBeObservable, couldBeSubject } = getTypeServices(context);
|
|
4023
4051
|
const [config = {}] = context.options;
|
|
4024
4052
|
const { allowThrowingAny = true, allowThrowingUnknown = true } = config;
|
|
4025
|
-
function checkThrowArgument(node) {
|
|
4053
|
+
function checkThrowArgument(node, noFunction = false) {
|
|
4026
4054
|
var _a;
|
|
4027
4055
|
let type = getTypeAtLocation(node);
|
|
4028
4056
|
let reportNode = node;
|
|
4029
|
-
if (couldBeFunction(type)) {
|
|
4057
|
+
if (!noFunction && couldBeFunction(type)) {
|
|
4030
4058
|
reportNode = (_a = node.body) != null ? _a : node;
|
|
4031
4059
|
const tsNode = esTreeNodeToTSNodeMap.get(node);
|
|
4032
4060
|
const annotation = tsNode.type;
|
|
@@ -4047,7 +4075,7 @@ var throwErrorRule = ruleCreator({
|
|
|
4047
4075
|
node: reportNode
|
|
4048
4076
|
});
|
|
4049
4077
|
}
|
|
4050
|
-
function
|
|
4078
|
+
function checkThrowError(node) {
|
|
4051
4079
|
if (couldBeObservable(node)) {
|
|
4052
4080
|
const [arg] = node.arguments;
|
|
4053
4081
|
if (arg) {
|
|
@@ -4055,13 +4083,18 @@ var throwErrorRule = ruleCreator({
|
|
|
4055
4083
|
}
|
|
4056
4084
|
}
|
|
4057
4085
|
}
|
|
4058
|
-
|
|
4059
|
-
|
|
4060
|
-
|
|
4061
|
-
|
|
4062
|
-
|
|
4063
|
-
|
|
4086
|
+
function checkSubjectError(node) {
|
|
4087
|
+
if (isMemberExpression(node.callee) && couldBeSubject(node.callee.object)) {
|
|
4088
|
+
const [arg] = node.arguments;
|
|
4089
|
+
if (arg) {
|
|
4090
|
+
checkThrowArgument(arg, true);
|
|
4091
|
+
}
|
|
4064
4092
|
}
|
|
4093
|
+
}
|
|
4094
|
+
return {
|
|
4095
|
+
"CallExpression[callee.name='throwError']": checkThrowError,
|
|
4096
|
+
"CallExpression[callee.property.name='throwError']": checkThrowError,
|
|
4097
|
+
"CallExpression[callee.property.name='error']": checkSubjectError
|
|
4065
4098
|
};
|
|
4066
4099
|
}
|
|
4067
4100
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// package.json
|
|
2
2
|
var name = "eslint-plugin-rxjs-x";
|
|
3
|
-
var version = "0.7.
|
|
3
|
+
var version = "0.7.5";
|
|
4
4
|
|
|
5
5
|
// src/configs/recommended.ts
|
|
6
6
|
var createRecommendedConfig = (plugin2) => ({
|
|
@@ -398,6 +398,9 @@ var SOURCES_OBJECT_ACCEPTING_STATIC_OBSERVABLE_CREATORS = [
|
|
|
398
398
|
"combineLatest",
|
|
399
399
|
"forkJoin"
|
|
400
400
|
];
|
|
401
|
+
var DEFAULT_UNBOUND_ALLOWED_TYPES = [
|
|
402
|
+
"Signal"
|
|
403
|
+
];
|
|
401
404
|
var DEFAULT_VALID_POST_COMPLETION_OPERATORS = [
|
|
402
405
|
"count",
|
|
403
406
|
"defaultIfEmpty",
|
|
@@ -932,7 +935,7 @@ var noAsyncSubscribeRule = ruleCreator({
|
|
|
932
935
|
requiresTypeChecking: true
|
|
933
936
|
},
|
|
934
937
|
messages: {
|
|
935
|
-
forbidden: "Passing async functions to subscribe is forbidden."
|
|
938
|
+
forbidden: "Passing async functions to subscribe is forbidden. Use operators like `concatMap` or `switchMap` to avoid race conditions."
|
|
936
939
|
},
|
|
937
940
|
schema: [],
|
|
938
941
|
type: "problem"
|
|
@@ -940,27 +943,39 @@ var noAsyncSubscribeRule = ruleCreator({
|
|
|
940
943
|
name: "no-async-subscribe",
|
|
941
944
|
create: (context) => {
|
|
942
945
|
const { couldBeObservable } = getTypeServices(context);
|
|
943
|
-
function
|
|
944
|
-
const
|
|
946
|
+
function report(node) {
|
|
947
|
+
const { loc } = node;
|
|
948
|
+
const asyncLoc = {
|
|
949
|
+
...loc,
|
|
950
|
+
end: {
|
|
951
|
+
...loc.start,
|
|
952
|
+
column: loc.start.column + 5
|
|
953
|
+
}
|
|
954
|
+
};
|
|
955
|
+
context.report({
|
|
956
|
+
messageId: "forbidden",
|
|
957
|
+
loc: asyncLoc
|
|
958
|
+
});
|
|
959
|
+
}
|
|
960
|
+
function checkSingleNext(funcNode) {
|
|
961
|
+
const parentNode = funcNode.parent;
|
|
945
962
|
const callee = parentNode.callee;
|
|
946
963
|
if (couldBeObservable(callee.object)) {
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
context.report({
|
|
956
|
-
messageId: "forbidden",
|
|
957
|
-
loc: asyncLoc
|
|
958
|
-
});
|
|
964
|
+
report(funcNode);
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
function checkObserverObjectProp(propNode) {
|
|
968
|
+
const parentNode = propNode.parent.parent;
|
|
969
|
+
const callee = parentNode.callee;
|
|
970
|
+
if (couldBeObservable(callee.object) && (isArrowFunctionExpression(propNode.value) || isFunctionExpression(propNode.value))) {
|
|
971
|
+
report(propNode.value);
|
|
959
972
|
}
|
|
960
973
|
}
|
|
961
974
|
return {
|
|
962
|
-
"CallExpression[callee.property.name='subscribe'] > FunctionExpression[async=true]":
|
|
963
|
-
"CallExpression[callee.property.name='subscribe'] > ArrowFunctionExpression[async=true]":
|
|
975
|
+
"CallExpression[callee.property.name='subscribe'] > FunctionExpression[async=true]": checkSingleNext,
|
|
976
|
+
"CallExpression[callee.property.name='subscribe'] > ArrowFunctionExpression[async=true]": checkSingleNext,
|
|
977
|
+
"CallExpression[callee.property.name='subscribe'] > ObjectExpression > Property[key.name='next'][value.type=\"ArrowFunctionExpression\"][value.async=true]": checkObserverObjectProp,
|
|
978
|
+
"CallExpression[callee.property.name='subscribe'] > ObjectExpression > Property[key.name='next'][value.type=\"FunctionExpression\"][value.async=true]": checkObserverObjectProp
|
|
964
979
|
};
|
|
965
980
|
}
|
|
966
981
|
});
|
|
@@ -3116,8 +3131,9 @@ import { ${functionName} } from ${quote}rxjs${quote};`
|
|
|
3116
3131
|
|
|
3117
3132
|
// src/rules/no-unbound-methods.ts
|
|
3118
3133
|
import { ESLintUtils as ESLintUtils9 } from "@typescript-eslint/utils";
|
|
3134
|
+
var defaultOptions11 = [];
|
|
3119
3135
|
var noUnboundMethodsRule = ruleCreator({
|
|
3120
|
-
defaultOptions:
|
|
3136
|
+
defaultOptions: defaultOptions11,
|
|
3121
3137
|
meta: {
|
|
3122
3138
|
docs: {
|
|
3123
3139
|
description: "Disallow passing unbound methods.",
|
|
@@ -3127,7 +3143,14 @@ var noUnboundMethodsRule = ruleCreator({
|
|
|
3127
3143
|
messages: {
|
|
3128
3144
|
forbidden: "Unbound methods are forbidden."
|
|
3129
3145
|
},
|
|
3130
|
-
schema: [
|
|
3146
|
+
schema: [
|
|
3147
|
+
{
|
|
3148
|
+
properties: {
|
|
3149
|
+
allowTypes: { type: "array", items: { type: "string" }, description: "An array of function types that are allowed to be passed unbound.", default: DEFAULT_UNBOUND_ALLOWED_TYPES }
|
|
3150
|
+
},
|
|
3151
|
+
type: "object"
|
|
3152
|
+
}
|
|
3153
|
+
],
|
|
3131
3154
|
type: "problem"
|
|
3132
3155
|
},
|
|
3133
3156
|
name: "no-unbound-methods",
|
|
@@ -3135,9 +3158,14 @@ var noUnboundMethodsRule = ruleCreator({
|
|
|
3135
3158
|
const { getTypeAtLocation } = ESLintUtils9.getParserServices(context);
|
|
3136
3159
|
const { couldBeObservable, couldBeSubscription } = getTypeServices(context);
|
|
3137
3160
|
const nodeMap = /* @__PURE__ */ new WeakMap();
|
|
3161
|
+
const [config = {}] = context.options;
|
|
3162
|
+
const { allowTypes = [] } = config;
|
|
3138
3163
|
function mapArguments(node) {
|
|
3139
3164
|
node.arguments.filter(isMemberExpression).forEach((arg) => {
|
|
3140
3165
|
const argType = getTypeAtLocation(arg);
|
|
3166
|
+
if (allowTypes.some((t) => couldBeType(argType, t))) {
|
|
3167
|
+
return;
|
|
3168
|
+
}
|
|
3141
3169
|
if (argType.getCallSignatures().length > 0) {
|
|
3142
3170
|
nodeMap.set(arg);
|
|
3143
3171
|
}
|
|
@@ -3180,9 +3208,9 @@ var noUnboundMethodsRule = ruleCreator({
|
|
|
3180
3208
|
|
|
3181
3209
|
// src/rules/no-unsafe-catch.ts
|
|
3182
3210
|
import { stripIndent as stripIndent5 } from "common-tags";
|
|
3183
|
-
var
|
|
3211
|
+
var defaultOptions12 = [];
|
|
3184
3212
|
var noUnsafeCatchRule = ruleCreator({
|
|
3185
|
-
defaultOptions:
|
|
3213
|
+
defaultOptions: defaultOptions12,
|
|
3186
3214
|
meta: {
|
|
3187
3215
|
docs: {
|
|
3188
3216
|
description: "Disallow unsafe `catchError` usage in effects and epics.",
|
|
@@ -3241,9 +3269,9 @@ var noUnsafeCatchRule = ruleCreator({
|
|
|
3241
3269
|
|
|
3242
3270
|
// src/rules/no-unsafe-first.ts
|
|
3243
3271
|
import { stripIndent as stripIndent6 } from "common-tags";
|
|
3244
|
-
var
|
|
3272
|
+
var defaultOptions13 = [];
|
|
3245
3273
|
var noUnsafeFirstRule = ruleCreator({
|
|
3246
|
-
defaultOptions:
|
|
3274
|
+
defaultOptions: defaultOptions13,
|
|
3247
3275
|
meta: {
|
|
3248
3276
|
docs: {
|
|
3249
3277
|
description: "Disallow unsafe `first`/`take` usage in effects and epics.",
|
|
@@ -3365,9 +3393,9 @@ var noUnsafeSubjectNext = ruleCreator({
|
|
|
3365
3393
|
// src/rules/no-unsafe-switchmap.ts
|
|
3366
3394
|
import { stripIndent as stripIndent7 } from "common-tags";
|
|
3367
3395
|
import decamelize from "decamelize";
|
|
3368
|
-
var
|
|
3396
|
+
var defaultOptions14 = [];
|
|
3369
3397
|
var noUnsafeSwitchmapRule = ruleCreator({
|
|
3370
|
-
defaultOptions:
|
|
3398
|
+
defaultOptions: defaultOptions14,
|
|
3371
3399
|
meta: {
|
|
3372
3400
|
docs: {
|
|
3373
3401
|
description: "Disallow unsafe `switchMap` usage in effects and epics.",
|
|
@@ -3490,9 +3518,9 @@ var noUnsafeSwitchmapRule = ruleCreator({
|
|
|
3490
3518
|
|
|
3491
3519
|
// src/rules/no-unsafe-takeuntil.ts
|
|
3492
3520
|
import { stripIndent as stripIndent8 } from "common-tags";
|
|
3493
|
-
var
|
|
3521
|
+
var defaultOptions15 = [];
|
|
3494
3522
|
var noUnsafeTakeuntilRule = ruleCreator({
|
|
3495
|
-
defaultOptions:
|
|
3523
|
+
defaultOptions: defaultOptions15,
|
|
3496
3524
|
meta: {
|
|
3497
3525
|
docs: {
|
|
3498
3526
|
description: "Disallow applying operators after `takeUntil`.",
|
|
@@ -3553,9 +3581,9 @@ var noUnsafeTakeuntilRule = ruleCreator({
|
|
|
3553
3581
|
});
|
|
3554
3582
|
|
|
3555
3583
|
// src/rules/prefer-observer.ts
|
|
3556
|
-
var
|
|
3584
|
+
var defaultOptions16 = [];
|
|
3557
3585
|
var preferObserverRule = ruleCreator({
|
|
3558
|
-
defaultOptions:
|
|
3586
|
+
defaultOptions: defaultOptions16,
|
|
3559
3587
|
meta: {
|
|
3560
3588
|
docs: {
|
|
3561
3589
|
description: "Disallow passing separate handlers to `subscribe` and `tap`.",
|
|
@@ -3791,9 +3819,9 @@ var preferRootOperatorsRule = ruleCreator({
|
|
|
3791
3819
|
|
|
3792
3820
|
// src/rules/suffix-subjects.ts
|
|
3793
3821
|
import { AST_NODE_TYPES as AST_NODE_TYPES9, ESLintUtils as ESLintUtils11 } from "@typescript-eslint/utils";
|
|
3794
|
-
var
|
|
3822
|
+
var defaultOptions17 = [];
|
|
3795
3823
|
var suffixSubjectsRule = ruleCreator({
|
|
3796
|
-
defaultOptions:
|
|
3824
|
+
defaultOptions: defaultOptions17,
|
|
3797
3825
|
meta: {
|
|
3798
3826
|
docs: {
|
|
3799
3827
|
description: "Enforce the use of a suffix in subject identifiers.",
|
|
@@ -3990,12 +4018,12 @@ var suffixSubjectsRule = ruleCreator({
|
|
|
3990
4018
|
// src/rules/throw-error.ts
|
|
3991
4019
|
import { ESLintUtils as ESLintUtils12 } from "@typescript-eslint/utils";
|
|
3992
4020
|
import * as tsutils4 from "ts-api-utils";
|
|
3993
|
-
var
|
|
4021
|
+
var defaultOptions18 = [];
|
|
3994
4022
|
var throwErrorRule = ruleCreator({
|
|
3995
|
-
defaultOptions:
|
|
4023
|
+
defaultOptions: defaultOptions18,
|
|
3996
4024
|
meta: {
|
|
3997
4025
|
docs: {
|
|
3998
|
-
description: "Enforce passing only `Error` values to `throwError`.",
|
|
4026
|
+
description: "Enforce passing only `Error` values to `throwError` or `Subject.error`.",
|
|
3999
4027
|
recommended: {
|
|
4000
4028
|
recommended: true,
|
|
4001
4029
|
strict: [{ allowThrowingAny: false, allowThrowingUnknown: false }]
|
|
@@ -4019,14 +4047,14 @@ var throwErrorRule = ruleCreator({
|
|
|
4019
4047
|
name: "throw-error",
|
|
4020
4048
|
create: (context) => {
|
|
4021
4049
|
const { esTreeNodeToTSNodeMap, program, getTypeAtLocation } = ESLintUtils12.getParserServices(context);
|
|
4022
|
-
const { couldBeObservable } = getTypeServices(context);
|
|
4050
|
+
const { couldBeObservable, couldBeSubject } = getTypeServices(context);
|
|
4023
4051
|
const [config = {}] = context.options;
|
|
4024
4052
|
const { allowThrowingAny = true, allowThrowingUnknown = true } = config;
|
|
4025
|
-
function checkThrowArgument(node) {
|
|
4053
|
+
function checkThrowArgument(node, noFunction = false) {
|
|
4026
4054
|
var _a;
|
|
4027
4055
|
let type = getTypeAtLocation(node);
|
|
4028
4056
|
let reportNode = node;
|
|
4029
|
-
if (couldBeFunction(type)) {
|
|
4057
|
+
if (!noFunction && couldBeFunction(type)) {
|
|
4030
4058
|
reportNode = (_a = node.body) != null ? _a : node;
|
|
4031
4059
|
const tsNode = esTreeNodeToTSNodeMap.get(node);
|
|
4032
4060
|
const annotation = tsNode.type;
|
|
@@ -4047,7 +4075,7 @@ var throwErrorRule = ruleCreator({
|
|
|
4047
4075
|
node: reportNode
|
|
4048
4076
|
});
|
|
4049
4077
|
}
|
|
4050
|
-
function
|
|
4078
|
+
function checkThrowError(node) {
|
|
4051
4079
|
if (couldBeObservable(node)) {
|
|
4052
4080
|
const [arg] = node.arguments;
|
|
4053
4081
|
if (arg) {
|
|
@@ -4055,13 +4083,18 @@ var throwErrorRule = ruleCreator({
|
|
|
4055
4083
|
}
|
|
4056
4084
|
}
|
|
4057
4085
|
}
|
|
4058
|
-
|
|
4059
|
-
|
|
4060
|
-
|
|
4061
|
-
|
|
4062
|
-
|
|
4063
|
-
|
|
4086
|
+
function checkSubjectError(node) {
|
|
4087
|
+
if (isMemberExpression(node.callee) && couldBeSubject(node.callee.object)) {
|
|
4088
|
+
const [arg] = node.arguments;
|
|
4089
|
+
if (arg) {
|
|
4090
|
+
checkThrowArgument(arg, true);
|
|
4091
|
+
}
|
|
4064
4092
|
}
|
|
4093
|
+
}
|
|
4094
|
+
return {
|
|
4095
|
+
"CallExpression[callee.name='throwError']": checkThrowError,
|
|
4096
|
+
"CallExpression[callee.property.name='throwError']": checkThrowError,
|
|
4097
|
+
"CallExpression[callee.property.name='error']": checkSubjectError
|
|
4065
4098
|
};
|
|
4066
4099
|
}
|
|
4067
4100
|
});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-rxjs-x",
|
|
3
3
|
"type": "commonjs",
|
|
4
|
-
"version": "0.7.
|
|
4
|
+
"version": "0.7.5",
|
|
5
5
|
"packageManager": "yarn@4.9.1+sha512.f95ce356460e05be48d66401c1ae64ef84d163dd689964962c6888a9810865e39097a5e9de748876c2e0bf89b232d583c33982773e9903ae7a76257270986538",
|
|
6
6
|
"description": "ESLint v9+ plugin for RxJS",
|
|
7
7
|
"author": "Jason Weinzierl <weinzierljason@gmail.com>",
|
|
@@ -72,28 +72,29 @@
|
|
|
72
72
|
}
|
|
73
73
|
},
|
|
74
74
|
"devDependencies": {
|
|
75
|
-
"@eslint/js": "^9.
|
|
75
|
+
"@eslint/js": "^9.28.0",
|
|
76
76
|
"@stylistic/eslint-plugin": "^4.4.0",
|
|
77
77
|
"@types/common-tags": "^1.8.4",
|
|
78
78
|
"@types/node": "~18.18.0",
|
|
79
|
-
"@typescript-eslint/rule-tester": "^8.
|
|
79
|
+
"@typescript-eslint/rule-tester": "^8.33.1",
|
|
80
80
|
"@typescript/vfs": "^1.6.1",
|
|
81
|
-
"@vitest/coverage-v8": "^3.
|
|
81
|
+
"@vitest/coverage-v8": "^3.2.0",
|
|
82
82
|
"@vitest/eslint-plugin": "^1.2.1",
|
|
83
83
|
"bumpp": "^10.1.1",
|
|
84
|
-
"eslint": "^9.
|
|
84
|
+
"eslint": "^9.28.0",
|
|
85
85
|
"eslint-config-flat-gitignore": "^2.1.0",
|
|
86
86
|
"eslint-doc-generator": "^2.1.2",
|
|
87
|
-
"eslint-import-resolver-typescript": "^4.4.
|
|
87
|
+
"eslint-import-resolver-typescript": "^4.4.2",
|
|
88
88
|
"eslint-plugin-eslint-plugin": "^6.4.0",
|
|
89
|
-
"eslint-plugin-import-x": "^4.
|
|
90
|
-
"eslint-plugin-n": "^17.
|
|
89
|
+
"eslint-plugin-import-x": "^4.15.0",
|
|
90
|
+
"eslint-plugin-n": "^17.19.0",
|
|
91
91
|
"markdownlint-cli2": "^0.18.1",
|
|
92
92
|
"rxjs": "^7.8.2",
|
|
93
93
|
"tsup": "^8.5.0",
|
|
94
94
|
"typescript": "~5.8.3",
|
|
95
|
-
"typescript-eslint": "^8.
|
|
96
|
-
"
|
|
95
|
+
"typescript-eslint": "^8.33.1",
|
|
96
|
+
"vite": "^6.3.5",
|
|
97
|
+
"vitest": "^3.2.0"
|
|
97
98
|
},
|
|
98
99
|
"engines": {
|
|
99
100
|
"node": "^18.18.0 || ^20.9.0 || >= 21.1.0"
|