expose-kit 0.8.0 → 0.9.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
@@ -321,9 +321,34 @@ Notes:
321
321
 
322
322
  ---
323
323
 
324
+ ### `expose fn-inliner`
325
+
326
+ Inline proxy function calls into expressions.
327
+ ```js
328
+ const add = (a, b) => a + b;
329
+ const sum = add(1, 2);
330
+ // after
331
+ const sum = 1 + 2;
332
+ ```
333
+ Example is [here](https://github.com/evex-dev/expose-kit/tree/main/commands/fn-inliner/mocks).
334
+
335
+ ```bash
336
+ expose fn-inliner path/to/file.js --output path/to/file.fn-inliner.js
337
+ ```
338
+
339
+ Args:
340
+ - `--o, --output <file>`
341
+ Output file path
342
+
343
+ Notes:
344
+ - Only inlines functions that return a single expression.
345
+ - Skips return expressions with assignments, functions, blocks, or sequences.
346
+
347
+ ---
348
+
324
349
  ### `expose remove-unused`
325
-
326
- Remove unused variabless.
350
+
351
+ Remove unused variabless.
327
352
  ```js
328
353
  // before
329
354
  var a = 0, b = 1;
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 dirname9, join as join9 } from "path";
5
+ import { dirname as dirname10, join as join10 } from "path";
6
6
  import { fileURLToPath } from "url";
7
7
  import chalk4 from "chalk";
8
8
 
@@ -746,11 +746,7 @@ var expand_object_default = createCommand((program2) => {
746
746
  }
747
747
  const loader = loading4("Expanding object access...").start();
748
748
  try {
749
- const { code: output, replacedCount } = await expandObjectAccess(
750
- fileContent,
751
- filename,
752
- targetName
753
- );
749
+ const { code: output, replacedCount } = await expandObjectAccess(fileContent, filename, targetName);
754
750
  writeFileSync3(outputPath, output, "utf8");
755
751
  loader.succeed(
756
752
  `Saved expand-object file to: ${outputPath} (${diff(fileContent, output).length} lines changed, ${replacedCount} replacements)`
@@ -932,7 +928,11 @@ var object_packer_default = createCommand((program2) => {
932
928
  }
933
929
  const loader = loading5("Packing object properties...").start();
934
930
  try {
935
- const { code: output, packedCount, removedStatements } = packObjectProperties(fileContent, filename);
931
+ const {
932
+ code: output,
933
+ packedCount,
934
+ removedStatements
935
+ } = packObjectProperties(fileContent, filename);
936
936
  writeFileSync4(outputPath, output, "utf8");
937
937
  loader.succeed(
938
938
  `Saved object-packer file to: ${outputPath} (${diff(fileContent, output).length} lines changed, ${packedCount} properties packed, ${removedStatements} statements removed)`
@@ -1525,7 +1525,11 @@ var remove_reassign_default = createCommand((program2) => {
1525
1525
  }
1526
1526
  const loader = loading8("Removing reassign aliases...").start();
1527
1527
  try {
1528
- const { code: output, aliasReplacedCount, wrapperReplacedCount } = removeReassign(fileContent, filename);
1528
+ const {
1529
+ code: output,
1530
+ aliasReplacedCount,
1531
+ wrapperReplacedCount
1532
+ } = removeReassign(fileContent, filename);
1529
1533
  writeFileSync7(outputPath, output, "utf8");
1530
1534
  loader.succeed(
1531
1535
  `Saved remove-reassign file to: ${outputPath} (${diff(fileContent, output).length} lines changed, ${aliasReplacedCount} aliases, ${wrapperReplacedCount} calls inlined)`
@@ -1657,6 +1661,188 @@ var remove_unused_default = createCommand((program2) => {
1657
1661
  );
1658
1662
  });
1659
1663
 
1664
+ // commands/fn-inliner/index.ts
1665
+ import { readFileSync as readFileSync10, writeFileSync as writeFileSync9 } from "fs";
1666
+ import { basename as basename9, dirname as dirname9, extname as extname9, join as join9 } from "path";
1667
+ import { parse as parse10 } from "@babel/parser";
1668
+ import traverse9 from "@babel/traverse";
1669
+ import generate9 from "@babel/generator";
1670
+ import * as t8 from "@babel/types";
1671
+ import loading10 from "loading-cli";
1672
+ var walk = patchDefault(traverse9);
1673
+ var createDefaultOutputPath9 = (inputPath) => {
1674
+ const ext = extname9(inputPath);
1675
+ if (!ext) {
1676
+ return `${inputPath}.fn-inliner.js`;
1677
+ }
1678
+ const base = basename9(inputPath, ext);
1679
+ return join9(dirname9(inputPath), `${base}.fn-inliner${ext}`);
1680
+ };
1681
+ var isProxyFunctionExpression = (node) => {
1682
+ 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));
1683
+ };
1684
+ var isProxyValue = (node) => {
1685
+ if (t8.isFunction(node) || t8.isBlockStatement(node) || t8.isSequenceExpression(node)) {
1686
+ return false;
1687
+ }
1688
+ let isValid = true;
1689
+ walk(node, {
1690
+ "SequenceExpression|BlockStatement|Function|AssignmentExpression"(path) {
1691
+ isValid = false;
1692
+ path.stop();
1693
+ },
1694
+ noScope: true
1695
+ });
1696
+ return isValid;
1697
+ };
1698
+ var copyExpression = (expression) => {
1699
+ return t8.cloneNode(expression, true);
1700
+ };
1701
+ var ProxyFunction = class {
1702
+ expression;
1703
+ constructor(expression) {
1704
+ this.expression = expression;
1705
+ }
1706
+ getReplacement(args) {
1707
+ 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");
1708
+ this.replaceParameters(expression, args);
1709
+ return expression;
1710
+ }
1711
+ replaceParameters(expression, args) {
1712
+ const paramMap = new Map(
1713
+ this.expression.params.map((param, index) => [
1714
+ param.name,
1715
+ args[index] ?? t8.identifier("undefined")
1716
+ ])
1717
+ );
1718
+ const pathsToReplace = [];
1719
+ walk(expression, {
1720
+ enter(path) {
1721
+ if (t8.isIdentifier(path.node) && !(path.parentPath?.isMemberExpression() && path.key === "property") && paramMap.has(path.node.name)) {
1722
+ const replacement = paramMap.get(path.node.name);
1723
+ pathsToReplace.push([path, replacement]);
1724
+ }
1725
+ },
1726
+ noScope: true
1727
+ });
1728
+ for (const [path, replacement] of pathsToReplace) {
1729
+ path.replaceWith(t8.cloneNode(replacement, true));
1730
+ }
1731
+ }
1732
+ };
1733
+ var ProxyFunctionVariable = class extends ProxyFunction {
1734
+ binding;
1735
+ constructor(binding, expression) {
1736
+ super(expression);
1737
+ this.binding = binding;
1738
+ }
1739
+ getCalls() {
1740
+ return this.binding.referencePaths;
1741
+ }
1742
+ replaceCall(path) {
1743
+ if (!path.parentPath || !path.parentPath.isCallExpression() || path.key !== "callee") {
1744
+ return false;
1745
+ }
1746
+ const argumentNodes = path.parentPath.node.arguments;
1747
+ const args = [];
1748
+ for (const argument of argumentNodes) {
1749
+ if (!t8.isExpression(argument)) {
1750
+ return false;
1751
+ }
1752
+ args.push(t8.cloneNode(argument, true));
1753
+ }
1754
+ const expression = this.getReplacement(args);
1755
+ path.parentPath.replaceWith(expression);
1756
+ return true;
1757
+ }
1758
+ };
1759
+ var collectProxyFunctions = (ast) => {
1760
+ const proxies = [];
1761
+ walk(ast, {
1762
+ FunctionDeclaration(path) {
1763
+ if (!path.node.id) return;
1764
+ if (!isProxyFunctionExpression(path.node)) return;
1765
+ const binding = path.scope.getBinding(path.node.id.name);
1766
+ if (!binding || !binding.constant) return;
1767
+ proxies.push(new ProxyFunctionVariable(binding, path.node));
1768
+ },
1769
+ VariableDeclarator(path) {
1770
+ if (!t8.isIdentifier(path.node.id)) return;
1771
+ const init = path.node.init;
1772
+ if (!init || !isProxyFunctionExpression(init)) return;
1773
+ const binding = path.scope.getBinding(path.node.id.name);
1774
+ if (!binding || !binding.constant) return;
1775
+ proxies.push(new ProxyFunctionVariable(binding, init));
1776
+ }
1777
+ });
1778
+ return proxies;
1779
+ };
1780
+ var inlineProxyFunctions = (code, filename) => {
1781
+ const ast = parse10(code, createParseOptions(filename));
1782
+ const proxies = collectProxyFunctions(ast);
1783
+ let replacedCount = 0;
1784
+ for (const proxy of proxies) {
1785
+ for (const referencePath of proxy.getCalls()) {
1786
+ if (referencePath.removed) continue;
1787
+ if (proxy.replaceCall(referencePath)) {
1788
+ replacedCount += 1;
1789
+ }
1790
+ }
1791
+ }
1792
+ return {
1793
+ code: patchDefault(generate9)(ast).code,
1794
+ replacedCount
1795
+ };
1796
+ };
1797
+ var fn_inliner_default = createCommand((program2) => {
1798
+ program2.command("fn-inliner").description("Inline proxy function calls into 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(
1799
+ async (fileArgument, options) => {
1800
+ await timeout(
1801
+ async ({ finish }) => {
1802
+ const filename = fileArgument ?? options.file ?? await createPrompt("Enter the file path:");
1803
+ if (!filename) {
1804
+ showError("No file provided");
1805
+ return finish();
1806
+ }
1807
+ try {
1808
+ const fileContent = readFileSync10(filename, "utf8");
1809
+ const defaultOutputPath = createDefaultOutputPath9(filename);
1810
+ let outputPath = options.output;
1811
+ if (!outputPath) {
1812
+ const promptPath = (await createPrompt("Enter the output file path:"))?.trim();
1813
+ outputPath = promptPath || defaultOutputPath;
1814
+ }
1815
+ const loader = loading10("Inlining proxy functions...").start();
1816
+ try {
1817
+ const { code: output, replacedCount } = inlineProxyFunctions(
1818
+ fileContent,
1819
+ filename
1820
+ );
1821
+ writeFileSync9(outputPath, output, "utf8");
1822
+ loader.succeed(
1823
+ `Saved fn-inliner file to: ${outputPath} (${diff(fileContent, output).length} lines changed, ${replacedCount} replacements)`
1824
+ );
1825
+ return finish();
1826
+ } catch (error) {
1827
+ loader.fail("Failed to apply fn-inliner transform");
1828
+ showError(
1829
+ `Error transforming file '${filename}': ${error instanceof Error ? error.message : "Unknown error"}`
1830
+ );
1831
+ return finish();
1832
+ }
1833
+ } catch (error) {
1834
+ showError(
1835
+ `Error reading file '${filename}': ${error instanceof Error ? error.message : "Unknown error"}`
1836
+ );
1837
+ return finish();
1838
+ }
1839
+ },
1840
+ options.unlimited ? null : 120 * 1e3
1841
+ );
1842
+ }
1843
+ );
1844
+ });
1845
+
1660
1846
  // utils/cli/showCredit.ts
1661
1847
  import chalk3 from "chalk";
1662
1848
  var beautify = (strings, ...values) => {
@@ -1681,10 +1867,10 @@ var calmGradienrain = (text) => {
1681
1867
  const endHue = 300;
1682
1868
  const saturation = 0.45;
1683
1869
  const value = 0.8;
1684
- const ease = (t8) => t8 * t8 * (3 - 2 * t8);
1870
+ const ease = (t9) => t9 * t9 * (3 - 2 * t9);
1685
1871
  return text.split("").map((char, i) => {
1686
- const t8 = ease(i / Math.max(text.length - 1, 1));
1687
- const hue = startHue + (endHue - startHue) * t8;
1872
+ const t9 = ease(i / Math.max(text.length - 1, 1));
1873
+ const hue = startHue + (endHue - startHue) * t9;
1688
1874
  const c = value * saturation;
1689
1875
  const h = hue / 60;
1690
1876
  const x = c * (1 - Math.abs(h % 2 - 1));
@@ -1708,10 +1894,10 @@ ${calmGradienrain(`Expose Kit v${VERSION}`)}
1708
1894
  `;
1709
1895
 
1710
1896
  // index.ts
1711
- import { readFileSync as readFileSync10 } from "fs";
1897
+ import { readFileSync as readFileSync11 } from "fs";
1712
1898
  var __filename = fileURLToPath(import.meta.url);
1713
- var __dirname = dirname9(__filename);
1714
- var pkg = JSON.parse(readFileSync10(join9(__dirname, "package.json"), "utf8"));
1899
+ var __dirname = dirname10(__filename);
1900
+ var pkg = JSON.parse(readFileSync11(join10(__dirname, "package.json"), "utf8"));
1715
1901
  console.log(showCredit(pkg.version));
1716
1902
  console.log();
1717
1903
  var program = new Command();
@@ -1729,6 +1915,7 @@ var commands = [
1729
1915
  pre_evaluate_default,
1730
1916
  remove_updater_default,
1731
1917
  remove_reassign_default,
1918
+ fn_inliner_default,
1732
1919
  remove_unused_default
1733
1920
  ];
1734
1921
  for (const command of commands) {
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expose-kit",
3
- "version": "0.8.0",
3
+ "version": "0.9.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.8.0",
3
+ "version": "0.9.0",
4
4
  "type": "module",
5
5
  "private": false,
6
6
  "author": "EdamAmex <edame8080@gmail.com> (https://github.com/EdamAme-x)",