@hangox/mg-cli 1.0.6 → 1.0.7

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/dist/cli.js CHANGED
@@ -103,27 +103,44 @@ function parseMgpLink(link) {
103
103
  const queryString = urlPart.slice(questionMarkIndex + 1);
104
104
  const params = new URLSearchParams(queryString);
105
105
  const encodedNodeId = params.get("nodeId");
106
- if (!encodedNodeId) {
106
+ const encodedPageId = params.get("pageId");
107
+ if (!encodedNodeId && !encodedPageId) {
107
108
  return null;
108
109
  }
109
- const nodeId = decodeURIComponent(encodedNodeId);
110
- if (!/^(\d+:\d+)(\/\d+:\d+)*$/.test(nodeId)) {
110
+ if (encodedNodeId && encodedPageId) {
111
111
  return null;
112
112
  }
113
- const encodedNodePath = params.get("nodePath");
114
- let nodePath;
115
- if (encodedNodePath) {
116
- const decodedNodePath = decodeURIComponent(encodedNodePath);
117
- nodePath = decodedNodePath.split("/").filter(Boolean);
118
- if (!nodePath.every((segment) => /^\d+:\d+$/.test(segment))) {
113
+ if (encodedNodeId) {
114
+ const nodeId = decodeURIComponent(encodedNodeId);
115
+ if (!/^(\d+:\d+)(\/\d+:\d+)*$/.test(nodeId)) {
119
116
  return null;
120
117
  }
118
+ const encodedNodePath = params.get("nodePath");
119
+ let nodePath;
120
+ if (encodedNodePath) {
121
+ const decodedNodePath = decodeURIComponent(encodedNodePath);
122
+ nodePath = decodedNodePath.split("/").filter(Boolean);
123
+ if (!nodePath.every((segment) => /^\d+:\d+$/.test(segment))) {
124
+ return null;
125
+ }
126
+ }
127
+ return {
128
+ pageUrl,
129
+ nodeId,
130
+ nodePath
131
+ };
121
132
  }
122
- return {
123
- pageUrl,
124
- nodeId,
125
- nodePath
126
- };
133
+ if (encodedPageId) {
134
+ const pageId = decodeURIComponent(encodedPageId);
135
+ if (!/^\d+:\d+$/.test(pageId)) {
136
+ return null;
137
+ }
138
+ return {
139
+ pageUrl,
140
+ pageId
141
+ };
142
+ }
143
+ return null;
127
144
  } catch {
128
145
  return null;
129
146
  }
@@ -477,7 +494,7 @@ function createLogger(options) {
477
494
  // src/server/connection-manager.ts
478
495
  var ConnectionManager = class {
479
496
  logger;
480
- /** Provider 连接(按页面 URL 索引) */
497
+ /** Provider 连接(按页面 URL 索引,支持同 URL 多个连接) */
481
498
  providers = /* @__PURE__ */ new Map();
482
499
  /** Consumer 连接 */
483
500
  consumers = /* @__PURE__ */ new Map();
@@ -513,7 +530,8 @@ var ConnectionManager = class {
513
530
  */
514
531
  checkHeartbeats() {
515
532
  const now = Date.now();
516
- for (const [id, ws] of this.allConnections) {
533
+ const entries = Array.from(this.allConnections.entries());
534
+ for (const [id, ws] of entries) {
517
535
  const lastActive = ws.connectionInfo.lastActiveAt.getTime();
518
536
  const elapsed = now - lastActive;
519
537
  if (elapsed > HEARTBEAT_TIMEOUT) {
@@ -543,14 +561,10 @@ var ConnectionManager = class {
543
561
  managedWs.isAlive = true;
544
562
  this.allConnections.set(connectionId, managedWs);
545
563
  if (type === "provider" /* PROVIDER */ && pageUrl) {
546
- const existing = this.providers.get(pageUrl);
547
- if (existing) {
548
- this.logger.info(`\u9875\u9762 ${pageUrl} \u5DF2\u6709\u8FDE\u63A5\uFF0C\u66FF\u6362\u4E3A\u65B0\u8FDE\u63A5`);
549
- this.removeConnection(existing);
550
- existing.close();
551
- }
552
- this.providers.set(pageUrl, managedWs);
553
- this.logger.info(`Provider \u8FDE\u63A5: ${pageUrl}`);
564
+ const existing = this.providers.get(pageUrl) || [];
565
+ existing.push(managedWs);
566
+ this.providers.set(pageUrl, existing);
567
+ this.logger.info(`Provider \u8FDE\u63A5: ${pageUrl} (\u5F53\u524D\u8BE5\u9875\u9762\u8FDE\u63A5\u6570: ${existing.length})`);
554
568
  } else if (type === "consumer" /* CONSUMER */) {
555
569
  this.consumers.set(connectionId, managedWs);
556
570
  this.logger.info(`Consumer \u8FDE\u63A5: ${connectionId}`);
@@ -564,8 +578,17 @@ var ConnectionManager = class {
564
578
  const { connectionId, connectionInfo } = ws;
565
579
  this.allConnections.delete(connectionId);
566
580
  if (connectionInfo.type === "provider" /* PROVIDER */ && connectionInfo.pageUrl) {
567
- this.providers.delete(connectionInfo.pageUrl);
568
- this.logger.info(`Provider \u65AD\u5F00: ${connectionInfo.pageUrl}`);
581
+ const connections = this.providers.get(connectionInfo.pageUrl);
582
+ if (connections) {
583
+ const index = connections.findIndex((c) => c.connectionId === connectionId);
584
+ if (index !== -1) {
585
+ connections.splice(index, 1);
586
+ if (connections.length === 0) {
587
+ this.providers.delete(connectionInfo.pageUrl);
588
+ }
589
+ }
590
+ }
591
+ this.logger.info(`Provider \u65AD\u5F00: ${connectionInfo.pageUrl} (\u8FDE\u63A5ID: ${connectionId})`);
569
592
  } else if (connectionInfo.type === "consumer" /* CONSUMER */) {
570
593
  this.consumers.delete(connectionId);
571
594
  this.logger.info(`Consumer \u65AD\u5F00: ${connectionId}`);
@@ -579,31 +602,48 @@ var ConnectionManager = class {
579
602
  ws.isAlive = true;
580
603
  }
581
604
  /**
582
- * 根据页面 URL 查找 Provider
605
+ * 根据页面 URL 查找 Provider(返回第一个可用的连接)
583
606
  */
584
607
  findProviderByPageUrl(pageUrl) {
585
- return this.providers.get(pageUrl);
608
+ const connections = this.providers.get(pageUrl);
609
+ return connections?.[0];
586
610
  }
587
611
  /**
588
612
  * 获取第一个可用的 Provider
589
613
  */
590
614
  getFirstProvider() {
591
- const iterator = this.providers.values();
592
- const first = iterator.next();
593
- return first.value;
615
+ const allConnections = Array.from(this.providers.values());
616
+ for (const connections of allConnections) {
617
+ if (connections.length > 0) {
618
+ return connections[0];
619
+ }
620
+ }
621
+ return void 0;
594
622
  }
595
623
  /**
596
624
  * 获取所有 Provider 信息
597
625
  */
598
626
  getAllProviders() {
599
- return Array.from(this.providers.values()).map((ws) => ws.connectionInfo);
627
+ const result = [];
628
+ const allConnections = Array.from(this.providers.values());
629
+ for (const connections of allConnections) {
630
+ for (const ws of connections) {
631
+ result.push(ws.connectionInfo);
632
+ }
633
+ }
634
+ return result;
600
635
  }
601
636
  /**
602
637
  * 获取连接统计
603
638
  */
604
639
  getStats() {
640
+ let providerCount = 0;
641
+ const allConnections = Array.from(this.providers.values());
642
+ for (const connections of allConnections) {
643
+ providerCount += connections.length;
644
+ }
605
645
  return {
606
- providers: this.providers.size,
646
+ providers: providerCount,
607
647
  consumers: this.consumers.size,
608
648
  total: this.allConnections.size
609
649
  };
@@ -619,7 +659,8 @@ var ConnectionManager = class {
619
659
  */
620
660
  closeAll() {
621
661
  this.stopHeartbeatCheck();
622
- for (const ws of this.allConnections.values()) {
662
+ const allWs = Array.from(this.allConnections.values());
663
+ for (const ws of allWs) {
623
664
  ws.close();
624
665
  }
625
666
  this.providers.clear();
@@ -773,24 +814,11 @@ function getVersion() {
773
814
  try {
774
815
  const currentFile = fileURLToPath(import.meta.url);
775
816
  const currentDir = dirname3(currentFile);
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
817
  const packageJsonPaths = [
792
818
  join2(currentDir, "..", "package.json"),
819
+ // dist/xxx.js -> ../package.json
793
820
  join2(currentDir, "..", "..", "package.json")
821
+ // src/shared/version.ts -> ../../package.json
794
822
  ];
795
823
  for (const packageJsonPath of packageJsonPaths) {
796
824
  if (existsSync3(packageJsonPath)) {
@@ -808,7 +836,11 @@ function getVersion() {
808
836
  return cachedVersion;
809
837
  }
810
838
  }
839
+ var DEV_VERSION = "9.9.9";
811
840
  function isVersionMatch(version1, version2) {
841
+ if (version1 === DEV_VERSION || version2 === DEV_VERSION) {
842
+ return true;
843
+ }
812
844
  return version1 === version2;
813
845
  }
814
846
 
@@ -1559,7 +1591,7 @@ import { writeFileSync as writeFileSync3 } from "fs";
1559
1591
  import { resolve as resolve3, dirname as dirname6 } from "path";
1560
1592
  import { mkdirSync as mkdirSync4 } from "fs";
1561
1593
  function createGetNodeByLinkCommand() {
1562
- return new Command3("get_node_by_link").description("\u89E3\u6790 mgp:// \u534F\u8BAE\u94FE\u63A5\u5E76\u83B7\u53D6\u8282\u70B9\u4FE1\u606F").requiredOption("--link <url>", "mgp:// \u534F\u8BAE\u94FE\u63A5").requiredOption("--output <path>", "\u8F93\u51FA JSON \u6587\u4EF6\u8DEF\u5F84").option("--maxDepth <number>", "\u904D\u5386\u6DF1\u5EA6", "1").option("--includeInvisible", "\u5305\u542B\u4E0D\u53EF\u89C1\u8282\u70B9", false).option("--raw", "\u4FDD\u7559\u539F\u59CB\u6570\u636E\uFF0C\u4E0D\u7CBE\u7B80\u9ED8\u8BA4\u503C\u5B57\u6BB5", false).option("--no-auto-start", "\u7981\u7528\u81EA\u52A8\u542F\u52A8 Server").option("--no-retry", "\u7981\u7528\u81EA\u52A8\u91CD\u8BD5").action(async (options) => {
1594
+ return new Command3("get_node_by_link").description("\u89E3\u6790 mgp:// \u534F\u8BAE\u94FE\u63A5\u5E76\u83B7\u53D6\u8282\u70B9/\u9875\u9762\u4FE1\u606F").requiredOption("--link <url>", "mgp:// \u534F\u8BAE\u94FE\u63A5\uFF08\u652F\u6301 nodeId \u548C pageId\uFF09").requiredOption("--output <path>", "\u8F93\u51FA JSON \u6587\u4EF6\u8DEF\u5F84").option("--maxDepth <number>", "\u904D\u5386\u6DF1\u5EA6", "1").option("--includeInvisible", "\u5305\u542B\u4E0D\u53EF\u89C1\u8282\u70B9", false).option("--raw", "\u4FDD\u7559\u539F\u59CB\u6570\u636E\uFF0C\u4E0D\u7CBE\u7B80\u9ED8\u8BA4\u503C\u5B57\u6BB5", false).option("--no-auto-start", "\u7981\u7528\u81EA\u52A8\u542F\u52A8 Server").option("--no-retry", "\u7981\u7528\u81EA\u52A8\u91CD\u8BD5").action(async (options) => {
1563
1595
  await handleGetNodeByLink(options);
1564
1596
  });
1565
1597
  }
@@ -1568,26 +1600,43 @@ async function handleGetNodeByLink(options) {
1568
1600
  if (!parsed) {
1569
1601
  console.error(`\u9519\u8BEF [${"E010" /* INVALID_LINK */}]: \u65E0\u6548\u7684 mgp:// \u94FE\u63A5\u683C\u5F0F`);
1570
1602
  console.error(`\u63D0\u4F9B\u7684\u94FE\u63A5: ${options.link}`);
1571
- console.error(`\u671F\u671B\u683C\u5F0F: mgp://[mastergo_page_url]/nodeId`);
1603
+ console.error(`\u671F\u671B\u683C\u5F0F:`);
1604
+ console.error(` \u8282\u70B9\u94FE\u63A5: mgp://[mastergo_page_url]?nodeId=[\u8282\u70B9ID]`);
1605
+ console.error(` \u9875\u9762\u94FE\u63A5: mgp://[mastergo_page_url]?pageId=[\u9875\u9762ID]`);
1572
1606
  process.exit(1);
1573
1607
  }
1574
- const { pageUrl, nodeId } = parsed;
1608
+ const { pageUrl, nodeId, pageId } = parsed;
1609
+ const isPageLink = !!pageId;
1575
1610
  const client = new MGClient({
1576
1611
  noAutoStart: options.noAutoStart,
1577
1612
  noRetry: options.noRetry
1578
1613
  });
1579
1614
  try {
1580
1615
  await client.connect();
1581
- const params = {
1582
- nodeId,
1583
- maxDepth: parseInt(options.maxDepth || "1", 10),
1584
- includeInvisible: options.includeInvisible || false
1585
- };
1586
- const data = await client.requestWithRetry(
1587
- "get_node_by_id" /* GET_NODE_BY_ID */,
1588
- params,
1589
- pageUrl
1590
- );
1616
+ let data;
1617
+ if (isPageLink) {
1618
+ const params = {
1619
+ pageId,
1620
+ maxDepth: parseInt(options.maxDepth || "1", 10),
1621
+ includeInvisible: options.includeInvisible || false
1622
+ };
1623
+ data = await client.requestWithRetry(
1624
+ "get_page_by_id" /* GET_PAGE_BY_ID */,
1625
+ params,
1626
+ pageUrl
1627
+ );
1628
+ } else {
1629
+ const params = {
1630
+ nodeId,
1631
+ maxDepth: parseInt(options.maxDepth || "1", 10),
1632
+ includeInvisible: options.includeInvisible || false
1633
+ };
1634
+ data = await client.requestWithRetry(
1635
+ "get_node_by_id" /* GET_NODE_BY_ID */,
1636
+ params,
1637
+ pageUrl
1638
+ );
1639
+ }
1591
1640
  const outputData = options.raw ? data : trimNodeDefaults(data);
1592
1641
  const outputPath = resolve3(options.output);
1593
1642
  const outputDir = dirname6(outputPath);
@@ -1599,9 +1648,15 @@ async function handleGetNodeByLink(options) {
1599
1648
  console.log(`\u6587\u4EF6\u8DEF\u5F84: ${outputPath}`);
1600
1649
  console.log(`Link: ${options.link}`);
1601
1650
  console.log(`\u9875\u9762 URL: ${pageUrl}`);
1602
- console.log(`\u8282\u70B9 ID: ${nodeId}`);
1651
+ if (isPageLink) {
1652
+ console.log(`\u9875\u9762 ID: ${pageId}`);
1653
+ console.log(`\u7C7B\u578B: \u9875\u9762`);
1654
+ } else {
1655
+ console.log(`\u8282\u70B9 ID: ${nodeId}`);
1656
+ console.log(`\u7C7B\u578B: \u8282\u70B9`);
1657
+ }
1603
1658
  console.log(`\u6570\u636E\u5927\u5C0F: ${size.toLocaleString()} \u5B57\u7B26 (\u7EA6 ${sizeKB} KB)`);
1604
- console.log(`\u8282\u70B9\u6DF1\u5EA6: ${params.maxDepth}`);
1659
+ console.log(`\u904D\u5386\u6DF1\u5EA6: ${options.maxDepth || "1"}`);
1605
1660
  if (!options.raw) {
1606
1661
  console.log(`\u6570\u636E\u6A21\u5F0F: \u7CBE\u7B80\u6A21\u5F0F (\u4F7F\u7528 --raw \u83B7\u53D6\u5B8C\u6574\u6570\u636E)`);
1607
1662
  }
@@ -1696,10 +1751,11 @@ async function handleExportImage(options) {
1696
1751
  let nodeId;
1697
1752
  if (options.link) {
1698
1753
  const linkInfo = parseMgpLink(options.link);
1699
- if (!linkInfo) {
1754
+ if (!linkInfo || !linkInfo.nodeId) {
1700
1755
  console.error(`\u9519\u8BEF [${"E010" /* INVALID_LINK */}]: \u65E0\u6548\u7684 mgp:// \u94FE\u63A5\u683C\u5F0F`);
1701
1756
  console.error(`\u63D0\u4F9B\u7684\u94FE\u63A5: ${options.link}`);
1702
1757
  console.error(`\u671F\u671B\u683C\u5F0F: mgp://[mastergo_page_url]?nodeId=xxx`);
1758
+ console.error(`\u6CE8\u610F: \u6B64\u547D\u4EE4\u4E0D\u652F\u6301\u9875\u9762\u94FE\u63A5 (pageId)\uFF0C\u8BF7\u4F7F\u7528\u8282\u70B9\u94FE\u63A5 (nodeId)`);
1703
1759
  process.exit(1);
1704
1760
  }
1705
1761
  pageUrl = linkInfo.pageUrl;
@@ -1865,7 +1921,7 @@ async function handleExecuteCode(code, options) {
1865
1921
  if (!parsed) {
1866
1922
  console.error(`\u9519\u8BEF [${"E010" /* INVALID_LINK */}]: \u65E0\u6548\u7684 mgp:// \u94FE\u63A5\u683C\u5F0F`);
1867
1923
  console.error(`\u63D0\u4F9B\u7684\u94FE\u63A5: ${options.link}`);
1868
- console.error(`\u671F\u671B\u683C\u5F0F: mgp://[mastergo_page_url]?nodeId=xxx`);
1924
+ console.error(`\u671F\u671B\u683C\u5F0F: mgp://[mastergo_page_url]?nodeId=xxx \u6216 mgp://[mastergo_page_url]?pageId=xxx`);
1869
1925
  process.exit(1);
1870
1926
  }
1871
1927
  pageUrl = parsed.pageUrl;
@@ -1970,7 +2026,7 @@ import { writeFileSync as writeFileSync7 } from "fs";
1970
2026
  import { resolve as resolve7, dirname as dirname10 } from "path";
1971
2027
  import { mkdirSync as mkdirSync8 } from "fs";
1972
2028
  function createGetNodeForSpaceCommand() {
1973
- return new Command8("get_node_for_space").description("\u83B7\u53D6\u8282\u70B9\u7684\u7A7A\u95F4\u4F4D\u7F6E\u4FE1\u606F\uFF08id\u3001name\u3001x\u3001y\u3001width\u3001height\uFF09\uFF0C\u7528\u4E8E AI \u7406\u89E3\u5143\u7D20\u5E03\u5C40\u3002\u9ED8\u8BA4\u83B7\u53D6\u6700\u6DF1\u5C42\u7EA7").option("--nodeId <id>", "\u8282\u70B9 ID\uFF0C\u683C\u5F0F\u5982 123:456\u3002\u4E0E --link \u4E8C\u9009\u4E00").option("--link <url>", "mgp:// \u534F\u8BAE\u94FE\u63A5\u3002\u4E0E --nodeId \u4E8C\u9009\u4E00").requiredOption("--output <path>", "\u8F93\u51FA JSON \u6587\u4EF6\u8DEF\u5F84").option("--domain <domain>", "MasterGo \u57DF\u540D\uFF0C\u9ED8\u8BA4 mastergo.netease.com\u3002\u4E0E --nodeId \u914D\u5408\u4F7F\u7528", "mastergo.netease.com").option("--fileId <id>", "\u6587\u4EF6 ID\uFF08\u7EAF\u6570\u5B57\uFF09\uFF0C\u4E0E --domain \u548C --nodeId \u914D\u5408\u4F7F\u7528").option("--maxDepth <number>", "\u904D\u5386\u6DF1\u5EA6\uFF0C\u9ED8\u8BA4 99\uFF08\u83B7\u53D6\u6700\u6DF1\u5C42\u7EA7\uFF09", "99").option("--includeInvisible", "\u5305\u542B\u4E0D\u53EF\u89C1\u8282\u70B9", false).option("--no-auto-start", "\u7981\u7528\u81EA\u52A8\u542F\u52A8 Server").option("--no-retry", "\u7981\u7528\u81EA\u52A8\u91CD\u8BD5").action(async (options) => {
2029
+ return new Command8("get_node_for_space").description("\u83B7\u53D6\u8282\u70B9\u6216\u9875\u9762\u7684\u7A7A\u95F4\u4F4D\u7F6E\u4FE1\u606F\uFF08id\u3001name\u3001x\u3001y\u3001width\u3001height\uFF09\uFF0C\u7528\u4E8E AI \u7406\u89E3\u5143\u7D20\u5E03\u5C40\u3002\u9ED8\u8BA4\u83B7\u53D6\u6700\u6DF1\u5C42\u7EA7\u3002\u652F\u6301 nodeId \u548C pageId \u94FE\u63A5").option("--nodeId <id>", "\u8282\u70B9 ID\uFF0C\u683C\u5F0F\u5982 123:456\u3002\u4E0E --link \u4E8C\u9009\u4E00").option("--link <url>", "mgp:// \u534F\u8BAE\u94FE\u63A5\uFF08\u652F\u6301 nodeId \u548C pageId\uFF09\u3002\u4E0E --nodeId \u4E8C\u9009\u4E00").requiredOption("--output <path>", "\u8F93\u51FA JSON \u6587\u4EF6\u8DEF\u5F84").option("--domain <domain>", "MasterGo \u57DF\u540D\uFF0C\u9ED8\u8BA4 mastergo.netease.com\u3002\u4E0E --nodeId \u914D\u5408\u4F7F\u7528", "mastergo.netease.com").option("--fileId <id>", "\u6587\u4EF6 ID\uFF08\u7EAF\u6570\u5B57\uFF09\uFF0C\u4E0E --domain \u548C --nodeId \u914D\u5408\u4F7F\u7528").option("--maxDepth <number>", "\u904D\u5386\u6DF1\u5EA6\uFF0C\u9ED8\u8BA4 99\uFF08\u83B7\u53D6\u6700\u6DF1\u5C42\u7EA7\uFF09", "99").option("--includeInvisible", "\u5305\u542B\u4E0D\u53EF\u89C1\u8282\u70B9", false).option("--no-auto-start", "\u7981\u7528\u81EA\u52A8\u542F\u52A8 Server").option("--no-retry", "\u7981\u7528\u81EA\u52A8\u91CD\u8BD5").action(async (options) => {
1974
2030
  await handleGetNodeForSpace(options);
1975
2031
  });
1976
2032
  }
@@ -1985,16 +2041,27 @@ async function handleGetNodeForSpace(options) {
1985
2041
  }
1986
2042
  let pageUrl;
1987
2043
  let nodeId;
2044
+ let pageId;
2045
+ let isPageMode = false;
1988
2046
  if (options.link) {
1989
2047
  const parsed = parseMgpLink(options.link);
1990
2048
  if (!parsed) {
1991
2049
  console.error(`\u9519\u8BEF [${"E010" /* INVALID_LINK */}]: \u65E0\u6548\u7684 mgp:// \u94FE\u63A5\u683C\u5F0F`);
1992
2050
  console.error(`\u63D0\u4F9B\u7684\u94FE\u63A5: ${options.link}`);
1993
- console.error(`\u671F\u671B\u683C\u5F0F: mgp://[mastergo_page_url]?nodeId=xxx`);
2051
+ console.error(`\u671F\u671B\u683C\u5F0F: mgp://[mastergo_page_url]?nodeId=xxx \u6216 mgp://[mastergo_page_url]?pageId=xxx`);
1994
2052
  process.exit(1);
1995
2053
  }
1996
2054
  pageUrl = parsed.pageUrl;
1997
- nodeId = parsed.nodeId;
2055
+ if (parsed.pageId) {
2056
+ isPageMode = true;
2057
+ pageId = parsed.pageId;
2058
+ } else if (parsed.nodeId) {
2059
+ nodeId = parsed.nodeId;
2060
+ } else {
2061
+ console.error(`\u9519\u8BEF [${"E010" /* INVALID_LINK */}]: \u94FE\u63A5\u4E2D\u5FC5\u987B\u5305\u542B nodeId \u6216 pageId \u53C2\u6570`);
2062
+ console.error(`\u63D0\u4F9B\u7684\u94FE\u63A5: ${options.link}`);
2063
+ process.exit(1);
2064
+ }
1998
2065
  } else {
1999
2066
  nodeId = options.nodeId;
2000
2067
  if (options.fileId) {
@@ -2008,16 +2075,32 @@ async function handleGetNodeForSpace(options) {
2008
2075
  });
2009
2076
  try {
2010
2077
  await client.connect();
2011
- const params = {
2012
- nodeId,
2013
- maxDepth: parseInt(options.maxDepth || "99", 10),
2014
- includeInvisible: options.includeInvisible || false
2015
- };
2016
- const data = await client.requestWithRetry(
2017
- "get_node_by_id" /* GET_NODE_BY_ID */,
2018
- params,
2019
- pageUrl
2020
- );
2078
+ const maxDepth = parseInt(options.maxDepth || "99", 10);
2079
+ const includeInvisible = options.includeInvisible || false;
2080
+ let data;
2081
+ if (isPageMode && pageId) {
2082
+ const params = {
2083
+ pageId,
2084
+ maxDepth,
2085
+ includeInvisible
2086
+ };
2087
+ data = await client.requestWithRetry(
2088
+ "get_page_by_id" /* GET_PAGE_BY_ID */,
2089
+ params,
2090
+ pageUrl
2091
+ );
2092
+ } else {
2093
+ const params = {
2094
+ nodeId,
2095
+ maxDepth,
2096
+ includeInvisible
2097
+ };
2098
+ data = await client.requestWithRetry(
2099
+ "get_node_by_id" /* GET_NODE_BY_ID */,
2100
+ params,
2101
+ pageUrl
2102
+ );
2103
+ }
2021
2104
  const spaceData = extractSpaceInfo(data);
2022
2105
  const outputPath = resolve7(options.output);
2023
2106
  const outputDir = dirname10(outputPath);
@@ -2031,9 +2114,15 @@ async function handleGetNodeForSpace(options) {
2031
2114
  console.log(`Link: ${options.link}`);
2032
2115
  console.log(`\u9875\u9762 URL: ${pageUrl}`);
2033
2116
  }
2034
- console.log(`\u8282\u70B9 ID: ${nodeId}`);
2117
+ if (isPageMode) {
2118
+ console.log(`\u9875\u9762 ID: ${pageId}`);
2119
+ console.log(`\u6A21\u5F0F: \u9875\u9762\u7A7A\u95F4\u4FE1\u606F`);
2120
+ } else {
2121
+ console.log(`\u8282\u70B9 ID: ${nodeId}`);
2122
+ console.log(`\u6A21\u5F0F: \u8282\u70B9\u7A7A\u95F4\u4FE1\u606F`);
2123
+ }
2035
2124
  console.log(`\u6570\u636E\u5927\u5C0F: ${size.toLocaleString()} \u5B57\u7B26 (\u7EA6 ${sizeKB} KB)`);
2036
- console.log(`\u8282\u70B9\u6DF1\u5EA6: ${params.maxDepth}`);
2125
+ console.log(`\u8282\u70B9\u6DF1\u5EA6: ${maxDepth}`);
2037
2126
  console.log(`\u6570\u636E\u6A21\u5F0F: \u7A7A\u95F4\u4FE1\u606F (\u4EC5 id, name, x, y, width, height)`);
2038
2127
  } catch (error) {
2039
2128
  if (error instanceof MGError) {