miniread 1.77.0 → 1.79.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/core/stable-naming.d.ts +6 -1
- package/dist/core/stable-naming.js +17 -0
- package/dist/transforms/_generated/manifest.js +11 -0
- package/dist/transforms/_generated/registry.js +4 -0
- package/dist/transforms/get-binding-stable-start.d.ts +2 -0
- package/dist/transforms/get-binding-stable-start.js +11 -0
- package/dist/transforms/recommended-transform-order.d.ts +1 -1
- package/dist/transforms/recommended-transform-order.js +2 -0
- package/dist/transforms/rename-fs-sync-variables/rename-fs-sync-variables-transform.js +1 -9
- package/dist/transforms/rename-indexeddb-request-variables/analyze-indexeddb-request-binding.d.ts +10 -0
- package/dist/transforms/rename-indexeddb-request-variables/analyze-indexeddb-request-binding.js +86 -0
- package/dist/transforms/rename-indexeddb-request-variables/manifest.json +12 -0
- package/dist/transforms/rename-indexeddb-request-variables/rename-indexeddb-request-variables-transform.d.ts +2 -0
- package/dist/transforms/rename-indexeddb-request-variables/rename-indexeddb-request-variables-transform.js +100 -0
- package/dist/transforms/rename-invalid-parameter-arguments/manifest.json +13 -0
- package/dist/transforms/rename-invalid-parameter-arguments/rename-invalid-parameter-arguments-transform.d.ts +2 -0
- package/dist/transforms/rename-invalid-parameter-arguments/rename-invalid-parameter-arguments-transform.js +142 -0
- package/package.json +1 -1
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* - Stable names (`$timeoutId`): Readable AND deterministic across versions
|
|
14
14
|
* - Readable names (`timeoutId`): Semantic but order-dependent
|
|
15
15
|
*/
|
|
16
|
-
import type { Scope } from "@babel/traverse";
|
|
16
|
+
import type { Binding, Scope } from "@babel/traverse";
|
|
17
17
|
/**
|
|
18
18
|
* Returns true if the name has been stable-renamed (starts with $).
|
|
19
19
|
* Transforms should skip variables with this prefix.
|
|
@@ -25,6 +25,11 @@ export declare const isStableRenamed: (name: string) => boolean;
|
|
|
25
25
|
* stabilized by one of the hash-based stabilization transforms.
|
|
26
26
|
*/
|
|
27
27
|
export declare const isHashBasedStableName: (name: string) => boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Returns true only when the exact stable name slot (`$${baseName}`) is
|
|
30
|
+
* available for this binding in the provided scope.
|
|
31
|
+
*/
|
|
32
|
+
export declare const canUseExactStableName: (scope: Scope, binding: Binding | undefined, currentName: string, baseName: string) => boolean;
|
|
28
33
|
/**
|
|
29
34
|
* Entry for a planned rename operation.
|
|
30
35
|
*/
|
|
@@ -29,6 +29,23 @@ export const isStableRenamed = (name) => {
|
|
|
29
29
|
* stabilized by one of the hash-based stabilization transforms.
|
|
30
30
|
*/
|
|
31
31
|
export const isHashBasedStableName = (name) => name.startsWith("$h_") || name.startsWith("$f_") || name.startsWith("$v_");
|
|
32
|
+
/**
|
|
33
|
+
* Returns true only when the exact stable name slot (`$${baseName}`) is
|
|
34
|
+
* available for this binding in the provided scope.
|
|
35
|
+
*/
|
|
36
|
+
export const canUseExactStableName = (scope, binding, currentName, baseName) => {
|
|
37
|
+
const candidateStable = makeStableName(baseName);
|
|
38
|
+
const programGlobals = getProgramValueGlobals(scope);
|
|
39
|
+
const stableTaken = candidateStable === currentName
|
|
40
|
+
? false
|
|
41
|
+
: scope.hasBinding(candidateStable) ||
|
|
42
|
+
programGlobals.has(candidateStable);
|
|
43
|
+
if (stableTaken)
|
|
44
|
+
return false;
|
|
45
|
+
if (binding && hasShadowingRisk(binding, scope, candidateStable))
|
|
46
|
+
return false;
|
|
47
|
+
return true;
|
|
48
|
+
};
|
|
32
49
|
/**
|
|
33
50
|
* Creates a stable name by adding the $ prefix.
|
|
34
51
|
* Internal helper - prefer using RenameGroup which handles stability logic automatically.
|
|
@@ -168,10 +168,19 @@ const manifestData = {
|
|
|
168
168
|
recommended: true,
|
|
169
169
|
evaluations: { "claude-code-2.1.10:claude-code-2.1.11": { "diffSizePercent": 100, "evaluatedAt": "2026-02-04T12:54:37.434Z", "changedLines": 14, "durationSeconds": 231.553556391, "stableNames": 1358 } },
|
|
170
170
|
},
|
|
171
|
+
"rename-indexeddb-request-variables": {
|
|
172
|
+
recommended: true,
|
|
173
|
+
evaluations: { "claude-code-2.1.10:claude-code-2.1.11": { "diffSizePercent": 100, "evaluatedAt": "2026-02-06T14:48:25.555Z", "changedLines": 30, "durationSeconds": 226.960178979, "stableNames": 1358 } },
|
|
174
|
+
},
|
|
171
175
|
"rename-interval-ids": {
|
|
172
176
|
recommended: true,
|
|
173
177
|
evaluations: { "claude-code-2.1.10:claude-code-2.1.11": { "diffSizePercent": 100, "evaluatedAt": "2026-02-01T09:30:55.276Z", "changedLines": 58, "durationSeconds": 201.398360841, "stableNames": 1358 } },
|
|
174
178
|
},
|
|
179
|
+
"rename-invalid-parameter-arguments": {
|
|
180
|
+
recommended: true,
|
|
181
|
+
notes: "Added to recommended for readability of invalidParameterError call sites.",
|
|
182
|
+
evaluations: { "claude-code-2.1.10:claude-code-2.1.11": { "diffSizePercent": 99.99811516350957, "evaluatedAt": "2026-02-06T12:52:02.935Z", "changedLines": 452, "durationSeconds": 211.048545671, "stableNames": 1381 } },
|
|
183
|
+
},
|
|
175
184
|
"rename-loop-index-variables": {
|
|
176
185
|
recommended: false,
|
|
177
186
|
notes: "Superseded by rename-loop-index-variables-v3.",
|
|
@@ -455,12 +464,14 @@ export const recommendedTransformIds = [
|
|
|
455
464
|
"rename-fs-sync-variables",
|
|
456
465
|
"rename-http-method-parameters",
|
|
457
466
|
"rename-interval-ids",
|
|
467
|
+
"rename-indexeddb-request-variables",
|
|
458
468
|
"rename-loop-index-variables-v3",
|
|
459
469
|
"rename-loop-length-variables",
|
|
460
470
|
"rename-document-fragment-variables",
|
|
461
471
|
"rename-object-keys-variables",
|
|
462
472
|
"rename-object-keys-iterator-variables",
|
|
463
473
|
"rename-parameters-to-match-properties-v2",
|
|
474
|
+
"rename-invalid-parameter-arguments",
|
|
464
475
|
"rename-promise-executor-parameters-v2",
|
|
465
476
|
"rename-range-parameters",
|
|
466
477
|
"rename-read-file-lines",
|
|
@@ -34,7 +34,9 @@ import { renameFileReaderVariablesTransform } from "../rename-file-reader-variab
|
|
|
34
34
|
import { renameFsSyncVariablesTransform } from "../rename-fs-sync-variables/rename-fs-sync-variables-transform.js";
|
|
35
35
|
import { renameHttpMethodParametersTransform } from "../rename-http-method-parameters/rename-http-method-parameters-transform.js";
|
|
36
36
|
import { renameHttpServerParametersTransform } from "../rename-http-server-parameters/rename-http-server-parameters-transform.js";
|
|
37
|
+
import { renameIndexeddbRequestVariablesTransform } from "../rename-indexeddb-request-variables/rename-indexeddb-request-variables-transform.js";
|
|
37
38
|
import { renameIntervalIdsTransform } from "../rename-interval-ids/rename-interval-ids-transform.js";
|
|
39
|
+
import { renameInvalidParameterArgumentsTransform } from "../rename-invalid-parameter-arguments/rename-invalid-parameter-arguments-transform.js";
|
|
38
40
|
import { renameLoopIndexVariablesTransform } from "../rename-loop-index-variables/rename-loop-index-variables-transform.js";
|
|
39
41
|
import { renameLoopIndexVariablesV2Transform } from "../rename-loop-index-variables-v2/rename-loop-index-variables-v2-transform.js";
|
|
40
42
|
import { renameLoopIndexVariablesV3Transform } from "../rename-loop-index-variables-v3/rename-loop-index-variables-v3-transform.js";
|
|
@@ -117,7 +119,9 @@ export const transformRegistry = {
|
|
|
117
119
|
[renameFsSyncVariablesTransform.id]: renameFsSyncVariablesTransform,
|
|
118
120
|
[renameHttpMethodParametersTransform.id]: renameHttpMethodParametersTransform,
|
|
119
121
|
[renameHttpServerParametersTransform.id]: renameHttpServerParametersTransform,
|
|
122
|
+
[renameIndexeddbRequestVariablesTransform.id]: renameIndexeddbRequestVariablesTransform,
|
|
120
123
|
[renameIntervalIdsTransform.id]: renameIntervalIdsTransform,
|
|
124
|
+
[renameInvalidParameterArgumentsTransform.id]: renameInvalidParameterArgumentsTransform,
|
|
121
125
|
[renameLoopIndexVariablesTransform.id]: renameLoopIndexVariablesTransform,
|
|
122
126
|
[renameLoopIndexVariablesV2Transform.id]: renameLoopIndexVariablesV2Transform,
|
|
123
127
|
[renameLoopIndexVariablesV3Transform.id]: renameLoopIndexVariablesV3Transform,
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const BINDING_INDEX_SCALE = 1_000_000;
|
|
2
|
+
export const getBindingStableStart = (binding) => {
|
|
3
|
+
const start = binding.identifier.start;
|
|
4
|
+
if (typeof start === "number")
|
|
5
|
+
return start;
|
|
6
|
+
const location = binding.identifier.loc;
|
|
7
|
+
if (location) {
|
|
8
|
+
return location.start.line * BINDING_INDEX_SCALE + location.start.column;
|
|
9
|
+
}
|
|
10
|
+
return Number.MAX_SAFE_INTEGER;
|
|
11
|
+
};
|
|
@@ -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-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-first-callback-parameters-v2", "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-promises", "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-first-callback-parameters-v2", "rename-error-variables", "rename-event-parameters", "rename-http-server-parameters", "rename-fs-sync-variables", "rename-http-method-parameters", "rename-interval-ids", "rename-indexeddb-request-variables", "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-invalid-parameter-arguments", "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-promises", "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"];
|
|
@@ -54,12 +54,14 @@ export const recommendedTransformOrder = [
|
|
|
54
54
|
"rename-fs-sync-variables",
|
|
55
55
|
"rename-http-method-parameters",
|
|
56
56
|
"rename-interval-ids",
|
|
57
|
+
"rename-indexeddb-request-variables",
|
|
57
58
|
"rename-loop-index-variables-v3",
|
|
58
59
|
"rename-loop-length-variables",
|
|
59
60
|
"rename-document-fragment-variables",
|
|
60
61
|
"rename-object-keys-variables",
|
|
61
62
|
"rename-object-keys-iterator-variables",
|
|
62
63
|
"rename-parameters-to-match-properties-v2",
|
|
64
|
+
"rename-invalid-parameter-arguments",
|
|
63
65
|
"rename-promise-executor-parameters-v2",
|
|
64
66
|
"rename-range-parameters",
|
|
65
67
|
"rename-read-file-lines",
|
|
@@ -2,6 +2,7 @@ import { createRequire } from "node:module";
|
|
|
2
2
|
import { collectExportedNames } from "../../core/collect-exported-names.js";
|
|
3
3
|
import { isStableRenamed, RenameGroup } from "../../core/stable-naming.js";
|
|
4
4
|
import { getFilesToProcess, } from "../../core/types.js";
|
|
5
|
+
import { getBindingStableStart } from "../get-binding-stable-start.js";
|
|
5
6
|
import { hasDynamicNameLookup } from "../has-dynamic-name-lookup.js";
|
|
6
7
|
import { isNodeFileSystemNamespaceBinding } from "../is-node-file-system-identifier.js";
|
|
7
8
|
const require = createRequire(import.meta.url);
|
|
@@ -56,15 +57,6 @@ const shouldRename = (identifier) => {
|
|
|
56
57
|
return false;
|
|
57
58
|
return true;
|
|
58
59
|
};
|
|
59
|
-
const getBindingStableStart = (binding) => {
|
|
60
|
-
const start = binding.identifier.start;
|
|
61
|
-
if (typeof start === "number")
|
|
62
|
-
return start;
|
|
63
|
-
const loc = binding.identifier.loc;
|
|
64
|
-
if (loc)
|
|
65
|
-
return loc.start.line * 1_000_000 + loc.start.column;
|
|
66
|
-
return Number.MAX_SAFE_INTEGER;
|
|
67
|
-
};
|
|
68
60
|
export const renameFsSyncVariablesTransform = {
|
|
69
61
|
id: "rename-fs-sync-variables",
|
|
70
62
|
description: "Renames Node fs bindings used with 2+ distinct fs.*Sync methods to stable fs-based names",
|
package/dist/transforms/rename-indexeddb-request-variables/analyze-indexeddb-request-binding.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Binding } from "@babel/traverse";
|
|
2
|
+
import type { CallExpression, OptionalCallExpression } from "@babel/types";
|
|
3
|
+
type RequestMethodName = "open" | "deleteDatabase";
|
|
4
|
+
type RequestUsage = {
|
|
5
|
+
properties: Set<string>;
|
|
6
|
+
};
|
|
7
|
+
export declare const getIndexedDatabaseRequestInitMethod: (init: CallExpression | OptionalCallExpression) => RequestMethodName | undefined;
|
|
8
|
+
export declare const getIndexedDBRequestUsage: (binding: Binding) => RequestUsage | undefined;
|
|
9
|
+
export declare const hasOpenRequestSpecificSignals: (properties: Set<string>) => boolean;
|
|
10
|
+
export {};
|
package/dist/transforms/rename-indexeddb-request-variables/analyze-indexeddb-request-binding.js
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
const REQUEST_MEMBER_PROPERTIES = new Set([
|
|
2
|
+
"onerror",
|
|
3
|
+
"onsuccess",
|
|
4
|
+
"onblocked",
|
|
5
|
+
"onupgradeneeded",
|
|
6
|
+
"result",
|
|
7
|
+
"error",
|
|
8
|
+
"transaction",
|
|
9
|
+
]);
|
|
10
|
+
const OPEN_ONLY_SPECIFIC_PROPERTIES = new Set([
|
|
11
|
+
"onblocked",
|
|
12
|
+
"onupgradeneeded",
|
|
13
|
+
"transaction",
|
|
14
|
+
]);
|
|
15
|
+
const REQUEST_EVENT_HANDLER_PROPERTIES = new Set([
|
|
16
|
+
"onsuccess",
|
|
17
|
+
"onerror",
|
|
18
|
+
"onblocked",
|
|
19
|
+
"onupgradeneeded",
|
|
20
|
+
]);
|
|
21
|
+
const REQUEST_VALUE_PROPERTIES = new Set(["result", "error"]);
|
|
22
|
+
const getMemberPropertyName = (member) => {
|
|
23
|
+
if (member.computed) {
|
|
24
|
+
if (member.property.type !== "StringLiteral")
|
|
25
|
+
return;
|
|
26
|
+
return member.property.value;
|
|
27
|
+
}
|
|
28
|
+
if (member.property.type !== "Identifier")
|
|
29
|
+
return;
|
|
30
|
+
return member.property.name;
|
|
31
|
+
};
|
|
32
|
+
export const getIndexedDatabaseRequestInitMethod = (init) => {
|
|
33
|
+
const callee = init.callee;
|
|
34
|
+
if (callee.type !== "MemberExpression" &&
|
|
35
|
+
callee.type !== "OptionalMemberExpression") {
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
const propertyName = getMemberPropertyName(callee);
|
|
39
|
+
if (!propertyName)
|
|
40
|
+
return undefined;
|
|
41
|
+
if (propertyName === "open")
|
|
42
|
+
return "open";
|
|
43
|
+
// `deleteDatabase` is distinctive enough that we intentionally avoid
|
|
44
|
+
// receiver-origin checks to preserve support for aliased IDB factories.
|
|
45
|
+
if (propertyName === "deleteDatabase")
|
|
46
|
+
return "deleteDatabase";
|
|
47
|
+
return undefined;
|
|
48
|
+
};
|
|
49
|
+
export const getIndexedDBRequestUsage = (binding) => {
|
|
50
|
+
const properties = new Set();
|
|
51
|
+
for (const referencePath of binding.referencePaths) {
|
|
52
|
+
// Be conservative: if any reference is not a direct request member access,
|
|
53
|
+
// skip renaming to avoid mislabeling generic `.open()` call results.
|
|
54
|
+
if (!referencePath.isIdentifier())
|
|
55
|
+
return;
|
|
56
|
+
const parentPath = referencePath.parentPath;
|
|
57
|
+
if (!parentPath.isMemberExpression() &&
|
|
58
|
+
!parentPath.isOptionalMemberExpression()) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const memberExpression = parentPath.node;
|
|
62
|
+
if (memberExpression.object !== referencePath.node)
|
|
63
|
+
return;
|
|
64
|
+
const propertyName = getMemberPropertyName(memberExpression);
|
|
65
|
+
if (!propertyName)
|
|
66
|
+
return;
|
|
67
|
+
if (!REQUEST_MEMBER_PROPERTIES.has(propertyName))
|
|
68
|
+
return;
|
|
69
|
+
properties.add(propertyName);
|
|
70
|
+
}
|
|
71
|
+
return { properties };
|
|
72
|
+
};
|
|
73
|
+
const hasAnyProperty = (properties, allowedProperties) => {
|
|
74
|
+
for (const property of properties) {
|
|
75
|
+
if (allowedProperties.has(property))
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
return false;
|
|
79
|
+
};
|
|
80
|
+
export const hasOpenRequestSpecificSignals = (properties) =>
|
|
81
|
+
// `open()` is generic across APIs, so we require either IndexedDB-specific
|
|
82
|
+
// signals (`onblocked`/`onupgradeneeded`/`transaction`) or the paired
|
|
83
|
+
// request pattern (event callback + `result`/`error`) used by IDB requests.
|
|
84
|
+
hasAnyProperty(properties, OPEN_ONLY_SPECIFIC_PROPERTIES) ||
|
|
85
|
+
(hasAnyProperty(properties, REQUEST_EVENT_HANDLER_PROPERTIES) &&
|
|
86
|
+
hasAnyProperty(properties, REQUEST_VALUE_PROPERTIES));
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
import { getIndexedDatabaseRequestInitMethod, getIndexedDBRequestUsage, hasOpenRequestSpecificSignals, } from "./analyze-indexeddb-request-binding.js";
|
|
3
|
+
import { collectExportedNames } from "../../core/collect-exported-names.js";
|
|
4
|
+
import { isStableRenamed, RenameGroup } from "../../core/stable-naming.js";
|
|
5
|
+
import { getFilesToProcess, } from "../../core/types.js";
|
|
6
|
+
import { getBindingStableStart } from "../get-binding-stable-start.js";
|
|
7
|
+
import { hasDynamicNameLookup } from "../has-dynamic-name-lookup.js";
|
|
8
|
+
const require = createRequire(import.meta.url);
|
|
9
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
10
|
+
const traverse = require("@babel/traverse").default;
|
|
11
|
+
const BASE_NAME = "dbRequest";
|
|
12
|
+
const getRequestMethod = (init) => {
|
|
13
|
+
if (init?.type !== "CallExpression" &&
|
|
14
|
+
init?.type !== "OptionalCallExpression") {
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
return getIndexedDatabaseRequestInitMethod(init);
|
|
18
|
+
};
|
|
19
|
+
export const renameIndexeddbRequestVariablesTransform = {
|
|
20
|
+
id: "rename-indexeddb-request-variables",
|
|
21
|
+
description: "Renames IndexedDB open/deleteDatabase request bindings to stable dbRequest names based on request event usage",
|
|
22
|
+
scope: "file",
|
|
23
|
+
parallelizable: true,
|
|
24
|
+
transform(context) {
|
|
25
|
+
let nodesVisited = 0;
|
|
26
|
+
let transformationsApplied = 0;
|
|
27
|
+
for (const fileInfo of getFilesToProcess(context)) {
|
|
28
|
+
if (hasDynamicNameLookup(fileInfo.ast))
|
|
29
|
+
continue;
|
|
30
|
+
const renameCandidatesByScope = new Map();
|
|
31
|
+
const isScript = fileInfo.ast.program.sourceType === "script";
|
|
32
|
+
const exportedNames = collectExportedNames(fileInfo.ast.program);
|
|
33
|
+
traverse(fileInfo.ast, {
|
|
34
|
+
VariableDeclarator(path) {
|
|
35
|
+
nodesVisited++;
|
|
36
|
+
const id = path.node.id;
|
|
37
|
+
if (id.type !== "Identifier")
|
|
38
|
+
return;
|
|
39
|
+
if (isStableRenamed(id.name))
|
|
40
|
+
return;
|
|
41
|
+
if (id.name.toLowerCase().includes("request"))
|
|
42
|
+
return;
|
|
43
|
+
const initMethod = getRequestMethod(path.node.init);
|
|
44
|
+
if (!initMethod)
|
|
45
|
+
return;
|
|
46
|
+
const binding = path.scope.getBinding(id.name);
|
|
47
|
+
if (!binding)
|
|
48
|
+
return;
|
|
49
|
+
if (!binding.constant)
|
|
50
|
+
return;
|
|
51
|
+
if (binding.referencePaths.length === 0)
|
|
52
|
+
return;
|
|
53
|
+
if (isScript && binding.scope.block.type === "Program")
|
|
54
|
+
return;
|
|
55
|
+
if (binding.scope.block.type === "Program" &&
|
|
56
|
+
exportedNames.has(id.name)) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const usage = getIndexedDBRequestUsage(binding);
|
|
60
|
+
if (!usage)
|
|
61
|
+
return;
|
|
62
|
+
if (usage.properties.size < 2)
|
|
63
|
+
return;
|
|
64
|
+
if (initMethod === "open" &&
|
|
65
|
+
!hasOpenRequestSpecificSignals(usage.properties)) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const existing = renameCandidatesByScope.get(binding.scope);
|
|
69
|
+
if (existing) {
|
|
70
|
+
existing.push(binding);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
renameCandidatesByScope.set(binding.scope, [binding]);
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
for (const [scope, bindings] of renameCandidatesByScope) {
|
|
78
|
+
bindings.sort((a, b) => {
|
|
79
|
+
const aStart = getBindingStableStart(a);
|
|
80
|
+
const bStart = getBindingStableStart(b);
|
|
81
|
+
if (aStart !== bStart)
|
|
82
|
+
return aStart - bStart;
|
|
83
|
+
return a.identifier.name.localeCompare(b.identifier.name);
|
|
84
|
+
});
|
|
85
|
+
for (const binding of bindings) {
|
|
86
|
+
// Apply per binding to force stable `$dbRequest` slots (`$dbRequest`,
|
|
87
|
+
// `$dbRequest2`, ...) even when multiple request bindings share scope.
|
|
88
|
+
const group = new RenameGroup();
|
|
89
|
+
group.add({
|
|
90
|
+
scope,
|
|
91
|
+
currentName: binding.identifier.name,
|
|
92
|
+
baseName: BASE_NAME,
|
|
93
|
+
});
|
|
94
|
+
transformationsApplied += group.apply();
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return Promise.resolve({ nodesVisited, transformationsApplied });
|
|
99
|
+
},
|
|
100
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"recommended": true,
|
|
3
|
+
"notes": "Added to recommended for readability of invalidParameterError call sites.",
|
|
4
|
+
"evaluations": {
|
|
5
|
+
"claude-code-2.1.10:claude-code-2.1.11": {
|
|
6
|
+
"diffSizePercent": 99.99811516350957,
|
|
7
|
+
"evaluatedAt": "2026-02-06T12:52:02.935Z",
|
|
8
|
+
"changedLines": 452,
|
|
9
|
+
"durationSeconds": 211.048545671,
|
|
10
|
+
"stableNames": 1381
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
import { isIdentifierName, isKeyword, isStrictBindReservedWord, } from "@babel/helper-validator-identifier";
|
|
3
|
+
import { RenameGroup, canUseExactStableName, 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 getValidBaseName = (value) => {
|
|
9
|
+
const trimmed = value.trim();
|
|
10
|
+
if (trimmed.length === 0)
|
|
11
|
+
return undefined;
|
|
12
|
+
const normalized = trimmed.replace(/^\$+/u, "");
|
|
13
|
+
if (normalized.length === 0)
|
|
14
|
+
return undefined;
|
|
15
|
+
if (!isIdentifierName(normalized))
|
|
16
|
+
return undefined;
|
|
17
|
+
if (normalized.startsWith("h_"))
|
|
18
|
+
return undefined;
|
|
19
|
+
if (normalized.startsWith("f_"))
|
|
20
|
+
return undefined;
|
|
21
|
+
if (normalized.startsWith("v_"))
|
|
22
|
+
return undefined;
|
|
23
|
+
// Keep module-mode strictness to avoid introducing bindings that become
|
|
24
|
+
// invalid when sourceType resolves to module in unambiguous parsing.
|
|
25
|
+
if (isKeyword(normalized) || isStrictBindReservedWord(normalized, true)) {
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
return normalized;
|
|
29
|
+
};
|
|
30
|
+
const isInvalidParameterErrorCallee = (callee) => {
|
|
31
|
+
if (callee.type === "Identifier") {
|
|
32
|
+
return callee.name === "invalidParameterError";
|
|
33
|
+
}
|
|
34
|
+
if (callee.type !== "MemberExpression")
|
|
35
|
+
return false;
|
|
36
|
+
if (callee.object.type !== "Identifier")
|
|
37
|
+
return false;
|
|
38
|
+
if (callee.object.name !== "errors")
|
|
39
|
+
return false;
|
|
40
|
+
if (callee.computed)
|
|
41
|
+
return false;
|
|
42
|
+
if (callee.property.type !== "Identifier")
|
|
43
|
+
return false;
|
|
44
|
+
return callee.property.name === "invalidParameterError";
|
|
45
|
+
};
|
|
46
|
+
const getInvalidParameterRename = (path) => {
|
|
47
|
+
if (!isInvalidParameterErrorCallee(path.node.callee))
|
|
48
|
+
return undefined;
|
|
49
|
+
if (path.node.arguments.length !== 3)
|
|
50
|
+
return undefined;
|
|
51
|
+
const [nameArgument, expectedTypeArgument, valueArgument] = path.node.arguments;
|
|
52
|
+
if (nameArgument?.type !== "StringLiteral")
|
|
53
|
+
return undefined;
|
|
54
|
+
// Keep this intentionally strict: we only rename for the canonical
|
|
55
|
+
// invalidParameterError("name", "expected", actual) signature.
|
|
56
|
+
if (expectedTypeArgument?.type !== "StringLiteral")
|
|
57
|
+
return undefined;
|
|
58
|
+
if (valueArgument?.type !== "Identifier")
|
|
59
|
+
return undefined;
|
|
60
|
+
const baseName = getValidBaseName(nameArgument.value);
|
|
61
|
+
if (!baseName)
|
|
62
|
+
return undefined;
|
|
63
|
+
const binding = path.scope.getBinding(valueArgument.name);
|
|
64
|
+
if (!binding)
|
|
65
|
+
return undefined;
|
|
66
|
+
if (binding.kind !== "param")
|
|
67
|
+
return undefined;
|
|
68
|
+
if (isStableRenamed(binding.identifier.name))
|
|
69
|
+
return undefined;
|
|
70
|
+
// Preserve already-semantic parameter names instead of forcing `$name`.
|
|
71
|
+
if (binding.identifier.name === baseName)
|
|
72
|
+
return undefined;
|
|
73
|
+
return {
|
|
74
|
+
baseName,
|
|
75
|
+
binding,
|
|
76
|
+
scope: binding.scope,
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
export const renameInvalidParameterArgumentsTransform = {
|
|
80
|
+
id: "rename-invalid-parameter-arguments",
|
|
81
|
+
description: 'Renames minified parameters passed to invalidParameterError("name", ...) to matching names, preferring stable $name when unambiguous and available.',
|
|
82
|
+
scope: "file",
|
|
83
|
+
parallelizable: true,
|
|
84
|
+
transform(context) {
|
|
85
|
+
let nodesVisited = 0;
|
|
86
|
+
let transformationsApplied = 0;
|
|
87
|
+
for (const fileInfo of getFilesToProcess(context)) {
|
|
88
|
+
const group = new RenameGroup();
|
|
89
|
+
const candidateByBinding = new Map();
|
|
90
|
+
const conflictedBindings = new Set();
|
|
91
|
+
traverse(fileInfo.ast, {
|
|
92
|
+
CallExpression(path) {
|
|
93
|
+
nodesVisited++;
|
|
94
|
+
const candidate = getInvalidParameterRename(path);
|
|
95
|
+
if (!candidate)
|
|
96
|
+
return;
|
|
97
|
+
if (conflictedBindings.has(candidate.binding))
|
|
98
|
+
return;
|
|
99
|
+
const existing = candidateByBinding.get(candidate.binding);
|
|
100
|
+
if (!existing) {
|
|
101
|
+
candidateByBinding.set(candidate.binding, candidate);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
if (existing.baseName === candidate.baseName)
|
|
105
|
+
return;
|
|
106
|
+
candidateByBinding.delete(candidate.binding);
|
|
107
|
+
conflictedBindings.add(candidate.binding);
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
const baseNameCountsByScope = new Map();
|
|
111
|
+
for (const candidate of candidateByBinding.values()) {
|
|
112
|
+
let countByBaseName = baseNameCountsByScope.get(candidate.scope);
|
|
113
|
+
if (!countByBaseName) {
|
|
114
|
+
countByBaseName = new Map();
|
|
115
|
+
baseNameCountsByScope.set(candidate.scope, countByBaseName);
|
|
116
|
+
}
|
|
117
|
+
countByBaseName.set(candidate.baseName, (countByBaseName.get(candidate.baseName) ?? 0) + 1);
|
|
118
|
+
}
|
|
119
|
+
for (const candidate of candidateByBinding.values()) {
|
|
120
|
+
const countByBaseName = baseNameCountsByScope.get(candidate.scope);
|
|
121
|
+
if (!countByBaseName)
|
|
122
|
+
continue;
|
|
123
|
+
const baseNameCount = countByBaseName.get(candidate.baseName);
|
|
124
|
+
if (!baseNameCount || baseNameCount > 1)
|
|
125
|
+
continue;
|
|
126
|
+
if (!canUseExactStableName(candidate.scope, candidate.binding, candidate.binding.identifier.name, candidate.baseName)) {
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
group.add({
|
|
130
|
+
scope: candidate.scope,
|
|
131
|
+
currentName: candidate.binding.identifier.name,
|
|
132
|
+
baseName: candidate.baseName,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
transformationsApplied += group.apply();
|
|
136
|
+
}
|
|
137
|
+
return Promise.resolve({
|
|
138
|
+
nodesVisited,
|
|
139
|
+
transformationsApplied,
|
|
140
|
+
});
|
|
141
|
+
},
|
|
142
|
+
};
|
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.79.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",
|