@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.
@@ -183,13 +183,13 @@ function C(e) {
183
183
  let t = new g();
184
184
  return e.forEach((e) => t.put(e)), [...t.values()];
185
185
  }
186
- function ee(e) {
186
+ function w(e) {
187
187
  return typeof e == "string";
188
188
  }
189
- function w(e) {
189
+ function T(e) {
190
190
  return Object.fromEntries(Object.entries(e).sort(([e], [t]) => e.localeCompare(t)));
191
191
  }
192
- var T = m(), E = class {
192
+ var ee = m(), E = class {
193
193
  static collectMetadata(e, t) {
194
194
  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 } : {});
195
195
  if (l(e, [
@@ -257,7 +257,7 @@ var T = m(), E = class {
257
257
  return t ? void 0 : e;
258
258
  }
259
259
  static getMetadataFromInternalRegistry(e) {
260
- return T.get(e);
260
+ return ee.get(e);
261
261
  }
262
262
  static getMetadataFromRegistry(e) {
263
263
  let t = this.getMetadataFromInternalRegistry(e), n = e.meta();
@@ -266,7 +266,7 @@ var T = m(), E = class {
266
266
  return Object.assign(Object.assign(Object.assign({ _internal: Object.assign(Object.assign({}, o ? { refId: o } : {}), r) }, i), c ? { description: c } : {}), l);
267
267
  }
268
268
  static setMetadataInRegistry(e, t) {
269
- T.add(e, t);
269
+ ee.add(e, t);
270
270
  }
271
271
  };
272
272
  function D(e, t) {
@@ -427,7 +427,7 @@ var oe = class extends A {
427
427
  getDiscriminatorValues(e, t) {
428
428
  if (l(e, "ZodObject")) {
429
429
  let n = e.def.shape?.[t];
430
- return n ? l(n, "ZodEnum") ? Object.values(n._zod.def.entries).filter(ee) : l(n, "ZodLiteral") ? n.def.values.filter(ee) : [] : [];
430
+ return n ? l(n, "ZodEnum") ? Object.values(n._zod.def.entries).filter(w) : l(n, "ZodLiteral") ? n.def.values.filter(w) : [] : [];
431
431
  }
432
432
  if (l(e, "ZodDiscriminatedUnion")) {
433
433
  let n = e.def.options.filter(u);
@@ -436,20 +436,20 @@ var oe = class extends A {
436
436
  return [];
437
437
  }
438
438
  };
439
- function j(e) {
439
+ function ue(e) {
440
440
  let t = Object.keys(e).filter((t) => typeof e[e[t]] != "number").map((t) => e[t]), n = t.filter((e) => typeof e == "number").length;
441
441
  return {
442
442
  values: t,
443
443
  type: n === 0 ? "string" : n === t.length ? "numeric" : "mixed"
444
444
  };
445
445
  }
446
- var ue = class {
446
+ var de = class {
447
447
  transform(e, t, n) {
448
- let { type: r, values: i } = j(e._zod.def.entries);
448
+ let { type: r, values: i } = ue(e._zod.def.entries);
449
449
  if (r === "mixed") throw new A("Enum has mixed string and number values, please specify the OpenAPI type manually");
450
450
  return Object.assign(Object.assign({}, n(r === "numeric" ? "integer" : "string")), { enum: t ? [...i, null] : i });
451
451
  }
452
- }, de = class {
452
+ }, j = class {
453
453
  transform(e, t, n, r) {
454
454
  let i = { allOf: this.flattenIntersectionTypes(e).map(r) };
455
455
  return t ? { anyOf: n([i], t) } : i;
@@ -497,7 +497,7 @@ var ue = class {
497
497
  transform(e, t, n) {
498
498
  let r = e.valueType, i = e.keyType, a = u(r) ? n(r) : {};
499
499
  if (l(i, "ZodEnum")) {
500
- let e = Object.values(i._zod.def.entries).filter(ee).reduce((e, t) => Object.assign(Object.assign({}, e), { [t]: a }), {});
500
+ let e = Object.values(i._zod.def.entries).filter(w).reduce((e, t) => Object.assign(Object.assign({}, e), { [t]: a }), {});
501
501
  return Object.assign(Object.assign({}, t("object")), { properties: e });
502
502
  }
503
503
  return Object.assign(Object.assign({}, t("object")), { additionalProperties: a });
@@ -588,7 +588,7 @@ var ve = class {
588
588
  if (l(e, "ZodNumber")) return "[+-]?\\d+(\\.\\d+)?";
589
589
  if (l(e, "ZodBoolean")) return "(true|false)";
590
590
  if (l(e, "ZodEnum")) {
591
- let { values: t } = j(e.def.entries);
591
+ let { values: t } = ue(e.def.entries);
592
592
  return `(${t.map((e) => this.escapeRegex(String(e))).join("|")})`;
593
593
  }
594
594
  return ".*";
@@ -598,7 +598,7 @@ var ve = class {
598
598
  }
599
599
  }, we = class {
600
600
  constructor(e, t) {
601
- 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);
601
+ 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);
602
602
  }
603
603
  transform(e, t, n, r, i) {
604
604
  if (l(e, "ZodNull")) return this.versionSpecifics.nullType;
@@ -648,7 +648,7 @@ var ve = class {
648
648
  this.rawComponents.forEach(({ componentType: t, name: n, component: r }) => {
649
649
  e[t] ?? (e[t] = {}), e[t][n] = r;
650
650
  });
651
- 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;
651
+ 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;
652
652
  return Object.assign(Object.assign({}, e), {
653
653
  schemas: r,
654
654
  parameters: o
@@ -21888,18 +21888,18 @@ var Fb = { hasSubscribers: !1 }, Ib = Fb, Lb = Fb, Rb = typeof performance == "o
21888
21888
  return this.#i;
21889
21889
  }
21890
21890
  constructor(t) {
21891
- 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;
21892
- if (this.backgroundFetchSize = ee, w !== void 0 && typeof w?.now != "function") throw TypeError("perf option must have a now() method if specified");
21893
- if (this.#s = w ?? Rb, n !== 0 && !Wb(n)) throw TypeError("max option must be a nonnegative integer");
21894
- let T = n ? Gb(n) : Array;
21895
- if (!T) throw Error("invalid max value: " + n);
21891
+ 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;
21892
+ if (this.backgroundFetchSize = w, T !== void 0 && typeof T?.now != "function") throw TypeError("perf option must have a now() method if specified");
21893
+ if (this.#s = T ?? Rb, n !== 0 && !Wb(n)) throw TypeError("max option must be a nonnegative integer");
21894
+ let ee = n ? Gb(n) : Array;
21895
+ if (!ee) throw Error("invalid max value: " + n);
21896
21896
  if (this.#e = n, this.#t = m, this.maxEntrySize = h || this.#t, this.sizeCalculation = g, this.sizeCalculation) {
21897
21897
  if (!this.#t && !this.maxEntrySize) throw TypeError("cannot set sizeCalculation without setting maxSize or maxEntrySize");
21898
21898
  if (typeof this.sizeCalculation != "function") throw TypeError("sizeCalculation set to non-function");
21899
21899
  }
21900
21900
  if (v !== void 0 && typeof v != "function") throw TypeError("memoMethod must be a function if defined");
21901
21901
  if (this.#o = v, _ !== void 0 && typeof _ != "function") throw TypeError("fetchMethod must be a function if specified");
21902
- 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) {
21902
+ 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) {
21903
21903
  if (this.#t !== 0 && !Wb(this.#t)) throw TypeError("maxSize must be a positive integer if specified");
21904
21904
  if (!Wb(this.maxEntrySize)) throw TypeError("maxEntrySize must be a positive integer if specified");
21905
21905
  this.#M();
@@ -23006,7 +23006,7 @@ var fx = class {
23006
23006
  });
23007
23007
  return clearTimeout(n), r;
23008
23008
  } catch (e) {
23009
- 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 });
23009
+ 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 });
23010
23010
  }
23011
23011
  }
23012
23012
  async purgeInternalWorkerCache(e, t, n, r, i) {
@@ -23029,67 +23029,70 @@ var fx = class {
23029
23029
  }
23030
23030
  }
23031
23031
  purgeNode(e, t, n, r = !1, i = []) {
23032
+ if (r) {
23033
+ console.log(`[CacheManager] Structural change detected on nodeId ${n}. Escalating to Global Purge.`), this.purgeGlobalCache(e, t);
23034
+ return;
23035
+ }
23032
23036
  let a = (async () => {
23033
23037
  try {
23034
- 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]) || {};
23035
- if (!o.slug) return;
23036
- 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();
23037
- for (let e of l) if (e.baseUrl && typeof e.baseUrl == "string" && e.baseUrl.trim() !== "") {
23038
+ 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]) || {};
23039
+ if (!a.slug) return;
23040
+ 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();
23041
+ for (let e of c) if (e.baseUrl && typeof e.baseUrl == "string" && e.baseUrl.trim() !== "") {
23038
23042
  let t = e.baseUrl.trim();
23039
- !t.startsWith("http://") && !t.startsWith("https://") && (t = `https://${t}`), m.add(t.replace(/\/+$/, ""));
23043
+ !t.startsWith("http://") && !t.startsWith("https://") && (t = `https://${t}`), p.add(t.replace(/\/+$/, ""));
23040
23044
  }
23041
- m.size === 0 && p && m.add(p);
23042
- 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);
23043
- await this.purgeInternalWorkerCache(e, t, n, f, d);
23044
- let v = this.getEnv(e).cdnDomain, { zoneId: y, apiToken: b } = this.getEnv(e), x = e.env?.BUNDLED_DEFINITIONS || {}, S = /* @__PURE__ */ new Set();
23045
- if (i.length > 0 && x.layouts) for (let e of Object.values(x.layouts)) for (let t of i) {
23045
+ p.size === 0 && f && p.add(f);
23046
+ 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);
23047
+ await this.purgeInternalWorkerCache(e, t, n, d, u);
23048
+ let _ = this.getEnv(e).cdnDomain, { zoneId: v, apiToken: y } = this.getEnv(e), b = e.env?.BUNDLED_DEFINITIONS || {}, x = /* @__PURE__ */ new Set();
23049
+ if (i.length > 0 && b.layouts) for (let e of Object.values(b.layouts)) for (let t of i) {
23046
23050
  let n = e.regions?.[t];
23047
23051
  if (n) {
23048
23052
  let e = n.purgeTargets || n.purgeTarget;
23049
23053
  if (e) {
23050
23054
  let t = Array.isArray(e) ? e : [e];
23051
- for (let e of t) typeof e == "string" && e.trim() && S.add(e.trim());
23055
+ for (let e of t) typeof e == "string" && e.trim() && x.add(e.trim());
23052
23056
  }
23053
23057
  }
23054
23058
  }
23055
- for (let t of m) {
23056
- let n = f === "home" || !f ? t : `${t}/${f}`, i = [n, `${n}/`];
23057
- r && i.push(`${t}/partials/nav`);
23058
- for (let e of S) {
23059
+ for (let t of p) {
23060
+ let n = d === "home" || !d ? t : `${t}/${d}`, r = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Set();
23061
+ r.add(n), r.add(`${n}/`), i.add(n), i.add(`${n}/`);
23062
+ for (let e of x) {
23059
23063
  let n = e.startsWith("/") ? e : `/${e}`;
23060
- i.push(`${t}${n}`);
23064
+ r.add(`${t}${n}`), i.add(`${t}${n}`);
23061
23065
  }
23062
- let a = d ? `&lang=${d}` : "";
23063
- 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}`));
23064
- else i.push(`https://${v}/api/v1/node/${f}${d ? `?lang=${d}` : ""}`), r && i.push(`https://${v}/api/v1/tree/main-nav`);
23065
- for (let e of _) e && i.push(`${t}${e.startsWith("/") ? e : `/${e}`}`);
23066
- 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`, {
23067
- method: "POST",
23068
- headers: {
23069
- Authorization: `Bearer ${b}`,
23070
- "Content-Type": "application/json"
23071
- },
23072
- body: JSON.stringify({ files: i })
23073
- }).catch(() => {}), r) {
23074
- let e = `${t}/partials/nav?_warmer=${Date.now()}`;
23075
- console.log(`[CacheManager] Prewarming cache at: ${e}`), fetch(e, { headers: {
23076
- "X-Cache-Warmer": "true",
23077
- "User-Agent": "Kama-Cache-Warmer/1.0"
23078
- } }).catch((e) => console.warn("[CacheManager] Prewarm fetch error:", e));
23079
- } else {
23080
- let e = `${n}${n.includes("?") ? "&" : "?"} _warmer=${Date.now()}`;
23081
- console.log(`[CacheManager] Prewarming cache at: ${e}`), fetch(e, { headers: {
23082
- "X-Cache-Warmer": "true",
23083
- "User-Agent": "Kama-Cache-Warmer/1.0"
23084
- } }).catch((e) => console.warn("[CacheManager] Prewarm fetch error:", e));
23066
+ let a = u ? `&lang=${u}` : "";
23067
+ 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}`);
23068
+ else i.add(`https://${_}/api/v1/node/${d}${u ? `?lang=${u}` : ""}`);
23069
+ for (let e of g) e && i.add(`${t}${e.startsWith("/") ? e : `/${e}`}`);
23070
+ if (await this.callAstroPurge(e, { urls: Array.from(r) }, t), v && y && !this.isLocalEnv(e, t)) try {
23071
+ let e = await (await fetch(`https://api.cloudflare.com/client/v4/zones/${v}/purge_cache`, {
23072
+ method: "POST",
23073
+ headers: {
23074
+ Authorization: `Bearer ${y}`,
23075
+ "Content-Type": "application/json"
23076
+ },
23077
+ body: JSON.stringify({ files: Array.from(i) })
23078
+ })).json();
23079
+ console.log("[CacheManager] CF Zone Purge Result:", e?.success ? "SUCCESS" : JSON.stringify(e));
23080
+ } catch (e) {
23081
+ console.warn("[CacheManager] CF Zone Purge failed to dispatch:", e);
23085
23082
  }
23086
- for (let e of S) {
23087
- let n = `${t}${e.startsWith("/") ? e : `/${e}`}?_warmer=${Date.now()}`;
23088
- console.log(`[CacheManager] Prewarming custom target: ${n}`), fetch(n, { headers: {
23083
+ let o = [], s = Date.now(), l = `${n}${n.includes("?") ? "&" : "?"}_warmer=${s}`;
23084
+ console.log(`[CacheManager] Prewarming cache at: ${l}`), o.push(fetch(l, { headers: {
23085
+ "X-Cache-Warmer": "true",
23086
+ "User-Agent": "Kama-Cache-Warmer/1.0"
23087
+ } }).catch((e) => console.warn("[CacheManager] Prewarm fetch error:", e)));
23088
+ for (let e of x) {
23089
+ let n = `${t}${e.startsWith("/") ? e : `/${e}`}?_warmer=${s}`;
23090
+ console.log(`[CacheManager] Prewarming custom target: ${n}`), o.push(fetch(n, { headers: {
23089
23091
  "X-Cache-Warmer": "true",
23090
23092
  "User-Agent": "Kama-Cache-Warmer/1.0"
23091
- } }).catch(() => {});
23093
+ } }).catch(() => {}));
23092
23094
  }
23095
+ await Promise.all(o);
23093
23096
  }
23094
23097
  } catch (e) {
23095
23098
  console.warn("[CacheManager] Dynamic purgeNode failed:", e);
@@ -23115,17 +23118,26 @@ var fx = class {
23115
23118
  try {
23116
23119
  let { zoneId: n, apiToken: r } = this.getEnv(e);
23117
23120
  if (!(await this.callAstroPurge(e, { purge_everything: !0 })).ok) return;
23118
- if (n && r && !this.isLocalEnv(e) && fetch(`https://api.cloudflare.com/client/v4/zones/${n}/purge_cache`, {
23119
- method: "POST",
23120
- headers: {
23121
- Authorization: `Bearer ${r}`,
23122
- "Content-Type": "application/json"
23123
- },
23124
- body: JSON.stringify({ purge_everything: !0 })
23125
- }).catch(() => {}), await new Promise((e) => setTimeout(e, 100)), t) await this.warmAllPublishedPages(e, t);
23121
+ if (n && r && !this.isLocalEnv(e)) try {
23122
+ let e = await (await fetch(`https://api.cloudflare.com/client/v4/zones/${n}/purge_cache`, {
23123
+ method: "POST",
23124
+ headers: {
23125
+ Authorization: `Bearer ${r}`,
23126
+ "Content-Type": "application/json"
23127
+ },
23128
+ body: JSON.stringify({ purge_everything: !0 })
23129
+ })).json();
23130
+ console.log("[CacheManager] CF Global Purge Result:", e?.success ? "SUCCESS" : JSON.stringify(e));
23131
+ } catch (e) {
23132
+ console.warn("[CacheManager] CF Global Purge failed to dispatch:", e);
23133
+ }
23134
+ if (t) await this.warmAllPublishedPages(e, t);
23126
23135
  else {
23127
23136
  let { frontendUrl: t } = this.getEnv(e);
23128
- fetch(`${t.replace(/\/+$/, "")}/?_warmer=${Date.now()}`, { headers: { "X-Cache-Warmer": "true" } }).catch(() => {});
23137
+ await fetch(`${t.replace(/\/+$/, "")}/?_warmer=${Date.now()}`, { headers: {
23138
+ "X-Cache-Warmer": "true",
23139
+ "User-Agent": "Kama-Cache-Warmer/1.0"
23140
+ } }).catch(() => {});
23129
23141
  }
23130
23142
  } catch (e) {
23131
23143
  console.warn("[CacheManager] Direct Global Purge skipped:", e);
@@ -23473,38 +23485,50 @@ mx.get("/", async (e) => {
23473
23485
  let x = `
23474
23486
  WITH filtered_nodes AS (
23475
23487
  SELECT cn.* FROM content_nodes cn ${g} ORDER BY ${y} ${l} LIMIT ? OFFSET ?
23488
+ ),
23489
+ node_asset_counts AS (
23490
+ SELECT
23491
+ na.nodeId,
23492
+ COUNT(DISTINCT CASE WHEN a.mimeType LIKE 'image/%' THEN COALESCE(a.parentAssetId, a.id) END) as imageCount,
23493
+ COUNT(DISTINCT CASE WHEN a.mimeType LIKE 'video/%' OR a.mimeType LIKE 'audio/%' THEN COALESCE(a.parentAssetId, a.id) END) as videoCount,
23494
+ 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,
23495
+ 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,
23496
+ COUNT(DISTINCT COALESCE(a.parentAssetId, a.id)) as assetCount
23497
+ FROM node_assets na
23498
+ JOIN assets a ON na.assetId = a.id
23499
+ GROUP BY na.nodeId
23476
23500
  )
23477
- SELECT fn.*,
23478
- COUNT(DISTINCT CASE WHEN a.mimeType LIKE 'image/%' THEN COALESCE(a.parentAssetId, a.id) END) as imageCount,
23479
- COUNT(DISTINCT CASE WHEN a.mimeType LIKE 'video/%' OR a.mimeType LIKE 'audio/%' THEN COALESCE(a.parentAssetId, a.id) END) as videoCount,
23480
- 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,
23481
- 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,
23482
- COUNT(DISTINCT COALESCE(a.parentAssetId, a.id)) as assetCount,
23483
- (SELECT path FROM node_routes nr WHERE nr.nodeId = fn.id AND isCanonical = 1 LIMIT 1) as routePath
23501
+ SELECT
23502
+ fn.*,
23503
+ COALESCE(nac.imageCount, 0) as imageCount,
23504
+ COALESCE(nac.videoCount, 0) as videoCount,
23505
+ COALESCE(nac.documentCount, 0) as documentCount,
23506
+ COALESCE(nac.otherCount, 0) as otherCount,
23507
+ COALESCE(nac.assetCount, 0) as assetCount,
23508
+ (SELECT path FROM node_routes nr WHERE nr.nodeId = fn.id AND isCanonical = 1 LIMIT 1) as routePath
23484
23509
  FROM filtered_nodes fn
23485
- LEFT JOIN node_assets na ON fn.id = na.nodeId
23486
- LEFT JOIN assets a ON na.assetId = a.id
23487
- GROUP BY fn.id ORDER BY ${y.replace("cn.", "fn.")} ${l}
23510
+ LEFT JOIN node_asset_counts nac ON fn.id = nac.nodeId
23511
+ ORDER BY ${y.replace("cn.", "fn.")} ${l}
23488
23512
  `, S = [
23489
23513
  ...m,
23490
23514
  f,
23491
23515
  p
23492
- ], C = await t.prepare(x).all(...S), ee = Array.isArray(C) ? C : C?.results || [], w = ee.map((e) => e.id), T = {}, E = {};
23493
- if (w.length > 0) {
23494
- let e = w.map(() => "?").join(","), n = await t.prepare(`
23516
+ ], C = await t.prepare(x).all(...S), w = Array.isArray(C) ? C : C?.results || [], T = w.map((e) => e.id), ee = {}, E = {};
23517
+ if (T.length > 0) {
23518
+ let e = T.map(() => "?").join(","), n = await t.prepare(`
23495
23519
  SELECT nc.nodeId, c.label FROM node_channels nc JOIN channels c ON nc.channelId = c.id WHERE nc.nodeId IN (${e})
23496
- `).all(...w);
23520
+ `).all(...T);
23497
23521
  (Array.isArray(n) ? n : n?.results || []).forEach((e) => {
23498
- T[e.nodeId] || (T[e.nodeId] = []), T[e.nodeId].push(e.label);
23522
+ ee[e.nodeId] || (ee[e.nodeId] = []), ee[e.nodeId].push(e.label);
23499
23523
  });
23500
23524
  let r = await t.prepare(`
23501
23525
  SELECT tn.contentId as nodeId, t.label FROM tree_nodes tn JOIN trees t ON tn.treeId = t.id WHERE tn.contentId IN (${e})
23502
- `).all(...w);
23526
+ `).all(...T);
23503
23527
  (Array.isArray(r) ? r : r?.results || []).forEach((e) => {
23504
23528
  E[e.nodeId] || (E[e.nodeId] = []), E[e.nodeId].includes(e.label) || E[e.nodeId].push(e.label);
23505
23529
  });
23506
23530
  }
23507
- let D = await Promise.all(ee.map(async (e) => {
23531
+ let D = await Promise.all(w.map(async (e) => {
23508
23532
  let n = e.status === "draft" || !!e.hasUnpublishedChanges, r = {
23509
23533
  id: e.id,
23510
23534
  title: e.title,
@@ -23522,7 +23546,7 @@ mx.get("/", async (e) => {
23522
23546
  updatedById: e.updatedById || null,
23523
23547
  createdAt: e.createdAt,
23524
23548
  updatedAt: e.updatedAt,
23525
- channelNames: T[e.id] || [],
23549
+ channelNames: ee[e.id] || [],
23526
23550
  treeNames: E[e.id] || [],
23527
23551
  assetCount: e.assetCount || 0,
23528
23552
  imageCount: e.imageCount || 0,
@@ -23544,9 +23568,9 @@ mx.get("/", async (e) => {
23544
23568
  limit: f
23545
23569
  });
23546
23570
  }), mx.post("/", async (e) => {
23547
- 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;
23548
- if (T) {
23549
- let e = await t.prepare("SELECT dataJson FROM trees WHERE id = ? OR key = ? LIMIT 1").get(Number(T) || -1, String(T));
23571
+ 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;
23572
+ if (ee) {
23573
+ let e = await t.prepare("SELECT dataJson FROM trees WHERE id = ? OR key = ? LIMIT 1").get(Number(ee) || -1, String(ee));
23550
23574
  if (e?.dataJson) try {
23551
23575
  let t = typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson;
23552
23576
  E = t.defaultLanguage?.trim() || t.language?.trim() || null;
@@ -23565,7 +23589,7 @@ mx.get("/", async (e) => {
23565
23589
  }
23566
23590
  }
23567
23591
  }
23568
- ee && E && ee === E && (ee = null);
23592
+ w && E && w === E && (w = null);
23569
23593
  let D = a, te = /* @__PURE__ */ new Set(), ne = !1, O = "draft", k = 0, A = s === void 0 ? null : _x(s);
23570
23594
  if (A) {
23571
23595
  let n = [];
@@ -23616,7 +23640,7 @@ mx.get("/", async (e) => {
23616
23640
  ...r,
23617
23641
  ...v
23618
23642
  }), l = !1;
23619
- 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) {
23643
+ 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) {
23620
23644
  for (let e of Object.keys(v)) if (JSON.stringify(v[e]) !== JSON.stringify(r[e])) {
23621
23645
  l = !0;
23622
23646
  break;
@@ -23638,13 +23662,13 @@ mx.get("/", async (e) => {
23638
23662
  }
23639
23663
  }
23640
23664
  }
23641
- 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;
23665
+ 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;
23642
23666
  O = e?.status === "published" || e?.publishedAt ? "published" : "draft";
23643
23667
  let h = e?.hasUnpublishedChanges === 1 || e?.hasUnpublishedChanges === !0;
23644
23668
  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);
23645
23669
  } else {
23646
23670
  ne = !0;
23647
- 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);
23671
+ 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);
23648
23672
  D = Number(e.lastInsertRowid);
23649
23673
  }
23650
23674
  if (h !== void 0 && Array.isArray(h) && D) {
@@ -24178,18 +24202,19 @@ kx.get("/", async (e) => {
24178
24202
  }
24179
24203
  }), kx.post("/", async (e) => {
24180
24204
  try {
24181
- 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 || "";
24182
- typeof w == "object" && w && (w = w.value || w.id || ""), w = String(w).trim();
24183
- 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;
24205
+ 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 || "";
24206
+ typeof T == "object" && T && (T = T.value || T.id || ""), T = String(T).trim();
24207
+ 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;
24184
24208
  if (await t.prepare("SELECT id FROM channels WHERE key = ? AND id != ? LIMIT 1").get(C, a ?? -1)) return e.json({
24185
24209
  error: `Channel API key "${C}" is already in use.`,
24186
24210
  field: "key"
24187
24211
  }, 409);
24188
24212
  let ne = a;
24189
- 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);
24213
+ 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);
24190
24214
  else {
24191
- 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);
24192
- ne = Number(e.lastInsertRowid);
24215
+ 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;
24216
+ if (!n || !n.id) throw Error("Failed to retrieve newly created Channel ID from Cloudflare D1.");
24217
+ ne = Number(n.id);
24193
24218
  }
24194
24219
  await t.prepare("DELETE FROM channel_trees WHERE channelId = ?").run(ne);
24195
24220
  let O = E.filter((e) => e && e.treeId && e.key);
@@ -24538,7 +24563,7 @@ function Yx(e) {
24538
24563
  channelTemplate: null,
24539
24564
  userTemplate: null
24540
24565
  };
24541
- 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 = {
24566
+ 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 = {
24542
24567
  ...p,
24543
24568
  ...f
24544
24569
  }, k = (e, t = "settings", n, r) => {
@@ -24666,7 +24691,7 @@ function Yx(e) {
24666
24691
  };
24667
24692
  });
24668
24693
  let ie = {};
24669
- Object.entries(ee).forEach(([e, t]) => {
24694
+ Object.entries(w).forEach(([e, t]) => {
24670
24695
  let n = A(t.tabs), r = k(t.fields || [], "settings", n);
24671
24696
  Array.isArray(t.fieldSets) && t.fieldSets.forEach((e) => {
24672
24697
  let t = O[e] || {}, i = t.fields || t, a = k(i, "settings", n);
@@ -24686,7 +24711,7 @@ function Yx(e) {
24686
24711
  };
24687
24712
  });
24688
24713
  let ae = {};
24689
- Object.entries(w).forEach(([e, t]) => {
24714
+ Object.entries(T).forEach(([e, t]) => {
24690
24715
  let n = A(t.tabs), r = k(t.fields || [], "settings", n);
24691
24716
  Array.isArray(t.fieldSets) && t.fieldSets.forEach((e) => {
24692
24717
  let t = O[e] || {}, n = t.fields || t, i = k(n);
@@ -24707,7 +24732,7 @@ function Yx(e) {
24707
24732
  };
24708
24733
  });
24709
24734
  let oe = {};
24710
- Object.entries(T).forEach(([e, t]) => {
24735
+ Object.entries(ee).forEach(([e, t]) => {
24711
24736
  let n = A(t.tabs), r = k(t.fields || [], "settings", n);
24712
24737
  Array.isArray(t.fieldSets) && t.fieldSets.forEach((e) => {
24713
24738
  let t = O[e] || {}, i = t.fields || t, a = k(i, "settings", n);
@@ -24789,26 +24814,26 @@ function Yx(e) {
24789
24814
  tabs: n
24790
24815
  };
24791
24816
  });
24792
- let j = g?.fields || {};
24817
+ let ue = g?.fields || {};
24793
24818
  Array.isArray(g?.fieldSets) && g?.fieldSets.forEach((e) => {
24794
24819
  let t = O[e] || {}, n = t.fields || t, r = k(n);
24795
24820
  Object.entries(r).forEach(([e, t]) => {
24796
- j[e] = Bx(j[e] || {}, t);
24821
+ ue[e] = Bx(ue[e] || {}, t);
24797
24822
  });
24798
24823
  });
24799
- let ue = g ? {
24824
+ let de = g ? {
24800
24825
  ...g,
24801
- fields: j
24802
- } : null, de = _?.fields || {};
24826
+ fields: ue
24827
+ } : null, j = _?.fields || {};
24803
24828
  Array.isArray(_?.fieldSets) && _?.fieldSets.forEach((e) => {
24804
24829
  let t = O[e] || {}, n = t.fields || t, r = k(n);
24805
24830
  Object.entries(r).forEach(([e, t]) => {
24806
- de[e] = Bx(de[e] || {}, t);
24831
+ j[e] = Bx(j[e] || {}, t);
24807
24832
  });
24808
24833
  });
24809
24834
  let fe = _ ? {
24810
24835
  ..._,
24811
- fields: de
24836
+ fields: j
24812
24837
  } : null;
24813
24838
  return {
24814
24839
  nodes: re,
@@ -24821,7 +24846,7 @@ function Yx(e) {
24821
24846
  fieldSets: O,
24822
24847
  nodeTemplate: m || null,
24823
24848
  treeTemplate: h || null,
24824
- channelTemplate: ue,
24849
+ channelTemplate: de,
24825
24850
  userTemplate: fe
24826
24851
  };
24827
24852
  }
@@ -25084,9 +25109,9 @@ nS.get("/", async (e) => {
25084
25109
  }
25085
25110
  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}`;
25086
25111
  if (!v) throw Error("Storage provider failed to return a valid storage key");
25087
- 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;
25088
- w && (await rS(t, "SELECT id FROM users WHERE id = ?", [w])).length === 0 && (w = null);
25089
- let T = new fx(e.env);
25112
+ 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;
25113
+ T && (await rS(t, "SELECT id FROM users WHERE id = ?", [T])).length === 0 && (T = null);
25114
+ let ee = new fx(e.env);
25090
25115
  if (s) {
25091
25116
  let r = await rS(t, "SELECT storageKeyPrivate, isSystemVariant, parentAssetId FROM assets WHERE id = ?", [s]);
25092
25117
  if (r.length > 0) {
@@ -25103,7 +25128,7 @@ nS.get("/", async (e) => {
25103
25128
  } catch (e) {
25104
25129
  console.warn("Failed to cleanup old asset", e);
25105
25130
  }
25106
- T.purgeAsset(e, t, s);
25131
+ ee.purgeAsset(e, t, s);
25107
25132
  let o = `${x}?v=${Date.now()}`;
25108
25133
  return e.json({
25109
25134
  id: s,
@@ -25127,7 +25152,7 @@ nS.get("/", async (e) => {
25127
25152
  C,
25128
25153
  v,
25129
25154
  x,
25130
- w,
25155
+ T,
25131
25156
  D,
25132
25157
  l,
25133
25158
  d
@@ -25135,7 +25160,7 @@ nS.get("/", async (e) => {
25135
25160
  let te = x;
25136
25161
  if (l) {
25137
25162
  let n = await rS(t, "SELECT cdnUrl, storageKeyPrivate FROM assets WHERE id = ?", [l]);
25138
- n.length > 0 && (te = aS(n[0].cdnUrl, n[0].storageKeyPrivate, y)), T.purgeAsset(e, t, l);
25163
+ n.length > 0 && (te = aS(n[0].cdnUrl, n[0].storageKeyPrivate, y)), ee.purgeAsset(e, t, l);
25139
25164
  }
25140
25165
  return e.json({
25141
25166
  id: E,
@@ -25288,7 +25313,18 @@ function sS() {
25288
25313
  assetUrls: /* @__PURE__ */ new Map()
25289
25314
  };
25290
25315
  }
25291
- function cS(e, t) {
25316
+ function cS(e, t, n = []) {
25317
+ let r = Date.now();
25318
+ if (e && String(e).trim() !== "") {
25319
+ let t = Date.parse(e);
25320
+ !isNaN(t) && t > r && n.push(t);
25321
+ }
25322
+ if (t && String(t).trim() !== "") {
25323
+ let e = Date.parse(t);
25324
+ !isNaN(e) && e > r && n.push(e);
25325
+ }
25326
+ }
25327
+ function lS(e, t) {
25292
25328
  let n = Date.now();
25293
25329
  if (e && String(e).trim() !== "") {
25294
25330
  let t = Date.parse(e);
@@ -25300,37 +25336,37 @@ function cS(e, t) {
25300
25336
  }
25301
25337
  return !0;
25302
25338
  }
25303
- async function lS(e, t, n, r) {
25304
- let i = t.filter((e) => e.componentId === "content-feed" || e.componentId === "article-list");
25305
- await Promise.all(i.map(async (t) => {
25306
- 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];
25307
- n && n !== "all" && (c += " AND id IN (SELECT nodeId FROM node_channels WHERE channelId = ?)", l.push(Number(n) || n));
25308
- let u = i.taxonomies || i.taxonomyFilters || {}, d = Object.keys(u);
25309
- if (d.length > 0) for (let e of d) {
25310
- let t = Array.isArray(u[e]) ? u[e] : [u[e]];
25339
+ async function uS(e, t, n, r, i) {
25340
+ let a = t.filter((e) => e.componentId === "content-feed" || e.componentId === "article-list");
25341
+ await Promise.all(a.map(async (t) => {
25342
+ 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];
25343
+ n && n !== "all" && (l += " AND id IN (SELECT nodeId FROM node_channels WHERE channelId = ?)", u.push(Number(n) || n));
25344
+ let d = a.taxonomies || a.taxonomyFilters || {}, f = Object.keys(d);
25345
+ if (f.length > 0) for (let e of f) {
25346
+ let t = Array.isArray(d[e]) ? d[e] : [d[e]];
25311
25347
  if (t.length > 0) {
25312
25348
  let n = t.map(() => "?").join(",");
25313
- c += ` AND EXISTS (
25349
+ l += ` AND EXISTS (
25314
25350
  SELECT 1 FROM node_terms nt
25315
25351
  INNER JOIN taxonomy_terms tt ON nt.termId = tt.id
25316
25352
  WHERE nt.nodeId = content_nodes.id
25317
25353
  AND tt.taxonomy = ?
25318
25354
  AND tt.key IN (${n})
25319
- )`, l.push(e, ...t);
25355
+ )`, u.push(e, ...t);
25320
25356
  }
25321
25357
  }
25322
- let f = "ORDER BY updatedAt DESC";
25323
- s === "published_desc" || s === "createdAt" ? f = "ORDER BY createdAt DESC" : s === "title_asc" && (f = "ORDER BY LOWER(title) ASC");
25324
- let p = `SELECT id, title, slug, language, dataJson, createdAt, updatedAt ${c} ${f} LIMIT ?`;
25325
- l.push(o);
25358
+ let p = "ORDER BY updatedAt DESC";
25359
+ c === "published_desc" || c === "createdAt" ? p = "ORDER BY createdAt DESC" : c === "title_asc" && (p = "ORDER BY LOWER(title) ASC");
25360
+ let m = `SELECT id, title, slug, language, dataJson, createdAt, updatedAt ${l} ${p} LIMIT ?`;
25361
+ u.push(s);
25326
25362
  try {
25327
- let n = await e.prepare(p).all(...l), i = Array.isArray(n) ? n : n?.results || [];
25328
- t.data.initialItems = i.map((e) => {
25363
+ let n = await e.prepare(m).all(...u), a = Array.isArray(n) ? n : n?.results || [];
25364
+ t.data.initialItems = a.map((e) => {
25329
25365
  let t = {};
25330
25366
  if (e.dataJson) try {
25331
25367
  t = typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson;
25332
25368
  } catch {}
25333
- return cS(t.startShowingAt, t.stopShowingAt) ? {
25369
+ return i && cS(t.startShowingAt, t.stopShowingAt, i), lS(t.startShowingAt, t.stopShowingAt) ? {
25334
25370
  id: e.id,
25335
25371
  title: e.title,
25336
25372
  slug: e.slug,
@@ -25347,23 +25383,23 @@ async function lS(e, t, n, r) {
25347
25383
  }
25348
25384
  }));
25349
25385
  }
25350
- async function uS(e, t, n, r, i, a = !1, o) {
25386
+ async function dS(e, t, n, r, i, a = !1, o, s) {
25351
25387
  if (!t) return { blocks: [] };
25352
- 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 || [];
25353
- if (!c || c.length === 0) return { blocks: [] };
25354
- let l = c.map((e) => e.contentId).filter((e) => e != null);
25355
- if (l.length === 0) return { blocks: [] };
25356
- 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();
25357
- p.forEach((e) => {
25388
+ 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 || [];
25389
+ if (!l || l.length === 0) return { blocks: [] };
25390
+ let u = l.map((e) => e.contentId).filter((e) => e != null);
25391
+ if (u.length === 0) return { blocks: [] };
25392
+ 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();
25393
+ m.forEach((e) => {
25358
25394
  let t = String(e.contentId);
25359
- m.has(t) || m.set(t, []), m.get(t).push(e);
25395
+ h.has(t) || h.set(t, []), h.get(t).push(e);
25360
25396
  });
25361
- for (let t of c) {
25362
- let n = m.get(String(t.contentId)) || [];
25397
+ for (let t of l) {
25398
+ let n = h.get(String(t.contentId)) || [];
25363
25399
  if (n.filter((e) => e.region === r).length === 0) continue;
25364
- let o = /* @__PURE__ */ new Set([r]), s = !0;
25365
- for (; s;) {
25366
- s = !1;
25400
+ let o = /* @__PURE__ */ new Set([r]), c = !0;
25401
+ for (; c;) {
25402
+ c = !1;
25367
25403
  for (let e of n) {
25368
25404
  if (!o.has(e.region)) continue;
25369
25405
  let t = {};
@@ -25374,39 +25410,40 @@ async function uS(e, t, n, r, i, a = !1, o) {
25374
25410
  for (let e of n) {
25375
25411
  if (!e.region || o.has(e.region)) continue;
25376
25412
  let t = e.region;
25377
- (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);
25413
+ (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);
25378
25414
  }
25379
25415
  }
25380
25416
  }
25381
- let c = await Promise.all(n.filter((e) => o.has(e.region)).map(async (t) => {
25417
+ let l = await Promise.all(n.filter((e) => o.has(e.region)).map(async (t) => {
25382
25418
  let n = {};
25383
25419
  try {
25384
25420
  n = (typeof t.dataJson == "string" ? JSON.parse(t.dataJson) : t.dataJson) || {};
25385
25421
  } catch {}
25386
- let o = n.hidden === !0 || n.hidden === 1 || n.hidden === "1" || n.hidden === "true", s = cS(n.startShowingAt, n.stopShowingAt);
25387
- if (!a && (o || !s)) return null;
25388
- 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);
25389
- return d = await ux(e, d), d = fS(d), d.blockId = u, {
25422
+ s && cS(n.startShowingAt, n.stopShowingAt, s);
25423
+ let o = n.hidden === !0 || n.hidden === 1 || n.hidden === "1" || n.hidden === "true", c = lS(n.startShowingAt, n.stopShowingAt);
25424
+ if (!a && (o || !c)) return null;
25425
+ 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);
25426
+ return f = await ux(e, f), f = pS(f), f.blockId = d, {
25390
25427
  region: t.region || r,
25391
25428
  block: {
25392
25429
  instanceId: t.id,
25393
- blockId: u,
25394
- componentId: c,
25395
- data: d
25430
+ blockId: d,
25431
+ componentId: l,
25432
+ data: f
25396
25433
  }
25397
25434
  };
25398
- })), l = {};
25399
- for (let e of c) e && (l[e.region] || (l[e.region] = []), l[e.region].push(e.block));
25400
- if (l[r] && l[r].length > 0) return {
25401
- blocks: l[r],
25402
- subRegions: l,
25435
+ })), u = {};
25436
+ for (let e of l) e && (u[e.region] || (u[e.region] = []), u[e.region].push(e.block));
25437
+ if (u[r] && u[r].length > 0) return {
25438
+ blocks: u[r],
25439
+ subRegions: u,
25403
25440
  inheritedFromId: String(t.contentId),
25404
25441
  inheritedFromTitle: t.title || t.slug
25405
25442
  };
25406
25443
  }
25407
25444
  return { blocks: [] };
25408
25445
  }
25409
- function dS(e, t = {}) {
25446
+ function fS(e, t = {}) {
25410
25447
  let n = {};
25411
25448
  for (let [r, i] of Object.entries(e)) r.endsWith("_meta") || [
25412
25449
  "disabledRegions",
@@ -25422,14 +25459,14 @@ function dS(e, t = {}) {
25422
25459
  ].includes(r) || r.startsWith("_") || (!t[r] || t[r].public !== !1) && (n[r] = i);
25423
25460
  return n;
25424
25461
  }
25425
- function fS(e) {
25426
- if (Array.isArray(e)) return e.map(fS);
25462
+ function pS(e) {
25463
+ if (Array.isArray(e)) return e.map(pS);
25427
25464
  if (!e || typeof e != "object") return e;
25428
25465
  if (typeof e.id == "string" && e.id.startsWith("ast_") && typeof e.url == "string") {
25429
25466
  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 ? {
25430
25467
  ...t,
25431
25468
  ...t.crops?.[r] || {}
25432
- } : t, a = Object.fromEntries(Object.entries(n).filter(([, t]) => t?.id !== e.id).map(([t, n]) => [t, fS({
25469
+ } : t, a = Object.fromEntries(Object.entries(n).filter(([, t]) => t?.id !== e.id).map(([t, n]) => [t, pS({
25433
25470
  ...n,
25434
25471
  title: n?.title ?? e.title ?? "",
25435
25472
  alt: n?.alt ?? e.alt ?? "",
@@ -25443,9 +25480,9 @@ function fS(e) {
25443
25480
  ...Object.keys(a).length > 0 ? { variants: a } : {}
25444
25481
  };
25445
25482
  }
25446
- return Object.fromEntries(Object.entries(e).map(([e, t]) => [e, fS(t)]));
25483
+ return Object.fromEntries(Object.entries(e).map(([e, t]) => [e, pS(t)]));
25447
25484
  }
25448
- async function pS(e, t, n, r) {
25485
+ async function mS(e, t, n, r) {
25449
25486
  if (typeof t == "string") {
25450
25487
  if (!t.includes("#node:") && !t.includes("data-node-id") && !t.includes("#asset:") && !t.includes("data-asset-id")) return t;
25451
25488
  let r = (e, t) => {
@@ -25478,25 +25515,25 @@ async function pS(e, t, n, r) {
25478
25515
  return /href\s*=\s*["'][^"']*["']/i.test(d) ? d = d.replace(/href\s*=\s*["'][^"']*["']/i, `href="${u}"`) : d += ` href="${u}"`, `<a ${d}>`;
25479
25516
  });
25480
25517
  }
25481
- if (Array.isArray(t)) return Promise.all(t.map((t) => pS(e, t, n, r)));
25518
+ if (Array.isArray(t)) return Promise.all(t.map((t) => mS(e, t, n, r)));
25482
25519
  if (t && typeof t == "object") {
25483
25520
  if (typeof t.href == "string" && (t.href.startsWith("#node:") || t.href.startsWith("#asset:"))) return {
25484
25521
  ...t,
25485
- href: await mS(e, t, n, r)
25522
+ href: await hS(e, t, n, r)
25486
25523
  };
25487
- let i = await Promise.all(Object.entries(t).map(async ([t, i]) => [t, await pS(e, i, n, r)]));
25524
+ let i = await Promise.all(Object.entries(t).map(async ([t, i]) => [t, await mS(e, i, n, r)]));
25488
25525
  return Object.fromEntries(i);
25489
25526
  }
25490
25527
  return t;
25491
25528
  }
25492
- async function mS(e, t, n, r) {
25529
+ async function hS(e, t, n, r) {
25493
25530
  let i = t.href.match(/^#node:(.+)$/), a = t.href.match(/^#asset:(.+)$/);
25494
- if (a) return hS(e, a[1], r);
25531
+ if (a) return gS(e, a[1], r);
25495
25532
  if (!i) return t.href;
25496
25533
  let o = i[1];
25497
25534
  return (await e.prepare("SELECT path FROM node_routes WHERE nodeId = ? AND channelId = ? AND isCanonical = 1 LIMIT 1").get(Number(o), n))?.path || "#";
25498
25535
  }
25499
- async function hS(e, t, n) {
25536
+ async function gS(e, t, n) {
25500
25537
  let r = String(t), i = n.assetUrls.get(r);
25501
25538
  if (i) return i;
25502
25539
  let a = (async () => {
@@ -25505,7 +25542,7 @@ async function hS(e, t, n) {
25505
25542
  })();
25506
25543
  return n.assetUrls.set(r, a), a;
25507
25544
  }
25508
- function gS(e) {
25545
+ function _S(e) {
25509
25546
  let t = e.socialImage;
25510
25547
  if (!t || typeof t != "object") return null;
25511
25548
  let n = (e, t) => {
@@ -25536,7 +25573,7 @@ function gS(e) {
25536
25573
  ])
25537
25574
  };
25538
25575
  }
25539
- async function _S(e, t, n, r, i) {
25576
+ async function vS(e, t, n, r, i) {
25540
25577
  let a = {}, o = null;
25541
25578
  if (t) {
25542
25579
  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([
@@ -25574,151 +25611,160 @@ async function _S(e, t, n, r, i) {
25574
25611
  inheritedFields: a
25575
25612
  };
25576
25613
  }
25577
- function vS(e) {
25614
+ function yS(e) {
25578
25615
  let t = Number(e?.env?.CMS_NODE_CACHE_TTL);
25579
25616
  return Number.isFinite(t) && t >= 60 ? Math.floor(t) : 300;
25580
25617
  }
25581
- async function yS(e, t, n, r) {
25618
+ async function bS(e, t, n, r) {
25582
25619
  try {
25583
25620
  await e.set(t, n, r);
25584
25621
  } catch (e) {
25585
25622
  console.warn("[CMS Cache] Failed to write node response to cache:", e);
25586
25623
  }
25587
25624
  }
25588
- async function bS(e) {
25625
+ async function xS(e) {
25589
25626
  try {
25590
- 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 = "";
25591
- l.includes("/node/") ? u = l.substring(l.indexOf("/node/") + 6) : l.endsWith("/node") && (u = "");
25627
+ 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 = "";
25628
+ u.includes("/node/") ? d = u.substring(u.indexOf("/node/") + 6) : u.endsWith("/node") && (d = "");
25592
25629
  try {
25593
- u = decodeURIComponent(u);
25630
+ d = decodeURIComponent(d);
25594
25631
  } catch {}
25595
- u = u.replace(/^\/+|\/+$/g, "");
25596
- 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));
25597
- if (!p) return e.json({ error: `Channel '${f}' not found` }, 404);
25598
- let m = p.status === "disabled" || p.status === "inactive" || p.isEnabled === 0 || p.isEnabled === !1;
25599
- if (!o && m) return e.json({ error: `Channel '${p.key || f}' is currently inactive` }, 404);
25600
- 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);
25601
- if (_?.redirectUrl) return e.json({
25602
- redirect: _.redirectUrl,
25632
+ d = d.replace(/^\/+|\/+$/g, "");
25633
+ 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));
25634
+ if (!m) return e.json({ error: `Channel '${p}' not found` }, 404);
25635
+ let h = m.status === "disabled" || m.status === "inactive" || m.isEnabled === 0 || m.isEnabled === !1;
25636
+ if (!s && h) return e.json({ error: `Channel '${m.key || p}' is currently inactive` }, 404);
25637
+ 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);
25638
+ if (v?.redirectUrl) return e.json({
25639
+ redirect: v.redirectUrl,
25603
25640
  isCanonical: !1
25604
25641
  });
25605
- let v = null, y = _?.treeId || c || null;
25606
- if (_?.nodeId) v = await t.prepare("SELECT * FROM content_nodes WHERE id = ?").get(_.nodeId);
25607
- else if (/^\d+$/.test(u)) v = await t.prepare("SELECT * FROM content_nodes WHERE id = ?").get(Number(u));
25642
+ let y = null, b = v?.treeId || l || null;
25643
+ if (v?.nodeId) y = await t.prepare("SELECT * FROM content_nodes WHERE id = ?").get(v.nodeId);
25644
+ else if (/^\d+$/.test(d)) y = await t.prepare("SELECT * FROM content_nodes WHERE id = ?").get(Number(d));
25608
25645
  else {
25609
- let e = u.split("/").pop() || u;
25610
- v = await t.prepare("SELECT * FROM content_nodes WHERE slug = ?").get(e);
25646
+ let e = d.split("/").pop() || d;
25647
+ y = await t.prepare("SELECT * FROM content_nodes WHERE slug = ?").get(e);
25611
25648
  }
25612
- if (!v) return e.json({ error: `Node '${u}' not found for Channel '${f}'` }, 404);
25613
- let b = null;
25614
- if (s) {
25615
- let e = await t.prepare("SELECT snapshotJson FROM node_revisions WHERE nodeId = ? AND version = ?").get(v.id, Number(s));
25649
+ if (!y) return e.json({ error: `Node '${d}' not found for Channel '${p}'` }, 404);
25650
+ let x = null;
25651
+ if (c) {
25652
+ let e = await t.prepare("SELECT snapshotJson FROM node_revisions WHERE nodeId = ? AND version = ?").get(y.id, Number(c));
25616
25653
  if (e && e.snapshotJson) try {
25617
- b = JSON.parse(e.snapshotJson), b.node && (b.node.title && (v.title = b.node.title), b.node.slug && (v.slug = b.node.slug));
25654
+ x = JSON.parse(e.snapshotJson), x.node && (x.node.title && (y.title = x.node.title), x.node.slug && (y.slug = x.node.slug));
25618
25655
  } catch (e) {
25619
25656
  console.error("[CMS] Failed to parse snapshotJson", e);
25620
25657
  }
25621
25658
  }
25622
- 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] : []);
25623
- !y && x?.treeId && (y = x.treeId), y ||= "main-nav";
25624
- let S = null;
25625
- if (y) {
25626
- let e = await t.prepare("SELECT dataJson FROM trees WHERE id = ? OR key = ? LIMIT 1").get(Number(y) || -1, String(y));
25659
+ 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] : []);
25660
+ !b && S?.treeId && (b = S.treeId), b ||= "main-nav";
25661
+ let C = null;
25662
+ if (b) {
25663
+ let e = await t.prepare("SELECT dataJson FROM trees WHERE id = ? OR key = ? LIMIT 1").get(Number(b) || -1, String(b));
25627
25664
  if (e?.dataJson) try {
25628
25665
  let t = typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson;
25629
- t.defaultLanguage ? S = String(t.defaultLanguage).trim() : t.language && (S = String(t.language).trim());
25666
+ t.defaultLanguage ? C = String(t.defaultLanguage).trim() : t.language && (C = String(t.language).trim());
25630
25667
  } catch {}
25631
25668
  }
25632
- let C = null;
25633
- if (p) {
25634
- if (p.defaultLanguage) C = String(p.defaultLanguage).trim();
25635
- else if (p.dataJson) try {
25636
- let e = typeof p.dataJson == "string" ? JSON.parse(p.dataJson) : p.dataJson;
25637
- e.defaultLanguage ? C = String(e.defaultLanguage).trim() : e.language && (C = String(e.language).trim());
25669
+ let w = null;
25670
+ if (m) {
25671
+ if (m.defaultLanguage) w = String(m.defaultLanguage).trim();
25672
+ else if (m.dataJson) try {
25673
+ let e = typeof m.dataJson == "string" ? JSON.parse(m.dataJson) : m.dataJson;
25674
+ e.defaultLanguage ? w = String(e.defaultLanguage).trim() : e.language && (w = String(e.language).trim());
25638
25675
  } catch {}
25639
25676
  }
25640
- 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);
25641
- if (!o && !D) {
25642
- let t = await te.get(E);
25643
- if (t) return e.header("X-Cache", "HIT"), e.json(t);
25644
- }
25645
- let ne = x?.parentId || null, O = _?.path || (d === "" ? "/" : d), k = {
25646
- id: v.id,
25647
- title: v.title,
25648
- slug: v.slug,
25649
- language: T,
25650
- path: O,
25651
- nodeType: v.contentType,
25652
- createdAt: v.createdAt,
25653
- updatedAt: v.updatedAt
25654
- }, A = dx(e.env?.BUNDLED_DEFINITIONS), re = v.contentType || "node", ie = A.nodes?.[re] || Object.values(A.nodes || {})[0] || {}, ae = { ...ie.fields || {} };
25655
- ie.tabs && Object.values(ie.tabs).forEach((e) => {
25656
- Object.assign(ae, e.fields || {});
25677
+ 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);
25678
+ if (!s && !te) {
25679
+ let t = await ne.get(D);
25680
+ if (t) {
25681
+ e.header("X-Cache", "HIT");
25682
+ let n = O;
25683
+ if (t.meta && t.meta.nextEventTimestamp) {
25684
+ let e = Math.floor((t.meta.nextEventTimestamp - Date.now()) / 1e3);
25685
+ e > 0 && e < n ? n = e : e <= 0 && (n = 0);
25686
+ }
25687
+ 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);
25688
+ }
25689
+ }
25690
+ let k = S?.parentId || null, A = v?.path || (f === "" ? "/" : f), re = {
25691
+ id: y.id,
25692
+ title: y.title,
25693
+ slug: y.slug,
25694
+ language: E,
25695
+ path: A,
25696
+ nodeType: y.contentType,
25697
+ createdAt: y.createdAt,
25698
+ updatedAt: y.updatedAt
25699
+ }, ie = dx(e.env?.BUNDLED_DEFINITIONS), ae = y.contentType || "node", oe = ie.nodes?.[ae] || Object.values(ie.nodes || {})[0] || {}, se = { ...oe.fields || {} };
25700
+ oe.tabs && Object.values(oe.tabs).forEach((e) => {
25701
+ Object.assign(se, e.fields || {});
25657
25702
  });
25658
- let oe = {}, se = null, ce = null, le = !1, j = {}, ue = o && v.draftDataJson || v.dataJson;
25659
- if (b && b.node && b.node.dataJson && (ue = b.node.dataJson), ue) try {
25660
- j = typeof ue == "string" ? JSON.parse(ue) : ue;
25703
+ let ce = {}, le = null, ue = null, de = !1, j = {}, fe = s && y.draftDataJson || y.dataJson;
25704
+ if (x && x.node && x.node.dataJson && (fe = x.node.dataJson), fe) try {
25705
+ j = typeof fe == "string" ? JSON.parse(fe) : fe;
25661
25706
  } catch {}
25662
- 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;
25663
- 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;
25664
- 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);
25665
- let ge = await ux(t, dS(j, ae));
25666
- ge = fS(ge), ge = await pS(t, ge, h, n), delete ge.language;
25667
- let _e = gS(ge);
25668
- 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;
25669
- 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";
25670
- if (!o && (ve || ye || be && !xe)) return e.json({ error: "Node is hidden, offline, or has never been published." }, 404);
25671
- let Se = [];
25672
- if (x?.treeNodeId) {
25673
- 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;
25674
- Se = n.map((e) => {
25675
- let t = {}, n = o && e.draftDataJson || e.dataJson;
25707
+ 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);
25708
+ 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;
25709
+ 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);
25710
+ let ve = await ux(t, fS(j, se));
25711
+ ve = pS(ve), ve = await mS(t, ve, g, n), delete ve.language;
25712
+ let ye = _S(ve);
25713
+ 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;
25714
+ 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";
25715
+ if (!s && (be || xe || Se && !Ce)) return e.json({ error: "Node is hidden, offline, or has never been published." }, 404);
25716
+ let we = [];
25717
+ if (S?.treeNodeId) {
25718
+ 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;
25719
+ we = n.map((e) => {
25720
+ let t = {}, n = s && e.draftDataJson || e.dataJson;
25676
25721
  if (!n) return null;
25677
25722
  try {
25678
25723
  t = (typeof n == "string" ? JSON.parse(n) : n) || {};
25679
25724
  } catch {}
25680
- 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, "");
25681
- return !o && (r || !a) ? null : {
25725
+ 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, "");
25726
+ return cS(t.startShowingAt, t.stopShowingAt, r), !s && (i || !o) ? null : {
25682
25727
  treeNodeId: e.treeNodeId,
25683
25728
  id: e.id,
25684
25729
  title: e.title,
25685
- slug: s,
25686
- language: e.language?.trim() || T || null,
25687
- path: `${i}/${s}`.replace(/\/+/g, "/"),
25730
+ slug: c,
25731
+ language: e.language?.trim() || E || null,
25732
+ path: `${a}/${c}`.replace(/\/+/g, "/"),
25688
25733
  nodeType: e.nodeType
25689
25734
  };
25690
25735
  }).filter(Boolean);
25691
25736
  }
25692
- k.children = Se;
25693
- let Ce = [];
25694
- if (b && b.blocks && Array.isArray(b.blocks)) Ce = b.blocks.map((e) => ({
25737
+ re.children = we;
25738
+ let Te = [];
25739
+ if (x && x.blocks && Array.isArray(x.blocks)) Te = x.blocks.map((e) => ({
25695
25740
  ...e,
25696
25741
  isDraft: 1
25697
25742
  }));
25698
25743
  else {
25699
- let e = +!!o, n = await t.prepare("SELECT * FROM content_blocks WHERE contentId = ? AND isDraft = ? ORDER BY sortOrder ASC").all(v.id, e);
25700
- Ce = Array.isArray(n) ? n : n?.results || [];
25744
+ let e = +!!s, n = await t.prepare("SELECT * FROM content_blocks WHERE contentId = ? AND isDraft = ? ORDER BY sortOrder ASC").all(y.id, e);
25745
+ Te = Array.isArray(n) ? n : n?.results || [];
25701
25746
  }
25702
- let we = {}, Te = {}, Ee = await Promise.all(Ce.map(async (e) => {
25703
- let r = e.region || "main", i = {};
25747
+ let Ee = {}, De = {}, Oe = await Promise.all(Te.map(async (e) => {
25748
+ let i = e.region || "main", a = {};
25704
25749
  try {
25705
- i = (typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson) || {};
25750
+ a = (typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson) || {};
25706
25751
  } catch {}
25707
- let a = i.hidden === !0 || i.hidden === 1 || i.hidden === "1" || i.hidden === "true", s = cS(i.startShowingAt, i.stopShowingAt);
25708
- if (!o && (a || !s)) return null;
25709
- 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);
25710
- return d = await ux(t, d), d = fS(d), d = await pS(t, d, h, n), d.blockId = u, {
25711
- region: r,
25752
+ cS(a.startShowingAt, a.stopShowingAt, r);
25753
+ let o = a.hidden === !0 || a.hidden === 1 || a.hidden === "1" || a.hidden === "true", c = lS(a.startShowingAt, a.stopShowingAt);
25754
+ if (!s && (o || !c)) return null;
25755
+ 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);
25756
+ return f = await ux(t, f), f = pS(f), f = await mS(t, f, g, n), f.blockId = d, {
25757
+ region: i,
25712
25758
  block: {
25713
25759
  instanceId: e.id,
25714
- blockId: u,
25715
- componentId: c,
25716
- data: d
25760
+ blockId: d,
25761
+ componentId: l,
25762
+ data: f
25717
25763
  }
25718
25764
  };
25719
25765
  }));
25720
- for (let e of Ee) e && (we[e.region] || (we[e.region] = [], Te[e.region] = { isInherited: !1 }), we[e.region].push(e.block));
25721
- let De = {
25766
+ for (let e of Oe) e && (Ee[e.region] || (Ee[e.region] = [], De[e.region] = { isInherited: !1 }), Ee[e.region].push(e.block));
25767
+ let ke = {
25722
25768
  header: {
25723
25769
  label: "Header",
25724
25770
  inherit: "parent"
@@ -25727,33 +25773,43 @@ async function bS(e) {
25727
25773
  label: "Footer",
25728
25774
  inherit: "parent"
25729
25775
  },
25730
- ...(he ? A.nodeLayouts?.[he] || A.layouts?.[he] : null)?.regions || { main: { label: "Content" } }
25776
+ ...(_e ? ie.nodeLayouts?.[_e] || ie.layouts?.[_e] : null)?.regions || { main: { label: "Content" } }
25731
25777
  };
25732
- for (let [e, r] of Object.entries(De)) {
25733
- let i = we[e] && we[e].length > 0, a = !!oe[e];
25734
- 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) {
25735
- let r = await uS(t, ne, String(y), e, A, o, n);
25736
- if (r.blocks.length > 0 && (we[e] = r.blocks, Te[e] = {
25778
+ for (let [e, i] of Object.entries(ke)) {
25779
+ let a = Ee[e] && Ee[e].length > 0, o = !!ce[e];
25780
+ 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) {
25781
+ let i = await dS(t, k, String(b), e, ie, s, n, r);
25782
+ if (i.blocks.length > 0 && (Ee[e] = i.blocks, De[e] = {
25737
25783
  isInherited: !0,
25738
- inheritedFromId: r.inheritedFromId,
25739
- inheritedFromTitle: r.inheritedFromTitle
25740
- }, r.subRegions)) for (let [t, n] of Object.entries(r.subRegions)) t !== e && (we[t] = n, Te[t] = {
25784
+ inheritedFromId: i.inheritedFromId,
25785
+ inheritedFromTitle: i.inheritedFromTitle
25786
+ }, i.subRegions)) for (let [t, n] of Object.entries(i.subRegions)) t !== e && (Ee[t] = n, De[t] = {
25741
25787
  isInherited: !0,
25742
- inheritedFromId: r.inheritedFromId,
25743
- inheritedFromTitle: r.inheritedFromTitle
25788
+ inheritedFromId: i.inheritedFromId,
25789
+ inheritedFromTitle: i.inheritedFromTitle
25744
25790
  });
25745
25791
  }
25746
25792
  }
25747
- await Promise.all(Object.keys(we).map((e) => lS(t, we[e], h, T)));
25748
- let Oe = {
25749
- channelId: h || g,
25750
- treeId: y,
25751
- language: T,
25752
- node: k,
25753
- content: we,
25754
- regionMeta: Te
25793
+ await Promise.all(Object.keys(Ee).map((e) => uS(t, Ee[e], g, E, r)));
25794
+ let Ae = O, je = null;
25795
+ if (r.length > 0) {
25796
+ je = Math.min(...r);
25797
+ let e = Math.floor((je - Date.now()) / 1e3);
25798
+ e > 0 && e < O && (Ae = e);
25799
+ }
25800
+ let Me = {
25801
+ channelId: g || _,
25802
+ treeId: b,
25803
+ language: E,
25804
+ meta: {
25805
+ cacheTtl: Ae,
25806
+ nextEventTimestamp: je
25807
+ },
25808
+ node: re,
25809
+ content: Ee,
25810
+ regionMeta: De
25755
25811
  };
25756
- return !o && !D && (e.header("X-Cache", "MISS"), await yS(te, E, Oe, vS(e))), e.json(Oe, 200);
25812
+ 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);
25757
25813
  } catch (t) {
25758
25814
  return console.error("[CMS Public API] Error fetching node by path:", t), e.json({
25759
25815
  error: "Failed to fetch JSON payload",
@@ -25761,20 +25817,24 @@ async function bS(e) {
25761
25817
  }, 500);
25762
25818
  }
25763
25819
  }
25764
- var xS = X({
25820
+ var SS = X({
25765
25821
  channelId: J().optional().openapi({ description: "The ID or key of the channel" }),
25766
25822
  channel: J().optional().openapi({ description: "Legacy alias for channelId" }),
25767
25823
  lang: J().optional().openapi({ description: "Requested language code" }),
25768
25824
  preview: lv(["true", "false"]).optional().openapi({ description: "Request unpublished draft data" }),
25769
25825
  revisionId: J().optional().openapi({ description: "Historical revision version to load" }),
25770
25826
  treeId: J().optional().openapi({ description: "The ID of the tree to resolve paths against" })
25771
- }), SS = X({
25827
+ }), CS = X({
25772
25828
  error: J(),
25773
25829
  details: J().optional()
25774
- }).openapi("ErrorResponse"), CS = X({
25830
+ }).openapi("ErrorResponse"), wS = X({
25775
25831
  channelId: G_([J(), c_()]),
25776
25832
  treeId: J().nullable(),
25777
25833
  language: J().nullable(),
25834
+ meta: X({
25835
+ cacheTtl: c_(),
25836
+ nextEventTimestamp: c_().nullable()
25837
+ }).optional(),
25778
25838
  node: tv(k_()),
25779
25839
  content: tv(z_(k_())),
25780
25840
  regionMeta: tv(X({
@@ -25782,7 +25842,7 @@ var xS = X({
25782
25842
  inheritedFromId: J().optional(),
25783
25843
  inheritedFromTitle: J().optional()
25784
25844
  }))
25785
- }).openapi("NodeResponse"), wS = eb({
25845
+ }).openapi("NodeResponse"), TS = eb({
25786
25846
  method: "get",
25787
25847
  path: "/{path}",
25788
25848
  summary: "Fetch CMS Node Content",
@@ -25790,26 +25850,26 @@ var xS = X({
25790
25850
  tags: ["Public Node API"],
25791
25851
  request: {
25792
25852
  params: X({ path: J().optional().openapi({ description: "The full URL path or slug of the requested node" }) }),
25793
- query: xS
25853
+ query: SS
25794
25854
  },
25795
25855
  responses: {
25796
25856
  200: {
25797
25857
  description: "Fully hydrated CMS Node",
25798
- content: { "application/json": { schema: CS } }
25858
+ content: { "application/json": { schema: wS } }
25799
25859
  },
25800
25860
  404: {
25801
25861
  description: "Node or Channel not found",
25802
- content: { "application/json": { schema: SS } }
25862
+ content: { "application/json": { schema: CS } }
25803
25863
  },
25804
25864
  500: {
25805
25865
  description: "Server error during hydration",
25806
- content: { "application/json": { schema: SS } }
25866
+ content: { "application/json": { schema: CS } }
25807
25867
  }
25808
25868
  }
25809
25869
  });
25810
- oS.openapi(wS, bS), oS.get("*", bS);
25811
- var TS = new $y();
25812
- function ES(e, t) {
25870
+ oS.openapi(TS, xS), oS.get("*", xS);
25871
+ var ES = new $y();
25872
+ function DS(e, t) {
25813
25873
  let n = /* @__PURE__ */ new Date();
25814
25874
  if (e && String(e).trim() !== "") {
25815
25875
  let t = new Date(e);
@@ -25821,22 +25881,22 @@ function ES(e, t) {
25821
25881
  }
25822
25882
  return !0;
25823
25883
  }
25824
- async function DS(e, t, n, r) {
25884
+ async function OS(e, t, n, r) {
25825
25885
  try {
25826
25886
  await e.set(t, n, r);
25827
25887
  } catch (e) {
25828
25888
  console.warn("[CMS Cache] Failed to write tree response to cache:", e);
25829
25889
  }
25830
25890
  }
25831
- var OS = X({ treeParam: J().openapi({ description: "The ID or key of the requested tree (e.g., \"main-nav\")" }) }), kS = X({
25891
+ var kS = X({ treeParam: J().openapi({ description: "The ID or key of the requested tree (e.g., \"main-nav\")" }) }), AS = X({
25832
25892
  channelId: J().optional().openapi({ description: "Channel ID to resolve context-aware routing" }),
25833
25893
  channel: J().optional().openapi({ description: "Legacy alias for channelId" }),
25834
25894
  lang: J().optional().openapi({ description: "Requested language code for tree nodes" }),
25835
25895
  preview: lv(["true", "false"]).optional().openapi({ description: "Set to true to retrieve unpublished draft data" })
25836
- }), AS = X({
25896
+ }), jS = X({
25837
25897
  error: J(),
25838
25898
  details: J().optional()
25839
- }).openapi("ErrorResponse"), jS = qv(() => X({
25899
+ }).openapi("ErrorResponse"), MS = qv(() => X({
25840
25900
  id: G_([J(), c_()]),
25841
25901
  treeNodeId: G_([J(), c_()]),
25842
25902
  parentId: G_([J(), c_()]).nullable(),
@@ -25849,40 +25909,40 @@ var OS = X({ treeParam: J().openapi({ description: "The ID or key of the request
25849
25909
  summary: J(),
25850
25910
  url: J().optional(),
25851
25911
  target: J().optional(),
25852
- children: z_(jS).optional()
25853
- })).openapi("TreeItem"), MS = X({
25912
+ children: z_(MS).optional()
25913
+ })).openapi("TreeItem"), NS = X({
25854
25914
  treeId: G_([c_(), J()]),
25855
25915
  key: J(),
25856
25916
  channelId: J(),
25857
25917
  language: J().nullable(),
25858
25918
  label: J(),
25859
- items: z_(jS)
25860
- }).catchall(k_()).openapi("TreeResponse"), NS = eb({
25919
+ items: z_(MS)
25920
+ }).catchall(k_()).openapi("TreeResponse"), PS = eb({
25861
25921
  method: "get",
25862
25922
  path: "/{treeParam}",
25863
25923
  summary: "Fetch CMS Navigation Tree",
25864
25924
  description: "Retrieves a fully hydrated, recursive navigation tree structure. Uses $O(1)$ pre-computed routing table paths.",
25865
25925
  tags: ["Public Tree API"],
25866
25926
  request: {
25867
- params: OS,
25868
- query: kS
25927
+ params: kS,
25928
+ query: AS
25869
25929
  },
25870
25930
  responses: {
25871
25931
  200: {
25872
25932
  description: "Fully hydrated CMS Tree payload",
25873
- content: { "application/json": { schema: MS } }
25933
+ content: { "application/json": { schema: NS } }
25874
25934
  },
25875
25935
  404: {
25876
25936
  description: "Tree or Channel not found / inactive",
25877
- content: { "application/json": { schema: AS } }
25937
+ content: { "application/json": { schema: jS } }
25878
25938
  },
25879
25939
  500: {
25880
25940
  description: "Server error during hydration",
25881
- content: { "application/json": { schema: AS } }
25941
+ content: { "application/json": { schema: jS } }
25882
25942
  }
25883
25943
  }
25884
25944
  });
25885
- TS.openapi(NS, async (e) => {
25945
+ ES.openapi(PS, async (e) => {
25886
25946
  try {
25887
25947
  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;
25888
25948
  if (i && i !== "default" && i !== "all") {
@@ -25945,7 +26005,7 @@ TS.openapi(NS, async (e) => {
25945
26005
  return (y.get(n) || []).map((e) => {
25946
26006
  let n = b.get(String(e.id)) || {}, r = {};
25947
26007
  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);
25948
- 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 = {
26008
+ 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 = {
25949
26009
  id: e.id,
25950
26010
  treeNodeId: e.id,
25951
26011
  parentId: e.parentId || null,
@@ -25971,7 +26031,7 @@ TS.openapi(NS, async (e) => {
25971
26031
  ..._,
25972
26032
  items: x(null)
25973
26033
  };
25974
- return !o && !h && (e.header("X-Cache", "MISS"), await DS(p, m, S, 300)), e.json(S, 200);
26034
+ return !o && !h && (e.header("X-Cache", "MISS"), await OS(p, m, S, 300)), e.json(S, 200);
25975
26035
  } catch (t) {
25976
26036
  return console.error("[CMS Public Tree API] Error:", t), e.json({
25977
26037
  error: "Failed to fetch public tree",
@@ -25979,19 +26039,19 @@ TS.openapi(NS, async (e) => {
25979
26039
  }, 500);
25980
26040
  }
25981
26041
  });
25982
- var PS = new $y();
25983
- function FS(e) {
26042
+ var FS = new $y();
26043
+ function IS(e) {
25984
26044
  let t = Number(e?.env?.CMS_CHANNEL_CACHE_TTL);
25985
26045
  return Number.isFinite(t) && t >= 60 ? Math.floor(t) : 300;
25986
26046
  }
25987
- async function IS(e, t, n, r) {
26047
+ async function LS(e, t, n, r) {
25988
26048
  try {
25989
26049
  await e.set(t, n, r);
25990
26050
  } catch (e) {
25991
26051
  console.warn("[CMS Cache] Failed to write channel response to cache:", e);
25992
26052
  }
25993
26053
  }
25994
- function LS(e, t) {
26054
+ function RS(e, t) {
25995
26055
  let n = {}, r = (e) => {
25996
26056
  if (!e || typeof e != "string") return;
25997
26057
  let n = t?.fieldSets?.[e] || t?.fieldsets?.[e] || t?.definitions?.[e] || t?.channels?.[e] || t?.[e];
@@ -26002,7 +26062,7 @@ function LS(e, t) {
26002
26062
  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);
26003
26063
  return n;
26004
26064
  }
26005
- function RS(e, t = {}) {
26065
+ function zS(e, t = {}) {
26006
26066
  let n = {}, r = Object.keys(t).length > 0;
26007
26067
  for (let [i, a] of Object.entries(e)) {
26008
26068
  if (i.endsWith("_meta") || [
@@ -26021,14 +26081,14 @@ function RS(e, t = {}) {
26021
26081
  }
26022
26082
  return n;
26023
26083
  }
26024
- function zS(e) {
26025
- if (Array.isArray(e)) return e.map(zS);
26084
+ function BS(e) {
26085
+ if (Array.isArray(e)) return e.map(BS);
26026
26086
  if (!e || typeof e != "object") return e;
26027
26087
  if (typeof e.id == "string" && e.id.startsWith("ast_") && typeof e.url == "string") {
26028
26088
  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 ? {
26029
26089
  ...t,
26030
26090
  ...t.crops?.[r] || {}
26031
- } : t, a = Object.fromEntries(Object.entries(n).filter(([, t]) => t?.id !== e.id).map(([t, n]) => [t, zS({
26091
+ } : t, a = Object.fromEntries(Object.entries(n).filter(([, t]) => t?.id !== e.id).map(([t, n]) => [t, BS({
26032
26092
  ...n,
26033
26093
  title: n?.title ?? e.title ?? "",
26034
26094
  alt: n?.alt ?? e.alt ?? "",
@@ -26042,9 +26102,9 @@ function zS(e) {
26042
26102
  ...Object.keys(a).length > 0 ? { variants: a } : {}
26043
26103
  };
26044
26104
  }
26045
- return Object.fromEntries(Object.entries(e).map(([e, t]) => [e, zS(t)]));
26105
+ return Object.fromEntries(Object.entries(e).map(([e, t]) => [e, BS(t)]));
26046
26106
  }
26047
- async function BS(e, t, n) {
26107
+ async function VS(e, t, n) {
26048
26108
  if (typeof t == "string") {
26049
26109
  if (!t.includes("#node:") && !t.includes("data-node-id") && !t.includes("#asset:") && !t.includes("data-asset-id")) return t;
26050
26110
  let r = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Set();
@@ -26077,45 +26137,45 @@ async function BS(e, t, n) {
26077
26137
  return /href\s*=\s*["'][^"']*["']/i.test(d) ? d = d.replace(/href\s*=\s*["'][^"']*["']/i, `href="${u}"`) : d += ` href="${u}"`, `<a ${d}>`;
26078
26138
  });
26079
26139
  }
26080
- if (Array.isArray(t)) return Promise.all(t.map((t) => BS(e, t, n)));
26140
+ if (Array.isArray(t)) return Promise.all(t.map((t) => VS(e, t, n)));
26081
26141
  if (t && typeof t == "object") {
26082
- let r = await Promise.all(Object.entries(t).map(async ([t, r]) => [t, await BS(e, r, n)]));
26142
+ let r = await Promise.all(Object.entries(t).map(async ([t, r]) => [t, await VS(e, r, n)]));
26083
26143
  return Object.fromEntries(r);
26084
26144
  }
26085
26145
  return t;
26086
26146
  }
26087
- 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({
26147
+ 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({
26088
26148
  error: J(),
26089
26149
  details: J().optional()
26090
- }).openapi("ErrorResponse"), WS = X({
26150
+ }).openapi("ErrorResponse"), GS = X({
26091
26151
  id: G_([c_(), J()]),
26092
26152
  key: J()
26093
- }).catchall(k_()).openapi("ChannelResponse"), GS = eb({
26153
+ }).catchall(k_()).openapi("ChannelResponse"), KS = eb({
26094
26154
  method: "get",
26095
26155
  path: "/{channelParam}",
26096
26156
  summary: "Fetch CMS Channel Settings",
26097
26157
  description: "Retrieves the fully hydrated, public-facing settings and payload for a specific CMS channel.",
26098
26158
  tags: ["Public Channel API"],
26099
26159
  request: {
26100
- params: VS,
26101
- query: HS
26160
+ params: HS,
26161
+ query: US
26102
26162
  },
26103
26163
  responses: {
26104
26164
  200: {
26105
26165
  description: "Fully hydrated CMS Channel payload",
26106
- content: { "application/json": { schema: WS } }
26166
+ content: { "application/json": { schema: GS } }
26107
26167
  },
26108
26168
  404: {
26109
26169
  description: "Channel not found or inactive",
26110
- content: { "application/json": { schema: US } }
26170
+ content: { "application/json": { schema: WS } }
26111
26171
  },
26112
26172
  500: {
26113
26173
  description: "Server error during hydration",
26114
- content: { "application/json": { schema: US } }
26174
+ content: { "application/json": { schema: WS } }
26115
26175
  }
26116
26176
  }
26117
26177
  });
26118
- PS.openapi(GS, async (e) => {
26178
+ FS.openapi(KS, async (e) => {
26119
26179
  try {
26120
26180
  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);
26121
26181
  if (!i && !a) {
@@ -26126,23 +26186,23 @@ PS.openapi(GS, async (e) => {
26126
26186
  if (!c) return e.json({ error: `Channel '${n}' not found` }, 404);
26127
26187
  let l = c.status === "disabled" || c.status === "inactive" || c.isEnabled === 0 || c.isEnabled === !1;
26128
26188
  if (!i && l) return e.json({ error: `Channel '${c.key || n}' is currently inactive` }, 404);
26129
- 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;
26189
+ 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;
26130
26190
  if (g) try {
26131
26191
  h = typeof g == "string" ? JSON.parse(g) : g;
26132
26192
  } catch (e) {
26133
26193
  console.warn("[CMS Public Channel API] Failed to parse channel dataJson:", e);
26134
26194
  }
26135
- let _ = RS({
26195
+ let _ = zS({
26136
26196
  ...h,
26137
26197
  ...c
26138
26198
  }, m);
26139
- _ = await ux(t, _), _ = zS(_), _ = await BS(t, _, u);
26199
+ _ = await ux(t, _), _ = BS(_), _ = await VS(t, _, u);
26140
26200
  let v = {
26141
26201
  id: c.id,
26142
26202
  key: c.key,
26143
26203
  ..._
26144
26204
  };
26145
- return !i && !a && (e.header("X-Cache", "MISS"), await IS(s, o, v, FS(e))), e.json(v, 200);
26205
+ return !i && !a && (e.header("X-Cache", "MISS"), await LS(s, o, v, IS(e))), e.json(v, 200);
26146
26206
  } catch (t) {
26147
26207
  return console.error("[CMS Public Channel API] Error:", t), e.json({
26148
26208
  error: "Failed to fetch public channel",
@@ -26150,8 +26210,8 @@ PS.openapi(GS, async (e) => {
26150
26210
  }, 500);
26151
26211
  }
26152
26212
  });
26153
- var KS = new $y();
26154
- function qS(e, t) {
26213
+ var qS = new $y();
26214
+ function JS(e, t) {
26155
26215
  if (t === "webp") return "image/webp";
26156
26216
  if (t === "avif") return "image/avif";
26157
26217
  if (t === "jpeg" || t === "jpg") return "image/jpeg";
@@ -26160,7 +26220,7 @@ function qS(e, t) {
26160
26220
  let n = e.toLowerCase();
26161
26221
  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";
26162
26222
  }
26163
- var JS = eb({
26223
+ var YS = eb({
26164
26224
  method: "get",
26165
26225
  path: "/*",
26166
26226
  summary: "Serve & Optimize Media Assets",
@@ -26217,12 +26277,15 @@ var JS = eb({
26217
26277
  }
26218
26278
  }
26219
26279
  });
26220
- KS.openapi(JS, async (e) => {
26280
+ qS.openapi(YS, async (e) => {
26221
26281
  try {
26222
26282
  let t = e.req.path.replace(/^\/media\//, "").replace(/^\//, "");
26223
26283
  if (!t) return e.text("Asset key missing", 400);
26224
26284
  let { w: n, h: r, q: i, f: a } = e.req.valid("query"), o = !!(n || r || i || a), s = e.req.header("Accept") || "", c = "";
26225
- 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"));
26285
+ if (o) {
26286
+ let e = !a || a === "auto";
26287
+ 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");
26288
+ }
26226
26289
  let l = typeof caches < "u" && caches?.default ? caches.default : null, u = e.req.url;
26227
26290
  if (o && c && !a) {
26228
26291
  let e = new URL(u);
@@ -26237,7 +26300,7 @@ KS.openapi(JS, async (e) => {
26237
26300
  if (!m) return e.text(`Asset not found: ${t}`, 404);
26238
26301
  if (!o) {
26239
26302
  let n = e.body(m, 200, {
26240
- "Content-Type": qS(t),
26303
+ "Content-Type": JS(t),
26241
26304
  "Cache-Control": "public, max-age=31536000, immutable"
26242
26305
  });
26243
26306
  return l && d && e.executionCtx?.waitUntil && e.executionCtx.waitUntil(l.put(d, n.clone())), n;
@@ -26251,7 +26314,7 @@ KS.openapi(JS, async (e) => {
26251
26314
  key: t,
26252
26315
  env: e.env,
26253
26316
  req: e.req.raw
26254
- }), _ = qS(t, c), v = e.body(g, 200, {
26317
+ }), _ = JS(t, c), v = e.body(g, 200, {
26255
26318
  "Content-Type": _,
26256
26319
  "Cache-Control": "public, max-age=31536000, immutable"
26257
26320
  });
@@ -26260,8 +26323,8 @@ KS.openapi(JS, async (e) => {
26260
26323
  return console.error("❌ [Public Assets Error]:", t), e.text("Internal Server Error", 500);
26261
26324
  }
26262
26325
  });
26263
- var YS = new $y();
26264
- function XS(e, t) {
26326
+ var XS = new $y();
26327
+ function ZS(e, t) {
26265
26328
  let n = /* @__PURE__ */ new Date();
26266
26329
  if (e && String(e).trim() !== "") {
26267
26330
  let t = new Date(e);
@@ -26273,31 +26336,31 @@ function XS(e, t) {
26273
26336
  }
26274
26337
  return !0;
26275
26338
  }
26276
- var ZS = X({
26339
+ var QS = X({
26277
26340
  channelId: J().optional().openapi({ description: "Optional channel ID/key to filter and resolve root paths for" }),
26278
26341
  channel: J().optional().openapi({ description: "Legacy alias for channelId" })
26279
- }), QS = z_(J()).openapi("PathsResponse"), $S = X({
26342
+ }), $S = z_(J()).openapi("PathsResponse"), eC = X({
26280
26343
  error: J(),
26281
26344
  details: J().optional()
26282
- }).openapi("ErrorResponse"), eC = eb({
26345
+ }).openapi("ErrorResponse"), tC = eb({
26283
26346
  method: "get",
26284
26347
  path: "/",
26285
26348
  summary: "Fetch All Public Paths",
26286
26349
  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.",
26287
26350
  tags: ["Public Paths API"],
26288
- request: { query: ZS },
26351
+ request: { query: QS },
26289
26352
  responses: {
26290
26353
  200: {
26291
26354
  description: "Array of valid public URL paths",
26292
- content: { "application/json": { schema: QS } }
26355
+ content: { "application/json": { schema: $S } }
26293
26356
  },
26294
26357
  500: {
26295
26358
  description: "Server error fetching paths",
26296
- content: { "application/json": { schema: $S } }
26359
+ content: { "application/json": { schema: eC } }
26297
26360
  }
26298
26361
  }
26299
26362
  });
26300
- YS.openapi(eC, async (e) => {
26363
+ XS.openapi(tC, async (e) => {
26301
26364
  try {
26302
26365
  let t = e.get("db"), n = e.req.valid("query"), r = n.channelId || n.channel, i = "", a = [];
26303
26366
  if (r && r !== "all") {
@@ -26322,7 +26385,7 @@ YS.openapi(eC, async (e) => {
26322
26385
  let t = !0;
26323
26386
  if (e.dataJson) try {
26324
26387
  let n = typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson;
26325
- t = XS(n?.startShowingAt, n?.stopShowingAt);
26388
+ t = ZS(n?.startShowingAt, n?.stopShowingAt);
26326
26389
  } catch {}
26327
26390
  t && c.push(e.path);
26328
26391
  }
@@ -26332,12 +26395,12 @@ YS.openapi(eC, async (e) => {
26332
26395
  return console.error("[CMS Paths API] Error:", t), e.json({ error: "Failed to fetch paths" }, 500);
26333
26396
  }
26334
26397
  });
26335
- var tC = new $y();
26336
- function nC(e) {
26398
+ var nC = new $y();
26399
+ function rC(e) {
26337
26400
  let t = (e || "").trim().toLowerCase(), n = dx()?.taxonomies || {};
26338
26401
  return n[t] ? t : n[`${t}s`] ? `${t}s` : t.endsWith("s") && n[t.slice(0, -1)] ? t.slice(0, -1) : t;
26339
26402
  }
26340
- var rC = X({
26403
+ var iC = X({
26341
26404
  id: c_(),
26342
26405
  taxonomy: J(),
26343
26406
  key: J(),
@@ -26347,14 +26410,14 @@ var rC = X({
26347
26410
  data: tv(k_()),
26348
26411
  createdAt: J(),
26349
26412
  updatedAt: J()
26350
- }), iC = X({
26413
+ }), aC = X({
26351
26414
  taxonomy: J(),
26352
- items: z_(rC),
26415
+ items: z_(iC),
26353
26416
  total: c_()
26354
- }).openapi("TaxonomyResponse"), aC = X({
26417
+ }).openapi("TaxonomyResponse"), oC = X({
26355
26418
  error: J(),
26356
26419
  details: J().optional()
26357
- }).openapi("ErrorResponse"), oC = eb({
26420
+ }).openapi("ErrorResponse"), sC = eb({
26358
26421
  method: "get",
26359
26422
  path: "/{taxonomy}",
26360
26423
  summary: "Fetch Public Taxonomy Terms",
@@ -26364,17 +26427,17 @@ var rC = X({
26364
26427
  responses: {
26365
26428
  200: {
26366
26429
  description: "List of taxonomy terms",
26367
- content: { "application/json": { schema: iC } }
26430
+ content: { "application/json": { schema: aC } }
26368
26431
  },
26369
26432
  500: {
26370
26433
  description: "Server error",
26371
- content: { "application/json": { schema: aC } }
26434
+ content: { "application/json": { schema: oC } }
26372
26435
  }
26373
26436
  }
26374
26437
  });
26375
- tC.openapi(oC, async (e) => {
26438
+ nC.openapi(sC, async (e) => {
26376
26439
  try {
26377
- 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";
26440
+ 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";
26378
26441
  if (!o) {
26379
26442
  let t = await n.get(a);
26380
26443
  if (t) return e.header("X-Cache", "HIT"), e.json(t);
@@ -26408,7 +26471,7 @@ tC.openapi(oC, async (e) => {
26408
26471
  return console.error("[Public Taxonomy API] Error fetching terms:", t), e.json({ error: "Failed to fetch taxonomy terms" }, 500);
26409
26472
  }
26410
26473
  });
26411
- var $ = new $y(), sC = !1;
26474
+ var $ = new $y(), cC = !1;
26412
26475
  $.use("*", t()), $.use("/media/*", t({
26413
26476
  origin: "*",
26414
26477
  allowMethods: [
@@ -26429,13 +26492,13 @@ $.use("*", t()), $.use("/media/*", t({
26429
26492
  let n = new URL(e.req.url), r = (e.req.header("host") || n.hostname).split(":")[0];
26430
26493
  e.set("currentDomain", r);
26431
26494
  let i = wb(e);
26432
- if (e.set("db", i), !sC) try {
26433
- await Mb(i), sC = !0;
26495
+ if (e.set("db", i), !cC) try {
26496
+ await Mb(i), cC = !0;
26434
26497
  } catch (e) {
26435
26498
  console.error("❌ [CMS Server] Failed to initialize system tables on cold start:", e);
26436
26499
  }
26437
26500
  await t();
26438
- }), $.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", {
26501
+ }), $.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", {
26439
26502
  openapi: "3.0.0",
26440
26503
  info: {
26441
26504
  title: "KAMA Engine Public API",