@zalify/cli 0.25.0 → 0.26.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 +8 -0
- package/dist/cli.js +98 -51
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -58,6 +58,14 @@ API keys — list and revoke them in **Settings → Developer**. One login
|
|
|
58
58
|
covers every workspace; `zalify workspace set` switches between them
|
|
59
59
|
locally, no re-login.
|
|
60
60
|
|
|
61
|
+
**Inside a brand checkout, the folder decides.** `ads` commands read the
|
|
62
|
+
checkout's own workspace (its `.zalify/brand-repo.json` stamp, or
|
|
63
|
+
`identity.yaml` for folders AdsBuddy downloaded) and act as that
|
|
64
|
+
workspace — no `workspace set` first, and no risk of pulling one
|
|
65
|
+
brand's campaigns into another's folder. `workspace set` still matters
|
|
66
|
+
for commands run outside any checkout, and for `ads create`, which
|
|
67
|
+
provisions a NEW brand into the workspace you chose.
|
|
68
|
+
|
|
61
69
|
## Command reference
|
|
62
70
|
|
|
63
71
|
### Auth & workspace
|
package/dist/cli.js
CHANGED
|
@@ -18259,7 +18259,7 @@ function updateNotifier(options) {
|
|
|
18259
18259
|
|
|
18260
18260
|
// src/cli.ts
|
|
18261
18261
|
import { createRequire as createRequire2 } from "node:module";
|
|
18262
|
-
import { dirname as
|
|
18262
|
+
import { dirname as dirname4, join as join14 } from "node:path";
|
|
18263
18263
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
18264
18264
|
|
|
18265
18265
|
// src/auth.ts
|
|
@@ -18271,7 +18271,7 @@ import { spawn as spawn2 } from "node:child_process";
|
|
|
18271
18271
|
// src/config.ts
|
|
18272
18272
|
import { readFileSync, writeFileSync as writeFileSync2, mkdirSync, rmSync, existsSync } from "node:fs";
|
|
18273
18273
|
import { homedir } from "node:os";
|
|
18274
|
-
import { join } from "node:path";
|
|
18274
|
+
import { dirname, join, resolve } from "node:path";
|
|
18275
18275
|
var dir = join(homedir(), ".zalify");
|
|
18276
18276
|
var file = join(dir, "config.json");
|
|
18277
18277
|
function migrate(raw) {
|
|
@@ -18339,16 +18339,60 @@ function enforceWorkspaceLink(root, auth) {
|
|
|
18339
18339
|
return;
|
|
18340
18340
|
}
|
|
18341
18341
|
if (ws.id !== auth.workspaceId) {
|
|
18342
|
-
throw new Error(`This checkout belongs to workspace "${ws.name ?? ws.slug ?? ws.id}" ` + `but the
|
|
18343
|
-
` + `Run \`zalify workspace set ${ws.slug ?? ws.id}\` first.`);
|
|
18342
|
+
throw new Error(`This checkout belongs to workspace "${ws.name ?? ws.slug ?? ws.id}" ` + `but the command is running as "${auth.workspaceName}" (${auth.workspaceSlug}).`);
|
|
18344
18343
|
}
|
|
18345
18344
|
}
|
|
18346
|
-
function
|
|
18345
|
+
function checkoutWorkspace(startDir) {
|
|
18346
|
+
let cur = resolve(startDir ?? process.cwd());
|
|
18347
|
+
for (let up = 0;up < 12; up += 1) {
|
|
18348
|
+
const stamp = join(cur, ".zalify", "brand-repo.json");
|
|
18349
|
+
if (existsSync(stamp)) {
|
|
18350
|
+
try {
|
|
18351
|
+
const link = JSON.parse(readFileSync(stamp, "utf8"));
|
|
18352
|
+
const ws = link.workspace;
|
|
18353
|
+
if (ws?.id) {
|
|
18354
|
+
return {
|
|
18355
|
+
root: cur,
|
|
18356
|
+
id: ws.id,
|
|
18357
|
+
name: ws.name ?? ws.slug ?? ws.id,
|
|
18358
|
+
slug: ws.slug ?? ws.id
|
|
18359
|
+
};
|
|
18360
|
+
}
|
|
18361
|
+
} catch {}
|
|
18362
|
+
}
|
|
18363
|
+
const identity = join(cur, "identity.yaml");
|
|
18364
|
+
if (existsSync(identity)) {
|
|
18365
|
+
const text = readFileSync(identity, "utf8");
|
|
18366
|
+
const id = /^workspace_id:\s*(\S+)\s*$/m.exec(text)?.[1];
|
|
18367
|
+
const slug = /^brand_slug:\s*(\S+)\s*$/m.exec(text)?.[1];
|
|
18368
|
+
if (id)
|
|
18369
|
+
return { root: cur, id, name: slug ?? id, slug: slug ?? id };
|
|
18370
|
+
}
|
|
18371
|
+
const parent = dirname(cur);
|
|
18372
|
+
if (parent === cur)
|
|
18373
|
+
break;
|
|
18374
|
+
cur = parent;
|
|
18375
|
+
}
|
|
18376
|
+
return null;
|
|
18377
|
+
}
|
|
18378
|
+
function requireActive(opts) {
|
|
18347
18379
|
const config = readConfig();
|
|
18348
18380
|
if (!config) {
|
|
18349
18381
|
throw new Error("Not logged in. Run `zalify login` first.");
|
|
18350
18382
|
}
|
|
18383
|
+
const here = opts?.global ? null : checkoutWorkspace();
|
|
18351
18384
|
if (config.version === 3) {
|
|
18385
|
+
if (here) {
|
|
18386
|
+
const known = config.workspacesCache?.find((w) => w.id === here.id) ?? null;
|
|
18387
|
+
return {
|
|
18388
|
+
appUrl: config.appUrl,
|
|
18389
|
+
key: config.userKey,
|
|
18390
|
+
workspaceId: here.id,
|
|
18391
|
+
workspaceName: known?.name ?? here.name,
|
|
18392
|
+
workspaceSlug: known?.slug ?? here.slug,
|
|
18393
|
+
config
|
|
18394
|
+
};
|
|
18395
|
+
}
|
|
18352
18396
|
if (!config.active) {
|
|
18353
18397
|
throw new Error("No active workspace. Run `zalify workspace list` then `zalify workspace set <slug>`.");
|
|
18354
18398
|
}
|
|
@@ -18365,7 +18409,10 @@ function requireActive() {
|
|
|
18365
18409
|
if (ids.length === 0) {
|
|
18366
18410
|
throw new Error("Not logged in. Run `zalify login` first.");
|
|
18367
18411
|
}
|
|
18368
|
-
|
|
18412
|
+
if (here && !config.workspaces[here.id]) {
|
|
18413
|
+
throw new Error(`This folder belongs to workspace "${here.slug}" but your login has no key for it. ` + "Run `zalify login` again to refresh your credentials.");
|
|
18414
|
+
}
|
|
18415
|
+
const workspaceId = here?.id ?? (config.activeWorkspaceId && config.workspaces[config.activeWorkspaceId] ? config.activeWorkspaceId : ids[0]);
|
|
18369
18416
|
const entry = config.workspaces[workspaceId];
|
|
18370
18417
|
return {
|
|
18371
18418
|
appUrl: config.appUrl,
|
|
@@ -18610,10 +18657,10 @@ async function whoami() {
|
|
|
18610
18657
|
// src/assets.ts
|
|
18611
18658
|
init_hash();
|
|
18612
18659
|
import { readFileSync as readFileSync2, writeFileSync as writeFileSync3, existsSync as existsSync2, readdirSync } from "node:fs";
|
|
18613
|
-
import { join as join2, resolve } from "node:path";
|
|
18660
|
+
import { join as join2, resolve as resolve2 } from "node:path";
|
|
18614
18661
|
var BATCH = 10;
|
|
18615
18662
|
function imagesDirFor(storeDir) {
|
|
18616
|
-
const dir2 = join2(
|
|
18663
|
+
const dir2 = join2(resolve2(storeDir), "images");
|
|
18617
18664
|
if (!existsSync2(dir2))
|
|
18618
18665
|
throw new Error(`No images/ directory in ${storeDir}`);
|
|
18619
18666
|
return dir2;
|
|
@@ -18947,7 +18994,7 @@ async function workspaceSet(slugOrId) {
|
|
|
18947
18994
|
// src/images.ts
|
|
18948
18995
|
init_hash();
|
|
18949
18996
|
import { readFileSync as readFileSync3, writeFileSync as writeFileSync4, existsSync as existsSync4, rmSync as rmSync2 } from "node:fs";
|
|
18950
|
-
import { join as join4, resolve as
|
|
18997
|
+
import { join as join4, resolve as resolve3 } from "node:path";
|
|
18951
18998
|
var MAX_JOBS_PER_REQUEST = 40;
|
|
18952
18999
|
var POLL_INTERVAL_MS = 5000;
|
|
18953
19000
|
var POLL_TIMEOUT_MS = 30 * 60 * 1000;
|
|
@@ -19112,7 +19159,7 @@ async function streamingGenerate(auth, manifest, missing, imagesDir, indexPath,
|
|
|
19112
19159
|
}
|
|
19113
19160
|
async function imagesGenerate(storeDir) {
|
|
19114
19161
|
const auth = requireActive();
|
|
19115
|
-
const imagesDir = join4(
|
|
19162
|
+
const imagesDir = join4(resolve3(storeDir), "images");
|
|
19116
19163
|
const manifestPath = join4(imagesDir, "manifest.json");
|
|
19117
19164
|
if (!existsSync4(manifestPath)) {
|
|
19118
19165
|
throw new Error(`No images/manifest.json in ${storeDir}`);
|
|
@@ -19155,12 +19202,12 @@ async function imagesGenerate(storeDir) {
|
|
|
19155
19202
|
|
|
19156
19203
|
// src/shopify.ts
|
|
19157
19204
|
import { readFileSync as readFileSync6, existsSync as existsSync7 } from "node:fs";
|
|
19158
|
-
import { basename as basename3, join as join7, resolve as
|
|
19205
|
+
import { basename as basename3, join as join7, resolve as resolve6 } from "node:path";
|
|
19159
19206
|
|
|
19160
19207
|
// src/shop.ts
|
|
19161
19208
|
import { spawn as spawn3, spawnSync as spawnSync3 } from "node:child_process";
|
|
19162
19209
|
import { existsSync as existsSync6, readFileSync as readFileSync5, writeFileSync as writeFileSync6 } from "node:fs";
|
|
19163
|
-
import { basename as basename2, join as join6, resolve as
|
|
19210
|
+
import { basename as basename2, join as join6, resolve as resolve5 } from "node:path";
|
|
19164
19211
|
|
|
19165
19212
|
// src/theme.ts
|
|
19166
19213
|
init_hash();
|
|
@@ -19180,7 +19227,7 @@ import {
|
|
|
19180
19227
|
writeFileSync as writeFileSync5
|
|
19181
19228
|
} from "node:fs";
|
|
19182
19229
|
import { tmpdir } from "node:os";
|
|
19183
|
-
import { basename, dirname, join as join5, resolve as
|
|
19230
|
+
import { basename, dirname as dirname2, join as join5, resolve as resolve4 } from "node:path";
|
|
19184
19231
|
var TEMPLATES_PKG = "@zalify/theme-templates";
|
|
19185
19232
|
var REGISTRY = "https://registry.npmjs.org";
|
|
19186
19233
|
var MANIFEST_PATH = ".zalify/theme.json";
|
|
@@ -19212,7 +19259,7 @@ async function downloadTarball(url) {
|
|
|
19212
19259
|
}
|
|
19213
19260
|
function extractTarball(file2) {
|
|
19214
19261
|
const dir2 = mkdtempSync(join5(tmpdir(), "zalify-theme-x-"));
|
|
19215
|
-
const result = spawnSync2("tar", ["-xzf",
|
|
19262
|
+
const result = spawnSync2("tar", ["-xzf", resolve4(file2), "-C", dir2], {
|
|
19216
19263
|
encoding: "utf8"
|
|
19217
19264
|
});
|
|
19218
19265
|
if (result.error || result.status !== 0) {
|
|
@@ -19280,7 +19327,7 @@ function writeJson(path9, value) {
|
|
|
19280
19327
|
`);
|
|
19281
19328
|
}
|
|
19282
19329
|
async function themeCreate(dir2, opts) {
|
|
19283
|
-
const targetDir =
|
|
19330
|
+
const targetDir = resolve4(dir2);
|
|
19284
19331
|
if (existsSync5(targetDir) && readdirSync2(targetDir).length > 0) {
|
|
19285
19332
|
throw new Error(`${dir2} already exists and is not empty`);
|
|
19286
19333
|
}
|
|
@@ -19364,7 +19411,7 @@ Runs on mock.shop demo data out of the box — edit .env to connect your store.`
|
|
|
19364
19411
|
console.log("Your theme customizations live in theme/ — see theme/README.md.");
|
|
19365
19412
|
}
|
|
19366
19413
|
function themeStatus(dir2 = ".") {
|
|
19367
|
-
const projectDir =
|
|
19414
|
+
const projectDir = resolve4(dir2);
|
|
19368
19415
|
const manifest = readProjectManifest(projectDir);
|
|
19369
19416
|
console.log(`${manifest.template} theme, ${TEMPLATES_PKG}@${manifest.version}` + (manifest.variant === "editor" ? " (editor variant)" : ""));
|
|
19370
19417
|
let clean = 0;
|
|
@@ -19392,7 +19439,7 @@ function looksBinary(...buffers) {
|
|
|
19392
19439
|
return buffers.some((b) => b.subarray(0, 8000).includes(0));
|
|
19393
19440
|
}
|
|
19394
19441
|
async function themeUpgrade(dir2 = ".", opts = {}) {
|
|
19395
|
-
const projectDir =
|
|
19442
|
+
const projectDir = resolve4(dir2);
|
|
19396
19443
|
const local = readProjectManifest(projectDir);
|
|
19397
19444
|
const variant = local.variant ?? "default";
|
|
19398
19445
|
const target = await acquireTemplatePkg(opts.tarball, opts.to);
|
|
@@ -19432,7 +19479,7 @@ async function themeUpgrade(dir2 = ".", opts = {}) {
|
|
|
19432
19479
|
const write = (bytes) => {
|
|
19433
19480
|
if (opts.dryRun)
|
|
19434
19481
|
return;
|
|
19435
|
-
mkdirSync2(
|
|
19482
|
+
mkdirSync2(dirname2(localPath), { recursive: true });
|
|
19436
19483
|
writeFileSync5(localPath, bytes);
|
|
19437
19484
|
};
|
|
19438
19485
|
if (oldHash && newHash) {
|
|
@@ -19656,7 +19703,7 @@ async function pollUntilReady(auth, id) {
|
|
|
19656
19703
|
}
|
|
19657
19704
|
async function shopCreate(dir2, opts) {
|
|
19658
19705
|
const auth = requireActive();
|
|
19659
|
-
const slug = basename2(
|
|
19706
|
+
const slug = basename2(resolve5(dir2)).toLowerCase().replaceAll(/[^a-z0-9-]+/g, "-").replaceAll(/^-+|-+$/g, "") || "site";
|
|
19660
19707
|
console.log(`Provisioning shop "${slug}" (workspace "${auth.workspaceName}")`);
|
|
19661
19708
|
const created = await request(auth, "POST", "/api/sites", {
|
|
19662
19709
|
slug,
|
|
@@ -19677,17 +19724,17 @@ async function shopCreate(dir2, opts) {
|
|
|
19677
19724
|
install: opts.install,
|
|
19678
19725
|
git: opts.git
|
|
19679
19726
|
});
|
|
19680
|
-
writeFileSync6(join6(
|
|
19727
|
+
writeFileSync6(join6(resolve5(dir2), ".zalify", "site.json"), JSON.stringify({ id: siteId, slug: view.slug, domain: view.domain, repo: view.githubRepo }, null, 2) + `
|
|
19681
19728
|
`);
|
|
19682
|
-
writeFileSync6(join6(
|
|
19729
|
+
writeFileSync6(join6(resolve5(dir2), "theme", "pixel.json"), JSON.stringify({ workspaceId: auth.workspaceId }, null, 2) + `
|
|
19683
19730
|
`);
|
|
19684
19731
|
if (opts.git !== false && view.githubRepo) {
|
|
19685
19732
|
const { token, repo } = await request(auth, "POST", `/api/sites/${siteId}/push-token`, {});
|
|
19686
|
-
const run = (args) => spawnSync3("git", args, { cwd:
|
|
19733
|
+
const run = (args) => spawnSync3("git", args, { cwd: resolve5(dir2), stdio: "ignore" });
|
|
19687
19734
|
run(["add", ".zalify/site.json", "theme/pixel.json"]);
|
|
19688
19735
|
run(["commit", "-m", "Link site record", "--no-verify"]);
|
|
19689
19736
|
run(["remote", "add", "origin", `https://github.com/${repo}.git`]);
|
|
19690
|
-
const push = spawnSync3("git", ["push", `https://x-access-token:${token}@github.com/${repo}.git`, "main"], { cwd:
|
|
19737
|
+
const push = spawnSync3("git", ["push", `https://x-access-token:${token}@github.com/${repo}.git`, "main"], { cwd: resolve5(dir2), stdio: "inherit" });
|
|
19691
19738
|
if (push.status !== 0) {
|
|
19692
19739
|
throw new Error(`git push to ${repo} failed — resolve and push manually.`);
|
|
19693
19740
|
}
|
|
@@ -19735,8 +19782,8 @@ async function resolveSite(auth, slugOrDir) {
|
|
|
19735
19782
|
return null;
|
|
19736
19783
|
};
|
|
19737
19784
|
let slug = null;
|
|
19738
|
-
if (slugOrDir && existsSync6(
|
|
19739
|
-
slug = fromDir(
|
|
19785
|
+
if (slugOrDir && existsSync6(resolve5(slugOrDir)))
|
|
19786
|
+
slug = fromDir(resolve5(slugOrDir));
|
|
19740
19787
|
if (!slug && slugOrDir)
|
|
19741
19788
|
slug = slugOrDir;
|
|
19742
19789
|
if (!slug)
|
|
@@ -19796,7 +19843,7 @@ async function maybeRefreshShops(auth, brandDir, siteSlugOverride) {
|
|
|
19796
19843
|
try {
|
|
19797
19844
|
let slug = siteSlugOverride ?? null;
|
|
19798
19845
|
if (!slug) {
|
|
19799
|
-
const storeJson = join6(
|
|
19846
|
+
const storeJson = join6(resolve5(brandDir), "store.json");
|
|
19800
19847
|
if (existsSync6(storeJson)) {
|
|
19801
19848
|
slug = JSON.parse(readFileSync5(storeJson, "utf8")).slug ?? null;
|
|
19802
19849
|
}
|
|
@@ -19881,7 +19928,7 @@ async function findProductId(auth, handle) {
|
|
|
19881
19928
|
}
|
|
19882
19929
|
async function shopifyImport(storeDir, options = {}) {
|
|
19883
19930
|
const auth = requireActive();
|
|
19884
|
-
const dir2 =
|
|
19931
|
+
const dir2 = resolve6(storeDir);
|
|
19885
19932
|
const catalog = readJson(join7(dir2, "catalog.json"), "catalog.json");
|
|
19886
19933
|
const { locations } = await gql(auth, `{ locations(first: 1) { nodes { id name } } }`);
|
|
19887
19934
|
const locationId = locations.nodes[0]?.id;
|
|
@@ -20090,7 +20137,7 @@ async function shopifyImport(storeDir, options = {}) {
|
|
|
20090
20137
|
}
|
|
20091
20138
|
async function shopifyUploadImages(storeDir, options = {}) {
|
|
20092
20139
|
const auth = requireActive();
|
|
20093
|
-
const dir2 =
|
|
20140
|
+
const dir2 = resolve6(storeDir);
|
|
20094
20141
|
const manifest = readJson(join7(dir2, "images", "manifest.json"), "images/manifest.json");
|
|
20095
20142
|
console.log(`Uploading images to the Shopify store connected to workspace "${auth.workspaceName}"`);
|
|
20096
20143
|
for (const entry of manifest.images) {
|
|
@@ -20172,7 +20219,7 @@ async function shopifyUploadImages(storeDir, options = {}) {
|
|
|
20172
20219
|
// src/ads.ts
|
|
20173
20220
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
20174
20221
|
import { existsSync as existsSync8, mkdirSync as mkdirSync3, readdirSync as readdirSync3, writeFileSync as writeFileSync7 } from "node:fs";
|
|
20175
|
-
import { basename as basename4, join as join8, relative, resolve as
|
|
20222
|
+
import { basename as basename4, join as join8, relative, resolve as resolve7 } from "node:path";
|
|
20176
20223
|
import { createInterface } from "node:readline/promises";
|
|
20177
20224
|
function apiError3(status, json) {
|
|
20178
20225
|
if (json.code === "SLUG_TAKEN") {
|
|
@@ -20224,7 +20271,7 @@ async function pollUntilReady2(auth, id) {
|
|
|
20224
20271
|
throw new Error("Provisioning timed out after 5 minutes — check the Temporal UI.");
|
|
20225
20272
|
}
|
|
20226
20273
|
function scaffoldStarter(dir2, slug, workspaceId) {
|
|
20227
|
-
const root =
|
|
20274
|
+
const root = resolve7(dir2);
|
|
20228
20275
|
const write = (rel, content) => {
|
|
20229
20276
|
const abs = join8(root, rel);
|
|
20230
20277
|
mkdirSync3(join8(abs, ".."), { recursive: true });
|
|
@@ -20277,15 +20324,15 @@ mirrors decisions into \`decisions/\` and daily signal digests into
|
|
|
20277
20324
|
`);
|
|
20278
20325
|
}
|
|
20279
20326
|
async function adsCreate(dir2) {
|
|
20280
|
-
const auth = requireActive();
|
|
20281
|
-
const slug = basename4(
|
|
20327
|
+
const auth = requireActive({ global: true });
|
|
20328
|
+
const slug = basename4(resolve7(dir2)).toLowerCase().replaceAll(/[^a-z0-9-]+/g, "-").replaceAll(/^-+|-+$/g, "") || "brand";
|
|
20282
20329
|
console.log(`Provisioning brand instance "${slug}" (workspace "${auth.workspaceName}")`);
|
|
20283
20330
|
const created = await request2(auth, "POST", "/api/repos", { slug });
|
|
20284
20331
|
const view = await pollUntilReady2(auth, created.repoId);
|
|
20285
20332
|
console.log(` ✓ provisioned: ${view.githubRepo}`);
|
|
20286
20333
|
scaffoldStarter(dir2, slug, auth.workspaceId);
|
|
20287
|
-
mkdirSync3(join8(
|
|
20288
|
-
writeFileSync7(join8(
|
|
20334
|
+
mkdirSync3(join8(resolve7(dir2), ".zalify"), { recursive: true });
|
|
20335
|
+
writeFileSync7(join8(resolve7(dir2), ".zalify", "brand-repo.json"), JSON.stringify({
|
|
20289
20336
|
id: created.repoId,
|
|
20290
20337
|
slug: view.slug,
|
|
20291
20338
|
repo: view.githubRepo,
|
|
@@ -20298,12 +20345,12 @@ async function adsCreate(dir2) {
|
|
|
20298
20345
|
`);
|
|
20299
20346
|
if (view.githubRepo) {
|
|
20300
20347
|
const { token, repo } = await request2(auth, "POST", `/api/repos/${created.repoId}/push-token`, {});
|
|
20301
|
-
const run = (args) => spawnSync4("git", args, { cwd:
|
|
20348
|
+
const run = (args) => spawnSync4("git", args, { cwd: resolve7(dir2), stdio: "ignore" });
|
|
20302
20349
|
run(["init", "-b", "main"]);
|
|
20303
20350
|
run(["add", "-A"]);
|
|
20304
20351
|
run(["commit", "-m", "Scaffold brand instance", "--no-verify"]);
|
|
20305
20352
|
run(["remote", "add", "origin", `https://github.com/${repo}.git`]);
|
|
20306
|
-
const push = spawnSync4("git", ["push", `https://x-access-token:${token}@github.com/${repo}.git`, "main"], { cwd:
|
|
20353
|
+
const push = spawnSync4("git", ["push", `https://x-access-token:${token}@github.com/${repo}.git`, "main"], { cwd: resolve7(dir2), stdio: "inherit" });
|
|
20307
20354
|
if (push.status !== 0) {
|
|
20308
20355
|
throw new Error(`git push to ${repo} failed — resolve and push manually.`);
|
|
20309
20356
|
}
|
|
@@ -20320,7 +20367,7 @@ Next steps:
|
|
|
20320
20367
|
}
|
|
20321
20368
|
var CAMPAIGN_NAME_RE = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;
|
|
20322
20369
|
function campaignParent(account) {
|
|
20323
|
-
const cwd =
|
|
20370
|
+
const cwd = resolve7(".");
|
|
20324
20371
|
const inCheckout = existsSync8(join8(cwd, ".zalify", "brand-repo.json")) || existsSync8(join8(cwd, "accounts"));
|
|
20325
20372
|
if (!inCheckout) {
|
|
20326
20373
|
throw new Error("Not inside a brand-instance checkout — run from the repo `zalify ads create` made.");
|
|
@@ -20378,7 +20425,7 @@ ad_sets:
|
|
|
20378
20425
|
age: 18-65
|
|
20379
20426
|
advantage: true
|
|
20380
20427
|
`);
|
|
20381
|
-
console.log(`✓ ${relative(
|
|
20428
|
+
console.log(`✓ ${relative(resolve7("."), dir2)}/ is ready`);
|
|
20382
20429
|
console.log(" 1. drag images into creatives/");
|
|
20383
20430
|
console.log(" 2. fill primary_text and link in campaign.yaml");
|
|
20384
20431
|
console.log(" 3. `zalify ads sync` when it lands — validate, diff, apply");
|
|
@@ -20417,7 +20464,7 @@ import {
|
|
|
20417
20464
|
readFileSync as readFileSync8,
|
|
20418
20465
|
writeFileSync as writeFileSync9
|
|
20419
20466
|
} from "node:fs";
|
|
20420
|
-
import { join as join10, resolve as
|
|
20467
|
+
import { join as join10, resolve as resolve8 } from "node:path";
|
|
20421
20468
|
import { createInterface as createInterface2 } from "node:readline/promises";
|
|
20422
20469
|
|
|
20423
20470
|
// node_modules/yaml/dist/index.js
|
|
@@ -20579,7 +20626,7 @@ async function adsCreativeGenerate(opts) {
|
|
|
20579
20626
|
|
|
20580
20627
|
// src/ads-diff.ts
|
|
20581
20628
|
function root() {
|
|
20582
|
-
const cwd =
|
|
20629
|
+
const cwd = resolve8(".");
|
|
20583
20630
|
if (existsSync10(join10(cwd, ".zalify", "brand-repo.json")) || existsSync10(join10(cwd, "campaigns"))) {
|
|
20584
20631
|
return cwd;
|
|
20585
20632
|
}
|
|
@@ -20748,10 +20795,10 @@ import {
|
|
|
20748
20795
|
readFileSync as readFileSync9,
|
|
20749
20796
|
writeFileSync as writeFileSync10
|
|
20750
20797
|
} from "node:fs";
|
|
20751
|
-
import { dirname as
|
|
20798
|
+
import { dirname as dirname3, join as join11, resolve as resolve9 } from "node:path";
|
|
20752
20799
|
var sha = (s) => createHash2("sha256").update(s).digest("hex");
|
|
20753
20800
|
function checkoutRoot() {
|
|
20754
|
-
const cwd =
|
|
20801
|
+
const cwd = resolve9(".");
|
|
20755
20802
|
if (existsSync11(join11(cwd, ".zalify", "brand-repo.json")) || existsSync11(join11(cwd, "accounts")) || existsSync11(join11(cwd, "campaigns"))) {
|
|
20756
20803
|
return cwd;
|
|
20757
20804
|
}
|
|
@@ -20823,7 +20870,7 @@ async function adsPull(opts) {
|
|
|
20823
20870
|
continue;
|
|
20824
20871
|
}
|
|
20825
20872
|
}
|
|
20826
|
-
mkdirSync5(
|
|
20873
|
+
mkdirSync5(dirname3(abs), { recursive: true });
|
|
20827
20874
|
writeFileSync10(abs, f.yaml);
|
|
20828
20875
|
bindings.pulled[f.path] = nextHash;
|
|
20829
20876
|
written += 1;
|
|
@@ -20837,7 +20884,7 @@ async function adsPull(opts) {
|
|
|
20837
20884
|
bindings.nodes[key] = v;
|
|
20838
20885
|
}
|
|
20839
20886
|
const bindingsPath = join11(root2, "accounts", ".bindings.json");
|
|
20840
|
-
mkdirSync5(
|
|
20887
|
+
mkdirSync5(dirname3(bindingsPath), { recursive: true });
|
|
20841
20888
|
writeFileSync10(bindingsPath, `${JSON.stringify(bindings, null, 2)}
|
|
20842
20889
|
`);
|
|
20843
20890
|
const exported = new Set(result.files.map((f) => f.path));
|
|
@@ -20863,7 +20910,7 @@ Review with git diff; commit when it reads right.`);
|
|
|
20863
20910
|
// src/ads-read.ts
|
|
20864
20911
|
import { spawn as spawn4 } from "node:child_process";
|
|
20865
20912
|
import { existsSync as existsSync12, readFileSync as readFileSync10 } from "node:fs";
|
|
20866
|
-
import { join as join12, resolve as
|
|
20913
|
+
import { join as join12, resolve as resolve10 } from "node:path";
|
|
20867
20914
|
async function serviceGet(auth, path9) {
|
|
20868
20915
|
const res = await fetch(`${auth.appUrl}/api/autopilot/${path9}`, {
|
|
20869
20916
|
headers: {
|
|
@@ -20951,7 +20998,7 @@ account changes: not tracked for this platform yet` : `
|
|
|
20951
20998
|
account changes: ${a.byPerson} by people, ${a.byMeta} automated`);
|
|
20952
20999
|
}
|
|
20953
21000
|
function adsDigest(dir2) {
|
|
20954
|
-
const root2 =
|
|
21001
|
+
const root2 = resolve10(dir2 ?? ".");
|
|
20955
21002
|
const path9 = join12(root2, "signals", "latest.json");
|
|
20956
21003
|
if (!existsSync12(path9)) {
|
|
20957
21004
|
throw new Error("signals/latest.json not found — run from a brand-instance checkout " + "(and pull: the service commits a digest daily).");
|
|
@@ -20995,7 +21042,7 @@ function adsOpen() {
|
|
|
20995
21042
|
}
|
|
20996
21043
|
async function adsDoctor(dir2) {
|
|
20997
21044
|
const auth = requireActive();
|
|
20998
|
-
const root2 =
|
|
21045
|
+
const root2 = resolve10(dir2 ?? ".");
|
|
20999
21046
|
let failed = 0;
|
|
21000
21047
|
const ok = (msg) => console.log(` ✓ ${msg}`);
|
|
21001
21048
|
const bad = (msg) => {
|
|
@@ -21081,7 +21128,7 @@ ${failed} problem${failed > 1 ? "s" : ""}.`);
|
|
|
21081
21128
|
|
|
21082
21129
|
// src/brand.ts
|
|
21083
21130
|
import { existsSync as existsSync13, mkdirSync as mkdirSync6, readdirSync as readdirSync6, readFileSync as readFileSync11, writeFileSync as writeFileSync11 } from "node:fs";
|
|
21084
|
-
import { basename as basename5, join as join13, resolve as
|
|
21131
|
+
import { basename as basename5, join as join13, resolve as resolve11 } from "node:path";
|
|
21085
21132
|
var AUTHORING_MD = `# Brand authoring guide
|
|
21086
21133
|
|
|
21087
21134
|
The rules for filling in this folder. An author — human or AI agent —
|
|
@@ -21382,7 +21429,7 @@ var MANIFEST_JSON = JSON.stringify({
|
|
|
21382
21429
|
}, null, 2) + `
|
|
21383
21430
|
`;
|
|
21384
21431
|
function brandInit(dir2 = ".", opts = {}) {
|
|
21385
|
-
const target =
|
|
21432
|
+
const target = resolve11(dir2);
|
|
21386
21433
|
const slug = basename5(target).toLowerCase().replaceAll(/[^a-z0-9-]+/g, "-").replaceAll(/^-+|-+$/g, "");
|
|
21387
21434
|
if (existsSync13(target) && readdirSync6(target).length > 0) {
|
|
21388
21435
|
throw new Error(`${dir2} already exists and is not empty`);
|
|
@@ -21405,7 +21452,7 @@ Author in this order: brand.md → catalog.json → images/manifest.json` + `
|
|
|
21405
21452
|
}
|
|
21406
21453
|
var MANIFEST_SIZES = new Set(["1024x1024", "1536x1024", "1024x1536"]);
|
|
21407
21454
|
function brandValidate(dir2 = ".") {
|
|
21408
|
-
const target =
|
|
21455
|
+
const target = resolve11(dir2);
|
|
21409
21456
|
const problems = [];
|
|
21410
21457
|
const warnings = [];
|
|
21411
21458
|
const readJson2 = (rel) => {
|
|
@@ -21595,7 +21642,7 @@ function brandValidate(dir2 = ".") {
|
|
|
21595
21642
|
}
|
|
21596
21643
|
|
|
21597
21644
|
// src/cli.ts
|
|
21598
|
-
var __dirname4 =
|
|
21645
|
+
var __dirname4 = dirname4(fileURLToPath3(import.meta.url));
|
|
21599
21646
|
var require2 = createRequire2(import.meta.url);
|
|
21600
21647
|
var pkg = require2(join14(__dirname4, "..", "package.json"));
|
|
21601
21648
|
try {
|