@adkit/cli 1.12.10 → 1.12.12

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 (2) hide show
  1. package/dist/cli.js +70 -46
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -167,12 +167,14 @@ function buildAuthSuggestion(code) {
167
167
  var AdkitClient = class {
168
168
  apiKey;
169
169
  baseUrl;
170
+ clientVersion;
170
171
  projectId;
171
- constructor({ apiKey, baseUrl, projectId }) {
172
+ constructor({ apiKey, baseUrl, clientVersion, projectId }) {
172
173
  const isLocalhost = baseUrl.startsWith("http://localhost") || baseUrl.startsWith("http://127.0.0.1");
173
174
  if (baseUrl.startsWith("http://") && !isLocalhost) throw new Error("HTTPS is required \u2014 insecure HTTP base URLs are not allowed");
174
175
  this.apiKey = apiKey;
175
176
  this.baseUrl = baseUrl;
177
+ this.clientVersion = clientVersion;
176
178
  this.projectId = projectId;
177
179
  }
178
180
  // eslint-disable-next-line max-lines-per-function -- shared client error mapping is intentionally centralized here.
@@ -180,8 +182,11 @@ var AdkitClient = class {
180
182
  const url = `${this.baseUrl}${path3}`;
181
183
  const headers = {
182
184
  Authorization: `Bearer ${this.apiKey}`,
183
- "Content-Type": "application/json"
185
+ "Content-Type": "application/json",
186
+ "User-Agent": this.clientVersion ? `adkit-cli/${this.clientVersion}` : "adkit-cli",
187
+ "x-adkit-client": "cli"
184
188
  };
189
+ if (this.clientVersion) headers["x-adkit-client-version"] = this.clientVersion;
185
190
  if (this.projectId) headers["x-adkit-project-id"] = this.projectId;
186
191
  const init = { method, headers };
187
192
  if (body !== void 0) init.body = JSON.stringify(body);
@@ -1375,28 +1380,30 @@ function readMediaFormatFlag(value) {
1375
1380
  throw new CliError("INVALID_VALUE", `Invalid --media-format: ${value}`, "Use one of: default, square, vertical, horizontal.");
1376
1381
  }
1377
1382
  async function listResults(client, args, flags) {
1378
- validateFlags(flags, ["campaign", "adset", "ad", "status", "period", "from", "to", "metrics", "actions", "attribution-window", "breakdown", "sort", "limit", "confirm", "raw"], "manage meta results");
1383
+ validateFlags(flags, ["account", "campaign-ids", "adset-ids", "ad-ids", "statuses", "period", "from", "to", "fields", "conversion-event-keys", "attribution-window", "breakdowns", "sort", "sort-direction", "limit", "offset", "confirm", "raw"], "manage meta results");
1379
1384
  const accountId = typeof flags.account === "string" ? flags.account : void 0;
1380
1385
  const level = parseResultsLevel(args);
1381
1386
  warnIgnoredResultsArgs(args);
1382
- const campaign = typeof flags.campaign === "string" ? flags.campaign : void 0;
1383
- const adset = typeof flags.adset === "string" ? flags.adset : void 0;
1384
- const ad = typeof flags.ad === "string" ? flags.ad : void 0;
1385
- const status2 = typeof flags.status === "string" ? flags.status : void 0;
1387
+ const campaignIds = typeof flags["campaign-ids"] === "string" ? flags["campaign-ids"] : void 0;
1388
+ const adsetIds = typeof flags["adset-ids"] === "string" ? flags["adset-ids"] : void 0;
1389
+ const adIds = typeof flags["ad-ids"] === "string" ? flags["ad-ids"] : void 0;
1390
+ const statuses = typeof flags.statuses === "string" ? flags.statuses : void 0;
1386
1391
  const period = typeof flags.period === "string" ? flags.period : void 0;
1387
1392
  const from = typeof flags.from === "string" ? flags.from : void 0;
1388
1393
  const to = typeof flags.to === "string" ? flags.to : void 0;
1389
- const metrics = typeof flags.metrics === "string" ? flags.metrics : void 0;
1390
- const actions = typeof flags.actions === "string" ? flags.actions : void 0;
1394
+ const fields = typeof flags.fields === "string" ? flags.fields : void 0;
1395
+ const conversionEventKeys = typeof flags["conversion-event-keys"] === "string" ? flags["conversion-event-keys"] : void 0;
1391
1396
  const attributionWindow = typeof flags["attribution-window"] === "string" ? flags["attribution-window"] : void 0;
1392
- const breakdown = typeof flags.breakdown === "string" ? flags.breakdown : void 0;
1397
+ const breakdowns = typeof flags.breakdowns === "string" ? flags.breakdowns : void 0;
1393
1398
  const sort = typeof flags.sort === "string" ? flags.sort : void 0;
1399
+ const sortDirection = typeof flags["sort-direction"] === "string" ? flags["sort-direction"] : void 0;
1394
1400
  const limit = typeof flags.limit === "string" ? flags.limit : void 0;
1401
+ const offset = typeof flags.offset === "string" ? flags.offset : void 0;
1395
1402
  const confirm = flags.confirm === true ? "true" : void 0;
1396
1403
  const raw = flags.raw === true ? "true" : void 0;
1397
- const hasTimeBreakdown = breakdown?.split(",").some((b) => b === "day" || b === "week" || b === "month");
1404
+ const hasTimeBreakdown = breakdowns?.split(",").some((b) => b === "day" || b === "week" || b === "month");
1398
1405
  if (period === "maximum" && hasTimeBreakdown && !confirm) throw new CliError("INVALID_VALUE", "maximum date range with time breakdowns (day/week/month) can produce very large result sets. Add --confirm to proceed.");
1399
- const qs = queryString({ accountId, level, campaign, adset, ad, status: status2, period, from, to, metrics, actions, "attribution-window": attributionWindow, breakdown, sort, limit, confirm, raw });
1406
+ const qs = queryString({ accountId, level, campaignIds, adsetIds, adIds, statuses, period, from, to, fields, conversionEventKeys, attributionWindow, breakdowns, sort, sortDirection, limit, offset, confirm, raw });
1400
1407
  return client.get(`/manage/meta/results${qs}`);
1401
1408
  }
1402
1409
  async function createAd(client, _args, flags) {
@@ -4383,20 +4390,22 @@ var RESULTS_HELP = `adkit manage meta results \u2014 Meta performance insights
4383
4390
  [campaigns|adsets|ads] Optional level positional arg (default: campaigns)
4384
4391
 
4385
4392
  Flags:
4386
- --campaign <ids> Comma-separated campaign IDs
4387
- --adset <ids> Comma-separated ad set IDs
4388
- --ad <ids> Comma-separated ad IDs
4389
- --status <s> active, paused (filter by entity status)
4393
+ --campaign-ids <ids> Comma-separated campaign IDs
4394
+ --adset-ids <ids> Comma-separated ad set IDs
4395
+ --ad-ids <ids> Comma-separated ad IDs
4396
+ --statuses <s> active, paused (filter by entity status)
4390
4397
  --period <range> Relative range like 7d or preset: today, yesterday, this_month, last_month, this_quarter, last_quarter, this_year, last_year, maximum (default: 30d)
4391
4398
  --from <date> Start date, YYYY-MM-DD
4392
4399
  --to <date> End date, YYYY-MM-DD
4393
- --metrics <list> Override the default insights field preset
4394
- --actions <list> purchase,lead or all
4400
+ --fields <list> Normalized fields, e.g. spend, impressions, clicks, conversionEvents, etc
4401
+ --conversion-event-keys <list> purchase,lead or all
4395
4402
  --attribution-window <w> 1d_click, 7d_click, 1d_view, 7d_click_1d_view, 28d_click_1d_view
4396
- --breakdown <list> day,week,month,age,gender,country,region,device_platform,publisher_platform,platform_position,impression_device
4403
+ --breakdowns <list> day, week, month, age, gender, country, region, device_platform, publisher_platform, platform_position, impression_device
4397
4404
  --confirm Required with --period maximum plus any breakdown
4398
4405
  --sort <field> spend = descending, +spend = ascending
4406
+ --sort-direction <d> asc or desc
4399
4407
  --limit <n> Limit rows after sorting
4408
+ --offset <n> Skip rows after sorting
4400
4409
  --raw Return Meta's paginated response without conversion
4401
4410
 
4402
4411
  Output: always JSON, even in TTY mode.
@@ -4405,15 +4414,15 @@ Examples:
4405
4414
  # Campaign overview (default: last 30 days)
4406
4415
  adkit manage meta results
4407
4416
  # Top-spending ads for a campaign
4408
- adkit manage meta results ads --campaign 123 --sort spend --limit 10
4417
+ adkit manage meta results ads --campaign-ids 123 --sort spend --limit 10
4409
4418
  # Daily performance by age group
4410
- adkit manage meta results adsets --period 7d --breakdown day,age
4419
+ adkit manage meta results adsets --period 7d --breakdowns day,age
4411
4420
  # Country breakdown for all time
4412
- adkit manage meta results ads --period maximum --breakdown country --confirm
4421
+ adkit manage meta results ads --period maximum --breakdowns country --confirm
4413
4422
  # Conversion data for a campaign
4414
- adkit manage meta results --campaign 123 --actions purchase,lead
4423
+ adkit manage meta results --campaign-ids 123 --conversion-event-keys purchase,lead
4415
4424
  # Raw API response with custom metrics
4416
- adkit manage meta results --campaign 123 --raw --metrics spend,impressions,actions`.trim();
4425
+ adkit manage meta results --campaign-ids 123 --raw --fields spend,impressions,conversionEvents`.trim();
4417
4426
  var CREATIVE_HELP = `adkit manage meta creatives \u2014 Meta ad creatives
4418
4427
 
4419
4428
  Prefer using "ads create --media" which handles creative creation automatically.
@@ -5818,7 +5827,7 @@ function requireClient(flags, options = {}) {
5818
5827
  if (!apiKey) throw new CliError("NOT_AUTHENTICATED", "No API key found", "Run: adkit setup");
5819
5828
  const baseUrl = getBaseUrl();
5820
5829
  const projectId = options.projectOptional ? void 0 : selectedProject;
5821
- return new AdkitClient({ apiKey, baseUrl, projectId });
5830
+ return new AdkitClient({ apiKey, baseUrl, clientVersion: CLI_VERSION, projectId });
5822
5831
  }
5823
5832
  function toPrintListDisplayRows(rows, isJson) {
5824
5833
  if (isJson) return rows;
@@ -5908,11 +5917,11 @@ function printResultsCard(data) {
5908
5917
  const parts = [];
5909
5918
  const reportCurrency = str(report, "currency");
5910
5919
  const timezone = str(report, "timezone");
5911
- const attrWindow = str(report, "attribution_window");
5920
+ const attrWindow = str(report, "attributionWindow") ?? str(report, "attribution_window");
5912
5921
  if (reportCurrency) parts.push(reportCurrency);
5913
5922
  if (timezone) parts.push(timezone);
5914
5923
  if (attrWindow) parts.push(attrWindow);
5915
- const dr = nested(report, "date_range");
5924
+ const dr = nested(report, "dateRange") ?? nested(report, "date_range");
5916
5925
  if (dr) {
5917
5926
  const from = str(dr, "from");
5918
5927
  const to = str(dr, "to");
@@ -5920,7 +5929,7 @@ function printResultsCard(data) {
5920
5929
  }
5921
5930
  if (parts.length > 0) console.log(parts.join(" \xB7 "));
5922
5931
  }
5923
- const results = data.results;
5932
+ const results = Array.isArray(data.rows) ? data.rows : data.results;
5924
5933
  if (!Array.isArray(results) || results.length === 0) {
5925
5934
  console.log("\nNo results for this period.");
5926
5935
  printWarnings(data.warnings);
@@ -5928,40 +5937,43 @@ function printResultsCard(data) {
5928
5937
  }
5929
5938
  for (const row of results) {
5930
5939
  if (!isObject(row)) continue;
5931
- const name = str(row, "campaign_name") || str(row, "adset_name") || str(row, "ad_name") || "Unknown";
5940
+ const entity = nested(row, "entity");
5941
+ const metrics = nested(row, "metrics");
5942
+ const breakdown = nested(row, "breakdown");
5943
+ const name = (entity ? str(entity, "name") : void 0) || str(row, "campaign_name") || str(row, "adset_name") || str(row, "ad_name") || "Unknown";
5932
5944
  const titleParts = [name];
5933
- const status2 = str(row, "status");
5934
- const spend = num(row, "spend");
5945
+ const status2 = (entity ? str(entity, "status") : void 0) || str(row, "status");
5946
+ const spend = (metrics ? num(metrics, "spend") : void 0) ?? num(row, "spend");
5935
5947
  if (status2) titleParts.push(status2);
5936
5948
  if (spend !== void 0) titleParts.push(`${fmtCurrency(spend, currency)} spent`);
5937
- const dateStart = str(row, "date_start");
5938
- const dateStop = str(row, "date_stop");
5949
+ const dateStart = (breakdown ? str(breakdown, "day") ?? str(breakdown, "week") ?? str(breakdown, "month") ?? str(breakdown, "dateStart") : void 0) ?? str(row, "date_start");
5950
+ const dateStop = (breakdown ? str(breakdown, "dateStop") : void 0) ?? str(row, "date_stop");
5939
5951
  if (dateStart && dateStop) titleParts.push(`${fmtShortDate(dateStart)} \u2013 ${fmtShortDate(dateStop)}`);
5940
5952
  else if (dateStart) titleParts.push(fmtShortDate(dateStart));
5941
5953
  else if (dateStop) titleParts.push(fmtShortDate(dateStop));
5942
- const age = str(row, "age");
5954
+ const age = (breakdown ? str(breakdown, "age") : void 0) ?? str(row, "age");
5943
5955
  if (age) titleParts.push(age);
5944
- const gender = str(row, "gender");
5956
+ const gender = (breakdown ? str(breakdown, "gender") : void 0) ?? str(row, "gender");
5945
5957
  if (gender) titleParts.push(gender);
5946
- const country = str(row, "country");
5958
+ const country = (breakdown ? str(breakdown, "country") : void 0) ?? str(row, "country");
5947
5959
  if (country) titleParts.push(country);
5948
- const region = str(row, "region");
5960
+ const region = (breakdown ? str(breakdown, "region") : void 0) ?? str(row, "region");
5949
5961
  if (region) titleParts.push(region);
5950
- const devicePlatform = str(row, "device_platform");
5962
+ const devicePlatform = (breakdown ? str(breakdown, "devicePlatform") : void 0) ?? str(row, "device_platform");
5951
5963
  if (devicePlatform) titleParts.push(devicePlatform);
5952
- const publisherPlatform = str(row, "publisher_platform");
5964
+ const publisherPlatform = (breakdown ? str(breakdown, "publisherPlatform") : void 0) ?? str(row, "publisher_platform");
5953
5965
  if (publisherPlatform) titleParts.push(publisherPlatform);
5954
- const platformPosition = str(row, "platform_position");
5966
+ const platformPosition = (breakdown ? str(breakdown, "platformPosition") : void 0) ?? str(row, "platform_position");
5955
5967
  if (platformPosition) titleParts.push(platformPosition);
5956
- const impressionDevice = str(row, "impression_device");
5968
+ const impressionDevice = (breakdown ? str(breakdown, "impressionDevice") : void 0) ?? str(row, "impression_device");
5957
5969
  if (impressionDevice) titleParts.push(impressionDevice);
5958
5970
  console.log(`
5959
5971
  ${titleParts.join(" \xB7 ")}`);
5960
- const impressions = num(row, "impressions");
5972
+ const impressions = (metrics ? num(metrics, "impressions") : void 0) ?? num(row, "impressions");
5961
5973
  if (impressions !== void 0) console.log(` Impressions ${fmtNum(impressions)}`);
5962
- const reach = num(row, "reach");
5974
+ const reach = (metrics ? num(metrics, "reach") : void 0) ?? num(row, "reach");
5963
5975
  if (reach !== void 0) {
5964
- const freq = num(row, "frequency");
5976
+ const freq = (metrics ? num(metrics, "frequency") : void 0) ?? num(row, "frequency");
5965
5977
  const freqStr = freq !== void 0 ? ` (${fmtPct(freq)} freq)` : "";
5966
5978
  console.log(` Reach ${fmtNum(reach)}${freqStr}`);
5967
5979
  }
@@ -5971,14 +5983,17 @@ ${titleParts.join(" \xB7 ")}`);
5971
5983
  if (all) printClickLine("Clicks", all, currency);
5972
5984
  const outbound = nested(clicks, "outbound");
5973
5985
  if (outbound) printClickLine("Outbound", outbound, currency);
5986
+ } else if (metrics) {
5987
+ printClickLine("Clicks", { count: metrics.clicks, ctr: metrics.ctr, cpc: metrics.cpc }, currency);
5988
+ printClickLine("Outbound", { count: metrics.outboundClicks, ctr: metrics.outboundCtr, cpc: metrics.costPerOutboundClick }, currency);
5974
5989
  }
5975
- const actions = nested(row, "actions");
5990
+ const actions = nested(row, "conversionEvents") ?? nested(row, "actions");
5976
5991
  if (actions) {
5977
5992
  for (const [key, val] of Object.entries(actions)) {
5978
5993
  if (!isObject(val)) continue;
5979
5994
  const parts = [];
5980
5995
  const count = num(val, "count");
5981
- const cost = num(val, "cost");
5996
+ const cost = num(val, "costPerResult") ?? num(val, "cost");
5982
5997
  if (count !== void 0) parts.push(fmtNum(count));
5983
5998
  if (cost !== void 0) parts.push(`${fmtCurrency(cost, currency)} each`);
5984
5999
  if (parts.length > 0) console.log(` ${humanizeAction(key).padEnd(14)}${parts.join(" \xB7 ")}`);
@@ -5992,6 +6007,15 @@ ${titleParts.join(" \xB7 ")}`);
5992
6007
  for (const [key, val] of Object.entries(aq)) if (typeof val === "string" && val !== "UNKNOWN") parts.push(`${humanizeAction(key)}: ${val}`);
5993
6008
  if (parts.length > 0) console.log(` Ad Quality ${parts.join(" \xB7 ")}`);
5994
6009
  }
6010
+ } else if (metrics) {
6011
+ const parts = [];
6012
+ const qualityRanking = str(metrics, "qualityRanking");
6013
+ const engagementRateRanking = str(metrics, "engagementRateRanking");
6014
+ const conversionRateRanking = str(metrics, "conversionRateRanking");
6015
+ if (qualityRanking && qualityRanking !== "UNKNOWN") parts.push(`quality: ${qualityRanking}`);
6016
+ if (engagementRateRanking && engagementRateRanking !== "UNKNOWN") parts.push(`engagement rate: ${engagementRateRanking}`);
6017
+ if (conversionRateRanking && conversionRateRanking !== "UNKNOWN") parts.push(`conversion rate: ${conversionRateRanking}`);
6018
+ if (parts.length > 0) console.log(` Ad Quality ${parts.join(" \xB7 ")}`);
5995
6019
  }
5996
6020
  }
5997
6021
  printWarnings(data.warnings);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adkit/cli",
3
- "version": "1.12.10",
3
+ "version": "1.12.12",
4
4
  "description": "The Ads CLI for AI agents — manage Meta & Google ad campaigns, browse the ad library, and generate creatives from your terminal.",
5
5
  "keywords": [
6
6
  "ads cli",