beervid-app-cli 0.2.1 → 0.2.3
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 +16 -5
- package/dist/cli.mjs +174 -250
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,21 +2,32 @@
|
|
|
2
2
|
|
|
3
3
|
BEERVID 第三方应用 Open API 的 TypeScript CLI 和 Claude Code Skill,提供 TikTok 视频发布、账号授权、数据查询等完整能力。
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## 安装与调用
|
|
6
6
|
|
|
7
|
-
###
|
|
7
|
+
### 全局安装
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
10
|
npm install -g beervid-app-cli
|
|
11
11
|
beervid --help
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
-
###
|
|
14
|
+
### npx 免安装调用
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
```bash
|
|
17
|
+
npx beervid-app-cli --help
|
|
18
|
+
npx beervid-app-cli config --show
|
|
19
|
+
npx beervid-app-cli upload --file ./video.mp4
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### node 直接调用
|
|
17
23
|
|
|
18
24
|
```bash
|
|
19
|
-
|
|
25
|
+
# 克隆仓库后先构建
|
|
26
|
+
npm install && npm run build
|
|
27
|
+
|
|
28
|
+
# 通过 node 运行入口文件
|
|
29
|
+
node dist/cli.mjs --help
|
|
30
|
+
node dist/cli.mjs config --show
|
|
20
31
|
```
|
|
21
32
|
|
|
22
33
|
## 配置
|
package/dist/cli.mjs
CHANGED
|
@@ -169,11 +169,11 @@ function register(cli2) {
|
|
|
169
169
|
if (type === "tt") {
|
|
170
170
|
const data = await openApiGet("/api/v1/open/thirdparty-auth/tt-url");
|
|
171
171
|
console.log("TT OAuth \u6388\u6743\u94FE\u63A5:");
|
|
172
|
-
printResult(
|
|
172
|
+
printResult(data);
|
|
173
173
|
} else {
|
|
174
174
|
const data = await openApiGet("/api/v1/open/thirdparty-auth/tts-url");
|
|
175
175
|
console.log("TTS OAuth \u6388\u6743\u94FE\u63A5:");
|
|
176
|
-
printResult(
|
|
176
|
+
printResult(data);
|
|
177
177
|
}
|
|
178
178
|
} catch (err) {
|
|
179
179
|
rethrowIfProcessExit(err);
|
|
@@ -451,7 +451,7 @@ function register5(cli2) {
|
|
|
451
451
|
|
|
452
452
|
// src/commands/query-video.ts
|
|
453
453
|
function register6(cli2) {
|
|
454
|
-
cli2.command("query-video", "\u67E5\u8BE2\u89C6\u9891\u7EDF\u8BA1\u6570\u636E").option("--business-id <id>", "TT \u8D26\u53F7 businessId\uFF08\u5FC5\u586B\uFF09").option("--item-ids <ids>", "\u89C6\u9891 ID\uFF0C\
|
|
454
|
+
cli2.command("query-video", "\u67E5\u8BE2\u89C6\u9891\u7EDF\u8BA1\u6570\u636E").option("--business-id <id>", "TT \u8D26\u53F7 businessId\uFF08\u5FC5\u586B\uFF09").option("--item-ids <ids>", "\u89C6\u9891 ID\uFF0C\u652F\u6301\u91CD\u590D\u4F20\u53C2\u6216\u9017\u53F7\u5206\u9694\uFF08\u5FC5\u586B\uFF09").action(
|
|
455
455
|
async (options) => {
|
|
456
456
|
if (!options.businessId || !options.itemIds) {
|
|
457
457
|
const missing = [
|
|
@@ -465,7 +465,7 @@ function register6(cli2) {
|
|
|
465
465
|
);
|
|
466
466
|
process.exit(1);
|
|
467
467
|
}
|
|
468
|
-
const itemIds = options.itemIds.split(",").map((id) => id.trim()).filter(Boolean);
|
|
468
|
+
const itemIds = (Array.isArray(options.itemIds) ? options.itemIds : [options.itemIds]).flatMap((value) => value.split(",")).map((id) => id.trim()).filter(Boolean);
|
|
469
469
|
if (itemIds.length === 0) {
|
|
470
470
|
console.error("\u9519\u8BEF: --item-ids \u4E0D\u80FD\u4E3A\u7A7A");
|
|
471
471
|
process.exit(1);
|
|
@@ -501,7 +501,7 @@ function register6(cli2) {
|
|
|
501
501
|
if (v.shareUrl) console.log(` \u94FE\u63A5: ${v.shareUrl}`);
|
|
502
502
|
console.log("");
|
|
503
503
|
}
|
|
504
|
-
printResult(
|
|
504
|
+
printResult(data);
|
|
505
505
|
} catch (err) {
|
|
506
506
|
rethrowIfProcessExit(err);
|
|
507
507
|
console.error("\u67E5\u8BE2\u89C6\u9891\u6570\u636E\u5931\u8D25:", err.message);
|
|
@@ -511,134 +511,6 @@ function register6(cli2) {
|
|
|
511
511
|
);
|
|
512
512
|
}
|
|
513
513
|
|
|
514
|
-
// src/commands/query-products.ts
|
|
515
|
-
var VALID_PRODUCT_TYPES = ["shop", "showcase", "all"];
|
|
516
|
-
function extractImageUrl(imageStr) {
|
|
517
|
-
const match = imageStr.match(/url=([^,}]+)/);
|
|
518
|
-
return match?.[1]?.trim() ?? imageStr;
|
|
519
|
-
}
|
|
520
|
-
async function queryProducts(creatorId, type, pageSize, pageToken) {
|
|
521
|
-
return openApiPost("/api/v1/open/tts/products/query", {
|
|
522
|
-
creatorUserOpenId: creatorId,
|
|
523
|
-
productType: type,
|
|
524
|
-
pageSize,
|
|
525
|
-
pageToken
|
|
526
|
-
});
|
|
527
|
-
}
|
|
528
|
-
function register7(cli2) {
|
|
529
|
-
cli2.command("query-products", "\u67E5\u8BE2 TTS \u5546\u54C1\u5217\u8868").option("--creator-id <id>", "TTS \u8D26\u53F7 creatorUserOpenId\uFF08\u5FC5\u586B\uFF09").option("--product-type <type>", "\u5546\u54C1\u6765\u6E90: shop / showcase / all\uFF08\u9ED8\u8BA4 all\uFF09").option("--page-size <n>", "\u6BCF\u9875\u6570\u91CF\uFF08\u9ED8\u8BA4 20\uFF09").option("--cursor <cursor>", "\u5206\u9875\u6E38\u6807\uFF08\u9996\u9875\u4E0D\u4F20\uFF09").action(
|
|
530
|
-
async (options) => {
|
|
531
|
-
if (!options.creatorId) {
|
|
532
|
-
console.error("\u7F3A\u5C11\u5FC5\u586B\u53C2\u6570: --creator-id\n");
|
|
533
|
-
console.error("\u7528\u6CD5: beervid query-products --creator-id <id>");
|
|
534
|
-
process.exit(1);
|
|
535
|
-
}
|
|
536
|
-
const creatorId = options.creatorId;
|
|
537
|
-
const productType = (options.productType ?? "all").toLowerCase();
|
|
538
|
-
const pageSize = parseInt(options.pageSize ?? "20", 10);
|
|
539
|
-
const cursor = options.cursor ?? "";
|
|
540
|
-
if (!VALID_PRODUCT_TYPES.includes(productType)) {
|
|
541
|
-
console.error("\u9519\u8BEF: --product-type \u5FC5\u987B\u4E3A shop\u3001showcase \u6216 all");
|
|
542
|
-
process.exit(1);
|
|
543
|
-
}
|
|
544
|
-
if (Number.isNaN(pageSize) || pageSize <= 0) {
|
|
545
|
-
console.error("\u9519\u8BEF: --page-size \u5FC5\u987B\u4E3A\u5927\u4E8E 0 \u7684\u6574\u6570");
|
|
546
|
-
process.exit(1);
|
|
547
|
-
}
|
|
548
|
-
try {
|
|
549
|
-
let shopToken = "";
|
|
550
|
-
let showcaseToken = "";
|
|
551
|
-
if (cursor) {
|
|
552
|
-
try {
|
|
553
|
-
const decoded = JSON.parse(
|
|
554
|
-
Buffer.from(cursor, "base64").toString()
|
|
555
|
-
);
|
|
556
|
-
shopToken = decoded.shopToken ?? "";
|
|
557
|
-
showcaseToken = decoded.showcaseToken ?? "";
|
|
558
|
-
} catch {
|
|
559
|
-
console.error("\u9519\u8BEF: \u65E0\u6548\u7684 cursor \u683C\u5F0F");
|
|
560
|
-
process.exit(1);
|
|
561
|
-
}
|
|
562
|
-
}
|
|
563
|
-
const typesToQuery = productType === "all" ? ["shop", "showcase"] : [productType];
|
|
564
|
-
const allProducts = /* @__PURE__ */ new Map();
|
|
565
|
-
let nextShopToken = null;
|
|
566
|
-
let nextShowcaseToken = null;
|
|
567
|
-
let successCount = 0;
|
|
568
|
-
const results = await Promise.allSettled(
|
|
569
|
-
typesToQuery.map(async (type) => {
|
|
570
|
-
const token = type === "shop" ? shopToken : showcaseToken;
|
|
571
|
-
const data = await queryProducts(creatorId, type, pageSize, token);
|
|
572
|
-
return { type, data };
|
|
573
|
-
})
|
|
574
|
-
);
|
|
575
|
-
for (const result of results) {
|
|
576
|
-
if (result.status === "rejected") {
|
|
577
|
-
console.error("\u67E5\u8BE2\u5931\u8D25:", result.reason?.message);
|
|
578
|
-
continue;
|
|
579
|
-
}
|
|
580
|
-
const { type, data } = result.value;
|
|
581
|
-
successCount += 1;
|
|
582
|
-
const items = Array.isArray(data) ? data : [data];
|
|
583
|
-
for (const group of items) {
|
|
584
|
-
if (type === "shop") nextShopToken = group.nextPageToken ?? null;
|
|
585
|
-
if (type === "showcase") nextShowcaseToken = group.nextPageToken ?? null;
|
|
586
|
-
for (const product of group.products ?? []) {
|
|
587
|
-
if (!allProducts.has(product.id)) {
|
|
588
|
-
allProducts.set(product.id, {
|
|
589
|
-
id: product.id,
|
|
590
|
-
title: product.title,
|
|
591
|
-
price: product.price,
|
|
592
|
-
images: (product.images ?? []).map(extractImageUrl),
|
|
593
|
-
salesCount: product.salesCount ?? 0,
|
|
594
|
-
brandName: product.brandName ?? "",
|
|
595
|
-
shopName: product.shopName ?? "",
|
|
596
|
-
source: product.source ?? type,
|
|
597
|
-
reviewStatus: product.reviewStatus,
|
|
598
|
-
inventoryStatus: product.inventoryStatus
|
|
599
|
-
});
|
|
600
|
-
}
|
|
601
|
-
}
|
|
602
|
-
}
|
|
603
|
-
}
|
|
604
|
-
if (successCount === 0) {
|
|
605
|
-
console.error("\u67E5\u8BE2\u5546\u54C1\u5931\u8D25: \u6240\u6709\u5546\u54C1\u6E90\u90FD\u8BF7\u6C42\u5931\u8D25");
|
|
606
|
-
process.exit(1);
|
|
607
|
-
}
|
|
608
|
-
const productList = Array.from(allProducts.values());
|
|
609
|
-
let nextCursor = null;
|
|
610
|
-
if (nextShopToken || nextShowcaseToken) {
|
|
611
|
-
nextCursor = Buffer.from(
|
|
612
|
-
JSON.stringify({
|
|
613
|
-
shopToken: nextShopToken ?? "",
|
|
614
|
-
showcaseToken: nextShowcaseToken ?? ""
|
|
615
|
-
})
|
|
616
|
-
).toString("base64");
|
|
617
|
-
}
|
|
618
|
-
console.log(`\u67E5\u8BE2\u5230 ${productList.length} \u4E2A\u5546\u54C1:
|
|
619
|
-
`);
|
|
620
|
-
for (const p of productList) {
|
|
621
|
-
console.log(` [${p.source}] ${p.title}`);
|
|
622
|
-
console.log(` ID: ${p.id} \u9500\u91CF: ${p.salesCount} \u54C1\u724C: ${p.brandName}`);
|
|
623
|
-
if (p.images.length > 0) console.log(` \u56FE\u7247: ${p.images[0]}`);
|
|
624
|
-
console.log("");
|
|
625
|
-
}
|
|
626
|
-
if (nextCursor) {
|
|
627
|
-
console.log(`\u4E0B\u4E00\u9875\u6E38\u6807: ${nextCursor}`);
|
|
628
|
-
console.log(`\u4F7F\u7528: beervid query-products --creator-id ${creatorId} --cursor ${nextCursor}`);
|
|
629
|
-
} else {
|
|
630
|
-
console.log("\u5DF2\u5230\u6700\u540E\u4E00\u9875");
|
|
631
|
-
}
|
|
632
|
-
printResult({ products: productList, nextCursor });
|
|
633
|
-
} catch (err) {
|
|
634
|
-
rethrowIfProcessExit(err);
|
|
635
|
-
console.error("\u67E5\u8BE2\u5546\u54C1\u5931\u8D25:", err.message);
|
|
636
|
-
process.exit(1);
|
|
637
|
-
}
|
|
638
|
-
}
|
|
639
|
-
);
|
|
640
|
-
}
|
|
641
|
-
|
|
642
514
|
// src/workflows/index.ts
|
|
643
515
|
import { createInterface } from "readline/promises";
|
|
644
516
|
import { stdin as input, stdout as output } from "process";
|
|
@@ -709,23 +581,6 @@ async function pollNormalVideoStatus(businessId, shareId, intervalSec, maxPolls)
|
|
|
709
581
|
raw: lastData
|
|
710
582
|
};
|
|
711
583
|
}
|
|
712
|
-
function normalizeVideoQuery(data) {
|
|
713
|
-
const list = data.videoList ?? data.videos ?? [];
|
|
714
|
-
const videos = list.map((video) => ({
|
|
715
|
-
itemId: video.itemId ?? video.item_id,
|
|
716
|
-
videoViews: video.videoViews ?? video.video_views ?? 0,
|
|
717
|
-
likes: video.likes ?? 0,
|
|
718
|
-
comments: video.comments ?? 0,
|
|
719
|
-
shares: video.shares ?? 0,
|
|
720
|
-
thumbnailUrl: video.thumbnailUrl ?? video.thumbnail_url ?? "",
|
|
721
|
-
shareUrl: video.shareUrl ?? video.share_url ?? ""
|
|
722
|
-
}));
|
|
723
|
-
return {
|
|
724
|
-
attempts: 1,
|
|
725
|
-
videos,
|
|
726
|
-
raw: data
|
|
727
|
-
};
|
|
728
|
-
}
|
|
729
584
|
async function queryVideoWithRetry(businessId, itemId, intervalSec, maxAttempts) {
|
|
730
585
|
const warnings = [];
|
|
731
586
|
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
@@ -733,10 +588,9 @@ async function queryVideoWithRetry(businessId, itemId, intervalSec, maxAttempts)
|
|
|
733
588
|
businessId,
|
|
734
589
|
itemIds: [itemId]
|
|
735
590
|
});
|
|
736
|
-
const
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
return { query: normalized, warnings };
|
|
591
|
+
const list = data.videoList ?? data.videos ?? [];
|
|
592
|
+
if (list.length > 0) {
|
|
593
|
+
return { query: data, warnings };
|
|
740
594
|
}
|
|
741
595
|
if (attempt < maxAttempts) {
|
|
742
596
|
await sleep2(intervalSec * 1e3);
|
|
@@ -748,25 +602,31 @@ async function queryVideoWithRetry(businessId, itemId, intervalSec, maxAttempts)
|
|
|
748
602
|
});
|
|
749
603
|
return { query: null, warnings };
|
|
750
604
|
}
|
|
751
|
-
function
|
|
605
|
+
function extractImageUrl(imageStr) {
|
|
752
606
|
const match = imageStr.match(/url=([^,}]+)/);
|
|
753
607
|
return match?.[1]?.trim() ?? imageStr;
|
|
754
608
|
}
|
|
755
609
|
function decodeCursor(cursor) {
|
|
756
610
|
const decoded = JSON.parse(Buffer.from(cursor, "base64").toString());
|
|
757
611
|
return {
|
|
758
|
-
shopToken: decoded.shopToken
|
|
759
|
-
showcaseToken: decoded.showcaseToken
|
|
612
|
+
shopToken: decoded.shopToken === void 0 ? "" : decoded.shopToken,
|
|
613
|
+
showcaseToken: decoded.showcaseToken === void 0 ? "" : decoded.showcaseToken
|
|
760
614
|
};
|
|
761
615
|
}
|
|
762
616
|
function encodeCursor(cursor) {
|
|
617
|
+
if (cursor.shopToken === null && cursor.showcaseToken === null) return null;
|
|
763
618
|
return Buffer.from(JSON.stringify(cursor)).toString("base64");
|
|
764
619
|
}
|
|
765
620
|
async function queryProductsPage(creatorId, productType, pageSize, cursor) {
|
|
766
|
-
const
|
|
621
|
+
const allTypesToQuery = productType === "all" ? ["shop", "showcase"] : [productType];
|
|
622
|
+
const typesToQuery = allTypesToQuery.filter((type) => {
|
|
623
|
+
const token = type === "shop" ? cursor.shopToken : cursor.showcaseToken;
|
|
624
|
+
return token !== null;
|
|
625
|
+
});
|
|
767
626
|
const allProducts = /* @__PURE__ */ new Map();
|
|
768
|
-
|
|
769
|
-
let
|
|
627
|
+
const rawGroups = [];
|
|
628
|
+
let nextShopToken = cursor.shopToken;
|
|
629
|
+
let nextShowcaseToken = cursor.showcaseToken;
|
|
770
630
|
let successCount = 0;
|
|
771
631
|
const failedSources = [];
|
|
772
632
|
const results = await Promise.allSettled(
|
|
@@ -776,7 +636,7 @@ async function queryProductsPage(creatorId, productType, pageSize, cursor) {
|
|
|
776
636
|
creatorUserOpenId: creatorId,
|
|
777
637
|
productType: type,
|
|
778
638
|
pageSize,
|
|
779
|
-
pageToken
|
|
639
|
+
pageToken: pageToken ?? ""
|
|
780
640
|
});
|
|
781
641
|
return { type, data };
|
|
782
642
|
})
|
|
@@ -792,16 +652,18 @@ async function queryProductsPage(creatorId, productType, pageSize, cursor) {
|
|
|
792
652
|
successCount += 1;
|
|
793
653
|
const { data } = result.value;
|
|
794
654
|
const groups = Array.isArray(data) ? data : [data];
|
|
655
|
+
rawGroups.push(...groups);
|
|
795
656
|
for (const group of groups) {
|
|
796
|
-
|
|
797
|
-
if (type === "
|
|
657
|
+
const token = group.nextPageToken === void 0 ? null : group.nextPageToken;
|
|
658
|
+
if (type === "shop") nextShopToken = token;
|
|
659
|
+
if (type === "showcase") nextShowcaseToken = token;
|
|
798
660
|
for (const product of group.products ?? []) {
|
|
799
661
|
if (!allProducts.has(product.id)) {
|
|
800
662
|
allProducts.set(product.id, {
|
|
801
663
|
id: product.id,
|
|
802
664
|
title: product.title,
|
|
803
665
|
price: product.price,
|
|
804
|
-
images: (product.images ?? []).map(
|
|
666
|
+
images: (product.images ?? []).map(extractImageUrl),
|
|
805
667
|
salesCount: product.salesCount ?? 0,
|
|
806
668
|
brandName: product.brandName ?? "",
|
|
807
669
|
shopName: product.shopName ?? "",
|
|
@@ -813,9 +675,10 @@ async function queryProductsPage(creatorId, productType, pageSize, cursor) {
|
|
|
813
675
|
}
|
|
814
676
|
}
|
|
815
677
|
}
|
|
816
|
-
const nextCursor =
|
|
678
|
+
const nextCursor = encodeCursor({ shopToken: nextShopToken, showcaseToken: nextShowcaseToken });
|
|
817
679
|
return {
|
|
818
680
|
products: Array.from(allProducts.values()),
|
|
681
|
+
rawGroups,
|
|
819
682
|
nextCursor,
|
|
820
683
|
successCount,
|
|
821
684
|
failedSources
|
|
@@ -823,6 +686,7 @@ async function queryProductsPage(creatorId, productType, pageSize, cursor) {
|
|
|
823
686
|
}
|
|
824
687
|
async function fetchProductPool(creatorId, productType, pageSize, maxPages) {
|
|
825
688
|
const allProducts = /* @__PURE__ */ new Map();
|
|
689
|
+
const rawGroups = [];
|
|
826
690
|
let cursor = { shopToken: "", showcaseToken: "" };
|
|
827
691
|
let nextCursor = null;
|
|
828
692
|
let pagesScanned = 0;
|
|
@@ -836,6 +700,7 @@ async function fetchProductPool(creatorId, productType, pageSize, maxPages) {
|
|
|
836
700
|
failedSourcesSet.add(src);
|
|
837
701
|
}
|
|
838
702
|
pagesScanned = page;
|
|
703
|
+
rawGroups.push(...pageResult.rawGroups);
|
|
839
704
|
for (const product of pageResult.products) {
|
|
840
705
|
if (!allProducts.has(product.id)) {
|
|
841
706
|
allProducts.set(product.id, product);
|
|
@@ -849,6 +714,7 @@ async function fetchProductPool(creatorId, productType, pageSize, maxPages) {
|
|
|
849
714
|
}
|
|
850
715
|
return {
|
|
851
716
|
products: Array.from(allProducts.values()),
|
|
717
|
+
rawGroups,
|
|
852
718
|
summary: {
|
|
853
719
|
productType,
|
|
854
720
|
pageSize,
|
|
@@ -860,27 +726,23 @@ async function fetchProductPool(creatorId, productType, pageSize, maxPages) {
|
|
|
860
726
|
}
|
|
861
727
|
};
|
|
862
728
|
}
|
|
863
|
-
function
|
|
864
|
-
|
|
729
|
+
function isProductPublishable(product) {
|
|
730
|
+
if (product.reviewStatus && product.reviewStatus.toUpperCase() !== "APPROVED") return false;
|
|
731
|
+
if (product.inventoryStatus && product.inventoryStatus.toUpperCase() !== "IN_STOCK") return false;
|
|
732
|
+
return true;
|
|
865
733
|
}
|
|
866
|
-
function
|
|
867
|
-
return
|
|
868
|
-
selectionMode,
|
|
869
|
-
id: product.id,
|
|
870
|
-
title: product.title,
|
|
871
|
-
salesCount: product.salesCount,
|
|
872
|
-
source: product.source,
|
|
873
|
-
price: product.price,
|
|
874
|
-
brandName: product.brandName,
|
|
875
|
-
shopName: product.shopName
|
|
876
|
-
};
|
|
734
|
+
function sortProductsForSelection(products) {
|
|
735
|
+
return products.filter(isProductPublishable).sort((a, b) => b.salesCount - a.salesCount);
|
|
877
736
|
}
|
|
878
737
|
async function promptForProductSelection(products) {
|
|
879
738
|
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
880
739
|
throw new Error("\u4EA4\u4E92\u6A21\u5F0F\u9700\u8981\u5728 TTY \u7EC8\u7AEF\u4E2D\u8FD0\u884C");
|
|
881
740
|
}
|
|
882
|
-
const candidates =
|
|
883
|
-
|
|
741
|
+
const candidates = products.filter(isProductPublishable).sort((a, b) => b.salesCount - a.salesCount).slice(0, 20);
|
|
742
|
+
if (candidates.length === 0) {
|
|
743
|
+
throw new Error("\u5F53\u524D\u5546\u54C1\u6C60\u4E2D\u6CA1\u6709\u53EF\u53D1\u5E03\u5546\u54C1\uFF08\u5BA1\u6838\u672A\u901A\u8FC7\u6216\u65E0\u5E93\u5B58\uFF09\uFF0C\u5982\u9700\u5F3A\u5236\u6307\u5B9A\u8BF7\u4F7F\u7528 --product-id/--product-title");
|
|
744
|
+
}
|
|
745
|
+
console.log(`\u53EF\u9009\u5546\u54C1\uFF08\u5C55\u793A\u524D ${candidates.length} \u4E2A\uFF0C\u6309\u9500\u91CF\u964D\u5E8F\uFF0C\u5DF2\u8FC7\u6EE4\u4E0D\u53EF\u53D1\u5E03\u5546\u54C1\uFF09\uFF1A`);
|
|
884
746
|
for (const [index, product] of candidates.entries()) {
|
|
885
747
|
console.log(
|
|
886
748
|
`${index + 1}. [${product.source}] ${product.title} | ID: ${product.id} | \u9500\u91CF: ${product.salesCount}`
|
|
@@ -904,6 +766,73 @@ async function promptForProductSelection(products) {
|
|
|
904
766
|
}
|
|
905
767
|
}
|
|
906
768
|
|
|
769
|
+
// src/commands/query-products.ts
|
|
770
|
+
var VALID_PRODUCT_TYPES = ["shop", "showcase", "all"];
|
|
771
|
+
function register7(cli2) {
|
|
772
|
+
cli2.command("query-products", "\u67E5\u8BE2 TTS \u5546\u54C1\u5217\u8868").option("--creator-id <id>", "TTS \u8D26\u53F7 creatorUserOpenId\uFF08\u5FC5\u586B\uFF09").option("--product-type <type>", "\u5546\u54C1\u6765\u6E90: shop / showcase / all\uFF08\u9ED8\u8BA4 all\uFF09").option("--page-size <n>", "\u6BCF\u9875\u6570\u91CF\uFF08\u9ED8\u8BA4 20\uFF09").option("--cursor <cursor>", "\u5206\u9875\u6E38\u6807\uFF08\u9996\u9875\u4E0D\u4F20\uFF09").action(
|
|
773
|
+
async (options) => {
|
|
774
|
+
if (!options.creatorId) {
|
|
775
|
+
console.error("\u7F3A\u5C11\u5FC5\u586B\u53C2\u6570: --creator-id\n");
|
|
776
|
+
console.error("\u7528\u6CD5: beervid query-products --creator-id <id>");
|
|
777
|
+
process.exit(1);
|
|
778
|
+
}
|
|
779
|
+
const creatorId = options.creatorId;
|
|
780
|
+
const productType = (options.productType ?? "all").toLowerCase();
|
|
781
|
+
const pageSize = parseInt(options.pageSize ?? "20", 10);
|
|
782
|
+
const cursor = options.cursor ?? "";
|
|
783
|
+
if (!VALID_PRODUCT_TYPES.includes(productType)) {
|
|
784
|
+
console.error("\u9519\u8BEF: --product-type \u5FC5\u987B\u4E3A shop\u3001showcase \u6216 all");
|
|
785
|
+
process.exit(1);
|
|
786
|
+
}
|
|
787
|
+
if (Number.isNaN(pageSize) || pageSize <= 0) {
|
|
788
|
+
console.error("\u9519\u8BEF: --page-size \u5FC5\u987B\u4E3A\u5927\u4E8E 0 \u7684\u6574\u6570");
|
|
789
|
+
process.exit(1);
|
|
790
|
+
}
|
|
791
|
+
try {
|
|
792
|
+
let inputCursor = { shopToken: "", showcaseToken: "" };
|
|
793
|
+
if (cursor) {
|
|
794
|
+
try {
|
|
795
|
+
inputCursor = decodeCursor(cursor);
|
|
796
|
+
} catch {
|
|
797
|
+
console.error("\u9519\u8BEF: \u65E0\u6548\u7684 cursor \u683C\u5F0F");
|
|
798
|
+
process.exit(1);
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
const pageResult = await queryProductsPage(
|
|
802
|
+
creatorId,
|
|
803
|
+
productType,
|
|
804
|
+
pageSize,
|
|
805
|
+
inputCursor
|
|
806
|
+
);
|
|
807
|
+
if (pageResult.successCount === 0 && pageResult.failedSources.length > 0) {
|
|
808
|
+
console.error("\u67E5\u8BE2\u5546\u54C1\u5931\u8D25: \u6240\u6709\u5546\u54C1\u6E90\u90FD\u8BF7\u6C42\u5931\u8D25");
|
|
809
|
+
process.exit(1);
|
|
810
|
+
}
|
|
811
|
+
const productList = pageResult.products;
|
|
812
|
+
console.log(`\u67E5\u8BE2\u5230 ${productList.length} \u4E2A\u5546\u54C1:
|
|
813
|
+
`);
|
|
814
|
+
for (const p of productList) {
|
|
815
|
+
console.log(` [${p.source}] ${p.title}`);
|
|
816
|
+
console.log(` ID: ${p.id} \u9500\u91CF: ${p.salesCount} \u54C1\u724C: ${p.brandName}`);
|
|
817
|
+
if (p.images.length > 0) console.log(` \u56FE\u7247: ${p.images[0]}`);
|
|
818
|
+
console.log("");
|
|
819
|
+
}
|
|
820
|
+
if (pageResult.nextCursor) {
|
|
821
|
+
console.log(`\u4E0B\u4E00\u9875\u6E38\u6807: ${pageResult.nextCursor}`);
|
|
822
|
+
console.log(`\u4F7F\u7528: beervid query-products --creator-id ${creatorId} --cursor ${pageResult.nextCursor}`);
|
|
823
|
+
} else {
|
|
824
|
+
console.log("\u5DF2\u5230\u6700\u540E\u4E00\u9875");
|
|
825
|
+
}
|
|
826
|
+
printResult(pageResult.rawGroups);
|
|
827
|
+
} catch (err) {
|
|
828
|
+
rethrowIfProcessExit(err);
|
|
829
|
+
console.error("\u67E5\u8BE2\u5546\u54C1\u5931\u8D25:", err.message);
|
|
830
|
+
process.exit(1);
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
);
|
|
834
|
+
}
|
|
835
|
+
|
|
907
836
|
// src/commands/publish-tt-flow.ts
|
|
908
837
|
function parsePositiveInt(value, optionName, defaultValue) {
|
|
909
838
|
const parsed = parseInt(value ?? `${defaultValue}`, 10);
|
|
@@ -953,7 +882,6 @@ function register8(cli2) {
|
|
|
953
882
|
intervalSec,
|
|
954
883
|
maxPolls
|
|
955
884
|
);
|
|
956
|
-
const warnings = [];
|
|
957
885
|
const videoId = status.postIds[0] ?? null;
|
|
958
886
|
let query = null;
|
|
959
887
|
if (status.finalStatus === "PUBLISH_COMPLETE" && videoId) {
|
|
@@ -965,18 +893,16 @@ function register8(cli2) {
|
|
|
965
893
|
queryMaxAttempts
|
|
966
894
|
);
|
|
967
895
|
query = queryResult.query;
|
|
968
|
-
|
|
896
|
+
for (const warning of queryResult.warnings) {
|
|
897
|
+
console.warn(warning.message);
|
|
898
|
+
}
|
|
969
899
|
}
|
|
970
|
-
|
|
971
|
-
flowType: "tt",
|
|
900
|
+
printResult({
|
|
972
901
|
upload,
|
|
973
902
|
publish,
|
|
974
|
-
status,
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
warnings
|
|
978
|
-
};
|
|
979
|
-
printResult(result);
|
|
903
|
+
status: status.raw,
|
|
904
|
+
query
|
|
905
|
+
});
|
|
980
906
|
if (status.finalStatus === "FAILED") {
|
|
981
907
|
process.exit(1);
|
|
982
908
|
}
|
|
@@ -1059,58 +985,62 @@ function register9(cli2) {
|
|
|
1059
985
|
);
|
|
1060
986
|
try {
|
|
1061
987
|
console.log("\u5F00\u59CB\u6267\u884C TTS \u5B8C\u6574\u53D1\u5E03\u6D41\u7A0B...");
|
|
1062
|
-
console.log("1/4 \u6B63\u5728\u67E5\u8BE2\u5546\u54C1\u5217\u8868...");
|
|
1063
|
-
const productPool = await fetchProductPool(
|
|
1064
|
-
options.creatorId,
|
|
1065
|
-
productType,
|
|
1066
|
-
pageSize,
|
|
1067
|
-
maxProductPages
|
|
1068
|
-
);
|
|
1069
|
-
const warnings = [];
|
|
1070
|
-
if (productPool.summary.reachedPageLimit && productPool.summary.nextCursor) {
|
|
1071
|
-
warnings.push({
|
|
1072
|
-
code: "PRODUCT_SCAN_LIMIT_REACHED",
|
|
1073
|
-
message: `\u5546\u54C1\u626B\u63CF\u5DF2\u8FBE\u5230\u9875\u6570\u4E0A\u9650 ${maxProductPages}\uFF0C\u4ECD\u5B58\u5728\u672A\u62C9\u53D6\u5206\u9875`
|
|
1074
|
-
});
|
|
1075
|
-
}
|
|
1076
|
-
if (productPool.summary.failedSources.length > 0) {
|
|
1077
|
-
warnings.push({
|
|
1078
|
-
code: "PRODUCT_SOURCE_PARTIAL_FAILURE",
|
|
1079
|
-
message: `\u4EE5\u4E0B\u5546\u54C1\u6E90\u8BF7\u6C42\u5931\u8D25: ${productPool.summary.failedSources.join(", ")}\uFF0C\u5546\u54C1\u6C60\u53EF\u80FD\u4E0D\u5B8C\u6574`
|
|
1080
|
-
});
|
|
1081
|
-
}
|
|
1082
|
-
if (productPool.products.length === 0) {
|
|
1083
|
-
console.error("TTS \u5B8C\u6574\u53D1\u5E03\u6D41\u7A0B\u5931\u8D25: \u5F53\u524D\u5546\u54C1\u6C60\u4E3A\u7A7A\uFF0C\u65E0\u6CD5\u9009\u62E9\u5546\u54C1");
|
|
1084
|
-
process.exit(1);
|
|
1085
|
-
}
|
|
1086
|
-
let selectionMode = "automatic";
|
|
1087
988
|
let selectedProduct;
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
989
|
+
let queriedProducts = null;
|
|
990
|
+
if (options.productId && options.productTitle) {
|
|
991
|
+
console.log("1/4 \u5DF2\u624B\u52A8\u6307\u5B9A\u5546\u54C1\uFF0C\u8DF3\u8FC7\u5546\u54C1\u67E5\u8BE2...");
|
|
992
|
+
selectedProduct = buildManualProduct(options.productId, options.productTitle);
|
|
993
|
+
} else {
|
|
994
|
+
console.log("1/4 \u6B63\u5728\u67E5\u8BE2\u5546\u54C1\u5217\u8868...");
|
|
995
|
+
const productPool = await fetchProductPool(
|
|
996
|
+
options.creatorId,
|
|
997
|
+
productType,
|
|
998
|
+
pageSize,
|
|
999
|
+
maxProductPages
|
|
1092
1000
|
);
|
|
1093
|
-
|
|
1094
|
-
if (
|
|
1095
|
-
console.
|
|
1096
|
-
|
|
1001
|
+
queriedProducts = productPool.rawGroups;
|
|
1002
|
+
if (productPool.summary.reachedPageLimit && productPool.summary.nextCursor) {
|
|
1003
|
+
console.warn(`\u5546\u54C1\u626B\u63CF\u5DF2\u8FBE\u5230\u9875\u6570\u4E0A\u9650 ${maxProductPages}\uFF0C\u4ECD\u5B58\u5728\u672A\u62C9\u53D6\u5206\u9875`);
|
|
1004
|
+
}
|
|
1005
|
+
if (productPool.summary.failedSources.length > 0) {
|
|
1006
|
+
console.warn(
|
|
1007
|
+
`\u4EE5\u4E0B\u5546\u54C1\u6E90\u8BF7\u6C42\u5931\u8D25: ${productPool.summary.failedSources.join(", ")}\uFF0C\u5546\u54C1\u6C60\u53EF\u80FD\u4E0D\u5B8C\u6574`
|
|
1097
1008
|
);
|
|
1098
|
-
process.exit(1);
|
|
1099
1009
|
}
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1010
|
+
if (options.productId) {
|
|
1011
|
+
const matchedProduct = productPool.products.find(
|
|
1012
|
+
(product) => product.id === options.productId
|
|
1013
|
+
);
|
|
1014
|
+
const resolvedTitle = matchedProduct?.title;
|
|
1015
|
+
if (!resolvedTitle) {
|
|
1016
|
+
console.error(
|
|
1017
|
+
"\u9519\u8BEF: \u624B\u52A8\u6307\u5B9A --product-id \u65F6\uFF0C\u5982\u65E0\u6CD5\u4ECE\u5DF2\u626B\u63CF\u5546\u54C1\u6C60\u8865\u9F50\u6807\u9898\uFF0C\u5219\u5FC5\u987B\u663E\u5F0F\u4F20\u5165 --product-title"
|
|
1018
|
+
);
|
|
1019
|
+
process.exit(1);
|
|
1020
|
+
}
|
|
1021
|
+
selectedProduct = buildManualProduct(options.productId, resolvedTitle, matchedProduct);
|
|
1022
|
+
} else if (options.interactive) {
|
|
1023
|
+
if (productPool.products.length === 0) {
|
|
1024
|
+
console.error("TTS \u5B8C\u6574\u53D1\u5E03\u6D41\u7A0B\u5931\u8D25: \u5F53\u524D\u5546\u54C1\u6C60\u4E3A\u7A7A\uFF0C\u65E0\u6CD5\u9009\u62E9\u5546\u54C1");
|
|
1025
|
+
process.exit(1);
|
|
1026
|
+
}
|
|
1027
|
+
console.log("2/4 \u8BF7\u9009\u62E9\u8981\u6302\u8F66\u7684\u5546\u54C1...");
|
|
1028
|
+
selectedProduct = await promptForProductSelection(productPool.products);
|
|
1029
|
+
} else {
|
|
1030
|
+
if (productPool.products.length === 0) {
|
|
1031
|
+
console.error("TTS \u5B8C\u6574\u53D1\u5E03\u6D41\u7A0B\u5931\u8D25: \u5F53\u524D\u5546\u54C1\u6C60\u4E3A\u7A7A\uFF0C\u65E0\u6CD5\u9009\u62E9\u5546\u54C1");
|
|
1032
|
+
process.exit(1);
|
|
1033
|
+
}
|
|
1034
|
+
console.log("2/4 \u6B63\u5728\u81EA\u52A8\u9009\u62E9\u5546\u54C1\uFF08\u6309\u9500\u91CF\u6700\u9AD8\u4F18\u5148\uFF09...");
|
|
1035
|
+
const publishable = sortProductsForSelection(productPool.products);
|
|
1036
|
+
if (publishable.length === 0) {
|
|
1037
|
+
console.error(
|
|
1038
|
+
"TTS \u5B8C\u6574\u53D1\u5E03\u6D41\u7A0B\u5931\u8D25: \u5546\u54C1\u6C60\u4E2D\u6CA1\u6709\u53EF\u53D1\u5E03\u5546\u54C1\uFF08\u5BA1\u6838\u672A\u901A\u8FC7\u6216\u65E0\u5E93\u5B58\uFF09\uFF0C\u5982\u9700\u5F3A\u5236\u6307\u5B9A\u8BF7\u4F7F\u7528 --product-id/--product-title"
|
|
1039
|
+
);
|
|
1040
|
+
process.exit(1);
|
|
1041
|
+
}
|
|
1042
|
+
selectedProduct = publishable[0];
|
|
1106
1043
|
}
|
|
1107
|
-
} else if (options.interactive) {
|
|
1108
|
-
selectionMode = "interactive";
|
|
1109
|
-
console.log("2/4 \u8BF7\u9009\u62E9\u8981\u6302\u8F66\u7684\u5546\u54C1...");
|
|
1110
|
-
selectedProduct = await promptForProductSelection(productPool.products);
|
|
1111
|
-
} else {
|
|
1112
|
-
console.log("2/4 \u6B63\u5728\u81EA\u52A8\u9009\u62E9\u5546\u54C1\uFF08\u6309\u9500\u91CF\u6700\u9AD8\u4F18\u5148\uFF09...");
|
|
1113
|
-
selectedProduct = sortProductsForSelection(productPool.products)[0];
|
|
1114
1044
|
}
|
|
1115
1045
|
console.log("3/4 \u6B63\u5728\u4E0A\u4F20\u6302\u8F66\u89C6\u9891...");
|
|
1116
1046
|
const upload = await uploadTtsVideo(options.file, options.creatorId, options.token);
|
|
@@ -1123,20 +1053,14 @@ function register9(cli2) {
|
|
|
1123
1053
|
options.caption
|
|
1124
1054
|
);
|
|
1125
1055
|
if (publishResult.productTitle !== selectedProduct.title) {
|
|
1126
|
-
|
|
1127
|
-
code: "PRODUCT_TITLE_TRUNCATED",
|
|
1128
|
-
message: "\u5546\u54C1\u6807\u9898\u8D85\u8FC7 29 \u5B57\u7B26\uFF0C\u53D1\u5E03\u65F6\u5DF2\u81EA\u52A8\u622A\u65AD"
|
|
1129
|
-
});
|
|
1056
|
+
console.warn("\u5546\u54C1\u6807\u9898\u8D85\u8FC7 29 \u5B57\u7B26\uFF0C\u53D1\u5E03\u65F6\u5DF2\u81EA\u52A8\u622A\u65AD");
|
|
1130
1057
|
}
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
selectedProduct: buildSelectedProductSummary(selectedProduct, selectionMode),
|
|
1058
|
+
printResult({
|
|
1059
|
+
products: queriedProducts,
|
|
1060
|
+
selectedProduct,
|
|
1135
1061
|
upload,
|
|
1136
|
-
publish: publishResult.publish
|
|
1137
|
-
|
|
1138
|
-
};
|
|
1139
|
-
printResult(result);
|
|
1062
|
+
publish: publishResult.publish
|
|
1063
|
+
});
|
|
1140
1064
|
} catch (err) {
|
|
1141
1065
|
rethrowIfProcessExit(err);
|
|
1142
1066
|
console.error("TTS \u5B8C\u6574\u53D1\u5E03\u6D41\u7A0B\u5931\u8D25:", err.message);
|
|
@@ -1187,7 +1111,7 @@ function register10(cli2) {
|
|
|
1187
1111
|
|
|
1188
1112
|
// src/cli.ts
|
|
1189
1113
|
var cli = cac("beervid");
|
|
1190
|
-
var cliVersion = true ? "0.2.
|
|
1114
|
+
var cliVersion = true ? "0.2.3" : pkg.version;
|
|
1191
1115
|
register10(cli);
|
|
1192
1116
|
register(cli);
|
|
1193
1117
|
register2(cli);
|