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

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