@koda-sl/baker-cli 0.25.1 → 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (182) hide show
  1. package/README.md +218 -0
  2. package/dist/cli.js +1 -1
  3. package/dist/commands/ads/index.d.ts.map +1 -1
  4. package/dist/commands/ads/index.js +12 -3
  5. package/dist/commands/ads/index.js.map +1 -1
  6. package/dist/commands/ads/linkedin/account.d.ts +20 -0
  7. package/dist/commands/ads/linkedin/account.d.ts.map +1 -0
  8. package/dist/commands/ads/linkedin/account.js +39 -0
  9. package/dist/commands/ads/linkedin/account.js.map +1 -0
  10. package/dist/commands/ads/linkedin/accounts.d.ts +20 -0
  11. package/dist/commands/ads/linkedin/accounts.d.ts.map +1 -0
  12. package/dist/commands/ads/linkedin/accounts.js +56 -0
  13. package/dist/commands/ads/linkedin/accounts.js.map +1 -0
  14. package/dist/commands/ads/linkedin/analytics.d.ts +84 -0
  15. package/dist/commands/ads/linkedin/analytics.d.ts.map +1 -0
  16. package/dist/commands/ads/linkedin/analytics.js +249 -0
  17. package/dist/commands/ads/linkedin/analytics.js.map +1 -0
  18. package/dist/commands/ads/linkedin/audience-size.d.ts +28 -0
  19. package/dist/commands/ads/linkedin/audience-size.d.ts.map +1 -0
  20. package/dist/commands/ads/linkedin/audience-size.js +75 -0
  21. package/dist/commands/ads/linkedin/audience-size.js.map +1 -0
  22. package/dist/commands/ads/linkedin/audit.d.ts +35 -0
  23. package/dist/commands/ads/linkedin/audit.d.ts.map +1 -0
  24. package/dist/commands/ads/linkedin/audit.js +136 -0
  25. package/dist/commands/ads/linkedin/audit.js.map +1 -0
  26. package/dist/commands/ads/linkedin/bid-pricing.d.ts +38 -0
  27. package/dist/commands/ads/linkedin/bid-pricing.d.ts.map +1 -0
  28. package/dist/commands/ads/linkedin/bid-pricing.js +76 -0
  29. package/dist/commands/ads/linkedin/bid-pricing.js.map +1 -0
  30. package/dist/commands/ads/linkedin/campaign-groups.d.ts +32 -0
  31. package/dist/commands/ads/linkedin/campaign-groups.d.ts.map +1 -0
  32. package/dist/commands/ads/linkedin/campaign-groups.js +50 -0
  33. package/dist/commands/ads/linkedin/campaign-groups.js.map +1 -0
  34. package/dist/commands/ads/linkedin/campaigns.d.ts +36 -0
  35. package/dist/commands/ads/linkedin/campaigns.d.ts.map +1 -0
  36. package/dist/commands/ads/linkedin/campaigns.js +57 -0
  37. package/dist/commands/ads/linkedin/campaigns.js.map +1 -0
  38. package/dist/commands/ads/linkedin/conversation.d.ts +36 -0
  39. package/dist/commands/ads/linkedin/conversation.d.ts.map +1 -0
  40. package/dist/commands/ads/linkedin/conversation.js +77 -0
  41. package/dist/commands/ads/linkedin/conversation.js.map +1 -0
  42. package/dist/commands/ads/linkedin/conversions.d.ts +2 -0
  43. package/dist/commands/ads/linkedin/conversions.d.ts.map +1 -0
  44. package/dist/commands/ads/linkedin/conversions.js +102 -0
  45. package/dist/commands/ads/linkedin/conversions.js.map +1 -0
  46. package/dist/commands/ads/linkedin/creatives.d.ts +36 -0
  47. package/dist/commands/ads/linkedin/creatives.d.ts.map +1 -0
  48. package/dist/commands/ads/linkedin/creatives.js +57 -0
  49. package/dist/commands/ads/linkedin/creatives.js.map +1 -0
  50. package/dist/commands/ads/linkedin/demographics.d.ts +40 -0
  51. package/dist/commands/ads/linkedin/demographics.d.ts.map +1 -0
  52. package/dist/commands/ads/linkedin/demographics.js +117 -0
  53. package/dist/commands/ads/linkedin/demographics.js.map +1 -0
  54. package/dist/commands/ads/linkedin/facets.d.ts +2 -0
  55. package/dist/commands/ads/linkedin/facets.d.ts.map +1 -0
  56. package/dist/commands/ads/linkedin/facets.js +95 -0
  57. package/dist/commands/ads/linkedin/facets.js.map +1 -0
  58. package/dist/commands/ads/linkedin/forecast.d.ts +50 -0
  59. package/dist/commands/ads/linkedin/forecast.d.ts.map +1 -0
  60. package/dist/commands/ads/linkedin/forecast.js +83 -0
  61. package/dist/commands/ads/linkedin/forecast.js.map +1 -0
  62. package/dist/commands/ads/linkedin/index.d.ts +19 -0
  63. package/dist/commands/ads/linkedin/index.d.ts.map +1 -0
  64. package/dist/commands/ads/linkedin/index.js +83 -0
  65. package/dist/commands/ads/linkedin/index.js.map +1 -0
  66. package/dist/commands/ads/linkedin/leads.d.ts +40 -0
  67. package/dist/commands/ads/linkedin/leads.d.ts.map +1 -0
  68. package/dist/commands/ads/linkedin/leads.js +75 -0
  69. package/dist/commands/ads/linkedin/leads.js.map +1 -0
  70. package/dist/commands/ads/linkedin/presets.d.ts +40 -0
  71. package/dist/commands/ads/linkedin/presets.d.ts.map +1 -0
  72. package/dist/commands/ads/linkedin/presets.js +193 -0
  73. package/dist/commands/ads/linkedin/presets.js.map +1 -0
  74. package/dist/commands/ads/linkedin/presets.test.d.ts +2 -0
  75. package/dist/commands/ads/linkedin/presets.test.d.ts.map +1 -0
  76. package/dist/commands/ads/linkedin/presets.test.js +98 -0
  77. package/dist/commands/ads/linkedin/presets.test.js.map +1 -0
  78. package/dist/commands/ads/linkedin/schemas.d.ts +2 -0
  79. package/dist/commands/ads/linkedin/schemas.d.ts.map +1 -0
  80. package/dist/commands/ads/linkedin/schemas.js +300 -0
  81. package/dist/commands/ads/linkedin/schemas.js.map +1 -0
  82. package/dist/commands/ads/linkedin/shared.d.ts +17 -0
  83. package/dist/commands/ads/linkedin/shared.d.ts.map +1 -0
  84. package/dist/commands/ads/linkedin/shared.js +116 -0
  85. package/dist/commands/ads/linkedin/shared.js.map +1 -0
  86. package/dist/commands/ads/linkedin/top-companies.d.ts +44 -0
  87. package/dist/commands/ads/linkedin/top-companies.d.ts.map +1 -0
  88. package/dist/commands/ads/linkedin/top-companies.js +86 -0
  89. package/dist/commands/ads/linkedin/top-companies.js.map +1 -0
  90. package/dist/commands/ads/x/accounts.d.ts +14 -0
  91. package/dist/commands/ads/x/accounts.d.ts.map +1 -0
  92. package/dist/commands/ads/x/accounts.js +73 -0
  93. package/dist/commands/ads/x/accounts.js.map +1 -0
  94. package/dist/commands/ads/x/active-entities.d.ts +43 -0
  95. package/dist/commands/ads/x/active-entities.d.ts.map +1 -0
  96. package/dist/commands/ads/x/active-entities.js +88 -0
  97. package/dist/commands/ads/x/active-entities.js.map +1 -0
  98. package/dist/commands/ads/x/audiences.d.ts +19 -0
  99. package/dist/commands/ads/x/audiences.d.ts.map +1 -0
  100. package/dist/commands/ads/x/audiences.js +65 -0
  101. package/dist/commands/ads/x/audiences.js.map +1 -0
  102. package/dist/commands/ads/x/campaigns.d.ts +34 -0
  103. package/dist/commands/ads/x/campaigns.d.ts.map +1 -0
  104. package/dist/commands/ads/x/campaigns.js +56 -0
  105. package/dist/commands/ads/x/campaigns.js.map +1 -0
  106. package/dist/commands/ads/x/cards.d.ts +19 -0
  107. package/dist/commands/ads/x/cards.d.ts.map +1 -0
  108. package/dist/commands/ads/x/cards.js +65 -0
  109. package/dist/commands/ads/x/cards.js.map +1 -0
  110. package/dist/commands/ads/x/error-parser.d.ts +3 -0
  111. package/dist/commands/ads/x/error-parser.d.ts.map +1 -0
  112. package/dist/commands/ads/x/error-parser.js +80 -0
  113. package/dist/commands/ads/x/error-parser.js.map +1 -0
  114. package/dist/commands/ads/x/funding.d.ts +19 -0
  115. package/dist/commands/ads/x/funding.d.ts.map +1 -0
  116. package/dist/commands/ads/x/funding.js +65 -0
  117. package/dist/commands/ads/x/funding.js.map +1 -0
  118. package/dist/commands/ads/x/index.d.ts +2 -0
  119. package/dist/commands/ads/x/index.d.ts.map +1 -0
  120. package/dist/commands/ads/x/index.js +50 -0
  121. package/dist/commands/ads/x/index.js.map +1 -0
  122. package/dist/commands/ads/x/line-items.d.ts +34 -0
  123. package/dist/commands/ads/x/line-items.d.ts.map +1 -0
  124. package/dist/commands/ads/x/line-items.js +55 -0
  125. package/dist/commands/ads/x/line-items.js.map +1 -0
  126. package/dist/commands/ads/x/media.d.ts +24 -0
  127. package/dist/commands/ads/x/media.d.ts.map +1 -0
  128. package/dist/commands/ads/x/media.js +70 -0
  129. package/dist/commands/ads/x/media.js.map +1 -0
  130. package/dist/commands/ads/x/output.d.ts +13 -0
  131. package/dist/commands/ads/x/output.d.ts.map +1 -0
  132. package/dist/commands/ads/x/output.js +75 -0
  133. package/dist/commands/ads/x/output.js.map +1 -0
  134. package/dist/commands/ads/x/presets.d.ts +15 -0
  135. package/dist/commands/ads/x/presets.d.ts.map +1 -0
  136. package/dist/commands/ads/x/presets.js +60 -0
  137. package/dist/commands/ads/x/presets.js.map +1 -0
  138. package/dist/commands/ads/x/promoted-tweets.d.ts +29 -0
  139. package/dist/commands/ads/x/promoted-tweets.d.ts.map +1 -0
  140. package/dist/commands/ads/x/promoted-tweets.js +74 -0
  141. package/dist/commands/ads/x/promoted-tweets.js.map +1 -0
  142. package/dist/commands/ads/x/run-list.d.ts +17 -0
  143. package/dist/commands/ads/x/run-list.d.ts.map +1 -0
  144. package/dist/commands/ads/x/run-list.js +60 -0
  145. package/dist/commands/ads/x/run-list.js.map +1 -0
  146. package/dist/commands/ads/x/stats/index.d.ts +2 -0
  147. package/dist/commands/ads/x/stats/index.d.ts.map +1 -0
  148. package/dist/commands/ads/x/stats/index.js +32 -0
  149. package/dist/commands/ads/x/stats/index.js.map +1 -0
  150. package/dist/commands/ads/x/stats/job-create.d.ts +58 -0
  151. package/dist/commands/ads/x/stats/job-create.d.ts.map +1 -0
  152. package/dist/commands/ads/x/stats/job-create.js +95 -0
  153. package/dist/commands/ads/x/stats/job-create.js.map +1 -0
  154. package/dist/commands/ads/x/stats/job-status.d.ts +18 -0
  155. package/dist/commands/ads/x/stats/job-status.d.ts.map +1 -0
  156. package/dist/commands/ads/x/stats/job-status.js +58 -0
  157. package/dist/commands/ads/x/stats/job-status.js.map +1 -0
  158. package/dist/commands/ads/x/stats/job.d.ts +63 -0
  159. package/dist/commands/ads/x/stats/job.d.ts.map +1 -0
  160. package/dist/commands/ads/x/stats/job.js +183 -0
  161. package/dist/commands/ads/x/stats/job.js.map +1 -0
  162. package/dist/commands/ads/x/stats/sync.d.ts +73 -0
  163. package/dist/commands/ads/x/stats/sync.d.ts.map +1 -0
  164. package/dist/commands/ads/x/stats/sync.js +151 -0
  165. package/dist/commands/ads/x/stats/sync.js.map +1 -0
  166. package/dist/commands/ads/x/targeting-constants.d.ts +34 -0
  167. package/dist/commands/ads/x/targeting-constants.d.ts.map +1 -0
  168. package/dist/commands/ads/x/targeting-constants.js +80 -0
  169. package/dist/commands/ads/x/targeting-constants.js.map +1 -0
  170. package/dist/commands/ads/x/targeting-criteria.d.ts +24 -0
  171. package/dist/commands/ads/x/targeting-criteria.d.ts.map +1 -0
  172. package/dist/commands/ads/x/targeting-criteria.js +69 -0
  173. package/dist/commands/ads/x/targeting-criteria.js.map +1 -0
  174. package/dist/env.d.ts +2 -0
  175. package/dist/env.d.ts.map +1 -1
  176. package/dist/env.js +8 -0
  177. package/dist/env.js.map +1 -1
  178. package/dist/error-handler.d.ts +1 -1
  179. package/dist/error-handler.d.ts.map +1 -1
  180. package/dist/error-handler.js +6 -0
  181. package/dist/error-handler.js.map +1 -1
  182. package/package.json +1 -1
