@round2ai/r2-cli 1.0.13-beta.0 → 1.0.14

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/r2-cli.js CHANGED
@@ -1,2165 +1,49 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __esm = (fn, res) => function __init() {
6
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
7
- };
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
-
13
- // src/components/UserInfoCard.tsx
14
- var UserInfoCard_exports = {};
15
- __export(UserInfoCard_exports, {
16
- UserInfoCard: () => UserInfoCard
17
- });
18
- import { Box, Text } from "ink";
19
- import { jsx, jsxs } from "react/jsx-runtime";
20
- function UserInfoCard({ userInfo, lastLogin, daysSinceLogin }) {
21
- const maskedMobile = userInfo.mobile ? userInfo.mobile.replace(/(\d{3})\d{4}(\d{4})/, "$1****$2") : "-";
22
- return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, borderStyle: "round", borderColor: "gray", paddingX: 1, children: [
23
- /* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: "\u7528\u6237\u4FE1\u606F" }),
24
- /* @__PURE__ */ jsxs(Box, { flexDirection: "row", marginTop: 1, children: [
25
- /* @__PURE__ */ jsx(Box, { width: 10, children: /* @__PURE__ */ jsx(Text, { color: "gray", children: "\u6635\u79F0" }) }),
26
- /* @__PURE__ */ jsx(Text, { color: "yellow", children: userInfo.nickname })
27
- ] }),
28
- /* @__PURE__ */ jsxs(Box, { flexDirection: "row", children: [
29
- /* @__PURE__ */ jsx(Box, { width: 10, children: /* @__PURE__ */ jsx(Text, { color: "gray", children: "\u624B\u673A\u53F7" }) }),
30
- /* @__PURE__ */ jsx(Text, { color: "yellow", children: maskedMobile })
31
- ] }),
32
- lastLogin && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
33
- /* @__PURE__ */ jsxs(Text, { color: "gray", children: [
34
- "\u6700\u540E\u767B\u5F55: ",
35
- lastLogin.toLocaleString()
36
- ] }),
37
- daysSinceLogin !== void 0 && /* @__PURE__ */ jsxs(Text, { color: "gray", children: [
38
- " \u8DDD\u4ECA: ",
39
- daysSinceLogin,
40
- " \u5929"
41
- ] })
42
- ] })
43
- ] });
44
- }
45
- var init_UserInfoCard = __esm({
46
- "src/components/UserInfoCard.tsx"() {
47
- "use strict";
48
- }
49
- });
50
-
51
- // src/utils/render.tsx
52
- var render_exports = {};
53
- __export(render_exports, {
54
- renderComponent: () => renderComponent,
55
- renderOnce: () => renderOnce
56
- });
57
- import React from "react";
58
- import chalk from "chalk";
59
- import { render } from "ink";
60
- import { Writable } from "node:stream";
61
- function renderOnce(component) {
62
- const prevLevel = chalk.level;
63
- if (!process.env.NO_COLOR) {
64
- chalk.level = 3;
65
- }
66
- try {
67
- const chunks = [];
68
- const buffer = new Writable({
69
- write(chunk, _, done) {
70
- chunks.push(Buffer.from(chunk));
71
- done();
72
- }
73
- });
74
- buffer.isTTY = true;
75
- buffer.columns = process.stdout.columns || 80;
76
- buffer.rows = process.stdout.rows || 24;
77
- const instance4 = render(component, {
78
- stdout: buffer,
79
- patchConsole: false
80
- });
81
- instance4.unmount();
82
- const raw = Buffer.concat(chunks).toString("utf8");
83
- const lastRender = raw.split(/\x1B\[2J\x1B\[3J\x1B\[H/).at(-1) || raw;
84
- const cleaned = lastRender.replace(/\x1B\[\?[\d;]+[hl]/g, "").trimEnd() + "\n";
85
- process.stdout.write(cleaned);
86
- } finally {
87
- chalk.level = prevLevel;
88
- }
89
- }
90
- function renderComponent(Component, props) {
91
- renderOnce(React.createElement(Component, props));
92
- }
93
- var init_render = __esm({
94
- "src/utils/render.tsx"() {
95
- "use strict";
96
- }
97
- });
98
-
99
- // src/components/ShopsTable.tsx
100
- var ShopsTable_exports = {};
101
- __export(ShopsTable_exports, {
102
- ShopsTable: () => ShopsTable
103
- });
104
- import { Box as Box2, Text as Text2 } from "ink";
105
- import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
106
- function normalizeShops(shops) {
107
- return shops.map((s) => {
108
- if ("shopName" in s) {
109
- return {
110
- id: s.shopId,
111
- name: s.shopName,
112
- platform: s.platform,
113
- expiresIn: s.expiresIn
114
- };
115
- }
116
- return {
117
- id: s.id,
118
- name: s.name,
119
- platform: s.thirdUserId,
120
- expiresIn: s.expiresIn
121
- };
122
- });
123
- }
124
- function Header({ hasPlatform, fillWidth }) {
125
- return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "row", paddingBottom: 0, children: [
126
- hasPlatform && /* @__PURE__ */ jsx2(Box2, { width: COL_PLATFORM, children: /* @__PURE__ */ jsx2(Text2, { bold: true, color: "white", children: "\u5E73\u53F0" }) }),
127
- /* @__PURE__ */ jsx2(Box2, { width: fillWidth, children: /* @__PURE__ */ jsx2(Text2, { bold: true, color: "white", children: "\u5E97\u94FA\u540D" }) }),
128
- /* @__PURE__ */ jsx2(Box2, { width: COL_ID, children: /* @__PURE__ */ jsx2(Text2, { bold: true, color: "white", children: "ID" }) }),
129
- /* @__PURE__ */ jsx2(Box2, { width: COL_STATUS, children: /* @__PURE__ */ jsx2(Text2, { bold: true, color: "white", children: "\u72B6\u6001" }) })
130
- ] });
131
- }
132
- function Row({ shop, hasPlatform, fillWidth }) {
133
- const platformLabel = PLATFORM_LABELS[shop.platform] ?? shop.platform;
134
- return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "row", children: [
135
- hasPlatform && /* @__PURE__ */ jsx2(Box2, { width: COL_PLATFORM, children: /* @__PURE__ */ jsx2(Text2, { color: "cyan", children: platformLabel }) }),
136
- /* @__PURE__ */ jsx2(Box2, { width: fillWidth, children: /* @__PURE__ */ jsx2(Text2, { bold: true, children: shop.name }) }),
137
- /* @__PURE__ */ jsx2(Box2, { width: COL_ID, children: /* @__PURE__ */ jsx2(Text2, { color: "gray", children: shop.id }) }),
138
- /* @__PURE__ */ jsx2(Box2, { width: COL_STATUS, children: /* @__PURE__ */ jsx2(Text2, { color: "green", children: "\u25CF \u6388\u6743\u4E2D" }) })
139
- ] });
140
- }
141
- function ShopsTable({ shops, platform }) {
142
- const items = normalizeShops(shops);
143
- const hasPlatform = platform === "all";
144
- const title = platform === "all" ? "\u6240\u6709\u6388\u6743\u5E97\u94FA" : `${PLATFORM_LABELS[platform] ?? platform}\u6388\u6743\u5E97\u94FA`;
145
- const termWidth = process.stdout.columns || 80;
146
- const borderPadding = 4;
147
- const fixedCols = COL_ID + COL_STATUS + (hasPlatform ? COL_PLATFORM : 0);
148
- const fillWidth = Math.max(termWidth - borderPadding - fixedCols, 20);
149
- const totalWidth = fixedCols + fillWidth;
150
- return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", marginTop: 1, borderStyle: "round", borderColor: "gray", paddingX: 1, children: [
151
- /* @__PURE__ */ jsxs2(Box2, { flexDirection: "row", children: [
152
- /* @__PURE__ */ jsx2(Text2, { bold: true, color: "cyan", children: title }),
153
- /* @__PURE__ */ jsxs2(Text2, { color: "gray", children: [
154
- " \xB7 ",
155
- items.length,
156
- " \u5BB6"
157
- ] })
158
- ] }),
159
- /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", marginTop: 1, children: [
160
- /* @__PURE__ */ jsx2(Header, { hasPlatform, fillWidth }),
161
- /* @__PURE__ */ jsx2(Text2, { color: "gray", children: "\u2500".repeat(totalWidth) }),
162
- items.map((shop) => /* @__PURE__ */ jsx2(Row, { shop, hasPlatform, fillWidth }, shop.id))
163
- ] })
164
- ] });
165
- }
166
- var PLATFORM_LABELS, COL_PLATFORM, COL_ID, COL_STATUS;
167
- var init_ShopsTable = __esm({
168
- "src/components/ShopsTable.tsx"() {
169
- "use strict";
170
- PLATFORM_LABELS = {
171
- xianyu: "\u95F2\u9C7C",
172
- douyin: "\u6296\u97F3"
173
- };
174
- COL_PLATFORM = 8;
175
- COL_ID = 16;
176
- COL_STATUS = 10;
177
- }
178
- });
179
-
180
- // src/components/StocksTable.tsx
181
- var StocksTable_exports = {};
182
- __export(StocksTable_exports, {
183
- StocksTable: () => StocksTable
184
- });
185
- import { Box as Box3, Text as Text3 } from "ink";
186
- import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
187
- function Header2({ fillWidth }) {
188
- return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "row", paddingBottom: 0, children: [
189
- /* @__PURE__ */ jsx3(Box3, { width: COL_ID2, children: /* @__PURE__ */ jsx3(Text3, { bold: true, color: "white", children: "ID" }) }),
190
- /* @__PURE__ */ jsx3(Box3, { width: COL_USER_ID, children: /* @__PURE__ */ jsx3(Text3, { bold: true, color: "white", children: "\u7528\u6237ID" }) }),
191
- /* @__PURE__ */ jsx3(Box3, { width: COL_STOCK_ID, children: /* @__PURE__ */ jsx3(Text3, { bold: true, color: "white", children: "\u4ED3\u5E93ID" }) }),
192
- /* @__PURE__ */ jsx3(Box3, { width: fillWidth, children: /* @__PURE__ */ jsx3(Text3, { bold: true, color: "white", children: "\u4ED3\u5E93\u540D\u79F0" }) }),
193
- /* @__PURE__ */ jsx3(Box3, { width: COL_TIME, children: /* @__PURE__ */ jsx3(Text3, { bold: true, color: "white", children: "\u521B\u5EFA\u65F6\u95F4" }) })
194
- ] });
195
- }
196
- function Row2({ stock, fillWidth }) {
197
- const created = new Date(stock.gmtCreate).toLocaleString("zh-CN");
198
- return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "row", children: [
199
- /* @__PURE__ */ jsx3(Box3, { width: COL_ID2, children: /* @__PURE__ */ jsx3(Text3, { color: "gray", children: stock.id }) }),
200
- /* @__PURE__ */ jsx3(Box3, { width: COL_USER_ID, children: /* @__PURE__ */ jsx3(Text3, { color: "gray", children: stock.userId }) }),
201
- /* @__PURE__ */ jsx3(Box3, { width: COL_STOCK_ID, children: /* @__PURE__ */ jsx3(Text3, { color: "gray", children: stock.stockId }) }),
202
- /* @__PURE__ */ jsx3(Box3, { width: fillWidth, children: /* @__PURE__ */ jsx3(Text3, { bold: true, children: stock.stockName }) }),
203
- /* @__PURE__ */ jsx3(Box3, { width: COL_TIME, children: /* @__PURE__ */ jsx3(Text3, { color: "gray", children: created }) })
204
- ] });
205
- }
206
- function StocksTable({ stocks }) {
207
- const termWidth = process.stdout.columns || 80;
208
- const borderPadding = 4;
209
- const fixedCols = COL_ID2 + COL_USER_ID + COL_STOCK_ID + COL_TIME;
210
- const fillWidth = Math.max(termWidth - borderPadding - fixedCols, 20);
211
- const totalWidth = fixedCols + fillWidth;
212
- return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", marginTop: 1, borderStyle: "round", borderColor: "gray", paddingX: 1, children: [
213
- /* @__PURE__ */ jsxs3(Box3, { flexDirection: "row", children: [
214
- /* @__PURE__ */ jsx3(Text3, { bold: true, color: "cyan", children: "\u4ED3\u5E93\u5217\u8868" }),
215
- /* @__PURE__ */ jsxs3(Text3, { color: "gray", children: [
216
- " \xB7 ",
217
- stocks.length,
218
- " \u4E2A"
219
- ] })
220
- ] }),
221
- /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", marginTop: 1, children: [
222
- /* @__PURE__ */ jsx3(Header2, { fillWidth }),
223
- /* @__PURE__ */ jsx3(Text3, { color: "gray", children: "\u2500".repeat(totalWidth) }),
224
- stocks.map((stock) => /* @__PURE__ */ jsx3(Row2, { stock, fillWidth }, stock.id))
225
- ] })
226
- ] });
227
- }
228
- var COL_ID2, COL_USER_ID, COL_STOCK_ID, COL_TIME;
229
- var init_StocksTable = __esm({
230
- "src/components/StocksTable.tsx"() {
231
- "use strict";
232
- COL_ID2 = 6;
233
- COL_USER_ID = 10;
234
- COL_STOCK_ID = 10;
235
- COL_TIME = 22;
236
- }
237
- });
238
-
239
- // src/entrypoints/r2-cli.tsx
240
- import { Command as Command18 } from "commander";
241
- import chalk17 from "chalk";
242
-
243
- // src/commands/setup.ts
244
- import "commander";
245
-
246
- // src/commands/auth/login.ts
247
- import { Command } from "commander";
248
-
249
- // src/services/auth/login.ts
250
- import chalk2 from "chalk";
251
-
252
- // src/errors/index.ts
253
- var R2Error = class _R2Error extends Error {
254
- constructor(message, code, details) {
255
- super(message);
256
- this.code = code;
257
- this.details = details;
258
- this.name = "R2Error";
259
- if (Error.captureStackTrace) {
260
- Error.captureStackTrace(this, _R2Error);
261
- }
262
- }
263
- code;
264
- details;
265
- };
266
- var ApiError = class extends R2Error {
267
- constructor(message, status, response) {
268
- super(message, "API_ERROR", response);
269
- this.status = status;
270
- this.response = response;
271
- this.name = "ApiError";
272
- }
273
- status;
274
- response;
275
- };
276
- var StorageError = class extends R2Error {
277
- constructor(message, path4, code) {
278
- super(message, "STORAGE_ERROR", { path: path4, code });
279
- this.path = path4;
280
- this.code = code;
281
- this.name = "StorageError";
282
- }
283
- path;
284
- code;
285
- };
286
- var AuthError = class extends R2Error {
287
- constructor(message) {
288
- super(message, "AUTH_ERROR");
289
- this.name = "AuthError";
290
- }
291
- };
292
- var PollingError = class extends R2Error {
293
- constructor(message, attempts, timeout) {
294
- super(message, "POLLING_ERROR", { attempts, timeout });
295
- this.attempts = attempts;
296
- this.timeout = timeout;
297
- this.name = "PollingError";
298
- }
299
- attempts;
300
- timeout;
301
- };
302
-
303
- // src/utils/polling.ts
304
- async function callWithTimeout(fn, ms, parentSignal) {
305
- const controller = new AbortController();
306
- const onParentAbort = () => controller.abort();
307
- parentSignal?.addEventListener("abort", onParentAbort, { once: true });
308
- const timer = setTimeout(() => controller.abort(), ms);
309
- try {
310
- return await fn();
311
- } catch (error) {
312
- if (controller.signal.aborted && !parentSignal?.aborted) {
313
- throw new PollingError("\u5355\u6B21\u8F6E\u8BE2\u8BF7\u6C42\u8D85\u65F6");
314
- }
315
- throw error;
316
- } finally {
317
- clearTimeout(timer);
318
- parentSignal?.removeEventListener("abort", onParentAbort);
319
- }
320
- }
321
- async function poll(fn, options, signal) {
322
- const { interval, timeout, condition } = options;
323
- const startTime = Date.now();
324
- let attempts = 0;
325
- while (Date.now() - startTime < timeout) {
326
- if (signal?.aborted) {
327
- throw new PollingError("\u8F6E\u8BE2\u88AB\u4E2D\u6B62");
328
- }
329
- attempts++;
330
- const remaining = timeout - (Date.now() - startTime);
331
- const data = await callWithTimeout(fn, remaining, signal);
332
- if (condition(data, attempts)) {
333
- return data;
334
- }
335
- await sleep(interval, signal);
336
- }
337
- throw new PollingError(`\u8F6E\u8BE2\u8D85\u65F6 (\u5DF2\u7B49\u5F85 ${Date.now() - startTime}ms, \u5171 ${attempts} \u6B21)`);
338
- }
339
- function sleep(ms, signal) {
340
- return new Promise((resolve, reject) => {
341
- if (signal?.aborted) {
342
- reject(new PollingError("\u8F6E\u8BE2\u88AB\u4E2D\u6B62"));
343
- return;
344
- }
345
- const onAbort = () => {
346
- clearTimeout(timer);
347
- reject(new PollingError("\u8F6E\u8BE2\u88AB\u4E2D\u6B62"));
348
- };
349
- const timer = setTimeout(() => {
350
- signal?.removeEventListener("abort", onAbort);
351
- resolve();
352
- }, ms);
353
- signal?.addEventListener("abort", onAbort, { once: true });
354
- });
355
- }
356
-
357
- // src/qr-server/render.ts
358
- import fs from "node:fs";
359
- import { fileURLToPath } from "node:url";
360
- import { createRequire } from "node:module";
361
- import path from "node:path";
362
- import { exec } from "node:child_process";
363
-
364
- // src/qr-server/server.ts
365
- import http from "node:http";
366
- var QrServer = class _QrServer {
367
- server = null;
368
- pages = /* @__PURE__ */ new Map();
369
- port = 0;
370
- idleTimer = null;
371
- static IDLE_TIMEOUT_MS = 1e4;
372
- async start() {
373
- if (this.server) return this.port;
374
- return new Promise((resolve, reject) => {
375
- this.server = http.createServer((req, res) => this.handleRequest(req, res));
376
- this.server.listen(0, "127.0.0.1", () => {
377
- const addr = this.server.address();
378
- if (typeof addr === "object" && addr) {
379
- this.port = addr.port;
380
- resolve(this.port);
381
- } else {
382
- reject(new Error("Failed to get server address"));
383
- }
384
- });
385
- this.server.on("error", reject);
386
- });
387
- }
388
- registerPage(route, html, qrBuffer, config) {
389
- const existing = this.pages.get(route);
390
- if (existing) {
391
- existing.qrBuffer = qrBuffer;
392
- existing.status = "waiting";
393
- existing.config = config;
394
- const payload = `data: ${JSON.stringify({ status: "waiting" })}
395
-
396
- `;
397
- for (const client4 of existing.sseClients) client4.write(payload);
398
- } else {
399
- this.pages.set(route, { html, qrBuffer, status: "waiting", sseClients: [], config });
400
- }
401
- this.resetIdleTimer();
402
- }
403
- unregisterPage(route) {
404
- const page = this.pages.get(route);
405
- if (!page) return;
406
- for (const client4 of page.sseClients) client4.end();
407
- page.sseClients.length = 0;
408
- this.pages.delete(route);
409
- if (this.pages.size === 0) this.close();
410
- }
411
- setStatus(route, status) {
412
- const page = this.pages.get(route);
413
- if (!page) return;
414
- page.status = status;
415
- const payload = `data: ${JSON.stringify({ status })}
416
-
417
- `;
418
- for (const client4 of page.sseClients) client4.write(payload);
419
- }
420
- close() {
421
- if (!this.server) return;
422
- if (this.idleTimer) {
423
- clearTimeout(this.idleTimer);
424
- this.idleTimer = null;
425
- }
426
- for (const page of this.pages.values()) {
427
- for (const client4 of page.sseClients) client4.end();
428
- page.sseClients.length = 0;
429
- }
430
- this.pages.clear();
431
- this.server.close();
432
- this.server = null;
433
- this.port = 0;
434
- instance = null;
435
- }
436
- resetIdleTimer() {
437
- if (this.idleTimer) clearTimeout(this.idleTimer);
438
- this.idleTimer = setTimeout(() => {
439
- const hasClients = [...this.pages.values()].some((p) => p.sseClients.length > 0);
440
- if (!hasClients) this.close();
441
- }, _QrServer.IDLE_TIMEOUT_MS);
442
- }
443
- handleRequest(req, res) {
444
- const url = req.url ?? "/";
445
- for (const [route, page] of this.pages) {
446
- if (url === route) {
447
- res.writeHead(302, { Location: route + "/" });
448
- res.end();
449
- return;
450
- }
451
- if (url === route + "/") {
452
- res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
453
- res.end(page.html);
454
- return;
455
- }
456
- if (url === route + "/qr.png") {
457
- res.writeHead(200, { "Content-Type": "image/png", "Content-Length": page.qrBuffer.length });
458
- res.end(page.qrBuffer);
459
- return;
460
- }
461
- if (url === route + "/events") {
462
- res.writeHead(200, {
463
- "Content-Type": "text/event-stream",
464
- "Cache-Control": "no-cache",
465
- Connection: "keep-alive"
466
- });
467
- res.write(`data: ${JSON.stringify({ status: page.status })}
468
-
469
- `);
470
- page.sseClients.push(res);
471
- req.on("close", () => {
472
- const idx = page.sseClients.indexOf(res);
473
- if (idx >= 0) page.sseClients.splice(idx, 1);
474
- });
475
- return;
476
- }
477
- if (url === route + "/config") {
478
- res.writeHead(200, { "Content-Type": "application/json" });
479
- res.end(JSON.stringify(page.config ?? {}));
480
- return;
481
- }
482
- }
483
- res.writeHead(404, { "Content-Type": "text/plain" });
484
- res.end("Not Found");
485
- }
486
- };
487
- var instance = null;
488
- var listenersRegistered = false;
489
- function cleanup() {
490
- if (instance) instance.close();
491
- }
492
- function ensureProcessListeners() {
493
- if (listenersRegistered) return;
494
- listenersRegistered = true;
495
- process.on("exit", cleanup);
496
- process.on("SIGINT", cleanup);
497
- process.on("SIGTERM", cleanup);
498
- setInterval(() => {
499
- if (process.stdin?.destroyed) cleanup();
500
- }, 3e3).unref();
501
- }
502
- function getQrServer() {
503
- if (!instance) {
504
- instance = new QrServer();
505
- ensureProcessListeners();
506
- }
507
- return instance;
508
- }
509
-
510
- // src/qr-server/render.ts
511
- var __dirname = path.dirname(fileURLToPath(import.meta.url));
512
- var LOGIN_ROUTE = "/login";
513
- var XIANYU_ROUTE = "/login-xianyu";
514
- var _require = null;
515
- async function loadHtml(filename) {
516
- return fs.promises.readFile(path.join(__dirname, "pages", filename), "utf-8");
517
- }
518
- async function generateQRBuffer(content) {
519
- if (!_require) _require = createRequire(import.meta.url);
520
- const QRCodeLib = _require("qrcode");
521
- return QRCodeLib.toBuffer(content, { width: 300, margin: 2 });
522
- }
523
- function openUrl(url) {
524
- const cmd = process.platform === "win32" ? `start "" "${url}"` : process.platform === "darwin" ? `open "${url}"` : `xdg-open "${url}"`;
525
- exec(cmd);
526
- }
527
- async function renderQRPage(route, htmlFile, content, config) {
528
- const [html, qrBuffer] = await Promise.all([
529
- loadHtml(htmlFile),
530
- generateQRBuffer(content)
531
- ]);
532
- const server = getQrServer();
533
- const port = await server.start();
534
- server.registerPage(route, html, qrBuffer, config);
535
- const qrUrl = `http://127.0.0.1:${port}${route}/`;
536
- return {
537
- url: content,
538
- qrUrl,
539
- setStatus: (status) => server.setStatus(route, status),
540
- closeServer: () => server.unregisterPage(route)
541
- };
542
- }
543
- function renderLoginQR(content) {
544
- return renderQRPage(LOGIN_ROUTE, "login.html", content);
545
- }
546
- function renderXianyuAuthQR(content, authUrl) {
547
- return renderQRPage(XIANYU_ROUTE, "xianyu-auth.html", content, { authUrl });
548
- }
549
-
550
- // src/services/storage/config-store.ts
551
- import { promises as fs2 } from "node:fs";
552
- import path2 from "node:path";
553
- import os from "node:os";
554
- var CONFIG_FILE_NAME = ".r2-cli";
555
- var ConfigStore = class {
556
- configPath;
557
- config;
558
- configLoaded = false;
559
- dirEnsured = false;
560
- constructor() {
561
- const homeDir = os.homedir();
562
- const configDir = path2.join(homeDir, CONFIG_FILE_NAME);
563
- this.configPath = path2.join(configDir, "config.json");
564
- this.config = { credentials: null };
565
- }
566
- getConfigPath() {
567
- return this.configPath;
568
- }
569
- async loadConfig() {
570
- if (this.configLoaded) return this.config;
571
- try {
572
- const content = await fs2.readFile(this.configPath, "utf-8");
573
- this.config = JSON.parse(content);
574
- this.configLoaded = true;
575
- return this.config;
576
- } catch {
577
- this.config = { credentials: null };
578
- this.configLoaded = true;
579
- return this.config;
580
- }
581
- }
582
- async ensureDir() {
583
- if (this.dirEnsured) return;
584
- const dirPath = path2.dirname(this.configPath);
585
- try {
586
- await fs2.stat(dirPath);
587
- } catch (error) {
588
- if (error.code === "ENOENT") {
589
- await fs2.mkdir(dirPath, { recursive: true });
590
- } else {
591
- throw new StorageError("Failed to create directory", dirPath, error.code);
592
- }
593
- }
594
- this.dirEnsured = true;
595
- }
596
- async saveConfig(config) {
597
- this.config = config;
598
- await this.ensureDir();
599
- const content = JSON.stringify(config, null, 2);
600
- const tmpPath = this.configPath + ".tmp";
601
- try {
602
- await fs2.writeFile(tmpPath, content, "utf-8");
603
- await fs2.rename(tmpPath, this.configPath);
604
- this.configLoaded = true;
605
- } catch (error) {
606
- await fs2.unlink(tmpPath).catch((e) => {
607
- if (typeof process.env.DEBUG !== "undefined") console.error("[config] cleanup tmp failed:", e);
608
- });
609
- throw new StorageError("Failed to save config", this.configPath, error.code);
610
- }
611
- }
612
- };
613
- var instance2 = null;
614
- function getConfigStore() {
615
- if (!instance2) instance2 = new ConfigStore();
616
- return instance2;
617
- }
618
-
619
- // src/services/storage/auth-storage.ts
620
- var TOKEN_EXPIRY_MARGIN_MS = 5 * 60 * 1e3;
621
- var AuthStorage = class {
622
- store = getConfigStore();
623
- isTokenExpired(cred) {
624
- if (!cred.expire) return false;
625
- return Date.now() >= cred.expire - TOKEN_EXPIRY_MARGIN_MS;
626
- }
627
- async saveCredentials(token, userInfo) {
628
- const now = Date.now();
629
- const durationMs = userInfo.expire ? Number.parseInt(userInfo.expire, 10) : 0;
630
- const credentials = {
631
- token,
632
- userInfo,
633
- timestamp: now,
634
- ...durationMs > 0 && { expire: now + durationMs }
635
- };
636
- let config = await this.store.loadConfig();
637
- config.credentials = credentials;
638
- await this.store.saveConfig(config);
639
- }
640
- async getCredentials() {
641
- const config = await this.store.loadConfig();
642
- if (!config.credentials) return null;
643
- if (this.isTokenExpired(config.credentials)) return null;
644
- return config.credentials;
645
- }
646
- async clearCredentials() {
647
- const config = await this.store.loadConfig();
648
- config.credentials = null;
649
- await this.store.saveConfig(config);
650
- }
651
- async getToken() {
652
- const credentials = await this.getCredentials();
653
- return credentials?.token ?? null;
654
- }
655
- async getUserInfo() {
656
- const credentials = await this.getCredentials();
657
- return credentials?.userInfo ?? null;
658
- }
659
- async isLoggedIn() {
660
- const credentials = await this.getCredentials();
661
- return credentials !== null;
662
- }
663
- };
664
- var instance3 = null;
665
- function getAuthStorage() {
666
- if (!instance3) instance3 = new AuthStorage();
667
- return instance3;
668
- }
669
-
670
- // src/services/api/client.ts
671
- var SERVER_BASEURL = "https://api.qiuxietang.com";
672
- var ApiClientService = class {
673
- config;
674
- authStorage = null;
675
- cachedToken = null;
676
- tokenExpiry = 0;
677
- constructor(config = {}) {
678
- this.config = {
679
- baseUrl: config.baseUrl ?? SERVER_BASEURL,
680
- version: config.version ?? "v3",
681
- debug: config.debug ?? false
682
- };
683
- this.authStorage = config.auth === false ? null : getAuthStorage();
684
- }
685
- buildUrl(path4) {
686
- const cleanPath = path4.startsWith("/") ? path4.slice(1) : path4;
687
- return `${this.config.baseUrl}/${this.config.version}/${cleanPath}`;
688
- }
689
- async getAuthToken() {
690
- if (!this.authStorage) return void 0;
691
- if (this.cachedToken && Date.now() < this.tokenExpiry) return this.cachedToken;
692
- const credentials = await this.authStorage.getCredentials();
693
- if (!credentials) {
694
- throw new AuthError("\u8BF7\u5148\u8FD0\u884C r2-cli auth login \u767B\u5F55");
695
- }
696
- this.cachedToken = credentials.token;
697
- this.tokenExpiry = credentials.expire ? credentials.expire - TOKEN_EXPIRY_MARGIN_MS : Date.now() + 30 * 60 * 1e3;
698
- return credentials.token;
699
- }
700
- /**
701
- * 发起请求,返回完整响应信封(含 token 等顶层字段)
702
- */
703
- async requestFull(path4, reqConfig) {
704
- const url = this.buildUrl(path4);
705
- const { method, headers: rawHeaders, body, timeout = 3e4 } = reqConfig;
706
- const token = await this.getAuthToken();
707
- const headers = { ...rawHeaders, ...token ? { token } : {} };
708
- const controller = new AbortController();
709
- const timer = setTimeout(() => controller.abort(), timeout);
710
- const init = {
711
- method,
712
- headers: { "Content-Type": "application/json", ...headers },
713
- signal: controller.signal
714
- };
715
- if (body !== void 0) init.body = JSON.stringify(body);
716
- if (this.config.debug) {
717
- console.error(`[API ${method}]`, url, body);
718
- }
719
- try {
720
- const response = await fetch(url, init);
721
- if (!response.ok) {
722
- if (response.status === 401) {
723
- if (this.authStorage) {
724
- this.cachedToken = null;
725
- await this.authStorage.clearCredentials().catch((e) => {
726
- console.error("[API] \u6E05\u9664\u51ED\u8BC1\u5931\u8D25:", e instanceof Error ? e.message : String(e));
727
- });
728
- }
729
- throw new AuthError("\u767B\u5F55\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u8FD0\u884C r2-cli auth login \u91CD\u65B0\u767B\u5F55");
730
- }
731
- const errorText = await response.text();
732
- throw new ApiError(errorText || `${response.status} ${response.statusText}`, response.status);
733
- }
734
- const result = await response.json();
735
- if (this.config.debug) {
736
- console.error("[API Response]", result);
737
- }
738
- if (!result.success || result.status !== 0) {
739
- throw new ApiError(result.msg || "\u672A\u77E5\u9519\u8BEF", result.status, result);
740
- }
741
- return result;
742
- } catch (error) {
743
- if (error instanceof DOMException && error.name === "AbortError") {
744
- throw new ApiError(`\u8BF7\u6C42\u8D85\u65F6 (${timeout}ms)`, 408);
745
- }
746
- throw error;
747
- } finally {
748
- clearTimeout(timer);
749
- }
750
- }
751
- async request(path4, config) {
752
- const result = await this.requestFull(path4, config);
753
- return result.data;
754
- }
755
- async get(path4, params, headers) {
756
- const fullPath = params && params.size > 0 ? `${path4}?${params.toString()}` : path4;
757
- return this.request(fullPath, { method: "GET", headers });
758
- }
759
- async post(path4, body, headers) {
760
- return this.request(path4, { method: "POST", body, headers });
761
- }
762
- async put(path4, body, headers) {
763
- return this.request(path4, { method: "PUT", body, headers });
764
- }
765
- async delete(path4, headers) {
766
- return this.request(path4, { method: "DELETE", headers });
767
- }
768
- /** 上传文件(multipart/form-data),不设置 Content-Type 让运行时自动处理 boundary */
769
- async upload(path4, formData, headers) {
770
- const url = this.buildUrl(path4);
771
- const token = await this.getAuthToken();
772
- const allHeaders = { ...headers, ...token ? { token } : {} };
773
- const controller = new AbortController();
774
- const timer = setTimeout(() => controller.abort(), 6e4);
775
- const init = {
776
- method: "POST",
777
- headers: allHeaders,
778
- body: formData,
779
- signal: controller.signal
780
- };
781
- if (this.config.debug) {
782
- console.error("[API UPLOAD]", url);
783
- }
784
- try {
785
- const response = await fetch(url, init);
786
- if (!response.ok) {
787
- if (response.status === 401) {
788
- if (this.authStorage) {
789
- this.cachedToken = null;
790
- await this.authStorage.clearCredentials().catch(() => {
791
- });
792
- }
793
- throw new AuthError("\u767B\u5F55\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u8FD0\u884C r2-cli auth login \u91CD\u65B0\u767B\u5F55");
794
- }
795
- const errorText = await response.text();
796
- throw new ApiError(errorText || `${response.status} ${response.statusText}`, response.status);
797
- }
798
- const result = await response.json();
799
- if (this.config.debug) {
800
- console.error("[API Response]", result);
801
- }
802
- if (!result.success || result.status !== 0) {
803
- throw new ApiError(result.msg || "\u672A\u77E5\u9519\u8BEF", result.status, result);
804
- }
805
- return result.data;
806
- } catch (error) {
807
- if (error instanceof DOMException && error.name === "AbortError") {
808
- throw new ApiError("\u4E0A\u4F20\u8D85\u65F6 (60000ms)", 408);
809
- }
810
- throw error;
811
- } finally {
812
- clearTimeout(timer);
813
- }
814
- }
815
- };
816
- var authClient = new ApiClientService();
817
- var noAuthClient = new ApiClientService({ auth: false });
818
-
819
- // src/services/api/modules/qrcode-auth.ts
820
- var client = noAuthClient;
821
- async function generateQRCode() {
822
- return client.post("app/qrcode/generate");
823
- }
824
- async function getQRCodeStatus(qrToken) {
825
- const params = new URLSearchParams();
826
- params.append("qrToken", qrToken);
827
- const fullPath = `app/qrcode/status?${params.toString()}`;
828
- const full = await client.requestFull(fullPath, { method: "GET" });
829
- if (full.token && typeof full.data === "object" && full.data !== null) {
830
- full.data.token = full.token;
831
- }
832
- return full.data;
833
- }
834
-
835
- // src/services/auth/login.ts
836
- async function displayUserInfo(userInfo, lastLogin, daysSinceLogin) {
837
- const { UserInfoCard: UserInfoCard2 } = await Promise.resolve().then(() => (init_UserInfoCard(), UserInfoCard_exports));
838
- const { renderComponent: renderComponent2 } = await Promise.resolve().then(() => (init_render(), render_exports));
839
- const props = lastLogin != null ? { userInfo, lastLogin, daysSinceLogin: daysSinceLogin ?? 0 } : { userInfo };
840
- renderComponent2(UserInfoCard2, props);
841
- }
842
- var LoginService = class {
843
- storage;
844
- constructor(storage) {
845
- this.storage = storage ?? getAuthStorage();
846
- }
847
- async generateQR() {
848
- const qrData = await generateQRCode();
849
- const qrContent = `https://m.puresnake.com/r2/auth/login?qrToken=${qrData.qrContent}&from=wechat`;
850
- const rendered = await renderLoginQR(qrContent);
851
- return { qrData, ...rendered };
852
- }
853
- async waitForLogin(qrToken, expireTimeMs, pollIntervalMs, signal, setStatus, silent) {
854
- const result = await poll(
855
- () => getQRCodeStatus(qrToken),
856
- {
857
- interval: pollIntervalMs,
858
- timeout: expireTimeMs,
859
- condition: (data) => {
860
- switch (data.status) {
861
- case "scanned":
862
- if (!silent) {
863
- console.log(chalk2.cyan(`
864
- \u{1F50D} \u5DF2\u626B\u7801: ${data.userInfo?.nickname || "\u672A\u77E5\u7528\u6237"}`));
865
- console.log(chalk2.yellow("\u8BF7\u5728 APP \u4E0A\u786E\u8BA4\u767B\u5F55"));
866
- }
867
- setStatus?.("scanning");
868
- return false;
869
- case "confirmed":
870
- if (!silent) console.log(chalk2.green("\n\u2705 \u7528\u6237\u5DF2\u786E\u8BA4\u767B\u5F55"));
871
- setStatus?.("success");
872
- return true;
873
- case "expired":
874
- if (!silent) console.log(chalk2.red("\n\u23F0 \u4E8C\u7EF4\u7801\u5DF2\u8FC7\u671F"));
875
- setStatus?.("expired");
876
- return true;
877
- case "canceled":
878
- if (!silent) console.log(chalk2.red("\n\u{1F6AB} \u7528\u6237\u5DF2\u53D6\u6D88\u767B\u5F55"));
879
- setStatus?.("expired");
880
- return true;
881
- default:
882
- return false;
883
- }
884
- }
885
- },
886
- signal ?? void 0
887
- );
888
- if (result.status === "confirmed" && result.token && result.userInfo) {
889
- await this.storage.saveCredentials(result.token, result.userInfo);
890
- return { userInfo: result.userInfo, token: result.token };
891
- }
892
- if (result.status === "expired") throw new AuthError("\u4E8C\u7EF4\u7801\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55");
893
- if (result.status === "canceled") throw new AuthError("\u7528\u6237\u5DF2\u53D6\u6D88\u767B\u5F55");
894
- throw new AuthError("\u767B\u5F55\u5931\u8D25: \u672A\u83B7\u53D6\u5230\u51ED\u8BC1");
895
- }
896
- async login(signal) {
897
- console.log(chalk2.cyan("\n\u{1F510} \u6B63\u5728\u542F\u52A8\u626B\u7801\u767B\u5F55..."));
898
- const { qrData, qrUrl, setStatus, closeServer } = await this.generateQR();
899
- console.log(chalk2.green("\u2705 \u4E8C\u7EF4\u7801\u5DF2\u751F\u6210\n"));
900
- console.log(chalk2.cyan(` \u94FE\u63A5: ${qrUrl}
901
- `));
902
- openUrl(qrUrl);
903
- console.log(chalk2.yellow("\u23F3 \u7B49\u5F85\u626B\u7801...\n"));
904
- const expireTimeMs = Number.parseInt(qrData.expireTime, 10);
905
- const pollIntervalMs = Number.parseInt(qrData.pollInterval, 10);
906
- try {
907
- const result = await this.waitForLogin(qrData.qrToken, expireTimeMs, pollIntervalMs, signal, setStatus);
908
- console.log(chalk2.green("\n\u2705 \u767B\u5F55\u6210\u529F\uFF01\n"));
909
- displayUserInfo(result.userInfo);
910
- return result;
911
- } catch (error) {
912
- console.log(chalk2.red("\n\u274C \u767B\u5F55\u5931\u8D25\n"));
913
- throw error;
914
- } finally {
915
- closeServer();
916
- }
917
- }
918
- async logout() {
919
- console.log(chalk2.cyan("\n\u{1F6AA} \u6B63\u5728\u9000\u51FA\u767B\u5F55..."));
920
- await this.storage.clearCredentials();
921
- console.log(chalk2.green("\u2705 \u5DF2\u9000\u51FA\u767B\u5F55\n"));
922
- }
923
- async status() {
924
- const isLoggedIn = await this.storage.isLoggedIn();
925
- if (!isLoggedIn) {
926
- console.log(chalk2.yellow("\u26A0\uFE0F \u5C1A\u672A\u767B\u5F55\u6216\u51ED\u8BC1\u5DF2\u8FC7\u671F\n"));
927
- return;
928
- }
929
- const credentials = await this.storage.getCredentials();
930
- const userInfo = credentials.userInfo;
931
- const lastLogin = new Date(credentials.timestamp);
932
- const daysSinceLogin = Math.floor((Date.now() - credentials.timestamp) / (1e3 * 60 * 60 * 24));
933
- console.log(chalk2.green("\u2705 \u5DF2\u767B\u5F55\n"));
934
- await displayUserInfo(userInfo, lastLogin, daysSinceLogin);
935
- }
936
- };
937
- var loginInstance = null;
938
- function getLoginService() {
939
- if (!loginInstance) loginInstance = new LoginService();
940
- return loginInstance;
941
- }
942
-
943
- // src/services/auth/xianyu-auth.ts
944
- import chalk3 from "chalk";
945
-
946
- // src/services/api/modules/xianyu-auth.ts
947
- var client2 = authClient;
948
- async function getAuthUrl() {
949
- return client2.get("mms/xianyu/auth/url");
950
- }
951
- async function getAuthStatus(state) {
952
- const params = new URLSearchParams({ state });
953
- return client2.get("mms/xianyu/auth/status", params);
954
- }
955
-
956
- // src/services/auth/xianyu-auth.ts
957
- async function generateAuthQR() {
958
- const authData = await getAuthUrl();
959
- const rendered = await renderXianyuAuthQR(authData.url, authData.url);
960
- return { authData, ...rendered };
961
- }
962
- async function waitForAuth(state, expireMs, intervalMs, signal, setStatus) {
963
- return poll(
964
- () => getAuthStatus(state),
965
- {
966
- interval: intervalMs,
967
- timeout: expireMs,
968
- condition: (data) => {
969
- if (data.status === "success") {
970
- console.log(chalk3.green(`
971
- \u2705 \u6388\u6743\u6210\u529F\uFF01\u5E97\u94FA: ${data.shopName} (${data.shopId})`));
972
- setStatus?.("success");
973
- return true;
974
- }
975
- if (data.status === "expired") {
976
- console.log(chalk3.red("\n\u23F0 \u6388\u6743\u94FE\u63A5\u5DF2\u8FC7\u671F"));
977
- setStatus?.("expired");
978
- return true;
979
- }
980
- return false;
981
- }
982
- },
983
- signal
984
- );
985
- }
986
- async function authorize(signal) {
987
- console.log(chalk3.cyan("\n\u{1F517} \u6B63\u5728\u83B7\u53D6\u95F2\u9C7C\u6388\u6743\u5730\u5740..."));
988
- const { authData, qrUrl, setStatus, closeServer } = await generateAuthQR();
989
- console.log(chalk3.green("\u2705 \u6388\u6743\u4E8C\u7EF4\u7801\u5DF2\u751F\u6210\n"));
990
- console.log(chalk3.cyan(` \u94FE\u63A5: ${qrUrl}`));
991
- console.log(chalk3.gray(` \u6216\u590D\u5236\u94FE\u63A5\u6253\u5F00: ${authData.url}`));
992
- openUrl(qrUrl);
993
- console.log(chalk3.yellow("\n\u23F3 \u7B49\u5F85\u6388\u6743...\n"));
994
- const expireMs = authData.expireTime ? Number.parseInt(authData.expireTime, 10) : 3e5;
995
- const intervalMs = authData.pollInterval ? Number.parseInt(authData.pollInterval, 10) : 1e3;
996
- try {
997
- const result = await waitForAuth(authData.state, expireMs, intervalMs, signal, setStatus);
998
- if (result.status === "success") return result;
999
- throw new AuthError("\u95F2\u9C7C\u6388\u6743\u5931\u8D25: " + (result.status === "expired" ? "\u94FE\u63A5\u5DF2\u8FC7\u671F" : "\u672A\u77E5\u72B6\u6001"));
1000
- } finally {
1001
- closeServer();
1002
- }
1003
- }
1004
-
1005
- // src/commands/shared.ts
1006
- import chalk4 from "chalk";
1007
- function handleCommandError(error) {
1008
- if (error instanceof AuthError) {
1009
- console.error(chalk4.red(`
1010
- \u25B2 ${error.message}`));
1011
- console.error(chalk4.gray(`\u2192 \u8BF7\u5148\u8FD0\u884C: r2-cli auth login
1012
- `));
1013
- } else if (error instanceof ApiError) {
1014
- console.error(chalk4.red(`\u25B2 \u64CD\u4F5C\u5931\u8D25: ${error.message}`));
1015
- if (error.status) {
1016
- console.error(chalk4.gray(` \u72B6\u6001\u7801: ${error.status}`));
1017
- }
1018
- } else if (error instanceof StorageError) {
1019
- console.error(chalk4.red(`\u25B2 \u914D\u7F6E\u6587\u4EF6\u5F02\u5E38: ${error.message}`));
1020
- if (error.path) console.error(chalk4.gray(` \u8DEF\u5F84: ${error.path}`));
1021
- console.error(chalk4.gray(`\u2192 \u8BF7\u5C1D\u8BD5\u91CD\u65B0\u767B\u5F55: r2-cli auth login
1022
- `));
1023
- } else {
1024
- const msg = error instanceof Error ? error.message : String(error);
1025
- console.error(chalk4.red(`\u25B2 ${msg}`));
1026
- }
1027
- process.exit(1);
1028
- }
1029
- function agentError(msg) {
1030
- console.log(JSON.stringify({ success: false, error: msg }));
1031
- process.exit(1);
1032
- }
1033
- function jsonAction(fn) {
1034
- return async (options) => {
1035
- try {
1036
- await fn(options);
1037
- } catch (error) {
1038
- if (options.json) {
1039
- const msg = error instanceof Error ? error.message : String(error);
1040
- const status = error instanceof ApiError ? error.status : void 0;
1041
- console.log(JSON.stringify({ success: false, error: msg, ...status != null && { status } }));
1042
- process.exit(1);
1043
- }
1044
- handleCommandError(error);
1045
- }
1046
- };
1047
- }
1048
- function agentAction(fn) {
1049
- return async (...args) => {
1050
- try {
1051
- await fn(...args);
1052
- } catch (error) {
1053
- const msg = error instanceof Error ? error.message : String(error);
1054
- agentError(msg);
1055
- }
1056
- };
1057
- }
1058
- var SENSITIVE_KEYS = /* @__PURE__ */ new Set(["accessToken", "refreshExpireIn"]);
1059
- function sanitizeShops(shops) {
1060
- return shops.map((shop) => {
1061
- const safe = {};
1062
- for (const [key, value] of Object.entries(shop)) {
1063
- if (!SENSITIVE_KEYS.has(key)) safe[key] = value;
1064
- }
1065
- return safe;
1066
- });
1067
- }
1068
-
1069
- // src/commands/auth/qr-flow.ts
1070
- async function runQRJsonFlow(config) {
1071
- const { qrInfo, qrUrl, setStatus, closeServer, waitArgs } = await config.generate();
1072
- console.log(JSON.stringify(qrInfo, null, 2));
1073
- openUrl(qrUrl);
1074
- try {
1075
- const result = await config.waitResult(waitArgs, setStatus);
1076
- console.log(JSON.stringify(config.formatSuccess(result)));
1077
- } catch (error) {
1078
- const msg = error instanceof Error ? error.message : String(error);
1079
- console.log(JSON.stringify({ success: false, error: msg }));
1080
- process.exit(1);
1081
- } finally {
1082
- setTimeout(closeServer, 1e3);
1083
- }
1084
- }
1085
-
1086
- // src/commands/auth/login.ts
1087
- function createLoginCommand() {
1088
- const command = new Command("login");
1089
- command.description("\u626B\u7801\u767B\u5F55 Round2AI \u8D26\u6237").option("--json", "\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09");
1090
- const pollCmd = new Command("poll").description("\u8F6E\u8BE2\u767B\u5F55\u72B6\u6001\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09").requiredOption("--token <qrToken>", "\u4E8C\u7EF4\u7801 token").option("--expire <ms>", "\u8FC7\u671F\u65F6\u95F4\uFF08\u6BEB\u79D2\uFF09", "300000").option("--interval <ms>", "\u8F6E\u8BE2\u95F4\u9694\uFF08\u6BEB\u79D2\uFF09", "1000").action(agentAction(async (options) => {
1091
- const service = getLoginService();
1092
- const result = await service.waitForLogin(
1093
- options.token,
1094
- Number.parseInt(options.expire, 10),
1095
- Number.parseInt(options.interval, 10)
1096
- );
1097
- console.log(JSON.stringify({ success: true, ...result }));
1098
- }));
1099
- command.addCommand(pollCmd);
1100
- command.action(async (options) => {
1101
- try {
1102
- if (options.json) {
1103
- await runQRJsonFlow({
1104
- generate: async () => {
1105
- const service = getLoginService();
1106
- const { qrData, qrUrl, setStatus, closeServer } = await service.generateQR();
1107
- const expireMs = Number.parseInt(qrData.expireTime, 10);
1108
- const intervalMs = Number.parseInt(qrData.pollInterval, 10);
1109
- return {
1110
- qrInfo: {
1111
- qrToken: qrData.qrToken,
1112
- expireTimeMs: expireMs,
1113
- pollIntervalMs: intervalMs,
1114
- url: `https://m.puresnake.com/r2/auth/login?qrToken=${qrData.qrContent}&from=wechat`,
1115
- qrUrl
1116
- },
1117
- qrUrl,
1118
- setStatus,
1119
- closeServer,
1120
- waitArgs: { qrToken: qrData.qrToken, expireMs, intervalMs }
1121
- };
1122
- },
1123
- waitResult: ({ qrToken, expireMs, intervalMs }, setStatus) => getLoginService().waitForLogin(qrToken, expireMs, intervalMs, void 0, setStatus, true),
1124
- formatSuccess: (result) => ({ success: true, userInfo: result.userInfo })
1125
- });
1126
- } else {
1127
- await getLoginService().login();
1128
- }
1129
- } catch (error) {
1130
- if (options.json) {
1131
- const msg = error instanceof Error ? error.message : String(error);
1132
- console.log(JSON.stringify({ success: false, error: msg }));
1133
- process.exit(1);
1134
- }
1135
- handleCommandError(error);
1136
- }
1137
- });
1138
- return command;
1139
- }
1140
-
1141
- // src/commands/auth/logout.ts
1142
- import { Command as Command2 } from "commander";
1143
- function createLogoutCommand() {
1144
- const command = new Command2("logout");
1145
- command.description("\u9000\u51FA\u767B\u5F55");
1146
- command.action(async () => {
1147
- try {
1148
- const loginService = getLoginService();
1149
- await loginService.logout();
1150
- } catch (error) {
1151
- handleCommandError(error);
1152
- }
1153
- });
1154
- return command;
1155
- }
1156
-
1157
- // src/commands/auth/status.ts
1158
- import { Command as Command3 } from "commander";
1159
- function createStatusCommand() {
1160
- const command = new Command3("status");
1161
- command.description("\u67E5\u770B\u767B\u5F55\u72B6\u6001");
1162
- command.action(async () => {
1163
- try {
1164
- const loginService = getLoginService();
1165
- await loginService.status();
1166
- } catch (error) {
1167
- handleCommandError(error);
1168
- }
1169
- });
1170
- return command;
1171
- }
1172
-
1173
- // src/commands/auth/xianyu.ts
1174
- import { Command as Command4 } from "commander";
1175
- function createXianyuAuthCommand() {
1176
- const command = new Command4("xianyu");
1177
- command.description("\u95F2\u9C7C\u5E97\u94FA\u6388\u6743").option("--json", "\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09");
1178
- const pollCmd = new Command4("poll").description("\u8F6E\u8BE2\u95F2\u9C7C\u6388\u6743\u72B6\u6001\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09").requiredOption("--state <state>", "\u6388\u6743\u8F6E\u8BE2 token").option("--expire <ms>", "\u8FC7\u671F\u65F6\u95F4\uFF08\u6BEB\u79D2\uFF09", "300000").option("--interval <ms>", "\u8F6E\u8BE2\u95F4\u9694\uFF08\u6BEB\u79D2\uFF09", "1000").action(agentAction(async (options) => {
1179
- const result = await waitForAuth(
1180
- options.state,
1181
- Number.parseInt(options.expire, 10),
1182
- Number.parseInt(options.interval, 10)
1183
- );
1184
- if (result.status === "success") {
1185
- console.log(JSON.stringify({ success: true, shopId: result.shopId, shopName: result.shopName }));
1186
- } else {
1187
- agentError(`\u6388\u6743\u72B6\u6001: ${result.status}`);
1188
- }
1189
- }));
1190
- command.addCommand(pollCmd);
1191
- command.action(async (options) => {
1192
- try {
1193
- if (options.json) {
1194
- await runQRJsonFlow({
1195
- generate: async () => {
1196
- const { authData, qrUrl, setStatus, closeServer } = await generateAuthQR();
1197
- const expireMs = authData.expireTime ? Number.parseInt(authData.expireTime, 10) : 3e5;
1198
- const intervalMs = authData.pollInterval ? Number.parseInt(authData.pollInterval, 10) : 1e3;
1199
- return {
1200
- qrInfo: {
1201
- state: authData.state,
1202
- expireTimeMs: expireMs,
1203
- pollIntervalMs: intervalMs,
1204
- qrUrl
1205
- },
1206
- qrUrl,
1207
- setStatus,
1208
- closeServer,
1209
- waitArgs: { state: authData.state, expireMs, intervalMs }
1210
- };
1211
- },
1212
- waitResult: async ({ state, expireMs, intervalMs }, setStatus) => {
1213
- const result = await waitForAuth(state, expireMs, intervalMs, void 0, setStatus);
1214
- if (result.status !== "success") throw new Error(`\u6388\u6743\u72B6\u6001: ${result.status}`);
1215
- return result;
1216
- },
1217
- formatSuccess: (result) => ({ success: true, shopId: result.shopId, shopName: result.shopName })
1218
- });
1219
- } else {
1220
- await authorize();
1221
- }
1222
- } catch (error) {
1223
- if (options.json) {
1224
- const msg = error instanceof Error ? error.message : String(error);
1225
- console.log(JSON.stringify({ success: false, error: msg }));
1226
- process.exit(1);
1227
- }
1228
- handleCommandError(error);
1229
- }
1230
- });
1231
- return command;
1232
- }
1233
-
1234
- // src/commands/goods/index.ts
1235
- import { Command as Command14 } from "commander";
1236
-
1237
- // src/commands/goods/up/index.ts
1238
- import { Command as Command5 } from "commander";
1239
- import chalk5 from "chalk";
1240
- import { select, input, confirm } from "@inquirer/prompts";
1241
-
1242
- // src/services/api/modules/goods.ts
1243
- import { readFileSync } from "node:fs";
1244
- import { basename } from "node:path";
1245
-
1246
- // src/utils/params.ts
1247
- function toParams(obj) {
1248
- const params = new URLSearchParams();
1249
- for (const [key, value] of Object.entries(obj)) {
1250
- if (value !== void 0 && value !== null && value !== "") {
1251
- params.append(key, String(value));
1252
- }
1253
- }
1254
- return params;
1255
- }
1256
-
1257
- // src/services/api/modules/goods.ts
1258
- var client3 = authClient;
1259
- async function listingUpXianyu(params) {
1260
- return client3.post("mms/goods/listing/up/xianyu", params);
1261
- }
1262
- async function getListingInfo(params) {
1263
- return client3.get("mms/goods/listing/get", toParams({ ...params }));
1264
- }
1265
- async function listingDownXianyu(params) {
1266
- return client3.post("mms/goods/listing/down/xianyu", params);
1267
- }
1268
- async function listingUpdatePrice(params) {
1269
- return client3.post("mms/goods/listing/update/xyPrice", params);
1270
- }
1271
- async function updateGoodsInfo(params) {
1272
- return client3.post("mms/goods/listing/update/goodsInfo", params);
1273
- }
1274
- async function getListingList(params) {
1275
- return client3.get("mms/goods/listing/list", params ? toParams({ ...params }) : void 0);
1276
- }
1277
- async function getUserShopList() {
1278
- const data = await client3.get("mms/user/shop/list");
1279
- return data ?? [];
1280
- }
1281
- async function getUserStockList() {
1282
- const data = await client3.get("mms/user/stock/list");
1283
- return data ?? [];
1284
- }
1285
- async function getSelectGoodsList(params) {
1286
- const queryParams = params ? toParams({ ...params }) : void 0;
1287
- return client3.get("mms/seller/goods/select/list", queryParams);
1288
- }
1289
- async function uploadXyImages(shopId, filePaths) {
1290
- const results = [];
1291
- for (const filePath of filePaths) {
1292
- const fileBuffer = readFileSync(filePath);
1293
- const fileName = basename(filePath);
1294
- const formData = new FormData();
1295
- formData.append("file", new Blob([fileBuffer]), fileName);
1296
- const result = await client3.upload(
1297
- `platform/xy/media/upload?shopId=${encodeURIComponent(shopId)}`,
1298
- formData
1299
- );
1300
- results.push(result);
1301
- }
1302
- return results;
1303
- }
1304
- async function listingHangUpXianyu(params) {
1305
- return client3.post("mms/goods/listing/hang/up/xianyu", params);
1306
- }
1307
- async function getXyCategories(spBizType = 16) {
1308
- const data = await client3.get("platform/xy/cat", toParams({ spBizType }));
1309
- return data ?? [];
1310
- }
1311
- async function getXyProps(channelCatId) {
1312
- const data = await client3.get("platform/xy/props", toParams({ channelCatId }));
1313
- return data ?? [];
1314
- }
1315
- async function getXyPropValues(channelCatId, propId, key) {
1316
- const data = await client3.get("platform/xy/props/value", toParams({ channelCatId, propId, key }));
1317
- return data ?? [];
1318
- }
1319
-
1320
- // src/commands/goods/up/index.ts
1321
- var LISTING_POLL_INTERVAL = 2e3;
1322
- var LISTING_POLL_TIMEOUT = 1e4;
1323
- function isProcessing(info) {
1324
- const status = info.status?.toLowerCase() ?? "";
1325
- return status === "" || status === "init" || status === "pending" || status === "processing";
1326
- }
1327
- async function pollListingStatus(stockGoodsId, shopId, platform, json) {
1328
- if (!json) {
1329
- process.stdout.write(chalk5.cyan("\u23F3 \u6B63\u5728\u67E5\u8BE2\u4E0A\u67B6\u8FDB\u5EA6..."));
1330
- }
1331
- const result = await poll(
1332
- () => getListingInfo({ stockGoodsId, shopId, platform }),
1333
- {
1334
- interval: LISTING_POLL_INTERVAL,
1335
- timeout: LISTING_POLL_TIMEOUT,
1336
- condition: (data) => !isProcessing(data)
1337
- }
1338
- );
1339
- if (!json) {
1340
- process.stdout.write("\r" + " ".repeat(30) + "\r");
1341
- }
1342
- return result;
1343
- }
1344
- function createUpCommand() {
1345
- const command = new Command5("up");
1346
- command.description("\u4E0A\u67B6\u5546\u54C1\u5230\u95F2\u9C7C");
1347
- command.option("--stock-goods-id <id>", "\u5E93\u5B58\u5546\u54C1ID\uFF08\u4ECE goods list \u83B7\u53D6\uFF09").option("--shop-id <id>", "\u5E97\u94FAID\uFF08\u4ECE goods shops \u83B7\u53D6\uFF09").option("--price <amount>", "\u4E0A\u67B6\u4EF7\u683C").option("-p, --platform <platform>", "\u5E73\u53F0", "xianyu").option("--json", "\u8F93\u51FA JSON\uFF08Agent \u7528\uFF09").action(jsonAction(async (options) => {
1348
- if (options.json && !(options.stockGoodsId && options.shopId && options.price)) {
1349
- console.log(JSON.stringify({ success: false, error: "Agent \u6A21\u5F0F\u9700\u8981 --stock-goods-id, --shop-id, --price" }));
1350
- process.exit(1);
1351
- }
1352
- if (options.stockGoodsId && options.shopId && options.price) {
1353
- const stockGoodsId2 = Number(options.stockGoodsId);
1354
- const shopId = options.shopId;
1355
- const price = Number(options.price);
1356
- const platform = options.platform;
1357
- const result = await listingUpXianyu({ stockGoodsId: stockGoodsId2, shopId, price, platform });
1358
- const listingInfo2 = await pollListingStatus(stockGoodsId2, shopId, platform, options.json);
1359
- if (options.json) {
1360
- console.log(JSON.stringify({ success: true, data: { submit: result, listing: listingInfo2 } }, null, 2));
1361
- } else {
1362
- const statusOk2 = listingInfo2.status?.toLowerCase() !== "failed";
1363
- console.log(statusOk2 ? chalk5.green("\u2713 \u4E0A\u67B6\u6210\u529F") : chalk5.red("\u2717 \u4E0A\u67B6\u5931\u8D25"));
1364
- console.log(JSON.stringify(listingInfo2, null, 2));
1365
- }
1366
- return;
1367
- }
1368
- const shops = await getUserShopList();
1369
- if (shops.length === 0) {
1370
- console.log(chalk5.yellow("\u6CA1\u6709\u5DF2\u6388\u6743\u5E97\u94FA\uFF0C\u8BF7\u5148\u8FD0\u884C r2-cli auth xianyu \u6388\u6743"));
1371
- return;
1372
- }
1373
- const selectedShop = await select({
1374
- message: "\u9009\u62E9\u5E97\u94FA",
1375
- choices: shops.map((s) => ({ name: `${s.shopName} (${s.platform})`, value: s.shopId }))
1376
- });
1377
- const stocks = await getUserStockList();
1378
- if (stocks.length === 0) {
1379
- console.log(chalk5.yellow("\u6CA1\u6709\u53EF\u7528\u7684\u4ED3\u5E93"));
1380
- return;
1381
- }
1382
- const selectedStock = await select({
1383
- message: "\u9009\u62E9\u4ED3\u5E93",
1384
- choices: stocks.map((s) => ({ name: s.stockName, value: s.stockId }))
1385
- });
1386
- const goodsList = await getSelectGoodsList({ stockId: selectedStock, size: 100 });
1387
- if (!goodsList.items?.length) {
1388
- console.log(chalk5.yellow("\u8BE5\u4ED3\u5E93\u6CA1\u6709\u53EF\u9009\u7684\u5546\u54C1"));
1389
- return;
1390
- }
1391
- const selectedGoods = await select({
1392
- message: "\u9009\u62E9\u5546\u54C1",
1393
- choices: goodsList.items.map((g) => ({
1394
- name: `${g.goodsName} ${g.size ? `| ${g.size}` : ""} | \xA5${g.salePrice}`,
1395
- value: g.stockGoodsId
1396
- }))
1397
- });
1398
- const priceInput = await input({
1399
- message: "\u8F93\u5165\u4E0A\u67B6\u4EF7\u683C",
1400
- default: goodsList.items.find((g) => g.stockGoodsId === selectedGoods)?.salePrice?.toString() ?? "",
1401
- validate: (v) => {
1402
- const n = Number(v);
1403
- return n > 0 ? true : "\u4EF7\u683C\u5FC5\u987B\u4E3A\u6B63\u6570";
1404
- }
1405
- });
1406
- const confirmed = await confirm({
1407
- message: `\u786E\u8BA4\u4E0A\u67B6\uFF1F\u4EF7\u683C \xA5${priceInput}`,
1408
- default: true
1409
- });
1410
- if (!confirmed) {
1411
- console.log(chalk5.gray("\u5DF2\u53D6\u6D88"));
1412
- return;
1413
- }
1414
- const stockGoodsId = Number(selectedGoods);
1415
- await listingUpXianyu({
1416
- stockGoodsId,
1417
- shopId: selectedShop,
1418
- price: Number(priceInput),
1419
- platform: "xianyu"
1420
- });
1421
- console.log(chalk5.green("\u2713 \u4E0A\u67B6\u5DF2\u63D0\u4EA4\uFF0C\u6B63\u5728\u67E5\u8BE2\u8FDB\u5EA6..."));
1422
- const listingInfo = await pollListingStatus(stockGoodsId, selectedShop, "xianyu");
1423
- const statusOk = listingInfo.status?.toLowerCase() !== "failed";
1424
- console.log(statusOk ? chalk5.green("\u2713 \u4E0A\u67B6\u6210\u529F") : chalk5.red("\u2717 \u4E0A\u67B6\u5931\u8D25"));
1425
- console.log(JSON.stringify(listingInfo, null, 2));
1426
- }));
1427
- return command;
1428
- }
1429
-
1430
- // src/commands/goods/shops.ts
1431
- import { Command as Command6 } from "commander";
1432
- import chalk6 from "chalk";
1433
- function createShopsCommand() {
1434
- const command = new Command6("shops");
1435
- command.description("\u67E5\u770B\u6240\u6709\u5DF2\u6388\u6743\u5E97\u94FA\uFF08\u8DE8\u5E73\u53F0\uFF09");
1436
- command.option("--json", "\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09");
1437
- command.action(jsonAction(async (options) => {
1438
- const shops = await getUserShopList();
1439
- if (options.json) {
1440
- console.log(JSON.stringify(sanitizeShops(shops), null, 2));
1441
- return;
1442
- }
1443
- if (!shops.length) {
1444
- console.log(chalk6.yellow("\u672A\u627E\u5230\u5DF2\u6388\u6743\u7684\u5E97\u94FA"));
1445
- console.log(chalk6.gray(" \u63D0\u793A: \u8BF7\u5148\u5728\u7B2C\u4E8C\u56DE\u5408 APP \u4E2D\u6388\u6743\u5E97\u94FA"));
1446
- return;
1447
- }
1448
- const { ShopsTable: ShopsTable2 } = await Promise.resolve().then(() => (init_ShopsTable(), ShopsTable_exports));
1449
- const { renderComponent: renderComponent2 } = await Promise.resolve().then(() => (init_render(), render_exports));
1450
- renderComponent2(ShopsTable2, { shops, platform: "all" });
1451
- }));
1452
- return command;
1453
- }
1454
-
1455
- // src/commands/goods/stocks.ts
1456
- import { Command as Command7 } from "commander";
1457
- import chalk7 from "chalk";
1458
- function createStocksCommand() {
1459
- const command = new Command7("stocks");
1460
- command.description("\u67E5\u770B\u6240\u6709\u4ED3\u5E93");
1461
- command.option("--json", "\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09");
1462
- command.action(jsonAction(async (options) => {
1463
- const stocks = await getUserStockList();
1464
- if (options.json) {
1465
- console.log(JSON.stringify(stocks, null, 2));
1466
- return;
1467
- }
1468
- if (!stocks.length) {
1469
- console.log(chalk7.yellow("\u672A\u627E\u5230\u4ED3\u5E93\u4FE1\u606F"));
1470
- return;
1471
- }
1472
- const { StocksTable: StocksTable2 } = await Promise.resolve().then(() => (init_StocksTable(), StocksTable_exports));
1473
- const { renderComponent: renderComponent2 } = await Promise.resolve().then(() => (init_render(), render_exports));
1474
- renderComponent2(StocksTable2, { stocks });
1475
- }));
1476
- return command;
1477
- }
1478
-
1479
- // src/commands/goods/list.ts
1480
- import { Command as Command8 } from "commander";
1481
- import chalk8 from "chalk";
1482
- function createListCommand() {
1483
- const command = new Command8("list");
1484
- command.description("\u67E5\u770B\u4ED3\u5E93\u4E2D\u7684\u9009\u54C1\u5546\u54C1");
1485
- command.option("--stock-id <id>", "\u4ED3\u5E93 ID\uFF08\u4ECE goods stocks \u83B7\u53D6\uFF09").option("--stock-goods-id <id>", "\u5E93\u5B58\u5546\u54C1 ID").option("--page <n>", "\u9875\u7801", "1").option("--size <n>", "\u6BCF\u9875\u6570\u91CF\uFF08\u6700\u5927 50\uFF09", "20").option("--json", "\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09");
1486
- command.action(
1487
- jsonAction(async (options) => {
1488
- const result = await getSelectGoodsList({
1489
- stockId: options.stockId || void 0,
1490
- stockGoodsId: options.stockGoodsId || void 0,
1491
- page: Number(options.page) || 1,
1492
- size: Math.min(Number(options.size) || 20, 50)
1493
- });
1494
- const data = result ?? { items: [], total: 0 };
1495
- if (options.json) {
1496
- if (!data.items?.length) {
1497
- console.log(JSON.stringify({ ...data, hint: "\u9009\u54C1\u5546\u54C1\u4E3A\u7A7A\uFF0C\u8BF7\u5148\u5728\u540E\u53F0\u751F\u6210\u9009\u54C1\u8868\u6570\u636E\u540E\u518D\u8BD5" }, null, 2));
1498
- } else {
1499
- console.log(JSON.stringify(data, null, 2));
1500
- }
1501
- return;
1502
- }
1503
- if (!data.items?.length) {
1504
- console.log(chalk8.yellow("\u6682\u65E0\u9009\u54C1\u5546\u54C1\uFF0C\u8BF7\u5148\u7ED1\u5B9A\u4ED3\u5E93\u6216\u5728\u540E\u53F0\u751F\u6210\u9009\u54C1\u8868\u6570\u636E"));
1505
- return;
1506
- }
1507
- console.log(chalk8.cyan(`
1508
- \u9009\u54C1\u5546\u54C1\uFF08\u5171 ${data.total} \u4EF6\uFF0C\u7B2C ${data.page} \u9875\uFF09
1509
- `));
1510
- for (const item of data.items) {
1511
- console.log(
1512
- ` ${chalk8.bold(item.goodsName)} ${item.size ? chalk8.gray(`| ${item.size}`) : ""}`
1513
- );
1514
- console.log(
1515
- ` \u54C1\u724C: ${item.brand} \u5EFA\u8BAE\u552E\u4EF7: \xA5${item.salePrice} stockGoodsId: ${chalk8.green(item.stockGoodsId)}`
1516
- );
1517
- console.log(chalk8.gray(` \u5206\u7C7B: ${item.cate1Name} > ${item.cate2Name} > ${item.cate3Name}`));
1518
- console.log();
1519
- }
1520
- })
1521
- );
1522
- return command;
1523
- }
1524
-
1525
- // src/commands/goods/listing.ts
1526
- import { Command as Command9 } from "commander";
1527
- import chalk9 from "chalk";
1528
- init_render();
1529
-
1530
- // src/components/ListingTable.tsx
1531
- import { Box as Box4, Text as Text4 } from "ink";
1532
- import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
1533
- var STATUS_MAP = {
1534
- init: { label: "\u5F85\u4E0A\u67B6", color: "yellow" },
1535
- up: { label: "\u5DF2\u4E0A\u67B6", color: "green" },
1536
- down: { label: "\u5DF2\u4E0B\u67B6", color: "gray" },
1537
- fail: { label: "\u5931\u8D25", color: "red" },
1538
- sold: { label: "\u5DF2\u552E\u51FA", color: "blue" }
1539
- };
1540
- var COL_ID3 = 4;
1541
- var COL_STATUS2 = 8;
1542
- var COL_BRAND = 12;
1543
- var COL_PRICE = 10;
1544
- var COL_SPEC = 6;
1545
- var COL_STOCK = 8;
1546
- function truncate(str, maxLen) {
1547
- return str.length > maxLen ? str.slice(0, maxLen - 1) + "\u2026" : str;
1548
- }
1549
- function formatTime(ts) {
1550
- if (!ts) return "-";
1551
- const d = new Date(ts);
1552
- const pad = (n) => String(n).padStart(2, "0");
1553
- return `${pad(d.getMonth() + 1)}/${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`;
1554
- }
1555
- function Header3({ fillWidth }) {
1556
- return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "row", children: [
1557
- /* @__PURE__ */ jsx4(Box4, { width: COL_ID3, children: /* @__PURE__ */ jsx4(Text4, { bold: true, color: "white", children: "ID" }) }),
1558
- /* @__PURE__ */ jsx4(Box4, { width: COL_STATUS2, children: /* @__PURE__ */ jsx4(Text4, { bold: true, color: "white", children: "\u72B6\u6001" }) }),
1559
- /* @__PURE__ */ jsx4(Box4, { width: COL_BRAND, children: /* @__PURE__ */ jsx4(Text4, { bold: true, color: "white", children: "\u54C1\u724C" }) }),
1560
- /* @__PURE__ */ jsx4(Box4, { width: fillWidth, children: /* @__PURE__ */ jsx4(Text4, { bold: true, color: "white", children: "\u5546\u54C1\u540D\u79F0" }) }),
1561
- /* @__PURE__ */ jsx4(Box4, { width: COL_PRICE, children: /* @__PURE__ */ jsx4(Text4, { bold: true, color: "white", children: "\u4EF7\u683C" }) }),
1562
- /* @__PURE__ */ jsx4(Box4, { width: COL_SPEC, children: /* @__PURE__ */ jsx4(Text4, { bold: true, color: "white", children: "\u89C4\u683C" }) }),
1563
- /* @__PURE__ */ jsx4(Box4, { width: COL_STOCK, children: /* @__PURE__ */ jsx4(Text4, { bold: true, color: "white", children: "\u5E93\u5B58ID" }) })
1564
- ] });
1565
- }
1566
- function DetailRow({ item }) {
1567
- return /* @__PURE__ */ jsx4(Box4, { flexDirection: "column", children: /* @__PURE__ */ jsx4(Text4, { color: "gray", children: ` shopId: ${item.shopId} thirdItemNo: ${item.thirdItemNo || "-"} outItemNo: ${item.outItemNo || "-"} \u8D27\u53F7: ${item.goodsNo || "-"} ${item.type || "-"} ${item.platform} \u521B\u5EFA: ${formatTime(item.gmtCreate)} \u4FEE\u6539: ${formatTime(item.gmtModified)}` }) });
1568
- }
1569
- function Row3({ item, fillWidth }) {
1570
- const status = STATUS_MAP[item.status] ?? { label: item.status, color: "white" };
1571
- return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", children: [
1572
- /* @__PURE__ */ jsxs4(Box4, { flexDirection: "row", children: [
1573
- /* @__PURE__ */ jsx4(Box4, { width: COL_ID3, children: /* @__PURE__ */ jsx4(Text4, { color: "gray", children: item.id }) }),
1574
- /* @__PURE__ */ jsx4(Box4, { width: COL_STATUS2, children: /* @__PURE__ */ jsx4(Text4, { color: status.color, children: status.label }) }),
1575
- /* @__PURE__ */ jsx4(Box4, { width: COL_BRAND, children: /* @__PURE__ */ jsx4(Text4, { color: "cyan", children: truncate(item.brandName || "-", COL_BRAND - 1) }) }),
1576
- /* @__PURE__ */ jsx4(Box4, { width: fillWidth, children: /* @__PURE__ */ jsx4(Text4, { children: truncate(item.goodsName, fillWidth - 1) }) }),
1577
- /* @__PURE__ */ jsx4(Box4, { width: COL_PRICE, children: /* @__PURE__ */ jsxs4(Text4, { color: "yellow", children: [
1578
- "\xA5",
1579
- item.price
1580
- ] }) }),
1581
- /* @__PURE__ */ jsx4(Box4, { width: COL_SPEC, children: /* @__PURE__ */ jsx4(Text4, { color: "gray", children: item.spec || "-" }) }),
1582
- /* @__PURE__ */ jsx4(Box4, { width: COL_STOCK, children: /* @__PURE__ */ jsx4(Text4, { color: "gray", children: item.stockGoodsId }) })
1583
- ] }),
1584
- /* @__PURE__ */ jsx4(DetailRow, { item })
1585
- ] });
1586
- }
1587
- function ListingTable({ items, total }) {
1588
- const termWidth = process.stdout.columns || 80;
1589
- const borderPadding = 4;
1590
- const fixedCols = COL_ID3 + COL_STATUS2 + COL_BRAND + COL_PRICE + COL_SPEC + COL_STOCK;
1591
- const fillWidth = Math.max(termWidth - borderPadding - fixedCols, 20);
1592
- const totalWidth = fixedCols + fillWidth;
1593
- return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginTop: 1, borderStyle: "round", borderColor: "gray", paddingX: 1, children: [
1594
- /* @__PURE__ */ jsxs4(Box4, { flexDirection: "row", children: [
1595
- /* @__PURE__ */ jsx4(Text4, { bold: true, color: "cyan", children: "\u4E0A\u67B6\u5217\u8868" }),
1596
- /* @__PURE__ */ jsxs4(Text4, { color: "gray", children: [
1597
- " \xB7 \u5171 ",
1598
- total,
1599
- " \u6761"
1600
- ] })
1601
- ] }),
1602
- /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginTop: 1, children: [
1603
- /* @__PURE__ */ jsx4(Header3, { fillWidth }),
1604
- /* @__PURE__ */ jsx4(Text4, { color: "gray", children: "\u2500".repeat(totalWidth) }),
1605
- items.map((item) => /* @__PURE__ */ jsx4(Row3, { item, fillWidth }, item.id))
1606
- ] })
1607
- ] });
1608
- }
1609
-
1610
- // src/commands/goods/listing.ts
1611
- function createListingCommand() {
1612
- const command = new Command9("listing");
1613
- command.description("\u67E5\u8BE2\u4E0A\u67B6\u5546\u54C1\u5217\u8868");
1614
- command.option("--id <id>", "\u4E0A\u67B6\u8BB0\u5F55 ID").option("--stock-goods-id <id>", "\u5E93\u5B58\u5546\u54C1 ID").option("--shop-id <id>", "\u5E97\u94FA ID").option("--stock-id <id>", "\u4ED3\u5E93 ID").option("-s, --status <status>", "\u72B6\u6001\u8FC7\u6EE4\uFF08init/up/down/fail/sold\uFF09").option("-p, --platform <platform>", "\u5E73\u53F0", "xianyu").option("--page <n>", "\u9875\u7801", "1").option("--size <n>", "\u6BCF\u9875\u6570\u91CF\uFF08\u6700\u5927 50\uFF09", "20").option("--json", "\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09");
1615
- command.action(
1616
- jsonAction(async (options) => {
1617
- const result = await getListingList({
1618
- id: options.id,
1619
- stockGoodsId: options.stockGoodsId ? Number(options.stockGoodsId) : void 0,
1620
- shopId: options.shopId,
1621
- stockId: options.stockId,
1622
- status: options.status,
1623
- platform: options.platform,
1624
- page: Number(options.page) || 1,
1625
- size: Math.min(Number(options.size) || 20, 50)
1626
- });
1627
- const data = result ?? { items: [], total: 0 };
1628
- if (options.json) {
1629
- if (!data.items?.length) {
1630
- console.log(JSON.stringify({ ...data, hint: "\u6682\u65E0\u4E0A\u67B6\u8BB0\u5F55" }, null, 2));
1631
- } else {
1632
- console.log(JSON.stringify(data, null, 2));
1633
- }
1634
- return;
1635
- }
1636
- if (!data.items?.length) {
1637
- console.log(chalk9.yellow("\u6682\u65E0\u4E0A\u67B6\u8BB0\u5F55"));
1638
- return;
1639
- }
1640
- renderComponent(ListingTable, { items: data.items, total: data.total });
1641
- })
1642
- );
1643
- return command;
1644
- }
1645
-
1646
- // src/commands/goods/down.ts
1647
- import { Command as Command10 } from "commander";
1648
- import chalk10 from "chalk";
1649
- function createDownCommand() {
1650
- const command = new Command10("down");
1651
- command.description("\u4E0B\u67B6\u95F2\u9C7C\u5546\u54C1");
1652
- command.option("--id <id>", "\u4E0A\u67B6\u8BB0\u5F55 ID").option("--stock-goods-id <id>", "\u5E93\u5B58\u5546\u54C1 ID").option("--shop-id <id>", "\u5E97\u94FA ID").option("--json", "\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09");
1653
- command.action(
1654
- jsonAction(async (options) => {
1655
- if (!options.id && !(options.stockGoodsId && options.shopId)) {
1656
- if (options.json) {
1657
- console.log(JSON.stringify({ success: false, error: "\u8BF7\u6307\u5B9A\u4E0B\u67B6\u6761\u4EF6\uFF1A--id <id> \u6216 --stock-goods-id <id> --shop-id <id>" }));
1658
- process.exit(1);
1659
- }
1660
- console.log(chalk10.yellow("\u8BF7\u6307\u5B9A\u4E0B\u67B6\u6761\u4EF6\uFF1A--id <id> \u6216 --stock-goods-id <id> --shop-id <id>"));
1661
- return;
1662
- }
1663
- const params = {};
1664
- if (options.id) params.id = options.id;
1665
- if (options.stockGoodsId) params.stockGoodsId = Number(options.stockGoodsId);
1666
- if (options.shopId) params.shopId = options.shopId;
1667
- if (!options.json) console.log(chalk10.cyan("\u{1F4E6} \u6B63\u5728\u4E0B\u67B6\u5546\u54C1..."));
1668
- const result = await listingDownXianyu(params);
1669
- if (options.json) {
1670
- console.log(JSON.stringify({ success: true, data: result }, null, 2));
1671
- } else {
1672
- console.log(chalk10.green("\u2705 \u4E0B\u67B6\u6210\u529F"));
1673
- console.log(JSON.stringify(result, null, 2));
1674
- }
1675
- })
1676
- );
1677
- return command;
1678
- }
1679
-
1680
- // src/commands/goods/price.ts
1681
- import { Command as Command11 } from "commander";
1682
- import chalk11 from "chalk";
1683
- function createPriceCommand() {
1684
- const command = new Command11("price");
1685
- command.description("\u4FEE\u6539\u95F2\u9C7C\u4E0A\u67B6\u5546\u54C1\u4EF7\u683C");
1686
- command.option("--id <id>", "\u4E0A\u67B6\u8BB0\u5F55 ID").option("--stock-goods-id <id>", "\u5E93\u5B58\u5546\u54C1 ID").option("--shop-id <id>", "\u5E97\u94FA ID").option("--price <amount>", "\u65B0\u4EF7\u683C\uFF08\u5FC5\u586B\uFF09").option("--json", "\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09");
1687
- command.action(
1688
- jsonAction(async (options) => {
1689
- if (!options.price) {
1690
- if (options.json) {
1691
- console.log(JSON.stringify({ success: false, error: "--price <amount> \u4E3A\u5FC5\u586B\u53C2\u6570" }));
1692
- process.exit(1);
1693
- }
1694
- console.log(chalk11.yellow("--price <amount> \u4E3A\u5FC5\u586B\u53C2\u6570"));
1695
- return;
1696
- }
1697
- if (!options.id && !(options.stockGoodsId && options.shopId)) {
1698
- if (options.json) {
1699
- console.log(JSON.stringify({ success: false, error: "\u8BF7\u6307\u5B9A\u5546\u54C1\uFF1A--id <id> \u6216 --stock-goods-id <id> --shop-id <id>" }));
1700
- process.exit(1);
1701
- }
1702
- console.log(chalk11.yellow("\u8BF7\u6307\u5B9A\u5546\u54C1\uFF1A--id <id> \u6216 --stock-goods-id <id> --shop-id <id>"));
1703
- return;
1704
- }
1705
- const params = { price: Number(options.price) };
1706
- if (options.id) params.id = options.id;
1707
- if (options.stockGoodsId) params.stockGoodsId = Number(options.stockGoodsId);
1708
- if (options.shopId) params.shopId = options.shopId;
1709
- if (!options.json) console.log(chalk11.cyan(`\u{1F4B0} \u6B63\u5728\u4FEE\u6539\u4EF7\u683C\u4E3A ${options.price}...`));
1710
- const result = await listingUpdatePrice(params);
1711
- if (options.json) {
1712
- console.log(JSON.stringify({ success: true, data: result }, null, 2));
1713
- } else {
1714
- console.log(chalk11.green("\u2705 \u4EF7\u683C\u4FEE\u6539\u6210\u529F"));
1715
- console.log(JSON.stringify(result, null, 2));
1716
- }
1717
- })
1718
- );
1719
- return command;
1720
- }
1721
-
1722
- // src/commands/goods/edit.ts
1723
- import { Command as Command12 } from "commander";
1724
- import chalk12 from "chalk";
1725
- function createEditCommand() {
1726
- const command = new Command12("edit");
1727
- command.description("\u4FEE\u6539\u5DF2\u4E0A\u67B6\u5546\u54C1\u4FE1\u606F\uFF08\u6807\u9898\u3001\u63CF\u8FF0\u3001\u54C1\u724C\u3001\u7C7B\u76EE\u3001\u56FE\u7247\u3001\u5C5E\u6027\u7B49\uFF09");
1728
- command.option("--id <id>", "\u5546\u54C1\u4E0A\u67B6 ID\uFF08goodsListingId\uFF0C\u63A8\u8350\uFF09").option("--stock-goods-id <id>", "\u5E93\u5B58\u5546\u54C1 ID\uFF08\u4E0E --account \u914D\u5408\uFF09").option("--account <shopId>", "\u95F2\u9C7C\u7528\u6237\u540D/\u5E97\u94FA ID\uFF08\u4E0E --stock-goods-id \u914D\u5408\uFF09").option("--title <title>", "\u5546\u54C1\u6807\u9898").option("--desc <desc>", "\u5546\u54C1\u63CF\u8FF0").option("--category-id <id>", "\u5546\u54C1\u7C7B\u76EE ID\uFF08\u5927\u5206\u7C7B\uFF0C\u540E\u7AEF\u5FC5\u586B\uFF09").option("--channel-cat-id <id>", "\u6E20\u9053\u7C7B\u76EE ID\uFF08\u5C0F\u5206\u7C7B\uFF0C\u540E\u7AEF\u5FC5\u586B\uFF09").option("--image-ids <ids>", "\u56FE\u7247 ID \u5217\u8868\uFF08\u9017\u53F7\u5206\u9694\uFF09").option("--item-attrs <json>", "\u5546\u54C1\u5C5E\u6027\u5217\u8868\uFF08JSON \u5B57\u7B26\u4E32\uFF09").option("--brand-name <name>", "\u54C1\u724C\u540D\u79F0").option("--stuff-status <status>", "\u6210\u8272\u7B49\u7EA7\uFF1A100=\u5168\u65B0 -1=\u51C6\u65B0 99=99\u65B0 95=95\u65B0 90=9\u65B0").option("--goods-no <no>", "\u8D27\u53F7").option("--original-price <price>", "\u539F\u4EF7\uFF08\u5355\u4F4D\uFF1A\u5143\uFF09").option("--size <size>", "\u5C3A\u7801").option("--json", "\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09");
1729
- command.action(
1730
- jsonAction(async (options) => {
1731
- if (!options.id && !(options.stockGoodsId && options.account)) {
1732
- if (options.json) {
1733
- console.log(JSON.stringify({ success: false, status: 400, error: "\u8BF7\u6307\u5B9A\u5546\u54C1\uFF1A--id <goodsListingId> \u6216 --stock-goods-id <id> --account <shopId>" }));
1734
- process.exit(1);
1735
- }
1736
- console.log(chalk12.yellow("\u8BF7\u6307\u5B9A\u5546\u54C1\uFF1A--id <goodsListingId> \u6216 --stock-goods-id <id> --account <shopId>"));
1737
- return;
1738
- }
1739
- const params = {};
1740
- if (options.id) params.goodsListingId = Number(options.id);
1741
- if (options.stockGoodsId) params.stockGoodsId = Number(options.stockGoodsId);
1742
- if (options.account) params.account = options.account;
1743
- if (options.title) params.title = options.title;
1744
- if (options.desc) params.desc = options.desc;
1745
- if (options.categoryId) params.categoryId = Number(options.categoryId);
1746
- if (options.channelCatId) params.channelCatId = options.channelCatId;
1747
- if (options.imageIds) params.imageIdList = options.imageIds.split(",").map((s) => s.trim());
1748
- if (options.brandName) params.brandName = options.brandName;
1749
- if (options.stuffStatus) params.stuffStatus = Number(options.stuffStatus);
1750
- if (options.goodsNo) params.goodsNo = options.goodsNo;
1751
- if (options.originalPrice) params.originalPrice = Number(options.originalPrice);
1752
- if (options.size) params.size = options.size;
1753
- if (options.itemAttrs) {
1754
- try {
1755
- params.itemAttrList = JSON.parse(options.itemAttrs);
1756
- } catch {
1757
- if (options.json) {
1758
- console.log(JSON.stringify({ success: false, status: 400, error: "--item-attrs JSON \u89E3\u6790\u5931\u8D25" }));
1759
- process.exit(1);
1760
- }
1761
- console.log(chalk12.yellow("--item-attrs JSON \u89E3\u6790\u5931\u8D25"));
1762
- return;
1763
- }
1764
- }
1765
- const hasUpdate = Object.keys(params).some(
1766
- (k) => !["goodsListingId", "stockGoodsId", "account"].includes(k)
1767
- );
1768
- if (!hasUpdate) {
1769
- if (options.json) {
1770
- console.log(JSON.stringify({ success: false, status: 400, error: "\u672A\u6307\u5B9A\u9700\u8981\u4FEE\u6539\u7684\u5B57\u6BB5" }));
1771
- process.exit(1);
1772
- }
1773
- console.log(chalk12.yellow("\u672A\u6307\u5B9A\u9700\u8981\u4FEE\u6539\u7684\u5B57\u6BB5"));
1774
- return;
1775
- }
1776
- if (!options.json) console.log(chalk12.cyan("\u6B63\u5728\u4FEE\u6539\u5546\u54C1\u4FE1\u606F..."));
1777
- const result = await updateGoodsInfo(params);
1778
- if (options.json) {
1779
- console.log(JSON.stringify({ success: true, data: result }, null, 2));
1780
- } else {
1781
- console.log(chalk12.green("\u2705 \u5546\u54C1\u4FE1\u606F\u4FEE\u6539\u6210\u529F"));
1782
- console.log(JSON.stringify(result, null, 2));
1783
- }
1784
- })
1785
- );
1786
- return command;
1787
- }
1788
-
1789
- // src/commands/goods/hang-up.ts
1790
- import { Command as Command13 } from "commander";
1791
- import chalk13 from "chalk";
1792
- var STUFF_STATUS_MAP = {
1793
- 100: "\u5168\u65B0",
1794
- [-1]: "\u51C6\u65B0",
1795
- 99: "99\u65B0",
1796
- 95: "95\u65B0",
1797
- 90: "9\u65B0"
1798
- };
1799
- function createHangUpCommand() {
1800
- const command = new Command13("hang-up");
1801
- command.description("\u95F2\u9C7C\u6302\u552E\u4E0A\u67B6\uFF08\u5B8C\u6574\u5546\u54C1\u4FE1\u606F\u6A21\u5F0F\uFF09");
1802
- command.addCommand(
1803
- new Command13("categories").description("\u83B7\u53D6\u95F2\u9C7C\u7C7B\u76EE\u5217\u8868\uFF08\u5927\u5206\u7C7B \u2192 \u5C0F\u5206\u7C7B\uFF09").option("--sp-biz-type <n>", "\u4E1A\u52A1\u5206\u7C7B\uFF0C16=\u5962\u54C1", "16").option("--json", "\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09").action(jsonAction(async (options) => {
1804
- const cats = await getXyCategories(Number(options.spBizType));
1805
- if (options.json) {
1806
- console.log(JSON.stringify(cats, null, 2));
1807
- return;
1808
- }
1809
- const grouped = /* @__PURE__ */ new Map();
1810
- for (const cat of cats) {
1811
- const key = String(cat.catId);
1812
- if (!grouped.has(key)) grouped.set(key, { catName: cat.catName, children: [] });
1813
- grouped.get(key).children.push({ channel: cat.channel, channelCatId: cat.channelCatId });
1814
- }
1815
- for (const [catId, group] of grouped) {
1816
- console.log(chalk13.bold(`${group.catName} (catId: ${chalk13.green(catId)})`));
1817
- for (const child of group.children) {
1818
- console.log(` ${child.channel} (channelCatId: ${chalk13.green(child.channelCatId)})`);
1819
- }
1820
- }
1821
- }))
1822
- );
1823
- command.addCommand(
1824
- new Command13("props").description("\u83B7\u53D6\u6307\u5B9A\u7C7B\u76EE\u4E0B\u7684\u5C5E\u6027\u5217\u8868\uFF08\u542B\u53EF\u9009\u503C\uFF09").requiredOption("--channel-cat-id <id>", "\u5C0F\u5206\u7C7B ID\uFF08\u4ECE categories \u83B7\u53D6\uFF09").option("--json", "\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09").action(jsonAction(async (options) => {
1825
- const props = await getXyProps(options.channelCatId);
1826
- if (options.json) {
1827
- console.log(JSON.stringify(props, null, 2));
1828
- return;
1829
- }
1830
- for (const prop of props) {
1831
- console.log(chalk13.bold(`
1832
- ${prop.propName} (propId: ${prop.propId})`));
1833
- if (prop.propsValues?.length) {
1834
- for (const val of prop.propsValues) {
1835
- console.log(` ${val.valueName} (valueId: ${val.valueId})`);
1836
- }
1837
- } else {
1838
- console.log(chalk13.gray(" \uFF08\u4F7F\u7528 brands \u5B50\u547D\u4EE4\u641C\u7D22\uFF09"));
1839
- }
1840
- }
1841
- }))
1842
- );
1843
- command.addCommand(
1844
- new Command13("brands").description("\u641C\u7D22\u95F2\u9C7C\u54C1\u724C\uFF08\u6309\u5173\u952E\u5B57\u8FC7\u6EE4\uFF09").requiredOption("--channel-cat-id <id>", "\u5C0F\u5206\u7C7B ID").requiredOption("--prop-id <id>", "\u5C5E\u6027 ID\uFF08\u54C1\u724C\u5C5E\u6027\u7684 propId\uFF09").requiredOption("--key <keyword>", "\u641C\u7D22\u5173\u952E\u5B57").option("--json", "\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09").action(jsonAction(async (options) => {
1845
- const values = await getXyPropValues(options.channelCatId, options.propId, options.key);
1846
- if (options.json) {
1847
- console.log(JSON.stringify(values, null, 2));
1848
- return;
1849
- }
1850
- if (!values.length) {
1851
- console.log(chalk13.yellow("\u672A\u627E\u5230\u5339\u914D\u7684\u54C1\u724C"));
1852
- return;
1853
- }
1854
- for (const val of values) {
1855
- console.log(` ${val.valueName} (valueId: ${val.valueId})`);
1856
- }
1857
- }))
1858
- );
1859
- command.addCommand(
1860
- new Command13("upload-images").description("\u6279\u91CF\u4E0A\u4F20\u56FE\u7247\u5230\u95F2\u9C7C\uFF08\u6302\u552E\u524D\u5FC5\u987B\u5148\u4E0A\u4F20\u56FE\u7247\uFF09").requiredOption("--shop-id <id>", "\u5E97\u94FA ID").requiredOption("--files <paths>", "\u56FE\u7247\u6587\u4EF6\u8DEF\u5F84\uFF0C\u9017\u53F7\u5206\u9694").option("--json", "\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09").action(jsonAction(async (options) => {
1861
- const filePaths = options.files.split(",").map((p) => p.trim()).filter(Boolean);
1862
- if (filePaths.length === 0) {
1863
- if (options.json) {
1864
- console.log(JSON.stringify({ success: false, error: "\u8BF7\u63D0\u4F9B\u81F3\u5C11\u4E00\u5F20\u56FE\u7247" }));
1865
- process.exit(1);
1866
- }
1867
- console.log(chalk13.yellow("\u8BF7\u63D0\u4F9B\u81F3\u5C11\u4E00\u5F20\u56FE\u7247"));
1868
- return;
1869
- }
1870
- if (!options.json) console.log(chalk13.cyan(`\u6B63\u5728\u4E0A\u4F20 ${filePaths.length} \u5F20\u56FE\u7247...`));
1871
- const images = await uploadXyImages(options.shopId, filePaths);
1872
- if (options.json) {
1873
- console.log(JSON.stringify({ success: true, images }, null, 2));
1874
- } else {
1875
- console.log(chalk13.green(`\u4E0A\u4F20\u6210\u529F\uFF0C\u5171 ${images.length} \u5F20`));
1876
- for (const img of images) {
1877
- console.log(` \u56FE\u7247ID: ${img.value}`);
1878
- }
1879
- }
1880
- }))
1881
- );
1882
- command.addCommand(
1883
- new Command13("submit").description("\u63D0\u4EA4\u6302\u552E\u4E0A\u67B6").requiredOption("--shop-id <id>", "\u5E97\u94FA ID\uFF08\u5373\u95F2\u9C7C\u7528\u6237\u540D account\uFF09").requiredOption("--title <title>", "\u5546\u54C1\u6807\u9898").requiredOption("--price <amount>", "\u552E\u4EF7").requiredOption("--category-id <id>", "\u5927\u5206\u7C7B ID\uFF08\u4ECE categories \u83B7\u53D6\uFF09").requiredOption("--channel-cat-id <id>", "\u5C0F\u5206\u7C7B ID\uFF08\u4ECE categories \u83B7\u53D6\uFF09").requiredOption("--image-ids <ids>", "\u56FE\u7247 ID \u5217\u8868\uFF0C\u9017\u53F7\u5206\u9694\uFF08\u5148\u901A\u8FC7 upload-images \u83B7\u53D6\uFF09").requiredOption("--stuff-status <n>", "\u6210\u8272\uFF1A100 \u5168\u65B0 / -1 \u51C6\u65B0 / 99 99\u65B0 / 95 95\u65B0 / 90 9\u65B0").option("--item-attrs <json>", '\u5546\u54C1\u5C5E\u6027\u5217\u8868 JSON\uFF0C\u683C\u5F0F: [{"propId":"x","valueId":"y","valueName":"z"}]').option("--brand-name <name>", "\u54C1\u724C\u540D\u79F0").option("--desc <desc>", "\u5546\u54C1\u63CF\u8FF0").option("--size <size>", "\u5C3A\u7801").option("--goods-no <no>", "\u8D27\u53F7").option("--original-price <amount>", "\u539F\u4EF7").option("--trade-type <n>", "\u4EA4\u6613\u65B9\u5F0F\uFF1A0 \u4EC5\u5728\u7EBF / 1 \u4EC5\u7EBF\u4E0B / 2 \u7EBF\u4E0A\u6216\u7EBF\u4E0B", "0").option("--transport-fee <amount>", "\u8FD0\u8D39\uFF08\u9ED8\u8BA4 0 \u5305\u90AE\uFF09", "0").option("--yhb", "\u662F\u5426\u5F00\u542F\u9A8C\u8D27\u5B9D").requiredOption("--out-item-no <no>", "\u5546\u5BB6\u7F16\u7801\uFF08\u540C\u5E97\u94FA\u552F\u4E00\uFF0C\u7528\u6237\u81EA\u5B9A\u4E49\uFF09").option("--division-id <id>", "\u884C\u653F\u533A\u5212 ID\uFF08\u5E02\u7EA7 ID\uFF0C\u9ED8\u8BA4\u676D\u5DDE 330100\uFF09", "330100").option("--json", "\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09").action(jsonAction(async (options) => {
1884
- const imageIdList = options.imageIds.split(",").map((id) => id.trim());
1885
- const params = {
1886
- account: options.shopId,
1887
- title: options.title,
1888
- reservePrice: Number(options.price),
1889
- categoryId: Number(options.categoryId),
1890
- channelCatId: options.channelCatId,
1891
- imageIdList,
1892
- stuffStatus: Number(options.stuffStatus),
1893
- itemBizType: 2,
1894
- spBizType: "16",
1895
- tradeType: Number(options.tradeType) || 0,
1896
- transportFee: Number(options.transportFee) || 0,
1897
- yhb: options.yhb ?? false,
1898
- ...options.brandName && { brandName: options.brandName },
1899
- ...options.desc && { desc: options.desc },
1900
- ...options.size && { size: options.size },
1901
- ...options.goodsNo && { goodsNo: options.goodsNo },
1902
- ...options.originalPrice && { originalPrice: Number(options.originalPrice) },
1903
- outItemNo: options.outItemNo,
1904
- divisionId: Number(options.divisionId) || 330100,
1905
- apiAfterSalesDo: {
1906
- supportFd10msPolicy: false,
1907
- supportFd24hsPolicy: false,
1908
- supportNfrPolicy: false,
1909
- supportSdrPolicy: false,
1910
- supportVnrPolicy: false,
1911
- supportGpaPolicy: false,
1912
- supportFd48hsPolicy: false
1913
- },
1914
- ...options.itemAttrs && { itemAttrList: JSON.parse(options.itemAttrs) }
1915
- };
1916
- if (!options.json) {
1917
- console.log(chalk13.cyan("\u6B63\u5728\u63D0\u4EA4\u6302\u552E..."));
1918
- console.log(chalk13.gray(` \u6807\u9898: ${params.title}`));
1919
- console.log(chalk13.gray(` \u552E\u4EF7: \xA5${params.reservePrice}`));
1920
- console.log(chalk13.gray(` \u6210\u8272: ${STUFF_STATUS_MAP[params.stuffStatus] ?? params.stuffStatus}`));
1921
- console.log(chalk13.gray(` \u56FE\u7247: ${imageIdList.length} \u5F20`));
1922
- if (params.itemAttrList?.length) {
1923
- console.log(chalk13.gray(` \u5C5E\u6027: ${params.itemAttrList.length} \u9879`));
1924
- }
1925
- }
1926
- const result = await listingHangUpXianyu(params);
1927
- if (options.json) {
1928
- console.log(JSON.stringify({ success: true, data: result }, null, 2));
1929
- } else {
1930
- console.log(chalk13.green("\u6302\u552E\u63D0\u4EA4\u6210\u529F"));
1931
- console.log(JSON.stringify(result, null, 2));
1932
- }
1933
- }))
1934
- );
1935
- return command;
1936
- }
1937
-
1938
- // src/commands/goods/index.ts
1939
- function createGoodsCommand() {
1940
- const command = new Command14("goods");
1941
- command.description("\u5546\u54C1\u7BA1\u7406");
1942
- command.addCommand(createShopsCommand());
1943
- command.addCommand(createStocksCommand());
1944
- command.addCommand(createListCommand());
1945
- command.addCommand(createListingCommand());
1946
- command.addCommand(createDownCommand());
1947
- command.addCommand(createPriceCommand());
1948
- command.addCommand(createEditCommand());
1949
- command.addCommand(createUpCommand());
1950
- command.addCommand(createHangUpCommand());
1951
- return command;
1952
- }
1953
-
1954
- // src/commands/uninstall.ts
1955
- import { Command as Command15 } from "commander";
1956
- import chalk14 from "chalk";
1957
- import { promises as fs3 } from "node:fs";
1958
- import path3 from "node:path";
1959
- import os2 from "node:os";
1960
- import { spawn } from "node:child_process";
1961
- var PKG_NAME = "@round2ai/r2-cli";
1962
- function createUninstallCommand() {
1963
- const command = new Command15("uninstall");
1964
- command.description("\u5378\u8F7D R2-CLI \u5E76\u6E05\u9664\u6240\u6709\u914D\u7F6E");
1965
- command.action(async () => {
1966
- try {
1967
- console.log(chalk14.yellow("\n\u26A0\uFE0F \u5373\u5C06\u6267\u884C\u4EE5\u4E0B\u64CD\u4F5C\uFF1A"));
1968
- console.log(chalk14.gray(` 1. \u5220\u9664\u914D\u7F6E\u76EE\u5F55 ~/.r2-cli/`));
1969
- console.log(chalk14.gray(` 2. \u5168\u5C40\u5378\u8F7D ${PKG_NAME}
1970
- `));
1971
- const { confirm: confirm2 } = await import("@inquirer/prompts");
1972
- const confirmed = await confirm2({ message: "\u786E\u8BA4\u5378\u8F7D\uFF1F", default: false });
1973
- if (!confirmed) {
1974
- console.log(chalk14.gray("\u5DF2\u53D6\u6D88\u5378\u8F7D"));
1975
- return;
1976
- }
1977
- const configDir = path3.join(os2.homedir(), ".r2-cli");
1978
- try {
1979
- await fs3.rm(configDir, { recursive: true, force: true });
1980
- console.log(chalk14.green("\u2705 \u914D\u7F6E\u6587\u4EF6\u5DF2\u6E05\u9664"));
1981
- } catch {
1982
- console.log(chalk14.yellow("\u26A0\uFE0F \u914D\u7F6E\u76EE\u5F55\u4E0D\u5B58\u5728\u6216\u65E0\u6CD5\u5220\u9664\uFF08\u53EF\u5FFD\u7565\uFF09"));
1983
- }
1984
- console.log(chalk14.cyan(`\u6B63\u5728\u5378\u8F7D ${PKG_NAME}...`));
1985
- const child = spawn("npm", ["uninstall", "-g", PKG_NAME], {
1986
- stdio: "inherit",
1987
- shell: true
1988
- });
1989
- child.on("exit", (code) => {
1990
- if (code === 0) {
1991
- console.log(chalk14.green(`
1992
- \u2705 ${PKG_NAME} \u5DF2\u5378\u8F7D`));
1993
- } else {
1994
- console.log(chalk14.yellow(`
1995
- \u26A0\uFE0F npm \u5378\u8F7D\u5931\u8D25 (exit code: ${code})`));
1996
- console.log(chalk14.gray(" \u5982\u901A\u8FC7 yarn/pnpm \u5B89\u88C5\uFF0C\u8BF7\u624B\u52A8\u5378\u8F7D"));
1997
- }
1998
- process.exit(code ?? 1);
1999
- });
2000
- } catch (error) {
2001
- handleCommandError(error);
2002
- }
2003
- });
2004
- return command;
2005
- }
2006
-
2007
- // src/commands/update.ts
2008
- import { Command as Command16 } from "commander";
2009
- import chalk15 from "chalk";
2010
- import { spawn as spawn2, execSync } from "node:child_process";
2011
-
2012
- // src/utils/version.ts
2013
- import { readFileSync as readFileSync2 } from "node:fs";
2014
- import { join } from "node:path";
2015
- function getVersion() {
2016
- for (const rel of ["../package.json", "../../package.json"]) {
2017
- try {
2018
- return JSON.parse(readFileSync2(join(import.meta.dirname, rel), "utf-8")).version;
2019
- } catch {
2020
- }
2021
- }
2022
- return "0.0.0";
2023
- }
2024
-
2025
- // src/commands/update.ts
2026
- var PKG_NAME2 = "@round2ai/r2-cli";
2027
- function run(cmd, args) {
2028
- return new Promise((resolve) => {
2029
- const child = spawn2(cmd, args, { stdio: "inherit" });
2030
- child.on("close", (code) => resolve(code ?? 1));
2031
- child.on("error", () => resolve(1));
2032
- });
2033
- }
2034
- function createUpdateCommand() {
2035
- return new Command16("update").description("\u4E00\u952E\u66F4\u65B0 CLI \u548C\u6280\u80FD").action(async () => {
2036
- const oldVersion = getVersion();
2037
- console.log(chalk15.cyan(`\u5F53\u524D\u7248\u672C: ${oldVersion}`));
2038
- console.log(chalk15.cyan("\u6B63\u5728\u66F4\u65B0 CLI..."));
2039
- const code = await run("npm", ["install", "-g", `${PKG_NAME2}@latest`]);
2040
- if (code !== 0) {
2041
- console.error(chalk15.red(`
2042
- \u2717 update failed \xB7 Try: npm install -g ${PKG_NAME2}@latest`));
2043
- process.exit(1);
2044
- }
2045
- let newVersion = oldVersion;
2046
- try {
2047
- const output = execSync("r2-cli --version", { encoding: "utf-8" }).trim();
2048
- newVersion = output || oldVersion;
2049
- } catch {
2050
- }
2051
- console.log(chalk15.green(`
2052
- \u2713 \u66F4\u65B0\u5B8C\u6210: ${oldVersion} \u2192 ${newVersion}`));
2053
- console.log(chalk15.green("\u2713 \u6280\u80FD\u5DF2\u540C\u6B65\u66F4\u65B0"));
2054
- });
2055
- }
2056
-
2057
- // src/commands/setup.ts
2058
- function setupCommands(program2) {
2059
- const authCommand = program2.command("auth").description("\u6388\u6743\u7BA1\u7406");
2060
- authCommand.addCommand(createLoginCommand());
2061
- authCommand.addCommand(createLogoutCommand());
2062
- authCommand.addCommand(createStatusCommand());
2063
- authCommand.addCommand(createXianyuAuthCommand());
2064
- program2.addCommand(createGoodsCommand());
2065
- program2.addCommand(createUninstallCommand());
2066
- program2.addCommand(createUpdateCommand());
2067
- }
2068
-
2069
- // src/services/update-check/index.ts
2070
- import chalk16 from "chalk";
2071
- var PKG_NAME3 = "@round2ai/r2-cli";
2072
- var REGISTRY_URLS = [
2073
- `https://registry.npmmirror.com/${encodeURIComponent(PKG_NAME3)}/latest`,
2074
- `https://registry.npmjs.org/${encodeURIComponent(PKG_NAME3)}/latest`
2075
- ];
2076
- var FETCH_TIMEOUT_MS = 5e3;
2077
- async function fetchVersionFromRegistry(url) {
2078
- const controller = new AbortController();
2079
- const timer = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
2080
- try {
2081
- const res = await fetch(url, { signal: controller.signal });
2082
- if (!res.ok) return null;
2083
- return (await res.json()).version ?? null;
2084
- } catch {
2085
- return null;
2086
- } finally {
2087
- clearTimeout(timer);
2088
- }
2089
- }
2090
- async function fetchLatestVersion() {
2091
- const results = await Promise.allSettled(REGISTRY_URLS.map(fetchVersionFromRegistry));
2092
- for (const r of results) {
2093
- if (r.status === "fulfilled" && r.value) return r.value;
2094
- }
2095
- return null;
2096
- }
2097
- function isNewer(latest, current) {
2098
- const la = latest.split(".").map(Number);
2099
- const cu = current.split(".").map(Number);
2100
- for (let i = 0; i < 3; i++) {
2101
- if ((la[i] ?? 0) !== (cu[i] ?? 0)) return (la[i] ?? 0) > (cu[i] ?? 0);
2102
- }
2103
- return false;
2104
- }
2105
- async function checkForUpdate(currentVersion) {
2106
- const latest = await fetchLatestVersion();
2107
- if (!latest) return;
2108
- if (isNewer(latest, currentVersion)) {
2109
- showUpdateNotification(currentVersion, latest);
2110
- }
2111
- }
2112
- function showUpdateNotification(current, latest) {
2113
- console.error(
2114
- chalk16.yellow(`
2115
- Update available: ${current} \u2192 ${latest}`) + chalk16.gray(`
3
+ var ce=Object.defineProperty;var it=(o,t)=>()=>(o&&(t=o(o=0)),t);var at=(o,t)=>{for(var e in t)ce(o,e,{get:t[e],enumerable:!0})};var fo={};at(fo,{UserInfoCard:()=>Ae});import{Box as H,Text as G}from"ink";import{jsx as q,jsxs as V}from"react/jsx-runtime";function Ae({userInfo:o,lastLogin:t,daysSinceLogin:e}){let r=o.mobile?o.mobile.replace(/(\d{3})\d{4}(\d{4})/,"$1****$2"):"-";return V(H,{flexDirection:"column",marginTop:1,borderStyle:"round",borderColor:"gray",paddingX:1,children:[q(G,{bold:!0,color:"cyan",children:"\u7528\u6237\u4FE1\u606F"}),V(H,{flexDirection:"row",marginTop:1,children:[q(H,{width:10,children:q(G,{color:"gray",children:"\u6635\u79F0"})}),q(G,{color:"yellow",children:o.nickname})]}),V(H,{flexDirection:"row",children:[q(H,{width:10,children:q(G,{color:"gray",children:"\u624B\u673A\u53F7"})}),q(G,{color:"yellow",children:r})]}),t&&V(H,{flexDirection:"column",marginTop:1,children:[V(G,{color:"gray",children:["\u6700\u540E\u767B\u5F55: ",t.toLocaleString()]}),e!==void 0&&V(G,{color:"gray",children:[" \u8DDD\u4ECA: ",e," \u5929"]})]})]})}var ho=it(()=>{"use strict"});var gt={};at(gt,{renderComponent:()=>$t,renderOnce:()=>yo});import ke from"react";import jt from"chalk";import{render as ve}from"ink";import{Writable as Ne}from"node:stream";function yo(o){let t=jt.level;process.env.NO_COLOR||(jt.level=3);try{let e=[],r=new Ne({write(l,y,m){e.push(Buffer.from(l)),m()}});r.isTTY=!0,r.columns=process.stdout.columns||80,r.rows=process.stdout.rows||24,ve(o,{stdout:r,patchConsole:!1}).unmount();let s=Buffer.concat(e).toString("utf8"),a=(s.split(/\x1B\[2J\x1B\[3J\x1B\[H/).at(-1)||s).replace(/\x1B\[\?[\d;]+[hl]/g,"").trimEnd()+`
4
+ `;process.stdout.write(a)}finally{jt.level=t}}function $t(o,t){yo(ke.createElement(o,t))}var et=it(()=>{"use strict"});var jo={};at(jo,{ShopsTable:()=>_e});import{Box as S,Text as N}from"ink";import{jsx as f,jsxs as K}from"react/jsx-runtime";function qe(o){return o.map(t=>"shopName"in t?{id:t.shopId,name:t.shopName,platform:t.platform,expiresIn:t.expiresIn}:{id:t.id,name:t.name,platform:t.thirdUserId,expiresIn:t.expiresIn})}function Je({hasPlatform:o,fillWidth:t}){return K(S,{flexDirection:"row",paddingBottom:0,children:[o&&f(S,{width:zt,children:f(N,{bold:!0,color:"white",children:"\u5E73\u53F0"})}),f(S,{width:t,children:f(N,{bold:!0,color:"white",children:"\u5E97\u94FA\u540D"})}),f(S,{width:Wt,children:f(N,{bold:!0,color:"white",children:"ID"})}),f(S,{width:Ht,children:f(N,{bold:!0,color:"white",children:"\u72B6\u6001"})})]})}function Xe({shop:o,hasPlatform:t,fillWidth:e}){let r=Eo[o.platform]??o.platform;return K(S,{flexDirection:"row",children:[t&&f(S,{width:zt,children:f(N,{color:"cyan",children:r})}),f(S,{width:e,children:f(N,{bold:!0,children:o.name})}),f(S,{width:Wt,children:f(N,{color:"gray",children:o.id})}),f(S,{width:Ht,children:f(N,{color:"green",children:"\u25CF \u6388\u6743\u4E2D"})})]})}function _e({shops:o,platform:t}){let e=qe(o),r=t==="all",n=t==="all"?"\u6240\u6709\u6388\u6743\u5E97\u94FA":`${Eo[t]??t}\u6388\u6743\u5E97\u94FA`,s=process.stdout.columns||80,i=4,a=Wt+Ht+(r?zt:0),l=Math.max(s-i-a,20),y=a+l;return K(S,{flexDirection:"column",marginTop:1,borderStyle:"round",borderColor:"gray",paddingX:1,children:[K(S,{flexDirection:"row",children:[f(N,{bold:!0,color:"cyan",children:n}),K(N,{color:"gray",children:[" \xB7 ",e.length," \u5BB6"]})]}),K(S,{flexDirection:"column",marginTop:1,children:[f(Je,{hasPlatform:r,fillWidth:l}),f(N,{color:"gray",children:"\u2500".repeat(y)}),e.map(m=>f(Xe,{shop:m,hasPlatform:r,fillWidth:l},m.id))]})]})}var Eo,zt,Wt,Ht,$o=it(()=>{"use strict";Eo={xianyu:"\u95F2\u9C7C",douyin:"\u6296\u97F3"},zt=8,Wt=16,Ht=10});var qo={};at(qo,{StocksTable:()=>ze});import{Box as x,Text as C}from"ink";import{jsx as u,jsxs as Y}from"react/jsx-runtime";function Me({fillWidth:o}){return Y(x,{flexDirection:"row",paddingBottom:0,children:[u(x,{width:Vt,children:u(C,{bold:!0,color:"white",children:"ID"})}),u(x,{width:Kt,children:u(C,{bold:!0,color:"white",children:"\u7528\u6237ID"})}),u(x,{width:Yt,children:u(C,{bold:!0,color:"white",children:"\u4ED3\u5E93ID"})}),u(x,{width:o,children:u(C,{bold:!0,color:"white",children:"\u4ED3\u5E93\u540D\u79F0"})}),u(x,{width:Zt,children:u(C,{bold:!0,color:"white",children:"\u521B\u5EFA\u65F6\u95F4"})})]})}function Fe({stock:o,fillWidth:t}){let e=new Date(o.gmtCreate).toLocaleString("zh-CN");return Y(x,{flexDirection:"row",children:[u(x,{width:Vt,children:u(C,{color:"gray",children:o.id})}),u(x,{width:Kt,children:u(C,{color:"gray",children:o.userId})}),u(x,{width:Yt,children:u(C,{color:"gray",children:o.stockId})}),u(x,{width:t,children:u(C,{bold:!0,children:o.stockName})}),u(x,{width:Zt,children:u(C,{color:"gray",children:e})})]})}function ze({stocks:o}){let t=process.stdout.columns||80,e=4,r=Vt+Kt+Yt+Zt,n=Math.max(t-e-r,20),s=r+n;return Y(x,{flexDirection:"column",marginTop:1,borderStyle:"round",borderColor:"gray",paddingX:1,children:[Y(x,{flexDirection:"row",children:[u(C,{bold:!0,color:"cyan",children:"\u4ED3\u5E93\u5217\u8868"}),Y(C,{color:"gray",children:[" \xB7 ",o.length," \u4E2A"]})]}),Y(x,{flexDirection:"column",marginTop:1,children:[u(Me,{fillWidth:n}),u(C,{color:"gray",children:"\u2500".repeat(s)}),o.map(i=>u(Fe,{stock:i,fillWidth:n},i.id))]})]})}var Vt,Kt,Yt,Zt,Jo=it(()=>{"use strict";Vt=6,Kt=10,Yt=10,Zt=22});import{Command as br}from"commander";import tt from"chalk";import"commander";import{Command as To}from"commander";import w from"chalk";var M=class o extends Error{constructor(e,r,n){super(e);this.code=r;this.details=n;this.name="R2Error",Error.captureStackTrace&&Error.captureStackTrace(this,o)}code;details},P=class extends M{constructor(e,r,n){super(e,"API_ERROR",n);this.status=r;this.response=n;this.name="ApiError"}status;response},$=class extends M{constructor(e,r,n){super(e,"STORAGE_ERROR",{path:r,code:n});this.path=r;this.code=n;this.name="StorageError"}path;code},I=class extends M{constructor(t){super(t,"AUTH_ERROR"),this.name="AuthError"}},U=class extends M{constructor(e,r,n){super(e,"POLLING_ERROR",{attempts:r,timeout:n});this.attempts=r;this.timeout=n;this.name="PollingError"}attempts;timeout};async function le(o,t,e){let r=new AbortController,n=()=>r.abort();e?.addEventListener("abort",n,{once:!0});let s=setTimeout(()=>r.abort(),t);try{return await o()}catch(i){throw r.signal.aborted&&!e?.aborted?new U("\u5355\u6B21\u8F6E\u8BE2\u8BF7\u6C42\u8D85\u65F6"):i}finally{clearTimeout(s),e?.removeEventListener("abort",n)}}async function F(o,t,e){let{interval:r,timeout:n,condition:s}=t,i=Date.now(),a=0;for(;Date.now()-i<n;){if(e?.aborted)throw new U("\u8F6E\u8BE2\u88AB\u4E2D\u6B62");a++;let l=n-(Date.now()-i),y=await le(o,l,e);if(s(y,a))return y;await de(r,e)}throw new U(`\u8F6E\u8BE2\u8D85\u65F6 (\u5DF2\u7B49\u5F85 ${Date.now()-i}ms, \u5171 ${a} \u6B21)`)}function de(o,t){return new Promise((e,r)=>{if(t?.aborted){r(new U("\u8F6E\u8BE2\u88AB\u4E2D\u6B62"));return}let n=()=>{clearTimeout(s),r(new U("\u8F6E\u8BE2\u88AB\u4E2D\u6B62"))},s=setTimeout(()=>{t?.removeEventListener("abort",n),e()},o);t?.addEventListener("abort",n,{once:!0})})}import ge from"node:fs";import{fileURLToPath as pe}from"node:url";import{createRequire as fe}from"node:module";import co from"node:path";import{exec as he}from"node:child_process";import ue from"node:http";var kt=class o{server=null;pages=new Map;port=0;idleTimer=null;static IDLE_TIMEOUT_MS=1e4;async start(){return this.server?this.port:new Promise((t,e)=>{this.server=ue.createServer((r,n)=>this.handleRequest(r,n)),this.server.listen(0,"127.0.0.1",()=>{let r=this.server.address();typeof r=="object"&&r?(this.port=r.port,t(this.port)):e(new Error("Failed to get server address"))}),this.server.on("error",e)})}registerPage(t,e,r,n){let s=this.pages.get(t);if(s){s.qrBuffer=r,s.status="waiting",s.config=n;let i=`data: ${JSON.stringify({status:"waiting"})}
5
+
6
+ `;for(let a of s.sseClients)a.write(i)}else this.pages.set(t,{html:e,qrBuffer:r,status:"waiting",sseClients:[],config:n});this.resetIdleTimer()}unregisterPage(t){let e=this.pages.get(t);if(e){for(let r of e.sseClients)r.end();e.sseClients.length=0,this.pages.delete(t),this.pages.size===0&&this.close()}}setStatus(t,e){let r=this.pages.get(t);if(!r)return;r.status=e;let n=`data: ${JSON.stringify({status:e})}
7
+
8
+ `;for(let s of r.sseClients)s.write(n)}close(){if(this.server){this.idleTimer&&(clearTimeout(this.idleTimer),this.idleTimer=null);for(let t of this.pages.values()){for(let e of t.sseClients)e.end();t.sseClients.length=0}this.pages.clear(),this.server.close(),this.server=null,this.port=0,z=null}}resetIdleTimer(){this.idleTimer&&clearTimeout(this.idleTimer),this.idleTimer=setTimeout(()=>{[...this.pages.values()].some(e=>e.sseClients.length>0)||this.close()},o.IDLE_TIMEOUT_MS)}handleRequest(t,e){let r=t.url??"/";for(let[n,s]of this.pages){if(r===n){e.writeHead(302,{Location:n+"/"}),e.end();return}if(r===n+"/"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(s.html);return}if(r===n+"/qr.png"){e.writeHead(200,{"Content-Type":"image/png","Content-Length":s.qrBuffer.length}),e.end(s.qrBuffer);return}if(r===n+"/events"){e.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}),e.write(`data: ${JSON.stringify({status:s.status})}
9
+
10
+ `),s.sseClients.push(e),t.on("close",()=>{let i=s.sseClients.indexOf(e);i>=0&&s.sseClients.splice(i,1)});return}if(r===n+"/config"){e.writeHead(200,{"Content-Type":"application/json"}),e.end(JSON.stringify(s.config??{}));return}}e.writeHead(404,{"Content-Type":"text/plain"}),e.end("Not Found")}},z=null,io=!1;function ct(){z&&z.close()}function me(){io||(io=!0,process.on("exit",ct),process.on("SIGINT",ct),process.on("SIGTERM",ct),setInterval(()=>{process.stdin?.destroyed&&ct()},3e3).unref())}function ao(){return z||(z=new kt,me()),z}var ye=co.dirname(pe(import.meta.url)),we="/login",xe="/login-xianyu",vt=null;async function Ie(o){return ge.promises.readFile(co.join(ye,"pages",o),"utf-8")}async function Se(o){return vt||(vt=fe(import.meta.url)),vt("qrcode").toBuffer(o,{width:300,margin:2})}function B(o){let t=process.platform==="win32"?`start "" "${o}"`:process.platform==="darwin"?`open "${o}"`:`xdg-open "${o}"`;he(t)}async function lo(o,t,e,r){let[n,s]=await Promise.all([Ie(t),Se(e)]),i=ao(),a=await i.start();i.registerPage(o,n,s,r);let l=`http://127.0.0.1:${a}${o}/`;return{url:e,qrUrl:l,setStatus:y=>i.setStatus(o,y),closeServer:()=>i.unregisterPage(o)}}function Nt(o){return lo(we,"login.html",o)}function Rt(o,t){return lo(xe,"xianyu-auth.html",o,{authUrl:t})}import{promises as W}from"node:fs";import Lt from"node:path";import Ce from"node:os";var Te=".r2-cli",lt=class{configPath;config;configLoaded=!1;dirEnsured=!1;constructor(){let t=Ce.homedir(),e=Lt.join(t,Te);this.configPath=Lt.join(e,"config.json"),this.config={credentials:null}}getConfigPath(){return this.configPath}async loadConfig(){if(this.configLoaded)return this.config;try{let t=await W.readFile(this.configPath,"utf-8");return this.config=JSON.parse(t),this.configLoaded=!0,this.config}catch{return this.config={credentials:null},this.configLoaded=!0,this.config}}async ensureDir(){if(this.dirEnsured)return;let t=Lt.dirname(this.configPath);try{await W.stat(t)}catch(e){if(e.code==="ENOENT")await W.mkdir(t,{recursive:!0});else throw new $("Failed to create directory",t,e.code)}this.dirEnsured=!0}async saveConfig(t){this.config=t,await this.ensureDir();let e=JSON.stringify(t,null,2),r=this.configPath+".tmp";try{await W.writeFile(r,e,"utf-8"),await W.rename(r,this.configPath),this.configLoaded=!0}catch(n){throw await W.unlink(r).catch(s=>{typeof process.env.DEBUG<"u"&&console.error("[config] cleanup tmp failed:",s)}),new $("Failed to save config",this.configPath,n.code)}}},Ot=null;function Dt(){return Ot||(Ot=new lt),Ot}var Et=300*1e3,dt=class{store=Dt();isTokenExpired(t){return t.expire?Date.now()>=t.expire-Et:!1}async saveCredentials(t,e){let r=Date.now(),n=e.expire?Number.parseInt(e.expire,10):0,s={token:t,userInfo:e,timestamp:r,...n>0&&{expire:r+n}},i=await this.store.loadConfig();i.credentials=s,await this.store.saveConfig(i)}async getCredentials(){let t=await this.store.loadConfig();return!t.credentials||this.isTokenExpired(t.credentials)?null:t.credentials}async clearCredentials(){let t=await this.store.loadConfig();t.credentials=null,await this.store.saveConfig(t)}async getToken(){return(await this.getCredentials())?.token??null}async getUserInfo(){return(await this.getCredentials())?.userInfo??null}async isLoggedIn(){return await this.getCredentials()!==null}},Ut=null;function ot(){return Ut||(Ut=new dt),Ut}var be="https://api.puresnake.com",ut=class{config;authStorage=null;cachedToken=null;tokenExpiry=0;constructor(t={}){this.config={baseUrl:t.baseUrl??be,version:t.version??"v3",debug:t.debug??!1},this.authStorage=t.auth===!1?null:ot()}buildUrl(t){let e=t.startsWith("/")?t.slice(1):t;return`${this.config.baseUrl}/${this.config.version}/${e}`}async getAuthToken(){if(!this.authStorage)return;if(this.cachedToken&&Date.now()<this.tokenExpiry)return this.cachedToken;let t=await this.authStorage.getCredentials();if(!t)throw new I("\u8BF7\u5148\u8FD0\u884C r2-cli auth login \u767B\u5F55");return this.cachedToken=t.token,this.tokenExpiry=t.expire?t.expire-Et:Date.now()+1800*1e3,t.token}async requestFull(t,e){let r=this.buildUrl(t),{method:n,headers:s,body:i,timeout:a=3e4}=e,l=await this.getAuthToken(),y={...s,...l?{token:l}:{}},m=new AbortController,b=setTimeout(()=>m.abort(),a),_={method:n,headers:{"Content-Type":"application/json",...y},signal:m.signal};i!==void 0&&(_.body=JSON.stringify(i)),this.config.debug&&console.error(`[API ${n}]`,r,i);try{let d=await fetch(r,_);if(!d.ok){if(d.status===401)throw this.authStorage&&(this.cachedToken=null,await this.authStorage.clearCredentials().catch(Q=>{console.error("[API] \u6E05\u9664\u51ED\u8BC1\u5931\u8D25:",Q instanceof Error?Q.message:String(Q))})),new I("\u767B\u5F55\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u8FD0\u884C r2-cli auth login \u91CD\u65B0\u767B\u5F55");let Pt=await d.text();throw new P(Pt||`${d.status} ${d.statusText}`,d.status)}let k=await d.json();if(this.config.debug&&console.error("[API Response]",k),!k.success||k.status!==0)throw new P(k.msg||"\u672A\u77E5\u9519\u8BEF",k.status,k);return k}catch(d){throw d instanceof DOMException&&d.name==="AbortError"?new P(`\u8BF7\u6C42\u8D85\u65F6 (${a}ms)`,408):d}finally{clearTimeout(b)}}async request(t,e){return(await this.requestFull(t,e)).data}async get(t,e,r){let n=e&&e.size>0?`${t}?${e.toString()}`:t;return this.request(n,{method:"GET",headers:r})}async post(t,e,r){return this.request(t,{method:"POST",body:e,headers:r})}async put(t,e,r){return this.request(t,{method:"PUT",body:e,headers:r})}async delete(t,e){return this.request(t,{method:"DELETE",headers:e})}async upload(t,e,r){let n=this.buildUrl(t),s=await this.getAuthToken(),i={...r,...s?{token:s}:{}},a=new AbortController,l=setTimeout(()=>a.abort(),6e4),y={method:"POST",headers:i,body:e,signal:a.signal};this.config.debug&&console.error("[API UPLOAD]",n);try{let m=await fetch(n,y);if(!m.ok){if(m.status===401)throw this.authStorage&&(this.cachedToken=null,await this.authStorage.clearCredentials().catch(()=>{})),new I("\u767B\u5F55\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u8FD0\u884C r2-cli auth login \u91CD\u65B0\u767B\u5F55");let _=await m.text();throw new P(_||`${m.status} ${m.statusText}`,m.status)}let b=await m.json();if(this.config.debug&&console.error("[API Response]",b),!b.success||b.status!==0)throw new P(b.msg||"\u672A\u77E5\u9519\u8BEF",b.status,b);return b.data}catch(m){throw m instanceof DOMException&&m.name==="AbortError"?new P("\u4E0A\u4F20\u8D85\u65F6 (60000ms)",408):m}finally{clearTimeout(l)}}},mt=new ut,uo=new ut({auth:!1});var mo=uo;async function go(){return mo.post("app/qrcode/generate")}async function po(o){let t=new URLSearchParams;t.append("qrToken",o);let e=`app/qrcode/status?${t.toString()}`,r=await mo.requestFull(e,{method:"GET"});return r.token&&typeof r.data=="object"&&r.data!==null&&(r.data.token=r.token),r.data}async function wo(o,t,e){let{UserInfoCard:r}=await Promise.resolve().then(()=>(ho(),fo)),{renderComponent:n}=await Promise.resolve().then(()=>(et(),gt)),s=t!=null?{userInfo:o,lastLogin:t,daysSinceLogin:e??0}:{userInfo:o};n(r,s)}var pt=class{storage;constructor(t){this.storage=t??ot()}async generateQR(){let t=await go(),e=`https://m.puresnake.com/r2/auth/login?qrToken=${t.qrContent}&from=wechat`,r=await Nt(e);return{qrData:t,...r}}async waitForLogin(t,e,r,n,s,i){let a=await F(()=>po(t),{interval:r,timeout:e,condition:l=>{switch(l.status){case"scanned":return i||(console.log(w.cyan(`
11
+ \u{1F50D} \u5DF2\u626B\u7801: ${l.userInfo?.nickname||"\u672A\u77E5\u7528\u6237"}`)),console.log(w.yellow("\u8BF7\u5728 APP \u4E0A\u786E\u8BA4\u767B\u5F55"))),s?.("scanning"),!1;case"confirmed":return i||console.log(w.green(`
12
+ \u2705 \u7528\u6237\u5DF2\u786E\u8BA4\u767B\u5F55`)),s?.("success"),!0;case"expired":return i||console.log(w.red(`
13
+ \u23F0 \u4E8C\u7EF4\u7801\u5DF2\u8FC7\u671F`)),s?.("expired"),!0;case"canceled":return i||console.log(w.red(`
14
+ \u{1F6AB} \u7528\u6237\u5DF2\u53D6\u6D88\u767B\u5F55`)),s?.("expired"),!0;default:return!1}}},n??void 0);if(a.status==="confirmed"&&a.token&&a.userInfo)return await this.storage.saveCredentials(a.token,a.userInfo),{userInfo:a.userInfo,token:a.token};throw a.status==="expired"?new I("\u4E8C\u7EF4\u7801\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55"):a.status==="canceled"?new I("\u7528\u6237\u5DF2\u53D6\u6D88\u767B\u5F55"):new I("\u767B\u5F55\u5931\u8D25: \u672A\u83B7\u53D6\u5230\u51ED\u8BC1")}async login(t){console.log(w.cyan(`
15
+ \u{1F510} \u6B63\u5728\u542F\u52A8\u626B\u7801\u767B\u5F55...`));let{qrData:e,qrUrl:r,setStatus:n,closeServer:s}=await this.generateQR();console.log(w.green(`\u2705 \u4E8C\u7EF4\u7801\u5DF2\u751F\u6210
16
+ `)),console.log(w.cyan(` \u94FE\u63A5: ${r}
17
+ `)),B(r),console.log(w.yellow(`\u23F3 \u7B49\u5F85\u626B\u7801...
18
+ `));let i=Number.parseInt(e.expireTime,10),a=Number.parseInt(e.pollInterval,10);try{let l=await this.waitForLogin(e.qrToken,i,a,t,n);return console.log(w.green(`
19
+ \u2705 \u767B\u5F55\u6210\u529F\uFF01
20
+ `)),wo(l.userInfo),l}catch(l){throw console.log(w.red(`
21
+ \u274C \u767B\u5F55\u5931\u8D25
22
+ `)),l}finally{s()}}async logout(){console.log(w.cyan(`
23
+ \u{1F6AA} \u6B63\u5728\u9000\u51FA\u767B\u5F55...`)),await this.storage.clearCredentials(),console.log(w.green(`\u2705 \u5DF2\u9000\u51FA\u767B\u5F55
24
+ `))}async status(){if(!await this.storage.isLoggedIn()){console.log(w.yellow(`\u26A0\uFE0F \u5C1A\u672A\u767B\u5F55\u6216\u51ED\u8BC1\u5DF2\u8FC7\u671F
25
+ `));return}let e=await this.storage.getCredentials(),r=e.userInfo,n=new Date(e.timestamp),s=Math.floor((Date.now()-e.timestamp)/(1e3*60*60*24));console.log(w.green(`\u2705 \u5DF2\u767B\u5F55
26
+ `)),await wo(r,n,s)}},Bt=null;function R(){return Bt||(Bt=new pt),Bt}import J from"chalk";var xo=mt;async function Io(){return xo.get("mms/xianyu/auth/url")}async function So(o){let t=new URLSearchParams({state:o});return xo.get("mms/xianyu/auth/status",t)}async function ft(){let o=await Io(),t=await Rt(o.url,o.url);return{authData:o,...t}}async function rt(o,t,e,r,n){return F(()=>So(o),{interval:e,timeout:t,condition:s=>s.status==="success"?(console.log(J.green(`
27
+ \u2705 \u6388\u6743\u6210\u529F\uFF01\u5E97\u94FA: ${s.shopName} (${s.shopId})`)),n?.("success"),!0):s.status==="expired"?(console.log(J.red(`
28
+ \u23F0 \u6388\u6743\u94FE\u63A5\u5DF2\u8FC7\u671F`)),n?.("expired"),!0):!1},r)}async function Gt(o){console.log(J.cyan(`
29
+ \u{1F517} \u6B63\u5728\u83B7\u53D6\u95F2\u9C7C\u6388\u6743\u5730\u5740...`));let{authData:t,qrUrl:e,setStatus:r,closeServer:n}=await ft();console.log(J.green(`\u2705 \u6388\u6743\u4E8C\u7EF4\u7801\u5DF2\u751F\u6210
30
+ `)),console.log(J.cyan(` \u94FE\u63A5: ${e}`)),console.log(J.gray(` \u6216\u590D\u5236\u94FE\u63A5\u6253\u5F00: ${t.url}`)),B(e),console.log(J.yellow(`
31
+ \u23F3 \u7B49\u5F85\u6388\u6743...
32
+ `));let s=t.expireTime?Number.parseInt(t.expireTime,10):3e5,i=t.pollInterval?Number.parseInt(t.pollInterval,10):1e3;try{let a=await rt(t.state,s,i,o,r);if(a.status==="success")return a;throw new I("\u95F2\u9C7C\u6388\u6743\u5931\u8D25: "+(a.status==="expired"?"\u94FE\u63A5\u5DF2\u8FC7\u671F":"\u672A\u77E5\u72B6\u6001"))}finally{n()}}import E from"chalk";function v(o){if(o instanceof I)console.error(E.red(`
33
+ \u25B2 ${o.message}`)),console.error(E.gray(`\u2192 \u8BF7\u5148\u8FD0\u884C: r2-cli auth login
34
+ `));else if(o instanceof P)console.error(E.red(`\u25B2 \u64CD\u4F5C\u5931\u8D25: ${o.message}`)),o.status&&console.error(E.gray(` \u72B6\u6001\u7801: ${o.status}`));else if(o instanceof $)console.error(E.red(`\u25B2 \u914D\u7F6E\u6587\u4EF6\u5F02\u5E38: ${o.message}`)),o.path&&console.error(E.gray(` \u8DEF\u5F84: ${o.path}`)),console.error(E.gray(`\u2192 \u8BF7\u5C1D\u8BD5\u91CD\u65B0\u767B\u5F55: r2-cli auth login
35
+ `));else{let t=o instanceof Error?o.message:String(o);console.error(E.red(`\u25B2 ${t}`))}process.exit(1)}function qt(o){console.log(JSON.stringify({success:!1,error:o})),process.exit(1)}function p(o){return async t=>{try{await o(t)}catch(e){if(t.json){let r=e instanceof Error?e.message:String(e),n=e instanceof P?e.status:void 0;console.log(JSON.stringify({success:!1,error:r,...n!=null&&{status:n}})),process.exit(1)}v(e)}}}function ht(o){return async(...t)=>{try{await o(...t)}catch(e){let r=e instanceof Error?e.message:String(e);qt(r)}}}var Le=new Set(["accessToken","refreshExpireIn"]);function Co(o){return o.map(t=>{let e={};for(let[r,n]of Object.entries(t))Le.has(r)||(e[r]=n);return e})}async function yt(o){let{qrInfo:t,qrUrl:e,setStatus:r,closeServer:n,waitArgs:s}=await o.generate();console.log(JSON.stringify(t,null,2)),B(e);try{let i=await o.waitResult(s,r);console.log(JSON.stringify(o.formatSuccess(i)))}catch(i){let a=i instanceof Error?i.message:String(i);console.log(JSON.stringify({success:!1,error:a})),process.exit(1)}finally{setTimeout(n,1e3)}}function Jt(){let o=new To("login");o.description("\u626B\u7801\u767B\u5F55 Round2AI \u8D26\u6237").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09");let t=new To("poll").description("\u8F6E\u8BE2\u767B\u5F55\u72B6\u6001\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09").requiredOption("--token <qrToken>","\u4E8C\u7EF4\u7801 token").option("--expire <ms>","\u8FC7\u671F\u65F6\u95F4\uFF08\u6BEB\u79D2\uFF09","300000").option("--interval <ms>","\u8F6E\u8BE2\u95F4\u9694\uFF08\u6BEB\u79D2\uFF09","1000").action(ht(async e=>{let n=await R().waitForLogin(e.token,Number.parseInt(e.expire,10),Number.parseInt(e.interval,10));console.log(JSON.stringify({success:!0,...n}))}));return o.addCommand(t),o.action(async e=>{try{e.json?await yt({generate:async()=>{let r=R(),{qrData:n,qrUrl:s,setStatus:i,closeServer:a}=await r.generateQR(),l=Number.parseInt(n.expireTime,10),y=Number.parseInt(n.pollInterval,10);return{qrInfo:{qrToken:n.qrToken,expireTimeMs:l,pollIntervalMs:y,url:`https://m.puresnake.com/r2/auth/login?qrToken=${n.qrContent}&from=wechat`,qrUrl:s},qrUrl:s,setStatus:i,closeServer:a,waitArgs:{qrToken:n.qrToken,expireMs:l,intervalMs:y}}},waitResult:({qrToken:r,expireMs:n,intervalMs:s},i)=>R().waitForLogin(r,n,s,void 0,i,!0),formatSuccess:r=>({success:!0,userInfo:r.userInfo})}):await R().login()}catch(r){if(e.json){let n=r instanceof Error?r.message:String(r);console.log(JSON.stringify({success:!1,error:n})),process.exit(1)}v(r)}}),o}import{Command as Oe}from"commander";function Xt(){let o=new Oe("logout");return o.description("\u9000\u51FA\u767B\u5F55"),o.action(async()=>{try{await R().logout()}catch(t){v(t)}}),o}import{Command as De}from"commander";function _t(){let o=new De("status");return o.description("\u67E5\u770B\u767B\u5F55\u72B6\u6001"),o.action(async()=>{try{await R().status()}catch(t){v(t)}}),o}import{Command as bo}from"commander";function Qt(){let o=new bo("xianyu");o.description("\u95F2\u9C7C\u5E97\u94FA\u6388\u6743").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09");let t=new bo("poll").description("\u8F6E\u8BE2\u95F2\u9C7C\u6388\u6743\u72B6\u6001\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09").requiredOption("--state <state>","\u6388\u6743\u8F6E\u8BE2 token").option("--expire <ms>","\u8FC7\u671F\u65F6\u95F4\uFF08\u6BEB\u79D2\uFF09","300000").option("--interval <ms>","\u8F6E\u8BE2\u95F4\u9694\uFF08\u6BEB\u79D2\uFF09","1000").action(ht(async e=>{let r=await rt(e.state,Number.parseInt(e.expire,10),Number.parseInt(e.interval,10));r.status==="success"?console.log(JSON.stringify({success:!0,shopId:r.shopId,shopName:r.shopName})):qt(`\u6388\u6743\u72B6\u6001: ${r.status}`)}));return o.addCommand(t),o.action(async e=>{try{e.json?await yt({generate:async()=>{let{authData:r,qrUrl:n,setStatus:s,closeServer:i}=await ft(),a=r.expireTime?Number.parseInt(r.expireTime,10):3e5,l=r.pollInterval?Number.parseInt(r.pollInterval,10):1e3;return{qrInfo:{state:r.state,expireTimeMs:a,pollIntervalMs:l,qrUrl:n},qrUrl:n,setStatus:s,closeServer:i,waitArgs:{state:r.state,expireMs:a,intervalMs:l}}},waitResult:async({state:r,expireMs:n,intervalMs:s},i)=>{let a=await rt(r,n,s,void 0,i);if(a.status!=="success")throw new Error(`\u6388\u6743\u72B6\u6001: ${a.status}`);return a},formatSuccess:r=>({success:!0,shopId:r.shopId,shopName:r.shopName})}):await Gt()}catch(r){if(e.json){let n=r instanceof Error?r.message:String(r);console.log(JSON.stringify({success:!1,error:n})),process.exit(1)}v(r)}}),o}import{Command as ir}from"commander";import{Command as Ue}from"commander";import L from"chalk";import{select as Ft,input as Ee,confirm as je}from"@inquirer/prompts";function X(o){let t=new URLSearchParams;for(let[e,r]of Object.entries(o))r!=null&&r!==""&&t.append(e,String(r));return t}var A=mt;async function Mt(o){return A.post("mms/goods/listing/up/xianyu",o)}async function Po(o){return A.get("mms/goods/listing/get",X({...o}))}async function Ao(o){return A.post("mms/goods/listing/down/xianyu",o)}async function ko(o){return A.post("mms/goods/listing/update/xyPrice",o)}async function vo(o){return A.get("mms/goods/listing/list",o?X({...o}):void 0)}async function wt(){return await A.get("mms/user/shop/list")??[]}async function xt(){return await A.get("mms/user/stock/list")??[]}async function It(o){let t=o?X({...o}):void 0;return A.get("mms/seller/goods/select/list",t)}async function No(o){return A.post("mms/goods/listing/hang/up/xianyu",o)}async function Ro(o=16){return await A.get("platform/xy/cat",X({spBizType:o}))??[]}async function Lo(o){return await A.get("platform/xy/props",X({channelCatId:o}))??[]}async function Oo(o,t,e){return await A.get("platform/xy/props/value",X({channelCatId:o,propId:t,key:e}))??[]}var $e=2e3,Be=1e4;function Ge(o){let t=o.status?.toLowerCase()??"";return t===""||t==="init"||t==="pending"||t==="processing"}async function Do(o,t,e,r){r||process.stdout.write(L.cyan("\u23F3 \u6B63\u5728\u67E5\u8BE2\u4E0A\u67B6\u8FDB\u5EA6..."));let n=await F(()=>Po({stockGoodsId:o,shopId:t,platform:e}),{interval:$e,timeout:Be,condition:s=>!Ge(s)});return r||process.stdout.write("\r"+" ".repeat(30)+"\r"),n}function Uo(){let o=new Ue("up");return o.description("\u4E0A\u67B6\u5546\u54C1\u5230\u95F2\u9C7C"),o.option("--stock-goods-id <id>","\u5E93\u5B58\u5546\u54C1ID\uFF08\u4ECE goods list \u83B7\u53D6\uFF09").option("--shop-id <id>","\u5E97\u94FAID\uFF08\u4ECE goods shops \u83B7\u53D6\uFF09").option("--price <amount>","\u4E0A\u67B6\u4EF7\u683C").option("-p, --platform <platform>","\u5E73\u53F0","xianyu").option("--json","\u8F93\u51FA JSON\uFF08Agent \u7528\uFF09").action(p(async t=>{if(t.json&&!(t.stockGoodsId&&t.shopId&&t.price)&&(console.log(JSON.stringify({success:!1,error:"Agent \u6A21\u5F0F\u9700\u8981 --stock-goods-id, --shop-id, --price"})),process.exit(1)),t.stockGoodsId&&t.shopId&&t.price){let d=Number(t.stockGoodsId),k=t.shopId,Pt=Number(t.price),Q=t.platform,ie=await Mt({stockGoodsId:d,shopId:k,price:Pt,platform:Q}),At=await Do(d,k,Q,t.json);if(t.json)console.log(JSON.stringify({success:!0,data:{submit:ie,listing:At}},null,2));else{let ae=At.status?.toLowerCase()!=="failed";console.log(ae?L.green("\u2713 \u4E0A\u67B6\u6210\u529F"):L.red("\u2717 \u4E0A\u67B6\u5931\u8D25")),console.log(JSON.stringify(At,null,2))}return}let e=await wt();if(e.length===0){console.log(L.yellow("\u6CA1\u6709\u5DF2\u6388\u6743\u5E97\u94FA\uFF0C\u8BF7\u5148\u8FD0\u884C r2-cli auth xianyu \u6388\u6743"));return}let r=await Ft({message:"\u9009\u62E9\u5E97\u94FA",choices:e.map(d=>({name:`${d.shopName} (${d.platform})`,value:d.shopId}))}),n=await xt();if(n.length===0){console.log(L.yellow("\u6CA1\u6709\u53EF\u7528\u7684\u4ED3\u5E93"));return}let s=await Ft({message:"\u9009\u62E9\u4ED3\u5E93",choices:n.map(d=>({name:d.stockName,value:d.stockId}))}),i=await It({stockId:s,size:100});if(!i.items?.length){console.log(L.yellow("\u8BE5\u4ED3\u5E93\u6CA1\u6709\u53EF\u9009\u7684\u5546\u54C1"));return}let a=await Ft({message:"\u9009\u62E9\u5546\u54C1",choices:i.items.map(d=>({name:`${d.goodsName} ${d.size?`| ${d.size}`:""} | \xA5${d.salePrice}`,value:d.stockGoodsId}))}),l=await Ee({message:"\u8F93\u5165\u4E0A\u67B6\u4EF7\u683C",default:i.items.find(d=>d.stockGoodsId===a)?.salePrice?.toString()??"",validate:d=>Number(d)>0?!0:"\u4EF7\u683C\u5FC5\u987B\u4E3A\u6B63\u6570"});if(!await je({message:`\u786E\u8BA4\u4E0A\u67B6\uFF1F\u4EF7\u683C \xA5${l}`,default:!0})){console.log(L.gray("\u5DF2\u53D6\u6D88"));return}let m=Number(a);await Mt({stockGoodsId:m,shopId:r,price:Number(l),platform:"xianyu"}),console.log(L.green("\u2713 \u4E0A\u67B6\u5DF2\u63D0\u4EA4\uFF0C\u6B63\u5728\u67E5\u8BE2\u8FDB\u5EA6..."));let b=await Do(m,r,"xianyu"),_=b.status?.toLowerCase()!=="failed";console.log(_?L.green("\u2713 \u4E0A\u67B6\u6210\u529F"):L.red("\u2717 \u4E0A\u67B6\u5931\u8D25")),console.log(JSON.stringify(b,null,2))})),o}import{Command as Qe}from"commander";import Bo from"chalk";function Go(){let o=new Qe("shops");return o.description("\u67E5\u770B\u6240\u6709\u5DF2\u6388\u6743\u5E97\u94FA\uFF08\u8DE8\u5E73\u53F0\uFF09"),o.option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09"),o.action(p(async t=>{let e=await wt();if(t.json){console.log(JSON.stringify(Co(e),null,2));return}if(!e.length){console.log(Bo.yellow("\u672A\u627E\u5230\u5DF2\u6388\u6743\u7684\u5E97\u94FA")),console.log(Bo.gray(" \u63D0\u793A: \u8BF7\u5148\u5728\u7B2C\u4E8C\u56DE\u5408 APP \u4E2D\u6388\u6743\u5E97\u94FA"));return}let{ShopsTable:r}=await Promise.resolve().then(()=>($o(),jo)),{renderComponent:n}=await Promise.resolve().then(()=>(et(),gt));n(r,{shops:e,platform:"all"})})),o}import{Command as We}from"commander";import He from"chalk";function Xo(){let o=new We("stocks");return o.description("\u67E5\u770B\u6240\u6709\u4ED3\u5E93"),o.option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09"),o.action(p(async t=>{let e=await xt();if(t.json){console.log(JSON.stringify(e,null,2));return}if(!e.length){console.log(He.yellow("\u672A\u627E\u5230\u4ED3\u5E93\u4FE1\u606F"));return}let{StocksTable:r}=await Promise.resolve().then(()=>(Jo(),qo)),{renderComponent:n}=await Promise.resolve().then(()=>(et(),gt));n(r,{stocks:e})})),o}import{Command as Ve}from"commander";import Z from"chalk";function _o(){let o=new Ve("list");return o.description("\u67E5\u770B\u4ED3\u5E93\u4E2D\u7684\u9009\u54C1\u5546\u54C1"),o.option("--stock-id <id>","\u4ED3\u5E93 ID\uFF08\u4ECE goods stocks \u83B7\u53D6\uFF09").option("--stock-goods-id <id>","\u5E93\u5B58\u5546\u54C1 ID").option("--page <n>","\u9875\u7801","1").option("--size <n>","\u6BCF\u9875\u6570\u91CF\uFF08\u6700\u5927 50\uFF09","20").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09"),o.action(p(async t=>{let r=await It({stockId:t.stockId||void 0,stockGoodsId:t.stockGoodsId||void 0,page:Number(t.page)||1,size:Math.min(Number(t.size)||20,50)})??{items:[],total:0};if(t.json){r.items?.length?console.log(JSON.stringify(r,null,2)):console.log(JSON.stringify({...r,hint:"\u9009\u54C1\u5546\u54C1\u4E3A\u7A7A\uFF0C\u8BF7\u5148\u5728\u540E\u53F0\u751F\u6210\u9009\u54C1\u8868\u6570\u636E\u540E\u518D\u8BD5"},null,2));return}if(!r.items?.length){console.log(Z.yellow("\u6682\u65E0\u9009\u54C1\u5546\u54C1\uFF0C\u8BF7\u5148\u7ED1\u5B9A\u4ED3\u5E93\u6216\u5728\u540E\u53F0\u751F\u6210\u9009\u54C1\u8868\u6570\u636E"));return}console.log(Z.cyan(`
36
+ \u9009\u54C1\u5546\u54C1\uFF08\u5171 ${r.total} \u4EF6\uFF0C\u7B2C ${r.page} \u9875\uFF09
37
+ `));for(let n of r.items)console.log(` ${Z.bold(n.goodsName)} ${n.size?Z.gray(`| ${n.size}`):""}`),console.log(` \u54C1\u724C: ${n.brand} \u5EFA\u8BAE\u552E\u4EF7: \xA5${n.salePrice} stockGoodsId: ${Z.green(n.stockGoodsId)}`),console.log(Z.gray(` \u5206\u7C7B: ${n.cate1Name} > ${n.cate2Name} > ${n.cate3Name}`)),console.log()})),o}import{Command as or}from"commander";import er from"chalk";et();import{Box as g,Text as h}from"ink";import{jsx as c,jsxs as j}from"react/jsx-runtime";var Ke={init:{label:"\u5F85\u4E0A\u67B6",color:"yellow"},up:{label:"\u5DF2\u4E0A\u67B6",color:"green"},down:{label:"\u5DF2\u4E0B\u67B6",color:"gray"},fail:{label:"\u5931\u8D25",color:"red"},sold:{label:"\u5DF2\u552E\u51FA",color:"blue"}},to=4,oo=8,St=12,eo=10,ro=6,no=8;function Qo(o,t){return o.length>t?o.slice(0,t-1)+"\u2026":o}function Mo(o){if(!o)return"-";let t=new Date(o),e=r=>String(r).padStart(2,"0");return`${e(t.getMonth()+1)}/${e(t.getDate())} ${e(t.getHours())}:${e(t.getMinutes())}`}function Ye({fillWidth:o}){return j(g,{flexDirection:"row",children:[c(g,{width:to,children:c(h,{bold:!0,color:"white",children:"ID"})}),c(g,{width:oo,children:c(h,{bold:!0,color:"white",children:"\u72B6\u6001"})}),c(g,{width:St,children:c(h,{bold:!0,color:"white",children:"\u54C1\u724C"})}),c(g,{width:o,children:c(h,{bold:!0,color:"white",children:"\u5546\u54C1\u540D\u79F0"})}),c(g,{width:eo,children:c(h,{bold:!0,color:"white",children:"\u4EF7\u683C"})}),c(g,{width:ro,children:c(h,{bold:!0,color:"white",children:"\u89C4\u683C"})}),c(g,{width:no,children:c(h,{bold:!0,color:"white",children:"\u5E93\u5B58ID"})})]})}function Ze({item:o}){return c(g,{flexDirection:"column",children:c(h,{color:"gray",children:` shopId: ${o.shopId} thirdItemNo: ${o.thirdItemNo||"-"} outItemNo: ${o.outItemNo||"-"} \u8D27\u53F7: ${o.goodsNo||"-"} ${o.type||"-"} ${o.platform} \u521B\u5EFA: ${Mo(o.gmtCreate)} \u4FEE\u6539: ${Mo(o.gmtModified)}`})})}function tr({item:o,fillWidth:t}){let e=Ke[o.status]??{label:o.status,color:"white"};return j(g,{flexDirection:"column",children:[j(g,{flexDirection:"row",children:[c(g,{width:to,children:c(h,{color:"gray",children:o.id})}),c(g,{width:oo,children:c(h,{color:e.color,children:e.label})}),c(g,{width:St,children:c(h,{color:"cyan",children:Qo(o.brandName||"-",St-1)})}),c(g,{width:t,children:c(h,{children:Qo(o.goodsName,t-1)})}),c(g,{width:eo,children:j(h,{color:"yellow",children:["\xA5",o.price]})}),c(g,{width:ro,children:c(h,{color:"gray",children:o.spec||"-"})}),c(g,{width:no,children:c(h,{color:"gray",children:o.stockGoodsId})})]}),c(Ze,{item:o})]})}function Fo({items:o,total:t}){let e=process.stdout.columns||80,r=4,n=to+oo+St+eo+ro+no,s=Math.max(e-r-n,20),i=n+s;return j(g,{flexDirection:"column",marginTop:1,borderStyle:"round",borderColor:"gray",paddingX:1,children:[j(g,{flexDirection:"row",children:[c(h,{bold:!0,color:"cyan",children:"\u4E0A\u67B6\u5217\u8868"}),j(h,{color:"gray",children:[" \xB7 \u5171 ",t," \u6761"]})]}),j(g,{flexDirection:"column",marginTop:1,children:[c(Ye,{fillWidth:s}),c(h,{color:"gray",children:"\u2500".repeat(i)}),o.map(a=>c(tr,{item:a,fillWidth:s},a.id))]})]})}function zo(){let o=new or("listing");return o.description("\u67E5\u8BE2\u4E0A\u67B6\u5546\u54C1\u5217\u8868"),o.option("--id <id>","\u4E0A\u67B6\u8BB0\u5F55 ID").option("--stock-goods-id <id>","\u5E93\u5B58\u5546\u54C1 ID").option("--shop-id <id>","\u5E97\u94FA ID").option("--stock-id <id>","\u4ED3\u5E93 ID").option("-s, --status <status>","\u72B6\u6001\u8FC7\u6EE4\uFF08init/up/down/fail/sold\uFF09").option("-p, --platform <platform>","\u5E73\u53F0","xianyu").option("--page <n>","\u9875\u7801","1").option("--size <n>","\u6BCF\u9875\u6570\u91CF\uFF08\u6700\u5927 50\uFF09","20").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09"),o.action(p(async t=>{let r=await vo({id:t.id,stockGoodsId:t.stockGoodsId?Number(t.stockGoodsId):void 0,shopId:t.shopId,stockId:t.stockId,status:t.status,platform:t.platform,page:Number(t.page)||1,size:Math.min(Number(t.size)||20,50)})??{items:[],total:0};if(t.json){r.items?.length?console.log(JSON.stringify(r,null,2)):console.log(JSON.stringify({...r,hint:"\u6682\u65E0\u4E0A\u67B6\u8BB0\u5F55"},null,2));return}if(!r.items?.length){console.log(er.yellow("\u6682\u65E0\u4E0A\u67B6\u8BB0\u5F55"));return}$t(Fo,{items:r.items,total:r.total})})),o}import{Command as rr}from"commander";import so from"chalk";function Wo(){let o=new rr("down");return o.description("\u4E0B\u67B6\u95F2\u9C7C\u5546\u54C1"),o.option("--id <id>","\u4E0A\u67B6\u8BB0\u5F55 ID").option("--stock-goods-id <id>","\u5E93\u5B58\u5546\u54C1 ID").option("--shop-id <id>","\u5E97\u94FA ID").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09"),o.action(p(async t=>{if(!t.id&&!(t.stockGoodsId&&t.shopId)){t.json&&(console.log(JSON.stringify({success:!1,error:"\u8BF7\u6307\u5B9A\u4E0B\u67B6\u6761\u4EF6\uFF1A--id <id> \u6216 --stock-goods-id <id> --shop-id <id>"})),process.exit(1)),console.log(so.yellow("\u8BF7\u6307\u5B9A\u4E0B\u67B6\u6761\u4EF6\uFF1A--id <id> \u6216 --stock-goods-id <id> --shop-id <id>"));return}let e={};t.id&&(e.id=t.id),t.stockGoodsId&&(e.stockGoodsId=Number(t.stockGoodsId)),t.shopId&&(e.shopId=t.shopId),t.json||console.log(so.cyan("\u{1F4E6} \u6B63\u5728\u4E0B\u67B6\u5546\u54C1..."));let r=await Ao(e);t.json?console.log(JSON.stringify({success:!0,data:r},null,2)):(console.log(so.green("\u2705 \u4E0B\u67B6\u6210\u529F")),console.log(JSON.stringify(r,null,2)))})),o}import{Command as nr}from"commander";import Ct from"chalk";function Ho(){let o=new nr("price");return o.description("\u4FEE\u6539\u95F2\u9C7C\u4E0A\u67B6\u5546\u54C1\u4EF7\u683C"),o.option("--id <id>","\u4E0A\u67B6\u8BB0\u5F55 ID").option("--stock-goods-id <id>","\u5E93\u5B58\u5546\u54C1 ID").option("--shop-id <id>","\u5E97\u94FA ID").option("--price <amount>","\u65B0\u4EF7\u683C\uFF08\u5FC5\u586B\uFF09").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09"),o.action(p(async t=>{if(!t.price){t.json&&(console.log(JSON.stringify({success:!1,error:"--price <amount> \u4E3A\u5FC5\u586B\u53C2\u6570"})),process.exit(1)),console.log(Ct.yellow("--price <amount> \u4E3A\u5FC5\u586B\u53C2\u6570"));return}if(!t.id&&!(t.stockGoodsId&&t.shopId)){t.json&&(console.log(JSON.stringify({success:!1,error:"\u8BF7\u6307\u5B9A\u5546\u54C1\uFF1A--id <id> \u6216 --stock-goods-id <id> --shop-id <id>"})),process.exit(1)),console.log(Ct.yellow("\u8BF7\u6307\u5B9A\u5546\u54C1\uFF1A--id <id> \u6216 --stock-goods-id <id> --shop-id <id>"));return}let e={price:Number(t.price)};t.id&&(e.id=t.id),t.stockGoodsId&&(e.stockGoodsId=Number(t.stockGoodsId)),t.shopId&&(e.shopId=t.shopId),t.json||console.log(Ct.cyan(`\u{1F4B0} \u6B63\u5728\u4FEE\u6539\u4EF7\u683C\u4E3A ${t.price}...`));let r=await ko(e);t.json?console.log(JSON.stringify({success:!0,data:r},null,2)):(console.log(Ct.green("\u2705 \u4EF7\u683C\u4FEE\u6539\u6210\u529F")),console.log(JSON.stringify(r,null,2)))})),o}import{Command as Fs}from"commander";import Ws from"chalk";import{Command as nt}from"commander";import T from"chalk";var sr={100:"\u5168\u65B0",[-1]:"\u51C6\u65B0",99:"99\u65B0",95:"95\u65B0",90:"9\u65B0"};function Vo(){let o=new nt("hang-up");return o.description("\u95F2\u9C7C\u6302\u552E\u4E0A\u67B6\uFF08\u5B8C\u6574\u5546\u54C1\u4FE1\u606F\u6A21\u5F0F\uFF09"),o.addCommand(new nt("categories").description("\u83B7\u53D6\u95F2\u9C7C\u7C7B\u76EE\u5217\u8868\uFF08\u5927\u5206\u7C7B \u2192 \u5C0F\u5206\u7C7B\uFF09").option("--sp-biz-type <n>","\u4E1A\u52A1\u5206\u7C7B\uFF0C16=\u5962\u54C1","16").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09").action(p(async t=>{let e=await Ro(Number(t.spBizType));if(t.json){console.log(JSON.stringify(e,null,2));return}let r=new Map;for(let n of e){let s=String(n.catId);r.has(s)||r.set(s,{catName:n.catName,children:[]}),r.get(s).children.push({channel:n.channel,channelCatId:n.channelCatId})}for(let[n,s]of r){console.log(T.bold(`${s.catName} (catId: ${T.green(n)})`));for(let i of s.children)console.log(` ${i.channel} (channelCatId: ${T.green(i.channelCatId)})`)}}))),o.addCommand(new nt("props").description("\u83B7\u53D6\u6307\u5B9A\u7C7B\u76EE\u4E0B\u7684\u5C5E\u6027\u5217\u8868\uFF08\u542B\u53EF\u9009\u503C\uFF09").requiredOption("--channel-cat-id <id>","\u5C0F\u5206\u7C7B ID\uFF08\u4ECE categories \u83B7\u53D6\uFF09").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09").action(p(async t=>{let e=await Lo(t.channelCatId);if(t.json){console.log(JSON.stringify(e,null,2));return}for(let r of e)if(console.log(T.bold(`
38
+ ${r.propName} (propId: ${r.propId})`)),r.propsValues?.length)for(let n of r.propsValues)console.log(` ${n.valueName} (valueId: ${n.valueId})`);else console.log(T.gray(" \uFF08\u4F7F\u7528 brands \u5B50\u547D\u4EE4\u641C\u7D22\uFF09"))}))),o.addCommand(new nt("brands").description("\u641C\u7D22\u95F2\u9C7C\u54C1\u724C\uFF08\u6309\u5173\u952E\u5B57\u8FC7\u6EE4\uFF09").requiredOption("--channel-cat-id <id>","\u5C0F\u5206\u7C7B ID").requiredOption("--prop-id <id>","\u5C5E\u6027 ID\uFF08\u54C1\u724C\u5C5E\u6027\u7684 propId\uFF09").requiredOption("--key <keyword>","\u641C\u7D22\u5173\u952E\u5B57").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09").action(p(async t=>{let e=await Oo(t.channelCatId,t.propId,t.key);if(t.json){console.log(JSON.stringify(e,null,2));return}if(!e.length){console.log(T.yellow("\u672A\u627E\u5230\u5339\u914D\u7684\u54C1\u724C"));return}for(let r of e)console.log(` ${r.valueName} (valueId: ${r.valueId})`)}))),o.addCommand(new nt("submit").description("\u63D0\u4EA4\u6302\u552E\u4E0A\u67B6").requiredOption("--shop-id <id>","\u5E97\u94FA ID\uFF08\u5373\u95F2\u9C7C\u7528\u6237\u540D account\uFF09").requiredOption("--title <title>","\u5546\u54C1\u6807\u9898").requiredOption("--price <amount>","\u552E\u4EF7").requiredOption("--category-id <id>","\u5927\u5206\u7C7B ID\uFF08\u4ECE categories \u83B7\u53D6\uFF09").requiredOption("--channel-cat-id <id>","\u5C0F\u5206\u7C7B ID\uFF08\u4ECE categories \u83B7\u53D6\uFF09").requiredOption("--image-ids <ids>","\u56FE\u7247 ID \u5217\u8868\uFF0C\u9017\u53F7\u5206\u9694\uFF08\u5148\u901A\u8FC7 upload-images \u83B7\u53D6\uFF09").requiredOption("--stuff-status <n>","\u6210\u8272\uFF1A100 \u5168\u65B0 / -1 \u51C6\u65B0 / 99 99\u65B0 / 95 95\u65B0 / 90 9\u65B0").option("--item-attrs <json>",'\u5546\u54C1\u5C5E\u6027\u5217\u8868 JSON\uFF0C\u683C\u5F0F: [{"propId":"x","valueId":"y","valueName":"z"}]').option("--brand-name <name>","\u54C1\u724C\u540D\u79F0").option("--desc <desc>","\u5546\u54C1\u63CF\u8FF0").option("--size <size>","\u5C3A\u7801").option("--goods-no <no>","\u8D27\u53F7").option("--original-price <amount>","\u539F\u4EF7").option("--trade-type <n>","\u4EA4\u6613\u65B9\u5F0F\uFF1A0 \u4EC5\u5728\u7EBF / 1 \u4EC5\u7EBF\u4E0B / 2 \u7EBF\u4E0A\u6216\u7EBF\u4E0B","0").option("--transport-fee <amount>","\u8FD0\u8D39\uFF08\u9ED8\u8BA4 0 \u5305\u90AE\uFF09","0").option("--yhb","\u662F\u5426\u5F00\u542F\u9A8C\u8D27\u5B9D").requiredOption("--out-item-no <no>","\u5546\u5BB6\u7F16\u7801\uFF08\u540C\u5E97\u94FA\u552F\u4E00\uFF0C\u7528\u6237\u81EA\u5B9A\u4E49\uFF09").option("--division-id <id>","\u884C\u653F\u533A\u5212 ID\uFF08\u5E02\u7EA7 ID\uFF0C\u9ED8\u8BA4\u676D\u5DDE 330100\uFF09","330100").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09").action(p(async t=>{let e=t.imageIds.split(",").map(s=>s.trim()),r={account:t.shopId,title:t.title,reservePrice:Number(t.price),categoryId:Number(t.categoryId),channelCatId:t.channelCatId,imageIdList:e,stuffStatus:Number(t.stuffStatus),itemBizType:2,spBizType:"16",tradeType:Number(t.tradeType)||0,transportFee:Number(t.transportFee)||0,yhb:t.yhb??!1,...t.brandName&&{brandName:t.brandName},...t.desc&&{desc:t.desc},...t.size&&{size:t.size},...t.goodsNo&&{goodsNo:t.goodsNo},...t.originalPrice&&{originalPrice:Number(t.originalPrice)},outItemNo:t.outItemNo,divisionId:Number(t.divisionId)||330100,apiAfterSalesDo:{supportFd10msPolicy:!1,supportFd24hsPolicy:!1,supportNfrPolicy:!1,supportSdrPolicy:!1,supportVnrPolicy:!1,supportGpaPolicy:!1,supportFd48hsPolicy:!1},...t.itemAttrs&&{itemAttrList:JSON.parse(t.itemAttrs)}};t.json||(console.log(T.cyan("\u6B63\u5728\u63D0\u4EA4\u6302\u552E...")),console.log(T.gray(` \u6807\u9898: ${r.title}`)),console.log(T.gray(` \u552E\u4EF7: \xA5${r.reservePrice}`)),console.log(T.gray(` \u6210\u8272: ${sr[r.stuffStatus]??r.stuffStatus}`)),console.log(T.gray(` \u56FE\u7247: ${e.length} \u5F20`)),r.itemAttrList?.length&&console.log(T.gray(` \u5C5E\u6027: ${r.itemAttrList.length} \u9879`)));let n=await No(r);t.json?console.log(JSON.stringify({success:!0,data:n},null,2)):(console.log(T.green("\u6302\u552E\u63D0\u4EA4\u6210\u529F")),console.log(JSON.stringify(n,null,2)))}))),o}function Ko(){let o=new ir("goods");return o.description("\u5546\u54C1\u7BA1\u7406"),o.addCommand(Go()),o.addCommand(Xo()),o.addCommand(_o()),o.addCommand(zo()),o.addCommand(Wo()),o.addCommand(Ho()),o.addCommand(Uo()),o.addCommand(Vo()),o}import{Command as ar}from"commander";import O from"chalk";import{promises as cr}from"node:fs";import lr from"node:path";import dr from"node:os";import{spawn as ur}from"node:child_process";var Tt="@round2ai/r2-cli";function Yo(){let o=new ar("uninstall");return o.description("\u5378\u8F7D R2-CLI \u5E76\u6E05\u9664\u6240\u6709\u914D\u7F6E"),o.action(async()=>{try{console.log(O.yellow(`
39
+ \u26A0\uFE0F \u5373\u5C06\u6267\u884C\u4EE5\u4E0B\u64CD\u4F5C\uFF1A`)),console.log(O.gray(" 1. \u5220\u9664\u914D\u7F6E\u76EE\u5F55 ~/.r2-cli/")),console.log(O.gray(` 2. \u5168\u5C40\u5378\u8F7D ${Tt}
40
+ `));let{confirm:t}=await import("@inquirer/prompts");if(!await t({message:"\u786E\u8BA4\u5378\u8F7D\uFF1F",default:!1})){console.log(O.gray("\u5DF2\u53D6\u6D88\u5378\u8F7D"));return}let r=lr.join(dr.homedir(),".r2-cli");try{await cr.rm(r,{recursive:!0,force:!0}),console.log(O.green("\u2705 \u914D\u7F6E\u6587\u4EF6\u5DF2\u6E05\u9664"))}catch{console.log(O.yellow("\u26A0\uFE0F \u914D\u7F6E\u76EE\u5F55\u4E0D\u5B58\u5728\u6216\u65E0\u6CD5\u5220\u9664\uFF08\u53EF\u5FFD\u7565\uFF09"))}console.log(O.cyan(`\u6B63\u5728\u5378\u8F7D ${Tt}...`)),ur("npm",["uninstall","-g",Tt],{stdio:"inherit",shell:!0}).on("exit",s=>{s===0?console.log(O.green(`
41
+ \u2705 ${Tt} \u5DF2\u5378\u8F7D`)):(console.log(O.yellow(`
42
+ \u26A0\uFE0F npm \u5378\u8F7D\u5931\u8D25 (exit code: ${s})`)),console.log(O.gray(" \u5982\u901A\u8FC7 yarn/pnpm \u5B89\u88C5\uFF0C\u8BF7\u624B\u52A8\u5378\u8F7D"))),process.exit(s??1)})}catch(t){v(t)}}),o}import{Command as pr}from"commander";import st from"chalk";import{spawn as fr,execSync as hr}from"node:child_process";import{readFileSync as mr}from"node:fs";import{join as gr}from"node:path";function bt(){for(let o of["../package.json","../../package.json"])try{return JSON.parse(mr(gr(import.meta.dirname,o),"utf-8")).version}catch{}return"0.0.0"}var Zo="@round2ai/r2-cli";function yr(o,t){return new Promise(e=>{let r=fr(o,t,{stdio:"inherit"});r.on("close",n=>e(n??1)),r.on("error",()=>e(1))})}function te(){return new pr("update").description("\u4E00\u952E\u66F4\u65B0 CLI \u548C\u6280\u80FD").action(async()=>{let o=bt();console.log(st.cyan(`\u5F53\u524D\u7248\u672C: ${o}`)),console.log(st.cyan("\u6B63\u5728\u66F4\u65B0 CLI...")),await yr("npm",["install","-g",`${Zo}@latest`])!==0&&(console.error(st.red(`
43
+ \u2717 update failed \xB7 Try: npm install -g ${Zo}@latest`)),process.exit(1));let e=o;try{e=hr("r2-cli --version",{encoding:"utf-8"}).trim()||o}catch{}console.log(st.green(`
44
+ \u2713 \u66F4\u65B0\u5B8C\u6210: ${o} \u2192 ${e}`)),console.log(st.green("\u2713 \u6280\u80FD\u5DF2\u540C\u6B65\u66F4\u65B0"))})}function oe(o){let t=o.command("auth").description("\u6388\u6743\u7BA1\u7406");t.addCommand(Jt()),t.addCommand(Xt()),t.addCommand(_t()),t.addCommand(Qt()),o.addCommand(Ko()),o.addCommand(Yo()),o.addCommand(te())}import ee from"chalk";var re="@round2ai/r2-cli",wr=[`https://registry.npmmirror.com/${encodeURIComponent(re)}/latest`,`https://registry.npmjs.org/${encodeURIComponent(re)}/latest`],xr=5e3;async function Ir(o){let t=new AbortController,e=setTimeout(()=>t.abort(),xr);try{let r=await fetch(o,{signal:t.signal});return r.ok?(await r.json()).version??null:null}catch{return null}finally{clearTimeout(e)}}async function Sr(){let o=await Promise.allSettled(wr.map(Ir));for(let t of o)if(t.status==="fulfilled"&&t.value)return t.value;return null}function Cr(o,t){let e=o.split(".").map(Number),r=t.split(".").map(Number);for(let n=0;n<3;n++)if((e[n]??0)!==(r[n]??0))return(e[n]??0)>(r[n]??0);return!1}async function ne(o){let t=await Sr();t&&Cr(t,o)&&Tr(o,t)}function Tr(o,t){console.error(ee.yellow(`
45
+ Update available: ${o} \u2192 ${t}`)+ee.gray(`
2116
46
  Run: r2-cli update
2117
- `)
2118
- );
2119
- }
2120
-
2121
- // src/entrypoints/r2-cli.tsx
2122
- async function displayWelcomeMessage() {
2123
- const { default: figlet } = await import("figlet");
2124
- console.log(
2125
- chalk17.cyan.bold(
2126
- figlet.textSync("R2-CLI", {
2127
- font: "Standard",
2128
- horizontalLayout: "full"
2129
- })
2130
- )
2131
- );
2132
- console.log(chalk17.gray(" \u5411 AI \u5F00\u653E\u4E8C\u624B\u6F6E\u5962\u4EA4\u6613\u5168\u94FE\u8DEF\u80FD\u529B\n"));
2133
- }
2134
- function setupCliApp() {
2135
- const program2 = new Command18();
2136
- program2.name("r2-cli").description("R2-CLI\uFF0C\u5411 AI \u5F00\u653E\u4E8C\u624B\u6F6E\u5962\u4EA4\u6613\u5168\u94FE\u8DEF\u80FD\u529B");
2137
- let version = getVersion();
2138
- if (version === "0.0.0") {
2139
- console.error(chalk17.yellow("Warning: unable to read version from package.json"));
2140
- }
2141
- program2.version(version, "-v, --version");
2142
- const updateCheckPromise2 = checkForUpdate(version);
2143
- program2.configureOutput({
2144
- writeErr: (str) => {
2145
- console.error(chalk17.red(str.replace("error:", "").trim()));
2146
- }
2147
- });
2148
- program2.action(async () => {
2149
- await displayWelcomeMessage();
2150
- program2.help();
2151
- });
2152
- setupCommands(program2);
2153
- return { program: program2, updateCheckPromise: updateCheckPromise2 };
2154
- }
2155
- function handleSignal() {
2156
- console.log(chalk17.gray("\n\u64CD\u4F5C\u5DF2\u53D6\u6D88"));
2157
- process.exit(130);
2158
- }
2159
- process.on("SIGINT", handleSignal);
2160
- process.on("SIGTERM", handleSignal);
2161
- var { program, updateCheckPromise } = setupCliApp();
2162
- program.parse(process.argv);
2163
- updateCheckPromise.catch((e) => {
2164
- console.error(chalk17.gray(`[update-check] ${e instanceof Error ? e.message : String(e)}`));
2165
- });
47
+ `))}async function Pr(){let{default:o}=await import("figlet");console.log(tt.cyan.bold(o.textSync("R2-CLI",{font:"Standard",horizontalLayout:"full"}))),console.log(tt.gray(` \u5411 AI \u5F00\u653E\u4E8C\u624B\u6F6E\u5962\u4EA4\u6613\u5168\u94FE\u8DEF\u80FD\u529B
48
+ `))}function Ar(){let o=new br;o.name("r2-cli").description("R2-CLI\uFF0C\u5411 AI \u5F00\u653E\u4E8C\u624B\u6F6E\u5962\u4EA4\u6613\u5168\u94FE\u8DEF\u80FD\u529B");let t=bt();t==="0.0.0"&&console.error(tt.yellow("Warning: unable to read version from package.json")),o.version(t,"-v, --version");let e=ne(t);return o.configureOutput({writeErr:r=>{console.error(tt.red(r.replace("error:","").trim()))}}),o.action(async()=>{await Pr(),o.help()}),oe(o),{program:o,updateCheckPromise:e}}function se(){console.log(tt.gray(`
49
+ \u64CD\u4F5C\u5DF2\u53D6\u6D88`)),process.exit(130)}process.on("SIGINT",se);process.on("SIGTERM",se);var{program:kr,updateCheckPromise:vr}=Ar();kr.parse(process.argv);vr.catch(o=>{console.error(tt.gray(`[update-check] ${o instanceof Error?o.message:String(o)}`))});