siluzan-tso-cli 1.1.29-beta.16 → 1.1.29-beta.17

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 CHANGED
@@ -51,7 +51,7 @@ siluzan-tso init -d /path/to/skills # 写入自定义目录
51
51
  siluzan-tso init --force # 强制覆盖已存在文件
52
52
  ```
53
53
 
54
- > **注意**:当前为测试版(1.1.29-beta.16),供内部测试使用。正式发布后安装命令将改为 `npm install -g siluzan-tso-cli`。
54
+ > **注意**:当前为测试版(1.1.29-beta.17),供内部测试使用。正式发布后安装命令将改为 `npm install -g siluzan-tso-cli`。
55
55
 
56
56
  | 助手 | 建议 `--ai` |
57
57
  | ----------------------- | ------------------------------------ |
package/dist/index.js CHANGED
@@ -4278,6 +4278,65 @@ var init_balance = __esm({
4278
4278
  }
4279
4279
  });
4280
4280
 
4281
+ // src/utils/media-account-batch.ts
4282
+ function mediaAccountDataBatchSize(media) {
4283
+ switch (media) {
4284
+ case "BingV2":
4285
+ case "TikTok":
4286
+ case "Yandex":
4287
+ return 10;
4288
+ case "Kwai":
4289
+ return 20;
4290
+ default:
4291
+ return 100;
4292
+ }
4293
+ }
4294
+ async function fetchBalanceAndOverviewSequential(opts) {
4295
+ const { media, accountIds, config, startDate, endDate, verbose } = opts;
4296
+ const balanceMap = /* @__PURE__ */ new Map();
4297
+ const overviewMap = /* @__PURE__ */ new Map();
4298
+ if (accountIds.length === 0) {
4299
+ return { balanceMap, overviewMap, chunkSize: mediaAccountDataBatchSize(media), chunkCount: 0 };
4300
+ }
4301
+ const chunkSize = mediaAccountDataBatchSize(media);
4302
+ const chunks = [];
4303
+ for (let i = 0; i < accountIds.length; i += chunkSize) {
4304
+ chunks.push(accountIds.slice(i, i + chunkSize));
4305
+ }
4306
+ for (let chunkIdx = 0; chunkIdx < chunks.length; chunkIdx++) {
4307
+ const ids = chunks[chunkIdx];
4308
+ const oneBased = chunkIdx + 1;
4309
+ opts.onChunkStart?.(oneBased, chunks.length, ids);
4310
+ const overviewChunk = await fetchOverviewMap(
4311
+ media,
4312
+ ids,
4313
+ config,
4314
+ startDate,
4315
+ endDate,
4316
+ verbose
4317
+ );
4318
+ opts.onOverviewDone?.(oneBased, chunks.length, ids, overviewChunk.size);
4319
+ for (const [k, v] of overviewChunk) overviewMap.set(k, v);
4320
+ const balanceChunk = await fetchBalanceMap(
4321
+ media,
4322
+ ids,
4323
+ config,
4324
+ startDate,
4325
+ endDate,
4326
+ verbose
4327
+ );
4328
+ opts.onBalanceDone?.(oneBased, chunks.length, ids, balanceChunk.size);
4329
+ for (const [k, v] of balanceChunk) balanceMap.set(k, v);
4330
+ }
4331
+ return { balanceMap, overviewMap, chunkSize, chunkCount: chunks.length };
4332
+ }
4333
+ var init_media_account_batch = __esm({
4334
+ "src/utils/media-account-batch.ts"() {
4335
+ "use strict";
4336
+ init_balance();
4337
+ }
4338
+ });
4339
+
4281
4340
  // src/commands/accounts-digest/list-fetch.ts
4282
4341
  async function fetchAccountsByMedia(media, config, opts) {
4283
4342
  const cfg = DIGEST_PLATFORM_CONFIG[media];
@@ -4426,30 +4485,47 @@ async function runAccountsDigest(opts) {
4426
4485
  }
4427
4486
  }
4428
4487
  const validIds = accountsList.filter((it) => it.ma?.mediaCustomerId && !it.ma?.invalidOAuthToken).map((it) => String(it.ma.mediaCustomerId));
4429
- const CHUNK = 100;
4430
- const chunks = [];
4431
- for (let i = 0; i < validIds.length; i += CHUNK) chunks.push(validIds.slice(i, i + CHUNK));
4432
- const balanceMap = /* @__PURE__ */ new Map();
4433
- const overviewMap = /* @__PURE__ */ new Map();
4434
- if (chunks.length > 0) {
4488
+ let balanceMap = /* @__PURE__ */ new Map();
4489
+ let overviewMap = /* @__PURE__ */ new Map();
4490
+ let batchChunkSize = null;
4491
+ if (validIds.length > 0) {
4435
4492
  process.stderr.write(
4436
- `\u23F3 \u62C9\u53D6\u4F59\u989D\u4E0E\u6D88\u8017\u6570\u636E\uFF08${validIds.length} \u4E2A\u8D26\u6237\uFF0C\u5206 ${chunks.length} \u6279\uFF09...
4493
+ `\u23F3 [accounts-digest] \u6709\u6548\u8D26\u6237 ${validIds.length} \u4E2A\uFF1B\u4E32\u884C\u62C9\u53D6\u6D88\u8017 \u2192 \u4F59\u989D\uFF08\u4E0E Web \u8D26\u6237\u5217\u8868\u5206\u6279\u53E3\u5F84\u4E00\u81F4\uFF09\u3002
4437
4494
  `
