@koda-sl/baker-cli 0.121.0-dev.6fedecad2 → 0.121.0-dev.775026ddd
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 +43 -83
- package/dist/{chunk-MWFJ5NOP.js → chunk-GQIOFHVI.js} +275 -132
- package/dist/chunk-GQIOFHVI.js.map +1 -0
- package/dist/cli.js +2669 -4244
- package/dist/cli.js.map +1 -1
- package/dist/engine/index.d.ts +30 -1
- package/dist/engine/index.js +1 -2
- package/package.json +1 -1
- package/dist/chunk-5WRI5ZAA.js +0 -31
- package/dist/chunk-5WRI5ZAA.js.map +0 -1
- package/dist/chunk-AVJ3B6LC.js +0 -97
- package/dist/chunk-AVJ3B6LC.js.map +0 -1
- package/dist/chunk-ISFSUDEQ.js +0 -264
- package/dist/chunk-ISFSUDEQ.js.map +0 -1
- package/dist/chunk-K47Q73CK.js +0 -156
- package/dist/chunk-K47Q73CK.js.map +0 -1
- package/dist/chunk-MWFJ5NOP.js.map +0 -1
- package/dist/chunk-YTEAWSEM.js +0 -39
- package/dist/chunk-YTEAWSEM.js.map +0 -1
- package/dist/client-PGOTU24X.js +0 -15
- package/dist/client-PGOTU24X.js.map +0 -1
- package/dist/env-TD4VXCQ7.js +0 -10
- package/dist/env-TD4VXCQ7.js.map +0 -1
- package/dist/output-2LGBISBQ.js +0 -18
- package/dist/output-2LGBISBQ.js.map +0 -1
- package/dist/shared-CQC3YRBA.js +0 -23
- package/dist/shared-CQC3YRBA.js.map +0 -1
package/dist/engine/index.d.ts
CHANGED
|
@@ -47,6 +47,13 @@ declare class BackendClient$1 {
|
|
|
47
47
|
putUrl: string;
|
|
48
48
|
publicUrl: string;
|
|
49
49
|
}>;
|
|
50
|
+
/** Remote cache lookup. A miss (404) — or an old backend without the route — returns null. */
|
|
51
|
+
getCacheEntry<T>(cacheKey: string, signal?: AbortSignal): Promise<T | null>;
|
|
52
|
+
putCacheEntry(entry: {
|
|
53
|
+
cacheKey: string;
|
|
54
|
+
}, signal?: AbortSignal): Promise<void>;
|
|
55
|
+
/** Durable run-history record — POST /api/canvas/runs (idempotent server-side on runId). */
|
|
56
|
+
recordRun(payload: unknown, signal?: AbortSignal): Promise<void>;
|
|
50
57
|
getArtifact(kind: string, name: string, version?: string, signal?: AbortSignal): Promise<ArtifactResponse>;
|
|
51
58
|
}
|
|
52
59
|
|
|
@@ -90,7 +97,6 @@ declare const CanvasSchema: z.ZodObject<{
|
|
|
90
97
|
voice_convert_node: z.ZodString;
|
|
91
98
|
scene_s: z.ZodOptional<z.ZodNumber>;
|
|
92
99
|
est_speech_s: z.ZodOptional<z.ZodNumber>;
|
|
93
|
-
speech_words: z.ZodOptional<z.ZodNumber>;
|
|
94
100
|
}, z.core.$strip>, z.ZodObject<{
|
|
95
101
|
scene: z.ZodNumber;
|
|
96
102
|
lipsync_node: z.ZodString;
|
|
@@ -339,6 +345,14 @@ type RunResult = {
|
|
|
339
345
|
duration_ms: number;
|
|
340
346
|
};
|
|
341
347
|
outputs_dir: string;
|
|
348
|
+
node_runs: NodeRunRecord[];
|
|
349
|
+
};
|
|
350
|
+
type NodeRunRecord = {
|
|
351
|
+
node_id: string;
|
|
352
|
+
node_type: string;
|
|
353
|
+
cached: boolean;
|
|
354
|
+
duration_ms: number;
|
|
355
|
+
credits: number;
|
|
342
356
|
};
|
|
343
357
|
type RunOptions = {
|
|
344
358
|
signal?: AbortSignal;
|
|
@@ -354,6 +368,13 @@ type EngineOptions = {
|
|
|
354
368
|
cache: CacheStore;
|
|
355
369
|
outputsDir: string;
|
|
356
370
|
log?: LogFn;
|
|
371
|
+
/**
|
|
372
|
+
* Stamp durable canvas-assets URLs onto fresh node outputs before they are
|
|
373
|
+
* cached — the precondition for remote cache portability and run-history
|
|
374
|
+
* records. Best-effort: a failed upload logs a warning and keeps the entry
|
|
375
|
+
* local-only, never fails the node.
|
|
376
|
+
*/
|
|
377
|
+
persistAssets?: boolean;
|
|
357
378
|
};
|
|
358
379
|
declare class Engine$1 {
|
|
359
380
|
private readonly registry;
|
|
@@ -362,6 +383,7 @@ declare class Engine$1 {
|
|
|
362
383
|
private readonly cache;
|
|
363
384
|
private readonly outputsDir;
|
|
364
385
|
private readonly log;
|
|
386
|
+
private readonly persistAssets;
|
|
365
387
|
constructor(opts: EngineOptions);
|
|
366
388
|
validate(canvas: unknown): {
|
|
367
389
|
ok: true;
|
|
@@ -467,6 +489,13 @@ declare function createEngineFromEnv(opts?: {
|
|
|
467
489
|
cacheDir?: string;
|
|
468
490
|
outputsDir?: string;
|
|
469
491
|
log?: (line: string) => void;
|
|
492
|
+
/**
|
|
493
|
+
* Layer the company-scoped remote cache over the local one (and stamp
|
|
494
|
+
* durable asset URLs onto fresh outputs) so a fresh sandbox re-runs an
|
|
495
|
+
* already-computed canvas at zero credits. Defaults to on; disable with
|
|
496
|
+
* `remoteCache: false` or env BAKER_CANVAS_REMOTE_CACHE=off.
|
|
497
|
+
*/
|
|
498
|
+
remoteCache?: boolean;
|
|
470
499
|
}): Engine$1;
|
|
471
500
|
|
|
472
501
|
export { BackendClient, Engine, LocalAssetStore, LocalCacheStore, ValidationError, createEngineFromEnv, defaultRegistry, generateCatalog, validateCanvasDeep };
|
package/dist/engine/index.js
CHANGED
package/package.json
CHANGED
package/dist/chunk-5WRI5ZAA.js
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
var __create = Object.create;
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
-
var __commonJS = (cb, mod) => function __require() {
|
|
8
|
-
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
9
|
-
};
|
|
10
|
-
var __copyProps = (to, from, except, desc) => {
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
-
for (let key of __getOwnPropNames(from))
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
19
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
20
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
21
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
22
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
23
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
24
|
-
mod
|
|
25
|
-
));
|
|
26
|
-
|
|
27
|
-
export {
|
|
28
|
-
__commonJS,
|
|
29
|
-
__toESM
|
|
30
|
-
};
|
|
31
|
-
//# sourceMappingURL=chunk-5WRI5ZAA.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/chunk-AVJ3B6LC.js
DELETED
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
handleConnectionError,
|
|
3
|
-
writeAdsJson
|
|
4
|
-
} from "./chunk-ISFSUDEQ.js";
|
|
5
|
-
import {
|
|
6
|
-
ApiError
|
|
7
|
-
} from "./chunk-K47Q73CK.js";
|
|
8
|
-
import {
|
|
9
|
-
getEnv
|
|
10
|
-
} from "./chunk-YTEAWSEM.js";
|
|
11
|
-
|
|
12
|
-
// src/commands/ads/meta/shared.ts
|
|
13
|
-
var DAY_MS = 864e5;
|
|
14
|
-
function handleMetaError(err) {
|
|
15
|
-
if (err instanceof ApiError) {
|
|
16
|
-
if (err.code === "UNAUTHORIZED" || err.code === "NOT_FOUND") {
|
|
17
|
-
handleConnectionError("meta_ads", err.message);
|
|
18
|
-
}
|
|
19
|
-
const envelope = {
|
|
20
|
-
ok: false,
|
|
21
|
-
error: {
|
|
22
|
-
code: err.code,
|
|
23
|
-
message: err.message,
|
|
24
|
-
fix: { action: "reject", explanation: err.message },
|
|
25
|
-
retryable: err.code === "RATE_LIMITED" || err.code === "INTERNAL_ERROR"
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
writeAdsJson(envelope);
|
|
29
|
-
process.exit(1);
|
|
30
|
-
}
|
|
31
|
-
const message = err instanceof Error ? err.message : "Unexpected error";
|
|
32
|
-
writeAdsJson({ ok: false, error: { code: "NETWORK_ERROR", message } });
|
|
33
|
-
process.exit(1);
|
|
34
|
-
}
|
|
35
|
-
var ACCOUNT_ID_RE = /^(act_)?[0-9]+$/;
|
|
36
|
-
function resolveAccountIdArg(args) {
|
|
37
|
-
const fromArgs = args["account-id"];
|
|
38
|
-
const id = fromArgs || getEnv().BAKER_META_AD_ACCOUNT_ID;
|
|
39
|
-
if (!id) {
|
|
40
|
-
writeAdsJson({
|
|
41
|
-
ok: false,
|
|
42
|
-
error: {
|
|
43
|
-
code: "MISSING_ACCOUNT_ID",
|
|
44
|
-
message: "Pass --account-id or set BAKER_META_AD_ACCOUNT_ID. Run `baker ads meta accounts` to find IDs."
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
process.exit(1);
|
|
48
|
-
}
|
|
49
|
-
if (!ACCOUNT_ID_RE.test(id)) {
|
|
50
|
-
writeAdsJson({
|
|
51
|
-
ok: false,
|
|
52
|
-
error: {
|
|
53
|
-
code: "INVALID_ACCOUNT_ID",
|
|
54
|
-
message: `Invalid account ID "${id}". Expected numeric ID, optionally prefixed with "act_".`
|
|
55
|
-
}
|
|
56
|
-
});
|
|
57
|
-
process.exit(1);
|
|
58
|
-
}
|
|
59
|
-
return id.startsWith("act_") ? id : `act_${id}`;
|
|
60
|
-
}
|
|
61
|
-
function getDateRange(args) {
|
|
62
|
-
const datePreset = args["date-preset"];
|
|
63
|
-
const since = args.since;
|
|
64
|
-
const until = args.until;
|
|
65
|
-
if (since && until) return { since, until };
|
|
66
|
-
return { datePreset: datePreset ?? "last_7d" };
|
|
67
|
-
}
|
|
68
|
-
function todayIso() {
|
|
69
|
-
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
70
|
-
}
|
|
71
|
-
function daysAgoIso(days) {
|
|
72
|
-
return new Date(Date.now() - days * DAY_MS).toISOString().slice(0, 10);
|
|
73
|
-
}
|
|
74
|
-
function csvOrJson(args) {
|
|
75
|
-
return args.output ?? "json";
|
|
76
|
-
}
|
|
77
|
-
function resolveEffectiveStatus(args) {
|
|
78
|
-
if (args["all-statuses"]) {
|
|
79
|
-
return void 0;
|
|
80
|
-
}
|
|
81
|
-
const explicit = args["effective-status"];
|
|
82
|
-
if (explicit) {
|
|
83
|
-
return explicit;
|
|
84
|
-
}
|
|
85
|
-
return "ACTIVE";
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
export {
|
|
89
|
-
handleMetaError,
|
|
90
|
-
resolveAccountIdArg,
|
|
91
|
-
getDateRange,
|
|
92
|
-
todayIso,
|
|
93
|
-
daysAgoIso,
|
|
94
|
-
csvOrJson,
|
|
95
|
-
resolveEffectiveStatus
|
|
96
|
-
};
|
|
97
|
-
//# sourceMappingURL=chunk-AVJ3B6LC.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/ads/meta/shared.ts"],"sourcesContent":["import { ApiError } from \"../../../client.ts\";\nimport { getEnv } from \"../../../env.ts\";\nimport { handleConnectionError } from \"../../../error-handler.ts\";\nimport { writeAdsJson } from \"../output.ts\";\nimport type { AdsErrorEnvelope } from \"../types.ts\";\n\nconst DAY_MS = 86_400_000;\n\nexport function handleMetaError(err: unknown): never {\n if (err instanceof ApiError) {\n if (err.code === \"UNAUTHORIZED\" || err.code === \"NOT_FOUND\") {\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: { action: \"reject\", explanation: err.message },\n retryable: err.code === \"RATE_LIMITED\" || 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 * 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":";;;;;;;;;;;;AAMA,IAAM,SAAS;AAER,SAAS,gBAAgB,KAAqB;AACnD,MAAI,eAAe,UAAU;AAC3B,QAAI,IAAI,SAAS,kBAAkB,IAAI,SAAS,aAAa;AAC3D,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,EAAE,QAAQ,UAAU,aAAa,IAAI,QAAQ;AAAA,QAClD,WAAW,IAAI,SAAS,kBAAkB,IAAI,SAAS;AAAA,MACzD;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;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/chunk-ISFSUDEQ.js
DELETED
|
@@ -1,264 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
apiGet
|
|
3
|
-
} from "./chunk-K47Q73CK.js";
|
|
4
|
-
import {
|
|
5
|
-
getEnv
|
|
6
|
-
} from "./chunk-YTEAWSEM.js";
|
|
7
|
-
|
|
8
|
-
// src/commands/ads/cache.ts
|
|
9
|
-
import { createHash } from "crypto";
|
|
10
|
-
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "fs";
|
|
11
|
-
import { homedir } from "os";
|
|
12
|
-
import { join } from "path";
|
|
13
|
-
var CACHE_DIR = join(homedir(), ".baker", "cache", "ads");
|
|
14
|
-
function ensureDir(dir) {
|
|
15
|
-
if (!existsSync(dir)) {
|
|
16
|
-
mkdirSync(dir, { recursive: true });
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
function hashKey(key) {
|
|
20
|
-
return createHash("sha256").update(key).digest("hex").slice(0, 16);
|
|
21
|
-
}
|
|
22
|
-
function cachePath(category, key) {
|
|
23
|
-
const dir = join(CACHE_DIR, category);
|
|
24
|
-
ensureDir(dir);
|
|
25
|
-
return join(dir, `${hashKey(key)}.json`);
|
|
26
|
-
}
|
|
27
|
-
function cacheGet(category, key) {
|
|
28
|
-
const path = cachePath(category, key);
|
|
29
|
-
if (!existsSync(path)) {
|
|
30
|
-
return null;
|
|
31
|
-
}
|
|
32
|
-
try {
|
|
33
|
-
const raw = readFileSync(path, "utf-8");
|
|
34
|
-
const entry = JSON.parse(raw);
|
|
35
|
-
if (entry.expiresAt < Date.now()) {
|
|
36
|
-
rmSync(path, { force: true });
|
|
37
|
-
return null;
|
|
38
|
-
}
|
|
39
|
-
return entry;
|
|
40
|
-
} catch {
|
|
41
|
-
rmSync(path, { force: true });
|
|
42
|
-
return null;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
function cacheSet(category, key, data, ttlMs, fields) {
|
|
46
|
-
const path = cachePath(category, key);
|
|
47
|
-
const entry = {
|
|
48
|
-
expiresAt: Date.now() + ttlMs,
|
|
49
|
-
data,
|
|
50
|
-
fields
|
|
51
|
-
};
|
|
52
|
-
writeFileSync(path, JSON.stringify(entry), "utf-8");
|
|
53
|
-
}
|
|
54
|
-
var HOUR = 60 * 60 * 1e3;
|
|
55
|
-
var MINUTE = 60 * 1e3;
|
|
56
|
-
function getQueryTtl(query) {
|
|
57
|
-
const upper = query.toUpperCase();
|
|
58
|
-
if (upper.includes("TODAY")) {
|
|
59
|
-
return 15 * MINUTE;
|
|
60
|
-
}
|
|
61
|
-
if (upper.includes("LAST_7_DAYS") || upper.includes("LAST_14_DAYS")) {
|
|
62
|
-
return 1 * HOUR;
|
|
63
|
-
}
|
|
64
|
-
return 6 * HOUR;
|
|
65
|
-
}
|
|
66
|
-
function buildQueryCacheKey(customerId, query) {
|
|
67
|
-
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
68
|
-
return `${customerId}:${today}:${query.trim().replace(/\s+/g, " ")}`;
|
|
69
|
-
}
|
|
70
|
-
function getManagerIdForCustomer(customerId) {
|
|
71
|
-
const cached = cacheGet("accounts", "list");
|
|
72
|
-
if (!cached) return void 0;
|
|
73
|
-
const account = cached.data.find((a) => a.id === customerId);
|
|
74
|
-
if (account?.access_type === "managed") return account.manager_id;
|
|
75
|
-
return void 0;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// src/error-handler.ts
|
|
79
|
-
function handleConnectionError(platform, originalMessage) {
|
|
80
|
-
const platformName = {
|
|
81
|
-
google_ads: "Google Ads",
|
|
82
|
-
ga4: "Google Analytics 4",
|
|
83
|
-
gsc: "Google Search Console",
|
|
84
|
-
x_ads: "X Ads",
|
|
85
|
-
meta_ads: "Meta Ads",
|
|
86
|
-
linkedin_ads: "LinkedIn Ads"
|
|
87
|
-
}[platform];
|
|
88
|
-
const alternative = {
|
|
89
|
-
google_ads: "keywords-for-site or research advertisers",
|
|
90
|
-
ga4: "lighthouse for page performance",
|
|
91
|
-
gsc: "keywords-for-site or research keyword-gap",
|
|
92
|
-
x_ads: "research advertisers",
|
|
93
|
-
meta_ads: "research advertisers or research keyword-ideas",
|
|
94
|
-
linkedin_ads: "research advertisers (LinkedIn Ad Library) or research keyword-ideas"
|
|
95
|
-
}[platform];
|
|
96
|
-
const code = {
|
|
97
|
-
google_ads: "NO_GOOGLE_ADS_CONNECTION",
|
|
98
|
-
ga4: "NO_GA4_CONNECTION",
|
|
99
|
-
gsc: "NO_GSC_CONNECTION",
|
|
100
|
-
x_ads: "NO_X_ADS_CONNECTION",
|
|
101
|
-
meta_ads: "NO_META_ADS_CONNECTION",
|
|
102
|
-
linkedin_ads: "NO_LINKEDIN_ADS_CONNECTION"
|
|
103
|
-
}[platform];
|
|
104
|
-
const envelope = {
|
|
105
|
-
ok: false,
|
|
106
|
-
error: {
|
|
107
|
-
code,
|
|
108
|
-
message: originalMessage || `No ${platformName} connection found for this company.`,
|
|
109
|
-
fix: {
|
|
110
|
-
action: "authenticate",
|
|
111
|
-
explanation: `AGENT INSTRUCTION: You cannot resolve this error programmatically. The user has not connected their ${platformName} account. Step 1: Inform the user that they must connect ${platformName} in their Baker dashboard settings for direct data queries. Step 2: Do not fail the overall audit or playbook. Document the missing connection, skip this specific check, and proceed with the rest of your tasks. (Optional fallback: use 'baker research ${alternative}' for estimated external insights).`
|
|
112
|
-
},
|
|
113
|
-
retryable: false
|
|
114
|
-
}
|
|
115
|
-
};
|
|
116
|
-
writeJsonEnvelope(envelope);
|
|
117
|
-
process.exit(1);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// src/commands/ads/output.ts
|
|
121
|
-
function writeAdsJson(envelope) {
|
|
122
|
-
process.stdout.write(`${JSON.stringify(envelope, null, 2)}
|
|
123
|
-
`);
|
|
124
|
-
}
|
|
125
|
-
function writeJsonEnvelope(envelope) {
|
|
126
|
-
process.stdout.write(`${JSON.stringify(envelope, null, 2)}
|
|
127
|
-
`);
|
|
128
|
-
}
|
|
129
|
-
function toCsvRow(values) {
|
|
130
|
-
return values.map((v) => {
|
|
131
|
-
if (v.includes(",") || v.includes('"') || v.includes("\n")) {
|
|
132
|
-
return `"${v.replace(/"/g, '""')}"`;
|
|
133
|
-
}
|
|
134
|
-
return v;
|
|
135
|
-
}).join(",");
|
|
136
|
-
}
|
|
137
|
-
function flattenRow(row) {
|
|
138
|
-
const flat = {};
|
|
139
|
-
for (const [key, val] of Object.entries(row)) {
|
|
140
|
-
flat[key] = typeof val === "object" && val !== null ? JSON.stringify(val) : String(val ?? "");
|
|
141
|
-
}
|
|
142
|
-
return flat;
|
|
143
|
-
}
|
|
144
|
-
function writeAdsCsv(data, fields) {
|
|
145
|
-
if (data.length === 0) return;
|
|
146
|
-
const cols = fields ?? Object.keys(data[0] ?? {});
|
|
147
|
-
process.stdout.write(`${toCsvRow(cols)}
|
|
148
|
-
`);
|
|
149
|
-
for (const row of data) {
|
|
150
|
-
const flat = flattenRow(row);
|
|
151
|
-
process.stdout.write(`${toCsvRow(cols.map((f) => flat[f] ?? ""))}
|
|
152
|
-
`);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
function writeAdsJsonl(data) {
|
|
156
|
-
for (const row of data) {
|
|
157
|
-
process.stdout.write(`${JSON.stringify(row)}
|
|
158
|
-
`);
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
function writeAdsMd(data, fields) {
|
|
162
|
-
if (data.length === 0) return;
|
|
163
|
-
const cols = fields ?? Object.keys(data[0] ?? {});
|
|
164
|
-
process.stdout.write(`| ${cols.join(" | ")} |
|
|
165
|
-
`);
|
|
166
|
-
process.stdout.write(`| ${cols.map(() => "---").join(" | ")} |
|
|
167
|
-
`);
|
|
168
|
-
for (const row of data) {
|
|
169
|
-
const flat = flattenRow(row);
|
|
170
|
-
process.stdout.write(`| ${cols.map((f) => flat[f] ?? "").join(" | ")} |
|
|
171
|
-
`);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
function writeAdsOutput(data, format, fields) {
|
|
175
|
-
switch (format) {
|
|
176
|
-
case "csv":
|
|
177
|
-
writeAdsCsv(data, fields);
|
|
178
|
-
break;
|
|
179
|
-
case "jsonl":
|
|
180
|
-
writeAdsJsonl(data);
|
|
181
|
-
break;
|
|
182
|
-
case "md":
|
|
183
|
-
writeAdsMd(data, fields);
|
|
184
|
-
break;
|
|
185
|
-
default:
|
|
186
|
-
writeAdsJson({ ok: true, data });
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
async function fetchAccounts(useCache = true) {
|
|
190
|
-
if (useCache) {
|
|
191
|
-
const cached = cacheGet("accounts", "list");
|
|
192
|
-
if (cached) return cached.data;
|
|
193
|
-
}
|
|
194
|
-
const params = !useCache ? { "skip-cache": "true" } : void 0;
|
|
195
|
-
const data = await apiGet("/api/ads/google/accounts", params);
|
|
196
|
-
if (useCache) {
|
|
197
|
-
cacheSet("accounts", "list", data, 60 * 60 * 1e3);
|
|
198
|
-
}
|
|
199
|
-
return data;
|
|
200
|
-
}
|
|
201
|
-
async function resolveCustomerId(args) {
|
|
202
|
-
const fromArgs = args["customer-id"];
|
|
203
|
-
const customerId = fromArgs || getEnv().BAKER_GOOGLE_ADS_CUSTOMER_ID;
|
|
204
|
-
if (customerId) {
|
|
205
|
-
if (!/^\d{10}$/.test(customerId)) {
|
|
206
|
-
writeAdsJson({
|
|
207
|
-
ok: false,
|
|
208
|
-
error: {
|
|
209
|
-
code: "INVALID_CUSTOMER_ID",
|
|
210
|
-
message: "Customer ID must be exactly 10 digits without dashes. Pass --customer-id or set BAKER_GOOGLE_ADS_CUSTOMER_ID."
|
|
211
|
-
}
|
|
212
|
-
});
|
|
213
|
-
process.exit(1);
|
|
214
|
-
}
|
|
215
|
-
return customerId;
|
|
216
|
-
}
|
|
217
|
-
const useCache = !args["no-cache"];
|
|
218
|
-
try {
|
|
219
|
-
const accounts = await fetchAccounts(useCache);
|
|
220
|
-
const [single] = accounts;
|
|
221
|
-
if (accounts.length === 1 && single) {
|
|
222
|
-
process.stderr.write(`Using account "${single.name}" (${single.id})
|
|
223
|
-
`);
|
|
224
|
-
return single.id;
|
|
225
|
-
}
|
|
226
|
-
if (accounts.length === 0) {
|
|
227
|
-
handleConnectionError("google_ads");
|
|
228
|
-
}
|
|
229
|
-
const list = accounts.map((a) => ` ${a.id} ${a.name}`).join("\n");
|
|
230
|
-
writeAdsJson({
|
|
231
|
-
ok: false,
|
|
232
|
-
error: {
|
|
233
|
-
code: "MULTIPLE_ACCOUNTS",
|
|
234
|
-
message: `Multiple accounts found. Pass --customer-id or set BAKER_GOOGLE_ADS_CUSTOMER_ID:
|
|
235
|
-
${list}`
|
|
236
|
-
}
|
|
237
|
-
});
|
|
238
|
-
process.exit(1);
|
|
239
|
-
} catch {
|
|
240
|
-
writeAdsJson({
|
|
241
|
-
ok: false,
|
|
242
|
-
error: {
|
|
243
|
-
code: "INVALID_CUSTOMER_ID",
|
|
244
|
-
message: "Could not auto-detect account. Pass --customer-id or set BAKER_GOOGLE_ADS_CUSTOMER_ID."
|
|
245
|
-
}
|
|
246
|
-
});
|
|
247
|
-
process.exit(1);
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
export {
|
|
252
|
-
cacheGet,
|
|
253
|
-
cacheSet,
|
|
254
|
-
getQueryTtl,
|
|
255
|
-
buildQueryCacheKey,
|
|
256
|
-
getManagerIdForCustomer,
|
|
257
|
-
handleConnectionError,
|
|
258
|
-
writeAdsJson,
|
|
259
|
-
writeJsonEnvelope,
|
|
260
|
-
toCsvRow,
|
|
261
|
-
writeAdsOutput,
|
|
262
|
-
resolveCustomerId
|
|
263
|
-
};
|
|
264
|
-
//# sourceMappingURL=chunk-ISFSUDEQ.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/ads/cache.ts","../src/error-handler.ts","../src/commands/ads/output.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport type { CacheEntry } from \"./types.ts\";\n\nconst CACHE_DIR = join(homedir(), \".baker\", \"cache\", \"ads\");\n\nfunction ensureDir(dir: string): void {\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n}\n\nfunction hashKey(key: string): string {\n return createHash(\"sha256\").update(key).digest(\"hex\").slice(0, 16);\n}\n\nfunction cachePath(category: string, key: string): string {\n const dir = join(CACHE_DIR, category);\n ensureDir(dir);\n return join(dir, `${hashKey(key)}.json`);\n}\n\nexport function cacheGet<T>(category: string, key: string): CacheEntry<T> | null {\n const path = cachePath(category, key);\n if (!existsSync(path)) {\n return null;\n }\n try {\n const raw = readFileSync(path, \"utf-8\");\n const entry = JSON.parse(raw) as CacheEntry<T>;\n if (entry.expiresAt < Date.now()) {\n rmSync(path, { force: true });\n return null;\n }\n return entry;\n } catch {\n rmSync(path, { force: true });\n return null;\n }\n}\n\nexport function cacheSet<T>(\n category: string,\n key: string,\n data: T,\n ttlMs: number,\n fields?: Record<string, string>,\n): void {\n const path = cachePath(category, key);\n const entry: CacheEntry<T> = {\n expiresAt: Date.now() + ttlMs,\n data,\n fields,\n };\n writeFileSync(path, JSON.stringify(entry), \"utf-8\");\n}\n\nconst HOUR = 60 * 60 * 1000;\nconst MINUTE = 60 * 1000;\n\nexport function getQueryTtl(query: string): number {\n const upper = query.toUpperCase();\n if (upper.includes(\"TODAY\")) {\n return 15 * MINUTE;\n }\n if (upper.includes(\"LAST_7_DAYS\") || upper.includes(\"LAST_14_DAYS\")) {\n return 1 * HOUR;\n }\n // Historical data (BETWEEN, LAST_30_DAYS, LAST_90_DAYS, etc.)\n return 6 * HOUR;\n}\n\nexport function buildQueryCacheKey(customerId: string, query: string): string {\n const today = new Date().toISOString().slice(0, 10);\n return `${customerId}:${today}:${query.trim().replace(/\\s+/g, \" \")}`;\n}\n\ninterface CachedAccount {\n id: string;\n access_type: \"direct\" | \"managed\";\n manager_id?: string;\n}\n\nexport function getManagerIdForCustomer(customerId: string): string | undefined {\n const cached = cacheGet<CachedAccount[]>(\"accounts\", \"list\");\n if (!cached) return undefined;\n const account = cached.data.find((a) => a.id === customerId);\n if (account?.access_type === \"managed\") return account.manager_id;\n return undefined;\n}\n","import { writeJsonEnvelope } from \"./commands/ads/output.ts\";\n\ntype ConnectionPlatform = \"google_ads\" | \"ga4\" | \"gsc\" | \"x_ads\" | \"meta_ads\" | \"linkedin_ads\";\n\n/**\n * Shared error handler for \"No Connection\" scenarios.\n * Provides a structured error for AI agents with a suggested fix and alternative commands.\n */\nexport function handleConnectionError(platform: ConnectionPlatform, originalMessage?: string): never {\n const platformName = {\n google_ads: \"Google Ads\",\n ga4: \"Google Analytics 4\",\n gsc: \"Google Search Console\",\n x_ads: \"X Ads\",\n meta_ads: \"Meta Ads\",\n linkedin_ads: \"LinkedIn Ads\",\n }[platform];\n\n const alternative = {\n google_ads: \"keywords-for-site or research advertisers\",\n ga4: \"lighthouse for page performance\",\n gsc: \"keywords-for-site or research keyword-gap\",\n x_ads: \"research advertisers\",\n meta_ads: \"research advertisers or research keyword-ideas\",\n linkedin_ads: \"research advertisers (LinkedIn Ad Library) or research keyword-ideas\",\n }[platform];\n\n const code = {\n google_ads: \"NO_GOOGLE_ADS_CONNECTION\",\n ga4: \"NO_GA4_CONNECTION\",\n gsc: \"NO_GSC_CONNECTION\",\n x_ads: \"NO_X_ADS_CONNECTION\",\n meta_ads: \"NO_META_ADS_CONNECTION\",\n linkedin_ads: \"NO_LINKEDIN_ADS_CONNECTION\",\n }[platform];\n\n const envelope = {\n ok: false,\n error: {\n code,\n message: originalMessage || `No ${platformName} connection found for this company.`,\n fix: {\n action: \"authenticate\",\n explanation: `AGENT INSTRUCTION: You cannot resolve this error programmatically. The user has not connected their ${platformName} account. Step 1: Inform the user that they must connect ${platformName} in their Baker dashboard settings for direct data queries. Step 2: Do not fail the overall audit or playbook. Document the missing connection, skip this specific check, and proceed with the rest of your tasks. (Optional fallback: use 'baker research ${alternative}' for estimated external insights).`,\n },\n retryable: false,\n },\n };\n\n writeJsonEnvelope(envelope);\n process.exit(1);\n}\n","import { apiGet } from \"../../client.ts\";\nimport { getEnv } from \"../../env.ts\";\nimport type { QueryContext } from \"../../geo-context.ts\";\nimport { cacheGet, cacheSet } from \"./cache.ts\";\nimport type { AdsErrorEnvelope, AdsFileSummary, AdsSuccessEnvelope } from \"./types.ts\";\n\ntype AdsOutput =\n | AdsSuccessEnvelope<unknown>\n | AdsErrorEnvelope\n | AdsFileSummary\n | { ok: true; data: unknown; query_context?: QueryContext; cached?: true; fields?: Record<string, string> }\n | { ok: false; error: { code: string; message: string } };\n\nexport function writeAdsJson(envelope: AdsOutput): void {\n process.stdout.write(`${JSON.stringify(envelope, null, 2)}\\n`);\n}\n\nexport function writeJsonEnvelope(envelope: Record<string, unknown>): void {\n process.stdout.write(`${JSON.stringify(envelope, null, 2)}\\n`);\n}\n\nexport function toCsvRow(values: string[]): string {\n return values\n .map((v) => {\n if (v.includes(\",\") || v.includes('\"') || v.includes(\"\\n\")) {\n return `\"${v.replace(/\"/g, '\"\"')}\"`;\n }\n return v;\n })\n .join(\",\");\n}\n\nfunction flattenRow(row: Record<string, unknown>): Record<string, string> {\n const flat: Record<string, string> = {};\n for (const [key, val] of Object.entries(row)) {\n flat[key] = typeof val === \"object\" && val !== null ? JSON.stringify(val) : String(val ?? \"\");\n }\n return flat;\n}\n\nfunction writeAdsCsv(data: Array<Record<string, unknown>>, fields?: string[]): void {\n if (data.length === 0) return;\n const cols = fields ?? Object.keys(data[0] ?? {});\n process.stdout.write(`${toCsvRow(cols)}\\n`);\n for (const row of data) {\n const flat = flattenRow(row);\n process.stdout.write(`${toCsvRow(cols.map((f) => flat[f] ?? \"\"))}\\n`);\n }\n}\n\nfunction writeAdsJsonl(data: Array<Record<string, unknown>>): void {\n for (const row of data) {\n process.stdout.write(`${JSON.stringify(row)}\\n`);\n }\n}\n\nfunction writeAdsMd(data: Array<Record<string, unknown>>, fields?: string[]): void {\n if (data.length === 0) return;\n const cols = fields ?? Object.keys(data[0] ?? {});\n process.stdout.write(`| ${cols.join(\" | \")} |\\n`);\n process.stdout.write(`| ${cols.map(() => \"---\").join(\" | \")} |\\n`);\n for (const row of data) {\n const flat = flattenRow(row);\n process.stdout.write(`| ${cols.map((f) => flat[f] ?? \"\").join(\" | \")} |\\n`);\n }\n}\n\nexport function writeAdsOutput(data: Array<Record<string, unknown>>, format: string, fields?: string[]): void {\n switch (format) {\n case \"csv\":\n writeAdsCsv(data, fields);\n break;\n case \"jsonl\":\n writeAdsJsonl(data);\n break;\n case \"md\":\n writeAdsMd(data, fields);\n break;\n default:\n writeAdsJson({ ok: true, data });\n }\n}\n\ninterface AccountInfo {\n id: string;\n name: string;\n access_type: \"direct\" | \"managed\";\n level: number;\n manager_id?: string;\n}\n\nasync function fetchAccounts(useCache = true): Promise<AccountInfo[]> {\n if (useCache) {\n const cached = cacheGet<AccountInfo[]>(\"accounts\", \"list\");\n if (cached) return cached.data;\n }\n const params = !useCache ? { \"skip-cache\": \"true\" } : undefined;\n const data = await apiGet<AccountInfo[]>(\"/api/ads/google/accounts\", params);\n if (useCache) {\n cacheSet(\"accounts\", \"list\", data, 60 * 60 * 1000);\n }\n return data;\n}\n\nimport { handleConnectionError } from \"../../error-handler.ts\";\n\nexport async function resolveCustomerId(args: Record<string, unknown>): Promise<string> {\n const fromArgs = args[\"customer-id\"] as string | undefined;\n const customerId = fromArgs || getEnv().BAKER_GOOGLE_ADS_CUSTOMER_ID;\n\n if (customerId) {\n if (!/^\\d{10}$/.test(customerId)) {\n writeAdsJson({\n ok: false,\n error: {\n code: \"INVALID_CUSTOMER_ID\",\n message:\n \"Customer ID must be exactly 10 digits without dashes. Pass --customer-id or set BAKER_GOOGLE_ADS_CUSTOMER_ID.\",\n },\n });\n process.exit(1);\n }\n return customerId;\n }\n\n const useCache = !args[\"no-cache\"];\n\n try {\n const accounts = await fetchAccounts(useCache);\n const [single] = accounts;\n if (accounts.length === 1 && single) {\n process.stderr.write(`Using account \"${single.name}\" (${single.id})\\n`);\n return single.id;\n }\n if (accounts.length === 0) {\n handleConnectionError(\"google_ads\");\n }\n const list = accounts.map((a) => ` ${a.id} ${a.name}`).join(\"\\n\");\n writeAdsJson({\n ok: false,\n error: {\n code: \"MULTIPLE_ACCOUNTS\",\n message: `Multiple accounts found. Pass --customer-id or set BAKER_GOOGLE_ADS_CUSTOMER_ID:\\n${list}`,\n },\n });\n process.exit(1);\n } catch {\n writeAdsJson({\n ok: false,\n error: {\n code: \"INVALID_CUSTOMER_ID\",\n message: \"Could not auto-detect account. Pass --customer-id or set BAKER_GOOGLE_ADS_CUSTOMER_ID.\",\n },\n });\n process.exit(1);\n }\n}\n"],"mappings":"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","names":[]}
|