@brightsideoy/kama 1.0.0-alpha.4 → 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);
@@ -23501,22 +23513,22 @@ mx.get("/", async (e) => {
23501
23513
  ...m,
23502
23514
  f,
23503
23515
  p
23504
- ], C = await t.prepare(x).all(...S), ee = Array.isArray(C) ? C : C?.results || [], w = ee.map((e) => e.id), T = {}, E = {};
23505
- if (w.length > 0) {
23506
- 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(`
23507
23519
  SELECT nc.nodeId, c.label FROM node_channels nc JOIN channels c ON nc.channelId = c.id WHERE nc.nodeId IN (${e})
23508
- `).all(...w);
23520
+ `).all(...T);
23509
23521
  (Array.isArray(n) ? n : n?.results || []).forEach((e) => {
23510
- 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);
23511
23523
  });
23512
23524
  let r = await t.prepare(`
23513
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})
23514
- `).all(...w);
23526
+ `).all(...T);
23515
23527
  (Array.isArray(r) ? r : r?.results || []).forEach((e) => {
23516
23528
  E[e.nodeId] || (E[e.nodeId] = []), E[e.nodeId].includes(e.label) || E[e.nodeId].push(e.label);
23517
23529
  });
23518
23530
  }
23519
- let D = await Promise.all(ee.map(async (e) => {
23531
+ let D = await Promise.all(w.map(async (e) => {
23520
23532
  let n = e.status === "draft" || !!e.hasUnpublishedChanges, r = {
23521
23533
  id: e.id,
23522
23534
  title: e.title,
@@ -23534,7 +23546,7 @@ mx.get("/", async (e) => {
23534
23546
  updatedById: e.updatedById || null,
23535
23547
  createdAt: e.createdAt,
23536
23548
  updatedAt: e.updatedAt,
23537
- channelNames: T[e.id] || [],
23549
+ channelNames: ee[e.id] || [],
23538
23550
  treeNames: E[e.id] || [],
23539
23551
  assetCount: e.assetCount || 0,
23540
23552
  imageCount: e.imageCount || 0,
@@ -23556,9 +23568,9 @@ mx.get("/", async (e) => {
23556
23568
  limit: f
23557
23569
  });
23558
23570
  }), mx.post("/", async (e) => {
23559
- 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;
23560
- if (T) {
23561
- 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));
23562
23574
  if (e?.dataJson) try {
23563
23575
  let t = typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson;
23564
23576
  E = t.defaultLanguage?.trim() || t.language?.trim() || null;
@@ -23577,7 +23589,7 @@ mx.get("/", async (e) => {
23577
23589
  }
23578
23590
  }
23579
23591
  }
23580
- ee && E && ee === E && (ee = null);
23592
+ w && E && w === E && (w = null);
23581
23593
  let D = a, te = /* @__PURE__ */ new Set(), ne = !1, O = "draft", k = 0, A = s === void 0 ? null : _x(s);
23582
23594
  if (A) {
23583
23595
  let n = [];
@@ -23628,7 +23640,7 @@ mx.get("/", async (e) => {
23628
23640
  ...r,
23629
23641
  ...v
23630
23642
  }), l = !1;
23631
- 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) {
23632
23644
  for (let e of Object.keys(v)) if (JSON.stringify(v[e]) !== JSON.stringify(r[e])) {
23633
23645
  l = !0;
23634
23646
  break;
@@ -23650,13 +23662,13 @@ mx.get("/", async (e) => {
23650
23662
  }
23651
23663
  }
23652
23664
  }
23653
- 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;
23654
23666
  O = e?.status === "published" || e?.publishedAt ? "published" : "draft";
23655
23667
  let h = e?.hasUnpublishedChanges === 1 || e?.hasUnpublishedChanges === !0;
23656
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);
23657
23669
  } else {
23658
23670
  ne = !0;
23659
- 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);
23660
23672
  D = Number(e.lastInsertRowid);
23661
23673
  }
23662
23674
  if (h !== void 0 && Array.isArray(h) && D) {
@@ -24190,18 +24202,19 @@ kx.get("/", async (e) => {
24190
24202
  }
24191
24203
  }), kx.post("/", async (e) => {
24192
24204
  try {
24193
- 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 || "";
24194
- typeof w == "object" && w && (w = w.value || w.id || ""), w = String(w).trim();
24195
- 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;
24196
24208
  if (await t.prepare("SELECT id FROM channels WHERE key = ? AND id != ? LIMIT 1").get(C, a ?? -1)) return e.json({
24197
24209
  error: `Channel API key "${C}" is already in use.`,
24198
24210
  field: "key"
24199
24211
  }, 409);
24200
24212
  let ne = a;
24201
- 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);
24202
24214
  else {
24203
- 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);
24204
- 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);
24205
24218
  }
24206
24219
  await t.prepare("DELETE FROM channel_trees WHERE channelId = ?").run(ne);
24207
24220
  let O = E.filter((e) => e && e.treeId && e.key);
@@ -24550,7 +24563,7 @@ function Yx(e) {
24550
24563
  channelTemplate: null,
24551
24564
  userTemplate: null
24552
24565
  };
24553
- 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 = {
24554
24567
  ...p,
24555
24568
  ...f
24556
24569
  }, k = (e, t = "settings", n, r) => {
@@ -24678,7 +24691,7 @@ function Yx(e) {
24678
24691
  };
24679
24692
  });
24680
24693
  let ie = {};
24681
- Object.entries(ee).forEach(([e, t]) => {
24694
+ Object.entries(w).forEach(([e, t]) => {
24682
24695
  let n = A(t.tabs), r = k(t.fields || [], "settings", n);
24683
24696
  Array.isArray(t.fieldSets) && t.fieldSets.forEach((e) => {
24684
24697
  let t = O[e] || {}, i = t.fields || t, a = k(i, "settings", n);
@@ -24698,7 +24711,7 @@ function Yx(e) {
24698
24711
  };
24699
24712
  });
24700
24713
  let ae = {};
24701
- Object.entries(w).forEach(([e, t]) => {
24714
+ Object.entries(T).forEach(([e, t]) => {
24702
24715
  let n = A(t.tabs), r = k(t.fields || [], "settings", n);
24703
24716
  Array.isArray(t.fieldSets) && t.fieldSets.forEach((e) => {
24704
24717
  let t = O[e] || {}, n = t.fields || t, i = k(n);
@@ -24719,7 +24732,7 @@ function Yx(e) {
24719
24732
  };
24720
24733
  });
24721
24734
  let oe = {};
24722
- Object.entries(T).forEach(([e, t]) => {
24735
+ Object.entries(ee).forEach(([e, t]) => {
24723
24736
  let n = A(t.tabs), r = k(t.fields || [], "settings", n);
24724
24737
  Array.isArray(t.fieldSets) && t.fieldSets.forEach((e) => {
24725
24738
  let t = O[e] || {}, i = t.fields || t, a = k(i, "settings", n);
@@ -24801,26 +24814,26 @@ function Yx(e) {
24801
24814
  tabs: n
24802
24815
  };
24803
24816
  });
24804
- let j = g?.fields || {};
24817
+ let ue = g?.fields || {};
24805
24818
  Array.isArray(g?.fieldSets) && g?.fieldSets.forEach((e) => {
24806
24819
  let t = O[e] || {}, n = t.fields || t, r = k(n);
24807
24820
  Object.entries(r).forEach(([e, t]) => {
24808
- j[e] = Bx(j[e] || {}, t);
24821
+ ue[e] = Bx(ue[e] || {}, t);
24809
24822
  });
24810
24823
  });
24811
- let ue = g ? {
24824
+ let de = g ? {
24812
24825
  ...g,
24813
- fields: j
24814
- } : null, de = _?.fields || {};
24826
+ fields: ue
24827
+ } : null, j = _?.fields || {};
24815
24828
  Array.isArray(_?.fieldSets) && _?.fieldSets.forEach((e) => {
24816
24829
  let t = O[e] || {}, n = t.fields || t, r = k(n);
24817
24830
  Object.entries(r).forEach(([e, t]) => {
24818
- de[e] = Bx(de[e] || {}, t);
24831
+ j[e] = Bx(j[e] || {}, t);
24819
24832
  });
24820
24833
  });
24821
24834
  let fe = _ ? {
24822
24835
  ..._,
24823
- fields: de
24836
+ fields: j
24824
24837
  } : null;
24825
24838
  return {
24826
24839
  nodes: re,
@@ -24833,7 +24846,7 @@ function Yx(e) {
24833
24846
  fieldSets: O,
24834
24847
  nodeTemplate: m || null,
24835
24848
  treeTemplate: h || null,
24836
- channelTemplate: ue,
24849
+ channelTemplate: de,
24837
24850
  userTemplate: fe
24838
24851
  };
24839
24852
  }
@@ -25096,9 +25109,9 @@ nS.get("/", async (e) => {
25096
25109
  }
25097
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}`;
25098
25111
  if (!v) throw Error("Storage provider failed to return a valid storage key");
25099
- 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;
25100
- w && (await rS(t, "SELECT id FROM users WHERE id = ?", [w])).length === 0 && (w = null);
25101
- 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);
25102
25115
  if (s) {
25103
25116
  let r = await rS(t, "SELECT storageKeyPrivate, isSystemVariant, parentAssetId FROM assets WHERE id = ?", [s]);
25104
25117
  if (r.length > 0) {
@@ -25115,7 +25128,7 @@ nS.get("/", async (e) => {
25115
25128
  } catch (e) {
25116
25129
  console.warn("Failed to cleanup old asset", e);
25117
25130
  }
25118
- T.purgeAsset(e, t, s);
25131
+ ee.purgeAsset(e, t, s);
25119
25132
  let o = `${x}?v=${Date.now()}`;
25120
25133
  return e.json({
25121
25134
  id: s,
@@ -25139,7 +25152,7 @@ nS.get("/", async (e) => {
25139
25152
  C,
25140
25153
  v,
25141
25154
  x,
25142
- w,
25155
+ T,
25143
25156
  D,
25144
25157
  l,
25145
25158
  d
@@ -25147,7 +25160,7 @@ nS.get("/", async (e) => {
25147
25160
  let te = x;
25148
25161
  if (l) {
25149
25162
  let n = await rS(t, "SELECT cdnUrl, storageKeyPrivate FROM assets WHERE id = ?", [l]);
25150
- 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);
25151
25164
  }
25152
25165
  return e.json({
25153
25166
  id: E,
@@ -25300,7 +25313,18 @@ function sS() {
25300
25313
  assetUrls: /* @__PURE__ */ new Map()
25301
25314
  };
25302
25315
  }
25303
- 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) {
25304
25328
  let n = Date.now();
25305
25329
  if (e && String(e).trim() !== "") {
25306
25330
  let t = Date.parse(e);
@@ -25312,37 +25336,37 @@ function cS(e, t) {
25312
25336
  }
25313
25337
  return !0;
25314
25338
  }
25315
- async function lS(e, t, n, r) {
25316
- let i = t.filter((e) => e.componentId === "content-feed" || e.componentId === "article-list");
25317
- await Promise.all(i.map(async (t) => {
25318
- 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];
25319
- n && n !== "all" && (c += " AND id IN (SELECT nodeId FROM node_channels WHERE channelId = ?)", l.push(Number(n) || n));
25320
- let u = i.taxonomies || i.taxonomyFilters || {}, d = Object.keys(u);
25321
- if (d.length > 0) for (let e of d) {
25322
- 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]];
25323
25347
  if (t.length > 0) {
25324
25348
  let n = t.map(() => "?").join(",");
25325
- c += ` AND EXISTS (
25349
+ l += ` AND EXISTS (
25326
25350
  SELECT 1 FROM node_terms nt
25327
25351
  INNER JOIN taxonomy_terms tt ON nt.termId = tt.id
25328
25352
  WHERE nt.nodeId = content_nodes.id
25329
25353
  AND tt.taxonomy = ?
25330
25354
  AND tt.key IN (${n})
25331
- )`, l.push(e, ...t);
25355
+ )`, u.push(e, ...t);
25332
25356
  }
25333
25357
  }
25334
- let f = "ORDER BY updatedAt DESC";
25335
- s === "published_desc" || s === "createdAt" ? f = "ORDER BY createdAt DESC" : s === "title_asc" && (f = "ORDER BY LOWER(title) ASC");
25336
- let p = `SELECT id, title, slug, language, dataJson, createdAt, updatedAt ${c} ${f} LIMIT ?`;
25337
- 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);
25338
25362
  try {
25339
- let n = await e.prepare(p).all(...l), i = Array.isArray(n) ? n : n?.results || [];
25340
- 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) => {
25341
25365
  let t = {};
25342
25366
  if (e.dataJson) try {
25343
25367
  t = typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson;
25344
25368
  } catch {}
25345
- return cS(t.startShowingAt, t.stopShowingAt) ? {
25369
+ return i && cS(t.startShowingAt, t.stopShowingAt, i), lS(t.startShowingAt, t.stopShowingAt) ? {
25346
25370
  id: e.id,
25347
25371
  title: e.title,
25348
25372
  slug: e.slug,
@@ -25359,23 +25383,23 @@ async function lS(e, t, n, r) {
25359
25383
  }
25360
25384
  }));
25361
25385
  }
25362
- async function uS(e, t, n, r, i, a = !1, o) {
25386
+ async function dS(e, t, n, r, i, a = !1, o, s) {
25363
25387
  if (!t) return { blocks: [] };
25364
- 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 || [];
25365
- if (!c || c.length === 0) return { blocks: [] };
25366
- let l = c.map((e) => e.contentId).filter((e) => e != null);
25367
- if (l.length === 0) return { blocks: [] };
25368
- 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();
25369
- 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) => {
25370
25394
  let t = String(e.contentId);
25371
- m.has(t) || m.set(t, []), m.get(t).push(e);
25395
+ h.has(t) || h.set(t, []), h.get(t).push(e);
25372
25396
  });
25373
- for (let t of c) {
25374
- let n = m.get(String(t.contentId)) || [];
25397
+ for (let t of l) {
25398
+ let n = h.get(String(t.contentId)) || [];
25375
25399
  if (n.filter((e) => e.region === r).length === 0) continue;
25376
- let o = /* @__PURE__ */ new Set([r]), s = !0;
25377
- for (; s;) {
25378
- s = !1;
25400
+ let o = /* @__PURE__ */ new Set([r]), c = !0;
25401
+ for (; c;) {
25402
+ c = !1;
25379
25403
  for (let e of n) {
25380
25404
  if (!o.has(e.region)) continue;
25381
25405
  let t = {};
@@ -25386,39 +25410,40 @@ async function uS(e, t, n, r, i, a = !1, o) {
25386
25410
  for (let e of n) {
25387
25411
  if (!e.region || o.has(e.region)) continue;
25388
25412
  let t = e.region;
25389
- (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);
25390
25414
  }
25391
25415
  }
25392
25416
  }
25393
- 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) => {
25394
25418
  let n = {};
25395
25419
  try {
25396
25420
  n = (typeof t.dataJson == "string" ? JSON.parse(t.dataJson) : t.dataJson) || {};
25397
25421
  } catch {}
25398
- let o = n.hidden === !0 || n.hidden === 1 || n.hidden === "1" || n.hidden === "true", s = cS(n.startShowingAt, n.stopShowingAt);
25399
- if (!a && (o || !s)) return null;
25400
- 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);
25401
- 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, {
25402
25427
  region: t.region || r,
25403
25428
  block: {
25404
25429
  instanceId: t.id,
25405
- blockId: u,
25406
- componentId: c,
25407
- data: d
25430
+ blockId: d,
25431
+ componentId: l,
25432
+ data: f
25408
25433
  }
25409
25434
  };
25410
- })), l = {};
25411
- for (let e of c) e && (l[e.region] || (l[e.region] = []), l[e.region].push(e.block));
25412
- if (l[r] && l[r].length > 0) return {
25413
- blocks: l[r],
25414
- 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,
25415
25440
  inheritedFromId: String(t.contentId),
25416
25441
  inheritedFromTitle: t.title || t.slug
25417
25442
  };
25418
25443
  }
25419
25444
  return { blocks: [] };
25420
25445
  }
25421
- function dS(e, t = {}) {
25446
+ function fS(e, t = {}) {
25422
25447
  let n = {};
25423
25448
  for (let [r, i] of Object.entries(e)) r.endsWith("_meta") || [
25424
25449
  "disabledRegions",
@@ -25434,14 +25459,14 @@ function dS(e, t = {}) {
25434
25459
  ].includes(r) || r.startsWith("_") || (!t[r] || t[r].public !== !1) && (n[r] = i);
25435
25460
  return n;
25436
25461
  }
25437
- function fS(e) {
25438
- if (Array.isArray(e)) return e.map(fS);
25462
+ function pS(e) {
25463
+ if (Array.isArray(e)) return e.map(pS);
25439
25464
  if (!e || typeof e != "object") return e;
25440
25465
  if (typeof e.id == "string" && e.id.startsWith("ast_") && typeof e.url == "string") {
25441
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 ? {
25442
25467
  ...t,
25443
25468
  ...t.crops?.[r] || {}
25444
- } : 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({
25445
25470
  ...n,
25446
25471
  title: n?.title ?? e.title ?? "",
25447
25472
  alt: n?.alt ?? e.alt ?? "",
@@ -25455,9 +25480,9 @@ function fS(e) {
25455
25480
  ...Object.keys(a).length > 0 ? { variants: a } : {}
25456
25481
  };
25457
25482
  }
25458
- 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)]));
25459
25484
  }
25460
- async function pS(e, t, n, r) {
25485
+ async function mS(e, t, n, r) {
25461
25486
  if (typeof t == "string") {
25462
25487
  if (!t.includes("#node:") && !t.includes("data-node-id") && !t.includes("#asset:") && !t.includes("data-asset-id")) return t;
25463
25488
  let r = (e, t) => {
@@ -25490,25 +25515,25 @@ async function pS(e, t, n, r) {
25490
25515
  return /href\s*=\s*["'][^"']*["']/i.test(d) ? d = d.replace(/href\s*=\s*["'][^"']*["']/i, `href="${u}"`) : d += ` href="${u}"`, `<a ${d}>`;
25491
25516
  });
25492
25517
  }
25493
- 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)));
25494
25519
  if (t && typeof t == "object") {
25495
25520
  if (typeof t.href == "string" && (t.href.startsWith("#node:") || t.href.startsWith("#asset:"))) return {
25496
25521
  ...t,
25497
- href: await mS(e, t, n, r)
25522
+ href: await hS(e, t, n, r)
25498
25523
  };
25499
- 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)]));
25500
25525
  return Object.fromEntries(i);
25501
25526
  }
25502
25527
  return t;
25503
25528
  }
25504
- async function mS(e, t, n, r) {
25529
+ async function hS(e, t, n, r) {
25505
25530
  let i = t.href.match(/^#node:(.+)$/), a = t.href.match(/^#asset:(.+)$/);
25506
- if (a) return hS(e, a[1], r);
25531
+ if (a) return gS(e, a[1], r);
25507
25532
  if (!i) return t.href;
25508
25533
  let o = i[1];
25509
25534
  return (await e.prepare("SELECT path FROM node_routes WHERE nodeId = ? AND channelId = ? AND isCanonical = 1 LIMIT 1").get(Number(o), n))?.path || "#";
25510
25535
  }
25511
- async function hS(e, t, n) {
25536
+ async function gS(e, t, n) {
25512
25537
  let r = String(t), i = n.assetUrls.get(r);
25513
25538
  if (i) return i;
25514
25539
  let a = (async () => {
@@ -25517,7 +25542,7 @@ async function hS(e, t, n) {
25517
25542
  })();
25518
25543
  return n.assetUrls.set(r, a), a;
25519
25544
  }
25520
- function gS(e) {
25545
+ function _S(e) {
25521
25546
  let t = e.socialImage;
25522
25547
  if (!t || typeof t != "object") return null;
25523
25548
  let n = (e, t) => {
@@ -25548,7 +25573,7 @@ function gS(e) {
25548
25573
  ])
25549
25574
  };
25550
25575
  }
25551
- async function _S(e, t, n, r, i) {
25576
+ async function vS(e, t, n, r, i) {
25552
25577
  let a = {}, o = null;
25553
25578
  if (t) {
25554
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([
@@ -25586,151 +25611,160 @@ async function _S(e, t, n, r, i) {
25586
25611
  inheritedFields: a
25587
25612
  };
25588
25613
  }
25589
- function vS(e) {
25614
+ function yS(e) {
25590
25615
  let t = Number(e?.env?.CMS_NODE_CACHE_TTL);
25591
25616
  return Number.isFinite(t) && t >= 60 ? Math.floor(t) : 300;
25592
25617
  }
25593
- async function yS(e, t, n, r) {
25618
+ async function bS(e, t, n, r) {
25594
25619
  try {
25595
25620
  await e.set(t, n, r);
25596
25621
  } catch (e) {
25597
25622
  console.warn("[CMS Cache] Failed to write node response to cache:", e);
25598
25623
  }
25599
25624
  }
25600
- async function bS(e) {
25625
+ async function xS(e) {
25601
25626
  try {
25602
- 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 = "";
25603
- 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 = "");
25604
25629
  try {
25605
- u = decodeURIComponent(u);
25630
+ d = decodeURIComponent(d);
25606
25631
  } catch {}
25607
- u = u.replace(/^\/+|\/+$/g, "");
25608
- 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));
25609
- if (!p) return e.json({ error: `Channel '${f}' not found` }, 404);
25610
- let m = p.status === "disabled" || p.status === "inactive" || p.isEnabled === 0 || p.isEnabled === !1;
25611
- if (!o && m) return e.json({ error: `Channel '${p.key || f}' is currently inactive` }, 404);
25612
- 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);
25613
- if (_?.redirectUrl) return e.json({
25614
- 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,
25615
25640
  isCanonical: !1
25616
25641
  });
25617
- let v = null, y = _?.treeId || c || null;
25618
- if (_?.nodeId) v = await t.prepare("SELECT * FROM content_nodes WHERE id = ?").get(_.nodeId);
25619
- 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));
25620
25645
  else {
25621
- let e = u.split("/").pop() || u;
25622
- 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);
25623
25648
  }
25624
- if (!v) return e.json({ error: `Node '${u}' not found for Channel '${f}'` }, 404);
25625
- let b = null;
25626
- if (s) {
25627
- 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));
25628
25653
  if (e && e.snapshotJson) try {
25629
- 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));
25630
25655
  } catch (e) {
25631
25656
  console.error("[CMS] Failed to parse snapshotJson", e);
25632
25657
  }
25633
25658
  }
25634
- 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] : []);
25635
- !y && x?.treeId && (y = x.treeId), y ||= "main-nav";
25636
- let S = null;
25637
- if (y) {
25638
- 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));
25639
25664
  if (e?.dataJson) try {
25640
25665
  let t = typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson;
25641
- 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());
25642
25667
  } catch {}
25643
25668
  }
25644
- let C = null;
25645
- if (p) {
25646
- if (p.defaultLanguage) C = String(p.defaultLanguage).trim();
25647
- else if (p.dataJson) try {
25648
- let e = typeof p.dataJson == "string" ? JSON.parse(p.dataJson) : p.dataJson;
25649
- 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());
25650
25675
  } catch {}
25651
25676
  }
25652
- 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);
25653
- if (!o && !D) {
25654
- let t = await te.get(E);
25655
- if (t) return e.header("X-Cache", "HIT"), e.json(t);
25656
- }
25657
- let ne = x?.parentId || null, O = _?.path || (d === "" ? "/" : d), k = {
25658
- id: v.id,
25659
- title: v.title,
25660
- slug: v.slug,
25661
- language: T,
25662
- path: O,
25663
- nodeType: v.contentType,
25664
- createdAt: v.createdAt,
25665
- updatedAt: v.updatedAt
25666
- }, A = dx(e.env?.BUNDLED_DEFINITIONS), re = v.contentType || "node", ie = A.nodes?.[re] || Object.values(A.nodes || {})[0] || {}, ae = { ...ie.fields || {} };
25667
- ie.tabs && Object.values(ie.tabs).forEach((e) => {
25668
- 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 || {});
25669
25702
  });
25670
- let oe = {}, se = null, ce = null, le = !1, j = {}, ue = o && v.draftDataJson || v.dataJson;
25671
- if (b && b.node && b.node.dataJson && (ue = b.node.dataJson), ue) try {
25672
- 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;
25673
25706
  } catch {}
25674
- 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;
25675
- 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;
25676
- 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);
25677
- let ge = await ux(t, dS(j, ae));
25678
- ge = fS(ge), ge = await pS(t, ge, h, n), delete ge.language;
25679
- let _e = gS(ge);
25680
- 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;
25681
- 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";
25682
- if (!o && (ve || ye || be && !xe)) return e.json({ error: "Node is hidden, offline, or has never been published." }, 404);
25683
- let Se = [];
25684
- if (x?.treeNodeId) {
25685
- 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;
25686
- Se = n.map((e) => {
25687
- 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;
25688
25721
  if (!n) return null;
25689
25722
  try {
25690
25723
  t = (typeof n == "string" ? JSON.parse(n) : n) || {};
25691
25724
  } catch {}
25692
- 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, "");
25693
- 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 : {
25694
25727
  treeNodeId: e.treeNodeId,
25695
25728
  id: e.id,
25696
25729
  title: e.title,
25697
- slug: s,
25698
- language: e.language?.trim() || T || null,
25699
- path: `${i}/${s}`.replace(/\/+/g, "/"),
25730
+ slug: c,
25731
+ language: e.language?.trim() || E || null,
25732
+ path: `${a}/${c}`.replace(/\/+/g, "/"),
25700
25733
  nodeType: e.nodeType
25701
25734
  };
25702
25735
  }).filter(Boolean);
25703
25736
  }
25704
- k.children = Se;
25705
- let Ce = [];
25706
- 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) => ({
25707
25740
  ...e,
25708
25741
  isDraft: 1
25709
25742
  }));
25710
25743
  else {
25711
- let e = +!!o, n = await t.prepare("SELECT * FROM content_blocks WHERE contentId = ? AND isDraft = ? ORDER BY sortOrder ASC").all(v.id, e);
25712
- 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 || [];
25713
25746
  }
25714
- let we = {}, Te = {}, Ee = await Promise.all(Ce.map(async (e) => {
25715
- 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 = {};
25716
25749
  try {
25717
- i = (typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson) || {};
25750
+ a = (typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson) || {};
25718
25751
  } catch {}
25719
- let a = i.hidden === !0 || i.hidden === 1 || i.hidden === "1" || i.hidden === "true", s = cS(i.startShowingAt, i.stopShowingAt);
25720
- if (!o && (a || !s)) return null;
25721
- 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);
25722
- return d = await ux(t, d), d = fS(d), d = await pS(t, d, h, n), d.blockId = u, {
25723
- 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,
25724
25758
  block: {
25725
25759
  instanceId: e.id,
25726
- blockId: u,
25727
- componentId: c,
25728
- data: d
25760
+ blockId: d,
25761
+ componentId: l,
25762
+ data: f
25729
25763
  }
25730
25764
  };
25731
25765
  }));
25732
- for (let e of Ee) e && (we[e.region] || (we[e.region] = [], Te[e.region] = { isInherited: !1 }), we[e.region].push(e.block));
25733
- 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 = {
25734
25768
  header: {
25735
25769
  label: "Header",
25736
25770
  inherit: "parent"
@@ -25739,33 +25773,43 @@ async function bS(e) {
25739
25773
  label: "Footer",
25740
25774
  inherit: "parent"
25741
25775
  },
25742
- ...(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" } }
25743
25777
  };
25744
- for (let [e, r] of Object.entries(De)) {
25745
- let i = we[e] && we[e].length > 0, a = !!oe[e];
25746
- 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) {
25747
- let r = await uS(t, ne, String(y), e, A, o, n);
25748
- 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] = {
25749
25783
  isInherited: !0,
25750
- inheritedFromId: r.inheritedFromId,
25751
- inheritedFromTitle: r.inheritedFromTitle
25752
- }, 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] = {
25753
25787
  isInherited: !0,
25754
- inheritedFromId: r.inheritedFromId,
25755
- inheritedFromTitle: r.inheritedFromTitle
25788
+ inheritedFromId: i.inheritedFromId,
25789
+ inheritedFromTitle: i.inheritedFromTitle
25756
25790
  });
25757
25791
  }
25758
25792
  }
25759
- await Promise.all(Object.keys(we).map((e) => lS(t, we[e], h, T)));
25760
- let Oe = {
25761
- channelId: h || g,
25762
- treeId: y,
25763
- language: T,
25764
- node: k,
25765
- content: we,
25766
- 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
25767
25811
  };
25768
- 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);
25769
25813
  } catch (t) {
25770
25814
  return console.error("[CMS Public API] Error fetching node by path:", t), e.json({
25771
25815
  error: "Failed to fetch JSON payload",
@@ -25773,20 +25817,24 @@ async function bS(e) {
25773
25817
  }, 500);
25774
25818
  }
25775
25819
  }
25776
- var xS = X({
25820
+ var SS = X({
25777
25821
  channelId: J().optional().openapi({ description: "The ID or key of the channel" }),
25778
25822
  channel: J().optional().openapi({ description: "Legacy alias for channelId" }),
25779
25823
  lang: J().optional().openapi({ description: "Requested language code" }),
25780
25824
  preview: lv(["true", "false"]).optional().openapi({ description: "Request unpublished draft data" }),
25781
25825
  revisionId: J().optional().openapi({ description: "Historical revision version to load" }),
25782
25826
  treeId: J().optional().openapi({ description: "The ID of the tree to resolve paths against" })
25783
- }), SS = X({
25827
+ }), CS = X({
25784
25828
  error: J(),
25785
25829
  details: J().optional()
25786
- }).openapi("ErrorResponse"), CS = X({
25830
+ }).openapi("ErrorResponse"), wS = X({
25787
25831
  channelId: G_([J(), c_()]),
25788
25832
  treeId: J().nullable(),
25789
25833
  language: J().nullable(),
25834
+ meta: X({
25835
+ cacheTtl: c_(),
25836
+ nextEventTimestamp: c_().nullable()
25837
+ }).optional(),
25790
25838
  node: tv(k_()),
25791
25839
  content: tv(z_(k_())),
25792
25840
  regionMeta: tv(X({
@@ -25794,7 +25842,7 @@ var xS = X({
25794
25842
  inheritedFromId: J().optional(),
25795
25843
  inheritedFromTitle: J().optional()
25796
25844
  }))
25797
- }).openapi("NodeResponse"), wS = eb({
25845
+ }).openapi("NodeResponse"), TS = eb({
25798
25846
  method: "get",
25799
25847
  path: "/{path}",
25800
25848
  summary: "Fetch CMS Node Content",
@@ -25802,26 +25850,26 @@ var xS = X({
25802
25850
  tags: ["Public Node API"],
25803
25851
  request: {
25804
25852
  params: X({ path: J().optional().openapi({ description: "The full URL path or slug of the requested node" }) }),
25805
- query: xS
25853
+ query: SS
25806
25854
  },
25807
25855
  responses: {
25808
25856
  200: {
25809
25857
  description: "Fully hydrated CMS Node",
25810
- content: { "application/json": { schema: CS } }
25858
+ content: { "application/json": { schema: wS } }
25811
25859
  },
25812
25860
  404: {
25813
25861
  description: "Node or Channel not found",
25814
- content: { "application/json": { schema: SS } }
25862
+ content: { "application/json": { schema: CS } }
25815
25863
  },
25816
25864
  500: {
25817
25865
  description: "Server error during hydration",
25818
- content: { "application/json": { schema: SS } }
25866
+ content: { "application/json": { schema: CS } }
25819
25867
  }
25820
25868
  }
25821
25869
  });
25822
- oS.openapi(wS, bS), oS.get("*", bS);
25823
- var TS = new $y();
25824
- function ES(e, t) {
25870
+ oS.openapi(TS, xS), oS.get("*", xS);
25871
+ var ES = new $y();
25872
+ function DS(e, t) {
25825
25873
  let n = /* @__PURE__ */ new Date();
25826
25874
  if (e && String(e).trim() !== "") {
25827
25875
  let t = new Date(e);
@@ -25833,22 +25881,22 @@ function ES(e, t) {
25833
25881
  }
25834
25882
  return !0;
25835
25883
  }
25836
- async function DS(e, t, n, r) {
25884
+ async function OS(e, t, n, r) {
25837
25885
  try {
25838
25886
  await e.set(t, n, r);
25839
25887
  } catch (e) {
25840
25888
  console.warn("[CMS Cache] Failed to write tree response to cache:", e);
25841
25889
  }
25842
25890
  }
25843
- 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({
25844
25892
  channelId: J().optional().openapi({ description: "Channel ID to resolve context-aware routing" }),
25845
25893
  channel: J().optional().openapi({ description: "Legacy alias for channelId" }),
25846
25894
  lang: J().optional().openapi({ description: "Requested language code for tree nodes" }),
25847
25895
  preview: lv(["true", "false"]).optional().openapi({ description: "Set to true to retrieve unpublished draft data" })
25848
- }), AS = X({
25896
+ }), jS = X({
25849
25897
  error: J(),
25850
25898
  details: J().optional()
25851
- }).openapi("ErrorResponse"), jS = qv(() => X({
25899
+ }).openapi("ErrorResponse"), MS = qv(() => X({
25852
25900
  id: G_([J(), c_()]),
25853
25901
  treeNodeId: G_([J(), c_()]),
25854
25902
  parentId: G_([J(), c_()]).nullable(),
@@ -25861,40 +25909,40 @@ var OS = X({ treeParam: J().openapi({ description: "The ID or key of the request
25861
25909
  summary: J(),
25862
25910
  url: J().optional(),
25863
25911
  target: J().optional(),
25864
- children: z_(jS).optional()
25865
- })).openapi("TreeItem"), MS = X({
25912
+ children: z_(MS).optional()
25913
+ })).openapi("TreeItem"), NS = X({
25866
25914
  treeId: G_([c_(), J()]),
25867
25915
  key: J(),
25868
25916
  channelId: J(),
25869
25917
  language: J().nullable(),
25870
25918
  label: J(),
25871
- items: z_(jS)
25872
- }).catchall(k_()).openapi("TreeResponse"), NS = eb({
25919
+ items: z_(MS)
25920
+ }).catchall(k_()).openapi("TreeResponse"), PS = eb({
25873
25921
  method: "get",
25874
25922
  path: "/{treeParam}",
25875
25923
  summary: "Fetch CMS Navigation Tree",
25876
25924
  description: "Retrieves a fully hydrated, recursive navigation tree structure. Uses $O(1)$ pre-computed routing table paths.",
25877
25925
  tags: ["Public Tree API"],
25878
25926
  request: {
25879
- params: OS,
25880
- query: kS
25927
+ params: kS,
25928
+ query: AS
25881
25929
  },
25882
25930
  responses: {
25883
25931
  200: {
25884
25932
  description: "Fully hydrated CMS Tree payload",
25885
- content: { "application/json": { schema: MS } }
25933
+ content: { "application/json": { schema: NS } }
25886
25934
  },
25887
25935
  404: {
25888
25936
  description: "Tree or Channel not found / inactive",
25889
- content: { "application/json": { schema: AS } }
25937
+ content: { "application/json": { schema: jS } }
25890
25938
  },
25891
25939
  500: {
25892
25940
  description: "Server error during hydration",
25893
- content: { "application/json": { schema: AS } }
25941
+ content: { "application/json": { schema: jS } }
25894
25942
  }
25895
25943
  }
25896
25944
  });
25897
- TS.openapi(NS, async (e) => {
25945
+ ES.openapi(PS, async (e) => {
25898
25946
  try {
25899
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;
25900
25948
  if (i && i !== "default" && i !== "all") {
@@ -25957,7 +26005,7 @@ TS.openapi(NS, async (e) => {
25957
26005
  return (y.get(n) || []).map((e) => {
25958
26006
  let n = b.get(String(e.id)) || {}, r = {};
25959
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);
25960
- 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 = {
25961
26009
  id: e.id,
25962
26010
  treeNodeId: e.id,
25963
26011
  parentId: e.parentId || null,
@@ -25983,7 +26031,7 @@ TS.openapi(NS, async (e) => {
25983
26031
  ..._,
25984
26032
  items: x(null)
25985
26033
  };
25986
- 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);
25987
26035
  } catch (t) {
25988
26036
  return console.error("[CMS Public Tree API] Error:", t), e.json({
25989
26037
  error: "Failed to fetch public tree",
@@ -25991,19 +26039,19 @@ TS.openapi(NS, async (e) => {
25991
26039
  }, 500);
25992
26040
  }
25993
26041
  });
25994
- var PS = new $y();
25995
- function FS(e) {
26042
+ var FS = new $y();
26043
+ function IS(e) {
25996
26044
  let t = Number(e?.env?.CMS_CHANNEL_CACHE_TTL);
25997
26045
  return Number.isFinite(t) && t >= 60 ? Math.floor(t) : 300;
25998
26046
  }
25999
- async function IS(e, t, n, r) {
26047
+ async function LS(e, t, n, r) {
26000
26048
  try {
26001
26049
  await e.set(t, n, r);
26002
26050
  } catch (e) {
26003
26051
  console.warn("[CMS Cache] Failed to write channel response to cache:", e);
26004
26052
  }
26005
26053
  }
26006
- function LS(e, t) {
26054
+ function RS(e, t) {
26007
26055
  let n = {}, r = (e) => {
26008
26056
  if (!e || typeof e != "string") return;
26009
26057
  let n = t?.fieldSets?.[e] || t?.fieldsets?.[e] || t?.definitions?.[e] || t?.channels?.[e] || t?.[e];
@@ -26014,7 +26062,7 @@ function LS(e, t) {
26014
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);
26015
26063
  return n;
26016
26064
  }
26017
- function RS(e, t = {}) {
26065
+ function zS(e, t = {}) {
26018
26066
  let n = {}, r = Object.keys(t).length > 0;
26019
26067
  for (let [i, a] of Object.entries(e)) {
26020
26068
  if (i.endsWith("_meta") || [
@@ -26033,14 +26081,14 @@ function RS(e, t = {}) {
26033
26081
  }
26034
26082
  return n;
26035
26083
  }
26036
- function zS(e) {
26037
- if (Array.isArray(e)) return e.map(zS);
26084
+ function BS(e) {
26085
+ if (Array.isArray(e)) return e.map(BS);
26038
26086
  if (!e || typeof e != "object") return e;
26039
26087
  if (typeof e.id == "string" && e.id.startsWith("ast_") && typeof e.url == "string") {
26040
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 ? {
26041
26089
  ...t,
26042
26090
  ...t.crops?.[r] || {}
26043
- } : 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({
26044
26092
  ...n,
26045
26093
  title: n?.title ?? e.title ?? "",
26046
26094
  alt: n?.alt ?? e.alt ?? "",
@@ -26054,9 +26102,9 @@ function zS(e) {
26054
26102
  ...Object.keys(a).length > 0 ? { variants: a } : {}
26055
26103
  };
26056
26104
  }
26057
- 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)]));
26058
26106
  }
26059
- async function BS(e, t, n) {
26107
+ async function VS(e, t, n) {
26060
26108
  if (typeof t == "string") {
26061
26109
  if (!t.includes("#node:") && !t.includes("data-node-id") && !t.includes("#asset:") && !t.includes("data-asset-id")) return t;
26062
26110
  let r = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Set();
@@ -26089,45 +26137,45 @@ async function BS(e, t, n) {
26089
26137
  return /href\s*=\s*["'][^"']*["']/i.test(d) ? d = d.replace(/href\s*=\s*["'][^"']*["']/i, `href="${u}"`) : d += ` href="${u}"`, `<a ${d}>`;
26090
26138
  });
26091
26139
  }
26092
- 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)));
26093
26141
  if (t && typeof t == "object") {
26094
- 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)]));
26095
26143
  return Object.fromEntries(r);
26096
26144
  }
26097
26145
  return t;
26098
26146
  }
26099
- 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({
26100
26148
  error: J(),
26101
26149
  details: J().optional()
26102
- }).openapi("ErrorResponse"), WS = X({
26150
+ }).openapi("ErrorResponse"), GS = X({
26103
26151
  id: G_([c_(), J()]),
26104
26152
  key: J()
26105
- }).catchall(k_()).openapi("ChannelResponse"), GS = eb({
26153
+ }).catchall(k_()).openapi("ChannelResponse"), KS = eb({
26106
26154
  method: "get",
26107
26155
  path: "/{channelParam}",
26108
26156
  summary: "Fetch CMS Channel Settings",
26109
26157
  description: "Retrieves the fully hydrated, public-facing settings and payload for a specific CMS channel.",
26110
26158
  tags: ["Public Channel API"],
26111
26159
  request: {
26112
- params: VS,
26113
- query: HS
26160
+ params: HS,
26161
+ query: US
26114
26162
  },
26115
26163
  responses: {
26116
26164
  200: {
26117
26165
  description: "Fully hydrated CMS Channel payload",
26118
- content: { "application/json": { schema: WS } }
26166
+ content: { "application/json": { schema: GS } }
26119
26167
  },
26120
26168
  404: {
26121
26169
  description: "Channel not found or inactive",
26122
- content: { "application/json": { schema: US } }
26170
+ content: { "application/json": { schema: WS } }
26123
26171
  },
26124
26172
  500: {
26125
26173
  description: "Server error during hydration",
26126
- content: { "application/json": { schema: US } }
26174
+ content: { "application/json": { schema: WS } }
26127
26175
  }
26128
26176
  }
26129
26177
  });
26130
- PS.openapi(GS, async (e) => {
26178
+ FS.openapi(KS, async (e) => {
26131
26179
  try {
26132
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);
26133
26181
  if (!i && !a) {
@@ -26138,23 +26186,23 @@ PS.openapi(GS, async (e) => {
26138
26186
  if (!c) return e.json({ error: `Channel '${n}' not found` }, 404);
26139
26187
  let l = c.status === "disabled" || c.status === "inactive" || c.isEnabled === 0 || c.isEnabled === !1;
26140
26188
  if (!i && l) return e.json({ error: `Channel '${c.key || n}' is currently inactive` }, 404);
26141
- 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;
26142
26190
  if (g) try {
26143
26191
  h = typeof g == "string" ? JSON.parse(g) : g;
26144
26192
  } catch (e) {
26145
26193
  console.warn("[CMS Public Channel API] Failed to parse channel dataJson:", e);
26146
26194
  }
26147
- let _ = RS({
26195
+ let _ = zS({
26148
26196
  ...h,
26149
26197
  ...c
26150
26198
  }, m);
26151
- _ = await ux(t, _), _ = zS(_), _ = await BS(t, _, u);
26199
+ _ = await ux(t, _), _ = BS(_), _ = await VS(t, _, u);
26152
26200
  let v = {
26153
26201
  id: c.id,
26154
26202
  key: c.key,
26155
26203
  ..._
26156
26204
  };
26157
- 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);
26158
26206
  } catch (t) {
26159
26207
  return console.error("[CMS Public Channel API] Error:", t), e.json({
26160
26208
  error: "Failed to fetch public channel",
@@ -26162,8 +26210,8 @@ PS.openapi(GS, async (e) => {
26162
26210
  }, 500);
26163
26211
  }
26164
26212
  });
26165
- var KS = new $y();
26166
- function qS(e, t) {
26213
+ var qS = new $y();
26214
+ function JS(e, t) {
26167
26215
  if (t === "webp") return "image/webp";
26168
26216
  if (t === "avif") return "image/avif";
26169
26217
  if (t === "jpeg" || t === "jpg") return "image/jpeg";
@@ -26172,7 +26220,7 @@ function qS(e, t) {
26172
26220
  let n = e.toLowerCase();
26173
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";
26174
26222
  }
26175
- var JS = eb({
26223
+ var YS = eb({
26176
26224
  method: "get",
26177
26225
  path: "/*",
26178
26226
  summary: "Serve & Optimize Media Assets",
@@ -26229,7 +26277,7 @@ var JS = eb({
26229
26277
  }
26230
26278
  }
26231
26279
  });
26232
- KS.openapi(JS, async (e) => {
26280
+ qS.openapi(YS, async (e) => {
26233
26281
  try {
26234
26282
  let t = e.req.path.replace(/^\/media\//, "").replace(/^\//, "");
26235
26283
  if (!t) return e.text("Asset key missing", 400);
@@ -26252,7 +26300,7 @@ KS.openapi(JS, async (e) => {
26252
26300
  if (!m) return e.text(`Asset not found: ${t}`, 404);
26253
26301
  if (!o) {
26254
26302
  let n = e.body(m, 200, {
26255
- "Content-Type": qS(t),
26303
+ "Content-Type": JS(t),
26256
26304
  "Cache-Control": "public, max-age=31536000, immutable"
26257
26305
  });
26258
26306
  return l && d && e.executionCtx?.waitUntil && e.executionCtx.waitUntil(l.put(d, n.clone())), n;
@@ -26266,7 +26314,7 @@ KS.openapi(JS, async (e) => {
26266
26314
  key: t,
26267
26315
  env: e.env,
26268
26316
  req: e.req.raw
26269
- }), _ = qS(t, c), v = e.body(g, 200, {
26317
+ }), _ = JS(t, c), v = e.body(g, 200, {
26270
26318
  "Content-Type": _,
26271
26319
  "Cache-Control": "public, max-age=31536000, immutable"
26272
26320
  });
@@ -26275,8 +26323,8 @@ KS.openapi(JS, async (e) => {
26275
26323
  return console.error("❌ [Public Assets Error]:", t), e.text("Internal Server Error", 500);
26276
26324
  }
26277
26325
  });
26278
- var YS = new $y();
26279
- function XS(e, t) {
26326
+ var XS = new $y();
26327
+ function ZS(e, t) {
26280
26328
  let n = /* @__PURE__ */ new Date();
26281
26329
  if (e && String(e).trim() !== "") {
26282
26330
  let t = new Date(e);
@@ -26288,31 +26336,31 @@ function XS(e, t) {
26288
26336
  }
26289
26337
  return !0;
26290
26338
  }
26291
- var ZS = X({
26339
+ var QS = X({
26292
26340
  channelId: J().optional().openapi({ description: "Optional channel ID/key to filter and resolve root paths for" }),
26293
26341
  channel: J().optional().openapi({ description: "Legacy alias for channelId" })
26294
- }), QS = z_(J()).openapi("PathsResponse"), $S = X({
26342
+ }), $S = z_(J()).openapi("PathsResponse"), eC = X({
26295
26343
  error: J(),
26296
26344
  details: J().optional()
26297
- }).openapi("ErrorResponse"), eC = eb({
26345
+ }).openapi("ErrorResponse"), tC = eb({
26298
26346
  method: "get",
26299
26347
  path: "/",
26300
26348
  summary: "Fetch All Public Paths",
26301
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.",
26302
26350
  tags: ["Public Paths API"],
26303
- request: { query: ZS },
26351
+ request: { query: QS },
26304
26352
  responses: {
26305
26353
  200: {
26306
26354
  description: "Array of valid public URL paths",
26307
- content: { "application/json": { schema: QS } }
26355
+ content: { "application/json": { schema: $S } }
26308
26356
  },
26309
26357
  500: {
26310
26358
  description: "Server error fetching paths",
26311
- content: { "application/json": { schema: $S } }
26359
+ content: { "application/json": { schema: eC } }
26312
26360
  }
26313
26361
  }
26314
26362
  });
26315
- YS.openapi(eC, async (e) => {
26363
+ XS.openapi(tC, async (e) => {
26316
26364
  try {
26317
26365
  let t = e.get("db"), n = e.req.valid("query"), r = n.channelId || n.channel, i = "", a = [];
26318
26366
  if (r && r !== "all") {
@@ -26337,7 +26385,7 @@ YS.openapi(eC, async (e) => {
26337
26385
  let t = !0;
26338
26386
  if (e.dataJson) try {
26339
26387
  let n = typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson;
26340
- t = XS(n?.startShowingAt, n?.stopShowingAt);
26388
+ t = ZS(n?.startShowingAt, n?.stopShowingAt);
26341
26389
  } catch {}
26342
26390
  t && c.push(e.path);
26343
26391
  }
@@ -26347,12 +26395,12 @@ YS.openapi(eC, async (e) => {
26347
26395
  return console.error("[CMS Paths API] Error:", t), e.json({ error: "Failed to fetch paths" }, 500);
26348
26396
  }
26349
26397
  });
26350
- var tC = new $y();
26351
- function nC(e) {
26398
+ var nC = new $y();
26399
+ function rC(e) {
26352
26400
  let t = (e || "").trim().toLowerCase(), n = dx()?.taxonomies || {};
26353
26401
  return n[t] ? t : n[`${t}s`] ? `${t}s` : t.endsWith("s") && n[t.slice(0, -1)] ? t.slice(0, -1) : t;
26354
26402
  }
26355
- var rC = X({
26403
+ var iC = X({
26356
26404
  id: c_(),
26357
26405
  taxonomy: J(),
26358
26406
  key: J(),
@@ -26362,14 +26410,14 @@ var rC = X({
26362
26410
  data: tv(k_()),
26363
26411
  createdAt: J(),
26364
26412
  updatedAt: J()
26365
- }), iC = X({
26413
+ }), aC = X({
26366
26414
  taxonomy: J(),
26367
- items: z_(rC),
26415
+ items: z_(iC),
26368
26416
  total: c_()
26369
- }).openapi("TaxonomyResponse"), aC = X({
26417
+ }).openapi("TaxonomyResponse"), oC = X({
26370
26418
  error: J(),
26371
26419
  details: J().optional()
26372
- }).openapi("ErrorResponse"), oC = eb({
26420
+ }).openapi("ErrorResponse"), sC = eb({
26373
26421
  method: "get",
26374
26422
  path: "/{taxonomy}",
26375
26423
  summary: "Fetch Public Taxonomy Terms",
@@ -26379,17 +26427,17 @@ var rC = X({
26379
26427
  responses: {
26380
26428
  200: {
26381
26429
  description: "List of taxonomy terms",
26382
- content: { "application/json": { schema: iC } }
26430
+ content: { "application/json": { schema: aC } }
26383
26431
  },
26384
26432
  500: {
26385
26433
  description: "Server error",
26386
- content: { "application/json": { schema: aC } }
26434
+ content: { "application/json": { schema: oC } }
26387
26435
  }
26388
26436
  }
26389
26437
  });
26390
- tC.openapi(oC, async (e) => {
26438
+ nC.openapi(sC, async (e) => {
26391
26439
  try {
26392
- 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";
26393
26441
  if (!o) {
26394
26442
  let t = await n.get(a);
26395
26443
  if (t) return e.header("X-Cache", "HIT"), e.json(t);
@@ -26423,7 +26471,7 @@ tC.openapi(oC, async (e) => {
26423
26471
  return console.error("[Public Taxonomy API] Error fetching terms:", t), e.json({ error: "Failed to fetch taxonomy terms" }, 500);
26424
26472
  }
26425
26473
  });
26426
- var $ = new $y(), sC = !1;
26474
+ var $ = new $y(), cC = !1;
26427
26475
  $.use("*", t()), $.use("/media/*", t({
26428
26476
  origin: "*",
26429
26477
  allowMethods: [
@@ -26444,13 +26492,13 @@ $.use("*", t()), $.use("/media/*", t({
26444
26492
  let n = new URL(e.req.url), r = (e.req.header("host") || n.hostname).split(":")[0];
26445
26493
  e.set("currentDomain", r);
26446
26494
  let i = wb(e);
26447
- if (e.set("db", i), !sC) try {
26448
- await Mb(i), sC = !0;
26495
+ if (e.set("db", i), !cC) try {
26496
+ await Mb(i), cC = !0;
26449
26497
  } catch (e) {
26450
26498
  console.error("❌ [CMS Server] Failed to initialize system tables on cold start:", e);
26451
26499
  }
26452
26500
  await t();
26453
- }), $.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", {
26454
26502
  openapi: "3.0.0",
26455
26503
  info: {
26456
26504
  title: "KAMA Engine Public API",