@optima-chat/tiktok-cli 0.14.0 → 0.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/index.js +46 -15
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -21,9 +21,9 @@ tiktok <domain> <verb> --shop <shopId> [--flags]
|
|
|
21
21
|
| `auth link` | 生成店铺绑定授权链接(无需 --shop) |
|
|
22
22
|
| `shops` | 查当前登录用户已授权店铺 |
|
|
23
23
|
| `orders list` | 订单列表(`--status --page-size --since`) |
|
|
24
|
-
| `orders get --id <id
|
|
24
|
+
| `orders get --id <id>[,<id>]` | 订单详情(多个用英文逗号连) |
|
|
25
25
|
| `analytics shop` | 店铺经营数据(`--from --to`,默认近30天) |
|
|
26
|
-
| `analytics products` | 商品维度数据(GMV
|
|
26
|
+
| `analytics products` | 商品维度数据(GMV 降序)。`--version` 默认 `202509`;`202605` 返回 `total_performance` + 分渠道 `*_performance` 组(**组是可选的、字段名三套变体、`overall_performance` 在新版不存在**,见 spec §3.0);未知版本本地拒,平台出新版可 `--force-version` 直接试;`--page-token` 翻页,**末页 `next_page_token` 为空串**(不是缺席) |
|
|
27
27
|
| `products list` | 商品列表 |
|
|
28
28
|
| `promotions list` | 促销活动。`--status` **省略 = 全部状态**(`ONGOING`/`NOT_START`/`EXPIRED`/`DEACTIVATED`;⚠️ 值写错平台**静默忽略并返回全部**,故 CLI **本地硬拒未知值**;平台将来新增值可用 `--force-status` 越过);`--page-size`(默认 20);`--page-token` 翻页,**末页无 `next_page_token`** |
|
|
29
29
|
| `finance statements` | 结算单 |
|
package/dist/index.js
CHANGED
|
@@ -134,8 +134,9 @@ function classify(status, body, shop) {
|
|
|
134
134
|
if (status === 0 || body?.code === 0) {
|
|
135
135
|
return { ok: true, data: body.data, meta };
|
|
136
136
|
}
|
|
137
|
-
|
|
138
|
-
if (status ===
|
|
137
|
+
const isBackendEnvelope = typeof body?.code !== "number" && typeof body?.error === "string";
|
|
138
|
+
if (status === 404 && isBackendEnvelope) return { ok: false, error: { code: "SHOP_NOT_AUTHORIZED", message: body.error, retryable: false }, meta };
|
|
139
|
+
if (status === 403 && isBackendEnvelope) return { ok: false, error: { code: "VALIDATION", message: body.error, retryable: false }, meta };
|
|
139
140
|
const tc = body?.code;
|
|
140
141
|
const msg = body?.message ?? body?.error ?? `HTTP ${status}`;
|
|
141
142
|
if (tc === 36009002 || status === 429) return { ok: false, error: { code: "RATE_LIMITED", message: msg, retryable: true, retry_after_s: 30 }, meta };
|
|
@@ -320,6 +321,7 @@ var today = () => (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
|
320
321
|
var daysAgo = (n) => new Date(Date.now() - n * 864e5).toISOString().slice(0, 10);
|
|
321
322
|
var toEpoch = (v) => /^\d+$/.test(v) ? Number(v) : Math.floor(Date.parse(v) / 1e3);
|
|
322
323
|
var PROMOTION_STATUSES = /* @__PURE__ */ new Set(["ONGOING", "NOT_START", "EXPIRED", "DEACTIVATED"]);
|
|
324
|
+
var ANALYTICS_PRODUCT_VERSIONS = /* @__PURE__ */ new Set(["202509", "202605"]);
|
|
323
325
|
var COMMANDS = [
|
|
324
326
|
{
|
|
325
327
|
name: "orders list",
|
|
@@ -345,9 +347,11 @@ var COMMANDS = [
|
|
|
345
347
|
},
|
|
346
348
|
{
|
|
347
349
|
name: "orders get",
|
|
348
|
-
summary: "\u8BA2\u5355\u8BE6\u60C5\uFF08--id \u5FC5\u586B\uFF09",
|
|
350
|
+
summary: "\u8BA2\u5355\u8BE6\u60C5\uFF08--id \u5FC5\u586B\uFF0C\u591A\u4E2A\u7528\u82F1\u6587\u9017\u53F7\u8FDE\uFF09",
|
|
349
351
|
flags: ["id"],
|
|
350
|
-
|
|
352
|
+
// 🔴 Get Order Detail 是 GET /order/202309/orders?ids=a,b(#42:原来写成 …/orders/detail,
|
|
353
|
+
// 平台回 36009009 Invalid path;cn-stage 测试店 2026-09-20 实打本路径 200)
|
|
354
|
+
run: ({ shop, args: args2 }) => proxy("GET", shop, "/order/202309/orders", { query: { ids: args2.id } })
|
|
351
355
|
},
|
|
352
356
|
// ── 售后(退货/取消)只读 ──
|
|
353
357
|
{
|
|
@@ -576,17 +580,44 @@ var COMMANDS = [
|
|
|
576
580
|
},
|
|
577
581
|
{
|
|
578
582
|
name: "analytics products",
|
|
579
|
-
summary: "\u5546\u54C1\u7EF4\u5EA6\u7ECF\u8425\u6570\u636E\uFF08\u6309 GMV \u964D\u5E8F\uFF09",
|
|
580
|
-
flags: ["from", "page-size", "to"],
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
583
|
+
summary: "\u5546\u54C1\u7EF4\u5EA6\u7ECF\u8425\u6570\u636E\uFF08\u6309 GMV \u964D\u5E8F\uFF1B--from --to \u9ED8\u8BA4\u8FD130\u5929\uFF1B--version 202509 \u9ED8\u8BA4\uFF5C202605 = \u5546\u54C1\u7EA7 key \u6362\u6210 total_performance + \u5206\u6E20\u9053 *_performance \u7EC4\uFF08\u7EC4\u53EF\u9009\u3001\u5B57\u6BB5\u540D\u6709\u4E09\u5957\u53D8\u4F53\uFF09\uFF0C\u672A\u77E5\u7248\u672C\u672C\u5730\u62D2\u3001\u5E73\u53F0\u5C06\u6765\u51FA\u65B0\u7248\u53EF\u7528 --force-version \u76F4\u63A5\u8BD5\uFF1B--page-size \u9ED8\u8BA420\uFF1B--page-token \u7FFB\u9875\uFF0C\u672B\u9875 next_page_token \u4E3A\u7A7A\u4E32\uFF09",
|
|
584
|
+
flags: ["force-version", "from", "page-size", "page-token", "to", "version"],
|
|
585
|
+
listKey: "products",
|
|
586
|
+
run: ({ shop, args: args2 }) => {
|
|
587
|
+
const ver = args2.version ? String(args2.version) : "202509";
|
|
588
|
+
if (!/^\d{6}$/.test(ver)) {
|
|
589
|
+
return Promise.resolve({
|
|
590
|
+
ok: false,
|
|
591
|
+
error: {
|
|
592
|
+
code: "VALIDATION",
|
|
593
|
+
message: `--version \u5FC5\u987B\u662F 6 \u4F4D\u6570\u5B57\uFF08\u5DF2\u77E5\u53D6\u503C\uFF1A${[...ANALYTICS_PRODUCT_VERSIONS].join(" / ")}\uFF09\uFF0C\u6536\u5230 ${JSON.stringify(ver)}\u3002\u26D4 \u683C\u5F0F\u4E0D\u5408\u6CD5\u65F6 --force-version \u4E5F\u4E0D\u653E\u884C\uFF0C\u4E0D\u53D1\u8BF7\u6C42\u3002`,
|
|
594
|
+
retryable: false
|
|
595
|
+
}
|
|
596
|
+
});
|
|
588
597
|
}
|
|
589
|
-
|
|
598
|
+
if (!ANALYTICS_PRODUCT_VERSIONS.has(ver) && !args2["force-version"]) {
|
|
599
|
+
return Promise.resolve({
|
|
600
|
+
ok: false,
|
|
601
|
+
error: {
|
|
602
|
+
code: "VALIDATION",
|
|
603
|
+
message: `\u672A\u77E5\u7684 --version ${JSON.stringify(ver)}\uFF1B\u5DF2\u77E5\u53D6\u503C\uFF1A${[...ANALYTICS_PRODUCT_VERSIONS].join(" / ")}\u3002\u5E73\u53F0\u82E5\u5DF2\u53D1\u5E03\u65B0\u7248\u672C\uFF0C\u53EF\u52A0 --force-version \u76F4\u63A5\u8BD5\uFF08\u7248\u672C\u4E0D\u5BF9\u5E73\u53F0\u4F1A\u660E\u786E\u56DE 36009004\uFF09\u3002\u672C\u5730\u62D2\uFF0C\u4E0D\u53D1\u8BF7\u6C42\u3002`,
|
|
604
|
+
retryable: false
|
|
605
|
+
}
|
|
606
|
+
});
|
|
607
|
+
}
|
|
608
|
+
return proxy("GET", shop, `/analytics/${ver}/shop_products/performance`, {
|
|
609
|
+
query: {
|
|
610
|
+
start_date_ge: args2.from ?? daysAgo(30),
|
|
611
|
+
end_date_lt: args2.to ?? today(),
|
|
612
|
+
sort_field: "gmv",
|
|
613
|
+
sort_order: "DESC",
|
|
614
|
+
page_size: args2["page-size"] ?? "20",
|
|
615
|
+
// 有值才带(照 analytics videos)。实测(spec §3.0 用例 07):第 1 页 token 翻到第 2 页零交集;
|
|
616
|
+
// 🔴 末页 next_page_token **键在、值为空串 ""**(不是缺席,与 promotions list 不同构)。
|
|
617
|
+
...args2["page-token"] ? { page_token: args2["page-token"] } : {}
|
|
618
|
+
}
|
|
619
|
+
});
|
|
620
|
+
}
|
|
590
621
|
},
|
|
591
622
|
{
|
|
592
623
|
name: "analytics videos",
|
|
@@ -1705,7 +1736,7 @@ function parseFlags(tokens) {
|
|
|
1705
1736
|
}
|
|
1706
1737
|
return { args: args2, positional: positional2 };
|
|
1707
1738
|
}
|
|
1708
|
-
var BOOLEAN_FLAGS = /* @__PURE__ */ new Set(["apply", "default", "unprocessed", "enable", "force-status"]);
|
|
1739
|
+
var BOOLEAN_FLAGS = /* @__PURE__ */ new Set(["apply", "default", "unprocessed", "enable", "force-status", "force-version"]);
|
|
1709
1740
|
var FLAG_TRUE = /* @__PURE__ */ new Set(["true", "1", "yes", "on"]);
|
|
1710
1741
|
var FLAG_FALSE = /* @__PURE__ */ new Set(["false", "0", "no", "off", ""]);
|
|
1711
1742
|
function normalizeBooleanFlags(args2) {
|