miniread 1.85.0 → 1.86.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.
Files changed (47) hide show
  1. package/dist/transforms/_generated/manifest.js +5 -0
  2. package/dist/transforms/_generated/registry.js +2 -0
  3. package/dist/transforms/preset-stats.json +2 -2
  4. package/dist/transforms/recommended-transform-order.d.ts +1 -1
  5. package/dist/transforms/recommended-transform-order.js +1 -0
  6. package/dist/transforms/rename-default-options-parameters-v3/manifest.json +12 -0
  7. package/dist/transforms/rename-default-options-parameters-v3/rename-default-options-parameters-v3-transform.d.ts +2 -0
  8. package/dist/transforms/rename-default-options-parameters-v3/rename-default-options-parameters-v3-transform.js +58 -0
  9. package/dist/transforms/rename-deferred-resolve-parameters/rename-binding-if-safe.d.ts +2 -2
  10. package/dist/transforms/rename-deferred-resolve-parameters/rename-binding-if-safe.js +1 -19
  11. package/dist/transforms/rename-deferred-resolve-parameters/single-executor-heuristics.d.ts +1 -1
  12. package/dist/transforms/rename-deferred-resolve-parameters/single-executor-heuristics.js +5 -25
  13. package/dist/transforms/rename-event-parameters/process-event-handler-function.js +6 -3
  14. package/dist/transforms/rename-promise-executor-parameters/promise-executor-heuristics.d.ts +0 -1
  15. package/dist/transforms/rename-promise-executor-parameters/promise-executor-heuristics.js +5 -26
  16. package/dist/transforms/rename-promise-executor-parameters/rename-binding-if-safe.d.ts +3 -3
  17. package/dist/transforms/rename-promise-executor-parameters/rename-binding-if-safe.js +5 -21
  18. package/dist/transforms/rename-promise-executor-parameters/rename-promise-executor-parameters-transform.js +5 -4
  19. package/dist/transforms/rename-promise-executor-parameters-v2/promise-executor-heuristics.d.ts +0 -1
  20. package/dist/transforms/rename-promise-executor-parameters-v2/promise-executor-heuristics.js +0 -21
  21. package/dist/transforms/rename-promise-executor-parameters-v2/rename-promise-executor-parameters-v2-transform.js +5 -4
  22. package/dist/transforms/shared/can-rename-binding-safely.d.ts +8 -0
  23. package/dist/transforms/{rename-event-parameters → shared}/can-rename-binding-safely.js +11 -2
  24. package/dist/transforms/shared/is-valid-binding-identifier.d.ts +1 -0
  25. package/dist/transforms/{rename-event-parameters → shared}/is-valid-binding-identifier.js +2 -2
  26. package/dist/transforms/stabilize-deferred-stable-rhs/stabilize-deferred-stable-rhs-transform.js +2 -1
  27. package/dist/transforms/stabilize-deferred-top-level-bindings/rename-helpers.d.ts +0 -4
  28. package/dist/transforms/stabilize-deferred-top-level-bindings/rename-helpers.js +0 -19
  29. package/dist/transforms/stabilize-deferred-top-level-bindings/stabilize-deferred-top-level-bindings-transform.js +6 -2
  30. package/dist/transforms/stabilize-top-level-bindings/stabilize-top-level-bindings-transform.js +1 -1
  31. package/package.json +1 -1
  32. package/dist/transforms/rename-deferred-resolve-parameters/is-valid-binding-identifier.d.ts +0 -1
  33. package/dist/transforms/rename-deferred-resolve-parameters/is-valid-binding-identifier.js +0 -10
  34. package/dist/transforms/rename-event-parameters/can-rename-binding-safely.d.ts +0 -2
  35. package/dist/transforms/rename-event-parameters/is-valid-binding-identifier.d.ts +0 -1
  36. package/dist/transforms/rename-promise-executor-parameters/is-valid-binding-identifier.d.ts +0 -1
  37. package/dist/transforms/rename-promise-executor-parameters/is-valid-binding-identifier.js +0 -10
  38. package/dist/transforms/rename-promise-executor-parameters-v2/is-valid-binding-identifier.d.ts +0 -1
  39. package/dist/transforms/rename-promise-executor-parameters-v2/is-valid-binding-identifier.js +0 -13
  40. package/dist/transforms/rename-promise-executor-parameters-v2/rename-binding-if-safe.d.ts +0 -2
  41. package/dist/transforms/rename-promise-executor-parameters-v2/rename-binding-if-safe.js +0 -21
  42. package/dist/transforms/stabilize-top-level-bindings/can-rename-binding-safely.d.ts +0 -2
  43. package/dist/transforms/stabilize-top-level-bindings/can-rename-binding-safely.js +0 -24
  44. package/dist/transforms/stabilize-top-level-bindings/is-valid-binding-identifier.d.ts +0 -1
  45. package/dist/transforms/stabilize-top-level-bindings/is-valid-binding-identifier.js +0 -10
  46. /package/dist/transforms/{rename-event-parameters → shared}/would-shadow-referenced-outer-binding.d.ts +0 -0
  47. /package/dist/transforms/{rename-event-parameters → shared}/would-shadow-referenced-outer-binding.js +0 -0
@@ -112,6 +112,10 @@ const manifestData = {
112
112
  recommended: true,
113
113
  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 } },
