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 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 dirname12, join as join12 } from "path";
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/fn-inliner/index.ts
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}.fn-inliner.js`;
1956
+ return `${inputPath}.control-flow-packer.js`;
1957
1957
  }
1958
1958
  const base = basename10(inputPath, ext);
1959
- return join10(dirname10(inputPath), `${base}.fn-inliner${ext}`);
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 t9.isFunction(node) && node.params.every((param) => t9.isIdentifier(param)) && (t9.isBlockStatement(node.body) && node.body.body.length === 1 && t9.isReturnStatement(node.body.body[0]) && (node.body.body[0].argument === void 0 || t9.isExpression(node.body.body[0].argument) && isProxyValue(node.body.body[0].argument)) || t9.isArrowFunctionExpression(node) && t9.isExpression(node.body) && isProxyValue(node.body));
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 (t9.isFunction(node) || t9.isBlockStatement(node) || t9.isSequenceExpression(node) || t9.isAssignmentExpression(node)) {
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 (!t9.isExpression(node)) {
2180
+ if (!t10.isExpression(node)) {
1970
2181
  return false;
1971
2182
  }
1972
- const wrapper = t9.file(t9.program([t9.expressionStatement(node)]));
1973
- walk2(wrapper, {
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 t9.cloneNode(expression, true);
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 = t9.isExpression(this.expression.body) ? copyExpression(this.expression.body) : this.expression.body.body[0].argument ? copyExpression(this.expression.body.body[0].argument) : t9.identifier("undefined");
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] ?? t9.identifier("undefined")
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 = t9.file(t9.program([t9.expressionStatement(expression)]));
2025
- walk2(wrapper, {
2235
+ const wrapper = t10.file(t10.program([t10.expressionStatement(expression)]));
2236
+ walk3(wrapper, {
2026
2237
  enter(path) {
2027
- if (t9.isIdentifier(path.node) && !shouldSkipIdentifier(path) && paramMap.has(path.node.name)) {
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(t9.cloneNode(replacement, true));
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 (!t9.isExpression(argument)) {
2266
+ if (!t10.isExpression(argument)) {
2056
2267
  return false;
2057
2268
  }
2058
- args.push(t9.cloneNode(argument, true));
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
- walk2(ast, {
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 (!t9.isIdentifier(path.node.id)) return;
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 = parse11(code, createParseOptions(filename));
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(generate10)(ast).code,
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 = readFileSync11(filename, "utf8");
2115
- const defaultOutputPath = createDefaultOutputPath10(filename);
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 = loading11("Inlining proxy functions...").start();
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
- writeFileSync10(outputPath, output, "utf8");
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 readFileSync12, writeFileSync as writeFileSync11 } from "fs";
2154
- import { basename as basename11, dirname as dirname11, extname as extname11, join as join11 } from "path";
2155
- import { parse as parse12 } from "@babel/parser";
2156
- import traverse11 from "@babel/traverse";
2157
- import generate11 from "@babel/generator";
2158
- import * as t10 from "@babel/types";
2159
- import loading12 from "loading-cli";
2160
- var walk3 = patchDefault(traverse11);
2161
- var createDefaultOutputPath11 = (inputPath) => {
2162
- const ext = extname11(inputPath);
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 = basename11(inputPath, ext);
2167
- return join11(dirname11(inputPath), `${base}.sequence-split${ext}`);
2377
+ const base = basename12(inputPath, ext);
2378
+ return join12(dirname12(inputPath), `${base}.sequence-split${ext}`);
2168
2379
  };
2169
2380
  var isExcluded = (node) => {
2170
- return t10.isIdentifier(node) && node.name === "eval";
2381
+ return t11.isIdentifier(node) && node.name === "eval";
2171
2382
  };
2172
2383
  var sequenceSplit = (code, filename) => {
2173
- const ast = parse12(code, createParseOptions(filename));
2384
+ const ast = parse13(code, createParseOptions(filename));
2174
2385
  let changedCount = 0;
2175
2386
  const markChanged = () => {
2176
2387
  changedCount += 1;
2177
2388
  };
2178
- walk3(ast, {
2389
+ walk4(ast, {
2179
2390
  ConditionalExpression(path) {
2180
2391
  if (!path.parentPath || !path.parentPath.isExpressionStatement()) return;
2181
- const replacement = t10.ifStatement(
2392
+ const replacement = t11.ifStatement(
2182
2393
  path.node.test,
2183
- t10.expressionStatement(path.node.consequent),
2184
- t10.expressionStatement(path.node.alternate)
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 : t10.unaryExpression("!", path.node.left);
2198
- const replacement = t10.ifStatement(
2408
+ const test = path.node.operator === "&&" ? path.node.left : t11.unaryExpression("!", path.node.left);
2409
+ const replacement = t11.ifStatement(
2199
2410
  test,
2200
- t10.expressionStatement(path.node.right)
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 (t10.isBlockStatement(path.node.body)) return;
2213
- path.node.body = t10.blockStatement([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 (!t10.isBlockStatement(path.node.consequent)) {
2218
- path.node.consequent = t10.blockStatement([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 && !t10.isBlockStatement(path.node.alternate) && !t10.isIfStatement(path.node.alternate)) {
2222
- path.node.alternate = t10.blockStatement([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) => t10.variableDeclaration(path.node.kind, [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 (!t10.isStatement(outerPath.node)) {
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) => t10.expressionStatement(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) => t10.expressionStatement(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(generate11)(ast).code,
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 = readFileSync12(filename, "utf8");
2298
- const defaultOutputPath = createDefaultOutputPath11(filename);
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 = loading12("Splitting sequences...").start();
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
- writeFileSync11(outputPath, output, "utf8");
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 = (t11) => t11 * t11 * (3 - 2 * t11);
2570
+ const ease = (t12) => t12 * t12 * (3 - 2 * t12);
2360
2571
  return text.split("").map((char, i) => {
2361
- const t11 = ease(i / Math.max(text.length - 1, 1));
2362
- const hue = startHue + (endHue - startHue) * t11;
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 readFileSync13 } from "fs";
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 = dirname12(__filename);
2390
- var pkg = JSON.parse(readFileSync13(join12(__dirname, "package.json"), "utf8"));
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expose-kit",
3
- "version": "0.11.0",
3
+ "version": "0.12.0",
4
4
  "type": "module",
5
5
  "private": false,
6
6
  "author": "EdamAmex <edame8080@gmail.com> (https://github.com/EdamAme-x)",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expose-kit",
3
- "version": "0.11.0",
3
+ "version": "0.12.0",
4
4
  "type": "module",
5
5
  "private": false,
6
6
  "author": "EdamAmex <edame8080@gmail.com> (https://github.com/EdamAme-x)",