miniread 1.3.1 → 1.5.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/expand-sequence-expressions-v4/expand-expression-statement-sequence.d.ts +3 -0
- package/dist/transforms/expand-sequence-expressions-v4/expand-expression-statement-sequence.js +86 -0
- package/dist/transforms/expand-sequence-expressions-v4/expand-return-sequence.d.ts +3 -0
- package/dist/transforms/expand-sequence-expressions-v4/expand-return-sequence.js +91 -0
- package/dist/transforms/expand-sequence-expressions-v4/expand-sequence-expressions-v4-transform.d.ts +2 -0
- package/dist/transforms/expand-sequence-expressions-v4/expand-sequence-expressions-v4-transform.js +48 -0
- package/dist/transforms/expand-sequence-expressions-v4/expand-throw-sequence.d.ts +3 -0
- package/dist/transforms/expand-sequence-expressions-v4/expand-throw-sequence.js +101 -0
- package/dist/transforms/expand-sequence-expressions-v4/expand-variable-declaration-sequence.d.ts +3 -0
- package/dist/transforms/expand-sequence-expressions-v4/expand-variable-declaration-sequence.js +99 -0
- package/dist/transforms/rename-event-parameters/can-rename-binding-safely.d.ts +2 -0
- package/dist/transforms/rename-event-parameters/can-rename-binding-safely.js +28 -0
- package/dist/transforms/rename-event-parameters/event-parameter-usage.d.ts +9 -0
- package/dist/transforms/rename-event-parameters/event-parameter-usage.js +72 -0
- package/dist/transforms/rename-event-parameters/event-property-names.d.ts +3 -0
- package/dist/transforms/rename-event-parameters/event-property-names.js +43 -0
- package/dist/transforms/rename-event-parameters/get-member-expression-for-reference.d.ts +3 -0
- package/dist/transforms/rename-event-parameters/get-member-expression-for-reference.js +10 -0
- package/dist/transforms/rename-event-parameters/get-target-event-name.d.ts +2 -0
- package/dist/transforms/rename-event-parameters/get-target-event-name.js +20 -0
- package/dist/transforms/rename-event-parameters/is-valid-binding-identifier.d.ts +1 -0
- package/dist/transforms/rename-event-parameters/is-valid-binding-identifier.js +10 -0
- package/dist/transforms/rename-event-parameters/process-event-handler-function.d.ts +5 -0
- package/dist/transforms/rename-event-parameters/process-event-handler-function.js +59 -0
- package/dist/transforms/rename-event-parameters/rename-event-parameters-transform.d.ts +2 -0
- package/dist/transforms/rename-event-parameters/rename-event-parameters-transform.js +36 -0
- package/dist/transforms/rename-event-parameters/would-shadow-referenced-outer-binding.d.ts +3 -0
- package/dist/transforms/rename-event-parameters/would-shadow-referenced-outer-binding.js +21 -0
- package/dist/transforms/transform-registry.js +4 -0
- package/package.json +1 -1
- package/transform-manifest.json +22 -3
package/dist/transforms/expand-sequence-expressions-v4/expand-expression-statement-sequence.js
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
const require = createRequire(import.meta.url);
|
|
3
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
4
|
+
const t = require("@babel/types");
|
|
5
|
+
const canReplaceWithMultiple = (path) => path.parentPath.isProgram() ||
|
|
6
|
+
path.parentPath.isBlockStatement() ||
|
|
7
|
+
path.parentPath.isStaticBlock() ||
|
|
8
|
+
path.parentPath.isSwitchCase();
|
|
9
|
+
const canWrapInBlock = (path) => {
|
|
10
|
+
const parentPath = path.parentPath;
|
|
11
|
+
if (parentPath.isIfStatement() &&
|
|
12
|
+
(path.key === "consequent" || path.key === "alternate")) {
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
if ((parentPath.isForStatement() ||
|
|
16
|
+
parentPath.isForInStatement() ||
|
|
17
|
+
parentPath.isForOfStatement() ||
|
|
18
|
+
parentPath.isWhileStatement() ||
|
|
19
|
+
parentPath.isDoWhileStatement() ||
|
|
20
|
+
parentPath.isWithStatement() ||
|
|
21
|
+
parentPath.isLabeledStatement()) &&
|
|
22
|
+
path.key === "body") {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
return false;
|
|
26
|
+
};
|
|
27
|
+
const isDirectiveProloguePosition = (path) => {
|
|
28
|
+
const parentPath = path.parentPath;
|
|
29
|
+
if (parentPath.isBlockStatement()) {
|
|
30
|
+
const grandParent = parentPath.parentPath;
|
|
31
|
+
if (parentPath.key !== "body")
|
|
32
|
+
return false;
|
|
33
|
+
if (!grandParent.isFunction())
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
else if (!parentPath.isProgram()) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
const siblings = parentPath.get("body");
|
|
40
|
+
if (!Array.isArray(siblings))
|
|
41
|
+
return false;
|
|
42
|
+
const index = siblings.findIndex((sibling) => sibling.node === path.node);
|
|
43
|
+
if (index === -1)
|
|
44
|
+
return false;
|
|
45
|
+
for (let bodyIndex = 0; bodyIndex < index; bodyIndex++) {
|
|
46
|
+
const sibling = siblings[bodyIndex];
|
|
47
|
+
if (!sibling)
|
|
48
|
+
return false;
|
|
49
|
+
if (!sibling.isExpressionStatement())
|
|
50
|
+
return false;
|
|
51
|
+
if (sibling.node.expression.type !== "StringLiteral")
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
return true;
|
|
55
|
+
};
|
|
56
|
+
export const tryExpandExpressionStatementSequence = (path) => {
|
|
57
|
+
if (!canReplaceWithMultiple(path) && !canWrapInBlock(path))
|
|
58
|
+
return false;
|
|
59
|
+
const expression = path.node.expression;
|
|
60
|
+
if (expression.type !== "SequenceExpression")
|
|
61
|
+
return false;
|
|
62
|
+
if (expression.expressions.length < 2)
|
|
63
|
+
return false;
|
|
64
|
+
const firstExpression = expression.expressions[0];
|
|
65
|
+
if (firstExpression?.type === "StringLiteral" &&
|
|
66
|
+
canReplaceWithMultiple(path) &&
|
|
67
|
+
isDirectiveProloguePosition(path)) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
const statements = expression.expressions.map((expr) => {
|
|
71
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
72
|
+
return t.expressionStatement(
|
|
73
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
74
|
+
t.cloneNode(expr, true));
|
|
75
|
+
});
|
|
76
|
+
if (canReplaceWithMultiple(path)) {
|
|
77
|
+
path.replaceWithMultiple(statements);
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
if (canWrapInBlock(path)) {
|
|
81
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
82
|
+
path.replaceWith(t.blockStatement(statements));
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
return false;
|
|
86
|
+
};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
const require = createRequire(import.meta.url);
|
|
3
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
4
|
+
const t = require("@babel/types");
|
|
5
|
+
const canReplaceWithMultiple = (path) => {
|
|
6
|
+
return path.parentPath.isBlockStatement() || path.parentPath.isSwitchCase();
|
|
7
|
+
};
|
|
8
|
+
const canWrapInBlock = (path) => {
|
|
9
|
+
const parentPath = path.parentPath;
|
|
10
|
+
if (parentPath.isIfStatement() &&
|
|
11
|
+
(path.key === "consequent" || path.key === "alternate")) {
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
if ((parentPath.isForStatement() ||
|
|
15
|
+
parentPath.isForInStatement() ||
|
|
16
|
+
parentPath.isForOfStatement() ||
|
|
17
|
+
parentPath.isWhileStatement() ||
|
|
18
|
+
parentPath.isDoWhileStatement() ||
|
|
19
|
+
parentPath.isWithStatement() ||
|
|
20
|
+
parentPath.isLabeledStatement()) &&
|
|
21
|
+
path.key === "body") {
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
return false;
|
|
25
|
+
};
|
|
26
|
+
const replaceReturnWithStatements = (path, statements) => {
|
|
27
|
+
if (canReplaceWithMultiple(path)) {
|
|
28
|
+
path.replaceWithMultiple(statements);
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
if (canWrapInBlock(path)) {
|
|
32
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
33
|
+
path.replaceWith(t.blockStatement(statements));
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
return false;
|
|
37
|
+
};
|
|
38
|
+
const isDirectiveProloguePosition = (path) => {
|
|
39
|
+
if (!path.parentPath.isBlockStatement())
|
|
40
|
+
return false;
|
|
41
|
+
if (path.parentPath.key !== "body")
|
|
42
|
+
return false;
|
|
43
|
+
if (!path.parentPath.parentPath.isFunction())
|
|
44
|
+
return false;
|
|
45
|
+
const siblings = path.parentPath.get("body");
|
|
46
|
+
if (!Array.isArray(siblings))
|
|
47
|
+
return false;
|
|
48
|
+
const index = siblings.findIndex((sibling) => sibling.node === path.node);
|
|
49
|
+
if (index === -1)
|
|
50
|
+
return false;
|
|
51
|
+
for (let bodyIndex = 0; bodyIndex < index; bodyIndex++) {
|
|
52
|
+
const sibling = siblings[bodyIndex];
|
|
53
|
+
if (!sibling)
|
|
54
|
+
return false;
|
|
55
|
+
if (!sibling.isExpressionStatement())
|
|
56
|
+
return false;
|
|
57
|
+
if (sibling.node.expression.type !== "StringLiteral")
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
return true;
|
|
61
|
+
};
|
|
62
|
+
export const tryExpandReturnSequence = (path) => {
|
|
63
|
+
if (!canReplaceWithMultiple(path) && !canWrapInBlock(path))
|
|
64
|
+
return false;
|
|
65
|
+
const argument = path.node.argument;
|
|
66
|
+
if (!argument)
|
|
67
|
+
return false;
|
|
68
|
+
if (argument.type !== "SequenceExpression")
|
|
69
|
+
return false;
|
|
70
|
+
if (argument.expressions.length < 2)
|
|
71
|
+
return false;
|
|
72
|
+
const leadingExpressions = argument.expressions.slice(0, -1);
|
|
73
|
+
const lastExpression = argument.expressions.at(-1);
|
|
74
|
+
if (!lastExpression)
|
|
75
|
+
return false;
|
|
76
|
+
const firstExpression = leadingExpressions[0];
|
|
77
|
+
if (firstExpression?.type === "StringLiteral" &&
|
|
78
|
+
isDirectiveProloguePosition(path)) {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
const statements = leadingExpressions.map((expression) => {
|
|
82
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
83
|
+
return t.expressionStatement(
|
|
84
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
85
|
+
t.cloneNode(expression, true));
|
|
86
|
+
});
|
|
87
|
+
statements.push(
|
|
88
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
89
|
+
t.returnStatement(t.cloneNode(lastExpression, true)));
|
|
90
|
+
return replaceReturnWithStatements(path, statements);
|
|
91
|
+
};
|
package/dist/transforms/expand-sequence-expressions-v4/expand-sequence-expressions-v4-transform.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
import { tryExpandExpressionStatementSequence } from "./expand-expression-statement-sequence.js";
|
|
3
|
+
import { tryExpandReturnSequence } from "./expand-return-sequence.js";
|
|
4
|
+
import { tryExpandThrowSequence } from "./expand-throw-sequence.js";
|
|
5
|
+
import { tryExpandVariableDeclarationSequenceInitializers } from "./expand-variable-declaration-sequence.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
|
+
export const expandSequenceExpressionsV4Transform = {
|
|
10
|
+
id: "expand-sequence-expressions-v4",
|
|
11
|
+
description: "Expands comma operator sequences in returns, throws, statements (including control-flow bodies), and variable initializers",
|
|
12
|
+
scope: "file",
|
|
13
|
+
parallelizable: true,
|
|
14
|
+
transform(context) {
|
|
15
|
+
const { projectGraph } = context;
|
|
16
|
+
let nodesVisited = 0;
|
|
17
|
+
let transformationsApplied = 0;
|
|
18
|
+
for (const [, fileInfo] of projectGraph.files) {
|
|
19
|
+
traverse(fileInfo.ast, {
|
|
20
|
+
ReturnStatement(path) {
|
|
21
|
+
nodesVisited++;
|
|
22
|
+
if (!tryExpandReturnSequence(path))
|
|
23
|
+
return;
|
|
24
|
+
transformationsApplied += 1;
|
|
25
|
+
},
|
|
26
|
+
ThrowStatement(path) {
|
|
27
|
+
nodesVisited++;
|
|
28
|
+
if (!tryExpandThrowSequence(path))
|
|
29
|
+
return;
|
|
30
|
+
transformationsApplied += 1;
|
|
31
|
+
},
|
|
32
|
+
ExpressionStatement(path) {
|
|
33
|
+
nodesVisited++;
|
|
34
|
+
if (!tryExpandExpressionStatementSequence(path))
|
|
35
|
+
return;
|
|
36
|
+
transformationsApplied += 1;
|
|
37
|
+
},
|
|
38
|
+
VariableDeclaration(path) {
|
|
39
|
+
nodesVisited++;
|
|
40
|
+
if (!tryExpandVariableDeclarationSequenceInitializers(path))
|
|
41
|
+
return;
|
|
42
|
+
transformationsApplied += 1;
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
return Promise.resolve({ nodesVisited, transformationsApplied });
|
|
47
|
+
},
|
|
48
|
+
};
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
const require = createRequire(import.meta.url);
|
|
3
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
4
|
+
const t = require("@babel/types");
|
|
5
|
+
const canReplaceWithMultiple = (path) => {
|
|
6
|
+
return (path.parentPath.isProgram() ||
|
|
7
|
+
path.parentPath.isBlockStatement() ||
|
|
8
|
+
path.parentPath.isStaticBlock() ||
|
|
9
|
+
path.parentPath.isSwitchCase());
|
|
10
|
+
};
|
|
11
|
+
const canWrapInBlock = (path) => {
|
|
12
|
+
const parentPath = path.parentPath;
|
|
13
|
+
if (parentPath.isIfStatement() &&
|
|
14
|
+
(path.key === "consequent" || path.key === "alternate")) {
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
if ((parentPath.isForStatement() ||
|
|
18
|
+
parentPath.isForInStatement() ||
|
|
19
|
+
parentPath.isForOfStatement() ||
|
|
20
|
+
parentPath.isWhileStatement() ||
|
|
21
|
+
parentPath.isDoWhileStatement() ||
|
|
22
|
+
parentPath.isWithStatement() ||
|
|
23
|
+
parentPath.isLabeledStatement()) &&
|
|
24
|
+
path.key === "body") {
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
return false;
|
|
28
|
+
};
|
|
29
|
+
const replaceThrowWithStatements = (path, statements) => {
|
|
30
|
+
if (canReplaceWithMultiple(path)) {
|
|
31
|
+
path.replaceWithMultiple(statements);
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
if (canWrapInBlock(path)) {
|
|
35
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
36
|
+
path.replaceWith(t.blockStatement(statements));
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
return false;
|
|
40
|
+
};
|
|
41
|
+
const isDirectiveProloguePosition = (path) => {
|
|
42
|
+
const parentPath = path.parentPath;
|
|
43
|
+
if (parentPath.isBlockStatement()) {
|
|
44
|
+
const grandParent = parentPath.parentPath;
|
|
45
|
+
if (parentPath.key !== "body")
|
|
46
|
+
return false;
|
|
47
|
+
if (!grandParent.isFunction())
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
else if (!parentPath.isProgram()) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
const siblings = parentPath.get("body");
|
|
54
|
+
if (!Array.isArray(siblings))
|
|
55
|
+
return false;
|
|
56
|
+
const index = siblings.findIndex((sibling) => sibling.node === path.node);
|
|
57
|
+
if (index === -1)
|
|
58
|
+
return false;
|
|
59
|
+
for (let bodyIndex = 0; bodyIndex < index; bodyIndex++) {
|
|
60
|
+
const sibling = siblings[bodyIndex];
|
|
61
|
+
if (!sibling)
|
|
62
|
+
return false;
|
|
63
|
+
if (!sibling.isExpressionStatement())
|
|
64
|
+
return false;
|
|
65
|
+
if (sibling.node.expression.type !== "StringLiteral")
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
return true;
|
|
69
|
+
};
|
|
70
|
+
export const tryExpandThrowSequence = (path) => {
|
|
71
|
+
if (!canReplaceWithMultiple(path) && !canWrapInBlock(path))
|
|
72
|
+
return false;
|
|
73
|
+
const argument = path.node.argument;
|
|
74
|
+
if (argument.type !== "SequenceExpression")
|
|
75
|
+
return false;
|
|
76
|
+
if (argument.expressions.length < 2)
|
|
77
|
+
return false;
|
|
78
|
+
const leadingExpressions = argument.expressions.slice(0, -1);
|
|
79
|
+
const lastExpression = argument.expressions.at(-1);
|
|
80
|
+
if (!lastExpression)
|
|
81
|
+
return false;
|
|
82
|
+
const firstExpression = leadingExpressions[0];
|
|
83
|
+
const shouldWrapFirstStringLiteral = firstExpression?.type === "StringLiteral" &&
|
|
84
|
+
isDirectiveProloguePosition(path);
|
|
85
|
+
const statements = leadingExpressions.map((expression) => {
|
|
86
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
87
|
+
let clonedExpression = t.cloneNode(expression, true);
|
|
88
|
+
if (shouldWrapFirstStringLiteral && expression === firstExpression) {
|
|
89
|
+
// Prevent inserting a directive prologue statement like `"use strict";`.
|
|
90
|
+
// `("use strict");` is not treated as a directive.
|
|
91
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
92
|
+
clonedExpression = t.parenthesizedExpression(clonedExpression);
|
|
93
|
+
}
|
|
94
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
95
|
+
return t.expressionStatement(clonedExpression);
|
|
96
|
+
});
|
|
97
|
+
statements.push(
|
|
98
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
99
|
+
t.throwStatement(t.cloneNode(lastExpression, true)));
|
|
100
|
+
return replaceThrowWithStatements(path, statements);
|
|
101
|
+
};
|
package/dist/transforms/expand-sequence-expressions-v4/expand-variable-declaration-sequence.js
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
const require = createRequire(import.meta.url);
|
|
3
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
4
|
+
const t = require("@babel/types");
|
|
5
|
+
const createExpressionStatement = (expression) => {
|
|
6
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
7
|
+
return t.expressionStatement(
|
|
8
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
9
|
+
t.cloneNode(expression, true));
|
|
10
|
+
};
|
|
11
|
+
const createVariableDeclarationStatement = (kind, declarator) => {
|
|
12
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
13
|
+
return t.variableDeclaration(kind, [declarator]);
|
|
14
|
+
};
|
|
15
|
+
const createVariableDeclarator = (id, init) => {
|
|
16
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
17
|
+
return t.variableDeclarator(
|
|
18
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
19
|
+
t.cloneNode(id, true), init
|
|
20
|
+
? // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
21
|
+
t.cloneNode(init, true)
|
|
22
|
+
: undefined);
|
|
23
|
+
};
|
|
24
|
+
const isSupportedStatementContainer = (path) => {
|
|
25
|
+
const parentPath = path.parentPath;
|
|
26
|
+
if (!parentPath)
|
|
27
|
+
return false;
|
|
28
|
+
return (parentPath.isProgram() ||
|
|
29
|
+
parentPath.isBlockStatement() ||
|
|
30
|
+
parentPath.isStaticBlock() ||
|
|
31
|
+
parentPath.isSwitchCase());
|
|
32
|
+
};
|
|
33
|
+
const isDirectiveProloguePosition = (path) => {
|
|
34
|
+
const parentPath = path.parentPath;
|
|
35
|
+
if (!parentPath)
|
|
36
|
+
return false;
|
|
37
|
+
if (parentPath.isBlockStatement()) {
|
|
38
|
+
const grandParent = parentPath.parentPath;
|
|
39
|
+
if (parentPath.key !== "body")
|
|
40
|
+
return false;
|
|
41
|
+
if (!grandParent.isFunction())
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
else if (!parentPath.isProgram()) {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
const siblings = parentPath.get("body");
|
|
48
|
+
if (!Array.isArray(siblings))
|
|
49
|
+
return false;
|
|
50
|
+
const index = siblings.findIndex((sibling) => sibling.node === path.node);
|
|
51
|
+
if (index === -1)
|
|
52
|
+
return false;
|
|
53
|
+
for (let bodyIndex = 0; bodyIndex < index; bodyIndex++) {
|
|
54
|
+
const sibling = siblings[bodyIndex];
|
|
55
|
+
if (!sibling)
|
|
56
|
+
return false;
|
|
57
|
+
if (!sibling.isExpressionStatement())
|
|
58
|
+
return false;
|
|
59
|
+
if (sibling.node.expression.type !== "StringLiteral")
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
return true;
|
|
63
|
+
};
|
|
64
|
+
export const tryExpandVariableDeclarationSequenceInitializers = (path) => {
|
|
65
|
+
if (!isSupportedStatementContainer(path))
|
|
66
|
+
return false;
|
|
67
|
+
if (isDirectiveProloguePosition(path)) {
|
|
68
|
+
const wouldInsertStringLiteral = path.node.declarations.some((declarator) => declarator.init?.type === "SequenceExpression" &&
|
|
69
|
+
declarator.init.expressions[0]?.type === "StringLiteral");
|
|
70
|
+
if (wouldInsertStringLiteral)
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
const hasAnySequence = path.node.declarations.some((declarator) => declarator.init?.type === "SequenceExpression" &&
|
|
74
|
+
declarator.init.expressions.length >= 2);
|
|
75
|
+
if (!hasAnySequence)
|
|
76
|
+
return false;
|
|
77
|
+
const kind = path.node.kind;
|
|
78
|
+
const statements = [];
|
|
79
|
+
for (const declarator of path.node.declarations) {
|
|
80
|
+
const init = declarator.init;
|
|
81
|
+
if (init?.type !== "SequenceExpression") {
|
|
82
|
+
statements.push(createVariableDeclarationStatement(kind, declarator));
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
const leadingExpressions = init.expressions.slice(0, -1);
|
|
86
|
+
const lastExpression = init.expressions.at(-1);
|
|
87
|
+
if (!lastExpression) {
|
|
88
|
+
statements.push(createVariableDeclarationStatement(kind, declarator));
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
for (const expression of leadingExpressions) {
|
|
92
|
+
statements.push(createExpressionStatement(expression));
|
|
93
|
+
}
|
|
94
|
+
const newDeclarator = createVariableDeclarator(declarator.id, lastExpression);
|
|
95
|
+
statements.push(createVariableDeclarationStatement(kind, newDeclarator));
|
|
96
|
+
}
|
|
97
|
+
path.replaceWithMultiple(statements);
|
|
98
|
+
return true;
|
|
99
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { isValidBindingIdentifier } from "./is-valid-binding-identifier.js";
|
|
2
|
+
const hasShadowingRisk = (binding, bindingScope, targetName) => binding.referencePaths.some((referencePath) => {
|
|
3
|
+
if (referencePath.scope === bindingScope)
|
|
4
|
+
return false;
|
|
5
|
+
// Only consider bindings between this reference’s scope and the binding scope.
|
|
6
|
+
// This avoids incorrectly blocking safe renames due to unrelated outer bindings.
|
|
7
|
+
const hasBindingOptions = {
|
|
8
|
+
noGlobals: true,
|
|
9
|
+
noUids: true,
|
|
10
|
+
// Present in Babel scope implementation, but missing from our TypeScript types.
|
|
11
|
+
upToScope: bindingScope,
|
|
12
|
+
};
|
|
13
|
+
return referencePath.scope.hasBinding(targetName, hasBindingOptions);
|
|
14
|
+
});
|
|
15
|
+
export const canRenameBindingSafely = (bindingScope, fromName, toName) => {
|
|
16
|
+
if (fromName === toName)
|
|
17
|
+
return false;
|
|
18
|
+
if (!isValidBindingIdentifier(toName))
|
|
19
|
+
return false;
|
|
20
|
+
if (bindingScope.hasOwnBinding(toName))
|
|
21
|
+
return false;
|
|
22
|
+
const binding = bindingScope.getBinding(fromName);
|
|
23
|
+
if (!binding)
|
|
24
|
+
return false;
|
|
25
|
+
if (hasShadowingRisk(binding, bindingScope, toName))
|
|
26
|
+
return false;
|
|
27
|
+
return true;
|
|
28
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Binding } from "@babel/traverse";
|
|
2
|
+
export type EventParameterUsage = {
|
|
3
|
+
isSafe: boolean;
|
|
4
|
+
propertyNames: Set<string>;
|
|
5
|
+
calledMethods: Set<string>;
|
|
6
|
+
hasNonMemberUsage: boolean;
|
|
7
|
+
};
|
|
8
|
+
export declare const getEventParameterUsage: (binding: Binding) => EventParameterUsage;
|
|
9
|
+
export declare const isHighConfidenceEventParameter: (usage: EventParameterUsage) => boolean;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { allowedEventPropertyNames } from "./event-property-names.js";
|
|
2
|
+
import { getMemberExpressionForReference } from "./get-member-expression-for-reference.js";
|
|
3
|
+
const isUnsafeNonMemberReference = (referencePath) => {
|
|
4
|
+
const parentPath = referencePath.parentPath;
|
|
5
|
+
if ((parentPath.isCallExpression() || parentPath.isOptionalCallExpression()) &&
|
|
6
|
+
referencePath.key === "callee")
|
|
7
|
+
return true;
|
|
8
|
+
if (parentPath.isNewExpression() && referencePath.key === "callee")
|
|
9
|
+
return true;
|
|
10
|
+
if (parentPath.isTaggedTemplateExpression() && referencePath.key === "tag")
|
|
11
|
+
return true;
|
|
12
|
+
if (parentPath.isMemberExpression() && referencePath.key === "property")
|
|
13
|
+
return true;
|
|
14
|
+
if (parentPath.isOptionalMemberExpression() &&
|
|
15
|
+
referencePath.key === "property")
|
|
16
|
+
return true;
|
|
17
|
+
if (parentPath.isUpdateExpression())
|
|
18
|
+
return true;
|
|
19
|
+
if (parentPath.isUnaryExpression() &&
|
|
20
|
+
parentPath.node.operator === "delete" &&
|
|
21
|
+
referencePath.key === "argument")
|
|
22
|
+
return true;
|
|
23
|
+
if (parentPath.isAssignmentExpression() && referencePath.key === "left")
|
|
24
|
+
return true;
|
|
25
|
+
return false;
|
|
26
|
+
};
|
|
27
|
+
export const getEventParameterUsage = (binding) => {
|
|
28
|
+
const propertyNames = new Set();
|
|
29
|
+
const calledMethods = new Set();
|
|
30
|
+
let hasNonMemberUsage = false;
|
|
31
|
+
for (const referencePath of binding.referencePaths) {
|
|
32
|
+
if (!referencePath.isIdentifier())
|
|
33
|
+
return { isSafe: false, propertyNames, calledMethods, hasNonMemberUsage };
|
|
34
|
+
const memberPath = getMemberExpressionForReference(referencePath);
|
|
35
|
+
if (!memberPath) {
|
|
36
|
+
hasNonMemberUsage = true;
|
|
37
|
+
if (isUnsafeNonMemberReference(referencePath)) {
|
|
38
|
+
return {
|
|
39
|
+
isSafe: false,
|
|
40
|
+
propertyNames,
|
|
41
|
+
calledMethods,
|
|
42
|
+
hasNonMemberUsage,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
if (memberPath.node.computed)
|
|
48
|
+
return { isSafe: false, propertyNames, calledMethods, hasNonMemberUsage };
|
|
49
|
+
if (memberPath.node.property.type !== "Identifier")
|
|
50
|
+
return { isSafe: false, propertyNames, calledMethods, hasNonMemberUsage };
|
|
51
|
+
const propertyName = memberPath.node.property.name;
|
|
52
|
+
if (!allowedEventPropertyNames.has(propertyName))
|
|
53
|
+
return { isSafe: false, propertyNames, calledMethods, hasNonMemberUsage };
|
|
54
|
+
propertyNames.add(propertyName);
|
|
55
|
+
const parentPath = memberPath.parentPath;
|
|
56
|
+
if ((parentPath.isCallExpression() ||
|
|
57
|
+
parentPath.isOptionalCallExpression()) &&
|
|
58
|
+
parentPath.node.callee === memberPath.node) {
|
|
59
|
+
calledMethods.add(propertyName);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return { isSafe: true, propertyNames, calledMethods, hasNonMemberUsage };
|
|
63
|
+
};
|
|
64
|
+
export const isHighConfidenceEventParameter = (usage) => {
|
|
65
|
+
if (!usage.isSafe)
|
|
66
|
+
return false;
|
|
67
|
+
if (usage.propertyNames.size === 0)
|
|
68
|
+
return false;
|
|
69
|
+
return (usage.calledMethods.has("preventDefault") ||
|
|
70
|
+
usage.calledMethods.has("stopPropagation") ||
|
|
71
|
+
usage.calledMethods.has("stopImmediatePropagation"));
|
|
72
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export const allowedEventPropertyNames = new Set([
|
|
2
|
+
// Strong signals
|
|
3
|
+
"preventDefault",
|
|
4
|
+
"stopPropagation",
|
|
5
|
+
"stopImmediatePropagation",
|
|
6
|
+
// Common event properties
|
|
7
|
+
"target",
|
|
8
|
+
"currentTarget",
|
|
9
|
+
"nativeEvent",
|
|
10
|
+
"type",
|
|
11
|
+
"defaultPrevented",
|
|
12
|
+
"timeStamp",
|
|
13
|
+
// Common UIEvent / MouseEvent properties
|
|
14
|
+
"clientX",
|
|
15
|
+
"clientY",
|
|
16
|
+
"pageX",
|
|
17
|
+
"pageY",
|
|
18
|
+
"screenX",
|
|
19
|
+
"screenY",
|
|
20
|
+
"button",
|
|
21
|
+
"buttons",
|
|
22
|
+
// KeyboardEvent properties
|
|
23
|
+
"key",
|
|
24
|
+
"code",
|
|
25
|
+
"keyCode",
|
|
26
|
+
"which",
|
|
27
|
+
// Modifier keys
|
|
28
|
+
"altKey",
|
|
29
|
+
"ctrlKey",
|
|
30
|
+
"metaKey",
|
|
31
|
+
"shiftKey",
|
|
32
|
+
]);
|
|
33
|
+
export const mouseEventPropertyNames = new Set([
|
|
34
|
+
"clientX",
|
|
35
|
+
"clientY",
|
|
36
|
+
"pageX",
|
|
37
|
+
"pageY",
|
|
38
|
+
"screenX",
|
|
39
|
+
"screenY",
|
|
40
|
+
"button",
|
|
41
|
+
"buttons",
|
|
42
|
+
]);
|
|
43
|
+
export const keyboardEventPropertyNames = new Set(["key", "code", "keyCode"]);
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { NodePath } from "@babel/traverse";
|
|
2
|
+
import type { Identifier, MemberExpression, OptionalMemberExpression } from "@babel/types";
|
|
3
|
+
export declare const getMemberExpressionForReference: (referencePath: NodePath<Identifier>) => NodePath<MemberExpression | OptionalMemberExpression> | undefined;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export const getMemberExpressionForReference = (referencePath) => {
|
|
2
|
+
const parentPath = referencePath.parentPath;
|
|
3
|
+
if (parentPath.isMemberExpression() &&
|
|
4
|
+
parentPath.node.object === referencePath.node)
|
|
5
|
+
return parentPath;
|
|
6
|
+
if (parentPath.isOptionalMemberExpression() &&
|
|
7
|
+
parentPath.node.object === referencePath.node)
|
|
8
|
+
return parentPath;
|
|
9
|
+
return;
|
|
10
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { keyboardEventPropertyNames, mouseEventPropertyNames, } from "./event-property-names.js";
|
|
2
|
+
export const getTargetEventName = (usage) => {
|
|
3
|
+
let hasMouseProperty = false;
|
|
4
|
+
let hasKeyboardProperty = false;
|
|
5
|
+
for (const name of usage.propertyNames) {
|
|
6
|
+
if (!hasMouseProperty && mouseEventPropertyNames.has(name)) {
|
|
7
|
+
hasMouseProperty = true;
|
|
8
|
+
}
|
|
9
|
+
if (!hasKeyboardProperty && keyboardEventPropertyNames.has(name)) {
|
|
10
|
+
hasKeyboardProperty = true;
|
|
11
|
+
}
|
|
12
|
+
if (hasMouseProperty && hasKeyboardProperty)
|
|
13
|
+
break;
|
|
14
|
+
}
|
|
15
|
+
if (hasKeyboardProperty && !hasMouseProperty)
|
|
16
|
+
return "keyboardEvent";
|
|
17
|
+
if (hasMouseProperty && !hasKeyboardProperty)
|
|
18
|
+
return "mouseEvent";
|
|
19
|
+
return "event";
|
|
20
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const isValidBindingIdentifier: (name: string) => boolean;
|
|
@@ -0,0 +1,10 @@
|
|
|
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
|
+
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { NodePath } from "@babel/traverse";
|
|
2
|
+
import type { ArrowFunctionExpression, FunctionDeclaration, FunctionExpression } from "@babel/types";
|
|
3
|
+
export declare const processEventHandlerFunction: (path: NodePath<FunctionDeclaration | FunctionExpression | ArrowFunctionExpression>, stats: {
|
|
4
|
+
transformationsApplied: number;
|
|
5
|
+
}) => void;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { getEventParameterUsage, isHighConfidenceEventParameter, } from "./event-parameter-usage.js";
|
|
2
|
+
import { getTargetEventName } from "./get-target-event-name.js";
|
|
3
|
+
import { canRenameBindingSafely } from "./can-rename-binding-safely.js";
|
|
4
|
+
import { wouldShadowReferencedOuterBinding } from "./would-shadow-referenced-outer-binding.js";
|
|
5
|
+
const wouldShadowReferencedImplicitGlobal = (functionPath, targetName) => {
|
|
6
|
+
const programScope = functionPath.scope.getProgramParent();
|
|
7
|
+
if (!Object.hasOwn(programScope.globals, targetName))
|
|
8
|
+
return false;
|
|
9
|
+
let foundReference = false;
|
|
10
|
+
functionPath.traverse({
|
|
11
|
+
Identifier(identifierPath) {
|
|
12
|
+
if (foundReference)
|
|
13
|
+
return;
|
|
14
|
+
if (identifierPath.node.name !== targetName)
|
|
15
|
+
return;
|
|
16
|
+
if (!identifierPath.isReferencedIdentifier())
|
|
17
|
+
return;
|
|
18
|
+
if (identifierPath.scope.getBinding(targetName))
|
|
19
|
+
return;
|
|
20
|
+
foundReference = true;
|
|
21
|
+
identifierPath.stop();
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
return foundReference;
|
|
25
|
+
};
|
|
26
|
+
export const processEventHandlerFunction = (path, stats) => {
|
|
27
|
+
const parameters = path.node.params;
|
|
28
|
+
if (parameters.length !== 1)
|
|
29
|
+
return;
|
|
30
|
+
const parameter = parameters[0];
|
|
31
|
+
if (!parameter)
|
|
32
|
+
return;
|
|
33
|
+
if (parameter.type !== "Identifier")
|
|
34
|
+
return;
|
|
35
|
+
// 1-2 character parameter names are a strong minification signal (e.g. `e`, `t`, `WA`).
|
|
36
|
+
// Keeping this conservative avoids renaming common intentional abbreviations (e.g. `evt`).
|
|
37
|
+
if (parameter.name.length > 2)
|
|
38
|
+
return;
|
|
39
|
+
const bindingScope = path.scope;
|
|
40
|
+
const binding = bindingScope.getBinding(parameter.name);
|
|
41
|
+
if (!binding)
|
|
42
|
+
return;
|
|
43
|
+
if (!binding.constant)
|
|
44
|
+
return;
|
|
45
|
+
const usage = getEventParameterUsage(binding);
|
|
46
|
+
if (!isHighConfidenceEventParameter(usage))
|
|
47
|
+
return;
|
|
48
|
+
const targetName = getTargetEventName(usage);
|
|
49
|
+
if (parameter.name === targetName)
|
|
50
|
+
return;
|
|
51
|
+
if (wouldShadowReferencedImplicitGlobal(path, targetName))
|
|
52
|
+
return;
|
|
53
|
+
if (wouldShadowReferencedOuterBinding(path, targetName))
|
|
54
|
+
return;
|
|
55
|
+
if (!canRenameBindingSafely(bindingScope, parameter.name, targetName))
|
|
56
|
+
return;
|
|
57
|
+
bindingScope.rename(parameter.name, targetName);
|
|
58
|
+
stats.transformationsApplied++;
|
|
59
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
import { processEventHandlerFunction } from "./process-event-handler-function.js";
|
|
3
|
+
const require = createRequire(import.meta.url);
|
|
4
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
5
|
+
const traverse = require("@babel/traverse").default;
|
|
6
|
+
export const renameEventParametersTransform = {
|
|
7
|
+
id: "rename-event-parameters",
|
|
8
|
+
description: "Renames minified single-parameter event handlers to event/mouseEvent/keyboardEvent when usage is high-confidence",
|
|
9
|
+
scope: "file",
|
|
10
|
+
parallelizable: true,
|
|
11
|
+
transform(context) {
|
|
12
|
+
const { projectGraph } = context;
|
|
13
|
+
let nodesVisited = 0;
|
|
14
|
+
const stats = { transformationsApplied: 0 };
|
|
15
|
+
for (const [, fileInfo] of projectGraph.files) {
|
|
16
|
+
traverse(fileInfo.ast, {
|
|
17
|
+
FunctionDeclaration(path) {
|
|
18
|
+
nodesVisited++;
|
|
19
|
+
processEventHandlerFunction(path, stats);
|
|
20
|
+
},
|
|
21
|
+
FunctionExpression(path) {
|
|
22
|
+
nodesVisited++;
|
|
23
|
+
processEventHandlerFunction(path, stats);
|
|
24
|
+
},
|
|
25
|
+
ArrowFunctionExpression(path) {
|
|
26
|
+
nodesVisited++;
|
|
27
|
+
processEventHandlerFunction(path, stats);
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
return Promise.resolve({
|
|
32
|
+
nodesVisited,
|
|
33
|
+
transformationsApplied: stats.transformationsApplied,
|
|
34
|
+
});
|
|
35
|
+
},
|
|
36
|
+
};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { NodePath } from "@babel/traverse";
|
|
2
|
+
import type { ArrowFunctionExpression, FunctionDeclaration, FunctionExpression } from "@babel/types";
|
|
3
|
+
export declare const wouldShadowReferencedOuterBinding: (functionPath: NodePath<FunctionDeclaration | FunctionExpression | ArrowFunctionExpression>, targetName: string) => boolean;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export const wouldShadowReferencedOuterBinding = (functionPath, targetName) => {
|
|
2
|
+
const outerBinding = functionPath.scope.getBinding(targetName);
|
|
3
|
+
if (!outerBinding)
|
|
4
|
+
return false;
|
|
5
|
+
let foundReference = false;
|
|
6
|
+
functionPath.traverse({
|
|
7
|
+
Identifier(identifierPath) {
|
|
8
|
+
if (foundReference)
|
|
9
|
+
return;
|
|
10
|
+
if (identifierPath.node.name !== targetName)
|
|
11
|
+
return;
|
|
12
|
+
if (!identifierPath.isReferencedIdentifier())
|
|
13
|
+
return;
|
|
14
|
+
if (identifierPath.scope.getBinding(targetName) !== outerBinding)
|
|
15
|
+
return;
|
|
16
|
+
foundReference = true;
|
|
17
|
+
identifierPath.stop();
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
return foundReference;
|
|
21
|
+
};
|
|
@@ -4,10 +4,12 @@ import { expandSequenceExpressionsTransform } from "./expand-sequence-expression
|
|
|
4
4
|
import { expandSequenceExpressionsV2Transform } from "./expand-sequence-expressions-v2/expand-sequence-expressions-v2-transform.js";
|
|
5
5
|
import { expandSpecialNumberLiteralsTransform } from "./expand-special-number-literals/expand-special-number-literals-transform.js";
|
|
6
6
|
import { expandSequenceExpressionsV3Transform } from "./expand-sequence-expressions-v3/expand-sequence-expressions-v3-transform.js";
|
|
7
|
+
import { expandSequenceExpressionsV4Transform } from "./expand-sequence-expressions-v4/expand-sequence-expressions-v4-transform.js";
|
|
7
8
|
import { expandThrowSequenceTransform } from "./expand-throw-sequence/expand-throw-sequence-transform.js";
|
|
8
9
|
import { expandUndefinedLiteralsTransform } from "./expand-undefined-literals/expand-undefined-literals-transform.js";
|
|
9
10
|
import { renameCatchParametersTransform } from "./rename-catch-parameters/rename-catch-parameters-transform.js";
|
|
10
11
|
import { renameDestructuredAliasesTransform } from "./rename-destructured-aliases/rename-destructured-aliases-transform.js";
|
|
12
|
+
import { renameEventParametersTransform } from "./rename-event-parameters/rename-event-parameters-transform.js";
|
|
11
13
|
import { renameLoopIndexVariablesTransform } from "./rename-loop-index-variables/rename-loop-index-variables-transform.js";
|
|
12
14
|
import { renamePromiseExecutorParametersTransform } from "./rename-promise-executor-parameters/rename-promise-executor-parameters-transform.js";
|
|
13
15
|
import { renameTimeoutIdsTransform } from "./rename-timeout-ids/rename-timeout-ids-transform.js";
|
|
@@ -20,10 +22,12 @@ export const transformRegistry = {
|
|
|
20
22
|
[expandSequenceExpressionsV2Transform.id]: expandSequenceExpressionsV2Transform,
|
|
21
23
|
[expandSequenceExpressionsV3Transform.id]: expandSequenceExpressionsV3Transform,
|
|
22
24
|
[expandSpecialNumberLiteralsTransform.id]: expandSpecialNumberLiteralsTransform,
|
|
25
|
+
[expandSequenceExpressionsV4Transform.id]: expandSequenceExpressionsV4Transform,
|
|
23
26
|
[expandThrowSequenceTransform.id]: expandThrowSequenceTransform,
|
|
24
27
|
[expandUndefinedLiteralsTransform.id]: expandUndefinedLiteralsTransform,
|
|
25
28
|
[renameCatchParametersTransform.id]: renameCatchParametersTransform,
|
|
26
29
|
[renameDestructuredAliasesTransform.id]: renameDestructuredAliasesTransform,
|
|
30
|
+
[renameEventParametersTransform.id]: renameEventParametersTransform,
|
|
27
31
|
[renameLoopIndexVariablesTransform.id]: renameLoopIndexVariablesTransform,
|
|
28
32
|
[renamePromiseExecutorParametersTransform.id]: renamePromiseExecutorParametersTransform,
|
|
29
33
|
[renameTimeoutIdsTransform.id]: renameTimeoutIdsTransform,
|
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.5.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",
|
package/transform-manifest.json
CHANGED
|
@@ -40,6 +40,15 @@
|
|
|
40
40
|
"evaluatedAt": "2026-01-23T07:48:59.087Z",
|
|
41
41
|
"notes": "Auto-added by evaluation script."
|
|
42
42
|
},
|
|
43
|
+
{
|
|
44
|
+
"id": "rename-event-parameters",
|
|
45
|
+
"description": "Renames minified single-parameter event handlers to event/mouseEvent/keyboardEvent when usage is high-confidence",
|
|
46
|
+
"scope": "file",
|
|
47
|
+
"parallelizable": true,
|
|
48
|
+
"diffReductionImpact": 0,
|
|
49
|
+
"recommended": true,
|
|
50
|
+
"notes": "Added manually; recommended based on high-confidence heuristics (not yet evaluated)."
|
|
51
|
+
},
|
|
43
52
|
{
|
|
44
53
|
"id": "rename-destructured-aliases",
|
|
45
54
|
"description": "Renames destructuring aliases to match property names (e.g., { foo: x } → { foo })",
|
|
@@ -86,10 +95,20 @@
|
|
|
86
95
|
"scope": "file",
|
|
87
96
|
"parallelizable": true,
|
|
88
97
|
"diffReductionImpact": -0.014391951831788763,
|
|
89
|
-
"recommended":
|
|
98
|
+
"recommended": false,
|
|
90
99
|
"evaluatedAt": "2026-01-23T08:21:23.662Z",
|
|
91
100
|
"notes": "Supersedes expand-sequence-expressions-v2 in the recommended preset. Measured with baseline none: -1.44%. Enabled for readability even when line diffs increase."
|
|
92
101
|
},
|
|
102
|
+
{
|
|
103
|
+
"id": "expand-sequence-expressions-v4",
|
|
104
|
+
"description": "Expands comma operator sequences in returns, throws, statements (including control-flow bodies), and variable initializers",
|
|
105
|
+
"scope": "file",
|
|
106
|
+
"parallelizable": true,
|
|
107
|
+
"diffReductionImpact": -0.01730809158000035,
|
|
108
|
+
"recommended": true,
|
|
109
|
+
"evaluatedAt": "2026-01-23T10:57:45.082Z",
|
|
110
|
+
"notes": "Measured with baseline none: -1.73%. Supersedes expand-sequence-expressions-v3 and includes control-flow-body expansion."
|
|
111
|
+
},
|
|
93
112
|
{
|
|
94
113
|
"id": "rename-use-reference-guards",
|
|
95
114
|
"description": "Renames boolean useRef(false) guard variables to hasRunRef/hasRunRef2/...",
|
|
@@ -153,8 +172,8 @@
|
|
|
153
172
|
],
|
|
154
173
|
"presetStats": {
|
|
155
174
|
"recommended": {
|
|
156
|
-
"diffReductionImpact": 0.
|
|
157
|
-
"notes": "Measured with baseline none: 0.
|
|
175
|
+
"diffReductionImpact": 0.0027273928389422997,
|
|
176
|
+
"notes": "Measured with baseline none: 0.27%."
|
|
158
177
|
}
|
|
159
178
|
}
|
|
160
179
|
}
|