@koda-sl/baker-cli 0.501.0 → 0.502.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.
- package/README.md +6 -0
- package/dist/{account-assets-GAKJQB6R.js → account-assets-LSXSW4RQ.js} +6 -6
- package/dist/{account-level-CAVVN4ZN.js → account-level-6T2WAPF3.js} +4 -4
- package/dist/{activities-CTGCJHLC.js → activities-LKLPORDI.js} +2 -2
- package/dist/{ads-HH5YTV4O.js → ads-CE3WX7VO.js} +2 -2
- package/dist/{ads-WU4ITH6J.js → ads-K2TIHZFC.js} +11 -11
- package/dist/{adsets-MMPN2SKX.js → adsets-MTB4LNE3.js} +15 -11
- package/dist/adsets-MTB4LNE3.js.map +1 -0
- package/dist/{asset-writes-IE3HUPWM.js → asset-writes-6QPHEAKF.js} +4 -4
- package/dist/{audience-writes-VXQTCSHH.js → audience-writes-3PSC7LRY.js} +4 -4
- package/dist/{audiences-75WHI3A3.js → audiences-UZ2V66OY.js} +6 -6
- package/dist/{campaigns-WHMJUFYV.js → campaigns-XSAJ3XSB.js} +13 -11
- package/dist/campaigns-XSAJ3XSB.js.map +1 -0
- package/dist/{catalogs-ORSZM5SY.js → catalogs-AIRFPJAJ.js} +3 -3
- package/dist/{chunk-GCLKAQUS.js → chunk-5YFQPJVS.js} +2 -2
- package/dist/{chunk-YIN6QNZD.js → chunk-6R2BU3FJ.js} +2 -2
- package/dist/{chunk-PRVX32SQ.js → chunk-HH7B2L3Z.js} +2 -2
- package/dist/{chunk-C4LZIBNP.js → chunk-KUY26RCF.js} +10 -1
- package/dist/{chunk-C4LZIBNP.js.map → chunk-KUY26RCF.js.map} +1 -1
- package/dist/{chunk-YGCRKABE.js → chunk-SHLA4JF7.js} +2 -2
- package/dist/{chunk-5B2WEPYR.js → chunk-SQCALAI7.js} +6 -3
- package/dist/chunk-SQCALAI7.js.map +1 -0
- package/dist/cli.js +1 -1
- package/dist/{copy-writes-OVCOZODC.js → copy-writes-2XW7VCDE.js} +4 -4
- package/dist/{creatives-RF3AG7HW.js → creatives-DPS46JXU.js} +4 -4
- package/dist/{custom-conversions-QFGIAISN.js → custom-conversions-E5RMKIPB.js} +4 -4
- package/dist/{insights-GISXHHOI.js → insights-7V3HWXS6.js} +2 -2
- package/dist/{instant-experiences-Y53I7FT4.js → instant-experiences-47IACDUJ.js} +3 -3
- package/dist/{leads-GF24GM54.js → leads-OYRLKTS6.js} +3 -3
- package/dist/{media-RTXIJEHY.js → media-2AKV75J4.js} +3 -3
- package/dist/{meta-AHI2HVBM.js → meta-CUWDMZQH.js} +32 -32
- package/dist/{page-photos-UUZRIJ4U.js → page-photos-BY7HNDX2.js} +3 -3
- package/dist/{preview-BM3NBH53.js → preview-SIKDCR27.js} +2 -2
- package/dist/{rule-writes-5FFQKSOE.js → rule-writes-BVHLNJLE.js} +4 -4
- package/dist/{rules-3FKLSJ5R.js → rules-R47FOFVB.js} +7 -7
- package/dist/{studies-ULLCWJSM.js → studies-ZYGAQVMK.js} +5 -5
- package/dist/{study-writes-ZAASDTGZ.js → study-writes-APXFR4OK.js} +3 -3
- package/dist/{targeting-TKV7XGRQ.js → targeting-EMKTVFJ2.js} +3 -3
- package/dist/{write-commands-S7AX24WF.js → write-commands-2L7T43YO.js} +21 -8
- package/dist/write-commands-2L7T43YO.js.map +1 -0
- package/package.json +1 -1
- package/dist/adsets-MMPN2SKX.js.map +0 -1
- package/dist/campaigns-WHMJUFYV.js.map +0 -1
- package/dist/chunk-5B2WEPYR.js.map +0 -1
- package/dist/write-commands-S7AX24WF.js.map +0 -1
- /package/dist/{account-assets-GAKJQB6R.js.map → account-assets-LSXSW4RQ.js.map} +0 -0
- /package/dist/{account-level-CAVVN4ZN.js.map → account-level-6T2WAPF3.js.map} +0 -0
- /package/dist/{activities-CTGCJHLC.js.map → activities-LKLPORDI.js.map} +0 -0
- /package/dist/{ads-HH5YTV4O.js.map → ads-CE3WX7VO.js.map} +0 -0
- /package/dist/{ads-WU4ITH6J.js.map → ads-K2TIHZFC.js.map} +0 -0
- /package/dist/{asset-writes-IE3HUPWM.js.map → asset-writes-6QPHEAKF.js.map} +0 -0
- /package/dist/{audience-writes-VXQTCSHH.js.map → audience-writes-3PSC7LRY.js.map} +0 -0
- /package/dist/{audiences-75WHI3A3.js.map → audiences-UZ2V66OY.js.map} +0 -0
- /package/dist/{catalogs-ORSZM5SY.js.map → catalogs-AIRFPJAJ.js.map} +0 -0
- /package/dist/{chunk-GCLKAQUS.js.map → chunk-5YFQPJVS.js.map} +0 -0
- /package/dist/{chunk-YIN6QNZD.js.map → chunk-6R2BU3FJ.js.map} +0 -0
- /package/dist/{chunk-PRVX32SQ.js.map → chunk-HH7B2L3Z.js.map} +0 -0
- /package/dist/{chunk-YGCRKABE.js.map → chunk-SHLA4JF7.js.map} +0 -0
- /package/dist/{copy-writes-OVCOZODC.js.map → copy-writes-2XW7VCDE.js.map} +0 -0
- /package/dist/{creatives-RF3AG7HW.js.map → creatives-DPS46JXU.js.map} +0 -0
- /package/dist/{custom-conversions-QFGIAISN.js.map → custom-conversions-E5RMKIPB.js.map} +0 -0
- /package/dist/{insights-GISXHHOI.js.map → insights-7V3HWXS6.js.map} +0 -0
- /package/dist/{instant-experiences-Y53I7FT4.js.map → instant-experiences-47IACDUJ.js.map} +0 -0
- /package/dist/{leads-GF24GM54.js.map → leads-OYRLKTS6.js.map} +0 -0
- /package/dist/{media-RTXIJEHY.js.map → media-2AKV75J4.js.map} +0 -0
- /package/dist/{meta-AHI2HVBM.js.map → meta-CUWDMZQH.js.map} +0 -0
- /package/dist/{page-photos-UUZRIJ4U.js.map → page-photos-BY7HNDX2.js.map} +0 -0
- /package/dist/{preview-BM3NBH53.js.map → preview-SIKDCR27.js.map} +0 -0
- /package/dist/{rule-writes-5FFQKSOE.js.map → rule-writes-BVHLNJLE.js.map} +0 -0
- /package/dist/{rules-3FKLSJ5R.js.map → rules-R47FOFVB.js.map} +0 -0
- /package/dist/{studies-ULLCWJSM.js.map → studies-ZYGAQVMK.js.map} +0 -0
- /package/dist/{study-writes-ZAASDTGZ.js.map → study-writes-APXFR4OK.js.map} +0 -0
- /package/dist/{targeting-TKV7XGRQ.js.map → targeting-EMKTVFJ2.js.map} +0 -0
package/README.md
CHANGED
|
@@ -1169,6 +1169,12 @@ baker ads meta lead-forms spec 987654321 > form.json # a live f
|
|
|
1169
1169
|
baker ads meta campaigns --account-id act_123 # ACTIVE only by default
|
|
1170
1170
|
baker ads meta ads --account-id act_123 --all-statuses # widen to everything
|
|
1171
1171
|
|
|
1172
|
+
# "Raise it from 80 to 100 a day" — listed budgets are in cents, as Meta sends them (a hint
|
|
1173
|
+
# says so); --daily-budget takes whole currency. A raise past 3x the current budget is refused
|
|
1174
|
+
# (usually an amount copied in cents) unless restated with --confirm-budget-increase.
|
|
1175
|
+
baker ads meta adsets --campaign-id 6123 # daily_budget "8000" is 80 EUR
|
|
1176
|
+
baker ads meta adsets update 6124 --daily-budget 100 # summary: daily budget 80 → 100 EUR
|
|
1177
|
+
|
|
1172
1178
|
# "Find the October ad" — Meta matches the name, so only that row is read
|
|
1173
1179
|
baker ads meta ads --account-id act_123 --all-statuses --name-contains octubre --fields id,name,adset_id,creative_id
|
|
1174
1180
|
|
|
@@ -221,11 +221,11 @@ var labelsCommand = defineCommand({
|
|
|
221
221
|
},
|
|
222
222
|
subCommands: {
|
|
223
223
|
list: () => labelsListCommand,
|
|
224
|
-
create: () => import("./asset-writes-
|
|
225
|
-
rename: () => import("./asset-writes-
|
|
226
|
-
delete: () => import("./asset-writes-
|
|
227
|
-
attach: () => import("./asset-writes-
|
|
228
|
-
detach: () => import("./asset-writes-
|
|
224
|
+
create: () => import("./asset-writes-6QPHEAKF.js").then((m) => m.labelsCreateCommand),
|
|
225
|
+
rename: () => import("./asset-writes-6QPHEAKF.js").then((m) => m.labelsRenameCommand),
|
|
226
|
+
delete: () => import("./asset-writes-6QPHEAKF.js").then((m) => m.labelsDeleteCommand),
|
|
227
|
+
attach: () => import("./asset-writes-6QPHEAKF.js").then((m) => m.labelsAttachCommand),
|
|
228
|
+
detach: () => import("./asset-writes-6QPHEAKF.js").then((m) => m.labelsDetachCommand)
|
|
229
229
|
},
|
|
230
230
|
args: labelsListArgs,
|
|
231
231
|
default: "list"
|
|
@@ -287,4 +287,4 @@ export {
|
|
|
287
287
|
instagramIdentityHints,
|
|
288
288
|
labelsCommand
|
|
289
289
|
};
|
|
290
|
-
//# sourceMappingURL=account-assets-
|
|
290
|
+
//# sourceMappingURL=account-assets-LSXSW4RQ.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
dayPartingFromFlags
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-5YFQPJVS.js";
|
|
4
4
|
import {
|
|
5
5
|
bareAccountId,
|
|
6
6
|
failWriteValidation,
|
|
@@ -8,8 +8,8 @@ import {
|
|
|
8
8
|
numberFlag,
|
|
9
9
|
requireTarget,
|
|
10
10
|
stageOp
|
|
11
|
-
} from "./chunk-
|
|
12
|
-
import "./chunk-
|
|
11
|
+
} from "./chunk-6R2BU3FJ.js";
|
|
12
|
+
import "./chunk-SQCALAI7.js";
|
|
13
13
|
import "./chunk-GDFJOCDO.js";
|
|
14
14
|
import {
|
|
15
15
|
handleMetaError
|
|
@@ -606,4 +606,4 @@ export {
|
|
|
606
606
|
pagePostsCommand,
|
|
607
607
|
reachFrequencyCommand
|
|
608
608
|
};
|
|
609
|
-
//# sourceMappingURL=account-level-
|
|
609
|
+
//# sourceMappingURL=account-level-6T2WAPF3.js.map
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
registerMetaListSchema,
|
|
4
4
|
shapeMetaListRows,
|
|
5
5
|
writeMetaListRows
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-KUY26RCF.js";
|
|
7
7
|
import {
|
|
8
8
|
csvOrJson,
|
|
9
9
|
handleMetaError,
|
|
@@ -72,4 +72,4 @@ Examples:
|
|
|
72
72
|
export {
|
|
73
73
|
activitiesCommand
|
|
74
74
|
};
|
|
75
|
-
//# sourceMappingURL=activities-
|
|
75
|
+
//# sourceMappingURL=activities-LKLPORDI.js.map
|
|
@@ -34,7 +34,7 @@ Full guides: __tooling__/docs/tools/baker/ads-<platform>.md (google|meta|linkedi
|
|
|
34
34
|
},
|
|
35
35
|
subCommands: {
|
|
36
36
|
google: () => import("./google-ZZCSZR63.js").then((m) => m.googleCommand),
|
|
37
|
-
meta: () => import("./meta-
|
|
37
|
+
meta: () => import("./meta-CUWDMZQH.js").then((m) => m.metaCommand),
|
|
38
38
|
linkedin: () => import("./linkedin-A4U6IGZX.js").then((m) => m.linkedinCommand),
|
|
39
39
|
x: () => import("./x-F5CSO2RN.js").then((m) => m.xCommand),
|
|
40
40
|
chatgpt: () => import("./chatgpt-23X76OFD.js").then((m) => m.chatgptCommand),
|
|
@@ -45,4 +45,4 @@ Full guides: __tooling__/docs/tools/baker/ads-<platform>.md (google|meta|linkedi
|
|
|
45
45
|
export {
|
|
46
46
|
adsCommand
|
|
47
47
|
};
|
|
48
|
-
//# sourceMappingURL=ads-
|
|
48
|
+
//# sourceMappingURL=ads-CE3WX7VO.js.map
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
registerMetaListSchema,
|
|
4
4
|
shapeMetaListRows,
|
|
5
5
|
writeMetaListRows
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-KUY26RCF.js";
|
|
7
7
|
import {
|
|
8
8
|
NAME_CONTAINS_ARG,
|
|
9
9
|
csvOrJson,
|
|
@@ -92,15 +92,15 @@ Examples:
|
|
|
92
92
|
},
|
|
93
93
|
subCommands: {
|
|
94
94
|
list: listCommand,
|
|
95
|
-
create: () => import("./write-commands-
|
|
96
|
-
update: () => import("./write-commands-
|
|
97
|
-
pause: () => import("./write-commands-
|
|
98
|
-
resume: () => import("./write-commands-
|
|
99
|
-
archive: () => import("./write-commands-
|
|
100
|
-
delete: () => import("./write-commands-
|
|
101
|
-
duplicate: () => import("./write-commands-
|
|
102
|
-
copy: () => import("./copy-writes-
|
|
103
|
-
retag: () => import("./write-commands-
|
|
95
|
+
create: () => import("./write-commands-2L7T43YO.js").then((m) => m.adsCreateCommand),
|
|
96
|
+
update: () => import("./write-commands-2L7T43YO.js").then((m) => m.adsUpdateCommand),
|
|
97
|
+
pause: () => import("./write-commands-2L7T43YO.js").then((m) => m.adsPauseCommand),
|
|
98
|
+
resume: () => import("./write-commands-2L7T43YO.js").then((m) => m.adsResumeCommand),
|
|
99
|
+
archive: () => import("./write-commands-2L7T43YO.js").then((m) => m.adsArchiveCommand),
|
|
100
|
+
delete: () => import("./write-commands-2L7T43YO.js").then((m) => m.adsDeleteCommand),
|
|
101
|
+
duplicate: () => import("./write-commands-2L7T43YO.js").then((m) => m.adsDuplicateCommand),
|
|
102
|
+
copy: () => import("./copy-writes-2XW7VCDE.js").then((m) => m.adsCopyCommand),
|
|
103
|
+
retag: () => import("./write-commands-2L7T43YO.js").then((m) => m.adsRetagCommand)
|
|
104
104
|
},
|
|
105
105
|
// `args` stays even though the parent has no `run`: citty scans rawArgs for the
|
|
106
106
|
// subcommand name using THIS command's arg defs, so without them `--account-id act_1`
|
|
@@ -112,4 +112,4 @@ Examples:
|
|
|
112
112
|
export {
|
|
113
113
|
adsListCommand
|
|
114
114
|
};
|
|
115
|
-
//# sourceMappingURL=ads-
|
|
115
|
+
//# sourceMappingURL=ads-K2TIHZFC.js.map
|
|
@@ -7,10 +7,11 @@ import {
|
|
|
7
7
|
} from "./chunk-G6XKD7QE.js";
|
|
8
8
|
import {
|
|
9
9
|
META_LIST_SHAPE_ARGS,
|
|
10
|
+
budgetUnitHints,
|
|
10
11
|
registerMetaListSchema,
|
|
11
12
|
shapeMetaListRows,
|
|
12
13
|
writeMetaListRows
|
|
13
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-KUY26RCF.js";
|
|
14
15
|
import {
|
|
15
16
|
NAME_CONTAINS_ARG,
|
|
16
17
|
csvOrJson,
|
|
@@ -130,7 +131,10 @@ var listCommand = defineCommand({
|
|
|
130
131
|
return;
|
|
131
132
|
}
|
|
132
133
|
const shaped = shapeMetaListRows("adsets", data, args);
|
|
133
|
-
writeMetaListRows("adsets", shaped, csvOrJson(args),
|
|
134
|
+
writeMetaListRows("adsets", shaped, csvOrJson(args), [
|
|
135
|
+
...statusFilterHints(data, effectiveStatus, "ad sets"),
|
|
136
|
+
...budgetUnitHints(data)
|
|
137
|
+
]);
|
|
134
138
|
} catch (err) {
|
|
135
139
|
handleMetaError(err);
|
|
136
140
|
}
|
|
@@ -156,14 +160,14 @@ Examples:
|
|
|
156
160
|
},
|
|
157
161
|
subCommands: {
|
|
158
162
|
list: listCommand,
|
|
159
|
-
create: () => import("./write-commands-
|
|
160
|
-
update: () => import("./write-commands-
|
|
161
|
-
pause: () => import("./write-commands-
|
|
162
|
-
resume: () => import("./write-commands-
|
|
163
|
-
archive: () => import("./write-commands-
|
|
164
|
-
delete: () => import("./write-commands-
|
|
165
|
-
duplicate: () => import("./write-commands-
|
|
166
|
-
copy: () => import("./copy-writes-
|
|
163
|
+
create: () => import("./write-commands-2L7T43YO.js").then((m) => m.adSetsCreateCommand),
|
|
164
|
+
update: () => import("./write-commands-2L7T43YO.js").then((m) => m.adSetsUpdateCommand),
|
|
165
|
+
pause: () => import("./write-commands-2L7T43YO.js").then((m) => m.adSetsPauseCommand),
|
|
166
|
+
resume: () => import("./write-commands-2L7T43YO.js").then((m) => m.adSetsResumeCommand),
|
|
167
|
+
archive: () => import("./write-commands-2L7T43YO.js").then((m) => m.adSetsArchiveCommand),
|
|
168
|
+
delete: () => import("./write-commands-2L7T43YO.js").then((m) => m.adSetsDeleteCommand),
|
|
169
|
+
duplicate: () => import("./write-commands-2L7T43YO.js").then((m) => m.adSetsDuplicateCommand),
|
|
170
|
+
copy: () => import("./copy-writes-2XW7VCDE.js").then((m) => m.adSetsCopyCommand)
|
|
167
171
|
},
|
|
168
172
|
// `args` stays even though the parent has no `run`: citty scans rawArgs for the
|
|
169
173
|
// subcommand name using THIS command's arg defs, so without them `--account-id act_1`
|
|
@@ -175,4 +179,4 @@ Examples:
|
|
|
175
179
|
export {
|
|
176
180
|
adsetsCommand
|
|
177
181
|
};
|
|
178
|
-
//# sourceMappingURL=adsets-
|
|
182
|
+
//# sourceMappingURL=adsets-MTB4LNE3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/ads/meta/adsets.ts"],"sourcesContent":["import path from \"node:path\";\nimport { defineCommand } from \"citty\";\nimport { readAudienceNames } from \"../../../audience-names.ts\";\nimport { NO_CACHE_ARG } from \"../../../cache-flag.ts\";\nimport { apiGet } from \"../../../client.ts\";\nimport { rememberedJev } from \"../../../engine/lib/remembered-nouls.ts\";\nimport type { ReviewUsage } from \"../../../engine/nodes/local/lib/render-review.ts\";\nimport { findWorkspaceRoot } from \"../../canvas/normalize-paths.ts\";\nimport { holdUnbilledSpend } from \"../../canvas/unbilled-spend.ts\";\nimport { writeAdsOutput } from \"../output.ts\";\nimport { adSetViewerRows, audienceNamesOf, flattenViewerRows, VIEWER_TABLE_COLUMNS } from \"./adset-viewers.ts\";\nimport {\n budgetUnitHints,\n META_LIST_SHAPE_ARGS,\n registerMetaListSchema,\n shapeMetaListRows,\n writeMetaListRows,\n} from \"./list-rows.ts\";\nimport {\n csvOrJson,\n handleMetaError,\n NAME_CONTAINS_ARG,\n resolveAccountIdArg,\n resolveEffectiveStatus,\n statusFilterHints,\n} from \"./shared.ts\";\n\nconst listArgs = {\n \"account-id\": { type: \"string\", description: \"Meta ad account ID\" },\n \"campaign-id\": { type: \"string\", description: \"Filter to one campaign\" },\n \"effective-status\": { type: \"string\", description: \"Comma-separated effective_status filter (overrides default)\" },\n \"all-statuses\": { type: \"boolean\", description: \"Drop the default ACTIVE filter\" },\n \"name-contains\": NAME_CONTAINS_ARG,\n limit: { type: \"string\", description: \"Max rows (default 1000)\" },\n \"no-cache\": NO_CACHE_ARG,\n audience: {\n type: \"boolean\",\n description:\n \"Who each ad set reaches, instead of the compact row: a viewer per ad set — temperature (cold|warm|hot), what they already know (brand/offer/product), placements, and the reasons, read from its targeting, the account's audiences and the campaign objective. Start here before writing an ad for an ad set: baker ads meta adsets --campaign-id 6123 --audience --output json\",\n },\n ...META_LIST_SHAPE_ARGS,\n} as const;\n\ntype MetaRow = Record<string, unknown>;\n\n/**\n * The audience list and the campaign objectives only sharpen the read: without them\n * each audience is read from its name and the objective is left out, so a refused\n * read degrades the viewer rather than failing the listing.\n */\nasync function readOrEmpty(path: string, params: Record<string, string>, label: string, hints: string[]) {\n try {\n return await apiGet<MetaRow[]>(path, params);\n } catch (err) {\n const message = err instanceof Error ? err.message : \"unknown error\";\n hints.push(`Could not read the account's ${label} (${message}); the viewer was read without them.`);\n return [];\n }\n}\n\nasync function writeAdSetViewers(\n adSets: MetaRow[],\n accountParams: Record<string, string>,\n format: string,\n hints: string[],\n): Promise<void> {\n const [audiences, campaigns] = await Promise.all([\n readOrEmpty(\"/api/ads/meta/audiences\", accountParams, \"audiences\", hints),\n readOrEmpty(\"/api/ads/meta/campaigns\", accountParams, \"campaigns\", hints),\n ]);\n const root = findWorkspaceRoot(process.cwd()) ?? process.cwd();\n const cacheDir = path.join(root, \"canvas\", \".cache\");\n const spent: ReviewUsage[] = [];\n const readName = await readAudienceNames(\n audienceNamesOf(adSets, audiences),\n rememberedJev(path.join(cacheDir, \"audience-names.json\"), (u) => spent.push(u)),\n );\n await holdUnbilledSpend(cacheDir, spent).catch(() => undefined);\n const rows = adSetViewerRows(adSets, audiences, campaigns, readName);\n if (rows.length > 0) {\n hints.push(\n 'Write each ad for the viewer of the ad set it will run in, then record it in the creative\\'s _definition.md: targetAdSet: \"<ad set id>\" and viewer: { temperature, knows, placements, source }.',\n );\n }\n if (format === \"md\" || format === \"csv\") {\n writeAdsOutput(flattenViewerRows(rows), format, [...VIEWER_TABLE_COLUMNS], hints);\n return;\n }\n writeAdsOutput(rows as unknown as MetaRow[], format, undefined, hints);\n}\n\nregisterMetaListSchema(\n \"adsets\",\n \"List ad sets in a Meta ad account, as a table by default: id, name, campaign_id, effective_status, optimization_goal, billing_event, bid_strategy, budgets, destination_type, is_dynamic_creative, learning_stage, end_time, created_time. Targeting is not in the compact row — ask for it with --fields id,name,targeting (or --full). --audience replaces the row with who each ad set reaches (a viewer: temperature, what they already know, placements, reasons) — read it before writing an ad for an ad set. Start here: baker ads meta adsets --campaign-id 6123 --all-statuses. --output json returns the rows in the envelope.\",\n listArgs,\n);\n\nconst listCommand = defineCommand({\n meta: {\n name: \"list\",\n description:\n \"List ad sets in a Meta ad account. Runs by default when no subcommand is given. Example: baker ads meta adsets --account-id act_123\",\n },\n args: listArgs,\n run: async ({ args }) => {\n const accountId = resolveAccountIdArg(args);\n const effectiveStatus = resolveEffectiveStatus(args);\n try {\n const params: Record<string, string> = { \"account-id\": accountId };\n if (args[\"campaign-id\"]) params[\"campaign-id\"] = args[\"campaign-id\"] as string;\n if (effectiveStatus) params[\"effective-status\"] = effectiveStatus;\n if (args[\"name-contains\"]) params[\"name-contains\"] = args[\"name-contains\"] as string;\n if (args.limit) params.limit = args.limit as string;\n if (args[\"no-cache\"]) params[\"skip-cache\"] = \"true\";\n const data = await apiGet<Array<Record<string, unknown>>>(\"/api/ads/meta/adsets\", params);\n if (args.audience) {\n const hints = statusFilterHints(data, effectiveStatus, \"ad sets\");\n const accountParams: Record<string, string> = { \"account-id\": accountId };\n if (args[\"no-cache\"]) accountParams[\"skip-cache\"] = \"true\";\n await writeAdSetViewers(data, accountParams, csvOrJson(args), hints);\n return;\n }\n const shaped = shapeMetaListRows(\"adsets\", data, args);\n writeMetaListRows(\"adsets\", shaped, csvOrJson(args), [\n ...statusFilterHints(data, effectiveStatus, \"ad sets\"),\n ...budgetUnitHints(data),\n ]);\n } catch (err) {\n handleMetaError(err);\n }\n },\n});\n\nexport const adsetsCommand = defineCommand({\n meta: {\n name: \"adsets\",\n description: `List ad sets in a Meta ad account, or stage writes (create/update/pause/resume/archive/delete/duplicate/copy).\nDefaults to ACTIVE only. Write subcommands stage ops on this chat's draft.\n\nListings print a table by default: id, name, campaign_id, effective_status, optimization_goal, billing_event,\nbid_strategy, budgets, destination_type, is_dynamic_creative, learning_stage, end_time, created_time. Targeting\nis not in the compact row — ask for it with --fields (dotted paths) or --full. --output json returns the rows as JSON.\n\nExamples:\n baker ads meta adsets --account-id act_123\n baker ads meta adsets --campaign-id 6123456789\n baker ads meta adsets --account-id act_123 --all-statuses --name-contains retargeting — find one ad set by name\n baker ads meta adsets --campaign-id 6123456789 --fields id,name,targeting.geo_locations\n baker ads meta adsets --campaign-id 6123456789 --audience --output json — who each ad set reaches (viewer per ad set)\n baker ads meta adsets create --campaign meta_temp_ab12 --name \"US 25-54\" --optimization-goal LINK_CLICKS --billing-event IMPRESSIONS --daily-budget 50 --targeting-file t.json`,\n },\n subCommands: {\n list: listCommand,\n create: () => import(\"./write-commands.ts\").then((m) => m.adSetsCreateCommand),\n update: () => import(\"./write-commands.ts\").then((m) => m.adSetsUpdateCommand),\n pause: () => import(\"./write-commands.ts\").then((m) => m.adSetsPauseCommand),\n resume: () => import(\"./write-commands.ts\").then((m) => m.adSetsResumeCommand),\n archive: () => import(\"./write-commands.ts\").then((m) => m.adSetsArchiveCommand),\n delete: () => import(\"./write-commands.ts\").then((m) => m.adSetsDeleteCommand),\n duplicate: () => import(\"./write-commands.ts\").then((m) => m.adSetsDuplicateCommand),\n copy: () => import(\"./copy-writes.ts\").then((m) => m.adSetsCopyCommand),\n },\n // `args` stays even though the parent has no `run`: citty scans rawArgs for the\n // subcommand name using THIS command's arg defs, so without them `--account-id act_1`\n // would read `act_1` as a subcommand. `default` (not `run`) dispatches the bare\n // invocation — citty falls through to `run` after a subcommand, double-executing it.\n args: listArgs,\n default: \"list\",\n});\n"],"mappings":"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","names":["path"]}
|
|
@@ -9,9 +9,9 @@ import {
|
|
|
9
9
|
labelsDetachCommand,
|
|
10
10
|
labelsRenameCommand,
|
|
11
11
|
mediaDeleteCommand
|
|
12
|
-
} from "./chunk-
|
|
13
|
-
import "./chunk-
|
|
14
|
-
import "./chunk-
|
|
12
|
+
} from "./chunk-HH7B2L3Z.js";
|
|
13
|
+
import "./chunk-6R2BU3FJ.js";
|
|
14
|
+
import "./chunk-SQCALAI7.js";
|
|
15
15
|
import "./chunk-GDFJOCDO.js";
|
|
16
16
|
import "./chunk-B2POVFR2.js";
|
|
17
17
|
import "./chunk-ERSX3MKH.js";
|
|
@@ -45,4 +45,4 @@ export {
|
|
|
45
45
|
labelsRenameCommand,
|
|
46
46
|
mediaDeleteCommand
|
|
47
47
|
};
|
|
48
|
-
//# sourceMappingURL=asset-writes-
|
|
48
|
+
//# sourceMappingURL=asset-writes-6QPHEAKF.js.map
|
|
@@ -3,19 +3,19 @@ import {
|
|
|
3
3
|
customerListBatches,
|
|
4
4
|
customerListFromFile,
|
|
5
5
|
customerListUploadRefusal
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-SHLA4JF7.js";
|
|
7
7
|
import {
|
|
8
8
|
bareAccountId,
|
|
9
9
|
failWriteValidation,
|
|
10
10
|
repeatedListFlag,
|
|
11
11
|
requireTarget,
|
|
12
12
|
stageOp
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-6R2BU3FJ.js";
|
|
14
14
|
import {
|
|
15
15
|
CUSTOMER_LIST_BATCH_ROWS,
|
|
16
16
|
CUSTOMER_LIST_MAX_BATCHES,
|
|
17
17
|
brandSafetyTargetingFields
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-SQCALAI7.js";
|
|
19
19
|
import "./chunk-GDFJOCDO.js";
|
|
20
20
|
import {
|
|
21
21
|
csvOrJson,
|
|
@@ -322,4 +322,4 @@ export {
|
|
|
322
322
|
savedAudiencesCommand,
|
|
323
323
|
targetingFromSavedAudience
|
|
324
324
|
};
|
|
325
|
-
//# sourceMappingURL=audience-writes-
|
|
325
|
+
//# sourceMappingURL=audience-writes-3PSC7LRY.js.map
|
|
@@ -67,11 +67,11 @@ Examples:
|
|
|
67
67
|
},
|
|
68
68
|
subCommands: {
|
|
69
69
|
list: listCommand,
|
|
70
|
-
create: () => import("./write-commands-
|
|
71
|
-
update: () => import("./write-commands-
|
|
72
|
-
delete: () => import("./audience-writes-
|
|
73
|
-
members: () => import("./audience-writes-
|
|
74
|
-
saved: () => import("./audience-writes-
|
|
70
|
+
create: () => import("./write-commands-2L7T43YO.js").then((m) => m.audiencesCreateCommand),
|
|
71
|
+
update: () => import("./write-commands-2L7T43YO.js").then((m) => m.audiencesUpdateCommand),
|
|
72
|
+
delete: () => import("./audience-writes-3PSC7LRY.js").then((m) => m.audiencesDeleteCommand),
|
|
73
|
+
members: () => import("./audience-writes-3PSC7LRY.js").then((m) => m.audiencesMembersCommand),
|
|
74
|
+
saved: () => import("./audience-writes-3PSC7LRY.js").then((m) => m.savedAudiencesCommand)
|
|
75
75
|
},
|
|
76
76
|
// `args` stays even though the parent has no `run`: citty scans rawArgs for the
|
|
77
77
|
// subcommand name using THIS command's arg defs, so without them `--account-id act_1`
|
|
@@ -83,4 +83,4 @@ Examples:
|
|
|
83
83
|
export {
|
|
84
84
|
audiencesCommand
|
|
85
85
|
};
|
|
86
|
-
//# sourceMappingURL=audiences-
|
|
86
|
+
//# sourceMappingURL=audiences-UZ2V66OY.js.map
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
META_LIST_SHAPE_ARGS,
|
|
3
|
+
budgetUnitHints,
|
|
3
4
|
registerMetaListSchema,
|
|
4
5
|
shapeMetaListRows,
|
|
5
6
|
writeMetaListRows
|
|
6
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-KUY26RCF.js";
|
|
7
8
|
import {
|
|
8
9
|
NAME_CONTAINS_ARG,
|
|
9
10
|
csvOrJson,
|
|
@@ -71,7 +72,8 @@ var listCommand = defineCommand({
|
|
|
71
72
|
const shaped = shapeMetaListRows("campaigns", data, args);
|
|
72
73
|
writeMetaListRows("campaigns", shaped, csvOrJson(args), [
|
|
73
74
|
...statusFilterHints(data, effectiveStatus, "campaigns"),
|
|
74
|
-
...advantagePlusHints(data)
|
|
75
|
+
...advantagePlusHints(data),
|
|
76
|
+
...budgetUnitHints(data)
|
|
75
77
|
]);
|
|
76
78
|
} catch (err) {
|
|
77
79
|
handleMetaError(err);
|
|
@@ -105,14 +107,14 @@ Examples:
|
|
|
105
107
|
},
|
|
106
108
|
subCommands: {
|
|
107
109
|
list: listCommand,
|
|
108
|
-
create: () => import("./write-commands-
|
|
109
|
-
update: () => import("./write-commands-
|
|
110
|
-
pause: () => import("./write-commands-
|
|
111
|
-
resume: () => import("./write-commands-
|
|
112
|
-
archive: () => import("./write-commands-
|
|
113
|
-
delete: () => import("./write-commands-
|
|
114
|
-
duplicate: () => import("./write-commands-
|
|
115
|
-
copy: () => import("./copy-writes-
|
|
110
|
+
create: () => import("./write-commands-2L7T43YO.js").then((m) => m.campaignsCreateCommand),
|
|
111
|
+
update: () => import("./write-commands-2L7T43YO.js").then((m) => m.campaignsUpdateCommand),
|
|
112
|
+
pause: () => import("./write-commands-2L7T43YO.js").then((m) => m.campaignsPauseCommand),
|
|
113
|
+
resume: () => import("./write-commands-2L7T43YO.js").then((m) => m.campaignsResumeCommand),
|
|
114
|
+
archive: () => import("./write-commands-2L7T43YO.js").then((m) => m.campaignsArchiveCommand),
|
|
115
|
+
delete: () => import("./write-commands-2L7T43YO.js").then((m) => m.campaignsDeleteCommand),
|
|
116
|
+
duplicate: () => import("./write-commands-2L7T43YO.js").then((m) => m.campaignsDuplicateCommand),
|
|
117
|
+
copy: () => import("./copy-writes-2XW7VCDE.js").then((m) => m.campaignsCopyCommand)
|
|
116
118
|
},
|
|
117
119
|
// `args` stays even though the parent has no `run`: citty scans rawArgs for the
|
|
118
120
|
// subcommand name using THIS command's arg defs, so without them `--account-id act_1`
|
|
@@ -125,4 +127,4 @@ export {
|
|
|
125
127
|
advantagePlusHints,
|
|
126
128
|
campaignsCommand
|
|
127
129
|
};
|
|
128
|
-
//# sourceMappingURL=campaigns-
|
|
130
|
+
//# sourceMappingURL=campaigns-XSAJ3XSB.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/ads/meta/campaigns.ts"],"sourcesContent":["import { defineCommand } from \"citty\";\nimport { NO_CACHE_ARG } from \"../../../cache-flag.ts\";\nimport { apiGet } from \"../../../client.ts\";\nimport {\n budgetUnitHints,\n META_LIST_SHAPE_ARGS,\n registerMetaListSchema,\n shapeMetaListRows,\n writeMetaListRows,\n} from \"./list-rows.ts\";\nimport {\n csvOrJson,\n handleMetaError,\n NAME_CONTAINS_ARG,\n resolveAccountIdArg,\n resolveEffectiveStatus,\n statusFilterHints,\n} from \"./shared.ts\";\n\n/**\n * Which listed campaigns Meta counts as Advantage+, read off the derived\n * `advantage_state_info` — a hint rather than a column, so the compact row of a\n * 100-campaign account stays small. Advantage+ is not a switch: it follows from\n * a campaign budget, Advantage+ audience and automatic placements.\n */\nexport function advantagePlusHints(rows: ReadonlyArray<Record<string, unknown>>): string[] {\n const named = rows.flatMap((row) => {\n const info = row.advantage_state_info as { advantage_state?: unknown } | undefined;\n const state = info?.advantage_state;\n return typeof state === \"string\" && state.startsWith(\"ADVANTAGE_PLUS_\")\n ? [`${String(row.id)} (${state.slice(\"ADVANTAGE_PLUS_\".length).toLowerCase()})`]\n : [];\n });\n return named.length > 0\n ? [\n `Advantage+ campaigns: ${named.join(\", \")}. Per-lever states (budget, audience, placements): --fields id,name,advantage_state_info.`,\n ]\n : [];\n}\n\nconst listArgs = {\n \"account-id\": { type: \"string\", description: \"Meta ad account ID\" },\n \"effective-status\": { type: \"string\", description: \"Comma-separated effective_status filter (overrides default)\" },\n \"all-statuses\": { type: \"boolean\", description: \"Drop the default ACTIVE filter and return everything\" },\n \"name-contains\": NAME_CONTAINS_ARG,\n limit: { type: \"string\", description: \"Max rows (default 1000)\" },\n \"no-cache\": NO_CACHE_ARG,\n ...META_LIST_SHAPE_ARGS,\n} as const;\n\nregisterMetaListSchema(\n \"campaigns\",\n \"List campaigns in a Meta ad account, as a table by default: id, name, effective_status, daily_budget, lifetime_budget, created_date. ACTIVE only unless --all-statuses. Start here: baker ads meta campaigns --account-id act_123 --all-statuses. --fields takes dotted paths for anything else (e.g. id,name,objective,bid_strategy,special_ad_categories,advantage_state_info); --full returns every field Meta sent; --output json returns the rows in the envelope. A hint names the campaigns Meta counts as Advantage+.\",\n listArgs,\n);\n\nconst listCommand = defineCommand({\n meta: {\n name: \"list\",\n description:\n \"List campaigns for a Meta ad account. Runs by default when no subcommand is given. Example: baker ads meta campaigns --account-id act_123\",\n },\n args: listArgs,\n run: async ({ args }) => {\n const accountId = resolveAccountIdArg(args);\n const effectiveStatus = resolveEffectiveStatus(args);\n try {\n const params: Record<string, string> = { \"account-id\": accountId };\n if (effectiveStatus) params[\"effective-status\"] = effectiveStatus;\n if (args[\"name-contains\"]) params[\"name-contains\"] = args[\"name-contains\"] as string;\n if (args.limit) params.limit = args.limit as string;\n if (args[\"no-cache\"]) params[\"skip-cache\"] = \"true\";\n const data = await apiGet<Array<Record<string, unknown>>>(\"/api/ads/meta/campaigns\", params);\n const shaped = shapeMetaListRows(\"campaigns\", data, args);\n writeMetaListRows(\"campaigns\", shaped, csvOrJson(args), [\n ...statusFilterHints(data, effectiveStatus, \"campaigns\"),\n ...advantagePlusHints(data),\n ...budgetUnitHints(data),\n ]);\n } catch (err) {\n handleMetaError(err);\n }\n },\n});\n\nexport const campaignsCommand = defineCommand({\n meta: {\n name: \"campaigns\",\n description: `List campaigns for a Meta ad account, or stage writes (create/update/pause/resume/archive/delete/duplicate/copy).\nDefaults to ACTIVE only — pass --all-statuses to widen. Write subcommands stage ops on this chat's draft and\napply only when the chat is published.\n\nIn Meta's API \"campaign\" is the top-of-tree object (what marketers usually call a campaign group).\nThe dashboard shows effective_status: ACTIVE, PAUSED, DELETED, ARCHIVED, IN_PROCESS, WITH_ISSUES, etc.\n\nListings print a table by default: id, name, effective_status, daily/lifetime budget, created_date.\n--fields takes dotted paths for anything else (objective, bid_strategy, special_ad_categories, created_time,\nadvantage_state_info). A hint names the campaigns Meta counts as Advantage+ — a state Meta derives from a\ncampaign budget, Advantage+ audience and automatic placements on every ad set, not a setting;\n--full returns every field; --output json returns the same rows in the { ok, data } envelope.\n\nExamples:\n baker ads meta campaigns --account-id act_123 # ACTIVE only\n baker ads meta campaigns --account-id act_123 --all-statuses # everything\n baker ads meta campaigns --account-id act_123 --all-statuses --name-contains Q3 # find one by name\n baker ads meta campaigns --account-id act_123 --fields id,name,objective,bid_strategy,special_ad_categories\n baker ads meta campaigns --account-id act_123 --output json # rows as JSON\n baker ads meta campaigns create --account-id act_123 --name \"Q3\" --objective OUTCOME_LEADS --daily-budget 50\n baker ads meta campaigns pause 6123 --account-id act_123`,\n },\n subCommands: {\n list: listCommand,\n create: () => import(\"./write-commands.ts\").then((m) => m.campaignsCreateCommand),\n update: () => import(\"./write-commands.ts\").then((m) => m.campaignsUpdateCommand),\n pause: () => import(\"./write-commands.ts\").then((m) => m.campaignsPauseCommand),\n resume: () => import(\"./write-commands.ts\").then((m) => m.campaignsResumeCommand),\n archive: () => import(\"./write-commands.ts\").then((m) => m.campaignsArchiveCommand),\n delete: () => import(\"./write-commands.ts\").then((m) => m.campaignsDeleteCommand),\n duplicate: () => import(\"./write-commands.ts\").then((m) => m.campaignsDuplicateCommand),\n copy: () => import(\"./copy-writes.ts\").then((m) => m.campaignsCopyCommand),\n },\n // `args` stays even though the parent has no `run`: citty scans rawArgs for the\n // subcommand name using THIS command's arg defs, so without them `--account-id act_1`\n // would read `act_1` as a subcommand. `default` (not `run`) dispatches the bare\n // invocation — citty falls through to `run` after a subcommand, double-executing it.\n args: listArgs,\n default: \"list\",\n});\n"],"mappings":"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","names":[]}
|
|
@@ -7,10 +7,10 @@ import {
|
|
|
7
7
|
requireTarget,
|
|
8
8
|
stageOp,
|
|
9
9
|
upper
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-6R2BU3FJ.js";
|
|
11
11
|
import {
|
|
12
12
|
retailerIdFilter
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-SQCALAI7.js";
|
|
14
14
|
import "./chunk-GDFJOCDO.js";
|
|
15
15
|
import {
|
|
16
16
|
csvOrJson,
|
|
@@ -776,4 +776,4 @@ export {
|
|
|
776
776
|
productFieldsFromArgs,
|
|
777
777
|
productSetFilterFromArgs
|
|
778
778
|
};
|
|
779
|
-
//# sourceMappingURL=catalogs-
|
|
779
|
+
//# sourceMappingURL=catalogs-AIRFPJAJ.js.map
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
failWriteValidation,
|
|
3
3
|
parseDateFlag,
|
|
4
4
|
parseMoneyFlag
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-6R2BU3FJ.js";
|
|
6
6
|
import {
|
|
7
7
|
repeatedValues
|
|
8
8
|
} from "./chunk-ERSX3MKH.js";
|
|
@@ -284,4 +284,4 @@ export {
|
|
|
284
284
|
clearFromFlags,
|
|
285
285
|
clearArg
|
|
286
286
|
};
|
|
287
|
-
//# sourceMappingURL=chunk-
|
|
287
|
+
//# sourceMappingURL=chunk-5YFQPJVS.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
metaDraftOpInputSchema
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-SQCALAI7.js";
|
|
4
4
|
import {
|
|
5
5
|
handleMetaError,
|
|
6
6
|
resolveAccountIdArg
|
|
@@ -204,4 +204,4 @@ export {
|
|
|
204
204
|
stageOps,
|
|
205
205
|
stageStatusChange
|
|
206
206
|
};
|
|
207
|
-
//# sourceMappingURL=chunk-
|
|
207
|
+
//# sourceMappingURL=chunk-6R2BU3FJ.js.map
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
requireTarget,
|
|
6
6
|
stageOp,
|
|
7
7
|
stageOps
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-6R2BU3FJ.js";
|
|
9
9
|
import {
|
|
10
10
|
repeatedValues
|
|
11
11
|
} from "./chunk-ERSX3MKH.js";
|
|
@@ -216,4 +216,4 @@ export {
|
|
|
216
216
|
labelsAttachCommand,
|
|
217
217
|
labelsDetachCommand
|
|
218
218
|
};
|
|
219
|
-
//# sourceMappingURL=chunk-
|
|
219
|
+
//# sourceMappingURL=chunk-HH7B2L3Z.js.map
|
|
@@ -129,6 +129,14 @@ function compactActivity(row) {
|
|
|
129
129
|
...change !== void 0 ? { change } : {}
|
|
130
130
|
};
|
|
131
131
|
}
|
|
132
|
+
function budgetUnitHints(rows) {
|
|
133
|
+
const listed = rows.map((row) => Number(row.daily_budget ?? row.lifetime_budget)).find((amount) => Number.isFinite(amount) && amount > 0);
|
|
134
|
+
if (listed === void 0) return [];
|
|
135
|
+
const whole = listed / 100;
|
|
136
|
+
return [
|
|
137
|
+
`Budgets here are in the account currency's smallest unit, as Meta sends them: daily_budget ${listed} is ${whole} in EUR or USD (currencies without cents, such as JPY, are not divided). Money flags take whole currency: --daily-budget ${whole}, never ${listed}.`
|
|
138
|
+
];
|
|
139
|
+
}
|
|
132
140
|
var PROJECTIONS = {
|
|
133
141
|
campaigns: { row: compactCampaign, columns: CAMPAIGN_COLUMNS, whenPresent: DIAGNOSTIC_COLUMNS },
|
|
134
142
|
adsets: { row: compactAdSet, columns: ADSET_COLUMNS, whenPresent: DIAGNOSTIC_COLUMNS },
|
|
@@ -183,9 +191,10 @@ function registerMetaListSchema(kind, description, args) {
|
|
|
183
191
|
}
|
|
184
192
|
|
|
185
193
|
export {
|
|
194
|
+
budgetUnitHints,
|
|
186
195
|
shapeMetaListRows,
|
|
187
196
|
writeMetaListRows,
|
|
188
197
|
META_LIST_SHAPE_ARGS,
|
|
189
198
|
registerMetaListSchema
|
|
190
199
|
};
|
|
191
|
-
//# sourceMappingURL=chunk-
|
|
200
|
+
//# sourceMappingURL=chunk-KUY26RCF.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/ads/meta/list-rows.ts"],"sourcesContent":["import { registerSchema } from \"../../../schemas.ts\";\nimport { asRecord, type CompactProjection, type ShapedRows, shapeListRows } from \"../list-rows.ts\";\nimport { writeAdsOutput } from \"../output.ts\";\n\n/**\n * The compact row of each Meta listing. The backend asks Graph for every field a\n * write or an audit might need (targeting, tracking specs, three status fields),\n * and 100 campaigns or two days of activity passed through whole ran to 55–78 KB.\n * A compact row carries what an agent decides with; `--fields` reaches any other\n * path and `--full` returns the record Graph sent.\n *\n * `effective_status` is the one status kept: it is what Ads Manager shows, and\n * `status`/`configured_status` only restate the toggle it already folds in.\n *\n * Listings print a table by default: keyed JSON repeats every column name on\n * every row, and 100 campaigns stayed near 30 KB even compact. `--output json`\n * returns the same rows in the envelope.\n */\n\ntype MetaRow = Record<string, unknown>;\n\nexport type MetaListKind = \"campaigns\" | \"adsets\" | \"ads\" | \"activities\";\n\nfunction pick(row: MetaRow, keys: readonly string[]): MetaRow {\n const picked: MetaRow = {};\n for (const key of keys) {\n if (row[key] !== undefined) picked[key] = row[key];\n }\n return picked;\n}\n\n/**\n * An account's campaign list is the widest listing an agent reads (100+ rows), so\n * its row is the narrowest: what a campaign is called, whether it runs and what\n * it spends. Objective, bid strategy and Special Ad Category are one `--fields`\n * away; the creation day is enough to order by, and `--fields created_time` has\n * the timestamp.\n */\nconst CAMPAIGN_COLUMNS = [\"id\", \"name\", \"effective_status\", \"daily_budget\", \"lifetime_budget\", \"created_date\"] as const;\n\n/** Why delivery stops and what Meta suggests: columns only when a row has one. */\nconst DIAGNOSTIC_COLUMNS = [\"issues\", \"suggestions\"] as const;\n\nfunction compactCampaign(row: MetaRow): MetaRow {\n const created = row.created_time;\n return {\n ...pick(row, [\"id\", \"name\", \"effective_status\", \"daily_budget\", \"lifetime_budget\"]),\n ...(typeof created === \"string\" ? { created_date: created.slice(0, 10) } : {}),\n ...diagnostics(row),\n };\n}\n\nconst ADSET_KEYS = [\n \"id\",\n \"name\",\n \"campaign_id\",\n \"effective_status\",\n \"optimization_goal\",\n \"billing_event\",\n \"bid_strategy\",\n \"daily_budget\",\n \"lifetime_budget\",\n \"destination_type\",\n // A Dynamic Creative ad set refuses every new ad, which changes the plan before anything is staged.\n \"is_dynamic_creative\",\n] as const;\n\nconst ADSET_COLUMNS = [...ADSET_KEYS, \"learning_stage\", \"end_time\", \"created_time\"] as const;\n\nfunction compactAdSet(row: MetaRow): MetaRow {\n const learning = asRecord(row.learning_stage_info)?.status;\n return {\n ...pick(row, ADSET_KEYS),\n ...(typeof learning === \"string\" ? { learning_stage: learning } : {}),\n ...pick(row, [\"end_time\", \"created_time\"]),\n ...diagnostics(row),\n };\n}\n\nconst AD_COLUMNS = [\n \"id\",\n \"name\",\n \"adset_id\",\n \"campaign_id\",\n \"effective_status\",\n \"creative_id\",\n \"issues\",\n \"created_time\",\n] as const;\n\n/** Why an ad is WITH_ISSUES — the one reason to open `issues_info`, in its own words. */\nfunction adIssues(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n return value.flatMap((entry) => {\n const issue = asRecord(entry);\n const text = issue?.error_summary ?? issue?.error_message;\n return typeof text === \"string\" && text ? [text] : [];\n });\n}\n\n/** Meta's suggestions for a campaign or ad set (`recommendations`), by their titles. */\nfunction suggestions(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n return value.flatMap((entry) => {\n const recommendation = asRecord(entry);\n const text = recommendation?.title ?? recommendation?.message;\n return typeof text === \"string\" && text ? [text] : [];\n });\n}\n\n/** Why a campaign or ad set cannot deliver, and what Meta suggests — only when Meta says something. */\nfunction diagnostics(row: MetaRow): MetaRow {\n const issues = adIssues(row.issues_info);\n const suggested = suggestions(row.recommendations);\n return {\n ...(issues.length > 0 ? { issues } : {}),\n ...(suggested.length > 0 ? { suggestions: suggested } : {}),\n };\n}\n\nfunction compactAd(row: MetaRow): MetaRow {\n const creativeId = asRecord(row.creative)?.id;\n const issues = adIssues(row.issues_info);\n return {\n ...pick(row, [\"id\", \"name\", \"adset_id\", \"campaign_id\", \"effective_status\"]),\n ...(creativeId !== undefined ? { creative_id: creativeId } : {}),\n ...(issues.length > 0 ? { issues } : {}),\n ...pick(row, [\"created_time\"]),\n };\n}\n\nconst ACTIVITY_COLUMNS = [\n \"event_time\",\n \"event_type\",\n \"actor_name\",\n \"object_type\",\n \"object_name\",\n \"object_id\",\n \"change\",\n] as const;\n\nfunction isScalar(value: unknown): value is string | number | null {\n return value === null || typeof value === \"string\" || typeof value === \"number\";\n}\n\n/**\n * `extra_data` is a JSON string whose shape varies by event type and carries most\n * of an activity's bytes (image URLs, whole targeting specs). A status, name,\n * budget or goal change stores its before and after as two plain values — those\n * read as one line; any richer change stays behind `--fields extra_data`.\n */\nexport function activityChange(extraData: unknown): string | undefined {\n if (typeof extraData !== \"string\") return undefined;\n let parsed: unknown;\n try {\n parsed = JSON.parse(extraData);\n } catch {\n return undefined;\n }\n const data = asRecord(parsed);\n // An absent old_value is one this read did not observe, not an unset one — only `null` means \"none\".\n if (!data || !(\"new_value\" in data) || !(\"old_value\" in data)) return undefined;\n const { old_value: before, new_value: after } = data;\n if (!isScalar(before) || !isScalar(after)) return undefined;\n const show = (value: string | number | null) => (value === null ? \"(none)\" : String(value));\n return `${show(before)} → ${show(after)}`;\n}\n\nfunction compactActivity(row: MetaRow): MetaRow {\n const change = activityChange(row.extra_data);\n return {\n ...pick(row, [\"event_time\", \"event_type\", \"actor_name\", \"object_type\", \"object_name\", \"object_id\"]),\n ...(change !== undefined ? { change } : {}),\n };\n}\n\nconst PROJECTIONS: Record<MetaListKind, CompactProjection<MetaRow>> = {\n campaigns: { row: compactCampaign, columns: CAMPAIGN_COLUMNS, whenPresent: DIAGNOSTIC_COLUMNS },\n adsets: { row: compactAdSet, columns: ADSET_COLUMNS, whenPresent: DIAGNOSTIC_COLUMNS },\n ads: { row: compactAd, columns: AD_COLUMNS },\n activities: { row: compactActivity, columns: ACTIVITY_COLUMNS },\n};\n\nexport function shapeMetaListRows(kind: MetaListKind, rows: MetaRow[], args: Record<string, unknown>): ShapedRows {\n return shapeListRows(rows, args, PROJECTIONS[kind]);\n}\n\nconst NOUNS: Record<MetaListKind, string> = {\n campaigns: \"campaigns\",\n adsets: \"ad sets\",\n ads: \"ads\",\n activities: \"activities\",\n};\n\n/**\n * A table of no rows prints nothing at all, which reads as a failed call — so an empty\n * listing says so, and says why when a status filter may be hiding rows.\n */\nexport function writeMetaListRows(kind: MetaListKind, shaped: ShapedRows, format: string, hints: string[] = []): void {\n if (format === \"md\" && shaped.rows.length === 0) {\n process.stdout.write(`${hints.length > 0 ? hints.join(\"\\n\") : `No ${NOUNS[kind]} matched.`}\\n`);\n return;\n }\n writeAdsOutput(shaped.rows, format, shaped.fields, [...hints, ...(shaped.hints ?? [])]);\n}\n\n/** The projection flags every Meta listing shares, worded once for help and `baker schema`. */\nexport const META_LIST_SHAPE_ARGS = {\n fields: {\n type: \"string\",\n description: \"CSV of dotted paths to return instead of the compact row, e.g. id,name,targeting.geo_locations\",\n },\n full: { type: \"boolean\", description: \"Return every field Meta sent (targeting, tracking specs, raw extra_data)\" },\n output: {\n type: \"string\",\n description: \"md|json|csv|jsonl — md (default) prints a table; json returns the rows in the { ok, data } envelope\",\n default: \"md\",\n },\n} as const;\n\ninterface ListArgDef {\n type: string;\n description?: string;\n default?: unknown;\n}\n\n/**\n * `baker schema ads.meta.<list>`, read off the same arg defs the command parses,\n * so the introspection an agent checks before a call cannot promise a flag the\n * command refuses — `--full` on `adsets` was guessed three times in one Session.\n */\nexport function registerMetaListSchema(\n kind: MetaListKind,\n description: string,\n args: Record<string, ListArgDef>,\n): void {\n registerSchema({\n command: `ads.meta.${kind}`,\n description,\n args: Object.fromEntries(\n Object.entries(args).map(([name, def]) => [\n name,\n {\n type: def.type,\n description: def.description ?? \"\",\n required: false,\n ...(def.default !== undefined ? { default: def.default } : {}),\n },\n ]),\n ),\n });\n}\n"],"mappings":";;;;;;;;;;;;AAuBA,SAAS,KAAK,KAAc,MAAkC;AAC5D,QAAM,SAAkB,CAAC;AACzB,aAAW,OAAO,MAAM;AACtB,QAAI,IAAI,GAAG,MAAM,OAAW,QAAO,GAAG,IAAI,IAAI,GAAG;AAAA,EACnD;AACA,SAAO;AACT;AASA,IAAM,mBAAmB,CAAC,MAAM,QAAQ,oBAAoB,gBAAgB,mBAAmB,cAAc;AAG7G,IAAM,qBAAqB,CAAC,UAAU,aAAa;AAEnD,SAAS,gBAAgB,KAAuB;AAC9C,QAAM,UAAU,IAAI;AACpB,SAAO;AAAA,IACL,GAAG,KAAK,KAAK,CAAC,MAAM,QAAQ,oBAAoB,gBAAgB,iBAAiB,CAAC;AAAA,IAClF,GAAI,OAAO,YAAY,WAAW,EAAE,cAAc,QAAQ,MAAM,GAAG,EAAE,EAAE,IAAI,CAAC;AAAA,IAC5E,GAAG,YAAY,GAAG;AAAA,EACpB;AACF;AAEA,IAAM,aAAa;AAAA,EACjB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AACF;AAEA,IAAM,gBAAgB,CAAC,GAAG,YAAY,kBAAkB,YAAY,cAAc;AAElF,SAAS,aAAa,KAAuB;AAC3C,QAAM,WAAW,SAAS,IAAI,mBAAmB,GAAG;AACpD,SAAO;AAAA,IACL,GAAG,KAAK,KAAK,UAAU;AAAA,IACvB,GAAI,OAAO,aAAa,WAAW,EAAE,gBAAgB,SAAS,IAAI,CAAC;AAAA,IACnE,GAAG,KAAK,KAAK,CAAC,YAAY,cAAc,CAAC;AAAA,IACzC,GAAG,YAAY,GAAG;AAAA,EACpB;AACF;AAEA,IAAM,aAAa;AAAA,EACjB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGA,SAAS,SAAS,OAA0B;AAC1C,MAAI,CAAC,MAAM,QAAQ,KAAK,EAAG,QAAO,CAAC;AACnC,SAAO,MAAM,QAAQ,CAAC,UAAU;AAC9B,UAAM,QAAQ,SAAS,KAAK;AAC5B,UAAM,OAAO,OAAO,iBAAiB,OAAO;AAC5C,WAAO,OAAO,SAAS,YAAY,OAAO,CAAC,IAAI,IAAI,CAAC;AAAA,EACtD,CAAC;AACH;AAGA,SAAS,YAAY,OAA0B;AAC7C,MAAI,CAAC,MAAM,QAAQ,KAAK,EAAG,QAAO,CAAC;AACnC,SAAO,MAAM,QAAQ,CAAC,UAAU;AAC9B,UAAM,iBAAiB,SAAS,KAAK;AACrC,UAAM,OAAO,gBAAgB,SAAS,gBAAgB;AACtD,WAAO,OAAO,SAAS,YAAY,OAAO,CAAC,IAAI,IAAI,CAAC;AAAA,EACtD,CAAC;AACH;AAGA,SAAS,YAAY,KAAuB;AAC1C,QAAM,SAAS,SAAS,IAAI,WAAW;AACvC,QAAM,YAAY,YAAY,IAAI,eAAe;AACjD,SAAO;AAAA,IACL,GAAI,OAAO,SAAS,IAAI,EAAE,OAAO,IAAI,CAAC;AAAA,IACtC,GAAI,UAAU,SAAS,IAAI,EAAE,aAAa,UAAU,IAAI,CAAC;AAAA,EAC3D;AACF;AAEA,SAAS,UAAU,KAAuB;AACxC,QAAM,aAAa,SAAS,IAAI,QAAQ,GAAG;AAC3C,QAAM,SAAS,SAAS,IAAI,WAAW;AACvC,SAAO;AAAA,IACL,GAAG,KAAK,KAAK,CAAC,MAAM,QAAQ,YAAY,eAAe,kBAAkB,CAAC;AAAA,IAC1E,GAAI,eAAe,SAAY,EAAE,aAAa,WAAW,IAAI,CAAC;AAAA,IAC9D,GAAI,OAAO,SAAS,IAAI,EAAE,OAAO,IAAI,CAAC;AAAA,IACtC,GAAG,KAAK,KAAK,CAAC,cAAc,CAAC;AAAA,EAC/B;AACF;AAEA,IAAM,mBAAmB;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,SAAS,SAAS,OAAiD;AACjE,SAAO,UAAU,QAAQ,OAAO,UAAU,YAAY,OAAO,UAAU;AACzE;AAQO,SAAS,eAAe,WAAwC;AACrE,MAAI,OAAO,cAAc,SAAU,QAAO;AAC1C,MAAI;AACJ,MAAI;AACF,aAAS,KAAK,MAAM,SAAS;AAAA,EAC/B,QAAQ;AACN,WAAO;AAAA,EACT;AACA,QAAM,OAAO,SAAS,MAAM;AAE5B,MAAI,CAAC,QAAQ,EAAE,eAAe,SAAS,EAAE,eAAe,MAAO,QAAO;AACtE,QAAM,EAAE,WAAW,QAAQ,WAAW,MAAM,IAAI;AAChD,MAAI,CAAC,SAAS,MAAM,KAAK,CAAC,SAAS,KAAK,EAAG,QAAO;AAClD,QAAM,OAAO,CAAC,UAAmC,UAAU,OAAO,WAAW,OAAO,KAAK;AACzF,SAAO,GAAG,KAAK,MAAM,CAAC,WAAM,KAAK,KAAK,CAAC;AACzC;AAEA,SAAS,gBAAgB,KAAuB;AAC9C,QAAM,SAAS,eAAe,IAAI,UAAU;AAC5C,SAAO;AAAA,IACL,GAAG,KAAK,KAAK,CAAC,cAAc,cAAc,cAAc,eAAe,eAAe,WAAW,CAAC;AAAA,IAClG,GAAI,WAAW,SAAY,EAAE,OAAO,IAAI,CAAC;AAAA,EAC3C;AACF;AAEA,IAAM,cAAgE;AAAA,EACpE,WAAW,EAAE,KAAK,iBAAiB,SAAS,kBAAkB,aAAa,mBAAmB;AAAA,EAC9F,QAAQ,EAAE,KAAK,cAAc,SAAS,eAAe,aAAa,mBAAmB;AAAA,EACrF,KAAK,EAAE,KAAK,WAAW,SAAS,WAAW;AAAA,EAC3C,YAAY,EAAE,KAAK,iBAAiB,SAAS,iBAAiB;AAChE;AAEO,SAAS,kBAAkB,MAAoB,MAAiB,MAA2C;AAChH,SAAO,cAAc,MAAM,MAAM,YAAY,IAAI,CAAC;AACpD;AAEA,IAAM,QAAsC;AAAA,EAC1C,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,YAAY;AACd;AAMO,SAAS,kBAAkB,MAAoB,QAAoB,QAAgB,QAAkB,CAAC,GAAS;AACpH,MAAI,WAAW,QAAQ,OAAO,KAAK,WAAW,GAAG;AAC/C,YAAQ,OAAO,MAAM,GAAG,MAAM,SAAS,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,MAAM,IAAI,CAAC,WAAW;AAAA,CAAI;AAC9F;AAAA,EACF;AACA,iBAAe,OAAO,MAAM,QAAQ,OAAO,QAAQ,CAAC,GAAG,OAAO,GAAI,OAAO,SAAS,CAAC,CAAE,CAAC;AACxF;AAGO,IAAM,uBAAuB;AAAA,EAClC,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,aAAa;AAAA,EACf;AAAA,EACA,MAAM,EAAE,MAAM,WAAW,aAAa,2EAA2E;AAAA,EACjH,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,aAAa;AAAA,IACb,SAAS;AAAA,EACX;AACF;AAaO,SAAS,uBACd,MACA,aACA,MACM;AACN,iBAAe;AAAA,IACb,SAAS,YAAY,IAAI;AAAA,IACzB;AAAA,IACA,MAAM,OAAO;AAAA,MACX,OAAO,QAAQ,IAAI,EAAE,IAAI,CAAC,CAAC,MAAM,GAAG,MAAM;AAAA,QACxC;AAAA,QACA;AAAA,UACE,MAAM,IAAI;AAAA,UACV,aAAa,IAAI,eAAe;AAAA,UAChC,UAAU;AAAA,UACV,GAAI,IAAI,YAAY,SAAY,EAAE,SAAS,IAAI,QAAQ,IAAI,CAAC;AAAA,QAC9D;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AACH;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/commands/ads/meta/list-rows.ts"],"sourcesContent":["import { registerSchema } from \"../../../schemas.ts\";\nimport { asRecord, type CompactProjection, type ShapedRows, shapeListRows } from \"../list-rows.ts\";\nimport { writeAdsOutput } from \"../output.ts\";\n\n/**\n * The compact row of each Meta listing. The backend asks Graph for every field a\n * write or an audit might need (targeting, tracking specs, three status fields),\n * and 100 campaigns or two days of activity passed through whole ran to 55–78 KB.\n * A compact row carries what an agent decides with; `--fields` reaches any other\n * path and `--full` returns the record Graph sent.\n *\n * `effective_status` is the one status kept: it is what Ads Manager shows, and\n * `status`/`configured_status` only restate the toggle it already folds in.\n *\n * Listings print a table by default: keyed JSON repeats every column name on\n * every row, and 100 campaigns stayed near 30 KB even compact. `--output json`\n * returns the same rows in the envelope.\n */\n\ntype MetaRow = Record<string, unknown>;\n\nexport type MetaListKind = \"campaigns\" | \"adsets\" | \"ads\" | \"activities\";\n\nfunction pick(row: MetaRow, keys: readonly string[]): MetaRow {\n const picked: MetaRow = {};\n for (const key of keys) {\n if (row[key] !== undefined) picked[key] = row[key];\n }\n return picked;\n}\n\n/**\n * An account's campaign list is the widest listing an agent reads (100+ rows), so\n * its row is the narrowest: what a campaign is called, whether it runs and what\n * it spends. Objective, bid strategy and Special Ad Category are one `--fields`\n * away; the creation day is enough to order by, and `--fields created_time` has\n * the timestamp.\n */\nconst CAMPAIGN_COLUMNS = [\"id\", \"name\", \"effective_status\", \"daily_budget\", \"lifetime_budget\", \"created_date\"] as const;\n\n/** Why delivery stops and what Meta suggests: columns only when a row has one. */\nconst DIAGNOSTIC_COLUMNS = [\"issues\", \"suggestions\"] as const;\n\nfunction compactCampaign(row: MetaRow): MetaRow {\n const created = row.created_time;\n return {\n ...pick(row, [\"id\", \"name\", \"effective_status\", \"daily_budget\", \"lifetime_budget\"]),\n ...(typeof created === \"string\" ? { created_date: created.slice(0, 10) } : {}),\n ...diagnostics(row),\n };\n}\n\nconst ADSET_KEYS = [\n \"id\",\n \"name\",\n \"campaign_id\",\n \"effective_status\",\n \"optimization_goal\",\n \"billing_event\",\n \"bid_strategy\",\n \"daily_budget\",\n \"lifetime_budget\",\n \"destination_type\",\n // A Dynamic Creative ad set refuses every new ad, which changes the plan before anything is staged.\n \"is_dynamic_creative\",\n] as const;\n\nconst ADSET_COLUMNS = [...ADSET_KEYS, \"learning_stage\", \"end_time\", \"created_time\"] as const;\n\nfunction compactAdSet(row: MetaRow): MetaRow {\n const learning = asRecord(row.learning_stage_info)?.status;\n return {\n ...pick(row, ADSET_KEYS),\n ...(typeof learning === \"string\" ? { learning_stage: learning } : {}),\n ...pick(row, [\"end_time\", \"created_time\"]),\n ...diagnostics(row),\n };\n}\n\nconst AD_COLUMNS = [\n \"id\",\n \"name\",\n \"adset_id\",\n \"campaign_id\",\n \"effective_status\",\n \"creative_id\",\n \"issues\",\n \"created_time\",\n] as const;\n\n/** Why an ad is WITH_ISSUES — the one reason to open `issues_info`, in its own words. */\nfunction adIssues(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n return value.flatMap((entry) => {\n const issue = asRecord(entry);\n const text = issue?.error_summary ?? issue?.error_message;\n return typeof text === \"string\" && text ? [text] : [];\n });\n}\n\n/** Meta's suggestions for a campaign or ad set (`recommendations`), by their titles. */\nfunction suggestions(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n return value.flatMap((entry) => {\n const recommendation = asRecord(entry);\n const text = recommendation?.title ?? recommendation?.message;\n return typeof text === \"string\" && text ? [text] : [];\n });\n}\n\n/** Why a campaign or ad set cannot deliver, and what Meta suggests — only when Meta says something. */\nfunction diagnostics(row: MetaRow): MetaRow {\n const issues = adIssues(row.issues_info);\n const suggested = suggestions(row.recommendations);\n return {\n ...(issues.length > 0 ? { issues } : {}),\n ...(suggested.length > 0 ? { suggestions: suggested } : {}),\n };\n}\n\nfunction compactAd(row: MetaRow): MetaRow {\n const creativeId = asRecord(row.creative)?.id;\n const issues = adIssues(row.issues_info);\n return {\n ...pick(row, [\"id\", \"name\", \"adset_id\", \"campaign_id\", \"effective_status\"]),\n ...(creativeId !== undefined ? { creative_id: creativeId } : {}),\n ...(issues.length > 0 ? { issues } : {}),\n ...pick(row, [\"created_time\"]),\n };\n}\n\nconst ACTIVITY_COLUMNS = [\n \"event_time\",\n \"event_type\",\n \"actor_name\",\n \"object_type\",\n \"object_name\",\n \"object_id\",\n \"change\",\n] as const;\n\nfunction isScalar(value: unknown): value is string | number | null {\n return value === null || typeof value === \"string\" || typeof value === \"number\";\n}\n\n/**\n * `extra_data` is a JSON string whose shape varies by event type and carries most\n * of an activity's bytes (image URLs, whole targeting specs). A status, name,\n * budget or goal change stores its before and after as two plain values — those\n * read as one line; any richer change stays behind `--fields extra_data`.\n */\nexport function activityChange(extraData: unknown): string | undefined {\n if (typeof extraData !== \"string\") return undefined;\n let parsed: unknown;\n try {\n parsed = JSON.parse(extraData);\n } catch {\n return undefined;\n }\n const data = asRecord(parsed);\n // An absent old_value is one this read did not observe, not an unset one — only `null` means \"none\".\n if (!data || !(\"new_value\" in data) || !(\"old_value\" in data)) return undefined;\n const { old_value: before, new_value: after } = data;\n if (!isScalar(before) || !isScalar(after)) return undefined;\n const show = (value: string | number | null) => (value === null ? \"(none)\" : String(value));\n return `${show(before)} → ${show(after)}`;\n}\n\nfunction compactActivity(row: MetaRow): MetaRow {\n const change = activityChange(row.extra_data);\n return {\n ...pick(row, [\"event_time\", \"event_type\", \"actor_name\", \"object_type\", \"object_name\", \"object_id\"]),\n ...(change !== undefined ? { change } : {}),\n };\n}\n\n/**\n * The unit a listing's budgets are in, said once rather than as a column (a\n * 100-campaign table stays small). Meta lists money in the account currency's\n * smallest unit and Baker passes it through unchanged (published reports read\n * it that way), while every money flag takes whole currency. An agent that once\n * took a listed \"8000\" for the flag's unit staged 10,000 EUR a day instead of 100.\n */\nexport function budgetUnitHints(rows: ReadonlyArray<Record<string, unknown>>): string[] {\n const listed = rows\n .map((row) => Number(row.daily_budget ?? row.lifetime_budget))\n .find((amount) => Number.isFinite(amount) && amount > 0);\n if (listed === undefined) return [];\n const whole = listed / 100;\n return [\n `Budgets here are in the account currency's smallest unit, as Meta sends them: daily_budget ${listed} is ${whole} in EUR or USD (currencies without cents, such as JPY, are not divided). Money flags take whole currency: --daily-budget ${whole}, never ${listed}.`,\n ];\n}\n\nconst PROJECTIONS: Record<MetaListKind, CompactProjection<MetaRow>> = {\n campaigns: { row: compactCampaign, columns: CAMPAIGN_COLUMNS, whenPresent: DIAGNOSTIC_COLUMNS },\n adsets: { row: compactAdSet, columns: ADSET_COLUMNS, whenPresent: DIAGNOSTIC_COLUMNS },\n ads: { row: compactAd, columns: AD_COLUMNS },\n activities: { row: compactActivity, columns: ACTIVITY_COLUMNS },\n};\n\nexport function shapeMetaListRows(kind: MetaListKind, rows: MetaRow[], args: Record<string, unknown>): ShapedRows {\n return shapeListRows(rows, args, PROJECTIONS[kind]);\n}\n\nconst NOUNS: Record<MetaListKind, string> = {\n campaigns: \"campaigns\",\n adsets: \"ad sets\",\n ads: \"ads\",\n activities: \"activities\",\n};\n\n/**\n * A table of no rows prints nothing at all, which reads as a failed call — so an empty\n * listing says so, and says why when a status filter may be hiding rows.\n */\nexport function writeMetaListRows(kind: MetaListKind, shaped: ShapedRows, format: string, hints: string[] = []): void {\n if (format === \"md\" && shaped.rows.length === 0) {\n process.stdout.write(`${hints.length > 0 ? hints.join(\"\\n\") : `No ${NOUNS[kind]} matched.`}\\n`);\n return;\n }\n writeAdsOutput(shaped.rows, format, shaped.fields, [...hints, ...(shaped.hints ?? [])]);\n}\n\n/** The projection flags every Meta listing shares, worded once for help and `baker schema`. */\nexport const META_LIST_SHAPE_ARGS = {\n fields: {\n type: \"string\",\n description: \"CSV of dotted paths to return instead of the compact row, e.g. id,name,targeting.geo_locations\",\n },\n full: { type: \"boolean\", description: \"Return every field Meta sent (targeting, tracking specs, raw extra_data)\" },\n output: {\n type: \"string\",\n description: \"md|json|csv|jsonl — md (default) prints a table; json returns the rows in the { ok, data } envelope\",\n default: \"md\",\n },\n} as const;\n\ninterface ListArgDef {\n type: string;\n description?: string;\n default?: unknown;\n}\n\n/**\n * `baker schema ads.meta.<list>`, read off the same arg defs the command parses,\n * so the introspection an agent checks before a call cannot promise a flag the\n * command refuses — `--full` on `adsets` was guessed three times in one Session.\n */\nexport function registerMetaListSchema(\n kind: MetaListKind,\n description: string,\n args: Record<string, ListArgDef>,\n): void {\n registerSchema({\n command: `ads.meta.${kind}`,\n description,\n args: Object.fromEntries(\n Object.entries(args).map(([name, def]) => [\n name,\n {\n type: def.type,\n description: def.description ?? \"\",\n required: false,\n ...(def.default !== undefined ? { default: def.default } : {}),\n },\n ]),\n ),\n });\n}\n"],"mappings":"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","names":[]}
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
UNHASHED_CUSTOMER_LIST_KEYS,
|
|
6
6
|
customAudienceMembersSchema,
|
|
7
7
|
customerListBatchSchema
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-SQCALAI7.js";
|
|
9
9
|
|
|
10
10
|
// src/commands/ads/meta/customer-list.ts
|
|
11
11
|
import { createHash } from "crypto";
|
|
@@ -388,4 +388,4 @@ export {
|
|
|
388
388
|
customerListBatches,
|
|
389
389
|
customerListUploadRefusal
|
|
390
390
|
};
|
|
391
|
-
//# sourceMappingURL=chunk-
|
|
391
|
+
//# sourceMappingURL=chunk-SHLA4JF7.js.map
|
|
@@ -4157,11 +4157,14 @@ function createOp(kind, payload) {
|
|
|
4157
4157
|
function updateOp(kind, payload) {
|
|
4158
4158
|
return z12.object({ kind: z12.literal(kind), accountId: accountIdSchema, target: updateTargetSchema, payload });
|
|
4159
4159
|
}
|
|
4160
|
+
function budgetUpdateOp(kind, payload) {
|
|
4161
|
+
return updateOp(kind, payload).extend({ confirmBudgetIncrease: z12.boolean().optional() });
|
|
4162
|
+
}
|
|
4160
4163
|
var metaDraftOpInputSchema = z12.discriminatedUnion("kind", [
|
|
4161
4164
|
createOp("campaign.create", campaignCreateSchema),
|
|
4162
|
-
|
|
4165
|
+
budgetUpdateOp("campaign.update", campaignUpdateSchema),
|
|
4163
4166
|
createOp("adSet.create", adSetCreateSchema),
|
|
4164
|
-
|
|
4167
|
+
budgetUpdateOp("adSet.update", adSetUpdateSchema),
|
|
4165
4168
|
createOp("adCreative.create", adCreativeCreateSchema),
|
|
4166
4169
|
updateOp("adCreative.update", adCreativeUpdateSchema),
|
|
4167
4170
|
createOp("ad.create", adCreateSchema),
|
|
@@ -4223,4 +4226,4 @@ export {
|
|
|
4223
4226
|
metaTargetingSchema,
|
|
4224
4227
|
metaDraftOpInputSchema
|
|
4225
4228
|
};
|
|
4226
|
-
//# sourceMappingURL=chunk-
|
|
4229
|
+
//# sourceMappingURL=chunk-SQCALAI7.js.map
|