@brightsideoy/kama 0.1.0-alpha.156 → 0.1.0-alpha.158
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 +222 -253
- package/content/definitions/nodes/page.yaml +0 -16
- package/dist/assets/index-B-WxBAFU.js +164 -0
- package/dist/assets/index-C5TmJVER.css +1 -0
- package/dist/{dist-C-WAK7EF.js → dist-CBGESg3a.js} +691 -475
- package/dist/index.html +2 -2
- package/dist/index.js +693 -475
- 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 +99 -33
- 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 +86 -17
- package/templates/astro-starter/src/pages/[...slug].astro +10 -22
- package/definitions/_page.yaml +0 -52
- package/dist/assets/index-DnRQYNN4.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
|
@@ -1854,24 +1854,6 @@ var u = /* @__PURE__ */ o({
|
|
|
1854
1854
|
},
|
|
1855
1855
|
required: !0
|
|
1856
1856
|
},
|
|
1857
|
-
logoText: {
|
|
1858
|
-
label: "Logo Text",
|
|
1859
|
-
type: "text",
|
|
1860
|
-
required: !1,
|
|
1861
|
-
public: !0,
|
|
1862
|
-
inherits: "logoText",
|
|
1863
|
-
rules: { required: !1 }
|
|
1864
|
-
},
|
|
1865
|
-
logoImage: {
|
|
1866
|
-
label: "Logo Image",
|
|
1867
|
-
type: "image",
|
|
1868
|
-
maxPreviewWidth: "300px",
|
|
1869
|
-
multiple: !1,
|
|
1870
|
-
allowedTypes: ["image/svg"],
|
|
1871
|
-
public: !0,
|
|
1872
|
-
inherits: "logoImage",
|
|
1873
|
-
rules: {}
|
|
1874
|
-
},
|
|
1875
1857
|
layoutId: {
|
|
1876
1858
|
label: "Page Layout",
|
|
1877
1859
|
type: "layout-select",
|
|
@@ -2200,24 +2182,6 @@ var u = /* @__PURE__ */ o({
|
|
|
2200
2182
|
},
|
|
2201
2183
|
required: !0
|
|
2202
2184
|
},
|
|
2203
|
-
logoText: {
|
|
2204
|
-
label: "Logo Text",
|
|
2205
|
-
type: "text",
|
|
2206
|
-
required: !1,
|
|
2207
|
-
public: !0,
|
|
2208
|
-
inherits: "logoText",
|
|
2209
|
-
rules: { required: !1 }
|
|
2210
|
-
},
|
|
2211
|
-
logoImage: {
|
|
2212
|
-
label: "Logo Image",
|
|
2213
|
-
type: "image",
|
|
2214
|
-
maxPreviewWidth: "300px",
|
|
2215
|
-
multiple: !1,
|
|
2216
|
-
allowedTypes: ["image/svg"],
|
|
2217
|
-
public: !0,
|
|
2218
|
-
inherits: "logoImage",
|
|
2219
|
-
rules: {}
|
|
2220
|
-
},
|
|
2221
2185
|
layoutId: {
|
|
2222
2186
|
label: "Page Layout",
|
|
2223
2187
|
type: "layout-select",
|
|
@@ -4815,10 +4779,10 @@ var u = /* @__PURE__ */ o({
|
|
|
4815
4779
|
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
4780
|
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
4781
|
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
|
|
4782
|
+
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
4783
|
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
4784
|
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
|
|
4785
|
+
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
4786
|
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
4787
|
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
4788
|
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 +5547,7 @@ var b = { hasSubscribers: !1 }, x = b, S = b, C = typeof performance == "object"
|
|
|
5583
5547
|
async clear() {
|
|
5584
5548
|
this.cache.clear();
|
|
5585
5549
|
}
|
|
5586
|
-
},
|
|
5550
|
+
}, P = class {
|
|
5587
5551
|
kv;
|
|
5588
5552
|
constructor(e) {
|
|
5589
5553
|
this.kv = e;
|
|
@@ -5600,7 +5564,7 @@ var b = { hasSubscribers: !1 }, x = b, S = b, C = typeof performance == "object"
|
|
|
5600
5564
|
this.kv && await this.kv.delete(e);
|
|
5601
5565
|
}
|
|
5602
5566
|
async clear() {}
|
|
5603
|
-
},
|
|
5567
|
+
}, te = class {
|
|
5604
5568
|
async get() {
|
|
5605
5569
|
return null;
|
|
5606
5570
|
}
|
|
@@ -5610,7 +5574,7 @@ var b = { hasSubscribers: !1 }, x = b, S = b, C = typeof performance == "object"
|
|
|
5610
5574
|
}, F = null;
|
|
5611
5575
|
function I(e) {
|
|
5612
5576
|
let t = process.env.CACHE_DRIVER || "lru";
|
|
5613
|
-
return t === "none" || t === "off" || t === "false" ? new
|
|
5577
|
+
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
5578
|
}
|
|
5615
5579
|
//#endregion
|
|
5616
5580
|
//#region server/storage/local.ts
|
|
@@ -5683,7 +5647,7 @@ var L = class {
|
|
|
5683
5647
|
if (e.code !== "ENOENT") throw e;
|
|
5684
5648
|
}
|
|
5685
5649
|
}
|
|
5686
|
-
},
|
|
5650
|
+
}, ne = class {
|
|
5687
5651
|
async process(e, t, n) {
|
|
5688
5652
|
let r = await import(
|
|
5689
5653
|
/* @vite-ignore */
|
|
@@ -5710,7 +5674,7 @@ var L = class {
|
|
|
5710
5674
|
return console.warn("⚠️ [SharpImageOptimizer] Processing failed, returning raw buffer."), e;
|
|
5711
5675
|
}
|
|
5712
5676
|
}
|
|
5713
|
-
},
|
|
5677
|
+
}, re = class {
|
|
5714
5678
|
bucket;
|
|
5715
5679
|
publicDomain;
|
|
5716
5680
|
constructor(e, t) {
|
|
@@ -5755,7 +5719,7 @@ var L = class {
|
|
|
5755
5719
|
async delete(e) {
|
|
5756
5720
|
await this.bucket.delete(e);
|
|
5757
5721
|
}
|
|
5758
|
-
},
|
|
5722
|
+
}, ie = class {
|
|
5759
5723
|
async process(e, t, n) {
|
|
5760
5724
|
let { env: r, key: i, req: a } = n;
|
|
5761
5725
|
if (r.IMAGES) try {
|
|
@@ -5792,18 +5756,18 @@ var L = class {
|
|
|
5792
5756
|
};
|
|
5793
5757
|
//#endregion
|
|
5794
5758
|
//#region server/storage/factory.ts
|
|
5795
|
-
function
|
|
5759
|
+
function ae(e) {
|
|
5796
5760
|
return e.KAMA_RUNTIME === "cloudflare" || e.MEDIA_BUCKET ? {
|
|
5797
|
-
storage: new
|
|
5798
|
-
optimizer: new
|
|
5761
|
+
storage: new re(e.MEDIA_BUCKET, e.CDN_DOMAIN || ""),
|
|
5762
|
+
optimizer: new ie()
|
|
5799
5763
|
} : {
|
|
5800
5764
|
storage: new L(e.LOCAL_MEDIA_PATH),
|
|
5801
|
-
optimizer: new
|
|
5765
|
+
optimizer: new ne()
|
|
5802
5766
|
};
|
|
5803
5767
|
}
|
|
5804
5768
|
//#endregion
|
|
5805
5769
|
//#region server/utils/node-assets-interceptor.ts
|
|
5806
|
-
function
|
|
5770
|
+
function R(e) {
|
|
5807
5771
|
if (!e || typeof e != "object") return {
|
|
5808
5772
|
cleanedData: e,
|
|
5809
5773
|
assetRefs: []
|
|
@@ -5881,7 +5845,7 @@ function z(e) {
|
|
|
5881
5845
|
}
|
|
5882
5846
|
return null;
|
|
5883
5847
|
}
|
|
5884
|
-
async function
|
|
5848
|
+
async function B(e, t) {
|
|
5885
5849
|
if (!t || typeof t != "object") return t;
|
|
5886
5850
|
let n = /* @__PURE__ */ new Set(), r = (e) => {
|
|
5887
5851
|
if (!e) return;
|
|
@@ -5994,7 +5958,7 @@ async function se(e, t) {
|
|
|
5994
5958
|
}
|
|
5995
5959
|
//#endregion
|
|
5996
5960
|
//#region src/utils/schema-loader.ts
|
|
5997
|
-
function
|
|
5961
|
+
function se(e) {
|
|
5998
5962
|
return e ? {
|
|
5999
5963
|
nodes: e.nodes || {},
|
|
6000
5964
|
trees: e.trees || {},
|
|
@@ -6013,7 +5977,7 @@ function ce(e) {
|
|
|
6013
5977
|
}
|
|
6014
5978
|
//#endregion
|
|
6015
5979
|
//#region server/services/cache-manager.ts
|
|
6016
|
-
var
|
|
5980
|
+
var V = class {
|
|
6017
5981
|
env;
|
|
6018
5982
|
constructor(e) {
|
|
6019
5983
|
this.env = e || {};
|
|
@@ -6025,7 +5989,8 @@ var B = class {
|
|
|
6025
5989
|
apiToken: e.env?.CLOUDFLARE_API_TOKEN || this.env.CLOUDFLARE_API_TOKEN,
|
|
6026
5990
|
frontendUrl: (e.env?.PUBLIC_FRONTEND_URL || this.env.PUBLIC_FRONTEND_URL || "http://localhost:4321").replace(/\/+$/, ""),
|
|
6027
5991
|
cdnDomain: t ? t.replace(/^https?:\/\//, "").replace(/\/+$/, "") : "localhost:8787",
|
|
6028
|
-
frontendWorker: e.env?.FRONTEND_WORKER || this.env.FRONTEND_WORKER
|
|
5992
|
+
frontendWorker: e.env?.FRONTEND_WORKER || this.env.FRONTEND_WORKER,
|
|
5993
|
+
disableCachePurge: e.env?.DISABLE_CACHE_PURGE || this.env.DISABLE_CACHE_PURGE
|
|
6029
5994
|
};
|
|
6030
5995
|
}
|
|
6031
5996
|
isLocalEnv(e, t) {
|
|
@@ -6049,19 +6014,33 @@ var B = class {
|
|
|
6049
6014
|
return r && n && r.startsWith(`https://${n}/`) && !r.includes("/media/") && (r = r.replace(`https://${n}/`, `https://${n}/media/`)), r;
|
|
6050
6015
|
}
|
|
6051
6016
|
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
|
-
|
|
6017
|
+
let { apiToken: r, frontendUrl: i, frontendWorker: a, disableCachePurge: o } = this.getEnv(e);
|
|
6018
|
+
if (o === "true" || o === !0 || o === "1") return new Response(JSON.stringify({ skipped: !0 }), { status: 200 });
|
|
6019
|
+
let s = (n || i).replace(/\/+$/, ""), c = `${s}/api/purge`, l = { "Content-Type": "application/json" };
|
|
6020
|
+
if (r && (l.Authorization = `Bearer ${r}`), a && typeof a.fetch == "function") try {
|
|
6021
|
+
return await a.fetch(new Request(c, {
|
|
6022
|
+
method: "POST",
|
|
6023
|
+
headers: l,
|
|
6024
|
+
body: JSON.stringify(t)
|
|
6025
|
+
}));
|
|
6026
|
+
} catch (e) {
|
|
6027
|
+
return console.info(`[CacheManager] Worker binding purge call to ${c} failed silently:`, e?.message || e), new Response(JSON.stringify({ error: e?.message }), { status: 502 });
|
|
6028
|
+
}
|
|
6029
|
+
try {
|
|
6030
|
+
let e = new AbortController(), n = setTimeout(() => e.abort(), 1500);
|
|
6031
|
+
console.log(`[CacheManager] Dispatching POST purge request to: ${c}`);
|
|
6032
|
+
let r = await fetch(c, {
|
|
6033
|
+
method: "POST",
|
|
6034
|
+
headers: l,
|
|
6035
|
+
body: JSON.stringify(t),
|
|
6036
|
+
signal: e.signal
|
|
6037
|
+
});
|
|
6038
|
+
return clearTimeout(n), r;
|
|
6039
|
+
} catch (e) {
|
|
6040
|
+
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 });
|
|
6041
|
+
}
|
|
6063
6042
|
}
|
|
6064
|
-
async purgeInternalWorkerCache(e, t, n, r, i
|
|
6043
|
+
async purgeInternalWorkerCache(e, t, n, r, i) {
|
|
6065
6044
|
try {
|
|
6066
6045
|
let a = I(e);
|
|
6067
6046
|
if (n) {
|
|
@@ -6074,7 +6053,7 @@ var B = class {
|
|
|
6074
6053
|
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
6054
|
i.length > 0 && (o = i.flatMap((e) => [String(e.id), e.key]).filter(Boolean));
|
|
6076
6055
|
}
|
|
6077
|
-
for (let t of o) await a.delete(`node:${t}:${i}:${e}`), await a.delete(`node:${t}:${i}:/${e}`);
|
|
6056
|
+
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
6057
|
}
|
|
6079
6058
|
} catch (e) {
|
|
6080
6059
|
console.warn("[CacheManager] Failed to purge internal worker cache:", e);
|
|
@@ -6085,30 +6064,30 @@ var B = class {
|
|
|
6085
6064
|
try {
|
|
6086
6065
|
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
6066
|
if (!a.slug) return;
|
|
6088
|
-
let o =
|
|
6089
|
-
for (let e of
|
|
6067
|
+
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();
|
|
6068
|
+
for (let e of c) if (e.baseUrl && typeof e.baseUrl == "string" && e.baseUrl.trim() !== "") {
|
|
6090
6069
|
let t = e.baseUrl.trim();
|
|
6091
|
-
!t.startsWith("http://") && !t.startsWith("https://") && (t = `https://${t}`),
|
|
6070
|
+
!t.startsWith("http://") && !t.startsWith("https://") && (t = `https://${t}`), p.add(t.replace(/\/+$/, ""));
|
|
6092
6071
|
}
|
|
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),
|
|
6072
|
+
p.size === 0 && f && p.add(f);
|
|
6073
|
+
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);
|
|
6074
|
+
await this.purgeInternalWorkerCache(e, t, n, d, u);
|
|
6075
|
+
let _ = this.getEnv(e).cdnDomain, { zoneId: v, apiToken: y } = this.getEnv(e);
|
|
6076
|
+
for (let t of p) {
|
|
6077
|
+
let n = d === "home" || !d ? t : `${t}/${d}`, i = [n, `${n}/`], a = u ? `&lang=${u}` : "";
|
|
6078
|
+
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}`);
|
|
6079
|
+
else i.push(`https://${_}/api/v1/node/${d}${u ? `?lang=${u}` : ""}`);
|
|
6080
|
+
for (let e of g) e && i.push(`${t}${e.startsWith("/") ? e : `/${e}`}`);
|
|
6081
|
+
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
6082
|
method: "POST",
|
|
6104
6083
|
headers: {
|
|
6105
|
-
Authorization: `Bearer ${
|
|
6084
|
+
Authorization: `Bearer ${y}`,
|
|
6106
6085
|
"Content-Type": "application/json"
|
|
6107
6086
|
},
|
|
6108
6087
|
body: JSON.stringify({ files: i })
|
|
6109
6088
|
}).catch(() => {}), !r) {
|
|
6110
6089
|
let e = `${n}${n.includes("?") ? "&" : "?"} _warmer=${Date.now()}`;
|
|
6111
|
-
console.log(`[CacheManager] Prewarming cache at: ${e}`),
|
|
6090
|
+
console.log(`[CacheManager] Prewarming cache at: ${e}`), fetch(e, { headers: {
|
|
6112
6091
|
"X-Cache-Warmer": "true",
|
|
6113
6092
|
"User-Agent": "Kama-Cache-Warmer/1.0"
|
|
6114
6093
|
} }).catch((e) => console.warn("[CacheManager] Prewarm fetch error:", e));
|
|
@@ -6137,35 +6116,49 @@ var B = class {
|
|
|
6137
6116
|
}
|
|
6138
6117
|
async purgeGlobalCacheDirect(e, t) {
|
|
6139
6118
|
try {
|
|
6140
|
-
let { zoneId: n, apiToken: r
|
|
6141
|
-
if (
|
|
6142
|
-
n && r && fetch(`https://api.cloudflare.com/client/v4/zones/${n}/purge_cache`, {
|
|
6119
|
+
let { zoneId: n, apiToken: r } = this.getEnv(e);
|
|
6120
|
+
if (!(await this.callAstroPurge(e, { purge_everything: !0 })).ok) return;
|
|
6121
|
+
if (n && r && !this.isLocalEnv(e) && fetch(`https://api.cloudflare.com/client/v4/zones/${n}/purge_cache`, {
|
|
6143
6122
|
method: "POST",
|
|
6144
6123
|
headers: {
|
|
6145
6124
|
Authorization: `Bearer ${r}`,
|
|
6146
6125
|
"Content-Type": "application/json"
|
|
6147
6126
|
},
|
|
6148
6127
|
body: JSON.stringify({ purge_everything: !0 })
|
|
6149
|
-
}).catch(() => {}), await new Promise((e) => setTimeout(e, 100)), t
|
|
6128
|
+
}).catch(() => {}), await new Promise((e) => setTimeout(e, 100)), t) await this.warmAllPublishedPages(e, t);
|
|
6129
|
+
else {
|
|
6130
|
+
let { frontendUrl: t } = this.getEnv(e);
|
|
6131
|
+
fetch(`${t.replace(/\/+$/, "")}/?_warmer=${Date.now()}`, { headers: { "X-Cache-Warmer": "true" } }).catch(() => {});
|
|
6132
|
+
}
|
|
6150
6133
|
} catch (e) {
|
|
6151
6134
|
console.warn("[CacheManager] Direct Global Purge skipped:", e);
|
|
6152
6135
|
}
|
|
6153
6136
|
}
|
|
6154
6137
|
async warmAllPublishedPages(e, t) {
|
|
6155
6138
|
try {
|
|
6156
|
-
let
|
|
6157
|
-
|
|
6158
|
-
|
|
6159
|
-
|
|
6160
|
-
|
|
6161
|
-
|
|
6162
|
-
|
|
6139
|
+
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 = {
|
|
6140
|
+
"X-Cache-Warmer": "true",
|
|
6141
|
+
"User-Agent": "Kama-Cache-Warmer/1.0"
|
|
6142
|
+
}, s = Date.now(), c = /* @__PURE__ */ new Set();
|
|
6143
|
+
for (let e of i) {
|
|
6144
|
+
let t = String(e.slug).replace(/^\/+|\/+$/g, ""), n = a;
|
|
6145
|
+
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(/\/+$/, ""));
|
|
6146
|
+
let r = t === "home" || !t ? n : `${n}/${t}`;
|
|
6147
|
+
c.add(`${r}?_warmer=${s}`);
|
|
6148
|
+
}
|
|
6149
|
+
c.add(`${a}/?_warmer=${s}`);
|
|
6150
|
+
let l = Array.from(c);
|
|
6151
|
+
for (let e = 0; e < l.length; e += 6) {
|
|
6152
|
+
let t = l.slice(e, e + 6);
|
|
6153
|
+
await Promise.all(t.map((e) => fetch(e, { headers: o }).catch((t) => console.warn(`[CacheWarmer] Skipped prewarm for ${e}:`, t?.message || t))));
|
|
6154
|
+
}
|
|
6155
|
+
console.log(`[CacheWarmer] Prewarmed ${l.length} published pages across ${Math.ceil(l.length / 6)} batches.`);
|
|
6163
6156
|
} catch (e) {
|
|
6164
6157
|
console.warn("⚠️ [CacheWarmer] Tree-wide warming failed:", e);
|
|
6165
6158
|
}
|
|
6166
6159
|
}
|
|
6167
|
-
},
|
|
6168
|
-
async function
|
|
6160
|
+
}, H = new e();
|
|
6161
|
+
async function ce(e, t, n = []) {
|
|
6169
6162
|
let r = e.prepare(t);
|
|
6170
6163
|
if (typeof r.bind == "function") {
|
|
6171
6164
|
let e = await r.bind(...n).all();
|
|
@@ -6177,24 +6170,25 @@ async function le(e, t, n = []) {
|
|
|
6177
6170
|
}
|
|
6178
6171
|
return [];
|
|
6179
6172
|
}
|
|
6180
|
-
async function
|
|
6173
|
+
async function le(e, t, n = []) {
|
|
6181
6174
|
let r = e.prepare(t);
|
|
6182
6175
|
if (typeof r.bind == "function") return r.bind(...n).run();
|
|
6183
6176
|
if (typeof r.run == "function") return r.run(...n);
|
|
6184
6177
|
}
|
|
6185
|
-
function
|
|
6178
|
+
function U(e) {
|
|
6186
6179
|
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
6180
|
}
|
|
6188
|
-
function
|
|
6181
|
+
function ue(e) {
|
|
6189
6182
|
return +(e === !0 || e === 1 || e === "1" || e === "true");
|
|
6190
6183
|
}
|
|
6191
|
-
function
|
|
6184
|
+
function de(e) {
|
|
6192
6185
|
if (e == null || e === "null" || e === "" || typeof e == "string" && e.startsWith("draft-")) return null;
|
|
6193
6186
|
let t = Number(e);
|
|
6194
6187
|
return isNaN(t) ? null : t;
|
|
6195
6188
|
}
|
|
6196
|
-
function
|
|
6189
|
+
function fe(e) {
|
|
6197
6190
|
let t = { ...e };
|
|
6191
|
+
delete t.language, delete t.defaultLanguage;
|
|
6198
6192
|
for (let e of [
|
|
6199
6193
|
"id",
|
|
6200
6194
|
"treeNodeId",
|
|
@@ -6205,7 +6199,6 @@ function H(e) {
|
|
|
6205
6199
|
"contentType",
|
|
6206
6200
|
"title",
|
|
6207
6201
|
"slug",
|
|
6208
|
-
"language",
|
|
6209
6202
|
"hidden",
|
|
6210
6203
|
"is_hidden",
|
|
6211
6204
|
"isHidden",
|
|
@@ -6222,17 +6215,22 @@ function H(e) {
|
|
|
6222
6215
|
]) delete t[e];
|
|
6223
6216
|
return t;
|
|
6224
6217
|
}
|
|
6225
|
-
function
|
|
6226
|
-
return e ? typeof e == "string" ? (e.startsWith("ast_") && t.add(e), t) : Array.isArray(e) ? (e.forEach((e) =>
|
|
6218
|
+
function pe(e, t = /* @__PURE__ */ new Set()) {
|
|
6219
|
+
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;
|
|
6220
|
+
}
|
|
6221
|
+
function me(e, t) {
|
|
6222
|
+
if (!e) return !0;
|
|
6223
|
+
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;
|
|
6224
|
+
return n || r || i || a || c;
|
|
6227
6225
|
}
|
|
6228
|
-
async function
|
|
6226
|
+
async function he(e, t, n) {
|
|
6229
6227
|
for (let r of n) {
|
|
6230
|
-
let n = (await
|
|
6231
|
-
if (!n || (await
|
|
6228
|
+
let n = (await ce(e, "\n SELECT id, storageKeyPrivate, isSystemVariant, parentAssetId, filename\n FROM assets WHERE id = ?\n ", [r]))[0];
|
|
6229
|
+
if (!n || (await ce(e, "SELECT 1 FROM node_assets WHERE assetId = ? LIMIT 1", [n.id])).length > 0) continue;
|
|
6232
6230
|
let i = [n];
|
|
6233
6231
|
if (!n.isSystemVariant) {
|
|
6234
|
-
let t = await
|
|
6235
|
-
if (r.length > 0 && (await
|
|
6232
|
+
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);
|
|
6233
|
+
if (r.length > 0 && (await ce(e, `SELECT DISTINCT assetId FROM node_assets WHERE assetId IN (${r.map(() => "?").join(",")})`, r)).length > 0) continue;
|
|
6236
6234
|
i = [n, ...t];
|
|
6237
6235
|
}
|
|
6238
6236
|
for (let e of i) if (e.storageKeyPrivate) try {
|
|
@@ -6241,10 +6239,10 @@ async function U(e, t, n) {
|
|
|
6241
6239
|
console.warn(`[Asset Cleanup] Failed to delete ${e.storageKeyPrivate}:`, t);
|
|
6242
6240
|
}
|
|
6243
6241
|
let a = i.map((e) => e.id), o = a.map(() => "?").join(",");
|
|
6244
|
-
await
|
|
6242
|
+
await le(e, `DELETE FROM node_assets WHERE assetId IN (${o})`, a), await le(e, `DELETE FROM assets WHERE id IN (${o})`, a);
|
|
6245
6243
|
}
|
|
6246
6244
|
}
|
|
6247
|
-
async function
|
|
6245
|
+
async function ge(e, t, n) {
|
|
6248
6246
|
let r = {}, i = null;
|
|
6249
6247
|
if (t) {
|
|
6250
6248
|
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 +6256,7 @@ async function W(e, t, n) {
|
|
|
6258
6256
|
}
|
|
6259
6257
|
}
|
|
6260
6258
|
if (!i) {
|
|
6261
|
-
let t = await e.prepare("SELECT dataJson FROM trees WHERE id = ?").get(n);
|
|
6259
|
+
let t = await e.prepare("SELECT dataJson FROM trees WHERE id = ? OR key = ? LIMIT 1").get(Number(n) || -1, String(n));
|
|
6262
6260
|
if (t && t.dataJson) try {
|
|
6263
6261
|
let e = typeof t.dataJson == "string" ? JSON.parse(t.dataJson) : t.dataJson;
|
|
6264
6262
|
e.subpageLayoutId && e.subpageLayoutId !== "inherit" && (i = e.subpageLayoutId);
|
|
@@ -6269,7 +6267,7 @@ async function W(e, t, n) {
|
|
|
6269
6267
|
inheritedFields: r
|
|
6270
6268
|
};
|
|
6271
6269
|
}
|
|
6272
|
-
|
|
6270
|
+
H.get("/", async (e) => {
|
|
6273
6271
|
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
6272
|
if (n) {
|
|
6275
6273
|
let r = Number(n);
|
|
@@ -6280,7 +6278,7 @@ V.get("/", async (e) => {
|
|
|
6280
6278
|
id: i.id,
|
|
6281
6279
|
title: i.title,
|
|
6282
6280
|
slug: i.slug,
|
|
6283
|
-
language: i.language ||
|
|
6281
|
+
language: i.language || null,
|
|
6284
6282
|
nodeType: i.contentType,
|
|
6285
6283
|
contentType: i.contentType,
|
|
6286
6284
|
isHidden: !!i.isHidden,
|
|
@@ -6294,9 +6292,9 @@ V.get("/", async (e) => {
|
|
|
6294
6292
|
updatedAt: i.updatedAt
|
|
6295
6293
|
}, s = i.draftDataJson || i.dataJson;
|
|
6296
6294
|
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 =
|
|
6295
|
+
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
6296
|
if (a) {
|
|
6299
|
-
let { resolvedLayoutId: e, inheritedFields: r } = await
|
|
6297
|
+
let { resolvedLayoutId: e, inheritedFields: r } = await ge(t, a.parentId, a.treeId);
|
|
6300
6298
|
(l === "inherit" || !l) && (l = e);
|
|
6301
6299
|
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
6300
|
}
|
|
@@ -6311,7 +6309,7 @@ V.get("/", async (e) => {
|
|
|
6311
6309
|
let r = t.allowedLayouts;
|
|
6312
6310
|
return r ? typeof r == "string" ? r === e : !Array.isArray(r) || r.length === 0 || r.includes(e) : !0;
|
|
6313
6311
|
})(l) && (l = null), (l === "inherit" || !l) && (l = c.defaultLayout || null);
|
|
6314
|
-
let u = await
|
|
6312
|
+
let u = await B(t, fe(n));
|
|
6315
6313
|
Object.assign(o, u), o.resolvedLayoutId = l;
|
|
6316
6314
|
} catch {}
|
|
6317
6315
|
let c = await t.prepare("SELECT channelId FROM node_channels WHERE nodeId = ?").all(r);
|
|
@@ -6321,7 +6319,7 @@ V.get("/", async (e) => {
|
|
|
6321
6319
|
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
6320
|
let n = {};
|
|
6323
6321
|
try {
|
|
6324
|
-
n = typeof e.dataJson == "string" ? JSON.parse(e.dataJson || "{}") : e.dataJson || {}, n && typeof n == "object" && (n = await
|
|
6322
|
+
n = typeof e.dataJson == "string" ? JSON.parse(e.dataJson || "{}") : e.dataJson || {}, n && typeof n == "object" && (n = await B(t, n));
|
|
6325
6323
|
} catch {
|
|
6326
6324
|
n = {};
|
|
6327
6325
|
}
|
|
@@ -6392,7 +6390,7 @@ V.get("/", async (e) => {
|
|
|
6392
6390
|
id: e.id,
|
|
6393
6391
|
title: e.title,
|
|
6394
6392
|
slug: e.slug,
|
|
6395
|
-
language: e.language ||
|
|
6393
|
+
language: e.language || null,
|
|
6396
6394
|
contentType: e.contentType,
|
|
6397
6395
|
nodeType: e.contentType,
|
|
6398
6396
|
isHidden: !!e.isHidden,
|
|
@@ -6409,7 +6407,7 @@ V.get("/", async (e) => {
|
|
|
6409
6407
|
assetCount: e.assetCount || 0
|
|
6410
6408
|
}, i = e.draftDataJson || e.dataJson;
|
|
6411
6409
|
if (i) try {
|
|
6412
|
-
let e = typeof i == "string" ? JSON.parse(i) : i, n = await
|
|
6410
|
+
let e = typeof i == "string" ? JSON.parse(i) : i, n = await B(t, fe(e));
|
|
6413
6411
|
Object.assign(r, n);
|
|
6414
6412
|
} catch {}
|
|
6415
6413
|
return r;
|
|
@@ -6421,13 +6419,35 @@ V.get("/", async (e) => {
|
|
|
6421
6419
|
offset: p,
|
|
6422
6420
|
limit: f
|
|
6423
6421
|
});
|
|
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 (
|
|
6422
|
+
}), H.post("/", async (e) => {
|
|
6423
|
+
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;
|
|
6424
|
+
if (T) {
|
|
6425
|
+
let e = await t.prepare("SELECT dataJson FROM trees WHERE id = ? OR key = ? LIMIT 1").get(Number(T) || -1, String(T));
|
|
6426
|
+
if (e?.dataJson) try {
|
|
6427
|
+
let t = typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson;
|
|
6428
|
+
E = t.defaultLanguage?.trim() || t.language?.trim() || null;
|
|
6429
|
+
} catch {}
|
|
6430
|
+
}
|
|
6431
|
+
if (!E && h && Array.isArray(h) && h.length > 0) {
|
|
6432
|
+
let e = typeof h[0] == "object" ? h[0].id : h[0];
|
|
6433
|
+
if (e && e !== "all") {
|
|
6434
|
+
let n = await t.prepare("SELECT defaultLanguage, dataJson FROM channels WHERE id = ? LIMIT 1").get(Number(e));
|
|
6435
|
+
if (n) {
|
|
6436
|
+
if (n.defaultLanguage) E = n.defaultLanguage.trim();
|
|
6437
|
+
else if (n.dataJson) try {
|
|
6438
|
+
let e = typeof n.dataJson == "string" ? JSON.parse(n.dataJson) : n.dataJson;
|
|
6439
|
+
E = e.defaultLanguage?.trim() || e.language?.trim() || null;
|
|
6440
|
+
} catch {}
|
|
6441
|
+
}
|
|
6442
|
+
}
|
|
6443
|
+
}
|
|
6444
|
+
C && E && C === E && (C = null);
|
|
6445
|
+
let D = a, O = /* @__PURE__ */ new Set(), k = !1, A = s === void 0 ? null : U(s);
|
|
6446
|
+
if (A) {
|
|
6427
6447
|
let n = [];
|
|
6428
6448
|
if (g !== void 0 && Array.isArray(g) && g.length > 0) for (let e of g) n.push({
|
|
6429
6449
|
treeId: Number(e.treeId),
|
|
6430
|
-
parentId:
|
|
6450
|
+
parentId: de(e.parentId ?? e._draftParentId ?? null)
|
|
6431
6451
|
});
|
|
6432
6452
|
else if (a) {
|
|
6433
6453
|
let e = await t.prepare("SELECT treeId, parentId FROM tree_nodes WHERE contentId = ?").all(a), r = Array.isArray(e) ? e : e?.results || [];
|
|
@@ -6437,94 +6457,103 @@ V.get("/", async (e) => {
|
|
|
6437
6457
|
});
|
|
6438
6458
|
}
|
|
6439
6459
|
for (let r of n) {
|
|
6440
|
-
let n = r.parentId === null ? "tn.parentId IS NULL" : "tn.parentId = ?", i = r.parentId === null ? [r.treeId,
|
|
6460
|
+
let n = r.parentId === null ? "tn.parentId IS NULL" : "tn.parentId = ?", i = r.parentId === null ? [r.treeId, A] : [
|
|
6441
6461
|
r.treeId,
|
|
6442
6462
|
r.parentId,
|
|
6443
|
-
|
|
6463
|
+
A
|
|
6444
6464
|
], o = `
|
|
6445
6465
|
SELECT cn.id FROM tree_nodes tn
|
|
6446
6466
|
INNER JOIN content_nodes cn ON tn.contentId = cn.id
|
|
6447
6467
|
WHERE tn.treeId = ? AND ${n} AND cn.slug = ? AND (cn.deletedAt IS NULL OR cn.deletedAt = '')
|
|
6448
6468
|
`;
|
|
6449
6469
|
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 '${
|
|
6470
|
+
error: `The slug '${A}' is already in use by another page in this section.`,
|
|
6451
6471
|
field: "slug"
|
|
6452
6472
|
}, 409);
|
|
6453
6473
|
}
|
|
6454
6474
|
}
|
|
6455
6475
|
if (a) {
|
|
6456
|
-
let e = await t.prepare("SELECT title, slug, language, contentType, draftDataJson, dataJson, publishedAt, status FROM content_nodes WHERE id = ?").get(a)
|
|
6476
|
+
let e = await t.prepare("SELECT title, slug, language, contentType, isHidden, draftDataJson, dataJson, publishedAt, status FROM content_nodes WHERE id = ?").get(a);
|
|
6477
|
+
k = me(e, {
|
|
6478
|
+
title: o,
|
|
6479
|
+
slug: A,
|
|
6480
|
+
isHidden: b,
|
|
6481
|
+
sanitizedFields: v
|
|
6482
|
+
});
|
|
6483
|
+
let n = e?.draftDataJson || e?.dataJson || "{}";
|
|
6457
6484
|
try {
|
|
6458
|
-
|
|
6485
|
+
pe(typeof n == "string" ? JSON.parse(n) : n, O);
|
|
6459
6486
|
} catch {}
|
|
6460
6487
|
if (m !== void 0) {
|
|
6461
6488
|
let e = await t.prepare("SELECT dataJson FROM content_blocks WHERE contentId = ? AND isDraft = 1").all(a);
|
|
6462
6489
|
(Array.isArray(e) ? e : e?.results || []).forEach((e) => {
|
|
6463
6490
|
try {
|
|
6464
|
-
|
|
6491
|
+
pe(typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson, O);
|
|
6465
6492
|
} catch {}
|
|
6466
6493
|
});
|
|
6467
6494
|
}
|
|
6468
|
-
let r = o === void 0 ? e?.title || "Untitled" : o, i =
|
|
6495
|
+
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
6496
|
try {
|
|
6470
|
-
|
|
6497
|
+
d = JSON.parse(u);
|
|
6471
6498
|
} catch {}
|
|
6472
|
-
let
|
|
6473
|
-
...
|
|
6499
|
+
let f = JSON.stringify({
|
|
6500
|
+
...d,
|
|
6474
6501
|
...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,
|
|
6502
|
+
}), p = e?.status === "published" || e?.publishedAt ? "published" : "draft", h = +(p === "published");
|
|
6503
|
+
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
6504
|
} else {
|
|
6478
|
-
|
|
6479
|
-
|
|
6505
|
+
k = !0;
|
|
6506
|
+
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);
|
|
6507
|
+
D = Number(e.lastInsertRowid);
|
|
6480
6508
|
}
|
|
6481
|
-
if (h !== void 0 && Array.isArray(h) &&
|
|
6482
|
-
await t.prepare("DELETE FROM node_channels WHERE nodeId = ?").run(
|
|
6509
|
+
if (h !== void 0 && Array.isArray(h) && D) {
|
|
6510
|
+
await t.prepare("DELETE FROM node_channels WHERE nodeId = ?").run(D);
|
|
6483
6511
|
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
6512
|
if (e.length > 0) {
|
|
6485
|
-
let n = e.map(() => "(?, ?)").join(", "), r = e.flatMap((e) => [
|
|
6513
|
+
let n = e.map(() => "(?, ?)").join(", "), r = e.flatMap((e) => [D, e]);
|
|
6486
6514
|
await t.prepare(`INSERT OR IGNORE INTO node_channels (nodeId, channelId) VALUES ${n}`).run(...r);
|
|
6487
6515
|
}
|
|
6488
6516
|
}
|
|
6489
|
-
if (g !== void 0 && Array.isArray(g) && g.length > 0 &&
|
|
6517
|
+
if (g !== void 0 && Array.isArray(g) && g.length > 0 && D) for (let e of g) {
|
|
6490
6518
|
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,
|
|
6519
|
+
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);
|
|
6520
|
+
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
6521
|
}
|
|
6494
|
-
let
|
|
6495
|
-
if (m !== void 0 && Array.isArray(m) &&
|
|
6496
|
-
await t.prepare("DELETE FROM content_blocks WHERE contentId = ? AND isDraft = 1").run(
|
|
6522
|
+
let j = [];
|
|
6523
|
+
if (m !== void 0 && Array.isArray(m) && D) {
|
|
6524
|
+
await t.prepare("DELETE FROM content_blocks WHERE contentId = ? AND isDraft = 1").run(D);
|
|
6497
6525
|
let e = [], n = [];
|
|
6498
6526
|
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 } =
|
|
6527
|
+
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
6528
|
...a,
|
|
6501
6529
|
blockId: o,
|
|
6502
6530
|
_instanceId: o
|
|
6503
6531
|
});
|
|
6504
|
-
c.forEach((e) =>
|
|
6532
|
+
c.forEach((e) => j.push({
|
|
6505
6533
|
...e,
|
|
6506
6534
|
fieldKey: `blocks[${t}].${e.fieldKey}`
|
|
6507
6535
|
}));
|
|
6508
6536
|
let l = r.region !== void 0 && r.region !== null && String(r.region).trim() !== "" ? String(r.region) : "content";
|
|
6509
|
-
e.push("(?, ?, ?, ?, ?, 1)"), n.push(
|
|
6537
|
+
e.push("(?, ?, ?, ?, ?, 1)"), n.push(D, t, i, JSON.stringify(s), l);
|
|
6510
6538
|
}
|
|
6511
6539
|
e.length > 0 && await t.prepare(`INSERT INTO content_blocks (contentId, sortOrder, elementType, dataJson, region, isDraft) VALUES ${e.join(", ")}`).run(...n);
|
|
6512
6540
|
}
|
|
6513
|
-
if (
|
|
6514
|
-
let n = [...y, ...
|
|
6515
|
-
await oe(t,
|
|
6516
|
-
let r = new Set(n.map((e) => e.assetId)), i = new Set([...
|
|
6541
|
+
if (D) {
|
|
6542
|
+
let n = [...y, ...j];
|
|
6543
|
+
await oe(t, D, n);
|
|
6544
|
+
let r = new Set(n.map((e) => e.assetId)), i = new Set([...O].filter((e) => !r.has(e)));
|
|
6517
6545
|
if (i.size > 0) {
|
|
6518
|
-
let { storage: n } =
|
|
6519
|
-
await
|
|
6546
|
+
let { storage: n } = ae(e.env);
|
|
6547
|
+
await he(t, n, i);
|
|
6520
6548
|
}
|
|
6521
6549
|
}
|
|
6522
|
-
return await I(e).clear(), e.json({
|
|
6550
|
+
return await I(e).clear(), D && new V(e.env).purgeNode(e, t, D, k), e.json({
|
|
6523
6551
|
success: !0,
|
|
6524
|
-
id:
|
|
6525
|
-
status: "draft"
|
|
6552
|
+
id: D,
|
|
6553
|
+
status: "draft",
|
|
6554
|
+
isStructuralChange: k
|
|
6526
6555
|
});
|
|
6527
|
-
}),
|
|
6556
|
+
}), H.post("/publish", async (e) => {
|
|
6528
6557
|
let t = e.get("db"), n = await e.req.json(), r = n.id || n.nodeId;
|
|
6529
6558
|
if (!r || isNaN(Number(r))) return e.json({ error: "Node ID required for publishing" }, 400);
|
|
6530
6559
|
let i = Number(r), a = e.get("user")?.id || null, o = await t.prepare("SELECT * FROM content_nodes WHERE id = ?").get(i);
|
|
@@ -6537,57 +6566,58 @@ V.get("/", async (e) => {
|
|
|
6537
6566
|
try {
|
|
6538
6567
|
c = typeof o.draftDataJson == "string" ? JSON.parse(o.draftDataJson) : o.draftDataJson || {};
|
|
6539
6568
|
} 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 (
|
|
6569
|
+
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 || "{}";
|
|
6570
|
+
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);
|
|
6571
|
+
let _ = await t.prepare("SELECT * FROM content_blocks WHERE contentId = ? AND isDraft = 1 ORDER BY sortOrder ASC").all(i), v = Array.isArray(_) ? _ : _?.results || [];
|
|
6572
|
+
if (v.length > 0) {
|
|
6544
6573
|
let e = [], n = [];
|
|
6545
|
-
for (let t of
|
|
6574
|
+
for (let t of v) {
|
|
6546
6575
|
let r = t.region !== void 0 && t.region !== null && String(t.region).trim() !== "" ? String(t.region) : "content";
|
|
6547
6576
|
e.push("(?, ?, ?, ?, ?, 0)"), n.push(i, t.sortOrder, t.elementType, t.dataJson, r);
|
|
6548
6577
|
}
|
|
6549
6578
|
await t.prepare(`INSERT INTO content_blocks (contentId, sortOrder, elementType, dataJson, region, isDraft) VALUES ${e.join(", ")}`).run(...n);
|
|
6550
6579
|
}
|
|
6551
|
-
let
|
|
6552
|
-
version:
|
|
6580
|
+
let y = ((await t.prepare("SELECT COUNT(*) as count FROM node_revisions WHERE nodeId = ?").get(i))?.count || 0) + 1, b = {
|
|
6581
|
+
version: y,
|
|
6553
6582
|
publishedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6554
6583
|
node: {
|
|
6555
6584
|
...o,
|
|
6556
|
-
dataJson:
|
|
6585
|
+
dataJson: g
|
|
6557
6586
|
},
|
|
6558
|
-
blocks:
|
|
6587
|
+
blocks: v
|
|
6559
6588
|
};
|
|
6560
|
-
return await t.prepare("INSERT INTO node_revisions (nodeId, version, snapshotJson, createdById) VALUES (?, ?, ?, ?)").run(i,
|
|
6589
|
+
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
6590
|
success: !0,
|
|
6562
6591
|
id: i,
|
|
6563
6592
|
status: "published",
|
|
6564
|
-
version:
|
|
6565
|
-
publishedAt:
|
|
6566
|
-
hasUnpublishedChanges: !1
|
|
6593
|
+
version: y,
|
|
6594
|
+
publishedAt: b.publishedAt,
|
|
6595
|
+
hasUnpublishedChanges: !1,
|
|
6596
|
+
isStructuralChange: h
|
|
6567
6597
|
});
|
|
6568
|
-
}),
|
|
6598
|
+
}), H.delete("/", async (e) => {
|
|
6569
6599
|
let t = e.get("db"), n = e.req.query("id");
|
|
6570
6600
|
if (!n) return e.json({ error: "Node ID required" }, 400);
|
|
6571
6601
|
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
|
|
6602
|
+
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
6603
|
success: !0,
|
|
6574
6604
|
deletedNodeId: r
|
|
6575
6605
|
});
|
|
6576
|
-
}),
|
|
6606
|
+
}), H.post("/restore", async (e) => {
|
|
6577
6607
|
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
|
|
6608
|
+
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
6609
|
success: !0,
|
|
6580
6610
|
restoredNodeId: r
|
|
6581
6611
|
})) : e.json({ error: "Node not found" }, 404) : e.json({ error: "Node ID required" }, 400);
|
|
6582
|
-
}),
|
|
6612
|
+
}), H.delete("/purge", async (e) => {
|
|
6583
6613
|
let t = e.get("db"), n = e.req.query("id");
|
|
6584
6614
|
if (!n) return e.json({ error: "Node ID required" }, 400);
|
|
6585
6615
|
let r = Number(n);
|
|
6586
|
-
return new
|
|
6616
|
+
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
6617
|
success: !0,
|
|
6588
6618
|
purgedNodeId: r
|
|
6589
6619
|
});
|
|
6590
|
-
}),
|
|
6620
|
+
}), H.get("/:id/revisions", async (e) => {
|
|
6591
6621
|
let t = e.get("db"), n = Number(e.req.param("id"));
|
|
6592
6622
|
if (isNaN(n)) return e.json({ error: "Invalid Node ID" }, 400);
|
|
6593
6623
|
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 +6633,7 @@ V.get("/", async (e) => {
|
|
|
6603
6633
|
};
|
|
6604
6634
|
});
|
|
6605
6635
|
return e.json({ revisions: i });
|
|
6606
|
-
}),
|
|
6636
|
+
}), H.get("/:id/revisions/:version", async (e) => {
|
|
6607
6637
|
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
6638
|
if (!i) return e.json({ error: "Snapshot not found" }, 404);
|
|
6609
6639
|
let a = {};
|
|
@@ -6613,7 +6643,7 @@ V.get("/", async (e) => {
|
|
|
6613
6643
|
return e.json({ error: "Corrupt snapshot data" }, 500);
|
|
6614
6644
|
}
|
|
6615
6645
|
return e.json({ snapshot: a });
|
|
6616
|
-
}),
|
|
6646
|
+
}), H.post("/:id/revisions/:version/restore", async (e) => {
|
|
6617
6647
|
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
6648
|
if (!a) return e.json({ error: "Snapshot not found" }, 404);
|
|
6619
6649
|
let o = {};
|
|
@@ -6634,8 +6664,8 @@ V.get("/", async (e) => {
|
|
|
6634
6664
|
});
|
|
6635
6665
|
//#endregion
|
|
6636
6666
|
//#region server/routes/admin/trees.ts
|
|
6637
|
-
var
|
|
6638
|
-
function
|
|
6667
|
+
var W = new e();
|
|
6668
|
+
function _e(e, t = null) {
|
|
6639
6669
|
let n = [];
|
|
6640
6670
|
for (let r = 0; r < e.length; r++) {
|
|
6641
6671
|
let i = e[r];
|
|
@@ -6647,19 +6677,19 @@ function he(e, t = null) {
|
|
|
6647
6677
|
id: o,
|
|
6648
6678
|
parentId: t,
|
|
6649
6679
|
sortOrder: r
|
|
6650
|
-
}), i.children && Array.isArray(i.children) && i.children.length > 0 && n.push(...
|
|
6680
|
+
}), i.children && Array.isArray(i.children) && i.children.length > 0 && n.push(..._e(i.children, o)));
|
|
6651
6681
|
}
|
|
6652
6682
|
return n;
|
|
6653
6683
|
}
|
|
6654
|
-
function
|
|
6684
|
+
function G(e) {
|
|
6655
6685
|
if (e == null || e === "null" || e === "" || typeof e == "string" && e.startsWith("draft-")) return null;
|
|
6656
6686
|
let t = Number(e);
|
|
6657
6687
|
return isNaN(t) ? null : t;
|
|
6658
6688
|
}
|
|
6659
|
-
function
|
|
6689
|
+
function ve(e) {
|
|
6660
6690
|
return +(e === !0 || e === 1 || e === "1" || e === "true");
|
|
6661
6691
|
}
|
|
6662
|
-
|
|
6692
|
+
W.get("/tree.json", async (e) => {
|
|
6663
6693
|
try {
|
|
6664
6694
|
let t = e.get("db"), n = e.req.query("treeId") || "main-nav", r = e.req.query("preview") === "true", i = 1;
|
|
6665
6695
|
if (isNaN(Number(n))) {
|
|
@@ -6694,7 +6724,7 @@ G.get("/tree.json", async (e) => {
|
|
|
6694
6724
|
id: e.contentId,
|
|
6695
6725
|
treeNodeId: e.treeNodeId,
|
|
6696
6726
|
parentId: e.parentId || null,
|
|
6697
|
-
language: e.language ||
|
|
6727
|
+
language: e.language?.trim() || null,
|
|
6698
6728
|
hidden: +!!s,
|
|
6699
6729
|
isHidden: s,
|
|
6700
6730
|
status: e.status || "draft",
|
|
@@ -6709,9 +6739,9 @@ G.get("/tree.json", async (e) => {
|
|
|
6709
6739
|
} catch (t) {
|
|
6710
6740
|
return console.error("[CMS Tree API] GET Error:", t), e.json({ error: t.message || "Failed to fetch tree" }, 500);
|
|
6711
6741
|
}
|
|
6712
|
-
}),
|
|
6742
|
+
}), W.post("/tree.json", async (e) => {
|
|
6713
6743
|
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
|
|
6744
|
+
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
6745
|
if (isNaN(Number(r))) {
|
|
6716
6746
|
let e = await t.prepare("SELECT id FROM trees WHERE key = ?").get(r);
|
|
6717
6747
|
if (e && e.id) o = Number(e.id);
|
|
@@ -6721,7 +6751,7 @@ G.get("/tree.json", async (e) => {
|
|
|
6721
6751
|
}
|
|
6722
6752
|
} else o = Number(r);
|
|
6723
6753
|
if (n.tree && Array.isArray(n.tree)) {
|
|
6724
|
-
let r =
|
|
6754
|
+
let r = _e(n.tree, null);
|
|
6725
6755
|
if (r.length > 0) for (let e = 0; e < r.length; e += 50) {
|
|
6726
6756
|
let n = r.slice(e, e + 50), i = n.map((e) => e.id), a = i.map(() => "?").join(","), s = "UPDATE tree_nodes SET \n";
|
|
6727
6757
|
s += "parentId = CASE id \n", n.forEach(() => {
|
|
@@ -6741,9 +6771,9 @@ G.get("/tree.json", async (e) => {
|
|
|
6741
6771
|
reorderedCount: r.length
|
|
6742
6772
|
});
|
|
6743
6773
|
}
|
|
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 =
|
|
6774
|
+
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
6775
|
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 =
|
|
6776
|
+
let g = G(u), _ = e.get("user")?.id || null;
|
|
6747
6777
|
if (s === "create") {
|
|
6748
6778
|
let r = m.slug || n.slug || c, s = r ? String(r).toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "") : null;
|
|
6749
6779
|
if (s) {
|
|
@@ -6765,23 +6795,41 @@ G.get("/tree.json", async (e) => {
|
|
|
6765
6795
|
field: "slug"
|
|
6766
6796
|
}, 409);
|
|
6767
6797
|
}
|
|
6768
|
-
let u =
|
|
6769
|
-
|
|
6770
|
-
|
|
6798
|
+
let u = m.language?.trim() || n.language?.trim() || null;
|
|
6799
|
+
if (!u) {
|
|
6800
|
+
let e = await t.prepare("SELECT dataJson FROM trees WHERE id = ?").get(o);
|
|
6801
|
+
if (e?.dataJson) try {
|
|
6802
|
+
let t = typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson;
|
|
6803
|
+
t.defaultLanguage && (u = t.defaultLanguage.trim());
|
|
6804
|
+
} catch {}
|
|
6805
|
+
}
|
|
6806
|
+
if (!u) {
|
|
6807
|
+
let e = [];
|
|
6808
|
+
if (n.channels && Array.isArray(n.channels) ? e = n.channels : n.channelId && n.channelId !== "all" && (e = [n.channelId]), e.length > 0) {
|
|
6809
|
+
let n = Number(e[0]);
|
|
6810
|
+
if (!isNaN(n)) {
|
|
6811
|
+
let e = await t.prepare("SELECT defaultLanguage FROM channels WHERE id = ?").get(n);
|
|
6812
|
+
e?.defaultLanguage && (u = e.defaultLanguage.trim());
|
|
6813
|
+
}
|
|
6814
|
+
}
|
|
6815
|
+
}
|
|
6816
|
+
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);
|
|
6817
|
+
await t.prepare("DELETE FROM tree_nodes WHERE treeId = ? AND contentId = ?").run(o, p);
|
|
6818
|
+
let v = g === null ? "parentId IS NULL" : "parentId = ?", y = g === null ? [o] : [o, g], b = (await t.prepare(`
|
|
6771
6819
|
SELECT COALESCE(MAX(sortOrder), -1) + 1 as nextSort
|
|
6772
6820
|
FROM tree_nodes
|
|
6773
|
-
WHERE treeId = ? AND ${
|
|
6774
|
-
`).get(...
|
|
6775
|
-
n.channels && Array.isArray(n.channels) ?
|
|
6776
|
-
let
|
|
6777
|
-
if (
|
|
6778
|
-
let e =
|
|
6821
|
+
WHERE treeId = ? AND ${v}
|
|
6822
|
+
`).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 = [];
|
|
6823
|
+
n.channels && Array.isArray(n.channels) ? C = n.channels : n.channelId && n.channelId !== "all" && (C = [n.channelId]);
|
|
6824
|
+
let w = [...new Set(C)].filter((e) => e && e !== "all").map((e) => Number(e));
|
|
6825
|
+
if (w.length > 0) {
|
|
6826
|
+
let e = w.map(() => "(?, ?)").join(", "), n = w.flatMap((e) => [p, e]);
|
|
6779
6827
|
await t.prepare(`INSERT OR IGNORE INTO node_channels (nodeId, channelId) VALUES ${e}`).run(...n);
|
|
6780
6828
|
}
|
|
6781
6829
|
return await i.clear(), a.purgeGlobalCache(e, t), e.json({
|
|
6782
6830
|
success: !0,
|
|
6783
|
-
id:
|
|
6784
|
-
treeNodeId:
|
|
6831
|
+
id: p,
|
|
6832
|
+
treeNodeId: S,
|
|
6785
6833
|
status: "draft"
|
|
6786
6834
|
}, 201);
|
|
6787
6835
|
}
|
|
@@ -6832,7 +6880,7 @@ G.get("/tree.json", async (e) => {
|
|
|
6832
6880
|
details: t.message
|
|
6833
6881
|
}, 500);
|
|
6834
6882
|
}
|
|
6835
|
-
}),
|
|
6883
|
+
}), W.get("/trees.json", async (e) => {
|
|
6836
6884
|
try {
|
|
6837
6885
|
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
6886
|
let n = Number(t.treeId), r = Number(t.channelId);
|
|
@@ -6862,7 +6910,7 @@ G.get("/tree.json", async (e) => {
|
|
|
6862
6910
|
} catch {
|
|
6863
6911
|
return e.json([]);
|
|
6864
6912
|
}
|
|
6865
|
-
}),
|
|
6913
|
+
}), W.post("/trees.json", async (e) => {
|
|
6866
6914
|
try {
|
|
6867
6915
|
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
6916
|
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 +6935,7 @@ G.get("/tree.json", async (e) => {
|
|
|
6887
6935
|
await t.prepare(`INSERT OR IGNORE INTO channel_trees (channelId, treeId, key) VALUES ${n}`).run(...r);
|
|
6888
6936
|
}
|
|
6889
6937
|
}
|
|
6890
|
-
return await I(e).clear(), new
|
|
6938
|
+
return await I(e).clear(), new V(e.env).purgeGlobalCache(e, t), e.json({
|
|
6891
6939
|
success: !0,
|
|
6892
6940
|
id: p,
|
|
6893
6941
|
key: o,
|
|
@@ -6901,12 +6949,12 @@ G.get("/tree.json", async (e) => {
|
|
|
6901
6949
|
} catch (t) {
|
|
6902
6950
|
return console.error("[API Trees] Error saving tree:", t), e.json({ error: t.message || "Failed to save tree" }, 500);
|
|
6903
6951
|
}
|
|
6904
|
-
}),
|
|
6952
|
+
}), W.delete("/trees.json", async (e) => {
|
|
6905
6953
|
let t = e.get("db"), n = e.req.query("id");
|
|
6906
6954
|
if (!n) return e.json({ error: "Tree ID required" }, 400);
|
|
6907
6955
|
let r = Number(n);
|
|
6908
6956
|
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
|
|
6957
|
+
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
6958
|
success: !0,
|
|
6911
6959
|
deletedTreeId: r
|
|
6912
6960
|
});
|
|
@@ -6916,8 +6964,8 @@ G.get("/tree.json", async (e) => {
|
|
|
6916
6964
|
});
|
|
6917
6965
|
//#endregion
|
|
6918
6966
|
//#region server/routes/admin/channels.ts
|
|
6919
|
-
var
|
|
6920
|
-
|
|
6967
|
+
var ye = new e();
|
|
6968
|
+
ye.get("/", async (e) => {
|
|
6921
6969
|
try {
|
|
6922
6970
|
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
6971
|
e[t.channelId] || (e[t.channelId] = []);
|
|
@@ -6941,7 +6989,7 @@ ve.get("/", async (e) => {
|
|
|
6941
6989
|
isHidden: !!e.isHidden,
|
|
6942
6990
|
trees: a[e.id] || []
|
|
6943
6991
|
};
|
|
6944
|
-
}), s = e.env?.BUNDLED_DEFINITIONS, c =
|
|
6992
|
+
}), s = e.env?.BUNDLED_DEFINITIONS, c = se(s), l = c?.channelTemplate || Object.values(c?.channels || {})[0] || {
|
|
6945
6993
|
label: "Channel Settings",
|
|
6946
6994
|
fields: {
|
|
6947
6995
|
key: {
|
|
@@ -6973,7 +7021,7 @@ ve.get("/", async (e) => {
|
|
|
6973
7021
|
}
|
|
6974
7022
|
};
|
|
6975
7023
|
return e.json({
|
|
6976
|
-
schema:
|
|
7024
|
+
schema: l,
|
|
6977
7025
|
channels: o
|
|
6978
7026
|
});
|
|
6979
7027
|
} catch (t) {
|
|
@@ -6983,24 +7031,26 @@ ve.get("/", async (e) => {
|
|
|
6983
7031
|
error: t.message
|
|
6984
7032
|
}, 500);
|
|
6985
7033
|
}
|
|
6986
|
-
}),
|
|
7034
|
+
}), ye.post("/", async (e) => {
|
|
6987
7035
|
try {
|
|
6988
|
-
let t = e.get("db"), n = await e.req.json(), r = n.
|
|
6989
|
-
|
|
6990
|
-
|
|
7036
|
+
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 || "";
|
|
7037
|
+
typeof T == "object" && T && (T = T.value || T.id || ""), T = String(T).trim();
|
|
7038
|
+
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;
|
|
7039
|
+
if (await t.prepare("SELECT id FROM channels WHERE key = ? AND id != ? LIMIT 1").get(C, a ?? -1)) return e.json({
|
|
7040
|
+
error: `Channel API key "${C}" is already in use.`,
|
|
6991
7041
|
field: "key"
|
|
6992
7042
|
}, 409);
|
|
6993
|
-
let
|
|
6994
|
-
if (
|
|
7043
|
+
let A = a;
|
|
7044
|
+
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
7045
|
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
|
-
|
|
7046
|
+
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);
|
|
7047
|
+
A = Number(e.lastInsertRowid);
|
|
6998
7048
|
}
|
|
6999
|
-
await t.prepare("DELETE FROM channel_trees WHERE channelId = ?").run(
|
|
7000
|
-
let
|
|
7001
|
-
if (
|
|
7002
|
-
let e =
|
|
7003
|
-
|
|
7049
|
+
await t.prepare("DELETE FROM channel_trees WHERE channelId = ?").run(A);
|
|
7050
|
+
let j = D.filter((e) => e && e.treeId && e.key);
|
|
7051
|
+
if (j.length > 0) {
|
|
7052
|
+
let e = j.map(() => "(?, ?, ?, ?)").join(", "), n = j.flatMap((e) => [
|
|
7053
|
+
A,
|
|
7004
7054
|
Number(e.treeId) || e.treeId,
|
|
7005
7055
|
String(e.key).trim(),
|
|
7006
7056
|
JSON.stringify(e.meta || {})
|
|
@@ -7010,9 +7060,10 @@ ve.get("/", async (e) => {
|
|
|
7010
7060
|
VALUES ${e}
|
|
7011
7061
|
`).run(...n);
|
|
7012
7062
|
}
|
|
7013
|
-
|
|
7063
|
+
let M = I(e);
|
|
7064
|
+
return await M.delete(`channel:${C}`), await M.delete(`channel:${A}`), await M.clear(), new V(e.env).purgeGlobalCache(e, t), e.json({
|
|
7014
7065
|
success: !0,
|
|
7015
|
-
id:
|
|
7066
|
+
id: A
|
|
7016
7067
|
});
|
|
7017
7068
|
} catch (t) {
|
|
7018
7069
|
return console.error("[API Channels] Error saving channel:", t), e.json({
|
|
@@ -7020,12 +7071,14 @@ ve.get("/", async (e) => {
|
|
|
7020
7071
|
details: t.message
|
|
7021
7072
|
}, 500);
|
|
7022
7073
|
}
|
|
7023
|
-
}),
|
|
7074
|
+
}), ye.delete("/", async (e) => {
|
|
7024
7075
|
let t = e.get("db"), n = e.req.query("id");
|
|
7025
7076
|
if (!n) return e.json({ error: "Channel ID required" }, 400);
|
|
7026
7077
|
let r = Number(n);
|
|
7027
7078
|
try {
|
|
7028
|
-
|
|
7079
|
+
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);
|
|
7080
|
+
let n = I(e);
|
|
7081
|
+
return await n.delete(`channel:${r}`), await n.clear(), new V(e.env).purgeGlobalCache(e, t), e.json({
|
|
7029
7082
|
success: !0,
|
|
7030
7083
|
deletedSiteId: r
|
|
7031
7084
|
});
|
|
@@ -7043,11 +7096,11 @@ if (typeof process < "u" && process?.versions?.node) try {
|
|
|
7043
7096
|
let e = i(import.meta.url);
|
|
7044
7097
|
K = e("node:fs"), q = e("node:path");
|
|
7045
7098
|
} catch {}
|
|
7046
|
-
function
|
|
7099
|
+
function be(e, t = "") {
|
|
7047
7100
|
let n = e.split(/[\\/]/).pop() || "";
|
|
7048
7101
|
return t && n.endsWith(t) ? n.slice(0, -t.length) : n;
|
|
7049
7102
|
}
|
|
7050
|
-
function
|
|
7103
|
+
function xe(e) {
|
|
7051
7104
|
let t = e.match(/\.[^.\\/]+$/);
|
|
7052
7105
|
return t ? t[0] : "";
|
|
7053
7106
|
}
|
|
@@ -7060,7 +7113,7 @@ var J = {
|
|
|
7060
7113
|
nodeLayouts: {},
|
|
7061
7114
|
blockLayouts: {}
|
|
7062
7115
|
};
|
|
7063
|
-
function
|
|
7116
|
+
function Se(e) {
|
|
7064
7117
|
return e ? typeof e == "string" ? e.trim() : Array.isArray(e) ? e.includes("*") ? "*" : e : "*" : "*";
|
|
7065
7118
|
}
|
|
7066
7119
|
function Y(e = {}, t = {}) {
|
|
@@ -7075,47 +7128,47 @@ function Y(e = {}, t = {}) {
|
|
|
7075
7128
|
};
|
|
7076
7129
|
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
7130
|
}
|
|
7078
|
-
function
|
|
7131
|
+
function Ce(e) {
|
|
7079
7132
|
if (!e || typeof e != "object") return e;
|
|
7080
|
-
if (Array.isArray(e)) return e.map(
|
|
7133
|
+
if (Array.isArray(e)) return e.map(Ce);
|
|
7081
7134
|
let t = {};
|
|
7082
7135
|
for (let [n, r] of Object.entries(e)) if (n === "<<" || n === "<<:") {
|
|
7083
|
-
let e =
|
|
7136
|
+
let e = Ce(r);
|
|
7084
7137
|
if (typeof e == "object" && e) {
|
|
7085
7138
|
if (Array.isArray(e)) for (let n of e) Object.assign(t, n);
|
|
7086
7139
|
else Object.assign(t, e);
|
|
7087
7140
|
}
|
|
7088
|
-
} else t[n] =
|
|
7141
|
+
} else t[n] = Ce(r);
|
|
7089
7142
|
return t;
|
|
7090
7143
|
}
|
|
7091
|
-
function
|
|
7092
|
-
return e ?
|
|
7144
|
+
function we(e, t) {
|
|
7145
|
+
return e ? Ce(n.parseDocument(e, { customTags: [{
|
|
7093
7146
|
tag: "!include",
|
|
7094
7147
|
resolve(e) {
|
|
7095
|
-
let n = (typeof e == "string" ? e : String(e?.strValue || e?.value || "")).trim(), r =
|
|
7148
|
+
let n = (typeof e == "string" ? e : String(e?.strValue || e?.value || "")).trim(), r = be(n);
|
|
7096
7149
|
if (!r) return n;
|
|
7097
7150
|
if (t && t.fieldSets) {
|
|
7098
7151
|
let e = Object.keys(t.fieldSets).find((e) => e.endsWith("/" + r) || e === r);
|
|
7099
|
-
if (e) return
|
|
7152
|
+
if (e) return we(t.fieldSets[e], t);
|
|
7100
7153
|
}
|
|
7101
7154
|
return n;
|
|
7102
7155
|
}
|
|
7103
7156
|
}] }).toJS() || {}) : {};
|
|
7104
7157
|
}
|
|
7105
|
-
function
|
|
7158
|
+
function Te(e, t = /* @__PURE__ */ new Set()) {
|
|
7106
7159
|
if (!K || !q) return {};
|
|
7107
7160
|
let r = q.resolve(e);
|
|
7108
7161
|
if (t.has(r) || (t.add(r), !K.existsSync(r))) return {};
|
|
7109
7162
|
let i = K.readFileSync(r, "utf-8");
|
|
7110
|
-
return
|
|
7163
|
+
return Ce(n.parseDocument(i, { customTags: [{
|
|
7111
7164
|
tag: "!include",
|
|
7112
7165
|
resolve(e) {
|
|
7113
7166
|
let n = (typeof e == "string" ? e : String(e?.strValue || e?.value || "")).trim();
|
|
7114
|
-
return n ?
|
|
7167
|
+
return n ? Te(q.resolve(q.dirname(r), n), new Set(t)) : {};
|
|
7115
7168
|
}
|
|
7116
7169
|
}] }).toJS() || {});
|
|
7117
7170
|
}
|
|
7118
|
-
function
|
|
7171
|
+
function Ee() {
|
|
7119
7172
|
if (!K || !q || typeof process > "u" || !process?.versions?.node) return null;
|
|
7120
7173
|
try {
|
|
7121
7174
|
let e = process.cwd(), t = "", n = [
|
|
@@ -7148,9 +7201,9 @@ function Te() {
|
|
|
7148
7201
|
let r = {}, i = K.readdirSync(n);
|
|
7149
7202
|
for (let e of i) {
|
|
7150
7203
|
if (!e.endsWith(".yaml") && !e.endsWith(".yml")) continue;
|
|
7151
|
-
let t = q.join(n, e), i =
|
|
7204
|
+
let t = q.join(n, e), i = be(e, xe(e));
|
|
7152
7205
|
try {
|
|
7153
|
-
r[i] =
|
|
7206
|
+
r[i] = Te(t);
|
|
7154
7207
|
} catch (t) {
|
|
7155
7208
|
console.error(`❌ Error parsing ${e}:`, t.message);
|
|
7156
7209
|
}
|
|
@@ -7178,14 +7231,14 @@ function Te() {
|
|
|
7178
7231
|
return console.error("❌ Exception inside readLocalFsBundle:", e), null;
|
|
7179
7232
|
}
|
|
7180
7233
|
}
|
|
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
|
-
}
|
|
7234
|
+
var De = null, Oe = null;
|
|
7188
7235
|
function ke(e) {
|
|
7236
|
+
if (!e) De = null, Oe = null;
|
|
7237
|
+
else if (De && Oe === e) return De;
|
|
7238
|
+
let t = Ae(e);
|
|
7239
|
+
return De = t, Oe = e, t;
|
|
7240
|
+
}
|
|
7241
|
+
function Ae(e) {
|
|
7189
7242
|
if (e) {
|
|
7190
7243
|
let t = {
|
|
7191
7244
|
nodes: {
|
|
@@ -7221,12 +7274,12 @@ function ke(e) {
|
|
|
7221
7274
|
let e = (e) => {
|
|
7222
7275
|
let n = {};
|
|
7223
7276
|
for (let [r, i] of Object.entries(e || {})) {
|
|
7224
|
-
let e =
|
|
7225
|
-
n[e] =
|
|
7277
|
+
let e = be(r, xe(r));
|
|
7278
|
+
n[e] = we(i, t);
|
|
7226
7279
|
}
|
|
7227
7280
|
return n;
|
|
7228
7281
|
};
|
|
7229
|
-
return
|
|
7282
|
+
return je({
|
|
7230
7283
|
rawNodes: e(t.nodes),
|
|
7231
7284
|
rawTrees: e(t.trees),
|
|
7232
7285
|
rawChannels: e(t.channels),
|
|
@@ -7236,12 +7289,12 @@ function ke(e) {
|
|
|
7236
7289
|
rawFieldSets: e(t.fieldSets)
|
|
7237
7290
|
});
|
|
7238
7291
|
}
|
|
7239
|
-
return
|
|
7292
|
+
return je(t);
|
|
7240
7293
|
}
|
|
7241
|
-
let t =
|
|
7242
|
-
return t && Object.keys(t.rawNodes || {}).length > 0 ?
|
|
7294
|
+
let t = Ee();
|
|
7295
|
+
return t && Object.keys(t.rawNodes || {}).length > 0 ? je(t) : je(null);
|
|
7243
7296
|
}
|
|
7244
|
-
function
|
|
7297
|
+
function je(e) {
|
|
7245
7298
|
if (!e) return {
|
|
7246
7299
|
nodes: {},
|
|
7247
7300
|
trees: {},
|
|
@@ -7376,8 +7429,8 @@ function Ae(e) {
|
|
|
7376
7429
|
inVault: t.inVault !== !1,
|
|
7377
7430
|
hasCanvas: t.hasCanvas === !0,
|
|
7378
7431
|
defaultLayout: t.defaultLayout,
|
|
7379
|
-
allowedBlocks:
|
|
7380
|
-
disallowedBlocks: t.disallowedBlocks ?
|
|
7432
|
+
allowedBlocks: Se(t.allowedBlocks),
|
|
7433
|
+
disallowedBlocks: t.disallowedBlocks ? Se(t.disallowedBlocks) : void 0,
|
|
7381
7434
|
tabs: n,
|
|
7382
7435
|
fields: r
|
|
7383
7436
|
};
|
|
@@ -7439,17 +7492,17 @@ function Ae(e) {
|
|
|
7439
7492
|
fields: n
|
|
7440
7493
|
};
|
|
7441
7494
|
});
|
|
7442
|
-
let
|
|
7495
|
+
let P = {};
|
|
7443
7496
|
Object.entries(T).forEach(([e, t]) => {
|
|
7444
7497
|
let n = A(t.tabs), r = k(t.fields || [], "settings", n), i = {}, a = t.regions || { content: { label: "Content" } };
|
|
7445
7498
|
Object.entries(a).forEach(([e, t]) => {
|
|
7446
7499
|
i[e] = {
|
|
7447
7500
|
...t,
|
|
7448
7501
|
label: t.label || e,
|
|
7449
|
-
allowedBlocks:
|
|
7450
|
-
disallowedBlocks: t.disallowedBlocks ?
|
|
7502
|
+
allowedBlocks: Se(t.allowedBlocks),
|
|
7503
|
+
disallowedBlocks: t.disallowedBlocks ? Se(t.disallowedBlocks) : void 0
|
|
7451
7504
|
};
|
|
7452
|
-
}),
|
|
7505
|
+
}), P[e] = {
|
|
7453
7506
|
...t,
|
|
7454
7507
|
id: t.id || e,
|
|
7455
7508
|
label: t.label || e,
|
|
@@ -7462,17 +7515,17 @@ function Ae(e) {
|
|
|
7462
7515
|
tabs: n
|
|
7463
7516
|
};
|
|
7464
7517
|
});
|
|
7465
|
-
let
|
|
7518
|
+
let te = {};
|
|
7466
7519
|
Object.entries(E).forEach(([e, t]) => {
|
|
7467
7520
|
let n = A(t.tabs), r = k(t.fields || [], "settings", n), i = {}, a = t.regions || { main: { label: "Main Content" } };
|
|
7468
7521
|
Object.entries(a).forEach(([e, t]) => {
|
|
7469
7522
|
i[e] = {
|
|
7470
7523
|
...t,
|
|
7471
7524
|
label: t.label || e,
|
|
7472
|
-
allowedBlocks:
|
|
7473
|
-
disallowedBlocks: t.disallowedBlocks ?
|
|
7525
|
+
allowedBlocks: Se(t.allowedBlocks),
|
|
7526
|
+
disallowedBlocks: t.disallowedBlocks ? Se(t.disallowedBlocks) : void 0
|
|
7474
7527
|
};
|
|
7475
|
-
}),
|
|
7528
|
+
}), te[e] = {
|
|
7476
7529
|
...t,
|
|
7477
7530
|
id: t.id || e,
|
|
7478
7531
|
label: t.label || e,
|
|
@@ -7502,7 +7555,7 @@ function Ae(e) {
|
|
|
7502
7555
|
L[e] = Y(L[e] || {}, t);
|
|
7503
7556
|
});
|
|
7504
7557
|
});
|
|
7505
|
-
let
|
|
7558
|
+
let ne = h ? {
|
|
7506
7559
|
...h,
|
|
7507
7560
|
fields: L
|
|
7508
7561
|
} : null;
|
|
@@ -7511,22 +7564,22 @@ function Ae(e) {
|
|
|
7511
7564
|
trees: M,
|
|
7512
7565
|
channels: N,
|
|
7513
7566
|
blocks: ee,
|
|
7514
|
-
nodeLayouts:
|
|
7515
|
-
blockLayouts:
|
|
7567
|
+
nodeLayouts: P,
|
|
7568
|
+
blockLayouts: te,
|
|
7516
7569
|
fieldSets: O,
|
|
7517
7570
|
nodeTemplate: f || null,
|
|
7518
7571
|
treeTemplate: p || null,
|
|
7519
7572
|
channelTemplate: I,
|
|
7520
|
-
userTemplate:
|
|
7573
|
+
userTemplate: ne
|
|
7521
7574
|
};
|
|
7522
7575
|
}
|
|
7523
7576
|
//#endregion
|
|
7524
7577
|
//#region server/routes/admin/schemas.ts
|
|
7525
|
-
var
|
|
7578
|
+
var Me = new e(), Ne = (e) => {
|
|
7526
7579
|
try {
|
|
7527
7580
|
let t = e.env?.BUNDLED_DEFINITIONS;
|
|
7528
7581
|
(!t || Object.keys(t).length === 0) && (t = f || d || u);
|
|
7529
|
-
let n =
|
|
7582
|
+
let n = ke(t);
|
|
7530
7583
|
return e.json(n, 200, { "Cache-Control": "no-cache, no-store, must-revalidate" });
|
|
7531
7584
|
} catch (t) {
|
|
7532
7585
|
return console.error("[CMS API] Error loading schemas:", t), e.json({
|
|
@@ -7535,10 +7588,10 @@ var je = new e(), Me = (e) => {
|
|
|
7535
7588
|
}, 500);
|
|
7536
7589
|
}
|
|
7537
7590
|
};
|
|
7538
|
-
|
|
7591
|
+
Me.get("/", Ne), Me.get("/schemas.json", Ne);
|
|
7539
7592
|
//#endregion
|
|
7540
7593
|
//#region server/routes/admin/validation.ts
|
|
7541
|
-
var
|
|
7594
|
+
var Pe = new e(), Fe = {
|
|
7542
7595
|
node: "content_nodes",
|
|
7543
7596
|
nodes: "content_nodes",
|
|
7544
7597
|
content_node: "content_nodes",
|
|
@@ -7550,7 +7603,7 @@ var Ne = new e(), Pe = {
|
|
|
7550
7603
|
user: "users",
|
|
7551
7604
|
users: "users",
|
|
7552
7605
|
user_account: "user_accounts"
|
|
7553
|
-
},
|
|
7606
|
+
}, Ie = {
|
|
7554
7607
|
content_nodes: [
|
|
7555
7608
|
"id",
|
|
7556
7609
|
"title",
|
|
@@ -7607,11 +7660,11 @@ var Ne = new e(), Pe = {
|
|
|
7607
7660
|
"createdAt"
|
|
7608
7661
|
]
|
|
7609
7662
|
};
|
|
7610
|
-
|
|
7663
|
+
Pe.post("/validate-unique", async (e) => {
|
|
7611
7664
|
try {
|
|
7612
7665
|
let t = e.get("db"), { entityType: n, field: r, value: i, excludeId: a } = await e.req.json();
|
|
7613
7666
|
if (!r || i == null || String(i).trim() === "") return e.json({ isUnique: !0 });
|
|
7614
|
-
let o =
|
|
7667
|
+
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
7668
|
if (a != null && String(a).trim() !== "") {
|
|
7616
7669
|
let e = Number(a);
|
|
7617
7670
|
l = isNaN(e) ? String(a) : e;
|
|
@@ -7623,11 +7676,11 @@ Ne.post("/validate-unique", async (e) => {
|
|
|
7623
7676
|
} catch (t) {
|
|
7624
7677
|
return console.error("[API Validation] Error validating global uniqueness:", t), e.json({ error: "Failed to validate uniqueness" }, 500);
|
|
7625
7678
|
}
|
|
7626
|
-
}),
|
|
7679
|
+
}), Pe.post("/validate-unique-sibling", async (e) => e.json({ isUnique: !0 }));
|
|
7627
7680
|
//#endregion
|
|
7628
7681
|
//#region server/routes/admin/stats.ts
|
|
7629
|
-
var
|
|
7630
|
-
|
|
7682
|
+
var Le = new e();
|
|
7683
|
+
Le.get("/", async (e) => {
|
|
7631
7684
|
try {
|
|
7632
7685
|
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
7686
|
...e,
|
|
@@ -7644,7 +7697,7 @@ Ie.get("/", async (e) => {
|
|
|
7644
7697
|
isHidden: !!e.isHidden,
|
|
7645
7698
|
channelNames: e.channelLabels ? e.channelLabels.split(",") : [],
|
|
7646
7699
|
treeNames: e.treeLabels ? e.treeLabels.split(",") : []
|
|
7647
|
-
})), p = e.env?.BUNDLED_DEFINITIONS, m =
|
|
7700
|
+
})), p = e.env?.BUNDLED_DEFINITIONS, m = se(p), h = m.nodes || m.nodeSchemas || {}, g = c.map((e) => {
|
|
7648
7701
|
let t = e.type || "node", n = h[t]?.label || t.charAt(0).toUpperCase() + t.slice(1);
|
|
7649
7702
|
return {
|
|
7650
7703
|
type: t,
|
|
@@ -7690,7 +7743,7 @@ async function Q(e, t, n = []) {
|
|
|
7690
7743
|
if (typeof r.bind == "function") return await r.bind(...n).run();
|
|
7691
7744
|
if (typeof r.run == "function") return await r.run(...n);
|
|
7692
7745
|
}
|
|
7693
|
-
function
|
|
7746
|
+
function Re(e, t, n) {
|
|
7694
7747
|
let r = e || (t ? `/media/${t}` : "");
|
|
7695
7748
|
return r && n && r.startsWith(`https://${n}/`) && !r.includes("/media/") && (r = r.replace(`https://${n}/`, `https://${n}/media/`)), r;
|
|
7696
7749
|
}
|
|
@@ -7732,7 +7785,7 @@ X.get("/", async (e) => {
|
|
|
7732
7785
|
...JSON.parse(t.dataJson || "{}")
|
|
7733
7786
|
};
|
|
7734
7787
|
} catch {}
|
|
7735
|
-
let r =
|
|
7788
|
+
let r = Re(t.cdnUrl, t.storageKeyPrivate, e.env?.CDN_DOMAIN);
|
|
7736
7789
|
return {
|
|
7737
7790
|
id: t.id,
|
|
7738
7791
|
filename: t.filename || "Untitled Asset",
|
|
@@ -7758,7 +7811,7 @@ X.get("/", async (e) => {
|
|
|
7758
7811
|
}
|
|
7759
7812
|
}), X.post("/upload", async (e) => {
|
|
7760
7813
|
try {
|
|
7761
|
-
let t = l(e), { storage: n } =
|
|
7814
|
+
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
7815
|
s && (await Z(t, "SELECT id FROM assets WHERE id = ?", [s])).length === 0 && (s = null);
|
|
7763
7816
|
let c = r.cropCoordinates, u = null, d = null;
|
|
7764
7817
|
if (c) {
|
|
@@ -7790,7 +7843,7 @@ X.get("/", async (e) => {
|
|
|
7790
7843
|
let D = x;
|
|
7791
7844
|
if (s) {
|
|
7792
7845
|
let n = await Z(t, "SELECT cdnUrl, storageKeyPrivate FROM assets WHERE id = ?", [s]);
|
|
7793
|
-
n.length > 0 && (D =
|
|
7846
|
+
n.length > 0 && (D = Re(n[0].cdnUrl, n[0].storageKeyPrivate, y)), new V(e.env).purgeAsset(e, t, s);
|
|
7794
7847
|
}
|
|
7795
7848
|
return e.json({
|
|
7796
7849
|
id: p,
|
|
@@ -7832,7 +7885,7 @@ X.get("/", async (e) => {
|
|
|
7832
7885
|
...JSON.parse(i.dataJson || "{}")
|
|
7833
7886
|
};
|
|
7834
7887
|
} catch {}
|
|
7835
|
-
let u =
|
|
7888
|
+
let u = Re(i.cdnUrl, i.storageKeyPrivate, e.env?.CDN_DOMAIN);
|
|
7836
7889
|
return e.json({
|
|
7837
7890
|
id: i.id,
|
|
7838
7891
|
filename: i.filename,
|
|
@@ -7859,7 +7912,7 @@ X.get("/", async (e) => {
|
|
|
7859
7912
|
createdAt: t.createdAt,
|
|
7860
7913
|
parentAssetId: t.parentAssetId || i.id,
|
|
7861
7914
|
cropCoordinates: n,
|
|
7862
|
-
url:
|
|
7915
|
+
url: Re(t.cdnUrl, t.storageKeyPrivate, e.env?.CDN_DOMAIN),
|
|
7863
7916
|
originalUrl: u
|
|
7864
7917
|
};
|
|
7865
7918
|
})
|
|
@@ -7879,14 +7932,14 @@ X.get("/", async (e) => {
|
|
|
7879
7932
|
r.filename === void 0 ? a.filename : r.filename,
|
|
7880
7933
|
JSON.stringify(o),
|
|
7881
7934
|
n
|
|
7882
|
-
]), new
|
|
7935
|
+
]), new V(e.env).purgeAsset(e, t, n), e.json({ success: !0 });
|
|
7883
7936
|
} catch {
|
|
7884
7937
|
return e.json({ error: "Failed to update asset" }, 500);
|
|
7885
7938
|
}
|
|
7886
7939
|
}), X.delete("/:id", async (e) => {
|
|
7887
7940
|
try {
|
|
7888
7941
|
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
|
|
7942
|
+
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
7943
|
n,
|
|
7891
7944
|
n,
|
|
7892
7945
|
`crop_%${r.filename ? r.filename.replace(/\.[^/.]+$/, "") : ""}%`,
|
|
@@ -7912,7 +7965,7 @@ X.get("/", async (e) => {
|
|
|
7912
7965
|
r,
|
|
7913
7966
|
`crop_%${i.filename ? i.filename.replace(/\.[^/.]+$/, "") : ""}%`,
|
|
7914
7967
|
`%${r}%`
|
|
7915
|
-
]), new
|
|
7968
|
+
]), new V(e.env).purgeAsset(e, t, r), e.json({
|
|
7916
7969
|
success: !0,
|
|
7917
7970
|
id: r,
|
|
7918
7971
|
restored: !0
|
|
@@ -7925,9 +7978,9 @@ X.get("/", async (e) => {
|
|
|
7925
7978
|
}
|
|
7926
7979
|
}), X.delete("/purge/:id", async (e) => {
|
|
7927
7980
|
try {
|
|
7928
|
-
let t = l(e), { storage: n } =
|
|
7981
|
+
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
7982
|
if (!i) return e.json({ error: "Asset not found" }, 404);
|
|
7930
|
-
new
|
|
7983
|
+
new V(e.env).purgeAsset(e, t, r);
|
|
7931
7984
|
let a = [i];
|
|
7932
7985
|
i.isSystemVariant || (a = [i, ...await Z(t, "SELECT id, storageKeyPrivate FROM assets WHERE parentAssetId = ? OR (isSystemVariant = 1 AND (filename LIKE ? OR filename LIKE ?))", [
|
|
7933
7986
|
r,
|
|
@@ -7959,8 +8012,8 @@ X.get("/", async (e) => {
|
|
|
7959
8012
|
});
|
|
7960
8013
|
//#endregion
|
|
7961
8014
|
//#region server/routes/public/node.ts
|
|
7962
|
-
var
|
|
7963
|
-
function
|
|
8015
|
+
var ze = new e();
|
|
8016
|
+
function Be() {
|
|
7964
8017
|
return {
|
|
7965
8018
|
fullPath: /* @__PURE__ */ new Map(),
|
|
7966
8019
|
treeEdges: /* @__PURE__ */ new Map(),
|
|
@@ -7968,10 +8021,10 @@ function ze() {
|
|
|
7968
8021
|
assetUrls: /* @__PURE__ */ new Map()
|
|
7969
8022
|
};
|
|
7970
8023
|
}
|
|
7971
|
-
function
|
|
8024
|
+
function Ve(...e) {
|
|
7972
8025
|
return e.map((e) => String(e ?? "")).join(":");
|
|
7973
8026
|
}
|
|
7974
|
-
function
|
|
8027
|
+
function He(e, t) {
|
|
7975
8028
|
let n = Date.now();
|
|
7976
8029
|
if (e && String(e).trim() !== "") {
|
|
7977
8030
|
let t = Date.parse(e);
|
|
@@ -7983,27 +8036,27 @@ function Ve(e, t) {
|
|
|
7983
8036
|
}
|
|
7984
8037
|
return !0;
|
|
7985
8038
|
}
|
|
7986
|
-
async function
|
|
7987
|
-
let
|
|
7988
|
-
await Promise.all(
|
|
7989
|
-
let
|
|
7990
|
-
n && n !== "all" && (
|
|
7991
|
-
let
|
|
7992
|
-
|
|
7993
|
-
let
|
|
7994
|
-
|
|
8039
|
+
async function Ue(e, t, n, r) {
|
|
8040
|
+
let i = t.filter((e) => e.componentId === "content-feed" || e.componentId === "article-list");
|
|
8041
|
+
await Promise.all(i.map(async (t) => {
|
|
8042
|
+
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];
|
|
8043
|
+
n && n !== "all" && (c += " AND id IN (SELECT nodeId FROM node_channels WHERE channelId = ?)", l.push(Number(n) || n));
|
|
8044
|
+
let u = "ORDER BY updatedAt DESC";
|
|
8045
|
+
s === "published_desc" || s === "createdAt" ? u = "ORDER BY createdAt DESC" : s === "title_asc" && (u = "ORDER BY LOWER(title) ASC");
|
|
8046
|
+
let d = `SELECT id, title, slug, language, dataJson, createdAt, updatedAt ${c} ${u} LIMIT ?`;
|
|
8047
|
+
l.push(o);
|
|
7995
8048
|
try {
|
|
7996
|
-
let n = await e.prepare(
|
|
7997
|
-
t.data.initialItems =
|
|
8049
|
+
let n = await e.prepare(d).all(...l), i = Array.isArray(n) ? n : n?.results || [];
|
|
8050
|
+
t.data.initialItems = i.map((e) => {
|
|
7998
8051
|
let t = {};
|
|
7999
8052
|
if (e.dataJson) try {
|
|
8000
8053
|
t = typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson;
|
|
8001
8054
|
} catch {}
|
|
8002
|
-
return
|
|
8055
|
+
return He(t.startShowingAt, t.stopShowingAt) ? {
|
|
8003
8056
|
id: e.id,
|
|
8004
8057
|
title: e.title,
|
|
8005
8058
|
slug: e.slug,
|
|
8006
|
-
language: e.language ||
|
|
8059
|
+
language: e.language?.trim() || r || null,
|
|
8007
8060
|
createdAt: e.createdAt,
|
|
8008
8061
|
updatedAt: e.updatedAt,
|
|
8009
8062
|
excerpt: t.excerpt || "",
|
|
@@ -8016,7 +8069,7 @@ async function He(e, t, n) {
|
|
|
8016
8069
|
}
|
|
8017
8070
|
}));
|
|
8018
8071
|
}
|
|
8019
|
-
async function
|
|
8072
|
+
async function We(e, t, n, r, i = !1, a) {
|
|
8020
8073
|
if (!t) return { blocks: [] };
|
|
8021
8074
|
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
8075
|
if (!s || s.length === 0) return { blocks: [] };
|
|
@@ -8052,10 +8105,10 @@ async function Ue(e, t, n, r, i = !1, a) {
|
|
|
8052
8105
|
try {
|
|
8053
8106
|
a = (typeof t.dataJson == "string" ? JSON.parse(t.dataJson) : t.dataJson) || {};
|
|
8054
8107
|
} catch {}
|
|
8055
|
-
let o = a.hidden === !0 || a.hidden === 1 || a.hidden === "1" || a.hidden === "true", s =
|
|
8108
|
+
let o = a.hidden === !0 || a.hidden === 1 || a.hidden === "1" || a.hidden === "true", s = He(a.startShowingAt, a.stopShowingAt);
|
|
8056
8109
|
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
|
|
8110
|
+
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);
|
|
8111
|
+
return d = await B(e, d), d = Ke(d), d.blockId = u, {
|
|
8059
8112
|
region: t.region || n,
|
|
8060
8113
|
block: {
|
|
8061
8114
|
instanceId: t.id,
|
|
@@ -8075,7 +8128,7 @@ async function Ue(e, t, n, r, i = !1, a) {
|
|
|
8075
8128
|
}
|
|
8076
8129
|
return { blocks: [] };
|
|
8077
8130
|
}
|
|
8078
|
-
function
|
|
8131
|
+
function Ge(e, t = {}) {
|
|
8079
8132
|
let n = {};
|
|
8080
8133
|
for (let [r, i] of Object.entries(e)) r.endsWith("_meta") || [
|
|
8081
8134
|
"disabledRegions",
|
|
@@ -8091,14 +8144,14 @@ function We(e, t = {}) {
|
|
|
8091
8144
|
].includes(r) || r.startsWith("_") || (!t[r] || t[r].public !== !1) && (n[r] = i);
|
|
8092
8145
|
return n;
|
|
8093
8146
|
}
|
|
8094
|
-
function
|
|
8095
|
-
if (Array.isArray(e)) return e.map(
|
|
8147
|
+
function Ke(e) {
|
|
8148
|
+
if (Array.isArray(e)) return e.map(Ke);
|
|
8096
8149
|
if (!e || typeof e != "object") return e;
|
|
8097
8150
|
if (typeof e.id == "string" && e.id.startsWith("ast_") && typeof e.url == "string") {
|
|
8098
8151
|
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
8152
|
...t,
|
|
8100
8153
|
...t.crops?.[r] || {}
|
|
8101
|
-
} : t, a = Object.fromEntries(Object.entries(n).filter(([, t]) => t?.id !== e.id).map(([t, n]) => [t,
|
|
8154
|
+
} : t, a = Object.fromEntries(Object.entries(n).filter(([, t]) => t?.id !== e.id).map(([t, n]) => [t, Ke({
|
|
8102
8155
|
...n,
|
|
8103
8156
|
title: n?.title ?? e.title ?? "",
|
|
8104
8157
|
alt: n?.alt ?? e.alt ?? "",
|
|
@@ -8112,9 +8165,9 @@ function Ge(e) {
|
|
|
8112
8165
|
...Object.keys(a).length > 0 ? { variants: a } : {}
|
|
8113
8166
|
};
|
|
8114
8167
|
}
|
|
8115
|
-
return Object.fromEntries(Object.entries(e).map(([e, t]) => [e,
|
|
8168
|
+
return Object.fromEntries(Object.entries(e).map(([e, t]) => [e, Ke(t)]));
|
|
8116
8169
|
}
|
|
8117
|
-
async function
|
|
8170
|
+
async function qe(e, t, n) {
|
|
8118
8171
|
if (typeof t == "string") {
|
|
8119
8172
|
if (!t.includes("#node:") && !t.includes("data-node-id") && !t.includes("#asset:") && !t.includes("data-asset-id")) return t;
|
|
8120
8173
|
let r = (e, t) => {
|
|
@@ -8132,9 +8185,9 @@ async function Ke(e, t, n) {
|
|
|
8132
8185
|
return await Promise.all(Array.from(t.matchAll(p)).map(async (t) => {
|
|
8133
8186
|
let i = t[1], a = r(i, "data-node-id"), o = r(i, "data-tree-id");
|
|
8134
8187
|
if (!a || !o) return;
|
|
8135
|
-
let s = await
|
|
8188
|
+
let s = await Ye(e, a, o, n);
|
|
8136
8189
|
if (s?.treeNodeId) {
|
|
8137
|
-
let t = await
|
|
8190
|
+
let t = await $e(e, String(s.treeNodeId), o, n);
|
|
8138
8191
|
f.set(`${a}:${o}`, t);
|
|
8139
8192
|
}
|
|
8140
8193
|
})), t.replace(p, (e, t) => {
|
|
@@ -8154,39 +8207,39 @@ async function Ke(e, t, n) {
|
|
|
8154
8207
|
return /href\s*=\s*["'][^"']*["']/i.test(h) ? h = h.replace(/href\s*=\s*["'][^"']*["']/i, `href="${m || "/"}"`) : h += ` href="${m || "/"}"`, `<a ${h}>`;
|
|
8155
8208
|
});
|
|
8156
8209
|
}
|
|
8157
|
-
if (Array.isArray(t)) return Promise.all(t.map((t) =>
|
|
8210
|
+
if (Array.isArray(t)) return Promise.all(t.map((t) => qe(e, t, n)));
|
|
8158
8211
|
if (t && typeof t == "object") {
|
|
8159
8212
|
if (typeof t.href == "string" && (t.href.startsWith("#node:") || t.href.startsWith("#asset:"))) return {
|
|
8160
8213
|
...t,
|
|
8161
|
-
href: await
|
|
8214
|
+
href: await Je(e, t, n)
|
|
8162
8215
|
};
|
|
8163
|
-
let r = await Promise.all(Object.entries(t).map(async ([t, r]) => [t, await
|
|
8216
|
+
let r = await Promise.all(Object.entries(t).map(async ([t, r]) => [t, await qe(e, r, n)]));
|
|
8164
8217
|
return Object.fromEntries(r);
|
|
8165
8218
|
}
|
|
8166
8219
|
return t;
|
|
8167
8220
|
}
|
|
8168
|
-
async function
|
|
8221
|
+
async function Je(e, t, n) {
|
|
8169
8222
|
let r = t.href.match(/^#node:(.+)$/), i = t.href.match(/^#asset:(.+)$/);
|
|
8170
|
-
if (i) return
|
|
8223
|
+
if (i) return Ze(e, i[1], n);
|
|
8171
8224
|
if (!r) return t.href;
|
|
8172
8225
|
let a = r[1];
|
|
8173
8226
|
if (t.treeId) {
|
|
8174
|
-
let r = await
|
|
8227
|
+
let r = await Ye(e, a, String(t.treeId), n);
|
|
8175
8228
|
if (r?.treeNodeId) {
|
|
8176
|
-
let i = await
|
|
8229
|
+
let i = await $e(e, String(r.treeNodeId), String(t.treeId), n);
|
|
8177
8230
|
if (i) return i;
|
|
8178
8231
|
}
|
|
8179
8232
|
}
|
|
8180
|
-
let o = await
|
|
8233
|
+
let o = await Xe(e, a, n);
|
|
8181
8234
|
return o === void 0 ? "#" : `/${o}`;
|
|
8182
8235
|
}
|
|
8183
|
-
async function
|
|
8184
|
-
let i =
|
|
8236
|
+
async function Ye(e, t, n, r) {
|
|
8237
|
+
let i = Ve(t, n), a = r.treeEdges.get(i);
|
|
8185
8238
|
if (a) return a;
|
|
8186
8239
|
let o = e.prepare("SELECT id as treeNodeId FROM tree_nodes WHERE contentId = ? AND treeId = ? LIMIT 1").get(t, n);
|
|
8187
8240
|
return r.treeEdges.set(i, Promise.resolve(o)), o;
|
|
8188
8241
|
}
|
|
8189
|
-
async function
|
|
8242
|
+
async function Xe(e, t, n) {
|
|
8190
8243
|
let r = String(t), i = n.nodeSlugs.get(r);
|
|
8191
8244
|
if (i) return i;
|
|
8192
8245
|
let a = (async () => {
|
|
@@ -8195,7 +8248,7 @@ async function Ye(e, t, n) {
|
|
|
8195
8248
|
})();
|
|
8196
8249
|
return n.nodeSlugs.set(r, a), a;
|
|
8197
8250
|
}
|
|
8198
|
-
async function
|
|
8251
|
+
async function Ze(e, t, n) {
|
|
8199
8252
|
let r = String(t), i = n.assetUrls.get(r);
|
|
8200
8253
|
if (i) return i;
|
|
8201
8254
|
let a = (async () => {
|
|
@@ -8204,7 +8257,7 @@ async function Xe(e, t, n) {
|
|
|
8204
8257
|
})();
|
|
8205
8258
|
return n.assetUrls.set(r, a), a;
|
|
8206
8259
|
}
|
|
8207
|
-
function
|
|
8260
|
+
function Qe(e) {
|
|
8208
8261
|
let t = e.socialImage;
|
|
8209
8262
|
if (!t || typeof t != "object") return null;
|
|
8210
8263
|
let n = (e, t) => {
|
|
@@ -8235,9 +8288,9 @@ function Ze(e) {
|
|
|
8235
8288
|
])
|
|
8236
8289
|
};
|
|
8237
8290
|
}
|
|
8238
|
-
async function
|
|
8291
|
+
async function $e(e, t, n, r) {
|
|
8239
8292
|
if (!t) return "";
|
|
8240
|
-
let i =
|
|
8293
|
+
let i = Ve(t, n);
|
|
8241
8294
|
if (r) {
|
|
8242
8295
|
let e = r.fullPath.get(i);
|
|
8243
8296
|
if (e) return e;
|
|
@@ -8252,7 +8305,7 @@ async function Qe(e, t, n, r) {
|
|
|
8252
8305
|
})();
|
|
8253
8306
|
return r && r.fullPath.set(i, a), a;
|
|
8254
8307
|
}
|
|
8255
|
-
async function
|
|
8308
|
+
async function et(e, t, n, r, i) {
|
|
8256
8309
|
let a = {}, o = null;
|
|
8257
8310
|
if (t) {
|
|
8258
8311
|
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 +8332,7 @@ async function $e(e, t, n, r, i) {
|
|
|
8279
8332
|
}
|
|
8280
8333
|
}
|
|
8281
8334
|
if (!o) {
|
|
8282
|
-
let t = await e.prepare("SELECT dataJson FROM trees WHERE id = ?").get(n);
|
|
8335
|
+
let t = await e.prepare("SELECT dataJson FROM trees WHERE id = ? OR key = ? LIMIT 1").get(Number(n) || -1, String(n));
|
|
8283
8336
|
if (t?.dataJson) try {
|
|
8284
8337
|
let e = typeof t.dataJson == "string" ? JSON.parse(t.dataJson) : t.dataJson;
|
|
8285
8338
|
e.subpageLayoutId && e.subpageLayoutId !== "inherit" && (o = e.subpageLayoutId);
|
|
@@ -8290,109 +8343,125 @@ async function $e(e, t, n, r, i) {
|
|
|
8290
8343
|
inheritedFields: a
|
|
8291
8344
|
};
|
|
8292
8345
|
}
|
|
8293
|
-
function
|
|
8346
|
+
function tt(e) {
|
|
8294
8347
|
let t = Number(e?.env?.CMS_NODE_CACHE_TTL);
|
|
8295
8348
|
return Number.isFinite(t) && t >= 60 ? Math.floor(t) : 300;
|
|
8296
8349
|
}
|
|
8297
|
-
async function
|
|
8350
|
+
async function nt(e, t, n, r) {
|
|
8298
8351
|
try {
|
|
8299
8352
|
await e.set(t, n, r);
|
|
8300
8353
|
} catch (e) {
|
|
8301
8354
|
console.warn("[CMS Cache] Failed to write node response to cache:", e);
|
|
8302
8355
|
}
|
|
8303
8356
|
}
|
|
8304
|
-
|
|
8357
|
+
ze.get("/*", async (e) => {
|
|
8305
8358
|
try {
|
|
8306
|
-
let t = e.get("db"), n =
|
|
8359
|
+
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
8360
|
if (!c) return e.json({ error: `Channel '${a}' not found` }, 404);
|
|
8308
8361
|
let l = c.status === "disabled" || c.status === "inactive" || c.isEnabled === 0 || c.isEnabled === !1;
|
|
8309
8362
|
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 = `
|
|
8363
|
+
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
8364
|
SELECT cn.*, tn.id as treeNodeId, tn.parentId, tn.treeId FROM content_nodes cn
|
|
8317
8365
|
INNER JOIN tree_nodes tn ON cn.id = tn.contentId
|
|
8318
8366
|
${u === null ? "" : "INNER JOIN node_channels nc ON cn.id = nc.nodeId"}
|
|
8319
8367
|
WHERE cn.slug = ? ${u === null ? "" : "AND nc.channelId = ?"}
|
|
8320
|
-
`,
|
|
8321
|
-
if (
|
|
8322
|
-
let e = await Promise.all(
|
|
8368
|
+
`, S = u === null ? [y] : [y, u], C = await t.prepare(x).all(...S), w = Array.isArray(C) ? C : C?.results || [];
|
|
8369
|
+
if (w.length > 0) {
|
|
8370
|
+
let e = await Promise.all(w.map(async (e) => ({
|
|
8323
8371
|
candidate: e,
|
|
8324
|
-
calculatedPath: await
|
|
8325
|
-
}))), r =
|
|
8372
|
+
calculatedPath: await $e(t, String(e.treeNodeId), String(e.treeId), n)
|
|
8373
|
+
}))), r = b.replace(/^\/+|\/+$/g, "");
|
|
8326
8374
|
for (let { candidate: t, calculatedPath: n } of e) {
|
|
8327
8375
|
let e = n.replace(/^\/+|\/+$/g, "");
|
|
8328
8376
|
if (e === r || r === "home" && (e === "" || e === "home")) {
|
|
8329
|
-
|
|
8377
|
+
h = t, g = t;
|
|
8330
8378
|
break;
|
|
8331
8379
|
}
|
|
8332
8380
|
}
|
|
8333
8381
|
}
|
|
8334
|
-
if (!
|
|
8335
|
-
if (!
|
|
8336
|
-
let e =
|
|
8337
|
-
|
|
8382
|
+
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);
|
|
8383
|
+
if (!g) {
|
|
8384
|
+
let e = _ ? [h.id, _] : [h.id];
|
|
8385
|
+
g = await t.prepare(`SELECT id as treeNodeId, treeId, parentId FROM tree_nodes WHERE contentId = ? ${_ ? "AND treeId = ?" : ""} LIMIT 1`).get(...e);
|
|
8386
|
+
}
|
|
8387
|
+
let T = g?.treeId || _ || "main-nav", E = null;
|
|
8388
|
+
if (T) {
|
|
8389
|
+
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));
|
|
8390
|
+
if (e?.dataJson) try {
|
|
8391
|
+
let t = typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson;
|
|
8392
|
+
t.defaultLanguage ? E = String(t.defaultLanguage).trim() : t.language && (E = String(t.language).trim());
|
|
8393
|
+
} catch {}
|
|
8394
|
+
}
|
|
8395
|
+
let D = null;
|
|
8396
|
+
if (c) {
|
|
8397
|
+
if (c.defaultLanguage) D = String(c.defaultLanguage).trim();
|
|
8398
|
+
else if (c.dataJson) try {
|
|
8399
|
+
let e = typeof c.dataJson == "string" ? JSON.parse(c.dataJson) : c.dataJson;
|
|
8400
|
+
e.defaultLanguage ? D = String(e.defaultLanguage).trim() : e.language && (D = String(e.language).trim());
|
|
8401
|
+
} catch {}
|
|
8402
|
+
}
|
|
8403
|
+
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";
|
|
8404
|
+
if (!s && !M) {
|
|
8405
|
+
let t = await f.get(j);
|
|
8406
|
+
if (t) return e.header("X-Cache", "HIT"), e.json(t);
|
|
8338
8407
|
}
|
|
8339
|
-
let
|
|
8340
|
-
id:
|
|
8341
|
-
title:
|
|
8342
|
-
slug:
|
|
8343
|
-
language:
|
|
8344
|
-
path:
|
|
8345
|
-
nodeType:
|
|
8346
|
-
createdAt:
|
|
8347
|
-
updatedAt:
|
|
8348
|
-
},
|
|
8349
|
-
|
|
8350
|
-
Object.assign(
|
|
8408
|
+
let N = g?.parentId || null, ee = g?.treeNodeId ? await $e(t, String(g.treeNodeId), String(T), n) : `/${(h.slug || "").replace(/^\/+|\/+$/g, "")}`, P = {
|
|
8409
|
+
id: h.id,
|
|
8410
|
+
title: h.title,
|
|
8411
|
+
slug: h.slug,
|
|
8412
|
+
language: A,
|
|
8413
|
+
path: ee === "" ? "/" : ee,
|
|
8414
|
+
nodeType: h.contentType,
|
|
8415
|
+
createdAt: h.createdAt,
|
|
8416
|
+
updatedAt: h.updatedAt
|
|
8417
|
+
}, te = h.contentType || "node", F = p.nodes?.[te] || Object.values(p.nodes || {})[0] || {}, L = { ...F.fields || {} };
|
|
8418
|
+
F.tabs && Object.values(F.tabs).forEach((e) => {
|
|
8419
|
+
Object.assign(L, e.fields || {});
|
|
8351
8420
|
});
|
|
8352
|
-
let
|
|
8353
|
-
if (
|
|
8354
|
-
|
|
8421
|
+
let ne = {}, re = null, ie = null, ae = !1, R = {}, oe = s && h.draftDataJson || h.dataJson;
|
|
8422
|
+
if (oe) try {
|
|
8423
|
+
R = typeof oe == "string" ? JSON.parse(oe) : oe;
|
|
8355
8424
|
} 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
|
-
|
|
8425
|
+
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;
|
|
8426
|
+
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;
|
|
8427
|
+
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);
|
|
8428
|
+
let U = await B(t, Ge(R, L));
|
|
8429
|
+
U = Ke(U), U = await qe(t, U, n), delete U.language;
|
|
8430
|
+
let ue = Qe(U);
|
|
8431
|
+
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;
|
|
8432
|
+
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";
|
|
8433
|
+
if (!s && (de || fe || pe && !me)) return e.json({ error: "Node is hidden, offline, or has never been published." }, 404);
|
|
8434
|
+
let he = [];
|
|
8435
|
+
if (g?.treeNodeId) {
|
|
8436
|
+
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;
|
|
8437
|
+
he = n.map((e) => {
|
|
8369
8438
|
let t = {}, n = s && e.draftDataJson || e.dataJson;
|
|
8370
8439
|
if (!n) return null;
|
|
8371
8440
|
try {
|
|
8372
8441
|
t = (typeof n == "string" ? JSON.parse(n) : n) || {};
|
|
8373
8442
|
} catch {}
|
|
8374
|
-
let i = Number(e.isHidden) === 1 || t.hidden === !0 || t.hidden === 1 || t.hidden === "1", a =
|
|
8443
|
+
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
8444
|
return !s && (i || !a) ? null : {
|
|
8376
8445
|
treeNodeId: e.treeNodeId,
|
|
8377
8446
|
id: e.id,
|
|
8378
8447
|
title: e.title,
|
|
8379
8448
|
slug: o,
|
|
8380
|
-
language: e.language ||
|
|
8449
|
+
language: e.language?.trim() || A || null,
|
|
8381
8450
|
path: `${r}/${o}`.replace(/\/+/g, "/"),
|
|
8382
8451
|
nodeType: e.nodeType
|
|
8383
8452
|
};
|
|
8384
8453
|
}).filter(Boolean);
|
|
8385
8454
|
}
|
|
8386
|
-
|
|
8387
|
-
let
|
|
8455
|
+
P.children = he;
|
|
8456
|
+
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
8457
|
let r = e.region || "main", i = {};
|
|
8389
8458
|
try {
|
|
8390
8459
|
i = (typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson) || {};
|
|
8391
8460
|
} catch {}
|
|
8392
|
-
let a = i.hidden === !0 || i.hidden === 1 || i.hidden === "1" || i.hidden === "true", o =
|
|
8461
|
+
let a = i.hidden === !0 || i.hidden === 1 || i.hidden === "1" || i.hidden === "true", o = He(i.startShowingAt, i.stopShowingAt);
|
|
8393
8462
|
if (!s && (a || !o)) return null;
|
|
8394
|
-
let c = e.elementType || e.componentId || "text-block", l =
|
|
8395
|
-
return d = await
|
|
8463
|
+
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);
|
|
8464
|
+
return d = await B(t, d), d = Ke(d), d = await qe(t, d, n), d.blockId = u, {
|
|
8396
8465
|
region: r,
|
|
8397
8466
|
block: {
|
|
8398
8467
|
instanceId: e.id,
|
|
@@ -8402,8 +8471,8 @@ Re.get("/*", async (e) => {
|
|
|
8402
8471
|
}
|
|
8403
8472
|
};
|
|
8404
8473
|
}));
|
|
8405
|
-
for (let e of
|
|
8406
|
-
let
|
|
8474
|
+
for (let e of ye) e && (G[e.region] || (G[e.region] = [], ve[e.region] = { isInherited: !1 }), G[e.region].push(e.block));
|
|
8475
|
+
let K = {
|
|
8407
8476
|
header: {
|
|
8408
8477
|
label: "Header",
|
|
8409
8478
|
inherit: "parent"
|
|
@@ -8412,33 +8481,33 @@ Re.get("/*", async (e) => {
|
|
|
8412
8481
|
label: "Footer",
|
|
8413
8482
|
inherit: "parent"
|
|
8414
8483
|
},
|
|
8415
|
-
...(
|
|
8484
|
+
...(le ? p.nodeLayouts?.[le] || p.layouts?.[le] : null)?.regions || { main: { label: "Content" } }
|
|
8416
8485
|
};
|
|
8417
|
-
for (let [e, r] of Object.entries(
|
|
8418
|
-
let i =
|
|
8419
|
-
if (
|
|
8420
|
-
let r = await
|
|
8421
|
-
if (r.blocks.length > 0 && (
|
|
8486
|
+
for (let [e, r] of Object.entries(K)) {
|
|
8487
|
+
let i = G[e] && G[e].length > 0, a = !!ne[e];
|
|
8488
|
+
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) {
|
|
8489
|
+
let r = await We(t, N, e, p, s, n);
|
|
8490
|
+
if (r.blocks.length > 0 && (G[e] = r.blocks, ve[e] = {
|
|
8422
8491
|
isInherited: !0,
|
|
8423
8492
|
inheritedFromId: r.inheritedFromId,
|
|
8424
8493
|
inheritedFromTitle: r.inheritedFromTitle
|
|
8425
|
-
}, r.subRegions)) for (let [t, n] of Object.entries(r.subRegions)) t !== e && (
|
|
8494
|
+
}, r.subRegions)) for (let [t, n] of Object.entries(r.subRegions)) t !== e && (G[t] = n, ve[t] = {
|
|
8426
8495
|
isInherited: !0,
|
|
8427
8496
|
inheritedFromId: r.inheritedFromId,
|
|
8428
8497
|
inheritedFromTitle: r.inheritedFromTitle
|
|
8429
8498
|
});
|
|
8430
8499
|
}
|
|
8431
8500
|
}
|
|
8432
|
-
await Promise.all(Object.keys(
|
|
8433
|
-
let
|
|
8501
|
+
await Promise.all(Object.keys(G).map((e) => Ue(t, G[e], u, A)));
|
|
8502
|
+
let q = {
|
|
8434
8503
|
channelId: u || d,
|
|
8435
|
-
treeId:
|
|
8436
|
-
language: A
|
|
8437
|
-
node:
|
|
8438
|
-
content:
|
|
8439
|
-
regionMeta:
|
|
8504
|
+
treeId: T,
|
|
8505
|
+
language: A,
|
|
8506
|
+
node: P,
|
|
8507
|
+
content: G,
|
|
8508
|
+
regionMeta: ve
|
|
8440
8509
|
};
|
|
8441
|
-
return !s && !
|
|
8510
|
+
return !s && !M && (e.header("X-Cache", "MISS"), await nt(f, j, q, tt(e))), e.json(q);
|
|
8442
8511
|
} catch (t) {
|
|
8443
8512
|
return console.error("[CMS Public API] Error fetching node by path:", t), e.json({
|
|
8444
8513
|
error: "Failed to fetch JSON payload",
|
|
@@ -8448,8 +8517,8 @@ Re.get("/*", async (e) => {
|
|
|
8448
8517
|
});
|
|
8449
8518
|
//#endregion
|
|
8450
8519
|
//#region server/routes/public/tree.ts
|
|
8451
|
-
var
|
|
8452
|
-
function
|
|
8520
|
+
var rt = new e();
|
|
8521
|
+
function it(e, t) {
|
|
8453
8522
|
let n = /* @__PURE__ */ new Date();
|
|
8454
8523
|
if (e && String(e).trim() !== "") {
|
|
8455
8524
|
let t = new Date(e);
|
|
@@ -8461,93 +8530,103 @@ function rt(e, t) {
|
|
|
8461
8530
|
}
|
|
8462
8531
|
return !0;
|
|
8463
8532
|
}
|
|
8464
|
-
async function
|
|
8533
|
+
async function at(e, t, n, r) {
|
|
8465
8534
|
try {
|
|
8466
8535
|
await e.set(t, n, r);
|
|
8467
8536
|
} catch (e) {
|
|
8468
8537
|
console.warn("[CMS Cache] Failed to write tree response to cache:", e);
|
|
8469
8538
|
}
|
|
8470
8539
|
}
|
|
8471
|
-
|
|
8540
|
+
rt.get("/:treeParam", async (e) => {
|
|
8472
8541
|
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";
|
|
8542
|
+
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
8543
|
if (r && r !== "default" && r !== "all") {
|
|
8475
8544
|
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
8545
|
if (n) {
|
|
8546
|
+
n.defaultLanguage && (o = n.defaultLanguage.trim());
|
|
8477
8547
|
let t = n.status === "disabled" || n.status === "inactive" || n.isEnabled === 0 || n.isEnabled === !1;
|
|
8478
|
-
if (!
|
|
8548
|
+
if (!a && t) return e.json({ error: `Channel '${n.key || r}' is currently inactive` }, 404);
|
|
8479
8549
|
}
|
|
8480
8550
|
}
|
|
8481
|
-
let
|
|
8482
|
-
if (
|
|
8483
|
-
|
|
8551
|
+
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);
|
|
8552
|
+
if (c && Number(c.isHidden) === 1 && !a) return e.json({ error: `Tree '${n}' is hidden` }, 404);
|
|
8553
|
+
let l = null;
|
|
8554
|
+
if (c) {
|
|
8555
|
+
if (c.defaultLanguage) l = String(c.defaultLanguage).trim();
|
|
8556
|
+
else if (c.dataJson) try {
|
|
8557
|
+
let e = typeof c.dataJson == "string" ? JSON.parse(c.dataJson) : c.dataJson;
|
|
8558
|
+
e.defaultLanguage && (l = String(e.defaultLanguage).trim());
|
|
8559
|
+
} catch {}
|
|
8560
|
+
}
|
|
8561
|
+
let u = l || o || i?.trim() || null, d = I(e), f = `tree:${r}:${n}:${u || "default"}`, p = e.req.header("x-bypass-cache") === "true";
|
|
8562
|
+
if (!a && !p) {
|
|
8563
|
+
let t = await d.get(f);
|
|
8484
8564
|
if (t) return e.header("X-Cache", "HIT"), e.json(t);
|
|
8485
8565
|
}
|
|
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);
|
|
8566
|
+
let m = c?.id || (s ? Number(n) : null), h = {};
|
|
8567
|
+
if (c && c.dataJson) try {
|
|
8568
|
+
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 || {};
|
|
8569
|
+
for (let [e, n] of Object.entries(t)) a[e]?.public === !0 && (h[e] = n);
|
|
8492
8570
|
} catch (e) {
|
|
8493
8571
|
console.warn("[CMS Public Tree API] Failed to parse tree dataJson", e);
|
|
8494
8572
|
}
|
|
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
|
-
|
|
8573
|
+
let g = [];
|
|
8574
|
+
if (m !== null) {
|
|
8575
|
+
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);
|
|
8576
|
+
g = Array.isArray(e) ? e : e?.results || [];
|
|
8499
8577
|
}
|
|
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) :
|
|
8578
|
+
if ((!g || g.length === 0) && !c) return e.json({ error: `Tree '${n}' not found` }, 404);
|
|
8579
|
+
let _ = /* @__PURE__ */ new Map();
|
|
8580
|
+
for (let e of g) {
|
|
8581
|
+
let t = !e.parentId || e.parentId === "null" || e.parentId === "" ? null : e.parentId, n = t === null ? "__ROOT__" : String(t), r = _.get(n);
|
|
8582
|
+
r ? r.push(e) : _.set(n, [e]);
|
|
8505
8583
|
}
|
|
8506
|
-
let
|
|
8507
|
-
for (let e of
|
|
8508
|
-
let t = String(e.treeNodeId), n =
|
|
8584
|
+
let v = /* @__PURE__ */ new Map();
|
|
8585
|
+
for (let e of g) {
|
|
8586
|
+
let t = String(e.treeNodeId), n = a && e.draftDataJson ? e.draftDataJson : e.dataJson;
|
|
8509
8587
|
if (!n) {
|
|
8510
|
-
|
|
8588
|
+
v.set(t, {});
|
|
8511
8589
|
continue;
|
|
8512
8590
|
}
|
|
8513
8591
|
try {
|
|
8514
8592
|
let e = typeof n == "string" ? JSON.parse(n) : n;
|
|
8515
|
-
|
|
8593
|
+
v.set(t, e && typeof e == "object" ? e : {});
|
|
8516
8594
|
} catch {
|
|
8517
|
-
|
|
8595
|
+
v.set(t, {});
|
|
8518
8596
|
}
|
|
8519
8597
|
}
|
|
8520
|
-
function
|
|
8598
|
+
function y(e = null, t = "") {
|
|
8521
8599
|
let n = e == null || e === "" || e === "null" ? "__ROOT__" : String(e);
|
|
8522
|
-
return (
|
|
8523
|
-
let n =
|
|
8600
|
+
return (_.get(n) || []).map((e) => {
|
|
8601
|
+
let n = v.get(String(e.treeNodeId)) || {}, r = {};
|
|
8524
8602
|
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
|
|
8603
|
+
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
8604
|
id: e.id,
|
|
8527
8605
|
treeNodeId: e.treeNodeId,
|
|
8528
8606
|
parentId: e.parentId || null,
|
|
8529
8607
|
title: e.title,
|
|
8530
8608
|
slug: c,
|
|
8531
|
-
language:
|
|
8609
|
+
language: d,
|
|
8532
8610
|
path: l,
|
|
8533
8611
|
nodeType: e.nodeType,
|
|
8534
8612
|
hidden: o || !s ? 1 : 0,
|
|
8535
8613
|
summary: r.summary || ""
|
|
8536
8614
|
};
|
|
8537
|
-
e.nodeType === "external-link" && (r.url && (
|
|
8538
|
-
let
|
|
8539
|
-
return
|
|
8540
|
-
}).filter((e) =>
|
|
8615
|
+
e.nodeType === "external-link" && (r.url && (f.url = r.url), r.target && (f.target = r.target));
|
|
8616
|
+
let p = l === "/" ? "" : l;
|
|
8617
|
+
return f.children = y(e.treeNodeId, p), f;
|
|
8618
|
+
}).filter((e) => a || !e.hidden);
|
|
8541
8619
|
}
|
|
8542
|
-
let
|
|
8543
|
-
treeId:
|
|
8544
|
-
key:
|
|
8620
|
+
let b = {
|
|
8621
|
+
treeId: c?.id || m,
|
|
8622
|
+
key: c?.key || n,
|
|
8545
8623
|
channelId: r,
|
|
8546
|
-
|
|
8547
|
-
|
|
8548
|
-
|
|
8624
|
+
language: u,
|
|
8625
|
+
label: c?.label || n,
|
|
8626
|
+
...h,
|
|
8627
|
+
items: y(null)
|
|
8549
8628
|
};
|
|
8550
|
-
return !
|
|
8629
|
+
return !a && !p && (e.header("X-Cache", "MISS"), await at(d, f, b, 300)), e.json(b);
|
|
8551
8630
|
} catch (t) {
|
|
8552
8631
|
return console.error("[CMS Public Tree API] Error:", t), e.json({
|
|
8553
8632
|
error: "Failed to fetch public tree",
|
|
@@ -8556,9 +8635,148 @@ nt.get("/:treeParam", async (e) => {
|
|
|
8556
8635
|
}
|
|
8557
8636
|
});
|
|
8558
8637
|
//#endregion
|
|
8638
|
+
//#region server/routes/public/channel.ts
|
|
8639
|
+
var ot = new e();
|
|
8640
|
+
function st(e) {
|
|
8641
|
+
let t = Number(e?.env?.CMS_CHANNEL_CACHE_TTL);
|
|
8642
|
+
return Number.isFinite(t) && t >= 60 ? Math.floor(t) : 300;
|
|
8643
|
+
}
|
|
8644
|
+
async function ct(e, t, n, r) {
|
|
8645
|
+
try {
|
|
8646
|
+
await e.set(t, n, r);
|
|
8647
|
+
} catch (e) {
|
|
8648
|
+
console.warn("[CMS Cache] Failed to write channel response to cache:", e);
|
|
8649
|
+
}
|
|
8650
|
+
}
|
|
8651
|
+
function lt(e, t) {
|
|
8652
|
+
let n = {}, r = (e) => {
|
|
8653
|
+
if (!e || typeof e != "string") return;
|
|
8654
|
+
let n = t?.fieldSets?.[e] || t?.fieldsets?.[e] || t?.definitions?.[e] || t?.channels?.[e] || t?.[e];
|
|
8655
|
+
n?.fields && i(n.fields);
|
|
8656
|
+
}, i = (e) => {
|
|
8657
|
+
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);
|
|
8658
|
+
};
|
|
8659
|
+
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);
|
|
8660
|
+
return n;
|
|
8661
|
+
}
|
|
8662
|
+
function ut(e, t = {}) {
|
|
8663
|
+
let n = {}, r = Object.keys(t).length > 0;
|
|
8664
|
+
for (let [i, a] of Object.entries(e)) {
|
|
8665
|
+
if (i.endsWith("_meta") || [
|
|
8666
|
+
"disabledRegions",
|
|
8667
|
+
"hidden",
|
|
8668
|
+
"is_hidden",
|
|
8669
|
+
"isHidden",
|
|
8670
|
+
"status",
|
|
8671
|
+
"startShowingAt",
|
|
8672
|
+
"stopShowingAt",
|
|
8673
|
+
"dataJson",
|
|
8674
|
+
"draftDataJson"
|
|
8675
|
+
].includes(i) || i.startsWith("_")) continue;
|
|
8676
|
+
let e = t[i];
|
|
8677
|
+
(!r || !e || e.public !== !1) && a != null && a !== "" && (n[i] = a);
|
|
8678
|
+
}
|
|
8679
|
+
return n;
|
|
8680
|
+
}
|
|
8681
|
+
function dt(e) {
|
|
8682
|
+
if (Array.isArray(e)) return e.map(dt);
|
|
8683
|
+
if (!e || typeof e != "object") return e;
|
|
8684
|
+
if (typeof e.id == "string" && e.id.startsWith("ast_") && typeof e.url == "string") {
|
|
8685
|
+
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 ? {
|
|
8686
|
+
...t,
|
|
8687
|
+
...t.crops?.[r] || {}
|
|
8688
|
+
} : t, a = Object.fromEntries(Object.entries(n).filter(([, t]) => t?.id !== e.id).map(([t, n]) => [t, dt({
|
|
8689
|
+
...n,
|
|
8690
|
+
title: n?.title ?? e.title ?? "",
|
|
8691
|
+
alt: n?.alt ?? e.alt ?? "",
|
|
8692
|
+
description: n?.description ?? e.description ?? ""
|
|
8693
|
+
})])), { metadataOverrides: o, ...s } = e;
|
|
8694
|
+
return {
|
|
8695
|
+
...s,
|
|
8696
|
+
title: i.title ?? e.title ?? "",
|
|
8697
|
+
alt: i.alt ?? e.alt ?? "",
|
|
8698
|
+
description: i.description ?? e.description ?? "",
|
|
8699
|
+
...Object.keys(a).length > 0 ? { variants: a } : {}
|
|
8700
|
+
};
|
|
8701
|
+
}
|
|
8702
|
+
return Object.fromEntries(Object.entries(e).map(([e, t]) => [e, dt(t)]));
|
|
8703
|
+
}
|
|
8704
|
+
async function ft(e, t) {
|
|
8705
|
+
if (typeof t == "string") {
|
|
8706
|
+
if (!t.includes("#node:") && !t.includes("data-node-id") && !t.includes("#asset:") && !t.includes("data-asset-id")) return t;
|
|
8707
|
+
let n = /* @__PURE__ */ new Set(), r = /* @__PURE__ */ new Set();
|
|
8708
|
+
for (let e of t.matchAll(/(?:#node:|data-node-id\s*=\s*["'])([^"'\s>]+)/gi)) n.add(e[1]);
|
|
8709
|
+
for (let e of t.matchAll(/(?:#asset:|data-asset-id\s*=\s*["'])([^"'\s>]+)/gi)) r.add(e[1]);
|
|
8710
|
+
if (n.size === 0 && r.size === 0) return t;
|
|
8711
|
+
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();
|
|
8712
|
+
(Array.isArray(a) ? a : a?.results || []).forEach((e) => o.set(String(e.id), String(e.slug || "").replace(/^\/+|\/+$/g, "")));
|
|
8713
|
+
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();
|
|
8714
|
+
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) => {
|
|
8715
|
+
let n = (e, t) => {
|
|
8716
|
+
let n = e.match(RegExp(`\\b${t}\\s*=\\s*(["'])(.*?)\\1`, "i"));
|
|
8717
|
+
return n ? n[2] : void 0;
|
|
8718
|
+
}, r = n(t, "data-node-id"), i = n(t, "data-asset-id"), a = n(t, "href") || "";
|
|
8719
|
+
if (a.startsWith("mailto:")) return `<a ${t.replace(/\s+target\s*=\s*["'][^"']*["']/i, "")}>`;
|
|
8720
|
+
let s = i || a.match(/^#asset:(.+)$/i)?.[1], c = r || a.match(/^#node:(.+)$/i)?.[1];
|
|
8721
|
+
if (!c && !s) return e;
|
|
8722
|
+
if (s && !c) {
|
|
8723
|
+
let n = l.get(s);
|
|
8724
|
+
if (n) {
|
|
8725
|
+
let e = t;
|
|
8726
|
+
return /href\s*=\s*["'][^"']*["']/i.test(e) ? e = e.replace(/href\s*=\s*["'][^"']*["']/i, `href="${n}"`) : e += ` href="${n}"`, `<a ${e}>`;
|
|
8727
|
+
}
|
|
8728
|
+
return e;
|
|
8729
|
+
}
|
|
8730
|
+
let u = o.get(c), d = u === void 0 ? "#" : `/${u}`, f = t;
|
|
8731
|
+
return /href\s*=\s*["'][^"']*["']/i.test(f) ? f = f.replace(/href\s*=\s*["'][^"']*["']/i, `href="${d || "/"}"`) : f += ` href="${d || "/"}"`, `<a ${f}>`;
|
|
8732
|
+
});
|
|
8733
|
+
}
|
|
8734
|
+
if (Array.isArray(t)) return Promise.all(t.map((t) => ft(e, t)));
|
|
8735
|
+
if (t && typeof t == "object") {
|
|
8736
|
+
let n = await Promise.all(Object.entries(t).map(async ([t, n]) => [t, await ft(e, n)]));
|
|
8737
|
+
return Object.fromEntries(n);
|
|
8738
|
+
}
|
|
8739
|
+
return t;
|
|
8740
|
+
}
|
|
8741
|
+
ot.get("/:channelParam", async (e) => {
|
|
8742
|
+
try {
|
|
8743
|
+
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);
|
|
8744
|
+
if (!r && !i) {
|
|
8745
|
+
let t = await o.get(a);
|
|
8746
|
+
if (t) return e.header("X-Cache", "HIT"), e.json(t);
|
|
8747
|
+
}
|
|
8748
|
+
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));
|
|
8749
|
+
if (!s) return e.json({ error: `Channel '${n}' not found` }, 404);
|
|
8750
|
+
let c = s.status === "disabled" || s.status === "inactive" || s.isEnabled === 0 || s.isEnabled === !1;
|
|
8751
|
+
if (!r && c) return e.json({ error: `Channel '${s.key || n}' is currently inactive` }, 404);
|
|
8752
|
+
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;
|
|
8753
|
+
if (m) try {
|
|
8754
|
+
p = typeof m == "string" ? JSON.parse(m) : m;
|
|
8755
|
+
} catch (e) {
|
|
8756
|
+
console.warn("[CMS Public Channel API] Failed to parse channel dataJson:", e);
|
|
8757
|
+
}
|
|
8758
|
+
let h = ut({
|
|
8759
|
+
...p,
|
|
8760
|
+
...s
|
|
8761
|
+
}, f);
|
|
8762
|
+
h = await B(t, h), h = dt(h), h = await ft(t, h);
|
|
8763
|
+
let g = {
|
|
8764
|
+
id: s.id,
|
|
8765
|
+
key: s.key,
|
|
8766
|
+
...h
|
|
8767
|
+
};
|
|
8768
|
+
return !r && !i && (e.header("X-Cache", "MISS"), await ct(o, a, g, st(e))), e.json(g);
|
|
8769
|
+
} catch (t) {
|
|
8770
|
+
return console.error("[CMS Public Channel API] Error:", t), e.json({
|
|
8771
|
+
error: "Failed to fetch public channel",
|
|
8772
|
+
...e.env?.ENVIRONMENT === "development" ? { details: t.message } : {}
|
|
8773
|
+
}, 500);
|
|
8774
|
+
}
|
|
8775
|
+
});
|
|
8776
|
+
//#endregion
|
|
8559
8777
|
//#region server/routes/public/assets.ts
|
|
8560
|
-
var
|
|
8561
|
-
function
|
|
8778
|
+
var pt = new e();
|
|
8779
|
+
function mt(e, t) {
|
|
8562
8780
|
if (t === "webp") return "image/webp";
|
|
8563
8781
|
if (t === "avif") return "image/avif";
|
|
8564
8782
|
if (t === "jpeg" || t === "jpg") return "image/jpeg";
|
|
@@ -8566,7 +8784,7 @@ function ot(e, t) {
|
|
|
8566
8784
|
let n = e.toLowerCase();
|
|
8567
8785
|
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
8786
|
}
|
|
8569
|
-
|
|
8787
|
+
pt.get("/*", async (e) => {
|
|
8570
8788
|
try {
|
|
8571
8789
|
let t = e.req.path.replace(/^\/media\//, "").replace(/^\//, "");
|
|
8572
8790
|
if (!t) return e.text("Asset key missing", 400);
|
|
@@ -8582,11 +8800,11 @@ at.get("/*", async (e) => {
|
|
|
8582
8800
|
let e = await l.match(d);
|
|
8583
8801
|
if (e) return e;
|
|
8584
8802
|
}
|
|
8585
|
-
let { storage: f, optimizer: p } =
|
|
8803
|
+
let { storage: f, optimizer: p } = ae(e.env), m = await f.get(t);
|
|
8586
8804
|
if (!m) return e.text(`Asset not found: ${t}`, 404);
|
|
8587
8805
|
if (!o) {
|
|
8588
8806
|
let n = e.body(m, 200, {
|
|
8589
|
-
"Content-Type":
|
|
8807
|
+
"Content-Type": mt(t),
|
|
8590
8808
|
"Cache-Control": "public, max-age=31536000, immutable"
|
|
8591
8809
|
});
|
|
8592
8810
|
return l && d && e.executionCtx?.waitUntil && e.executionCtx.waitUntil(l.put(d, n.clone())), n;
|
|
@@ -8600,7 +8818,7 @@ at.get("/*", async (e) => {
|
|
|
8600
8818
|
key: t,
|
|
8601
8819
|
env: e.env,
|
|
8602
8820
|
req: e.req.raw
|
|
8603
|
-
}), _ =
|
|
8821
|
+
}), _ = mt(t, c), v = e.body(g, 200, {
|
|
8604
8822
|
"Content-Type": _,
|
|
8605
8823
|
"Cache-Control": "public, max-age=31536000, immutable"
|
|
8606
8824
|
});
|
|
@@ -8611,8 +8829,8 @@ at.get("/*", async (e) => {
|
|
|
8611
8829
|
});
|
|
8612
8830
|
//#endregion
|
|
8613
8831
|
//#region server/routes/public/paths.ts
|
|
8614
|
-
var
|
|
8615
|
-
function
|
|
8832
|
+
var ht = new e();
|
|
8833
|
+
function gt(e, t) {
|
|
8616
8834
|
let n = /* @__PURE__ */ new Date();
|
|
8617
8835
|
if (e && String(e).trim() !== "") {
|
|
8618
8836
|
let t = new Date(e);
|
|
@@ -8624,7 +8842,7 @@ function ct(e, t) {
|
|
|
8624
8842
|
}
|
|
8625
8843
|
return !0;
|
|
8626
8844
|
}
|
|
8627
|
-
|
|
8845
|
+
ht.get("/", async (e) => {
|
|
8628
8846
|
try {
|
|
8629
8847
|
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
8848
|
for (let e of n) {
|
|
@@ -8648,7 +8866,7 @@ st.get("/", async (e) => {
|
|
|
8648
8866
|
function o(e = null, t = "") {
|
|
8649
8867
|
let n = e == null || e === "" || e === "null" ? "__ROOT__" : String(e), s = i.get(n) || [];
|
|
8650
8868
|
for (let e of s) {
|
|
8651
|
-
let n = a.get(String(e.treeNodeId)) || {}, i = e.status === "published" || e.status === "active", s =
|
|
8869
|
+
let n = a.get(String(e.treeNodeId)) || {}, i = e.status === "published" || e.status === "active", s = gt(n.startShowingAt, n.stopShowingAt);
|
|
8652
8870
|
if (!i || !s) continue;
|
|
8653
8871
|
let c = (e.slug || "").replace(/^\/+|\/+$/g, ""), l = c === "home" || c === "homee" ? "/" : `${t}/${c}`.replace(/\/+/g, "/");
|
|
8654
8872
|
e.nodeType !== "external-link" && r.push(l);
|
|
@@ -8665,7 +8883,7 @@ st.get("/", async (e) => {
|
|
|
8665
8883
|
});
|
|
8666
8884
|
//#endregion
|
|
8667
8885
|
//#region server/index.ts
|
|
8668
|
-
var $ = new e(),
|
|
8886
|
+
var $ = new e(), _t = !1;
|
|
8669
8887
|
$.use("*", t()), $.use("/media/*", t({
|
|
8670
8888
|
origin: "*",
|
|
8671
8889
|
allowMethods: [
|
|
@@ -8686,13 +8904,13 @@ $.use("*", t()), $.use("/media/*", t({
|
|
|
8686
8904
|
let n = new URL(e.req.url), r = (e.req.header("host") || n.hostname).split(":")[0];
|
|
8687
8905
|
e.set("currentDomain", r);
|
|
8688
8906
|
let i = l(e);
|
|
8689
|
-
if (e.set("db", i), !
|
|
8690
|
-
await _(i),
|
|
8907
|
+
if (e.set("db", i), !_t) try {
|
|
8908
|
+
await _(i), _t = !0;
|
|
8691
8909
|
} catch (e) {
|
|
8692
8910
|
console.error("❌ [CMS Server] Failed to initialize system tables on cold start:", e);
|
|
8693
8911
|
}
|
|
8694
8912
|
await t();
|
|
8695
|
-
}), $.route("/media",
|
|
8913
|
+
}), $.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
8914
|
if (e.env?.ASSETS) {
|
|
8697
8915
|
let t = await e.env.ASSETS.fetch(e.req.raw);
|
|
8698
8916
|
if (t.status === 404) {
|
|
@@ -8704,4 +8922,4 @@ $.use("*", t()), $.use("/media/*", t({
|
|
|
8704
8922
|
return t();
|
|
8705
8923
|
});
|
|
8706
8924
|
//#endregion
|
|
8707
|
-
export { $ as app, $ as default,
|
|
8925
|
+
export { $ as app, $ as default, ke as compileDefinitions, Ae as getCmsDefinitions };
|