eslint-rule-forge 0.5.1 → 0.6.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 +1 -0
- package/dist/imports.d.mts +24 -2
- package/dist/imports.d.mts.map +1 -1
- package/dist/imports.mjs +83 -25
- package/dist/imports.mjs.map +1 -1
- package/dist/rules/prefer-array-is-array.d.mts.map +1 -1
- package/dist/rules/prefer-array-is-array.mjs +56 -49
- package/dist/rules/prefer-array-is-array.mjs.map +1 -1
- package/dist/rules/prefer-is-non-null-object.d.mts.map +1 -1
- package/dist/rules/prefer-is-non-null-object.mjs +13 -8
- package/dist/rules/prefer-is-non-null-object.mjs.map +1 -1
- package/dist/rules/prefer-is-record-and-has-key.d.mts.map +1 -1
- package/dist/rules/prefer-is-record-and-has-key.mjs +14 -9
- package/dist/rules/prefer-is-record-and-has-key.mjs.map +1 -1
- package/dist/rules/prefer-safe-parse.d.mts.map +1 -1
- package/dist/rules/prefer-safe-parse.mjs +19 -10
- package/dist/rules/prefer-safe-parse.mjs.map +1 -1
- package/package.json +5 -5
- package/src/imports.mts +151 -54
- package/src/rules/prefer-array-is-array.mts +25 -18
- package/src/rules/prefer-is-non-null-object.mts +16 -9
- package/src/rules/prefer-is-record-and-has-key.mts +17 -12
- package/src/rules/prefer-safe-parse.mts +26 -21
|
@@ -5,8 +5,7 @@ import {
|
|
|
5
5
|
} from '@typescript-eslint/utils';
|
|
6
6
|
import type { ReadonlyRecord } from 'ts-type-forge';
|
|
7
7
|
import * as ts from 'typescript';
|
|
8
|
-
import {
|
|
9
|
-
import { bindValueImports } from '../imports.mjs';
|
|
8
|
+
import { bindValueImportsAt } from '../imports.mjs';
|
|
10
9
|
import { getArgumentText } from '../parentheses.mjs';
|
|
11
10
|
import {
|
|
12
11
|
isIdentifierNamed,
|
|
@@ -142,7 +141,7 @@ const createSafeParseRule = <MessageId extends string>(
|
|
|
142
141
|
schema: [],
|
|
143
142
|
messages: {
|
|
144
143
|
...messages,
|
|
145
|
-
replaceWithSafeParse: `Replace with \`
|
|
144
|
+
replaceWithSafeParse: `Replace with \`{{resultName}}.unwrapOkOr({{namespaceName}}.${method}({{argName}}), Number.NaN)\`.`,
|
|
146
145
|
},
|
|
147
146
|
defaultOptions: [],
|
|
148
147
|
},
|
|
@@ -185,30 +184,39 @@ const createSafeParseRule = <MessageId extends string>(
|
|
|
185
184
|
mut_reports.push({ node, argExpression: firstArg });
|
|
186
185
|
},
|
|
187
186
|
'Program:exit': () => {
|
|
188
|
-
|
|
187
|
+
if (mut_reports.length === 0) {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const bindingAt = bindValueImportsAt(
|
|
189
192
|
sourceCode,
|
|
190
193
|
moduleName,
|
|
191
194
|
requiredImports,
|
|
192
195
|
);
|
|
193
196
|
|
|
194
|
-
const localNameOf = (name: string): string | undefined =>
|
|
195
|
-
binding?.localNames[requiredImports.indexOf(name)];
|
|
196
|
-
|
|
197
|
-
const namespaceName = localNameOf(namespace);
|
|
198
|
-
|
|
199
|
-
const resultName = localNameOf('Result');
|
|
200
|
-
|
|
201
197
|
// A suggestion, never an autofix: the replacement parses some
|
|
202
198
|
// strings differently (`parseInt('1e3')` is 1, the rewrite 1000;
|
|
203
199
|
// `parseFloat('12px')` is 12, the rewrite NaN; `Number('')` is 0, the
|
|
204
200
|
// rewrite NaN), so applying it is a person's decision. Each one
|
|
205
201
|
// brings its names into scope itself, so that it is complete alone.
|
|
206
202
|
for (const { node, argExpression } of mut_reports) {
|
|
203
|
+
const binding = bindingAt(node);
|
|
204
|
+
|
|
205
|
+
const localNameOf = (name: string): string | undefined =>
|
|
206
|
+
binding?.localNames[requiredImports.indexOf(name)];
|
|
207
|
+
|
|
208
|
+
const namespaceName = localNameOf(namespace);
|
|
209
|
+
|
|
210
|
+
const resultName = localNameOf('Result');
|
|
211
|
+
|
|
207
212
|
const argText = getArgumentText(sourceCode, argExpression);
|
|
208
213
|
|
|
209
214
|
const data = {
|
|
210
215
|
original: sourceCode.getText(node),
|
|
211
216
|
argName: argText,
|
|
217
|
+
// The names the suggestion writes; with none, the exports' own.
|
|
218
|
+
namespaceName: namespaceName ?? namespace,
|
|
219
|
+
resultName: resultName ?? 'Result',
|
|
212
220
|
} as const;
|
|
213
221
|
|
|
214
222
|
context.report({
|
|
@@ -218,10 +226,7 @@ const createSafeParseRule = <MessageId extends string>(
|
|
|
218
226
|
suggest:
|
|
219
227
|
binding === undefined ||
|
|
220
228
|
namespaceName === undefined ||
|
|
221
|
-
resultName === undefined
|
|
222
|
-
[namespaceName, resultName].some((name) =>
|
|
223
|
-
hasForeignBinding(sourceCode, node, name, moduleName),
|
|
224
|
-
)
|
|
229
|
+
resultName === undefined
|
|
225
230
|
? []
|
|
226
231
|
: [
|
|
227
232
|
{
|
|
@@ -244,12 +249,12 @@ const createSafeParseRule = <MessageId extends string>(
|
|
|
244
249
|
} as const;
|
|
245
250
|
};
|
|
246
251
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
}: SafeParseRuleConfig): string =>
|
|
252
|
-
`Replace \`{{original}}\` with \`
|
|
252
|
+
/**
|
|
253
|
+
* The report's message. `{{namespaceName}}` and `{{resultName}}` are the names
|
|
254
|
+
* the suggestion writes.
|
|
255
|
+
*/
|
|
256
|
+
const messageText = ({ moduleName, method }: SafeParseRuleConfig): string =>
|
|
257
|
+
`Replace \`{{original}}\` with \`{{resultName}}.unwrapOkOr({{namespaceName}}.${method}({{argName}}), Number.NaN)\` from ${moduleName}. It parses some strings differently from the call it replaces, so check the input before applying it.` as const;
|
|
253
258
|
|
|
254
259
|
/** Whether `callee` is the global function `name`, as in `parseInt(...)`. */
|
|
255
260
|
const isGlobalCall = (callee: TSESTree.Expression, name: string): boolean =>
|