@hangox/mg-cli 1.0.4 → 1.0.6

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/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.6
package/dist/cli.js CHANGED
@@ -18,9 +18,16 @@ import { dirname, resolve, isAbsolute } from "path";
18
18
  // src/shared/constants.ts
19
19
  import { homedir } from "os";
20
20
  import { join } from "path";
21
- var DEFAULT_PORT = 9527;
22
- var PORT_RANGE_START = 9527;
23
- var PORT_RANGE_END = 9536;
21
+ var IS_DEV_MODE = process.env.MG_DEV_MODE === "true";
22
+ var PROD_DEFAULT_PORT = 9527;
23
+ var PROD_PORT_RANGE_START = 9527;
24
+ var PROD_PORT_RANGE_END = 9536;
25
+ var DEV_DEFAULT_PORT = 19527;
26
+ var DEV_PORT_RANGE_START = 19527;
27
+ var DEV_PORT_RANGE_END = 19536;
28
+ var DEFAULT_PORT = IS_DEV_MODE ? DEV_DEFAULT_PORT : PROD_DEFAULT_PORT;
29
+ var PORT_RANGE_START = IS_DEV_MODE ? DEV_PORT_RANGE_START : PROD_PORT_RANGE_START;
30
+ var PORT_RANGE_END = IS_DEV_MODE ? DEV_PORT_RANGE_END : PROD_PORT_RANGE_END;
24
31
  var PORT_SCAN_TIMEOUT = 500;
25
32
  var CONFIG_DIR = join(homedir(), ".mg-plugin");
26
33
  var SERVER_INFO_FILE = join(CONFIG_DIR, "server.json");
