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