@brightsideoy/kama 0.1.0-alpha.128 → 0.1.0-alpha.130

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
@@ -6255,66 +6255,88 @@ Z.get("/", async (e) => {
6255
6255
  }), Z.post("/publish", async (e) => {
6256
6256
  let t = e.get("db"), n = await e.req.json(), r = n.id || n.nodeId;
6257
6257
  if (!r || isNaN(Number(r))) return e.json({ error: "Node ID required for publishing" }, 400);
6258
- let i = Number(r), a = e.get("user")?.id || null;
6259
- if (!await t.prepare("SELECT status, slug, title FROM content_nodes WHERE id = ?").get(i)) return e.json({ error: "Node not found" }, 404);
6260
- let o = [];
6261
- o.push({
6258
+ let i = Number(r), a = e.get("user")?.id || null, o = (await fi(t, "SELECT * FROM content_nodes WHERE id = ?", [i]))[0];
6259
+ if (!o) return e.json({ error: "Node not found" }, 404);
6260
+ let s = [];
6261
+ return s.push({
6262
6262
  sql: "UPDATE content_nodes \n SET publishedDataJson = draftDataJson, \n dataJson = draftDataJson, \n publishedAt = CURRENT_TIMESTAMP, \n status = 'published', \n updatedById = ?, \n updatedAt = CURRENT_TIMESTAMP \n WHERE id = ?",
6263
6263
  params: [a, i]
6264
- }), o.push({
6264
+ }), s.push({
6265
6265
  sql: "DELETE FROM content_blocks WHERE contentId = ? AND isDraft = 0",
6266
6266
  params: [i]
6267
- }), o.push({
6267
+ }), s.push({
6268
6268
  sql: "INSERT INTO content_blocks (contentId, sortOrder, elementType, dataJson, region, isDraft) \n SELECT contentId, sortOrder, elementType, dataJson, region, 0 \n FROM content_blocks \n WHERE contentId = ? AND isDraft = 1",
6269
6269
  params: [i]
6270
- });
6271
- let s = ((await t.prepare("SELECT COUNT(*) as count FROM node_revisions WHERE nodeId = ?").get(i))?.count || 0) + 1;
6272
- return o.push({
6273
- sql: "INSERT INTO node_revisions (nodeId, version, snapshotJson, createdById) \n SELECT ?, ?, \n json_object(\n 'version', ?, \n 'publishedAt', CURRENT_TIMESTAMP, \n 'node', json_patch(draftDataJson, json_object('contentType', contentType)), \n 'blocks', (SELECT json_group_array(json_object('elementType', elementType, 'dataJson', dataJson, 'region', region, 'sortOrder', sortOrder, 'instanceId', instanceId)) FROM content_blocks WHERE contentId = ? AND isDraft = 1)\n ), ?\n FROM content_nodes WHERE id = ?",
6274
- params: [
6275
- i,
6276
- s,
6277
- s,
6278
- i,
6279
- a,
6280
- i
6281
- ]
6282
- }), await t.batch(o), di(e, async () => {
6283
- new X(e.env).purgeNode(e, t, i, !1), await Y(e).clear();
6270
+ }), await t.batch(s), di(e, async () => {
6271
+ try {
6272
+ let n = ((await fi(t, "SELECT COUNT(*) as count FROM node_revisions WHERE nodeId = ?", [i]))[0]?.count || 0) + 1, r = (await fi(t, "SELECT elementType, dataJson, region, sortOrder FROM content_blocks WHERE contentId = ? AND isDraft = 1", [i])).map((e) => {
6273
+ let t = e.dataJson ? JSON.parse(e.dataJson) : {};
6274
+ return {
6275
+ ...e,
6276
+ instanceId: t.blockId || t.id || `block-${Date.now()}`,
6277
+ dataJson: t
6278
+ };
6279
+ }), s = JSON.stringify({
6280
+ version: n,
6281
+ publishedAt: (/* @__PURE__ */ new Date()).toISOString(),
6282
+ node: {
6283
+ ...o.draftDataJson ? JSON.parse(o.draftDataJson) : {},
6284
+ title: o.title,
6285
+ slug: o.slug,
6286
+ nodeType: o.contentType,
6287
+ contentType: o.contentType,
6288
+ language: o.language,
6289
+ isHidden: o.isHidden,
6290
+ status: "published"
6291
+ },
6292
+ blocks: r
6293
+ });
6294
+ await pi(t, "INSERT INTO node_revisions (nodeId, version, snapshotJson, createdById) VALUES (?, ?, ?, ?)", [
6295
+ i,
6296
+ n,
6297
+ s,
6298
+ a
6299
+ ]), new X(e.env).purgeNode(e, t, i, !1);
6300
+ } catch (e) {
6301
+ console.warn("Failed to compile revision snapshot in background", e);
6302
+ }
6284
6303
  }), e.json({
6285
6304
  success: !0,
6286
6305
  id: i,
6287
6306
  status: "published",
6288
- version: s,
6289
6307
  publishedAt: (/* @__PURE__ */ new Date()).toISOString()
6290
6308
  });
6291
6309
  }), Z.get("/revisions", async (e) => {
6292
6310
  let t = e.get("db"), n = Number(e.req.query("id"));
6293
6311
  if (!n || isNaN(n)) return e.json({ error: "Invalid Node ID" }, 400);
6294
- let r = await t.prepare("\n SELECT r.id, r.version, r.createdAt, r.createdById, u.name as createdByName, u.email as createdByEmail\n FROM node_revisions r LEFT JOIN users u ON r.createdById = u.id\n WHERE r.nodeId = ? ORDER BY r.createdAt DESC LIMIT 50\n ").all(n), i = (Array.isArray(r) ? r : r?.results || []).map((e) => ({
6312
+ let r = (await fi(t, "\n SELECT r.id, r.version, r.createdAt, r.createdById, u.name as createdByName, u.email as createdByEmail\n FROM node_revisions r LEFT JOIN users u ON r.createdById = u.id\n WHERE r.nodeId = ? ORDER BY r.createdAt DESC LIMIT 50\n ", [n])).map((e) => ({
6295
6313
  ...e,
6296
6314
  createdAt: (e.createdAt || "").replace(" ", "T") + "Z"
6297
6315
  }));
6298
- return e.json({ revisions: i });
6316
+ return e.json({ revisions: r });
6299
6317
  }), Z.get("/revisions/payload", async (e) => {
6300
6318
  let t = e.get("db"), n = Number(e.req.query("id")), r = Number(e.req.query("revisionId"));
6301
6319
  if (!n || isNaN(n) || !r || isNaN(r)) return e.json({ error: "Invalid IDs" }, 400);
6302
- let i = await t.prepare("SELECT snapshotJson FROM node_revisions WHERE id = ? AND nodeId = ?").get(r, n);
6303
- if (!i) return e.json({ error: "Revision not found" }, 404);
6304
- let a = {};
6320
+ let i = (await fi(t, "SELECT * FROM content_nodes WHERE id = ?", [n]))[0] || {}, a = (await fi(t, "SELECT snapshotJson FROM node_revisions WHERE id = ? AND nodeId = ?", [r, n]))[0];
6321
+ if (!a) return e.json({ error: "Revision not found" }, 404);
6322
+ let o = {};
6305
6323
  try {
6306
- a = typeof i.snapshotJson == "string" ? JSON.parse(i.snapshotJson) : i.snapshotJson;
6324
+ o = typeof a.snapshotJson == "string" ? JSON.parse(a.snapshotJson) : a.snapshotJson;
6307
6325
  } catch {
6308
6326
  return e.json({ error: "Failed to parse snapshot" }, 500);
6309
6327
  }
6310
- let o = typeof a.node?.dataJson == "string" ? JSON.parse(a.node.dataJson) : a.node?.dataJson || {};
6311
- o = await ui(t, _i(o));
6312
- let s = {
6313
- ...a.node,
6314
- ...o,
6315
- nodeType: a.node?.contentType || a.node?.nodeType,
6316
- contentType: a.node?.contentType || a.node?.nodeType
6317
- }, c = a.blocks || [], l = await Promise.all(c.map(async (e) => {
6328
+ let s = typeof o.node?.dataJson == "string" ? JSON.parse(o.node.dataJson) : o.node?.dataJson || o.node || {};
6329
+ s = await ui(t, _i(s));
6330
+ let c = {
6331
+ ...i,
6332
+ nodeType: i.contentType,
6333
+ ...o.node,
6334
+ ...s,
6335
+ nodeType: o.node?.contentType || o.node?.nodeType || i.contentType,
6336
+ contentType: o.node?.contentType || o.node?.nodeType || i.contentType,
6337
+ title: o.node?.title || i.title,
6338
+ slug: o.node?.slug || i.slug
6339
+ }, l = o.blocks || [], u = await Promise.all(l.map(async (e) => {
6318
6340
  let n = typeof e.dataJson == "string" ? JSON.parse(e.dataJson || "{}") : e.dataJson || {};
6319
6341
  n = await ui(t, n);
6320
6342
  let r = n.blockId || n._instanceId || (n.id && !String(n.id).startsWith("ast_") ? n.id : null) || e.instanceId || String(e.id), i = { ...n };
@@ -6327,9 +6349,9 @@ Z.get("/", async (e) => {
6327
6349
  };
6328
6350
  }));
6329
6351
  return e.json({
6330
- node: s,
6331
- blocks: l,
6332
- version: a.version
6352
+ node: c,
6353
+ blocks: u,
6354
+ version: o.version
6333
6355
  });
6334
6356
  }), Z.delete("/", async (e) => {
6335
6357
  let t = e.get("db"), n = e.req.query("id");
@@ -6388,7 +6410,13 @@ Z.get("/", async (e) => {
6388
6410
  //#endregion
6389
6411
  //#region server/routes/admin/trees.ts
6390
6412
  var yi = new n();
6391
- function bi(e, t = null) {
6413
+ function bi(e, t) {
6414
+ let n = Promise.resolve(typeof t == "function" ? t() : t).catch((e) => console.error("[Background Task Error]:", e));
6415
+ try {
6416
+ e.executionCtx && typeof e.executionCtx.waitUntil == "function" && e.executionCtx.waitUntil(n);
6417
+ } catch {}
6418
+ }
6419
+ function xi(e, t = null) {
6392
6420
  let n = [];
6393
6421
  for (let r = 0; r < e.length; r++) {
6394
6422
  let i = e[r];
@@ -6400,16 +6428,16 @@ function bi(e, t = null) {
6400
6428
  id: o,
6401
6429
  parentId: t,
6402
6430
  sortOrder: r
6403
- }), i.children && Array.isArray(i.children) && i.children.length > 0 && n.push(...bi(i.children, o)));
6431
+ }), i.children && Array.isArray(i.children) && i.children.length > 0 && n.push(...xi(i.children, o)));
6404
6432
  }
6405
6433
  return n;
6406
6434
  }
6407
- function xi(e) {
6435
+ function Si(e) {
6408
6436
  if (e == null || e === "null" || e === "" || typeof e == "string" && e.startsWith("draft-")) return null;
6409
6437
  let t = Number(e);
6410
6438
  return isNaN(t) ? null : t;
6411
6439
  }
6412
- function Si(e) {
6440
+ function Ci(e) {
6413
6441
  return +(e === !0 || e === 1 || e === "1" || e === "true");
6414
6442
  }
6415
6443
  yi.get("/tree.json", async (e) => {
@@ -6464,43 +6492,39 @@ yi.get("/tree.json", async (e) => {
6464
6492
  }
6465
6493
  }), yi.post("/tree.json", async (e) => {
6466
6494
  try {
6467
- let t = e.get("db"), n = await e.req.json(), r = n.treeId ? String(n.treeId).trim() : "main-nav", i = Y(e), a = new X(e.env), o = 1;
6495
+ let t = e.get("db"), n = await e.req.json(), r = n.treeId ? String(n.treeId).trim() : "main-nav", i = 1;
6468
6496
  if (isNaN(Number(r))) {
6469
6497
  let e = await t.prepare("SELECT id FROM trees WHERE key = ?").get(r);
6470
- if (e && e.id) o = Number(e.id);
6471
- else {
6472
- let e = await t.prepare("SELECT id FROM trees LIMIT 1").get();
6473
- e && e.id && (o = Number(e.id));
6474
- }
6475
- } else o = Number(r);
6498
+ e && e.id && (i = Number(e.id));
6499
+ } else i = Number(r);
6476
6500
  if (n.tree && Array.isArray(n.tree)) {
6477
- let r = bi(n.tree, null);
6478
- if (r.length > 0) for (let e = 0; e < r.length; e += 15) {
6479
- let n = r.slice(e, e + 15), i = n.map((e) => e.id), a = i.map(() => "?").join(","), s = "UPDATE tree_nodes SET \n";
6480
- s += "parentId = CASE id \n", n.forEach(() => {
6481
- s += "WHEN ? THEN ? \n";
6482
- }), s += "ELSE parentId END, \n", s += "sortOrder = CASE id \n", n.forEach(() => {
6483
- s += "WHEN ? THEN ? \n";
6484
- }), s += "ELSE sortOrder END \n", s += `WHERE id IN (${a}) AND treeId = ?`;
6485
- let c = [];
6486
- n.forEach((e) => {
6487
- c.push(e.id, e.parentId);
6488
- }), n.forEach((e) => {
6489
- c.push(e.id, e.sortOrder);
6490
- }), c.push(...i), c.push(o), await t.prepare(s).run(...c);
6501
+ let r = xi(n.tree, null);
6502
+ if (r.length > 0) {
6503
+ let e = r.map((e) => ({
6504
+ sql: "UPDATE tree_nodes SET parentId = ?, sortOrder = ? WHERE id = ? AND treeId = ?",
6505
+ params: [
6506
+ e.parentId,
6507
+ e.sortOrder,
6508
+ e.id,
6509
+ i
6510
+ ]
6511
+ }));
6512
+ await t.batch(e);
6491
6513
  }
6492
- return await i.clear(), a.purgeGlobalCache(e, t), e.json({
6514
+ return bi(e, async () => {
6515
+ await Y(e).clear(), new X(e.env).purgeGlobalCache(e, t);
6516
+ }), e.json({
6493
6517
  success: !0,
6494
6518
  reorderedCount: r.length
6495
6519
  });
6496
6520
  }
6497
- let { action: s, title: c, nodeType: l, parentId: u, contentId: d, nodeData: f = {}, pageData: p = {} } = n, m = Object.keys(f).length > 0 ? { ...f } : { ...p }, h = Si(n.isHidden === void 0 ? m.isHidden === void 0 ? m.hidden : m.isHidden : n.isHidden);
6498
- delete m._isTreeDraft, delete m._draftParentId, delete m.isNew, delete m.nodeType, delete m.contentType, delete m.title, delete m.slug, delete m.hidden, delete m.is_hidden, delete m.isHidden, delete m.status;
6499
- let g = xi(u), _ = e.get("user")?.id || null;
6500
- if (s === "create") {
6501
- let r = m.slug || n.slug || c, s = r ? String(r).toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "") : null;
6502
- if (s) {
6503
- let r = g === null ? "tn.parentId IS NULL" : "tn.parentId = ?", i = n.contentId || n.id ? Number(n.contentId || n.id) : null, a = `
6521
+ let { action: a, title: o, nodeType: s, parentId: c, contentId: l, nodeData: u = {}, pageData: d = {} } = n, f = Object.keys(u).length > 0 ? { ...u } : { ...d }, p = Ci(n.isHidden === void 0 ? f.isHidden === void 0 ? f.hidden : f.isHidden : n.isHidden);
6522
+ delete f._isTreeDraft, delete f._draftParentId, delete f.isNew, delete f.nodeType, delete f.contentType, delete f.title, delete f.slug, delete f.hidden, delete f.is_hidden, delete f.isHidden, delete f.status;
6523
+ let m = Si(c), h = e.get("user")?.id || null;
6524
+ if (a === "create") {
6525
+ let r = f.slug || n.slug || o, a = r ? String(r).toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "") : null;
6526
+ if (a) {
6527
+ let r = m === null ? "tn.parentId IS NULL" : "tn.parentId = ?", o = n.contentId || n.id ? Number(n.contentId || n.id) : null, s = `
6504
6528
  SELECT 1
6505
6529
  FROM tree_nodes tn
6506
6530
  INNER JOIN content_nodes cn ON tn.contentId = cn.id
@@ -6508,49 +6532,51 @@ yi.get("/tree.json", async (e) => {
6508
6532
  AND ${r}
6509
6533
  AND cn.slug = ?
6510
6534
  AND (cn.deletedAt IS NULL OR cn.deletedAt = '')
6511
- `, c = g === null ? [o, s] : [
6512
- o,
6513
- g,
6514
- s
6535
+ `, c = m === null ? [i, a] : [
6536
+ i,
6537
+ m,
6538
+ a
6515
6539
  ];
6516
- if (i && !isNaN(i) && (a += " AND cn.id != ?", c.push(i)), a += " LIMIT 1", await t.prepare(a).get(...c)) return e.json({
6517
- error: `The slug '${s}' is already in use by another page in this section.`,
6540
+ if (o && !isNaN(o) && (s += " AND cn.id != ?", c.push(o)), s += " LIMIT 1", await t.prepare(s).get(...c)) return e.json({
6541
+ error: `The slug '${a}' is already in use by another page in this section.`,
6518
6542
  field: "slug"
6519
6543
  }, 409);
6520
6544
  }
6521
- let u = JSON.stringify(m), d = await t.prepare("\n INSERT INTO content_nodes (contentType, title, slug, language, isHidden, status, draftDataJson, dataJson, createdById, updatedById)\n VALUES (?, ?, ?, ?, ?, 'draft', ?, NULL, ?, ?)\n ").run(l || "page", c || "Untitled", s, m.language || n.language || "en", h, u, _, _), f = Number(d.lastInsertRowid);
6522
- await t.prepare("DELETE FROM tree_nodes WHERE treeId = ? AND contentId = ?").run(o, f);
6523
- let p = g === null ? "parentId IS NULL" : "parentId = ?", v = g === null ? [o] : [o, g], y = (await t.prepare(`
6545
+ let c = JSON.stringify(f), l = await t.prepare("\n INSERT INTO content_nodes (contentType, title, slug, language, isHidden, status, draftDataJson, dataJson, createdById, updatedById)\n VALUES (?, ?, ?, ?, ?, 'draft', ?, NULL, ?, ?)\n ").run(s || "page", o || "Untitled", a, f.language || n.language || "en", p, c, h, h), u = Number(l.lastInsertRowid);
6546
+ await t.prepare("DELETE FROM tree_nodes WHERE treeId = ? AND contentId = ?").run(i, u);
6547
+ let d = m === null ? "parentId IS NULL" : "parentId = ?", g = m === null ? [i] : [i, m], _ = (await t.prepare(`
6524
6548
  SELECT COALESCE(MAX(sortOrder), -1) + 1 as nextSort
6525
6549
  FROM tree_nodes
6526
- WHERE treeId = ? AND ${p}
6527
- `).get(...v))?.nextSort ?? 0, b = await t.prepare("\n INSERT INTO tree_nodes (treeId, contentId, parentId, sortOrder)\n VALUES (?, ?, ?, ?)\n ").run(o, f, g, y), x = Number(b.lastInsertRowid), S = [];
6528
- n.channels && Array.isArray(n.channels) ? S = n.channels : n.channelId && n.channelId !== "all" && (S = [n.channelId]);
6529
- let C = [...new Set(S)].filter((e) => e && e !== "all").map((e) => Number(e));
6530
- if (C.length > 0) {
6531
- let e = C.map(() => "(?, ?)").join(", "), n = C.flatMap((e) => [f, e]);
6550
+ WHERE treeId = ? AND ${d}
6551
+ `).get(...g))?.nextSort ?? 0, v = await t.prepare("\n INSERT INTO tree_nodes (treeId, contentId, parentId, sortOrder)\n VALUES (?, ?, ?, ?)\n ").run(i, u, m, _), y = Number(v.lastInsertRowid), b = [];
6552
+ n.channels && Array.isArray(n.channels) ? b = n.channels : n.channelId && n.channelId !== "all" && (b = [n.channelId]);
6553
+ let x = [...new Set(b)].filter((e) => e && e !== "all").map((e) => Number(e));
6554
+ if (x.length > 0) {
6555
+ let e = x.map(() => "(?, ?)").join(", "), n = x.flatMap((e) => [u, e]);
6532
6556
  await t.prepare(`INSERT OR IGNORE INTO node_channels (nodeId, channelId) VALUES ${e}`).run(...n);
6533
6557
  }
6534
- return await i.clear(), a.purgeGlobalCache(e, t), e.json({
6558
+ return bi(e, async () => {
6559
+ await Y(e).clear(), new X(e.env).purgeGlobalCache(e, t);
6560
+ }), e.json({
6535
6561
  success: !0,
6536
- id: f,
6537
- treeNodeId: x,
6562
+ id: u,
6563
+ treeNodeId: y,
6538
6564
  status: "draft"
6539
6565
  }, 201);
6540
6566
  }
6541
- if (s === "attach") {
6542
- if (!d) return e.json({ error: "contentId is required for attach" }, 400);
6543
- let n = await t.prepare("SELECT slug FROM content_nodes WHERE id = ?").get(d);
6567
+ if (a === "attach") {
6568
+ if (!l) return e.json({ error: "contentId is required for attach" }, 400);
6569
+ let n = await t.prepare("SELECT slug FROM content_nodes WHERE id = ?").get(l);
6544
6570
  if (n && n.slug) {
6545
- let r = g === null ? "tn.parentId IS NULL" : "tn.parentId = ?", i = g === null ? [
6546
- o,
6571
+ let r = m === null ? "tn.parentId IS NULL" : "tn.parentId = ?", a = m === null ? [
6572
+ i,
6547
6573
  n.slug,
6548
- d
6574
+ l
6549
6575
  ] : [
6550
- o,
6551
- g,
6576
+ i,
6577
+ m,
6552
6578
  n.slug,
6553
- d
6579
+ l
6554
6580
  ];
6555
6581
  if (await t.prepare(`
6556
6582
  SELECT 1
@@ -6562,21 +6588,25 @@ yi.get("/tree.json", async (e) => {
6562
6588
  AND cn.id != ?
6563
6589
  AND (cn.deletedAt IS NULL OR cn.deletedAt = '')
6564
6590
  LIMIT 1
6565
- `).get(...i)) return e.json({
6591
+ `).get(...a)) return e.json({
6566
6592
  error: `Cannot attach. The slug '${n.slug}' is already in use by another page in this section.`,
6567
6593
  field: "slug"
6568
6594
  }, 409);
6569
6595
  }
6570
- await t.prepare("DELETE FROM tree_nodes WHERE treeId = ? AND contentId = ?").run(o, d);
6571
- let r = await t.prepare("\n INSERT INTO tree_nodes (treeId, contentId, parentId, sortOrder)\n VALUES (?, ?, ?, 0)\n ").run(o, d, g), s = Number(r.lastInsertRowid);
6572
- return await i.clear(), a.purgeGlobalCache(e, t), e.json({
6596
+ await t.prepare("DELETE FROM tree_nodes WHERE treeId = ? AND contentId = ?").run(i, l);
6597
+ let r = await t.prepare("\n INSERT INTO tree_nodes (treeId, contentId, parentId, sortOrder)\n VALUES (?, ?, ?, 0)\n ").run(i, l, m), a = Number(r.lastInsertRowid);
6598
+ return bi(e, async () => {
6599
+ await Y(e).clear(), new X(e.env).purgeGlobalCache(e, t);
6600
+ }), e.json({
6573
6601
  success: !0,
6574
- treeNodeId: s
6602
+ treeNodeId: a
6575
6603
  });
6576
6604
  }
6577
- if (s === "detach") {
6605
+ if (a === "detach") {
6578
6606
  let r = n.treeNodeId || n.contentId;
6579
- return r ? (await t.prepare("\n UPDATE tree_nodes \n SET parentId = (SELECT parentId FROM tree_nodes WHERE (id = ? OR contentId = ?) AND treeId = ?) \n WHERE parentId = ? AND treeId = ?\n ").run(r, r, o, r, o), await t.prepare("DELETE FROM tree_nodes WHERE (id = ? OR contentId = ?) AND treeId = ?").run(r, r, o), await i.clear(), a.purgeGlobalCache(e, t), e.json({ success: !0 })) : e.json({ error: "treeNodeId or contentId required for detach" }, 400);
6607
+ return r ? (await t.prepare("\n UPDATE tree_nodes \n SET parentId = (SELECT parentId FROM tree_nodes WHERE (id = ? OR contentId = ?) AND treeId = ?) \n WHERE parentId = ? AND treeId = ?\n ").run(r, r, i, r, i), await t.prepare("DELETE FROM tree_nodes WHERE (id = ? OR contentId = ?) AND treeId = ?").run(r, r, i), bi(e, async () => {
6608
+ await Y(e).clear(), new X(e.env).purgeGlobalCache(e, t);
6609
+ }), e.json({ success: !0 })) : e.json({ error: "treeNodeId or contentId required for detach" }, 400);
6580
6610
  }
6581
6611
  return e.json({ error: "Invalid payload or action" }, 400);
6582
6612
  } catch (t) {
@@ -6640,7 +6670,9 @@ yi.get("/tree.json", async (e) => {
6640
6670
  await t.prepare(`INSERT OR IGNORE INTO channel_trees (channelId, treeId, key) VALUES ${n}`).run(...r);
6641
6671
  }
6642
6672
  }
6643
- return await Y(e).clear(), new X(e.env).purgeGlobalCache(e, t), e.json({
6673
+ return bi(e, async () => {
6674
+ await Y(e).clear(), new X(e.env).purgeGlobalCache(e, t);
6675
+ }), e.json({
6644
6676
  success: !0,
6645
6677
  id: p,
6646
6678
  key: o,
@@ -6659,7 +6691,9 @@ yi.get("/tree.json", async (e) => {
6659
6691
  if (!n) return e.json({ error: "Tree ID required" }, 400);
6660
6692
  let r = Number(n);
6661
6693
  try {
6662
- 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 Y(e).clear(), new X(e.env).purgeGlobalCache(e, t), e.json({
6694
+ 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), bi(e, async () => {
6695
+ await Y(e).clear(), new X(e.env).purgeGlobalCache(e, t);
6696
+ }), e.json({
6663
6697
  success: !0,
6664
6698
  deletedTreeId: r
6665
6699
  });
@@ -6669,8 +6703,8 @@ yi.get("/tree.json", async (e) => {
6669
6703
  });
6670
6704
  //#endregion
6671
6705
  //#region server/routes/admin/channels.ts
6672
- var Ci = new n();
6673
- Ci.get("/", async (e) => {
6706
+ var wi = new n();
6707
+ wi.get("/", async (e) => {
6674
6708
  try {
6675
6709
  let t = e.get("db"), n = await t.prepare("SELECT * FROM channels ORDER BY id ASC").all(), r = Array.isArray(n) ? n : n?.results || [], i = await t.prepare("SELECT channelId, treeId, key, metaJson FROM channel_trees ORDER BY rowid ASC").all(), a = ((Array.isArray(i) ? i : i?.results || []) || []).reduce((e, t) => {
6676
6710
  e[t.channelId] || (e[t.channelId] = []);
@@ -6738,7 +6772,7 @@ Ci.get("/", async (e) => {
6738
6772
  error: t.message
6739
6773
  }, 500);
6740
6774
  }
6741
- }), Ci.post("/", async (e) => {
6775
+ }), wi.post("/", async (e) => {
6742
6776
  try {
6743
6777
  let t = e.get("db"), n = await e.req.json(), r = n.id, i = r != null && r !== "" && !isNaN(Number(r)) ? Number(r) : null, { key: a, label: o, channelType: s, domain: c, baseUrl: l, defaultLanguage: u, isHidden: d = !1, trees: f = [], createdById: p = null, updatedById: m = null, id: h, createdAt: g, updatedAt: _, ...v } = n, y = a?.trim() || "main", b = o?.trim() || "Untitled Channel", x = s ?? "website", S = c ?? "localhost", C = l ?? "http://localhost:4321", w = u ?? "en", T = JSON.stringify(v || {}), E = e.get("user")?.id || m || p, D = E === void 0 ? null : E;
6744
6778
  if (await t.prepare("SELECT id FROM channels WHERE key = ? AND id != ? LIMIT 1").get(y, i ?? -1)) return e.json({
@@ -6778,7 +6812,7 @@ Ci.get("/", async (e) => {
6778
6812
  details: t.message
6779
6813
  }, 500);
6780
6814
  }
6781
- }), Ci.delete("/", async (e) => {
6815
+ }), wi.delete("/", async (e) => {
6782
6816
  let t = e.get("db"), n = e.req.query("id");
6783
6817
  if (!n) return e.json({ error: "Channel ID required" }, 400);
6784
6818
  let r = Number(n);
@@ -6796,7 +6830,7 @@ Ci.get("/", async (e) => {
6796
6830
  });
6797
6831
  //#endregion
6798
6832
  //#region server/db/bundled-definitions.ts
6799
- var wi = {
6833
+ var Ti = {
6800
6834
  nodes: {
6801
6835
  address: {
6802
6836
  id: "address",
@@ -11503,11 +11537,11 @@ var wi = {
11503
11537
  treeTemplate: null,
11504
11538
  channelTemplate: null,
11505
11539
  userTemplate: null
11506
- }, Ti = new n(), Ei = null, Di = (e) => {
11540
+ }, Ei = new n(), Di = null, Oi = (e) => {
11507
11541
  try {
11508
11542
  let t = process.env.NODE_ENV !== "production";
11509
- if (!Ei || t) {
11510
- let t = e.env?.BUNDLED_DEFINITIONS || wi || {}, n = Mr(t) || {}, r = e.get("schemas") || {}, i = r.rawChannels || {}, a = r.rawNodes || {}, o = r.rawTrees || {}, s = r.rawBlocks || {}, c = r.rawNodeLayouts || {}, l = r.rawBlockLayouts || {}, u = t.rawChannels || t.channels || n.channels || {}, d = t.rawNodes || t.nodes || n.nodes || {}, f = t.rawTrees || t.trees || n.trees || {}, p = t.rawBlocks || t.blocks || n.blocks || {}, m = t.rawNodeLayouts || t.nodeLayouts || n.nodeLayouts || {}, h = t.rawBlockLayouts || t.blockLayouts || n.blockLayouts || {}, g = Object.keys(i).length > 0 ? i : u, _ = Object.keys(a).length > 0 ? a : d, v = Object.keys(o).length > 0 ? o : f, y = Object.keys(s).length > 0 ? s : p, b = Object.keys(c).length > 0 ? c : m, x = Object.keys(l).length > 0 ? l : h, S = n.userTemplate || {
11543
+ if (!Di || t) {
11544
+ let t = e.env?.BUNDLED_DEFINITIONS || Ti || {}, n = Mr(t) || {}, r = e.get("schemas") || {}, i = r.rawChannels || {}, a = r.rawNodes || {}, o = r.rawTrees || {}, s = r.rawBlocks || {}, c = r.rawNodeLayouts || {}, l = r.rawBlockLayouts || {}, u = t.rawChannels || t.channels || n.channels || {}, d = t.rawNodes || t.nodes || n.nodes || {}, f = t.rawTrees || t.trees || n.trees || {}, p = t.rawBlocks || t.blocks || n.blocks || {}, m = t.rawNodeLayouts || t.nodeLayouts || n.nodeLayouts || {}, h = t.rawBlockLayouts || t.blockLayouts || n.blockLayouts || {}, g = Object.keys(i).length > 0 ? i : u, _ = Object.keys(a).length > 0 ? a : d, v = Object.keys(o).length > 0 ? o : f, y = Object.keys(s).length > 0 ? s : p, b = Object.keys(c).length > 0 ? c : m, x = Object.keys(l).length > 0 ? l : h, S = n.userTemplate || {
11511
11545
  id: "userTemplate",
11512
11546
  label: "User Account",
11513
11547
  fields: {
@@ -11543,7 +11577,7 @@ var wi = {
11543
11577
  }
11544
11578
  }
11545
11579
  }, C = Object.keys(g)[0];
11546
- Ei = {
11580
+ Di = {
11547
11581
  channelTemplate: n.channelTemplate || (C ? g[C] : null),
11548
11582
  treeTemplate: n.treeTemplate || null,
11549
11583
  userTemplate: S,
@@ -11558,7 +11592,7 @@ var wi = {
11558
11592
  blockLayouts: x
11559
11593
  };
11560
11594
  }
11561
- return e.json(Ei, 200, { "Cache-Control": "no-cache, no-store, must-revalidate" });
11595
+ return e.json(Di, 200, { "Cache-Control": "no-cache, no-store, must-revalidate" });
11562
11596
  } catch (t) {
11563
11597
  return console.error("[CMS API] Error loading schemas:", t), e.json({
11564
11598
  error: "Failed to load schemas",
@@ -11566,10 +11600,10 @@ var wi = {
11566
11600
  }, 500);
11567
11601
  }
11568
11602
  };
11569
- Ti.get("/", Di), Ti.get("/schemas.json", Di);
11603
+ Ei.get("/", Oi), Ei.get("/schemas.json", Oi);
11570
11604
  //#endregion
11571
11605
  //#region server/routes/admin/validation.ts
11572
- var Oi = new n(), ki = {
11606
+ var ki = new n(), Ai = {
11573
11607
  node: "content_nodes",
11574
11608
  nodes: "content_nodes",
11575
11609
  content_node: "content_nodes",
@@ -11581,7 +11615,7 @@ var Oi = new n(), ki = {
11581
11615
  user: "users",
11582
11616
  users: "users",
11583
11617
  user_account: "user_accounts"
11584
- }, Ai = {
11618
+ }, ji = {
11585
11619
  content_nodes: [
11586
11620
  "id",
11587
11621
  "title",
@@ -11638,11 +11672,11 @@ var Oi = new n(), ki = {
11638
11672
  "createdAt"
11639
11673
  ]
11640
11674
  };
11641
- Oi.post("/validate-unique", async (e) => {
11675
+ ki.post("/validate-unique", async (e) => {
11642
11676
  try {
11643
11677
  let t = e.get("db"), { entityType: n, field: r, value: i, excludeId: a } = await e.req.json();
11644
11678
  if (!r || i == null || String(i).trim() === "") return e.json({ isUnique: !0 });
11645
- let o = ki[n] || "content_nodes", s = r.replace(/[^a-zA-Z0-9_]/g, ""), c = (Ai[o] || Ai.content_nodes).includes(s), l = -1;
11679
+ let o = Ai[n] || "content_nodes", s = r.replace(/[^a-zA-Z0-9_]/g, ""), c = (ji[o] || ji.content_nodes).includes(s), l = -1;
11646
11680
  if (a != null && String(a).trim() !== "") {
11647
11681
  let e = Number(a);
11648
11682
  l = isNaN(e) ? String(a) : e;
@@ -11654,7 +11688,7 @@ Oi.post("/validate-unique", async (e) => {
11654
11688
  } catch (t) {
11655
11689
  return console.error("[API Validation] Error validating global uniqueness:", t), e.json({ error: "Failed to validate uniqueness" }, 500);
11656
11690
  }
11657
- }), Oi.post("/validate-unique-sibling", async (e) => {
11691
+ }), ki.post("/validate-unique-sibling", async (e) => {
11658
11692
  try {
11659
11693
  let t = e.get("db"), { slug: n, treeId: r, parentId: i, excludeTreeNodeId: a } = await e.req.json();
11660
11694
  if (!n || !String(n).trim() || !r) return e.json({ isUnique: !0 });
@@ -11682,8 +11716,8 @@ Oi.post("/validate-unique", async (e) => {
11682
11716
  });
11683
11717
  //#endregion
11684
11718
  //#region server/routes/admin/stats.ts
11685
- var ji = new n();
11686
- ji.get("/", async (e) => {
11719
+ var Mi = new n();
11720
+ Mi.get("/", async (e) => {
11687
11721
  try {
11688
11722
  let t = e.get("db"), n = await t.prepare("\n SELECT \n COUNT(*) as total,\n SUM(CASE WHEN isHidden = 0 THEN 1 ELSE 0 END) as published,\n SUM(CASE WHEN isHidden = 1 THEN 1 ELSE 0 END) as hidden\n FROM content_nodes\n ").get(), r = Number(n?.total) || 0, i = Number(n?.published) || 0, a = Number(n?.hidden) || 0, o = await t.prepare("\n SELECT \n (SELECT COUNT(*) FROM channels) as totalChannels,\n (SELECT COUNT(*) FROM trees) as totalTrees,\n (SELECT COUNT(*) FROM users) as totalUsers\n ").get(), s = await t.prepare("\n SELECT contentType as type, COUNT(*) as count \n FROM content_nodes \n GROUP BY contentType \n ORDER BY count DESC\n ").all(), c = Array.isArray(s) ? s : s?.results || [], l = await t.prepare("\n SELECT id, title, slug, contentType, isHidden, status, updatedAt \n FROM content_nodes \n ORDER BY updatedAt DESC \n LIMIT 5\n ").all(), u = (Array.isArray(l) ? l : l?.results || []).map((e) => ({
11689
11723
  ...e,
@@ -11726,7 +11760,7 @@ ji.get("/", async (e) => {
11726
11760
  });
11727
11761
  //#endregion
11728
11762
  //#region server/storage/provider.ts
11729
- function Mi(e) {
11763
+ function Ni(e) {
11730
11764
  let t = e.split(".").pop()?.toLowerCase() || "bin";
11731
11765
  return t = t.replace(/[^a-z0-9]/g, ""), [
11732
11766
  "php",
@@ -11741,14 +11775,14 @@ function Mi(e) {
11741
11775
  "cjs"
11742
11776
  ].includes(t) ? "bin" : t;
11743
11777
  }
11744
- var Ni = class {
11778
+ var Pi = class {
11745
11779
  bucket;
11746
11780
  publicDomain;
11747
11781
  constructor(e, t) {
11748
11782
  this.bucket = e, this.publicDomain = t;
11749
11783
  }
11750
11784
  async upload(e, t = "uploads") {
11751
- let n = Mi(e.name), r = `${t}/${crypto.randomUUID().replace(/-/g, "")}.${n}`;
11785
+ let n = Ni(e.name), r = `${t}/${crypto.randomUUID().replace(/-/g, "")}.${n}`;
11752
11786
  return await this.bucket.put(r, e.stream(), { httpMetadata: { contentType: e.type } }), {
11753
11787
  key: r,
11754
11788
  url: `/media/${r.replace(/^\//, "")}`
@@ -11757,7 +11791,7 @@ var Ni = class {
11757
11791
  async delete(e) {
11758
11792
  await this.bucket.delete(e);
11759
11793
  }
11760
- }, Pi = class {
11794
+ }, Fi = class {
11761
11795
  customStoragePath;
11762
11796
  constructor(e) {
11763
11797
  this.customStoragePath = e;
@@ -11775,7 +11809,7 @@ var Ni = class {
11775
11809
  ), { pipeline: a } = await import(
11776
11810
  /* @vite-ignore */
11777
11811
  "node:stream/promises"
11778
- ), o = Mi(e.name), s = `${t}/${crypto.randomUUID().replace(/-/g, "")}.${o}`, c = this.customStoragePath || "./public/media", l = n.resolve(process.cwd(), c), u = n.join(l, s);
11812
+ ), o = Ni(e.name), s = `${t}/${crypto.randomUUID().replace(/-/g, "")}.${o}`, c = this.customStoragePath || "./public/media", l = n.resolve(process.cwd(), c), u = n.join(l, s);
11779
11813
  await i.mkdir(n.dirname(u), { recursive: !0 });
11780
11814
  let d = r.createWriteStream(u);
11781
11815
  return await a(e.stream(), d), {
@@ -11798,16 +11832,16 @@ var Ni = class {
11798
11832
  }
11799
11833
  }
11800
11834
  };
11801
- function Fi(e) {
11835
+ function Ii(e) {
11802
11836
  if (e.MEDIA_BUCKET) {
11803
11837
  let t = e.CDN_DOMAIN || "cdn.yourdomain.com";
11804
- return new Ni(e.MEDIA_BUCKET, t);
11838
+ return new Pi(e.MEDIA_BUCKET, t);
11805
11839
  }
11806
- return new Pi(e.LOCAL_MEDIA_PATH);
11840
+ return new Fi(e.LOCAL_MEDIA_PATH);
11807
11841
  }
11808
11842
  //#endregion
11809
11843
  //#region server/routes/admin/assets.ts
11810
- var Ii = new n();
11844
+ var Li = new n();
11811
11845
  async function Q(e, t, n = []) {
11812
11846
  let r = e.prepare(t);
11813
11847
  if (typeof r.bind == "function") {
@@ -11820,19 +11854,19 @@ async function Q(e, t, n = []) {
11820
11854
  }
11821
11855
  return [];
11822
11856
  }
11823
- async function Li(e, t, n = []) {
11857
+ async function Ri(e, t, n = []) {
11824
11858
  let r = e.prepare(t);
11825
11859
  if (typeof r.bind == "function") return await r.bind(...n).run();
11826
11860
  if (typeof r.run == "function") return await r.run(...n);
11827
11861
  }
11828
- function Ri(e, t) {
11862
+ function zi(e, t) {
11829
11863
  let n = e || (t ? `/media/${t}` : "");
11830
11864
  try {
11831
11865
  n.startsWith("http") && (n = new URL(n).pathname);
11832
11866
  } catch {}
11833
11867
  return n.startsWith("/media/") || (n = `/media/${n.replace(/^\/+/, "")}`), n;
11834
11868
  }
11835
- Ii.get("/", async (e) => {
11869
+ Li.get("/", async (e) => {
11836
11870
  try {
11837
11871
  let t = zr(e), { search: n = "", type: r = "all", page: i = "1", limit: a = "24", sort: o = "createdAt", order: s = "DESC", nodeId: c, channelId: l, trashed: u } = e.req.query(), d = Math.max(1, parseInt(i, 10) || 1), f = Math.max(1, Math.min(100, parseInt(a, 10) || 24)), p = (d - 1) * f, m = {
11838
11872
  createdAt: "a.createdAt",
@@ -11899,7 +11933,7 @@ Ii.get("/", async (e) => {
11899
11933
  ...JSON.parse(e.dataJson || "{}")
11900
11934
  };
11901
11935
  } catch {}
11902
- let n = Ri(e.cdnUrl, e.storageKeyPrivate);
11936
+ let n = zi(e.cdnUrl, e.storageKeyPrivate);
11903
11937
  return {
11904
11938
  id: e.id,
11905
11939
  filename: e.filename || "Untitled Asset",
@@ -11923,9 +11957,9 @@ Ii.get("/", async (e) => {
11923
11957
  details: t.message || String(t)
11924
11958
  }, 500);
11925
11959
  }
11926
- }), Ii.post("/upload", async (e) => {
11960
+ }), Li.post("/upload", async (e) => {
11927
11961
  try {
11928
- let t = zr(e), n = Fi(e.env), r = await e.req.parseBody(), i = r.file, a = r.isVariant === "true" || r.isVariant === "1" || r.temporary === "true", o = r.parentAssetId || r.parentAsset, s = typeof o == "string" && o.trim().length > 0 ? o.trim() : null;
11962
+ let t = zr(e), n = Ii(e.env), r = await e.req.parseBody(), i = r.file, a = r.isVariant === "true" || r.isVariant === "1" || r.temporary === "true", o = r.parentAssetId || r.parentAsset, s = typeof o == "string" && o.trim().length > 0 ? o.trim() : null;
11929
11963
  s && (await Q(t, "SELECT id FROM assets WHERE id = ?", [s])).length === 0 && (s = null);
11930
11964
  let c = r.cropCoordinates, l = null, u = null;
11931
11965
  if (c) {
@@ -11942,7 +11976,7 @@ Ii.get("/", async (e) => {
11942
11976
  let v = `/media/${_.replace(/^\//, "")}`, y = i.type || "application/octet-stream", b = i.size || 0, x = e.get("userId"), S = typeof x == "string" && x.trim().length > 0 ? x : null;
11943
11977
  S && (await Q(t, "SELECT id FROM users WHERE id = ?", [S])).length === 0 && (S = null);
11944
11978
  let C = +!!m;
11945
- await Li(t, "\n INSERT INTO assets (id, filename, mimeType, sizeBytes, storageKeyPrivate, cdnUrl, createdById, isSystemVariant, parentAssetId, cropCoordinatesJson)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ", [
11979
+ await Ri(t, "\n INSERT INTO assets (id, filename, mimeType, sizeBytes, storageKeyPrivate, cdnUrl, createdById, isSystemVariant, parentAssetId, cropCoordinatesJson)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ", [
11946
11980
  f,
11947
11981
  i.name,
11948
11982
  y,
@@ -11957,7 +11991,7 @@ Ii.get("/", async (e) => {
11957
11991
  let w = v;
11958
11992
  if (s) {
11959
11993
  let n = await Q(t, "SELECT cdnUrl, storageKeyPrivate FROM assets WHERE id = ?", [s]);
11960
- n.length > 0 && (w = Ri(n[0].cdnUrl, n[0].storageKeyPrivate)), new X(e.env).purgeAsset(e, t, s);
11994
+ n.length > 0 && (w = zi(n[0].cdnUrl, n[0].storageKeyPrivate)), new X(e.env).purgeAsset(e, t, s);
11961
11995
  }
11962
11996
  return e.json({
11963
11997
  id: f,
@@ -11976,7 +12010,7 @@ Ii.get("/", async (e) => {
11976
12010
  details: t.message || String(t)
11977
12011
  }, 500);
11978
12012
  }
11979
- }), Ii.get("/:id/details", async (e) => {
12013
+ }), Li.get("/:id/details", async (e) => {
11980
12014
  try {
11981
12015
  let t = zr(e), n = e.req.param("id"), r = await Q(t, "SELECT * FROM assets WHERE id = ?", [n]);
11982
12016
  if (!r || r.length === 0) return e.json({ error: "Asset not found" }, 404);
@@ -11999,7 +12033,7 @@ Ii.get("/", async (e) => {
11999
12033
  ...JSON.parse(i.dataJson || "{}")
12000
12034
  };
12001
12035
  } catch {}
12002
- let l = Ri(i.cdnUrl, i.storageKeyPrivate);
12036
+ let l = zi(i.cdnUrl, i.storageKeyPrivate);
12003
12037
  return e.json({
12004
12038
  id: i.id,
12005
12039
  filename: i.filename,
@@ -12026,7 +12060,7 @@ Ii.get("/", async (e) => {
12026
12060
  createdAt: e.createdAt,
12027
12061
  parentAssetId: e.parentAssetId || i.id,
12028
12062
  cropCoordinates: t,
12029
- url: Ri(e.cdnUrl, e.storageKeyPrivate),
12063
+ url: zi(e.cdnUrl, e.storageKeyPrivate),
12030
12064
  originalUrl: l
12031
12065
  };
12032
12066
  })
@@ -12034,7 +12068,7 @@ Ii.get("/", async (e) => {
12034
12068
  } catch (t) {
12035
12069
  return console.error("❌ [Asset Details Error]:", t), e.json({ error: "Failed to load details" }, 500);
12036
12070
  }
12037
- }), Ii.put("/:id", async (e) => {
12071
+ }), Li.put("/:id", async (e) => {
12038
12072
  try {
12039
12073
  let t = zr(e), n = e.req.param("id"), r = await e.req.json(), i = await Q(t, "SELECT filename, dataJson FROM assets WHERE id = ?", [n]);
12040
12074
  if (!i || i.length === 0) return e.json({ error: "Asset not found" }, 404);
@@ -12042,7 +12076,7 @@ Ii.get("/", async (e) => {
12042
12076
  try {
12043
12077
  o = JSON.parse(a.dataJson || "{}");
12044
12078
  } catch {}
12045
- return r.title !== void 0 && (o.title = r.title), r.alt !== void 0 && (o.alt = r.alt), r.description !== void 0 && (o.description = r.description), await Li(t, "UPDATE assets SET filename = ?, dataJson = ?, updatedAt = CURRENT_TIMESTAMP WHERE id = ?", [
12079
+ return r.title !== void 0 && (o.title = r.title), r.alt !== void 0 && (o.alt = r.alt), r.description !== void 0 && (o.description = r.description), await Ri(t, "UPDATE assets SET filename = ?, dataJson = ?, updatedAt = CURRENT_TIMESTAMP WHERE id = ?", [
12046
12080
  r.filename === void 0 ? a.filename : r.filename,
12047
12081
  JSON.stringify(o),
12048
12082
  n
@@ -12050,10 +12084,10 @@ Ii.get("/", async (e) => {
12050
12084
  } catch (t) {
12051
12085
  return console.error("❌ [Asset Update Error]:", t), e.json({ error: "Failed to update asset" }, 500);
12052
12086
  }
12053
- }), Ii.delete("/:id", async (e) => {
12087
+ }), Li.delete("/:id", async (e) => {
12054
12088
  try {
12055
12089
  let t = zr(e), n = e.req.param("id"), r = (await Q(t, "SELECT id, filename, isSystemVariant FROM assets WHERE id = ?", [n]))[0];
12056
- return r ? (new X(e.env).purgeAsset(e, t, n), r.isSystemVariant ? await Li(t, "UPDATE assets SET deletedAt = CURRENT_TIMESTAMP WHERE id = ?", [n]) : await Li(t, "UPDATE assets\n SET deletedAt = CURRENT_TIMESTAMP\n WHERE id = ? OR parentAssetId = ? OR (isSystemVariant = 1 AND (filename LIKE ? OR filename LIKE ?))", [
12090
+ return r ? (new X(e.env).purgeAsset(e, t, n), r.isSystemVariant ? await Ri(t, "UPDATE assets SET deletedAt = CURRENT_TIMESTAMP WHERE id = ?", [n]) : await Ri(t, "UPDATE assets\n SET deletedAt = CURRENT_TIMESTAMP\n WHERE id = ? OR parentAssetId = ? OR (isSystemVariant = 1 AND (filename LIKE ? OR filename LIKE ?))", [
12057
12091
  n,
12058
12092
  n,
12059
12093
  `crop_%${r.filename ? r.filename.replace(/\.[^/.]+$/, "") : ""}%`,
@@ -12069,12 +12103,12 @@ Ii.get("/", async (e) => {
12069
12103
  details: t.message || String(t)
12070
12104
  }, 500);
12071
12105
  }
12072
- }), Ii.post("/restore", async (e) => {
12106
+ }), Li.post("/restore", async (e) => {
12073
12107
  try {
12074
12108
  let t = zr(e), n = await e.req.json(), r = n.id || n.assetId;
12075
12109
  if (!r) return e.json({ error: "Asset ID required" }, 400);
12076
12110
  let i = (await Q(t, "SELECT id, filename FROM assets WHERE id = ?", [r]))[0];
12077
- return i ? (await Li(t, "UPDATE assets \n SET deletedAt = NULL \n WHERE id = ? OR parentAssetId = ? OR (isSystemVariant = 1 AND (filename LIKE ? OR filename LIKE ?))", [
12111
+ return i ? (await Ri(t, "UPDATE assets \n SET deletedAt = NULL \n WHERE id = ? OR parentAssetId = ? OR (isSystemVariant = 1 AND (filename LIKE ? OR filename LIKE ?))", [
12078
12112
  r,
12079
12113
  r,
12080
12114
  `crop_%${i.filename ? i.filename.replace(/\.[^/.]+$/, "") : ""}%`,
@@ -12090,9 +12124,9 @@ Ii.get("/", async (e) => {
12090
12124
  details: t.message
12091
12125
  }, 500);
12092
12126
  }
12093
- }), Ii.delete("/purge/:id", async (e) => {
12127
+ }), Li.delete("/purge/:id", async (e) => {
12094
12128
  try {
12095
- let t = zr(e), n = Fi(e.env), r = e.req.param("id"), i = (await Q(t, "SELECT id, filename, storageKeyPrivate, isSystemVariant FROM assets WHERE id = ?", [r]))[0];
12129
+ let t = zr(e), n = Ii(e.env), r = e.req.param("id"), i = (await Q(t, "SELECT id, filename, storageKeyPrivate, isSystemVariant FROM assets WHERE id = ?", [r]))[0];
12096
12130
  if (!i) return e.json({ error: "Asset not found" }, 404);
12097
12131
  new X(e.env).purgeAsset(e, t, r);
12098
12132
  let a = [i];
@@ -12110,7 +12144,7 @@ Ii.get("/", async (e) => {
12110
12144
  }
12111
12145
  }
12112
12146
  let s = o.map(() => "?").join(",");
12113
- return await Li(t, `DELETE FROM node_assets WHERE assetId IN (${s})`, o), await Li(t, `DELETE FROM assets WHERE id IN (${s})`, o), e.json({
12147
+ return await Ri(t, `DELETE FROM node_assets WHERE assetId IN (${s})`, o), await Ri(t, `DELETE FROM assets WHERE id IN (${s})`, o), e.json({
12114
12148
  success: !0,
12115
12149
  id: r,
12116
12150
  purged: !0,
@@ -12126,14 +12160,14 @@ Ii.get("/", async (e) => {
12126
12160
  });
12127
12161
  //#endregion
12128
12162
  //#region server/routes/public/node.ts
12129
- var zi = new n();
12130
- function Bi(e, t) {
12163
+ var Bi = new n();
12164
+ function Vi(e, t) {
12131
12165
  let n = Promise.resolve(t).catch((e) => console.error("[Background Task Error]:", e));
12132
12166
  try {
12133
12167
  e.executionCtx && typeof e.executionCtx.waitUntil == "function" && e.executionCtx.waitUntil(n);
12134
12168
  } catch {}
12135
12169
  }
12136
- function Vi() {
12170
+ function Hi() {
12137
12171
  return {
12138
12172
  fullPath: /* @__PURE__ */ new Map(),
12139
12173
  treeEdges: /* @__PURE__ */ new Map(),
@@ -12141,15 +12175,15 @@ function Vi() {
12141
12175
  assetUrls: /* @__PURE__ */ new Map()
12142
12176
  };
12143
12177
  }
12144
- function Hi(...e) {
12178
+ function Ui(...e) {
12145
12179
  return e.map((e) => String(e ?? "")).join(":");
12146
12180
  }
12147
- function Ui(e) {
12181
+ function Wi(e) {
12148
12182
  if (!e || String(e).trim() === "") return null;
12149
12183
  let t = new Date(e.includes("T") ? e : e.replace(" ", "T") + "Z");
12150
12184
  return isNaN(t.getTime()) ? e : t.toISOString();
12151
12185
  }
12152
- function Wi(e, t) {
12186
+ function Gi(e, t) {
12153
12187
  let n = Date.now();
12154
12188
  if (e && String(e).trim() !== "") {
12155
12189
  let t = Date.parse(e);
@@ -12161,7 +12195,7 @@ function Wi(e, t) {
12161
12195
  }
12162
12196
  return !0;
12163
12197
  }
12164
- async function Gi(e, t, n) {
12198
+ async function Ki(e, t, n) {
12165
12199
  let r = t.filter((e) => e.componentId === "content-feed" || e.componentId === "article-list");
12166
12200
  await Promise.all(r.map(async (t) => {
12167
12201
  let r = t.data || {}, i = r.nodeType || "article", a = Number(r.limit) || 12, o = r.sortBy || "updatedAt", s = "FROM content_nodes WHERE contentType = ? AND isHidden = 0 AND (status = 'published' OR status IS NULL)", c = [i];
@@ -12175,13 +12209,13 @@ async function Gi(e, t, n) {
12175
12209
  if (e.dataJson) try {
12176
12210
  t = typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson;
12177
12211
  } catch {}
12178
- return Wi(t.startShowingAt, t.stopShowingAt) ? {
12212
+ return Gi(t.startShowingAt, t.stopShowingAt) ? {
12179
12213
  id: e.id,
12180
12214
  title: e.title,
12181
12215
  slug: e.slug,
12182
12216
  language: e.language || "en",
12183
- createdAt: Ui(e.createdAt),
12184
- updatedAt: Ui(e.updatedAt),
12217
+ createdAt: Wi(e.createdAt),
12218
+ updatedAt: Wi(e.updatedAt),
12185
12219
  excerpt: t.excerpt || "",
12186
12220
  image: t.image || t.coverImage || null,
12187
12221
  author: t.author || null
@@ -12192,7 +12226,7 @@ async function Gi(e, t, n) {
12192
12226
  }
12193
12227
  }));
12194
12228
  }
12195
- async function Ki(e, t, n, r, i = !1, a) {
12229
+ async function qi(e, t, n, r, i = !1, a) {
12196
12230
  if (!t) return { blocks: [] };
12197
12231
  let o = await e.prepare("\n WITH RECURSIVE ancestor_path(id, contentId, title, slug, parentId, level) AS (\n SELECT t.id, t.contentId, c.title, c.slug, t.parentId, 0 FROM tree_nodes t INNER JOIN content_nodes c ON t.contentId = c.id WHERE t.id = ? OR c.id = ?\n UNION ALL\n SELECT t.id, t.contentId, c.title, c.slug, t.parentId, ap.level + 1 FROM tree_nodes t INNER JOIN content_nodes c ON t.contentId = c.id INNER JOIN ancestor_path ap ON t.id = ap.parentId\n ) SELECT * FROM ancestor_path ORDER BY level ASC\n ").all(t, t), s = Array.isArray(o) ? o : o?.results || [];
12198
12232
  if (!s || s.length === 0) return { blocks: [] };
@@ -12233,10 +12267,10 @@ async function Ki(e, t, n, r, i = !1, a) {
12233
12267
  try {
12234
12268
  a = (typeof t.dataJson == "string" ? JSON.parse(t.dataJson) : t.dataJson) || {};
12235
12269
  } catch {}
12236
- let o = a.hidden === !0 || a.hidden === 1 || a.hidden === "1" || a.hidden === "true", s = Wi(a.startShowingAt, a.stopShowingAt);
12270
+ let o = a.hidden === !0 || a.hidden === 1 || a.hidden === "1" || a.hidden === "true", s = Gi(a.startShowingAt, a.stopShowingAt);
12237
12271
  if (!i && (o || !s)) return null;
12238
- let c = t.elementType || t.componentId || "text-block", l = r.blocks?.[c]?.fields || r.elements?.[c]?.fields || r.components?.[c]?.fields || {}, u = String(a.blockId || a._instanceId || (a.id && !String(a.id).startsWith("ast_") ? a.id : null) || t.blockId || t.id), d = qi(a, l);
12239
- return d = await ui(e, d), d = Ji(d), d.blockId = u, {
12272
+ let c = t.elementType || t.componentId || "text-block", l = r.blocks?.[c]?.fields || r.elements?.[c]?.fields || r.components?.[c]?.fields || {}, u = String(a.blockId || a._instanceId || (a.id && !String(a.id).startsWith("ast_") ? a.id : null) || t.blockId || t.id), d = Ji(a, l);
12273
+ return d = await ui(e, d), d = Yi(d), d.blockId = u, {
12240
12274
  region: t.region || n,
12241
12275
  block: {
12242
12276
  instanceId: t.id,
@@ -12256,7 +12290,7 @@ async function Ki(e, t, n, r, i = !1, a) {
12256
12290
  }
12257
12291
  return { blocks: [] };
12258
12292
  }
12259
- function qi(e, t = {}) {
12293
+ function Ji(e, t = {}) {
12260
12294
  let n = {};
12261
12295
  for (let [r, i] of Object.entries(e)) {
12262
12296
  if (r === "id" && typeof i == "string" && i.startsWith("ast_")) {
@@ -12267,14 +12301,14 @@ function qi(e, t = {}) {
12267
12301
  }
12268
12302
  return n;
12269
12303
  }
12270
- function Ji(e) {
12271
- if (Array.isArray(e)) return e.map(Ji);
12304
+ function Yi(e) {
12305
+ if (Array.isArray(e)) return e.map(Yi);
12272
12306
  if (!e || typeof e != "object") return e;
12273
12307
  if (typeof e.id == "string" && e.id.startsWith("ast_") && typeof e.url == "string") {
12274
12308
  let t = e.metadataOverrides || {}, n = e.variants && typeof e.variants == "object" ? e.variants : {}, r = Object.entries(n).find(([, t]) => t?.id === e.id)?.[0], i = r ? {
12275
12309
  ...t,
12276
12310
  ...t.crops?.[r] || {}
12277
- } : t, a = Object.fromEntries(Object.entries(n).filter(([, t]) => t?.id !== e.id).map(([t, n]) => [t, Ji({
12311
+ } : t, a = Object.fromEntries(Object.entries(n).filter(([, t]) => t?.id !== e.id).map(([t, n]) => [t, Yi({
12278
12312
  ...n,
12279
12313
  title: n?.title ?? e.title ?? "",
12280
12314
  alt: n?.alt ?? e.alt ?? "",
@@ -12288,9 +12322,9 @@ function Ji(e) {
12288
12322
  ...Object.keys(a).length > 0 ? { variants: a } : {}
12289
12323
  };
12290
12324
  }
12291
- return Object.fromEntries(Object.entries(e).map(([e, t]) => [e, Ji(t)]));
12325
+ return Object.fromEntries(Object.entries(e).map(([e, t]) => [e, Yi(t)]));
12292
12326
  }
12293
- async function Yi(e, t, n) {
12327
+ async function Xi(e, t, n) {
12294
12328
  if (!t) return t;
12295
12329
  if (typeof t == "string") {
12296
12330
  if (!t.includes("#node:") && !t.includes("data-node-id") && !t.includes("#asset:") && !t.includes("data-asset-id")) return t;
@@ -12309,9 +12343,9 @@ async function Yi(e, t, n) {
12309
12343
  return await Promise.all(Array.from(t.matchAll(d)).map(async (t) => {
12310
12344
  let i = t[1], a = r(i, "data-node-id"), o = r(i, "data-tree-id");
12311
12345
  if (!a || !o) return;
12312
- let s = await Zi(e, a, o, n);
12346
+ let s = await Qi(e, a, o, n);
12313
12347
  if (s?.treeNodeId) {
12314
- let t = await ta(e, String(s.treeNodeId), o, n);
12348
+ let t = await na(e, String(s.treeNodeId), o, n);
12315
12349
  u.set(`${a}:${o}`, t);
12316
12350
  }
12317
12351
  })), t.replace(d, (e, t) => {
@@ -12331,41 +12365,41 @@ async function Yi(e, t, n) {
12331
12365
  return /href\s*=/.test(h) || (h += ` href="${m || "/"}"`), `<a ${h}>`;
12332
12366
  });
12333
12367
  }
12334
- if (Array.isArray(t)) return Promise.all(t.map((t) => Yi(e, t, n)));
12368
+ if (Array.isArray(t)) return Promise.all(t.map((t) => Xi(e, t, n)));
12335
12369
  if (typeof t == "object") {
12336
12370
  let r = JSON.stringify(t);
12337
12371
  if (!r.includes("#node:") && !r.includes("data-node-id") && !r.includes("#asset:") && !r.includes("data-asset-id")) return t;
12338
12372
  if (typeof t.href == "string" && (t.href.startsWith("#node:") || t.href.startsWith("#asset:"))) return {
12339
12373
  ...t,
12340
- href: await Xi(e, t, n)
12374
+ href: await Zi(e, t, n)
12341
12375
  };
12342
- let i = await Promise.all(Object.entries(t).map(async ([t, r]) => [t, await Yi(e, r, n)]));
12376
+ let i = await Promise.all(Object.entries(t).map(async ([t, r]) => [t, await Xi(e, r, n)]));
12343
12377
  return Object.fromEntries(i);
12344
12378
  }
12345
12379
  return t;
12346
12380
  }
12347
- async function Xi(e, t, n) {
12381
+ async function Zi(e, t, n) {
12348
12382
  let r = t.href.match(/^#node:(.+)$/), i = t.href.match(/^#asset:(.+)$/);
12349
- if (i) return $i(e, i[1], n);
12383
+ if (i) return ea(e, i[1], n);
12350
12384
  if (!r) return t.href;
12351
12385
  let a = r[1];
12352
12386
  if (t.treeId) {
12353
- let r = await Zi(e, a, String(t.treeId), n);
12387
+ let r = await Qi(e, a, String(t.treeId), n);
12354
12388
  if (r?.treeNodeId) {
12355
- let i = await ta(e, String(r.treeNodeId), String(t.treeId), n);
12389
+ let i = await na(e, String(r.treeNodeId), String(t.treeId), n);
12356
12390
  if (i) return i;
12357
12391
  }
12358
12392
  }
12359
- let o = await Qi(e, a, n);
12393
+ let o = await $i(e, a, n);
12360
12394
  return o === void 0 ? "#" : `/${o}`;
12361
12395
  }
12362
- async function Zi(e, t, n, r) {
12363
- let i = Hi(t, n);
12396
+ async function Qi(e, t, n, r) {
12397
+ let i = Ui(t, n);
12364
12398
  if (r.treeEdges.has(i)) return r.treeEdges.get(i);
12365
12399
  let a = e.prepare("SELECT id as treeNodeId FROM tree_nodes WHERE contentId = ? AND treeId = ? LIMIT 1").get(t, n);
12366
12400
  return r.treeEdges.set(i, Promise.resolve(a)), a;
12367
12401
  }
12368
- async function Qi(e, t, n) {
12402
+ async function $i(e, t, n) {
12369
12403
  let r = String(t);
12370
12404
  if (n.nodeSlugs.has(r)) return n.nodeSlugs.get(r);
12371
12405
  let i = (async () => {
@@ -12374,7 +12408,7 @@ async function Qi(e, t, n) {
12374
12408
  })();
12375
12409
  return n.nodeSlugs.set(r, i), i;
12376
12410
  }
12377
- async function $i(e, t, n) {
12411
+ async function ea(e, t, n) {
12378
12412
  let r = String(t);
12379
12413
  if (n.assetUrls.has(r)) return n.assetUrls.get(r);
12380
12414
  let i = (async () => {
@@ -12383,7 +12417,7 @@ async function $i(e, t, n) {
12383
12417
  })();
12384
12418
  return n.assetUrls.set(r, i), i;
12385
12419
  }
12386
- function ea(e) {
12420
+ function ta(e) {
12387
12421
  let t = e.socialImage;
12388
12422
  if (!t || typeof t != "object") return null;
12389
12423
  let n = (e, t) => {
@@ -12414,9 +12448,9 @@ function ea(e) {
12414
12448
  ])
12415
12449
  };
12416
12450
  }
12417
- async function ta(e, t, n, r) {
12451
+ async function na(e, t, n, r) {
12418
12452
  if (!t) return "";
12419
- let i = Hi(t, n);
12453
+ let i = Ui(t, n);
12420
12454
  if (r && r.fullPath.has(i)) return r.fullPath.get(i);
12421
12455
  let a = (async () => {
12422
12456
  let r = await e.prepare("\n WITH RECURSIVE ancestor_path(id, parentId, slug, level) AS (\n SELECT t.id, t.parentId, c.slug, 0 FROM tree_nodes t INNER JOIN content_nodes c ON t.contentId = c.id WHERE t.id = ? AND t.treeId = ?\n UNION ALL\n SELECT t.id, t.parentId, c.slug, ap.level + 1 FROM tree_nodes t INNER JOIN content_nodes c ON t.contentId = c.id INNER JOIN ancestor_path ap ON t.id = ap.parentId WHERE t.treeId = ?\n ) SELECT slug FROM ancestor_path ORDER BY level DESC\n ").all(t, n, n), i = Array.isArray(r) ? r : r?.results || [], a = [];
@@ -12428,7 +12462,7 @@ async function ta(e, t, n, r) {
12428
12462
  })();
12429
12463
  return r && r.fullPath.set(i, a), a;
12430
12464
  }
12431
- async function na(e, t, n, r, i) {
12465
+ async function ra(e, t, n, r, i) {
12432
12466
  let a = {}, o = null;
12433
12467
  if (t) {
12434
12468
  let n = await e.prepare("\n WITH RECURSIVE ancestor_path(id, contentId, title, slug, parentId, level) AS (\n SELECT t.id, t.contentId, c.title, c.slug, t.parentId, 0 FROM tree_nodes t INNER JOIN content_nodes c ON t.contentId = c.id WHERE t.id = ? OR c.id = ?\n UNION ALL\n SELECT t.id, t.contentId, c.title, c.slug, t.parentId, ap.level + 1 FROM tree_nodes t INNER JOIN content_nodes c ON t.contentId = c.id INNER JOIN ancestor_path ap ON t.id = ap.parentId\n ) SELECT c.dataJson, c.draftDataJson FROM ancestor_path ap INNER JOIN content_nodes c ON ap.contentId = c.id ORDER BY ap.level ASC\n ").all(t, t), i = Array.isArray(n) ? n : n?.results || [], s = /* @__PURE__ */ new Set([
@@ -12466,13 +12500,13 @@ async function na(e, t, n, r, i) {
12466
12500
  inheritedFields: a
12467
12501
  };
12468
12502
  }
12469
- function ra(e) {
12503
+ function ia(e) {
12470
12504
  let t = Number(e?.env?.CMS_NODE_CACHE_TTL);
12471
12505
  return Number.isFinite(t) && t >= 60 ? Math.floor(t) : 300;
12472
12506
  }
12473
- zi.get("/*", async (e) => {
12507
+ Bi.get("/*", async (e) => {
12474
12508
  try {
12475
- let t = e.get("db"), n = Vi(), r = new URL(e.req.url).pathname.match(/\/node\/(.+)$/), i = (r ? r[1] : "home").replace(/^\/+|\/+$/g, ""), a = e.req.query("channelId") || e.req.query("channel") || "1", o = e.req.query("lang") || "en", s = e.req.query("preview") === "true", c = isNaN(Number(a)) ? await t.prepare("SELECT * FROM channels WHERE key = ?").get(a) : await t.prepare("SELECT * FROM channels WHERE id = ?").get(Number(a));
12509
+ let t = e.get("db"), n = Hi(), r = new URL(e.req.url).pathname.match(/\/node\/(.+)$/), i = (r ? r[1] : "home").replace(/^\/+|\/+$/g, ""), a = e.req.query("channelId") || e.req.query("channel") || "1", o = e.req.query("lang") || "en", s = e.req.query("preview") === "true", c = isNaN(Number(a)) ? await t.prepare("SELECT * FROM channels WHERE key = ?").get(a) : await t.prepare("SELECT * FROM channels WHERE id = ?").get(Number(a));
12476
12510
  if (!c) return e.json({ error: `Channel '${a}' not found` }, 404);
12477
12511
  let l = c.status === "disabled" || c.status === "inactive" || c.isEnabled === 0 || c.isEnabled === !1;
12478
12512
  if (!s && l) return e.json({ error: `Channel '${c.key || a}' is currently inactive` }, 404);
@@ -12491,7 +12525,7 @@ zi.get("/*", async (e) => {
12491
12525
  if (E.length > 0) {
12492
12526
  let e = await Promise.all(E.map(async (e) => ({
12493
12527
  candidate: e,
12494
- calculatedPath: await ta(t, String(e.treeNodeId), String(e.treeId), n)
12528
+ calculatedPath: await na(t, String(e.treeNodeId), String(e.treeId), n)
12495
12529
  }))), r = S.replace(/^\/+|\/+$/g, "");
12496
12530
  for (let { candidate: t, calculatedPath: n } of e) {
12497
12531
  let e = n.replace(/^\/+|\/+$/g, "");
@@ -12506,7 +12540,7 @@ zi.get("/*", async (e) => {
12506
12540
  let e = y ? [_.id, y] : [_.id];
12507
12541
  v = await t.prepare(`SELECT id as treeNodeId, treeId, parentId FROM tree_nodes WHERE contentId = ? ${y ? "AND treeId = ?" : ""} LIMIT 1`).get(...e);
12508
12542
  }
12509
- let D = v?.treeId || y || "main-nav", O = v?.parentId || null, ee = v?.treeNodeId ? await ta(t, String(v.treeNodeId), String(D), n) : `/${(_.slug || "").replace(/^\/+|\/+$/g, "")}`, k = {}, te = s && _.draftDataJson ? _.draftDataJson : _.dataJson || _.draftDataJson;
12543
+ let D = v?.treeId || y || "main-nav", O = v?.parentId || null, ee = v?.treeNodeId ? await na(t, String(v.treeNodeId), String(D), n) : `/${(_.slug || "").replace(/^\/+|\/+$/g, "")}`, k = {}, te = s && _.draftDataJson ? _.draftDataJson : _.dataJson || _.draftDataJson;
12510
12544
  if (te) try {
12511
12545
  k = typeof te == "string" ? JSON.parse(te) : te;
12512
12546
  } catch {}
@@ -12515,7 +12549,7 @@ zi.get("/*", async (e) => {
12515
12549
  Object.assign(j, e.fields || {});
12516
12550
  });
12517
12551
  let ie = +!!s, [ae, oe, M] = await Promise.all([
12518
- na(t, O, D, s, j),
12552
+ ra(t, O, D, s, j),
12519
12553
  v?.treeNodeId ? t.prepare("SELECT t.id as treeNodeId, t.contentId as id, c.title, c.slug, c.language, c.contentType as nodeType, c.isHidden, c.dataJson, c.draftDataJson FROM tree_nodes t INNER JOIN content_nodes c ON t.contentId = c.id WHERE t.parentId = ? AND t.treeId = ? ORDER BY t.sortOrder ASC").all(v.treeNodeId, D) : Promise.resolve([]),
12520
12554
  t.prepare("SELECT * FROM content_blocks WHERE contentId = ? AND isDraft = ? ORDER BY sortOrder ASC").all(_.id, ie)
12521
12555
  ]), { resolvedLayoutId: N, inheritedFields: se } = ae, P = {
@@ -12524,10 +12558,10 @@ zi.get("/*", async (e) => {
12524
12558
  slug: _.slug,
12525
12559
  path: ee === "" ? "/" : ee,
12526
12560
  nodeType: ne,
12527
- createdAt: Ui(_.createdAt),
12528
- updatedAt: Ui(_.updatedAt),
12529
- publishedAt: Ui(k.publishedAt || _.createdAt)
12530
- }, ce = k.disabledRegions || {}, le = k.hidden === !0 || k.hidden === 1 || k.hidden === "1" || k.hidden === "true", F = k.startShowingAt || null, ue = k.stopShowingAt || null, de = qi(k, j), fe = de.layoutId || null, pe = fe && fe !== "inherit", me = !1, I = null;
12561
+ createdAt: Wi(_.createdAt),
12562
+ updatedAt: Wi(_.updatedAt),
12563
+ publishedAt: Wi(k.publishedAt || _.createdAt)
12564
+ }, ce = k.disabledRegions || {}, le = k.hidden === !0 || k.hidden === 1 || k.hidden === "1" || k.hidden === "true", F = k.startShowingAt || null, ue = k.stopShowingAt || null, de = Ji(k, j), fe = de.layoutId || null, pe = fe && fe !== "inherit", me = !1, I = null;
12531
12565
  j.layoutId && (me = !0, j.layoutId.options && Array.isArray(j.layoutId.options) && (I = j.layoutId.options.map((e) => typeof e == "object" ? e.value || e.id : e)));
12532
12566
  let he = null;
12533
12567
  if (me && I && I.length === 1 && I[0] !== "inherit") he = I[0];
@@ -12538,10 +12572,10 @@ zi.get("/*", async (e) => {
12538
12572
  }
12539
12573
  for (let [e, t] of Object.entries(se)) j[e] && (de[e] === void 0 || de[e] === null || de[e] === "" || de[e] === "inherit") && t !== void 0 && (de[e] = t);
12540
12574
  let L = await ui(t, de);
12541
- L = Ji(L), L = await Yi(t, L, n);
12542
- let R = ea(L);
12575
+ L = Yi(L), L = await Xi(t, L, n);
12576
+ let R = ta(L);
12543
12577
  delete L.socialImage, delete L.fbImage, delete L.xImage, delete L.whatsappImage, R && (L.socialImages = R), delete L.id, delete L.title, delete L.slug, delete L.language, delete L.contentType, delete L.nodeType, delete L.createdAt, delete L.updatedAt, delete L.publishedAt, delete L.channelId, delete L.treeId, delete L.path, L.iconName === "" && (L.iconName = null), Object.assign(P, L), A.hasCanvas && (P.layoutId = he);
12544
- let ge = Number(_.isHidden) === 1 || le, _e = !Wi(F, ue);
12578
+ let ge = Number(_.isHidden) === 1 || le, _e = !Gi(F, ue);
12545
12579
  if (!s && (ge || _e)) return e.json({ error: "Node is hidden or outside its scheduled publishing window" }, 404);
12546
12580
  let ve = [];
12547
12581
  if (v?.treeNodeId) {
@@ -12551,7 +12585,7 @@ zi.get("/*", async (e) => {
12551
12585
  try {
12552
12586
  n = (typeof r == "string" ? JSON.parse(r) : r) || {};
12553
12587
  } catch {}
12554
- let i = Number(e.isHidden) === 1 || n.hidden === !0 || n.hidden === 1 || n.hidden === "1", a = Wi(n.startShowingAt, n.stopShowingAt), o = (e.slug || "").replace(/^\/+|\/+$/g, "");
12588
+ let i = Number(e.isHidden) === 1 || n.hidden === !0 || n.hidden === 1 || n.hidden === "1", a = Gi(n.startShowingAt, n.stopShowingAt), o = (e.slug || "").replace(/^\/+|\/+$/g, "");
12555
12589
  return !s && (i || !a) ? null : {
12556
12590
  treeNodeId: e.treeNodeId,
12557
12591
  id: e.id,
@@ -12574,10 +12608,10 @@ zi.get("/*", async (e) => {
12574
12608
  try {
12575
12609
  i = (typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson) || {};
12576
12610
  } catch {}
12577
- let a = i.hidden === !0 || i.hidden === 1 || i.hidden === "1" || i.hidden === "true", o = Wi(i.startShowingAt, i.stopShowingAt);
12611
+ let a = i.hidden === !0 || i.hidden === 1 || i.hidden === "1" || i.hidden === "true", o = Gi(i.startShowingAt, i.stopShowingAt);
12578
12612
  if (!s && (a || !o)) return null;
12579
- let c = e.elementType || e.componentId || "text-block", l = h.blocks?.[c]?.fields || h.elements?.[c]?.fields || h.components?.[c]?.fields || {}, u = String(i.blockId || i._instanceId || (i.id && !String(i.id).startsWith("ast_") ? i.id : null) || e.blockId || e.id), d = qi(i, l);
12580
- return d = await ui(t, d), d = Ji(d), d = await Yi(t, d, n), d.blockId = u, {
12613
+ let c = e.elementType || e.componentId || "text-block", l = h.blocks?.[c]?.fields || h.elements?.[c]?.fields || h.components?.[c]?.fields || {}, u = String(i.blockId || i._instanceId || (i.id && !String(i.id).startsWith("ast_") ? i.id : null) || e.blockId || e.id), d = Ji(i, l);
12614
+ return d = await ui(t, d), d = Yi(d), d = await Xi(t, d, n), d.blockId = u, {
12581
12615
  region: r,
12582
12616
  block: {
12583
12617
  instanceId: e.id,
@@ -12602,7 +12636,7 @@ zi.get("/*", async (e) => {
12602
12636
  for (let [e, r] of Object.entries(xe)) {
12603
12637
  let i = z[e] && z[e].length > 0, a = !!ce[e];
12604
12638
  if (z[e] || (z[e] = [], B[e] = { isInherited: !1 }), (r?.inherit === "parent" || r?.inherit === !0 || r?.inherit === "true" || e === "header" || e === "footer") && !i && !a && O) {
12605
- let r = await Ki(t, O, e, h, s, n);
12639
+ let r = await qi(t, O, e, h, s, n);
12606
12640
  if (r.blocks.length > 0 && (z[e] = r.blocks, B[e] = {
12607
12641
  isInherited: !0,
12608
12642
  inheritedFromId: r.inheritedFromId,
@@ -12614,7 +12648,7 @@ zi.get("/*", async (e) => {
12614
12648
  });
12615
12649
  }
12616
12650
  }
12617
- await Promise.all(Object.keys(z).map((e) => Gi(t, z[e], u)));
12651
+ await Promise.all(Object.keys(z).map((e) => Ki(t, z[e], u)));
12618
12652
  let Se = {
12619
12653
  channelId: u || d,
12620
12654
  treeId: D,
@@ -12623,7 +12657,7 @@ zi.get("/*", async (e) => {
12623
12657
  content: z,
12624
12658
  regionMeta: B
12625
12659
  };
12626
- return !s && !m ? (e.header("X-Cache", "MISS"), Bi(e, f.set(p, Se, ra(e)))) : e.header("Cache-Control", "no-store, no-cache, must-revalidate"), e.json(Se);
12660
+ return !s && !m ? (e.header("X-Cache", "MISS"), Vi(e, f.set(p, Se, ia(e)))) : e.header("Cache-Control", "no-store, no-cache, must-revalidate"), e.json(Se);
12627
12661
  } catch (t) {
12628
12662
  console.error("[CMS Public API] Error fetching node by path:", t);
12629
12663
  let n = e.env?.ENVIRONMENT === "development";
@@ -12635,14 +12669,14 @@ zi.get("/*", async (e) => {
12635
12669
  });
12636
12670
  //#endregion
12637
12671
  //#region server/routes/public/tree.ts
12638
- var ia = new n();
12639
- function aa(e, t) {
12672
+ var aa = new n();
12673
+ function oa(e, t) {
12640
12674
  let n = Promise.resolve(t).catch((e) => console.error("[Background Task Error]:", e));
12641
12675
  try {
12642
12676
  e.executionCtx && typeof e.executionCtx.waitUntil == "function" && e.executionCtx.waitUntil(n);
12643
12677
  } catch {}
12644
12678
  }
12645
- function oa(e, t) {
12679
+ function sa(e, t) {
12646
12680
  let n = /* @__PURE__ */ new Date();
12647
12681
  if (e && String(e).trim() !== "") {
12648
12682
  let t = new Date(e);
@@ -12654,7 +12688,7 @@ function oa(e, t) {
12654
12688
  }
12655
12689
  return !0;
12656
12690
  }
12657
- ia.get("/:treeParam", async (e) => {
12691
+ aa.get("/:treeParam", async (e) => {
12658
12692
  try {
12659
12693
  let t = e.get("db"), n = e.req.param("treeParam"), r = e.req.query("channelId") || e.req.query("channel") || "default", i = e.req.query("preview") === "true";
12660
12694
  if (r && r !== "default" && r !== "all") {
@@ -12732,7 +12766,7 @@ ia.get("/:treeParam", async (e) => {
12732
12766
  "isHidden",
12733
12767
  "status"
12734
12768
  ].includes(e) || (r[e] = t);
12735
- let a = !i && (e.status === "draft" || e.status === "new"), o = Number(e.isHidden) === 1 || a || n.hidden === !0 || n.hidden === 1 || n.hidden === "1" || n.hidden === "true", s = oa(n.startShowingAt, n.stopShowingAt), c = (e.slug || "").replace(/^\/+|\/+$/g, ""), l = (!e.parentId || e.parentId === "null" || e.parentId === "") && (c === "home" || c === "homee") ? "/" : `${t}/${c}`.replace(/\/+/g, "/"), u = {
12769
+ let a = !i && (e.status === "draft" || e.status === "new"), o = Number(e.isHidden) === 1 || a || n.hidden === !0 || n.hidden === 1 || n.hidden === "1" || n.hidden === "true", s = sa(n.startShowingAt, n.stopShowingAt), c = (e.slug || "").replace(/^\/+|\/+$/g, ""), l = (!e.parentId || e.parentId === "null" || e.parentId === "") && (c === "home" || c === "homee") ? "/" : `${t}/${c}`.replace(/\/+/g, "/"), u = {
12736
12770
  id: e.id,
12737
12771
  treeNodeId: e.treeNodeId,
12738
12772
  parentId: e.parentId || null,
@@ -12757,7 +12791,7 @@ ia.get("/:treeParam", async (e) => {
12757
12791
  ...m,
12758
12792
  items: _(null)
12759
12793
  };
12760
- return !i && !s ? (e.header("X-Cache", "MISS"), aa(e, a.set(o, v, 300))) : e.header("Cache-Control", "no-store, no-cache, must-revalidate"), e.json(v);
12794
+ return !i && !s ? (e.header("X-Cache", "MISS"), oa(e, a.set(o, v, 300))) : e.header("Cache-Control", "no-store, no-cache, must-revalidate"), e.json(v);
12761
12795
  } catch (t) {
12762
12796
  return console.error("[CMS Public Tree API] Error:", t), e.json({
12763
12797
  error: "Failed to fetch public tree",
@@ -12767,8 +12801,8 @@ ia.get("/:treeParam", async (e) => {
12767
12801
  });
12768
12802
  //#endregion
12769
12803
  //#region server/routes/public/assets.ts
12770
- var sa = new n();
12771
- function ca(e, t) {
12804
+ var ca = new n();
12805
+ function la(e, t) {
12772
12806
  if (t === "webp") return "image/webp";
12773
12807
  if (t === "avif") return "image/avif";
12774
12808
  if (t === "jpeg" || t === "jpg") return "image/jpeg";
@@ -12776,7 +12810,7 @@ function ca(e, t) {
12776
12810
  let n = e.toLowerCase();
12777
12811
  return n.endsWith(".jpg") || n.endsWith(".jpeg") ? "image/jpeg" : n.endsWith(".png") ? "image/png" : n.endsWith(".webp") ? "image/webp" : n.endsWith(".gif") ? "image/gif" : n.endsWith(".svg") ? "image/svg+xml" : n.endsWith(".pdf") ? "application/pdf" : n.endsWith(".mp4") ? "video/mp4" : n.endsWith(".webm") ? "video/webm" : "application/octet-stream";
12778
12812
  }
12779
- sa.get("/*", async (e) => {
12813
+ ca.get("/*", async (e) => {
12780
12814
  let t = e.req.path.replace(/^\/media\//, "").replace(/^\//, "");
12781
12815
  if (!t) return e.text("Asset key missing", 400);
12782
12816
  let n = e.env?.MEDIA_BUCKET, { w: r, h: i, q: a, f: o } = e.req.query(), s = !!(r || i || a || o), c = e.req.header("Accept") || "", l = "";
@@ -12793,7 +12827,7 @@ sa.get("/*", async (e) => {
12793
12827
  }
12794
12828
  let p = e.req.header("Via")?.includes("image-resizing") || e.req.header("User-Agent")?.includes("Cloudflare-ImgRen"), m = new URL(e.req.url), h = e.env?.CDN_DOMAIN || m.hostname;
12795
12829
  if (n) {
12796
- let l = ca(t), u = l.startsWith("image/") && !l.includes("svg");
12830
+ let l = la(t), u = l.startsWith("image/") && !l.includes("svg");
12797
12831
  if (s && u && h && !p) {
12798
12832
  let e = r ? parseInt(r, 10) : void 0, n = i ? parseInt(i, 10) : void 0, s = a ? parseInt(a, 10) : 85, l = o || "auto", u = `https://${h}/media/${t}`;
12799
12833
  try {
@@ -12836,7 +12870,7 @@ sa.get("/*", async (e) => {
12836
12870
  if (!s) {
12837
12871
  let n = _(C);
12838
12872
  return e.body(n, 200, {
12839
- "Content-Type": ca(t),
12873
+ "Content-Type": la(t),
12840
12874
  "Cache-Control": "public, max-age=86400"
12841
12875
  });
12842
12876
  }
@@ -12844,7 +12878,7 @@ sa.get("/*", async (e) => {
12844
12878
  if (g(f)) {
12845
12879
  let n = _(f);
12846
12880
  return e.body(n, 200, {
12847
- "Content-Type": ca(t, u),
12881
+ "Content-Type": la(t, u),
12848
12882
  "Cache-Control": "public, max-age=31536000, immutable",
12849
12883
  "X-Local-Cache": "HIT"
12850
12884
  });
@@ -12857,14 +12891,14 @@ sa.get("/*", async (e) => {
12857
12891
  typeof n == "number" && (a.width = n), typeof o == "number" && (a.height = o), (a.width || a.height) && (a.fit = "cover", i = i.resize(a)), u === "webp" ? i = i.webp({ quality: typeof c == "number" ? c : 80 }) : u === "avif" ? i = i.avif({ quality: typeof c == "number" ? c : 70 }) : u === "jpeg" || u === "jpg" ? i = i.jpeg({ quality: typeof c == "number" ? c : 80 }) : u === "png" && (i = i.png({ quality: typeof c == "number" ? c : 80 }));
12858
12892
  let s = await i.toBuffer();
12859
12893
  return v(x(f), { recursive: !0 }), y(f, s), e.body(s, 200, {
12860
- "Content-Type": ca(t, u),
12894
+ "Content-Type": la(t, u),
12861
12895
  "Cache-Control": "public, max-age=31536000, immutable",
12862
12896
  "X-Local-Cache": "MISS"
12863
12897
  });
12864
12898
  } catch {
12865
12899
  let n = _(C);
12866
12900
  return e.body(n, 200, {
12867
- "Content-Type": ca(t),
12901
+ "Content-Type": la(t),
12868
12902
  "Cache-Control": "public, max-age=86400"
12869
12903
  });
12870
12904
  }
@@ -12875,8 +12909,8 @@ sa.get("/*", async (e) => {
12875
12909
  });
12876
12910
  //#endregion
12877
12911
  //#region server/routes/public/paths.ts
12878
- var la = new n();
12879
- function ua(e, t) {
12912
+ var ua = new n();
12913
+ function da(e, t) {
12880
12914
  let n = /* @__PURE__ */ new Date();
12881
12915
  if (e && String(e).trim() !== "") {
12882
12916
  let t = new Date(e);
@@ -12888,7 +12922,7 @@ function ua(e, t) {
12888
12922
  }
12889
12923
  return !0;
12890
12924
  }
12891
- la.get("/", async (e) => {
12925
+ ua.get("/", async (e) => {
12892
12926
  try {
12893
12927
  let t = await e.get("db").prepare("\n SELECT\n t.id as treeNodeId,\n t.parentId,\n c.slug,\n c.contentType as nodeType,\n c.status,\n c.dataJson\n FROM tree_nodes t\n INNER JOIN content_nodes c ON t.contentId = c.id\n WHERE (c.deletedAt IS NULL OR c.deletedAt = '')\n ORDER BY t.sortOrder ASC\n ").all(), n = Array.isArray(t) ? t : t?.results || [], r = [], i = /* @__PURE__ */ new Map();
12894
12928
  for (let e of n) {
@@ -12912,7 +12946,7 @@ la.get("/", async (e) => {
12912
12946
  function o(e = null, t = "") {
12913
12947
  let n = e == null || e === "" || e === "null" ? "__ROOT__" : String(e), s = i.get(n) || [];
12914
12948
  for (let e of s) {
12915
- let n = a.get(String(e.treeNodeId)) || {}, i = e.status === "published" || e.status === "active", s = ua(n.startShowingAt, n.stopShowingAt);
12949
+ let n = a.get(String(e.treeNodeId)) || {}, i = e.status === "published" || e.status === "active", s = da(n.startShowingAt, n.stopShowingAt);
12916
12950
  if (!i || !s) continue;
12917
12951
  let c = (e.slug || "").replace(/^\/+|\/+$/g, ""), l = c === "home" || c === "homee" ? "/" : `${t}/${c}`.replace(/\/+/g, "/");
12918
12952
  e.nodeType !== "external-link" && r.push(l);
@@ -12929,7 +12963,7 @@ la.get("/", async (e) => {
12929
12963
  });
12930
12964
  //#endregion
12931
12965
  //#region server/index.ts
12932
- var da = Nr(), $ = new n(), fa = !1;
12966
+ var fa = Nr(), $ = new n(), pa = !1;
12933
12967
  $.use("*", Fr()), $.use("/media/*", Fr({
12934
12968
  origin: "*",
12935
12969
  allowMethods: [
@@ -12947,18 +12981,18 @@ $.use("*", Fr()), $.use("/media/*", Fr({
12947
12981
  await t(), e.header("Cache-Control", "public, max-age=31536000, immutable"), e.header("Access-Control-Allow-Origin", "*");
12948
12982
  }), $.use("*", async (e, t) => {
12949
12983
  if (e.req.path.startsWith("/media/")) return t();
12950
- let n = da;
12984
+ let n = fa;
12951
12985
  e.env?.BUNDLED_DEFINITIONS && (e.env.BUNDLED_DEFINITIONS._isCompiled || (e.env.BUNDLED_DEFINITIONS = Nr(e.env.BUNDLED_DEFINITIONS), e.env.BUNDLED_DEFINITIONS._isCompiled = !0), n = e.env.BUNDLED_DEFINITIONS), e.set("schemas", n);
12952
12986
  let r = new URL(e.req.url), i = (e.req.header("host") || r.hostname).split(":")[0];
12953
12987
  e.set("currentDomain", i);
12954
12988
  let a = zr(e);
12955
- if (e.set("db", a), !fa) try {
12956
- await Ur(a, n), fa = !0;
12989
+ if (e.set("db", a), !pa) try {
12990
+ await Ur(a, n), pa = !0;
12957
12991
  } catch (e) {
12958
12992
  console.error("❌ [CMS Server] Failed to initialize system tables on cold start:", e);
12959
12993
  }
12960
12994
  await t();
12961
- }), $.route("/media", sa), $.use("/media/*", Gr()), $.route("/api/cms/nodes", Z), $.route("/api/cms/nodes.json", Z), $.route("/api/cms/formcsv", Z), $.route("/api/cms/formcsv.json", Z), $.route("/api/cms/stats", ji), $.route("/api/cms/stats.json", ji), $.route("/api/cms", yi), $.route("/api/cms/channels", Ci), $.route("/api/cms/channels.json", Ci), $.route("/api/cms/schemas", Ti), $.route("/api/cms/schemas.json", Ti), $.route("/api/admin/schemas", Ti), $.route("/api/cms", Oi), $.route("/api/admin/assets", Ii), $.route("/api/v1/node", zi), $.route("/api/v1/page", zi), $.route("/api/v1/tree", ia), $.route("/api/v1/all-paths", la), $.get("*", async (e) => {
12995
+ }), $.route("/media", ca), $.use("/media/*", Gr()), $.route("/api/cms/nodes", Z), $.route("/api/cms/nodes.json", Z), $.route("/api/cms/formcsv", Z), $.route("/api/cms/formcsv.json", Z), $.route("/api/cms/stats", Mi), $.route("/api/cms/stats.json", Mi), $.route("/api/cms", yi), $.route("/api/cms/channels", wi), $.route("/api/cms/channels.json", wi), $.route("/api/cms/schemas", Ei), $.route("/api/cms/schemas.json", Ei), $.route("/api/admin/schemas", Ei), $.route("/api/cms", ki), $.route("/api/admin/assets", Li), $.route("/api/v1/node", Bi), $.route("/api/v1/page", Bi), $.route("/api/v1/tree", aa), $.route("/api/v1/all-paths", ua), $.get("*", async (e) => {
12962
12996
  if (e.env?.ASSETS) {
12963
12997
  let t = await e.env.ASSETS.fetch(e.req.raw);
12964
12998
  if (t.status === 404) {