@brightsideoy/kama 1.0.0-alpha.7 → 1.0.0-alpha.8

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/dist/index.js CHANGED
@@ -23369,7 +23369,7 @@ async function px(e) {
23369
23369
  } catch (t) {
23370
23370
  console.error(`[Route Generator] Failed to parse channel ${e.id} dataJson:`, t);
23371
23371
  }
23372
- let i = await e.prepare("SELECT id, slug FROM content_nodes WHERE (deletedAt IS NULL OR deletedAt = '')").all(), a = Array.isArray(i) ? i : i?.results || [], o = /* @__PURE__ */ new Map();
23372
+ let i = await e.prepare("SELECT id, slug FROM content_nodes WHERE status = 'published' AND (deletedAt IS NULL OR deletedAt = '')").all(), a = Array.isArray(i) ? i : i?.results || [], o = /* @__PURE__ */ new Map();
23373
23373
  for (let e of a) e.slug && o.set(Number(e.id), String(e.slug).replace(/^\/+|\/+$/g, ""));
23374
23374
  let s = await e.prepare("SELECT channelId, treeId FROM channel_trees").all(), c = Array.isArray(s) ? s : s?.results || [], l = await e.prepare("SELECT treeId, contentId, parentId, sortOrder FROM tree_nodes ORDER BY sortOrder ASC").all(), u = Array.isArray(l) ? l : l?.results || [], d = await e.prepare("SELECT nodeId, channelId FROM node_channels").all(), f = Array.isArray(d) ? d : d?.results || [], p = /* @__PURE__ */ new Map(), m = /* @__PURE__ */ new Set();
