@sonicjs-cms/core 3.0.0-beta.22 → 3.0.0-beta.24
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/dist/adapters.cjs +512 -0
- package/dist/adapters.cjs.map +1 -0
- package/dist/adapters.d.cts +342 -0
- package/dist/adapters.d.ts +342 -0
- package/dist/adapters.js +501 -0
- package/dist/adapters.js.map +1 -0
- package/dist/admin-documents-form.template-55V2ZGWT.js +6 -0
- package/dist/{admin-documents-form.template-DDSH6ROU.js.map → admin-documents-form.template-55V2ZGWT.js.map} +1 -1
- package/dist/admin-documents-form.template-YNAVMJCV.cjs +19 -0
- package/dist/{admin-layout-catalyst.template-YQ4EMF2J.js.map → admin-documents-form.template-YNAVMJCV.cjs.map} +1 -1
- package/dist/admin-layout-catalyst.template-3XZXDGF7.cjs +21 -0
- package/dist/{admin-layout-catalyst.template-KDHKVLXR.cjs.map → admin-layout-catalyst.template-3XZXDGF7.cjs.map} +1 -1
- package/dist/admin-layout-catalyst.template-6UQGLCKI.js +7 -0
- package/dist/{admin-documents-form.template-LSZKGA5J.cjs.map → admin-layout-catalyst.template-6UQGLCKI.js.map} +1 -1
- package/dist/{chunk-FTXGZ3BF.cjs → chunk-37V3RET3.cjs} +21 -37
- package/dist/chunk-37V3RET3.cjs.map +1 -0
- package/dist/{chunk-3CT3SUR4.cjs → chunk-A2SN3RVL.cjs} +3 -3
- package/dist/chunk-A2SN3RVL.cjs.map +1 -0
- package/dist/{chunk-CRGUD4KC.cjs → chunk-BBEKHLTW.cjs} +9 -9
- package/dist/{chunk-CRGUD4KC.cjs.map → chunk-BBEKHLTW.cjs.map} +1 -1
- package/dist/{chunk-RMRJGMDE.js → chunk-BHND5PEV.js} +3 -3
- package/dist/{chunk-RMRJGMDE.js.map → chunk-BHND5PEV.js.map} +1 -1
- package/dist/{chunk-OBA2RYZN.js → chunk-BJROXF4N.js} +3 -3
- package/dist/{chunk-OBA2RYZN.js.map → chunk-BJROXF4N.js.map} +1 -1
- package/dist/{chunk-EUJAEB6W.cjs → chunk-BP52BFIV.cjs} +53 -4
- package/dist/chunk-BP52BFIV.cjs.map +1 -0
- package/dist/{chunk-PXNTCCPE.cjs → chunk-E66UVONV.cjs} +8 -8
- package/dist/{chunk-PXNTCCPE.cjs.map → chunk-E66UVONV.cjs.map} +1 -1
- package/dist/{chunk-CHWT5KBK.js → chunk-FHPEM77Y.js} +9 -25
- package/dist/chunk-FHPEM77Y.js.map +1 -0
- package/dist/{chunk-JFLZHOQP.cjs → chunk-I767LVN7.cjs} +531 -419
- package/dist/chunk-I767LVN7.cjs.map +1 -0
- package/dist/{chunk-N32OWET6.cjs → chunk-JMJM7DMM.cjs} +5 -5
- package/dist/{chunk-N32OWET6.cjs.map → chunk-JMJM7DMM.cjs.map} +1 -1
- package/dist/{chunk-QWSR4THH.cjs → chunk-KKNEYIZJ.cjs} +12 -5
- package/dist/chunk-KKNEYIZJ.cjs.map +1 -0
- package/dist/{chunk-73O4GPJ6.js → chunk-LNI3FYSI.js} +12 -5
- package/dist/chunk-LNI3FYSI.js.map +1 -0
- package/dist/{chunk-PYZYU7EK.cjs → chunk-QCJHCSOK.cjs} +36 -2
- package/dist/chunk-QCJHCSOK.cjs.map +1 -0
- package/dist/{chunk-MGHHPNJN.cjs → chunk-QJUJNTIU.cjs} +11 -59
- package/dist/chunk-QJUJNTIU.cjs.map +1 -0
- package/dist/{chunk-DOMXI5PM.js → chunk-RJ2O5IIE.js} +36 -2
- package/dist/chunk-RJ2O5IIE.js.map +1 -0
- package/dist/{chunk-5V62WT6M.js → chunk-THFZSDIU.js} +4 -2
- package/dist/chunk-THFZSDIU.js.map +1 -0
- package/dist/{chunk-2FCKKOA5.js → chunk-UIHIXTIS.js} +3 -3
- package/dist/chunk-UIHIXTIS.js.map +1 -0
- package/dist/{chunk-JQISFW6U.js → chunk-URIBTX27.js} +3 -3
- package/dist/{chunk-JQISFW6U.js.map → chunk-URIBTX27.js.map} +1 -1
- package/dist/{chunk-K623Q6WD.cjs → chunk-UYJQDDEE.cjs} +4 -2
- package/dist/chunk-UYJQDDEE.cjs.map +1 -0
- package/dist/{chunk-6KNTZ67K.js → chunk-VC5XVPLM.js} +234 -126
- package/dist/chunk-VC5XVPLM.js.map +1 -0
- package/dist/{chunk-I2DM27HP.js → chunk-VGEZNFWH.js} +49 -4
- package/dist/chunk-VGEZNFWH.js.map +1 -0
- package/dist/{chunk-GB2Q2DNK.js → chunk-VYQVDL2M.js} +5 -49
- package/dist/chunk-VYQVDL2M.js.map +1 -0
- package/dist/{define-plugin-DsKiGu1q.d.cts → define-plugin-DMcvEy_C.d.cts} +33 -0
- package/dist/{define-plugin-BYIey6sp.d.ts → define-plugin-D_6D9vVZ.d.ts} +33 -0
- package/dist/index.cjs +2587 -326
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +30 -3
- package/dist/index.d.ts +30 -3
- package/dist/index.js +2281 -22
- package/dist/index.js.map +1 -1
- package/dist/middleware.cjs +34 -34
- package/dist/middleware.js +5 -5
- package/dist/migrations-FGXZPKDC.cjs +13 -0
- package/dist/{migrations-UIMA6ZL6.cjs.map → migrations-FGXZPKDC.cjs.map} +1 -1
- package/dist/migrations-Z6D27NAW.js +4 -0
- package/dist/{migrations-HLK2QF4T.js.map → migrations-Z6D27NAW.js.map} +1 -1
- package/dist/plugins.cjs +40 -40
- package/dist/plugins.d.cts +1 -1
- package/dist/plugins.d.ts +1 -1
- package/dist/plugins.js +3 -3
- package/dist/routes.cjs +29 -29
- package/dist/routes.js +9 -9
- package/dist/services.cjs +18 -18
- package/dist/services.js +2 -2
- package/dist/templates.cjs +17 -17
- package/dist/templates.js +3 -3
- package/dist/utils.cjs +3 -3
- package/dist/utils.js +1 -1
- package/migrations/0001_core.sql +7 -1
- package/package.json +10 -3
- package/dist/admin-documents-form.template-DDSH6ROU.js +0 -6
- package/dist/admin-documents-form.template-LSZKGA5J.cjs +0 -19
- package/dist/admin-layout-catalyst.template-KDHKVLXR.cjs +0 -21
- package/dist/admin-layout-catalyst.template-YQ4EMF2J.js +0 -7
- package/dist/chunk-2FCKKOA5.js.map +0 -1
- package/dist/chunk-3CT3SUR4.cjs.map +0 -1
- package/dist/chunk-5V62WT6M.js.map +0 -1
- package/dist/chunk-6KNTZ67K.js.map +0 -1
- package/dist/chunk-73O4GPJ6.js.map +0 -1
- package/dist/chunk-CHWT5KBK.js.map +0 -1
- package/dist/chunk-DOMXI5PM.js.map +0 -1
- package/dist/chunk-EUJAEB6W.cjs.map +0 -1
- package/dist/chunk-FTXGZ3BF.cjs.map +0 -1
- package/dist/chunk-GB2Q2DNK.js.map +0 -1
- package/dist/chunk-I2DM27HP.js.map +0 -1
- package/dist/chunk-JFLZHOQP.cjs.map +0 -1
- package/dist/chunk-K623Q6WD.cjs.map +0 -1
- package/dist/chunk-MGHHPNJN.cjs.map +0 -1
- package/dist/chunk-PYZYU7EK.cjs.map +0 -1
- package/dist/chunk-QWSR4THH.cjs.map +0 -1
- package/dist/migrations-HLK2QF4T.js +0 -4
- package/dist/migrations-UIMA6ZL6.cjs +0 -13
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var chunkXWVDSM2L_cjs = require('./chunk-XWVDSM2L.cjs');
|
|
4
|
-
var
|
|
4
|
+
var chunkJMJM7DMM_cjs = require('./chunk-JMJM7DMM.cjs');
|
|
5
5
|
var chunk36Z3AKX3_cjs = require('./chunk-36Z3AKX3.cjs');
|
|
6
|
-
var
|
|
6
|
+
var chunk37V3RET3_cjs = require('./chunk-37V3RET3.cjs');
|
|
7
7
|
var chunkLTZ5WYOK_cjs = require('./chunk-LTZ5WYOK.cjs');
|
|
8
8
|
var chunkKIGVVO6N_cjs = require('./chunk-KIGVVO6N.cjs');
|
|
9
|
-
var
|
|
10
|
-
var
|
|
11
|
-
var
|
|
12
|
-
var
|
|
13
|
-
var
|
|
9
|
+
var chunkQCJHCSOK_cjs = require('./chunk-QCJHCSOK.cjs');
|
|
10
|
+
var chunkA2SN3RVL_cjs = require('./chunk-A2SN3RVL.cjs');
|
|
11
|
+
var chunkE66UVONV_cjs = require('./chunk-E66UVONV.cjs');
|
|
12
|
+
var chunkUYJQDDEE_cjs = require('./chunk-UYJQDDEE.cjs');
|
|
13
|
+
var chunkBP52BFIV_cjs = require('./chunk-BP52BFIV.cjs');
|
|
14
14
|
var chunkJ6JTWD2A_cjs = require('./chunk-J6JTWD2A.cjs');
|
|
15
15
|
var chunkIXUHXTHW_cjs = require('./chunk-IXUHXTHW.cjs');
|
|
16
16
|
var chunkRCQ2HIQD_cjs = require('./chunk-RCQ2HIQD.cjs');
|
|
17
|
-
var
|
|
17
|
+
var chunkKKNEYIZJ_cjs = require('./chunk-KKNEYIZJ.cjs');
|
|
18
18
|
var chunkMNWKYY5E_cjs = require('./chunk-MNWKYY5E.cjs');
|
|
19
19
|
var hono = require('hono');
|
|
20
20
|
var zod = require('zod');
|
|
@@ -151,6 +151,18 @@ var DocumentRepository = class {
|
|
|
151
151
|
const row = await this.db.prepare("SELECT * FROM documents WHERE root_id = ? AND tenant_id = ? AND is_published = 1").bind(rootId, this.tenantId).first();
|
|
152
152
|
return row ? rowToDocument(row) : null;
|
|
153
153
|
}
|
|
154
|
+
// Slug lookup for a single doc. Prefer the published row; fall back to the current
|
|
155
|
+
// draft so a never-published doc is still reachable by slug (matches getById, which
|
|
156
|
+
// resolves drafts too). ORDER BY makes the preference deterministic when both exist.
|
|
157
|
+
async getBySlug(typeId, slug) {
|
|
158
|
+
const row = await this.db.prepare(
|
|
159
|
+
`SELECT * FROM documents
|
|
160
|
+
WHERE tenant_id = ? AND type_id = ? AND slug = ? AND deleted_at IS NULL
|
|
161
|
+
AND (is_published = 1 OR is_current_draft = 1)
|
|
162
|
+
ORDER BY is_published DESC LIMIT 1`
|
|
163
|
+
).bind(this.tenantId, typeId, slug).first();
|
|
164
|
+
return row ? rowToDocument(row) : null;
|
|
165
|
+
}
|
|
154
166
|
// Unified, tenant-scoped list with optional generated-column / facet filters and sort. This is the
|
|
155
167
|
// single place document list SQL is built — route handlers must call this, never inline SQL (R4).
|
|
156
168
|
async list(opts = {}) {
|
|
@@ -259,7 +271,7 @@ function getDocumentRequestContext(c) {
|
|
|
259
271
|
|
|
260
272
|
// src/routes/api-documents.ts
|
|
261
273
|
async function aclAllowsRead(db, tenantId, principalSet, row, preloadedType) {
|
|
262
|
-
const docType = preloadedType ?? await new
|
|
274
|
+
const docType = preloadedType ?? await new chunk37V3RET3_cjs.DocumentTypeRegistry(db).findById(row.type_id);
|
|
263
275
|
if (!docType) return false;
|
|
264
276
|
return new DocumentRepository(db, tenantId).isAllowed(principalSet, row.root_id, "read", docType.settings);
|
|
265
277
|
}
|
|
@@ -277,7 +289,7 @@ apiDocumentsRoutes.get("/", async (c) => {
|
|
|
277
289
|
if (!typeId) {
|
|
278
290
|
return c.json({ error: "type query parameter is required" }, 400);
|
|
279
291
|
}
|
|
280
|
-
const registry = new
|
|
292
|
+
const registry = new chunk37V3RET3_cjs.DocumentTypeRegistry(db);
|
|
281
293
|
const docType = await registry.findById(typeId);
|
|
282
294
|
if (!docType || !docType.isActive) {
|
|
283
295
|
return c.json({ error: "Unknown document type" }, 400);
|
|
@@ -359,7 +371,7 @@ apiDocumentsRoutes.get("/root/:rootId", async (c) => {
|
|
|
359
371
|
AND (expires_at IS NULL OR expires_at > ?) LIMIT 1`
|
|
360
372
|
).bind(rootId, now, now).first();
|
|
361
373
|
if (!row) return c.json({ error: "Not found" }, 404);
|
|
362
|
-
const docType = await new
|
|
374
|
+
const docType = await new chunk37V3RET3_cjs.DocumentTypeRegistry(db).findById(row.type_id);
|
|
363
375
|
const effTenant = effectiveTenantForType(tenantId, docType?.settings);
|
|
364
376
|
if (row.tenant_id !== effTenant) return c.json({ error: "Not found" }, 404);
|
|
365
377
|
if (!await aclAllowsRead(db, effTenant, principalSet, row, docType)) {
|
|
@@ -395,7 +407,7 @@ apiDocumentsRoutes.get("/:id", async (c) => {
|
|
|
395
407
|
AND (expires_at IS NULL OR expires_at > ?) LIMIT 1`
|
|
396
408
|
).bind(id, now, now).first();
|
|
397
409
|
if (!row) return c.json({ error: "Not found" }, 404);
|
|
398
|
-
const docType = await new
|
|
410
|
+
const docType = await new chunk37V3RET3_cjs.DocumentTypeRegistry(db).findById(row.type_id);
|
|
399
411
|
const effTenant = effectiveTenantForType(tenantId, docType?.settings);
|
|
400
412
|
if (row.tenant_id !== effTenant) return c.json({ error: "Not found" }, 404);
|
|
401
413
|
if (!await aclAllowsRead(db, effTenant, principalSet, row, docType)) {
|
|
@@ -465,17 +477,17 @@ async function resolveDocScope(c, db, by, opts = {}) {
|
|
|
465
477
|
const draft = opts.currentDraftOnly ? " AND is_current_draft = 1" : "";
|
|
466
478
|
const row = await db.prepare(`SELECT type_id, root_id, tenant_id FROM documents WHERE ${col} = ?${draft} LIMIT 1`).bind(val).first();
|
|
467
479
|
if (!row) return null;
|
|
468
|
-
const docType = await new
|
|
480
|
+
const docType = await new chunk37V3RET3_cjs.DocumentTypeRegistry(db).findById(row.type_id);
|
|
469
481
|
const tenantId = effectiveTenantForType(getRequestTenant(c), docType?.settings);
|
|
470
482
|
if (row.tenant_id !== tenantId) return null;
|
|
471
483
|
return { typeId: row.type_id, rootId: row.root_id, tenantId, docType };
|
|
472
484
|
}
|
|
473
485
|
var adminDocumentsRoutes = new hono.Hono();
|
|
474
|
-
adminDocumentsRoutes.use("*",
|
|
475
|
-
adminDocumentsRoutes.use("*",
|
|
486
|
+
adminDocumentsRoutes.use("*", chunk37V3RET3_cjs.requireAuth());
|
|
487
|
+
adminDocumentsRoutes.use("*", chunk37V3RET3_cjs.requireRole(["admin", "editor"]));
|
|
476
488
|
adminDocumentsRoutes.get("/types", async (c) => {
|
|
477
489
|
try {
|
|
478
|
-
const registry = new
|
|
490
|
+
const registry = new chunk37V3RET3_cjs.DocumentTypeRegistry(c.env.DB);
|
|
479
491
|
const types = await registry.findAll();
|
|
480
492
|
return c.json({ data: types });
|
|
481
493
|
} catch (error) {
|
|
@@ -503,7 +515,7 @@ adminDocumentsRoutes.get("/", async (c) => {
|
|
|
503
515
|
if (!typeId) {
|
|
504
516
|
return c.json({ error: "type query parameter is required" }, 400);
|
|
505
517
|
}
|
|
506
|
-
const registry = new
|
|
518
|
+
const registry = new chunk37V3RET3_cjs.DocumentTypeRegistry(db);
|
|
507
519
|
const docType = await registry.findById(typeId);
|
|
508
520
|
if (!docType || !docType.isActive) {
|
|
509
521
|
return c.json({ error: "Unknown document type" }, 400);
|
|
@@ -614,7 +626,7 @@ adminDocumentsRoutes.post("/", async (c) => {
|
|
|
614
626
|
const input = validation.data;
|
|
615
627
|
const db = c.env.DB;
|
|
616
628
|
const user = c.get("user");
|
|
617
|
-
const registry = new
|
|
629
|
+
const registry = new chunk37V3RET3_cjs.DocumentTypeRegistry(db);
|
|
618
630
|
const docType = await registry.findById(input.typeId);
|
|
619
631
|
if (!docType || !docType.isActive) {
|
|
620
632
|
return c.json({ error: "Unknown document type" }, 400);
|
|
@@ -746,7 +758,7 @@ adminDocumentsRoutes.post("/types/:typeId/reindex", async (c) => {
|
|
|
746
758
|
try {
|
|
747
759
|
const { typeId } = c.req.param();
|
|
748
760
|
const db = c.env.DB;
|
|
749
|
-
const registry = new
|
|
761
|
+
const registry = new chunk37V3RET3_cjs.DocumentTypeRegistry(db);
|
|
750
762
|
const docType = await registry.findById(typeId);
|
|
751
763
|
if (!docType) return c.json({ error: "Unknown document type" }, 400);
|
|
752
764
|
const reindexTenant = effectiveTenantForType(getRequestTenant(c), docType.settings);
|
|
@@ -900,13 +912,13 @@ async function resolveContentVariables(contentData, db) {
|
|
|
900
912
|
// src/routes/api-content-crud.ts
|
|
901
913
|
var apiContentCrudRoutes = new hono.Hono();
|
|
902
914
|
async function resolveDocBacking(db, collectionIdOrName) {
|
|
903
|
-
const registry =
|
|
915
|
+
const registry = chunkQCJHCSOK_cjs.getCollectionRegistry();
|
|
904
916
|
const record = registry.getBySlugOrName(collectionIdOrName) ?? registry.getById(collectionIdOrName);
|
|
905
917
|
if (record) {
|
|
906
|
-
const docType2 = await new
|
|
918
|
+
const docType2 = await new chunk37V3RET3_cjs.DocumentTypeRegistry(db).findById(record.name);
|
|
907
919
|
return docType2 ? { coll: { id: record.id, name: record.name }, docType: docType2 } : null;
|
|
908
920
|
}
|
|
909
|
-
const docType = await new
|
|
921
|
+
const docType = await new chunk37V3RET3_cjs.DocumentTypeRegistry(db).findById(collectionIdOrName);
|
|
910
922
|
if (docType) {
|
|
911
923
|
return { coll: { id: collectionIdOrName, name: collectionIdOrName }, docType };
|
|
912
924
|
}
|
|
@@ -949,7 +961,7 @@ apiContentCrudRoutes.get("/check-slug", async (c) => {
|
|
|
949
961
|
}, 500);
|
|
950
962
|
}
|
|
951
963
|
});
|
|
952
|
-
apiContentCrudRoutes.get("/:id",
|
|
964
|
+
apiContentCrudRoutes.get("/:id", chunk37V3RET3_cjs.optionalAuth(), async (c) => {
|
|
953
965
|
try {
|
|
954
966
|
const id = c.req.param("id");
|
|
955
967
|
const db = c.env.DB;
|
|
@@ -959,7 +971,7 @@ apiContentCrudRoutes.get("/:id", chunkFTXGZ3BF_cjs.optionalAuth(), async (c) =>
|
|
|
959
971
|
).bind(id, getRequestTenant(c)).first();
|
|
960
972
|
let transformedContent;
|
|
961
973
|
if (docRow) {
|
|
962
|
-
const coll =
|
|
974
|
+
const coll = chunkQCJHCSOK_cjs.getCollectionRegistry().getByName(docRow.type_id);
|
|
963
975
|
transformedContent = {
|
|
964
976
|
id: docRow.root_id,
|
|
965
977
|
title: docRow.title,
|
|
@@ -993,7 +1005,7 @@ apiContentCrudRoutes.get("/:id", chunkFTXGZ3BF_cjs.optionalAuth(), async (c) =>
|
|
|
993
1005
|
}, 500);
|
|
994
1006
|
}
|
|
995
1007
|
});
|
|
996
|
-
apiContentCrudRoutes.post("/",
|
|
1008
|
+
apiContentCrudRoutes.post("/", chunk37V3RET3_cjs.requireAuth(), chunk37V3RET3_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
|
|
997
1009
|
try {
|
|
998
1010
|
const db = c.env.DB;
|
|
999
1011
|
const user = c.get("user");
|
|
@@ -1068,7 +1080,7 @@ apiContentCrudRoutes.post("/", chunkFTXGZ3BF_cjs.requireAuth(), chunkFTXGZ3BF_cj
|
|
|
1068
1080
|
}, 500);
|
|
1069
1081
|
}
|
|
1070
1082
|
});
|
|
1071
|
-
apiContentCrudRoutes.put("/:id",
|
|
1083
|
+
apiContentCrudRoutes.put("/:id", chunk37V3RET3_cjs.requireAuth(), chunk37V3RET3_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
|
|
1072
1084
|
try {
|
|
1073
1085
|
const id = c.req.param("id");
|
|
1074
1086
|
const db = c.env.DB;
|
|
@@ -1090,7 +1102,7 @@ apiContentCrudRoutes.put("/:id", chunkFTXGZ3BF_cjs.requireAuth(), chunkFTXGZ3BF_
|
|
|
1090
1102
|
} catch (err) {
|
|
1091
1103
|
return c.json({ error: "Write cancelled by plugin", details: String(err) }, 400);
|
|
1092
1104
|
}
|
|
1093
|
-
const docType = await new
|
|
1105
|
+
const docType = await new chunk37V3RET3_cjs.DocumentTypeRegistry(db).findById(docRow.type_id);
|
|
1094
1106
|
const svc = new chunkLTZ5WYOK_cjs.DocumentsService(db, {
|
|
1095
1107
|
queryableFields: docType?.queryableFields ?? [],
|
|
1096
1108
|
typeSchemaVersion: docType?.schemaVersion ?? 1,
|
|
@@ -1113,7 +1125,7 @@ apiContentCrudRoutes.put("/:id", chunkFTXGZ3BF_cjs.requireAuth(), chunkFTXGZ3BF_
|
|
|
1113
1125
|
const cache = chunk36Z3AKX3_cjs.getCacheService(chunk36Z3AKX3_cjs.CACHE_CONFIGS.api);
|
|
1114
1126
|
await cache.invalidate("content-filtered:*");
|
|
1115
1127
|
await cache.invalidate("collection-content-filtered:*");
|
|
1116
|
-
const coll =
|
|
1128
|
+
const coll = chunkQCJHCSOK_cjs.getCollectionRegistry().getByName(docRow.type_id);
|
|
1117
1129
|
const saved = await db.prepare("SELECT * FROM documents WHERE id = ?").bind(newDraft.id).first();
|
|
1118
1130
|
const savedData = saved?.data ? JSON.parse(saved.data) : {};
|
|
1119
1131
|
dispatchHookEvent(c, "content:after:update", { collection: docRow.type_id, id, data: savedData, user: actor }, "fire-and-forget");
|
|
@@ -1134,7 +1146,7 @@ apiContentCrudRoutes.put("/:id", chunkFTXGZ3BF_cjs.requireAuth(), chunkFTXGZ3BF_
|
|
|
1134
1146
|
}, 500);
|
|
1135
1147
|
}
|
|
1136
1148
|
});
|
|
1137
|
-
apiContentCrudRoutes.delete("/:id",
|
|
1149
|
+
apiContentCrudRoutes.delete("/:id", chunk37V3RET3_cjs.requireAuth(), chunk37V3RET3_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
|
|
1138
1150
|
try {
|
|
1139
1151
|
const id = c.req.param("id");
|
|
1140
1152
|
const db = c.env.DB;
|
|
@@ -1260,7 +1272,7 @@ apiRoutes.use("*", async (c, next) => {
|
|
|
1260
1272
|
c.header("X-Response-Time", `${totalTime}ms`);
|
|
1261
1273
|
});
|
|
1262
1274
|
apiRoutes.use("*", async (c, next) => {
|
|
1263
|
-
const cacheEnabled = await
|
|
1275
|
+
const cacheEnabled = await chunk37V3RET3_cjs.isPluginActive(c.env.DB, "core-cache");
|
|
1264
1276
|
c.set("cacheEnabled", cacheEnabled);
|
|
1265
1277
|
await next();
|
|
1266
1278
|
});
|
|
@@ -1283,7 +1295,7 @@ apiRoutes.get("/", (c) => {
|
|
|
1283
1295
|
openapi: "3.0.0",
|
|
1284
1296
|
info: {
|
|
1285
1297
|
title: "SonicJS AI API",
|
|
1286
|
-
version:
|
|
1298
|
+
version: chunkKKNEYIZJ_cjs.getCoreVersion(),
|
|
1287
1299
|
description: "RESTful API for SonicJS headless CMS - a modern, AI-powered content management system built on Cloudflare Workers",
|
|
1288
1300
|
contact: {
|
|
1289
1301
|
name: "SonicJS Support",
|
|
@@ -1713,8 +1725,8 @@ apiRoutes.get("/collections", async (c) => {
|
|
|
1713
1725
|
}
|
|
1714
1726
|
c.header("X-Cache-Status", "MISS");
|
|
1715
1727
|
c.header("X-Cache-Source", "registry");
|
|
1716
|
-
const records =
|
|
1717
|
-
const transformedResults = records.map(
|
|
1728
|
+
const records = chunkQCJHCSOK_cjs.getCollectionRegistry().listActive().filter((r) => !r.internal);
|
|
1729
|
+
const transformedResults = records.map(chunkQCJHCSOK_cjs.collectionRecordToRow);
|
|
1718
1730
|
const responseData = {
|
|
1719
1731
|
data: transformedResults,
|
|
1720
1732
|
meta: addTimingMeta(c, {
|
|
@@ -1735,7 +1747,7 @@ apiRoutes.get("/collections", async (c) => {
|
|
|
1735
1747
|
return c.json({ error: "Failed to fetch collections" }, 500);
|
|
1736
1748
|
}
|
|
1737
1749
|
});
|
|
1738
|
-
apiRoutes.get("/content",
|
|
1750
|
+
apiRoutes.get("/content", chunk37V3RET3_cjs.optionalAuth(), async (c) => {
|
|
1739
1751
|
const executionStart = Date.now();
|
|
1740
1752
|
try {
|
|
1741
1753
|
const db = c.env.DB;
|
|
@@ -1744,7 +1756,7 @@ apiRoutes.get("/content", chunkFTXGZ3BF_cjs.optionalAuth(), async (c) => {
|
|
|
1744
1756
|
const collIdByName = /* @__PURE__ */ new Map();
|
|
1745
1757
|
let typeId;
|
|
1746
1758
|
let typeIds;
|
|
1747
|
-
const registry =
|
|
1759
|
+
const registry = chunkQCJHCSOK_cjs.getCollectionRegistry();
|
|
1748
1760
|
if (queryParams.collection) {
|
|
1749
1761
|
const collectionName = queryParams.collection;
|
|
1750
1762
|
const record = registry.getByName(collectionName);
|
|
@@ -1843,13 +1855,13 @@ apiRoutes.get("/content", chunkFTXGZ3BF_cjs.optionalAuth(), async (c) => {
|
|
|
1843
1855
|
}, 500);
|
|
1844
1856
|
}
|
|
1845
1857
|
});
|
|
1846
|
-
apiRoutes.get("/collections/:collection/content",
|
|
1858
|
+
apiRoutes.get("/collections/:collection/content", chunk37V3RET3_cjs.optionalAuth(), async (c) => {
|
|
1847
1859
|
const executionStart = Date.now();
|
|
1848
1860
|
try {
|
|
1849
1861
|
const collection = c.req.param("collection");
|
|
1850
1862
|
const db = c.env.DB;
|
|
1851
1863
|
const queryParams = c.req.query();
|
|
1852
|
-
const record =
|
|
1864
|
+
const record = chunkQCJHCSOK_cjs.getCollectionRegistry().getBySlugOrName(collection);
|
|
1853
1865
|
if (!record || record.isActive === false) {
|
|
1854
1866
|
return c.json({ error: "Collection not found" }, 404);
|
|
1855
1867
|
}
|
|
@@ -1905,7 +1917,7 @@ apiRoutes.get("/collections/:collection/content", chunkFTXGZ3BF_cjs.optionalAuth
|
|
|
1905
1917
|
const responseData = {
|
|
1906
1918
|
data: transformedResults,
|
|
1907
1919
|
meta: addTimingMeta(c, {
|
|
1908
|
-
...includeCollection ? { collection:
|
|
1920
|
+
...includeCollection ? { collection: chunkQCJHCSOK_cjs.collectionRecordToRow(record) } : {},
|
|
1909
1921
|
count: results.length,
|
|
1910
1922
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1911
1923
|
// D44: echo the caller's filter with the access policy applied (status=published forced for
|
|
@@ -1930,13 +1942,13 @@ apiRoutes.get("/collections/:collection/content", chunkFTXGZ3BF_cjs.optionalAuth
|
|
|
1930
1942
|
}
|
|
1931
1943
|
});
|
|
1932
1944
|
apiRoutes.route("/content", api_content_crud_default);
|
|
1933
|
-
apiRoutes.get("/:collection",
|
|
1945
|
+
apiRoutes.get("/:collection", chunk37V3RET3_cjs.optionalAuth(), async (c) => {
|
|
1934
1946
|
const executionStart = Date.now();
|
|
1935
1947
|
try {
|
|
1936
1948
|
const collection = c.req.param("collection");
|
|
1937
1949
|
const db = c.env.DB;
|
|
1938
1950
|
const queryParams = c.req.query();
|
|
1939
|
-
const record =
|
|
1951
|
+
const record = chunkQCJHCSOK_cjs.getCollectionRegistry().getBySlugOrName(collection);
|
|
1940
1952
|
if (!record || record.isActive === false) {
|
|
1941
1953
|
return c.json({ error: "Collection not found" }, 404);
|
|
1942
1954
|
}
|
|
@@ -1976,7 +1988,7 @@ apiRoutes.get("/:collection", chunkFTXGZ3BF_cjs.optionalAuth(), async (c) => {
|
|
|
1976
1988
|
const responseData = {
|
|
1977
1989
|
data: transformedResults,
|
|
1978
1990
|
meta: addTimingMeta(c, {
|
|
1979
|
-
...includeCollection ? { collection:
|
|
1991
|
+
...includeCollection ? { collection: chunkQCJHCSOK_cjs.collectionRecordToRow(record) } : {},
|
|
1980
1992
|
count: results.length,
|
|
1981
1993
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1982
1994
|
filter: normalizePublicContentFilter(filter, role),
|
|
@@ -1994,12 +2006,12 @@ apiRoutes.get("/:collection", chunkFTXGZ3BF_cjs.optionalAuth(), async (c) => {
|
|
|
1994
2006
|
return c.json({ error: "Failed to fetch content", details: error instanceof Error ? error.message : String(error) }, 500);
|
|
1995
2007
|
}
|
|
1996
2008
|
});
|
|
1997
|
-
apiRoutes.get("/:collection/:id",
|
|
2009
|
+
apiRoutes.get("/:collection/:id", chunk37V3RET3_cjs.optionalAuth(), async (c) => {
|
|
1998
2010
|
try {
|
|
1999
2011
|
const collection = c.req.param("collection");
|
|
2000
2012
|
const id = c.req.param("id");
|
|
2001
2013
|
const db = c.env.DB;
|
|
2002
|
-
const record =
|
|
2014
|
+
const record = chunkQCJHCSOK_cjs.getCollectionRegistry().getBySlugOrName(collection);
|
|
2003
2015
|
if (!record || record.isActive === false) {
|
|
2004
2016
|
return c.json({ error: "Collection not found" }, 404);
|
|
2005
2017
|
}
|
|
@@ -2008,7 +2020,7 @@ apiRoutes.get("/:collection/:id", chunkFTXGZ3BF_cjs.optionalAuth(), async (c) =>
|
|
|
2008
2020
|
privileged ? "SELECT * FROM documents WHERE root_id = ? AND type_id = ? AND tenant_id = 'default' AND is_current_draft = 1 AND deleted_at IS NULL" : "SELECT * FROM documents WHERE root_id = ? AND type_id = ? AND tenant_id = 'default' AND is_published = 1 AND deleted_at IS NULL"
|
|
2009
2021
|
).bind(id, record.name).first();
|
|
2010
2022
|
if (!docRow) return c.json({ error: "Content not found" }, 404);
|
|
2011
|
-
const coll =
|
|
2023
|
+
const coll = chunkQCJHCSOK_cjs.getCollectionRegistry().getByName(docRow.type_id);
|
|
2012
2024
|
const transformedContent = {
|
|
2013
2025
|
id: docRow.root_id,
|
|
2014
2026
|
title: docRow.title,
|
|
@@ -2026,7 +2038,7 @@ apiRoutes.get("/:collection/:id", chunkFTXGZ3BF_cjs.optionalAuth(), async (c) =>
|
|
|
2026
2038
|
return c.json({ error: "Failed to fetch content", details: error instanceof Error ? error.message : String(error) }, 500);
|
|
2027
2039
|
}
|
|
2028
2040
|
});
|
|
2029
|
-
apiRoutes.post("/:collection",
|
|
2041
|
+
apiRoutes.post("/:collection", chunk37V3RET3_cjs.requireAuth(), chunk37V3RET3_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
|
|
2030
2042
|
try {
|
|
2031
2043
|
const collection = c.req.param("collection");
|
|
2032
2044
|
const db = c.env.DB;
|
|
@@ -2059,14 +2071,14 @@ apiRoutes.post("/:collection", chunkFTXGZ3BF_cjs.requireAuth(), chunkFTXGZ3BF_cj
|
|
|
2059
2071
|
return c.json({ error: "Failed to create content", details: error instanceof Error ? error.message : String(error) }, 500);
|
|
2060
2072
|
}
|
|
2061
2073
|
});
|
|
2062
|
-
apiRoutes.put("/:collection/:id",
|
|
2074
|
+
apiRoutes.put("/:collection/:id", chunk37V3RET3_cjs.requireAuth(), chunk37V3RET3_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
|
|
2063
2075
|
try {
|
|
2064
2076
|
const collection = c.req.param("collection");
|
|
2065
2077
|
const id = c.req.param("id");
|
|
2066
2078
|
const db = c.env.DB;
|
|
2067
2079
|
const user = c.get("user");
|
|
2068
2080
|
const body = await c.req.json();
|
|
2069
|
-
const collRecord =
|
|
2081
|
+
const collRecord = chunkQCJHCSOK_cjs.getCollectionRegistry().getBySlugOrName(collection);
|
|
2070
2082
|
const typeName = collRecord?.name ?? collection;
|
|
2071
2083
|
const docRow = await db.prepare("SELECT root_id, type_id FROM documents WHERE root_id = ? AND type_id = ? AND tenant_id = 'default' AND is_current_draft = 1 AND deleted_at IS NULL").bind(id, typeName).first();
|
|
2072
2084
|
if (!docRow) return c.json({ error: "Content not found" }, 404);
|
|
@@ -2078,7 +2090,7 @@ apiRoutes.put("/:collection/:id", chunkFTXGZ3BF_cjs.requireAuth(), chunkFTXGZ3BF
|
|
|
2078
2090
|
} catch (err) {
|
|
2079
2091
|
return c.json({ error: "Write cancelled by plugin", details: String(err) }, 400);
|
|
2080
2092
|
}
|
|
2081
|
-
const docType = await new
|
|
2093
|
+
const docType = await new chunk37V3RET3_cjs.DocumentTypeRegistry(db).findById(docRow.type_id);
|
|
2082
2094
|
const svc = new chunkLTZ5WYOK_cjs.DocumentsService(db, { queryableFields: docType?.queryableFields ?? [], typeSchemaVersion: docType?.schemaVersion ?? 1, maxVersionsPerRoot: docType?.settings?.maxVersionsPerRoot ?? 50, tenantId: "default", versioning: docType?.settings?.versioning ?? false });
|
|
2083
2095
|
const input = {};
|
|
2084
2096
|
if (body.title !== void 0) input.title = body.title;
|
|
@@ -2095,7 +2107,7 @@ apiRoutes.put("/:collection/:id", chunkFTXGZ3BF_cjs.requireAuth(), chunkFTXGZ3BF
|
|
|
2095
2107
|
const cache = chunk36Z3AKX3_cjs.getCacheService(chunk36Z3AKX3_cjs.CACHE_CONFIGS.api);
|
|
2096
2108
|
await cache.invalidate("content-filtered:*");
|
|
2097
2109
|
await cache.invalidate("collection-content-filtered:*");
|
|
2098
|
-
const coll =
|
|
2110
|
+
const coll = chunkQCJHCSOK_cjs.getCollectionRegistry().getByName(docRow.type_id);
|
|
2099
2111
|
const saved = await db.prepare("SELECT * FROM documents WHERE id = ?").bind(newDraft.id).first();
|
|
2100
2112
|
const savedData = saved?.data ? JSON.parse(saved.data) : {};
|
|
2101
2113
|
dispatchHookEvent(c, "content:after:update", { collection: docRow.type_id, id, data: savedData, user: actor }, "fire-and-forget");
|
|
@@ -2107,13 +2119,13 @@ apiRoutes.put("/:collection/:id", chunkFTXGZ3BF_cjs.requireAuth(), chunkFTXGZ3BF
|
|
|
2107
2119
|
return c.json({ error: "Failed to update content", details: error instanceof Error ? error.message : String(error) }, 500);
|
|
2108
2120
|
}
|
|
2109
2121
|
});
|
|
2110
|
-
apiRoutes.delete("/:collection/:id",
|
|
2122
|
+
apiRoutes.delete("/:collection/:id", chunk37V3RET3_cjs.requireAuth(), chunk37V3RET3_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
|
|
2111
2123
|
try {
|
|
2112
2124
|
const collection = c.req.param("collection");
|
|
2113
2125
|
const id = c.req.param("id");
|
|
2114
2126
|
const db = c.env.DB;
|
|
2115
2127
|
const user = c.get("user");
|
|
2116
|
-
const collRecord =
|
|
2128
|
+
const collRecord = chunkQCJHCSOK_cjs.getCollectionRegistry().getBySlugOrName(collection);
|
|
2117
2129
|
const typeName = collRecord?.name ?? collection;
|
|
2118
2130
|
const docRow = await db.prepare("SELECT type_id FROM documents WHERE root_id = ? AND type_id = ? AND tenant_id = 'default' AND deleted_at IS NULL LIMIT 1").bind(id, typeName).first();
|
|
2119
2131
|
if (!docRow) return c.json({ error: "Content not found" }, 404);
|
|
@@ -2335,7 +2347,7 @@ var fileValidationSchema = zod.z.object({
|
|
|
2335
2347
|
// 50MB max
|
|
2336
2348
|
});
|
|
2337
2349
|
var apiMediaRoutes = new hono.Hono();
|
|
2338
|
-
apiMediaRoutes.use("*",
|
|
2350
|
+
apiMediaRoutes.use("*", chunk37V3RET3_cjs.requireAuth());
|
|
2339
2351
|
apiMediaRoutes.post("/upload", async (c) => {
|
|
2340
2352
|
try {
|
|
2341
2353
|
const user = c.get("user");
|
|
@@ -3033,7 +3045,7 @@ apiSystemRoutes.get("/info", (c) => {
|
|
|
3033
3045
|
apiSystemRoutes.get("/stats", async (c) => {
|
|
3034
3046
|
try {
|
|
3035
3047
|
const db = c.env.DB;
|
|
3036
|
-
const typeIds =
|
|
3048
|
+
const typeIds = chunkQCJHCSOK_cjs.getCollectionRegistry().listActive().filter((r) => !r.internal).map((r) => r.name);
|
|
3037
3049
|
let contentStats = null;
|
|
3038
3050
|
if (typeIds.length > 0) {
|
|
3039
3051
|
const placeholders = typeIds.map(() => "?").join(",");
|
|
@@ -3108,12 +3120,12 @@ apiSystemRoutes.get("/env", (c) => {
|
|
|
3108
3120
|
});
|
|
3109
3121
|
var api_system_default = apiSystemRoutes;
|
|
3110
3122
|
var adminApiRoutes = new hono.Hono();
|
|
3111
|
-
adminApiRoutes.use("*",
|
|
3112
|
-
adminApiRoutes.use("*",
|
|
3123
|
+
adminApiRoutes.use("*", chunk37V3RET3_cjs.requireAuth());
|
|
3124
|
+
adminApiRoutes.use("*", chunk37V3RET3_cjs.requireRole(["admin", "editor"]));
|
|
3113
3125
|
adminApiRoutes.get("/stats", async (c) => {
|
|
3114
3126
|
try {
|
|
3115
3127
|
const db = c.env.DB;
|
|
3116
|
-
const userCollections =
|
|
3128
|
+
const userCollections = chunkQCJHCSOK_cjs.getCollectionRegistry().listActive().filter((r) => !r.internal);
|
|
3117
3129
|
const collectionsCount = userCollections.length;
|
|
3118
3130
|
let contentCount = 0;
|
|
3119
3131
|
if (userCollections.length > 0) {
|
|
@@ -3204,7 +3216,7 @@ adminApiRoutes.get("/collections", async (c) => {
|
|
|
3204
3216
|
try {
|
|
3205
3217
|
const search = c.req.query("search") || "";
|
|
3206
3218
|
const includeInactive = c.req.query("includeInactive") === "true";
|
|
3207
|
-
let records =
|
|
3219
|
+
let records = chunkQCJHCSOK_cjs.getCollectionRegistry().list().filter((r) => !r.internal);
|
|
3208
3220
|
if (!includeInactive) records = records.filter((r) => r.isActive !== false);
|
|
3209
3221
|
if (search) {
|
|
3210
3222
|
const needle = search.toLowerCase();
|
|
@@ -3236,7 +3248,7 @@ adminApiRoutes.get("/collections", async (c) => {
|
|
|
3236
3248
|
adminApiRoutes.get("/collections/:id", async (c) => {
|
|
3237
3249
|
try {
|
|
3238
3250
|
const id = c.req.param("id");
|
|
3239
|
-
const registry =
|
|
3251
|
+
const registry = chunkQCJHCSOK_cjs.getCollectionRegistry();
|
|
3240
3252
|
const record = registry.getById(id) ?? registry.getByName(id);
|
|
3241
3253
|
if (!record) {
|
|
3242
3254
|
return c.json({ error: "Collection not found" }, 404);
|
|
@@ -3286,7 +3298,7 @@ adminApiRoutes.get("/references", async (c) => {
|
|
|
3286
3298
|
if (collectionParams.length === 0) {
|
|
3287
3299
|
return c.json({ error: "Collection is required" }, 400);
|
|
3288
3300
|
}
|
|
3289
|
-
const registry =
|
|
3301
|
+
const registry = chunkQCJHCSOK_cjs.getCollectionRegistry();
|
|
3290
3302
|
const matched = collectionParams.map((param) => registry.getById(param) ?? registry.getByName(param)).filter((r) => !!r);
|
|
3291
3303
|
const seen = /* @__PURE__ */ new Set();
|
|
3292
3304
|
const collections = matched.filter((r) => {
|
|
@@ -3401,7 +3413,7 @@ adminApiRoutes.patch("/collections/:id", collectionsReadOnly);
|
|
|
3401
3413
|
adminApiRoutes.delete("/collections/:id", collectionsReadOnly);
|
|
3402
3414
|
adminApiRoutes.get("/migrations/status", async (c) => {
|
|
3403
3415
|
try {
|
|
3404
|
-
const { MigrationService: MigrationService2 } = await import('./migrations-
|
|
3416
|
+
const { MigrationService: MigrationService2 } = await import('./migrations-FGXZPKDC.cjs');
|
|
3405
3417
|
const db = c.env.DB;
|
|
3406
3418
|
const migrationService = new MigrationService2(db);
|
|
3407
3419
|
const status = await migrationService.getMigrationStatus();
|
|
@@ -3444,7 +3456,7 @@ adminApiRoutes.post("/migrations/run", async (c) => {
|
|
|
3444
3456
|
});
|
|
3445
3457
|
adminApiRoutes.get("/migrations/validate", async (c) => {
|
|
3446
3458
|
try {
|
|
3447
|
-
const { MigrationService: MigrationService2 } = await import('./migrations-
|
|
3459
|
+
const { MigrationService: MigrationService2 } = await import('./migrations-FGXZPKDC.cjs');
|
|
3448
3460
|
const db = c.env.DB;
|
|
3449
3461
|
const migrationService = new MigrationService2(db);
|
|
3450
3462
|
const validation = await migrationService.validateSchema();
|
|
@@ -3594,8 +3606,8 @@ function renderLoginPage(data, demoLoginActive = false) {
|
|
|
3594
3606
|
<div class="mt-8 sm:mx-auto sm:w-full sm:max-w-md">
|
|
3595
3607
|
<div class="bg-zinc-900 shadow-sm ring-1 ring-white/10 rounded-xl px-6 py-8 sm:px-10">
|
|
3596
3608
|
<!-- Alerts -->
|
|
3597
|
-
${data.error ? `<div class="mb-6">${
|
|
3598
|
-
${data.message ? `<div class="mb-6">${
|
|
3609
|
+
${data.error ? `<div class="mb-6">${chunkE66UVONV_cjs.renderAlert({ type: "error", message: data.error })}</div>` : ""}
|
|
3610
|
+
${data.message ? `<div class="mb-6">${chunkE66UVONV_cjs.renderAlert({ type: "success", message: data.message })}</div>` : ""}
|
|
3599
3611
|
|
|
3600
3612
|
<!-- Form Response (HTMX target) -->
|
|
3601
3613
|
<div id="form-response" class="mb-6"></div>
|
|
@@ -3759,7 +3771,7 @@ function renderRegisterPage(data) {
|
|
|
3759
3771
|
<div class="mt-8 sm:mx-auto sm:w-full sm:max-w-md">
|
|
3760
3772
|
<div class="bg-zinc-900 shadow-sm ring-1 ring-white/10 rounded-xl px-6 py-8 sm:px-10">
|
|
3761
3773
|
<!-- Alerts -->
|
|
3762
|
-
${data.error ? `<div class="mb-6">${
|
|
3774
|
+
${data.error ? `<div class="mb-6">${chunkE66UVONV_cjs.renderAlert({ type: "error", message: data.error })}</div>` : ""}
|
|
3763
3775
|
|
|
3764
3776
|
<!-- Form -->
|
|
3765
3777
|
<form
|
|
@@ -3859,7 +3871,7 @@ function renderRegisterPage(data) {
|
|
|
3859
3871
|
}
|
|
3860
3872
|
|
|
3861
3873
|
// src/services/email/email-service-singleton.ts
|
|
3862
|
-
var singleton =
|
|
3874
|
+
var singleton = chunkBP52BFIV_cjs.createServiceSingleton("EmailService");
|
|
3863
3875
|
function setEmailService(service2) {
|
|
3864
3876
|
singleton.set(service2);
|
|
3865
3877
|
}
|
|
@@ -4667,7 +4679,7 @@ function getLexicalInitScript(settings = {}) {
|
|
|
4667
4679
|
</script>
|
|
4668
4680
|
`;
|
|
4669
4681
|
}
|
|
4670
|
-
var lexicalEditorPlugin =
|
|
4682
|
+
var lexicalEditorPlugin = chunkBP52BFIV_cjs.definePlugin({
|
|
4671
4683
|
id: "lexical-editor",
|
|
4672
4684
|
version: "1.0.0",
|
|
4673
4685
|
name: "Lexical Editor",
|
|
@@ -7073,7 +7085,7 @@ api.put("/:userId", async (c) => {
|
|
|
7073
7085
|
await saveCustomData(db, userId, sanitized);
|
|
7074
7086
|
return c.json({ success: true });
|
|
7075
7087
|
});
|
|
7076
|
-
var userProfilesPlugin =
|
|
7088
|
+
var userProfilesPlugin = chunkBP52BFIV_cjs.definePlugin({
|
|
7077
7089
|
id: "user-profiles",
|
|
7078
7090
|
version: "1.0.0",
|
|
7079
7091
|
name: "User Profiles",
|
|
@@ -7111,8 +7123,8 @@ function renderPasswordResetEmail(resetLink, firstName) {
|
|
|
7111
7123
|
async function setCsrfCookie(c, maxAge) {
|
|
7112
7124
|
const secret = c.env?.JWT_SECRET || JWT_SECRET_FALLBACK;
|
|
7113
7125
|
const isDev = c.env?.ENVIRONMENT === "development" || !c.env?.ENVIRONMENT;
|
|
7114
|
-
const csrfToken = await
|
|
7115
|
-
const cookieMaxAge = await
|
|
7126
|
+
const csrfToken = await chunk37V3RET3_cjs.generateCsrfToken(secret);
|
|
7127
|
+
const cookieMaxAge = await chunk37V3RET3_cjs.getJwtExpirySecondsFromDb(c.env?.DB, c.env);
|
|
7116
7128
|
cookie.setCookie(c, "csrf_token", csrfToken, {
|
|
7117
7129
|
httpOnly: false,
|
|
7118
7130
|
secure: !isDev,
|
|
@@ -7171,7 +7183,7 @@ var loginSchema = zod.z.object({
|
|
|
7171
7183
|
});
|
|
7172
7184
|
authRoutes.post(
|
|
7173
7185
|
"/register",
|
|
7174
|
-
|
|
7186
|
+
chunk37V3RET3_cjs.rateLimit({ max: 30, windowMs: 60 * 1e3, keyPrefix: "register" }),
|
|
7175
7187
|
async (c) => {
|
|
7176
7188
|
try {
|
|
7177
7189
|
const db = c.env.DB;
|
|
@@ -7207,7 +7219,7 @@ authRoutes.post(
|
|
|
7207
7219
|
if (existingUser) {
|
|
7208
7220
|
return c.json({ error: "User with this email already exists" }, 400);
|
|
7209
7221
|
}
|
|
7210
|
-
const passwordHash = await
|
|
7222
|
+
const passwordHash = await chunk37V3RET3_cjs.AuthManager.hashPassword(password);
|
|
7211
7223
|
const userId = crypto.randomUUID();
|
|
7212
7224
|
const now = /* @__PURE__ */ new Date();
|
|
7213
7225
|
const nowSec = Math.floor(now.getTime() / 1e3);
|
|
@@ -7240,8 +7252,8 @@ authRoutes.post(
|
|
|
7240
7252
|
{ user: { id: userId, email: normalizedEmail, role: "viewer" } },
|
|
7241
7253
|
"fire-and-forget"
|
|
7242
7254
|
);
|
|
7243
|
-
const tokenTtl = await
|
|
7244
|
-
const token = await
|
|
7255
|
+
const tokenTtl = await chunk37V3RET3_cjs.getJwtExpirySecondsFromDb(c.env.DB, c.env);
|
|
7256
|
+
const token = await chunk37V3RET3_cjs.AuthManager.generateToken(userId, normalizedEmail, "viewer", c.env.JWT_SECRET, tokenTtl);
|
|
7245
7257
|
cookie.setCookie(c, "auth_token", token, {
|
|
7246
7258
|
httpOnly: true,
|
|
7247
7259
|
secure: true,
|
|
@@ -7273,7 +7285,7 @@ authRoutes.post(
|
|
|
7273
7285
|
);
|
|
7274
7286
|
authRoutes.post(
|
|
7275
7287
|
"/login",
|
|
7276
|
-
|
|
7288
|
+
chunk37V3RET3_cjs.rateLimit({ max: 30, windowMs: 60 * 1e3, keyPrefix: "login" }),
|
|
7277
7289
|
async (c) => {
|
|
7278
7290
|
try {
|
|
7279
7291
|
const body = await c.req.json();
|
|
@@ -7305,8 +7317,8 @@ authRoutes.post(
|
|
|
7305
7317
|
await setCsrfCookie(c);
|
|
7306
7318
|
const baBody = await baRes.json();
|
|
7307
7319
|
const user = baBody.user ?? {};
|
|
7308
|
-
const tokenTtl = await
|
|
7309
|
-
const token = await
|
|
7320
|
+
const tokenTtl = await chunk37V3RET3_cjs.getJwtExpirySecondsFromDb(c.env.DB, c.env);
|
|
7321
|
+
const token = await chunk37V3RET3_cjs.AuthManager.generateToken(
|
|
7310
7322
|
user.id,
|
|
7311
7323
|
user.email,
|
|
7312
7324
|
user.role ?? "viewer",
|
|
@@ -7367,7 +7379,7 @@ authRoutes.get("/logout", async (c) => {
|
|
|
7367
7379
|
clearCsrfCookie(c);
|
|
7368
7380
|
return c.redirect("/auth/login?message=You have been logged out successfully");
|
|
7369
7381
|
});
|
|
7370
|
-
authRoutes.get("/me",
|
|
7382
|
+
authRoutes.get("/me", chunk37V3RET3_cjs.requireAuth(), async (c) => {
|
|
7371
7383
|
try {
|
|
7372
7384
|
const user = c.get("user");
|
|
7373
7385
|
if (!user) {
|
|
@@ -7387,7 +7399,7 @@ authRoutes.get("/me", chunkFTXGZ3BF_cjs.requireAuth(), async (c) => {
|
|
|
7387
7399
|
});
|
|
7388
7400
|
authRoutes.post(
|
|
7389
7401
|
"/refresh",
|
|
7390
|
-
|
|
7402
|
+
chunk37V3RET3_cjs.rateLimit({ max: 60, windowMs: 60 * 1e3, keyPrefix: "refresh" }),
|
|
7391
7403
|
async (c) => {
|
|
7392
7404
|
try {
|
|
7393
7405
|
let token = c.req.header("Authorization")?.replace("Bearer ", "");
|
|
@@ -7396,8 +7408,8 @@ authRoutes.post(
|
|
|
7396
7408
|
return c.json({ error: "Authentication required" }, 401);
|
|
7397
7409
|
}
|
|
7398
7410
|
const db = c.env.DB;
|
|
7399
|
-
const grace = await
|
|
7400
|
-
const payload = await
|
|
7411
|
+
const grace = await chunk37V3RET3_cjs.getJwtRefreshGraceSecondsFromDb(db, c.env);
|
|
7412
|
+
const payload = await chunk37V3RET3_cjs.AuthManager.verifyToken(token, c.env.JWT_SECRET, grace);
|
|
7401
7413
|
if (!payload) {
|
|
7402
7414
|
return c.json({ error: "Invalid or expired token" }, 401);
|
|
7403
7415
|
}
|
|
@@ -7405,8 +7417,8 @@ authRoutes.post(
|
|
|
7405
7417
|
if (!row || !row.is_active) {
|
|
7406
7418
|
return c.json({ error: "User is not active" }, 401);
|
|
7407
7419
|
}
|
|
7408
|
-
const tokenTtl = await
|
|
7409
|
-
const newToken = await
|
|
7420
|
+
const tokenTtl = await chunk37V3RET3_cjs.getJwtExpirySecondsFromDb(db, c.env);
|
|
7421
|
+
const newToken = await chunk37V3RET3_cjs.AuthManager.generateToken(row.id, row.email, row.role, c.env.JWT_SECRET, tokenTtl);
|
|
7410
7422
|
cookie.setCookie(c, "auth_token", newToken, {
|
|
7411
7423
|
httpOnly: true,
|
|
7412
7424
|
secure: true,
|
|
@@ -7426,7 +7438,7 @@ authRoutes.post(
|
|
|
7426
7438
|
);
|
|
7427
7439
|
authRoutes.post(
|
|
7428
7440
|
"/register/form",
|
|
7429
|
-
|
|
7441
|
+
chunk37V3RET3_cjs.rateLimit({ max: 30, windowMs: 60 * 1e3, keyPrefix: "register" }),
|
|
7430
7442
|
async (c) => {
|
|
7431
7443
|
try {
|
|
7432
7444
|
const db = c.env.DB;
|
|
@@ -7471,7 +7483,7 @@ authRoutes.post(
|
|
|
7471
7483
|
</div>
|
|
7472
7484
|
`);
|
|
7473
7485
|
}
|
|
7474
|
-
const passwordHash = await
|
|
7486
|
+
const passwordHash = await chunk37V3RET3_cjs.AuthManager.hashPassword(password);
|
|
7475
7487
|
const role = isFirstUser ? "admin" : "viewer";
|
|
7476
7488
|
const userId = crypto.randomUUID();
|
|
7477
7489
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -7513,8 +7525,8 @@ authRoutes.post(
|
|
|
7513
7525
|
{ user: { id: userId, email: normalizedEmail, role } },
|
|
7514
7526
|
"fire-and-forget"
|
|
7515
7527
|
);
|
|
7516
|
-
const tokenTtl = await
|
|
7517
|
-
const token = await
|
|
7528
|
+
const tokenTtl = await chunk37V3RET3_cjs.getJwtExpirySecondsFromDb(c.env.DB, c.env);
|
|
7529
|
+
const token = await chunk37V3RET3_cjs.AuthManager.generateToken(userId, normalizedEmail, role, c.env.JWT_SECRET, tokenTtl);
|
|
7518
7530
|
cookie.setCookie(c, "auth_token", token, {
|
|
7519
7531
|
httpOnly: true,
|
|
7520
7532
|
secure: false,
|
|
@@ -7546,7 +7558,7 @@ authRoutes.post(
|
|
|
7546
7558
|
);
|
|
7547
7559
|
authRoutes.post(
|
|
7548
7560
|
"/login/form",
|
|
7549
|
-
|
|
7561
|
+
chunk37V3RET3_cjs.rateLimit({ max: 30, windowMs: 60 * 1e3, keyPrefix: "login" }),
|
|
7550
7562
|
async (c) => {
|
|
7551
7563
|
try {
|
|
7552
7564
|
const formData = await c.req.formData();
|
|
@@ -7615,14 +7627,14 @@ authRoutes.post(
|
|
|
7615
7627
|
);
|
|
7616
7628
|
authRoutes.post(
|
|
7617
7629
|
"/seed-admin",
|
|
7618
|
-
|
|
7630
|
+
chunk37V3RET3_cjs.rateLimit({ max: 10, windowMs: 60 * 1e3, keyPrefix: "seed-admin" }),
|
|
7619
7631
|
async (c) => {
|
|
7620
7632
|
try {
|
|
7621
7633
|
const db = c.env.DB;
|
|
7622
7634
|
const rbac = new chunkLTZ5WYOK_cjs.RbacService(db);
|
|
7623
7635
|
const results = [];
|
|
7624
7636
|
const upsertSeedUser = async (opts) => {
|
|
7625
|
-
const passwordHash = await
|
|
7637
|
+
const passwordHash = await chunk37V3RET3_cjs.AuthManager.hashPassword(opts.password);
|
|
7626
7638
|
const nowMs = Date.now();
|
|
7627
7639
|
const nowSec = Math.floor(nowMs / 1e3);
|
|
7628
7640
|
const existing = await db.prepare("SELECT id FROM auth_user WHERE email = ?").bind(opts.email).first();
|
|
@@ -7847,7 +7859,7 @@ authRoutes.post("/accept-invitation", async (c) => {
|
|
|
7847
7859
|
if (invitationAge > maxAge) {
|
|
7848
7860
|
return c.json({ error: "Invitation has expired" }, 400);
|
|
7849
7861
|
}
|
|
7850
|
-
const passwordHash = await
|
|
7862
|
+
const passwordHash = await chunk37V3RET3_cjs.AuthManager.hashPassword(password);
|
|
7851
7863
|
const updateStmt = db.prepare(`
|
|
7852
7864
|
UPDATE auth_user SET
|
|
7853
7865
|
password_hash = ?,
|
|
@@ -7864,8 +7876,8 @@ authRoutes.post("/accept-invitation", async (c) => {
|
|
|
7864
7876
|
Date.now(),
|
|
7865
7877
|
invitedUser.id
|
|
7866
7878
|
).run();
|
|
7867
|
-
const tokenTtl = await
|
|
7868
|
-
const authToken = await
|
|
7879
|
+
const tokenTtl = await chunk37V3RET3_cjs.getJwtExpirySecondsFromDb(c.env.DB, c.env);
|
|
7880
|
+
const authToken = await chunk37V3RET3_cjs.AuthManager.generateToken(invitedUser.id, invitedUser.email, invitedUser.role, c.env.JWT_SECRET, tokenTtl);
|
|
7869
7881
|
cookie.setCookie(c, "auth_token", authToken, {
|
|
7870
7882
|
httpOnly: true,
|
|
7871
7883
|
secure: true,
|
|
@@ -7881,7 +7893,7 @@ authRoutes.post("/accept-invitation", async (c) => {
|
|
|
7881
7893
|
});
|
|
7882
7894
|
authRoutes.post(
|
|
7883
7895
|
"/request-password-reset",
|
|
7884
|
-
|
|
7896
|
+
chunk37V3RET3_cjs.rateLimit({ max: 3, windowMs: 15 * 60 * 1e3, keyPrefix: "password-reset" }),
|
|
7885
7897
|
async (c) => {
|
|
7886
7898
|
try {
|
|
7887
7899
|
const formData = await c.req.formData();
|
|
@@ -8118,7 +8130,7 @@ authRoutes.post("/reset-password", async (c) => {
|
|
|
8118
8130
|
if (Date.now() > user.password_reset_expires) {
|
|
8119
8131
|
return c.json({ error: "Reset token has expired" }, 400);
|
|
8120
8132
|
}
|
|
8121
|
-
const newPasswordHash = await
|
|
8133
|
+
const newPasswordHash = await chunk37V3RET3_cjs.AuthManager.hashPassword(password);
|
|
8122
8134
|
try {
|
|
8123
8135
|
const historyStmt = db.prepare(`
|
|
8124
8136
|
INSERT INTO auth_password_history (id, user_id, password_hash, created_at)
|
|
@@ -8332,7 +8344,7 @@ app.post("/test-seed-defaults", async (c) => {
|
|
|
8332
8344
|
var test_cleanup_default = app;
|
|
8333
8345
|
|
|
8334
8346
|
// src/plugins/available/easy-mdx/index.ts
|
|
8335
|
-
|
|
8347
|
+
chunkBP52BFIV_cjs.definePlugin({
|
|
8336
8348
|
id: "easy-mdx",
|
|
8337
8349
|
version: "1.0.0",
|
|
8338
8350
|
name: "EasyMDE Markdown Editor",
|
|
@@ -8532,7 +8544,7 @@ function getMDXEditorInitScript(config) {
|
|
|
8532
8544
|
}
|
|
8533
8545
|
|
|
8534
8546
|
// src/plugins/available/tinymce-plugin/index.ts
|
|
8535
|
-
|
|
8547
|
+
chunkBP52BFIV_cjs.definePlugin({
|
|
8536
8548
|
id: "tinymce-plugin",
|
|
8537
8549
|
version: "1.0.0",
|
|
8538
8550
|
name: "TinyMCE",
|
|
@@ -8802,7 +8814,7 @@ function getQuillCDN(version = "2.0.2") {
|
|
|
8802
8814
|
</style>
|
|
8803
8815
|
`;
|
|
8804
8816
|
}
|
|
8805
|
-
|
|
8817
|
+
chunkBP52BFIV_cjs.definePlugin({
|
|
8806
8818
|
id: "quill-editor",
|
|
8807
8819
|
version: "1.0.0",
|
|
8808
8820
|
name: "Quill Editor",
|
|
@@ -8814,7 +8826,7 @@ chunkEUJAEB6W_cjs.definePlugin({
|
|
|
8814
8826
|
});
|
|
8815
8827
|
|
|
8816
8828
|
// src/templates/pages/admin-content-form.template.ts
|
|
8817
|
-
|
|
8829
|
+
chunkUYJQDDEE_cjs.init_admin_layout_catalyst_template();
|
|
8818
8830
|
function renderContentFormPage(data, opts) {
|
|
8819
8831
|
const isEdit = data.isEdit || !!data.id;
|
|
8820
8832
|
const title = isEdit ? `Edit: ${data.title || "Content"}` : `New ${data.collection.display_name}`;
|
|
@@ -8896,8 +8908,8 @@ function renderContentFormPage(data, opts) {
|
|
|
8896
8908
|
<!-- Form Content -->
|
|
8897
8909
|
<div class="px-6 py-6">
|
|
8898
8910
|
<div id="form-messages">
|
|
8899
|
-
${data.error ?
|
|
8900
|
-
${data.success ?
|
|
8911
|
+
${data.error ? chunkE66UVONV_cjs.renderAlert({ type: "error", message: data.error, dismissible: true }) : ""}
|
|
8912
|
+
${data.success ? chunkE66UVONV_cjs.renderAlert({ type: "success", message: data.success, dismissible: true }) : ""}
|
|
8901
8913
|
</div>
|
|
8902
8914
|
|
|
8903
8915
|
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
|
@@ -9010,20 +9022,20 @@ function renderContentFormPage(data, opts) {
|
|
|
9010
9022
|
<dl class="space-y-3 text-sm">
|
|
9011
9023
|
<div>
|
|
9012
9024
|
<dt class="text-zinc-500 dark:text-zinc-400">Created</dt>
|
|
9013
|
-
<dd class="mt-1 text-zinc-950 dark:text-white">${data.created_at ? new Date(data.created_at).toLocaleDateString() : "Unknown"}</dd>
|
|
9025
|
+
<dd class="mt-1 text-zinc-950 dark:text-white">${data.created_at ? new Date(data.created_at * 1e3).toLocaleDateString() : "Unknown"}</dd>
|
|
9014
9026
|
</div>
|
|
9015
9027
|
<div>
|
|
9016
9028
|
<dt class="text-zinc-500 dark:text-zinc-400">Last Modified</dt>
|
|
9017
|
-
<dd class="mt-1 text-zinc-950 dark:text-white">${data.updated_at ? new Date(data.updated_at).toLocaleDateString() : "Unknown"}</dd>
|
|
9029
|
+
<dd class="mt-1 text-zinc-950 dark:text-white">${data.updated_at ? new Date(data.updated_at * 1e3).toLocaleDateString() : "Unknown"}</dd>
|
|
9018
9030
|
</div>
|
|
9019
9031
|
<div>
|
|
9020
9032
|
<dt class="text-zinc-500 dark:text-zinc-400">Author</dt>
|
|
9021
|
-
<dd class="mt-1 text-zinc-950 dark:text-white">${data.data?.author || "Unknown"}</dd>
|
|
9033
|
+
<dd class="mt-1 text-zinc-950 dark:text-white">${chunkMNWKYY5E_cjs.escapeHtml(String(data.data?.author || data.author_name || "Unknown"))}</dd>
|
|
9022
9034
|
</div>
|
|
9023
9035
|
${data.published_at ? `
|
|
9024
9036
|
<div>
|
|
9025
9037
|
<dt class="text-zinc-500 dark:text-zinc-400">Published</dt>
|
|
9026
|
-
<dd class="mt-1 text-zinc-950 dark:text-white">${new Date(data.published_at).toLocaleDateString()}</dd>
|
|
9038
|
+
<dd class="mt-1 text-zinc-950 dark:text-white">${new Date(data.published_at * 1e3).toLocaleDateString()}</dd>
|
|
9027
9039
|
</div>
|
|
9028
9040
|
` : ""}
|
|
9029
9041
|
</dl>
|
|
@@ -9133,7 +9145,7 @@ function renderContentFormPage(data, opts) {
|
|
|
9133
9145
|
</div>
|
|
9134
9146
|
|
|
9135
9147
|
<!-- Confirmation Dialogs -->
|
|
9136
|
-
${
|
|
9148
|
+
${chunkE66UVONV_cjs.renderConfirmationDialog({
|
|
9137
9149
|
id: "duplicate-content-confirm",
|
|
9138
9150
|
title: "Duplicate Content",
|
|
9139
9151
|
message: "Create a copy of this content?",
|
|
@@ -9144,7 +9156,7 @@ function renderContentFormPage(data, opts) {
|
|
|
9144
9156
|
onConfirm: "performDuplicateContent()"
|
|
9145
9157
|
})}
|
|
9146
9158
|
|
|
9147
|
-
${
|
|
9159
|
+
${chunkE66UVONV_cjs.renderConfirmationDialog({
|
|
9148
9160
|
id: "delete-content-confirm",
|
|
9149
9161
|
title: "Delete Content",
|
|
9150
9162
|
message: "Are you sure you want to delete this content? This action cannot be undone.",
|
|
@@ -9155,7 +9167,7 @@ function renderContentFormPage(data, opts) {
|
|
|
9155
9167
|
onConfirm: `performDeleteContent('${data.id}')`
|
|
9156
9168
|
})}
|
|
9157
9169
|
|
|
9158
|
-
${
|
|
9170
|
+
${chunkE66UVONV_cjs.renderConfirmationDialog({
|
|
9159
9171
|
id: "delete-repeater-item-confirm",
|
|
9160
9172
|
title: "Delete Item",
|
|
9161
9173
|
message: "Are you sure you want to delete this item? This action cannot be undone.",
|
|
@@ -9166,7 +9178,7 @@ function renderContentFormPage(data, opts) {
|
|
|
9166
9178
|
onConfirm: "performRepeaterDelete()"
|
|
9167
9179
|
})}
|
|
9168
9180
|
|
|
9169
|
-
${
|
|
9181
|
+
${chunkE66UVONV_cjs.renderConfirmationDialog({
|
|
9170
9182
|
id: "delete-block-confirm",
|
|
9171
9183
|
title: "Delete Block",
|
|
9172
9184
|
message: "Are you sure you want to delete this block? This action cannot be undone.",
|
|
@@ -9177,7 +9189,7 @@ function renderContentFormPage(data, opts) {
|
|
|
9177
9189
|
onConfirm: "performRepeaterDelete()"
|
|
9178
9190
|
})}
|
|
9179
9191
|
|
|
9180
|
-
${
|
|
9192
|
+
${chunkE66UVONV_cjs.getConfirmationDialogScript()}
|
|
9181
9193
|
|
|
9182
9194
|
${data.lexicalEnabled ? getLexicalStyles() : "<!-- Lexical plugin not active -->"}
|
|
9183
9195
|
|
|
@@ -10263,11 +10275,11 @@ function renderContentFormPage(data, opts) {
|
|
|
10263
10275
|
content: pageContent,
|
|
10264
10276
|
version: data.version
|
|
10265
10277
|
};
|
|
10266
|
-
return
|
|
10278
|
+
return chunkUYJQDDEE_cjs.renderAdminLayoutCatalyst(layoutData);
|
|
10267
10279
|
}
|
|
10268
10280
|
|
|
10269
10281
|
// src/templates/pages/admin-content-list.template.ts
|
|
10270
|
-
|
|
10282
|
+
chunkUYJQDDEE_cjs.init_admin_layout_catalyst_template();
|
|
10271
10283
|
function renderContentListPage(data) {
|
|
10272
10284
|
const urlParams = new URLSearchParams();
|
|
10273
10285
|
if (data.modelName && data.modelName !== "all") urlParams.set("model", data.modelName);
|
|
@@ -10701,8 +10713,8 @@ function renderContentListPage(data) {
|
|
|
10701
10713
|
|
|
10702
10714
|
<!-- Content List -->
|
|
10703
10715
|
<div id="content-list">
|
|
10704
|
-
${
|
|
10705
|
-
${
|
|
10716
|
+
${chunkE66UVONV_cjs.renderTable(tableData)}
|
|
10717
|
+
${chunkE66UVONV_cjs.renderPagination(paginationData)}
|
|
10706
10718
|
</div>
|
|
10707
10719
|
|
|
10708
10720
|
</div>
|
|
@@ -10912,7 +10924,7 @@ function renderContentListPage(data) {
|
|
|
10912
10924
|
</script>
|
|
10913
10925
|
|
|
10914
10926
|
<!-- Confirmation Dialog for Bulk Actions -->
|
|
10915
|
-
${
|
|
10927
|
+
${chunkE66UVONV_cjs.renderConfirmationDialog({
|
|
10916
10928
|
id: "bulk-action-confirm",
|
|
10917
10929
|
title: "Confirm Bulk Action",
|
|
10918
10930
|
message: "Are you sure you want to perform this action? This operation will affect multiple items.",
|
|
@@ -10924,7 +10936,7 @@ function renderContentListPage(data) {
|
|
|
10924
10936
|
})}
|
|
10925
10937
|
|
|
10926
10938
|
<!-- Confirmation Dialog Script -->
|
|
10927
|
-
${
|
|
10939
|
+
${chunkE66UVONV_cjs.getConfirmationDialogScript()}
|
|
10928
10940
|
|
|
10929
10941
|
<!-- Advanced Search Modal -->
|
|
10930
10942
|
<div id="advancedSearchModal" class="hidden fixed inset-0 z-50 overflow-y-auto" aria-labelledby="modal-title" role="dialog" aria-modal="true">
|
|
@@ -11221,7 +11233,7 @@ function renderContentListPage(data) {
|
|
|
11221
11233
|
version: data.version,
|
|
11222
11234
|
content: pageContent
|
|
11223
11235
|
};
|
|
11224
|
-
return
|
|
11236
|
+
return chunkUYJQDDEE_cjs.renderAdminLayoutCatalyst(layoutData);
|
|
11225
11237
|
}
|
|
11226
11238
|
|
|
11227
11239
|
// src/routes/admin-content-field-types.ts
|
|
@@ -11376,7 +11388,7 @@ function extractFieldData(fields, formData, options = {}) {
|
|
|
11376
11388
|
}
|
|
11377
11389
|
return { data, errors };
|
|
11378
11390
|
}
|
|
11379
|
-
adminContentRoutes.use("*",
|
|
11391
|
+
adminContentRoutes.use("*", chunk37V3RET3_cjs.requireAuth());
|
|
11380
11392
|
async function getCollectionFields(db, collectionId) {
|
|
11381
11393
|
console.log(`[getCollectionFields] Loading fields for collection: ${collectionId}`);
|
|
11382
11394
|
const collectionStmt = db.prepare("SELECT schema, queryable_fields FROM document_types WHERE id = ?");
|
|
@@ -11403,7 +11415,7 @@ async function getCollectionFields(db, collectionId) {
|
|
|
11403
11415
|
};
|
|
11404
11416
|
});
|
|
11405
11417
|
}
|
|
11406
|
-
const codeCollections2 = await
|
|
11418
|
+
const codeCollections2 = await chunkQCJHCSOK_cjs.loadCollectionConfigs();
|
|
11407
11419
|
const codeMatch = codeCollections2.find((c) => c.name === collectionId);
|
|
11408
11420
|
if (codeMatch && codeMatch.schema?.properties) {
|
|
11409
11421
|
console.log(`[getCollectionFields] DB doc type has no properties \u2014 using code collection schema`);
|
|
@@ -11435,7 +11447,7 @@ async function getCollectionFields(db, collectionId) {
|
|
|
11435
11447
|
}
|
|
11436
11448
|
}
|
|
11437
11449
|
console.log(`[getCollectionFields] Not in database, checking code collections`);
|
|
11438
|
-
const codeCollections = await
|
|
11450
|
+
const codeCollections = await chunkQCJHCSOK_cjs.loadCollectionConfigs();
|
|
11439
11451
|
console.log(`[getCollectionFields] Found ${codeCollections.length} code collections`);
|
|
11440
11452
|
const codeCollection = codeCollections.find((c) => c.name === collectionId);
|
|
11441
11453
|
if (codeCollection && codeCollection.schema) {
|
|
@@ -11489,7 +11501,7 @@ async function getCollection(db, collectionId) {
|
|
|
11489
11501
|
};
|
|
11490
11502
|
}
|
|
11491
11503
|
console.log(`[getCollection] Not in database, checking code collections`);
|
|
11492
|
-
const codeCollections = await
|
|
11504
|
+
const codeCollections = await chunkQCJHCSOK_cjs.loadCollectionConfigs();
|
|
11493
11505
|
const codeCollection = codeCollections.find((c) => c.name === collectionId);
|
|
11494
11506
|
if (codeCollection) {
|
|
11495
11507
|
console.log(`[getCollection] Found code collection: ${collectionId}`);
|
|
@@ -11508,7 +11520,7 @@ async function getCollection(db, collectionId) {
|
|
|
11508
11520
|
}
|
|
11509
11521
|
async function getDocBackingType(db, collectionName) {
|
|
11510
11522
|
if (!collectionName) return null;
|
|
11511
|
-
const dt = await new
|
|
11523
|
+
const dt = await new chunk37V3RET3_cjs.DocumentTypeRegistry(db).findById(collectionName);
|
|
11512
11524
|
return dt && dt.isActive ? dt : null;
|
|
11513
11525
|
}
|
|
11514
11526
|
async function getCollectionByName(db, name) {
|
|
@@ -11525,7 +11537,7 @@ async function getCollectionByName(db, name) {
|
|
|
11525
11537
|
};
|
|
11526
11538
|
}
|
|
11527
11539
|
console.log(`[getCollectionByName] Not in database, checking code collections`);
|
|
11528
|
-
const codeCollections = await
|
|
11540
|
+
const codeCollections = await chunkQCJHCSOK_cjs.loadCollectionConfigs();
|
|
11529
11541
|
const codeCollection = codeCollections.find((c) => c.name === name);
|
|
11530
11542
|
if (codeCollection) {
|
|
11531
11543
|
console.log(`[getCollectionByName] Found code collection: ${name}`);
|
|
@@ -11541,7 +11553,7 @@ async function getCollectionByName(db, name) {
|
|
|
11541
11553
|
return null;
|
|
11542
11554
|
}
|
|
11543
11555
|
async function loadContentEditorFlags(db) {
|
|
11544
|
-
const flags = { workflowEnabled: await
|
|
11556
|
+
const flags = { workflowEnabled: await chunk37V3RET3_cjs.isPluginActive(db, "workflow") };
|
|
11545
11557
|
const editors = [
|
|
11546
11558
|
["tinymce-plugin", "tinymce"],
|
|
11547
11559
|
["quill-editor", "quill"],
|
|
@@ -11549,10 +11561,10 @@ async function loadContentEditorFlags(db) {
|
|
|
11549
11561
|
["lexical-editor", "lexical"]
|
|
11550
11562
|
];
|
|
11551
11563
|
for (const [plugin, key] of editors) {
|
|
11552
|
-
const enabled = await
|
|
11564
|
+
const enabled = await chunk37V3RET3_cjs.isPluginActive(db, plugin);
|
|
11553
11565
|
flags[`${key}Enabled`] = enabled;
|
|
11554
11566
|
if (enabled) {
|
|
11555
|
-
const ps = new
|
|
11567
|
+
const ps = new chunkQCJHCSOK_cjs.PluginService(db);
|
|
11556
11568
|
const p = await ps.getPlugin(plugin);
|
|
11557
11569
|
flags[`${key}Settings`] = p?.settings;
|
|
11558
11570
|
}
|
|
@@ -11588,9 +11600,9 @@ adminContentRoutes.get("/", async (c) => {
|
|
|
11588
11600
|
const offset = (page - 1) * limit;
|
|
11589
11601
|
const collectionsStmt = db.prepare("SELECT id, name, display_name FROM document_types WHERE is_active = 1 ORDER BY display_name");
|
|
11590
11602
|
const { results: collectionsResults } = await collectionsStmt.all();
|
|
11591
|
-
const codeCollections = await
|
|
11603
|
+
const codeCollections = await chunkQCJHCSOK_cjs.loadCollectionConfigs();
|
|
11592
11604
|
const codeCollectionMap = new Map(codeCollections.map((c2) => [c2.name, c2]));
|
|
11593
|
-
const docTypeRegistry = new
|
|
11605
|
+
const docTypeRegistry = new chunk37V3RET3_cjs.DocumentTypeRegistry(db);
|
|
11594
11606
|
const docTypes = (await docTypeRegistry.findAll()).filter((dt) => !dt.settings?.internal && !dt.isAuth);
|
|
11595
11607
|
const visibleTypeIds = new Set(docTypes.map((dt) => dt.id));
|
|
11596
11608
|
const allCollections = [
|
|
@@ -11602,7 +11614,7 @@ adminContentRoutes.get("/", async (c) => {
|
|
|
11602
11614
|
...allCollections.map((c2) => ({ name: c2.name, displayName: c2.displayName })),
|
|
11603
11615
|
...docTypes.filter((dt) => !collectionNames.has(dt.id)).map((dt) => ({ name: `doc:${dt.id}`, displayName: dt.displayName }))
|
|
11604
11616
|
];
|
|
11605
|
-
const newContentCollections = await
|
|
11617
|
+
const newContentCollections = await chunkQCJHCSOK_cjs.getVisibleCollections(db);
|
|
11606
11618
|
const docBackedCollection = !modelName.startsWith("doc:") && modelName !== "all" ? docTypes.find((dt) => dt.id === modelName) : void 0;
|
|
11607
11619
|
const isDocModel = modelName.startsWith("doc:") || !!docBackedCollection;
|
|
11608
11620
|
if (isDocModel) {
|
|
@@ -11625,6 +11637,14 @@ adminContentRoutes.get("/", async (c) => {
|
|
|
11625
11637
|
docSql += " ORDER BY updated_at DESC LIMIT ? OFFSET ?";
|
|
11626
11638
|
docParams.push(limit, offset);
|
|
11627
11639
|
const { results: docRows } = await db.prepare(docSql).bind(...docParams).all();
|
|
11640
|
+
const docUserIds = [...new Set((docRows ?? []).map((r) => r.created_by).filter(Boolean))];
|
|
11641
|
+
const docAuthorMap = {};
|
|
11642
|
+
for (let i = 0; i < docUserIds.length; i += 99) {
|
|
11643
|
+
const chunk = docUserIds.slice(i, i + 99);
|
|
11644
|
+
const ph = chunk.map(() => "?").join(",");
|
|
11645
|
+
const { results: uRows } = await db.prepare(`SELECT id, email FROM auth_user WHERE id IN (${ph})`).bind(...chunk).all();
|
|
11646
|
+
for (const u of uRows ?? []) docAuthorMap[u.id] = u.email;
|
|
11647
|
+
}
|
|
11628
11648
|
const statusBadgeCss = {
|
|
11629
11649
|
published: "bg-green-50 dark:bg-green-500/10 text-green-700 dark:text-green-400 ring-1 ring-inset ring-green-600/20 dark:ring-green-500/20",
|
|
11630
11650
|
draft: "bg-zinc-50 dark:bg-zinc-500/10 text-zinc-700 dark:text-zinc-400 ring-1 ring-inset ring-zinc-600/20 dark:ring-zinc-500/20"
|
|
@@ -11641,7 +11661,7 @@ adminContentRoutes.get("/", async (c) => {
|
|
|
11641
11661
|
slug: row.slug || "",
|
|
11642
11662
|
modelName: docType?.displayName ?? typeId,
|
|
11643
11663
|
statusBadge: `<span class="inline-flex items-center rounded-md px-2 py-1 text-xs font-medium ${css}">${label}</span>`,
|
|
11644
|
-
authorName: row.created_by || "System",
|
|
11664
|
+
authorName: (row.created_by ? docAuthorMap[row.created_by] ?? row.created_by : null) || "System",
|
|
11645
11665
|
// Document timestamps are stored in SECONDS (documents.ts), unlike legacy content rows which
|
|
11646
11666
|
// store MILLISECONDS — hence the *1000 here (D23).
|
|
11647
11667
|
formattedDate: new Date((row.updated_at ?? 0) * 1e3).toLocaleDateString(),
|
|
@@ -11689,8 +11709,8 @@ adminContentRoutes.get("/", async (c) => {
|
|
|
11689
11709
|
SELECT d.root_id AS id, d.title AS title, d.slug AS slug,
|
|
11690
11710
|
CASE WHEN d.is_published = 1 THEN 'published' ELSE 'draft' END AS status,
|
|
11691
11711
|
d.updated_at * 1000 AS updated_at,
|
|
11692
|
-
dt.display_name AS cdisplay, COALESCE(d.created_by, 'System') AS author_label
|
|
11693
|
-
FROM documents d JOIN document_types dt ON dt.id = d.type_id
|
|
11712
|
+
dt.display_name AS cdisplay, COALESCE(u.email, d.created_by, 'System') AS author_label
|
|
11713
|
+
FROM documents d JOIN document_types dt ON dt.id = d.type_id LEFT JOIN auth_user u ON u.id = d.created_by
|
|
11694
11714
|
WHERE ${docConds.join(" AND ")}
|
|
11695
11715
|
ORDER BY updated_at DESC LIMIT ? OFFSET ?`;
|
|
11696
11716
|
const { results: unionRows } = await db.prepare(unionSql).bind(...docParams, limit, offset).all();
|
|
@@ -11879,9 +11899,9 @@ adminContentRoutes.get("/new", async (c) => {
|
|
|
11879
11899
|
const collectionsStmt = db2.prepare("SELECT id, name, display_name, description FROM document_types WHERE is_active = 1 ORDER BY display_name");
|
|
11880
11900
|
const { results } = await collectionsStmt.all();
|
|
11881
11901
|
const visibleTypeIds = new Set(
|
|
11882
|
-
(await new
|
|
11902
|
+
(await new chunk37V3RET3_cjs.DocumentTypeRegistry(db2).findAll()).filter((dt) => !dt.settings?.internal && !dt.isAuth).map((dt) => dt.id)
|
|
11883
11903
|
);
|
|
11884
|
-
const codeCollections = await
|
|
11904
|
+
const codeCollections = await chunkQCJHCSOK_cjs.loadCollectionConfigs();
|
|
11885
11905
|
const dbCollectionNames = new Set((results || []).map((r) => r.name));
|
|
11886
11906
|
const allCollections = [
|
|
11887
11907
|
...codeCollections.filter((c2) => !dbCollectionNames.has(c2.name)).map((c2) => ({
|
|
@@ -11947,32 +11967,32 @@ adminContentRoutes.get("/new", async (c) => {
|
|
|
11947
11967
|
return c.html(renderContentFormPage(formData2));
|
|
11948
11968
|
}
|
|
11949
11969
|
const fields = await getCollectionFields(db, collection.id);
|
|
11950
|
-
const workflowEnabled = await
|
|
11951
|
-
const tinymceEnabled = await
|
|
11970
|
+
const workflowEnabled = await chunk37V3RET3_cjs.isPluginActive(db, "workflow");
|
|
11971
|
+
const tinymceEnabled = await chunk37V3RET3_cjs.isPluginActive(db, "tinymce-plugin");
|
|
11952
11972
|
let tinymceSettings;
|
|
11953
11973
|
if (tinymceEnabled) {
|
|
11954
|
-
const pluginService = new
|
|
11974
|
+
const pluginService = new chunkQCJHCSOK_cjs.PluginService(db);
|
|
11955
11975
|
const tinymcePlugin2 = await pluginService.getPlugin("tinymce-plugin");
|
|
11956
11976
|
tinymceSettings = tinymcePlugin2?.settings;
|
|
11957
11977
|
}
|
|
11958
|
-
const quillEnabled = await
|
|
11978
|
+
const quillEnabled = await chunk37V3RET3_cjs.isPluginActive(db, "quill-editor");
|
|
11959
11979
|
let quillSettings;
|
|
11960
11980
|
if (quillEnabled) {
|
|
11961
|
-
const pluginService = new
|
|
11981
|
+
const pluginService = new chunkQCJHCSOK_cjs.PluginService(db);
|
|
11962
11982
|
const quillPlugin = await pluginService.getPlugin("quill-editor");
|
|
11963
11983
|
quillSettings = quillPlugin?.settings;
|
|
11964
11984
|
}
|
|
11965
|
-
const mdxeditorEnabled = await
|
|
11985
|
+
const mdxeditorEnabled = await chunk37V3RET3_cjs.isPluginActive(db, "easy-mdx");
|
|
11966
11986
|
let mdxeditorSettings;
|
|
11967
11987
|
if (mdxeditorEnabled) {
|
|
11968
|
-
const pluginService = new
|
|
11988
|
+
const pluginService = new chunkQCJHCSOK_cjs.PluginService(db);
|
|
11969
11989
|
const mdxeditorPlugin = await pluginService.getPlugin("easy-mdx");
|
|
11970
11990
|
mdxeditorSettings = mdxeditorPlugin?.settings;
|
|
11971
11991
|
}
|
|
11972
|
-
const lexicalEnabled = await
|
|
11992
|
+
const lexicalEnabled = await chunk37V3RET3_cjs.isPluginActive(db, "lexical-editor");
|
|
11973
11993
|
let lexicalSettings;
|
|
11974
11994
|
if (lexicalEnabled) {
|
|
11975
|
-
const pluginService = new
|
|
11995
|
+
const pluginService = new chunkQCJHCSOK_cjs.PluginService(db);
|
|
11976
11996
|
const lexicalPlugin = await pluginService.getPlugin("lexical-editor");
|
|
11977
11997
|
lexicalSettings = lexicalPlugin?.settings;
|
|
11978
11998
|
}
|
|
@@ -12031,6 +12051,13 @@ adminContentRoutes.get("/:id/edit", async (c) => {
|
|
|
12031
12051
|
if (docType && dcoll) {
|
|
12032
12052
|
const fields2 = await getCollectionFields(db, dcoll.id);
|
|
12033
12053
|
const flags = await loadContentEditorFlags(db);
|
|
12054
|
+
let authorName;
|
|
12055
|
+
if (docRow.created_by) {
|
|
12056
|
+
const authorRow = await db.prepare("SELECT name, first_name, last_name, email FROM auth_user WHERE id = ?").bind(docRow.created_by).first();
|
|
12057
|
+
if (authorRow) {
|
|
12058
|
+
authorName = authorRow.name || [authorRow.first_name, authorRow.last_name].filter(Boolean).join(" ") || authorRow.email;
|
|
12059
|
+
}
|
|
12060
|
+
}
|
|
12034
12061
|
const formData2 = {
|
|
12035
12062
|
id: docRow.root_id,
|
|
12036
12063
|
title: docRow.title,
|
|
@@ -12045,6 +12072,7 @@ adminContentRoutes.get("/:id/edit", async (c) => {
|
|
|
12045
12072
|
isEdit: true,
|
|
12046
12073
|
referrerParams,
|
|
12047
12074
|
versioningEnabled: docType?.settings?.versioning === true,
|
|
12075
|
+
author_name: authorName,
|
|
12048
12076
|
user: user ? { name: user.email, email: user.email, role: user.role } : void 0,
|
|
12049
12077
|
version: c.get("appVersion"),
|
|
12050
12078
|
...flags
|
|
@@ -12100,32 +12128,32 @@ adminContentRoutes.get("/:id/edit", async (c) => {
|
|
|
12100
12128
|
};
|
|
12101
12129
|
const fields = await getCollectionFields(db, content.collection_id);
|
|
12102
12130
|
const contentData = content.data ? JSON.parse(content.data) : {};
|
|
12103
|
-
const workflowEnabled = await
|
|
12104
|
-
const tinymceEnabled = await
|
|
12131
|
+
const workflowEnabled = await chunk37V3RET3_cjs.isPluginActive(db, "workflow");
|
|
12132
|
+
const tinymceEnabled = await chunk37V3RET3_cjs.isPluginActive(db, "tinymce-plugin");
|
|
12105
12133
|
let tinymceSettings;
|
|
12106
12134
|
if (tinymceEnabled) {
|
|
12107
|
-
const pluginService = new
|
|
12135
|
+
const pluginService = new chunkQCJHCSOK_cjs.PluginService(db);
|
|
12108
12136
|
const tinymcePlugin2 = await pluginService.getPlugin("tinymce-plugin");
|
|
12109
12137
|
tinymceSettings = tinymcePlugin2?.settings;
|
|
12110
12138
|
}
|
|
12111
|
-
const quillEnabled = await
|
|
12139
|
+
const quillEnabled = await chunk37V3RET3_cjs.isPluginActive(db, "quill-editor");
|
|
12112
12140
|
let quillSettings;
|
|
12113
12141
|
if (quillEnabled) {
|
|
12114
|
-
const pluginService = new
|
|
12142
|
+
const pluginService = new chunkQCJHCSOK_cjs.PluginService(db);
|
|
12115
12143
|
const quillPlugin = await pluginService.getPlugin("quill-editor");
|
|
12116
12144
|
quillSettings = quillPlugin?.settings;
|
|
12117
12145
|
}
|
|
12118
|
-
const mdxeditorEnabled = await
|
|
12146
|
+
const mdxeditorEnabled = await chunk37V3RET3_cjs.isPluginActive(db, "easy-mdx");
|
|
12119
12147
|
let mdxeditorSettings;
|
|
12120
12148
|
if (mdxeditorEnabled) {
|
|
12121
|
-
const pluginService = new
|
|
12149
|
+
const pluginService = new chunkQCJHCSOK_cjs.PluginService(db);
|
|
12122
12150
|
const mdxeditorPlugin = await pluginService.getPlugin("easy-mdx");
|
|
12123
12151
|
mdxeditorSettings = mdxeditorPlugin?.settings;
|
|
12124
12152
|
}
|
|
12125
|
-
const lexicalEnabled = await
|
|
12153
|
+
const lexicalEnabled = await chunk37V3RET3_cjs.isPluginActive(db, "lexical-editor");
|
|
12126
12154
|
let lexicalSettings;
|
|
12127
12155
|
if (lexicalEnabled) {
|
|
12128
|
-
const pluginService = new
|
|
12156
|
+
const pluginService = new chunkQCJHCSOK_cjs.PluginService(db);
|
|
12129
12157
|
const lexicalPlugin = await pluginService.getPlugin("lexical-editor");
|
|
12130
12158
|
lexicalSettings = lexicalPlugin?.settings;
|
|
12131
12159
|
}
|
|
@@ -12204,6 +12232,7 @@ adminContentRoutes.post("/", async (c) => {
|
|
|
12204
12232
|
const fields = await getCollectionFields(db, collectionId);
|
|
12205
12233
|
const { data, errors } = extractFieldData(fields, formData);
|
|
12206
12234
|
if (Object.keys(errors).length > 0) {
|
|
12235
|
+
const flags = await loadContentEditorFlags(db);
|
|
12207
12236
|
const formDataWithErrors = {
|
|
12208
12237
|
collection,
|
|
12209
12238
|
fields,
|
|
@@ -12214,7 +12243,8 @@ adminContentRoutes.post("/", async (c) => {
|
|
|
12214
12243
|
name: user.email,
|
|
12215
12244
|
email: user.email,
|
|
12216
12245
|
role: user.role
|
|
12217
|
-
} : void 0
|
|
12246
|
+
} : void 0,
|
|
12247
|
+
...flags
|
|
12218
12248
|
};
|
|
12219
12249
|
if (c.req.header("HX-Request") === "true") {
|
|
12220
12250
|
c.header("HX-Retarget", "#content-form-page");
|
|
@@ -12395,6 +12425,7 @@ adminContentRoutes.put("/:id", async (c) => {
|
|
|
12395
12425
|
const fields = await getCollectionFields(db, existingContent.collection_id);
|
|
12396
12426
|
const { data, errors } = extractFieldData(fields, formData);
|
|
12397
12427
|
if (Object.keys(errors).length > 0) {
|
|
12428
|
+
const flags = await loadContentEditorFlags(db);
|
|
12398
12429
|
const formDataWithErrors = {
|
|
12399
12430
|
id,
|
|
12400
12431
|
collection,
|
|
@@ -12407,7 +12438,8 @@ adminContentRoutes.put("/:id", async (c) => {
|
|
|
12407
12438
|
name: user.email,
|
|
12408
12439
|
email: user.email,
|
|
12409
12440
|
role: user.role
|
|
12410
|
-
} : void 0
|
|
12441
|
+
} : void 0,
|
|
12442
|
+
...flags
|
|
12411
12443
|
};
|
|
12412
12444
|
if (c.req.header("HX-Request") === "true") {
|
|
12413
12445
|
c.header("HX-Retarget", "#content-form-page");
|
|
@@ -12498,7 +12530,7 @@ adminContentRoutes.put("/:id", async (c) => {
|
|
|
12498
12530
|
`);
|
|
12499
12531
|
}
|
|
12500
12532
|
});
|
|
12501
|
-
adminContentRoutes.post("/preview",
|
|
12533
|
+
adminContentRoutes.post("/preview", chunk37V3RET3_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
|
|
12502
12534
|
try {
|
|
12503
12535
|
const formData = await c.req.formData();
|
|
12504
12536
|
const collectionId = formData.get("collection_id");
|
|
@@ -12817,7 +12849,7 @@ adminContentRoutes.delete("/:id", async (c) => {
|
|
|
12817
12849
|
return c.json({ success: false, error: "Failed to delete content" }, 500);
|
|
12818
12850
|
}
|
|
12819
12851
|
});
|
|
12820
|
-
adminContentRoutes.get("/:id/version/:version/preview",
|
|
12852
|
+
adminContentRoutes.get("/:id/version/:version/preview", chunk37V3RET3_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
|
|
12821
12853
|
try {
|
|
12822
12854
|
const id = c.req.param("id");
|
|
12823
12855
|
const version = parseInt(c.req.param("version") || "0");
|
|
@@ -12913,7 +12945,7 @@ function parseDocFormData(formData, queryableFields = []) {
|
|
|
12913
12945
|
return { title, slug, data };
|
|
12914
12946
|
}
|
|
12915
12947
|
async function getDocService(db, typeId, tenantId) {
|
|
12916
|
-
const registry = new
|
|
12948
|
+
const registry = new chunk37V3RET3_cjs.DocumentTypeRegistry(db);
|
|
12917
12949
|
const docType = await registry.findById(typeId);
|
|
12918
12950
|
const svc = new chunkLTZ5WYOK_cjs.DocumentsService(db, {
|
|
12919
12951
|
queryableFields: docType?.queryableFields ?? [],
|
|
@@ -12926,10 +12958,10 @@ async function getDocService(db, typeId, tenantId) {
|
|
|
12926
12958
|
}
|
|
12927
12959
|
adminContentRoutes.get("/documents/:typeId/new", async (c) => {
|
|
12928
12960
|
const { typeId } = c.req.param();
|
|
12929
|
-
const registry = new
|
|
12961
|
+
const registry = new chunk37V3RET3_cjs.DocumentTypeRegistry(c.env.DB);
|
|
12930
12962
|
const docType = await registry.findById(typeId);
|
|
12931
12963
|
if (!docType) return c.html("<p>Unknown document type.</p>", 404);
|
|
12932
|
-
return c.html(
|
|
12964
|
+
return c.html(chunkJMJM7DMM_cjs.renderDocumentFormPage({ docType, isEdit: false, user: userCtx(c) }));
|
|
12933
12965
|
});
|
|
12934
12966
|
adminContentRoutes.post("/documents/:typeId/new", async (c) => {
|
|
12935
12967
|
const { typeId } = c.req.param();
|
|
@@ -12951,17 +12983,17 @@ adminContentRoutes.post("/documents/:typeId/new", async (c) => {
|
|
|
12951
12983
|
}), user?.userId);
|
|
12952
12984
|
return c.redirect(`/admin/content/documents/${typeId}/${doc.rootId}/edit?message=Created+successfully`);
|
|
12953
12985
|
} catch (err) {
|
|
12954
|
-
const registry = new
|
|
12986
|
+
const registry = new chunk37V3RET3_cjs.DocumentTypeRegistry(c.env.DB);
|
|
12955
12987
|
const docType = await registry.findById(typeId);
|
|
12956
12988
|
if (!docType) return c.html("<p>Unknown document type.</p>", 404);
|
|
12957
|
-
return c.html(
|
|
12989
|
+
return c.html(chunkJMJM7DMM_cjs.renderDocumentFormPage({ docType, isEdit: false, user: userCtx(c), message: err?.message ?? "Failed to create", messageType: "error" }));
|
|
12958
12990
|
}
|
|
12959
12991
|
});
|
|
12960
12992
|
adminContentRoutes.get("/documents/:typeId/:rootId/edit", async (c) => {
|
|
12961
12993
|
const { typeId, rootId } = c.req.param();
|
|
12962
12994
|
const db = c.env.DB;
|
|
12963
12995
|
const message = c.req.query("message");
|
|
12964
|
-
const registry = new
|
|
12996
|
+
const registry = new chunk37V3RET3_cjs.DocumentTypeRegistry(db);
|
|
12965
12997
|
const docType = await registry.findById(typeId);
|
|
12966
12998
|
if (!docType) return c.html("<p>Unknown document type.</p>", 404);
|
|
12967
12999
|
const tenantId = reqTenant(c);
|
|
@@ -13008,7 +13040,7 @@ adminContentRoutes.get("/documents/:typeId/:rootId/edit", async (c) => {
|
|
|
13008
13040
|
createdAt: draftRow.created_at,
|
|
13009
13041
|
updatedAt: draftRow.updated_at
|
|
13010
13042
|
};
|
|
13011
|
-
return c.html(
|
|
13043
|
+
return c.html(chunkJMJM7DMM_cjs.renderDocumentFormPage({ docType, doc, publishedDoc, isEdit: true, message, user: userCtx(c), versioningEnabled: docType?.settings?.versioning === true }));
|
|
13012
13044
|
});
|
|
13013
13045
|
adminContentRoutes.post("/documents/:typeId/:rootId", async (c) => {
|
|
13014
13046
|
const { typeId, rootId } = c.req.param();
|
|
@@ -13073,12 +13105,12 @@ adminContentRoutes.post("/documents/:typeId/:documentId/delete", async (c) => {
|
|
|
13073
13105
|
adminContentRoutes.get("/documents/:typeId/:rootId/versions", async (c) => {
|
|
13074
13106
|
const { typeId, rootId } = c.req.param();
|
|
13075
13107
|
const db = c.env.DB;
|
|
13076
|
-
const { renderVersionHistoryFragment } = await import('./admin-documents-form.template-
|
|
13077
|
-
const registry = new
|
|
13108
|
+
const { renderVersionHistoryFragment } = await import('./admin-documents-form.template-YNAVMJCV.cjs');
|
|
13109
|
+
const registry = new chunk37V3RET3_cjs.DocumentTypeRegistry(db);
|
|
13078
13110
|
const docType = await registry.findById(typeId);
|
|
13079
13111
|
if (!docType) return c.html("<div>Unknown type.</div>", 404);
|
|
13080
13112
|
const result = await db.prepare(
|
|
13081
|
-
"SELECT id, version_number, is_current_draft, is_published, status, updated_at, created_by FROM documents WHERE root_id = ? AND tenant_id = ? ORDER BY version_number DESC LIMIT 50"
|
|
13113
|
+
"SELECT d.id, d.version_number, d.is_current_draft, d.is_published, d.status, d.updated_at, COALESCE(u.email, d.created_by) AS created_by FROM documents d LEFT JOIN auth_user u ON u.id = d.created_by WHERE d.root_id = ? AND d.tenant_id = ? ORDER BY d.version_number DESC LIMIT 50"
|
|
13082
13114
|
).bind(rootId, reqTenant(c)).all();
|
|
13083
13115
|
const versions = (result.results ?? []).map((r) => ({
|
|
13084
13116
|
id: r.id,
|
|
@@ -13094,7 +13126,7 @@ adminContentRoutes.get("/documents/:typeId/:rootId/versions", async (c) => {
|
|
|
13094
13126
|
var admin_content_default = adminContentRoutes;
|
|
13095
13127
|
|
|
13096
13128
|
// src/templates/pages/admin-profile.template.ts
|
|
13097
|
-
|
|
13129
|
+
chunkUYJQDDEE_cjs.init_admin_layout_catalyst_template();
|
|
13098
13130
|
function renderAvatarImage(avatarUrl, firstName, lastName) {
|
|
13099
13131
|
return `<div id="avatar-image-container" class="w-24 h-24 rounded-full mx-auto mb-4 overflow-hidden bg-gradient-to-br from-cyan-400 to-purple-400 flex items-center justify-center ring-4 ring-zinc-950/5 dark:ring-white/10">
|
|
13100
13132
|
${avatarUrl ? `<img src="${avatarUrl}" alt="Profile picture" class="w-full h-full object-cover">` : `<span class="text-2xl font-bold text-white">${firstName.charAt(0)}${lastName.charAt(0)}</span>`}
|
|
@@ -13114,8 +13146,8 @@ function renderProfilePage(data) {
|
|
|
13114
13146
|
</div>
|
|
13115
13147
|
|
|
13116
13148
|
<!-- Alert Messages -->
|
|
13117
|
-
${data.error ?
|
|
13118
|
-
${data.success ?
|
|
13149
|
+
${data.error ? chunkE66UVONV_cjs.renderAlert({ type: "error", message: data.error, dismissible: true }) : ""}
|
|
13150
|
+
${data.success ? chunkE66UVONV_cjs.renderAlert({ type: "success", message: data.success, dismissible: true }) : ""}
|
|
13119
13151
|
|
|
13120
13152
|
<!-- Profile Form -->
|
|
13121
13153
|
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
|
|
@@ -13492,7 +13524,7 @@ function renderProfilePage(data) {
|
|
|
13492
13524
|
version: data.version,
|
|
13493
13525
|
content: pageContent
|
|
13494
13526
|
};
|
|
13495
|
-
return
|
|
13527
|
+
return chunkUYJQDDEE_cjs.renderAdminLayoutCatalyst(layoutData);
|
|
13496
13528
|
}
|
|
13497
13529
|
|
|
13498
13530
|
// src/templates/pages/admin-activity-logs.template.ts
|
|
@@ -13702,7 +13734,7 @@ function renderActivityLogsPage(data) {
|
|
|
13702
13734
|
user: data.user,
|
|
13703
13735
|
content: pageContent
|
|
13704
13736
|
};
|
|
13705
|
-
return
|
|
13737
|
+
return chunkE66UVONV_cjs.renderAdminLayout(layoutData);
|
|
13706
13738
|
}
|
|
13707
13739
|
function getActionBadgeClass(action) {
|
|
13708
13740
|
if (action.includes("login") || action.includes("logout")) {
|
|
@@ -13722,7 +13754,7 @@ function formatAction(action) {
|
|
|
13722
13754
|
}
|
|
13723
13755
|
|
|
13724
13756
|
// src/templates/pages/admin-user-edit.template.ts
|
|
13725
|
-
|
|
13757
|
+
chunkUYJQDDEE_cjs.init_admin_layout_catalyst_template();
|
|
13726
13758
|
|
|
13727
13759
|
// src/templates/components/confirmation-dialog.template.ts
|
|
13728
13760
|
function renderConfirmationDialog2(options) {
|
|
@@ -13918,8 +13950,8 @@ function renderUserEditPage(data) {
|
|
|
13918
13950
|
|
|
13919
13951
|
<!-- Alert Messages -->
|
|
13920
13952
|
<div id="form-messages" class="mb-6 empty:mb-0">
|
|
13921
|
-
${data.error ?
|
|
13922
|
-
${data.success ?
|
|
13953
|
+
${data.error ? chunkE66UVONV_cjs.renderAlert({ type: "error", message: data.error, dismissible: true }) : ""}
|
|
13954
|
+
${data.success ? chunkE66UVONV_cjs.renderAlert({ type: "success", message: data.success, dismissible: true }) : ""}
|
|
13923
13955
|
</div>
|
|
13924
13956
|
|
|
13925
13957
|
<!-- User Edit Form -->
|
|
@@ -14241,11 +14273,11 @@ function renderUserEditPage(data) {
|
|
|
14241
14273
|
user: data.user,
|
|
14242
14274
|
content: pageContent
|
|
14243
14275
|
};
|
|
14244
|
-
return
|
|
14276
|
+
return chunkUYJQDDEE_cjs.renderAdminLayoutCatalyst(layoutData);
|
|
14245
14277
|
}
|
|
14246
14278
|
|
|
14247
14279
|
// src/templates/pages/admin-user-new.template.ts
|
|
14248
|
-
|
|
14280
|
+
chunkUYJQDDEE_cjs.init_admin_layout_catalyst_template();
|
|
14249
14281
|
function renderUserNewPage(data) {
|
|
14250
14282
|
const pageContent = `
|
|
14251
14283
|
<div>
|
|
@@ -14284,8 +14316,8 @@ function renderUserNewPage(data) {
|
|
|
14284
14316
|
|
|
14285
14317
|
<!-- Alert Messages -->
|
|
14286
14318
|
<div id="form-messages">
|
|
14287
|
-
${data.error ?
|
|
14288
|
-
${data.success ?
|
|
14319
|
+
${data.error ? chunkE66UVONV_cjs.renderAlert({ type: "error", message: data.error, dismissible: true }) : ""}
|
|
14320
|
+
${data.success ? chunkE66UVONV_cjs.renderAlert({ type: "success", message: data.success, dismissible: true }) : ""}
|
|
14289
14321
|
</div>
|
|
14290
14322
|
|
|
14291
14323
|
<!-- User New Form -->
|
|
@@ -14515,11 +14547,11 @@ function renderUserNewPage(data) {
|
|
|
14515
14547
|
user: data.user,
|
|
14516
14548
|
content: pageContent
|
|
14517
14549
|
};
|
|
14518
|
-
return
|
|
14550
|
+
return chunkUYJQDDEE_cjs.renderAdminLayoutCatalyst(layoutData);
|
|
14519
14551
|
}
|
|
14520
14552
|
|
|
14521
14553
|
// src/templates/pages/admin-users-list.template.ts
|
|
14522
|
-
|
|
14554
|
+
chunkUYJQDDEE_cjs.init_admin_layout_catalyst_template();
|
|
14523
14555
|
function renderUsersListPage(data) {
|
|
14524
14556
|
const columns = [
|
|
14525
14557
|
{
|
|
@@ -14675,8 +14707,8 @@ function renderUsersListPage(data) {
|
|
|
14675
14707
|
</div>
|
|
14676
14708
|
|
|
14677
14709
|
<!-- Alert Messages -->
|
|
14678
|
-
${data.error ?
|
|
14679
|
-
${data.success ?
|
|
14710
|
+
${data.error ? chunkE66UVONV_cjs.renderAlert({ type: "error", message: data.error, dismissible: true }) : ""}
|
|
14711
|
+
${data.success ? chunkE66UVONV_cjs.renderAlert({ type: "success", message: data.success, dismissible: true }) : ""}
|
|
14680
14712
|
|
|
14681
14713
|
<!-- Stats -->
|
|
14682
14714
|
<div class="mb-6">
|
|
@@ -14853,10 +14885,10 @@ function renderUsersListPage(data) {
|
|
|
14853
14885
|
</div>
|
|
14854
14886
|
|
|
14855
14887
|
<!-- Users Table -->
|
|
14856
|
-
${
|
|
14888
|
+
${chunkE66UVONV_cjs.renderTable(tableData)}
|
|
14857
14889
|
|
|
14858
14890
|
<!-- Pagination -->
|
|
14859
|
-
${data.pagination ?
|
|
14891
|
+
${data.pagination ? chunkE66UVONV_cjs.renderPagination(data.pagination) : ""}
|
|
14860
14892
|
</div>
|
|
14861
14893
|
|
|
14862
14894
|
<script>
|
|
@@ -14927,7 +14959,7 @@ function renderUsersListPage(data) {
|
|
|
14927
14959
|
version: data.version,
|
|
14928
14960
|
content: pageContent
|
|
14929
14961
|
};
|
|
14930
|
-
return
|
|
14962
|
+
return chunkUYJQDDEE_cjs.renderAdminLayoutCatalyst(layoutData);
|
|
14931
14963
|
}
|
|
14932
14964
|
|
|
14933
14965
|
// src/plugins/core-plugins/multi-tenant-plugin/services/tenant-service.ts
|
|
@@ -15007,7 +15039,7 @@ var TenantService = class {
|
|
|
15007
15039
|
SET name = ?, domain = ?, status = ?, notes = ?, updated_at = ?
|
|
15008
15040
|
WHERE slug = ?
|
|
15009
15041
|
`).bind(name, domain, status, notes, now, slug).run();
|
|
15010
|
-
|
|
15042
|
+
chunkQCJHCSOK_cjs.invalidateTenantCache();
|
|
15011
15043
|
const updated = await this.getTenantBySlug(slug);
|
|
15012
15044
|
if (!updated) throw new Error("Tenant not found");
|
|
15013
15045
|
return updated;
|
|
@@ -15025,7 +15057,7 @@ var TenantService = class {
|
|
|
15025
15057
|
throw new Error(`Tenant '${slug}' still owns ${docCount} document(s). Delete or migrate its content first.`);
|
|
15026
15058
|
}
|
|
15027
15059
|
await this.db.prepare(`DELETE FROM auth_tenant WHERE slug = ?`).bind(slug).run();
|
|
15028
|
-
|
|
15060
|
+
chunkQCJHCSOK_cjs.invalidateTenantCache();
|
|
15029
15061
|
}
|
|
15030
15062
|
// ─── Membership (auth_tenant_member) ───────────────────────────────────────
|
|
15031
15063
|
// Tenant resolution and the admin switcher are gated on membership: an authed user may only
|
|
@@ -15269,7 +15301,7 @@ var TenantService = class {
|
|
|
15269
15301
|
INSERT INTO auth_tenant (id, name, slug, status, domain, notes, metadata, created_at, updated_at)
|
|
15270
15302
|
VALUES (?, ?, ?, 'active', ?, ?, '{}', ?, ?)
|
|
15271
15303
|
`).bind(id, input.name, input.slug, input.domain, input.notes, now, now).run();
|
|
15272
|
-
|
|
15304
|
+
chunkQCJHCSOK_cjs.invalidateTenantCache();
|
|
15273
15305
|
const created = await this.getTenantBySlug(input.slug);
|
|
15274
15306
|
if (!created) throw new Error("Failed to create tenant");
|
|
15275
15307
|
return created;
|
|
@@ -15293,14 +15325,14 @@ function mapRowToTenant(row) {
|
|
|
15293
15325
|
|
|
15294
15326
|
// src/routes/admin-users.ts
|
|
15295
15327
|
var userRoutes = new hono.Hono();
|
|
15296
|
-
userRoutes.use("*",
|
|
15297
|
-
userRoutes.use("/users/*",
|
|
15298
|
-
userRoutes.use("/users",
|
|
15299
|
-
userRoutes.use("/invite-user",
|
|
15300
|
-
userRoutes.use("/resend-invitation/*",
|
|
15301
|
-
userRoutes.use("/cancel-invitation/*",
|
|
15302
|
-
userRoutes.use("/activity-logs",
|
|
15303
|
-
userRoutes.use("/activity-logs/*",
|
|
15328
|
+
userRoutes.use("*", chunk37V3RET3_cjs.requireAuth());
|
|
15329
|
+
userRoutes.use("/users/*", chunk37V3RET3_cjs.requireRole(["admin"]));
|
|
15330
|
+
userRoutes.use("/users", chunk37V3RET3_cjs.requireRole(["admin"]));
|
|
15331
|
+
userRoutes.use("/invite-user", chunk37V3RET3_cjs.requireRole(["admin"]));
|
|
15332
|
+
userRoutes.use("/resend-invitation/*", chunk37V3RET3_cjs.requireRole(["admin"]));
|
|
15333
|
+
userRoutes.use("/cancel-invitation/*", chunk37V3RET3_cjs.requireRole(["admin"]));
|
|
15334
|
+
userRoutes.use("/activity-logs", chunk37V3RET3_cjs.requireRole(["admin"]));
|
|
15335
|
+
userRoutes.use("/activity-logs/*", chunk37V3RET3_cjs.requireRole(["admin"]));
|
|
15304
15336
|
userRoutes.get("/", (c) => {
|
|
15305
15337
|
return c.redirect("/admin/dashboard");
|
|
15306
15338
|
});
|
|
@@ -15411,7 +15443,7 @@ userRoutes.put("/profile", async (c) => {
|
|
|
15411
15443
|
const language = formData.get("language")?.toString() || "en";
|
|
15412
15444
|
const emailNotifications = formData.get("email_notifications") === "1";
|
|
15413
15445
|
if (!firstName || !lastName || !email) {
|
|
15414
|
-
return c.html(
|
|
15446
|
+
return c.html(chunkJMJM7DMM_cjs.renderAlert({
|
|
15415
15447
|
type: "error",
|
|
15416
15448
|
message: "First name, last name, and email are required.",
|
|
15417
15449
|
dismissible: true
|
|
@@ -15419,7 +15451,7 @@ userRoutes.put("/profile", async (c) => {
|
|
|
15419
15451
|
}
|
|
15420
15452
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
15421
15453
|
if (!emailRegex.test(email)) {
|
|
15422
|
-
return c.html(
|
|
15454
|
+
return c.html(chunkJMJM7DMM_cjs.renderAlert({
|
|
15423
15455
|
type: "error",
|
|
15424
15456
|
message: "Please enter a valid email address.",
|
|
15425
15457
|
dismissible: true
|
|
@@ -15431,7 +15463,7 @@ userRoutes.put("/profile", async (c) => {
|
|
|
15431
15463
|
`);
|
|
15432
15464
|
const existingUser = await checkStmt.bind(email, user.userId).first();
|
|
15433
15465
|
if (existingUser) {
|
|
15434
|
-
return c.html(
|
|
15466
|
+
return c.html(chunkJMJM7DMM_cjs.renderAlert({
|
|
15435
15467
|
type: "error",
|
|
15436
15468
|
message: "Email is already taken by another user.",
|
|
15437
15469
|
dismissible: true
|
|
@@ -15463,11 +15495,11 @@ userRoutes.put("/profile", async (c) => {
|
|
|
15463
15495
|
const validation = validateCustomData(sanitized, profileConfig);
|
|
15464
15496
|
if (!validation.valid) {
|
|
15465
15497
|
const errorMessages = Object.values(validation.errors).join(", ");
|
|
15466
|
-
return c.html(
|
|
15498
|
+
return c.html(chunkJMJM7DMM_cjs.renderAlert({ type: "error", message: errorMessages, dismissible: true }), 400);
|
|
15467
15499
|
}
|
|
15468
15500
|
await saveCustomData(db, user.userId, sanitized);
|
|
15469
15501
|
}
|
|
15470
|
-
await
|
|
15502
|
+
await chunk37V3RET3_cjs.logActivity(
|
|
15471
15503
|
db,
|
|
15472
15504
|
user.userId,
|
|
15473
15505
|
"profile.update",
|
|
@@ -15477,14 +15509,14 @@ userRoutes.put("/profile", async (c) => {
|
|
|
15477
15509
|
c.req.header("x-forwarded-for") || c.req.header("cf-connecting-ip"),
|
|
15478
15510
|
c.req.header("user-agent")
|
|
15479
15511
|
);
|
|
15480
|
-
return c.html(
|
|
15512
|
+
return c.html(chunkJMJM7DMM_cjs.renderAlert({
|
|
15481
15513
|
type: "success",
|
|
15482
15514
|
message: "Profile updated successfully!",
|
|
15483
15515
|
dismissible: true
|
|
15484
15516
|
}));
|
|
15485
15517
|
} catch (error) {
|
|
15486
15518
|
console.error("Profile update error:", error);
|
|
15487
|
-
return c.html(
|
|
15519
|
+
return c.html(chunkJMJM7DMM_cjs.renderAlert({
|
|
15488
15520
|
type: "error",
|
|
15489
15521
|
message: "Failed to update profile. Please try again.",
|
|
15490
15522
|
dismissible: true
|
|
@@ -15498,7 +15530,7 @@ userRoutes.post("/profile/avatar", async (c) => {
|
|
|
15498
15530
|
const formData = await c.req.formData();
|
|
15499
15531
|
const avatarFile = formData.get("avatar");
|
|
15500
15532
|
if (!avatarFile || typeof avatarFile === "string" || !avatarFile.name) {
|
|
15501
|
-
return c.html(
|
|
15533
|
+
return c.html(chunkJMJM7DMM_cjs.renderAlert({
|
|
15502
15534
|
type: "error",
|
|
15503
15535
|
message: "Please select an image file.",
|
|
15504
15536
|
dismissible: true
|
|
@@ -15506,7 +15538,7 @@ userRoutes.post("/profile/avatar", async (c) => {
|
|
|
15506
15538
|
}
|
|
15507
15539
|
const allowedTypes = ["image/jpeg", "image/png", "image/gif", "image/webp"];
|
|
15508
15540
|
if (!allowedTypes.includes(avatarFile.type)) {
|
|
15509
|
-
return c.html(
|
|
15541
|
+
return c.html(chunkJMJM7DMM_cjs.renderAlert({
|
|
15510
15542
|
type: "error",
|
|
15511
15543
|
message: "Please upload a valid image file (JPEG, PNG, GIF, or WebP).",
|
|
15512
15544
|
dismissible: true
|
|
@@ -15514,7 +15546,7 @@ userRoutes.post("/profile/avatar", async (c) => {
|
|
|
15514
15546
|
}
|
|
15515
15547
|
const maxSize = 5 * 1024 * 1024;
|
|
15516
15548
|
if (avatarFile.size > maxSize) {
|
|
15517
|
-
return c.html(
|
|
15549
|
+
return c.html(chunkJMJM7DMM_cjs.renderAlert({
|
|
15518
15550
|
type: "error",
|
|
15519
15551
|
message: "Image file must be smaller than 5MB.",
|
|
15520
15552
|
dismissible: true
|
|
@@ -15530,7 +15562,7 @@ userRoutes.post("/profile/avatar", async (c) => {
|
|
|
15530
15562
|
SELECT first_name, last_name FROM auth_user WHERE id = ?
|
|
15531
15563
|
`);
|
|
15532
15564
|
const userData = await userStmt.bind(user.userId).first();
|
|
15533
|
-
await
|
|
15565
|
+
await chunk37V3RET3_cjs.logActivity(
|
|
15534
15566
|
db,
|
|
15535
15567
|
user.userId,
|
|
15536
15568
|
"profile.avatar_update",
|
|
@@ -15540,7 +15572,7 @@ userRoutes.post("/profile/avatar", async (c) => {
|
|
|
15540
15572
|
c.req.header("x-forwarded-for") || c.req.header("cf-connecting-ip"),
|
|
15541
15573
|
c.req.header("user-agent")
|
|
15542
15574
|
);
|
|
15543
|
-
const alertHtml =
|
|
15575
|
+
const alertHtml = chunkJMJM7DMM_cjs.renderAlert({
|
|
15544
15576
|
type: "success",
|
|
15545
15577
|
message: "Profile picture updated successfully!",
|
|
15546
15578
|
dismissible: true
|
|
@@ -15554,7 +15586,7 @@ userRoutes.post("/profile/avatar", async (c) => {
|
|
|
15554
15586
|
return c.html(alertHtml + avatarImageWithOob);
|
|
15555
15587
|
} catch (error) {
|
|
15556
15588
|
console.error("Avatar upload error:", error);
|
|
15557
|
-
return c.html(
|
|
15589
|
+
return c.html(chunkJMJM7DMM_cjs.renderAlert({
|
|
15558
15590
|
type: "error",
|
|
15559
15591
|
message: "Failed to upload profile picture. Please try again.",
|
|
15560
15592
|
dismissible: true
|
|
@@ -15570,21 +15602,21 @@ userRoutes.post("/profile/password", async (c) => {
|
|
|
15570
15602
|
const newPassword = formData.get("new_password")?.toString() || "";
|
|
15571
15603
|
const confirmPassword = formData.get("confirm_password")?.toString() || "";
|
|
15572
15604
|
if (!currentPassword || !newPassword || !confirmPassword) {
|
|
15573
|
-
return c.html(
|
|
15605
|
+
return c.html(chunkJMJM7DMM_cjs.renderAlert({
|
|
15574
15606
|
type: "error",
|
|
15575
15607
|
message: "All password fields are required.",
|
|
15576
15608
|
dismissible: true
|
|
15577
15609
|
}));
|
|
15578
15610
|
}
|
|
15579
15611
|
if (newPassword !== confirmPassword) {
|
|
15580
|
-
return c.html(
|
|
15612
|
+
return c.html(chunkJMJM7DMM_cjs.renderAlert({
|
|
15581
15613
|
type: "error",
|
|
15582
15614
|
message: "New passwords do not match.",
|
|
15583
15615
|
dismissible: true
|
|
15584
15616
|
}));
|
|
15585
15617
|
}
|
|
15586
15618
|
if (newPassword.length < 8) {
|
|
15587
|
-
return c.html(
|
|
15619
|
+
return c.html(chunkJMJM7DMM_cjs.renderAlert({
|
|
15588
15620
|
type: "error",
|
|
15589
15621
|
message: "New password must be at least 8 characters long.",
|
|
15590
15622
|
dismissible: true
|
|
@@ -15595,21 +15627,21 @@ userRoutes.post("/profile/password", async (c) => {
|
|
|
15595
15627
|
`);
|
|
15596
15628
|
const userData = await userStmt.bind(user.userId).first();
|
|
15597
15629
|
if (!userData) {
|
|
15598
|
-
return c.html(
|
|
15630
|
+
return c.html(chunkJMJM7DMM_cjs.renderAlert({
|
|
15599
15631
|
type: "error",
|
|
15600
15632
|
message: "User not found.",
|
|
15601
15633
|
dismissible: true
|
|
15602
15634
|
}));
|
|
15603
15635
|
}
|
|
15604
|
-
const validPassword = await
|
|
15636
|
+
const validPassword = await chunk37V3RET3_cjs.AuthManager.verifyPassword(currentPassword, userData.password_hash);
|
|
15605
15637
|
if (!validPassword) {
|
|
15606
|
-
return c.html(
|
|
15638
|
+
return c.html(chunkJMJM7DMM_cjs.renderAlert({
|
|
15607
15639
|
type: "error",
|
|
15608
15640
|
message: "Current password is incorrect.",
|
|
15609
15641
|
dismissible: true
|
|
15610
15642
|
}));
|
|
15611
15643
|
}
|
|
15612
|
-
const newPasswordHash = await
|
|
15644
|
+
const newPasswordHash = await chunk37V3RET3_cjs.AuthManager.hashPassword(newPassword);
|
|
15613
15645
|
const historyStmt = db.prepare(`
|
|
15614
15646
|
INSERT INTO auth_password_history (id, user_id, password_hash, created_at)
|
|
15615
15647
|
VALUES (?, ?, ?, ?)
|
|
@@ -15625,7 +15657,7 @@ userRoutes.post("/profile/password", async (c) => {
|
|
|
15625
15657
|
WHERE id = ?
|
|
15626
15658
|
`);
|
|
15627
15659
|
await updateStmt.bind(newPasswordHash, Date.now(), user.userId).run();
|
|
15628
|
-
await
|
|
15660
|
+
await chunk37V3RET3_cjs.logActivity(
|
|
15629
15661
|
db,
|
|
15630
15662
|
user.userId,
|
|
15631
15663
|
"profile.password_change",
|
|
@@ -15635,14 +15667,14 @@ userRoutes.post("/profile/password", async (c) => {
|
|
|
15635
15667
|
c.req.header("x-forwarded-for") || c.req.header("cf-connecting-ip"),
|
|
15636
15668
|
c.req.header("user-agent")
|
|
15637
15669
|
);
|
|
15638
|
-
return c.html(
|
|
15670
|
+
return c.html(chunkJMJM7DMM_cjs.renderAlert({
|
|
15639
15671
|
type: "success",
|
|
15640
15672
|
message: "Password updated successfully!",
|
|
15641
15673
|
dismissible: true
|
|
15642
15674
|
}));
|
|
15643
15675
|
} catch (error) {
|
|
15644
15676
|
console.error("Password change error:", error);
|
|
15645
|
-
return c.html(
|
|
15677
|
+
return c.html(chunkJMJM7DMM_cjs.renderAlert({
|
|
15646
15678
|
type: "error",
|
|
15647
15679
|
message: "Failed to update password. Please try again.",
|
|
15648
15680
|
dismissible: true
|
|
@@ -15692,7 +15724,7 @@ userRoutes.get("/users", async (c) => {
|
|
|
15692
15724
|
`);
|
|
15693
15725
|
const countResult = await countStmt.bind(...params).first();
|
|
15694
15726
|
const totalUsers = countResult?.total || 0;
|
|
15695
|
-
await
|
|
15727
|
+
await chunk37V3RET3_cjs.logActivity(
|
|
15696
15728
|
db,
|
|
15697
15729
|
user.userId,
|
|
15698
15730
|
"users.list_view",
|
|
@@ -15763,7 +15795,7 @@ userRoutes.get("/users", async (c) => {
|
|
|
15763
15795
|
if (isApiRequest) {
|
|
15764
15796
|
return c.json({ error: "Failed to load users" }, 500);
|
|
15765
15797
|
}
|
|
15766
|
-
return c.html(
|
|
15798
|
+
return c.html(chunkJMJM7DMM_cjs.renderAlert({
|
|
15767
15799
|
type: "error",
|
|
15768
15800
|
message: "Failed to load users. Please try again.",
|
|
15769
15801
|
dismissible: true
|
|
@@ -15794,7 +15826,7 @@ userRoutes.get("/users/new", async (c) => {
|
|
|
15794
15826
|
return c.html(renderUserNewPage(pageData));
|
|
15795
15827
|
} catch (error) {
|
|
15796
15828
|
console.error("User new page error:", error);
|
|
15797
|
-
return c.html(
|
|
15829
|
+
return c.html(chunkJMJM7DMM_cjs.renderAlert({
|
|
15798
15830
|
type: "error",
|
|
15799
15831
|
message: "Failed to load user creation page. Please try again.",
|
|
15800
15832
|
dismissible: true
|
|
@@ -15828,12 +15860,12 @@ userRoutes.post("/users/new", async (c) => {
|
|
|
15828
15860
|
const validation = validateCustomData(sanitized, profileConfig);
|
|
15829
15861
|
if (!validation.valid) {
|
|
15830
15862
|
const errorMessages = Object.values(validation.errors).join(", ");
|
|
15831
|
-
return c.html(
|
|
15863
|
+
return c.html(chunkJMJM7DMM_cjs.renderAlert({ type: "error", message: errorMessages, dismissible: true }), 400);
|
|
15832
15864
|
}
|
|
15833
15865
|
sanitizedRegistrationCustom = sanitized;
|
|
15834
15866
|
}
|
|
15835
15867
|
if (!firstName || !lastName || !email || !password) {
|
|
15836
|
-
return c.html(
|
|
15868
|
+
return c.html(chunkJMJM7DMM_cjs.renderAlert({
|
|
15837
15869
|
type: "error",
|
|
15838
15870
|
message: "First name, last name, email, and password are required.",
|
|
15839
15871
|
dismissible: true
|
|
@@ -15841,21 +15873,21 @@ userRoutes.post("/users/new", async (c) => {
|
|
|
15841
15873
|
}
|
|
15842
15874
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
15843
15875
|
if (!emailRegex.test(email)) {
|
|
15844
|
-
return c.html(
|
|
15876
|
+
return c.html(chunkJMJM7DMM_cjs.renderAlert({
|
|
15845
15877
|
type: "error",
|
|
15846
15878
|
message: "Please enter a valid email address.",
|
|
15847
15879
|
dismissible: true
|
|
15848
15880
|
}));
|
|
15849
15881
|
}
|
|
15850
15882
|
if (password.length < 8) {
|
|
15851
|
-
return c.html(
|
|
15883
|
+
return c.html(chunkJMJM7DMM_cjs.renderAlert({
|
|
15852
15884
|
type: "error",
|
|
15853
15885
|
message: "Password must be at least 8 characters long.",
|
|
15854
15886
|
dismissible: true
|
|
15855
15887
|
}));
|
|
15856
15888
|
}
|
|
15857
15889
|
if (password !== confirmPassword) {
|
|
15858
|
-
return c.html(
|
|
15890
|
+
return c.html(chunkJMJM7DMM_cjs.renderAlert({
|
|
15859
15891
|
type: "error",
|
|
15860
15892
|
message: "Passwords do not match.",
|
|
15861
15893
|
dismissible: true
|
|
@@ -15867,13 +15899,13 @@ userRoutes.post("/users/new", async (c) => {
|
|
|
15867
15899
|
`);
|
|
15868
15900
|
const existingUser = await checkStmt.bind(email).first();
|
|
15869
15901
|
if (existingUser) {
|
|
15870
|
-
return c.html(
|
|
15902
|
+
return c.html(chunkJMJM7DMM_cjs.renderAlert({
|
|
15871
15903
|
type: "error",
|
|
15872
15904
|
message: "Email is already taken.",
|
|
15873
15905
|
dismissible: true
|
|
15874
15906
|
}));
|
|
15875
15907
|
}
|
|
15876
|
-
const passwordHash = await
|
|
15908
|
+
const passwordHash = await chunk37V3RET3_cjs.AuthManager.hashPassword(password);
|
|
15877
15909
|
const userId = crypto.randomUUID();
|
|
15878
15910
|
const createStmt = db.prepare(`
|
|
15879
15911
|
INSERT INTO auth_user (
|
|
@@ -15898,7 +15930,7 @@ userRoutes.post("/users/new", async (c) => {
|
|
|
15898
15930
|
if (sanitizedRegistrationCustom !== null && Object.keys(sanitizedRegistrationCustom).length > 0) {
|
|
15899
15931
|
await writeProfileData(db, userId, { custom: sanitizedRegistrationCustom }, user.userId);
|
|
15900
15932
|
}
|
|
15901
|
-
await
|
|
15933
|
+
await chunk37V3RET3_cjs.logActivity(
|
|
15902
15934
|
db,
|
|
15903
15935
|
user.userId,
|
|
15904
15936
|
"user!.create",
|
|
@@ -15912,7 +15944,7 @@ userRoutes.post("/users/new", async (c) => {
|
|
|
15912
15944
|
return c.body(null, 200);
|
|
15913
15945
|
} catch (error) {
|
|
15914
15946
|
console.error("User creation error:", error);
|
|
15915
|
-
return c.html(
|
|
15947
|
+
return c.html(chunkJMJM7DMM_cjs.renderAlert({
|
|
15916
15948
|
type: "error",
|
|
15917
15949
|
message: "Failed to create user!. Please try again.",
|
|
15918
15950
|
dismissible: true
|
|
@@ -15937,7 +15969,7 @@ userRoutes.get("/users/:id", async (c) => {
|
|
|
15937
15969
|
if (!userRecord) {
|
|
15938
15970
|
return c.json({ error: "User not found" }, 404);
|
|
15939
15971
|
}
|
|
15940
|
-
await
|
|
15972
|
+
await chunk37V3RET3_cjs.logActivity(
|
|
15941
15973
|
db,
|
|
15942
15974
|
user.userId,
|
|
15943
15975
|
"user!.view",
|
|
@@ -15982,7 +16014,7 @@ userRoutes.get("/users/:id/edit", async (c) => {
|
|
|
15982
16014
|
`);
|
|
15983
16015
|
const userToEdit = await userStmt.bind(userId).first();
|
|
15984
16016
|
if (!userToEdit) {
|
|
15985
|
-
return c.html(
|
|
16017
|
+
return c.html(chunkJMJM7DMM_cjs.renderAlert({
|
|
15986
16018
|
type: "error",
|
|
15987
16019
|
message: "User not found",
|
|
15988
16020
|
dismissible: true
|
|
@@ -16052,7 +16084,7 @@ userRoutes.get("/users/:id/edit", async (c) => {
|
|
|
16052
16084
|
return c.html(renderUserEditPage(pageData));
|
|
16053
16085
|
} catch (error) {
|
|
16054
16086
|
console.error("User edit page error:", error);
|
|
16055
|
-
return c.html(
|
|
16087
|
+
return c.html(chunkJMJM7DMM_cjs.renderAlert({
|
|
16056
16088
|
type: "error",
|
|
16057
16089
|
message: "Failed to load user. Please try again.",
|
|
16058
16090
|
dismissible: true
|
|
@@ -16085,12 +16117,12 @@ userRoutes.put("/users/:id", async (c) => {
|
|
|
16085
16117
|
const validation = validateCustomData(sanitized, profileConfig);
|
|
16086
16118
|
if (!validation.valid) {
|
|
16087
16119
|
const errorMessages = Object.values(validation.errors).join(", ");
|
|
16088
|
-
return c.html(
|
|
16120
|
+
return c.html(chunkJMJM7DMM_cjs.renderAlert({ type: "error", message: errorMessages, dismissible: true }), 400);
|
|
16089
16121
|
}
|
|
16090
16122
|
sanitizedCustom = sanitized;
|
|
16091
16123
|
}
|
|
16092
16124
|
if (!email) {
|
|
16093
|
-
return c.html(
|
|
16125
|
+
return c.html(chunkJMJM7DMM_cjs.renderAlert({
|
|
16094
16126
|
type: "error",
|
|
16095
16127
|
message: "Email is required.",
|
|
16096
16128
|
dismissible: true
|
|
@@ -16098,7 +16130,7 @@ userRoutes.put("/users/:id", async (c) => {
|
|
|
16098
16130
|
}
|
|
16099
16131
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
16100
16132
|
if (!emailRegex.test(email)) {
|
|
16101
|
-
return c.html(
|
|
16133
|
+
return c.html(chunkJMJM7DMM_cjs.renderAlert({
|
|
16102
16134
|
type: "error",
|
|
16103
16135
|
message: "Please enter a valid email address.",
|
|
16104
16136
|
dismissible: true
|
|
@@ -16106,14 +16138,14 @@ userRoutes.put("/users/:id", async (c) => {
|
|
|
16106
16138
|
}
|
|
16107
16139
|
if (newPassword) {
|
|
16108
16140
|
if (newPassword.length < 8) {
|
|
16109
|
-
return c.html(
|
|
16141
|
+
return c.html(chunkJMJM7DMM_cjs.renderAlert({
|
|
16110
16142
|
type: "error",
|
|
16111
16143
|
message: "Password must be at least 8 characters long.",
|
|
16112
16144
|
dismissible: true
|
|
16113
16145
|
}));
|
|
16114
16146
|
}
|
|
16115
16147
|
if (newPassword !== confirmPassword) {
|
|
16116
|
-
return c.html(
|
|
16148
|
+
return c.html(chunkJMJM7DMM_cjs.renderAlert({
|
|
16117
16149
|
type: "error",
|
|
16118
16150
|
message: "Passwords do not match.",
|
|
16119
16151
|
dismissible: true
|
|
@@ -16126,7 +16158,7 @@ userRoutes.put("/users/:id", async (c) => {
|
|
|
16126
16158
|
`);
|
|
16127
16159
|
const existingUser = await checkStmt.bind(email, userId).first();
|
|
16128
16160
|
if (existingUser) {
|
|
16129
|
-
return c.html(
|
|
16161
|
+
return c.html(chunkJMJM7DMM_cjs.renderAlert({
|
|
16130
16162
|
type: "error",
|
|
16131
16163
|
message: "Email is already taken by another user.",
|
|
16132
16164
|
dismissible: true
|
|
@@ -16151,7 +16183,7 @@ userRoutes.put("/users/:id", async (c) => {
|
|
|
16151
16183
|
userId
|
|
16152
16184
|
).run();
|
|
16153
16185
|
if (newPassword) {
|
|
16154
|
-
const passwordHash = await
|
|
16186
|
+
const passwordHash = await chunk37V3RET3_cjs.AuthManager.hashPassword(newPassword);
|
|
16155
16187
|
const updatePasswordStmt = db.prepare(`
|
|
16156
16188
|
UPDATE auth_user SET password_hash = ?, updated_at = ? WHERE id = ?
|
|
16157
16189
|
`);
|
|
@@ -16164,7 +16196,7 @@ userRoutes.put("/users/:id", async (c) => {
|
|
|
16164
16196
|
...sanitizedCustom !== null ? { custom: sanitizedCustom } : {}
|
|
16165
16197
|
}, user.userId);
|
|
16166
16198
|
}
|
|
16167
|
-
await
|
|
16199
|
+
await chunk37V3RET3_cjs.logActivity(
|
|
16168
16200
|
db,
|
|
16169
16201
|
user.userId,
|
|
16170
16202
|
"user.update",
|
|
@@ -16174,7 +16206,7 @@ userRoutes.put("/users/:id", async (c) => {
|
|
|
16174
16206
|
c.req.header("x-forwarded-for") || c.req.header("cf-connecting-ip"),
|
|
16175
16207
|
c.req.header("user-agent")
|
|
16176
16208
|
);
|
|
16177
|
-
return c.html(
|
|
16209
|
+
return c.html(chunkJMJM7DMM_cjs.renderAlert({
|
|
16178
16210
|
type: "success",
|
|
16179
16211
|
message: "User updated successfully!",
|
|
16180
16212
|
dismissible: true,
|
|
@@ -16182,7 +16214,7 @@ userRoutes.put("/users/:id", async (c) => {
|
|
|
16182
16214
|
}));
|
|
16183
16215
|
} catch (error) {
|
|
16184
16216
|
console.error("User update error:", error);
|
|
16185
|
-
return c.html(
|
|
16217
|
+
return c.html(chunkJMJM7DMM_cjs.renderAlert({
|
|
16186
16218
|
type: "error",
|
|
16187
16219
|
message: "Failed to update user. Please try again.",
|
|
16188
16220
|
dismissible: true
|
|
@@ -16210,7 +16242,7 @@ userRoutes.post("/users/:id/toggle", async (c) => {
|
|
|
16210
16242
|
UPDATE auth_user SET is_active = ?, updated_at = ? WHERE id = ?
|
|
16211
16243
|
`);
|
|
16212
16244
|
await toggleStmt.bind(active ? 1 : 0, Date.now(), userId).run();
|
|
16213
|
-
await
|
|
16245
|
+
await chunk37V3RET3_cjs.logActivity(
|
|
16214
16246
|
db,
|
|
16215
16247
|
user.userId,
|
|
16216
16248
|
active ? "user.activate" : "user.deactivate",
|
|
@@ -16251,7 +16283,7 @@ userRoutes.delete("/users/:id", async (c) => {
|
|
|
16251
16283
|
DELETE FROM auth_user WHERE id = ?
|
|
16252
16284
|
`);
|
|
16253
16285
|
await deleteStmt.bind(userId).run();
|
|
16254
|
-
await
|
|
16286
|
+
await chunk37V3RET3_cjs.logActivity(
|
|
16255
16287
|
db,
|
|
16256
16288
|
user.userId,
|
|
16257
16289
|
"user!.hard_delete",
|
|
@@ -16270,7 +16302,7 @@ userRoutes.delete("/users/:id", async (c) => {
|
|
|
16270
16302
|
UPDATE auth_user SET is_active = 0, updated_at = ? WHERE id = ?
|
|
16271
16303
|
`);
|
|
16272
16304
|
await deleteStmt.bind(Date.now(), userId).run();
|
|
16273
|
-
await
|
|
16305
|
+
await chunk37V3RET3_cjs.logActivity(
|
|
16274
16306
|
db,
|
|
16275
16307
|
user.userId,
|
|
16276
16308
|
"user!.soft_delete",
|
|
@@ -16336,7 +16368,7 @@ userRoutes.post("/invite-user", async (c) => {
|
|
|
16336
16368
|
Date.now(),
|
|
16337
16369
|
Date.now()
|
|
16338
16370
|
).run();
|
|
16339
|
-
await
|
|
16371
|
+
await chunk37V3RET3_cjs.logActivity(
|
|
16340
16372
|
db,
|
|
16341
16373
|
user.userId,
|
|
16342
16374
|
"user!.invite_sent",
|
|
@@ -16393,7 +16425,7 @@ userRoutes.post("/resend-invitation/:id", async (c) => {
|
|
|
16393
16425
|
Date.now(),
|
|
16394
16426
|
userId
|
|
16395
16427
|
).run();
|
|
16396
|
-
await
|
|
16428
|
+
await chunk37V3RET3_cjs.logActivity(
|
|
16397
16429
|
db,
|
|
16398
16430
|
user.userId,
|
|
16399
16431
|
"user!.invitation_resent",
|
|
@@ -16429,7 +16461,7 @@ userRoutes.delete("/cancel-invitation/:id", async (c) => {
|
|
|
16429
16461
|
}
|
|
16430
16462
|
const deleteStmt = db.prepare(`DELETE FROM auth_user WHERE id = ?`);
|
|
16431
16463
|
await deleteStmt.bind(userId).run();
|
|
16432
|
-
await
|
|
16464
|
+
await chunk37V3RET3_cjs.logActivity(
|
|
16433
16465
|
db,
|
|
16434
16466
|
user.userId,
|
|
16435
16467
|
"user!.invitation_cancelled",
|
|
@@ -16678,7 +16710,7 @@ function getFileIcon(mimeType) {
|
|
|
16678
16710
|
}
|
|
16679
16711
|
|
|
16680
16712
|
// src/templates/pages/admin-media-library.template.ts
|
|
16681
|
-
|
|
16713
|
+
chunkUYJQDDEE_cjs.init_admin_layout_catalyst_template();
|
|
16682
16714
|
function renderMediaLibraryPage(data) {
|
|
16683
16715
|
const pageContent = `
|
|
16684
16716
|
<div>
|
|
@@ -17613,7 +17645,7 @@ function renderMediaLibraryPage(data) {
|
|
|
17613
17645
|
version: data.version,
|
|
17614
17646
|
content: pageContent
|
|
17615
17647
|
};
|
|
17616
|
-
return
|
|
17648
|
+
return chunkUYJQDDEE_cjs.renderAdminLayoutCatalyst(layoutData);
|
|
17617
17649
|
}
|
|
17618
17650
|
|
|
17619
17651
|
// src/templates/components/media-file-details.template.ts
|
|
@@ -17810,7 +17842,7 @@ var fileValidationSchema2 = zod.z.object({
|
|
|
17810
17842
|
// 50MB max
|
|
17811
17843
|
});
|
|
17812
17844
|
var adminMediaRoutes = new hono.Hono();
|
|
17813
|
-
adminMediaRoutes.use("*",
|
|
17845
|
+
adminMediaRoutes.use("*", chunk37V3RET3_cjs.requireAuth());
|
|
17814
17846
|
adminMediaRoutes.get("/", async (c) => {
|
|
17815
17847
|
try {
|
|
17816
17848
|
const user = c.get("user");
|
|
@@ -17852,7 +17884,7 @@ adminMediaRoutes.get("/selector", async (c) => {
|
|
|
17852
17884
|
const { searchParams } = new URL(c.req.url);
|
|
17853
17885
|
const search = searchParams.get("search") || "";
|
|
17854
17886
|
const db = c.env.DB;
|
|
17855
|
-
const pluginService = new
|
|
17887
|
+
const pluginService = new chunkQCJHCSOK_cjs.PluginService(db);
|
|
17856
17888
|
const mediaPlugin = await pluginService.getPlugin("core-media");
|
|
17857
17889
|
if (!mediaPlugin || mediaPlugin.status !== "active") {
|
|
17858
17890
|
return c.html(html.html`
|
|
@@ -18228,7 +18260,7 @@ adminMediaRoutes.put("/:id", async (c) => {
|
|
|
18228
18260
|
`);
|
|
18229
18261
|
}
|
|
18230
18262
|
});
|
|
18231
|
-
adminMediaRoutes.delete("/cleanup",
|
|
18263
|
+
adminMediaRoutes.delete("/cleanup", chunk37V3RET3_cjs.requireRole("admin"), async (c) => {
|
|
18232
18264
|
try {
|
|
18233
18265
|
const db = c.env.DB;
|
|
18234
18266
|
const allMediaStmt = db.prepare("SELECT id, r2_key, filename FROM media WHERE deleted_at IS NULL");
|
|
@@ -18486,7 +18518,7 @@ function generateMediaItemHTML(file) {
|
|
|
18486
18518
|
}
|
|
18487
18519
|
|
|
18488
18520
|
// src/templates/pages/admin-plugins-list.template.ts
|
|
18489
|
-
|
|
18521
|
+
chunkUYJQDDEE_cjs.init_admin_layout_catalyst_template();
|
|
18490
18522
|
function renderPluginsListPage(data) {
|
|
18491
18523
|
const categories = [
|
|
18492
18524
|
{ value: "content", label: "Content Management" },
|
|
@@ -18969,7 +19001,7 @@ function renderPluginsListPage(data) {
|
|
|
18969
19001
|
version: data.version,
|
|
18970
19002
|
content: pageContent
|
|
18971
19003
|
};
|
|
18972
|
-
return
|
|
19004
|
+
return chunkUYJQDDEE_cjs.renderAdminLayoutCatalyst(layoutData);
|
|
18973
19005
|
}
|
|
18974
19006
|
function renderPluginCard(plugin) {
|
|
18975
19007
|
const statusColors = {
|
|
@@ -19346,8 +19378,9 @@ function escapeHtmlAttr(value) {
|
|
|
19346
19378
|
return value.replace(/&/g, "&").replace(/"/g, """).replace(/'/g, "'").replace(/</g, "<").replace(/>/g, ">");
|
|
19347
19379
|
}
|
|
19348
19380
|
function renderPluginSettingsPage(data) {
|
|
19349
|
-
const { plugin, activity = [], user } = data;
|
|
19350
|
-
const
|
|
19381
|
+
const { plugin, activity = [], user, settingsTabData } = data;
|
|
19382
|
+
const pluginDef = chunkBP52BFIV_cjs.getPluginDefinition(plugin.id || plugin.name);
|
|
19383
|
+
const hasUserSettings = pluginDef?.settingsTabContent != null || Object.keys(plugin.settings || {}).some((k) => !k.startsWith("_"));
|
|
19351
19384
|
const defaultTab = hasUserSettings ? "settings" : "info";
|
|
19352
19385
|
const pageContent = `
|
|
19353
19386
|
<div class="w-full px-4 sm:px-6 lg:px-8 py-6">
|
|
@@ -19427,7 +19460,7 @@ function renderPluginSettingsPage(data) {
|
|
|
19427
19460
|
<div id="tab-content">
|
|
19428
19461
|
<!-- Settings Tab -->
|
|
19429
19462
|
<div id="settings-content" class="tab-content hidden">
|
|
19430
|
-
${hasUserSettings ? renderSettingsTab(plugin) : ""}
|
|
19463
|
+
${hasUserSettings ? renderSettingsTab(plugin, settingsTabData) : ""}
|
|
19431
19464
|
</div>
|
|
19432
19465
|
|
|
19433
19466
|
<!-- Activity Tab -->
|
|
@@ -19623,7 +19656,7 @@ function renderPluginSettingsPage(data) {
|
|
|
19623
19656
|
user,
|
|
19624
19657
|
content: pageContent
|
|
19625
19658
|
};
|
|
19626
|
-
return
|
|
19659
|
+
return chunkE66UVONV_cjs.renderAdminLayout(layoutData);
|
|
19627
19660
|
}
|
|
19628
19661
|
function renderStatusBadge(status) {
|
|
19629
19662
|
const statusColors = {
|
|
@@ -19648,10 +19681,14 @@ function renderToggleButton(plugin) {
|
|
|
19648
19681
|
}
|
|
19649
19682
|
return plugin.status === "active" ? `<button onclick="togglePlugin('${plugin.id}', 'deactivate')" class="bg-red-600 hover:bg-red-700 text-white px-4 py-2 rounded-lg text-sm font-medium transition-colors">Deactivate</button>` : `<button onclick="togglePlugin('${plugin.id}', 'activate')" class="bg-green-600 hover:bg-green-700 text-white px-4 py-2 rounded-lg text-sm font-medium transition-colors">Activate</button>`;
|
|
19650
19683
|
}
|
|
19651
|
-
function renderSettingsTab(plugin) {
|
|
19684
|
+
function renderSettingsTab(plugin, settingsTabData) {
|
|
19652
19685
|
const settings = plugin.settings || {};
|
|
19653
19686
|
const pluginId = plugin.id || plugin.name;
|
|
19654
19687
|
const hasUserKeys = Object.keys(settings).some((k) => !k.startsWith("_"));
|
|
19688
|
+
const pluginDef = chunkBP52BFIV_cjs.getPluginDefinition(pluginId);
|
|
19689
|
+
if (pluginDef?.settingsTabContent) {
|
|
19690
|
+
return pluginDef.settingsTabContent.render({ plugin, settings, data: settingsTabData });
|
|
19691
|
+
}
|
|
19655
19692
|
const customRenderer = pluginSettingsComponents[pluginId];
|
|
19656
19693
|
if (customRenderer) {
|
|
19657
19694
|
return `
|
|
@@ -19998,8 +20035,7 @@ function formatTimestamp(timestamp) {
|
|
|
19998
20035
|
}
|
|
19999
20036
|
var pluginSettingsComponents = {
|
|
20000
20037
|
"otp-login": renderOTPLoginSettingsContent,
|
|
20001
|
-
"email": renderEmailSettingsContent
|
|
20002
|
-
"oauth-providers": renderOAuthProvidersSettingsContent
|
|
20038
|
+
"email": renderEmailSettingsContent
|
|
20003
20039
|
};
|
|
20004
20040
|
function renderOTPLoginSettingsContent(plugin, settings) {
|
|
20005
20041
|
const siteName = settings.siteName || "SonicJS";
|
|
@@ -20722,105 +20758,163 @@ defineUserProfile({
|
|
|
20722
20758
|
</div>
|
|
20723
20759
|
`;
|
|
20724
20760
|
}
|
|
20725
|
-
function renderOAuthProvidersSettingsContent(_plugin, settings) {
|
|
20726
|
-
const providers = settings.providers || {};
|
|
20727
|
-
const github = providers.github || {};
|
|
20728
|
-
const google = providers.google || {};
|
|
20729
|
-
const inputClass = "w-full px-3 py-2 rounded-lg bg-white/5 border border-white/10 focus:border-blue-500 focus:outline-none text-white";
|
|
20730
|
-
function renderProviderCard(name, label, icon, data) {
|
|
20731
|
-
const clientId = escapeHtmlAttr(data.clientId || "");
|
|
20732
|
-
const clientSecret = escapeHtmlAttr(data.clientSecret || "");
|
|
20733
|
-
const enabled = data.enabled === true;
|
|
20734
|
-
return `
|
|
20735
|
-
<div class="backdrop-blur-md bg-white/5 rounded-xl border border-white/10 p-6">
|
|
20736
|
-
<div class="flex items-center justify-between mb-4">
|
|
20737
|
-
<h3 class="text-lg font-semibold text-white flex items-center gap-2">
|
|
20738
|
-
<span>${icon}</span> ${label}
|
|
20739
|
-
</h3>
|
|
20740
|
-
<label class="relative inline-flex items-center cursor-pointer">
|
|
20741
|
-
<input type="checkbox" id="oauth_${name}_enabled" ${enabled ? "checked" : ""} class="sr-only peer">
|
|
20742
|
-
<div class="w-11 h-6 bg-gray-600 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-800 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-blue-600"></div>
|
|
20743
|
-
<span class="ml-2 text-sm text-gray-300">Enabled</span>
|
|
20744
|
-
</label>
|
|
20745
|
-
</div>
|
|
20746
|
-
<div class="space-y-4">
|
|
20747
|
-
<div>
|
|
20748
|
-
<label for="oauth_${name}_clientId" class="block text-sm font-medium text-gray-300 mb-2">Client ID</label>
|
|
20749
|
-
<input type="text" id="oauth_${name}_clientId" value="${clientId}" placeholder="${label} OAuth Client ID" class="${inputClass}">
|
|
20750
|
-
</div>
|
|
20751
|
-
<div>
|
|
20752
|
-
<label for="oauth_${name}_clientSecret" class="block text-sm font-medium text-gray-300 mb-2">Client Secret</label>
|
|
20753
|
-
<input type="password" id="oauth_${name}_clientSecret" value="${clientSecret}" placeholder="${label} OAuth Client Secret" class="${inputClass}">
|
|
20754
|
-
</div>
|
|
20755
|
-
</div>
|
|
20756
|
-
</div>
|
|
20757
|
-
`;
|
|
20758
|
-
}
|
|
20759
|
-
return `
|
|
20760
|
-
<div class="space-y-6">
|
|
20761
|
-
<div class="bg-blue-500/10 border border-blue-500/20 rounded-lg p-4">
|
|
20762
|
-
<p class="text-blue-200 text-sm">
|
|
20763
|
-
Configure OAuth provider credentials below. Credentials are stored securely and used server-side only.
|
|
20764
|
-
Make sure to add the callback URL <code class="text-blue-300">/auth/oauth/[provider]/callback</code> to your OAuth app's allowed redirect URIs.
|
|
20765
|
-
</p>
|
|
20766
|
-
</div>
|
|
20767
|
-
|
|
20768
|
-
${renderProviderCard("github", "GitHub", "\u{1F419}", github)}
|
|
20769
|
-
${renderProviderCard("google", "Google", "\u{1F535}", google)}
|
|
20770
|
-
</div>
|
|
20771
20761
|
|
|
20772
|
-
|
|
20773
|
-
|
|
20774
|
-
|
|
20775
|
-
|
|
20776
|
-
|
|
20777
|
-
|
|
20778
|
-
|
|
20779
|
-
|
|
20780
|
-
|
|
20781
|
-
|
|
20782
|
-
|
|
20783
|
-
|
|
20784
|
-
|
|
20785
|
-
|
|
20786
|
-
|
|
20787
|
-
|
|
20788
|
-
|
|
20789
|
-
|
|
20790
|
-
|
|
20791
|
-
|
|
20792
|
-
|
|
20793
|
-
|
|
20794
|
-
|
|
20795
|
-
|
|
20796
|
-
|
|
20797
|
-
|
|
20798
|
-
|
|
20799
|
-
|
|
20800
|
-
|
|
20801
|
-
|
|
20802
|
-
|
|
20803
|
-
|
|
20804
|
-
|
|
20805
|
-
|
|
20806
|
-
|
|
20807
|
-
|
|
20808
|
-
|
|
20809
|
-
|
|
20810
|
-
|
|
20811
|
-
|
|
20812
|
-
|
|
20813
|
-
|
|
20814
|
-
|
|
20815
|
-
|
|
20816
|
-
|
|
20817
|
-
|
|
20762
|
+
// src/plugins/core-plugins/menu-plugin/services/menu-reconcile.ts
|
|
20763
|
+
async function upsertPluginRow(db, slug, entry, visible) {
|
|
20764
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
20765
|
+
const existing = await db.prepare(
|
|
20766
|
+
`SELECT id FROM documents
|
|
20767
|
+
WHERE slug = ? AND type_id = 'menu_item' AND tenant_id = 'default'
|
|
20768
|
+
AND is_current_draft = 1 AND deleted_at IS NULL`
|
|
20769
|
+
).bind(slug).first();
|
|
20770
|
+
if (existing) {
|
|
20771
|
+
await db.prepare(
|
|
20772
|
+
`UPDATE documents
|
|
20773
|
+
SET data = json_set(data, '$.url', ?, '$.pluginId', ?, '$.visible', ?),
|
|
20774
|
+
visible = ?,
|
|
20775
|
+
updated_at = ?
|
|
20776
|
+
WHERE id = ? AND tenant_id = 'default'`
|
|
20777
|
+
).bind(entry.url, entry.pluginId, visible ? 1 : 0, visible ? 1 : 0, now, existing.id).run();
|
|
20778
|
+
return;
|
|
20779
|
+
}
|
|
20780
|
+
const id = chunkKIGVVO6N_cjs.nanoid();
|
|
20781
|
+
const data = JSON.stringify({
|
|
20782
|
+
label: entry.label,
|
|
20783
|
+
url: entry.url,
|
|
20784
|
+
icon: entry.icon,
|
|
20785
|
+
target: "_self",
|
|
20786
|
+
isExternal: false,
|
|
20787
|
+
visible,
|
|
20788
|
+
parent: null,
|
|
20789
|
+
source: "plugin",
|
|
20790
|
+
pluginId: entry.pluginId,
|
|
20791
|
+
permissions: [],
|
|
20792
|
+
lockedFields: ["url"],
|
|
20793
|
+
sortOrder: entry.sortOrder
|
|
20794
|
+
});
|
|
20795
|
+
await db.prepare(
|
|
20796
|
+
`INSERT INTO documents (id, root_id, type_id, type_version, version_of_id, version_number,
|
|
20797
|
+
is_current_draft, is_published, status, parent_root_id, slug, path, title, zone,
|
|
20798
|
+
sort_order, visible, published_at, scheduled_at, expires_at, deleted_at,
|
|
20799
|
+
tenant_id, locale, translation_group_id, data, metadata,
|
|
20800
|
+
owner_id, created_by, updated_by, created_at, updated_at)
|
|
20801
|
+
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`
|
|
20802
|
+
).bind(
|
|
20803
|
+
id,
|
|
20804
|
+
id,
|
|
20805
|
+
"menu_item",
|
|
20806
|
+
1,
|
|
20807
|
+
null,
|
|
20808
|
+
1,
|
|
20809
|
+
1,
|
|
20810
|
+
0,
|
|
20811
|
+
"draft",
|
|
20812
|
+
"",
|
|
20813
|
+
slug,
|
|
20814
|
+
null,
|
|
20815
|
+
entry.label,
|
|
20816
|
+
null,
|
|
20817
|
+
entry.sortOrder,
|
|
20818
|
+
visible ? 1 : 0,
|
|
20819
|
+
null,
|
|
20820
|
+
null,
|
|
20821
|
+
null,
|
|
20822
|
+
null,
|
|
20823
|
+
"default",
|
|
20824
|
+
"default",
|
|
20825
|
+
"",
|
|
20826
|
+
data,
|
|
20827
|
+
"{}",
|
|
20828
|
+
null,
|
|
20829
|
+
null,
|
|
20830
|
+
null,
|
|
20831
|
+
now,
|
|
20832
|
+
now
|
|
20833
|
+
).run();
|
|
20834
|
+
}
|
|
20835
|
+
async function deactivateStalePluginRows(db, activePluginIds) {
|
|
20836
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
20837
|
+
const rows = await db.prepare(
|
|
20838
|
+
`SELECT id, data FROM documents
|
|
20839
|
+
WHERE type_id = 'menu_item' AND tenant_id = 'default'
|
|
20840
|
+
AND is_current_draft = 1 AND deleted_at IS NULL
|
|
20841
|
+
AND json_extract(data, '$.source') = 'plugin'`
|
|
20842
|
+
).all();
|
|
20843
|
+
const stale = (rows.results ?? []).filter((row) => {
|
|
20844
|
+
let pluginId;
|
|
20845
|
+
try {
|
|
20846
|
+
pluginId = JSON.parse(row.data)?.pluginId;
|
|
20847
|
+
} catch {
|
|
20848
|
+
return false;
|
|
20849
|
+
}
|
|
20850
|
+
return pluginId !== void 0 && !activePluginIds.has(pluginId);
|
|
20851
|
+
});
|
|
20852
|
+
if (stale.length === 0) return;
|
|
20853
|
+
await db.batch(
|
|
20854
|
+
stale.map(
|
|
20855
|
+
(row) => db.prepare(
|
|
20856
|
+
`UPDATE documents
|
|
20857
|
+
SET data = json_set(data, '$.visible', 0), visible = 0, updated_at = ?
|
|
20858
|
+
WHERE id = ? AND tenant_id = 'default'`
|
|
20859
|
+
).bind(now, row.id)
|
|
20860
|
+
)
|
|
20861
|
+
);
|
|
20862
|
+
}
|
|
20863
|
+
async function fetchActivePluginIds(db) {
|
|
20864
|
+
try {
|
|
20865
|
+
const rows = await db.prepare(
|
|
20866
|
+
`SELECT slug FROM documents
|
|
20867
|
+
WHERE type_id = 'plugin' AND tenant_id = 'default'
|
|
20868
|
+
AND is_current_draft = 1 AND deleted_at IS NULL
|
|
20869
|
+
AND json_extract(data, '$.status') = 'active'`
|
|
20870
|
+
).all();
|
|
20871
|
+
return new Set((rows.results ?? []).map((r) => r.slug));
|
|
20872
|
+
} catch {
|
|
20873
|
+
return /* @__PURE__ */ new Set();
|
|
20874
|
+
}
|
|
20875
|
+
}
|
|
20876
|
+
async function reconcileMenuFromPlugins(db) {
|
|
20877
|
+
try {
|
|
20878
|
+
const singletonEntries = chunkBP52BFIV_cjs.getPluginMenu();
|
|
20879
|
+
const manifestEntries = Object.values(chunkQCJHCSOK_cjs.PLUGIN_REGISTRY).filter(
|
|
20880
|
+
(p) => p.adminMenu !== null
|
|
20881
|
+
);
|
|
20882
|
+
const byPluginId = /* @__PURE__ */ new Map();
|
|
20883
|
+
manifestEntries.forEach((p, idx) => {
|
|
20884
|
+
const menu = p.adminMenu;
|
|
20885
|
+
byPluginId.set(p.id, {
|
|
20886
|
+
pluginId: p.id,
|
|
20887
|
+
label: menu.label,
|
|
20888
|
+
url: menu.path,
|
|
20889
|
+
icon: menu.icon,
|
|
20890
|
+
sortOrder: 100 + idx * 10
|
|
20891
|
+
});
|
|
20892
|
+
});
|
|
20893
|
+
singletonEntries.forEach((entry, idx) => {
|
|
20894
|
+
const pathParts = entry.path.replace(/\/$/, "").split("/");
|
|
20895
|
+
const pluginId = pathParts[pathParts.length - 1] || entry.label.toLowerCase().replace(/\s+/g, "-");
|
|
20896
|
+
byPluginId.set(pluginId, {
|
|
20897
|
+
pluginId,
|
|
20898
|
+
label: entry.label,
|
|
20899
|
+
url: entry.path,
|
|
20900
|
+
icon: entry.icon ?? "puzzle-piece",
|
|
20901
|
+
sortOrder: 100 + idx * 10
|
|
20902
|
+
});
|
|
20903
|
+
});
|
|
20904
|
+
const activeIds = await fetchActivePluginIds(db);
|
|
20905
|
+
for (const [pluginId, entry] of byPluginId) {
|
|
20906
|
+
const slug = `menu:plugin:${pluginId}`;
|
|
20907
|
+
await upsertPluginRow(db, slug, entry, activeIds.has(pluginId));
|
|
20908
|
+
}
|
|
20909
|
+
await deactivateStalePluginRows(db, activeIds);
|
|
20910
|
+
} catch {
|
|
20911
|
+
}
|
|
20818
20912
|
}
|
|
20819
20913
|
|
|
20820
20914
|
// src/routes/admin-plugins.ts
|
|
20821
20915
|
var adminPluginRoutes = new hono.Hono();
|
|
20822
|
-
adminPluginRoutes.use("*",
|
|
20823
|
-
var AVAILABLE_PLUGINS = Object.values(
|
|
20916
|
+
adminPluginRoutes.use("*", chunk37V3RET3_cjs.requireAuth());
|
|
20917
|
+
var AVAILABLE_PLUGINS = Object.values(chunkQCJHCSOK_cjs.PLUGIN_REGISTRY).map((p) => ({
|
|
20824
20918
|
id: p.id,
|
|
20825
20919
|
name: p.codeName,
|
|
20826
20920
|
display_name: p.displayName,
|
|
@@ -20840,7 +20934,7 @@ adminPluginRoutes.get("/", async (c) => {
|
|
|
20840
20934
|
if (user?.role !== "admin") {
|
|
20841
20935
|
return c.text("Access denied", 403);
|
|
20842
20936
|
}
|
|
20843
|
-
const pluginService = new
|
|
20937
|
+
const pluginService = new chunkQCJHCSOK_cjs.PluginService(db);
|
|
20844
20938
|
let installedPlugins = [];
|
|
20845
20939
|
let stats = { total: 0, active: 0, inactive: 0, errors: 0, uninstalled: 0 };
|
|
20846
20940
|
try {
|
|
@@ -20849,9 +20943,11 @@ adminPluginRoutes.get("/", async (c) => {
|
|
|
20849
20943
|
} catch (error) {
|
|
20850
20944
|
console.error("Error loading plugins:", error);
|
|
20851
20945
|
}
|
|
20852
|
-
const
|
|
20946
|
+
const registryIds = new Set(AVAILABLE_PLUGINS.map((p) => p.id));
|
|
20947
|
+
const validInstalledPlugins = installedPlugins.filter((p) => registryIds.has(p.id));
|
|
20948
|
+
const installedPluginIds = new Set(validInstalledPlugins.map((p) => p.id));
|
|
20853
20949
|
const uninstalledPlugins = AVAILABLE_PLUGINS.filter((p) => !installedPluginIds.has(p.id));
|
|
20854
|
-
const templatePlugins =
|
|
20950
|
+
const templatePlugins = validInstalledPlugins.map((p) => ({
|
|
20855
20951
|
id: p.id,
|
|
20856
20952
|
name: p.name,
|
|
20857
20953
|
displayName: p.display_name,
|
|
@@ -20887,7 +20983,7 @@ adminPluginRoutes.get("/", async (c) => {
|
|
|
20887
20983
|
}));
|
|
20888
20984
|
const allPlugins = [...templatePlugins, ...uninstalledTemplatePlugins];
|
|
20889
20985
|
stats.uninstalled = uninstalledPlugins.length;
|
|
20890
|
-
stats.total =
|
|
20986
|
+
stats.total = validInstalledPlugins.length + uninstalledPlugins.length;
|
|
20891
20987
|
const pageData = {
|
|
20892
20988
|
plugins: allPlugins,
|
|
20893
20989
|
stats,
|
|
@@ -20912,10 +21008,10 @@ adminPluginRoutes.get("/:id", async (c) => {
|
|
|
20912
21008
|
if (user?.role !== "admin") {
|
|
20913
21009
|
return c.redirect("/admin/plugins");
|
|
20914
21010
|
}
|
|
20915
|
-
const pluginService = new
|
|
21011
|
+
const pluginService = new chunkQCJHCSOK_cjs.PluginService(db);
|
|
20916
21012
|
let plugin = await pluginService.getPlugin(pluginId);
|
|
20917
21013
|
if (!plugin) {
|
|
20918
|
-
const def =
|
|
21014
|
+
const def = chunkBP52BFIV_cjs.getPluginDefinition(pluginId);
|
|
20919
21015
|
if (!def) return c.text("Plugin not found", 404);
|
|
20920
21016
|
plugin = await pluginService.ensurePlugin(pluginId, {
|
|
20921
21017
|
displayName: def.displayName ?? pluginId,
|
|
@@ -20986,6 +21082,15 @@ adminPluginRoutes.get("/:id", async (c) => {
|
|
|
20986
21082
|
timestamp: item.timestamp,
|
|
20987
21083
|
user: item.userId || null
|
|
20988
21084
|
}));
|
|
21085
|
+
const pluginDef = chunkBP52BFIV_cjs.getPluginDefinition(pluginId);
|
|
21086
|
+
let settingsTabData = void 0;
|
|
21087
|
+
if (pluginDef?.settingsTabContent?.loadData) {
|
|
21088
|
+
try {
|
|
21089
|
+
settingsTabData = await pluginDef.settingsTabContent.loadData(db);
|
|
21090
|
+
} catch (e) {
|
|
21091
|
+
console.error(`settingsTabContent.loadData failed for plugin "${pluginId}":`, e);
|
|
21092
|
+
}
|
|
21093
|
+
}
|
|
20989
21094
|
const pageData = {
|
|
20990
21095
|
plugin: templatePlugin,
|
|
20991
21096
|
activity: templateActivity,
|
|
@@ -20993,7 +21098,8 @@ adminPluginRoutes.get("/:id", async (c) => {
|
|
|
20993
21098
|
name: user?.email || "User",
|
|
20994
21099
|
email: user?.email || "",
|
|
20995
21100
|
role: user?.role || "user"
|
|
20996
|
-
}
|
|
21101
|
+
},
|
|
21102
|
+
settingsTabData
|
|
20997
21103
|
};
|
|
20998
21104
|
return c.html(renderPluginSettingsPage(pageData));
|
|
20999
21105
|
} catch (error) {
|
|
@@ -21006,14 +21112,14 @@ adminPluginRoutes.get("/:id/configure", async (c) => {
|
|
|
21006
21112
|
const user = c.get("user");
|
|
21007
21113
|
const pluginId = c.req.param("id");
|
|
21008
21114
|
if (user?.role !== "admin") return c.redirect("/admin/plugins");
|
|
21009
|
-
const def =
|
|
21115
|
+
const def = chunkBP52BFIV_cjs.getPluginDefinition(pluginId);
|
|
21010
21116
|
if (!def?.configSchema) return c.text("No schema-driven settings for this plugin", 404);
|
|
21011
21117
|
const db = c.env.DB;
|
|
21012
|
-
const pluginService = new
|
|
21118
|
+
const pluginService = new chunkQCJHCSOK_cjs.PluginService(db);
|
|
21013
21119
|
const plugin = await pluginService.getPlugin(pluginId);
|
|
21014
21120
|
const stored = plugin?.settings ?? {};
|
|
21015
|
-
const values =
|
|
21016
|
-
const fieldsHtml =
|
|
21121
|
+
const values = chunkBP52BFIV_cjs.applySchemaDefaults(def.configSchema, stored);
|
|
21122
|
+
const fieldsHtml = chunkBP52BFIV_cjs.renderSchemaFields(def.configSchema, values);
|
|
21017
21123
|
const displayName = plugin?.display_name ?? def.displayName ?? def.id;
|
|
21018
21124
|
return c.html(`<!DOCTYPE html>
|
|
21019
21125
|
<html lang="en"><head>
|
|
@@ -21040,12 +21146,12 @@ adminPluginRoutes.post("/:id/configure", async (c) => {
|
|
|
21040
21146
|
const user = c.get("user");
|
|
21041
21147
|
const pluginId = c.req.param("id");
|
|
21042
21148
|
if (user?.role !== "admin") return c.json({ error: "Access denied" }, 403);
|
|
21043
|
-
const def =
|
|
21149
|
+
const def = chunkBP52BFIV_cjs.getPluginDefinition(pluginId);
|
|
21044
21150
|
if (!def?.configSchema) return c.text("No schema-driven settings for this plugin", 404);
|
|
21045
21151
|
const form = await c.req.formData();
|
|
21046
|
-
const parsed =
|
|
21152
|
+
const parsed = chunkBP52BFIV_cjs.parseFormDataToSettings(def.configSchema, form);
|
|
21047
21153
|
const db = c.env.DB;
|
|
21048
|
-
const pluginService = new
|
|
21154
|
+
const pluginService = new chunkQCJHCSOK_cjs.PluginService(db);
|
|
21049
21155
|
await pluginService.ensurePlugin(pluginId, {
|
|
21050
21156
|
displayName: def.displayName ?? pluginId,
|
|
21051
21157
|
version: def.version,
|
|
@@ -21069,8 +21175,9 @@ adminPluginRoutes.post("/:id/activate", async (c) => {
|
|
|
21069
21175
|
if (user?.role !== "admin") {
|
|
21070
21176
|
return c.json({ error: "Access denied" }, 403);
|
|
21071
21177
|
}
|
|
21072
|
-
const pluginService = new
|
|
21178
|
+
const pluginService = new chunkQCJHCSOK_cjs.PluginService(db);
|
|
21073
21179
|
await pluginService.activatePlugin(pluginId);
|
|
21180
|
+
await reconcileMenuFromPlugins(db);
|
|
21074
21181
|
return c.json({ success: true });
|
|
21075
21182
|
} catch (error) {
|
|
21076
21183
|
console.error("Error activating plugin:", error);
|
|
@@ -21086,8 +21193,9 @@ adminPluginRoutes.post("/:id/deactivate", async (c) => {
|
|
|
21086
21193
|
if (user?.role !== "admin") {
|
|
21087
21194
|
return c.json({ error: "Access denied" }, 403);
|
|
21088
21195
|
}
|
|
21089
|
-
const pluginService = new
|
|
21196
|
+
const pluginService = new chunkQCJHCSOK_cjs.PluginService(db);
|
|
21090
21197
|
await pluginService.deactivatePlugin(pluginId);
|
|
21198
|
+
await reconcileMenuFromPlugins(db);
|
|
21091
21199
|
return c.json({ success: true });
|
|
21092
21200
|
} catch (error) {
|
|
21093
21201
|
console.error("Error deactivating plugin:", error);
|
|
@@ -21103,8 +21211,8 @@ adminPluginRoutes.post("/install", async (c) => {
|
|
|
21103
21211
|
return c.json({ error: "Access denied" }, 403);
|
|
21104
21212
|
}
|
|
21105
21213
|
const body = await c.req.json();
|
|
21106
|
-
const pluginService = new
|
|
21107
|
-
const registryEntry =
|
|
21214
|
+
const pluginService = new chunkQCJHCSOK_cjs.PluginService(db);
|
|
21215
|
+
const registryEntry = chunkQCJHCSOK_cjs.findPluginByCodeName(body.name) || chunkQCJHCSOK_cjs.PLUGIN_REGISTRY[body.name] || chunkQCJHCSOK_cjs.PLUGIN_REGISTRY[body.id];
|
|
21108
21216
|
if (!registryEntry) {
|
|
21109
21217
|
return c.json({ error: "Plugin not found in registry" }, 404);
|
|
21110
21218
|
}
|
|
@@ -21137,7 +21245,7 @@ adminPluginRoutes.post("/:id/uninstall", async (c) => {
|
|
|
21137
21245
|
if (user?.role !== "admin") {
|
|
21138
21246
|
return c.json({ error: "Access denied" }, 403);
|
|
21139
21247
|
}
|
|
21140
|
-
const pluginService = new
|
|
21248
|
+
const pluginService = new chunkQCJHCSOK_cjs.PluginService(db);
|
|
21141
21249
|
await pluginService.uninstallPlugin(pluginId);
|
|
21142
21250
|
return c.json({ success: true });
|
|
21143
21251
|
} catch (error) {
|
|
@@ -21155,7 +21263,7 @@ adminPluginRoutes.post("/:id/settings", async (c) => {
|
|
|
21155
21263
|
return c.json({ error: "Access denied" }, 403);
|
|
21156
21264
|
}
|
|
21157
21265
|
const settings = await c.req.json();
|
|
21158
|
-
const pluginService = new
|
|
21266
|
+
const pluginService = new chunkQCJHCSOK_cjs.PluginService(db);
|
|
21159
21267
|
const existingPlugin = await pluginService.getPlugin(pluginId);
|
|
21160
21268
|
const existingSettings = existingPlugin?.settings ?? {};
|
|
21161
21269
|
await pluginService.updatePluginSettings(pluginId, { ...existingSettings, ...settings });
|
|
@@ -21190,7 +21298,7 @@ function formatLastUpdated(timestamp) {
|
|
|
21190
21298
|
}
|
|
21191
21299
|
|
|
21192
21300
|
// src/templates/pages/admin-logs-list.template.ts
|
|
21193
|
-
|
|
21301
|
+
chunkUYJQDDEE_cjs.init_admin_layout_catalyst_template();
|
|
21194
21302
|
function renderLogsListPage(data) {
|
|
21195
21303
|
const { logs, pagination, filters, user } = data;
|
|
21196
21304
|
const content = `
|
|
@@ -21501,7 +21609,7 @@ function renderLogsListPage(data) {
|
|
|
21501
21609
|
user,
|
|
21502
21610
|
content
|
|
21503
21611
|
};
|
|
21504
|
-
return
|
|
21612
|
+
return chunkUYJQDDEE_cjs.renderAdminLayoutCatalyst(layoutData);
|
|
21505
21613
|
}
|
|
21506
21614
|
function renderLogDetailsPage(data) {
|
|
21507
21615
|
const { log, user } = data;
|
|
@@ -21713,7 +21821,7 @@ function renderLogDetailsPage(data) {
|
|
|
21713
21821
|
</div>
|
|
21714
21822
|
</div>
|
|
21715
21823
|
`;
|
|
21716
|
-
return
|
|
21824
|
+
return chunkE66UVONV_cjs.adminLayoutV2({
|
|
21717
21825
|
title: `Log Details - ${log.id}`,
|
|
21718
21826
|
user,
|
|
21719
21827
|
content
|
|
@@ -21956,7 +22064,7 @@ function renderLogConfigPage(data) {
|
|
|
21956
22064
|
|
|
21957
22065
|
<script src="https://unpkg.com/htmx.org@1.9.6"></script>
|
|
21958
22066
|
`;
|
|
21959
|
-
return
|
|
22067
|
+
return chunkE66UVONV_cjs.adminLayoutV2({
|
|
21960
22068
|
title: "Log Configuration",
|
|
21961
22069
|
user,
|
|
21962
22070
|
content
|
|
@@ -21965,7 +22073,7 @@ function renderLogConfigPage(data) {
|
|
|
21965
22073
|
|
|
21966
22074
|
// src/routes/admin-logs.ts
|
|
21967
22075
|
var adminLogsRoutes = new hono.Hono();
|
|
21968
|
-
adminLogsRoutes.use("*",
|
|
22076
|
+
adminLogsRoutes.use("*", chunk37V3RET3_cjs.requireAuth());
|
|
21969
22077
|
adminLogsRoutes.get("/", async (c) => {
|
|
21970
22078
|
try {
|
|
21971
22079
|
const user = c.get("user");
|
|
@@ -22337,7 +22445,7 @@ adminCheckboxRoutes.get("/", (c) => {
|
|
|
22337
22445
|
role: user.role
|
|
22338
22446
|
} : void 0
|
|
22339
22447
|
};
|
|
22340
|
-
return c.html(
|
|
22448
|
+
return c.html(chunkE66UVONV_cjs.renderCheckboxPage(pageData));
|
|
22341
22449
|
});
|
|
22342
22450
|
|
|
22343
22451
|
// src/templates/pages/admin-dashboard.template.ts
|
|
@@ -22409,7 +22517,7 @@ function renderDashboardPage(data) {
|
|
|
22409
22517
|
version: data.version,
|
|
22410
22518
|
content: pageContent
|
|
22411
22519
|
};
|
|
22412
|
-
return
|
|
22520
|
+
return chunkE66UVONV_cjs.renderAdminLayout(layoutData);
|
|
22413
22521
|
}
|
|
22414
22522
|
function renderStatsCards(stats) {
|
|
22415
22523
|
const cards = [
|
|
@@ -22957,9 +23065,9 @@ function renderStorageUsage(databaseSizeBytes, mediaSizeBytes) {
|
|
|
22957
23065
|
}
|
|
22958
23066
|
|
|
22959
23067
|
// src/routes/admin-dashboard.ts
|
|
22960
|
-
var VERSION =
|
|
23068
|
+
var VERSION = chunkKKNEYIZJ_cjs.getCoreVersion();
|
|
22961
23069
|
var router = new hono.Hono();
|
|
22962
|
-
router.use("*",
|
|
23070
|
+
router.use("*", chunk37V3RET3_cjs.requireAuth());
|
|
22963
23071
|
router.get("/", async (c) => {
|
|
22964
23072
|
const user = c.get("user");
|
|
22965
23073
|
try {
|
|
@@ -23149,7 +23257,7 @@ router.get("/system-status", async (c) => {
|
|
|
23149
23257
|
});
|
|
23150
23258
|
|
|
23151
23259
|
// src/templates/pages/admin-collections-list.template.ts
|
|
23152
|
-
|
|
23260
|
+
chunkUYJQDDEE_cjs.init_admin_layout_catalyst_template();
|
|
23153
23261
|
|
|
23154
23262
|
// src/templates/components/table.template.ts
|
|
23155
23263
|
function renderTable2(data) {
|
|
@@ -23631,11 +23739,11 @@ function renderCollectionsListPage(data) {
|
|
|
23631
23739
|
version: data.version,
|
|
23632
23740
|
content: pageContent
|
|
23633
23741
|
};
|
|
23634
|
-
return
|
|
23742
|
+
return chunkUYJQDDEE_cjs.renderAdminLayoutCatalyst(layoutData);
|
|
23635
23743
|
}
|
|
23636
23744
|
|
|
23637
23745
|
// src/templates/pages/admin-collections-form.template.ts
|
|
23638
|
-
|
|
23746
|
+
chunkUYJQDDEE_cjs.init_admin_layout_catalyst_template();
|
|
23639
23747
|
function getFieldTypeBadge(fieldType) {
|
|
23640
23748
|
const typeLabels = {
|
|
23641
23749
|
"text": "Text",
|
|
@@ -23808,8 +23916,8 @@ function renderCollectionFormPage(data) {
|
|
|
23808
23916
|
<!-- Form Content -->
|
|
23809
23917
|
<div class="px-6 py-6">
|
|
23810
23918
|
<div id="form-messages"></div>
|
|
23811
|
-
${data.error ?
|
|
23812
|
-
${data.success ?
|
|
23919
|
+
${data.error ? chunkJMJM7DMM_cjs.renderAlert({ type: "error", message: data.error, dismissible: true }) : ""}
|
|
23920
|
+
${data.success ? chunkJMJM7DMM_cjs.renderAlert({ type: "success", message: data.success, dismissible: true }) : ""}
|
|
23813
23921
|
|
|
23814
23922
|
<!-- Form Styling -->
|
|
23815
23923
|
<style>
|
|
@@ -23920,7 +24028,7 @@ function renderCollectionFormPage(data) {
|
|
|
23920
24028
|
}
|
|
23921
24029
|
</style>
|
|
23922
24030
|
|
|
23923
|
-
${
|
|
24031
|
+
${chunkE66UVONV_cjs.renderForm(formData)}
|
|
23924
24032
|
|
|
23925
24033
|
${isEdit && data.managed ? `
|
|
23926
24034
|
<!-- Read-Only Fields Display for Managed Collections -->
|
|
@@ -24918,13 +25026,13 @@ function renderCollectionFormPage(data) {
|
|
|
24918
25026
|
version: data.version,
|
|
24919
25027
|
content: pageContent
|
|
24920
25028
|
};
|
|
24921
|
-
return
|
|
25029
|
+
return chunkUYJQDDEE_cjs.renderAdminLayoutCatalyst(layoutData);
|
|
24922
25030
|
}
|
|
24923
25031
|
|
|
24924
25032
|
// src/routes/admin-collections.ts
|
|
24925
|
-
|
|
25033
|
+
chunkUYJQDDEE_cjs.init_admin_layout_catalyst_template();
|
|
24926
25034
|
var adminCollectionsRoutes = new hono.Hono();
|
|
24927
|
-
adminCollectionsRoutes.use("*",
|
|
25035
|
+
adminCollectionsRoutes.use("*", chunk37V3RET3_cjs.requireAuth());
|
|
24928
25036
|
adminCollectionsRoutes.get("/", async (c) => {
|
|
24929
25037
|
try {
|
|
24930
25038
|
const user = c.get("user");
|
|
@@ -24941,7 +25049,7 @@ adminCollectionsRoutes.get("/", async (c) => {
|
|
|
24941
25049
|
results = queryResults.results ?? [];
|
|
24942
25050
|
} catch (e) {
|
|
24943
25051
|
}
|
|
24944
|
-
const codeCollections =
|
|
25052
|
+
const codeCollections = chunkQCJHCSOK_cjs.getCollectionRegistry().list();
|
|
24945
25053
|
const codeCollectionsMap = new Map(
|
|
24946
25054
|
codeCollections.map((cfg) => {
|
|
24947
25055
|
const fieldCount = cfg.schema?.properties ? Object.keys(cfg.schema.properties).length : 0;
|
|
@@ -24955,7 +25063,7 @@ adminCollectionsRoutes.get("/", async (c) => {
|
|
|
24955
25063
|
field_count: fieldCount,
|
|
24956
25064
|
managed: cfg.managed !== false,
|
|
24957
25065
|
source_type: "code",
|
|
24958
|
-
internal:
|
|
25066
|
+
internal: chunkQCJHCSOK_cjs.isCodeCollectionInternal(cfg),
|
|
24959
25067
|
versioning: cfg.versioning === true
|
|
24960
25068
|
}];
|
|
24961
25069
|
})
|
|
@@ -24994,7 +25102,7 @@ adminCollectionsRoutes.get("/", async (c) => {
|
|
|
24994
25102
|
field_count: fieldCount,
|
|
24995
25103
|
managed: false,
|
|
24996
25104
|
source_type: row.source === "code" || row.source === "system" || row.source === "plugin" ? "code" : "user",
|
|
24997
|
-
internal:
|
|
25105
|
+
internal: chunkQCJHCSOK_cjs.isDbDocTypeInternal(row.source),
|
|
24998
25106
|
versioning: dbVersioning
|
|
24999
25107
|
};
|
|
25000
25108
|
});
|
|
@@ -25151,11 +25259,11 @@ export const myPlugin = definePlugin({
|
|
|
25151
25259
|
`;
|
|
25152
25260
|
const u = user;
|
|
25153
25261
|
return c.html(
|
|
25154
|
-
|
|
25262
|
+
chunkUYJQDDEE_cjs.renderAdminLayoutCatalyst({
|
|
25155
25263
|
title: "Add a Collection",
|
|
25156
25264
|
pageTitle: "Add a Collection",
|
|
25157
25265
|
currentPath: "/admin/collections",
|
|
25158
|
-
version:
|
|
25266
|
+
version: chunkKKNEYIZJ_cjs.getCoreVersion(),
|
|
25159
25267
|
user: u ? { name: u.email ?? "Admin", email: u.email ?? "", role: u.role ?? "admin" } : void 0,
|
|
25160
25268
|
content
|
|
25161
25269
|
})
|
|
@@ -25172,7 +25280,7 @@ adminCollectionsRoutes.get("/:id", async (c) => {
|
|
|
25172
25280
|
collection = await stmt.bind(id).first();
|
|
25173
25281
|
} catch {
|
|
25174
25282
|
}
|
|
25175
|
-
const registryRecord =
|
|
25283
|
+
const registryRecord = chunkQCJHCSOK_cjs.getCollectionRegistry().getById(id) ?? chunkQCJHCSOK_cjs.getCollectionRegistry().getByName(id);
|
|
25176
25284
|
if (!collection && !registryRecord) {
|
|
25177
25285
|
const formData2 = {
|
|
25178
25286
|
isEdit: true,
|
|
@@ -25219,9 +25327,9 @@ adminCollectionsRoutes.get("/:id", async (c) => {
|
|
|
25219
25327
|
isCodeDriven = true;
|
|
25220
25328
|
}
|
|
25221
25329
|
const [tinymceActive, quillActive, mdxeditorActive] = await Promise.all([
|
|
25222
|
-
|
|
25223
|
-
|
|
25224
|
-
|
|
25330
|
+
chunk37V3RET3_cjs.isPluginActive(db, "tinymce-plugin"),
|
|
25331
|
+
chunk37V3RET3_cjs.isPluginActive(db, "quill-editor"),
|
|
25332
|
+
chunk37V3RET3_cjs.isPluginActive(db, "easy-mdx")
|
|
25225
25333
|
]);
|
|
25226
25334
|
const displayName = collection?.display_name ?? registryRecord?.displayName ?? id;
|
|
25227
25335
|
const formData = {
|
|
@@ -25241,9 +25349,9 @@ adminCollectionsRoutes.get("/:id", async (c) => {
|
|
|
25241
25349
|
console.error("Error fetching collection:", error);
|
|
25242
25350
|
const user = c.get("user");
|
|
25243
25351
|
const [tinymceActive, quillActive, mdxeditorActive] = await Promise.all([
|
|
25244
|
-
|
|
25245
|
-
|
|
25246
|
-
|
|
25352
|
+
chunk37V3RET3_cjs.isPluginActive(db, "tinymce-plugin"),
|
|
25353
|
+
chunk37V3RET3_cjs.isPluginActive(db, "quill-editor"),
|
|
25354
|
+
chunk37V3RET3_cjs.isPluginActive(db, "easy-mdx")
|
|
25247
25355
|
]);
|
|
25248
25356
|
const formData = {
|
|
25249
25357
|
isEdit: true,
|
|
@@ -25257,7 +25365,7 @@ adminCollectionsRoutes.get("/:id", async (c) => {
|
|
|
25257
25365
|
});
|
|
25258
25366
|
|
|
25259
25367
|
// src/templates/pages/admin-settings.template.ts
|
|
25260
|
-
|
|
25368
|
+
chunkUYJQDDEE_cjs.init_admin_layout_catalyst_template();
|
|
25261
25369
|
function renderSettingsPage(data) {
|
|
25262
25370
|
const activeTab = data.activeTab || "general";
|
|
25263
25371
|
const pageContent = `
|
|
@@ -25647,7 +25755,7 @@ function renderSettingsPage(data) {
|
|
|
25647
25755
|
version: data.version,
|
|
25648
25756
|
content: pageContent
|
|
25649
25757
|
};
|
|
25650
|
-
return
|
|
25758
|
+
return chunkUYJQDDEE_cjs.renderAdminLayoutCatalyst(layoutData);
|
|
25651
25759
|
}
|
|
25652
25760
|
function renderTabButton(tabId, label, iconPath, activeTab) {
|
|
25653
25761
|
const isActive = activeTab === tabId;
|
|
@@ -26192,7 +26300,7 @@ function renderDatabaseToolsSettings(settings) {
|
|
|
26192
26300
|
|
|
26193
26301
|
// src/routes/admin-settings.ts
|
|
26194
26302
|
var adminSettingsRoutes = new hono.Hono();
|
|
26195
|
-
adminSettingsRoutes.use("*",
|
|
26303
|
+
adminSettingsRoutes.use("*", chunk37V3RET3_cjs.requireAuth());
|
|
26196
26304
|
function getMockSettings(user) {
|
|
26197
26305
|
return {
|
|
26198
26306
|
general: {
|
|
@@ -26295,7 +26403,7 @@ adminSettingsRoutes.get("/database-tools", (c) => {
|
|
|
26295
26403
|
adminSettingsRoutes.get("/api/migrations/status", async (c) => {
|
|
26296
26404
|
try {
|
|
26297
26405
|
const db = c.env.DB;
|
|
26298
|
-
const migrationService = new
|
|
26406
|
+
const migrationService = new chunkA2SN3RVL_cjs.MigrationService(db);
|
|
26299
26407
|
const status = await migrationService.getMigrationStatus();
|
|
26300
26408
|
return c.json({
|
|
26301
26409
|
success: true,
|
|
@@ -26335,7 +26443,7 @@ adminSettingsRoutes.post("/api/migrations/run", async (c) => {
|
|
|
26335
26443
|
adminSettingsRoutes.get("/api/migrations/validate", async (c) => {
|
|
26336
26444
|
try {
|
|
26337
26445
|
const db = c.env.DB;
|
|
26338
|
-
const migrationService = new
|
|
26446
|
+
const migrationService = new chunkA2SN3RVL_cjs.MigrationService(db);
|
|
26339
26447
|
const validation = await migrationService.validateSchema();
|
|
26340
26448
|
return c.json({
|
|
26341
26449
|
success: true,
|
|
@@ -26593,7 +26701,7 @@ adminSettingsRoutes.post("/", async (c) => {
|
|
|
26593
26701
|
});
|
|
26594
26702
|
|
|
26595
26703
|
// src/templates/pages/admin-api-reference.template.ts
|
|
26596
|
-
|
|
26704
|
+
chunkUYJQDDEE_cjs.init_admin_layout_catalyst_template();
|
|
26597
26705
|
function renderAuthBadge(auth) {
|
|
26598
26706
|
if (auth === true) {
|
|
26599
26707
|
return `
|
|
@@ -26924,20 +27032,20 @@ function renderAPIReferencePage(data) {
|
|
|
26924
27032
|
version: data.version,
|
|
26925
27033
|
content: pageContent
|
|
26926
27034
|
};
|
|
26927
|
-
return
|
|
27035
|
+
return chunkUYJQDDEE_cjs.renderAdminLayoutCatalyst(layoutData);
|
|
26928
27036
|
}
|
|
26929
27037
|
|
|
26930
27038
|
// src/routes/admin-api-reference.ts
|
|
26931
|
-
var VERSION2 =
|
|
27039
|
+
var VERSION2 = chunkKKNEYIZJ_cjs.getCoreVersion();
|
|
26932
27040
|
var router2 = new hono.Hono();
|
|
26933
|
-
router2.use("*",
|
|
27041
|
+
router2.use("*", chunk37V3RET3_cjs.requireAuth());
|
|
26934
27042
|
router2.get("/", async (c) => {
|
|
26935
27043
|
const user = c.get("user");
|
|
26936
27044
|
try {
|
|
26937
27045
|
const app2 = chunk36Z3AKX3_cjs.getAppInstance();
|
|
26938
27046
|
const baseEndpoints = chunk36Z3AKX3_cjs.buildRouteList(app2);
|
|
26939
27047
|
const collectionRoutes = [];
|
|
26940
|
-
const collections =
|
|
27048
|
+
const collections = chunkQCJHCSOK_cjs.getCollectionRegistry().listActive().filter((r) => !r.internal);
|
|
26941
27049
|
const methodOrder = { GET: 0, POST: 1, PUT: 2, PATCH: 3, DELETE: 4 };
|
|
26942
27050
|
for (const col of collections) {
|
|
26943
27051
|
const displayName = col.displayName || col.name;
|
|
@@ -27034,8 +27142,10 @@ exports.createUserProfilesPlugin = createUserProfilesPlugin;
|
|
|
27034
27142
|
exports.defineUserProfile = defineUserProfile;
|
|
27035
27143
|
exports.denyIfNotAllowed = denyIfNotAllowed;
|
|
27036
27144
|
exports.dispatchHookEvent = dispatchHookEvent;
|
|
27145
|
+
exports.effectiveTenantForType = effectiveTenantForType;
|
|
27037
27146
|
exports.getConfirmationDialogScript = getConfirmationDialogScript2;
|
|
27038
27147
|
exports.getCustomData = getCustomData;
|
|
27148
|
+
exports.getDocumentRequestContext = getDocumentRequestContext;
|
|
27039
27149
|
exports.getEmailService = getEmailService;
|
|
27040
27150
|
exports.getUserProfileConfig = getUserProfileConfig;
|
|
27041
27151
|
exports.getVariablesCached = getVariablesCached;
|
|
@@ -27043,6 +27153,7 @@ exports.hasEmailService = hasEmailService;
|
|
|
27043
27153
|
exports.invalidateVariablesCache = invalidateVariablesCache;
|
|
27044
27154
|
exports.isValidMemberRole = isValidMemberRole;
|
|
27045
27155
|
exports.lexicalEditorPlugin = lexicalEditorPlugin;
|
|
27156
|
+
exports.reconcileMenuFromPlugins = reconcileMenuFromPlugins;
|
|
27046
27157
|
exports.renderConfirmationDialog = renderConfirmationDialog2;
|
|
27047
27158
|
exports.renderTable = renderTable2;
|
|
27048
27159
|
exports.resolveDocScope = resolveDocScope;
|
|
@@ -27052,7 +27163,8 @@ exports.router2 = router2;
|
|
|
27052
27163
|
exports.setEmailService = setEmailService;
|
|
27053
27164
|
exports.setVariablesCache = setVariablesCache;
|
|
27054
27165
|
exports.test_cleanup_default = test_cleanup_default;
|
|
27166
|
+
exports.updateDocumentSchema = updateDocumentSchema;
|
|
27055
27167
|
exports.userProfilesPlugin = userProfilesPlugin;
|
|
27056
27168
|
exports.userRoutes = userRoutes;
|
|
27057
|
-
//# sourceMappingURL=chunk-
|
|
27058
|
-
//# sourceMappingURL=chunk-
|
|
27169
|
+
//# sourceMappingURL=chunk-I767LVN7.cjs.map
|
|
27170
|
+
//# sourceMappingURL=chunk-I767LVN7.cjs.map
|