114
114
  },
115
+ "rename-default-options-parameters-v3": {
116
+ recommended: true,
117
+ evaluations: { "claude-code-2.1.10:claude-code-2.1.11": { "diffSizePercent": 99.98303647158609, "evaluatedAt": "2026-02-06T21:30:46.281Z", "changedLines": 2568, "durationSeconds": 339.62647627599995, "stableNames": 1359 } },
118
+ },
115
119
  "rename-deferred-resolve-parameters": {
116
120
  recommended: true,
117
121
  notes: "Measured with baseline none: 0.00%. Renames single-parameter promise executors to $resolve when usage only stores or calls the resolver.",
@@ -482,6 +486,7 @@ export const recommendedTransformIds = [
482
486
  "rename-platform-win32-flags",
483
487
  "rename-date-now-start-times",
484
488
  "rename-default-options-parameters-v2",
489
+ "rename-default-options-parameters-v3",
485
490
  "rename-deferred-resolve-parameters",
486
491
  "rename-deferred-resolve-parameters-v2",
487
492
  "rename-destructured-aliases",
@@ -22,6 +22,7 @@ import { renameComparisonFlagsTransform } from "../rename-comparison-flags/renam
22
22
  import { renameDateNowStartTimesTransform } from "../rename-date-now-start-times/rename-date-now-start-times-transform.js";
23
23
  import { renameDefaultOptionsParametersTransform } from "../rename-default-options-parameters/rename-default-options-parameters-transform.js";
24
24
  import { renameDefaultOptionsParametersV2Transform } from "../rename-default-options-parameters-v2/rename-default-options-parameters-v2-transform.js";
25
+ import { renameDefaultOptionsParametersV3Transform } from "../rename-default-options-parameters-v3/rename-default-options-parameters-v3-transform.js";
25
26
  import { renameDeferredResolveParametersTransform } from "../rename-deferred-resolve-parameters/rename-deferred-resolve-parameters-transform.js";
26
27
  import { renameDeferredResolveParametersV2Transform } from "../rename-deferred-resolve-parameters-v2/rename-deferred-resolve-parameters-v2-transform.js";
27
28
  import { renameDestructuredAliasesTransform } from "../rename-destructured-aliases/rename-destructured-aliases-transform.js";
@@ -114,6 +115,7 @@ export const transformRegistry = {
114
115
  [renameDateNowStartTimesTransform.id]: renameDateNowStartTimesTransform,
115
116
  [renameDefaultOptionsParametersTransform.id]: renameDefaultOptionsParametersTransform,
116
117
  [renameDefaultOptionsParametersV2Transform.id]: renameDefaultOptionsParametersV2Transform,
118
+ [renameDefaultOptionsParametersV3Transform.id]: renameDefaultOptionsParametersV3Transform,
117
119
  [renameDeferredResolveParametersTransform.id]: renameDeferredResolveParametersTransform,
118
120
  [renameDeferredResolveParametersV2Transform.id]: renameDeferredResolveParametersV2Transform,
119
121
  [renameDestructuredAliasesTransform.id]: renameDestructuredAliasesTransform,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "recommended": {
3
- "diffSizePercent": 30.450475921213833,
4
- "notes": "Measured with baseline none: 30.45% of original diff."
3
+ "diffSizePercent": 30.431627556309493,
4
+ "notes": "Measured with baseline none: 30.43% of original diff."
5
5
  }
6
6
  }
@@ -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-platform-win32-flags", "rename-date-now-start-times", "rename-default-options-parameters-v2", "rename-deferred-resolve-parameters", "rename-deferred-resolve-parameters-v2", "rename-destructured-aliases", "rename-rest-parameters", "rename-rest-pop-callbacks", "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-add-event-listener-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-object-keys-reducer-parameters", "rename-object-entries-parameters", "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-setstate-updater-parameters", "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-platform-win32-flags", "rename-date-now-start-times", "rename-default-options-parameters-v2", "rename-default-options-parameters-v3", "rename-deferred-resolve-parameters", "rename-deferred-resolve-parameters-v2", "rename-destructured-aliases", "rename-rest-parameters", "rename-rest-pop-callbacks", "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-add-event-listener-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-object-keys-reducer-parameters", "rename-object-entries-parameters", "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-setstate-updater-parameters", "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"];
@@ -39,6 +39,7 @@ export const recommendedTransformOrder = [
39
39
  "rename-platform-win32-flags",
40
40
  "rename-date-now-start-times",
41
41
  "rename-default-options-parameters-v2",
42
+ "rename-default-options-parameters-v3",
42
43
  "rename-deferred-resolve-parameters",
43
44
  "rename-deferred-resolve-parameters-v2",
44
45
  "rename-destructured-aliases",
@@ -0,0 +1,12 @@
1
+ {
2
+ "recommended": true,
3
+ "evaluations": {
4
+ "claude-code-2.1.10:claude-code-2.1.11": {
5
+ "diffSizePercent": 99.98303647158609,
6
+ "evaluatedAt": "2026-02-06T21:30:46.281Z",
7
+ "changedLines": 2568,
8
+ "durationSeconds": 339.62647627599995,
9
+ "stableNames": 1359
10
+ }
11
+ }
12
+ }
@@ -0,0 +1,2 @@
1
+ import { type Transform } from "../../core/types.js";
2
+ export declare const renameDefaultOptionsParametersV3Transform: Transform;
@@ -0,0 +1,58 @@
1
+ import { createRequire } from "node:module";
2
+ import * as t from "@babel/types";
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 BASE_NAME = "options";
9
+ const collectDefaultOptionsParameterNames = (path) => {
10
+ const parameterNames = [];
11
+ for (const parameter of path.node.params) {
12
+ if (!t.isAssignmentPattern(parameter))
13
+ continue;
14
+ if (!t.isIdentifier(parameter.left))
15
+ continue;
16
+ if (!t.isObjectExpression(parameter.right))
17
+ continue;
18
+ if (parameter.right.properties.length > 0)
19
+ continue;
20
+ parameterNames.push(parameter.left.name);
21
+ }
22
+ return parameterNames;
23
+ };
24
+ export const renameDefaultOptionsParametersV3Transform = {
25
+ id: "rename-default-options-parameters-v3",
26
+ description: "Renames parameters defaulted to {} into stable options names",
27
+ scope: "file",
28
+ parallelizable: true,
29
+ transform(context) {
30
+ let nodesVisited = 0;
31
+ let transformationsApplied = 0;
32
+ for (const fileInfo of getFilesToProcess(context)) {
33
+ const group = new RenameGroup();
34
+ traverse(fileInfo.ast, {
35
+ Function(path) {
36
+ nodesVisited++;
37
+ const parameterNames = collectDefaultOptionsParameterNames(path);
38
+ for (const parameterName of parameterNames) {
39
+ if (parameterName === BASE_NAME)
40
+ continue;
41
+ if (isStableRenamed(parameterName))
42
+ continue;
43
+ group.add({
44
+ scope: path.scope,
45
+ currentName: parameterName,
46
+ baseName: BASE_NAME,
47
+ });
48
+ }
49
+ },
50
+ });
51
+ transformationsApplied += group.apply();
52
+ }
53
+ return Promise.resolve({
54
+ nodesVisited,
55
+ transformationsApplied,
56
+ });
57
+ },
58
+ };
@@ -1,2 +1,2 @@
1
- import type { NodePath } from "@babel/traverse";
2
- export declare const renameBindingIfSafe: (bindingScope: NodePath["scope"], fromName: string, toName: string) => boolean;
1
+ import type { Scope } from "@babel/traverse";
2
+ export declare const renameBindingIfSafe: (bindingScope: Scope, fromName: string, toName: string) => boolean;
@@ -1,22 +1,4 @@
1
- import { hasShadowingRisk } from "../../core/has-shadowing-risk.js";
2
- import { isValidBindingIdentifier } from "./is-valid-binding-identifier.js";
3
- const canRenameBindingSafely = (bindingScope, fromName, toName) => {
4
- if (fromName === toName)
5
- return false;
6
- if (!isValidBindingIdentifier(toName))
7
- return false;
8
- if (bindingScope.hasOwnBinding(toName))
9
- return false;
10
- const programScope = bindingScope.getProgramParent();
11
- if (Object.hasOwn(programScope.globals, toName))
12
- return false;
13
- const binding = bindingScope.getBinding(fromName);
14
- if (!binding)
15
- return false;
16
- if (hasShadowingRisk(binding, bindingScope, toName))
17
- return false;
18
- return true;
19
- };
1
+ import { canRenameBindingSafely } from "../shared/can-rename-binding-safely.js";
20
2
  export const renameBindingIfSafe = (bindingScope, fromName, toName) => {
21
3
  if (!canRenameBindingSafely(bindingScope, fromName, toName))
22
4
  return false;
@@ -3,4 +3,4 @@ import type { ArrowFunctionExpression, FunctionExpression, NewExpression } from
3
3
  export declare const getSingleExecutorFunctionIfEligible: (path: NodePath<NewExpression>) => NodePath<FunctionExpression | ArrowFunctionExpression> | undefined;
4
4
  export declare const isDirectCallOfBinding: (referencePath: NodePath) => boolean;
5
5
  export declare const isAssignedToIdentifier: (referencePath: NodePath, bindingName: string) => boolean;
6
- export declare const wouldShadowReferencedOuterBinding: (executorPath: NodePath<FunctionExpression | ArrowFunctionExpression>, targetName: string) => boolean;
6
+ export { wouldShadowReferencedOuterBinding } from "../shared/would-shadow-referenced-outer-binding.js";
@@ -1,6 +1,6 @@
1
- import { isValidBindingIdentifier } from "./is-valid-binding-identifier.js";
2
- const isExecutorParameterEligible = (parameter) => {
3
- if (!isValidBindingIdentifier(parameter.name))
1
+ import { isValidBindingIdentifier } from "../shared/is-valid-binding-identifier.js";
2
+ const isExecutorParameterEligible = (parameterName) => {
3
+ if (!isValidBindingIdentifier(parameterName))
4
4
  return false;
5
5
  return true;
6
6
  };
@@ -20,7 +20,7 @@ export const getSingleExecutorFunctionIfEligible = (path) => {
20
20
  return;
21
21
  if (parameter.type !== "Identifier")
22
22
  return;
23
- if (!isExecutorParameterEligible(parameter))
23
+ if (!isExecutorParameterEligible(parameter.name))
24
24
  return;
25
25
  return executor;
26
26
  };
@@ -48,24 +48,4 @@ export const isAssignedToIdentifier = (referencePath, bindingName) => {
48
48
  }
49
49
  return false;
50
50
  };
51
- export const wouldShadowReferencedOuterBinding = (executorPath, targetName) => {
52
- const parentBinding = executorPath.scope.getBinding(targetName);
53
- if (!parentBinding)
54
- return false;
55
- let foundReference = false;
56
- executorPath.traverse({
57
- Identifier(identifierPath) {
58
- if (foundReference)
59
- return;
60
- if (identifierPath.node.name !== targetName)
61
- return;
62
- if (!identifierPath.isReferencedIdentifier())
63
- return;
64
- if (identifierPath.scope.getBinding(targetName) !== parentBinding)
65
- return;
66
- foundReference = true;
67
- identifierPath.stop();
68
- },
69
- });
70
- return foundReference;
71
- };
51
+ export { wouldShadowReferencedOuterBinding } from "../shared/would-shadow-referenced-outer-binding.js";
@@ -1,8 +1,8 @@
1
1
  import { isStableRenamed } from "../../core/stable-naming.js";
2
+ import { canRenameBindingSafely } from "../shared/can-rename-binding-safely.js";
3
+ import { wouldShadowReferencedOuterBinding } from "../shared/would-shadow-referenced-outer-binding.js";
2
4
  import { getEventParameterUsage, isHighConfidenceEventParameter, } from "./event-parameter-usage.js";
3
5
  import { getTargetEventName } from "./get-target-event-name.js";
4
- import { canRenameBindingSafely } from "./can-rename-binding-safely.js";
5
- import { wouldShadowReferencedOuterBinding } from "./would-shadow-referenced-outer-binding.js";
6
6
  const wouldShadowReferencedImplicitGlobal = (functionPath, targetName) => {
7
7
  const programScope = functionPath.scope.getProgramParent();
8
8
  if (!Object.hasOwn(programScope.globals, targetName))
@@ -53,8 +53,11 @@ export const processEventHandlerFunction = (path, group) => {
53
53
  return;
54
54
  if (wouldShadowReferencedOuterBinding(path, targetName))
55
55
  return;
56
- if (!canRenameBindingSafely(bindingScope, currentName, targetName))
56
+ if (!canRenameBindingSafely(bindingScope, currentName, targetName, {
57
+ checkGlobals: false,
58
+ })) {
57
59
  return;
60
+ }
58
61
  group.add({
59
62
  scope: bindingScope,
60
63
  currentName,
@@ -3,4 +3,3 @@ import type { ArrowFunctionExpression, FunctionExpression, NewExpression } from
3
3
  export declare const getExecutorFunctionIfEligible: (path: NodePath<NewExpression>) => NodePath<FunctionExpression | ArrowFunctionExpression> | undefined;
4
4
  export declare const isDirectCallOfBinding: (referencePath: NodePath) => boolean;
5
5
  export declare const isAssignedToOnHandlerProperty: (referencePath: NodePath) => boolean;
6
- export declare const wouldShadowReferencedOuterBinding: (executorPath: NodePath<FunctionExpression | ArrowFunctionExpression>, targetName: string) => boolean;
@@ -1,11 +1,11 @@
1
- import { isValidBindingIdentifier } from "./is-valid-binding-identifier.js";
1
+ import { isValidBindingIdentifier } from "../shared/is-valid-binding-identifier.js";
2
2
  const allowedOnHandlerPropertyNames = new Set([
3
3
  "onabort",
4
4
  "onerror",
5
5
  "ontimeout",
6
6
  ]);
7
- const isExecutorParameterEligible = (parameter) => {
8
- if (!isValidBindingIdentifier(parameter.name))
7
+ const isExecutorParameterEligible = (parameterName) => {
8
+ if (!isValidBindingIdentifier(parameterName))
9
9
  return false;
10
10
  return true;
11
11
  };
@@ -30,9 +30,9 @@ export const getExecutorFunctionIfEligible = (path) => {
30
30
  return;
31
31
  if (secondParameter.type !== "Identifier")
32
32
  return;
33
- if (!isExecutorParameterEligible(firstParameter))
33
+ if (!isExecutorParameterEligible(firstParameter.name))
34
34
  return;
35
- if (!isExecutorParameterEligible(secondParameter))
35
+ if (!isExecutorParameterEligible(secondParameter.name))
36
36
  return;
37
37
  return executor;
38
38
  };
@@ -61,24 +61,3 @@ export const isAssignedToOnHandlerProperty = (referencePath) => {
61
61
  return false;
62
62
  return true;
63
63
  };
64
- export const wouldShadowReferencedOuterBinding = (executorPath, targetName) => {
65
- const parentBinding = executorPath.scope.getBinding(targetName);
66
- if (!parentBinding)
67
- return false;
68
- let foundReference = false;
69
- executorPath.traverse({
70
- Identifier(identifierPath) {
71
- if (foundReference)
72
- return;
73
- if (identifierPath.node.name !== targetName)
74
- return;
75
- if (!identifierPath.isReferencedIdentifier())
76
- return;
77
- if (identifierPath.scope.getBinding(targetName) !== parentBinding)
78
- return;
79
- foundReference = true;
80
- identifierPath.stop();
81
- },
82
- });
83
- return foundReference;
84
- };
@@ -1,3 +1,3 @@
1
- import type { NodePath } from "@babel/traverse";
2
- export declare const canRenameBindingSafely: (bindingScope: NodePath["scope"], fromName: string, toName: string) => boolean;
3
- export declare const renameBindingIfSafe: (bindingScope: NodePath["scope"], fromName: string, toName: string) => boolean;
1
+ import type { Scope } from "@babel/traverse";
2
+ export declare const canRenamePromiseBindingSafely: (bindingScope: Scope, fromName: string, toName: string) => boolean;
3
+ export declare const renameBindingIfSafe: (bindingScope: Scope, fromName: string, toName: string) => boolean;
@@ -1,27 +1,11 @@
1
- import { hasShadowingRisk } from "../../core/has-shadowing-risk.js";
2
- import { isValidBindingIdentifier } from "./is-valid-binding-identifier.js";
3
- export const canRenameBindingSafely = (bindingScope, fromName, toName) => {
4
- if (fromName === toName)
5
- return false;
6
- if (!isValidBindingIdentifier(toName))
7
- return false;
8
- if (bindingScope.hasOwnBinding(toName))
9
- return false;
10
- const programScope = bindingScope.getProgramParent();
11
- // `globals` contains only referenced (unbound) globals for this file, so this does not block
12
- // in files where the identifier is never used.
13
- if (Object.hasOwn(programScope.globals, toName))
14
- return false;
15
- const binding = bindingScope.getBinding(fromName);
16
- if (!binding)
17
- return false;
18
- if (hasShadowingRisk(binding, bindingScope, toName))
19
- return false;
20
- return true;
1
+ import { canRenameBindingSafely } from "../shared/can-rename-binding-safely.js";
2
+ export const canRenamePromiseBindingSafely = (bindingScope, fromName, toName) => {
3
+ return canRenameBindingSafely(bindingScope, fromName, toName);
21
4
  };
22
5
  export const renameBindingIfSafe = (bindingScope, fromName, toName) => {
23
- if (!canRenameBindingSafely(bindingScope, fromName, toName))
6
+ if (!canRenamePromiseBindingSafely(bindingScope, fromName, toName)) {
24
7
  return false;
8
+ }
25
9
  bindingScope.rename(fromName, toName);
26
10
  return true;
27
11
  };
@@ -1,8 +1,9 @@
1
1
  import { createRequire } from "node:module";
2
2
  import { isStableRenamed } from "../../core/stable-naming.js";
3
3
  import { getFilesToProcess, } from "../../core/types.js";
4
- import { getExecutorFunctionIfEligible, isAssignedToOnHandlerProperty, isDirectCallOfBinding, wouldShadowReferencedOuterBinding, } from "./promise-executor-heuristics.js";
5
- import { canRenameBindingSafely, renameBindingIfSafe, } from "./rename-binding-if-safe.js";
4
+ import { getExecutorFunctionIfEligible, isAssignedToOnHandlerProperty, isDirectCallOfBinding, } from "./promise-executor-heuristics.js";
5
+ import { canRenamePromiseBindingSafely, renameBindingIfSafe, } from "./rename-binding-if-safe.js";
6
+ import { wouldShadowReferencedOuterBinding } from "../shared/would-shadow-referenced-outer-binding.js";
6
7
  const STABLE_PREFIX = "$";
7
8
  const require = createRequire(import.meta.url);
8
9
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
@@ -56,10 +57,10 @@ export const renamePromiseExecutorParametersTransform = {
56
57
  const wantsRejectRename = rejectParameter.name !== targetRejectName;
57
58
  const canRenameResolve = !wantsResolveRename ||
58
59
  (!resolveWouldShadow &&
59
- canRenameBindingSafely(bindingScope, resolveParameter.name, targetResolveName));
60
+ canRenamePromiseBindingSafely(bindingScope, resolveParameter.name, targetResolveName));
60
61
  const canRenameReject = !wantsRejectRename ||
61
62
  (!rejectWouldShadow &&
62
- canRenameBindingSafely(bindingScope, rejectParameter.name, targetRejectName));
63
+ canRenamePromiseBindingSafely(bindingScope, rejectParameter.name, targetRejectName));
63
64
  // Avoid ending up with inconsistent executor signatures like `(WA, reject)` —
64
65
  // only rename when both parameters are already correct or can be renamed safely.
65
66
  if (!canRenameResolve || !canRenameReject)
@@ -5,4 +5,3 @@ export declare const isDirectCallOfBinding: (referencePath: NodePath) => boolean
5
5
  export declare const isAssignedToOnHandlerProperty: (referencePath: NodePath) => boolean;
6
6
  export declare const isErrorEventHandlerArgument: (referencePath: NodePath) => boolean;
7
7
  export declare const isErrorEventHandlerRemovalArgument: (referencePath: NodePath) => boolean;
8
- export declare const wouldShadowReferencedOuterBinding: (executorPath: NodePath<FunctionExpression | ArrowFunctionExpression>, targetName: string) => boolean;
@@ -122,24 +122,3 @@ export const isErrorEventHandlerRemovalArgument = (referencePath) => {
122
122
  }
123
123
  return true;
124
124
  };
125
- export const wouldShadowReferencedOuterBinding = (executorPath, targetName) => {
126
- const parentBinding = executorPath.scope.getBinding(targetName);
127
- if (!parentBinding)
128
- return false;
129
- let foundReference = false;
130
- executorPath.traverse({
131
- Identifier(identifierPath) {
132
- if (foundReference)
133
- return;
134
- if (identifierPath.node.name !== targetName)
135
- return;
136
- if (!identifierPath.isReferencedIdentifier())
137
- return;
138
- if (identifierPath.scope.getBinding(targetName) !== parentBinding)
139
- return;
140
- foundReference = true;
141
- identifierPath.stop();
142
- },
143
- });
144
- return foundReference;
145
- };
@@ -1,8 +1,9 @@
1
1
  import { createRequire } from "node:module";
2
2
  import { isStableRenamed } from "../../core/stable-naming.js";
3
3
  import { getFilesToProcess, } from "../../core/types.js";
4
- import { getExecutorFunctionIfEligible, isAssignedToOnHandlerProperty, isDirectCallOfBinding, isErrorEventHandlerArgument, isErrorEventHandlerRemovalArgument, wouldShadowReferencedOuterBinding, } from "./promise-executor-heuristics.js";
5
- import { canRenameBindingSafely } from "./rename-binding-if-safe.js";
4
+ import { getExecutorFunctionIfEligible, isAssignedToOnHandlerProperty, isDirectCallOfBinding, isErrorEventHandlerArgument, isErrorEventHandlerRemovalArgument, } from "./promise-executor-heuristics.js";
5
+ import { canRenameBindingSafely } from "../shared/can-rename-binding-safely.js";
6
+ import { wouldShadowReferencedOuterBinding } from "../shared/would-shadow-referenced-outer-binding.js";
6
7
  const STABLE_PREFIX = "$";
7
8
  const require = createRequire(import.meta.url);
8
9
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
@@ -92,10 +93,10 @@ export const renamePromiseExecutorParametersV2Transform = {
92
93
  const fromRejectName = rejectParameter.name;
93
94
  const canRenameResolve = !wantsResolveRename ||
94
95
  (!resolveWouldShadow &&
95
- canRenameBindingSafely(bindingScope, fromResolveName, targetResolveName));
96
+ canRenameBindingSafely(bindingScope, fromResolveName, targetResolveName, { strictMode: false }));
96
97
  const canRenameReject = !wantsRejectRename ||
97
98
  (!rejectWouldShadow &&
98
- canRenameBindingSafely(bindingScope, fromRejectName, targetRejectName));
99
+ canRenameBindingSafely(bindingScope, fromRejectName, targetRejectName, { strictMode: false }));
99
100
  // Avoid ending up with inconsistent executor signatures like `(WA, reject)` —
100
101
  // only rename when both parameters are already correct or can be renamed safely.
101
102
  if (!canRenameResolve || !canRenameReject)
@@ -0,0 +1,8 @@
1
+ import type { Scope } from "@babel/traverse";
2
+ type CanRenameBindingSafelyOptions = {
3
+ checkGlobals?: boolean;
4
+ strictMode?: boolean;
5
+ validateIdentifier?: boolean;
6
+ };
7
+ export declare const canRenameBindingSafely: (bindingScope: Scope, fromName: string, toName: string, options?: CanRenameBindingSafelyOptions) => boolean;
8
+ export {};
@@ -1,12 +1,21 @@
1
1
  import { hasShadowingRisk } from "../../core/has-shadowing-risk.js";
2
2
  import { isValidBindingIdentifier } from "./is-valid-binding-identifier.js";
3
- export const canRenameBindingSafely = (bindingScope, fromName, toName) => {
3
+ export const canRenameBindingSafely = (bindingScope, fromName, toName, options = {}) => {
4
+ const checkGlobals = options.checkGlobals ?? true;
5
+ const strictMode = options.strictMode ?? true;
6
+ const validateIdentifier = options.validateIdentifier ?? true;
4
7
  if (fromName === toName)
5
8
  return false;
6
- if (!isValidBindingIdentifier(toName))
9
+ if (validateIdentifier && !isValidBindingIdentifier(toName, strictMode)) {
7
10
  return false;
11
+ }
8
12
  if (bindingScope.hasOwnBinding(toName))
9
13
  return false;
14
+ if (checkGlobals) {
15
+ const programScope = bindingScope.getProgramParent();
16
+ if (Object.hasOwn(programScope.globals, toName))
17
+ return false;
18
+ }
10
19
  const binding = bindingScope.getBinding(fromName);
11
20
  if (!binding)
12
21
  return false;
@@ -0,0 +1 @@
1
+ export declare const isValidBindingIdentifier: (name: string, strictMode?: boolean) => boolean;
@@ -1,10 +1,10 @@
1
1
  import { isIdentifierName, isKeyword, isStrictBindReservedWord, } from "@babel/helper-validator-identifier";
2
- export const isValidBindingIdentifier = (name) => {
2
+ export const isValidBindingIdentifier = (name, strictMode = true) => {
3
3
  if (!isIdentifierName(name))
4
4
  return false;
5
5
  if (isKeyword(name))
6
6
  return false;
7
- if (isStrictBindReservedWord(name, true))
7
+ if (isStrictBindReservedWord(name, strictMode))
8
8
  return false;
9
9
  return true;
10
10
  };
@@ -5,7 +5,8 @@ import * as t from "@babel/types";
5
5
  import { getFilesToProcess, } from "../../core/types.js";
6
6
  import { generateCode } from "../../cli/generate-code.js";
7
7
  import { isHashBasedStableName } from "../../core/stable-naming.js";
8
- import { canRenameBindingSafely, findEnclosingBindingName, renameBindingInPlace, } from "../stabilize-deferred-top-level-bindings/rename-helpers.js";
8
+ import { findEnclosingBindingName, renameBindingInPlace, } from "../stabilize-deferred-top-level-bindings/rename-helpers.js";
9
+ import { canRenameBindingSafely } from "../shared/can-rename-binding-safely.js";
9
10
  import { hasAllStableReferences } from "./check-rhs-stability.js";
10
11
  const require = createRequire(import.meta.url);
11
12
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
@@ -12,10 +12,6 @@ export declare const extractHashFromStableName: (name: string) => string | undef
12
12
  * afterwards to refresh scope state.
13
13
  */
14
14
  export declare const renameBindingInPlace: (bindingScope: Scope, fromName: string, toName: string) => boolean;
15
- /**
16
- * Check if we can safely rename a binding.
17
- */
18
- export declare const canRenameBindingSafely: (bindingScope: Scope, fromName: string, toName: string) => boolean;
19
15
  /**
20
16
  * Walk up the AST to find the binding name of the enclosing function.
21
17
  * Handles `var $h_xxx = () => { ... }`, `$h_xxx = fn(() => { ... })`,
@@ -1,5 +1,4 @@
1
1
  import * as t from "@babel/types";
2
- import { hasShadowingRisk } from "../../core/has-shadowing-risk.js";
3
2
  /**
4
3
  * Extract the hash suffix from a stable function name (`$h_` or `$f_` prefix).
5
4
  * Does not match `$v_` names — those are deferred variables, not functions.
@@ -48,24 +47,6 @@ export const renameBindingInPlace = (bindingScope, fromName, toName) => {
48
47
  }
49
48
  return true;
50
49
  };
51
- /**
52
- * Check if we can safely rename a binding.
53
- */
54
- export const canRenameBindingSafely = (bindingScope, fromName, toName) => {
55
- if (fromName === toName)
56
- return false;
57
- if (bindingScope.hasOwnBinding(toName))
58
- return false;
59
- const programScope = bindingScope.getProgramParent();
60
- if (Object.hasOwn(programScope.globals, toName))
61
- return false;
62
- const binding = bindingScope.getBinding(fromName);
63
- if (!binding)
64
- return false;
65
- if (hasShadowingRisk(binding, bindingScope, toName))
66
- return false;
67
- return true;
68
- };
69
50
  /**
70
51
  * Walk up the AST to find the binding name of the enclosing function.
71
52
  * Handles `var $h_xxx = () => { ... }`, `$h_xxx = fn(() => { ... })`,
@@ -3,7 +3,8 @@ import { parse } from "@babel/parser";
3
3
  import { getFilesToProcess, } from "../../core/types.js";
4
4
  import { generateCode } from "../../cli/generate-code.js";
5
5
  import { collectDeferredVariables, filterToSingleVariableFunctions, } from "./collect-deferred-variables.js";
6
- import { canRenameBindingSafely, extractHashFromStableName, renameBindingInPlace, } from "./rename-helpers.js";
6
+ import { extractHashFromStableName, renameBindingInPlace, } from "./rename-helpers.js";
7
+ import { canRenameBindingSafely } from "../shared/can-rename-binding-safely.js";
7
8
  const require = createRequire(import.meta.url);
8
9
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
9
10
  const traverse = require("@babel/traverse").default;
@@ -45,8 +46,11 @@ export const stabilizeDeferredTopLevelBindingsTransform = {
45
46
  const newName = `$v_${hash}`;
46
47
  if (usedNewNames.has(newName))
47
48
  continue;
48
- if (!canRenameBindingSafely(scope, variableName, newName))
49
+ if (!canRenameBindingSafely(scope, variableName, newName, {
50
+ validateIdentifier: false,
51
+ })) {
49
52
  continue;
53
+ }
50
54
  if (renameBindingInPlace(scope, variableName, newName)) {
51
55
  usedNewNames.add(newName);
52
56
  fileTransformations++;
@@ -2,7 +2,7 @@ import { parse } from "@babel/parser";
2
2
  import { collectExportedNames } from "../../core/collect-exported-names.js";
3
3
  import { getFilesToProcess, } from "../../core/types.js";
4
4
  import { generateCode } from "../../cli/generate-code.js";
5
- import { canRenameBindingSafely } from "./can-rename-binding-safely.js";
5
+ import { canRenameBindingSafely } from "../shared/can-rename-binding-safely.js";
6
6
  import { collectRenameCandidates } from "./collect-rename-candidates.js";
7
7
  import { detectDynamicNameLookup } from "../dynamic-name-lookup/detect-dynamic-name-lookup.js";
8
8
  import { renameBindingInPlace } from "./rename-binding-in-place.js";
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.85.0",
5
+ "version": "1.86.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",
@@ -1 +0,0 @@
1
- export declare const isValidBindingIdentifier: (name: string) => boolean;
@@ -1,10 +0,0 @@
1
- import { isIdentifierName, isKeyword, isStrictBindReservedWord, } from "@babel/helper-validator-identifier";
2
- export const isValidBindingIdentifier = (name) => {
3
- if (!isIdentifierName(name))
4
- return false;
5
- if (isKeyword(name))
6
- return false;
7
- if (isStrictBindReservedWord(name, true))
8
- return false;
9
- return true;
10
- };
@@ -1,2 +0,0 @@
1
- import type { Scope } from "@babel/traverse";
2
- export declare const canRenameBindingSafely: (bindingScope: Scope, fromName: string, toName: string) => boolean;
@@ -1 +0,0 @@
1
- export declare const isValidBindingIdentifier: (name: string) => boolean;
@@ -1 +0,0 @@
1
- export declare const isValidBindingIdentifier: (name: string) => boolean;
@@ -1,10 +0,0 @@
1
- import { isIdentifierName, isKeyword, isStrictBindReservedWord, } from "@babel/helper-validator-identifier";
2
- export const isValidBindingIdentifier = (name) => {
3
- if (!isIdentifierName(name))
4
- return false;
5
- if (isKeyword(name))
6
- return false;
7
- if (isStrictBindReservedWord(name, true))
8
- return false;
9
- return true;
10
- };
@@ -1 +0,0 @@
1
- export declare const isValidBindingIdentifier: (name: string) => boolean;
@@ -1,13 +0,0 @@
1
- import { isIdentifierName, isKeyword, isStrictBindReservedWord, } from "@babel/helper-validator-identifier";
2
- export const isValidBindingIdentifier = (name) => {
3
- if (!isIdentifierName(name))
4
- return false;
5
- if (isKeyword(name))
6
- return false;
7
- // Parse uses `sourceType: "unambiguous"` which often yields `script`; in that mode,
8
- // some module-only reserved words (e.g. `await`) can be valid identifiers.
9
- // When code is parsed as a module, invalid bindings are rejected by the parser anyway.
10
- if (isStrictBindReservedWord(name, false))
11
- return false;
12
- return true;
13
- };
@@ -1,2 +0,0 @@
1
- import type { NodePath } from "@babel/traverse";
2
- export declare const canRenameBindingSafely: (bindingScope: NodePath["scope"], fromName: string, toName: string) => boolean;
@@ -1,21 +0,0 @@
1
- import { hasShadowingRisk } from "../../core/has-shadowing-risk.js";
2
- import { isValidBindingIdentifier } from "./is-valid-binding-identifier.js";
3
- export const canRenameBindingSafely = (bindingScope, fromName, toName) => {
4
- if (fromName === toName)
5
- return false;
6
- if (!isValidBindingIdentifier(toName))
7
- return false;
8
- if (bindingScope.hasOwnBinding(toName))
9
- return false;
10
- const programScope = bindingScope.getProgramParent();
11
- // `globals` contains only referenced (unbound) globals for this file, so this does not block
12
- // in files where the identifier is never used.
13
- if (Object.hasOwn(programScope.globals, toName))
14
- return false;
15
- const binding = bindingScope.getBinding(fromName);
16
- if (!binding)
17
- return false;
18
- if (hasShadowingRisk(binding, bindingScope, toName))
19
- return false;
20
- return true;
21
- };
@@ -1,2 +0,0 @@
1
- import type { Scope } from "@babel/traverse";
2
- export declare const canRenameBindingSafely: (bindingScope: Scope, fromName: string, toName: string) => boolean;
@@ -1,24 +0,0 @@
1
- import { hasShadowingRisk } from "../../core/has-shadowing-risk.js";
2
- import { isValidBindingIdentifier } from "./is-valid-binding-identifier.js";
3
- export const canRenameBindingSafely = (bindingScope, fromName, toName) => {
4
- if (fromName === toName)
5
- return false; // no rename needed
6
- if (!isValidBindingIdentifier(toName))
7
- return false;
8
- if (bindingScope.hasOwnBinding(toName))
9
- return false;
10
- // This transform renames only program-scope bindings; nested-scope collisions are
11
- // prevented via `hasShadowingRisk` below.
12
- const programScope = bindingScope.getProgramParent();
13
- // NOTE: `toName` always uses the `$h_` prefix, so it can't collide with common
14
- // builtin globals like `window`/`document` even if they aren't referenced. This
15
- // check is about avoiding accidental capture of *referenced* globals.
16
- if (Object.hasOwn(programScope.globals, toName))
17
- return false;
18
- const binding = bindingScope.getBinding(fromName);
19
- if (!binding)
20
- return false;
21
- if (hasShadowingRisk(binding, bindingScope, toName))
22
- return false;
23
- return true;
24
- };
@@ -1 +0,0 @@
1
- export declare const isValidBindingIdentifier: (name: string) => boolean;
@@ -1,10 +0,0 @@
1
- import { isIdentifierName, isKeyword, isStrictBindReservedWord, } from "@babel/helper-validator-identifier";
2
- export const isValidBindingIdentifier = (name) => {
3
- if (!isIdentifierName(name))
4
- return false;
5
- if (isKeyword(name))
6
- return false;
7
- if (isStrictBindReservedWord(name, true))
8
- return false;
9
- return true;
10
- };