@brightsideoy/kama 1.0.0-alpha.13 → 1.0.0-alpha.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/bin/cli.js +282 -158
  2. package/dist/assets/AssetEditor-CEHxvQj0.js +1 -0
  3. package/dist/assets/AssetEditor-D5j7pwcK.css +1 -0
  4. package/dist/assets/CmsHelp-BO_vWABq.css +1 -0
  5. package/dist/assets/CmsHelp-Cnr801lx.js +1 -0
  6. package/dist/assets/CmsPublisher-C3fRoBte.js +3 -0
  7. package/dist/assets/CmsPublisher-CugEqTD8.css +1 -0
  8. package/dist/assets/CmsUserCenter-Ac0GywlR.css +1 -0
  9. package/dist/assets/CmsUserCenter-DiuXfjMc.js +1 -0
  10. package/dist/assets/EditorSplitPreview-BzKh4wFB.css +1 -0
  11. package/dist/assets/EditorSplitPreview-tpZZF1o5.js +1 -0
  12. package/dist/assets/NodeEditor-Bd89OptF.css +1 -0
  13. package/dist/assets/NodeEditor-DaCIVPGT.js +147 -0
  14. package/dist/assets/TrashWorkspace-CTq0OFA-.js +1 -0
  15. package/dist/assets/TrashWorkspace-DtMgxg13.css +1 -0
  16. package/dist/assets/_plugin-vue_export-helper-CTn6xl4w.js +5 -0
  17. package/dist/assets/history-XvWNE5zO.js +1 -0
  18. package/dist/assets/index-BbV9FaG-.css +1 -0
  19. package/dist/assets/index-CHczMewv.js +14 -0
  20. package/dist/assets/layers-D0DLWjff.js +1 -0
  21. package/dist/assets/link-Bs_SUS0O.js +1 -0
  22. package/dist/assets/rotate-ccw-CvD7yNQj.js +1 -0
  23. package/dist/assets/save-C8e-QRkP.js +1 -0
  24. package/dist/assets/smartphone-Wy6xQi_i.js +1 -0
  25. package/dist/{dist-kIJlDMvm.js → dist-Ca4GRlV3.js} +619 -535
  26. package/dist/index.html +3 -2
  27. package/dist/index.js +619 -535
  28. package/dist/schema-compiler.js +1 -1
  29. package/package.json +1 -1
  30. package/schema.sql +3 -0
  31. package/templates/astro-starter/src/components/blocks/NodeList.astro +59 -63
  32. package/templates/astro-starter/src/middleware.ts +63 -35
  33. package/templates/astro-starter/src/pages/[...slug].astro +5 -12
  34. package/templates/astro-starter/src/pages/api/load-nodes.ts +42 -14
  35. package/templates/astro-starter/src/pages/api/partials/node-cards.astro +101 -0
  36. package/templates/kama-worker/setup-local-db.mjs +17 -0
  37. package/dist/assets/index-B1ogCRCg.js +0 -164
  38. package/dist/assets/index-CGLx9oqF.css +0 -1
package/dist/index.js CHANGED
@@ -278,9 +278,9 @@ function D(e, t) {
278
278
  return r && E.setMetadataInRegistry(t, r), t;
279
279
  });
280
280
  }
