@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.
Files changed (108) hide show
  1. package/dist/adapters.cjs +512 -0
  2. package/dist/adapters.cjs.map +1 -0
  3. package/dist/adapters.d.cts +342 -0
  4. package/dist/adapters.d.ts +342 -0
  5. package/dist/adapters.js +501 -0
  6. package/dist/adapters.js.map +1 -0
  7. package/dist/admin-documents-form.template-55V2ZGWT.js +6 -0
  8. package/dist/{admin-documents-form.template-DDSH6ROU.js.map → admin-documents-form.template-55V2ZGWT.js.map} +1 -1
  9. package/dist/admin-documents-form.template-YNAVMJCV.cjs +19 -0
  10. package/dist/{admin-layout-catalyst.template-YQ4EMF2J.js.map → admin-documents-form.template-YNAVMJCV.cjs.map} +1 -1
  11. package/dist/admin-layout-catalyst.template-3XZXDGF7.cjs +21 -0
  12. package/dist/{admin-layout-catalyst.template-KDHKVLXR.cjs.map → admin-layout-catalyst.template-3XZXDGF7.cjs.map} +1 -1
  13. package/dist/admin-layout-catalyst.template-6UQGLCKI.js +7 -0
  14. package/dist/{admin-documents-form.template-LSZKGA5J.cjs.map → admin-layout-catalyst.template-6UQGLCKI.js.map} +1 -1
  15. package/dist/{chunk-FTXGZ3BF.cjs → chunk-37V3RET3.cjs} +21 -37
  16. package/dist/chunk-37V3RET3.cjs.map +1 -0
  17. package/dist/{chunk-3CT3SUR4.cjs → chunk-A2SN3RVL.cjs} +3 -3
  18. package/dist/chunk-A2SN3RVL.cjs.map +1 -0
  19. package/dist/{chunk-CRGUD4KC.cjs → chunk-BBEKHLTW.cjs} +9 -9
  20. package/dist/{chunk-CRGUD4KC.cjs.map → chunk-BBEKHLTW.cjs.map} +1 -1
  21. package/dist/{chunk-RMRJGMDE.js → chunk-BHND5PEV.js} +3 -3
  22. package/dist/{chunk-RMRJGMDE.js.map → chunk-BHND5PEV.js.map} +1 -1
  23. package/dist/{chunk-OBA2RYZN.js → chunk-BJROXF4N.js} +3 -3
  24. package/dist/{chunk-OBA2RYZN.js.map → chunk-BJROXF4N.js.map} +1 -1
  25. package/dist/{chunk-EUJAEB6W.cjs → chunk-BP52BFIV.cjs} +53 -4
  26. package/dist/chunk-BP52BFIV.cjs.map +1 -0
  27. package/dist/{chunk-PXNTCCPE.cjs → chunk-E66UVONV.cjs} +8 -8
  28. package/dist/{chunk-PXNTCCPE.cjs.map → chunk-E66UVONV.cjs.map} +1 -1
  29. package/dist/{chunk-CHWT5KBK.js → chunk-FHPEM77Y.js} +9 -25
  30. package/dist/chunk-FHPEM77Y.js.map +1 -0
  31. package/dist/{chunk-JFLZHOQP.cjs → chunk-I767LVN7.cjs} +531 -419
  32. package/dist/chunk-I767LVN7.cjs.map +1 -0
  33. package/dist/{chunk-N32OWET6.cjs → chunk-JMJM7DMM.cjs} +5 -5
  34. package/dist/{chunk-N32OWET6.cjs.map → chunk-JMJM7DMM.cjs.map} +1 -1
  35. package/dist/{chunk-QWSR4THH.cjs → chunk-KKNEYIZJ.cjs} +12 -5
  36. package/dist/chunk-KKNEYIZJ.cjs.map +1 -0
  37. package/dist/{chunk-73O4GPJ6.js → chunk-LNI3FYSI.js} +12 -5
  38. package/dist/chunk-LNI3FYSI.js.map +1 -0
  39. package/dist/{chunk-PYZYU7EK.cjs → chunk-QCJHCSOK.cjs} +36 -2
  40. package/dist/chunk-QCJHCSOK.cjs.map +1 -0
  41. package/dist/{chunk-MGHHPNJN.cjs → chunk-QJUJNTIU.cjs} +11 -59
  42. package/dist/chunk-QJUJNTIU.cjs.map +1 -0
  43. package/dist/{chunk-DOMXI5PM.js → chunk-RJ2O5IIE.js} +36 -2
  44. package/dist/chunk-RJ2O5IIE.js.map +1 -0
  45. package/dist/{chunk-5V62WT6M.js → chunk-THFZSDIU.js} +4 -2
  46. package/dist/chunk-THFZSDIU.js.map +1 -0
  47. package/dist/{chunk-2FCKKOA5.js → chunk-UIHIXTIS.js} +3 -3
  48. package/dist/chunk-UIHIXTIS.js.map +1 -0
  49. package/dist/{chunk-JQISFW6U.js → chunk-URIBTX27.js} +3 -3
  50. package/dist/{chunk-JQISFW6U.js.map → chunk-URIBTX27.js.map} +1 -1
  51. package/dist/{chunk-K623Q6WD.cjs → chunk-UYJQDDEE.cjs} +4 -2
  52. package/dist/chunk-UYJQDDEE.cjs.map +1 -0
  53. package/dist/{chunk-6KNTZ67K.js → chunk-VC5XVPLM.js} +234 -126
  54. package/dist/chunk-VC5XVPLM.js.map +1 -0
  55. package/dist/{chunk-I2DM27HP.js → chunk-VGEZNFWH.js} +49 -4
  56. package/dist/chunk-VGEZNFWH.js.map +1 -0
  57. package/dist/{chunk-GB2Q2DNK.js → chunk-VYQVDL2M.js} +5 -49
  58. package/dist/chunk-VYQVDL2M.js.map +1 -0
  59. package/dist/{define-plugin-DsKiGu1q.d.cts → define-plugin-DMcvEy_C.d.cts} +33 -0
  60. package/dist/{define-plugin-BYIey6sp.d.ts → define-plugin-D_6D9vVZ.d.ts} +33 -0
  61. package/dist/index.cjs +2587 -326
  62. package/dist/index.cjs.map +1 -1
  63. package/dist/index.d.cts +30 -3
  64. package/dist/index.d.ts +30 -3
  65. package/dist/index.js +2281 -22
  66. package/dist/index.js.map +1 -1
  67. package/dist/middleware.cjs +34 -34
  68. package/dist/middleware.js +5 -5
  69. package/dist/migrations-FGXZPKDC.cjs +13 -0
  70. package/dist/{migrations-UIMA6ZL6.cjs.map → migrations-FGXZPKDC.cjs.map} +1 -1
  71. package/dist/migrations-Z6D27NAW.js +4 -0
  72. package/dist/{migrations-HLK2QF4T.js.map → migrations-Z6D27NAW.js.map} +1 -1
  73. package/dist/plugins.cjs +40 -40
  74. package/dist/plugins.d.cts +1 -1
  75. package/dist/plugins.d.ts +1 -1
  76. package/dist/plugins.js +3 -3
  77. package/dist/routes.cjs +29 -29
  78. package/dist/routes.js +9 -9
  79. package/dist/services.cjs +18 -18
  80. package/dist/services.js +2 -2
  81. package/dist/templates.cjs +17 -17
  82. package/dist/templates.js +3 -3
  83. package/dist/utils.cjs +3 -3
  84. package/dist/utils.js +1 -1
  85. package/migrations/0001_core.sql +7 -1
  86. package/package.json +10 -3
  87. package/dist/admin-documents-form.template-DDSH6ROU.js +0 -6
  88. package/dist/admin-documents-form.template-LSZKGA5J.cjs +0 -19
  89. package/dist/admin-layout-catalyst.template-KDHKVLXR.cjs +0 -21
  90. package/dist/admin-layout-catalyst.template-YQ4EMF2J.js +0 -7
  91. package/dist/chunk-2FCKKOA5.js.map +0 -1
  92. package/dist/chunk-3CT3SUR4.cjs.map +0 -1
  93. package/dist/chunk-5V62WT6M.js.map +0 -1
  94. package/dist/chunk-6KNTZ67K.js.map +0 -1
  95. package/dist/chunk-73O4GPJ6.js.map +0 -1
  96. package/dist/chunk-CHWT5KBK.js.map +0 -1
  97. package/dist/chunk-DOMXI5PM.js.map +0 -1
  98. package/dist/chunk-EUJAEB6W.cjs.map +0 -1
  99. package/dist/chunk-FTXGZ3BF.cjs.map +0 -1
  100. package/dist/chunk-GB2Q2DNK.js.map +0 -1
  101. package/dist/chunk-I2DM27HP.js.map +0 -1
  102. package/dist/chunk-JFLZHOQP.cjs.map +0 -1
  103. package/dist/chunk-K623Q6WD.cjs.map +0 -1
  104. package/dist/chunk-MGHHPNJN.cjs.map +0 -1
  105. package/dist/chunk-PYZYU7EK.cjs.map +0 -1
  106. package/dist/chunk-QWSR4THH.cjs.map +0 -1
  107. package/dist/migrations-HLK2QF4T.js +0 -4
  108. 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 chunkN32OWET6_cjs = require('./chunk-N32OWET6.cjs');
