@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
@@ -276,9 +276,9 @@ function D(e, t) {
276
276
  return r && E.setMetadataInRegistry(t, r), t;
277
277
  });
278
278
  }
279
- function O(e) {
279
+ function te(e) {
280
280
  e.ZodType.prototype.openapi === void 0 && (e.ZodType.prototype.openapi = function(...e) {
281
- 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);
281
+ 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);
282
282
  function h(e) {
283
283
  E.setMetadataInRegistry(e, Object.assign(Object.assign({}, Object.keys(f).length > 0 ? { _internal: f } : void 0), p));
284
284
  }
@@ -304,7 +304,7 @@ function O(e) {
304
304
  }, m;
305
305
  });
306
306
  }
307
- function te(e, t, n) {
307
+ function O(e, t, n) {
308
308
  return typeof e == "string" ? {
309
309
  refId: e,
310
310
  metadata: t,
@@ -16543,7 +16543,7 @@ var $y = class t extends e {
16543
16543
  };
16544
16544
  return Object.defineProperty(t, "getRoutingPath", { enumerable: !1 });
16545
16545
  };
16546
- O(Xy);
16546
+ te(Xy);
16547
16547
  function tb(e, t) {
16548
16548
  let n = {};
16549
16549
  return Object.keys(e.paths).forEach((r) => {
@@ -22030,7 +22030,7 @@ var Tb = /* @__PURE__ */ o({
22030
22030
  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 ",
22031
22031
  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 ",
22032
22032
  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 ",
22033
- 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 ",
22033
+ 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 ",
22034
22034
  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 ",
22035
22035
  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 ",
22036
22036
  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 ",
@@ -22041,11 +22041,11 @@ var Tb = /* @__PURE__ */ o({
22041
22041
  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 ",
22042
22042
  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 ",
22043
22043
  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 "
22044
- }, 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(".");
22044
+ }, 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(".");
22045
22045
  function Ab(e) {
22046
22046
  let t = /* @__PURE__ */ new Set();
22047
22047
  function n(e) {
22048
- 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));
22048
+ 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));
22049
22049
  }
22050
22050
  return n(e), Array.from(t);
22051
22051
  }
@@ -22072,6 +22072,18 @@ async function Mb(e, t) {
22072
22072
  if (!n.has("hasUnpublishedChanges")) try {
22073
22073
  await e.prepare("ALTER TABLE \"content_nodes\" ADD COLUMN hasUnpublishedChanges INTEGER DEFAULT 0;").run();
22074
22074
  } catch {}
22075
+ let t = !1;
22076
+ if (!n.has("startShowingAt")) try {
22077
+ await e.prepare("ALTER TABLE \"content_nodes\" ADD COLUMN startShowingAt TEXT;").run(), t = !0;
22078
+ } catch {}
22079
+ if (!n.has("stopShowingAt")) try {
22080
+ await e.prepare("ALTER TABLE \"content_nodes\" ADD COLUMN stopShowingAt TEXT;").run(), t = !0;
22081
+ } catch {}
22082
+ if (t) try {
22083
+ 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.");
22084
+ } catch (e) {
22085
+ console.error("[Schema Sync] Failed to backfill dates:", e);
22086
+ }
22075
22087
  }
22076
22088
  if (t === "assets") {
22077
22089
  if (!n.has("parentAssetId")) try {
@@ -22830,7 +22842,9 @@ var Fb = { hasSubscribers: !1 }, Ib = Fb, Lb = Fb, Rb = typeof performance == "o
22830
22842
  }, Qb = null;
22831
22843
  function $b(e) {
22832
22844
  let t = process.env.CACHE_DRIVER || "lru";
22833
- 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();
22845
+ if (t === "none" || t === "off" || t === "false") return new Zb();
22846
+ let n = e?.env?.CACHE_KV || e?.env?.CMS_CACHE_KV;
22847
+ return n ? new Xb(n) : t === "lru" ? (Qb ||= new Yb(), Qb) : new Zb();
22834
22848
  }
22835
22849
  var ex = class {
22836
22850
  customStoragePath;
@@ -23389,6 +23403,7 @@ var mx = class {
23389
23403
  return {
23390
23404
  zoneId: e.env?.CLOUDFLARE_ZONE_ID || this.env.CLOUDFLARE_ZONE_ID,
23391
23405
  apiToken: e.env?.CLOUDFLARE_API_TOKEN || this.env.CLOUDFLARE_API_TOKEN,
23406
+ purgeToken: e.env?.FRONTEND_API_SECRET || this.env.FRONTEND_API_SECRET || e.env?.CLOUDFLARE_API_TOKEN || this.env.CLOUDFLARE_API_TOKEN,
23392
23407
  frontendUrl: (e.env?.PUBLIC_FRONTEND_URL || this.env.PUBLIC_FRONTEND_URL || "http://localhost:4321").replace(/\/+$/, ""),
23393
23408
  cdnDomain: t ? t.replace(/^https?:\/\//, "").replace(/\/+$/, "") : "localhost:8787",
23394
23409
  frontendWorker: e.env?.FRONTEND_WORKER || this.env.FRONTEND_WORKER,
@@ -23416,7 +23431,7 @@ var mx = class {
23416
23431
  return r && n && r.startsWith(`https://${n}/`) && !r.includes("/media/") && (r = r.replace(`https://${n}/`, `https://${n}/media/`)), r;
23417
23432
  }
23418
23433
  async callAstroPurge(e, t, n) {
23419
- let { apiToken: r, frontendUrl: i, frontendWorker: a, disableCachePurge: o } = this.getEnv(e);
23434
+ let { purgeToken: r, frontendUrl: i, frontendWorker: a, disableCachePurge: o } = this.getEnv(e);
23420
23435
  if (o === "true" || o === !0 || o === "1") return new Response(JSON.stringify({ skipped: !0 }), { status: 200 });
23421
23436
  let s = (n || i).replace(/\/+$/, ""), c = `${s}/api/purge`, l = { "Content-Type": "application/json" };
23422
23437
  if (r && (l.Authorization = `Bearer ${r}`), a && typeof a.fetch == "function") try {
@@ -23446,8 +23461,21 @@ var mx = class {
23446
23461
  try {
23447
23462
  let a = $b(e);
23448
23463
  if (n) {
23449
- 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 || [];
23450
- for (let e of i) await a.delete(`tree:default:${e.treeId}`), await a.delete(`tree:all:${e.treeId}`);
23464
+ 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();
23465
+ for (let e of o) {
23466
+ let t = /* @__PURE__ */ new Set(["default", "all"]);
23467
+ e.channelId !== null && e.channelId !== void 0 && t.add(String(e.channelId)), e.channelKey && t.add(String(e.channelKey));
23468
+ let n = /* @__PURE__ */ new Set();
23469
+ e.treeId !== null && e.treeId !== void 0 && n.add(String(e.treeId)), e.treeKey && n.add(String(e.treeKey));
23470
+ let r = /* @__PURE__ */ new Set(["default"]);
23471
+ i && r.add(i.trim()), e.channelDefaultLanguage && r.add(String(e.channelDefaultLanguage).trim());
23472
+ try {
23473
+ let t = typeof e.treeDataJson == "string" ? JSON.parse(e.treeDataJson) : e.treeDataJson;
23474
+ (t?.defaultLanguage || t?.language) && r.add(String(t.defaultLanguage || t.language).trim());
23475
+ } catch {}
23476
+ for (let e of t) for (let t of n) for (let n of r) s.add(`tree:${e}:${t}:${n || "default"}`);
23477
+ }
23478
+ await Promise.all(Array.from(s, (e) => a.delete(e)));
23451
23479
  }
23452
23480
  if (r) {
23453
23481
  let e = r.replace(/^\/+|\/+$/g, ""), o = ["default", "1"];
@@ -23461,9 +23489,37 @@ var mx = class {
23461
23489
  console.warn("[CacheManager] Failed to purge internal worker cache:", e);
23462
23490
  }
23463
23491
  }
23492
+ async purgeVisibilityChange(e, t, n) {
23493
+ try {
23494
+ 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];
23495
+ await this.purgeInternalWorkerCache(e, t, n, i?.slug, i?.language);
23496
+ let a = await this.callAstroPurge(e, { purge_everything: !0 }), o = await a.json().catch(() => ({}));
23497
+ if (!a.ok || o?.success === !1 || o?.skipped) return console.warn(`[CacheManager] Visibility purge failed at Astro Worker (${a.status}).`), !1;
23498
+ let { zoneId: s, apiToken: c } = this.getEnv(e), l = this.isLocalEnv(e);
23499
+ if (s && c && !this.isLocalEnv(e)) {
23500
+ let e = await fetch(`https://api.cloudflare.com/client/v4/zones/${s}/purge_cache`, {
23501
+ method: "POST",
23502
+ headers: {
23503
+ Authorization: `Bearer ${c}`,
23504
+ "Content-Type": "application/json"
23505
+ },
23506
+ body: JSON.stringify({ purge_everything: !0 })
23507
+ }), t = await e.json().catch(() => ({}));
23508
+ l = e.ok && t?.success === !0, l || console.warn("[CacheManager] Visibility purge failed at Cloudflare Zone cache:", JSON.stringify(t));
23509
+ } else this.isLocalEnv(e) || console.warn("[CacheManager] Visibility purge lacks CLOUDFLARE_ZONE_ID or CLOUDFLARE_API_TOKEN.");
23510
+ return this.dispatch(e, this.warmAllPublishedPages(e, t)), l;
23511
+ } catch (e) {
23512
+ return console.warn("[CacheManager] Visibility cache purge failed:", e), !1;
23513
+ }
23514
+ }
23464
23515
  purgeNode(e, t, n, r = !1, i = []) {
23465
23516
  if (r) {
23466
- console.log(`[CacheManager] Structural change detected on nodeId ${n}. Escalating to Global Purge.`), this.purgeGlobalCache(e, t);
23517
+ console.log(`[CacheManager] Structural change detected on nodeId ${n}. Escalating to Global Purge.`);
23518
+ let r = (async () => {
23519
+ 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];
23520
+ await this.purgeInternalWorkerCache(e, t, n, i?.slug, i?.language), await this.purgeGlobalCacheDirect(e, t);
23521
+ })();
23522
+ this.dispatch(e, r);
23467
23523
  return;
23468
23524
  }
23469
23525
  let a = (async () => {
@@ -23549,8 +23605,12 @@ var mx = class {
23549
23605
  }
23550
23606
  async purgeGlobalCacheDirect(e, t) {
23551
23607
  try {
23552
- let { zoneId: n, apiToken: r } = this.getEnv(e);
23553
- if (!(await this.callAstroPurge(e, { purge_everything: !0 })).ok) return;
23608
+ let { zoneId: n, apiToken: r } = this.getEnv(e), i = await this.callAstroPurge(e, { purge_everything: !0 });
23609
+ if (!i.ok) {
23610
+ let e = await i.text().catch(() => "");
23611
+ console.warn(`[CacheManager] Astro global purge failed (${i.status}): ${e.slice(0, 500)}`);
23612
+ return;
23613
+ }
23554
23614
  if (n && r && !this.isLocalEnv(e)) try {
23555
23615
  let e = await (await fetch(`https://api.cloudflare.com/client/v4/zones/${n}/purge_cache`, {
23556
23616
  method: "POST",
@@ -23690,8 +23750,9 @@ async function hx(e) {
23690
23750
  await e.prepare("DELETE FROM node_routes").run();
23691
23751
  let h = Array.from(p.values());
23692
23752
  if (h.length === 0) return;
23693
- for (let t = 0; t < h.length; t += 50) {
23694
- let n = h.slice(t, t + 50), r = n.map(() => "(?, ?, ?, ?, ?, ?)").join(","), i = n.flatMap((e) => [
23753
+ let g = [];
23754
+ for (let e = 0; e < h.length; e += 15) {
23755
+ let t = h.slice(e, e + 15), n = t.map(() => "(?, ?, ?, ?, ?, ?)").join(","), r = t.flatMap((e) => [
23695
23756
  e.path,
23696
23757
  e.channelId,
23697
23758
  e.nodeId,
@@ -23699,10 +23760,17 @@ async function hx(e) {
23699
23760
  e.isCanonical,
23700
23761
  e.redirectUrl ?? null
23701
23762
  ]);
23702
- await e.prepare(`
23703
- INSERT INTO node_routes (path, channelId, nodeId, treeId, isCanonical, redirectUrl)
23704
- VALUES ${r}
23705
- `).run(...i);
23763
+ g.push({
23764
+ placeholders: n,
23765
+ params: r
23766
+ });
23767
+ }
23768
+ for (let t = 0; t < g.length; t += 50) {
23769
+ let n = g.slice(t, t + 50);
23770
+ await Promise.all(n.map((t) => e.prepare(`
23771
+ INSERT INTO node_routes (path, channelId, nodeId, treeId, isCanonical, redirectUrl)
23772
+ VALUES ${t.placeholders}
23773
+ `).run(...t.params)));
23706
23774
  }
23707
23775
  console.log(`[Route Generator] Successfully built ${h.length} enterprise routes.`);
23708
23776
  } catch (e) {
@@ -23710,7 +23778,25 @@ async function hx(e) {
23710
23778
  }
23711
23779
  }
23712
23780
  var gx = new e();
23713
- async function _x(e, t, n = []) {
23781
+ function _x(e, t, n = []) {
23782
+ let r = new mx(e.env), i = (async () => {
23783
+ for (let i of n) {
23784
+ 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];
23785
+ await r.purgeInternalWorkerCache(e, t, i, a?.slug, a?.language);
23786
+ }
23787
+ await hx(t), await r.purgeGlobalCacheDirect(e, t);
23788
+ })().catch((e) => {
23789
+ console.error("[Node Routes] Background rebuild/purge failed:", e);
23790
+ });
23791
+ try {
23792
+ let t = e.executionCtx;
23793
+ if (t && typeof t.waitUntil == "function") {
23794
+ t.waitUntil(i);
23795
+ return;
23796
+ }
23797
+ } catch {}
23798
+ }
23799
+ async function vx(e, t, n = []) {
23714
23800
  let r = e.prepare(t);
23715
23801
  if (typeof r.bind == "function") {
23716
23802
  let e = await r.bind(...n).all();
@@ -23722,75 +23808,50 @@ async function _x(e, t, n = []) {
23722
23808
  }
23723
23809
  return [];
23724
23810
  }
23725
- async function vx(e, t, n = []) {
23811
+ async function yx(e, t, n = []) {
23726
23812
  let r = e.prepare(t);
23727
23813
  if (typeof r.bind == "function") return r.bind(...n).run();
23728
23814
  if (typeof r.run == "function") return r.run(...n);
23729
23815
  }
23730
- function yx(e) {
23816
+ function bx(e) {
23731
23817
  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;
23732
23818
  }
23733
- function bx(e) {
23819
+ function xx(e) {
23734
23820
  return +(e === !0 || e === 1 || e === "1" || e === "true");
23735
23821
  }
23736
- function xx(e) {
23822
+ function Sx(e) {
23737
23823
  if (e == null || e === "null" || e === "" || typeof e == "string" && e.startsWith("draft-")) return null;
23738
23824
  let t = Number(e);
23739
23825
  return isNaN(t) ? null : t;
23740
23826
  }
23741
- function Sx(e) {
23827
+ function Cx(e) {
23742
23828
  let t = { ...e };
23743
23829
  delete t.language, delete t.defaultLanguage;
23744
- for (let e of [
23745
- "id",
23746
- "treeNodeId",
23747
- "isNew",
23748
- "_isTreeDraft",
23749
- "_draftParentId",
23750
- "nodeType",
23751
- "contentType",
23752
- "title",
23753
- "slug",
23754
- "path",
23755
- "routePath",
23756
- "hidden",
23757
- "is_hidden",
23758
- "isHidden",
23759
- "status",
23760
- "createdById",
23761
- "updatedById",
23762
- "draftDataJson",
23763
- "publishedDataJson",
23764
- "publishedAt",
23765
- "deletedAt",
23766
- "channelNames",
23767
- "treeNames",
23768
- "hasUnpublishedChanges"
23769
- ]) delete t[e];
23830
+ 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];
23770
23831
  return t;
23771
23832
  }
23772
- function Cx(e, t = /* @__PURE__ */ new Set()) {
23773
- 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;
23833
+ function wx(e, t = /* @__PURE__ */ new Set()) {
23834
+ 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;
23774
23835
  }
23775
- function wx(e, t) {
23836
+ function Tx(e, t) {
23776
23837
  if (!e) return !0;
23777
- 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;
23778
- return n || r || i || a || c;
23838
+ 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;
23839
+ return n || r || i || a || o || s || u;
23779
23840
  }
23780
- async function Tx(e, t, n) {
23841
+ async function Ex(e, t, n) {
23781
23842
  for (let r of n) {
23782
- let n = (await _x(e, "\n SELECT id, storageKeyPrivate, isSystemVariant, parentAssetId, filename\n FROM assets WHERE id = ?\n ", [r]))[0];
23783
- if (n && n.isSystemVariant && !((await _x(e, "SELECT 1 FROM node_assets WHERE assetId = ? LIMIT 1", [n.id])).length > 0)) {
23843
+ let n = (await vx(e, "\n SELECT id, storageKeyPrivate, isSystemVariant, parentAssetId, filename\n FROM assets WHERE id = ?\n ", [r]))[0];
23844
+ if (n && n.isSystemVariant && !((await vx(e, "SELECT 1 FROM node_assets WHERE assetId = ? LIMIT 1", [n.id])).length > 0)) {
23784
23845
  if (n.storageKeyPrivate) try {
23785
23846
  await t.delete(n.storageKeyPrivate);
23786
23847
  } catch (e) {
23787
23848
  console.warn(`[Asset Cleanup] Failed to delete crop ${n.storageKeyPrivate}:`, e);
23788
23849
  }
23789
- await vx(e, "DELETE FROM node_assets WHERE assetId = ?", [n.id]), await vx(e, "DELETE FROM assets WHERE id = ?", [n.id]);
23850
+ await yx(e, "DELETE FROM node_assets WHERE assetId = ?", [n.id]), await yx(e, "DELETE FROM assets WHERE id = ?", [n.id]);
23790
23851
  }
23791
23852
  }
23792
23853
  }
23793
- async function Ex(e, t, n) {
23854
+ async function Dx(e, t, n) {
23794
23855
  let r = {}, i = null;
23795
23856
  if (t) {
23796
23857
  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 || [];
@@ -23839,6 +23900,8 @@ gx.get("/", async (e) => {
23839
23900
  nodeType: i.contentType,
23840
23901
  contentType: i.contentType,
23841
23902
  isHidden: !!i.isHidden,
23903
+ startShowingAt: i.startShowingAt || null,
23904
+ stopShowingAt: i.stopShowingAt || null,
23842
23905
  status: i.status || "draft",
23843
23906
  publishedAt: i.publishedAt || null,
23844
23907
  hasUnpublishedChanges: s,
@@ -23851,7 +23914,7 @@ gx.get("/", async (e) => {
23851
23914
  if (l) try {
23852
23915
  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;
23853
23916
  if (a) {
23854
- let { resolvedLayoutId: e, inheritedFields: r } = await Ex(t, a.parentId, a.treeId);
23917
+ let { resolvedLayoutId: e, inheritedFields: r } = await Dx(t, a.parentId, a.treeId);
23855
23918
  (s === "inherit" || !s) && (s = e);
23856
23919
  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);
23857
23920
  }
@@ -23866,7 +23929,7 @@ gx.get("/", async (e) => {
23866
23929
  let r = t.allowedLayouts;
23867
23930
  return r ? typeof r == "string" ? r === e : !Array.isArray(r) || r.length === 0 || r.includes(e) : !0;
23868
23931
  })(s) && (s = null), (s === "inherit" || !s) && (s = o.defaultLayout || null);
23869
- let u = await fx(t, Sx(n));
23932
+ let u = await fx(t, Cx(n));
23870
23933
  Object.assign(c, u), c.resolvedLayoutId = s;
23871
23934
  } catch {}
23872
23935
  let u = await t.prepare("SELECT channelId FROM node_channels WHERE nodeId = ?").all(r);
@@ -23894,7 +23957,7 @@ gx.get("/", async (e) => {
23894
23957
  blocks: m
23895
23958
  });
23896
23959
  }
23897
- let m = [], h = [o ? "(cn.deletedAt IS NOT NULL AND cn.deletedAt != '')" : "(cn.deletedAt IS NULL OR cn.deletedAt = '')"];
23960
+ let m = [], h = [o ? "cn.deletedAt IS NOT NULL" : "cn.deletedAt IS NULL"];
23898
23961
  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") {
23899
23962
  let e = r.split(",").map((e) => e.trim()).filter(Boolean);
23900
23963
  e.length > 0 && (h.push(`cn.contentType IN (${e.map(() => "?").join(",")})`), m.push(...e));
@@ -23971,6 +24034,8 @@ gx.get("/", async (e) => {
23971
24034
  contentType: e.contentType,
23972
24035
  nodeType: e.contentType,
23973
24036
  isHidden: !!e.isHidden,
24037
+ startShowingAt: e.startShowingAt || null,
24038
+ stopShowingAt: e.stopShowingAt || null,
23974
24039
  status: e.status || "draft",
23975
24040
  publishedAt: e.publishedAt || null,
23976
24041
  hasUnpublishedChanges: n,
@@ -23988,7 +24053,7 @@ gx.get("/", async (e) => {
23988
24053
  otherCount: e.otherCount || 0
23989
24054
  }, i = e.draftDataJson || e.dataJson;
23990
24055
  if (i) try {
23991
- let e = typeof i == "string" ? JSON.parse(i) : i, n = await fx(t, Sx(e));
24056
+ let e = typeof i == "string" ? JSON.parse(i) : i, n = await fx(t, Cx(e));
23992
24057
  Object.assign(r, n);
23993
24058
  } catch {}
23994
24059
  return r;
@@ -24001,34 +24066,34 @@ gx.get("/", async (e) => {
24001
24066
  limit: f
24002
24067
  });
24003
24068
  }), gx.post("/", async (e) => {
24004
- 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;
24005
- if (E) {
24006
- let e = await t.prepare("SELECT dataJson FROM trees WHERE id = ? OR key = ? LIMIT 1").get(Number(E) || -1, String(E));
24069
+ 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;
24070
+ if (te) {
24071
+ let e = await t.prepare("SELECT dataJson FROM trees WHERE id = ? OR key = ? LIMIT 1").get(Number(te) || -1, String(te));
24007
24072
  if (e?.dataJson) try {
24008
24073
  let t = typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson;
24009
- D = t.defaultLanguage?.trim() || t.language?.trim() || null;
24074
+ O = t.defaultLanguage?.trim() || t.language?.trim() || null;
24010
24075
  } catch {}
24011
24076
  }
24012
- if (!D && h && Array.isArray(h) && h.length > 0) {
24013
- let e = typeof h[0] == "object" ? h[0].id : h[0];
24077
+ if (!O && _ && Array.isArray(_) && _.length > 0) {
24078
+ let e = typeof _[0] == "object" ? _[0].id : _[0];
24014
24079
  if (e && e !== "all") {
24015
24080
  let n = await t.prepare("SELECT defaultLanguage, dataJson FROM channels WHERE id = ? LIMIT 1").get(Number(e));
24016
24081
  if (n) {
24017
- if (n.defaultLanguage) D = n.defaultLanguage.trim();
24082
+ if (n.defaultLanguage) O = n.defaultLanguage.trim();
24018
24083
  else if (n.dataJson) try {
24019
24084
  let e = typeof n.dataJson == "string" ? JSON.parse(n.dataJson) : n.dataJson;
24020
- D = e.defaultLanguage?.trim() || e.language?.trim() || null;
24085
+ O = e.defaultLanguage?.trim() || e.language?.trim() || null;
24021
24086
  } catch {}
24022
24087
  }
24023
24088
  }
24024
24089
  }
24025
- T && D && T === D && (T = null);
24026
- let O = a, te = /* @__PURE__ */ new Set(), k = !1, A = "draft", ne = 0, j = s === void 0 ? null : yx(s);
24027
- if (j) {
24090
+ E && O && E === O && (E = null);
24091
+ let k = a, A = /* @__PURE__ */ new Set(), ne = !1, j = "draft", re = 0, ie = s === void 0 ? null : bx(s);
24092
+ if (ie) {
24028
24093
  let n = [];
24029
- if (g !== void 0 && Array.isArray(g) && g.length > 0) for (let e of g) n.push({
24094
+ if (v !== void 0 && Array.isArray(v) && v.length > 0) for (let e of v) n.push({
24030
24095
  treeId: Number(e.treeId),
24031
- parentId: xx(e.parentId ?? e._draftParentId ?? null)
24096
+ parentId: Sx(e.parentId ?? e._draftParentId ?? null)
24032
24097
  });
24033
24098
  else if (a) {
24034
24099
  let e = await t.prepare("SELECT treeId, parentId FROM tree_nodes WHERE contentId = ?").all(a), r = Array.isArray(e) ? e : e?.results || [];
@@ -24038,140 +24103,146 @@ gx.get("/", async (e) => {
24038
24103
  });
24039
24104
  }
24040
24105
  for (let r of n) {
24041
- let n = r.parentId === null ? "tn.parentId IS NULL" : "tn.parentId = ?", i = r.parentId === null ? [r.treeId, j] : [
24106
+ let n = r.parentId === null ? "tn.parentId IS NULL" : "tn.parentId = ?", i = r.parentId === null ? [r.treeId, ie] : [
24042
24107
  r.treeId,
24043
24108
  r.parentId,
24044
- j
24109
+ ie
24045
24110
  ], o = `
24046
24111
  SELECT cn.id FROM tree_nodes tn
24047
24112
  INNER JOIN content_nodes cn ON tn.contentId = cn.id
24048
- WHERE tn.treeId = ? AND ${n} AND cn.slug = ? AND (cn.deletedAt IS NULL OR cn.deletedAt = '')
24113
+ WHERE tn.treeId = ? AND ${n} AND cn.slug = ? AND cn.deletedAt IS NULL
24049
24114
  `;
24050
24115
  if (a && (o += " AND cn.id != ?", i.push(a)), o += " LIMIT 1", await t.prepare(o).get(...i)) return e.json({
24051
- error: `The slug '${j}' is already in use by another page in this section.`,
24116
+ error: `The slug '${ie}' is already in use by another page in this section.`,
24052
24117
  field: "slug"
24053
24118
  }, 409);
24054
24119
  }
24055
24120
  }
24056
24121
  if (a) {
24057
- 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;
24058
- k = wx(e, {
24122
+ 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;
24123
+ ne = Tx(e, {
24059
24124
  title: n,
24060
24125
  slug: r,
24061
24126
  isHidden: u,
24062
- sanitizedFields: v
24127
+ startShowingAt: d,
24128
+ stopShowingAt: f,
24129
+ sanitizedFields: b
24063
24130
  });
24064
- let d = e?.draftDataJson || e?.dataJson || "{}";
24131
+ let p = e?.draftDataJson || e?.dataJson || "{}";
24065
24132
  try {
24066
- Cx(typeof d == "string" ? JSON.parse(d) : d, te);
24133
+ wx(typeof p == "string" ? JSON.parse(p) : p, A);
24067
24134
  } catch {}
24068
- let f = {};
24135
+ let _ = {};
24069
24136
  try {
24070
- f = JSON.parse(d);
24137
+ _ = JSON.parse(p);
24071
24138
  } catch {}
24072
- let p = {
24139
+ let v = {
24073
24140
  title: n,
24074
24141
  slug: r,
24075
24142
  contentType: i,
24076
24143
  language: l,
24077
24144
  isHidden: u,
24145
+ startShowingAt: d,
24146
+ stopShowingAt: f,
24147
+ ...b
24148
+ }, y = JSON.stringify({
24149
+ ..._,
24078
24150
  ...v
24079
- }, h = JSON.stringify({
24080
- ...f,
24081
- ...p
24082
- }), g = !1;
24083
- 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) {
24084
- for (let e of Object.keys(v)) if (JSON.stringify(v[e]) !== JSON.stringify(f[e])) {
24085
- g = !0;
24151
+ }), x = !1;
24152
+ 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) {
24153
+ for (let e of Object.keys(b)) if (JSON.stringify(b[e]) !== JSON.stringify(_[e])) {
24154
+ x = !0;
24086
24155
  break;
24087
24156
  }
24088
24157
  }
24089
- if (!g && m !== void 0) {
24158
+ if (!x && g !== void 0) {
24090
24159
  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 || [];
24091
- if (m.length !== n.length) g = !0;
24092
- else for (let e = 0; e < m.length; e++) {
24093
- let t = m[e], r = n[e], i = t.componentId || t.elementType || "text-block", a = t.region || "content", o = { ...t.data || {} };
24160
+ if (g.length !== n.length) x = !0;
24161
+ else for (let e = 0; e < g.length; e++) {
24162
+ let t = g[e], r = n[e], i = t.componentId || t.elementType || "text-block", a = t.region || "content", o = { ...t.data || {} };
24094
24163
  delete o._instanceId, delete o.blockId;
24095
24164
  let s = {};
24096
24165
  try {
24097
24166
  s = JSON.parse(r.dataJson);
24098
24167
  } catch {}
24099
24168
  if (delete s._instanceId, delete s.blockId, i !== r.elementType || a !== r.region || JSON.stringify(o) !== JSON.stringify(s)) {
24100
- g = !0;
24169
+ x = !0;
24101
24170
  break;
24102
24171
  }
24103
24172
  }
24104
24173
  }
24105
- A = e?.status === "published" || e?.publishedAt ? "published" : "draft";
24106
- let _ = e?.hasUnpublishedChanges === 1 || e?.hasUnpublishedChanges === !0;
24107
- ne = g ? 1 : +!!_;
24108
- 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;
24109
- 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);
24174
+ j = e?.status === "published" || e?.publishedAt ? "published" : "draft";
24175
+ let S = e?.hasUnpublishedChanges === 1 || e?.hasUnpublishedChanges === !0;
24176
+ re = x ? 1 : +!!S;
24177
+ 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;
24178
+ 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);
24110
24179
  } else {
24111
- k = !0;
24112
- let e = {
24180
+ ne = !0;
24181
+ let e = m === void 0 ? null : m, n = h === void 0 ? null : h, r = {
24113
24182
  title: o || "Untitled",
24114
- slug: j,
24115
- contentType: C,
24116
- language: T,
24117
- isHidden: S,
24118
- ...v
24119
- }, 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);
24120
- O = Number(n.lastInsertRowid);
24121
- }
24122
- if (h !== void 0 && Array.isArray(h) && O) {
24123
- await t.prepare("DELETE FROM node_channels WHERE nodeId = ?").run(O);
24124
- 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);
24183
+ slug: ie,
24184
+ contentType: T,
24185
+ language: E,
24186
+ isHidden: w,
24187
+ startShowingAt: e,
24188
+ stopShowingAt: n,
24189
+ ...b
24190
+ }, 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);
24191
+ k = Number(i.lastInsertRowid);
24192
+ }
24193
+ if (_ !== void 0 && Array.isArray(_) && k) {
24194
+ await t.prepare("DELETE FROM node_channels WHERE nodeId = ?").run(k);
24195
+ 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);
24125
24196
  if (e.length > 0) {
24126
- let n = e.map(() => "(?, ?)").join(", "), r = e.flatMap((e) => [O, e]);
24197
+ let n = e.map(() => "(?, ?)").join(", "), r = e.flatMap((e) => [k, e]);
24127
24198
  await t.prepare(`INSERT OR IGNORE INTO node_channels (nodeId, channelId) VALUES ${n}`).run(...r);
24128
24199
  }
24129
24200
  }
24130
- if (g !== void 0 && Array.isArray(g) && g.length > 0 && O) for (let e of g) {
24201
+ if (v !== void 0 && Array.isArray(v) && v.length > 0 && k) for (let e of v) {
24131
24202
  if (!e || !e.treeId) continue;
24132
- 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);
24133
- 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));
24203
+ 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);
24204
+ 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));
24134
24205
  }
24135
- let re = [], ie = [], ae = [];
24136
- if (m !== void 0 && Array.isArray(m) && O) {
24137
- await t.prepare("DELETE FROM content_blocks WHERE contentId = ? AND isDraft = 1").run(O);
24206
+ let ae = [], oe = [], se = [];
24207
+ if (g !== void 0 && Array.isArray(g) && k) {
24208
+ await t.prepare("DELETE FROM content_blocks WHERE contentId = ? AND isDraft = 1").run(k);
24138
24209
  let e = [], n = [];
24139
- for (let t = 0; t < m.length; t++) {
24140
- 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({
24210
+ for (let t = 0; t < g.length; t++) {
24211
+ 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({
24141
24212
  ...a,
24142
24213
  blockId: o,
24143
24214
  _instanceId: o
24144
24215
  });
24145
- c.forEach((e) => re.push({
24216
+ c.forEach((e) => ae.push({
24146
24217
  ...e,
24147
24218
  fieldKey: `blocks[${t}].${e.fieldKey}`
24148
- })), l.forEach((e) => ie.push({
24219
+ })), l.forEach((e) => oe.push({
24149
24220
  ...e,
24150
24221
  fieldKey: `blocks[${t}].${e.fieldKey}`
24151
- })), u.forEach((e) => ae.push({
24222
+ })), u.forEach((e) => se.push({
24152
24223
  ...e,
24153
24224
  fieldKey: `blocks[${t}].${e.fieldKey}`
24154
24225
  }));
24155
24226
  let d = r.region !== void 0 && r.region !== null && String(r.region).trim() !== "" ? String(r.region) : "content";
24156
- e.push("(?, ?, ?, ?, ?, 1)"), n.push(O, t, i, JSON.stringify(s), d);
24227
+ e.push("(?, ?, ?, ?, ?, 1)"), n.push(k, t, i, JSON.stringify(s), d);
24157
24228
  }
24158
24229
  e.length > 0 && await t.prepare(`INSERT INTO content_blocks (contentId, sortOrder, elementType, dataJson, region, isDraft) VALUES ${e.join(", ")}`).run(...n);
24159
24230
  }
24160
- if (O) {
24161
- let n = [...y, ...re], r = [...b, ...ie], i = [...x, ...ae];
24162
- await ox(t, O, n), await sx(t, O, r), await cx(t, O, i);
24163
- let a = new Set(n.map((e) => e.assetId)), o = new Set([...te].filter((e) => !a.has(e)));
24231
+ if (k) {
24232
+ let n = [...x, ...ae], r = [...S, ...oe], i = [...C, ...se];
24233
+ await ox(t, k, n), await sx(t, k, r), await cx(t, k, i);
24234
+ let a = new Set(n.map((e) => e.assetId)), o = new Set([...A].filter((e) => !a.has(e)));
24164
24235
  if (o.size > 0) {
24165
24236
  let { storage: n } = ix(e.env);
24166
- await Tx(t, n, o);
24237
+ await Ex(t, n, o);
24167
24238
  }
24168
24239
  }
24169
24240
  return await $b(e).clear(), e.json({
24170
24241
  success: !0,
24171
- id: O,
24172
- status: A,
24173
- hasUnpublishedChanges: ne === 1 || A === "draft",
24174
- isStructuralChange: k
24242
+ id: k,
24243
+ status: j,
24244
+ hasUnpublishedChanges: re === 1 || j === "draft",
24245
+ isStructuralChange: ne
24175
24246
  });
24176
24247
  }), gx.post("/publish", async (e) => {
24177
24248
  let t = e.get("db"), n = await e.req.json(), r = n.id || n.nodeId;
@@ -24186,34 +24257,36 @@ gx.get("/", async (e) => {
24186
24257
  try {
24187
24258
  c = typeof o.draftDataJson == "string" ? JSON.parse(o.draftDataJson) : o.draftDataJson || {};
24188
24259
  } catch {}
24189
- 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;
24190
- 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);
24191
- 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 || [];
24192
- if (C.length > 0) {
24260
+ 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;
24261
+ 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);
24262
+ 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 || [];
24263
+ if (te.length > 0) {
24193
24264
  let e = [], n = [];
24194
- for (let t of C) {
24265
+ for (let t of te) {
24195
24266
  let r = t.region !== void 0 && t.region !== null && String(t.region).trim() !== "" ? String(t.region) : "content";
24196
24267
  e.push("(?, ?, ?, ?, ?, 0)"), n.push(i, t.sortOrder, t.elementType, t.dataJson, r);
24197
24268
  }
24198
24269
  await t.prepare(`INSERT INTO content_blocks (contentId, sortOrder, elementType, dataJson, region, isDraft) VALUES ${e.join(", ")}`).run(...n);
24199
24270
  }
24200
- let w = ((await t.prepare("SELECT COUNT(*) as count FROM node_revisions WHERE nodeId = ?").get(i))?.count || 0) + 1, T = {
24201
- version: w,
24271
+ let O = ((await t.prepare("SELECT COUNT(*) as count FROM node_revisions WHERE nodeId = ?").get(i))?.count || 0) + 1, k = {
24272
+ version: O,
24202
24273
  publishedAt: (/* @__PURE__ */ new Date()).toISOString(),
24203
24274
  node: {
24204
24275
  ...o,
24205
- dataJson: g
24276
+ dataJson: b
24206
24277
  },
24207
- blocks: C
24278
+ blocks: te
24208
24279
  };
24209
- 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({
24280
+ await t.prepare("INSERT INTO node_revisions (nodeId, version, snapshotJson, createdById) VALUES (?, ?, ?, ?)").run(i, O, JSON.stringify(k), a), await $b(e).clear();
24281
+ let A = new mx(e.env);
24282
+ return y ? _x(e, t, [i]) : A.purgeNode(e, t, i, !1), e.json({
24210
24283
  success: !0,
24211
24284
  id: i,
24212
24285
  status: "published",
24213
- version: w,
24214
- publishedAt: T.publishedAt,
24286
+ version: O,
24287
+ publishedAt: k.publishedAt,
24215
24288
  hasUnpublishedChanges: !1,
24216
- isStructuralChange: h
24289
+ isStructuralChange: y
24217
24290
  });
24218
24291
  }), gx.post("/publish/batch", async (e) => {
24219
24292
  let t = e.get("db"), n = await e.req.json(), r = n.ids;
@@ -24232,33 +24305,33 @@ gx.get("/", async (e) => {
24232
24305
  try {
24233
24306
  l = typeof s.draftDataJson == "string" ? JSON.parse(s.draftDataJson) : s.draftDataJson || {};
24234
24307
  } catch {}
24235
- 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();
24236
- (u !== "" && d !== "" && u !== d || f !== "" && p !== "" && f !== p || m !== "" && h !== "" && m !== h) && (a = !0);
24237
- 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;
24238
- 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);
24239
- 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 || [];
24240
- if (C.length > 0) {
24308
+ 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 ?? "";
24309
+ (u !== "" && d !== "" && u !== d || f !== "" && p !== "" && f !== p || m !== "" && h !== "" && m !== h || g !== _ || v !== y) && (a = !0);
24310
+ 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;
24311
+ 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);
24312
+ 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 || [];
24313
+ if (te.length > 0) {
24241
24314
  let e = [], n = [];
24242
- for (let t of C) {
24315
+ for (let t of te) {
24243
24316
  let i = t.region !== void 0 && t.region !== null && String(t.region).trim() !== "" ? String(t.region) : "content";
24244
24317
  e.push("(?, ?, ?, ?, ?, 0)"), n.push(r, t.sortOrder, t.elementType, t.dataJson, i);
24245
24318
  }
24246
24319
  await t.prepare(`INSERT INTO content_blocks (contentId, sortOrder, elementType, dataJson, region, isDraft) VALUES ${e.join(", ")}`).run(...n);
24247
24320
  }
24248
- let w = ((await t.prepare("SELECT COUNT(*) as count FROM node_revisions WHERE nodeId = ?").get(r))?.count || 0) + 1, T = {
24249
- version: w,
24321
+ let O = ((await t.prepare("SELECT COUNT(*) as count FROM node_revisions WHERE nodeId = ?").get(r))?.count || 0) + 1, k = {
24322
+ version: O,
24250
24323
  publishedAt: (/* @__PURE__ */ new Date()).toISOString(),
24251
24324
  node: {
24252
24325
  ...s,
24253
- dataJson: g
24326
+ dataJson: b
24254
24327
  },
24255
- blocks: C
24328
+ blocks: te
24256
24329
  };
24257
- await t.prepare("INSERT INTO node_revisions (nodeId, version, snapshotJson, createdById) VALUES (?, ?, ?, ?)").run(r, w, JSON.stringify(T), i), o.push(r);
24330
+ await t.prepare("INSERT INTO node_revisions (nodeId, version, snapshotJson, createdById) VALUES (?, ?, ?, ?)").run(r, O, JSON.stringify(k), i), o.push(r);
24258
24331
  }
24259
24332
  await $b(e).clear();
24260
24333
  let s = new mx(e.env);
24261
- if (a) await hx(t), s.purgeGlobalCache(e, t);
24334
+ if (a) _x(e, t, o);
24262
24335
  else for (let n of o) s.purgeNode(e, t, n, !1);
24263
24336
  return e.json({
24264
24337
  success: !0,
@@ -24270,13 +24343,13 @@ gx.get("/", async (e) => {
24270
24343
  let t = e.get("db"), n = e.req.query("id");
24271
24344
  if (!n) return e.json({ error: "Node ID required" }, 400);
24272
24345
  let r = Number(n);
24273
- 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({
24346
+ 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({
24274
24347
  success: !0,
24275
24348
  deletedNodeId: r
24276
24349
  });
24277
24350
  }), gx.post("/restore", async (e) => {
24278
24351
  let t = e.get("db"), n = await e.req.json(), r = Number(n.id);
24279
- 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({
24352
+ 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({
24280
24353
  success: !0,
24281
24354
  restoredNodeId: r
24282
24355
  })) : e.json({ error: "Node not found" }, 404) : e.json({ error: "Node ID required" }, 400);
@@ -24284,7 +24357,7 @@ gx.get("/", async (e) => {
24284
24357
  let t = e.get("db"), n = e.req.query("id");
24285
24358
  if (!n) return e.json({ error: "Node ID required" }, 400);
24286
24359
  let r = Number(n);
24287
- 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({
24360
+ 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({
24288
24361
  success: !0,
24289
24362
  purgedNodeId: r
24290
24363
  });
@@ -24299,7 +24372,7 @@ gx.get("/", async (e) => {
24299
24372
  } catch {}
24300
24373
  return {
24301
24374
  version: e.version,
24302
- publishedAt: t || new DatetoISOString(),
24375
+ publishedAt: t || (/* @__PURE__ */ new Date()).toISOString(),
24303
24376
  createdById: e.createdById
24304
24377
  };
24305
24378
  });
@@ -24357,13 +24430,16 @@ gx.get("/", async (e) => {
24357
24430
  let t = JSON.stringify(e);
24358
24431
  s += ", dataJson = ?, publishedDataJson = ?", c.push(t, t);
24359
24432
  }
24360
- 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({
24433
+ s += " WHERE id = ?", c.push(n), await t.prepare(s).run(...c), await $b(e).clear();
24434
+ let u = await new mx(e.env).purgeVisibilityChange(e, t, n);
24435
+ return e.json({
24361
24436
  success: !0,
24362
- isHidden: i
24437
+ isHidden: i,
24438
+ cacheInvalidated: u
24363
24439
  });
24364
24440
  });
24365
- var Dx = new e();
24366
- function Ox(e, t = null) {
24441
+ var Ox = new e();
24442
+ function kx(e, t = null) {
24367
24443
  let n = [];
24368
24444
  for (let r = 0; r < e.length; r++) {
24369
24445
  let i = e[r];
@@ -24375,19 +24451,19 @@ function Ox(e, t = null) {
24375
24451
  id: o,
24376
24452
  parentId: t,
24377
24453
  sortOrder: r
24378
- }), i.children && Array.isArray(i.children) && i.children.length > 0 && n.push(...Ox(i.children, o)));
24454
+ }), i.children && Array.isArray(i.children) && i.children.length > 0 && n.push(...kx(i.children, o)));
24379
24455
  }
24380
24456
  return n;
24381
24457
  }
24382
- function kx(e) {
24458
+ function Ax(e) {
24383
24459
  if (e == null || e === "null" || e === "" || typeof e == "string" && e.startsWith("draft-")) return null;
24384
24460
  let t = Number(e);
24385
24461
  return isNaN(t) ? null : t;
24386
24462
  }
24387
- function Ax(e) {
24463
+ function jx(e) {
24388
24464
  return +(e === !0 || e === 1 || e === "1" || e === "true");
24389
24465
  }
24390
- Dx.get("/tree.json", async (e) => {
24466
+ Ox.get("/tree.json", async (e) => {
24391
24467
  try {
24392
24468
  let t = e.get("db"), n = e.req.query("treeId") || "main-nav", r = e.req.query("preview") === "true", i = 1;
24393
24469
  if (isNaN(Number(n))) {
@@ -24398,7 +24474,7 @@ Dx.get("/tree.json", async (e) => {
24398
24474
  e && e.id && (i = Number(e.id));
24399
24475
  }
24400
24476
  } else i = Number(n);
24401
- 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();
24477
+ 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();
24402
24478
  for (let e of o) {
24403
24479
  let t = e.contentId;
24404
24480
  c.has(t) || (c.add(t), s.push(e));
@@ -24440,7 +24516,7 @@ Dx.get("/tree.json", async (e) => {
24440
24516
  } catch (t) {
24441
24517
  return console.error("[CMS Tree API] GET Error:", t), e.json({ error: t.message || "Failed to fetch tree" }, 500);
24442
24518
  }
24443
- }), Dx.post("/tree.json", async (e) => {
24519
+ }), Ox.post("/tree.json", async (e) => {
24444
24520
  try {
24445
24521
  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;
24446
24522
  if (isNaN(Number(r))) {
@@ -24452,7 +24528,7 @@ Dx.get("/tree.json", async (e) => {
24452
24528
  }
24453
24529
  } else o = Number(r);
24454
24530
  if (n.tree && Array.isArray(n.tree)) {
24455
- let r = Ox(n.tree, null);
24531
+ let r = kx(n.tree, null);
24456
24532
  if (r.length > 0) for (let e = 0; e < r.length; e += 50) {
24457
24533
  let n = r.slice(e, e + 50), i = n.map((e) => e.id), a = i.map(() => "?").join(","), s = "UPDATE tree_nodes SET \n";
24458
24534
  s += "parentId = CASE contentId \n", n.forEach(() => {
@@ -24472,9 +24548,9 @@ Dx.get("/tree.json", async (e) => {
24472
24548
  reorderedCount: r.length
24473
24549
  });
24474
24550
  }
24475
- 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);
24551
+ 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);
24476
24552
  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;
24477
- let g = kx(u), _ = e.get("user")?.id || null;
24553
+ let g = Ax(u), _ = e.get("user")?.id || null;
24478
24554
  if (s === "create") {
24479
24555
  let r = m.slug || n.slug || c, a = r ? String(r).toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "") : null;
24480
24556
  if (a) {
@@ -24582,7 +24658,7 @@ Dx.get("/tree.json", async (e) => {
24582
24658
  details: t.message
24583
24659
  }, 500);
24584
24660
  }
24585
- }), Dx.get("/trees.json", async (e) => {
24661
+ }), Ox.get("/trees.json", async (e) => {
24586
24662
  try {
24587
24663
  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) => {
24588
24664
  let n = Number(t.treeId), r = Number(t.channelId);
@@ -24612,7 +24688,7 @@ Dx.get("/tree.json", async (e) => {
24612
24688
  } catch {
24613
24689
  return e.json([]);
24614
24690
  }
24615
- }), Dx.post("/trees.json", async (e) => {
24691
+ }), Ox.post("/trees.json", async (e) => {
24616
24692
  try {
24617
24693
  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 };
24618
24694
  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({
@@ -24651,7 +24727,7 @@ Dx.get("/tree.json", async (e) => {
24651
24727
  } catch (t) {
24652
24728
  return console.error("[API Trees] Error saving tree:", t), e.json({ error: t.message || "Failed to save tree" }, 500);
24653
24729
  }
24654
- }), Dx.delete("/trees.json", async (e) => {
24730
+ }), Ox.delete("/trees.json", async (e) => {
24655
24731
  let t = e.get("db"), n = e.req.query("id");
24656
24732
  if (!n) return e.json({ error: "Tree ID required" }, 400);
24657
24733
  let r = Number(n);
@@ -24664,8 +24740,8 @@ Dx.get("/tree.json", async (e) => {
24664
24740
  return e.json({ error: "Failed to delete tree" }, 500);
24665
24741
  }
24666
24742
  });
24667
- var jx = new e();
24668
- jx.get("/", async (e) => {
24743
+ var Mx = new e();
24744
+ Mx.get("/", async (e) => {
24669
24745
  try {
24670
24746
  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) => {
24671
24747
  e[t.channelId] || (e[t.channelId] = []);
@@ -24731,27 +24807,27 @@ jx.get("/", async (e) => {
24731
24807
  error: t.message
24732
24808
  }, 500);
24733
24809
  }
24734
- }), jx.post("/", async (e) => {
24810
+ }), Mx.post("/", async (e) => {
24735
24811
  try {
24736
24812
  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 || "";
24737
24813
  typeof T == "object" && T && (T = T.value || T.id || ""), T = String(T).trim();
24738
- 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;
24814
+ 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;
24739
24815
  if (await t.prepare("SELECT id FROM channels WHERE key = ? AND id != ? LIMIT 1").get(C, a ?? -1)) return e.json({
24740
24816
  error: `Channel API key "${C}" is already in use.`,
24741
24817
  field: "key"
24742
24818
  }, 409);
24743
- let te = a;
24744
- 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);
24819
+ let O = a;
24820
+ 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);
24745
24821
  else {
24746
- 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;
24822
+ 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;
24747
24823
  if (!n || !n.id) throw Error("Failed to retrieve newly created Channel ID from Cloudflare D1.");
24748
- te = Number(n.id);
24824
+ O = Number(n.id);
24749
24825
  }
24750
- await t.prepare("DELETE FROM channel_trees WHERE channelId = ?").run(te);
24826
+ await t.prepare("DELETE FROM channel_trees WHERE channelId = ?").run(O);
24751
24827
  let k = E.filter((e) => e && e.treeId && e.key);
24752
24828
  if (k.length > 0) {
24753
24829
  let e = k.map(() => "(?, ?, ?, ?)").join(", "), n = k.flatMap((e) => [
24754
- te,
24830
+ O,
24755
24831
  Number(e.treeId) || e.treeId,
24756
24832
  String(e.key).trim(),
24757
24833
  JSON.stringify(e.meta || {})
@@ -24762,9 +24838,9 @@ jx.get("/", async (e) => {
24762
24838
  `).run(...n);
24763
24839
  }
24764
24840
  let A = $b(e);
24765
- 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({
24841
+ 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({
24766
24842
  success: !0,
24767
- id: te
24843
+ id: O
24768
24844
  });
24769
24845
  } catch (t) {
24770
24846
  return console.error("[API Channels] Error saving channel:", t), e.json({
@@ -24772,7 +24848,7 @@ jx.get("/", async (e) => {
24772
24848
  details: t.message
24773
24849
  }, 500);
24774
24850
  }
24775
- }), jx.delete("/", async (e) => {
24851
+ }), Mx.delete("/", async (e) => {
24776
24852
  let t = e.get("db"), n = e.req.query("id");
24777
24853
  if (!n) return e.json({ error: "Channel ID required" }, 400);
24778
24854
  let r = Number(n);
@@ -24790,15 +24866,15 @@ jx.get("/", async (e) => {
24790
24866
  }, 500);
24791
24867
  }
24792
24868
  });
24793
- var Mx = new e();
24794
- function Nx(e) {
24869
+ var Nx = new e();
24870
+ function Px(e) {
24795
24871
  return e.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().trim().replace(/[^a-z0-9\s-]/g, "").replace(/[\s-]+/g, "-").replace(/^-+|-+$/g, "");
24796
24872
  }
24797
- function Px(e) {
24873
+ function Fx(e) {
24798
24874
  let t = (e || "").trim().toLowerCase(), n = px()?.taxonomies || {};
24799
24875
  return n[t] ? t : n[`${t}s`] ? `${t}s` : t.endsWith("s") && n[t.slice(0, -1)] ? t.slice(0, -1) : t;
24800
24876
  }
24801
- async function Fx(e, t, n = []) {
24877
+ async function Ix(e, t, n = []) {
24802
24878
  let r = e.prepare(t);
24803
24879
  if (typeof r.bind == "function") {
24804
24880
  let e = await r.bind(...n).all();
@@ -24810,10 +24886,10 @@ async function Fx(e, t, n = []) {
24810
24886
  }
24811
24887
  return [];
24812
24888
  }
24813
- Mx.get("/:taxonomy", async (e) => {
24814
- let t = e.get("db"), n = Px(e.req.param("taxonomy"));
24889
+ Nx.get("/:taxonomy", async (e) => {
24890
+ let t = e.get("db"), n = Fx(e.req.param("taxonomy"));
24815
24891
  try {
24816
- 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) => ({
24892
+ 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) => ({
24817
24893
  ...e,
24818
24894
  data: e.dataJson ? JSON.parse(e.dataJson) : {}
24819
24895
  }));
@@ -24824,12 +24900,12 @@ Mx.get("/:taxonomy", async (e) => {
24824
24900
  } catch (t) {
24825
24901
  return console.error("[Taxonomy API] Error fetching terms:", t), e.json({ error: "Failed to fetch taxonomy terms" }, 500);
24826
24902
  }
24827
- }), Mx.post("/:taxonomy", async (e) => {
24828
- let t = e.get("db"), n = Px(e.req.param("taxonomy")), r = await e.req.json(), i = r.label?.trim();
24903
+ }), Nx.post("/:taxonomy", async (e) => {
24904
+ let t = e.get("db"), n = Fx(e.req.param("taxonomy")), r = await e.req.json(), i = r.label?.trim();
24829
24905
  if (!i) return e.json({ error: "Label is required" }, 400);
24830
- 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) : "{}";
24906
+ 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) : "{}";
24831
24907
  try {
24832
- 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);
24908
+ 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);
24833
24909
  let r = t.prepare("\n INSERT INTO taxonomy_terms (taxonomy, key, label, parentId, sortOrder, dataJson)\n VALUES (?, ?, ?, ?, ?, ?)\n "), l;
24834
24910
  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({
24835
24911
  success: !0,
@@ -24838,12 +24914,12 @@ Mx.get("/:taxonomy", async (e) => {
24838
24914
  } catch (t) {
24839
24915
  return console.error("[Taxonomy API] Error creating term:", t), e.json({ error: "Failed to create taxonomy term" }, 500);
24840
24916
  }
24841
- }), Mx.put("/:taxonomy/:id", async (e) => {
24842
- let t = e.get("db"), n = Px(e.req.param("taxonomy")), r = Number(e.req.param("id"));
24917
+ }), Nx.put("/:taxonomy/:id", async (e) => {
24918
+ let t = e.get("db"), n = Fx(e.req.param("taxonomy")), r = Number(e.req.param("id"));
24843
24919
  if (isNaN(r)) return e.json({ error: "Invalid term ID" }, 400);
24844
24920
  let i = await e.req.json();
24845
24921
  try {
24846
- let a = await Fx(t, "SELECT * FROM taxonomy_terms WHERE id = ? AND taxonomy = ?", [r, n]);
24922
+ let a = await Ix(t, "SELECT * FROM taxonomy_terms WHERE id = ? AND taxonomy = ?", [r, n]);
24847
24923
  if (a.length === 0) return e.json({ error: "Term not found" }, 404);
24848
24924
  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;
24849
24925
  if (i.data) {
@@ -24853,14 +24929,14 @@ Mx.get("/:taxonomy", async (e) => {
24853
24929
  ...i.data
24854
24930
  });
24855
24931
  }
24856
- 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);
24932
+ 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);
24857
24933
  let f = t.prepare("\n UPDATE taxonomy_terms \n SET label = ?, key = ?, parentId = ?, sortOrder = ?, dataJson = ?, updatedAt = CURRENT_TIMESTAMP\n WHERE id = ?\n ");
24858
24934
  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 });
24859
24935
  } catch (t) {
24860
24936
  return console.error("[Taxonomy API] Error updating term:", t), e.json({ error: "Failed to update taxonomy term" }, 500);
24861
24937
  }
24862
- }), Mx.delete("/:taxonomy/:id", async (e) => {
24863
- let t = e.get("db"), n = Px(e.req.param("taxonomy")), r = Number(e.req.param("id"));
24938
+ }), Nx.delete("/:taxonomy/:id", async (e) => {
24939
+ let t = e.get("db"), n = Fx(e.req.param("taxonomy")), r = Number(e.req.param("id"));
24864
24940
  if (isNaN(r)) return e.json({ error: "Invalid term ID" }, 400);
24865
24941
  try {
24866
24942
  let i = t.prepare("DELETE FROM taxonomy_terms WHERE id = ? AND taxonomy = ?");
@@ -24869,20 +24945,20 @@ Mx.get("/:taxonomy", async (e) => {
24869
24945
  return console.error("[Taxonomy API] Error deleting term:", t), e.json({ error: "Failed to delete taxonomy term" }, 500);
24870
24946
  }
24871
24947
  });
24872
- var Ix = null, Lx = null;
24948
+ var Lx = null, Rx = null;
24873
24949
  if (typeof process < "u" && process?.versions?.node) try {
24874
24950
  let e = i(import.meta.url);
24875
- Ix = e("node:fs"), Lx = e("node:path");
24951
+ Lx = e("node:fs"), Rx = e("node:path");
24876
24952
  } catch {}
24877
- function Rx(e, t = "") {
24953
+ function zx(e, t = "") {
24878
24954
  let n = e.split(/[\\/]/).pop() || "";
24879
24955
  return t && n.endsWith(t) ? n.slice(0, -t.length) : n;
24880
24956
  }
24881
- function zx(e) {
24957
+ function Bx(e) {
24882
24958
  let t = e.match(/\.[^.\\/]+$/);
24883
24959
  return t ? t[0] : "";
24884
24960
  }
24885
- var Bx = {
24961
+ var Vx = {
24886
24962
  nodes: {},
24887
24963
  trees: {},
24888
24964
  blocks: {},
@@ -24892,10 +24968,10 @@ var Bx = {
24892
24968
  nodeLayouts: {},
24893
24969
  blockLayouts: {}
24894
24970
  };
24895
- function Vx(e) {
24971
+ function Hx(e) {
24896
24972
  return e ? typeof e == "string" ? e.trim() : Array.isArray(e) ? e.includes("*") ? "*" : e : "*" : "*";
24897
24973
  }
24898
- function Hx(e = {}, t = {}) {
24974
+ function Ux(e = {}, t = {}) {
24899
24975
  let n = {
24900
24976
  ...e,
24901
24977
  ...t,
@@ -24907,62 +24983,62 @@ function Hx(e = {}, t = {}) {
24907
24983
  };
24908
24984
  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;
24909
24985
  }
24910
- function Ux(e) {
24986
+ function Wx(e) {
24911
24987
  if (!e || typeof e != "object") return e;
24912
- if (Array.isArray(e)) return e.map(Ux);
24988
+ if (Array.isArray(e)) return e.map(Wx);
24913
24989
  let t = {};
24914
24990
  for (let [n, r] of Object.entries(e)) if (n === "<<" || n === "<<:") {
24915
- let e = Ux(r);
24991
+ let e = Wx(r);
24916
24992
  if (typeof e == "object" && e) {
24917
24993
  if (Array.isArray(e)) for (let n of e) Object.assign(t, n);
24918
24994
  else Object.assign(t, e);
24919
24995
  }
24920
- } else t[n] = Ux(r);
24996
+ } else t[n] = Wx(r);
24921
24997
  return t;
24922
24998
  }
24923
- function Wx(e, t) {
24924
- return e ? Ux(n.parseDocument(e, { customTags: [{
24999
+ function Gx(e, t) {
25000
+ return e ? Wx(n.parseDocument(e, { customTags: [{
24925
25001
  tag: "!include",
24926
25002
  resolve(e) {
24927
- let n = (typeof e == "string" ? e : String(e?.strValue || e?.value || "")).trim(), r = Rx(n);
25003
+ let n = (typeof e == "string" ? e : String(e?.strValue || e?.value || "")).trim(), r = zx(n);
24928
25004
  if (!r) return n;
24929
25005
  if (t && t.fieldSets) {
24930
25006
  let e = Object.keys(t.fieldSets).find((e) => e.endsWith("/" + r) || e === r);
24931
- if (e) return Wx(t.fieldSets[e], t);
25007
+ if (e) return Gx(t.fieldSets[e], t);
24932
25008
  }
24933
25009
  return n;
24934
25010
  }
24935
25011
  }] }).toJS() || {}) : {};
24936
25012
  }
24937
- function Gx(e, t = /* @__PURE__ */ new Set()) {
24938
- if (!Ix || !Lx) return {};
24939
- let r = Lx.resolve(e);
24940
- if (t.has(r) || (t.add(r), !Ix.existsSync(r))) return {};
24941
- let i = Ix.readFileSync(r, "utf-8");
24942
- return Ux(n.parseDocument(i, { customTags: [{
25013
+ function Kx(e, t = /* @__PURE__ */ new Set()) {
25014
+ if (!Lx || !Rx) return {};
25015
+ let r = Rx.resolve(e);
25016
+ if (t.has(r) || (t.add(r), !Lx.existsSync(r))) return {};
25017
+ let i = Lx.readFileSync(r, "utf-8");
25018
+ return Wx(n.parseDocument(i, { customTags: [{
24943
25019
  tag: "!include",
24944
25020
  resolve(e) {
24945
25021
  let n = (typeof e == "string" ? e : String(e?.strValue || e?.value || "")).trim();
24946
- return n ? Gx(Lx.resolve(Lx.dirname(r), n), new Set(t)) : {};
25022
+ return n ? Kx(Rx.resolve(Rx.dirname(r), n), new Set(t)) : {};
24947
25023
  }
24948
25024
  }] }).toJS() || {});
24949
25025
  }
24950
- function Kx() {
24951
- if (!Ix || !Lx || typeof process > "u" || !process?.versions?.node) return null;
25026
+ function qx() {
25027
+ if (!Lx || !Rx || typeof process > "u" || !process?.versions?.node) return null;
24952
25028
  try {
24953
25029
  let e = process.cwd(), t = "", n = [
24954
- Lx.resolve(e, "content/definitions"),
24955
- Lx.resolve(e, "content"),
24956
- Lx.resolve(e, "definitions"),
24957
- Lx.resolve(e, "kama-worker/content/definitions")
25030
+ Rx.resolve(e, "content/definitions"),
25031
+ Rx.resolve(e, "content"),
25032
+ Rx.resolve(e, "definitions"),
25033
+ Rx.resolve(e, "kama-worker/content/definitions")
24958
25034
  ];
24959
25035
  try {
24960
25036
  if (import.meta.url) {
24961
- let e = Lx.dirname(r(import.meta.url));
24962
- n.push(Lx.resolve(e, "../../content/definitions")), n.push(Lx.resolve(e, "../content/definitions"));
25037
+ let e = Rx.dirname(r(import.meta.url));
25038
+ n.push(Rx.resolve(e, "../../content/definitions")), n.push(Rx.resolve(e, "../content/definitions"));
24963
25039
  }
24964
25040
  } catch {}
24965
- for (let e of n) if (Ix.existsSync(e)) {
25041
+ for (let e of n) if (Lx.existsSync(e)) {
24966
25042
  t = e;
24967
25043
  break;
24968
25044
  }
@@ -24970,19 +25046,19 @@ function Kx() {
24970
25046
  let i = (e) => {
24971
25047
  let n = "";
24972
25048
  for (let r of e) {
24973
- let e = Lx.join(t, r);
24974
- if (Ix.existsSync(e)) {
25049
+ let e = Rx.join(t, r);
25050
+ if (Lx.existsSync(e)) {
24975
25051
  n = e;
24976
25052
  break;
24977
25053
  }
24978
25054
  }
24979
25055
  if (!n) return {};
24980
- let r = {}, i = Ix.readdirSync(n);
25056
+ let r = {}, i = Lx.readdirSync(n);
24981
25057
  for (let e of i) {
24982
25058
  if (!e.endsWith(".yaml") && !e.endsWith(".yml")) continue;
24983
- let t = Lx.join(n, e), i = Rx(e, zx(e));
25059
+ let t = Rx.join(n, e), i = zx(e, Bx(e));
24984
25060
  try {
24985
- r[i] = Gx(t);
25061
+ r[i] = Kx(t);
24986
25062
  } catch (t) {
24987
25063
  console.error(`❌ Error parsing ${e}:`, t.message);
24988
25064
  }
@@ -25011,59 +25087,59 @@ function Kx() {
25011
25087
  return console.error("❌ Exception inside readLocalFsBundle:", e), null;
25012
25088
  }
25013
25089
  }
25014
- var qx = null, Jx = null;
25015
- function Yx(e) {
25016
- if (!e) qx = null, Jx = null;
25017
- else if (qx && Jx === e) return qx;
25018
- let t = Xx(e);
25019
- return qx = t, Jx = e, t;
25020
- }
25090
+ var Jx = null, Yx = null;
25021
25091
  function Xx(e) {
25092
+ if (!e) Jx = null, Yx = null;
25093
+ else if (Jx && Yx === e) return Jx;
25094
+ let t = Zx(e);
25095
+ return Jx = t, Yx = e, t;
25096
+ }
25097
+ function Zx(e) {
25022
25098
  if (e) {
25023
25099
  let t = {
25024
25100
  nodes: {
25025
25101
  ...e.nodes || e.rawNodes || {},
25026
- ...Bx.nodes
25102
+ ...Vx.nodes
25027
25103
  },
25028
25104
  trees: {
25029
25105
  ...e.trees || e.rawTrees || {},
25030
- ...Bx.trees
25106
+ ...Vx.trees
25031
25107
  },
25032
25108
  channels: {
25033
25109
  ...e.channels || e.rawChannels || {},
25034
- ...Bx.channels
25110
+ ...Vx.channels
25035
25111
  },
25036
25112
  taxonomies: {
25037
25113
  ...e.taxonomies || e.rawTaxonomies || {},
25038
- ...Bx.taxonomies
25114
+ ...Vx.taxonomies
25039
25115
  },
25040
25116
  blocks: {
25041
25117
  ...e.blocks || e.rawBlocks || {},
25042
- ...Bx.blocks
25118
+ ...Vx.blocks
25043
25119
  },
25044
25120
  nodeLayouts: {
25045
25121
  ...e.nodeLayouts || e.rawNodeLayouts || {},
25046
- ...Bx.nodeLayouts
25122
+ ...Vx.nodeLayouts
25047
25123
  },
25048
25124
  blockLayouts: {
25049
25125
  ...e.blockLayouts || e.rawBlockLayouts || {},
25050
- ...Bx.blockLayouts
25126
+ ...Vx.blockLayouts
25051
25127
  },
25052
25128
  fieldSets: {
25053
25129
  ...e.fieldSets || e.rawFieldSets || {},
25054
- ...Bx.fieldSets
25130
+ ...Vx.fieldSets
25055
25131
  }
25056
25132
  };
25057
25133
  if (typeof Object.values(t.nodes)[0] == "string") {
25058
25134
  let e = (e) => {
25059
25135
  let n = {};
25060
25136
  for (let [r, i] of Object.entries(e || {})) {
25061
- let e = Rx(r, zx(r));
25062
- n[e] = Wx(i, t);
25137
+ let e = zx(r, Bx(r));
25138
+ n[e] = Gx(i, t);
25063
25139
  }
25064
25140
  return n;
25065
25141
  };
25066
- return Zx({
25142
+ return Qx({
25067
25143
  rawNodes: e(t.nodes),
25068
25144
  rawTrees: e(t.trees),
25069
25145
  rawChannels: e(t.channels),
@@ -25074,12 +25150,12 @@ function Xx(e) {
25074
25150
  rawFieldSets: e(t.fieldSets)
25075
25151
  });
25076
25152
  }
25077
- return Zx(t);
25153
+ return Qx(t);
25078
25154
  }
25079
- let t = Kx();
25080
- return t && Object.keys(t.rawNodes || {}).length > 0 ? Zx(t) : Zx(null);
25155
+ let t = qx();
25156
+ return t && Object.keys(t.rawNodes || {}).length > 0 ? Qx(t) : Qx(null);
25081
25157
  }
25082
- function Zx(e) {
25158
+ function Qx(e) {
25083
25159
  if (!e) return {
25084
25160
  nodes: {},
25085
25161
  trees: {},
@@ -25094,7 +25170,7 @@ function Zx(e) {
25094
25170
  channelTemplate: null,
25095
25171
  userTemplate: null
25096
25172
  };
25097
- 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 = {
25173
+ 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 = {
25098
25174
  ...p,
25099
25175
  ...f
25100
25176
  }, A = (e, t = "settings", n, r) => {
@@ -25111,11 +25187,11 @@ function Zx(e) {
25111
25187
  fields: {}
25112
25188
  }), Object.entries(s).forEach(([e, r]) => {
25113
25189
  let i = n[t].fields[e] || {};
25114
- n[t].fields[e] = Hx(i, r);
25190
+ n[t].fields[e] = Ux(i, r);
25115
25191
  });
25116
25192
  } else Object.entries(s).forEach(([e, t]) => {
25117
25193
  let n = i[e] || {};
25118
- i[e] = Hx(n, t);
25194
+ i[e] = Ux(n, t);
25119
25195
  });
25120
25196
  };
25121
25197
  return !Array.isArray(e) && typeof e == "object" && e ? (Object.entries(e).forEach(([e, t]) => {
@@ -25124,15 +25200,15 @@ function Zx(e) {
25124
25200
  a(String(t));
25125
25201
  return;
25126
25202
  }
25127
- let n = i[e] || te[e] || {};
25128
- i[e] = Hx(n, typeof t == "object" && t ? t : { label: String(t) });
25203
+ let n = i[e] || O[e] || {};
25204
+ i[e] = Ux(n, typeof t == "object" && t ? t : { label: String(t) });
25129
25205
  }), i) : (Array.isArray(e) && e.forEach((e) => {
25130
25206
  if (typeof e == "string") {
25131
25207
  if (e.includes("/") || e.endsWith(".yaml") || e.endsWith(".yml")) return;
25132
25208
  if (e.startsWith("fieldSet:")) a(e.replace("fieldSet:", "").trim());
25133
25209
  else {
25134
- let t = i[e] || te[e] || {};
25135
- i[e] = Hx(t, {
25210
+ let t = i[e] || O[e] || {};
25211
+ i[e] = Ux(t, {
25136
25212
  type: "text",
25137
25213
  label: e
25138
25214
  });
@@ -25140,8 +25216,8 @@ function Zx(e) {
25140
25216
  } else typeof e == "object" && e && Object.entries(e).forEach(([e, t]) => {
25141
25217
  if (e === "fieldSet") a(String(t));
25142
25218
  else if (e !== "<<" && e !== "<<:") {
25143
- let n = i[e] || te[e] || {};
25144
- i[e] = Hx(n, typeof t == "object" && t ? t : {});
25219
+ let n = i[e] || O[e] || {};
25220
+ i[e] = Ux(n, typeof t == "object" && t ? t : {});
25145
25221
  }
25146
25222
  });
25147
25223
  }), i);
@@ -25159,7 +25235,7 @@ function Zx(e) {
25159
25235
  let s = A(i.fields || i, a, n, t);
25160
25236
  Object.entries(s).forEach(([e, t]) => {
25161
25237
  let r = n[a].fields[e] || {};
25162
- n[a].fields[e] = Hx(r, t);
25238
+ n[a].fields[e] = Ux(r, t);
25163
25239
  });
25164
25240
  }
25165
25241
  }), n) : (Object.entries(e).forEach(([e, r]) => {
@@ -25175,7 +25251,7 @@ function Zx(e) {
25175
25251
  Object.entries(s).forEach(([t, r]) => {
25176
25252
  if (t === "<<" || t === "<<:" || t === "label") return;
25177
25253
  let i = n[e].fields[t] || {};
25178
- n[e].fields[t] = Hx(i, r);
25254
+ n[e].fields[t] = Ux(i, r);
25179
25255
  });
25180
25256
  }), n);
25181
25257
  }, j = {};
@@ -25193,16 +25269,16 @@ function Zx(e) {
25193
25269
  fields: {}
25194
25270
  }), Object.entries(o).forEach(([e, r]) => {
25195
25271
  let i = n[t].fields[e] || {};
25196
- n[t].fields[e] = Hx(i, r);
25272
+ n[t].fields[e] = Ux(i, r);
25197
25273
  });
25198
25274
  } else Object.entries(o).forEach(([e, t]) => {
25199
- let n = r[e] || te[e] || {};
25200
- r[e] = Hx(n, t);
25275
+ let n = r[e] || O[e] || {};
25276
+ r[e] = Ux(n, t);
25201
25277
  });
25202
25278
  }), Object.values(n).forEach((e) => {
25203
25279
  Object.entries(e.fields).forEach(([e, t]) => {
25204
25280
  let n = r[e] || {};
25205
- r[e] = Hx(n, t);
25281
+ r[e] = Ux(n, t);
25206
25282
  });
25207
25283
  }), Object.keys(n).length === 0 && Object.keys(r).length > 0 && (n.settings = {
25208
25284
  label: t.label || "Settings",
@@ -25215,8 +25291,8 @@ function Zx(e) {
25215
25291
  inVault: t.inVault !== !1,
25216
25292
  hasCanvas: t.hasCanvas === !0,
25217
25293
  defaultLayout: t.defaultLayout,
25218
- allowedBlocks: Vx(t.allowedBlocks),
25219
- disallowedBlocks: t.disallowedBlocks ? Vx(t.disallowedBlocks) : void 0,
25294
+ allowedBlocks: Hx(t.allowedBlocks),
25295
+ disallowedBlocks: t.disallowedBlocks ? Hx(t.disallowedBlocks) : void 0,
25220
25296
  tabs: n,
25221
25297
  fields: r
25222
25298
  };
@@ -25227,11 +25303,11 @@ function Zx(e) {
25227
25303
  Array.isArray(t.fieldSets) && t.fieldSets.forEach((e) => {
25228
25304
  let t = k[e] || {}, i = t.fields || t, a = A(i, "settings", n);
25229
25305
  Object.entries(a).forEach(([e, t]) => {
25230
- r[e] = Hx(r[e] || {}, t);
25306
+ r[e] = Ux(r[e] || {}, t);
25231
25307
  });
25232
25308
  }), Object.values(n).forEach((e) => {
25233
25309
  Object.entries(e.fields).forEach(([e, t]) => {
25234
- r[e] = Hx(r[e] || {}, t);
25310
+ r[e] = Ux(r[e] || {}, t);
25235
25311
  });
25236
25312
  }), re[e] = {
25237
25313
  ...t,
@@ -25247,11 +25323,11 @@ function Zx(e) {
25247
25323
  Array.isArray(t.fieldSets) && t.fieldSets.forEach((e) => {
25248
25324
  let t = k[e] || {}, n = t.fields || t, i = A(n);
25249
25325
  Object.entries(i).forEach(([e, t]) => {
25250
- r[e] = Hx(r[e] || {}, t);
25326
+ r[e] = Ux(r[e] || {}, t);
25251
25327
  });
25252
25328
  }), Object.values(n).forEach((e) => {
25253
25329
  Object.entries(e.fields).forEach(([e, t]) => {
25254
- r[e] = Hx(r[e] || {}, t);
25330
+ r[e] = Ux(r[e] || {}, t);
25255
25331
  });
25256
25332
  }), ie[e] = {
25257
25333
  ...t,
@@ -25268,11 +25344,11 @@ function Zx(e) {
25268
25344
  Array.isArray(t.fieldSets) && t.fieldSets.forEach((e) => {
25269
25345
  let t = k[e] || {}, i = t.fields || t, a = A(i, "settings", n);
25270
25346
  Object.entries(a).forEach(([e, t]) => {
25271
- r[e] = Hx(r[e] || {}, t);
25347
+ r[e] = Ux(r[e] || {}, t);
25272
25348
  });
25273
25349
  }), Object.values(n).forEach((e) => {
25274
25350
  Object.entries(e.fields).forEach(([e, t]) => {
25275
- r[e] = Hx(r[e] || {}, t);
25351
+ r[e] = Ux(r[e] || {}, t);
25276
25352
  });
25277
25353
  }), ae[e] = {
25278
25354
  ...t,
@@ -25289,7 +25365,7 @@ function Zx(e) {
25289
25365
  Array.isArray(t.fieldSets) && t.fieldSets.forEach((e) => {
25290
25366
  let t = k[e] || {}, r = t.fields || t, i = A(r);
25291
25367
  Object.entries(i).forEach(([e, t]) => {
25292
- n[e] = Hx(n[e] || {}, t);
25368
+ n[e] = Ux(n[e] || {}, t);
25293
25369
  });
25294
25370
  }), oe[e] = {
25295
25371
  ...t,
@@ -25306,8 +25382,8 @@ function Zx(e) {
25306
25382
  i[e] = {
25307
25383
  ...t,
25308
25384
  label: t.label || e,
25309
- allowedBlocks: Vx(t.allowedBlocks),
25310
- disallowedBlocks: t.disallowedBlocks ? Vx(t.disallowedBlocks) : void 0
25385
+ allowedBlocks: Hx(t.allowedBlocks),
25386
+ disallowedBlocks: t.disallowedBlocks ? Hx(t.disallowedBlocks) : void 0
25311
25387
  };
25312
25388
  }), se[e] = {
25313
25389
  ...t,
@@ -25323,14 +25399,14 @@ function Zx(e) {
25323
25399
  };
25324
25400
  });
25325
25401
  let ce = {};
25326
- Object.entries(O).forEach(([e, t]) => {
25402
+ Object.entries(te).forEach(([e, t]) => {
25327
25403
  let n = ne(t.tabs), r = A(t.fields || [], "settings", n), i = {}, a = t.regions || { main: { label: "Main Content" } };
25328
25404
  Object.entries(a).forEach(([e, t]) => {
25329
25405
  i[e] = {
25330
25406
  ...t,
25331
25407
  label: t.label || e,
25332
- allowedBlocks: Vx(t.allowedBlocks),
25333
- disallowedBlocks: t.disallowedBlocks ? Vx(t.disallowedBlocks) : void 0
25408
+ allowedBlocks: Hx(t.allowedBlocks),
25409
+ disallowedBlocks: t.disallowedBlocks ? Hx(t.disallowedBlocks) : void 0
25334
25410
  };
25335
25411
  }), ce[e] = {
25336
25412
  ...t,
@@ -25349,7 +25425,7 @@ function Zx(e) {
25349
25425
  Array.isArray(g?.fieldSets) && g?.fieldSets.forEach((e) => {
25350
25426
  let t = k[e] || {}, n = t.fields || t, r = A(n);
25351
25427
  Object.entries(r).forEach(([e, t]) => {
25352
- le[e] = Hx(le[e] || {}, t);
25428
+ le[e] = Ux(le[e] || {}, t);
25353
25429
  });
25354
25430
  });
25355
25431
  let ue = g ? {
@@ -25359,7 +25435,7 @@ function Zx(e) {
25359
25435
  Array.isArray(_?.fieldSets) && _?.fieldSets.forEach((e) => {
25360
25436
  let t = k[e] || {}, n = t.fields || t, r = A(n);
25361
25437
  Object.entries(r).forEach(([e, t]) => {
25362
- de[e] = Hx(de[e] || {}, t);
25438
+ de[e] = Ux(de[e] || {}, t);
25363
25439
  });
25364
25440
  });
25365
25441
  let fe = _ ? {
@@ -25381,11 +25457,11 @@ function Zx(e) {
25381
25457
  userTemplate: fe
25382
25458
  };
25383
25459
  }
25384
- var Qx = new e(), $x = (e) => {
25460
+ var $x = new e(), eS = (e) => {
25385
25461
  try {
25386
25462
  let t = e.env?.BUNDLED_DEFINITIONS;
25387
25463
  (!t || Object.keys(t).length === 0) && (t = Db || Eb || Tb);
25388
- let n = Yx(t);
25464
+ let n = Xx(t);
25389
25465
  return e.json(n, 200, { "Cache-Control": "no-cache, no-store, must-revalidate" });
25390
25466
  } catch (t) {
25391
25467
  return console.error("[CMS API] Error loading schemas:", t), e.json({
@@ -25394,8 +25470,8 @@ var Qx = new e(), $x = (e) => {
25394
25470
  }, 500);
25395
25471
  }
25396
25472
  };
25397
- Qx.get("/", $x), Qx.get("/schemas.json", $x);
25398
- var eS = new e(), tS = {
25473
+ $x.get("/", eS), $x.get("/schemas.json", eS);
25474
+ var tS = new e(), nS = {
25399
25475
  node: "content_nodes",
25400
25476
  nodes: "content_nodes",
25401
25477
  content_node: "content_nodes",
@@ -25407,7 +25483,7 @@ var eS = new e(), tS = {
25407
25483
  user: "users",
25408
25484
  users: "users",
25409
25485
  user_account: "user_accounts"
25410
- }, nS = {
25486
+ }, rS = {
25411
25487
  content_nodes: [
25412
25488
  "id",
25413
25489
  "title",
@@ -25464,11 +25540,11 @@ var eS = new e(), tS = {
25464
25540
  "createdAt"
25465
25541
  ]
25466
25542
  };
25467
- eS.post("/validate-unique", async (e) => {
25543
+ tS.post("/validate-unique", async (e) => {
25468
25544
  try {
25469
25545
  let t = e.get("db"), { entityType: n, field: r, value: i, excludeId: a } = await e.req.json();
25470
25546
  if (!r || i == null || String(i).trim() === "") return e.json({ isUnique: !0 });
25471
- let o = tS[n] || "content_nodes", s = r.replace(/[^a-zA-Z0-9_]/g, ""), c = (nS[o] || nS.content_nodes).includes(s), l = -1;
25547
+ let o = nS[n] || "content_nodes", s = r.replace(/[^a-zA-Z0-9_]/g, ""), c = (rS[o] || rS.content_nodes).includes(s), l = -1;
25472
25548
  if (a != null && String(a).trim() !== "") {
25473
25549
  let e = Number(a);
25474
25550
  l = isNaN(e) ? String(a) : e;
@@ -25480,14 +25556,14 @@ eS.post("/validate-unique", async (e) => {
25480
25556
  } catch (t) {
25481
25557
  return console.error("[API Validation] Error validating global uniqueness:", t), e.json({ error: "Failed to validate uniqueness" }, 500);
25482
25558
  }
25483
- }), eS.post("/validate-unique-sibling", async (e) => e.json({ isUnique: !0 }));
25484
- var rS = new e();
25485
- rS.get("/", async (e) => {
25559
+ }), tS.post("/validate-unique-sibling", async (e) => e.json({ isUnique: !0 }));
25560
+ var iS = new e();
25561
+ iS.get("/", async (e) => {
25486
25562
  try {
25487
- 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) => ({
25563
+ 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) => ({
25488
25564
  ...e,
25489
25565
  isHidden: !!e.isHidden
25490
- })), 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) => ({
25566
+ })), 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) => ({
25491
25567
  id: e.id,
25492
25568
  title: e.title,
25493
25569
  slug: e.slug,
@@ -25525,8 +25601,8 @@ rS.get("/", async (e) => {
25525
25601
  }, 500);
25526
25602
  }
25527
25603
  });
25528
- var iS = new e();
25529
- async function aS(e, t, n = []) {
25604
+ var aS = new e();
25605
+ async function oS(e, t, n = []) {
25530
25606
  let r = e.prepare(t);
25531
25607
  if (typeof r.bind == "function") {
25532
25608
  let e = await r.bind(...n).all();
@@ -25538,16 +25614,16 @@ async function aS(e, t, n = []) {
25538
25614
  }
25539
25615
  return [];
25540
25616
  }
25541
- async function oS(e, t, n = []) {
25617
+ async function sS(e, t, n = []) {
25542
25618
  let r = e.prepare(t);
25543
25619
  if (typeof r.bind == "function") return await r.bind(...n).run();
25544
25620
  if (typeof r.run == "function") return await r.run(...n);
25545
25621
  }
25546
- function sS(e, t, n) {
25622
+ function cS(e, t, n) {
25547
25623
  let r = e || (t ? `/media/${t}` : "");
25548
25624
  return r && n && r.startsWith(`https://${n}/`) && !r.includes("/media/") && (r = r.replace(`https://${n}/`, `https://${n}/media/`)), r;
25549
25625
  }
25550
- iS.get("/", async (e) => {
25626
+ aS.get("/", async (e) => {
25551
25627
  try {
25552
25628
  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 = {
25553
25629
  createdAt: "a.createdAt",
@@ -25557,7 +25633,7 @@ iS.get("/", async (e) => {
25557
25633
  sizeBytes: "a.sizeBytes"
25558
25634
  }[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 = '')"];
25559
25635
  if (c) {
25560
- 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)]);
25636
+ 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)]);
25561
25637
  if (e.length === 0) _.push("1 = 0");
25562
25638
  else {
25563
25639
  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 ");
@@ -25571,10 +25647,10 @@ iS.get("/", async (e) => {
25571
25647
  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/%")));
25572
25648
  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 ?`;
25573
25649
  g.push(f, p);
25574
- let y = await aS(t, v, g), b = y.map((e) => e.id), x = /* @__PURE__ */ new Map(), S = /* @__PURE__ */ new Map();
25650
+ let y = await oS(t, v, g), b = y.map((e) => e.id), x = /* @__PURE__ */ new Map(), S = /* @__PURE__ */ new Map();
25575
25651
  if (b.length > 0) {
25576
25652
  let e = b.map(() => "?").join(",");
25577
- (await aS(t, `
25653
+ (await oS(t, `
25578
25654
  SELECT master.id AS assetId, COUNT(DISTINCT na.nodeId) AS count
25579
25655
  FROM assets master
25580
25656
  INNER JOIN node_assets na ON (
@@ -25582,7 +25658,7 @@ iS.get("/", async (e) => {
25582
25658
  EXISTS (SELECT 1 FROM assets crop WHERE crop.id = na.assetId AND crop.isSystemVariant = 1 AND crop.parentAssetId = master.id)
25583
25659
  )
25584
25660
  WHERE master.id IN (${e})
25585
- GROUP BY master.id`, b)).forEach((e) => x.set(String(e.assetId), e.count || 0)), (await aS(t, `
25661
+ GROUP BY master.id`, b)).forEach((e) => x.set(String(e.assetId), e.count || 0)), (await oS(t, `
25586
25662
  SELECT parentAssetId, COUNT(id) AS count
25587
25663
  FROM assets
25588
25664
  WHERE isSystemVariant = 1 AND parentAssetId IN (${e})
@@ -25600,7 +25676,7 @@ iS.get("/", async (e) => {
25600
25676
  ...JSON.parse(t.dataJson || "{}")
25601
25677
  };
25602
25678
  } catch {}
25603
- let r = sS(t.cdnUrl, t.storageKeyPrivate, e.env?.CDN_DOMAIN);
25679
+ let r = cS(t.cdnUrl, t.storageKeyPrivate, e.env?.CDN_DOMAIN);
25604
25680
  return {
25605
25681
  id: t.id,
25606
25682
  filename: t.filename || "Untitled Asset",
@@ -25625,7 +25701,7 @@ iS.get("/", async (e) => {
25625
25701
  details: t.message || String(t)
25626
25702
  }, 500);
25627
25703
  }
25628
- }), iS.post("/upload", async (e) => {
25704
+ }), aS.post("/upload", async (e) => {
25629
25705
  try {
25630
25706
  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;
25631
25707
  if (!i || !(i instanceof File)) return e.json({ error: "No file uploaded" }, 400);
@@ -25641,13 +25717,13 @@ iS.get("/", async (e) => {
25641
25717
  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}`;
25642
25718
  if (!v) throw Error("Storage provider failed to return a valid storage key");
25643
25719
  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;
25644
- T && (await aS(t, "SELECT id FROM users WHERE id = ?", [T])).length === 0 && (T = null);
25720
+ T && (await oS(t, "SELECT id FROM users WHERE id = ?", [T])).length === 0 && (T = null);
25645
25721
  let ee = new mx(e.env);
25646
25722
  if (s) {
25647
- let r = await aS(t, "SELECT storageKeyPrivate, isSystemVariant, parentAssetId FROM assets WHERE id = ?", [s]);
25723
+ let r = await oS(t, "SELECT storageKeyPrivate, isSystemVariant, parentAssetId FROM assets WHERE id = ?", [s]);
25648
25724
  if (r.length > 0) {
25649
25725
  let a = r[0];
25650
- if (await oS(t, "UPDATE assets SET filename = ?, mimeType = ?, sizeBytes = ?, storageKeyPrivate = ?, cdnUrl = ?, updatedAt = CURRENT_TIMESTAMP WHERE id = ?", [
25726
+ if (await sS(t, "UPDATE assets SET filename = ?, mimeType = ?, sizeBytes = ?, storageKeyPrivate = ?, cdnUrl = ?, updatedAt = CURRENT_TIMESTAMP WHERE id = ?", [
25651
25727
  i.name,
25652
25728
  S,
25653
25729
  C,
@@ -25676,7 +25752,7 @@ iS.get("/", async (e) => {
25676
25752
  }
25677
25753
  }
25678
25754
  let E = `ast_${p}`, D = +!!h;
25679
- await oS(t, "INSERT INTO assets (id, filename, mimeType, sizeBytes, storageKeyPrivate, cdnUrl, createdById, isSystemVariant, parentAssetId, cropCoordinatesJson) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", [
25755
+ await sS(t, "INSERT INTO assets (id, filename, mimeType, sizeBytes, storageKeyPrivate, cdnUrl, createdById, isSystemVariant, parentAssetId, cropCoordinatesJson) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", [
25680
25756
  E,
25681
25757
  i.name,
25682
25758
  S,
@@ -25688,15 +25764,15 @@ iS.get("/", async (e) => {
25688
25764
  l,
25689
25765
  d
25690
25766
  ]);
25691
- let O = x;
25767
+ let te = x;
25692
25768
  if (l) {
25693
- let n = await aS(t, "SELECT cdnUrl, storageKeyPrivate FROM assets WHERE id = ?", [l]);
25694
- n.length > 0 && (O = sS(n[0].cdnUrl, n[0].storageKeyPrivate, y)), ee.purgeAsset(e, t, l);
25769
+ let n = await oS(t, "SELECT cdnUrl, storageKeyPrivate FROM assets WHERE id = ?", [l]);
25770
+ n.length > 0 && (te = cS(n[0].cdnUrl, n[0].storageKeyPrivate, y)), ee.purgeAsset(e, t, l);
25695
25771
  }
25696
25772
  return e.json({
25697
25773
  id: E,
25698
25774
  url: x,
25699
- originalUrl: O,
25775
+ originalUrl: te,
25700
25776
  parentAssetId: l,
25701
25777
  cropCoordinates: f,
25702
25778
  filename: i.name,
@@ -25710,11 +25786,11 @@ iS.get("/", async (e) => {
25710
25786
  details: t.message || String(t)
25711
25787
  }, 500);
25712
25788
  }
25713
- }), iS.get("/:id/details", async (e) => {
25789
+ }), aS.get("/:id/details", async (e) => {
25714
25790
  try {
25715
- let t = wb(e), n = e.req.param("id"), r = await aS(t, "SELECT * FROM assets WHERE id = ?", [n]);
25791
+ let t = wb(e), n = e.req.param("id"), r = await oS(t, "SELECT * FROM assets WHERE id = ?", [n]);
25716
25792
  if (!r || r.length === 0) return e.json({ error: "Asset not found" }, 404);
25717
- 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 = {
25793
+ 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 = {
25718
25794
  title: "",
25719
25795
  alt: "",
25720
25796
  description: ""
@@ -25725,7 +25801,7 @@ iS.get("/", async (e) => {
25725
25801
  ...JSON.parse(i.dataJson || "{}")
25726
25802
  };
25727
25803
  } catch {}
25728
- let c = i.updatedAt ? new Date(i.updatedAt).getTime() : Date.now(), l = `${sS(i.cdnUrl, i.storageKeyPrivate, e.env?.CDN_DOMAIN)}?v=${c}`;
25804
+ let c = i.updatedAt ? new Date(i.updatedAt).getTime() : Date.now(), l = `${cS(i.cdnUrl, i.storageKeyPrivate, e.env?.CDN_DOMAIN)}?v=${c}`;
25729
25805
  return e.json({
25730
25806
  id: i.id,
25731
25807
  filename: i.filename,
@@ -25744,7 +25820,7 @@ iS.get("/", async (e) => {
25744
25820
  if (t.cropCoordinatesJson) try {
25745
25821
  n = JSON.parse(t.cropCoordinatesJson);
25746
25822
  } catch {}
25747
- let r = t.updatedAt ? new Date(t.updatedAt).getTime() : c, a = sS(t.cdnUrl, t.storageKeyPrivate, e.env?.CDN_DOMAIN);
25823
+ let r = t.updatedAt ? new Date(t.updatedAt).getTime() : c, a = cS(t.cdnUrl, t.storageKeyPrivate, e.env?.CDN_DOMAIN);
25748
25824
  return {
25749
25825
  id: t.id,
25750
25826
  filename: t.filename,
@@ -25761,15 +25837,15 @@ iS.get("/", async (e) => {
25761
25837
  } catch {
25762
25838
  return e.json({ error: "Failed to load details" }, 500);
25763
25839
  }
25764
- }), iS.put("/:id", async (e) => {
25840
+ }), aS.put("/:id", async (e) => {
25765
25841
  try {
25766
- 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]);
25842
+ 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]);
25767
25843
  if (!i || i.length === 0) return e.json({ error: "Asset not found" }, 404);
25768
25844
  let a = i[0], o = {};
25769
25845
  try {
25770
25846
  o = JSON.parse(a.dataJson || "{}");
25771
25847
  } catch {}
25772
- 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 = ?", [
25848
+ 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 = ?", [
25773
25849
  r.filename === void 0 ? a.filename : r.filename,
25774
25850
  JSON.stringify(o),
25775
25851
  n
@@ -25777,10 +25853,10 @@ iS.get("/", async (e) => {
25777
25853
  } catch {
25778
25854
  return e.json({ error: "Failed to update asset" }, 500);
25779
25855
  }
25780
- }), iS.delete("/:id", async (e) => {
25856
+ }), aS.delete("/:id", async (e) => {
25781
25857
  try {
25782
- let t = wb(e), n = e.req.param("id"), r = (await aS(t, "SELECT id, filename, isSystemVariant FROM assets WHERE id = ?", [n]))[0];
25783
- 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({
25858
+ let t = wb(e), n = e.req.param("id"), r = (await oS(t, "SELECT id, filename, isSystemVariant FROM assets WHERE id = ?", [n]))[0];
25859
+ 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({
25784
25860
  success: !0,
25785
25861
  id: n,
25786
25862
  trashed: !0
@@ -25791,10 +25867,10 @@ iS.get("/", async (e) => {
25791
25867
  details: t.message || String(t)
25792
25868
  }, 500);
25793
25869
  }
25794
- }), iS.post("/restore", async (e) => {
25870
+ }), aS.post("/restore", async (e) => {
25795
25871
  try {
25796
25872
  let t = wb(e), n = await e.req.json(), r = n.id || n.assetId;
25797
- 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({
25873
+ 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({
25798
25874
  success: !0,
25799
25875
  id: r,
25800
25876
  restored: !0
@@ -25805,13 +25881,13 @@ iS.get("/", async (e) => {
25805
25881
  details: t.message
25806
25882
  }, 500);
25807
25883
  }
25808
- }), iS.delete("/purge/:id", async (e) => {
25884
+ }), aS.delete("/purge/:id", async (e) => {
25809
25885
  try {
25810
- 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];
25886
+ 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];
25811
25887
  if (!i) return e.json({ error: "Asset not found" }, 404);
25812
25888
  new mx(e.env).purgeAsset(e, t, r);
25813
25889
  let a = [i];
25814
- i.isSystemVariant || (a = [i, ...await aS(t, "SELECT id, storageKeyPrivate FROM assets WHERE isSystemVariant = 1 AND parentAssetId = ?", [r])]);
25890
+ i.isSystemVariant || (a = [i, ...await oS(t, "SELECT id, storageKeyPrivate FROM assets WHERE isSystemVariant = 1 AND parentAssetId = ?", [r])]);
25815
25891
  let o = a.map((e) => e.id);
25816
25892
  if (typeof n.delete == "function") {
25817
25893
  for (let e of a) if (e.storageKeyPrivate) try {
@@ -25821,7 +25897,7 @@ iS.get("/", async (e) => {
25821
25897
  }
25822
25898
  }
25823
25899
  let s = o.map(() => "?").join(",");
25824
- 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({
25900
+ 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({
25825
25901
  success: !0,
25826
25902
  id: r,
25827
25903
  purged: !0,
@@ -25835,8 +25911,8 @@ iS.get("/", async (e) => {
25835
25911
  }, 500);
25836
25912
  }
25837
25913
  });
25838
- var cS = new $y();
25839
- function lS() {
25914
+ var lS = new $y();
25915
+ function uS() {
25840
25916
  return {
25841
25917
  fullPath: /* @__PURE__ */ new Map(),
25842
25918
  treeEdges: /* @__PURE__ */ new Map(),
@@ -25844,7 +25920,7 @@ function lS() {
25844
25920
  assetUrls: /* @__PURE__ */ new Map()
25845
25921
  };
25846
25922
  }
25847
- function uS(e, t, n = []) {
25923
+ function dS(e, t, n = []) {
25848
25924
  let r = Date.now();
25849
25925
  if (e && String(e).trim() !== "") {
25850
25926
  let t = Date.parse(e);
@@ -25855,7 +25931,7 @@ function uS(e, t, n = []) {
25855
25931
  !isNaN(e) && e > r && n.push(e);
25856
25932
  }
25857
25933
  }
25858
- function dS(e, t) {
25934
+ function fS(e, t) {
25859
25935
  let n = Date.now();
25860
25936
  if (e && String(e).trim() !== "") {
25861
25937
  let t = Date.parse(e);
@@ -25867,13 +25943,15 @@ function dS(e, t) {
25867
25943
  }
25868
25944
  return !0;
25869
25945
  }
25870
- async function fS(e, t, n, r, i) {
25946
+ async function pS(e, t, n, r, i) {
25871
25947
  let a = t.filter((e) => e.componentId === "content-feed" || e.componentId === "article-list" || e.componentId === "nodeList" || e.componentId === "node-list");
25872
25948
  await Promise.all(a.map(async (t) => {
25873
25949
  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();
25874
25950
  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));
25875
- let f = `FROM content_nodes WHERE contentType IN (${s.map(() => "?").join(",")}) AND isHidden = 0 AND (status = 'published' OR status IS NULL)`, p = [...s];
25876
- n && n !== "all" && (f += " AND id IN (SELECT nodeId FROM node_channels WHERE channelId = ?)", p.push(Number(n) || n));
25951
+ let f = `FROM content_nodes WHERE contentType IN (${s.map(() => "?").join(",")}) AND isHidden = 0 AND IFNULL(status, 'published') = 'published'`, p = [...s];
25952
+ 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));
25953
+ let m = (/* @__PURE__ */ new Date()).toISOString();
25954
+ f += " AND IFNULL(json_extract(dataJson, '$.startShowingAt'), '') <= ?", p.push(m), f += " AND IFNULL(json_extract(dataJson, '$.stopShowingAt'), '9999-12-31') >= ?", p.push(m);
25877
25955
  for (let e of [
25878
25956
  "authors",
25879
25957
  "categories",
@@ -25893,18 +25971,18 @@ async function fS(e, t, n, r, i) {
25893
25971
  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);
25894
25972
  }
25895
25973
  }
25896
- let m = "ORDER BY updatedAt DESC";
25897
- u === "published_desc" || u === "createdAt" ? m = "ORDER BY createdAt DESC" : u === "title_asc" && (m = "ORDER BY LOWER(title) ASC");
25898
- let h = `SELECT id, title, slug, language, dataJson, createdAt, updatedAt ${f} ${m} LIMIT ? OFFSET ?`;
25974
+ let h = "ORDER BY updatedAt DESC";
25975
+ u === "published_desc" || u === "createdAt" ? h = "ORDER BY createdAt DESC" : u === "title_asc" && (h = "ORDER BY LOWER(title) ASC");
25976
+ let g = `SELECT id, title, slug, language, dataJson, createdAt, updatedAt ${f} ${h} LIMIT ? OFFSET ?`;
25899
25977
  p.push(c, l);
25900
25978
  try {
25901
- let n = await e.prepare(h).all(...p), a = Array.isArray(n) ? n : n?.results || [];
25902
- t.data.initialItems = a.map((e) => {
25979
+ let n = await e.prepare(g).all(...p), o = Array.isArray(n) ? n : n?.results || [];
25980
+ t.data.initialItems = o.map((e) => {
25903
25981
  let t = {};
25904
25982
  if (e.dataJson) try {
25905
25983
  t = typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson;
25906
25984
  } catch {}
25907
- return i && uS(t.startShowingAt, t.stopShowingAt, i), dS(t.startShowingAt, t.stopShowingAt) ? {
25985
+ return i && dS(t.startShowingAt, t.stopShowingAt, i), {
25908
25986
  id: e.id,
25909
25987
  title: e.title,
25910
25988
  slug: e.slug,
@@ -25914,14 +25992,14 @@ async function fS(e, t, n, r, i) {
25914
25992
  excerpt: t.excerpt || "",
25915
25993
  image: t.image || t.coverImage || null,
25916
25994
  author: t.author || null
25917
- } : null;
25918
- }).filter(Boolean), t.data.initialItems.length === c ? t.data.loadMoreUrl = `/api/v1/nodes?${d.toString()}` : t.data.loadMoreUrl = null;
25995
+ };
25996
+ }), a.disablePagination !== !0 && a.disablePagination !== "1" && o.length === c ? t.data.loadMoreUrl = `/api/v1/nodes?${d.toString()}` : t.data.loadMoreUrl = null;
25919
25997
  } catch (e) {
25920
25998
  console.error("[CMS Hydration] Failed to hydrate content feed block", e), t.data.initialItems = [], t.data.loadMoreUrl = null;
25921
25999
  }
25922
26000
  }));
25923
26001
  }
25924
- async function pS(e, t, n, r, i, a = !1, o, s) {
26002
+ async function mS(e, t, n, r, i, a = !1, o, s) {
25925
26003
  if (!t) return { blocks: [] };
25926
26004
  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 || [];
25927
26005
  if (!l || l.length === 0) return { blocks: [] };
@@ -25957,11 +26035,11 @@ async function pS(e, t, n, r, i, a = !1, o, s) {
25957
26035
  try {
25958
26036
  n = (typeof t.dataJson == "string" ? JSON.parse(t.dataJson) : t.dataJson) || {};
25959
26037
  } catch {}
25960
- s && uS(n.startShowingAt, n.stopShowingAt, s);
25961
- let o = n.hidden === !0 || n.hidden === 1 || n.hidden === "1" || n.hidden === "true", c = dS(n.startShowingAt, n.stopShowingAt);
26038
+ s && dS(n.startShowingAt, n.stopShowingAt, s);
26039
+ let o = n.hidden === !0 || n.hidden === 1 || n.hidden === "1" || n.hidden === "true", c = fS(n.startShowingAt, n.stopShowingAt);
25962
26040
  if (!a && (o || !c)) return null;
25963
- 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);
25964
- return f = await fx(e, f), f = hS(f), f.blockId = d, {
26041
+ 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);
26042
+ return f = await fx(e, f), f = gS(f), f.blockId = d, {
25965
26043
  region: t.region || r,
25966
26044
  block: {
25967
26045
  instanceId: t.id,
@@ -25981,7 +26059,7 @@ async function pS(e, t, n, r, i, a = !1, o, s) {
25981
26059
  }
25982
26060
  return { blocks: [] };
25983
26061
  }
25984
- function mS(e, t = {}) {
26062
+ function hS(e, t = {}) {
25985
26063
  let n = {};
25986
26064
  for (let [r, i] of Object.entries(e)) r.endsWith("_meta") || [
25987
26065
  "disabledRegions",
@@ -25997,14 +26075,14 @@ function mS(e, t = {}) {
25997
26075
  ].includes(r) || r.startsWith("_") || (!t[r] || t[r].public !== !1) && (n[r] = i);
25998
26076
  return n;
25999
26077
  }
26000
- function hS(e) {
26001
- if (Array.isArray(e)) return e.map(hS);
26078
+ function gS(e) {
26079
+ if (Array.isArray(e)) return e.map(gS);
26002
26080
  if (!e || typeof e != "object") return e;
26003
26081
  if (typeof e.id == "string" && e.id.startsWith("ast_") && typeof e.url == "string") {
26004
26082
  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 ? {
26005
26083
  ...t,
26006
26084
  ...t.crops?.[r] || {}
26007
- } : t, a = Object.fromEntries(Object.entries(n).filter(([, t]) => t?.id !== e.id).map(([t, n]) => [t, hS({
26085
+ } : t, a = Object.fromEntries(Object.entries(n).filter(([, t]) => t?.id !== e.id).map(([t, n]) => [t, gS({
26008
26086
  ...n,
26009
26087
  title: n?.title ?? e.title ?? "",
26010
26088
  alt: n?.alt ?? e.alt ?? "",
@@ -26018,9 +26096,9 @@ function hS(e) {
26018
26096
  ...Object.keys(a).length > 0 ? { variants: a } : {}
26019
26097
  };
26020
26098
  }
26021
- return Object.fromEntries(Object.entries(e).map(([e, t]) => [e, hS(t)]));
26099
+ return Object.fromEntries(Object.entries(e).map(([e, t]) => [e, gS(t)]));
26022
26100
  }
26023
- async function gS(e, t, n, r) {
26101
+ async function _S(e, t, n, r) {
26024
26102
  if (typeof t == "string") {
26025
26103
  if (!t.includes("#node:") && !t.includes("data-node-id") && !t.includes("#asset:") && !t.includes("data-asset-id")) return t;
26026
26104
  let r = (e, t) => {
@@ -26053,25 +26131,25 @@ async function gS(e, t, n, r) {
26053
26131
  return /href\s*=\s*["'][^"']*["']/i.test(d) ? d = d.replace(/href\s*=\s*["'][^"']*["']/i, `href="${u}"`) : d += ` href="${u}"`, `<a ${d}>`;
26054
26132
  });
26055
26133
  }
26056
- if (Array.isArray(t)) return Promise.all(t.map((t) => gS(e, t, n, r)));
26134
+ if (Array.isArray(t)) return Promise.all(t.map((t) => _S(e, t, n, r)));
26057
26135
  if (t && typeof t == "object") {
26058
26136
  if (typeof t.href == "string" && (t.href.startsWith("#node:") || t.href.startsWith("#asset:"))) return {
26059
26137
  ...t,
26060
- href: await _S(e, t, n, r)
26138
+ href: await vS(e, t, n, r)
26061
26139
  };
26062
- let i = await Promise.all(Object.entries(t).map(async ([t, i]) => [t, await gS(e, i, n, r)]));
26140
+ let i = await Promise.all(Object.entries(t).map(async ([t, i]) => [t, await _S(e, i, n, r)]));
26063
26141
  return Object.fromEntries(i);
26064
26142
  }
26065
26143
  return t;
26066
26144
  }
26067
- async function _S(e, t, n, r) {
26145
+ async function vS(e, t, n, r) {
26068
26146
  let i = t.href.match(/^#node:(.+)$/), a = t.href.match(/^#asset:(.+)$/);
26069
- if (a) return vS(e, a[1], r);
26147
+ if (a) return yS(e, a[1], r);
26070
26148
  if (!i) return t.href;
26071
26149
  let o = i[1];
26072
26150
  return (await e.prepare("SELECT path FROM node_routes WHERE nodeId = ? AND channelId = ? AND isCanonical = 1 LIMIT 1").get(Number(o), n))?.path || "#";
26073
26151
  }
26074
- async function vS(e, t, n) {
26152
+ async function yS(e, t, n) {
26075
26153
  let r = String(t), i = n.assetUrls.get(r);
26076
26154
  if (i) return i;
26077
26155
  let a = (async () => {
@@ -26080,7 +26158,7 @@ async function vS(e, t, n) {
26080
26158
  })();
26081
26159
  return n.assetUrls.set(r, a), a;
26082
26160
  }
26083
- function yS(e) {
26161
+ function bS(e) {
26084
26162
  let t = e.socialImage;
26085
26163
  if (!t || typeof t != "object") return null;
26086
26164
  let n = (e, t) => {
@@ -26111,7 +26189,7 @@ function yS(e) {
26111
26189
  ])
26112
26190
  };
26113
26191
  }
26114
- async function bS(e, t, n, r, i) {
26192
+ async function xS(e, t, n, r, i) {
26115
26193
  let a = {}, o = null;
26116
26194
  if (t) {
26117
26195
  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([
@@ -26149,20 +26227,20 @@ async function bS(e, t, n, r, i) {
26149
26227
  inheritedFields: a
26150
26228
  };
26151
26229
  }
26152
- function xS(e) {
26230
+ function SS(e) {
26153
26231
  let t = Number(e?.env?.CMS_NODE_CACHE_TTL);
26154
26232
  return Number.isFinite(t) && t >= 60 ? Math.floor(t) : 300;
26155
26233
  }
26156
- async function SS(e, t, n, r) {
26234
+ async function CS(e, t, n, r) {
26157
26235
  try {
26158
26236
  await e.set(t, n, r);
26159
26237
  } catch (e) {
26160
26238
  console.warn("[CMS Cache] Failed to write node response to cache:", e);
26161
26239
  }
26162
26240
  }
26163
- async function CS(e) {
26241
+ async function wS(e) {
26164
26242
  try {
26165
- 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 = "";
26243
+ 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 = "";
26166
26244
  u.includes("/node/") ? d = u.substring(u.indexOf("/node/") + 6) : u.endsWith("/node") && (d = "");
26167
26245
  try {
26168
26246
  d = decodeURIComponent(d);
@@ -26212,9 +26290,9 @@ async function CS(e) {
26212
26290
  e.defaultLanguage ? w = String(e.defaultLanguage).trim() : e.language && (w = String(e.language).trim());
26213
26291
  } catch {}
26214
26292
  }
26215
- 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);
26216
- if (!s && !O) {
26217
- let t = await te.get(D);
26293
+ 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);
26294
+ if (!s && !te) {
26295
+ let t = await O.get(D);
26218
26296
  if (t) {
26219
26297
  e.header("X-Cache", "HIT");
26220
26298
  let n = k;
@@ -26242,14 +26320,14 @@ async function CS(e) {
26242
26320
  if (x && x.node && x.node.dataJson && (fe = x.node.dataJson), fe) try {
26243
26321
  de = typeof fe == "string" ? JSON.parse(fe) : fe;
26244
26322
  } catch {}
26245
- 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);
26246
- 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;
26323
+ 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);
26324
+ 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;
26247
26325
  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);
26248
- let ve = await fx(t, mS(de, oe));
26249
- ve = hS(ve), ve = await gS(t, ve, g, n), delete ve.language;
26250
- let ye = yS(ve);
26326
+ let ve = await fx(t, hS(de, oe));
26327
+ ve = gS(ve), ve = await _S(t, ve, g, n), delete ve.language;
26328
+ let ye = bS(ve);
26251
26329
  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;
26252
- 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";
26330
+ 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";
26253
26331
  if (!s && (be || xe || Se && !Ce)) return e.json({ error: "Node is hidden, offline, or has never been published." }, 404);
26254
26332
  let we = [];
26255
26333
  if (S?.treeNodeId) {
@@ -26260,8 +26338,8 @@ async function CS(e) {
26260
26338
  try {
26261
26339
  t = (typeof n == "string" ? JSON.parse(n) : n) || {};
26262
26340
  } catch {}
26263
- 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, "");
26264
- return uS(t.startShowingAt, t.stopShowingAt, r), !s && (i || !o) ? null : {
26341
+ 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, "");
26342
+ return dS(t.startShowingAt, t.stopShowingAt, r), !s && (i || !o) ? null : {
26265
26343
  treeNodeId: e.treeNodeId,
26266
26344
  id: e.id,
26267
26345
  title: e.title,
@@ -26287,11 +26365,11 @@ async function CS(e) {
26287
26365
  try {
26288
26366
  a = (typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson) || {};
26289
26367
  } catch {}
26290
- uS(a.startShowingAt, a.stopShowingAt, r);
26291
- let o = a.hidden === !0 || a.hidden === 1 || a.hidden === "1" || a.hidden === "true", c = dS(a.startShowingAt, a.stopShowingAt);
26368
+ dS(a.startShowingAt, a.stopShowingAt, r);
26369
+ let o = a.hidden === !0 || a.hidden === 1 || a.hidden === "1" || a.hidden === "true", c = fS(a.startShowingAt, a.stopShowingAt);
26292
26370
  if (!s && (o || !c)) return null;
26293
- 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);
26294
- return f = await fx(t, f), f = hS(f), f = await gS(t, f, g, n), f.blockId = d, {
26371
+ 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);
26372
+ return f = await fx(t, f), f = gS(f), f = await _S(t, f, g, n), f.blockId = d, {
26295
26373
  region: i,
26296
26374
  block: {
26297
26375
  instanceId: e.id,
@@ -26316,7 +26394,7 @@ async function CS(e) {
26316
26394
  for (let [e, i] of Object.entries(ke)) {
26317
26395
  let a = Ee[e] && Ee[e].length > 0, o = !!se[e];
26318
26396
  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) {
26319
- let i = await pS(t, A, String(b), e, re, s, n, r);
26397
+ let i = await mS(t, A, String(b), e, re, s, n, r);
26320
26398
  if (i.blocks.length > 0 && (Ee[e] = i.blocks, De[e] = {
26321
26399
  isInherited: !0,
26322
26400
  inheritedFromId: i.inheritedFromId,
@@ -26328,7 +26406,7 @@ async function CS(e) {
26328
26406
  });
26329
26407
  }
26330
26408
  }
26331
- await Promise.all(Object.keys(Ee).map((e) => fS(t, Ee[e], g, E, r)));
26409
+ await Promise.all(Object.keys(Ee).map((e) => pS(t, Ee[e], g, E, r)));
26332
26410
  let Ae = null, je = null;
26333
26411
  if (r.length > 0) {
26334
26412
  je = Math.min(...r);
@@ -26347,10 +26425,10 @@ async function CS(e) {
26347
26425
  content: Ee,
26348
26426
  regionMeta: De
26349
26427
  };
26350
- if (!s && !O) {
26428
+ if (!s && !te) {
26351
26429
  e.header("X-Cache", "MISS");
26352
26430
  let t = Ae === null ? k : Ae;
26353
- e.header("Cache-Control", `public, max-age=${t}, s-maxage=${t}`), await SS(te, D, Me, t);
26431
+ e.header("Cache-Control", `public, max-age=${t}, s-maxage=${t}`), await CS(O, D, Me, t);
26354
26432
  } else e.header("Cache-Control", "no-cache, no-store, must-revalidate");
26355
26433
  return e.json(Me, 200);
26356
26434
  } catch (t) {
@@ -26360,17 +26438,17 @@ async function CS(e) {
26360
26438
  }, 500);
26361
26439
  }
26362
26440
  }
26363
- var wS = X({
26441
+ var TS = X({
26364
26442
  channelId: J().optional().openapi({ description: "The ID or key of the channel" }),
26365
26443
  channel: J().optional().openapi({ description: "Legacy alias for channelId" }),
26366
26444
  lang: J().optional().openapi({ description: "Requested language code" }),
26367
26445
  preview: lv(["true", "false"]).optional().openapi({ description: "Request unpublished draft data" }),
26368
26446
  revisionId: J().optional().openapi({ description: "Historical revision version to load" }),
26369
26447
  treeId: J().optional().openapi({ description: "The ID of the tree to resolve paths against" })
26370
- }), TS = X({
26448
+ }), ES = X({
26371
26449
  error: J(),
26372
26450
  details: J().optional()
26373
- }).openapi("ErrorResponse"), ES = X({
26451
+ }).openapi("ErrorResponse"), DS = X({
26374
26452
  channelId: G_([J(), c_()]),
26375
26453
  treeId: J().nullable(),
26376
26454
  language: J().nullable(),
@@ -26385,7 +26463,7 @@ var wS = X({
26385
26463
  inheritedFromId: J().optional(),
26386
26464
  inheritedFromTitle: J().optional()
26387
26465
  }))
26388
- }).openapi("NodeResponse"), DS = eb({
26466
+ }).openapi("NodeResponse"), OS = eb({
26389
26467
  method: "get",
26390
26468
  path: "/{path}",
26391
26469
  summary: "Fetch CMS Node Content",
@@ -26393,25 +26471,25 @@ var wS = X({
26393
26471
  tags: ["Public Node API"],
26394
26472
  request: {
26395
26473
  params: X({ path: J().optional().openapi({ description: "The full URL path or slug of the requested node" }) }),
26396
- query: wS
26474
+ query: TS
26397
26475
  },
26398
26476
  responses: {
26399
26477
  200: {
26400
26478
  description: "Fully hydrated CMS Node",
26401
- content: { "application/json": { schema: ES } }
26479
+ content: { "application/json": { schema: DS } }
26402
26480
  },
26403
26481
  404: {
26404
26482
  description: "Node or Channel not found",
26405
- content: { "application/json": { schema: TS } }
26483
+ content: { "application/json": { schema: ES } }
26406
26484
  },
26407
26485
  500: {
26408
26486
  description: "Server error during hydration",
26409
- content: { "application/json": { schema: TS } }
26487
+ content: { "application/json": { schema: ES } }
26410
26488
  }
26411
26489
  }
26412
26490
  });
26413
- cS.openapi(DS, CS), cS.get("*", CS);
26414
- var OS = new $y(), kS = X({
26491
+ lS.openapi(OS, wS), lS.get("*", wS);
26492
+ var kS = new $y(), AS = X({
26415
26493
  nodeType: J().default("article").openapi({ description: "Content types (comma separated)" }),
26416
26494
  channelId: J().optional().openapi({ description: "Channel ID or key" }),
26417
26495
  limit: Ky().min(1).max(50).default(12).openapi({ description: "Number of items (max 50)" }),
@@ -26424,34 +26502,29 @@ var OS = new $y(), kS = X({
26424
26502
  authors: G_([J(), z_(J())]).optional(),
26425
26503
  categories: G_([J(), z_(J())]).optional(),
26426
26504
  tags: G_([J(), z_(J())]).optional()
26427
- }), AS = async (e) => {
26505
+ }), jS = async (e) => {
26428
26506
  try {
26429
- 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];
26430
- n.channelId && n.channelId !== "all" && (a += " AND id IN (SELECT nodeId FROM node_channels WHERE channelId = ?)", o.push(Number(n.channelId) || n.channelId));
26431
- let s = (e, t, n = !1) => {
26507
+ 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];
26508
+ 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));
26509
+ let s = (/* @__PURE__ */ new Date()).toISOString();
26510
+ a += " AND IFNULL(json_extract(dataJson, '$.startShowingAt'), '') <= ?", o.push(s), a += " AND IFNULL(json_extract(dataJson, '$.stopShowingAt'), '9999-12-31') >= ?", o.push(s);
26511
+ let c = (e, t, n = !1) => {
26432
26512
  let r = Array.isArray(t) ? t : t.split(",").map((e) => e.trim());
26433
26513
  if (r.length === 0) return;
26434
26514
  let i = r.map(() => "?").join(",");
26435
- n ? (a += ` AND EXISTS (
26436
- SELECT 1 FROM node_relations nr
26437
- WHERE nr.sourceNodeId = content_nodes.id AND nr.fieldKey = ? AND nr.targetNodeId IN (${i})
26438
- )`, o.push(e, ...r)) : (a += ` AND EXISTS (
26439
- SELECT 1 FROM node_terms nt
26440
- INNER JOIN taxonomy_terms tt ON nt.termId = tt.id
26441
- WHERE nt.nodeId = content_nodes.id AND tt.taxonomy = ? AND tt.key IN (${i})
26442
- )`, o.push(e, ...r));
26515
+ 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));
26443
26516
  };
26444
- n.authors && s("authors", n.authors, !0), n.categories && s("categories", n.categories, !1), n.tags && s("tags", n.tags, !1);
26445
- let c = "ORDER BY updatedAt DESC";
26446
- n.sortBy === "createdAt" ? c = "ORDER BY createdAt DESC" : n.sortBy === "title_asc" && (c = "ORDER BY LOWER(title) ASC");
26447
- let l = `SELECT id, title, slug, language, dataJson, createdAt, updatedAt ${a} ${c} LIMIT ? OFFSET ?`;
26517
+ n.authors && c("authors", n.authors, !0), n.categories && c("categories", n.categories, !1), n.tags && c("tags", n.tags, !1);
26518
+ let l = "ORDER BY updatedAt DESC";
26519
+ n.sortBy === "createdAt" ? l = "ORDER BY createdAt DESC" : n.sortBy === "title_asc" && (l = "ORDER BY LOWER(title) ASC");
26520
+ let u = `SELECT id, title, slug, language, dataJson, createdAt, updatedAt ${a} ${l} LIMIT ? OFFSET ?`;
26448
26521
  o.push(n.limit, n.offset);
26449
- let u = await t.prepare(l).all(...o), d = Array.isArray(u) ? u : u?.results || [], f = Date.now(), p = d.map((e) => {
26522
+ let d = await t.prepare(u).all(...o), f = Array.isArray(d) ? d : d?.results || [], p = f.map((e) => {
26450
26523
  let t = {};
26451
26524
  try {
26452
26525
  t = typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson || {};
26453
26526
  } catch {}
26454
- return t.startShowingAt && Date.parse(t.startShowingAt) > f || t.stopShowingAt && Date.parse(t.stopShowingAt) < f ? null : {
26527
+ return {
26455
26528
  id: e.id,
26456
26529
  title: e.title,
26457
26530
  slug: e.slug,
@@ -26462,22 +26535,23 @@ var OS = new $y(), kS = X({
26462
26535
  image: t.image || t.coverImage || null,
26463
26536
  author: t.author || null
26464
26537
  };
26465
- }).filter(Boolean);
26538
+ });
26466
26539
  return e.json({
26467
26540
  items: p,
26468
26541
  count: p.length,
26542
+ rawCount: f.length,
26469
26543
  limit: n.limit,
26470
26544
  offset: n.offset
26471
26545
  }, 200);
26472
26546
  } catch (t) {
26473
26547
  return console.error("[CMS API] Error fetching nodes list:", t), e.json({ error: "Failed to fetch nodes list" }, 500);
26474
26548
  }
26475
- }, jS = eb({
26549
+ }, MS = eb({
26476
26550
  method: "get",
26477
26551
  path: "/",
26478
26552
  summary: "Fetch filtered list of nodes",
26479
26553
  tags: ["Public Node API"],
26480
- request: { query: kS },
26554
+ request: { query: AS },
26481
26555
  responses: {
26482
26556
  200: {
26483
26557
  description: "List of nodes",
@@ -26486,9 +26560,9 @@ var OS = new $y(), kS = X({
26486
26560
  500: { description: "Server error" }
26487
26561
  }
26488
26562
  });
26489
- OS.openapi(jS, AS);
26490
- var MS = new $y();
26491
- function NS(e, t) {
26563
+ kS.openapi(MS, jS);
26564
+ var NS = new $y();
26565
+ function PS(e, t) {
26492
26566
  let n = /* @__PURE__ */ new Date();
26493
26567
  if (e && String(e).trim() !== "") {
26494
26568
  let t = new Date(e);
@@ -26500,22 +26574,22 @@ function NS(e, t) {
26500
26574
  }
26501
26575
  return !0;
26502
26576
  }
26503
- async function PS(e, t, n, r) {
26577
+ async function FS(e, t, n, r) {
26504
26578
  try {
26505
26579
  await e.set(t, n, r);
26506
26580
  } catch (e) {
26507
26581
  console.warn("[CMS Cache] Failed to write tree response to cache:", e);
26508
26582
  }
26509
26583
  }
26510
- var FS = X({ treeParam: J().openapi({ description: "The ID or key of the requested tree (e.g., \"main-nav\")" }) }), IS = X({
26584
+ var IS = X({ treeParam: J().openapi({ description: "The ID or key of the requested tree (e.g., \"main-nav\")" }) }), LS = X({
26511
26585
  channelId: J().optional().openapi({ description: "Channel ID to resolve context-aware routing" }),
26512
26586
  channel: J().optional().openapi({ description: "Legacy alias for channelId" }),
26513
26587
  lang: J().optional().openapi({ description: "Requested language code for tree nodes" }),
26514
26588
  preview: lv(["true", "false"]).optional().openapi({ description: "Set to true to retrieve unpublished draft data" })
26515
- }), LS = X({
26589
+ }), RS = X({
26516
26590
  error: J(),
26517
26591
  details: J().optional()
26518
- }).openapi("ErrorResponse"), RS = qv(() => X({
26592
+ }).openapi("ErrorResponse"), zS = qv(() => X({
26519
26593
  id: G_([J(), c_()]),
26520
26594
  treeNodeId: G_([J(), c_()]),
26521
26595
  parentId: G_([J(), c_()]).nullable(),
@@ -26528,40 +26602,40 @@ var FS = X({ treeParam: J().openapi({ description: "The ID or key of the request
26528
26602
  summary: J(),
26529
26603
  url: J().optional(),
26530
26604
  target: J().optional(),
26531
- children: z_(RS).optional()
26532
- })).openapi("TreeItem"), zS = X({
26605
+ children: z_(zS).optional()
26606
+ })).openapi("TreeItem"), BS = X({
26533
26607
  treeId: G_([c_(), J()]),
26534
26608
  key: J(),
26535
26609
  channelId: J(),
26536
26610
  language: J().nullable(),
26537
26611
  label: J(),
26538
- items: z_(RS)
26539
- }).catchall(k_()).openapi("TreeResponse"), BS = eb({
26612
+ items: z_(zS)
26613
+ }).catchall(k_()).openapi("TreeResponse"), VS = eb({
26540
26614
  method: "get",
26541
26615
  path: "/{treeParam}",
26542
26616
  summary: "Fetch CMS Navigation Tree",
26543
26617
  description: "Retrieves a fully hydrated, recursive navigation tree structure. Uses $O(1)$ pre-computed routing table paths.",
26544
26618
  tags: ["Public Tree API"],
26545
26619
  request: {
26546
- params: FS,
26547
- query: IS
26620
+ params: IS,
26621
+ query: LS
26548
26622
  },
26549
26623
  responses: {
26550
26624
  200: {
26551
26625
  description: "Fully hydrated CMS Tree payload",
26552
- content: { "application/json": { schema: zS } }
26626
+ content: { "application/json": { schema: BS } }
26553
26627
  },
26554
26628
  404: {
26555
26629
  description: "Tree or Channel not found / inactive",
26556
- content: { "application/json": { schema: LS } }
26630
+ content: { "application/json": { schema: RS } }
26557
26631
  },
26558
26632
  500: {
26559
26633
  description: "Server error during hydration",
26560
- content: { "application/json": { schema: LS } }
26634
+ content: { "application/json": { schema: RS } }
26561
26635
  }
26562
26636
  }
26563
26637
  });
26564
- MS.openapi(BS, async (e) => {
26638
+ NS.openapi(VS, async (e) => {
26565
26639
  try {
26566
26640
  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;
26567
26641
  if (i && i !== "default" && i !== "all") {
@@ -26596,7 +26670,7 @@ MS.openapi(BS, async (e) => {
26596
26670
  }
26597
26671
  let v = [];
26598
26672
  if (g !== null) {
26599
- 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);
26673
+ 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);
26600
26674
  v = Array.isArray(e) ? e : e?.results || [];
26601
26675
  }
26602
26676
  if ((!v || v.length === 0) && !u) return e.json({ error: `Tree '${n}' not found` }, 404);
@@ -26624,7 +26698,7 @@ MS.openapi(BS, async (e) => {
26624
26698
  return (y.get(n) || []).map((e) => {
26625
26699
  let n = b.get(String(e.id)) || {}, r = {};
26626
26700
  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);
26627
- 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 = {
26701
+ 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 = {
26628
26702
  id: e.id,
26629
26703
  treeNodeId: e.id,
26630
26704
  parentId: e.parentId || null,
@@ -26650,7 +26724,7 @@ MS.openapi(BS, async (e) => {
26650
26724
  ..._,
26651
26725
  items: x(null)
26652
26726
  };
26653
- return !o && !h && (e.header("X-Cache", "MISS"), await PS(p, m, S, 300)), e.json(S, 200);
26727
+ return !o && !h && (e.header("X-Cache", "MISS"), await FS(p, m, S, 300)), e.json(S, 200);
26654
26728
  } catch (t) {
26655
26729
  return console.error("[CMS Public Tree API] Error:", t), e.json({
26656
26730
  error: "Failed to fetch public tree",
@@ -26658,19 +26732,19 @@ MS.openapi(BS, async (e) => {
26658
26732
  }, 500);
26659
26733
  }
26660
26734
  });
26661
- var VS = new $y();
26662
- function HS(e) {
26735
+ var HS = new $y();
26736
+ function US(e) {
26663
26737
  let t = Number(e?.env?.CMS_CHANNEL_CACHE_TTL);
26664
26738
  return Number.isFinite(t) && t >= 60 ? Math.floor(t) : 300;
26665
26739
  }
26666
- async function US(e, t, n, r) {
26740
+ async function WS(e, t, n, r) {
26667
26741
  try {
26668
26742
  await e.set(t, n, r);
26669
26743
  } catch (e) {
26670
26744
  console.warn("[CMS Cache] Failed to write channel response to cache:", e);
26671
26745
  }
26672
26746
  }
26673
- function WS(e, t) {
26747
+ function GS(e, t) {
26674
26748
  let n = {}, r = (e) => {
26675
26749
  if (!e || typeof e != "string") return;
26676
26750
  let n = t?.fieldSets?.[e] || t?.fieldsets?.[e] || t?.definitions?.[e] || t?.channels?.[e] || t?.[e];
@@ -26681,7 +26755,7 @@ function WS(e, t) {
26681
26755
  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);
26682
26756
  return n;
26683
26757
  }
26684
- function GS(e, t = {}) {
26758
+ function KS(e, t = {}) {
26685
26759
  let n = {}, r = Object.keys(t).length > 0;
26686
26760
  for (let [i, a] of Object.entries(e)) {
26687
26761
  if (i.endsWith("_meta") || [
@@ -26700,14 +26774,14 @@ function GS(e, t = {}) {
26700
26774
  }
26701
26775
  return n;
26702
26776
  }
26703
- function KS(e) {
26704
- if (Array.isArray(e)) return e.map(KS);
26777
+ function qS(e) {
26778
+ if (Array.isArray(e)) return e.map(qS);
26705
26779
  if (!e || typeof e != "object") return e;
26706
26780
  if (typeof e.id == "string" && e.id.startsWith("ast_") && typeof e.url == "string") {
26707
26781
  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 ? {
26708
26782
  ...t,
26709
26783
  ...t.crops?.[r] || {}
26710
- } : t, a = Object.fromEntries(Object.entries(n).filter(([, t]) => t?.id !== e.id).map(([t, n]) => [t, KS({
26784
+ } : t, a = Object.fromEntries(Object.entries(n).filter(([, t]) => t?.id !== e.id).map(([t, n]) => [t, qS({
26711
26785
  ...n,
26712
26786
  title: n?.title ?? e.title ?? "",
26713
26787
  alt: n?.alt ?? e.alt ?? "",
@@ -26721,9 +26795,19 @@ function KS(e) {
26721
26795
  ...Object.keys(a).length > 0 ? { variants: a } : {}
26722
26796
  };
26723
26797
  }
26724
- return Object.fromEntries(Object.entries(e).map(([e, t]) => [e, KS(t)]));
26798
+ return Object.fromEntries(Object.entries(e).map(([e, t]) => [e, qS(t)]));
26799
+ }
26800
+ async function JS(e, t, n) {
26801
+ let r = t.href.match(/^#node:(.+)$/), i = t.href.match(/^#asset:(.+)$/);
26802
+ if (i) {
26803
+ let t = i[1], n = await e.prepare("SELECT cdnUrl, storageKeyPrivate FROM assets WHERE id = ?").get(t);
26804
+ return n?.cdnUrl || (n?.storageKeyPrivate ? `/media/${n.storageKeyPrivate}` : "#");
26805
+ }
26806
+ if (!r) return t.href;
26807
+ let a = r[1];
26808
+ return (await e.prepare("SELECT path FROM node_routes WHERE nodeId = ? AND channelId = ? AND isCanonical = 1 LIMIT 1").get(Number(a), n))?.path || "#";
26725
26809
  }
26726
- async function qS(e, t, n) {
26810
+ async function YS(e, t, n) {
26727
26811
  if (typeof t == "string") {
26728
26812
  if (!t.includes("#node:") && !t.includes("data-node-id") && !t.includes("#asset:") && !t.includes("data-asset-id")) return t;
26729
26813
  let r = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Set();
@@ -26756,45 +26840,52 @@ async function qS(e, t, n) {
26756
26840
  return /href\s*=\s*["'][^"']*["']/i.test(d) ? d = d.replace(/href\s*=\s*["'][^"']*["']/i, `href="${u}"`) : d += ` href="${u}"`, `<a ${d}>`;
26757
26841
  });
26758
26842
  }
26759
- if (Array.isArray(t)) return Promise.all(t.map((t) => qS(e, t, n)));
26843
+ if (Array.isArray(t)) return Promise.all(t.map((t) => YS(e, t, n)));
26760
26844
  if (t && typeof t == "object") {
26761
- let r = await Promise.all(Object.entries(t).map(async ([t, r]) => [t, await qS(e, r, n)]));
26845
+ if (typeof t.href == "string" && (t.href.startsWith("#node:") || t.href.startsWith("#asset:"))) {
26846
+ 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)]));
26847
+ return {
26848
+ ...Object.fromEntries(i),
26849
+ href: r
26850
+ };
26851
+ }
26852
+ let r = await Promise.all(Object.entries(t).map(async ([t, r]) => [t, await YS(e, r, n)]));
26762
26853
  return Object.fromEntries(r);
26763
26854
  }
26764
26855
  return t;
26765
26856
  }
26766
- 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({
26857
+ 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({
26767
26858
  error: J(),
26768
26859
  details: J().optional()
26769
- }).openapi("ErrorResponse"), ZS = X({
26860
+ }).openapi("ErrorResponse"), $S = X({
26770
26861
  id: G_([c_(), J()]),
26771
26862
  key: J()
26772
- }).catchall(k_()).openapi("ChannelResponse"), QS = eb({
26863
+ }).catchall(k_()).openapi("ChannelResponse"), eC = eb({
26773
26864
  method: "get",
26774
26865
  path: "/{channelParam}",
26775
26866
  summary: "Fetch CMS Channel Settings",
26776
26867
  description: "Retrieves the fully hydrated, public-facing settings and payload for a specific CMS channel.",
26777
26868
  tags: ["Public Channel API"],
26778
26869
  request: {
26779
- params: JS,
26780
- query: YS
26870
+ params: XS,
26871
+ query: ZS
26781
26872
  },
26782
26873
  responses: {
26783
26874
  200: {
26784
26875
  description: "Fully hydrated CMS Channel payload",
26785
- content: { "application/json": { schema: ZS } }
26876
+ content: { "application/json": { schema: $S } }
26786
26877
  },
26787
26878
  404: {
26788
26879
  description: "Channel not found or inactive",
26789
- content: { "application/json": { schema: XS } }
26880
+ content: { "application/json": { schema: QS } }
26790
26881
  },
26791
26882
  500: {
26792
26883
  description: "Server error during hydration",
26793
- content: { "application/json": { schema: XS } }
26884
+ content: { "application/json": { schema: QS } }
26794
26885
  }
26795
26886
  }
26796
26887
  });
26797
- VS.openapi(QS, async (e) => {
26888
+ HS.openapi(eC, async (e) => {
26798
26889
  try {
26799
26890
  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);
26800
26891
  if (!i && !a) {
@@ -26805,23 +26896,23 @@ VS.openapi(QS, async (e) => {
26805
26896
  if (!c) return e.json({ error: `Channel '${n}' not found` }, 404);
26806
26897
  let l = c.status === "disabled" || c.status === "inactive" || c.isEnabled === 0 || c.isEnabled === !1;
26807
26898
  if (!i && l) return e.json({ error: `Channel '${c.key || n}' is currently inactive` }, 404);
26808
- 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;
26899
+ 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;
26809
26900
  if (g) try {
26810
26901
  h = typeof g == "string" ? JSON.parse(g) : g;
26811
26902
  } catch (e) {
26812
26903
  console.warn("[CMS Public Channel API] Failed to parse channel dataJson:", e);
26813
26904
  }
26814
- let _ = GS({
26905
+ let _ = KS({
26815
26906
  ...h,
26816
26907
  ...c
26817
26908
  }, m);
26818
- _ = await fx(t, _), _ = KS(_), _ = await qS(t, _, u);
26909
+ _ = await fx(t, _), _ = qS(_), _ = await YS(t, _, u);
26819
26910
  let v = {
26820
26911
  id: c.id,
26821
26912
  key: c.key,
26822
26913
  ..._
26823
26914
  };
26824
- return !i && !a && (e.header("X-Cache", "MISS"), await US(s, o, v, HS(e))), e.json(v, 200);
26915
+ return !i && !a && (e.header("X-Cache", "MISS"), await WS(s, o, v, US(e))), e.json(v, 200);
26825
26916
  } catch (t) {
26826
26917
  return console.error("[CMS Public Channel API] Error:", t), e.json({
26827
26918
  error: "Failed to fetch public channel",
@@ -26829,8 +26920,8 @@ VS.openapi(QS, async (e) => {
26829
26920
  }, 500);
26830
26921
  }
26831
26922
  });
26832
- var $S = new $y();
26833
- function eC(e, t) {
26923
+ var tC = new $y();
26924
+ function nC(e, t) {
26834
26925
  if (t === "webp") return "image/webp";
26835
26926
  if (t === "avif") return "image/avif";
26836
26927
  if (t === "jpeg" || t === "jpg") return "image/jpeg";
@@ -26839,7 +26930,7 @@ function eC(e, t) {
26839
26930
  let n = e.toLowerCase();
26840
26931
  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";
26841
26932
  }
26842
- var tC = [
26933
+ var rC = [
26843
26934
  320,
26844
26935
  640,
26845
26936
  768,
@@ -26849,10 +26940,10 @@ var tC = [
26849
26940
  2560,
26850
26941
  3840
26851
26942
  ];
26852
- function nC(e) {
26853
- if (!(!e || isNaN(e) || e <= 0)) return tC.reduce((t, n) => Math.abs(n - e) < Math.abs(t - e) ? n : t);
26943
+ function iC(e) {
26944
+ if (!(!e || isNaN(e) || e <= 0)) return rC.reduce((t, n) => Math.abs(n - e) < Math.abs(t - e) ? n : t);
26854
26945
  }
26855
- var rC = eb({
26946
+ var aC = eb({
26856
26947
  method: "get",
26857
26948
  path: "/*",
26858
26949
  summary: "Serve & Optimize Media Assets",
@@ -26912,11 +27003,11 @@ var rC = eb({
26912
27003
  }
26913
27004
  }
26914
27005
  });
26915
- $S.openapi(rC, async (e) => {
27006
+ tC.openapi(aC, async (e) => {
26916
27007
  try {
26917
27008
  let t = e.req.path.replace(/^\/media\//, "").replace(/^\//, "");
26918
27009
  if (!t) return e.text("Asset key missing", 400);
26919
- 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 = "";
27010
+ 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 = "";
26920
27011
  if (o) {
26921
27012
  let e = !a || a === "auto";
26922
27013
  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");
@@ -26935,7 +27026,7 @@ $S.openapi(rC, async (e) => {
26935
27026
  if (!h) return e.text(`Asset not found: ${t}`, 404);
26936
27027
  if (!o) {
26937
27028
  let n = e.body(h, 200, {
26938
- "Content-Type": eC(t),
27029
+ "Content-Type": nC(t),
26939
27030
  "Cache-Control": "public, max-age=31536000, immutable"
26940
27031
  });
26941
27032
  return u && f && e.executionCtx?.waitUntil && e.executionCtx.waitUntil(u.put(f, n.clone())), n;
@@ -26949,7 +27040,7 @@ $S.openapi(rC, async (e) => {
26949
27040
  key: t,
26950
27041
  env: e.env,
26951
27042
  req: e.req.raw
26952
- }), v = eC(t, l), y = e.body(_, 200, {
27043
+ }), v = nC(t, l), y = e.body(_, 200, {
26953
27044
  "Content-Type": v,
26954
27045
  "Cache-Control": "public, max-age=31536000, immutable"
26955
27046
  });
@@ -26958,8 +27049,8 @@ $S.openapi(rC, async (e) => {
26958
27049
  return console.error("❌ [Public Assets Error]:", t), e.text("Internal Server Error", 500);
26959
27050
  }
26960
27051
  });
26961
- var iC = new $y();
26962
- function aC(e, t) {
27052
+ var oC = new $y();
27053
+ function sC(e, t) {
26963
27054
  let n = /* @__PURE__ */ new Date();
26964
27055
  if (e && String(e).trim() !== "") {
26965
27056
  let t = new Date(e);
@@ -26971,31 +27062,31 @@ function aC(e, t) {
26971
27062
  }
26972
27063
  return !0;
26973
27064
  }
26974
- var oC = X({
27065
+ var cC = X({
26975
27066
  channelId: J().optional().openapi({ description: "Optional channel ID/key to filter and resolve root paths for" }),
26976
27067
  channel: J().optional().openapi({ description: "Legacy alias for channelId" })
26977
- }), sC = z_(J()).openapi("PathsResponse"), cC = X({
27068
+ }), lC = z_(J()).openapi("PathsResponse"), uC = X({
26978
27069
  error: J(),
26979
27070
  details: J().optional()
26980
- }).openapi("ErrorResponse"), lC = eb({
27071
+ }).openapi("ErrorResponse"), dC = eb({
26981
27072
  method: "get",
26982
27073
  path: "/",
26983
27074
  summary: "Fetch All Public Paths",
26984
27075
  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.",
26985
27076
  tags: ["Public Paths API"],
26986
- request: { query: oC },
27077
+ request: { query: cC },
26987
27078
  responses: {
26988
27079
  200: {
26989
27080
  description: "Array of valid public URL paths",
26990
- content: { "application/json": { schema: sC } }
27081
+ content: { "application/json": { schema: lC } }
26991
27082
  },
26992
27083
  500: {
26993
27084
  description: "Server error fetching paths",
26994
- content: { "application/json": { schema: cC } }
27085
+ content: { "application/json": { schema: uC } }
26995
27086
  }
26996
27087
  }
26997
27088
  });
26998
- iC.openapi(lC, async (e) => {
27089
+ oC.openapi(dC, async (e) => {
26999
27090
  try {
27000
27091
  let t = e.get("db"), n = e.req.valid("query"), r = n.channelId || n.channel, i = "", a = [];
27001
27092
  if (r && r !== "all") {
@@ -27006,7 +27097,8 @@ iC.openapi(lC, async (e) => {
27006
27097
  SELECT
27007
27098
  nr.path,
27008
27099
  cn.contentType as nodeType,
27009
- cn.dataJson
27100
+ cn.startShowingAt,
27101
+ cn.stopShowingAt
27010
27102
  FROM node_routes nr
27011
27103
  INNER JOIN content_nodes cn ON nr.nodeId = cn.id
27012
27104
  WHERE nr.isCanonical = 1
@@ -27015,27 +27107,19 @@ iC.openapi(lC, async (e) => {
27015
27107
  ${i}
27016
27108
  ORDER BY nr.path ASC
27017
27109
  `).all(...a), s = Array.isArray(o) ? o : o?.results || [], c = [];
27018
- for (let e of s) {
27019
- if (e.nodeType === "external-link" || !e.path) continue;
27020
- let t = !0;
27021
- if (e.dataJson) try {
27022
- let n = typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson;
27023
- t = aC(n?.startShowingAt, n?.stopShowingAt);
27024
- } catch {}
27025
- t && c.push(e.path);
27026
- }
27110
+ for (let e of s) e.nodeType !== "external-link" && e.path && sC(e.startShowingAt, e.stopShowingAt) && c.push(e.path);
27027
27111
  let l = [...new Set(c)];
27028
27112
  return e.json(l, 200);
27029
27113
  } catch (t) {
27030
27114
  return console.error("[CMS Paths API] Error:", t), e.json({ error: "Failed to fetch paths" }, 500);
27031
27115
  }
27032
27116
  });
27033
- var uC = new $y();
27034
- function dC(e) {
27117
+ var fC = new $y();
27118
+ function pC(e) {
27035
27119
  let t = (e || "").trim().toLowerCase(), n = px()?.taxonomies || {};
27036
27120
  return n[t] ? t : n[`${t}s`] ? `${t}s` : t.endsWith("s") && n[t.slice(0, -1)] ? t.slice(0, -1) : t;
27037
27121
  }
27038
- var fC = X({
27122
+ var mC = X({
27039
27123
  id: c_(),
27040
27124
  taxonomy: J(),
27041
27125
  key: J(),
@@ -27045,14 +27129,14 @@ var fC = X({
27045
27129
  data: tv(k_()),
27046
27130
  createdAt: J(),
27047
27131
  updatedAt: J()
27048
- }), pC = X({
27132
+ }), hC = X({
27049
27133
  taxonomy: J(),
27050
- items: z_(fC),
27134
+ items: z_(mC),
27051
27135
  total: c_()
27052
- }).openapi("TaxonomyResponse"), mC = X({
27136
+ }).openapi("TaxonomyResponse"), gC = X({
27053
27137
  error: J(),
27054
27138
  details: J().optional()
27055
- }).openapi("ErrorResponse"), hC = eb({
27139
+ }).openapi("ErrorResponse"), _C = eb({
27056
27140
  method: "get",
27057
27141
  path: "/{taxonomy}",
27058
27142
  summary: "Fetch Public Taxonomy Terms",
@@ -27062,17 +27146,17 @@ var fC = X({
27062
27146
  responses: {
27063
27147
  200: {
27064
27148
  description: "List of taxonomy terms",
27065
- content: { "application/json": { schema: pC } }
27149
+ content: { "application/json": { schema: hC } }
27066
27150
  },
27067
27151
  500: {
27068
27152
  description: "Server error",
27069
- content: { "application/json": { schema: mC } }
27153
+ content: { "application/json": { schema: gC } }
27070
27154
  }
27071
27155
  }
27072
27156
  });
27073
- uC.openapi(hC, async (e) => {
27157
+ fC.openapi(_C, async (e) => {
27074
27158
  try {
27075
- 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";
27159
+ 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";
27076
27160
  if (!o) {
27077
27161
  let t = await n.get(a);
27078
27162
  if (t) return e.header("X-Cache", "HIT"), e.json(t);
@@ -27106,7 +27190,7 @@ uC.openapi(hC, async (e) => {
27106
27190
  return console.error("[Public Taxonomy API] Error fetching terms:", t), e.json({ error: "Failed to fetch taxonomy terms" }, 500);
27107
27191
  }
27108
27192
  });
27109
- var $ = new $y(), gC = !1;
27193
+ var $ = new $y(), vC = !1;
27110
27194
  $.use("*", t()), $.use("/media/*", t({
27111
27195
  origin: "*",
27112
27196
  allowMethods: [
@@ -27127,20 +27211,20 @@ $.use("*", t()), $.use("/media/*", t({
27127
27211
  let n = new URL(e.req.url), r = (e.req.header("host") || n.hostname).split(":")[0];
27128
27212
  e.set("currentDomain", r);
27129
27213
  let i = wb(e);
27130
- if (e.set("db", i), !gC) try {
27131
- await Mb(i), gC = !0;
27214
+ if (e.set("db", i), !vC) try {
27215
+ await Mb(i), vC = !0;
27132
27216
  } catch (e) {
27133
27217
  console.error("❌ [CMS Server] Failed to initialize system tables on cold start:", e);
27134
27218
  }
27135
27219
  await t();
27136
- }), $.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) => {
27220
+ }), $.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) => {
27137
27221
  let n = e.env?.FRONTEND_API_SECRET;
27138
27222
  if (n) {
27139
27223
  let t = e.req.header("Authorization"), r = e.req.header("x-api-key"), i = t?.startsWith("Bearer ") ? t.substring(7).trim() : r?.trim();
27140
27224
  if (!i || i !== n) return e.json({ error: "Unauthorized: Invalid or missing API secret." }, 401);
27141
27225
  } else console.warn("⚠️ [CMS Security] FRONTEND_API_SECRET is not set in .env. The API is completely exposed to the public.");
27142
27226
  return t();
27143
- }), $.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", {
27227
+ }), $.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", {
27144
27228
  openapi: "3.0.0",
27145
27229
  info: {
27146
27230
  title: "KAMA Engine Public API",
@@ -27159,4 +27243,4 @@ $.use("*", t()), $.use("/media/*", t({
27159
27243
  return t();
27160
27244
  });
27161
27245
  //#endregion
27162
- export { Yx as compileDefinitions };
27246
+ export { Xx as compileDefinitions };