@koda-sl/baker-cli 0.365.0 → 0.366.0-dev.1010f7728
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 -1
- package/dist/{chunk-FXVELNAS.js → chunk-A2LM5EDF.js} +3 -6
- package/dist/{chunk-FXVELNAS.js.map → chunk-A2LM5EDF.js.map} +1 -1
- package/dist/{chunk-AI4HWQVN.js → chunk-K2IKLMCM.js} +4 -4
- package/dist/chunk-K2IKLMCM.js.map +1 -0
- package/dist/{chunk-L4QXAYIC.js → chunk-WXSUOPOU.js} +51 -15
- package/dist/chunk-WXSUOPOU.js.map +1 -0
- package/dist/cli.js +48 -38
- package/dist/cli.js.map +1 -1
- package/dist/engine/index.js +1 -1
- package/dist/{output-AT5SRVH7.js → output-M2DBCZFG.js} +2 -2
- package/dist/{shared-HZ44PY2F.js → shared-3VVQPSFH.js} +9 -5
- package/package.json +1 -1
- package/dist/chunk-AI4HWQVN.js.map +0 -1
- package/dist/chunk-L4QXAYIC.js.map +0 -1
- /package/dist/{output-AT5SRVH7.js.map → output-M2DBCZFG.js.map} +0 -0
- /package/dist/{shared-HZ44PY2F.js.map → shared-3VVQPSFH.js.map} +0 -0
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
handleConnectionError,
|
|
3
3
|
needsConnectionFix,
|
|
4
4
|
writeAdsJson
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-A2LM5EDF.js";
|
|
6
6
|
import {
|
|
7
7
|
ApiError
|
|
8
8
|
} from "./chunk-MZQC4LII.js";
|
|
@@ -10,6 +10,37 @@ import {
|
|
|
10
10
|
getEnv
|
|
11
11
|
} from "./chunk-2OKSJNLA.js";
|
|
12
12
|
|
|
13
|
+
// src/commands/ads/project-fields.ts
|
|
14
|
+
function asRecord(value) {
|
|
15
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
|
|
16
|
+
}
|
|
17
|
+
function readPath(row, path) {
|
|
18
|
+
let current = row;
|
|
19
|
+
for (const segment of path.split(".")) {
|
|
20
|
+
const record = asRecord(current);
|
|
21
|
+
if (!record) return void 0;
|
|
22
|
+
current = record[segment];
|
|
23
|
+
}
|
|
24
|
+
return current;
|
|
25
|
+
}
|
|
26
|
+
function projectFields(rows, paths) {
|
|
27
|
+
return rows.map((row) => {
|
|
28
|
+
const projected = {};
|
|
29
|
+
for (const path of paths) {
|
|
30
|
+
const value = readPath(row, path);
|
|
31
|
+
if (value !== void 0) {
|
|
32
|
+
projected[path] = value;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return projected;
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
function parseFieldsArg(value) {
|
|
39
|
+
if (typeof value !== "string") return void 0;
|
|
40
|
+
const paths = value.split(",").map((field) => field.trim()).filter((field) => field.length > 0);
|
|
41
|
+
return paths.length > 0 ? paths : void 0;
|
|
42
|
+
}
|
|
43
|
+
|
|
13
44
|
// src/commands/ads/meta/shared.ts
|
|
14
45
|
var DAY_MS = 864e5;
|
|
15
46
|
function metaForbiddenFix(message) {
|
|
@@ -87,6 +118,18 @@ function daysAgoIso(days) {
|
|
|
87
118
|
function csvOrJson(args) {
|
|
88
119
|
return args.output ?? "json";
|
|
89
120
|
}
|
|
121
|
+
var NAME_CONTAINS_ARG = {
|
|
122
|
+
type: "string",
|
|
123
|
+
description: "Only rows whose name contains this text, matched by Meta before anything is returned. Start here to find one entity by name: --name-contains octubre --all-statuses"
|
|
124
|
+
};
|
|
125
|
+
var FIELDS_ARG = {
|
|
126
|
+
type: "string",
|
|
127
|
+
description: "Comma-separated fields to print instead of the whole row; nested ones by dotted path. Pair with --name-contains: --fields id,name,adset_id,creative.id"
|
|
128
|
+
};
|
|
129
|
+
function projectListRows(rows, args) {
|
|
130
|
+
const paths = parseFieldsArg(args.fields);
|
|
131
|
+
return paths ? { rows: projectFields(rows, paths), fields: paths } : { rows };
|
|
132
|
+
}
|
|
90
133
|
function resolveEffectiveStatus(args) {
|
|
91
134
|
if (args["all-statuses"]) {
|
|
92
135
|
return void 0;
|
|
@@ -97,19 +140,10 @@ function resolveEffectiveStatus(args) {
|
|
|
97
140
|
}
|
|
98
141
|
return "ACTIVE";
|
|
99
142
|
}
|
|
100
|
-
function statusFilterHints(rows, effectiveStatus, noun) {
|
|
101
|
-
if (rows.length > 0 || effectiveStatus === void 0) return [];
|
|
102
|
-
if (effectiveStatus === "ACTIVE") {
|
|
103
|
-
return [
|
|
104
|
-
`No ACTIVE ${noun}. The ACTIVE filter hides paused, archived and in-review ones (under a paused campaign or ad set that is all of them), so this does NOT mean none exist. Re-run with --all-statuses before concluding there are none.`
|
|
105
|
-
];
|
|
106
|
-
}
|
|
107
|
-
return [
|
|
108
|
-
`No ${noun} with effective_status ${effectiveStatus}. Re-run with --all-statuses to see every status before concluding there are none.`
|
|
109
|
-
];
|
|
110
|
-
}
|
|
111
143
|
|
|
112
144
|
export {
|
|
145
|
+
projectFields,
|
|
146
|
+
parseFieldsArg,
|
|
113
147
|
metaForbiddenFix,
|
|
114
148
|
handleMetaError,
|
|
115
149
|
resolveAccountIdArg,
|
|
@@ -117,7 +151,9 @@ export {
|
|
|
117
151
|
todayIso,
|
|
118
152
|
daysAgoIso,
|
|
119
153
|
csvOrJson,
|
|
120
|
-
|
|
121
|
-
|
|
154
|
+
NAME_CONTAINS_ARG,
|
|
155
|
+
FIELDS_ARG,
|
|
156
|
+
projectListRows,
|
|
157
|
+
resolveEffectiveStatus
|
|
122
158
|
};
|
|
123
|
-
//# sourceMappingURL=chunk-
|
|
159
|
+
//# sourceMappingURL=chunk-WXSUOPOU.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/ads/project-fields.ts","../src/commands/ads/meta/shared.ts"],"sourcesContent":["function asRecord(value: unknown): Record<string, unknown> | undefined {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : undefined;\n}\n\n/** Reads one dotted path (`content.textAd.landingPage`) out of a record. */\nexport function readPath(row: Record<string, unknown>, path: string): unknown {\n let current: unknown = row;\n for (const segment of path.split(\".\")) {\n const record = asRecord(current);\n if (!record) return undefined;\n current = record[segment];\n }\n return current;\n}\n\nexport function projectFields(rows: Array<Record<string, unknown>>, paths: string[]): Array<Record<string, unknown>> {\n return rows.map((row) => {\n const projected: Record<string, unknown> = {};\n for (const path of paths) {\n const value = readPath(row, path);\n if (value !== undefined) {\n projected[path] = value;\n }\n }\n return projected;\n });\n}\n\n/** `--fields id, name,creative.id` → the dotted paths it names, or none when it names nothing. */\nexport function parseFieldsArg(value: unknown): string[] | undefined {\n if (typeof value !== \"string\") return undefined;\n const paths = value\n .split(\",\")\n .map((field) => field.trim())\n .filter((field) => field.length > 0);\n return paths.length > 0 ? paths : undefined;\n}\n","import { ApiError } from \"../../../client.ts\";\nimport { getEnv } from \"../../../env.ts\";\nimport { handleConnectionError, needsConnectionFix } from \"../../../error-handler.ts\";\nimport { writeAdsJson } from \"../output.ts\";\nimport { parseFieldsArg, projectFields } from \"../project-fields.ts\";\nimport type { AdsErrorEnvelope, QueryFix } from \"../types.ts\";\n\nconst DAY_MS = 86_400_000;\n\n/**\n * Meta answers a permission refusal (Graph codes 200/10/294) with a bare\n * \"Permissions error\" that covers two causes needing opposite remedies: a\n * consent grant the connection never got — nothing validates Meta's granted\n * scopes after connect, unlike HubSpot's `requireCapability` — or a role the\n * user lacks on one asset, since a Pixel/Dataset, Page or catalog lives in a\n * Business and is assigned separately from the ad account. Only the blast radius\n * separates them, so hand the agent that test rather than a verdict: guessing\n * \"reconnect\" wastes the user's time on an unassigned asset, and ruling it out\n * strands a connection that really is short a scope.\n */\nexport function metaForbiddenFix(message: string): QueryFix {\n return {\n action: \"reject\",\n explanation: [\n message,\n \"This is a permission refusal, not a dead connection, and Meta returns the same code for two causes with opposite remedies. Tell them apart by how much else works before you answer.\",\n \"If other reads on this account are ALSO refused (campaigns, ad sets, insights), the connection is short a permission it was never granted. Only the user can widen it, by reconnecting Meta from the dashboard.\",\n \"If those reads work and only this object is refused, the asset (pixel/dataset, Page, or catalog) belongs to a Business the connected user holds no role in. Ad-account access does not carry asset access and reconnecting cannot grant it — the client assigns that asset to the connected user or partner in Meta Business settings, under the asset's own section (Data sources → Datasets for a pixel).\",\n \"Either way do not retry the same call, and do not abort the wider job. Continue with what you can read, and state in your answer that this specific check could not run and why — never present the task as verified when this step was skipped.\",\n ].join(\"\\n\\n\"),\n };\n}\n\nexport function handleMetaError(err: unknown): never {\n if (err instanceof ApiError) {\n if (needsConnectionFix(err.code, err.message)) {\n handleConnectionError(\"meta_ads\", err.message);\n }\n const envelope: AdsErrorEnvelope = {\n ok: false,\n error: {\n code: err.code,\n message: err.message,\n fix: err.code === \"FORBIDDEN\" ? metaForbiddenFix(err.message) : { action: \"reject\", explanation: err.message },\n retryable: err.code === \"RATE_LIMITED\" || err.code === \"UNAVAILABLE\" || err.code === \"INTERNAL_ERROR\",\n },\n };\n writeAdsJson(envelope);\n process.exit(1);\n }\n const message = err instanceof Error ? err.message : \"Unexpected error\";\n writeAdsJson({ ok: false, error: { code: \"NETWORK_ERROR\", message } });\n process.exit(1);\n}\n\nconst ACCOUNT_ID_RE = /^(act_)?[0-9]+$/;\n\n/** Pull the default Meta ad account ID from `--account-id` arg or `BAKER_META_AD_ACCOUNT_ID` env. */\nexport function resolveAccountIdArg(args: Record<string, unknown>): string {\n const fromArgs = args[\"account-id\"] as string | undefined;\n const id = fromArgs || getEnv().BAKER_META_AD_ACCOUNT_ID;\n if (!id) {\n writeAdsJson({\n ok: false,\n error: {\n code: \"MISSING_ACCOUNT_ID\",\n message: \"Pass --account-id or set BAKER_META_AD_ACCOUNT_ID. Run `baker ads meta accounts` to find IDs.\",\n },\n });\n process.exit(1);\n }\n if (!ACCOUNT_ID_RE.test(id)) {\n writeAdsJson({\n ok: false,\n error: {\n code: \"INVALID_ACCOUNT_ID\",\n message: `Invalid account ID \"${id}\". Expected numeric ID, optionally prefixed with \"act_\".`,\n },\n });\n process.exit(1);\n }\n return id.startsWith(\"act_\") ? id : `act_${id}`;\n}\n\nexport function getDateRange(args: Record<string, unknown>): { datePreset?: string; since?: string; until?: string } {\n const datePreset = args[\"date-preset\"] as string | undefined;\n const since = args.since as string | undefined;\n const until = args.until as string | undefined;\n if (since && until) return { since, until };\n return { datePreset: datePreset ?? \"last_7d\" };\n}\n\nexport function todayIso(): string {\n return new Date().toISOString().slice(0, 10);\n}\n\nexport function daysAgoIso(days: number): string {\n return new Date(Date.now() - days * DAY_MS).toISOString().slice(0, 10);\n}\n\nexport function csvOrJson(args: Record<string, unknown>): string {\n return (args.output as string | undefined) ?? \"json\";\n}\n\n/**\n * Matched by Meta itself, so finding one entity by name reads only the rows that\n * match instead of the whole account.\n */\nexport const NAME_CONTAINS_ARG = {\n type: \"string\",\n description:\n \"Only rows whose name contains this text, matched by Meta before anything is returned. Start here to find one entity by name: --name-contains octubre --all-statuses\",\n} as const;\n\nexport const FIELDS_ARG = {\n type: \"string\",\n description:\n \"Comma-separated fields to print instead of the whole row; nested ones by dotted path. Pair with --name-contains: --fields id,name,adset_id,creative.id\",\n} as const;\n\n/**\n * The rows a campaigns/adsets/ads listing prints, plus the columns csv/md must\n * use. `--fields` keeps only the named paths, so a lookup prints a few hundred\n * bytes instead of every row's tracking and issue blocks.\n */\nexport function projectListRows(\n rows: Array<Record<string, unknown>>,\n args: Record<string, unknown>,\n): { rows: Array<Record<string, unknown>>; fields?: string[] } {\n const paths = parseFieldsArg(args.fields);\n return paths ? { rows: projectFields(rows, paths), fields: paths } : { rows };\n}\n\n/**\n * Default to ACTIVE-only on listings — that's almost always what an AI agent or\n * a human glance wants. Pass `--effective-status ACTIVE,PAUSED` to override, or\n * `--all-statuses` to drop the filter entirely.\n */\nexport function resolveEffectiveStatus(args: Record<string, unknown>): string | undefined {\n if (args[\"all-statuses\"]) {\n return undefined;\n }\n const explicit = args[\"effective-status\"] as string | undefined;\n if (explicit) {\n return explicit;\n }\n return \"ACTIVE\";\n}\n"],"mappings":";;;;;;;;;;;;;AAAA,SAAS,SAAS,OAAqD;AACrE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK,IACrE,QACD;AACN;AAGO,SAAS,SAAS,KAA8B,MAAuB;AAC5E,MAAI,UAAmB;AACvB,aAAW,WAAW,KAAK,MAAM,GAAG,GAAG;AACrC,UAAM,SAAS,SAAS,OAAO;AAC/B,QAAI,CAAC,OAAQ,QAAO;AACpB,cAAU,OAAO,OAAO;AAAA,EAC1B;AACA,SAAO;AACT;AAEO,SAAS,cAAc,MAAsC,OAAiD;AACnH,SAAO,KAAK,IAAI,CAAC,QAAQ;AACvB,UAAM,YAAqC,CAAC;AAC5C,eAAW,QAAQ,OAAO;AACxB,YAAM,QAAQ,SAAS,KAAK,IAAI;AAChC,UAAI,UAAU,QAAW;AACvB,kBAAU,IAAI,IAAI;AAAA,MACpB;AAAA,IACF;AACA,WAAO;AAAA,EACT,CAAC;AACH;AAGO,SAAS,eAAe,OAAsC;AACnE,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,QAAM,QAAQ,MACX,MAAM,GAAG,EACT,IAAI,CAAC,UAAU,MAAM,KAAK,CAAC,EAC3B,OAAO,CAAC,UAAU,MAAM,SAAS,CAAC;AACrC,SAAO,MAAM,SAAS,IAAI,QAAQ;AACpC;;;AC/BA,IAAM,SAAS;AAaR,SAAS,iBAAiB,SAA2B;AAC1D,SAAO;AAAA,IACL,QAAQ;AAAA,IACR,aAAa;AAAA,MACX;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,MAAM;AAAA,EACf;AACF;AAEO,SAAS,gBAAgB,KAAqB;AACnD,MAAI,eAAe,UAAU;AAC3B,QAAI,mBAAmB,IAAI,MAAM,IAAI,OAAO,GAAG;AAC7C,4BAAsB,YAAY,IAAI,OAAO;AAAA,IAC/C;AACA,UAAM,WAA6B;AAAA,MACjC,IAAI;AAAA,MACJ,OAAO;AAAA,QACL,MAAM,IAAI;AAAA,QACV,SAAS,IAAI;AAAA,QACb,KAAK,IAAI,SAAS,cAAc,iBAAiB,IAAI,OAAO,IAAI,EAAE,QAAQ,UAAU,aAAa,IAAI,QAAQ;AAAA,QAC7G,WAAW,IAAI,SAAS,kBAAkB,IAAI,SAAS,iBAAiB,IAAI,SAAS;AAAA,MACvF;AAAA,IACF;AACA,iBAAa,QAAQ;AACrB,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,QAAM,UAAU,eAAe,QAAQ,IAAI,UAAU;AACrD,eAAa,EAAE,IAAI,OAAO,OAAO,EAAE,MAAM,iBAAiB,QAAQ,EAAE,CAAC;AACrE,UAAQ,KAAK,CAAC;AAChB;AAEA,IAAM,gBAAgB;AAGf,SAAS,oBAAoB,MAAuC;AACzE,QAAM,WAAW,KAAK,YAAY;AAClC,QAAM,KAAK,YAAY,OAAO,EAAE;AAChC,MAAI,CAAC,IAAI;AACP,iBAAa;AAAA,MACX,IAAI;AAAA,MACJ,OAAO;AAAA,QACL,MAAM;AAAA,QACN,SAAS;AAAA,MACX;AAAA,IACF,CAAC;AACD,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,MAAI,CAAC,cAAc,KAAK,EAAE,GAAG;AAC3B,iBAAa;AAAA,MACX,IAAI;AAAA,MACJ,OAAO;AAAA,QACL,MAAM;AAAA,QACN,SAAS,uBAAuB,EAAE;AAAA,MACpC;AAAA,IACF,CAAC;AACD,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,SAAO,GAAG,WAAW,MAAM,IAAI,KAAK,OAAO,EAAE;AAC/C;AAEO,SAAS,aAAa,MAAwF;AACnH,QAAM,aAAa,KAAK,aAAa;AACrC,QAAM,QAAQ,KAAK;AACnB,QAAM,QAAQ,KAAK;AACnB,MAAI,SAAS,MAAO,QAAO,EAAE,OAAO,MAAM;AAC1C,SAAO,EAAE,YAAY,cAAc,UAAU;AAC/C;AAEO,SAAS,WAAmB;AACjC,UAAO,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE;AAC7C;AAEO,SAAS,WAAW,MAAsB;AAC/C,SAAO,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,EAAE;AACvE;AAEO,SAAS,UAAU,MAAuC;AAC/D,SAAQ,KAAK,UAAiC;AAChD;AAMO,IAAM,oBAAoB;AAAA,EAC/B,MAAM;AAAA,EACN,aACE;AACJ;AAEO,IAAM,aAAa;AAAA,EACxB,MAAM;AAAA,EACN,aACE;AACJ;AAOO,SAAS,gBACd,MACA,MAC6D;AAC7D,QAAM,QAAQ,eAAe,KAAK,MAAM;AACxC,SAAO,QAAQ,EAAE,MAAM,cAAc,MAAM,KAAK,GAAG,QAAQ,MAAM,IAAI,EAAE,KAAK;AAC9E;AAOO,SAAS,uBAAuB,MAAmD;AACxF,MAAI,KAAK,cAAc,GAAG;AACxB,WAAO;AAAA,EACT;AACA,QAAM,WAAW,KAAK,kBAAkB;AACxC,MAAI,UAAU;AACZ,WAAO;AAAA,EACT;AACA,SAAO;AACT;","names":[]}
|
package/dist/cli.js
CHANGED
|
@@ -69,17 +69,21 @@ import {
|
|
|
69
69
|
validateCanvasDeep,
|
|
70
70
|
withoutCastName,
|
|
71
71
|
ytDlpBlockSignal
|
|
72
|
-
} from "./chunk-
|
|
72
|
+
} from "./chunk-K2IKLMCM.js";
|
|
73
73
|
import {
|
|
74
|
+
FIELDS_ARG,
|
|
75
|
+
NAME_CONTAINS_ARG,
|
|
74
76
|
csvOrJson,
|
|
75
77
|
daysAgoIso,
|
|
76
78
|
getDateRange,
|
|
77
79
|
handleMetaError,
|
|
80
|
+
parseFieldsArg,
|
|
81
|
+
projectFields,
|
|
82
|
+
projectListRows,
|
|
78
83
|
resolveAccountIdArg,
|
|
79
84
|
resolveEffectiveStatus,
|
|
80
|
-
statusFilterHints,
|
|
81
85
|
todayIso
|
|
82
|
-
} from "./chunk-
|
|
86
|
+
} from "./chunk-WXSUOPOU.js";
|
|
83
87
|
import {
|
|
84
88
|
buildQueryCacheKey,
|
|
85
89
|
cacheGet,
|
|
@@ -95,7 +99,7 @@ import {
|
|
|
95
99
|
writeAdsJson,
|
|
96
100
|
writeAdsOutput,
|
|
97
101
|
writeJsonEnvelope
|
|
98
|
-
} from "./chunk-
|
|
102
|
+
} from "./chunk-A2LM5EDF.js";
|
|
99
103
|
import {
|
|
100
104
|
ApiError,
|
|
101
105
|
apiGet,
|
|
@@ -22999,27 +23003,6 @@ function compactRow(row) {
|
|
|
22999
23003
|
...destination.postUrn ? { postUrn: destination.postUrn } : {}
|
|
23000
23004
|
};
|
|
23001
23005
|
}
|
|
23002
|
-
function readPath2(row, path48) {
|
|
23003
|
-
let current = row;
|
|
23004
|
-
for (const segment of path48.split(".")) {
|
|
23005
|
-
const record = asRecord(current);
|
|
23006
|
-
if (!record) return void 0;
|
|
23007
|
-
current = record[segment];
|
|
23008
|
-
}
|
|
23009
|
-
return current;
|
|
23010
|
-
}
|
|
23011
|
-
function projectFields(rows, paths) {
|
|
23012
|
-
return rows.map((row) => {
|
|
23013
|
-
const projected = {};
|
|
23014
|
-
for (const path48 of paths) {
|
|
23015
|
-
const value = readPath2(row, path48);
|
|
23016
|
-
if (value !== void 0) {
|
|
23017
|
-
projected[path48] = value;
|
|
23018
|
-
}
|
|
23019
|
-
}
|
|
23020
|
-
return projected;
|
|
23021
|
-
});
|
|
23022
|
-
}
|
|
23023
23006
|
function unmappedShapeWarnings(rows, rawContentReturned) {
|
|
23024
23007
|
const unmapped = rows.filter((row) => row.content && creativeDestination(row.content).format === "unknown");
|
|
23025
23008
|
if (unmapped.length === 0) return [];
|
|
@@ -23033,12 +23016,9 @@ function unmappedShapeWarnings(rows, rawContentReturned) {
|
|
|
23033
23016
|
}
|
|
23034
23017
|
function shapeRows(rows, args5) {
|
|
23035
23018
|
const raw = rows;
|
|
23036
|
-
const
|
|
23037
|
-
if (
|
|
23038
|
-
|
|
23039
|
-
if (paths.length > 0) {
|
|
23040
|
-
return { rows: projectFields(raw, paths), fields: paths };
|
|
23041
|
-
}
|
|
23019
|
+
const paths = parseFieldsArg(args5.fields);
|
|
23020
|
+
if (paths) {
|
|
23021
|
+
return { rows: projectFields(raw, paths), fields: paths };
|
|
23042
23022
|
}
|
|
23043
23023
|
if (args5.full) return { rows: raw };
|
|
23044
23024
|
return { rows: rows.map(compactRow), fields: [...COMPACT_COLUMNS] };
|
|
@@ -26382,8 +26362,8 @@ Example: baker ads meta ads retag 120252158038400247 --url-tags "utm_source={{si
|
|
|
26382
26362
|
run: async ({ args: args5 }) => {
|
|
26383
26363
|
const { apiPost: apiPost2 } = await import("./client-3DGBQ2H3.js");
|
|
26384
26364
|
const { requireChatId: requireChatId2 } = await import("./env-BSG7TY5Y.js");
|
|
26385
|
-
const { writeJsonEnvelope: writeJsonEnvelope2 } = await import("./output-
|
|
26386
|
-
const { handleMetaError: handleMetaError2 } = await import("./shared-
|
|
26365
|
+
const { writeJsonEnvelope: writeJsonEnvelope2 } = await import("./output-M2DBCZFG.js");
|
|
26366
|
+
const { handleMetaError: handleMetaError2 } = await import("./shared-3VVQPSFH.js");
|
|
26387
26367
|
try {
|
|
26388
26368
|
const accountId = bareAccountId2(args5);
|
|
26389
26369
|
const urlTags = typeof args5["url-tags"] === "string" ? args5["url-tags"] : void 0;
|
|
@@ -26530,8 +26510,8 @@ function duplicateCommand2(entity, label) {
|
|
|
26530
26510
|
run: async ({ args: args5 }) => {
|
|
26531
26511
|
const { apiPost: apiPost2 } = await import("./client-3DGBQ2H3.js");
|
|
26532
26512
|
const { requireChatId: requireChatId2 } = await import("./env-BSG7TY5Y.js");
|
|
26533
|
-
const { writeJsonEnvelope: writeJsonEnvelope2 } = await import("./output-
|
|
26534
|
-
const { handleMetaError: handleMetaError2 } = await import("./shared-
|
|
26513
|
+
const { writeJsonEnvelope: writeJsonEnvelope2 } = await import("./output-M2DBCZFG.js");
|
|
26514
|
+
const { handleMetaError: handleMetaError2 } = await import("./shared-3VVQPSFH.js");
|
|
26535
26515
|
try {
|
|
26536
26516
|
const accountId = bareAccountId2(args5);
|
|
26537
26517
|
const chatId = requireChatId2();
|
|
@@ -26570,6 +26550,8 @@ var listArgs4 = {
|
|
|
26570
26550
|
"campaign-id": { type: "string", description: "Filter to one campaign" },
|
|
26571
26551
|
"effective-status": { type: "string", description: "Comma-separated effective_status filter (overrides default)" },
|
|
26572
26552
|
"all-statuses": { type: "boolean", description: "Drop the default ACTIVE filter" },
|
|
26553
|
+
"name-contains": NAME_CONTAINS_ARG,
|
|
26554
|
+
fields: FIELDS_ARG,
|
|
26573
26555
|
limit: { type: "string", description: "Max rows (default 1000)" },
|
|
26574
26556
|
"no-cache": NO_CACHE_ARG,
|
|
26575
26557
|
output: { type: "string", description: "Output format", default: "json" }
|
|
@@ -26588,10 +26570,17 @@ var listCommand4 = defineCommand58({
|
|
|
26588
26570
|
if (args5["adset-id"]) params["adset-id"] = args5["adset-id"];
|
|
26589
26571
|
if (args5["campaign-id"]) params["campaign-id"] = args5["campaign-id"];
|
|
26590
26572
|
if (effectiveStatus) params["effective-status"] = effectiveStatus;
|
|
26573
|
+
if (args5["name-contains"]) params["name-contains"] = args5["name-contains"];
|
|
26591
26574
|
if (args5.limit) params.limit = args5.limit;
|
|
26592
26575
|
if (args5["no-cache"]) params["skip-cache"] = "true";
|
|
26593
26576
|
const data = await apiGet("/api/ads/meta/ads", params);
|
|
26594
|
-
|
|
26577
|
+
const { rows, fields } = projectListRows(data, args5);
|
|
26578
|
+
const fmt = csvOrJson(args5);
|
|
26579
|
+
if (fmt !== "json") {
|
|
26580
|
+
writeAdsOutput(rows, fmt, fields);
|
|
26581
|
+
return;
|
|
26582
|
+
}
|
|
26583
|
+
writeAdsJson({ ok: true, data: rows });
|
|
26595
26584
|
} catch (err) {
|
|
26596
26585
|
handleMetaError(err);
|
|
26597
26586
|
}
|
|
@@ -26608,6 +26597,7 @@ The dashboard shows effective_status (e.g. WITH_ISSUES, PENDING_REVIEW, DISAPPRO
|
|
|
26608
26597
|
Examples:
|
|
26609
26598
|
baker ads meta ads --account-id act_123
|
|
26610
26599
|
baker ads meta ads --adset-id 6123
|
|
26600
|
+
baker ads meta ads --account-id act_123 --all-statuses --name-contains octubre --fields id,name,adset_id,creative.id \u2014 find one ad by name
|
|
26611
26601
|
baker ads meta ads create --name "Ad 1" --adset meta_temp_as01 --creative meta_temp_cr01
|
|
26612
26602
|
baker ads meta ads pause 6123 --account-id act_123
|
|
26613
26603
|
baker ads meta ads retag 6123 --set "utm_medium=paid-social" \u2014 fix tracking on a LIVE ad, keeping everything else`
|
|
@@ -26637,6 +26627,8 @@ var listArgs5 = {
|
|
|
26637
26627
|
"campaign-id": { type: "string", description: "Filter to one campaign" },
|
|
26638
26628
|
"effective-status": { type: "string", description: "Comma-separated effective_status filter (overrides default)" },
|
|
26639
26629
|
"all-statuses": { type: "boolean", description: "Drop the default ACTIVE filter" },
|
|
26630
|
+
"name-contains": NAME_CONTAINS_ARG,
|
|
26631
|
+
fields: FIELDS_ARG,
|
|
26640
26632
|
limit: { type: "string", description: "Max rows (default 1000)" },
|
|
26641
26633
|
"no-cache": NO_CACHE_ARG,
|
|
26642
26634
|
output: { type: "string", description: "Output format", default: "json" }
|
|
@@ -26654,10 +26646,17 @@ var listCommand5 = defineCommand59({
|
|
|
26654
26646
|
const params = { "account-id": accountId };
|
|
26655
26647
|
if (args5["campaign-id"]) params["campaign-id"] = args5["campaign-id"];
|
|
26656
26648
|
if (effectiveStatus) params["effective-status"] = effectiveStatus;
|
|
26649
|
+
if (args5["name-contains"]) params["name-contains"] = args5["name-contains"];
|
|
26657
26650
|
if (args5.limit) params.limit = args5.limit;
|
|
26658
26651
|
if (args5["no-cache"]) params["skip-cache"] = "true";
|
|
26659
26652
|
const data = await apiGet("/api/ads/meta/adsets", params);
|
|
26660
|
-
|
|
26653
|
+
const { rows, fields } = projectListRows(data, args5);
|
|
26654
|
+
const fmt = csvOrJson(args5);
|
|
26655
|
+
if (fmt !== "json") {
|
|
26656
|
+
writeAdsOutput(rows, fmt, fields);
|
|
26657
|
+
return;
|
|
26658
|
+
}
|
|
26659
|
+
writeAdsJson({ ok: true, data: rows });
|
|
26661
26660
|
} catch (err) {
|
|
26662
26661
|
handleMetaError(err);
|
|
26663
26662
|
}
|
|
@@ -26672,6 +26671,7 @@ Defaults to ACTIVE only. Write subcommands stage ops on this chat's draft.
|
|
|
26672
26671
|
Examples:
|
|
26673
26672
|
baker ads meta adsets --account-id act_123
|
|
26674
26673
|
baker ads meta adsets --campaign-id 6123456789
|
|
26674
|
+
baker ads meta adsets --account-id act_123 --all-statuses --name-contains retargeting --fields id,name,campaign_id \u2014 find one ad set by name
|
|
26675
26675
|
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`
|
|
26676
26676
|
},
|
|
26677
26677
|
subCommands: {
|
|
@@ -26783,6 +26783,8 @@ var listArgs7 = {
|
|
|
26783
26783
|
"account-id": { type: "string", description: "Meta ad account ID" },
|
|
26784
26784
|
"effective-status": { type: "string", description: "Comma-separated effective_status filter (overrides default)" },
|
|
26785
26785
|
"all-statuses": { type: "boolean", description: "Drop the default ACTIVE filter and return everything" },
|
|
26786
|
+
"name-contains": NAME_CONTAINS_ARG,
|
|
26787
|
+
fields: FIELDS_ARG,
|
|
26786
26788
|
limit: { type: "string", description: "Max rows (default 1000)" },
|
|
26787
26789
|
"no-cache": NO_CACHE_ARG,
|
|
26788
26790
|
output: { type: "string", description: "Output format", default: "json" }
|
|
@@ -26799,10 +26801,17 @@ var listCommand7 = defineCommand62({
|
|
|
26799
26801
|
try {
|
|
26800
26802
|
const params = { "account-id": accountId };
|
|
26801
26803
|
if (effectiveStatus) params["effective-status"] = effectiveStatus;
|
|
26804
|
+
if (args5["name-contains"]) params["name-contains"] = args5["name-contains"];
|
|
26802
26805
|
if (args5.limit) params.limit = args5.limit;
|
|
26803
26806
|
if (args5["no-cache"]) params["skip-cache"] = "true";
|
|
26804
26807
|
const data = await apiGet("/api/ads/meta/campaigns", params);
|
|
26805
|
-
|
|
26808
|
+
const { rows, fields } = projectListRows(data, args5);
|
|
26809
|
+
const fmt = csvOrJson(args5);
|
|
26810
|
+
if (fmt !== "json") {
|
|
26811
|
+
writeAdsOutput(rows, fmt, fields);
|
|
26812
|
+
return;
|
|
26813
|
+
}
|
|
26814
|
+
writeAdsJson({ ok: true, data: rows });
|
|
26806
26815
|
} catch (err) {
|
|
26807
26816
|
handleMetaError(err);
|
|
26808
26817
|
}
|
|
@@ -26821,6 +26830,7 @@ The dashboard shows effective_status: ACTIVE, PAUSED, DELETED, ARCHIVED, IN_PROC
|
|
|
26821
26830
|
Examples:
|
|
26822
26831
|
baker ads meta campaigns --account-id act_123 # ACTIVE only
|
|
26823
26832
|
baker ads meta campaigns --account-id act_123 --all-statuses # everything
|
|
26833
|
+
baker ads meta campaigns --account-id act_123 --all-statuses --name-contains Q3 --fields id,name,status # find one by name
|
|
26824
26834
|
baker ads meta campaigns create --account-id act_123 --name "Q3" --objective OUTCOME_LEADS --daily-budget 50
|
|
26825
26835
|
baker ads meta campaigns pause 6123 --account-id act_123`
|
|
26826
26836
|
},
|