@@ -0,0 +1,65 @@
1
+ import { defineCommand } from "citty";
2
+ import { ApiError, apiGet } from "../../../client.js";
3
+ import { registerSchema } from "../../../schemas.js";
4
+ import { cacheGet, cacheSet } from "../cache.js";
5
+ import { writeAdsJson, writeAdsOutput } from "../output.js";
6
+ import { parseXApiError } from "./error-parser.js";
7
+ import { resolveXAccountId } from "./output.js";
8
+ registerSchema({
9
+ command: "ads.x.funding",
10
+ description: "List funding instruments for an X Ads account. Returns id, type, currency, credit_limit_local_micro, funded_amount_local_micro, status. Falls back to BAKER_X_ADS_ACCOUNT_ID env var.",
11
+ args: {
12
+ "account-id": { type: "string", description: "X Ads account ID (base36)", required: false },
13
+ "no-cache": { type: "boolean", description: "Skip cache", required: false },
14
+ },
15
+ });
16
+ export const fundingCommand = defineCommand({
17
+ meta: {
18
+ name: "funding",
19
+ description: `List funding instruments for an X Ads account.
20
+
21
+ Examples:
22
+ baker ads x funding --account-id 18ce53xyz`,
23
+ },
24
+ args: {
25
+ "account-id": { type: "string", description: "X Ads account ID", required: false },
26
+ "no-cache": { type: "boolean", description: "Skip cache", required: false },
27
+ output: { type: "string", description: "Format: json|csv|md", required: false, default: "json" },
28
+ },
29
+ run: async ({ args }) => {
30
+ const accountId = await resolveXAccountId(args);
31
+ const useCache = !args["no-cache"];
32
+ const cacheKey = `funding:${accountId}`;
33
+ if (useCache) {
34
+ const cached = cacheGet("x-account-data", cacheKey);
35
+ if (cached) {
36
+ writeAdsJson({ ok: true, data: cached.data, cached: true });
37
+ return;
38
+ }
39
+ }
40
+ try {
41
+ const params = { "account-id": accountId };
42
+ if (!useCache)
43
+ params["skip-cache"] = "true";
44
+ const data = await apiGet("/api/ads/x/funding-instruments", params);
45
+ if (useCache) {
46
+ cacheSet("x-account-data", cacheKey, data, 60 * 60 * 1000);
47
+ }
48
+ const format = args.output || "json";
49
+ if (format !== "json") {
50
+ writeAdsOutput(data, format);
51
+ return;
52
+ }
53
+ writeAdsJson({ ok: true, data });
54
+ }
55
+ catch (err) {
56
+ if (err instanceof ApiError) {
57
+ writeAdsJson(parseXApiError(err.message, accountId));
58
+ process.exit(1);
59
+ }
60
+ writeAdsJson({ ok: false, error: { code: "NETWORK_ERROR", message: "Unexpected error" } });
61
+ process.exit(1);
62
+ }
63
+ },
64
+ });
65
+ //# sourceMappingURL=funding.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"funding.js","sourceRoot":"","sources":["../../../../src/commands/ads/x/funding.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const xCommand: import("citty").CommandDef<import("citty").ArgsDef>;
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/ads/x/index.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,QAAQ,qDAmCnB,CAAC"}
@@ -0,0 +1,50 @@
1
+ import { defineCommand } from "citty";
2
+ import { accountsCommand } from "./accounts.js";
3
+ import { activeEntitiesCommand } from "./active-entities.js";
4
+ import { audiencesCommand } from "./audiences.js";
5
+ import { campaignsCommand } from "./campaigns.js";
6
+ import { cardsCommand } from "./cards.js";
7
+ import { fundingCommand } from "./funding.js";
8
+ import { lineItemsCommand } from "./line-items.js";
9
+ import { mediaCommand } from "./media.js";
10
+ import { promotedTweetsCommand } from "./promoted-tweets.js";
11
+ import { statsCommand } from "./stats/index.js";
12
+ import { targetingConstantsCommand } from "./targeting-constants.js";
13
+ import { targetingCriteriaCommand } from "./targeting-criteria.js";
14
+ export const xCommand = defineCommand({
15
+ meta: {
16
+ name: "x",
17
+ description: `X (Twitter) Ads commands. Read campaigns, line items, promoted tweets, creatives, audiences, and analytics.
18
+
19
+ Start here:
20
+ baker ads x accounts — list accessible X Ads accounts
21
+ baker ads x stats sync --list-presets — see available stats presets
22
+ baker ads x targeting-constants --constant locations --q "Madrid"
23
+
24
+ Examples:
25
+ baker ads x campaigns --account-id 18ce53xyz
26
+ baker ads x line-items --account-id 18ce53xyz --campaign-ids abc
27
+ baker ads x promoted-tweets --account-id 18ce53xyz
28
+ baker ads x stats sync --preset campaign-engagement-7d --entity-ids abc,def
29
+ baker ads x stats job-create --entity CAMPAIGN --entity-ids abc \\
30
+ --start-time 2026-04-01T00:00:00Z --end-time 2026-05-01T00:00:00Z \\
31
+ --metric-groups ENGAGEMENT,BILLING --segmentation-type LOCATIONS
32
+
33
+ The CLI auto-detects --account-id when exactly one X Ads account is connected, or via BAKER_X_ADS_ACCOUNT_ID.`,
34
+ },
35
+ subCommands: {
36
+ accounts: accountsCommand,
37
+ funding: fundingCommand,
38
+ campaigns: campaignsCommand,
39
+ "line-items": lineItemsCommand,
40
+ "promoted-tweets": promotedTweetsCommand,
41
+ cards: cardsCommand,
42
+ media: mediaCommand,
43
+ audiences: audiencesCommand,
44
+ "targeting-criteria": targetingCriteriaCommand,
45
+ "targeting-constants": targetingConstantsCommand,
46
+ "active-entities": activeEntitiesCommand,
47
+ stats: statsCommand,
48
+ },
49
+ });
50
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/commands/ads/x/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAEnE,MAAM,CAAC,MAAM,QAAQ,GAAG,aAAa,CAAC;IACpC,IAAI,EAAE;QACJ,IAAI,EAAE,GAAG;QACT,WAAW,EAAE;;;;;;;;;;;;;;;;8GAgB6F;KAC3G;IACD,WAAW,EAAE;QACX,QAAQ,EAAE,eAAe;QACzB,OAAO,EAAE,cAAc;QACvB,SAAS,EAAE,gBAAgB;QAC3B,YAAY,EAAE,gBAAgB;QAC9B,iBAAiB,EAAE,qBAAqB;QACxC,KAAK,EAAE,YAAY;QACnB,KAAK,EAAE,YAAY;QACnB,SAAS,EAAE,gBAAgB;QAC3B,oBAAoB,EAAE,wBAAwB;QAC9C,qBAAqB,EAAE,yBAAyB;QAChD,iBAAiB,EAAE,qBAAqB;QACxC,KAAK,EAAE,YAAY;KACpB;CACF,CAAC,CAAC"}
@@ -0,0 +1,34 @@
1
+ export declare const lineItemsCommand: import("citty").CommandDef<{
2
+ readonly "account-id": {
3
+ readonly type: "string";
4
+ readonly description: "X Ads account ID";
5
+ readonly required: false;
6
+ };
7
+ readonly "campaign-ids": {
8
+ readonly type: "string";
9
+ readonly description: "CSV of campaign IDs";
10
+ readonly required: false;
11
+ };
12
+ readonly "line-item-ids": {
13
+ readonly type: "string";
14
+ readonly description: "CSV of line item IDs";
15
+ readonly required: false;
16
+ };
17
+ readonly "with-deleted": {
18
+ readonly type: "boolean";
19
+ readonly description: "Include deleted";
20
+ readonly required: false;
21
+ };
22
+ readonly "no-cache": {
23
+ readonly type: "boolean";
24
+ readonly description: "Skip cache";
25
+ readonly required: false;
26
+ };
27
+ readonly output: {
28
+ readonly type: "string";
29
+ readonly description: "Format: json|csv|md";
30
+ readonly required: false;
31
+ readonly default: "json";
32
+ };
33
+ }>;
34
+ //# sourceMappingURL=line-items.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"line-items.d.ts","sourceRoot":"","sources":["../../../../src/commands/ads/x/line-items.ts"],"names":[],"mappings":"AAkBA,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAsC3B,CAAC"}
@@ -0,0 +1,55 @@
1
+ import { defineCommand } from "citty";
2
+ import { registerSchema } from "../../../schemas.js";
3
+ import { resolveXAccountId } from "./output.js";
4
+ import { runListCommand } from "./run-list.js";
5
+ registerSchema({
6
+ command: "ads.x.lineItems",
7
+ description: "List line items (ad groups) for an X Ads account. Returns bid, product_type, objective, placements, schedule. Filter by campaign-ids or line-item-ids (CSV).",
8
+ args: {
9
+ "account-id": { type: "string", description: "X Ads account ID", required: false },
10
+ "campaign-ids": { type: "string", description: "CSV of campaign IDs", required: false },
11
+ "line-item-ids": { type: "string", description: "CSV of line item IDs", required: false },
12
+ "with-deleted": { type: "boolean", description: "Include deleted", required: false },
13
+ "no-cache": { type: "boolean", description: "Skip cache", required: false },
14
+ },
15
+ });
16
+ export const lineItemsCommand = defineCommand({
17
+ meta: {
18
+ name: "line-items",
19
+ description: `List X Ads line items (ad groups).
20
+
21
+ Examples:
22
+ baker ads x line-items --account-id 18ce53xyz --campaign-ids abc
23
+ baker ads x line-items --account-id 18ce53xyz --with-deleted`,
24
+ },
25
+ args: {
26
+ "account-id": { type: "string", description: "X Ads account ID", required: false },
27
+ "campaign-ids": { type: "string", description: "CSV of campaign IDs", required: false },
28
+ "line-item-ids": { type: "string", description: "CSV of line item IDs", required: false },
29
+ "with-deleted": { type: "boolean", description: "Include deleted", required: false },
30
+ "no-cache": { type: "boolean", description: "Skip cache", required: false },
31
+ output: { type: "string", description: "Format: json|csv|md", required: false, default: "json" },
32
+ },
33
+ run: async ({ args }) => {
34
+ const accountId = await resolveXAccountId(args);
35
+ const useCache = !args["no-cache"];
36
+ const today = new Date().toISOString().slice(0, 10);
37
+ const cacheKey = `line-items:${accountId}:${today}:${args["campaign-ids"] ?? ""}:${args["line-item-ids"] ?? ""}:${args["with-deleted"] ? "1" : "0"}`;
38
+ await runListCommand({
39
+ path: "/api/ads/x/line-items",
40
+ cacheCategory: "x-account-data",
41
+ cacheKey,
42
+ cacheTtlMs: 60 * 60 * 1000,
43
+ params: {
44
+ "account-id": accountId,
45
+ "campaign-ids": args["campaign-ids"],
46
+ "line-item-ids": args["line-item-ids"],
47
+ "with-deleted": args["with-deleted"] ? "true" : undefined,
48
+ },
49
+ format: args.output || "json",
50
+ accountId,
51
+ useCache,
52
+ });
53
+ },
54
+ });
55
+ //# sourceMappingURL=line-items.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"line-items.js","sourceRoot":"","sources":["../../../../src/commands/ads/x/line-items.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ export declare const mediaCommand: import("citty").CommandDef<{
2
+ readonly "account-id": {
3
+ readonly type: "string";
4
+ readonly description: "X Ads account ID";
5
+ readonly required: false;
6
+ };
7
+ readonly "media-type": {
8
+ readonly type: "string";
9
+ readonly description: "IMAGE | GIF | VIDEO";
10
+ readonly required: false;
11
+ };
12
+ readonly "no-cache": {
13
+ readonly type: "boolean";
14
+ readonly description: "Skip cache";
15
+ readonly required: false;
16
+ };
17
+ readonly output: {
18
+ readonly type: "string";
19
+ readonly description: "Format: json|csv|md";
20
+ readonly required: false;
21
+ readonly default: "json";
22
+ };
23
+ }>;
24
+ //# sourceMappingURL=media.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media.d.ts","sourceRoot":"","sources":["../../../../src/commands/ads/x/media.ts"],"names":[],"mappings":"AAmBA,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;EAkDvB,CAAC"}
@@ -0,0 +1,70 @@
1
+ import { defineCommand } from "citty";
2
+ import { ApiError, apiGet } from "../../../client.js";
3
+ import { registerSchema } from "../../../schemas.js";
4
+ import { cacheGet, cacheSet } from "../cache.js";
5
+ import { writeAdsJson, writeAdsOutput } from "../output.js";
6
+ import { parseXApiError } from "./error-parser.js";
7
+ import { resolveXAccountId } from "./output.js";
8
+ registerSchema({
9
+ command: "ads.x.media",
10
+ description: "List media assets in the X Ads media library (images, GIFs, videos). Filter by media-type (IMAGE, GIF, VIDEO).",
11
+ args: {
12
+ "account-id": { type: "string", description: "X Ads account ID", required: false },
13
+ "media-type": { type: "string", description: "IMAGE | GIF | VIDEO", required: false },
14
+ "no-cache": { type: "boolean", description: "Skip cache", required: false },
15
+ },
16
+ });
17
+ export const mediaCommand = defineCommand({
18
+ meta: {
19
+ name: "media",
20
+ description: `List media assets in the X Ads media library.
21
+
22
+ Examples:
23
+ baker ads x media --account-id 18ce53xyz
24
+ baker ads x media --account-id 18ce53xyz --media-type VIDEO`,
25
+ },
26
+ args: {
27
+ "account-id": { type: "string", description: "X Ads account ID", required: false },
28
+ "media-type": { type: "string", description: "IMAGE | GIF | VIDEO", required: false },
29
+ "no-cache": { type: "boolean", description: "Skip cache", required: false },
30
+ output: { type: "string", description: "Format: json|csv|md", required: false, default: "json" },
31
+ },
32
+ run: async ({ args }) => {
33
+ const accountId = await resolveXAccountId(args);
34
+ const useCache = !args["no-cache"];
35
+ const cacheKey = `media:${accountId}:${args["media-type"] ?? "ALL"}`;
36
+ if (useCache) {
37
+ const cached = cacheGet("x-account-data", cacheKey);
38
+ if (cached) {
39
+ writeAdsJson({ ok: true, data: cached.data, cached: true });
40
+ return;
41
+ }
42
+ }
43
+ try {
44
+ const params = { "account-id": accountId };
45
+ if (args["media-type"])
46
+ params["media-type"] = args["media-type"];
47
+ if (!useCache)
48
+ params["skip-cache"] = "true";
49
+ const data = await apiGet("/api/ads/x/media-library", params);
50
+ if (useCache) {
51
+ cacheSet("x-account-data", cacheKey, data, 6 * 60 * 60 * 1000);
52
+ }
53
+ const format = args.output || "json";
54
+ if (format !== "json") {
55
+ writeAdsOutput(data, format);
56
+ return;
57
+ }
58
+ writeAdsJson({ ok: true, data });
59
+ }
60
+ catch (err) {
61
+ if (err instanceof ApiError) {
62
+ writeAdsJson(parseXApiError(err.message, accountId));
63
+ process.exit(1);
64
+ }
65
+ writeAdsJson({ ok: false, error: { code: "NETWORK_ERROR", message: "Unexpected error" } });
66
+ process.exit(1);
67
+ }
68
+ },
69
+ });
70
+ //# sourceMappingURL=media.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media.js","sourceRoot":"","sources":["../../../../src/commands/ads/x/media.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export interface XAccountInfo {
2
+ id: string;
3
+ name: string;
4
+ approval_status?: string;
5
+ timezone?: string;
6
+ currency?: string;
7
+ }
8
+ /**
9
+ * Resolve an X Ads account_id from either --account-id, BAKER_X_ADS_ACCOUNT_ID, or
10
+ * (if exactly one account is connected) auto-detect.
11
+ */
12
+ export declare function resolveXAccountId(args: Record<string, unknown>): Promise<string>;
13
+ //# sourceMappingURL=output.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../../../src/commands/ads/x/output.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAiBD;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAmDtF"}
@@ -0,0 +1,75 @@
1
+ import { ApiError, apiGet } from "../../../client.js";
2
+ import { getEnv } from "../../../env.js";
3
+ import { handleConnectionError } from "../../../error-handler.js";
4
+ import { cacheGet, cacheSet } from "../cache.js";
5
+ import { writeAdsJson } from "../output.js";
6
+ const ACCOUNTS_CACHE_TTL_MS = 60 * 60 * 1000;
7
+ async function fetchXAccounts(useCache) {
8
+ if (useCache) {
9
+ const cached = cacheGet("x-accounts", "list");
10
+ if (cached)
11
+ return cached.data;
12
+ }
13
+ const params = !useCache ? { "skip-cache": "true" } : undefined;
14
+ const data = await apiGet("/api/ads/x/accounts", params);
15
+ if (useCache) {
16
+ cacheSet("x-accounts", "list", data, ACCOUNTS_CACHE_TTL_MS);
17
+ }
18
+ return data;
19
+ }
20
+ /**
21
+ * Resolve an X Ads account_id from either --account-id, BAKER_X_ADS_ACCOUNT_ID, or
22
+ * (if exactly one account is connected) auto-detect.
23
+ */
24
+ export async function resolveXAccountId(args) {
25
+ const fromArgs = args["account-id"];
26
+ const accountId = fromArgs || getEnv().BAKER_X_ADS_ACCOUNT_ID;
27
+ if (accountId) {
28
+ if (!/^[a-z0-9]+$/.test(accountId)) {
29
+ writeAdsJson({
30
+ ok: false,
31
+ error: {
32
+ code: "INVALID_ACCOUNT_ID",
33
+ message: "X Ads account ID must be a base36 string (lowercase letters and digits). Pass --account-id or set BAKER_X_ADS_ACCOUNT_ID.",
34
+ },
35
+ });
36
+ process.exit(1);
37
+ }
38
+ return accountId;
39
+ }
40
+ const useCache = !args["no-cache"];
41
+ try {
42
+ const accounts = await fetchXAccounts(useCache);
43
+ const [single] = accounts;
44
+ if (accounts.length === 1 && single) {
45
+ process.stderr.write(`Using account "${single.name}" (${single.id})\n`);
46
+ return single.id;
47
+ }
48
+ if (accounts.length === 0) {
49
+ handleConnectionError("x_ads");
50
+ }
51
+ const list = accounts.map((a) => ` ${a.id} ${a.name}`).join("\n");
52
+ writeAdsJson({
53
+ ok: false,
54
+ error: {
55
+ code: "MULTIPLE_ACCOUNTS",
56
+ message: `Multiple X Ads accounts found. Pass --account-id or set BAKER_X_ADS_ACCOUNT_ID:\n${list}`,
57
+ },
58
+ });
59
+ process.exit(1);
60
+ }
61
+ catch (err) {
62
+ if (err instanceof ApiError && (err.code === "UNAUTHORIZED" || err.code === "NOT_FOUND")) {
63
+ handleConnectionError("x_ads", err.message);
64
+ }
65
+ writeAdsJson({
66
+ ok: false,
67
+ error: {
68
+ code: "INVALID_ACCOUNT_ID",
69
+ message: "Could not auto-detect account. Pass --account-id or set BAKER_X_ADS_ACCOUNT_ID.",
70
+ },
71
+ });
72
+ process.exit(1);
73
+ }
74
+ }
75
+ //# sourceMappingURL=output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../../../../src/commands/ads/x/output.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAU5C,MAAM,qBAAqB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAE7C,KAAK,UAAU,cAAc,CAAC,QAAiB;IAC7C,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,MAAM,GAAG,QAAQ,CAAiB,YAAY,EAAE,MAAM,CAAC,CAAC;QAC9D,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC,IAAI,CAAC;IACjC,CAAC;IACD,MAAM,MAAM,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IAChE,MAAM,IAAI,GAAG,MAAM,MAAM,CAAiB,qBAAqB,EAAE,MAAM,CAAC,CAAC;IACzE,IAAI,QAAQ,EAAE,CAAC;QACb,QAAQ,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,qBAAqB,CAAC,CAAC;IAC9D,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAA6B;IACnE,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAuB,CAAC;IAC1D,MAAM,SAAS,GAAG,QAAQ,IAAI,MAAM,EAAE,CAAC,sBAAsB,CAAC;IAC9D,IAAI,SAAS,EAAE,CAAC;QACd,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YACnC,YAAY,CAAC;gBACX,EAAE,EAAE,KAAK;gBACT,KAAK,EAAE;oBACL,IAAI,EAAE,oBAAoB;oBAC1B,OAAO,EACL,2HAA2H;iBAC9H;aACF,CAAC,CAAC;YACH,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,QAAQ,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACnC,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,QAAQ,CAAC,CAAC;QAChD,MAAM,CAAC,MAAM,CAAC,GAAG,QAAQ,CAAC;QAC1B,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,EAAE,CAAC;YACpC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,kBAAkB,MAAM,CAAC,IAAI,MAAM,MAAM,CAAC,EAAE,KAAK,CAAC,CAAC;YACxE,OAAO,MAAM,CAAC,EAAE,CAAC;QACnB,CAAC;QACD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,qBAAqB,CAAC,OAAO,CAAC,CAAC;QACjC,CAAC;QACD,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpE,YAAY,CAAC;YACX,EAAE,EAAE,KAAK;YACT,KAAK,EAAE;gBACL,IAAI,EAAE,mBAAmB;gBACzB,OAAO,EAAE,oFAAoF,IAAI,EAAE;aACpG;SACF,CAAC,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,QAAQ,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,cAAc,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,CAAC,EAAE,CAAC;YACzF,qBAAqB,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;QAC9C,CAAC;QACD,YAAY,CAAC;YACX,EAAE,EAAE,KAAK;YACT,KAAK,EAAE;gBACL,IAAI,EAAE,oBAAoB;gBAC1B,OAAO,EAAE,iFAAiF;aAC3F;SACF,CAAC,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,15 @@
1
+ interface XStatsPreset {
2
+ name: string;
3
+ description: string;
4
+ entity: string;
5
+ metricGroups: string[];
6
+ granularity: "TOTAL" | "DAY" | "HOUR";
7
+ defaultDays: number;
8
+ placement: "ALL_ON_TWITTER" | "PUBLISHER_NETWORK";
9
+ }
10
+ export declare const X_STATS_PRESETS: XStatsPreset[];
11
+ export declare function getPreset(name: string): XStatsPreset | undefined;
12
+ /** Hour-aligned ISO 8601 string `daysAgo` days before now (UTC). */
13
+ export declare function isoHourFloor(daysAgo: number): string;
14
+ export {};
15
+ //# sourceMappingURL=presets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presets.d.ts","sourceRoot":"","sources":["../../../../src/commands/ads/x/presets.ts"],"names":[],"mappings":"AAAA,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,WAAW,EAAE,OAAO,GAAG,KAAK,GAAG,MAAM,CAAC;IACtC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,gBAAgB,GAAG,mBAAmB,CAAC;CACnD;AAED,eAAO,MAAM,eAAe,EAAE,YAAY,EA8CzC,CAAC;AAEF,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAEhE;AAED,oEAAoE;AACpE,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAOpD"}
@@ -0,0 +1,60 @@
1
+ export const X_STATS_PRESETS = [
2
+ {
3
+ name: "campaign-engagement-7d",
4
+ description: "Campaign-level engagements + impressions over the last 7 days, daily granularity",
5
+ entity: "CAMPAIGN",
6
+ metricGroups: ["ENGAGEMENT"],
7
+ granularity: "DAY",
8
+ defaultDays: 7,
9
+ placement: "ALL_ON_TWITTER",
10
+ },
11
+ {
12
+ name: "campaign-spend-30d",
13
+ description: "Campaign-level billed engagements + spend over the last 30 days, daily",
14
+ entity: "CAMPAIGN",
15
+ metricGroups: ["BILLING"],
16
+ granularity: "DAY",
17
+ defaultDays: 30,
18
+ placement: "ALL_ON_TWITTER",
19
+ },
20
+ {
21
+ name: "tweet-performance-7d",
22
+ description: "Promoted tweet engagement + media metrics over the last 7 days, daily",
23
+ entity: "PROMOTED_TWEET",
24
+ metricGroups: ["ENGAGEMENT", "MEDIA"],
25
+ granularity: "DAY",
26
+ defaultDays: 7,
27
+ placement: "ALL_ON_TWITTER",
28
+ },
29
+ {
30
+ name: "video-performance-30d",
31
+ description: "Promoted tweet video views/CTAs + engagement over the last 30 days, daily",
32
+ entity: "PROMOTED_TWEET",
33
+ metricGroups: ["VIDEO", "ENGAGEMENT"],
34
+ granularity: "DAY",
35
+ defaultDays: 30,
36
+ placement: "ALL_ON_TWITTER",
37
+ },
38
+ {
39
+ name: "line-item-conversions-30d",
40
+ description: "Line item web conversions + billing over the last 30 days, daily",
41
+ entity: "LINE_ITEM",
42
+ metricGroups: ["WEB_CONVERSION", "BILLING"],
43
+ granularity: "DAY",
44
+ defaultDays: 30,
45
+ placement: "ALL_ON_TWITTER",
46
+ },
47
+ ];
48
+ export function getPreset(name) {
49
+ return X_STATS_PRESETS.find((p) => p.name === name);
50
+ }
51
+ /** Hour-aligned ISO 8601 string `daysAgo` days before now (UTC). */
52
+ export function isoHourFloor(daysAgo) {
53
+ const d = new Date();
54
+ d.setUTCMilliseconds(0);
55
+ d.setUTCSeconds(0);
56
+ d.setUTCMinutes(0);
57
+ d.setUTCDate(d.getUTCDate() - daysAgo);
58
+ return d.toISOString();
59
+ }
60
+ //# sourceMappingURL=presets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presets.js","sourceRoot":"","sources":["../../../../src/commands/ads/x/presets.ts"],"names":[],"mappings":"AAUA,MAAM,CAAC,MAAM,eAAe,GAAmB;IAC7C;QACE,IAAI,EAAE,wBAAwB;QAC9B,WAAW,EAAE,kFAAkF;QAC/F,MAAM,EAAE,UAAU;QAClB,YAAY,EAAE,CAAC,YAAY,CAAC;QAC5B,WAAW,EAAE,KAAK;QAClB,WAAW,EAAE,CAAC;QACd,SAAS,EAAE,gBAAgB;KAC5B;IACD;QACE,IAAI,EAAE,oBAAoB;QAC1B,WAAW,EAAE,wEAAwE;QACrF,MAAM,EAAE,UAAU;QAClB,YAAY,EAAE,CAAC,SAAS,CAAC;QACzB,WAAW,EAAE,KAAK;QAClB,WAAW,EAAE,EAAE;QACf,SAAS,EAAE,gBAAgB;KAC5B;IACD;QACE,IAAI,EAAE,sBAAsB;QAC5B,WAAW,EAAE,uEAAuE;QACpF,MAAM,EAAE,gBAAgB;QACxB,YAAY,EAAE,CAAC,YAAY,EAAE,OAAO,CAAC;QACrC,WAAW,EAAE,KAAK;QAClB,WAAW,EAAE,CAAC;QACd,SAAS,EAAE,gBAAgB;KAC5B;IACD;QACE,IAAI,EAAE,uBAAuB;QAC7B,WAAW,EAAE,2EAA2E;QACxF,MAAM,EAAE,gBAAgB;QACxB,YAAY,EAAE,CAAC,OAAO,EAAE,YAAY,CAAC;QACrC,WAAW,EAAE,KAAK;QAClB,WAAW,EAAE,EAAE;QACf,SAAS,EAAE,gBAAgB;KAC5B;IACD;QACE,IAAI,EAAE,2BAA2B;QACjC,WAAW,EAAE,kEAAkE;QAC/E,MAAM,EAAE,WAAW;QACnB,YAAY,EAAE,CAAC,gBAAgB,EAAE,SAAS,CAAC;QAC3C,WAAW,EAAE,KAAK;QAClB,WAAW,EAAE,EAAE;QACf,SAAS,EAAE,gBAAgB;KAC5B;CACF,CAAC;AAEF,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;AACtD,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,YAAY,CAAC,OAAe;IAC1C,MAAM,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC;IACrB,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC;IACxB,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;IACnB,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;IACnB,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,EAAE,GAAG,OAAO,CAAC,CAAC;IACvC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;AACzB,CAAC"}
@@ -0,0 +1,29 @@
1
+ export declare const promotedTweetsCommand: import("citty").CommandDef<{
2
+ readonly "account-id": {
3
+ readonly type: "string";
4
+ readonly description: "X Ads account ID";
5
+ readonly required: false;
6
+ };
7
+ readonly "line-item-ids": {
8
+ readonly type: "string";
9
+ readonly description: "CSV of line item IDs";
10
+ readonly required: false;
11
+ };
12
+ readonly "with-deleted": {
13
+ readonly type: "boolean";
14
+ readonly description: "Include deleted";
15
+ readonly required: false;
16
+ };
17
+ readonly "no-cache": {
18
+ readonly type: "boolean";
19
+ readonly description: "Skip cache";
20
+ readonly required: false;
21
+ };
22
+ readonly output: {
23
+ readonly type: "string";
24
+ readonly description: "Format: json|csv|md";
25
+ readonly required: false;
26
+ readonly default: "json";
27
+ };
28
+ }>;
29
+ //# sourceMappingURL=promoted-tweets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promoted-tweets.d.ts","sourceRoot":"","sources":["../../../../src/commands/ads/x/promoted-tweets.ts"],"names":[],"mappings":"AAoBA,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoDhC,CAAC"}
@@ -0,0 +1,74 @@
1
+ import { defineCommand } from "citty";
2
+ import { ApiError, apiGet } from "../../../client.js";
3
+ import { registerSchema } from "../../../schemas.js";
4
+ import { cacheGet, cacheSet } from "../cache.js";
5
+ import { writeAdsJson, writeAdsOutput } from "../output.js";
6
+ import { parseXApiError } from "./error-parser.js";
7
+ import { resolveXAccountId } from "./output.js";
8
+ registerSchema({
9
+ command: "ads.x.promotedTweets",
10
+ description: "List promoted tweets for an X Ads account. Returns id, line_item_id, tweet_id, approval_status. Filter by line-item-ids (CSV).",
11
+ args: {
12
+ "account-id": { type: "string", description: "X Ads account ID", required: false },
13
+ "line-item-ids": { type: "string", description: "CSV of line item IDs", required: false },
14
+ "with-deleted": { type: "boolean", description: "Include deleted", required: false },
15
+ "no-cache": { type: "boolean", description: "Skip cache", required: false },
16
+ },
17
+ });
18
+ export const promotedTweetsCommand = defineCommand({
19
+ meta: {
20
+ name: "promoted-tweets",
21
+ description: `List X Ads promoted tweets.
22
+
23
+ Examples:
24
+ baker ads x promoted-tweets --account-id 18ce53xyz --line-item-ids abc,def`,
25
+ },
26
+ args: {
27
+ "account-id": { type: "string", description: "X Ads account ID", required: false },
28
+ "line-item-ids": { type: "string", description: "CSV of line item IDs", required: false },
29
+ "with-deleted": { type: "boolean", description: "Include deleted", required: false },
30
+ "no-cache": { type: "boolean", description: "Skip cache", required: false },
31
+ output: { type: "string", description: "Format: json|csv|md", required: false, default: "json" },
32
+ },
33
+ run: async ({ args }) => {
34
+ const accountId = await resolveXAccountId(args);
35
+ const useCache = !args["no-cache"];
36
+ const today = new Date().toISOString().slice(0, 10);
37
+ const cacheKey = `promoted-tweets:${accountId}:${today}:${args["line-item-ids"] ?? ""}:${args["with-deleted"] ? "1" : "0"}`;
38
+ if (useCache) {
39
+ const cached = cacheGet("x-account-data", cacheKey);
40
+ if (cached) {
41
+ writeAdsJson({ ok: true, data: cached.data, cached: true });
42
+ return;
43
+ }
44
+ }
45
+ try {
46
+ const params = { "account-id": accountId };
47
+ if (args["line-item-ids"])
48
+ params["line-item-ids"] = args["line-item-ids"];
49
+ if (args["with-deleted"])
50
+ params["with-deleted"] = "true";
51
+ if (!useCache)
52
+ params["skip-cache"] = "true";
53
+ const data = await apiGet("/api/ads/x/promoted-tweets", params);
54
+ if (useCache) {
55
+ cacheSet("x-account-data", cacheKey, data, 60 * 60 * 1000);
56
+ }
57
+ const format = args.output || "json";
58
+ if (format !== "json") {
59
+ writeAdsOutput(data, format);
60
+ return;
61
+ }
62
+ writeAdsJson({ ok: true, data });
63
+ }
64
+ catch (err) {
65
+ if (err instanceof ApiError) {
66
+ writeAdsJson(parseXApiError(err.message, accountId));
67
+ process.exit(1);
68
+ }
69
+ writeAdsJson({ ok: false, error: { code: "NETWORK_ERROR", message: "Unexpected error" } });
70
+ process.exit(1);
71
+ }
72
+ },
73
+ });
74
+ //# sourceMappingURL=promoted-tweets.js.map