@@ -346,7 +353,7 @@ var ErrorNames = {
346
353
  var ErrorMessages = {
347
354
  ["E001" /* CONNECTION_FAILED */]: "\u65E0\u6CD5\u8FDE\u63A5\u5230 MG Server",
348
355
  ["E002" /* CONNECTION_TIMEOUT */]: "\u8FDE\u63A5\u8D85\u65F6",
349
- ["E003" /* NO_PAGE_CONNECTED */]: "\u6CA1\u6709 MasterGo \u9875\u9762\u8FDE\u63A5\u5230 Server",
356
+ ["E003" /* NO_PAGE_CONNECTED */]: "\u6CA1\u6709 MasterGo \u9875\u9762\u8FDE\u63A5\u5230 Server\u3002\u8BF7\u5B89\u88C5 MG Plugin \u6D4F\u89C8\u5668\u6269\u5C55: https://chromewebstore.google.com/detail/mg-plugin/ddhihanlpcdneicohnglnaliefnkaeja",
350
357
  ["E004" /* PAGE_NOT_FOUND */]: "\u672A\u627E\u5230\u5339\u914D\u7684\u9875\u9762",
351
358
  ["E005" /* NODE_NOT_FOUND */]: "\u8282\u70B9\u4E0D\u5B58\u5728",
352
359
  ["E006" /* NO_SELECTION */]: "\u6CA1\u6709\u9009\u4E2D\u4EFB\u4F55\u8282\u70B9",
@@ -648,7 +655,7 @@ var RequestHandler = class {
648
655
  } else {
649
656
  provider = this.connectionManager.getFirstProvider();
650
657
  if (!provider) {
651
- this.sendError(consumer, requestId, "E003" /* NO_PAGE_CONNECTED */, "\u6CA1\u6709\u9875\u9762\u8FDE\u63A5\u5230 Server");
658
+ this.sendError(consumer, requestId, "E003" /* NO_PAGE_CONNECTED */, ErrorMessages["E003" /* NO_PAGE_CONNECTED */]);
652
659
  return;
653
660
  }
654
661
  }
@@ -766,13 +773,26 @@ function getVersion() {
766
773
  try {
767
774
  const currentFile = fileURLToPath(import.meta.url);
768
775
  const currentDir = dirname3(currentFile);
769
- const possiblePaths = [
776
+ const versionFilePaths = [
777
+ join2(currentDir, "..", "VERSION"),
778
+ // dist/xxx.js -> ../VERSION
779
+ join2(currentDir, "..", "..", "VERSION")
780
+ // src/shared/version.ts -> ../../VERSION
781
+ ];
782
+ for (const versionFilePath of versionFilePaths) {
783
+ if (existsSync3(versionFilePath)) {
784
+ const version = readFileSync2(versionFilePath, "utf-8").trim();
785
+ if (version) {
786
+ cachedVersion = version;
787
+ return cachedVersion;
788
+ }
789
+ }
790
+ }
791
+ const packageJsonPaths = [
770
792
  join2(currentDir, "..", "package.json"),
771
- // dist/xxx.js -> ../package.json
772
793
  join2(currentDir, "..", "..", "package.json")
773
- // src/shared/version.ts -> ../../package.json
774
794
  ];
775
- for (const packageJsonPath of possiblePaths) {
795
+ for (const packageJsonPath of packageJsonPaths) {
776
796
  if (existsSync3(packageJsonPath)) {
777
797
  const packageJson = JSON.parse(readFileSync2(packageJsonPath, "utf-8"));
778
798
  if (packageJson.name === "@hangox/mg-cli") {
@@ -1459,7 +1479,8 @@ function createServerCommand() {
1459
1479
  } else {
1460
1480
  console.log(``);
1461
1481
  console.log(`\u5DF2\u8FDE\u63A5\u9875\u9762: \u65E0`);
1462
- console.log(`\u63D0\u793A: \u8BF7\u5728 Chrome \u4E2D\u6253\u5F00 MasterGo \u9875\u9762\u5E76\u786E\u4FDD\u63D2\u4EF6\u5DF2\u542F\u7528`);
1482
+ console.log(`\u63D0\u793A: \u8BF7\u5B89\u88C5 MG Plugin \u6D4F\u89C8\u5668\u6269\u5C55\u5E76\u5728 Chrome \u4E2D\u6253\u5F00 MasterGo \u9875\u9762`);
1483
+ console.log(` \u63D2\u4EF6\u5730\u5740: https://chromewebstore.google.com/detail/mg-plugin/ddhihanlpcdneicohnglnaliefnkaeja`);
1463
1484
  }
1464
1485
  } catch {
1465
1486
  console.log("MG Server \u72B6\u6001: \u8FD0\u884C\u4E2D \u2713");
@@ -1644,18 +1665,19 @@ async function handleGetAllNodes(options) {
1644
1665
 
1645
1666
  // src/cli/commands/export-image.ts
1646
1667
  import { Command as Command5 } from "commander";
1647
- import { writeFileSync as writeFileSync5 } from "fs";
1648
- import { resolve as resolve5, dirname as dirname8, extname } from "path";
1668
+ import { writeFileSync as writeFileSync5, unlinkSync as unlinkSync2 } from "fs";
1669
+ import { resolve as resolve5, dirname as dirname8, extname, basename } from "path";
1649
1670
  import { mkdirSync as mkdirSync6 } from "fs";
1650
1671
  import { tmpdir } from "os";
1672
+ import { vdConvert } from "vd-tool";
1651
1673
  function createExportImageCommand() {
1652
- return new Command5("export_image").description("\u5BFC\u51FA MasterGo \u8282\u70B9\u4E3A\u56FE\u7247\u6587\u4EF6\u3002\u5F3A\u70C8\u5EFA\u8BAE\u6307\u5B9A --output\uFF0C\u5426\u5219\u4FDD\u5B58\u5230\u4E34\u65F6\u76EE\u5F55\u53EF\u80FD\u88AB\u7CFB\u7EDF\u6E05\u7406").option("--output <path>", "\u8F93\u51FA\u6587\u4EF6\u8DEF\u5F84\u3002\u5F3A\u70C8\u5EFA\u8BAE\u6307\u5B9A\uFF0C\u5426\u5219\u4FDD\u5B58\u5230\u7CFB\u7EDF\u4E34\u65F6\u76EE\u5F55\u53EF\u80FD\u88AB\u6E05\u7406").option("--link <mgp-link>", "mgp:// \u534F\u8BAE\u94FE\u63A5\u3002\u4E0E --nodeId/--domain/--fileId \u4E8C\u9009\u4E00").option("--nodeId <id>", "\u8282\u70B9 ID\uFF0C\u683C\u5F0F\u5982 123:456\u3002\u4E0E --domain/--fileId \u914D\u5408\u4F7F\u7528").option("--domain <domain>", "MasterGo \u57DF\u540D\uFF0C\u9ED8\u8BA4 mastergo.netease.com", "mastergo.netease.com").option("--fileId <id>", "\u6587\u4EF6 ID\uFF08\u7EAF\u6570\u5B57\uFF09\uFF0C\u4E0E --domain \u914D\u5408\u6307\u5B9A\u76EE\u6807\u9875\u9762").option("--format <type>", "\u5BFC\u51FA\u683C\u5F0F\uFF1APNG\uFF08\u65E0\u635F\u900F\u660E\uFF09\u3001JPG\uFF08\u6709\u635F\uFF09\u3001SVG\uFF08\u77E2\u91CF\uFF09\u3001PDF\u3001WEBP", "PNG").option("--scale <number>", "\u7F29\u653E\u500D\u7387\uFF08\u5982 1\u30012\u30013\uFF09\u3002\u4E0E width/height \u4E92\u65A5").option("--width <number>", "\u56FA\u5B9A\u5BBD\u5EA6\uFF08\u50CF\u7D20\uFF09\u3002\u4E0E scale/height \u4E92\u65A5").option("--height <number>", "\u56FA\u5B9A\u9AD8\u5EA6\uFF08\u50CF\u7D20\uFF09\u3002\u4E0E scale/width \u4E92\u65A5").option("--useAbsoluteBounds", "\u4F7F\u7528\u5B8C\u6574\u5C3A\u5BF8\u3002true: \u5305\u542B\u88AB\u88C1\u526A\u90E8\u5206\uFF0Cfalse: \u53EA\u5BFC\u51FA\u53EF\u89C1\u533A\u57DF", false).option("--no-use-render-bounds", "\u4E0D\u5305\u542B\u7279\u6548\u548C\u5916\u63CF\u8FB9\u3002\u9ED8\u8BA4\u5305\u542B\u9634\u5F71\u3001\u5916\u63CF\u8FB9\u7B49").option("--no-auto-start", "\u7981\u7528\u81EA\u52A8\u542F\u52A8 Server").option("--no-retry", "\u7981\u7528\u81EA\u52A8\u91CD\u8BD5").action(async (options) => {
1674
+ return new Command5("export_image").description("\u5BFC\u51FA MasterGo \u8282\u70B9\u4E3A\u56FE\u7247\u6587\u4EF6\u3002\u5F3A\u70C8\u5EFA\u8BAE\u6307\u5B9A --output\uFF0C\u5426\u5219\u4FDD\u5B58\u5230\u4E34\u65F6\u76EE\u5F55\u53EF\u80FD\u88AB\u7CFB\u7EDF\u6E05\u7406").option("--output <path>", "\u8F93\u51FA\u6587\u4EF6\u8DEF\u5F84\u3002\u5F3A\u70C8\u5EFA\u8BAE\u6307\u5B9A\uFF0C\u5426\u5219\u4FDD\u5B58\u5230\u7CFB\u7EDF\u4E34\u65F6\u76EE\u5F55\u53EF\u80FD\u88AB\u6E05\u7406").option("--link <mgp-link>", "mgp:// \u534F\u8BAE\u94FE\u63A5\u3002\u4E0E --nodeId/--domain/--fileId \u4E8C\u9009\u4E00").option("--nodeId <id>", "\u8282\u70B9 ID\uFF0C\u683C\u5F0F\u5982 123:456\u3002\u4E0E --domain/--fileId \u914D\u5408\u4F7F\u7528").option("--domain <domain>", "MasterGo \u57DF\u540D\uFF0C\u9ED8\u8BA4 mastergo.netease.com", "mastergo.netease.com").option("--fileId <id>", "\u6587\u4EF6 ID\uFF08\u7EAF\u6570\u5B57\uFF09\uFF0C\u4E0E --domain \u914D\u5408\u6307\u5B9A\u76EE\u6807\u9875\u9762").option("--format <type>", "\u5BFC\u51FA\u683C\u5F0F\uFF1APNG\uFF08\u65E0\u635F\u900F\u660E\uFF09\u3001JPG\uFF08\u6709\u635F\uFF09\u3001SVG\uFF08\u77E2\u91CF\uFF09\u3001PDF\u3001WEBP\u3001VECTOR\uFF08Android VectorDrawable\uFF09", "PNG").option("--scale <number>", "\u7F29\u653E\u500D\u7387\uFF08\u5982 1\u30012\u30013\uFF09\u3002\u4E0E width/height \u4E92\u65A5").option("--width <number>", "\u56FA\u5B9A\u5BBD\u5EA6\uFF08\u50CF\u7D20\uFF09\u3002\u4E0E scale/height \u4E92\u65A5").option("--height <number>", "\u56FA\u5B9A\u9AD8\u5EA6\uFF08\u50CF\u7D20\uFF09\u3002\u4E0E scale/width \u4E92\u65A5").option("--useAbsoluteBounds", "\u4F7F\u7528\u5B8C\u6574\u5C3A\u5BF8\u3002true: \u5305\u542B\u88AB\u88C1\u526A\u90E8\u5206\uFF0Cfalse: \u53EA\u5BFC\u51FA\u53EF\u89C1\u533A\u57DF", false).option("--no-use-render-bounds", "\u4E0D\u5305\u542B\u7279\u6548\u548C\u5916\u63CF\u8FB9\u3002\u9ED8\u8BA4\u5305\u542B\u9634\u5F71\u3001\u5916\u63CF\u8FB9\u7B49").option("--no-auto-start", "\u7981\u7528\u81EA\u52A8\u542F\u52A8 Server").option("--no-retry", "\u7981\u7528\u81EA\u52A8\u91CD\u8BD5").action(async (options) => {
1653
1675
  await handleExportImage(options);
1654
1676
  });
1655
1677
  }
1656
1678
  async function handleExportImage(options) {
1657
1679
  const format = options.format?.toUpperCase() || "PNG";
1658
- const validFormats = ["PNG", "JPG", "SVG", "PDF", "WEBP"];
1680
+ const validFormats = ["PNG", "JPG", "SVG", "PDF", "WEBP", "VECTOR"];
1659
1681
  if (!validFormats.includes(format)) {
1660
1682
  console.error(`\u9519\u8BEF: \u4E0D\u652F\u6301\u7684\u683C\u5F0F "${options.format}"`);
1661
1683
  console.error(`\u652F\u6301\u7684\u683C\u5F0F: ${validFormats.join(", ")}`);
@@ -1697,8 +1719,10 @@ async function handleExportImage(options) {
1697
1719
  });
1698
1720
  try {
1699
1721
  await client.connect();
1722
+ const isVectorFormat = format === "VECTOR";
1723
+ const requestFormat = isVectorFormat ? "SVG" : format;
1700
1724
  const params = {
1701
- format,
1725
+ format: requestFormat,
1702
1726
  useAbsoluteBounds: options.useAbsoluteBounds || false,
1703
1727
  useRenderBounds: options.useRenderBounds !== false
1704
1728
  };
@@ -1734,9 +1758,38 @@ async function handleExportImage(options) {
1734
1758
  const outputDir = dirname8(outputPath);
1735
1759
  mkdirSync6(outputDir, { recursive: true });
1736
1760
  const buffer = Buffer.from(response.data, "base64");
1737
- writeFileSync5(outputPath, buffer);
1738
- const sizeKB = (buffer.length / 1024).toFixed(2);
1739
- console.log(`\u6587\u4EF6\u8DEF\u5F84: ${outputPath}`);
1761
+ let finalPath = outputPath;
1762
+ let finalSize = buffer.length;
1763
+ if (isVectorFormat) {
1764
+ const tempSvgPath = resolve5(tmpdir(), `temp_${Date.now()}.svg`);
1765
+ writeFileSync5(tempSvgPath, buffer);
1766
+ try {
1767
+ const vectorOutputDir = dirname8(outputPath);
1768
+ const convertedPath = await convertSvgToVector(tempSvgPath, vectorOutputDir);
1769
+ const expectedOutputName = basename(tempSvgPath, ".svg") + ".xml";
1770
+ const expectedOutputPath = resolve5(vectorOutputDir, expectedOutputName);
1771
+ if (expectedOutputPath !== outputPath) {
1772
+ const { renameSync, existsSync: existsSync4 } = await import("fs");
1773
+ if (existsSync4(expectedOutputPath)) {
1774
+ renameSync(expectedOutputPath, outputPath);
1775
+ } else if (existsSync4(convertedPath)) {
1776
+ renameSync(convertedPath, outputPath);
1777
+ }
1778
+ }
1779
+ const { statSync } = await import("fs");
1780
+ finalSize = statSync(outputPath).size;
1781
+ finalPath = outputPath;
1782
+ } finally {
1783
+ try {
1784
+ unlinkSync2(tempSvgPath);
1785
+ } catch {
1786
+ }
1787
+ }
1788
+ } else {
1789
+ writeFileSync5(outputPath, buffer);
1790
+ }
1791
+ const sizeKB = (finalSize / 1024).toFixed(2);
1792
+ console.log(`\u6587\u4EF6\u8DEF\u5F84: ${finalPath}`);
1740
1793
  if (options.link) {
1741
1794
  console.log(`Link: ${options.link}`);
1742
1795
  }
@@ -1745,8 +1798,8 @@ async function handleExportImage(options) {
1745
1798
  } else {
1746
1799
  console.log("\u8282\u70B9 ID: (\u9009\u4E2D\u7684\u8282\u70B9)");
1747
1800
  }
1748
- console.log(`\u5BFC\u51FA\u683C\u5F0F: ${format}`);
1749
- console.log(`\u6587\u4EF6\u5927\u5C0F: ${buffer.length.toLocaleString()} \u5B57\u8282 (\u7EA6 ${sizeKB} KB)`);
1801
+ console.log(`\u5BFC\u51FA\u683C\u5F0F: ${format}${isVectorFormat ? " (Android VectorDrawable)" : ""}`);
1802
+ console.log(`\u6587\u4EF6\u5927\u5C0F: ${finalSize.toLocaleString()} \u5B57\u8282 (\u7EA6 ${sizeKB} KB)`);
1750
1803
  } catch (error) {
1751
1804
  if (error instanceof MGError) {
1752
1805
  console.error(`\u9519\u8BEF [${error.code}]: ${error.message}`);
@@ -1764,10 +1817,35 @@ function getExtension(format) {
1764
1817
  JPG: ".jpg",
1765
1818
  SVG: ".svg",
1766
1819
  PDF: ".pdf",
1767
- WEBP: ".webp"
1820
+ WEBP: ".webp",
1821
+ VECTOR: ".xml"
1768
1822
  };
1769
1823
  return extensions[format];
1770
1824
  }
1825
+ async function convertSvgToVector(svgPath, outputDir) {
1826
+ try {
1827
+ const result = await vdConvert(svgPath, {
1828
+ outDir: outputDir
1829
+ });
1830
+ if (result.errors && result.errors.length > 0) {
1831
+ throw new Error(`VectorDrawable \u8F6C\u6362\u5931\u8D25: ${result.errors.join(", ")}`);
1832
+ }
1833
+ if (result.warnings && result.warnings.length > 0) {
1834
+ console.log(`\u8B66\u544A: ${result.warnings.join(", ")}`);
1835
+ }
1836
+ return result.output;
1837
+ } catch (error) {
1838
+ if (error instanceof Error) {
1839
+ if (error.message.includes("ENOENT") || error.message.includes("java")) {
1840
+ throw new Error(
1841
+ "VectorDrawable \u8F6C\u6362\u9700\u8981 Java 8 \u6216\u66F4\u9AD8\u7248\u672C\u3002\n\u8BF7\u5B89\u88C5 Java: https://adoptium.net/ \u6216 brew install openjdk"
1842
+ );
1843
+ }
1844
+ throw error;
1845
+ }
1846
+ throw new Error(`VectorDrawable \u8F6C\u6362\u5931\u8D25: ${error}`);
1847
+ }
1848
+ }
1771
1849
 
1772
1850
  // src/cli/commands/execute-code.ts
1773
1851
  import { Command as Command6 } from "commander";