eslint-plugin-rxjs-x 0.9.1 → 0.9.2

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 CHANGED
@@ -128,7 +128,7 @@ The package includes the following rules.
128
128
  | [no-async-subscribe](docs/rules/no-async-subscribe.md) | Disallow passing `async` functions to `subscribe`. | ✅ 🔒 | | | 💭 | |
129
129
  | [no-compat](docs/rules/no-compat.md) | Disallow the `rxjs-compat` package. | | | | | ❌ |
130
130
  | [no-connectable](docs/rules/no-connectable.md) | Disallow operators that return connectable observables. | | | | 💭 | |
131
- | [no-create](docs/rules/no-create.md) | Disallow the static `Observable.create` function. | ✅ 🔒 | | | 💭 | |
131
+ | [no-create](docs/rules/no-create.md) | Disallow the static `Observable.create` and `Subject.create` functions. | ✅ 🔒 | | | 💭 | |
132
132
  | [no-cyclic-action](docs/rules/no-cyclic-action.md) | Disallow cyclic actions in effects and epics. | | | | 💭 | |
133
133
  | [no-explicit-generics](docs/rules/no-explicit-generics.md) | Disallow unnecessary explicit generic type arguments. | | | | 💭 | |
134
134
  | [no-exposed-subjects](docs/rules/no-exposed-subjects.md) | Disallow public and protected subjects. | 🔒 | | | 💭 | |
@@ -142,7 +142,7 @@ The package includes the following rules.
142
142
  | [no-ignored-subscribe](docs/rules/no-ignored-subscribe.md) | Disallow calling `subscribe` without specifying arguments. | | | | 💭 | |
143
143
  | [no-ignored-subscription](docs/rules/no-ignored-subscription.md) | Disallow ignoring the subscription returned by `subscribe`. | | | | 💭 | |
144
144
  | [no-ignored-takewhile-value](docs/rules/no-ignored-takewhile-value.md) | Disallow ignoring the value within `takeWhile`. | ✅ 🔒 | | | | |
145
- | [no-implicit-any-catch](docs/rules/no-implicit-any-catch.md) | Disallow implicit `any` error parameters in `catchError` operators. | ✅ 🔒 | 🔧 | 💡 | 💭 | |
145
+ | [no-implicit-any-catch](docs/rules/no-implicit-any-catch.md) | Disallow implicit `any` error parameters in `catchError`, `subscribe`, and `tap`. | ✅ 🔒 | 🔧 | 💡 | 💭 | |
146
146
  | [no-index](docs/rules/no-index.md) | Disallow importing index modules. | ✅ 🔒 | | | | |
147
147
  | [no-internal](docs/rules/no-internal.md) | Disallow importing internal modules. | ✅ 🔒 | 🔧 | 💡 | | |
148
148
  | [no-misused-observables](docs/rules/no-misused-observables.md) | Disallow Observables in places not designed to handle them. | 🔒 | | | 💭 | |
@@ -167,6 +167,6 @@ The package includes the following rules.
167
167
  | [prefer-observer](docs/rules/prefer-observer.md) | Disallow passing separate handlers to `subscribe` and `tap`. | ✅ 🔒 | 🔧 | 💡 | 💭 | |
168
168
  | [prefer-root-operators](docs/rules/prefer-root-operators.md) | Disallow importing operators from `rxjs/operators`. | ✅ 🔒 | 🔧 | 💡 | | |
169
169
  | [suffix-subjects](docs/rules/suffix-subjects.md) | Enforce the use of a suffix in subject identifiers. | | | | 💭 | |
170
- | [throw-error](docs/rules/throw-error.md) | Enforce passing only `Error` values to `throwError` or `Subject.error`. | ✅ 🔒 | | | 💭 | |
170
+ | [throw-error](docs/rules/throw-error.md) | Enforce passing only `Error` values to `throwError` or `Subject.error`. | ✅ 🔒 | | 💡 | 💭 | |
171
171
 
172
172
  <!-- end auto-generated rules list -->
