@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.
- package/dist/cli.js +70 -46
- 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", "
|
|
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
|
|
1383
|
-
const
|
|
1384
|
-
const
|
|
1385
|
-
const
|
|
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
|
|
1390
|
-
const
|
|
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
|
|
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 =
|
|
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,
|
|
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>
|
|
4387
|
-
--adset <ids>
|
|
4388
|
-
--ad <ids>
|
|
4389
|
-
--
|
|
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
|
-
--
|
|
4394
|
-
--
|
|
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
|
-
--
|
|
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 --
|
|
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 --
|
|
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 --
|
|
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 --
|
|
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
|
|
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