miniread 1.72.0 → 1.74.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/dist/transforms/_generated/manifest.js +13 -2
- package/dist/transforms/_generated/registry.js +4 -0
- package/dist/transforms/preset-stats.json +2 -2
- package/dist/transforms/recommended-transform-order.d.ts +1 -1
- package/dist/transforms/recommended-transform-order.js +2 -1
- package/dist/transforms/rename-default-options-parameters/manifest.json +3 -1
- package/dist/transforms/rename-default-options-parameters-v2/collect-default-options-parameter-names.d.ts +3 -0
- package/dist/transforms/rename-default-options-parameters-v2/collect-default-options-parameter-names.js +64 -0
- package/dist/transforms/rename-default-options-parameters-v2/get-defaulted-parameter-name.d.ts +4 -0
- package/dist/transforms/rename-default-options-parameters-v2/get-defaulted-parameter-name.js +117 -0
- package/dist/transforms/rename-default-options-parameters-v2/manifest.json +12 -0
- package/dist/transforms/rename-default-options-parameters-v2/rename-default-options-parameters-v2-transform.d.ts +2 -0
- package/dist/transforms/rename-default-options-parameters-v2/rename-default-options-parameters-v2-transform.js +43 -0
- package/dist/transforms/rename-file-reader-variables/manifest.json +12 -0
- package/dist/transforms/rename-file-reader-variables/rename-file-reader-variables-transform.d.ts +2 -0
- package/dist/transforms/rename-file-reader-variables/rename-file-reader-variables-transform.js +111 -0
- package/package.json +1 -1
|
@@ -99,9 +99,15 @@ const manifestData = {
|
|
|
99
99
|
evaluations: { "claude-code-2.1.10:claude-code-2.1.11": { "diffSizePercent": 99.99622028196697, "evaluatedAt": "2026-01-25T23:12:36.102Z", "changedLines": 354, "durationSeconds": 62.624233667, "stableNames": 1362 } },
|
|
100
100
|
},
|
|
101
101
|
"rename-default-options-parameters": {
|
|
102
|
-
recommended:
|
|
102
|
+
recommended: false,
|
|
103
|
+
notes: "Superseded by rename-default-options-parameters-v2.",
|
|
104
|
+
supersededBy: "rename-default-options-parameters-v2",
|
|
103
105
|
evaluations: { "legacy:evaluation": { "evaluatedAt": "2026-01-25T19:51:46.527Z", "changedLines": 0, "durationSeconds": 0, "stableNames": 0, "diffSizePercent": 100 }, "claude-code-2.1.10:claude-code-2.1.11": { "diffSizePercent": 100, "evaluatedAt": "2026-01-25T23:13:21.099Z", "changedLines": 0, "durationSeconds": 41.827803458, "stableNames": 1357 } },
|
|
104
106
|
},
|
|
107
|
+
"rename-default-options-parameters-v2": {
|
|
108
|
+
recommended: true,
|
|
109
|
+
evaluations: { "claude-code-2.1.10:claude-code-2.1.11": { "diffSizePercent": 100, "evaluatedAt": "2026-02-06T12:59:48.597Z", "changedLines": 774, "durationSeconds": 235.023578515, "stableNames": 1358 } },
|
|
110
|
+
},
|
|
105
111
|
"rename-deferred-resolve-parameters": {
|
|
106
112
|
recommended: true,
|
|
107
113
|
notes: "Measured with baseline none: 0.00%. Renames single-parameter promise executors to $resolve when usage only stores or calls the resolver.",
|
|
@@ -140,6 +146,10 @@ const manifestData = {
|
|
|
140
146
|
notes: "Measured with baseline none: 100.00%. Added to recommended for readability.",
|
|
141
147
|
evaluations: { "claude-code-2.1.10:claude-code-2.1.11": { "diffSizePercent": 100, "evaluatedAt": "2026-02-05T18:46:50.023Z", "changedLines": 4, "durationSeconds": 165.60063108, "stableNames": 1358 } },
|
|
142
148
|
},
|
|
149
|
+
"rename-file-reader-variables": {
|
|
150
|
+
recommended: true,
|
|
151
|
+
evaluations: { "claude-code-2.1.10:claude-code-2.1.11": { "diffSizePercent": 100, "evaluatedAt": "2026-02-05T18:45:30.224Z", "changedLines": 56, "durationSeconds": 179.39064335899997, "stableNames": 1358 } },
|
|
152
|
+
},
|
|
143
153
|
"rename-fs-sync-variables": {
|
|
144
154
|
recommended: true,
|
|
145
155
|
notes: "Auto-added by evaluation script. Note: rename transforms can slightly increase diff size in isolation (longer identifiers), but the goal here is stability/readability and improved alignment when composed with other transforms in the recommended preset. Safety: skips files with obvious dynamic name-lookup patterns (e.g. free `eval` / `Function` / `with`) since string-based lookups are not rewritten by renames.",
|
|
@@ -422,11 +432,12 @@ export const recommendedTransformIds = [
|
|
|
422
432
|
"rename-client-aliases",
|
|
423
433
|
"rename-comparison-flags",
|
|
424
434
|
"rename-date-now-start-times",
|
|
425
|
-
"rename-default-options-parameters",
|
|
435
|
+
"rename-default-options-parameters-v2",
|
|
426
436
|
"rename-deferred-resolve-parameters",
|
|
427
437
|
"rename-destructured-aliases",
|
|
428
438
|
"rename-rest-parameters",
|
|
429
439
|
"rename-execfile-arguments",
|
|
440
|
+
"rename-file-reader-variables",
|
|
430
441
|
"rename-error-first-callback-parameters",
|
|
431
442
|
"rename-error-variables",
|
|
432
443
|
"rename-event-parameters",
|
|
@@ -20,6 +20,7 @@ import { renameClientAliasesTransform } from "../rename-client-aliases/rename-cl
|
|
|
20
20
|
import { renameComparisonFlagsTransform } from "../rename-comparison-flags/rename-comparison-flags-transform.js";
|
|
21
21
|
import { renameDateNowStartTimesTransform } from "../rename-date-now-start-times/rename-date-now-start-times-transform.js";
|
|
22
22
|
import { renameDefaultOptionsParametersTransform } from "../rename-default-options-parameters/rename-default-options-parameters-transform.js";
|
|
23
|
+
import { renameDefaultOptionsParametersV2Transform } from "../rename-default-options-parameters-v2/rename-default-options-parameters-v2-transform.js";
|
|
23
24
|
import { renameDeferredResolveParametersTransform } from "../rename-deferred-resolve-parameters/rename-deferred-resolve-parameters-transform.js";
|
|
24
25
|
import { renameDestructuredAliasesTransform } from "../rename-destructured-aliases/rename-destructured-aliases-transform.js";
|
|
25
26
|
import { renameDocumentFragmentVariablesTransform } from "../rename-document-fragment-variables/rename-document-fragment-variables-transform.js";
|
|
@@ -28,6 +29,7 @@ import { renameErrorVariablesTransform } from "../rename-error-variables/rename-
|
|
|
28
29
|
import { renameEventParametersTransform } from "../rename-event-parameters/rename-event-parameters-transform.js";
|
|
29
30
|
import { renameExecfileArgumentsTransform } from "../rename-execfile-arguments/rename-execfile-arguments-transform.js";
|
|
30
31
|
import { renameFileExtensionVariablesTransform } from "../rename-file-extension-variables/rename-file-extension-variables-transform.js";
|
|
32
|
+
import { renameFileReaderVariablesTransform } from "../rename-file-reader-variables/rename-file-reader-variables-transform.js";
|
|
31
33
|
import { renameFsSyncVariablesTransform } from "../rename-fs-sync-variables/rename-fs-sync-variables-transform.js";
|
|
32
34
|
import { renameHttpMethodParametersTransform } from "../rename-http-method-parameters/rename-http-method-parameters-transform.js";
|
|
33
35
|
import { renameHttpServerParametersTransform } from "../rename-http-server-parameters/rename-http-server-parameters-transform.js";
|
|
@@ -99,6 +101,7 @@ export const transformRegistry = {
|
|
|
99
101
|
[renameComparisonFlagsTransform.id]: renameComparisonFlagsTransform,
|
|
100
102
|
[renameDateNowStartTimesTransform.id]: renameDateNowStartTimesTransform,
|
|
101
103
|
[renameDefaultOptionsParametersTransform.id]: renameDefaultOptionsParametersTransform,
|
|
104
|
+
[renameDefaultOptionsParametersV2Transform.id]: renameDefaultOptionsParametersV2Transform,
|
|
102
105
|
[renameDeferredResolveParametersTransform.id]: renameDeferredResolveParametersTransform,
|
|
103
106
|
[renameDestructuredAliasesTransform.id]: renameDestructuredAliasesTransform,
|
|
104
107
|
[renameDocumentFragmentVariablesTransform.id]: renameDocumentFragmentVariablesTransform,
|
|
@@ -107,6 +110,7 @@ export const transformRegistry = {
|
|
|
107
110
|
[renameEventParametersTransform.id]: renameEventParametersTransform,
|
|
108
111
|
[renameExecfileArgumentsTransform.id]: renameExecfileArgumentsTransform,
|
|
109
112
|
[renameFileExtensionVariablesTransform.id]: renameFileExtensionVariablesTransform,
|
|
113
|
+
[renameFileReaderVariablesTransform.id]: renameFileReaderVariablesTransform,
|
|
110
114
|
[renameFsSyncVariablesTransform.id]: renameFsSyncVariablesTransform,
|
|
111
115
|
[renameHttpMethodParametersTransform.id]: renameHttpMethodParametersTransform,
|
|
112
116
|
[renameHttpServerParametersTransform.id]: renameHttpServerParametersTransform,
|
|
@@ -4,4 +4,4 @@
|
|
|
4
4
|
* This lets us tune transform interactions intentionally instead of relying on
|
|
5
5
|
* alphabetical ID sorting.
|
|
6
6
|
*/
|
|
7
|
-
export declare const recommendedTransformOrder: readonly ["stabilize-top-level-bindings", "stabilize-nested-bindings", "stabilize-deferred-top-level-bindings", "stabilize-deferred-stable-rhs", "expand-boolean-literals", "expand-sequence-expressions-v5", "expand-special-number-literals", "expand-typeof-undefined-comparisons", "expand-undefined-literals", "remove-redundant-else", "rename-arguments-length-flags", "rename-asap-wrappers", "rename-awaiter-parameters", "rename-awaiter-helper-functions", "rename-buffer-variables", "rename-to-buffer-results", "rename-catch-parameters", "rename-promise-catch-parameters", "rename-char-code-at", "rename-charcode-variables-v2", "rename-client-aliases", "rename-comparison-flags", "rename-date-now-start-times", "rename-default-options-parameters", "rename-deferred-resolve-parameters", "rename-destructured-aliases", "rename-rest-parameters", "rename-execfile-arguments", "rename-error-first-callback-parameters", "rename-error-variables", "rename-event-parameters", "rename-http-server-parameters", "rename-fs-sync-variables", "rename-http-method-parameters", "rename-interval-ids", "rename-loop-index-variables-v3", "rename-loop-length-variables", "rename-document-fragment-variables", "rename-object-keys-variables", "rename-object-keys-iterator-variables", "rename-parameters-to-match-properties-v2", "rename-promise-executor-parameters-v2", "rename-range-parameters", "rename-read-file-lines", "rename-regex-builders", "rename-regex-source-parameters", "rename-search-parameters-variables", "rename-file-extension-variables", "rename-string-split-variables", "rename-this-aliases", "rename-timeout-ids", "rename-typeof-variables", "rename-typescript-helper-aliases", "rename-uint8array-concat-variables", "rename-url-parameters", "rename-url-variables", "rename-use-reference-guards-v2", "rename-use-reference-sets", "rename-worker-handles", "rename-zod-check-parameters", "simplify-boolean-negations", "simplify-string-trim", "split-variable-declarations", "use-optional-chaining", "use-object-property-shorthand", "use-object-shorthand", "replace-dynamic-require-eval"];
|
|
7
|
+
export declare const recommendedTransformOrder: readonly ["stabilize-top-level-bindings", "stabilize-nested-bindings", "stabilize-deferred-top-level-bindings", "stabilize-deferred-stable-rhs", "expand-boolean-literals", "expand-sequence-expressions-v5", "expand-special-number-literals", "expand-typeof-undefined-comparisons", "expand-undefined-literals", "remove-redundant-else", "rename-arguments-length-flags", "rename-asap-wrappers", "rename-awaiter-parameters", "rename-awaiter-helper-functions", "rename-buffer-variables", "rename-to-buffer-results", "rename-catch-parameters", "rename-promise-catch-parameters", "rename-char-code-at", "rename-charcode-variables-v2", "rename-client-aliases", "rename-comparison-flags", "rename-date-now-start-times", "rename-default-options-parameters-v2", "rename-deferred-resolve-parameters", "rename-destructured-aliases", "rename-rest-parameters", "rename-execfile-arguments", "rename-file-reader-variables", "rename-error-first-callback-parameters", "rename-error-variables", "rename-event-parameters", "rename-http-server-parameters", "rename-fs-sync-variables", "rename-http-method-parameters", "rename-interval-ids", "rename-loop-index-variables-v3", "rename-loop-length-variables", "rename-document-fragment-variables", "rename-object-keys-variables", "rename-object-keys-iterator-variables", "rename-parameters-to-match-properties-v2", "rename-promise-executor-parameters-v2", "rename-range-parameters", "rename-read-file-lines", "rename-regex-builders", "rename-regex-source-parameters", "rename-search-parameters-variables", "rename-file-extension-variables", "rename-string-split-variables", "rename-this-aliases", "rename-timeout-ids", "rename-typeof-variables", "rename-typescript-helper-aliases", "rename-uint8array-concat-variables", "rename-url-parameters", "rename-url-variables", "rename-use-reference-guards-v2", "rename-use-reference-sets", "rename-worker-handles", "rename-zod-check-parameters", "simplify-boolean-negations", "simplify-string-trim", "split-variable-declarations", "use-optional-chaining", "use-object-property-shorthand", "use-object-shorthand", "replace-dynamic-require-eval"];
|
|
@@ -37,11 +37,12 @@ export const recommendedTransformOrder = [
|
|
|
37
37
|
"rename-client-aliases",
|
|
38
38
|
"rename-comparison-flags",
|
|
39
39
|
"rename-date-now-start-times",
|
|
40
|
-
"rename-default-options-parameters",
|
|
40
|
+
"rename-default-options-parameters-v2",
|
|
41
41
|
"rename-deferred-resolve-parameters",
|
|
42
42
|
"rename-destructured-aliases",
|
|
43
43
|
"rename-rest-parameters",
|
|
44
44
|
"rename-execfile-arguments",
|
|
45
|
+
"rename-file-reader-variables",
|
|
45
46
|
"rename-error-first-callback-parameters",
|
|
46
47
|
"rename-error-variables",
|
|
47
48
|
"rename-event-parameters",
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import * as t from "@babel/types";
|
|
2
|
+
import { getDefaultedParameterName } from "./get-defaulted-parameter-name.js";
|
|
3
|
+
const getDefaultOptionsParameterNamesFromChain = (statement, parameterNames, allowUndefinedCheck) => {
|
|
4
|
+
let matchedParameterName;
|
|
5
|
+
let current = statement;
|
|
6
|
+
while (current) {
|
|
7
|
+
const parameterName = getDefaultedParameterName(current, parameterNames, {
|
|
8
|
+
allowUndefinedCheck,
|
|
9
|
+
});
|
|
10
|
+
if (!parameterName)
|
|
11
|
+
return undefined;
|
|
12
|
+
if (!matchedParameterName) {
|
|
13
|
+
matchedParameterName = parameterName;
|
|
14
|
+
}
|
|
15
|
+
else if (matchedParameterName !== parameterName) {
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
if (!current.alternate) {
|
|
19
|
+
current = undefined;
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
if (!t.isIfStatement(current.alternate))
|
|
23
|
+
return undefined;
|
|
24
|
+
current = current.alternate;
|
|
25
|
+
}
|
|
26
|
+
return matchedParameterName;
|
|
27
|
+
};
|
|
28
|
+
export const collectDefaultOptionsParameterNames = (path) => {
|
|
29
|
+
const allowUndefinedCheck = !path.scope.hasBinding("undefined", true);
|
|
30
|
+
const body = path.node.body;
|
|
31
|
+
if (!t.isBlockStatement(body))
|
|
32
|
+
return [];
|
|
33
|
+
const parameterNames = new Set();
|
|
34
|
+
for (const parameter of path.node.params) {
|
|
35
|
+
if (!t.isIdentifier(parameter))
|
|
36
|
+
continue;
|
|
37
|
+
parameterNames.add(parameter.name);
|
|
38
|
+
}
|
|
39
|
+
let sawIfStatement = false;
|
|
40
|
+
let matchedParameterName;
|
|
41
|
+
for (const statement of body.body) {
|
|
42
|
+
if (t.isExpressionStatement(statement) &&
|
|
43
|
+
t.isStringLiteral(statement.expression)) {
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
if (!t.isIfStatement(statement))
|
|
47
|
+
break;
|
|
48
|
+
const chainMatch = getDefaultOptionsParameterNamesFromChain(statement, parameterNames, allowUndefinedCheck);
|
|
49
|
+
if (!chainMatch)
|
|
50
|
+
break;
|
|
51
|
+
sawIfStatement = true;
|
|
52
|
+
if (!matchedParameterName) {
|
|
53
|
+
matchedParameterName = chainMatch;
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
if (matchedParameterName !== chainMatch)
|
|
57
|
+
return [];
|
|
58
|
+
}
|
|
59
|
+
if (!sawIfStatement)
|
|
60
|
+
return [];
|
|
61
|
+
if (!matchedParameterName)
|
|
62
|
+
return [];
|
|
63
|
+
return [matchedParameterName];
|
|
64
|
+
};
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import * as t from "@babel/types";
|
|
2
|
+
const isEmptyObjectAssignment = (expression, parameterName) => {
|
|
3
|
+
if (!t.isAssignmentExpression(expression, { operator: "=" }))
|
|
4
|
+
return false;
|
|
5
|
+
if (!t.isIdentifier(expression.left, { name: parameterName }))
|
|
6
|
+
return false;
|
|
7
|
+
if (!t.isObjectExpression(expression.right))
|
|
8
|
+
return false;
|
|
9
|
+
return expression.right.properties.length === 0;
|
|
10
|
+
};
|
|
11
|
+
const hasEmptyObjectAssignment = (statement, parameterName) => {
|
|
12
|
+
if (t.isReturnStatement(statement) || t.isThrowStatement(statement)) {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
if (t.isExpressionStatement(statement)) {
|
|
16
|
+
return isEmptyObjectAssignment(statement.expression, parameterName);
|
|
17
|
+
}
|
|
18
|
+
if (t.isBlockStatement(statement)) {
|
|
19
|
+
for (const child of statement.body) {
|
|
20
|
+
if (t.isReturnStatement(child) || t.isThrowStatement(child))
|
|
21
|
+
return false;
|
|
22
|
+
if (!t.isExpressionStatement(child))
|
|
23
|
+
continue;
|
|
24
|
+
if (isEmptyObjectAssignment(child.expression, parameterName))
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return false;
|
|
29
|
+
};
|
|
30
|
+
const getUndefinedCheckedParameterName = (test) => {
|
|
31
|
+
if (!t.isBinaryExpression(test, { operator: "===" }))
|
|
32
|
+
return undefined;
|
|
33
|
+
const { left, right } = test;
|
|
34
|
+
if (t.isIdentifier(left) && t.isIdentifier(right, { name: "undefined" })) {
|
|
35
|
+
return left.name;
|
|
36
|
+
}
|
|
37
|
+
if (t.isIdentifier(left, { name: "undefined" }) && t.isIdentifier(right)) {
|
|
38
|
+
return right.name;
|
|
39
|
+
}
|
|
40
|
+
return undefined;
|
|
41
|
+
};
|
|
42
|
+
const getFalsyCheckedParameterName = (test) => {
|
|
43
|
+
if (!t.isUnaryExpression(test, { operator: "!" }))
|
|
44
|
+
return undefined;
|
|
45
|
+
if (!t.isIdentifier(test.argument))
|
|
46
|
+
return undefined;
|
|
47
|
+
return test.argument.name;
|
|
48
|
+
};
|
|
49
|
+
const getTypeofFunctionCheckedParameterName = (test) => {
|
|
50
|
+
if (!t.isBinaryExpression(test))
|
|
51
|
+
return undefined;
|
|
52
|
+
if (test.operator !== "===" && test.operator !== "==")
|
|
53
|
+
return undefined;
|
|
54
|
+
const leftTypeofTarget = t.isUnaryExpression(test.left, {
|
|
55
|
+
operator: "typeof",
|
|
56
|
+
})
|
|
57
|
+
? test.left.argument
|
|
58
|
+
: undefined;
|
|
59
|
+
const rightTypeofTarget = t.isUnaryExpression(test.right, {
|
|
60
|
+
operator: "typeof",
|
|
61
|
+
})
|
|
62
|
+
? test.right.argument
|
|
63
|
+
: undefined;
|
|
64
|
+
const leftFunctionLiteral = t.isStringLiteral(test.left, {
|
|
65
|
+
value: "function",
|
|
66
|
+
})
|
|
67
|
+
? test.left
|
|
68
|
+
: undefined;
|
|
69
|
+
const rightFunctionLiteral = t.isStringLiteral(test.right, {
|
|
70
|
+
value: "function",
|
|
71
|
+
})
|
|
72
|
+
? test.right
|
|
73
|
+
: undefined;
|
|
74
|
+
if (leftFunctionLiteral &&
|
|
75
|
+
rightTypeofTarget &&
|
|
76
|
+
t.isIdentifier(rightTypeofTarget)) {
|
|
77
|
+
return rightTypeofTarget.name;
|
|
78
|
+
}
|
|
79
|
+
if (rightFunctionLiteral &&
|
|
80
|
+
leftTypeofTarget &&
|
|
81
|
+
t.isIdentifier(leftTypeofTarget)) {
|
|
82
|
+
return leftTypeofTarget.name;
|
|
83
|
+
}
|
|
84
|
+
return undefined;
|
|
85
|
+
};
|
|
86
|
+
export const getDefaultedParameterName = (statement, parameterNames, options) => {
|
|
87
|
+
if (options.allowUndefinedCheck) {
|
|
88
|
+
const undefinedCheckedName = getUndefinedCheckedParameterName(statement.test);
|
|
89
|
+
if (undefinedCheckedName) {
|
|
90
|
+
if (!parameterNames.has(undefinedCheckedName))
|
|
91
|
+
return undefined;
|
|
92
|
+
if (!hasEmptyObjectAssignment(statement.consequent, undefinedCheckedName)) {
|
|
93
|
+
return undefined;
|
|
94
|
+
}
|
|
95
|
+
return undefinedCheckedName;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
const falsyCheckedName = getFalsyCheckedParameterName(statement.test);
|
|
99
|
+
if (falsyCheckedName) {
|
|
100
|
+
if (!parameterNames.has(falsyCheckedName))
|
|
101
|
+
return undefined;
|
|
102
|
+
if (!hasEmptyObjectAssignment(statement.consequent, falsyCheckedName)) {
|
|
103
|
+
return undefined;
|
|
104
|
+
}
|
|
105
|
+
return falsyCheckedName;
|
|
106
|
+
}
|
|
107
|
+
const typeofCheckedName = getTypeofFunctionCheckedParameterName(statement.test);
|
|
108
|
+
if (typeofCheckedName) {
|
|
109
|
+
if (!parameterNames.has(typeofCheckedName))
|
|
110
|
+
return undefined;
|
|
111
|
+
if (!hasEmptyObjectAssignment(statement.consequent, typeofCheckedName)) {
|
|
112
|
+
return undefined;
|
|
113
|
+
}
|
|
114
|
+
return typeofCheckedName;
|
|
115
|
+
}
|
|
116
|
+
return undefined;
|
|
117
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
import { isStableRenamed, RenameGroup } from "../../core/stable-naming.js";
|
|
3
|
+
import { getFilesToProcess, } from "../../core/types.js";
|
|
4
|
+
import { collectDefaultOptionsParameterNames } from "./collect-default-options-parameter-names.js";
|
|
5
|
+
const require = createRequire(import.meta.url);
|
|
6
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
7
|
+
const traverse = require("@babel/traverse").default;
|
|
8
|
+
const BASE_NAME = "options";
|
|
9
|
+
export const renameDefaultOptionsParametersV2Transform = {
|
|
10
|
+
id: "rename-default-options-parameters-v2",
|
|
11
|
+
description: "Renames defaulted options-like parameters into stable options names",
|
|
12
|
+
scope: "file",
|
|
13
|
+
parallelizable: true,
|
|
14
|
+
transform(context) {
|
|
15
|
+
let nodesVisited = 0;
|
|
16
|
+
let transformationsApplied = 0;
|
|
17
|
+
for (const fileInfo of getFilesToProcess(context)) {
|
|
18
|
+
const group = new RenameGroup();
|
|
19
|
+
traverse(fileInfo.ast, {
|
|
20
|
+
Function(path) {
|
|
21
|
+
nodesVisited++;
|
|
22
|
+
const parameterNames = collectDefaultOptionsParameterNames(path);
|
|
23
|
+
for (const parameterName of parameterNames) {
|
|
24
|
+
if (parameterName === BASE_NAME)
|
|
25
|
+
continue;
|
|
26
|
+
if (isStableRenamed(parameterName))
|
|
27
|
+
continue;
|
|
28
|
+
group.add({
|
|
29
|
+
scope: path.scope,
|
|
30
|
+
currentName: parameterName,
|
|
31
|
+
baseName: BASE_NAME,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
transformationsApplied += group.apply();
|
|
37
|
+
}
|
|
38
|
+
return Promise.resolve({
|
|
39
|
+
nodesVisited,
|
|
40
|
+
transformationsApplied,
|
|
41
|
+
});
|
|
42
|
+
},
|
|
43
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"recommended": true,
|
|
3
|
+
"evaluations": {
|
|
4
|
+
"claude-code-2.1.10:claude-code-2.1.11": {
|
|
5
|
+
"diffSizePercent": 100,
|
|
6
|
+
"evaluatedAt": "2026-02-05T18:45:30.224Z",
|
|
7
|
+
"changedLines": 56,
|
|
8
|
+
"durationSeconds": 179.39064335899997,
|
|
9
|
+
"stableNames": 1358
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
}
|
package/dist/transforms/rename-file-reader-variables/rename-file-reader-variables-transform.js
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
import { collectExportedNames } from "../../core/collect-exported-names.js";
|
|
3
|
+
import { RenameGroup, isStableRenamed } from "../../core/stable-naming.js";
|
|
4
|
+
import { getFilesToProcess, } from "../../core/types.js";
|
|
5
|
+
const require = createRequire(import.meta.url);
|
|
6
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
7
|
+
const traverse = require("@babel/traverse").default;
|
|
8
|
+
const isTypeOnlyImportSpecifier = (binding, node) => {
|
|
9
|
+
const declaration = binding.path.parent;
|
|
10
|
+
if (declaration.type !== "ImportDeclaration") {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
if (node.type === "ImportSpecifier" && node.importKind === "type") {
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
return declaration.importKind === "type";
|
|
17
|
+
};
|
|
18
|
+
const isTypeOnlyFileReaderBinding = (binding) => {
|
|
19
|
+
const node = binding.path.node;
|
|
20
|
+
const declaration = binding.path.parent;
|
|
21
|
+
if (node.type === "ImportSpecifier" ||
|
|
22
|
+
node.type === "ImportDefaultSpecifier") {
|
|
23
|
+
return isTypeOnlyImportSpecifier(binding, node);
|
|
24
|
+
}
|
|
25
|
+
if (declaration.type === "VariableDeclaration" && declaration.declare) {
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
if (node.type === "TSDeclareFunction" ||
|
|
29
|
+
(node.type === "ClassDeclaration" && node.declare === true) ||
|
|
30
|
+
(node.type === "FunctionDeclaration" && node.declare === true)) {
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
return (node.type === "TSTypeAliasDeclaration" ||
|
|
34
|
+
node.type === "TSInterfaceDeclaration");
|
|
35
|
+
};
|
|
36
|
+
const hasRuntimeFileReaderShadowing = (path) => {
|
|
37
|
+
const binding = path.scope.getBinding("FileReader");
|
|
38
|
+
// Ambient declarations like `declare class FileReader` typically do not
|
|
39
|
+
// produce bindings in Babel's TS scope model, so `binding` is often absent.
|
|
40
|
+
if (!binding) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
// Keep using getBinding so we can inspect and ignore type-only TS bindings.
|
|
44
|
+
if (isTypeOnlyFileReaderBinding(binding)) {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
return true;
|
|
48
|
+
};
|
|
49
|
+
const isFileReaderConstructor = (path) => {
|
|
50
|
+
const { callee } = path.node;
|
|
51
|
+
if (callee.type !== "Identifier")
|
|
52
|
+
return false;
|
|
53
|
+
if (callee.name !== "FileReader")
|
|
54
|
+
return false;
|
|
55
|
+
if (hasRuntimeFileReaderShadowing(path))
|
|
56
|
+
return false;
|
|
57
|
+
return true;
|
|
58
|
+
};
|
|
59
|
+
export const renameFileReaderVariablesTransform = {
|
|
60
|
+
id: "rename-file-reader-variables",
|
|
61
|
+
description: "Rename variables initialized with new FileReader() to stable fileReader-derived names",
|
|
62
|
+
scope: "file",
|
|
63
|
+
parallelizable: true,
|
|
64
|
+
transform(context) {
|
|
65
|
+
let nodesVisited = 0;
|
|
66
|
+
let transformationsApplied = 0;
|
|
67
|
+
for (const fileInfo of getFilesToProcess(context)) {
|
|
68
|
+
const renameGroup = new RenameGroup();
|
|
69
|
+
const exportedNames = collectExportedNames(fileInfo.ast.program);
|
|
70
|
+
traverse(fileInfo.ast, {
|
|
71
|
+
VariableDeclarator(path) {
|
|
72
|
+
nodesVisited++;
|
|
73
|
+
const { id } = path.node;
|
|
74
|
+
if (id.type !== "Identifier") {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
const initPath = path.get("init");
|
|
78
|
+
if (Array.isArray(initPath) || !initPath.isNewExpression()) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
if (!isFileReaderConstructor(initPath)) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
const currentName = id.name;
|
|
85
|
+
if (isStableRenamed(currentName)) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
// Preserve already-semantic names (e.g. myFileReader) to avoid needless churn.
|
|
89
|
+
if (currentName.toLowerCase().includes("filereader")) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const binding = path.scope.getBinding(currentName);
|
|
93
|
+
if (!binding?.constant) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
if (binding.scope.block.type === "Program" &&
|
|
97
|
+
exportedNames.has(currentName)) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
renameGroup.add({
|
|
101
|
+
scope: path.scope,
|
|
102
|
+
currentName,
|
|
103
|
+
baseName: "fileReader",
|
|
104
|
+
});
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
transformationsApplied += renameGroup.apply();
|
|
108
|
+
}
|
|
109
|
+
return Promise.resolve({ nodesVisited, transformationsApplied });
|
|
110
|
+
},
|
|
111
|
+
};
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "miniread",
|
|
3
3
|
"author": "Łukasz Jerciński",
|
|
4
4
|
"license": "MIT",
|
|
5
|
-
"version": "1.
|
|
5
|
+
"version": "1.74.0",
|
|
6
6
|
"description": "Transform minified JavaScript/TypeScript into a more readable form using deterministic AST-based transforms.",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|