@brightsideoy/kama 1.0.0-alpha.13 → 1.0.0-alpha.16
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/dist/assets/AssetEditor-CEHxvQj0.js +1 -0
- package/dist/assets/AssetEditor-D5j7pwcK.css +1 -0
- package/dist/assets/CmsHelp-BO_vWABq.css +1 -0
- package/dist/assets/CmsHelp-Cnr801lx.js +1 -0
- package/dist/assets/CmsPublisher-C3fRoBte.js +3 -0
- package/dist/assets/CmsPublisher-CugEqTD8.css +1 -0
- package/dist/assets/CmsUserCenter-Ac0GywlR.css +1 -0
- package/dist/assets/CmsUserCenter-DiuXfjMc.js +1 -0
- package/dist/assets/EditorSplitPreview-BzKh4wFB.css +1 -0
- package/dist/assets/EditorSplitPreview-tpZZF1o5.js +1 -0
- package/dist/assets/NodeEditor-Bd89OptF.css +1 -0
- package/dist/assets/NodeEditor-DaCIVPGT.js +147 -0
- package/dist/assets/TrashWorkspace-CTq0OFA-.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-BbV9FaG-.css +1 -0
- package/dist/assets/index-CHczMewv.js +14 -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-Ca4GRlV3.js} +619 -535
- package/dist/index.html +3 -2
- package/dist/index.js +619 -535
- 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) => {
|
|
@@ -22198,7 +22198,7 @@ var Tb = /* @__PURE__ */ o({
|
|
|
22198
22198
|
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
22199
|
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
22200
|
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 ",
|
|
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 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
22202
|
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
22203
|
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
22204
|
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 +22209,11 @@ var Tb = /* @__PURE__ */ o({
|
|
|
22209
22209
|
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
22210
|
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
22211
|
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(".");
|
|
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);.CREATE INDEX IF NOT EXISTS idx_content_nodes_public_feed ON content_nodes(contentType, isHidden, status, startShowingAt, stopShowingAt, updatedAt DESC);".split(".");
|
|
22213
22213
|
function Ab(e) {
|
|
22214
22214
|
let t = /* @__PURE__ */ new Set();
|
|
22215
22215
|
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));
|
|
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" && 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
22217
|
}
|
|
22218
22218
|
return n(e), Array.from(t);
|
|
22219
22219
|
}
|
|
@@ -22240,6 +22240,18 @@ async function Mb(e, t) {
|
|
|
22240
22240
|
if (!n.has("hasUnpublishedChanges")) try {
|
|
22241
22241
|
await e.prepare("ALTER TABLE \"content_nodes\" ADD COLUMN hasUnpublishedChanges INTEGER DEFAULT 0;").run();
|
|
22242
22242
|
} catch {}
|
|
22243
|
+
let t = !1;
|
|
22244
|
+
if (!n.has("startShowingAt")) try {
|
|
22245
|
+
await e.prepare("ALTER TABLE \"content_nodes\" ADD COLUMN startShowingAt TEXT;").run(), t = !0;
|
|
22246
|
+
} catch {}
|
|
22247
|
+
if (!n.has("stopShowingAt")) try {
|
|
22248
|
+
await e.prepare("ALTER TABLE \"content_nodes\" ADD COLUMN stopShowingAt TEXT;").run(), t = !0;
|
|
22249
|
+
} catch {}
|
|
22250
|
+
if (t) try {
|
|
22251
|
+
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.");
|
|
22252
|
+
} catch (e) {
|
|
22253
|
+
console.error("[Schema Sync] Failed to backfill dates:", e);
|
|
22254
|
+
}
|
|
22243
22255
|
}
|
|
22244
22256
|
if (t === "assets") {
|
|
22245
22257
|
if (!n.has("parentAssetId")) try {
|
|
@@ -23002,7 +23014,9 @@ var Fb = { hasSubscribers: !1 }, Ib = Fb, Lb = Fb, Rb = typeof performance == "o
|
|
|
23002
23014
|
}, Qb = null;
|
|
23003
23015
|
function $b(e) {
|
|
23004
23016
|
let t = process.env.CACHE_DRIVER || "lru";
|
|
23005
|
-
|
|
23017
|
+
if (t === "none" || t === "off" || t === "false") return new Zb();
|
|
23018
|
+
let n = e?.env?.CACHE_KV || e?.env?.CMS_CACHE_KV;
|
|
23019
|
+
return n ? new Xb(n) : t === "lru" ? (Qb ||= new Yb(), Qb) : new Zb();
|
|
23006
23020
|
}
|
|
23007
23021
|
//#endregion
|
|
23008
23022
|
//#region server/storage/local.ts
|
|
@@ -23573,6 +23587,7 @@ var mx = class {
|
|
|
23573
23587
|
return {
|
|
23574
23588
|
zoneId: e.env?.CLOUDFLARE_ZONE_ID || this.env.CLOUDFLARE_ZONE_ID,
|
|
23575
23589
|
apiToken: e.env?.CLOUDFLARE_API_TOKEN || this.env.CLOUDFLARE_API_TOKEN,
|
|
23590
|
+
purgeToken: e.env?.FRONTEND_API_SECRET || this.env.FRONTEND_API_SECRET || e.env?.CLOUDFLARE_API_TOKEN || this.env.CLOUDFLARE_API_TOKEN,
|
|
23576
23591
|
frontendUrl: (e.env?.PUBLIC_FRONTEND_URL || this.env.PUBLIC_FRONTEND_URL || "http://localhost:4321").replace(/\/+$/, ""),
|
|
23577
23592
|
cdnDomain: t ? t.replace(/^https?:\/\//, "").replace(/\/+$/, "") : "localhost:8787",
|
|
23578
23593
|
frontendWorker: e.env?.FRONTEND_WORKER || this.env.FRONTEND_WORKER,
|
|
@@ -23600,7 +23615,7 @@ var mx = class {
|
|
|
23600
23615
|
return r && n && r.startsWith(`https://${n}/`) && !r.includes("/media/") && (r = r.replace(`https://${n}/`, `https://${n}/media/`)), r;
|
|
23601
23616
|
}
|
|
23602
23617
|
async callAstroPurge(e, t, n) {
|
|
23603
|
-
let {
|
|
23618
|
+
let { purgeToken: r, frontendUrl: i, frontendWorker: a, disableCachePurge: o } = this.getEnv(e);
|
|
23604
23619
|
if (o === "true" || o === !0 || o === "1") return new Response(JSON.stringify({ skipped: !0 }), { status: 200 });
|
|
23605
23620
|
let s = (n || i).replace(/\/+$/, ""), c = `${s}/api/purge`, l = { "Content-Type": "application/json" };
|
|
23606
23621
|
if (r && (l.Authorization = `Bearer ${r}`), a && typeof a.fetch == "function") try {
|
|
@@ -23630,8 +23645,21 @@ var mx = class {
|
|
|
23630
23645
|
try {
|
|
23631
23646
|
let a = $b(e);
|
|
23632
23647
|
if (n) {
|
|
23633
|
-
let e = t.prepare("SELECT treeId FROM tree_nodes WHERE contentId =
|
|
23634
|
-
for (let e of
|
|
23648
|
+
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();
|
|
23649
|
+
for (let e of o) {
|
|
23650
|
+
let t = /* @__PURE__ */ new Set(["default", "all"]);
|
|
23651
|
+
e.channelId !== null && e.channelId !== void 0 && t.add(String(e.channelId)), e.channelKey && t.add(String(e.channelKey));
|
|
23652
|
+
let n = /* @__PURE__ */ new Set();
|
|
23653
|
+
e.treeId !== null && e.treeId !== void 0 && n.add(String(e.treeId)), e.treeKey && n.add(String(e.treeKey));
|
|
23654
|
+
let r = /* @__PURE__ */ new Set(["default"]);
|
|
23655
|
+
i && r.add(i.trim()), e.channelDefaultLanguage && r.add(String(e.channelDefaultLanguage).trim());
|
|
23656
|
+
try {
|
|
23657
|
+
let t = typeof e.treeDataJson == "string" ? JSON.parse(e.treeDataJson) : e.treeDataJson;
|
|
23658
|
+
(t?.defaultLanguage || t?.language) && r.add(String(t.defaultLanguage || t.language).trim());
|
|
23659
|
+
} catch {}
|
|
23660
|
+
for (let e of t) for (let t of n) for (let n of r) s.add(`tree:${e}:${t}:${n || "default"}`);
|
|
23661
|
+
}
|
|
23662
|
+
await Promise.all(Array.from(s, (e) => a.delete(e)));
|
|
23635
23663
|
}
|
|
23636
23664
|
if (r) {
|
|
23637
23665
|
let e = r.replace(/^\/+|\/+$/g, ""), o = ["default", "1"];
|
|
@@ -23645,9 +23673,37 @@ var mx = class {
|
|
|
23645
23673
|
console.warn("[CacheManager] Failed to purge internal worker cache:", e);
|
|
23646
23674
|
}
|
|
23647
23675
|
}
|
|
23676
|
+
async purgeVisibilityChange(e, t, n) {
|
|
23677
|
+
try {
|
|
23678
|
+
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];
|
|
23679
|
+
await this.purgeInternalWorkerCache(e, t, n, i?.slug, i?.language);
|
|
23680
|
+
let a = await this.callAstroPurge(e, { purge_everything: !0 }), o = await a.json().catch(() => ({}));
|
|
23681
|
+
if (!a.ok || o?.success === !1 || o?.skipped) return console.warn(`[CacheManager] Visibility purge failed at Astro Worker (${a.status}).`), !1;
|
|
23682
|
+
let { zoneId: s, apiToken: c } = this.getEnv(e), l = this.isLocalEnv(e);
|
|
23683
|
+
if (s && c && !this.isLocalEnv(e)) {
|
|
23684
|
+
let e = await fetch(`https://api.cloudflare.com/client/v4/zones/${s}/purge_cache`, {
|
|
23685
|
+
method: "POST",
|
|
23686
|
+
headers: {
|
|
23687
|
+
Authorization: `Bearer ${c}`,
|
|
23688
|
+
"Content-Type": "application/json"
|
|
23689
|
+
},
|
|
23690
|
+
body: JSON.stringify({ purge_everything: !0 })
|
|
23691
|
+
}), t = await e.json().catch(() => ({}));
|
|
23692
|
+
l = e.ok && t?.success === !0, l || console.warn("[CacheManager] Visibility purge failed at Cloudflare Zone cache:", JSON.stringify(t));
|
|
23693
|
+
} else this.isLocalEnv(e) || console.warn("[CacheManager] Visibility purge lacks CLOUDFLARE_ZONE_ID or CLOUDFLARE_API_TOKEN.");
|
|
23694
|
+
return this.dispatch(e, this.warmAllPublishedPages(e, t)), l;
|
|
23695
|
+
} catch (e) {
|
|
23696
|
+
return console.warn("[CacheManager] Visibility cache purge failed:", e), !1;
|
|
23697
|
+
}
|
|
23698
|
+
}
|
|
23648
23699
|
purgeNode(e, t, n, r = !1, i = []) {
|
|
23649
23700
|
if (r) {
|
|
23650
|
-
console.log(`[CacheManager] Structural change detected on nodeId ${n}. Escalating to Global Purge.`)
|
|
23701
|
+
console.log(`[CacheManager] Structural change detected on nodeId ${n}. Escalating to Global Purge.`);
|
|
23702
|
+
let r = (async () => {
|
|
23703
|
+
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];
|
|
23704
|
+
await this.purgeInternalWorkerCache(e, t, n, i?.slug, i?.language), await this.purgeGlobalCacheDirect(e, t);
|
|
23705
|
+
})();
|
|
23706
|
+
this.dispatch(e, r);
|
|
23651
23707
|
return;
|
|
23652
23708
|
}
|
|
23653
23709
|
let a = (async () => {
|
|
@@ -23733,8 +23789,12 @@ var mx = class {
|
|
|
23733
23789
|
}
|
|
23734
23790
|
async purgeGlobalCacheDirect(e, t) {
|
|
23735
23791
|
try {
|
|
23736
|
-
let { zoneId: n, apiToken: r } = this.getEnv(e);
|
|
23737
|
-
if (!
|
|
23792
|
+
let { zoneId: n, apiToken: r } = this.getEnv(e), i = await this.callAstroPurge(e, { purge_everything: !0 });
|
|
23793
|
+
if (!i.ok) {
|
|
23794
|
+
let e = await i.text().catch(() => "");
|
|
23795
|
+
console.warn(`[CacheManager] Astro global purge failed (${i.status}): ${e.slice(0, 500)}`);
|
|
23796
|
+
return;
|
|
23797
|
+
}
|
|
23738
23798
|
if (n && r && !this.isLocalEnv(e)) try {
|
|
23739
23799
|
let e = await (await fetch(`https://api.cloudflare.com/client/v4/zones/${n}/purge_cache`, {
|
|
23740
23800
|
method: "POST",
|
|
@@ -23876,8 +23936,9 @@ async function hx(e) {
|
|
|
23876
23936
|
await e.prepare("DELETE FROM node_routes").run();
|
|
23877
23937
|
let h = Array.from(p.values());
|
|
23878
23938
|
if (h.length === 0) return;
|
|
23879
|
-
|
|
23880
|
-
|
|
23939
|
+
let g = [];
|
|
23940
|
+
for (let e = 0; e < h.length; e += 15) {
|
|
23941
|
+
let t = h.slice(e, e + 15), n = t.map(() => "(?, ?, ?, ?, ?, ?)").join(","), r = t.flatMap((e) => [
|
|
23881
23942
|
e.path,
|
|
23882
23943
|
e.channelId,
|
|
23883
23944
|
e.nodeId,
|
|
@@ -23885,10 +23946,17 @@ async function hx(e) {
|
|
|
23885
23946
|
e.isCanonical,
|
|
23886
23947
|
e.redirectUrl ?? null
|
|
23887
23948
|
]);
|
|
23888
|
-
|
|
23889
|
-
|
|
23890
|
-
|
|
23891
|
-
|
|
23949
|
+
g.push({
|
|
23950
|
+
placeholders: n,
|
|
23951
|
+
params: r
|
|
23952
|
+
});
|
|
23953
|
+
}
|
|
23954
|
+
for (let t = 0; t < g.length; t += 50) {
|
|
23955
|
+
let n = g.slice(t, t + 50);
|
|
23956
|
+
await Promise.all(n.map((t) => e.prepare(`
|
|
23957
|
+
INSERT INTO node_routes (path, channelId, nodeId, treeId, isCanonical, redirectUrl)
|
|
23958
|
+
VALUES ${t.placeholders}
|
|
23959
|
+
`).run(...t.params)));
|
|
23892
23960
|
}
|
|
23893
23961
|
console.log(`[Route Generator] Successfully built ${h.length} enterprise routes.`);
|
|
23894
23962
|
} catch (e) {
|
|
@@ -23898,7 +23966,25 @@ async function hx(e) {
|
|
|
23898
23966
|
//#endregion
|
|
23899
23967
|
//#region server/routes/admin/nodes.ts
|
|
23900
23968
|
var gx = new e();
|
|
23901
|
-
|
|
23969
|
+
function _x(e, t, n = []) {
|
|
23970
|
+
let r = new mx(e.env), i = (async () => {
|
|
23971
|
+
for (let i of n) {
|
|
23972
|
+
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];
|
|
23973
|
+
await r.purgeInternalWorkerCache(e, t, i, a?.slug, a?.language);
|
|
23974
|
+
}
|
|
23975
|
+
await hx(t), await r.purgeGlobalCacheDirect(e, t);
|
|
23976
|
+
})().catch((e) => {
|
|
23977
|
+
console.error("[Node Routes] Background rebuild/purge failed:", e);
|
|
23978
|
+
});
|
|
23979
|
+
try {
|
|
23980
|
+
let t = e.executionCtx;
|
|
23981
|
+
if (t && typeof t.waitUntil == "function") {
|
|
23982
|
+
t.waitUntil(i);
|
|
23983
|
+
return;
|
|
23984
|
+
}
|
|
23985
|
+
} catch {}
|
|
23986
|
+
}
|
|
23987
|
+
async function vx(e, t, n = []) {
|
|
23902
23988
|
let r = e.prepare(t);
|
|
23903
23989
|
if (typeof r.bind == "function") {
|
|
23904
23990
|
let e = await r.bind(...n).all();
|
|
@@ -23910,75 +23996,50 @@ async function _x(e, t, n = []) {
|
|
|
23910
23996
|
}
|
|
23911
23997
|
return [];
|
|
23912
23998
|
}
|
|
23913
|
-
async function
|
|
23999
|
+
async function yx(e, t, n = []) {
|
|
23914
24000
|
let r = e.prepare(t);
|
|
23915
24001
|
if (typeof r.bind == "function") return r.bind(...n).run();
|
|
23916
24002
|
if (typeof r.run == "function") return r.run(...n);
|
|
23917
24003
|
}
|
|
23918
|
-
function
|
|
24004
|
+
function bx(e) {
|
|
23919
24005
|
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
24006
|
}
|
|
23921
|
-
function
|
|
24007
|
+
function xx(e) {
|
|
23922
24008
|
return +(e === !0 || e === 1 || e === "1" || e === "true");
|
|
23923
24009
|
}
|
|
23924
|
-
function
|
|
24010
|
+
function Sx(e) {
|
|
23925
24011
|
if (e == null || e === "null" || e === "" || typeof e == "string" && e.startsWith("draft-")) return null;
|
|
23926
24012
|
let t = Number(e);
|
|
23927
24013
|
return isNaN(t) ? null : t;
|
|
23928
24014
|
}
|
|
23929
|
-
function
|
|
24015
|
+
function Cx(e) {
|
|
23930
24016
|
let t = { ...e };
|
|
23931
24017
|
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];
|
|
24018
|
+
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
24019
|
return t;
|
|
23959
24020
|
}
|
|
23960
|
-
function
|
|
23961
|
-
return e ? typeof e == "string" ? (e.startsWith("ast_") && t.add(e), t) : Array.isArray(e) ? (e.forEach((e) =>
|
|
24021
|
+
function wx(e, t = /* @__PURE__ */ new Set()) {
|
|
24022
|
+
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
24023
|
}
|
|
23963
|
-
function
|
|
24024
|
+
function Tx(e, t) {
|
|
23964
24025
|
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 ||
|
|
24026
|
+
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;
|
|
24027
|
+
return n || r || i || a || o || s || u;
|
|
23967
24028
|
}
|
|
23968
|
-
async function
|
|
24029
|
+
async function Ex(e, t, n) {
|
|
23969
24030
|
for (let r of n) {
|
|
23970
|
-
let n = (await
|
|
23971
|
-
if (n && n.isSystemVariant && !((await
|
|
24031
|
+
let n = (await vx(e, "\n SELECT id, storageKeyPrivate, isSystemVariant, parentAssetId, filename\n FROM assets WHERE id = ?\n ", [r]))[0];
|
|
24032
|
+
if (n && n.isSystemVariant && !((await vx(e, "SELECT 1 FROM node_assets WHERE assetId = ? LIMIT 1", [n.id])).length > 0)) {
|
|
23972
24033
|
if (n.storageKeyPrivate) try {
|
|
23973
24034
|
await t.delete(n.storageKeyPrivate);
|
|
23974
24035
|
} catch (e) {
|
|
23975
24036
|
console.warn(`[Asset Cleanup] Failed to delete crop ${n.storageKeyPrivate}:`, e);
|
|
23976
24037
|
}
|
|
23977
|
-
await
|
|
24038
|
+
await yx(e, "DELETE FROM node_assets WHERE assetId = ?", [n.id]), await yx(e, "DELETE FROM assets WHERE id = ?", [n.id]);
|
|
23978
24039
|
}
|
|
23979
24040
|
}
|
|
23980
24041
|
}
|
|
23981
|
-
async function
|
|
24042
|
+
async function Dx(e, t, n) {
|
|
23982
24043
|
let r = {}, i = null;
|
|
23983
24044
|
if (t) {
|
|
23984
24045
|
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 +24088,8 @@ gx.get("/", async (e) => {
|
|
|
24027
24088
|
nodeType: i.contentType,
|
|
24028
24089
|
contentType: i.contentType,
|
|
24029
24090
|
isHidden: !!i.isHidden,
|
|
24091
|
+
startShowingAt: i.startShowingAt || null,
|
|
24092
|
+
stopShowingAt: i.stopShowingAt || null,
|
|
24030
24093
|
status: i.status || "draft",
|
|
24031
24094
|
publishedAt: i.publishedAt || null,
|
|
24032
24095
|
hasUnpublishedChanges: s,
|
|
@@ -24039,7 +24102,7 @@ gx.get("/", async (e) => {
|
|
|
24039
24102
|
if (l) try {
|
|
24040
24103
|
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
24104
|
if (a) {
|
|
24042
|
-
let { resolvedLayoutId: e, inheritedFields: r } = await
|
|
24105
|
+
let { resolvedLayoutId: e, inheritedFields: r } = await Dx(t, a.parentId, a.treeId);
|
|
24043
24106
|
(s === "inherit" || !s) && (s = e);
|
|
24044
24107
|
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
24108
|
}
|
|
@@ -24054,7 +24117,7 @@ gx.get("/", async (e) => {
|
|
|
24054
24117
|
let r = t.allowedLayouts;
|
|
24055
24118
|
return r ? typeof r == "string" ? r === e : !Array.isArray(r) || r.length === 0 || r.includes(e) : !0;
|
|
24056
24119
|
})(s) && (s = null), (s === "inherit" || !s) && (s = o.defaultLayout || null);
|
|
24057
|
-
let u = await fx(t,
|
|
24120
|
+
let u = await fx(t, Cx(n));
|
|
24058
24121
|
Object.assign(c, u), c.resolvedLayoutId = s;
|
|
24059
24122
|
} catch {}
|
|
24060
24123
|
let u = await t.prepare("SELECT channelId FROM node_channels WHERE nodeId = ?").all(r);
|
|
@@ -24082,7 +24145,7 @@ gx.get("/", async (e) => {
|
|
|
24082
24145
|
blocks: m
|
|
24083
24146
|
});
|
|
24084
24147
|
}
|
|
24085
|
-
let m = [], h = [o ? "
|
|
24148
|
+
let m = [], h = [o ? "cn.deletedAt IS NOT NULL" : "cn.deletedAt IS NULL"];
|
|
24086
24149
|
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
24150
|
let e = r.split(",").map((e) => e.trim()).filter(Boolean);
|
|
24088
24151
|
e.length > 0 && (h.push(`cn.contentType IN (${e.map(() => "?").join(",")})`), m.push(...e));
|
|
@@ -24159,6 +24222,8 @@ gx.get("/", async (e) => {
|
|
|
24159
24222
|
contentType: e.contentType,
|
|
24160
24223
|
nodeType: e.contentType,
|
|
24161
24224
|
isHidden: !!e.isHidden,
|
|
24225
|
+
startShowingAt: e.startShowingAt || null,
|
|
24226
|
+
stopShowingAt: e.stopShowingAt || null,
|
|
24162
24227
|
status: e.status || "draft",
|
|
24163
24228
|
publishedAt: e.publishedAt || null,
|
|
24164
24229
|
hasUnpublishedChanges: n,
|
|
@@ -24176,7 +24241,7 @@ gx.get("/", async (e) => {
|
|
|
24176
24241
|
otherCount: e.otherCount || 0
|
|
24177
24242
|
}, i = e.draftDataJson || e.dataJson;
|
|
24178
24243
|
if (i) try {
|
|
24179
|
-
let e = typeof i == "string" ? JSON.parse(i) : i, n = await fx(t,
|
|
24244
|
+
let e = typeof i == "string" ? JSON.parse(i) : i, n = await fx(t, Cx(e));
|
|
24180
24245
|
Object.assign(r, n);
|
|
24181
24246
|
} catch {}
|
|
24182
24247
|
return r;
|
|
@@ -24189,34 +24254,34 @@ gx.get("/", async (e) => {
|
|
|
24189
24254
|
limit: f
|
|
24190
24255
|
});
|
|
24191
24256
|
}), 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(
|
|
24257
|
+
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;
|
|
24258
|
+
if (te) {
|
|
24259
|
+
let e = await t.prepare("SELECT dataJson FROM trees WHERE id = ? OR key = ? LIMIT 1").get(Number(te) || -1, String(te));
|
|
24195
24260
|
if (e?.dataJson) try {
|
|
24196
24261
|
let t = typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson;
|
|
24197
|
-
|
|
24262
|
+
O = t.defaultLanguage?.trim() || t.language?.trim() || null;
|
|
24198
24263
|
} catch {}
|
|
24199
24264
|
}
|
|
24200
|
-
if (!
|
|
24201
|
-
let e = typeof
|
|
24265
|
+
if (!O && _ && Array.isArray(_) && _.length > 0) {
|
|
24266
|
+
let e = typeof _[0] == "object" ? _[0].id : _[0];
|
|
24202
24267
|
if (e && e !== "all") {
|
|
24203
24268
|
let n = await t.prepare("SELECT defaultLanguage, dataJson FROM channels WHERE id = ? LIMIT 1").get(Number(e));
|
|
24204
24269
|
if (n) {
|
|
24205
|
-
if (n.defaultLanguage)
|
|
24270
|
+
if (n.defaultLanguage) O = n.defaultLanguage.trim();
|
|
24206
24271
|
else if (n.dataJson) try {
|
|
24207
24272
|
let e = typeof n.dataJson == "string" ? JSON.parse(n.dataJson) : n.dataJson;
|
|
24208
|
-
|
|
24273
|
+
O = e.defaultLanguage?.trim() || e.language?.trim() || null;
|
|
24209
24274
|
} catch {}
|
|
24210
24275
|
}
|
|
24211
24276
|
}
|
|
24212
24277
|
}
|
|
24213
|
-
|
|
24214
|
-
let
|
|
24215
|
-
if (
|
|
24278
|
+
E && O && E === O && (E = null);
|
|
24279
|
+
let k = a, A = /* @__PURE__ */ new Set(), ne = !1, j = "draft", re = 0, ie = s === void 0 ? null : bx(s);
|
|
24280
|
+
if (ie) {
|
|
24216
24281
|
let n = [];
|
|
24217
|
-
if (
|
|
24282
|
+
if (v !== void 0 && Array.isArray(v) && v.length > 0) for (let e of v) n.push({
|
|
24218
24283
|
treeId: Number(e.treeId),
|
|
24219
|
-
parentId:
|
|
24284
|
+
parentId: Sx(e.parentId ?? e._draftParentId ?? null)
|
|
24220
24285
|
});
|
|
24221
24286
|
else if (a) {
|
|
24222
24287
|
let e = await t.prepare("SELECT treeId, parentId FROM tree_nodes WHERE contentId = ?").all(a), r = Array.isArray(e) ? e : e?.results || [];
|
|
@@ -24226,140 +24291,146 @@ gx.get("/", async (e) => {
|
|
|
24226
24291
|
});
|
|
24227
24292
|
}
|
|
24228
24293
|
for (let r of n) {
|
|
24229
|
-
let n = r.parentId === null ? "tn.parentId IS NULL" : "tn.parentId = ?", i = r.parentId === null ? [r.treeId,
|
|
24294
|
+
let n = r.parentId === null ? "tn.parentId IS NULL" : "tn.parentId = ?", i = r.parentId === null ? [r.treeId, ie] : [
|
|
24230
24295
|
r.treeId,
|
|
24231
24296
|
r.parentId,
|
|
24232
|
-
|
|
24297
|
+
ie
|
|
24233
24298
|
], o = `
|
|
24234
24299
|
SELECT cn.id FROM tree_nodes tn
|
|
24235
24300
|
INNER JOIN content_nodes cn ON tn.contentId = cn.id
|
|
24236
|
-
WHERE tn.treeId = ? AND ${n} AND cn.slug = ? AND
|
|
24301
|
+
WHERE tn.treeId = ? AND ${n} AND cn.slug = ? AND cn.deletedAt IS NULL
|
|
24237
24302
|
`;
|
|
24238
24303
|
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 '${
|
|
24304
|
+
error: `The slug '${ie}' is already in use by another page in this section.`,
|
|
24240
24305
|
field: "slug"
|
|
24241
24306
|
}, 409);
|
|
24242
24307
|
}
|
|
24243
24308
|
}
|
|
24244
24309
|
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
|
-
|
|
24310
|
+
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;
|
|
24311
|
+
ne = Tx(e, {
|
|
24247
24312
|
title: n,
|
|
24248
24313
|
slug: r,
|
|
24249
24314
|
isHidden: u,
|
|
24250
|
-
|
|
24315
|
+
startShowingAt: d,
|
|
24316
|
+
stopShowingAt: f,
|
|
24317
|
+
sanitizedFields: b
|
|
24251
24318
|
});
|
|
24252
|
-
let
|
|
24319
|
+
let p = e?.draftDataJson || e?.dataJson || "{}";
|
|
24253
24320
|
try {
|
|
24254
|
-
|
|
24321
|
+
wx(typeof p == "string" ? JSON.parse(p) : p, A);
|
|
24255
24322
|
} catch {}
|
|
24256
|
-
let
|
|
24323
|
+
let _ = {};
|
|
24257
24324
|
try {
|
|
24258
|
-
|
|
24325
|
+
_ = JSON.parse(p);
|
|
24259
24326
|
} catch {}
|
|
24260
|
-
let
|
|
24327
|
+
let v = {
|
|
24261
24328
|
title: n,
|
|
24262
24329
|
slug: r,
|
|
24263
24330
|
contentType: i,
|
|
24264
24331
|
language: l,
|
|
24265
24332
|
isHidden: u,
|
|
24333
|
+
startShowingAt: d,
|
|
24334
|
+
stopShowingAt: f,
|
|
24335
|
+
...b
|
|
24336
|
+
}, y = JSON.stringify({
|
|
24337
|
+
..._,
|
|
24266
24338
|
...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;
|
|
24339
|
+
}), x = !1;
|
|
24340
|
+
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) {
|
|
24341
|
+
for (let e of Object.keys(b)) if (JSON.stringify(b[e]) !== JSON.stringify(_[e])) {
|
|
24342
|
+
x = !0;
|
|
24274
24343
|
break;
|
|
24275
24344
|
}
|
|
24276
24345
|
}
|
|
24277
|
-
if (!
|
|
24346
|
+
if (!x && g !== void 0) {
|
|
24278
24347
|
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 =
|
|
24348
|
+
if (g.length !== n.length) x = !0;
|
|
24349
|
+
else for (let e = 0; e < g.length; e++) {
|
|
24350
|
+
let t = g[e], r = n[e], i = t.componentId || t.elementType || "text-block", a = t.region || "content", o = { ...t.data || {} };
|
|
24282
24351
|
delete o._instanceId, delete o.blockId;
|
|
24283
24352
|
let s = {};
|
|
24284
24353
|
try {
|
|
24285
24354
|
s = JSON.parse(r.dataJson);
|
|
24286
24355
|
} catch {}
|
|
24287
24356
|
if (delete s._instanceId, delete s.blockId, i !== r.elementType || a !== r.region || JSON.stringify(o) !== JSON.stringify(s)) {
|
|
24288
|
-
|
|
24357
|
+
x = !0;
|
|
24289
24358
|
break;
|
|
24290
24359
|
}
|
|
24291
24360
|
}
|
|
24292
24361
|
}
|
|
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(
|
|
24362
|
+
j = e?.status === "published" || e?.publishedAt ? "published" : "draft";
|
|
24363
|
+
let S = e?.hasUnpublishedChanges === 1 || e?.hasUnpublishedChanges === !0;
|
|
24364
|
+
re = x ? 1 : +!!S;
|
|
24365
|
+
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;
|
|
24366
|
+
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
24367
|
} else {
|
|
24299
|
-
|
|
24300
|
-
let e = {
|
|
24368
|
+
ne = !0;
|
|
24369
|
+
let e = m === void 0 ? null : m, n = h === void 0 ? null : h, r = {
|
|
24301
24370
|
title: o || "Untitled",
|
|
24302
|
-
slug:
|
|
24303
|
-
contentType:
|
|
24304
|
-
language:
|
|
24305
|
-
isHidden:
|
|
24306
|
-
|
|
24307
|
-
|
|
24308
|
-
|
|
24309
|
-
|
|
24310
|
-
|
|
24311
|
-
|
|
24312
|
-
|
|
24371
|
+
slug: ie,
|
|
24372
|
+
contentType: T,
|
|
24373
|
+
language: E,
|
|
24374
|
+
isHidden: w,
|
|
24375
|
+
startShowingAt: e,
|
|
24376
|
+
stopShowingAt: n,
|
|
24377
|
+
...b
|
|
24378
|
+
}, 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);
|
|
24379
|
+
k = Number(i.lastInsertRowid);
|
|
24380
|
+
}
|
|
24381
|
+
if (_ !== void 0 && Array.isArray(_) && k) {
|
|
24382
|
+
await t.prepare("DELETE FROM node_channels WHERE nodeId = ?").run(k);
|
|
24383
|
+
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
24384
|
if (e.length > 0) {
|
|
24314
|
-
let n = e.map(() => "(?, ?)").join(", "), r = e.flatMap((e) => [
|
|
24385
|
+
let n = e.map(() => "(?, ?)").join(", "), r = e.flatMap((e) => [k, e]);
|
|
24315
24386
|
await t.prepare(`INSERT OR IGNORE INTO node_channels (nodeId, channelId) VALUES ${n}`).run(...r);
|
|
24316
24387
|
}
|
|
24317
24388
|
}
|
|
24318
|
-
if (
|
|
24389
|
+
if (v !== void 0 && Array.isArray(v) && v.length > 0 && k) for (let e of v) {
|
|
24319
24390
|
if (!e || !e.treeId) continue;
|
|
24320
|
-
let n = Number(e.treeId) || e.treeId, r =
|
|
24321
|
-
a ? ((a.parentId !== r || a.sortOrder !== i) && (
|
|
24391
|
+
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);
|
|
24392
|
+
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
24393
|
}
|
|
24323
|
-
let
|
|
24324
|
-
if (
|
|
24325
|
-
await t.prepare("DELETE FROM content_blocks WHERE contentId = ? AND isDraft = 1").run(
|
|
24394
|
+
let ae = [], oe = [], se = [];
|
|
24395
|
+
if (g !== void 0 && Array.isArray(g) && k) {
|
|
24396
|
+
await t.prepare("DELETE FROM content_blocks WHERE contentId = ? AND isDraft = 1").run(k);
|
|
24326
24397
|
let e = [], n = [];
|
|
24327
|
-
for (let t = 0; t <
|
|
24328
|
-
let r =
|
|
24398
|
+
for (let t = 0; t < g.length; t++) {
|
|
24399
|
+
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
24400
|
...a,
|
|
24330
24401
|
blockId: o,
|
|
24331
24402
|
_instanceId: o
|
|
24332
24403
|
});
|
|
24333
|
-
c.forEach((e) =>
|
|
24404
|
+
c.forEach((e) => ae.push({
|
|
24334
24405
|
...e,
|
|
24335
24406
|
fieldKey: `blocks[${t}].${e.fieldKey}`
|
|
24336
|
-
})), l.forEach((e) =>
|
|
24407
|
+
})), l.forEach((e) => oe.push({
|
|
24337
24408
|
...e,
|
|
24338
24409
|
fieldKey: `blocks[${t}].${e.fieldKey}`
|
|
24339
|
-
})), u.forEach((e) =>
|
|
24410
|
+
})), u.forEach((e) => se.push({
|
|
24340
24411
|
...e,
|
|
24341
24412
|
fieldKey: `blocks[${t}].${e.fieldKey}`
|
|
24342
24413
|
}));
|
|
24343
24414
|
let d = r.region !== void 0 && r.region !== null && String(r.region).trim() !== "" ? String(r.region) : "content";
|
|
24344
|
-
e.push("(?, ?, ?, ?, ?, 1)"), n.push(
|
|
24415
|
+
e.push("(?, ?, ?, ?, ?, 1)"), n.push(k, t, i, JSON.stringify(s), d);
|
|
24345
24416
|
}
|
|
24346
24417
|
e.length > 0 && await t.prepare(`INSERT INTO content_blocks (contentId, sortOrder, elementType, dataJson, region, isDraft) VALUES ${e.join(", ")}`).run(...n);
|
|
24347
24418
|
}
|
|
24348
|
-
if (
|
|
24349
|
-
let n = [...
|
|
24350
|
-
await ox(t,
|
|
24351
|
-
let a = new Set(n.map((e) => e.assetId)), o = new Set([...
|
|
24419
|
+
if (k) {
|
|
24420
|
+
let n = [...x, ...ae], r = [...S, ...oe], i = [...C, ...se];
|
|
24421
|
+
await ox(t, k, n), await sx(t, k, r), await cx(t, k, i);
|
|
24422
|
+
let a = new Set(n.map((e) => e.assetId)), o = new Set([...A].filter((e) => !a.has(e)));
|
|
24352
24423
|
if (o.size > 0) {
|
|
24353
24424
|
let { storage: n } = ix(e.env);
|
|
24354
|
-
await
|
|
24425
|
+
await Ex(t, n, o);
|
|
24355
24426
|
}
|
|
24356
24427
|
}
|
|
24357
24428
|
return await $b(e).clear(), e.json({
|
|
24358
24429
|
success: !0,
|
|
24359
|
-
id:
|
|
24360
|
-
status:
|
|
24361
|
-
hasUnpublishedChanges:
|
|
24362
|
-
isStructuralChange:
|
|
24430
|
+
id: k,
|
|
24431
|
+
status: j,
|
|
24432
|
+
hasUnpublishedChanges: re === 1 || j === "draft",
|
|
24433
|
+
isStructuralChange: ne
|
|
24363
24434
|
});
|
|
24364
24435
|
}), gx.post("/publish", async (e) => {
|
|
24365
24436
|
let t = e.get("db"), n = await e.req.json(), r = n.id || n.nodeId;
|
|
@@ -24374,34 +24445,36 @@ gx.get("/", async (e) => {
|
|
|
24374
24445
|
try {
|
|
24375
24446
|
c = typeof o.draftDataJson == "string" ? JSON.parse(o.draftDataJson) : o.draftDataJson || {};
|
|
24376
24447
|
} 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 (
|
|
24448
|
+
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;
|
|
24449
|
+
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);
|
|
24450
|
+
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 || [];
|
|
24451
|
+
if (te.length > 0) {
|
|
24381
24452
|
let e = [], n = [];
|
|
24382
|
-
for (let t of
|
|
24453
|
+
for (let t of te) {
|
|
24383
24454
|
let r = t.region !== void 0 && t.region !== null && String(t.region).trim() !== "" ? String(t.region) : "content";
|
|
24384
24455
|
e.push("(?, ?, ?, ?, ?, 0)"), n.push(i, t.sortOrder, t.elementType, t.dataJson, r);
|
|
24385
24456
|
}
|
|
24386
24457
|
await t.prepare(`INSERT INTO content_blocks (contentId, sortOrder, elementType, dataJson, region, isDraft) VALUES ${e.join(", ")}`).run(...n);
|
|
24387
24458
|
}
|
|
24388
|
-
let
|
|
24389
|
-
version:
|
|
24459
|
+
let O = ((await t.prepare("SELECT COUNT(*) as count FROM node_revisions WHERE nodeId = ?").get(i))?.count || 0) + 1, k = {
|
|
24460
|
+
version: O,
|
|
24390
24461
|
publishedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
24391
24462
|
node: {
|
|
24392
24463
|
...o,
|
|
24393
|
-
dataJson:
|
|
24464
|
+
dataJson: b
|
|
24394
24465
|
},
|
|
24395
|
-
blocks:
|
|
24466
|
+
blocks: te
|
|
24396
24467
|
};
|
|
24397
|
-
|
|
24468
|
+
await t.prepare("INSERT INTO node_revisions (nodeId, version, snapshotJson, createdById) VALUES (?, ?, ?, ?)").run(i, O, JSON.stringify(k), a), await $b(e).clear();
|
|
24469
|
+
let A = new mx(e.env);
|
|
24470
|
+
return y ? _x(e, t, [i]) : A.purgeNode(e, t, i, !1), e.json({
|
|
24398
24471
|
success: !0,
|
|
24399
24472
|
id: i,
|
|
24400
24473
|
status: "published",
|
|
24401
|
-
version:
|
|
24402
|
-
publishedAt:
|
|
24474
|
+
version: O,
|
|
24475
|
+
publishedAt: k.publishedAt,
|
|
24403
24476
|
hasUnpublishedChanges: !1,
|
|
24404
|
-
isStructuralChange:
|
|
24477
|
+
isStructuralChange: y
|
|
24405
24478
|
});
|
|
24406
24479
|
}), gx.post("/publish/batch", async (e) => {
|
|
24407
24480
|
let t = e.get("db"), n = await e.req.json(), r = n.ids;
|
|
@@ -24420,33 +24493,33 @@ gx.get("/", async (e) => {
|
|
|
24420
24493
|
try {
|
|
24421
24494
|
l = typeof s.draftDataJson == "string" ? JSON.parse(s.draftDataJson) : s.draftDataJson || {};
|
|
24422
24495
|
} 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 (
|
|
24496
|
+
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 ?? "";
|
|
24497
|
+
(u !== "" && d !== "" && u !== d || f !== "" && p !== "" && f !== p || m !== "" && h !== "" && m !== h || g !== _ || v !== y) && (a = !0);
|
|
24498
|
+
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;
|
|
24499
|
+
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);
|
|
24500
|
+
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 || [];
|
|
24501
|
+
if (te.length > 0) {
|
|
24429
24502
|
let e = [], n = [];
|
|
24430
|
-
for (let t of
|
|
24503
|
+
for (let t of te) {
|
|
24431
24504
|
let i = t.region !== void 0 && t.region !== null && String(t.region).trim() !== "" ? String(t.region) : "content";
|
|
24432
24505
|
e.push("(?, ?, ?, ?, ?, 0)"), n.push(r, t.sortOrder, t.elementType, t.dataJson, i);
|
|
24433
24506
|
}
|
|
24434
24507
|
await t.prepare(`INSERT INTO content_blocks (contentId, sortOrder, elementType, dataJson, region, isDraft) VALUES ${e.join(", ")}`).run(...n);
|
|
24435
24508
|
}
|
|
24436
|
-
let
|
|
24437
|
-
version:
|
|
24509
|
+
let O = ((await t.prepare("SELECT COUNT(*) as count FROM node_revisions WHERE nodeId = ?").get(r))?.count || 0) + 1, k = {
|
|
24510
|
+
version: O,
|
|
24438
24511
|
publishedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
24439
24512
|
node: {
|
|
24440
24513
|
...s,
|
|
24441
|
-
dataJson:
|
|
24514
|
+
dataJson: b
|
|
24442
24515
|
},
|
|
24443
|
-
blocks:
|
|
24516
|
+
blocks: te
|
|
24444
24517
|
};
|
|
24445
|
-
await t.prepare("INSERT INTO node_revisions (nodeId, version, snapshotJson, createdById) VALUES (?, ?, ?, ?)").run(r,
|
|
24518
|
+
await t.prepare("INSERT INTO node_revisions (nodeId, version, snapshotJson, createdById) VALUES (?, ?, ?, ?)").run(r, O, JSON.stringify(k), i), o.push(r);
|
|
24446
24519
|
}
|
|
24447
24520
|
await $b(e).clear();
|
|
24448
24521
|
let s = new mx(e.env);
|
|
24449
|
-
if (a)
|
|
24522
|
+
if (a) _x(e, t, o);
|
|
24450
24523
|
else for (let n of o) s.purgeNode(e, t, n, !1);
|
|
24451
24524
|
return e.json({
|
|
24452
24525
|
success: !0,
|
|
@@ -24458,13 +24531,13 @@ gx.get("/", async (e) => {
|
|
|
24458
24531
|
let t = e.get("db"), n = e.req.query("id");
|
|
24459
24532
|
if (!n) return e.json({ error: "Node ID required" }, 400);
|
|
24460
24533
|
let r = Number(n);
|
|
24461
|
-
return await t.prepare("UPDATE content_nodes SET deletedAt = CURRENT_TIMESTAMP WHERE id = ?").run(r), await $b(e).clear(),
|
|
24534
|
+
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
24535
|
success: !0,
|
|
24463
24536
|
deletedNodeId: r
|
|
24464
24537
|
});
|
|
24465
24538
|
}), gx.post("/restore", async (e) => {
|
|
24466
24539
|
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(),
|
|
24540
|
+
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
24541
|
success: !0,
|
|
24469
24542
|
restoredNodeId: r
|
|
24470
24543
|
})) : e.json({ error: "Node not found" }, 404) : e.json({ error: "Node ID required" }, 400);
|
|
@@ -24472,7 +24545,7 @@ gx.get("/", async (e) => {
|
|
|
24472
24545
|
let t = e.get("db"), n = e.req.query("id");
|
|
24473
24546
|
if (!n) return e.json({ error: "Node ID required" }, 400);
|
|
24474
24547
|
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(),
|
|
24548
|
+
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
24549
|
success: !0,
|
|
24477
24550
|
purgedNodeId: r
|
|
24478
24551
|
});
|
|
@@ -24487,7 +24560,7 @@ gx.get("/", async (e) => {
|
|
|
24487
24560
|
} catch {}
|
|
24488
24561
|
return {
|
|
24489
24562
|
version: e.version,
|
|
24490
|
-
publishedAt: t || new
|
|
24563
|
+
publishedAt: t || (/* @__PURE__ */ new Date()).toISOString(),
|
|
24491
24564
|
createdById: e.createdById
|
|
24492
24565
|
};
|
|
24493
24566
|
});
|
|
@@ -24545,15 +24618,18 @@ gx.get("/", async (e) => {
|
|
|
24545
24618
|
let t = JSON.stringify(e);
|
|
24546
24619
|
s += ", dataJson = ?, publishedDataJson = ?", c.push(t, t);
|
|
24547
24620
|
}
|
|
24548
|
-
|
|
24621
|
+
s += " WHERE id = ?", c.push(n), await t.prepare(s).run(...c), await $b(e).clear();
|
|
24622
|
+
let u = await new mx(e.env).purgeVisibilityChange(e, t, n);
|
|
24623
|
+
return e.json({
|
|
24549
24624
|
success: !0,
|
|
24550
|
-
isHidden: i
|
|
24625
|
+
isHidden: i,
|
|
24626
|
+
cacheInvalidated: u
|
|
24551
24627
|
});
|
|
24552
24628
|
});
|
|
24553
24629
|
//#endregion
|
|
24554
24630
|
//#region server/routes/admin/trees.ts
|
|
24555
|
-
var
|
|
24556
|
-
function
|
|
24631
|
+
var Ox = new e();
|
|
24632
|
+
function kx(e, t = null) {
|
|
24557
24633
|
let n = [];
|
|
24558
24634
|
for (let r = 0; r < e.length; r++) {
|
|
24559
24635
|
let i = e[r];
|
|
@@ -24565,19 +24641,19 @@ function Ox(e, t = null) {
|
|
|
24565
24641
|
id: o,
|
|
24566
24642
|
parentId: t,
|
|
24567
24643
|
sortOrder: r
|
|
24568
|
-
}), i.children && Array.isArray(i.children) && i.children.length > 0 && n.push(...
|
|
24644
|
+
}), i.children && Array.isArray(i.children) && i.children.length > 0 && n.push(...kx(i.children, o)));
|
|
24569
24645
|
}
|
|
24570
24646
|
return n;
|
|
24571
24647
|
}
|
|
24572
|
-
function
|
|
24648
|
+
function Ax(e) {
|
|
24573
24649
|
if (e == null || e === "null" || e === "" || typeof e == "string" && e.startsWith("draft-")) return null;
|
|
24574
24650
|
let t = Number(e);
|
|
24575
24651
|
return isNaN(t) ? null : t;
|
|
24576
24652
|
}
|
|
24577
|
-
function
|
|
24653
|
+
function jx(e) {
|
|
24578
24654
|
return +(e === !0 || e === 1 || e === "1" || e === "true");
|
|
24579
24655
|
}
|
|
24580
|
-
|
|
24656
|
+
Ox.get("/tree.json", async (e) => {
|
|
24581
24657
|
try {
|
|
24582
24658
|
let t = e.get("db"), n = e.req.query("treeId") || "main-nav", r = e.req.query("preview") === "true", i = 1;
|
|
24583
24659
|
if (isNaN(Number(n))) {
|
|
@@ -24588,7 +24664,7 @@ Dx.get("/tree.json", async (e) => {
|
|
|
24588
24664
|
e && e.id && (i = Number(e.id));
|
|
24589
24665
|
}
|
|
24590
24666
|
} 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 (
|
|
24667
|
+
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
24668
|
for (let e of o) {
|
|
24593
24669
|
let t = e.contentId;
|
|
24594
24670
|
c.has(t) || (c.add(t), s.push(e));
|
|
@@ -24630,7 +24706,7 @@ Dx.get("/tree.json", async (e) => {
|
|
|
24630
24706
|
} catch (t) {
|
|
24631
24707
|
return console.error("[CMS Tree API] GET Error:", t), e.json({ error: t.message || "Failed to fetch tree" }, 500);
|
|
24632
24708
|
}
|
|
24633
|
-
}),
|
|
24709
|
+
}), Ox.post("/tree.json", async (e) => {
|
|
24634
24710
|
try {
|
|
24635
24711
|
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
24712
|
if (isNaN(Number(r))) {
|
|
@@ -24642,7 +24718,7 @@ Dx.get("/tree.json", async (e) => {
|
|
|
24642
24718
|
}
|
|
24643
24719
|
} else o = Number(r);
|
|
24644
24720
|
if (n.tree && Array.isArray(n.tree)) {
|
|
24645
|
-
let r =
|
|
24721
|
+
let r = kx(n.tree, null);
|
|
24646
24722
|
if (r.length > 0) for (let e = 0; e < r.length; e += 50) {
|
|
24647
24723
|
let n = r.slice(e, e + 50), i = n.map((e) => e.id), a = i.map(() => "?").join(","), s = "UPDATE tree_nodes SET \n";
|
|
24648
24724
|
s += "parentId = CASE contentId \n", n.forEach(() => {
|
|
@@ -24662,9 +24738,9 @@ Dx.get("/tree.json", async (e) => {
|
|
|
24662
24738
|
reorderedCount: r.length
|
|
24663
24739
|
});
|
|
24664
24740
|
}
|
|
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 =
|
|
24741
|
+
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
24742
|
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 =
|
|
24743
|
+
let g = Ax(u), _ = e.get("user")?.id || null;
|
|
24668
24744
|
if (s === "create") {
|
|
24669
24745
|
let r = m.slug || n.slug || c, a = r ? String(r).toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "") : null;
|
|
24670
24746
|
if (a) {
|
|
@@ -24772,7 +24848,7 @@ Dx.get("/tree.json", async (e) => {
|
|
|
24772
24848
|
details: t.message
|
|
24773
24849
|
}, 500);
|
|
24774
24850
|
}
|
|
24775
|
-
}),
|
|
24851
|
+
}), Ox.get("/trees.json", async (e) => {
|
|
24776
24852
|
try {
|
|
24777
24853
|
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
24854
|
let n = Number(t.treeId), r = Number(t.channelId);
|
|
@@ -24802,7 +24878,7 @@ Dx.get("/tree.json", async (e) => {
|
|
|
24802
24878
|
} catch {
|
|
24803
24879
|
return e.json([]);
|
|
24804
24880
|
}
|
|
24805
|
-
}),
|
|
24881
|
+
}), Ox.post("/trees.json", async (e) => {
|
|
24806
24882
|
try {
|
|
24807
24883
|
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
24884
|
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 +24917,7 @@ Dx.get("/tree.json", async (e) => {
|
|
|
24841
24917
|
} catch (t) {
|
|
24842
24918
|
return console.error("[API Trees] Error saving tree:", t), e.json({ error: t.message || "Failed to save tree" }, 500);
|
|
24843
24919
|
}
|
|
24844
|
-
}),
|
|
24920
|
+
}), Ox.delete("/trees.json", async (e) => {
|
|
24845
24921
|
let t = e.get("db"), n = e.req.query("id");
|
|
24846
24922
|
if (!n) return e.json({ error: "Tree ID required" }, 400);
|
|
24847
24923
|
let r = Number(n);
|
|
@@ -24856,8 +24932,8 @@ Dx.get("/tree.json", async (e) => {
|
|
|
24856
24932
|
});
|
|
24857
24933
|
//#endregion
|
|
24858
24934
|
//#region server/routes/admin/channels.ts
|
|
24859
|
-
var
|
|
24860
|
-
|
|
24935
|
+
var Mx = new e();
|
|
24936
|
+
Mx.get("/", async (e) => {
|
|
24861
24937
|
try {
|
|
24862
24938
|
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
24939
|
e[t.channelId] || (e[t.channelId] = []);
|
|
@@ -24923,27 +24999,27 @@ jx.get("/", async (e) => {
|
|
|
24923
24999
|
error: t.message
|
|
24924
25000
|
}, 500);
|
|
24925
25001
|
}
|
|
24926
|
-
}),
|
|
25002
|
+
}), Mx.post("/", async (e) => {
|
|
24927
25003
|
try {
|
|
24928
25004
|
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
25005
|
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 || {}),
|
|
25006
|
+
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
25007
|
if (await t.prepare("SELECT id FROM channels WHERE key = ? AND id != ? LIMIT 1").get(C, a ?? -1)) return e.json({
|
|
24932
25008
|
error: `Channel API key "${C}" is already in use.`,
|
|
24933
25009
|
field: "key"
|
|
24934
25010
|
}, 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,
|
|
25011
|
+
let O = a;
|
|
25012
|
+
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
25013
|
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,
|
|
25014
|
+
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
25015
|
if (!n || !n.id) throw Error("Failed to retrieve newly created Channel ID from Cloudflare D1.");
|
|
24940
|
-
|
|
25016
|
+
O = Number(n.id);
|
|
24941
25017
|
}
|
|
24942
|
-
await t.prepare("DELETE FROM channel_trees WHERE channelId = ?").run(
|
|
25018
|
+
await t.prepare("DELETE FROM channel_trees WHERE channelId = ?").run(O);
|
|
24943
25019
|
let k = E.filter((e) => e && e.treeId && e.key);
|
|
24944
25020
|
if (k.length > 0) {
|
|
24945
25021
|
let e = k.map(() => "(?, ?, ?, ?)").join(", "), n = k.flatMap((e) => [
|
|
24946
|
-
|
|
25022
|
+
O,
|
|
24947
25023
|
Number(e.treeId) || e.treeId,
|
|
24948
25024
|
String(e.key).trim(),
|
|
24949
25025
|
JSON.stringify(e.meta || {})
|
|
@@ -24954,9 +25030,9 @@ jx.get("/", async (e) => {
|
|
|
24954
25030
|
`).run(...n);
|
|
24955
25031
|
}
|
|
24956
25032
|
let A = $b(e);
|
|
24957
|
-
return await A.delete(`channel:${C}`), await A.delete(`channel:${
|
|
25033
|
+
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
25034
|
success: !0,
|
|
24959
|
-
id:
|
|
25035
|
+
id: O
|
|
24960
25036
|
});
|
|
24961
25037
|
} catch (t) {
|
|
24962
25038
|
return console.error("[API Channels] Error saving channel:", t), e.json({
|
|
@@ -24964,7 +25040,7 @@ jx.get("/", async (e) => {
|
|
|
24964
25040
|
details: t.message
|
|
24965
25041
|
}, 500);
|
|
24966
25042
|
}
|
|
24967
|
-
}),
|
|
25043
|
+
}), Mx.delete("/", async (e) => {
|
|
24968
25044
|
let t = e.get("db"), n = e.req.query("id");
|
|
24969
25045
|
if (!n) return e.json({ error: "Channel ID required" }, 400);
|
|
24970
25046
|
let r = Number(n);
|
|
@@ -24984,15 +25060,15 @@ jx.get("/", async (e) => {
|
|
|
24984
25060
|
});
|
|
24985
25061
|
//#endregion
|
|
24986
25062
|
//#region server/routes/admin/taxonomies.ts
|
|
24987
|
-
var
|
|
24988
|
-
function
|
|
25063
|
+
var Nx = new e();
|
|
25064
|
+
function Px(e) {
|
|
24989
25065
|
return e.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().trim().replace(/[^a-z0-9\s-]/g, "").replace(/[\s-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
24990
25066
|
}
|
|
24991
|
-
function
|
|
25067
|
+
function Fx(e) {
|
|
24992
25068
|
let t = (e || "").trim().toLowerCase(), n = px()?.taxonomies || {};
|
|
24993
25069
|
return n[t] ? t : n[`${t}s`] ? `${t}s` : t.endsWith("s") && n[t.slice(0, -1)] ? t.slice(0, -1) : t;
|
|
24994
25070
|
}
|
|
24995
|
-
async function
|
|
25071
|
+
async function Ix(e, t, n = []) {
|
|
24996
25072
|
let r = e.prepare(t);
|
|
24997
25073
|
if (typeof r.bind == "function") {
|
|
24998
25074
|
let e = await r.bind(...n).all();
|
|
@@ -25004,10 +25080,10 @@ async function Fx(e, t, n = []) {
|
|
|
25004
25080
|
}
|
|
25005
25081
|
return [];
|
|
25006
25082
|
}
|
|
25007
|
-
|
|
25008
|
-
let t = e.get("db"), n =
|
|
25083
|
+
Nx.get("/:taxonomy", async (e) => {
|
|
25084
|
+
let t = e.get("db"), n = Fx(e.req.param("taxonomy"));
|
|
25009
25085
|
try {
|
|
25010
|
-
let r = (await
|
|
25086
|
+
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
25087
|
...e,
|
|
25012
25088
|
data: e.dataJson ? JSON.parse(e.dataJson) : {}
|
|
25013
25089
|
}));
|
|
@@ -25018,12 +25094,12 @@ Mx.get("/:taxonomy", async (e) => {
|
|
|
25018
25094
|
} catch (t) {
|
|
25019
25095
|
return console.error("[Taxonomy API] Error fetching terms:", t), e.json({ error: "Failed to fetch taxonomy terms" }, 500);
|
|
25020
25096
|
}
|
|
25021
|
-
}),
|
|
25022
|
-
let t = e.get("db"), n =
|
|
25097
|
+
}), Nx.post("/:taxonomy", async (e) => {
|
|
25098
|
+
let t = e.get("db"), n = Fx(e.req.param("taxonomy")), r = await e.req.json(), i = r.label?.trim();
|
|
25023
25099
|
if (!i) return e.json({ error: "Label is required" }, 400);
|
|
25024
|
-
let a = r.key?.trim() ||
|
|
25100
|
+
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
25101
|
try {
|
|
25026
|
-
if ((await
|
|
25102
|
+
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
25103
|
let r = t.prepare("\n INSERT INTO taxonomy_terms (taxonomy, key, label, parentId, sortOrder, dataJson)\n VALUES (?, ?, ?, ?, ?, ?)\n "), l;
|
|
25028
25104
|
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
25105
|
success: !0,
|
|
@@ -25032,12 +25108,12 @@ Mx.get("/:taxonomy", async (e) => {
|
|
|
25032
25108
|
} catch (t) {
|
|
25033
25109
|
return console.error("[Taxonomy API] Error creating term:", t), e.json({ error: "Failed to create taxonomy term" }, 500);
|
|
25034
25110
|
}
|
|
25035
|
-
}),
|
|
25036
|
-
let t = e.get("db"), n =
|
|
25111
|
+
}), Nx.put("/:taxonomy/:id", async (e) => {
|
|
25112
|
+
let t = e.get("db"), n = Fx(e.req.param("taxonomy")), r = Number(e.req.param("id"));
|
|
25037
25113
|
if (isNaN(r)) return e.json({ error: "Invalid term ID" }, 400);
|
|
25038
25114
|
let i = await e.req.json();
|
|
25039
25115
|
try {
|
|
25040
|
-
let a = await
|
|
25116
|
+
let a = await Ix(t, "SELECT * FROM taxonomy_terms WHERE id = ? AND taxonomy = ?", [r, n]);
|
|
25041
25117
|
if (a.length === 0) return e.json({ error: "Term not found" }, 404);
|
|
25042
25118
|
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
25119
|
if (i.data) {
|
|
@@ -25047,14 +25123,14 @@ Mx.get("/:taxonomy", async (e) => {
|
|
|
25047
25123
|
...i.data
|
|
25048
25124
|
});
|
|
25049
25125
|
}
|
|
25050
|
-
if (c !== o.key && (await
|
|
25126
|
+
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
25127
|
let f = t.prepare("\n UPDATE taxonomy_terms \n SET label = ?, key = ?, parentId = ?, sortOrder = ?, dataJson = ?, updatedAt = CURRENT_TIMESTAMP\n WHERE id = ?\n ");
|
|
25052
25128
|
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
25129
|
} catch (t) {
|
|
25054
25130
|
return console.error("[Taxonomy API] Error updating term:", t), e.json({ error: "Failed to update taxonomy term" }, 500);
|
|
25055
25131
|
}
|
|
25056
|
-
}),
|
|
25057
|
-
let t = e.get("db"), n =
|
|
25132
|
+
}), Nx.delete("/:taxonomy/:id", async (e) => {
|
|
25133
|
+
let t = e.get("db"), n = Fx(e.req.param("taxonomy")), r = Number(e.req.param("id"));
|
|
25058
25134
|
if (isNaN(r)) return e.json({ error: "Invalid term ID" }, 400);
|
|
25059
25135
|
try {
|
|
25060
25136
|
let i = t.prepare("DELETE FROM taxonomy_terms WHERE id = ? AND taxonomy = ?");
|
|
@@ -25065,20 +25141,20 @@ Mx.get("/:taxonomy", async (e) => {
|
|
|
25065
25141
|
});
|
|
25066
25142
|
//#endregion
|
|
25067
25143
|
//#region server/schema/engine.ts
|
|
25068
|
-
var
|
|
25144
|
+
var Lx = null, Rx = null;
|
|
25069
25145
|
if (typeof process < "u" && process?.versions?.node) try {
|
|
25070
25146
|
let e = i(import.meta.url);
|
|
25071
|
-
|
|
25147
|
+
Lx = e("node:fs"), Rx = e("node:path");
|
|
25072
25148
|
} catch {}
|
|
25073
|
-
function
|
|
25149
|
+
function zx(e, t = "") {
|
|
25074
25150
|
let n = e.split(/[\\/]/).pop() || "";
|
|
25075
25151
|
return t && n.endsWith(t) ? n.slice(0, -t.length) : n;
|
|
25076
25152
|
}
|
|
25077
|
-
function
|
|
25153
|
+
function Bx(e) {
|
|
25078
25154
|
let t = e.match(/\.[^.\\/]+$/);
|
|
25079
25155
|
return t ? t[0] : "";
|
|
25080
25156
|
}
|
|
25081
|
-
var
|
|
25157
|
+
var Vx = {
|
|
25082
25158
|
nodes: {},
|
|
25083
25159
|
trees: {},
|
|
25084
25160
|
blocks: {},
|
|
@@ -25088,10 +25164,10 @@ var Bx = {
|
|
|
25088
25164
|
nodeLayouts: {},
|
|
25089
25165
|
blockLayouts: {}
|
|
25090
25166
|
};
|
|
25091
|
-
function
|
|
25167
|
+
function Hx(e) {
|
|
25092
25168
|
return e ? typeof e == "string" ? e.trim() : Array.isArray(e) ? e.includes("*") ? "*" : e : "*" : "*";
|
|
25093
25169
|
}
|
|
25094
|
-
function
|
|
25170
|
+
function Ux(e = {}, t = {}) {
|
|
25095
25171
|
let n = {
|
|
25096
25172
|
...e,
|
|
25097
25173
|
...t,
|
|
@@ -25103,62 +25179,62 @@ function Hx(e = {}, t = {}) {
|
|
|
25103
25179
|
};
|
|
25104
25180
|
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
25181
|
}
|
|
25106
|
-
function
|
|
25182
|
+
function Wx(e) {
|
|
25107
25183
|
if (!e || typeof e != "object") return e;
|
|
25108
|
-
if (Array.isArray(e)) return e.map(
|
|
25184
|
+
if (Array.isArray(e)) return e.map(Wx);
|
|
25109
25185
|
let t = {};
|
|
25110
25186
|
for (let [n, r] of Object.entries(e)) if (n === "<<" || n === "<<:") {
|
|
25111
|
-
let e =
|
|
25187
|
+
let e = Wx(r);
|
|
25112
25188
|
if (typeof e == "object" && e) {
|
|
25113
25189
|
if (Array.isArray(e)) for (let n of e) Object.assign(t, n);
|
|
25114
25190
|
else Object.assign(t, e);
|
|
25115
25191
|
}
|
|
25116
|
-
} else t[n] =
|
|
25192
|
+
} else t[n] = Wx(r);
|
|
25117
25193
|
return t;
|
|
25118
25194
|
}
|
|
25119
|
-
function
|
|
25120
|
-
return e ?
|
|
25195
|
+
function Gx(e, t) {
|
|
25196
|
+
return e ? Wx(n.parseDocument(e, { customTags: [{
|
|
25121
25197
|
tag: "!include",
|
|
25122
25198
|
resolve(e) {
|
|
25123
|
-
let n = (typeof e == "string" ? e : String(e?.strValue || e?.value || "")).trim(), r =
|
|
25199
|
+
let n = (typeof e == "string" ? e : String(e?.strValue || e?.value || "")).trim(), r = zx(n);
|
|
25124
25200
|
if (!r) return n;
|
|
25125
25201
|
if (t && t.fieldSets) {
|
|
25126
25202
|
let e = Object.keys(t.fieldSets).find((e) => e.endsWith("/" + r) || e === r);
|
|
25127
|
-
if (e) return
|
|
25203
|
+
if (e) return Gx(t.fieldSets[e], t);
|
|
25128
25204
|
}
|
|
25129
25205
|
return n;
|
|
25130
25206
|
}
|
|
25131
25207
|
}] }).toJS() || {}) : {};
|
|
25132
25208
|
}
|
|
25133
|
-
function
|
|
25134
|
-
if (!
|
|
25135
|
-
let r =
|
|
25136
|
-
if (t.has(r) || (t.add(r), !
|
|
25137
|
-
let i =
|
|
25138
|
-
return
|
|
25209
|
+
function Kx(e, t = /* @__PURE__ */ new Set()) {
|
|
25210
|
+
if (!Lx || !Rx) return {};
|
|
25211
|
+
let r = Rx.resolve(e);
|
|
25212
|
+
if (t.has(r) || (t.add(r), !Lx.existsSync(r))) return {};
|
|
25213
|
+
let i = Lx.readFileSync(r, "utf-8");
|
|
25214
|
+
return Wx(n.parseDocument(i, { customTags: [{
|
|
25139
25215
|
tag: "!include",
|
|
25140
25216
|
resolve(e) {
|
|
25141
25217
|
let n = (typeof e == "string" ? e : String(e?.strValue || e?.value || "")).trim();
|
|
25142
|
-
return n ?
|
|
25218
|
+
return n ? Kx(Rx.resolve(Rx.dirname(r), n), new Set(t)) : {};
|
|
25143
25219
|
}
|
|
25144
25220
|
}] }).toJS() || {});
|
|
25145
25221
|
}
|
|
25146
|
-
function
|
|
25147
|
-
if (!
|
|
25222
|
+
function qx() {
|
|
25223
|
+
if (!Lx || !Rx || typeof process > "u" || !process?.versions?.node) return null;
|
|
25148
25224
|
try {
|
|
25149
25225
|
let e = process.cwd(), t = "", n = [
|
|
25150
|
-
|
|
25151
|
-
|
|
25152
|
-
|
|
25153
|
-
|
|
25226
|
+
Rx.resolve(e, "content/definitions"),
|
|
25227
|
+
Rx.resolve(e, "content"),
|
|
25228
|
+
Rx.resolve(e, "definitions"),
|
|
25229
|
+
Rx.resolve(e, "kama-worker/content/definitions")
|
|
25154
25230
|
];
|
|
25155
25231
|
try {
|
|
25156
25232
|
if (import.meta.url) {
|
|
25157
|
-
let e =
|
|
25158
|
-
n.push(
|
|
25233
|
+
let e = Rx.dirname(r(import.meta.url));
|
|
25234
|
+
n.push(Rx.resolve(e, "../../content/definitions")), n.push(Rx.resolve(e, "../content/definitions"));
|
|
25159
25235
|
}
|
|
25160
25236
|
} catch {}
|
|
25161
|
-
for (let e of n) if (
|
|
25237
|
+
for (let e of n) if (Lx.existsSync(e)) {
|
|
25162
25238
|
t = e;
|
|
25163
25239
|
break;
|
|
25164
25240
|
}
|
|
@@ -25166,19 +25242,19 @@ function Kx() {
|
|
|
25166
25242
|
let i = (e) => {
|
|
25167
25243
|
let n = "";
|
|
25168
25244
|
for (let r of e) {
|
|
25169
|
-
let e =
|
|
25170
|
-
if (
|
|
25245
|
+
let e = Rx.join(t, r);
|
|
25246
|
+
if (Lx.existsSync(e)) {
|
|
25171
25247
|
n = e;
|
|
25172
25248
|
break;
|
|
25173
25249
|
}
|
|
25174
25250
|
}
|
|
25175
25251
|
if (!n) return {};
|
|
25176
|
-
let r = {}, i =
|
|
25252
|
+
let r = {}, i = Lx.readdirSync(n);
|
|
25177
25253
|
for (let e of i) {
|
|
25178
25254
|
if (!e.endsWith(".yaml") && !e.endsWith(".yml")) continue;
|
|
25179
|
-
let t =
|
|
25255
|
+
let t = Rx.join(n, e), i = zx(e, Bx(e));
|
|
25180
25256
|
try {
|
|
25181
|
-
r[i] =
|
|
25257
|
+
r[i] = Kx(t);
|
|
25182
25258
|
} catch (t) {
|
|
25183
25259
|
console.error(`❌ Error parsing ${e}:`, t.message);
|
|
25184
25260
|
}
|
|
@@ -25207,59 +25283,59 @@ function Kx() {
|
|
|
25207
25283
|
return console.error("❌ Exception inside readLocalFsBundle:", e), null;
|
|
25208
25284
|
}
|
|
25209
25285
|
}
|
|
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
|
-
}
|
|
25286
|
+
var Jx = null, Yx = null;
|
|
25217
25287
|
function Xx(e) {
|
|
25288
|
+
if (!e) Jx = null, Yx = null;
|
|
25289
|
+
else if (Jx && Yx === e) return Jx;
|
|
25290
|
+
let t = Zx(e);
|
|
25291
|
+
return Jx = t, Yx = e, t;
|
|
25292
|
+
}
|
|
25293
|
+
function Zx(e) {
|
|
25218
25294
|
if (e) {
|
|
25219
25295
|
let t = {
|
|
25220
25296
|
nodes: {
|
|
25221
25297
|
...e.nodes || e.rawNodes || {},
|
|
25222
|
-
...
|
|
25298
|
+
...Vx.nodes
|
|
25223
25299
|
},
|
|
25224
25300
|
trees: {
|
|
25225
25301
|
...e.trees || e.rawTrees || {},
|
|
25226
|
-
...
|
|
25302
|
+
...Vx.trees
|
|
25227
25303
|
},
|
|
25228
25304
|
channels: {
|
|
25229
25305
|
...e.channels || e.rawChannels || {},
|
|
25230
|
-
...
|
|
25306
|
+
...Vx.channels
|
|
25231
25307
|
},
|
|
25232
25308
|
taxonomies: {
|
|
25233
25309
|
...e.taxonomies || e.rawTaxonomies || {},
|
|
25234
|
-
...
|
|
25310
|
+
...Vx.taxonomies
|
|
25235
25311
|
},
|
|
25236
25312
|
blocks: {
|
|
25237
25313
|
...e.blocks || e.rawBlocks || {},
|
|
25238
|
-
...
|
|
25314
|
+
...Vx.blocks
|
|
25239
25315
|
},
|
|
25240
25316
|
nodeLayouts: {
|
|
25241
25317
|
...e.nodeLayouts || e.rawNodeLayouts || {},
|
|
25242
|
-
...
|
|
25318
|
+
...Vx.nodeLayouts
|
|
25243
25319
|
},
|
|
25244
25320
|
blockLayouts: {
|
|
25245
25321
|
...e.blockLayouts || e.rawBlockLayouts || {},
|
|
25246
|
-
...
|
|
25322
|
+
...Vx.blockLayouts
|
|
25247
25323
|
},
|
|
25248
25324
|
fieldSets: {
|
|
25249
25325
|
...e.fieldSets || e.rawFieldSets || {},
|
|
25250
|
-
...
|
|
25326
|
+
...Vx.fieldSets
|
|
25251
25327
|
}
|
|
25252
25328
|
};
|
|
25253
25329
|
if (typeof Object.values(t.nodes)[0] == "string") {
|
|
25254
25330
|
let e = (e) => {
|
|
25255
25331
|
let n = {};
|
|
25256
25332
|
for (let [r, i] of Object.entries(e || {})) {
|
|
25257
|
-
let e =
|
|
25258
|
-
n[e] =
|
|
25333
|
+
let e = zx(r, Bx(r));
|
|
25334
|
+
n[e] = Gx(i, t);
|
|
25259
25335
|
}
|
|
25260
25336
|
return n;
|
|
25261
25337
|
};
|
|
25262
|
-
return
|
|
25338
|
+
return Qx({
|
|
25263
25339
|
rawNodes: e(t.nodes),
|
|
25264
25340
|
rawTrees: e(t.trees),
|
|
25265
25341
|
rawChannels: e(t.channels),
|
|
@@ -25270,12 +25346,12 @@ function Xx(e) {
|
|
|
25270
25346
|
rawFieldSets: e(t.fieldSets)
|
|
25271
25347
|
});
|
|
25272
25348
|
}
|
|
25273
|
-
return
|
|
25349
|
+
return Qx(t);
|
|
25274
25350
|
}
|
|
25275
|
-
let t =
|
|
25276
|
-
return t && Object.keys(t.rawNodes || {}).length > 0 ?
|
|
25351
|
+
let t = qx();
|
|
25352
|
+
return t && Object.keys(t.rawNodes || {}).length > 0 ? Qx(t) : Qx(null);
|
|
25277
25353
|
}
|
|
25278
|
-
function
|
|
25354
|
+
function Qx(e) {
|
|
25279
25355
|
if (!e) return {
|
|
25280
25356
|
nodes: {},
|
|
25281
25357
|
trees: {},
|
|
@@ -25290,7 +25366,7 @@ function Zx(e) {
|
|
|
25290
25366
|
channelTemplate: null,
|
|
25291
25367
|
userTemplate: null
|
|
25292
25368
|
};
|
|
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,
|
|
25369
|
+
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
25370
|
...p,
|
|
25295
25371
|
...f
|
|
25296
25372
|
}, A = (e, t = "settings", n, r) => {
|
|
@@ -25307,11 +25383,11 @@ function Zx(e) {
|
|
|
25307
25383
|
fields: {}
|
|
25308
25384
|
}), Object.entries(s).forEach(([e, r]) => {
|
|
25309
25385
|
let i = n[t].fields[e] || {};
|
|
25310
|
-
n[t].fields[e] =
|
|
25386
|
+
n[t].fields[e] = Ux(i, r);
|
|
25311
25387
|
});
|
|
25312
25388
|
} else Object.entries(s).forEach(([e, t]) => {
|
|
25313
25389
|
let n = i[e] || {};
|
|
25314
|
-
i[e] =
|
|
25390
|
+
i[e] = Ux(n, t);
|
|
25315
25391
|
});
|
|
25316
25392
|
};
|
|
25317
25393
|
return !Array.isArray(e) && typeof e == "object" && e ? (Object.entries(e).forEach(([e, t]) => {
|
|
@@ -25320,15 +25396,15 @@ function Zx(e) {
|
|
|
25320
25396
|
a(String(t));
|
|
25321
25397
|
return;
|
|
25322
25398
|
}
|
|
25323
|
-
let n = i[e] ||
|
|
25324
|
-
i[e] =
|
|
25399
|
+
let n = i[e] || O[e] || {};
|
|
25400
|
+
i[e] = Ux(n, typeof t == "object" && t ? t : { label: String(t) });
|
|
25325
25401
|
}), i) : (Array.isArray(e) && e.forEach((e) => {
|
|
25326
25402
|
if (typeof e == "string") {
|
|
25327
25403
|
if (e.includes("/") || e.endsWith(".yaml") || e.endsWith(".yml")) return;
|
|
25328
25404
|
if (e.startsWith("fieldSet:")) a(e.replace("fieldSet:", "").trim());
|
|
25329
25405
|
else {
|
|
25330
|
-
let t = i[e] ||
|
|
25331
|
-
i[e] =
|
|
25406
|
+
let t = i[e] || O[e] || {};
|
|
25407
|
+
i[e] = Ux(t, {
|
|
25332
25408
|
type: "text",
|
|
25333
25409
|
label: e
|
|
25334
25410
|
});
|
|
@@ -25336,8 +25412,8 @@ function Zx(e) {
|
|
|
25336
25412
|
} else typeof e == "object" && e && Object.entries(e).forEach(([e, t]) => {
|
|
25337
25413
|
if (e === "fieldSet") a(String(t));
|
|
25338
25414
|
else if (e !== "<<" && e !== "<<:") {
|
|
25339
|
-
let n = i[e] ||
|
|
25340
|
-
i[e] =
|
|
25415
|
+
let n = i[e] || O[e] || {};
|
|
25416
|
+
i[e] = Ux(n, typeof t == "object" && t ? t : {});
|
|
25341
25417
|
}
|
|
25342
25418
|
});
|
|
25343
25419
|
}), i);
|
|
@@ -25355,7 +25431,7 @@ function Zx(e) {
|
|
|
25355
25431
|
let s = A(i.fields || i, a, n, t);
|
|
25356
25432
|
Object.entries(s).forEach(([e, t]) => {
|
|
25357
25433
|
let r = n[a].fields[e] || {};
|
|
25358
|
-
n[a].fields[e] =
|
|
25434
|
+
n[a].fields[e] = Ux(r, t);
|
|
25359
25435
|
});
|
|
25360
25436
|
}
|
|
25361
25437
|
}), n) : (Object.entries(e).forEach(([e, r]) => {
|
|
@@ -25371,7 +25447,7 @@ function Zx(e) {
|
|
|
25371
25447
|
Object.entries(s).forEach(([t, r]) => {
|
|
25372
25448
|
if (t === "<<" || t === "<<:" || t === "label") return;
|
|
25373
25449
|
let i = n[e].fields[t] || {};
|
|
25374
|
-
n[e].fields[t] =
|
|
25450
|
+
n[e].fields[t] = Ux(i, r);
|
|
25375
25451
|
});
|
|
25376
25452
|
}), n);
|
|
25377
25453
|
}, j = {};
|
|
@@ -25389,16 +25465,16 @@ function Zx(e) {
|
|
|
25389
25465
|
fields: {}
|
|
25390
25466
|
}), Object.entries(o).forEach(([e, r]) => {
|
|
25391
25467
|
let i = n[t].fields[e] || {};
|
|
25392
|
-
n[t].fields[e] =
|
|
25468
|
+
n[t].fields[e] = Ux(i, r);
|
|
25393
25469
|
});
|
|
25394
25470
|
} else Object.entries(o).forEach(([e, t]) => {
|
|
25395
|
-
let n = r[e] ||
|
|
25396
|
-
r[e] =
|
|
25471
|
+
let n = r[e] || O[e] || {};
|
|
25472
|
+
r[e] = Ux(n, t);
|
|
25397
25473
|
});
|
|
25398
25474
|
}), Object.values(n).forEach((e) => {
|
|
25399
25475
|
Object.entries(e.fields).forEach(([e, t]) => {
|
|
25400
25476
|
let n = r[e] || {};
|
|
25401
|
-
r[e] =
|
|
25477
|
+
r[e] = Ux(n, t);
|
|
25402
25478
|
});
|
|
25403
25479
|
}), Object.keys(n).length === 0 && Object.keys(r).length > 0 && (n.settings = {
|
|
25404
25480
|
label: t.label || "Settings",
|
|
@@ -25411,8 +25487,8 @@ function Zx(e) {
|
|
|
25411
25487
|
inVault: t.inVault !== !1,
|
|
25412
25488
|
hasCanvas: t.hasCanvas === !0,
|
|
25413
25489
|
defaultLayout: t.defaultLayout,
|
|
25414
|
-
allowedBlocks:
|
|
25415
|
-
disallowedBlocks: t.disallowedBlocks ?
|
|
25490
|
+
allowedBlocks: Hx(t.allowedBlocks),
|
|
25491
|
+
disallowedBlocks: t.disallowedBlocks ? Hx(t.disallowedBlocks) : void 0,
|
|
25416
25492
|
tabs: n,
|
|
25417
25493
|
fields: r
|
|
25418
25494
|
};
|
|
@@ -25423,11 +25499,11 @@ function Zx(e) {
|
|
|
25423
25499
|
Array.isArray(t.fieldSets) && t.fieldSets.forEach((e) => {
|
|
25424
25500
|
let t = k[e] || {}, i = t.fields || t, a = A(i, "settings", n);
|
|
25425
25501
|
Object.entries(a).forEach(([e, t]) => {
|
|
25426
|
-
r[e] =
|
|
25502
|
+
r[e] = Ux(r[e] || {}, t);
|
|
25427
25503
|
});
|
|
25428
25504
|
}), Object.values(n).forEach((e) => {
|
|
25429
25505
|
Object.entries(e.fields).forEach(([e, t]) => {
|
|
25430
|
-
r[e] =
|
|
25506
|
+
r[e] = Ux(r[e] || {}, t);
|
|
25431
25507
|
});
|
|
25432
25508
|
}), re[e] = {
|
|
25433
25509
|
...t,
|
|
@@ -25443,11 +25519,11 @@ function Zx(e) {
|
|
|
25443
25519
|
Array.isArray(t.fieldSets) && t.fieldSets.forEach((e) => {
|
|
25444
25520
|
let t = k[e] || {}, n = t.fields || t, i = A(n);
|
|
25445
25521
|
Object.entries(i).forEach(([e, t]) => {
|
|
25446
|
-
r[e] =
|
|
25522
|
+
r[e] = Ux(r[e] || {}, t);
|
|
25447
25523
|
});
|
|
25448
25524
|
}), Object.values(n).forEach((e) => {
|
|
25449
25525
|
Object.entries(e.fields).forEach(([e, t]) => {
|
|
25450
|
-
r[e] =
|
|
25526
|
+
r[e] = Ux(r[e] || {}, t);
|
|
25451
25527
|
});
|
|
25452
25528
|
}), ie[e] = {
|
|
25453
25529
|
...t,
|
|
@@ -25464,11 +25540,11 @@ function Zx(e) {
|
|
|
25464
25540
|
Array.isArray(t.fieldSets) && t.fieldSets.forEach((e) => {
|
|
25465
25541
|
let t = k[e] || {}, i = t.fields || t, a = A(i, "settings", n);
|
|
25466
25542
|
Object.entries(a).forEach(([e, t]) => {
|
|
25467
|
-
r[e] =
|
|
25543
|
+
r[e] = Ux(r[e] || {}, t);
|
|
25468
25544
|
});
|
|
25469
25545
|
}), Object.values(n).forEach((e) => {
|
|
25470
25546
|
Object.entries(e.fields).forEach(([e, t]) => {
|
|
25471
|
-
r[e] =
|
|
25547
|
+
r[e] = Ux(r[e] || {}, t);
|
|
25472
25548
|
});
|
|
25473
25549
|
}), ae[e] = {
|
|
25474
25550
|
...t,
|
|
@@ -25485,7 +25561,7 @@ function Zx(e) {
|
|
|
25485
25561
|
Array.isArray(t.fieldSets) && t.fieldSets.forEach((e) => {
|
|
25486
25562
|
let t = k[e] || {}, r = t.fields || t, i = A(r);
|
|
25487
25563
|
Object.entries(i).forEach(([e, t]) => {
|
|
25488
|
-
n[e] =
|
|
25564
|
+
n[e] = Ux(n[e] || {}, t);
|
|
25489
25565
|
});
|
|
25490
25566
|
}), oe[e] = {
|
|
25491
25567
|
...t,
|
|
@@ -25502,8 +25578,8 @@ function Zx(e) {
|
|
|
25502
25578
|
i[e] = {
|
|
25503
25579
|
...t,
|
|
25504
25580
|
label: t.label || e,
|
|
25505
|
-
allowedBlocks:
|
|
25506
|
-
disallowedBlocks: t.disallowedBlocks ?
|
|
25581
|
+
allowedBlocks: Hx(t.allowedBlocks),
|
|
25582
|
+
disallowedBlocks: t.disallowedBlocks ? Hx(t.disallowedBlocks) : void 0
|
|
25507
25583
|
};
|
|
25508
25584
|
}), se[e] = {
|
|
25509
25585
|
...t,
|
|
@@ -25519,14 +25595,14 @@ function Zx(e) {
|
|
|
25519
25595
|
};
|
|
25520
25596
|
});
|
|
25521
25597
|
let ce = {};
|
|
25522
|
-
Object.entries(
|
|
25598
|
+
Object.entries(te).forEach(([e, t]) => {
|
|
25523
25599
|
let n = ne(t.tabs), r = A(t.fields || [], "settings", n), i = {}, a = t.regions || { main: { label: "Main Content" } };
|
|
25524
25600
|
Object.entries(a).forEach(([e, t]) => {
|
|
25525
25601
|
i[e] = {
|
|
25526
25602
|
...t,
|
|
25527
25603
|
label: t.label || e,
|
|
25528
|
-
allowedBlocks:
|
|
25529
|
-
disallowedBlocks: t.disallowedBlocks ?
|
|
25604
|
+
allowedBlocks: Hx(t.allowedBlocks),
|
|
25605
|
+
disallowedBlocks: t.disallowedBlocks ? Hx(t.disallowedBlocks) : void 0
|
|
25530
25606
|
};
|
|
25531
25607
|
}), ce[e] = {
|
|
25532
25608
|
...t,
|
|
@@ -25545,7 +25621,7 @@ function Zx(e) {
|
|
|
25545
25621
|
Array.isArray(g?.fieldSets) && g?.fieldSets.forEach((e) => {
|
|
25546
25622
|
let t = k[e] || {}, n = t.fields || t, r = A(n);
|
|
25547
25623
|
Object.entries(r).forEach(([e, t]) => {
|
|
25548
|
-
le[e] =
|
|
25624
|
+
le[e] = Ux(le[e] || {}, t);
|
|
25549
25625
|
});
|
|
25550
25626
|
});
|
|
25551
25627
|
let ue = g ? {
|
|
@@ -25555,7 +25631,7 @@ function Zx(e) {
|
|
|
25555
25631
|
Array.isArray(_?.fieldSets) && _?.fieldSets.forEach((e) => {
|
|
25556
25632
|
let t = k[e] || {}, n = t.fields || t, r = A(n);
|
|
25557
25633
|
Object.entries(r).forEach(([e, t]) => {
|
|
25558
|
-
de[e] =
|
|
25634
|
+
de[e] = Ux(de[e] || {}, t);
|
|
25559
25635
|
});
|
|
25560
25636
|
});
|
|
25561
25637
|
let fe = _ ? {
|
|
@@ -25579,11 +25655,11 @@ function Zx(e) {
|
|
|
25579
25655
|
}
|
|
25580
25656
|
//#endregion
|
|
25581
25657
|
//#region server/routes/admin/schemas.ts
|
|
25582
|
-
var
|
|
25658
|
+
var $x = new e(), eS = (e) => {
|
|
25583
25659
|
try {
|
|
25584
25660
|
let t = e.env?.BUNDLED_DEFINITIONS;
|
|
25585
25661
|
(!t || Object.keys(t).length === 0) && (t = Db || Eb || Tb);
|
|
25586
|
-
let n =
|
|
25662
|
+
let n = Xx(t);
|
|
25587
25663
|
return e.json(n, 200, { "Cache-Control": "no-cache, no-store, must-revalidate" });
|
|
25588
25664
|
} catch (t) {
|
|
25589
25665
|
return console.error("[CMS API] Error loading schemas:", t), e.json({
|
|
@@ -25592,10 +25668,10 @@ var Qx = new e(), $x = (e) => {
|
|
|
25592
25668
|
}, 500);
|
|
25593
25669
|
}
|
|
25594
25670
|
};
|
|
25595
|
-
|
|
25671
|
+
$x.get("/", eS), $x.get("/schemas.json", eS);
|
|
25596
25672
|
//#endregion
|
|
25597
25673
|
//#region server/routes/admin/validation.ts
|
|
25598
|
-
var
|
|
25674
|
+
var tS = new e(), nS = {
|
|
25599
25675
|
node: "content_nodes",
|
|
25600
25676
|
nodes: "content_nodes",
|
|
25601
25677
|
content_node: "content_nodes",
|
|
@@ -25607,7 +25683,7 @@ var eS = new e(), tS = {
|
|
|
25607
25683
|
user: "users",
|
|
25608
25684
|
users: "users",
|
|
25609
25685
|
user_account: "user_accounts"
|
|
25610
|
-
},
|
|
25686
|
+
}, rS = {
|
|
25611
25687
|
content_nodes: [
|
|
25612
25688
|
"id",
|
|
25613
25689
|
"title",
|
|
@@ -25664,11 +25740,11 @@ var eS = new e(), tS = {
|
|
|
25664
25740
|
"createdAt"
|
|
25665
25741
|
]
|
|
25666
25742
|
};
|
|
25667
|
-
|
|
25743
|
+
tS.post("/validate-unique", async (e) => {
|
|
25668
25744
|
try {
|
|
25669
25745
|
let t = e.get("db"), { entityType: n, field: r, value: i, excludeId: a } = await e.req.json();
|
|
25670
25746
|
if (!r || i == null || String(i).trim() === "") return e.json({ isUnique: !0 });
|
|
25671
|
-
let o =
|
|
25747
|
+
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
25748
|
if (a != null && String(a).trim() !== "") {
|
|
25673
25749
|
let e = Number(a);
|
|
25674
25750
|
l = isNaN(e) ? String(a) : e;
|
|
@@ -25680,16 +25756,16 @@ eS.post("/validate-unique", async (e) => {
|
|
|
25680
25756
|
} catch (t) {
|
|
25681
25757
|
return console.error("[API Validation] Error validating global uniqueness:", t), e.json({ error: "Failed to validate uniqueness" }, 500);
|
|
25682
25758
|
}
|
|
25683
|
-
}),
|
|
25759
|
+
}), tS.post("/validate-unique-sibling", async (e) => e.json({ isUnique: !0 }));
|
|
25684
25760
|
//#endregion
|
|
25685
25761
|
//#region server/routes/admin/stats.ts
|
|
25686
|
-
var
|
|
25687
|
-
|
|
25762
|
+
var iS = new e();
|
|
25763
|
+
iS.get("/", async (e) => {
|
|
25688
25764
|
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
|
|
25765
|
+
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
25766
|
...e,
|
|
25691
25767
|
isHidden: !!e.isHidden
|
|
25692
|
-
})), d = await t.prepare("\n
|
|
25768
|
+
})), 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
25769
|
id: e.id,
|
|
25694
25770
|
title: e.title,
|
|
25695
25771
|
slug: e.slug,
|
|
@@ -25729,8 +25805,8 @@ rS.get("/", async (e) => {
|
|
|
25729
25805
|
});
|
|
25730
25806
|
//#endregion
|
|
25731
25807
|
//#region server/routes/admin/assets.ts
|
|
25732
|
-
var
|
|
25733
|
-
async function
|
|
25808
|
+
var aS = new e();
|
|
25809
|
+
async function oS(e, t, n = []) {
|
|
25734
25810
|
let r = e.prepare(t);
|
|
25735
25811
|
if (typeof r.bind == "function") {
|
|
25736
25812
|
let e = await r.bind(...n).all();
|
|
@@ -25742,16 +25818,16 @@ async function aS(e, t, n = []) {
|
|
|
25742
25818
|
}
|
|
25743
25819
|
return [];
|
|
25744
25820
|
}
|
|
25745
|
-
async function
|
|
25821
|
+
async function sS(e, t, n = []) {
|
|
25746
25822
|
let r = e.prepare(t);
|
|
25747
25823
|
if (typeof r.bind == "function") return await r.bind(...n).run();
|
|
25748
25824
|
if (typeof r.run == "function") return await r.run(...n);
|
|
25749
25825
|
}
|
|
25750
|
-
function
|
|
25826
|
+
function cS(e, t, n) {
|
|
25751
25827
|
let r = e || (t ? `/media/${t}` : "");
|
|
25752
25828
|
return r && n && r.startsWith(`https://${n}/`) && !r.includes("/media/") && (r = r.replace(`https://${n}/`, `https://${n}/media/`)), r;
|
|
25753
25829
|
}
|
|
25754
|
-
|
|
25830
|
+
aS.get("/", async (e) => {
|
|
25755
25831
|
try {
|
|
25756
25832
|
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
25833
|
createdAt: "a.createdAt",
|
|
@@ -25761,7 +25837,7 @@ iS.get("/", async (e) => {
|
|
|
25761
25837
|
sizeBytes: "a.sizeBytes"
|
|
25762
25838
|
}[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
25839
|
if (c) {
|
|
25764
|
-
let e = await
|
|
25840
|
+
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
25841
|
if (e.length === 0) _.push("1 = 0");
|
|
25766
25842
|
else {
|
|
25767
25843
|
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 +25851,10 @@ iS.get("/", async (e) => {
|
|
|
25775
25851
|
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
25852
|
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
25853
|
g.push(f, p);
|
|
25778
|
-
let y = await
|
|
25854
|
+
let y = await oS(t, v, g), b = y.map((e) => e.id), x = /* @__PURE__ */ new Map(), S = /* @__PURE__ */ new Map();
|
|
25779
25855
|
if (b.length > 0) {
|
|
25780
25856
|
let e = b.map(() => "?").join(",");
|
|
25781
|
-
(await
|
|
25857
|
+
(await oS(t, `
|
|
25782
25858
|
SELECT master.id AS assetId, COUNT(DISTINCT na.nodeId) AS count
|
|
25783
25859
|
FROM assets master
|
|
25784
25860
|
INNER JOIN node_assets na ON (
|
|
@@ -25786,7 +25862,7 @@ iS.get("/", async (e) => {
|
|
|
25786
25862
|
EXISTS (SELECT 1 FROM assets crop WHERE crop.id = na.assetId AND crop.isSystemVariant = 1 AND crop.parentAssetId = master.id)
|
|
25787
25863
|
)
|
|
25788
25864
|
WHERE master.id IN (${e})
|
|
25789
|
-
GROUP BY master.id`, b)).forEach((e) => x.set(String(e.assetId), e.count || 0)), (await
|
|
25865
|
+
GROUP BY master.id`, b)).forEach((e) => x.set(String(e.assetId), e.count || 0)), (await oS(t, `
|
|
25790
25866
|
SELECT parentAssetId, COUNT(id) AS count
|
|
25791
25867
|
FROM assets
|
|
25792
25868
|
WHERE isSystemVariant = 1 AND parentAssetId IN (${e})
|
|
@@ -25804,7 +25880,7 @@ iS.get("/", async (e) => {
|
|
|
25804
25880
|
...JSON.parse(t.dataJson || "{}")
|
|
25805
25881
|
};
|
|
25806
25882
|
} catch {}
|
|
25807
|
-
let r =
|
|
25883
|
+
let r = cS(t.cdnUrl, t.storageKeyPrivate, e.env?.CDN_DOMAIN);
|
|
25808
25884
|
return {
|
|
25809
25885
|
id: t.id,
|
|
25810
25886
|
filename: t.filename || "Untitled Asset",
|
|
@@ -25829,7 +25905,7 @@ iS.get("/", async (e) => {
|
|
|
25829
25905
|
details: t.message || String(t)
|
|
25830
25906
|
}, 500);
|
|
25831
25907
|
}
|
|
25832
|
-
}),
|
|
25908
|
+
}), aS.post("/upload", async (e) => {
|
|
25833
25909
|
try {
|
|
25834
25910
|
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
25911
|
if (!i || !(i instanceof File)) return e.json({ error: "No file uploaded" }, 400);
|
|
@@ -25845,13 +25921,13 @@ iS.get("/", async (e) => {
|
|
|
25845
25921
|
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
25922
|
if (!v) throw Error("Storage provider failed to return a valid storage key");
|
|
25847
25923
|
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
|
|
25924
|
+
T && (await oS(t, "SELECT id FROM users WHERE id = ?", [T])).length === 0 && (T = null);
|
|
25849
25925
|
let ee = new mx(e.env);
|
|
25850
25926
|
if (s) {
|
|
25851
|
-
let r = await
|
|
25927
|
+
let r = await oS(t, "SELECT storageKeyPrivate, isSystemVariant, parentAssetId FROM assets WHERE id = ?", [s]);
|
|
25852
25928
|
if (r.length > 0) {
|
|
25853
25929
|
let a = r[0];
|
|
25854
|
-
if (await
|
|
25930
|
+
if (await sS(t, "UPDATE assets SET filename = ?, mimeType = ?, sizeBytes = ?, storageKeyPrivate = ?, cdnUrl = ?, updatedAt = CURRENT_TIMESTAMP WHERE id = ?", [
|
|
25855
25931
|
i.name,
|
|
25856
25932
|
S,
|
|
25857
25933
|
C,
|
|
@@ -25880,7 +25956,7 @@ iS.get("/", async (e) => {
|
|
|
25880
25956
|
}
|
|
25881
25957
|
}
|
|
25882
25958
|
let E = `ast_${p}`, D = +!!h;
|
|
25883
|
-
await
|
|
25959
|
+
await sS(t, "INSERT INTO assets (id, filename, mimeType, sizeBytes, storageKeyPrivate, cdnUrl, createdById, isSystemVariant, parentAssetId, cropCoordinatesJson) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", [
|
|
25884
25960
|
E,
|
|
25885
25961
|
i.name,
|
|
25886
25962
|
S,
|
|
@@ -25892,15 +25968,15 @@ iS.get("/", async (e) => {
|
|
|
25892
25968
|
l,
|
|
25893
25969
|
d
|
|
25894
25970
|
]);
|
|
25895
|
-
let
|
|
25971
|
+
let te = x;
|
|
25896
25972
|
if (l) {
|
|
25897
|
-
let n = await
|
|
25898
|
-
n.length > 0 && (
|
|
25973
|
+
let n = await oS(t, "SELECT cdnUrl, storageKeyPrivate FROM assets WHERE id = ?", [l]);
|
|
25974
|
+
n.length > 0 && (te = cS(n[0].cdnUrl, n[0].storageKeyPrivate, y)), ee.purgeAsset(e, t, l);
|
|
25899
25975
|
}
|
|
25900
25976
|
return e.json({
|
|
25901
25977
|
id: E,
|
|
25902
25978
|
url: x,
|
|
25903
|
-
originalUrl:
|
|
25979
|
+
originalUrl: te,
|
|
25904
25980
|
parentAssetId: l,
|
|
25905
25981
|
cropCoordinates: f,
|
|
25906
25982
|
filename: i.name,
|
|
@@ -25914,11 +25990,11 @@ iS.get("/", async (e) => {
|
|
|
25914
25990
|
details: t.message || String(t)
|
|
25915
25991
|
}, 500);
|
|
25916
25992
|
}
|
|
25917
|
-
}),
|
|
25993
|
+
}), aS.get("/:id/details", async (e) => {
|
|
25918
25994
|
try {
|
|
25919
|
-
let t = wb(e), n = e.req.param("id"), r = await
|
|
25995
|
+
let t = wb(e), n = e.req.param("id"), r = await oS(t, "SELECT * FROM assets WHERE id = ?", [n]);
|
|
25920
25996
|
if (!r || r.length === 0) return e.json({ error: "Asset not found" }, 404);
|
|
25921
|
-
let i = r[0], a = await
|
|
25997
|
+
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
25998
|
title: "",
|
|
25923
25999
|
alt: "",
|
|
25924
26000
|
description: ""
|
|
@@ -25929,7 +26005,7 @@ iS.get("/", async (e) => {
|
|
|
25929
26005
|
...JSON.parse(i.dataJson || "{}")
|
|
25930
26006
|
};
|
|
25931
26007
|
} catch {}
|
|
25932
|
-
let c = i.updatedAt ? new Date(i.updatedAt).getTime() : Date.now(), l = `${
|
|
26008
|
+
let c = i.updatedAt ? new Date(i.updatedAt).getTime() : Date.now(), l = `${cS(i.cdnUrl, i.storageKeyPrivate, e.env?.CDN_DOMAIN)}?v=${c}`;
|
|
25933
26009
|
return e.json({
|
|
25934
26010
|
id: i.id,
|
|
25935
26011
|
filename: i.filename,
|
|
@@ -25948,7 +26024,7 @@ iS.get("/", async (e) => {
|
|
|
25948
26024
|
if (t.cropCoordinatesJson) try {
|
|
25949
26025
|
n = JSON.parse(t.cropCoordinatesJson);
|
|
25950
26026
|
} catch {}
|
|
25951
|
-
let r = t.updatedAt ? new Date(t.updatedAt).getTime() : c, a =
|
|
26027
|
+
let r = t.updatedAt ? new Date(t.updatedAt).getTime() : c, a = cS(t.cdnUrl, t.storageKeyPrivate, e.env?.CDN_DOMAIN);
|
|
25952
26028
|
return {
|
|
25953
26029
|
id: t.id,
|
|
25954
26030
|
filename: t.filename,
|
|
@@ -25965,15 +26041,15 @@ iS.get("/", async (e) => {
|
|
|
25965
26041
|
} catch {
|
|
25966
26042
|
return e.json({ error: "Failed to load details" }, 500);
|
|
25967
26043
|
}
|
|
25968
|
-
}),
|
|
26044
|
+
}), aS.put("/:id", async (e) => {
|
|
25969
26045
|
try {
|
|
25970
|
-
let t = wb(e), n = e.req.param("id"), r = await e.req.json(), i = await
|
|
26046
|
+
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
26047
|
if (!i || i.length === 0) return e.json({ error: "Asset not found" }, 404);
|
|
25972
26048
|
let a = i[0], o = {};
|
|
25973
26049
|
try {
|
|
25974
26050
|
o = JSON.parse(a.dataJson || "{}");
|
|
25975
26051
|
} 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
|
|
26052
|
+
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
26053
|
r.filename === void 0 ? a.filename : r.filename,
|
|
25978
26054
|
JSON.stringify(o),
|
|
25979
26055
|
n
|
|
@@ -25981,10 +26057,10 @@ iS.get("/", async (e) => {
|
|
|
25981
26057
|
} catch {
|
|
25982
26058
|
return e.json({ error: "Failed to update asset" }, 500);
|
|
25983
26059
|
}
|
|
25984
|
-
}),
|
|
26060
|
+
}), aS.delete("/:id", async (e) => {
|
|
25985
26061
|
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
|
|
26062
|
+
let t = wb(e), n = e.req.param("id"), r = (await oS(t, "SELECT id, filename, isSystemVariant FROM assets WHERE id = ?", [n]))[0];
|
|
26063
|
+
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
26064
|
success: !0,
|
|
25989
26065
|
id: n,
|
|
25990
26066
|
trashed: !0
|
|
@@ -25995,10 +26071,10 @@ iS.get("/", async (e) => {
|
|
|
25995
26071
|
details: t.message || String(t)
|
|
25996
26072
|
}, 500);
|
|
25997
26073
|
}
|
|
25998
|
-
}),
|
|
26074
|
+
}), aS.post("/restore", async (e) => {
|
|
25999
26075
|
try {
|
|
26000
26076
|
let t = wb(e), n = await e.req.json(), r = n.id || n.assetId;
|
|
26001
|
-
return r ? (await
|
|
26077
|
+
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
26078
|
success: !0,
|
|
26003
26079
|
id: r,
|
|
26004
26080
|
restored: !0
|
|
@@ -26009,13 +26085,13 @@ iS.get("/", async (e) => {
|
|
|
26009
26085
|
details: t.message
|
|
26010
26086
|
}, 500);
|
|
26011
26087
|
}
|
|
26012
|
-
}),
|
|
26088
|
+
}), aS.delete("/purge/:id", async (e) => {
|
|
26013
26089
|
try {
|
|
26014
|
-
let t = wb(e), { storage: n } = ix(e.env), r = e.req.param("id"), i = (await
|
|
26090
|
+
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
26091
|
if (!i) return e.json({ error: "Asset not found" }, 404);
|
|
26016
26092
|
new mx(e.env).purgeAsset(e, t, r);
|
|
26017
26093
|
let a = [i];
|
|
26018
|
-
i.isSystemVariant || (a = [i, ...await
|
|
26094
|
+
i.isSystemVariant || (a = [i, ...await oS(t, "SELECT id, storageKeyPrivate FROM assets WHERE isSystemVariant = 1 AND parentAssetId = ?", [r])]);
|
|
26019
26095
|
let o = a.map((e) => e.id);
|
|
26020
26096
|
if (typeof n.delete == "function") {
|
|
26021
26097
|
for (let e of a) if (e.storageKeyPrivate) try {
|
|
@@ -26025,7 +26101,7 @@ iS.get("/", async (e) => {
|
|
|
26025
26101
|
}
|
|
26026
26102
|
}
|
|
26027
26103
|
let s = o.map(() => "?").join(",");
|
|
26028
|
-
return await
|
|
26104
|
+
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
26105
|
success: !0,
|
|
26030
26106
|
id: r,
|
|
26031
26107
|
purged: !0,
|
|
@@ -26041,8 +26117,8 @@ iS.get("/", async (e) => {
|
|
|
26041
26117
|
});
|
|
26042
26118
|
//#endregion
|
|
26043
26119
|
//#region server/routes/public/node.ts
|
|
26044
|
-
var
|
|
26045
|
-
function
|
|
26120
|
+
var lS = new $y();
|
|
26121
|
+
function uS() {
|
|
26046
26122
|
return {
|
|
26047
26123
|
fullPath: /* @__PURE__ */ new Map(),
|
|
26048
26124
|
treeEdges: /* @__PURE__ */ new Map(),
|
|
@@ -26050,7 +26126,7 @@ function lS() {
|
|
|
26050
26126
|
assetUrls: /* @__PURE__ */ new Map()
|
|
26051
26127
|
};
|
|
26052
26128
|
}
|
|
26053
|
-
function
|
|
26129
|
+
function dS(e, t, n = []) {
|
|
26054
26130
|
let r = Date.now();
|
|
26055
26131
|
if (e && String(e).trim() !== "") {
|
|
26056
26132
|
let t = Date.parse(e);
|
|
@@ -26061,7 +26137,7 @@ function uS(e, t, n = []) {
|
|
|
26061
26137
|
!isNaN(e) && e > r && n.push(e);
|
|
26062
26138
|
}
|
|
26063
26139
|
}
|
|
26064
|
-
function
|
|
26140
|
+
function fS(e, t) {
|
|
26065
26141
|
let n = Date.now();
|
|
26066
26142
|
if (e && String(e).trim() !== "") {
|
|
26067
26143
|
let t = Date.parse(e);
|
|
@@ -26073,13 +26149,15 @@ function dS(e, t) {
|
|
|
26073
26149
|
}
|
|
26074
26150
|
return !0;
|
|
26075
26151
|
}
|
|
26076
|
-
async function
|
|
26152
|
+
async function pS(e, t, n, r, i) {
|
|
26077
26153
|
let a = t.filter((e) => e.componentId === "content-feed" || e.componentId === "article-list" || e.componentId === "nodeList" || e.componentId === "node-list");
|
|
26078
26154
|
await Promise.all(a.map(async (t) => {
|
|
26079
26155
|
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
26156
|
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
|
|
26157
|
+
let f = `FROM content_nodes WHERE contentType IN (${s.map(() => "?").join(",")}) AND isHidden = 0 AND IFNULL(status, 'published') = 'published'`, p = [...s];
|
|
26158
|
+
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));
|
|
26159
|
+
let m = (/* @__PURE__ */ new Date()).toISOString();
|
|
26160
|
+
f += " AND IFNULL(json_extract(dataJson, '$.startShowingAt'), '') <= ?", p.push(m), f += " AND IFNULL(json_extract(dataJson, '$.stopShowingAt'), '9999-12-31') >= ?", p.push(m);
|
|
26083
26161
|
for (let e of [
|
|
26084
26162
|
"authors",
|
|
26085
26163
|
"categories",
|
|
@@ -26099,18 +26177,18 @@ async function fS(e, t, n, r, i) {
|
|
|
26099
26177
|
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
26178
|
}
|
|
26101
26179
|
}
|
|
26102
|
-
let
|
|
26103
|
-
u === "published_desc" || u === "createdAt" ?
|
|
26104
|
-
let
|
|
26180
|
+
let h = "ORDER BY updatedAt DESC";
|
|
26181
|
+
u === "published_desc" || u === "createdAt" ? h = "ORDER BY createdAt DESC" : u === "title_asc" && (h = "ORDER BY LOWER(title) ASC");
|
|
26182
|
+
let g = `SELECT id, title, slug, language, dataJson, createdAt, updatedAt ${f} ${h} LIMIT ? OFFSET ?`;
|
|
26105
26183
|
p.push(c, l);
|
|
26106
26184
|
try {
|
|
26107
|
-
let n = await e.prepare(
|
|
26108
|
-
t.data.initialItems =
|
|
26185
|
+
let n = await e.prepare(g).all(...p), o = Array.isArray(n) ? n : n?.results || [];
|
|
26186
|
+
t.data.initialItems = o.map((e) => {
|
|
26109
26187
|
let t = {};
|
|
26110
26188
|
if (e.dataJson) try {
|
|
26111
26189
|
t = typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson;
|
|
26112
26190
|
} catch {}
|
|
26113
|
-
return i &&
|
|
26191
|
+
return i && dS(t.startShowingAt, t.stopShowingAt, i), {
|
|
26114
26192
|
id: e.id,
|
|
26115
26193
|
title: e.title,
|
|
26116
26194
|
slug: e.slug,
|
|
@@ -26120,14 +26198,14 @@ async function fS(e, t, n, r, i) {
|
|
|
26120
26198
|
excerpt: t.excerpt || "",
|
|
26121
26199
|
image: t.image || t.coverImage || null,
|
|
26122
26200
|
author: t.author || null
|
|
26123
|
-
}
|
|
26124
|
-
})
|
|
26201
|
+
};
|
|
26202
|
+
}), a.disablePagination !== !0 && a.disablePagination !== "1" && o.length === c ? t.data.loadMoreUrl = `/api/v1/nodes?${d.toString()}` : t.data.loadMoreUrl = null;
|
|
26125
26203
|
} catch (e) {
|
|
26126
26204
|
console.error("[CMS Hydration] Failed to hydrate content feed block", e), t.data.initialItems = [], t.data.loadMoreUrl = null;
|
|
26127
26205
|
}
|
|
26128
26206
|
}));
|
|
26129
26207
|
}
|
|
26130
|
-
async function
|
|
26208
|
+
async function mS(e, t, n, r, i, a = !1, o, s) {
|
|
26131
26209
|
if (!t) return { blocks: [] };
|
|
26132
26210
|
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
26211
|
if (!l || l.length === 0) return { blocks: [] };
|
|
@@ -26163,11 +26241,11 @@ async function pS(e, t, n, r, i, a = !1, o, s) {
|
|
|
26163
26241
|
try {
|
|
26164
26242
|
n = (typeof t.dataJson == "string" ? JSON.parse(t.dataJson) : t.dataJson) || {};
|
|
26165
26243
|
} catch {}
|
|
26166
|
-
s &&
|
|
26167
|
-
let o = n.hidden === !0 || n.hidden === 1 || n.hidden === "1" || n.hidden === "true", c =
|
|
26244
|
+
s && dS(n.startShowingAt, n.stopShowingAt, s);
|
|
26245
|
+
let o = n.hidden === !0 || n.hidden === 1 || n.hidden === "1" || n.hidden === "true", c = fS(n.startShowingAt, n.stopShowingAt);
|
|
26168
26246
|
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 =
|
|
26247
|
+
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);
|
|
26248
|
+
return f = await fx(e, f), f = gS(f), f.blockId = d, {
|
|
26171
26249
|
region: t.region || r,
|
|
26172
26250
|
block: {
|
|
26173
26251
|
instanceId: t.id,
|
|
@@ -26187,7 +26265,7 @@ async function pS(e, t, n, r, i, a = !1, o, s) {
|
|
|
26187
26265
|
}
|
|
26188
26266
|
return { blocks: [] };
|
|
26189
26267
|
}
|
|
26190
|
-
function
|
|
26268
|
+
function hS(e, t = {}) {
|
|
26191
26269
|
let n = {};
|
|
26192
26270
|
for (let [r, i] of Object.entries(e)) r.endsWith("_meta") || [
|
|
26193
26271
|
"disabledRegions",
|
|
@@ -26203,14 +26281,14 @@ function mS(e, t = {}) {
|
|
|
26203
26281
|
].includes(r) || r.startsWith("_") || (!t[r] || t[r].public !== !1) && (n[r] = i);
|
|
26204
26282
|
return n;
|
|
26205
26283
|
}
|
|
26206
|
-
function
|
|
26207
|
-
if (Array.isArray(e)) return e.map(
|
|
26284
|
+
function gS(e) {
|
|
26285
|
+
if (Array.isArray(e)) return e.map(gS);
|
|
26208
26286
|
if (!e || typeof e != "object") return e;
|
|
26209
26287
|
if (typeof e.id == "string" && e.id.startsWith("ast_") && typeof e.url == "string") {
|
|
26210
26288
|
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
26289
|
...t,
|
|
26212
26290
|
...t.crops?.[r] || {}
|
|
26213
|
-
} : t, a = Object.fromEntries(Object.entries(n).filter(([, t]) => t?.id !== e.id).map(([t, n]) => [t,
|
|
26291
|
+
} : t, a = Object.fromEntries(Object.entries(n).filter(([, t]) => t?.id !== e.id).map(([t, n]) => [t, gS({
|
|
26214
26292
|
...n,
|
|
26215
26293
|
title: n?.title ?? e.title ?? "",
|
|
26216
26294
|
alt: n?.alt ?? e.alt ?? "",
|
|
@@ -26224,9 +26302,9 @@ function hS(e) {
|
|
|
26224
26302
|
...Object.keys(a).length > 0 ? { variants: a } : {}
|
|
26225
26303
|
};
|
|
26226
26304
|
}
|
|
26227
|
-
return Object.fromEntries(Object.entries(e).map(([e, t]) => [e,
|
|
26305
|
+
return Object.fromEntries(Object.entries(e).map(([e, t]) => [e, gS(t)]));
|
|
26228
26306
|
}
|
|
26229
|
-
async function
|
|
26307
|
+
async function _S(e, t, n, r) {
|
|
26230
26308
|
if (typeof t == "string") {
|
|
26231
26309
|
if (!t.includes("#node:") && !t.includes("data-node-id") && !t.includes("#asset:") && !t.includes("data-asset-id")) return t;
|
|
26232
26310
|
let r = (e, t) => {
|
|
@@ -26259,25 +26337,25 @@ async function gS(e, t, n, r) {
|
|
|
26259
26337
|
return /href\s*=\s*["'][^"']*["']/i.test(d) ? d = d.replace(/href\s*=\s*["'][^"']*["']/i, `href="${u}"`) : d += ` href="${u}"`, `<a ${d}>`;
|
|
26260
26338
|
});
|
|
26261
26339
|
}
|
|
26262
|
-
if (Array.isArray(t)) return Promise.all(t.map((t) =>
|
|
26340
|
+
if (Array.isArray(t)) return Promise.all(t.map((t) => _S(e, t, n, r)));
|
|
26263
26341
|
if (t && typeof t == "object") {
|
|
26264
26342
|
if (typeof t.href == "string" && (t.href.startsWith("#node:") || t.href.startsWith("#asset:"))) return {
|
|
26265
26343
|
...t,
|
|
26266
|
-
href: await
|
|
26344
|
+
href: await vS(e, t, n, r)
|
|
26267
26345
|
};
|
|
26268
|
-
let i = await Promise.all(Object.entries(t).map(async ([t, i]) => [t, await
|
|
26346
|
+
let i = await Promise.all(Object.entries(t).map(async ([t, i]) => [t, await _S(e, i, n, r)]));
|
|
26269
26347
|
return Object.fromEntries(i);
|
|
26270
26348
|
}
|
|
26271
26349
|
return t;
|
|
26272
26350
|
}
|
|
26273
|
-
async function
|
|
26351
|
+
async function vS(e, t, n, r) {
|
|
26274
26352
|
let i = t.href.match(/^#node:(.+)$/), a = t.href.match(/^#asset:(.+)$/);
|
|
26275
|
-
if (a) return
|
|
26353
|
+
if (a) return yS(e, a[1], r);
|
|
26276
26354
|
if (!i) return t.href;
|
|
26277
26355
|
let o = i[1];
|
|
26278
26356
|
return (await e.prepare("SELECT path FROM node_routes WHERE nodeId = ? AND channelId = ? AND isCanonical = 1 LIMIT 1").get(Number(o), n))?.path || "#";
|
|
26279
26357
|
}
|
|
26280
|
-
async function
|
|
26358
|
+
async function yS(e, t, n) {
|
|
26281
26359
|
let r = String(t), i = n.assetUrls.get(r);
|
|
26282
26360
|
if (i) return i;
|
|
26283
26361
|
let a = (async () => {
|
|
@@ -26286,7 +26364,7 @@ async function vS(e, t, n) {
|
|
|
26286
26364
|
})();
|
|
26287
26365
|
return n.assetUrls.set(r, a), a;
|
|
26288
26366
|
}
|
|
26289
|
-
function
|
|
26367
|
+
function bS(e) {
|
|
26290
26368
|
let t = e.socialImage;
|
|
26291
26369
|
if (!t || typeof t != "object") return null;
|
|
26292
26370
|
let n = (e, t) => {
|
|
@@ -26317,7 +26395,7 @@ function yS(e) {
|
|
|
26317
26395
|
])
|
|
26318
26396
|
};
|
|
26319
26397
|
}
|
|
26320
|
-
async function
|
|
26398
|
+
async function xS(e, t, n, r, i) {
|
|
26321
26399
|
let a = {}, o = null;
|
|
26322
26400
|
if (t) {
|
|
26323
26401
|
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 +26433,20 @@ async function bS(e, t, n, r, i) {
|
|
|
26355
26433
|
inheritedFields: a
|
|
26356
26434
|
};
|
|
26357
26435
|
}
|
|
26358
|
-
function
|
|
26436
|
+
function SS(e) {
|
|
26359
26437
|
let t = Number(e?.env?.CMS_NODE_CACHE_TTL);
|
|
26360
26438
|
return Number.isFinite(t) && t >= 60 ? Math.floor(t) : 300;
|
|
26361
26439
|
}
|
|
26362
|
-
async function
|
|
26440
|
+
async function CS(e, t, n, r) {
|
|
26363
26441
|
try {
|
|
26364
26442
|
await e.set(t, n, r);
|
|
26365
26443
|
} catch (e) {
|
|
26366
26444
|
console.warn("[CMS Cache] Failed to write node response to cache:", e);
|
|
26367
26445
|
}
|
|
26368
26446
|
}
|
|
26369
|
-
async function
|
|
26447
|
+
async function wS(e) {
|
|
26370
26448
|
try {
|
|
26371
|
-
let t = e.get("db"), n =
|
|
26449
|
+
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
26450
|
u.includes("/node/") ? d = u.substring(u.indexOf("/node/") + 6) : u.endsWith("/node") && (d = "");
|
|
26373
26451
|
try {
|
|
26374
26452
|
d = decodeURIComponent(d);
|
|
@@ -26418,9 +26496,9 @@ async function CS(e) {
|
|
|
26418
26496
|
e.defaultLanguage ? w = String(e.defaultLanguage).trim() : e.language && (w = String(e.language).trim());
|
|
26419
26497
|
} catch {}
|
|
26420
26498
|
}
|
|
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
|
|
26499
|
+
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);
|
|
26500
|
+
if (!s && !te) {
|
|
26501
|
+
let t = await O.get(D);
|
|
26424
26502
|
if (t) {
|
|
26425
26503
|
e.header("X-Cache", "HIT");
|
|
26426
26504
|
let n = k;
|
|
@@ -26448,14 +26526,14 @@ async function CS(e) {
|
|
|
26448
26526
|
if (x && x.node && x.node.dataJson && (fe = x.node.dataJson), fe) try {
|
|
26449
26527
|
de = typeof fe == "string" ? JSON.parse(fe) : fe;
|
|
26450
26528
|
} 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
|
|
26529
|
+
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);
|
|
26530
|
+
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
26531
|
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 =
|
|
26532
|
+
let ve = await fx(t, hS(de, oe));
|
|
26533
|
+
ve = gS(ve), ve = await _S(t, ve, g, n), delete ve.language;
|
|
26534
|
+
let ye = bS(ve);
|
|
26457
26535
|
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 = !
|
|
26536
|
+
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
26537
|
if (!s && (be || xe || Se && !Ce)) return e.json({ error: "Node is hidden, offline, or has never been published." }, 404);
|
|
26460
26538
|
let we = [];
|
|
26461
26539
|
if (S?.treeNodeId) {
|
|
@@ -26466,8 +26544,8 @@ async function CS(e) {
|
|
|
26466
26544
|
try {
|
|
26467
26545
|
t = (typeof n == "string" ? JSON.parse(n) : n) || {};
|
|
26468
26546
|
} catch {}
|
|
26469
|
-
let i = Number(e.isHidden) === 1 || t.hidden === !0 || t.hidden === 1 || t.hidden === "1", o =
|
|
26470
|
-
return
|
|
26547
|
+
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, "");
|
|
26548
|
+
return dS(t.startShowingAt, t.stopShowingAt, r), !s && (i || !o) ? null : {
|
|
26471
26549
|
treeNodeId: e.treeNodeId,
|
|
26472
26550
|
id: e.id,
|
|
26473
26551
|
title: e.title,
|
|
@@ -26493,11 +26571,11 @@ async function CS(e) {
|
|
|
26493
26571
|
try {
|
|
26494
26572
|
a = (typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson) || {};
|
|
26495
26573
|
} catch {}
|
|
26496
|
-
|
|
26497
|
-
let o = a.hidden === !0 || a.hidden === 1 || a.hidden === "1" || a.hidden === "true", c =
|
|
26574
|
+
dS(a.startShowingAt, a.stopShowingAt, r);
|
|
26575
|
+
let o = a.hidden === !0 || a.hidden === 1 || a.hidden === "1" || a.hidden === "true", c = fS(a.startShowingAt, a.stopShowingAt);
|
|
26498
26576
|
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 =
|
|
26577
|
+
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);
|
|
26578
|
+
return f = await fx(t, f), f = gS(f), f = await _S(t, f, g, n), f.blockId = d, {
|
|
26501
26579
|
region: i,
|
|
26502
26580
|
block: {
|
|
26503
26581
|
instanceId: e.id,
|
|
@@ -26522,7 +26600,7 @@ async function CS(e) {
|
|
|
26522
26600
|
for (let [e, i] of Object.entries(ke)) {
|
|
26523
26601
|
let a = Ee[e] && Ee[e].length > 0, o = !!se[e];
|
|
26524
26602
|
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
|
|
26603
|
+
let i = await mS(t, A, String(b), e, re, s, n, r);
|
|
26526
26604
|
if (i.blocks.length > 0 && (Ee[e] = i.blocks, De[e] = {
|
|
26527
26605
|
isInherited: !0,
|
|
26528
26606
|
inheritedFromId: i.inheritedFromId,
|
|
@@ -26534,7 +26612,7 @@ async function CS(e) {
|
|
|
26534
26612
|
});
|
|
26535
26613
|
}
|
|
26536
26614
|
}
|
|
26537
|
-
await Promise.all(Object.keys(Ee).map((e) =>
|
|
26615
|
+
await Promise.all(Object.keys(Ee).map((e) => pS(t, Ee[e], g, E, r)));
|
|
26538
26616
|
let Ae = null, je = null;
|
|
26539
26617
|
if (r.length > 0) {
|
|
26540
26618
|
je = Math.min(...r);
|
|
@@ -26553,10 +26631,10 @@ async function CS(e) {
|
|
|
26553
26631
|
content: Ee,
|
|
26554
26632
|
regionMeta: De
|
|
26555
26633
|
};
|
|
26556
|
-
if (!s && !
|
|
26634
|
+
if (!s && !te) {
|
|
26557
26635
|
e.header("X-Cache", "MISS");
|
|
26558
26636
|
let t = Ae === null ? k : Ae;
|
|
26559
|
-
e.header("Cache-Control", `public, max-age=${t}, s-maxage=${t}`), await
|
|
26637
|
+
e.header("Cache-Control", `public, max-age=${t}, s-maxage=${t}`), await CS(O, D, Me, t);
|
|
26560
26638
|
} else e.header("Cache-Control", "no-cache, no-store, must-revalidate");
|
|
26561
26639
|
return e.json(Me, 200);
|
|
26562
26640
|
} catch (t) {
|
|
@@ -26566,17 +26644,17 @@ async function CS(e) {
|
|
|
26566
26644
|
}, 500);
|
|
26567
26645
|
}
|
|
26568
26646
|
}
|
|
26569
|
-
var
|
|
26647
|
+
var TS = X({
|
|
26570
26648
|
channelId: J().optional().openapi({ description: "The ID or key of the channel" }),
|
|
26571
26649
|
channel: J().optional().openapi({ description: "Legacy alias for channelId" }),
|
|
26572
26650
|
lang: J().optional().openapi({ description: "Requested language code" }),
|
|
26573
26651
|
preview: lv(["true", "false"]).optional().openapi({ description: "Request unpublished draft data" }),
|
|
26574
26652
|
revisionId: J().optional().openapi({ description: "Historical revision version to load" }),
|
|
26575
26653
|
treeId: J().optional().openapi({ description: "The ID of the tree to resolve paths against" })
|
|
26576
|
-
}),
|
|
26654
|
+
}), ES = X({
|
|
26577
26655
|
error: J(),
|
|
26578
26656
|
details: J().optional()
|
|
26579
|
-
}).openapi("ErrorResponse"),
|
|
26657
|
+
}).openapi("ErrorResponse"), DS = X({
|
|
26580
26658
|
channelId: G_([J(), c_()]),
|
|
26581
26659
|
treeId: J().nullable(),
|
|
26582
26660
|
language: J().nullable(),
|
|
@@ -26591,7 +26669,7 @@ var wS = X({
|
|
|
26591
26669
|
inheritedFromId: J().optional(),
|
|
26592
26670
|
inheritedFromTitle: J().optional()
|
|
26593
26671
|
}))
|
|
26594
|
-
}).openapi("NodeResponse"),
|
|
26672
|
+
}).openapi("NodeResponse"), OS = eb({
|
|
26595
26673
|
method: "get",
|
|
26596
26674
|
path: "/{path}",
|
|
26597
26675
|
summary: "Fetch CMS Node Content",
|
|
@@ -26599,27 +26677,27 @@ var wS = X({
|
|
|
26599
26677
|
tags: ["Public Node API"],
|
|
26600
26678
|
request: {
|
|
26601
26679
|
params: X({ path: J().optional().openapi({ description: "The full URL path or slug of the requested node" }) }),
|
|
26602
|
-
query:
|
|
26680
|
+
query: TS
|
|
26603
26681
|
},
|
|
26604
26682
|
responses: {
|
|
26605
26683
|
200: {
|
|
26606
26684
|
description: "Fully hydrated CMS Node",
|
|
26607
|
-
content: { "application/json": { schema:
|
|
26685
|
+
content: { "application/json": { schema: DS } }
|
|
26608
26686
|
},
|
|
26609
26687
|
404: {
|
|
26610
26688
|
description: "Node or Channel not found",
|
|
26611
|
-
content: { "application/json": { schema:
|
|
26689
|
+
content: { "application/json": { schema: ES } }
|
|
26612
26690
|
},
|
|
26613
26691
|
500: {
|
|
26614
26692
|
description: "Server error during hydration",
|
|
26615
|
-
content: { "application/json": { schema:
|
|
26693
|
+
content: { "application/json": { schema: ES } }
|
|
26616
26694
|
}
|
|
26617
26695
|
}
|
|
26618
26696
|
});
|
|
26619
|
-
|
|
26697
|
+
lS.openapi(OS, wS), lS.get("*", wS);
|
|
26620
26698
|
//#endregion
|
|
26621
26699
|
//#region server/routes/public/nodes.ts
|
|
26622
|
-
var
|
|
26700
|
+
var kS = new $y(), AS = X({
|
|
26623
26701
|
nodeType: J().default("article").openapi({ description: "Content types (comma separated)" }),
|
|
26624
26702
|
channelId: J().optional().openapi({ description: "Channel ID or key" }),
|
|
26625
26703
|
limit: Ky().min(1).max(50).default(12).openapi({ description: "Number of items (max 50)" }),
|
|
@@ -26632,34 +26710,29 @@ var OS = new $y(), kS = X({
|
|
|
26632
26710
|
authors: G_([J(), z_(J())]).optional(),
|
|
26633
26711
|
categories: G_([J(), z_(J())]).optional(),
|
|
26634
26712
|
tags: G_([J(), z_(J())]).optional()
|
|
26635
|
-
}),
|
|
26713
|
+
}), jS = async (e) => {
|
|
26636
26714
|
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 = (
|
|
26715
|
+
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];
|
|
26716
|
+
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));
|
|
26717
|
+
let s = (/* @__PURE__ */ new Date()).toISOString();
|
|
26718
|
+
a += " AND IFNULL(json_extract(dataJson, '$.startShowingAt'), '') <= ?", o.push(s), a += " AND IFNULL(json_extract(dataJson, '$.stopShowingAt'), '9999-12-31') >= ?", o.push(s);
|
|
26719
|
+
let c = (e, t, n = !1) => {
|
|
26640
26720
|
let r = Array.isArray(t) ? t : t.split(",").map((e) => e.trim());
|
|
26641
26721
|
if (r.length === 0) return;
|
|
26642
26722
|
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));
|
|
26723
|
+
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
26724
|
};
|
|
26652
|
-
n.authors &&
|
|
26653
|
-
let
|
|
26654
|
-
n.sortBy === "createdAt" ?
|
|
26655
|
-
let
|
|
26725
|
+
n.authors && c("authors", n.authors, !0), n.categories && c("categories", n.categories, !1), n.tags && c("tags", n.tags, !1);
|
|
26726
|
+
let l = "ORDER BY updatedAt DESC";
|
|
26727
|
+
n.sortBy === "createdAt" ? l = "ORDER BY createdAt DESC" : n.sortBy === "title_asc" && (l = "ORDER BY LOWER(title) ASC");
|
|
26728
|
+
let u = `SELECT id, title, slug, language, dataJson, createdAt, updatedAt ${a} ${l} LIMIT ? OFFSET ?`;
|
|
26656
26729
|
o.push(n.limit, n.offset);
|
|
26657
|
-
let
|
|
26730
|
+
let d = await t.prepare(u).all(...o), f = Array.isArray(d) ? d : d?.results || [], p = f.map((e) => {
|
|
26658
26731
|
let t = {};
|
|
26659
26732
|
try {
|
|
26660
26733
|
t = typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson || {};
|
|
26661
26734
|
} catch {}
|
|
26662
|
-
return
|
|
26735
|
+
return {
|
|
26663
26736
|
id: e.id,
|
|
26664
26737
|
title: e.title,
|
|
26665
26738
|
slug: e.slug,
|
|
@@ -26670,22 +26743,23 @@ var OS = new $y(), kS = X({
|
|
|
26670
26743
|
image: t.image || t.coverImage || null,
|
|
26671
26744
|
author: t.author || null
|
|
26672
26745
|
};
|
|
26673
|
-
})
|
|
26746
|
+
});
|
|
26674
26747
|
return e.json({
|
|
26675
26748
|
items: p,
|
|
26676
26749
|
count: p.length,
|
|
26750
|
+
rawCount: f.length,
|
|
26677
26751
|
limit: n.limit,
|
|
26678
26752
|
offset: n.offset
|
|
26679
26753
|
}, 200);
|
|
26680
26754
|
} catch (t) {
|
|
26681
26755
|
return console.error("[CMS API] Error fetching nodes list:", t), e.json({ error: "Failed to fetch nodes list" }, 500);
|
|
26682
26756
|
}
|
|
26683
|
-
},
|
|
26757
|
+
}, MS = eb({
|
|
26684
26758
|
method: "get",
|
|
26685
26759
|
path: "/",
|
|
26686
26760
|
summary: "Fetch filtered list of nodes",
|
|
26687
26761
|
tags: ["Public Node API"],
|
|
26688
|
-
request: { query:
|
|
26762
|
+
request: { query: AS },
|
|
26689
26763
|
responses: {
|
|
26690
26764
|
200: {
|
|
26691
26765
|
description: "List of nodes",
|
|
@@ -26694,11 +26768,11 @@ var OS = new $y(), kS = X({
|
|
|
26694
26768
|
500: { description: "Server error" }
|
|
26695
26769
|
}
|
|
26696
26770
|
});
|
|
26697
|
-
|
|
26771
|
+
kS.openapi(MS, jS);
|
|
26698
26772
|
//#endregion
|
|
26699
26773
|
//#region server/routes/public/tree.ts
|
|
26700
|
-
var
|
|
26701
|
-
function
|
|
26774
|
+
var NS = new $y();
|
|
26775
|
+
function PS(e, t) {
|
|
26702
26776
|
let n = /* @__PURE__ */ new Date();
|
|
26703
26777
|
if (e && String(e).trim() !== "") {
|
|
26704
26778
|
let t = new Date(e);
|
|
@@ -26710,22 +26784,22 @@ function NS(e, t) {
|
|
|
26710
26784
|
}
|
|
26711
26785
|
return !0;
|
|
26712
26786
|
}
|
|
26713
|
-
async function
|
|
26787
|
+
async function FS(e, t, n, r) {
|
|
26714
26788
|
try {
|
|
26715
26789
|
await e.set(t, n, r);
|
|
26716
26790
|
} catch (e) {
|
|
26717
26791
|
console.warn("[CMS Cache] Failed to write tree response to cache:", e);
|
|
26718
26792
|
}
|
|
26719
26793
|
}
|
|
26720
|
-
var
|
|
26794
|
+
var IS = X({ treeParam: J().openapi({ description: "The ID or key of the requested tree (e.g., \"main-nav\")" }) }), LS = X({
|
|
26721
26795
|
channelId: J().optional().openapi({ description: "Channel ID to resolve context-aware routing" }),
|
|
26722
26796
|
channel: J().optional().openapi({ description: "Legacy alias for channelId" }),
|
|
26723
26797
|
lang: J().optional().openapi({ description: "Requested language code for tree nodes" }),
|
|
26724
26798
|
preview: lv(["true", "false"]).optional().openapi({ description: "Set to true to retrieve unpublished draft data" })
|
|
26725
|
-
}),
|
|
26799
|
+
}), RS = X({
|
|
26726
26800
|
error: J(),
|
|
26727
26801
|
details: J().optional()
|
|
26728
|
-
}).openapi("ErrorResponse"),
|
|
26802
|
+
}).openapi("ErrorResponse"), zS = qv(() => X({
|
|
26729
26803
|
id: G_([J(), c_()]),
|
|
26730
26804
|
treeNodeId: G_([J(), c_()]),
|
|
26731
26805
|
parentId: G_([J(), c_()]).nullable(),
|
|
@@ -26738,40 +26812,40 @@ var FS = X({ treeParam: J().openapi({ description: "The ID or key of the request
|
|
|
26738
26812
|
summary: J(),
|
|
26739
26813
|
url: J().optional(),
|
|
26740
26814
|
target: J().optional(),
|
|
26741
|
-
children: z_(
|
|
26742
|
-
})).openapi("TreeItem"),
|
|
26815
|
+
children: z_(zS).optional()
|
|
26816
|
+
})).openapi("TreeItem"), BS = X({
|
|
26743
26817
|
treeId: G_([c_(), J()]),
|
|
26744
26818
|
key: J(),
|
|
26745
26819
|
channelId: J(),
|
|
26746
26820
|
language: J().nullable(),
|
|
26747
26821
|
label: J(),
|
|
26748
|
-
items: z_(
|
|
26749
|
-
}).catchall(k_()).openapi("TreeResponse"),
|
|
26822
|
+
items: z_(zS)
|
|
26823
|
+
}).catchall(k_()).openapi("TreeResponse"), VS = eb({
|
|
26750
26824
|
method: "get",
|
|
26751
26825
|
path: "/{treeParam}",
|
|
26752
26826
|
summary: "Fetch CMS Navigation Tree",
|
|
26753
26827
|
description: "Retrieves a fully hydrated, recursive navigation tree structure. Uses $O(1)$ pre-computed routing table paths.",
|
|
26754
26828
|
tags: ["Public Tree API"],
|
|
26755
26829
|
request: {
|
|
26756
|
-
params:
|
|
26757
|
-
query:
|
|
26830
|
+
params: IS,
|
|
26831
|
+
query: LS
|
|
26758
26832
|
},
|
|
26759
26833
|
responses: {
|
|
26760
26834
|
200: {
|
|
26761
26835
|
description: "Fully hydrated CMS Tree payload",
|
|
26762
|
-
content: { "application/json": { schema:
|
|
26836
|
+
content: { "application/json": { schema: BS } }
|
|
26763
26837
|
},
|
|
26764
26838
|
404: {
|
|
26765
26839
|
description: "Tree or Channel not found / inactive",
|
|
26766
|
-
content: { "application/json": { schema:
|
|
26840
|
+
content: { "application/json": { schema: RS } }
|
|
26767
26841
|
},
|
|
26768
26842
|
500: {
|
|
26769
26843
|
description: "Server error during hydration",
|
|
26770
|
-
content: { "application/json": { schema:
|
|
26844
|
+
content: { "application/json": { schema: RS } }
|
|
26771
26845
|
}
|
|
26772
26846
|
}
|
|
26773
26847
|
});
|
|
26774
|
-
|
|
26848
|
+
NS.openapi(VS, async (e) => {
|
|
26775
26849
|
try {
|
|
26776
26850
|
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
26851
|
if (i && i !== "default" && i !== "all") {
|
|
@@ -26806,7 +26880,7 @@ MS.openapi(BS, async (e) => {
|
|
|
26806
26880
|
}
|
|
26807
26881
|
let v = [];
|
|
26808
26882
|
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);
|
|
26883
|
+
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
26884
|
v = Array.isArray(e) ? e : e?.results || [];
|
|
26811
26885
|
}
|
|
26812
26886
|
if ((!v || v.length === 0) && !u) return e.json({ error: `Tree '${n}' not found` }, 404);
|
|
@@ -26834,7 +26908,7 @@ MS.openapi(BS, async (e) => {
|
|
|
26834
26908
|
return (y.get(n) || []).map((e) => {
|
|
26835
26909
|
let n = b.get(String(e.id)) || {}, r = {};
|
|
26836
26910
|
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 =
|
|
26911
|
+
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
26912
|
id: e.id,
|
|
26839
26913
|
treeNodeId: e.id,
|
|
26840
26914
|
parentId: e.parentId || null,
|
|
@@ -26860,7 +26934,7 @@ MS.openapi(BS, async (e) => {
|
|
|
26860
26934
|
..._,
|
|
26861
26935
|
items: x(null)
|
|
26862
26936
|
};
|
|
26863
|
-
return !o && !h && (e.header("X-Cache", "MISS"), await
|
|
26937
|
+
return !o && !h && (e.header("X-Cache", "MISS"), await FS(p, m, S, 300)), e.json(S, 200);
|
|
26864
26938
|
} catch (t) {
|
|
26865
26939
|
return console.error("[CMS Public Tree API] Error:", t), e.json({
|
|
26866
26940
|
error: "Failed to fetch public tree",
|
|
@@ -26870,19 +26944,19 @@ MS.openapi(BS, async (e) => {
|
|
|
26870
26944
|
});
|
|
26871
26945
|
//#endregion
|
|
26872
26946
|
//#region server/routes/public/channel.ts
|
|
26873
|
-
var
|
|
26874
|
-
function
|
|
26947
|
+
var HS = new $y();
|
|
26948
|
+
function US(e) {
|
|
26875
26949
|
let t = Number(e?.env?.CMS_CHANNEL_CACHE_TTL);
|
|
26876
26950
|
return Number.isFinite(t) && t >= 60 ? Math.floor(t) : 300;
|
|
26877
26951
|
}
|
|
26878
|
-
async function
|
|
26952
|
+
async function WS(e, t, n, r) {
|
|
26879
26953
|
try {
|
|
26880
26954
|
await e.set(t, n, r);
|
|
26881
26955
|
} catch (e) {
|
|
26882
26956
|
console.warn("[CMS Cache] Failed to write channel response to cache:", e);
|
|
26883
26957
|
}
|
|
26884
26958
|
}
|
|
26885
|
-
function
|
|
26959
|
+
function GS(e, t) {
|
|
26886
26960
|
let n = {}, r = (e) => {
|
|
26887
26961
|
if (!e || typeof e != "string") return;
|
|
26888
26962
|
let n = t?.fieldSets?.[e] || t?.fieldsets?.[e] || t?.definitions?.[e] || t?.channels?.[e] || t?.[e];
|
|
@@ -26893,7 +26967,7 @@ function WS(e, t) {
|
|
|
26893
26967
|
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
26968
|
return n;
|
|
26895
26969
|
}
|
|
26896
|
-
function
|
|
26970
|
+
function KS(e, t = {}) {
|
|
26897
26971
|
let n = {}, r = Object.keys(t).length > 0;
|
|
26898
26972
|
for (let [i, a] of Object.entries(e)) {
|
|
26899
26973
|
if (i.endsWith("_meta") || [
|
|
@@ -26912,14 +26986,14 @@ function GS(e, t = {}) {
|
|
|
26912
26986
|
}
|
|
26913
26987
|
return n;
|
|
26914
26988
|
}
|
|
26915
|
-
function
|
|
26916
|
-
if (Array.isArray(e)) return e.map(
|
|
26989
|
+
function qS(e) {
|
|
26990
|
+
if (Array.isArray(e)) return e.map(qS);
|
|
26917
26991
|
if (!e || typeof e != "object") return e;
|
|
26918
26992
|
if (typeof e.id == "string" && e.id.startsWith("ast_") && typeof e.url == "string") {
|
|
26919
26993
|
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
26994
|
...t,
|
|
26921
26995
|
...t.crops?.[r] || {}
|
|
26922
|
-
} : t, a = Object.fromEntries(Object.entries(n).filter(([, t]) => t?.id !== e.id).map(([t, n]) => [t,
|
|
26996
|
+
} : t, a = Object.fromEntries(Object.entries(n).filter(([, t]) => t?.id !== e.id).map(([t, n]) => [t, qS({
|
|
26923
26997
|
...n,
|
|
26924
26998
|
title: n?.title ?? e.title ?? "",
|
|
26925
26999
|
alt: n?.alt ?? e.alt ?? "",
|
|
@@ -26933,9 +27007,19 @@ function KS(e) {
|
|
|
26933
27007
|
...Object.keys(a).length > 0 ? { variants: a } : {}
|
|
26934
27008
|
};
|
|
26935
27009
|
}
|
|
26936
|
-
return Object.fromEntries(Object.entries(e).map(([e, t]) => [e,
|
|
27010
|
+
return Object.fromEntries(Object.entries(e).map(([e, t]) => [e, qS(t)]));
|
|
27011
|
+
}
|
|
27012
|
+
async function JS(e, t, n) {
|
|
27013
|
+
let r = t.href.match(/^#node:(.+)$/), i = t.href.match(/^#asset:(.+)$/);
|
|
27014
|
+
if (i) {
|
|
27015
|
+
let t = i[1], n = await e.prepare("SELECT cdnUrl, storageKeyPrivate FROM assets WHERE id = ?").get(t);
|
|
27016
|
+
return n?.cdnUrl || (n?.storageKeyPrivate ? `/media/${n.storageKeyPrivate}` : "#");
|
|
27017
|
+
}
|
|
27018
|
+
if (!r) return t.href;
|
|
27019
|
+
let a = r[1];
|
|
27020
|
+
return (await e.prepare("SELECT path FROM node_routes WHERE nodeId = ? AND channelId = ? AND isCanonical = 1 LIMIT 1").get(Number(a), n))?.path || "#";
|
|
26937
27021
|
}
|
|
26938
|
-
async function
|
|
27022
|
+
async function YS(e, t, n) {
|
|
26939
27023
|
if (typeof t == "string") {
|
|
26940
27024
|
if (!t.includes("#node:") && !t.includes("data-node-id") && !t.includes("#asset:") && !t.includes("data-asset-id")) return t;
|
|
26941
27025
|
let r = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Set();
|
|
@@ -26968,45 +27052,52 @@ async function qS(e, t, n) {
|
|
|
26968
27052
|
return /href\s*=\s*["'][^"']*["']/i.test(d) ? d = d.replace(/href\s*=\s*["'][^"']*["']/i, `href="${u}"`) : d += ` href="${u}"`, `<a ${d}>`;
|
|
26969
27053
|
});
|
|
26970
27054
|
}
|
|
26971
|
-
if (Array.isArray(t)) return Promise.all(t.map((t) =>
|
|
27055
|
+
if (Array.isArray(t)) return Promise.all(t.map((t) => YS(e, t, n)));
|
|
26972
27056
|
if (t && typeof t == "object") {
|
|
26973
|
-
|
|
27057
|
+
if (typeof t.href == "string" && (t.href.startsWith("#node:") || t.href.startsWith("#asset:"))) {
|
|
27058
|
+
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)]));
|
|
27059
|
+
return {
|
|
27060
|
+
...Object.fromEntries(i),
|
|
27061
|
+
href: r
|
|
27062
|
+
};
|
|
27063
|
+
}
|
|
27064
|
+
let r = await Promise.all(Object.entries(t).map(async ([t, r]) => [t, await YS(e, r, n)]));
|
|
26974
27065
|
return Object.fromEntries(r);
|
|
26975
27066
|
}
|
|
26976
27067
|
return t;
|
|
26977
27068
|
}
|
|
26978
|
-
var
|
|
27069
|
+
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
27070
|
error: J(),
|
|
26980
27071
|
details: J().optional()
|
|
26981
|
-
}).openapi("ErrorResponse"),
|
|
27072
|
+
}).openapi("ErrorResponse"), $S = X({
|
|
26982
27073
|
id: G_([c_(), J()]),
|
|
26983
27074
|
key: J()
|
|
26984
|
-
}).catchall(k_()).openapi("ChannelResponse"),
|
|
27075
|
+
}).catchall(k_()).openapi("ChannelResponse"), eC = eb({
|
|
26985
27076
|
method: "get",
|
|
26986
27077
|
path: "/{channelParam}",
|
|
26987
27078
|
summary: "Fetch CMS Channel Settings",
|
|
26988
27079
|
description: "Retrieves the fully hydrated, public-facing settings and payload for a specific CMS channel.",
|
|
26989
27080
|
tags: ["Public Channel API"],
|
|
26990
27081
|
request: {
|
|
26991
|
-
params:
|
|
26992
|
-
query:
|
|
27082
|
+
params: XS,
|
|
27083
|
+
query: ZS
|
|
26993
27084
|
},
|
|
26994
27085
|
responses: {
|
|
26995
27086
|
200: {
|
|
26996
27087
|
description: "Fully hydrated CMS Channel payload",
|
|
26997
|
-
content: { "application/json": { schema:
|
|
27088
|
+
content: { "application/json": { schema: $S } }
|
|
26998
27089
|
},
|
|
26999
27090
|
404: {
|
|
27000
27091
|
description: "Channel not found or inactive",
|
|
27001
|
-
content: { "application/json": { schema:
|
|
27092
|
+
content: { "application/json": { schema: QS } }
|
|
27002
27093
|
},
|
|
27003
27094
|
500: {
|
|
27004
27095
|
description: "Server error during hydration",
|
|
27005
|
-
content: { "application/json": { schema:
|
|
27096
|
+
content: { "application/json": { schema: QS } }
|
|
27006
27097
|
}
|
|
27007
27098
|
}
|
|
27008
27099
|
});
|
|
27009
|
-
|
|
27100
|
+
HS.openapi(eC, async (e) => {
|
|
27010
27101
|
try {
|
|
27011
27102
|
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
27103
|
if (!i && !a) {
|
|
@@ -27017,23 +27108,23 @@ VS.openapi(QS, async (e) => {
|
|
|
27017
27108
|
if (!c) return e.json({ error: `Channel '${n}' not found` }, 404);
|
|
27018
27109
|
let l = c.status === "disabled" || c.status === "inactive" || c.isEnabled === 0 || c.isEnabled === !1;
|
|
27019
27110
|
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 =
|
|
27111
|
+
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
27112
|
if (g) try {
|
|
27022
27113
|
h = typeof g == "string" ? JSON.parse(g) : g;
|
|
27023
27114
|
} catch (e) {
|
|
27024
27115
|
console.warn("[CMS Public Channel API] Failed to parse channel dataJson:", e);
|
|
27025
27116
|
}
|
|
27026
|
-
let _ =
|
|
27117
|
+
let _ = KS({
|
|
27027
27118
|
...h,
|
|
27028
27119
|
...c
|
|
27029
27120
|
}, m);
|
|
27030
|
-
_ = await fx(t, _), _ =
|
|
27121
|
+
_ = await fx(t, _), _ = qS(_), _ = await YS(t, _, u);
|
|
27031
27122
|
let v = {
|
|
27032
27123
|
id: c.id,
|
|
27033
27124
|
key: c.key,
|
|
27034
27125
|
..._
|
|
27035
27126
|
};
|
|
27036
|
-
return !i && !a && (e.header("X-Cache", "MISS"), await
|
|
27127
|
+
return !i && !a && (e.header("X-Cache", "MISS"), await WS(s, o, v, US(e))), e.json(v, 200);
|
|
27037
27128
|
} catch (t) {
|
|
27038
27129
|
return console.error("[CMS Public Channel API] Error:", t), e.json({
|
|
27039
27130
|
error: "Failed to fetch public channel",
|
|
@@ -27043,8 +27134,8 @@ VS.openapi(QS, async (e) => {
|
|
|
27043
27134
|
});
|
|
27044
27135
|
//#endregion
|
|
27045
27136
|
//#region server/routes/public/assets.ts
|
|
27046
|
-
var
|
|
27047
|
-
function
|
|
27137
|
+
var tC = new $y();
|
|
27138
|
+
function nC(e, t) {
|
|
27048
27139
|
if (t === "webp") return "image/webp";
|
|
27049
27140
|
if (t === "avif") return "image/avif";
|
|
27050
27141
|
if (t === "jpeg" || t === "jpg") return "image/jpeg";
|
|
@@ -27053,7 +27144,7 @@ function eC(e, t) {
|
|
|
27053
27144
|
let n = e.toLowerCase();
|
|
27054
27145
|
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
27146
|
}
|
|
27056
|
-
var
|
|
27147
|
+
var rC = [
|
|
27057
27148
|
320,
|
|
27058
27149
|
640,
|
|
27059
27150
|
768,
|
|
@@ -27063,10 +27154,10 @@ var tC = [
|
|
|
27063
27154
|
2560,
|
|
27064
27155
|
3840
|
|
27065
27156
|
];
|
|
27066
|
-
function
|
|
27067
|
-
if (!(!e || isNaN(e) || e <= 0)) return
|
|
27157
|
+
function iC(e) {
|
|
27158
|
+
if (!(!e || isNaN(e) || e <= 0)) return rC.reduce((t, n) => Math.abs(n - e) < Math.abs(t - e) ? n : t);
|
|
27068
27159
|
}
|
|
27069
|
-
var
|
|
27160
|
+
var aC = eb({
|
|
27070
27161
|
method: "get",
|
|
27071
27162
|
path: "/*",
|
|
27072
27163
|
summary: "Serve & Optimize Media Assets",
|
|
@@ -27126,11 +27217,11 @@ var rC = eb({
|
|
|
27126
27217
|
}
|
|
27127
27218
|
}
|
|
27128
27219
|
});
|
|
27129
|
-
|
|
27220
|
+
tC.openapi(aC, async (e) => {
|
|
27130
27221
|
try {
|
|
27131
27222
|
let t = e.req.path.replace(/^\/media\//, "").replace(/^\//, "");
|
|
27132
27223
|
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 =
|
|
27224
|
+
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
27225
|
if (o) {
|
|
27135
27226
|
let e = !a || a === "auto";
|
|
27136
27227
|
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 +27240,7 @@ $S.openapi(rC, async (e) => {
|
|
|
27149
27240
|
if (!h) return e.text(`Asset not found: ${t}`, 404);
|
|
27150
27241
|
if (!o) {
|
|
27151
27242
|
let n = e.body(h, 200, {
|
|
27152
|
-
"Content-Type":
|
|
27243
|
+
"Content-Type": nC(t),
|
|
27153
27244
|
"Cache-Control": "public, max-age=31536000, immutable"
|
|
27154
27245
|
});
|
|
27155
27246
|
return u && f && e.executionCtx?.waitUntil && e.executionCtx.waitUntil(u.put(f, n.clone())), n;
|
|
@@ -27163,7 +27254,7 @@ $S.openapi(rC, async (e) => {
|
|
|
27163
27254
|
key: t,
|
|
27164
27255
|
env: e.env,
|
|
27165
27256
|
req: e.req.raw
|
|
27166
|
-
}), v =
|
|
27257
|
+
}), v = nC(t, l), y = e.body(_, 200, {
|
|
27167
27258
|
"Content-Type": v,
|
|
27168
27259
|
"Cache-Control": "public, max-age=31536000, immutable"
|
|
27169
27260
|
});
|
|
@@ -27174,8 +27265,8 @@ $S.openapi(rC, async (e) => {
|
|
|
27174
27265
|
});
|
|
27175
27266
|
//#endregion
|
|
27176
27267
|
//#region server/routes/public/paths.ts
|
|
27177
|
-
var
|
|
27178
|
-
function
|
|
27268
|
+
var oC = new $y();
|
|
27269
|
+
function sC(e, t) {
|
|
27179
27270
|
let n = /* @__PURE__ */ new Date();
|
|
27180
27271
|
if (e && String(e).trim() !== "") {
|
|
27181
27272
|
let t = new Date(e);
|
|
@@ -27187,31 +27278,31 @@ function aC(e, t) {
|
|
|
27187
27278
|
}
|
|
27188
27279
|
return !0;
|
|
27189
27280
|
}
|
|
27190
|
-
var
|
|
27281
|
+
var cC = X({
|
|
27191
27282
|
channelId: J().optional().openapi({ description: "Optional channel ID/key to filter and resolve root paths for" }),
|
|
27192
27283
|
channel: J().optional().openapi({ description: "Legacy alias for channelId" })
|
|
27193
|
-
}),
|
|
27284
|
+
}), lC = z_(J()).openapi("PathsResponse"), uC = X({
|
|
27194
27285
|
error: J(),
|
|
27195
27286
|
details: J().optional()
|
|
27196
|
-
}).openapi("ErrorResponse"),
|
|
27287
|
+
}).openapi("ErrorResponse"), dC = eb({
|
|
27197
27288
|
method: "get",
|
|
27198
27289
|
path: "/",
|
|
27199
27290
|
summary: "Fetch All Public Paths",
|
|
27200
27291
|
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
27292
|
tags: ["Public Paths API"],
|
|
27202
|
-
request: { query:
|
|
27293
|
+
request: { query: cC },
|
|
27203
27294
|
responses: {
|
|
27204
27295
|
200: {
|
|
27205
27296
|
description: "Array of valid public URL paths",
|
|
27206
|
-
content: { "application/json": { schema:
|
|
27297
|
+
content: { "application/json": { schema: lC } }
|
|
27207
27298
|
},
|
|
27208
27299
|
500: {
|
|
27209
27300
|
description: "Server error fetching paths",
|
|
27210
|
-
content: { "application/json": { schema:
|
|
27301
|
+
content: { "application/json": { schema: uC } }
|
|
27211
27302
|
}
|
|
27212
27303
|
}
|
|
27213
27304
|
});
|
|
27214
|
-
|
|
27305
|
+
oC.openapi(dC, async (e) => {
|
|
27215
27306
|
try {
|
|
27216
27307
|
let t = e.get("db"), n = e.req.valid("query"), r = n.channelId || n.channel, i = "", a = [];
|
|
27217
27308
|
if (r && r !== "all") {
|
|
@@ -27222,7 +27313,8 @@ iC.openapi(lC, async (e) => {
|
|
|
27222
27313
|
SELECT
|
|
27223
27314
|
nr.path,
|
|
27224
27315
|
cn.contentType as nodeType,
|
|
27225
|
-
cn.
|
|
27316
|
+
cn.startShowingAt,
|
|
27317
|
+
cn.stopShowingAt
|
|
27226
27318
|
FROM node_routes nr
|
|
27227
27319
|
INNER JOIN content_nodes cn ON nr.nodeId = cn.id
|
|
27228
27320
|
WHERE nr.isCanonical = 1
|
|
@@ -27231,15 +27323,7 @@ iC.openapi(lC, async (e) => {
|
|
|
27231
27323
|
${i}
|
|
27232
27324
|
ORDER BY nr.path ASC
|
|
27233
27325
|
`).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
|
-
}
|
|
27326
|
+
for (let e of s) e.nodeType !== "external-link" && e.path && sC(e.startShowingAt, e.stopShowingAt) && c.push(e.path);
|
|
27243
27327
|
let l = [...new Set(c)];
|
|
27244
27328
|
return e.json(l, 200);
|
|
27245
27329
|
} catch (t) {
|
|
@@ -27248,12 +27332,12 @@ iC.openapi(lC, async (e) => {
|
|
|
27248
27332
|
});
|
|
27249
27333
|
//#endregion
|
|
27250
27334
|
//#region server/routes/public/taxonomies.ts
|
|
27251
|
-
var
|
|
27252
|
-
function
|
|
27335
|
+
var fC = new $y();
|
|
27336
|
+
function pC(e) {
|
|
27253
27337
|
let t = (e || "").trim().toLowerCase(), n = px()?.taxonomies || {};
|
|
27254
27338
|
return n[t] ? t : n[`${t}s`] ? `${t}s` : t.endsWith("s") && n[t.slice(0, -1)] ? t.slice(0, -1) : t;
|
|
27255
27339
|
}
|
|
27256
|
-
var
|
|
27340
|
+
var mC = X({
|
|
27257
27341
|
id: c_(),
|
|
27258
27342
|
taxonomy: J(),
|
|
27259
27343
|
key: J(),
|
|
@@ -27263,14 +27347,14 @@ var fC = X({
|
|
|
27263
27347
|
data: tv(k_()),
|
|
27264
27348
|
createdAt: J(),
|
|
27265
27349
|
updatedAt: J()
|
|
27266
|
-
}),
|
|
27350
|
+
}), hC = X({
|
|
27267
27351
|
taxonomy: J(),
|
|
27268
|
-
items: z_(
|
|
27352
|
+
items: z_(mC),
|
|
27269
27353
|
total: c_()
|
|
27270
|
-
}).openapi("TaxonomyResponse"),
|
|
27354
|
+
}).openapi("TaxonomyResponse"), gC = X({
|
|
27271
27355
|
error: J(),
|
|
27272
27356
|
details: J().optional()
|
|
27273
|
-
}).openapi("ErrorResponse"),
|
|
27357
|
+
}).openapi("ErrorResponse"), _C = eb({
|
|
27274
27358
|
method: "get",
|
|
27275
27359
|
path: "/{taxonomy}",
|
|
27276
27360
|
summary: "Fetch Public Taxonomy Terms",
|
|
@@ -27280,17 +27364,17 @@ var fC = X({
|
|
|
27280
27364
|
responses: {
|
|
27281
27365
|
200: {
|
|
27282
27366
|
description: "List of taxonomy terms",
|
|
27283
|
-
content: { "application/json": { schema:
|
|
27367
|
+
content: { "application/json": { schema: hC } }
|
|
27284
27368
|
},
|
|
27285
27369
|
500: {
|
|
27286
27370
|
description: "Server error",
|
|
27287
|
-
content: { "application/json": { schema:
|
|
27371
|
+
content: { "application/json": { schema: gC } }
|
|
27288
27372
|
}
|
|
27289
27373
|
}
|
|
27290
27374
|
});
|
|
27291
|
-
|
|
27375
|
+
fC.openapi(_C, async (e) => {
|
|
27292
27376
|
try {
|
|
27293
|
-
let t = e.get("db"), n = $b(e), r = e.req.valid("param").taxonomy, i =
|
|
27377
|
+
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
27378
|
if (!o) {
|
|
27295
27379
|
let t = await n.get(a);
|
|
27296
27380
|
if (t) return e.header("X-Cache", "HIT"), e.json(t);
|
|
@@ -27326,7 +27410,7 @@ uC.openapi(hC, async (e) => {
|
|
|
27326
27410
|
});
|
|
27327
27411
|
//#endregion
|
|
27328
27412
|
//#region server/index.ts
|
|
27329
|
-
var $ = new $y(),
|
|
27413
|
+
var $ = new $y(), vC = !1;
|
|
27330
27414
|
$.use("*", t()), $.use("/media/*", t({
|
|
27331
27415
|
origin: "*",
|
|
27332
27416
|
allowMethods: [
|
|
@@ -27347,20 +27431,20 @@ $.use("*", t()), $.use("/media/*", t({
|
|
|
27347
27431
|
let n = new URL(e.req.url), r = (e.req.header("host") || n.hostname).split(":")[0];
|
|
27348
27432
|
e.set("currentDomain", r);
|
|
27349
27433
|
let i = wb(e);
|
|
27350
|
-
if (e.set("db", i), !
|
|
27351
|
-
await Mb(i),
|
|
27434
|
+
if (e.set("db", i), !vC) try {
|
|
27435
|
+
await Mb(i), vC = !0;
|
|
27352
27436
|
} catch (e) {
|
|
27353
27437
|
console.error("❌ [CMS Server] Failed to initialize system tables on cold start:", e);
|
|
27354
27438
|
}
|
|
27355
27439
|
await t();
|
|
27356
|
-
}), $.route("/media",
|
|
27440
|
+
}), $.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
27441
|
let n = e.env?.FRONTEND_API_SECRET;
|
|
27358
27442
|
if (n) {
|
|
27359
27443
|
let t = e.req.header("Authorization"), r = e.req.header("x-api-key"), i = t?.startsWith("Bearer ") ? t.substring(7).trim() : r?.trim();
|
|
27360
27444
|
if (!i || i !== n) return e.json({ error: "Unauthorized: Invalid or missing API secret." }, 401);
|
|
27361
27445
|
} else console.warn("⚠️ [CMS Security] FRONTEND_API_SECRET is not set in .env. The API is completely exposed to the public.");
|
|
27362
27446
|
return t();
|
|
27363
|
-
}), $.route("/api/v1/node",
|
|
27447
|
+
}), $.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
27448
|
openapi: "3.0.0",
|
|
27365
27449
|
info: {
|
|
27366
27450
|
title: "KAMA Engine Public API",
|
|
@@ -27379,4 +27463,4 @@ $.use("*", t()), $.use("/media/*", t({
|
|
|
27379
27463
|
return t();
|
|
27380
27464
|
});
|
|
27381
27465
|
//#endregion
|
|
27382
|
-
export { $ as app, $ as default,
|
|
27466
|
+
export { $ as app, $ as default, Xx as compileDefinitions, Zx as getCmsDefinitions };
|