@brightsideoy/kama 1.0.0-alpha.3 → 1.0.0-alpha.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -185,13 +185,13 @@ function C(e) {
185
185
  let t = new g();
186
186
  return e.forEach((e) => t.put(e)), [...t.values()];
187
187
  }
188
- function ee(e) {
188
+ function w(e) {
189
189
  return typeof e == "string";
190
190
  }
191
- function w(e) {
191
+ function T(e) {
192
192
  return Object.fromEntries(Object.entries(e).sort(([e], [t]) => e.localeCompare(t)));
193
193
  }
194
- var T = m(), E = class {
194
+ var ee = m(), E = class {
195
195
  static collectMetadata(e, t) {
196
196
  let n = this.getMetadataFromRegistry(e), r = Object.assign(Object.assign({}, n?._internal), t?._internal), i = Object.assign(Object.assign({}, n?.param), t?.param), a = Object.assign(Object.assign(Object.assign(Object.assign({}, Object.keys(r).length > 0 ? { _internal: r } : {}), n), t), Object.keys(i).length > 0 ? { param: i } : {});
197
197
  if (l(e, [
@@ -259,7 +259,7 @@ var T = m(), E = class {
259
259
  return t ? void 0 : e;
260
260
  }
261
261
  static getMetadataFromInternalRegistry(e) {
262
- return T.get(e);
262
+ return ee.get(e);
263
263
  }
264
264
  static getMetadataFromRegistry(e) {
265
265
  let t = this.getMetadataFromInternalRegistry(e), n = e.meta();
@@ -268,7 +268,7 @@ var T = m(), E = class {
268
268
  return Object.assign(Object.assign(Object.assign({ _internal: Object.assign(Object.assign({}, o ? { refId: o } : {}), r) }, i), c ? { description: c } : {}), l);
269
269
  }
270
270
  static setMetadataInRegistry(e, t) {
271
- T.add(e, t);
271
+ ee.add(e, t);
272
272
  }
273
273
  };
274
274
  function D(e, t) {
@@ -429,7 +429,7 @@ var oe = class extends A {
429
429
  getDiscriminatorValues(e, t) {
430
430
  if (l(e, "ZodObject")) {
431
431
  let n = e.def.shape?.[t];
432
- return n ? l(n, "ZodEnum") ? Object.values(n._zod.def.entries).filter(ee) : l(n, "ZodLiteral") ? n.def.values.filter(ee) : [] : [];
432
+ return n ? l(n, "ZodEnum") ? Object.values(n._zod.def.entries).filter(w) : l(n, "ZodLiteral") ? n.def.values.filter(w) : [] : [];
433
433
  }
434
434
  if (l(e, "ZodDiscriminatedUnion")) {
435
435
  let n = e.def.options.filter(u);
@@ -438,20 +438,20 @@ var oe = class extends A {
438
438
  return [];
439
439
  }
440
440
  };
441
- function j(e) {
441
+ function ue(e) {
442
442
  let t = Object.keys(e).filter((t) => typeof e[e[t]] != "number").map((t) => e[t]), n = t.filter((e) => typeof e == "number").length;
443
443
  return {
444
444
  values: t,
445
445
  type: n === 0 ? "string" : n === t.length ? "numeric" : "mixed"
446
446
  };
447
447
  }
448
- var ue = class {
448
+ var de = class {
449
449
  transform(e, t, n) {
450
- let { type: r, values: i } = j(e._zod.def.entries);
450
+ let { type: r, values: i } = ue(e._zod.def.entries);
451
451
  if (r === "mixed") throw new A("Enum has mixed string and number values, please specify the OpenAPI type manually");
452
452
  return Object.assign(Object.assign({}, n(r === "numeric" ? "integer" : "string")), { enum: t ? [...i, null] : i });
453
453
  }
454
- }, de = class {
454
+ }, j = class {
455
455
  transform(e, t, n, r) {
456
456
  let i = { allOf: this.flattenIntersectionTypes(e).map(r) };
457
457
  return t ? { anyOf: n([i], t) } : i;
@@ -499,7 +499,7 @@ var ue = class {
499
499
  transform(e, t, n) {
500
500
  let r = e.valueType, i = e.keyType, a = u(r) ? n(r) : {};
501
501
  if (l(i, "ZodEnum")) {
502
- let e = Object.values(i._zod.def.entries).filter(ee).reduce((e, t) => Object.assign(Object.assign({}, e), { [t]: a }), {});
502
+ let e = Object.values(i._zod.def.entries).filter(w).reduce((e, t) => Object.assign(Object.assign({}, e), { [t]: a }), {});
503
503
  return Object.assign(Object.assign({}, t("object")), { properties: e });
504
504
  }
505
505
  return Object.assign(Object.assign({}, t("object")), { additionalProperties: a });
@@ -590,7 +590,7 @@ var ve = class {
590
590
  if (l(e, "ZodNumber")) return "[+-]?\\d+(\\.\\d+)?";
591
591
  if (l(e, "ZodBoolean")) return "(true|false)";
592
592
  if (l(e, "ZodEnum")) {
593
- let { values: t } = j(e.def.entries);
593
+ let { values: t } = ue(e.def.entries);
594
594
  return `(${t.map((e) => this.escapeRegex(String(e))).join("|")})`;
595
595
  }
596
596
  return ".*";
@@ -600,7 +600,7 @@ var ve = class {
600
600
  }
601
601
  }, we = class {
602
602
  constructor(e, t) {
603
- this.versionSpecifics = e, this.objectTransformer = new me(), this.stringTransformer = new ve(), this.numberTransformer = new pe(), this.bigIntTransformer = new ce(), this.dateTransformer = new xe(), this.lazyTransformer = new Se(), this.literalTransformer = new fe(), this.templateLiteralTransformer = new Ce(), this.enumTransformer = new ue(), this.arrayTransformer = new se(), this.discriminatedUnionTransformer = new le(), this.intersectionTransformer = new de(), this.recordTransformer = new he(), this.tupleTransformer = new ye(e), this.unionTransformer = new be(t);
603
+ this.versionSpecifics = e, this.objectTransformer = new me(), this.stringTransformer = new ve(), this.numberTransformer = new pe(), this.bigIntTransformer = new ce(), this.dateTransformer = new xe(), this.lazyTransformer = new Se(), this.literalTransformer = new fe(), this.templateLiteralTransformer = new Ce(), this.enumTransformer = new de(), this.arrayTransformer = new se(), this.discriminatedUnionTransformer = new le(), this.intersectionTransformer = new j(), this.recordTransformer = new he(), this.tupleTransformer = new ye(e), this.unionTransformer = new be(t);
604
604
  }
605
605
  transform(e, t, n, r, i) {
606
606
  if (l(e, "ZodNull")) return this.versionSpecifics.nullType;
@@ -650,7 +650,7 @@ var ve = class {
650
650
  this.rawComponents.forEach(({ componentType: t, name: n, component: r }) => {
651
651
  e[t] ?? (e[t] = {}), e[t][n] = r;
652
652
  });
653
- let t = e.schemas ?? {}, n = Object.assign(Object.assign({}, t), this.filteredSchemaRefs), r = this.options?.sortComponents === "alphabetically" ? w(n) : n, i = e.parameters ?? {}, a = Object.assign(Object.assign({}, i), this.paramRefs), o = this.options?.sortComponents === "alphabetically" ? w(a) : a;
653
+ let t = e.schemas ?? {}, n = Object.assign(Object.assign({}, t), this.filteredSchemaRefs), r = this.options?.sortComponents === "alphabetically" ? T(n) : n, i = e.parameters ?? {}, a = Object.assign(Object.assign({}, i), this.paramRefs), o = this.options?.sortComponents === "alphabetically" ? T(a) : a;
654
654
  return Object.assign(Object.assign({}, e), {
655
655
  schemas: r,
656
656
  parameters: o
@@ -22060,18 +22060,18 @@ var Fb = { hasSubscribers: !1 }, Ib = Fb, Lb = Fb, Rb = typeof performance == "o
22060
22060
  return this.#i;
22061
22061
  }
22062
22062
  constructor(t) {
22063
- let { max: n = 0, ttl: r, ttlResolution: i = 1, ttlAutopurge: a, updateAgeOnGet: o, updateAgeOnHas: s, allowStale: c, dispose: l, onInsert: u, disposeAfter: d, noDisposeOnSet: f, noUpdateTTL: p, maxSize: m = 0, maxEntrySize: h = 0, sizeCalculation: g, fetchMethod: _, memoMethod: v, noDeleteOnFetchRejection: y, noDeleteOnStaleGet: b, allowStaleOnFetchRejection: x, allowStaleOnFetchAbort: S, ignoreFetchAbort: C, backgroundFetchSize: ee = 1, perf: w } = t;
22064
- if (this.backgroundFetchSize = ee, w !== void 0 && typeof w?.now != "function") throw TypeError("perf option must have a now() method if specified");
22065
- if (this.#s = w ?? Rb, n !== 0 && !Wb(n)) throw TypeError("max option must be a nonnegative integer");
22066
- let T = n ? Gb(n) : Array;
22067
- if (!T) throw Error("invalid max value: " + n);
22063
+ let { max: n = 0, ttl: r, ttlResolution: i = 1, ttlAutopurge: a, updateAgeOnGet: o, updateAgeOnHas: s, allowStale: c, dispose: l, onInsert: u, disposeAfter: d, noDisposeOnSet: f, noUpdateTTL: p, maxSize: m = 0, maxEntrySize: h = 0, sizeCalculation: g, fetchMethod: _, memoMethod: v, noDeleteOnFetchRejection: y, noDeleteOnStaleGet: b, allowStaleOnFetchRejection: x, allowStaleOnFetchAbort: S, ignoreFetchAbort: C, backgroundFetchSize: w = 1, perf: T } = t;
22064
+ if (this.backgroundFetchSize = w, T !== void 0 && typeof T?.now != "function") throw TypeError("perf option must have a now() method if specified");
22065
+ if (this.#s = T ?? Rb, n !== 0 && !Wb(n)) throw TypeError("max option must be a nonnegative integer");
22066
+ let ee = n ? Gb(n) : Array;
22067
+ if (!ee) throw Error("invalid max value: " + n);
22068
22068
  if (this.#e = n, this.#t = m, this.maxEntrySize = h || this.#t, this.sizeCalculation = g, this.sizeCalculation) {
22069
22069
  if (!this.#t && !this.maxEntrySize) throw TypeError("cannot set sizeCalculation without setting maxSize or maxEntrySize");
22070
22070
  if (typeof this.sizeCalculation != "function") throw TypeError("sizeCalculation set to non-function");
22071
22071
  }
22072
22072
  if (v !== void 0 && typeof v != "function") throw TypeError("memoMethod must be a function if defined");
22073
22073
  if (this.#o = v, _ !== void 0 && typeof _ != "function") throw TypeError("fetchMethod must be a function if specified");
22074
- if (this.#a = _, this.#w = !!_, this.#u = /* @__PURE__ */ new Map(), this.#d = Array.from({ length: n }).fill(void 0), this.#f = Array.from({ length: n }).fill(void 0), this.#p = new T(n), this.#m = new T(n), this.#h = 0, this.#g = 0, this.#_ = qb.create(n), this.#c = 0, this.#l = 0, typeof l == "function" && (this.#n = l), typeof u == "function" && (this.#r = u), typeof d == "function" ? (this.#i = d, this.#v = []) : (this.#i = void 0, this.#v = void 0), this.#C = !!this.#n, this.#E = !!this.#r, this.#T = !!this.#i, this.noDisposeOnSet = !!f, this.noUpdateTTL = !!p, this.noDeleteOnFetchRejection = !!y, this.allowStaleOnFetchRejection = !!x, this.allowStaleOnFetchAbort = !!S, this.ignoreFetchAbort = !!C, this.maxEntrySize !== 0) {
22074
+ if (this.#a = _, this.#w = !!_, this.#u = /* @__PURE__ */ new Map(), this.#d = Array.from({ length: n }).fill(void 0), this.#f = Array.from({ length: n }).fill(void 0), this.#p = new ee(n), this.#m = new ee(n), this.#h = 0, this.#g = 0, this.#_ = qb.create(n), this.#c = 0, this.#l = 0, typeof l == "function" && (this.#n = l), typeof u == "function" && (this.#r = u), typeof d == "function" ? (this.#i = d, this.#v = []) : (this.#i = void 0, this.#v = void 0), this.#C = !!this.#n, this.#E = !!this.#r, this.#T = !!this.#i, this.noDisposeOnSet = !!f, this.noUpdateTTL = !!p, this.noDeleteOnFetchRejection = !!y, this.allowStaleOnFetchRejection = !!x, this.allowStaleOnFetchAbort = !!S, this.ignoreFetchAbort = !!C, this.maxEntrySize !== 0) {
22075
22075
  if (this.#t !== 0 && !Wb(this.#t)) throw TypeError("maxSize must be a positive integer if specified");
22076
22076
  if (!Wb(this.maxEntrySize)) throw TypeError("maxEntrySize must be a positive integer if specified");
22077
22077
  this.#M();
@@ -23190,7 +23190,7 @@ var fx = class {
23190
23190
  });
23191
23191
  return clearTimeout(n), r;
23192
23192
  } catch (e) {
23193
- return e.name === "AbortError" ? console.info(`[CacheManager] Purge request to ${c} timed out (dev server un-responsive).`) : e?.cause?.code === "ECONNREFUSED" || e?.code === "ECONNREFUSED" ? console.info(`[CacheManager] Frontend purge listener offline at ${s} (port not reachable).`) : console.warn(`[CacheManager] Non-fatal purge warning for ${c}:`, e?.message || e), new Response(JSON.stringify({ error: "Connection refused or timed out" }), { status: 503 });
23193
+ return e.name === "AbortError" ? console.info(`[CacheManager] Purge request to ${c} timed out (dev server un-responsive).`) : e?.cause?.code === "ECONNREFUSED" || e?.code === "ECONNREFUSED" ? console.info(`[CacheManager] Frontend purge listener offline at ${s}.`) : console.warn(`[CacheManager] Non-fatal purge warning for ${c}:`, e?.message || e), new Response(JSON.stringify({ error: "Connection refused or timed out" }), { status: 503 });
23194
23194
  }
23195
23195
  }
23196
23196
  async purgeInternalWorkerCache(e, t, n, r, i) {
@@ -23213,67 +23213,70 @@ var fx = class {
23213
23213
  }
23214
23214
  }
23215
23215
  purgeNode(e, t, n, r = !1, i = []) {
23216
+ if (r) {
23217
+ console.log(`[CacheManager] Structural change detected on nodeId ${n}. Escalating to Global Purge.`), this.purgeGlobalCache(e, t);
23218
+ return;
23219
+ }
23216
23220
  let a = (async () => {
23217
23221
  try {
23218
- let a = t.prepare("SELECT slug, status, language FROM content_nodes WHERE id = ?"), o = (typeof a.get == "function" ? await a.get(n) : (await a.bind(n).all())?.results?.[0]) || {};
23219
- if (!o.slug) return;
23220
- let s = t.prepare("\n SELECT c.id, c.key, c.baseUrl, c.defaultLanguage \n FROM node_channels nc \n JOIN channels c ON nc.channelId = c.id \n WHERE nc.nodeId = ?\n "), c = typeof s.all == "function" ? await s.all(n) : await s.bind(n).all(), l = Array.isArray(c) ? c : c?.results || [], u = l.length > 0 ? l[0]?.defaultLanguage?.trim() : null, d = o.language?.trim() || u || null, f = String(o.slug).replace(/^\/+|\/+$/g, ""), p = this.getEnv(e).frontendUrl, m = /* @__PURE__ */ new Set();
23221
- for (let e of l) if (e.baseUrl && typeof e.baseUrl == "string" && e.baseUrl.trim() !== "") {
23222
+ let r = t.prepare("SELECT slug, status, language FROM content_nodes WHERE id = ?"), a = (typeof r.get == "function" ? await r.get(n) : (await r.bind(n).all())?.results?.[0]) || {};
23223
+ if (!a.slug) return;
23224
+ let o = t.prepare("\n SELECT c.id, c.key, c.baseUrl, c.defaultLanguage \n FROM node_channels nc \n JOIN channels c ON nc.channelId = c.id \n WHERE nc.nodeId = ?\n "), s = typeof o.all == "function" ? await o.all(n) : await o.bind(n).all(), c = Array.isArray(s) ? s : s?.results || [], l = c.length > 0 ? c[0]?.defaultLanguage?.trim() : null, u = a.language?.trim() || l || null, d = String(a.slug).replace(/^\/+|\/+$/g, ""), f = this.getEnv(e).frontendUrl, p = /* @__PURE__ */ new Set();
23225
+ for (let e of c) if (e.baseUrl && typeof e.baseUrl == "string" && e.baseUrl.trim() !== "") {
23222
23226
  let t = e.baseUrl.trim();
23223
- !t.startsWith("http://") && !t.startsWith("https://") && (t = `https://${t}`), m.add(t.replace(/\/+$/, ""));
23227
+ !t.startsWith("http://") && !t.startsWith("https://") && (t = `https://${t}`), p.add(t.replace(/\/+$/, ""));
23224
23228
  }
23225
- m.size === 0 && p && m.add(p);
23226
- let h = t.prepare("\n SELECT DISTINCT a.cdnUrl, a.storageKeyPrivate\n FROM node_assets na\n JOIN assets a ON na.assetId = a.id\n WHERE na.nodeId = ?\n "), g = typeof h.all == "function" ? await h.all(n) : await h.bind(n).all(), _ = (Array.isArray(g) ? g : g?.results || []).map((t) => t.url || this.getSafeUrl(t.cdnUrl, t.storageKeyPrivate, this.getEnv(e).cdnDomain)).filter(Boolean);
23227
- await this.purgeInternalWorkerCache(e, t, n, f, d);
23228
- let v = this.getEnv(e).cdnDomain, { zoneId: y, apiToken: b } = this.getEnv(e), x = e.env?.BUNDLED_DEFINITIONS || {}, S = /* @__PURE__ */ new Set();
23229
- if (i.length > 0 && x.layouts) for (let e of Object.values(x.layouts)) for (let t of i) {
23229
+ p.size === 0 && f && p.add(f);
23230
+ let m = t.prepare("\n SELECT DISTINCT a.cdnUrl, a.storageKeyPrivate\n FROM node_assets na\n JOIN assets a ON na.assetId = a.id\n WHERE na.nodeId = ?\n "), h = typeof m.all == "function" ? await m.all(n) : await m.bind(n).all(), g = (Array.isArray(h) ? h : h?.results || []).map((t) => t.url || this.getSafeUrl(t.cdnUrl, t.storageKeyPrivate, this.getEnv(e).cdnDomain)).filter(Boolean);
23231
+ await this.purgeInternalWorkerCache(e, t, n, d, u);
23232
+ let _ = this.getEnv(e).cdnDomain, { zoneId: v, apiToken: y } = this.getEnv(e), b = e.env?.BUNDLED_DEFINITIONS || {}, x = /* @__PURE__ */ new Set();
23233
+ if (i.length > 0 && b.layouts) for (let e of Object.values(b.layouts)) for (let t of i) {
23230
23234
  let n = e.regions?.[t];
23231
23235
  if (n) {
23232
23236
  let e = n.purgeTargets || n.purgeTarget;
23233
23237
  if (e) {
23234
23238
  let t = Array.isArray(e) ? e : [e];
23235
- for (let e of t) typeof e == "string" && e.trim() && S.add(e.trim());
23239
+ for (let e of t) typeof e == "string" && e.trim() && x.add(e.trim());
23236
23240
  }
23237
23241
  }
23238
23242
  }
23239
- for (let t of m) {
23240
- let n = f === "home" || !f ? t : `${t}/${f}`, i = [n, `${n}/`];
23241
- r && i.push(`${t}/partials/nav`);
23242
- for (let e of S) {
23243
+ for (let t of p) {
23244
+ let n = d === "home" || !d ? t : `${t}/${d}`, r = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Set();
23245
+ r.add(n), r.add(`${n}/`), i.add(n), i.add(`${n}/`);
23246
+ for (let e of x) {
23243
23247
  let n = e.startsWith("/") ? e : `/${e}`;
23244
- i.push(`${t}${n}`);
23248
+ r.add(`${t}${n}`), i.add(`${t}${n}`);
23245
23249
  }
23246
- let a = d ? `&lang=${d}` : "";
23247
- if (l.length > 0) for (let e of l) e.id && i.push(`https://${v}/api/v1/node/${f}?channelId=${e.id}${a}`), e.key && i.push(`https://${v}/api/v1/node/${f}?channelId=${e.key}${a}`), r && (e.id && i.push(`https://${v}/api/v1/tree/main-nav?channelId=${e.id}`), e.key && i.push(`https://${v}/api/v1/tree/main-nav?channelId=${e.key}`));
23248
- else i.push(`https://${v}/api/v1/node/${f}${d ? `?lang=${d}` : ""}`), r && i.push(`https://${v}/api/v1/tree/main-nav`);
23249
- for (let e of _) e && i.push(`${t}${e.startsWith("/") ? e : `/${e}`}`);
23250
- if (await this.callAstroPurge(e, { urls: i }, t), y && b && !this.isLocalEnv(e, t) && fetch(`https://api.cloudflare.com/client/v4/zones/${y}/purge_cache`, {
23251
- method: "POST",
23252
- headers: {
23253
- Authorization: `Bearer ${b}`,
23254
- "Content-Type": "application/json"
23255
- },
23256
- body: JSON.stringify({ files: i })
23257
- }).catch(() => {}), r) {
23258
- let e = `${t}/partials/nav?_warmer=${Date.now()}`;
23259
- console.log(`[CacheManager] Prewarming cache at: ${e}`), fetch(e, { headers: {
23260
- "X-Cache-Warmer": "true",
23261
- "User-Agent": "Kama-Cache-Warmer/1.0"
23262
- } }).catch((e) => console.warn("[CacheManager] Prewarm fetch error:", e));
23263
- } else {
23264
- let e = `${n}${n.includes("?") ? "&" : "?"} _warmer=${Date.now()}`;
23265
- console.log(`[CacheManager] Prewarming cache at: ${e}`), fetch(e, { headers: {
23266
- "X-Cache-Warmer": "true",
23267
- "User-Agent": "Kama-Cache-Warmer/1.0"
23268
- } }).catch((e) => console.warn("[CacheManager] Prewarm fetch error:", e));
23250
+ let a = u ? `&lang=${u}` : "";
23251
+ if (c.length > 0) for (let e of c) e.id && i.add(`https://${_}/api/v1/node/${d}?channelId=${e.id}${a}`), e.key && i.add(`https://${_}/api/v1/node/${d}?channelId=${e.key}${a}`);
23252
+ else i.add(`https://${_}/api/v1/node/${d}${u ? `?lang=${u}` : ""}`);
23253
+ for (let e of g) e && i.add(`${t}${e.startsWith("/") ? e : `/${e}`}`);
23254
+ if (await this.callAstroPurge(e, { urls: Array.from(r) }, t), v && y && !this.isLocalEnv(e, t)) try {
23255
+ let e = await (await fetch(`https://api.cloudflare.com/client/v4/zones/${v}/purge_cache`, {
23256
+ method: "POST",
23257
+ headers: {
23258
+ Authorization: `Bearer ${y}`,
23259
+ "Content-Type": "application/json"
23260
+ },
23261
+ body: JSON.stringify({ files: Array.from(i) })
23262
+ })).json();
23263
+ console.log("[CacheManager] CF Zone Purge Result:", e?.success ? "SUCCESS" : JSON.stringify(e));
23264
+ } catch (e) {
23265
+ console.warn("[CacheManager] CF Zone Purge failed to dispatch:", e);
23269
23266
  }
23270
- for (let e of S) {
23271
- let n = `${t}${e.startsWith("/") ? e : `/${e}`}?_warmer=${Date.now()}`;
23272
- console.log(`[CacheManager] Prewarming custom target: ${n}`), fetch(n, { headers: {
23267
+ let o = [], s = Date.now(), l = `${n}${n.includes("?") ? "&" : "?"}_warmer=${s}`;
23268
+ console.log(`[CacheManager] Prewarming cache at: ${l}`), o.push(fetch(l, { headers: {
23269
+ "X-Cache-Warmer": "true",
23270
+ "User-Agent": "Kama-Cache-Warmer/1.0"
23271
+ } }).catch((e) => console.warn("[CacheManager] Prewarm fetch error:", e)));
23272
+ for (let e of x) {
23273
+ let n = `${t}${e.startsWith("/") ? e : `/${e}`}?_warmer=${s}`;
23274
+ console.log(`[CacheManager] Prewarming custom target: ${n}`), o.push(fetch(n, { headers: {
23273
23275
  "X-Cache-Warmer": "true",
23274
23276
  "User-Agent": "Kama-Cache-Warmer/1.0"
23275
- } }).catch(() => {});
23277
+ } }).catch(() => {}));
23276
23278
  }
23279
+ await Promise.all(o);
23277
23280
  }
23278
23281
  } catch (e) {
23279
23282
  console.warn("[CacheManager] Dynamic purgeNode failed:", e);
@@ -23299,17 +23302,26 @@ var fx = class {
23299
23302
  try {
23300
23303
  let { zoneId: n, apiToken: r } = this.getEnv(e);
23301
23304
  if (!(await this.callAstroPurge(e, { purge_everything: !0 })).ok) return;
23302
- if (n && r && !this.isLocalEnv(e) && fetch(`https://api.cloudflare.com/client/v4/zones/${n}/purge_cache`, {
23303
- method: "POST",
23304
- headers: {
23305
- Authorization: `Bearer ${r}`,
23306
- "Content-Type": "application/json"
23307
- },
23308
- body: JSON.stringify({ purge_everything: !0 })
23309
- }).catch(() => {}), await new Promise((e) => setTimeout(e, 100)), t) await this.warmAllPublishedPages(e, t);
23305
+ if (n && r && !this.isLocalEnv(e)) try {
23306
+ let e = await (await fetch(`https://api.cloudflare.com/client/v4/zones/${n}/purge_cache`, {
23307
+ method: "POST",
23308
+ headers: {
23309
+ Authorization: `Bearer ${r}`,
23310
+ "Content-Type": "application/json"
23311
+ },
23312
+ body: JSON.stringify({ purge_everything: !0 })
23313
+ })).json();
23314
+ console.log("[CacheManager] CF Global Purge Result:", e?.success ? "SUCCESS" : JSON.stringify(e));
23315
+ } catch (e) {
23316
+ console.warn("[CacheManager] CF Global Purge failed to dispatch:", e);
23317
+ }
23318
+ if (t) await this.warmAllPublishedPages(e, t);
23310
23319
  else {
23311
23320
  let { frontendUrl: t } = this.getEnv(e);
23312
- fetch(`${t.replace(/\/+$/, "")}/?_warmer=${Date.now()}`, { headers: { "X-Cache-Warmer": "true" } }).catch(() => {});
23321
+ await fetch(`${t.replace(/\/+$/, "")}/?_warmer=${Date.now()}`, { headers: {
23322
+ "X-Cache-Warmer": "true",
23323
+ "User-Agent": "Kama-Cache-Warmer/1.0"
23324
+ } }).catch(() => {});
23313
23325
  }
23314
23326
  } catch (e) {
23315
23327
  console.warn("[CacheManager] Direct Global Purge skipped:", e);
@@ -23661,38 +23673,50 @@ mx.get("/", async (e) => {
23661
23673
  let x = `
23662
23674
  WITH filtered_nodes AS (
23663
23675
  SELECT cn.* FROM content_nodes cn ${g} ORDER BY ${y} ${l} LIMIT ? OFFSET ?
23676
+ ),
23677
+ node_asset_counts AS (
23678
+ SELECT
23679
+ na.nodeId,
23680
+ COUNT(DISTINCT CASE WHEN a.mimeType LIKE 'image/%' THEN COALESCE(a.parentAssetId, a.id) END) as imageCount,
23681
+ COUNT(DISTINCT CASE WHEN a.mimeType LIKE 'video/%' OR a.mimeType LIKE 'audio/%' THEN COALESCE(a.parentAssetId, a.id) END) as videoCount,
23682
+ COUNT(DISTINCT CASE WHEN a.mimeType LIKE 'application/pdf%' OR a.mimeType LIKE 'application/msword%' OR a.mimeType LIKE 'application/vnd%' OR a.mimeType LIKE 'text/%' THEN COALESCE(a.parentAssetId, a.id) END) as documentCount,
23683
+ COUNT(DISTINCT CASE WHEN a.mimeType NOT LIKE 'image/%' AND a.mimeType NOT LIKE 'video/%' AND a.mimeType NOT LIKE 'audio/%' AND a.mimeType NOT LIKE 'application/pdf%' AND a.mimeType NOT LIKE 'application/msword%' AND a.mimeType NOT LIKE 'application/vnd%' AND a.mimeType NOT LIKE 'text/%' THEN COALESCE(a.parentAssetId, a.id) END) as otherCount,
23684
+ COUNT(DISTINCT COALESCE(a.parentAssetId, a.id)) as assetCount
23685
+ FROM node_assets na
23686
+ JOIN assets a ON na.assetId = a.id
23687
+ GROUP BY na.nodeId
23664
23688
  )
23665
- SELECT fn.*,
23666
- COUNT(DISTINCT CASE WHEN a.mimeType LIKE 'image/%' THEN COALESCE(a.parentAssetId, a.id) END) as imageCount,
23667
- COUNT(DISTINCT CASE WHEN a.mimeType LIKE 'video/%' OR a.mimeType LIKE 'audio/%' THEN COALESCE(a.parentAssetId, a.id) END) as videoCount,
23668
- COUNT(DISTINCT CASE WHEN a.mimeType LIKE 'application/pdf%' OR a.mimeType LIKE 'application/msword%' OR a.mimeType LIKE 'application/vnd%' OR a.mimeType LIKE 'text/%' THEN COALESCE(a.parentAssetId, a.id) END) as documentCount,
23669
- COUNT(DISTINCT CASE WHEN a.id IS NOT NULL AND a.mimeType NOT LIKE 'image/%' AND a.mimeType NOT LIKE 'video/%' AND a.mimeType NOT LIKE 'audio/%' AND a.mimeType NOT LIKE 'application/pdf%' AND a.mimeType NOT LIKE 'application/msword%' AND a.mimeType NOT LIKE 'application/vnd%' AND a.mimeType NOT LIKE 'text/%' THEN COALESCE(a.parentAssetId, a.id) END) as otherCount,
23670
- COUNT(DISTINCT COALESCE(a.parentAssetId, a.id)) as assetCount,
23671
- (SELECT path FROM node_routes nr WHERE nr.nodeId = fn.id AND isCanonical = 1 LIMIT 1) as routePath
23689
+ SELECT
23690
+ fn.*,
23691
+ COALESCE(nac.imageCount, 0) as imageCount,
23692
+ COALESCE(nac.videoCount, 0) as videoCount,
23693
+ COALESCE(nac.documentCount, 0) as documentCount,
23694
+ COALESCE(nac.otherCount, 0) as otherCount,
23695
+ COALESCE(nac.assetCount, 0) as assetCount,
23696
+ (SELECT path FROM node_routes nr WHERE nr.nodeId = fn.id AND isCanonical = 1 LIMIT 1) as routePath
23672
23697
  FROM filtered_nodes fn
23673
- LEFT JOIN node_assets na ON fn.id = na.nodeId
23674
- LEFT JOIN assets a ON na.assetId = a.id
23675
- GROUP BY fn.id ORDER BY ${y.replace("cn.", "fn.")} ${l}
23698
+ LEFT JOIN node_asset_counts nac ON fn.id = nac.nodeId
23699
+ ORDER BY ${y.replace("cn.", "fn.")} ${l}
23676
23700
  `, S = [
23677
23701
  ...m,
23678
23702
  f,
23679
23703
  p
23680
- ], C = await t.prepare(x).all(...S), ee = Array.isArray(C) ? C : C?.results || [], w = ee.map((e) => e.id), T = {}, E = {};
23681
- if (w.length > 0) {
23682
- let e = w.map(() => "?").join(","), n = await t.prepare(`
23704
+ ], C = await t.prepare(x).all(...S), w = Array.isArray(C) ? C : C?.results || [], T = w.map((e) => e.id), ee = {}, E = {};
23705
+ if (T.length > 0) {
23706
+ let e = T.map(() => "?").join(","), n = await t.prepare(`
23683
23707
  SELECT nc.nodeId, c.label FROM node_channels nc JOIN channels c ON nc.channelId = c.id WHERE nc.nodeId IN (${e})
23684
- `).all(...w);
23708
+ `).all(...T);
23685
23709
  (Array.isArray(n) ? n : n?.results || []).forEach((e) => {
23686
- T[e.nodeId] || (T[e.nodeId] = []), T[e.nodeId].push(e.label);
23710
+ ee[e.nodeId] || (ee[e.nodeId] = []), ee[e.nodeId].push(e.label);
23687
23711
  });
23688
23712
  let r = await t.prepare(`
23689
23713
  SELECT tn.contentId as nodeId, t.label FROM tree_nodes tn JOIN trees t ON tn.treeId = t.id WHERE tn.contentId IN (${e})
23690
- `).all(...w);
23714
+ `).all(...T);
23691
23715
  (Array.isArray(r) ? r : r?.results || []).forEach((e) => {
23692
23716
  E[e.nodeId] || (E[e.nodeId] = []), E[e.nodeId].includes(e.label) || E[e.nodeId].push(e.label);
23693
23717
  });
23694
23718
  }
23695
- let D = await Promise.all(ee.map(async (e) => {
23719
+ let D = await Promise.all(w.map(async (e) => {
23696
23720
  let n = e.status === "draft" || !!e.hasUnpublishedChanges, r = {
23697
23721
  id: e.id,
23698
23722
  title: e.title,
@@ -23710,7 +23734,7 @@ mx.get("/", async (e) => {
23710
23734
  updatedById: e.updatedById || null,
23711
23735
  createdAt: e.createdAt,
23712
23736
  updatedAt: e.updatedAt,
23713
- channelNames: T[e.id] || [],
23737
+ channelNames: ee[e.id] || [],
23714
23738
  treeNames: E[e.id] || [],
23715
23739
  assetCount: e.assetCount || 0,
23716
23740
  imageCount: e.imageCount || 0,
@@ -23732,9 +23756,9 @@ mx.get("/", async (e) => {
23732
23756
  limit: f
23733
23757
  });
23734
23758
  }), mx.post("/", async (e) => {
23735
- 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 } = ax(bx(_)), x = vx(d === void 0 ? f === void 0 ? p : f : d), S = l || u || "page", C = e.get("user")?.id || null, ee = typeof c == "string" && c.trim() !== "" ? c.trim() : null, w = g && Array.isArray(g) && g.length > 0 ? g[0] : null, T = w ? w.treeId || w.id : null, E = null;
23736
- if (T) {
23737
- let e = await t.prepare("SELECT dataJson FROM trees WHERE id = ? OR key = ? LIMIT 1").get(Number(T) || -1, String(T));
23759
+ 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 } = ax(bx(_)), x = vx(d === void 0 ? f === void 0 ? p : f : d), S = l || u || "page", C = e.get("user")?.id || null, w = typeof c == "string" && c.trim() !== "" ? c.trim() : null, T = g && Array.isArray(g) && g.length > 0 ? g[0] : null, ee = T ? T.treeId || T.id : null, E = null;
23760
+ if (ee) {
23761
+ let e = await t.prepare("SELECT dataJson FROM trees WHERE id = ? OR key = ? LIMIT 1").get(Number(ee) || -1, String(ee));
23738
23762
  if (e?.dataJson) try {
23739
23763
  let t = typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson;
23740
23764
  E = t.defaultLanguage?.trim() || t.language?.trim() || null;
@@ -23753,7 +23777,7 @@ mx.get("/", async (e) => {
23753
23777
  }
23754
23778
  }
23755
23779
  }
23756
- ee && E && ee === E && (ee = null);
23780
+ w && E && w === E && (w = null);
23757
23781
  let D = a, te = /* @__PURE__ */ new Set(), ne = !1, O = "draft", k = 0, A = s === void 0 ? null : _x(s);
23758
23782
  if (A) {
23759
23783
  let n = [];
@@ -23804,7 +23828,7 @@ mx.get("/", async (e) => {
23804
23828
  ...r,
23805
23829
  ...v
23806
23830
  }), l = !1;
23807
- if (o !== void 0 && o.trim() !== (e?.title || "Untitled") && (l = !0), s !== void 0 && A !== e?.slug && (l = !0), c !== void 0 && ee !== e?.language && (l = !0), !l && Object.keys(v).length > 0) {
23831
+ if (o !== void 0 && o.trim() !== (e?.title || "Untitled") && (l = !0), s !== void 0 && A !== e?.slug && (l = !0), c !== void 0 && w !== e?.language && (l = !0), !l && Object.keys(v).length > 0) {
23808
23832
  for (let e of Object.keys(v)) if (JSON.stringify(v[e]) !== JSON.stringify(r[e])) {
23809
23833
  l = !0;
23810
23834
  break;
@@ -23826,13 +23850,13 @@ mx.get("/", async (e) => {
23826
23850
  }
23827
23851
  }
23828
23852
  }
23829
- let u = o === void 0 ? e?.title || "Untitled" : o, d = A ?? e?.slug ?? null, f = S || e?.contentType || "page", p = c === void 0 ? e?.language : ee;
23853
+ let u = o === void 0 ? e?.title || "Untitled" : o, d = A ?? e?.slug ?? null, f = S || e?.contentType || "page", p = c === void 0 ? e?.language : w;
23830
23854
  O = e?.status === "published" || e?.publishedAt ? "published" : "draft";
23831
23855
  let h = e?.hasUnpublishedChanges === 1 || e?.hasUnpublishedChanges === !0;
23832
23856
  k = l ? 1 : +!!h, 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(u, d, p, f, x, O, i, k, C, a);
23833
23857
  } else {
23834
23858
  ne = !0;
23835
- let e = 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(S, o || "Untitled", A, ee, x, JSON.stringify(v), C, C);
23859
+ let e = 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(S, o || "Untitled", A, w, x, JSON.stringify(v), C, C);
23836
23860
  D = Number(e.lastInsertRowid);
23837
23861
  }
23838
23862
  if (h !== void 0 && Array.isArray(h) && D) {
@@ -24370,18 +24394,19 @@ kx.get("/", async (e) => {
24370
24394
  }
24371
24395
  }), kx.post("/", async (e) => {
24372
24396
  try {
24373
- 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", ee = s?.trim() || "Untitled Channel", w = d || f || p || "";
24374
- typeof w == "object" && w && (w = w.value || w.id || ""), w = String(w).trim();
24375
- let T = 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;
24397
+ 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 || "";
24398
+ typeof T == "object" && T && (T = T.value || T.id || ""), T = String(T).trim();
24399
+ 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;
24376
24400
  if (await t.prepare("SELECT id FROM channels WHERE key = ? AND id != ? LIMIT 1").get(C, a ?? -1)) return e.json({
24377
24401
  error: `Channel API key "${C}" is already in use.`,
24378
24402
  field: "key"
24379
24403
  }, 409);
24380
24404
  let ne = a;
24381
- 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, ee, c, l, u, w, +!!T, D, te, a);
24405
+ 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);
24382
24406
  else {
24383
- let e = await t.prepare("\n INSERT INTO channels (key, label, channelType, domain, baseUrl, defaultLanguage, isHidden, dataJson, createdById, updatedById)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ").run(C, ee, c, l, u, w, +!!T, D, te, te);
24384
- ne = Number(e.lastInsertRowid);
24407
+ 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;
24408
+ if (!n || !n.id) throw Error("Failed to retrieve newly created Channel ID from Cloudflare D1.");
24409
+ ne = Number(n.id);
24385
24410
  }
24386
24411
  await t.prepare("DELETE FROM channel_trees WHERE channelId = ?").run(ne);
24387
24412
  let O = E.filter((e) => e && e.treeId && e.key);
@@ -24734,7 +24759,7 @@ function Yx(e) {
24734
24759
  channelTemplate: null,
24735
24760
  userTemplate: null
24736
24761
  };
24737
- 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, ee = Object.keys(n).length > 0 ? n : y, w = Object.keys(r).length > 0 ? r : i, T = 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, ne = m?.fields || {}, O = {
24762
+ 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, ne = m?.fields || {}, O = {
24738
24763
  ...p,
24739
24764
  ...f
24740
24765
  }, k = (e, t = "settings", n, r) => {
@@ -24862,7 +24887,7 @@ function Yx(e) {
24862
24887
  };
24863
24888
  });
24864
24889
  let ie = {};
24865
- Object.entries(ee).forEach(([e, t]) => {
24890
+ Object.entries(w).forEach(([e, t]) => {
24866
24891
  let n = A(t.tabs), r = k(t.fields || [], "settings", n);
24867
24892
  Array.isArray(t.fieldSets) && t.fieldSets.forEach((e) => {
24868
24893
  let t = O[e] || {}, i = t.fields || t, a = k(i, "settings", n);
@@ -24882,7 +24907,7 @@ function Yx(e) {
24882
24907
  };
24883
24908
  });
24884
24909
  let ae = {};
24885
- Object.entries(w).forEach(([e, t]) => {
24910
+ Object.entries(T).forEach(([e, t]) => {
24886
24911
  let n = A(t.tabs), r = k(t.fields || [], "settings", n);
24887
24912
  Array.isArray(t.fieldSets) && t.fieldSets.forEach((e) => {
24888
24913
  let t = O[e] || {}, n = t.fields || t, i = k(n);
@@ -24903,7 +24928,7 @@ function Yx(e) {
24903
24928
  };
24904
24929
  });
24905
24930
  let oe = {};
24906
- Object.entries(T).forEach(([e, t]) => {
24931
+ Object.entries(ee).forEach(([e, t]) => {
24907
24932
  let n = A(t.tabs), r = k(t.fields || [], "settings", n);
24908
24933
  Array.isArray(t.fieldSets) && t.fieldSets.forEach((e) => {
24909
24934
  let t = O[e] || {}, i = t.fields || t, a = k(i, "settings", n);
@@ -24985,26 +25010,26 @@ function Yx(e) {
24985
25010
  tabs: n
24986
25011
  };
24987
25012
  });
24988
- let j = g?.fields || {};
25013
+ let ue = g?.fields || {};
24989
25014
  Array.isArray(g?.fieldSets) && g?.fieldSets.forEach((e) => {
24990
25015
  let t = O[e] || {}, n = t.fields || t, r = k(n);
24991
25016
  Object.entries(r).forEach(([e, t]) => {
24992
- j[e] = Bx(j[e] || {}, t);
25017
+ ue[e] = Bx(ue[e] || {}, t);
24993
25018
  });
24994
25019
  });
24995
- let ue = g ? {
25020
+ let de = g ? {
24996
25021
  ...g,
24997
- fields: j
24998
- } : null, de = _?.fields || {};
25022
+ fields: ue
25023
+ } : null, j = _?.fields || {};
24999
25024
  Array.isArray(_?.fieldSets) && _?.fieldSets.forEach((e) => {
25000
25025
  let t = O[e] || {}, n = t.fields || t, r = k(n);
25001
25026
  Object.entries(r).forEach(([e, t]) => {
25002
- de[e] = Bx(de[e] || {}, t);
25027
+ j[e] = Bx(j[e] || {}, t);
25003
25028
  });
25004
25029
  });
25005
25030
  let fe = _ ? {
25006
25031
  ..._,
25007
- fields: de
25032
+ fields: j
25008
25033
  } : null;
25009
25034
  return {
25010
25035
  nodes: re,
@@ -25017,7 +25042,7 @@ function Yx(e) {
25017
25042
  fieldSets: O,
25018
25043
  nodeTemplate: m || null,
25019
25044
  treeTemplate: h || null,
25020
- channelTemplate: ue,
25045
+ channelTemplate: de,
25021
25046
  userTemplate: fe
25022
25047
  };
25023
25048
  }
@@ -25288,9 +25313,9 @@ nS.get("/", async (e) => {
25288
25313
  }
25289
25314
  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}`;
25290
25315
  if (!v) throw Error("Storage provider failed to return a valid storage key");
25291
- 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, ee = e.get("userId"), w = typeof ee == "string" && ee.trim().length > 0 ? ee : null;
25292
- w && (await rS(t, "SELECT id FROM users WHERE id = ?", [w])).length === 0 && (w = null);
25293
- let T = new fx(e.env);
25316
+ 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;
25317
+ T && (await rS(t, "SELECT id FROM users WHERE id = ?", [T])).length === 0 && (T = null);
25318
+ let ee = new fx(e.env);
25294
25319
  if (s) {
25295
25320
  let r = await rS(t, "SELECT storageKeyPrivate, isSystemVariant, parentAssetId FROM assets WHERE id = ?", [s]);
25296
25321
  if (r.length > 0) {
@@ -25307,7 +25332,7 @@ nS.get("/", async (e) => {
25307
25332
  } catch (e) {
25308
25333
  console.warn("Failed to cleanup old asset", e);
25309
25334
  }
25310
- T.purgeAsset(e, t, s);
25335
+ ee.purgeAsset(e, t, s);
25311
25336
  let o = `${x}?v=${Date.now()}`;
25312
25337
  return e.json({
25313
25338
  id: s,
@@ -25331,7 +25356,7 @@ nS.get("/", async (e) => {
25331
25356
  C,
25332
25357
  v,
25333
25358
  x,
25334
- w,
25359
+ T,
25335
25360
  D,
25336
25361
  l,
25337
25362
  d
@@ -25339,7 +25364,7 @@ nS.get("/", async (e) => {
25339
25364
  let te = x;
25340
25365
  if (l) {
25341
25366
  let n = await rS(t, "SELECT cdnUrl, storageKeyPrivate FROM assets WHERE id = ?", [l]);
25342
- n.length > 0 && (te = aS(n[0].cdnUrl, n[0].storageKeyPrivate, y)), T.purgeAsset(e, t, l);
25367
+ n.length > 0 && (te = aS(n[0].cdnUrl, n[0].storageKeyPrivate, y)), ee.purgeAsset(e, t, l);
25343
25368
  }
25344
25369
  return e.json({
25345
25370
  id: E,
@@ -25494,7 +25519,18 @@ function sS() {
25494
25519
  assetUrls: /* @__PURE__ */ new Map()
25495
25520
  };
25496
25521
  }
25497
- function cS(e, t) {
25522
+ function cS(e, t, n = []) {
25523
+ let r = Date.now();
25524
+ if (e && String(e).trim() !== "") {
25525
+ let t = Date.parse(e);
25526
+ !isNaN(t) && t > r && n.push(t);
25527
+ }
25528
+ if (t && String(t).trim() !== "") {
25529
+ let e = Date.parse(t);
25530
+ !isNaN(e) && e > r && n.push(e);
25531
+ }
25532
+ }
25533
+ function lS(e, t) {
25498
25534
  let n = Date.now();
25499
25535
  if (e && String(e).trim() !== "") {
25500
25536
  let t = Date.parse(e);
@@ -25506,37 +25542,37 @@ function cS(e, t) {
25506
25542
  }
25507
25543
  return !0;
25508
25544
  }
25509
- async function lS(e, t, n, r) {
25510
- let i = t.filter((e) => e.componentId === "content-feed" || e.componentId === "article-list");
25511
- await Promise.all(i.map(async (t) => {
25512
- let i = t.data || {}, a = i.nodeType || "article", o = Number(i.limit) || 12, s = i.sortBy || "updatedAt", c = "FROM content_nodes WHERE contentType = ? AND isHidden = 0 AND (status = 'published' OR status IS NULL)", l = [a];
25513
- n && n !== "all" && (c += " AND id IN (SELECT nodeId FROM node_channels WHERE channelId = ?)", l.push(Number(n) || n));
25514
- let u = i.taxonomies || i.taxonomyFilters || {}, d = Object.keys(u);
25515
- if (d.length > 0) for (let e of d) {
25516
- let t = Array.isArray(u[e]) ? u[e] : [u[e]];
25545
+ async function uS(e, t, n, r, i) {
25546
+ let a = t.filter((e) => e.componentId === "content-feed" || e.componentId === "article-list");
25547
+ await Promise.all(a.map(async (t) => {
25548
+ let a = t.data || {}, o = a.nodeType || "article", s = Number(a.limit) || 12, c = a.sortBy || "updatedAt", l = "FROM content_nodes WHERE contentType = ? AND isHidden = 0 AND (status = 'published' OR status IS NULL)", u = [o];
25549
+ n && n !== "all" && (l += " AND id IN (SELECT nodeId FROM node_channels WHERE channelId = ?)", u.push(Number(n) || n));
25550
+ let d = a.taxonomies || a.taxonomyFilters || {}, f = Object.keys(d);
25551
+ if (f.length > 0) for (let e of f) {
25552
+ let t = Array.isArray(d[e]) ? d[e] : [d[e]];
25517
25553
  if (t.length > 0) {
25518
25554
  let n = t.map(() => "?").join(",");
25519
- c += ` AND EXISTS (
25555
+ l += ` AND EXISTS (
25520
25556
  SELECT 1 FROM node_terms nt
25521
25557
  INNER JOIN taxonomy_terms tt ON nt.termId = tt.id
25522
25558
  WHERE nt.nodeId = content_nodes.id
25523
25559
  AND tt.taxonomy = ?
25524
25560
  AND tt.key IN (${n})
25525
- )`, l.push(e, ...t);
25561
+ )`, u.push(e, ...t);
25526
25562
  }
25527
25563
  }
25528
- let f = "ORDER BY updatedAt DESC";
25529
- s === "published_desc" || s === "createdAt" ? f = "ORDER BY createdAt DESC" : s === "title_asc" && (f = "ORDER BY LOWER(title) ASC");
25530
- let p = `SELECT id, title, slug, language, dataJson, createdAt, updatedAt ${c} ${f} LIMIT ?`;
25531
- l.push(o);
25564
+ let p = "ORDER BY updatedAt DESC";
25565
+ c === "published_desc" || c === "createdAt" ? p = "ORDER BY createdAt DESC" : c === "title_asc" && (p = "ORDER BY LOWER(title) ASC");
25566
+ let m = `SELECT id, title, slug, language, dataJson, createdAt, updatedAt ${l} ${p} LIMIT ?`;
25567
+ u.push(s);
25532
25568
  try {
25533
- let n = await e.prepare(p).all(...l), i = Array.isArray(n) ? n : n?.results || [];
25534
- t.data.initialItems = i.map((e) => {
25569
+ let n = await e.prepare(m).all(...u), a = Array.isArray(n) ? n : n?.results || [];
25570
+ t.data.initialItems = a.map((e) => {
25535
25571
  let t = {};
25536
25572
  if (e.dataJson) try {
25537
25573
  t = typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson;
25538
25574
  } catch {}
25539
- return cS(t.startShowingAt, t.stopShowingAt) ? {
25575
+ return i && cS(t.startShowingAt, t.stopShowingAt, i), lS(t.startShowingAt, t.stopShowingAt) ? {
25540
25576
  id: e.id,
25541
25577
  title: e.title,
25542
25578
  slug: e.slug,
@@ -25553,23 +25589,23 @@ async function lS(e, t, n, r) {
25553
25589
  }
25554
25590
  }));
25555
25591
  }
25556
- async function uS(e, t, n, r, i, a = !1, o) {
25592
+ async function dS(e, t, n, r, i, a = !1, o, s) {
25557
25593
  if (!t) return { blocks: [] };
25558
- let s = 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), c = Array.isArray(s) ? s : s?.results || [];
25559
- if (!c || c.length === 0) return { blocks: [] };
25560
- let l = c.map((e) => e.contentId).filter((e) => e != null);
25561
- if (l.length === 0) return { blocks: [] };
25562
- let u = l.map(() => "?").join(","), d = +!!a, f = await e.prepare(`SELECT * FROM content_blocks WHERE contentId IN (${u}) AND isDraft = ? ORDER BY contentId ASC, sortOrder ASC`).all(...l, d), p = Array.isArray(f) ? f : f?.results || [], m = /* @__PURE__ */ new Map();
25563
- p.forEach((e) => {
25594
+ 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 || [];
25595
+ if (!l || l.length === 0) return { blocks: [] };
25596
+ let u = l.map((e) => e.contentId).filter((e) => e != null);
25597
+ if (u.length === 0) return { blocks: [] };
25598
+ let d = u.map(() => "?").join(","), f = +!!a, p = await e.prepare(`SELECT * FROM content_blocks WHERE contentId IN (${d}) AND isDraft = ? ORDER BY contentId ASC, sortOrder ASC`).all(...u, f), m = Array.isArray(p) ? p : p?.results || [], h = /* @__PURE__ */ new Map();
25599
+ m.forEach((e) => {
25564
25600
  let t = String(e.contentId);
25565
- m.has(t) || m.set(t, []), m.get(t).push(e);
25601
+ h.has(t) || h.set(t, []), h.get(t).push(e);
25566
25602
  });
25567
- for (let t of c) {
25568
- let n = m.get(String(t.contentId)) || [];
25603
+ for (let t of l) {
25604
+ let n = h.get(String(t.contentId)) || [];
25569
25605
  if (n.filter((e) => e.region === r).length === 0) continue;
25570
- let o = /* @__PURE__ */ new Set([r]), s = !0;
25571
- for (; s;) {
25572
- s = !1;
25606
+ let o = /* @__PURE__ */ new Set([r]), c = !0;
25607
+ for (; c;) {
25608
+ c = !1;
25573
25609
  for (let e of n) {
25574
25610
  if (!o.has(e.region)) continue;
25575
25611
  let t = {};
@@ -25580,39 +25616,40 @@ async function uS(e, t, n, r, i, a = !1, o) {
25580
25616
  for (let e of n) {
25581
25617
  if (!e.region || o.has(e.region)) continue;
25582
25618
  let t = e.region;
25583
- (t.startsWith(`${r}-`) || t.startsWith(`${r}_`) || i && i !== "undefined" && i !== "null" && (t.startsWith(`${i}-`) || t.startsWith(`${i}_`) || t.startsWith(i))) && (o.add(t), s = !0);
25619
+ (t.startsWith(`${r}-`) || t.startsWith(`${r}_`) || i && i !== "undefined" && i !== "null" && (t.startsWith(`${i}-`) || t.startsWith(`${i}_`) || t.startsWith(i))) && (o.add(t), c = !0);
25584
25620
  }
25585
25621
  }
25586
25622
  }
25587
- let c = await Promise.all(n.filter((e) => o.has(e.region)).map(async (t) => {
25623
+ let l = await Promise.all(n.filter((e) => o.has(e.region)).map(async (t) => {
25588
25624
  let n = {};
25589
25625
  try {
25590
25626
  n = (typeof t.dataJson == "string" ? JSON.parse(t.dataJson) : t.dataJson) || {};
25591
25627
  } catch {}
25592
- let o = n.hidden === !0 || n.hidden === 1 || n.hidden === "1" || n.hidden === "true", s = cS(n.startShowingAt, n.stopShowingAt);
25593
- if (!a && (o || !s)) return null;
25594
- let c = t.elementType || t.componentId || "text-block", l = i.blocks?.[c]?.fields || i.elements?.[c]?.fields || i.components?.[c]?.fields || {}, u = String(n.blockId || n._instanceId || n.id || t.blockId || t.id), d = dS(n, l);
25595
- return d = await ux(e, d), d = fS(d), d.blockId = u, {
25628
+ s && cS(n.startShowingAt, n.stopShowingAt, s);
25629
+ let o = n.hidden === !0 || n.hidden === 1 || n.hidden === "1" || n.hidden === "true", c = lS(n.startShowingAt, n.stopShowingAt);
25630
+ if (!a && (o || !c)) return null;
25631
+ 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 = fS(n, u);
25632
+ return f = await ux(e, f), f = pS(f), f.blockId = d, {
25596
25633
  region: t.region || r,
25597
25634
  block: {
25598
25635
  instanceId: t.id,
25599
- blockId: u,
25600
- componentId: c,
25601
- data: d
25636
+ blockId: d,
25637
+ componentId: l,
25638
+ data: f
25602
25639
  }
25603
25640
  };
25604
- })), l = {};
25605
- for (let e of c) e && (l[e.region] || (l[e.region] = []), l[e.region].push(e.block));
25606
- if (l[r] && l[r].length > 0) return {
25607
- blocks: l[r],
25608
- subRegions: l,
25641
+ })), u = {};
25642
+ for (let e of l) e && (u[e.region] || (u[e.region] = []), u[e.region].push(e.block));
25643
+ if (u[r] && u[r].length > 0) return {
25644
+ blocks: u[r],
25645
+ subRegions: u,
25609
25646
  inheritedFromId: String(t.contentId),
25610
25647
  inheritedFromTitle: t.title || t.slug
25611
25648
  };
25612
25649
  }
25613
25650
  return { blocks: [] };
25614
25651
  }
25615
- function dS(e, t = {}) {
25652
+ function fS(e, t = {}) {
25616
25653
  let n = {};
25617
25654
  for (let [r, i] of Object.entries(e)) r.endsWith("_meta") || [
25618
25655
  "disabledRegions",
@@ -25628,14 +25665,14 @@ function dS(e, t = {}) {
25628
25665
  ].includes(r) || r.startsWith("_") || (!t[r] || t[r].public !== !1) && (n[r] = i);
25629
25666
  return n;
25630
25667
  }
25631
- function fS(e) {
25632
- if (Array.isArray(e)) return e.map(fS);
25668
+ function pS(e) {
25669
+ if (Array.isArray(e)) return e.map(pS);
25633
25670
  if (!e || typeof e != "object") return e;
25634
25671
  if (typeof e.id == "string" && e.id.startsWith("ast_") && typeof e.url == "string") {
25635
25672
  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 ? {
25636
25673
  ...t,
25637
25674
  ...t.crops?.[r] || {}
25638
- } : t, a = Object.fromEntries(Object.entries(n).filter(([, t]) => t?.id !== e.id).map(([t, n]) => [t, fS({
25675
+ } : t, a = Object.fromEntries(Object.entries(n).filter(([, t]) => t?.id !== e.id).map(([t, n]) => [t, pS({
25639
25676
  ...n,
25640
25677
  title: n?.title ?? e.title ?? "",
25641
25678
  alt: n?.alt ?? e.alt ?? "",
@@ -25649,9 +25686,9 @@ function fS(e) {
25649
25686
  ...Object.keys(a).length > 0 ? { variants: a } : {}
25650
25687
  };
25651
25688
  }
25652
- return Object.fromEntries(Object.entries(e).map(([e, t]) => [e, fS(t)]));
25689
+ return Object.fromEntries(Object.entries(e).map(([e, t]) => [e, pS(t)]));
25653
25690
  }
25654
- async function pS(e, t, n, r) {
25691
+ async function mS(e, t, n, r) {
25655
25692
  if (typeof t == "string") {
25656
25693
  if (!t.includes("#node:") && !t.includes("data-node-id") && !t.includes("#asset:") && !t.includes("data-asset-id")) return t;
25657
25694
  let r = (e, t) => {
@@ -25684,25 +25721,25 @@ async function pS(e, t, n, r) {
25684
25721
  return /href\s*=\s*["'][^"']*["']/i.test(d) ? d = d.replace(/href\s*=\s*["'][^"']*["']/i, `href="${u}"`) : d += ` href="${u}"`, `<a ${d}>`;
25685
25722
  });
25686
25723
  }
25687
- if (Array.isArray(t)) return Promise.all(t.map((t) => pS(e, t, n, r)));
25724
+ if (Array.isArray(t)) return Promise.all(t.map((t) => mS(e, t, n, r)));
25688
25725
  if (t && typeof t == "object") {
25689
25726
  if (typeof t.href == "string" && (t.href.startsWith("#node:") || t.href.startsWith("#asset:"))) return {
25690
25727
  ...t,
25691
- href: await mS(e, t, n, r)
25728
+ href: await hS(e, t, n, r)
25692
25729
  };
25693
- let i = await Promise.all(Object.entries(t).map(async ([t, i]) => [t, await pS(e, i, n, r)]));
25730
+ let i = await Promise.all(Object.entries(t).map(async ([t, i]) => [t, await mS(e, i, n, r)]));
25694
25731
  return Object.fromEntries(i);
25695
25732
  }
25696
25733
  return t;
25697
25734
  }
25698
- async function mS(e, t, n, r) {
25735
+ async function hS(e, t, n, r) {
25699
25736
  let i = t.href.match(/^#node:(.+)$/), a = t.href.match(/^#asset:(.+)$/);
25700
- if (a) return hS(e, a[1], r);
25737
+ if (a) return gS(e, a[1], r);
25701
25738
  if (!i) return t.href;
25702
25739
  let o = i[1];
25703
25740
  return (await e.prepare("SELECT path FROM node_routes WHERE nodeId = ? AND channelId = ? AND isCanonical = 1 LIMIT 1").get(Number(o), n))?.path || "#";
25704
25741
  }
25705
- async function hS(e, t, n) {
25742
+ async function gS(e, t, n) {
25706
25743
  let r = String(t), i = n.assetUrls.get(r);
25707
25744
  if (i) return i;
25708
25745
  let a = (async () => {
@@ -25711,7 +25748,7 @@ async function hS(e, t, n) {
25711
25748
  })();
25712
25749
  return n.assetUrls.set(r, a), a;
25713
25750
  }
25714
- function gS(e) {
25751
+ function _S(e) {
25715
25752
  let t = e.socialImage;
25716
25753
  if (!t || typeof t != "object") return null;
25717
25754
  let n = (e, t) => {
@@ -25742,7 +25779,7 @@ function gS(e) {
25742
25779
  ])
25743
25780
  };
25744
25781
  }
25745
- async function _S(e, t, n, r, i) {
25782
+ async function vS(e, t, n, r, i) {
25746
25783
  let a = {}, o = null;
25747
25784
  if (t) {
25748
25785
  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([
@@ -25780,151 +25817,160 @@ async function _S(e, t, n, r, i) {
25780
25817
  inheritedFields: a
25781
25818
  };
25782
25819
  }
25783
- function vS(e) {
25820
+ function yS(e) {
25784
25821
  let t = Number(e?.env?.CMS_NODE_CACHE_TTL);
25785
25822
  return Number.isFinite(t) && t >= 60 ? Math.floor(t) : 300;
25786
25823
  }
25787
- async function yS(e, t, n, r) {
25824
+ async function bS(e, t, n, r) {
25788
25825
  try {
25789
25826
  await e.set(t, n, r);
25790
25827
  } catch (e) {
25791
25828
  console.warn("[CMS Cache] Failed to write node response to cache:", e);
25792
25829
  }
25793
25830
  }
25794
- async function bS(e) {
25831
+ async function xS(e) {
25795
25832
  try {
25796
- let t = e.get("db"), n = sS(), r = new URL(e.req.url), i = r.searchParams.get("channelId") || r.searchParams.get("channel"), a = r.searchParams.get("lang"), o = r.searchParams.get("preview") === "true", s = r.searchParams.get("revisionId"), c = r.searchParams.get("treeId"), l = r.pathname, u = "";
25797
- l.includes("/node/") ? u = l.substring(l.indexOf("/node/") + 6) : l.endsWith("/node") && (u = "");
25833
+ let t = e.get("db"), n = sS(), 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 = "";
25834
+ u.includes("/node/") ? d = u.substring(u.indexOf("/node/") + 6) : u.endsWith("/node") && (d = "");
25798
25835
  try {
25799
- u = decodeURIComponent(u);
25836
+ d = decodeURIComponent(d);
25800
25837
  } catch {}
25801
- u = u.replace(/^\/+|\/+$/g, "");
25802
- let d = u === "" || u === "index" ? "/" : `/${u}`, f = i || "1", p = isNaN(Number(f)) ? await t.prepare("SELECT * FROM channels WHERE key = ?").get(f) : await t.prepare("SELECT * FROM channels WHERE id = ?").get(Number(f));
25803
- if (!p) return e.json({ error: `Channel '${f}' not found` }, 404);
25804
- let m = p.status === "disabled" || p.status === "inactive" || p.isEnabled === 0 || p.isEnabled === !1;
25805
- if (!o && m) return e.json({ error: `Channel '${p.key || f}' is currently inactive` }, 404);
25806
- let h = p.id, g = p.key || f, _ = await t.prepare("\n SELECT * FROM node_routes WHERE path = ? AND channelId = ? LIMIT 1\n ").get(d, h);
25807
- if (_?.redirectUrl) return e.json({
25808
- redirect: _.redirectUrl,
25838
+ d = d.replace(/^\/+|\/+$/g, "");
25839
+ let f = d === "" || d === "index" ? "/" : `/${d}`, p = a || "1", m = isNaN(Number(p)) ? await t.prepare("SELECT * FROM channels WHERE key = ?").get(p) : await t.prepare("SELECT * FROM channels WHERE id = ?").get(Number(p));
25840
+ if (!m) return e.json({ error: `Channel '${p}' not found` }, 404);
25841
+ let h = m.status === "disabled" || m.status === "inactive" || m.isEnabled === 0 || m.isEnabled === !1;
25842
+ if (!s && h) return e.json({ error: `Channel '${m.key || p}' is currently inactive` }, 404);
25843
+ let g = m.id, _ = m.key || p, v = await t.prepare("\n SELECT * FROM node_routes WHERE path = ? AND channelId = ? LIMIT 1\n ").get(f, g);
25844
+ if (v?.redirectUrl) return e.json({
25845
+ redirect: v.redirectUrl,
25809
25846
  isCanonical: !1
25810
25847
  });
25811
- let v = null, y = _?.treeId || c || null;
25812
- if (_?.nodeId) v = await t.prepare("SELECT * FROM content_nodes WHERE id = ?").get(_.nodeId);
25813
- else if (/^\d+$/.test(u)) v = await t.prepare("SELECT * FROM content_nodes WHERE id = ?").get(Number(u));
25848
+ let y = null, b = v?.treeId || l || null;
25849
+ if (v?.nodeId) y = await t.prepare("SELECT * FROM content_nodes WHERE id = ?").get(v.nodeId);
25850
+ else if (/^\d+$/.test(d)) y = await t.prepare("SELECT * FROM content_nodes WHERE id = ?").get(Number(d));
25814
25851
  else {
25815
- let e = u.split("/").pop() || u;
25816
- v = await t.prepare("SELECT * FROM content_nodes WHERE slug = ?").get(e);
25852
+ let e = d.split("/").pop() || d;
25853
+ y = await t.prepare("SELECT * FROM content_nodes WHERE slug = ?").get(e);
25817
25854
  }
25818
- if (!v) return e.json({ error: `Node '${u}' not found for Channel '${f}'` }, 404);
25819
- let b = null;
25820
- if (s) {
25821
- let e = await t.prepare("SELECT snapshotJson FROM node_revisions WHERE nodeId = ? AND version = ?").get(v.id, Number(s));
25855
+ if (!y) return e.json({ error: `Node '${d}' not found for Channel '${p}'` }, 404);
25856
+ let x = null;
25857
+ if (c) {
25858
+ let e = await t.prepare("SELECT snapshotJson FROM node_revisions WHERE nodeId = ? AND version = ?").get(y.id, Number(c));
25822
25859
  if (e && e.snapshotJson) try {
25823
- b = JSON.parse(e.snapshotJson), b.node && (b.node.title && (v.title = b.node.title), b.node.slug && (v.slug = b.node.slug));
25860
+ x = JSON.parse(e.snapshotJson), x.node && (x.node.title && (y.title = x.node.title), x.node.slug && (y.slug = x.node.slug));
25824
25861
  } catch (e) {
25825
25862
  console.error("[CMS] Failed to parse snapshotJson", e);
25826
25863
  }
25827
25864
  }
25828
- let x = await t.prepare(`SELECT contentId as treeNodeId, treeId, parentId FROM tree_nodes WHERE contentId = ? ${y ? "AND treeId = ?" : ""} LIMIT 1`).get(v.id, ...y ? [y] : []);
25829
- !y && x?.treeId && (y = x.treeId), y ||= "main-nav";
25830
- let S = null;
25831
- if (y) {
25832
- let e = await t.prepare("SELECT dataJson FROM trees WHERE id = ? OR key = ? LIMIT 1").get(Number(y) || -1, String(y));
25865
+ let S = await t.prepare(`SELECT contentId as treeNodeId, treeId, parentId FROM tree_nodes WHERE contentId = ? ${b ? "AND treeId = ?" : ""} LIMIT 1`).get(y.id, ...b ? [b] : []);
25866
+ !b && S?.treeId && (b = S.treeId), b ||= "main-nav";
25867
+ let C = null;
25868
+ if (b) {
25869
+ let e = await t.prepare("SELECT dataJson FROM trees WHERE id = ? OR key = ? LIMIT 1").get(Number(b) || -1, String(b));
25833
25870
  if (e?.dataJson) try {
25834
25871
  let t = typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson;
25835
- t.defaultLanguage ? S = String(t.defaultLanguage).trim() : t.language && (S = String(t.language).trim());
25872
+ t.defaultLanguage ? C = String(t.defaultLanguage).trim() : t.language && (C = String(t.language).trim());
25836
25873
  } catch {}
25837
25874
  }
25838
- let C = null;
25839
- if (p) {
25840
- if (p.defaultLanguage) C = String(p.defaultLanguage).trim();
25841
- else if (p.dataJson) try {
25842
- let e = typeof p.dataJson == "string" ? JSON.parse(p.dataJson) : p.dataJson;
25843
- e.defaultLanguage ? C = String(e.defaultLanguage).trim() : e.language && (C = String(e.language).trim());
25875
+ let w = null;
25876
+ if (m) {
25877
+ if (m.defaultLanguage) w = String(m.defaultLanguage).trim();
25878
+ else if (m.dataJson) try {
25879
+ let e = typeof m.dataJson == "string" ? JSON.parse(m.dataJson) : m.dataJson;
25880
+ e.defaultLanguage ? w = String(e.defaultLanguage).trim() : e.language && (w = String(e.language).trim());
25844
25881
  } catch {}
25845
25882
  }
25846
- let ee = v.language?.trim() || null, w = S || C || a?.trim() || null, T = ee || w || null, E = `node:${h || g}:${T || "default"}:${u}`, D = e.req.header("x-bypass-cache") === "true" || !!s, te = $b(e);
25847
- if (!o && !D) {
25848
- let t = await te.get(E);
25849
- if (t) return e.header("X-Cache", "HIT"), e.json(t);
25850
- }
25851
- let ne = x?.parentId || null, O = _?.path || (d === "" ? "/" : d), k = {
25852
- id: v.id,
25853
- title: v.title,
25854
- slug: v.slug,
25855
- language: T,
25856
- path: O,
25857
- nodeType: v.contentType,
25858
- createdAt: v.createdAt,
25859
- updatedAt: v.updatedAt
25860
- }, A = dx(e.env?.BUNDLED_DEFINITIONS), re = v.contentType || "node", ie = A.nodes?.[re] || Object.values(A.nodes || {})[0] || {}, ae = { ...ie.fields || {} };
25861
- ie.tabs && Object.values(ie.tabs).forEach((e) => {
25862
- Object.assign(ae, e.fields || {});
25883
+ 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, ne = $b(e), O = yS(e);
25884
+ if (!s && !te) {
25885
+ let t = await ne.get(D);
25886
+ if (t) {
25887
+ e.header("X-Cache", "HIT");
25888
+ let n = O;
25889
+ if (t.meta && t.meta.nextEventTimestamp) {
25890
+ let e = Math.floor((t.meta.nextEventTimestamp - Date.now()) / 1e3);
25891
+ e > 0 && e < n ? n = e : e <= 0 && (n = 0);
25892
+ }
25893
+ return n > 0 ? e.header("Cache-Control", `public, max-age=${n}, s-maxage=${n}`) : e.header("Cache-Control", "no-cache, no-store, must-revalidate"), e.json(t);
25894
+ }
25895
+ }
25896
+ let k = S?.parentId || null, A = v?.path || (f === "" ? "/" : f), re = {
25897
+ id: y.id,
25898
+ title: y.title,
25899
+ slug: y.slug,
25900
+ language: E,
25901
+ path: A,
25902
+ nodeType: y.contentType,
25903
+ createdAt: y.createdAt,
25904
+ updatedAt: y.updatedAt
25905
+ }, ie = dx(e.env?.BUNDLED_DEFINITIONS), ae = y.contentType || "node", oe = ie.nodes?.[ae] || Object.values(ie.nodes || {})[0] || {}, se = { ...oe.fields || {} };
25906
+ oe.tabs && Object.values(oe.tabs).forEach((e) => {
25907
+ Object.assign(se, e.fields || {});
25863
25908
  });
25864
- let oe = {}, se = null, ce = null, le = !1, j = {}, ue = o && v.draftDataJson || v.dataJson;
25865
- if (b && b.node && b.node.dataJson && (ue = b.node.dataJson), ue) try {
25866
- j = typeof ue == "string" ? JSON.parse(ue) : ue;
25909
+ let ce = {}, le = null, ue = null, de = !1, j = {}, fe = s && y.draftDataJson || y.dataJson;
25910
+ if (x && x.node && x.node.dataJson && (fe = x.node.dataJson), fe) try {
25911
+ j = typeof fe == "string" ? JSON.parse(fe) : fe;
25867
25912
  } catch {}
25868
- j.disabledRegions && (oe = j.disabledRegions), le = j.hidden === !0 || j.hidden === 1 || j.hidden === "1" || j.hidden === "true", se = j.startShowingAt || null, ce = j.stopShowingAt || null;
25869
- let de = j.layoutId, fe = de && de !== "inherit", { resolvedLayoutId: pe, inheritedFields: me } = await _S(t, ne, y, o, ae), he = fe ? de : pe || ie.defaultLayout || null;
25870
- for (let [e, t] of Object.entries(me)) (j[e] === void 0 || j[e] === null || j[e] === "" || j[e] === "inherit") && t !== void 0 && (j[e] = t);
25871
- let ge = await ux(t, dS(j, ae));
25872
- ge = fS(ge), ge = await pS(t, ge, h, n), delete ge.language;
25873
- let _e = gS(ge);
25874
- delete ge.socialImage, delete ge.fbImage, delete ge.xImage, delete ge.whatsappImage, _e && (ge.socialImages = _e), Object.assign(k, ge), k.id = v.id, k.slug = v.slug, k.title = v.title, k.path = O, k.layoutId = he;
25875
- let ve = Number(v.isHidden) === 1 || le, ye = !cS(se, ce), be = v.status === "draft" || v.status === "new", xe = v.dataJson && v.dataJson !== "{}" && v.dataJson !== "null";
25876
- if (!o && (ve || ye || be && !xe)) return e.json({ error: "Node is hidden, offline, or has never been published." }, 404);
25877
- let Se = [];
25878
- if (x?.treeNodeId) {
25879
- let e = await t.prepare("\n SELECT t.contentId as treeNodeId, t.contentId as id, c.title, c.slug, c.language, c.contentType as nodeType, c.isHidden, c.dataJson, c.draftDataJson\n FROM tree_nodes t INNER JOIN content_nodes c ON t.contentId = c.id WHERE t.parentId = ? AND t.treeId = ? ORDER BY t.sortOrder ASC\n ").all(x.treeNodeId, y), n = Array.isArray(e) ? e : e?.results || [], r = k.path || "", i = r === "/" ? "" : r;
25880
- Se = n.map((e) => {
25881
- let t = {}, n = o && e.draftDataJson || e.dataJson;
25913
+ j.disabledRegions && (ce = j.disabledRegions), de = j.hidden === !0 || j.hidden === 1 || j.hidden === "1" || j.hidden === "true", le = j.startShowingAt || null, ue = j.stopShowingAt || null, cS(le, ue, r);
25914
+ let pe = j.layoutId, me = pe && pe !== "inherit", { resolvedLayoutId: he, inheritedFields: ge } = await vS(t, k, b, s, se), _e = me ? pe : he || oe.defaultLayout || null;
25915
+ for (let [e, t] of Object.entries(ge)) (j[e] === void 0 || j[e] === null || j[e] === "" || j[e] === "inherit") && t !== void 0 && (j[e] = t);
25916
+ let ve = await ux(t, fS(j, se));
25917
+ ve = pS(ve), ve = await mS(t, ve, g, n), delete ve.language;
25918
+ let ye = _S(ve);
25919
+ delete ve.socialImage, delete ve.fbImage, delete ve.xImage, delete ve.whatsappImage, ye && (ve.socialImages = ye), Object.assign(re, ve), re.id = y.id, re.slug = y.slug, re.title = y.title, re.path = A, re.layoutId = _e;
25920
+ let be = Number(y.isHidden) === 1 || de, xe = !lS(le, ue), Se = y.status === "draft" || y.status === "new", Ce = y.dataJson && y.dataJson !== "{}" && y.dataJson !== "null";
25921
+ if (!s && (be || xe || Se && !Ce)) return e.json({ error: "Node is hidden, offline, or has never been published." }, 404);
25922
+ let we = [];
25923
+ if (S?.treeNodeId) {
25924
+ let e = await t.prepare("\n SELECT t.contentId as treeNodeId, t.contentId as id, c.title, c.slug, c.language, c.contentType as nodeType, c.isHidden, c.dataJson, c.draftDataJson\n FROM tree_nodes t INNER JOIN content_nodes c ON t.contentId = c.id WHERE t.parentId = ? AND t.treeId = ? ORDER BY t.sortOrder ASC\n ").all(S.treeNodeId, b), n = Array.isArray(e) ? e : e?.results || [], i = re.path || "", a = i === "/" ? "" : i;
25925
+ we = n.map((e) => {
25926
+ let t = {}, n = s && e.draftDataJson || e.dataJson;
25882
25927
  if (!n) return null;
25883
25928
  try {
25884
25929
  t = (typeof n == "string" ? JSON.parse(n) : n) || {};
25885
25930
  } catch {}
25886
- let r = Number(e.isHidden) === 1 || t.hidden === !0 || t.hidden === 1 || t.hidden === "1", a = cS(t.startShowingAt, t.stopShowingAt), s = (e.slug || "").replace(/^\/+|\/+$/g, "");
25887
- return !o && (r || !a) ? null : {
25931
+ let i = Number(e.isHidden) === 1 || t.hidden === !0 || t.hidden === 1 || t.hidden === "1", o = lS(t.startShowingAt, t.stopShowingAt), c = (e.slug || "").replace(/^\/+|\/+$/g, "");
25932
+ return cS(t.startShowingAt, t.stopShowingAt, r), !s && (i || !o) ? null : {
25888
25933
  treeNodeId: e.treeNodeId,
25889
25934
  id: e.id,
25890
25935
  title: e.title,
25891
- slug: s,
25892
- language: e.language?.trim() || T || null,
25893
- path: `${i}/${s}`.replace(/\/+/g, "/"),
25936
+ slug: c,
25937
+ language: e.language?.trim() || E || null,
25938
+ path: `${a}/${c}`.replace(/\/+/g, "/"),
25894
25939
  nodeType: e.nodeType
25895
25940
  };
25896
25941
  }).filter(Boolean);
25897
25942
  }
25898
- k.children = Se;
25899
- let Ce = [];
25900
- if (b && b.blocks && Array.isArray(b.blocks)) Ce = b.blocks.map((e) => ({
25943
+ re.children = we;
25944
+ let Te = [];
25945
+ if (x && x.blocks && Array.isArray(x.blocks)) Te = x.blocks.map((e) => ({
25901
25946
  ...e,
25902
25947
  isDraft: 1
25903
25948
  }));
25904
25949
  else {
25905
- let e = +!!o, n = await t.prepare("SELECT * FROM content_blocks WHERE contentId = ? AND isDraft = ? ORDER BY sortOrder ASC").all(v.id, e);
25906
- Ce = Array.isArray(n) ? n : n?.results || [];
25950
+ let e = +!!s, n = await t.prepare("SELECT * FROM content_blocks WHERE contentId = ? AND isDraft = ? ORDER BY sortOrder ASC").all(y.id, e);
25951
+ Te = Array.isArray(n) ? n : n?.results || [];
25907
25952
  }
25908
- let we = {}, Te = {}, Ee = await Promise.all(Ce.map(async (e) => {
25909
- let r = e.region || "main", i = {};
25953
+ let Ee = {}, De = {}, Oe = await Promise.all(Te.map(async (e) => {
25954
+ let i = e.region || "main", a = {};
25910
25955
  try {
25911
- i = (typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson) || {};
25956
+ a = (typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson) || {};
25912
25957
  } catch {}
25913
- let a = i.hidden === !0 || i.hidden === 1 || i.hidden === "1" || i.hidden === "true", s = cS(i.startShowingAt, i.stopShowingAt);
25914
- if (!o && (a || !s)) return null;
25915
- let c = e.elementType || e.componentId || "text-block", l = A.blocks?.[c]?.fields || A.elements?.[c]?.fields || A.components?.[c]?.fields || {}, u = String(i.blockId || i._instanceId || i.id || e.blockId || e.id), d = dS(i, l);
25916
- return d = await ux(t, d), d = fS(d), d = await pS(t, d, h, n), d.blockId = u, {
25917
- region: r,
25958
+ cS(a.startShowingAt, a.stopShowingAt, r);
25959
+ let o = a.hidden === !0 || a.hidden === 1 || a.hidden === "1" || a.hidden === "true", c = lS(a.startShowingAt, a.stopShowingAt);
25960
+ if (!s && (o || !c)) return null;
25961
+ let l = e.elementType || e.componentId || "text-block", u = ie.blocks?.[l]?.fields || ie.elements?.[l]?.fields || ie.components?.[l]?.fields || {}, d = String(a.blockId || a._instanceId || a.id || e.blockId || e.id), f = fS(a, u);
25962
+ return f = await ux(t, f), f = pS(f), f = await mS(t, f, g, n), f.blockId = d, {
25963
+ region: i,
25918
25964
  block: {
25919
25965
  instanceId: e.id,
25920
- blockId: u,
25921
- componentId: c,
25922
- data: d
25966
+ blockId: d,
25967
+ componentId: l,
25968
+ data: f
25923
25969
  }
25924
25970
  };
25925
25971
  }));
25926
- for (let e of Ee) e && (we[e.region] || (we[e.region] = [], Te[e.region] = { isInherited: !1 }), we[e.region].push(e.block));
25927
- let De = {
25972
+ for (let e of Oe) e && (Ee[e.region] || (Ee[e.region] = [], De[e.region] = { isInherited: !1 }), Ee[e.region].push(e.block));
25973
+ let ke = {
25928
25974
  header: {
25929
25975
  label: "Header",
25930
25976
  inherit: "parent"
@@ -25933,33 +25979,43 @@ async function bS(e) {
25933
25979
  label: "Footer",
25934
25980
  inherit: "parent"
25935
25981
  },
25936
- ...(he ? A.nodeLayouts?.[he] || A.layouts?.[he] : null)?.regions || { main: { label: "Content" } }
25982
+ ...(_e ? ie.nodeLayouts?.[_e] || ie.layouts?.[_e] : null)?.regions || { main: { label: "Content" } }
25937
25983
  };
25938
- for (let [e, r] of Object.entries(De)) {
25939
- let i = we[e] && we[e].length > 0, a = !!oe[e];
25940
- if (we[e] || (we[e] = [], Te[e] = { isInherited: !1 }), (r?.inherit === "parent" || r?.inherit === !0 || r?.inherit === "true" || e === "header" || e === "footer") && !i && !a && ne) {
25941
- let r = await uS(t, ne, String(y), e, A, o, n);
25942
- if (r.blocks.length > 0 && (we[e] = r.blocks, Te[e] = {
25984
+ for (let [e, i] of Object.entries(ke)) {
25985
+ let a = Ee[e] && Ee[e].length > 0, o = !!ce[e];
25986
+ if (Ee[e] || (Ee[e] = [], De[e] = { isInherited: !1 }), (i?.inherit === "parent" || i?.inherit === !0 || i?.inherit === "true" || e === "header" || e === "footer") && !a && !o && k) {
25987
+ let i = await dS(t, k, String(b), e, ie, s, n, r);
25988
+ if (i.blocks.length > 0 && (Ee[e] = i.blocks, De[e] = {
25943
25989
  isInherited: !0,
25944
- inheritedFromId: r.inheritedFromId,
25945
- inheritedFromTitle: r.inheritedFromTitle
25946
- }, r.subRegions)) for (let [t, n] of Object.entries(r.subRegions)) t !== e && (we[t] = n, Te[t] = {
25990
+ inheritedFromId: i.inheritedFromId,
25991
+ inheritedFromTitle: i.inheritedFromTitle
25992
+ }, i.subRegions)) for (let [t, n] of Object.entries(i.subRegions)) t !== e && (Ee[t] = n, De[t] = {
25947
25993
  isInherited: !0,
25948
- inheritedFromId: r.inheritedFromId,
25949
- inheritedFromTitle: r.inheritedFromTitle
25994
+ inheritedFromId: i.inheritedFromId,
25995
+ inheritedFromTitle: i.inheritedFromTitle
25950
25996
  });
25951
25997
  }
25952
25998
  }
25953
- await Promise.all(Object.keys(we).map((e) => lS(t, we[e], h, T)));
25954
- let Oe = {
25955
- channelId: h || g,
25956
- treeId: y,
25957
- language: T,
25958
- node: k,
25959
- content: we,
25960
- regionMeta: Te
25999
+ await Promise.all(Object.keys(Ee).map((e) => uS(t, Ee[e], g, E, r)));
26000
+ let Ae = O, je = null;
26001
+ if (r.length > 0) {
26002
+ je = Math.min(...r);
26003
+ let e = Math.floor((je - Date.now()) / 1e3);
26004
+ e > 0 && e < O && (Ae = e);
26005
+ }
26006
+ let Me = {
26007
+ channelId: g || _,
26008
+ treeId: b,
26009
+ language: E,
26010
+ meta: {
26011
+ cacheTtl: Ae,
26012
+ nextEventTimestamp: je
26013
+ },
26014
+ node: re,
26015
+ content: Ee,
26016
+ regionMeta: De
25961
26017
  };
25962
- return !o && !D && (e.header("X-Cache", "MISS"), await yS(te, E, Oe, vS(e))), e.json(Oe, 200);
26018
+ return !s && !te ? (e.header("X-Cache", "MISS"), e.header("Cache-Control", `public, max-age=${Ae}, s-maxage=${Ae}`), await bS(ne, D, Me, Ae)) : e.header("Cache-Control", "no-cache, no-store, must-revalidate"), e.json(Me, 200);
25963
26019
  } catch (t) {
25964
26020
  return console.error("[CMS Public API] Error fetching node by path:", t), e.json({
25965
26021
  error: "Failed to fetch JSON payload",
@@ -25967,20 +26023,24 @@ async function bS(e) {
25967
26023
  }, 500);
25968
26024
  }
25969
26025
  }
25970
- var xS = X({
26026
+ var SS = X({
25971
26027
  channelId: J().optional().openapi({ description: "The ID or key of the channel" }),
25972
26028
  channel: J().optional().openapi({ description: "Legacy alias for channelId" }),
25973
26029
  lang: J().optional().openapi({ description: "Requested language code" }),
25974
26030
  preview: lv(["true", "false"]).optional().openapi({ description: "Request unpublished draft data" }),
25975
26031
  revisionId: J().optional().openapi({ description: "Historical revision version to load" }),
25976
26032
  treeId: J().optional().openapi({ description: "The ID of the tree to resolve paths against" })
25977
- }), SS = X({
26033
+ }), CS = X({
25978
26034
  error: J(),
25979
26035
  details: J().optional()
25980
- }).openapi("ErrorResponse"), CS = X({
26036
+ }).openapi("ErrorResponse"), wS = X({
25981
26037
  channelId: G_([J(), c_()]),
25982
26038
  treeId: J().nullable(),
25983
26039
  language: J().nullable(),
26040
+ meta: X({
26041
+ cacheTtl: c_(),
26042
+ nextEventTimestamp: c_().nullable()
26043
+ }).optional(),
25984
26044
  node: tv(k_()),
25985
26045
  content: tv(z_(k_())),
25986
26046
  regionMeta: tv(X({
@@ -25988,7 +26048,7 @@ var xS = X({
25988
26048
  inheritedFromId: J().optional(),
25989
26049
  inheritedFromTitle: J().optional()
25990
26050
  }))
25991
- }).openapi("NodeResponse"), wS = eb({
26051
+ }).openapi("NodeResponse"), TS = eb({
25992
26052
  method: "get",
25993
26053
  path: "/{path}",
25994
26054
  summary: "Fetch CMS Node Content",
@@ -25996,28 +26056,28 @@ var xS = X({
25996
26056
  tags: ["Public Node API"],
25997
26057
  request: {
25998
26058
  params: X({ path: J().optional().openapi({ description: "The full URL path or slug of the requested node" }) }),
25999
- query: xS
26059
+ query: SS
26000
26060
  },
26001
26061
  responses: {
26002
26062
  200: {
26003
26063
  description: "Fully hydrated CMS Node",
26004
- content: { "application/json": { schema: CS } }
26064
+ content: { "application/json": { schema: wS } }
26005
26065
  },
26006
26066
  404: {
26007
26067
  description: "Node or Channel not found",
26008
- content: { "application/json": { schema: SS } }
26068
+ content: { "application/json": { schema: CS } }
26009
26069
  },
26010
26070
  500: {
26011
26071
  description: "Server error during hydration",
26012
- content: { "application/json": { schema: SS } }
26072
+ content: { "application/json": { schema: CS } }
26013
26073
  }
26014
26074
  }
26015
26075
  });
26016
- oS.openapi(wS, bS), oS.get("*", bS);
26076
+ oS.openapi(TS, xS), oS.get("*", xS);
26017
26077
  //#endregion
26018
26078
  //#region server/routes/public/tree.ts
26019
- var TS = new $y();
26020
- function ES(e, t) {
26079
+ var ES = new $y();
26080
+ function DS(e, t) {
26021
26081
  let n = /* @__PURE__ */ new Date();
26022
26082
  if (e && String(e).trim() !== "") {
26023
26083
  let t = new Date(e);
@@ -26029,22 +26089,22 @@ function ES(e, t) {
26029
26089
  }
26030
26090
  return !0;
26031
26091
  }
26032
- async function DS(e, t, n, r) {
26092
+ async function OS(e, t, n, r) {
26033
26093
  try {
26034
26094
  await e.set(t, n, r);
26035
26095
  } catch (e) {
26036
26096
  console.warn("[CMS Cache] Failed to write tree response to cache:", e);
26037
26097
  }
26038
26098
  }
26039
- var OS = X({ treeParam: J().openapi({ description: "The ID or key of the requested tree (e.g., \"main-nav\")" }) }), kS = X({
26099
+ var kS = X({ treeParam: J().openapi({ description: "The ID or key of the requested tree (e.g., \"main-nav\")" }) }), AS = X({
26040
26100
  channelId: J().optional().openapi({ description: "Channel ID to resolve context-aware routing" }),
26041
26101
  channel: J().optional().openapi({ description: "Legacy alias for channelId" }),
26042
26102
  lang: J().optional().openapi({ description: "Requested language code for tree nodes" }),
26043
26103
  preview: lv(["true", "false"]).optional().openapi({ description: "Set to true to retrieve unpublished draft data" })
26044
- }), AS = X({
26104
+ }), jS = X({
26045
26105
  error: J(),
26046
26106
  details: J().optional()
26047
- }).openapi("ErrorResponse"), jS = qv(() => X({
26107
+ }).openapi("ErrorResponse"), MS = qv(() => X({
26048
26108
  id: G_([J(), c_()]),
26049
26109
  treeNodeId: G_([J(), c_()]),
26050
26110
  parentId: G_([J(), c_()]).nullable(),
@@ -26057,40 +26117,40 @@ var OS = X({ treeParam: J().openapi({ description: "The ID or key of the request
26057
26117
  summary: J(),
26058
26118
  url: J().optional(),
26059
26119
  target: J().optional(),
26060
- children: z_(jS).optional()
26061
- })).openapi("TreeItem"), MS = X({
26120
+ children: z_(MS).optional()
26121
+ })).openapi("TreeItem"), NS = X({
26062
26122
  treeId: G_([c_(), J()]),
26063
26123
  key: J(),
26064
26124
  channelId: J(),
26065
26125
  language: J().nullable(),
26066
26126
  label: J(),
26067
- items: z_(jS)
26068
- }).catchall(k_()).openapi("TreeResponse"), NS = eb({
26127
+ items: z_(MS)
26128
+ }).catchall(k_()).openapi("TreeResponse"), PS = eb({
26069
26129
  method: "get",
26070
26130
  path: "/{treeParam}",
26071
26131
  summary: "Fetch CMS Navigation Tree",
26072
26132
  description: "Retrieves a fully hydrated, recursive navigation tree structure. Uses $O(1)$ pre-computed routing table paths.",
26073
26133
  tags: ["Public Tree API"],
26074
26134
  request: {
26075
- params: OS,
26076
- query: kS
26135
+ params: kS,
26136
+ query: AS
26077
26137
  },
26078
26138
  responses: {
26079
26139
  200: {
26080
26140
  description: "Fully hydrated CMS Tree payload",
26081
- content: { "application/json": { schema: MS } }
26141
+ content: { "application/json": { schema: NS } }
26082
26142
  },
26083
26143
  404: {
26084
26144
  description: "Tree or Channel not found / inactive",
26085
- content: { "application/json": { schema: AS } }
26145
+ content: { "application/json": { schema: jS } }
26086
26146
  },
26087
26147
  500: {
26088
26148
  description: "Server error during hydration",
26089
- content: { "application/json": { schema: AS } }
26149
+ content: { "application/json": { schema: jS } }
26090
26150
  }
26091
26151
  }
26092
26152
  });
26093
- TS.openapi(NS, async (e) => {
26153
+ ES.openapi(PS, async (e) => {
26094
26154
  try {
26095
26155
  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;
26096
26156
  if (i && i !== "default" && i !== "all") {
@@ -26153,7 +26213,7 @@ TS.openapi(NS, async (e) => {
26153
26213
  return (y.get(n) || []).map((e) => {
26154
26214
  let n = b.get(String(e.id)) || {}, r = {};
26155
26215
  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);
26156
- 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 = ES(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 = {
26216
+ 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 = DS(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 = {
26157
26217
  id: e.id,
26158
26218
  treeNodeId: e.id,
26159
26219
  parentId: e.parentId || null,
@@ -26179,7 +26239,7 @@ TS.openapi(NS, async (e) => {
26179
26239
  ..._,
26180
26240
  items: x(null)
26181
26241
  };
26182
- return !o && !h && (e.header("X-Cache", "MISS"), await DS(p, m, S, 300)), e.json(S, 200);
26242
+ return !o && !h && (e.header("X-Cache", "MISS"), await OS(p, m, S, 300)), e.json(S, 200);
26183
26243
  } catch (t) {
26184
26244
  return console.error("[CMS Public Tree API] Error:", t), e.json({
26185
26245
  error: "Failed to fetch public tree",
@@ -26189,19 +26249,19 @@ TS.openapi(NS, async (e) => {
26189
26249
  });
26190
26250
  //#endregion
26191
26251
  //#region server/routes/public/channel.ts
26192
- var PS = new $y();
26193
- function FS(e) {
26252
+ var FS = new $y();
26253
+ function IS(e) {
26194
26254
  let t = Number(e?.env?.CMS_CHANNEL_CACHE_TTL);
26195
26255
  return Number.isFinite(t) && t >= 60 ? Math.floor(t) : 300;
26196
26256
  }
26197
- async function IS(e, t, n, r) {
26257
+ async function LS(e, t, n, r) {
26198
26258
  try {
26199
26259
  await e.set(t, n, r);
26200
26260
  } catch (e) {
26201
26261
  console.warn("[CMS Cache] Failed to write channel response to cache:", e);
26202
26262
  }
26203
26263
  }
26204
- function LS(e, t) {
26264
+ function RS(e, t) {
26205
26265
  let n = {}, r = (e) => {
26206
26266
  if (!e || typeof e != "string") return;
26207
26267
  let n = t?.fieldSets?.[e] || t?.fieldsets?.[e] || t?.definitions?.[e] || t?.channels?.[e] || t?.[e];
@@ -26212,7 +26272,7 @@ function LS(e, t) {
26212
26272
  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);
26213
26273
  return n;
26214
26274
  }
26215
- function RS(e, t = {}) {
26275
+ function zS(e, t = {}) {
26216
26276
  let n = {}, r = Object.keys(t).length > 0;
26217
26277
  for (let [i, a] of Object.entries(e)) {
26218
26278
  if (i.endsWith("_meta") || [
@@ -26231,14 +26291,14 @@ function RS(e, t = {}) {
26231
26291
  }
26232
26292
  return n;
26233
26293
  }
26234
- function zS(e) {
26235
- if (Array.isArray(e)) return e.map(zS);
26294
+ function BS(e) {
26295
+ if (Array.isArray(e)) return e.map(BS);
26236
26296
  if (!e || typeof e != "object") return e;
26237
26297
  if (typeof e.id == "string" && e.id.startsWith("ast_") && typeof e.url == "string") {
26238
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 ? {
26239
26299
  ...t,
26240
26300
  ...t.crops?.[r] || {}
26241
- } : t, a = Object.fromEntries(Object.entries(n).filter(([, t]) => t?.id !== e.id).map(([t, n]) => [t, zS({
26301
+ } : t, a = Object.fromEntries(Object.entries(n).filter(([, t]) => t?.id !== e.id).map(([t, n]) => [t, BS({
26242
26302
  ...n,
26243
26303
  title: n?.title ?? e.title ?? "",
26244
26304
  alt: n?.alt ?? e.alt ?? "",
@@ -26252,9 +26312,9 @@ function zS(e) {
26252
26312
  ...Object.keys(a).length > 0 ? { variants: a } : {}
26253
26313
  };
26254
26314
  }
26255
- return Object.fromEntries(Object.entries(e).map(([e, t]) => [e, zS(t)]));
26315
+ return Object.fromEntries(Object.entries(e).map(([e, t]) => [e, BS(t)]));
26256
26316
  }
26257
- async function BS(e, t, n) {
26317
+ async function VS(e, t, n) {
26258
26318
  if (typeof t == "string") {
26259
26319
  if (!t.includes("#node:") && !t.includes("data-node-id") && !t.includes("#asset:") && !t.includes("data-asset-id")) return t;
26260
26320
  let r = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Set();
@@ -26287,45 +26347,45 @@ async function BS(e, t, n) {
26287
26347
  return /href\s*=\s*["'][^"']*["']/i.test(d) ? d = d.replace(/href\s*=\s*["'][^"']*["']/i, `href="${u}"`) : d += ` href="${u}"`, `<a ${d}>`;
26288
26348
  });
26289
26349
  }
26290
- if (Array.isArray(t)) return Promise.all(t.map((t) => BS(e, t, n)));
26350
+ if (Array.isArray(t)) return Promise.all(t.map((t) => VS(e, t, n)));
26291
26351
  if (t && typeof t == "object") {
26292
- let r = await Promise.all(Object.entries(t).map(async ([t, r]) => [t, await BS(e, r, n)]));
26352
+ let r = await Promise.all(Object.entries(t).map(async ([t, r]) => [t, await VS(e, r, n)]));
26293
26353
  return Object.fromEntries(r);
26294
26354
  }
26295
26355
  return t;
26296
26356
  }
26297
- var VS = X({ channelParam: J().openapi({ description: "The ID or key (slug) of the requested channel" }) }), HS = X({ preview: lv(["true", "false"]).optional().openapi({ description: "Set to true to retrieve unpublished draft data" }) }), US = X({
26357
+ var HS = X({ channelParam: J().openapi({ description: "The ID or key (slug) of the requested channel" }) }), US = X({ preview: lv(["true", "false"]).optional().openapi({ description: "Set to true to retrieve unpublished draft data" }) }), WS = X({
26298
26358
  error: J(),
26299
26359
  details: J().optional()
26300
- }).openapi("ErrorResponse"), WS = X({
26360
+ }).openapi("ErrorResponse"), GS = X({
26301
26361
  id: G_([c_(), J()]),
26302
26362
  key: J()
26303
- }).catchall(k_()).openapi("ChannelResponse"), GS = eb({
26363
+ }).catchall(k_()).openapi("ChannelResponse"), KS = eb({
26304
26364
  method: "get",
26305
26365
  path: "/{channelParam}",
26306
26366
  summary: "Fetch CMS Channel Settings",
26307
26367
  description: "Retrieves the fully hydrated, public-facing settings and payload for a specific CMS channel.",
26308
26368
  tags: ["Public Channel API"],
26309
26369
  request: {
26310
- params: VS,
26311
- query: HS
26370
+ params: HS,
26371
+ query: US
26312
26372
  },
26313
26373
  responses: {
26314
26374
  200: {
26315
26375
  description: "Fully hydrated CMS Channel payload",
26316
- content: { "application/json": { schema: WS } }
26376
+ content: { "application/json": { schema: GS } }
26317
26377
  },
26318
26378
  404: {
26319
26379
  description: "Channel not found or inactive",
26320
- content: { "application/json": { schema: US } }
26380
+ content: { "application/json": { schema: WS } }
26321
26381
  },
26322
26382
  500: {
26323
26383
  description: "Server error during hydration",
26324
- content: { "application/json": { schema: US } }
26384
+ content: { "application/json": { schema: WS } }
26325
26385
  }
26326
26386
  }
26327
26387
  });
26328
- PS.openapi(GS, async (e) => {
26388
+ FS.openapi(KS, async (e) => {
26329
26389
  try {
26330
26390
  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);
26331
26391
  if (!i && !a) {
@@ -26336,23 +26396,23 @@ PS.openapi(GS, async (e) => {
26336
26396
  if (!c) return e.json({ error: `Channel '${n}' not found` }, 404);
26337
26397
  let l = c.status === "disabled" || c.status === "inactive" || c.isEnabled === 0 || c.isEnabled === !1;
26338
26398
  if (!i && l) return e.json({ error: `Channel '${c.key || n}' is currently inactive` }, 404);
26339
- let u = Number(c.id), d = e.env?.BUNDLED_DEFINITIONS, f = dx(d), p = c.channelType || c.key || "website", m = LS(f.channels?.[p] || f.channels?.[c.key] || f.channels?.website || f.definitions?.["channel-base"] || {}, f), h = {}, g = i && c.draftDataJson || c.dataJson;
26399
+ let u = Number(c.id), d = e.env?.BUNDLED_DEFINITIONS, f = dx(d), p = c.channelType || c.key || "website", m = RS(f.channels?.[p] || f.channels?.[c.key] || f.channels?.website || f.definitions?.["channel-base"] || {}, f), h = {}, g = i && c.draftDataJson || c.dataJson;
26340
26400
  if (g) try {
26341
26401
  h = typeof g == "string" ? JSON.parse(g) : g;
26342
26402
  } catch (e) {
26343
26403
  console.warn("[CMS Public Channel API] Failed to parse channel dataJson:", e);
26344
26404
  }
26345
- let _ = RS({
26405
+ let _ = zS({
26346
26406
  ...h,
26347
26407
  ...c
26348
26408
  }, m);
26349
- _ = await ux(t, _), _ = zS(_), _ = await BS(t, _, u);
26409
+ _ = await ux(t, _), _ = BS(_), _ = await VS(t, _, u);
26350
26410
  let v = {
26351
26411
  id: c.id,
26352
26412
  key: c.key,
26353
26413
  ..._
26354
26414
  };
26355
- return !i && !a && (e.header("X-Cache", "MISS"), await IS(s, o, v, FS(e))), e.json(v, 200);
26415
+ return !i && !a && (e.header("X-Cache", "MISS"), await LS(s, o, v, IS(e))), e.json(v, 200);
26356
26416
  } catch (t) {
26357
26417
  return console.error("[CMS Public Channel API] Error:", t), e.json({
26358
26418
  error: "Failed to fetch public channel",
@@ -26362,8 +26422,8 @@ PS.openapi(GS, async (e) => {
26362
26422
  });
26363
26423
  //#endregion
26364
26424
  //#region server/routes/public/assets.ts
26365
- var KS = new $y();
26366
- function qS(e, t) {
26425
+ var qS = new $y();
26426
+ function JS(e, t) {
26367
26427
  if (t === "webp") return "image/webp";
26368
26428
  if (t === "avif") return "image/avif";
26369
26429
  if (t === "jpeg" || t === "jpg") return "image/jpeg";
@@ -26372,7 +26432,7 @@ function qS(e, t) {
26372
26432
  let n = e.toLowerCase();
26373
26433
  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";
26374
26434
  }
26375
- var JS = eb({
26435
+ var YS = eb({
26376
26436
  method: "get",
26377
26437
  path: "/*",
26378
26438
  summary: "Serve & Optimize Media Assets",
@@ -26429,12 +26489,15 @@ var JS = eb({
26429
26489
  }
26430
26490
  }
26431
26491
  });
26432
- KS.openapi(JS, async (e) => {
26492
+ qS.openapi(YS, async (e) => {
26433
26493
  try {
26434
26494
  let t = e.req.path.replace(/^\/media\//, "").replace(/^\//, "");
26435
26495
  if (!t) return e.text("Asset key missing", 400);
26436
26496
  let { w: n, h: r, q: i, f: a } = e.req.valid("query"), o = !!(n || r || i || a), s = e.req.header("Accept") || "", c = "";
26437
- o && (a === "avif" || !a && s.includes("image/avif") ? c = "avif" : a === "webp" || !a && s.includes("image/webp") ? c = "webp" : a === "jpeg" || a === "jpg" ? c = "jpeg" : a === "png" && (c = "png"));
26497
+ if (o) {
26498
+ let e = !a || a === "auto";
26499
+ a === "avif" || e && s.includes("image/avif") ? c = "avif" : a === "webp" || e && s.includes("image/webp") ? c = "webp" : a === "jpeg" || a === "jpg" ? c = "jpeg" : a === "png" && (c = "png");
26500
+ }
26438
26501
  let l = typeof caches < "u" && caches?.default ? caches.default : null, u = e.req.url;
26439
26502
  if (o && c && !a) {
26440
26503
  let e = new URL(u);
@@ -26449,7 +26512,7 @@ KS.openapi(JS, async (e) => {
26449
26512
  if (!m) return e.text(`Asset not found: ${t}`, 404);
26450
26513
  if (!o) {
26451
26514
  let n = e.body(m, 200, {
26452
- "Content-Type": qS(t),
26515
+ "Content-Type": JS(t),
26453
26516
  "Cache-Control": "public, max-age=31536000, immutable"
26454
26517
  });
26455
26518
  return l && d && e.executionCtx?.waitUntil && e.executionCtx.waitUntil(l.put(d, n.clone())), n;
@@ -26463,7 +26526,7 @@ KS.openapi(JS, async (e) => {
26463
26526
  key: t,
26464
26527
  env: e.env,
26465
26528
  req: e.req.raw
26466
- }), _ = qS(t, c), v = e.body(g, 200, {
26529
+ }), _ = JS(t, c), v = e.body(g, 200, {
26467
26530
  "Content-Type": _,
26468
26531
  "Cache-Control": "public, max-age=31536000, immutable"
26469
26532
  });
@@ -26474,8 +26537,8 @@ KS.openapi(JS, async (e) => {
26474
26537
  });
26475
26538
  //#endregion
26476
26539
  //#region server/routes/public/paths.ts
26477
- var YS = new $y();
26478
- function XS(e, t) {
26540
+ var XS = new $y();
26541
+ function ZS(e, t) {
26479
26542
  let n = /* @__PURE__ */ new Date();
26480
26543
  if (e && String(e).trim() !== "") {
26481
26544
  let t = new Date(e);
@@ -26487,31 +26550,31 @@ function XS(e, t) {
26487
26550
  }
26488
26551
  return !0;
26489
26552
  }
26490
- var ZS = X({
26553
+ var QS = X({
26491
26554
  channelId: J().optional().openapi({ description: "Optional channel ID/key to filter and resolve root paths for" }),
26492
26555
  channel: J().optional().openapi({ description: "Legacy alias for channelId" })
26493
- }), QS = z_(J()).openapi("PathsResponse"), $S = X({
26556
+ }), $S = z_(J()).openapi("PathsResponse"), eC = X({
26494
26557
  error: J(),
26495
26558
  details: J().optional()
26496
- }).openapi("ErrorResponse"), eC = eb({
26559
+ }).openapi("ErrorResponse"), tC = eb({
26497
26560
  method: "get",
26498
26561
  path: "/",
26499
26562
  summary: "Fetch All Public Paths",
26500
26563
  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.",
26501
26564
  tags: ["Public Paths API"],
26502
- request: { query: ZS },
26565
+ request: { query: QS },
26503
26566
  responses: {
26504
26567
  200: {
26505
26568
  description: "Array of valid public URL paths",
26506
- content: { "application/json": { schema: QS } }
26569
+ content: { "application/json": { schema: $S } }
26507
26570
  },
26508
26571
  500: {
26509
26572
  description: "Server error fetching paths",
26510
- content: { "application/json": { schema: $S } }
26573
+ content: { "application/json": { schema: eC } }
26511
26574
  }
26512
26575
  }
26513
26576
  });
26514
- YS.openapi(eC, async (e) => {
26577
+ XS.openapi(tC, async (e) => {
26515
26578
  try {
26516
26579
  let t = e.get("db"), n = e.req.valid("query"), r = n.channelId || n.channel, i = "", a = [];
26517
26580
  if (r && r !== "all") {
@@ -26536,7 +26599,7 @@ YS.openapi(eC, async (e) => {
26536
26599
  let t = !0;
26537
26600
  if (e.dataJson) try {
26538
26601
  let n = typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson;
26539
- t = XS(n?.startShowingAt, n?.stopShowingAt);
26602
+ t = ZS(n?.startShowingAt, n?.stopShowingAt);
26540
26603
  } catch {}
26541
26604
  t && c.push(e.path);
26542
26605
  }
@@ -26548,12 +26611,12 @@ YS.openapi(eC, async (e) => {
26548
26611
  });
26549
26612
  //#endregion
26550
26613
  //#region server/routes/public/taxonomies.ts
26551
- var tC = new $y();
26552
- function nC(e) {
26614
+ var nC = new $y();
26615
+ function rC(e) {
26553
26616
  let t = (e || "").trim().toLowerCase(), n = dx()?.taxonomies || {};
26554
26617
  return n[t] ? t : n[`${t}s`] ? `${t}s` : t.endsWith("s") && n[t.slice(0, -1)] ? t.slice(0, -1) : t;
26555
26618
  }
26556
- var rC = X({
26619
+ var iC = X({
26557
26620
  id: c_(),
26558
26621
  taxonomy: J(),
26559
26622
  key: J(),
@@ -26563,14 +26626,14 @@ var rC = X({
26563
26626
  data: tv(k_()),
26564
26627
  createdAt: J(),
26565
26628
  updatedAt: J()
26566
- }), iC = X({
26629
+ }), aC = X({
26567
26630
  taxonomy: J(),
26568
- items: z_(rC),
26631
+ items: z_(iC),
26569
26632
  total: c_()
26570
- }).openapi("TaxonomyResponse"), aC = X({
26633
+ }).openapi("TaxonomyResponse"), oC = X({
26571
26634
  error: J(),
26572
26635
  details: J().optional()
26573
- }).openapi("ErrorResponse"), oC = eb({
26636
+ }).openapi("ErrorResponse"), sC = eb({
26574
26637
  method: "get",
26575
26638
  path: "/{taxonomy}",
26576
26639
  summary: "Fetch Public Taxonomy Terms",
@@ -26580,17 +26643,17 @@ var rC = X({
26580
26643
  responses: {
26581
26644
  200: {
26582
26645
  description: "List of taxonomy terms",
26583
- content: { "application/json": { schema: iC } }
26646
+ content: { "application/json": { schema: aC } }
26584
26647
  },
26585
26648
  500: {
26586
26649
  description: "Server error",
26587
- content: { "application/json": { schema: aC } }
26650
+ content: { "application/json": { schema: oC } }
26588
26651
  }
26589
26652
  }
26590
26653
  });
26591
- tC.openapi(oC, async (e) => {
26654
+ nC.openapi(sC, async (e) => {
26592
26655
  try {
26593
- let t = e.get("db"), n = $b(e), r = e.req.valid("param").taxonomy, i = nC(r), a = `taxonomy:public:${i}`, o = e.req.header("x-bypass-cache") === "true";
26656
+ let t = e.get("db"), n = $b(e), r = e.req.valid("param").taxonomy, i = rC(r), a = `taxonomy:public:${i}`, o = e.req.header("x-bypass-cache") === "true";
26594
26657
  if (!o) {
26595
26658
  let t = await n.get(a);
26596
26659
  if (t) return e.header("X-Cache", "HIT"), e.json(t);
@@ -26626,7 +26689,7 @@ tC.openapi(oC, async (e) => {
26626
26689
  });
26627
26690
  //#endregion
26628
26691
  //#region server/index.ts
26629
- var $ = new $y(), sC = !1;
26692
+ var $ = new $y(), cC = !1;
26630
26693
  $.use("*", t()), $.use("/media/*", t({
26631
26694
  origin: "*",
26632
26695
  allowMethods: [
@@ -26647,13 +26710,13 @@ $.use("*", t()), $.use("/media/*", t({
26647
26710
  let n = new URL(e.req.url), r = (e.req.header("host") || n.hostname).split(":")[0];
26648
26711
  e.set("currentDomain", r);
26649
26712
  let i = wb(e);
26650
- if (e.set("db", i), !sC) try {
26651
- await Mb(i), sC = !0;
26713
+ if (e.set("db", i), !cC) try {
26714
+ await Mb(i), cC = !0;
26652
26715
  } catch (e) {
26653
26716
  console.error("❌ [CMS Server] Failed to initialize system tables on cold start:", e);
26654
26717
  }
26655
26718
  await t();
26656
- }), $.route("/media", KS), $.use("/media/*", Pb()), $.route("/api/cms/nodes", mx), $.route("/api/cms/nodes.json", mx), $.route("/api/cms/formcsv", mx), $.route("/api/cms/formcsv.json", mx), $.route("/api/cms/stats", tS), $.route("/api/cms/stats.json", tS), $.route("/api/cms", Tx), $.route("/api/cms/trees.json", Tx), $.route("/api/cms/channels", kx), $.route("/api/cms/channels.json", kx), $.route("/api/cms/taxonomies", Ax), $.route("/api/cms/taxonomies.json", Ax), $.route("/api/cms/schemas", Xx), $.route("/api/cms/schemas.json", Xx), $.route("/api/cms", Qx), $.route("/api/admin/assets", nS), $.route("/api/v1/node", oS), $.route("/api/v1/tree", TS), $.route("/api/v1/channel", PS), $.route("/api/v1/all-paths", YS), $.route("/api/v1/taxonomies", tC), $.doc("/api/openapi.json", {
26719
+ }), $.route("/media", qS), $.use("/media/*", Pb()), $.route("/api/cms/nodes", mx), $.route("/api/cms/nodes.json", mx), $.route("/api/cms/formcsv", mx), $.route("/api/cms/formcsv.json", mx), $.route("/api/cms/stats", tS), $.route("/api/cms/stats.json", tS), $.route("/api/cms", Tx), $.route("/api/cms/trees.json", Tx), $.route("/api/cms/channels", kx), $.route("/api/cms/channels.json", kx), $.route("/api/cms/taxonomies", Ax), $.route("/api/cms/taxonomies.json", Ax), $.route("/api/cms/schemas", Xx), $.route("/api/cms/schemas.json", Xx), $.route("/api/cms", Qx), $.route("/api/admin/assets", nS), $.route("/api/v1/node", oS), $.route("/api/v1/tree", ES), $.route("/api/v1/channel", FS), $.route("/api/v1/all-paths", XS), $.route("/api/v1/taxonomies", nC), $.doc("/api/openapi.json", {
26657
26720
  openapi: "3.0.0",
26658
26721
  info: {
26659
26722
  title: "KAMA Engine Public API",