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.
- package/dist/{automator-session-RrZjw3X5.js → automator-session-CvStbY9I.js} +363 -19
- package/dist/{cli-_qia2--1.js → cli-C9KfpthX.js} +8 -1076
- package/dist/cli.js +2 -2
- package/dist/commands-B4HFVW-Q.js +2 -0
- package/dist/commands-Js_IjVxE.js +1142 -0
- package/dist/index.d.ts +6 -1
- package/dist/index.js +5 -5
- package/dist/run-mcp-CL909GLy.js +2 -0
- package/dist/{run-mcp-By4qRg8l.js → run-mcp-DvHYYX0m.js} +1 -1
- package/package.json +3 -3
- package/dist/commands-D_j5_0eE.js +0 -2
- package/dist/commands-fWDebiQq.js +0 -335
- package/dist/run-mcp-CTk4KA3y.js +0 -2
|
@@ -1,170 +1,15 @@
|
|
|
1
|
-
import {
|
|
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-
|
|
3
|
-
import "./run-mcp-
|
|
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
|
|
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-
|
|
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-
|
|
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 {
|
|
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 };
|