4438
4495
  );
4439
- const [bMaps, oMaps] = await Promise.all([
4440
- Promise.all(
4441
- chunks.map(
4442
- (ids) => fetchBalanceMap(media, ids, config, opts.startDate, opts.endDate, opts.verbose)
4443
- )
4444
- ),
4445
- Promise.all(
4446
- chunks.map(
4447
- (ids) => fetchOverviewMap(media, ids, config, opts.startDate, opts.endDate, opts.verbose)
4448
- )
4449
- )
4450
- ]);
4451
- for (const m of bMaps) for (const [k, v] of m) balanceMap.set(k, v);
4452
- for (const m of oMaps) for (const [k, v] of m) overviewMap.set(k, v);
4496
+ const fetched = await fetchBalanceAndOverviewSequential({
4497
+ media,
4498
+ accountIds: validIds,
4499
+ config,
4500
+ startDate: opts.startDate,
4501
+ endDate: opts.endDate,
4502
+ verbose: opts.verbose,
4503
+ onChunkStart: (chunkIdx, totalChunks, ids) => {
4504
+ process.stderr.write(
4505
+ ` \u2192 [\u6D88\u8017] \u7B2C ${chunkIdx}/${totalChunks} \u6279\uFF08${ids.length} \u6237\uFF09\u2026
4506
+ `
4507
+ );
4508
+ },
4509
+ onOverviewDone: (chunkIdx, totalChunks, ids, size) => {
4510
+ process.stderr.write(
4511
+ ` \u2713 [\u6D88\u8017] \u7B2C ${chunkIdx}/${totalChunks} \u6279\u5B8C\u6210\uFF08${ids.length} \u6237 \u2192 ${size} \u6761\uFF09
4512
+ `
4513
+ );
4514
+ process.stderr.write(
4515
+ ` \u2192 [\u4F59\u989D] \u7B2C ${chunkIdx}/${totalChunks} \u6279\uFF08${ids.length} \u6237\uFF09\u2026
4516
+ `
4517
+ );
4518
+ },
4519
+ onBalanceDone: (chunkIdx, totalChunks, ids, size) => {
4520
+ process.stderr.write(
4521
+ ` \u2713 [\u4F59\u989D] \u7B2C ${chunkIdx}/${totalChunks} \u6279\u5B8C\u6210\uFF08${ids.length} \u6237 \u2192 ${size} \u6761\uFF09
4522
+ `
4523
+ );
4524
+ }
4525
+ });
4526
+ balanceMap = fetched.balanceMap;
4527
+ overviewMap = fetched.overviewMap;
4528
+ batchChunkSize = fetched.chunkSize;
4453
4529
  }
4454
4530
  const rows = [];
