expose-kit 0.11.0 → 0.12.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/README.md +38 -0
- package/dist/index.js +280 -68
- package/dist/package.json +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -358,6 +358,44 @@ Notes:
|
|
|
358
358
|
|
|
359
359
|
---
|
|
360
360
|
|
|
361
|
+
### `expose control-flow-packer`
|
|
362
|
+
|
|
363
|
+
Inline control-flow flattening loops generated by string-based state machines.
|
|
364
|
+
```js
|
|
365
|
+
const _0x1 = "a|b|c".split("|");
|
|
366
|
+
let _0x2 = 0;
|
|
367
|
+
|
|
368
|
+
while (true) {
|
|
369
|
+
switch (_0x1[_0x2++]) {
|
|
370
|
+
case "a":
|
|
371
|
+
console.log("a");
|
|
372
|
+
continue;
|
|
373
|
+
case "b":
|
|
374
|
+
console.log("b");
|
|
375
|
+
continue;
|
|
376
|
+
case "c":
|
|
377
|
+
console.log("c");
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
break;
|
|
381
|
+
}
|
|
382
|
+
```
|
|
383
|
+
Example is [here](https://github.com/evex-dev/expose-kit/tree/main/commands/control-flow-packer/mocks).
|
|
384
|
+
|
|
385
|
+
```bash
|
|
386
|
+
expose control-flow-packer path/to/file.js --output path/to/file.control-flow-packer.js
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
Args:
|
|
390
|
+
- `--o, --output <file>`
|
|
391
|
+
Output file path
|
|
392
|
+
|
|
393
|
+
Notes:
|
|
394
|
+
- Only flattens loops whose state array comes from a literal `split`.
|
|
395
|
+
- Stops when a branch returns or a state token is missing.
|
|
396
|
+
|
|
397
|
+
---
|
|
398
|
+
|
|
361
399
|
### `expose fn-inliner`
|
|
362
400
|
|
|
363
401
|
Inline proxy function calls into expressions.
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
// index.ts
|
|
4
4
|
import { Command } from "commander";
|
|
5
|
-
import { dirname as
|
|
5
|
+
import { dirname as dirname13, join as join13 } from "path";
|
|
6
6
|
import { fileURLToPath } from "url";
|
|
7
7
|
import chalk4 from "chalk";
|
|
8
8
|
|
|
@@ -1941,7 +1941,7 @@ var remove_deadcode_default = createCommand((program3) => {
|
|
|
1941
1941
|
);
|
|
1942
1942
|
});
|
|
1943
1943
|
|
|
1944
|
-
// commands/
|
|
1944
|
+
// commands/control-flow-packer/index.ts
|
|
1945
1945
|
import { readFileSync as readFileSync11, writeFileSync as writeFileSync10 } from "fs";
|
|
1946
1946
|
import { basename as basename10, dirname as dirname10, extname as extname10, join as join10 } from "path";
|
|
1947
1947
|
import { parse as parse11 } from "@babel/parser";
|
|
@@ -1953,24 +1953,235 @@ var walk2 = patchDefault(traverse10);
|
|
|
1953
1953
|
var createDefaultOutputPath10 = (inputPath) => {
|
|
1954
1954
|
const ext = extname10(inputPath);
|
|
1955
1955
|
if (!ext) {
|
|
1956
|
-
return `${inputPath}.
|
|
1956
|
+
return `${inputPath}.control-flow-packer.js`;
|
|
1957
1957
|
}
|
|
1958
1958
|
const base = basename10(inputPath, ext);
|
|
1959
|
-
return join10(dirname10(inputPath), `${base}.
|
|
1959
|
+
return join10(dirname10(inputPath), `${base}.control-flow-packer${ext}`);
|
|
1960
|
+
};
|
|
1961
|
+
var isDeclarationOrAssignmentExpression = (node) => {
|
|
1962
|
+
if (t9.isAssignmentExpression(node)) {
|
|
1963
|
+
return t9.isIdentifier(node.left) && t9.isNumericLiteral(node.right);
|
|
1964
|
+
}
|
|
1965
|
+
if (t9.isVariableDeclaration(node) && node.declarations.length === 1 && t9.isIdentifier(node.declarations[0].id) && node.declarations[0].init && t9.isNumericLiteral(node.declarations[0].init)) {
|
|
1966
|
+
return true;
|
|
1967
|
+
}
|
|
1968
|
+
return false;
|
|
1969
|
+
};
|
|
1970
|
+
var extractCounterInfo = (node) => {
|
|
1971
|
+
if (t9.isAssignmentExpression(node)) {
|
|
1972
|
+
return {
|
|
1973
|
+
counterName: node.left.name,
|
|
1974
|
+
initialValue: node.right.value
|
|
1975
|
+
};
|
|
1976
|
+
}
|
|
1977
|
+
const declaration = node.declarations[0];
|
|
1978
|
+
return {
|
|
1979
|
+
counterName: declaration.id.name,
|
|
1980
|
+
initialValue: declaration.init.value
|
|
1981
|
+
};
|
|
1982
|
+
};
|
|
1983
|
+
var isStateArrayExpression = (node) => {
|
|
1984
|
+
return t9.isCallExpression(node) && t9.isMemberExpression(node.callee) && t9.isStringLiteral(node.callee.object) && (t9.isStringLiteral(node.callee.property) && node.callee.property.value === "split" || t9.isIdentifier(node.callee.property) && node.callee.property.name === "split") && node.arguments.length === 1 && t9.isStringLiteral(node.arguments[0]);
|
|
1985
|
+
};
|
|
1986
|
+
var isFlatteningLoopBody = (node, statesName, counterName) => {
|
|
1987
|
+
return t9.isBlockStatement(node) && node.body.length === 2 && t9.isBreakStatement(node.body[1]) && t9.isSwitchStatement(node.body[0]) && t9.isMemberExpression(node.body[0].discriminant) && t9.isIdentifier(node.body[0].discriminant.object) && node.body[0].discriminant.object.name === statesName && t9.isUpdateExpression(node.body[0].discriminant.property) && t9.isIdentifier(node.body[0].discriminant.property.argument) && node.body[0].discriminant.property.argument.name === counterName && node.body[0].cases.every(
|
|
1988
|
+
(c) => c.test && t9.isStringLiteral(c.test)
|
|
1989
|
+
);
|
|
1990
|
+
};
|
|
1991
|
+
var isFlatteningForLoop = (node, statesName) => {
|
|
1992
|
+
return t9.isForStatement(node) && node.init !== null && isDeclarationOrAssignmentExpression(node.init) && isFlatteningLoopBody(
|
|
1993
|
+
node.body,
|
|
1994
|
+
statesName,
|
|
1995
|
+
t9.isAssignmentExpression(node.init) ? node.init.left.name : node.init.declarations[0].id.name
|
|
1996
|
+
);
|
|
1997
|
+
};
|
|
1998
|
+
var isFlatteningWhileLoop = (node, statesName, counterName) => {
|
|
1999
|
+
return t9.isWhileStatement(node) && t9.isBooleanLiteral(node.test) && node.test.value === true && isFlatteningLoopBody(node.body, statesName, counterName);
|
|
2000
|
+
};
|
|
2001
|
+
var getStates = (expression) => {
|
|
2002
|
+
const delimiter = expression.arguments[0].value;
|
|
2003
|
+
return expression.callee.object.value.split(delimiter);
|
|
2004
|
+
};
|
|
2005
|
+
var collectStatements = (cases, states, initialValue) => {
|
|
2006
|
+
const casesMap = new Map(
|
|
2007
|
+
cases.map((c) => [c.test.value, c.consequent])
|
|
2008
|
+
);
|
|
2009
|
+
const statements = [];
|
|
2010
|
+
for (let index = initialValue; index < states.length; index++) {
|
|
2011
|
+
const state = states[index];
|
|
2012
|
+
if (state === void 0 || !casesMap.has(state)) {
|
|
2013
|
+
break;
|
|
2014
|
+
}
|
|
2015
|
+
const blockStatements = casesMap.get(state);
|
|
2016
|
+
for (const statement of blockStatements) {
|
|
2017
|
+
if (t9.isContinueStatement(statement)) {
|
|
2018
|
+
continue;
|
|
2019
|
+
}
|
|
2020
|
+
statements.push(t9.cloneNode(statement, true));
|
|
2021
|
+
}
|
|
2022
|
+
const lastStatement = blockStatements[blockStatements.length - 1];
|
|
2023
|
+
if (lastStatement && t9.isReturnStatement(lastStatement)) {
|
|
2024
|
+
break;
|
|
2025
|
+
}
|
|
2026
|
+
}
|
|
2027
|
+
return statements;
|
|
2028
|
+
};
|
|
2029
|
+
var packControlFlow = (code, filename) => {
|
|
2030
|
+
const ast = parse11(code, createParseOptions(filename));
|
|
2031
|
+
let changedCount = 0;
|
|
2032
|
+
walk2(ast, {
|
|
2033
|
+
VariableDeclarator(path) {
|
|
2034
|
+
if (!path.node.init || !t9.isIdentifier(path.node.id)) {
|
|
2035
|
+
return;
|
|
2036
|
+
}
|
|
2037
|
+
if (!isStateArrayExpression(path.node.init)) {
|
|
2038
|
+
return;
|
|
2039
|
+
}
|
|
2040
|
+
const statementPath = path.getStatementParent();
|
|
2041
|
+
if (!statementPath?.isVariableDeclaration()) {
|
|
2042
|
+
return;
|
|
2043
|
+
}
|
|
2044
|
+
if (statementPath.node.declarations.length !== 1) {
|
|
2045
|
+
return;
|
|
2046
|
+
}
|
|
2047
|
+
const stateVariableName = path.node.id.name;
|
|
2048
|
+
const states = getStates(path.node.init);
|
|
2049
|
+
let nextPath = statementPath.getNextSibling();
|
|
2050
|
+
if (!nextPath) {
|
|
2051
|
+
return;
|
|
2052
|
+
}
|
|
2053
|
+
let loopPath = null;
|
|
2054
|
+
let initialValue = null;
|
|
2055
|
+
let counterName;
|
|
2056
|
+
if (nextPath.isForStatement() && isFlatteningForLoop(nextPath.node, stateVariableName)) {
|
|
2057
|
+
loopPath = nextPath;
|
|
2058
|
+
const initNode = nextPath.node.init;
|
|
2059
|
+
if (!initNode || !isDeclarationOrAssignmentExpression(initNode)) {
|
|
2060
|
+
return;
|
|
2061
|
+
}
|
|
2062
|
+
const counterInfo = extractCounterInfo(initNode);
|
|
2063
|
+
initialValue = counterInfo.initialValue;
|
|
2064
|
+
counterName = counterInfo.counterName;
|
|
2065
|
+
} else if (isDeclarationOrAssignmentExpression(nextPath.node)) {
|
|
2066
|
+
const counterInfo = extractCounterInfo(
|
|
2067
|
+
nextPath.node
|
|
2068
|
+
);
|
|
2069
|
+
counterName = counterInfo.counterName;
|
|
2070
|
+
initialValue = counterInfo.initialValue;
|
|
2071
|
+
nextPath = nextPath.getNextSibling();
|
|
2072
|
+
if (!nextPath || !nextPath.isWhileStatement()) {
|
|
2073
|
+
return;
|
|
2074
|
+
}
|
|
2075
|
+
if (!isFlatteningWhileLoop(
|
|
2076
|
+
nextPath.node,
|
|
2077
|
+
stateVariableName,
|
|
2078
|
+
counterName
|
|
2079
|
+
)) {
|
|
2080
|
+
return;
|
|
2081
|
+
}
|
|
2082
|
+
loopPath = nextPath;
|
|
2083
|
+
} else {
|
|
2084
|
+
return;
|
|
2085
|
+
}
|
|
2086
|
+
if (!loopPath || initialValue === null || counterName === void 0) {
|
|
2087
|
+
return;
|
|
2088
|
+
}
|
|
2089
|
+
const body = loopPath.node.body;
|
|
2090
|
+
const cases = body.body[0].cases;
|
|
2091
|
+
const statements = collectStatements(cases, states, initialValue);
|
|
2092
|
+
if (statements.length === 0) {
|
|
2093
|
+
return;
|
|
2094
|
+
}
|
|
2095
|
+
statementPath.remove();
|
|
2096
|
+
loopPath.replaceWithMultiple(statements);
|
|
2097
|
+
loopPath.skip();
|
|
2098
|
+
changedCount += 1;
|
|
2099
|
+
}
|
|
2100
|
+
});
|
|
2101
|
+
return {
|
|
2102
|
+
code: patchDefault(generate10)(ast).code,
|
|
2103
|
+
changedCount
|
|
2104
|
+
};
|
|
2105
|
+
};
|
|
2106
|
+
var control_flow_packer_default = createCommand((program3) => {
|
|
2107
|
+
program3.command("control-flow-packer").description("Inline control-flow flattening loops").argument("[file]", "The file to transform").option("--input, --file <file>", "The file to transform").option("--o, --output <file>", "Output file path").option("--unlimited", "Unlimited timeout").action(
|
|
2108
|
+
async (fileArgument, options) => {
|
|
2109
|
+
await timeout(
|
|
2110
|
+
async ({ finish }) => {
|
|
2111
|
+
const filename = fileArgument ?? options.file ?? await createPrompt("Enter the file path:");
|
|
2112
|
+
if (!filename) {
|
|
2113
|
+
showError("No file provided");
|
|
2114
|
+
return finish();
|
|
2115
|
+
}
|
|
2116
|
+
try {
|
|
2117
|
+
const fileContent = readFileSync11(filename, "utf8");
|
|
2118
|
+
const defaultOutputPath = createDefaultOutputPath10(filename);
|
|
2119
|
+
let outputPath = options.output;
|
|
2120
|
+
if (!outputPath) {
|
|
2121
|
+
const promptPath = (await createPrompt("Enter the output file path:"))?.trim();
|
|
2122
|
+
outputPath = promptPath || defaultOutputPath;
|
|
2123
|
+
}
|
|
2124
|
+
const loader = loading11("Packing control flow...").start();
|
|
2125
|
+
try {
|
|
2126
|
+
const { code: output, changedCount } = packControlFlow(
|
|
2127
|
+
fileContent,
|
|
2128
|
+
filename
|
|
2129
|
+
);
|
|
2130
|
+
writeFileSync10(outputPath, output, "utf8");
|
|
2131
|
+
loader.succeed(
|
|
2132
|
+
`Saved control-flow-packer file to: ${outputPath} (${diff(fileContent, output).length} lines changed, ${changedCount} edits)`
|
|
2133
|
+
);
|
|
2134
|
+
return finish();
|
|
2135
|
+
} catch (error) {
|
|
2136
|
+
loader.fail("Failed to apply control-flow-packer transform");
|
|
2137
|
+
showError(
|
|
2138
|
+
`Error transforming file '${filename}': ${error instanceof Error ? error.message : "Unknown error"}`
|
|
2139
|
+
);
|
|
2140
|
+
return finish();
|
|
2141
|
+
}
|
|
2142
|
+
} catch (error) {
|
|
2143
|
+
showError(
|
|
2144
|
+
`Error reading file '${filename}': ${error instanceof Error ? error.message : "Unknown error"}`
|
|
2145
|
+
);
|
|
2146
|
+
return finish();
|
|
2147
|
+
}
|
|
2148
|
+
},
|
|
2149
|
+
options.unlimited ? null : 120 * 1e3
|
|
2150
|
+
);
|
|
2151
|
+
}
|
|
2152
|
+
);
|
|
2153
|
+
});
|
|
2154
|
+
|
|
2155
|
+
// commands/fn-inliner/index.ts
|
|
2156
|
+
import { readFileSync as readFileSync12, writeFileSync as writeFileSync11 } from "fs";
|
|
2157
|
+
import { basename as basename11, dirname as dirname11, extname as extname11, join as join11 } from "path";
|
|
2158
|
+
import { parse as parse12 } from "@babel/parser";
|
|
2159
|
+
import traverse11 from "@babel/traverse";
|
|
2160
|
+
import generate11 from "@babel/generator";
|
|
2161
|
+
import * as t10 from "@babel/types";
|
|
2162
|
+
import loading12 from "loading-cli";
|
|
2163
|
+
var walk3 = patchDefault(traverse11);
|
|
2164
|
+
var createDefaultOutputPath11 = (inputPath) => {
|
|
2165
|
+
const ext = extname11(inputPath);
|
|
2166
|
+
if (!ext) {
|
|
2167
|
+
return `${inputPath}.fn-inliner.js`;
|
|
2168
|
+
}
|
|
2169
|
+
const base = basename11(inputPath, ext);
|
|
2170
|
+
return join11(dirname11(inputPath), `${base}.fn-inliner${ext}`);
|
|
1960
2171
|
};
|
|
1961
2172
|
var isProxyFunctionExpression = (node) => {
|
|
1962
|
-
return
|
|
2173
|
+
return t10.isFunction(node) && node.params.every((param) => t10.isIdentifier(param)) && (t10.isBlockStatement(node.body) && node.body.body.length === 1 && t10.isReturnStatement(node.body.body[0]) && (node.body.body[0].argument === void 0 || t10.isExpression(node.body.body[0].argument) && isProxyValue(node.body.body[0].argument)) || t10.isArrowFunctionExpression(node) && t10.isExpression(node.body) && isProxyValue(node.body));
|
|
1963
2174
|
};
|
|
1964
2175
|
var isProxyValue = (node) => {
|
|
1965
|
-
if (
|
|
2176
|
+
if (t10.isFunction(node) || t10.isBlockStatement(node) || t10.isSequenceExpression(node) || t10.isAssignmentExpression(node)) {
|
|
1966
2177
|
return false;
|
|
1967
2178
|
}
|
|
1968
2179
|
let isValid = true;
|
|
1969
|
-
if (!
|
|
2180
|
+
if (!t10.isExpression(node)) {
|
|
1970
2181
|
return false;
|
|
1971
2182
|
}
|
|
1972
|
-
const wrapper =
|
|
1973
|
-
|
|
2183
|
+
const wrapper = t10.file(t10.program([t10.expressionStatement(node)]));
|
|
2184
|
+
walk3(wrapper, {
|
|
1974
2185
|
"SequenceExpression|BlockStatement|Function|AssignmentExpression"(path) {
|
|
1975
2186
|
isValid = false;
|
|
1976
2187
|
path.stop();
|
|
@@ -1980,7 +2191,7 @@ var isProxyValue = (node) => {
|
|
|
1980
2191
|
return isValid;
|
|
1981
2192
|
};
|
|
1982
2193
|
var copyExpression = (expression) => {
|
|
1983
|
-
return
|
|
2194
|
+
return t10.cloneNode(expression, true);
|
|
1984
2195
|
};
|
|
1985
2196
|
var ProxyFunction = class {
|
|
1986
2197
|
expression;
|
|
@@ -1988,7 +2199,7 @@ var ProxyFunction = class {
|
|
|
1988
2199
|
this.expression = expression;
|
|
1989
2200
|
}
|
|
1990
2201
|
getReplacement(args) {
|
|
1991
|
-
const expression =
|
|
2202
|
+
const expression = t10.isExpression(this.expression.body) ? copyExpression(this.expression.body) : this.expression.body.body[0].argument ? copyExpression(this.expression.body.body[0].argument) : t10.identifier("undefined");
|
|
1992
2203
|
this.replaceParameters(expression, args);
|
|
1993
2204
|
return expression;
|
|
1994
2205
|
}
|
|
@@ -1996,7 +2207,7 @@ var ProxyFunction = class {
|
|
|
1996
2207
|
const paramMap = new Map(
|
|
1997
2208
|
this.expression.params.map((param, index) => [
|
|
1998
2209
|
param.name,
|
|
1999
|
-
args[index] ??
|
|
2210
|
+
args[index] ?? t10.identifier("undefined")
|
|
2000
2211
|
])
|
|
2001
2212
|
);
|
|
2002
2213
|
const pathsToReplace = [];
|
|
@@ -2021,10 +2232,10 @@ var ProxyFunction = class {
|
|
|
2021
2232
|
}
|
|
2022
2233
|
return false;
|
|
2023
2234
|
};
|
|
2024
|
-
const wrapper =
|
|
2025
|
-
|
|
2235
|
+
const wrapper = t10.file(t10.program([t10.expressionStatement(expression)]));
|
|
2236
|
+
walk3(wrapper, {
|
|
2026
2237
|
enter(path) {
|
|
2027
|
-
if (
|
|
2238
|
+
if (t10.isIdentifier(path.node) && !shouldSkipIdentifier(path) && paramMap.has(path.node.name)) {
|
|
2028
2239
|
const replacement = paramMap.get(path.node.name);
|
|
2029
2240
|
pathsToReplace.push([path, replacement]);
|
|
2030
2241
|
}
|
|
@@ -2032,7 +2243,7 @@ var ProxyFunction = class {
|
|
|
2032
2243
|
noScope: true
|
|
2033
2244
|
});
|
|
2034
2245
|
for (const [path, replacement] of pathsToReplace) {
|
|
2035
|
-
path.replaceWith(
|
|
2246
|
+
path.replaceWith(t10.cloneNode(replacement, true));
|
|
2036
2247
|
}
|
|
2037
2248
|
}
|
|
2038
2249
|
};
|
|
@@ -2052,10 +2263,10 @@ var ProxyFunctionVariable = class extends ProxyFunction {
|
|
|
2052
2263
|
const argumentNodes = path.parentPath.node.arguments;
|
|
2053
2264
|
const args = [];
|
|
2054
2265
|
for (const argument of argumentNodes) {
|
|
2055
|
-
if (!
|
|
2266
|
+
if (!t10.isExpression(argument)) {
|
|
2056
2267
|
return false;
|
|
2057
2268
|
}
|
|
2058
|
-
args.push(
|
|
2269
|
+
args.push(t10.cloneNode(argument, true));
|
|
2059
2270
|
}
|
|
2060
2271
|
const expression = this.getReplacement(args);
|
|
2061
2272
|
path.parentPath.replaceWith(expression);
|
|
@@ -2064,7 +2275,7 @@ var ProxyFunctionVariable = class extends ProxyFunction {
|
|
|
2064
2275
|
};
|
|
2065
2276
|
var collectProxyFunctions = (ast) => {
|
|
2066
2277
|
const proxies = [];
|
|
2067
|
-
|
|
2278
|
+
walk3(ast, {
|
|
2068
2279
|
FunctionDeclaration(path) {
|
|
2069
2280
|
if (!path.node.id) return;
|
|
2070
2281
|
if (!isProxyFunctionExpression(path.node)) return;
|
|
@@ -2073,7 +2284,7 @@ var collectProxyFunctions = (ast) => {
|
|
|
2073
2284
|
proxies.push(new ProxyFunctionVariable(binding, path.node));
|
|
2074
2285
|
},
|
|
2075
2286
|
VariableDeclarator(path) {
|
|
2076
|
-
if (!
|
|
2287
|
+
if (!t10.isIdentifier(path.node.id)) return;
|
|
2077
2288
|
const init = path.node.init;
|
|
2078
2289
|
if (!init || !isProxyFunctionExpression(init)) return;
|
|
2079
2290
|
const binding = path.scope.getBinding(path.node.id.name);
|
|
@@ -2084,7 +2295,7 @@ var collectProxyFunctions = (ast) => {
|
|
|
2084
2295
|
return proxies;
|
|
2085
2296
|
};
|
|
2086
2297
|
var inlineProxyFunctions = (code, filename) => {
|
|
2087
|
-
const ast =
|
|
2298
|
+
const ast = parse12(code, createParseOptions(filename));
|
|
2088
2299
|
const proxies = collectProxyFunctions(ast);
|
|
2089
2300
|
let replacedCount = 0;
|
|
2090
2301
|
for (const proxy of proxies) {
|
|
@@ -2096,7 +2307,7 @@ var inlineProxyFunctions = (code, filename) => {
|
|
|
2096
2307
|
}
|
|
2097
2308
|
}
|
|
2098
2309
|
return {
|
|
2099
|
-
code: patchDefault(
|
|
2310
|
+
code: patchDefault(generate11)(ast).code,
|
|
2100
2311
|
replacedCount
|
|
2101
2312
|
};
|
|
2102
2313
|
};
|
|
@@ -2111,20 +2322,20 @@ var fn_inliner_default = createCommand((program3) => {
|
|
|
2111
2322
|
return finish();
|
|
2112
2323
|
}
|
|
2113
2324
|
try {
|
|
2114
|
-
const fileContent =
|
|
2115
|
-
const defaultOutputPath =
|
|
2325
|
+
const fileContent = readFileSync12(filename, "utf8");
|
|
2326
|
+
const defaultOutputPath = createDefaultOutputPath11(filename);
|
|
2116
2327
|
let outputPath = options.output;
|
|
2117
2328
|
if (!outputPath) {
|
|
2118
2329
|
const promptPath = (await createPrompt("Enter the output file path:"))?.trim();
|
|
2119
2330
|
outputPath = promptPath || defaultOutputPath;
|
|
2120
2331
|
}
|
|
2121
|
-
const loader =
|
|
2332
|
+
const loader = loading12("Inlining proxy functions...").start();
|
|
2122
2333
|
try {
|
|
2123
2334
|
const { code: output, replacedCount } = inlineProxyFunctions(
|
|
2124
2335
|
fileContent,
|
|
2125
2336
|
filename
|
|
2126
2337
|
);
|
|
2127
|
-
|
|
2338
|
+
writeFileSync11(outputPath, output, "utf8");
|
|
2128
2339
|
loader.succeed(
|
|
2129
2340
|
`Saved fn-inliner file to: ${outputPath} (${diff(fileContent, output).length} lines changed, ${replacedCount} replacements)`
|
|
2130
2341
|
);
|
|
@@ -2150,38 +2361,38 @@ var fn_inliner_default = createCommand((program3) => {
|
|
|
2150
2361
|
});
|
|
2151
2362
|
|
|
2152
2363
|
// commands/sequence-split/index.ts
|
|
2153
|
-
import { readFileSync as
|
|
2154
|
-
import { basename as
|
|
2155
|
-
import { parse as
|
|
2156
|
-
import
|
|
2157
|
-
import
|
|
2158
|
-
import * as
|
|
2159
|
-
import
|
|
2160
|
-
var
|
|
2161
|
-
var
|
|
2162
|
-
const ext =
|
|
2364
|
+
import { readFileSync as readFileSync13, writeFileSync as writeFileSync12 } from "fs";
|
|
2365
|
+
import { basename as basename12, dirname as dirname12, extname as extname12, join as join12 } from "path";
|
|
2366
|
+
import { parse as parse13 } from "@babel/parser";
|
|
2367
|
+
import traverse12 from "@babel/traverse";
|
|
2368
|
+
import generate12 from "@babel/generator";
|
|
2369
|
+
import * as t11 from "@babel/types";
|
|
2370
|
+
import loading13 from "loading-cli";
|
|
2371
|
+
var walk4 = patchDefault(traverse12);
|
|
2372
|
+
var createDefaultOutputPath12 = (inputPath) => {
|
|
2373
|
+
const ext = extname12(inputPath);
|
|
2163
2374
|
if (!ext) {
|
|
2164
2375
|
return `${inputPath}.sequence-split.js`;
|
|
2165
2376
|
}
|
|
2166
|
-
const base =
|
|
2167
|
-
return
|
|
2377
|
+
const base = basename12(inputPath, ext);
|
|
2378
|
+
return join12(dirname12(inputPath), `${base}.sequence-split${ext}`);
|
|
2168
2379
|
};
|
|
2169
2380
|
var isExcluded = (node) => {
|
|
2170
|
-
return
|
|
2381
|
+
return t11.isIdentifier(node) && node.name === "eval";
|
|
2171
2382
|
};
|
|
2172
2383
|
var sequenceSplit = (code, filename) => {
|
|
2173
|
-
const ast =
|
|
2384
|
+
const ast = parse13(code, createParseOptions(filename));
|
|
2174
2385
|
let changedCount = 0;
|
|
2175
2386
|
const markChanged = () => {
|
|
2176
2387
|
changedCount += 1;
|
|
2177
2388
|
};
|
|
2178
|
-
|
|
2389
|
+
walk4(ast, {
|
|
2179
2390
|
ConditionalExpression(path) {
|
|
2180
2391
|
if (!path.parentPath || !path.parentPath.isExpressionStatement()) return;
|
|
2181
|
-
const replacement =
|
|
2392
|
+
const replacement = t11.ifStatement(
|
|
2182
2393
|
path.node.test,
|
|
2183
|
-
|
|
2184
|
-
|
|
2394
|
+
t11.expressionStatement(path.node.consequent),
|
|
2395
|
+
t11.expressionStatement(path.node.alternate)
|
|
2185
2396
|
);
|
|
2186
2397
|
if (path.parentPath.parentPath && path.parentPath.parentPath.key === "alternate" && path.parentPath.parentPath.isBlockStatement() && path.parentPath.parentPath.node.body.length === 1) {
|
|
2187
2398
|
path.parentPath.parentPath.replaceWith(replacement);
|
|
@@ -2194,10 +2405,10 @@ var sequenceSplit = (code, filename) => {
|
|
|
2194
2405
|
LogicalExpression(path) {
|
|
2195
2406
|
if (!path.parentPath || !path.parentPath.isExpressionStatement()) return;
|
|
2196
2407
|
if (path.node.operator !== "&&" && path.node.operator !== "||") return;
|
|
2197
|
-
const test = path.node.operator === "&&" ? path.node.left :
|
|
2198
|
-
const replacement =
|
|
2408
|
+
const test = path.node.operator === "&&" ? path.node.left : t11.unaryExpression("!", path.node.left);
|
|
2409
|
+
const replacement = t11.ifStatement(
|
|
2199
2410
|
test,
|
|
2200
|
-
|
|
2411
|
+
t11.expressionStatement(path.node.right)
|
|
2201
2412
|
);
|
|
2202
2413
|
if (path.parentPath.parentPath && path.parentPath.parentPath.key === "alternate" && path.parentPath.parentPath.isBlockStatement() && path.parentPath.parentPath.node.body.length === 1) {
|
|
2203
2414
|
path.parentPath.parentPath.replaceWith(replacement);
|
|
@@ -2209,24 +2420,24 @@ var sequenceSplit = (code, filename) => {
|
|
|
2209
2420
|
},
|
|
2210
2421
|
"ForStatement|WhileStatement|DoWhileStatement"(path) {
|
|
2211
2422
|
if (!path.isForStatement() && !path.isWhileStatement() && !path.isDoWhileStatement()) return;
|
|
2212
|
-
if (
|
|
2213
|
-
path.node.body =
|
|
2423
|
+
if (t11.isBlockStatement(path.node.body)) return;
|
|
2424
|
+
path.node.body = t11.blockStatement([path.node.body]);
|
|
2214
2425
|
markChanged();
|
|
2215
2426
|
},
|
|
2216
2427
|
IfStatement(path) {
|
|
2217
|
-
if (!
|
|
2218
|
-
path.node.consequent =
|
|
2428
|
+
if (!t11.isBlockStatement(path.node.consequent)) {
|
|
2429
|
+
path.node.consequent = t11.blockStatement([path.node.consequent]);
|
|
2219
2430
|
markChanged();
|
|
2220
2431
|
}
|
|
2221
|
-
if (path.node.alternate && !
|
|
2222
|
-
path.node.alternate =
|
|
2432
|
+
if (path.node.alternate && !t11.isBlockStatement(path.node.alternate) && !t11.isIfStatement(path.node.alternate)) {
|
|
2433
|
+
path.node.alternate = t11.blockStatement([path.node.alternate]);
|
|
2223
2434
|
markChanged();
|
|
2224
2435
|
}
|
|
2225
2436
|
},
|
|
2226
2437
|
VariableDeclaration(path) {
|
|
2227
2438
|
if (path.node.declarations.length <= 1) return;
|
|
2228
2439
|
const replacements = path.node.declarations.map(
|
|
2229
|
-
(declaration) =>
|
|
2440
|
+
(declaration) => t11.variableDeclaration(path.node.kind, [declaration])
|
|
2230
2441
|
);
|
|
2231
2442
|
if (path.parentPath?.isForStatement() && path.parentKey === "init") {
|
|
2232
2443
|
const lastDeclaration = replacements.pop();
|
|
@@ -2247,7 +2458,7 @@ var sequenceSplit = (code, filename) => {
|
|
|
2247
2458
|
return;
|
|
2248
2459
|
}
|
|
2249
2460
|
let outerPath = path;
|
|
2250
|
-
while (!
|
|
2461
|
+
while (!t11.isStatement(outerPath.node)) {
|
|
2251
2462
|
const parent = outerPath.parentPath;
|
|
2252
2463
|
if (!parent) return;
|
|
2253
2464
|
if (parent.isConditionalExpression() && (outerPath.key === "consequent" || outerPath.key === "alternate") || parent.isLogicalExpression() && outerPath.key === "right" || parent.isForStatement() && (outerPath.key === "test" || outerPath.key === "update") || parent.isDoWhileStatement() && outerPath.key === "test" || parent.isArrowFunctionExpression() && outerPath.key === "body") {
|
|
@@ -2260,7 +2471,7 @@ var sequenceSplit = (code, filename) => {
|
|
|
2260
2471
|
const firstExpressions = expressions.splice(0, expressions.length - 2);
|
|
2261
2472
|
if (firstExpressions.length > 0) {
|
|
2262
2473
|
const expressionStatements = firstExpressions.map(
|
|
2263
|
-
(expression) =>
|
|
2474
|
+
(expression) => t11.expressionStatement(expression)
|
|
2264
2475
|
);
|
|
2265
2476
|
outerPath.insertBefore(expressionStatements);
|
|
2266
2477
|
markChanged();
|
|
@@ -2268,7 +2479,7 @@ var sequenceSplit = (code, filename) => {
|
|
|
2268
2479
|
} else {
|
|
2269
2480
|
const finalExpression = expressions.splice(expressions.length - 1, 1)[0];
|
|
2270
2481
|
const expressionStatements = expressions.map(
|
|
2271
|
-
(expression) =>
|
|
2482
|
+
(expression) => t11.expressionStatement(expression)
|
|
2272
2483
|
);
|
|
2273
2484
|
outerPath.insertBefore(expressionStatements);
|
|
2274
2485
|
if (finalExpression) {
|
|
@@ -2279,7 +2490,7 @@ var sequenceSplit = (code, filename) => {
|
|
|
2279
2490
|
}
|
|
2280
2491
|
});
|
|
2281
2492
|
return {
|
|
2282
|
-
code: patchDefault(
|
|
2493
|
+
code: patchDefault(generate12)(ast).code,
|
|
2283
2494
|
changedCount
|
|
2284
2495
|
};
|
|
2285
2496
|
};
|
|
@@ -2294,20 +2505,20 @@ var sequence_split_default = createCommand((program3) => {
|
|
|
2294
2505
|
return finish();
|
|
2295
2506
|
}
|
|
2296
2507
|
try {
|
|
2297
|
-
const fileContent =
|
|
2298
|
-
const defaultOutputPath =
|
|
2508
|
+
const fileContent = readFileSync13(filename, "utf8");
|
|
2509
|
+
const defaultOutputPath = createDefaultOutputPath12(filename);
|
|
2299
2510
|
let outputPath = options.output;
|
|
2300
2511
|
if (!outputPath) {
|
|
2301
2512
|
const promptPath = (await createPrompt("Enter the output file path:"))?.trim();
|
|
2302
2513
|
outputPath = promptPath || defaultOutputPath;
|
|
2303
2514
|
}
|
|
2304
|
-
const loader =
|
|
2515
|
+
const loader = loading13("Splitting sequences...").start();
|
|
2305
2516
|
try {
|
|
2306
2517
|
const { code: output, changedCount } = sequenceSplit(
|
|
2307
2518
|
fileContent,
|
|
2308
2519
|
filename
|
|
2309
2520
|
);
|
|
2310
|
-
|
|
2521
|
+
writeFileSync12(outputPath, output, "utf8");
|
|
2311
2522
|
loader.succeed(
|
|
2312
2523
|
`Saved sequence-split file to: ${outputPath} (${diff(fileContent, output).length} lines changed, ${changedCount} transforms)`
|
|
2313
2524
|
);
|
|
@@ -2356,10 +2567,10 @@ var calmGradienrain = (text) => {
|
|
|
2356
2567
|
const endHue = 300;
|
|
2357
2568
|
const saturation = 0.45;
|
|
2358
2569
|
const value = 0.8;
|
|
2359
|
-
const ease = (
|
|
2570
|
+
const ease = (t12) => t12 * t12 * (3 - 2 * t12);
|
|
2360
2571
|
return text.split("").map((char, i) => {
|
|
2361
|
-
const
|
|
2362
|
-
const hue = startHue + (endHue - startHue) *
|
|
2572
|
+
const t12 = ease(i / Math.max(text.length - 1, 1));
|
|
2573
|
+
const hue = startHue + (endHue - startHue) * t12;
|
|
2363
2574
|
const c = value * saturation;
|
|
2364
2575
|
const h = hue / 60;
|
|
2365
2576
|
const x = c * (1 - Math.abs(h % 2 - 1));
|
|
@@ -2383,11 +2594,11 @@ ${calmGradienrain(`Expose Kit v${VERSION}`)} ${update && update.latest !== VERSI
|
|
|
2383
2594
|
`;
|
|
2384
2595
|
|
|
2385
2596
|
// index.ts
|
|
2386
|
-
import { readFileSync as
|
|
2597
|
+
import { readFileSync as readFileSync14 } from "fs";
|
|
2387
2598
|
import updateNotifier from "update-notifier";
|
|
2388
2599
|
var __filename = fileURLToPath(import.meta.url);
|
|
2389
|
-
var __dirname =
|
|
2390
|
-
var pkg = JSON.parse(
|
|
2600
|
+
var __dirname = dirname13(__filename);
|
|
2601
|
+
var pkg = JSON.parse(readFileSync14(join13(__dirname, "package.json"), "utf8"));
|
|
2391
2602
|
var notifier = updateNotifier({
|
|
2392
2603
|
pkg,
|
|
2393
2604
|
updateCheckInterval: 1e3 * 60 * 60 * 24 * 3
|
|
@@ -2411,6 +2622,7 @@ var commands = [
|
|
|
2411
2622
|
remove_updater_default,
|
|
2412
2623
|
remove_reassign_default,
|
|
2413
2624
|
remove_deadcode_default,
|
|
2625
|
+
control_flow_packer_default,
|
|
2414
2626
|
fn_inliner_default,
|
|
2415
2627
|
remove_unused_default,
|
|
2416
2628
|
sequence_split_default
|
package/dist/package.json
CHANGED