weapp-ide-cli 5.4.0 → 5.4.2

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.
@@ -1,170 +1,15 @@
1
- import { A as colors, B as defaultCustomConfigFilePath, F as createLocaleConfig, I as overwriteCustomConfig, L as readCustomConfig, M as createAutoBootstrapDevtoolsConfig, N as createAutoTrustProjectConfig, O as isOperatingSystemSupported, P as createCustomConfig, R as removeCustomConfigKey, S as resolveCliPath, T as resolveDevtoolsAutomationDefaults, V as resolvePath, b as bootstrapWechatDevtoolsSettings, c as i18nText, j as logger_default, k as operatingSystemName, l as validateLocaleOption, o as withMiniProgram, r as connectMiniProgram, s as configureLocaleFromArgv, w as getConfiguredLocale, x as detectWechatDevtoolsServicePort } from "./automator-session-RrZjw3X5.js";
2
- import { a as navigateBack, c as pageStack, d as remote, f as scrollTo, g as tap, i as input, l as reLaunch, m as systemInfo, n as captureScreenshotBuffer, o as navigateTo, p as switchTab, r as currentPage, s as pageData, t as audit, u as redirectTo } from "./commands-fWDebiQq.js";
3
- import "./run-mcp-By4qRg8l.js";
1
+ import { $ as readCustomConfig, B as getConfiguredLocale, C as configureLocaleFromArgv, J as createAutoBootstrapDevtoolsConfig, K as colors, Q as overwriteCustomConfig, R as resolveCliPath, T as validateLocaleOption, V as resolveDevtoolsAutomationDefaults, X as createCustomConfig, Y as createAutoTrustProjectConfig, Z as createLocaleConfig, et as removeCustomConfigKey, nt as defaultCustomConfigFilePath, q as logger_default, r as connectMiniProgram, w as i18nText } from "./automator-session-CvStbY9I.js";
2
+ import { $ as parseAutomatorArgs, A as isWechatIdeLoggedIn, B as runWechatCliCommand, C as clearWechatIdeCache, F as quitWechatIde, G as transformArgv, H as execute, K as promptForCliPath, L as resetWechatIdeFileUtils, M as openWechatIde, N as openWechatIdeOtherProject, P as previewWechatIde, Q as startWechatIdeEngineBuildByHttp, S as buildWechatIdeNpm, T as closeWechatIdeProject, U as createAlias, W as createPathCompat, Y as pollWechatIdeEngineBuildResultByHttp, _ as autoPreviewWechatIde, a as navigateBack, b as buildWechatIdeApk, c as pageStack, d as remote, et as readBooleanOption, f as scrollTo, g as tap, i as input, j as loginWechatIde, l as reLaunch, m as systemInfo, n as captureScreenshotBuffer, nt as removeOption, o as navigateTo, p as switchTab, r as currentPage, s as pageData, t as audit, tt as readOptionValue, u as redirectTo, v as autoReplayWechatIde, x as buildWechatIdeIpa, y as autoWechatIde, z as uploadWechatIde } from "./commands-Js_IjVxE.js";
3
+ import "./run-mcp-DvHYYX0m.js";
4
4
  import fs from "node:fs/promises";
5
5
  import path from "node:path";
6
6
  import { fs as fs$1 } from "@weapp-core/shared/fs";
7
- import process, { stdin, stdout } from "node:process";
7
+ import process from "node:process";
8
8
  import { PNG } from "pngjs";
9
9
  import pixelmatch from "pixelmatch";
10
- import { createInterface } from "node:readline/promises";
11
- import { emitKeypressEvents } from "node:readline";
12
10
  import { execa } from "execa";
13
11
  import { inspect } from "node:util";
14
12
  import { cac } from "cac";
15
- //#region src/cli/automator-argv.ts
16
- function parsePositiveInt(raw) {
17
- const value = Number.parseInt(raw, 10);
18
- if (!Number.isFinite(value) || value <= 0) return;
19
- return value;
20
- }
21
- function takesValue(optionName) {
22
- return optionName === "-p" || optionName === "--project" || optionName === "-t" || optionName === "--timeout" || optionName === "--port" || optionName === "--session-id" || optionName === "-o" || optionName === "--output" || optionName === "--page" || optionName === "--login-retry" || optionName === "--login-retry-timeout" || optionName === "--lang" || optionName === "--platform" || optionName === "--runtime-url" || optionName === "--qr-output" || optionName === "-r" || optionName === "--result-output" || optionName === "--info-output" || optionName === "-i";
23
- }
24
- /**
25
- * @description 解析 automator 命令通用参数与位置参数。
26
- */
27
- function parseAutomatorArgs(argv) {
28
- const positionals = [];
29
- let projectPath = process.cwd();
30
- let timeout;
31
- let port;
32
- let sessionId;
33
- let json = false;
34
- for (let index = 0; index < argv.length; index += 1) {
35
- const token = argv[index];
36
- if (!token) continue;
37
- if (token === "-p" || token === "--project") {
38
- const value = argv[index + 1];
39
- if (typeof value === "string" && !value.startsWith("-")) {
40
- projectPath = value;
41
- index += 1;
42
- } else projectPath = process.cwd();
43
- continue;
44
- }
45
- if (token.startsWith("--project=")) {
46
- projectPath = token.slice(10) || process.cwd();
47
- continue;
48
- }
49
- if (token === "-t" || token === "--timeout") {
50
- const value = argv[index + 1];
51
- if (typeof value === "string") {
52
- timeout = parsePositiveInt(value);
53
- index += 1;
54
- }
55
- continue;
56
- }
57
- if (token.startsWith("--timeout=")) {
58
- timeout = parsePositiveInt(token.slice(10));
59
- continue;
60
- }
61
- if (token === "--port") {
62
- const value = argv[index + 1];
63
- if (typeof value === "string") {
64
- port = parsePositiveInt(value);
65
- index += 1;
66
- }
67
- continue;
68
- }
69
- if (token.startsWith("--port=")) {
70
- port = parsePositiveInt(token.slice(7));
71
- continue;
72
- }
73
- if (token === "--session-id") {
74
- const value = argv[index + 1];
75
- if (typeof value === "string" && !value.startsWith("-")) {
76
- sessionId = value.trim() || void 0;
77
- index += 1;
78
- }
79
- continue;
80
- }
81
- if (token.startsWith("--session-id=")) {
82
- sessionId = token.slice(13).trim() || void 0;
83
- continue;
84
- }
85
- if (token === "--json") {
86
- json = true;
87
- continue;
88
- }
89
- if (token.startsWith("-")) {
90
- if (takesValue(token.includes("=") ? token.slice(0, token.indexOf("=")) : token) && !token.includes("=")) {
91
- const value = argv[index + 1];
92
- if (typeof value === "string" && !value.startsWith("-")) index += 1;
93
- }
94
- continue;
95
- }
96
- positionals.push(token);
97
- }
98
- return {
99
- projectPath,
100
- ...timeout ? { timeout } : {},
101
- ...port ? { port } : {},
102
- ...sessionId ? { sessionId } : {},
103
- json,
104
- positionals
105
- };
106
- }
107
- /**
108
- * @description 读取选项值,支持多个别名,以及 --option value 与 --option=value。
109
- */
110
- function readOptionValue(argv, ...optionNames) {
111
- for (const optionName of optionNames) {
112
- const optionWithEqual = `${optionName}=`;
113
- for (let index = 0; index < argv.length; index += 1) {
114
- const token = argv[index];
115
- if (!token) continue;
116
- if (token === optionName) {
117
- const value = argv[index + 1];
118
- if (typeof value !== "string") return;
119
- return value.trim();
120
- }
121
- if (token.startsWith(optionWithEqual)) return token.slice(optionWithEqual.length).trim();
122
- }
123
- }
124
- }
125
- /**
126
- * @description 读取布尔选项,支持裸 flag、--flag=true/false 与 --flag true/false。
127
- */
128
- function readBooleanOption(argv, ...optionNames) {
129
- for (const optionName of optionNames) {
130
- const optionWithEqual = `${optionName}=`;
131
- for (let index = 0; index < argv.length; index += 1) {
132
- const token = argv[index];
133
- if (!token) continue;
134
- if (token === optionName) {
135
- const nextToken = argv[index + 1];
136
- if (nextToken === "true") return true;
137
- if (nextToken === "false") return false;
138
- return true;
139
- }
140
- if (token.startsWith(optionWithEqual)) {
141
- const rawValue = token.slice(optionWithEqual.length).trim().toLowerCase();
142
- if (rawValue === "true") return true;
143
- if (rawValue === "false") return false;
144
- }
145
- }
146
- }
147
- }
148
- /**
149
- * @description 删除参数中的指定选项(同时支持 --opt value 与 --opt=value)。
150
- */
151
- function removeOption(argv, optionName) {
152
- const optionWithEqual = `${optionName}=`;
153
- const nextArgv = [];
154
- for (let index = 0; index < argv.length; index += 1) {
155
- const token = argv[index];
156
- if (!token) continue;
157
- if (token === optionName) {
158
- const nextToken = argv[index + 1];
159
- if (takesValue(optionName) && typeof nextToken === "string" && !nextToken.startsWith("-")) index += 1;
160
- continue;
161
- }
162
- if (token.startsWith(optionWithEqual)) continue;
163
- nextArgv.push(token);
164
- }
165
- return nextArgv;
166
- }
167
- //#endregion
168
13
  //#region src/cli/imageDiff.ts