package/dist/index.d.mts CHANGED
@@ -50,8 +50,8 @@ declare const allRules: {
50
50
  description: "Disallow operators that return connectable observables.";
51
51
  requiresTypeChecking: true;
52
52
  }, TSESLint.RuleListener>;
53
- 'no-create': TSESLint.RuleModule<"forbidden", [], {
54
- description: "Disallow the static `Observable.create` function.";
53
+ 'no-create': TSESLint.RuleModule<"forbidden" | "forbiddenSubject", [], {
54
+ description: "Disallow the static `Observable.create` and `Subject.create` functions.";
55
55
  recommended: "recommended";
56
56
  requiresTypeChecking: true;
57
57
  }, TSESLint.RuleListener>;
@@ -120,10 +120,11 @@ declare const allRules: {
120
120
  description: "Disallow ignoring the value within `takeWhile`.";
121
121
  recommended: "recommended";
122
122
  }, TSESLint.RuleListener>;
123
- 'no-implicit-any-catch': TSESLint.RuleModule<"explicitAny" | "implicitAny" | "narrowed" | "suggestExplicitUnknown" | "suggestExplicitAny", readonly {
123
+ 'no-implicit-any-catch': TSESLint.RuleModule<"explicitAny" | "implicitAny" | "narrowed" | "narrowedAllowError" | "suggestExplicitUnknown" | "suggestExplicitAny" | "suggestExplicitError", readonly {
124
124
  allowExplicitAny?: boolean;
125
+ allowExplicitError?: boolean;
125
126
  }[], {
126
- description: "Disallow implicit `any` error parameters in `catchError` operators.";
127
+ description: "Disallow implicit `any` error parameters in `catchError`, `subscribe`, and `tap`.";
127
128
  recommended: {
128
129
  recommended: true;
129
130
  strict: [{
@@ -267,7 +268,7 @@ declare const allRules: {
267
268
  description: "Enforce the use of a suffix in subject identifiers.";
268
269
  requiresTypeChecking: true;
269
270
  }, TSESLint.RuleListener>;
270
- 'throw-error': TSESLint.RuleModule<"forbidden", readonly {
271
+ 'throw-error': TSESLint.RuleModule<"forbidden" | "suggestErrorConstructor", readonly {
271
272
  allowThrowingAny?: boolean;
272
273
  allowThrowingUnknown?: boolean;
273
274
  }[], {
package/dist/index.d.ts CHANGED
@@ -50,8 +50,8 @@ declare const allRules: {
50
50
  description: "Disallow operators that return connectable observables.";
51
51
  requiresTypeChecking: true;
52
52
  }, TSESLint.RuleListener>;
53
- 'no-create': TSESLint.RuleModule<"forbidden", [], {
54
- description: "Disallow the static `Observable.create` function.";
53
+ 'no-create': TSESLint.RuleModule<"forbidden" | "forbiddenSubject", [], {
54
+ description: "Disallow the static `Observable.create` and `Subject.create` functions.";
55
55
  recommended: "recommended";
56
56
  requiresTypeChecking: true;
57
57
  }, TSESLint.RuleListener>;
@@ -120,10 +120,11 @@ declare const allRules: {
120
120
  description: "Disallow ignoring the value within `takeWhile`.";
121
121
  recommended: "recommended";
122
122
  }, TSESLint.RuleListener>;
123
- 'no-implicit-any-catch': TSESLint.RuleModule<"explicitAny" | "implicitAny" | "narrowed" | "suggestExplicitUnknown" | "suggestExplicitAny", readonly {
123
+ 'no-implicit-any-catch': TSESLint.RuleModule<"explicitAny" | "implicitAny" | "narrowed" | "narrowedAllowError" | "suggestExplicitUnknown" | "suggestExplicitAny" | "suggestExplicitError", readonly {
124
124
  allowExplicitAny?: boolean;
125
+ allowExplicitError?: boolean;
125
126
  }[], {
126
- description: "Disallow implicit `any` error parameters in `catchError` operators.";
127
+ description: "Disallow implicit `any` error parameters in `catchError`, `subscribe`, and `tap`.";
127
128
  recommended: {
128
129
  recommended: true;
129
130
  strict: [{
@@ -267,7 +268,7 @@ declare const allRules: {
267
268
  description: "Enforce the use of a suffix in subject identifiers.";
268
269
  requiresTypeChecking: true;
269
270
  }, TSESLint.RuleListener>;
270
- 'throw-error': TSESLint.RuleModule<"forbidden", readonly {
271
+ 'throw-error': TSESLint.RuleModule<"forbidden" | "suggestErrorConstructor", readonly {
271
272
  allowThrowingAny?: boolean;
272
273
  allowThrowingUnknown?: boolean;
273
274
  }[], {
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.9.1";
3
+ var version = "0.9.2";
4
4
 
5
5
  // src/configs/recommended.ts
6
6
  var createRecommendedConfig = (plugin2) => ({
@@ -274,6 +274,9 @@ function isJSXExpressionContainer(node) {
274
274
  function isLiteral(node) {
275
275
  return node.type === _utils.AST_NODE_TYPES.Literal;
276
276
  }
277
+ function isTemplateLiteral(node) {
278
+ return node.type === _utils.AST_NODE_TYPES.TemplateLiteral;
279
+ }
277
280
  function isMemberExpression(node) {
278
281
  return node.type === _utils.AST_NODE_TYPES.MemberExpression;
279
282
  }
@@ -1103,19 +1106,20 @@ var noCreateRule = ruleCreator({
1103
1106
  defaultOptions: [],
1104
1107
  meta: {
1105
1108
  docs: {
1106
- description: "Disallow the static `Observable.create` function.",
1109
+ description: "Disallow the static `Observable.create` and `Subject.create` functions.",
1107
1110
  recommended: "recommended",
1108
1111
  requiresTypeChecking: true
1109
1112
  },
1110
1113
  messages: {
1111
- forbidden: "Observable.create is forbidden; use new Observable."
1114
+ forbidden: "Observable.create is forbidden; use new Observable.",
1115
+ forbiddenSubject: "Subject.create is forbidden."
1112
1116
  },
1113
1117
  schema: [],
1114
1118
  type: "problem"
1115
1119
  },
1116
1120
  name: "no-create",
1117
1121
  create: (context) => {
1118
- const { couldBeObservable } = getTypeServices(context);
1122
+ const { couldBeObservable, couldBeType: couldBeType2 } = getTypeServices(context);
1119
1123
  return {
1120
1124
  "CallExpression > MemberExpression[object.name='Observable'] > Identifier[name='create']": (node) => {
1121
1125
  const memberExpression = node.parent;
@@ -1125,6 +1129,15 @@ var noCreateRule = ruleCreator({
1125
1129
  node
1126
1130
  });
1127
1131
  }
1132
+ },
1133
+ "CallExpression > MemberExpression[object.name=/^(Subject|BehaviorSubject|AsyncSubject|ReplaySubject)$/] > Identifier[name='create']": (node) => {
1134
+ const memberExpression = node.parent;
1135
+ if (couldBeType2(memberExpression.object, /^(Subject|BehaviorSubject|AsyncSubject|ReplaySubject)$/)) {
1136
+ context.report({
1137
+ messageId: "forbiddenSubject",
1138
+ node
1139
+ });
1140
+ }
1128
1141
  }
1129
1142
  };
1130
1143
  }
@@ -2090,7 +2103,7 @@ var noImplicitAnyCatchRule = ruleCreator({
2090
2103
  defaultOptions: defaultOptions8,
2091
2104
  meta: {
2092
2105
  docs: {
2093
- description: "Disallow implicit `any` error parameters in `catchError` operators.",
2106
+ description: "Disallow implicit `any` error parameters in `catchError`, `subscribe`, and `tap`.",
2094
2107
  recommended: {
2095
2108
  recommended: true,
2096
2109
  strict: [{
@@ -2105,8 +2118,10 @@ var noImplicitAnyCatchRule = ruleCreator({
2105
2118
  explicitAny: "Explicit `any` in error callback.",
2106
2119
  implicitAny: "Implicit `any` in error callback.",
2107
2120
  narrowed: "Error type must be `unknown` or `any`.",
2121
+ narrowedAllowError: "Error type must be `unknown`, `any`, or `Error`.",
2108
2122
  suggestExplicitUnknown: "Use `unknown` instead to explicitly and safely assert the type is correct.",
2109
- suggestExplicitAny: "Use `any` instead to explicitly opt out of type safety."
2123
+ suggestExplicitAny: "Use `any` instead to explicitly opt out of type safety.",
2124
+ suggestExplicitError: "Use `Error` instead."
2110
2125
  },
2111
2126
  schema: [
2112
2127
  {
@@ -2116,6 +2131,11 @@ var noImplicitAnyCatchRule = ruleCreator({
2116
2131
  type: "boolean",
2117
2132
  description: "Allow error variable to be explicitly typed as `any`.",
2118
2133
  default: true
2134
+ },
2135
+ allowExplicitError: {
2136
+ type: "boolean",
2137
+ description: "Allow narrowing error type to `Error`.",
2138
+ default: false
2119
2139
  }
2120
2140
  },
2121
2141
  type: "object"
@@ -2126,7 +2146,7 @@ var noImplicitAnyCatchRule = ruleCreator({
2126
2146
  name: "no-implicit-any-catch",
2127
2147
  create: (context) => {
2128
2148
  const [config = {}] = context.options;
2129
- const { allowExplicitAny = true } = config;
2149
+ const { allowExplicitAny = true, allowExplicitError = false } = config;
2130
2150
  const { couldBeObservable } = getTypeServices(context);
2131
2151
  const sourceCode = context.sourceCode;
2132
2152
  function createReplacerFix(typeAnnotation, replaceWith) {
@@ -2171,20 +2191,33 @@ var noImplicitAnyCatchRule = ruleCreator({
2171
2191
  ]
2172
2192
  });
2173
2193
  } else if (type !== _utils.AST_NODE_TYPES.TSUnknownKeyword) {
2174
- context.report({
2175
- messageId: "narrowed",
2176
- node: param,
2177
- suggest: [
2178
- {
2179
- messageId: "suggestExplicitUnknown",
2180
- fix: createReplacerFix(typeAnnotation, "unknown")
2181
- },
2182
- allowExplicitAny ? {
2183
- messageId: "suggestExplicitAny",
2184
- fix: createReplacerFix(typeAnnotation, "any")
2185
- } : null
2186
- ].filter((x) => !!x)
2187
- });
2194
+ let isAllowedError = false;
2195
+ if (allowExplicitError && type === _utils.AST_NODE_TYPES.TSTypeReference) {
2196
+ const typeRef = typeAnnotation.typeAnnotation;
2197
+ if (isIdentifier(typeRef.typeName)) {
2198
+ isAllowedError = typeRef.typeName.name === "Error";
2199
+ }
2200
+ }
2201
+ if (!isAllowedError) {
2202
+ context.report({
2203
+ messageId: allowExplicitError ? "narrowedAllowError" : "narrowed",
2204
+ node: param,
2205
+ suggest: [
2206
+ {
2207
+ messageId: "suggestExplicitUnknown",
2208
+ fix: createReplacerFix(typeAnnotation, "unknown")
2209
+ },
2210
+ allowExplicitAny ? {
2211
+ messageId: "suggestExplicitAny",
2212
+ fix: createReplacerFix(typeAnnotation, "any")
2213
+ } : null,
2214
+ allowExplicitError && !isAllowedError ? {
2215
+ messageId: "suggestExplicitError",
2216
+ fix: createReplacerFix(typeAnnotation, "Error")
2217
+ } : null
2218
+ ].filter((x) => !!x)
2219
+ });
2220
+ }
2188
2221
  }
2189
2222
  } else {
2190
2223
  const hasRestParams = restParams.length > 0;
@@ -4317,7 +4350,8 @@ var throwErrorRule = ruleCreator({
4317
4350
  requiresTypeChecking: true
4318
4351
  },
4319
4352
  messages: {
4320
- forbidden: "Passing non-Error values is forbidden."
4353
+ forbidden: "Passing non-Error values is forbidden.",
4354
+ suggestErrorConstructor: "Wrap string in Error constructor."
4321
4355
  },
4322
4356
  schema: [
4323
4357
  {
@@ -4328,7 +4362,8 @@ var throwErrorRule = ruleCreator({
4328
4362
  type: "object"
4329
4363
  }
4330
4364
  ],
4331
- type: "problem"
4365
+ type: "problem",
4366
+ hasSuggestions: true
4332
4367
  },
4333
4368
  name: "throw-error",
4334
4369
  create: (context) => {
@@ -4356,9 +4391,22 @@ var throwErrorRule = ruleCreator({
4356
4391
  if (couldBeType(type, /^Error$/)) {
4357
4392
  return;
4358
4393
  }
4394
+ const isString = isTemplateLiteral(reportNode) || isLiteral(reportNode) && typeof reportNode.value === "string";
4359
4395
  context.report({
4360
4396
  messageId: "forbidden",
4361
- node: reportNode
4397
+ node: reportNode,
4398
+ ...isString && {
4399
+ suggest: [
4400
+ {
4401
+ messageId: "suggestErrorConstructor",
4402
+ fix: (fixer) => {
4403
+ const sourceCode = context.sourceCode;
4404
+ const nodeText = sourceCode.getText(reportNode);
4405
+ return fixer.replaceText(reportNode, `new Error(${nodeText})`);
4406
+ }
4407
+ }
4408
+ ]
4409
+ }
4362
4410
  });
4363
4411
  }
4364
4412
  function checkThrowError(node) {
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.9.1";
3
+ var version = "0.9.2";
4
4
 
5
5
  // src/configs/recommended.ts
6
6
  var createRecommendedConfig = (plugin2) => ({
@@ -274,6 +274,9 @@ function isJSXExpressionContainer(node) {
274
274
  function isLiteral(node) {
275
275
  return node.type === AST_NODE_TYPES.Literal;
276
276
  }
277
+ function isTemplateLiteral(node) {
278
+ return node.type === AST_NODE_TYPES.TemplateLiteral;
279
+ }
277
280
  function isMemberExpression(node) {
278
281
  return node.type === AST_NODE_TYPES.MemberExpression;
279
282
  }
@@ -1103,19 +1106,20 @@ var noCreateRule = ruleCreator({
1103
1106
  defaultOptions: [],
1104
1107
  meta: {
1105
1108
  docs: {
1106
- description: "Disallow the static `Observable.create` function.",
1109
+ description: "Disallow the static `Observable.create` and `Subject.create` functions.",
1107
1110
  recommended: "recommended",
1108
1111
  requiresTypeChecking: true
1109
1112
  },
1110
1113
  messages: {
1111
- forbidden: "Observable.create is forbidden; use new Observable."
1114
+ forbidden: "Observable.create is forbidden; use new Observable.",
1115
+ forbiddenSubject: "Subject.create is forbidden."
1112
1116
  },
1113
1117
  schema: [],
1114
1118
  type: "problem"
1115
1119
  },
1116
1120
  name: "no-create",
1117
1121
  create: (context) => {
1118
- const { couldBeObservable } = getTypeServices(context);
1122
+ const { couldBeObservable, couldBeType: couldBeType2 } = getTypeServices(context);
1119
1123
  return {
1120
1124
  "CallExpression > MemberExpression[object.name='Observable'] > Identifier[name='create']": (node) => {
1121
1125
  const memberExpression = node.parent;
@@ -1125,6 +1129,15 @@ var noCreateRule = ruleCreator({
1125
1129
  node
1126
1130
  });
1127
1131
  }
1132
+ },
1133
+ "CallExpression > MemberExpression[object.name=/^(Subject|BehaviorSubject|AsyncSubject|ReplaySubject)$/] > Identifier[name='create']": (node) => {
1134
+ const memberExpression = node.parent;
1135
+ if (couldBeType2(memberExpression.object, /^(Subject|BehaviorSubject|AsyncSubject|ReplaySubject)$/)) {
1136
+ context.report({
1137
+ messageId: "forbiddenSubject",
1138
+ node
1139
+ });
1140
+ }
1128
1141
  }
1129
1142
  };
1130
1143
  }
@@ -2090,7 +2103,7 @@ var noImplicitAnyCatchRule = ruleCreator({
2090
2103
  defaultOptions: defaultOptions8,
2091
2104
  meta: {
2092
2105
  docs: {
2093
- description: "Disallow implicit `any` error parameters in `catchError` operators.",
2106
+ description: "Disallow implicit `any` error parameters in `catchError`, `subscribe`, and `tap`.",
2094
2107
  recommended: {
2095
2108
  recommended: true,
2096
2109
  strict: [{
@@ -2105,8 +2118,10 @@ var noImplicitAnyCatchRule = ruleCreator({
2105
2118
  explicitAny: "Explicit `any` in error callback.",
2106
2119
  implicitAny: "Implicit `any` in error callback.",
2107
2120
  narrowed: "Error type must be `unknown` or `any`.",
2121
+ narrowedAllowError: "Error type must be `unknown`, `any`, or `Error`.",
2108
2122
  suggestExplicitUnknown: "Use `unknown` instead to explicitly and safely assert the type is correct.",
2109
- suggestExplicitAny: "Use `any` instead to explicitly opt out of type safety."
2123
+ suggestExplicitAny: "Use `any` instead to explicitly opt out of type safety.",
2124
+ suggestExplicitError: "Use `Error` instead."
2110
2125
  },
2111
2126
  schema: [
2112
2127
  {
@@ -2116,6 +2131,11 @@ var noImplicitAnyCatchRule = ruleCreator({
2116
2131
  type: "boolean",
2117
2132
  description: "Allow error variable to be explicitly typed as `any`.",
2118
2133
  default: true
2134
+ },
2135
+ allowExplicitError: {
2136
+ type: "boolean",
2137
+ description: "Allow narrowing error type to `Error`.",
2138
+ default: false
2119
2139
  }
2120
2140
  },
2121
2141
  type: "object"
@@ -2126,7 +2146,7 @@ var noImplicitAnyCatchRule = ruleCreator({
2126
2146
  name: "no-implicit-any-catch",
2127
2147
  create: (context) => {
2128
2148
  const [config = {}] = context.options;
2129
- const { allowExplicitAny = true } = config;
2149
+ const { allowExplicitAny = true, allowExplicitError = false } = config;
2130
2150
  const { couldBeObservable } = getTypeServices(context);
2131
2151
  const sourceCode = context.sourceCode;
2132
2152
  function createReplacerFix(typeAnnotation, replaceWith) {
@@ -2171,20 +2191,33 @@ var noImplicitAnyCatchRule = ruleCreator({
2171
2191
  ]
2172
2192
  });
2173
2193
  } else if (type !== AST_NODE_TYPES4.TSUnknownKeyword) {
2174
- context.report({
2175
- messageId: "narrowed",
2176
- node: param,
2177
- suggest: [
2178
- {
2179
- messageId: "suggestExplicitUnknown",
2180
- fix: createReplacerFix(typeAnnotation, "unknown")
2181
- },
2182
- allowExplicitAny ? {
2183
- messageId: "suggestExplicitAny",
2184
- fix: createReplacerFix(typeAnnotation, "any")
2185
- } : null
2186
- ].filter((x) => !!x)
2187
- });
2194
+ let isAllowedError = false;
2195
+ if (allowExplicitError && type === AST_NODE_TYPES4.TSTypeReference) {
2196
+ const typeRef = typeAnnotation.typeAnnotation;
2197
+ if (isIdentifier(typeRef.typeName)) {
2198
+ isAllowedError = typeRef.typeName.name === "Error";
2199
+ }
2200
+ }
2201
+ if (!isAllowedError) {
2202
+ context.report({
2203
+ messageId: allowExplicitError ? "narrowedAllowError" : "narrowed",
2204
+ node: param,
2205
+ suggest: [
2206
+ {
2207
+ messageId: "suggestExplicitUnknown",
2208
+ fix: createReplacerFix(typeAnnotation, "unknown")
2209
+ },
2210
+ allowExplicitAny ? {
2211
+ messageId: "suggestExplicitAny",
2212
+ fix: createReplacerFix(typeAnnotation, "any")
2213
+ } : null,
2214
+ allowExplicitError && !isAllowedError ? {
2215
+ messageId: "suggestExplicitError",
2216
+ fix: createReplacerFix(typeAnnotation, "Error")
2217
+ } : null
2218
+ ].filter((x) => !!x)
2219
+ });
2220
+ }
2188
2221
  }
2189
2222
  } else {
2190
2223
  const hasRestParams = restParams.length > 0;
@@ -4317,7 +4350,8 @@ var throwErrorRule = ruleCreator({
4317
4350
  requiresTypeChecking: true
4318
4351
  },
4319
4352
  messages: {
4320
- forbidden: "Passing non-Error values is forbidden."
4353
+ forbidden: "Passing non-Error values is forbidden.",
4354
+ suggestErrorConstructor: "Wrap string in Error constructor."
4321
4355
  },
4322
4356
  schema: [
4323
4357
  {
@@ -4328,7 +4362,8 @@ var throwErrorRule = ruleCreator({
4328
4362
  type: "object"
4329
4363
  }
4330
4364
  ],
4331
- type: "problem"
4365
+ type: "problem",
4366
+ hasSuggestions: true
4332
4367
  },
4333
4368
  name: "throw-error",
4334
4369
  create: (context) => {
@@ -4356,9 +4391,22 @@ var throwErrorRule = ruleCreator({
4356
4391
  if (couldBeType(type, /^Error$/)) {
4357
4392
  return;
4358
4393
  }
4394
+ const isString = isTemplateLiteral(reportNode) || isLiteral(reportNode) && typeof reportNode.value === "string";
4359
4395
  context.report({
4360
4396
  messageId: "forbidden",
4361
- node: reportNode
4397
+ node: reportNode,
4398
+ ...isString && {
4399
+ suggest: [
4400
+ {
4401
+ messageId: "suggestErrorConstructor",
4402
+ fix: (fixer) => {
4403
+ const sourceCode = context.sourceCode;
4404
+ const nodeText = sourceCode.getText(reportNode);
4405
+ return fixer.replaceText(reportNode, `new Error(${nodeText})`);
4406
+ }
4407
+ }
4408
+ ]
4409
+ }
4362
4410
  });
4363
4411
  }
4364
4412
  function checkThrowError(node) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "eslint-plugin-rxjs-x",
3
3
  "type": "commonjs",
4
- "version": "0.9.1",
4
+ "version": "0.9.2",
5
5
  "packageManager": "yarn@4.12.0+sha512.f45ab632439a67f8bc759bf32ead036a1f413287b9042726b7cc4818b7b49e14e9423ba49b18f9e06ea4941c1ad062385b1d8760a8d5091a1a31e5f6219afca8",
6
6
  "description": "Modern ESLint plugin for RxJS",
7
7
  "author": "Jason Weinzierl <weinzierljason@gmail.com>",
@@ -84,7 +84,7 @@
84
84
  "@typescript/vfs": "^1.6.2",
85
85
  "@vitest/coverage-v8": "^3.2.4",
86
86
  "@vitest/eslint-plugin": "^1.4.0",
87
- "bumpp": "^10.4.0",
87
+ "bumpp": "^10.4.1",
88
88
  "eslint": "^9.39.2",
89
89
  "eslint-config-flat-gitignore": "^2.1.0",
90
90
  "eslint-doc-generator": "^2.4.0",