4
+ var chunkJMJM7DMM_cjs = require('./chunk-JMJM7DMM.cjs');
5
5
  var chunk36Z3AKX3_cjs = require('./chunk-36Z3AKX3.cjs');
6
- var chunkFTXGZ3BF_cjs = require('./chunk-FTXGZ3BF.cjs');
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 chunkPYZYU7EK_cjs = require('./chunk-PYZYU7EK.cjs');
10
- var chunk3CT3SUR4_cjs = require('./chunk-3CT3SUR4.cjs');
11
- var chunkPXNTCCPE_cjs = require('./chunk-PXNTCCPE.cjs');
12
- var chunkK623Q6WD_cjs = require('./chunk-K623Q6WD.cjs');
13
- var chunkEUJAEB6W_cjs = require('./chunk-EUJAEB6W.cjs');
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 chunkQWSR4THH_cjs = require('./chunk-QWSR4THH.cjs');
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 chunkFTXGZ3BF_cjs.DocumentTypeRegistry(db).findById(row.type_id);
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 chunkFTXGZ3BF_cjs.DocumentTypeRegistry(db);
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 chunkFTXGZ3BF_cjs.DocumentTypeRegistry(db).findById(row.type_id);
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 chunkFTXGZ3BF_cjs.DocumentTypeRegistry(db).findById(row.type_id);
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 chunkFTXGZ3BF_cjs.DocumentTypeRegistry(db).findById(row.type_id);
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("*", chunkFTXGZ3BF_cjs.requireAuth());
475
- adminDocumentsRoutes.use("*", chunkFTXGZ3BF_cjs.requireRole(["admin", "editor"]));
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 chunkFTXGZ3BF_cjs.DocumentTypeRegistry(c.env.DB);
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 chunkFTXGZ3BF_cjs.DocumentTypeRegistry(db);
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 chunkFTXGZ3BF_cjs.DocumentTypeRegistry(db);
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 chunkFTXGZ3BF_cjs.DocumentTypeRegistry(db);
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 = chunkPYZYU7EK_cjs.getCollectionRegistry();
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 chunkFTXGZ3BF_cjs.DocumentTypeRegistry(db).findById(record.name);
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 chunkFTXGZ3BF_cjs.DocumentTypeRegistry(db).findById(collectionIdOrName);
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", chunkFTXGZ3BF_cjs.optionalAuth(), async (c) => {
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 = chunkPYZYU7EK_cjs.getCollectionRegistry().getByName(docRow.type_id);
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("/", chunkFTXGZ3BF_cjs.requireAuth(), chunkFTXGZ3BF_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
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", chunkFTXGZ3BF_cjs.requireAuth(), chunkFTXGZ3BF_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
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 chunkFTXGZ3BF_cjs.DocumentTypeRegistry(db).findById(docRow.type_id);
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 = chunkPYZYU7EK_cjs.getCollectionRegistry().getByName(docRow.type_id);
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", chunkFTXGZ3BF_cjs.requireAuth(), chunkFTXGZ3BF_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
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 chunkFTXGZ3BF_cjs.isPluginActive(c.env.DB, "core-cache");
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: chunkQWSR4THH_cjs.getCoreVersion(),
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 = chunkPYZYU7EK_cjs.getCollectionRegistry().listActive().filter((r) => !r.internal);
1717
- const transformedResults = records.map(chunkPYZYU7EK_cjs.collectionRecordToRow);
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", chunkFTXGZ3BF_cjs.optionalAuth(), async (c) => {
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 = chunkPYZYU7EK_cjs.getCollectionRegistry();
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", chunkFTXGZ3BF_cjs.optionalAuth(), async (c) => {
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 = chunkPYZYU7EK_cjs.getCollectionRegistry().getBySlugOrName(collection);
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: chunkPYZYU7EK_cjs.collectionRecordToRow(record) } : {},
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", chunkFTXGZ3BF_cjs.optionalAuth(), async (c) => {
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 = chunkPYZYU7EK_cjs.getCollectionRegistry().getBySlugOrName(collection);
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: chunkPYZYU7EK_cjs.collectionRecordToRow(record) } : {},
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", chunkFTXGZ3BF_cjs.optionalAuth(), async (c) => {
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 = chunkPYZYU7EK_cjs.getCollectionRegistry().getBySlugOrName(collection);
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 = chunkPYZYU7EK_cjs.getCollectionRegistry().getByName(docRow.type_id);
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", chunkFTXGZ3BF_cjs.requireAuth(), chunkFTXGZ3BF_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
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", chunkFTXGZ3BF_cjs.requireAuth(), chunkFTXGZ3BF_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
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 = chunkPYZYU7EK_cjs.getCollectionRegistry().getBySlugOrName(collection);
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 chunkFTXGZ3BF_cjs.DocumentTypeRegistry(db).findById(docRow.type_id);
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 = chunkPYZYU7EK_cjs.getCollectionRegistry().getByName(docRow.type_id);
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", chunkFTXGZ3BF_cjs.requireAuth(), chunkFTXGZ3BF_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
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 = chunkPYZYU7EK_cjs.getCollectionRegistry().getBySlugOrName(collection);
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("*", chunkFTXGZ3BF_cjs.requireAuth());
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 = chunkPYZYU7EK_cjs.getCollectionRegistry().listActive().filter((r) => !r.internal).map((r) => r.name);
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("*", chunkFTXGZ3BF_cjs.requireAuth());
3112
- adminApiRoutes.use("*", chunkFTXGZ3BF_cjs.requireRole(["admin", "editor"]));
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 = chunkPYZYU7EK_cjs.getCollectionRegistry().listActive().filter((r) => !r.internal);
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 = chunkPYZYU7EK_cjs.getCollectionRegistry().list().filter((r) => !r.internal);
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 = chunkPYZYU7EK_cjs.getCollectionRegistry();
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 = chunkPYZYU7EK_cjs.getCollectionRegistry();
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-UIMA6ZL6.cjs');
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-UIMA6ZL6.cjs');
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">${chunkPXNTCCPE_cjs.renderAlert({ type: "error", message: data.error })}</div>` : ""}
3598
- ${data.message ? `<div class="mb-6">${chunkPXNTCCPE_cjs.renderAlert({ type: "success", message: data.message })}</div>` : ""}
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">${chunkPXNTCCPE_cjs.renderAlert({ type: "error", message: data.error })}</div>` : ""}
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 = chunkEUJAEB6W_cjs.createServiceSingleton("EmailService");
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 = chunkEUJAEB6W_cjs.definePlugin({
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 = chunkEUJAEB6W_cjs.definePlugin({
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 chunkFTXGZ3BF_cjs.generateCsrfToken(secret);
7115
- const cookieMaxAge = await chunkFTXGZ3BF_cjs.getJwtExpirySecondsFromDb(c.env?.DB, c.env);
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
- chunkFTXGZ3BF_cjs.rateLimit({ max: 30, windowMs: 60 * 1e3, keyPrefix: "register" }),
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 chunkFTXGZ3BF_cjs.AuthManager.hashPassword(password);
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 chunkFTXGZ3BF_cjs.getJwtExpirySecondsFromDb(c.env.DB, c.env);
7244
- const token = await chunkFTXGZ3BF_cjs.AuthManager.generateToken(userId, normalizedEmail, "viewer", c.env.JWT_SECRET, tokenTtl);
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
- chunkFTXGZ3BF_cjs.rateLimit({ max: 30, windowMs: 60 * 1e3, keyPrefix: "login" }),
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 chunkFTXGZ3BF_cjs.getJwtExpirySecondsFromDb(c.env.DB, c.env);
7309
- const token = await chunkFTXGZ3BF_cjs.AuthManager.generateToken(
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", chunkFTXGZ3BF_cjs.requireAuth(), async (c) => {
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
- chunkFTXGZ3BF_cjs.rateLimit({ max: 60, windowMs: 60 * 1e3, keyPrefix: "refresh" }),
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 chunkFTXGZ3BF_cjs.getJwtRefreshGraceSecondsFromDb(db, c.env);
7400
- const payload = await chunkFTXGZ3BF_cjs.AuthManager.verifyToken(token, c.env.JWT_SECRET, grace);
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 chunkFTXGZ3BF_cjs.getJwtExpirySecondsFromDb(db, c.env);
7409
- const newToken = await chunkFTXGZ3BF_cjs.AuthManager.generateToken(row.id, row.email, row.role, c.env.JWT_SECRET, tokenTtl);
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
- chunkFTXGZ3BF_cjs.rateLimit({ max: 30, windowMs: 60 * 1e3, keyPrefix: "register" }),
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 chunkFTXGZ3BF_cjs.AuthManager.hashPassword(password);
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 chunkFTXGZ3BF_cjs.getJwtExpirySecondsFromDb(c.env.DB, c.env);
7517
- const token = await chunkFTXGZ3BF_cjs.AuthManager.generateToken(userId, normalizedEmail, role, c.env.JWT_SECRET, tokenTtl);
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
- chunkFTXGZ3BF_cjs.rateLimit({ max: 30, windowMs: 60 * 1e3, keyPrefix: "login" }),
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
- chunkFTXGZ3BF_cjs.rateLimit({ max: 10, windowMs: 60 * 1e3, keyPrefix: "seed-admin" }),
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 chunkFTXGZ3BF_cjs.AuthManager.hashPassword(opts.password);
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 chunkFTXGZ3BF_cjs.AuthManager.hashPassword(password);
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 chunkFTXGZ3BF_cjs.getJwtExpirySecondsFromDb(c.env.DB, c.env);
7868
- const authToken = await chunkFTXGZ3BF_cjs.AuthManager.generateToken(invitedUser.id, invitedUser.email, invitedUser.role, c.env.JWT_SECRET, tokenTtl);
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
- chunkFTXGZ3BF_cjs.rateLimit({ max: 3, windowMs: 15 * 60 * 1e3, keyPrefix: "password-reset" }),
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 chunkFTXGZ3BF_cjs.AuthManager.hashPassword(password);
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
- chunkEUJAEB6W_cjs.definePlugin({
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
- chunkEUJAEB6W_cjs.definePlugin({
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
- chunkEUJAEB6W_cjs.definePlugin({
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
- chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
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 ? chunkPXNTCCPE_cjs.renderAlert({ type: "error", message: data.error, dismissible: true }) : ""}
8900
- ${data.success ? chunkPXNTCCPE_cjs.renderAlert({ type: "success", message: data.success, dismissible: true }) : ""}
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
- ${chunkPXNTCCPE_cjs.renderConfirmationDialog({
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
- ${chunkPXNTCCPE_cjs.renderConfirmationDialog({
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
- ${chunkPXNTCCPE_cjs.renderConfirmationDialog({
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
- ${chunkPXNTCCPE_cjs.renderConfirmationDialog({
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
- ${chunkPXNTCCPE_cjs.getConfirmationDialogScript()}
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 chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
10278
+ return chunkUYJQDDEE_cjs.renderAdminLayoutCatalyst(layoutData);
10267
10279
  }
10268
10280
 
10269
10281
  // src/templates/pages/admin-content-list.template.ts
10270
- chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
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
- ${chunkPXNTCCPE_cjs.renderTable(tableData)}
10705
- ${chunkPXNTCCPE_cjs.renderPagination(paginationData)}
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
- ${chunkPXNTCCPE_cjs.renderConfirmationDialog({
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
- ${chunkPXNTCCPE_cjs.getConfirmationDialogScript()}
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 chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
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("*", chunkFTXGZ3BF_cjs.requireAuth());
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 chunkPYZYU7EK_cjs.loadCollectionConfigs();
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 chunkPYZYU7EK_cjs.loadCollectionConfigs();
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 chunkPYZYU7EK_cjs.loadCollectionConfigs();
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 chunkFTXGZ3BF_cjs.DocumentTypeRegistry(db).findById(collectionName);
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 chunkPYZYU7EK_cjs.loadCollectionConfigs();
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 chunkFTXGZ3BF_cjs.isPluginActive(db, "workflow") };
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 chunkFTXGZ3BF_cjs.isPluginActive(db, plugin);
11564
+ const enabled = await chunk37V3RET3_cjs.isPluginActive(db, plugin);
11553
11565
  flags[`${key}Enabled`] = enabled;
11554
11566
  if (enabled) {
11555
- const ps = new chunkPYZYU7EK_cjs.PluginService(db);
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 chunkPYZYU7EK_cjs.loadCollectionConfigs();
11603
+ const codeCollections = await chunkQCJHCSOK_cjs.loadCollectionConfigs();
11592
11604
  const codeCollectionMap = new Map(codeCollections.map((c2) => [c2.name, c2]));
11593
- const docTypeRegistry = new chunkFTXGZ3BF_cjs.DocumentTypeRegistry(db);
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 chunkPYZYU7EK_cjs.getVisibleCollections(db);
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 chunkFTXGZ3BF_cjs.DocumentTypeRegistry(db2).findAll()).filter((dt) => !dt.settings?.internal && !dt.isAuth).map((dt) => dt.id)
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 chunkPYZYU7EK_cjs.loadCollectionConfigs();
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 chunkFTXGZ3BF_cjs.isPluginActive(db, "workflow");
11951
- const tinymceEnabled = await chunkFTXGZ3BF_cjs.isPluginActive(db, "tinymce-plugin");
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 chunkPYZYU7EK_cjs.PluginService(db);
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 chunkFTXGZ3BF_cjs.isPluginActive(db, "quill-editor");
11978
+ const quillEnabled = await chunk37V3RET3_cjs.isPluginActive(db, "quill-editor");
11959
11979
  let quillSettings;
11960
11980
  if (quillEnabled) {
11961
- const pluginService = new chunkPYZYU7EK_cjs.PluginService(db);
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 chunkFTXGZ3BF_cjs.isPluginActive(db, "easy-mdx");
11985
+ const mdxeditorEnabled = await chunk37V3RET3_cjs.isPluginActive(db, "easy-mdx");
11966
11986
  let mdxeditorSettings;
11967
11987
  if (mdxeditorEnabled) {
11968
- const pluginService = new chunkPYZYU7EK_cjs.PluginService(db);
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 chunkFTXGZ3BF_cjs.isPluginActive(db, "lexical-editor");
11992
+ const lexicalEnabled = await chunk37V3RET3_cjs.isPluginActive(db, "lexical-editor");
11973
11993
  let lexicalSettings;
11974
11994
  if (lexicalEnabled) {
11975
- const pluginService = new chunkPYZYU7EK_cjs.PluginService(db);
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 chunkFTXGZ3BF_cjs.isPluginActive(db, "workflow");
12104
- const tinymceEnabled = await chunkFTXGZ3BF_cjs.isPluginActive(db, "tinymce-plugin");
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 chunkPYZYU7EK_cjs.PluginService(db);
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 chunkFTXGZ3BF_cjs.isPluginActive(db, "quill-editor");
12139
+ const quillEnabled = await chunk37V3RET3_cjs.isPluginActive(db, "quill-editor");
12112
12140
  let quillSettings;
12113
12141
  if (quillEnabled) {
12114
- const pluginService = new chunkPYZYU7EK_cjs.PluginService(db);
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 chunkFTXGZ3BF_cjs.isPluginActive(db, "easy-mdx");
12146
+ const mdxeditorEnabled = await chunk37V3RET3_cjs.isPluginActive(db, "easy-mdx");
12119
12147
  let mdxeditorSettings;
12120
12148
  if (mdxeditorEnabled) {
12121
- const pluginService = new chunkPYZYU7EK_cjs.PluginService(db);
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 chunkFTXGZ3BF_cjs.isPluginActive(db, "lexical-editor");
12153
+ const lexicalEnabled = await chunk37V3RET3_cjs.isPluginActive(db, "lexical-editor");
12126
12154
  let lexicalSettings;
12127
12155
  if (lexicalEnabled) {
12128
- const pluginService = new chunkPYZYU7EK_cjs.PluginService(db);
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", chunkFTXGZ3BF_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
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", chunkFTXGZ3BF_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
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 chunkFTXGZ3BF_cjs.DocumentTypeRegistry(db);
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 chunkFTXGZ3BF_cjs.DocumentTypeRegistry(c.env.DB);
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(chunkN32OWET6_cjs.renderDocumentFormPage({ docType, isEdit: false, user: userCtx(c) }));
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 chunkFTXGZ3BF_cjs.DocumentTypeRegistry(c.env.DB);
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(chunkN32OWET6_cjs.renderDocumentFormPage({ docType, isEdit: false, user: userCtx(c), message: err?.message ?? "Failed to create", messageType: "error" }));
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 chunkFTXGZ3BF_cjs.DocumentTypeRegistry(db);
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(chunkN32OWET6_cjs.renderDocumentFormPage({ docType, doc, publishedDoc, isEdit: true, message, user: userCtx(c), versioningEnabled: docType?.settings?.versioning === true }));
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-LSZKGA5J.cjs');
13077
- const registry = new chunkFTXGZ3BF_cjs.DocumentTypeRegistry(db);
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
- chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
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 ? chunkPXNTCCPE_cjs.renderAlert({ type: "error", message: data.error, dismissible: true }) : ""}
13118
- ${data.success ? chunkPXNTCCPE_cjs.renderAlert({ type: "success", message: data.success, dismissible: true }) : ""}
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 chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
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 chunkPXNTCCPE_cjs.renderAdminLayout(layoutData);
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
- chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
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 ? chunkPXNTCCPE_cjs.renderAlert({ type: "error", message: data.error, dismissible: true }) : ""}
13922
- ${data.success ? chunkPXNTCCPE_cjs.renderAlert({ type: "success", message: data.success, dismissible: true }) : ""}
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 chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
14276
+ return chunkUYJQDDEE_cjs.renderAdminLayoutCatalyst(layoutData);
14245
14277
  }
14246
14278
 
14247
14279
  // src/templates/pages/admin-user-new.template.ts
14248
- chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
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 ? chunkPXNTCCPE_cjs.renderAlert({ type: "error", message: data.error, dismissible: true }) : ""}
14288
- ${data.success ? chunkPXNTCCPE_cjs.renderAlert({ type: "success", message: data.success, dismissible: true }) : ""}
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 chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
14550
+ return chunkUYJQDDEE_cjs.renderAdminLayoutCatalyst(layoutData);
14519
14551
  }
14520
14552
 
14521
14553
  // src/templates/pages/admin-users-list.template.ts
14522
- chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
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 ? chunkPXNTCCPE_cjs.renderAlert({ type: "error", message: data.error, dismissible: true }) : ""}
14679
- ${data.success ? chunkPXNTCCPE_cjs.renderAlert({ type: "success", message: data.success, dismissible: true }) : ""}
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
- ${chunkPXNTCCPE_cjs.renderTable(tableData)}
14888
+ ${chunkE66UVONV_cjs.renderTable(tableData)}
14857
14889
 
14858
14890
  <!-- Pagination -->
14859
- ${data.pagination ? chunkPXNTCCPE_cjs.renderPagination(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 chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
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
- chunkPYZYU7EK_cjs.invalidateTenantCache();
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
- chunkPYZYU7EK_cjs.invalidateTenantCache();
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
- chunkPYZYU7EK_cjs.invalidateTenantCache();
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("*", chunkFTXGZ3BF_cjs.requireAuth());
15297
- userRoutes.use("/users/*", chunkFTXGZ3BF_cjs.requireRole(["admin"]));
15298
- userRoutes.use("/users", chunkFTXGZ3BF_cjs.requireRole(["admin"]));
15299
- userRoutes.use("/invite-user", chunkFTXGZ3BF_cjs.requireRole(["admin"]));
15300
- userRoutes.use("/resend-invitation/*", chunkFTXGZ3BF_cjs.requireRole(["admin"]));
15301
- userRoutes.use("/cancel-invitation/*", chunkFTXGZ3BF_cjs.requireRole(["admin"]));
15302
- userRoutes.use("/activity-logs", chunkFTXGZ3BF_cjs.requireRole(["admin"]));
15303
- userRoutes.use("/activity-logs/*", chunkFTXGZ3BF_cjs.requireRole(["admin"]));
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(chunkN32OWET6_cjs.renderAlert({
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(chunkN32OWET6_cjs.renderAlert({
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(chunkN32OWET6_cjs.renderAlert({
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(chunkN32OWET6_cjs.renderAlert({ type: "error", message: errorMessages, dismissible: true }), 400);
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 chunkFTXGZ3BF_cjs.logActivity(
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(chunkN32OWET6_cjs.renderAlert({
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(chunkN32OWET6_cjs.renderAlert({
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(chunkN32OWET6_cjs.renderAlert({
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(chunkN32OWET6_cjs.renderAlert({
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(chunkN32OWET6_cjs.renderAlert({
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 chunkFTXGZ3BF_cjs.logActivity(
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 = chunkN32OWET6_cjs.renderAlert({
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(chunkN32OWET6_cjs.renderAlert({
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(chunkN32OWET6_cjs.renderAlert({
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(chunkN32OWET6_cjs.renderAlert({
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(chunkN32OWET6_cjs.renderAlert({
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(chunkN32OWET6_cjs.renderAlert({
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 chunkFTXGZ3BF_cjs.AuthManager.verifyPassword(currentPassword, userData.password_hash);
15636
+ const validPassword = await chunk37V3RET3_cjs.AuthManager.verifyPassword(currentPassword, userData.password_hash);
15605
15637
  if (!validPassword) {
15606
- return c.html(chunkN32OWET6_cjs.renderAlert({
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 chunkFTXGZ3BF_cjs.AuthManager.hashPassword(newPassword);
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 chunkFTXGZ3BF_cjs.logActivity(
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(chunkN32OWET6_cjs.renderAlert({
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(chunkN32OWET6_cjs.renderAlert({
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 chunkFTXGZ3BF_cjs.logActivity(
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(chunkN32OWET6_cjs.renderAlert({
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(chunkN32OWET6_cjs.renderAlert({
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(chunkN32OWET6_cjs.renderAlert({ type: "error", message: errorMessages, dismissible: true }), 400);
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(chunkN32OWET6_cjs.renderAlert({
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(chunkN32OWET6_cjs.renderAlert({
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(chunkN32OWET6_cjs.renderAlert({
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(chunkN32OWET6_cjs.renderAlert({
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(chunkN32OWET6_cjs.renderAlert({
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 chunkFTXGZ3BF_cjs.AuthManager.hashPassword(password);
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 chunkFTXGZ3BF_cjs.logActivity(
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(chunkN32OWET6_cjs.renderAlert({
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 chunkFTXGZ3BF_cjs.logActivity(
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(chunkN32OWET6_cjs.renderAlert({
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(chunkN32OWET6_cjs.renderAlert({
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(chunkN32OWET6_cjs.renderAlert({ type: "error", message: errorMessages, dismissible: true }), 400);
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(chunkN32OWET6_cjs.renderAlert({
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(chunkN32OWET6_cjs.renderAlert({
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(chunkN32OWET6_cjs.renderAlert({
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(chunkN32OWET6_cjs.renderAlert({
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(chunkN32OWET6_cjs.renderAlert({
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 chunkFTXGZ3BF_cjs.AuthManager.hashPassword(newPassword);
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 chunkFTXGZ3BF_cjs.logActivity(
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(chunkN32OWET6_cjs.renderAlert({
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(chunkN32OWET6_cjs.renderAlert({
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 chunkFTXGZ3BF_cjs.logActivity(
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 chunkFTXGZ3BF_cjs.logActivity(
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 chunkFTXGZ3BF_cjs.logActivity(
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 chunkFTXGZ3BF_cjs.logActivity(
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 chunkFTXGZ3BF_cjs.logActivity(
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 chunkFTXGZ3BF_cjs.logActivity(
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
- chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
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 chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
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("*", chunkFTXGZ3BF_cjs.requireAuth());
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 chunkPYZYU7EK_cjs.PluginService(db);
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", chunkFTXGZ3BF_cjs.requireRole("admin"), async (c) => {
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
- chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
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 chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
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, "&amp;").replace(/"/g, "&quot;").replace(/'/g, "&#39;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
19347
19379
  }
19348
19380
  function renderPluginSettingsPage(data) {
19349
- const { plugin, activity = [], user } = data;
19350
- const hasUserSettings = plugin.id in pluginSettingsComponents || Object.keys(plugin.settings || {}).some((k) => !k.startsWith("_"));
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 chunkPXNTCCPE_cjs.renderAdminLayout(layoutData);
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
- <script>
20773
- (function () {
20774
- const origSave = window.saveSettings;
20775
- window.saveSettings = async function () {
20776
- const settings = {
20777
- providers: {
20778
- github: {
20779
- clientId: document.getElementById('oauth_github_clientId').value,
20780
- clientSecret: document.getElementById('oauth_github_clientSecret').value,
20781
- enabled: document.getElementById('oauth_github_enabled').checked,
20782
- },
20783
- google: {
20784
- clientId: document.getElementById('oauth_google_clientId').value,
20785
- clientSecret: document.getElementById('oauth_google_clientSecret').value,
20786
- enabled: document.getElementById('oauth_google_enabled').checked,
20787
- },
20788
- }
20789
- };
20790
-
20791
- const saveButton = document.getElementById('save-button');
20792
- saveButton.disabled = true;
20793
- saveButton.textContent = 'Saving...';
20794
-
20795
- try {
20796
- const response = await fetch('/admin/plugins/oauth-providers/settings', {
20797
- method: 'POST',
20798
- headers: { 'Content-Type': 'application/json' },
20799
- body: JSON.stringify(settings),
20800
- });
20801
- const result = await response.json();
20802
- if (result.success) {
20803
- showNotification('Settings saved successfully', 'success');
20804
- setTimeout(() => location.reload(), 1000);
20805
- } else {
20806
- throw new Error(result.error || 'Failed to save settings');
20807
- }
20808
- } catch (error) {
20809
- showNotification(error.message, 'error');
20810
- } finally {
20811
- saveButton.disabled = false;
20812
- saveButton.textContent = 'Save Settings';
20813
- }
20814
- };
20815
- })();
20816
- </script>
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("*", chunkFTXGZ3BF_cjs.requireAuth());
20823
- var AVAILABLE_PLUGINS = Object.values(chunkPYZYU7EK_cjs.PLUGIN_REGISTRY).map((p) => ({
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 chunkPYZYU7EK_cjs.PluginService(db);
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 installedPluginIds = new Set(installedPlugins.map((p) => p.id));
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 = installedPlugins.map((p) => ({
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 = installedPlugins.length + uninstalledPlugins.length;
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 chunkPYZYU7EK_cjs.PluginService(db);
21011
+ const pluginService = new chunkQCJHCSOK_cjs.PluginService(db);
20916
21012
  let plugin = await pluginService.getPlugin(pluginId);
20917
21013
  if (!plugin) {
20918
- const def = chunkEUJAEB6W_cjs.getPluginDefinition(pluginId);
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 = chunkEUJAEB6W_cjs.getPluginDefinition(pluginId);
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 chunkPYZYU7EK_cjs.PluginService(db);
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 = chunkEUJAEB6W_cjs.applySchemaDefaults(def.configSchema, stored);
21016
- const fieldsHtml = chunkEUJAEB6W_cjs.renderSchemaFields(def.configSchema, values);
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 = chunkEUJAEB6W_cjs.getPluginDefinition(pluginId);
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 = chunkEUJAEB6W_cjs.parseFormDataToSettings(def.configSchema, form);
21152
+ const parsed = chunkBP52BFIV_cjs.parseFormDataToSettings(def.configSchema, form);
21047
21153
  const db = c.env.DB;
21048
- const pluginService = new chunkPYZYU7EK_cjs.PluginService(db);
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 chunkPYZYU7EK_cjs.PluginService(db);
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 chunkPYZYU7EK_cjs.PluginService(db);
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 chunkPYZYU7EK_cjs.PluginService(db);
21107
- const registryEntry = chunkPYZYU7EK_cjs.findPluginByCodeName(body.name) || chunkPYZYU7EK_cjs.PLUGIN_REGISTRY[body.name] || chunkPYZYU7EK_cjs.PLUGIN_REGISTRY[body.id];
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 chunkPYZYU7EK_cjs.PluginService(db);
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 chunkPYZYU7EK_cjs.PluginService(db);
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
- chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
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 chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
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 chunkPXNTCCPE_cjs.adminLayoutV2({
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 chunkPXNTCCPE_cjs.adminLayoutV2({
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("*", chunkFTXGZ3BF_cjs.requireAuth());
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(chunkPXNTCCPE_cjs.renderCheckboxPage(pageData));
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 chunkPXNTCCPE_cjs.renderAdminLayout(layoutData);
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 = chunkQWSR4THH_cjs.getCoreVersion();
23068
+ var VERSION = chunkKKNEYIZJ_cjs.getCoreVersion();
22961
23069
  var router = new hono.Hono();
22962
- router.use("*", chunkFTXGZ3BF_cjs.requireAuth());
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
- chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
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 chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
23742
+ return chunkUYJQDDEE_cjs.renderAdminLayoutCatalyst(layoutData);
23635
23743
  }
23636
23744
 
23637
23745
  // src/templates/pages/admin-collections-form.template.ts
23638
- chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
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 ? chunkN32OWET6_cjs.renderAlert({ type: "error", message: data.error, dismissible: true }) : ""}
23812
- ${data.success ? chunkN32OWET6_cjs.renderAlert({ type: "success", message: data.success, dismissible: true }) : ""}
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
- ${chunkPXNTCCPE_cjs.renderForm(formData)}
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 chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
25029
+ return chunkUYJQDDEE_cjs.renderAdminLayoutCatalyst(layoutData);
24922
25030
  }
24923
25031
 
24924
25032
  // src/routes/admin-collections.ts
24925
- chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
25033
+ chunkUYJQDDEE_cjs.init_admin_layout_catalyst_template();
24926
25034
  var adminCollectionsRoutes = new hono.Hono();
24927
- adminCollectionsRoutes.use("*", chunkFTXGZ3BF_cjs.requireAuth());
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 = chunkPYZYU7EK_cjs.getCollectionRegistry().list();
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: chunkPYZYU7EK_cjs.isCodeCollectionInternal(cfg),
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: chunkPYZYU7EK_cjs.isDbDocTypeInternal(row.source),
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
- chunkK623Q6WD_cjs.renderAdminLayoutCatalyst({
25262
+ chunkUYJQDDEE_cjs.renderAdminLayoutCatalyst({
25155
25263
  title: "Add a Collection",
25156
25264
  pageTitle: "Add a Collection",
25157
25265
  currentPath: "/admin/collections",
25158
- version: chunkQWSR4THH_cjs.getCoreVersion(),
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 = chunkPYZYU7EK_cjs.getCollectionRegistry().getById(id) ?? chunkPYZYU7EK_cjs.getCollectionRegistry().getByName(id);
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
- chunkFTXGZ3BF_cjs.isPluginActive(db, "tinymce-plugin"),
25223
- chunkFTXGZ3BF_cjs.isPluginActive(db, "quill-editor"),
25224
- chunkFTXGZ3BF_cjs.isPluginActive(db, "easy-mdx")
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
- chunkFTXGZ3BF_cjs.isPluginActive(db, "tinymce-plugin"),
25245
- chunkFTXGZ3BF_cjs.isPluginActive(db, "quill-editor"),
25246
- chunkFTXGZ3BF_cjs.isPluginActive(db, "easy-mdx")
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
- chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
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 chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
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("*", chunkFTXGZ3BF_cjs.requireAuth());
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 chunk3CT3SUR4_cjs.MigrationService(db);
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 chunk3CT3SUR4_cjs.MigrationService(db);
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
- chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
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 chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
27035
+ return chunkUYJQDDEE_cjs.renderAdminLayoutCatalyst(layoutData);
26928
27036
  }
26929
27037
 
26930
27038
  // src/routes/admin-api-reference.ts
26931
- var VERSION2 = chunkQWSR4THH_cjs.getCoreVersion();
27039
+ var VERSION2 = chunkKKNEYIZJ_cjs.getCoreVersion();
26932
27040
  var router2 = new hono.Hono();
26933
- router2.use("*", chunkFTXGZ3BF_cjs.requireAuth());
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 = chunkPYZYU7EK_cjs.getCollectionRegistry().listActive().filter((r) => !r.internal);
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-JFLZHOQP.cjs.map
27058
- //# sourceMappingURL=chunk-JFLZHOQP.cjs.map
27169
+ //# sourceMappingURL=chunk-I767LVN7.cjs.map
27170
+ //# sourceMappingURL=chunk-I767LVN7.cjs.map