169
14
  function readPng(buffer, label) {
170
15
  try {
@@ -452,6 +297,7 @@ function parseScreenshotArgs(argv) {
452
297
  ...parsed.timeout ? { timeout: parsed.timeout } : {},
453
298
  ...parsed.port ? { port: parsed.port } : {},
454
299
  ...parsed.sessionId ? { sessionId: parsed.sessionId } : {},
300
+ ...parsed.preferOpenedSession === false ? { preferOpenedSession: parsed.preferOpenedSession } : {},
455
301
  ...outputPath ? { outputPath } : {},
456
302
  ...page ? { page } : {},
457
303
  ...fullPage ? { fullPage: true } : {}
@@ -467,7 +313,7 @@ async function runScreenshot(argv) {
467
313
  }
468
314
  const options = parseScreenshotArgs(argv);
469
315
  const isJsonOutput = argv.includes("--json");
470
- const { takeScreenshot } = await import("./commands-D_j5_0eE.js");
316
+ const { takeScreenshot } = await import("./commands-B4HFVW-Q.js");
471
317
  const result = await takeScreenshot(options);
472
318
  if (isJsonOutput) {
473
319
  console.log(JSON.stringify(result, null, 2));
@@ -994,188 +840,6 @@ function isWeappIdeTopLevelCommand(command) {
994
840
  return Boolean(command && WEAPP_IDE_TOP_LEVEL_COMMAND_SET.has(command));
995
841
  }
996
842
  //#endregion
997
- //#region src/cli/inputCoordinator.ts
998
- const sharedSessions = /* @__PURE__ */ new Set();
999
- const exclusiveKeypressStack = [];
1000
- const EXCLUSIVE_KEYPRESS_CARRYOVER_GUARD_MS = 500;
1001
- let initialized = false;
1002
- let rawModeEnabled = false;
1003
- let dataListenerAttached = false;
1004
- let keypressListenerAttached = false;
1005
- let lastExclusiveResolvedKeypress;
1006
- function hasInteractiveStdin() {
1007
- return Boolean(process.stdin?.isTTY);
1008
- }
1009
- function canSetRawMode() {
1010
- return typeof process.stdin?.setRawMode === "function";
1011
- }
1012
- function updateTerminalState() {
1013
- const shouldKeepInputActive = Array.from(sharedSessions).some((session) => !session.closed && !session.suspended) || exclusiveKeypressStack.length > 0;
1014
- if (canSetRawMode() && rawModeEnabled !== shouldKeepInputActive) {
1015
- process.stdin.setRawMode(shouldKeepInputActive);
1016
- rawModeEnabled = shouldKeepInputActive;
1017
- }
1018
- if (shouldKeepInputActive) {
1019
- process.stdin.resume();
1020
- return;
1021
- }
1022
- process.stdin.pause();
1023
- }
1024
- function handleData(chunk) {
1025
- if (exclusiveKeypressStack.length > 0) return;
1026
- for (const session of sharedSessions) {
1027
- if (session.closed || session.suspended || !session.options.onData) continue;
1028
- session.options.onData(chunk);
1029
- }
1030
- }
1031
- function handleKeypress(str, key) {
1032
- const activeExclusive = exclusiveKeypressStack[exclusiveKeypressStack.length - 1];
1033
- if (activeExclusive) {
1034
- const now = Date.now();
1035
- const signature = `${key?.ctrl ? "ctrl+" : ""}${key?.name ?? str}`;
1036
- if (lastExclusiveResolvedKeypress && lastExclusiveResolvedKeypress.signature === signature && now - lastExclusiveResolvedKeypress.timestamp <= EXCLUSIVE_KEYPRESS_CARRYOVER_GUARD_MS) {
1037
- lastExclusiveResolvedKeypress.timestamp = now;
1038
- return;
1039
- }
1040
- if (now < activeExclusive.ignoreUntil) return;
1041
- const nextValue = activeExclusive.onKeypress(str, key);
1042
- if (nextValue !== void 0) {
1043
- clearTimeout(activeExclusive.timeout);
1044
- exclusiveKeypressStack.pop();
1045
- lastExclusiveResolvedKeypress = {
1046
- signature,
1047
- timestamp: now
1048
- };
1049
- updateTerminalState();
1050
- activeExclusive.resolve(nextValue);
1051
- }
1052
- return;
1053
- }
1054
- for (const session of sharedSessions) {
1055
- if (session.closed || session.suspended || !session.options.onKeypress) continue;
1056
- session.options.onKeypress(str, key);
1057
- }
1058
- }
1059
- function ensureCoordinatorInitialized() {
1060
- if (initialized || !hasInteractiveStdin()) return;
1061
- emitKeypressEvents(process.stdin);
1062
- if (!dataListenerAttached) {
1063
- process.stdin.on("data", handleData);
1064
- dataListenerAttached = true;
1065
- }
1066
- if (!keypressListenerAttached) {
1067
- process.stdin.on("keypress", handleKeypress);
1068
- keypressListenerAttached = true;
1069
- }
1070
- initialized = true;
1071
- }
1072
- function createSharedInputSession(options) {
1073
- if (!hasInteractiveStdin()) return;
1074
- ensureCoordinatorInitialized();
1075
- const session = {
1076
- closed: false,
1077
- options,
1078
- suspended: false
1079
- };
1080
- sharedSessions.add(session);
1081
- updateTerminalState();
1082
- return {
1083
- close() {
1084
- if (session.closed) return;
1085
- session.closed = true;
1086
- sharedSessions.delete(session);
1087
- updateTerminalState();
1088
- },
1089
- resume() {
1090
- if (session.closed) return;
1091
- session.suspended = false;
1092
- updateTerminalState();
1093
- },
1094
- suspend() {
1095
- if (session.closed) return;
1096
- session.suspended = true;
1097
- updateTerminalState();
1098
- }
1099
- };
1100
- }
1101
- async function waitForExclusiveKeypress(options) {
1102
- if (!hasInteractiveStdin()) return "timeout";
1103
- ensureCoordinatorInitialized();
1104
- return await new Promise((resolve) => {
1105
- const normalizedTimeoutMs = Number.isFinite(options.timeoutMs) && options.timeoutMs && options.timeoutMs > 0 ? options.timeoutMs : 3e4;
1106
- const normalizedIgnoreInitialMs = Number.isFinite(options.ignoreInitialMs) && options.ignoreInitialMs && options.ignoreInitialMs > 0 ? options.ignoreInitialMs : 0;
1107
- const record = {
1108
- ignoreUntil: Date.now() + normalizedIgnoreInitialMs,
1109
- onKeypress: options.onKeypress,
1110
- resolve,
1111
- timeout: setTimeout(() => {
1112
- const index = exclusiveKeypressStack.lastIndexOf(record);
1113
- if (index >= 0) exclusiveKeypressStack.splice(index, 1);
1114
- updateTerminalState();
1115
- resolve("timeout");
1116
- }, normalizedTimeoutMs)
1117
- };
1118
- exclusiveKeypressStack.push(record);
1119
- updateTerminalState();
1120
- });
1121
- }
1122
- async function runWithSuspendedSharedInput(runner) {
1123
- const previousStates = /* @__PURE__ */ new Map();
1124
- for (const session of sharedSessions) {
1125
- if (session.closed) continue;
1126
- previousStates.set(session, session.suspended);
1127
- session.suspended = true;
1128
- }
1129
- if (canSetRawMode() && rawModeEnabled) {
1130
- process.stdin.setRawMode(false);
1131
- rawModeEnabled = false;
1132
- }
1133
- process.stdin.resume();
1134
- try {
1135
- return await runner();
1136
- } finally {
1137
- for (const [session, suspended] of previousStates) if (!session.closed) session.suspended = suspended;
1138
- updateTerminalState();
1139
- }
1140
- }
1141
- //#endregion
1142
- //#region src/cli/prompt.ts
1143
- /**
1144
- * @description 交互式提示并保存 CLI 路径
1145
- */
1146
- async function promptForCliPath() {
1147
- return await runWithSuspendedSharedInput(async () => {
1148
- const rl = createInterface({
1149
- input: stdin,
1150
- output: stdout
1151
- });
1152
- try {
1153
- logger_default.info(`请设置 ${colors.bold("微信web开发者工具 CLI")} 的路径`);
1154
- logger_default.info("提示:命令行工具默认所在位置:");
1155
- logger_default.info(`- MacOS: ${colors.green("<安装路径>/Contents/MacOS/cli")}`);
1156
- logger_default.info(`- Windows: ${colors.green("<安装路径>/cli.bat")}`);
1157
- logger_default.info(`- Linux: ${colors.green("<安装路径>/files/bin/bin/wechat-devtools-cli")}`);
1158
- const cliPath = (await rl.question("请输入微信web开发者工具 CLI 路径:")).trim();
1159
- if (!cliPath) {
1160
- logger_default.error("路径不能为空,已取消本次配置。");
1161
- return null;
1162
- }
1163
- try {
1164
- const normalizedPath = await createCustomConfig({ cliPath });
1165
- logger_default.info(`全局配置存储位置:${colors.green(defaultCustomConfigFilePath)}`);
1166
- if (!await fs$1.pathExists(normalizedPath)) logger_default.warn("在当前路径未找到微信web开发者命令行工具,请确认路径是否正确。");
1167
- return normalizedPath;
1168
- } catch (error) {
1169
- const reason = error instanceof Error ? error.message : String(error);
1170
- logger_default.error(`保存配置失败:${reason}`);
1171
- return null;
1172
- }
1173
- } finally {
1174
- rl.close();
1175
- }
1176
- });
1177
- }
1178
- //#endregion
1179
843
  //#region src/cli/config-command.ts
1180
844
  function parseBooleanConfigValue(rawValue) {
1181
845
  const normalized = rawValue.trim().toLowerCase();
@@ -1318,98 +982,6 @@ async function handleConfigCommand(argv) {
1318
982
  throw new Error(i18nText("支持的 config 子命令:lang | set-lang | show | get | set | unset | doctor | import | export", "Supported config subcommands: lang | set-lang | show | get | set | unset | doctor | import | export"));
1319
983
  }
1320
984
  //#endregion
1321
- //#region src/cli/http.ts
1322
- const DEFAULT_WECHAT_DEVTOOLS_HTTP_PORT = 9420;
1323
- const ENGINE_BUILD_NOT_START = "NOT_START";
1324
- const ENGINE_BUILD_OPEN_PROJECT = "OPEN_PROJECT";
1325
- const ENGINE_BUILD_BUILDING = "BUILDING";
1326
- const ENGINE_BUILD_END = "END";
1327
- const ENGINE_BUILD_ERROR = "ERROR";
1328
- function createWechatDevtoolsHttpError(message, code) {
1329
- const error = new Error(message);
1330
- error.code = code;
1331
- return error;
1332
- }
1333
- async function resolveWechatDevtoolsHttpPort(port) {
1334
- if (typeof port === "number" && Number.isInteger(port) && port > 0) return port;
1335
- const detected = await detectWechatDevtoolsServicePort();
1336
- if (detected.servicePortEnabled === false) throw createWechatDevtoolsHttpError("WECHAT_DEVTOOLS_SERVICE_PORT_DISABLED", "WECHAT_DEVTOOLS_SERVICE_PORT_DISABLED");
1337
- return detected.servicePort ?? DEFAULT_WECHAT_DEVTOOLS_HTTP_PORT;
1338
- }
1339
- function createWechatDevtoolsHttpUrl(port, pathname, query) {
1340
- const url = new URL(`http://127.0.0.1:${port}${pathname}`);
1341
- for (const [key, value] of Object.entries(query)) url.searchParams.set(key, value);
1342
- return url;
1343
- }
1344
- function parseWechatDevtoolsEngineBuildResult(body) {
1345
- try {
1346
- return JSON.parse(body);
1347
- } catch {
1348
- return {};
1349
- }
1350
- }
1351
- async function requestWechatDevtoolsHttp(pathname, query, options = {}) {
1352
- const url = createWechatDevtoolsHttpUrl(await resolveWechatDevtoolsHttpPort(options.port), pathname, query);
1353
- const controller = new AbortController();
1354
- const timeout = setTimeout(() => {
1355
- controller.abort();
1356
- }, options.timeoutMs ?? 1e4);
1357
- try {
1358
- const response = await fetch(url, {
1359
- method: "GET",
1360
- signal: controller.signal
1361
- });
1362
- const body = await response.text();
1363
- if (!response.ok) throw createWechatDevtoolsHttpError(body || `HTTP ${response.status}`, "WECHAT_DEVTOOLS_HTTP_REQUEST_FAILED");
1364
- return body;
1365
- } catch (error) {
1366
- if (error instanceof Error && error.name === "AbortError") throw createWechatDevtoolsHttpError("WECHAT_DEVTOOLS_HTTP_TIMEOUT", "WECHAT_DEVTOOLS_HTTP_TIMEOUT");
1367
- throw error;
1368
- } finally {
1369
- clearTimeout(timeout);
1370
- }
1371
- }
1372
- /**
1373
- * @description 通过微信开发者工具 HTTP 服务端口重新打开项目;若项目已打开,开发者工具会刷新当前项目。
1374
- */
1375
- async function openWechatIdeProjectByHttp(projectPath, options = {}) {
1376
- return await requestWechatDevtoolsHttp("/open", { projectpath: path.resolve(projectPath) }, options);
1377
- }
1378
- /**
1379
- * @description 通过微信开发者工具 HTTP 服务端口重置当前项目的 fileutils 状态。
1380
- */
1381
- async function resetWechatIdeFileUtilsByHttp(projectPath, options = {}) {
1382
- return await requestWechatDevtoolsHttp("/v2/resetfileutils", { project: path.resolve(projectPath) }, options);
1383
- }
1384
- /**
1385
- * @description 通过微信开发者工具 HTTP 服务端口触发 engine build。
1386
- */
1387
- async function startWechatIdeEngineBuildByHttp(projectPath, options = {}) {
1388
- return { body: await requestWechatDevtoolsHttp("/engine/build", { projectpath: path.resolve(projectPath) }, options) };
1389
- }
1390
- /**
1391
- * @description 轮询微信开发者工具 engine build 状态。
1392
- */
1393
- async function pollWechatIdeEngineBuildResultByHttp(options = {}) {
1394
- const body = await requestWechatDevtoolsHttp("/engine/buildResult/", {}, options);
1395
- const parsed = parseWechatDevtoolsEngineBuildResult(body);
1396
- const status = parsed.status;
1397
- return {
1398
- body,
1399
- done: status === ENGINE_BUILD_END,
1400
- failed: status === ENGINE_BUILD_ERROR,
1401
- msg: parsed.msg,
1402
- status
1403
- };
1404
- }
1405
- const WECHAT_DEVTOOLS_ENGINE_BUILD_STATUSES = {
1406
- BUILDING: ENGINE_BUILD_BUILDING,
1407
- END: ENGINE_BUILD_END,
1408
- ERROR: ENGINE_BUILD_ERROR,
1409
- NOT_START: ENGINE_BUILD_NOT_START,
1410
- OPEN_PROJECT: ENGINE_BUILD_OPEN_PROJECT
1411
- };
1412
- //#endregion
1413
985
  //#region src/cli/engine.ts
1414
986
  function createEngineBuildError(message, code) {
1415
987
  const error = new Error(message);
@@ -1649,58 +1221,6 @@ function toPlainObject(value) {
1649
1221
  return value;
1650
1222
  }
1651
1223
  //#endregion
1652
- //#region src/utils/argv.ts
1653
- function ensurePathArgument(argv, optionIndex) {
1654
- const paramIdx = optionIndex + 1;
1655
- const param = argv[paramIdx];
1656
- if (param && !param.startsWith("-")) argv[paramIdx] = resolvePath(param);
1657
- else argv.splice(paramIdx, 0, process.cwd());
1658
- return argv;
1659
- }
1660
- /**
1661
- * @description 依次应用 argv 处理函数(不修改原始 argv)
1662
- */
1663
- function transformArgv(argv, transforms) {
1664
- return transforms.reduce((current, transform) => transform(current), [...argv]);
1665
- }
1666
- /**
1667
- * @description 创建参数别名转换器
1668
- */
1669
- function createAlias(entry) {
1670
- return (input) => {
1671
- const argv = [...input];
1672
- let optionIndex = argv.indexOf(entry.find);
1673
- if (optionIndex > -1) argv.splice(optionIndex, 1, entry.replacement);
1674
- else optionIndex = argv.indexOf(entry.replacement);
1675
- if (optionIndex === -1) return argv;
1676
- return ensurePathArgument(argv, optionIndex);
1677
- };
1678
- }
1679
- /**
1680
- * @description 创建路径参数兼容转换器(补全或规范化路径)
1681
- */
1682
- function createPathCompat(option) {
1683
- return (input) => {
1684
- const argv = [...input];
1685
- const optionIndex = argv.indexOf(option);
1686
- if (optionIndex === -1) return argv;
1687
- return ensurePathArgument(argv, optionIndex);
1688
- };
1689
- }
1690
- //#endregion
1691
- //#region src/utils/exec.ts
1692
- /**
1693
- * @description 执行 CLI 命令并透传输出
1694
- */
1695
- async function execute(cliPath, argv, options = {}) {
1696
- const { pipeStdout = true, pipeStderr = true } = options;
1697
- const { execa } = await import("execa");
1698
- const task = execa(cliPath, argv);
1699
- if (pipeStdout) task?.stdout?.pipe(process.stdout);
1700
- if (pipeStderr) task?.stderr?.pipe(process.stderr);
1701
- return await task;
1702
- }
1703
- //#endregion
1704
1224
  //#region src/cli/minidev.ts
1705
1225
  const MINIDEV_COMMAND = "minidev";
1706
1226
  function isCommandNotFound(error) {
@@ -1725,337 +1245,6 @@ async function runMinidev(argv) {
1725
1245
  }
1726
1246
  }
1727
1247
  //#endregion
1728
- //#region src/cli/retry.ts
1729
- const RETRY_PROMPT_INITIAL_IGNORE_MS = 300;
1730
- const RETRY_CONFIRM_KEYS = ["y"];
1731
- const RETRY_CANCEL_KEYS = [
1732
- "q",
1733
- "Esc",
1734
- "Ctrl+C"
1735
- ];
1736
- const LOGIN_REQUIRED_PATTERNS = [
1737
- /code\s*[:=]\s*10/i,
1738
- /需要重新登录/,
1739
- /need\s+re-?login/i,
1740
- /re-?login/i
1741
- ];
1742
- /**
1743
- * @description 提取执行错误文本,便于统一匹配与提示。
1744
- */
1745
- function extractExecutionErrorText(error) {
1746
- if (!error || typeof error !== "object") return "";
1747
- const parts = [];
1748
- const candidate = error;
1749
- for (const field of [
1750
- candidate.message,
1751
- candidate.shortMessage,
1752
- candidate.stderr,
1753
- candidate.stdout
1754
- ]) if (typeof field === "string" && field.trim()) parts.push(field);
1755
- return parts.join("\n");
1756
- }
1757
- function extractLoginRequiredMessage(text) {
1758
- if (!text) return "";
1759
- if (/需要重新登录/.test(text)) return "需要重新登录";
1760
- const englishMatch = text.match(/need\s+re-?login|re-?login/i);
1761
- if (englishMatch?.[0]) return englishMatch[0].toLowerCase();
1762
- const firstLine = text.split(/\r?\n/).map((line) => line.trim()).find((line) => Boolean(line) && !line.startsWith("at "));
1763
- if (!firstLine) return "";
1764
- return firstLine.replace(/^\[error\]\s*/i, "").replace(/^error\s*:\s*/i, "").slice(0, 120);
1765
- }
1766
- /**
1767
- * @description 判断是否为微信开发者工具登录失效错误。
1768
- */
1769
- function isWechatIdeLoginRequiredError(error) {
1770
- const text = extractExecutionErrorText(error);
1771
- if (!text) return false;
1772
- return LOGIN_REQUIRED_PATTERNS.some((pattern) => pattern.test(text));
1773
- }
1774
- /**
1775
- * @description 将登录失效错误格式化为更易读的摘要。
1776
- */
1777
- function formatWechatIdeLoginRequiredError(error) {
1778
- const text = extractExecutionErrorText(error);
1779
- const code = text.match(/code\s*[:=]\s*(\d+)/i)?.[1];
1780
- const message = extractLoginRequiredMessage(text);
1781
- const lines = ["微信开发者工具返回登录错误:"];
1782
- if (code) lines.push(`- code: ${code}`);
1783
- if (message) lines.push(`- message: ${message}`);
1784
- if (!code && !message) lines.push("- message: 需要重新登录");
1785
- return lines.join("\n");
1786
- }
1787
- /**
1788
- * @description 创建登录失效专用错误,并携带退出码语义。
1789
- */
1790
- function createWechatIdeLoginRequiredExitError(error, reason) {
1791
- const summary = formatWechatIdeLoginRequiredError(error);
1792
- const message = reason ? `${reason}\n${summary}` : summary;
1793
- const loginError = new Error(message);
1794
- loginError.name = "WechatIdeLoginRequiredError";
1795
- loginError.code = 10;
1796
- loginError.exitCode = 10;
1797
- return loginError;
1798
- }
1799
- /**
1800
- * @description 交互等待用户按 y 重试,按 q 或 Ctrl+C 取消。
1801
- */
1802
- async function waitForRetryKeypress(options = {}) {
1803
- const { timeoutMs = 3e4 } = options;
1804
- if (!process.stdin.isTTY) return "cancel";
1805
- return await waitForExclusiveKeypress({
1806
- ignoreInitialMs: 300,
1807
- onKeypress: (_str, key) => {
1808
- if (!key) return;
1809
- if (key.ctrl && key.name === "c") return "cancel";
1810
- if (key.name === "y") return "retry";
1811
- if (key.name === "q" || key.name === "escape") return "cancel";
1812
- },
1813
- timeoutMs
1814
- });
1815
- }
1816
- function highlightHotkey(key) {
1817
- return colors.bold(colors.green(key));
1818
- }
1819
- /**
1820
- * @description 生成重试按键提示,并高亮关键热键。
1821
- */
1822
- function formatRetryHotkeyPrompt(timeoutMs = 3e4) {
1823
- const highlight = (key) => highlightHotkey(key);
1824
- const timeoutSeconds = Math.max(1, Math.ceil(timeoutMs / 1e3));
1825
- const confirmKeys = RETRY_CONFIRM_KEYS.map(highlight).join(" / ");
1826
- const cancelKeys = RETRY_CANCEL_KEYS.map(highlight).join(" / ");
1827
- return i18nText(`按 ${confirmKeys} 重试,按 ${cancelKeys} 退出(${timeoutSeconds}s 内无输入将自动失败)。`, `Press ${confirmKeys} to retry, ${cancelKeys} to cancel (auto fail in ${timeoutSeconds}s).`);
1828
- }
1829
- /**
1830
- * @description 输出重试热键提示,并独占等待当前提示对应的按键输入。
1831
- */
1832
- async function promptRetryKeypress(options) {
1833
- const { logger, timeoutMs = 3e4 } = options;
1834
- logger.info(formatRetryHotkeyPrompt(timeoutMs));
1835
- return await waitForRetryKeypress({ timeoutMs });
1836
- }
1837
- /**
1838
- * @description 统一处理微信开发者工具登录失效场景下的提示与重试交互。
1839
- */
1840
- async function promptWechatIdeLoginRetry(options) {
1841
- const { allowRetry = true, cancelLevel = "info", error, logger, promptOpenIdeLogin = false, retryTimeoutMs = 3e4 } = options;
1842
- logger.error(i18nText("检测到微信开发者工具登录状态失效,请先登录后重试。", "Wechat DevTools login has expired. Please login and retry."));
1843
- if (promptOpenIdeLogin) logger.warn(i18nText("请先打开微信开发者工具完成登录。", "Please open Wechat DevTools and complete login first."));
1844
- logger.warn(formatWechatIdeLoginRequiredError(error));
1845
- if (!allowRetry) return "cancel";
1846
- const action = await promptRetryKeypress({
1847
- logger,
1848
- timeoutMs: retryTimeoutMs
1849
- });
1850
- if (action === "timeout") {
1851
- logger.error(i18nText(`等待登录重试输入超时(${retryTimeoutMs}ms),已自动取消。`, `Retry prompt timed out (${retryTimeoutMs}ms), canceled automatically.`));
1852
- return "cancel";
1853
- }
1854
- if (action !== "retry") {
1855
- logger[cancelLevel](i18nText("已取消重试。完成登录后请重新执行当前命令。", "Retry canceled. Please run the command again after login."));
1856
- return "cancel";
1857
- }
1858
- return "retry";
1859
- }
1860
- //#endregion
1861
- //#region src/cli/run-login-config.ts
1862
- function normalizeLoginRetryMode(value, nonInteractive) {
1863
- if (value && value !== "never" && value !== "once" && value !== "always") throw new Error(i18nText(`不支持的 --login-retry 值: ${value}(仅支持 never/once/always)`, `Invalid --login-retry value: ${value} (supported: never/once/always)`));
1864
- if (value === "never" || value === "once" || value === "always") return value;
1865
- return nonInteractive ? "never" : "always";
1866
- }
1867
- function normalizeLoginRetryTimeout(value) {
1868
- if (!value) return 3e4;
1869
- const parsed = Number.parseInt(value, 10);
1870
- if (!Number.isFinite(parsed) || parsed <= 0) throw new Error(i18nText(`无效的 --login-retry-timeout 值: ${value}(必须为正整数)`, `Invalid --login-retry-timeout value: ${value} (must be a positive integer)`));
1871
- return parsed;
1872
- }
1873
- function isStdinInteractive() {
1874
- return Boolean(process.stdin && process.stdin.isTTY);
1875
- }
1876
- function stripLoginRetryControlFlags(argv) {
1877
- let next = removeOption(argv, "--login-retry");
1878
- next = removeOption(next, "--login-retry-timeout");
1879
- next = removeOption(next, "--non-interactive");
1880
- return next;
1881
- }
1882
- /**
1883
- * @description 解析登录重试相关控制参数,并产出实际执行微信 CLI 所需的运行时参数。
1884
- */
1885
- function resolveLoginRetryConfig(argv) {
1886
- const nonInteractiveFlag = argv.includes("--non-interactive");
1887
- const ciMode = process.env.CI === "true";
1888
- const nonTtyStdin = !isStdinInteractive();
1889
- const nonInteractive = nonInteractiveFlag || ciMode || nonTtyStdin;
1890
- const retryModeRaw = readOptionValue(argv, "--login-retry")?.toLowerCase();
1891
- return {
1892
- nonInteractive,
1893
- retryMode: normalizeLoginRetryMode(retryModeRaw, nonInteractive),
1894
- retryTimeoutMs: normalizeLoginRetryTimeout(readOptionValue(argv, "--login-retry-timeout")),
1895
- runtimeArgv: stripLoginRetryControlFlags(argv)
1896
- };
1897
- }
1898
- //#endregion
1899
- //#region src/cli/run-login-executor.ts
1900
- /**
1901
- * @description 执行可重试命令循环,并将“是否可重试”与“如何提示重试”交给调用方定义。
1902
- */
1903
- async function runRetryableCommand(options) {
1904
- const { createCancelError, execute, isRetryableResult, onCancel, onRetry, promptRetry, shouldRetry } = options;
1905
- let retryCount = 0;
1906
- while (true) {
1907
- const result = await execute();
1908
- if (!isRetryableResult(result)) return result;
1909
- if (shouldRetry(await promptRetry(result, retryCount))) {
1910
- retryCount += 1;
1911
- onRetry?.();
1912
- continue;
1913
- }
1914
- onCancel?.(result);
1915
- throw createCancelError(result);
1916
- }
1917
- }
1918
- //#endregion
1919
- //#region src/cli/run-login.ts
1920
- function unwrapWechatCliExecutionError(result) {
1921
- return result.kind === "retryable" ? result.error : result.value;
1922
- }
1923
- async function promptLoginRetry(errorLike, options, retryCount) {
1924
- const { nonInteractive, retryMode, retryTimeoutMs } = options;
1925
- if (nonInteractive) {
1926
- logger_default.error(i18nText("当前为非交互模式,检测到登录失效后直接失败。", "Non-interactive mode enabled, failing immediately on login expiration."));
1927
- return "cancel";
1928
- }
1929
- if (!(retryMode === "always" || retryMode === "once" && retryCount < 1)) {
1930
- await promptWechatIdeLoginRetry({
1931
- allowRetry: false,
1932
- error: errorLike,
1933
- logger: logger_default,
1934
- promptOpenIdeLogin: true,
1935
- retryTimeoutMs
1936
- });
1937
- logger_default.info(i18nText("当前重试策略不允许继续重试。", "Current retry policy does not allow further retries."));
1938
- return "cancel";
1939
- }
1940
- return await promptWechatIdeLoginRetry({
1941
- error: errorLike,
1942
- logger: logger_default,
1943
- promptOpenIdeLogin: true,
1944
- retryTimeoutMs
1945
- });
1946
- }
1947
- function flushExecutionOutput(result) {
1948
- if (!result || typeof result !== "object") return;
1949
- const candidate = result;
1950
- if (typeof candidate.stdout === "string" && candidate.stdout) process.stdout.write(candidate.stdout);
1951
- if (typeof candidate.stderr === "string" && candidate.stderr) process.stderr.write(candidate.stderr);
1952
- }
1953
- /**
1954
- * @description 运行微信开发者工具 CLI,并在登录失效时允许按键重试。
1955
- */
1956
- async function runWechatCliWithRetry(cliPath, argv) {
1957
- const loginRetryOptions = resolveLoginRetryConfig(argv);
1958
- const result = await runWithSuspendedSharedInput(async () => {
1959
- return await runRetryableCommand({
1960
- createCancelError: (result) => createWechatIdeLoginRequiredExitError(unwrapWechatCliExecutionError(result)),
1961
- execute: async () => {
1962
- try {
1963
- return {
1964
- kind: "result",
1965
- value: await execute(cliPath, loginRetryOptions.runtimeArgv, {
1966
- pipeStdout: false,
1967
- pipeStderr: false
1968
- })
1969
- };
1970
- } catch (error) {
1971
- if (!isWechatIdeLoginRequiredError(error)) throw error;
1972
- return {
1973
- error,
1974
- kind: "retryable"
1975
- };
1976
- }
1977
- },
1978
- isRetryableResult: (result) => result.kind === "retryable" || isWechatIdeLoginRequiredError(result.value),
1979
- onRetry: () => {
1980
- logger_default.info(i18nText("正在重试连接微信开发者工具...", "Retrying to connect Wechat DevTools..."));
1981
- },
1982
- promptRetry: async (result, retryCount) => {
1983
- return await promptLoginRetry(unwrapWechatCliExecutionError(result), loginRetryOptions, retryCount);
1984
- },
1985
- shouldRetry: (action) => action === "retry"
1986
- });
1987
- });
1988
- if (result.kind === "retryable") throw createWechatIdeLoginRequiredExitError(result.error);
1989
- if (isWechatIdeLoginRequiredError(result.value)) throw createWechatIdeLoginRequiredExitError(result.value);
1990
- flushExecutionOutput(result.value);
1991
- }
1992
- //#endregion
1993
- //#region src/cli/run-wechat-cli.ts
1994
- function shouldBootstrapWechatDevtools(command) {
1995
- return command === "open" || command === "auto" || command === "auto-preview";
1996
- }
1997
- function appendOptionValue(argv, sourceArgv, optionName) {
1998
- const value = readOptionValue(sourceArgv, optionName);
1999
- if (value !== void 0) argv.push(optionName, value);
2000
- }
2001
- function createAutoPreviewWakeArgv(argv, trustProject) {
2002
- if (argv[0] !== "auto-preview") return;
2003
- const projectPath = readOptionValue(argv, "--project");
2004
- const appid = readOptionValue(argv, "--appid");
2005
- if (!projectPath && !appid) return;
2006
- const wakeArgv = ["open"];
2007
- appendOptionValue(wakeArgv, argv, "--project");
2008
- appendOptionValue(wakeArgv, argv, "--appid");
2009
- appendOptionValue(wakeArgv, argv, "--ext-appid");
2010
- if (trustProject === true) wakeArgv.push("--trust-project");
2011
- return wakeArgv;
2012
- }
2013
- function resolveBooleanCliOption(argv, optionName) {
2014
- if (argv.includes(optionName)) return true;
2015
- const rawValue = readOptionValue(argv, optionName);
2016
- if (rawValue === void 0) return;
2017
- const normalized = rawValue.trim().toLowerCase();
2018
- if (normalized === "" || normalized === "true" || normalized === "1" || normalized === "on") return true;
2019
- if (normalized === "false" || normalized === "0" || normalized === "off") return false;
2020
- return true;
2021
- }
2022
- async function handleMissingCliPath(source) {
2023
- const message = source === "custom" ? i18nText("在当前自定义路径中未找到微信web开发者命令行工具,请重新指定路径。", "Cannot find Wechat Web DevTools CLI in custom path, please reconfigure it.") : i18nText(`未检测到微信web开发者命令行工具,请执行 ${colors.bold(colors.green("weapp-ide-cli config"))} 指定路径。`, `Wechat Web DevTools CLI not found, please run ${colors.bold(colors.green("weapp-ide-cli config"))} to configure it.`);
2024
- logger_default.warn(message);
2025
- await promptForCliPath();
2026
- }
2027
- async function maybeBootstrapWechatDevtoolsSettings(argv) {
2028
- const command = argv[0];
2029
- if (!shouldBootstrapWechatDevtools(command)) return;
2030
- const config = await readCustomConfig();
2031
- if (config.autoBootstrapDevtools === false) return;
2032
- const projectPath = readOptionValue(argv, "--project");
2033
- const trustProjectOption = resolveBooleanCliOption(argv, "--trust-project");
2034
- const trustProject = trustProjectOption === void 0 ? config.autoTrustProject ?? false : trustProjectOption;
2035
- await bootstrapWechatDevtoolsSettings({
2036
- projectPath,
2037
- trustProject
2038
- });
2039
- return { trustProject };
2040
- }
2041
- /**
2042
- * @description 执行微信开发者工具 CLI 阶段,包括环境检查、路径解析、bootstrap 与登录重试。
2043
- */
2044
- async function runWechatCliCommand(argv) {
2045
- if (!isOperatingSystemSupported(operatingSystemName)) {
2046
- logger_default.warn(i18nText(`微信web开发者工具不支持当前平台:${operatingSystemName} !`, `Wechat Web DevTools CLI is not supported on current platform: ${operatingSystemName}!`));
2047
- return;
2048
- }
2049
- const { cliPath, source } = await resolveCliPath();
2050
- if (!cliPath) {
2051
- await handleMissingCliPath(source);
2052
- return;
2053
- }
2054
- const wakeArgv = createAutoPreviewWakeArgv(argv, (await maybeBootstrapWechatDevtoolsSettings(argv))?.trustProject);
2055
- if (wakeArgv) await runWechatCliWithRetry(cliPath, wakeArgv);
2056
- await runWechatCliWithRetry(cliPath, argv);
2057
- }
2058
- //#endregion
2059
1248
  //#region src/cli/wechat-command-schema.ts
2060
1249
  const CACHE_CLEAN_TYPES = [
2061
1250
  "storage",
@@ -2140,263 +1329,6 @@ function validateWechatCliCommandArgs(argv) {
2140
1329
  }
2141
1330
  }
2142
1331
  //#endregion
2143
- //#region src/cli/wechat-commands.ts
2144
- function appendProjectLocatorArgv(argv, options) {
2145
- if (options.projectPath) argv.push("--project", path.resolve(options.projectPath));
2146
- if (options.appid) argv.push("--appid", options.appid);
2147
- if (options.extAppid) argv.push("--ext-appid", options.extAppid);
2148
- }
2149
- /**
2150
- * @description 调用微信开发者工具 open 命令。
2151
- */
2152
- async function openWechatIde(options = {}) {
2153
- const argv = ["open"];
2154
- appendProjectLocatorArgv(argv, options);
2155
- if (options.platform) argv.push("--platform", options.platform);
2156
- if (options.trustProject) argv.push("--trust-project");
2157
- await runWechatCliCommand(argv);
2158
- }
2159
- /**
2160
- * @description 调用微信开发者工具 login 命令。
2161
- */
2162
- async function loginWechatIde(options = {}) {
2163
- const argv = ["login"];
2164
- if (options.qrFormat) argv.push("--qr-format", options.qrFormat);
2165
- if (options.qrOutput) argv.push("--qr-output", path.resolve(options.qrOutput));
2166
- if (options.qrSize) argv.push("--qr-size", options.qrSize);
2167
- if (options.resultOutput) argv.push("--result-output", path.resolve(options.resultOutput));
2168
- await runWechatCliCommand(argv);
2169
- }
2170
- /**
2171
- * @description 调用微信开发者工具 islogin 命令。
2172
- */
2173
- async function isWechatIdeLoggedIn() {
2174
- await runWechatCliCommand(["islogin"]);
2175
- }
2176
- /**
2177
- * @description 调用微信开发者工具 build-npm 命令。
2178
- */
2179
- async function buildWechatIdeNpm(options = {}) {
2180
- const argv = [
2181
- "build-npm",
2182
- "--project",
2183
- path.resolve(options.projectPath ?? process.cwd())
2184
- ];
2185
- if (options.compileType) argv.push("--compile-type", options.compileType);
2186
- await runWechatCliCommand(argv);
2187
- }
2188
- /**
2189
- * @description 调用微信开发者工具 preview 命令。
2190
- */
2191
- async function previewWechatIde(options = {}) {
2192
- const argv = ["preview"];
2193
- appendProjectLocatorArgv(argv, options);
2194
- if (options.qrFormat) argv.push("--qr-format", options.qrFormat);
2195
- if (options.qrOutput) argv.push("--qr-output", path.resolve(options.qrOutput));
2196
- if (options.qrSize) argv.push("--qr-size", options.qrSize);
2197
- if (options.infoOutput) argv.push("--info-output", path.resolve(options.infoOutput));
2198
- if (options.compileCondition) argv.push("--compile-condition", options.compileCondition);
2199
- await runWechatCliCommand(argv);
2200
- }
2201
- /**
2202
- * @description 调用微信开发者工具 auto-preview 命令。
2203
- */
2204
- async function autoPreviewWechatIde(options = {}) {
2205
- const argv = ["auto-preview"];
2206
- appendProjectLocatorArgv(argv, options);
2207
- if (options.infoOutput) argv.push("--info-output", path.resolve(options.infoOutput));
2208
- if (options.compileCondition) argv.push("--compile-condition", options.compileCondition);
2209
- await runWechatCliCommand(argv);
2210
- }
2211
- /**
2212
- * @description 调用微信开发者工具 auto 命令。
2213
- */
2214
- async function autoWechatIde(options = {}) {
2215
- const argv = ["auto"];
2216
- appendProjectLocatorArgv(argv, options);
2217
- if (options.port) argv.push("--auto-port", options.port);
2218
- if (options.account) argv.push("--auto-account", options.account);
2219
- if (options.testTicket) argv.push("--test-ticket", options.testTicket);
2220
- if (options.ticket) argv.push("--ticket", options.ticket);
2221
- if (options.trustProject) argv.push("--trust-project");
2222
- await runWechatCliCommand(argv);
2223
- }
2224
- /**
2225
- * @description 调用微信开发者工具 auto-replay 命令。
2226
- */
2227
- async function autoReplayWechatIde(options = {}) {
2228
- const argv = ["auto-replay"];
2229
- appendProjectLocatorArgv(argv, options);
2230
- if (options.port) argv.push("--auto-port", options.port);
2231
- if (options.account) argv.push("--auto-account", options.account);
2232
- if (options.replayAll) argv.push("--replay-all");
2233
- if (options.replayConfigPath) argv.push("--replay-config-path", path.resolve(options.replayConfigPath));
2234
- if (options.testTicket) argv.push("--test-ticket", options.testTicket);
2235
- if (options.ticket) argv.push("--ticket", options.ticket);
2236
- if (options.trustProject) argv.push("--trust-project");
2237
- await runWechatCliCommand(argv);
2238
- }
2239
- /**
2240
- * @description 调用微信开发者工具 upload 命令。
2241
- */
2242
- async function uploadWechatIde(options) {
2243
- const argv = ["upload"];
2244
- appendProjectLocatorArgv(argv, options);
2245
- argv.push("--version", options.version, "--desc", options.desc);
2246
- if (options.infoOutput) argv.push("--info-output", path.resolve(options.infoOutput));
2247
- await runWechatCliCommand(argv);
2248
- }
2249
- /**
2250
- * @description 调用微信开发者工具 close 命令。
2251
- */
2252
- async function closeWechatIdeProject() {
2253
- await runWechatCliCommand(["close"]);
2254
- }
2255
- /**
2256
- * @description 调用微信开发者工具 quit 命令。
2257
- */
2258
- async function quitWechatIde() {
2259
- await runWechatCliCommand(["quit"]);
2260
- }
2261
- /**
2262
- * @description 调用微信开发者工具 cache 命令。
2263
- */
2264
- async function clearWechatIdeCache(options) {
2265
- await runWechatCliCommand([
2266
- "cache",
2267
- "--clean",
2268
- options.clean
2269
- ]);
2270
- }
2271
- /**
2272
- * @description 调用微信开发者工具 open-other 命令。
2273
- */
2274
- async function openWechatIdeOtherProject(_options = {}) {
2275
- await runWechatCliCommand(["open-other"]);
2276
- }
2277
- /**
2278
- * @description 通过微信开发者工具 HTTP 服务端口重置指定项目的 fileutils 状态。
2279
- */
2280
- async function resetWechatIdeFileUtils(options) {
2281
- await resetWechatIdeFileUtilsByHttp(path.resolve(options.projectPath));
2282
- }
2283
- function createAutomatorSessionOptions(options) {
2284
- return {
2285
- ...options.port ? { port: options.port } : {},
2286
- preferOpenedSession: options.preferOpenedSession ?? true,
2287
- projectPath: path.resolve(options.projectPath),
2288
- ...options.sessionId ? { sessionId: options.sessionId } : {},
2289
- sharedSession: options.sharedSession ?? true,
2290
- timeout: options.timeout
2291
- };
2292
- }
2293
- /**
2294
- * @description 通过已打开或新建的 automator 会话获取开发者工具基础信息。
2295
- */
2296
- async function getWechatIdeToolInfo(options) {
2297
- return await withMiniProgram(createAutomatorSessionOptions(options), async (miniProgram) => {
2298
- return await miniProgram.toolInfo();
2299
- });
2300
- }
2301
- /**
2302
- * @description 通过已打开或新建的 automator 会话执行项目编译。
2303
- */
2304
- async function compileWechatIdeByAutomator(options) {
2305
- return await withMiniProgram(createAutomatorSessionOptions(options), async (miniProgram) => {
2306
- return await miniProgram.compile({ force: options.force });
2307
- });
2308
- }
2309
- /**
2310
- * @description 通过已打开或新建的 automator 会话清理开发者工具缓存。
2311
- */
2312
- async function clearWechatIdeCacheByAutomator(options) {
2313
- return await withMiniProgram(createAutomatorSessionOptions(options), async (miniProgram) => {
2314
- return await miniProgram.clearCache({ clean: options.clean });
2315
- });
2316
- }
2317
- /**
2318
- * @description 通过已打开或新建的 automator 会话获取当前 ticket。
2319
- */
2320
- async function getWechatIdeTicket(options) {
2321
- return await withMiniProgram(createAutomatorSessionOptions(options), async (miniProgram) => {
2322
- return await miniProgram.getTicket();
2323
- });
2324
- }
2325
- /**
2326
- * @description 通过已打开或新建的 automator 会话设置 ticket。
2327
- */
2328
- async function setWechatIdeTicket(options) {
2329
- return await withMiniProgram(createAutomatorSessionOptions(options), async (miniProgram) => {
2330
- await miniProgram.setTicket(options.ticket);
2331
- });
2332
- }
2333
- /**
2334
- * @description 通过已打开或新建的 automator 会话刷新 ticket。
2335
- */
2336
- async function refreshWechatIdeTicket(options) {
2337
- return await withMiniProgram(createAutomatorSessionOptions(options), async (miniProgram) => {
2338
- await miniProgram.refreshTicket();
2339
- });
2340
- }
2341
- /**
2342
- * @description 通过已打开或新建的 automator 会话获取测试账号列表。
2343
- */
2344
- async function getWechatIdeTestAccounts(options) {
2345
- return await withMiniProgram(createAutomatorSessionOptions(options), async (miniProgram) => {
2346
- return await miniProgram.testAccounts();
2347
- });
2348
- }
2349
- /**
2350
- * @description 调用微信开发者工具 build-apk 命令。
2351
- */
2352
- async function buildWechatIdeApk(options) {
2353
- const argv = [
2354
- "build-apk",
2355
- "--key-store",
2356
- path.resolve(options.keyStore),
2357
- "--key-alias",
2358
- options.keyAlias,
2359
- "--key-pass",
2360
- options.keyPass,
2361
- "--store-pass",
2362
- options.storePass,
2363
- "--output",
2364
- path.resolve(options.output)
2365
- ];
2366
- if (options.useAab !== void 0) argv.push("--use-aab", String(options.useAab));
2367
- if (options.desc) argv.push("--desc", options.desc);
2368
- if (options.isUploadResourceBundle) argv.push("--isUploadResourceBundle");
2369
- if (options.resourceBundleVersion) argv.push("--resourceBundleVersion", options.resourceBundleVersion);
2370
- if (options.resourceBundleDesc) argv.push("--resourceBundleDesc", options.resourceBundleDesc);
2371
- await runWechatCliCommand(argv);
2372
- }
2373
- /**
2374
- * @description 调用微信开发者工具 build-ipa 命令。
2375
- */
2376
- async function buildWechatIdeIpa(options) {
2377
- const argv = [
2378
- "build-ipa",
2379
- "--output",
2380
- path.resolve(options.output),
2381
- "--isDistribute",
2382
- String(options.isDistribute)
2383
- ];
2384
- if (options.isRemoteBuild !== void 0) argv.push("--isRemoteBuild", String(options.isRemoteBuild));
2385
- if (options.profilePath) argv.push("--profilePath", path.resolve(options.profilePath));
2386
- if (options.certificateName) argv.push("--certificateName", options.certificateName);
2387
- if (options.p12Path) argv.push("--p12Path", path.resolve(options.p12Path));
2388
- if (options.p12Password) argv.push("--p12Password", options.p12Password);
2389
- if (options.tpnsProfilePath) argv.push("--tpnsProfilePath", path.resolve(options.tpnsProfilePath));
2390
- if (options.isUploadBeta !== void 0) argv.push("--isUploadBeta", String(options.isUploadBeta));
2391
- if (options.isUploadResourceBundle) argv.push("--isUploadResourceBundle");
2392
- if (options.resourceBundleVersion) argv.push("--resourceBundleVersion", options.resourceBundleVersion);
2393
- if (options.resourceBundleDesc) argv.push("--resourceBundleDesc", options.resourceBundleDesc);
2394
- if (options.versionName) argv.push("--versionName", options.versionName);
2395
- if (options.versionCode !== void 0) argv.push("--versionCode", String(options.versionCode));
2396
- if (options.versionDesc) argv.push("--versionDesc", options.versionDesc);
2397
- await runWechatCliCommand(argv);
2398
- }
2399
- //#endregion
2400
1332
  //#region src/cli/wechat-dispatch.ts
2401
1333
  function hasOption(argv, optionName) {
2402
1334
  return argv.includes(optionName) || argv.some((token) => token.startsWith(`${optionName}=`));
@@ -2673,7 +1605,7 @@ async function parse(argv) {
2673
1605
  return;
2674
1606
  }
2675
1607
  if (matchedCommand === "mcp") {
2676
- const { runMcpCommand } = await import("./run-mcp-CTk4KA3y.js");
1608
+ const { runMcpCommand } = await import("./run-mcp-CL909GLy.js");
2677
1609
  await runMcpCommand(argv.slice(1));
2678
1610
  return;
2679
1611
  }
@@ -2691,4 +1623,4 @@ async function parse(argv) {
2691
1623
  await runWechatCliCommand(formattedArgv);
2692
1624
  }
2693
1625
  //#endregion
2694
- export { requestWechatDevtoolsHttp as $, RETRY_CANCEL_KEYS as A, waitForRetryKeypress as B, refreshWechatIdeTicket as C, readOptionValue as Ct, validateWechatCliCommandArgs as D, uploadWechatIde as E, formatRetryHotkeyPrompt as F, transformArgv as G, execute as H, formatWechatIdeLoginRequiredError as I, runWechatIdeEngineBuild as J, startForwardConsole as K, isWechatIdeLoginRequiredError as L, RETRY_PROMPT_INITIAL_IGNORE_MS as M, createWechatIdeLoginRequiredExitError as N, runWechatCliWithRetry as O, extractExecutionErrorText as P, pollWechatIdeEngineBuildResultByHttp as Q, promptRetryKeypress as R, quitWechatIde as S, readBooleanOption as St, setWechatIdeTicket as T, createAlias as U, runMinidev as V, createPathCompat as W, WECHAT_DEVTOOLS_ENGINE_BUILD_STATUSES as X, runWechatIdeEngineBuildByHttp as Y, openWechatIdeProjectByHttp as Z, isWechatIdeLoggedIn as _, parseScreenshotArgs as _t, autoReplayWechatIde as a, runWithSuspendedSharedInput as at, openWechatIdeOtherProject as b, printCompareHelp as bt, buildWechatIdeIpa as c, MCP_COMMAND_NAME as ct, clearWechatIdeCacheByAutomator as d, WECHAT_CLI_COMMAND_NAMES as dt, resetWechatIdeFileUtilsByHttp as et, closeWechatIdeProject as f, isWeappIdeTopLevelCommand as ft, getWechatIdeToolInfo as g, runAutomatorCommand as gt, getWechatIdeTicket as h, isAutomatorCommand as ht, autoPreviewWechatIde as i, createSharedInputSession as it, RETRY_CONFIRM_KEYS as j, runRetryableCommand as k, buildWechatIdeNpm as l, MINIDEV_NAMESPACE_COMMAND_NAMES as lt, getWechatIdeTestAccounts as m, getAutomatorCommandHelp as mt, parse as n, handleConfigCommand as nt, autoWechatIde as o, waitForExclusiveKeypress as ot, compileWechatIdeByAutomator as p, AUTOMATOR_COMMAND_NAMES as pt, isWechatIdeEngineBuildEndpointMissingError as q, dispatchWechatCliCommand as r, promptForCliPath as rt, buildWechatIdeApk as s, CONFIG_COMMAND_NAME as st, createCli as t, startWechatIdeEngineBuildByHttp as tt, clearWechatIdeCache as u, WEAPP_IDE_TOP_LEVEL_COMMAND_NAMES as ut, loginWechatIde as v, printScreenshotHelp as vt, resetWechatIdeFileUtils as w, removeOption as wt, previewWechatIde as x, parseAutomatorArgs as xt, openWechatIde as y, parseCompareArgs as yt, promptWechatIdeLoginRetry as z };
1626
+ export { parseCompareArgs as C, printScreenshotHelp as S, AUTOMATOR_COMMAND_NAMES as _, runMinidev as a, runAutomatorCommand as b, runWechatIdeEngineBuild as c, CONFIG_COMMAND_NAME as d, MCP_COMMAND_NAME as f, isWeappIdeTopLevelCommand as g, WECHAT_CLI_COMMAND_NAMES as h, validateWechatCliCommandArgs as i, runWechatIdeEngineBuildByHttp as l, WEAPP_IDE_TOP_LEVEL_COMMAND_NAMES as m, parse as n, startForwardConsole as o, MINIDEV_NAMESPACE_COMMAND_NAMES as p, dispatchWechatCliCommand as r, isWechatIdeEngineBuildEndpointMissingError as s, createCli as t, handleConfigCommand as u, getAutomatorCommandHelp as v, printCompareHelp as w, parseScreenshotArgs as x, isAutomatorCommand as y };