weapp-ide-cli 5.0.3 → 5.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -1
- package/dist/{chunk-A26E3I4U.js → chunk-QTQD5BFV.js} +115 -22
- package/dist/cli.js +10 -1
- package/dist/index.d.ts +14 -3
- package/dist/index.js +3 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -110,10 +110,27 @@ weapp config
|
|
|
110
110
|
2. 首次运行前可通过 `weapp config` 写入 CLI 路径,也可在 CI 中直接向 `~/.weapp-ide-cli/config.json` 写入。
|
|
111
111
|
3. 在自动化流程中建议加上 `--qr-output`、`--result-output` 等参数,以便收集产物或日志。
|
|
112
112
|
|
|
113
|
+
推荐在 CI 或非交互脚本里显式启用非交互模式,避免登录失效时卡在按键等待:
|
|
114
|
+
|
|
115
|
+
```sh
|
|
116
|
+
weapp build-npm -p --non-interactive
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
登录重试相关参数:
|
|
120
|
+
|
|
121
|
+
- `--non-interactive`:非交互模式,登录失效时直接失败(退出码语义保留为 `10`)。
|
|
122
|
+
- `--login-retry=never|once|always`:控制登录失效后的重试策略。
|
|
123
|
+
- `--login-retry-timeout=<ms>`:交互重试等待超时(默认 `30000`)。
|
|
124
|
+
|
|
125
|
+
当检测到以下场景时,会自动启用非交互模式:
|
|
126
|
+
|
|
127
|
+
- `CI=true`
|
|
128
|
+
- `stdin` 非 TTY
|
|
129
|
+
|
|
113
130
|
## 常见问题
|
|
114
131
|
|
|
115
132
|
- **命令执行后无反应**:请确认微信开发者工具已开启服务端口,并尝试重新登录或升级工具版本。
|
|
116
|
-
- **提示 `需要重新登录` 或 `code: 10
|
|
133
|
+
- **提示 `需要重新登录` 或 `code: 10`**:表示微信开发者工具登录态失效。交互模式下可按 `r` 重试,按 `q`、`Esc` 或 `Ctrl+C` 取消;非交互模式(含 CI / 非TTY)会直接失败返回非 0。
|
|
117
134
|
- **提示未找到 CLI**:检查配置文件中的路径是否真实存在,可使用绝对路径避免解析误差。
|
|
118
135
|
- **Linux 环境报错**:需安装社区版工具并将 `wechat-devtools-cli` 加入 `PATH`,否则只能手动指定路径。
|
|
119
136
|
|
|
@@ -328,6 +328,16 @@ function formatWechatIdeLoginRequiredError(error) {
|
|
|
328
328
|
}
|
|
329
329
|
return lines.join("\n");
|
|
330
330
|
}
|
|
331
|
+
function createWechatIdeLoginRequiredExitError(error, reason) {
|
|
332
|
+
const summary = formatWechatIdeLoginRequiredError(error);
|
|
333
|
+
const message = reason ? `${reason}
|
|
334
|
+
${summary}` : summary;
|
|
335
|
+
const loginError = new Error(message);
|
|
336
|
+
loginError.name = "WechatIdeLoginRequiredError";
|
|
337
|
+
loginError.code = 10;
|
|
338
|
+
loginError.exitCode = 10;
|
|
339
|
+
return loginError;
|
|
340
|
+
}
|
|
331
341
|
function extractLoginRequiredMessage(text) {
|
|
332
342
|
if (!text) {
|
|
333
343
|
return "";
|
|
@@ -345,9 +355,10 @@ function extractLoginRequiredMessage(text) {
|
|
|
345
355
|
}
|
|
346
356
|
return firstLine.replace(/^\[error\]\s*/i, "").replace(/^error\s*:\s*/i, "").slice(0, 120);
|
|
347
357
|
}
|
|
348
|
-
async function waitForRetryKeypress() {
|
|
358
|
+
async function waitForRetryKeypress(options = {}) {
|
|
359
|
+
const { timeoutMs = 3e4 } = options;
|
|
349
360
|
if (!process5.stdin.isTTY) {
|
|
350
|
-
return
|
|
361
|
+
return "cancel";
|
|
351
362
|
}
|
|
352
363
|
emitKeypressEvents(process5.stdin);
|
|
353
364
|
const hasSetRawMode = typeof process5.stdin.setRawMode === "function";
|
|
@@ -356,7 +367,13 @@ async function waitForRetryKeypress() {
|
|
|
356
367
|
}
|
|
357
368
|
process5.stdin.resume();
|
|
358
369
|
return new Promise((resolve) => {
|
|
370
|
+
let settled = false;
|
|
371
|
+
const normalizedTimeoutMs = Number.isFinite(timeoutMs) && timeoutMs > 0 ? timeoutMs : 3e4;
|
|
372
|
+
const timeout = setTimeout(() => {
|
|
373
|
+
done("timeout");
|
|
374
|
+
}, normalizedTimeoutMs);
|
|
359
375
|
const cleanup = () => {
|
|
376
|
+
clearTimeout(timeout);
|
|
360
377
|
process5.stdin.off("keypress", onKeypress);
|
|
361
378
|
if (hasSetRawMode) {
|
|
362
379
|
process5.stdin.setRawMode(false);
|
|
@@ -364,6 +381,10 @@ async function waitForRetryKeypress() {
|
|
|
364
381
|
process5.stdin.pause();
|
|
365
382
|
};
|
|
366
383
|
const done = (value) => {
|
|
384
|
+
if (settled) {
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
387
|
+
settled = true;
|
|
367
388
|
cleanup();
|
|
368
389
|
resolve(value);
|
|
369
390
|
};
|
|
@@ -372,23 +393,24 @@ async function waitForRetryKeypress() {
|
|
|
372
393
|
return;
|
|
373
394
|
}
|
|
374
395
|
if (key.ctrl && key.name === "c") {
|
|
375
|
-
done(
|
|
396
|
+
done("cancel");
|
|
376
397
|
return;
|
|
377
398
|
}
|
|
378
399
|
if (key.name === "r") {
|
|
379
|
-
done(
|
|
400
|
+
done("retry");
|
|
380
401
|
return;
|
|
381
402
|
}
|
|
382
403
|
if (key.name === "q" || key.name === "escape") {
|
|
383
|
-
done(
|
|
404
|
+
done("cancel");
|
|
384
405
|
}
|
|
385
406
|
};
|
|
386
407
|
process5.stdin.on("keypress", onKeypress);
|
|
387
408
|
});
|
|
388
409
|
}
|
|
389
|
-
function formatRetryHotkeyPrompt() {
|
|
410
|
+
function formatRetryHotkeyPrompt(timeoutMs = 3e4) {
|
|
390
411
|
const highlight = (key) => highlightHotkey(key);
|
|
391
|
-
|
|
412
|
+
const timeoutSeconds = Math.max(1, Math.ceil(timeoutMs / 1e3));
|
|
413
|
+
return `\u6309 ${highlight("r")} \u91CD\u8BD5\uFF0C\u6309 ${highlight("q")} / ${highlight("Esc")} / ${highlight("Ctrl+C")} \u9000\u51FA\uFF08${timeoutSeconds}s \u5185\u65E0\u8F93\u5165\u5C06\u81EA\u52A8\u5931\u8D25\uFF09\u3002`;
|
|
392
414
|
}
|
|
393
415
|
function highlightHotkey(key) {
|
|
394
416
|
return colors.bold(colors.green(key));
|
|
@@ -398,6 +420,9 @@ function highlightHotkey(key) {
|
|
|
398
420
|
import process6 from "process";
|
|
399
421
|
var MINIDEV_NAMESPACE = /* @__PURE__ */ new Set(["alipay", "ali", "minidev"]);
|
|
400
422
|
var ALIPAY_PLATFORM_ALIASES = /* @__PURE__ */ new Set(["alipay", "ali", "minidev"]);
|
|
423
|
+
function isStdinInteractive() {
|
|
424
|
+
return Boolean(process6.stdin && process6.stdin.isTTY);
|
|
425
|
+
}
|
|
401
426
|
var ARG_TRANSFORMS = [
|
|
402
427
|
createAlias({ find: "-p", replacement: "--project" }),
|
|
403
428
|
createPathCompat("--result-output"),
|
|
@@ -414,8 +439,10 @@ async function parse(argv) {
|
|
|
414
439
|
return;
|
|
415
440
|
}
|
|
416
441
|
const formattedArgv = transformArgv(argv, ARG_TRANSFORMS);
|
|
417
|
-
|
|
418
|
-
|
|
442
|
+
const loginRetryOptions = resolveLoginRetryOptions(formattedArgv);
|
|
443
|
+
const runtimeArgv = stripLoginRetryControlFlags(formattedArgv);
|
|
444
|
+
if (shouldDelegateOpenToMinidev(runtimeArgv)) {
|
|
445
|
+
await runMinidev(createMinidevOpenArgv(runtimeArgv));
|
|
419
446
|
return;
|
|
420
447
|
}
|
|
421
448
|
if (!isOperatingSystemSupported(operatingSystemName)) {
|
|
@@ -433,11 +460,11 @@ async function parse(argv) {
|
|
|
433
460
|
await promptForCliPath();
|
|
434
461
|
return;
|
|
435
462
|
}
|
|
436
|
-
await runWechatCliWithRetry(cliPath,
|
|
463
|
+
await runWechatCliWithRetry(cliPath, runtimeArgv, loginRetryOptions);
|
|
437
464
|
}
|
|
438
|
-
async function runWechatCliWithRetry(cliPath, argv) {
|
|
439
|
-
let
|
|
440
|
-
while (
|
|
465
|
+
async function runWechatCliWithRetry(cliPath, argv, options) {
|
|
466
|
+
let retryCount = 0;
|
|
467
|
+
while (true) {
|
|
441
468
|
try {
|
|
442
469
|
const result = await execute(cliPath, argv, {
|
|
443
470
|
pipeStdout: false,
|
|
@@ -447,31 +474,96 @@ async function runWechatCliWithRetry(cliPath, argv) {
|
|
|
447
474
|
flushExecutionOutput(result);
|
|
448
475
|
return;
|
|
449
476
|
}
|
|
450
|
-
|
|
451
|
-
if (
|
|
477
|
+
const action = await promptLoginRetry(result, options, retryCount);
|
|
478
|
+
if (action === "retry") {
|
|
479
|
+
retryCount += 1;
|
|
452
480
|
logger_default.info("\u6B63\u5728\u91CD\u8BD5\u8FDE\u63A5\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177...");
|
|
481
|
+
continue;
|
|
453
482
|
}
|
|
483
|
+
throw createWechatIdeLoginRequiredExitError(result);
|
|
454
484
|
} catch (error) {
|
|
455
485
|
if (!isWechatIdeLoginRequiredError(error)) {
|
|
456
486
|
throw error;
|
|
457
487
|
}
|
|
458
|
-
|
|
459
|
-
if (
|
|
488
|
+
const action = await promptLoginRetry(error, options, retryCount);
|
|
489
|
+
if (action === "retry") {
|
|
490
|
+
retryCount += 1;
|
|
460
491
|
logger_default.info("\u6B63\u5728\u91CD\u8BD5\u8FDE\u63A5\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177...");
|
|
492
|
+
continue;
|
|
461
493
|
}
|
|
494
|
+
throw createWechatIdeLoginRequiredExitError(error);
|
|
462
495
|
}
|
|
463
496
|
}
|
|
464
497
|
}
|
|
465
|
-
async function promptLoginRetry(errorLike) {
|
|
498
|
+
async function promptLoginRetry(errorLike, options, retryCount) {
|
|
499
|
+
const {
|
|
500
|
+
nonInteractive,
|
|
501
|
+
retryMode,
|
|
502
|
+
retryTimeoutMs
|
|
503
|
+
} = options;
|
|
466
504
|
logger_default.error("\u68C0\u6D4B\u5230\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177\u767B\u5F55\u72B6\u6001\u5931\u6548\uFF0C\u8BF7\u5148\u767B\u5F55\u540E\u91CD\u8BD5\u3002");
|
|
467
505
|
logger_default.warn("\u8BF7\u5148\u6253\u5F00\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177\u5B8C\u6210\u767B\u5F55\u3002");
|
|
468
506
|
logger_default.warn(formatWechatIdeLoginRequiredError(errorLike));
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
507
|
+
if (nonInteractive) {
|
|
508
|
+
logger_default.error("\u5F53\u524D\u4E3A\u975E\u4EA4\u4E92\u6A21\u5F0F\uFF0C\u68C0\u6D4B\u5230\u767B\u5F55\u5931\u6548\u540E\u76F4\u63A5\u5931\u8D25\u3002");
|
|
509
|
+
return "cancel";
|
|
510
|
+
}
|
|
511
|
+
const shouldAllowRetry = retryMode === "always" || retryMode === "once" && retryCount < 1;
|
|
512
|
+
if (!shouldAllowRetry) {
|
|
513
|
+
logger_default.info("\u5F53\u524D\u91CD\u8BD5\u7B56\u7565\u4E0D\u5141\u8BB8\u7EE7\u7EED\u91CD\u8BD5\u3002");
|
|
514
|
+
return "cancel";
|
|
515
|
+
}
|
|
516
|
+
logger_default.info(formatRetryHotkeyPrompt(retryTimeoutMs));
|
|
517
|
+
const action = await waitForRetryKeypress({ timeoutMs: retryTimeoutMs });
|
|
518
|
+
if (action === "timeout") {
|
|
519
|
+
logger_default.error(`\u7B49\u5F85\u767B\u5F55\u91CD\u8BD5\u8F93\u5165\u8D85\u65F6\uFF08${retryTimeoutMs}ms\uFF09\uFF0C\u5DF2\u81EA\u52A8\u53D6\u6D88\u3002`);
|
|
520
|
+
return "cancel";
|
|
521
|
+
}
|
|
522
|
+
if (action !== "retry") {
|
|
472
523
|
logger_default.info("\u5DF2\u53D6\u6D88\u91CD\u8BD5\u3002\u5B8C\u6210\u767B\u5F55\u540E\u8BF7\u91CD\u65B0\u6267\u884C\u5F53\u524D\u547D\u4EE4\u3002");
|
|
524
|
+
return "cancel";
|
|
473
525
|
}
|
|
474
|
-
return
|
|
526
|
+
return "retry";
|
|
527
|
+
}
|
|
528
|
+
function resolveLoginRetryOptions(argv) {
|
|
529
|
+
const nonInteractiveFlag = readBooleanFlag(argv, "--non-interactive");
|
|
530
|
+
const ciMode = process6.env.CI === "true";
|
|
531
|
+
const nonTtyStdin = !isStdinInteractive();
|
|
532
|
+
const nonInteractive = nonInteractiveFlag || ciMode || nonTtyStdin;
|
|
533
|
+
const retryModeRaw = readOptionValue(argv, "--login-retry");
|
|
534
|
+
const retryMode = normalizeLoginRetryMode(retryModeRaw, nonInteractive);
|
|
535
|
+
const retryTimeoutRaw = readOptionValue(argv, "--login-retry-timeout");
|
|
536
|
+
const retryTimeoutMs = normalizeLoginRetryTimeout(retryTimeoutRaw);
|
|
537
|
+
return {
|
|
538
|
+
nonInteractive,
|
|
539
|
+
retryMode,
|
|
540
|
+
retryTimeoutMs
|
|
541
|
+
};
|
|
542
|
+
}
|
|
543
|
+
function normalizeLoginRetryMode(value, nonInteractive) {
|
|
544
|
+
if (value === "never" || value === "once" || value === "always") {
|
|
545
|
+
return value;
|
|
546
|
+
}
|
|
547
|
+
return nonInteractive ? "never" : "always";
|
|
548
|
+
}
|
|
549
|
+
function normalizeLoginRetryTimeout(value) {
|
|
550
|
+
if (!value) {
|
|
551
|
+
return 3e4;
|
|
552
|
+
}
|
|
553
|
+
const parsed = Number.parseInt(value, 10);
|
|
554
|
+
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
555
|
+
return 3e4;
|
|
556
|
+
}
|
|
557
|
+
return parsed;
|
|
558
|
+
}
|
|
559
|
+
function readBooleanFlag(argv, optionName) {
|
|
560
|
+
return argv.includes(optionName);
|
|
561
|
+
}
|
|
562
|
+
function stripLoginRetryControlFlags(argv) {
|
|
563
|
+
let next = removeOption(argv, "--login-retry");
|
|
564
|
+
next = removeOption(next, "--login-retry-timeout");
|
|
565
|
+
next = removeOption(next, "--non-interactive");
|
|
566
|
+
return next;
|
|
475
567
|
}
|
|
476
568
|
function shouldDelegateOpenToMinidev(argv) {
|
|
477
569
|
if (argv[0] !== "open") {
|
|
@@ -562,6 +654,7 @@ export {
|
|
|
562
654
|
isWechatIdeLoginRequiredError,
|
|
563
655
|
extractExecutionErrorText,
|
|
564
656
|
formatWechatIdeLoginRequiredError,
|
|
657
|
+
createWechatIdeLoginRequiredExitError,
|
|
565
658
|
waitForRetryKeypress,
|
|
566
659
|
formatRetryHotkeyPrompt,
|
|
567
660
|
parse
|
package/dist/cli.js
CHANGED
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
import {
|
|
2
2
|
logger_default,
|
|
3
3
|
parse
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-QTQD5BFV.js";
|
|
5
5
|
|
|
6
6
|
// src/cli.ts
|
|
7
7
|
import process from "process";
|
|
8
8
|
var argv = process.argv.slice(2);
|
|
9
9
|
parse(argv).catch((err) => {
|
|
10
10
|
logger_default.error(err);
|
|
11
|
+
if (typeof err?.exitCode === "number") {
|
|
12
|
+
process.exitCode = err.exitCode;
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
if (typeof err?.code === "number") {
|
|
16
|
+
process.exitCode = err.code;
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
process.exitCode = 1;
|
|
11
20
|
});
|
package/dist/index.d.ts
CHANGED
|
@@ -18,6 +18,10 @@ declare function resolveCliPath(): Promise<{
|
|
|
18
18
|
source: ConfigSource;
|
|
19
19
|
}>;
|
|
20
20
|
|
|
21
|
+
interface RetryKeypressOptions {
|
|
22
|
+
timeoutMs?: number;
|
|
23
|
+
}
|
|
24
|
+
type RetryPromptResult = 'retry' | 'cancel' | 'timeout';
|
|
21
25
|
/**
|
|
22
26
|
* @description 判断是否为微信开发者工具登录失效错误。
|
|
23
27
|
*/
|
|
@@ -30,14 +34,21 @@ declare function extractExecutionErrorText(error: unknown): string;
|
|
|
30
34
|
* @description 将登录失效错误格式化为更易读的摘要。
|
|
31
35
|
*/
|
|
32
36
|
declare function formatWechatIdeLoginRequiredError(error: unknown): string;
|
|
37
|
+
/**
|
|
38
|
+
* @description 创建登录失效专用错误,并携带退出码语义。
|
|
39
|
+
*/
|
|
40
|
+
declare function createWechatIdeLoginRequiredExitError(error: unknown, reason?: string): Error & {
|
|
41
|
+
code: number;
|
|
42
|
+
exitCode: number;
|
|
43
|
+
};
|
|
33
44
|
/**
|
|
34
45
|
* @description 交互等待用户按键重试,按 r 重试,按 q 或 Ctrl+C 取消。
|
|
35
46
|
*/
|
|
36
|
-
declare function waitForRetryKeypress(): Promise<
|
|
47
|
+
declare function waitForRetryKeypress(options?: RetryKeypressOptions): Promise<RetryPromptResult>;
|
|
37
48
|
/**
|
|
38
49
|
* @description 生成重试按键提示,并高亮关键热键。
|
|
39
50
|
*/
|
|
40
|
-
declare function formatRetryHotkeyPrompt(): string;
|
|
51
|
+
declare function formatRetryHotkeyPrompt(timeoutMs?: number): string;
|
|
41
52
|
|
|
42
53
|
/**
|
|
43
54
|
* @description CLI 入口解析与分发
|
|
@@ -144,4 +155,4 @@ declare function execute(cliPath: string, argv: string[], options?: ExecuteOptio
|
|
|
144
155
|
*/
|
|
145
156
|
declare function resolvePath(filePath: string): string;
|
|
146
157
|
|
|
147
|
-
export { type ArgvTransform, type BaseConfig, type ConfigSource, type ResolvedConfig, type SupportedPlatform, SupportedPlatformsMap, createAlias, createCustomConfig, createPathCompat, defaultCustomConfigDirPath, defaultCustomConfigFilePath, execute, extractExecutionErrorText, formatRetryHotkeyPrompt, formatWechatIdeLoginRequiredError, getConfig, getDefaultCliPath, isOperatingSystemSupported, isWechatIdeLoginRequiredError, operatingSystemName, parse, promptForCliPath, resolveCliPath, resolvePath, runMinidev, transformArgv, waitForRetryKeypress };
|
|
158
|
+
export { type ArgvTransform, type BaseConfig, type ConfigSource, type ResolvedConfig, type RetryKeypressOptions, type RetryPromptResult, type SupportedPlatform, SupportedPlatformsMap, createAlias, createCustomConfig, createPathCompat, createWechatIdeLoginRequiredExitError, defaultCustomConfigDirPath, defaultCustomConfigFilePath, execute, extractExecutionErrorText, formatRetryHotkeyPrompt, formatWechatIdeLoginRequiredError, getConfig, getDefaultCliPath, isOperatingSystemSupported, isWechatIdeLoginRequiredError, operatingSystemName, parse, promptForCliPath, resolveCliPath, resolvePath, runMinidev, transformArgv, waitForRetryKeypress };
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
createAlias,
|
|
4
4
|
createCustomConfig,
|
|
5
5
|
createPathCompat,
|
|
6
|
+
createWechatIdeLoginRequiredExitError,
|
|
6
7
|
defaultCustomConfigDirPath,
|
|
7
8
|
defaultCustomConfigFilePath,
|
|
8
9
|
execute,
|
|
@@ -21,12 +22,13 @@ import {
|
|
|
21
22
|
runMinidev,
|
|
22
23
|
transformArgv,
|
|
23
24
|
waitForRetryKeypress
|
|
24
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-QTQD5BFV.js";
|
|
25
26
|
export {
|
|
26
27
|
SupportedPlatformsMap,
|
|
27
28
|
createAlias,
|
|
28
29
|
createCustomConfig,
|
|
29
30
|
createPathCompat,
|
|
31
|
+
createWechatIdeLoginRequiredExitError,
|
|
30
32
|
defaultCustomConfigDirPath,
|
|
31
33
|
defaultCustomConfigFilePath,
|
|
32
34
|
execute,
|