@zalify/cli 0.24.0 → 0.25.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.
Files changed (2) hide show
  1. package/dist/cli.js +65 -5
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -18316,6 +18316,33 @@ function writeConfig(config) {
18316
18316
  function deleteConfig() {
18317
18317
  rmSync(file, { force: true });
18318
18318
  }
18319
+ function enforceWorkspaceLink(root, auth) {
18320
+ const linkPath = join(root, ".zalify", "brand-repo.json");
18321
+ if (!existsSync(linkPath))
18322
+ return;
18323
+ let link;
18324
+ try {
18325
+ link = JSON.parse(readFileSync(linkPath, "utf8"));
18326
+ } catch {
18327
+ return;
18328
+ }
18329
+ const ws = link.workspace;
18330
+ if (!ws?.id) {
18331
+ link.workspace = {
18332
+ id: auth.workspaceId,
18333
+ name: auth.workspaceName,
18334
+ slug: auth.workspaceSlug
18335
+ };
18336
+ writeFileSync2(linkPath, `${JSON.stringify(link, null, 2)}
18337
+ `);
18338
+ console.log(`stamped workspace "${auth.workspaceSlug}" into .zalify/brand-repo.json — commit it.`);
18339
+ return;
18340
+ }
18341
+ if (ws.id !== auth.workspaceId) {
18342
+ throw new Error(`This checkout belongs to workspace "${ws.name ?? ws.slug ?? ws.id}" ` + `but the active workspace is "${auth.workspaceName}" (${auth.workspaceSlug}).
18343
+ ` + `Run \`zalify workspace set ${ws.slug ?? ws.id}\` first.`);
18344
+ }
18345
+ }
18319
18346
  function requireActive() {
18320
18347
  const config = readConfig();
18321
18348
  if (!config) {
@@ -20258,7 +20285,16 @@ async function adsCreate(dir2) {
20258
20285
  console.log(` ✓ provisioned: ${view.githubRepo}`);
20259
20286
  scaffoldStarter(dir2, slug, auth.workspaceId);
20260
20287
  mkdirSync3(join8(resolve6(dir2), ".zalify"), { recursive: true });
20261
- writeFileSync7(join8(resolve6(dir2), ".zalify", "brand-repo.json"), JSON.stringify({ id: created.repoId, slug: view.slug, repo: view.githubRepo }, null, 2) + `
20288
+ writeFileSync7(join8(resolve6(dir2), ".zalify", "brand-repo.json"), JSON.stringify({
20289
+ id: created.repoId,
20290
+ slug: view.slug,
20291
+ repo: view.githubRepo,
20292
+ workspace: {
20293
+ id: auth.workspaceId,
20294
+ name: auth.workspaceName,
20295
+ slug: auth.workspaceSlug
20296
+ }
20297
+ }, null, 2) + `
20262
20298
  `);
20263
20299
  if (view.githubRepo) {
20264
20300
  const { token, repo } = await request2(auth, "POST", `/api/repos/${created.repoId}/push-token`, {});
@@ -20568,7 +20604,9 @@ async function collect(base) {
20568
20604
  }
20569
20605
  }
20570
20606
  for (const rel of campaignDirs(base)) {
20571
- files.push(await collectFolder(base, rel));
20607
+ const payload = await collectFolder(base, rel);
20608
+ const imported = typeof payload.doc === "object" && payload.doc !== null && payload.doc.imported === true;
20609
+ files.push(imported ? { path: payload.path, doc: payload.doc } : payload);
20572
20610
  }
20573
20611
  return { files };
20574
20612
  }
@@ -20628,6 +20666,7 @@ ${s.creates} to create, ${s.updates} to update, ${s.unchanged} unchanged` + `${r
20628
20666
  async function adsDiff() {
20629
20667
  const auth = requireActive();
20630
20668
  const base = root();
20669
+ enforceWorkspaceLink(base, auth);
20631
20670
  const { files } = await collect(base);
20632
20671
  if (files.length === 0) {
20633
20672
  console.log("No campaign files — `zalify ads pull` or `zalify ads new` first.");
@@ -20645,6 +20684,7 @@ async function adsDiff() {
20645
20684
  async function adsApply(opts) {
20646
20685
  const auth = requireActive();
20647
20686
  const base = root();
20687
+ enforceWorkspaceLink(base, auth);
20648
20688
  const { files } = await collect(base);
20649
20689
  if (files.length === 0) {
20650
20690
  console.log("No campaign files — `zalify ads pull` or `zalify ads new` first.");
@@ -20732,6 +20772,7 @@ function readBindings(root2) {
20732
20772
  async function adsPull(opts) {
20733
20773
  const auth = requireActive();
20734
20774
  const root2 = checkoutRoot();
20775
+ enforceWorkspaceLink(root2, auth);
20735
20776
  const params = new URLSearchParams;
20736
20777
  if (opts.account)
20737
20778
  params.set("account", opts.account);
@@ -20750,10 +20791,22 @@ async function adsPull(opts) {
20750
20791
  }
20751
20792
  const result = await res.json();
20752
20793
  const bindings = readBindings(root2);
20794
+ const ownedElsewhere = new Map;
20795
+ for (const [key, v] of Object.entries(bindings.nodes)) {
20796
+ if (v.kind === "campaign")
20797
+ ownedElsewhere.set(v.id, key.split("#")[0]);
20798
+ }
20753
20799
  let written = 0;
20754
20800
  let unchanged = 0;
20801
+ let owned = 0;
20755
20802
  const skipped = [];
20756
20803
  for (const f of result.files) {
20804
+ const campaignId = result.bindings[`${f.path}#campaign`]?.id;
20805
+ const owner = campaignId ? ownedElsewhere.get(campaignId) : undefined;
20806
+ if (owner && owner !== f.path) {
20807
+ owned += 1;
20808
+ continue;
20809
+ }
20757
20810
  const abs = join11(root2, f.path);
20758
20811
  const nextHash = sha(f.yaml);
20759
20812
  const lastPulled = bindings.pulled[f.path];
@@ -20764,7 +20817,7 @@ async function adsPull(opts) {
20764
20817
  bindings.pulled[f.path] = nextHash;
20765
20818
  continue;
20766
20819
  }
20767
- const locallyEdited = lastPulled !== undefined && sha(current) !== lastPulled;
20820
+ const locallyEdited = lastPulled === undefined || sha(current) !== lastPulled;
20768
20821
  if (locallyEdited && !opts.force) {
20769
20822
  skipped.push(f.path);
20770
20823
  continue;
@@ -20775,7 +20828,14 @@ async function adsPull(opts) {
20775
20828
  bindings.pulled[f.path] = nextHash;
20776
20829
  written += 1;
20777
20830
  }
20778
- Object.assign(bindings.nodes, result.bindings);
20831
+ for (const [key, v] of Object.entries(result.bindings)) {
20832
+ const file2 = key.split("#")[0];
20833
+ const campaignId = result.bindings[`${file2}#campaign`]?.id;
20834
+ const owner = campaignId ? ownedElsewhere.get(campaignId) : undefined;
20835
+ if (owner && owner !== file2)
20836
+ continue;
20837
+ bindings.nodes[key] = v;
20838
+ }
20779
20839
  const bindingsPath = join11(root2, "accounts", ".bindings.json");
20780
20840
  mkdirSync5(dirname2(bindingsPath), { recursive: true });
20781
20841
  writeFileSync10(bindingsPath, `${JSON.stringify(bindings, null, 2)}
@@ -20783,7 +20843,7 @@ async function adsPull(opts) {
20783
20843
  const exported = new Set(result.files.map((f) => f.path));
20784
20844
  const gone = Object.keys(bindings.pulled).filter((p) => !exported.has(p) && existsSync11(join11(root2, p)));
20785
20845
  const s = result.summary;
20786
- console.log(`pulled ${s.campaigns} campaigns (${s.adSets} ad sets, ${s.ads} ads): ` + `${written} written, ${unchanged} unchanged, ${skipped.length} kept (locally edited)`);
20846
+ console.log(`pulled ${s.campaigns} campaigns (${s.adSets} ad sets, ${s.ads} ads): ` + `${written} written, ${unchanged} unchanged, ${skipped.length} kept (locally edited)` + `${owned ? `, ${owned} owned by authored files` : ""}`);
20787
20847
  for (const p of skipped)
20788
20848
  console.log(` kept ${p} (edited — --force overwrites)`);
20789
20849
  if (gone.length > 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zalify/cli",
3
- "version": "0.24.0",
3
+ "version": "0.25.0",
4
4
  "description": "Zalify CLI - command-line interface for Zalify",
5
5
  "type": "module",
6
6
  "main": "dist/cli.js",