@brightsideoy/kama 1.0.0-alpha.4 → 1.0.0-alpha.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli.js +156 -278
- package/brightsideoy-kama-1.0.0-alpha.5.tgz +0 -0
- package/dist/assets/index-CHQAZAAH.css +1 -0
- package/dist/assets/{index-CiW_gEtr.js → index-g1H_KYcg.js} +46 -46
- package/dist/{dist-rKCoLpZH.js → dist-BmDMKgKk.js} +415 -367
- package/dist/index.html +2 -2
- package/dist/index.js +415 -367
- package/dist/schema-compiler.js +1 -1
- package/package.json +1 -1
- package/templates/astro-starter/src/middleware.ts +115 -42
- package/templates/astro-starter/src/pages/[...slug].astro +51 -31
- package/dist/assets/index-DHKk9t5r.css +0 -1
|
@@ -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
|
|
186
|
+
function w(e) {
|
|
187
187
|
return typeof e == "string";
|
|
188
188
|
}
|
|
189
|
-
function
|
|
189
|
+
function T(e) {
|
|
190
190
|
return Object.fromEntries(Object.entries(e).sort(([e], [t]) => e.localeCompare(t)));
|
|
191
191
|
}
|
|
192
|
-
var
|
|
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
|
|
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
|
-
|
|
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(
|
|
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
|
|
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
|
|
446
|
+
var de = class {
|
|
447
447
|
transform(e, t, n) {
|
|
448
|
-
let { type: r, values: i } =
|
|
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
|
-
},
|
|
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(
|
|
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 } =
|
|
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
|
|
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" ?
|
|
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:
|
|
21892
|
-
if (this.backgroundFetchSize =
|
|
21893
|
-
if (this.#s =
|
|
21894
|
-
let
|
|
21895
|
-
if (!
|
|
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
|
|
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}
|
|
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
|
|
23035
|
-
if (!
|
|
23036
|
-
let
|
|
23037
|
-
for (let e of
|
|
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}`),
|
|
23043
|
+
!t.startsWith("http://") && !t.startsWith("https://") && (t = `https://${t}`), p.add(t.replace(/\/+$/, ""));
|
|
23040
23044
|
}
|
|
23041
|
-
|
|
23042
|
-
let
|
|
23043
|
-
await this.purgeInternalWorkerCache(e, t, n,
|
|
23044
|
-
let
|
|
23045
|
-
if (i.length > 0 &&
|
|
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() &&
|
|
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
|
|
23056
|
-
let n =
|
|
23057
|
-
r
|
|
23058
|
-
for (let e of
|
|
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.
|
|
23064
|
+
r.add(`${t}${n}`), i.add(`${t}${n}`);
|
|
23061
23065
|
}
|
|
23062
|
-
let a =
|
|
23063
|
-
if (
|
|
23064
|
-
else i.
|
|
23065
|
-
for (let e of
|
|
23066
|
-
if (await this.callAstroPurge(e, { urls:
|
|
23067
|
-
|
|
23068
|
-
|
|
23069
|
-
|
|
23070
|
-
|
|
23071
|
-
|
|
23072
|
-
|
|
23073
|
-
|
|
23074
|
-
|
|
23075
|
-
console.log(
|
|
23076
|
-
|
|
23077
|
-
|
|
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
|
-
|
|
23087
|
-
|
|
23088
|
-
|
|
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)
|
|
23119
|
-
|
|
23120
|
-
|
|
23121
|
-
|
|
23122
|
-
|
|
23123
|
-
|
|
23124
|
-
|
|
23125
|
-
|
|
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: {
|
|
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),
|
|
23505
|
-
if (
|
|
23506
|
-
let e =
|
|
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(...
|
|
23520
|
+
`).all(...T);
|
|
23509
23521
|
(Array.isArray(n) ? n : n?.results || []).forEach((e) => {
|
|
23510
|
-
|
|
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(...
|
|
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(
|
|
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:
|
|
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,
|
|
23560
|
-
if (
|
|
23561
|
-
let e = await t.prepare("SELECT dataJson FROM trees WHERE id = ? OR key = ? LIMIT 1").get(Number(
|
|
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
|
-
|
|
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 &&
|
|
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 :
|
|
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,
|
|
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",
|
|
24194
|
-
typeof
|
|
24195
|
-
let
|
|
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,
|
|
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 ").
|
|
24204
|
-
|
|
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,
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
|
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
|
-
|
|
24821
|
+
ue[e] = Bx(ue[e] || {}, t);
|
|
24809
24822
|
});
|
|
24810
24823
|
});
|
|
24811
|
-
let
|
|
24824
|
+
let de = g ? {
|
|
24812
24825
|
...g,
|
|
24813
|
-
fields:
|
|
24814
|
-
} : null,
|
|
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
|
-
|
|
24831
|
+
j[e] = Bx(j[e] || {}, t);
|
|
24819
24832
|
});
|
|
24820
24833
|
});
|
|
24821
24834
|
let fe = _ ? {
|
|
24822
24835
|
..._,
|
|
24823
|
-
fields:
|
|
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:
|
|
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,
|
|
25100
|
-
|
|
25101
|
-
let
|
|
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
|
-
|
|
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
|
-
|
|
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)),
|
|
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
|
|
25316
|
-
let
|
|
25317
|
-
await Promise.all(
|
|
25318
|
-
let
|
|
25319
|
-
n && n !== "all" && (
|
|
25320
|
-
let
|
|
25321
|
-
if (
|
|
25322
|
-
let t = Array.isArray(
|
|
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
|
-
|
|
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
|
-
)`,
|
|
25355
|
+
)`, u.push(e, ...t);
|
|
25332
25356
|
}
|
|
25333
25357
|
}
|
|
25334
|
-
let
|
|
25335
|
-
|
|
25336
|
-
let
|
|
25337
|
-
|
|
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(
|
|
25340
|
-
t.data.initialItems =
|
|
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
|
|
25386
|
+
async function dS(e, t, n, r, i, a = !1, o, s) {
|
|
25363
25387
|
if (!t) return { blocks: [] };
|
|
25364
|
-
let
|
|
25365
|
-
if (!
|
|
25366
|
-
let
|
|
25367
|
-
if (
|
|
25368
|
-
let
|
|
25369
|
-
|
|
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
|
-
|
|
25395
|
+
h.has(t) || h.set(t, []), h.get(t).push(e);
|
|
25372
25396
|
});
|
|
25373
|
-
for (let t of
|
|
25374
|
-
let n =
|
|
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]),
|
|
25377
|
-
for (;
|
|
25378
|
-
|
|
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),
|
|
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
|
|
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
|
-
|
|
25399
|
-
|
|
25400
|
-
|
|
25401
|
-
|
|
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:
|
|
25406
|
-
componentId:
|
|
25407
|
-
data:
|
|
25430
|
+
blockId: d,
|
|
25431
|
+
componentId: l,
|
|
25432
|
+
data: f
|
|
25408
25433
|
}
|
|
25409
25434
|
};
|
|
25410
|
-
})),
|
|
25411
|
-
for (let e of
|
|
25412
|
-
if (
|
|
25413
|
-
blocks:
|
|
25414
|
-
subRegions:
|
|
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
|
|
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
|
|
25438
|
-
if (Array.isArray(e)) return e.map(
|
|
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,
|
|
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,
|
|
25483
|
+
return Object.fromEntries(Object.entries(e).map(([e, t]) => [e, pS(t)]));
|
|
25459
25484
|
}
|
|
25460
|
-
async function
|
|
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) =>
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
25625
|
+
async function xS(e) {
|
|
25601
25626
|
try {
|
|
25602
|
-
let t = e.get("db"), n = sS(), r = new URL(e.req.url),
|
|
25603
|
-
|
|
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
|
-
|
|
25630
|
+
d = decodeURIComponent(d);
|
|
25606
25631
|
} catch {}
|
|
25607
|
-
|
|
25608
|
-
let
|
|
25609
|
-
if (!
|
|
25610
|
-
let
|
|
25611
|
-
if (!
|
|
25612
|
-
let
|
|
25613
|
-
if (
|
|
25614
|
-
redirect:
|
|
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
|
|
25618
|
-
if (
|
|
25619
|
-
else if (/^\d+$/.test(
|
|
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 =
|
|
25622
|
-
|
|
25646
|
+
let e = d.split("/").pop() || d;
|
|
25647
|
+
y = await t.prepare("SELECT * FROM content_nodes WHERE slug = ?").get(e);
|
|
25623
25648
|
}
|
|
25624
|
-
if (!
|
|
25625
|
-
let
|
|
25626
|
-
if (
|
|
25627
|
-
let e = await t.prepare("SELECT snapshotJson FROM node_revisions WHERE nodeId = ? AND version = ?").get(
|
|
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
|
-
|
|
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
|
|
25635
|
-
!
|
|
25636
|
-
let
|
|
25637
|
-
if (
|
|
25638
|
-
let e = await t.prepare("SELECT dataJson FROM trees WHERE id = ? OR key = ? LIMIT 1").get(Number(
|
|
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 ?
|
|
25666
|
+
t.defaultLanguage ? C = String(t.defaultLanguage).trim() : t.language && (C = String(t.language).trim());
|
|
25642
25667
|
} catch {}
|
|
25643
25668
|
}
|
|
25644
|
-
let
|
|
25645
|
-
if (
|
|
25646
|
-
if (
|
|
25647
|
-
else if (
|
|
25648
|
-
let e = typeof
|
|
25649
|
-
e.defaultLanguage ?
|
|
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
|
|
25653
|
-
if (!
|
|
25654
|
-
let t = await
|
|
25655
|
-
if (t)
|
|
25656
|
-
|
|
25657
|
-
|
|
25658
|
-
|
|
25659
|
-
|
|
25660
|
-
|
|
25661
|
-
|
|
25662
|
-
|
|
25663
|
-
|
|
25664
|
-
|
|
25665
|
-
|
|
25666
|
-
|
|
25667
|
-
|
|
25668
|
-
|
|
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
|
|
25671
|
-
if (
|
|
25672
|
-
j = typeof
|
|
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 && (
|
|
25675
|
-
let
|
|
25676
|
-
for (let [e, t] of Object.entries(
|
|
25677
|
-
let
|
|
25678
|
-
|
|
25679
|
-
let
|
|
25680
|
-
delete
|
|
25681
|
-
let
|
|
25682
|
-
if (!
|
|
25683
|
-
let
|
|
25684
|
-
if (
|
|
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(
|
|
25686
|
-
|
|
25687
|
-
let t = {}, n =
|
|
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
|
|
25693
|
-
return !
|
|
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:
|
|
25698
|
-
language: e.language?.trim() ||
|
|
25699
|
-
path: `${
|
|
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
|
-
|
|
25705
|
-
let
|
|
25706
|
-
if (
|
|
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 = +!!
|
|
25712
|
-
|
|
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
|
|
25715
|
-
let
|
|
25747
|
+
let Ee = {}, De = {}, Oe = await Promise.all(Te.map(async (e) => {
|
|
25748
|
+
let i = e.region || "main", a = {};
|
|
25716
25749
|
try {
|
|
25717
|
-
|
|
25750
|
+
a = (typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson) || {};
|
|
25718
25751
|
} catch {}
|
|
25719
|
-
|
|
25720
|
-
|
|
25721
|
-
|
|
25722
|
-
|
|
25723
|
-
|
|
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:
|
|
25727
|
-
componentId:
|
|
25728
|
-
data:
|
|
25760
|
+
blockId: d,
|
|
25761
|
+
componentId: l,
|
|
25762
|
+
data: f
|
|
25729
25763
|
}
|
|
25730
25764
|
};
|
|
25731
25765
|
}));
|
|
25732
|
-
for (let e of
|
|
25733
|
-
let
|
|
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
|
-
...(
|
|
25776
|
+
...(_e ? ie.nodeLayouts?.[_e] || ie.layouts?.[_e] : null)?.regions || { main: { label: "Content" } }
|
|
25743
25777
|
};
|
|
25744
|
-
for (let [e,
|
|
25745
|
-
let
|
|
25746
|
-
if (
|
|
25747
|
-
let
|
|
25748
|
-
if (
|
|
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:
|
|
25751
|
-
inheritedFromTitle:
|
|
25752
|
-
},
|
|
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:
|
|
25755
|
-
inheritedFromTitle:
|
|
25788
|
+
inheritedFromId: i.inheritedFromId,
|
|
25789
|
+
inheritedFromTitle: i.inheritedFromTitle
|
|
25756
25790
|
});
|
|
25757
25791
|
}
|
|
25758
25792
|
}
|
|
25759
|
-
await Promise.all(Object.keys(
|
|
25760
|
-
let
|
|
25761
|
-
|
|
25762
|
-
|
|
25763
|
-
|
|
25764
|
-
|
|
25765
|
-
|
|
25766
|
-
|
|
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 !
|
|
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
|
|
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
|
-
}),
|
|
25827
|
+
}), CS = X({
|
|
25784
25828
|
error: J(),
|
|
25785
25829
|
details: J().optional()
|
|
25786
|
-
}).openapi("ErrorResponse"),
|
|
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"),
|
|
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:
|
|
25853
|
+
query: SS
|
|
25806
25854
|
},
|
|
25807
25855
|
responses: {
|
|
25808
25856
|
200: {
|
|
25809
25857
|
description: "Fully hydrated CMS Node",
|
|
25810
|
-
content: { "application/json": { schema:
|
|
25858
|
+
content: { "application/json": { schema: wS } }
|
|
25811
25859
|
},
|
|
25812
25860
|
404: {
|
|
25813
25861
|
description: "Node or Channel not found",
|
|
25814
|
-
content: { "application/json": { schema:
|
|
25862
|
+
content: { "application/json": { schema: CS } }
|
|
25815
25863
|
},
|
|
25816
25864
|
500: {
|
|
25817
25865
|
description: "Server error during hydration",
|
|
25818
|
-
content: { "application/json": { schema:
|
|
25866
|
+
content: { "application/json": { schema: CS } }
|
|
25819
25867
|
}
|
|
25820
25868
|
}
|
|
25821
25869
|
});
|
|
25822
|
-
oS.openapi(
|
|
25823
|
-
var
|
|
25824
|
-
function
|
|
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
|
|
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
|
|
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
|
-
}),
|
|
25896
|
+
}), jS = X({
|
|
25849
25897
|
error: J(),
|
|
25850
25898
|
details: J().optional()
|
|
25851
|
-
}).openapi("ErrorResponse"),
|
|
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_(
|
|
25865
|
-
})).openapi("TreeItem"),
|
|
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_(
|
|
25872
|
-
}).catchall(k_()).openapi("TreeResponse"),
|
|
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:
|
|
25880
|
-
query:
|
|
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:
|
|
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:
|
|
25937
|
+
content: { "application/json": { schema: jS } }
|
|
25890
25938
|
},
|
|
25891
25939
|
500: {
|
|
25892
25940
|
description: "Server error during hydration",
|
|
25893
|
-
content: { "application/json": { schema:
|
|
25941
|
+
content: { "application/json": { schema: jS } }
|
|
25894
25942
|
}
|
|
25895
25943
|
}
|
|
25896
25944
|
});
|
|
25897
|
-
|
|
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 =
|
|
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
|
|
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
|
|
25995
|
-
function
|
|
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
|
|
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
|
|
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
|
|
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
|
|
26037
|
-
if (Array.isArray(e)) return e.map(
|
|
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,
|
|
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,
|
|
26105
|
+
return Object.fromEntries(Object.entries(e).map(([e, t]) => [e, BS(t)]));
|
|
26058
26106
|
}
|
|
26059
|
-
async function
|
|
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) =>
|
|
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
|
|
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
|
|
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"),
|
|
26150
|
+
}).openapi("ErrorResponse"), GS = X({
|
|
26103
26151
|
id: G_([c_(), J()]),
|
|
26104
26152
|
key: J()
|
|
26105
|
-
}).catchall(k_()).openapi("ChannelResponse"),
|
|
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:
|
|
26113
|
-
query:
|
|
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:
|
|
26166
|
+
content: { "application/json": { schema: GS } }
|
|
26119
26167
|
},
|
|
26120
26168
|
404: {
|
|
26121
26169
|
description: "Channel not found or inactive",
|
|
26122
|
-
content: { "application/json": { schema:
|
|
26170
|
+
content: { "application/json": { schema: WS } }
|
|
26123
26171
|
},
|
|
26124
26172
|
500: {
|
|
26125
26173
|
description: "Server error during hydration",
|
|
26126
|
-
content: { "application/json": { schema:
|
|
26174
|
+
content: { "application/json": { schema: WS } }
|
|
26127
26175
|
}
|
|
26128
26176
|
}
|
|
26129
26177
|
});
|
|
26130
|
-
|
|
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 =
|
|
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 _ =
|
|
26195
|
+
let _ = zS({
|
|
26148
26196
|
...h,
|
|
26149
26197
|
...c
|
|
26150
26198
|
}, m);
|
|
26151
|
-
_ = await ux(t, _), _ =
|
|
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
|
|
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
|
|
26166
|
-
function
|
|
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
|
|
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
|
-
|
|
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":
|
|
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
|
-
}), _ =
|
|
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
|
|
26279
|
-
function
|
|
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
|
|
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
|
-
}),
|
|
26342
|
+
}), $S = z_(J()).openapi("PathsResponse"), eC = X({
|
|
26295
26343
|
error: J(),
|
|
26296
26344
|
details: J().optional()
|
|
26297
|
-
}).openapi("ErrorResponse"),
|
|
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:
|
|
26351
|
+
request: { query: QS },
|
|
26304
26352
|
responses: {
|
|
26305
26353
|
200: {
|
|
26306
26354
|
description: "Array of valid public URL paths",
|
|
26307
|
-
content: { "application/json": { schema:
|
|
26355
|
+
content: { "application/json": { schema: $S } }
|
|
26308
26356
|
},
|
|
26309
26357
|
500: {
|
|
26310
26358
|
description: "Server error fetching paths",
|
|
26311
|
-
content: { "application/json": { schema:
|
|
26359
|
+
content: { "application/json": { schema: eC } }
|
|
26312
26360
|
}
|
|
26313
26361
|
}
|
|
26314
26362
|
});
|
|
26315
|
-
|
|
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 =
|
|
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
|
|
26351
|
-
function
|
|
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
|
|
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
|
-
}),
|
|
26413
|
+
}), aC = X({
|
|
26366
26414
|
taxonomy: J(),
|
|
26367
|
-
items: z_(
|
|
26415
|
+
items: z_(iC),
|
|
26368
26416
|
total: c_()
|
|
26369
|
-
}).openapi("TaxonomyResponse"),
|
|
26417
|
+
}).openapi("TaxonomyResponse"), oC = X({
|
|
26370
26418
|
error: J(),
|
|
26371
26419
|
details: J().optional()
|
|
26372
|
-
}).openapi("ErrorResponse"),
|
|
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:
|
|
26430
|
+
content: { "application/json": { schema: aC } }
|
|
26383
26431
|
},
|
|
26384
26432
|
500: {
|
|
26385
26433
|
description: "Server error",
|
|
26386
|
-
content: { "application/json": { schema:
|
|
26434
|
+
content: { "application/json": { schema: oC } }
|
|
26387
26435
|
}
|
|
26388
26436
|
}
|
|
26389
26437
|
});
|
|
26390
|
-
|
|
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 =
|
|
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(),
|
|
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), !
|
|
26448
|
-
await Mb(i),
|
|
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",
|
|
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",
|