@zhin.js/scaffold-wizard 0.1.9 → 0.2.0

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.
@@ -0,0 +1,90 @@
1
+ /**
2
+ * 微信 iLink(ClawBot)扫码登录流程 — 向导内联实现。
3
+ * 协议与 plugins/adapters/weixin-ilink/src/login.ts 一致(SSOT),
4
+ * 此处复制最小 HTTP 面,避免向导在适配器包安装前产生依赖。
5
+ */
6
+ const DEFAULT_BASE_URL = 'https://ilinkai.weixin.qq.com';
7
+ const DEFAULT_BOT_TYPE = '3';
8
+ const POLL_INTERVAL_MS = 500;
9
+ const QR_LONG_POLL_TIMEOUT_MS = 35_000;
10
+ export class IlinkQrLoginError extends Error {
11
+ reason;
12
+ constructor(message, reason) {
13
+ super(message);
14
+ this.reason = reason;
15
+ this.name = 'IlinkQrLoginError';
16
+ }
17
+ }
18
+ /** 与 adapter login.ts 的 buildBaseInfo 对齐的最小结构。 */
19
+ function buildBaseInfo() {
20
+ return { channel_version: '0.0.0', bot_agent: 'Zhin.js' };
21
+ }
22
+ /**
23
+ * 微信 iLink 扫码登录:获取二维码 → 展示 → 长轮询直至 confirmed。
24
+ * 成功返回 bot_token 等凭证;过期/超时/网络失败抛 IlinkQrLoginError。
25
+ */
26
+ export async function loginWithIlinkQr(options) {
27
+ const fetchImpl = options.fetchImpl ?? fetch;
28
+ const sleep = options.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
29
+ const apiBaseUrl = options.baseUrl ?? DEFAULT_BASE_URL;
30
+ const timeoutMs = options.timeoutMs ?? 480_000;
31
+ let qr;
32
+ try {
33
+ const res = await fetchImpl(`${apiBaseUrl}/ilink/bot/get_bot_qrcode?bot_type=${encodeURIComponent(DEFAULT_BOT_TYPE)}`, {
34
+ method: 'POST',
35
+ headers: { 'content-type': 'application/json' },
36
+ body: JSON.stringify({ local_token_list: [], base_info: buildBaseInfo() }),
37
+ });
38
+ if (!res.ok)
39
+ throw new Error(`HTTP ${res.status}`);
40
+ qr = await res.json();
41
+ }
42
+ catch (error) {
43
+ throw new IlinkQrLoginError(`获取登录二维码失败:${error instanceof Error ? error.message : String(error)}`, 'network');
44
+ }
45
+ const qrcodeUrl = qr.qrcode_img_content || qr.qrcode;
46
+ await options.onQrCode(qrcodeUrl);
47
+ const deadline = Date.now() + timeoutMs;
48
+ let currentBaseUrl = apiBaseUrl;
49
+ let lastStatus;
50
+ while (Date.now() < deadline) {
51
+ let status;
52
+ try {
53
+ const res = await fetchImpl(`${currentBaseUrl}/ilink/bot/get_qrcode_status?qrcode=${encodeURIComponent(qr.qrcode)}`, { signal: AbortSignal.timeout(QR_LONG_POLL_TIMEOUT_MS) });
54
+ if (!res.ok)
55
+ throw new Error(`HTTP ${res.status}`);
56
+ status = await res.json();
57
+ }
58
+ catch {
59
+ // 长轮询超时/瞬断视为继续等待
60
+ await sleep(POLL_INTERVAL_MS);
61
+ continue;
62
+ }
63
+ if (status.status !== lastStatus) {
64
+ lastStatus = status.status;
65
+ options.onStatus?.(status.status);
66
+ }
67
+ if (status.status === 'scaned_but_redirect' && status.redirect_host) {
68
+ currentBaseUrl = status.redirect_host.startsWith('http')
69
+ ? status.redirect_host
70
+ : `https://${status.redirect_host}`;
71
+ }
72
+ if (status.status === 'confirmed' || status.status === 'binded_redirect') {
73
+ if (!status.bot_token) {
74
+ throw new IlinkQrLoginError('扫码成功但未返回 bot_token,请重试或改用手动输入', 'protocol');
75
+ }
76
+ return {
77
+ botToken: status.bot_token,
78
+ ...(status.ilink_user_id ? { ilinkUserId: status.ilink_user_id } : {}),
79
+ ...(status.ilink_endpoint_id ? { ilinkBotId: status.ilink_endpoint_id } : {}),
80
+ baseUrl: status.baseurl ?? currentBaseUrl,
81
+ };
82
+ }
83
+ if (status.status === 'expired') {
84
+ throw new IlinkQrLoginError('二维码已过期', 'expired');
85
+ }
86
+ await sleep(POLL_INTERVAL_MS);
87
+ }
88
+ throw new IlinkQrLoginError('微信扫码登录超时', 'timeout');
89
+ }
90
+ //# sourceMappingURL=weixin-ilink-login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"weixin-ilink-login.js","sourceRoot":"","sources":["../src/weixin-ilink-login.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhin.js/scaffold-wizard",
3
- "version": "0.1.9",
3
+ "version": "0.2.0",
4
4
  "description": "Shared interactive scaffold wizard for create-zhin-app and @zhin.js/cli",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
@@ -20,6 +20,7 @@
20
20
  "chalk": "^5.6.2",
21
21
  "fs-extra": "^11.3.6",
22
22
  "inquirer": "^14.0.2",
23
+ "qrcode": "^1.5.4",
23
24
  "smol-toml": "^1.7.0",
24
25
  "yaml": "^2.9.0"
25
26
  },
@@ -27,6 +28,7 @@
27
28
  "@types/fs-extra": "^11.0.4",
28
29
  "@types/inquirer": "^9.0.10",
29
30
  "@types/node": "^26.1.0",
31
+ "@types/qrcode": "^1.5.5",
30
32
  "typescript": "^6.0.3"
31
33
  },
32
34
  "engines": {