miniread 1.35.0 → 1.36.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/collect-exported-names.d.ts +2 -0
- package/dist/core/collect-exported-names.js +68 -0
- package/dist/core/stable-naming.js +8 -4
- package/dist/transforms/_generated/manifest.js +6 -0
- package/dist/transforms/_generated/registry.js +2 -0
- package/dist/transforms/rename-client-aliases/manifest.json +6 -0
- package/dist/transforms/rename-client-aliases/rename-client-aliases-transform.d.ts +2 -0
- package/dist/transforms/rename-client-aliases/rename-client-aliases-transform.js +65 -0
- package/dist/transforms/rename-this-aliases/rename-this-aliases-transform.js +1 -68
- package/dist/transforms/rename-typeof-variables/rename-typeof-variables-transform.js +1 -68
- package/package.json +1 -1
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { isArrayPattern, isAssignmentPattern, isClassDeclaration, isExportNamedDeclaration, isExportSpecifier, isFunctionDeclaration, isIdentifier, isObjectPattern, isObjectProperty, isRestElement, isVariableDeclaration, } from "@babel/types";
|
|
2
|
+
const addBindingNamesFromNode = (node, out) => {
|
|
3
|
+
const babelNode = node;
|
|
4
|
+
if (!babelNode)
|
|
5
|
+
return;
|
|
6
|
+
if (babelNode.type === "VoidPattern")
|
|
7
|
+
return;
|
|
8
|
+
if (isIdentifier(babelNode)) {
|
|
9
|
+
out.add(babelNode.name);
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
if (isObjectPattern(babelNode)) {
|
|
13
|
+
for (const property of babelNode.properties) {
|
|
14
|
+
if (isRestElement(property)) {
|
|
15
|
+
addBindingNamesFromNode(property.argument, out);
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
if (!isObjectProperty(property))
|
|
19
|
+
continue;
|
|
20
|
+
addBindingNamesFromNode(property.value, out);
|
|
21
|
+
}
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
if (isArrayPattern(babelNode)) {
|
|
25
|
+
for (const element of babelNode.elements) {
|
|
26
|
+
addBindingNamesFromNode(element, out);
|
|
27
|
+
}
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (isRestElement(babelNode)) {
|
|
31
|
+
addBindingNamesFromNode(babelNode.argument, out);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
if (isAssignmentPattern(babelNode)) {
|
|
35
|
+
addBindingNamesFromNode(babelNode.left, out);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
export const collectExportedNames = (program) => {
|
|
39
|
+
const exportedNames = new Set();
|
|
40
|
+
for (const statement of program.body) {
|
|
41
|
+
if (!isExportNamedDeclaration(statement))
|
|
42
|
+
continue;
|
|
43
|
+
const declaration = statement.declaration;
|
|
44
|
+
if (declaration) {
|
|
45
|
+
if (isVariableDeclaration(declaration)) {
|
|
46
|
+
for (const declarator of declaration.declarations) {
|
|
47
|
+
addBindingNamesFromNode(declarator.id, exportedNames);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
else if (isFunctionDeclaration(declaration) ||
|
|
51
|
+
isClassDeclaration(declaration)) {
|
|
52
|
+
const id = declaration.id;
|
|
53
|
+
if (!id)
|
|
54
|
+
continue;
|
|
55
|
+
exportedNames.add(id.name);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
for (const specifier of statement.specifiers) {
|
|
59
|
+
if (!isExportSpecifier(specifier))
|
|
60
|
+
continue;
|
|
61
|
+
const local = specifier.local;
|
|
62
|
+
if (!isIdentifier(local))
|
|
63
|
+
continue;
|
|
64
|
+
exportedNames.add(local.name);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return exportedNames;
|
|
68
|
+
};
|
|
@@ -38,7 +38,7 @@ const hasShadowingRisk = (binding, bindingScope, targetName) => binding.referenc
|
|
|
38
38
|
/**
|
|
39
39
|
* Finds the next available name slot in a scope.
|
|
40
40
|
*/
|
|
41
|
-
const findAvailableName = (scope, binding, baseName, startIndex, canBeStable) => {
|
|
41
|
+
const findAvailableName = (scope, binding, baseName, startIndex, canBeStable, currentName) => {
|
|
42
42
|
let index = startIndex;
|
|
43
43
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
44
44
|
while (true) {
|
|
@@ -47,8 +47,12 @@ const findAvailableName = (scope, binding, baseName, startIndex, canBeStable) =>
|
|
|
47
47
|
const candidateStable = makeStableName(candidateBase);
|
|
48
48
|
const candidateReadable = candidateBase;
|
|
49
49
|
// Check if either form is already taken in this scope
|
|
50
|
-
const stableTaken =
|
|
51
|
-
|
|
50
|
+
const stableTaken = candidateStable === currentName
|
|
51
|
+
? false
|
|
52
|
+
: scope.hasBinding(candidateStable);
|
|
53
|
+
const readableTaken = candidateReadable === currentName
|
|
54
|
+
? false
|
|
55
|
+
: scope.hasBinding(candidateReadable);
|
|
52
56
|
if (!stableTaken && !readableTaken) {
|
|
53
57
|
// This slot is available
|
|
54
58
|
const name = canBeStable ? candidateStable : candidateReadable;
|
|
@@ -124,7 +128,7 @@ export class RenameGroup {
|
|
|
124
128
|
let index = 1;
|
|
125
129
|
for (const entry of group) {
|
|
126
130
|
// Find next available name slot
|
|
127
|
-
const targetName = findAvailableName(scope, scope.getBinding(entry.currentName), baseName, index, canBeStable);
|
|
131
|
+
const targetName = findAvailableName(scope, scope.getBinding(entry.currentName), baseName, index, canBeStable, entry.currentName);
|
|
128
132
|
index = targetName.nextIndex;
|
|
129
133
|
if (entry.currentName !== targetName.name) {
|
|
130
134
|
scope.rename(entry.currentName, targetName.name);
|
|
@@ -81,6 +81,12 @@ const manifestData = {
|
|
|
81
81
|
evaluatedAt: "2026-01-23T18:10:00.000Z",
|
|
82
82
|
notes: "Derives names from charCodeAt argument for better stability (e.g., $charCodeAtIndex, $charCodeAtIndexPlus1).",
|
|
83
83
|
},
|
|
84
|
+
"rename-client-aliases": {
|
|
85
|
+
diffReductionImpact: 0,
|
|
86
|
+
recommended: true,
|
|
87
|
+
evaluatedAt: "2026-01-24T15:58:39.356Z",
|
|
88
|
+
notes: "Measured with baseline none: 0.00%. Added to recommended for readability.",
|
|
89
|
+
},
|
|
84
90
|
"rename-comparison-flags": {
|
|
85
91
|
diffReductionImpact: 0,
|
|
86
92
|
recommended: true,
|
|
@@ -13,6 +13,7 @@ import { renameCatchParametersTransform } from "../rename-catch-parameters/renam
|
|
|
13
13
|
import { renameCharCodeAtTransform } from "../rename-char-code-at/rename-char-code-at-transform.js";
|
|
14
14
|
import { renameCharcodeVariablesTransform } from "../rename-charcode-variables/rename-charcode-variables-transform.js";
|
|
15
15
|
import { renameCharcodeVariablesV2Transform } from "../rename-charcode-variables-v2/rename-charcode-variables-v2-transform.js";
|
|
16
|
+
import { renameClientAliasesTransform } from "../rename-client-aliases/rename-client-aliases-transform.js";
|
|
16
17
|
import { renameComparisonFlagsTransform } from "../rename-comparison-flags/rename-comparison-flags-transform.js";
|
|
17
18
|
import { renameDateNowStartTimesTransform } from "../rename-date-now-start-times/rename-date-now-start-times-transform.js";
|
|
18
19
|
import { renameDefaultOptionsParametersTransform } from "../rename-default-options-parameters/rename-default-options-parameters-transform.js";
|
|
@@ -55,6 +56,7 @@ export const transformRegistry = {
|
|
|
55
56
|
[renameCharCodeAtTransform.id]: renameCharCodeAtTransform,
|
|
56
57
|
[renameCharcodeVariablesTransform.id]: renameCharcodeVariablesTransform,
|
|
57
58
|
[renameCharcodeVariablesV2Transform.id]: renameCharcodeVariablesV2Transform,
|
|
59
|
+
[renameClientAliasesTransform.id]: renameClientAliasesTransform,
|
|
58
60
|
[renameComparisonFlagsTransform.id]: renameComparisonFlagsTransform,
|
|
59
61
|
[renameDateNowStartTimesTransform.id]: renameDateNowStartTimesTransform,
|
|
60
62
|
[renameDefaultOptionsParametersTransform.id]: renameDefaultOptionsParametersTransform,
|
|
@@ -0,0 +1,65 @@
|
|
|
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 BASE_NAME = "client";
|
|
9
|
+
const isClientMemberExpression = (node) => {
|
|
10
|
+
if (node.computed) {
|
|
11
|
+
return ((node.property.type === "StringLiteral" &&
|
|
12
|
+
node.property.value === "client") ||
|
|
13
|
+
(node.property.type === "TemplateLiteral" &&
|
|
14
|
+
node.property.expressions.length === 0 &&
|
|
15
|
+
node.property.quasis[0]?.value.cooked === "client"));
|
|
16
|
+
}
|
|
17
|
+
return node.property.type === "Identifier" && node.property.name === "client";
|
|
18
|
+
};
|
|
19
|
+
export const renameClientAliasesTransform = {
|
|
20
|
+
id: "rename-client-aliases",
|
|
21
|
+
description: "Renames aliases of *.client to $client/$client2/...",
|
|
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
|
+
const group = new RenameGroup();
|
|
29
|
+
const exportedNames = collectExportedNames(fileInfo.ast.program);
|
|
30
|
+
traverse(fileInfo.ast, {
|
|
31
|
+
VariableDeclarator(path) {
|
|
32
|
+
nodesVisited++;
|
|
33
|
+
const id = path.node.id;
|
|
34
|
+
if (id.type !== "Identifier")
|
|
35
|
+
return;
|
|
36
|
+
if (isStableRenamed(id.name))
|
|
37
|
+
return;
|
|
38
|
+
const init = path.node.init;
|
|
39
|
+
if (init?.type !== "MemberExpression")
|
|
40
|
+
return;
|
|
41
|
+
if (!isClientMemberExpression(init))
|
|
42
|
+
return;
|
|
43
|
+
const binding = path.scope.getBinding(id.name);
|
|
44
|
+
if (!binding)
|
|
45
|
+
return;
|
|
46
|
+
if (!binding.constant)
|
|
47
|
+
return;
|
|
48
|
+
if (binding.referencePaths.length === 0)
|
|
49
|
+
return;
|
|
50
|
+
if (binding.scope.block.type === "Program" &&
|
|
51
|
+
exportedNames.has(id.name)) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
group.add({
|
|
55
|
+
scope: binding.scope,
|
|
56
|
+
currentName: id.name,
|
|
57
|
+
baseName: BASE_NAME,
|
|
58
|
+
});
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
transformationsApplied += group.apply();
|
|
62
|
+
}
|
|
63
|
+
return Promise.resolve({ nodesVisited, transformationsApplied });
|
|
64
|
+
},
|
|
65
|
+
};
|
|
@@ -1,78 +1,11 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
|
-
import {
|
|
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
5
|
const require = createRequire(import.meta.url);
|
|
6
6
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
7
7
|
const traverse = require("@babel/traverse").default;
|
|
8
8
|
const BASE_NAME = "thisRef";
|
|
9
|
-
const addBindingNamesFromNode = (node, out) => {
|
|
10
|
-
const babelNode = node;
|
|
11
|
-
if (!babelNode)
|
|
12
|
-
return;
|
|
13
|
-
if (babelNode.type === "VoidPattern")
|
|
14
|
-
return;
|
|
15
|
-
if (isIdentifier(babelNode)) {
|
|
16
|
-
out.add(babelNode.name);
|
|
17
|
-
return;
|
|
18
|
-
}
|
|
19
|
-
if (isObjectPattern(babelNode)) {
|
|
20
|
-
for (const property of babelNode.properties) {
|
|
21
|
-
if (isRestElement(property)) {
|
|
22
|
-
addBindingNamesFromNode(property.argument, out);
|
|
23
|
-
continue;
|
|
24
|
-
}
|
|
25
|
-
if (!isObjectProperty(property))
|
|
26
|
-
continue;
|
|
27
|
-
addBindingNamesFromNode(property.value, out);
|
|
28
|
-
}
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
if (isArrayPattern(babelNode)) {
|
|
32
|
-
for (const element of babelNode.elements) {
|
|
33
|
-
addBindingNamesFromNode(element, out);
|
|
34
|
-
}
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
if (isRestElement(babelNode)) {
|
|
38
|
-
addBindingNamesFromNode(babelNode.argument, out);
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
if (isAssignmentPattern(babelNode)) {
|
|
42
|
-
addBindingNamesFromNode(babelNode.left, out);
|
|
43
|
-
}
|
|
44
|
-
};
|
|
45
|
-
const collectExportedNames = (program) => {
|
|
46
|
-
const exportedNames = new Set();
|
|
47
|
-
for (const statement of program.body) {
|
|
48
|
-
if (!isExportNamedDeclaration(statement))
|
|
49
|
-
continue;
|
|
50
|
-
const declaration = statement.declaration;
|
|
51
|
-
if (declaration) {
|
|
52
|
-
if (isVariableDeclaration(declaration)) {
|
|
53
|
-
for (const declarator of declaration.declarations) {
|
|
54
|
-
addBindingNamesFromNode(declarator.id, exportedNames);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
else if (isFunctionDeclaration(declaration) ||
|
|
58
|
-
isClassDeclaration(declaration)) {
|
|
59
|
-
const id = declaration.id;
|
|
60
|
-
if (!id)
|
|
61
|
-
continue;
|
|
62
|
-
exportedNames.add(id.name);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
for (const specifier of statement.specifiers) {
|
|
66
|
-
if (!isExportSpecifier(specifier))
|
|
67
|
-
continue;
|
|
68
|
-
const local = specifier.local;
|
|
69
|
-
if (!isIdentifier(local))
|
|
70
|
-
continue;
|
|
71
|
-
exportedNames.add(local.name);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
return exportedNames;
|
|
75
|
-
};
|
|
76
9
|
export const renameThisAliasesTransform = {
|
|
77
10
|
id: "rename-this-aliases",
|
|
78
11
|
description: "Renames `var x = this` aliases to $thisRef (stable when unique) or thisRef/thisRef2/...",
|
|
@@ -1,78 +1,11 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
|
-
import {
|
|
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
5
|
const require = createRequire(import.meta.url);
|
|
6
6
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
7
7
|
const traverse = require("@babel/traverse").default;
|
|
8
8
|
const BASE_NAME = "type";
|
|
9
|
-
const addBindingNamesFromNode = (node, out) => {
|
|
10
|
-
const babelNode = node;
|
|
11
|
-
if (!babelNode)
|
|
12
|
-
return;
|
|
13
|
-
if (babelNode.type === "VoidPattern")
|
|
14
|
-
return;
|
|
15
|
-
if (isIdentifier(babelNode)) {
|
|
16
|
-
out.add(babelNode.name);
|
|
17
|
-
return;
|
|
18
|
-
}
|
|
19
|
-
if (isObjectPattern(babelNode)) {
|
|
20
|
-
for (const property of babelNode.properties) {
|
|
21
|
-
if (isRestElement(property)) {
|
|
22
|
-
addBindingNamesFromNode(property.argument, out);
|
|
23
|
-
continue;
|
|
24
|
-
}
|
|
25
|
-
if (!isObjectProperty(property))
|
|
26
|
-
continue;
|
|
27
|
-
addBindingNamesFromNode(property.value, out);
|
|
28
|
-
}
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
if (isArrayPattern(babelNode)) {
|
|
32
|
-
for (const element of babelNode.elements) {
|
|
33
|
-
addBindingNamesFromNode(element, out);
|
|
34
|
-
}
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
if (isRestElement(babelNode)) {
|
|
38
|
-
addBindingNamesFromNode(babelNode.argument, out);
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
if (isAssignmentPattern(babelNode)) {
|
|
42
|
-
addBindingNamesFromNode(babelNode.left, out);
|
|
43
|
-
}
|
|
44
|
-
};
|
|
45
|
-
const collectExportedNames = (program) => {
|
|
46
|
-
const exportedNames = new Set();
|
|
47
|
-
for (const statement of program.body) {
|
|
48
|
-
if (!isExportNamedDeclaration(statement))
|
|
49
|
-
continue;
|
|
50
|
-
const declaration = statement.declaration;
|
|
51
|
-
if (declaration) {
|
|
52
|
-
if (isVariableDeclaration(declaration)) {
|
|
53
|
-
for (const declarator of declaration.declarations) {
|
|
54
|
-
addBindingNamesFromNode(declarator.id, exportedNames);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
else if (isFunctionDeclaration(declaration) ||
|
|
58
|
-
isClassDeclaration(declaration)) {
|
|
59
|
-
const id = declaration.id;
|
|
60
|
-
if (!id)
|
|
61
|
-
continue;
|
|
62
|
-
exportedNames.add(id.name);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
for (const specifier of statement.specifiers) {
|
|
66
|
-
if (!isExportSpecifier(specifier))
|
|
67
|
-
continue;
|
|
68
|
-
const local = specifier.local;
|
|
69
|
-
if (!isIdentifier(local))
|
|
70
|
-
continue;
|
|
71
|
-
exportedNames.add(local.name);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
return exportedNames;
|
|
75
|
-
};
|
|
76
9
|
export const renameTypeofVariablesTransform = {
|
|
77
10
|
id: "rename-typeof-variables",
|
|
78
11
|
description: "Renames variables assigned from typeof expressions to $type (stable when unique) or type/type2/...",
|
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.36.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",
|