miniread 1.26.0 → 1.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/transforms/_generated/manifest.js +12 -0
- package/dist/transforms/_generated/registry.js +4 -0
- package/dist/transforms/rename-regex-builders/is-regex-builder-object.d.ts +3 -0
- package/dist/transforms/rename-regex-builders/is-regex-builder-object.js +113 -0
- package/dist/transforms/rename-regex-builders/manifest.json +6 -0
- package/dist/transforms/rename-regex-builders/rename-regex-builders-transform.d.ts +2 -0
- package/dist/transforms/rename-regex-builders/rename-regex-builders-transform.js +51 -0
- package/dist/transforms/use-object-shorthand/manifest.json +6 -0
- package/dist/transforms/use-object-shorthand/use-object-shorthand-transform.d.ts +2 -0
- package/dist/transforms/use-object-shorthand/use-object-shorthand-transform.js +48 -0
- package/package.json +1 -1
|
@@ -130,6 +130,12 @@ const manifestData = {
|
|
|
130
130
|
evaluatedAt: "2026-01-22T21:39:53.578Z",
|
|
131
131
|
notes: "Auto-added by evaluation script.",
|
|
132
132
|
},
|
|
133
|
+
"rename-regex-builders": {
|
|
134
|
+
diffReductionImpact: 0,
|
|
135
|
+
recommended: true,
|
|
136
|
+
evaluatedAt: "2026-01-24T15:54:39.303Z",
|
|
137
|
+
notes: "Measured with baseline none: 0.00%. Added to recommended for readability.",
|
|
138
|
+
},
|
|
133
139
|
"rename-replace-child-parameters": {
|
|
134
140
|
diffReductionImpact: 0,
|
|
135
141
|
recommended: false,
|
|
@@ -185,6 +191,12 @@ const manifestData = {
|
|
|
185
191
|
evaluatedAt: "2026-01-23T05:45:27.981Z",
|
|
186
192
|
notes: "Auto-added by evaluation script. Measured with baseline none: -0.28%. Enabled in the recommended preset for readability and to normalize variable declarations even when line diffs increase.",
|
|
187
193
|
},
|
|
194
|
+
"use-object-shorthand": {
|
|
195
|
+
diffReductionImpact: 0,
|
|
196
|
+
recommended: true,
|
|
197
|
+
evaluatedAt: "2026-01-24T12:08:16.000Z",
|
|
198
|
+
notes: "Improves readability by using object shorthand for stable-renamed identifiers; no diff reduction impact expected.",
|
|
199
|
+
},
|
|
188
200
|
};
|
|
189
201
|
export const manifestEntries = Object.entries(transformRegistry)
|
|
190
202
|
.map(([id, transform]) => {
|
|
@@ -21,6 +21,7 @@ import { renameLoopLengthVariablesTransform } from "../rename-loop-length-variab
|
|
|
21
21
|
import { renameParametersToMatchPropertiesTransform } from "../rename-parameters-to-match-properties/rename-parameters-to-match-properties-transform.js";
|
|
22
22
|
import { renameParametersToMatchPropertiesV2Transform } from "../rename-parameters-to-match-properties-v2/rename-parameters-to-match-properties-v2-transform.js";
|
|
23
23
|
import { renamePromiseExecutorParametersTransform } from "../rename-promise-executor-parameters/rename-promise-executor-parameters-transform.js";
|
|
24
|
+
import { renameRegexBuildersTransform } from "../rename-regex-builders/rename-regex-builders-transform.js";
|
|
24
25
|
import { renameReplaceChildParametersTransform } from "../rename-replace-child-parameters/rename-replace-child-parameters-transform.js";
|
|
25
26
|
import { renameRestParametersTransform } from "../rename-rest-parameters/rename-rest-parameters-transform.js";
|
|
26
27
|
import { renameThisAliasesTransform } from "../rename-this-aliases/rename-this-aliases-transform.js";
|
|
@@ -31,6 +32,7 @@ import { renameUseReferenceGuardsTransform } from "../rename-use-reference-guard
|
|
|
31
32
|
import { renameUseReferenceGuardsV2Transform } from "../rename-use-reference-guards-v2/rename-use-reference-guards-v2-transform.js";
|
|
32
33
|
import { simplifyBooleanNegationsTransform } from "../simplify-boolean-negations/simplify-boolean-negations-transform.js";
|
|
33
34
|
import { splitVariableDeclarationsTransform } from "../split-variable-declarations/split-variable-declarations-transform.js";
|
|
35
|
+
import { useObjectShorthandTransform } from "../use-object-shorthand/use-object-shorthand-transform.js";
|
|
34
36
|
export const transformRegistry = {
|
|
35
37
|
[expandBooleanLiteralsTransform.id]: expandBooleanLiteralsTransform,
|
|
36
38
|
[expandSequenceExpressionsV4Transform.id]: expandSequenceExpressionsV4Transform,
|
|
@@ -53,6 +55,7 @@ export const transformRegistry = {
|
|
|
53
55
|
[renameParametersToMatchPropertiesTransform.id]: renameParametersToMatchPropertiesTransform,
|
|
54
56
|
[renameParametersToMatchPropertiesV2Transform.id]: renameParametersToMatchPropertiesV2Transform,
|
|
55
57
|
[renamePromiseExecutorParametersTransform.id]: renamePromiseExecutorParametersTransform,
|
|
58
|
+
[renameRegexBuildersTransform.id]: renameRegexBuildersTransform,
|
|
56
59
|
[renameReplaceChildParametersTransform.id]: renameReplaceChildParametersTransform,
|
|
57
60
|
[renameRestParametersTransform.id]: renameRestParametersTransform,
|
|
58
61
|
[renameThisAliasesTransform.id]: renameThisAliasesTransform,
|
|
@@ -63,5 +66,6 @@ export const transformRegistry = {
|
|
|
63
66
|
[renameUseReferenceGuardsV2Transform.id]: renameUseReferenceGuardsV2Transform,
|
|
64
67
|
[simplifyBooleanNegationsTransform.id]: simplifyBooleanNegationsTransform,
|
|
65
68
|
[splitVariableDeclarationsTransform.id]: splitVariableDeclarationsTransform,
|
|
69
|
+
[useObjectShorthandTransform.id]: useObjectShorthandTransform,
|
|
66
70
|
};
|
|
67
71
|
export const allTransformIds = Object.keys(transformRegistry);
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
const getSequenceTail = (expressionPath) => {
|
|
2
|
+
let tailPath = expressionPath;
|
|
3
|
+
while (tailPath.isSequenceExpression()) {
|
|
4
|
+
const expressions = tailPath.get("expressions");
|
|
5
|
+
const lastExpression = expressions.at(-1);
|
|
6
|
+
if (!lastExpression)
|
|
7
|
+
break;
|
|
8
|
+
tailPath = lastExpression;
|
|
9
|
+
}
|
|
10
|
+
return tailPath;
|
|
11
|
+
};
|
|
12
|
+
const isPropertyNamed = (property, name) => {
|
|
13
|
+
if (property.key.type === "Identifier") {
|
|
14
|
+
return !property.computed && property.key.name === name;
|
|
15
|
+
}
|
|
16
|
+
if (property.key.type === "StringLiteral") {
|
|
17
|
+
return property.key.value === name;
|
|
18
|
+
}
|
|
19
|
+
return false;
|
|
20
|
+
};
|
|
21
|
+
const getPropertyFunctionPath = (objectExpressionPath, name) => {
|
|
22
|
+
const propertyPaths = objectExpressionPath.get("properties");
|
|
23
|
+
for (const propertyPath of propertyPaths) {
|
|
24
|
+
if (propertyPath.isSpreadElement())
|
|
25
|
+
continue;
|
|
26
|
+
if (propertyPath.isObjectMethod()) {
|
|
27
|
+
if (propertyPath.node.kind !== "method")
|
|
28
|
+
continue;
|
|
29
|
+
if (isPropertyNamed(propertyPath.node, name)) {
|
|
30
|
+
return propertyPath;
|
|
31
|
+
}
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (!propertyPath.isObjectProperty())
|
|
35
|
+
continue;
|
|
36
|
+
if (!isPropertyNamed(propertyPath.node, name))
|
|
37
|
+
continue;
|
|
38
|
+
const valuePath = propertyPath.get("value");
|
|
39
|
+
if (valuePath.isFunctionExpression() ||
|
|
40
|
+
valuePath.isArrowFunctionExpression()) {
|
|
41
|
+
return valuePath;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return undefined;
|
|
45
|
+
};
|
|
46
|
+
const returnsIdentifierBinding = (functionPath, identifierName, expectedBinding) => {
|
|
47
|
+
const bodyPath = functionPath.get("body");
|
|
48
|
+
const implicitReturnPath = getSequenceTail(bodyPath);
|
|
49
|
+
if (implicitReturnPath.isIdentifier({ name: identifierName })) {
|
|
50
|
+
return (implicitReturnPath.scope.getBinding(identifierName) === expectedBinding);
|
|
51
|
+
}
|
|
52
|
+
let found = false;
|
|
53
|
+
bodyPath.traverse({
|
|
54
|
+
Function(innerFunctionPath) {
|
|
55
|
+
innerFunctionPath.skip();
|
|
56
|
+
},
|
|
57
|
+
ReturnStatement(returnPath) {
|
|
58
|
+
const argumentPath = returnPath.get("argument");
|
|
59
|
+
if (!argumentPath.node)
|
|
60
|
+
return;
|
|
61
|
+
const returnValuePath = getSequenceTail(argumentPath);
|
|
62
|
+
if (!returnValuePath.isIdentifier({ name: identifierName }))
|
|
63
|
+
return;
|
|
64
|
+
if (returnValuePath.scope.getBinding(identifierName) !== expectedBinding)
|
|
65
|
+
return;
|
|
66
|
+
found = true;
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
return found;
|
|
70
|
+
};
|
|
71
|
+
const returnsNewRegExpGlobal = (functionPath) => {
|
|
72
|
+
const bodyPath = functionPath.get("body");
|
|
73
|
+
const implicitReturnPath = getSequenceTail(bodyPath);
|
|
74
|
+
if (implicitReturnPath.isNewExpression()) {
|
|
75
|
+
const calleePath = implicitReturnPath.get("callee");
|
|
76
|
+
return (calleePath.isIdentifier({ name: "RegExp" }) &&
|
|
77
|
+
!calleePath.scope.getBinding("RegExp"));
|
|
78
|
+
}
|
|
79
|
+
let found = false;
|
|
80
|
+
bodyPath.traverse({
|
|
81
|
+
Function(innerFunctionPath) {
|
|
82
|
+
innerFunctionPath.skip();
|
|
83
|
+
},
|
|
84
|
+
ReturnStatement(returnPath) {
|
|
85
|
+
const argumentPath = returnPath.get("argument");
|
|
86
|
+
if (!argumentPath.node)
|
|
87
|
+
return;
|
|
88
|
+
const returnValuePath = getSequenceTail(argumentPath);
|
|
89
|
+
if (!returnValuePath.isNewExpression())
|
|
90
|
+
return;
|
|
91
|
+
const calleePath = returnValuePath.get("callee");
|
|
92
|
+
if (!calleePath.isIdentifier({ name: "RegExp" }))
|
|
93
|
+
return;
|
|
94
|
+
if (calleePath.scope.getBinding("RegExp"))
|
|
95
|
+
return;
|
|
96
|
+
found = true;
|
|
97
|
+
},
|
|
98
|
+
});
|
|
99
|
+
return found;
|
|
100
|
+
};
|
|
101
|
+
export const isRegexBuilderObject = (objectExpressionPath, bindingName, binding) => {
|
|
102
|
+
const replaceFunction = getPropertyFunctionPath(objectExpressionPath, "replace");
|
|
103
|
+
if (!replaceFunction)
|
|
104
|
+
return false;
|
|
105
|
+
if (!returnsIdentifierBinding(replaceFunction, bindingName, binding))
|
|
106
|
+
return false;
|
|
107
|
+
const getRegexFunction = getPropertyFunctionPath(objectExpressionPath, "getRegex");
|
|
108
|
+
if (!getRegexFunction)
|
|
109
|
+
return false;
|
|
110
|
+
if (!returnsNewRegExpGlobal(getRegexFunction))
|
|
111
|
+
return false;
|
|
112
|
+
return true;
|
|
113
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
import { isStableRenamed, RenameGroup } from "../../core/stable-naming.js";
|
|
3
|
+
import { getFilesToProcess, } from "../../core/types.js";
|
|
4
|
+
import * as t from "@babel/types";
|
|
5
|
+
import { isRegexBuilderObject } from "./is-regex-builder-object.js";
|
|
6
|
+
const require = createRequire(import.meta.url);
|
|
7
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
8
|
+
const traverse = require("@babel/traverse").default;
|
|
9
|
+
const BASE_NAME = "regexBuilder";
|
|
10
|
+
export const renameRegexBuildersTransform = {
|
|
11
|
+
id: "rename-regex-builders",
|
|
12
|
+
description: "Renames fluent regex builder objects to $regexBuilder/$regexBuilder2 when they expose replace() and getRegex().",
|
|
13
|
+
scope: "file",
|
|
14
|
+
parallelizable: true,
|
|
15
|
+
transform(context) {
|
|
16
|
+
let nodesVisited = 0;
|
|
17
|
+
let transformationsApplied = 0;
|
|
18
|
+
for (const fileInfo of getFilesToProcess(context)) {
|
|
19
|
+
const group = new RenameGroup();
|
|
20
|
+
traverse(fileInfo.ast, {
|
|
21
|
+
VariableDeclarator(path) {
|
|
22
|
+
nodesVisited++;
|
|
23
|
+
const id = path.node.id;
|
|
24
|
+
if (!t.isIdentifier(id))
|
|
25
|
+
return;
|
|
26
|
+
if (isStableRenamed(id.name))
|
|
27
|
+
return;
|
|
28
|
+
const binding = path.scope.getBinding(id.name);
|
|
29
|
+
if (!binding)
|
|
30
|
+
return;
|
|
31
|
+
if (!binding.constant)
|
|
32
|
+
return;
|
|
33
|
+
const initPath = path.get("init");
|
|
34
|
+
if (!initPath.isObjectExpression())
|
|
35
|
+
return;
|
|
36
|
+
if (!isRegexBuilderObject(initPath, id.name, binding))
|
|
37
|
+
return;
|
|
38
|
+
if (path.scope.hasBinding("RegExp", true))
|
|
39
|
+
return;
|
|
40
|
+
group.add({
|
|
41
|
+
scope: path.scope,
|
|
42
|
+
currentName: id.name,
|
|
43
|
+
baseName: BASE_NAME,
|
|
44
|
+
});
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
transformationsApplied += group.apply();
|
|
48
|
+
}
|
|
49
|
+
return Promise.resolve({ nodesVisited, transformationsApplied });
|
|
50
|
+
},
|
|
51
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
import { isIdentifier } from "@babel/types";
|
|
3
|
+
import { 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 isShorthandCandidate = (path) => {
|
|
9
|
+
if (path.node.shorthand)
|
|
10
|
+
return false;
|
|
11
|
+
if (path.node.computed)
|
|
12
|
+
return false;
|
|
13
|
+
if (!path.parentPath.isObjectExpression() &&
|
|
14
|
+
!path.parentPath.isObjectPattern()) {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
if (!isIdentifier(path.node.key))
|
|
18
|
+
return false;
|
|
19
|
+
if (path.node.key.name === "__proto__")
|
|
20
|
+
return false;
|
|
21
|
+
if (!isIdentifier(path.node.value))
|
|
22
|
+
return false;
|
|
23
|
+
if (!isStableRenamed(path.node.value.name))
|
|
24
|
+
return false;
|
|
25
|
+
return path.node.key.name === path.node.value.name;
|
|
26
|
+
};
|
|
27
|
+
export const useObjectShorthandTransform = {
|
|
28
|
+
id: "use-object-shorthand",
|
|
29
|
+
description: "Use object property shorthand for stable-renamed identifiers with matching keys",
|
|
30
|
+
scope: "file",
|
|
31
|
+
parallelizable: true,
|
|
32
|
+
transform(context) {
|
|
33
|
+
let nodesVisited = 0;
|
|
34
|
+
let transformationsApplied = 0;
|
|
35
|
+
for (const fileInfo of getFilesToProcess(context)) {
|
|
36
|
+
traverse(fileInfo.ast, {
|
|
37
|
+
ObjectProperty(path) {
|
|
38
|
+
nodesVisited++;
|
|
39
|
+
if (!isShorthandCandidate(path))
|
|
40
|
+
return;
|
|
41
|
+
path.node.shorthand = true;
|
|
42
|
+
transformationsApplied++;
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
return Promise.resolve({ nodesVisited, transformationsApplied });
|
|
47
|
+
},
|
|
48
|
+
};
|
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.27.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",
|