281
- function O(e) {
281
+ function te(e) {
282
282
  e.ZodType.prototype.openapi === void 0 && (e.ZodType.prototype.openapi = function(...e) {
283
- let { refId: t, metadata: n, options: r } = te(...e), i = n ?? {}, { param: a } = i, o = s(i, ["param"]), c = E.getMetadataFromRegistry(this) ?? {}, { _internal: u } = c, d = s(c, ["_internal"]), f = Object.assign(Object.assign(Object.assign({}, u), r), t ? { refId: t } : void 0), p = Object.assign(Object.assign(Object.assign({}, d), o), d?.param || a ? { param: Object.assign(Object.assign({}, d?.param), a) } : void 0), m = new this.constructor(this._def);
283
+ let { refId: t, metadata: n, options: r } = O(...e), i = n ?? {}, { param: a } = i, o = s(i, ["param"]), c = E.getMetadataFromRegistry(this) ?? {}, { _internal: u } = c, d = s(c, ["_internal"]), f = Object.assign(Object.assign(Object.assign({}, u), r), t ? { refId: t } : void 0), p = Object.assign(Object.assign(Object.assign({}, d), o), d?.param || a ? { param: Object.assign(Object.assign({}, d?.param), a) } : void 0), m = new this.constructor(this._def);
284
284
  function h(e) {
285
285
  E.setMetadataInRegistry(e, Object.assign(Object.assign({}, Object.keys(f).length > 0 ? { _internal: f } : void 0), p));
286
286
  }
@@ -306,7 +306,7 @@ function O(e) {
306
306
  }, m;
307
307
  });
308
308
  }
309
- function te(e, t, n) {
309
+ function O(e, t, n) {
310
310
  return typeof e == "string" ? {
311
311
  refId: e,
312
312
  metadata: t,
@@ -16707,7 +16707,7 @@ var $y = class t extends e {
16707
16707
  };
16708
16708
  return Object.defineProperty(t, "getRoutingPath", { enumerable: !1 });
16709
16709
  };
16710
- O(Xy);
16710
+ te(Xy);
16711
16711
  function tb(e, t) {
16712
16712
  let n = {};
16713
16713
  return Object.keys(e.paths).forEach((r) => {
@@ -22198,7 +22198,7 @@ var Tb = /* @__PURE__ */ o({
22198
22198
  channels: "\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n key TEXT UNIQUE NOT NULL,\n label TEXT NOT NULL,\n channelType TEXT,\n domain TEXT,\n baseUrl TEXT,\n defaultLanguage TEXT,\n isHidden INTEGER NOT NULL DEFAULT 0,\n dataJson TEXT,\n createdById TEXT,\n updatedById TEXT,\n createdAt TEXT DEFAULT CURRENT_TIMESTAMP,\n updatedAt TEXT DEFAULT CURRENT_TIMESTAMP,\n FOREIGN KEY (createdById) REFERENCES users(id) ON DELETE SET NULL,\n FOREIGN KEY (updatedById) REFERENCES users(id) ON DELETE SET NULL\n ",
22199
22199
  trees: "\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n key TEXT UNIQUE NOT NULL,\n label TEXT NOT NULL,\n treeType TEXT,\n channelId INTEGER,\n isHidden INTEGER NOT NULL DEFAULT 0,\n dataJson TEXT,\n createdById TEXT,\n updatedById TEXT,\n createdAt TEXT DEFAULT CURRENT_TIMESTAMP,\n updatedAt TEXT DEFAULT CURRENT_TIMESTAMP,\n FOREIGN KEY (channelId) REFERENCES channels(id) ON DELETE SET NULL,\n FOREIGN KEY (createdById) REFERENCES users(id) ON DELETE SET NULL,\n FOREIGN KEY (updatedById) REFERENCES users(id) ON DELETE SET NULL\n ",
22200
22200
  channel_trees: "\n channelId INTEGER NOT NULL,\n treeId INTEGER NOT NULL,\n key TEXT NOT NULL DEFAULT 'main',\n metaJson TEXT,\n PRIMARY KEY (channelId, treeId, key),\n FOREIGN KEY (channelId) REFERENCES channels(id) ON DELETE CASCADE,\n FOREIGN KEY (treeId) REFERENCES trees(id) ON DELETE CASCADE\n ",
22201
- content_nodes: "\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n contentType TEXT NOT NULL,\n title TEXT NOT NULL,\n slug TEXT,\n language TEXT,\n isHidden INTEGER NOT NULL DEFAULT 0,\n status TEXT DEFAULT 'draft',\n hasUnpublishedChanges INTEGER DEFAULT 0,\n disabledRegionsJson TEXT DEFAULT '{}',\n dataJson TEXT,\n draftDataJson TEXT,\n publishedDataJson TEXT,\n publishedAt TEXT,\n createdById TEXT,\n updatedById TEXT,\n createdAt TEXT DEFAULT CURRENT_TIMESTAMP,\n updatedAt TEXT DEFAULT CURRENT_TIMESTAMP,\n deletedAt TEXT,\n FOREIGN KEY (createdById) REFERENCES users(id) ON DELETE SET NULL,\n FOREIGN KEY (updatedById) REFERENCES users(id) ON DELETE SET NULL\n ",
22201
+ content_nodes: "\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n contentType TEXT NOT NULL,\n title TEXT NOT NULL,\n slug TEXT,\n language TEXT,\n isHidden INTEGER NOT NULL DEFAULT 0,\n status TEXT DEFAULT 'draft',\n startShowingAt TEXT,\n stopShowingAt TEXT,\n hasUnpublishedChanges INTEGER DEFAULT 0,\n disabledRegionsJson TEXT DEFAULT '{}',\n dataJson TEXT,\n draftDataJson TEXT,\n publishedDataJson TEXT,\n publishedAt TEXT,\n createdById TEXT,\n updatedById TEXT,\n createdAt TEXT DEFAULT CURRENT_TIMESTAMP,\n updatedAt TEXT DEFAULT CURRENT_TIMESTAMP,\n deletedAt TEXT,\n FOREIGN KEY (createdById) REFERENCES users(id) ON DELETE SET NULL,\n FOREIGN KEY (updatedById) REFERENCES users(id) ON DELETE SET NULL\n ",
22202
22202
  node_channels: "\n nodeId INTEGER NOT NULL,\n channelId INTEGER NOT NULL,\n PRIMARY KEY (nodeId, channelId),\n FOREIGN KEY (nodeId) REFERENCES content_nodes(id) ON DELETE CASCADE,\n FOREIGN KEY (channelId) REFERENCES channels(id) ON DELETE CASCADE\n ",
22203
22203
  tree_nodes: "\n treeId INTEGER NOT NULL,\n contentId INTEGER NOT NULL,\n parentId INTEGER,\n sortOrder INTEGER DEFAULT 0,\n PRIMARY KEY (treeId, contentId),\n FOREIGN KEY (treeId) REFERENCES trees(id) ON DELETE CASCADE,\n FOREIGN KEY (contentId) REFERENCES content_nodes(id) ON DELETE CASCADE,\n FOREIGN KEY (parentId) REFERENCES content_nodes(id) ON DELETE CASCADE\n ",
22204
22204
  content_blocks: "\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n contentId INTEGER NOT NULL,\n region TEXT DEFAULT 'main',\n elementType TEXT NOT NULL,\n dataJson TEXT,\n sortOrder INTEGER DEFAULT 0,\n isDraft INTEGER NOT NULL DEFAULT 1,\n FOREIGN KEY (contentId) REFERENCES content_nodes(id) ON DELETE CASCADE\n ",
@@ -22209,11 +22209,11 @@ var Tb = /* @__PURE__ */ o({
22209
22209
  node_terms: "\n nodeId INTEGER NOT NULL,\n termId INTEGER NOT NULL,\n fieldKey TEXT NOT NULL,\n sortOrder INTEGER DEFAULT 0,\n PRIMARY KEY (nodeId, termId, fieldKey),\n FOREIGN KEY (nodeId) REFERENCES content_nodes(id) ON DELETE CASCADE,\n FOREIGN KEY (termId) REFERENCES taxonomy_terms(id) ON DELETE CASCADE\n ",
22210
22210
  node_relations: "\n sourceNodeId INTEGER NOT NULL,\n targetNodeId INTEGER NOT NULL,\n fieldKey TEXT NOT NULL,\n sortOrder INTEGER DEFAULT 0,\n PRIMARY KEY (sourceNodeId, targetNodeId, fieldKey),\n FOREIGN KEY (sourceNodeId) REFERENCES content_nodes(id) ON DELETE CASCADE,\n FOREIGN KEY (targetNodeId) REFERENCES content_nodes(id) ON DELETE CASCADE\n ",
22211
22211
  node_routes: "\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n path TEXT NOT NULL,\n channelId INTEGER NOT NULL,\n nodeId INTEGER,\n treeId INTEGER,\n isCanonical INTEGER DEFAULT 1,\n redirectUrl TEXT,\n createdAt TEXT DEFAULT CURRENT_TIMESTAMP,\n updatedAt TEXT DEFAULT CURRENT_TIMESTAMP,\n FOREIGN KEY (channelId) REFERENCES channels(id) ON DELETE CASCADE,\n FOREIGN KEY (nodeId) REFERENCES content_nodes(id) ON DELETE CASCADE,\n FOREIGN KEY (treeId) REFERENCES trees(id) ON DELETE CASCADE,\n UNIQUE(path, channelId)\n "
22212
- }, kb = /* @__PURE__ */ "CREATE INDEX IF NOT EXISTS idx_tree_nodes_tree_parent ON tree_nodes(treeId, parentId);.CREATE INDEX IF NOT EXISTS idx_tree_nodes_contentId ON tree_nodes(contentId);.CREATE INDEX IF NOT EXISTS idx_content_nodes_slug_status ON content_nodes(slug, status);.CREATE INDEX IF NOT EXISTS idx_content_blocks_node ON content_blocks(contentId, isDraft);.CREATE INDEX IF NOT EXISTS idx_node_assets_nodeId ON node_assets(nodeId);.CREATE INDEX IF NOT EXISTS idx_node_assets_assetId ON node_assets(assetId);.CREATE INDEX IF NOT EXISTS idx_content_schemas_type ON content_schemas(type);.CREATE INDEX IF NOT EXISTS idx_sessions_user ON sessions(userId);.CREATE INDEX IF NOT EXISTS idx_sessions_expires ON sessions(expiresAt);.CREATE INDEX IF NOT EXISTS idx_channels_visibility ON channels(isHidden);.CREATE INDEX IF NOT EXISTS idx_trees_visibility ON trees(isHidden);.CREATE INDEX IF NOT EXISTS idx_content_nodes_visibility ON content_nodes(isHidden, status);.CREATE INDEX IF NOT EXISTS idx_content_nodes_slug ON content_nodes(slug);.CREATE INDEX IF NOT EXISTS idx_content_nodes_type ON content_nodes(contentType);.CREATE INDEX IF NOT EXISTS idx_content_nodes_deleted_updated ON content_nodes(deletedAt, updatedAt DESC);.CREATE INDEX IF NOT EXISTS idx_tree_nodes_hierarchy ON tree_nodes(treeId, parentId, sortOrder);.CREATE INDEX IF NOT EXISTS idx_tree_nodes_content ON tree_nodes(contentId, treeId);.CREATE INDEX IF NOT EXISTS idx_content_blocks_content ON content_blocks(contentId, isDraft, region, sortOrder);.CREATE INDEX IF NOT EXISTS idx_node_channels_channel ON node_channels(channelId, nodeId);.CREATE INDEX IF NOT EXISTS idx_node_channels_node ON node_channels(nodeId, channelId);.CREATE INDEX IF NOT EXISTS idx_node_assets_node_asset ON node_assets(nodeId, assetId);.CREATE INDEX IF NOT EXISTS idx_node_assets_asset_node ON node_assets(assetId, nodeId);.CREATE UNIQUE INDEX IF NOT EXISTS idx_node_revisions_version ON node_revisions(nodeId, version);.CREATE INDEX IF NOT EXISTS idx_assets_system_created ON assets(isSystemVariant, createdAt DESC);.CREATE INDEX IF NOT EXISTS idx_assets_system_mime ON assets(isSystemVariant, mimeType);.CREATE INDEX IF NOT EXISTS idx_assets_deleted ON assets(deletedAt);.CREATE INDEX IF NOT EXISTS idx_assets_parent ON assets(parentAssetId);.CREATE INDEX IF NOT EXISTS idx_taxonomy_terms_tax ON taxonomy_terms(taxonomy);.CREATE INDEX IF NOT EXISTS idx_node_terms_node ON node_terms(nodeId);.CREATE INDEX IF NOT EXISTS idx_node_terms_term ON node_terms(termId);.CREATE INDEX IF NOT EXISTS idx_node_terms_node_term ON node_terms(nodeId, termId);.CREATE INDEX IF NOT EXISTS idx_node_terms_term_node ON node_terms(termId, nodeId);.CREATE INDEX IF NOT EXISTS idx_node_relations_source ON node_relations(sourceNodeId);.CREATE INDEX IF NOT EXISTS idx_node_relations_target ON node_relations(targetNodeId);.CREATE INDEX IF NOT EXISTS idx_node_routes_lookup ON node_routes(path, channelId);.CREATE INDEX IF NOT EXISTS idx_node_routes_node ON node_routes(nodeId);".split(".");
22212
+ }, kb = /* @__PURE__ */ "CREATE INDEX IF NOT EXISTS idx_tree_nodes_tree_parent ON tree_nodes(treeId, parentId);.CREATE INDEX IF NOT EXISTS idx_tree_nodes_contentId ON tree_nodes(contentId);.CREATE INDEX IF NOT EXISTS idx_content_nodes_slug_status ON content_nodes(slug, status);.CREATE INDEX IF NOT EXISTS idx_content_blocks_node ON content_blocks(contentId, isDraft);.CREATE INDEX IF NOT EXISTS idx_node_assets_nodeId ON node_assets(nodeId);.CREATE INDEX IF NOT EXISTS idx_node_assets_assetId ON node_assets(assetId);.CREATE INDEX IF NOT EXISTS idx_content_schemas_type ON content_schemas(type);.CREATE INDEX IF NOT EXISTS idx_sessions_user ON sessions(userId);.CREATE INDEX IF NOT EXISTS idx_sessions_expires ON sessions(expiresAt);.CREATE INDEX IF NOT EXISTS idx_channels_visibility ON channels(isHidden);.CREATE INDEX IF NOT EXISTS idx_trees_visibility ON trees(isHidden);.CREATE INDEX IF NOT EXISTS idx_content_nodes_visibility ON content_nodes(isHidden, status);.CREATE INDEX IF NOT EXISTS idx_content_nodes_slug ON content_nodes(slug);.CREATE INDEX IF NOT EXISTS idx_content_nodes_type ON content_nodes(contentType);.CREATE INDEX IF NOT EXISTS idx_content_nodes_deleted_updated ON content_nodes(deletedAt, updatedAt DESC);.CREATE INDEX IF NOT EXISTS idx_tree_nodes_hierarchy ON tree_nodes(treeId, parentId, sortOrder);.CREATE INDEX IF NOT EXISTS idx_tree_nodes_content ON tree_nodes(contentId, treeId);.CREATE INDEX IF NOT EXISTS idx_content_blocks_content ON content_blocks(contentId, isDraft, region, sortOrder);.CREATE INDEX IF NOT EXISTS idx_node_channels_channel ON node_channels(channelId, nodeId);.CREATE INDEX IF NOT EXISTS idx_node_channels_node ON node_channels(nodeId, channelId);.CREATE INDEX IF NOT EXISTS idx_node_assets_node_asset ON node_assets(nodeId, assetId);.CREATE INDEX IF NOT EXISTS idx_node_assets_asset_node ON node_assets(assetId, nodeId);.CREATE UNIQUE INDEX IF NOT EXISTS idx_node_revisions_version ON node_revisions(nodeId, version);.CREATE INDEX IF NOT EXISTS idx_assets_system_created ON assets(isSystemVariant, createdAt DESC);.CREATE INDEX IF NOT EXISTS idx_assets_system_mime ON assets(isSystemVariant, mimeType);.CREATE INDEX IF NOT EXISTS idx_assets_deleted ON assets(deletedAt);.CREATE INDEX IF NOT EXISTS idx_assets_parent ON assets(parentAssetId);.CREATE INDEX IF NOT EXISTS idx_taxonomy_terms_tax ON taxonomy_terms(taxonomy);.CREATE INDEX IF NOT EXISTS idx_node_terms_node ON node_terms(nodeId);.CREATE INDEX IF NOT EXISTS idx_node_terms_term ON node_terms(termId);.CREATE INDEX IF NOT EXISTS idx_node_terms_node_term ON node_terms(nodeId, termId);.CREATE INDEX IF NOT EXISTS idx_node_terms_term_node ON node_terms(termId, nodeId);.CREATE INDEX IF NOT EXISTS idx_node_relations_source ON node_relations(sourceNodeId);.CREATE INDEX IF NOT EXISTS idx_node_relations_target ON node_relations(targetNodeId);.CREATE INDEX IF NOT EXISTS idx_node_routes_lookup ON node_routes(path, channelId);.CREATE INDEX IF NOT EXISTS idx_node_routes_node ON node_routes(nodeId);.CREATE INDEX IF NOT EXISTS idx_content_nodes_public_feed ON content_nodes(contentType, isHidden, status, startShowingAt, stopShowingAt, updatedAt DESC);".split(".");
22213
22213
  function Ab(e) {
22214
22214
  let t = /* @__PURE__ */ new Set();
22215
22215
  function n(e) {
22216
- if (!(typeof e != "object" || !e)) for (let [r, i] of Object.entries(e)) typeof i == "object" && i && (i.index === !0 && r !== "id" && r !== "slug" && r !== "contentType" && t.add(`CREATE INDEX IF NOT EXISTS idx_content_nodes_${r} ON content_nodes (json_extract(dataJson, '$.${r}'));`), n(i));
22216
+ if (!(typeof e != "object" || !e)) for (let [r, i] of Object.entries(e)) typeof i == "object" && i && (i.index === !0 && r !== "id" && r !== "slug" && r !== "contentType" && r !== "startShowingAt" && r !== "stopShowingAt" && t.add(`CREATE INDEX IF NOT EXISTS idx_content_nodes_${r} ON content_nodes (json_extract(dataJson, '$.${r}'));`), n(i));
22217
22217
  }
22218
22218
  return n(e), Array.from(t);
22219
22219
  }
@@ -22240,6 +22240,18 @@ async function Mb(e, t) {
22240
22240
  if (!n.has("hasUnpublishedChanges")) try {
22241
22241
  await e.prepare("ALTER TABLE \"content_nodes\" ADD COLUMN hasUnpublishedChanges INTEGER DEFAULT 0;").run();
22242
22242
  } catch {}
22243
+ let t = !1;
22244
+ if (!n.has("startShowingAt")) try {
22245
+ await e.prepare("ALTER TABLE \"content_nodes\" ADD COLUMN startShowingAt TEXT;").run(), t = !0;
22246
+ } catch {}
22247
+ if (!n.has("stopShowingAt")) try {
22248
+ await e.prepare("ALTER TABLE \"content_nodes\" ADD COLUMN stopShowingAt TEXT;").run(), t = !0;
22249
+ } catch {}
22250
+ if (t) try {
22251
+ console.log("[Schema Sync] Migrating visibility dates out of JSON payload..."), await e.prepare("\n UPDATE content_nodes \n SET \n startShowingAt = json_extract(dataJson, '$.startShowingAt'),\n stopShowingAt = json_extract(dataJson, '$.stopShowingAt')\n WHERE json_extract(dataJson, '$.startShowingAt') IS NOT NULL \n OR json_extract(dataJson, '$.stopShowingAt') IS NOT NULL;\n ").run(), console.log("[Schema Sync] Date migration complete.");
22252
+ } catch (e) {
22253
+ console.error("[Schema Sync] Failed to backfill dates:", e);
22254
+ }
22243
22255
  }
22244
22256
  if (t === "assets") {
22245
22257
  if (!n.has("parentAssetId")) try {
@@ -23002,7 +23014,9 @@ var Fb = { hasSubscribers: !1 }, Ib = Fb, Lb = Fb, Rb = typeof performance == "o
23002
23014
  }, Qb = null;
23003
23015
  function $b(e) {
23004
23016
  let t = process.env.CACHE_DRIVER || "lru";
23005
- return t === "none" || t === "off" || t === "false" ? new Zb() : e?.env?.CMS_CACHE_KV ? new Xb(e.env.CMS_CACHE_KV) : t === "lru" ? (Qb ||= new Yb(), Qb) : new Zb();
23017
+ if (t === "none" || t === "off" || t === "false") return new Zb();
23018
+ let n = e?.env?.CACHE_KV || e?.env?.CMS_CACHE_KV;
23019
+ return n ? new Xb(n) : t === "lru" ? (Qb ||= new Yb(), Qb) : new Zb();
23006
23020
  }
23007
23021
  //#endregion
23008
23022
  //#region server/storage/local.ts
@@ -23573,6 +23587,7 @@ var mx = class {
23573
23587
  return {
23574
23588
  zoneId: e.env?.CLOUDFLARE_ZONE_ID || this.env.CLOUDFLARE_ZONE_ID,
23575
23589
  apiToken: e.env?.CLOUDFLARE_API_TOKEN || this.env.CLOUDFLARE_API_TOKEN,
23590
+ purgeToken: e.env?.FRONTEND_API_SECRET || this.env.FRONTEND_API_SECRET || e.env?.CLOUDFLARE_API_TOKEN || this.env.CLOUDFLARE_API_TOKEN,
23576
23591
  frontendUrl: (e.env?.PUBLIC_FRONTEND_URL || this.env.PUBLIC_FRONTEND_URL || "http://localhost:4321").replace(/\/+$/, ""),
23577
23592
  cdnDomain: t ? t.replace(/^https?:\/\//, "").replace(/\/+$/, "") : "localhost:8787",
23578
23593
  frontendWorker: e.env?.FRONTEND_WORKER || this.env.FRONTEND_WORKER,
@@ -23600,7 +23615,7 @@ var mx = class {
23600
23615
  return r && n && r.startsWith(`https://${n}/`) && !r.includes("/media/") && (r = r.replace(`https://${n}/`, `https://${n}/media/`)), r;
23601
23616
  }
23602
23617
  async callAstroPurge(e, t, n) {
23603
- let { apiToken: r, frontendUrl: i, frontendWorker: a, disableCachePurge: o } = this.getEnv(e);
23618
+ let { purgeToken: r, frontendUrl: i, frontendWorker: a, disableCachePurge: o } = this.getEnv(e);
23604
23619
  if (o === "true" || o === !0 || o === "1") return new Response(JSON.stringify({ skipped: !0 }), { status: 200 });
23605
23620
  let s = (n || i).replace(/\/+$/, ""), c = `${s}/api/purge`, l = { "Content-Type": "application/json" };
23606
23621
  if (r && (l.Authorization = `Bearer ${r}`), a && typeof a.fetch == "function") try {
@@ -23630,8 +23645,21 @@ var mx = class {
23630
23645
  try {
23631
23646
  let a = $b(e);
23632
23647
  if (n) {
23633
- let e = t.prepare("SELECT treeId FROM tree_nodes WHERE contentId = ?"), r = typeof e.all == "function" ? await e.all(n) : await e.bind(n).all(), i = Array.isArray(r) ? r : r?.results || [];
23634
- for (let e of i) await a.delete(`tree:default:${e.treeId}`), await a.delete(`tree:all:${e.treeId}`);
23648
+ let e = t.prepare("\n SELECT DISTINCT\n t.id AS treeId,\n t.key AS treeKey,\n t.dataJson AS treeDataJson,\n c.id AS channelId,\n c.key AS channelKey,\n c.defaultLanguage AS channelDefaultLanguage\n FROM tree_nodes tn\n JOIN trees t ON t.id = tn.treeId\n LEFT JOIN channel_trees ct ON ct.treeId = t.id\n LEFT JOIN channels c ON c.id = ct.channelId\n WHERE tn.contentId = ?\n "), r = typeof e.all == "function" ? await e.all(n) : await e.bind(n).all(), o = Array.isArray(r) ? r : r?.results || [], s = /* @__PURE__ */ new Set();
23649
+ for (let e of o) {
23650
+ let t = /* @__PURE__ */ new Set(["default", "all"]);
23651
+ e.channelId !== null && e.channelId !== void 0 && t.add(String(e.channelId)), e.channelKey && t.add(String(e.channelKey));
23652
+ let n = /* @__PURE__ */ new Set();
23653
+ e.treeId !== null && e.treeId !== void 0 && n.add(String(e.treeId)), e.treeKey && n.add(String(e.treeKey));
23654
+ let r = /* @__PURE__ */ new Set(["default"]);
23655
+ i && r.add(i.trim()), e.channelDefaultLanguage && r.add(String(e.channelDefaultLanguage).trim());
23656
+ try {
23657
+ let t = typeof e.treeDataJson == "string" ? JSON.parse(e.treeDataJson) : e.treeDataJson;
23658
+ (t?.defaultLanguage || t?.language) && r.add(String(t.defaultLanguage || t.language).trim());
23659
+ } catch {}
23660
+ for (let e of t) for (let t of n) for (let n of r) s.add(`tree:${e}:${t}:${n || "default"}`);
23661
+ }
23662
+ await Promise.all(Array.from(s, (e) => a.delete(e)));
23635
23663
  }
23636
23664
  if (r) {
23637
23665
  let e = r.replace(/^\/+|\/+$/g, ""), o = ["default", "1"];
@@ -23645,9 +23673,37 @@ var mx = class {
23645
23673
  console.warn("[CacheManager] Failed to purge internal worker cache:", e);
23646
23674
  }
23647
23675
  }
23676
+ async purgeVisibilityChange(e, t, n) {
23677
+ try {
23678
+ let r = t.prepare("SELECT slug, language FROM content_nodes WHERE id = ?"), i = typeof r.get == "function" ? await r.get(n) : (await r.bind(n).all())?.results?.[0];
23679
+ await this.purgeInternalWorkerCache(e, t, n, i?.slug, i?.language);
23680
+ let a = await this.callAstroPurge(e, { purge_everything: !0 }), o = await a.json().catch(() => ({}));
23681
+ if (!a.ok || o?.success === !1 || o?.skipped) return console.warn(`[CacheManager] Visibility purge failed at Astro Worker (${a.status}).`), !1;
23682
+ let { zoneId: s, apiToken: c } = this.getEnv(e), l = this.isLocalEnv(e);
23683
+ if (s && c && !this.isLocalEnv(e)) {
23684
+ let e = await fetch(`https://api.cloudflare.com/client/v4/zones/${s}/purge_cache`, {
23685
+ method: "POST",
23686
+ headers: {
23687
+ Authorization: `Bearer ${c}`,
23688
+ "Content-Type": "application/json"
23689
+ },
23690
+ body: JSON.stringify({ purge_everything: !0 })
23691
+ }), t = await e.json().catch(() => ({}));
23692
+ l = e.ok && t?.success === !0, l || console.warn("[CacheManager] Visibility purge failed at Cloudflare Zone cache:", JSON.stringify(t));
23693
+ } else this.isLocalEnv(e) || console.warn("[CacheManager] Visibility purge lacks CLOUDFLARE_ZONE_ID or CLOUDFLARE_API_TOKEN.");
23694
+ return this.dispatch(e, this.warmAllPublishedPages(e, t)), l;
23695
+ } catch (e) {
23696
+ return console.warn("[CacheManager] Visibility cache purge failed:", e), !1;
23697
+ }
23698
+ }
23648
23699
  purgeNode(e, t, n, r = !1, i = []) {
23649
23700
  if (r) {
23650
- console.log(`[CacheManager] Structural change detected on nodeId ${n}. Escalating to Global Purge.`), this.purgeGlobalCache(e, t);
23701
+ console.log(`[CacheManager] Structural change detected on nodeId ${n}. Escalating to Global Purge.`);
23702
+ let r = (async () => {
23703
+ let r = t.prepare("SELECT slug, language FROM content_nodes WHERE id = ?"), i = typeof r.get == "function" ? await r.get(n) : (await r.bind(n).all())?.results?.[0];
23704
+ await this.purgeInternalWorkerCache(e, t, n, i?.slug, i?.language), await this.purgeGlobalCacheDirect(e, t);
23705
+ })();
23706
+ this.dispatch(e, r);
23651
23707
  return;
23652
23708
  }
23653
23709
  let a = (async () => {
@@ -23733,8 +23789,12 @@ var mx = class {
23733
23789
  }
23734
23790
  async purgeGlobalCacheDirect(e, t) {
23735
23791
  try {
23736
- let { zoneId: n, apiToken: r } = this.getEnv(e);
23737
- if (!(await this.callAstroPurge(e, { purge_everything: !0 })).ok) return;
23792
+ let { zoneId: n, apiToken: r } = this.getEnv(e), i = await this.callAstroPurge(e, { purge_everything: !0 });
23793
+ if (!i.ok) {
23794
+ let e = await i.text().catch(() => "");
23795
+ console.warn(`[CacheManager] Astro global purge failed (${i.status}): ${e.slice(0, 500)}`);
23796
+ return;
23797
+ }
23738
23798
  if (n && r && !this.isLocalEnv(e)) try {
23739
23799
  let e = await (await fetch(`https://api.cloudflare.com/client/v4/zones/${n}/purge_cache`, {
23740
23800
  method: "POST",
@@ -23876,8 +23936,9 @@ async function hx(e) {
23876
23936
  await e.prepare("DELETE FROM node_routes").run();
23877
23937
  let h = Array.from(p.values());
23878
23938
  if (h.length === 0) return;
23879
- for (let t = 0; t < h.length; t += 50) {
23880
- let n = h.slice(t, t + 50), r = n.map(() => "(?, ?, ?, ?, ?, ?)").join(","), i = n.flatMap((e) => [
23939
+ let g = [];
23940
+ for (let e = 0; e < h.length; e += 15) {
23941
+ let t = h.slice(e, e + 15), n = t.map(() => "(?, ?, ?, ?, ?, ?)").join(","), r = t.flatMap((e) => [
23881
23942
  e.path,
23882
23943
  e.channelId,
23883
23944
  e.nodeId,
@@ -23885,10 +23946,17 @@ async function hx(e) {
23885
23946
  e.isCanonical,
23886
23947
  e.redirectUrl ?? null
23887
23948
  ]);
23888
- await e.prepare(`
23889
- INSERT INTO node_routes (path, channelId, nodeId, treeId, isCanonical, redirectUrl)
23890
- VALUES ${r}
23891
- `).run(...i);
23949
+ g.push({
23950
+ placeholders: n,
23951
+ params: r
23952
+ });
23953
+ }
23954
+ for (let t = 0; t < g.length; t += 50) {
23955
+ let n = g.slice(t, t + 50);
23956
+ await Promise.all(n.map((t) => e.prepare(`
23957
+ INSERT INTO node_routes (path, channelId, nodeId, treeId, isCanonical, redirectUrl)
23958
+ VALUES ${t.placeholders}
23959
+ `).run(...t.params)));
23892
23960
  }
23893
23961
  console.log(`[Route Generator] Successfully built ${h.length} enterprise routes.`);
23894
23962
  } catch (e) {
@@ -23898,7 +23966,25 @@ async function hx(e) {
23898
23966
  //#endregion
23899
23967
  //#region server/routes/admin/nodes.ts
23900
23968
  var gx = new e();
23901
- async function _x(e, t, n = []) {
23969
+ function _x(e, t, n = []) {
23970
+ let r = new mx(e.env), i = (async () => {
23971
+ for (let i of n) {
23972
+ let n = t.prepare("SELECT slug, language FROM content_nodes WHERE id = ?"), a = typeof n.get == "function" ? await n.get(i) : (await n.bind(i).all())?.results?.[0];
23973
+ await r.purgeInternalWorkerCache(e, t, i, a?.slug, a?.language);
23974
+ }
23975
+ await hx(t), await r.purgeGlobalCacheDirect(e, t);
23976
+ })().catch((e) => {
23977
+ console.error("[Node Routes] Background rebuild/purge failed:", e);
23978
+ });
23979
+ try {
23980
+ let t = e.executionCtx;
23981
+ if (t && typeof t.waitUntil == "function") {
23982
+ t.waitUntil(i);
23983
+ return;
23984
+ }
23985
+ } catch {}
23986
+ }
23987
+ async function vx(e, t, n = []) {
23902
23988
  let r = e.prepare(t);
23903
23989
  if (typeof r.bind == "function") {
23904
23990
  let e = await r.bind(...n).all();
@@ -23910,75 +23996,50 @@ async function _x(e, t, n = []) {
23910
23996
  }
23911
23997
  return [];
23912
23998
  }
23913
- async function vx(e, t, n = []) {
23999
+ async function yx(e, t, n = []) {
23914
24000
  let r = e.prepare(t);
23915
24001
  if (typeof r.bind == "function") return r.bind(...n).run();
23916
24002
  if (typeof r.run == "function") return r.run(...n);
23917
24003
  }
23918
- function yx(e) {
24004
+ function bx(e) {
23919
24005
  return !e || !e.trim() ? null : e.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().trim().replace(/[^a-z0-9\s-]/g, "").replace(/[\s-]+/g, "-").replace(/^-+|-+$/g, "") || null;
23920
24006
  }
23921
- function bx(e) {
24007
+ function xx(e) {
23922
24008
  return +(e === !0 || e === 1 || e === "1" || e === "true");
23923
24009
  }
23924
- function xx(e) {
24010
+ function Sx(e) {
23925
24011
  if (e == null || e === "null" || e === "" || typeof e == "string" && e.startsWith("draft-")) return null;
23926
24012
  let t = Number(e);
23927
24013
  return isNaN(t) ? null : t;
23928
24014
  }
23929
- function Sx(e) {
24015
+ function Cx(e) {
23930
24016
  let t = { ...e };
23931
24017
  delete t.language, delete t.defaultLanguage;
23932
- for (let e of [
23933
- "id",
23934
- "treeNodeId",
23935
- "isNew",
23936
- "_isTreeDraft",
23937
- "_draftParentId",
23938
- "nodeType",
23939
- "contentType",
23940
- "title",
23941
- "slug",
23942
- "path",
23943
- "routePath",
23944
- "hidden",
23945
- "is_hidden",
23946
- "isHidden",
23947
- "status",
23948
- "createdById",
23949
- "updatedById",
23950
- "draftDataJson",
23951
- "publishedDataJson",
23952
- "publishedAt",
23953
- "deletedAt",
23954
- "channelNames",
23955
- "treeNames",
23956
- "hasUnpublishedChanges"
23957
- ]) delete t[e];
24018
+ for (let e of /* @__PURE__ */ "id.treeNodeId.isNew._isTreeDraft._draftParentId.nodeType.contentType.title.slug.path.routePath.hidden.is_hidden.isHidden.startShowingAt.stopShowingAt.status.createdById.updatedById.draftDataJson.publishedDataJson.publishedAt.deletedAt.channelNames.treeNames.hasUnpublishedChanges".split(".")) delete t[e];
23958
24019
  return t;
23959
24020
  }
23960
- function Cx(e, t = /* @__PURE__ */ new Set()) {
23961
- return e ? typeof e == "string" ? (e.startsWith("ast_") && t.add(e), t) : Array.isArray(e) ? (e.forEach((e) => Cx(e, t)), t) : (typeof e == "object" && Object.values(e).forEach((e) => Cx(e, t)), t) : t;
24021
+ function wx(e, t = /* @__PURE__ */ new Set()) {
24022
+ return e ? typeof e == "string" ? (e.startsWith("ast_") && t.add(e), t) : Array.isArray(e) ? (e.forEach((e) => wx(e, t)), t) : (typeof e == "object" && Object.values(e).forEach((e) => wx(e, t)), t) : t;
23962
24023
  }
23963
- function wx(e, t) {
24024
+ function Tx(e, t) {
23964
24025
  if (!e) return !0;
23965
- let n = t.title !== void 0 && t.title?.trim() !== e.title?.trim(), r = t.slug !== void 0 && t.slug !== e.slug, i = t.isHidden !== void 0 && bx(t.isHidden) !== bx(e.isHidden), a = t.status !== void 0 && t.status !== e.status, o = typeof e.draftDataJson == "string" ? JSON.parse(e.draftDataJson || "{}") : e.draftDataJson || {}, s = t.sanitizedFields || {}, c = s.menuTitle !== void 0 && s.menuTitle !== o.menuTitle;
23966
- return n || r || i || a || c;
24026
+ let n = t.title !== void 0 && t.title?.trim() !== e.title?.trim(), r = t.slug !== void 0 && t.slug !== e.slug, i = t.isHidden !== void 0 && xx(t.isHidden) !== xx(e.isHidden), a = t.status !== void 0 && t.status !== e.status, o = t.startShowingAt !== void 0 && t.startShowingAt !== e.startShowingAt, s = t.stopShowingAt !== void 0 && t.stopShowingAt !== e.stopShowingAt, c = typeof e.draftDataJson == "string" ? JSON.parse(e.draftDataJson || "{}") : e.draftDataJson || {}, l = t.sanitizedFields || {}, u = l.menuTitle !== void 0 && l.menuTitle !== c.menuTitle;
24027
+ return n || r || i || a || o || s || u;
23967
24028
  }
23968
- async function Tx(e, t, n) {
24029
+ async function Ex(e, t, n) {
23969
24030
  for (let r of n) {
23970
- let n = (await _x(e, "\n SELECT id, storageKeyPrivate, isSystemVariant, parentAssetId, filename\n FROM assets WHERE id = ?\n ", [r]))[0];
23971
- if (n && n.isSystemVariant && !((await _x(e, "SELECT 1 FROM node_assets WHERE assetId = ? LIMIT 1", [n.id])).length > 0)) {
24031
+ let n = (await vx(e, "\n SELECT id, storageKeyPrivate, isSystemVariant, parentAssetId, filename\n FROM assets WHERE id = ?\n ", [r]))[0];
24032
+ if (n && n.isSystemVariant && !((await vx(e, "SELECT 1 FROM node_assets WHERE assetId = ? LIMIT 1", [n.id])).length > 0)) {
23972
24033
  if (n.storageKeyPrivate) try {
23973
24034
  await t.delete(n.storageKeyPrivate);
23974
24035
  } catch (e) {
23975
24036
  console.warn(`[Asset Cleanup] Failed to delete crop ${n.storageKeyPrivate}:`, e);
23976
24037
  }
23977
- await vx(e, "DELETE FROM node_assets WHERE assetId = ?", [n.id]), await vx(e, "DELETE FROM assets WHERE id = ?", [n.id]);
24038
+ await yx(e, "DELETE FROM node_assets WHERE assetId = ?", [n.id]), await yx(e, "DELETE FROM assets WHERE id = ?", [n.id]);
23978
24039
  }
23979
24040
  }
23980
24041
  }
23981
- async function Ex(e, t, n) {
24042
+ async function Dx(e, t, n) {
23982
24043
  let r = {}, i = null;
23983
24044
  if (t) {
23984
24045
  let a = await e.prepare("\n WITH RECURSIVE ancestor_path(id, parentId, draftDataJson, dataJson, level) AS (\n SELECT t.contentId as id, t.parentId, c.draftDataJson, c.dataJson, 0\n FROM tree_nodes t\n INNER JOIN content_nodes c ON t.contentId = c.id\n WHERE t.contentId = ? AND t.treeId = ?\n UNION ALL\n SELECT t.contentId as id, t.parentId, c.draftDataJson, c.dataJson, 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.contentId = ap.parentId AND t.treeId = ?\n )\n SELECT draftDataJson, dataJson FROM ancestor_path ORDER BY level ASC\n ").all(t, n, n), o = Array.isArray(a) ? a : a?.results || [];
@@ -24027,6 +24088,8 @@ gx.get("/", async (e) => {
24027
24088
  nodeType: i.contentType,
24028
24089
  contentType: i.contentType,
24029
24090
  isHidden: !!i.isHidden,
24091
+ startShowingAt: i.startShowingAt || null,
24092
+ stopShowingAt: i.stopShowingAt || null,
24030
24093
  status: i.status || "draft",
24031
24094
  publishedAt: i.publishedAt || null,
24032
24095
  hasUnpublishedChanges: s,
@@ -24039,7 +24102,7 @@ gx.get("/", async (e) => {
24039
24102
  if (l) try {
24040
24103
  let n = typeof l == "string" ? JSON.parse(l) : l, a = await t.prepare("SELECT contentId as treeNodeId, treeId, parentId FROM tree_nodes WHERE contentId = ? LIMIT 1").get(r), o = px(e.env?.BUNDLED_DEFINITIONS).nodes?.[i.contentType] || {}, s = n.layoutId || null;
24041
24104
  if (a) {
24042
- let { resolvedLayoutId: e, inheritedFields: r } = await Ex(t, a.parentId, a.treeId);
24105
+ let { resolvedLayoutId: e, inheritedFields: r } = await Dx(t, a.parentId, a.treeId);
24043
24106
  (s === "inherit" || !s) && (s = e);
24044
24107
  for (let [e, t] of Object.entries(r)) e !== "layoutId" && e !== "subpageLayoutId" && (n[e] === void 0 || n[e] === null || n[e] === "") && t !== void 0 && (n[e] = t);
24045
24108
  }
@@ -24054,7 +24117,7 @@ gx.get("/", async (e) => {
24054
24117
  let r = t.allowedLayouts;
24055
24118
  return r ? typeof r == "string" ? r === e : !Array.isArray(r) || r.length === 0 || r.includes(e) : !0;
24056
24119
  })(s) && (s = null), (s === "inherit" || !s) && (s = o.defaultLayout || null);
24057
- let u = await fx(t, Sx(n));
24120
+ let u = await fx(t, Cx(n));
24058
24121
  Object.assign(c, u), c.resolvedLayoutId = s;
24059
24122
  } catch {}
24060
24123
  let u = await t.prepare("SELECT channelId FROM node_channels WHERE nodeId = ?").all(r);
@@ -24082,7 +24145,7 @@ gx.get("/", async (e) => {
24082
24145
  blocks: m
24083
24146
  });
24084
24147
  }
24085
- let m = [], h = [o ? "(cn.deletedAt IS NOT NULL AND cn.deletedAt != '')" : "(cn.deletedAt IS NULL OR cn.deletedAt = '')"];
24148
+ let m = [], h = [o ? "cn.deletedAt IS NOT NULL" : "cn.deletedAt IS NULL"];
24086
24149
  if (a && a !== "all" && (h.push("EXISTS (SELECT 1 FROM node_channels nc WHERE nc.nodeId = cn.id AND nc.channelId = ?)"), m.push(Number(a) || a)), s && (h.push("\n EXISTS (\n SELECT 1 FROM node_assets na_f \n JOIN assets a_f ON a_f.id = na_f.assetId\n WHERE na_f.nodeId = cn.id \n AND (na_f.assetId = ? OR a_f.parentAssetId = ? OR a_f.id = (SELECT parentAssetId FROM assets WHERE id = ?))\n )\n "), m.push(s, s, s)), r && r !== "all") {
24087
24150
  let e = r.split(",").map((e) => e.trim()).filter(Boolean);
24088
24151
  e.length > 0 && (h.push(`cn.contentType IN (${e.map(() => "?").join(",")})`), m.push(...e));
@@ -24159,6 +24222,8 @@ gx.get("/", async (e) => {
24159
24222
  contentType: e.contentType,
24160
24223
  nodeType: e.contentType,
24161
24224
  isHidden: !!e.isHidden,
24225
+ startShowingAt: e.startShowingAt || null,
24226
+ stopShowingAt: e.stopShowingAt || null,
24162
24227
  status: e.status || "draft",
24163
24228
  publishedAt: e.publishedAt || null,
24164
24229
  hasUnpublishedChanges: n,
@@ -24176,7 +24241,7 @@ gx.get("/", async (e) => {
24176
24241
  otherCount: e.otherCount || 0
24177
24242
  }, i = e.draftDataJson || e.dataJson;
24178
24243
  if (i) try {
24179
- let e = typeof i == "string" ? JSON.parse(i) : i, n = await fx(t, Sx(e));
24244
+ let e = typeof i == "string" ? JSON.parse(i) : i, n = await fx(t, Cx(e));
24180
24245
  Object.assign(r, n);
24181
24246
  } catch {}
24182
24247
  return r;
@@ -24189,34 +24254,34 @@ gx.get("/", async (e) => {
24189
24254
  limit: f
24190
24255
  });
24191
24256
  }), gx.post("/", async (e) => {
24192
- let t = e.get("db"), n = await e.req.json(), r = n.node || n.activeNode || n, i = r.id || n.id, a = i != null && i !== "" && !isNaN(Number(i)) ? Number(i) : null, { title: o, slug: s, language: c, nodeType: l, contentType: u, isHidden: d, hidden: f, is_hidden: p, blocks: m, channels: h, trees: g, ..._ } = r, { cleanedData: v, assetRefs: y, termRefs: b, nodeRefs: x } = ax(Sx(_)), S = bx(d === void 0 ? f === void 0 ? p : f : d), C = l || u || "page", w = e.get("user")?.id || null, T = typeof c == "string" && c.trim() !== "" ? c.trim() : null, ee = g && Array.isArray(g) && g.length > 0 ? g[0] : null, E = ee ? ee.treeId || ee.id : null, D = null;
24193
- if (E) {
24194
- let e = await t.prepare("SELECT dataJson FROM trees WHERE id = ? OR key = ? LIMIT 1").get(Number(E) || -1, String(E));
24257
+ let t = e.get("db"), n = await e.req.json(), r = n.node || n.activeNode || n, i = r.id || n.id, a = i != null && i !== "" && !isNaN(Number(i)) ? Number(i) : null, { title: o, slug: s, language: c, nodeType: l, contentType: u, isHidden: d, hidden: f, is_hidden: p, startShowingAt: m, stopShowingAt: h, blocks: g, channels: _, trees: v, ...y } = r, { cleanedData: b, assetRefs: x, termRefs: S, nodeRefs: C } = ax(Cx(y)), w = xx(d === void 0 ? f === void 0 ? p : f : d), T = l || u || "page", ee = e.get("user")?.id || null, E = typeof c == "string" && c.trim() !== "" ? c.trim() : null, D = v && Array.isArray(v) && v.length > 0 ? v[0] : null, te = D ? D.treeId || D.id : null, O = null;
24258
+ if (te) {
24259
+ let e = await t.prepare("SELECT dataJson FROM trees WHERE id = ? OR key = ? LIMIT 1").get(Number(te) || -1, String(te));
24195
24260
  if (e?.dataJson) try {
24196
24261
  let t = typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson;
24197
- D = t.defaultLanguage?.trim() || t.language?.trim() || null;
24262
+ O = t.defaultLanguage?.trim() || t.language?.trim() || null;
24198
24263
  } catch {}
24199
24264
  }
24200
- if (!D && h && Array.isArray(h) && h.length > 0) {
24201
- let e = typeof h[0] == "object" ? h[0].id : h[0];
24265
+ if (!O && _ && Array.isArray(_) && _.length > 0) {
24266
+ let e = typeof _[0] == "object" ? _[0].id : _[0];
24202
24267
  if (e && e !== "all") {
24203
24268
  let n = await t.prepare("SELECT defaultLanguage, dataJson FROM channels WHERE id = ? LIMIT 1").get(Number(e));
24204
24269
  if (n) {
24205
- if (n.defaultLanguage) D = n.defaultLanguage.trim();
24270
+ if (n.defaultLanguage) O = n.defaultLanguage.trim();
24206
24271
  else if (n.dataJson) try {
24207
24272
  let e = typeof n.dataJson == "string" ? JSON.parse(n.dataJson) : n.dataJson;
24208
- D = e.defaultLanguage?.trim() || e.language?.trim() || null;
24273
+ O = e.defaultLanguage?.trim() || e.language?.trim() || null;
24209
24274
  } catch {}
24210
24275
  }
24211
24276
  }
24212
24277
  }
24213
- T && D && T === D && (T = null);
24214
- let O = a, te = /* @__PURE__ */ new Set(), k = !1, A = "draft", ne = 0, j = s === void 0 ? null : yx(s);
24215
- if (j) {
24278
+ E && O && E === O && (E = null);
24279
+ let k = a, A = /* @__PURE__ */ new Set(), ne = !1, j = "draft", re = 0, ie = s === void 0 ? null : bx(s);
24280
+ if (ie) {
24216
24281
  let n = [];
24217
- if (g !== void 0 && Array.isArray(g) && g.length > 0) for (let e of g) n.push({
24282
+ if (v !== void 0 && Array.isArray(v) && v.length > 0) for (let e of v) n.push({
24218
24283
  treeId: Number(e.treeId),
24219
- parentId: xx(e.parentId ?? e._draftParentId ?? null)
24284
+ parentId: Sx(e.parentId ?? e._draftParentId ?? null)
24220
24285
  });
24221
24286
  else if (a) {
24222
24287
  let e = await t.prepare("SELECT treeId, parentId FROM tree_nodes WHERE contentId = ?").all(a), r = Array.isArray(e) ? e : e?.results || [];
@@ -24226,140 +24291,146 @@ gx.get("/", async (e) => {
24226
24291
  });
24227
24292
  }
24228
24293
  for (let r of n) {
24229
- let n = r.parentId === null ? "tn.parentId IS NULL" : "tn.parentId = ?", i = r.parentId === null ? [r.treeId, j] : [
24294
+ let n = r.parentId === null ? "tn.parentId IS NULL" : "tn.parentId = ?", i = r.parentId === null ? [r.treeId, ie] : [
24230
24295
  r.treeId,
24231
24296
  r.parentId,
24232
- j
24297
+ ie
24233
24298
  ], o = `
24234
24299
  SELECT cn.id FROM tree_nodes tn
24235
24300
  INNER JOIN content_nodes cn ON tn.contentId = cn.id
24236
- WHERE tn.treeId = ? AND ${n} AND cn.slug = ? AND (cn.deletedAt IS NULL OR cn.deletedAt = '')
24301
+ WHERE tn.treeId = ? AND ${n} AND cn.slug = ? AND cn.deletedAt IS NULL
24237
24302
  `;
24238
24303
  if (a && (o += " AND cn.id != ?", i.push(a)), o += " LIMIT 1", await t.prepare(o).get(...i)) return e.json({
24239
- error: `The slug '${j}' is already in use by another page in this section.`,
24304
+ error: `The slug '${ie}' is already in use by another page in this section.`,
24240
24305
  field: "slug"
24241
24306
  }, 409);
24242
24307
  }
24243
24308
  }
24244
24309
  if (a) {
24245
- let e = await t.prepare("SELECT title, slug, language, contentType, isHidden, draftDataJson, dataJson, publishedAt, status, hasUnpublishedChanges FROM content_nodes WHERE id = ?").get(a), n = o === void 0 ? e?.title || "Untitled" : o, r = j ?? e?.slug ?? null, i = C || e?.contentType || "page", l = c === void 0 ? e?.language ?? null : T, u = S === void 0 ? bx(e?.isHidden) : S;
24246
- k = wx(e, {
24310
+ let e = await t.prepare("SELECT title, slug, language, contentType, isHidden, startShowingAt, stopShowingAt, draftDataJson, dataJson, publishedAt, status, hasUnpublishedChanges FROM content_nodes WHERE id = ?").get(a), n = o === void 0 ? e?.title || "Untitled" : o, r = ie ?? e?.slug ?? null, i = T || e?.contentType || "page", l = c === void 0 ? e?.language ?? null : E, u = w === void 0 ? xx(e?.isHidden) : w, d = m === void 0 ? e?.startShowingAt ?? null : m, f = h === void 0 ? e?.stopShowingAt ?? null : h;
24311
+ ne = Tx(e, {
24247
24312
  title: n,
24248
24313
  slug: r,
24249
24314
  isHidden: u,
24250
- sanitizedFields: v
24315
+ startShowingAt: d,
24316
+ stopShowingAt: f,
24317
+ sanitizedFields: b
24251
24318
  });
24252
- let d = e?.draftDataJson || e?.dataJson || "{}";
24319
+ let p = e?.draftDataJson || e?.dataJson || "{}";
24253
24320
  try {
24254
- Cx(typeof d == "string" ? JSON.parse(d) : d, te);
24321
+ wx(typeof p == "string" ? JSON.parse(p) : p, A);
24255
24322
  } catch {}
24256
- let f = {};
24323
+ let _ = {};
24257
24324
  try {
24258
- f = JSON.parse(d);
24325
+ _ = JSON.parse(p);
24259
24326
  } catch {}
24260
- let p = {
24327
+ let v = {
24261
24328
  title: n,
24262
24329
  slug: r,
24263
24330
  contentType: i,
24264
24331
  language: l,
24265
24332
  isHidden: u,
24333
+ startShowingAt: d,
24334
+ stopShowingAt: f,
24335
+ ...b
24336
+ }, y = JSON.stringify({
24337
+ ..._,
24266
24338
  ...v
24267
- }, h = JSON.stringify({
24268
- ...f,
24269
- ...p
24270
- }), g = !1;
24271
- if (o !== void 0 && o.trim() !== (e?.title || "Untitled") && (g = !0), s !== void 0 && j !== e?.slug && (g = !0), c !== void 0 && T !== e?.language && (g = !0), !g && Object.keys(v).length > 0) {
24272
- for (let e of Object.keys(v)) if (JSON.stringify(v[e]) !== JSON.stringify(f[e])) {
24273
- g = !0;
24339
+ }), x = !1;
24340
+ if (o !== void 0 && o.trim() !== (e?.title || "Untitled") && (x = !0), s !== void 0 && ie !== e?.slug && (x = !0), c !== void 0 && E !== e?.language && (x = !0), m !== void 0 && d !== e?.startShowingAt && (x = !0), h !== void 0 && f !== e?.stopShowingAt && (x = !0), !x && Object.keys(b).length > 0) {
24341
+ for (let e of Object.keys(b)) if (JSON.stringify(b[e]) !== JSON.stringify(_[e])) {
24342
+ x = !0;
24274
24343
  break;
24275
24344
  }
24276
24345
  }
24277
- if (!g && m !== void 0) {
24346
+ if (!x && g !== void 0) {
24278
24347
  let e = await t.prepare("SELECT region, elementType, dataJson FROM content_blocks WHERE contentId = ? AND isDraft = 1 ORDER BY sortOrder ASC").all(a), n = Array.isArray(e) ? e : e?.results || [];
24279
- if (m.length !== n.length) g = !0;
24280
- else for (let e = 0; e < m.length; e++) {
24281
- let t = m[e], r = n[e], i = t.componentId || t.elementType || "text-block", a = t.region || "content", o = { ...t.data || {} };
24348
+ if (g.length !== n.length) x = !0;
24349
+ else for (let e = 0; e < g.length; e++) {
24350
+ let t = g[e], r = n[e], i = t.componentId || t.elementType || "text-block", a = t.region || "content", o = { ...t.data || {} };
24282
24351
  delete o._instanceId, delete o.blockId;
24283
24352
  let s = {};
24284
24353
  try {
24285
24354
  s = JSON.parse(r.dataJson);
24286
24355
  } catch {}
24287
24356
  if (delete s._instanceId, delete s.blockId, i !== r.elementType || a !== r.region || JSON.stringify(o) !== JSON.stringify(s)) {
24288
- g = !0;
24357
+ x = !0;
24289
24358
  break;
24290
24359
  }
24291
24360
  }
24292
24361
  }
24293
- A = e?.status === "published" || e?.publishedAt ? "published" : "draft";
24294
- let _ = e?.hasUnpublishedChanges === 1 || e?.hasUnpublishedChanges === !0;
24295
- ne = g ? 1 : +!!_;
24296
- let y = e?.publishedAt != null || e?.status === "published", b = y ? e.title : n, x = y ? e.slug : r, ee = y ? e.contentType : i, E = y ? e.language : l, D = y ? e.isHidden : u;
24297
- await t.prepare("\n UPDATE content_nodes \n SET title = ?, slug = ?, language = ?, contentType = ?, isHidden = ?, status = ?, draftDataJson = ?, hasUnpublishedChanges = ?, updatedById = ?, updatedAt = CURRENT_TIMESTAMP\n WHERE id = ?\n ").run(b, x, E, ee, D, A, h, ne, w, a);
24362
+ j = e?.status === "published" || e?.publishedAt ? "published" : "draft";
24363
+ let S = e?.hasUnpublishedChanges === 1 || e?.hasUnpublishedChanges === !0;
24364
+ re = x ? 1 : +!!S;
24365
+ let C = e?.publishedAt != null || e?.status === "published", D = C ? e.title : n, te = C ? e.slug : r, O = C ? e.contentType : i, k = C ? e.language : l, ae = C ? e.isHidden : u, oe = C ? e.startShowingAt : d, se = C ? e.stopShowingAt : f;
24366
+ await t.prepare("\n UPDATE content_nodes \n SET title = ?, slug = ?, language = ?, contentType = ?, isHidden = ?, startShowingAt = ?, stopShowingAt = ?, status = ?, draftDataJson = ?, hasUnpublishedChanges = ?, updatedById = ?, updatedAt = CURRENT_TIMESTAMP\n WHERE id = ?\n ").run(D, te, k, O, ae, oe, se, j, y, re, ee, a);
24298
24367
  } else {
24299
- k = !0;
24300
- let e = {
24368
+ ne = !0;
24369
+ let e = m === void 0 ? null : m, n = h === void 0 ? null : h, r = {
24301
24370
  title: o || "Untitled",
24302
- slug: j,
24303
- contentType: C,
24304
- language: T,
24305
- isHidden: S,
24306
- ...v
24307
- }, n = await t.prepare("\n INSERT INTO content_nodes (contentType, title, slug, language, isHidden, status, draftDataJson, dataJson, hasUnpublishedChanges, createdById, updatedById)\n VALUES (?, ?, ?, ?, ?, 'draft', ?, NULL, 0, ?, ?)\n ").run(C, o || "Untitled", j, T, S, JSON.stringify(e), w, w);
24308
- O = Number(n.lastInsertRowid);
24309
- }
24310
- if (h !== void 0 && Array.isArray(h) && O) {
24311
- await t.prepare("DELETE FROM node_channels WHERE nodeId = ?").run(O);
24312
- let e = [...new Set(h.map((e) => typeof e == "object" && e ? e.id || e.channelId : e))].filter((e) => e && e !== "all").map((e) => Number(e) || e);
24371
+ slug: ie,
24372
+ contentType: T,
24373
+ language: E,
24374
+ isHidden: w,
24375
+ startShowingAt: e,
24376
+ stopShowingAt: n,
24377
+ ...b
24378
+ }, i = await t.prepare("\n INSERT INTO content_nodes (contentType, title, slug, language, isHidden, startShowingAt, stopShowingAt, status, draftDataJson, dataJson, hasUnpublishedChanges, createdById, updatedById)\n VALUES (?, ?, ?, ?, ?, ?, ?, 'draft', ?, NULL, 0, ?, ?)\n ").run(T, o || "Untitled", ie, E, w, e, n, JSON.stringify(r), ee, ee);
24379
+ k = Number(i.lastInsertRowid);
24380
+ }
24381
+ if (_ !== void 0 && Array.isArray(_) && k) {
24382
+ await t.prepare("DELETE FROM node_channels WHERE nodeId = ?").run(k);
24383
+ let e = [...new Set(_.map((e) => typeof e == "object" && e ? e.id || e.channelId : e))].filter((e) => e && e !== "all").map((e) => Number(e) || e);
24313
24384
  if (e.length > 0) {
24314
- let n = e.map(() => "(?, ?)").join(", "), r = e.flatMap((e) => [O, e]);
24385
+ let n = e.map(() => "(?, ?)").join(", "), r = e.flatMap((e) => [k, e]);
24315
24386
  await t.prepare(`INSERT OR IGNORE INTO node_channels (nodeId, channelId) VALUES ${n}`).run(...r);
24316
24387
  }
24317
24388
  }
24318
- if (g !== void 0 && Array.isArray(g) && g.length > 0 && O) for (let e of g) {
24389
+ if (v !== void 0 && Array.isArray(v) && v.length > 0 && k) for (let e of v) {
24319
24390
  if (!e || !e.treeId) continue;
24320
- let n = Number(e.treeId) || e.treeId, r = xx(e.parentId ?? e._draftParentId ?? null), i = typeof e.sortOrder == "number" ? e.sortOrder : 0, a = await t.prepare("SELECT contentId, parentId, sortOrder FROM tree_nodes WHERE treeId = ? AND contentId = ?").get(n, O);
24321
- a ? ((a.parentId !== r || a.sortOrder !== i) && (k = !0), await t.prepare("UPDATE tree_nodes SET parentId = ?, sortOrder = ? WHERE treeId = ? AND contentId = ?").run(r, i, n, O)) : (k = !0, await t.prepare("INSERT INTO tree_nodes (treeId, contentId, parentId, sortOrder) VALUES (?, ?, ?, ?)").run(n, O, r, i));
24391
+ let n = Number(e.treeId) || e.treeId, r = Sx(e.parentId ?? e._draftParentId ?? null), i = typeof e.sortOrder == "number" ? e.sortOrder : 0, a = await t.prepare("SELECT contentId, parentId, sortOrder FROM tree_nodes WHERE treeId = ? AND contentId = ?").get(n, k);
24392
+ a ? ((a.parentId !== r || a.sortOrder !== i) && (ne = !0), await t.prepare("UPDATE tree_nodes SET parentId = ?, sortOrder = ? WHERE treeId = ? AND contentId = ?").run(r, i, n, k)) : (ne = !0, await t.prepare("INSERT INTO tree_nodes (treeId, contentId, parentId, sortOrder) VALUES (?, ?, ?, ?)").run(n, k, r, i));
24322
24393
  }
24323
- let re = [], ie = [], ae = [];
24324
- if (m !== void 0 && Array.isArray(m) && O) {
24325
- await t.prepare("DELETE FROM content_blocks WHERE contentId = ? AND isDraft = 1").run(O);
24394
+ let ae = [], oe = [], se = [];
24395
+ if (g !== void 0 && Array.isArray(g) && k) {
24396
+ await t.prepare("DELETE FROM content_blocks WHERE contentId = ? AND isDraft = 1").run(k);
24326
24397
  let e = [], n = [];
24327
- for (let t = 0; t < m.length; t++) {
24328
- let r = m[t], i = r.componentId || r.elementType || "text-block", a = r.data || {}, o = String(r.blockId || a.blockId || r.instanceId || r.id || `block-${Date.now()}`), { cleanedData: s, assetRefs: c, termRefs: l, nodeRefs: u } = ax({
24398
+ for (let t = 0; t < g.length; t++) {
24399
+ let r = g[t], i = r.componentId || r.elementType || "text-block", a = r.data || {}, o = String(r.blockId || a.blockId || r.instanceId || r.id || `block-${Date.now()}`), { cleanedData: s, assetRefs: c, termRefs: l, nodeRefs: u } = ax({
24329
24400
  ...a,
24330
24401
  blockId: o,
24331
24402
  _instanceId: o
24332
24403
  });
24333
- c.forEach((e) => re.push({
24404
+ c.forEach((e) => ae.push({
24334
24405
  ...e,
24335
24406
  fieldKey: `blocks[${t}].${e.fieldKey}`
24336
- })), l.forEach((e) => ie.push({
24407
+ })), l.forEach((e) => oe.push({
24337
24408
  ...e,
24338
24409
  fieldKey: `blocks[${t}].${e.fieldKey}`
24339
- })), u.forEach((e) => ae.push({
24410
+ })), u.forEach((e) => se.push({
24340
24411
  ...e,
24341
24412
  fieldKey: `blocks[${t}].${e.fieldKey}`
24342
24413
  }));
24343
24414
  let d = r.region !== void 0 && r.region !== null && String(r.region).trim() !== "" ? String(r.region) : "content";
24344
- e.push("(?, ?, ?, ?, ?, 1)"), n.push(O, t, i, JSON.stringify(s), d);
24415
+ e.push("(?, ?, ?, ?, ?, 1)"), n.push(k, t, i, JSON.stringify(s), d);
24345
24416
  }
24346
24417
  e.length > 0 && await t.prepare(`INSERT INTO content_blocks (contentId, sortOrder, elementType, dataJson, region, isDraft) VALUES ${e.join(", ")}`).run(...n);
24347
24418
  }
24348
- if (O) {
24349
- let n = [...y, ...re], r = [...b, ...ie], i = [...x, ...ae];
24350
- await ox(t, O, n), await sx(t, O, r), await cx(t, O, i);
24351
- let a = new Set(n.map((e) => e.assetId)), o = new Set([...te].filter((e) => !a.has(e)));
24419
+ if (k) {
24420
+ let n = [...x, ...ae], r = [...S, ...oe], i = [...C, ...se];
24421
+ await ox(t, k, n), await sx(t, k, r), await cx(t, k, i);
24422
+ let a = new Set(n.map((e) => e.assetId)), o = new Set([...A].filter((e) => !a.has(e)));
24352
24423
  if (o.size > 0) {
24353
24424
  let { storage: n } = ix(e.env);
24354
- await Tx(t, n, o);
24425
+ await Ex(t, n, o);
24355
24426
  }
24356
24427
  }
24357
24428
  return await $b(e).clear(), e.json({
24358
24429
  success: !0,
24359
- id: O,
24360
- status: A,
24361
- hasUnpublishedChanges: ne === 1 || A === "draft",
24362
- isStructuralChange: k
24430
+ id: k,
24431
+ status: j,
24432
+ hasUnpublishedChanges: re === 1 || j === "draft",
24433
+ isStructuralChange: ne
24363
24434
  });
24364
24435
  }), gx.post("/publish", async (e) => {
24365
24436
  let t = e.get("db"), n = await e.req.json(), r = n.id || n.nodeId;
@@ -24374,34 +24445,36 @@ gx.get("/", async (e) => {
24374
24445
  try {
24375
24446
  c = typeof o.draftDataJson == "string" ? JSON.parse(o.draftDataJson) : o.draftDataJson || {};
24376
24447
  } catch {}
24377
- let l = (s.title ?? o.title ?? "").trim(), u = (c.title ?? n.title ?? o.title ?? "").trim(), d = (s.slug ?? o.slug ?? "").trim(), f = (c.slug ?? n.slug ?? o.slug ?? "").trim(), p = (s.menuTitle ?? "").trim(), m = (c.menuTitle ?? "").trim(), h = l !== "" && u !== "" && l !== u || d !== "" && f !== "" && d !== f || p !== "" && m !== "" && p !== m, g = o.draftDataJson || o.dataJson || "{}", _ = c.title ?? n.title ?? o.title ?? "Untitled", v = c.slug ?? n.slug ?? o.slug ?? null, y = c.language === void 0 ? o.language : c.language, b = c.contentType ?? o.contentType ?? "page", x = c.isHidden === void 0 ? o.isHidden : c.isHidden;
24378
- await t.prepare("\n UPDATE content_nodes\n SET title = ?, slug = ?, language = ?, contentType = ?, isHidden = ?, publishedDataJson = ?, dataJson = ?, publishedAt = CURRENT_TIMESTAMP, status = 'published', hasUnpublishedChanges = 0, updatedById = ?, updatedAt = CURRENT_TIMESTAMP\n WHERE id = ?\n ").run(_, v, y, b, x, g, g, a, i), await t.prepare("DELETE FROM content_blocks WHERE contentId = ? AND isDraft = 0").run(i);
24379
- let S = await t.prepare("SELECT * FROM content_blocks WHERE contentId = ? AND isDraft = 1 ORDER BY sortOrder ASC").all(i), C = Array.isArray(S) ? S : S?.results || [];
24380
- if (C.length > 0) {
24448
+ let l = (s.title ?? o.title ?? "").trim(), u = (c.title ?? n.title ?? o.title ?? "").trim(), d = (s.slug ?? o.slug ?? "").trim(), f = (c.slug ?? n.slug ?? o.slug ?? "").trim(), p = (s.menuTitle ?? "").trim(), m = (c.menuTitle ?? "").trim(), h = s.startShowingAt ?? o.startShowingAt ?? "", g = c.startShowingAt ?? n.startShowingAt ?? o.startShowingAt ?? "", _ = s.stopShowingAt ?? o.stopShowingAt ?? "", v = c.stopShowingAt ?? n.stopShowingAt ?? o.stopShowingAt ?? "", y = l !== "" && u !== "" && l !== u || d !== "" && f !== "" && d !== f || p !== "" && m !== "" && p !== m || h !== g || _ !== v, b = o.draftDataJson || o.dataJson || "{}", x = c.title ?? n.title ?? o.title ?? "Untitled", S = c.slug ?? n.slug ?? o.slug ?? null, C = c.language === void 0 ? o.language : c.language, w = c.contentType ?? o.contentType ?? "page", T = c.isHidden === void 0 ? o.isHidden : c.isHidden, ee = c.startShowingAt === void 0 ? n.startShowingAt === void 0 ? o.startShowingAt : n.startShowingAt : c.startShowingAt, E = c.stopShowingAt === void 0 ? n.stopShowingAt === void 0 ? o.stopShowingAt : n.stopShowingAt : c.stopShowingAt;
24449
+ await t.prepare("\n UPDATE content_nodes\n SET title = ?, slug = ?, language = ?, contentType = ?, isHidden = ?, startShowingAt = ?, stopShowingAt = ?, publishedDataJson = ?, dataJson = ?, publishedAt = CURRENT_TIMESTAMP, status = 'published', hasUnpublishedChanges = 0, updatedById = ?, updatedAt = CURRENT_TIMESTAMP\n WHERE id = ?\n ").run(x, S, C, w, T, ee, E, b, b, a, i), await t.prepare("DELETE FROM content_blocks WHERE contentId = ? AND isDraft = 0").run(i);
24450
+ let D = await t.prepare("SELECT * FROM content_blocks WHERE contentId = ? AND isDraft = 1 ORDER BY sortOrder ASC").all(i), te = Array.isArray(D) ? D : D?.results || [];
24451
+ if (te.length > 0) {
24381
24452
  let e = [], n = [];
24382
- for (let t of C) {
24453
+ for (let t of te) {
24383
24454
  let r = t.region !== void 0 && t.region !== null && String(t.region).trim() !== "" ? String(t.region) : "content";
24384
24455
  e.push("(?, ?, ?, ?, ?, 0)"), n.push(i, t.sortOrder, t.elementType, t.dataJson, r);
24385
24456
  }
24386
24457
  await t.prepare(`INSERT INTO content_blocks (contentId, sortOrder, elementType, dataJson, region, isDraft) VALUES ${e.join(", ")}`).run(...n);
24387
24458
  }
24388
- let w = ((await t.prepare("SELECT COUNT(*) as count FROM node_revisions WHERE nodeId = ?").get(i))?.count || 0) + 1, T = {
24389
- version: w,
24459
+ let O = ((await t.prepare("SELECT COUNT(*) as count FROM node_revisions WHERE nodeId = ?").get(i))?.count || 0) + 1, k = {
24460
+ version: O,
24390
24461
  publishedAt: (/* @__PURE__ */ new Date()).toISOString(),
24391
24462
  node: {
24392
24463
  ...o,
24393
- dataJson: g
24464
+ dataJson: b
24394
24465
  },
24395
- blocks: C
24466
+ blocks: te
24396
24467
  };
24397
- return await t.prepare("INSERT INTO node_revisions (nodeId, version, snapshotJson, createdById) VALUES (?, ?, ?, ?)").run(i, w, JSON.stringify(T), a), await $b(e).clear(), h && await hx(t), new mx(e.env).purgeNode(e, t, i, h), e.json({
24468
+ await t.prepare("INSERT INTO node_revisions (nodeId, version, snapshotJson, createdById) VALUES (?, ?, ?, ?)").run(i, O, JSON.stringify(k), a), await $b(e).clear();
24469
+ let A = new mx(e.env);
24470
+ return y ? _x(e, t, [i]) : A.purgeNode(e, t, i, !1), e.json({
24398
24471
  success: !0,
24399
24472
  id: i,
24400
24473
  status: "published",
24401
- version: w,
24402
- publishedAt: T.publishedAt,
24474
+ version: O,
24475
+ publishedAt: k.publishedAt,
24403
24476
  hasUnpublishedChanges: !1,
24404
- isStructuralChange: h
24477
+ isStructuralChange: y
24405
24478
  });
24406
24479
  }), gx.post("/publish/batch", async (e) => {
24407
24480
  let t = e.get("db"), n = await e.req.json(), r = n.ids;
@@ -24420,33 +24493,33 @@ gx.get("/", async (e) => {
24420
24493
  try {
24421
24494
  l = typeof s.draftDataJson == "string" ? JSON.parse(s.draftDataJson) : s.draftDataJson || {};
24422
24495
  } catch {}
24423
- let u = (c.title ?? s.title ?? "").trim(), d = (l.title ?? n.title ?? s.title ?? "").trim(), f = (c.slug ?? s.slug ?? "").trim(), p = (l.slug ?? n.slug ?? s.slug ?? "").trim(), m = (c.menuTitle ?? "").trim(), h = (l.menuTitle ?? "").trim();
24424
- (u !== "" && d !== "" && u !== d || f !== "" && p !== "" && f !== p || m !== "" && h !== "" && m !== h) && (a = !0);
24425
- let g = s.draftDataJson || s.dataJson || "{}", _ = l.title ?? n.title ?? s.title ?? "Untitled", v = l.slug ?? n.slug ?? s.slug ?? null, y = l.language === void 0 ? s.language : l.language, b = l.contentType ?? s.contentType ?? "page", x = l.isHidden === void 0 ? s.isHidden : l.isHidden;
24426
- await t.prepare("\n UPDATE content_nodes\n SET title = ?, slug = ?, language = ?, contentType = ?, isHidden = ?, publishedDataJson = ?, dataJson = ?, publishedAt = CURRENT_TIMESTAMP, status = 'published', hasUnpublishedChanges = 0, updatedById = ?, updatedAt = CURRENT_TIMESTAMP\n WHERE id = ?\n ").run(_, v, y, b, x, g, g, i, r), await t.prepare("DELETE FROM content_blocks WHERE contentId = ? AND isDraft = 0").run(r);
24427
- let S = await t.prepare("SELECT * FROM content_blocks WHERE contentId = ? AND isDraft = 1 ORDER BY sortOrder ASC").all(r), C = Array.isArray(S) ? S : S?.results || [];
24428
- if (C.length > 0) {
24496
+ let u = (c.title ?? s.title ?? "").trim(), d = (l.title ?? n.title ?? s.title ?? "").trim(), f = (c.slug ?? s.slug ?? "").trim(), p = (l.slug ?? n.slug ?? s.slug ?? "").trim(), m = (c.menuTitle ?? "").trim(), h = (l.menuTitle ?? "").trim(), g = c.startShowingAt ?? s.startShowingAt ?? "", _ = l.startShowingAt ?? n.startShowingAt ?? s.startShowingAt ?? "", v = c.stopShowingAt ?? s.stopShowingAt ?? "", y = l.stopShowingAt ?? n.stopShowingAt ?? s.stopShowingAt ?? "";
24497
+ (u !== "" && d !== "" && u !== d || f !== "" && p !== "" && f !== p || m !== "" && h !== "" && m !== h || g !== _ || v !== y) && (a = !0);
24498
+ let b = s.draftDataJson || s.dataJson || "{}", x = l.title ?? n.title ?? s.title ?? "Untitled", S = l.slug ?? n.slug ?? s.slug ?? null, C = l.language === void 0 ? s.language : l.language, w = l.contentType ?? s.contentType ?? "page", T = l.isHidden === void 0 ? s.isHidden : l.isHidden, ee = l.startShowingAt === void 0 ? n.startShowingAt === void 0 ? s.startShowingAt : n.startShowingAt : l.startShowingAt, E = l.stopShowingAt === void 0 ? n.stopShowingAt === void 0 ? s.stopShowingAt : n.stopShowingAt : l.stopShowingAt;
24499
+ await t.prepare("\n UPDATE content_nodes\n SET title = ?, slug = ?, language = ?, contentType = ?, isHidden = ?, startShowingAt = ?, stopShowingAt = ?, publishedDataJson = ?, dataJson = ?, publishedAt = CURRENT_TIMESTAMP, status = 'published', hasUnpublishedChanges = 0, updatedById = ?, updatedAt = CURRENT_TIMESTAMP\n WHERE id = ?\n ").run(x, S, C, w, T, ee, E, b, b, i, r), await t.prepare("DELETE FROM content_blocks WHERE contentId = ? AND isDraft = 0").run(r);
24500
+ let D = await t.prepare("SELECT * FROM content_blocks WHERE contentId = ? AND isDraft = 1 ORDER BY sortOrder ASC").all(r), te = Array.isArray(D) ? D : D?.results || [];
24501
+ if (te.length > 0) {
24429
24502
  let e = [], n = [];
24430
- for (let t of C) {
24503
+ for (let t of te) {
24431
24504
  let i = t.region !== void 0 && t.region !== null && String(t.region).trim() !== "" ? String(t.region) : "content";
24432
24505
  e.push("(?, ?, ?, ?, ?, 0)"), n.push(r, t.sortOrder, t.elementType, t.dataJson, i);
24433
24506
  }
24434
24507
  await t.prepare(`INSERT INTO content_blocks (contentId, sortOrder, elementType, dataJson, region, isDraft) VALUES ${e.join(", ")}`).run(...n);
24435
24508
  }
24436
- let w = ((await t.prepare("SELECT COUNT(*) as count FROM node_revisions WHERE nodeId = ?").get(r))?.count || 0) + 1, T = {
24437
- version: w,
24509
+ let O = ((await t.prepare("SELECT COUNT(*) as count FROM node_revisions WHERE nodeId = ?").get(r))?.count || 0) + 1, k = {
24510
+ version: O,
24438
24511
  publishedAt: (/* @__PURE__ */ new Date()).toISOString(),
24439
24512
  node: {
24440
24513
  ...s,
24441
- dataJson: g
24514
+ dataJson: b
24442
24515
  },
24443
- blocks: C
24516
+ blocks: te
24444
24517
  };
24445
- await t.prepare("INSERT INTO node_revisions (nodeId, version, snapshotJson, createdById) VALUES (?, ?, ?, ?)").run(r, w, JSON.stringify(T), i), o.push(r);
24518
+ await t.prepare("INSERT INTO node_revisions (nodeId, version, snapshotJson, createdById) VALUES (?, ?, ?, ?)").run(r, O, JSON.stringify(k), i), o.push(r);
24446
24519
  }
24447
24520
  await $b(e).clear();
24448
24521
  let s = new mx(e.env);
24449
- if (a) await hx(t), s.purgeGlobalCache(e, t);
24522
+ if (a) _x(e, t, o);
24450
24523
  else for (let n of o) s.purgeNode(e, t, n, !1);
24451
24524
  return e.json({
24452
24525
  success: !0,
@@ -24458,13 +24531,13 @@ gx.get("/", async (e) => {
24458
24531
  let t = e.get("db"), n = e.req.query("id");
24459
24532
  if (!n) return e.json({ error: "Node ID required" }, 400);
24460
24533
  let r = Number(n);
24461
- return await t.prepare("UPDATE content_nodes SET deletedAt = CURRENT_TIMESTAMP WHERE id = ?").run(r), await $b(e).clear(), await hx(t), new mx(e.env).purgeNode(e, t, r, !0), e.json({
24534
+ return await t.prepare("UPDATE content_nodes SET deletedAt = CURRENT_TIMESTAMP WHERE id = ?").run(r), await $b(e).clear(), new mx(e.env), _x(e, t, [r]), e.json({
24462
24535
  success: !0,
24463
24536
  deletedNodeId: r
24464
24537
  });
24465
24538
  }), gx.post("/restore", async (e) => {
24466
24539
  let t = e.get("db"), n = await e.req.json(), r = Number(n.id);
24467
- return r ? await t.prepare("SELECT id FROM content_nodes WHERE id = ?").get(r) ? (await t.prepare("UPDATE content_nodes SET deletedAt = NULL WHERE id = ?").run(r), await $b(e).clear(), await hx(t), new mx(e.env).purgeNode(e, t, r, !0), e.json({
24540
+ return r ? await t.prepare("SELECT id FROM content_nodes WHERE id = ?").get(r) ? (await t.prepare("UPDATE content_nodes SET deletedAt = NULL WHERE id = ?").run(r), await $b(e).clear(), new mx(e.env), _x(e, t, [r]), e.json({
24468
24541
  success: !0,
24469
24542
  restoredNodeId: r
24470
24543
  })) : e.json({ error: "Node not found" }, 404) : e.json({ error: "Node ID required" }, 400);
@@ -24472,7 +24545,7 @@ gx.get("/", async (e) => {
24472
24545
  let t = e.get("db"), n = e.req.query("id");
24473
24546
  if (!n) return e.json({ error: "Node ID required" }, 400);
24474
24547
  let r = Number(n);
24475
- return await t.prepare("DELETE FROM node_channels WHERE nodeId = ?").run(r), await t.prepare("DELETE FROM tree_nodes WHERE contentId = ?").run(r), await t.prepare("DELETE FROM content_blocks WHERE contentId = ?").run(r), await t.prepare("DELETE FROM node_revisions WHERE nodeId = ?").run(r), await t.prepare("DELETE FROM node_assets WHERE nodeId = ?").run(r), await t.prepare("DELETE FROM node_terms WHERE nodeId = ?").run(r), await t.prepare("DELETE FROM content_nodes WHERE id = ?").run(r), await $b(e).clear(), await hx(t), new mx(e.env).purgeNode(e, t, r, !0), e.json({
24548
+ return await new mx(e.env).purgeInternalWorkerCache(e, t, r), await t.prepare("DELETE FROM node_channels WHERE nodeId = ?").run(r), await t.prepare("DELETE FROM tree_nodes WHERE contentId = ?").run(r), await t.prepare("DELETE FROM content_blocks WHERE contentId = ?").run(r), await t.prepare("DELETE FROM node_revisions WHERE nodeId = ?").run(r), await t.prepare("DELETE FROM node_assets WHERE nodeId = ?").run(r), await t.prepare("DELETE FROM node_terms WHERE nodeId = ?").run(r), await t.prepare("DELETE FROM content_nodes WHERE id = ?").run(r), await $b(e).clear(), _x(e, t), e.json({
24476
24549
  success: !0,
24477
24550
  purgedNodeId: r
24478
24551
  });
@@ -24487,7 +24560,7 @@ gx.get("/", async (e) => {
24487
24560
  } catch {}
24488
24561
  return {
24489
24562
  version: e.version,
24490
- publishedAt: t || new DatetoISOString(),
24563
+ publishedAt: t || (/* @__PURE__ */ new Date()).toISOString(),
24491
24564
  createdById: e.createdById
24492
24565
  };
24493
24566
  });
@@ -24545,15 +24618,18 @@ gx.get("/", async (e) => {
24545
24618
  let t = JSON.stringify(e);
24546
24619
  s += ", dataJson = ?, publishedDataJson = ?", c.push(t, t);
24547
24620
  }
24548
- return s += " WHERE id = ?", c.push(n), await t.prepare(s).run(...c), await $b(e).clear(), await hx(t), new mx(e.env).purgeNode(e, t, n, !0), e.json({
24621
+ s += " WHERE id = ?", c.push(n), await t.prepare(s).run(...c), await $b(e).clear();
24622
+ let u = await new mx(e.env).purgeVisibilityChange(e, t, n);
24623
+ return e.json({
24549
24624
  success: !0,
24550
- isHidden: i
24625
+ isHidden: i,
24626
+ cacheInvalidated: u
24551
24627
  });
24552
24628
  });
24553
24629
  //#endregion
24554
24630
  //#region server/routes/admin/trees.ts
24555
- var Dx = new e();
24556
- function Ox(e, t = null) {
24631
+ var Ox = new e();
24632
+ function kx(e, t = null) {
24557
24633
  let n = [];
24558
24634
  for (let r = 0; r < e.length; r++) {
24559
24635
  let i = e[r];
@@ -24565,19 +24641,19 @@ function Ox(e, t = null) {
24565
24641
  id: o,
24566
24642
  parentId: t,
24567
24643
  sortOrder: r
24568
- }), i.children && Array.isArray(i.children) && i.children.length > 0 && n.push(...Ox(i.children, o)));
24644
+ }), i.children && Array.isArray(i.children) && i.children.length > 0 && n.push(...kx(i.children, o)));
24569
24645
  }
24570
24646
  return n;
24571
24647
  }
24572
- function kx(e) {
24648
+ function Ax(e) {
24573
24649
  if (e == null || e === "null" || e === "" || typeof e == "string" && e.startsWith("draft-")) return null;
24574
24650
  let t = Number(e);
24575
24651
  return isNaN(t) ? null : t;
24576
24652
  }
24577
- function Ax(e) {
24653
+ function jx(e) {
24578
24654
  return +(e === !0 || e === 1 || e === "1" || e === "true");
24579
24655
  }
24580
- Dx.get("/tree.json", async (e) => {
24656
+ Ox.get("/tree.json", async (e) => {
24581
24657
  try {
24582
24658
  let t = e.get("db"), n = e.req.query("treeId") || "main-nav", r = e.req.query("preview") === "true", i = 1;
24583
24659
  if (isNaN(Number(n))) {
@@ -24588,7 +24664,7 @@ Dx.get("/tree.json", async (e) => {
24588
24664
  e && e.id && (i = Number(e.id));
24589
24665
  }
24590
24666
  } else i = Number(n);
24591
- let a = await t.prepare("\n SELECT \n t.contentId as treeNodeId, \n t.treeId,\n t.contentId,\n t.parentId,\n t.sortOrder,\n c.title,\n c.slug,\n c.language,\n c.contentType as nodeType,\n c.isHidden,\n c.status,\n c.publishedAt,\n c.hasUnpublishedChanges,\n c.dataJson,\n c.draftDataJson,\n (SELECT COUNT(*) FROM node_assets WHERE nodeId = t.contentId) as assetCount\n FROM tree_nodes t\n INNER JOIN content_nodes c ON t.contentId = c.id\n WHERE t.treeId = ? AND (c.deletedAt IS NULL OR c.deletedAt = '')\n ORDER BY t.sortOrder ASC\n ").all(i), o = Array.isArray(a) ? a : a?.results || [], s = [], c = /* @__PURE__ */ new Set();
24667
+ let a = await t.prepare("\n WITH tree_asset_counts AS (\n SELECT na.nodeId, COUNT(*) as assetCount \n FROM node_assets na \n INNER JOIN tree_nodes tn ON na.nodeId = tn.contentId \n WHERE tn.treeId = ? \n GROUP BY na.nodeId\n )\n SELECT \n t.contentId as treeNodeId, \n t.treeId,\n t.contentId,\n t.parentId,\n t.sortOrder,\n c.title,\n c.slug,\n c.language,\n c.contentType as nodeType,\n c.isHidden,\n c.status,\n c.publishedAt,\n c.hasUnpublishedChanges,\n c.dataJson,\n c.draftDataJson,\n COALESCE(ac.assetCount, 0) as assetCount\n FROM tree_nodes t\n INNER JOIN content_nodes c ON t.contentId = c.id\n LEFT JOIN tree_asset_counts ac ON t.contentId = ac.nodeId\n WHERE t.treeId = ? AND c.deletedAt IS NULL\n ORDER BY t.sortOrder ASC\n ").all(i, i), o = Array.isArray(a) ? a : a?.results || [], s = [], c = /* @__PURE__ */ new Set();
24592
24668
  for (let e of o) {
24593
24669
  let t = e.contentId;
24594
24670
  c.has(t) || (c.add(t), s.push(e));
@@ -24630,7 +24706,7 @@ Dx.get("/tree.json", async (e) => {
24630
24706
  } catch (t) {
24631
24707
  return console.error("[CMS Tree API] GET Error:", t), e.json({ error: t.message || "Failed to fetch tree" }, 500);
24632
24708
  }
24633
- }), Dx.post("/tree.json", async (e) => {
24709
+ }), Ox.post("/tree.json", async (e) => {
24634
24710
  try {
24635
24711
  let t = e.get("db"), n = await e.req.json(), r = n.treeId ? String(n.treeId).trim() : "main-nav", i = $b(e), a = new mx(e.env), o = 1;
24636
24712
  if (isNaN(Number(r))) {
@@ -24642,7 +24718,7 @@ Dx.get("/tree.json", async (e) => {
24642
24718
  }
24643
24719
  } else o = Number(r);
24644
24720
  if (n.tree && Array.isArray(n.tree)) {
24645
- let r = Ox(n.tree, null);
24721
+ let r = kx(n.tree, null);
24646
24722
  if (r.length > 0) for (let e = 0; e < r.length; e += 50) {
24647
24723
  let n = r.slice(e, e + 50), i = n.map((e) => e.id), a = i.map(() => "?").join(","), s = "UPDATE tree_nodes SET \n";
24648
24724
  s += "parentId = CASE contentId \n", n.forEach(() => {
@@ -24662,9 +24738,9 @@ Dx.get("/tree.json", async (e) => {
24662
24738
  reorderedCount: r.length
24663
24739
  });
24664
24740
  }
24665
- 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 = Ax(n.isHidden === void 0 ? m.isHidden === void 0 ? m.hidden : m.isHidden : n.isHidden);
24741
+ 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 = jx(n.isHidden === void 0 ? m.isHidden === void 0 ? m.hidden : m.isHidden : n.isHidden);
24666
24742
  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;
24667
- let g = kx(u), _ = e.get("user")?.id || null;
24743
+ let g = Ax(u), _ = e.get("user")?.id || null;
24668
24744
  if (s === "create") {
24669
24745
  let r = m.slug || n.slug || c, a = r ? String(r).toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "") : null;
24670
24746
  if (a) {
@@ -24772,7 +24848,7 @@ Dx.get("/tree.json", async (e) => {
24772
24848
  details: t.message
24773
24849
  }, 500);
24774
24850
  }
24775
- }), Dx.get("/trees.json", async (e) => {
24851
+ }), Ox.get("/trees.json", async (e) => {
24776
24852
  try {
24777
24853
  let t = e.get("db"), n = await t.prepare("SELECT * FROM trees ORDER BY LOWER(label) ASC").all(), r = Array.isArray(n) ? n : n?.results || [], i = await t.prepare("SELECT channelId, treeId FROM channel_trees").all(), a = (Array.isArray(i) ? i : i?.results || []).reduce((e, t) => {
24778
24854
  let n = Number(t.treeId), r = Number(t.channelId);
@@ -24802,7 +24878,7 @@ Dx.get("/tree.json", async (e) => {
24802
24878
  } catch {
24803
24879
  return e.json([]);
24804
24880
  }
24805
- }), Dx.post("/trees.json", async (e) => {
24881
+ }), Ox.post("/trees.json", async (e) => {
24806
24882
  try {
24807
24883
  let t = e.get("db"), n = await e.req.json(), r = n.id, i = r != null && r !== "" && !isNaN(Number(r)) ? Number(r) : null, a = `tree-${Date.now().toString(36)}`, o = (n.key || n.slug || a).toLowerCase().replace(/[^a-z0-9_-]/g, "-"), s = n.label?.trim() || o, c = n.treeType !== void 0 && n.treeType !== null ? n.treeType : n.type ?? "site", l = n.channelId !== void 0 && n.channelId !== null && Number(n.channelId) || null, u = +(n.isHidden === !0 || n.isHidden === 1 || n.isHidden === "true"), d = e.get("user")?.id || null, f = { ...n };
24808
24884
  if (delete f.id, delete f.key, delete f.label, delete f.treeType, delete f.type, delete f.channelId, delete f.channels, delete f.isHidden, delete f.createdById, delete f.updatedById, delete f.createdAt, delete f.updatedAt, await t.prepare("SELECT id FROM trees WHERE key = ? AND id != ? LIMIT 1").get(o, i ?? -1)) return e.json({
@@ -24841,7 +24917,7 @@ Dx.get("/tree.json", async (e) => {
24841
24917
  } catch (t) {
24842
24918
  return console.error("[API Trees] Error saving tree:", t), e.json({ error: t.message || "Failed to save tree" }, 500);
24843
24919
  }
24844
- }), Dx.delete("/trees.json", async (e) => {
24920
+ }), Ox.delete("/trees.json", async (e) => {
24845
24921
  let t = e.get("db"), n = e.req.query("id");
24846
24922
  if (!n) return e.json({ error: "Tree ID required" }, 400);
24847
24923
  let r = Number(n);
@@ -24856,8 +24932,8 @@ Dx.get("/tree.json", async (e) => {
24856
24932
  });
24857
24933
  //#endregion
24858
24934
  //#region server/routes/admin/channels.ts
24859
- var jx = new e();
24860
- jx.get("/", async (e) => {
24935
+ var Mx = new e();
24936
+ Mx.get("/", async (e) => {
24861
24937
  try {
24862
24938
  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) => {
24863
24939
  e[t.channelId] || (e[t.channelId] = []);
@@ -24923,27 +24999,27 @@ jx.get("/", async (e) => {
24923
24999
  error: t.message
24924
25000
  }, 500);
24925
25001
  }
24926
- }), jx.post("/", async (e) => {
25002
+ }), Mx.post("/", async (e) => {
24927
25003
  try {
24928
25004
  let t = e.get("db"), n = await e.req.json(), r = n.channel || n.data || n, i = r.id, a = i != null && i !== "" && !isNaN(Number(i)) ? Number(i) : null, { key: o, label: s, channelType: c = "website", domain: l = "localhost", baseUrl: u = "http://localhost:4321", defaultLanguage: d, default_language: f, language: p, isHidden: m, hidden: h, trees: g = [], createdById: _ = null, updatedById: v = null, id: y, createdAt: b, updatedAt: x, ...S } = r, C = o?.trim() || "main", w = s?.trim() || "Untitled Channel", T = d || f || p || "";
24929
25005
  typeof T == "object" && T && (T = T.value || T.id || ""), T = String(T).trim();
24930
- let ee = m === !0 || m === "true" || m === 1 || h === !0 || h === "true" || h === 1, E = Array.isArray(g) ? g : [], D = JSON.stringify(S || {}), O = e.get("user")?.id || v || _ || null;
25006
+ let ee = m === !0 || m === "true" || m === 1 || h === !0 || h === "true" || h === 1, E = Array.isArray(g) ? g : [], D = JSON.stringify(S || {}), te = e.get("user")?.id || v || _ || null;
24931
25007
  if (await t.prepare("SELECT id FROM channels WHERE key = ? AND id != ? LIMIT 1").get(C, a ?? -1)) return e.json({
24932
25008
  error: `Channel API key "${C}" is already in use.`,
24933
25009
  field: "key"
24934
25010
  }, 409);
24935
- let te = a;
24936
- if (a) await t.prepare("\n UPDATE channels \n SET key = ?, label = ?, channelType = ?, domain = ?, baseUrl = ?, defaultLanguage = ?, \n isHidden = ?, dataJson = ?, updatedById = ?, updatedAt = CURRENT_TIMESTAMP\n WHERE id = ?\n ").run(C, w, c, l, u, T, +!!ee, D, O, a);
25011
+ let O = a;
25012
+ if (a) await t.prepare("\n UPDATE channels \n SET key = ?, label = ?, channelType = ?, domain = ?, baseUrl = ?, defaultLanguage = ?, \n isHidden = ?, dataJson = ?, updatedById = ?, updatedAt = CURRENT_TIMESTAMP\n WHERE id = ?\n ").run(C, w, c, l, u, T, +!!ee, D, te, a);
24937
25013
  else {
24938
- let e = await t.prepare("\n INSERT INTO channels (key, label, channelType, domain, baseUrl, defaultLanguage, isHidden, dataJson, createdById, updatedById)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n RETURNING id\n ").get(C, w, c, l, u, T, +!!ee, D, O, O), n = e?.results?.[0] || e;
25014
+ let e = await t.prepare("\n INSERT INTO channels (key, label, channelType, domain, baseUrl, defaultLanguage, isHidden, dataJson, createdById, updatedById)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n RETURNING id\n ").get(C, w, c, l, u, T, +!!ee, D, te, te), n = e?.results?.[0] || e;
24939
25015
  if (!n || !n.id) throw Error("Failed to retrieve newly created Channel ID from Cloudflare D1.");
24940
- te = Number(n.id);
25016
+ O = Number(n.id);
24941
25017
  }
24942
- await t.prepare("DELETE FROM channel_trees WHERE channelId = ?").run(te);
25018
+ await t.prepare("DELETE FROM channel_trees WHERE channelId = ?").run(O);
24943
25019
  let k = E.filter((e) => e && e.treeId && e.key);
24944
25020
  if (k.length > 0) {
24945
25021
  let e = k.map(() => "(?, ?, ?, ?)").join(", "), n = k.flatMap((e) => [
24946
- te,
25022
+ O,
24947
25023
  Number(e.treeId) || e.treeId,
24948
25024
  String(e.key).trim(),
24949
25025
  JSON.stringify(e.meta || {})
@@ -24954,9 +25030,9 @@ jx.get("/", async (e) => {
24954
25030
  `).run(...n);
24955
25031
  }
24956
25032
  let A = $b(e);
24957
- return await A.delete(`channel:${C}`), await A.delete(`channel:${te}`), await A.clear(), await hx(t), new mx(e.env).purgeGlobalCache(e, t), e.json({
25033
+ return await A.delete(`channel:${C}`), await A.delete(`channel:${O}`), await A.clear(), await hx(t), new mx(e.env).purgeGlobalCache(e, t), e.json({
24958
25034
  success: !0,
24959
- id: te
25035
+ id: O
24960
25036
  });
24961
25037
  } catch (t) {
24962
25038
  return console.error("[API Channels] Error saving channel:", t), e.json({
@@ -24964,7 +25040,7 @@ jx.get("/", async (e) => {
24964
25040
  details: t.message
24965
25041
  }, 500);
24966
25042
  }
24967
- }), jx.delete("/", async (e) => {
25043
+ }), Mx.delete("/", async (e) => {
24968
25044
  let t = e.get("db"), n = e.req.query("id");
24969
25045
  if (!n) return e.json({ error: "Channel ID required" }, 400);
24970
25046
  let r = Number(n);
@@ -24984,15 +25060,15 @@ jx.get("/", async (e) => {
24984
25060
  });
24985
25061
  //#endregion
24986
25062
  //#region server/routes/admin/taxonomies.ts
24987
- var Mx = new e();
24988
- function Nx(e) {
25063
+ var Nx = new e();
25064
+ function Px(e) {
24989
25065
  return e.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().trim().replace(/[^a-z0-9\s-]/g, "").replace(/[\s-]+/g, "-").replace(/^-+|-+$/g, "");
24990
25066
  }
24991
- function Px(e) {
25067
+ function Fx(e) {
24992
25068
  let t = (e || "").trim().toLowerCase(), n = px()?.taxonomies || {};
24993
25069
  return n[t] ? t : n[`${t}s`] ? `${t}s` : t.endsWith("s") && n[t.slice(0, -1)] ? t.slice(0, -1) : t;
24994
25070
  }
24995
- async function Fx(e, t, n = []) {
25071
+ async function Ix(e, t, n = []) {
24996
25072
  let r = e.prepare(t);
24997
25073
  if (typeof r.bind == "function") {
24998
25074
  let e = await r.bind(...n).all();
@@ -25004,10 +25080,10 @@ async function Fx(e, t, n = []) {
25004
25080
  }
25005
25081
  return [];
25006
25082
  }
25007
- Mx.get("/:taxonomy", async (e) => {
25008
- let t = e.get("db"), n = Px(e.req.param("taxonomy"));
25083
+ Nx.get("/:taxonomy", async (e) => {
25084
+ let t = e.get("db"), n = Fx(e.req.param("taxonomy"));
25009
25085
  try {
25010
- let r = (await Fx(t, "\n SELECT id, taxonomy, key, label, parentId, sortOrder, dataJson, createdAt, updatedAt\n FROM taxonomy_terms\n WHERE taxonomy = ?\n ORDER BY sortOrder ASC, label ASC\n ", [n])).map((e) => ({
25086
+ let r = (await Ix(t, "\n SELECT id, taxonomy, key, label, parentId, sortOrder, dataJson, createdAt, updatedAt\n FROM taxonomy_terms\n WHERE taxonomy = ?\n ORDER BY sortOrder ASC, label ASC\n ", [n])).map((e) => ({
25011
25087
  ...e,
25012
25088
  data: e.dataJson ? JSON.parse(e.dataJson) : {}
25013
25089
  }));
@@ -25018,12 +25094,12 @@ Mx.get("/:taxonomy", async (e) => {
25018
25094
  } catch (t) {
25019
25095
  return console.error("[Taxonomy API] Error fetching terms:", t), e.json({ error: "Failed to fetch taxonomy terms" }, 500);
25020
25096
  }
25021
- }), Mx.post("/:taxonomy", async (e) => {
25022
- let t = e.get("db"), n = Px(e.req.param("taxonomy")), r = await e.req.json(), i = r.label?.trim();
25097
+ }), Nx.post("/:taxonomy", async (e) => {
25098
+ let t = e.get("db"), n = Fx(e.req.param("taxonomy")), r = await e.req.json(), i = r.label?.trim();
25023
25099
  if (!i) return e.json({ error: "Label is required" }, 400);
25024
- let a = r.key?.trim() || Nx(i), o = r.parentId ? Number(r.parentId) : null, s = r.sortOrder ? Number(r.sortOrder) : 0, c = r.data ? JSON.stringify(r.data) : "{}";
25100
+ let a = r.key?.trim() || Px(i), o = r.parentId ? Number(r.parentId) : null, s = r.sortOrder ? Number(r.sortOrder) : 0, c = r.data ? JSON.stringify(r.data) : "{}";
25025
25101
  try {
25026
- if ((await Fx(t, "SELECT id FROM taxonomy_terms WHERE taxonomy = ? AND key = ?", [n, a])).length > 0) return e.json({ error: `A term with the key '${a}' already exists in this taxonomy.` }, 409);
25102
+ if ((await Ix(t, "SELECT id FROM taxonomy_terms WHERE taxonomy = ? AND key = ?", [n, a])).length > 0) return e.json({ error: `A term with the key '${a}' already exists in this taxonomy.` }, 409);
25027
25103
  let r = t.prepare("\n INSERT INTO taxonomy_terms (taxonomy, key, label, parentId, sortOrder, dataJson)\n VALUES (?, ?, ?, ?, ?, ?)\n "), l;
25028
25104
  return l = typeof r.bind == "function" ? await r.bind(n, a, i, o, s, c).run() : await r.run(n, a, i, o, s, c), e.json({
25029
25105
  success: !0,
@@ -25032,12 +25108,12 @@ Mx.get("/:taxonomy", async (e) => {
25032
25108
  } catch (t) {
25033
25109
  return console.error("[Taxonomy API] Error creating term:", t), e.json({ error: "Failed to create taxonomy term" }, 500);
25034
25110
  }
25035
- }), Mx.put("/:taxonomy/:id", async (e) => {
25036
- let t = e.get("db"), n = Px(e.req.param("taxonomy")), r = Number(e.req.param("id"));
25111
+ }), Nx.put("/:taxonomy/:id", async (e) => {
25112
+ let t = e.get("db"), n = Fx(e.req.param("taxonomy")), r = Number(e.req.param("id"));
25037
25113
  if (isNaN(r)) return e.json({ error: "Invalid term ID" }, 400);
25038
25114
  let i = await e.req.json();
25039
25115
  try {
25040
- let a = await Fx(t, "SELECT * FROM taxonomy_terms WHERE id = ? AND taxonomy = ?", [r, n]);
25116
+ let a = await Ix(t, "SELECT * FROM taxonomy_terms WHERE id = ? AND taxonomy = ?", [r, n]);
25041
25117
  if (a.length === 0) return e.json({ error: "Term not found" }, 404);
25042
25118
  let o = a[0], s = i.label === void 0 ? o.label : i.label.trim(), c = i.key === void 0 ? o.key : i.key.trim(), l = i.parentId === void 0 ? o.parentId : i.parentId ? Number(i.parentId) : null, u = i.sortOrder === void 0 ? o.sortOrder : Number(i.sortOrder), d = o.dataJson;
25043
25119
  if (i.data) {
@@ -25047,14 +25123,14 @@ Mx.get("/:taxonomy", async (e) => {
25047
25123
  ...i.data
25048
25124
  });
25049
25125
  }
25050
- if (c !== o.key && (await Fx(t, "SELECT id FROM taxonomy_terms WHERE taxonomy = ? AND key = ?", [n, c])).length > 0) return e.json({ error: `A term with the key '${c}' already exists in this taxonomy.` }, 409);
25126
+ if (c !== o.key && (await Ix(t, "SELECT id FROM taxonomy_terms WHERE taxonomy = ? AND key = ?", [n, c])).length > 0) return e.json({ error: `A term with the key '${c}' already exists in this taxonomy.` }, 409);
25051
25127
  let f = t.prepare("\n UPDATE taxonomy_terms \n SET label = ?, key = ?, parentId = ?, sortOrder = ?, dataJson = ?, updatedAt = CURRENT_TIMESTAMP\n WHERE id = ?\n ");
25052
25128
  return typeof f.bind == "function" ? await f.bind(s, c, l, u, d, r).run() : await f.run(s, c, l, u, d, r), e.json({ success: !0 });
25053
25129
  } catch (t) {
25054
25130
  return console.error("[Taxonomy API] Error updating term:", t), e.json({ error: "Failed to update taxonomy term" }, 500);
25055
25131
  }
25056
- }), Mx.delete("/:taxonomy/:id", async (e) => {
25057
- let t = e.get("db"), n = Px(e.req.param("taxonomy")), r = Number(e.req.param("id"));
25132
+ }), Nx.delete("/:taxonomy/:id", async (e) => {
25133
+ let t = e.get("db"), n = Fx(e.req.param("taxonomy")), r = Number(e.req.param("id"));
25058
25134
  if (isNaN(r)) return e.json({ error: "Invalid term ID" }, 400);
25059
25135
  try {
25060
25136
  let i = t.prepare("DELETE FROM taxonomy_terms WHERE id = ? AND taxonomy = ?");
@@ -25065,20 +25141,20 @@ Mx.get("/:taxonomy", async (e) => {
25065
25141
  });
25066
25142
  //#endregion
25067
25143
  //#region server/schema/engine.ts
25068
- var Ix = null, Lx = null;
25144
+ var Lx = null, Rx = null;
25069
25145
  if (typeof process < "u" && process?.versions?.node) try {
25070
25146
  let e = i(import.meta.url);
25071
- Ix = e("node:fs"), Lx = e("node:path");
25147
+ Lx = e("node:fs"), Rx = e("node:path");
25072
25148
  } catch {}
25073
- function Rx(e, t = "") {
25149
+ function zx(e, t = "") {
25074
25150
  let n = e.split(/[\\/]/).pop() || "";
25075
25151
  return t && n.endsWith(t) ? n.slice(0, -t.length) : n;
25076
25152
  }
25077
- function zx(e) {
25153
+ function Bx(e) {
25078
25154
  let t = e.match(/\.[^.\\/]+$/);
25079
25155
  return t ? t[0] : "";
25080
25156
  }
25081
- var Bx = {
25157
+ var Vx = {
25082
25158
  nodes: {},
25083
25159
  trees: {},
25084
25160
  blocks: {},
@@ -25088,10 +25164,10 @@ var Bx = {
25088
25164
  nodeLayouts: {},
25089
25165
  blockLayouts: {}
25090
25166
  };
25091
- function Vx(e) {
25167
+ function Hx(e) {
25092
25168
  return e ? typeof e == "string" ? e.trim() : Array.isArray(e) ? e.includes("*") ? "*" : e : "*" : "*";
25093
25169
  }
25094
- function Hx(e = {}, t = {}) {
25170
+ function Ux(e = {}, t = {}) {
25095
25171
  let n = {
25096
25172
  ...e,
25097
25173
  ...t,
@@ -25103,62 +25179,62 @@ function Hx(e = {}, t = {}) {
25103
25179
  };
25104
25180
  return t.required === !0 || String(t.required).toLowerCase() === "true" || t.rules?.required === !0 || String(t.rules?.required).toLowerCase() === "true" || t.required === void 0 && (e.required === !0 || String(e.required).toLowerCase() === "true" || e.rules?.required === !0 || String(e.rules?.required).toLowerCase() === "true") ? (n.required = !0, n.rules.required = !0) : (t.required === !1 || t.rules?.required === !1) && (n.required = !1, n.rules.required = !1), n;
25105
25181
  }
25106
- function Ux(e) {
25182
+ function Wx(e) {
25107
25183
  if (!e || typeof e != "object") return e;
25108
- if (Array.isArray(e)) return e.map(Ux);
25184
+ if (Array.isArray(e)) return e.map(Wx);
25109
25185
  let t = {};
25110
25186
  for (let [n, r] of Object.entries(e)) if (n === "<<" || n === "<<:") {
25111
- let e = Ux(r);
25187
+ let e = Wx(r);
25112
25188
  if (typeof e == "object" && e) {
25113
25189
  if (Array.isArray(e)) for (let n of e) Object.assign(t, n);
25114
25190
  else Object.assign(t, e);
25115
25191
  }
25116
- } else t[n] = Ux(r);
25192
+ } else t[n] = Wx(r);
25117
25193
  return t;
25118
25194
  }
25119
- function Wx(e, t) {
25120
- return e ? Ux(n.parseDocument(e, { customTags: [{
25195
+ function Gx(e, t) {
25196
+ return e ? Wx(n.parseDocument(e, { customTags: [{
25121
25197
  tag: "!include",
25122
25198
  resolve(e) {
25123
- let n = (typeof e == "string" ? e : String(e?.strValue || e?.value || "")).trim(), r = Rx(n);
25199
+ let n = (typeof e == "string" ? e : String(e?.strValue || e?.value || "")).trim(), r = zx(n);
25124
25200
  if (!r) return n;
25125
25201
  if (t && t.fieldSets) {
25126
25202
  let e = Object.keys(t.fieldSets).find((e) => e.endsWith("/" + r) || e === r);
25127
- if (e) return Wx(t.fieldSets[e], t);
25203
+ if (e) return Gx(t.fieldSets[e], t);
25128
25204
  }
25129
25205
  return n;
25130
25206
  }
25131
25207
  }] }).toJS() || {}) : {};
25132
25208
  }
25133
- function Gx(e, t = /* @__PURE__ */ new Set()) {
25134
- if (!Ix || !Lx) return {};
25135
- let r = Lx.resolve(e);
25136
- if (t.has(r) || (t.add(r), !Ix.existsSync(r))) return {};
25137
- let i = Ix.readFileSync(r, "utf-8");
25138
- return Ux(n.parseDocument(i, { customTags: [{
25209
+ function Kx(e, t = /* @__PURE__ */ new Set()) {
25210
+ if (!Lx || !Rx) return {};
25211
+ let r = Rx.resolve(e);
25212
+ if (t.has(r) || (t.add(r), !Lx.existsSync(r))) return {};
25213
+ let i = Lx.readFileSync(r, "utf-8");
25214
+ return Wx(n.parseDocument(i, { customTags: [{
25139
25215
  tag: "!include",
25140
25216
  resolve(e) {
25141
25217
  let n = (typeof e == "string" ? e : String(e?.strValue || e?.value || "")).trim();
25142
- return n ? Gx(Lx.resolve(Lx.dirname(r), n), new Set(t)) : {};
25218
+ return n ? Kx(Rx.resolve(Rx.dirname(r), n), new Set(t)) : {};
25143
25219
  }
25144
25220
  }] }).toJS() || {});
25145
25221
  }
25146
- function Kx() {
25147
- if (!Ix || !Lx || typeof process > "u" || !process?.versions?.node) return null;
25222
+ function qx() {
25223
+ if (!Lx || !Rx || typeof process > "u" || !process?.versions?.node) return null;
25148
25224
  try {
25149
25225
  let e = process.cwd(), t = "", n = [
25150
- Lx.resolve(e, "content/definitions"),
25151
- Lx.resolve(e, "content"),
25152
- Lx.resolve(e, "definitions"),
25153
- Lx.resolve(e, "kama-worker/content/definitions")
25226
+ Rx.resolve(e, "content/definitions"),
25227
+ Rx.resolve(e, "content"),
25228
+ Rx.resolve(e, "definitions"),
25229
+ Rx.resolve(e, "kama-worker/content/definitions")
25154
25230
  ];
25155
25231
  try {
25156
25232
  if (import.meta.url) {
25157
- let e = Lx.dirname(r(import.meta.url));
25158
- n.push(Lx.resolve(e, "../../content/definitions")), n.push(Lx.resolve(e, "../content/definitions"));
25233
+ let e = Rx.dirname(r(import.meta.url));
25234
+ n.push(Rx.resolve(e, "../../content/definitions")), n.push(Rx.resolve(e, "../content/definitions"));
25159
25235
  }
25160
25236
  } catch {}
25161
- for (let e of n) if (Ix.existsSync(e)) {
25237
+ for (let e of n) if (Lx.existsSync(e)) {
25162
25238
  t = e;
25163
25239
  break;
25164
25240
  }
@@ -25166,19 +25242,19 @@ function Kx() {
25166
25242
  let i = (e) => {
25167
25243
  let n = "";
25168
25244
  for (let r of e) {
25169
- let e = Lx.join(t, r);
25170
- if (Ix.existsSync(e)) {
25245
+ let e = Rx.join(t, r);
25246
+ if (Lx.existsSync(e)) {
25171
25247
  n = e;
25172
25248
  break;
25173
25249
  }
25174
25250
  }
25175
25251
  if (!n) return {};
25176
- let r = {}, i = Ix.readdirSync(n);
25252
+ let r = {}, i = Lx.readdirSync(n);
25177
25253
  for (let e of i) {
25178
25254
  if (!e.endsWith(".yaml") && !e.endsWith(".yml")) continue;
25179
- let t = Lx.join(n, e), i = Rx(e, zx(e));
25255
+ let t = Rx.join(n, e), i = zx(e, Bx(e));
25180
25256
  try {
25181
- r[i] = Gx(t);
25257
+ r[i] = Kx(t);
25182
25258
  } catch (t) {
25183
25259
  console.error(`❌ Error parsing ${e}:`, t.message);
25184
25260
  }
@@ -25207,59 +25283,59 @@ function Kx() {
25207
25283
  return console.error("❌ Exception inside readLocalFsBundle:", e), null;
25208
25284
  }
25209
25285
  }
25210
- var qx = null, Jx = null;
25211
- function Yx(e) {
25212
- if (!e) qx = null, Jx = null;
25213
- else if (qx && Jx === e) return qx;
25214
- let t = Xx(e);
25215
- return qx = t, Jx = e, t;
25216
- }
25286
+ var Jx = null, Yx = null;
25217
25287
  function Xx(e) {
25288
+ if (!e) Jx = null, Yx = null;
25289
+ else if (Jx && Yx === e) return Jx;
25290
+ let t = Zx(e);
25291
+ return Jx = t, Yx = e, t;
25292
+ }
25293
+ function Zx(e) {
25218
25294
  if (e) {
25219
25295
  let t = {
25220
25296
  nodes: {
25221
25297
  ...e.nodes || e.rawNodes || {},
25222
- ...Bx.nodes
25298
+ ...Vx.nodes
25223
25299
  },
25224
25300
  trees: {
25225
25301
  ...e.trees || e.rawTrees || {},
25226
- ...Bx.trees
25302
+ ...Vx.trees
25227
25303
  },
25228
25304
  channels: {
25229
25305
  ...e.channels || e.rawChannels || {},
25230
- ...Bx.channels
25306
+ ...Vx.channels
25231
25307
  },
25232
25308
  taxonomies: {
25233
25309
  ...e.taxonomies || e.rawTaxonomies || {},
25234
- ...Bx.taxonomies
25310
+ ...Vx.taxonomies
25235
25311
  },
25236
25312
  blocks: {
25237
25313
  ...e.blocks || e.rawBlocks || {},
25238
- ...Bx.blocks
25314
+ ...Vx.blocks
25239
25315
  },
25240
25316
  nodeLayouts: {
25241
25317
  ...e.nodeLayouts || e.rawNodeLayouts || {},
25242
- ...Bx.nodeLayouts
25318
+ ...Vx.nodeLayouts
25243
25319
  },
25244
25320
  blockLayouts: {
25245
25321
  ...e.blockLayouts || e.rawBlockLayouts || {},
25246
- ...Bx.blockLayouts
25322
+ ...Vx.blockLayouts
25247
25323
  },
25248
25324
  fieldSets: {
25249
25325
  ...e.fieldSets || e.rawFieldSets || {},
25250
- ...Bx.fieldSets
25326
+ ...Vx.fieldSets
25251
25327
  }
25252
25328
  };
25253
25329
  if (typeof Object.values(t.nodes)[0] == "string") {
25254
25330
  let e = (e) => {
25255
25331
  let n = {};
25256
25332
  for (let [r, i] of Object.entries(e || {})) {
25257
- let e = Rx(r, zx(r));
25258
- n[e] = Wx(i, t);
25333
+ let e = zx(r, Bx(r));
25334
+ n[e] = Gx(i, t);
25259
25335
  }
25260
25336
  return n;
25261
25337
  };
25262
- return Zx({
25338
+ return Qx({
25263
25339
  rawNodes: e(t.nodes),
25264
25340
  rawTrees: e(t.trees),
25265
25341
  rawChannels: e(t.channels),
@@ -25270,12 +25346,12 @@ function Xx(e) {
25270
25346
  rawFieldSets: e(t.fieldSets)
25271
25347
  });
25272
25348
  }
25273
- return Zx(t);
25349
+ return Qx(t);
25274
25350
  }
25275
- let t = Kx();
25276
- return t && Object.keys(t.rawNodes || {}).length > 0 ? Zx(t) : Zx(null);
25351
+ let t = qx();
25352
+ return t && Object.keys(t.rawNodes || {}).length > 0 ? Qx(t) : Qx(null);
25277
25353
  }
25278
- function Zx(e) {
25354
+ function Qx(e) {
25279
25355
  if (!e) return {
25280
25356
  nodes: {},
25281
25357
  trees: {},
@@ -25290,7 +25366,7 @@ function Zx(e) {
25290
25366
  channelTemplate: null,
25291
25367
  userTemplate: null
25292
25368
  };
25293
- let { rawNodes: t = {}, rawTrees: n = {}, rawChannels: r = {}, channels: i = {}, rawTaxonomies: a = {}, taxonomies: o = {}, rawBlocks: s = {}, rawElements: c = {}, rawNodeLayouts: l = {}, rawBlockLayouts: u = {}, rawLayouts: d = {}, rawFieldSets: f = {}, rawTemplates: p = {}, nodeTemplate: m = null, treeTemplate: h = null, channelTemplate: g = null, userTemplate: _ = null, nodes: v = {}, trees: y = {}, blocks: b = {}, nodeLayouts: x = {}, blockLayouts: S = {} } = e, C = Object.keys(t).length > 0 ? t : v, w = Object.keys(n).length > 0 ? n : y, T = Object.keys(r).length > 0 ? r : i, ee = Object.keys(a).length > 0 ? a : o, E = Object.keys(s).length > 0 ? s : Object.keys(c).length > 0 ? c : b, D = Object.keys(l).length > 0 ? l : Object.keys(d).length > 0 ? d : x, O = Object.keys(u).length > 0 ? u : S, te = m?.fields || {}, k = {
25369
+ let { rawNodes: t = {}, rawTrees: n = {}, rawChannels: r = {}, channels: i = {}, rawTaxonomies: a = {}, taxonomies: o = {}, rawBlocks: s = {}, rawElements: c = {}, rawNodeLayouts: l = {}, rawBlockLayouts: u = {}, rawLayouts: d = {}, rawFieldSets: f = {}, rawTemplates: p = {}, nodeTemplate: m = null, treeTemplate: h = null, channelTemplate: g = null, userTemplate: _ = null, nodes: v = {}, trees: y = {}, blocks: b = {}, nodeLayouts: x = {}, blockLayouts: S = {} } = e, C = Object.keys(t).length > 0 ? t : v, w = Object.keys(n).length > 0 ? n : y, T = Object.keys(r).length > 0 ? r : i, ee = Object.keys(a).length > 0 ? a : o, E = Object.keys(s).length > 0 ? s : Object.keys(c).length > 0 ? c : b, D = Object.keys(l).length > 0 ? l : Object.keys(d).length > 0 ? d : x, te = Object.keys(u).length > 0 ? u : S, O = m?.fields || {}, k = {
25294
25370
  ...p,
25295
25371
  ...f
25296
25372
  }, A = (e, t = "settings", n, r) => {
@@ -25307,11 +25383,11 @@ function Zx(e) {
25307
25383
  fields: {}
25308
25384
  }), Object.entries(s).forEach(([e, r]) => {
25309
25385
  let i = n[t].fields[e] || {};
25310
- n[t].fields[e] = Hx(i, r);
25386
+ n[t].fields[e] = Ux(i, r);
25311
25387
  });
25312
25388
  } else Object.entries(s).forEach(([e, t]) => {
25313
25389
  let n = i[e] || {};
25314
- i[e] = Hx(n, t);
25390
+ i[e] = Ux(n, t);
25315
25391
  });
25316
25392
  };
25317
25393
  return !Array.isArray(e) && typeof e == "object" && e ? (Object.entries(e).forEach(([e, t]) => {
@@ -25320,15 +25396,15 @@ function Zx(e) {
25320
25396
  a(String(t));
25321
25397
  return;
25322
25398
  }
25323
- let n = i[e] || te[e] || {};
25324
- i[e] = Hx(n, typeof t == "object" && t ? t : { label: String(t) });
25399
+ let n = i[e] || O[e] || {};
25400
+ i[e] = Ux(n, typeof t == "object" && t ? t : { label: String(t) });
25325
25401
  }), i) : (Array.isArray(e) && e.forEach((e) => {
25326
25402
  if (typeof e == "string") {
25327
25403
  if (e.includes("/") || e.endsWith(".yaml") || e.endsWith(".yml")) return;
25328
25404
  if (e.startsWith("fieldSet:")) a(e.replace("fieldSet:", "").trim());
25329
25405
  else {
25330
- let t = i[e] || te[e] || {};
25331
- i[e] = Hx(t, {
25406
+ let t = i[e] || O[e] || {};
25407
+ i[e] = Ux(t, {
25332
25408
  type: "text",
25333
25409
  label: e
25334
25410
  });
@@ -25336,8 +25412,8 @@ function Zx(e) {
25336
25412
  } else typeof e == "object" && e && Object.entries(e).forEach(([e, t]) => {
25337
25413
  if (e === "fieldSet") a(String(t));
25338
25414
  else if (e !== "<<" && e !== "<<:") {
25339
- let n = i[e] || te[e] || {};
25340
- i[e] = Hx(n, typeof t == "object" && t ? t : {});
25415
+ let n = i[e] || O[e] || {};
25416
+ i[e] = Ux(n, typeof t == "object" && t ? t : {});
25341
25417
  }
25342
25418
  });
25343
25419
  }), i);
@@ -25355,7 +25431,7 @@ function Zx(e) {
25355
25431
  let s = A(i.fields || i, a, n, t);
25356
25432
  Object.entries(s).forEach(([e, t]) => {
25357
25433
  let r = n[a].fields[e] || {};
25358
- n[a].fields[e] = Hx(r, t);
25434
+ n[a].fields[e] = Ux(r, t);
25359
25435
  });
25360
25436
  }
25361
25437
  }), n) : (Object.entries(e).forEach(([e, r]) => {
@@ -25371,7 +25447,7 @@ function Zx(e) {
25371
25447
  Object.entries(s).forEach(([t, r]) => {
25372
25448
  if (t === "<<" || t === "<<:" || t === "label") return;
25373
25449
  let i = n[e].fields[t] || {};
25374
- n[e].fields[t] = Hx(i, r);
25450
+ n[e].fields[t] = Ux(i, r);
25375
25451
  });
25376
25452
  }), n);
25377
25453
  }, j = {};
@@ -25389,16 +25465,16 @@ function Zx(e) {
25389
25465
  fields: {}
25390
25466
  }), Object.entries(o).forEach(([e, r]) => {
25391
25467
  let i = n[t].fields[e] || {};
25392
- n[t].fields[e] = Hx(i, r);
25468
+ n[t].fields[e] = Ux(i, r);
25393
25469
  });
25394
25470
  } else Object.entries(o).forEach(([e, t]) => {
25395
- let n = r[e] || te[e] || {};
25396
- r[e] = Hx(n, t);
25471
+ let n = r[e] || O[e] || {};
25472
+ r[e] = Ux(n, t);
25397
25473
  });
25398
25474
  }), Object.values(n).forEach((e) => {
25399
25475
  Object.entries(e.fields).forEach(([e, t]) => {
25400
25476
  let n = r[e] || {};
25401
- r[e] = Hx(n, t);
25477
+ r[e] = Ux(n, t);
25402
25478
  });
25403
25479
  }), Object.keys(n).length === 0 && Object.keys(r).length > 0 && (n.settings = {
25404
25480
  label: t.label || "Settings",
@@ -25411,8 +25487,8 @@ function Zx(e) {
25411
25487
  inVault: t.inVault !== !1,
25412
25488
  hasCanvas: t.hasCanvas === !0,
25413
25489
  defaultLayout: t.defaultLayout,
25414
- allowedBlocks: Vx(t.allowedBlocks),
25415
- disallowedBlocks: t.disallowedBlocks ? Vx(t.disallowedBlocks) : void 0,
25490
+ allowedBlocks: Hx(t.allowedBlocks),
25491
+ disallowedBlocks: t.disallowedBlocks ? Hx(t.disallowedBlocks) : void 0,
25416
25492
  tabs: n,
25417
25493
  fields: r
25418
25494
  };
@@ -25423,11 +25499,11 @@ function Zx(e) {
25423
25499
  Array.isArray(t.fieldSets) && t.fieldSets.forEach((e) => {
25424
25500
  let t = k[e] || {}, i = t.fields || t, a = A(i, "settings", n);
25425
25501
  Object.entries(a).forEach(([e, t]) => {
25426
- r[e] = Hx(r[e] || {}, t);
25502
+ r[e] = Ux(r[e] || {}, t);
25427
25503
  });
25428
25504
  }), Object.values(n).forEach((e) => {
25429
25505
  Object.entries(e.fields).forEach(([e, t]) => {
25430
- r[e] = Hx(r[e] || {}, t);
25506
+ r[e] = Ux(r[e] || {}, t);
25431
25507
  });
25432
25508
  }), re[e] = {
25433
25509
  ...t,
@@ -25443,11 +25519,11 @@ function Zx(e) {
25443
25519
  Array.isArray(t.fieldSets) && t.fieldSets.forEach((e) => {
25444
25520
  let t = k[e] || {}, n = t.fields || t, i = A(n);
25445
25521
  Object.entries(i).forEach(([e, t]) => {
25446
- r[e] = Hx(r[e] || {}, t);
25522
+ r[e] = Ux(r[e] || {}, t);
25447
25523
  });
25448
25524
  }), Object.values(n).forEach((e) => {
25449
25525
  Object.entries(e.fields).forEach(([e, t]) => {
25450
- r[e] = Hx(r[e] || {}, t);
25526
+ r[e] = Ux(r[e] || {}, t);
25451
25527
  });
25452
25528
  }), ie[e] = {
25453
25529
  ...t,
@@ -25464,11 +25540,11 @@ function Zx(e) {
25464
25540
  Array.isArray(t.fieldSets) && t.fieldSets.forEach((e) => {
25465
25541
  let t = k[e] || {}, i = t.fields || t, a = A(i, "settings", n);
25466
25542
  Object.entries(a).forEach(([e, t]) => {
25467
- r[e] = Hx(r[e] || {}, t);
25543
+ r[e] = Ux(r[e] || {}, t);
25468
25544
  });
25469
25545
  }), Object.values(n).forEach((e) => {
25470
25546
  Object.entries(e.fields).forEach(([e, t]) => {
25471
- r[e] = Hx(r[e] || {}, t);
25547
+ r[e] = Ux(r[e] || {}, t);
25472
25548
  });
25473
25549
  }), ae[e] = {
25474
25550
  ...t,
@@ -25485,7 +25561,7 @@ function Zx(e) {
25485
25561
  Array.isArray(t.fieldSets) && t.fieldSets.forEach((e) => {
25486
25562
  let t = k[e] || {}, r = t.fields || t, i = A(r);
25487
25563
  Object.entries(i).forEach(([e, t]) => {
25488
- n[e] = Hx(n[e] || {}, t);
25564
+ n[e] = Ux(n[e] || {}, t);
25489
25565
  });
25490
25566
  }), oe[e] = {
25491
25567
  ...t,
@@ -25502,8 +25578,8 @@ function Zx(e) {
25502
25578
  i[e] = {
25503
25579
  ...t,
25504
25580
  label: t.label || e,
25505
- allowedBlocks: Vx(t.allowedBlocks),
25506
- disallowedBlocks: t.disallowedBlocks ? Vx(t.disallowedBlocks) : void 0
25581
+ allowedBlocks: Hx(t.allowedBlocks),
25582
+ disallowedBlocks: t.disallowedBlocks ? Hx(t.disallowedBlocks) : void 0
25507
25583
  };
25508
25584
  }), se[e] = {
25509
25585
  ...t,
@@ -25519,14 +25595,14 @@ function Zx(e) {
25519
25595
  };
25520
25596
  });
25521
25597
  let ce = {};
25522
- Object.entries(O).forEach(([e, t]) => {
25598
+ Object.entries(te).forEach(([e, t]) => {
25523
25599
  let n = ne(t.tabs), r = A(t.fields || [], "settings", n), i = {}, a = t.regions || { main: { label: "Main Content" } };
25524
25600
  Object.entries(a).forEach(([e, t]) => {
25525
25601
  i[e] = {
25526
25602
  ...t,
25527
25603
  label: t.label || e,
25528
- allowedBlocks: Vx(t.allowedBlocks),
25529
- disallowedBlocks: t.disallowedBlocks ? Vx(t.disallowedBlocks) : void 0
25604
+ allowedBlocks: Hx(t.allowedBlocks),
25605
+ disallowedBlocks: t.disallowedBlocks ? Hx(t.disallowedBlocks) : void 0
25530
25606
  };
25531
25607
  }), ce[e] = {
25532
25608
  ...t,
@@ -25545,7 +25621,7 @@ function Zx(e) {
25545
25621
  Array.isArray(g?.fieldSets) && g?.fieldSets.forEach((e) => {
25546
25622
  let t = k[e] || {}, n = t.fields || t, r = A(n);
25547
25623
  Object.entries(r).forEach(([e, t]) => {
25548
- le[e] = Hx(le[e] || {}, t);
25624
+ le[e] = Ux(le[e] || {}, t);
25549
25625
  });
25550
25626
  });
25551
25627
  let ue = g ? {
@@ -25555,7 +25631,7 @@ function Zx(e) {
25555
25631
  Array.isArray(_?.fieldSets) && _?.fieldSets.forEach((e) => {
25556
25632
  let t = k[e] || {}, n = t.fields || t, r = A(n);
25557
25633
  Object.entries(r).forEach(([e, t]) => {
25558
- de[e] = Hx(de[e] || {}, t);
25634
+ de[e] = Ux(de[e] || {}, t);
25559
25635
  });
25560
25636
  });
25561
25637
  let fe = _ ? {
@@ -25579,11 +25655,11 @@ function Zx(e) {
25579
25655
  }
25580
25656
  //#endregion
25581
25657
  //#region server/routes/admin/schemas.ts
25582
- var Qx = new e(), $x = (e) => {
25658
+ var $x = new e(), eS = (e) => {
25583
25659
  try {
25584
25660
  let t = e.env?.BUNDLED_DEFINITIONS;
25585
25661
  (!t || Object.keys(t).length === 0) && (t = Db || Eb || Tb);
25586
- let n = Yx(t);
25662
+ let n = Xx(t);
25587
25663
  return e.json(n, 200, { "Cache-Control": "no-cache, no-store, must-revalidate" });
25588
25664
  } catch (t) {
25589
25665
  return console.error("[CMS API] Error loading schemas:", t), e.json({
@@ -25592,10 +25668,10 @@ var Qx = new e(), $x = (e) => {
25592
25668
  }, 500);
25593
25669
  }
25594
25670
  };
25595
- Qx.get("/", $x), Qx.get("/schemas.json", $x);
25671
+ $x.get("/", eS), $x.get("/schemas.json", eS);
25596
25672
  //#endregion
25597
25673
  //#region server/routes/admin/validation.ts
25598
- var eS = new e(), tS = {
25674
+ var tS = new e(), nS = {
25599
25675
  node: "content_nodes",
25600
25676
  nodes: "content_nodes",
25601
25677
  content_node: "content_nodes",
@@ -25607,7 +25683,7 @@ var eS = new e(), tS = {
25607
25683
  user: "users",
25608
25684
  users: "users",
25609
25685
  user_account: "user_accounts"
25610
- }, nS = {
25686
+ }, rS = {
25611
25687
  content_nodes: [
25612
25688
  "id",
25613
25689
  "title",
@@ -25664,11 +25740,11 @@ var eS = new e(), tS = {
25664
25740
  "createdAt"
25665
25741
  ]
25666
25742
  };
25667
- eS.post("/validate-unique", async (e) => {
25743
+ tS.post("/validate-unique", async (e) => {
25668
25744
  try {
25669
25745
  let t = e.get("db"), { entityType: n, field: r, value: i, excludeId: a } = await e.req.json();
25670
25746
  if (!r || i == null || String(i).trim() === "") return e.json({ isUnique: !0 });
25671
- let o = tS[n] || "content_nodes", s = r.replace(/[^a-zA-Z0-9_]/g, ""), c = (nS[o] || nS.content_nodes).includes(s), l = -1;
25747
+ let o = nS[n] || "content_nodes", s = r.replace(/[^a-zA-Z0-9_]/g, ""), c = (rS[o] || rS.content_nodes).includes(s), l = -1;
25672
25748
  if (a != null && String(a).trim() !== "") {
25673
25749
  let e = Number(a);
25674
25750
  l = isNaN(e) ? String(a) : e;
@@ -25680,16 +25756,16 @@ eS.post("/validate-unique", async (e) => {
25680
25756
  } catch (t) {
25681
25757
  return console.error("[API Validation] Error validating global uniqueness:", t), e.json({ error: "Failed to validate uniqueness" }, 500);
25682
25758
  }
25683
- }), eS.post("/validate-unique-sibling", async (e) => e.json({ isUnique: !0 }));
25759
+ }), tS.post("/validate-unique-sibling", async (e) => e.json({ isUnique: !0 }));
25684
25760
  //#endregion
25685
25761
  //#region server/routes/admin/stats.ts
25686
- var rS = new e();
25687
- rS.get("/", async (e) => {
25762
+ var iS = new e();
25763
+ iS.get("/", async (e) => {
25688
25764
  try {
25689
- 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 WHERE deletedAt IS NULL OR deletedAt = ''\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 WHERE deletedAt IS NULL OR deletedAt = ''\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 WHERE deletedAt IS NULL OR deletedAt = ''\n ORDER BY updatedAt DESC \n LIMIT 5\n ").all(), u = (Array.isArray(l) ? l : l?.results || []).map((e) => ({
25765
+ 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 WHERE deletedAt IS NULL\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 WHERE deletedAt IS NULL\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 WHERE deletedAt IS NULL\n ORDER BY updatedAt DESC \n LIMIT 5\n ").all(), u = (Array.isArray(l) ? l : l?.results || []).map((e) => ({
25690
25766
  ...e,
25691
25767
  isHidden: !!e.isHidden
25692
- })), d = await t.prepare("\n SELECT \n cn.id, \n cn.title, \n cn.slug, \n cn.contentType, \n cn.isHidden, \n cn.status, \n cn.publishedAt,\n cn.hasUnpublishedChanges,\n cn.updatedAt,\n GROUP_CONCAT(DISTINCT ch.label) as channelLabels,\n GROUP_CONCAT(DISTINCT t.label) as treeLabels\n FROM content_nodes cn\n LEFT JOIN node_channels nc ON cn.id = nc.nodeId\n LEFT JOIN channels ch ON nc.channelId = ch.id\n LEFT JOIN tree_nodes tn ON cn.id = tn.contentId\n LEFT JOIN trees t ON tn.treeId = t.id\n WHERE (cn.deletedAt IS NULL OR cn.deletedAt = '')\n AND (cn.status = 'draft' OR cn.hasUnpublishedChanges = 1)\n GROUP BY cn.id\n ORDER BY cn.updatedAt DESC\n ").all(), f = (Array.isArray(d) ? d : d?.results || []).map((e) => ({
25768
+ })), d = await t.prepare("\n WITH pending_drafts AS (\n SELECT id, title, slug, contentType, isHidden, status, publishedAt, hasUnpublishedChanges, updatedAt\n FROM content_nodes\n WHERE deletedAt IS NULL\n AND (status = 'draft' OR hasUnpublishedChanges = 1)\n ORDER BY updatedAt DESC\n LIMIT 100\n )\n SELECT \n pd.*,\n GROUP_CONCAT(DISTINCT ch.label) as channelLabels,\n GROUP_CONCAT(DISTINCT t.label) as treeLabels\n FROM pending_drafts pd\n LEFT JOIN node_channels nc ON pd.id = nc.nodeId\n LEFT JOIN channels ch ON nc.channelId = ch.id\n LEFT JOIN tree_nodes tn ON pd.id = tn.contentId\n LEFT JOIN trees t ON tn.treeId = t.id\n GROUP BY pd.id\n ORDER BY pd.updatedAt DESC\n ").all(), f = (Array.isArray(d) ? d : d?.results || []).map((e) => ({
25693
25769
  id: e.id,
25694
25770
  title: e.title,
25695
25771
  slug: e.slug,
@@ -25729,8 +25805,8 @@ rS.get("/", async (e) => {
25729
25805
  });
25730
25806
  //#endregion
25731
25807
  //#region server/routes/admin/assets.ts
25732
- var iS = new e();
25733
- async function aS(e, t, n = []) {
25808
+ var aS = new e();
25809
+ async function oS(e, t, n = []) {
25734
25810
  let r = e.prepare(t);
25735
25811
  if (typeof r.bind == "function") {
25736
25812
  let e = await r.bind(...n).all();
@@ -25742,16 +25818,16 @@ async function aS(e, t, n = []) {
25742
25818
  }
25743
25819
  return [];
25744
25820
  }
25745
- async function oS(e, t, n = []) {
25821
+ async function sS(e, t, n = []) {
25746
25822
  let r = e.prepare(t);
25747
25823
  if (typeof r.bind == "function") return await r.bind(...n).run();
25748
25824
  if (typeof r.run == "function") return await r.run(...n);
25749
25825
  }
25750
- function sS(e, t, n) {
25826
+ function cS(e, t, n) {
25751
25827
  let r = e || (t ? `/media/${t}` : "");
25752
25828
  return r && n && r.startsWith(`https://${n}/`) && !r.includes("/media/") && (r = r.replace(`https://${n}/`, `https://${n}/media/`)), r;
25753
25829
  }
25754
- iS.get("/", async (e) => {
25830
+ aS.get("/", async (e) => {
25755
25831
  try {
25756
25832
  let t = wb(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 = {
25757
25833
  createdAt: "a.createdAt",
@@ -25761,7 +25837,7 @@ iS.get("/", async (e) => {
25761
25837
  sizeBytes: "a.sizeBytes"
25762
25838
  }[o] || "a.createdAt", h = s.toUpperCase() === "ASC" ? "ASC" : "DESC", g = [], _ = ["(a.isSystemVariant = 0 OR a.isSystemVariant IS NULL)", u === "true" || u === "1" ? "(a.deletedAt IS NOT NULL AND a.deletedAt != '')" : "(a.deletedAt IS NULL OR a.deletedAt = '')"];
25763
25839
  if (c) {
25764
- let e = await aS(t, "SELECT a.id, a.filename, a.isSystemVariant FROM node_assets na JOIN assets a ON na.assetId = a.id WHERE na.nodeId = ?", [Number(c)]);
25840
+ let e = await oS(t, "SELECT a.id, a.filename, a.isSystemVariant FROM node_assets na JOIN assets a ON na.assetId = a.id WHERE na.nodeId = ?", [Number(c)]);
25765
25841
  if (e.length === 0) _.push("1 = 0");
25766
25842
  else {
25767
25843
  let t = e.map((e) => e.isSystemVariant ? `(a.id = '${e.id}' OR a.id IN (SELECT parentAssetId FROM assets WHERE id = '${e.id}'))` : `a.id = '${e.id}'`).join(" OR ");
@@ -25775,10 +25851,10 @@ iS.get("/", async (e) => {
25775
25851
  n && n.trim() !== "" && (_.push("a.filename LIKE ?"), g.push(`%${n.trim()}%`)), r && r !== "all" && (r === "image" ? (_.push("a.mimeType LIKE ?"), g.push("image/%")) : r === "document" ? (_.push("(a.mimeType LIKE ? OR a.mimeType LIKE ? OR a.mimeType LIKE ?)"), g.push("application/pdf%", "application/msword%", "application/vnd%")) : r === "video" && (_.push("(a.mimeType LIKE ? OR a.mimeType LIKE ?)"), g.push("video/%", "audio/%")));
25776
25852
  let v = `SELECT a.id, a.filename, a.mimeType, a.sizeBytes, a.cdnUrl, a.storageKeyPrivate, a.createdAt, a.updatedAt, a.deletedAt, a.dataJson FROM assets a ${` WHERE ${_.join(" AND ")}`} ORDER BY ${m} ${h} LIMIT ? OFFSET ?`;
25777
25853
  g.push(f, p);
25778
- let y = await aS(t, v, g), b = y.map((e) => e.id), x = /* @__PURE__ */ new Map(), S = /* @__PURE__ */ new Map();
25854
+ let y = await oS(t, v, g), b = y.map((e) => e.id), x = /* @__PURE__ */ new Map(), S = /* @__PURE__ */ new Map();
25779
25855
  if (b.length > 0) {
25780
25856
  let e = b.map(() => "?").join(",");
25781
- (await aS(t, `
25857
+ (await oS(t, `
25782
25858
  SELECT master.id AS assetId, COUNT(DISTINCT na.nodeId) AS count
25783
25859
  FROM assets master
25784
25860
  INNER JOIN node_assets na ON (
@@ -25786,7 +25862,7 @@ iS.get("/", async (e) => {
25786
25862
  EXISTS (SELECT 1 FROM assets crop WHERE crop.id = na.assetId AND crop.isSystemVariant = 1 AND crop.parentAssetId = master.id)
25787
25863
  )
25788
25864
  WHERE master.id IN (${e})
25789
- GROUP BY master.id`, b)).forEach((e) => x.set(String(e.assetId), e.count || 0)), (await aS(t, `
25865
+ GROUP BY master.id`, b)).forEach((e) => x.set(String(e.assetId), e.count || 0)), (await oS(t, `
25790
25866
  SELECT parentAssetId, COUNT(id) AS count
25791
25867
  FROM assets
25792
25868
  WHERE isSystemVariant = 1 AND parentAssetId IN (${e})
@@ -25804,7 +25880,7 @@ iS.get("/", async (e) => {
25804
25880
  ...JSON.parse(t.dataJson || "{}")
25805
25881
  };
25806
25882
  } catch {}
25807
- let r = sS(t.cdnUrl, t.storageKeyPrivate, e.env?.CDN_DOMAIN);
25883
+ let r = cS(t.cdnUrl, t.storageKeyPrivate, e.env?.CDN_DOMAIN);
25808
25884
  return {
25809
25885
  id: t.id,
25810
25886
  filename: t.filename || "Untitled Asset",
@@ -25829,7 +25905,7 @@ iS.get("/", async (e) => {
25829
25905
  details: t.message || String(t)
25830
25906
  }, 500);
25831
25907
  }
25832
- }), iS.post("/upload", async (e) => {
25908
+ }), aS.post("/upload", async (e) => {
25833
25909
  try {
25834
25910
  let t = wb(e), { storage: n } = ix(e.env), r = await e.req.parseBody(), i = r.file, a = r.isVariant === "true" || r.isVariant === "1" || r.temporary === "true", o = r.replaceAssetId, s = typeof o == "string" && o.trim().length > 0 ? o.trim() : null, c = r.parentAssetId || r.parentAsset, l = typeof c == "string" && c.trim().length > 0 ? c.trim() : null;
25835
25911
  if (!i || !(i instanceof File)) return e.json({ error: "No file uploaded" }, 400);
@@ -25845,13 +25921,13 @@ iS.get("/", async (e) => {
25845
25921
  let p = crypto.randomUUID().replace(/-/g, "").slice(0, 12), m = (/* @__PURE__ */ new Date()).toISOString().slice(0, 7).replace("-", "/"), h = a || i.name.startsWith("crop_"), g = h ? `kama/cache/${m}/${p}` : `kama/uploads/${m}/${p}`, _ = await n.upload(i, g), v = typeof _ == "string" ? _ : _?.key || _?.storageKeyPrivate || _?.storageKey || `${g}/${p}_${i.name}`;
25846
25922
  if (!v) throw Error("Storage provider failed to return a valid storage key");
25847
25923
  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;
25848
- T && (await aS(t, "SELECT id FROM users WHERE id = ?", [T])).length === 0 && (T = null);
25924
+ T && (await oS(t, "SELECT id FROM users WHERE id = ?", [T])).length === 0 && (T = null);
25849
25925
  let ee = new mx(e.env);
25850
25926
  if (s) {
25851
- let r = await aS(t, "SELECT storageKeyPrivate, isSystemVariant, parentAssetId FROM assets WHERE id = ?", [s]);
25927
+ let r = await oS(t, "SELECT storageKeyPrivate, isSystemVariant, parentAssetId FROM assets WHERE id = ?", [s]);
25852
25928
  if (r.length > 0) {
25853
25929
  let a = r[0];
25854
- if (await oS(t, "UPDATE assets SET filename = ?, mimeType = ?, sizeBytes = ?, storageKeyPrivate = ?, cdnUrl = ?, updatedAt = CURRENT_TIMESTAMP WHERE id = ?", [
25930
+ if (await sS(t, "UPDATE assets SET filename = ?, mimeType = ?, sizeBytes = ?, storageKeyPrivate = ?, cdnUrl = ?, updatedAt = CURRENT_TIMESTAMP WHERE id = ?", [
25855
25931
  i.name,
25856
25932
  S,
25857
25933
  C,
@@ -25880,7 +25956,7 @@ iS.get("/", async (e) => {
25880
25956
  }
25881
25957
  }
25882
25958
  let E = `ast_${p}`, D = +!!h;
25883
- await oS(t, "INSERT INTO assets (id, filename, mimeType, sizeBytes, storageKeyPrivate, cdnUrl, createdById, isSystemVariant, parentAssetId, cropCoordinatesJson) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", [
25959
+ await sS(t, "INSERT INTO assets (id, filename, mimeType, sizeBytes, storageKeyPrivate, cdnUrl, createdById, isSystemVariant, parentAssetId, cropCoordinatesJson) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", [
25884
25960
  E,
25885
25961
  i.name,
25886
25962
  S,
@@ -25892,15 +25968,15 @@ iS.get("/", async (e) => {
25892
25968
  l,
25893
25969
  d
25894
25970
  ]);
25895
- let O = x;
25971
+ let te = x;
25896
25972
  if (l) {
25897
- let n = await aS(t, "SELECT cdnUrl, storageKeyPrivate FROM assets WHERE id = ?", [l]);
25898
- n.length > 0 && (O = sS(n[0].cdnUrl, n[0].storageKeyPrivate, y)), ee.purgeAsset(e, t, l);
25973
+ let n = await oS(t, "SELECT cdnUrl, storageKeyPrivate FROM assets WHERE id = ?", [l]);
25974
+ n.length > 0 && (te = cS(n[0].cdnUrl, n[0].storageKeyPrivate, y)), ee.purgeAsset(e, t, l);
25899
25975
  }
25900
25976
  return e.json({
25901
25977
  id: E,
25902
25978
  url: x,
25903
- originalUrl: O,
25979
+ originalUrl: te,
25904
25980
  parentAssetId: l,
25905
25981
  cropCoordinates: f,
25906
25982
  filename: i.name,
@@ -25914,11 +25990,11 @@ iS.get("/", async (e) => {
25914
25990
  details: t.message || String(t)
25915
25991
  }, 500);
25916
25992
  }
25917
- }), iS.get("/:id/details", async (e) => {
25993
+ }), aS.get("/:id/details", async (e) => {
25918
25994
  try {
25919
- let t = wb(e), n = e.req.param("id"), r = await aS(t, "SELECT * FROM assets WHERE id = ?", [n]);
25995
+ let t = wb(e), n = e.req.param("id"), r = await oS(t, "SELECT * FROM assets WHERE id = ?", [n]);
25920
25996
  if (!r || r.length === 0) return e.json({ error: "Asset not found" }, 404);
25921
- let i = r[0], a = await aS(t, "\n SELECT DISTINCT cn.id, cn.title, cn.contentType, cn.slug, na.fieldKey, na.assetId \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 na.assetId = ? OR (crop.isSystemVariant = 1 AND crop.parentAssetId = ?)\n ", [n, n]), o = await aS(t, "\n SELECT id, filename, mimeType, sizeBytes, cdnUrl, storageKeyPrivate, parentAssetId, cropCoordinatesJson, createdAt, updatedAt \n FROM assets \n WHERE isSystemVariant = 1 AND parentAssetId = ? \n ORDER BY createdAt DESC\n ", [n]), s = {
25997
+ let i = r[0], a = await oS(t, "\n SELECT DISTINCT cn.id, cn.title, cn.contentType, cn.slug, na.fieldKey, na.assetId \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 na.assetId = ? OR (crop.isSystemVariant = 1 AND crop.parentAssetId = ?)\n ", [n, n]), o = await oS(t, "\n SELECT id, filename, mimeType, sizeBytes, cdnUrl, storageKeyPrivate, parentAssetId, cropCoordinatesJson, createdAt, updatedAt \n FROM assets \n WHERE isSystemVariant = 1 AND parentAssetId = ? \n ORDER BY createdAt DESC\n ", [n]), s = {
25922
25998
  title: "",
25923
25999
  alt: "",
25924
26000
  description: ""
@@ -25929,7 +26005,7 @@ iS.get("/", async (e) => {
25929
26005
  ...JSON.parse(i.dataJson || "{}")
25930
26006
  };
25931
26007
  } catch {}
25932
- let c = i.updatedAt ? new Date(i.updatedAt).getTime() : Date.now(), l = `${sS(i.cdnUrl, i.storageKeyPrivate, e.env?.CDN_DOMAIN)}?v=${c}`;
26008
+ let c = i.updatedAt ? new Date(i.updatedAt).getTime() : Date.now(), l = `${cS(i.cdnUrl, i.storageKeyPrivate, e.env?.CDN_DOMAIN)}?v=${c}`;
25933
26009
  return e.json({
25934
26010
  id: i.id,
25935
26011
  filename: i.filename,
@@ -25948,7 +26024,7 @@ iS.get("/", async (e) => {
25948
26024
  if (t.cropCoordinatesJson) try {
25949
26025
  n = JSON.parse(t.cropCoordinatesJson);
25950
26026
  } catch {}
25951
- let r = t.updatedAt ? new Date(t.updatedAt).getTime() : c, a = sS(t.cdnUrl, t.storageKeyPrivate, e.env?.CDN_DOMAIN);
26027
+ let r = t.updatedAt ? new Date(t.updatedAt).getTime() : c, a = cS(t.cdnUrl, t.storageKeyPrivate, e.env?.CDN_DOMAIN);
25952
26028
  return {
25953
26029
  id: t.id,
25954
26030
  filename: t.filename,
@@ -25965,15 +26041,15 @@ iS.get("/", async (e) => {
25965
26041
  } catch {
25966
26042
  return e.json({ error: "Failed to load details" }, 500);
25967
26043
  }
25968
- }), iS.put("/:id", async (e) => {
26044
+ }), aS.put("/:id", async (e) => {
25969
26045
  try {
25970
- let t = wb(e), n = e.req.param("id"), r = await e.req.json(), i = await aS(t, "SELECT filename, dataJson FROM assets WHERE id = ?", [n]);
26046
+ let t = wb(e), n = e.req.param("id"), r = await e.req.json(), i = await oS(t, "SELECT filename, dataJson FROM assets WHERE id = ?", [n]);
25971
26047
  if (!i || i.length === 0) return e.json({ error: "Asset not found" }, 404);
25972
26048
  let a = i[0], o = {};
25973
26049
  try {
25974
26050
  o = JSON.parse(a.dataJson || "{}");
25975
26051
  } catch {}
25976
- 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 oS(t, "UPDATE assets SET filename = ?, dataJson = ?, updatedAt = CURRENT_TIMESTAMP WHERE id = ?", [
26052
+ 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 sS(t, "UPDATE assets SET filename = ?, dataJson = ?, updatedAt = CURRENT_TIMESTAMP WHERE id = ?", [
25977
26053
  r.filename === void 0 ? a.filename : r.filename,
25978
26054
  JSON.stringify(o),
25979
26055
  n
@@ -25981,10 +26057,10 @@ iS.get("/", async (e) => {
25981
26057
  } catch {
25982
26058
  return e.json({ error: "Failed to update asset" }, 500);
25983
26059
  }
25984
- }), iS.delete("/:id", async (e) => {
26060
+ }), aS.delete("/:id", async (e) => {
25985
26061
  try {
25986
- let t = wb(e), n = e.req.param("id"), r = (await aS(t, "SELECT id, filename, isSystemVariant FROM assets WHERE id = ?", [n]))[0];
25987
- return r ? (new mx(e.env).purgeAsset(e, t, n), r.isSystemVariant ? await oS(t, "UPDATE assets SET deletedAt = CURRENT_TIMESTAMP WHERE id = ?", [n]) : await oS(t, "UPDATE assets SET deletedAt = CURRENT_TIMESTAMP WHERE id = ? OR (isSystemVariant = 1 AND parentAssetId = ?)", [n, n]), e.json({
26062
+ let t = wb(e), n = e.req.param("id"), r = (await oS(t, "SELECT id, filename, isSystemVariant FROM assets WHERE id = ?", [n]))[0];
26063
+ return r ? (new mx(e.env).purgeAsset(e, t, n), r.isSystemVariant ? await sS(t, "UPDATE assets SET deletedAt = CURRENT_TIMESTAMP WHERE id = ?", [n]) : await sS(t, "UPDATE assets SET deletedAt = CURRENT_TIMESTAMP WHERE id = ? OR (isSystemVariant = 1 AND parentAssetId = ?)", [n, n]), e.json({
25988
26064
  success: !0,
25989
26065
  id: n,
25990
26066
  trashed: !0
@@ -25995,10 +26071,10 @@ iS.get("/", async (e) => {
25995
26071
  details: t.message || String(t)
25996
26072
  }, 500);
25997
26073
  }
25998
- }), iS.post("/restore", async (e) => {
26074
+ }), aS.post("/restore", async (e) => {
25999
26075
  try {
26000
26076
  let t = wb(e), n = await e.req.json(), r = n.id || n.assetId;
26001
- return r ? (await aS(t, "SELECT id, filename FROM assets WHERE id = ?", [r]))[0] ? (await oS(t, "UPDATE assets SET deletedAt = NULL WHERE id = ? OR (isSystemVariant = 1 AND parentAssetId = ?)", [r, r]), new mx(e.env).purgeAsset(e, t, r), e.json({
26077
+ return r ? (await oS(t, "SELECT id, filename FROM assets WHERE id = ?", [r]))[0] ? (await sS(t, "UPDATE assets SET deletedAt = NULL WHERE id = ? OR (isSystemVariant = 1 AND parentAssetId = ?)", [r, r]), new mx(e.env).purgeAsset(e, t, r), e.json({
26002
26078
  success: !0,
26003
26079
  id: r,
26004
26080
  restored: !0
@@ -26009,13 +26085,13 @@ iS.get("/", async (e) => {
26009
26085
  details: t.message
26010
26086
  }, 500);
26011
26087
  }
26012
- }), iS.delete("/purge/:id", async (e) => {
26088
+ }), aS.delete("/purge/:id", async (e) => {
26013
26089
  try {
26014
- let t = wb(e), { storage: n } = ix(e.env), r = e.req.param("id"), i = (await aS(t, "SELECT id, filename, storageKeyPrivate, isSystemVariant FROM assets WHERE id = ?", [r]))[0];
26090
+ let t = wb(e), { storage: n } = ix(e.env), r = e.req.param("id"), i = (await oS(t, "SELECT id, filename, storageKeyPrivate, isSystemVariant FROM assets WHERE id = ?", [r]))[0];
26015
26091
  if (!i) return e.json({ error: "Asset not found" }, 404);
26016
26092
  new mx(e.env).purgeAsset(e, t, r);
26017
26093
  let a = [i];
26018
- i.isSystemVariant || (a = [i, ...await aS(t, "SELECT id, storageKeyPrivate FROM assets WHERE isSystemVariant = 1 AND parentAssetId = ?", [r])]);
26094
+ i.isSystemVariant || (a = [i, ...await oS(t, "SELECT id, storageKeyPrivate FROM assets WHERE isSystemVariant = 1 AND parentAssetId = ?", [r])]);
26019
26095
  let o = a.map((e) => e.id);
26020
26096
  if (typeof n.delete == "function") {
26021
26097
  for (let e of a) if (e.storageKeyPrivate) try {
@@ -26025,7 +26101,7 @@ iS.get("/", async (e) => {
26025
26101
  }
26026
26102
  }
26027
26103
  let s = o.map(() => "?").join(",");
26028
- return await oS(t, `DELETE FROM node_assets WHERE assetId IN (${s})`, o), await oS(t, `DELETE FROM assets WHERE id IN (${s})`, o), e.json({
26104
+ return await sS(t, `DELETE FROM node_assets WHERE assetId IN (${s})`, o), await sS(t, `DELETE FROM assets WHERE id IN (${s})`, o), e.json({
26029
26105
  success: !0,
26030
26106
  id: r,
26031
26107
  purged: !0,
@@ -26041,8 +26117,8 @@ iS.get("/", async (e) => {
26041
26117
  });
26042
26118
  //#endregion
26043
26119
  //#region server/routes/public/node.ts
26044
- var cS = new $y();
26045
- function lS() {
26120
+ var lS = new $y();
26121
+ function uS() {
26046
26122
  return {
26047
26123
  fullPath: /* @__PURE__ */ new Map(),
26048
26124
  treeEdges: /* @__PURE__ */ new Map(),
@@ -26050,7 +26126,7 @@ function lS() {
26050
26126
  assetUrls: /* @__PURE__ */ new Map()
26051
26127
  };
26052
26128
  }
26053
- function uS(e, t, n = []) {
26129
+ function dS(e, t, n = []) {
26054
26130
  let r = Date.now();
26055
26131
  if (e && String(e).trim() !== "") {
26056
26132
  let t = Date.parse(e);
@@ -26061,7 +26137,7 @@ function uS(e, t, n = []) {
26061
26137
  !isNaN(e) && e > r && n.push(e);
26062
26138
  }
26063
26139
  }
26064
- function dS(e, t) {
26140
+ function fS(e, t) {
26065
26141
  let n = Date.now();
26066
26142
  if (e && String(e).trim() !== "") {
26067
26143
  let t = Date.parse(e);
@@ -26073,13 +26149,15 @@ function dS(e, t) {
26073
26149
  }
26074
26150
  return !0;
26075
26151
  }
26076
- async function fS(e, t, n, r, i) {
26152
+ async function pS(e, t, n, r, i) {
26077
26153
  let a = t.filter((e) => e.componentId === "content-feed" || e.componentId === "article-list" || e.componentId === "nodeList" || e.componentId === "node-list");
26078
26154
  await Promise.all(a.map(async (t) => {
26079
26155
  let a = t.data || {}, o = a.nodeType || ["article"], s = (Array.isArray(o) ? o : String(o).split(",")).map((e) => String(e).trim()).filter(Boolean), c = Number(a.limit) || 12, l = Number(a.offset) || 0, u = a.sortBy || "updatedAt", d = new URLSearchParams();
26080
26156
  d.set("nodeType", s.join(",")), d.set("limit", c.toString()), d.set("offset", (l + c).toString()), d.set("sortBy", u), n && n !== "all" && d.set("channelId", String(n));
26081
- let f = `FROM content_nodes WHERE contentType IN (${s.map(() => "?").join(",")}) AND isHidden = 0 AND (status = 'published' OR status IS NULL)`, p = [...s];
26082
- n && n !== "all" && (f += " AND id IN (SELECT nodeId FROM node_channels WHERE channelId = ?)", p.push(Number(n) || n));
26157
+ let f = `FROM content_nodes WHERE contentType IN (${s.map(() => "?").join(",")}) AND isHidden = 0 AND IFNULL(status, 'published') = 'published'`, p = [...s];
26158
+ n && n !== "all" && (f += " AND EXISTS (SELECT 1 FROM node_channels nc WHERE nc.nodeId = content_nodes.id AND nc.channelId = ?)", p.push(Number(n) || n));
26159
+ let m = (/* @__PURE__ */ new Date()).toISOString();
26160
+ f += " AND IFNULL(json_extract(dataJson, '$.startShowingAt'), '') <= ?", p.push(m), f += " AND IFNULL(json_extract(dataJson, '$.stopShowingAt'), '9999-12-31') >= ?", p.push(m);
26083
26161
  for (let e of [
26084
26162
  "authors",
26085
26163
  "categories",
@@ -26099,18 +26177,18 @@ async function fS(e, t, n, r, i) {
26099
26177
  f += e === "authors" ? ` AND EXISTS (SELECT 1 FROM node_relations nr WHERE nr.sourceNodeId = content_nodes.id AND nr.fieldKey = ? AND nr.targetNodeId IN (${n}))` : ` AND EXISTS (SELECT 1 FROM node_terms nt INNER JOIN taxonomy_terms tt ON nt.termId = tt.id WHERE nt.nodeId = content_nodes.id AND tt.taxonomy = ? AND tt.key IN (${n}))`, p.push(e, ...t);
26100
26178
  }
26101
26179
  }
26102
- let m = "ORDER BY updatedAt DESC";
26103
- u === "published_desc" || u === "createdAt" ? m = "ORDER BY createdAt DESC" : u === "title_asc" && (m = "ORDER BY LOWER(title) ASC");
26104
- let h = `SELECT id, title, slug, language, dataJson, createdAt, updatedAt ${f} ${m} LIMIT ? OFFSET ?`;
26180
+ let h = "ORDER BY updatedAt DESC";
26181
+ u === "published_desc" || u === "createdAt" ? h = "ORDER BY createdAt DESC" : u === "title_asc" && (h = "ORDER BY LOWER(title) ASC");
26182
+ let g = `SELECT id, title, slug, language, dataJson, createdAt, updatedAt ${f} ${h} LIMIT ? OFFSET ?`;
26105
26183
  p.push(c, l);
26106
26184
  try {
26107
- let n = await e.prepare(h).all(...p), a = Array.isArray(n) ? n : n?.results || [];
26108
- t.data.initialItems = a.map((e) => {
26185
+ let n = await e.prepare(g).all(...p), o = Array.isArray(n) ? n : n?.results || [];
26186
+ t.data.initialItems = o.map((e) => {
26109
26187
  let t = {};
26110
26188
  if (e.dataJson) try {
26111
26189
  t = typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson;
26112
26190
  } catch {}
26113
- return i && uS(t.startShowingAt, t.stopShowingAt, i), dS(t.startShowingAt, t.stopShowingAt) ? {
26191
+ return i && dS(t.startShowingAt, t.stopShowingAt, i), {
26114
26192
  id: e.id,
26115
26193
  title: e.title,
26116
26194
  slug: e.slug,
@@ -26120,14 +26198,14 @@ async function fS(e, t, n, r, i) {
26120
26198
  excerpt: t.excerpt || "",
26121
26199
  image: t.image || t.coverImage || null,
26122
26200
  author: t.author || null
26123
- } : null;
26124
- }).filter(Boolean), t.data.initialItems.length === c ? t.data.loadMoreUrl = `/api/v1/nodes?${d.toString()}` : t.data.loadMoreUrl = null;
26201
+ };
26202
+ }), a.disablePagination !== !0 && a.disablePagination !== "1" && o.length === c ? t.data.loadMoreUrl = `/api/v1/nodes?${d.toString()}` : t.data.loadMoreUrl = null;
26125
26203
  } catch (e) {
26126
26204
  console.error("[CMS Hydration] Failed to hydrate content feed block", e), t.data.initialItems = [], t.data.loadMoreUrl = null;
26127
26205
  }
26128
26206
  }));
26129
26207
  }
26130
- async function pS(e, t, n, r, i, a = !1, o, s) {
26208
+ async function mS(e, t, n, r, i, a = !1, o, s) {
26131
26209
  if (!t) return { blocks: [] };
26132
26210
  let c = await e.prepare("\n WITH RECURSIVE ancestor_path(contentId, title, slug, parentId, level) AS (\n SELECT 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.contentId = ? AND t.treeId = ?\n UNION ALL\n SELECT 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.contentId = ap.parentId AND t.treeId = ?\n )\n SELECT * FROM ancestor_path ORDER BY level ASC\n ").all(t, n, n), l = Array.isArray(c) ? c : c?.results || [];
26133
26211
  if (!l || l.length === 0) return { blocks: [] };
@@ -26163,11 +26241,11 @@ async function pS(e, t, n, r, i, a = !1, o, s) {
26163
26241
  try {
26164
26242
  n = (typeof t.dataJson == "string" ? JSON.parse(t.dataJson) : t.dataJson) || {};
26165
26243
  } catch {}
26166
- s && uS(n.startShowingAt, n.stopShowingAt, s);
26167
- let o = n.hidden === !0 || n.hidden === 1 || n.hidden === "1" || n.hidden === "true", c = dS(n.startShowingAt, n.stopShowingAt);
26244
+ s && dS(n.startShowingAt, n.stopShowingAt, s);
26245
+ let o = n.hidden === !0 || n.hidden === 1 || n.hidden === "1" || n.hidden === "true", c = fS(n.startShowingAt, n.stopShowingAt);
26168
26246
  if (!a && (o || !c)) return null;
26169
- let l = t.elementType || t.componentId || "text-block", u = i.blocks?.[l]?.fields || i.elements?.[l]?.fields || i.components?.[l]?.fields || {}, d = String(n.blockId || n._instanceId || n.id || t.blockId || t.id), f = mS(n, u);
26170
- return f = await fx(e, f), f = hS(f), f.blockId = d, {
26247
+ let l = t.elementType || t.componentId || "text-block", u = i.blocks?.[l]?.fields || i.elements?.[l]?.fields || i.components?.[l]?.fields || {}, d = String(n.blockId || n._instanceId || n.id || t.blockId || t.id), f = hS(n, u);
26248
+ return f = await fx(e, f), f = gS(f), f.blockId = d, {
26171
26249
  region: t.region || r,
26172
26250
  block: {
26173
26251
  instanceId: t.id,
@@ -26187,7 +26265,7 @@ async function pS(e, t, n, r, i, a = !1, o, s) {
26187
26265
  }
26188
26266
  return { blocks: [] };
26189
26267
  }
26190
- function mS(e, t = {}) {
26268
+ function hS(e, t = {}) {
26191
26269
  let n = {};
26192
26270
  for (let [r, i] of Object.entries(e)) r.endsWith("_meta") || [
26193
26271
  "disabledRegions",
@@ -26203,14 +26281,14 @@ function mS(e, t = {}) {
26203
26281
  ].includes(r) || r.startsWith("_") || (!t[r] || t[r].public !== !1) && (n[r] = i);
26204
26282
  return n;
26205
26283
  }
26206
- function hS(e) {
26207
- if (Array.isArray(e)) return e.map(hS);
26284
+ function gS(e) {
26285
+ if (Array.isArray(e)) return e.map(gS);
26208
26286
  if (!e || typeof e != "object") return e;
26209
26287
  if (typeof e.id == "string" && e.id.startsWith("ast_") && typeof e.url == "string") {
26210
26288
  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 ? {
26211
26289
  ...t,
26212
26290
  ...t.crops?.[r] || {}
26213
- } : t, a = Object.fromEntries(Object.entries(n).filter(([, t]) => t?.id !== e.id).map(([t, n]) => [t, hS({
26291
+ } : t, a = Object.fromEntries(Object.entries(n).filter(([, t]) => t?.id !== e.id).map(([t, n]) => [t, gS({
26214
26292
  ...n,
26215
26293
  title: n?.title ?? e.title ?? "",
26216
26294
  alt: n?.alt ?? e.alt ?? "",
@@ -26224,9 +26302,9 @@ function hS(e) {
26224
26302
  ...Object.keys(a).length > 0 ? { variants: a } : {}
26225
26303
  };
26226
26304
  }
26227
- return Object.fromEntries(Object.entries(e).map(([e, t]) => [e, hS(t)]));
26305
+ return Object.fromEntries(Object.entries(e).map(([e, t]) => [e, gS(t)]));
26228
26306
  }
26229
- async function gS(e, t, n, r) {
26307
+ async function _S(e, t, n, r) {
26230
26308
  if (typeof t == "string") {
26231
26309
  if (!t.includes("#node:") && !t.includes("data-node-id") && !t.includes("#asset:") && !t.includes("data-asset-id")) return t;
26232
26310
  let r = (e, t) => {
@@ -26259,25 +26337,25 @@ async function gS(e, t, n, r) {
26259
26337
  return /href\s*=\s*["'][^"']*["']/i.test(d) ? d = d.replace(/href\s*=\s*["'][^"']*["']/i, `href="${u}"`) : d += ` href="${u}"`, `<a ${d}>`;
26260
26338
  });
26261
26339
  }
26262
- if (Array.isArray(t)) return Promise.all(t.map((t) => gS(e, t, n, r)));
26340
+ if (Array.isArray(t)) return Promise.all(t.map((t) => _S(e, t, n, r)));
26263
26341
  if (t && typeof t == "object") {
26264
26342
  if (typeof t.href == "string" && (t.href.startsWith("#node:") || t.href.startsWith("#asset:"))) return {
26265
26343
  ...t,
26266
- href: await _S(e, t, n, r)
26344
+ href: await vS(e, t, n, r)
26267
26345
  };
26268
- let i = await Promise.all(Object.entries(t).map(async ([t, i]) => [t, await gS(e, i, n, r)]));
26346
+ let i = await Promise.all(Object.entries(t).map(async ([t, i]) => [t, await _S(e, i, n, r)]));
26269
26347
  return Object.fromEntries(i);
26270
26348
  }
26271
26349
  return t;
26272
26350
  }
26273
- async function _S(e, t, n, r) {
26351
+ async function vS(e, t, n, r) {
26274
26352
  let i = t.href.match(/^#node:(.+)$/), a = t.href.match(/^#asset:(.+)$/);
26275
- if (a) return vS(e, a[1], r);
26353
+ if (a) return yS(e, a[1], r);
26276
26354
  if (!i) return t.href;
26277
26355
  let o = i[1];
26278
26356
  return (await e.prepare("SELECT path FROM node_routes WHERE nodeId = ? AND channelId = ? AND isCanonical = 1 LIMIT 1").get(Number(o), n))?.path || "#";
26279
26357
  }
26280
- async function vS(e, t, n) {
26358
+ async function yS(e, t, n) {
26281
26359
  let r = String(t), i = n.assetUrls.get(r);
26282
26360
  if (i) return i;
26283
26361
  let a = (async () => {
@@ -26286,7 +26364,7 @@ async function vS(e, t, n) {
26286
26364
  })();
26287
26365
  return n.assetUrls.set(r, a), a;
26288
26366
  }
26289
- function yS(e) {
26367
+ function bS(e) {
26290
26368
  let t = e.socialImage;
26291
26369
  if (!t || typeof t != "object") return null;
26292
26370
  let n = (e, t) => {
@@ -26317,7 +26395,7 @@ function yS(e) {
26317
26395
  ])
26318
26396
  };
26319
26397
  }
26320
- async function bS(e, t, n, r, i) {
26398
+ async function xS(e, t, n, r, i) {
26321
26399
  let a = {}, o = null;
26322
26400
  if (t) {
26323
26401
  let i = await e.prepare("\n WITH RECURSIVE ancestor_path(contentId, title, slug, parentId, level) AS (\n SELECT 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.contentId = ? AND t.treeId = ?\n UNION ALL\n SELECT 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.contentId = ap.parentId AND t.treeId = ?\n )\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, n, n), s = Array.isArray(i) ? i : i?.results || [], c = /* @__PURE__ */ new Set([
@@ -26355,20 +26433,20 @@ async function bS(e, t, n, r, i) {
26355
26433
  inheritedFields: a
26356
26434
  };
26357
26435
  }
26358
- function xS(e) {
26436
+ function SS(e) {
26359
26437
  let t = Number(e?.env?.CMS_NODE_CACHE_TTL);
26360
26438
  return Number.isFinite(t) && t >= 60 ? Math.floor(t) : 300;
26361
26439
  }
26362
- async function SS(e, t, n, r) {
26440
+ async function CS(e, t, n, r) {
26363
26441
  try {
26364
26442
  await e.set(t, n, r);
26365
26443
  } catch (e) {
26366
26444
  console.warn("[CMS Cache] Failed to write node response to cache:", e);
26367
26445
  }
26368
26446
  }
26369
- async function CS(e) {
26447
+ async function wS(e) {
26370
26448
  try {
26371
- let t = e.get("db"), n = lS(), r = [], i = new URL(e.req.url), a = i.searchParams.get("channelId") || i.searchParams.get("channel"), o = i.searchParams.get("lang"), s = i.searchParams.get("preview") === "true", c = i.searchParams.get("revisionId"), l = i.searchParams.get("treeId"), u = i.pathname, d = "";
26449
+ let t = e.get("db"), n = uS(), r = [], i = new URL(e.req.url), a = i.searchParams.get("channelId") || i.searchParams.get("channel"), o = i.searchParams.get("lang"), s = i.searchParams.get("preview") === "true", c = i.searchParams.get("revisionId"), l = i.searchParams.get("treeId"), u = i.pathname, d = "";
26372
26450
  u.includes("/node/") ? d = u.substring(u.indexOf("/node/") + 6) : u.endsWith("/node") && (d = "");
26373
26451
  try {
26374
26452
  d = decodeURIComponent(d);
@@ -26418,9 +26496,9 @@ async function CS(e) {
26418
26496
  e.defaultLanguage ? w = String(e.defaultLanguage).trim() : e.language && (w = String(e.language).trim());
26419
26497
  } catch {}
26420
26498
  }
26421
- let T = y.language?.trim() || null, ee = C || w || o?.trim() || null, E = T || ee || null, D = `node:${g || _}:${E || "default"}:${d}`, O = e.req.header("x-bypass-cache") === "true" || !!c, te = $b(e), k = xS(e);
26422
- if (!s && !O) {
26423
- let t = await te.get(D);
26499
+ let T = y.language?.trim() || null, ee = C || w || o?.trim() || null, E = T || ee || null, D = `node:${g || _}:${E || "default"}:${d}`, te = e.req.header("x-bypass-cache") === "true" || !!c, O = $b(e), k = SS(e);
26500
+ if (!s && !te) {
26501
+ let t = await O.get(D);
26424
26502
  if (t) {
26425
26503
  e.header("X-Cache", "HIT");
26426
26504
  let n = k;
@@ -26448,14 +26526,14 @@ async function CS(e) {
26448
26526
  if (x && x.node && x.node.dataJson && (fe = x.node.dataJson), fe) try {
26449
26527
  de = typeof fe == "string" ? JSON.parse(fe) : fe;
26450
26528
  } catch {}
26451
- de.disabledRegions && (se = de.disabledRegions), ue = de.hidden === !0 || de.hidden === 1 || de.hidden === "1" || de.hidden === "true", ce = de.startShowingAt || null, le = de.stopShowingAt || null, uS(ce, le, r);
26452
- let pe = de.layoutId, me = pe && pe !== "inherit", { resolvedLayoutId: he, inheritedFields: ge } = await bS(t, A, b, s, oe), _e = me ? pe : he || ae.defaultLayout || null;
26529
+ de.disabledRegions && (se = de.disabledRegions), ue = de.hidden === !0 || de.hidden === 1 || de.hidden === "1" || de.hidden === "true", ce = de.startShowingAt || null, le = de.stopShowingAt || null, dS(ce, le, r);
26530
+ let pe = de.layoutId, me = pe && pe !== "inherit", { resolvedLayoutId: he, inheritedFields: ge } = await xS(t, A, b, s, oe), _e = me ? pe : he || ae.defaultLayout || null;
26453
26531
  for (let [e, t] of Object.entries(ge)) (de[e] === void 0 || de[e] === null || de[e] === "" || de[e] === "inherit") && t !== void 0 && (de[e] = t);
26454
- let ve = await fx(t, mS(de, oe));
26455
- ve = hS(ve), ve = await gS(t, ve, g, n), delete ve.language;
26456
- let ye = yS(ve);
26532
+ let ve = await fx(t, hS(de, oe));
26533
+ ve = gS(ve), ve = await _S(t, ve, g, n), delete ve.language;
26534
+ let ye = bS(ve);
26457
26535
  delete ve.socialImage, delete ve.fbImage, delete ve.xImage, delete ve.whatsappImage, ye && (ve.socialImages = ye), Object.assign(j, ve), j.id = y.id, j.slug = y.slug, j.title = y.title, j.path = ne, j.layoutId = _e;
26458
- let be = Number(y.isHidden) === 1 || ue, xe = !dS(ce, le), Se = y.status === "draft" || y.status === "new", Ce = y.dataJson && y.dataJson !== "{}" && y.dataJson !== "null";
26536
+ let be = Number(y.isHidden) === 1 || ue, xe = !fS(ce, le), Se = y.status === "draft" || y.status === "new", Ce = y.dataJson && y.dataJson !== "{}" && y.dataJson !== "null";
26459
26537
  if (!s && (be || xe || Se && !Ce)) return e.json({ error: "Node is hidden, offline, or has never been published." }, 404);
26460
26538
  let we = [];
26461
26539
  if (S?.treeNodeId) {
@@ -26466,8 +26544,8 @@ async function CS(e) {
26466
26544
  try {
26467
26545
  t = (typeof n == "string" ? JSON.parse(n) : n) || {};
26468
26546
  } catch {}
26469
- let i = Number(e.isHidden) === 1 || t.hidden === !0 || t.hidden === 1 || t.hidden === "1", o = dS(t.startShowingAt, t.stopShowingAt), c = (e.slug || "").replace(/^\/+|\/+$/g, "");
26470
- return uS(t.startShowingAt, t.stopShowingAt, r), !s && (i || !o) ? null : {
26547
+ let i = Number(e.isHidden) === 1 || t.hidden === !0 || t.hidden === 1 || t.hidden === "1", o = fS(t.startShowingAt, t.stopShowingAt), c = (e.slug || "").replace(/^\/+|\/+$/g, "");
26548
+ return dS(t.startShowingAt, t.stopShowingAt, r), !s && (i || !o) ? null : {
26471
26549
  treeNodeId: e.treeNodeId,
26472
26550
  id: e.id,
26473
26551
  title: e.title,
@@ -26493,11 +26571,11 @@ async function CS(e) {
26493
26571
  try {
26494
26572
  a = (typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson) || {};
26495
26573
  } catch {}
26496
- uS(a.startShowingAt, a.stopShowingAt, r);
26497
- let o = a.hidden === !0 || a.hidden === 1 || a.hidden === "1" || a.hidden === "true", c = dS(a.startShowingAt, a.stopShowingAt);
26574
+ dS(a.startShowingAt, a.stopShowingAt, r);
26575
+ let o = a.hidden === !0 || a.hidden === 1 || a.hidden === "1" || a.hidden === "true", c = fS(a.startShowingAt, a.stopShowingAt);
26498
26576
  if (!s && (o || !c)) return null;
26499
- let l = e.elementType || e.componentId || "text-block", u = re.blocks?.[l]?.fields || re.elements?.[l]?.fields || re.components?.[l]?.fields || {}, d = String(a.blockId || a._instanceId || a.id || e.blockId || e.id), f = mS(a, u);
26500
- return f = await fx(t, f), f = hS(f), f = await gS(t, f, g, n), f.blockId = d, {
26577
+ let l = e.elementType || e.componentId || "text-block", u = re.blocks?.[l]?.fields || re.elements?.[l]?.fields || re.components?.[l]?.fields || {}, d = String(a.blockId || a._instanceId || a.id || e.blockId || e.id), f = hS(a, u);
26578
+ return f = await fx(t, f), f = gS(f), f = await _S(t, f, g, n), f.blockId = d, {
26501
26579
  region: i,
26502
26580
  block: {
26503
26581
  instanceId: e.id,
@@ -26522,7 +26600,7 @@ async function CS(e) {
26522
26600
  for (let [e, i] of Object.entries(ke)) {
26523
26601
  let a = Ee[e] && Ee[e].length > 0, o = !!se[e];
26524
26602
  if (Ee[e] || (Ee[e] = [], De[e] = { isInherited: !1 }), (i?.inherit === "parent" || i?.inherit === !0 || i?.inherit === "true" || e === "header" || e === "footer") && !a && !o && A) {
26525
- let i = await pS(t, A, String(b), e, re, s, n, r);
26603
+ let i = await mS(t, A, String(b), e, re, s, n, r);
26526
26604
  if (i.blocks.length > 0 && (Ee[e] = i.blocks, De[e] = {
26527
26605
  isInherited: !0,
26528
26606
  inheritedFromId: i.inheritedFromId,
@@ -26534,7 +26612,7 @@ async function CS(e) {
26534
26612
  });
26535
26613
  }
26536
26614
  }
26537
- await Promise.all(Object.keys(Ee).map((e) => fS(t, Ee[e], g, E, r)));
26615
+ await Promise.all(Object.keys(Ee).map((e) => pS(t, Ee[e], g, E, r)));
26538
26616
  let Ae = null, je = null;
26539
26617
  if (r.length > 0) {
26540
26618
  je = Math.min(...r);
@@ -26553,10 +26631,10 @@ async function CS(e) {
26553
26631
  content: Ee,
26554
26632
  regionMeta: De
26555
26633
  };
26556
- if (!s && !O) {
26634
+ if (!s && !te) {
26557
26635
  e.header("X-Cache", "MISS");
26558
26636
  let t = Ae === null ? k : Ae;
26559
- e.header("Cache-Control", `public, max-age=${t}, s-maxage=${t}`), await SS(te, D, Me, t);
26637
+ e.header("Cache-Control", `public, max-age=${t}, s-maxage=${t}`), await CS(O, D, Me, t);
26560
26638
  } else e.header("Cache-Control", "no-cache, no-store, must-revalidate");
26561
26639
  return e.json(Me, 200);
26562
26640
  } catch (t) {
@@ -26566,17 +26644,17 @@ async function CS(e) {
26566
26644
  }, 500);
26567
26645
  }
26568
26646
  }
26569
- var wS = X({
26647
+ var TS = X({
26570
26648
  channelId: J().optional().openapi({ description: "The ID or key of the channel" }),
26571
26649
  channel: J().optional().openapi({ description: "Legacy alias for channelId" }),
26572
26650
  lang: J().optional().openapi({ description: "Requested language code" }),
26573
26651
  preview: lv(["true", "false"]).optional().openapi({ description: "Request unpublished draft data" }),
26574
26652
  revisionId: J().optional().openapi({ description: "Historical revision version to load" }),
26575
26653
  treeId: J().optional().openapi({ description: "The ID of the tree to resolve paths against" })
26576
- }), TS = X({
26654
+ }), ES = X({
26577
26655
  error: J(),
26578
26656
  details: J().optional()
26579
- }).openapi("ErrorResponse"), ES = X({
26657
+ }).openapi("ErrorResponse"), DS = X({
26580
26658
  channelId: G_([J(), c_()]),
26581
26659
  treeId: J().nullable(),
26582
26660
  language: J().nullable(),
@@ -26591,7 +26669,7 @@ var wS = X({
26591
26669
  inheritedFromId: J().optional(),
26592
26670
  inheritedFromTitle: J().optional()
26593
26671
  }))
26594
- }).openapi("NodeResponse"), DS = eb({
26672
+ }).openapi("NodeResponse"), OS = eb({
26595
26673
  method: "get",
26596
26674
  path: "/{path}",
26597
26675
  summary: "Fetch CMS Node Content",
@@ -26599,27 +26677,27 @@ var wS = X({
26599
26677
  tags: ["Public Node API"],
26600
26678
  request: {
26601
26679
  params: X({ path: J().optional().openapi({ description: "The full URL path or slug of the requested node" }) }),
26602
- query: wS
26680
+ query: TS
26603
26681
  },
26604
26682
  responses: {
26605
26683
  200: {
26606
26684
  description: "Fully hydrated CMS Node",
26607
- content: { "application/json": { schema: ES } }
26685
+ content: { "application/json": { schema: DS } }
26608
26686
  },
26609
26687
  404: {
26610
26688
  description: "Node or Channel not found",
26611
- content: { "application/json": { schema: TS } }
26689
+ content: { "application/json": { schema: ES } }
26612
26690
  },
26613
26691
  500: {
26614
26692
  description: "Server error during hydration",
26615
- content: { "application/json": { schema: TS } }
26693
+ content: { "application/json": { schema: ES } }
26616
26694
  }
26617
26695
  }
26618
26696
  });
26619
- cS.openapi(DS, CS), cS.get("*", CS);
26697
+ lS.openapi(OS, wS), lS.get("*", wS);
26620
26698
  //#endregion
26621
26699
  //#region server/routes/public/nodes.ts
26622
- var OS = new $y(), kS = X({
26700
+ var kS = new $y(), AS = X({
26623
26701
  nodeType: J().default("article").openapi({ description: "Content types (comma separated)" }),
26624
26702
  channelId: J().optional().openapi({ description: "Channel ID or key" }),
26625
26703
  limit: Ky().min(1).max(50).default(12).openapi({ description: "Number of items (max 50)" }),
@@ -26632,34 +26710,29 @@ var OS = new $y(), kS = X({
26632
26710
  authors: G_([J(), z_(J())]).optional(),
26633
26711
  categories: G_([J(), z_(J())]).optional(),
26634
26712
  tags: G_([J(), z_(J())]).optional()
26635
- }), AS = async (e) => {
26713
+ }), jS = async (e) => {
26636
26714
  try {
26637
- let t = e.get("db"), n = e.req.valid("query"), r = n.nodeType || "article", i = String(r).split(",").map((e) => e.trim()).filter(Boolean), a = `FROM content_nodes WHERE contentType IN (${i.map(() => "?").join(",")}) AND isHidden = 0 AND (status = 'published' OR status IS NULL)`, o = [...i];
26638
- n.channelId && n.channelId !== "all" && (a += " AND id IN (SELECT nodeId FROM node_channels WHERE channelId = ?)", o.push(Number(n.channelId) || n.channelId));
26639
- let s = (e, t, n = !1) => {
26715
+ let t = e.get("db"), n = e.req.valid("query"), r = n.nodeType || "article", i = String(r).split(",").map((e) => e.trim()).filter(Boolean), a = `FROM content_nodes WHERE contentType IN (${i.map(() => "?").join(",")}) AND isHidden = 0 AND IFNULL(status, 'published') = 'published'`, o = [...i];
26716
+ n.channelId && n.channelId !== "all" && (a += " AND EXISTS (SELECT 1 FROM node_channels nc WHERE nc.nodeId = content_nodes.id AND nc.channelId = ?)", o.push(Number(n.channelId) || n.channelId));
26717
+ let s = (/* @__PURE__ */ new Date()).toISOString();
26718
+ a += " AND IFNULL(json_extract(dataJson, '$.startShowingAt'), '') <= ?", o.push(s), a += " AND IFNULL(json_extract(dataJson, '$.stopShowingAt'), '9999-12-31') >= ?", o.push(s);
26719
+ let c = (e, t, n = !1) => {
26640
26720
  let r = Array.isArray(t) ? t : t.split(",").map((e) => e.trim());
26641
26721
  if (r.length === 0) return;
26642
26722
  let i = r.map(() => "?").join(",");
26643
- n ? (a += ` AND EXISTS (
26644
- SELECT 1 FROM node_relations nr
26645
- WHERE nr.sourceNodeId = content_nodes.id AND nr.fieldKey = ? AND nr.targetNodeId IN (${i})
26646
- )`, o.push(e, ...r)) : (a += ` AND EXISTS (
26647
- SELECT 1 FROM node_terms nt
26648
- INNER JOIN taxonomy_terms tt ON nt.termId = tt.id
26649
- WHERE nt.nodeId = content_nodes.id AND tt.taxonomy = ? AND tt.key IN (${i})
26650
- )`, o.push(e, ...r));
26723
+ n ? (a += ` AND EXISTS (SELECT 1 FROM node_relations nr WHERE nr.sourceNodeId = content_nodes.id AND nr.fieldKey = ? AND nr.targetNodeId IN (${i}))`, o.push(e, ...r)) : (a += ` AND EXISTS (SELECT 1 FROM node_terms nt INNER JOIN taxonomy_terms tt ON nt.termId = tt.id WHERE nt.nodeId = content_nodes.id AND tt.taxonomy = ? AND tt.key IN (${i}))`, o.push(e, ...r));
26651
26724
  };
26652
- n.authors && s("authors", n.authors, !0), n.categories && s("categories", n.categories, !1), n.tags && s("tags", n.tags, !1);
26653
- let c = "ORDER BY updatedAt DESC";
26654
- n.sortBy === "createdAt" ? c = "ORDER BY createdAt DESC" : n.sortBy === "title_asc" && (c = "ORDER BY LOWER(title) ASC");
26655
- let l = `SELECT id, title, slug, language, dataJson, createdAt, updatedAt ${a} ${c} LIMIT ? OFFSET ?`;
26725
+ n.authors && c("authors", n.authors, !0), n.categories && c("categories", n.categories, !1), n.tags && c("tags", n.tags, !1);
26726
+ let l = "ORDER BY updatedAt DESC";
26727
+ n.sortBy === "createdAt" ? l = "ORDER BY createdAt DESC" : n.sortBy === "title_asc" && (l = "ORDER BY LOWER(title) ASC");
26728
+ let u = `SELECT id, title, slug, language, dataJson, createdAt, updatedAt ${a} ${l} LIMIT ? OFFSET ?`;
26656
26729
  o.push(n.limit, n.offset);
26657
- let u = await t.prepare(l).all(...o), d = Array.isArray(u) ? u : u?.results || [], f = Date.now(), p = d.map((e) => {
26730
+ let d = await t.prepare(u).all(...o), f = Array.isArray(d) ? d : d?.results || [], p = f.map((e) => {
26658
26731
  let t = {};
26659
26732
  try {
26660
26733
  t = typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson || {};
26661
26734
  } catch {}
26662
- return t.startShowingAt && Date.parse(t.startShowingAt) > f || t.stopShowingAt && Date.parse(t.stopShowingAt) < f ? null : {
26735
+ return {
26663
26736
  id: e.id,
26664
26737
  title: e.title,
26665
26738
  slug: e.slug,
@@ -26670,22 +26743,23 @@ var OS = new $y(), kS = X({
26670
26743
  image: t.image || t.coverImage || null,
26671
26744
  author: t.author || null
26672
26745
  };
26673
- }).filter(Boolean);
26746
+ });
26674
26747
  return e.json({
26675
26748
  items: p,
26676
26749
  count: p.length,
26750
+ rawCount: f.length,
26677
26751
  limit: n.limit,
26678
26752
  offset: n.offset
26679
26753
  }, 200);
26680
26754
  } catch (t) {
26681
26755
  return console.error("[CMS API] Error fetching nodes list:", t), e.json({ error: "Failed to fetch nodes list" }, 500);
26682
26756
  }
26683
- }, jS = eb({
26757
+ }, MS = eb({
26684
26758
  method: "get",
26685
26759
  path: "/",
26686
26760
  summary: "Fetch filtered list of nodes",
26687
26761
  tags: ["Public Node API"],
26688
- request: { query: kS },
26762
+ request: { query: AS },
26689
26763
  responses: {
26690
26764
  200: {
26691
26765
  description: "List of nodes",
@@ -26694,11 +26768,11 @@ var OS = new $y(), kS = X({
26694
26768
  500: { description: "Server error" }
26695
26769
  }
26696
26770
  });
26697
- OS.openapi(jS, AS);
26771
+ kS.openapi(MS, jS);
26698
26772
  //#endregion
26699
26773
  //#region server/routes/public/tree.ts
26700
- var MS = new $y();
26701
- function NS(e, t) {
26774
+ var NS = new $y();
26775
+ function PS(e, t) {
26702
26776
  let n = /* @__PURE__ */ new Date();
26703
26777
  if (e && String(e).trim() !== "") {
26704
26778
  let t = new Date(e);
@@ -26710,22 +26784,22 @@ function NS(e, t) {
26710
26784
  }
26711
26785
  return !0;
26712
26786
  }
26713
- async function PS(e, t, n, r) {
26787
+ async function FS(e, t, n, r) {
26714
26788
  try {
26715
26789
  await e.set(t, n, r);
26716
26790
  } catch (e) {
26717
26791
  console.warn("[CMS Cache] Failed to write tree response to cache:", e);
26718
26792
  }
26719
26793
  }
26720
- var FS = X({ treeParam: J().openapi({ description: "The ID or key of the requested tree (e.g., \"main-nav\")" }) }), IS = X({
26794
+ var IS = X({ treeParam: J().openapi({ description: "The ID or key of the requested tree (e.g., \"main-nav\")" }) }), LS = X({
26721
26795
  channelId: J().optional().openapi({ description: "Channel ID to resolve context-aware routing" }),
26722
26796
  channel: J().optional().openapi({ description: "Legacy alias for channelId" }),
26723
26797
  lang: J().optional().openapi({ description: "Requested language code for tree nodes" }),
26724
26798
  preview: lv(["true", "false"]).optional().openapi({ description: "Set to true to retrieve unpublished draft data" })
26725
- }), LS = X({
26799
+ }), RS = X({
26726
26800
  error: J(),
26727
26801
  details: J().optional()
26728
- }).openapi("ErrorResponse"), RS = qv(() => X({
26802
+ }).openapi("ErrorResponse"), zS = qv(() => X({
26729
26803
  id: G_([J(), c_()]),
26730
26804
  treeNodeId: G_([J(), c_()]),
26731
26805
  parentId: G_([J(), c_()]).nullable(),
@@ -26738,40 +26812,40 @@ var FS = X({ treeParam: J().openapi({ description: "The ID or key of the request
26738
26812
  summary: J(),
26739
26813
  url: J().optional(),
26740
26814
  target: J().optional(),
26741
- children: z_(RS).optional()
26742
- })).openapi("TreeItem"), zS = X({
26815
+ children: z_(zS).optional()
26816
+ })).openapi("TreeItem"), BS = X({
26743
26817
  treeId: G_([c_(), J()]),
26744
26818
  key: J(),
26745
26819
  channelId: J(),
26746
26820
  language: J().nullable(),
26747
26821
  label: J(),
26748
- items: z_(RS)
26749
- }).catchall(k_()).openapi("TreeResponse"), BS = eb({
26822
+ items: z_(zS)
26823
+ }).catchall(k_()).openapi("TreeResponse"), VS = eb({
26750
26824
  method: "get",
26751
26825
  path: "/{treeParam}",
26752
26826
  summary: "Fetch CMS Navigation Tree",
26753
26827
  description: "Retrieves a fully hydrated, recursive navigation tree structure. Uses $O(1)$ pre-computed routing table paths.",
26754
26828
  tags: ["Public Tree API"],
26755
26829
  request: {
26756
- params: FS,
26757
- query: IS
26830
+ params: IS,
26831
+ query: LS
26758
26832
  },
26759
26833
  responses: {
26760
26834
  200: {
26761
26835
  description: "Fully hydrated CMS Tree payload",
26762
- content: { "application/json": { schema: zS } }
26836
+ content: { "application/json": { schema: BS } }
26763
26837
  },
26764
26838
  404: {
26765
26839
  description: "Tree or Channel not found / inactive",
26766
- content: { "application/json": { schema: LS } }
26840
+ content: { "application/json": { schema: RS } }
26767
26841
  },
26768
26842
  500: {
26769
26843
  description: "Server error during hydration",
26770
- content: { "application/json": { schema: LS } }
26844
+ content: { "application/json": { schema: RS } }
26771
26845
  }
26772
26846
  }
26773
26847
  });
26774
- MS.openapi(BS, async (e) => {
26848
+ NS.openapi(VS, async (e) => {
26775
26849
  try {
26776
26850
  let t = e.get("db"), { treeParam: n } = e.req.valid("param"), r = e.req.valid("query"), i = r.channelId || r.channel || "default", a = r.lang, o = r.preview === "true", s = null, c = -1;
26777
26851
  if (i && i !== "default" && i !== "all") {
@@ -26806,7 +26880,7 @@ MS.openapi(BS, async (e) => {
26806
26880
  }
26807
26881
  let v = [];
26808
26882
  if (g !== null) {
26809
- let e = await t.prepare("\n SELECT \n t.contentId as treeNodeId,\n t.treeId,\n t.contentId as id,\n t.parentId,\n t.sortOrder,\n c.title,\n c.slug,\n c.language,\n c.contentType as nodeType,\n c.isHidden,\n c.status,\n c.dataJson,\n c.draftDataJson,\n (\n SELECT path \n FROM node_routes \n WHERE nodeId = c.id AND channelId = ? \n ORDER BY CASE WHEN treeId = t.treeId THEN 0 ELSE 1 END ASC \n LIMIT 1\n ) as materializedPath\n FROM tree_nodes t\n INNER JOIN content_nodes c ON t.contentId = c.id\n WHERE t.treeId = ? AND (c.deletedAt IS NULL OR c.deletedAt = '')\n ORDER BY t.sortOrder ASC\n ").all(c, g);
26883
+ let e = await t.prepare("\n SELECT \n t.contentId as treeNodeId,\n t.treeId,\n t.contentId as id,\n t.parentId,\n t.sortOrder,\n c.title,\n c.slug,\n c.language,\n c.contentType as nodeType,\n c.isHidden,\n c.startShowingAt,\n c.stopShowingAt,\n c.status,\n c.dataJson,\n c.draftDataJson,\n (\n SELECT path \n FROM node_routes \n WHERE nodeId = c.id AND channelId = ? \n ORDER BY CASE WHEN treeId = t.treeId THEN 0 ELSE 1 END ASC \n LIMIT 1\n ) as materializedPath\n FROM tree_nodes t\n INNER JOIN content_nodes c ON t.contentId = c.id\n WHERE t.treeId = ? AND (c.deletedAt IS NULL OR c.deletedAt = '')\n ORDER BY t.sortOrder ASC\n ").all(c, g);
26810
26884
  v = Array.isArray(e) ? e : e?.results || [];
26811
26885
  }
26812
26886
  if ((!v || v.length === 0) && !u) return e.json({ error: `Tree '${n}' not found` }, 404);
@@ -26834,7 +26908,7 @@ MS.openapi(BS, async (e) => {
26834
26908
  return (y.get(n) || []).map((e) => {
26835
26909
  let n = b.get(String(e.id)) || {}, r = {};
26836
26910
  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);
26837
- let i = !o && (e.status === "draft" || e.status === "new"), a = Number(e.isHidden) === 1 || i || n.hidden === !0 || n.hidden === 1 || n.hidden === "1" || n.hidden === "true", s = NS(n.startShowingAt, n.stopShowingAt), c = (e.slug || "").replace(/^\/+|\/+$/g, ""), l = !e.parentId || e.parentId === "null" || e.parentId === "", u = e.materializedPath || (l ? `/${c}` : `${t}/${c}`.replace(/\/+/g, "/")), d = e.language && String(e.language).trim() !== "" ? e.language.trim() : f, p = {
26911
+ let i = !o && (e.status === "draft" || e.status === "new"), a = Number(e.isHidden) === 1 || i || n.hidden === !0 || n.hidden === 1 || n.hidden === "1" || n.hidden === "true", s = PS(e.startShowingAt === void 0 ? n.startShowingAt : e.startShowingAt, e.stopShowingAt === void 0 ? n.stopShowingAt : e.stopShowingAt), c = (e.slug || "").replace(/^\/+|\/+$/g, ""), l = !e.parentId || e.parentId === "null" || e.parentId === "", u = e.materializedPath || (l ? `/${c}` : `${t}/${c}`.replace(/\/+/g, "/")), d = e.language && String(e.language).trim() !== "" ? e.language.trim() : f, p = {
26838
26912
  id: e.id,
26839
26913
  treeNodeId: e.id,
26840
26914
  parentId: e.parentId || null,
@@ -26860,7 +26934,7 @@ MS.openapi(BS, async (e) => {
26860
26934
  ..._,
26861
26935
  items: x(null)
26862
26936
  };
26863
- return !o && !h && (e.header("X-Cache", "MISS"), await PS(p, m, S, 300)), e.json(S, 200);
26937
+ return !o && !h && (e.header("X-Cache", "MISS"), await FS(p, m, S, 300)), e.json(S, 200);
26864
26938
  } catch (t) {
26865
26939
  return console.error("[CMS Public Tree API] Error:", t), e.json({
26866
26940
  error: "Failed to fetch public tree",
@@ -26870,19 +26944,19 @@ MS.openapi(BS, async (e) => {
26870
26944
  });
26871
26945
  //#endregion
26872
26946
  //#region server/routes/public/channel.ts
26873
- var VS = new $y();
26874
- function HS(e) {
26947
+ var HS = new $y();
26948
+ function US(e) {
26875
26949
  let t = Number(e?.env?.CMS_CHANNEL_CACHE_TTL);
26876
26950
  return Number.isFinite(t) && t >= 60 ? Math.floor(t) : 300;
26877
26951
  }
26878
- async function US(e, t, n, r) {
26952
+ async function WS(e, t, n, r) {
26879
26953
  try {
26880
26954
  await e.set(t, n, r);
26881
26955
  } catch (e) {
26882
26956
  console.warn("[CMS Cache] Failed to write channel response to cache:", e);
26883
26957
  }
26884
26958
  }
26885
- function WS(e, t) {
26959
+ function GS(e, t) {
26886
26960
  let n = {}, r = (e) => {
26887
26961
  if (!e || typeof e != "string") return;
26888
26962
  let n = t?.fieldSets?.[e] || t?.fieldsets?.[e] || t?.definitions?.[e] || t?.channels?.[e] || t?.[e];
@@ -26893,7 +26967,7 @@ function WS(e, t) {
26893
26967
  if (e?.fieldSets && Array.isArray(e.fieldSets) && e.fieldSets.forEach((e) => r(e)), e?.fields && i(e.fields), e?.tabs && typeof e.tabs == "object") for (let t of Object.values(e.tabs)) t?.fields && i(t.fields);
26894
26968
  return n;
26895
26969
  }
26896
- function GS(e, t = {}) {
26970
+ function KS(e, t = {}) {
26897
26971
  let n = {}, r = Object.keys(t).length > 0;
26898
26972
  for (let [i, a] of Object.entries(e)) {
26899
26973
  if (i.endsWith("_meta") || [
@@ -26912,14 +26986,14 @@ function GS(e, t = {}) {
26912
26986
  }
26913
26987
  return n;
26914
26988
  }
26915
- function KS(e) {
26916
- if (Array.isArray(e)) return e.map(KS);
26989
+ function qS(e) {
26990
+ if (Array.isArray(e)) return e.map(qS);
26917
26991
  if (!e || typeof e != "object") return e;
26918
26992
  if (typeof e.id == "string" && e.id.startsWith("ast_") && typeof e.url == "string") {
26919
26993
  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 ? {
26920
26994
  ...t,
26921
26995
  ...t.crops?.[r] || {}
26922
- } : t, a = Object.fromEntries(Object.entries(n).filter(([, t]) => t?.id !== e.id).map(([t, n]) => [t, KS({
26996
+ } : t, a = Object.fromEntries(Object.entries(n).filter(([, t]) => t?.id !== e.id).map(([t, n]) => [t, qS({
26923
26997
  ...n,
26924
26998
  title: n?.title ?? e.title ?? "",
26925
26999
  alt: n?.alt ?? e.alt ?? "",
@@ -26933,9 +27007,19 @@ function KS(e) {
26933
27007
  ...Object.keys(a).length > 0 ? { variants: a } : {}
26934
27008
  };
26935
27009
  }
26936
- return Object.fromEntries(Object.entries(e).map(([e, t]) => [e, KS(t)]));
27010
+ return Object.fromEntries(Object.entries(e).map(([e, t]) => [e, qS(t)]));
27011
+ }
27012
+ async function JS(e, t, n) {
27013
+ let r = t.href.match(/^#node:(.+)$/), i = t.href.match(/^#asset:(.+)$/);
27014
+ if (i) {
27015
+ let t = i[1], n = await e.prepare("SELECT cdnUrl, storageKeyPrivate FROM assets WHERE id = ?").get(t);
27016
+ return n?.cdnUrl || (n?.storageKeyPrivate ? `/media/${n.storageKeyPrivate}` : "#");
27017
+ }
27018
+ if (!r) return t.href;
27019
+ let a = r[1];
27020
+ return (await e.prepare("SELECT path FROM node_routes WHERE nodeId = ? AND channelId = ? AND isCanonical = 1 LIMIT 1").get(Number(a), n))?.path || "#";
26937
27021
  }
26938
- async function qS(e, t, n) {
27022
+ async function YS(e, t, n) {
26939
27023
  if (typeof t == "string") {
26940
27024
  if (!t.includes("#node:") && !t.includes("data-node-id") && !t.includes("#asset:") && !t.includes("data-asset-id")) return t;
26941
27025
  let r = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Set();
@@ -26968,45 +27052,52 @@ async function qS(e, t, n) {
26968
27052
  return /href\s*=\s*["'][^"']*["']/i.test(d) ? d = d.replace(/href\s*=\s*["'][^"']*["']/i, `href="${u}"`) : d += ` href="${u}"`, `<a ${d}>`;
26969
27053
  });
26970
27054
  }
26971
- if (Array.isArray(t)) return Promise.all(t.map((t) => qS(e, t, n)));
27055
+ if (Array.isArray(t)) return Promise.all(t.map((t) => YS(e, t, n)));
26972
27056
  if (t && typeof t == "object") {
26973
- let r = await Promise.all(Object.entries(t).map(async ([t, r]) => [t, await qS(e, r, n)]));
27057
+ if (typeof t.href == "string" && (t.href.startsWith("#node:") || t.href.startsWith("#asset:"))) {
27058
+ let r = await JS(e, t, n), i = await Promise.all(Object.entries(t).filter(([e]) => e !== "href").map(async ([t, r]) => [t, await YS(e, r, n)]));
27059
+ return {
27060
+ ...Object.fromEntries(i),
27061
+ href: r
27062
+ };
27063
+ }
27064
+ let r = await Promise.all(Object.entries(t).map(async ([t, r]) => [t, await YS(e, r, n)]));
26974
27065
  return Object.fromEntries(r);
26975
27066
  }
26976
27067
  return t;
26977
27068
  }
26978
- var JS = X({ channelParam: J().openapi({ description: "The ID or key (slug) of the requested channel" }) }), YS = X({ preview: lv(["true", "false"]).optional().openapi({ description: "Set to true to retrieve unpublished draft data" }) }), XS = X({
27069
+ var XS = X({ channelParam: J().openapi({ description: "The ID or key (slug) of the requested channel" }) }), ZS = X({ preview: lv(["true", "false"]).optional().openapi({ description: "Set to true to retrieve unpublished draft data" }) }), QS = X({
26979
27070
  error: J(),
26980
27071
  details: J().optional()
26981
- }).openapi("ErrorResponse"), ZS = X({
27072
+ }).openapi("ErrorResponse"), $S = X({
26982
27073
  id: G_([c_(), J()]),
26983
27074
  key: J()
26984
- }).catchall(k_()).openapi("ChannelResponse"), QS = eb({
27075
+ }).catchall(k_()).openapi("ChannelResponse"), eC = eb({
26985
27076
  method: "get",
26986
27077
  path: "/{channelParam}",
26987
27078
  summary: "Fetch CMS Channel Settings",
26988
27079
  description: "Retrieves the fully hydrated, public-facing settings and payload for a specific CMS channel.",
26989
27080
  tags: ["Public Channel API"],
26990
27081
  request: {
26991
- params: JS,
26992
- query: YS
27082
+ params: XS,
27083
+ query: ZS
26993
27084
  },
26994
27085
  responses: {
26995
27086
  200: {
26996
27087
  description: "Fully hydrated CMS Channel payload",
26997
- content: { "application/json": { schema: ZS } }
27088
+ content: { "application/json": { schema: $S } }
26998
27089
  },
26999
27090
  404: {
27000
27091
  description: "Channel not found or inactive",
27001
- content: { "application/json": { schema: XS } }
27092
+ content: { "application/json": { schema: QS } }
27002
27093
  },
27003
27094
  500: {
27004
27095
  description: "Server error during hydration",
27005
- content: { "application/json": { schema: XS } }
27096
+ content: { "application/json": { schema: QS } }
27006
27097
  }
27007
27098
  }
27008
27099
  });
27009
- VS.openapi(QS, async (e) => {
27100
+ HS.openapi(eC, async (e) => {
27010
27101
  try {
27011
27102
  let t = e.get("db"), { channelParam: n } = e.req.valid("param"), { preview: r } = e.req.valid("query"), i = r === "true", a = e.req.header("x-bypass-cache") === "true", o = `channel:${n}:${i ? "preview" : "live"}`, s = $b(e);
27012
27103
  if (!i && !a) {
@@ -27017,23 +27108,23 @@ VS.openapi(QS, async (e) => {
27017
27108
  if (!c) return e.json({ error: `Channel '${n}' not found` }, 404);
27018
27109
  let l = c.status === "disabled" || c.status === "inactive" || c.isEnabled === 0 || c.isEnabled === !1;
27019
27110
  if (!i && l) return e.json({ error: `Channel '${c.key || n}' is currently inactive` }, 404);
27020
- let u = Number(c.id), d = e.env?.BUNDLED_DEFINITIONS, f = px(d), p = c.channelType || c.key || "website", m = WS(f.channels?.[p] || f.channels?.[c.key] || f.channels?.website || f.definitions?.["channel-base"] || {}, f), h = {}, g = i && c.draftDataJson || c.dataJson;
27111
+ let u = Number(c.id), d = e.env?.BUNDLED_DEFINITIONS, f = px(d), p = c.channelType || c.key || "website", m = GS(f.channels?.[p] || f.channels?.[c.key] || f.channels?.website || f.definitions?.["channel-base"] || {}, f), h = {}, g = i && c.draftDataJson || c.dataJson;
27021
27112
  if (g) try {
27022
27113
  h = typeof g == "string" ? JSON.parse(g) : g;
27023
27114
  } catch (e) {
27024
27115
  console.warn("[CMS Public Channel API] Failed to parse channel dataJson:", e);
27025
27116
  }
27026
- let _ = GS({
27117
+ let _ = KS({
27027
27118
  ...h,
27028
27119
  ...c
27029
27120
  }, m);
27030
- _ = await fx(t, _), _ = KS(_), _ = await qS(t, _, u);
27121
+ _ = await fx(t, _), _ = qS(_), _ = await YS(t, _, u);
27031
27122
  let v = {
27032
27123
  id: c.id,
27033
27124
  key: c.key,
27034
27125
  ..._
27035
27126
  };
27036
- return !i && !a && (e.header("X-Cache", "MISS"), await US(s, o, v, HS(e))), e.json(v, 200);
27127
+ return !i && !a && (e.header("X-Cache", "MISS"), await WS(s, o, v, US(e))), e.json(v, 200);
27037
27128
  } catch (t) {
27038
27129
  return console.error("[CMS Public Channel API] Error:", t), e.json({
27039
27130
  error: "Failed to fetch public channel",
@@ -27043,8 +27134,8 @@ VS.openapi(QS, async (e) => {
27043
27134
  });
27044
27135
  //#endregion
27045
27136
  //#region server/routes/public/assets.ts
27046
- var $S = new $y();
27047
- function eC(e, t) {
27137
+ var tC = new $y();
27138
+ function nC(e, t) {
27048
27139
  if (t === "webp") return "image/webp";
27049
27140
  if (t === "avif") return "image/avif";
27050
27141
  if (t === "jpeg" || t === "jpg") return "image/jpeg";
@@ -27053,7 +27144,7 @@ function eC(e, t) {
27053
27144
  let n = e.toLowerCase();
27054
27145
  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" : "application/octet-stream";
27055
27146
  }
27056
- var tC = [
27147
+ var rC = [
27057
27148
  320,
27058
27149
  640,
27059
27150
  768,
@@ -27063,10 +27154,10 @@ var tC = [
27063
27154
  2560,
27064
27155
  3840
27065
27156
  ];
27066
- function nC(e) {
27067
- if (!(!e || isNaN(e) || e <= 0)) return tC.reduce((t, n) => Math.abs(n - e) < Math.abs(t - e) ? n : t);
27157
+ function iC(e) {
27158
+ if (!(!e || isNaN(e) || e <= 0)) return rC.reduce((t, n) => Math.abs(n - e) < Math.abs(t - e) ? n : t);
27068
27159
  }
27069
- var rC = eb({
27160
+ var aC = eb({
27070
27161
  method: "get",
27071
27162
  path: "/*",
27072
27163
  summary: "Serve & Optimize Media Assets",
@@ -27126,11 +27217,11 @@ var rC = eb({
27126
27217
  }
27127
27218
  }
27128
27219
  });
27129
- $S.openapi(rC, async (e) => {
27220
+ tC.openapi(aC, async (e) => {
27130
27221
  try {
27131
27222
  let t = e.req.path.replace(/^\/media\//, "").replace(/^\//, "");
27132
27223
  if (!t) return e.text("Asset key missing", 400);
27133
- let { w: n, h: r, q: i, f: a } = e.req.valid("query"), o = !!(n || r || i || a), s = nC(n ? parseInt(n, 10) : void 0), c = e.req.header("Accept") || "", l = "";
27224
+ let { w: n, h: r, q: i, f: a } = e.req.valid("query"), o = !!(n || r || i || a), s = iC(n ? parseInt(n, 10) : void 0), c = e.req.header("Accept") || "", l = "";
27134
27225
  if (o) {
27135
27226
  let e = !a || a === "auto";
27136
27227
  a === "avif" || e && c.includes("image/avif") ? l = "avif" : a === "webp" || e && c.includes("image/webp") ? l = "webp" : a === "jpeg" || a === "jpg" ? l = "jpeg" : a === "png" && (l = "png");
@@ -27149,7 +27240,7 @@ $S.openapi(rC, async (e) => {
27149
27240
  if (!h) return e.text(`Asset not found: ${t}`, 404);
27150
27241
  if (!o) {
27151
27242
  let n = e.body(h, 200, {
27152
- "Content-Type": eC(t),
27243
+ "Content-Type": nC(t),
27153
27244
  "Cache-Control": "public, max-age=31536000, immutable"
27154
27245
  });
27155
27246
  return u && f && e.executionCtx?.waitUntil && e.executionCtx.waitUntil(u.put(f, n.clone())), n;
@@ -27163,7 +27254,7 @@ $S.openapi(rC, async (e) => {
27163
27254
  key: t,
27164
27255
  env: e.env,
27165
27256
  req: e.req.raw
27166
- }), v = eC(t, l), y = e.body(_, 200, {
27257
+ }), v = nC(t, l), y = e.body(_, 200, {
27167
27258
  "Content-Type": v,
27168
27259
  "Cache-Control": "public, max-age=31536000, immutable"
27169
27260
  });
@@ -27174,8 +27265,8 @@ $S.openapi(rC, async (e) => {
27174
27265
  });
27175
27266
  //#endregion
27176
27267
  //#region server/routes/public/paths.ts
27177
- var iC = new $y();
27178
- function aC(e, t) {
27268
+ var oC = new $y();
27269
+ function sC(e, t) {
27179
27270
  let n = /* @__PURE__ */ new Date();
27180
27271
  if (e && String(e).trim() !== "") {
27181
27272
  let t = new Date(e);
@@ -27187,31 +27278,31 @@ function aC(e, t) {
27187
27278
  }
27188
27279
  return !0;
27189
27280
  }
27190
- var oC = X({
27281
+ var cC = X({
27191
27282
  channelId: J().optional().openapi({ description: "Optional channel ID/key to filter and resolve root paths for" }),
27192
27283
  channel: J().optional().openapi({ description: "Legacy alias for channelId" })
27193
- }), sC = z_(J()).openapi("PathsResponse"), cC = X({
27284
+ }), lC = z_(J()).openapi("PathsResponse"), uC = X({
27194
27285
  error: J(),
27195
27286
  details: J().optional()
27196
- }).openapi("ErrorResponse"), lC = eb({
27287
+ }).openapi("ErrorResponse"), dC = eb({
27197
27288
  method: "get",
27198
27289
  path: "/",
27199
27290
  summary: "Fetch All Public Paths",
27200
27291
  description: "Retrieves a deduplicated array of all active, published node paths leveraging the $O(1)$ node_routes table. Includes both tree-bound and standalone pages.",
27201
27292
  tags: ["Public Paths API"],
27202
- request: { query: oC },
27293
+ request: { query: cC },
27203
27294
  responses: {
27204
27295
  200: {
27205
27296
  description: "Array of valid public URL paths",
27206
- content: { "application/json": { schema: sC } }
27297
+ content: { "application/json": { schema: lC } }
27207
27298
  },
27208
27299
  500: {
27209
27300
  description: "Server error fetching paths",
27210
- content: { "application/json": { schema: cC } }
27301
+ content: { "application/json": { schema: uC } }
27211
27302
  }
27212
27303
  }
27213
27304
  });
27214
- iC.openapi(lC, async (e) => {
27305
+ oC.openapi(dC, async (e) => {
27215
27306
  try {
27216
27307
  let t = e.get("db"), n = e.req.valid("query"), r = n.channelId || n.channel, i = "", a = [];
27217
27308
  if (r && r !== "all") {
@@ -27222,7 +27313,8 @@ iC.openapi(lC, async (e) => {
27222
27313
  SELECT
27223
27314
  nr.path,
27224
27315
  cn.contentType as nodeType,
27225
- cn.dataJson
27316
+ cn.startShowingAt,
27317
+ cn.stopShowingAt
27226
27318
  FROM node_routes nr
27227
27319
  INNER JOIN content_nodes cn ON nr.nodeId = cn.id
27228
27320
  WHERE nr.isCanonical = 1
@@ -27231,15 +27323,7 @@ iC.openapi(lC, async (e) => {
27231
27323
  ${i}
27232
27324
  ORDER BY nr.path ASC
27233
27325
  `).all(...a), s = Array.isArray(o) ? o : o?.results || [], c = [];
27234
- for (let e of s) {
27235
- if (e.nodeType === "external-link" || !e.path) continue;
27236
- let t = !0;
27237
- if (e.dataJson) try {
27238
- let n = typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson;
27239
- t = aC(n?.startShowingAt, n?.stopShowingAt);
27240
- } catch {}
27241
- t && c.push(e.path);
27242
- }
27326
+ for (let e of s) e.nodeType !== "external-link" && e.path && sC(e.startShowingAt, e.stopShowingAt) && c.push(e.path);
27243
27327
  let l = [...new Set(c)];
27244
27328
  return e.json(l, 200);
27245
27329
  } catch (t) {
@@ -27248,12 +27332,12 @@ iC.openapi(lC, async (e) => {
27248
27332
  });
27249
27333
  //#endregion
27250
27334
  //#region server/routes/public/taxonomies.ts
27251
- var uC = new $y();
27252
- function dC(e) {
27335
+ var fC = new $y();
27336
+ function pC(e) {
27253
27337
  let t = (e || "").trim().toLowerCase(), n = px()?.taxonomies || {};
27254
27338
  return n[t] ? t : n[`${t}s`] ? `${t}s` : t.endsWith("s") && n[t.slice(0, -1)] ? t.slice(0, -1) : t;
27255
27339
  }
27256
- var fC = X({
27340
+ var mC = X({
27257
27341
  id: c_(),
27258
27342
  taxonomy: J(),
27259
27343
  key: J(),
@@ -27263,14 +27347,14 @@ var fC = X({
27263
27347
  data: tv(k_()),
27264
27348
  createdAt: J(),
27265
27349
  updatedAt: J()
27266
- }), pC = X({
27350
+ }), hC = X({
27267
27351
  taxonomy: J(),
27268
- items: z_(fC),
27352
+ items: z_(mC),
27269
27353
  total: c_()
27270
- }).openapi("TaxonomyResponse"), mC = X({
27354
+ }).openapi("TaxonomyResponse"), gC = X({
27271
27355
  error: J(),
27272
27356
  details: J().optional()
27273
- }).openapi("ErrorResponse"), hC = eb({
27357
+ }).openapi("ErrorResponse"), _C = eb({
27274
27358
  method: "get",
27275
27359
  path: "/{taxonomy}",
27276
27360
  summary: "Fetch Public Taxonomy Terms",
@@ -27280,17 +27364,17 @@ var fC = X({
27280
27364
  responses: {
27281
27365
  200: {
27282
27366
  description: "List of taxonomy terms",
27283
- content: { "application/json": { schema: pC } }
27367
+ content: { "application/json": { schema: hC } }
27284
27368
  },
27285
27369
  500: {
27286
27370
  description: "Server error",
27287
- content: { "application/json": { schema: mC } }
27371
+ content: { "application/json": { schema: gC } }
27288
27372
  }
27289
27373
  }
27290
27374
  });
27291
- uC.openapi(hC, async (e) => {
27375
+ fC.openapi(_C, async (e) => {
27292
27376
  try {
27293
- let t = e.get("db"), n = $b(e), r = e.req.valid("param").taxonomy, i = dC(r), a = `taxonomy:public:${i}`, o = e.req.header("x-bypass-cache") === "true";
27377
+ let t = e.get("db"), n = $b(e), r = e.req.valid("param").taxonomy, i = pC(r), a = `taxonomy:public:${i}`, o = e.req.header("x-bypass-cache") === "true";
27294
27378
  if (!o) {
27295
27379
  let t = await n.get(a);
27296
27380
  if (t) return e.header("X-Cache", "HIT"), e.json(t);
@@ -27326,7 +27410,7 @@ uC.openapi(hC, async (e) => {
27326
27410
  });
27327
27411
  //#endregion
27328
27412
  //#region server/index.ts
27329
- var $ = new $y(), gC = !1;
27413
+ var $ = new $y(), vC = !1;
27330
27414
  $.use("*", t()), $.use("/media/*", t({
27331
27415
  origin: "*",
27332
27416
  allowMethods: [
@@ -27347,20 +27431,20 @@ $.use("*", t()), $.use("/media/*", t({
27347
27431
  let n = new URL(e.req.url), r = (e.req.header("host") || n.hostname).split(":")[0];
27348
27432
  e.set("currentDomain", r);
27349
27433
  let i = wb(e);
27350
- if (e.set("db", i), !gC) try {
27351
- await Mb(i), gC = !0;
27434
+ if (e.set("db", i), !vC) try {
27435
+ await Mb(i), vC = !0;
27352
27436
  } catch (e) {
27353
27437
  console.error("❌ [CMS Server] Failed to initialize system tables on cold start:", e);
27354
27438
  }
27355
27439
  await t();
27356
- }), $.route("/media", $S), $.use("/media/*", Pb()), $.route("/api/cms/nodes", gx), $.route("/api/cms/nodes.json", gx), $.route("/api/cms/formcsv", gx), $.route("/api/cms/formcsv.json", gx), $.route("/api/cms/stats", rS), $.route("/api/cms/stats.json", rS), $.route("/api/cms", Dx), $.route("/api/cms/trees.json", Dx), $.route("/api/cms/channels", jx), $.route("/api/cms/channels.json", jx), $.route("/api/cms/taxonomies", Mx), $.route("/api/cms/taxonomies.json", Mx), $.route("/api/cms/schemas", Qx), $.route("/api/cms/schemas.json", Qx), $.route("/api/cms", eS), $.route("/api/admin/assets", iS), $.use("/api/v1/*", async (e, t) => {
27440
+ }), $.route("/media", tC), $.use("/media/*", Pb()), $.route("/api/cms/nodes", gx), $.route("/api/cms/nodes.json", gx), $.route("/api/cms/formcsv", gx), $.route("/api/cms/formcsv.json", gx), $.route("/api/cms/stats", iS), $.route("/api/cms/stats.json", iS), $.route("/api/cms", Ox), $.route("/api/cms/trees.json", Ox), $.route("/api/cms/channels", Mx), $.route("/api/cms/channels.json", Mx), $.route("/api/cms/taxonomies", Nx), $.route("/api/cms/taxonomies.json", Nx), $.route("/api/cms/schemas", $x), $.route("/api/cms/schemas.json", $x), $.route("/api/cms", tS), $.route("/api/admin/assets", aS), $.use("/api/v1/*", async (e, t) => {
27357
27441
  let n = e.env?.FRONTEND_API_SECRET;
27358
27442
  if (n) {
27359
27443
  let t = e.req.header("Authorization"), r = e.req.header("x-api-key"), i = t?.startsWith("Bearer ") ? t.substring(7).trim() : r?.trim();
27360
27444
  if (!i || i !== n) return e.json({ error: "Unauthorized: Invalid or missing API secret." }, 401);
27361
27445
  } else console.warn("⚠️ [CMS Security] FRONTEND_API_SECRET is not set in .env. The API is completely exposed to the public.");
27362
27446
  return t();
27363
- }), $.route("/api/v1/node", cS), $.route("/api/v1/nodes", OS), $.route("/api/v1/tree", MS), $.route("/api/v1/channel", VS), $.route("/api/v1/all-paths", iC), $.route("/api/v1/taxonomies", uC), $.doc("/api/openapi.json", {
27447
+ }), $.route("/api/v1/node", lS), $.route("/api/v1/nodes", kS), $.route("/api/v1/tree", NS), $.route("/api/v1/channel", HS), $.route("/api/v1/all-paths", oC), $.route("/api/v1/taxonomies", fC), $.doc("/api/openapi.json", {
27364
27448
  openapi: "3.0.0",
27365
27449
  info: {
27366
27450
  title: "KAMA Engine Public API",
@@ -27379,4 +27463,4 @@ $.use("*", t()), $.use("/media/*", t({
27379
27463
  return t();
27380
27464
  });
27381
27465
  //#endregion
27382
- export { $ as app, $ as default, Yx as compileDefinitions, Xx as getCmsDefinitions };
27466
+ export { $ as app, $ as default, Xx as compileDefinitions, Zx as getCmsDefinitions };