@brightsideoy/kama 0.1.0-alpha.155 → 0.1.0-alpha.157
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 +229 -231
- package/dist/assets/index-BesA3e7A.js +164 -0
- package/dist/assets/index-D6yHZ_u1.css +1 -0
- package/dist/{dist-C-WAK7EF.js → dist-mic4UZBb.js} +691 -439
- package/dist/index.html +2 -2
- package/dist/index.js +693 -439
- package/dist/schema-compiler.js +1 -1
- package/package.json +1 -1
- package/schema.sql +2 -2
- package/templates/astro-starter/src/components/blocks/BlockRenderer.astro +1 -0
- package/templates/astro-starter/src/components/blocks/ColumnLayout.astro +1 -0
- package/templates/astro-starter/src/components/blocks/HeaderImage.astro +1 -0
- package/templates/astro-starter/src/components/blocks/HtmlBlock.astro +2 -1
- package/templates/astro-starter/src/components/blocks/ImageBlock.astro +39 -71
- package/templates/astro-starter/src/components/blocks/TextBlock.astro +2 -0
- package/templates/astro-starter/src/components/global/Breadcrumb.astro +2 -0
- package/templates/astro-starter/src/components/global/Footer.astro +2 -0
- package/templates/astro-starter/src/components/global/Header.astro +100 -28
- package/templates/astro-starter/src/components/{seo/SeoHead.astro → global/MetaHead.astro} +101 -49
- package/templates/astro-starter/src/components/global/NavigationMenu.astro +1 -0
- package/templates/astro-starter/src/components/ui/KamaImage.astro +114 -67
- package/templates/astro-starter/src/layouts/SkeletonLayout.astro +5 -3
- package/templates/astro-starter/src/layouts/StandardLayout.astro +14 -5
- package/templates/astro-starter/src/lib/cms.ts +48 -0
- package/templates/astro-starter/src/lib/media/kama-image-service.ts +16 -1
- package/templates/astro-starter/src/lib/media/media-proxy.ts +8 -6
- package/templates/astro-starter/src/lib/media/media-url.ts +65 -1
- package/templates/astro-starter/src/middleware.ts +131 -18
- package/templates/astro-starter/src/pages/[...slug].astro +10 -9
- package/definitions/_page.yaml +0 -52
- package/dist/assets/index-DGHRgyms.js +0 -164
- package/dist/assets/index-EaDn3OUJ.css +0 -1
- /package/templates/astro-starter/{public/css → src/styles}/standard-theme.css +0 -0
package/dist/index.js
CHANGED
|
@@ -4815,10 +4815,10 @@ var u = /* @__PURE__ */ o({
|
|
|
4815
4815
|
users: "\n id TEXT PRIMARY KEY,\n email TEXT UNIQUE NOT NULL,\n name TEXT NOT NULL,\n globalRole TEXT DEFAULT 'editor',\n createdAt TEXT DEFAULT CURRENT_TIMESTAMP,\n updatedAt TEXT DEFAULT CURRENT_TIMESTAMP\n ",
|
|
4816
4816
|
user_accounts: "\n id TEXT PRIMARY KEY,\n userId TEXT NOT NULL,\n provider TEXT NOT NULL,\n providerAccountId TEXT NOT NULL,\n passwordHash TEXT NOT NULL,\n createdAt TEXT DEFAULT CURRENT_TIMESTAMP,\n FOREIGN KEY (userId) REFERENCES users(id) ON DELETE CASCADE,\n UNIQUE(provider, providerAccountId)\n ",
|
|
4817
4817
|
sessions: "\n id TEXT PRIMARY KEY,\n userId TEXT NOT NULL,\n expiresAt TEXT NOT NULL,\n createdAt TEXT DEFAULT CURRENT_TIMESTAMP,\n FOREIGN KEY (userId) REFERENCES users(id) ON DELETE CASCADE\n ",
|
|
4818
|
-
channels: "\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n key TEXT UNIQUE NOT NULL,\n label TEXT NOT NULL,\n channelType TEXT,\n domain TEXT,\n baseUrl TEXT,\n defaultLanguage TEXT
|
|
4818
|
+
channels: "\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n key TEXT UNIQUE NOT NULL,\n label TEXT NOT NULL,\n channelType TEXT,\n domain TEXT,\n baseUrl TEXT,\n defaultLanguage TEXT,\n isHidden INTEGER NOT NULL DEFAULT 0,\n dataJson TEXT,\n createdById TEXT,\n updatedById TEXT,\n createdAt TEXT DEFAULT CURRENT_TIMESTAMP,\n updatedAt TEXT DEFAULT CURRENT_TIMESTAMP,\n FOREIGN KEY (createdById) REFERENCES users(id) ON DELETE SET NULL,\n FOREIGN KEY (updatedById) REFERENCES users(id) ON DELETE SET NULL\n ",
|
|
4819
4819
|
trees: "\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n key TEXT UNIQUE NOT NULL,\n label TEXT NOT NULL,\n treeType TEXT,\n channelId INTEGER,\n isHidden INTEGER NOT NULL DEFAULT 0,\n dataJson TEXT,\n createdById TEXT,\n updatedById TEXT,\n createdAt TEXT DEFAULT CURRENT_TIMESTAMP,\n updatedAt TEXT DEFAULT CURRENT_TIMESTAMP,\n FOREIGN KEY (channelId) REFERENCES channels(id) ON DELETE SET NULL,\n FOREIGN KEY (createdById) REFERENCES users(id) ON DELETE SET NULL,\n FOREIGN KEY (updatedById) REFERENCES users(id) ON DELETE SET NULL\n ",
|
|
4820
4820
|
channel_trees: "\n channelId INTEGER NOT NULL,\n treeId INTEGER NOT NULL,\n key TEXT NOT NULL DEFAULT 'main',\n metaJson TEXT,\n PRIMARY KEY (channelId, treeId, key),\n FOREIGN KEY (channelId) REFERENCES channels(id) ON DELETE CASCADE,\n FOREIGN KEY (treeId) REFERENCES trees(id) ON DELETE CASCADE\n ",
|
|
4821
|
-
content_nodes: "\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n contentType TEXT NOT NULL,\n title TEXT NOT NULL,\n slug TEXT,\n language TEXT
|
|
4821
|
+
content_nodes: "\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n contentType TEXT NOT NULL,\n title TEXT NOT NULL,\n slug TEXT,\n language TEXT,\n isHidden INTEGER NOT NULL DEFAULT 0,\n status TEXT DEFAULT 'draft',\n hasUnpublishedChanges INTEGER DEFAULT 0,\n disabledRegionsJson TEXT DEFAULT '{}',\n dataJson TEXT,\n draftDataJson TEXT,\n publishedDataJson TEXT,\n publishedAt TEXT,\n createdById TEXT,\n updatedById TEXT,\n createdAt TEXT DEFAULT CURRENT_TIMESTAMP,\n updatedAt TEXT DEFAULT CURRENT_TIMESTAMP,\n deletedAt TEXT,\n FOREIGN KEY (createdById) REFERENCES users(id) ON DELETE SET NULL,\n FOREIGN KEY (updatedById) REFERENCES users(id) ON DELETE SET NULL\n ",
|
|
4822
4822
|
node_channels: "\n nodeId INTEGER NOT NULL,\n channelId INTEGER NOT NULL,\n PRIMARY KEY (nodeId, channelId),\n FOREIGN KEY (nodeId) REFERENCES content_nodes(id) ON DELETE CASCADE,\n FOREIGN KEY (channelId) REFERENCES channels(id) ON DELETE CASCADE\n ",
|
|
4823
4823
|
tree_nodes: "\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n treeId INTEGER NOT NULL,\n contentId INTEGER NOT NULL,\n parentId INTEGER,\n sortOrder INTEGER DEFAULT 0,\n FOREIGN KEY (treeId) REFERENCES trees(id) ON DELETE CASCADE,\n FOREIGN KEY (contentId) REFERENCES content_nodes(id) ON DELETE CASCADE,\n FOREIGN KEY (parentId) REFERENCES tree_nodes(id) ON DELETE CASCADE\n ",
|
|
4824
4824
|
content_blocks: "\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n contentId INTEGER NOT NULL,\n region TEXT DEFAULT 'main',\n elementType TEXT NOT NULL,\n dataJson TEXT,\n sortOrder INTEGER DEFAULT 0,\n isDraft INTEGER NOT NULL DEFAULT 1,\n FOREIGN KEY (contentId) REFERENCES content_nodes(id) ON DELETE CASCADE\n ",
|
|
@@ -5583,7 +5583,7 @@ var b = { hasSubscribers: !1 }, x = b, S = b, C = typeof performance == "object"
|
|
|
5583
5583
|
async clear() {
|
|
5584
5584
|
this.cache.clear();
|
|
5585
5585
|
}
|
|
5586
|
-
},
|
|
5586
|
+
}, P = class {
|
|
5587
5587
|
kv;
|
|
5588
5588
|
constructor(e) {
|
|
5589
5589
|
this.kv = e;
|
|
@@ -5600,7 +5600,7 @@ var b = { hasSubscribers: !1 }, x = b, S = b, C = typeof performance == "object"
|
|
|
5600
5600
|
this.kv && await this.kv.delete(e);
|
|
5601
5601
|
}
|
|
5602
5602
|
async clear() {}
|
|
5603
|
-
},
|
|
5603
|
+
}, te = class {
|
|
5604
5604
|
async get() {
|
|
5605
5605
|
return null;
|
|
5606
5606
|
}
|
|
@@ -5610,7 +5610,7 @@ var b = { hasSubscribers: !1 }, x = b, S = b, C = typeof performance == "object"
|
|
|
5610
5610
|
}, F = null;
|
|
5611
5611
|
function I(e) {
|
|
5612
5612
|
let t = process.env.CACHE_DRIVER || "lru";
|
|
5613
|
-
return t === "none" || t === "off" || t === "false" ? new
|
|
5613
|
+
return t === "none" || t === "off" || t === "false" ? new te() : e?.env?.CMS_CACHE_KV ? new P(e.env.CMS_CACHE_KV) : t === "lru" ? (F ||= new ee(), F) : new te();
|
|
5614
5614
|
}
|
|
5615
5615
|
//#endregion
|
|
5616
5616
|
//#region server/storage/local.ts
|
|
@@ -5683,7 +5683,7 @@ var L = class {
|
|
|
5683
5683
|
if (e.code !== "ENOENT") throw e;
|
|
5684
5684
|
}
|
|
5685
5685
|
}
|
|
5686
|
-
},
|
|
5686
|
+
}, ne = class {
|
|
5687
5687
|
async process(e, t, n) {
|
|
5688
5688
|
let r = await import(
|
|
5689
5689
|
/* @vite-ignore */
|
|
@@ -5710,7 +5710,7 @@ var L = class {
|
|
|
5710
5710
|
return console.warn("⚠️ [SharpImageOptimizer] Processing failed, returning raw buffer."), e;
|
|
5711
5711
|
}
|
|
5712
5712
|
}
|
|
5713
|
-
},
|
|
5713
|
+
}, re = class {
|
|
5714
5714
|
bucket;
|
|
5715
5715
|
publicDomain;
|
|
5716
5716
|
constructor(e, t) {
|
|
@@ -5755,7 +5755,7 @@ var L = class {
|
|
|
5755
5755
|
async delete(e) {
|
|
5756
5756
|
await this.bucket.delete(e);
|
|
5757
5757
|
}
|
|
5758
|
-
},
|
|
5758
|
+
}, ie = class {
|
|
5759
5759
|
async process(e, t, n) {
|
|
5760
5760
|
let { env: r, key: i, req: a } = n;
|
|
5761
5761
|
if (r.IMAGES) try {
|
|
@@ -5792,18 +5792,18 @@ var L = class {
|
|
|
5792
5792
|
};
|
|
5793
5793
|
//#endregion
|
|
5794
5794
|
//#region server/storage/factory.ts
|
|
5795
|
-
function
|
|
5795
|
+
function ae(e) {
|
|
5796
5796
|
return e.KAMA_RUNTIME === "cloudflare" || e.MEDIA_BUCKET ? {
|
|
5797
|
-
storage: new
|
|
5798
|
-
optimizer: new
|
|
5797
|
+
storage: new re(e.MEDIA_BUCKET, e.CDN_DOMAIN || ""),
|
|
5798
|
+
optimizer: new ie()
|
|
5799
5799
|
} : {
|
|
5800
5800
|
storage: new L(e.LOCAL_MEDIA_PATH),
|
|
5801
|
-
optimizer: new
|
|
5801
|
+
optimizer: new ne()
|
|
5802
5802
|
};
|
|
5803
5803
|
}
|
|
5804
5804
|
//#endregion
|
|
5805
5805
|
//#region server/utils/node-assets-interceptor.ts
|
|
5806
|
-
function
|
|
5806
|
+
function R(e) {
|
|
5807
5807
|
if (!e || typeof e != "object") return {
|
|
5808
5808
|
cleanedData: e,
|
|
5809
5809
|
assetRefs: []
|
|
@@ -5881,7 +5881,7 @@ function z(e) {
|
|
|
5881
5881
|
}
|
|
5882
5882
|
return null;
|
|
5883
5883
|
}
|
|
5884
|
-
async function
|
|
5884
|
+
async function B(e, t) {
|
|
5885
5885
|
if (!t || typeof t != "object") return t;
|
|
5886
5886
|
let n = /* @__PURE__ */ new Set(), r = (e) => {
|
|
5887
5887
|
if (!e) return;
|
|
@@ -5994,7 +5994,7 @@ async function se(e, t) {
|
|
|
5994
5994
|
}
|
|
5995
5995
|
//#endregion
|
|
5996
5996
|
//#region src/utils/schema-loader.ts
|
|
5997
|
-
function
|
|
5997
|
+
function se(e) {
|
|
5998
5998
|
return e ? {
|
|
5999
5999
|
nodes: e.nodes || {},
|
|
6000
6000
|
trees: e.trees || {},
|
|
@@ -6013,7 +6013,7 @@ function ce(e) {
|
|
|
6013
6013
|
}
|
|
6014
6014
|
//#endregion
|
|
6015
6015
|
//#region server/services/cache-manager.ts
|
|
6016
|
-
var
|
|
6016
|
+
var V = class {
|
|
6017
6017
|
env;
|
|
6018
6018
|
constructor(e) {
|
|
6019
6019
|
this.env = e || {};
|
|
@@ -6025,7 +6025,8 @@ var B = class {
|
|
|
6025
6025
|
apiToken: e.env?.CLOUDFLARE_API_TOKEN || this.env.CLOUDFLARE_API_TOKEN,
|
|
6026
6026
|
frontendUrl: (e.env?.PUBLIC_FRONTEND_URL || this.env.PUBLIC_FRONTEND_URL || "http://localhost:4321").replace(/\/+$/, ""),
|
|
6027
6027
|
cdnDomain: t ? t.replace(/^https?:\/\//, "").replace(/\/+$/, "") : "localhost:8787",
|
|
6028
|
-
frontendWorker: e.env?.FRONTEND_WORKER || this.env.FRONTEND_WORKER
|
|
6028
|
+
frontendWorker: e.env?.FRONTEND_WORKER || this.env.FRONTEND_WORKER,
|
|
6029
|
+
disableCachePurge: e.env?.DISABLE_CACHE_PURGE || this.env.DISABLE_CACHE_PURGE
|
|
6029
6030
|
};
|
|
6030
6031
|
}
|
|
6031
6032
|
isLocalEnv(e, t) {
|
|
@@ -6049,19 +6050,33 @@ var B = class {
|
|
|
6049
6050
|
return r && n && r.startsWith(`https://${n}/`) && !r.includes("/media/") && (r = r.replace(`https://${n}/`, `https://${n}/media/`)), r;
|
|
6050
6051
|
}
|
|
6051
6052
|
async callAstroPurge(e, t, n) {
|
|
6052
|
-
let { apiToken: r, frontendUrl: i } = this.getEnv(e)
|
|
6053
|
-
if (
|
|
6054
|
-
|
|
6055
|
-
|
|
6056
|
-
|
|
6057
|
-
|
|
6058
|
-
|
|
6059
|
-
|
|
6060
|
-
|
|
6061
|
-
|
|
6062
|
-
|
|
6053
|
+
let { apiToken: r, frontendUrl: i, frontendWorker: a, disableCachePurge: o } = this.getEnv(e);
|
|
6054
|
+
if (o === "true" || o === !0 || o === "1") return new Response(JSON.stringify({ skipped: !0 }), { status: 200 });
|
|
6055
|
+
let s = (n || i).replace(/\/+$/, ""), c = `${s}/api/purge`, l = { "Content-Type": "application/json" };
|
|
6056
|
+
if (r && (l.Authorization = `Bearer ${r}`), a && typeof a.fetch == "function") try {
|
|
6057
|
+
return await a.fetch(new Request(c, {
|
|
6058
|
+
method: "POST",
|
|
6059
|
+
headers: l,
|
|
6060
|
+
body: JSON.stringify(t)
|
|
6061
|
+
}));
|
|
6062
|
+
} catch (e) {
|
|
6063
|
+
return console.info(`[CacheManager] Worker binding purge call to ${c} failed silently:`, e?.message || e), new Response(JSON.stringify({ error: e?.message }), { status: 502 });
|
|
6064
|
+
}
|
|
6065
|
+
try {
|
|
6066
|
+
let e = new AbortController(), n = setTimeout(() => e.abort(), 1500);
|
|
6067
|
+
console.log(`[CacheManager] Dispatching POST purge request to: ${c}`);
|
|
6068
|
+
let r = await fetch(c, {
|
|
6069
|
+
method: "POST",
|
|
6070
|
+
headers: l,
|
|
6071
|
+
body: JSON.stringify(t),
|
|
6072
|
+
signal: e.signal
|
|
6073
|
+
});
|
|
6074
|
+
return clearTimeout(n), r;
|
|
6075
|
+
} catch (e) {
|
|
6076
|
+
return e.name === "AbortError" ? console.info(`[CacheManager] Purge request to ${c} timed out (dev server un-responsive).`) : e?.cause?.code === "ECONNREFUSED" || e?.code === "ECONNREFUSED" ? console.info(`[CacheManager] Frontend purge listener offline at ${s} (port not reachable).`) : console.warn(`[CacheManager] Non-fatal purge warning for ${c}:`, e?.message || e), new Response(JSON.stringify({ error: "Connection refused or timed out" }), { status: 503 });
|
|
6077
|
+
}
|
|
6063
6078
|
}
|
|
6064
|
-
async purgeInternalWorkerCache(e, t, n, r, i
|
|
6079
|
+
async purgeInternalWorkerCache(e, t, n, r, i) {
|
|
6065
6080
|
try {
|
|
6066
6081
|
let a = I(e);
|
|
6067
6082
|
if (n) {
|
|
@@ -6074,7 +6089,7 @@ var B = class {
|
|
|
6074
6089
|
let e = t.prepare("SELECT c.key, c.id FROM node_channels nc JOIN channels c ON nc.channelId = c.id WHERE nc.nodeId = ?"), r = typeof e.all == "function" ? await e.all(n) : await e.bind(n).all(), i = Array.isArray(r) ? r : r?.results || [];
|
|
6075
6090
|
i.length > 0 && (o = i.flatMap((e) => [String(e.id), e.key]).filter(Boolean));
|
|
6076
6091
|
}
|
|
6077
|
-
for (let t of o) await a.delete(`node:${t}:${i}:${e}`), await a.delete(`node:${t}:${i}:/${e}`);
|
|
6092
|
+
for (let t of o) i && (await a.delete(`node:${t}:${i}:${e}`), await a.delete(`node:${t}:${i}:/${e}`)), await a.delete(`node:${t}:${e}`), await a.delete(`node:${t}:/${e}`);
|
|
6078
6093
|
}
|
|
6079
6094
|
} catch (e) {
|
|
6080
6095
|
console.warn("[CacheManager] Failed to purge internal worker cache:", e);
|
|
@@ -6085,30 +6100,30 @@ var B = class {
|
|
|
6085
6100
|
try {
|
|
6086
6101
|
let i = t.prepare("SELECT slug, status, language FROM content_nodes WHERE id = ?"), a = (typeof i.get == "function" ? await i.get(n) : (await i.bind(n).all())?.results?.[0]) || {};
|
|
6087
6102
|
if (!a.slug) return;
|
|
6088
|
-
let o =
|
|
6089
|
-
for (let e of
|
|
6103
|
+
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();
|
|
6104
|
+
for (let e of c) if (e.baseUrl && typeof e.baseUrl == "string" && e.baseUrl.trim() !== "") {
|
|
6090
6105
|
let t = e.baseUrl.trim();
|
|
6091
|
-
!t.startsWith("http://") && !t.startsWith("https://") && (t = `https://${t}`),
|
|
6106
|
+
!t.startsWith("http://") && !t.startsWith("https://") && (t = `https://${t}`), p.add(t.replace(/\/+$/, ""));
|
|
6092
6107
|
}
|
|
6093
|
-
|
|
6094
|
-
let
|
|
6095
|
-
await this.purgeInternalWorkerCache(e, t, n,
|
|
6096
|
-
let
|
|
6097
|
-
for (let t of
|
|
6098
|
-
let n =
|
|
6099
|
-
if (
|
|
6100
|
-
else i.push(`https://${
|
|
6101
|
-
for (let e of
|
|
6102
|
-
if (await this.callAstroPurge(e, { urls: i }, t),
|
|
6108
|
+
p.size === 0 && f && p.add(f);
|
|
6109
|
+
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);
|
|
6110
|
+
await this.purgeInternalWorkerCache(e, t, n, d, u);
|
|
6111
|
+
let _ = this.getEnv(e).cdnDomain, { zoneId: v, apiToken: y } = this.getEnv(e);
|
|
6112
|
+
for (let t of p) {
|
|
6113
|
+
let n = d === "home" || !d ? t : `${t}/${d}`, i = [n, `${n}/`], a = u ? `&lang=${u}` : "";
|
|
6114
|
+
if (c.length > 0) for (let e of c) e.id && i.push(`https://${_}/api/v1/node/${d}?channelId=${e.id}${a}`), e.key && i.push(`https://${_}/api/v1/node/${d}?channelId=${e.key}${a}`);
|
|
6115
|
+
else i.push(`https://${_}/api/v1/node/${d}${u ? `?lang=${u}` : ""}`);
|
|
6116
|
+
for (let e of g) e && i.push(`${t}${e.startsWith("/") ? e : `/${e}`}`);
|
|
6117
|
+
if (await this.callAstroPurge(e, { urls: i }, t), v && y && !this.isLocalEnv(e, t) && fetch(`https://api.cloudflare.com/client/v4/zones/${v}/purge_cache`, {
|
|
6103
6118
|
method: "POST",
|
|
6104
6119
|
headers: {
|
|
6105
|
-
Authorization: `Bearer ${
|
|
6120
|
+
Authorization: `Bearer ${y}`,
|
|
6106
6121
|
"Content-Type": "application/json"
|
|
6107
6122
|
},
|
|
6108
6123
|
body: JSON.stringify({ files: i })
|
|
6109
6124
|
}).catch(() => {}), !r) {
|
|
6110
6125
|
let e = `${n}${n.includes("?") ? "&" : "?"} _warmer=${Date.now()}`;
|
|
6111
|
-
console.log(`[CacheManager] Prewarming cache at: ${e}`),
|
|
6126
|
+
console.log(`[CacheManager] Prewarming cache at: ${e}`), fetch(e, { headers: {
|
|
6112
6127
|
"X-Cache-Warmer": "true",
|
|
6113
6128
|
"User-Agent": "Kama-Cache-Warmer/1.0"
|
|
6114
6129
|
} }).catch((e) => console.warn("[CacheManager] Prewarm fetch error:", e));
|
|
@@ -6137,35 +6152,49 @@ var B = class {
|
|
|
6137
6152
|
}
|
|
6138
6153
|
async purgeGlobalCacheDirect(e, t) {
|
|
6139
6154
|
try {
|
|
6140
|
-
let { zoneId: n, apiToken: r
|
|
6141
|
-
if (
|
|
6142
|
-
n && r && fetch(`https://api.cloudflare.com/client/v4/zones/${n}/purge_cache`, {
|
|
6155
|
+
let { zoneId: n, apiToken: r } = this.getEnv(e);
|
|
6156
|
+
if (!(await this.callAstroPurge(e, { purge_everything: !0 })).ok) return;
|
|
6157
|
+
if (n && r && !this.isLocalEnv(e) && fetch(`https://api.cloudflare.com/client/v4/zones/${n}/purge_cache`, {
|
|
6143
6158
|
method: "POST",
|
|
6144
6159
|
headers: {
|
|
6145
6160
|
Authorization: `Bearer ${r}`,
|
|
6146
6161
|
"Content-Type": "application/json"
|
|
6147
6162
|
},
|
|
6148
6163
|
body: JSON.stringify({ purge_everything: !0 })
|
|
6149
|
-
}).catch(() => {}), await new Promise((e) => setTimeout(e, 100)), t
|
|
6164
|
+
}).catch(() => {}), await new Promise((e) => setTimeout(e, 100)), t) await this.warmAllPublishedPages(e, t);
|
|
6165
|
+
else {
|
|
6166
|
+
let { frontendUrl: t } = this.getEnv(e);
|
|
6167
|
+
fetch(`${t.replace(/\/+$/, "")}/?_warmer=${Date.now()}`, { headers: { "X-Cache-Warmer": "true" } }).catch(() => {});
|
|
6168
|
+
}
|
|
6150
6169
|
} catch (e) {
|
|
6151
6170
|
console.warn("[CacheManager] Direct Global Purge skipped:", e);
|
|
6152
6171
|
}
|
|
6153
6172
|
}
|
|
6154
6173
|
async warmAllPublishedPages(e, t) {
|
|
6155
6174
|
try {
|
|
6156
|
-
let
|
|
6157
|
-
|
|
6158
|
-
|
|
6159
|
-
|
|
6160
|
-
|
|
6161
|
-
|
|
6162
|
-
|
|
6175
|
+
let n = t.prepare("\n SELECT DISTINCT cn.slug, c.baseUrl\n FROM content_nodes cn\n LEFT JOIN node_channels nc ON cn.id = nc.nodeId\n LEFT JOIN channels c ON nc.channelId = c.id\n WHERE cn.status = 'published' AND cn.slug IS NOT NULL AND (cn.deletedAt IS NULL OR cn.deletedAt = '')\n LIMIT 100\n "), r = typeof n.all == "function" ? await n.all() : await n.bind().all(), i = Array.isArray(r) ? r : r?.results || [], a = this.getEnv(e).frontendUrl, o = {
|
|
6176
|
+
"X-Cache-Warmer": "true",
|
|
6177
|
+
"User-Agent": "Kama-Cache-Warmer/1.0"
|
|
6178
|
+
}, s = Date.now(), c = /* @__PURE__ */ new Set();
|
|
6179
|
+
for (let e of i) {
|
|
6180
|
+
let t = String(e.slug).replace(/^\/+|\/+$/g, ""), n = a;
|
|
6181
|
+
e.baseUrl && typeof e.baseUrl == "string" && e.baseUrl.trim() !== "" && (n = e.baseUrl.trim(), !n.startsWith("http://") && !n.startsWith("https://") && (n = `https://${n}`), n = n.replace(/\/+$/, ""));
|
|
6182
|
+
let r = t === "home" || !t ? n : `${n}/${t}`;
|
|
6183
|
+
c.add(`${r}?_warmer=${s}`);
|
|
6184
|
+
}
|
|
6185
|
+
c.add(`${a}/?_warmer=${s}`);
|
|
6186
|
+
let l = Array.from(c);
|
|
6187
|
+
for (let e = 0; e < l.length; e += 6) {
|
|
6188
|
+
let t = l.slice(e, e + 6);
|
|
6189
|
+
await Promise.all(t.map((e) => fetch(e, { headers: o }).catch((t) => console.warn(`[CacheWarmer] Skipped prewarm for ${e}:`, t?.message || t))));
|
|
6190
|
+
}
|
|
6191
|
+
console.log(`[CacheWarmer] Prewarmed ${l.length} published pages across ${Math.ceil(l.length / 6)} batches.`);
|
|
6163
6192
|
} catch (e) {
|
|
6164
6193
|
console.warn("⚠️ [CacheWarmer] Tree-wide warming failed:", e);
|
|
6165
6194
|
}
|
|
6166
6195
|
}
|
|
6167
|
-
},
|
|
6168
|
-
async function
|
|
6196
|
+
}, H = new e();
|
|
6197
|
+
async function ce(e, t, n = []) {
|
|
6169
6198
|
let r = e.prepare(t);
|
|
6170
6199
|
if (typeof r.bind == "function") {
|
|
6171
6200
|
let e = await r.bind(...n).all();
|
|
@@ -6177,24 +6206,25 @@ async function le(e, t, n = []) {
|
|
|
6177
6206
|
}
|
|
6178
6207
|
return [];
|
|
6179
6208
|
}
|
|
6180
|
-
async function
|
|
6209
|
+
async function le(e, t, n = []) {
|
|
6181
6210
|
let r = e.prepare(t);
|
|
6182
6211
|
if (typeof r.bind == "function") return r.bind(...n).run();
|
|
6183
6212
|
if (typeof r.run == "function") return r.run(...n);
|
|
6184
6213
|
}
|
|
6185
|
-
function
|
|
6214
|
+
function U(e) {
|
|
6186
6215
|
return !e || !e.trim() ? null : e.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().trim().replace(/[^a-z0-9\s-]/g, "").replace(/[\s-]+/g, "-").replace(/^-+|-+$/g, "") || null;
|
|
6187
6216
|
}
|
|
6188
|
-
function
|
|
6217
|
+
function ue(e) {
|
|
6189
6218
|
return +(e === !0 || e === 1 || e === "1" || e === "true");
|
|
6190
6219
|
}
|
|
6191
|
-
function
|
|
6220
|
+
function de(e) {
|
|
6192
6221
|
if (e == null || e === "null" || e === "" || typeof e == "string" && e.startsWith("draft-")) return null;
|
|
6193
6222
|
let t = Number(e);
|
|
6194
6223
|
return isNaN(t) ? null : t;
|
|
6195
6224
|
}
|
|
6196
|
-
function
|
|
6225
|
+
function fe(e) {
|
|
6197
6226
|
let t = { ...e };
|
|
6227
|
+
delete t.language, delete t.defaultLanguage;
|
|
6198
6228
|
for (let e of [
|
|
6199
6229
|
"id",
|
|
6200
6230
|
"treeNodeId",
|
|
@@ -6205,7 +6235,6 @@ function H(e) {
|
|
|
6205
6235
|
"contentType",
|
|
6206
6236
|
"title",
|
|
6207
6237
|
"slug",
|
|
6208
|
-
"language",
|
|
6209
6238
|
"hidden",
|
|
6210
6239
|
"is_hidden",
|
|
6211
6240
|
"isHidden",
|
|
@@ -6222,17 +6251,22 @@ function H(e) {
|
|
|
6222
6251
|
]) delete t[e];
|
|
6223
6252
|
return t;
|
|
6224
6253
|
}
|
|
6225
|
-
function
|
|
6226
|
-
return e ? typeof e == "string" ? (e.startsWith("ast_") && t.add(e), t) : Array.isArray(e) ? (e.forEach((e) =>
|
|
6254
|
+
function pe(e, t = /* @__PURE__ */ new Set()) {
|
|
6255
|
+
return e ? typeof e == "string" ? (e.startsWith("ast_") && t.add(e), t) : Array.isArray(e) ? (e.forEach((e) => pe(e, t)), t) : (typeof e == "object" && Object.values(e).forEach((e) => pe(e, t)), t) : t;
|
|
6256
|
+
}
|
|
6257
|
+
function me(e, t) {
|
|
6258
|
+
if (!e) return !0;
|
|
6259
|
+
let n = t.title !== void 0 && t.title?.trim() !== e.title?.trim(), r = t.slug !== void 0 && t.slug !== e.slug, i = t.isHidden !== void 0 && ue(t.isHidden) !== ue(e.isHidden), a = t.status !== void 0 && t.status !== e.status, o = typeof e.draftDataJson == "string" ? JSON.parse(e.draftDataJson || "{}") : e.draftDataJson || {}, s = t.sanitizedFields || {}, c = s.menuTitle !== void 0 && s.menuTitle !== o.menuTitle;
|
|
6260
|
+
return n || r || i || a || c;
|
|
6227
6261
|
}
|
|
6228
|
-
async function
|
|
6262
|
+
async function he(e, t, n) {
|
|
6229
6263
|
for (let r of n) {
|
|
6230
|
-
let n = (await
|
|
6231
|
-
if (!n || (await
|
|
6264
|
+
let n = (await ce(e, "\n SELECT id, storageKeyPrivate, isSystemVariant, parentAssetId, filename\n FROM assets WHERE id = ?\n ", [r]))[0];
|
|
6265
|
+
if (!n || (await ce(e, "SELECT 1 FROM node_assets WHERE assetId = ? LIMIT 1", [n.id])).length > 0) continue;
|
|
6232
6266
|
let i = [n];
|
|
6233
6267
|
if (!n.isSystemVariant) {
|
|
6234
|
-
let t = await
|
|
6235
|
-
if (r.length > 0 && (await
|
|
6268
|
+
let t = await ce(e, "\n SELECT id, storageKeyPrivate, isSystemVariant, parentAssetId, filename\n FROM assets\n WHERE parentAssetId = ? OR (isSystemVariant = 1 AND filename LIKE ?)\n ", [n.id, `crop_%${String(n.filename || "").replace(/\.[^/.]+$/, "")}%`]), r = t.map((e) => e.id);
|
|
6269
|
+
if (r.length > 0 && (await ce(e, `SELECT DISTINCT assetId FROM node_assets WHERE assetId IN (${r.map(() => "?").join(",")})`, r)).length > 0) continue;
|
|
6236
6270
|
i = [n, ...t];
|
|
6237
6271
|
}
|
|
6238
6272
|
for (let e of i) if (e.storageKeyPrivate) try {
|
|
@@ -6241,10 +6275,10 @@ async function U(e, t, n) {
|
|
|
6241
6275
|
console.warn(`[Asset Cleanup] Failed to delete ${e.storageKeyPrivate}:`, t);
|
|
6242
6276
|
}
|
|
6243
6277
|
let a = i.map((e) => e.id), o = a.map(() => "?").join(",");
|
|
6244
|
-
await
|
|
6278
|
+
await le(e, `DELETE FROM node_assets WHERE assetId IN (${o})`, a), await le(e, `DELETE FROM assets WHERE id IN (${o})`, a);
|
|
6245
6279
|
}
|
|
6246
6280
|
}
|
|
6247
|
-
async function
|
|
6281
|
+
async function ge(e, t, n) {
|
|
6248
6282
|
let r = {}, i = null;
|
|
6249
6283
|
if (t) {
|
|
6250
6284
|
let n = await e.prepare("\n WITH RECURSIVE ancestor_path(id, parentId, draftDataJson, dataJson, level) AS (\n SELECT t.id, t.parentId, c.draftDataJson, c.dataJson, 0\n FROM tree_nodes t\n INNER JOIN content_nodes c ON t.contentId = c.id\n WHERE t.id = ?\n UNION ALL\n SELECT t.id, t.parentId, c.draftDataJson, c.dataJson, ap.level + 1\n FROM tree_nodes t\n INNER JOIN content_nodes c ON t.contentId = c.id\n INNER JOIN ancestor_path ap ON t.id = ap.parentId\n )\n SELECT draftDataJson, dataJson FROM ancestor_path ORDER BY level ASC\n ").all(t), a = Array.isArray(n) ? n : n?.results || [];
|
|
@@ -6258,7 +6292,7 @@ async function W(e, t, n) {
|
|
|
6258
6292
|
}
|
|
6259
6293
|
}
|
|
6260
6294
|
if (!i) {
|
|
6261
|
-
let t = await e.prepare("SELECT dataJson FROM trees WHERE id = ?").get(n);
|
|
6295
|
+
let t = await e.prepare("SELECT dataJson FROM trees WHERE id = ? OR key = ? LIMIT 1").get(Number(n) || -1, String(n));
|
|
6262
6296
|
if (t && t.dataJson) try {
|
|
6263
6297
|
let e = typeof t.dataJson == "string" ? JSON.parse(t.dataJson) : t.dataJson;
|
|
6264
6298
|
e.subpageLayoutId && e.subpageLayoutId !== "inherit" && (i = e.subpageLayoutId);
|
|
@@ -6269,7 +6303,7 @@ async function W(e, t, n) {
|
|
|
6269
6303
|
inheritedFields: r
|
|
6270
6304
|
};
|
|
6271
6305
|
}
|
|
6272
|
-
|
|
6306
|
+
H.get("/", async (e) => {
|
|
6273
6307
|
let t = e.get("db"), n = e.req.query("id"), r = e.req.query("type"), i = e.req.query("q") || e.req.query("search"), a = e.req.query("channelId"), o = e.req.query("trashed") === "true", s = e.req.query("assetId"), c = e.req.query("sort") || "updatedAt", l = (e.req.query("order") || "DESC").toUpperCase() === "ASC" ? "ASC" : "DESC", u = e.req.query("limit"), d = e.req.query("offset"), f = Math.max(1, Math.min(100, parseInt(u || "50", 10))), p = Math.max(0, parseInt(d || "0", 10));
|
|
6274
6308
|
if (n) {
|
|
6275
6309
|
let r = Number(n);
|
|
@@ -6280,7 +6314,7 @@ V.get("/", async (e) => {
|
|
|
6280
6314
|
id: i.id,
|
|
6281
6315
|
title: i.title,
|
|
6282
6316
|
slug: i.slug,
|
|
6283
|
-
language: i.language ||
|
|
6317
|
+
language: i.language || null,
|
|
6284
6318
|
nodeType: i.contentType,
|
|
6285
6319
|
contentType: i.contentType,
|
|
6286
6320
|
isHidden: !!i.isHidden,
|
|
@@ -6294,9 +6328,9 @@ V.get("/", async (e) => {
|
|
|
6294
6328
|
updatedAt: i.updatedAt
|
|
6295
6329
|
}, s = i.draftDataJson || i.dataJson;
|
|
6296
6330
|
if (s) try {
|
|
6297
|
-
let n = typeof s == "string" ? JSON.parse(s) : s, a = await t.prepare("SELECT id as treeNodeId, treeId, parentId FROM tree_nodes WHERE contentId = ? LIMIT 1").get(r), c =
|
|
6331
|
+
let n = typeof s == "string" ? JSON.parse(s) : s, a = await t.prepare("SELECT id as treeNodeId, treeId, parentId FROM tree_nodes WHERE contentId = ? LIMIT 1").get(r), c = se(e.env?.BUNDLED_DEFINITIONS).nodes?.[i.contentType] || {}, l = n.layoutId || null;
|
|
6298
6332
|
if (a) {
|
|
6299
|
-
let { resolvedLayoutId: e, inheritedFields: r } = await
|
|
6333
|
+
let { resolvedLayoutId: e, inheritedFields: r } = await ge(t, a.parentId, a.treeId);
|
|
6300
6334
|
(l === "inherit" || !l) && (l = e);
|
|
6301
6335
|
for (let [e, t] of Object.entries(r)) e !== "layoutId" && e !== "subpageLayoutId" && (n[e] === void 0 || n[e] === null || n[e] === "") && t !== void 0 && (n[e] = t);
|
|
6302
6336
|
}
|
|
@@ -6311,7 +6345,7 @@ V.get("/", async (e) => {
|
|
|
6311
6345
|
let r = t.allowedLayouts;
|
|
6312
6346
|
return r ? typeof r == "string" ? r === e : !Array.isArray(r) || r.length === 0 || r.includes(e) : !0;
|
|
6313
6347
|
})(l) && (l = null), (l === "inherit" || !l) && (l = c.defaultLayout || null);
|
|
6314
|
-
let u = await
|
|
6348
|
+
let u = await B(t, fe(n));
|
|
6315
6349
|
Object.assign(o, u), o.resolvedLayoutId = l;
|
|
6316
6350
|
} catch {}
|
|
6317
6351
|
let c = await t.prepare("SELECT channelId FROM node_channels WHERE nodeId = ?").all(r);
|
|
@@ -6321,7 +6355,7 @@ V.get("/", async (e) => {
|
|
|
6321
6355
|
let u = await t.prepare("SELECT * FROM content_blocks WHERE contentId = ? AND isDraft = 1 ORDER BY sortOrder ASC").all(r), d = Array.isArray(u) ? u : u?.results || [], f = await Promise.all(d.map(async (e) => {
|
|
6322
6356
|
let n = {};
|
|
6323
6357
|
try {
|
|
6324
|
-
n = typeof e.dataJson == "string" ? JSON.parse(e.dataJson || "{}") : e.dataJson || {}, n && typeof n == "object" && (n = await
|
|
6358
|
+
n = typeof e.dataJson == "string" ? JSON.parse(e.dataJson || "{}") : e.dataJson || {}, n && typeof n == "object" && (n = await B(t, n));
|
|
6325
6359
|
} catch {
|
|
6326
6360
|
n = {};
|
|
6327
6361
|
}
|
|
@@ -6392,7 +6426,7 @@ V.get("/", async (e) => {
|
|
|
6392
6426
|
id: e.id,
|
|
6393
6427
|
title: e.title,
|
|
6394
6428
|
slug: e.slug,
|
|
6395
|
-
language: e.language ||
|
|
6429
|
+
language: e.language || null,
|
|
6396
6430
|
contentType: e.contentType,
|
|
6397
6431
|
nodeType: e.contentType,
|
|
6398
6432
|
isHidden: !!e.isHidden,
|
|
@@ -6409,7 +6443,7 @@ V.get("/", async (e) => {
|
|
|
6409
6443
|
assetCount: e.assetCount || 0
|
|
6410
6444
|
}, i = e.draftDataJson || e.dataJson;
|
|
6411
6445
|
if (i) try {
|
|
6412
|
-
let e = typeof i == "string" ? JSON.parse(i) : i, n = await
|
|
6446
|
+
let e = typeof i == "string" ? JSON.parse(i) : i, n = await B(t, fe(e));
|
|
6413
6447
|
Object.assign(r, n);
|
|
6414
6448
|
} catch {}
|
|
6415
6449
|
return r;
|
|
@@ -6421,13 +6455,35 @@ V.get("/", async (e) => {
|
|
|
6421
6455
|
offset: p,
|
|
6422
6456
|
limit: f
|
|
6423
6457
|
});
|
|
6424
|
-
}),
|
|
6425
|
-
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 } =
|
|
6426
|
-
if (
|
|
6458
|
+
}), H.post("/", async (e) => {
|
|
6459
|
+
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 } = R(fe(_)), b = ue(d === void 0 ? f === void 0 ? p : f : d), x = l || u || "page", S = e.get("user")?.id || null, C = typeof c == "string" && c.trim() !== "" ? c.trim() : null, w = g && Array.isArray(g) && g.length > 0 ? g[0] : null, T = w ? w.treeId || w.id : null, E = null;
|
|
6460
|
+
if (T) {
|
|
6461
|
+
let e = await t.prepare("SELECT dataJson FROM trees WHERE id = ? OR key = ? LIMIT 1").get(Number(T) || -1, String(T));
|
|
6462
|
+
if (e?.dataJson) try {
|
|
6463
|
+
let t = typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson;
|
|
6464
|
+
E = t.defaultLanguage?.trim() || t.language?.trim() || null;
|
|
6465
|
+
} catch {}
|
|
6466
|
+
}
|
|
6467
|
+
if (!E && h && Array.isArray(h) && h.length > 0) {
|
|
6468
|
+
let e = typeof h[0] == "object" ? h[0].id : h[0];
|
|
6469
|
+
if (e && e !== "all") {
|
|
6470
|
+
let n = await t.prepare("SELECT defaultLanguage, dataJson FROM channels WHERE id = ? LIMIT 1").get(Number(e));
|
|
6471
|
+
if (n) {
|
|
6472
|
+
if (n.defaultLanguage) E = n.defaultLanguage.trim();
|
|
6473
|
+
else if (n.dataJson) try {
|
|
6474
|
+
let e = typeof n.dataJson == "string" ? JSON.parse(n.dataJson) : n.dataJson;
|
|
6475
|
+
E = e.defaultLanguage?.trim() || e.language?.trim() || null;
|
|
6476
|
+
} catch {}
|
|
6477
|
+
}
|
|
6478
|
+
}
|
|
6479
|
+
}
|
|
6480
|
+
C && E && C === E && (C = null);
|
|
6481
|
+
let D = a, O = /* @__PURE__ */ new Set(), k = !1, A = s === void 0 ? null : U(s);
|
|
6482
|
+
if (A) {
|
|
6427
6483
|
let n = [];
|
|
6428
6484
|
if (g !== void 0 && Array.isArray(g) && g.length > 0) for (let e of g) n.push({
|
|
6429
6485
|
treeId: Number(e.treeId),
|
|
6430
|
-
parentId:
|
|
6486
|
+
parentId: de(e.parentId ?? e._draftParentId ?? null)
|
|
6431
6487
|
});
|
|
6432
6488
|
else if (a) {
|
|
6433
6489
|
let e = await t.prepare("SELECT treeId, parentId FROM tree_nodes WHERE contentId = ?").all(a), r = Array.isArray(e) ? e : e?.results || [];
|
|
@@ -6437,94 +6493,103 @@ V.get("/", async (e) => {
|
|
|
6437
6493
|
});
|
|
6438
6494
|
}
|
|
6439
6495
|
for (let r of n) {
|
|
6440
|
-
let n = r.parentId === null ? "tn.parentId IS NULL" : "tn.parentId = ?", i = r.parentId === null ? [r.treeId,
|
|
6496
|
+
let n = r.parentId === null ? "tn.parentId IS NULL" : "tn.parentId = ?", i = r.parentId === null ? [r.treeId, A] : [
|
|
6441
6497
|
r.treeId,
|
|
6442
6498
|
r.parentId,
|
|
6443
|
-
|
|
6499
|
+
A
|
|
6444
6500
|
], o = `
|
|
6445
6501
|
SELECT cn.id FROM tree_nodes tn
|
|
6446
6502
|
INNER JOIN content_nodes cn ON tn.contentId = cn.id
|
|
6447
6503
|
WHERE tn.treeId = ? AND ${n} AND cn.slug = ? AND (cn.deletedAt IS NULL OR cn.deletedAt = '')
|
|
6448
6504
|
`;
|
|
6449
6505
|
if (a && (o += " AND cn.id != ?", i.push(a)), o += " LIMIT 1", await t.prepare(o).get(...i)) return e.json({
|
|
6450
|
-
error: `The slug '${
|
|
6506
|
+
error: `The slug '${A}' is already in use by another page in this section.`,
|
|
6451
6507
|
field: "slug"
|
|
6452
6508
|
}, 409);
|
|
6453
6509
|
}
|
|
6454
6510
|
}
|
|
6455
6511
|
if (a) {
|
|
6456
|
-
let e = await t.prepare("SELECT title, slug, language, contentType, draftDataJson, dataJson, publishedAt, status FROM content_nodes WHERE id = ?").get(a)
|
|
6512
|
+
let e = await t.prepare("SELECT title, slug, language, contentType, isHidden, draftDataJson, dataJson, publishedAt, status FROM content_nodes WHERE id = ?").get(a);
|
|
6513
|
+
k = me(e, {
|
|
6514
|
+
title: o,
|
|
6515
|
+
slug: A,
|
|
6516
|
+
isHidden: b,
|
|
6517
|
+
sanitizedFields: v
|
|
6518
|
+
});
|
|
6519
|
+
let n = e?.draftDataJson || e?.dataJson || "{}";
|
|
6457
6520
|
try {
|
|
6458
|
-
|
|
6521
|
+
pe(typeof n == "string" ? JSON.parse(n) : n, O);
|
|
6459
6522
|
} catch {}
|
|
6460
6523
|
if (m !== void 0) {
|
|
6461
6524
|
let e = await t.prepare("SELECT dataJson FROM content_blocks WHERE contentId = ? AND isDraft = 1").all(a);
|
|
6462
6525
|
(Array.isArray(e) ? e : e?.results || []).forEach((e) => {
|
|
6463
6526
|
try {
|
|
6464
|
-
|
|
6527
|
+
pe(typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson, O);
|
|
6465
6528
|
} catch {}
|
|
6466
6529
|
});
|
|
6467
6530
|
}
|
|
6468
|
-
let r = o === void 0 ? e?.title || "Untitled" : o, i =
|
|
6531
|
+
let r = o === void 0 ? e?.title || "Untitled" : o, i = A ?? e?.slug ?? null, s = x || e?.contentType || "page", l = c === void 0 ? e?.language : C, u = e?.draftDataJson || e?.dataJson || "{}", d = {};
|
|
6469
6532
|
try {
|
|
6470
|
-
|
|
6533
|
+
d = JSON.parse(u);
|
|
6471
6534
|
} catch {}
|
|
6472
|
-
let
|
|
6473
|
-
...
|
|
6535
|
+
let f = JSON.stringify({
|
|
6536
|
+
...d,
|
|
6474
6537
|
...v
|
|
6475
|
-
}),
|
|
6476
|
-
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(r, i,
|
|
6538
|
+
}), p = e?.status === "published" || e?.publishedAt ? "published" : "draft", h = +(p === "published");
|
|
6539
|
+
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(r, i, l, s, b, p, f, h, S, a);
|
|
6477
6540
|
} else {
|
|
6478
|
-
|
|
6479
|
-
|
|
6541
|
+
k = !0;
|
|
6542
|
+
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(x, o || "Untitled", A, C, b, JSON.stringify(v), S, S);
|
|
6543
|
+
D = Number(e.lastInsertRowid);
|
|
6480
6544
|
}
|
|
6481
|
-
if (h !== void 0 && Array.isArray(h) &&
|
|
6482
|
-
await t.prepare("DELETE FROM node_channels WHERE nodeId = ?").run(
|
|
6545
|
+
if (h !== void 0 && Array.isArray(h) && D) {
|
|
6546
|
+
await t.prepare("DELETE FROM node_channels WHERE nodeId = ?").run(D);
|
|
6483
6547
|
let e = [...new Set(h.map((e) => typeof e == "object" && e ? e.id || e.channelId : e))].filter((e) => e && e !== "all").map((e) => Number(e) || e);
|
|
6484
6548
|
if (e.length > 0) {
|
|
6485
|
-
let n = e.map(() => "(?, ?)").join(", "), r = e.flatMap((e) => [
|
|
6549
|
+
let n = e.map(() => "(?, ?)").join(", "), r = e.flatMap((e) => [D, e]);
|
|
6486
6550
|
await t.prepare(`INSERT OR IGNORE INTO node_channels (nodeId, channelId) VALUES ${n}`).run(...r);
|
|
6487
6551
|
}
|
|
6488
6552
|
}
|
|
6489
|
-
if (g !== void 0 && Array.isArray(g) && g.length > 0 &&
|
|
6553
|
+
if (g !== void 0 && Array.isArray(g) && g.length > 0 && D) for (let e of g) {
|
|
6490
6554
|
if (!e || !e.treeId) continue;
|
|
6491
|
-
let n = Number(e.treeId) || e.treeId, r =
|
|
6492
|
-
a ? await t.prepare("UPDATE tree_nodes SET parentId = ?, sortOrder = ? WHERE id = ?").run(r, i, a.id) : await t.prepare("INSERT INTO tree_nodes (treeId, contentId, parentId, sortOrder) VALUES (?, ?, ?, ?)").run(n,
|
|
6555
|
+
let n = Number(e.treeId) || e.treeId, r = de(e.parentId ?? e._draftParentId ?? null), i = typeof e.sortOrder == "number" ? e.sortOrder : 0, a = await t.prepare("SELECT id, parentId, sortOrder FROM tree_nodes WHERE treeId = ? AND contentId = ?").get(n, D);
|
|
6556
|
+
a ? ((a.parentId !== r || a.sortOrder !== i) && (k = !0), await t.prepare("UPDATE tree_nodes SET parentId = ?, sortOrder = ? WHERE id = ?").run(r, i, a.id)) : (k = !0, await t.prepare("INSERT INTO tree_nodes (treeId, contentId, parentId, sortOrder) VALUES (?, ?, ?, ?)").run(n, D, r, i));
|
|
6493
6557
|
}
|
|
6494
|
-
let
|
|
6495
|
-
if (m !== void 0 && Array.isArray(m) &&
|
|
6496
|
-
await t.prepare("DELETE FROM content_blocks WHERE contentId = ? AND isDraft = 1").run(
|
|
6558
|
+
let j = [];
|
|
6559
|
+
if (m !== void 0 && Array.isArray(m) && D) {
|
|
6560
|
+
await t.prepare("DELETE FROM content_blocks WHERE contentId = ? AND isDraft = 1").run(D);
|
|
6497
6561
|
let e = [], n = [];
|
|
6498
6562
|
for (let t = 0; t < m.length; t++) {
|
|
6499
|
-
let r = m[t], i = r.componentId || r.elementType || "text-block", a = r.data || {}, o = String(r.blockId || a.blockId || r.instanceId || r.id || `block-${Date.now()}`), { cleanedData: s, assetRefs: c } =
|
|
6563
|
+
let r = m[t], i = r.componentId || r.elementType || "text-block", a = r.data || {}, o = String(r.blockId || a.blockId || r.instanceId || r.id || `block-${Date.now()}`), { cleanedData: s, assetRefs: c } = R({
|
|
6500
6564
|
...a,
|
|
6501
6565
|
blockId: o,
|
|
6502
6566
|
_instanceId: o
|
|
6503
6567
|
});
|
|
6504
|
-
c.forEach((e) =>
|
|
6568
|
+
c.forEach((e) => j.push({
|
|
6505
6569
|
...e,
|
|
6506
6570
|
fieldKey: `blocks[${t}].${e.fieldKey}`
|
|
6507
6571
|
}));
|
|
6508
6572
|
let l = r.region !== void 0 && r.region !== null && String(r.region).trim() !== "" ? String(r.region) : "content";
|
|
6509
|
-
e.push("(?, ?, ?, ?, ?, 1)"), n.push(
|
|
6573
|
+
e.push("(?, ?, ?, ?, ?, 1)"), n.push(D, t, i, JSON.stringify(s), l);
|
|
6510
6574
|
}
|
|
6511
6575
|
e.length > 0 && await t.prepare(`INSERT INTO content_blocks (contentId, sortOrder, elementType, dataJson, region, isDraft) VALUES ${e.join(", ")}`).run(...n);
|
|
6512
6576
|
}
|
|
6513
|
-
if (
|
|
6514
|
-
let n = [...y, ...
|
|
6515
|
-
await oe(t,
|
|
6516
|
-
let r = new Set(n.map((e) => e.assetId)), i = new Set([...
|
|
6577
|
+
if (D) {
|
|
6578
|
+
let n = [...y, ...j];
|
|
6579
|
+
await oe(t, D, n);
|
|
6580
|
+
let r = new Set(n.map((e) => e.assetId)), i = new Set([...O].filter((e) => !r.has(e)));
|
|
6517
6581
|
if (i.size > 0) {
|
|
6518
|
-
let { storage: n } =
|
|
6519
|
-
await
|
|
6582
|
+
let { storage: n } = ae(e.env);
|
|
6583
|
+
await he(t, n, i);
|
|
6520
6584
|
}
|
|
6521
6585
|
}
|
|
6522
|
-
return await I(e).clear(), e.json({
|
|
6586
|
+
return await I(e).clear(), D && new V(e.env).purgeNode(e, t, D, k), e.json({
|
|
6523
6587
|
success: !0,
|
|
6524
|
-
id:
|
|
6525
|
-
status: "draft"
|
|
6588
|
+
id: D,
|
|
6589
|
+
status: "draft",
|
|
6590
|
+
isStructuralChange: k
|
|
6526
6591
|
});
|
|
6527
|
-
}),
|
|
6592
|
+
}), H.post("/publish", async (e) => {
|
|
6528
6593
|
let t = e.get("db"), n = await e.req.json(), r = n.id || n.nodeId;
|
|
6529
6594
|
if (!r || isNaN(Number(r))) return e.json({ error: "Node ID required for publishing" }, 400);
|
|
6530
6595
|
let i = Number(r), a = e.get("user")?.id || null, o = await t.prepare("SELECT * FROM content_nodes WHERE id = ?").get(i);
|
|
@@ -6537,57 +6602,58 @@ V.get("/", async (e) => {
|
|
|
6537
6602
|
try {
|
|
6538
6603
|
c = typeof o.draftDataJson == "string" ? JSON.parse(o.draftDataJson) : o.draftDataJson || {};
|
|
6539
6604
|
} catch {}
|
|
6540
|
-
let l = (s.title ?? o.title ?? "").trim(), u = (c.title ?? n.title ?? o.title ?? "").trim(), d = (s.slug ?? o.slug ?? "").trim(), f = (c.slug ?? n.slug ?? o.slug ?? "").trim(), p = l !== "" && u !== "" && l !== u || d !== "" && f !== "" && d !== f
|
|
6541
|
-
await t.prepare("\n UPDATE content_nodes\n SET publishedDataJson = ?, dataJson = ?, publishedAt = CURRENT_TIMESTAMP, status = 'published', hasUnpublishedChanges = 0, updatedById = ?, updatedAt = CURRENT_TIMESTAMP\n WHERE id = ?\n ").run(
|
|
6542
|
-
let
|
|
6543
|
-
if (
|
|
6605
|
+
let l = (s.title ?? o.title ?? "").trim(), u = (c.title ?? n.title ?? o.title ?? "").trim(), d = (s.slug ?? o.slug ?? "").trim(), f = (c.slug ?? n.slug ?? o.slug ?? "").trim(), p = (s.menuTitle ?? "").trim(), m = (c.menuTitle ?? "").trim(), h = l !== "" && u !== "" && l !== u || d !== "" && f !== "" && d !== f || p !== "" && m !== "" && p !== m, g = o.draftDataJson || o.dataJson || "{}";
|
|
6606
|
+
await t.prepare("\n UPDATE content_nodes\n SET publishedDataJson = ?, dataJson = ?, publishedAt = CURRENT_TIMESTAMP, status = 'published', hasUnpublishedChanges = 0, updatedById = ?, updatedAt = CURRENT_TIMESTAMP\n WHERE id = ?\n ").run(g, g, a, i), await t.prepare("DELETE FROM content_blocks WHERE contentId = ? AND isDraft = 0").run(i);
|
|
6607
|
+
let _ = await t.prepare("SELECT * FROM content_blocks WHERE contentId = ? AND isDraft = 1 ORDER BY sortOrder ASC").all(i), v = Array.isArray(_) ? _ : _?.results || [];
|
|
6608
|
+
if (v.length > 0) {
|
|
6544
6609
|
let e = [], n = [];
|
|
6545
|
-
for (let t of
|
|
6610
|
+
for (let t of v) {
|
|
6546
6611
|
let r = t.region !== void 0 && t.region !== null && String(t.region).trim() !== "" ? String(t.region) : "content";
|
|
6547
6612
|
e.push("(?, ?, ?, ?, ?, 0)"), n.push(i, t.sortOrder, t.elementType, t.dataJson, r);
|
|
6548
6613
|
}
|
|
6549
6614
|
await t.prepare(`INSERT INTO content_blocks (contentId, sortOrder, elementType, dataJson, region, isDraft) VALUES ${e.join(", ")}`).run(...n);
|
|
6550
6615
|
}
|
|
6551
|
-
let
|
|
6552
|
-
version:
|
|
6616
|
+
let y = ((await t.prepare("SELECT COUNT(*) as count FROM node_revisions WHERE nodeId = ?").get(i))?.count || 0) + 1, b = {
|
|
6617
|
+
version: y,
|
|
6553
6618
|
publishedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6554
6619
|
node: {
|
|
6555
6620
|
...o,
|
|
6556
|
-
dataJson:
|
|
6621
|
+
dataJson: g
|
|
6557
6622
|
},
|
|
6558
|
-
blocks:
|
|
6623
|
+
blocks: v
|
|
6559
6624
|
};
|
|
6560
|
-
return await t.prepare("INSERT INTO node_revisions (nodeId, version, snapshotJson, createdById) VALUES (?, ?, ?, ?)").run(i,
|
|
6625
|
+
return await t.prepare("INSERT INTO node_revisions (nodeId, version, snapshotJson, createdById) VALUES (?, ?, ?, ?)").run(i, y, JSON.stringify(b), a), await I(e).clear(), new V(e.env).purgeNode(e, t, i, h), e.json({
|
|
6561
6626
|
success: !0,
|
|
6562
6627
|
id: i,
|
|
6563
6628
|
status: "published",
|
|
6564
|
-
version:
|
|
6565
|
-
publishedAt:
|
|
6566
|
-
hasUnpublishedChanges: !1
|
|
6629
|
+
version: y,
|
|
6630
|
+
publishedAt: b.publishedAt,
|
|
6631
|
+
hasUnpublishedChanges: !1,
|
|
6632
|
+
isStructuralChange: h
|
|
6567
6633
|
});
|
|
6568
|
-
}),
|
|
6634
|
+
}), H.delete("/", async (e) => {
|
|
6569
6635
|
let t = e.get("db"), n = e.req.query("id");
|
|
6570
6636
|
if (!n) return e.json({ error: "Node ID required" }, 400);
|
|
6571
6637
|
let r = Number(n);
|
|
6572
|
-
return await t.prepare("UPDATE content_nodes SET deletedAt = CURRENT_TIMESTAMP WHERE id = ?").run(r), await I(e).clear(), new
|
|
6638
|
+
return await t.prepare("UPDATE content_nodes SET deletedAt = CURRENT_TIMESTAMP WHERE id = ?").run(r), await I(e).clear(), new V(e.env).purgeNode(e, t, r, !0), e.json({
|
|
6573
6639
|
success: !0,
|
|
6574
6640
|
deletedNodeId: r
|
|
6575
6641
|
});
|
|
6576
|
-
}),
|
|
6642
|
+
}), H.post("/restore", async (e) => {
|
|
6577
6643
|
let t = e.get("db"), n = await e.req.json(), r = Number(n.id);
|
|
6578
|
-
return r ? await t.prepare("SELECT id FROM content_nodes WHERE id = ?").get(r) ? (await t.prepare("UPDATE content_nodes SET deletedAt = NULL WHERE id = ?").run(r), await I(e).clear(), new
|
|
6644
|
+
return r ? await t.prepare("SELECT id FROM content_nodes WHERE id = ?").get(r) ? (await t.prepare("UPDATE content_nodes SET deletedAt = NULL WHERE id = ?").run(r), await I(e).clear(), new V(e.env).purgeNode(e, t, r, !0), e.json({
|
|
6579
6645
|
success: !0,
|
|
6580
6646
|
restoredNodeId: r
|
|
6581
6647
|
})) : e.json({ error: "Node not found" }, 404) : e.json({ error: "Node ID required" }, 400);
|
|
6582
|
-
}),
|
|
6648
|
+
}), H.delete("/purge", async (e) => {
|
|
6583
6649
|
let t = e.get("db"), n = e.req.query("id");
|
|
6584
6650
|
if (!n) return e.json({ error: "Node ID required" }, 400);
|
|
6585
6651
|
let r = Number(n);
|
|
6586
|
-
return new
|
|
6652
|
+
return new V(e.env).purgeNode(e, t, r, !0), await t.prepare("DELETE FROM node_channels WHERE nodeId = ?").run(r), await t.prepare("DELETE FROM tree_nodes WHERE contentId = ?").run(r), await t.prepare("DELETE FROM content_blocks WHERE contentId = ?").run(r), await t.prepare("DELETE FROM node_revisions WHERE nodeId = ?").run(r), await t.prepare("DELETE FROM node_assets WHERE nodeId = ?").run(r), await t.prepare("DELETE FROM content_nodes WHERE id = ?").run(r), await I(e).clear(), e.json({
|
|
6587
6653
|
success: !0,
|
|
6588
6654
|
purgedNodeId: r
|
|
6589
6655
|
});
|
|
6590
|
-
}),
|
|
6656
|
+
}), H.get("/:id/revisions", async (e) => {
|
|
6591
6657
|
let t = e.get("db"), n = Number(e.req.param("id"));
|
|
6592
6658
|
if (isNaN(n)) return e.json({ error: "Invalid Node ID" }, 400);
|
|
6593
6659
|
let r = await t.prepare("\n SELECT version, createdById, snapshotJson \n FROM node_revisions \n WHERE nodeId = ? \n ORDER BY version DESC\n ").all(n), i = (Array.isArray(r) ? r : r?.results || []).map((e) => {
|
|
@@ -6603,7 +6669,7 @@ V.get("/", async (e) => {
|
|
|
6603
6669
|
};
|
|
6604
6670
|
});
|
|
6605
6671
|
return e.json({ revisions: i });
|
|
6606
|
-
}),
|
|
6672
|
+
}), H.get("/:id/revisions/:version", async (e) => {
|
|
6607
6673
|
let t = e.get("db"), n = Number(e.req.param("id")), r = Number(e.req.param("version")), i = await t.prepare("SELECT snapshotJson FROM node_revisions WHERE nodeId = ? AND version = ?").get(n, r);
|
|
6608
6674
|
if (!i) return e.json({ error: "Snapshot not found" }, 404);
|
|
6609
6675
|
let a = {};
|
|
@@ -6613,7 +6679,7 @@ V.get("/", async (e) => {
|
|
|
6613
6679
|
return e.json({ error: "Corrupt snapshot data" }, 500);
|
|
6614
6680
|
}
|
|
6615
6681
|
return e.json({ snapshot: a });
|
|
6616
|
-
}),
|
|
6682
|
+
}), H.post("/:id/revisions/:version/restore", async (e) => {
|
|
6617
6683
|
let t = e.get("db"), n = Number(e.req.param("id")), r = Number(e.req.param("version")), i = e.get("user")?.id || null, a = await t.prepare("SELECT snapshotJson FROM node_revisions WHERE nodeId = ? AND version = ?").get(n, r);
|
|
6618
6684
|
if (!a) return e.json({ error: "Snapshot not found" }, 404);
|
|
6619
6685
|
let o = {};
|
|
@@ -6634,8 +6700,8 @@ V.get("/", async (e) => {
|
|
|
6634
6700
|
});
|
|
6635
6701
|
//#endregion
|
|
6636
6702
|
//#region server/routes/admin/trees.ts
|
|
6637
|
-
var
|
|
6638
|
-
function
|
|
6703
|
+
var W = new e();
|
|
6704
|
+
function _e(e, t = null) {
|
|
6639
6705
|
let n = [];
|
|
6640
6706
|
for (let r = 0; r < e.length; r++) {
|
|
6641
6707
|
let i = e[r];
|
|
@@ -6647,19 +6713,19 @@ function he(e, t = null) {
|
|
|
6647
6713
|
id: o,
|
|
6648
6714
|
parentId: t,
|
|
6649
6715
|
sortOrder: r
|
|
6650
|
-
}), i.children && Array.isArray(i.children) && i.children.length > 0 && n.push(...
|
|
6716
|
+
}), i.children && Array.isArray(i.children) && i.children.length > 0 && n.push(..._e(i.children, o)));
|
|
6651
6717
|
}
|
|
6652
6718
|
return n;
|
|
6653
6719
|
}
|
|
6654
|
-
function
|
|
6720
|
+
function G(e) {
|
|
6655
6721
|
if (e == null || e === "null" || e === "" || typeof e == "string" && e.startsWith("draft-")) return null;
|
|
6656
6722
|
let t = Number(e);
|
|
6657
6723
|
return isNaN(t) ? null : t;
|
|
6658
6724
|
}
|
|
6659
|
-
function
|
|
6725
|
+
function ve(e) {
|
|
6660
6726
|
return +(e === !0 || e === 1 || e === "1" || e === "true");
|
|
6661
6727
|
}
|
|
6662
|
-
|
|
6728
|
+
W.get("/tree.json", async (e) => {
|
|
6663
6729
|
try {
|
|
6664
6730
|
let t = e.get("db"), n = e.req.query("treeId") || "main-nav", r = e.req.query("preview") === "true", i = 1;
|
|
6665
6731
|
if (isNaN(Number(n))) {
|
|
@@ -6694,7 +6760,7 @@ G.get("/tree.json", async (e) => {
|
|
|
6694
6760
|
id: e.contentId,
|
|
6695
6761
|
treeNodeId: e.treeNodeId,
|
|
6696
6762
|
parentId: e.parentId || null,
|
|
6697
|
-
language: e.language ||
|
|
6763
|
+
language: e.language?.trim() || null,
|
|
6698
6764
|
hidden: +!!s,
|
|
6699
6765
|
isHidden: s,
|
|
6700
6766
|
status: e.status || "draft",
|
|
@@ -6709,9 +6775,9 @@ G.get("/tree.json", async (e) => {
|
|
|
6709
6775
|
} catch (t) {
|
|
6710
6776
|
return console.error("[CMS Tree API] GET Error:", t), e.json({ error: t.message || "Failed to fetch tree" }, 500);
|
|
6711
6777
|
}
|
|
6712
|
-
}),
|
|
6778
|
+
}), W.post("/tree.json", async (e) => {
|
|
6713
6779
|
try {
|
|
6714
|
-
let t = e.get("db"), n = await e.req.json(), r = n.treeId ? String(n.treeId).trim() : "main-nav", i = I(e), a = new
|
|
6780
|
+
let t = e.get("db"), n = await e.req.json(), r = n.treeId ? String(n.treeId).trim() : "main-nav", i = I(e), a = new V(e.env), o = 1;
|
|
6715
6781
|
if (isNaN(Number(r))) {
|
|
6716
6782
|
let e = await t.prepare("SELECT id FROM trees WHERE key = ?").get(r);
|
|
6717
6783
|
if (e && e.id) o = Number(e.id);
|
|
@@ -6721,7 +6787,7 @@ G.get("/tree.json", async (e) => {
|
|
|
6721
6787
|
}
|
|
6722
6788
|
} else o = Number(r);
|
|
6723
6789
|
if (n.tree && Array.isArray(n.tree)) {
|
|
6724
|
-
let r =
|
|
6790
|
+
let r = _e(n.tree, null);
|
|
6725
6791
|
if (r.length > 0) for (let e = 0; e < r.length; e += 50) {
|
|
6726
6792
|
let n = r.slice(e, e + 50), i = n.map((e) => e.id), a = i.map(() => "?").join(","), s = "UPDATE tree_nodes SET \n";
|
|
6727
6793
|
s += "parentId = CASE id \n", n.forEach(() => {
|
|
@@ -6741,9 +6807,9 @@ G.get("/tree.json", async (e) => {
|
|
|
6741
6807
|
reorderedCount: r.length
|
|
6742
6808
|
});
|
|
6743
6809
|
}
|
|
6744
|
-
let { action: s, title: c, nodeType: l, parentId: u, contentId: d, nodeData: f = {}, pageData: p = {} } = n, m = Object.keys(f).length > 0 ? { ...f } : { ...p }, h =
|
|
6810
|
+
let { action: s, title: c, nodeType: l, parentId: u, contentId: d, nodeData: f = {}, pageData: p = {} } = n, m = Object.keys(f).length > 0 ? { ...f } : { ...p }, h = ve(n.isHidden === void 0 ? m.isHidden === void 0 ? m.hidden : m.isHidden : n.isHidden);
|
|
6745
6811
|
delete m._isTreeDraft, delete m._draftParentId, delete m.isNew, delete m.nodeType, delete m.contentType, delete m.title, delete m.slug, delete m.hidden, delete m.is_hidden, delete m.isHidden, delete m.status;
|
|
6746
|
-
let g =
|
|
6812
|
+
let g = G(u), _ = e.get("user")?.id || null;
|
|
6747
6813
|
if (s === "create") {
|
|
6748
6814
|
let r = m.slug || n.slug || c, s = r ? String(r).toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "") : null;
|
|
6749
6815
|
if (s) {
|
|
@@ -6765,23 +6831,41 @@ G.get("/tree.json", async (e) => {
|
|
|
6765
6831
|
field: "slug"
|
|
6766
6832
|
}, 409);
|
|
6767
6833
|
}
|
|
6768
|
-
let u =
|
|
6769
|
-
|
|
6770
|
-
|
|
6834
|
+
let u = m.language?.trim() || n.language?.trim() || null;
|
|
6835
|
+
if (!u) {
|
|
6836
|
+
let e = await t.prepare("SELECT dataJson FROM trees WHERE id = ?").get(o);
|
|
6837
|
+
if (e?.dataJson) try {
|
|
6838
|
+
let t = typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson;
|
|
6839
|
+
t.defaultLanguage && (u = t.defaultLanguage.trim());
|
|
6840
|
+
} catch {}
|
|
6841
|
+
}
|
|
6842
|
+
if (!u) {
|
|
6843
|
+
let e = [];
|
|
6844
|
+
if (n.channels && Array.isArray(n.channels) ? e = n.channels : n.channelId && n.channelId !== "all" && (e = [n.channelId]), e.length > 0) {
|
|
6845
|
+
let n = Number(e[0]);
|
|
6846
|
+
if (!isNaN(n)) {
|
|
6847
|
+
let e = await t.prepare("SELECT defaultLanguage FROM channels WHERE id = ?").get(n);
|
|
6848
|
+
e?.defaultLanguage && (u = e.defaultLanguage.trim());
|
|
6849
|
+
}
|
|
6850
|
+
}
|
|
6851
|
+
}
|
|
6852
|
+
let d = JSON.stringify(m), f = await t.prepare("\n INSERT INTO content_nodes (contentType, title, slug, language, isHidden, status, draftDataJson, dataJson, createdById, updatedById)\n VALUES (?, ?, ?, ?, ?, 'draft', ?, NULL, ?, ?)\n ").run(l || "page", c || "Untitled", s, u, h, d, _, _), p = Number(f.lastInsertRowid);
|
|
6853
|
+
await t.prepare("DELETE FROM tree_nodes WHERE treeId = ? AND contentId = ?").run(o, p);
|
|
6854
|
+
let v = g === null ? "parentId IS NULL" : "parentId = ?", y = g === null ? [o] : [o, g], b = (await t.prepare(`
|
|
6771
6855
|
SELECT COALESCE(MAX(sortOrder), -1) + 1 as nextSort
|
|
6772
6856
|
FROM tree_nodes
|
|
6773
|
-
WHERE treeId = ? AND ${
|
|
6774
|
-
`).get(...
|
|
6775
|
-
n.channels && Array.isArray(n.channels) ?
|
|
6776
|
-
let
|
|
6777
|
-
if (
|
|
6778
|
-
let e =
|
|
6857
|
+
WHERE treeId = ? AND ${v}
|
|
6858
|
+
`).get(...y))?.nextSort ?? 0, x = await t.prepare("\n INSERT INTO tree_nodes (treeId, contentId, parentId, sortOrder)\n VALUES (?, ?, ?, ?)\n ").run(o, p, g, b), S = Number(x.lastInsertRowid), C = [];
|
|
6859
|
+
n.channels && Array.isArray(n.channels) ? C = n.channels : n.channelId && n.channelId !== "all" && (C = [n.channelId]);
|
|
6860
|
+
let w = [...new Set(C)].filter((e) => e && e !== "all").map((e) => Number(e));
|
|
6861
|
+
if (w.length > 0) {
|
|
6862
|
+
let e = w.map(() => "(?, ?)").join(", "), n = w.flatMap((e) => [p, e]);
|
|
6779
6863
|
await t.prepare(`INSERT OR IGNORE INTO node_channels (nodeId, channelId) VALUES ${e}`).run(...n);
|
|
6780
6864
|
}
|
|
6781
6865
|
return await i.clear(), a.purgeGlobalCache(e, t), e.json({
|
|
6782
6866
|
success: !0,
|
|
6783
|
-
id:
|
|
6784
|
-
treeNodeId:
|
|
6867
|
+
id: p,
|
|
6868
|
+
treeNodeId: S,
|
|
6785
6869
|
status: "draft"
|
|
6786
6870
|
}, 201);
|
|
6787
6871
|
}
|
|
@@ -6832,7 +6916,7 @@ G.get("/tree.json", async (e) => {
|
|
|
6832
6916
|
details: t.message
|
|
6833
6917
|
}, 500);
|
|
6834
6918
|
}
|
|
6835
|
-
}),
|
|
6919
|
+
}), W.get("/trees.json", async (e) => {
|
|
6836
6920
|
try {
|
|
6837
6921
|
let t = e.get("db"), n = await t.prepare("SELECT * FROM trees ORDER BY LOWER(label) ASC").all(), r = Array.isArray(n) ? n : n?.results || [], i = await t.prepare("SELECT channelId, treeId FROM channel_trees").all(), a = (Array.isArray(i) ? i : i?.results || []).reduce((e, t) => {
|
|
6838
6922
|
let n = Number(t.treeId), r = Number(t.channelId);
|
|
@@ -6862,7 +6946,7 @@ G.get("/tree.json", async (e) => {
|
|
|
6862
6946
|
} catch {
|
|
6863
6947
|
return e.json([]);
|
|
6864
6948
|
}
|
|
6865
|
-
}),
|
|
6949
|
+
}), W.post("/trees.json", async (e) => {
|
|
6866
6950
|
try {
|
|
6867
6951
|
let t = e.get("db"), n = await e.req.json(), r = n.id, i = r != null && r !== "" && !isNaN(Number(r)) ? Number(r) : null, a = `tree-${Date.now().toString(36)}`, o = (n.key || n.slug || a).toLowerCase().replace(/[^a-z0-9_-]/g, "-"), s = n.label?.trim() || o, c = n.treeType !== void 0 && n.treeType !== null ? n.treeType : n.type ?? "site", l = n.channelId !== void 0 && n.channelId !== null && Number(n.channelId) || null, u = +(n.isHidden === !0 || n.isHidden === 1 || n.isHidden === "true"), d = e.get("user")?.id || null, f = { ...n };
|
|
6868
6952
|
if (delete f.id, delete f.key, delete f.label, delete f.treeType, delete f.type, delete f.channelId, delete f.channels, delete f.isHidden, delete f.createdById, delete f.updatedById, delete f.createdAt, delete f.updatedAt, await t.prepare("SELECT id FROM trees WHERE key = ? AND id != ? LIMIT 1").get(o, i ?? -1)) return e.json({
|
|
@@ -6887,7 +6971,7 @@ G.get("/tree.json", async (e) => {
|
|
|
6887
6971
|
await t.prepare(`INSERT OR IGNORE INTO channel_trees (channelId, treeId, key) VALUES ${n}`).run(...r);
|
|
6888
6972
|
}
|
|
6889
6973
|
}
|
|
6890
|
-
return await I(e).clear(), new
|
|
6974
|
+
return await I(e).clear(), new V(e.env).purgeGlobalCache(e, t), e.json({
|
|
6891
6975
|
success: !0,
|
|
6892
6976
|
id: p,
|
|
6893
6977
|
key: o,
|
|
@@ -6901,12 +6985,12 @@ G.get("/tree.json", async (e) => {
|
|
|
6901
6985
|
} catch (t) {
|
|
6902
6986
|
return console.error("[API Trees] Error saving tree:", t), e.json({ error: t.message || "Failed to save tree" }, 500);
|
|
6903
6987
|
}
|
|
6904
|
-
}),
|
|
6988
|
+
}), W.delete("/trees.json", async (e) => {
|
|
6905
6989
|
let t = e.get("db"), n = e.req.query("id");
|
|
6906
6990
|
if (!n) return e.json({ error: "Tree ID required" }, 400);
|
|
6907
6991
|
let r = Number(n);
|
|
6908
6992
|
try {
|
|
6909
|
-
return await t.prepare("DELETE FROM trees WHERE id = ?").run(r), await t.prepare("DELETE FROM channel_trees WHERE treeId = ?").run(r), await t.prepare("DELETE FROM tree_nodes WHERE treeId = ?").run(r), await I(e).clear(), new
|
|
6993
|
+
return await t.prepare("DELETE FROM trees WHERE id = ?").run(r), await t.prepare("DELETE FROM channel_trees WHERE treeId = ?").run(r), await t.prepare("DELETE FROM tree_nodes WHERE treeId = ?").run(r), await I(e).clear(), new V(e.env).purgeGlobalCache(e, t), e.json({
|
|
6910
6994
|
success: !0,
|
|
6911
6995
|
deletedTreeId: r
|
|
6912
6996
|
});
|
|
@@ -6916,8 +7000,8 @@ G.get("/tree.json", async (e) => {
|
|
|
6916
7000
|
});
|
|
6917
7001
|
//#endregion
|
|
6918
7002
|
//#region server/routes/admin/channels.ts
|
|
6919
|
-
var
|
|
6920
|
-
|
|
7003
|
+
var ye = new e();
|
|
7004
|
+
ye.get("/", async (e) => {
|
|
6921
7005
|
try {
|
|
6922
7006
|
let t = e.get("db"), n = await t.prepare("SELECT * FROM channels ORDER BY id ASC").all(), r = Array.isArray(n) ? n : n?.results || [], i = await t.prepare("SELECT channelId, treeId, key, metaJson FROM channel_trees").all(), a = ((Array.isArray(i) ? i : i?.results || []) || []).reduce((e, t) => {
|
|
6923
7007
|
e[t.channelId] || (e[t.channelId] = []);
|
|
@@ -6941,7 +7025,7 @@ ve.get("/", async (e) => {
|
|
|
6941
7025
|
isHidden: !!e.isHidden,
|
|
6942
7026
|
trees: a[e.id] || []
|
|
6943
7027
|
};
|
|
6944
|
-
}), s = e.env?.BUNDLED_DEFINITIONS, c =
|
|
7028
|
+
}), s = e.env?.BUNDLED_DEFINITIONS, c = se(s), l = c?.channelTemplate || Object.values(c?.channels || {})[0] || {
|
|
6945
7029
|
label: "Channel Settings",
|
|
6946
7030
|
fields: {
|
|
6947
7031
|
key: {
|
|
@@ -6973,7 +7057,7 @@ ve.get("/", async (e) => {
|
|
|
6973
7057
|
}
|
|
6974
7058
|
};
|
|
6975
7059
|
return e.json({
|
|
6976
|
-
schema:
|
|
7060
|
+
schema: l,
|
|
6977
7061
|
channels: o
|
|
6978
7062
|
});
|
|
6979
7063
|
} catch (t) {
|
|
@@ -6983,24 +7067,26 @@ ve.get("/", async (e) => {
|
|
|
6983
7067
|
error: t.message
|
|
6984
7068
|
}, 500);
|
|
6985
7069
|
}
|
|
6986
|
-
}),
|
|
7070
|
+
}), ye.post("/", async (e) => {
|
|
6987
7071
|
try {
|
|
6988
|
-
let t = e.get("db"), n = await e.req.json(), r = n.
|
|
6989
|
-
|
|
6990
|
-
|
|
7072
|
+
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 || "";
|
|
7073
|
+
typeof T == "object" && T && (T = T.value || T.id || ""), T = String(T).trim();
|
|
7074
|
+
let E = m === !0 || m === "true" || m === 1 || h === !0 || h === "true" || h === 1, D = Array.isArray(g) ? g : [], O = JSON.stringify(S || {}), k = e.get("user")?.id || v || _ || null;
|
|
7075
|
+
if (await t.prepare("SELECT id FROM channels WHERE key = ? AND id != ? LIMIT 1").get(C, a ?? -1)) return e.json({
|
|
7076
|
+
error: `Channel API key "${C}" is already in use.`,
|
|
6991
7077
|
field: "key"
|
|
6992
7078
|
}, 409);
|
|
6993
|
-
let
|
|
6994
|
-
if (
|
|
7079
|
+
let A = a;
|
|
7080
|
+
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, +!!E, O, k, a);
|
|
6995
7081
|
else {
|
|
6996
|
-
let e = await t.prepare("\n INSERT INTO channels (key, label, channelType, domain, baseUrl, defaultLanguage, isHidden, dataJson, createdById, updatedById)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ").run(
|
|
6997
|
-
|
|
7082
|
+
let e = await t.prepare("\n INSERT INTO channels (key, label, channelType, domain, baseUrl, defaultLanguage, isHidden, dataJson, createdById, updatedById)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ").run(C, w, c, l, u, T, +!!E, O, k, k);
|
|
7083
|
+
A = Number(e.lastInsertRowid);
|
|
6998
7084
|
}
|
|
6999
|
-
await t.prepare("DELETE FROM channel_trees WHERE channelId = ?").run(
|
|
7000
|
-
let
|
|
7001
|
-
if (
|
|
7002
|
-
let e =
|
|
7003
|
-
|
|
7085
|
+
await t.prepare("DELETE FROM channel_trees WHERE channelId = ?").run(A);
|
|
7086
|
+
let j = D.filter((e) => e && e.treeId && e.key);
|
|
7087
|
+
if (j.length > 0) {
|
|
7088
|
+
let e = j.map(() => "(?, ?, ?, ?)").join(", "), n = j.flatMap((e) => [
|
|
7089
|
+
A,
|
|
7004
7090
|
Number(e.treeId) || e.treeId,
|
|
7005
7091
|
String(e.key).trim(),
|
|
7006
7092
|
JSON.stringify(e.meta || {})
|
|
@@ -7010,9 +7096,10 @@ ve.get("/", async (e) => {
|
|
|
7010
7096
|
VALUES ${e}
|
|
7011
7097
|
`).run(...n);
|
|
7012
7098
|
}
|
|
7013
|
-
|
|
7099
|
+
let M = I(e);
|
|
7100
|
+
return await M.delete(`channel:${C}`), await M.delete(`channel:${A}`), await M.clear(), new V(e.env).purgeGlobalCache(e, t), e.json({
|
|
7014
7101
|
success: !0,
|
|
7015
|
-
id:
|
|
7102
|
+
id: A
|
|
7016
7103
|
});
|
|
7017
7104
|
} catch (t) {
|
|
7018
7105
|
return console.error("[API Channels] Error saving channel:", t), e.json({
|
|
@@ -7020,12 +7107,14 @@ ve.get("/", async (e) => {
|
|
|
7020
7107
|
details: t.message
|
|
7021
7108
|
}, 500);
|
|
7022
7109
|
}
|
|
7023
|
-
}),
|
|
7110
|
+
}), ye.delete("/", async (e) => {
|
|
7024
7111
|
let t = e.get("db"), n = e.req.query("id");
|
|
7025
7112
|
if (!n) return e.json({ error: "Channel ID required" }, 400);
|
|
7026
7113
|
let r = Number(n);
|
|
7027
7114
|
try {
|
|
7028
|
-
|
|
7115
|
+
await t.prepare("DELETE FROM channel_trees WHERE channelId = ?").run(r), await t.prepare("DELETE FROM node_channels WHERE channelId = ?").run(r), await t.prepare("DELETE FROM channels WHERE id = ?").run(r);
|
|
7116
|
+
let n = I(e);
|
|
7117
|
+
return await n.delete(`channel:${r}`), await n.clear(), new V(e.env).purgeGlobalCache(e, t), e.json({
|
|
7029
7118
|
success: !0,
|
|
7030
7119
|
deletedSiteId: r
|
|
7031
7120
|
});
|
|
@@ -7043,11 +7132,11 @@ if (typeof process < "u" && process?.versions?.node) try {
|
|
|
7043
7132
|
let e = i(import.meta.url);
|
|
7044
7133
|
K = e("node:fs"), q = e("node:path");
|
|
7045
7134
|
} catch {}
|
|
7046
|
-
function
|
|
7135
|
+
function be(e, t = "") {
|
|
7047
7136
|
let n = e.split(/[\\/]/).pop() || "";
|
|
7048
7137
|
return t && n.endsWith(t) ? n.slice(0, -t.length) : n;
|
|
7049
7138
|
}
|
|
7050
|
-
function
|
|
7139
|
+
function xe(e) {
|
|
7051
7140
|
let t = e.match(/\.[^.\\/]+$/);
|
|
7052
7141
|
return t ? t[0] : "";
|
|
7053
7142
|
}
|
|
@@ -7060,7 +7149,7 @@ var J = {
|
|
|
7060
7149
|
nodeLayouts: {},
|
|
7061
7150
|
blockLayouts: {}
|
|
7062
7151
|
};
|
|
7063
|
-
function
|
|
7152
|
+
function Se(e) {
|
|
7064
7153
|
return e ? typeof e == "string" ? e.trim() : Array.isArray(e) ? e.includes("*") ? "*" : e : "*" : "*";
|
|
7065
7154
|
}
|
|
7066
7155
|
function Y(e = {}, t = {}) {
|
|
@@ -7075,47 +7164,47 @@ function Y(e = {}, t = {}) {
|
|
|
7075
7164
|
};
|
|
7076
7165
|
return t.required === !0 || String(t.required).toLowerCase() === "true" || t.rules?.required === !0 || String(t.rules?.required).toLowerCase() === "true" || t.required === void 0 && (e.required === !0 || String(e.required).toLowerCase() === "true" || e.rules?.required === !0 || String(e.rules?.required).toLowerCase() === "true") ? (n.required = !0, n.rules.required = !0) : (t.required === !1 || t.rules?.required === !1) && (n.required = !1, n.rules.required = !1), n;
|
|
7077
7166
|
}
|
|
7078
|
-
function
|
|
7167
|
+
function Ce(e) {
|
|
7079
7168
|
if (!e || typeof e != "object") return e;
|
|
7080
|
-
if (Array.isArray(e)) return e.map(
|
|
7169
|
+
if (Array.isArray(e)) return e.map(Ce);
|
|
7081
7170
|
let t = {};
|
|
7082
7171
|
for (let [n, r] of Object.entries(e)) if (n === "<<" || n === "<<:") {
|
|
7083
|
-
let e =
|
|
7172
|
+
let e = Ce(r);
|
|
7084
7173
|
if (typeof e == "object" && e) {
|
|
7085
7174
|
if (Array.isArray(e)) for (let n of e) Object.assign(t, n);
|
|
7086
7175
|
else Object.assign(t, e);
|
|
7087
7176
|
}
|
|
7088
|
-
} else t[n] =
|
|
7177
|
+
} else t[n] = Ce(r);
|
|
7089
7178
|
return t;
|
|
7090
7179
|
}
|
|
7091
|
-
function
|
|
7092
|
-
return e ?
|
|
7180
|
+
function we(e, t) {
|
|
7181
|
+
return e ? Ce(n.parseDocument(e, { customTags: [{
|
|
7093
7182
|
tag: "!include",
|
|
7094
7183
|
resolve(e) {
|
|
7095
|
-
let n = (typeof e == "string" ? e : String(e?.strValue || e?.value || "")).trim(), r =
|
|
7184
|
+
let n = (typeof e == "string" ? e : String(e?.strValue || e?.value || "")).trim(), r = be(n);
|
|
7096
7185
|
if (!r) return n;
|
|
7097
7186
|
if (t && t.fieldSets) {
|
|
7098
7187
|
let e = Object.keys(t.fieldSets).find((e) => e.endsWith("/" + r) || e === r);
|
|
7099
|
-
if (e) return
|
|
7188
|
+
if (e) return we(t.fieldSets[e], t);
|
|
7100
7189
|
}
|
|
7101
7190
|
return n;
|
|
7102
7191
|
}
|
|
7103
7192
|
}] }).toJS() || {}) : {};
|
|
7104
7193
|
}
|
|
7105
|
-
function
|
|
7194
|
+
function Te(e, t = /* @__PURE__ */ new Set()) {
|
|
7106
7195
|
if (!K || !q) return {};
|
|
7107
7196
|
let r = q.resolve(e);
|
|
7108
7197
|
if (t.has(r) || (t.add(r), !K.existsSync(r))) return {};
|
|
7109
7198
|
let i = K.readFileSync(r, "utf-8");
|
|
7110
|
-
return
|
|
7199
|
+
return Ce(n.parseDocument(i, { customTags: [{
|
|
7111
7200
|
tag: "!include",
|
|
7112
7201
|
resolve(e) {
|
|
7113
7202
|
let n = (typeof e == "string" ? e : String(e?.strValue || e?.value || "")).trim();
|
|
7114
|
-
return n ?
|
|
7203
|
+
return n ? Te(q.resolve(q.dirname(r), n), new Set(t)) : {};
|
|
7115
7204
|
}
|
|
7116
7205
|
}] }).toJS() || {});
|
|
7117
7206
|
}
|
|
7118
|
-
function
|
|
7207
|
+
function Ee() {
|
|
7119
7208
|
if (!K || !q || typeof process > "u" || !process?.versions?.node) return null;
|
|
7120
7209
|
try {
|
|
7121
7210
|
let e = process.cwd(), t = "", n = [
|
|
@@ -7148,9 +7237,9 @@ function Te() {
|
|
|
7148
7237
|
let r = {}, i = K.readdirSync(n);
|
|
7149
7238
|
for (let e of i) {
|
|
7150
7239
|
if (!e.endsWith(".yaml") && !e.endsWith(".yml")) continue;
|
|
7151
|
-
let t = q.join(n, e), i =
|
|
7240
|
+
let t = q.join(n, e), i = be(e, xe(e));
|
|
7152
7241
|
try {
|
|
7153
|
-
r[i] =
|
|
7242
|
+
r[i] = Te(t);
|
|
7154
7243
|
} catch (t) {
|
|
7155
7244
|
console.error(`❌ Error parsing ${e}:`, t.message);
|
|
7156
7245
|
}
|
|
@@ -7178,14 +7267,14 @@ function Te() {
|
|
|
7178
7267
|
return console.error("❌ Exception inside readLocalFsBundle:", e), null;
|
|
7179
7268
|
}
|
|
7180
7269
|
}
|
|
7181
|
-
var
|
|
7182
|
-
function Oe(e) {
|
|
7183
|
-
if (!e) Ee = null, De = null;
|
|
7184
|
-
else if (Ee && De === e) return Ee;
|
|
7185
|
-
let t = ke(e);
|
|
7186
|
-
return Ee = t, De = e, t;
|
|
7187
|
-
}
|
|
7270
|
+
var De = null, Oe = null;
|
|
7188
7271
|
function ke(e) {
|
|
7272
|
+
if (!e) De = null, Oe = null;
|
|
7273
|
+
else if (De && Oe === e) return De;
|
|
7274
|
+
let t = Ae(e);
|
|
7275
|
+
return De = t, Oe = e, t;
|
|
7276
|
+
}
|
|
7277
|
+
function Ae(e) {
|
|
7189
7278
|
if (e) {
|
|
7190
7279
|
let t = {
|
|
7191
7280
|
nodes: {
|
|
@@ -7221,12 +7310,12 @@ function ke(e) {
|
|
|
7221
7310
|
let e = (e) => {
|
|
7222
7311
|
let n = {};
|
|
7223
7312
|
for (let [r, i] of Object.entries(e || {})) {
|
|
7224
|
-
let e =
|
|
7225
|
-
n[e] =
|
|
7313
|
+
let e = be(r, xe(r));
|
|
7314
|
+
n[e] = we(i, t);
|
|
7226
7315
|
}
|
|
7227
7316
|
return n;
|
|
7228
7317
|
};
|
|
7229
|
-
return
|
|
7318
|
+
return je({
|
|
7230
7319
|
rawNodes: e(t.nodes),
|
|
7231
7320
|
rawTrees: e(t.trees),
|
|
7232
7321
|
rawChannels: e(t.channels),
|
|
@@ -7236,12 +7325,12 @@ function ke(e) {
|
|
|
7236
7325
|
rawFieldSets: e(t.fieldSets)
|
|
7237
7326
|
});
|
|
7238
7327
|
}
|
|
7239
|
-
return
|
|
7328
|
+
return je(t);
|
|
7240
7329
|
}
|
|
7241
|
-
let t =
|
|
7242
|
-
return t && Object.keys(t.rawNodes || {}).length > 0 ?
|
|
7330
|
+
let t = Ee();
|
|
7331
|
+
return t && Object.keys(t.rawNodes || {}).length > 0 ? je(t) : je(null);
|
|
7243
7332
|
}
|
|
7244
|
-
function
|
|
7333
|
+
function je(e) {
|
|
7245
7334
|
if (!e) return {
|
|
7246
7335
|
nodes: {},
|
|
7247
7336
|
trees: {},
|
|
@@ -7376,8 +7465,8 @@ function Ae(e) {
|
|
|
7376
7465
|
inVault: t.inVault !== !1,
|
|
7377
7466
|
hasCanvas: t.hasCanvas === !0,
|
|
7378
7467
|
defaultLayout: t.defaultLayout,
|
|
7379
|
-
allowedBlocks:
|
|
7380
|
-
disallowedBlocks: t.disallowedBlocks ?
|
|
7468
|
+
allowedBlocks: Se(t.allowedBlocks),
|
|
7469
|
+
disallowedBlocks: t.disallowedBlocks ? Se(t.disallowedBlocks) : void 0,
|
|
7381
7470
|
tabs: n,
|
|
7382
7471
|
fields: r
|
|
7383
7472
|
};
|
|
@@ -7439,17 +7528,17 @@ function Ae(e) {
|
|
|
7439
7528
|
fields: n
|
|
7440
7529
|
};
|
|
7441
7530
|
});
|
|
7442
|
-
let
|
|
7531
|
+
let P = {};
|
|
7443
7532
|
Object.entries(T).forEach(([e, t]) => {
|
|
7444
7533
|
let n = A(t.tabs), r = k(t.fields || [], "settings", n), i = {}, a = t.regions || { content: { label: "Content" } };
|
|
7445
7534
|
Object.entries(a).forEach(([e, t]) => {
|
|
7446
7535
|
i[e] = {
|
|
7447
7536
|
...t,
|
|
7448
7537
|
label: t.label || e,
|
|
7449
|
-
allowedBlocks:
|
|
7450
|
-
disallowedBlocks: t.disallowedBlocks ?
|
|
7538
|
+
allowedBlocks: Se(t.allowedBlocks),
|
|
7539
|
+
disallowedBlocks: t.disallowedBlocks ? Se(t.disallowedBlocks) : void 0
|
|
7451
7540
|
};
|
|
7452
|
-
}),
|
|
7541
|
+
}), P[e] = {
|
|
7453
7542
|
...t,
|
|
7454
7543
|
id: t.id || e,
|
|
7455
7544
|
label: t.label || e,
|
|
@@ -7462,17 +7551,17 @@ function Ae(e) {
|
|
|
7462
7551
|
tabs: n
|
|
7463
7552
|
};
|
|
7464
7553
|
});
|
|
7465
|
-
let
|
|
7554
|
+
let te = {};
|
|
7466
7555
|
Object.entries(E).forEach(([e, t]) => {
|
|
7467
7556
|
let n = A(t.tabs), r = k(t.fields || [], "settings", n), i = {}, a = t.regions || { main: { label: "Main Content" } };
|
|
7468
7557
|
Object.entries(a).forEach(([e, t]) => {
|
|
7469
7558
|
i[e] = {
|
|
7470
7559
|
...t,
|
|
7471
7560
|
label: t.label || e,
|
|
7472
|
-
allowedBlocks:
|
|
7473
|
-
disallowedBlocks: t.disallowedBlocks ?
|
|
7561
|
+
allowedBlocks: Se(t.allowedBlocks),
|
|
7562
|
+
disallowedBlocks: t.disallowedBlocks ? Se(t.disallowedBlocks) : void 0
|
|
7474
7563
|
};
|
|
7475
|
-
}),
|
|
7564
|
+
}), te[e] = {
|
|
7476
7565
|
...t,
|
|
7477
7566
|
id: t.id || e,
|
|
7478
7567
|
label: t.label || e,
|
|
@@ -7502,7 +7591,7 @@ function Ae(e) {
|
|
|
7502
7591
|
L[e] = Y(L[e] || {}, t);
|
|
7503
7592
|
});
|
|
7504
7593
|
});
|
|
7505
|
-
let
|
|
7594
|
+
let ne = h ? {
|
|
7506
7595
|
...h,
|
|
7507
7596
|
fields: L
|
|
7508
7597
|
} : null;
|
|
@@ -7511,22 +7600,22 @@ function Ae(e) {
|
|
|
7511
7600
|
trees: M,
|
|
7512
7601
|
channels: N,
|
|
7513
7602
|
blocks: ee,
|
|
7514
|
-
nodeLayouts:
|
|
7515
|
-
blockLayouts:
|
|
7603
|
+
nodeLayouts: P,
|
|
7604
|
+
blockLayouts: te,
|
|
7516
7605
|
fieldSets: O,
|
|
7517
7606
|
nodeTemplate: f || null,
|
|
7518
7607
|
treeTemplate: p || null,
|
|
7519
7608
|
channelTemplate: I,
|
|
7520
|
-
userTemplate:
|
|
7609
|
+
userTemplate: ne
|
|
7521
7610
|
};
|
|
7522
7611
|
}
|
|
7523
7612
|
//#endregion
|
|
7524
7613
|
//#region server/routes/admin/schemas.ts
|
|
7525
|
-
var
|
|
7614
|
+
var Me = new e(), Ne = (e) => {
|
|
7526
7615
|
try {
|
|
7527
7616
|
let t = e.env?.BUNDLED_DEFINITIONS;
|
|
7528
7617
|
(!t || Object.keys(t).length === 0) && (t = f || d || u);
|
|
7529
|
-
let n =
|
|
7618
|
+
let n = ke(t);
|
|
7530
7619
|
return e.json(n, 200, { "Cache-Control": "no-cache, no-store, must-revalidate" });
|
|
7531
7620
|
} catch (t) {
|
|
7532
7621
|
return console.error("[CMS API] Error loading schemas:", t), e.json({
|
|
@@ -7535,10 +7624,10 @@ var je = new e(), Me = (e) => {
|
|
|
7535
7624
|
}, 500);
|
|
7536
7625
|
}
|
|
7537
7626
|
};
|
|
7538
|
-
|
|
7627
|
+
Me.get("/", Ne), Me.get("/schemas.json", Ne);
|
|
7539
7628
|
//#endregion
|
|
7540
7629
|
//#region server/routes/admin/validation.ts
|
|
7541
|
-
var
|
|
7630
|
+
var Pe = new e(), Fe = {
|
|
7542
7631
|
node: "content_nodes",
|
|
7543
7632
|
nodes: "content_nodes",
|
|
7544
7633
|
content_node: "content_nodes",
|
|
@@ -7550,7 +7639,7 @@ var Ne = new e(), Pe = {
|
|
|
7550
7639
|
user: "users",
|
|
7551
7640
|
users: "users",
|
|
7552
7641
|
user_account: "user_accounts"
|
|
7553
|
-
},
|
|
7642
|
+
}, Ie = {
|
|
7554
7643
|
content_nodes: [
|
|
7555
7644
|
"id",
|
|
7556
7645
|
"title",
|
|
@@ -7607,11 +7696,11 @@ var Ne = new e(), Pe = {
|
|
|
7607
7696
|
"createdAt"
|
|
7608
7697
|
]
|
|
7609
7698
|
};
|
|
7610
|
-
|
|
7699
|
+
Pe.post("/validate-unique", async (e) => {
|
|
7611
7700
|
try {
|
|
7612
7701
|
let t = e.get("db"), { entityType: n, field: r, value: i, excludeId: a } = await e.req.json();
|
|
7613
7702
|
if (!r || i == null || String(i).trim() === "") return e.json({ isUnique: !0 });
|
|
7614
|
-
let o =
|
|
7703
|
+
let o = Fe[n] || "content_nodes", s = r.replace(/[^a-zA-Z0-9_]/g, ""), c = (Ie[o] || Ie.content_nodes).includes(s), l = -1;
|
|
7615
7704
|
if (a != null && String(a).trim() !== "") {
|
|
7616
7705
|
let e = Number(a);
|
|
7617
7706
|
l = isNaN(e) ? String(a) : e;
|
|
@@ -7623,11 +7712,11 @@ Ne.post("/validate-unique", async (e) => {
|
|
|
7623
7712
|
} catch (t) {
|
|
7624
7713
|
return console.error("[API Validation] Error validating global uniqueness:", t), e.json({ error: "Failed to validate uniqueness" }, 500);
|
|
7625
7714
|
}
|
|
7626
|
-
}),
|
|
7715
|
+
}), Pe.post("/validate-unique-sibling", async (e) => e.json({ isUnique: !0 }));
|
|
7627
7716
|
//#endregion
|
|
7628
7717
|
//#region server/routes/admin/stats.ts
|
|
7629
|
-
var
|
|
7630
|
-
|
|
7718
|
+
var Le = new e();
|
|
7719
|
+
Le.get("/", async (e) => {
|
|
7631
7720
|
try {
|
|
7632
7721
|
let t = e.get("db"), n = await t.prepare("\n SELECT \n COUNT(*) as total,\n SUM(CASE WHEN isHidden = 0 THEN 1 ELSE 0 END) as published,\n SUM(CASE WHEN isHidden = 1 THEN 1 ELSE 0 END) as hidden\n FROM content_nodes\n WHERE deletedAt IS NULL OR deletedAt = ''\n ").get(), r = Number(n?.total) || 0, i = Number(n?.published) || 0, a = Number(n?.hidden) || 0, o = await t.prepare("\n SELECT \n (SELECT COUNT(*) FROM channels) as totalChannels,\n (SELECT COUNT(*) FROM trees) as totalTrees,\n (SELECT COUNT(*) FROM users) as totalUsers\n ").get(), s = await t.prepare("\n SELECT contentType as type, COUNT(*) as count \n FROM content_nodes \n WHERE deletedAt IS NULL OR deletedAt = ''\n GROUP BY contentType \n ORDER BY count DESC\n ").all(), c = Array.isArray(s) ? s : s?.results || [], l = await t.prepare("\n SELECT id, title, slug, contentType, isHidden, status, updatedAt \n FROM content_nodes \n WHERE deletedAt IS NULL OR deletedAt = ''\n ORDER BY updatedAt DESC \n LIMIT 5\n ").all(), u = (Array.isArray(l) ? l : l?.results || []).map((e) => ({
|
|
7633
7722
|
...e,
|
|
@@ -7644,7 +7733,7 @@ Ie.get("/", async (e) => {
|
|
|
7644
7733
|
isHidden: !!e.isHidden,
|
|
7645
7734
|
channelNames: e.channelLabels ? e.channelLabels.split(",") : [],
|
|
7646
7735
|
treeNames: e.treeLabels ? e.treeLabels.split(",") : []
|
|
7647
|
-
})), p = e.env?.BUNDLED_DEFINITIONS, m =
|
|
7736
|
+
})), p = e.env?.BUNDLED_DEFINITIONS, m = se(p), h = m.nodes || m.nodeSchemas || {}, g = c.map((e) => {
|
|
7648
7737
|
let t = e.type || "node", n = h[t]?.label || t.charAt(0).toUpperCase() + t.slice(1);
|
|
7649
7738
|
return {
|
|
7650
7739
|
type: t,
|
|
@@ -7690,7 +7779,7 @@ async function Q(e, t, n = []) {
|
|
|
7690
7779
|
if (typeof r.bind == "function") return await r.bind(...n).run();
|
|
7691
7780
|
if (typeof r.run == "function") return await r.run(...n);
|
|
7692
7781
|
}
|
|
7693
|
-
function
|
|
7782
|
+
function Re(e, t, n) {
|
|
7694
7783
|
let r = e || (t ? `/media/${t}` : "");
|
|
7695
7784
|
return r && n && r.startsWith(`https://${n}/`) && !r.includes("/media/") && (r = r.replace(`https://${n}/`, `https://${n}/media/`)), r;
|
|
7696
7785
|
}
|
|
@@ -7732,7 +7821,7 @@ X.get("/", async (e) => {
|
|
|
7732
7821
|
...JSON.parse(t.dataJson || "{}")
|
|
7733
7822
|
};
|
|
7734
7823
|
} catch {}
|
|
7735
|
-
let r =
|
|
7824
|
+
let r = Re(t.cdnUrl, t.storageKeyPrivate, e.env?.CDN_DOMAIN);
|
|
7736
7825
|
return {
|
|
7737
7826
|
id: t.id,
|
|
7738
7827
|
filename: t.filename || "Untitled Asset",
|
|
@@ -7758,7 +7847,7 @@ X.get("/", async (e) => {
|
|
|
7758
7847
|
}
|
|
7759
7848
|
}), X.post("/upload", async (e) => {
|
|
7760
7849
|
try {
|
|
7761
|
-
let t = l(e), { storage: n } =
|
|
7850
|
+
let t = l(e), { storage: n } = ae(e.env), r = await e.req.parseBody(), i = r.file, a = r.isVariant === "true" || r.isVariant === "1" || r.temporary === "true", o = r.parentAssetId || r.parentAsset, s = typeof o == "string" && o.trim().length > 0 ? o.trim() : null;
|
|
7762
7851
|
s && (await Z(t, "SELECT id FROM assets WHERE id = ?", [s])).length === 0 && (s = null);
|
|
7763
7852
|
let c = r.cropCoordinates, u = null, d = null;
|
|
7764
7853
|
if (c) {
|
|
@@ -7790,7 +7879,7 @@ X.get("/", async (e) => {
|
|
|
7790
7879
|
let D = x;
|
|
7791
7880
|
if (s) {
|
|
7792
7881
|
let n = await Z(t, "SELECT cdnUrl, storageKeyPrivate FROM assets WHERE id = ?", [s]);
|
|
7793
|
-
n.length > 0 && (D =
|
|
7882
|
+
n.length > 0 && (D = Re(n[0].cdnUrl, n[0].storageKeyPrivate, y)), new V(e.env).purgeAsset(e, t, s);
|
|
7794
7883
|
}
|
|
7795
7884
|
return e.json({
|
|
7796
7885
|
id: p,
|
|
@@ -7832,7 +7921,7 @@ X.get("/", async (e) => {
|
|
|
7832
7921
|
...JSON.parse(i.dataJson || "{}")
|
|
7833
7922
|
};
|
|
7834
7923
|
} catch {}
|
|
7835
|
-
let u =
|
|
7924
|
+
let u = Re(i.cdnUrl, i.storageKeyPrivate, e.env?.CDN_DOMAIN);
|
|
7836
7925
|
return e.json({
|
|
7837
7926
|
id: i.id,
|
|
7838
7927
|
filename: i.filename,
|
|
@@ -7859,7 +7948,7 @@ X.get("/", async (e) => {
|
|
|
7859
7948
|
createdAt: t.createdAt,
|
|
7860
7949
|
parentAssetId: t.parentAssetId || i.id,
|
|
7861
7950
|
cropCoordinates: n,
|
|
7862
|
-
url:
|
|
7951
|
+
url: Re(t.cdnUrl, t.storageKeyPrivate, e.env?.CDN_DOMAIN),
|
|
7863
7952
|
originalUrl: u
|
|
7864
7953
|
};
|
|
7865
7954
|
})
|
|
@@ -7879,14 +7968,14 @@ X.get("/", async (e) => {
|
|
|
7879
7968
|
r.filename === void 0 ? a.filename : r.filename,
|
|
7880
7969
|
JSON.stringify(o),
|
|
7881
7970
|
n
|
|
7882
|
-
]), new
|
|
7971
|
+
]), new V(e.env).purgeAsset(e, t, n), e.json({ success: !0 });
|
|
7883
7972
|
} catch {
|
|
7884
7973
|
return e.json({ error: "Failed to update asset" }, 500);
|
|
7885
7974
|
}
|
|
7886
7975
|
}), X.delete("/:id", async (e) => {
|
|
7887
7976
|
try {
|
|
7888
7977
|
let t = l(e), n = e.req.param("id"), r = (await Z(t, "SELECT id, filename, isSystemVariant FROM assets WHERE id = ?", [n]))[0];
|
|
7889
|
-
return r ? (new
|
|
7978
|
+
return r ? (new V(e.env).purgeAsset(e, t, n), r.isSystemVariant ? await Q(t, "UPDATE assets SET deletedAt = CURRENT_TIMESTAMP WHERE id = ?", [n]) : await Q(t, "UPDATE assets SET deletedAt = CURRENT_TIMESTAMP WHERE id = ? OR parentAssetId = ? OR (isSystemVariant = 1 AND (filename LIKE ? OR filename LIKE ?))", [
|
|
7890
7979
|
n,
|
|
7891
7980
|
n,
|
|
7892
7981
|
`crop_%${r.filename ? r.filename.replace(/\.[^/.]+$/, "") : ""}%`,
|
|
@@ -7912,7 +8001,7 @@ X.get("/", async (e) => {
|
|
|
7912
8001
|
r,
|
|
7913
8002
|
`crop_%${i.filename ? i.filename.replace(/\.[^/.]+$/, "") : ""}%`,
|
|
7914
8003
|
`%${r}%`
|
|
7915
|
-
]), new
|
|
8004
|
+
]), new V(e.env).purgeAsset(e, t, r), e.json({
|
|
7916
8005
|
success: !0,
|
|
7917
8006
|
id: r,
|
|
7918
8007
|
restored: !0
|
|
@@ -7925,9 +8014,9 @@ X.get("/", async (e) => {
|
|
|
7925
8014
|
}
|
|
7926
8015
|
}), X.delete("/purge/:id", async (e) => {
|
|
7927
8016
|
try {
|
|
7928
|
-
let t = l(e), { storage: n } =
|
|
8017
|
+
let t = l(e), { storage: n } = ae(e.env), r = e.req.param("id"), i = (await Z(t, "SELECT id, filename, storageKeyPrivate, isSystemVariant FROM assets WHERE id = ?", [r]))[0];
|
|
7929
8018
|
if (!i) return e.json({ error: "Asset not found" }, 404);
|
|
7930
|
-
new
|
|
8019
|
+
new V(e.env).purgeAsset(e, t, r);
|
|
7931
8020
|
let a = [i];
|
|
7932
8021
|
i.isSystemVariant || (a = [i, ...await Z(t, "SELECT id, storageKeyPrivate FROM assets WHERE parentAssetId = ? OR (isSystemVariant = 1 AND (filename LIKE ? OR filename LIKE ?))", [
|
|
7933
8022
|
r,
|
|
@@ -7959,8 +8048,8 @@ X.get("/", async (e) => {
|
|
|
7959
8048
|
});
|
|
7960
8049
|
//#endregion
|
|
7961
8050
|
//#region server/routes/public/node.ts
|
|
7962
|
-
var
|
|
7963
|
-
function
|
|
8051
|
+
var ze = new e();
|
|
8052
|
+
function Be() {
|
|
7964
8053
|
return {
|
|
7965
8054
|
fullPath: /* @__PURE__ */ new Map(),
|
|
7966
8055
|
treeEdges: /* @__PURE__ */ new Map(),
|
|
@@ -7968,10 +8057,10 @@ function ze() {
|
|
|
7968
8057
|
assetUrls: /* @__PURE__ */ new Map()
|
|
7969
8058
|
};
|
|
7970
8059
|
}
|
|
7971
|
-
function
|
|
8060
|
+
function Ve(...e) {
|
|
7972
8061
|
return e.map((e) => String(e ?? "")).join(":");
|
|
7973
8062
|
}
|
|
7974
|
-
function
|
|
8063
|
+
function He(e, t) {
|
|
7975
8064
|
let n = Date.now();
|
|
7976
8065
|
if (e && String(e).trim() !== "") {
|
|
7977
8066
|
let t = Date.parse(e);
|
|
@@ -7983,27 +8072,27 @@ function Ve(e, t) {
|
|
|
7983
8072
|
}
|
|
7984
8073
|
return !0;
|
|
7985
8074
|
}
|
|
7986
|
-
async function
|
|
7987
|
-
let
|
|
7988
|
-
await Promise.all(
|
|
7989
|
-
let
|
|
7990
|
-
n && n !== "all" && (
|
|
7991
|
-
let
|
|
7992
|
-
|
|
7993
|
-
let
|
|
7994
|
-
|
|
8075
|
+
async function Ue(e, t, n, r) {
|
|
8076
|
+
let i = t.filter((e) => e.componentId === "content-feed" || e.componentId === "article-list");
|
|
8077
|
+
await Promise.all(i.map(async (t) => {
|
|
8078
|
+
let i = t.data || {}, a = i.nodeType || "article", o = Number(i.limit) || 12, s = i.sortBy || "updatedAt", c = "FROM content_nodes WHERE contentType = ? AND isHidden = 0 AND (status = 'published' OR status IS NULL)", l = [a];
|
|
8079
|
+
n && n !== "all" && (c += " AND id IN (SELECT nodeId FROM node_channels WHERE channelId = ?)", l.push(Number(n) || n));
|
|
8080
|
+
let u = "ORDER BY updatedAt DESC";
|
|
8081
|
+
s === "published_desc" || s === "createdAt" ? u = "ORDER BY createdAt DESC" : s === "title_asc" && (u = "ORDER BY LOWER(title) ASC");
|
|
8082
|
+
let d = `SELECT id, title, slug, language, dataJson, createdAt, updatedAt ${c} ${u} LIMIT ?`;
|
|
8083
|
+
l.push(o);
|
|
7995
8084
|
try {
|
|
7996
|
-
let n = await e.prepare(
|
|
7997
|
-
t.data.initialItems =
|
|
8085
|
+
let n = await e.prepare(d).all(...l), i = Array.isArray(n) ? n : n?.results || [];
|
|
8086
|
+
t.data.initialItems = i.map((e) => {
|
|
7998
8087
|
let t = {};
|
|
7999
8088
|
if (e.dataJson) try {
|
|
8000
8089
|
t = typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson;
|
|
8001
8090
|
} catch {}
|
|
8002
|
-
return
|
|
8091
|
+
return He(t.startShowingAt, t.stopShowingAt) ? {
|
|
8003
8092
|
id: e.id,
|
|
8004
8093
|
title: e.title,
|
|
8005
8094
|
slug: e.slug,
|
|
8006
|
-
language: e.language ||
|
|
8095
|
+
language: e.language?.trim() || r || null,
|
|
8007
8096
|
createdAt: e.createdAt,
|
|
8008
8097
|
updatedAt: e.updatedAt,
|
|
8009
8098
|
excerpt: t.excerpt || "",
|
|
@@ -8016,7 +8105,7 @@ async function He(e, t, n) {
|
|
|
8016
8105
|
}
|
|
8017
8106
|
}));
|
|
8018
8107
|
}
|
|
8019
|
-
async function
|
|
8108
|
+
async function We(e, t, n, r, i = !1, a) {
|
|
8020
8109
|
if (!t) return { blocks: [] };
|
|
8021
8110
|
let o = await e.prepare("\n WITH RECURSIVE ancestor_path(id, contentId, title, slug, parentId, level) AS (\n SELECT t.id, 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.id = ? OR c.id = ?\n UNION ALL\n SELECT t.id, 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.id = ap.parentId\n )\n SELECT * FROM ancestor_path ORDER BY level ASC\n ").all(t, t), s = Array.isArray(o) ? o : o?.results || [];
|
|
8022
8111
|
if (!s || s.length === 0) return { blocks: [] };
|
|
@@ -8052,10 +8141,10 @@ async function Ue(e, t, n, r, i = !1, a) {
|
|
|
8052
8141
|
try {
|
|
8053
8142
|
a = (typeof t.dataJson == "string" ? JSON.parse(t.dataJson) : t.dataJson) || {};
|
|
8054
8143
|
} catch {}
|
|
8055
|
-
let o = a.hidden === !0 || a.hidden === 1 || a.hidden === "1" || a.hidden === "true", s =
|
|
8144
|
+
let o = a.hidden === !0 || a.hidden === 1 || a.hidden === "1" || a.hidden === "true", s = He(a.startShowingAt, a.stopShowingAt);
|
|
8056
8145
|
if (!i && (o || !s)) return null;
|
|
8057
|
-
let c = t.elementType || t.componentId || "text-block", l = r.blocks?.[c]?.fields || r.elements?.[c]?.fields || r.components?.[c]?.fields || {}, u = String(a.blockId || a._instanceId || a.id || t.blockId || t.id), d =
|
|
8058
|
-
return d = await
|
|
8146
|
+
let c = t.elementType || t.componentId || "text-block", l = r.blocks?.[c]?.fields || r.elements?.[c]?.fields || r.components?.[c]?.fields || {}, u = String(a.blockId || a._instanceId || a.id || t.blockId || t.id), d = Ge(a, l);
|
|
8147
|
+
return d = await B(e, d), d = Ke(d), d.blockId = u, {
|
|
8059
8148
|
region: t.region || n,
|
|
8060
8149
|
block: {
|
|
8061
8150
|
instanceId: t.id,
|
|
@@ -8075,7 +8164,7 @@ async function Ue(e, t, n, r, i = !1, a) {
|
|
|
8075
8164
|
}
|
|
8076
8165
|
return { blocks: [] };
|
|
8077
8166
|
}
|
|
8078
|
-
function
|
|
8167
|
+
function Ge(e, t = {}) {
|
|
8079
8168
|
let n = {};
|
|
8080
8169
|
for (let [r, i] of Object.entries(e)) r.endsWith("_meta") || [
|
|
8081
8170
|
"disabledRegions",
|
|
@@ -8091,14 +8180,14 @@ function We(e, t = {}) {
|
|
|
8091
8180
|
].includes(r) || r.startsWith("_") || (!t[r] || t[r].public !== !1) && (n[r] = i);
|
|
8092
8181
|
return n;
|
|
8093
8182
|
}
|
|
8094
|
-
function
|
|
8095
|
-
if (Array.isArray(e)) return e.map(
|
|
8183
|
+
function Ke(e) {
|
|
8184
|
+
if (Array.isArray(e)) return e.map(Ke);
|
|
8096
8185
|
if (!e || typeof e != "object") return e;
|
|
8097
8186
|
if (typeof e.id == "string" && e.id.startsWith("ast_") && typeof e.url == "string") {
|
|
8098
8187
|
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 ? {
|
|
8099
8188
|
...t,
|
|
8100
8189
|
...t.crops?.[r] || {}
|
|
8101
|
-
} : t, a = Object.fromEntries(Object.entries(n).filter(([, t]) => t?.id !== e.id).map(([t, n]) => [t,
|
|
8190
|
+
} : t, a = Object.fromEntries(Object.entries(n).filter(([, t]) => t?.id !== e.id).map(([t, n]) => [t, Ke({
|
|
8102
8191
|
...n,
|
|
8103
8192
|
title: n?.title ?? e.title ?? "",
|
|
8104
8193
|
alt: n?.alt ?? e.alt ?? "",
|
|
@@ -8112,9 +8201,9 @@ function Ge(e) {
|
|
|
8112
8201
|
...Object.keys(a).length > 0 ? { variants: a } : {}
|
|
8113
8202
|
};
|
|
8114
8203
|
}
|
|
8115
|
-
return Object.fromEntries(Object.entries(e).map(([e, t]) => [e,
|
|
8204
|
+
return Object.fromEntries(Object.entries(e).map(([e, t]) => [e, Ke(t)]));
|
|
8116
8205
|
}
|
|
8117
|
-
async function
|
|
8206
|
+
async function qe(e, t, n) {
|
|
8118
8207
|
if (typeof t == "string") {
|
|
8119
8208
|
if (!t.includes("#node:") && !t.includes("data-node-id") && !t.includes("#asset:") && !t.includes("data-asset-id")) return t;
|
|
8120
8209
|
let r = (e, t) => {
|
|
@@ -8132,9 +8221,9 @@ async function Ke(e, t, n) {
|
|
|
8132
8221
|
return await Promise.all(Array.from(t.matchAll(p)).map(async (t) => {
|
|
8133
8222
|
let i = t[1], a = r(i, "data-node-id"), o = r(i, "data-tree-id");
|
|
8134
8223
|
if (!a || !o) return;
|
|
8135
|
-
let s = await
|
|
8224
|
+
let s = await Ye(e, a, o, n);
|
|
8136
8225
|
if (s?.treeNodeId) {
|
|
8137
|
-
let t = await
|
|
8226
|
+
let t = await $e(e, String(s.treeNodeId), o, n);
|
|
8138
8227
|
f.set(`${a}:${o}`, t);
|
|
8139
8228
|
}
|
|
8140
8229
|
})), t.replace(p, (e, t) => {
|
|
@@ -8154,39 +8243,39 @@ async function Ke(e, t, n) {
|
|
|
8154
8243
|
return /href\s*=\s*["'][^"']*["']/i.test(h) ? h = h.replace(/href\s*=\s*["'][^"']*["']/i, `href="${m || "/"}"`) : h += ` href="${m || "/"}"`, `<a ${h}>`;
|
|
8155
8244
|
});
|
|
8156
8245
|
}
|
|
8157
|
-
if (Array.isArray(t)) return Promise.all(t.map((t) =>
|
|
8246
|
+
if (Array.isArray(t)) return Promise.all(t.map((t) => qe(e, t, n)));
|
|
8158
8247
|
if (t && typeof t == "object") {
|
|
8159
8248
|
if (typeof t.href == "string" && (t.href.startsWith("#node:") || t.href.startsWith("#asset:"))) return {
|
|
8160
8249
|
...t,
|
|
8161
|
-
href: await
|
|
8250
|
+
href: await Je(e, t, n)
|
|
8162
8251
|
};
|
|
8163
|
-
let r = await Promise.all(Object.entries(t).map(async ([t, r]) => [t, await
|
|
8252
|
+
let r = await Promise.all(Object.entries(t).map(async ([t, r]) => [t, await qe(e, r, n)]));
|
|
8164
8253
|
return Object.fromEntries(r);
|
|
8165
8254
|
}
|
|
8166
8255
|
return t;
|
|
8167
8256
|
}
|
|
8168
|
-
async function
|
|
8257
|
+
async function Je(e, t, n) {
|
|
8169
8258
|
let r = t.href.match(/^#node:(.+)$/), i = t.href.match(/^#asset:(.+)$/);
|
|
8170
|
-
if (i) return
|
|
8259
|
+
if (i) return Ze(e, i[1], n);
|
|
8171
8260
|
if (!r) return t.href;
|
|
8172
8261
|
let a = r[1];
|
|
8173
8262
|
if (t.treeId) {
|
|
8174
|
-
let r = await
|
|
8263
|
+
let r = await Ye(e, a, String(t.treeId), n);
|
|
8175
8264
|
if (r?.treeNodeId) {
|
|
8176
|
-
let i = await
|
|
8265
|
+
let i = await $e(e, String(r.treeNodeId), String(t.treeId), n);
|
|
8177
8266
|
if (i) return i;
|
|
8178
8267
|
}
|
|
8179
8268
|
}
|
|
8180
|
-
let o = await
|
|
8269
|
+
let o = await Xe(e, a, n);
|
|
8181
8270
|
return o === void 0 ? "#" : `/${o}`;
|
|
8182
8271
|
}
|
|
8183
|
-
async function
|
|
8184
|
-
let i =
|
|
8272
|
+
async function Ye(e, t, n, r) {
|
|
8273
|
+
let i = Ve(t, n), a = r.treeEdges.get(i);
|
|
8185
8274
|
if (a) return a;
|
|
8186
8275
|
let o = e.prepare("SELECT id as treeNodeId FROM tree_nodes WHERE contentId = ? AND treeId = ? LIMIT 1").get(t, n);
|
|
8187
8276
|
return r.treeEdges.set(i, Promise.resolve(o)), o;
|
|
8188
8277
|
}
|
|
8189
|
-
async function
|
|
8278
|
+
async function Xe(e, t, n) {
|
|
8190
8279
|
let r = String(t), i = n.nodeSlugs.get(r);
|
|
8191
8280
|
if (i) return i;
|
|
8192
8281
|
let a = (async () => {
|
|
@@ -8195,7 +8284,7 @@ async function Ye(e, t, n) {
|
|
|
8195
8284
|
})();
|
|
8196
8285
|
return n.nodeSlugs.set(r, a), a;
|
|
8197
8286
|
}
|
|
8198
|
-
async function
|
|
8287
|
+
async function Ze(e, t, n) {
|
|
8199
8288
|
let r = String(t), i = n.assetUrls.get(r);
|
|
8200
8289
|
if (i) return i;
|
|
8201
8290
|
let a = (async () => {
|
|
@@ -8204,7 +8293,7 @@ async function Xe(e, t, n) {
|
|
|
8204
8293
|
})();
|
|
8205
8294
|
return n.assetUrls.set(r, a), a;
|
|
8206
8295
|
}
|
|
8207
|
-
function
|
|
8296
|
+
function Qe(e) {
|
|
8208
8297
|
let t = e.socialImage;
|
|
8209
8298
|
if (!t || typeof t != "object") return null;
|
|
8210
8299
|
let n = (e, t) => {
|
|
@@ -8235,9 +8324,9 @@ function Ze(e) {
|
|
|
8235
8324
|
])
|
|
8236
8325
|
};
|
|
8237
8326
|
}
|
|
8238
|
-
async function
|
|
8327
|
+
async function $e(e, t, n, r) {
|
|
8239
8328
|
if (!t) return "";
|
|
8240
|
-
let i =
|
|
8329
|
+
let i = Ve(t, n);
|
|
8241
8330
|
if (r) {
|
|
8242
8331
|
let e = r.fullPath.get(i);
|
|
8243
8332
|
if (e) return e;
|
|
@@ -8252,7 +8341,7 @@ async function Qe(e, t, n, r) {
|
|
|
8252
8341
|
})();
|
|
8253
8342
|
return r && r.fullPath.set(i, a), a;
|
|
8254
8343
|
}
|
|
8255
|
-
async function
|
|
8344
|
+
async function et(e, t, n, r, i) {
|
|
8256
8345
|
let a = {}, o = null;
|
|
8257
8346
|
if (t) {
|
|
8258
8347
|
let n = await e.prepare("\n WITH RECURSIVE ancestor_path(id, contentId, title, slug, parentId, level) AS (\n SELECT t.id, 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.id = ? OR c.id = ?\n UNION ALL\n SELECT t.id, 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.id = ap.parentId\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, t), i = Array.isArray(n) ? n : n?.results || [], s = /* @__PURE__ */ new Set([
|
|
@@ -8279,7 +8368,7 @@ async function $e(e, t, n, r, i) {
|
|
|
8279
8368
|
}
|
|
8280
8369
|
}
|
|
8281
8370
|
if (!o) {
|
|
8282
|
-
let t = await e.prepare("SELECT dataJson FROM trees WHERE id = ?").get(n);
|
|
8371
|
+
let t = await e.prepare("SELECT dataJson FROM trees WHERE id = ? OR key = ? LIMIT 1").get(Number(n) || -1, String(n));
|
|
8283
8372
|
if (t?.dataJson) try {
|
|
8284
8373
|
let e = typeof t.dataJson == "string" ? JSON.parse(t.dataJson) : t.dataJson;
|
|
8285
8374
|
e.subpageLayoutId && e.subpageLayoutId !== "inherit" && (o = e.subpageLayoutId);
|
|
@@ -8290,109 +8379,125 @@ async function $e(e, t, n, r, i) {
|
|
|
8290
8379
|
inheritedFields: a
|
|
8291
8380
|
};
|
|
8292
8381
|
}
|
|
8293
|
-
function
|
|
8382
|
+
function tt(e) {
|
|
8294
8383
|
let t = Number(e?.env?.CMS_NODE_CACHE_TTL);
|
|
8295
8384
|
return Number.isFinite(t) && t >= 60 ? Math.floor(t) : 300;
|
|
8296
8385
|
}
|
|
8297
|
-
async function
|
|
8386
|
+
async function nt(e, t, n, r) {
|
|
8298
8387
|
try {
|
|
8299
8388
|
await e.set(t, n, r);
|
|
8300
8389
|
} catch (e) {
|
|
8301
8390
|
console.warn("[CMS Cache] Failed to write node response to cache:", e);
|
|
8302
8391
|
}
|
|
8303
8392
|
}
|
|
8304
|
-
|
|
8393
|
+
ze.get("/*", async (e) => {
|
|
8305
8394
|
try {
|
|
8306
|
-
let t = e.get("db"), n =
|
|
8395
|
+
let t = e.get("db"), n = Be(), r = new URL(e.req.url).pathname.match(/\/node\/(.+)$/), i = (r ? r[1] : "home").replace(/^\/+|\/+$/g, ""), a = e.req.query("channelId") || e.req.query("channel") || "1", o = e.req.query("lang"), s = e.req.query("preview") === "true", c = isNaN(Number(a)) ? await t.prepare("SELECT * FROM channels WHERE key = ?").get(a) : await t.prepare("SELECT * FROM channels WHERE id = ?").get(Number(a));
|
|
8307
8396
|
if (!c) return e.json({ error: `Channel '${a}' not found` }, 404);
|
|
8308
8397
|
let l = c.status === "disabled" || c.status === "inactive" || c.isEnabled === 0 || c.isEnabled === !1;
|
|
8309
8398
|
if (!s && l) return e.json({ error: `Channel '${c.key || a}' is currently inactive` }, 404);
|
|
8310
|
-
let u = c.id, d = c.key || a, f = I(e), p =
|
|
8311
|
-
if (!s && !m) {
|
|
8312
|
-
let t = await f.get(p);
|
|
8313
|
-
if (t) return e.header("X-Cache", "HIT"), e.json(t);
|
|
8314
|
-
}
|
|
8315
|
-
let h = ce(e.env?.BUNDLED_DEFINITIONS), g = /^\d+$/.test(i), _ = null, v = null, y = e.req.query("treeId"), b = i.split("/"), x = b[b.length - 1], S = "/" + i.replace(/^\/+|\/+$/g, ""), C = `
|
|
8399
|
+
let u = c.id, d = c.key || a, f = I(e), p = se(e.env?.BUNDLED_DEFINITIONS), m = /^\d+$/.test(i), h = null, g = null, _ = e.req.query("treeId"), v = i.split("/"), y = v[v.length - 1], b = "/" + i.replace(/^\/+|\/+$/g, ""), x = `
|
|
8316
8400
|
SELECT cn.*, tn.id as treeNodeId, tn.parentId, tn.treeId FROM content_nodes cn
|
|
8317
8401
|
INNER JOIN tree_nodes tn ON cn.id = tn.contentId
|
|
8318
8402
|
${u === null ? "" : "INNER JOIN node_channels nc ON cn.id = nc.nodeId"}
|
|
8319
8403
|
WHERE cn.slug = ? ${u === null ? "" : "AND nc.channelId = ?"}
|
|
8320
|
-
`,
|
|
8321
|
-
if (
|
|
8322
|
-
let e = await Promise.all(
|
|
8404
|
+
`, S = u === null ? [y] : [y, u], C = await t.prepare(x).all(...S), w = Array.isArray(C) ? C : C?.results || [];
|
|
8405
|
+
if (w.length > 0) {
|
|
8406
|
+
let e = await Promise.all(w.map(async (e) => ({
|
|
8323
8407
|
candidate: e,
|
|
8324
|
-
calculatedPath: await
|
|
8325
|
-
}))), r =
|
|
8408
|
+
calculatedPath: await $e(t, String(e.treeNodeId), String(e.treeId), n)
|
|
8409
|
+
}))), r = b.replace(/^\/+|\/+$/g, "");
|
|
8326
8410
|
for (let { candidate: t, calculatedPath: n } of e) {
|
|
8327
8411
|
let e = n.replace(/^\/+|\/+$/g, "");
|
|
8328
8412
|
if (e === r || r === "home" && (e === "" || e === "home")) {
|
|
8329
|
-
|
|
8413
|
+
h = t, g = t;
|
|
8330
8414
|
break;
|
|
8331
8415
|
}
|
|
8332
8416
|
}
|
|
8333
8417
|
}
|
|
8334
|
-
if (!
|
|
8335
|
-
if (!
|
|
8336
|
-
let e =
|
|
8337
|
-
|
|
8418
|
+
if (!h && v.length === 1 && (h = u === null ? await t.prepare("SELECT * FROM content_nodes WHERE slug = ?").get(y) : await t.prepare("SELECT cn.* FROM content_nodes cn INNER JOIN node_channels nc ON cn.id = nc.nodeId WHERE cn.slug = ? AND nc.channelId = ?").get(y, u)), !h && m && (h = u === null ? await t.prepare("SELECT * FROM content_nodes WHERE id = ?").get(Number(i)) : await t.prepare("SELECT cn.* FROM content_nodes cn INNER JOIN node_channels nc ON cn.id = nc.nodeId WHERE cn.id = ? AND nc.channelId = ?").get(Number(i), u)), !h) return e.json({ error: `Node '${i}' not found for Channel '${a}'` }, 404);
|
|
8419
|
+
if (!g) {
|
|
8420
|
+
let e = _ ? [h.id, _] : [h.id];
|
|
8421
|
+
g = await t.prepare(`SELECT id as treeNodeId, treeId, parentId FROM tree_nodes WHERE contentId = ? ${_ ? "AND treeId = ?" : ""} LIMIT 1`).get(...e);
|
|
8338
8422
|
}
|
|
8339
|
-
let
|
|
8340
|
-
|
|
8341
|
-
|
|
8342
|
-
|
|
8343
|
-
|
|
8344
|
-
|
|
8345
|
-
|
|
8346
|
-
|
|
8347
|
-
|
|
8348
|
-
|
|
8349
|
-
|
|
8350
|
-
|
|
8423
|
+
let T = g?.treeId || _ || "main-nav", E = null;
|
|
8424
|
+
if (T) {
|
|
8425
|
+
let e = await t.prepare("\n SELECT dataJson \n FROM trees \n WHERE id = ? OR key = ? \n LIMIT 1\n ").get(Number(T) || -1, String(T));
|
|
8426
|
+
if (e?.dataJson) try {
|
|
8427
|
+
let t = typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson;
|
|
8428
|
+
t.defaultLanguage ? E = String(t.defaultLanguage).trim() : t.language && (E = String(t.language).trim());
|
|
8429
|
+
} catch {}
|
|
8430
|
+
}
|
|
8431
|
+
let D = null;
|
|
8432
|
+
if (c) {
|
|
8433
|
+
if (c.defaultLanguage) D = String(c.defaultLanguage).trim();
|
|
8434
|
+
else if (c.dataJson) try {
|
|
8435
|
+
let e = typeof c.dataJson == "string" ? JSON.parse(c.dataJson) : c.dataJson;
|
|
8436
|
+
e.defaultLanguage ? D = String(e.defaultLanguage).trim() : e.language && (D = String(e.language).trim());
|
|
8437
|
+
} catch {}
|
|
8438
|
+
}
|
|
8439
|
+
let O = h.language?.trim() || null, k = E || D || o?.trim() || null, A = O || k || null, j = `node:${u || d}:${A || "default"}:${i}`, M = e.req.header("x-bypass-cache") === "true";
|
|
8440
|
+
if (!s && !M) {
|
|
8441
|
+
let t = await f.get(j);
|
|
8442
|
+
if (t) return e.header("X-Cache", "HIT"), e.json(t);
|
|
8443
|
+
}
|
|
8444
|
+
let N = g?.parentId || null, ee = g?.treeNodeId ? await $e(t, String(g.treeNodeId), String(T), n) : `/${(h.slug || "").replace(/^\/+|\/+$/g, "")}`, P = {
|
|
8445
|
+
id: h.id,
|
|
8446
|
+
title: h.title,
|
|
8447
|
+
slug: h.slug,
|
|
8448
|
+
language: A,
|
|
8449
|
+
path: ee === "" ? "/" : ee,
|
|
8450
|
+
nodeType: h.contentType,
|
|
8451
|
+
createdAt: h.createdAt,
|
|
8452
|
+
updatedAt: h.updatedAt
|
|
8453
|
+
}, te = h.contentType || "node", F = p.nodes?.[te] || Object.values(p.nodes || {})[0] || {}, L = { ...F.fields || {} };
|
|
8454
|
+
F.tabs && Object.values(F.tabs).forEach((e) => {
|
|
8455
|
+
Object.assign(L, e.fields || {});
|
|
8351
8456
|
});
|
|
8352
|
-
let
|
|
8353
|
-
if (
|
|
8354
|
-
|
|
8457
|
+
let ne = {}, re = null, ie = null, ae = !1, R = {}, oe = s && h.draftDataJson || h.dataJson;
|
|
8458
|
+
if (oe) try {
|
|
8459
|
+
R = typeof oe == "string" ? JSON.parse(oe) : oe;
|
|
8355
8460
|
} catch {}
|
|
8356
|
-
|
|
8357
|
-
let
|
|
8358
|
-
for (let [e, t] of Object.entries(
|
|
8359
|
-
let
|
|
8360
|
-
|
|
8361
|
-
let
|
|
8362
|
-
delete
|
|
8363
|
-
let
|
|
8364
|
-
if (!s && (
|
|
8365
|
-
let
|
|
8366
|
-
if (
|
|
8367
|
-
let e = await t.prepare("\n SELECT t.id 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(
|
|
8368
|
-
|
|
8461
|
+
R.disabledRegions && (ne = R.disabledRegions), ae = R.hidden === !0 || R.hidden === 1 || R.hidden === "1" || R.hidden === "true", re = R.startShowingAt || null, ie = R.stopShowingAt || null;
|
|
8462
|
+
let z = R.layoutId, V = z && z !== "inherit", { resolvedLayoutId: H, inheritedFields: ce } = await et(t, N, T, s, L), le = V ? z : H || F.defaultLayout || null;
|
|
8463
|
+
for (let [e, t] of Object.entries(ce)) (R[e] === void 0 || R[e] === null || R[e] === "" || R[e] === "inherit") && t !== void 0 && (R[e] = t);
|
|
8464
|
+
let U = await B(t, Ge(R, L));
|
|
8465
|
+
U = Ke(U), U = await qe(t, U, n), delete U.language;
|
|
8466
|
+
let ue = Qe(U);
|
|
8467
|
+
delete U.socialImage, delete U.fbImage, delete U.xImage, delete U.whatsappImage, ue && (U.socialImages = ue), P.slug = h.slug, P.title = h.title, Object.assign(P, U), P.layoutId = le;
|
|
8468
|
+
let de = Number(h.isHidden) === 1 || ae, fe = !He(re, ie), pe = h.status === "draft" || h.status === "new", me = h.dataJson && h.dataJson !== "{}" && h.dataJson !== "null";
|
|
8469
|
+
if (!s && (de || fe || pe && !me)) return e.json({ error: "Node is hidden, offline, or has never been published." }, 404);
|
|
8470
|
+
let he = [];
|
|
8471
|
+
if (g?.treeNodeId) {
|
|
8472
|
+
let e = await t.prepare("\n SELECT t.id 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(g.treeNodeId, T), n = Array.isArray(e) ? e : e?.results || [], r = P.path === "/" ? "" : P.path;
|
|
8473
|
+
he = n.map((e) => {
|
|
8369
8474
|
let t = {}, n = s && e.draftDataJson || e.dataJson;
|
|
8370
8475
|
if (!n) return null;
|
|
8371
8476
|
try {
|
|
8372
8477
|
t = (typeof n == "string" ? JSON.parse(n) : n) || {};
|
|
8373
8478
|
} catch {}
|
|
8374
|
-
let i = Number(e.isHidden) === 1 || t.hidden === !0 || t.hidden === 1 || t.hidden === "1", a =
|
|
8479
|
+
let i = Number(e.isHidden) === 1 || t.hidden === !0 || t.hidden === 1 || t.hidden === "1", a = He(t.startShowingAt, t.stopShowingAt), o = (e.slug || "").replace(/^\/+|\/+$/g, "");
|
|
8375
8480
|
return !s && (i || !a) ? null : {
|
|
8376
8481
|
treeNodeId: e.treeNodeId,
|
|
8377
8482
|
id: e.id,
|
|
8378
8483
|
title: e.title,
|
|
8379
8484
|
slug: o,
|
|
8380
|
-
language: e.language ||
|
|
8485
|
+
language: e.language?.trim() || A || null,
|
|
8381
8486
|
path: `${r}/${o}`.replace(/\/+/g, "/"),
|
|
8382
8487
|
nodeType: e.nodeType
|
|
8383
8488
|
};
|
|
8384
8489
|
}).filter(Boolean);
|
|
8385
8490
|
}
|
|
8386
|
-
|
|
8387
|
-
let
|
|
8491
|
+
P.children = he;
|
|
8492
|
+
let ge = +!!s, W = await t.prepare("SELECT * FROM content_blocks WHERE contentId = ? AND isDraft = ? ORDER BY sortOrder ASC").all(h.id, ge), _e = Array.isArray(W) ? W : W?.results || [], G = {}, ve = {}, ye = await Promise.all(_e.map(async (e) => {
|
|
8388
8493
|
let r = e.region || "main", i = {};
|
|
8389
8494
|
try {
|
|
8390
8495
|
i = (typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson) || {};
|
|
8391
8496
|
} catch {}
|
|
8392
|
-
let a = i.hidden === !0 || i.hidden === 1 || i.hidden === "1" || i.hidden === "true", o =
|
|
8497
|
+
let a = i.hidden === !0 || i.hidden === 1 || i.hidden === "1" || i.hidden === "true", o = He(i.startShowingAt, i.stopShowingAt);
|
|
8393
8498
|
if (!s && (a || !o)) return null;
|
|
8394
|
-
let c = e.elementType || e.componentId || "text-block", l =
|
|
8395
|
-
return d = await
|
|
8499
|
+
let c = e.elementType || e.componentId || "text-block", l = p.blocks?.[c]?.fields || p.elements?.[c]?.fields || p.components?.[c]?.fields || {}, u = String(i.blockId || i._instanceId || i.id || e.blockId || e.id), d = Ge(i, l);
|
|
8500
|
+
return d = await B(t, d), d = Ke(d), d = await qe(t, d, n), d.blockId = u, {
|
|
8396
8501
|
region: r,
|
|
8397
8502
|
block: {
|
|
8398
8503
|
instanceId: e.id,
|
|
@@ -8402,8 +8507,8 @@ Re.get("/*", async (e) => {
|
|
|
8402
8507
|
}
|
|
8403
8508
|
};
|
|
8404
8509
|
}));
|
|
8405
|
-
for (let e of
|
|
8406
|
-
let
|
|
8510
|
+
for (let e of ye) e && (G[e.region] || (G[e.region] = [], ve[e.region] = { isInherited: !1 }), G[e.region].push(e.block));
|
|
8511
|
+
let K = {
|
|
8407
8512
|
header: {
|
|
8408
8513
|
label: "Header",
|
|
8409
8514
|
inherit: "parent"
|
|
@@ -8412,33 +8517,33 @@ Re.get("/*", async (e) => {
|
|
|
8412
8517
|
label: "Footer",
|
|
8413
8518
|
inherit: "parent"
|
|
8414
8519
|
},
|
|
8415
|
-
...(
|
|
8520
|
+
...(le ? p.nodeLayouts?.[le] || p.layouts?.[le] : null)?.regions || { main: { label: "Content" } }
|
|
8416
8521
|
};
|
|
8417
|
-
for (let [e, r] of Object.entries(
|
|
8418
|
-
let i =
|
|
8419
|
-
if (
|
|
8420
|
-
let r = await
|
|
8421
|
-
if (r.blocks.length > 0 && (
|
|
8522
|
+
for (let [e, r] of Object.entries(K)) {
|
|
8523
|
+
let i = G[e] && G[e].length > 0, a = !!ne[e];
|
|
8524
|
+
if (G[e] || (G[e] = [], ve[e] = { isInherited: !1 }), (r?.inherit === "parent" || r?.inherit === !0 || r?.inherit === "true" || e === "header" || e === "footer") && !i && !a && N) {
|
|
8525
|
+
let r = await We(t, N, e, p, s, n);
|
|
8526
|
+
if (r.blocks.length > 0 && (G[e] = r.blocks, ve[e] = {
|
|
8422
8527
|
isInherited: !0,
|
|
8423
8528
|
inheritedFromId: r.inheritedFromId,
|
|
8424
8529
|
inheritedFromTitle: r.inheritedFromTitle
|
|
8425
|
-
}, r.subRegions)) for (let [t, n] of Object.entries(r.subRegions)) t !== e && (
|
|
8530
|
+
}, r.subRegions)) for (let [t, n] of Object.entries(r.subRegions)) t !== e && (G[t] = n, ve[t] = {
|
|
8426
8531
|
isInherited: !0,
|
|
8427
8532
|
inheritedFromId: r.inheritedFromId,
|
|
8428
8533
|
inheritedFromTitle: r.inheritedFromTitle
|
|
8429
8534
|
});
|
|
8430
8535
|
}
|
|
8431
8536
|
}
|
|
8432
|
-
await Promise.all(Object.keys(
|
|
8433
|
-
let
|
|
8537
|
+
await Promise.all(Object.keys(G).map((e) => Ue(t, G[e], u, A)));
|
|
8538
|
+
let q = {
|
|
8434
8539
|
channelId: u || d,
|
|
8435
|
-
treeId:
|
|
8436
|
-
language: A
|
|
8437
|
-
node:
|
|
8438
|
-
content:
|
|
8439
|
-
regionMeta:
|
|
8540
|
+
treeId: T,
|
|
8541
|
+
language: A,
|
|
8542
|
+
node: P,
|
|
8543
|
+
content: G,
|
|
8544
|
+
regionMeta: ve
|
|
8440
8545
|
};
|
|
8441
|
-
return !s && !
|
|
8546
|
+
return !s && !M && (e.header("X-Cache", "MISS"), await nt(f, j, q, tt(e))), e.json(q);
|
|
8442
8547
|
} catch (t) {
|
|
8443
8548
|
return console.error("[CMS Public API] Error fetching node by path:", t), e.json({
|
|
8444
8549
|
error: "Failed to fetch JSON payload",
|
|
@@ -8448,8 +8553,8 @@ Re.get("/*", async (e) => {
|
|
|
8448
8553
|
});
|
|
8449
8554
|
//#endregion
|
|
8450
8555
|
//#region server/routes/public/tree.ts
|
|
8451
|
-
var
|
|
8452
|
-
function
|
|
8556
|
+
var rt = new e();
|
|
8557
|
+
function it(e, t) {
|
|
8453
8558
|
let n = /* @__PURE__ */ new Date();
|
|
8454
8559
|
if (e && String(e).trim() !== "") {
|
|
8455
8560
|
let t = new Date(e);
|
|
@@ -8461,93 +8566,103 @@ function rt(e, t) {
|
|
|
8461
8566
|
}
|
|
8462
8567
|
return !0;
|
|
8463
8568
|
}
|
|
8464
|
-
async function
|
|
8569
|
+
async function at(e, t, n, r) {
|
|
8465
8570
|
try {
|
|
8466
8571
|
await e.set(t, n, r);
|
|
8467
8572
|
} catch (e) {
|
|
8468
8573
|
console.warn("[CMS Cache] Failed to write tree response to cache:", e);
|
|
8469
8574
|
}
|
|
8470
8575
|
}
|
|
8471
|
-
|
|
8576
|
+
rt.get("/:treeParam", async (e) => {
|
|
8472
8577
|
try {
|
|
8473
|
-
let t = e.get("db"), n = e.req.param("treeParam"), r = e.req.query("channelId") || e.req.query("channel") || "default", i = e.req.query("preview") === "true";
|
|
8578
|
+
let t = e.get("db"), n = e.req.param("treeParam"), r = e.req.query("channelId") || e.req.query("channel") || "default", i = e.req.query("lang"), a = e.req.query("preview") === "true", o = null;
|
|
8474
8579
|
if (r && r !== "default" && r !== "all") {
|
|
8475
8580
|
let n = isNaN(Number(r)) ? await t.prepare("SELECT * FROM channels WHERE key = ?").get(r) : await t.prepare("SELECT * FROM channels WHERE id = ?").get(Number(r));
|
|
8476
8581
|
if (n) {
|
|
8582
|
+
n.defaultLanguage && (o = n.defaultLanguage.trim());
|
|
8477
8583
|
let t = n.status === "disabled" || n.status === "inactive" || n.isEnabled === 0 || n.isEnabled === !1;
|
|
8478
|
-
if (!
|
|
8584
|
+
if (!a && t) return e.json({ error: `Channel '${n.key || r}' is currently inactive` }, 404);
|
|
8479
8585
|
}
|
|
8480
8586
|
}
|
|
8481
|
-
let
|
|
8482
|
-
if (
|
|
8483
|
-
|
|
8587
|
+
let s = !isNaN(Number(n)), c = s ? await t.prepare("SELECT * FROM trees WHERE id = ?").get(Number(n)) : await t.prepare("SELECT * FROM trees WHERE key = ?").get(n);
|
|
8588
|
+
if (c && Number(c.isHidden) === 1 && !a) return e.json({ error: `Tree '${n}' is hidden` }, 404);
|
|
8589
|
+
let l = null;
|
|
8590
|
+
if (c) {
|
|
8591
|
+
if (c.defaultLanguage) l = String(c.defaultLanguage).trim();
|
|
8592
|
+
else if (c.dataJson) try {
|
|
8593
|
+
let e = typeof c.dataJson == "string" ? JSON.parse(c.dataJson) : c.dataJson;
|
|
8594
|
+
e.defaultLanguage && (l = String(e.defaultLanguage).trim());
|
|
8595
|
+
} catch {}
|
|
8596
|
+
}
|
|
8597
|
+
let u = l || o || i?.trim() || null, d = I(e), f = `tree:${r}:${n}:${u || "default"}`, p = e.req.header("x-bypass-cache") === "true";
|
|
8598
|
+
if (!a && !p) {
|
|
8599
|
+
let t = await d.get(f);
|
|
8484
8600
|
if (t) return e.header("X-Cache", "HIT"), e.json(t);
|
|
8485
8601
|
}
|
|
8486
|
-
let
|
|
8487
|
-
if (
|
|
8488
|
-
|
|
8489
|
-
|
|
8490
|
-
let t = typeof l.dataJson == "string" ? JSON.parse(l.dataJson) : l.dataJson, r = e.env?.BUNDLED_DEFINITIONS, i = ce(r), a = (i.trees?.[l.treeType || n] || i.trees?.site || {}).fields || {};
|
|
8491
|
-
for (let [e, n] of Object.entries(t)) a[e]?.public === !0 && (d[e] = n);
|
|
8602
|
+
let m = c?.id || (s ? Number(n) : null), h = {};
|
|
8603
|
+
if (c && c.dataJson) try {
|
|
8604
|
+
let t = typeof c.dataJson == "string" ? JSON.parse(c.dataJson) : c.dataJson, r = e.env?.BUNDLED_DEFINITIONS, i = se(r), a = (i.trees?.[c.treeType || n] || i.trees?.site || {}).fields || {};
|
|
8605
|
+
for (let [e, n] of Object.entries(t)) a[e]?.public === !0 && (h[e] = n);
|
|
8492
8606
|
} catch (e) {
|
|
8493
8607
|
console.warn("[CMS Public Tree API] Failed to parse tree dataJson", e);
|
|
8494
8608
|
}
|
|
8495
|
-
let
|
|
8496
|
-
if (
|
|
8497
|
-
let e = await t.prepare("\n SELECT \n t.id as treeNodeId,\n t.treeId,\n t.contentId as id,\n t.parentId,\n t.sortOrder,\n c.title,\n c.slug,\n c.language,\n c.contentType as nodeType,\n c.isHidden,\n c.status,\n c.dataJson,\n c.draftDataJson\n FROM tree_nodes t\n INNER JOIN content_nodes c ON t.contentId = c.id\n WHERE t.treeId = ? AND (c.deletedAt IS NULL OR c.deletedAt = '')\n ORDER BY t.sortOrder ASC\n ").all(
|
|
8498
|
-
|
|
8609
|
+
let g = [];
|
|
8610
|
+
if (m !== null) {
|
|
8611
|
+
let e = await t.prepare("\n SELECT \n t.id as treeNodeId,\n t.treeId,\n t.contentId as id,\n t.parentId,\n t.sortOrder,\n c.title,\n c.slug,\n c.language,\n c.contentType as nodeType,\n c.isHidden,\n c.status,\n c.dataJson,\n c.draftDataJson\n FROM tree_nodes t\n INNER JOIN content_nodes c ON t.contentId = c.id\n WHERE t.treeId = ? AND (c.deletedAt IS NULL OR c.deletedAt = '')\n ORDER BY t.sortOrder ASC\n ").all(m);
|
|
8612
|
+
g = Array.isArray(e) ? e : e?.results || [];
|
|
8499
8613
|
}
|
|
8500
|
-
if ((!
|
|
8501
|
-
let
|
|
8502
|
-
for (let e of
|
|
8503
|
-
let t = !e.parentId || e.parentId === "null" || e.parentId === "" ? null : e.parentId, n = t === null ? "__ROOT__" : String(t), r =
|
|
8504
|
-
r ? r.push(e) :
|
|
8614
|
+
if ((!g || g.length === 0) && !c) return e.json({ error: `Tree '${n}' not found` }, 404);
|
|
8615
|
+
let _ = /* @__PURE__ */ new Map();
|
|
8616
|
+
for (let e of g) {
|
|
8617
|
+
let t = !e.parentId || e.parentId === "null" || e.parentId === "" ? null : e.parentId, n = t === null ? "__ROOT__" : String(t), r = _.get(n);
|
|
8618
|
+
r ? r.push(e) : _.set(n, [e]);
|
|
8505
8619
|
}
|
|
8506
|
-
let
|
|
8507
|
-
for (let e of
|
|
8508
|
-
let t = String(e.treeNodeId), n =
|
|
8620
|
+
let v = /* @__PURE__ */ new Map();
|
|
8621
|
+
for (let e of g) {
|
|
8622
|
+
let t = String(e.treeNodeId), n = a && e.draftDataJson ? e.draftDataJson : e.dataJson;
|
|
8509
8623
|
if (!n) {
|
|
8510
|
-
|
|
8624
|
+
v.set(t, {});
|
|
8511
8625
|
continue;
|
|
8512
8626
|
}
|
|
8513
8627
|
try {
|
|
8514
8628
|
let e = typeof n == "string" ? JSON.parse(n) : n;
|
|
8515
|
-
|
|
8629
|
+
v.set(t, e && typeof e == "object" ? e : {});
|
|
8516
8630
|
} catch {
|
|
8517
|
-
|
|
8631
|
+
v.set(t, {});
|
|
8518
8632
|
}
|
|
8519
8633
|
}
|
|
8520
|
-
function
|
|
8634
|
+
function y(e = null, t = "") {
|
|
8521
8635
|
let n = e == null || e === "" || e === "null" ? "__ROOT__" : String(e);
|
|
8522
|
-
return (
|
|
8523
|
-
let n =
|
|
8636
|
+
return (_.get(n) || []).map((e) => {
|
|
8637
|
+
let n = v.get(String(e.treeNodeId)) || {}, r = {};
|
|
8524
8638
|
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);
|
|
8525
|
-
let
|
|
8639
|
+
let i = !a && (e.status === "draft" || e.status === "new"), o = Number(e.isHidden) === 1 || i || n.hidden === !0 || n.hidden === 1 || n.hidden === "1" || n.hidden === "true", s = it(n.startShowingAt, n.stopShowingAt), c = (e.slug || "").replace(/^\/+|\/+$/g, ""), l = (!e.parentId || e.parentId === "null" || e.parentId === "") && (c === "home" || c === "homee") ? "/" : `${t}/${c}`.replace(/\/+/g, "/"), d = e.language && String(e.language).trim() !== "" ? e.language.trim() : u, f = {
|
|
8526
8640
|
id: e.id,
|
|
8527
8641
|
treeNodeId: e.treeNodeId,
|
|
8528
8642
|
parentId: e.parentId || null,
|
|
8529
8643
|
title: e.title,
|
|
8530
8644
|
slug: c,
|
|
8531
|
-
language:
|
|
8645
|
+
language: d,
|
|
8532
8646
|
path: l,
|
|
8533
8647
|
nodeType: e.nodeType,
|
|
8534
8648
|
hidden: o || !s ? 1 : 0,
|
|
8535
8649
|
summary: r.summary || ""
|
|
8536
8650
|
};
|
|
8537
|
-
e.nodeType === "external-link" && (r.url && (
|
|
8538
|
-
let
|
|
8539
|
-
return
|
|
8540
|
-
}).filter((e) =>
|
|
8651
|
+
e.nodeType === "external-link" && (r.url && (f.url = r.url), r.target && (f.target = r.target));
|
|
8652
|
+
let p = l === "/" ? "" : l;
|
|
8653
|
+
return f.children = y(e.treeNodeId, p), f;
|
|
8654
|
+
}).filter((e) => a || !e.hidden);
|
|
8541
8655
|
}
|
|
8542
|
-
let
|
|
8543
|
-
treeId:
|
|
8544
|
-
key:
|
|
8656
|
+
let b = {
|
|
8657
|
+
treeId: c?.id || m,
|
|
8658
|
+
key: c?.key || n,
|
|
8545
8659
|
channelId: r,
|
|
8546
|
-
|
|
8547
|
-
|
|
8548
|
-
|
|
8660
|
+
language: u,
|
|
8661
|
+
label: c?.label || n,
|
|
8662
|
+
...h,
|
|
8663
|
+
items: y(null)
|
|
8549
8664
|
};
|
|
8550
|
-
return !
|
|
8665
|
+
return !a && !p && (e.header("X-Cache", "MISS"), await at(d, f, b, 300)), e.json(b);
|
|
8551
8666
|
} catch (t) {
|
|
8552
8667
|
return console.error("[CMS Public Tree API] Error:", t), e.json({
|
|
8553
8668
|
error: "Failed to fetch public tree",
|
|
@@ -8556,9 +8671,148 @@ nt.get("/:treeParam", async (e) => {
|
|
|
8556
8671
|
}
|
|
8557
8672
|
});
|
|
8558
8673
|
//#endregion
|
|
8674
|
+
//#region server/routes/public/channel.ts
|
|
8675
|
+
var ot = new e();
|
|
8676
|
+
function st(e) {
|
|
8677
|
+
let t = Number(e?.env?.CMS_CHANNEL_CACHE_TTL);
|
|
8678
|
+
return Number.isFinite(t) && t >= 60 ? Math.floor(t) : 300;
|
|
8679
|
+
}
|
|
8680
|
+
async function ct(e, t, n, r) {
|
|
8681
|
+
try {
|
|
8682
|
+
await e.set(t, n, r);
|
|
8683
|
+
} catch (e) {
|
|
8684
|
+
console.warn("[CMS Cache] Failed to write channel response to cache:", e);
|
|
8685
|
+
}
|
|
8686
|
+
}
|
|
8687
|
+
function lt(e, t) {
|
|
8688
|
+
let n = {}, r = (e) => {
|
|
8689
|
+
if (!e || typeof e != "string") return;
|
|
8690
|
+
let n = t?.fieldSets?.[e] || t?.fieldsets?.[e] || t?.definitions?.[e] || t?.channels?.[e] || t?.[e];
|
|
8691
|
+
n?.fields && i(n.fields);
|
|
8692
|
+
}, i = (e) => {
|
|
8693
|
+
if (!(!e || typeof e != "object")) for (let [t, i] of Object.entries(e)) t === "fieldSet" && typeof i == "string" ? r(i) : i && typeof i == "object" && i.fieldSet ? r(i.fieldSet) : t !== "fieldSet" && (n[t] = i);
|
|
8694
|
+
};
|
|
8695
|
+
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);
|
|
8696
|
+
return n;
|
|
8697
|
+
}
|
|
8698
|
+
function ut(e, t = {}) {
|
|
8699
|
+
let n = {}, r = Object.keys(t).length > 0;
|
|
8700
|
+
for (let [i, a] of Object.entries(e)) {
|
|
8701
|
+
if (i.endsWith("_meta") || [
|
|
8702
|
+
"disabledRegions",
|
|
8703
|
+
"hidden",
|
|
8704
|
+
"is_hidden",
|
|
8705
|
+
"isHidden",
|
|
8706
|
+
"status",
|
|
8707
|
+
"startShowingAt",
|
|
8708
|
+
"stopShowingAt",
|
|
8709
|
+
"dataJson",
|
|
8710
|
+
"draftDataJson"
|
|
8711
|
+
].includes(i) || i.startsWith("_")) continue;
|
|
8712
|
+
let e = t[i];
|
|
8713
|
+
(!r || !e || e.public !== !1) && a != null && a !== "" && (n[i] = a);
|
|
8714
|
+
}
|
|
8715
|
+
return n;
|
|
8716
|
+
}
|
|
8717
|
+
function dt(e) {
|
|
8718
|
+
if (Array.isArray(e)) return e.map(dt);
|
|
8719
|
+
if (!e || typeof e != "object") return e;
|
|
8720
|
+
if (typeof e.id == "string" && e.id.startsWith("ast_") && typeof e.url == "string") {
|
|
8721
|
+
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 ? {
|
|
8722
|
+
...t,
|
|
8723
|
+
...t.crops?.[r] || {}
|
|
8724
|
+
} : t, a = Object.fromEntries(Object.entries(n).filter(([, t]) => t?.id !== e.id).map(([t, n]) => [t, dt({
|
|
8725
|
+
...n,
|
|
8726
|
+
title: n?.title ?? e.title ?? "",
|
|
8727
|
+
alt: n?.alt ?? e.alt ?? "",
|
|
8728
|
+
description: n?.description ?? e.description ?? ""
|
|
8729
|
+
})])), { metadataOverrides: o, ...s } = e;
|
|
8730
|
+
return {
|
|
8731
|
+
...s,
|
|
8732
|
+
title: i.title ?? e.title ?? "",
|
|
8733
|
+
alt: i.alt ?? e.alt ?? "",
|
|
8734
|
+
description: i.description ?? e.description ?? "",
|
|
8735
|
+
...Object.keys(a).length > 0 ? { variants: a } : {}
|
|
8736
|
+
};
|
|
8737
|
+
}
|
|
8738
|
+
return Object.fromEntries(Object.entries(e).map(([e, t]) => [e, dt(t)]));
|
|
8739
|
+
}
|
|
8740
|
+
async function ft(e, t) {
|
|
8741
|
+
if (typeof t == "string") {
|
|
8742
|
+
if (!t.includes("#node:") && !t.includes("data-node-id") && !t.includes("#asset:") && !t.includes("data-asset-id")) return t;
|
|
8743
|
+
let n = /* @__PURE__ */ new Set(), r = /* @__PURE__ */ new Set();
|
|
8744
|
+
for (let e of t.matchAll(/(?:#node:|data-node-id\s*=\s*["'])([^"'\s>]+)/gi)) n.add(e[1]);
|
|
8745
|
+
for (let e of t.matchAll(/(?:#asset:|data-asset-id\s*=\s*["'])([^"'\s>]+)/gi)) r.add(e[1]);
|
|
8746
|
+
if (n.size === 0 && r.size === 0) return t;
|
|
8747
|
+
let i = Array.from(n).map(() => "?").join(","), a = n.size > 0 ? await e.prepare(`SELECT id, slug FROM content_nodes WHERE id IN (${i})`).all(...n) : [], o = /* @__PURE__ */ new Map();
|
|
8748
|
+
(Array.isArray(a) ? a : a?.results || []).forEach((e) => o.set(String(e.id), String(e.slug || "").replace(/^\/+|\/+$/g, "")));
|
|
8749
|
+
let s = Array.from(r).map(() => "?").join(","), c = r.size > 0 ? await e.prepare(`SELECT id, cdnUrl, storageKeyPrivate FROM assets WHERE id IN (${s})`).all(...r) : [], l = /* @__PURE__ */ new Map();
|
|
8750
|
+
return (Array.isArray(c) ? c : c?.results || []).forEach((e) => l.set(String(e.id), e.cdnUrl || (e.storageKeyPrivate ? `/media/${e.storageKeyPrivate}` : ""))), t.replace(/<a\s+([^>]+)>/gi, (e, t) => {
|
|
8751
|
+
let n = (e, t) => {
|
|
8752
|
+
let n = e.match(RegExp(`\\b${t}\\s*=\\s*(["'])(.*?)\\1`, "i"));
|
|
8753
|
+
return n ? n[2] : void 0;
|
|
8754
|
+
}, r = n(t, "data-node-id"), i = n(t, "data-asset-id"), a = n(t, "href") || "";
|
|
8755
|
+
if (a.startsWith("mailto:")) return `<a ${t.replace(/\s+target\s*=\s*["'][^"']*["']/i, "")}>`;
|
|
8756
|
+
let s = i || a.match(/^#asset:(.+)$/i)?.[1], c = r || a.match(/^#node:(.+)$/i)?.[1];
|
|
8757
|
+
if (!c && !s) return e;
|
|
8758
|
+
if (s && !c) {
|
|
8759
|
+
let n = l.get(s);
|
|
8760
|
+
if (n) {
|
|
8761
|
+
let e = t;
|
|
8762
|
+
return /href\s*=\s*["'][^"']*["']/i.test(e) ? e = e.replace(/href\s*=\s*["'][^"']*["']/i, `href="${n}"`) : e += ` href="${n}"`, `<a ${e}>`;
|
|
8763
|
+
}
|
|
8764
|
+
return e;
|
|
8765
|
+
}
|
|
8766
|
+
let u = o.get(c), d = u === void 0 ? "#" : `/${u}`, f = t;
|
|
8767
|
+
return /href\s*=\s*["'][^"']*["']/i.test(f) ? f = f.replace(/href\s*=\s*["'][^"']*["']/i, `href="${d || "/"}"`) : f += ` href="${d || "/"}"`, `<a ${f}>`;
|
|
8768
|
+
});
|
|
8769
|
+
}
|
|
8770
|
+
if (Array.isArray(t)) return Promise.all(t.map((t) => ft(e, t)));
|
|
8771
|
+
if (t && typeof t == "object") {
|
|
8772
|
+
let n = await Promise.all(Object.entries(t).map(async ([t, n]) => [t, await ft(e, n)]));
|
|
8773
|
+
return Object.fromEntries(n);
|
|
8774
|
+
}
|
|
8775
|
+
return t;
|
|
8776
|
+
}
|
|
8777
|
+
ot.get("/:channelParam", async (e) => {
|
|
8778
|
+
try {
|
|
8779
|
+
let t = e.get("db"), n = e.req.param("channelParam"), r = e.req.query("preview") === "true", i = e.req.header("x-bypass-cache") === "true", a = `channel:${n}:${r ? "preview" : "live"}`, o = I(e);
|
|
8780
|
+
if (!r && !i) {
|
|
8781
|
+
let t = await o.get(a);
|
|
8782
|
+
if (t) return e.header("X-Cache", "HIT"), e.json(t);
|
|
8783
|
+
}
|
|
8784
|
+
let s = isNaN(Number(n)) ? await t.prepare("SELECT * FROM channels WHERE key = ?").get(n) : await t.prepare("SELECT * FROM channels WHERE id = ?").get(Number(n));
|
|
8785
|
+
if (!s) return e.json({ error: `Channel '${n}' not found` }, 404);
|
|
8786
|
+
let c = s.status === "disabled" || s.status === "inactive" || s.isEnabled === 0 || s.isEnabled === !1;
|
|
8787
|
+
if (!r && c) return e.json({ error: `Channel '${s.key || n}' is currently inactive` }, 404);
|
|
8788
|
+
let l = e.env?.BUNDLED_DEFINITIONS, u = se(l), d = s.channelType || s.key || "website", f = lt(u.channels?.[d] || u.channels?.[s.key] || u.channels?.website || u.definitions?.["channel-base"] || {}, u), p = {}, m = r && s.draftDataJson || s.dataJson;
|
|
8789
|
+
if (m) try {
|
|
8790
|
+
p = typeof m == "string" ? JSON.parse(m) : m;
|
|
8791
|
+
} catch (e) {
|
|
8792
|
+
console.warn("[CMS Public Channel API] Failed to parse channel dataJson:", e);
|
|
8793
|
+
}
|
|
8794
|
+
let h = ut({
|
|
8795
|
+
...p,
|
|
8796
|
+
...s
|
|
8797
|
+
}, f);
|
|
8798
|
+
h = await B(t, h), h = dt(h), h = await ft(t, h);
|
|
8799
|
+
let g = {
|
|
8800
|
+
id: s.id,
|
|
8801
|
+
key: s.key,
|
|
8802
|
+
...h
|
|
8803
|
+
};
|
|
8804
|
+
return !r && !i && (e.header("X-Cache", "MISS"), await ct(o, a, g, st(e))), e.json(g);
|
|
8805
|
+
} catch (t) {
|
|
8806
|
+
return console.error("[CMS Public Channel API] Error:", t), e.json({
|
|
8807
|
+
error: "Failed to fetch public channel",
|
|
8808
|
+
...e.env?.ENVIRONMENT === "development" ? { details: t.message } : {}
|
|
8809
|
+
}, 500);
|
|
8810
|
+
}
|
|
8811
|
+
});
|
|
8812
|
+
//#endregion
|
|
8559
8813
|
//#region server/routes/public/assets.ts
|
|
8560
|
-
var
|
|
8561
|
-
function
|
|
8814
|
+
var pt = new e();
|
|
8815
|
+
function mt(e, t) {
|
|
8562
8816
|
if (t === "webp") return "image/webp";
|
|
8563
8817
|
if (t === "avif") return "image/avif";
|
|
8564
8818
|
if (t === "jpeg" || t === "jpg") return "image/jpeg";
|
|
@@ -8566,7 +8820,7 @@ function ot(e, t) {
|
|
|
8566
8820
|
let n = e.toLowerCase();
|
|
8567
8821
|
return n.endsWith(".jpg") || n.endsWith(".jpeg") ? "image/jpeg" : n.endsWith(".png") ? "image/png" : n.endsWith(".webp") ? "image/webp" : n.endsWith(".svg") ? "image/svg+xml" : n.endsWith(".pdf") ? "application/pdf" : n.endsWith(".mp4") ? "video/mp4" : "application/octet-stream";
|
|
8568
8822
|
}
|
|
8569
|
-
|
|
8823
|
+
pt.get("/*", async (e) => {
|
|
8570
8824
|
try {
|
|
8571
8825
|
let t = e.req.path.replace(/^\/media\//, "").replace(/^\//, "");
|
|
8572
8826
|
if (!t) return e.text("Asset key missing", 400);
|
|
@@ -8582,11 +8836,11 @@ at.get("/*", async (e) => {
|
|
|
8582
8836
|
let e = await l.match(d);
|
|
8583
8837
|
if (e) return e;
|
|
8584
8838
|
}
|
|
8585
|
-
let { storage: f, optimizer: p } =
|
|
8839
|
+
let { storage: f, optimizer: p } = ae(e.env), m = await f.get(t);
|
|
8586
8840
|
if (!m) return e.text(`Asset not found: ${t}`, 404);
|
|
8587
8841
|
if (!o) {
|
|
8588
8842
|
let n = e.body(m, 200, {
|
|
8589
|
-
"Content-Type":
|
|
8843
|
+
"Content-Type": mt(t),
|
|
8590
8844
|
"Cache-Control": "public, max-age=31536000, immutable"
|
|
8591
8845
|
});
|
|
8592
8846
|
return l && d && e.executionCtx?.waitUntil && e.executionCtx.waitUntil(l.put(d, n.clone())), n;
|
|
@@ -8600,7 +8854,7 @@ at.get("/*", async (e) => {
|
|
|
8600
8854
|
key: t,
|
|
8601
8855
|
env: e.env,
|
|
8602
8856
|
req: e.req.raw
|
|
8603
|
-
}), _ =
|
|
8857
|
+
}), _ = mt(t, c), v = e.body(g, 200, {
|
|
8604
8858
|
"Content-Type": _,
|
|
8605
8859
|
"Cache-Control": "public, max-age=31536000, immutable"
|
|
8606
8860
|
});
|
|
@@ -8611,8 +8865,8 @@ at.get("/*", async (e) => {
|
|
|
8611
8865
|
});
|
|
8612
8866
|
//#endregion
|
|
8613
8867
|
//#region server/routes/public/paths.ts
|
|
8614
|
-
var
|
|
8615
|
-
function
|
|
8868
|
+
var ht = new e();
|
|
8869
|
+
function gt(e, t) {
|
|
8616
8870
|
let n = /* @__PURE__ */ new Date();
|
|
8617
8871
|
if (e && String(e).trim() !== "") {
|
|
8618
8872
|
let t = new Date(e);
|
|
@@ -8624,7 +8878,7 @@ function ct(e, t) {
|
|
|
8624
8878
|
}
|
|
8625
8879
|
return !0;
|
|
8626
8880
|
}
|
|
8627
|
-
|
|
8881
|
+
ht.get("/", async (e) => {
|
|
8628
8882
|
try {
|
|
8629
8883
|
let t = await e.get("db").prepare("\n SELECT\n t.id as treeNodeId,\n t.parentId,\n c.slug,\n c.contentType as nodeType,\n c.status,\n c.dataJson\n FROM tree_nodes t\n INNER JOIN content_nodes c ON t.contentId = c.id\n WHERE (c.deletedAt IS NULL OR c.deletedAt = '')\n ORDER BY t.sortOrder ASC\n ").all(), n = Array.isArray(t) ? t : t?.results || [], r = [], i = /* @__PURE__ */ new Map();
|
|
8630
8884
|
for (let e of n) {
|
|
@@ -8648,7 +8902,7 @@ st.get("/", async (e) => {
|
|
|
8648
8902
|
function o(e = null, t = "") {
|
|
8649
8903
|
let n = e == null || e === "" || e === "null" ? "__ROOT__" : String(e), s = i.get(n) || [];
|
|
8650
8904
|
for (let e of s) {
|
|
8651
|
-
let n = a.get(String(e.treeNodeId)) || {}, i = e.status === "published" || e.status === "active", s =
|
|
8905
|
+
let n = a.get(String(e.treeNodeId)) || {}, i = e.status === "published" || e.status === "active", s = gt(n.startShowingAt, n.stopShowingAt);
|
|
8652
8906
|
if (!i || !s) continue;
|
|
8653
8907
|
let c = (e.slug || "").replace(/^\/+|\/+$/g, ""), l = c === "home" || c === "homee" ? "/" : `${t}/${c}`.replace(/\/+/g, "/");
|
|
8654
8908
|
e.nodeType !== "external-link" && r.push(l);
|
|
@@ -8665,7 +8919,7 @@ st.get("/", async (e) => {
|
|
|
8665
8919
|
});
|
|
8666
8920
|
//#endregion
|
|
8667
8921
|
//#region server/index.ts
|
|
8668
|
-
var $ = new e(),
|
|
8922
|
+
var $ = new e(), _t = !1;
|
|
8669
8923
|
$.use("*", t()), $.use("/media/*", t({
|
|
8670
8924
|
origin: "*",
|
|
8671
8925
|
allowMethods: [
|
|
@@ -8686,13 +8940,13 @@ $.use("*", t()), $.use("/media/*", t({
|
|
|
8686
8940
|
let n = new URL(e.req.url), r = (e.req.header("host") || n.hostname).split(":")[0];
|
|
8687
8941
|
e.set("currentDomain", r);
|
|
8688
8942
|
let i = l(e);
|
|
8689
|
-
if (e.set("db", i), !
|
|
8690
|
-
await _(i),
|
|
8943
|
+
if (e.set("db", i), !_t) try {
|
|
8944
|
+
await _(i), _t = !0;
|
|
8691
8945
|
} catch (e) {
|
|
8692
8946
|
console.error("❌ [CMS Server] Failed to initialize system tables on cold start:", e);
|
|
8693
8947
|
}
|
|
8694
8948
|
await t();
|
|
8695
|
-
}), $.route("/media",
|
|
8949
|
+
}), $.route("/media", pt), $.use("/media/*", y()), $.route("/api/cms/nodes", H), $.route("/api/cms/nodes.json", H), $.route("/api/cms/formcsv", H), $.route("/api/cms/formcsv.json", H), $.route("/api/cms/stats", Le), $.route("/api/cms/stats.json", Le), $.route("/api/cms", W), $.route("/api/cms/channels", ye), $.route("/api/cms/channels.json", ye), $.route("/api/cms/schemas", Me), $.route("/api/cms/schemas.json", Me), $.route("/api/cms", Pe), $.route("/api/admin/assets", X), $.route("/api/v1/node", ze), $.route("/api/v1/page", ze), $.route("/api/v1/tree", rt), $.route("/api/v1/channel", ot), $.route("/api/v1/all-paths", ht), $.get("*", async (e, t) => {
|
|
8696
8950
|
if (e.env?.ASSETS) {
|
|
8697
8951
|
let t = await e.env.ASSETS.fetch(e.req.raw);
|
|
8698
8952
|
if (t.status === 404) {
|
|
@@ -8704,4 +8958,4 @@ $.use("*", t()), $.use("/media/*", t({
|
|
|
8704
8958
|
return t();
|
|
8705
8959
|
});
|
|
8706
8960
|
//#endregion
|
|
8707
|
-
export { $ as app, $ as default,
|
|
8961
|
+
export { $ as app, $ as default, ke as compileDefinitions, Ae as getCmsDefinitions };
|