@jiangzhx/adcli 0.1.3 → 0.1.4

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/cli.js CHANGED
@@ -2040,6 +2040,18 @@ function isNotFoundError(error) {
2040
2040
  return error instanceof Error && "code" in error && error.code === "ENOENT";
2041
2041
  }
2042
2042
 
2043
+ // src/lib/search/output.ts
2044
+ var defaultPublicDocsBaseUrl = "https://adcli.jiangzhx.com";
2045
+ function publicDocsUrl(publicPath, baseUrl = defaultPublicDocsBaseUrl) {
2046
+ return new URL(publicPath, baseUrl).toString();
2047
+ }
2048
+ function withPublicUrls(results) {
2049
+ return results.map((result) => ({
2050
+ ...result,
2051
+ public_url: publicDocsUrl(result.public_path)
2052
+ }));
2053
+ }
2054
+
2043
2055
  // node_modules/.bun/minisearch@7.2.0/node_modules/minisearch/dist/es/index.js
2044
2056
  var ENTRIES = "ENTRIES";
2045
2057
  var KEYS = "KEYS";
@@ -3308,33 +3320,59 @@ function compact(value) {
3308
3320
  return value.toLowerCase().replace(/\s+/g, "");
3309
3321
  }
3310
3322
 
3311
- // packages/oceanengine-ad-open-sdk/dist/runtime/ApiException.js
3312
- class ApiException extends Error {
3313
- statusCode;
3314
- responseBody;
3315
- headers;
3316
- constructor(message, options = {}) {
3317
- super(message);
3318
- this.name = "ApiException";
3319
- this.statusCode = options.statusCode;
3320
- this.responseBody = options.responseBody;
3321
- this.headers = options.headers;
3323
+ // packages/oceanengine-ad-open-sdk/dist/api/client.js
3324
+ var import_json_bigint = __toESM(require_json_bigint(), 1);
3325
+
3326
+ // packages/oceanengine-ad-open-sdk/dist/config/configuration.js
3327
+ class Configuration {
3328
+ host = "api.oceanengine.com";
3329
+ scheme = "https";
3330
+ defaultHeaders = new Map;
3331
+ userAgent = "Bytedance Ads Openapi SDK";
3332
+ debug = false;
3333
+ logEnable = false;
3334
+ useLogMw = true;
3335
+ constructor(options = {}) {
3336
+ if (options.host) {
3337
+ this.host = options.host;
3338
+ }
3339
+ if (options.scheme) {
3340
+ this.scheme = options.scheme;
3341
+ }
3342
+ if (options.userAgent) {
3343
+ this.userAgent = options.userAgent;
3344
+ }
3345
+ if (options.debug != null) {
3346
+ this.debug = options.debug;
3347
+ }
3348
+ if (options.logEnable != null) {
3349
+ this.logEnable = options.logEnable;
3350
+ }
3351
+ if (options.useLogMw != null) {
3352
+ this.useLogMw = options.useLogMw;
3353
+ }
3354
+ for (const [name, value] of Object.entries(options.defaultHeaders ?? {})) {
3355
+ this.defaultHeaders.set(name, value);
3356
+ }
3357
+ }
3358
+ addDefaultHeader(name, value) {
3359
+ this.defaultHeaders.set(name, value);
3360
+ }
3361
+ getBasePath() {
3362
+ return `${this.scheme}://${this.host}`;
3322
3363
  }
3323
3364
  }
3324
-
3325
- // packages/oceanengine-ad-open-sdk/dist/runtime/json.js
3326
- var import_json_bigint = __toESM(require_json_bigint(), 1);
3327
- var JSONBigStringParser = import_json_bigint.default({ storeAsString: true });
3328
- function parseJsonPreservingLargeIntegers(text) {
3329
- return JSONBigStringParser.parse(text);
3365
+ function NewConfiguration() {
3366
+ return new Configuration;
3330
3367
  }
3368
+ var DefaultConfiguration = NewConfiguration();
3331
3369
 
3332
- // packages/oceanengine-ad-open-sdk/dist/runtime/sdk-version.js
3333
- var SDK_VERSION = "1.1.87";
3370
+ // packages/oceanengine-ad-open-sdk/dist/api/client.js
3371
+ var JSONBigStringParser = import_json_bigint.default({ storeAsString: true });
3372
+ var SDK_VERSION = "1.1.88";
3334
3373
 
3335
- // packages/oceanengine-ad-open-sdk/dist/runtime/ApiClient.js
3336
3374
  class ApiClient {
3337
- basePath = "https://api.oceanengine.com";
3375
+ basePath = DefaultConfiguration.getBasePath();
3338
3376
  fetchImpl;
3339
3377
  defaultHeaders = new Headers;
3340
3378
  constructor(options = {}) {
@@ -3342,9 +3380,12 @@ class ApiClient {
3342
3380
  if (options.basePath) {
3343
3381
  this.basePath = options.basePath;
3344
3382
  }
3345
- this.setUserAgent("Bytedance Ads Openapi SDK");
3383
+ this.setUserAgent(DefaultConfiguration.userAgent);
3346
3384
  this.addDefaultHeader("X-Sdk-Language", "node");
3347
3385
  this.addDefaultHeader("X-Sdk-Version", SDK_VERSION);
3386
+ for (const [name, value] of DefaultConfiguration.defaultHeaders) {
3387
+ this.addDefaultHeader(name, value);
3388
+ }
3348
3389
  }
3349
3390
  getBasePath() {
3350
3391
  return this.basePath;
@@ -3366,7 +3407,9 @@ class ApiClient {
3366
3407
  return this;
3367
3408
  }
3368
3409
  buildUrl(path3, queryParams = []) {
3369
- const url = new URL(path3, this.basePath);
3410
+ const basePath = this.basePath.endsWith("/") ? this.basePath : `${this.basePath}/`;
3411
+ const relativePath = path3.startsWith("/") ? path3.slice(1) : path3;
3412
+ const url = new URL(relativePath, basePath);
3370
3413
  for (const param of queryParams) {
3371
3414
  if (param.value == null) {
3372
3415
  continue;
@@ -3378,10 +3421,11 @@ class ApiClient {
3378
3421
  }
3379
3422
  continue;
3380
3423
  }
3381
- if (param.collectionFormat !== "csv") {
3382
- throw new ApiException(`Unsupported collection format for query parameter '${param.name}'`);
3424
+ if (param.collectionFormat === "csv") {
3425
+ url.searchParams.append(param.name, param.value.map((value) => this.parameterToString(value)).join(","));
3426
+ continue;
3383
3427
  }
3384
- url.searchParams.append(param.name, param.value.map((value) => this.parameterToString(value)).join(","));
3428
+ url.searchParams.append(param.name, this.parameterToString(param.value));
3385
3429
  continue;
3386
3430
  }
3387
3431
  url.searchParams.append(param.name, this.parameterToString(param.value));
@@ -3483,7 +3527,24 @@ class ApiClient {
3483
3527
  return String(value);
3484
3528
  }
3485
3529
  }
3486
- // packages/oceanengine-ad-open-sdk/dist/apis/Oauth2AdvertiserGetApi.js
3530
+
3531
+ class ApiException extends Error {
3532
+ statusCode;
3533
+ responseBody;
3534
+ headers;
3535
+ constructor(message, options = {}) {
3536
+ super(message);
3537
+ this.name = "ApiException";
3538
+ this.statusCode = options.statusCode;
3539
+ this.responseBody = options.responseBody;
3540
+ this.headers = options.headers;
3541
+ }
3542
+ }
3543
+ function parseJsonPreservingLargeIntegers(text) {
3544
+ return JSONBigStringParser.parse(text);
3545
+ }
3546
+
3547
+ // packages/oceanengine-ad-open-sdk/dist/api/api_oauth2_advertiser_get.js
3487
3548
  class Oauth2AdvertiserGetApi {
3488
3549
  apiClient;
3489
3550
  constructor(apiClient = new ApiClient) {
@@ -3510,7 +3571,7 @@ class Oauth2AdvertiserGetApi {
3510
3571
  }
3511
3572
  }
3512
3573
 
3513
- // packages/oceanengine-ad-open-sdk/dist/apis/ProjectListV30Api.js
3574
+ // packages/oceanengine-ad-open-sdk/dist/api/api_project_list_v30.js
3514
3575
  class ProjectListV30Api {
3515
3576
  apiClient;
3516
3577
  constructor(apiClient = new ApiClient) {
@@ -3528,13 +3589,13 @@ class ProjectListV30Api {
3528
3589
  }
3529
3590
  async openApiV30ProjectListGetWithHttpInfo(request) {
3530
3591
  if (request.advertiserId == null) {
3531
- throw new ApiException("Missing the required parameter 'advertiserId' when calling openApiV30ProjectListGet");
3592
+ throw new ApiException("advertiserId is required and must be specified");
3532
3593
  }
3533
3594
  return this.apiClient.requestWithHttpInfo({
3534
3595
  method: "GET",
3535
3596
  path: "/open_api/v3.0/project/list/",
3536
3597
  queryParams: [
3537
- { name: "fields", value: request.fields, collectionFormat: "csv" },
3598
+ { name: "fields", value: request.fields },
3538
3599
  { name: "filtering", value: request.filtering },
3539
3600
  { name: "advertiser_id", value: request.advertiserId },
3540
3601
  { name: "page", value: request.page },
@@ -3544,7 +3605,7 @@ class ProjectListV30Api {
3544
3605
  }
3545
3606
  }
3546
3607
 
3547
- // packages/oceanengine-ad-open-sdk/dist/apis/PromotionListV30Api.js
3608
+ // packages/oceanengine-ad-open-sdk/dist/api/api_promotion_list_v30.js
3548
3609
  class PromotionListV30Api {
3549
3610
  apiClient;
3550
3611
  constructor(apiClient = new ApiClient) {
@@ -3562,7 +3623,10 @@ class PromotionListV30Api {
3562
3623
  }
3563
3624
  async openApiV30PromotionListGetWithHttpInfo(request) {
3564
3625
  if (request.advertiserId == null) {
3565
- throw new ApiException("Missing the required parameter 'advertiserId' when calling openApiV30PromotionListGet");
3626
+ throw new ApiException("advertiserId is required and must be specified");
3627
+ }
3628
+ if (request.advertiserId != null && Number(request.advertiserId) < 1) {
3629
+ throw new ApiException("advertiserId must be greater than 1");
3566
3630
  }
3567
3631
  return this.apiClient.requestWithHttpInfo({
3568
3632
  method: "GET",
@@ -3570,7 +3634,7 @@ class PromotionListV30Api {
3570
3634
  queryParams: [
3571
3635
  { name: "advertiser_id", value: request.advertiserId },
3572
3636
  { name: "filtering", value: request.filtering },
3573
- { name: "fields", value: request.fields, collectionFormat: "csv" },
3637
+ { name: "fields", value: request.fields },
3574
3638
  { name: "including_material_atrributes", value: request.includingMaterialAtrributes },
3575
3639
  { name: "page", value: request.page },
3576
3640
  { name: "page_size", value: request.pageSize },
@@ -3580,6 +3644,7 @@ class PromotionListV30Api {
3580
3644
  });
3581
3645
  }
3582
3646
  }
3647
+
3583
3648
  // src/commands/oceanengine/config.ts
3584
3649
  import { chmod, mkdir as mkdir2, readFile as readFile2, rename as rename2, writeFile as writeFile2 } from "node:fs/promises";
3585
3650
  import path3 from "node:path";
@@ -3681,6 +3746,9 @@ function formatOceanEngineOutput(payload, json, argv = []) {
3681
3746
  if (isOceanEngineErrorPayload(payload)) {
3682
3747
  return JSON.stringify(payload, null, 2);
3683
3748
  }
3749
+ if (argv[0] === "advertiser" && argv[1] === "list") {
3750
+ return formatEntityList(payload, "advertiser_id", ["advertiser_id", "id"], ["advertiser_name", "name"]);
3751
+ }
3684
3752
  if (argv[0] === "project" && argv[1] === "list") {
3685
3753
  return formatEntityList(payload, "project_id", ["project_id", "id"], ["name", "project_name"]);
3686
3754
  }
@@ -3832,87 +3900,1016 @@ function isOceanEngineErrorPayload(payload) {
3832
3900
  return isRecord(payload) && typeof payload.code === "number" && payload.code !== 0;
3833
3901
  }
3834
3902
 
3835
- // src/cli.ts
3836
- var help = `adcli
3837
-
3838
- Usage:
3839
- adcli list [platform] [--json]
3840
- adcli doc <command>
3841
- adcli oceanengine <resource> <command>
3842
- adcli prompt
3843
- adcli llms
3844
-
3845
- Commands:
3846
- list List supported advertising platforms and capabilities
3847
- doc Search and sync published advertising API docs
3848
- oceanengine Call OceanEngine APIs through the generated Node.js SDK
3849
- prompt Print an AI/Agent instruction prompt for using the docs pack
3850
- llms Print LLM-readable docs pack entry URLs
3851
- `;
3852
- var docHelp = `adcli doc
3853
-
3854
- Usage:
3855
- adcli doc search <query> [--platform tencent_ads] [--limit 10] [--json] [--refresh]
3856
- adcli doc sync
3903
+ // packages/tencent-ads-marketing-api-sdk/dist/api/v3/client.js
3904
+ var import_json_bigint2 = __toESM(require_json_bigint(), 1);
3857
3905
 
3858
- Commands:
3859
- search Search published advertising API docs
3860
- sync Download and cache the latest search index
3861
- `;
3862
- var oceanEngineHelp = `adcli oceanengine
3906
+ // packages/tencent-ads-marketing-api-sdk/dist/config/v3/configuration.js
3907
+ class Configuration2 {
3908
+ basePath = "https://api.e.qq.com/v3.0";
3909
+ defaultHeaders = new Map;
3910
+ userAgent = "Tencent Ads Marketing API SDK";
3911
+ constructor(options = {}) {
3912
+ if (options.basePath) {
3913
+ this.basePath = options.basePath;
3914
+ }
3915
+ if (options.userAgent) {
3916
+ this.userAgent = options.userAgent;
3917
+ }
3918
+ for (const [name, value] of Object.entries(options.defaultHeaders ?? {})) {
3919
+ this.defaultHeaders.set(name, value);
3920
+ }
3921
+ }
3922
+ addDefaultHeader(name, value) {
3923
+ this.defaultHeaders.set(name, value);
3924
+ }
3925
+ }
3926
+ function NewConfiguration2() {
3927
+ return new Configuration2;
3928
+ }
3929
+ var DefaultConfiguration2 = NewConfiguration2();
3863
3930
 
3864
- Usage:
3865
- adcli oceanengine auth <token>
3866
- adcli oceanengine advertiser list [--access-token token] [--json]
3867
- adcli oceanengine project list --advertiser-id 123 [--access-token token] [--page 1] [--page-size 20] [--filtering '{"status":"PROJECT_STATUS_ALL"}'] [--json]
3868
- adcli oceanengine promotion list --advertiser-id 123 [--access-token token] [--project-id 456] [--fields promotion_id,name,status_first] [--filtering '{}'] [--json]
3931
+ // packages/tencent-ads-marketing-api-sdk/dist/api/v3/client.js
3932
+ var JSONBigStringParser2 = import_json_bigint2.default({ storeAsString: true });
3933
+ var SDK_VERSION2 = "1.7.85";
3869
3934
 
3870
- Environment:
3871
- Token precedence is --access-token, OCEANENGINE_ACCESS_TOKEN, then the saved token.
3872
- Project list does not include deleted projects by default; use filtering status PROJECT_STATUS_ALL for all projects.
3873
- `;
3874
- async function main() {
3875
- const args = parseArgs(process.argv.slice(2));
3876
- if (!args.domain || args.domain === "help" || args.domain === "--help" || args.domain === "-h") {
3877
- console.log(help.trim());
3878
- return;
3935
+ class ApiClient2 {
3936
+ basePath = DefaultConfiguration2.basePath;
3937
+ fetchImpl;
3938
+ accessToken;
3939
+ userToken;
3940
+ defaultHeaders = new Headers;
3941
+ constructor(options = {}) {
3942
+ this.fetchImpl = options.fetch ?? fetch;
3943
+ if (options.basePath) {
3944
+ this.basePath = options.basePath;
3945
+ }
3946
+ this.setUserAgent("Tencent Ads Marketing API SDK");
3947
+ this.addDefaultHeader("X-Sdk-Language", "node");
3948
+ this.addDefaultHeader("X-Sdk-Version", SDK_VERSION2);
3879
3949
  }
3880
- if (args.domain === "list") {
3881
- const index2 = await loadSearchIndex({ index: args.index, refresh: args.refresh });
3882
- printDocList(index2, args);
3883
- return;
3950
+ getBasePath() {
3951
+ return this.basePath;
3884
3952
  }
3885
- if (args.domain === "doc" && (!args.command || args.command === "--help" || args.command === "-h" || args.command === "help")) {
3886
- console.log(docHelp.trim());
3887
- return;
3953
+ setBasePath(basePath) {
3954
+ this.basePath = basePath;
3955
+ return this;
3888
3956
  }
3889
- if (args.domain === "doc" && args.command === "sync") {
3890
- const index2 = await refreshSearchIndex();
3891
- const cache = getSearchIndexCacheInfo();
3892
- console.log(`Synced ${index2.documents.length} docs to ${cache.cachePath}`);
3893
- return;
3957
+ setUserAgent(userAgent) {
3958
+ this.addDefaultHeader("User-Agent", userAgent);
3959
+ return this;
3894
3960
  }
3895
- if (args.domain === "doc" && args.command === "list") {
3896
- const index2 = await loadSearchIndex({ index: args.index, refresh: args.refresh });
3897
- printDocList(index2, args);
3898
- return;
3961
+ addDefaultHeader(name, value) {
3962
+ this.defaultHeaders.set(name, value);
3963
+ return this;
3899
3964
  }
3900
- if (args.domain === "prompt") {
3901
- printLlms({ ...args, domain: "llms", command: "prompt" });
3902
- return;
3965
+ setAccessToken(token) {
3966
+ this.accessToken = token;
3967
+ this.addDefaultHeader("Access-Token", token);
3968
+ return this;
3903
3969
  }
3904
- if (args.domain === "llms") {
3905
- printLlms(args);
3906
- return;
3970
+ setUserToken(token) {
3971
+ this.userToken = token;
3972
+ return this;
3907
3973
  }
3908
- if (args.domain === "oceanengine") {
3909
- if (!args.command || args.command === "--help" || args.command === "-h" || args.command === "help") {
3910
- console.log(oceanEngineHelp.trim());
3974
+ buildUrl(path4, queryParams = [], basePathOverride) {
3975
+ const requestBasePath = basePathOverride ?? this.basePath;
3976
+ const basePath = requestBasePath.endsWith("/") ? requestBasePath : `${requestBasePath}/`;
3977
+ const relativePath = path4.startsWith("/") ? path4.slice(1) : path4;
3978
+ const url = new URL(relativePath, basePath);
3979
+ for (const param of queryParams) {
3980
+ if (param.value == null) {
3981
+ continue;
3982
+ }
3983
+ if (Array.isArray(param.value)) {
3984
+ if (param.collectionFormat === "multi") {
3985
+ url.searchParams.append(param.name, JSON.stringify(param.value));
3986
+ continue;
3987
+ }
3988
+ if (param.collectionFormat !== "csv") {
3989
+ throw new ApiException2(`Unsupported collection format for query parameter '${param.name}'`);
3990
+ }
3991
+ url.searchParams.append(param.name, param.value.map((value) => this.parameterToString(value)).join(","));
3992
+ continue;
3993
+ }
3994
+ url.searchParams.append(param.name, this.parameterToString(param.value));
3995
+ }
3996
+ this.applyAuthQueryParams(url);
3997
+ return url;
3998
+ }
3999
+ async request(options) {
4000
+ const response = await this.requestWithHttpInfo(options);
4001
+ return response.data;
4002
+ }
4003
+ async requestWithHttpInfo(options) {
4004
+ const request = this.buildRequest(options);
4005
+ const response = await this.fetchImpl(request);
4006
+ const responseBody = await this.readResponseBody(response, options.responseType);
4007
+ if (!response.ok) {
4008
+ throw new ApiException2(`HTTP ${response.status}`, {
4009
+ statusCode: response.status,
4010
+ responseBody,
4011
+ headers: response.headers
4012
+ });
4013
+ }
4014
+ return {
4015
+ data: this.unwrapResponseData(responseBody, options.responseType),
4016
+ statusCode: response.status,
4017
+ headers: response.headers
4018
+ };
4019
+ }
4020
+ buildRequest(options) {
4021
+ const headers = new Headers(this.defaultHeaders);
4022
+ for (const [name, value] of Object.entries(options.headers ?? {})) {
4023
+ headers.set(name, value);
4024
+ }
4025
+ if (!headers.has("Accept")) {
4026
+ headers.set("Accept", "application/json");
4027
+ }
4028
+ if (options.contentType && options.contentType !== "multipart/form-data") {
4029
+ headers.set("Content-Type", options.contentType);
4030
+ }
4031
+ let body;
4032
+ if (options.method !== "GET" && (options.formParams || options.files)) {
4033
+ const contentType = options.contentType ?? "application/x-www-form-urlencoded";
4034
+ if (contentType === "multipart/form-data") {
4035
+ body = this.buildMultipartFormBody(options.formParams, options.files);
4036
+ } else if (contentType === "application/x-www-form-urlencoded") {
4037
+ headers.set("Content-Type", contentType);
4038
+ const formBody = new URLSearchParams;
4039
+ for (const [name, value] of Object.entries(options.formParams ?? {})) {
4040
+ if (value != null) {
4041
+ formBody.append(name, this.parameterToString(value));
4042
+ }
4043
+ }
4044
+ body = formBody;
4045
+ } else {
4046
+ throw new ApiException2(`Unsupported form content type '${contentType}'`);
4047
+ }
4048
+ } else if (options.method !== "GET" && options.body != null) {
4049
+ const contentType = options.contentType ?? "application/json";
4050
+ headers.set("Content-Type", contentType);
4051
+ body = contentType === "application/json" ? JSON.stringify(options.body) : String(options.body);
4052
+ }
4053
+ return new Request(this.buildUrl(options.path, options.queryParams, options.basePath), {
4054
+ method: options.method,
4055
+ headers,
4056
+ body
4057
+ });
4058
+ }
4059
+ buildMultipartFormBody(formParams = {}, files = {}) {
4060
+ const formBody = new FormData;
4061
+ for (const [name, value] of Object.entries(formParams)) {
4062
+ if (value != null) {
4063
+ formBody.append(name, this.parameterToString(value));
4064
+ }
4065
+ }
4066
+ for (const [name, value] of Object.entries(files)) {
4067
+ if (value != null) {
4068
+ formBody.append(name, value);
4069
+ }
4070
+ }
4071
+ return formBody;
4072
+ }
4073
+ async readResponseBody(response, responseType = "json") {
4074
+ if (responseType === "arrayBuffer") {
4075
+ return response.arrayBuffer();
4076
+ }
4077
+ const text = await response.text();
4078
+ if (!text) {
3911
4079
  return;
3912
4080
  }
3913
- const oceanEngineArgv = [args.command, ...args.query];
3914
- const payload = await runOceanEngineCommand(oceanEngineArgv);
3915
- console.log(formatOceanEngineOutput(payload, args.json, oceanEngineArgv));
4081
+ if (responseType === "text") {
4082
+ return text;
4083
+ }
4084
+ const contentType = response.headers.get("Content-Type") ?? "";
4085
+ if (contentType.includes("application/json")) {
4086
+ return parseJsonPreservingLargeIntegers2(text);
4087
+ }
4088
+ return text;
4089
+ }
4090
+ unwrapResponseData(responseBody, responseType = "json") {
4091
+ if (responseType !== "json" || !isRecord2(responseBody) || typeof responseBody.code !== "number") {
4092
+ return responseBody;
4093
+ }
4094
+ if (responseBody.code !== 0) {
4095
+ throw new ApiException2(getApiErrorMessage(responseBody), {
4096
+ responseBody
4097
+ });
4098
+ }
4099
+ return responseBody.data;
4100
+ }
4101
+ parameterToString(value) {
4102
+ if (value instanceof Date) {
4103
+ return value.toISOString();
4104
+ }
4105
+ if (typeof value === "object" && value !== null) {
4106
+ return JSON.stringify(value);
4107
+ }
4108
+ return String(value);
4109
+ }
4110
+ applyAuthQueryParams(url) {
4111
+ if (!this.accessToken) {
4112
+ return;
4113
+ }
4114
+ url.searchParams.set("access_token", this.accessToken);
4115
+ url.searchParams.set("timestamp", Math.floor(Date.now() / 1000).toString());
4116
+ url.searchParams.set("nonce", createNonce());
4117
+ if (this.userToken) {
4118
+ url.searchParams.set("user_token", this.userToken);
4119
+ }
4120
+ }
4121
+ }
4122
+
4123
+ class ApiException2 extends Error {
4124
+ statusCode;
4125
+ responseBody;
4126
+ headers;
4127
+ constructor(message, options = {}) {
4128
+ super(message);
4129
+ this.name = "ApiException";
4130
+ this.statusCode = options.statusCode;
4131
+ this.responseBody = options.responseBody;
4132
+ this.headers = options.headers;
4133
+ }
4134
+ }
4135
+ function parseJsonPreservingLargeIntegers2(text) {
4136
+ return JSONBigStringParser2.parse(text);
4137
+ }
4138
+ function isRecord2(value) {
4139
+ return typeof value === "object" && value !== null && !Array.isArray(value);
4140
+ }
4141
+ function getApiErrorMessage(responseBody) {
4142
+ if (typeof responseBody.message === "string" && responseBody.message) {
4143
+ return responseBody.message;
4144
+ }
4145
+ if (typeof responseBody.message_cn === "string" && responseBody.message_cn) {
4146
+ return responseBody.message_cn;
4147
+ }
4148
+ return `Tencent Ads API error: ${responseBody.code}`;
4149
+ }
4150
+ function createNonce() {
4151
+ return crypto.randomUUID().replaceAll("-", "").slice(0, 20);
4152
+ }
4153
+
4154
+ // packages/tencent-ads-marketing-api-sdk/dist/api/v3/api_adgroups.js
4155
+ class AdgroupsApi {
4156
+ apiClient;
4157
+ constructor(apiClient = new ApiClient2) {
4158
+ this.apiClient = apiClient;
4159
+ }
4160
+ getApiClient() {
4161
+ return this.apiClient;
4162
+ }
4163
+ setApiClient(apiClient) {
4164
+ this.apiClient = apiClient;
4165
+ }
4166
+ async add(request) {
4167
+ const response = await this.addWithHttpInfo(request);
4168
+ return response.data;
4169
+ }
4170
+ async addWithHttpInfo(request) {
4171
+ if (request.data == null) {
4172
+ throw new ApiException2("Missing the required parameter 'data' when calling add");
4173
+ }
4174
+ return this.apiClient.requestWithHttpInfo({
4175
+ method: "POST",
4176
+ basePath: DefaultConfiguration2.basePath,
4177
+ path: "/adgroups/add",
4178
+ queryParams: [],
4179
+ contentType: "application/json",
4180
+ body: request.data
4181
+ });
4182
+ }
4183
+ async delete(request) {
4184
+ const response = await this.deleteWithHttpInfo(request);
4185
+ return response.data;
4186
+ }
4187
+ async deleteWithHttpInfo(request) {
4188
+ if (request.data == null) {
4189
+ throw new ApiException2("Missing the required parameter 'data' when calling delete");
4190
+ }
4191
+ return this.apiClient.requestWithHttpInfo({
4192
+ method: "POST",
4193
+ basePath: DefaultConfiguration2.basePath,
4194
+ path: "/adgroups/delete",
4195
+ queryParams: [],
4196
+ contentType: "application/json",
4197
+ body: request.data
4198
+ });
4199
+ }
4200
+ async get(request) {
4201
+ const response = await this.getWithHttpInfo(request);
4202
+ return response.data;
4203
+ }
4204
+ async getWithHttpInfo(request) {
4205
+ if (request.accountId == null) {
4206
+ throw new ApiException2("Missing the required parameter 'accountId' when calling get");
4207
+ }
4208
+ return this.apiClient.requestWithHttpInfo({
4209
+ method: "GET",
4210
+ basePath: DefaultConfiguration2.basePath,
4211
+ path: "/adgroups/get",
4212
+ queryParams: [
4213
+ { name: "account_id", value: request.accountId },
4214
+ { name: "filtering", value: request.filtering, collectionFormat: "multi" },
4215
+ { name: "page", value: request.page },
4216
+ { name: "page_size", value: request.pageSize },
4217
+ { name: "is_deleted", value: request.isDeleted },
4218
+ { name: "fields", value: request.fields, collectionFormat: "multi" },
4219
+ { name: "pagination_mode", value: request.paginationMode },
4220
+ { name: "cursor", value: request.cursor }
4221
+ ],
4222
+ contentType: "text/plain"
4223
+ });
4224
+ }
4225
+ async update(request) {
4226
+ const response = await this.updateWithHttpInfo(request);
4227
+ return response.data;
4228
+ }
4229
+ async updateWithHttpInfo(request) {
4230
+ if (request.data == null) {
4231
+ throw new ApiException2("Missing the required parameter 'data' when calling update");
4232
+ }
4233
+ return this.apiClient.requestWithHttpInfo({
4234
+ method: "POST",
4235
+ basePath: DefaultConfiguration2.basePath,
4236
+ path: "/adgroups/update",
4237
+ queryParams: [],
4238
+ contentType: "application/json",
4239
+ body: request.data
4240
+ });
4241
+ }
4242
+ async updateBidAmount(request) {
4243
+ const response = await this.updateBidAmountWithHttpInfo(request);
4244
+ return response.data;
4245
+ }
4246
+ async updateBidAmountWithHttpInfo(request) {
4247
+ if (request.data == null) {
4248
+ throw new ApiException2("Missing the required parameter 'data' when calling updateBidAmount");
4249
+ }
4250
+ return this.apiClient.requestWithHttpInfo({
4251
+ method: "POST",
4252
+ basePath: DefaultConfiguration2.basePath,
4253
+ path: "/adgroups/update_bid_amount",
4254
+ queryParams: [],
4255
+ contentType: "application/json",
4256
+ body: request.data
4257
+ });
4258
+ }
4259
+ async updateConfiguredStatus(request) {
4260
+ const response = await this.updateConfiguredStatusWithHttpInfo(request);
4261
+ return response.data;
4262
+ }
4263
+ async updateConfiguredStatusWithHttpInfo(request) {
4264
+ if (request.data == null) {
4265
+ throw new ApiException2("Missing the required parameter 'data' when calling updateConfiguredStatus");
4266
+ }
4267
+ return this.apiClient.requestWithHttpInfo({
4268
+ method: "POST",
4269
+ basePath: DefaultConfiguration2.basePath,
4270
+ path: "/adgroups/update_configured_status",
4271
+ queryParams: [],
4272
+ contentType: "application/json",
4273
+ body: request.data
4274
+ });
4275
+ }
4276
+ async updateDailyBudget(request) {
4277
+ const response = await this.updateDailyBudgetWithHttpInfo(request);
4278
+ return response.data;
4279
+ }
4280
+ async updateDailyBudgetWithHttpInfo(request) {
4281
+ if (request.data == null) {
4282
+ throw new ApiException2("Missing the required parameter 'data' when calling updateDailyBudget");
4283
+ }
4284
+ return this.apiClient.requestWithHttpInfo({
4285
+ method: "POST",
4286
+ basePath: DefaultConfiguration2.basePath,
4287
+ path: "/adgroups/update_daily_budget",
4288
+ queryParams: [],
4289
+ contentType: "application/json",
4290
+ body: request.data
4291
+ });
4292
+ }
4293
+ async updateDatetime(request) {
4294
+ const response = await this.updateDatetimeWithHttpInfo(request);
4295
+ return response.data;
4296
+ }
4297
+ async updateDatetimeWithHttpInfo(request) {
4298
+ if (request.data == null) {
4299
+ throw new ApiException2("Missing the required parameter 'data' when calling updateDatetime");
4300
+ }
4301
+ return this.apiClient.requestWithHttpInfo({
4302
+ method: "POST",
4303
+ basePath: DefaultConfiguration2.basePath,
4304
+ path: "/adgroups/update_datetime",
4305
+ queryParams: [],
4306
+ contentType: "application/json",
4307
+ body: request.data
4308
+ });
4309
+ }
4310
+ }
4311
+
4312
+ // packages/tencent-ads-marketing-api-sdk/dist/api/v3/api_advertiser.js
4313
+ class AdvertiserApi {
4314
+ apiClient;
4315
+ constructor(apiClient = new ApiClient2) {
4316
+ this.apiClient = apiClient;
4317
+ }
4318
+ getApiClient() {
4319
+ return this.apiClient;
4320
+ }
4321
+ setApiClient(apiClient) {
4322
+ this.apiClient = apiClient;
4323
+ }
4324
+ async add(request) {
4325
+ const response = await this.addWithHttpInfo(request);
4326
+ return response.data;
4327
+ }
4328
+ async addWithHttpInfo(request) {
4329
+ if (request.data == null) {
4330
+ throw new ApiException2("Missing the required parameter 'data' when calling add");
4331
+ }
4332
+ return this.apiClient.requestWithHttpInfo({
4333
+ method: "POST",
4334
+ basePath: DefaultConfiguration2.basePath,
4335
+ path: "/advertiser/add",
4336
+ queryParams: [],
4337
+ contentType: "application/json",
4338
+ body: request.data
4339
+ });
4340
+ }
4341
+ async get(request) {
4342
+ const response = await this.getWithHttpInfo(request);
4343
+ return response.data;
4344
+ }
4345
+ async getWithHttpInfo(request) {
4346
+ if (request.fields == null) {
4347
+ throw new ApiException2("Missing the required parameter 'fields' when calling get");
4348
+ }
4349
+ if (request.paginationMode == null) {
4350
+ throw new ApiException2("Missing the required parameter 'paginationMode' when calling get");
4351
+ }
4352
+ if (request.pageSize == null) {
4353
+ throw new ApiException2("Missing the required parameter 'pageSize' when calling get");
4354
+ }
4355
+ return this.apiClient.requestWithHttpInfo({
4356
+ method: "GET",
4357
+ basePath: DefaultConfiguration2.basePath,
4358
+ path: "/advertiser/get",
4359
+ queryParams: [
4360
+ { name: "agency_id", value: request.agencyId },
4361
+ { name: "account_id", value: request.accountId },
4362
+ { name: "filtering", value: request.filtering, collectionFormat: "multi" },
4363
+ { name: "fields", value: request.fields, collectionFormat: "multi" },
4364
+ { name: "pagination_mode", value: request.paginationMode },
4365
+ { name: "page", value: request.page },
4366
+ { name: "page_size", value: request.pageSize },
4367
+ { name: "cursor", value: request.cursor }
4368
+ ],
4369
+ contentType: "text/plain"
4370
+ });
4371
+ }
4372
+ async update(request) {
4373
+ const response = await this.updateWithHttpInfo(request);
4374
+ return response.data;
4375
+ }
4376
+ async updateWithHttpInfo(request) {
4377
+ if (request.data == null) {
4378
+ throw new ApiException2("Missing the required parameter 'data' when calling update");
4379
+ }
4380
+ return this.apiClient.requestWithHttpInfo({
4381
+ method: "POST",
4382
+ basePath: DefaultConfiguration2.basePath,
4383
+ path: "/advertiser/update",
4384
+ queryParams: [],
4385
+ contentType: "application/json",
4386
+ body: request.data
4387
+ });
4388
+ }
4389
+ async updateDailyBudget(request) {
4390
+ const response = await this.updateDailyBudgetWithHttpInfo(request);
4391
+ return response.data;
4392
+ }
4393
+ async updateDailyBudgetWithHttpInfo(request) {
4394
+ if (request.data == null) {
4395
+ throw new ApiException2("Missing the required parameter 'data' when calling updateDailyBudget");
4396
+ }
4397
+ return this.apiClient.requestWithHttpInfo({
4398
+ method: "POST",
4399
+ basePath: DefaultConfiguration2.basePath,
4400
+ path: "/advertiser/update_daily_budget",
4401
+ queryParams: [],
4402
+ contentType: "application/json",
4403
+ body: request.data
4404
+ });
4405
+ }
4406
+ }
4407
+
4408
+ // packages/tencent-ads-marketing-api-sdk/dist/api/v3/api_dynamic_creatives.js
4409
+ class DynamicCreativesApi {
4410
+ apiClient;
4411
+ constructor(apiClient = new ApiClient2) {
4412
+ this.apiClient = apiClient;
4413
+ }
4414
+ getApiClient() {
4415
+ return this.apiClient;
4416
+ }
4417
+ setApiClient(apiClient) {
4418
+ this.apiClient = apiClient;
4419
+ }
4420
+ async add(request) {
4421
+ const response = await this.addWithHttpInfo(request);
4422
+ return response.data;
4423
+ }
4424
+ async addWithHttpInfo(request) {
4425
+ if (request.data == null) {
4426
+ throw new ApiException2("Missing the required parameter 'data' when calling add");
4427
+ }
4428
+ return this.apiClient.requestWithHttpInfo({
4429
+ method: "POST",
4430
+ basePath: DefaultConfiguration2.basePath,
4431
+ path: "/dynamic_creatives/add",
4432
+ queryParams: [],
4433
+ contentType: "application/json",
4434
+ body: request.data
4435
+ });
4436
+ }
4437
+ async delete(request) {
4438
+ const response = await this.deleteWithHttpInfo(request);
4439
+ return response.data;
4440
+ }
4441
+ async deleteWithHttpInfo(request) {
4442
+ if (request.data == null) {
4443
+ throw new ApiException2("Missing the required parameter 'data' when calling delete");
4444
+ }
4445
+ return this.apiClient.requestWithHttpInfo({
4446
+ method: "POST",
4447
+ basePath: DefaultConfiguration2.basePath,
4448
+ path: "/dynamic_creatives/delete",
4449
+ queryParams: [],
4450
+ contentType: "application/json",
4451
+ body: request.data
4452
+ });
4453
+ }
4454
+ async get(request) {
4455
+ const response = await this.getWithHttpInfo(request);
4456
+ return response.data;
4457
+ }
4458
+ async getWithHttpInfo(request) {
4459
+ if (request.accountId == null) {
4460
+ throw new ApiException2("Missing the required parameter 'accountId' when calling get");
4461
+ }
4462
+ return this.apiClient.requestWithHttpInfo({
4463
+ method: "GET",
4464
+ basePath: DefaultConfiguration2.basePath,
4465
+ path: "/dynamic_creatives/get",
4466
+ queryParams: [
4467
+ { name: "account_id", value: request.accountId },
4468
+ { name: "filtering", value: request.filtering, collectionFormat: "multi" },
4469
+ { name: "page", value: request.page },
4470
+ { name: "page_size", value: request.pageSize },
4471
+ { name: "fields", value: request.fields, collectionFormat: "multi" },
4472
+ { name: "is_deleted", value: request.isDeleted },
4473
+ { name: "pagination_mode", value: request.paginationMode },
4474
+ { name: "cursor", value: request.cursor }
4475
+ ],
4476
+ contentType: "text/plain"
4477
+ });
4478
+ }
4479
+ async update(request) {
4480
+ const response = await this.updateWithHttpInfo(request);
4481
+ return response.data;
4482
+ }
4483
+ async updateWithHttpInfo(request) {
4484
+ if (request.data == null) {
4485
+ throw new ApiException2("Missing the required parameter 'data' when calling update");
4486
+ }
4487
+ return this.apiClient.requestWithHttpInfo({
4488
+ method: "POST",
4489
+ basePath: DefaultConfiguration2.basePath,
4490
+ path: "/dynamic_creatives/update",
4491
+ queryParams: [],
4492
+ contentType: "application/json",
4493
+ body: request.data
4494
+ });
4495
+ }
4496
+ }
4497
+
4498
+ // packages/tencent-ads-marketing-api-sdk/dist/api/v3/api_organization_account_relation.js
4499
+ class OrganizationAccountRelationApi {
4500
+ apiClient;
4501
+ constructor(apiClient = new ApiClient2) {
4502
+ this.apiClient = apiClient;
4503
+ }
4504
+ getApiClient() {
4505
+ return this.apiClient;
4506
+ }
4507
+ setApiClient(apiClient) {
4508
+ this.apiClient = apiClient;
4509
+ }
4510
+ async get(request) {
4511
+ const response = await this.getWithHttpInfo(request);
4512
+ return response.data;
4513
+ }
4514
+ async getWithHttpInfo(request) {
4515
+ if (request.paginationMode == null) {
4516
+ throw new ApiException2("Missing the required parameter 'paginationMode' when calling get");
4517
+ }
4518
+ return this.apiClient.requestWithHttpInfo({
4519
+ method: "GET",
4520
+ basePath: DefaultConfiguration2.basePath,
4521
+ path: "/organization_account_relation/get",
4522
+ queryParams: [
4523
+ { name: "account_id", value: request.accountId },
4524
+ { name: "advertiser_type", value: request.advertiserType },
4525
+ { name: "business_unit_id", value: request.businessUnitId },
4526
+ { name: "pagination_mode", value: request.paginationMode },
4527
+ { name: "cursor", value: request.cursor },
4528
+ { name: "page", value: request.page },
4529
+ { name: "page_size", value: request.pageSize },
4530
+ { name: "fields", value: request.fields, collectionFormat: "multi" }
4531
+ ],
4532
+ contentType: "text/plain"
4533
+ });
4534
+ }
4535
+ }
4536
+
4537
+ // src/commands/tencent-ads/config.ts
4538
+ import { chmod as chmod2, mkdir as mkdir3, readFile as readFile3, rename as rename3, writeFile as writeFile3 } from "node:fs/promises";
4539
+ import path4 from "node:path";
4540
+ function getTencentAdsConfigInfo(options = {}) {
4541
+ const configDir = options.configDir ?? envPaths("adcli", { suffix: "" }).cache;
4542
+ return {
4543
+ configPath: path4.join(configDir, "tencent-ads.json")
4544
+ };
4545
+ }
4546
+ async function saveTencentAdsAccessToken(token, options = {}) {
4547
+ const trimmed = token.trim();
4548
+ if (!trimmed) {
4549
+ throw new Error("missing Tencent Ads token");
4550
+ }
4551
+ const configInfo = getTencentAdsConfigInfo(options);
4552
+ await mkdir3(path4.dirname(configInfo.configPath), { recursive: true });
4553
+ const tempPath = `${configInfo.configPath}.${process.pid}.tmp`;
4554
+ await writeFile3(tempPath, `${JSON.stringify({ access_token: trimmed })}
4555
+ `, {
4556
+ encoding: "utf8",
4557
+ mode: 384
4558
+ });
4559
+ await rename3(tempPath, configInfo.configPath);
4560
+ await chmod2(configInfo.configPath, 384);
4561
+ return configInfo;
4562
+ }
4563
+ async function loadTencentAdsAccessToken(options = {}) {
4564
+ const configInfo = getTencentAdsConfigInfo(options);
4565
+ let config;
4566
+ try {
4567
+ config = JSON.parse(await readFile3(configInfo.configPath, "utf8"));
4568
+ } catch (error) {
4569
+ if (isNotFoundError3(error)) {
4570
+ return;
4571
+ }
4572
+ throw error;
4573
+ }
4574
+ if (typeof config.access_token !== "string" || !config.access_token.trim()) {
4575
+ return;
4576
+ }
4577
+ return config.access_token.trim();
4578
+ }
4579
+ function isNotFoundError3(error) {
4580
+ return error instanceof Error && "code" in error && error.code === "ENOENT";
4581
+ }
4582
+
4583
+ // src/commands/tencent-ads/commands.ts
4584
+ async function runTencentAdsCommand(argv, options = {}) {
4585
+ const args = parseTencentAdsArgs(argv);
4586
+ if (args.resource === "auth") {
4587
+ const token2 = args.action;
4588
+ if (!token2) {
4589
+ throw new Error("missing Tencent Ads token");
4590
+ }
4591
+ const configInfo = await saveTencentAdsAccessToken(token2, { configDir: options.configDir });
4592
+ return {
4593
+ ok: true,
4594
+ config_path: configInfo.configPath
4595
+ };
4596
+ }
4597
+ const token = await resolveAccessToken2(args, options);
4598
+ const apiClient = new ApiClient2({ fetch: options.fetch }).setAccessToken(token);
4599
+ if (args.resource === "advertiser" && args.action === "list") {
4600
+ return new OrganizationAccountRelationApi(apiClient).get({
4601
+ accountId: getOptionalId(args, "account-id") ?? getOptionalId(args, "advertiser-id"),
4602
+ fields: parseCsv2(args.flags.fields) ?? ["account_id", "corporation_name", "is_bid", "is_mp", "is_adx", "comment_list"],
4603
+ page: parseNumberFlag2(args.flags.page) ?? 1,
4604
+ pageSize: parseNumberFlag2(args.flags["page-size"]) ?? 100,
4605
+ paginationMode: getOptionalString2(args.flags["pagination-mode"]) ?? "PAGINATION_MODE_NORMAL"
4606
+ });
4607
+ }
4608
+ if (args.resource === "advertiser" && args.action === "get") {
4609
+ return new AdvertiserApi(apiClient).get({
4610
+ accountId: getRequiredAccountId(args),
4611
+ fields: parseCsv2(args.flags.fields) ?? ["account_id", "account_name"],
4612
+ filtering: parseJsonFlag2(args.flags.filtering),
4613
+ page: parseNumberFlag2(args.flags.page),
4614
+ pageSize: parseNumberFlag2(args.flags["page-size"]) ?? 20,
4615
+ paginationMode: getOptionalString2(args.flags["pagination-mode"]) ?? "PAGINATION_MODE_NORMAL"
4616
+ });
4617
+ }
4618
+ if (args.resource === "adgroup" && args.action === "list") {
4619
+ return new AdgroupsApi(apiClient).get({
4620
+ accountId: getRequiredAccountId(args),
4621
+ filtering: parseJsonFlag2(args.flags.filtering),
4622
+ fields: parseCsv2(args.flags.fields),
4623
+ page: parseNumberFlag2(args.flags.page),
4624
+ pageSize: parseNumberFlag2(args.flags["page-size"])
4625
+ });
4626
+ }
4627
+ if (args.resource === "dynamic-creative" && args.action === "list") {
4628
+ return new DynamicCreativesApi(apiClient).get({
4629
+ accountId: getRequiredAccountId(args),
4630
+ filtering: parseJsonFlag2(args.flags.filtering),
4631
+ fields: parseCsv2(args.flags.fields),
4632
+ page: parseNumberFlag2(args.flags.page),
4633
+ pageSize: parseNumberFlag2(args.flags["page-size"])
4634
+ });
4635
+ }
4636
+ throw new Error(`unknown tencent-ads command: ${[args.resource, args.action].filter(Boolean).join(" ")}`);
4637
+ }
4638
+ function formatTencentAdsOutput(payload, json, argv = []) {
4639
+ if (json) {
4640
+ return JSON.stringify(payload, null, 2);
4641
+ }
4642
+ if (isTencentAdsErrorPayload(payload)) {
4643
+ return JSON.stringify(payload, null, 2);
4644
+ }
4645
+ if (argv[0] === "advertiser" && argv[1] === "list") {
4646
+ return formatEntityList2(payload, "account_id", ["account_id", "id"], ["account_name", "corporation_name", "name"]);
4647
+ }
4648
+ if (argv[0] === "advertiser" && argv[1] === "get") {
4649
+ return formatEntityList2(payload, "account_id", ["account_id", "id"], ["account_name", "corporation_name", "name"]);
4650
+ }
4651
+ if (argv[0] === "adgroup" && argv[1] === "list") {
4652
+ return formatEntityList2(payload, "adgroup_id", ["adgroup_id", "id"], ["adgroup_name", "name"]);
4653
+ }
4654
+ if (argv[0] === "dynamic-creative" && argv[1] === "list") {
4655
+ return formatEntityList2(payload, "dynamic_creative_id", ["dynamic_creative_id", "id"], ["dynamic_creative_name", "name"]);
4656
+ }
4657
+ return JSON.stringify(payload, null, 2);
4658
+ }
4659
+ function formatTencentAdsError(error) {
4660
+ if (!isRecord3(error) || !("responseBody" in error)) {
4661
+ return;
4662
+ }
4663
+ const responseBody = error.responseBody;
4664
+ if (responseBody == null) {
4665
+ return;
4666
+ }
4667
+ if (typeof responseBody === "string") {
4668
+ return responseBody;
4669
+ }
4670
+ return JSON.stringify(responseBody, null, 2);
4671
+ }
4672
+ function parseTencentAdsArgs(argv) {
4673
+ const args = {
4674
+ resource: argv[0],
4675
+ action: argv[1],
4676
+ flags: {}
4677
+ };
4678
+ for (let index = 2;index < argv.length; index += 1) {
4679
+ const value = argv[index];
4680
+ if (!value?.startsWith("--")) {
4681
+ continue;
4682
+ }
4683
+ const name = value.slice(2);
4684
+ const next = argv[index + 1];
4685
+ if (!next || next.startsWith("--")) {
4686
+ args.flags[name] = true;
4687
+ continue;
4688
+ }
4689
+ args.flags[name] = next;
4690
+ index += 1;
4691
+ }
4692
+ return args;
4693
+ }
4694
+ async function resolveAccessToken2(args, options) {
4695
+ const explicitToken = getOptionalString2(args.flags["access-token"]);
4696
+ if (explicitToken) {
4697
+ return explicitToken;
4698
+ }
4699
+ const env2 = options.env ?? process.env;
4700
+ const envToken = getOptionalString2(env2.TENCENT_ADS_ACCESS_TOKEN);
4701
+ if (envToken) {
4702
+ return envToken;
4703
+ }
4704
+ const savedToken = await loadTencentAdsAccessToken({ configDir: options.configDir });
4705
+ if (savedToken) {
4706
+ return savedToken;
4707
+ }
4708
+ throw new Error("missing --access-token; run adcli tencent-ads auth <token> or set TENCENT_ADS_ACCESS_TOKEN");
4709
+ }
4710
+ function getRequiredAccountId(args) {
4711
+ return getRequiredId2(args, "account-id", "advertiser-id");
4712
+ }
4713
+ function getRequiredString2(args, flag, alias) {
4714
+ const value = getOptionalString2(args.flags[flag]) ?? (alias ? getOptionalString2(args.flags[alias]) : undefined);
4715
+ if (!value) {
4716
+ throw new Error(alias ? `missing --${flag} or --${alias}` : `missing --${flag}`);
4717
+ }
4718
+ return value;
4719
+ }
4720
+ function getOptionalString2(value) {
4721
+ if (typeof value !== "string" || !value) {
4722
+ return;
4723
+ }
4724
+ return value;
4725
+ }
4726
+ function getOptionalId(args, flag) {
4727
+ const value = getOptionalString2(args.flags[flag]);
4728
+ if (!value) {
4729
+ return;
4730
+ }
4731
+ if (!/^\d+$/.test(value)) {
4732
+ throw new Error(`--${flag} must be an integer id`);
4733
+ }
4734
+ return value;
4735
+ }
4736
+ function getRequiredId2(args, flag, alias) {
4737
+ const value = getRequiredString2(args, flag, alias);
4738
+ if (!/^\d+$/.test(value)) {
4739
+ throw new Error(alias ? `--${flag} or --${alias} must be an integer id` : `--${flag} must be an integer id`);
4740
+ }
4741
+ return value;
4742
+ }
4743
+ function parseNumberFlag2(value) {
4744
+ if (value == null || value === true) {
4745
+ return;
4746
+ }
4747
+ const parsed = Number(value);
4748
+ if (!Number.isFinite(parsed)) {
4749
+ throw new Error(`numeric flag must be a number: ${value}`);
4750
+ }
4751
+ return parsed;
4752
+ }
4753
+ function parseCsv2(value) {
4754
+ if (typeof value !== "string" || !value) {
4755
+ return;
4756
+ }
4757
+ return value.split(",").map((item) => item.trim()).filter(Boolean);
4758
+ }
4759
+ function parseJsonFlag2(value) {
4760
+ if (typeof value !== "string" || !value) {
4761
+ return;
4762
+ }
4763
+ return parseJsonPreservingLargeIntegers2(value);
4764
+ }
4765
+ function formatEntityList2(payload, idHeader, idKeys, nameKeys) {
4766
+ const list = getPayloadList2(payload);
4767
+ const header = `${idHeader} name`;
4768
+ if (list.length === 0) {
4769
+ return header;
4770
+ }
4771
+ return [
4772
+ header,
4773
+ ...list.map((item) => {
4774
+ const id = getRecordValue2(item, idKeys);
4775
+ const name = getRecordValue2(item, nameKeys);
4776
+ return `${id} ${name}`;
4777
+ })
4778
+ ].join(`
4779
+ `);
4780
+ }
4781
+ function getPayloadList2(payload) {
4782
+ if (isRecord3(payload) && Array.isArray(payload.list)) {
4783
+ return payload.list.filter(isRecord3);
4784
+ }
4785
+ if (!isRecord3(payload) || !isRecord3(payload.data) || !Array.isArray(payload.data.list)) {
4786
+ return [];
4787
+ }
4788
+ return payload.data.list.filter(isRecord3);
4789
+ }
4790
+ function getRecordValue2(record, keys) {
4791
+ for (const key of keys) {
4792
+ const value = record[key];
4793
+ if (typeof value === "string" || typeof value === "number") {
4794
+ return String(value);
4795
+ }
4796
+ }
4797
+ return "";
4798
+ }
4799
+ function isRecord3(value) {
4800
+ return typeof value === "object" && value !== null && !Array.isArray(value);
4801
+ }
4802
+ function isTencentAdsErrorPayload(payload) {
4803
+ return isRecord3(payload) && typeof payload.code === "number" && payload.code !== 0;
4804
+ }
4805
+
4806
+ // src/cli.ts
4807
+ var help = `adcli
4808
+
4809
+ Usage:
4810
+ adcli list [platform] [--json]
4811
+ adcli doc <command>
4812
+ adcli oceanengine <resource> <command>
4813
+ adcli tencent-ads <resource> <command>
4814
+ adcli prompt
4815
+ adcli llms
4816
+
4817
+ Commands:
4818
+ list List supported advertising platforms and capabilities
4819
+ doc Search and sync published advertising API docs
4820
+ oceanengine Call OceanEngine APIs through the generated Node.js SDK
4821
+ tencent-ads Call Tencent Ads APIs through the generated Node.js SDK
4822
+ prompt Print an AI/Agent instruction prompt for using the docs pack
4823
+ llms Print LLM-readable docs pack entry URLs
4824
+ `;
4825
+ var docHelp = `adcli doc
4826
+
4827
+ Usage:
4828
+ adcli doc search <query> [--platform tencent_ads] [--limit 10] [--json] [--refresh]
4829
+ adcli doc sync
4830
+
4831
+ Commands:
4832
+ search Search published advertising API docs
4833
+ sync Download and cache the latest search index
4834
+ `;
4835
+ var oceanEngineHelp = `adcli oceanengine
4836
+
4837
+ Usage:
4838
+ adcli oceanengine auth <token>
4839
+ adcli oceanengine advertiser list [--access-token token] [--json]
4840
+ adcli oceanengine project list --advertiser-id 123 [--access-token token] [--page 1] [--page-size 20] [--filtering '{"status":"PROJECT_STATUS_ALL"}'] [--json]
4841
+ adcli oceanengine promotion list --advertiser-id 123 [--access-token token] [--project-id 456] [--fields promotion_id,name,status_first] [--filtering '{}'] [--json]
4842
+
4843
+ Environment:
4844
+ Token precedence is --access-token, OCEANENGINE_ACCESS_TOKEN, then the saved token.
4845
+ Project list does not include deleted projects by default; use filtering status PROJECT_STATUS_ALL for all projects.
4846
+ `;
4847
+ var tencentAdsHelp = `adcli tencent-ads
4848
+
4849
+ Usage:
4850
+ adcli tencent-ads auth <token>
4851
+ adcli tencent-ads advertiser list [--access-token token] [--page 1] [--page-size 100] [--json]
4852
+ adcli tencent-ads advertiser get --account-id 123 [--access-token token] [--fields account_id,account_name] [--json]
4853
+ adcli tencent-ads adgroup list --account-id 123 [--access-token token] [--page 1] [--page-size 20] [--fields adgroup_id,adgroup_name] [--filtering '{}'] [--json]
4854
+ adcli tencent-ads dynamic-creative list --account-id 123 [--access-token token] [--fields dynamic_creative_id,dynamic_creative_name] [--filtering '{}'] [--json]
4855
+
4856
+ Environment:
4857
+ Token precedence is --access-token, TENCENT_ADS_ACCESS_TOKEN, then the saved token.
4858
+ --advertiser-id is accepted as an alias for --account-id.
4859
+ Tencent Ads command names follow v3 API resources; use --filtering for resource filters.
4860
+ `;
4861
+ async function main() {
4862
+ const args = parseArgs(process.argv.slice(2));
4863
+ if (!args.domain || args.domain === "help" || args.domain === "--help" || args.domain === "-h") {
4864
+ console.log(help.trim());
4865
+ return;
4866
+ }
4867
+ if (args.domain === "list") {
4868
+ const index2 = await loadSearchIndex({ index: args.index, refresh: args.refresh });
4869
+ printDocList(index2, args);
4870
+ return;
4871
+ }
4872
+ if (args.domain === "doc" && (!args.command || args.command === "--help" || args.command === "-h" || args.command === "help")) {
4873
+ console.log(docHelp.trim());
4874
+ return;
4875
+ }
4876
+ if (args.domain === "doc" && args.command === "sync") {
4877
+ const index2 = await refreshSearchIndex();
4878
+ const cache = getSearchIndexCacheInfo();
4879
+ console.log(`Synced ${index2.documents.length} docs to ${cache.cachePath}`);
4880
+ return;
4881
+ }
4882
+ if (args.domain === "doc" && args.command === "list") {
4883
+ const index2 = await loadSearchIndex({ index: args.index, refresh: args.refresh });
4884
+ printDocList(index2, args);
4885
+ return;
4886
+ }
4887
+ if (args.domain === "prompt") {
4888
+ printLlms({ ...args, domain: "llms", command: "prompt" });
4889
+ return;
4890
+ }
4891
+ if (args.domain === "llms") {
4892
+ printLlms(args);
4893
+ return;
4894
+ }
4895
+ if (args.domain === "oceanengine") {
4896
+ if (!args.command || args.command === "--help" || args.command === "-h" || args.command === "help") {
4897
+ console.log(oceanEngineHelp.trim());
4898
+ return;
4899
+ }
4900
+ const oceanEngineArgv = [args.command, ...args.query];
4901
+ const payload = await runOceanEngineCommand(oceanEngineArgv);
4902
+ console.log(formatOceanEngineOutput(payload, args.json, oceanEngineArgv));
4903
+ return;
4904
+ }
4905
+ if (args.domain === "tencent-ads") {
4906
+ if (!args.command || args.command === "--help" || args.command === "-h" || args.command === "help") {
4907
+ console.log(tencentAdsHelp.trim());
4908
+ return;
4909
+ }
4910
+ const tencentAdsArgv = [args.command, ...args.query];
4911
+ const payload = await runTencentAdsCommand(tencentAdsArgv);
4912
+ console.log(formatTencentAdsOutput(payload, args.json, tencentAdsArgv));
3916
4913
  return;
3917
4914
  }
3918
4915
  if (args.domain !== "doc" || args.command !== "search") {
@@ -3932,7 +4929,7 @@ async function main() {
3932
4929
  limit: args.limit
3933
4930
  });
3934
4931
  if (args.json) {
3935
- console.log(JSON.stringify({ query, results }, null, 2));
4932
+ console.log(JSON.stringify({ query, results: withPublicUrls(results) }, null, 2));
3936
4933
  return;
3937
4934
  }
3938
4935
  if (results.length === 0) {
@@ -3941,7 +4938,7 @@ async function main() {
3941
4938
  }
3942
4939
  for (const [index2, result] of results.entries()) {
3943
4940
  console.log(`${index2 + 1}. [${result.platform}] ${result.title}`);
3944
- console.log(` Doc: ${result.public_path}`);
4941
+ console.log(` LLMs: ${publicDocsUrl(result.public_path)}`);
3945
4942
  if (result.source_url) {
3946
4943
  console.log(` Source: ${result.source_url}`);
3947
4944
  }
@@ -4078,6 +5075,6 @@ function parseArgs(argv) {
4078
5075
  return args;
4079
5076
  }
4080
5077
  main().catch((error) => {
4081
- console.error(formatOceanEngineError(error) ?? (error instanceof Error ? error.message : error));
5078
+ console.error(formatTencentAdsError(error) ?? formatOceanEngineError(error) ?? (error instanceof Error ? error.message : error));
4082
5079
  process.exit(1);
4083
5080
  });