expose-kit 0.10.4 → 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
@@ -110,6 +110,8 @@ After `safe-scope`, combine common techniques like:
110
110
  After **each step**, run `parsable` and `remove-unused` again.
111
111
  (even if it's not frequent, we might overlook something broken)
112
112
 
113
+ The more you do it, the clearer it becomes.
114
+
113
115
  Expose Kit will also clearly indicate whether a **diff** exists, making inspection easy.
114
116
 
115
117
  Repeat this process, and the original code will gradually reveal itself.
@@ -324,6 +326,76 @@ Notes:
324
326
 
325
327
  ---
326
328
 
329
+ ### `expose remove-deadcode`
330
+
331
+ Remove unreachable branches and simplify conditional expressions.
332
+ ```js
333
+ if (true) {
334
+ a();
335
+ } else {
336
+ b();
337
+ }
338
+ // after
339
+ a();
340
+
341
+ const x = cond ? true : false;
342
+ // after
343
+ const x = !!cond;
344
+ ```
345
+ Example is [here](https://github.com/evex-dev/expose-kit/tree/main/commands/remove-deadcode/mocks).
346
+
347
+ ```bash
348
+ expose remove-deadcode path/to/file.js --output path/to/file.remove-deadcode.js
349
+ ```
350
+
351
+ Args:
352
+ - `--o, --output <file>`
353
+ Output file path
354
+
355
+ Notes:
356
+ - Only removes branches with literal/array/object tests.
357
+ - Simplifies ternaries when both branches are booleans.
358
+
359
+ ---
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
+
327
399
  ### `expose fn-inliner`
328
400
 
329
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 dirname11, join as join11 } 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
 
@@ -1780,7 +1780,7 @@ var remove_unused_default = createCommand((program3) => {
1780
1780
  );
1781
1781
  });
1782
1782
 
1783
- // commands/fn-inliner/index.ts
1783
+ // commands/remove-deadcode/index.ts
1784
1784
  import { readFileSync as readFileSync10, writeFileSync as writeFileSync9 } from "fs";
1785
1785
  import { basename as basename9, dirname as dirname9, extname as extname9, join as join9 } from "path";
1786
1786
  import { parse as parse10 } from "@babel/parser";
