@optima-chat/tiktok-cli 0.14.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +1 -1
  2. package/dist/index.js +39 -11
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -23,7 +23,7 @@ tiktok <domain> <verb> --shop <shopId> [--flags]
23
23
  | `orders list` | 订单列表(`--status --page-size --since`) |
24
24
  | `orders get --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
@@ -320,6 +320,7 @@ var today = () => (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
320
320
  var daysAgo = (n) => new Date(Date.now() - n * 864e5).toISOString().slice(0, 10);
321
321
  var toEpoch = (v) => /^\d+$/.test(v) ? Number(v) : Math.floor(Date.parse(v) / 1e3);
322
322
  var PROMOTION_STATUSES = /* @__PURE__ */ new Set(["ONGOING", "NOT_START", "EXPIRED", "DEACTIVATED"]);
323
+ var ANALYTICS_PRODUCT_VERSIONS = /* @__PURE__ */ new Set(["202509", "202605"]);
323
324
  var COMMANDS = [
324
325
  {
325
326
  name: "orders list",
@@ -576,17 +577,44 @@ var COMMANDS = [
576
577
  },
577
578
  {
578
579
  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
- run: ({ shop, args: args2 }) => proxy("GET", shop, "/analytics/202509/shop_products/performance", {
582
- query: {
583
- start_date_ge: args2.from ?? daysAgo(30),
584
- end_date_lt: args2.to ?? today(),
585
- sort_field: "gmv",
586
- sort_order: "DESC",
587
- page_size: args2["page-size"] ?? "20"
580
+ 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",
581
+ flags: ["force-version", "from", "page-size", "page-token", "to", "version"],
582
+ listKey: "products",
583
+ run: ({ shop, args: args2 }) => {
584
+ const ver = args2.version ? String(args2.version) : "202509";
585
+ if (!/^\d{6}$/.test(ver)) {
586
+ return Promise.resolve({
587
+ ok: false,
588
+ error: {
589
+ code: "VALIDATION",
590
+ 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`,
591
+ retryable: false
592
+ }
593
+ });
588
594
  }
589
- })
595
+ if (!ANALYTICS_PRODUCT_VERSIONS.has(ver) && !args2["force-version"]) {
596
+ return Promise.resolve({
597
+ ok: false,
598
+ error: {
599
+ code: "VALIDATION",
600
+ 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`,
601
+ retryable: false
602
+ }
603
+ });
604
+ }
605
+ return proxy("GET", shop, `/analytics/${ver}/shop_products/performance`, {
606
+ query: {
607
+ start_date_ge: args2.from ?? daysAgo(30),
608
+ end_date_lt: args2.to ?? today(),
609
+ sort_field: "gmv",
610
+ sort_order: "DESC",
611
+ page_size: args2["page-size"] ?? "20",
612
+ // 有值才带(照 analytics videos)。实测(spec §3.0 用例 07):第 1 页 token 翻到第 2 页零交集;
613
+ // 🔴 末页 next_page_token **键在、值为空串 ""**(不是缺席,与 promotions list 不同构)。
614
+ ...args2["page-token"] ? { page_token: args2["page-token"] } : {}
615
+ }
616
+ });
617
+ }
590
618
  },
591
619
  {
592
620
  name: "analytics videos",
@@ -1705,7 +1733,7 @@ function parseFlags(tokens) {
1705
1733
  }
1706
1734
  return { args: args2, positional: positional2 };
1707
1735
  }
1708
- var BOOLEAN_FLAGS = /* @__PURE__ */ new Set(["apply", "default", "unprocessed", "enable", "force-status"]);
1736
+ var BOOLEAN_FLAGS = /* @__PURE__ */ new Set(["apply", "default", "unprocessed", "enable", "force-status", "force-version"]);
1709
1737
  var FLAG_TRUE = /* @__PURE__ */ new Set(["true", "1", "yes", "on"]);
1710
1738
  var FLAG_FALSE = /* @__PURE__ */ new Set(["false", "0", "no", "off", ""]);
1711
1739
  function normalizeBooleanFlags(args2) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optima-chat/tiktok-cli",
3
- "version": "0.14.0",
3
+ "version": "0.15.0",
4
4
  "description": "TikTok Shop CLI for Optima agents — 经 tiktok-backend 操作店铺",
5
5
  "type": "module",
6
6
  "bin": {