23375
23375
  for (let e of n) {
@@ -23809,34 +23809,41 @@ mx.get("/", async (e) => {
23809
23809
  }
23810
23810
  }
23811
23811
  if (a) {
23812
- let e = await t.prepare("SELECT title, slug, language, contentType, isHidden, draftDataJson, dataJson, publishedAt, status, hasUnpublishedChanges FROM content_nodes WHERE id = ?").get(a);
23812
+ let e = await t.prepare("SELECT title, slug, language, contentType, isHidden, draftDataJson, dataJson, publishedAt, status, hasUnpublishedChanges FROM content_nodes WHERE id = ?").get(a), n = o === void 0 ? e?.title || "Untitled" : o, r = A ?? e?.slug ?? null, i = S || e?.contentType || "page", l = c === void 0 ? e?.language ?? null : w, u = x === void 0 ? vx(e?.isHidden) : x;
23813
23813
  ne = Sx(e, {
23814
- title: o,
23815
- slug: A,
23816
- isHidden: x,
23814
+ title: n,
23815
+ slug: r,
23816
+ isHidden: u,
23817
23817
  sanitizedFields: v
23818
23818
  });
23819
- let n = e?.draftDataJson || e?.dataJson || "{}";
23819
+ let d = e?.draftDataJson || e?.dataJson || "{}";
23820
23820
  try {
23821
- xx(typeof n == "string" ? JSON.parse(n) : n, te);
23821
+ xx(typeof d == "string" ? JSON.parse(d) : d, te);
23822
23822
  } catch {}
23823
- let r = {};
23823
+ let f = {};
23824
23824
  try {
23825
- r = JSON.parse(n);
23825
+ f = JSON.parse(d);
23826
23826
  } catch {}
23827
- let i = JSON.stringify({
23828
- ...r,
23827
+ let p = {
23828
+ title: n,
23829
+ slug: r,
23830
+ contentType: i,
23831
+ language: l,
23832
+ isHidden: u,
23829
23833
  ...v
23830
- }), l = !1;
23831
- if (o !== void 0 && o.trim() !== (e?.title || "Untitled") && (l = !0), s !== void 0 && A !== e?.slug && (l = !0), c !== void 0 && w !== e?.language && (l = !0), !l && Object.keys(v).length > 0) {
23832
- for (let e of Object.keys(v)) if (JSON.stringify(v[e]) !== JSON.stringify(r[e])) {
23833
- l = !0;
23834
+ }, h = JSON.stringify({
23835
+ ...f,
23836
+ ...p
23837
+ }), g = !1;
23838
+ if (o !== void 0 && o.trim() !== (e?.title || "Untitled") && (g = !0), s !== void 0 && A !== e?.slug && (g = !0), c !== void 0 && w !== e?.language && (g = !0), !g && Object.keys(v).length > 0) {
23839
+ for (let e of Object.keys(v)) if (JSON.stringify(v[e]) !== JSON.stringify(f[e])) {
23840
+ g = !0;
23834
23841
  break;
23835
23842
  }
23836
23843
  }
23837
- if (!l && m !== void 0) {
23844
+ if (!g && m !== void 0) {
23838
23845
  let e = await t.prepare("SELECT region, elementType, dataJson FROM content_blocks WHERE contentId = ? AND isDraft = 1 ORDER BY sortOrder ASC").all(a), n = Array.isArray(e) ? e : e?.results || [];
23839
- if (m.length !== n.length) l = !0;
23846
+ if (m.length !== n.length) g = !0;
23840
23847
  else for (let e = 0; e < m.length; e++) {
23841
23848
  let t = m[e], r = n[e], i = t.componentId || t.elementType || "text-block", a = t.region || "content", o = { ...t.data || {} };
23842
23849
  delete o._instanceId, delete o.blockId;
@@ -23845,19 +23852,27 @@ mx.get("/", async (e) => {
23845
23852
  s = JSON.parse(r.dataJson);
23846
23853
  } catch {}
23847
23854
  if (delete s._instanceId, delete s.blockId, i !== r.elementType || a !== r.region || JSON.stringify(o) !== JSON.stringify(s)) {
23848
- l = !0;
23855
+ g = !0;
23849
23856
  break;
23850
23857
  }
23851
23858
  }
23852
23859
  }
23853
- let u = o === void 0 ? e?.title || "Untitled" : o, d = A ?? e?.slug ?? null, f = S || e?.contentType || "page", p = c === void 0 ? e?.language : w;
23854
23860
  O = e?.status === "published" || e?.publishedAt ? "published" : "draft";
23855
- let h = e?.hasUnpublishedChanges === 1 || e?.hasUnpublishedChanges === !0;
23856
- k = l ? 1 : +!!h, await t.prepare("\n UPDATE content_nodes \n SET title = ?, slug = ?, language = ?, contentType = ?, isHidden = ?, status = ?, draftDataJson = ?, hasUnpublishedChanges = ?, updatedById = ?, updatedAt = CURRENT_TIMESTAMP\n WHERE id = ?\n ").run(u, d, p, f, x, O, i, k, C, a);
23861
+ let _ = e?.hasUnpublishedChanges === 1 || e?.hasUnpublishedChanges === !0;
23862
+ k = g ? 1 : +!!_;
23863
+ let y = e?.publishedAt != null || e?.status === "published", b = y ? e.title : n, T = y ? e.slug : r, ee = y ? e.contentType : i, E = y ? e.language : l, D = y ? e.isHidden : u;
23864
+ await t.prepare("\n UPDATE content_nodes \n SET title = ?, slug = ?, language = ?, contentType = ?, isHidden = ?, status = ?, draftDataJson = ?, hasUnpublishedChanges = ?, updatedById = ?, updatedAt = CURRENT_TIMESTAMP\n WHERE id = ?\n ").run(b, T, E, ee, D, O, h, k, C, a);
23857
23865
  } else {
23858
23866
  ne = !0;
23859
- let e = await t.prepare("\n INSERT INTO content_nodes (contentType, title, slug, language, isHidden, status, draftDataJson, dataJson, hasUnpublishedChanges, createdById, updatedById)\n VALUES (?, ?, ?, ?, ?, 'draft', ?, NULL, 0, ?, ?)\n ").run(S, o || "Untitled", A, w, x, JSON.stringify(v), C, C);
23860
- D = Number(e.lastInsertRowid);
23867
+ let e = {
23868
+ title: o || "Untitled",
23869
+ slug: A,
23870
+ contentType: S,
23871
+ language: w,
23872
+ isHidden: x,
23873
+ ...v
23874
+ }, n = await t.prepare("\n INSERT INTO content_nodes (contentType, title, slug, language, isHidden, status, draftDataJson, dataJson, hasUnpublishedChanges, createdById, updatedById)\n VALUES (?, ?, ?, ?, ?, 'draft', ?, NULL, 0, ?, ?)\n ").run(S, o || "Untitled", A, w, x, JSON.stringify(e), C, C);
23875
+ D = Number(n.lastInsertRowid);
23861
23876
  }
23862
23877
  if (h !== void 0 && Array.isArray(h) && D) {
23863
23878
  await t.prepare("DELETE FROM node_channels WHERE nodeId = ?").run(D);
@@ -23903,7 +23918,7 @@ mx.get("/", async (e) => {
23903
23918
  await Cx(t, n, a);
23904
23919
  }
23905
23920
  }
23906
- return await $b(e).clear(), ne && await px(t), e.json({
23921
+ return await $b(e).clear(), e.json({
23907
23922
  success: !0,
23908
23923
  id: D,
23909
23924
  status: O,
@@ -23923,46 +23938,97 @@ mx.get("/", async (e) => {
23923
23938
  try {
23924
23939
  c = typeof o.draftDataJson == "string" ? JSON.parse(o.draftDataJson) : o.draftDataJson || {};
23925
23940
  } catch {}
23926
- let l = (s.title ?? o.title ?? "").trim(), u = (c.title ?? n.title ?? o.title ?? "").trim(), d = (s.slug ?? o.slug ?? "").trim(), f = (c.slug ?? n.slug ?? o.slug ?? "").trim(), p = (s.menuTitle ?? "").trim(), m = (c.menuTitle ?? "").trim(), h = l !== "" && u !== "" && l !== u || d !== "" && f !== "" && d !== f || p !== "" && m !== "" && p !== m, g = o.draftDataJson || o.dataJson || "{}";
23927
- await t.prepare("\n UPDATE content_nodes\n SET publishedDataJson = ?, dataJson = ?, publishedAt = CURRENT_TIMESTAMP, status = 'published', hasUnpublishedChanges = 0, updatedById = ?, updatedAt = CURRENT_TIMESTAMP\n WHERE id = ?\n ").run(g, g, a, i), await t.prepare("DELETE FROM content_blocks WHERE contentId = ? AND isDraft = 0").run(i);
23928
- let _ = await t.prepare("SELECT * FROM content_blocks WHERE contentId = ? AND isDraft = 1 ORDER BY sortOrder ASC").all(i), v = Array.isArray(_) ? _ : _?.results || [];
23929
- if (v.length > 0) {
23941
+ let l = (s.title ?? o.title ?? "").trim(), u = (c.title ?? n.title ?? o.title ?? "").trim(), d = (s.slug ?? o.slug ?? "").trim(), f = (c.slug ?? n.slug ?? o.slug ?? "").trim(), p = (s.menuTitle ?? "").trim(), m = (c.menuTitle ?? "").trim(), h = l !== "" && u !== "" && l !== u || d !== "" && f !== "" && d !== f || p !== "" && m !== "" && p !== m, g = o.draftDataJson || o.dataJson || "{}", _ = c.title ?? n.title ?? o.title ?? "Untitled", v = c.slug ?? n.slug ?? o.slug ?? null, y = c.language === void 0 ? o.language : c.language, b = c.contentType ?? o.contentType ?? "page", x = c.isHidden === void 0 ? o.isHidden : c.isHidden;
23942
+ await t.prepare("\n UPDATE content_nodes\n SET title = ?, slug = ?, language = ?, contentType = ?, isHidden = ?, publishedDataJson = ?, dataJson = ?, publishedAt = CURRENT_TIMESTAMP, status = 'published', hasUnpublishedChanges = 0, updatedById = ?, updatedAt = CURRENT_TIMESTAMP\n WHERE id = ?\n ").run(_, v, y, b, x, g, g, a, i), await t.prepare("DELETE FROM content_blocks WHERE contentId = ? AND isDraft = 0").run(i);
23943
+ let S = await t.prepare("SELECT * FROM content_blocks WHERE contentId = ? AND isDraft = 1 ORDER BY sortOrder ASC").all(i), C = Array.isArray(S) ? S : S?.results || [];
23944
+ if (C.length > 0) {
23930
23945
  let e = [], n = [];
23931
- for (let t of v) {
23946
+ for (let t of C) {
23932
23947
  let r = t.region !== void 0 && t.region !== null && String(t.region).trim() !== "" ? String(t.region) : "content";
23933
23948
  e.push("(?, ?, ?, ?, ?, 0)"), n.push(i, t.sortOrder, t.elementType, t.dataJson, r);
23934
23949
  }
23935
23950
  await t.prepare(`INSERT INTO content_blocks (contentId, sortOrder, elementType, dataJson, region, isDraft) VALUES ${e.join(", ")}`).run(...n);
23936
23951
  }
23937
- let y = ((await t.prepare("SELECT COUNT(*) as count FROM node_revisions WHERE nodeId = ?").get(i))?.count || 0) + 1, b = {
23938
- version: y,
23952
+ let w = ((await t.prepare("SELECT COUNT(*) as count FROM node_revisions WHERE nodeId = ?").get(i))?.count || 0) + 1, T = {
23953
+ version: w,
23939
23954
  publishedAt: (/* @__PURE__ */ new Date()).toISOString(),
23940
23955
  node: {
23941
23956
  ...o,
23942
23957
  dataJson: g
23943
23958
  },
23944
- blocks: v
23959
+ blocks: C
23945
23960
  };
23946
- return await t.prepare("INSERT INTO node_revisions (nodeId, version, snapshotJson, createdById) VALUES (?, ?, ?, ?)").run(i, y, JSON.stringify(b), a), await $b(e).clear(), new fx(e.env).purgeNode(e, t, i, h), h && await px(t), e.json({
23961
+ return await t.prepare("INSERT INTO node_revisions (nodeId, version, snapshotJson, createdById) VALUES (?, ?, ?, ?)").run(i, w, JSON.stringify(T), a), await $b(e).clear(), h && await px(t), new fx(e.env).purgeNode(e, t, i, h), e.json({
23947
23962
  success: !0,
23948
23963
  id: i,
23949
23964
  status: "published",
23950
- version: y,
23951
- publishedAt: b.publishedAt,
23965
+ version: w,
23966
+ publishedAt: T.publishedAt,
23952
23967
  hasUnpublishedChanges: !1,
23953
23968
  isStructuralChange: h
23954
23969
  });
23970
+ }), mx.post("/publish/batch", async (e) => {
23971
+ let t = e.get("db"), n = await e.req.json(), r = n.ids;
23972
+ if (!Array.isArray(r) || r.length === 0) return e.json({ error: "Array of Node IDs required" }, 400);
23973
+ let i = e.get("user")?.id || null, a = !1, o = [];
23974
+ for (let e of r) {
23975
+ let r = Number(e);
23976
+ if (isNaN(r)) continue;
23977
+ let s = await t.prepare("SELECT * FROM content_nodes WHERE id = ?").get(r);
23978
+ if (!s) continue;
23979
+ let c = {};
23980
+ try {
23981
+ c = typeof s.publishedDataJson == "string" ? JSON.parse(s.publishedDataJson) : s.publishedDataJson || {};
23982
+ } catch {}
23983
+ let l = {};
23984
+ try {
23985
+ l = typeof s.draftDataJson == "string" ? JSON.parse(s.draftDataJson) : s.draftDataJson || {};
23986
+ } catch {}
23987
+ let u = (c.title ?? s.title ?? "").trim(), d = (l.title ?? n.title ?? s.title ?? "").trim(), f = (c.slug ?? s.slug ?? "").trim(), p = (l.slug ?? n.slug ?? s.slug ?? "").trim(), m = (c.menuTitle ?? "").trim(), h = (l.menuTitle ?? "").trim();
23988
+ (u !== "" && d !== "" && u !== d || f !== "" && p !== "" && f !== p || m !== "" && h !== "" && m !== h) && (a = !0);
23989
+ let g = s.draftDataJson || s.dataJson || "{}", _ = l.title ?? n.title ?? s.title ?? "Untitled", v = l.slug ?? n.slug ?? s.slug ?? null, y = l.language === void 0 ? s.language : l.language, b = l.contentType ?? s.contentType ?? "page", x = l.isHidden === void 0 ? s.isHidden : l.isHidden;
23990
+ await t.prepare("\n UPDATE content_nodes\n SET title = ?, slug = ?, language = ?, contentType = ?, isHidden = ?, publishedDataJson = ?, dataJson = ?, publishedAt = CURRENT_TIMESTAMP, status = 'published', hasUnpublishedChanges = 0, updatedById = ?, updatedAt = CURRENT_TIMESTAMP\n WHERE id = ?\n ").run(_, v, y, b, x, g, g, i, r), await t.prepare("DELETE FROM content_blocks WHERE contentId = ? AND isDraft = 0").run(r);
23991
+ let S = await t.prepare("SELECT * FROM content_blocks WHERE contentId = ? AND isDraft = 1 ORDER BY sortOrder ASC").all(r), C = Array.isArray(S) ? S : S?.results || [];
23992
+ if (C.length > 0) {
23993
+ let e = [], n = [];
23994
+ for (let t of C) {
23995
+ let i = t.region !== void 0 && t.region !== null && String(t.region).trim() !== "" ? String(t.region) : "content";
23996
+ e.push("(?, ?, ?, ?, ?, 0)"), n.push(r, t.sortOrder, t.elementType, t.dataJson, i);
23997
+ }
23998
+ await t.prepare(`INSERT INTO content_blocks (contentId, sortOrder, elementType, dataJson, region, isDraft) VALUES ${e.join(", ")}`).run(...n);
23999
+ }
24000
+ let w = ((await t.prepare("SELECT COUNT(*) as count FROM node_revisions WHERE nodeId = ?").get(r))?.count || 0) + 1, T = {
24001
+ version: w,
24002
+ publishedAt: (/* @__PURE__ */ new Date()).toISOString(),
24003
+ node: {
24004
+ ...s,
24005
+ dataJson: g
24006
+ },
24007
+ blocks: C
24008
+ };
24009
+ await t.prepare("INSERT INTO node_revisions (nodeId, version, snapshotJson, createdById) VALUES (?, ?, ?, ?)").run(r, w, JSON.stringify(T), i), o.push(r);
24010
+ }
24011
+ await $b(e).clear();
24012
+ let s = new fx(e.env);
24013
+ if (a) await px(t), s.purgeGlobalCache(e, t);
24014
+ else for (let n of o) s.purgeNode(e, t, n, !1);
24015
+ return e.json({
24016
+ success: !0,
24017
+ publishedCount: o.length,
24018
+ publishedIds: o,
24019
+ isStructuralChange: a
24020
+ });
23955
24021
  }), mx.delete("/", async (e) => {
23956
24022
  let t = e.get("db"), n = e.req.query("id");
23957
24023
  if (!n) return e.json({ error: "Node ID required" }, 400);
23958
24024
  let r = Number(n);
23959
- return await t.prepare("UPDATE content_nodes SET deletedAt = CURRENT_TIMESTAMP WHERE id = ?").run(r), await $b(e).clear(), new fx(e.env).purgeNode(e, t, r, !0), await px(t), e.json({
24025
+ return await t.prepare("UPDATE content_nodes SET deletedAt = CURRENT_TIMESTAMP WHERE id = ?").run(r), await $b(e).clear(), await px(t), new fx(e.env).purgeNode(e, t, r, !0), e.json({
23960
24026
  success: !0,
23961
24027
  deletedNodeId: r
23962
24028
  });
23963
24029
  }), mx.post("/restore", async (e) => {
23964
24030
  let t = e.get("db"), n = await e.req.json(), r = Number(n.id);
23965
- return r ? await t.prepare("SELECT id FROM content_nodes WHERE id = ?").get(r) ? (await t.prepare("UPDATE content_nodes SET deletedAt = NULL WHERE id = ?").run(r), await $b(e).clear(), new fx(e.env).purgeNode(e, t, r, !0), await px(t), e.json({
24031
+ return r ? await t.prepare("SELECT id FROM content_nodes WHERE id = ?").get(r) ? (await t.prepare("UPDATE content_nodes SET deletedAt = NULL WHERE id = ?").run(r), await $b(e).clear(), await px(t), new fx(e.env).purgeNode(e, t, r, !0), e.json({
23966
24032
  success: !0,
23967
24033
  restoredNodeId: r
23968
24034
  })) : e.json({ error: "Node not found" }, 404) : e.json({ error: "Node ID required" }, 400);
@@ -23970,7 +24036,7 @@ mx.get("/", async (e) => {
23970
24036
  let t = e.get("db"), n = e.req.query("id");
23971
24037
  if (!n) return e.json({ error: "Node ID required" }, 400);
23972
24038
  let r = Number(n);
23973
- return new fx(e.env).purgeNode(e, t, r, !0), await t.prepare("DELETE FROM node_channels WHERE nodeId = ?").run(r), await t.prepare("DELETE FROM tree_nodes WHERE contentId = ?").run(r), await t.prepare("DELETE FROM content_blocks WHERE contentId = ?").run(r), await t.prepare("DELETE FROM node_revisions WHERE nodeId = ?").run(r), await t.prepare("DELETE FROM node_assets WHERE nodeId = ?").run(r), await t.prepare("DELETE FROM node_terms WHERE nodeId = ?").run(r), await t.prepare("DELETE FROM content_nodes WHERE id = ?").run(r), await $b(e).clear(), await px(t), e.json({
24039
+ return await t.prepare("DELETE FROM node_channels WHERE nodeId = ?").run(r), await t.prepare("DELETE FROM tree_nodes WHERE contentId = ?").run(r), await t.prepare("DELETE FROM content_blocks WHERE contentId = ?").run(r), await t.prepare("DELETE FROM node_revisions WHERE nodeId = ?").run(r), await t.prepare("DELETE FROM node_assets WHERE nodeId = ?").run(r), await t.prepare("DELETE FROM node_terms WHERE nodeId = ?").run(r), await t.prepare("DELETE FROM content_nodes WHERE id = ?").run(r), await $b(e).clear(), await px(t), new fx(e.env).purgeNode(e, t, r, !0), e.json({
23974
24040
  success: !0,
23975
24041
  purgedNodeId: r
23976
24042
  });
@@ -24001,20 +24067,23 @@ mx.get("/", async (e) => {
24001
24067
  }
24002
24068
  return e.json({ snapshot: a });
24003
24069
  }), mx.post("/:id/revisions/:version/restore", async (e) => {
24004
- let t = e.get("db"), n = Number(e.req.param("id")), r = Number(e.req.param("version")), i = e.get("user")?.id || null, a = await t.prepare("SELECT snapshotJson FROM node_revisions WHERE nodeId = ? AND version = ?").get(n, r);
24005
- if (!a) return e.json({ error: "Snapshot not found" }, 404);
24006
- let o = {};
24070
+ let t = e.get("db"), n = Number(e.req.param("id")), r = Number(e.req.param("version")), i = e.get("user")?.id || null, a = await t.prepare("SELECT * FROM content_nodes WHERE id = ?").get(n);
24071
+ if (!a) return e.json({ error: "Node not found" }, 404);
24072
+ let o = await t.prepare("SELECT snapshotJson FROM node_revisions WHERE nodeId = ? AND version = ?").get(n, r);
24073
+ if (!o) return e.json({ error: "Snapshot not found" }, 404);
24074
+ let s = {};
24007
24075
  try {
24008
- o = JSON.parse(a.snapshotJson);
24076
+ s = JSON.parse(o.snapshotJson);
24009
24077
  } catch {
24010
24078
  return e.json({ error: "Corrupt snapshot data" }, 500);
24011
24079
  }
24012
- if (await t.prepare("\n UPDATE content_nodes\n SET draftDataJson = ?, title = ?, slug = ?, updatedById = ?, updatedAt = CURRENT_TIMESTAMP, status = 'draft', hasUnpublishedChanges = 1\n WHERE id = ?\n ").run(o.node?.dataJson || "{}", o.node?.title || "Restored Document", o.node?.slug || null, i, n), await t.prepare("DELETE FROM content_blocks WHERE contentId = ? AND isDraft = 1").run(n), o.blocks && Array.isArray(o.blocks) && o.blocks.length > 0) {
24080
+ let c = a.status === "published" || a.publishedAt != null, l = c ? a.title : s.node?.title || "Restored Document", u = c ? a.slug : s.node?.slug || null;
24081
+ if (await t.prepare("\n UPDATE content_nodes\n SET draftDataJson = ?, title = ?, slug = ?, updatedById = ?, updatedAt = CURRENT_TIMESTAMP, status = 'draft', hasUnpublishedChanges = 1\n WHERE id = ?\n ").run(s.node?.dataJson || "{}", l, u, i, n), await t.prepare("DELETE FROM content_blocks WHERE contentId = ? AND isDraft = 1").run(n), s.blocks && Array.isArray(s.blocks) && s.blocks.length > 0) {
24013
24082
  let e = [], r = [];
24014
- for (let t of o.blocks) e.push("(?, ?, ?, ?, ?, 1)"), r.push(n, t.sortOrder, t.elementType, t.dataJson, t.region || "content");
24083
+ for (let t of s.blocks) e.push("(?, ?, ?, ?, ?, 1)"), r.push(n, t.sortOrder, t.elementType, t.dataJson, t.region || "content");
24015
24084
  await t.prepare(`INSERT INTO content_blocks (contentId, sortOrder, elementType, dataJson, region, isDraft) VALUES ${e.join(", ")}`).run(...r);
24016
24085
  }
24017
- return await $b(e).clear(), await px(t), e.json({
24086
+ return await $b(e).clear(), e.json({
24018
24087
  success: !0,
24019
24088
  restoredVersion: r
24020
24089
  });
@@ -24126,7 +24195,7 @@ Tx.get("/tree.json", async (e) => {
24126
24195
  c.push(e.id, e.sortOrder);
24127
24196
  }), c.push(...i), c.push(o), await t.prepare(s).run(...c);
24128
24197
  }
24129
- return await i.clear(), r.length > 0 && a.purgeNode(e, t, r[0].id, !0), await px(t), e.json({
24198
+ return await px(t), await i.clear(), r.length > 0 && a.purgeNode(e, t, r[0].id, !0), e.json({
24130
24199
  success: !0,
24131
24200
  reorderedCount: r.length
24132
24201
  });
@@ -24188,7 +24257,7 @@ Tx.get("/tree.json", async (e) => {
24188
24257
  let e = x.map(() => "(?, ?)").join(", "), n = x.flatMap((e) => [f, e]);
24189
24258
  await t.prepare(`INSERT OR IGNORE INTO node_channels (nodeId, channelId) VALUES ${e}`).run(...n);
24190
24259
  }
24191
- return await i.clear(), await px(t), e.json({
24260
+ return await px(t), await i.clear(), e.json({
24192
24261
  success: !0,
24193
24262
  id: f,
24194
24263
  treeNodeId: f,
@@ -24225,14 +24294,14 @@ Tx.get("/tree.json", async (e) => {
24225
24294
  field: "slug"
24226
24295
  }, 409);
24227
24296
  }
24228
- return await t.prepare("DELETE FROM tree_nodes WHERE treeId = ? AND contentId = ?").run(o, d), await t.prepare("\n INSERT INTO tree_nodes (treeId, contentId, parentId, sortOrder)\n VALUES (?, ?, ?, 0)\n ").run(o, d, g), await i.clear(), a.purgeNode(e, t, d, !0), await px(t), e.json({
24297
+ return await t.prepare("DELETE FROM tree_nodes WHERE treeId = ? AND contentId = ?").run(o, d), await t.prepare("\n INSERT INTO tree_nodes (treeId, contentId, parentId, sortOrder)\n VALUES (?, ?, ?, 0)\n ").run(o, d, g), await px(t), await i.clear(), a.purgeNode(e, t, d, !0), e.json({
24229
24298
  success: !0,
24230
24299
  treeNodeId: d
24231
24300
  });
24232
24301
  }
24233
24302
  if (s === "detach") {
24234
24303
  let r = n.contentId || n.id || n.treeNodeId;
24235
- return r ? (await t.prepare("\n UPDATE tree_nodes \n SET parentId = (SELECT parentId FROM tree_nodes WHERE contentId = ? AND treeId = ?) \n WHERE parentId = ? AND treeId = ?\n ").run(r, o, r, o), await t.prepare("DELETE FROM tree_nodes WHERE contentId = ? AND treeId = ?").run(r, o), await i.clear(), a.purgeNode(e, t, r, !0), await px(t), e.json({ success: !0 })) : e.json({ error: "contentId required for detach" }, 400);
24304
+ return r ? (await t.prepare("\n UPDATE tree_nodes \n SET parentId = (SELECT parentId FROM tree_nodes WHERE contentId = ? AND treeId = ?) \n WHERE parentId = ? AND treeId = ?\n ").run(r, o, r, o), await t.prepare("DELETE FROM tree_nodes WHERE contentId = ? AND treeId = ?").run(r, o), await px(t), await i.clear(), a.purgeNode(e, t, r, !0), e.json({ success: !0 })) : e.json({ error: "contentId required for detach" }, 400);
24236
24305
  }
24237
24306
  return e.json({ error: "Invalid payload or action" }, 400);
24238
24307
  } catch (t) {
@@ -24296,7 +24365,7 @@ Tx.get("/tree.json", async (e) => {
24296
24365
  await t.prepare(`INSERT OR IGNORE INTO channel_trees (channelId, treeId, key) VALUES ${n}`).run(...r);
24297
24366
  }
24298
24367
  }
24299
- return await $b(e).clear(), new fx(e.env).purgeGlobalCache(e, t), await px(t), e.json({
24368
+ return await px(t), await $b(e).clear(), new fx(e.env).purgeGlobalCache(e, t), e.json({
24300
24369
  success: !0,
24301
24370
  id: p,
24302
24371
  key: o,
@@ -24315,7 +24384,7 @@ Tx.get("/tree.json", async (e) => {
24315
24384
  if (!n) return e.json({ error: "Tree ID required" }, 400);
24316
24385
  let r = Number(n);
24317
24386
  try {
24318
- return await t.prepare("DELETE FROM trees WHERE id = ?").run(r), await t.prepare("DELETE FROM channel_trees WHERE treeId = ?").run(r), await t.prepare("DELETE FROM tree_nodes WHERE treeId = ?").run(r), await $b(e).clear(), new fx(e.env).purgeGlobalCache(e, t), await px(t), e.json({
24387
+ return await t.prepare("DELETE FROM trees WHERE id = ?").run(r), await t.prepare("DELETE FROM channel_trees WHERE treeId = ?").run(r), await t.prepare("DELETE FROM tree_nodes WHERE treeId = ?").run(r), await px(t), await $b(e).clear(), new fx(e.env).purgeGlobalCache(e, t), e.json({
24319
24388
  success: !0,
24320
24389
  deletedTreeId: r
24321
24390
  });
@@ -24423,7 +24492,7 @@ kx.get("/", async (e) => {
24423
24492
  `).run(...n);
24424
24493
  }
24425
24494
  let k = $b(e);
24426
- return await k.delete(`channel:${C}`), await k.delete(`channel:${ne}`), await k.clear(), new fx(e.env).purgeGlobalCache(e, t), e.json({
24495
+ return await k.delete(`channel:${C}`), await k.delete(`channel:${ne}`), await k.clear(), await px(t), new fx(e.env).purgeGlobalCache(e, t), e.json({
24427
24496
  success: !0,
24428
24497
  id: ne
24429
24498
  });
@@ -24440,7 +24509,7 @@ kx.get("/", async (e) => {
24440
24509
  try {
24441
24510
  await t.prepare("DELETE FROM channel_trees WHERE channelId = ?").run(r), await t.prepare("DELETE FROM node_channels WHERE channelId = ?").run(r), await t.prepare("DELETE FROM channels WHERE id = ?").run(r);
24442
24511
  let n = $b(e);
24443
- return await n.delete(`channel:${r}`), await n.clear(), new fx(e.env).purgeGlobalCache(e, t), e.json({
24512
+ return await n.delete(`channel:${r}`), await n.clear(), await px(t), new fx(e.env).purgeGlobalCache(e, t), e.json({
24444
24513
  success: !0,
24445
24514
  deletedSiteId: r
24446
24515
  });
@@ -30,7 +30,7 @@ async function f() {
30
30
  if (n(f)) l = (await import(t(f).href)).compileDefinitions;
31
31
  else if (n(p)) l = (await import(t(p).href)).compileDefinitions;
32
32
  else try {
33
- l = (await import("./dist-BmDMKgKk.js")).compileDefinitions;
33
+ l = (await import("./dist-KAwiRitk.js")).compileDefinitions;
34
34
  } catch (e) {
35
35
  console.error("\x1B[31m ✖\x1B[0m \x1B[31mCould not resolve Kama Schema Engine:\x1B[0m", e), process.exit(1);
36
36
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brightsideoy/kama",
3
- "version": "1.0.0-alpha.7",
3
+ "version": "1.0.0-alpha.8",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -8,7 +8,9 @@
8
8
  ".": {
9
9
  "types": "./dist/index.d.ts",
10
10
  "import": "./dist/index.js"
11
- }
11
+ },
12
+ "./schema.sql": "./schema.sql",
13
+ "./package.json": "./package.json"
12
14
  },
13
15
  "bin": {
14
16
  "kama": "bin/cli.js",
@@ -261,3 +261,50 @@ const isSkeleton = node?.nodeType === "page-skeleton";
261
261
  </StandardLayout>
262
262
  )
263
263
  }
264
+ <script is:inline>
265
+ // 🎯 HTML-Over-The-Wire Hot-Swap Logic (Vite & Astro Safe)
266
+ if (window !== window.top) {
267
+ window.addEventListener("message", async event => {
268
+ if (event.data && event.data.type === "kama-preview-update") {
269
+ try {
270
+ // 1. Remember scroll position
271
+ const currentScrollY = window.scrollY;
272
+
273
+ // 2. Fetch the newly saved draft HTML in the background
274
+ const res = await fetch(event.data.url);
275
+ const newHtml = await res.text();
276
+ const newDoc = new DOMParser().parseFromString(newHtml, "text/html");
277
+
278
+ // 🎯 CORE FIX: Strip all embedded scripts, styles, and Vite client links
279
+ // from the NEW document before they ever touch the live DOM.
280
+ // This stops the browser from aggressively re-fetching them and throwing ERR_ABORTED.
281
+ newDoc.body
282
+ .querySelectorAll("script, style, link, meta, noscript")
283
+ .forEach(el => el.remove());
284
+
285
+ const preserveTags = ["SCRIPT", "STYLE", "LINK", "META", "NOSCRIPT"];
286
+
287
+ // 3. Safely wipe the current body EXCEPT for our preserved assets
288
+ Array.from(document.body.children).forEach(child => {
289
+ if (!preserveTags.includes(child.tagName.toUpperCase())) {
290
+ child.remove();
291
+ }
292
+ });
293
+
294
+ // 4. Inject the clean structural content
295
+ const referenceNode = document.body.firstChild;
296
+ Array.from(newDoc.body.children).forEach(child => {
297
+ if (!preserveTags.includes(child.tagName.toUpperCase())) {
298
+ document.body.insertBefore(child.cloneNode(true), referenceNode);
299
+ }
300
+ });
301
+
302
+ // 5. Restore scroll position instantly
303
+ window.scrollTo(0, currentScrollY);
304
+ } catch (err) {
305
+ console.error("[KAMA Preview] Failed to hot-swap HTML:", err);
306
+ }
307
+ }
308
+ });
309
+ }
310
+ </script>