4455
4531
  for (const item of accountsList) {
@@ -4505,6 +4581,7 @@ async function runAccountsDigest(opts) {
4505
4581
  /** 取数策略:list = 全量翻清单后过滤,subset = 跳过翻页直接对 -a 指定的 ID 拉数据 */
4506
4582
  source: scannedFromList ? "list" : "subset",
4507
4583
  returned: rows.length,
4584
+ batchChunkSize: validIds.length > 0 ? batchChunkSize : null,
4508
4585
  totals: {
4509
4586
  spend: +totals.spend.toFixed(2),
4510
4587
  clicks: totals.clicks,
@@ -4581,6 +4658,7 @@ var init_run = __esm({
4581
4658
  init_balance();
4582
4659
  init_cli_table();
4583
4660
  init_currency_display();
4661
+ init_media_account_batch();
4584
4662
  init_list_fetch();
4585
4663
  }
4586
4664
  });
@@ -105251,6 +105329,7 @@ init_cli_json_snapshot();
105251
105329
  init_balance();
105252
105330
  init_cli_table();
105253
105331
  init_currency_display();
105332
+ init_media_account_batch();
105254
105333
 
105255
105334
  // src/commands/balance-scan/list-fetch.ts
105256
105335
  init_auth();
@@ -105394,18 +105473,6 @@ async function fetchAllAccountPages(media, pageSize, maxPages, config, verbose)
105394
105473
  }
105395
105474
 
105396
105475
  // src/commands/balance-scan/run.ts
105397
- function balanceScanChunkSize(media) {
105398
- switch (media) {
105399
- case "BingV2":
105400
- case "TikTok":
105401
- case "Yandex":
105402
- return 10;
105403
- case "Kwai":
105404
- return 20;
105405
- default:
105406
- return 100;
105407
- }
105408
- }
105409
105476
  async function runBalanceScan(opts) {
105410
105477
  let config = loadConfig(opts.token);
105411
105478
  if (opts.refreshDp) {
@@ -105463,53 +105530,44 @@ async function runBalanceScan(opts) {
105463
105530
  }
105464
105531
  let balanceMap = /* @__PURE__ */ new Map();
105465
105532
  let overviewMap = /* @__PURE__ */ new Map();
105533
+ let batchChunkSize = null;
105466
105534
  if (validIds.length > 0) {
105467
- const chunkSize = balanceScanChunkSize(media);
105468
- const chunks = [];
105469
- for (let i = 0; i < validIds.length; i += chunkSize) {
105470
- chunks.push(validIds.slice(i, i + chunkSize));
105471
- }
105535
+ const chunkSize = mediaAccountDataBatchSize(media);
105472
105536
  process.stderr.write(
105473
- `\u23F3 [balance-scan] \u6709\u6548\u8D26\u6237 ${validIds.length} \u4E2A\uFF0C\u5206 ${chunks.length} \u6279\uFF08\u6BCF\u6279 \u2264${chunkSize} \u6237\uFF09\uFF1B\u6309 Web \u8D26\u6237\u5217\u8868\u53E3\u5F84\u4E32\u884C\u62C9\u53D6\u6D88\u8017 \u2192 \u4F59\u989D\uFF08\u5355\u8BF7\u6C42\u6700\u957F\u7EA6 10 \u5206\u949F\uFF09\u3002
105537
+ `\u23F3 [balance-scan] \u6709\u6548\u8D26\u6237 ${validIds.length} \u4E2A\uFF1B\u6309 Web \u8D26\u6237\u5217\u8868\u53E3\u5F84\u4E32\u884C\u62C9\u53D6\u6D88\u8017 \u2192 \u4F59\u989D\uFF08\u6BCF\u6279 \u2264${chunkSize} \u6237\uFF0C\u5355\u8BF7\u6C42\u6700\u957F\u7EA6 10 \u5206\u949F\uFF09\u3002
105474
105538
  `
105475
105539
  );
105476
- for (let chunkIdx = 0; chunkIdx < chunks.length; chunkIdx++) {
105477
- const ids = chunks[chunkIdx];
105478
- process.stderr.write(
105479
- ` \u2192 [\u8FD17\u65E5\u6D88\u8017] \u7B2C ${chunkIdx + 1}/${chunks.length} \u6279\u8BF7\u6C42\u4E2D\uFF08${ids.length} \u6237\uFF09\u2026
105540
+ const fetched = await fetchBalanceAndOverviewSequential({
105541
+ media,
105542
+ accountIds: validIds,
105543
+ config,
105544
+ verbose: opts.verbose,
105545
+ onChunkStart: (chunkIdx, totalChunks, ids) => {
105546
+ process.stderr.write(
105547
+ ` \u2192 [\u8FD17\u65E5\u6D88\u8017] \u7B2C ${chunkIdx}/${totalChunks} \u6279\u8BF7\u6C42\u4E2D\uFF08${ids.length} \u6237\uFF09\u2026
105480
105548
  `
105481
- );
105482
- const overviewChunk = await fetchOverviewMap(
105483
- media,
105484
- ids,
105485
- config,
105486
- void 0,
105487
- void 0,
105488
- opts.verbose
105489
- );
105490
- process.stderr.write(
105491
- ` \u2713 [\u8FD17\u65E5\u6D88\u8017] \u7B2C ${chunkIdx + 1}/${chunks.length} \u6279\u5B8C\u6210\uFF08${ids.length} \u6237 \u2192 ${overviewChunk.size} \u6761\uFF09
105549
+ );
105550
+ },
105551
+ onOverviewDone: (chunkIdx, totalChunks, ids, size) => {
105552
+ process.stderr.write(
105553
+ ` \u2713 [\u8FD17\u65E5\u6D88\u8017] \u7B2C ${chunkIdx}/${totalChunks} \u6279\u5B8C\u6210\uFF08${ids.length} \u6237 \u2192 ${size} \u6761\uFF09
105492
105554
  `
105493
- );
105494
- for (const [k, v] of overviewChunk) overviewMap.set(k, v);
105495
- process.stderr.write(
105496
- ` \u2192 [\u4F59\u989D] \u7B2C ${chunkIdx + 1}/${chunks.length} \u6279\u8BF7\u6C42\u4E2D\uFF08${ids.length} \u6237\uFF09\u2026
105555
+ );
105556
+ process.stderr.write(
105557
+ ` \u2192 [\u4F59\u989D] \u7B2C ${chunkIdx}/${totalChunks} \u6279\u8BF7\u6C42\u4E2D\uFF08${ids.length} \u6237\uFF09\u2026
105497
105558
  `
105498
- );
105499
- const balanceChunk = await fetchBalanceMap(
105500
- media,
105501
- ids,
105502
- config,
105503
- void 0,
105504
- void 0,
105505
- opts.verbose
105506
- );
105507
- process.stderr.write(
105508
- ` \u2713 [\u4F59\u989D] \u7B2C ${chunkIdx + 1}/${chunks.length} \u6279\u5B8C\u6210\uFF08${ids.length} \u6237 \u2192 ${balanceChunk.size} \u6761\uFF09
105559
+ );
105560
+ },
105561
+ onBalanceDone: (chunkIdx, totalChunks, ids, size) => {
105562
+ process.stderr.write(
105563
+ ` \u2713 [\u4F59\u989D] \u7B2C ${chunkIdx}/${totalChunks} \u6279\u5B8C\u6210\uFF08${ids.length} \u6237 \u2192 ${size} \u6761\uFF09
105509
105564
  `
105510
- );
105511
- for (const [k, v] of balanceChunk) balanceMap.set(k, v);
105512
- }
105565
+ );
105566
+ }
105567
+ });
105568
+ balanceMap = fetched.balanceMap;
105569
+ overviewMap = fetched.overviewMap;
105570
+ batchChunkSize = fetched.chunkSize;
105513
105571
  process.stderr.write(`\u23F3 [balance-scan] \u4F59\u989D\u4E0E\u6D88\u8017\u5DF2\u9F50\uFF0C\u6B63\u5728\u6309\u9608\u503C\u7B5B\u9009\u2026
105514
105572
  `);
105515
105573
  }
@@ -105568,7 +105626,7 @@ async function runBalanceScan(opts) {
105568
105626
  },
105569
105627
  pageSize,
105570
105628
  maxPages,
105571
- batchChunkSize: validIds.length > 0 ? balanceScanChunkSize(media) : null,
105629
+ batchChunkSize: validIds.length > 0 ? batchChunkSize : null,
105572
105630
  totalReported: total ?? null,
105573
105631
  generatedAt: (/* @__PURE__ */ new Date()).toISOString()
105574
105632
  };
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "slug": "siluzan-tso",
3
- "version": "1.1.29-beta.16",
4
- "publishedAt": 1781686919463
3
+ "version": "1.1.29-beta.17",
4
+ "publishedAt": 1781748956615
5
5
  }
@@ -9,7 +9,7 @@ $ErrorActionPreference = 'Stop'
9
9
  # -- Package info (injected at build time) ------------------------------------
10
10
  $PKG_NAME = 'siluzan-tso-cli'
11
11
  # PKG_VERSION 锁定到与本脚本同批构建产物一致的版本,避免与 dist/skill 错位
12
- $PKG_VERSION = '1.1.29-beta.16'
12
+ $PKG_VERSION = '1.1.29-beta.17'
13
13
  $CLI_BIN = 'siluzan-tso'
14
14
  $SKILL_LABEL = 'Siluzan TSO'
15
15
  $INSTALL_CMD = 'npm install -g siluzan-tso-cli@beta'
@@ -9,7 +9,7 @@ set -euo pipefail
9
9
  # -- Package info (injected at build time) ------------------------------------
10
10
  readonly PKG_NAME="siluzan-tso-cli"
11
11
  # PKG_VERSION 锁定到与本脚本同批构建产物一致的版本,避免与 dist/skill 错位
12
- readonly PKG_VERSION="1.1.29-beta.16"
12
+ readonly PKG_VERSION="1.1.29-beta.17"
13
13
  readonly CLI_BIN="siluzan-tso"
14
14
  readonly SKILL_LABEL="Siluzan TSO"
15
15
  readonly INSTALL_CMD="npm install -g siluzan-tso-cli@beta"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "siluzan-tso-cli",
3
- "version": "1.1.29-beta.16",
3
+ "version": "1.1.29-beta.17",
4
4
  "description": "Siluzan 广告账户管理 CLI — 查询账户、余额、消耗数据,管理绑定关系与充值。",
5
5
  "keywords": [
6
6
  "ad-account",