@brightsideoy/kama 1.0.0-alpha.13 → 1.0.0-alpha.17
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 +282 -158
- package/content/definitions/taxonomies/categories.yaml +5 -2
- package/content/definitions/taxonomies/tags.yaml +5 -2
- package/dist/assets/AssetEditor-CCNDGlQ_.js +1 -0
- package/dist/assets/AssetEditor-D5j7pwcK.css +1 -0
- package/dist/assets/CmsHelp-BO_vWABq.css +1 -0
- package/dist/assets/CmsHelp-m9EOY_nE.js +1 -0
- package/dist/assets/CmsPublisher-Cs_ys68V.js +3 -0
- package/dist/assets/CmsPublisher-CugEqTD8.css +1 -0
- package/dist/assets/CmsUserCenter-Ac0GywlR.css +1 -0
- package/dist/assets/CmsUserCenter-D-T6HyWF.js +1 -0
- package/dist/assets/EditorSplitPreview-BzKh4wFB.css +1 -0
- package/dist/assets/EditorSplitPreview-CnWpXZWQ.js +1 -0
- package/dist/assets/NodeEditor-B1TvB2eW.css +1 -0
- package/dist/assets/NodeEditor-CZGnkwvf.js +147 -0
- package/dist/assets/TrashWorkspace-CERX58Ek.js +1 -0
- package/dist/assets/TrashWorkspace-DtMgxg13.css +1 -0
- package/dist/assets/_plugin-vue_export-helper-CTn6xl4w.js +5 -0
- package/dist/assets/history-XvWNE5zO.js +1 -0
- package/dist/assets/index-BpOAL4tE.js +14 -0
- package/dist/assets/index-C-EkPNvq.css +1 -0
- package/dist/assets/layers-D0DLWjff.js +1 -0
- package/dist/assets/link-Bs_SUS0O.js +1 -0
- package/dist/assets/rotate-ccw-CvD7yNQj.js +1 -0
- package/dist/assets/save-C8e-QRkP.js +1 -0
- package/dist/assets/smartphone-Wy6xQi_i.js +1 -0
- package/dist/{dist-kIJlDMvm.js → dist-BGv2bzzF.js} +633 -539
- package/dist/index.html +3 -2
- package/dist/index.js +633 -539
- package/dist/schema-compiler.js +1 -1
- package/package.json +1 -1
- package/schema.sql +3 -0
- package/templates/astro-starter/src/components/blocks/NodeList.astro +59 -63
- package/templates/astro-starter/src/middleware.ts +63 -35
- package/templates/astro-starter/src/pages/[...slug].astro +5 -12
- package/templates/astro-starter/src/pages/api/load-nodes.ts +42 -14
- package/templates/astro-starter/src/pages/api/partials/node-cards.astro +101 -0
- package/templates/kama-worker/setup-local-db.mjs +17 -0
- package/dist/assets/index-B1ogCRCg.js +0 -164
- package/dist/assets/index-CGLx9oqF.css +0 -1
package/dist/index.js
CHANGED
|
@@ -278,9 +278,9 @@ function D(e, t) {
|
|
|
278
278
|
return r && E.setMetadataInRegistry(t, r), t;
|
|
279
279
|
});
|
|
280
280
|
}
|
|
281
|
-
function
|
|
281
|
+
function te(e) {
|
|
282
282
|
e.ZodType.prototype.openapi === void 0 && (e.ZodType.prototype.openapi = function(...e) {
|
|
283
|
-
let { refId: t, metadata: n, options: r } =
|
|
283
|
+
let { refId: t, metadata: n, options: r } = O(...e), i = n ?? {}, { param: a } = i, o = s(i, ["param"]), c = E.getMetadataFromRegistry(this) ?? {}, { _internal: u } = c, d = s(c, ["_internal"]), f = Object.assign(Object.assign(Object.assign({}, u), r), t ? { refId: t } : void 0), p = Object.assign(Object.assign(Object.assign({}, d), o), d?.param || a ? { param: Object.assign(Object.assign({}, d?.param), a) } : void 0), m = new this.constructor(this._def);
|
|
284
284
|
function h(e) {
|
|
285
285
|
E.setMetadataInRegistry(e, Object.assign(Object.assign({}, Object.keys(f).length > 0 ? { _internal: f } : void 0), p));
|
|
286
286
|
}
|
|
@@ -306,7 +306,7 @@ function O(e) {
|
|
|
306
306
|
}, m;
|
|
307
307
|
});
|
|
308
308
|
}
|
|
309
|
-
function
|
|
309
|
+
function O(e, t, n) {
|
|
310
310
|
return typeof e == "string" ? {
|
|
311
311
|
refId: e,
|
|
312
312
|
metadata: t,
|
|
@@ -16707,7 +16707,7 @@ var $y = class t extends e {
|
|
|
16707
16707
|
};
|
|
16708
16708
|
return Object.defineProperty(t, "getRoutingPath", { enumerable: !1 });
|
|
16709
16709
|
};
|
|
16710
|
-
|
|
16710
|
+
te(Xy);
|
|
16711
16711
|
function tb(e, t) {
|
|
16712
16712
|
let n = {};
|
|
16713
16713
|
return Object.keys(e.paths).forEach((r) => {
|
|
@@ -20777,9 +20777,14 @@ var Tb = /* @__PURE__ */ o({
|
|
|
20777
20777
|
label: "Category",
|
|
20778
20778
|
hierarchical: !0,
|
|
20779
20779
|
fields: {
|
|
20780
|
+
label: {
|
|
20781
|
+
type: "text",
|
|
20782
|
+
label: "Label",
|
|
20783
|
+
required: !0,
|
|
20784
|
+
rules: { required: !0 }
|
|
20785
|
+
},
|
|
20780
20786
|
slug: {
|
|
20781
|
-
|
|
20782
|
-
linkedTo: "key",
|
|
20787
|
+
linkedTo: "label",
|
|
20783
20788
|
rules: {}
|
|
20784
20789
|
},
|
|
20785
20790
|
description: {
|
|
@@ -20807,9 +20812,14 @@ var Tb = /* @__PURE__ */ o({
|
|
|
20807
20812
|
label: "Tag",
|
|
20808
20813
|
hierarchical: !1,
|
|
20809
20814
|
fields: {
|
|
20815
|
+
label: {
|
|
20816
|
+
type: "text",
|
|
20817
|
+
label: "Label",
|
|
20818
|
+
required: !0,
|
|
20819
|
+
rules: { required: !0 }
|
|
20820
|
+
},
|
|
20810
20821
|
slug: {
|
|
20811
|
-
|
|
20812
|
-
linkedTo: "key",
|
|
20822
|
+
linkedTo: "label",
|
|
20813
20823
|
rules: {}
|
|
20814
20824
|
},
|
|
20815
20825
|
iconName: {
|
|
@@ -22198,7 +22208,7 @@ var Tb = /* @__PURE__ */ o({
|
|
|
22198
22208
|
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 ",
|
|
22199
22209
|
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 ",
|
|
22200
22210
|
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 ",
|
|
22201
|
-
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 ",
|
|
22211
|
+
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 startShowingAt TEXT,\n stopShowingAt TEXT,\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 ",
|
|
22202
22212
|
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 ",
|
|
22203
22213
|
tree_nodes: "\n treeId INTEGER NOT NULL,\n contentId INTEGER NOT NULL,\n parentId INTEGER,\n sortOrder INTEGER DEFAULT 0,\n PRIMARY KEY (treeId, contentId),\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 content_nodes(id) ON DELETE CASCADE\n ",
|
|
22204
22214
|
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 ",
|
|
@@ -22209,11 +22219,11 @@ var Tb = /* @__PURE__ */ o({
|
|
|
22209
22219
|
node_terms: "\n nodeId INTEGER NOT NULL,\n termId INTEGER NOT NULL,\n fieldKey TEXT NOT NULL,\n sortOrder INTEGER DEFAULT 0,\n PRIMARY KEY (nodeId, termId, fieldKey),\n FOREIGN KEY (nodeId) REFERENCES content_nodes(id) ON DELETE CASCADE,\n FOREIGN KEY (termId) REFERENCES taxonomy_terms(id) ON DELETE CASCADE\n ",
|
|
22210
22220
|
node_relations: "\n sourceNodeId INTEGER NOT NULL,\n targetNodeId INTEGER NOT NULL,\n fieldKey TEXT NOT NULL,\n sortOrder INTEGER DEFAULT 0,\n PRIMARY KEY (sourceNodeId, targetNodeId, fieldKey),\n FOREIGN KEY (sourceNodeId) REFERENCES content_nodes(id) ON DELETE CASCADE,\n FOREIGN KEY (targetNodeId) REFERENCES content_nodes(id) ON DELETE CASCADE\n ",
|
|
22211
22221
|
node_routes: "\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n path TEXT NOT NULL,\n channelId INTEGER NOT NULL,\n nodeId INTEGER,\n treeId INTEGER,\n isCanonical INTEGER DEFAULT 1,\n redirectUrl TEXT,\n createdAt TEXT DEFAULT CURRENT_TIMESTAMP,\n updatedAt TEXT DEFAULT CURRENT_TIMESTAMP,\n FOREIGN KEY (channelId) REFERENCES channels(id) ON DELETE CASCADE,\n FOREIGN KEY (nodeId) REFERENCES content_nodes(id) ON DELETE CASCADE,\n FOREIGN KEY (treeId) REFERENCES trees(id) ON DELETE CASCADE,\n UNIQUE(path, channelId)\n "
|
|
22212
|
-
}, kb = /* @__PURE__ */ "CREATE INDEX IF NOT EXISTS idx_tree_nodes_tree_parent ON tree_nodes(treeId, parentId);.CREATE INDEX IF NOT EXISTS idx_tree_nodes_contentId ON tree_nodes(contentId);.CREATE INDEX IF NOT EXISTS idx_content_nodes_slug_status ON content_nodes(slug, status);.CREATE INDEX IF NOT EXISTS idx_content_blocks_node ON content_blocks(contentId, isDraft);.CREATE INDEX IF NOT EXISTS idx_node_assets_nodeId ON node_assets(nodeId);.CREATE INDEX IF NOT EXISTS idx_node_assets_assetId ON node_assets(assetId);.CREATE INDEX IF NOT EXISTS idx_content_schemas_type ON content_schemas(type);.CREATE INDEX IF NOT EXISTS idx_sessions_user ON sessions(userId);.CREATE INDEX IF NOT EXISTS idx_sessions_expires ON sessions(expiresAt);.CREATE INDEX IF NOT EXISTS idx_channels_visibility ON channels(isHidden);.CREATE INDEX IF NOT EXISTS idx_trees_visibility ON trees(isHidden);.CREATE INDEX IF NOT EXISTS idx_content_nodes_visibility ON content_nodes(isHidden, status);.CREATE INDEX IF NOT EXISTS idx_content_nodes_slug ON content_nodes(slug);.CREATE INDEX IF NOT EXISTS idx_content_nodes_type ON content_nodes(contentType);.CREATE INDEX IF NOT EXISTS idx_content_nodes_deleted_updated ON content_nodes(deletedAt, updatedAt DESC);.CREATE INDEX IF NOT EXISTS idx_tree_nodes_hierarchy ON tree_nodes(treeId, parentId, sortOrder);.CREATE INDEX IF NOT EXISTS idx_tree_nodes_content ON tree_nodes(contentId, treeId);.CREATE INDEX IF NOT EXISTS idx_content_blocks_content ON content_blocks(contentId, isDraft, region, sortOrder);.CREATE INDEX IF NOT EXISTS idx_node_channels_channel ON node_channels(channelId, nodeId);.CREATE INDEX IF NOT EXISTS idx_node_channels_node ON node_channels(nodeId, channelId);.CREATE INDEX IF NOT EXISTS idx_node_assets_node_asset ON node_assets(nodeId, assetId);.CREATE INDEX IF NOT EXISTS idx_node_assets_asset_node ON node_assets(assetId, nodeId);.CREATE UNIQUE INDEX IF NOT EXISTS idx_node_revisions_version ON node_revisions(nodeId, version);.CREATE INDEX IF NOT EXISTS idx_assets_system_created ON assets(isSystemVariant, createdAt DESC);.CREATE INDEX IF NOT EXISTS idx_assets_system_mime ON assets(isSystemVariant, mimeType);.CREATE INDEX IF NOT EXISTS idx_assets_deleted ON assets(deletedAt);.CREATE INDEX IF NOT EXISTS idx_assets_parent ON assets(parentAssetId);.CREATE INDEX IF NOT EXISTS idx_taxonomy_terms_tax ON taxonomy_terms(taxonomy);.CREATE INDEX IF NOT EXISTS idx_node_terms_node ON node_terms(nodeId);.CREATE INDEX IF NOT EXISTS idx_node_terms_term ON node_terms(termId);.CREATE INDEX IF NOT EXISTS idx_node_terms_node_term ON node_terms(nodeId, termId);.CREATE INDEX IF NOT EXISTS idx_node_terms_term_node ON node_terms(termId, nodeId);.CREATE INDEX IF NOT EXISTS idx_node_relations_source ON node_relations(sourceNodeId);.CREATE INDEX IF NOT EXISTS idx_node_relations_target ON node_relations(targetNodeId);.CREATE INDEX IF NOT EXISTS idx_node_routes_lookup ON node_routes(path, channelId);.CREATE INDEX IF NOT EXISTS idx_node_routes_node ON node_routes(nodeId);".split(".");
|
|
22222
|
+
}, kb = /* @__PURE__ */ "CREATE INDEX IF NOT EXISTS idx_tree_nodes_tree_parent ON tree_nodes(treeId, parentId);.CREATE INDEX IF NOT EXISTS idx_tree_nodes_contentId ON tree_nodes(contentId);.CREATE INDEX IF NOT EXISTS idx_content_nodes_slug_status ON content_nodes(slug, status);.CREATE INDEX IF NOT EXISTS idx_content_blocks_node ON content_blocks(contentId, isDraft);.CREATE INDEX IF NOT EXISTS idx_node_assets_nodeId ON node_assets(nodeId);.CREATE INDEX IF NOT EXISTS idx_node_assets_assetId ON node_assets(assetId);.CREATE INDEX IF NOT EXISTS idx_content_schemas_type ON content_schemas(type);.CREATE INDEX IF NOT EXISTS idx_sessions_user ON sessions(userId);.CREATE INDEX IF NOT EXISTS idx_sessions_expires ON sessions(expiresAt);.CREATE INDEX IF NOT EXISTS idx_channels_visibility ON channels(isHidden);.CREATE INDEX IF NOT EXISTS idx_trees_visibility ON trees(isHidden);.CREATE INDEX IF NOT EXISTS idx_content_nodes_visibility ON content_nodes(isHidden, status);.CREATE INDEX IF NOT EXISTS idx_content_nodes_slug ON content_nodes(slug);.CREATE INDEX IF NOT EXISTS idx_content_nodes_type ON content_nodes(contentType);.CREATE INDEX IF NOT EXISTS idx_content_nodes_deleted_updated ON content_nodes(deletedAt, updatedAt DESC);.CREATE INDEX IF NOT EXISTS idx_tree_nodes_hierarchy ON tree_nodes(treeId, parentId, sortOrder);.CREATE INDEX IF NOT EXISTS idx_tree_nodes_content ON tree_nodes(contentId, treeId);.CREATE INDEX IF NOT EXISTS idx_content_blocks_content ON content_blocks(contentId, isDraft, region, sortOrder);.CREATE INDEX IF NOT EXISTS idx_node_channels_channel ON node_channels(channelId, nodeId);.CREATE INDEX IF NOT EXISTS idx_node_channels_node ON node_channels(nodeId, channelId);.CREATE INDEX IF NOT EXISTS idx_node_assets_node_asset ON node_assets(nodeId, assetId);.CREATE INDEX IF NOT EXISTS idx_node_assets_asset_node ON node_assets(assetId, nodeId);.CREATE UNIQUE INDEX IF NOT EXISTS idx_node_revisions_version ON node_revisions(nodeId, version);.CREATE INDEX IF NOT EXISTS idx_assets_system_created ON assets(isSystemVariant, createdAt DESC);.CREATE INDEX IF NOT EXISTS idx_assets_system_mime ON assets(isSystemVariant, mimeType);.CREATE INDEX IF NOT EXISTS idx_assets_deleted ON assets(deletedAt);.CREATE INDEX IF NOT EXISTS idx_assets_parent ON assets(parentAssetId);.CREATE INDEX IF NOT EXISTS idx_taxonomy_terms_tax ON taxonomy_terms(taxonomy);.CREATE INDEX IF NOT EXISTS idx_node_terms_node ON node_terms(nodeId);.CREATE INDEX IF NOT EXISTS idx_node_terms_term ON node_terms(termId);.CREATE INDEX IF NOT EXISTS idx_node_terms_node_term ON node_terms(nodeId, termId);.CREATE INDEX IF NOT EXISTS idx_node_terms_term_node ON node_terms(termId, nodeId);.CREATE INDEX IF NOT EXISTS idx_node_relations_source ON node_relations(sourceNodeId);.CREATE INDEX IF NOT EXISTS idx_node_relations_target ON node_relations(targetNodeId);.CREATE INDEX IF NOT EXISTS idx_node_routes_lookup ON node_routes(path, channelId);.CREATE INDEX IF NOT EXISTS idx_node_routes_node ON node_routes(nodeId);.CREATE INDEX IF NOT EXISTS idx_content_nodes_public_feed ON content_nodes(contentType, isHidden, status, startShowingAt, stopShowingAt, updatedAt DESC);".split(".");
|
|
22213
22223
|
function Ab(e) {
|
|
22214
22224
|
let t = /* @__PURE__ */ new Set();
|
|
22215
22225
|
function n(e) {
|
|
22216
|
-
if (!(typeof e != "object" || !e)) for (let [r, i] of Object.entries(e)) typeof i == "object" && i && (i.index === !0 && r !== "id" && r !== "slug" && r !== "contentType" && t.add(`CREATE INDEX IF NOT EXISTS idx_content_nodes_${r} ON content_nodes (json_extract(dataJson, '$.${r}'));`), n(i));
|
|
22226
|
+
if (!(typeof e != "object" || !e)) for (let [r, i] of Object.entries(e)) typeof i == "object" && i && (i.index === !0 && r !== "id" && r !== "slug" && r !== "contentType" && r !== "startShowingAt" && r !== "stopShowingAt" && t.add(`CREATE INDEX IF NOT EXISTS idx_content_nodes_${r} ON content_nodes (json_extract(dataJson, '$.${r}'));`), n(i));
|
|
22217
22227
|
}
|
|
22218
22228
|
return n(e), Array.from(t);
|
|
22219
22229
|
}
|
|
@@ -22240,6 +22250,18 @@ async function Mb(e, t) {
|
|
|
22240
22250
|
if (!n.has("hasUnpublishedChanges")) try {
|
|
22241
22251
|
await e.prepare("ALTER TABLE \"content_nodes\" ADD COLUMN hasUnpublishedChanges INTEGER DEFAULT 0;").run();
|
|
22242
22252
|
} catch {}
|
|
22253
|
+
let t = !1;
|
|
22254
|
+
if (!n.has("startShowingAt")) try {
|
|
22255
|
+
await e.prepare("ALTER TABLE \"content_nodes\" ADD COLUMN startShowingAt TEXT;").run(), t = !0;
|
|
22256
|
+
} catch {}
|
|
22257
|
+
if (!n.has("stopShowingAt")) try {
|
|
22258
|
+
await e.prepare("ALTER TABLE \"content_nodes\" ADD COLUMN stopShowingAt TEXT;").run(), t = !0;
|
|
22259
|
+
} catch {}
|
|
22260
|
+
if (t) try {
|
|
22261
|
+
console.log("[Schema Sync] Migrating visibility dates out of JSON payload..."), await e.prepare("\n UPDATE content_nodes \n SET \n startShowingAt = json_extract(dataJson, '$.startShowingAt'),\n stopShowingAt = json_extract(dataJson, '$.stopShowingAt')\n WHERE json_extract(dataJson, '$.startShowingAt') IS NOT NULL \n OR json_extract(dataJson, '$.stopShowingAt') IS NOT NULL;\n ").run(), console.log("[Schema Sync] Date migration complete.");
|
|
22262
|
+
} catch (e) {
|
|
22263
|
+
console.error("[Schema Sync] Failed to backfill dates:", e);
|
|
22264
|
+
}
|
|
22243
22265
|
}
|
|
22244
22266
|
if (t === "assets") {
|
|
22245
22267
|
if (!n.has("parentAssetId")) try {
|
|
@@ -23002,7 +23024,9 @@ var Fb = { hasSubscribers: !1 }, Ib = Fb, Lb = Fb, Rb = typeof performance == "o
|
|
|
23002
23024
|
}, Qb = null;
|
|
23003
23025
|
function $b(e) {
|
|
23004
23026
|
let t = process.env.CACHE_DRIVER || "lru";
|
|
23005
|
-
|
|
23027
|
+
if (t === "none" || t === "off" || t === "false") return new Zb();
|
|
23028
|
+
let n = e?.env?.CACHE_KV || e?.env?.CMS_CACHE_KV;
|
|
23029
|
+
return n ? new Xb(n) : t === "lru" ? (Qb ||= new Yb(), Qb) : new Zb();
|
|
23006
23030
|
}
|
|
23007
23031
|
//#endregion
|
|
23008
23032
|
//#region server/storage/local.ts
|
|
@@ -23573,6 +23597,7 @@ var mx = class {
|
|
|
23573
23597
|
return {
|
|
23574
23598
|
zoneId: e.env?.CLOUDFLARE_ZONE_ID || this.env.CLOUDFLARE_ZONE_ID,
|
|
23575
23599
|
apiToken: e.env?.CLOUDFLARE_API_TOKEN || this.env.CLOUDFLARE_API_TOKEN,
|
|
23600
|
+
purgeToken: e.env?.FRONTEND_API_SECRET || this.env.FRONTEND_API_SECRET || e.env?.CLOUDFLARE_API_TOKEN || this.env.CLOUDFLARE_API_TOKEN,
|
|
23576
23601
|
frontendUrl: (e.env?.PUBLIC_FRONTEND_URL || this.env.PUBLIC_FRONTEND_URL || "http://localhost:4321").replace(/\/+$/, ""),
|
|
23577
23602
|
cdnDomain: t ? t.replace(/^https?:\/\//, "").replace(/\/+$/, "") : "localhost:8787",
|
|
23578
23603
|
frontendWorker: e.env?.FRONTEND_WORKER || this.env.FRONTEND_WORKER,
|
|
@@ -23600,7 +23625,7 @@ var mx = class {
|
|
|
23600
23625
|
return r && n && r.startsWith(`https://${n}/`) && !r.includes("/media/") && (r = r.replace(`https://${n}/`, `https://${n}/media/`)), r;
|
|
23601
23626
|
}
|
|
23602
23627
|
async callAstroPurge(e, t, n) {
|
|
23603
|
-
let {
|
|
23628
|
+
let { purgeToken: r, frontendUrl: i, frontendWorker: a, disableCachePurge: o } = this.getEnv(e);
|
|
23604
23629
|
if (o === "true" || o === !0 || o === "1") return new Response(JSON.stringify({ skipped: !0 }), { status: 200 });
|
|
23605
23630
|
let s = (n || i).replace(/\/+$/, ""), c = `${s}/api/purge`, l = { "Content-Type": "application/json" };
|
|
23606
23631
|
if (r && (l.Authorization = `Bearer ${r}`), a && typeof a.fetch == "function") try {
|
|
@@ -23630,8 +23655,21 @@ var mx = class {
|
|
|
23630
23655
|
try {
|
|
23631
23656
|
let a = $b(e);
|
|
23632
23657
|
if (n) {
|
|
23633
|
-
let e = t.prepare("SELECT treeId FROM tree_nodes WHERE contentId =
|
|
23634
|
-
for (let e of
|
|
23658
|
+
let e = t.prepare("\n SELECT DISTINCT\n t.id AS treeId,\n t.key AS treeKey,\n t.dataJson AS treeDataJson,\n c.id AS channelId,\n c.key AS channelKey,\n c.defaultLanguage AS channelDefaultLanguage\n FROM tree_nodes tn\n JOIN trees t ON t.id = tn.treeId\n LEFT JOIN channel_trees ct ON ct.treeId = t.id\n LEFT JOIN channels c ON c.id = ct.channelId\n WHERE tn.contentId = ?\n "), r = typeof e.all == "function" ? await e.all(n) : await e.bind(n).all(), o = Array.isArray(r) ? r : r?.results || [], s = /* @__PURE__ */ new Set();
|
|
23659
|
+
for (let e of o) {
|
|
23660
|
+
let t = /* @__PURE__ */ new Set(["default", "all"]);
|
|
23661
|
+
e.channelId !== null && e.channelId !== void 0 && t.add(String(e.channelId)), e.channelKey && t.add(String(e.channelKey));
|
|
23662
|
+
let n = /* @__PURE__ */ new Set();
|
|
23663
|
+
e.treeId !== null && e.treeId !== void 0 && n.add(String(e.treeId)), e.treeKey && n.add(String(e.treeKey));
|
|
23664
|
+
let r = /* @__PURE__ */ new Set(["default"]);
|
|
23665
|
+
i && r.add(i.trim()), e.channelDefaultLanguage && r.add(String(e.channelDefaultLanguage).trim());
|
|
23666
|
+
try {
|
|
23667
|
+
let t = typeof e.treeDataJson == "string" ? JSON.parse(e.treeDataJson) : e.treeDataJson;
|
|
23668
|
+
(t?.defaultLanguage || t?.language) && r.add(String(t.defaultLanguage || t.language).trim());
|
|
23669
|
+
} catch {}
|
|
23670
|
+
for (let e of t) for (let t of n) for (let n of r) s.add(`tree:${e}:${t}:${n || "default"}`);
|
|
23671
|
+
}
|
|
23672
|
+
await Promise.all(Array.from(s, (e) => a.delete(e)));
|
|
23635
23673
|
}
|
|
23636
23674
|
if (r) {
|
|
23637
23675
|
let e = r.replace(/^\/+|\/+$/g, ""), o = ["default", "1"];
|
|
@@ -23645,9 +23683,37 @@ var mx = class {
|
|
|
23645
23683
|
console.warn("[CacheManager] Failed to purge internal worker cache:", e);
|
|
23646
23684
|
}
|
|
23647
23685
|
}
|
|
23686
|
+
async purgeVisibilityChange(e, t, n) {
|
|
23687
|
+
try {
|
|
23688
|
+
let r = t.prepare("SELECT slug, language FROM content_nodes WHERE id = ?"), i = typeof r.get == "function" ? await r.get(n) : (await r.bind(n).all())?.results?.[0];
|
|
23689
|
+
await this.purgeInternalWorkerCache(e, t, n, i?.slug, i?.language);
|
|
23690
|
+
let a = await this.callAstroPurge(e, { purge_everything: !0 }), o = await a.json().catch(() => ({}));
|
|
23691
|
+
if (!a.ok || o?.success === !1 || o?.skipped) return console.warn(`[CacheManager] Visibility purge failed at Astro Worker (${a.status}).`), !1;
|
|
23692
|
+
let { zoneId: s, apiToken: c } = this.getEnv(e), l = this.isLocalEnv(e);
|
|
23693
|
+
if (s && c && !this.isLocalEnv(e)) {
|
|
23694
|
+
let e = await fetch(`https://api.cloudflare.com/client/v4/zones/${s}/purge_cache`, {
|
|
23695
|
+
method: "POST",
|
|
23696
|
+
headers: {
|
|
23697
|
+
Authorization: `Bearer ${c}`,
|
|
23698
|
+
"Content-Type": "application/json"
|
|
23699
|
+
},
|
|
23700
|
+
body: JSON.stringify({ purge_everything: !0 })
|
|
23701
|
+
}), t = await e.json().catch(() => ({}));
|
|
23702
|
+
l = e.ok && t?.success === !0, l || console.warn("[CacheManager] Visibility purge failed at Cloudflare Zone cache:", JSON.stringify(t));
|
|
23703
|
+
} else this.isLocalEnv(e) || console.warn("[CacheManager] Visibility purge lacks CLOUDFLARE_ZONE_ID or CLOUDFLARE_API_TOKEN.");
|
|
23704
|
+
return this.dispatch(e, this.warmAllPublishedPages(e, t)), l;
|
|
23705
|
+
} catch (e) {
|
|
23706
|
+
return console.warn("[CacheManager] Visibility cache purge failed:", e), !1;
|
|
23707
|
+
}
|
|
23708
|
+
}
|
|
23648
23709
|
purgeNode(e, t, n, r = !1, i = []) {
|
|
23649
23710
|
if (r) {
|
|
23650
|
-
console.log(`[CacheManager] Structural change detected on nodeId ${n}. Escalating to Global Purge.`)
|
|
23711
|
+
console.log(`[CacheManager] Structural change detected on nodeId ${n}. Escalating to Global Purge.`);
|
|
23712
|
+
let r = (async () => {
|
|
23713
|
+
let r = t.prepare("SELECT slug, language FROM content_nodes WHERE id = ?"), i = typeof r.get == "function" ? await r.get(n) : (await r.bind(n).all())?.results?.[0];
|
|
23714
|
+
await this.purgeInternalWorkerCache(e, t, n, i?.slug, i?.language), await this.purgeGlobalCacheDirect(e, t);
|
|
23715
|
+
})();
|
|
23716
|
+
this.dispatch(e, r);
|
|
23651
23717
|
return;
|
|
23652
23718
|
}
|
|
23653
23719
|
let a = (async () => {
|
|
@@ -23733,8 +23799,12 @@ var mx = class {
|
|
|
23733
23799
|
}
|
|
23734
23800
|
async purgeGlobalCacheDirect(e, t) {
|
|
23735
23801
|
try {
|
|
23736
|
-
let { zoneId: n, apiToken: r } = this.getEnv(e);
|
|
23737
|
-
if (!
|
|
23802
|
+
let { zoneId: n, apiToken: r } = this.getEnv(e), i = await this.callAstroPurge(e, { purge_everything: !0 });
|
|
23803
|
+
if (!i.ok) {
|
|
23804
|
+
let e = await i.text().catch(() => "");
|
|
23805
|
+
console.warn(`[CacheManager] Astro global purge failed (${i.status}): ${e.slice(0, 500)}`);
|
|
23806
|
+
return;
|
|
23807
|
+
}
|
|
23738
23808
|
if (n && r && !this.isLocalEnv(e)) try {
|
|
23739
23809
|
let e = await (await fetch(`https://api.cloudflare.com/client/v4/zones/${n}/purge_cache`, {
|
|
23740
23810
|
method: "POST",
|
|
@@ -23876,8 +23946,9 @@ async function hx(e) {
|
|
|
23876
23946
|
await e.prepare("DELETE FROM node_routes").run();
|
|
23877
23947
|
let h = Array.from(p.values());
|
|
23878
23948
|
if (h.length === 0) return;
|
|
23879
|
-
|
|
23880
|
-
|
|
23949
|
+
let g = [];
|
|
23950
|
+
for (let e = 0; e < h.length; e += 15) {
|
|
23951
|
+
let t = h.slice(e, e + 15), n = t.map(() => "(?, ?, ?, ?, ?, ?)").join(","), r = t.flatMap((e) => [
|
|
23881
23952
|
e.path,
|
|
23882
23953
|
e.channelId,
|
|
23883
23954
|
e.nodeId,
|
|
@@ -23885,10 +23956,17 @@ async function hx(e) {
|
|
|
23885
23956
|
e.isCanonical,
|
|
23886
23957
|
e.redirectUrl ?? null
|
|
23887
23958
|
]);
|
|
23888
|
-
|
|
23889
|
-
|
|
23890
|
-
|
|
23891
|
-
|
|
23959
|
+
g.push({
|
|
23960
|
+
placeholders: n,
|
|
23961
|
+
params: r
|
|
23962
|
+
});
|
|
23963
|
+
}
|
|
23964
|
+
for (let t = 0; t < g.length; t += 50) {
|
|
23965
|
+
let n = g.slice(t, t + 50);
|
|
23966
|
+
await Promise.all(n.map((t) => e.prepare(`
|
|
23967
|
+
INSERT INTO node_routes (path, channelId, nodeId, treeId, isCanonical, redirectUrl)
|
|
23968
|
+
VALUES ${t.placeholders}
|
|
23969
|
+
`).run(...t.params)));
|
|
23892
23970
|
}
|
|
23893
23971
|
console.log(`[Route Generator] Successfully built ${h.length} enterprise routes.`);
|
|
23894
23972
|
} catch (e) {
|
|
@@ -23898,7 +23976,25 @@ async function hx(e) {
|
|
|
23898
23976
|
//#endregion
|
|
23899
23977
|
//#region server/routes/admin/nodes.ts
|
|
23900
23978
|
var gx = new e();
|
|
23901
|
-
|
|
23979
|
+
function _x(e, t, n = []) {
|
|
23980
|
+
let r = new mx(e.env), i = (async () => {
|
|
23981
|
+
for (let i of n) {
|
|
23982
|
+
let n = t.prepare("SELECT slug, language FROM content_nodes WHERE id = ?"), a = typeof n.get == "function" ? await n.get(i) : (await n.bind(i).all())?.results?.[0];
|
|
23983
|
+
await r.purgeInternalWorkerCache(e, t, i, a?.slug, a?.language);
|
|
23984
|
+
}
|
|
23985
|
+
await hx(t), await r.purgeGlobalCacheDirect(e, t);
|
|
23986
|
+
})().catch((e) => {
|
|
23987
|
+
console.error("[Node Routes] Background rebuild/purge failed:", e);
|
|
23988
|
+
});
|
|
23989
|
+
try {
|
|
23990
|
+
let t = e.executionCtx;
|
|
23991
|
+
if (t && typeof t.waitUntil == "function") {
|
|
23992
|
+
t.waitUntil(i);
|
|
23993
|
+
return;
|
|
23994
|
+
}
|
|
23995
|
+
} catch {}
|
|
23996
|
+
}
|
|
23997
|
+
async function vx(e, t, n = []) {
|
|
23902
23998
|
let r = e.prepare(t);
|
|
23903
23999
|
if (typeof r.bind == "function") {
|
|
23904
24000
|
let e = await r.bind(...n).all();
|
|
@@ -23910,75 +24006,50 @@ async function _x(e, t, n = []) {
|
|
|
23910
24006
|
}
|
|
23911
24007
|
return [];
|
|
23912
24008
|
}
|
|
23913
|
-
async function
|
|
24009
|
+
async function yx(e, t, n = []) {
|
|
23914
24010
|
let r = e.prepare(t);
|
|
23915
24011
|
if (typeof r.bind == "function") return r.bind(...n).run();
|
|
23916
24012
|
if (typeof r.run == "function") return r.run(...n);
|
|
23917
24013
|
}
|
|
23918
|
-
function
|
|
24014
|
+
function bx(e) {
|
|
23919
24015
|
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;
|
|
23920
24016
|
}
|
|
23921
|
-
function
|
|
24017
|
+
function xx(e) {
|
|
23922
24018
|
return +(e === !0 || e === 1 || e === "1" || e === "true");
|
|
23923
24019
|
}
|
|
23924
|
-
function
|
|
24020
|
+
function Sx(e) {
|
|
23925
24021
|
if (e == null || e === "null" || e === "" || typeof e == "string" && e.startsWith("draft-")) return null;
|
|
23926
24022
|
let t = Number(e);
|
|
23927
24023
|
return isNaN(t) ? null : t;
|
|
23928
24024
|
}
|
|
23929
|
-
function
|
|
24025
|
+
function Cx(e) {
|
|
23930
24026
|
let t = { ...e };
|
|
23931
24027
|
delete t.language, delete t.defaultLanguage;
|
|
23932
|
-
for (let e of [
|
|
23933
|
-
"id",
|
|
23934
|
-
"treeNodeId",
|
|
23935
|
-
"isNew",
|
|
23936
|
-
"_isTreeDraft",
|
|
23937
|
-
"_draftParentId",
|
|
23938
|
-
"nodeType",
|
|
23939
|
-
"contentType",
|
|
23940
|
-
"title",
|
|
23941
|
-
"slug",
|
|
23942
|
-
"path",
|
|
23943
|
-
"routePath",
|
|
23944
|
-
"hidden",
|
|
23945
|
-
"is_hidden",
|
|
23946
|
-
"isHidden",
|
|
23947
|
-
"status",
|
|
23948
|
-
"createdById",
|
|
23949
|
-
"updatedById",
|
|
23950
|
-
"draftDataJson",
|
|
23951
|
-
"publishedDataJson",
|
|
23952
|
-
"publishedAt",
|
|
23953
|
-
"deletedAt",
|
|
23954
|
-
"channelNames",
|
|
23955
|
-
"treeNames",
|
|
23956
|
-
"hasUnpublishedChanges"
|
|
23957
|
-
]) delete t[e];
|
|
24028
|
+
for (let e of /* @__PURE__ */ "id.treeNodeId.isNew._isTreeDraft._draftParentId.nodeType.contentType.title.slug.path.routePath.hidden.is_hidden.isHidden.startShowingAt.stopShowingAt.status.createdById.updatedById.draftDataJson.publishedDataJson.publishedAt.deletedAt.channelNames.treeNames.hasUnpublishedChanges".split(".")) delete t[e];
|
|
23958
24029
|
return t;
|
|
23959
24030
|
}
|
|
23960
|
-
function
|
|
23961
|
-
return e ? typeof e == "string" ? (e.startsWith("ast_") && t.add(e), t) : Array.isArray(e) ? (e.forEach((e) =>
|
|
24031
|
+
function wx(e, t = /* @__PURE__ */ new Set()) {
|
|
24032
|
+
return e ? typeof e == "string" ? (e.startsWith("ast_") && t.add(e), t) : Array.isArray(e) ? (e.forEach((e) => wx(e, t)), t) : (typeof e == "object" && Object.values(e).forEach((e) => wx(e, t)), t) : t;
|
|
23962
24033
|
}
|
|
23963
|
-
function
|
|
24034
|
+
function Tx(e, t) {
|
|
23964
24035
|
if (!e) return !0;
|
|
23965
|
-
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 &&
|
|
23966
|
-
return n || r || i || a ||
|
|
24036
|
+
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 && xx(t.isHidden) !== xx(e.isHidden), a = t.status !== void 0 && t.status !== e.status, o = t.startShowingAt !== void 0 && t.startShowingAt !== e.startShowingAt, s = t.stopShowingAt !== void 0 && t.stopShowingAt !== e.stopShowingAt, c = typeof e.draftDataJson == "string" ? JSON.parse(e.draftDataJson || "{}") : e.draftDataJson || {}, l = t.sanitizedFields || {}, u = l.menuTitle !== void 0 && l.menuTitle !== c.menuTitle;
|
|
24037
|
+
return n || r || i || a || o || s || u;
|
|
23967
24038
|
}
|
|
23968
|
-
async function
|
|
24039
|
+
async function Ex(e, t, n) {
|
|
23969
24040
|
for (let r of n) {
|
|
23970
|
-
let n = (await
|
|
23971
|
-
if (n && n.isSystemVariant && !((await
|
|
24041
|
+
let n = (await vx(e, "\n SELECT id, storageKeyPrivate, isSystemVariant, parentAssetId, filename\n FROM assets WHERE id = ?\n ", [r]))[0];
|
|
24042
|
+
if (n && n.isSystemVariant && !((await vx(e, "SELECT 1 FROM node_assets WHERE assetId = ? LIMIT 1", [n.id])).length > 0)) {
|
|
23972
24043
|
if (n.storageKeyPrivate) try {
|
|
23973
24044
|
await t.delete(n.storageKeyPrivate);
|
|
23974
24045
|
} catch (e) {
|
|
23975
24046
|
console.warn(`[Asset Cleanup] Failed to delete crop ${n.storageKeyPrivate}:`, e);
|
|
23976
24047
|
}
|
|
23977
|
-
await
|
|
24048
|
+
await yx(e, "DELETE FROM node_assets WHERE assetId = ?", [n.id]), await yx(e, "DELETE FROM assets WHERE id = ?", [n.id]);
|
|
23978
24049
|
}
|
|
23979
24050
|
}
|
|
23980
24051
|
}
|
|
23981
|
-
async function
|
|
24052
|
+
async function Dx(e, t, n) {
|
|
23982
24053
|
let r = {}, i = null;
|
|
23983
24054
|
if (t) {
|
|
23984
24055
|
let a = await e.prepare("\n WITH RECURSIVE ancestor_path(id, parentId, draftDataJson, dataJson, level) AS (\n SELECT t.contentId as 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.contentId = ? AND t.treeId = ?\n UNION ALL\n SELECT t.contentId as 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.contentId = ap.parentId AND t.treeId = ?\n )\n SELECT draftDataJson, dataJson FROM ancestor_path ORDER BY level ASC\n ").all(t, n, n), o = Array.isArray(a) ? a : a?.results || [];
|
|
@@ -24027,6 +24098,8 @@ gx.get("/", async (e) => {
|
|
|
24027
24098
|
nodeType: i.contentType,
|
|
24028
24099
|
contentType: i.contentType,
|
|
24029
24100
|
isHidden: !!i.isHidden,
|
|
24101
|
+
startShowingAt: i.startShowingAt || null,
|
|
24102
|
+
stopShowingAt: i.stopShowingAt || null,
|
|
24030
24103
|
status: i.status || "draft",
|
|
24031
24104
|
publishedAt: i.publishedAt || null,
|
|
24032
24105
|
hasUnpublishedChanges: s,
|
|
@@ -24039,7 +24112,7 @@ gx.get("/", async (e) => {
|
|
|
24039
24112
|
if (l) try {
|
|
24040
24113
|
let n = typeof l == "string" ? JSON.parse(l) : l, a = await t.prepare("SELECT contentId as treeNodeId, treeId, parentId FROM tree_nodes WHERE contentId = ? LIMIT 1").get(r), o = px(e.env?.BUNDLED_DEFINITIONS).nodes?.[i.contentType] || {}, s = n.layoutId || null;
|
|
24041
24114
|
if (a) {
|
|
24042
|
-
let { resolvedLayoutId: e, inheritedFields: r } = await
|
|
24115
|
+
let { resolvedLayoutId: e, inheritedFields: r } = await Dx(t, a.parentId, a.treeId);
|
|
24043
24116
|
(s === "inherit" || !s) && (s = e);
|
|
24044
24117
|
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);
|
|
24045
24118
|
}
|
|
@@ -24054,7 +24127,7 @@ gx.get("/", async (e) => {
|
|
|
24054
24127
|
let r = t.allowedLayouts;
|
|
24055
24128
|
return r ? typeof r == "string" ? r === e : !Array.isArray(r) || r.length === 0 || r.includes(e) : !0;
|
|
24056
24129
|
})(s) && (s = null), (s === "inherit" || !s) && (s = o.defaultLayout || null);
|
|
24057
|
-
let u = await fx(t,
|
|
24130
|
+
let u = await fx(t, Cx(n));
|
|
24058
24131
|
Object.assign(c, u), c.resolvedLayoutId = s;
|
|
24059
24132
|
} catch {}
|
|
24060
24133
|
let u = await t.prepare("SELECT channelId FROM node_channels WHERE nodeId = ?").all(r);
|
|
@@ -24082,7 +24155,7 @@ gx.get("/", async (e) => {
|
|
|
24082
24155
|
blocks: m
|
|
24083
24156
|
});
|
|
24084
24157
|
}
|
|
24085
|
-
let m = [], h = [o ? "
|
|
24158
|
+
let m = [], h = [o ? "cn.deletedAt IS NOT NULL" : "cn.deletedAt IS NULL"];
|
|
24086
24159
|
if (a && a !== "all" && (h.push("EXISTS (SELECT 1 FROM node_channels nc WHERE nc.nodeId = cn.id AND nc.channelId = ?)"), m.push(Number(a) || a)), s && (h.push("\n EXISTS (\n SELECT 1 FROM node_assets na_f \n JOIN assets a_f ON a_f.id = na_f.assetId\n WHERE na_f.nodeId = cn.id \n AND (na_f.assetId = ? OR a_f.parentAssetId = ? OR a_f.id = (SELECT parentAssetId FROM assets WHERE id = ?))\n )\n "), m.push(s, s, s)), r && r !== "all") {
|
|
24087
24160
|
let e = r.split(",").map((e) => e.trim()).filter(Boolean);
|
|
24088
24161
|
e.length > 0 && (h.push(`cn.contentType IN (${e.map(() => "?").join(",")})`), m.push(...e));
|
|
@@ -24159,6 +24232,8 @@ gx.get("/", async (e) => {
|
|
|
24159
24232
|
contentType: e.contentType,
|
|
24160
24233
|
nodeType: e.contentType,
|
|
24161
24234
|
isHidden: !!e.isHidden,
|
|
24235
|
+
startShowingAt: e.startShowingAt || null,
|
|
24236
|
+
stopShowingAt: e.stopShowingAt || null,
|
|
24162
24237
|
status: e.status || "draft",
|
|
24163
24238
|
publishedAt: e.publishedAt || null,
|
|
24164
24239
|
hasUnpublishedChanges: n,
|
|
@@ -24176,7 +24251,7 @@ gx.get("/", async (e) => {
|
|
|
24176
24251
|
otherCount: e.otherCount || 0
|
|
24177
24252
|
}, i = e.draftDataJson || e.dataJson;
|
|
24178
24253
|
if (i) try {
|
|
24179
|
-
let e = typeof i == "string" ? JSON.parse(i) : i, n = await fx(t,
|
|
24254
|
+
let e = typeof i == "string" ? JSON.parse(i) : i, n = await fx(t, Cx(e));
|
|
24180
24255
|
Object.assign(r, n);
|
|
24181
24256
|
} catch {}
|
|
24182
24257
|
return r;
|
|
@@ -24189,34 +24264,34 @@ gx.get("/", async (e) => {
|
|
|
24189
24264
|
limit: f
|
|
24190
24265
|
});
|
|
24191
24266
|
}), gx.post("/", async (e) => {
|
|
24192
|
-
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,
|
|
24193
|
-
if (
|
|
24194
|
-
let e = await t.prepare("SELECT dataJson FROM trees WHERE id = ? OR key = ? LIMIT 1").get(Number(
|
|
24267
|
+
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, startShowingAt: m, stopShowingAt: h, blocks: g, channels: _, trees: v, ...y } = r, { cleanedData: b, assetRefs: x, termRefs: S, nodeRefs: C } = ax(Cx(y)), w = xx(d === void 0 ? f === void 0 ? p : f : d), T = l || u || "page", ee = e.get("user")?.id || null, E = typeof c == "string" && c.trim() !== "" ? c.trim() : null, D = v && Array.isArray(v) && v.length > 0 ? v[0] : null, te = D ? D.treeId || D.id : null, O = null;
|
|
24268
|
+
if (te) {
|
|
24269
|
+
let e = await t.prepare("SELECT dataJson FROM trees WHERE id = ? OR key = ? LIMIT 1").get(Number(te) || -1, String(te));
|
|
24195
24270
|
if (e?.dataJson) try {
|
|
24196
24271
|
let t = typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson;
|
|
24197
|
-
|
|
24272
|
+
O = t.defaultLanguage?.trim() || t.language?.trim() || null;
|
|
24198
24273
|
} catch {}
|
|
24199
24274
|
}
|
|
24200
|
-
if (!
|
|
24201
|
-
let e = typeof
|
|
24275
|
+
if (!O && _ && Array.isArray(_) && _.length > 0) {
|
|
24276
|
+
let e = typeof _[0] == "object" ? _[0].id : _[0];
|
|
24202
24277
|
if (e && e !== "all") {
|
|
24203
24278
|
let n = await t.prepare("SELECT defaultLanguage, dataJson FROM channels WHERE id = ? LIMIT 1").get(Number(e));
|
|
24204
24279
|
if (n) {
|
|
24205
|
-
if (n.defaultLanguage)
|
|
24280
|
+
if (n.defaultLanguage) O = n.defaultLanguage.trim();
|
|
24206
24281
|
else if (n.dataJson) try {
|
|
24207
24282
|
let e = typeof n.dataJson == "string" ? JSON.parse(n.dataJson) : n.dataJson;
|
|
24208
|
-
|
|
24283
|
+
O = e.defaultLanguage?.trim() || e.language?.trim() || null;
|
|
24209
24284
|
} catch {}
|
|
24210
24285
|
}
|
|
24211
24286
|
}
|
|
24212
24287
|
}
|
|
24213
|
-
|
|
24214
|
-
let
|
|
24215
|
-
if (
|
|
24288
|
+
E && O && E === O && (E = null);
|
|
24289
|
+
let k = a, A = /* @__PURE__ */ new Set(), ne = !1, j = "draft", re = 0, ie = s === void 0 ? null : bx(s);
|
|
24290
|
+
if (ie) {
|
|
24216
24291
|
let n = [];
|
|
24217
|
-
if (
|
|
24292
|
+
if (v !== void 0 && Array.isArray(v) && v.length > 0) for (let e of v) n.push({
|
|
24218
24293
|
treeId: Number(e.treeId),
|
|
24219
|
-
parentId:
|
|
24294
|
+
parentId: Sx(e.parentId ?? e._draftParentId ?? null)
|
|
24220
24295
|
});
|
|
24221
24296
|
else if (a) {
|
|
24222
24297
|
let e = await t.prepare("SELECT treeId, parentId FROM tree_nodes WHERE contentId = ?").all(a), r = Array.isArray(e) ? e : e?.results || [];
|
|
@@ -24226,140 +24301,146 @@ gx.get("/", async (e) => {
|
|
|
24226
24301
|
});
|
|
24227
24302
|
}
|
|
24228
24303
|
for (let r of n) {
|
|
24229
|
-
let n = r.parentId === null ? "tn.parentId IS NULL" : "tn.parentId = ?", i = r.parentId === null ? [r.treeId,
|
|
24304
|
+
let n = r.parentId === null ? "tn.parentId IS NULL" : "tn.parentId = ?", i = r.parentId === null ? [r.treeId, ie] : [
|
|
24230
24305
|
r.treeId,
|
|
24231
24306
|
r.parentId,
|
|
24232
|
-
|
|
24307
|
+
ie
|
|
24233
24308
|
], o = `
|
|
24234
24309
|
SELECT cn.id FROM tree_nodes tn
|
|
24235
24310
|
INNER JOIN content_nodes cn ON tn.contentId = cn.id
|
|
24236
|
-
WHERE tn.treeId = ? AND ${n} AND cn.slug = ? AND
|
|
24311
|
+
WHERE tn.treeId = ? AND ${n} AND cn.slug = ? AND cn.deletedAt IS NULL
|
|
24237
24312
|
`;
|
|
24238
24313
|
if (a && (o += " AND cn.id != ?", i.push(a)), o += " LIMIT 1", await t.prepare(o).get(...i)) return e.json({
|
|
24239
|
-
error: `The slug '${
|
|
24314
|
+
error: `The slug '${ie}' is already in use by another page in this section.`,
|
|
24240
24315
|
field: "slug"
|
|
24241
24316
|
}, 409);
|
|
24242
24317
|
}
|
|
24243
24318
|
}
|
|
24244
24319
|
if (a) {
|
|
24245
|
-
let e = await t.prepare("SELECT title, slug, language, contentType, isHidden, draftDataJson, dataJson, publishedAt, status, hasUnpublishedChanges FROM content_nodes WHERE id = ?").get(a), n = o === void 0 ? e?.title || "Untitled" : o, r =
|
|
24246
|
-
|
|
24320
|
+
let e = await t.prepare("SELECT title, slug, language, contentType, isHidden, startShowingAt, stopShowingAt, draftDataJson, dataJson, publishedAt, status, hasUnpublishedChanges FROM content_nodes WHERE id = ?").get(a), n = o === void 0 ? e?.title || "Untitled" : o, r = ie ?? e?.slug ?? null, i = T || e?.contentType || "page", l = c === void 0 ? e?.language ?? null : E, u = w === void 0 ? xx(e?.isHidden) : w, d = m === void 0 ? e?.startShowingAt ?? null : m, f = h === void 0 ? e?.stopShowingAt ?? null : h;
|
|
24321
|
+
ne = Tx(e, {
|
|
24247
24322
|
title: n,
|
|
24248
24323
|
slug: r,
|
|
24249
24324
|
isHidden: u,
|
|
24250
|
-
|
|
24325
|
+
startShowingAt: d,
|
|
24326
|
+
stopShowingAt: f,
|
|
24327
|
+
sanitizedFields: b
|
|
24251
24328
|
});
|
|
24252
|
-
let
|
|
24329
|
+
let p = e?.draftDataJson || e?.dataJson || "{}";
|
|
24253
24330
|
try {
|
|
24254
|
-
|
|
24331
|
+
wx(typeof p == "string" ? JSON.parse(p) : p, A);
|
|
24255
24332
|
} catch {}
|
|
24256
|
-
let
|
|
24333
|
+
let _ = {};
|
|
24257
24334
|
try {
|
|
24258
|
-
|
|
24335
|
+
_ = JSON.parse(p);
|
|
24259
24336
|
} catch {}
|
|
24260
|
-
let
|
|
24337
|
+
let v = {
|
|
24261
24338
|
title: n,
|
|
24262
24339
|
slug: r,
|
|
24263
24340
|
contentType: i,
|
|
24264
24341
|
language: l,
|
|
24265
24342
|
isHidden: u,
|
|
24343
|
+
startShowingAt: d,
|
|
24344
|
+
stopShowingAt: f,
|
|
24345
|
+
...b
|
|
24346
|
+
}, y = JSON.stringify({
|
|
24347
|
+
..._,
|
|
24266
24348
|
...v
|
|
24267
|
-
},
|
|
24268
|
-
|
|
24269
|
-
|
|
24270
|
-
|
|
24271
|
-
if (o !== void 0 && o.trim() !== (e?.title || "Untitled") && (g = !0), s !== void 0 && j !== e?.slug && (g = !0), c !== void 0 && T !== e?.language && (g = !0), !g && Object.keys(v).length > 0) {
|
|
24272
|
-
for (let e of Object.keys(v)) if (JSON.stringify(v[e]) !== JSON.stringify(f[e])) {
|
|
24273
|
-
g = !0;
|
|
24349
|
+
}), x = !1;
|
|
24350
|
+
if (o !== void 0 && o.trim() !== (e?.title || "Untitled") && (x = !0), s !== void 0 && ie !== e?.slug && (x = !0), c !== void 0 && E !== e?.language && (x = !0), m !== void 0 && d !== e?.startShowingAt && (x = !0), h !== void 0 && f !== e?.stopShowingAt && (x = !0), !x && Object.keys(b).length > 0) {
|
|
24351
|
+
for (let e of Object.keys(b)) if (JSON.stringify(b[e]) !== JSON.stringify(_[e])) {
|
|
24352
|
+
x = !0;
|
|
24274
24353
|
break;
|
|
24275
24354
|
}
|
|
24276
24355
|
}
|
|
24277
|
-
if (!
|
|
24356
|
+
if (!x && g !== void 0) {
|
|
24278
24357
|
let e = await t.prepare("SELECT region, elementType, dataJson FROM content_blocks WHERE contentId = ? AND isDraft = 1 ORDER BY sortOrder ASC").all(a), n = Array.isArray(e) ? e : e?.results || [];
|
|
24279
|
-
if (
|
|
24280
|
-
else for (let e = 0; e <
|
|
24281
|
-
let t =
|
|
24358
|
+
if (g.length !== n.length) x = !0;
|
|
24359
|
+
else for (let e = 0; e < g.length; e++) {
|
|
24360
|
+
let t = g[e], r = n[e], i = t.componentId || t.elementType || "text-block", a = t.region || "content", o = { ...t.data || {} };
|
|
24282
24361
|
delete o._instanceId, delete o.blockId;
|
|
24283
24362
|
let s = {};
|
|
24284
24363
|
try {
|
|
24285
24364
|
s = JSON.parse(r.dataJson);
|
|
24286
24365
|
} catch {}
|
|
24287
24366
|
if (delete s._instanceId, delete s.blockId, i !== r.elementType || a !== r.region || JSON.stringify(o) !== JSON.stringify(s)) {
|
|
24288
|
-
|
|
24367
|
+
x = !0;
|
|
24289
24368
|
break;
|
|
24290
24369
|
}
|
|
24291
24370
|
}
|
|
24292
24371
|
}
|
|
24293
|
-
|
|
24294
|
-
let
|
|
24295
|
-
|
|
24296
|
-
let
|
|
24297
|
-
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(
|
|
24372
|
+
j = e?.status === "published" || e?.publishedAt ? "published" : "draft";
|
|
24373
|
+
let S = e?.hasUnpublishedChanges === 1 || e?.hasUnpublishedChanges === !0;
|
|
24374
|
+
re = x ? 1 : +!!S;
|
|
24375
|
+
let C = e?.publishedAt != null || e?.status === "published", D = C ? e.title : n, te = C ? e.slug : r, O = C ? e.contentType : i, k = C ? e.language : l, ae = C ? e.isHidden : u, oe = C ? e.startShowingAt : d, se = C ? e.stopShowingAt : f;
|
|
24376
|
+
await t.prepare("\n UPDATE content_nodes \n SET title = ?, slug = ?, language = ?, contentType = ?, isHidden = ?, startShowingAt = ?, stopShowingAt = ?, status = ?, draftDataJson = ?, hasUnpublishedChanges = ?, updatedById = ?, updatedAt = CURRENT_TIMESTAMP\n WHERE id = ?\n ").run(D, te, k, O, ae, oe, se, j, y, re, ee, a);
|
|
24298
24377
|
} else {
|
|
24299
|
-
|
|
24300
|
-
let e = {
|
|
24378
|
+
ne = !0;
|
|
24379
|
+
let e = m === void 0 ? null : m, n = h === void 0 ? null : h, r = {
|
|
24301
24380
|
title: o || "Untitled",
|
|
24302
|
-
slug:
|
|
24303
|
-
contentType:
|
|
24304
|
-
language:
|
|
24305
|
-
isHidden:
|
|
24306
|
-
|
|
24307
|
-
|
|
24308
|
-
|
|
24309
|
-
|
|
24310
|
-
|
|
24311
|
-
|
|
24312
|
-
|
|
24381
|
+
slug: ie,
|
|
24382
|
+
contentType: T,
|
|
24383
|
+
language: E,
|
|
24384
|
+
isHidden: w,
|
|
24385
|
+
startShowingAt: e,
|
|
24386
|
+
stopShowingAt: n,
|
|
24387
|
+
...b
|
|
24388
|
+
}, i = await t.prepare("\n INSERT INTO content_nodes (contentType, title, slug, language, isHidden, startShowingAt, stopShowingAt, status, draftDataJson, dataJson, hasUnpublishedChanges, createdById, updatedById)\n VALUES (?, ?, ?, ?, ?, ?, ?, 'draft', ?, NULL, 0, ?, ?)\n ").run(T, o || "Untitled", ie, E, w, e, n, JSON.stringify(r), ee, ee);
|
|
24389
|
+
k = Number(i.lastInsertRowid);
|
|
24390
|
+
}
|
|
24391
|
+
if (_ !== void 0 && Array.isArray(_) && k) {
|
|
24392
|
+
await t.prepare("DELETE FROM node_channels WHERE nodeId = ?").run(k);
|
|
24393
|
+
let e = [...new Set(_.map((e) => typeof e == "object" && e ? e.id || e.channelId : e))].filter((e) => e && e !== "all").map((e) => Number(e) || e);
|
|
24313
24394
|
if (e.length > 0) {
|
|
24314
|
-
let n = e.map(() => "(?, ?)").join(", "), r = e.flatMap((e) => [
|
|
24395
|
+
let n = e.map(() => "(?, ?)").join(", "), r = e.flatMap((e) => [k, e]);
|
|
24315
24396
|
await t.prepare(`INSERT OR IGNORE INTO node_channels (nodeId, channelId) VALUES ${n}`).run(...r);
|
|
24316
24397
|
}
|
|
24317
24398
|
}
|
|
24318
|
-
if (
|
|
24399
|
+
if (v !== void 0 && Array.isArray(v) && v.length > 0 && k) for (let e of v) {
|
|
24319
24400
|
if (!e || !e.treeId) continue;
|
|
24320
|
-
let n = Number(e.treeId) || e.treeId, r =
|
|
24321
|
-
a ? ((a.parentId !== r || a.sortOrder !== i) && (
|
|
24401
|
+
let n = Number(e.treeId) || e.treeId, r = Sx(e.parentId ?? e._draftParentId ?? null), i = typeof e.sortOrder == "number" ? e.sortOrder : 0, a = await t.prepare("SELECT contentId, parentId, sortOrder FROM tree_nodes WHERE treeId = ? AND contentId = ?").get(n, k);
|
|
24402
|
+
a ? ((a.parentId !== r || a.sortOrder !== i) && (ne = !0), await t.prepare("UPDATE tree_nodes SET parentId = ?, sortOrder = ? WHERE treeId = ? AND contentId = ?").run(r, i, n, k)) : (ne = !0, await t.prepare("INSERT INTO tree_nodes (treeId, contentId, parentId, sortOrder) VALUES (?, ?, ?, ?)").run(n, k, r, i));
|
|
24322
24403
|
}
|
|
24323
|
-
let
|
|
24324
|
-
if (
|
|
24325
|
-
await t.prepare("DELETE FROM content_blocks WHERE contentId = ? AND isDraft = 1").run(
|
|
24404
|
+
let ae = [], oe = [], se = [];
|
|
24405
|
+
if (g !== void 0 && Array.isArray(g) && k) {
|
|
24406
|
+
await t.prepare("DELETE FROM content_blocks WHERE contentId = ? AND isDraft = 1").run(k);
|
|
24326
24407
|
let e = [], n = [];
|
|
24327
|
-
for (let t = 0; t <
|
|
24328
|
-
let r =
|
|
24408
|
+
for (let t = 0; t < g.length; t++) {
|
|
24409
|
+
let r = g[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, termRefs: l, nodeRefs: u } = ax({
|
|
24329
24410
|
...a,
|
|
24330
24411
|
blockId: o,
|
|
24331
24412
|
_instanceId: o
|
|
24332
24413
|
});
|
|
24333
|
-
c.forEach((e) =>
|
|
24414
|
+
c.forEach((e) => ae.push({
|
|
24334
24415
|
...e,
|
|
24335
24416
|
fieldKey: `blocks[${t}].${e.fieldKey}`
|
|
24336
|
-
})), l.forEach((e) =>
|
|
24417
|
+
})), l.forEach((e) => oe.push({
|
|
24337
24418
|
...e,
|
|
24338
24419
|
fieldKey: `blocks[${t}].${e.fieldKey}`
|
|
24339
|
-
})), u.forEach((e) =>
|
|
24420
|
+
})), u.forEach((e) => se.push({
|
|
24340
24421
|
...e,
|
|
24341
24422
|
fieldKey: `blocks[${t}].${e.fieldKey}`
|
|
24342
24423
|
}));
|
|
24343
24424
|
let d = r.region !== void 0 && r.region !== null && String(r.region).trim() !== "" ? String(r.region) : "content";
|
|
24344
|
-
e.push("(?, ?, ?, ?, ?, 1)"), n.push(
|
|
24425
|
+
e.push("(?, ?, ?, ?, ?, 1)"), n.push(k, t, i, JSON.stringify(s), d);
|
|
24345
24426
|
}
|
|
24346
24427
|
e.length > 0 && await t.prepare(`INSERT INTO content_blocks (contentId, sortOrder, elementType, dataJson, region, isDraft) VALUES ${e.join(", ")}`).run(...n);
|
|
24347
24428
|
}
|
|
24348
|
-
if (
|
|
24349
|
-
let n = [...
|
|
24350
|
-
await ox(t,
|
|
24351
|
-
let a = new Set(n.map((e) => e.assetId)), o = new Set([...
|
|
24429
|
+
if (k) {
|
|
24430
|
+
let n = [...x, ...ae], r = [...S, ...oe], i = [...C, ...se];
|
|
24431
|
+
await ox(t, k, n), await sx(t, k, r), await cx(t, k, i);
|
|
24432
|
+
let a = new Set(n.map((e) => e.assetId)), o = new Set([...A].filter((e) => !a.has(e)));
|
|
24352
24433
|
if (o.size > 0) {
|
|
24353
24434
|
let { storage: n } = ix(e.env);
|
|
24354
|
-
await
|
|
24435
|
+
await Ex(t, n, o);
|
|
24355
24436
|
}
|
|
24356
24437
|
}
|
|
24357
24438
|
return await $b(e).clear(), e.json({
|
|
24358
24439
|
success: !0,
|
|
24359
|
-
id:
|
|
24360
|
-
status:
|
|
24361
|
-
hasUnpublishedChanges:
|
|
24362
|
-
isStructuralChange:
|
|
24440
|
+
id: k,
|
|
24441
|
+
status: j,
|
|
24442
|
+
hasUnpublishedChanges: re === 1 || j === "draft",
|
|
24443
|
+
isStructuralChange: ne
|
|
24363
24444
|
});
|
|
24364
24445
|
}), gx.post("/publish", async (e) => {
|
|
24365
24446
|
let t = e.get("db"), n = await e.req.json(), r = n.id || n.nodeId;
|
|
@@ -24374,34 +24455,36 @@ gx.get("/", async (e) => {
|
|
|
24374
24455
|
try {
|
|
24375
24456
|
c = typeof o.draftDataJson == "string" ? JSON.parse(o.draftDataJson) : o.draftDataJson || {};
|
|
24376
24457
|
} catch {}
|
|
24377
|
-
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
|
|
24378
|
-
await t.prepare("\n UPDATE content_nodes\n SET title = ?, slug = ?, language = ?, contentType = ?, isHidden = ?, publishedDataJson = ?, dataJson = ?, publishedAt = CURRENT_TIMESTAMP, status = 'published', hasUnpublishedChanges = 0, updatedById = ?, updatedAt = CURRENT_TIMESTAMP\n WHERE id = ?\n ").run(
|
|
24379
|
-
let
|
|
24380
|
-
if (
|
|
24458
|
+
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 = s.startShowingAt ?? o.startShowingAt ?? "", g = c.startShowingAt ?? n.startShowingAt ?? o.startShowingAt ?? "", _ = s.stopShowingAt ?? o.stopShowingAt ?? "", v = c.stopShowingAt ?? n.stopShowingAt ?? o.stopShowingAt ?? "", y = l !== "" && u !== "" && l !== u || d !== "" && f !== "" && d !== f || p !== "" && m !== "" && p !== m || h !== g || _ !== v, b = o.draftDataJson || o.dataJson || "{}", x = c.title ?? n.title ?? o.title ?? "Untitled", S = c.slug ?? n.slug ?? o.slug ?? null, C = c.language === void 0 ? o.language : c.language, w = c.contentType ?? o.contentType ?? "page", T = c.isHidden === void 0 ? o.isHidden : c.isHidden, ee = c.startShowingAt === void 0 ? n.startShowingAt === void 0 ? o.startShowingAt : n.startShowingAt : c.startShowingAt, E = c.stopShowingAt === void 0 ? n.stopShowingAt === void 0 ? o.stopShowingAt : n.stopShowingAt : c.stopShowingAt;
|
|
24459
|
+
await t.prepare("\n UPDATE content_nodes\n SET title = ?, slug = ?, language = ?, contentType = ?, isHidden = ?, startShowingAt = ?, stopShowingAt = ?, publishedDataJson = ?, dataJson = ?, publishedAt = CURRENT_TIMESTAMP, status = 'published', hasUnpublishedChanges = 0, updatedById = ?, updatedAt = CURRENT_TIMESTAMP\n WHERE id = ?\n ").run(x, S, C, w, T, ee, E, b, b, a, i), await t.prepare("DELETE FROM content_blocks WHERE contentId = ? AND isDraft = 0").run(i);
|
|
24460
|
+
let D = await t.prepare("SELECT * FROM content_blocks WHERE contentId = ? AND isDraft = 1 ORDER BY sortOrder ASC").all(i), te = Array.isArray(D) ? D : D?.results || [];
|
|
24461
|
+
if (te.length > 0) {
|
|
24381
24462
|
let e = [], n = [];
|
|
24382
|
-
for (let t of
|
|
24463
|
+
for (let t of te) {
|
|
24383
24464
|
let r = t.region !== void 0 && t.region !== null && String(t.region).trim() !== "" ? String(t.region) : "content";
|
|
24384
24465
|
e.push("(?, ?, ?, ?, ?, 0)"), n.push(i, t.sortOrder, t.elementType, t.dataJson, r);
|
|
24385
24466
|
}
|
|
24386
24467
|
await t.prepare(`INSERT INTO content_blocks (contentId, sortOrder, elementType, dataJson, region, isDraft) VALUES ${e.join(", ")}`).run(...n);
|
|
24387
24468
|
}
|
|
24388
|
-
let
|
|
24389
|
-
version:
|
|
24469
|
+
let O = ((await t.prepare("SELECT COUNT(*) as count FROM node_revisions WHERE nodeId = ?").get(i))?.count || 0) + 1, k = {
|
|
24470
|
+
version: O,
|
|
24390
24471
|
publishedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
24391
24472
|
node: {
|
|
24392
24473
|
...o,
|
|
24393
|
-
dataJson:
|
|
24474
|
+
dataJson: b
|
|
24394
24475
|
},
|
|
24395
|
-
blocks:
|
|
24476
|
+
blocks: te
|
|
24396
24477
|
};
|
|
24397
|
-
|
|
24478
|
+
await t.prepare("INSERT INTO node_revisions (nodeId, version, snapshotJson, createdById) VALUES (?, ?, ?, ?)").run(i, O, JSON.stringify(k), a), await $b(e).clear();
|
|
24479
|
+
let A = new mx(e.env);
|
|
24480
|
+
return y ? _x(e, t, [i]) : A.purgeNode(e, t, i, !1), e.json({
|
|
24398
24481
|
success: !0,
|
|
24399
24482
|
id: i,
|
|
24400
24483
|
status: "published",
|
|
24401
|
-
version:
|
|
24402
|
-
publishedAt:
|
|
24484
|
+
version: O,
|
|
24485
|
+
publishedAt: k.publishedAt,
|
|
24403
24486
|
hasUnpublishedChanges: !1,
|
|
24404
|
-
isStructuralChange:
|
|
24487
|
+
isStructuralChange: y
|
|
24405
24488
|
});
|
|
24406
24489
|
}), gx.post("/publish/batch", async (e) => {
|
|
24407
24490
|
let t = e.get("db"), n = await e.req.json(), r = n.ids;
|
|
@@ -24420,33 +24503,33 @@ gx.get("/", async (e) => {
|
|
|
24420
24503
|
try {
|
|
24421
24504
|
l = typeof s.draftDataJson == "string" ? JSON.parse(s.draftDataJson) : s.draftDataJson || {};
|
|
24422
24505
|
} catch {}
|
|
24423
|
-
let u = (c.title ?? s.title ?? "").trim(), d = (l.title ?? n.title ?? s.title ?? "").trim(), f = (c.slug ?? s.slug ?? "").trim(), p = (l.slug ?? n.slug ?? s.slug ?? "").trim(), m = (c.menuTitle ?? "").trim(), h = (l.menuTitle ?? "").trim();
|
|
24424
|
-
(u !== "" && d !== "" && u !== d || f !== "" && p !== "" && f !== p || m !== "" && h !== "" && m !== h) && (a = !0);
|
|
24425
|
-
let
|
|
24426
|
-
await t.prepare("\n UPDATE content_nodes\n SET title = ?, slug = ?, language = ?, contentType = ?, isHidden = ?, publishedDataJson = ?, dataJson = ?, publishedAt = CURRENT_TIMESTAMP, status = 'published', hasUnpublishedChanges = 0, updatedById = ?, updatedAt = CURRENT_TIMESTAMP\n WHERE id = ?\n ").run(
|
|
24427
|
-
let
|
|
24428
|
-
if (
|
|
24506
|
+
let u = (c.title ?? s.title ?? "").trim(), d = (l.title ?? n.title ?? s.title ?? "").trim(), f = (c.slug ?? s.slug ?? "").trim(), p = (l.slug ?? n.slug ?? s.slug ?? "").trim(), m = (c.menuTitle ?? "").trim(), h = (l.menuTitle ?? "").trim(), g = c.startShowingAt ?? s.startShowingAt ?? "", _ = l.startShowingAt ?? n.startShowingAt ?? s.startShowingAt ?? "", v = c.stopShowingAt ?? s.stopShowingAt ?? "", y = l.stopShowingAt ?? n.stopShowingAt ?? s.stopShowingAt ?? "";
|
|
24507
|
+
(u !== "" && d !== "" && u !== d || f !== "" && p !== "" && f !== p || m !== "" && h !== "" && m !== h || g !== _ || v !== y) && (a = !0);
|
|
24508
|
+
let b = s.draftDataJson || s.dataJson || "{}", x = l.title ?? n.title ?? s.title ?? "Untitled", S = l.slug ?? n.slug ?? s.slug ?? null, C = l.language === void 0 ? s.language : l.language, w = l.contentType ?? s.contentType ?? "page", T = l.isHidden === void 0 ? s.isHidden : l.isHidden, ee = l.startShowingAt === void 0 ? n.startShowingAt === void 0 ? s.startShowingAt : n.startShowingAt : l.startShowingAt, E = l.stopShowingAt === void 0 ? n.stopShowingAt === void 0 ? s.stopShowingAt : n.stopShowingAt : l.stopShowingAt;
|
|
24509
|
+
await t.prepare("\n UPDATE content_nodes\n SET title = ?, slug = ?, language = ?, contentType = ?, isHidden = ?, startShowingAt = ?, stopShowingAt = ?, publishedDataJson = ?, dataJson = ?, publishedAt = CURRENT_TIMESTAMP, status = 'published', hasUnpublishedChanges = 0, updatedById = ?, updatedAt = CURRENT_TIMESTAMP\n WHERE id = ?\n ").run(x, S, C, w, T, ee, E, b, b, i, r), await t.prepare("DELETE FROM content_blocks WHERE contentId = ? AND isDraft = 0").run(r);
|
|
24510
|
+
let D = await t.prepare("SELECT * FROM content_blocks WHERE contentId = ? AND isDraft = 1 ORDER BY sortOrder ASC").all(r), te = Array.isArray(D) ? D : D?.results || [];
|
|
24511
|
+
if (te.length > 0) {
|
|
24429
24512
|
let e = [], n = [];
|
|
24430
|
-
for (let t of
|
|
24513
|
+
for (let t of te) {
|
|
24431
24514
|
let i = t.region !== void 0 && t.region !== null && String(t.region).trim() !== "" ? String(t.region) : "content";
|
|
24432
24515
|
e.push("(?, ?, ?, ?, ?, 0)"), n.push(r, t.sortOrder, t.elementType, t.dataJson, i);
|
|
24433
24516
|
}
|
|
24434
24517
|
await t.prepare(`INSERT INTO content_blocks (contentId, sortOrder, elementType, dataJson, region, isDraft) VALUES ${e.join(", ")}`).run(...n);
|
|
24435
24518
|
}
|
|
24436
|
-
let
|
|
24437
|
-
version:
|
|
24519
|
+
let O = ((await t.prepare("SELECT COUNT(*) as count FROM node_revisions WHERE nodeId = ?").get(r))?.count || 0) + 1, k = {
|
|
24520
|
+
version: O,
|
|
24438
24521
|
publishedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
24439
24522
|
node: {
|
|
24440
24523
|
...s,
|
|
24441
|
-
dataJson:
|
|
24524
|
+
dataJson: b
|
|
24442
24525
|
},
|
|
24443
|
-
blocks:
|
|
24526
|
+
blocks: te
|
|
24444
24527
|
};
|
|
24445
|
-
await t.prepare("INSERT INTO node_revisions (nodeId, version, snapshotJson, createdById) VALUES (?, ?, ?, ?)").run(r,
|
|
24528
|
+
await t.prepare("INSERT INTO node_revisions (nodeId, version, snapshotJson, createdById) VALUES (?, ?, ?, ?)").run(r, O, JSON.stringify(k), i), o.push(r);
|
|
24446
24529
|
}
|
|
24447
24530
|
await $b(e).clear();
|
|
24448
24531
|
let s = new mx(e.env);
|
|
24449
|
-
if (a)
|
|
24532
|
+
if (a) _x(e, t, o);
|
|
24450
24533
|
else for (let n of o) s.purgeNode(e, t, n, !1);
|
|
24451
24534
|
return e.json({
|
|
24452
24535
|
success: !0,
|
|
@@ -24458,13 +24541,13 @@ gx.get("/", async (e) => {
|
|
|
24458
24541
|
let t = e.get("db"), n = e.req.query("id");
|
|
24459
24542
|
if (!n) return e.json({ error: "Node ID required" }, 400);
|
|
24460
24543
|
let r = Number(n);
|
|
24461
|
-
return await t.prepare("UPDATE content_nodes SET deletedAt = CURRENT_TIMESTAMP WHERE id = ?").run(r), await $b(e).clear(),
|
|
24544
|
+
return await t.prepare("UPDATE content_nodes SET deletedAt = CURRENT_TIMESTAMP WHERE id = ?").run(r), await $b(e).clear(), new mx(e.env), _x(e, t, [r]), e.json({
|
|
24462
24545
|
success: !0,
|
|
24463
24546
|
deletedNodeId: r
|
|
24464
24547
|
});
|
|
24465
24548
|
}), gx.post("/restore", async (e) => {
|
|
24466
24549
|
let t = e.get("db"), n = await e.req.json(), r = Number(n.id);
|
|
24467
|
-
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 $b(e).clear(),
|
|
24550
|
+
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 $b(e).clear(), new mx(e.env), _x(e, t, [r]), e.json({
|
|
24468
24551
|
success: !0,
|
|
24469
24552
|
restoredNodeId: r
|
|
24470
24553
|
})) : e.json({ error: "Node not found" }, 404) : e.json({ error: "Node ID required" }, 400);
|
|
@@ -24472,7 +24555,7 @@ gx.get("/", async (e) => {
|
|
|
24472
24555
|
let t = e.get("db"), n = e.req.query("id");
|
|
24473
24556
|
if (!n) return e.json({ error: "Node ID required" }, 400);
|
|
24474
24557
|
let r = Number(n);
|
|
24475
|
-
return 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 node_terms WHERE nodeId = ?").run(r), await t.prepare("DELETE FROM content_nodes WHERE id = ?").run(r), await $b(e).clear(),
|
|
24558
|
+
return await new mx(e.env).purgeInternalWorkerCache(e, t, r), 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 node_terms WHERE nodeId = ?").run(r), await t.prepare("DELETE FROM content_nodes WHERE id = ?").run(r), await $b(e).clear(), _x(e, t), e.json({
|
|
24476
24559
|
success: !0,
|
|
24477
24560
|
purgedNodeId: r
|
|
24478
24561
|
});
|
|
@@ -24487,7 +24570,7 @@ gx.get("/", async (e) => {
|
|
|
24487
24570
|
} catch {}
|
|
24488
24571
|
return {
|
|
24489
24572
|
version: e.version,
|
|
24490
|
-
publishedAt: t || new
|
|
24573
|
+
publishedAt: t || (/* @__PURE__ */ new Date()).toISOString(),
|
|
24491
24574
|
createdById: e.createdById
|
|
24492
24575
|
};
|
|
24493
24576
|
});
|
|
@@ -24545,15 +24628,18 @@ gx.get("/", async (e) => {
|
|
|
24545
24628
|
let t = JSON.stringify(e);
|
|
24546
24629
|
s += ", dataJson = ?, publishedDataJson = ?", c.push(t, t);
|
|
24547
24630
|
}
|
|
24548
|
-
|
|
24631
|
+
s += " WHERE id = ?", c.push(n), await t.prepare(s).run(...c), await $b(e).clear();
|
|
24632
|
+
let u = await new mx(e.env).purgeVisibilityChange(e, t, n);
|
|
24633
|
+
return e.json({
|
|
24549
24634
|
success: !0,
|
|
24550
|
-
isHidden: i
|
|
24635
|
+
isHidden: i,
|
|
24636
|
+
cacheInvalidated: u
|
|
24551
24637
|
});
|
|
24552
24638
|
});
|
|
24553
24639
|
//#endregion
|
|
24554
24640
|
//#region server/routes/admin/trees.ts
|
|
24555
|
-
var
|
|
24556
|
-
function
|
|
24641
|
+
var Ox = new e();
|
|
24642
|
+
function kx(e, t = null) {
|
|
24557
24643
|
let n = [];
|
|
24558
24644
|
for (let r = 0; r < e.length; r++) {
|
|
24559
24645
|
let i = e[r];
|
|
@@ -24565,19 +24651,19 @@ function Ox(e, t = null) {
|
|
|
24565
24651
|
id: o,
|
|
24566
24652
|
parentId: t,
|
|
24567
24653
|
sortOrder: r
|
|
24568
|
-
}), i.children && Array.isArray(i.children) && i.children.length > 0 && n.push(...
|
|
24654
|
+
}), i.children && Array.isArray(i.children) && i.children.length > 0 && n.push(...kx(i.children, o)));
|
|
24569
24655
|
}
|
|
24570
24656
|
return n;
|
|
24571
24657
|
}
|
|
24572
|
-
function
|
|
24658
|
+
function Ax(e) {
|
|
24573
24659
|
if (e == null || e === "null" || e === "" || typeof e == "string" && e.startsWith("draft-")) return null;
|
|
24574
24660
|
let t = Number(e);
|
|
24575
24661
|
return isNaN(t) ? null : t;
|
|
24576
24662
|
}
|
|
24577
|
-
function
|
|
24663
|
+
function jx(e) {
|
|
24578
24664
|
return +(e === !0 || e === 1 || e === "1" || e === "true");
|
|
24579
24665
|
}
|
|
24580
|
-
|
|
24666
|
+
Ox.get("/tree.json", async (e) => {
|
|
24581
24667
|
try {
|
|
24582
24668
|
let t = e.get("db"), n = e.req.query("treeId") || "main-nav", r = e.req.query("preview") === "true", i = 1;
|
|
24583
24669
|
if (isNaN(Number(n))) {
|
|
@@ -24588,7 +24674,7 @@ Dx.get("/tree.json", async (e) => {
|
|
|
24588
24674
|
e && e.id && (i = Number(e.id));
|
|
24589
24675
|
}
|
|
24590
24676
|
} else i = Number(n);
|
|
24591
|
-
let a = await t.prepare("\n SELECT \n t.contentId as treeNodeId, \n t.treeId,\n t.contentId,\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.publishedAt,\n c.hasUnpublishedChanges,\n c.dataJson,\n c.draftDataJson,\n (
|
|
24677
|
+
let a = await t.prepare("\n WITH tree_asset_counts AS (\n SELECT na.nodeId, COUNT(*) as assetCount \n FROM node_assets na \n INNER JOIN tree_nodes tn ON na.nodeId = tn.contentId \n WHERE tn.treeId = ? \n GROUP BY na.nodeId\n )\n SELECT \n t.contentId as treeNodeId, \n t.treeId,\n t.contentId,\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.publishedAt,\n c.hasUnpublishedChanges,\n c.dataJson,\n c.draftDataJson,\n COALESCE(ac.assetCount, 0) as assetCount\n FROM tree_nodes t\n INNER JOIN content_nodes c ON t.contentId = c.id\n LEFT JOIN tree_asset_counts ac ON t.contentId = ac.nodeId\n WHERE t.treeId = ? AND c.deletedAt IS NULL\n ORDER BY t.sortOrder ASC\n ").all(i, i), o = Array.isArray(a) ? a : a?.results || [], s = [], c = /* @__PURE__ */ new Set();
|
|
24592
24678
|
for (let e of o) {
|
|
24593
24679
|
let t = e.contentId;
|
|
24594
24680
|
c.has(t) || (c.add(t), s.push(e));
|
|
@@ -24630,7 +24716,7 @@ Dx.get("/tree.json", async (e) => {
|
|
|
24630
24716
|
} catch (t) {
|
|
24631
24717
|
return console.error("[CMS Tree API] GET Error:", t), e.json({ error: t.message || "Failed to fetch tree" }, 500);
|
|
24632
24718
|
}
|
|
24633
|
-
}),
|
|
24719
|
+
}), Ox.post("/tree.json", async (e) => {
|
|
24634
24720
|
try {
|
|
24635
24721
|
let t = e.get("db"), n = await e.req.json(), r = n.treeId ? String(n.treeId).trim() : "main-nav", i = $b(e), a = new mx(e.env), o = 1;
|
|
24636
24722
|
if (isNaN(Number(r))) {
|
|
@@ -24642,7 +24728,7 @@ Dx.get("/tree.json", async (e) => {
|
|
|
24642
24728
|
}
|
|
24643
24729
|
} else o = Number(r);
|
|
24644
24730
|
if (n.tree && Array.isArray(n.tree)) {
|
|
24645
|
-
let r =
|
|
24731
|
+
let r = kx(n.tree, null);
|
|
24646
24732
|
if (r.length > 0) for (let e = 0; e < r.length; e += 50) {
|
|
24647
24733
|
let n = r.slice(e, e + 50), i = n.map((e) => e.id), a = i.map(() => "?").join(","), s = "UPDATE tree_nodes SET \n";
|
|
24648
24734
|
s += "parentId = CASE contentId \n", n.forEach(() => {
|
|
@@ -24662,9 +24748,9 @@ Dx.get("/tree.json", async (e) => {
|
|
|
24662
24748
|
reorderedCount: r.length
|
|
24663
24749
|
});
|
|
24664
24750
|
}
|
|
24665
|
-
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 =
|
|
24751
|
+
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 = jx(n.isHidden === void 0 ? m.isHidden === void 0 ? m.hidden : m.isHidden : n.isHidden);
|
|
24666
24752
|
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;
|
|
24667
|
-
let g =
|
|
24753
|
+
let g = Ax(u), _ = e.get("user")?.id || null;
|
|
24668
24754
|
if (s === "create") {
|
|
24669
24755
|
let r = m.slug || n.slug || c, a = r ? String(r).toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "") : null;
|
|
24670
24756
|
if (a) {
|
|
@@ -24772,7 +24858,7 @@ Dx.get("/tree.json", async (e) => {
|
|
|
24772
24858
|
details: t.message
|
|
24773
24859
|
}, 500);
|
|
24774
24860
|
}
|
|
24775
|
-
}),
|
|
24861
|
+
}), Ox.get("/trees.json", async (e) => {
|
|
24776
24862
|
try {
|
|
24777
24863
|
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) => {
|
|
24778
24864
|
let n = Number(t.treeId), r = Number(t.channelId);
|
|
@@ -24802,7 +24888,7 @@ Dx.get("/tree.json", async (e) => {
|
|
|
24802
24888
|
} catch {
|
|
24803
24889
|
return e.json([]);
|
|
24804
24890
|
}
|
|
24805
|
-
}),
|
|
24891
|
+
}), Ox.post("/trees.json", async (e) => {
|
|
24806
24892
|
try {
|
|
24807
24893
|
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 };
|
|
24808
24894
|
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({
|
|
@@ -24841,7 +24927,7 @@ Dx.get("/tree.json", async (e) => {
|
|
|
24841
24927
|
} catch (t) {
|
|
24842
24928
|
return console.error("[API Trees] Error saving tree:", t), e.json({ error: t.message || "Failed to save tree" }, 500);
|
|
24843
24929
|
}
|
|
24844
|
-
}),
|
|
24930
|
+
}), Ox.delete("/trees.json", async (e) => {
|
|
24845
24931
|
let t = e.get("db"), n = e.req.query("id");
|
|
24846
24932
|
if (!n) return e.json({ error: "Tree ID required" }, 400);
|
|
24847
24933
|
let r = Number(n);
|
|
@@ -24856,8 +24942,8 @@ Dx.get("/tree.json", async (e) => {
|
|
|
24856
24942
|
});
|
|
24857
24943
|
//#endregion
|
|
24858
24944
|
//#region server/routes/admin/channels.ts
|
|
24859
|
-
var
|
|
24860
|
-
|
|
24945
|
+
var Mx = new e();
|
|
24946
|
+
Mx.get("/", async (e) => {
|
|
24861
24947
|
try {
|
|
24862
24948
|
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) => {
|
|
24863
24949
|
e[t.channelId] || (e[t.channelId] = []);
|
|
@@ -24923,27 +25009,27 @@ jx.get("/", async (e) => {
|
|
|
24923
25009
|
error: t.message
|
|
24924
25010
|
}, 500);
|
|
24925
25011
|
}
|
|
24926
|
-
}),
|
|
25012
|
+
}), Mx.post("/", async (e) => {
|
|
24927
25013
|
try {
|
|
24928
25014
|
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 || "";
|
|
24929
25015
|
typeof T == "object" && T && (T = T.value || T.id || ""), T = String(T).trim();
|
|
24930
|
-
let ee = m === !0 || m === "true" || m === 1 || h === !0 || h === "true" || h === 1, E = Array.isArray(g) ? g : [], D = JSON.stringify(S || {}),
|
|
25016
|
+
let ee = m === !0 || m === "true" || m === 1 || h === !0 || h === "true" || h === 1, E = Array.isArray(g) ? g : [], D = JSON.stringify(S || {}), te = e.get("user")?.id || v || _ || null;
|
|
24931
25017
|
if (await t.prepare("SELECT id FROM channels WHERE key = ? AND id != ? LIMIT 1").get(C, a ?? -1)) return e.json({
|
|
24932
25018
|
error: `Channel API key "${C}" is already in use.`,
|
|
24933
25019
|
field: "key"
|
|
24934
25020
|
}, 409);
|
|
24935
|
-
let
|
|
24936
|
-
if (a) await t.prepare("\n UPDATE channels \n SET key = ?, label = ?, channelType = ?, domain = ?, baseUrl = ?, defaultLanguage = ?, \n isHidden = ?, dataJson = ?, updatedById = ?, updatedAt = CURRENT_TIMESTAMP\n WHERE id = ?\n ").run(C, w, c, l, u, T, +!!ee, D,
|
|
25021
|
+
let O = a;
|
|
25022
|
+
if (a) await t.prepare("\n UPDATE channels \n SET key = ?, label = ?, channelType = ?, domain = ?, baseUrl = ?, defaultLanguage = ?, \n isHidden = ?, dataJson = ?, updatedById = ?, updatedAt = CURRENT_TIMESTAMP\n WHERE id = ?\n ").run(C, w, c, l, u, T, +!!ee, D, te, a);
|
|
24937
25023
|
else {
|
|
24938
|
-
let e = await t.prepare("\n INSERT INTO channels (key, label, channelType, domain, baseUrl, defaultLanguage, isHidden, dataJson, createdById, updatedById)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n RETURNING id\n ").get(C, w, c, l, u, T, +!!ee, D,
|
|
25024
|
+
let e = await t.prepare("\n INSERT INTO channels (key, label, channelType, domain, baseUrl, defaultLanguage, isHidden, dataJson, createdById, updatedById)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n RETURNING id\n ").get(C, w, c, l, u, T, +!!ee, D, te, te), n = e?.results?.[0] || e;
|
|
24939
25025
|
if (!n || !n.id) throw Error("Failed to retrieve newly created Channel ID from Cloudflare D1.");
|
|
24940
|
-
|
|
25026
|
+
O = Number(n.id);
|
|
24941
25027
|
}
|
|
24942
|
-
await t.prepare("DELETE FROM channel_trees WHERE channelId = ?").run(
|
|
25028
|
+
await t.prepare("DELETE FROM channel_trees WHERE channelId = ?").run(O);
|
|
24943
25029
|
let k = E.filter((e) => e && e.treeId && e.key);
|
|
24944
25030
|
if (k.length > 0) {
|
|
24945
25031
|
let e = k.map(() => "(?, ?, ?, ?)").join(", "), n = k.flatMap((e) => [
|
|
24946
|
-
|
|
25032
|
+
O,
|
|
24947
25033
|
Number(e.treeId) || e.treeId,
|
|
24948
25034
|
String(e.key).trim(),
|
|
24949
25035
|
JSON.stringify(e.meta || {})
|
|
@@ -24954,9 +25040,9 @@ jx.get("/", async (e) => {
|
|
|
24954
25040
|
`).run(...n);
|
|
24955
25041
|
}
|
|
24956
25042
|
let A = $b(e);
|
|
24957
|
-
return await A.delete(`channel:${C}`), await A.delete(`channel:${
|
|
25043
|
+
return await A.delete(`channel:${C}`), await A.delete(`channel:${O}`), await A.clear(), await hx(t), new mx(e.env).purgeGlobalCache(e, t), e.json({
|
|
24958
25044
|
success: !0,
|
|
24959
|
-
id:
|
|
25045
|
+
id: O
|
|
24960
25046
|
});
|
|
24961
25047
|
} catch (t) {
|
|
24962
25048
|
return console.error("[API Channels] Error saving channel:", t), e.json({
|
|
@@ -24964,7 +25050,7 @@ jx.get("/", async (e) => {
|
|
|
24964
25050
|
details: t.message
|
|
24965
25051
|
}, 500);
|
|
24966
25052
|
}
|
|
24967
|
-
}),
|
|
25053
|
+
}), Mx.delete("/", async (e) => {
|
|
24968
25054
|
let t = e.get("db"), n = e.req.query("id");
|
|
24969
25055
|
if (!n) return e.json({ error: "Channel ID required" }, 400);
|
|
24970
25056
|
let r = Number(n);
|
|
@@ -24984,15 +25070,15 @@ jx.get("/", async (e) => {
|
|
|
24984
25070
|
});
|
|
24985
25071
|
//#endregion
|
|
24986
25072
|
//#region server/routes/admin/taxonomies.ts
|
|
24987
|
-
var
|
|
24988
|
-
function
|
|
25073
|
+
var Nx = new e();
|
|
25074
|
+
function Px(e) {
|
|
24989
25075
|
return e.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().trim().replace(/[^a-z0-9\s-]/g, "").replace(/[\s-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
24990
25076
|
}
|
|
24991
|
-
function
|
|
25077
|
+
function Fx(e) {
|
|
24992
25078
|
let t = (e || "").trim().toLowerCase(), n = px()?.taxonomies || {};
|
|
24993
25079
|
return n[t] ? t : n[`${t}s`] ? `${t}s` : t.endsWith("s") && n[t.slice(0, -1)] ? t.slice(0, -1) : t;
|
|
24994
25080
|
}
|
|
24995
|
-
async function
|
|
25081
|
+
async function Ix(e, t, n = []) {
|
|
24996
25082
|
let r = e.prepare(t);
|
|
24997
25083
|
if (typeof r.bind == "function") {
|
|
24998
25084
|
let e = await r.bind(...n).all();
|
|
@@ -25004,10 +25090,10 @@ async function Fx(e, t, n = []) {
|
|
|
25004
25090
|
}
|
|
25005
25091
|
return [];
|
|
25006
25092
|
}
|
|
25007
|
-
|
|
25008
|
-
let t = e.get("db"), n =
|
|
25093
|
+
Nx.get("/:taxonomy", async (e) => {
|
|
25094
|
+
let t = e.get("db"), n = Fx(e.req.param("taxonomy"));
|
|
25009
25095
|
try {
|
|
25010
|
-
let r = (await
|
|
25096
|
+
let r = (await Ix(t, "\n SELECT id, taxonomy, key, label, parentId, sortOrder, dataJson, createdAt, updatedAt\n FROM taxonomy_terms\n WHERE taxonomy = ?\n ORDER BY sortOrder ASC, label ASC\n ", [n])).map((e) => ({
|
|
25011
25097
|
...e,
|
|
25012
25098
|
data: e.dataJson ? JSON.parse(e.dataJson) : {}
|
|
25013
25099
|
}));
|
|
@@ -25018,12 +25104,12 @@ Mx.get("/:taxonomy", async (e) => {
|
|
|
25018
25104
|
} catch (t) {
|
|
25019
25105
|
return console.error("[Taxonomy API] Error fetching terms:", t), e.json({ error: "Failed to fetch taxonomy terms" }, 500);
|
|
25020
25106
|
}
|
|
25021
|
-
}),
|
|
25022
|
-
let t = e.get("db"), n =
|
|
25107
|
+
}), Nx.post("/:taxonomy", async (e) => {
|
|
25108
|
+
let t = e.get("db"), n = Fx(e.req.param("taxonomy")), r = await e.req.json(), i = r.label?.trim();
|
|
25023
25109
|
if (!i) return e.json({ error: "Label is required" }, 400);
|
|
25024
|
-
let a = r.key?.trim() ||
|
|
25110
|
+
let a = r.key?.trim() || Px(i), o = r.parentId ? Number(r.parentId) : null, s = r.sortOrder ? Number(r.sortOrder) : 0, c = r.data ? JSON.stringify(r.data) : "{}";
|
|
25025
25111
|
try {
|
|
25026
|
-
if ((await
|
|
25112
|
+
if ((await Ix(t, "SELECT id FROM taxonomy_terms WHERE taxonomy = ? AND key = ?", [n, a])).length > 0) return e.json({ error: `A term with the key '${a}' already exists in this taxonomy.` }, 409);
|
|
25027
25113
|
let r = t.prepare("\n INSERT INTO taxonomy_terms (taxonomy, key, label, parentId, sortOrder, dataJson)\n VALUES (?, ?, ?, ?, ?, ?)\n "), l;
|
|
25028
25114
|
return l = typeof r.bind == "function" ? await r.bind(n, a, i, o, s, c).run() : await r.run(n, a, i, o, s, c), e.json({
|
|
25029
25115
|
success: !0,
|
|
@@ -25032,12 +25118,12 @@ Mx.get("/:taxonomy", async (e) => {
|
|
|
25032
25118
|
} catch (t) {
|
|
25033
25119
|
return console.error("[Taxonomy API] Error creating term:", t), e.json({ error: "Failed to create taxonomy term" }, 500);
|
|
25034
25120
|
}
|
|
25035
|
-
}),
|
|
25036
|
-
let t = e.get("db"), n =
|
|
25121
|
+
}), Nx.put("/:taxonomy/:id", async (e) => {
|
|
25122
|
+
let t = e.get("db"), n = Fx(e.req.param("taxonomy")), r = Number(e.req.param("id"));
|
|
25037
25123
|
if (isNaN(r)) return e.json({ error: "Invalid term ID" }, 400);
|
|
25038
25124
|
let i = await e.req.json();
|
|
25039
25125
|
try {
|
|
25040
|
-
let a = await
|
|
25126
|
+
let a = await Ix(t, "SELECT * FROM taxonomy_terms WHERE id = ? AND taxonomy = ?", [r, n]);
|
|
25041
25127
|
if (a.length === 0) return e.json({ error: "Term not found" }, 404);
|
|
25042
25128
|
let o = a[0], s = i.label === void 0 ? o.label : i.label.trim(), c = i.key === void 0 ? o.key : i.key.trim(), l = i.parentId === void 0 ? o.parentId : i.parentId ? Number(i.parentId) : null, u = i.sortOrder === void 0 ? o.sortOrder : Number(i.sortOrder), d = o.dataJson;
|
|
25043
25129
|
if (i.data) {
|
|
@@ -25047,14 +25133,14 @@ Mx.get("/:taxonomy", async (e) => {
|
|
|
25047
25133
|
...i.data
|
|
25048
25134
|
});
|
|
25049
25135
|
}
|
|
25050
|
-
if (c !== o.key && (await
|
|
25136
|
+
if (c !== o.key && (await Ix(t, "SELECT id FROM taxonomy_terms WHERE taxonomy = ? AND key = ?", [n, c])).length > 0) return e.json({ error: `A term with the key '${c}' already exists in this taxonomy.` }, 409);
|
|
25051
25137
|
let f = t.prepare("\n UPDATE taxonomy_terms \n SET label = ?, key = ?, parentId = ?, sortOrder = ?, dataJson = ?, updatedAt = CURRENT_TIMESTAMP\n WHERE id = ?\n ");
|
|
25052
25138
|
return typeof f.bind == "function" ? await f.bind(s, c, l, u, d, r).run() : await f.run(s, c, l, u, d, r), e.json({ success: !0 });
|
|
25053
25139
|
} catch (t) {
|
|
25054
25140
|
return console.error("[Taxonomy API] Error updating term:", t), e.json({ error: "Failed to update taxonomy term" }, 500);
|
|
25055
25141
|
}
|
|
25056
|
-
}),
|
|
25057
|
-
let t = e.get("db"), n =
|
|
25142
|
+
}), Nx.delete("/:taxonomy/:id", async (e) => {
|
|
25143
|
+
let t = e.get("db"), n = Fx(e.req.param("taxonomy")), r = Number(e.req.param("id"));
|
|
25058
25144
|
if (isNaN(r)) return e.json({ error: "Invalid term ID" }, 400);
|
|
25059
25145
|
try {
|
|
25060
25146
|
let i = t.prepare("DELETE FROM taxonomy_terms WHERE id = ? AND taxonomy = ?");
|
|
@@ -25065,20 +25151,20 @@ Mx.get("/:taxonomy", async (e) => {
|
|
|
25065
25151
|
});
|
|
25066
25152
|
//#endregion
|
|
25067
25153
|
//#region server/schema/engine.ts
|
|
25068
|
-
var
|
|
25154
|
+
var Lx = null, Rx = null;
|
|
25069
25155
|
if (typeof process < "u" && process?.versions?.node) try {
|
|
25070
25156
|
let e = i(import.meta.url);
|
|
25071
|
-
|
|
25157
|
+
Lx = e("node:fs"), Rx = e("node:path");
|
|
25072
25158
|
} catch {}
|
|
25073
|
-
function
|
|
25159
|
+
function zx(e, t = "") {
|
|
25074
25160
|
let n = e.split(/[\\/]/).pop() || "";
|
|
25075
25161
|
return t && n.endsWith(t) ? n.slice(0, -t.length) : n;
|
|
25076
25162
|
}
|
|
25077
|
-
function
|
|
25163
|
+
function Bx(e) {
|
|
25078
25164
|
let t = e.match(/\.[^.\\/]+$/);
|
|
25079
25165
|
return t ? t[0] : "";
|
|
25080
25166
|
}
|
|
25081
|
-
var
|
|
25167
|
+
var Vx = {
|
|
25082
25168
|
nodes: {},
|
|
25083
25169
|
trees: {},
|
|
25084
25170
|
blocks: {},
|
|
@@ -25088,10 +25174,10 @@ var Bx = {
|
|
|
25088
25174
|
nodeLayouts: {},
|
|
25089
25175
|
blockLayouts: {}
|
|
25090
25176
|
};
|
|
25091
|
-
function
|
|
25177
|
+
function Hx(e) {
|
|
25092
25178
|
return e ? typeof e == "string" ? e.trim() : Array.isArray(e) ? e.includes("*") ? "*" : e : "*" : "*";
|
|
25093
25179
|
}
|
|
25094
|
-
function
|
|
25180
|
+
function Ux(e = {}, t = {}) {
|
|
25095
25181
|
let n = {
|
|
25096
25182
|
...e,
|
|
25097
25183
|
...t,
|
|
@@ -25103,62 +25189,62 @@ function Hx(e = {}, t = {}) {
|
|
|
25103
25189
|
};
|
|
25104
25190
|
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;
|
|
25105
25191
|
}
|
|
25106
|
-
function
|
|
25192
|
+
function Wx(e) {
|
|
25107
25193
|
if (!e || typeof e != "object") return e;
|
|
25108
|
-
if (Array.isArray(e)) return e.map(
|
|
25194
|
+
if (Array.isArray(e)) return e.map(Wx);
|
|
25109
25195
|
let t = {};
|
|
25110
25196
|
for (let [n, r] of Object.entries(e)) if (n === "<<" || n === "<<:") {
|
|
25111
|
-
let e =
|
|
25197
|
+
let e = Wx(r);
|
|
25112
25198
|
if (typeof e == "object" && e) {
|
|
25113
25199
|
if (Array.isArray(e)) for (let n of e) Object.assign(t, n);
|
|
25114
25200
|
else Object.assign(t, e);
|
|
25115
25201
|
}
|
|
25116
|
-
} else t[n] =
|
|
25202
|
+
} else t[n] = Wx(r);
|
|
25117
25203
|
return t;
|
|
25118
25204
|
}
|
|
25119
|
-
function
|
|
25120
|
-
return e ?
|
|
25205
|
+
function Gx(e, t) {
|
|
25206
|
+
return e ? Wx(n.parseDocument(e, { customTags: [{
|
|
25121
25207
|
tag: "!include",
|
|
25122
25208
|
resolve(e) {
|
|
25123
|
-
let n = (typeof e == "string" ? e : String(e?.strValue || e?.value || "")).trim(), r =
|
|
25209
|
+
let n = (typeof e == "string" ? e : String(e?.strValue || e?.value || "")).trim(), r = zx(n);
|
|
25124
25210
|
if (!r) return n;
|
|
25125
25211
|
if (t && t.fieldSets) {
|
|
25126
25212
|
let e = Object.keys(t.fieldSets).find((e) => e.endsWith("/" + r) || e === r);
|
|
25127
|
-
if (e) return
|
|
25213
|
+
if (e) return Gx(t.fieldSets[e], t);
|
|
25128
25214
|
}
|
|
25129
25215
|
return n;
|
|
25130
25216
|
}
|
|
25131
25217
|
}] }).toJS() || {}) : {};
|
|
25132
25218
|
}
|
|
25133
|
-
function
|
|
25134
|
-
if (!
|
|
25135
|
-
let r =
|
|
25136
|
-
if (t.has(r) || (t.add(r), !
|
|
25137
|
-
let i =
|
|
25138
|
-
return
|
|
25219
|
+
function Kx(e, t = /* @__PURE__ */ new Set()) {
|
|
25220
|
+
if (!Lx || !Rx) return {};
|
|
25221
|
+
let r = Rx.resolve(e);
|
|
25222
|
+
if (t.has(r) || (t.add(r), !Lx.existsSync(r))) return {};
|
|
25223
|
+
let i = Lx.readFileSync(r, "utf-8");
|
|
25224
|
+
return Wx(n.parseDocument(i, { customTags: [{
|
|
25139
25225
|
tag: "!include",
|
|
25140
25226
|
resolve(e) {
|
|
25141
25227
|
let n = (typeof e == "string" ? e : String(e?.strValue || e?.value || "")).trim();
|
|
25142
|
-
return n ?
|
|
25228
|
+
return n ? Kx(Rx.resolve(Rx.dirname(r), n), new Set(t)) : {};
|
|
25143
25229
|
}
|
|
25144
25230
|
}] }).toJS() || {});
|
|
25145
25231
|
}
|
|
25146
|
-
function
|
|
25147
|
-
if (!
|
|
25232
|
+
function qx() {
|
|
25233
|
+
if (!Lx || !Rx || typeof process > "u" || !process?.versions?.node) return null;
|
|
25148
25234
|
try {
|
|
25149
25235
|
let e = process.cwd(), t = "", n = [
|
|
25150
|
-
|
|
25151
|
-
|
|
25152
|
-
|
|
25153
|
-
|
|
25236
|
+
Rx.resolve(e, "content/definitions"),
|
|
25237
|
+
Rx.resolve(e, "content"),
|
|
25238
|
+
Rx.resolve(e, "definitions"),
|
|
25239
|
+
Rx.resolve(e, "kama-worker/content/definitions")
|
|
25154
25240
|
];
|
|
25155
25241
|
try {
|
|
25156
25242
|
if (import.meta.url) {
|
|
25157
|
-
let e =
|
|
25158
|
-
n.push(
|
|
25243
|
+
let e = Rx.dirname(r(import.meta.url));
|
|
25244
|
+
n.push(Rx.resolve(e, "../../content/definitions")), n.push(Rx.resolve(e, "../content/definitions"));
|
|
25159
25245
|
}
|
|
25160
25246
|
} catch {}
|
|
25161
|
-
for (let e of n) if (
|
|
25247
|
+
for (let e of n) if (Lx.existsSync(e)) {
|
|
25162
25248
|
t = e;
|
|
25163
25249
|
break;
|
|
25164
25250
|
}
|
|
@@ -25166,19 +25252,19 @@ function Kx() {
|
|
|
25166
25252
|
let i = (e) => {
|
|
25167
25253
|
let n = "";
|
|
25168
25254
|
for (let r of e) {
|
|
25169
|
-
let e =
|
|
25170
|
-
if (
|
|
25255
|
+
let e = Rx.join(t, r);
|
|
25256
|
+
if (Lx.existsSync(e)) {
|
|
25171
25257
|
n = e;
|
|
25172
25258
|
break;
|
|
25173
25259
|
}
|
|
25174
25260
|
}
|
|
25175
25261
|
if (!n) return {};
|
|
25176
|
-
let r = {}, i =
|
|
25262
|
+
let r = {}, i = Lx.readdirSync(n);
|
|
25177
25263
|
for (let e of i) {
|
|
25178
25264
|
if (!e.endsWith(".yaml") && !e.endsWith(".yml")) continue;
|
|
25179
|
-
let t =
|
|
25265
|
+
let t = Rx.join(n, e), i = zx(e, Bx(e));
|
|
25180
25266
|
try {
|
|
25181
|
-
r[i] =
|
|
25267
|
+
r[i] = Kx(t);
|
|
25182
25268
|
} catch (t) {
|
|
25183
25269
|
console.error(`❌ Error parsing ${e}:`, t.message);
|
|
25184
25270
|
}
|
|
@@ -25207,59 +25293,59 @@ function Kx() {
|
|
|
25207
25293
|
return console.error("❌ Exception inside readLocalFsBundle:", e), null;
|
|
25208
25294
|
}
|
|
25209
25295
|
}
|
|
25210
|
-
var
|
|
25211
|
-
function Yx(e) {
|
|
25212
|
-
if (!e) qx = null, Jx = null;
|
|
25213
|
-
else if (qx && Jx === e) return qx;
|
|
25214
|
-
let t = Xx(e);
|
|
25215
|
-
return qx = t, Jx = e, t;
|
|
25216
|
-
}
|
|
25296
|
+
var Jx = null, Yx = null;
|
|
25217
25297
|
function Xx(e) {
|
|
25298
|
+
if (!e) Jx = null, Yx = null;
|
|
25299
|
+
else if (Jx && Yx === e) return Jx;
|
|
25300
|
+
let t = Zx(e);
|
|
25301
|
+
return Jx = t, Yx = e, t;
|
|
25302
|
+
}
|
|
25303
|
+
function Zx(e) {
|
|
25218
25304
|
if (e) {
|
|
25219
25305
|
let t = {
|
|
25220
25306
|
nodes: {
|
|
25221
25307
|
...e.nodes || e.rawNodes || {},
|
|
25222
|
-
...
|
|
25308
|
+
...Vx.nodes
|
|
25223
25309
|
},
|
|
25224
25310
|
trees: {
|
|
25225
25311
|
...e.trees || e.rawTrees || {},
|
|
25226
|
-
...
|
|
25312
|
+
...Vx.trees
|
|
25227
25313
|
},
|
|
25228
25314
|
channels: {
|
|
25229
25315
|
...e.channels || e.rawChannels || {},
|
|
25230
|
-
...
|
|
25316
|
+
...Vx.channels
|
|
25231
25317
|
},
|
|
25232
25318
|
taxonomies: {
|
|
25233
25319
|
...e.taxonomies || e.rawTaxonomies || {},
|
|
25234
|
-
...
|
|
25320
|
+
...Vx.taxonomies
|
|
25235
25321
|
},
|
|
25236
25322
|
blocks: {
|
|
25237
25323
|
...e.blocks || e.rawBlocks || {},
|
|
25238
|
-
...
|
|
25324
|
+
...Vx.blocks
|
|
25239
25325
|
},
|
|
25240
25326
|
nodeLayouts: {
|
|
25241
25327
|
...e.nodeLayouts || e.rawNodeLayouts || {},
|
|
25242
|
-
...
|
|
25328
|
+
...Vx.nodeLayouts
|
|
25243
25329
|
},
|
|
25244
25330
|
blockLayouts: {
|
|
25245
25331
|
...e.blockLayouts || e.rawBlockLayouts || {},
|
|
25246
|
-
...
|
|
25332
|
+
...Vx.blockLayouts
|
|
25247
25333
|
},
|
|
25248
25334
|
fieldSets: {
|
|
25249
25335
|
...e.fieldSets || e.rawFieldSets || {},
|
|
25250
|
-
...
|
|
25336
|
+
...Vx.fieldSets
|
|
25251
25337
|
}
|
|
25252
25338
|
};
|
|
25253
25339
|
if (typeof Object.values(t.nodes)[0] == "string") {
|
|
25254
25340
|
let e = (e) => {
|
|
25255
25341
|
let n = {};
|
|
25256
25342
|
for (let [r, i] of Object.entries(e || {})) {
|
|
25257
|
-
let e =
|
|
25258
|
-
n[e] =
|
|
25343
|
+
let e = zx(r, Bx(r));
|
|
25344
|
+
n[e] = Gx(i, t);
|
|
25259
25345
|
}
|
|
25260
25346
|
return n;
|
|
25261
25347
|
};
|
|
25262
|
-
return
|
|
25348
|
+
return Qx({
|
|
25263
25349
|
rawNodes: e(t.nodes),
|
|
25264
25350
|
rawTrees: e(t.trees),
|
|
25265
25351
|
rawChannels: e(t.channels),
|
|
@@ -25270,12 +25356,12 @@ function Xx(e) {
|
|
|
25270
25356
|
rawFieldSets: e(t.fieldSets)
|
|
25271
25357
|
});
|
|
25272
25358
|
}
|
|
25273
|
-
return
|
|
25359
|
+
return Qx(t);
|
|
25274
25360
|
}
|
|
25275
|
-
let t =
|
|
25276
|
-
return t && Object.keys(t.rawNodes || {}).length > 0 ?
|
|
25361
|
+
let t = qx();
|
|
25362
|
+
return t && Object.keys(t.rawNodes || {}).length > 0 ? Qx(t) : Qx(null);
|
|
25277
25363
|
}
|
|
25278
|
-
function
|
|
25364
|
+
function Qx(e) {
|
|
25279
25365
|
if (!e) return {
|
|
25280
25366
|
nodes: {},
|
|
25281
25367
|
trees: {},
|
|
@@ -25290,7 +25376,7 @@ function Zx(e) {
|
|
|
25290
25376
|
channelTemplate: null,
|
|
25291
25377
|
userTemplate: null
|
|
25292
25378
|
};
|
|
25293
|
-
let { rawNodes: t = {}, rawTrees: n = {}, rawChannels: r = {}, channels: i = {}, rawTaxonomies: a = {}, taxonomies: o = {}, rawBlocks: s = {}, rawElements: c = {}, rawNodeLayouts: l = {}, rawBlockLayouts: u = {}, rawLayouts: d = {}, rawFieldSets: f = {}, rawTemplates: p = {}, nodeTemplate: m = null, treeTemplate: h = null, channelTemplate: g = null, userTemplate: _ = null, nodes: v = {}, trees: y = {}, blocks: b = {}, nodeLayouts: x = {}, blockLayouts: S = {} } = e, C = Object.keys(t).length > 0 ? t : v, w = Object.keys(n).length > 0 ? n : y, T = Object.keys(r).length > 0 ? r : i, ee = Object.keys(a).length > 0 ? a : o, E = Object.keys(s).length > 0 ? s : Object.keys(c).length > 0 ? c : b, D = Object.keys(l).length > 0 ? l : Object.keys(d).length > 0 ? d : x,
|
|
25379
|
+
let { rawNodes: t = {}, rawTrees: n = {}, rawChannels: r = {}, channels: i = {}, rawTaxonomies: a = {}, taxonomies: o = {}, rawBlocks: s = {}, rawElements: c = {}, rawNodeLayouts: l = {}, rawBlockLayouts: u = {}, rawLayouts: d = {}, rawFieldSets: f = {}, rawTemplates: p = {}, nodeTemplate: m = null, treeTemplate: h = null, channelTemplate: g = null, userTemplate: _ = null, nodes: v = {}, trees: y = {}, blocks: b = {}, nodeLayouts: x = {}, blockLayouts: S = {} } = e, C = Object.keys(t).length > 0 ? t : v, w = Object.keys(n).length > 0 ? n : y, T = Object.keys(r).length > 0 ? r : i, ee = Object.keys(a).length > 0 ? a : o, E = Object.keys(s).length > 0 ? s : Object.keys(c).length > 0 ? c : b, D = Object.keys(l).length > 0 ? l : Object.keys(d).length > 0 ? d : x, te = Object.keys(u).length > 0 ? u : S, O = m?.fields || {}, k = {
|
|
25294
25380
|
...p,
|
|
25295
25381
|
...f
|
|
25296
25382
|
}, A = (e, t = "settings", n, r) => {
|
|
@@ -25307,11 +25393,11 @@ function Zx(e) {
|
|
|
25307
25393
|
fields: {}
|
|
25308
25394
|
}), Object.entries(s).forEach(([e, r]) => {
|
|
25309
25395
|
let i = n[t].fields[e] || {};
|
|
25310
|
-
n[t].fields[e] =
|
|
25396
|
+
n[t].fields[e] = Ux(i, r);
|
|
25311
25397
|
});
|
|
25312
25398
|
} else Object.entries(s).forEach(([e, t]) => {
|
|
25313
25399
|
let n = i[e] || {};
|
|
25314
|
-
i[e] =
|
|
25400
|
+
i[e] = Ux(n, t);
|
|
25315
25401
|
});
|
|
25316
25402
|
};
|
|
25317
25403
|
return !Array.isArray(e) && typeof e == "object" && e ? (Object.entries(e).forEach(([e, t]) => {
|
|
@@ -25320,15 +25406,15 @@ function Zx(e) {
|
|
|
25320
25406
|
a(String(t));
|
|
25321
25407
|
return;
|
|
25322
25408
|
}
|
|
25323
|
-
let n = i[e] ||
|
|
25324
|
-
i[e] =
|
|
25409
|
+
let n = i[e] || O[e] || {};
|
|
25410
|
+
i[e] = Ux(n, typeof t == "object" && t ? t : { label: String(t) });
|
|
25325
25411
|
}), i) : (Array.isArray(e) && e.forEach((e) => {
|
|
25326
25412
|
if (typeof e == "string") {
|
|
25327
25413
|
if (e.includes("/") || e.endsWith(".yaml") || e.endsWith(".yml")) return;
|
|
25328
25414
|
if (e.startsWith("fieldSet:")) a(e.replace("fieldSet:", "").trim());
|
|
25329
25415
|
else {
|
|
25330
|
-
let t = i[e] ||
|
|
25331
|
-
i[e] =
|
|
25416
|
+
let t = i[e] || O[e] || {};
|
|
25417
|
+
i[e] = Ux(t, {
|
|
25332
25418
|
type: "text",
|
|
25333
25419
|
label: e
|
|
25334
25420
|
});
|
|
@@ -25336,8 +25422,8 @@ function Zx(e) {
|
|
|
25336
25422
|
} else typeof e == "object" && e && Object.entries(e).forEach(([e, t]) => {
|
|
25337
25423
|
if (e === "fieldSet") a(String(t));
|
|
25338
25424
|
else if (e !== "<<" && e !== "<<:") {
|
|
25339
|
-
let n = i[e] ||
|
|
25340
|
-
i[e] =
|
|
25425
|
+
let n = i[e] || O[e] || {};
|
|
25426
|
+
i[e] = Ux(n, typeof t == "object" && t ? t : {});
|
|
25341
25427
|
}
|
|
25342
25428
|
});
|
|
25343
25429
|
}), i);
|
|
@@ -25355,7 +25441,7 @@ function Zx(e) {
|
|
|
25355
25441
|
let s = A(i.fields || i, a, n, t);
|
|
25356
25442
|
Object.entries(s).forEach(([e, t]) => {
|
|
25357
25443
|
let r = n[a].fields[e] || {};
|
|
25358
|
-
n[a].fields[e] =
|
|
25444
|
+
n[a].fields[e] = Ux(r, t);
|
|
25359
25445
|
});
|
|
25360
25446
|
}
|
|
25361
25447
|
}), n) : (Object.entries(e).forEach(([e, r]) => {
|
|
@@ -25371,7 +25457,7 @@ function Zx(e) {
|
|
|
25371
25457
|
Object.entries(s).forEach(([t, r]) => {
|
|
25372
25458
|
if (t === "<<" || t === "<<:" || t === "label") return;
|
|
25373
25459
|
let i = n[e].fields[t] || {};
|
|
25374
|
-
n[e].fields[t] =
|
|
25460
|
+
n[e].fields[t] = Ux(i, r);
|
|
25375
25461
|
});
|
|
25376
25462
|
}), n);
|
|
25377
25463
|
}, j = {};
|
|
@@ -25389,16 +25475,16 @@ function Zx(e) {
|
|
|
25389
25475
|
fields: {}
|
|
25390
25476
|
}), Object.entries(o).forEach(([e, r]) => {
|
|
25391
25477
|
let i = n[t].fields[e] || {};
|
|
25392
|
-
n[t].fields[e] =
|
|
25478
|
+
n[t].fields[e] = Ux(i, r);
|
|
25393
25479
|
});
|
|
25394
25480
|
} else Object.entries(o).forEach(([e, t]) => {
|
|
25395
|
-
let n = r[e] ||
|
|
25396
|
-
r[e] =
|
|
25481
|
+
let n = r[e] || O[e] || {};
|
|
25482
|
+
r[e] = Ux(n, t);
|
|
25397
25483
|
});
|
|
25398
25484
|
}), Object.values(n).forEach((e) => {
|
|
25399
25485
|
Object.entries(e.fields).forEach(([e, t]) => {
|
|
25400
25486
|
let n = r[e] || {};
|
|
25401
|
-
r[e] =
|
|
25487
|
+
r[e] = Ux(n, t);
|
|
25402
25488
|
});
|
|
25403
25489
|
}), Object.keys(n).length === 0 && Object.keys(r).length > 0 && (n.settings = {
|
|
25404
25490
|
label: t.label || "Settings",
|
|
@@ -25411,8 +25497,8 @@ function Zx(e) {
|
|
|
25411
25497
|
inVault: t.inVault !== !1,
|
|
25412
25498
|
hasCanvas: t.hasCanvas === !0,
|
|
25413
25499
|
defaultLayout: t.defaultLayout,
|
|
25414
|
-
allowedBlocks:
|
|
25415
|
-
disallowedBlocks: t.disallowedBlocks ?
|
|
25500
|
+
allowedBlocks: Hx(t.allowedBlocks),
|
|
25501
|
+
disallowedBlocks: t.disallowedBlocks ? Hx(t.disallowedBlocks) : void 0,
|
|
25416
25502
|
tabs: n,
|
|
25417
25503
|
fields: r
|
|
25418
25504
|
};
|
|
@@ -25423,11 +25509,11 @@ function Zx(e) {
|
|
|
25423
25509
|
Array.isArray(t.fieldSets) && t.fieldSets.forEach((e) => {
|
|
25424
25510
|
let t = k[e] || {}, i = t.fields || t, a = A(i, "settings", n);
|
|
25425
25511
|
Object.entries(a).forEach(([e, t]) => {
|
|
25426
|
-
r[e] =
|
|
25512
|
+
r[e] = Ux(r[e] || {}, t);
|
|
25427
25513
|
});
|
|
25428
25514
|
}), Object.values(n).forEach((e) => {
|
|
25429
25515
|
Object.entries(e.fields).forEach(([e, t]) => {
|
|
25430
|
-
r[e] =
|
|
25516
|
+
r[e] = Ux(r[e] || {}, t);
|
|
25431
25517
|
});
|
|
25432
25518
|
}), re[e] = {
|
|
25433
25519
|
...t,
|
|
@@ -25443,11 +25529,11 @@ function Zx(e) {
|
|
|
25443
25529
|
Array.isArray(t.fieldSets) && t.fieldSets.forEach((e) => {
|
|
25444
25530
|
let t = k[e] || {}, n = t.fields || t, i = A(n);
|
|
25445
25531
|
Object.entries(i).forEach(([e, t]) => {
|
|
25446
|
-
r[e] =
|
|
25532
|
+
r[e] = Ux(r[e] || {}, t);
|
|
25447
25533
|
});
|
|
25448
25534
|
}), Object.values(n).forEach((e) => {
|
|
25449
25535
|
Object.entries(e.fields).forEach(([e, t]) => {
|
|
25450
|
-
r[e] =
|
|
25536
|
+
r[e] = Ux(r[e] || {}, t);
|
|
25451
25537
|
});
|
|
25452
25538
|
}), ie[e] = {
|
|
25453
25539
|
...t,
|
|
@@ -25464,11 +25550,11 @@ function Zx(e) {
|
|
|
25464
25550
|
Array.isArray(t.fieldSets) && t.fieldSets.forEach((e) => {
|
|
25465
25551
|
let t = k[e] || {}, i = t.fields || t, a = A(i, "settings", n);
|
|
25466
25552
|
Object.entries(a).forEach(([e, t]) => {
|
|
25467
|
-
r[e] =
|
|
25553
|
+
r[e] = Ux(r[e] || {}, t);
|
|
25468
25554
|
});
|
|
25469
25555
|
}), Object.values(n).forEach((e) => {
|
|
25470
25556
|
Object.entries(e.fields).forEach(([e, t]) => {
|
|
25471
|
-
r[e] =
|
|
25557
|
+
r[e] = Ux(r[e] || {}, t);
|
|
25472
25558
|
});
|
|
25473
25559
|
}), ae[e] = {
|
|
25474
25560
|
...t,
|
|
@@ -25485,7 +25571,7 @@ function Zx(e) {
|
|
|
25485
25571
|
Array.isArray(t.fieldSets) && t.fieldSets.forEach((e) => {
|
|
25486
25572
|
let t = k[e] || {}, r = t.fields || t, i = A(r);
|
|
25487
25573
|
Object.entries(i).forEach(([e, t]) => {
|
|
25488
|
-
n[e] =
|
|
25574
|
+
n[e] = Ux(n[e] || {}, t);
|
|
25489
25575
|
});
|
|
25490
25576
|
}), oe[e] = {
|
|
25491
25577
|
...t,
|
|
@@ -25502,8 +25588,8 @@ function Zx(e) {
|
|
|
25502
25588
|
i[e] = {
|
|
25503
25589
|
...t,
|
|
25504
25590
|
label: t.label || e,
|
|
25505
|
-
allowedBlocks:
|
|
25506
|
-
disallowedBlocks: t.disallowedBlocks ?
|
|
25591
|
+
allowedBlocks: Hx(t.allowedBlocks),
|
|
25592
|
+
disallowedBlocks: t.disallowedBlocks ? Hx(t.disallowedBlocks) : void 0
|
|
25507
25593
|
};
|
|
25508
25594
|
}), se[e] = {
|
|
25509
25595
|
...t,
|
|
@@ -25519,14 +25605,14 @@ function Zx(e) {
|
|
|
25519
25605
|
};
|
|
25520
25606
|
});
|
|
25521
25607
|
let ce = {};
|
|
25522
|
-
Object.entries(
|
|
25608
|
+
Object.entries(te).forEach(([e, t]) => {
|
|
25523
25609
|
let n = ne(t.tabs), r = A(t.fields || [], "settings", n), i = {}, a = t.regions || { main: { label: "Main Content" } };
|
|
25524
25610
|
Object.entries(a).forEach(([e, t]) => {
|
|
25525
25611
|
i[e] = {
|
|
25526
25612
|
...t,
|
|
25527
25613
|
label: t.label || e,
|
|
25528
|
-
allowedBlocks:
|
|
25529
|
-
disallowedBlocks: t.disallowedBlocks ?
|
|
25614
|
+
allowedBlocks: Hx(t.allowedBlocks),
|
|
25615
|
+
disallowedBlocks: t.disallowedBlocks ? Hx(t.disallowedBlocks) : void 0
|
|
25530
25616
|
};
|
|
25531
25617
|
}), ce[e] = {
|
|
25532
25618
|
...t,
|
|
@@ -25545,7 +25631,7 @@ function Zx(e) {
|
|
|
25545
25631
|
Array.isArray(g?.fieldSets) && g?.fieldSets.forEach((e) => {
|
|
25546
25632
|
let t = k[e] || {}, n = t.fields || t, r = A(n);
|
|
25547
25633
|
Object.entries(r).forEach(([e, t]) => {
|
|
25548
|
-
le[e] =
|
|
25634
|
+
le[e] = Ux(le[e] || {}, t);
|
|
25549
25635
|
});
|
|
25550
25636
|
});
|
|
25551
25637
|
let ue = g ? {
|
|
@@ -25555,7 +25641,7 @@ function Zx(e) {
|
|
|
25555
25641
|
Array.isArray(_?.fieldSets) && _?.fieldSets.forEach((e) => {
|
|
25556
25642
|
let t = k[e] || {}, n = t.fields || t, r = A(n);
|
|
25557
25643
|
Object.entries(r).forEach(([e, t]) => {
|
|
25558
|
-
de[e] =
|
|
25644
|
+
de[e] = Ux(de[e] || {}, t);
|
|
25559
25645
|
});
|
|
25560
25646
|
});
|
|
25561
25647
|
let fe = _ ? {
|
|
@@ -25579,11 +25665,11 @@ function Zx(e) {
|
|
|
25579
25665
|
}
|
|
25580
25666
|
//#endregion
|
|
25581
25667
|
//#region server/routes/admin/schemas.ts
|
|
25582
|
-
var
|
|
25668
|
+
var $x = new e(), eS = (e) => {
|
|
25583
25669
|
try {
|
|
25584
25670
|
let t = e.env?.BUNDLED_DEFINITIONS;
|
|
25585
25671
|
(!t || Object.keys(t).length === 0) && (t = Db || Eb || Tb);
|
|
25586
|
-
let n =
|
|
25672
|
+
let n = Xx(t);
|
|
25587
25673
|
return e.json(n, 200, { "Cache-Control": "no-cache, no-store, must-revalidate" });
|
|
25588
25674
|
} catch (t) {
|
|
25589
25675
|
return console.error("[CMS API] Error loading schemas:", t), e.json({
|
|
@@ -25592,10 +25678,10 @@ var Qx = new e(), $x = (e) => {
|
|
|
25592
25678
|
}, 500);
|
|
25593
25679
|
}
|
|
25594
25680
|
};
|
|
25595
|
-
|
|
25681
|
+
$x.get("/", eS), $x.get("/schemas.json", eS);
|
|
25596
25682
|
//#endregion
|
|
25597
25683
|
//#region server/routes/admin/validation.ts
|
|
25598
|
-
var
|
|
25684
|
+
var tS = new e(), nS = {
|
|
25599
25685
|
node: "content_nodes",
|
|
25600
25686
|
nodes: "content_nodes",
|
|
25601
25687
|
content_node: "content_nodes",
|
|
@@ -25607,7 +25693,7 @@ var eS = new e(), tS = {
|
|
|
25607
25693
|
user: "users",
|
|
25608
25694
|
users: "users",
|
|
25609
25695
|
user_account: "user_accounts"
|
|
25610
|
-
},
|
|
25696
|
+
}, rS = {
|
|
25611
25697
|
content_nodes: [
|
|
25612
25698
|
"id",
|
|
25613
25699
|
"title",
|
|
@@ -25664,11 +25750,11 @@ var eS = new e(), tS = {
|
|
|
25664
25750
|
"createdAt"
|
|
25665
25751
|
]
|
|
25666
25752
|
};
|
|
25667
|
-
|
|
25753
|
+
tS.post("/validate-unique", async (e) => {
|
|
25668
25754
|
try {
|
|
25669
25755
|
let t = e.get("db"), { entityType: n, field: r, value: i, excludeId: a } = await e.req.json();
|
|
25670
25756
|
if (!r || i == null || String(i).trim() === "") return e.json({ isUnique: !0 });
|
|
25671
|
-
let o =
|
|
25757
|
+
let o = nS[n] || "content_nodes", s = r.replace(/[^a-zA-Z0-9_]/g, ""), c = (rS[o] || rS.content_nodes).includes(s), l = -1;
|
|
25672
25758
|
if (a != null && String(a).trim() !== "") {
|
|
25673
25759
|
let e = Number(a);
|
|
25674
25760
|
l = isNaN(e) ? String(a) : e;
|
|
@@ -25680,16 +25766,16 @@ eS.post("/validate-unique", async (e) => {
|
|
|
25680
25766
|
} catch (t) {
|
|
25681
25767
|
return console.error("[API Validation] Error validating global uniqueness:", t), e.json({ error: "Failed to validate uniqueness" }, 500);
|
|
25682
25768
|
}
|
|
25683
|
-
}),
|
|
25769
|
+
}), tS.post("/validate-unique-sibling", async (e) => e.json({ isUnique: !0 }));
|
|
25684
25770
|
//#endregion
|
|
25685
25771
|
//#region server/routes/admin/stats.ts
|
|
25686
|
-
var
|
|
25687
|
-
|
|
25772
|
+
var iS = new e();
|
|
25773
|
+
iS.get("/", async (e) => {
|
|
25688
25774
|
try {
|
|
25689
|
-
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
|
|
25775
|
+
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\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\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\n ORDER BY updatedAt DESC \n LIMIT 5\n ").all(), u = (Array.isArray(l) ? l : l?.results || []).map((e) => ({
|
|
25690
25776
|
...e,
|
|
25691
25777
|
isHidden: !!e.isHidden
|
|
25692
|
-
})), d = await t.prepare("\n
|
|
25778
|
+
})), d = await t.prepare("\n WITH pending_drafts AS (\n SELECT id, title, slug, contentType, isHidden, status, publishedAt, hasUnpublishedChanges, updatedAt\n FROM content_nodes\n WHERE deletedAt IS NULL\n AND (status = 'draft' OR hasUnpublishedChanges = 1)\n ORDER BY updatedAt DESC\n LIMIT 100\n )\n SELECT \n pd.*,\n GROUP_CONCAT(DISTINCT ch.label) as channelLabels,\n GROUP_CONCAT(DISTINCT t.label) as treeLabels\n FROM pending_drafts pd\n LEFT JOIN node_channels nc ON pd.id = nc.nodeId\n LEFT JOIN channels ch ON nc.channelId = ch.id\n LEFT JOIN tree_nodes tn ON pd.id = tn.contentId\n LEFT JOIN trees t ON tn.treeId = t.id\n GROUP BY pd.id\n ORDER BY pd.updatedAt DESC\n ").all(), f = (Array.isArray(d) ? d : d?.results || []).map((e) => ({
|
|
25693
25779
|
id: e.id,
|
|
25694
25780
|
title: e.title,
|
|
25695
25781
|
slug: e.slug,
|
|
@@ -25729,8 +25815,8 @@ rS.get("/", async (e) => {
|
|
|
25729
25815
|
});
|
|
25730
25816
|
//#endregion
|
|
25731
25817
|
//#region server/routes/admin/assets.ts
|
|
25732
|
-
var
|
|
25733
|
-
async function
|
|
25818
|
+
var aS = new e();
|
|
25819
|
+
async function oS(e, t, n = []) {
|
|
25734
25820
|
let r = e.prepare(t);
|
|
25735
25821
|
if (typeof r.bind == "function") {
|
|
25736
25822
|
let e = await r.bind(...n).all();
|
|
@@ -25742,16 +25828,16 @@ async function aS(e, t, n = []) {
|
|
|
25742
25828
|
}
|
|
25743
25829
|
return [];
|
|
25744
25830
|
}
|
|
25745
|
-
async function
|
|
25831
|
+
async function sS(e, t, n = []) {
|
|
25746
25832
|
let r = e.prepare(t);
|
|
25747
25833
|
if (typeof r.bind == "function") return await r.bind(...n).run();
|
|
25748
25834
|
if (typeof r.run == "function") return await r.run(...n);
|
|
25749
25835
|
}
|
|
25750
|
-
function
|
|
25836
|
+
function cS(e, t, n) {
|
|
25751
25837
|
let r = e || (t ? `/media/${t}` : "");
|
|
25752
25838
|
return r && n && r.startsWith(`https://${n}/`) && !r.includes("/media/") && (r = r.replace(`https://${n}/`, `https://${n}/media/`)), r;
|
|
25753
25839
|
}
|
|
25754
|
-
|
|
25840
|
+
aS.get("/", async (e) => {
|
|
25755
25841
|
try {
|
|
25756
25842
|
let t = wb(e), { search: n = "", type: r = "all", page: i = "1", limit: a = "24", sort: o = "createdAt", order: s = "DESC", nodeId: c, channelId: l, trashed: u } = e.req.query(), d = Math.max(1, parseInt(i, 10) || 1), f = Math.max(1, Math.min(100, parseInt(a, 10) || 24)), p = (d - 1) * f, m = {
|
|
25757
25843
|
createdAt: "a.createdAt",
|
|
@@ -25761,7 +25847,7 @@ iS.get("/", async (e) => {
|
|
|
25761
25847
|
sizeBytes: "a.sizeBytes"
|
|
25762
25848
|
}[o] || "a.createdAt", h = s.toUpperCase() === "ASC" ? "ASC" : "DESC", g = [], _ = ["(a.isSystemVariant = 0 OR a.isSystemVariant IS NULL)", u === "true" || u === "1" ? "(a.deletedAt IS NOT NULL AND a.deletedAt != '')" : "(a.deletedAt IS NULL OR a.deletedAt = '')"];
|
|
25763
25849
|
if (c) {
|
|
25764
|
-
let e = await
|
|
25850
|
+
let e = await oS(t, "SELECT a.id, a.filename, a.isSystemVariant FROM node_assets na JOIN assets a ON na.assetId = a.id WHERE na.nodeId = ?", [Number(c)]);
|
|
25765
25851
|
if (e.length === 0) _.push("1 = 0");
|
|
25766
25852
|
else {
|
|
25767
25853
|
let t = e.map((e) => e.isSystemVariant ? `(a.id = '${e.id}' OR a.id IN (SELECT parentAssetId FROM assets WHERE id = '${e.id}'))` : `a.id = '${e.id}'`).join(" OR ");
|
|
@@ -25775,10 +25861,10 @@ iS.get("/", async (e) => {
|
|
|
25775
25861
|
n && n.trim() !== "" && (_.push("a.filename LIKE ?"), g.push(`%${n.trim()}%`)), r && r !== "all" && (r === "image" ? (_.push("a.mimeType LIKE ?"), g.push("image/%")) : r === "document" ? (_.push("(a.mimeType LIKE ? OR a.mimeType LIKE ? OR a.mimeType LIKE ?)"), g.push("application/pdf%", "application/msword%", "application/vnd%")) : r === "video" && (_.push("(a.mimeType LIKE ? OR a.mimeType LIKE ?)"), g.push("video/%", "audio/%")));
|
|
25776
25862
|
let v = `SELECT a.id, a.filename, a.mimeType, a.sizeBytes, a.cdnUrl, a.storageKeyPrivate, a.createdAt, a.updatedAt, a.deletedAt, a.dataJson FROM assets a ${` WHERE ${_.join(" AND ")}`} ORDER BY ${m} ${h} LIMIT ? OFFSET ?`;
|
|
25777
25863
|
g.push(f, p);
|
|
25778
|
-
let y = await
|
|
25864
|
+
let y = await oS(t, v, g), b = y.map((e) => e.id), x = /* @__PURE__ */ new Map(), S = /* @__PURE__ */ new Map();
|
|
25779
25865
|
if (b.length > 0) {
|
|
25780
25866
|
let e = b.map(() => "?").join(",");
|
|
25781
|
-
(await
|
|
25867
|
+
(await oS(t, `
|
|
25782
25868
|
SELECT master.id AS assetId, COUNT(DISTINCT na.nodeId) AS count
|
|
25783
25869
|
FROM assets master
|
|
25784
25870
|
INNER JOIN node_assets na ON (
|
|
@@ -25786,7 +25872,7 @@ iS.get("/", async (e) => {
|
|
|
25786
25872
|
EXISTS (SELECT 1 FROM assets crop WHERE crop.id = na.assetId AND crop.isSystemVariant = 1 AND crop.parentAssetId = master.id)
|
|
25787
25873
|
)
|
|
25788
25874
|
WHERE master.id IN (${e})
|
|
25789
|
-
GROUP BY master.id`, b)).forEach((e) => x.set(String(e.assetId), e.count || 0)), (await
|
|
25875
|
+
GROUP BY master.id`, b)).forEach((e) => x.set(String(e.assetId), e.count || 0)), (await oS(t, `
|
|
25790
25876
|
SELECT parentAssetId, COUNT(id) AS count
|
|
25791
25877
|
FROM assets
|
|
25792
25878
|
WHERE isSystemVariant = 1 AND parentAssetId IN (${e})
|
|
@@ -25804,7 +25890,7 @@ iS.get("/", async (e) => {
|
|
|
25804
25890
|
...JSON.parse(t.dataJson || "{}")
|
|
25805
25891
|
};
|
|
25806
25892
|
} catch {}
|
|
25807
|
-
let r =
|
|
25893
|
+
let r = cS(t.cdnUrl, t.storageKeyPrivate, e.env?.CDN_DOMAIN);
|
|
25808
25894
|
return {
|
|
25809
25895
|
id: t.id,
|
|
25810
25896
|
filename: t.filename || "Untitled Asset",
|
|
@@ -25829,7 +25915,7 @@ iS.get("/", async (e) => {
|
|
|
25829
25915
|
details: t.message || String(t)
|
|
25830
25916
|
}, 500);
|
|
25831
25917
|
}
|
|
25832
|
-
}),
|
|
25918
|
+
}), aS.post("/upload", async (e) => {
|
|
25833
25919
|
try {
|
|
25834
25920
|
let t = wb(e), { storage: n } = ix(e.env), r = await e.req.parseBody(), i = r.file, a = r.isVariant === "true" || r.isVariant === "1" || r.temporary === "true", o = r.replaceAssetId, s = typeof o == "string" && o.trim().length > 0 ? o.trim() : null, c = r.parentAssetId || r.parentAsset, l = typeof c == "string" && c.trim().length > 0 ? c.trim() : null;
|
|
25835
25921
|
if (!i || !(i instanceof File)) return e.json({ error: "No file uploaded" }, 400);
|
|
@@ -25845,13 +25931,13 @@ iS.get("/", async (e) => {
|
|
|
25845
25931
|
let p = crypto.randomUUID().replace(/-/g, "").slice(0, 12), m = (/* @__PURE__ */ new Date()).toISOString().slice(0, 7).replace("-", "/"), h = a || i.name.startsWith("crop_"), g = h ? `kama/cache/${m}/${p}` : `kama/uploads/${m}/${p}`, _ = await n.upload(i, g), v = typeof _ == "string" ? _ : _?.key || _?.storageKeyPrivate || _?.storageKey || `${g}/${p}_${i.name}`;
|
|
25846
25932
|
if (!v) throw Error("Storage provider failed to return a valid storage key");
|
|
25847
25933
|
let y = e.env.CDN_DOMAIN, b = v.replace(/^\//, ""), x = y ? `https://${y}/media/${b}` : `/media/${b}`, S = i.type || "application/octet-stream", C = i.size || 0, w = e.get("userId"), T = typeof w == "string" && w.trim().length > 0 ? w : null;
|
|
25848
|
-
T && (await
|
|
25934
|
+
T && (await oS(t, "SELECT id FROM users WHERE id = ?", [T])).length === 0 && (T = null);
|
|
25849
25935
|
let ee = new mx(e.env);
|
|
25850
25936
|
if (s) {
|
|
25851
|
-
let r = await
|
|
25937
|
+
let r = await oS(t, "SELECT storageKeyPrivate, isSystemVariant, parentAssetId FROM assets WHERE id = ?", [s]);
|
|
25852
25938
|
if (r.length > 0) {
|
|
25853
25939
|
let a = r[0];
|
|
25854
|
-
if (await
|
|
25940
|
+
if (await sS(t, "UPDATE assets SET filename = ?, mimeType = ?, sizeBytes = ?, storageKeyPrivate = ?, cdnUrl = ?, updatedAt = CURRENT_TIMESTAMP WHERE id = ?", [
|
|
25855
25941
|
i.name,
|
|
25856
25942
|
S,
|
|
25857
25943
|
C,
|
|
@@ -25880,7 +25966,7 @@ iS.get("/", async (e) => {
|
|
|
25880
25966
|
}
|
|
25881
25967
|
}
|
|
25882
25968
|
let E = `ast_${p}`, D = +!!h;
|
|
25883
|
-
await
|
|
25969
|
+
await sS(t, "INSERT INTO assets (id, filename, mimeType, sizeBytes, storageKeyPrivate, cdnUrl, createdById, isSystemVariant, parentAssetId, cropCoordinatesJson) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", [
|
|
25884
25970
|
E,
|
|
25885
25971
|
i.name,
|
|
25886
25972
|
S,
|
|
@@ -25892,15 +25978,15 @@ iS.get("/", async (e) => {
|
|
|
25892
25978
|
l,
|
|
25893
25979
|
d
|
|
25894
25980
|
]);
|
|
25895
|
-
let
|
|
25981
|
+
let te = x;
|
|
25896
25982
|
if (l) {
|
|
25897
|
-
let n = await
|
|
25898
|
-
n.length > 0 && (
|
|
25983
|
+
let n = await oS(t, "SELECT cdnUrl, storageKeyPrivate FROM assets WHERE id = ?", [l]);
|
|
25984
|
+
n.length > 0 && (te = cS(n[0].cdnUrl, n[0].storageKeyPrivate, y)), ee.purgeAsset(e, t, l);
|
|
25899
25985
|
}
|
|
25900
25986
|
return e.json({
|
|
25901
25987
|
id: E,
|
|
25902
25988
|
url: x,
|
|
25903
|
-
originalUrl:
|
|
25989
|
+
originalUrl: te,
|
|
25904
25990
|
parentAssetId: l,
|
|
25905
25991
|
cropCoordinates: f,
|
|
25906
25992
|
filename: i.name,
|
|
@@ -25914,11 +26000,11 @@ iS.get("/", async (e) => {
|
|
|
25914
26000
|
details: t.message || String(t)
|
|
25915
26001
|
}, 500);
|
|
25916
26002
|
}
|
|
25917
|
-
}),
|
|
26003
|
+
}), aS.get("/:id/details", async (e) => {
|
|
25918
26004
|
try {
|
|
25919
|
-
let t = wb(e), n = e.req.param("id"), r = await
|
|
26005
|
+
let t = wb(e), n = e.req.param("id"), r = await oS(t, "SELECT * FROM assets WHERE id = ?", [n]);
|
|
25920
26006
|
if (!r || r.length === 0) return e.json({ error: "Asset not found" }, 404);
|
|
25921
|
-
let i = r[0], a = await
|
|
26007
|
+
let i = r[0], a = await oS(t, "\n SELECT DISTINCT cn.id, cn.title, cn.contentType, cn.slug, na.fieldKey, na.assetId \n FROM node_assets na \n INNER JOIN content_nodes cn ON na.nodeId = cn.id \n LEFT JOIN assets crop ON na.assetId = crop.id \n WHERE na.assetId = ? OR (crop.isSystemVariant = 1 AND crop.parentAssetId = ?)\n ", [n, n]), o = await oS(t, "\n SELECT id, filename, mimeType, sizeBytes, cdnUrl, storageKeyPrivate, parentAssetId, cropCoordinatesJson, createdAt, updatedAt \n FROM assets \n WHERE isSystemVariant = 1 AND parentAssetId = ? \n ORDER BY createdAt DESC\n ", [n]), s = {
|
|
25922
26008
|
title: "",
|
|
25923
26009
|
alt: "",
|
|
25924
26010
|
description: ""
|
|
@@ -25929,7 +26015,7 @@ iS.get("/", async (e) => {
|
|
|
25929
26015
|
...JSON.parse(i.dataJson || "{}")
|
|
25930
26016
|
};
|
|
25931
26017
|
} catch {}
|
|
25932
|
-
let c = i.updatedAt ? new Date(i.updatedAt).getTime() : Date.now(), l = `${
|
|
26018
|
+
let c = i.updatedAt ? new Date(i.updatedAt).getTime() : Date.now(), l = `${cS(i.cdnUrl, i.storageKeyPrivate, e.env?.CDN_DOMAIN)}?v=${c}`;
|
|
25933
26019
|
return e.json({
|
|
25934
26020
|
id: i.id,
|
|
25935
26021
|
filename: i.filename,
|
|
@@ -25948,7 +26034,7 @@ iS.get("/", async (e) => {
|
|
|
25948
26034
|
if (t.cropCoordinatesJson) try {
|
|
25949
26035
|
n = JSON.parse(t.cropCoordinatesJson);
|
|
25950
26036
|
} catch {}
|
|
25951
|
-
let r = t.updatedAt ? new Date(t.updatedAt).getTime() : c, a =
|
|
26037
|
+
let r = t.updatedAt ? new Date(t.updatedAt).getTime() : c, a = cS(t.cdnUrl, t.storageKeyPrivate, e.env?.CDN_DOMAIN);
|
|
25952
26038
|
return {
|
|
25953
26039
|
id: t.id,
|
|
25954
26040
|
filename: t.filename,
|
|
@@ -25965,15 +26051,15 @@ iS.get("/", async (e) => {
|
|
|
25965
26051
|
} catch {
|
|
25966
26052
|
return e.json({ error: "Failed to load details" }, 500);
|
|
25967
26053
|
}
|
|
25968
|
-
}),
|
|
26054
|
+
}), aS.put("/:id", async (e) => {
|
|
25969
26055
|
try {
|
|
25970
|
-
let t = wb(e), n = e.req.param("id"), r = await e.req.json(), i = await
|
|
26056
|
+
let t = wb(e), n = e.req.param("id"), r = await e.req.json(), i = await oS(t, "SELECT filename, dataJson FROM assets WHERE id = ?", [n]);
|
|
25971
26057
|
if (!i || i.length === 0) return e.json({ error: "Asset not found" }, 404);
|
|
25972
26058
|
let a = i[0], o = {};
|
|
25973
26059
|
try {
|
|
25974
26060
|
o = JSON.parse(a.dataJson || "{}");
|
|
25975
26061
|
} catch {}
|
|
25976
|
-
return r.title !== void 0 && (o.title = r.title), r.alt !== void 0 && (o.alt = r.alt), r.description !== void 0 && (o.description = r.description), await
|
|
26062
|
+
return r.title !== void 0 && (o.title = r.title), r.alt !== void 0 && (o.alt = r.alt), r.description !== void 0 && (o.description = r.description), await sS(t, "UPDATE assets SET filename = ?, dataJson = ?, updatedAt = CURRENT_TIMESTAMP WHERE id = ?", [
|
|
25977
26063
|
r.filename === void 0 ? a.filename : r.filename,
|
|
25978
26064
|
JSON.stringify(o),
|
|
25979
26065
|
n
|
|
@@ -25981,10 +26067,10 @@ iS.get("/", async (e) => {
|
|
|
25981
26067
|
} catch {
|
|
25982
26068
|
return e.json({ error: "Failed to update asset" }, 500);
|
|
25983
26069
|
}
|
|
25984
|
-
}),
|
|
26070
|
+
}), aS.delete("/:id", async (e) => {
|
|
25985
26071
|
try {
|
|
25986
|
-
let t = wb(e), n = e.req.param("id"), r = (await
|
|
25987
|
-
return r ? (new mx(e.env).purgeAsset(e, t, n), r.isSystemVariant ? await
|
|
26072
|
+
let t = wb(e), n = e.req.param("id"), r = (await oS(t, "SELECT id, filename, isSystemVariant FROM assets WHERE id = ?", [n]))[0];
|
|
26073
|
+
return r ? (new mx(e.env).purgeAsset(e, t, n), r.isSystemVariant ? await sS(t, "UPDATE assets SET deletedAt = CURRENT_TIMESTAMP WHERE id = ?", [n]) : await sS(t, "UPDATE assets SET deletedAt = CURRENT_TIMESTAMP WHERE id = ? OR (isSystemVariant = 1 AND parentAssetId = ?)", [n, n]), e.json({
|
|
25988
26074
|
success: !0,
|
|
25989
26075
|
id: n,
|
|
25990
26076
|
trashed: !0
|
|
@@ -25995,10 +26081,10 @@ iS.get("/", async (e) => {
|
|
|
25995
26081
|
details: t.message || String(t)
|
|
25996
26082
|
}, 500);
|
|
25997
26083
|
}
|
|
25998
|
-
}),
|
|
26084
|
+
}), aS.post("/restore", async (e) => {
|
|
25999
26085
|
try {
|
|
26000
26086
|
let t = wb(e), n = await e.req.json(), r = n.id || n.assetId;
|
|
26001
|
-
return r ? (await
|
|
26087
|
+
return r ? (await oS(t, "SELECT id, filename FROM assets WHERE id = ?", [r]))[0] ? (await sS(t, "UPDATE assets SET deletedAt = NULL WHERE id = ? OR (isSystemVariant = 1 AND parentAssetId = ?)", [r, r]), new mx(e.env).purgeAsset(e, t, r), e.json({
|
|
26002
26088
|
success: !0,
|
|
26003
26089
|
id: r,
|
|
26004
26090
|
restored: !0
|
|
@@ -26009,13 +26095,13 @@ iS.get("/", async (e) => {
|
|
|
26009
26095
|
details: t.message
|
|
26010
26096
|
}, 500);
|
|
26011
26097
|
}
|
|
26012
|
-
}),
|
|
26098
|
+
}), aS.delete("/purge/:id", async (e) => {
|
|
26013
26099
|
try {
|
|
26014
|
-
let t = wb(e), { storage: n } = ix(e.env), r = e.req.param("id"), i = (await
|
|
26100
|
+
let t = wb(e), { storage: n } = ix(e.env), r = e.req.param("id"), i = (await oS(t, "SELECT id, filename, storageKeyPrivate, isSystemVariant FROM assets WHERE id = ?", [r]))[0];
|
|
26015
26101
|
if (!i) return e.json({ error: "Asset not found" }, 404);
|
|
26016
26102
|
new mx(e.env).purgeAsset(e, t, r);
|
|
26017
26103
|
let a = [i];
|
|
26018
|
-
i.isSystemVariant || (a = [i, ...await
|
|
26104
|
+
i.isSystemVariant || (a = [i, ...await oS(t, "SELECT id, storageKeyPrivate FROM assets WHERE isSystemVariant = 1 AND parentAssetId = ?", [r])]);
|
|
26019
26105
|
let o = a.map((e) => e.id);
|
|
26020
26106
|
if (typeof n.delete == "function") {
|
|
26021
26107
|
for (let e of a) if (e.storageKeyPrivate) try {
|
|
@@ -26025,7 +26111,7 @@ iS.get("/", async (e) => {
|
|
|
26025
26111
|
}
|
|
26026
26112
|
}
|
|
26027
26113
|
let s = o.map(() => "?").join(",");
|
|
26028
|
-
return await
|
|
26114
|
+
return await sS(t, `DELETE FROM node_assets WHERE assetId IN (${s})`, o), await sS(t, `DELETE FROM assets WHERE id IN (${s})`, o), e.json({
|
|
26029
26115
|
success: !0,
|
|
26030
26116
|
id: r,
|
|
26031
26117
|
purged: !0,
|
|
@@ -26041,8 +26127,8 @@ iS.get("/", async (e) => {
|
|
|
26041
26127
|
});
|
|
26042
26128
|
//#endregion
|
|
26043
26129
|
//#region server/routes/public/node.ts
|
|
26044
|
-
var
|
|
26045
|
-
function
|
|
26130
|
+
var lS = new $y();
|
|
26131
|
+
function uS() {
|
|
26046
26132
|
return {
|
|
26047
26133
|
fullPath: /* @__PURE__ */ new Map(),
|
|
26048
26134
|
treeEdges: /* @__PURE__ */ new Map(),
|
|
@@ -26050,7 +26136,7 @@ function lS() {
|
|
|
26050
26136
|
assetUrls: /* @__PURE__ */ new Map()
|
|
26051
26137
|
};
|
|
26052
26138
|
}
|
|
26053
|
-
function
|
|
26139
|
+
function dS(e, t, n = []) {
|
|
26054
26140
|
let r = Date.now();
|
|
26055
26141
|
if (e && String(e).trim() !== "") {
|
|
26056
26142
|
let t = Date.parse(e);
|
|
@@ -26061,7 +26147,7 @@ function uS(e, t, n = []) {
|
|
|
26061
26147
|
!isNaN(e) && e > r && n.push(e);
|
|
26062
26148
|
}
|
|
26063
26149
|
}
|
|
26064
|
-
function
|
|
26150
|
+
function fS(e, t) {
|
|
26065
26151
|
let n = Date.now();
|
|
26066
26152
|
if (e && String(e).trim() !== "") {
|
|
26067
26153
|
let t = Date.parse(e);
|
|
@@ -26073,13 +26159,15 @@ function dS(e, t) {
|
|
|
26073
26159
|
}
|
|
26074
26160
|
return !0;
|
|
26075
26161
|
}
|
|
26076
|
-
async function
|
|
26162
|
+
async function pS(e, t, n, r, i) {
|
|
26077
26163
|
let a = t.filter((e) => e.componentId === "content-feed" || e.componentId === "article-list" || e.componentId === "nodeList" || e.componentId === "node-list");
|
|
26078
26164
|
await Promise.all(a.map(async (t) => {
|
|
26079
26165
|
let a = t.data || {}, o = a.nodeType || ["article"], s = (Array.isArray(o) ? o : String(o).split(",")).map((e) => String(e).trim()).filter(Boolean), c = Number(a.limit) || 12, l = Number(a.offset) || 0, u = a.sortBy || "updatedAt", d = new URLSearchParams();
|
|
26080
26166
|
d.set("nodeType", s.join(",")), d.set("limit", c.toString()), d.set("offset", (l + c).toString()), d.set("sortBy", u), n && n !== "all" && d.set("channelId", String(n));
|
|
26081
|
-
let f = `FROM content_nodes WHERE contentType IN (${s.map(() => "?").join(",")}) AND isHidden = 0 AND (status = 'published'
|
|
26082
|
-
n && n !== "all" && (f += " AND
|
|
26167
|
+
let f = `FROM content_nodes WHERE contentType IN (${s.map(() => "?").join(",")}) AND isHidden = 0 AND IFNULL(status, 'published') = 'published'`, p = [...s];
|
|
26168
|
+
n && n !== "all" && (f += " AND EXISTS (SELECT 1 FROM node_channels nc WHERE nc.nodeId = content_nodes.id AND nc.channelId = ?)", p.push(Number(n) || n));
|
|
26169
|
+
let m = (/* @__PURE__ */ new Date()).toISOString();
|
|
26170
|
+
f += " AND IFNULL(json_extract(dataJson, '$.startShowingAt'), '') <= ?", p.push(m), f += " AND IFNULL(json_extract(dataJson, '$.stopShowingAt'), '9999-12-31') >= ?", p.push(m);
|
|
26083
26171
|
for (let e of [
|
|
26084
26172
|
"authors",
|
|
26085
26173
|
"categories",
|
|
@@ -26099,18 +26187,18 @@ async function fS(e, t, n, r, i) {
|
|
|
26099
26187
|
f += e === "authors" ? ` AND EXISTS (SELECT 1 FROM node_relations nr WHERE nr.sourceNodeId = content_nodes.id AND nr.fieldKey = ? AND nr.targetNodeId IN (${n}))` : ` AND EXISTS (SELECT 1 FROM node_terms nt INNER JOIN taxonomy_terms tt ON nt.termId = tt.id WHERE nt.nodeId = content_nodes.id AND tt.taxonomy = ? AND tt.key IN (${n}))`, p.push(e, ...t);
|
|
26100
26188
|
}
|
|
26101
26189
|
}
|
|
26102
|
-
let
|
|
26103
|
-
u === "published_desc" || u === "createdAt" ?
|
|
26104
|
-
let
|
|
26190
|
+
let h = "ORDER BY updatedAt DESC";
|
|
26191
|
+
u === "published_desc" || u === "createdAt" ? h = "ORDER BY createdAt DESC" : u === "title_asc" && (h = "ORDER BY LOWER(title) ASC");
|
|
26192
|
+
let g = `SELECT id, title, slug, language, dataJson, createdAt, updatedAt ${f} ${h} LIMIT ? OFFSET ?`;
|
|
26105
26193
|
p.push(c, l);
|
|
26106
26194
|
try {
|
|
26107
|
-
let n = await e.prepare(
|
|
26108
|
-
t.data.initialItems =
|
|
26195
|
+
let n = await e.prepare(g).all(...p), o = Array.isArray(n) ? n : n?.results || [];
|
|
26196
|
+
t.data.initialItems = o.map((e) => {
|
|
26109
26197
|
let t = {};
|
|
26110
26198
|
if (e.dataJson) try {
|
|
26111
26199
|
t = typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson;
|
|
26112
26200
|
} catch {}
|
|
26113
|
-
return i &&
|
|
26201
|
+
return i && dS(t.startShowingAt, t.stopShowingAt, i), {
|
|
26114
26202
|
id: e.id,
|
|
26115
26203
|
title: e.title,
|
|
26116
26204
|
slug: e.slug,
|
|
@@ -26120,14 +26208,14 @@ async function fS(e, t, n, r, i) {
|
|
|
26120
26208
|
excerpt: t.excerpt || "",
|
|
26121
26209
|
image: t.image || t.coverImage || null,
|
|
26122
26210
|
author: t.author || null
|
|
26123
|
-
}
|
|
26124
|
-
})
|
|
26211
|
+
};
|
|
26212
|
+
}), a.disablePagination !== !0 && a.disablePagination !== "1" && o.length === c ? t.data.loadMoreUrl = `/api/v1/nodes?${d.toString()}` : t.data.loadMoreUrl = null;
|
|
26125
26213
|
} catch (e) {
|
|
26126
26214
|
console.error("[CMS Hydration] Failed to hydrate content feed block", e), t.data.initialItems = [], t.data.loadMoreUrl = null;
|
|
26127
26215
|
}
|
|
26128
26216
|
}));
|
|
26129
26217
|
}
|
|
26130
|
-
async function
|
|
26218
|
+
async function mS(e, t, n, r, i, a = !1, o, s) {
|
|
26131
26219
|
if (!t) return { blocks: [] };
|
|
26132
26220
|
let c = await e.prepare("\n WITH RECURSIVE ancestor_path(contentId, title, slug, parentId, level) AS (\n SELECT t.contentId, c.title, c.slug, t.parentId, 0 FROM tree_nodes t INNER JOIN content_nodes c ON t.contentId = c.id WHERE t.contentId = ? AND t.treeId = ?\n UNION ALL\n SELECT t.contentId, c.title, c.slug, t.parentId, ap.level + 1 FROM tree_nodes t INNER JOIN content_nodes c ON t.contentId = c.id INNER JOIN ancestor_path ap ON t.contentId = ap.parentId AND t.treeId = ?\n )\n SELECT * FROM ancestor_path ORDER BY level ASC\n ").all(t, n, n), l = Array.isArray(c) ? c : c?.results || [];
|
|
26133
26221
|
if (!l || l.length === 0) return { blocks: [] };
|
|
@@ -26163,11 +26251,11 @@ async function pS(e, t, n, r, i, a = !1, o, s) {
|
|
|
26163
26251
|
try {
|
|
26164
26252
|
n = (typeof t.dataJson == "string" ? JSON.parse(t.dataJson) : t.dataJson) || {};
|
|
26165
26253
|
} catch {}
|
|
26166
|
-
s &&
|
|
26167
|
-
let o = n.hidden === !0 || n.hidden === 1 || n.hidden === "1" || n.hidden === "true", c =
|
|
26254
|
+
s && dS(n.startShowingAt, n.stopShowingAt, s);
|
|
26255
|
+
let o = n.hidden === !0 || n.hidden === 1 || n.hidden === "1" || n.hidden === "true", c = fS(n.startShowingAt, n.stopShowingAt);
|
|
26168
26256
|
if (!a && (o || !c)) return null;
|
|
26169
|
-
let l = t.elementType || t.componentId || "text-block", u = i.blocks?.[l]?.fields || i.elements?.[l]?.fields || i.components?.[l]?.fields || {}, d = String(n.blockId || n._instanceId || n.id || t.blockId || t.id), f =
|
|
26170
|
-
return f = await fx(e, f), f =
|
|
26257
|
+
let l = t.elementType || t.componentId || "text-block", u = i.blocks?.[l]?.fields || i.elements?.[l]?.fields || i.components?.[l]?.fields || {}, d = String(n.blockId || n._instanceId || n.id || t.blockId || t.id), f = hS(n, u);
|
|
26258
|
+
return f = await fx(e, f), f = gS(f), f.blockId = d, {
|
|
26171
26259
|
region: t.region || r,
|
|
26172
26260
|
block: {
|
|
26173
26261
|
instanceId: t.id,
|
|
@@ -26187,7 +26275,7 @@ async function pS(e, t, n, r, i, a = !1, o, s) {
|
|
|
26187
26275
|
}
|
|
26188
26276
|
return { blocks: [] };
|
|
26189
26277
|
}
|
|
26190
|
-
function
|
|
26278
|
+
function hS(e, t = {}) {
|
|
26191
26279
|
let n = {};
|
|
26192
26280
|
for (let [r, i] of Object.entries(e)) r.endsWith("_meta") || [
|
|
26193
26281
|
"disabledRegions",
|
|
@@ -26203,14 +26291,14 @@ function mS(e, t = {}) {
|
|
|
26203
26291
|
].includes(r) || r.startsWith("_") || (!t[r] || t[r].public !== !1) && (n[r] = i);
|
|
26204
26292
|
return n;
|
|
26205
26293
|
}
|
|
26206
|
-
function
|
|
26207
|
-
if (Array.isArray(e)) return e.map(
|
|
26294
|
+
function gS(e) {
|
|
26295
|
+
if (Array.isArray(e)) return e.map(gS);
|
|
26208
26296
|
if (!e || typeof e != "object") return e;
|
|
26209
26297
|
if (typeof e.id == "string" && e.id.startsWith("ast_") && typeof e.url == "string") {
|
|
26210
26298
|
let t = e.metadataOverrides || {}, n = e.variants && typeof e.variants == "object" ? e.variants : {}, r = Object.entries(n).find(([, t]) => t?.id === e.id)?.[0], i = r ? {
|
|
26211
26299
|
...t,
|
|
26212
26300
|
...t.crops?.[r] || {}
|
|
26213
|
-
} : t, a = Object.fromEntries(Object.entries(n).filter(([, t]) => t?.id !== e.id).map(([t, n]) => [t,
|
|
26301
|
+
} : t, a = Object.fromEntries(Object.entries(n).filter(([, t]) => t?.id !== e.id).map(([t, n]) => [t, gS({
|
|
26214
26302
|
...n,
|
|
26215
26303
|
title: n?.title ?? e.title ?? "",
|
|
26216
26304
|
alt: n?.alt ?? e.alt ?? "",
|
|
@@ -26224,9 +26312,9 @@ function hS(e) {
|
|
|
26224
26312
|
...Object.keys(a).length > 0 ? { variants: a } : {}
|
|
26225
26313
|
};
|
|
26226
26314
|
}
|
|
26227
|
-
return Object.fromEntries(Object.entries(e).map(([e, t]) => [e,
|
|
26315
|
+
return Object.fromEntries(Object.entries(e).map(([e, t]) => [e, gS(t)]));
|
|
26228
26316
|
}
|
|
26229
|
-
async function
|
|
26317
|
+
async function _S(e, t, n, r) {
|
|
26230
26318
|
if (typeof t == "string") {
|
|
26231
26319
|
if (!t.includes("#node:") && !t.includes("data-node-id") && !t.includes("#asset:") && !t.includes("data-asset-id")) return t;
|
|
26232
26320
|
let r = (e, t) => {
|
|
@@ -26259,25 +26347,25 @@ async function gS(e, t, n, r) {
|
|
|
26259
26347
|
return /href\s*=\s*["'][^"']*["']/i.test(d) ? d = d.replace(/href\s*=\s*["'][^"']*["']/i, `href="${u}"`) : d += ` href="${u}"`, `<a ${d}>`;
|
|
26260
26348
|
});
|
|
26261
26349
|
}
|
|
26262
|
-
if (Array.isArray(t)) return Promise.all(t.map((t) =>
|
|
26350
|
+
if (Array.isArray(t)) return Promise.all(t.map((t) => _S(e, t, n, r)));
|
|
26263
26351
|
if (t && typeof t == "object") {
|
|
26264
26352
|
if (typeof t.href == "string" && (t.href.startsWith("#node:") || t.href.startsWith("#asset:"))) return {
|
|
26265
26353
|
...t,
|
|
26266
|
-
href: await
|
|
26354
|
+
href: await vS(e, t, n, r)
|
|
26267
26355
|
};
|
|
26268
|
-
let i = await Promise.all(Object.entries(t).map(async ([t, i]) => [t, await
|
|
26356
|
+
let i = await Promise.all(Object.entries(t).map(async ([t, i]) => [t, await _S(e, i, n, r)]));
|
|
26269
26357
|
return Object.fromEntries(i);
|
|
26270
26358
|
}
|
|
26271
26359
|
return t;
|
|
26272
26360
|
}
|
|
26273
|
-
async function
|
|
26361
|
+
async function vS(e, t, n, r) {
|
|
26274
26362
|
let i = t.href.match(/^#node:(.+)$/), a = t.href.match(/^#asset:(.+)$/);
|
|
26275
|
-
if (a) return
|
|
26363
|
+
if (a) return yS(e, a[1], r);
|
|
26276
26364
|
if (!i) return t.href;
|
|
26277
26365
|
let o = i[1];
|
|
26278
26366
|
return (await e.prepare("SELECT path FROM node_routes WHERE nodeId = ? AND channelId = ? AND isCanonical = 1 LIMIT 1").get(Number(o), n))?.path || "#";
|
|
26279
26367
|
}
|
|
26280
|
-
async function
|
|
26368
|
+
async function yS(e, t, n) {
|
|
26281
26369
|
let r = String(t), i = n.assetUrls.get(r);
|
|
26282
26370
|
if (i) return i;
|
|
26283
26371
|
let a = (async () => {
|
|
@@ -26286,7 +26374,7 @@ async function vS(e, t, n) {
|
|
|
26286
26374
|
})();
|
|
26287
26375
|
return n.assetUrls.set(r, a), a;
|
|
26288
26376
|
}
|
|
26289
|
-
function
|
|
26377
|
+
function bS(e) {
|
|
26290
26378
|
let t = e.socialImage;
|
|
26291
26379
|
if (!t || typeof t != "object") return null;
|
|
26292
26380
|
let n = (e, t) => {
|
|
@@ -26317,7 +26405,7 @@ function yS(e) {
|
|
|
26317
26405
|
])
|
|
26318
26406
|
};
|
|
26319
26407
|
}
|
|
26320
|
-
async function
|
|
26408
|
+
async function xS(e, t, n, r, i) {
|
|
26321
26409
|
let a = {}, o = null;
|
|
26322
26410
|
if (t) {
|
|
26323
26411
|
let i = await e.prepare("\n WITH RECURSIVE ancestor_path(contentId, title, slug, parentId, level) AS (\n SELECT t.contentId, c.title, c.slug, t.parentId, 0 FROM tree_nodes t INNER JOIN content_nodes c ON t.contentId = c.id WHERE t.contentId = ? AND t.treeId = ?\n UNION ALL\n SELECT t.contentId, c.title, c.slug, t.parentId, ap.level + 1 FROM tree_nodes t INNER JOIN content_nodes c ON t.contentId = c.id INNER JOIN ancestor_path ap ON t.contentId = ap.parentId AND t.treeId = ?\n )\n SELECT c.dataJson, c.draftDataJson FROM ancestor_path ap INNER JOIN content_nodes c ON ap.contentId = c.id ORDER BY ap.level ASC\n ").all(t, n, n), s = Array.isArray(i) ? i : i?.results || [], c = /* @__PURE__ */ new Set([
|
|
@@ -26355,20 +26443,20 @@ async function bS(e, t, n, r, i) {
|
|
|
26355
26443
|
inheritedFields: a
|
|
26356
26444
|
};
|
|
26357
26445
|
}
|
|
26358
|
-
function
|
|
26446
|
+
function SS(e) {
|
|
26359
26447
|
let t = Number(e?.env?.CMS_NODE_CACHE_TTL);
|
|
26360
26448
|
return Number.isFinite(t) && t >= 60 ? Math.floor(t) : 300;
|
|
26361
26449
|
}
|
|
26362
|
-
async function
|
|
26450
|
+
async function CS(e, t, n, r) {
|
|
26363
26451
|
try {
|
|
26364
26452
|
await e.set(t, n, r);
|
|
26365
26453
|
} catch (e) {
|
|
26366
26454
|
console.warn("[CMS Cache] Failed to write node response to cache:", e);
|
|
26367
26455
|
}
|
|
26368
26456
|
}
|
|
26369
|
-
async function
|
|
26457
|
+
async function wS(e) {
|
|
26370
26458
|
try {
|
|
26371
|
-
let t = e.get("db"), n =
|
|
26459
|
+
let t = e.get("db"), n = uS(), r = [], i = new URL(e.req.url), a = i.searchParams.get("channelId") || i.searchParams.get("channel"), o = i.searchParams.get("lang"), s = i.searchParams.get("preview") === "true", c = i.searchParams.get("revisionId"), l = i.searchParams.get("treeId"), u = i.pathname, d = "";
|
|
26372
26460
|
u.includes("/node/") ? d = u.substring(u.indexOf("/node/") + 6) : u.endsWith("/node") && (d = "");
|
|
26373
26461
|
try {
|
|
26374
26462
|
d = decodeURIComponent(d);
|
|
@@ -26418,9 +26506,9 @@ async function CS(e) {
|
|
|
26418
26506
|
e.defaultLanguage ? w = String(e.defaultLanguage).trim() : e.language && (w = String(e.language).trim());
|
|
26419
26507
|
} catch {}
|
|
26420
26508
|
}
|
|
26421
|
-
let T = y.language?.trim() || null, ee = C || w || o?.trim() || null, E = T || ee || null, D = `node:${g || _}:${E || "default"}:${d}`,
|
|
26422
|
-
if (!s && !
|
|
26423
|
-
let t = await
|
|
26509
|
+
let T = y.language?.trim() || null, ee = C || w || o?.trim() || null, E = T || ee || null, D = `node:${g || _}:${E || "default"}:${d}`, te = e.req.header("x-bypass-cache") === "true" || !!c, O = $b(e), k = SS(e);
|
|
26510
|
+
if (!s && !te) {
|
|
26511
|
+
let t = await O.get(D);
|
|
26424
26512
|
if (t) {
|
|
26425
26513
|
e.header("X-Cache", "HIT");
|
|
26426
26514
|
let n = k;
|
|
@@ -26448,14 +26536,14 @@ async function CS(e) {
|
|
|
26448
26536
|
if (x && x.node && x.node.dataJson && (fe = x.node.dataJson), fe) try {
|
|
26449
26537
|
de = typeof fe == "string" ? JSON.parse(fe) : fe;
|
|
26450
26538
|
} catch {}
|
|
26451
|
-
de.disabledRegions && (se = de.disabledRegions), ue = de.hidden === !0 || de.hidden === 1 || de.hidden === "1" || de.hidden === "true", ce = de.startShowingAt || null, le = de.stopShowingAt || null,
|
|
26452
|
-
let pe = de.layoutId, me = pe && pe !== "inherit", { resolvedLayoutId: he, inheritedFields: ge } = await
|
|
26539
|
+
de.disabledRegions && (se = de.disabledRegions), ue = de.hidden === !0 || de.hidden === 1 || de.hidden === "1" || de.hidden === "true", ce = de.startShowingAt || null, le = de.stopShowingAt || null, dS(ce, le, r);
|
|
26540
|
+
let pe = de.layoutId, me = pe && pe !== "inherit", { resolvedLayoutId: he, inheritedFields: ge } = await xS(t, A, b, s, oe), _e = me ? pe : he || ae.defaultLayout || null;
|
|
26453
26541
|
for (let [e, t] of Object.entries(ge)) (de[e] === void 0 || de[e] === null || de[e] === "" || de[e] === "inherit") && t !== void 0 && (de[e] = t);
|
|
26454
|
-
let ve = await fx(t,
|
|
26455
|
-
ve =
|
|
26456
|
-
let ye =
|
|
26542
|
+
let ve = await fx(t, hS(de, oe));
|
|
26543
|
+
ve = gS(ve), ve = await _S(t, ve, g, n), delete ve.language;
|
|
26544
|
+
let ye = bS(ve);
|
|
26457
26545
|
delete ve.socialImage, delete ve.fbImage, delete ve.xImage, delete ve.whatsappImage, ye && (ve.socialImages = ye), Object.assign(j, ve), j.id = y.id, j.slug = y.slug, j.title = y.title, j.path = ne, j.layoutId = _e;
|
|
26458
|
-
let be = Number(y.isHidden) === 1 || ue, xe = !
|
|
26546
|
+
let be = Number(y.isHidden) === 1 || ue, xe = !fS(ce, le), Se = y.status === "draft" || y.status === "new", Ce = y.dataJson && y.dataJson !== "{}" && y.dataJson !== "null";
|
|
26459
26547
|
if (!s && (be || xe || Se && !Ce)) return e.json({ error: "Node is hidden, offline, or has never been published." }, 404);
|
|
26460
26548
|
let we = [];
|
|
26461
26549
|
if (S?.treeNodeId) {
|
|
@@ -26466,8 +26554,8 @@ async function CS(e) {
|
|
|
26466
26554
|
try {
|
|
26467
26555
|
t = (typeof n == "string" ? JSON.parse(n) : n) || {};
|
|
26468
26556
|
} catch {}
|
|
26469
|
-
let i = Number(e.isHidden) === 1 || t.hidden === !0 || t.hidden === 1 || t.hidden === "1", o =
|
|
26470
|
-
return
|
|
26557
|
+
let i = Number(e.isHidden) === 1 || t.hidden === !0 || t.hidden === 1 || t.hidden === "1", o = fS(t.startShowingAt, t.stopShowingAt), c = (e.slug || "").replace(/^\/+|\/+$/g, "");
|
|
26558
|
+
return dS(t.startShowingAt, t.stopShowingAt, r), !s && (i || !o) ? null : {
|
|
26471
26559
|
treeNodeId: e.treeNodeId,
|
|
26472
26560
|
id: e.id,
|
|
26473
26561
|
title: e.title,
|
|
@@ -26493,11 +26581,11 @@ async function CS(e) {
|
|
|
26493
26581
|
try {
|
|
26494
26582
|
a = (typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson) || {};
|
|
26495
26583
|
} catch {}
|
|
26496
|
-
|
|
26497
|
-
let o = a.hidden === !0 || a.hidden === 1 || a.hidden === "1" || a.hidden === "true", c =
|
|
26584
|
+
dS(a.startShowingAt, a.stopShowingAt, r);
|
|
26585
|
+
let o = a.hidden === !0 || a.hidden === 1 || a.hidden === "1" || a.hidden === "true", c = fS(a.startShowingAt, a.stopShowingAt);
|
|
26498
26586
|
if (!s && (o || !c)) return null;
|
|
26499
|
-
let l = e.elementType || e.componentId || "text-block", u = re.blocks?.[l]?.fields || re.elements?.[l]?.fields || re.components?.[l]?.fields || {}, d = String(a.blockId || a._instanceId || a.id || e.blockId || e.id), f =
|
|
26500
|
-
return f = await fx(t, f), f =
|
|
26587
|
+
let l = e.elementType || e.componentId || "text-block", u = re.blocks?.[l]?.fields || re.elements?.[l]?.fields || re.components?.[l]?.fields || {}, d = String(a.blockId || a._instanceId || a.id || e.blockId || e.id), f = hS(a, u);
|
|
26588
|
+
return f = await fx(t, f), f = gS(f), f = await _S(t, f, g, n), f.blockId = d, {
|
|
26501
26589
|
region: i,
|
|
26502
26590
|
block: {
|
|
26503
26591
|
instanceId: e.id,
|
|
@@ -26522,7 +26610,7 @@ async function CS(e) {
|
|
|
26522
26610
|
for (let [e, i] of Object.entries(ke)) {
|
|
26523
26611
|
let a = Ee[e] && Ee[e].length > 0, o = !!se[e];
|
|
26524
26612
|
if (Ee[e] || (Ee[e] = [], De[e] = { isInherited: !1 }), (i?.inherit === "parent" || i?.inherit === !0 || i?.inherit === "true" || e === "header" || e === "footer") && !a && !o && A) {
|
|
26525
|
-
let i = await
|
|
26613
|
+
let i = await mS(t, A, String(b), e, re, s, n, r);
|
|
26526
26614
|
if (i.blocks.length > 0 && (Ee[e] = i.blocks, De[e] = {
|
|
26527
26615
|
isInherited: !0,
|
|
26528
26616
|
inheritedFromId: i.inheritedFromId,
|
|
@@ -26534,7 +26622,7 @@ async function CS(e) {
|
|
|
26534
26622
|
});
|
|
26535
26623
|
}
|
|
26536
26624
|
}
|
|
26537
|
-
await Promise.all(Object.keys(Ee).map((e) =>
|
|
26625
|
+
await Promise.all(Object.keys(Ee).map((e) => pS(t, Ee[e], g, E, r)));
|
|
26538
26626
|
let Ae = null, je = null;
|
|
26539
26627
|
if (r.length > 0) {
|
|
26540
26628
|
je = Math.min(...r);
|
|
@@ -26553,10 +26641,10 @@ async function CS(e) {
|
|
|
26553
26641
|
content: Ee,
|
|
26554
26642
|
regionMeta: De
|
|
26555
26643
|
};
|
|
26556
|
-
if (!s && !
|
|
26644
|
+
if (!s && !te) {
|
|
26557
26645
|
e.header("X-Cache", "MISS");
|
|
26558
26646
|
let t = Ae === null ? k : Ae;
|
|
26559
|
-
e.header("Cache-Control", `public, max-age=${t}, s-maxage=${t}`), await
|
|
26647
|
+
e.header("Cache-Control", `public, max-age=${t}, s-maxage=${t}`), await CS(O, D, Me, t);
|
|
26560
26648
|
} else e.header("Cache-Control", "no-cache, no-store, must-revalidate");
|
|
26561
26649
|
return e.json(Me, 200);
|
|
26562
26650
|
} catch (t) {
|
|
@@ -26566,17 +26654,17 @@ async function CS(e) {
|
|
|
26566
26654
|
}, 500);
|
|
26567
26655
|
}
|
|
26568
26656
|
}
|
|
26569
|
-
var
|
|
26657
|
+
var TS = X({
|
|
26570
26658
|
channelId: J().optional().openapi({ description: "The ID or key of the channel" }),
|
|
26571
26659
|
channel: J().optional().openapi({ description: "Legacy alias for channelId" }),
|
|
26572
26660
|
lang: J().optional().openapi({ description: "Requested language code" }),
|
|
26573
26661
|
preview: lv(["true", "false"]).optional().openapi({ description: "Request unpublished draft data" }),
|
|
26574
26662
|
revisionId: J().optional().openapi({ description: "Historical revision version to load" }),
|
|
26575
26663
|
treeId: J().optional().openapi({ description: "The ID of the tree to resolve paths against" })
|
|
26576
|
-
}),
|
|
26664
|
+
}), ES = X({
|
|
26577
26665
|
error: J(),
|
|
26578
26666
|
details: J().optional()
|
|
26579
|
-
}).openapi("ErrorResponse"),
|
|
26667
|
+
}).openapi("ErrorResponse"), DS = X({
|
|
26580
26668
|
channelId: G_([J(), c_()]),
|
|
26581
26669
|
treeId: J().nullable(),
|
|
26582
26670
|
language: J().nullable(),
|
|
@@ -26591,7 +26679,7 @@ var wS = X({
|
|
|
26591
26679
|
inheritedFromId: J().optional(),
|
|
26592
26680
|
inheritedFromTitle: J().optional()
|
|
26593
26681
|
}))
|
|
26594
|
-
}).openapi("NodeResponse"),
|
|
26682
|
+
}).openapi("NodeResponse"), OS = eb({
|
|
26595
26683
|
method: "get",
|
|
26596
26684
|
path: "/{path}",
|
|
26597
26685
|
summary: "Fetch CMS Node Content",
|
|
@@ -26599,27 +26687,27 @@ var wS = X({
|
|
|
26599
26687
|
tags: ["Public Node API"],
|
|
26600
26688
|
request: {
|
|
26601
26689
|
params: X({ path: J().optional().openapi({ description: "The full URL path or slug of the requested node" }) }),
|
|
26602
|
-
query:
|
|
26690
|
+
query: TS
|
|
26603
26691
|
},
|
|
26604
26692
|
responses: {
|
|
26605
26693
|
200: {
|
|
26606
26694
|
description: "Fully hydrated CMS Node",
|
|
26607
|
-
content: { "application/json": { schema:
|
|
26695
|
+
content: { "application/json": { schema: DS } }
|
|
26608
26696
|
},
|
|
26609
26697
|
404: {
|
|
26610
26698
|
description: "Node or Channel not found",
|
|
26611
|
-
content: { "application/json": { schema:
|
|
26699
|
+
content: { "application/json": { schema: ES } }
|
|
26612
26700
|
},
|
|
26613
26701
|
500: {
|
|
26614
26702
|
description: "Server error during hydration",
|
|
26615
|
-
content: { "application/json": { schema:
|
|
26703
|
+
content: { "application/json": { schema: ES } }
|
|
26616
26704
|
}
|
|
26617
26705
|
}
|
|
26618
26706
|
});
|
|
26619
|
-
|
|
26707
|
+
lS.openapi(OS, wS), lS.get("*", wS);
|
|
26620
26708
|
//#endregion
|
|
26621
26709
|
//#region server/routes/public/nodes.ts
|
|
26622
|
-
var
|
|
26710
|
+
var kS = new $y(), AS = X({
|
|
26623
26711
|
nodeType: J().default("article").openapi({ description: "Content types (comma separated)" }),
|
|
26624
26712
|
channelId: J().optional().openapi({ description: "Channel ID or key" }),
|
|
26625
26713
|
limit: Ky().min(1).max(50).default(12).openapi({ description: "Number of items (max 50)" }),
|
|
@@ -26632,34 +26720,29 @@ var OS = new $y(), kS = X({
|
|
|
26632
26720
|
authors: G_([J(), z_(J())]).optional(),
|
|
26633
26721
|
categories: G_([J(), z_(J())]).optional(),
|
|
26634
26722
|
tags: G_([J(), z_(J())]).optional()
|
|
26635
|
-
}),
|
|
26723
|
+
}), jS = async (e) => {
|
|
26636
26724
|
try {
|
|
26637
|
-
let t = e.get("db"), n = e.req.valid("query"), r = n.nodeType || "article", i = String(r).split(",").map((e) => e.trim()).filter(Boolean), a = `FROM content_nodes WHERE contentType IN (${i.map(() => "?").join(",")}) AND isHidden = 0 AND (status = 'published'
|
|
26638
|
-
n.channelId && n.channelId !== "all" && (a += " AND
|
|
26639
|
-
let s = (
|
|
26725
|
+
let t = e.get("db"), n = e.req.valid("query"), r = n.nodeType || "article", i = String(r).split(",").map((e) => e.trim()).filter(Boolean), a = `FROM content_nodes WHERE contentType IN (${i.map(() => "?").join(",")}) AND isHidden = 0 AND IFNULL(status, 'published') = 'published'`, o = [...i];
|
|
26726
|
+
n.channelId && n.channelId !== "all" && (a += " AND EXISTS (SELECT 1 FROM node_channels nc WHERE nc.nodeId = content_nodes.id AND nc.channelId = ?)", o.push(Number(n.channelId) || n.channelId));
|
|
26727
|
+
let s = (/* @__PURE__ */ new Date()).toISOString();
|
|
26728
|
+
a += " AND IFNULL(json_extract(dataJson, '$.startShowingAt'), '') <= ?", o.push(s), a += " AND IFNULL(json_extract(dataJson, '$.stopShowingAt'), '9999-12-31') >= ?", o.push(s);
|
|
26729
|
+
let c = (e, t, n = !1) => {
|
|
26640
26730
|
let r = Array.isArray(t) ? t : t.split(",").map((e) => e.trim());
|
|
26641
26731
|
if (r.length === 0) return;
|
|
26642
26732
|
let i = r.map(() => "?").join(",");
|
|
26643
|
-
n ? (a += ` AND EXISTS (
|
|
26644
|
-
SELECT 1 FROM node_relations nr
|
|
26645
|
-
WHERE nr.sourceNodeId = content_nodes.id AND nr.fieldKey = ? AND nr.targetNodeId IN (${i})
|
|
26646
|
-
)`, o.push(e, ...r)) : (a += ` AND EXISTS (
|
|
26647
|
-
SELECT 1 FROM node_terms nt
|
|
26648
|
-
INNER JOIN taxonomy_terms tt ON nt.termId = tt.id
|
|
26649
|
-
WHERE nt.nodeId = content_nodes.id AND tt.taxonomy = ? AND tt.key IN (${i})
|
|
26650
|
-
)`, o.push(e, ...r));
|
|
26733
|
+
n ? (a += ` AND EXISTS (SELECT 1 FROM node_relations nr WHERE nr.sourceNodeId = content_nodes.id AND nr.fieldKey = ? AND nr.targetNodeId IN (${i}))`, o.push(e, ...r)) : (a += ` AND EXISTS (SELECT 1 FROM node_terms nt INNER JOIN taxonomy_terms tt ON nt.termId = tt.id WHERE nt.nodeId = content_nodes.id AND tt.taxonomy = ? AND tt.key IN (${i}))`, o.push(e, ...r));
|
|
26651
26734
|
};
|
|
26652
|
-
n.authors &&
|
|
26653
|
-
let
|
|
26654
|
-
n.sortBy === "createdAt" ?
|
|
26655
|
-
let
|
|
26735
|
+
n.authors && c("authors", n.authors, !0), n.categories && c("categories", n.categories, !1), n.tags && c("tags", n.tags, !1);
|
|
26736
|
+
let l = "ORDER BY updatedAt DESC";
|
|
26737
|
+
n.sortBy === "createdAt" ? l = "ORDER BY createdAt DESC" : n.sortBy === "title_asc" && (l = "ORDER BY LOWER(title) ASC");
|
|
26738
|
+
let u = `SELECT id, title, slug, language, dataJson, createdAt, updatedAt ${a} ${l} LIMIT ? OFFSET ?`;
|
|
26656
26739
|
o.push(n.limit, n.offset);
|
|
26657
|
-
let
|
|
26740
|
+
let d = await t.prepare(u).all(...o), f = Array.isArray(d) ? d : d?.results || [], p = f.map((e) => {
|
|
26658
26741
|
let t = {};
|
|
26659
26742
|
try {
|
|
26660
26743
|
t = typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson || {};
|
|
26661
26744
|
} catch {}
|
|
26662
|
-
return
|
|
26745
|
+
return {
|
|
26663
26746
|
id: e.id,
|
|
26664
26747
|
title: e.title,
|
|
26665
26748
|
slug: e.slug,
|
|
@@ -26670,22 +26753,23 @@ var OS = new $y(), kS = X({
|
|
|
26670
26753
|
image: t.image || t.coverImage || null,
|
|
26671
26754
|
author: t.author || null
|
|
26672
26755
|
};
|
|
26673
|
-
})
|
|
26756
|
+
});
|
|
26674
26757
|
return e.json({
|
|
26675
26758
|
items: p,
|
|
26676
26759
|
count: p.length,
|
|
26760
|
+
rawCount: f.length,
|
|
26677
26761
|
limit: n.limit,
|
|
26678
26762
|
offset: n.offset
|
|
26679
26763
|
}, 200);
|
|
26680
26764
|
} catch (t) {
|
|
26681
26765
|
return console.error("[CMS API] Error fetching nodes list:", t), e.json({ error: "Failed to fetch nodes list" }, 500);
|
|
26682
26766
|
}
|
|
26683
|
-
},
|
|
26767
|
+
}, MS = eb({
|
|
26684
26768
|
method: "get",
|
|
26685
26769
|
path: "/",
|
|
26686
26770
|
summary: "Fetch filtered list of nodes",
|
|
26687
26771
|
tags: ["Public Node API"],
|
|
26688
|
-
request: { query:
|
|
26772
|
+
request: { query: AS },
|
|
26689
26773
|
responses: {
|
|
26690
26774
|
200: {
|
|
26691
26775
|
description: "List of nodes",
|
|
@@ -26694,11 +26778,11 @@ var OS = new $y(), kS = X({
|
|
|
26694
26778
|
500: { description: "Server error" }
|
|
26695
26779
|
}
|
|
26696
26780
|
});
|
|
26697
|
-
|
|
26781
|
+
kS.openapi(MS, jS);
|
|
26698
26782
|
//#endregion
|
|
26699
26783
|
//#region server/routes/public/tree.ts
|
|
26700
|
-
var
|
|
26701
|
-
function
|
|
26784
|
+
var NS = new $y();
|
|
26785
|
+
function PS(e, t) {
|
|
26702
26786
|
let n = /* @__PURE__ */ new Date();
|
|
26703
26787
|
if (e && String(e).trim() !== "") {
|
|
26704
26788
|
let t = new Date(e);
|
|
@@ -26710,22 +26794,22 @@ function NS(e, t) {
|
|
|
26710
26794
|
}
|
|
26711
26795
|
return !0;
|
|
26712
26796
|
}
|
|
26713
|
-
async function
|
|
26797
|
+
async function FS(e, t, n, r) {
|
|
26714
26798
|
try {
|
|
26715
26799
|
await e.set(t, n, r);
|
|
26716
26800
|
} catch (e) {
|
|
26717
26801
|
console.warn("[CMS Cache] Failed to write tree response to cache:", e);
|
|
26718
26802
|
}
|
|
26719
26803
|
}
|
|
26720
|
-
var
|
|
26804
|
+
var IS = X({ treeParam: J().openapi({ description: "The ID or key of the requested tree (e.g., \"main-nav\")" }) }), LS = X({
|
|
26721
26805
|
channelId: J().optional().openapi({ description: "Channel ID to resolve context-aware routing" }),
|
|
26722
26806
|
channel: J().optional().openapi({ description: "Legacy alias for channelId" }),
|
|
26723
26807
|
lang: J().optional().openapi({ description: "Requested language code for tree nodes" }),
|
|
26724
26808
|
preview: lv(["true", "false"]).optional().openapi({ description: "Set to true to retrieve unpublished draft data" })
|
|
26725
|
-
}),
|
|
26809
|
+
}), RS = X({
|
|
26726
26810
|
error: J(),
|
|
26727
26811
|
details: J().optional()
|
|
26728
|
-
}).openapi("ErrorResponse"),
|
|
26812
|
+
}).openapi("ErrorResponse"), zS = qv(() => X({
|
|
26729
26813
|
id: G_([J(), c_()]),
|
|
26730
26814
|
treeNodeId: G_([J(), c_()]),
|
|
26731
26815
|
parentId: G_([J(), c_()]).nullable(),
|
|
@@ -26738,40 +26822,40 @@ var FS = X({ treeParam: J().openapi({ description: "The ID or key of the request
|
|
|
26738
26822
|
summary: J(),
|
|
26739
26823
|
url: J().optional(),
|
|
26740
26824
|
target: J().optional(),
|
|
26741
|
-
children: z_(
|
|
26742
|
-
})).openapi("TreeItem"),
|
|
26825
|
+
children: z_(zS).optional()
|
|
26826
|
+
})).openapi("TreeItem"), BS = X({
|
|
26743
26827
|
treeId: G_([c_(), J()]),
|
|
26744
26828
|
key: J(),
|
|
26745
26829
|
channelId: J(),
|
|
26746
26830
|
language: J().nullable(),
|
|
26747
26831
|
label: J(),
|
|
26748
|
-
items: z_(
|
|
26749
|
-
}).catchall(k_()).openapi("TreeResponse"),
|
|
26832
|
+
items: z_(zS)
|
|
26833
|
+
}).catchall(k_()).openapi("TreeResponse"), VS = eb({
|
|
26750
26834
|
method: "get",
|
|
26751
26835
|
path: "/{treeParam}",
|
|
26752
26836
|
summary: "Fetch CMS Navigation Tree",
|
|
26753
26837
|
description: "Retrieves a fully hydrated, recursive navigation tree structure. Uses $O(1)$ pre-computed routing table paths.",
|
|
26754
26838
|
tags: ["Public Tree API"],
|
|
26755
26839
|
request: {
|
|
26756
|
-
params:
|
|
26757
|
-
query:
|
|
26840
|
+
params: IS,
|
|
26841
|
+
query: LS
|
|
26758
26842
|
},
|
|
26759
26843
|
responses: {
|
|
26760
26844
|
200: {
|
|
26761
26845
|
description: "Fully hydrated CMS Tree payload",
|
|
26762
|
-
content: { "application/json": { schema:
|
|
26846
|
+
content: { "application/json": { schema: BS } }
|
|
26763
26847
|
},
|
|
26764
26848
|
404: {
|
|
26765
26849
|
description: "Tree or Channel not found / inactive",
|
|
26766
|
-
content: { "application/json": { schema:
|
|
26850
|
+
content: { "application/json": { schema: RS } }
|
|
26767
26851
|
},
|
|
26768
26852
|
500: {
|
|
26769
26853
|
description: "Server error during hydration",
|
|
26770
|
-
content: { "application/json": { schema:
|
|
26854
|
+
content: { "application/json": { schema: RS } }
|
|
26771
26855
|
}
|
|
26772
26856
|
}
|
|
26773
26857
|
});
|
|
26774
|
-
|
|
26858
|
+
NS.openapi(VS, async (e) => {
|
|
26775
26859
|
try {
|
|
26776
26860
|
let t = e.get("db"), { treeParam: n } = e.req.valid("param"), r = e.req.valid("query"), i = r.channelId || r.channel || "default", a = r.lang, o = r.preview === "true", s = null, c = -1;
|
|
26777
26861
|
if (i && i !== "default" && i !== "all") {
|
|
@@ -26806,7 +26890,7 @@ MS.openapi(BS, async (e) => {
|
|
|
26806
26890
|
}
|
|
26807
26891
|
let v = [];
|
|
26808
26892
|
if (g !== null) {
|
|
26809
|
-
let e = await t.prepare("\n SELECT \n t.contentId 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 (\n SELECT path \n FROM node_routes \n WHERE nodeId = c.id AND channelId = ? \n ORDER BY CASE WHEN treeId = t.treeId THEN 0 ELSE 1 END ASC \n LIMIT 1\n ) as materializedPath\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(c, g);
|
|
26893
|
+
let e = await t.prepare("\n SELECT \n t.contentId 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.startShowingAt,\n c.stopShowingAt,\n c.status,\n c.dataJson,\n c.draftDataJson,\n (\n SELECT path \n FROM node_routes \n WHERE nodeId = c.id AND channelId = ? \n ORDER BY CASE WHEN treeId = t.treeId THEN 0 ELSE 1 END ASC \n LIMIT 1\n ) as materializedPath\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(c, g);
|
|
26810
26894
|
v = Array.isArray(e) ? e : e?.results || [];
|
|
26811
26895
|
}
|
|
26812
26896
|
if ((!v || v.length === 0) && !u) return e.json({ error: `Tree '${n}' not found` }, 404);
|
|
@@ -26834,7 +26918,7 @@ MS.openapi(BS, async (e) => {
|
|
|
26834
26918
|
return (y.get(n) || []).map((e) => {
|
|
26835
26919
|
let n = b.get(String(e.id)) || {}, r = {};
|
|
26836
26920
|
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);
|
|
26837
|
-
let i = !o && (e.status === "draft" || e.status === "new"), a = Number(e.isHidden) === 1 || i || n.hidden === !0 || n.hidden === 1 || n.hidden === "1" || n.hidden === "true", s =
|
|
26921
|
+
let i = !o && (e.status === "draft" || e.status === "new"), a = Number(e.isHidden) === 1 || i || n.hidden === !0 || n.hidden === 1 || n.hidden === "1" || n.hidden === "true", s = PS(e.startShowingAt === void 0 ? n.startShowingAt : e.startShowingAt, e.stopShowingAt === void 0 ? n.stopShowingAt : e.stopShowingAt), c = (e.slug || "").replace(/^\/+|\/+$/g, ""), l = !e.parentId || e.parentId === "null" || e.parentId === "", u = e.materializedPath || (l ? `/${c}` : `${t}/${c}`.replace(/\/+/g, "/")), d = e.language && String(e.language).trim() !== "" ? e.language.trim() : f, p = {
|
|
26838
26922
|
id: e.id,
|
|
26839
26923
|
treeNodeId: e.id,
|
|
26840
26924
|
parentId: e.parentId || null,
|
|
@@ -26860,7 +26944,7 @@ MS.openapi(BS, async (e) => {
|
|
|
26860
26944
|
..._,
|
|
26861
26945
|
items: x(null)
|
|
26862
26946
|
};
|
|
26863
|
-
return !o && !h && (e.header("X-Cache", "MISS"), await
|
|
26947
|
+
return !o && !h && (e.header("X-Cache", "MISS"), await FS(p, m, S, 300)), e.json(S, 200);
|
|
26864
26948
|
} catch (t) {
|
|
26865
26949
|
return console.error("[CMS Public Tree API] Error:", t), e.json({
|
|
26866
26950
|
error: "Failed to fetch public tree",
|
|
@@ -26870,19 +26954,19 @@ MS.openapi(BS, async (e) => {
|
|
|
26870
26954
|
});
|
|
26871
26955
|
//#endregion
|
|
26872
26956
|
//#region server/routes/public/channel.ts
|
|
26873
|
-
var
|
|
26874
|
-
function
|
|
26957
|
+
var HS = new $y();
|
|
26958
|
+
function US(e) {
|
|
26875
26959
|
let t = Number(e?.env?.CMS_CHANNEL_CACHE_TTL);
|
|
26876
26960
|
return Number.isFinite(t) && t >= 60 ? Math.floor(t) : 300;
|
|
26877
26961
|
}
|
|
26878
|
-
async function
|
|
26962
|
+
async function WS(e, t, n, r) {
|
|
26879
26963
|
try {
|
|
26880
26964
|
await e.set(t, n, r);
|
|
26881
26965
|
} catch (e) {
|
|
26882
26966
|
console.warn("[CMS Cache] Failed to write channel response to cache:", e);
|
|
26883
26967
|
}
|
|
26884
26968
|
}
|
|
26885
|
-
function
|
|
26969
|
+
function GS(e, t) {
|
|
26886
26970
|
let n = {}, r = (e) => {
|
|
26887
26971
|
if (!e || typeof e != "string") return;
|
|
26888
26972
|
let n = t?.fieldSets?.[e] || t?.fieldsets?.[e] || t?.definitions?.[e] || t?.channels?.[e] || t?.[e];
|
|
@@ -26893,7 +26977,7 @@ function WS(e, t) {
|
|
|
26893
26977
|
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);
|
|
26894
26978
|
return n;
|
|
26895
26979
|
}
|
|
26896
|
-
function
|
|
26980
|
+
function KS(e, t = {}) {
|
|
26897
26981
|
let n = {}, r = Object.keys(t).length > 0;
|
|
26898
26982
|
for (let [i, a] of Object.entries(e)) {
|
|
26899
26983
|
if (i.endsWith("_meta") || [
|
|
@@ -26912,14 +26996,14 @@ function GS(e, t = {}) {
|
|
|
26912
26996
|
}
|
|
26913
26997
|
return n;
|
|
26914
26998
|
}
|
|
26915
|
-
function
|
|
26916
|
-
if (Array.isArray(e)) return e.map(
|
|
26999
|
+
function qS(e) {
|
|
27000
|
+
if (Array.isArray(e)) return e.map(qS);
|
|
26917
27001
|
if (!e || typeof e != "object") return e;
|
|
26918
27002
|
if (typeof e.id == "string" && e.id.startsWith("ast_") && typeof e.url == "string") {
|
|
26919
27003
|
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 ? {
|
|
26920
27004
|
...t,
|
|
26921
27005
|
...t.crops?.[r] || {}
|
|
26922
|
-
} : t, a = Object.fromEntries(Object.entries(n).filter(([, t]) => t?.id !== e.id).map(([t, n]) => [t,
|
|
27006
|
+
} : t, a = Object.fromEntries(Object.entries(n).filter(([, t]) => t?.id !== e.id).map(([t, n]) => [t, qS({
|
|
26923
27007
|
...n,
|
|
26924
27008
|
title: n?.title ?? e.title ?? "",
|
|
26925
27009
|
alt: n?.alt ?? e.alt ?? "",
|
|
@@ -26933,9 +27017,19 @@ function KS(e) {
|
|
|
26933
27017
|
...Object.keys(a).length > 0 ? { variants: a } : {}
|
|
26934
27018
|
};
|
|
26935
27019
|
}
|
|
26936
|
-
return Object.fromEntries(Object.entries(e).map(([e, t]) => [e,
|
|
27020
|
+
return Object.fromEntries(Object.entries(e).map(([e, t]) => [e, qS(t)]));
|
|
26937
27021
|
}
|
|
26938
|
-
async function
|
|
27022
|
+
async function JS(e, t, n) {
|
|
27023
|
+
let r = t.href.match(/^#node:(.+)$/), i = t.href.match(/^#asset:(.+)$/);
|
|
27024
|
+
if (i) {
|
|
27025
|
+
let t = i[1], n = await e.prepare("SELECT cdnUrl, storageKeyPrivate FROM assets WHERE id = ?").get(t);
|
|
27026
|
+
return n?.cdnUrl || (n?.storageKeyPrivate ? `/media/${n.storageKeyPrivate}` : "#");
|
|
27027
|
+
}
|
|
27028
|
+
if (!r) return t.href;
|
|
27029
|
+
let a = r[1];
|
|
27030
|
+
return (await e.prepare("SELECT path FROM node_routes WHERE nodeId = ? AND channelId = ? AND isCanonical = 1 LIMIT 1").get(Number(a), n))?.path || "#";
|
|
27031
|
+
}
|
|
27032
|
+
async function YS(e, t, n) {
|
|
26939
27033
|
if (typeof t == "string") {
|
|
26940
27034
|
if (!t.includes("#node:") && !t.includes("data-node-id") && !t.includes("#asset:") && !t.includes("data-asset-id")) return t;
|
|
26941
27035
|
let r = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Set();
|
|
@@ -26968,45 +27062,52 @@ async function qS(e, t, n) {
|
|
|
26968
27062
|
return /href\s*=\s*["'][^"']*["']/i.test(d) ? d = d.replace(/href\s*=\s*["'][^"']*["']/i, `href="${u}"`) : d += ` href="${u}"`, `<a ${d}>`;
|
|
26969
27063
|
});
|
|
26970
27064
|
}
|
|
26971
|
-
if (Array.isArray(t)) return Promise.all(t.map((t) =>
|
|
27065
|
+
if (Array.isArray(t)) return Promise.all(t.map((t) => YS(e, t, n)));
|
|
26972
27066
|
if (t && typeof t == "object") {
|
|
26973
|
-
|
|
27067
|
+
if (typeof t.href == "string" && (t.href.startsWith("#node:") || t.href.startsWith("#asset:"))) {
|
|
27068
|
+
let r = await JS(e, t, n), i = await Promise.all(Object.entries(t).filter(([e]) => e !== "href").map(async ([t, r]) => [t, await YS(e, r, n)]));
|
|
27069
|
+
return {
|
|
27070
|
+
...Object.fromEntries(i),
|
|
27071
|
+
href: r
|
|
27072
|
+
};
|
|
27073
|
+
}
|
|
27074
|
+
let r = await Promise.all(Object.entries(t).map(async ([t, r]) => [t, await YS(e, r, n)]));
|
|
26974
27075
|
return Object.fromEntries(r);
|
|
26975
27076
|
}
|
|
26976
27077
|
return t;
|
|
26977
27078
|
}
|
|
26978
|
-
var
|
|
27079
|
+
var XS = X({ channelParam: J().openapi({ description: "The ID or key (slug) of the requested channel" }) }), ZS = X({ preview: lv(["true", "false"]).optional().openapi({ description: "Set to true to retrieve unpublished draft data" }) }), QS = X({
|
|
26979
27080
|
error: J(),
|
|
26980
27081
|
details: J().optional()
|
|
26981
|
-
}).openapi("ErrorResponse"),
|
|
27082
|
+
}).openapi("ErrorResponse"), $S = X({
|
|
26982
27083
|
id: G_([c_(), J()]),
|
|
26983
27084
|
key: J()
|
|
26984
|
-
}).catchall(k_()).openapi("ChannelResponse"),
|
|
27085
|
+
}).catchall(k_()).openapi("ChannelResponse"), eC = eb({
|
|
26985
27086
|
method: "get",
|
|
26986
27087
|
path: "/{channelParam}",
|
|
26987
27088
|
summary: "Fetch CMS Channel Settings",
|
|
26988
27089
|
description: "Retrieves the fully hydrated, public-facing settings and payload for a specific CMS channel.",
|
|
26989
27090
|
tags: ["Public Channel API"],
|
|
26990
27091
|
request: {
|
|
26991
|
-
params:
|
|
26992
|
-
query:
|
|
27092
|
+
params: XS,
|
|
27093
|
+
query: ZS
|
|
26993
27094
|
},
|
|
26994
27095
|
responses: {
|
|
26995
27096
|
200: {
|
|
26996
27097
|
description: "Fully hydrated CMS Channel payload",
|
|
26997
|
-
content: { "application/json": { schema:
|
|
27098
|
+
content: { "application/json": { schema: $S } }
|
|
26998
27099
|
},
|
|
26999
27100
|
404: {
|
|
27000
27101
|
description: "Channel not found or inactive",
|
|
27001
|
-
content: { "application/json": { schema:
|
|
27102
|
+
content: { "application/json": { schema: QS } }
|
|
27002
27103
|
},
|
|
27003
27104
|
500: {
|
|
27004
27105
|
description: "Server error during hydration",
|
|
27005
|
-
content: { "application/json": { schema:
|
|
27106
|
+
content: { "application/json": { schema: QS } }
|
|
27006
27107
|
}
|
|
27007
27108
|
}
|
|
27008
27109
|
});
|
|
27009
|
-
|
|
27110
|
+
HS.openapi(eC, async (e) => {
|
|
27010
27111
|
try {
|
|
27011
27112
|
let t = e.get("db"), { channelParam: n } = e.req.valid("param"), { preview: r } = e.req.valid("query"), i = r === "true", a = e.req.header("x-bypass-cache") === "true", o = `channel:${n}:${i ? "preview" : "live"}`, s = $b(e);
|
|
27012
27113
|
if (!i && !a) {
|
|
@@ -27017,23 +27118,23 @@ VS.openapi(QS, async (e) => {
|
|
|
27017
27118
|
if (!c) return e.json({ error: `Channel '${n}' not found` }, 404);
|
|
27018
27119
|
let l = c.status === "disabled" || c.status === "inactive" || c.isEnabled === 0 || c.isEnabled === !1;
|
|
27019
27120
|
if (!i && l) return e.json({ error: `Channel '${c.key || n}' is currently inactive` }, 404);
|
|
27020
|
-
let u = Number(c.id), d = e.env?.BUNDLED_DEFINITIONS, f = px(d), p = c.channelType || c.key || "website", m =
|
|
27121
|
+
let u = Number(c.id), d = e.env?.BUNDLED_DEFINITIONS, f = px(d), p = c.channelType || c.key || "website", m = GS(f.channels?.[p] || f.channels?.[c.key] || f.channels?.website || f.definitions?.["channel-base"] || {}, f), h = {}, g = i && c.draftDataJson || c.dataJson;
|
|
27021
27122
|
if (g) try {
|
|
27022
27123
|
h = typeof g == "string" ? JSON.parse(g) : g;
|
|
27023
27124
|
} catch (e) {
|
|
27024
27125
|
console.warn("[CMS Public Channel API] Failed to parse channel dataJson:", e);
|
|
27025
27126
|
}
|
|
27026
|
-
let _ =
|
|
27127
|
+
let _ = KS({
|
|
27027
27128
|
...h,
|
|
27028
27129
|
...c
|
|
27029
27130
|
}, m);
|
|
27030
|
-
_ = await fx(t, _), _ =
|
|
27131
|
+
_ = await fx(t, _), _ = qS(_), _ = await YS(t, _, u);
|
|
27031
27132
|
let v = {
|
|
27032
27133
|
id: c.id,
|
|
27033
27134
|
key: c.key,
|
|
27034
27135
|
..._
|
|
27035
27136
|
};
|
|
27036
|
-
return !i && !a && (e.header("X-Cache", "MISS"), await
|
|
27137
|
+
return !i && !a && (e.header("X-Cache", "MISS"), await WS(s, o, v, US(e))), e.json(v, 200);
|
|
27037
27138
|
} catch (t) {
|
|
27038
27139
|
return console.error("[CMS Public Channel API] Error:", t), e.json({
|
|
27039
27140
|
error: "Failed to fetch public channel",
|
|
@@ -27043,8 +27144,8 @@ VS.openapi(QS, async (e) => {
|
|
|
27043
27144
|
});
|
|
27044
27145
|
//#endregion
|
|
27045
27146
|
//#region server/routes/public/assets.ts
|
|
27046
|
-
var
|
|
27047
|
-
function
|
|
27147
|
+
var tC = new $y();
|
|
27148
|
+
function nC(e, t) {
|
|
27048
27149
|
if (t === "webp") return "image/webp";
|
|
27049
27150
|
if (t === "avif") return "image/avif";
|
|
27050
27151
|
if (t === "jpeg" || t === "jpg") return "image/jpeg";
|
|
@@ -27053,7 +27154,7 @@ function eC(e, t) {
|
|
|
27053
27154
|
let n = e.toLowerCase();
|
|
27054
27155
|
return n.endsWith(".jpg") || n.endsWith(".jpeg") ? "image/jpeg" : n.endsWith(".png") ? "image/png" : n.endsWith(".webp") ? "image/webp" : n.endsWith(".gif") ? "image/gif" : n.endsWith(".svg") ? "image/svg+xml" : n.endsWith(".pdf") ? "application/pdf" : n.endsWith(".mp4") ? "video/mp4" : "application/octet-stream";
|
|
27055
27156
|
}
|
|
27056
|
-
var
|
|
27157
|
+
var rC = [
|
|
27057
27158
|
320,
|
|
27058
27159
|
640,
|
|
27059
27160
|
768,
|
|
@@ -27063,10 +27164,10 @@ var tC = [
|
|
|
27063
27164
|
2560,
|
|
27064
27165
|
3840
|
|
27065
27166
|
];
|
|
27066
|
-
function
|
|
27067
|
-
if (!(!e || isNaN(e) || e <= 0)) return
|
|
27167
|
+
function iC(e) {
|
|
27168
|
+
if (!(!e || isNaN(e) || e <= 0)) return rC.reduce((t, n) => Math.abs(n - e) < Math.abs(t - e) ? n : t);
|
|
27068
27169
|
}
|
|
27069
|
-
var
|
|
27170
|
+
var aC = eb({
|
|
27070
27171
|
method: "get",
|
|
27071
27172
|
path: "/*",
|
|
27072
27173
|
summary: "Serve & Optimize Media Assets",
|
|
@@ -27126,11 +27227,11 @@ var rC = eb({
|
|
|
27126
27227
|
}
|
|
27127
27228
|
}
|
|
27128
27229
|
});
|
|
27129
|
-
|
|
27230
|
+
tC.openapi(aC, async (e) => {
|
|
27130
27231
|
try {
|
|
27131
27232
|
let t = e.req.path.replace(/^\/media\//, "").replace(/^\//, "");
|
|
27132
27233
|
if (!t) return e.text("Asset key missing", 400);
|
|
27133
|
-
let { w: n, h: r, q: i, f: a } = e.req.valid("query"), o = !!(n || r || i || a), s =
|
|
27234
|
+
let { w: n, h: r, q: i, f: a } = e.req.valid("query"), o = !!(n || r || i || a), s = iC(n ? parseInt(n, 10) : void 0), c = e.req.header("Accept") || "", l = "";
|
|
27134
27235
|
if (o) {
|
|
27135
27236
|
let e = !a || a === "auto";
|
|
27136
27237
|
a === "avif" || e && c.includes("image/avif") ? l = "avif" : a === "webp" || e && c.includes("image/webp") ? l = "webp" : a === "jpeg" || a === "jpg" ? l = "jpeg" : a === "png" && (l = "png");
|
|
@@ -27149,7 +27250,7 @@ $S.openapi(rC, async (e) => {
|
|
|
27149
27250
|
if (!h) return e.text(`Asset not found: ${t}`, 404);
|
|
27150
27251
|
if (!o) {
|
|
27151
27252
|
let n = e.body(h, 200, {
|
|
27152
|
-
"Content-Type":
|
|
27253
|
+
"Content-Type": nC(t),
|
|
27153
27254
|
"Cache-Control": "public, max-age=31536000, immutable"
|
|
27154
27255
|
});
|
|
27155
27256
|
return u && f && e.executionCtx?.waitUntil && e.executionCtx.waitUntil(u.put(f, n.clone())), n;
|
|
@@ -27163,7 +27264,7 @@ $S.openapi(rC, async (e) => {
|
|
|
27163
27264
|
key: t,
|
|
27164
27265
|
env: e.env,
|
|
27165
27266
|
req: e.req.raw
|
|
27166
|
-
}), v =
|
|
27267
|
+
}), v = nC(t, l), y = e.body(_, 200, {
|
|
27167
27268
|
"Content-Type": v,
|
|
27168
27269
|
"Cache-Control": "public, max-age=31536000, immutable"
|
|
27169
27270
|
});
|
|
@@ -27174,8 +27275,8 @@ $S.openapi(rC, async (e) => {
|
|
|
27174
27275
|
});
|
|
27175
27276
|
//#endregion
|
|
27176
27277
|
//#region server/routes/public/paths.ts
|
|
27177
|
-
var
|
|
27178
|
-
function
|
|
27278
|
+
var oC = new $y();
|
|
27279
|
+
function sC(e, t) {
|
|
27179
27280
|
let n = /* @__PURE__ */ new Date();
|
|
27180
27281
|
if (e && String(e).trim() !== "") {
|
|
27181
27282
|
let t = new Date(e);
|
|
@@ -27187,31 +27288,31 @@ function aC(e, t) {
|
|
|
27187
27288
|
}
|
|
27188
27289
|
return !0;
|
|
27189
27290
|
}
|
|
27190
|
-
var
|
|
27291
|
+
var cC = X({
|
|
27191
27292
|
channelId: J().optional().openapi({ description: "Optional channel ID/key to filter and resolve root paths for" }),
|
|
27192
27293
|
channel: J().optional().openapi({ description: "Legacy alias for channelId" })
|
|
27193
|
-
}),
|
|
27294
|
+
}), lC = z_(J()).openapi("PathsResponse"), uC = X({
|
|
27194
27295
|
error: J(),
|
|
27195
27296
|
details: J().optional()
|
|
27196
|
-
}).openapi("ErrorResponse"),
|
|
27297
|
+
}).openapi("ErrorResponse"), dC = eb({
|
|
27197
27298
|
method: "get",
|
|
27198
27299
|
path: "/",
|
|
27199
27300
|
summary: "Fetch All Public Paths",
|
|
27200
27301
|
description: "Retrieves a deduplicated array of all active, published node paths leveraging the $O(1)$ node_routes table. Includes both tree-bound and standalone pages.",
|
|
27201
27302
|
tags: ["Public Paths API"],
|
|
27202
|
-
request: { query:
|
|
27303
|
+
request: { query: cC },
|
|
27203
27304
|
responses: {
|
|
27204
27305
|
200: {
|
|
27205
27306
|
description: "Array of valid public URL paths",
|
|
27206
|
-
content: { "application/json": { schema:
|
|
27307
|
+
content: { "application/json": { schema: lC } }
|
|
27207
27308
|
},
|
|
27208
27309
|
500: {
|
|
27209
27310
|
description: "Server error fetching paths",
|
|
27210
|
-
content: { "application/json": { schema:
|
|
27311
|
+
content: { "application/json": { schema: uC } }
|
|
27211
27312
|
}
|
|
27212
27313
|
}
|
|
27213
27314
|
});
|
|
27214
|
-
|
|
27315
|
+
oC.openapi(dC, async (e) => {
|
|
27215
27316
|
try {
|
|
27216
27317
|
let t = e.get("db"), n = e.req.valid("query"), r = n.channelId || n.channel, i = "", a = [];
|
|
27217
27318
|
if (r && r !== "all") {
|
|
@@ -27222,7 +27323,8 @@ iC.openapi(lC, async (e) => {
|
|
|
27222
27323
|
SELECT
|
|
27223
27324
|
nr.path,
|
|
27224
27325
|
cn.contentType as nodeType,
|
|
27225
|
-
cn.
|
|
27326
|
+
cn.startShowingAt,
|
|
27327
|
+
cn.stopShowingAt
|
|
27226
27328
|
FROM node_routes nr
|
|
27227
27329
|
INNER JOIN content_nodes cn ON nr.nodeId = cn.id
|
|
27228
27330
|
WHERE nr.isCanonical = 1
|
|
@@ -27231,15 +27333,7 @@ iC.openapi(lC, async (e) => {
|
|
|
27231
27333
|
${i}
|
|
27232
27334
|
ORDER BY nr.path ASC
|
|
27233
27335
|
`).all(...a), s = Array.isArray(o) ? o : o?.results || [], c = [];
|
|
27234
|
-
for (let e of s)
|
|
27235
|
-
if (e.nodeType === "external-link" || !e.path) continue;
|
|
27236
|
-
let t = !0;
|
|
27237
|
-
if (e.dataJson) try {
|
|
27238
|
-
let n = typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson;
|
|
27239
|
-
t = aC(n?.startShowingAt, n?.stopShowingAt);
|
|
27240
|
-
} catch {}
|
|
27241
|
-
t && c.push(e.path);
|
|
27242
|
-
}
|
|
27336
|
+
for (let e of s) e.nodeType !== "external-link" && e.path && sC(e.startShowingAt, e.stopShowingAt) && c.push(e.path);
|
|
27243
27337
|
let l = [...new Set(c)];
|
|
27244
27338
|
return e.json(l, 200);
|
|
27245
27339
|
} catch (t) {
|
|
@@ -27248,12 +27342,12 @@ iC.openapi(lC, async (e) => {
|
|
|
27248
27342
|
});
|
|
27249
27343
|
//#endregion
|
|
27250
27344
|
//#region server/routes/public/taxonomies.ts
|
|
27251
|
-
var
|
|
27252
|
-
function
|
|
27345
|
+
var fC = new $y();
|
|
27346
|
+
function pC(e) {
|
|
27253
27347
|
let t = (e || "").trim().toLowerCase(), n = px()?.taxonomies || {};
|
|
27254
27348
|
return n[t] ? t : n[`${t}s`] ? `${t}s` : t.endsWith("s") && n[t.slice(0, -1)] ? t.slice(0, -1) : t;
|
|
27255
27349
|
}
|
|
27256
|
-
var
|
|
27350
|
+
var mC = X({
|
|
27257
27351
|
id: c_(),
|
|
27258
27352
|
taxonomy: J(),
|
|
27259
27353
|
key: J(),
|
|
@@ -27263,14 +27357,14 @@ var fC = X({
|
|
|
27263
27357
|
data: tv(k_()),
|
|
27264
27358
|
createdAt: J(),
|
|
27265
27359
|
updatedAt: J()
|
|
27266
|
-
}),
|
|
27360
|
+
}), hC = X({
|
|
27267
27361
|
taxonomy: J(),
|
|
27268
|
-
items: z_(
|
|
27362
|
+
items: z_(mC),
|
|
27269
27363
|
total: c_()
|
|
27270
|
-
}).openapi("TaxonomyResponse"),
|
|
27364
|
+
}).openapi("TaxonomyResponse"), gC = X({
|
|
27271
27365
|
error: J(),
|
|
27272
27366
|
details: J().optional()
|
|
27273
|
-
}).openapi("ErrorResponse"),
|
|
27367
|
+
}).openapi("ErrorResponse"), _C = eb({
|
|
27274
27368
|
method: "get",
|
|
27275
27369
|
path: "/{taxonomy}",
|
|
27276
27370
|
summary: "Fetch Public Taxonomy Terms",
|
|
@@ -27280,17 +27374,17 @@ var fC = X({
|
|
|
27280
27374
|
responses: {
|
|
27281
27375
|
200: {
|
|
27282
27376
|
description: "List of taxonomy terms",
|
|
27283
|
-
content: { "application/json": { schema:
|
|
27377
|
+
content: { "application/json": { schema: hC } }
|
|
27284
27378
|
},
|
|
27285
27379
|
500: {
|
|
27286
27380
|
description: "Server error",
|
|
27287
|
-
content: { "application/json": { schema:
|
|
27381
|
+
content: { "application/json": { schema: gC } }
|
|
27288
27382
|
}
|
|
27289
27383
|
}
|
|
27290
27384
|
});
|
|
27291
|
-
|
|
27385
|
+
fC.openapi(_C, async (e) => {
|
|
27292
27386
|
try {
|
|
27293
|
-
let t = e.get("db"), n = $b(e), r = e.req.valid("param").taxonomy, i =
|
|
27387
|
+
let t = e.get("db"), n = $b(e), r = e.req.valid("param").taxonomy, i = pC(r), a = `taxonomy:public:${i}`, o = e.req.header("x-bypass-cache") === "true";
|
|
27294
27388
|
if (!o) {
|
|
27295
27389
|
let t = await n.get(a);
|
|
27296
27390
|
if (t) return e.header("X-Cache", "HIT"), e.json(t);
|
|
@@ -27326,7 +27420,7 @@ uC.openapi(hC, async (e) => {
|
|
|
27326
27420
|
});
|
|
27327
27421
|
//#endregion
|
|
27328
27422
|
//#region server/index.ts
|
|
27329
|
-
var $ = new $y(),
|
|
27423
|
+
var $ = new $y(), vC = !1;
|
|
27330
27424
|
$.use("*", t()), $.use("/media/*", t({
|
|
27331
27425
|
origin: "*",
|
|
27332
27426
|
allowMethods: [
|
|
@@ -27347,20 +27441,20 @@ $.use("*", t()), $.use("/media/*", t({
|
|
|
27347
27441
|
let n = new URL(e.req.url), r = (e.req.header("host") || n.hostname).split(":")[0];
|
|
27348
27442
|
e.set("currentDomain", r);
|
|
27349
27443
|
let i = wb(e);
|
|
27350
|
-
if (e.set("db", i), !
|
|
27351
|
-
await Mb(i),
|
|
27444
|
+
if (e.set("db", i), !vC) try {
|
|
27445
|
+
await Mb(i), vC = !0;
|
|
27352
27446
|
} catch (e) {
|
|
27353
27447
|
console.error("❌ [CMS Server] Failed to initialize system tables on cold start:", e);
|
|
27354
27448
|
}
|
|
27355
27449
|
await t();
|
|
27356
|
-
}), $.route("/media",
|
|
27450
|
+
}), $.route("/media", tC), $.use("/media/*", Pb()), $.route("/api/cms/nodes", gx), $.route("/api/cms/nodes.json", gx), $.route("/api/cms/formcsv", gx), $.route("/api/cms/formcsv.json", gx), $.route("/api/cms/stats", iS), $.route("/api/cms/stats.json", iS), $.route("/api/cms", Ox), $.route("/api/cms/trees.json", Ox), $.route("/api/cms/channels", Mx), $.route("/api/cms/channels.json", Mx), $.route("/api/cms/taxonomies", Nx), $.route("/api/cms/taxonomies.json", Nx), $.route("/api/cms/schemas", $x), $.route("/api/cms/schemas.json", $x), $.route("/api/cms", tS), $.route("/api/admin/assets", aS), $.use("/api/v1/*", async (e, t) => {
|
|
27357
27451
|
let n = e.env?.FRONTEND_API_SECRET;
|
|
27358
27452
|
if (n) {
|
|
27359
27453
|
let t = e.req.header("Authorization"), r = e.req.header("x-api-key"), i = t?.startsWith("Bearer ") ? t.substring(7).trim() : r?.trim();
|
|
27360
27454
|
if (!i || i !== n) return e.json({ error: "Unauthorized: Invalid or missing API secret." }, 401);
|
|
27361
27455
|
} else console.warn("⚠️ [CMS Security] FRONTEND_API_SECRET is not set in .env. The API is completely exposed to the public.");
|
|
27362
27456
|
return t();
|
|
27363
|
-
}), $.route("/api/v1/node",
|
|
27457
|
+
}), $.route("/api/v1/node", lS), $.route("/api/v1/nodes", kS), $.route("/api/v1/tree", NS), $.route("/api/v1/channel", HS), $.route("/api/v1/all-paths", oC), $.route("/api/v1/taxonomies", fC), $.doc("/api/openapi.json", {
|
|
27364
27458
|
openapi: "3.0.0",
|
|
27365
27459
|
info: {
|
|
27366
27460
|
title: "KAMA Engine Public API",
|
|
@@ -27379,4 +27473,4 @@ $.use("*", t()), $.use("/media/*", t({
|
|
|
27379
27473
|
return t();
|
|
27380
27474
|
});
|
|
27381
27475
|
//#endregion
|
|
27382
|
-
export { $ as app, $ as default,
|
|
27476
|
+
export { $ as app, $ as default, Xx as compileDefinitions, Zx as getCmsDefinitions };
|