@@ -1792,24 +1792,396 @@ var walk = patchDefault(traverse9);
1792
1792
  var createDefaultOutputPath9 = (inputPath) => {
1793
1793
  const ext = extname9(inputPath);
1794
1794
  if (!ext) {
1795
- return `${inputPath}.fn-inliner.js`;
1795
+ return `${inputPath}.remove-deadcode.js`;
1796
1796
  }
1797
1797
  const base = basename9(inputPath, ext);
1798
- return join9(dirname9(inputPath), `${base}.fn-inliner${ext}`);
1798
+ return join9(dirname9(inputPath), `${base}.remove-deadcode${ext}`);
1799
+ };
1800
+ var isSemiLiteral = (node) => {
1801
+ return t8.isLiteral(node) || t8.isArrayExpression(node) || t8.isObjectExpression(node);
1802
+ };
1803
+ var isTruthy = (literal) => {
1804
+ if (t8.isBooleanLiteral(literal) || t8.isNumericLiteral(literal)) {
1805
+ return Boolean(literal.value);
1806
+ }
1807
+ if (t8.isStringLiteral(literal)) {
1808
+ return literal.value.length > 0;
1809
+ }
1810
+ if (t8.isNullLiteral(literal)) {
1811
+ return false;
1812
+ }
1813
+ if (t8.isBigIntLiteral(literal)) {
1814
+ return literal.value !== "0";
1815
+ }
1816
+ return true;
1817
+ };
1818
+ var replaceWithStatements = (path, statements) => {
1819
+ const parent = path.parentPath;
1820
+ if (parent?.isBlockStatement() || parent?.isProgram() || parent?.isSwitchCase()) {
1821
+ path.replaceWithMultiple(statements);
1822
+ return;
1823
+ }
1824
+ if (statements.length === 0) {
1825
+ path.remove();
1826
+ return;
1827
+ }
1828
+ if (statements.length === 1 && statements[0]) {
1829
+ path.replaceWith(statements[0]);
1830
+ return;
1831
+ }
1832
+ path.replaceWith(t8.blockStatement(statements));
1833
+ };
1834
+ var removeDeadCode = (code, filename) => {
1835
+ const ast = parse10(code, createParseOptions(filename));
1836
+ let changedCount = 0;
1837
+ walk(ast, {
1838
+ IfStatement(path) {
1839
+ if (!isSemiLiteral(path.node.test)) return;
1840
+ if (isTruthy(path.node.test)) {
1841
+ const statements = t8.isBlockStatement(path.node.consequent) ? path.node.consequent.body : [path.node.consequent];
1842
+ replaceWithStatements(path, statements);
1843
+ } else {
1844
+ if (path.node.alternate) {
1845
+ if (t8.isBlockStatement(path.node.alternate)) {
1846
+ replaceWithStatements(path, path.node.alternate.body);
1847
+ } else {
1848
+ replaceWithStatements(path, [path.node.alternate]);
1849
+ }
1850
+ } else {
1851
+ path.remove();
1852
+ }
1853
+ }
1854
+ changedCount += 1;
1855
+ },
1856
+ ConditionalExpression(path) {
1857
+ if (isSemiLiteral(path.node.test)) {
1858
+ const replacement = isTruthy(path.node.test) ? path.node.consequent : path.node.alternate;
1859
+ path.replaceWith(replacement);
1860
+ changedCount += 1;
1861
+ return;
1862
+ }
1863
+ if (t8.isBooleanLiteral(path.node.consequent) && t8.isBooleanLiteral(path.node.alternate)) {
1864
+ const consequent = path.node.consequent.value;
1865
+ const alternate = path.node.alternate.value;
1866
+ let replacement;
1867
+ if (consequent && !alternate) {
1868
+ replacement = t8.unaryExpression(
1869
+ "!",
1870
+ t8.unaryExpression("!", path.node.test)
1871
+ );
1872
+ } else if (!consequent && alternate) {
1873
+ replacement = t8.unaryExpression("!", path.node.test);
1874
+ } else if (consequent && alternate) {
1875
+ replacement = t8.sequenceExpression([
1876
+ path.node.test,
1877
+ t8.booleanLiteral(true)
1878
+ ]);
1879
+ } else {
1880
+ replacement = t8.sequenceExpression([
1881
+ path.node.test,
1882
+ t8.booleanLiteral(false)
1883
+ ]);
1884
+ }
1885
+ path.replaceWith(replacement);
1886
+ changedCount += 1;
1887
+ }
1888
+ }
1889
+ });
1890
+ return {
1891
+ code: patchDefault(generate9)(ast).code,
1892
+ changedCount
1893
+ };
1894
+ };
1895
+ var remove_deadcode_default = createCommand((program3) => {
1896
+ program3.command("remove-deadcode").description("Remove unreachable branches and simplify conditional expressions").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(
1897
+ async (fileArgument, options) => {
1898
+ await timeout(
1899
+ async ({ finish }) => {
1900
+ const filename = fileArgument ?? options.file ?? await createPrompt("Enter the file path:");
1901
+ if (!filename) {
1902
+ showError("No file provided");
1903
+ return finish();
1904
+ }
1905
+ try {
1906
+ const fileContent = readFileSync10(filename, "utf8");
1907
+ const defaultOutputPath = createDefaultOutputPath9(filename);
1908
+ let outputPath = options.output;
1909
+ if (!outputPath) {
1910
+ const promptPath = (await createPrompt("Enter the output file path:"))?.trim();
1911
+ outputPath = promptPath || defaultOutputPath;
1912
+ }
1913
+ const loader = loading10("Removing dead code...").start();
1914
+ try {
1915
+ const { code: output, changedCount } = removeDeadCode(
1916
+ fileContent,
1917
+ filename
1918
+ );
1919
+ writeFileSync9(outputPath, output, "utf8");
1920
+ loader.succeed(
1921
+ `Saved remove-deadcode file to: ${outputPath} (${diff(fileContent, output).length} lines changed, ${changedCount} edits)`
1922
+ );
1923
+ return finish();
1924
+ } catch (error) {
1925
+ loader.fail("Failed to apply remove-deadcode transform");
1926
+ showError(
1927
+ `Error transforming file '${filename}': ${error instanceof Error ? error.message : "Unknown error"}`
1928
+ );
1929
+ return finish();
1930
+ }
1931
+ } catch (error) {
1932
+ showError(
1933
+ `Error reading file '${filename}': ${error instanceof Error ? error.message : "Unknown error"}`
1934
+ );
1935
+ return finish();
1936
+ }
1937
+ },
1938
+ options.unlimited ? null : 120 * 1e3
1939
+ );
1940
+ }
1941
+ );
1942
+ });
1943
+
1944
+ // commands/control-flow-packer/index.ts
1945
+ import { readFileSync as readFileSync11, writeFileSync as writeFileSync10 } from "fs";
1946
+ import { basename as basename10, dirname as dirname10, extname as extname10, join as join10 } from "path";
1947
+ import { parse as parse11 } from "@babel/parser";
1948
+ import traverse10 from "@babel/traverse";
1949
+ import generate10 from "@babel/generator";
1950
+ import * as t9 from "@babel/types";
1951
+ import loading11 from "loading-cli";
1952
+ var walk2 = patchDefault(traverse10);
1953
+ var createDefaultOutputPath10 = (inputPath) => {
1954
+ const ext = extname10(inputPath);
1955
+ if (!ext) {
1956
+ return `${inputPath}.control-flow-packer.js`;
1957
+ }
1958
+ const base = basename10(inputPath, 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}`);
1799
2171
  };
1800
2172
  var isProxyFunctionExpression = (node) => {
1801
- return t8.isFunction(node) && node.params.every((param) => t8.isIdentifier(param)) && (t8.isBlockStatement(node.body) && node.body.body.length === 1 && t8.isReturnStatement(node.body.body[0]) && (node.body.body[0].argument === void 0 || t8.isExpression(node.body.body[0].argument) && isProxyValue(node.body.body[0].argument)) || t8.isArrowFunctionExpression(node) && t8.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));
1802
2174
  };
1803
2175
  var isProxyValue = (node) => {
1804
- if (t8.isFunction(node) || t8.isBlockStatement(node) || t8.isSequenceExpression(node) || t8.isAssignmentExpression(node)) {
2176
+ if (t10.isFunction(node) || t10.isBlockStatement(node) || t10.isSequenceExpression(node) || t10.isAssignmentExpression(node)) {
1805
2177
  return false;
1806
2178
  }
1807
2179
  let isValid = true;
1808
- if (!t8.isExpression(node)) {
2180
+ if (!t10.isExpression(node)) {
1809
2181
  return false;
1810
2182
  }
1811
- const wrapper = t8.file(t8.program([t8.expressionStatement(node)]));
1812
- walk(wrapper, {
2183
+ const wrapper = t10.file(t10.program([t10.expressionStatement(node)]));
2184
+ walk3(wrapper, {
1813
2185
  "SequenceExpression|BlockStatement|Function|AssignmentExpression"(path) {
1814
2186
  isValid = false;
1815
2187
  path.stop();
@@ -1819,7 +2191,7 @@ var isProxyValue = (node) => {
1819
2191
  return isValid;
1820
2192
  };
1821
2193
  var copyExpression = (expression) => {
1822
- return t8.cloneNode(expression, true);
2194
+ return t10.cloneNode(expression, true);
1823
2195
  };
1824
2196
  var ProxyFunction = class {
1825
2197
  expression;
@@ -1827,7 +2199,7 @@ var ProxyFunction = class {
1827
2199
  this.expression = expression;
1828
2200
  }
1829
2201
  getReplacement(args) {
1830
- const expression = t8.isExpression(this.expression.body) ? copyExpression(this.expression.body) : this.expression.body.body[0].argument ? copyExpression(this.expression.body.body[0].argument) : t8.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");
1831
2203
  this.replaceParameters(expression, args);
1832
2204
  return expression;
1833
2205
  }
@@ -1835,7 +2207,7 @@ var ProxyFunction = class {
1835
2207
  const paramMap = new Map(
1836
2208
  this.expression.params.map((param, index) => [
1837
2209
  param.name,
1838
- args[index] ?? t8.identifier("undefined")
2210
+ args[index] ?? t10.identifier("undefined")
1839
2211
  ])
1840
2212
  );
1841
2213
  const pathsToReplace = [];
@@ -1860,10 +2232,10 @@ var ProxyFunction = class {
1860
2232
  }
1861
2233
  return false;
1862
2234
  };
1863
- const wrapper = t8.file(t8.program([t8.expressionStatement(expression)]));
1864
- walk(wrapper, {
2235
+ const wrapper = t10.file(t10.program([t10.expressionStatement(expression)]));
2236
+ walk3(wrapper, {
1865
2237
  enter(path) {
1866
- if (t8.isIdentifier(path.node) && !shouldSkipIdentifier(path) && paramMap.has(path.node.name)) {
2238
+ if (t10.isIdentifier(path.node) && !shouldSkipIdentifier(path) && paramMap.has(path.node.name)) {
1867
2239
  const replacement = paramMap.get(path.node.name);
1868
2240
  pathsToReplace.push([path, replacement]);
1869
2241
  }
@@ -1871,7 +2243,7 @@ var ProxyFunction = class {
1871
2243
  noScope: true
1872
2244
  });
1873
2245
  for (const [path, replacement] of pathsToReplace) {
1874
- path.replaceWith(t8.cloneNode(replacement, true));
2246
+ path.replaceWith(t10.cloneNode(replacement, true));
1875
2247
  }
1876
2248
  }
1877
2249
  };
@@ -1891,10 +2263,10 @@ var ProxyFunctionVariable = class extends ProxyFunction {
1891
2263
  const argumentNodes = path.parentPath.node.arguments;
1892
2264
  const args = [];
1893
2265
  for (const argument of argumentNodes) {
1894
- if (!t8.isExpression(argument)) {
2266
+ if (!t10.isExpression(argument)) {
1895
2267
  return false;
1896
2268
  }
1897
- args.push(t8.cloneNode(argument, true));
2269
+ args.push(t10.cloneNode(argument, true));
1898
2270
  }
1899
2271
  const expression = this.getReplacement(args);
1900
2272
  path.parentPath.replaceWith(expression);
@@ -1903,7 +2275,7 @@ var ProxyFunctionVariable = class extends ProxyFunction {
1903
2275
  };
1904
2276
  var collectProxyFunctions = (ast) => {
1905
2277
  const proxies = [];
1906
- walk(ast, {
2278
+ walk3(ast, {
1907
2279
  FunctionDeclaration(path) {
1908
2280
  if (!path.node.id) return;
1909
2281
  if (!isProxyFunctionExpression(path.node)) return;
@@ -1912,7 +2284,7 @@ var collectProxyFunctions = (ast) => {
1912
2284
  proxies.push(new ProxyFunctionVariable(binding, path.node));
1913
2285
  },
1914
2286
  VariableDeclarator(path) {
1915
- if (!t8.isIdentifier(path.node.id)) return;
2287
+ if (!t10.isIdentifier(path.node.id)) return;
1916
2288
  const init = path.node.init;
1917
2289
  if (!init || !isProxyFunctionExpression(init)) return;
1918
2290
  const binding = path.scope.getBinding(path.node.id.name);
@@ -1923,7 +2295,7 @@ var collectProxyFunctions = (ast) => {
1923
2295
  return proxies;
1924
2296
  };
1925
2297
  var inlineProxyFunctions = (code, filename) => {
1926
- const ast = parse10(code, createParseOptions(filename));
2298
+ const ast = parse12(code, createParseOptions(filename));
1927
2299
  const proxies = collectProxyFunctions(ast);
1928
2300
  let replacedCount = 0;
1929
2301
  for (const proxy of proxies) {
@@ -1935,7 +2307,7 @@ var inlineProxyFunctions = (code, filename) => {
1935
2307
  }
1936
2308
  }
1937
2309
  return {
1938
- code: patchDefault(generate9)(ast).code,
2310
+ code: patchDefault(generate11)(ast).code,
1939
2311
  replacedCount
1940
2312
  };
1941
2313
  };
@@ -1950,20 +2322,20 @@ var fn_inliner_default = createCommand((program3) => {
1950
2322
  return finish();
1951
2323
  }
1952
2324
  try {
1953
- const fileContent = readFileSync10(filename, "utf8");
1954
- const defaultOutputPath = createDefaultOutputPath9(filename);
2325
+ const fileContent = readFileSync12(filename, "utf8");
2326
+ const defaultOutputPath = createDefaultOutputPath11(filename);
1955
2327
  let outputPath = options.output;
1956
2328
  if (!outputPath) {
1957
2329
  const promptPath = (await createPrompt("Enter the output file path:"))?.trim();
1958
2330
  outputPath = promptPath || defaultOutputPath;
1959
2331
  }
1960
- const loader = loading10("Inlining proxy functions...").start();
2332
+ const loader = loading12("Inlining proxy functions...").start();
1961
2333
  try {
1962
2334
  const { code: output, replacedCount } = inlineProxyFunctions(
1963
2335
  fileContent,
1964
2336
  filename
1965
2337
  );
1966
- writeFileSync9(outputPath, output, "utf8");
2338
+ writeFileSync11(outputPath, output, "utf8");
1967
2339
  loader.succeed(
1968
2340
  `Saved fn-inliner file to: ${outputPath} (${diff(fileContent, output).length} lines changed, ${replacedCount} replacements)`
1969
2341
  );
@@ -1989,38 +2361,38 @@ var fn_inliner_default = createCommand((program3) => {
1989
2361
  });
1990
2362
 
1991
2363
  // commands/sequence-split/index.ts
1992
- import { readFileSync as readFileSync11, writeFileSync as writeFileSync10 } from "fs";
1993
- import { basename as basename10, dirname as dirname10, extname as extname10, join as join10 } from "path";
1994
- import { parse as parse11 } from "@babel/parser";
1995
- import traverse10 from "@babel/traverse";
1996
- import generate10 from "@babel/generator";
1997
- import * as t9 from "@babel/types";
1998
- import loading11 from "loading-cli";
1999
- var walk2 = patchDefault(traverse10);
2000
- var createDefaultOutputPath10 = (inputPath) => {
2001
- const ext = extname10(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);
2002
2374
  if (!ext) {
2003
2375
  return `${inputPath}.sequence-split.js`;
2004
2376
  }
2005
- const base = basename10(inputPath, ext);
2006
- return join10(dirname10(inputPath), `${base}.sequence-split${ext}`);
2377
+ const base = basename12(inputPath, ext);
2378
+ return join12(dirname12(inputPath), `${base}.sequence-split${ext}`);
2007
2379
  };
2008
2380
  var isExcluded = (node) => {
2009
- return t9.isIdentifier(node) && node.name === "eval";
2381
+ return t11.isIdentifier(node) && node.name === "eval";
2010
2382
  };
2011
2383
  var sequenceSplit = (code, filename) => {
2012
- const ast = parse11(code, createParseOptions(filename));
2384
+ const ast = parse13(code, createParseOptions(filename));
2013
2385
  let changedCount = 0;
2014
2386
  const markChanged = () => {
2015
2387
  changedCount += 1;
2016
2388
  };
2017
- walk2(ast, {
2389
+ walk4(ast, {
2018
2390
  ConditionalExpression(path) {
2019
2391
  if (!path.parentPath || !path.parentPath.isExpressionStatement()) return;
2020
- const replacement = t9.ifStatement(
2392
+ const replacement = t11.ifStatement(
2021
2393
  path.node.test,
2022
- t9.expressionStatement(path.node.consequent),
2023
- t9.expressionStatement(path.node.alternate)
2394
+ t11.expressionStatement(path.node.consequent),
2395
+ t11.expressionStatement(path.node.alternate)
2024
2396
  );
2025
2397
  if (path.parentPath.parentPath && path.parentPath.parentPath.key === "alternate" && path.parentPath.parentPath.isBlockStatement() && path.parentPath.parentPath.node.body.length === 1) {
2026
2398
  path.parentPath.parentPath.replaceWith(replacement);
@@ -2033,10 +2405,10 @@ var sequenceSplit = (code, filename) => {
2033
2405
  LogicalExpression(path) {
2034
2406
  if (!path.parentPath || !path.parentPath.isExpressionStatement()) return;
2035
2407
  if (path.node.operator !== "&&" && path.node.operator !== "||") return;
2036
- const test = path.node.operator === "&&" ? path.node.left : t9.unaryExpression("!", path.node.left);
2037
- const replacement = t9.ifStatement(
2408
+ const test = path.node.operator === "&&" ? path.node.left : t11.unaryExpression("!", path.node.left);
2409
+ const replacement = t11.ifStatement(
2038
2410
  test,
2039
- t9.expressionStatement(path.node.right)
2411
+ t11.expressionStatement(path.node.right)
2040
2412
  );
2041
2413
  if (path.parentPath.parentPath && path.parentPath.parentPath.key === "alternate" && path.parentPath.parentPath.isBlockStatement() && path.parentPath.parentPath.node.body.length === 1) {
2042
2414
  path.parentPath.parentPath.replaceWith(replacement);
@@ -2048,24 +2420,24 @@ var sequenceSplit = (code, filename) => {
2048
2420
  },
2049
2421
  "ForStatement|WhileStatement|DoWhileStatement"(path) {
2050
2422
  if (!path.isForStatement() && !path.isWhileStatement() && !path.isDoWhileStatement()) return;
2051
- if (t9.isBlockStatement(path.node.body)) return;
2052
- path.node.body = t9.blockStatement([path.node.body]);
2423
+ if (t11.isBlockStatement(path.node.body)) return;
2424
+ path.node.body = t11.blockStatement([path.node.body]);
2053
2425
  markChanged();
2054
2426
  },
2055
2427
  IfStatement(path) {
2056
- if (!t9.isBlockStatement(path.node.consequent)) {
2057
- path.node.consequent = t9.blockStatement([path.node.consequent]);
2428
+ if (!t11.isBlockStatement(path.node.consequent)) {
2429
+ path.node.consequent = t11.blockStatement([path.node.consequent]);
2058
2430
  markChanged();
2059
2431
  }
2060
- if (path.node.alternate && !t9.isBlockStatement(path.node.alternate) && !t9.isIfStatement(path.node.alternate)) {
2061
- path.node.alternate = t9.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]);
2062
2434
  markChanged();
2063
2435
  }
2064
2436
  },
2065
2437
  VariableDeclaration(path) {
2066
2438
  if (path.node.declarations.length <= 1) return;
2067
2439
  const replacements = path.node.declarations.map(
2068
- (declaration) => t9.variableDeclaration(path.node.kind, [declaration])
2440
+ (declaration) => t11.variableDeclaration(path.node.kind, [declaration])
2069
2441
  );
2070
2442
  if (path.parentPath?.isForStatement() && path.parentKey === "init") {
2071
2443
  const lastDeclaration = replacements.pop();
@@ -2086,7 +2458,7 @@ var sequenceSplit = (code, filename) => {
2086
2458
  return;
2087
2459
  }
2088
2460
  let outerPath = path;
2089
- while (!t9.isStatement(outerPath.node)) {
2461
+ while (!t11.isStatement(outerPath.node)) {
2090
2462
  const parent = outerPath.parentPath;
2091
2463
  if (!parent) return;
2092
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") {
@@ -2099,7 +2471,7 @@ var sequenceSplit = (code, filename) => {
2099
2471
  const firstExpressions = expressions.splice(0, expressions.length - 2);
2100
2472
  if (firstExpressions.length > 0) {
2101
2473
  const expressionStatements = firstExpressions.map(
2102
- (expression) => t9.expressionStatement(expression)
2474
+ (expression) => t11.expressionStatement(expression)
2103
2475
  );
2104
2476
  outerPath.insertBefore(expressionStatements);
2105
2477
  markChanged();
@@ -2107,7 +2479,7 @@ var sequenceSplit = (code, filename) => {
2107
2479
  } else {
2108
2480
  const finalExpression = expressions.splice(expressions.length - 1, 1)[0];
2109
2481
  const expressionStatements = expressions.map(
2110
- (expression) => t9.expressionStatement(expression)
2482
+ (expression) => t11.expressionStatement(expression)
2111
2483
  );
2112
2484
  outerPath.insertBefore(expressionStatements);
2113
2485
  if (finalExpression) {
@@ -2118,7 +2490,7 @@ var sequenceSplit = (code, filename) => {
2118
2490
  }
2119
2491
  });
2120
2492
  return {
2121
- code: patchDefault(generate10)(ast).code,
2493
+ code: patchDefault(generate12)(ast).code,
2122
2494
  changedCount
2123
2495
  };
2124
2496
  };
@@ -2133,20 +2505,20 @@ var sequence_split_default = createCommand((program3) => {
2133
2505
  return finish();
2134
2506
  }
2135
2507
  try {
2136
- const fileContent = readFileSync11(filename, "utf8");
2137
- const defaultOutputPath = createDefaultOutputPath10(filename);
2508
+ const fileContent = readFileSync13(filename, "utf8");
2509
+ const defaultOutputPath = createDefaultOutputPath12(filename);
2138
2510
  let outputPath = options.output;
2139
2511
  if (!outputPath) {
2140
2512
  const promptPath = (await createPrompt("Enter the output file path:"))?.trim();
2141
2513
  outputPath = promptPath || defaultOutputPath;
2142
2514
  }
2143
- const loader = loading11("Splitting sequences...").start();
2515
+ const loader = loading13("Splitting sequences...").start();
2144
2516
  try {
2145
2517
  const { code: output, changedCount } = sequenceSplit(
2146
2518
  fileContent,
2147
2519
  filename
2148
2520
  );
2149
- writeFileSync10(outputPath, output, "utf8");
2521
+ writeFileSync12(outputPath, output, "utf8");
2150
2522
  loader.succeed(
2151
2523
  `Saved sequence-split file to: ${outputPath} (${diff(fileContent, output).length} lines changed, ${changedCount} transforms)`
2152
2524
  );
@@ -2195,10 +2567,10 @@ var calmGradienrain = (text) => {
2195
2567
  const endHue = 300;
2196
2568
  const saturation = 0.45;
2197
2569
  const value = 0.8;
2198
- const ease = (t10) => t10 * t10 * (3 - 2 * t10);
2570
+ const ease = (t12) => t12 * t12 * (3 - 2 * t12);
2199
2571
  return text.split("").map((char, i) => {
2200
- const t10 = ease(i / Math.max(text.length - 1, 1));
2201
- const hue = startHue + (endHue - startHue) * t10;
2572
+ const t12 = ease(i / Math.max(text.length - 1, 1));
2573
+ const hue = startHue + (endHue - startHue) * t12;
2202
2574
  const c = value * saturation;
2203
2575
  const h = hue / 60;
2204
2576
  const x = c * (1 - Math.abs(h % 2 - 1));
@@ -2222,14 +2594,15 @@ ${calmGradienrain(`Expose Kit v${VERSION}`)} ${update && update.latest !== VERSI
2222
2594
  `;
2223
2595
 
2224
2596
  // index.ts
2225
- import { readFileSync as readFileSync12 } from "fs";
2597
+ import { readFileSync as readFileSync14 } from "fs";
2226
2598
  import updateNotifier from "update-notifier";
2227
2599
  var __filename = fileURLToPath(import.meta.url);
2228
- var __dirname = dirname11(__filename);
2229
- var pkg = JSON.parse(readFileSync12(join11(__dirname, "package.json"), "utf8"));
2600
+ var __dirname = dirname13(__filename);
2601
+ var pkg = JSON.parse(readFileSync14(join13(__dirname, "package.json"), "utf8"));
2230
2602
  var notifier = updateNotifier({
2231
2603
  pkg,
2232
- updateCheckInterval: 0
2604
+ updateCheckInterval: 1e3 * 60 * 60 * 24 * 3
2605
+ // 3 days
2233
2606
  });
2234
2607
  console.log(showCredit(pkg.version, notifier.update));
2235
2608
  console.log();
@@ -2248,6 +2621,8 @@ var commands = [
2248
2621
  pre_evaluate_default,
2249
2622
  remove_updater_default,
2250
2623
  remove_reassign_default,
2624
+ remove_deadcode_default,
2625
+ control_flow_packer_default,
2251
2626
  fn_inliner_default,
2252
2627
  remove_unused_default,
2253
2628
  sequence_split_default
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expose-kit",
3
- "version": "0.10.4",
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.10.4",
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)",