miniread 1.37.0 → 1.38.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.
@@ -220,6 +220,12 @@ const manifestData = {
220
220
  evaluatedAt: "2026-01-24T15:52:58.710Z",
221
221
  notes: "Measured with baseline none: 0.00%. Added to recommended for readability.",
222
222
  },
223
+ "rename-url-variables": {
224
+ diffReductionImpact: 0.000018848364904289205,
225
+ recommended: true,
226
+ evaluatedAt: "2026-01-24T23:50:56.857Z",
227
+ notes: "Measured with baseline none: 0.00%. Added to recommended for readability.",
228
+ },
223
229
  "rename-use-reference-guards": {
224
230
  diffReductionImpact: 0,
225
231
  recommended: false,
@@ -37,6 +37,7 @@ import { renameTimeoutIdsTransform } from "../rename-timeout-ids/rename-timeout-
37
37
  import { renameTypeofVariablesTransform } from "../rename-typeof-variables/rename-typeof-variables-transform.js";
38
38
  import { renameUint8arrayConcatVariablesTransform } from "../rename-uint8array-concat-variables/rename-uint8array-concat-variables-transform.js";
39
39
  import { renameUrlParametersTransform } from "../rename-url-parameters/rename-url-parameters-transform.js";
40
+ import { renameUrlVariablesTransform } from "../rename-url-variables/rename-url-variables-transform.js";
40
41
  import { renameUseReferenceGuardsTransform } from "../rename-use-reference-guards/rename-use-reference-guards-transform.js";
41
42
  import { renameUseReferenceGuardsV2Transform } from "../rename-use-reference-guards-v2/rename-use-reference-guards-v2-transform.js";
42
43
  import { simplifyBooleanNegationsTransform } from "../simplify-boolean-negations/simplify-boolean-negations-transform.js";
@@ -81,6 +82,7 @@ export const transformRegistry = {
81
82
  [renameTypeofVariablesTransform.id]: renameTypeofVariablesTransform,
82
83
  [renameUint8arrayConcatVariablesTransform.id]: renameUint8arrayConcatVariablesTransform,
83
84
  [renameUrlParametersTransform.id]: renameUrlParametersTransform,
85
+ [renameUrlVariablesTransform.id]: renameUrlVariablesTransform,
84
86
  [renameUseReferenceGuardsTransform.id]: renameUseReferenceGuardsTransform,
85
87
  [renameUseReferenceGuardsV2Transform.id]: renameUseReferenceGuardsV2Transform,
86
88
  [simplifyBooleanNegationsTransform.id]: simplifyBooleanNegationsTransform,
@@ -2,59 +2,10 @@ import { createRequire } from "node:module";
2
2
  import { isIdentifierName, isKeyword, isStrictBindReservedWord, } from "@babel/helper-validator-identifier";
3
3
  import { isStableRenamed, RenameGroup } from "../../core/stable-naming.js";
4
4
  import { getFilesToProcess, } from "../../core/types.js";
5
+ import { hasUrlDestructure } from "../url-usage-heuristics.js";
5
6
  const require = createRequire(import.meta.url);
6
7
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
7
8
  const traverse = require("@babel/traverse").default;
8
- const urlPropertyNames = new Set([
9
- "hash",
10
- "host",
11
- "hostname",
12
- "href",
13
- "origin",
14
- "password",
15
- "pathname",
16
- "port",
17
- "protocol",
18
- "search",
19
- "searchParams",
20
- "username",
21
- ]);
22
- const countUrlProperties = (pattern) => {
23
- let count = 0;
24
- for (const property of pattern.properties) {
25
- if (property.type !== "ObjectProperty")
26
- continue;
27
- if (property.computed)
28
- continue;
29
- const key = property.key;
30
- const keyName = key.type === "Identifier"
31
- ? key.name
32
- : key.type === "StringLiteral"
33
- ? key.value
34
- : undefined;
35
- if (keyName && urlPropertyNames.has(keyName)) {
36
- count += 1;
37
- }
38
- }
39
- return count;
40
- };
41
- const hasUrlDestructure = (referencePath) => {
42
- const parent = referencePath.parentPath;
43
- if (!parent)
44
- return false;
45
- if (parent.isVariableDeclarator() &&
46
- parent.node.init === referencePath.node &&
47
- parent.node.id.type === "ObjectPattern") {
48
- return countUrlProperties(parent.node.id) >= 2;
49
- }
50
- if (parent.isAssignmentExpression() &&
51
- parent.node.operator === "=" &&
52
- parent.node.right === referencePath.node &&
53
- parent.node.left.type === "ObjectPattern") {
54
- return countUrlProperties(parent.node.left) >= 2;
55
- }
56
- return false;
57
- };
58
9
  const hasUrlConstruction = (referencePath) => {
59
10
  const parent = referencePath.parentPath;
60
11
  if (!parent?.isNewExpression())
@@ -0,0 +1,6 @@
1
+ {
2
+ "diffReductionImpact": 0.000018848364904289205,
3
+ "recommended": true,
4
+ "evaluatedAt": "2026-01-24T23:50:56.857Z",
5
+ "notes": "Measured with baseline none: 0.00%. Added to recommended for readability."
6
+ }
@@ -0,0 +1,2 @@
1
+ import { type Transform } from "../../core/types.js";
2
+ export declare const renameUrlVariablesTransform: Transform;
@@ -0,0 +1,94 @@
1
+ import { createRequire } from "node:module";
2
+ import { isStableRenamed, RenameGroup } from "../../core/stable-naming.js";
3
+ import { getFilesToProcess, } from "../../core/types.js";
4
+ import { hasUrlDestructure, urlPropertyNames, } from "../url-usage-heuristics.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 isUrlConstruction = (node) => {
9
+ if (node?.type !== "NewExpression")
10
+ return false;
11
+ if (node.callee.type !== "Identifier" || node.callee.name !== "URL") {
12
+ return false;
13
+ }
14
+ return true;
15
+ };
16
+ const isUrlPropertyAccess = (referencePath) => {
17
+ const parent = referencePath.parentPath;
18
+ if (!parent)
19
+ return false;
20
+ if (!parent.isMemberExpression())
21
+ return false;
22
+ if (parent.node.object !== referencePath.node)
23
+ return false;
24
+ if (parent.node.computed)
25
+ return false;
26
+ const key = parent.node.property;
27
+ const keyName = key.type === "Identifier"
28
+ ? key.name
29
+ : key.type === "StringLiteral"
30
+ ? key.value
31
+ : undefined;
32
+ if (!keyName)
33
+ return false;
34
+ return urlPropertyNames.has(keyName);
35
+ };
36
+ export const renameUrlVariablesTransform = {
37
+ id: "rename-url-variables",
38
+ description: "Renames variables initialized with new URL(...) when they are accessed via URL properties",
39
+ scope: "file",
40
+ parallelizable: true,
41
+ transform(context) {
42
+ let nodesVisited = 0;
43
+ let transformationsApplied = 0;
44
+ for (const fileInfo of getFilesToProcess(context)) {
45
+ const group = new RenameGroup();
46
+ traverse(fileInfo.ast, {
47
+ VariableDeclarator(path) {
48
+ nodesVisited += 1;
49
+ if (path.node.id.type !== "Identifier")
50
+ return;
51
+ if (!isUrlConstruction(path.node.init))
52
+ return;
53
+ const currentName = path.node.id.name;
54
+ if (isStableRenamed(currentName))
55
+ return;
56
+ const binding = path.scope.getBinding(currentName);
57
+ if (!binding)
58
+ return;
59
+ let sawUrlDestructure = false;
60
+ let propertyAccesses = 0;
61
+ for (const referencePath of binding.referencePaths) {
62
+ const hasDestructure = hasUrlDestructure(referencePath);
63
+ if (hasDestructure) {
64
+ sawUrlDestructure = true;
65
+ }
66
+ if (propertyAccesses < 2 && isUrlPropertyAccess(referencePath)) {
67
+ propertyAccesses += 1;
68
+ }
69
+ if (sawUrlDestructure || propertyAccesses >= 2)
70
+ break;
71
+ }
72
+ if (!sawUrlDestructure && propertyAccesses < 2)
73
+ return;
74
+ const candidateName = "url";
75
+ if (candidateName === currentName)
76
+ return;
77
+ const programScope = path.scope.getProgramParent();
78
+ if (Object.hasOwn(programScope.globals, candidateName))
79
+ return;
80
+ group.add({
81
+ scope: path.scope,
82
+ currentName,
83
+ baseName: candidateName,
84
+ });
85
+ },
86
+ });
87
+ transformationsApplied += group.apply();
88
+ }
89
+ return Promise.resolve({
90
+ nodesVisited,
91
+ transformationsApplied,
92
+ });
93
+ },
94
+ };
@@ -0,0 +1,3 @@
1
+ import type { NodePath } from "@babel/traverse";
2
+ export declare const urlPropertyNames: Set<string>;
3
+ export declare const hasUrlDestructure: (referencePath: NodePath) => boolean;
@@ -0,0 +1,50 @@
1
+ export const urlPropertyNames = new Set([
2
+ "hash",
3
+ "host",
4
+ "hostname",
5
+ "href",
6
+ "origin",
7
+ "password",
8
+ "pathname",
9
+ "port",
10
+ "protocol",
11
+ "search",
12
+ "searchParams",
13
+ "username",
14
+ ]);
15
+ const countUrlProperties = (pattern) => {
16
+ let count = 0;
17
+ for (const property of pattern.properties) {
18
+ if (property.type !== "ObjectProperty")
19
+ continue;
20
+ if (property.computed)
21
+ continue;
22
+ const key = property.key;
23
+ const keyName = key.type === "Identifier"
24
+ ? key.name
25
+ : key.type === "StringLiteral"
26
+ ? key.value
27
+ : undefined;
28
+ if (keyName && urlPropertyNames.has(keyName)) {
29
+ count += 1;
30
+ }
31
+ }
32
+ return count;
33
+ };
34
+ export const hasUrlDestructure = (referencePath) => {
35
+ const parent = referencePath.parentPath;
36
+ if (!parent)
37
+ return false;
38
+ if (parent.isVariableDeclarator() &&
39
+ parent.node.init === referencePath.node &&
40
+ parent.node.id.type === "ObjectPattern") {
41
+ return countUrlProperties(parent.node.id) >= 2;
42
+ }
43
+ if (parent.isAssignmentExpression() &&
44
+ parent.node.operator === "=" &&
45
+ parent.node.right === referencePath.node &&
46
+ parent.node.left.type === "ObjectPattern") {
47
+ return countUrlProperties(parent.node.left) >= 2;
48
+ }
49
+ return false;
50
+ };
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.37.0",
5
+ "version": "1.38.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",