@brightsideoy/kama 0.1.0-alpha.86 → 0.1.0-alpha.88

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
@@ -7406,7 +7406,13 @@ var X = class {
7406
7406
  this.env = e, this.zoneId = e.CLOUDFLARE_ZONE_ID, this.apiToken = e.CLOUDFLARE_API_TOKEN, this.frontendUrl = (e.PUBLIC_FRONTEND_URL || "https://kama.t3cloud.eu").replace(/\/+$/, "");
7407
7407
  }
7408
7408
  dispatch(e, t) {
7409
- e.executionCtx && typeof e.executionCtx.waitUntil == "function" ? e.executionCtx.waitUntil(t) : t.catch((e) => console.warn("[CacheManager Warn]:", e));
7409
+ try {
7410
+ if (e.executionCtx && typeof e.executionCtx.waitUntil == "function") {
7411
+ e.executionCtx.waitUntil(t);
7412
+ return;
7413
+ }
7414
+ } catch {}
7415
+ t.catch((e) => console.warn("[CacheManager Warn]:", e));
7410
7416
  }
7411
7417
  async callAstroPurge(e, t) {
7412
7418
  let n = `${this.frontendUrl}/api/purge`, r = {
@@ -7849,17 +7855,20 @@ Z.get("/", async (e) => {
7849
7855
  }
7850
7856
  }
7851
7857
  if (g !== void 0 && Array.isArray(g) && w) {
7858
+ let e = await t.prepare("SELECT treeId, parentId, sortOrder FROM tree_nodes WHERE contentId = ?").all(w), n = Array.isArray(e) ? e : e?.results || [];
7852
7859
  await t.prepare("DELETE FROM tree_nodes WHERE contentId = ?").run(w);
7853
- let e = /* @__PURE__ */ new Set(), n = [], r = [];
7854
- for (let t of g) if (t && t.treeId) {
7855
- let i = Number(t.treeId) || t.treeId;
7856
- if (!e.has(i)) {
7857
- e.add(i);
7858
- let a = hi(t.parentId ?? t._draftParentId ?? null), o = typeof t.sortOrder == "number" ? t.sortOrder : 0;
7859
- n.push("(?, ?, ?, ?)"), r.push(i, w, a, o);
7860
+ let r = /* @__PURE__ */ new Set(), i = [], a = [];
7861
+ for (let e of g) if (e && e.treeId) {
7862
+ let t = Number(e.treeId) || e.treeId;
7863
+ if (!r.has(t)) {
7864
+ r.add(t);
7865
+ let o = n.find((e) => Number(e.treeId) === Number(t)), s = hi(e.parentId ?? e._draftParentId ?? null);
7866
+ s === null && o && o.parentId !== null && (s = o.parentId);
7867
+ let c = 0;
7868
+ typeof e.sortOrder == "number" ? c = e.sortOrder : o && typeof o.sortOrder == "number" && (c = o.sortOrder), i.push("(?, ?, ?, ?)"), a.push(t, w, s, c);
7860
7869
  }
7861
7870
  }
7862
- n.length > 0 && await t.prepare(`INSERT INTO tree_nodes (treeId, contentId, parentId, sortOrder) VALUES ${n.join(", ")}`).run(...r);
7871
+ i.length > 0 && await t.prepare(`INSERT INTO tree_nodes (treeId, contentId, parentId, sortOrder) VALUES ${i.join(", ")}`).run(...a);
7863
7872
  }
7864
7873
  let E = [];
7865
7874
  if (m !== void 0 && Array.isArray(m) && w) {
@@ -7945,7 +7954,7 @@ Z.get("/", async (e) => {
7945
7954
  let a = new X(e.env);
7946
7955
  if (i && await a.purgeInternalWorkerCache(e, t, r, i.slug, i.language || "en"), i && i.status === "published") {
7947
7956
  let n = await fi(t, r);
7948
- a.purgeSmart(e, t, r, i.slug, n, !0);
7957
+ i.slug && a.purgeAndWarmSlug(e, i.slug, n), a.purgeSmart(e, t, r, i.slug, n, !0);
7949
7958
  }
7950
7959
  return e.json({
7951
7960
  success: !0,
@@ -7955,11 +7964,12 @@ Z.get("/", async (e) => {
7955
7964
  let t = e.get("db"), n = await e.req.json(), r = Number(n.id);
7956
7965
  if (!r) return e.json({ error: "Node ID required" }, 400);
7957
7966
  let i = await t.prepare("SELECT slug, language, status FROM content_nodes WHERE id = ?").get(r);
7967
+ if (!i) return e.json({ error: "Node not found" }, 404);
7958
7968
  await t.prepare("UPDATE content_nodes SET deletedAt = NULL WHERE id = ?").run(r), await J(e).clear();
7959
7969
  let a = new X(e.env);
7960
7970
  if (i && await a.purgeInternalWorkerCache(e, t, r, i.slug, i.language || "en"), i && i.status === "published") {
7961
7971
  let n = await fi(t, r);
7962
- a.purgeSmart(e, t, r, i.slug, n, !0);
7972
+ i.slug && a.purgeAndWarmSlug(e, i.slug, n), a.purgeSmart(e, t, r, i.slug, n, !0);
7963
7973
  }
7964
7974
  return e.json({
7965
7975
  success: !0,
@@ -7969,7 +7979,7 @@ Z.get("/", async (e) => {
7969
7979
  let t = e.get("db"), n = e.req.query("id");
7970
7980
  if (!n) return e.json({ error: "Node ID required" }, 400);
7971
7981
  let r = Number(n), i = await t.prepare("SELECT slug, language, status FROM content_nodes WHERE id = ?").get(r), a = await fi(t, r), o = new X(e.env);
7972
- return i && await o.purgeInternalWorkerCache(e, t, r, i.slug, i.language || "en"), 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 content_nodes WHERE id = ?").run(r), await J(e).clear(), i && i.status === "published" && o.purgeSmart(e, t, r, i.slug, a, !0), e.json({
7982
+ return i && await o.purgeInternalWorkerCache(e, t, r, i.slug, i.language || "en"), 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 content_nodes WHERE id = ?").run(r), await J(e).clear(), i && i.status === "published" && (i.slug && o.purgeAndWarmSlug(e, i.slug, a), o.purgeSmart(e, t, r, i.slug, a, !0)), e.json({
7973
7983
  success: !0,
7974
7984
  purgedNodeId: r
7975
7985
  });
@@ -8001,6 +8011,15 @@ function Si(e) {
8001
8011
  function Ci(e) {
8002
8012
  return +(e === !0 || e === 1 || e === "1" || e === "true");
8003
8013
  }
8014
+ function wi(e, t) {
8015
+ try {
8016
+ if (e.executionCtx && typeof e.executionCtx.waitUntil == "function") {
8017
+ e.executionCtx.waitUntil(t);
8018
+ return;
8019
+ }
8020
+ } catch {}
8021
+ t.catch((e) => console.error("[Tree bgTask Error]:", e));
8022
+ }
8004
8023
  bi.get("/tree.json", async (e) => {
8005
8024
  try {
8006
8025
  let t = e.get("db"), n = e.req.query("treeId") || "main-nav", r = e.req.query("preview") === "true", i = 1;
@@ -8078,7 +8097,7 @@ bi.get("/tree.json", async (e) => {
8078
8097
  c.push(e.id, e.sortOrder);
8079
8098
  }), c.push(...i), c.push(o), await t.prepare(s).run(...c);
8080
8099
  }
8081
- return await i.clear(), e.executionCtx && typeof e.executionCtx.waitUntil == "function" ? e.executionCtx.waitUntil(a.purgeGlobalCacheDirect(e, t)) : await a.purgeGlobalCacheDirect(e, t), e.json({
8100
+ return await i.clear(), wi(e, a.purgeGlobalCacheDirect(e, t)), e.json({
8082
8101
  success: !0,
8083
8102
  reorderedCount: r.length
8084
8103
  });
@@ -8117,7 +8136,7 @@ bi.get("/tree.json", async (e) => {
8117
8136
  let e = b.map(() => "(?, ?)").join(", "), n = b.flatMap((e) => [f, e]);
8118
8137
  await t.prepare(`INSERT OR IGNORE INTO node_channels (nodeId, channelId) VALUES ${e}`).run(...n);
8119
8138
  }
8120
- return await i.clear(), e.executionCtx && typeof e.executionCtx.waitUntil == "function" ? e.executionCtx.waitUntil(a.purgeGlobalCacheDirect(e, t)) : await a.purgeGlobalCacheDirect(e, t), e.json({
8139
+ return await i.clear(), wi(e, a.purgeGlobalCacheDirect(e, t)), e.json({
8121
8140
  success: !0,
8122
8141
  id: f,
8123
8142
  treeNodeId: v,
@@ -8155,14 +8174,14 @@ bi.get("/tree.json", async (e) => {
8155
8174
  }
8156
8175
  await t.prepare("DELETE FROM tree_nodes WHERE treeId = ? AND contentId = ?").run(o, d);
8157
8176
  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);
8158
- return await i.clear(), e.executionCtx && typeof e.executionCtx.waitUntil == "function" ? e.executionCtx.waitUntil(a.purgeGlobalCacheDirect(e, t)) : await a.purgeGlobalCacheDirect(e, t), e.json({
8177
+ return await i.clear(), wi(e, a.purgeGlobalCacheDirect(e, t)), e.json({
8159
8178
  success: !0,
8160
8179
  treeNodeId: s
8161
8180
  });
8162
8181
  }
8163
8182
  if (s === "detach") {
8164
8183
  let r = n.treeNodeId || n.contentId;
8165
- 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(), e.executionCtx && typeof e.executionCtx.waitUntil == "function" ? e.executionCtx.waitUntil(a.purgeGlobalCacheDirect(e, t)) : await a.purgeGlobalCacheDirect(e, t), e.json({ success: !0 })) : e.json({ error: "treeNodeId or contentId required for detach" }, 400);
8184
+ 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(), wi(e, a.purgeGlobalCacheDirect(e, t)), e.json({ success: !0 })) : e.json({ error: "treeNodeId or contentId required for detach" }, 400);
8166
8185
  }
8167
8186
  return e.json({ error: "Invalid payload or action" }, 400);
8168
8187
  } catch (t) {
@@ -8226,9 +8245,7 @@ bi.get("/tree.json", async (e) => {
8226
8245
  await t.prepare(`INSERT OR IGNORE INTO channel_trees (channelId, treeId, key) VALUES ${n}`).run(...r);
8227
8246
  }
8228
8247
  }
8229
- await J(e).clear();
8230
- let m = new X(e.env);
8231
- return e.executionCtx && typeof e.executionCtx.waitUntil == "function" ? e.executionCtx.waitUntil(m.purgeGlobalCacheDirect(e, t)) : await m.purgeGlobalCacheDirect(e, t), e.json({
8248
+ return await J(e).clear(), wi(e, new X(e.env).purgeGlobalCacheDirect(e, t)), e.json({
8232
8249
  success: !0,
8233
8250
  id: p,
8234
8251
  key: o,
@@ -8247,9 +8264,7 @@ bi.get("/tree.json", async (e) => {
8247
8264
  if (!n) return e.json({ error: "Tree ID required" }, 400);
8248
8265
  let r = Number(n);
8249
8266
  try {
8250
- 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 J(e).clear();
8251
- let n = new X(e.env);
8252
- return e.executionCtx && typeof e.executionCtx.waitUntil == "function" ? e.executionCtx.waitUntil(n.purgeGlobalCacheDirect(e, t)) : await n.purgeGlobalCacheDirect(e, t), e.json({
8267
+ 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 J(e).clear(), wi(e, new X(e.env).purgeGlobalCacheDirect(e, t)), e.json({
8253
8268
  success: !0,
8254
8269
  deletedTreeId: r
8255
8270
  });
@@ -8259,8 +8274,8 @@ bi.get("/tree.json", async (e) => {
8259
8274
  });
8260
8275
  //#endregion
8261
8276
  //#region server/routes/admin/channels.ts
8262
- var wi = new e();
8263
- wi.get("/", async (e) => {
8277
+ var Ti = new e();
8278
+ Ti.get("/", async (e) => {
8264
8279
  try {
8265
8280
  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").all(), a = ((Array.isArray(i) ? i : i?.results || []) || []).reduce((e, t) => {
8266
8281
  e[t.channelId] || (e[t.channelId] = []);
@@ -8326,7 +8341,7 @@ wi.get("/", async (e) => {
8326
8341
  error: t.message
8327
8342
  }, 500);
8328
8343
  }
8329
- }), wi.post("/", async (e) => {
8344
+ }), Ti.post("/", async (e) => {
8330
8345
  try {
8331
8346
  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 = "website", domain: c = "localhost", baseUrl: l = "http://localhost:4321", defaultLanguage: u = "en", 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 = Array.isArray(f) ? f : [], S = JSON.stringify(v || {}), C = e.get("user")?.id || m || p || null;
8332
8347
  if (await t.prepare("SELECT id FROM channels WHERE key = ? AND id != ? LIMIT 1").get(y, i ?? -1)) return e.json({
@@ -8365,7 +8380,7 @@ wi.get("/", async (e) => {
8365
8380
  details: t.message
8366
8381
  }, 500);
8367
8382
  }
8368
- }), wi.delete("/", async (e) => {
8383
+ }), Ti.delete("/", async (e) => {
8369
8384
  let t = e.get("db"), n = e.req.query("id");
8370
8385
  if (!n) return e.json({ error: "Channel ID required" }, 400);
8371
8386
  let r = Number(n);
@@ -8385,9 +8400,9 @@ wi.get("/", async (e) => {
8385
8400
  });
8386
8401
  //#endregion
8387
8402
  //#region server/routes/admin/schemas.ts
8388
- var Ti = new e(), Ei = null, Di = (e) => {
8403
+ var Ei = new e(), Di = null, Oi = (e) => {
8389
8404
  try {
8390
- if (!Ei) {
8405
+ if (!Di) {
8391
8406
  let t = ci(e.env?.BUNDLED_DEFINITIONS || Or), n = t.userTemplate || {
8392
8407
  id: "userTemplate",
8393
8408
  label: "User Account",
@@ -8424,7 +8439,7 @@ var Ti = new e(), Ei = null, Di = (e) => {
8424
8439
  }
8425
8440
  }
8426
8441
  };
8427
- Ei = {
8442
+ Di = {
8428
8443
  channelTemplate: t.channelTemplate || null,
8429
8444
  treeTemplate: t.treeTemplate || null,
8430
8445
  userTemplate: n,
@@ -8436,7 +8451,7 @@ var Ti = new e(), Ei = null, Di = (e) => {
8436
8451
  blockLayouts: t.blockLayouts || {}
8437
8452
  };
8438
8453
  }
8439
- return e.json(Ei, 200, { "Cache-Control": "public, max-age=300, stale-while-revalidate=86400" });
8454
+ return e.json(Di, 200, { "Cache-Control": "public, max-age=300, stale-while-revalidate=86400" });
8440
8455
  } catch (t) {
8441
8456
  return console.error("[CMS API] Error loading schemas:", t), e.json({
8442
8457
  error: "Failed to load schemas",
@@ -8444,10 +8459,10 @@ var Ti = new e(), Ei = null, Di = (e) => {
8444
8459
  }, 500);
8445
8460
  }
8446
8461
  };
8447
- Ti.get("/", Di), Ti.get("/schemas.json", Di);
8462
+ Ei.get("/", Oi), Ei.get("/schemas.json", Oi);
8448
8463
  //#endregion
8449
8464
  //#region server/routes/admin/validation.ts
8450
- var Oi = new e(), ki = {
8465
+ var ki = new e(), Ai = {
8451
8466
  node: "content_nodes",
8452
8467
  nodes: "content_nodes",
8453
8468
  content_node: "content_nodes",
@@ -8459,7 +8474,7 @@ var Oi = new e(), ki = {
8459
8474
  user: "users",
8460
8475
  users: "users",
8461
8476
  user_account: "user_accounts"
8462
- }, Ai = {
8477
+ }, ji = {
8463
8478
  content_nodes: [
8464
8479
  "id",
8465
8480
  "title",
@@ -8516,11 +8531,11 @@ var Oi = new e(), ki = {
8516
8531
  "createdAt"
8517
8532
  ]
8518
8533
  };
8519
- Oi.post("/validate-unique", async (e) => {
8534
+ ki.post("/validate-unique", async (e) => {
8520
8535
  try {
8521
8536
  let t = e.get("db"), { entityType: n, field: r, value: i, excludeId: a } = await e.req.json();
8522
8537
  if (!r || i == null || String(i).trim() === "") return e.json({ isUnique: !0 });
8523
- let o = ki[n] || "content_nodes", s = r.replace(/[^a-zA-Z0-9_]/g, ""), c = (Ai[o] || Ai.content_nodes).includes(s), l = -1;
8538
+ let o = Ai[n] || "content_nodes", s = r.replace(/[^a-zA-Z0-9_]/g, ""), c = (ji[o] || ji.content_nodes).includes(s), l = -1;
8524
8539
  if (a != null && String(a).trim() !== "") {
8525
8540
  let e = Number(a);
8526
8541
  l = isNaN(e) ? String(a) : e;
@@ -8532,7 +8547,7 @@ Oi.post("/validate-unique", async (e) => {
8532
8547
  } catch (t) {
8533
8548
  return console.error("[API Validation] Error validating global uniqueness:", t), e.json({ error: "Failed to validate uniqueness" }, 500);
8534
8549
  }
8535
- }), Oi.post("/validate-unique-sibling", async (e) => {
8550
+ }), ki.post("/validate-unique-sibling", async (e) => {
8536
8551
  try {
8537
8552
  let t = e.get("db"), { slug: n, treeId: r, parentId: i, excludeTreeNodeId: a } = await e.req.json();
8538
8553
  if (!n || !String(n).trim() || !r) return e.json({ isUnique: !0 });
@@ -8559,8 +8574,8 @@ Oi.post("/validate-unique", async (e) => {
8559
8574
  });
8560
8575
  //#endregion
8561
8576
  //#region server/routes/admin/stats.ts
8562
- var ji = new e();
8563
- ji.get("/", async (e) => {
8577
+ var Mi = new e();
8578
+ Mi.get("/", async (e) => {
8564
8579
  try {
8565
8580
  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) => ({
8566
8581
  ...e,
@@ -8603,7 +8618,7 @@ ji.get("/", async (e) => {
8603
8618
  });
8604
8619
  //#endregion
8605
8620
  //#region server/routes/admin/assets.ts
8606
- var Mi = new e();
8621
+ var Ni = new e();
8607
8622
  async function Q(e, t, n = []) {
8608
8623
  let r = e.prepare(t);
8609
8624
  if (typeof r.bind == "function") {
@@ -8616,20 +8631,20 @@ async function Q(e, t, n = []) {
8616
8631
  }
8617
8632
  return [];
8618
8633
  }
8619
- async function Ni(e, t, n = []) {
8634
+ async function Pi(e, t, n = []) {
8620
8635
  let r = e.prepare(t);
8621
8636
  if (typeof r.bind == "function") return await r.bind(...n).run();
8622
8637
  if (typeof r.run == "function") return await r.run(...n);
8623
8638
  }
8624
- function Pi(e, t, n) {
8639
+ function Fi(e, t, n) {
8625
8640
  let r = e || (t ? `/media/${t}` : "");
8626
8641
  return r && n && r.startsWith(`https://${n}/`) && !r.includes("/media/") && (r = r.replace(`https://${n}/`, `https://${n}/media/`)), r;
8627
8642
  }
8628
- async function Fi(e, t, n) {
8643
+ async function Ii(e, t, n) {
8629
8644
  try {
8630
8645
  let r = new X(e.env), i = await Q(t, "\n SELECT cdnUrl, storageKeyPrivate\n FROM assets\n WHERE id = ? OR parentAssetId = ?\n ", [n, n]), a = [];
8631
8646
  for (let t of i) {
8632
- let n = Pi(t.cdnUrl, t.storageKeyPrivate, e.env?.CDN_DOMAIN);
8647
+ let n = Fi(t.cdnUrl, t.storageKeyPrivate, e.env?.CDN_DOMAIN);
8633
8648
  n && a.push(n);
8634
8649
  }
8635
8650
  let o = await Q(t, "\n SELECT DISTINCT cn.id, cn.slug, cn.status\n FROM node_assets na\n INNER JOIN content_nodes cn ON na.nodeId = cn.id\n LEFT JOIN assets crop ON na.assetId = crop.id\n WHERE cn.status = 'published' AND (\n na.assetId = ?\n OR crop.parentAssetId = ?\n OR crop.id = (SELECT parentAssetId FROM assets WHERE id = ?)\n )\n ", [
@@ -8643,7 +8658,7 @@ async function Fi(e, t, n) {
8643
8658
  console.warn("[Assets Router] Failed to purge edge cache for asset nodes:", e);
8644
8659
  }
8645
8660
  }
8646
- Mi.get("/", async (e) => {
8661
+ Ni.get("/", async (e) => {
8647
8662
  try {
8648
8663
  let t = u(e), { search: n = "", type: r = "all", page: i = "1", limit: a = "24", sort: o = "createdAt", order: s = "DESC", nodeId: c, channelId: l, trashed: d } = e.req.query(), f = Math.max(1, parseInt(i, 10) || 1), p = Math.max(1, Math.min(100, parseInt(a, 10) || 24)), m = (f - 1) * p, h = {
8649
8664
  createdAt: "a.createdAt",
@@ -8710,7 +8725,7 @@ Mi.get("/", async (e) => {
8710
8725
  ...JSON.parse(t.dataJson || "{}")
8711
8726
  };
8712
8727
  } catch {}
8713
- let r = Pi(t.cdnUrl, t.storageKeyPrivate, e.env?.CDN_DOMAIN);
8728
+ let r = Fi(t.cdnUrl, t.storageKeyPrivate, e.env?.CDN_DOMAIN);
8714
8729
  return {
8715
8730
  id: t.id,
8716
8731
  filename: t.filename || "Untitled Asset",
@@ -8734,7 +8749,7 @@ Mi.get("/", async (e) => {
8734
8749
  details: t.message || String(t)
8735
8750
  }, 500);
8736
8751
  }
8737
- }), Mi.post("/upload", async (e) => {
8752
+ }), Ni.post("/upload", async (e) => {
8738
8753
  try {
8739
8754
  let t = u(e), n = ni(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;
8740
8755
  s && (await Q(t, "SELECT id FROM assets WHERE id = ?", [s])).length === 0 && (s = null);
@@ -8753,7 +8768,7 @@ Mi.get("/", async (e) => {
8753
8768
  let y = e.env.CDN_DOMAIN, b = v.replace(/^\//, ""), x = y ? `https://${y}/media/${b}` : `/media/${b}`, S = i.type || "application/octet-stream", C = i.size || 0, w = e.get("userId"), T = typeof w == "string" && w.trim().length > 0 ? w : null;
8754
8769
  T && (await Q(t, "SELECT id FROM users WHERE id = ?", [T])).length === 0 && (T = null);
8755
8770
  let E = +!!h;
8756
- await Ni(t, "\n INSERT INTO assets (id, filename, mimeType, sizeBytes, storageKeyPrivate, cdnUrl, createdById, isSystemVariant, parentAssetId, cropCoordinatesJson)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ", [
8771
+ await Pi(t, "\n INSERT INTO assets (id, filename, mimeType, sizeBytes, storageKeyPrivate, cdnUrl, createdById, isSystemVariant, parentAssetId, cropCoordinatesJson)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ", [
8757
8772
  p,
8758
8773
  i.name,
8759
8774
  S,
@@ -8768,7 +8783,7 @@ Mi.get("/", async (e) => {
8768
8783
  let D = x;
8769
8784
  if (s) {
8770
8785
  let n = await Q(t, "SELECT cdnUrl, storageKeyPrivate FROM assets WHERE id = ?", [s]);
8771
- n.length > 0 && (D = Pi(n[0].cdnUrl, n[0].storageKeyPrivate, y)), await Fi(e, t, s);
8786
+ n.length > 0 && (D = Fi(n[0].cdnUrl, n[0].storageKeyPrivate, y)), await Ii(e, t, s);
8772
8787
  }
8773
8788
  return e.json({
8774
8789
  id: p,
@@ -8787,7 +8802,7 @@ Mi.get("/", async (e) => {
8787
8802
  details: t.message || String(t)
8788
8803
  }, 500);
8789
8804
  }
8790
- }), Mi.get("/:id/details", async (e) => {
8805
+ }), Ni.get("/:id/details", async (e) => {
8791
8806
  try {
8792
8807
  let t = u(e), n = e.req.param("id"), r = await Q(t, "SELECT * FROM assets WHERE id = ?", [n]);
8793
8808
  if (!r || r.length === 0) return e.json({ error: "Asset not found" }, 404);
@@ -8810,7 +8825,7 @@ Mi.get("/", async (e) => {
8810
8825
  ...JSON.parse(i.dataJson || "{}")
8811
8826
  };
8812
8827
  } catch {}
8813
- let l = Pi(i.cdnUrl, i.storageKeyPrivate, e.env?.CDN_DOMAIN);
8828
+ let l = Fi(i.cdnUrl, i.storageKeyPrivate, e.env?.CDN_DOMAIN);
8814
8829
  return e.json({
8815
8830
  id: i.id,
8816
8831
  filename: i.filename,
@@ -8837,7 +8852,7 @@ Mi.get("/", async (e) => {
8837
8852
  createdAt: t.createdAt,
8838
8853
  parentAssetId: t.parentAssetId || i.id,
8839
8854
  cropCoordinates: n,
8840
- url: Pi(t.cdnUrl, t.storageKeyPrivate, e.env?.CDN_DOMAIN),
8855
+ url: Fi(t.cdnUrl, t.storageKeyPrivate, e.env?.CDN_DOMAIN),
8841
8856
  originalUrl: l
8842
8857
  };
8843
8858
  })
@@ -8845,7 +8860,7 @@ Mi.get("/", async (e) => {
8845
8860
  } catch (t) {
8846
8861
  return console.error("❌ [Asset Details Error]:", t), e.json({ error: "Failed to load details" }, 500);
8847
8862
  }
8848
- }), Mi.put("/:id", async (e) => {
8863
+ }), Ni.put("/:id", async (e) => {
8849
8864
  try {
8850
8865
  let t = u(e), n = e.req.param("id"), r = await e.req.json(), i = await Q(t, "SELECT filename, dataJson FROM assets WHERE id = ?", [n]);
8851
8866
  if (!i || i.length === 0) return e.json({ error: "Asset not found" }, 404);
@@ -8853,18 +8868,18 @@ Mi.get("/", async (e) => {
8853
8868
  try {
8854
8869
  o = JSON.parse(a.dataJson || "{}");
8855
8870
  } catch {}
8856
- 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 Ni(t, "UPDATE assets SET filename = ?, dataJson = ?, updatedAt = CURRENT_TIMESTAMP WHERE id = ?", [
8871
+ 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 Pi(t, "UPDATE assets SET filename = ?, dataJson = ?, updatedAt = CURRENT_TIMESTAMP WHERE id = ?", [
8857
8872
  r.filename === void 0 ? a.filename : r.filename,
8858
8873
  JSON.stringify(o),
8859
8874
  n
8860
- ]), await Fi(e, t, n), e.json({ success: !0 });
8875
+ ]), await Ii(e, t, n), e.json({ success: !0 });
8861
8876
  } catch (t) {
8862
8877
  return console.error("❌ [Asset Update Error]:", t), e.json({ error: "Failed to update asset" }, 500);
8863
8878
  }
8864
- }), Mi.delete("/:id", async (e) => {
8879
+ }), Ni.delete("/:id", async (e) => {
8865
8880
  try {
8866
8881
  let t = u(e), n = e.req.param("id"), r = (await Q(t, "SELECT id, filename, isSystemVariant FROM assets WHERE id = ?", [n]))[0];
8867
- return r ? (await Fi(e, t, n), r.isSystemVariant ? await Ni(t, "UPDATE assets SET deletedAt = CURRENT_TIMESTAMP WHERE id = ?", [n]) : await Ni(t, "UPDATE assets\n SET deletedAt = CURRENT_TIMESTAMP\n WHERE id = ? OR parentAssetId = ? OR (isSystemVariant = 1 AND (filename LIKE ? OR filename LIKE ?))", [
8882
+ return r ? (await Ii(e, t, n), r.isSystemVariant ? await Pi(t, "UPDATE assets SET deletedAt = CURRENT_TIMESTAMP WHERE id = ?", [n]) : await Pi(t, "UPDATE assets\n SET deletedAt = CURRENT_TIMESTAMP\n WHERE id = ? OR parentAssetId = ? OR (isSystemVariant = 1 AND (filename LIKE ? OR filename LIKE ?))", [
8868
8883
  n,
8869
8884
  n,
8870
8885
  `crop_%${r.filename ? r.filename.replace(/\.[^/.]+$/, "") : ""}%`,
@@ -8880,17 +8895,17 @@ Mi.get("/", async (e) => {
8880
8895
  details: t.message || String(t)
8881
8896
  }, 500);
8882
8897
  }
8883
- }), Mi.post("/restore", async (e) => {
8898
+ }), Ni.post("/restore", async (e) => {
8884
8899
  try {
8885
8900
  let t = u(e), n = await e.req.json(), r = n.id || n.assetId;
8886
8901
  if (!r) return e.json({ error: "Asset ID required" }, 400);
8887
8902
  let i = (await Q(t, "SELECT id, filename FROM assets WHERE id = ?", [r]))[0];
8888
- return i ? (await Ni(t, "UPDATE assets \n SET deletedAt = NULL \n WHERE id = ? OR parentAssetId = ? OR (isSystemVariant = 1 AND (filename LIKE ? OR filename LIKE ?))", [
8903
+ return i ? (await Pi(t, "UPDATE assets \n SET deletedAt = NULL \n WHERE id = ? OR parentAssetId = ? OR (isSystemVariant = 1 AND (filename LIKE ? OR filename LIKE ?))", [
8889
8904
  r,
8890
8905
  r,
8891
8906
  `crop_%${i.filename ? i.filename.replace(/\.[^/.]+$/, "") : ""}%`,
8892
8907
  `%${r}%`
8893
- ]), await Fi(e, t, r), e.json({
8908
+ ]), await Ii(e, t, r), e.json({
8894
8909
  success: !0,
8895
8910
  id: r,
8896
8911
  restored: !0
@@ -8901,11 +8916,11 @@ Mi.get("/", async (e) => {
8901
8916
  details: t.message
8902
8917
  }, 500);
8903
8918
  }
8904
- }), Mi.delete("/purge/:id", async (e) => {
8919
+ }), Ni.delete("/purge/:id", async (e) => {
8905
8920
  try {
8906
8921
  let t = u(e), n = ni(e.env), r = e.req.param("id"), i = (await Q(t, "SELECT id, filename, storageKeyPrivate, isSystemVariant FROM assets WHERE id = ?", [r]))[0];
8907
8922
  if (!i) return e.json({ error: "Asset not found" }, 404);
8908
- await Fi(e, t, r);
8923
+ await Ii(e, t, r);
8909
8924
  let a = [i];
8910
8925
  i.isSystemVariant || (a = [i, ...await Q(t, "SELECT id, storageKeyPrivate FROM assets \n WHERE parentAssetId = ? OR (isSystemVariant = 1 AND (filename LIKE ? OR filename LIKE ?))", [
8911
8926
  r,
@@ -8921,7 +8936,7 @@ Mi.get("/", async (e) => {
8921
8936
  }
8922
8937
  }
8923
8938
  let s = o.map(() => "?").join(",");
8924
- return await Ni(t, `DELETE FROM node_assets WHERE assetId IN (${s})`, o), await Ni(t, `DELETE FROM assets WHERE id IN (${s})`, o), e.json({
8939
+ return await Pi(t, `DELETE FROM node_assets WHERE assetId IN (${s})`, o), await Pi(t, `DELETE FROM assets WHERE id IN (${s})`, o), e.json({
8925
8940
  success: !0,
8926
8941
  id: r,
8927
8942
  purged: !0,
@@ -8937,8 +8952,8 @@ Mi.get("/", async (e) => {
8937
8952
  });
8938
8953
  //#endregion
8939
8954
  //#region server/routes/public/node.ts
8940
- var Ii = new e();
8941
- function Li() {
8955
+ var Li = new e();
8956
+ function Ri() {
8942
8957
  return {
8943
8958
  fullPath: /* @__PURE__ */ new Map(),
8944
8959
  treeEdges: /* @__PURE__ */ new Map(),
@@ -8946,10 +8961,10 @@ function Li() {
8946
8961
  assetUrls: /* @__PURE__ */ new Map()
8947
8962
  };
8948
8963
  }
8949
- function Ri(...e) {
8964
+ function zi(...e) {
8950
8965
  return e.map((e) => String(e ?? "")).join(":");
8951
8966
  }
8952
- function zi(e, t) {
8967
+ function Bi(e, t) {
8953
8968
  let n = Date.now();
8954
8969
  if (e && String(e).trim() !== "") {
8955
8970
  let t = Date.parse(e);
@@ -8961,7 +8976,7 @@ function zi(e, t) {
8961
8976
  }
8962
8977
  return !0;
8963
8978
  }
8964
- async function Bi(e, t, n) {
8979
+ async function Vi(e, t, n) {
8965
8980
  let r = t.filter((e) => e.componentId === "content-feed" || e.componentId === "article-list");
8966
8981
  await Promise.all(r.map(async (t) => {
8967
8982
  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];
@@ -8982,7 +8997,7 @@ async function Bi(e, t, n) {
8982
8997
  if (e.dataJson) try {
8983
8998
  t = typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson;
8984
8999
  } catch {}
8985
- return zi(t.startShowingAt, t.stopShowingAt) ? {
9000
+ return Bi(t.startShowingAt, t.stopShowingAt) ? {
8986
9001
  id: e.id,
8987
9002
  title: e.title,
8988
9003
  slug: e.slug,
@@ -8999,7 +9014,7 @@ async function Bi(e, t, n) {
8999
9014
  }
9000
9015
  }));
9001
9016
  }
9002
- async function Vi(e, t, n, r, i = !1, a) {
9017
+ async function Hi(e, t, n, r, i = !1, a) {
9003
9018
  if (!t) return { blocks: [] };
9004
9019
  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\n FROM tree_nodes t\n INNER JOIN content_nodes c ON t.contentId = c.id\n WHERE t.id = ? OR c.id = ?\n\n UNION ALL\n\n SELECT t.id, t.contentId, c.title, c.slug, t.parentId, ap.level + 1\n FROM tree_nodes t\n INNER JOIN content_nodes c ON t.contentId = c.id\n INNER JOIN ancestor_path ap ON t.id = ap.parentId\n )\n SELECT *\n FROM ancestor_path\n ORDER BY level ASC\n ").all(t, t), s = Array.isArray(o) ? o : o?.results || [];
9005
9020
  if (!s || s.length === 0) return { blocks: [] };
@@ -9055,10 +9070,10 @@ async function Vi(e, t, n, r, i = !1, a) {
9055
9070
  try {
9056
9071
  a = (typeof t.dataJson == "string" ? JSON.parse(t.dataJson) : t.dataJson) || {};
9057
9072
  } catch {}
9058
- let o = a.hidden === !0 || a.hidden === 1 || a.hidden === "1" || a.hidden === "true", s = zi(a.startShowingAt, a.stopShowingAt);
9073
+ let o = a.hidden === !0 || a.hidden === 1 || a.hidden === "1" || a.hidden === "true", s = Bi(a.startShowingAt, a.stopShowingAt);
9059
9074
  if (!i && (o || !s)) return null;
9060
- 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 || t.blockId || t.id), d = Hi(a, l);
9061
- return d = await oi(e, d), d = Ui(d), d.blockId = u, {
9075
+ 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 || t.blockId || t.id), d = Ui(a, l);
9076
+ return d = await oi(e, d), d = Wi(d), d.blockId = u, {
9062
9077
  region: t.region || n,
9063
9078
  block: {
9064
9079
  instanceId: t.id,
@@ -9078,7 +9093,7 @@ async function Vi(e, t, n, r, i = !1, a) {
9078
9093
  }
9079
9094
  return { blocks: [] };
9080
9095
  }
9081
- function Hi(e, t = {}) {
9096
+ function Ui(e, t = {}) {
9082
9097
  let n = {};
9083
9098
  for (let [r, i] of Object.entries(e)) {
9084
9099
  if (r.endsWith("_meta") || r === "disabledRegions" || r === "hidden" || r === "is_hidden" || r === "isHidden" || r === "status" || r === "startShowingAt" || r === "stopShowingAt" || r === "slug" || r === "title" || r === "id" || r.startsWith("_")) continue;
@@ -9087,14 +9102,14 @@ function Hi(e, t = {}) {
9087
9102
  }
9088
9103
  return n;
9089
9104
  }
9090
- function Ui(e) {
9091
- if (Array.isArray(e)) return e.map(Ui);
9105
+ function Wi(e) {
9106
+ if (Array.isArray(e)) return e.map(Wi);
9092
9107
  if (!e || typeof e != "object") return e;
9093
9108
  if (typeof e.id == "string" && e.id.startsWith("ast_") && typeof e.url == "string") {
9094
9109
  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 ? {
9095
9110
  ...t,
9096
9111
  ...t.crops?.[r] || {}
9097
- } : t, a = Object.fromEntries(Object.entries(n).filter(([, t]) => t?.id !== e.id).map(([t, n]) => [t, Ui({
9112
+ } : t, a = Object.fromEntries(Object.entries(n).filter(([, t]) => t?.id !== e.id).map(([t, n]) => [t, Wi({
9098
9113
  ...n,
9099
9114
  title: n?.title ?? e.title ?? "",
9100
9115
  alt: n?.alt ?? e.alt ?? "",
@@ -9108,9 +9123,9 @@ function Ui(e) {
9108
9123
  ...Object.keys(a).length > 0 ? { variants: a } : {}
9109
9124
  };
9110
9125
  }
9111
- return Object.fromEntries(Object.entries(e).map(([e, t]) => [e, Ui(t)]));
9126
+ return Object.fromEntries(Object.entries(e).map(([e, t]) => [e, Wi(t)]));
9112
9127
  }
9113
- async function Wi(e, t, n) {
9128
+ async function Gi(e, t, n) {
9114
9129
  if (typeof t == "string") {
9115
9130
  if (!t.includes("#node:") && !t.includes("data-node-id") && !t.includes("#asset:") && !t.includes("data-asset-id")) return t;
9116
9131
  let r = (e, t) => {
@@ -9136,9 +9151,9 @@ async function Wi(e, t, n) {
9136
9151
  return await Promise.all(Array.from(t.matchAll(h)).map(async (t) => {
9137
9152
  let i = t[1], a = r(i, "data-node-id"), o = r(i, "data-tree-id");
9138
9153
  if (!a || !o) return;
9139
- let s = await Ki(e, a, o, n);
9154
+ let s = await qi(e, a, o, n);
9140
9155
  if (s?.treeNodeId) {
9141
- let t = await Xi(e, String(s.treeNodeId), o, n);
9156
+ let t = await Zi(e, String(s.treeNodeId), o, n);
9142
9157
  m.set(`${a}:${o}`, t);
9143
9158
  }
9144
9159
  })), t.replace(h, (e, t) => {
@@ -9158,39 +9173,39 @@ async function Wi(e, t, n) {
9158
9173
  return /href\s*=\s*["'][^"']*["']/i.test(_) ? _ = _.replace(/href\s*=\s*["'][^"']*["']/i, `href="${g || "/"}"`) : _ += ` href="${g || "/"}"`, `<a ${_}>`;
9159
9174
  });
9160
9175
  }
9161
- if (Array.isArray(t)) return Promise.all(t.map((t) => Wi(e, t, n)));
9176
+ if (Array.isArray(t)) return Promise.all(t.map((t) => Gi(e, t, n)));
9162
9177
  if (t && typeof t == "object") {
9163
9178
  if (typeof t.href == "string" && (t.href.startsWith("#node:") || t.href.startsWith("#asset:"))) return {
9164
9179
  ...t,
9165
- href: await Gi(e, t, n)
9180
+ href: await Ki(e, t, n)
9166
9181
  };
9167
- let r = await Promise.all(Object.entries(t).map(async ([t, r]) => [t, await Wi(e, r, n)]));
9182
+ let r = await Promise.all(Object.entries(t).map(async ([t, r]) => [t, await Gi(e, r, n)]));
9168
9183
  return Object.fromEntries(r);
9169
9184
  }
9170
9185
  return t;
9171
9186
  }
9172
- async function Gi(e, t, n) {
9187
+ async function Ki(e, t, n) {
9173
9188
  let r = t.href.match(/^#node:(.+)$/), i = t.href.match(/^#asset:(.+)$/);
9174
- if (i) return Ji(e, i[1], n);
9189
+ if (i) return Yi(e, i[1], n);
9175
9190
  if (!r) return t.href;
9176
9191
  let a = r[1];
9177
9192
  if (t.treeId) {
9178
- let r = await Ki(e, a, String(t.treeId), n);
9193
+ let r = await qi(e, a, String(t.treeId), n);
9179
9194
  if (r?.treeNodeId) {
9180
- let i = await Xi(e, String(r.treeNodeId), String(t.treeId), n);
9195
+ let i = await Zi(e, String(r.treeNodeId), String(t.treeId), n);
9181
9196
  if (i) return i;
9182
9197
  }
9183
9198
  }
9184
- let o = await qi(e, a, n);
9199
+ let o = await Ji(e, a, n);
9185
9200
  return o === void 0 ? "#" : `/${o}`;
9186
9201
  }
9187
- async function Ki(e, t, n, r) {
9188
- let i = Ri(t, n), a = r.treeEdges.get(i);
9202
+ async function qi(e, t, n, r) {
9203
+ let i = zi(t, n), a = r.treeEdges.get(i);
9189
9204
  if (a) return a;
9190
9205
  let o = e.prepare("\n SELECT id as treeNodeId\n FROM tree_nodes\n WHERE contentId = ?\n AND treeId = ?\n LIMIT 1\n ").get(t, n);
9191
9206
  return r.treeEdges.set(i, Promise.resolve(o)), o;
9192
9207
  }
9193
- async function qi(e, t, n) {
9208
+ async function Ji(e, t, n) {
9194
9209
  let r = String(t), i = n.nodeSlugs.get(r);
9195
9210
  if (i) return i;
9196
9211
  let a = (async () => {
@@ -9199,7 +9214,7 @@ async function qi(e, t, n) {
9199
9214
  })();
9200
9215
  return n.nodeSlugs.set(r, a), a;
9201
9216
  }
9202
- async function Ji(e, t, n) {
9217
+ async function Yi(e, t, n) {
9203
9218
  let r = String(t), i = n.assetUrls.get(r);
9204
9219
  if (i) return i;
9205
9220
  let a = (async () => {
@@ -9208,7 +9223,7 @@ async function Ji(e, t, n) {
9208
9223
  })();
9209
9224
  return n.assetUrls.set(r, a), a;
9210
9225
  }
9211
- function Yi(e) {
9226
+ function Xi(e) {
9212
9227
  let t = e.socialImage;
9213
9228
  if (!t || typeof t != "object") return null;
9214
9229
  let n = (e, t) => {
@@ -9239,9 +9254,9 @@ function Yi(e) {
9239
9254
  ])
9240
9255
  };
9241
9256
  }
9242
- async function Xi(e, t, n, r) {
9257
+ async function Zi(e, t, n, r) {
9243
9258
  if (!t) return "";
9244
- let i = Ri(t, n);
9259
+ let i = zi(t, n);
9245
9260
  if (r) {
9246
9261
  let e = r.fullPath.get(i);
9247
9262
  if (e) return e;
@@ -9256,7 +9271,7 @@ async function Xi(e, t, n, r) {
9256
9271
  })();
9257
9272
  return r && r.fullPath.set(i, a), a;
9258
9273
  }
9259
- async function Zi(e, t, n, r, i) {
9274
+ async function Qi(e, t, n, r, i) {
9260
9275
  let a = {}, o = null;
9261
9276
  if (t) {
9262
9277
  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\n FROM tree_nodes t\n INNER JOIN content_nodes c ON t.contentId = c.id\n WHERE t.id = ? OR c.id = ?\n\n UNION ALL\n\n SELECT t.id, t.contentId, c.title, c.slug, t.parentId, ap.level + 1\n FROM tree_nodes t\n INNER JOIN content_nodes c ON t.contentId = c.id\n INNER JOIN ancestor_path ap ON t.id = ap.parentId\n )\n SELECT c.dataJson, c.draftDataJson\n FROM ancestor_path ap\n INNER JOIN content_nodes c ON ap.contentId = c.id\n ORDER BY ap.level ASC\n ").all(t, t), i = Array.isArray(n) ? n : n?.results || [], s = /* @__PURE__ */ new Set([
@@ -9294,20 +9309,20 @@ async function Zi(e, t, n, r, i) {
9294
9309
  inheritedFields: a
9295
9310
  };
9296
9311
  }
9297
- function Qi(e) {
9312
+ function $i(e) {
9298
9313
  let t = Number(e?.env?.CMS_NODE_CACHE_TTL);
9299
9314
  return Number.isFinite(t) && t >= 60 ? Math.floor(t) : 300;
9300
9315
  }
9301
- async function $i(e, t, n, r) {
9316
+ async function ea(e, t, n, r) {
9302
9317
  try {
9303
9318
  await e.set(t, n, r);
9304
9319
  } catch (e) {
9305
9320
  console.warn("[CMS Cache] Failed to write node response to cache:", e);
9306
9321
  }
9307
9322
  }
9308
- Ii.get("/*", async (e) => {
9323
+ Li.get("/*", async (e) => {
9309
9324
  try {
9310
- let t = e.get("db"), n = Li(), 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));
9325
+ let t = e.get("db"), n = Ri(), 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));
9311
9326
  if (!c) return e.json({ error: `Channel '${a}' not found` }, 404);
9312
9327
  let l = c.status === "disabled" || c.status === "inactive" || c.isEnabled === 0 || c.isEnabled === !1;
9313
9328
  if (!s && l) return e.json({ error: `Channel '${c.key || a}' is currently inactive` }, 404);
@@ -9332,7 +9347,7 @@ Ii.get("/*", async (e) => {
9332
9347
  if (E.length > 0) {
9333
9348
  let e = await Promise.all(E.map(async (e) => ({
9334
9349
  candidate: e,
9335
- calculatedPath: await Xi(t, String(e.treeNodeId), String(e.treeId), n)
9350
+ calculatedPath: await Zi(t, String(e.treeNodeId), String(e.treeId), n)
9336
9351
  }))), r = S.replace(/^\/+|\/+$/g, "");
9337
9352
  for (let { candidate: t, calculatedPath: n } of e) {
9338
9353
  let e = n.replace(/^\/+|\/+$/g, "");
@@ -9356,7 +9371,7 @@ Ii.get("/*", async (e) => {
9356
9371
  LIMIT 1
9357
9372
  `).get(...e);
9358
9373
  }
9359
- let D = v?.treeId || y || "main-nav", O = v?.parentId || null, k = v?.treeNodeId ? await Xi(t, String(v.treeNodeId), String(D), n) : `/${(_.slug || "").replace(/^\/+|\/+$/g, "")}`, A = {
9374
+ let D = v?.treeId || y || "main-nav", O = v?.parentId || null, k = v?.treeNodeId ? await Zi(t, String(v.treeNodeId), String(D), n) : `/${(_.slug || "").replace(/^\/+|\/+$/g, "")}`, A = {
9360
9375
  id: _.id,
9361
9376
  title: _.title,
9362
9377
  slug: _.slug,
@@ -9374,13 +9389,13 @@ Ii.get("/*", async (e) => {
9374
9389
  M = typeof N == "string" ? JSON.parse(N) : N;
9375
9390
  } catch {}
9376
9391
  M.disabledRegions && (ne = M.disabledRegions), ae = M.hidden === !0 || M.hidden === 1 || M.hidden === "1" || M.hidden === "true", re = M.startShowingAt || null, ie = M.stopShowingAt || null;
9377
- let oe = M.layoutId, se = oe && oe !== "inherit", { resolvedLayoutId: ce, inheritedFields: le } = await Zi(t, O, D, s, j), P = se ? oe : ce || te.defaultLayout || null;
9392
+ let oe = M.layoutId, se = oe && oe !== "inherit", { resolvedLayoutId: ce, inheritedFields: le } = await Qi(t, O, D, s, j), P = se ? oe : ce || te.defaultLayout || null;
9378
9393
  for (let [e, t] of Object.entries(le)) (M[e] === void 0 || M[e] === null || M[e] === "" || M[e] === "inherit") && t !== void 0 && (M[e] = t);
9379
- let F = await oi(t, Hi(M, j));
9380
- F = Ui(F), F = await Wi(t, F, n);
9381
- let ue = Yi(F);
9394
+ let F = await oi(t, Ui(M, j));
9395
+ F = Wi(F), F = await Gi(t, F, n);
9396
+ let ue = Xi(F);
9382
9397
  delete F.socialImage, delete F.fbImage, delete F.xImage, delete F.whatsappImage, ue && (F.socialImages = ue), A.slug = _.slug, A.title = _.title, Object.assign(A, F), A.layoutId = P;
9383
- let de = Number(_.isHidden) === 1 || ae, fe = !zi(re, ie);
9398
+ let de = Number(_.isHidden) === 1 || ae, fe = !Bi(re, ie);
9384
9399
  if (!s && (de || fe)) return e.json({ error: "Node is hidden or outside its scheduled publishing window" }, 404);
9385
9400
  let pe = [];
9386
9401
  if (v?.treeNodeId) {
@@ -9390,7 +9405,7 @@ Ii.get("/*", async (e) => {
9390
9405
  try {
9391
9406
  t = (typeof n == "string" ? JSON.parse(n) : n) || {};
9392
9407
  } catch {}
9393
- let i = Number(e.isHidden) === 1 || t.hidden === !0 || t.hidden === 1 || t.hidden === "1", a = zi(t.startShowingAt, t.stopShowingAt), o = (e.slug || "").replace(/^\/+|\/+$/g, "");
9408
+ let i = Number(e.isHidden) === 1 || t.hidden === !0 || t.hidden === 1 || t.hidden === "1", a = Bi(t.startShowingAt, t.stopShowingAt), o = (e.slug || "").replace(/^\/+|\/+$/g, "");
9394
9409
  return !s && (i || !a) ? null : {
9395
9410
  treeNodeId: e.treeNodeId,
9396
9411
  id: e.id,
@@ -9410,10 +9425,10 @@ Ii.get("/*", async (e) => {
9410
9425
  try {
9411
9426
  i = (typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson) || {};
9412
9427
  } catch {}
9413
- let a = i.hidden === !0 || i.hidden === 1 || i.hidden === "1" || i.hidden === "true", o = zi(i.startShowingAt, i.stopShowingAt);
9428
+ let a = i.hidden === !0 || i.hidden === 1 || i.hidden === "1" || i.hidden === "true", o = Bi(i.startShowingAt, i.stopShowingAt);
9414
9429
  if (!s && (a || !o)) return null;
9415
- 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 || e.blockId || e.id), d = Hi(i, l);
9416
- return d = await oi(t, d), d = Ui(d), d = await Wi(t, d, n), d.blockId = u, {
9430
+ 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 || e.blockId || e.id), d = Ui(i, l);
9431
+ return d = await oi(t, d), d = Wi(d), d = await Gi(t, d, n), d.blockId = u, {
9417
9432
  region: r,
9418
9433
  block: {
9419
9434
  instanceId: e.id,
@@ -9438,7 +9453,7 @@ Ii.get("/*", async (e) => {
9438
9453
  for (let [e, r] of Object.entries(ge)) {
9439
9454
  let i = R[e] && R[e].length > 0, a = !!ne[e];
9440
9455
  if (R[e] || (R[e] = [], z[e] = { isInherited: !1 }), (r?.inherit === "parent" || r?.inherit === !0 || r?.inherit === "true" || e === "header" || e === "footer") && !i && !a && O) {
9441
- let r = await Vi(t, O, e, h, s, n);
9456
+ let r = await Hi(t, O, e, h, s, n);
9442
9457
  if (r.blocks.length > 0 && (R[e] = r.blocks, z[e] = {
9443
9458
  isInherited: !0,
9444
9459
  inheritedFromId: r.inheritedFromId,
@@ -9450,7 +9465,7 @@ Ii.get("/*", async (e) => {
9450
9465
  });
9451
9466
  }
9452
9467
  }
9453
- await Promise.all(Object.keys(R).map((e) => Bi(t, R[e], u)));
9468
+ await Promise.all(Object.keys(R).map((e) => Vi(t, R[e], u)));
9454
9469
  let _e = {
9455
9470
  channelId: u || d,
9456
9471
  treeId: D,
@@ -9459,7 +9474,7 @@ Ii.get("/*", async (e) => {
9459
9474
  content: R,
9460
9475
  regionMeta: z
9461
9476
  };
9462
- return !s && !m && (e.header("X-Cache", "MISS"), await $i(f, p, _e, Qi(e))), e.json(_e);
9477
+ return !s && !m && (e.header("X-Cache", "MISS"), await ea(f, p, _e, $i(e))), e.json(_e);
9463
9478
  } catch (t) {
9464
9479
  console.error("[CMS Public API] Error fetching node by path:", t);
9465
9480
  let n = e.env?.ENVIRONMENT === "development";
@@ -9471,8 +9486,8 @@ Ii.get("/*", async (e) => {
9471
9486
  });
9472
9487
  //#endregion
9473
9488
  //#region server/routes/public/tree.ts
9474
- var ea = new e();
9475
- function ta(e, t) {
9489
+ var ta = new e();
9490
+ function na(e, t) {
9476
9491
  let n = /* @__PURE__ */ new Date();
9477
9492
  if (e && String(e).trim() !== "") {
9478
9493
  let t = new Date(e);
@@ -9484,14 +9499,14 @@ function ta(e, t) {
9484
9499
  }
9485
9500
  return !0;
9486
9501
  }
9487
- async function na(e, t, n, r) {
9502
+ async function ra(e, t, n, r) {
9488
9503
  try {
9489
9504
  await e.set(t, n, r);
9490
9505
  } catch (e) {
9491
9506
  console.warn("[CMS Cache] Failed to write tree response to cache:", e);
9492
9507
  }
9493
9508
  }
9494
- ea.get("/:treeParam", async (e) => {
9509
+ ta.get("/:treeParam", async (e) => {
9495
9510
  try {
9496
9511
  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";
9497
9512
  if (r && r !== "default" && r !== "all") {
@@ -9545,7 +9560,7 @@ ea.get("/:treeParam", async (e) => {
9545
9560
  return (p.get(n) || []).map((e) => {
9546
9561
  let n = m.get(String(e.treeNodeId)) || {}, r = {};
9547
9562
  for (let [e, t] of Object.entries(n)) e !== "_isTreeDraft" && e !== "_draftParentId" && e !== "isNew" && e !== "hidden" && e !== "is_hidden" && e !== "isHidden" && e !== "status" && (r[e] = t);
9548
- 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 = ta(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 = {
9563
+ 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 = na(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 = {
9549
9564
  id: e.id,
9550
9565
  treeNodeId: e.treeNodeId,
9551
9566
  parentId: e.parentId || null,
@@ -9570,7 +9585,7 @@ ea.get("/:treeParam", async (e) => {
9570
9585
  ...d,
9571
9586
  items: h(null)
9572
9587
  };
9573
- return !i && !s && (e.header("X-Cache", "MISS"), await na(a, o, g, 300)), e.json(g);
9588
+ return !i && !s && (e.header("X-Cache", "MISS"), await ra(a, o, g, 300)), e.json(g);
9574
9589
  } catch (t) {
9575
9590
  return console.error("[CMS Public Tree API] Error:", t), e.json({
9576
9591
  error: "Failed to fetch public tree",
@@ -9580,8 +9595,8 @@ ea.get("/:treeParam", async (e) => {
9580
9595
  });
9581
9596
  //#endregion
9582
9597
  //#region server/routes/public/assets.ts
9583
- var ra = new e();
9584
- function ia(e, t) {
9598
+ var ia = new e();
9599
+ function aa(e, t) {
9585
9600
  if (t === "webp") return "image/webp";
9586
9601
  if (t === "avif") return "image/avif";
9587
9602
  if (t === "jpeg" || t === "jpg") return "image/jpeg";
@@ -9589,7 +9604,7 @@ function ia(e, t) {
9589
9604
  let n = e.toLowerCase();
9590
9605
  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";
9591
9606
  }
9592
- ra.get("/*", async (e) => {
9607
+ ia.get("/*", async (e) => {
9593
9608
  let t = e.req.path.replace(/^\/media\//, "").replace(/^\//, "");
9594
9609
  if (!t) return e.text("Asset key missing", 400);
9595
9610
  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 = "";
@@ -9612,7 +9627,7 @@ ra.get("/*", async (e) => {
9612
9627
  c = await n.get(e);
9613
9628
  }
9614
9629
  if (!c) return e.text(`Asset not found: ${t}`, 404);
9615
- let d = c.httpMetadata?.contentType || ia(t), m = d.startsWith("image/") && !d.includes("svg"), g = !1;
9630
+ let d = c.httpMetadata?.contentType || aa(t), m = d.startsWith("image/") && !d.includes("svg"), g = !1;
9616
9631
  if (s && m && e.env?.IMAGES) {
9617
9632
  g = !0;
9618
9633
  try {
@@ -9675,7 +9690,7 @@ ra.get("/*", async (e) => {
9675
9690
  if (!s) {
9676
9691
  let n = _(C);
9677
9692
  return e.body(n, 200, {
9678
- "Content-Type": ia(t),
9693
+ "Content-Type": aa(t),
9679
9694
  "Cache-Control": "public, max-age=86400"
9680
9695
  });
9681
9696
  }
@@ -9683,7 +9698,7 @@ ra.get("/*", async (e) => {
9683
9698
  if (g(f)) {
9684
9699
  let n = _(f);
9685
9700
  return e.body(n, 200, {
9686
- "Content-Type": ia(t, u),
9701
+ "Content-Type": aa(t, u),
9687
9702
  "Cache-Control": "public, max-age=31536000, immutable",
9688
9703
  "X-Local-Cache": "HIT"
9689
9704
  });
@@ -9696,14 +9711,14 @@ ra.get("/*", async (e) => {
9696
9711
  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 }));
9697
9712
  let s = await i.toBuffer();
9698
9713
  return v(x(f), { recursive: !0 }), y(f, s), e.body(s, 200, {
9699
- "Content-Type": ia(t, u),
9714
+ "Content-Type": aa(t, u),
9700
9715
  "Cache-Control": "public, max-age=31536000, immutable",
9701
9716
  "X-Local-Cache": "MISS"
9702
9717
  });
9703
9718
  } catch {
9704
9719
  let n = _(C);
9705
9720
  return e.body(n, 200, {
9706
- "Content-Type": ia(t),
9721
+ "Content-Type": aa(t),
9707
9722
  "Cache-Control": "public, max-age=86400"
9708
9723
  });
9709
9724
  }
@@ -9714,8 +9729,8 @@ ra.get("/*", async (e) => {
9714
9729
  });
9715
9730
  //#endregion
9716
9731
  //#region server/routes/public/paths.ts
9717
- var aa = new e();
9718
- function oa(e, t) {
9732
+ var oa = new e();
9733
+ function sa(e, t) {
9719
9734
  let n = /* @__PURE__ */ new Date();
9720
9735
  if (e && String(e).trim() !== "") {
9721
9736
  let t = new Date(e);
@@ -9727,7 +9742,7 @@ function oa(e, t) {
9727
9742
  }
9728
9743
  return !0;
9729
9744
  }
9730
- aa.get("/", async (e) => {
9745
+ oa.get("/", async (e) => {
9731
9746
  try {
9732
9747
  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();
9733
9748
  for (let e of n) {
@@ -9751,7 +9766,7 @@ aa.get("/", async (e) => {
9751
9766
  function o(e = null, t = "") {
9752
9767
  let n = e == null || e === "" || e === "null" ? "__ROOT__" : String(e), s = i.get(n) || [];
9753
9768
  for (let e of s) {
9754
- let n = a.get(String(e.treeNodeId)) || {}, i = e.status === "published" || e.status === "active", s = oa(n.startShowingAt, n.stopShowingAt);
9769
+ let n = a.get(String(e.treeNodeId)) || {}, i = e.status === "published" || e.status === "active", s = sa(n.startShowingAt, n.stopShowingAt);
9755
9770
  if (!i || !s) continue;
9756
9771
  let c = (e.slug || "").replace(/^\/+|\/+$/g, ""), l = c === "home" || c === "homee" ? "/" : `${t}/${c}`.replace(/\/+/g, "/");
9757
9772
  e.nodeType !== "external-link" && r.push(l);
@@ -9768,7 +9783,7 @@ aa.get("/", async (e) => {
9768
9783
  });
9769
9784
  //#endregion
9770
9785
  //#region server/index.ts
9771
- var $ = new e(), sa = !1;
9786
+ var $ = new e(), ca = !1;
9772
9787
  $.use("*", o()), $.use("/media/*", o({
9773
9788
  origin: "*",
9774
9789
  allowMethods: [
@@ -9789,13 +9804,13 @@ $.use("*", o()), $.use("/media/*", o({
9789
9804
  let n = new URL(e.req.url), r = (e.req.header("host") || n.hostname).split(":")[0];
9790
9805
  e.set("currentDomain", r);
9791
9806
  let i = u(e);
9792
- if (e.set("db", i), !sa) try {
9793
- await Mr(i), sa = !0;
9807
+ if (e.set("db", i), !ca) try {
9808
+ await Mr(i), ca = !0;
9794
9809
  } catch (e) {
9795
9810
  console.error("❌ [CMS Server] Failed to initialize system tables on cold start:", e);
9796
9811
  }
9797
9812
  await t();
9798
- }), $.route("/media", ra), $.use("/media/*", Fr()), $.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", bi), $.route("/api/cms/channels", wi), $.route("/api/cms/channels.json", wi), $.route("/api/cms/schemas", Ti), $.route("/api/cms/schemas.json", Ti), $.route("/api/cms", Oi), $.route("/api/admin/assets", Mi), $.route("/api/v1/node", Ii), $.route("/api/v1/page", Ii), $.route("/api/v1/tree", ea), $.route("/api/v1/all-paths", aa), $.get("*", async (e) => {
9813
+ }), $.route("/media", ia), $.use("/media/*", Fr()), $.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", bi), $.route("/api/cms/channels", Ti), $.route("/api/cms/channels.json", Ti), $.route("/api/cms/schemas", Ei), $.route("/api/cms/schemas.json", Ei), $.route("/api/cms", ki), $.route("/api/admin/assets", Ni), $.route("/api/v1/node", Li), $.route("/api/v1/page", Li), $.route("/api/v1/tree", ta), $.route("/api/v1/all-paths", oa), $.get("*", async (e) => {
9799
9814
  if (e.env?.ASSETS) {
9800
9815
  let t = await e.env.ASSETS.fetch(e.req.raw);
9801
9816
  if (t.status === 404) {