@sonicjs-cms/core 3.0.0-beta.2 → 3.0.0-beta.20

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 (170) hide show
  1. package/README.md +48 -49
  2. package/dist/admin-documents-form.template-DDSH6ROU.js +6 -0
  3. package/dist/{admin-documents-form.template-NLSI6Z42.js.map → admin-documents-form.template-DDSH6ROU.js.map} +1 -1
  4. package/dist/admin-documents-form.template-LSZKGA5J.cjs +19 -0
  5. package/dist/{admin-layout-catalyst.template-WHJGSWWD.js.map → admin-documents-form.template-LSZKGA5J.cjs.map} +1 -1
  6. package/dist/{filter-bar.template-DlVYMk-T.d.ts → admin-layout-catalyst.template-DrwDUfsE.d.cts} +25 -1
  7. package/dist/{filter-bar.template-DlVYMk-T.d.cts → admin-layout-catalyst.template-DrwDUfsE.d.ts} +25 -1
  8. package/dist/admin-layout-catalyst.template-KDHKVLXR.cjs +21 -0
  9. package/dist/{admin-layout-catalyst.template-ZK5HD545.cjs.map → admin-layout-catalyst.template-KDHKVLXR.cjs.map} +1 -1
  10. package/dist/admin-layout-catalyst.template-YQ4EMF2J.js +7 -0
  11. package/dist/{admin-documents-form.template-KN7JF66Q.cjs.map → admin-layout-catalyst.template-YQ4EMF2J.js.map} +1 -1
  12. package/dist/{app-Bo0X1OWX.d.ts → app-01M0dIwt.d.ts} +1 -1
  13. package/dist/{app-Do66yCcV.d.cts → app-aj39TGHB.d.cts} +1 -1
  14. package/dist/{chunk-ZEZ245PW.js → chunk-2XAQTPAE.js} +4 -236
  15. package/dist/chunk-2XAQTPAE.js.map +1 -0
  16. package/dist/{chunk-BDDABDAB.cjs → chunk-36Z3AKX3.cjs} +3 -239
  17. package/dist/chunk-36Z3AKX3.cjs.map +1 -0
  18. package/dist/{chunk-VXE42MYF.cjs → chunk-3E7IROND.cjs} +695 -428
  19. package/dist/chunk-3E7IROND.cjs.map +1 -0
  20. package/dist/{chunk-BLMTL57B.js → chunk-3TMTYJAJ.js} +26 -4
  21. package/dist/chunk-3TMTYJAJ.js.map +1 -0
  22. package/dist/{chunk-AAWNRBRB.cjs → chunk-4SHNHNRP.cjs} +95 -20
  23. package/dist/chunk-4SHNHNRP.cjs.map +1 -0
  24. package/dist/{chunk-QAYFOER6.cjs → chunk-5ARIHAGN.cjs} +285 -3
  25. package/dist/chunk-5ARIHAGN.cjs.map +1 -0
  26. package/dist/{chunk-XW56B23A.cjs → chunk-5RSB5SEK.cjs} +4 -4
  27. package/dist/{chunk-XW56B23A.cjs.map → chunk-5RSB5SEK.cjs.map} +1 -1
  28. package/dist/{chunk-VD2EA3WT.js → chunk-5UCMLBRQ.js} +328 -62
  29. package/dist/chunk-5UCMLBRQ.js.map +1 -0
  30. package/dist/{chunk-3TB6AT6X.js → chunk-5V62WT6M.js} +35 -4
  31. package/dist/chunk-5V62WT6M.js.map +1 -0
  32. package/dist/{chunk-LRZIAW7U.cjs → chunk-AQJEMVAY.cjs} +3 -3
  33. package/dist/chunk-AQJEMVAY.cjs.map +1 -0
  34. package/dist/{chunk-WULONYGB.cjs → chunk-CRGUD4KC.cjs} +9 -9
  35. package/dist/{chunk-WULONYGB.cjs.map → chunk-CRGUD4KC.cjs.map} +1 -1
  36. package/dist/{chunk-NLJVSER2.js → chunk-DSXEVMOM.js} +3 -2
  37. package/dist/chunk-DSXEVMOM.js.map +1 -0
  38. package/dist/{chunk-H2AXVCLS.cjs → chunk-DTGCXWWM.cjs} +141 -74
  39. package/dist/chunk-DTGCXWWM.cjs.map +1 -0
  40. package/dist/{chunk-NUKJ54GA.cjs → chunk-GMMCCIQO.cjs} +6 -6
  41. package/dist/{chunk-NUKJ54GA.cjs.map → chunk-GMMCCIQO.cjs.map} +1 -1
  42. package/dist/{chunk-6OUHGKFD.js → chunk-GMZ5TGYP.js} +3 -3
  43. package/dist/{chunk-6OUHGKFD.js.map → chunk-GMZ5TGYP.js.map} +1 -1
  44. package/dist/{chunk-6JQOUUOB.js → chunk-JQISFW6U.js} +3 -3
  45. package/dist/{chunk-6JQOUUOB.js.map → chunk-JQISFW6U.js.map} +1 -1
  46. package/dist/{chunk-NAVPFIG5.cjs → chunk-K623Q6WD.cjs} +35 -3
  47. package/dist/chunk-K623Q6WD.cjs.map +1 -0
  48. package/dist/{chunk-JEQ7FLOD.cjs → chunk-KIGVVO6N.cjs} +16 -10
  49. package/dist/chunk-KIGVVO6N.cjs.map +1 -0
  50. package/dist/{chunk-2CB4KY7I.cjs → chunk-LTZ5WYOK.cjs} +29 -7
  51. package/dist/chunk-LTZ5WYOK.cjs.map +1 -0
  52. package/dist/{chunk-YHSQVQXX.js → chunk-MYQ7KZUQ.js} +135 -68
  53. package/dist/chunk-MYQ7KZUQ.js.map +1 -0
  54. package/dist/{chunk-DNQCEKUK.cjs → chunk-N32OWET6.cjs} +5 -5
  55. package/dist/{chunk-DNQCEKUK.cjs.map → chunk-N32OWET6.cjs.map} +1 -1
  56. package/dist/{chunk-HDWE5FRJ.js → chunk-OBA2RYZN.js} +3 -3
  57. package/dist/{chunk-HDWE5FRJ.js.map → chunk-OBA2RYZN.js.map} +1 -1
  58. package/dist/{chunk-MVIZJOO5.cjs → chunk-PXNTCCPE.cjs} +8 -8
  59. package/dist/{chunk-MVIZJOO5.cjs.map → chunk-PXNTCCPE.cjs.map} +1 -1
  60. package/dist/{chunk-ZGGXCFR6.js → chunk-RDH6PUOP.js} +282 -4
  61. package/dist/chunk-RDH6PUOP.js.map +1 -0
  62. package/dist/{chunk-EF2NQUIQ.js → chunk-RMRJGMDE.js} +3 -3
  63. package/dist/{chunk-EF2NQUIQ.js.map → chunk-RMRJGMDE.js.map} +1 -1
  64. package/dist/{chunk-IVPRUGTY.js → chunk-SOZUG52O.js} +4 -4
  65. package/dist/{chunk-IVPRUGTY.js.map → chunk-SOZUG52O.js.map} +1 -1
  66. package/dist/{chunk-DSA4UX5B.cjs → chunk-TQG5FNNR.cjs} +3 -2
  67. package/dist/chunk-TQG5FNNR.cjs.map +1 -0
  68. package/dist/{chunk-GCDZZNIN.js → chunk-UWUP2VMT.js} +16 -10
  69. package/dist/chunk-UWUP2VMT.js.map +1 -0
  70. package/dist/{chunk-IESEVHXL.js → chunk-VVYVFCML.js} +12 -3
  71. package/dist/chunk-VVYVFCML.js.map +1 -0
  72. package/dist/{chunk-NMPEMSU4.js → chunk-W53J3BJ2.js} +3 -3
  73. package/dist/chunk-W53J3BJ2.js.map +1 -0
  74. package/dist/{chunk-RZ6H7OZK.js → chunk-WCA4VENG.js} +87 -12
  75. package/dist/chunk-WCA4VENG.js.map +1 -0
  76. package/dist/{chunk-HIKBY7MS.cjs → chunk-XWVDSM2L.cjs} +12 -3
  77. package/dist/chunk-XWVDSM2L.cjs.map +1 -0
  78. package/dist/{collection-config-JgHOpFCG.d.ts → collection-config-BTzAvKt2.d.cts} +25 -0
  79. package/dist/{collection-config-JgHOpFCG.d.cts → collection-config-BTzAvKt2.d.ts} +25 -0
  80. package/dist/config-6FB2BXMP.js +6 -0
  81. package/dist/{config-HFXANXCC.js.map → config-6FB2BXMP.js.map} +1 -1
  82. package/dist/config-OCH7S4WK.cjs +19 -0
  83. package/dist/{config-ON6FNMYX.cjs.map → config-OCH7S4WK.cjs.map} +1 -1
  84. package/dist/{define-plugin-BzNHc1ZI.d.ts → define-plugin-BYIey6sp.d.ts} +1 -1
  85. package/dist/{define-plugin-IWDKYaVm.d.cts → define-plugin-DsKiGu1q.d.cts} +1 -1
  86. package/dist/document-projection-4HG75S5S.js +4 -0
  87. package/dist/{document-projection-YYMC6I4U.js.map → document-projection-4HG75S5S.js.map} +1 -1
  88. package/dist/document-projection-JQHSTSFD.cjs +13 -0
  89. package/dist/{document-projection-TDWRJX3Z.cjs.map → document-projection-JQHSTSFD.cjs.map} +1 -1
  90. package/dist/index.cjs +928 -378
  91. package/dist/index.cjs.map +1 -1
  92. package/dist/index.d.cts +200 -12
  93. package/dist/index.d.ts +200 -12
  94. package/dist/index.js +612 -75
  95. package/dist/index.js.map +1 -1
  96. package/dist/middleware.cjs +37 -34
  97. package/dist/middleware.d.cts +2 -2
  98. package/dist/middleware.d.ts +2 -2
  99. package/dist/middleware.js +8 -5
  100. package/dist/migrations-HZJ6U6SX.js +4 -0
  101. package/dist/{migrations-WCAVBD7C.js.map → migrations-HZJ6U6SX.js.map} +1 -1
  102. package/dist/migrations-VQAFXMU7.cjs +13 -0
  103. package/dist/{migrations-NJJWQUKK.cjs.map → migrations-VQAFXMU7.cjs.map} +1 -1
  104. package/dist/{plugin-bootstrap-B8ThJU21.d.cts → plugin-bootstrap-BHWQ2df8.d.cts} +1 -1
  105. package/dist/{plugin-bootstrap-qu8hJgUt.d.ts → plugin-bootstrap-Bj4fxX1q.d.ts} +1 -1
  106. package/dist/plugins.cjs +40 -40
  107. package/dist/plugins.d.cts +2 -2
  108. package/dist/plugins.d.ts +2 -2
  109. package/dist/plugins.js +3 -3
  110. package/dist/rbac-7QZ4JZ2E.cjs +14 -0
  111. package/dist/{rbac-VONLJJKB.cjs.map → rbac-7QZ4JZ2E.cjs.map} +1 -1
  112. package/dist/rbac-Y43IEQOP.js +5 -0
  113. package/dist/{rbac-O73MFKDA.js.map → rbac-Y43IEQOP.js.map} +1 -1
  114. package/dist/routes.cjs +34 -34
  115. package/dist/routes.d.cts +2 -2
  116. package/dist/routes.d.ts +2 -2
  117. package/dist/routes.js +14 -14
  118. package/dist/services.cjs +42 -42
  119. package/dist/services.d.cts +16 -3
  120. package/dist/services.d.ts +16 -3
  121. package/dist/services.js +3 -3
  122. package/dist/{telemetry-B9vIV4wh.d.cts → telemetry-Cku1ax74.d.cts} +1 -1
  123. package/dist/{telemetry-B9vIV4wh.d.ts → telemetry-Cku1ax74.d.ts} +1 -1
  124. package/dist/templates.cjs +17 -17
  125. package/dist/templates.d.cts +2 -24
  126. package/dist/templates.d.ts +2 -24
  127. package/dist/templates.js +3 -3
  128. package/dist/{types-Dea1eNxU.d.ts → types-DT7XN5TX.d.cts} +1 -1
  129. package/dist/{types-Dea1eNxU.d.cts → types-DT7XN5TX.d.ts} +1 -1
  130. package/dist/types.d.cts +2 -2
  131. package/dist/types.d.ts +2 -2
  132. package/dist/utils.cjs +8 -8
  133. package/dist/utils.d.cts +2 -2
  134. package/dist/utils.d.ts +2 -2
  135. package/dist/utils.js +2 -2
  136. package/package.json +1 -1
  137. package/dist/admin-documents-form.template-KN7JF66Q.cjs +0 -19
  138. package/dist/admin-documents-form.template-NLSI6Z42.js +0 -6
  139. package/dist/admin-layout-catalyst.template-WHJGSWWD.js +0 -7
  140. package/dist/admin-layout-catalyst.template-ZK5HD545.cjs +0 -17
  141. package/dist/chunk-2CB4KY7I.cjs.map +0 -1
  142. package/dist/chunk-3TB6AT6X.js.map +0 -1
  143. package/dist/chunk-AAWNRBRB.cjs.map +0 -1
  144. package/dist/chunk-BDDABDAB.cjs.map +0 -1
  145. package/dist/chunk-BLMTL57B.js.map +0 -1
  146. package/dist/chunk-DSA4UX5B.cjs.map +0 -1
  147. package/dist/chunk-GCDZZNIN.js.map +0 -1
  148. package/dist/chunk-H2AXVCLS.cjs.map +0 -1
  149. package/dist/chunk-HIKBY7MS.cjs.map +0 -1
  150. package/dist/chunk-IESEVHXL.js.map +0 -1
  151. package/dist/chunk-JEQ7FLOD.cjs.map +0 -1
  152. package/dist/chunk-LRZIAW7U.cjs.map +0 -1
  153. package/dist/chunk-NAVPFIG5.cjs.map +0 -1
  154. package/dist/chunk-NLJVSER2.js.map +0 -1
  155. package/dist/chunk-NMPEMSU4.js.map +0 -1
  156. package/dist/chunk-QAYFOER6.cjs.map +0 -1
  157. package/dist/chunk-RZ6H7OZK.js.map +0 -1
  158. package/dist/chunk-VD2EA3WT.js.map +0 -1
  159. package/dist/chunk-VXE42MYF.cjs.map +0 -1
  160. package/dist/chunk-YHSQVQXX.js.map +0 -1
  161. package/dist/chunk-ZEZ245PW.js.map +0 -1
  162. package/dist/chunk-ZGGXCFR6.js.map +0 -1
  163. package/dist/config-HFXANXCC.js +0 -6
  164. package/dist/config-ON6FNMYX.cjs +0 -19
  165. package/dist/document-projection-TDWRJX3Z.cjs +0 -13
  166. package/dist/document-projection-YYMC6I4U.js +0 -4
  167. package/dist/migrations-NJJWQUKK.cjs +0 -13
  168. package/dist/migrations-WCAVBD7C.js +0 -4
  169. package/dist/rbac-O73MFKDA.js +0 -5
  170. package/dist/rbac-VONLJJKB.cjs +0 -14
@@ -1,24 +1,23 @@
1
1
  'use strict';
2
2
 
3
- var chunkHIKBY7MS_cjs = require('./chunk-HIKBY7MS.cjs');
4
- var chunkDNQCEKUK_cjs = require('./chunk-DNQCEKUK.cjs');
5
- var chunkBDDABDAB_cjs = require('./chunk-BDDABDAB.cjs');
6
- var chunkAAWNRBRB_cjs = require('./chunk-AAWNRBRB.cjs');
7
- var chunk2CB4KY7I_cjs = require('./chunk-2CB4KY7I.cjs');
8
- var chunkJEQ7FLOD_cjs = require('./chunk-JEQ7FLOD.cjs');
9
- var chunkQAYFOER6_cjs = require('./chunk-QAYFOER6.cjs');
10
- var chunkDSA4UX5B_cjs = require('./chunk-DSA4UX5B.cjs');
11
- var chunkMVIZJOO5_cjs = require('./chunk-MVIZJOO5.cjs');
12
- var chunkNAVPFIG5_cjs = require('./chunk-NAVPFIG5.cjs');
13
- var chunkXW56B23A_cjs = require('./chunk-XW56B23A.cjs');
3
+ var chunkXWVDSM2L_cjs = require('./chunk-XWVDSM2L.cjs');
4
+ var chunkN32OWET6_cjs = require('./chunk-N32OWET6.cjs');
5
+ var chunk36Z3AKX3_cjs = require('./chunk-36Z3AKX3.cjs');
6
+ var chunk4SHNHNRP_cjs = require('./chunk-4SHNHNRP.cjs');
7
+ var chunkLTZ5WYOK_cjs = require('./chunk-LTZ5WYOK.cjs');
8
+ var chunkKIGVVO6N_cjs = require('./chunk-KIGVVO6N.cjs');
9
+ var chunk5ARIHAGN_cjs = require('./chunk-5ARIHAGN.cjs');
10
+ var chunkTQG5FNNR_cjs = require('./chunk-TQG5FNNR.cjs');
11
+ var chunkPXNTCCPE_cjs = require('./chunk-PXNTCCPE.cjs');
12
+ var chunkK623Q6WD_cjs = require('./chunk-K623Q6WD.cjs');
13
+ var chunk5RSB5SEK_cjs = require('./chunk-5RSB5SEK.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 chunkLRZIAW7U_cjs = require('./chunk-LRZIAW7U.cjs');
17
+ var chunkAQJEMVAY_cjs = require('./chunk-AQJEMVAY.cjs');
18
18
  var chunkMNWKYY5E_cjs = require('./chunk-MNWKYY5E.cjs');
19
19
  var hono = require('hono');
20
20
  var zod = require('zod');
21
- var cors = require('hono/cors');
22
21
  var cookie = require('hono/cookie');
23
22
  var html = require('hono/html');
24
23
 
@@ -27,6 +26,7 @@ var DocumentPermissionsService = class {
27
26
  constructor(db) {
28
27
  this.db = db;
29
28
  }
29
+ db;
30
30
  // Deny wins. Overrides beat base grants. Empty ACL falls back to base grants.
31
31
  async isAllowed(principalSet, rootId, permission, typeSettings, tenantId) {
32
32
  const overrides = await this.getDocumentPermissions(rootId, principalSet, permission, tenantId);
@@ -74,7 +74,7 @@ var DocumentPermissionsService = class {
74
74
  async grantPermission(opts) {
75
75
  const { tenantId, rootId, principalType, principalId, permission, effect = "allow", createdBy } = opts;
76
76
  const now = Math.floor(Date.now() / 1e3);
77
- const id = chunkJEQ7FLOD_cjs.nanoid();
77
+ const id = chunkKIGVVO6N_cjs.nanoid();
78
78
  await this.db.prepare(
79
79
  `INSERT INTO document_permissions (id, tenant_id, root_id, principal_type, principal_id, permission, effect, inherited, created_at, created_by)
80
80
  VALUES (?, ?, ?, ?, ?, ?, ?, 0, ?, ?)
@@ -135,6 +135,8 @@ var DocumentRepository = class {
135
135
  this.tenantId = tenantId;
136
136
  this.permissions = new DocumentPermissionsService(db);
137
137
  }
138
+ db;
139
+ tenantId;
138
140
  permissions;
139
141
  // ─── Reads ───────────────────────────────────────────────────────────────
140
142
  async getById(id) {
@@ -257,7 +259,7 @@ function getDocumentRequestContext(c) {
257
259
 
258
260
  // src/routes/api-documents.ts
259
261
  async function aclAllowsRead(db, tenantId, principalSet, row, preloadedType) {
260
- const docType = preloadedType ?? await new chunkAAWNRBRB_cjs.DocumentTypeRegistry(db).findById(row.type_id);
262
+ const docType = preloadedType ?? await new chunk4SHNHNRP_cjs.DocumentTypeRegistry(db).findById(row.type_id);
261
263
  if (!docType) return false;
262
264
  return new DocumentRepository(db, tenantId).isAllowed(principalSet, row.root_id, "read", docType.settings);
263
265
  }
@@ -275,7 +277,7 @@ apiDocumentsRoutes.get("/", async (c) => {
275
277
  if (!typeId) {
276
278
  return c.json({ error: "type query parameter is required" }, 400);
277
279
  }
278
- const registry = new chunkAAWNRBRB_cjs.DocumentTypeRegistry(db);
280
+ const registry = new chunk4SHNHNRP_cjs.DocumentTypeRegistry(db);
279
281
  const docType = await registry.findById(typeId);
280
282
  if (!docType || !docType.isActive) {
281
283
  return c.json({ error: "Unknown document type" }, 400);
@@ -357,7 +359,7 @@ apiDocumentsRoutes.get("/root/:rootId", async (c) => {
357
359
  AND (expires_at IS NULL OR expires_at > ?) LIMIT 1`
358
360
  ).bind(rootId, now, now).first();
359
361
  if (!row) return c.json({ error: "Not found" }, 404);
360
- const docType = await new chunkAAWNRBRB_cjs.DocumentTypeRegistry(db).findById(row.type_id);
362
+ const docType = await new chunk4SHNHNRP_cjs.DocumentTypeRegistry(db).findById(row.type_id);
361
363
  const effTenant = effectiveTenantForType(tenantId, docType?.settings);
362
364
  if (row.tenant_id !== effTenant) return c.json({ error: "Not found" }, 404);
363
365
  if (!await aclAllowsRead(db, effTenant, principalSet, row, docType)) {
@@ -393,7 +395,7 @@ apiDocumentsRoutes.get("/:id", async (c) => {
393
395
  AND (expires_at IS NULL OR expires_at > ?) LIMIT 1`
394
396
  ).bind(id, now, now).first();
395
397
  if (!row) return c.json({ error: "Not found" }, 404);
396
- const docType = await new chunkAAWNRBRB_cjs.DocumentTypeRegistry(db).findById(row.type_id);
398
+ const docType = await new chunk4SHNHNRP_cjs.DocumentTypeRegistry(db).findById(row.type_id);
397
399
  const effTenant = effectiveTenantForType(tenantId, docType?.settings);
398
400
  if (row.tenant_id !== effTenant) return c.json({ error: "Not found" }, 404);
399
401
  if (!await aclAllowsRead(db, effTenant, principalSet, row, docType)) {
@@ -463,17 +465,17 @@ async function resolveDocScope(c, db, by, opts = {}) {
463
465
  const draft = opts.currentDraftOnly ? " AND is_current_draft = 1" : "";
464
466
  const row = await db.prepare(`SELECT type_id, root_id, tenant_id FROM documents WHERE ${col} = ?${draft} LIMIT 1`).bind(val).first();
465
467
  if (!row) return null;
466
- const docType = await new chunkAAWNRBRB_cjs.DocumentTypeRegistry(db).findById(row.type_id);
468
+ const docType = await new chunk4SHNHNRP_cjs.DocumentTypeRegistry(db).findById(row.type_id);
467
469
  const tenantId = effectiveTenantForType(getRequestTenant(c), docType?.settings);
468
470
  if (row.tenant_id !== tenantId) return null;
469
471
  return { typeId: row.type_id, rootId: row.root_id, tenantId, docType };
470
472
  }
471
473
  var adminDocumentsRoutes = new hono.Hono();
472
- adminDocumentsRoutes.use("*", chunkAAWNRBRB_cjs.requireAuth());
473
- adminDocumentsRoutes.use("*", chunkAAWNRBRB_cjs.requireRole(["admin", "editor"]));
474
+ adminDocumentsRoutes.use("*", chunk4SHNHNRP_cjs.requireAuth());
475
+ adminDocumentsRoutes.use("*", chunk4SHNHNRP_cjs.requireRole(["admin", "editor"]));
474
476
  adminDocumentsRoutes.get("/types", async (c) => {
475
477
  try {
476
- const registry = new chunkAAWNRBRB_cjs.DocumentTypeRegistry(c.env.DB);
478
+ const registry = new chunk4SHNHNRP_cjs.DocumentTypeRegistry(c.env.DB);
477
479
  const types = await registry.findAll();
478
480
  return c.json({ data: types });
479
481
  } catch (error) {
@@ -501,7 +503,7 @@ adminDocumentsRoutes.get("/", async (c) => {
501
503
  if (!typeId) {
502
504
  return c.json({ error: "type query parameter is required" }, 400);
503
505
  }
504
- const registry = new chunkAAWNRBRB_cjs.DocumentTypeRegistry(db);
506
+ const registry = new chunk4SHNHNRP_cjs.DocumentTypeRegistry(db);
505
507
  const docType = await registry.findById(typeId);
506
508
  if (!docType || !docType.isActive) {
507
509
  return c.json({ error: "Unknown document type" }, 400);
@@ -612,7 +614,7 @@ adminDocumentsRoutes.post("/", async (c) => {
612
614
  const input = validation.data;
613
615
  const db = c.env.DB;
614
616
  const user = c.get("user");
615
- const registry = new chunkAAWNRBRB_cjs.DocumentTypeRegistry(db);
617
+ const registry = new chunk4SHNHNRP_cjs.DocumentTypeRegistry(db);
616
618
  const docType = await registry.findById(input.typeId);
617
619
  if (!docType || !docType.isActive) {
618
620
  return c.json({ error: "Unknown document type" }, 400);
@@ -620,7 +622,7 @@ adminDocumentsRoutes.post("/", async (c) => {
620
622
  const createDenied = await denyIfNotAllowed(c, db, "", "create", docType.settings);
621
623
  if (createDenied) return createDenied;
622
624
  const tenantId = effectiveTenantForType(getRequestTenant(c), docType.settings);
623
- const svc = new chunk2CB4KY7I_cjs.DocumentsService(db, {
625
+ const svc = new chunkLTZ5WYOK_cjs.DocumentsService(db, {
624
626
  queryableFields: docType.queryableFields,
625
627
  typeSchemaVersion: docType.schemaVersion,
626
628
  maxVersionsPerRoot: docType.settings.maxVersionsPerRoot,
@@ -658,7 +660,7 @@ adminDocumentsRoutes.put("/:rootId", async (c) => {
658
660
  const docType = scope.docType;
659
661
  const updateDenied = await denyIfNotAllowed(c, db, rootId, "update", docType?.settings, scope.tenantId);
660
662
  if (updateDenied) return updateDenied;
661
- const svc = new chunk2CB4KY7I_cjs.DocumentsService(db, {
663
+ const svc = new chunkLTZ5WYOK_cjs.DocumentsService(db, {
662
664
  queryableFields: docType?.queryableFields ?? [],
663
665
  typeSchemaVersion: docType?.schemaVersion,
664
666
  maxVersionsPerRoot: docType?.settings.maxVersionsPerRoot,
@@ -683,7 +685,7 @@ adminDocumentsRoutes.post("/:id/publish", async (c) => {
683
685
  const docType = scope.docType;
684
686
  const publishDenied = await denyIfNotAllowed(c, db, scope.rootId, "publish", docType?.settings, scope.tenantId);
685
687
  if (publishDenied) return publishDenied;
686
- const svc = new chunk2CB4KY7I_cjs.DocumentsService(db, {
688
+ const svc = new chunkLTZ5WYOK_cjs.DocumentsService(db, {
687
689
  queryableFields: docType?.queryableFields ?? [],
688
690
  typeSchemaVersion: docType?.schemaVersion,
689
691
  tenantId: scope.tenantId,
@@ -706,7 +708,7 @@ adminDocumentsRoutes.post("/:id/unpublish", async (c) => {
706
708
  const docType = scope.docType;
707
709
  const unpublishDenied = await denyIfNotAllowed(c, db, scope.rootId, "publish", docType?.settings, scope.tenantId);
708
710
  if (unpublishDenied) return unpublishDenied;
709
- const svc = new chunk2CB4KY7I_cjs.DocumentsService(db, {
711
+ const svc = new chunkLTZ5WYOK_cjs.DocumentsService(db, {
710
712
  queryableFields: docType?.queryableFields ?? [],
711
713
  tenantId: scope.tenantId
712
714
  });
@@ -728,7 +730,7 @@ adminDocumentsRoutes.delete("/:id", async (c) => {
728
730
  const docType = scope.docType;
729
731
  const deleteDenied = await denyIfNotAllowed(c, db, scope.rootId, "delete", docType?.settings, scope.tenantId);
730
732
  if (deleteDenied) return deleteDenied;
731
- const svc = new chunk2CB4KY7I_cjs.DocumentsService(db, { queryableFields: docType?.queryableFields ?? [], tenantId: scope.tenantId });
733
+ const svc = new chunkLTZ5WYOK_cjs.DocumentsService(db, { queryableFields: docType?.queryableFields ?? [], tenantId: scope.tenantId });
732
734
  if (docType?.settings.pii) {
733
735
  if (scope.rootId) await svc.erase(scope.rootId, scope.tenantId);
734
736
  } else {
@@ -744,13 +746,13 @@ adminDocumentsRoutes.post("/types/:typeId/reindex", async (c) => {
744
746
  try {
745
747
  const { typeId } = c.req.param();
746
748
  const db = c.env.DB;
747
- const registry = new chunkAAWNRBRB_cjs.DocumentTypeRegistry(db);
749
+ const registry = new chunk4SHNHNRP_cjs.DocumentTypeRegistry(db);
748
750
  const docType = await registry.findById(typeId);
749
751
  if (!docType) return c.json({ error: "Unknown document type" }, 400);
750
752
  const reindexTenant = effectiveTenantForType(getRequestTenant(c), docType.settings);
751
753
  const reindexDenied = await denyIfNotAllowed(c, db, "", "manage", docType.settings, reindexTenant);
752
754
  if (reindexDenied) return reindexDenied;
753
- const { DocumentProjection } = await import('./document-projection-TDWRJX3Z.cjs');
755
+ const { DocumentProjection } = await import('./document-projection-JQHSTSFD.cjs');
754
756
  const projection = new DocumentProjection(db);
755
757
  const rebuilt = await projection.reindexType(typeId, reindexTenant, docType.queryableFields);
756
758
  return c.json({ rebuilt });
@@ -898,13 +900,13 @@ async function resolveContentVariables(contentData, db) {
898
900
  // src/routes/api-content-crud.ts
899
901
  var apiContentCrudRoutes = new hono.Hono();
900
902
  async function resolveDocBacking(db, collectionIdOrName) {
901
- const registry = chunkQAYFOER6_cjs.getCollectionRegistry();
903
+ const registry = chunk5ARIHAGN_cjs.getCollectionRegistry();
902
904
  const record = registry.getBySlugOrName(collectionIdOrName) ?? registry.getById(collectionIdOrName);
903
905
  if (record) {
904
- const docType2 = await new chunkAAWNRBRB_cjs.DocumentTypeRegistry(db).findById(record.name);
906
+ const docType2 = await new chunk4SHNHNRP_cjs.DocumentTypeRegistry(db).findById(record.name);
905
907
  return docType2 ? { coll: { id: record.id, name: record.name }, docType: docType2 } : null;
906
908
  }
907
- const docType = await new chunkAAWNRBRB_cjs.DocumentTypeRegistry(db).findById(collectionIdOrName);
909
+ const docType = await new chunk4SHNHNRP_cjs.DocumentTypeRegistry(db).findById(collectionIdOrName);
908
910
  if (docType) {
909
911
  return { coll: { id: collectionIdOrName, name: collectionIdOrName }, docType };
910
912
  }
@@ -947,7 +949,7 @@ apiContentCrudRoutes.get("/check-slug", async (c) => {
947
949
  }, 500);
948
950
  }
949
951
  });
950
- apiContentCrudRoutes.get("/:id", chunkAAWNRBRB_cjs.optionalAuth(), async (c) => {
952
+ apiContentCrudRoutes.get("/:id", chunk4SHNHNRP_cjs.optionalAuth(), async (c) => {
951
953
  try {
952
954
  const id = c.req.param("id");
953
955
  const db = c.env.DB;
@@ -957,7 +959,7 @@ apiContentCrudRoutes.get("/:id", chunkAAWNRBRB_cjs.optionalAuth(), async (c) =>
957
959
  ).bind(id, getRequestTenant(c)).first();
958
960
  let transformedContent;
959
961
  if (docRow) {
960
- const coll = chunkQAYFOER6_cjs.getCollectionRegistry().getByName(docRow.type_id);
962
+ const coll = chunk5ARIHAGN_cjs.getCollectionRegistry().getByName(docRow.type_id);
961
963
  transformedContent = {
962
964
  id: docRow.root_id,
963
965
  title: docRow.title,
@@ -966,8 +968,8 @@ apiContentCrudRoutes.get("/:id", chunkAAWNRBRB_cjs.optionalAuth(), async (c) =>
966
968
  collectionId: coll?.id ?? docRow.type_id,
967
969
  data: docRow.data ? JSON.parse(docRow.data) : {},
968
970
  // D29: document timestamps are SECONDS; legacy `content` API contract is MILLISECONDS.
969
- created_at: chunk2CB4KY7I_cjs.documentSecondsToMs(docRow.created_at),
970
- updated_at: chunk2CB4KY7I_cjs.documentSecondsToMs(docRow.updated_at)
971
+ created_at: chunkLTZ5WYOK_cjs.documentSecondsToMs(docRow.created_at),
972
+ updated_at: chunkLTZ5WYOK_cjs.documentSecondsToMs(docRow.updated_at)
971
973
  };
972
974
  } else {
973
975
  return c.json({ error: "Content not found" }, 404);
@@ -991,7 +993,7 @@ apiContentCrudRoutes.get("/:id", chunkAAWNRBRB_cjs.optionalAuth(), async (c) =>
991
993
  }, 500);
992
994
  }
993
995
  });
994
- apiContentCrudRoutes.post("/", chunkAAWNRBRB_cjs.requireAuth(), chunkAAWNRBRB_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
996
+ apiContentCrudRoutes.post("/", chunk4SHNHNRP_cjs.requireAuth(), chunk4SHNHNRP_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
995
997
  try {
996
998
  const db = c.env.DB;
997
999
  const user = c.get("user");
@@ -1025,7 +1027,7 @@ apiContentCrudRoutes.post("/", chunkAAWNRBRB_cjs.requireAuth(), chunkAAWNRBRB_cj
1025
1027
  return c.json({ error: "Write cancelled by plugin", details: String(err) }, 400);
1026
1028
  }
1027
1029
  const tenantId = getRequestTenant(c);
1028
- const svc = new chunk2CB4KY7I_cjs.DocumentsService(db, {
1030
+ const svc = new chunkLTZ5WYOK_cjs.DocumentsService(db, {
1029
1031
  queryableFields: backing.docType.queryableFields ?? [],
1030
1032
  typeSchemaVersion: backing.docType.schemaVersion ?? 1,
1031
1033
  maxVersionsPerRoot: backing.docType.settings?.maxVersionsPerRoot ?? 50,
@@ -1044,7 +1046,7 @@ apiContentCrudRoutes.post("/", chunkAAWNRBRB_cjs.requireAuth(), chunkAAWNRBRB_cj
1044
1046
  }),
1045
1047
  user?.userId
1046
1048
  );
1047
- const cache = chunkBDDABDAB_cjs.getCacheService(chunkBDDABDAB_cjs.CACHE_CONFIGS.api);
1049
+ const cache = chunk36Z3AKX3_cjs.getCacheService(chunk36Z3AKX3_cjs.CACHE_CONFIGS.api);
1048
1050
  await cache.invalidate("content-filtered:*");
1049
1051
  await cache.invalidate("collection-content-filtered:*");
1050
1052
  dispatchHookEvent(
@@ -1054,7 +1056,7 @@ apiContentCrudRoutes.post("/", chunkAAWNRBRB_cjs.requireAuth(), chunkAAWNRBRB_cj
1054
1056
  "fire-and-forget"
1055
1057
  );
1056
1058
  return c.json({
1057
- data: { id: doc.rootId, title: doc.title, slug: doc.slug, status: doc.status, collectionId: backing.coll.id, data: doc.data, created_at: chunk2CB4KY7I_cjs.documentSecondsToMs(doc.createdAt), updated_at: chunk2CB4KY7I_cjs.documentSecondsToMs(doc.updatedAt) }
1059
+ data: { id: doc.rootId, title: doc.title, slug: doc.slug, status: doc.status, collectionId: backing.coll.id, data: doc.data, created_at: chunkLTZ5WYOK_cjs.documentSecondsToMs(doc.createdAt), updated_at: chunkLTZ5WYOK_cjs.documentSecondsToMs(doc.updatedAt) }
1058
1060
  }, 201);
1059
1061
  }
1060
1062
  return c.json({ error: "Collection is not document-backed" }, 400);
@@ -1066,7 +1068,7 @@ apiContentCrudRoutes.post("/", chunkAAWNRBRB_cjs.requireAuth(), chunkAAWNRBRB_cj
1066
1068
  }, 500);
1067
1069
  }
1068
1070
  });
1069
- apiContentCrudRoutes.put("/:id", chunkAAWNRBRB_cjs.requireAuth(), chunkAAWNRBRB_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
1071
+ apiContentCrudRoutes.put("/:id", chunk4SHNHNRP_cjs.requireAuth(), chunk4SHNHNRP_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
1070
1072
  try {
1071
1073
  const id = c.req.param("id");
1072
1074
  const db = c.env.DB;
@@ -1088,8 +1090,8 @@ apiContentCrudRoutes.put("/:id", chunkAAWNRBRB_cjs.requireAuth(), chunkAAWNRBRB_
1088
1090
  } catch (err) {
1089
1091
  return c.json({ error: "Write cancelled by plugin", details: String(err) }, 400);
1090
1092
  }
1091
- const docType = await new chunkAAWNRBRB_cjs.DocumentTypeRegistry(db).findById(docRow.type_id);
1092
- const svc = new chunk2CB4KY7I_cjs.DocumentsService(db, {
1093
+ const docType = await new chunk4SHNHNRP_cjs.DocumentTypeRegistry(db).findById(docRow.type_id);
1094
+ const svc = new chunkLTZ5WYOK_cjs.DocumentsService(db, {
1093
1095
  queryableFields: docType?.queryableFields ?? [],
1094
1096
  typeSchemaVersion: docType?.schemaVersion ?? 1,
1095
1097
  maxVersionsPerRoot: docType?.settings?.maxVersionsPerRoot ?? 50,
@@ -1108,10 +1110,10 @@ apiContentCrudRoutes.put("/:id", chunkAAWNRBRB_cjs.requireAuth(), chunkAAWNRBRB_
1108
1110
  } else if (body.status === "draft" && pub) {
1109
1111
  await svc.unpublish(pub.id);
1110
1112
  }
1111
- const cache = chunkBDDABDAB_cjs.getCacheService(chunkBDDABDAB_cjs.CACHE_CONFIGS.api);
1113
+ const cache = chunk36Z3AKX3_cjs.getCacheService(chunk36Z3AKX3_cjs.CACHE_CONFIGS.api);
1112
1114
  await cache.invalidate("content-filtered:*");
1113
1115
  await cache.invalidate("collection-content-filtered:*");
1114
- const coll = chunkQAYFOER6_cjs.getCollectionRegistry().getByName(docRow.type_id);
1116
+ const coll = chunk5ARIHAGN_cjs.getCollectionRegistry().getByName(docRow.type_id);
1115
1117
  const saved = await db.prepare("SELECT * FROM documents WHERE id = ?").bind(newDraft.id).first();
1116
1118
  const savedData = saved?.data ? JSON.parse(saved.data) : {};
1117
1119
  dispatchHookEvent(c, "content:after:update", { collection: docRow.type_id, id, data: savedData, user: actor }, "fire-and-forget");
@@ -1120,7 +1122,7 @@ apiContentCrudRoutes.put("/:id", chunkAAWNRBRB_cjs.requireAuth(), chunkAAWNRBRB_
1120
1122
  dispatchHookEvent(c, "content:after:publish", { collection: docRow.type_id, id, data: savedData, user: actor }, "fire-and-forget");
1121
1123
  }
1122
1124
  return c.json({
1123
- data: { id: saved.root_id, title: saved.title, slug: saved.slug, status: saved.status, collectionId: coll?.id ?? docRow.type_id, data: savedData, created_at: chunk2CB4KY7I_cjs.documentSecondsToMs(saved.created_at), updated_at: chunk2CB4KY7I_cjs.documentSecondsToMs(saved.updated_at) }
1125
+ data: { id: saved.root_id, title: saved.title, slug: saved.slug, status: saved.status, collectionId: coll?.id ?? docRow.type_id, data: savedData, created_at: chunkLTZ5WYOK_cjs.documentSecondsToMs(saved.created_at), updated_at: chunkLTZ5WYOK_cjs.documentSecondsToMs(saved.updated_at) }
1124
1126
  });
1125
1127
  }
1126
1128
  return c.json({ error: "Content not found" }, 404);
@@ -1132,7 +1134,7 @@ apiContentCrudRoutes.put("/:id", chunkAAWNRBRB_cjs.requireAuth(), chunkAAWNRBRB_
1132
1134
  }, 500);
1133
1135
  }
1134
1136
  });
1135
- apiContentCrudRoutes.delete("/:id", chunkAAWNRBRB_cjs.requireAuth(), chunkAAWNRBRB_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
1137
+ apiContentCrudRoutes.delete("/:id", chunk4SHNHNRP_cjs.requireAuth(), chunk4SHNHNRP_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
1136
1138
  try {
1137
1139
  const id = c.req.param("id");
1138
1140
  const db = c.env.DB;
@@ -1148,7 +1150,7 @@ apiContentCrudRoutes.delete("/:id", chunkAAWNRBRB_cjs.requireAuth(), chunkAAWNRB
1148
1150
  }
1149
1151
  const now = Math.floor(Date.now() / 1e3);
1150
1152
  await db.prepare("UPDATE documents SET deleted_at = ?, updated_at = ? WHERE root_id = ? AND tenant_id = ?").bind(now, now, id, tenantId).run();
1151
- const cache = chunkBDDABDAB_cjs.getCacheService(chunkBDDABDAB_cjs.CACHE_CONFIGS.api);
1153
+ const cache = chunk36Z3AKX3_cjs.getCacheService(chunk36Z3AKX3_cjs.CACHE_CONFIGS.api);
1152
1154
  await cache.invalidate("content-filtered:*");
1153
1155
  await cache.invalidate("collection-content-filtered:*");
1154
1156
  dispatchHookEvent(c, "content:after:delete", { collection: docRow.type_id, id, data: {}, user: actor }, "fire-and-forget");
@@ -1245,8 +1247,8 @@ function mapDocRowToContent(row, collectionId) {
1245
1247
  collectionId,
1246
1248
  data: row.data ? JSON.parse(row.data) : {},
1247
1249
  // D29: document timestamps are SECONDS; the legacy `content` API contract is MILLISECONDS.
1248
- created_at: chunk2CB4KY7I_cjs.documentSecondsToMs(row.created_at),
1249
- updated_at: chunk2CB4KY7I_cjs.documentSecondsToMs(row.updated_at)
1250
+ created_at: chunkLTZ5WYOK_cjs.documentSecondsToMs(row.created_at),
1251
+ updated_at: chunkLTZ5WYOK_cjs.documentSecondsToMs(row.updated_at)
1250
1252
  };
1251
1253
  }
1252
1254
  var apiRoutes = new hono.Hono();
@@ -1258,20 +1260,10 @@ apiRoutes.use("*", async (c, next) => {
1258
1260
  c.header("X-Response-Time", `${totalTime}ms`);
1259
1261
  });
1260
1262
  apiRoutes.use("*", async (c, next) => {
1261
- const cacheEnabled = await chunkAAWNRBRB_cjs.isPluginActive(c.env.DB, "core-cache");
1263
+ const cacheEnabled = await chunk4SHNHNRP_cjs.isPluginActive(c.env.DB, "core-cache");
1262
1264
  c.set("cacheEnabled", cacheEnabled);
1263
1265
  await next();
1264
1266
  });
1265
- apiRoutes.use("*", cors.cors({
1266
- origin: (origin, c) => {
1267
- const allowed = c.env?.CORS_ORIGINS;
1268
- if (!allowed) return null;
1269
- const list = allowed.split(",").map((s) => s.trim());
1270
- return list.includes(origin) ? origin : null;
1271
- },
1272
- allowMethods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
1273
- allowHeaders: ["Content-Type", "Authorization", "X-API-Key"]
1274
- }));
1275
1267
  function addTimingMeta(c, meta = {}, executionStartTime) {
1276
1268
  const totalTime = Date.now() - c.get("startTime");
1277
1269
  const executionTime = executionStartTime ? Date.now() - executionStartTime : void 0;
@@ -1291,7 +1283,7 @@ apiRoutes.get("/", (c) => {
1291
1283
  openapi: "3.0.0",
1292
1284
  info: {
1293
1285
  title: "SonicJS AI API",
1294
- version: chunkLRZIAW7U_cjs.getCoreVersion(),
1286
+ version: chunkAQJEMVAY_cjs.getCoreVersion(),
1295
1287
  description: "RESTful API for SonicJS headless CMS - a modern, AI-powered content management system built on Cloudflare Workers",
1296
1288
  contact: {
1297
1289
  name: "SonicJS Support",
@@ -1695,7 +1687,7 @@ apiRoutes.get("/collections", async (c) => {
1695
1687
  try {
1696
1688
  const db = c.env.DB;
1697
1689
  const cacheEnabled = c.get("cacheEnabled");
1698
- const cache = chunkBDDABDAB_cjs.getCacheService(chunkBDDABDAB_cjs.CACHE_CONFIGS.api);
1690
+ const cache = chunk36Z3AKX3_cjs.getCacheService(chunk36Z3AKX3_cjs.CACHE_CONFIGS.api);
1699
1691
  const cacheKey = cache.generateKey("collections", "all");
1700
1692
  if (cacheEnabled) {
1701
1693
  const cacheResult = await cache.getWithSource(cacheKey);
@@ -1721,8 +1713,8 @@ apiRoutes.get("/collections", async (c) => {
1721
1713
  }
1722
1714
  c.header("X-Cache-Status", "MISS");
1723
1715
  c.header("X-Cache-Source", "registry");
1724
- const records = chunkQAYFOER6_cjs.getCollectionRegistry().listActive().filter((r) => !r.internal);
1725
- const transformedResults = records.map(chunkQAYFOER6_cjs.collectionRecordToRow);
1716
+ const records = chunk5ARIHAGN_cjs.getCollectionRegistry().listActive().filter((r) => !r.internal);
1717
+ const transformedResults = records.map(chunk5ARIHAGN_cjs.collectionRecordToRow);
1726
1718
  const responseData = {
1727
1719
  data: transformedResults,
1728
1720
  meta: addTimingMeta(c, {
@@ -1743,7 +1735,7 @@ apiRoutes.get("/collections", async (c) => {
1743
1735
  return c.json({ error: "Failed to fetch collections" }, 500);
1744
1736
  }
1745
1737
  });
1746
- apiRoutes.get("/content", chunkAAWNRBRB_cjs.optionalAuth(), async (c) => {
1738
+ apiRoutes.get("/content", chunk4SHNHNRP_cjs.optionalAuth(), async (c) => {
1747
1739
  const executionStart = Date.now();
1748
1740
  try {
1749
1741
  const db = c.env.DB;
@@ -1752,7 +1744,7 @@ apiRoutes.get("/content", chunkAAWNRBRB_cjs.optionalAuth(), async (c) => {
1752
1744
  const collIdByName = /* @__PURE__ */ new Map();
1753
1745
  let typeId;
1754
1746
  let typeIds;
1755
- const registry = chunkQAYFOER6_cjs.getCollectionRegistry();
1747
+ const registry = chunk5ARIHAGN_cjs.getCollectionRegistry();
1756
1748
  if (queryParams.collection) {
1757
1749
  const collectionName = queryParams.collection;
1758
1750
  const record = registry.getByName(collectionName);
@@ -1795,7 +1787,7 @@ apiRoutes.get("/content", chunkAAWNRBRB_cjs.optionalAuth(), async (c) => {
1795
1787
  }, 400);
1796
1788
  }
1797
1789
  const cacheEnabled = c.get("cacheEnabled");
1798
- const cache = chunkBDDABDAB_cjs.getCacheService(chunkBDDABDAB_cjs.CACHE_CONFIGS.api);
1790
+ const cache = chunk36Z3AKX3_cjs.getCacheService(chunk36Z3AKX3_cjs.CACHE_CONFIGS.api);
1799
1791
  const cacheKey = cache.generateKey("content-filtered", JSON.stringify({ filter: normalizedFilter, query: queryResult.sql }));
1800
1792
  if (cacheEnabled) {
1801
1793
  const cacheResult = await cache.getWithSource(cacheKey);
@@ -1851,13 +1843,13 @@ apiRoutes.get("/content", chunkAAWNRBRB_cjs.optionalAuth(), async (c) => {
1851
1843
  }, 500);
1852
1844
  }
1853
1845
  });
1854
- apiRoutes.get("/collections/:collection/content", chunkAAWNRBRB_cjs.optionalAuth(), async (c) => {
1846
+ apiRoutes.get("/collections/:collection/content", chunk4SHNHNRP_cjs.optionalAuth(), async (c) => {
1855
1847
  const executionStart = Date.now();
1856
1848
  try {
1857
1849
  const collection = c.req.param("collection");
1858
1850
  const db = c.env.DB;
1859
1851
  const queryParams = c.req.query();
1860
- const record = chunkQAYFOER6_cjs.getCollectionRegistry().getBySlugOrName(collection);
1852
+ const record = chunk5ARIHAGN_cjs.getCollectionRegistry().getBySlugOrName(collection);
1861
1853
  if (!record || record.isActive === false) {
1862
1854
  return c.json({ error: "Collection not found" }, 404);
1863
1855
  }
@@ -1879,7 +1871,7 @@ apiRoutes.get("/collections/:collection/content", chunkAAWNRBRB_cjs.optionalAuth
1879
1871
  }, 400);
1880
1872
  }
1881
1873
  const cacheEnabled = c.get("cacheEnabled");
1882
- const cache = chunkBDDABDAB_cjs.getCacheService(chunkBDDABDAB_cjs.CACHE_CONFIGS.api);
1874
+ const cache = chunk36Z3AKX3_cjs.getCacheService(chunk36Z3AKX3_cjs.CACHE_CONFIGS.api);
1883
1875
  const includeCollection = queryParams.include?.split(",").map((s) => s.trim()).includes("collection");
1884
1876
  const cacheKey = cache.generateKey("collection-content-filtered", `${collection}:${JSON.stringify({ filter: normalizedFilter, query: queryResult.sql, includeCollection })}`);
1885
1877
  if (cacheEnabled) {
@@ -1913,7 +1905,7 @@ apiRoutes.get("/collections/:collection/content", chunkAAWNRBRB_cjs.optionalAuth
1913
1905
  const responseData = {
1914
1906
  data: transformedResults,
1915
1907
  meta: addTimingMeta(c, {
1916
- ...includeCollection ? { collection: chunkQAYFOER6_cjs.collectionRecordToRow(record) } : {},
1908
+ ...includeCollection ? { collection: chunk5ARIHAGN_cjs.collectionRecordToRow(record) } : {},
1917
1909
  count: results.length,
1918
1910
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1919
1911
  // D44: echo the caller's filter with the access policy applied (status=published forced for
@@ -1938,13 +1930,13 @@ apiRoutes.get("/collections/:collection/content", chunkAAWNRBRB_cjs.optionalAuth
1938
1930
  }
1939
1931
  });
1940
1932
  apiRoutes.route("/content", api_content_crud_default);
1941
- apiRoutes.get("/:collection", chunkAAWNRBRB_cjs.optionalAuth(), async (c) => {
1933
+ apiRoutes.get("/:collection", chunk4SHNHNRP_cjs.optionalAuth(), async (c) => {
1942
1934
  const executionStart = Date.now();
1943
1935
  try {
1944
1936
  const collection = c.req.param("collection");
1945
1937
  const db = c.env.DB;
1946
1938
  const queryParams = c.req.query();
1947
- const record = chunkQAYFOER6_cjs.getCollectionRegistry().getBySlugOrName(collection);
1939
+ const record = chunk5ARIHAGN_cjs.getCollectionRegistry().getBySlugOrName(collection);
1948
1940
  if (!record || record.isActive === false) {
1949
1941
  return c.json({ error: "Collection not found" }, 404);
1950
1942
  }
@@ -1963,7 +1955,7 @@ apiRoutes.get("/:collection", chunkAAWNRBRB_cjs.optionalAuth(), async (c) => {
1963
1955
  const collectionCache = record.cache;
1964
1956
  const collectionCacheDisabled = collectionCache?.enabled === false;
1965
1957
  const cacheEnabled = c.get("cacheEnabled") && !collectionCacheDisabled;
1966
- const cache = chunkBDDABDAB_cjs.getCacheService(chunkBDDABDAB_cjs.CACHE_CONFIGS.api);
1958
+ const cache = chunk36Z3AKX3_cjs.getCacheService(chunk36Z3AKX3_cjs.CACHE_CONFIGS.api);
1967
1959
  const includeCollection = queryParams.include?.split(",").map((s) => s.trim()).includes("collection");
1968
1960
  const cacheKey = cache.generateKey("collection-content-filtered", `${collection}:${JSON.stringify({ filter: normalizedFilter, query: queryResult.sql, includeCollection })}`);
1969
1961
  if (cacheEnabled) {
@@ -1984,7 +1976,7 @@ apiRoutes.get("/:collection", chunkAAWNRBRB_cjs.optionalAuth(), async (c) => {
1984
1976
  const responseData = {
1985
1977
  data: transformedResults,
1986
1978
  meta: addTimingMeta(c, {
1987
- ...includeCollection ? { collection: chunkQAYFOER6_cjs.collectionRecordToRow(record) } : {},
1979
+ ...includeCollection ? { collection: chunk5ARIHAGN_cjs.collectionRecordToRow(record) } : {},
1988
1980
  count: results.length,
1989
1981
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1990
1982
  filter: normalizePublicContentFilter(filter, role),
@@ -2002,12 +1994,12 @@ apiRoutes.get("/:collection", chunkAAWNRBRB_cjs.optionalAuth(), async (c) => {
2002
1994
  return c.json({ error: "Failed to fetch content", details: error instanceof Error ? error.message : String(error) }, 500);
2003
1995
  }
2004
1996
  });
2005
- apiRoutes.get("/:collection/:id", chunkAAWNRBRB_cjs.optionalAuth(), async (c) => {
1997
+ apiRoutes.get("/:collection/:id", chunk4SHNHNRP_cjs.optionalAuth(), async (c) => {
2006
1998
  try {
2007
1999
  const collection = c.req.param("collection");
2008
2000
  const id = c.req.param("id");
2009
2001
  const db = c.env.DB;
2010
- const record = chunkQAYFOER6_cjs.getCollectionRegistry().getBySlugOrName(collection);
2002
+ const record = chunk5ARIHAGN_cjs.getCollectionRegistry().getBySlugOrName(collection);
2011
2003
  if (!record || record.isActive === false) {
2012
2004
  return c.json({ error: "Collection not found" }, 404);
2013
2005
  }
@@ -2016,7 +2008,7 @@ apiRoutes.get("/:collection/:id", chunkAAWNRBRB_cjs.optionalAuth(), async (c) =>
2016
2008
  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"
2017
2009
  ).bind(id, record.name).first();
2018
2010
  if (!docRow) return c.json({ error: "Content not found" }, 404);
2019
- const coll = chunkQAYFOER6_cjs.getCollectionRegistry().getByName(docRow.type_id);
2011
+ const coll = chunk5ARIHAGN_cjs.getCollectionRegistry().getByName(docRow.type_id);
2020
2012
  const transformedContent = {
2021
2013
  id: docRow.root_id,
2022
2014
  title: docRow.title,
@@ -2024,8 +2016,8 @@ apiRoutes.get("/:collection/:id", chunkAAWNRBRB_cjs.optionalAuth(), async (c) =>
2024
2016
  status: docRow.status,
2025
2017
  collectionId: coll?.id ?? docRow.type_id,
2026
2018
  data: docRow.data ? JSON.parse(docRow.data) : {},
2027
- created_at: chunk2CB4KY7I_cjs.documentSecondsToMs(docRow.created_at),
2028
- updated_at: chunk2CB4KY7I_cjs.documentSecondsToMs(docRow.updated_at)
2019
+ created_at: chunkLTZ5WYOK_cjs.documentSecondsToMs(docRow.created_at),
2020
+ updated_at: chunkLTZ5WYOK_cjs.documentSecondsToMs(docRow.updated_at)
2029
2021
  };
2030
2022
  dispatchHookEvent(c, "content:read", { collection: docRow.type_id, id: docRow.root_id, data: transformedContent.data }, "fire-and-forget");
2031
2023
  return c.json({ data: transformedContent });
@@ -2034,7 +2026,7 @@ apiRoutes.get("/:collection/:id", chunkAAWNRBRB_cjs.optionalAuth(), async (c) =>
2034
2026
  return c.json({ error: "Failed to fetch content", details: error instanceof Error ? error.message : String(error) }, 500);
2035
2027
  }
2036
2028
  });
2037
- apiRoutes.post("/:collection", chunkAAWNRBRB_cjs.requireAuth(), chunkAAWNRBRB_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
2029
+ apiRoutes.post("/:collection", chunk4SHNHNRP_cjs.requireAuth(), chunk4SHNHNRP_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
2038
2030
  try {
2039
2031
  const collection = c.req.param("collection");
2040
2032
  const db = c.env.DB;
@@ -2055,26 +2047,26 @@ apiRoutes.post("/:collection", chunkAAWNRBRB_cjs.requireAuth(), chunkAAWNRBRB_cj
2055
2047
  } catch (err) {
2056
2048
  return c.json({ error: "Write cancelled by plugin", details: String(err) }, 400);
2057
2049
  }
2058
- const svc = new chunk2CB4KY7I_cjs.DocumentsService(db, { queryableFields: backing.docType.queryableFields ?? [], typeSchemaVersion: backing.docType.schemaVersion ?? 1, maxVersionsPerRoot: backing.docType.settings?.maxVersionsPerRoot ?? 50, tenantId: "default", versioning: backing.docType.settings?.versioning ?? false });
2050
+ const svc = new chunkLTZ5WYOK_cjs.DocumentsService(db, { queryableFields: backing.docType.queryableFields ?? [], typeSchemaVersion: backing.docType.schemaVersion ?? 1, maxVersionsPerRoot: backing.docType.settings?.maxVersionsPerRoot ?? 50, tenantId: "default", versioning: backing.docType.settings?.versioning ?? false });
2059
2051
  const doc = await svc.create(createDocumentSchema.parse({ typeId: backing.coll.name, tenantId: "default", locale: "default", title, slug: finalSlug, data: hookData, publishOnCreate: (status || "draft") === "published" }), user?.userId);
2060
- const cache = chunkBDDABDAB_cjs.getCacheService(chunkBDDABDAB_cjs.CACHE_CONFIGS.api);
2052
+ const cache = chunk36Z3AKX3_cjs.getCacheService(chunk36Z3AKX3_cjs.CACHE_CONFIGS.api);
2061
2053
  await cache.invalidate("content-filtered:*");
2062
2054
  await cache.invalidate("collection-content-filtered:*");
2063
2055
  dispatchHookEvent(c, "content:after:create", { collection: backing.coll.name, id: doc.rootId, data: doc.data ?? {}, user: actor }, "fire-and-forget");
2064
- return c.json({ data: { id: doc.rootId, title: doc.title, slug: doc.slug, status: doc.status, collectionId: backing.coll.id, data: doc.data, created_at: chunk2CB4KY7I_cjs.documentSecondsToMs(doc.createdAt), updated_at: chunk2CB4KY7I_cjs.documentSecondsToMs(doc.updatedAt) } }, 201);
2056
+ return c.json({ data: { id: doc.rootId, title: doc.title, slug: doc.slug, status: doc.status, collectionId: backing.coll.id, data: doc.data, created_at: chunkLTZ5WYOK_cjs.documentSecondsToMs(doc.createdAt), updated_at: chunkLTZ5WYOK_cjs.documentSecondsToMs(doc.updatedAt) } }, 201);
2065
2057
  } catch (error) {
2066
2058
  console.error("Error creating content:", error);
2067
2059
  return c.json({ error: "Failed to create content", details: error instanceof Error ? error.message : String(error) }, 500);
2068
2060
  }
2069
2061
  });
2070
- apiRoutes.put("/:collection/:id", chunkAAWNRBRB_cjs.requireAuth(), chunkAAWNRBRB_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
2062
+ apiRoutes.put("/:collection/:id", chunk4SHNHNRP_cjs.requireAuth(), chunk4SHNHNRP_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
2071
2063
  try {
2072
2064
  const collection = c.req.param("collection");
2073
2065
  const id = c.req.param("id");
2074
2066
  const db = c.env.DB;
2075
2067
  const user = c.get("user");
2076
2068
  const body = await c.req.json();
2077
- const collRecord = chunkQAYFOER6_cjs.getCollectionRegistry().getBySlugOrName(collection);
2069
+ const collRecord = chunk5ARIHAGN_cjs.getCollectionRegistry().getBySlugOrName(collection);
2078
2070
  const typeName = collRecord?.name ?? collection;
2079
2071
  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();
2080
2072
  if (!docRow) return c.json({ error: "Content not found" }, 404);
@@ -2086,8 +2078,8 @@ apiRoutes.put("/:collection/:id", chunkAAWNRBRB_cjs.requireAuth(), chunkAAWNRBRB
2086
2078
  } catch (err) {
2087
2079
  return c.json({ error: "Write cancelled by plugin", details: String(err) }, 400);
2088
2080
  }
2089
- const docType = await new chunkAAWNRBRB_cjs.DocumentTypeRegistry(db).findById(docRow.type_id);
2090
- const svc = new chunk2CB4KY7I_cjs.DocumentsService(db, { queryableFields: docType?.queryableFields ?? [], typeSchemaVersion: docType?.schemaVersion ?? 1, maxVersionsPerRoot: docType?.settings?.maxVersionsPerRoot ?? 50, tenantId: "default", versioning: docType?.settings?.versioning ?? false });
2081
+ const docType = await new chunk4SHNHNRP_cjs.DocumentTypeRegistry(db).findById(docRow.type_id);
2082
+ 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 });
2091
2083
  const input = {};
2092
2084
  if (body.title !== void 0) input.title = body.title;
2093
2085
  if (body.slug !== void 0) input.slug = slugify(body.slug);
@@ -2100,28 +2092,28 @@ apiRoutes.put("/:collection/:id", chunkAAWNRBRB_cjs.requireAuth(), chunkAAWNRBRB
2100
2092
  } else if (body.status === "draft" && pub) {
2101
2093
  await svc.unpublish(pub.id);
2102
2094
  }
2103
- const cache = chunkBDDABDAB_cjs.getCacheService(chunkBDDABDAB_cjs.CACHE_CONFIGS.api);
2095
+ const cache = chunk36Z3AKX3_cjs.getCacheService(chunk36Z3AKX3_cjs.CACHE_CONFIGS.api);
2104
2096
  await cache.invalidate("content-filtered:*");
2105
2097
  await cache.invalidate("collection-content-filtered:*");
2106
- const coll = chunkQAYFOER6_cjs.getCollectionRegistry().getByName(docRow.type_id);
2098
+ const coll = chunk5ARIHAGN_cjs.getCollectionRegistry().getByName(docRow.type_id);
2107
2099
  const saved = await db.prepare("SELECT * FROM documents WHERE id = ?").bind(newDraft.id).first();
2108
2100
  const savedData = saved?.data ? JSON.parse(saved.data) : {};
2109
2101
  dispatchHookEvent(c, "content:after:update", { collection: docRow.type_id, id, data: savedData, user: actor }, "fire-and-forget");
2110
2102
  const nowPublished = body.status === "published" || body.status === void 0 && wasPublished;
2111
2103
  if (nowPublished && !wasPublished) dispatchHookEvent(c, "content:after:publish", { collection: docRow.type_id, id, data: savedData, user: actor }, "fire-and-forget");
2112
- return c.json({ data: { id: saved.root_id, title: saved.title, slug: saved.slug, status: saved.status, collectionId: coll?.id ?? docRow.type_id, data: savedData, created_at: chunk2CB4KY7I_cjs.documentSecondsToMs(saved.created_at), updated_at: chunk2CB4KY7I_cjs.documentSecondsToMs(saved.updated_at) } });
2104
+ return c.json({ data: { id: saved.root_id, title: saved.title, slug: saved.slug, status: saved.status, collectionId: coll?.id ?? docRow.type_id, data: savedData, created_at: chunkLTZ5WYOK_cjs.documentSecondsToMs(saved.created_at), updated_at: chunkLTZ5WYOK_cjs.documentSecondsToMs(saved.updated_at) } });
2113
2105
  } catch (error) {
2114
2106
  console.error("Error updating content:", error);
2115
2107
  return c.json({ error: "Failed to update content", details: error instanceof Error ? error.message : String(error) }, 500);
2116
2108
  }
2117
2109
  });
2118
- apiRoutes.delete("/:collection/:id", chunkAAWNRBRB_cjs.requireAuth(), chunkAAWNRBRB_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
2110
+ apiRoutes.delete("/:collection/:id", chunk4SHNHNRP_cjs.requireAuth(), chunk4SHNHNRP_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
2119
2111
  try {
2120
2112
  const collection = c.req.param("collection");
2121
2113
  const id = c.req.param("id");
2122
2114
  const db = c.env.DB;
2123
2115
  const user = c.get("user");
2124
- const collRecord = chunkQAYFOER6_cjs.getCollectionRegistry().getBySlugOrName(collection);
2116
+ const collRecord = chunk5ARIHAGN_cjs.getCollectionRegistry().getBySlugOrName(collection);
2125
2117
  const typeName = collRecord?.name ?? collection;
2126
2118
  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();
2127
2119
  if (!docRow) return c.json({ error: "Content not found" }, 404);
@@ -2133,7 +2125,7 @@ apiRoutes.delete("/:collection/:id", chunkAAWNRBRB_cjs.requireAuth(), chunkAAWNR
2133
2125
  }
2134
2126
  const now = Math.floor(Date.now() / 1e3);
2135
2127
  await db.prepare("UPDATE documents SET deleted_at = ?, updated_at = ? WHERE root_id = ? AND tenant_id = 'default'").bind(now, now, id).run();
2136
- const cache = chunkBDDABDAB_cjs.getCacheService(chunkBDDABDAB_cjs.CACHE_CONFIGS.api);
2128
+ const cache = chunk36Z3AKX3_cjs.getCacheService(chunk36Z3AKX3_cjs.CACHE_CONFIGS.api);
2137
2129
  await cache.invalidate("content-filtered:*");
2138
2130
  await cache.invalidate("collection-content-filtered:*");
2139
2131
  dispatchHookEvent(c, "content:after:delete", { collection: docRow.type_id, id, data: {}, user: actor }, "fire-and-forget");
@@ -2204,9 +2196,11 @@ var MediaDocumentService = class {
2204
2196
  this.db = db;
2205
2197
  this.tenantId = tenantId;
2206
2198
  }
2199
+ db;
2200
+ tenantId;
2207
2201
  /** Create a media_asset document from R2 upload metadata. Published-on-create (immediately usable). */
2208
2202
  async createFromUpload(meta, createdBy) {
2209
- const svc = new chunk2CB4KY7I_cjs.DocumentsService(this.db, { queryableFields: MEDIA_QUERYABLE, tenantId: this.tenantId, maxVersionsPerRoot: 5 });
2203
+ const svc = new chunkLTZ5WYOK_cjs.DocumentsService(this.db, { queryableFields: MEDIA_QUERYABLE, tenantId: this.tenantId, maxVersionsPerRoot: 5 });
2210
2204
  return svc.create(
2211
2205
  createDocumentSchema.parse({
2212
2206
  typeId: "media_asset",
@@ -2279,7 +2273,7 @@ var MediaDocumentService = class {
2279
2273
  }
2280
2274
  /** Update alt/caption/tags on a media_asset document (saveDraft + publish atomically). */
2281
2275
  async updateMetadata(rootId, meta, updatedBy) {
2282
- const svc = new chunk2CB4KY7I_cjs.DocumentsService(this.db, { queryableFields: MEDIA_QUERYABLE, tenantId: this.tenantId, maxVersionsPerRoot: 5 });
2276
+ const svc = new chunkLTZ5WYOK_cjs.DocumentsService(this.db, { queryableFields: MEDIA_QUERYABLE, tenantId: this.tenantId, maxVersionsPerRoot: 5 });
2283
2277
  const newDraft = await svc.saveDraft(rootId, { data: meta }, updatedBy);
2284
2278
  return svc.publish(newDraft.id, updatedBy);
2285
2279
  }
@@ -2336,7 +2330,7 @@ var fileValidationSchema = zod.z.object({
2336
2330
  // 50MB max
2337
2331
  });
2338
2332
  var apiMediaRoutes = new hono.Hono();
2339
- apiMediaRoutes.use("*", chunkAAWNRBRB_cjs.requireAuth());
2333
+ apiMediaRoutes.use("*", chunk4SHNHNRP_cjs.requireAuth());
2340
2334
  apiMediaRoutes.post("/upload", async (c) => {
2341
2335
  try {
2342
2336
  const user = c.get("user");
@@ -3034,7 +3028,7 @@ apiSystemRoutes.get("/info", (c) => {
3034
3028
  apiSystemRoutes.get("/stats", async (c) => {
3035
3029
  try {
3036
3030
  const db = c.env.DB;
3037
- const typeIds = chunkQAYFOER6_cjs.getCollectionRegistry().listActive().filter((r) => !r.internal).map((r) => r.name);
3031
+ const typeIds = chunk5ARIHAGN_cjs.getCollectionRegistry().listActive().filter((r) => !r.internal).map((r) => r.name);
3038
3032
  let contentStats = null;
3039
3033
  if (typeIds.length > 0) {
3040
3034
  const placeholders = typeIds.map(() => "?").join(",");
@@ -3109,12 +3103,12 @@ apiSystemRoutes.get("/env", (c) => {
3109
3103
  });
3110
3104
  var api_system_default = apiSystemRoutes;
3111
3105
  var adminApiRoutes = new hono.Hono();
3112
- adminApiRoutes.use("*", chunkAAWNRBRB_cjs.requireAuth());
3113
- adminApiRoutes.use("*", chunkAAWNRBRB_cjs.requireRole(["admin", "editor"]));
3106
+ adminApiRoutes.use("*", chunk4SHNHNRP_cjs.requireAuth());
3107
+ adminApiRoutes.use("*", chunk4SHNHNRP_cjs.requireRole(["admin", "editor"]));
3114
3108
  adminApiRoutes.get("/stats", async (c) => {
3115
3109
  try {
3116
3110
  const db = c.env.DB;
3117
- const userCollections = chunkQAYFOER6_cjs.getCollectionRegistry().listActive().filter((r) => !r.internal);
3111
+ const userCollections = chunk5ARIHAGN_cjs.getCollectionRegistry().listActive().filter((r) => !r.internal);
3118
3112
  const collectionsCount = userCollections.length;
3119
3113
  let contentCount = 0;
3120
3114
  if (userCollections.length > 0) {
@@ -3205,7 +3199,7 @@ adminApiRoutes.get("/collections", async (c) => {
3205
3199
  try {
3206
3200
  const search = c.req.query("search") || "";
3207
3201
  const includeInactive = c.req.query("includeInactive") === "true";
3208
- let records = chunkQAYFOER6_cjs.getCollectionRegistry().list().filter((r) => !r.internal);
3202
+ let records = chunk5ARIHAGN_cjs.getCollectionRegistry().list().filter((r) => !r.internal);
3209
3203
  if (!includeInactive) records = records.filter((r) => r.isActive !== false);
3210
3204
  if (search) {
3211
3205
  const needle = search.toLowerCase();
@@ -3237,7 +3231,7 @@ adminApiRoutes.get("/collections", async (c) => {
3237
3231
  adminApiRoutes.get("/collections/:id", async (c) => {
3238
3232
  try {
3239
3233
  const id = c.req.param("id");
3240
- const registry = chunkQAYFOER6_cjs.getCollectionRegistry();
3234
+ const registry = chunk5ARIHAGN_cjs.getCollectionRegistry();
3241
3235
  const record = registry.getById(id) ?? registry.getByName(id);
3242
3236
  if (!record) {
3243
3237
  return c.json({ error: "Collection not found" }, 404);
@@ -3287,7 +3281,7 @@ adminApiRoutes.get("/references", async (c) => {
3287
3281
  if (collectionParams.length === 0) {
3288
3282
  return c.json({ error: "Collection is required" }, 400);
3289
3283
  }
3290
- const registry = chunkQAYFOER6_cjs.getCollectionRegistry();
3284
+ const registry = chunk5ARIHAGN_cjs.getCollectionRegistry();
3291
3285
  const matched = collectionParams.map((param) => registry.getById(param) ?? registry.getByName(param)).filter((r) => !!r);
3292
3286
  const seen = /* @__PURE__ */ new Set();
3293
3287
  const collections = matched.filter((r) => {
@@ -3402,7 +3396,7 @@ adminApiRoutes.patch("/collections/:id", collectionsReadOnly);
3402
3396
  adminApiRoutes.delete("/collections/:id", collectionsReadOnly);
3403
3397
  adminApiRoutes.get("/migrations/status", async (c) => {
3404
3398
  try {
3405
- const { MigrationService: MigrationService2 } = await import('./migrations-NJJWQUKK.cjs');
3399
+ const { MigrationService: MigrationService2 } = await import('./migrations-VQAFXMU7.cjs');
3406
3400
  const db = c.env.DB;
3407
3401
  const migrationService = new MigrationService2(db);
3408
3402
  const status = await migrationService.getMigrationStatus();
@@ -3445,7 +3439,7 @@ adminApiRoutes.post("/migrations/run", async (c) => {
3445
3439
  });
3446
3440
  adminApiRoutes.get("/migrations/validate", async (c) => {
3447
3441
  try {
3448
- const { MigrationService: MigrationService2 } = await import('./migrations-NJJWQUKK.cjs');
3442
+ const { MigrationService: MigrationService2 } = await import('./migrations-VQAFXMU7.cjs');
3449
3443
  const db = c.env.DB;
3450
3444
  const migrationService = new MigrationService2(db);
3451
3445
  const validation = await migrationService.validateSchema();
@@ -3595,8 +3589,8 @@ function renderLoginPage(data, demoLoginActive = false) {
3595
3589
  <div class="mt-8 sm:mx-auto sm:w-full sm:max-w-md">
3596
3590
  <div class="bg-zinc-900 shadow-sm ring-1 ring-white/10 rounded-xl px-6 py-8 sm:px-10">
3597
3591
  <!-- Alerts -->
3598
- ${data.error ? `<div class="mb-6">${chunkMVIZJOO5_cjs.renderAlert({ type: "error", message: data.error })}</div>` : ""}
3599
- ${data.message ? `<div class="mb-6">${chunkMVIZJOO5_cjs.renderAlert({ type: "success", message: data.message })}</div>` : ""}
3592
+ ${data.error ? `<div class="mb-6">${chunkPXNTCCPE_cjs.renderAlert({ type: "error", message: data.error })}</div>` : ""}
3593
+ ${data.message ? `<div class="mb-6">${chunkPXNTCCPE_cjs.renderAlert({ type: "success", message: data.message })}</div>` : ""}
3600
3594
 
3601
3595
  <!-- Form Response (HTMX target) -->
3602
3596
  <div id="form-response" class="mb-6"></div>
@@ -3604,7 +3598,7 @@ function renderLoginPage(data, demoLoginActive = false) {
3604
3598
  <!-- Form -->
3605
3599
  <form
3606
3600
  id="login-form"
3607
- hx-post="/auth/login/form"
3601
+ hx-post="/auth/login/form${data.redirect ? `?redirect=${encodeURIComponent(data.redirect)}` : ""}"
3608
3602
  hx-target="#form-response"
3609
3603
  hx-swap="innerHTML"
3610
3604
  class="space-y-6"
@@ -3760,7 +3754,7 @@ function renderRegisterPage(data) {
3760
3754
  <div class="mt-8 sm:mx-auto sm:w-full sm:max-w-md">
3761
3755
  <div class="bg-zinc-900 shadow-sm ring-1 ring-white/10 rounded-xl px-6 py-8 sm:px-10">
3762
3756
  <!-- Alerts -->
3763
- ${data.error ? `<div class="mb-6">${chunkMVIZJOO5_cjs.renderAlert({ type: "error", message: data.error })}</div>` : ""}
3757
+ ${data.error ? `<div class="mb-6">${chunkPXNTCCPE_cjs.renderAlert({ type: "error", message: data.error })}</div>` : ""}
3764
3758
 
3765
3759
  <!-- Form -->
3766
3760
  <form
@@ -3860,7 +3854,7 @@ function renderRegisterPage(data) {
3860
3854
  }
3861
3855
 
3862
3856
  // src/services/email/email-service-singleton.ts
3863
- var singleton = chunkXW56B23A_cjs.createServiceSingleton("EmailService");
3857
+ var singleton = chunk5RSB5SEK_cjs.createServiceSingleton("EmailService");
3864
3858
  function setEmailService(service2) {
3865
3859
  singleton.set(service2);
3866
3860
  }
@@ -3904,7 +3898,7 @@ function emptyProfile() {
3904
3898
  return { custom: {} };
3905
3899
  }
3906
3900
  function service(db) {
3907
- return new chunk2CB4KY7I_cjs.DocumentsService(db, { tenantId: "default", maxVersionsPerRoot: 1, queryableFields: [] });
3901
+ return new chunkLTZ5WYOK_cjs.DocumentsService(db, { tenantId: "default", maxVersionsPerRoot: 1, queryableFields: [] });
3908
3902
  }
3909
3903
  async function readProfileData(db, userId) {
3910
3904
  const row = await db.prepare(
@@ -4668,7 +4662,7 @@ function getLexicalInitScript(settings = {}) {
4668
4662
  </script>
4669
4663
  `;
4670
4664
  }
4671
- var lexicalEditorPlugin = chunkXW56B23A_cjs.definePlugin({
4665
+ var lexicalEditorPlugin = chunk5RSB5SEK_cjs.definePlugin({
4672
4666
  id: "lexical-editor",
4673
4667
  version: "1.0.0",
4674
4668
  name: "Lexical Editor",
@@ -5592,6 +5586,79 @@ function renderDynamicField(field, options = {}) {
5592
5586
  `;
5593
5587
  break;
5594
5588
  }
5589
+ case "json": {
5590
+ const jsonParsedValue = value !== null && value !== void 0 && typeof value !== "string" ? value : typeof value === "string" && value !== "" ? (() => {
5591
+ try {
5592
+ return JSON.parse(value);
5593
+ } catch {
5594
+ return value;
5595
+ }
5596
+ })() : null;
5597
+ const jsonDisplayValue = jsonParsedValue !== null && typeof jsonParsedValue !== "string" ? JSON.stringify(jsonParsedValue, null, 2) : typeof jsonParsedValue === "string" ? jsonParsedValue : "";
5598
+ const viewerId = `${fieldId}-viewer`;
5599
+ const textareaId = `${fieldId}-textarea`;
5600
+ const jsonDataAttr = escapeHtml2(JSON.stringify(jsonParsedValue ?? null));
5601
+ const isEmpty = jsonParsedValue === null || jsonDisplayValue === "";
5602
+ if (disabled) {
5603
+ fieldHTML = `
5604
+ <div
5605
+ id="${viewerId}"
5606
+ class="json-viewer-host rounded-lg px-3 py-2 text-xs bg-white dark:bg-zinc-800 shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 min-h-[2.5rem] overflow-auto"
5607
+ data-json-viewer
5608
+ data-json="${jsonDataAttr}"
5609
+ data-open="${opts.open ?? 2}"
5610
+ >${isEmpty ? '<span class="text-zinc-400 dark:text-zinc-500 italic">empty</span>' : ""}</div>
5611
+ ${getJsonViewerScript()}
5612
+ `;
5613
+ } else {
5614
+ fieldHTML = `
5615
+ <div class="json-field-wrapper space-y-2">
5616
+ <div class="flex items-center justify-end">
5617
+ <button
5618
+ type="button"
5619
+ id="${fieldId}-toggle"
5620
+ class="text-xs text-zinc-500 dark:text-zinc-400 hover:text-zinc-700 dark:hover:text-zinc-200 underline transition-colors"
5621
+ data-json-toggle
5622
+ data-viewer="${viewerId}"
5623
+ data-textarea="${textareaId}"
5624
+ data-hidden-input="${fieldId}"
5625
+ >Edit JSON</button>
5626
+ </div>
5627
+
5628
+ <div
5629
+ id="${viewerId}"
5630
+ class="json-viewer-host rounded-lg px-3 py-2 text-xs bg-white dark:bg-zinc-800 shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 min-h-[2.5rem] overflow-auto"
5631
+ data-json-viewer
5632
+ data-json="${jsonDataAttr}"
5633
+ data-open="${opts.open ?? 2}"
5634
+ >${isEmpty ? '<span class="text-zinc-400 dark:text-zinc-500 italic">empty \u2014 click &quot;Edit JSON&quot; to add data</span>' : ""}</div>
5635
+
5636
+ <textarea
5637
+ id="${textareaId}"
5638
+ rows="${opts.rows || 8}"
5639
+ placeholder="${opts.placeholder || "{}"}"
5640
+ class="${baseClasses} ${errorClasses} resize-y font-mono text-xs hidden"
5641
+ aria-label="${escapeHtml2(field.field_label)}"
5642
+ data-json-edit-area
5643
+ data-viewer="${viewerId}"
5644
+ data-hidden-input="${fieldId}"
5645
+ >${escapeHtml2(jsonDisplayValue)}</textarea>
5646
+
5647
+ <input
5648
+ type="hidden"
5649
+ id="${fieldId}"
5650
+ name="${fieldName}"
5651
+ value="${escapeHtml2(jsonDisplayValue)}"
5652
+ ${required}
5653
+ >
5654
+
5655
+ <div id="${fieldId}-json-error" class="text-xs text-pink-500 dark:text-pink-400 hidden"></div>
5656
+ </div>
5657
+ ${getJsonViewerScript()}
5658
+ `;
5659
+ }
5660
+ break;
5661
+ }
5595
5662
  default:
5596
5663
  fieldHTML = `
5597
5664
  <input
@@ -6088,6 +6155,120 @@ function normalizeBlockField(fieldConfig, fieldName) {
6088
6155
  options
6089
6156
  };
6090
6157
  }
6158
+ function getJsonViewerScript() {
6159
+ return `
6160
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/json-formatter-js@2.5.23/dist/json-formatter.min.css" id="json-formatter-css" onload="this.removeAttribute('onload')" onerror="">
6161
+ <script>
6162
+ (function() {
6163
+ var JS_URL = 'https://cdn.jsdelivr.net/npm/json-formatter-js@2.5.23/dist/json-formatter.umd.min.js';
6164
+
6165
+ function isDark() {
6166
+ return document.documentElement.classList.contains('dark') ||
6167
+ document.documentElement.dataset.theme === 'dark' ||
6168
+ window.matchMedia('(prefers-color-scheme: dark)').matches;
6169
+ }
6170
+
6171
+ function initViewer(el) {
6172
+ var raw = el.dataset.json;
6173
+ var open = parseInt(el.dataset.open || '2', 10);
6174
+ if (!raw || raw === 'null') return;
6175
+ var data;
6176
+ try { data = JSON.parse(raw); } catch(e) { el.textContent = raw; return; }
6177
+ var fmt = new JSONFormatter(data, open, {
6178
+ hoverPreviewEnabled: true,
6179
+ hoverPreviewArrayCount: 5,
6180
+ hoverPreviewFieldCount: 5,
6181
+ theme: isDark() ? 'dark' : '',
6182
+ animateOpen: true,
6183
+ animateClose: true,
6184
+ });
6185
+ el.innerHTML = '';
6186
+ el.appendChild(fmt.render());
6187
+ }
6188
+
6189
+ function initAllViewers() {
6190
+ document.querySelectorAll('[data-json-viewer]').forEach(function(el) { initViewer(el); });
6191
+ }
6192
+
6193
+ function ensureLoaded(cb) {
6194
+ if (window.JSONFormatter) { cb(); return; }
6195
+ if (window.__jsonFormatterCallbacks) { window.__jsonFormatterCallbacks.push(cb); return; }
6196
+ window.__jsonFormatterCallbacks = [cb];
6197
+ var s = document.createElement('script');
6198
+ s.src = JS_URL;
6199
+ s.onload = function() {
6200
+ (window.__jsonFormatterCallbacks || []).forEach(function(fn) { fn(); });
6201
+ window.__jsonFormatterCallbacks = null;
6202
+ };
6203
+ document.head.appendChild(s);
6204
+ }
6205
+
6206
+ if (!window.__sonicJsonViewerInit) {
6207
+ window.__sonicJsonViewerInit = true;
6208
+
6209
+ // Toggle between viewer and edit textarea
6210
+ document.addEventListener('click', function(e) {
6211
+ var btn = e.target.closest('[data-json-toggle]');
6212
+ if (!btn) return;
6213
+ var viewerId = btn.dataset.viewer;
6214
+ var textareaId = btn.dataset.textarea;
6215
+ var hiddenId = btn.dataset.hiddenInput;
6216
+ var viewer = document.getElementById(viewerId);
6217
+ var textarea = document.getElementById(textareaId);
6218
+ var hidden = document.getElementById(hiddenId);
6219
+ var errorEl = hidden ? document.getElementById(hiddenId + '-json-error') : null;
6220
+ if (!viewer || !textarea) return;
6221
+ var isEditing = !textarea.classList.contains('hidden');
6222
+ if (isEditing) {
6223
+ // Switching back to viewer \u2014 validate + refresh
6224
+ var raw = textarea.value.trim();
6225
+ if (raw) {
6226
+ try {
6227
+ var parsed = JSON.parse(raw);
6228
+ if (hidden) hidden.value = raw;
6229
+ viewer.dataset.json = JSON.stringify(parsed);
6230
+ ensureLoaded(function() { initViewer(viewer); });
6231
+ if (errorEl) { errorEl.textContent = ''; errorEl.classList.add('hidden'); }
6232
+ } catch(ex) {
6233
+ if (errorEl) { errorEl.textContent = 'Invalid JSON: ' + ex.message; errorEl.classList.remove('hidden'); }
6234
+ return;
6235
+ }
6236
+ } else {
6237
+ if (hidden) hidden.value = '';
6238
+ viewer.innerHTML = '<span class="text-zinc-400 dark:text-zinc-500 italic">empty</span>';
6239
+ }
6240
+ textarea.classList.add('hidden');
6241
+ viewer.classList.remove('hidden');
6242
+ btn.textContent = 'Edit JSON';
6243
+ } else {
6244
+ // Switching to edit \u2014 populate textarea from hidden input
6245
+ if (hidden && hidden.value) {
6246
+ try {
6247
+ textarea.value = JSON.stringify(JSON.parse(hidden.value), null, 2);
6248
+ } catch(e) {
6249
+ textarea.value = hidden.value;
6250
+ }
6251
+ }
6252
+ viewer.classList.add('hidden');
6253
+ textarea.classList.remove('hidden');
6254
+ btn.textContent = 'Preview';
6255
+ }
6256
+ });
6257
+ }
6258
+
6259
+ function run() {
6260
+ ensureLoaded(initAllViewers);
6261
+ }
6262
+
6263
+ if (document.readyState === 'loading') {
6264
+ document.addEventListener('DOMContentLoaded', run);
6265
+ } else {
6266
+ run();
6267
+ }
6268
+ })();
6269
+ </script>
6270
+ `;
6271
+ }
6091
6272
  function getStructuredFieldScript() {
6092
6273
  return `
6093
6274
  ${getReadFieldValueScript()}
@@ -6887,7 +7068,7 @@ api.put("/:userId", async (c) => {
6887
7068
  await saveCustomData(db, userId, sanitized);
6888
7069
  return c.json({ success: true });
6889
7070
  });
6890
- var userProfilesPlugin = chunkXW56B23A_cjs.definePlugin({
7071
+ var userProfilesPlugin = chunk5RSB5SEK_cjs.definePlugin({
6891
7072
  id: "user-profiles",
6892
7073
  version: "1.0.0",
6893
7074
  name: "User Profiles",
@@ -6925,8 +7106,8 @@ function renderPasswordResetEmail(resetLink, firstName) {
6925
7106
  async function setCsrfCookie(c, maxAge) {
6926
7107
  const secret = c.env?.JWT_SECRET || JWT_SECRET_FALLBACK;
6927
7108
  const isDev = c.env?.ENVIRONMENT === "development" || !c.env?.ENVIRONMENT;
6928
- const csrfToken = await chunkAAWNRBRB_cjs.generateCsrfToken(secret);
6929
- const cookieMaxAge = await chunkAAWNRBRB_cjs.getJwtExpirySecondsFromDb(c.env?.DB, c.env);
7109
+ const csrfToken = await chunk4SHNHNRP_cjs.generateCsrfToken(secret);
7110
+ const cookieMaxAge = await chunk4SHNHNRP_cjs.getJwtExpirySecondsFromDb(c.env?.DB, c.env);
6930
7111
  cookie.setCookie(c, "csrf_token", csrfToken, {
6931
7112
  httpOnly: false,
6932
7113
  secure: !isDev,
@@ -6948,10 +7129,12 @@ var authRoutes = new hono.Hono();
6948
7129
  authRoutes.get("/login", async (c) => {
6949
7130
  const error = c.req.query("error");
6950
7131
  const message = c.req.query("message");
7132
+ const redirect = c.req.query("redirect");
6951
7133
  const pageData = {
6952
7134
  error: error || void 0,
6953
7135
  message: message || void 0,
6954
- version: c.get("appVersion")
7136
+ version: c.get("appVersion"),
7137
+ redirect: redirect && redirect.startsWith("/") ? redirect : void 0
6955
7138
  };
6956
7139
  const db = c.env.DB;
6957
7140
  let demoLoginActive = false;
@@ -6964,9 +7147,9 @@ authRoutes.get("/login", async (c) => {
6964
7147
  });
6965
7148
  authRoutes.get("/register", async (c) => {
6966
7149
  const db = c.env.DB;
6967
- const isFirstUser = await chunkHIKBY7MS_cjs.isFirstUserRegistration(db);
7150
+ const isFirstUser = await chunkXWVDSM2L_cjs.isFirstUserRegistration(db);
6968
7151
  if (!isFirstUser) {
6969
- const registrationEnabled = await chunkHIKBY7MS_cjs.isRegistrationEnabled(db);
7152
+ const registrationEnabled = await chunkXWVDSM2L_cjs.isRegistrationEnabled(db);
6970
7153
  if (!registrationEnabled) {
6971
7154
  return c.redirect("/auth/login?error=Registration is currently disabled");
6972
7155
  }
@@ -6983,13 +7166,13 @@ var loginSchema = zod.z.object({
6983
7166
  });
6984
7167
  authRoutes.post(
6985
7168
  "/register",
6986
- chunkAAWNRBRB_cjs.rateLimit({ max: 30, windowMs: 60 * 1e3, keyPrefix: "register" }),
7169
+ chunk4SHNHNRP_cjs.rateLimit({ max: 30, windowMs: 60 * 1e3, keyPrefix: "register" }),
6987
7170
  async (c) => {
6988
7171
  try {
6989
7172
  const db = c.env.DB;
6990
- const isFirstUser = await chunkHIKBY7MS_cjs.isFirstUserRegistration(db);
7173
+ const isFirstUser = await chunkXWVDSM2L_cjs.isFirstUserRegistration(db);
6991
7174
  if (!isFirstUser) {
6992
- const registrationEnabled = await chunkHIKBY7MS_cjs.isRegistrationEnabled(db);
7175
+ const registrationEnabled = await chunkXWVDSM2L_cjs.isRegistrationEnabled(db);
6993
7176
  if (!registrationEnabled) {
6994
7177
  return c.json({ error: "Registration is currently disabled" }, 403);
6995
7178
  }
@@ -7000,7 +7183,7 @@ authRoutes.post(
7000
7183
  } catch (parseError) {
7001
7184
  return c.json({ error: "Invalid JSON in request body" }, 400);
7002
7185
  }
7003
- const validationSchema = await chunkHIKBY7MS_cjs.authValidationService.buildRegistrationSchema(db);
7186
+ const validationSchema = await chunkXWVDSM2L_cjs.authValidationService.buildRegistrationSchema(db);
7004
7187
  let validatedData;
7005
7188
  try {
7006
7189
  validatedData = await validationSchema.parseAsync(requestData);
@@ -7012,14 +7195,14 @@ authRoutes.post(
7012
7195
  }
7013
7196
  const email = validatedData.email;
7014
7197
  const password = validatedData.password;
7015
- const firstName = validatedData.firstName || chunkHIKBY7MS_cjs.authValidationService.generateDefaultValue("firstName", validatedData);
7016
- const lastName = validatedData.lastName || chunkHIKBY7MS_cjs.authValidationService.generateDefaultValue("lastName", validatedData);
7198
+ const firstName = validatedData.firstName || chunkXWVDSM2L_cjs.authValidationService.generateDefaultValue("firstName", validatedData);
7199
+ const lastName = validatedData.lastName || chunkXWVDSM2L_cjs.authValidationService.generateDefaultValue("lastName", validatedData);
7017
7200
  const normalizedEmail = email.toLowerCase();
7018
7201
  const existingUser = await db.prepare("SELECT id FROM auth_user WHERE email = ?").bind(normalizedEmail).first();
7019
7202
  if (existingUser) {
7020
7203
  return c.json({ error: "User with this email already exists" }, 400);
7021
7204
  }
7022
- const passwordHash = await chunkAAWNRBRB_cjs.AuthManager.hashPassword(password);
7205
+ const passwordHash = await chunk4SHNHNRP_cjs.AuthManager.hashPassword(password);
7023
7206
  const userId = crypto.randomUUID();
7024
7207
  const now = /* @__PURE__ */ new Date();
7025
7208
  const nowSec = Math.floor(now.getTime() / 1e3);
@@ -7052,8 +7235,8 @@ authRoutes.post(
7052
7235
  { user: { id: userId, email: normalizedEmail, role: "viewer" } },
7053
7236
  "fire-and-forget"
7054
7237
  );
7055
- const tokenTtl = await chunkAAWNRBRB_cjs.getJwtExpirySecondsFromDb(c.env.DB, c.env);
7056
- const token = await chunkAAWNRBRB_cjs.AuthManager.generateToken(userId, normalizedEmail, "viewer", c.env.JWT_SECRET, tokenTtl);
7238
+ const tokenTtl = await chunk4SHNHNRP_cjs.getJwtExpirySecondsFromDb(c.env.DB, c.env);
7239
+ const token = await chunk4SHNHNRP_cjs.AuthManager.generateToken(userId, normalizedEmail, "viewer", c.env.JWT_SECRET, tokenTtl);
7057
7240
  cookie.setCookie(c, "auth_token", token, {
7058
7241
  httpOnly: true,
7059
7242
  secure: true,
@@ -7085,7 +7268,7 @@ authRoutes.post(
7085
7268
  );
7086
7269
  authRoutes.post(
7087
7270
  "/login",
7088
- chunkAAWNRBRB_cjs.rateLimit({ max: 30, windowMs: 60 * 1e3, keyPrefix: "login" }),
7271
+ chunk4SHNHNRP_cjs.rateLimit({ max: 30, windowMs: 60 * 1e3, keyPrefix: "login" }),
7089
7272
  async (c) => {
7090
7273
  try {
7091
7274
  const body = await c.req.json();
@@ -7095,7 +7278,7 @@ authRoutes.post(
7095
7278
  }
7096
7279
  const { email, password } = validation.data;
7097
7280
  const normalizedEmail = email.toLowerCase();
7098
- const { createAuth } = await import('./config-ON6FNMYX.cjs');
7281
+ const { createAuth } = await import('./config-OCH7S4WK.cjs');
7099
7282
  const auth = createAuth(c.env);
7100
7283
  const baReq = new Request(new URL("/auth/sign-in/email", c.req.url).href, {
7101
7284
  method: "POST",
@@ -7117,6 +7300,20 @@ authRoutes.post(
7117
7300
  await setCsrfCookie(c);
7118
7301
  const baBody = await baRes.json();
7119
7302
  const user = baBody.user ?? {};
7303
+ const tokenTtl = await chunk4SHNHNRP_cjs.getJwtExpirySecondsFromDb(c.env.DB, c.env);
7304
+ const token = await chunk4SHNHNRP_cjs.AuthManager.generateToken(
7305
+ user.id,
7306
+ user.email,
7307
+ user.role ?? "viewer",
7308
+ c.env.JWT_SECRET,
7309
+ tokenTtl
7310
+ );
7311
+ cookie.setCookie(c, "auth_token", token, {
7312
+ httpOnly: true,
7313
+ secure: true,
7314
+ sameSite: "Strict",
7315
+ maxAge: tokenTtl
7316
+ });
7120
7317
  return c.json({
7121
7318
  user: {
7122
7319
  id: user.id,
@@ -7124,7 +7321,8 @@ authRoutes.post(
7124
7321
  firstName: user.name?.split(" ")[0] ?? "",
7125
7322
  lastName: user.name?.split(" ").slice(1).join(" ") ?? "",
7126
7323
  role: user.role ?? "viewer"
7127
- }
7324
+ },
7325
+ token
7128
7326
  });
7129
7327
  } catch (error) {
7130
7328
  console.error("Login error:", error);
@@ -7134,7 +7332,7 @@ authRoutes.post(
7134
7332
  );
7135
7333
  authRoutes.post("/logout", async (c) => {
7136
7334
  try {
7137
- const { createAuth } = await import('./config-ON6FNMYX.cjs');
7335
+ const { createAuth } = await import('./config-OCH7S4WK.cjs');
7138
7336
  const auth = createAuth(c.env);
7139
7337
  const baReq = new Request(new URL("/auth/sign-out", c.req.url).href, {
7140
7338
  method: "POST",
@@ -7150,7 +7348,7 @@ authRoutes.post("/logout", async (c) => {
7150
7348
  });
7151
7349
  authRoutes.get("/logout", async (c) => {
7152
7350
  try {
7153
- const { createAuth } = await import('./config-ON6FNMYX.cjs');
7351
+ const { createAuth } = await import('./config-OCH7S4WK.cjs');
7154
7352
  const auth = createAuth(c.env);
7155
7353
  const baReq = new Request(new URL("/auth/sign-out", c.req.url).href, {
7156
7354
  method: "POST",
@@ -7164,7 +7362,7 @@ authRoutes.get("/logout", async (c) => {
7164
7362
  clearCsrfCookie(c);
7165
7363
  return c.redirect("/auth/login?message=You have been logged out successfully");
7166
7364
  });
7167
- authRoutes.get("/me", chunkAAWNRBRB_cjs.requireAuth(), async (c) => {
7365
+ authRoutes.get("/me", chunk4SHNHNRP_cjs.requireAuth(), async (c) => {
7168
7366
  try {
7169
7367
  const user = c.get("user");
7170
7368
  if (!user) {
@@ -7184,7 +7382,7 @@ authRoutes.get("/me", chunkAAWNRBRB_cjs.requireAuth(), async (c) => {
7184
7382
  });
7185
7383
  authRoutes.post(
7186
7384
  "/refresh",
7187
- chunkAAWNRBRB_cjs.rateLimit({ max: 60, windowMs: 60 * 1e3, keyPrefix: "refresh" }),
7385
+ chunk4SHNHNRP_cjs.rateLimit({ max: 60, windowMs: 60 * 1e3, keyPrefix: "refresh" }),
7188
7386
  async (c) => {
7189
7387
  try {
7190
7388
  let token = c.req.header("Authorization")?.replace("Bearer ", "");
@@ -7193,8 +7391,8 @@ authRoutes.post(
7193
7391
  return c.json({ error: "Authentication required" }, 401);
7194
7392
  }
7195
7393
  const db = c.env.DB;
7196
- const grace = await chunkAAWNRBRB_cjs.getJwtRefreshGraceSecondsFromDb(db, c.env);
7197
- const payload = await chunkAAWNRBRB_cjs.AuthManager.verifyToken(token, c.env.JWT_SECRET, grace);
7394
+ const grace = await chunk4SHNHNRP_cjs.getJwtRefreshGraceSecondsFromDb(db, c.env);
7395
+ const payload = await chunk4SHNHNRP_cjs.AuthManager.verifyToken(token, c.env.JWT_SECRET, grace);
7198
7396
  if (!payload) {
7199
7397
  return c.json({ error: "Invalid or expired token" }, 401);
7200
7398
  }
@@ -7202,8 +7400,8 @@ authRoutes.post(
7202
7400
  if (!row || !row.is_active) {
7203
7401
  return c.json({ error: "User is not active" }, 401);
7204
7402
  }
7205
- const tokenTtl = await chunkAAWNRBRB_cjs.getJwtExpirySecondsFromDb(db, c.env);
7206
- const newToken = await chunkAAWNRBRB_cjs.AuthManager.generateToken(row.id, row.email, row.role, c.env.JWT_SECRET, tokenTtl);
7403
+ const tokenTtl = await chunk4SHNHNRP_cjs.getJwtExpirySecondsFromDb(db, c.env);
7404
+ const newToken = await chunk4SHNHNRP_cjs.AuthManager.generateToken(row.id, row.email, row.role, c.env.JWT_SECRET, tokenTtl);
7207
7405
  cookie.setCookie(c, "auth_token", newToken, {
7208
7406
  httpOnly: true,
7209
7407
  secure: true,
@@ -7223,13 +7421,13 @@ authRoutes.post(
7223
7421
  );
7224
7422
  authRoutes.post(
7225
7423
  "/register/form",
7226
- chunkAAWNRBRB_cjs.rateLimit({ max: 30, windowMs: 60 * 1e3, keyPrefix: "register" }),
7424
+ chunk4SHNHNRP_cjs.rateLimit({ max: 30, windowMs: 60 * 1e3, keyPrefix: "register" }),
7227
7425
  async (c) => {
7228
7426
  try {
7229
7427
  const db = c.env.DB;
7230
- const isFirstUser = await chunkHIKBY7MS_cjs.isFirstUserRegistration(db);
7428
+ const isFirstUser = await chunkXWVDSM2L_cjs.isFirstUserRegistration(db);
7231
7429
  if (!isFirstUser) {
7232
- const registrationEnabled = await chunkHIKBY7MS_cjs.isRegistrationEnabled(db);
7430
+ const registrationEnabled = await chunkXWVDSM2L_cjs.isRegistrationEnabled(db);
7233
7431
  if (!registrationEnabled) {
7234
7432
  return c.html(html.html`
7235
7433
  <div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded">
@@ -7247,7 +7445,7 @@ authRoutes.post(
7247
7445
  };
7248
7446
  const normalizedEmail = requestData.email?.toLowerCase();
7249
7447
  requestData.email = normalizedEmail;
7250
- const validationSchema = await chunkHIKBY7MS_cjs.authValidationService.buildRegistrationSchema(db);
7448
+ const validationSchema = await chunkXWVDSM2L_cjs.authValidationService.buildRegistrationSchema(db);
7251
7449
  const validation = await validationSchema.safeParseAsync(requestData);
7252
7450
  if (!validation.success) {
7253
7451
  return c.html(html.html`
@@ -7258,8 +7456,8 @@ authRoutes.post(
7258
7456
  }
7259
7457
  const validatedData = validation.data;
7260
7458
  const password = validatedData.password;
7261
- const firstName = validatedData.firstName || chunkHIKBY7MS_cjs.authValidationService.generateDefaultValue("firstName", validatedData);
7262
- const lastName = validatedData.lastName || chunkHIKBY7MS_cjs.authValidationService.generateDefaultValue("lastName", validatedData);
7459
+ const firstName = validatedData.firstName || chunkXWVDSM2L_cjs.authValidationService.generateDefaultValue("firstName", validatedData);
7460
+ const lastName = validatedData.lastName || chunkXWVDSM2L_cjs.authValidationService.generateDefaultValue("lastName", validatedData);
7263
7461
  const existingUser = await db.prepare("SELECT id FROM auth_user WHERE email = ?").bind(normalizedEmail).first();
7264
7462
  if (existingUser) {
7265
7463
  return c.html(html.html`
@@ -7268,7 +7466,7 @@ authRoutes.post(
7268
7466
  </div>
7269
7467
  `);
7270
7468
  }
7271
- const passwordHash = await chunkAAWNRBRB_cjs.AuthManager.hashPassword(password);
7469
+ const passwordHash = await chunk4SHNHNRP_cjs.AuthManager.hashPassword(password);
7272
7470
  const role = isFirstUser ? "admin" : "viewer";
7273
7471
  const userId = crypto.randomUUID();
7274
7472
  const now = /* @__PURE__ */ new Date();
@@ -7302,7 +7500,7 @@ authRoutes.post(
7302
7500
  await saveCustomData(db, userId, sanitized);
7303
7501
  }
7304
7502
  }
7305
- const rbacService = new chunk2CB4KY7I_cjs.RbacService(db);
7503
+ const rbacService = new chunkLTZ5WYOK_cjs.RbacService(db);
7306
7504
  await rbacService.addUserRoleByName(userId, role);
7307
7505
  dispatchHookEvent(
7308
7506
  c,
@@ -7310,8 +7508,8 @@ authRoutes.post(
7310
7508
  { user: { id: userId, email: normalizedEmail, role } },
7311
7509
  "fire-and-forget"
7312
7510
  );
7313
- const tokenTtl = await chunkAAWNRBRB_cjs.getJwtExpirySecondsFromDb(c.env.DB, c.env);
7314
- const token = await chunkAAWNRBRB_cjs.AuthManager.generateToken(userId, normalizedEmail, role, c.env.JWT_SECRET, tokenTtl);
7511
+ const tokenTtl = await chunk4SHNHNRP_cjs.getJwtExpirySecondsFromDb(c.env.DB, c.env);
7512
+ const token = await chunk4SHNHNRP_cjs.AuthManager.generateToken(userId, normalizedEmail, role, c.env.JWT_SECRET, tokenTtl);
7315
7513
  cookie.setCookie(c, "auth_token", token, {
7316
7514
  httpOnly: true,
7317
7515
  secure: false,
@@ -7343,7 +7541,7 @@ authRoutes.post(
7343
7541
  );
7344
7542
  authRoutes.post(
7345
7543
  "/login/form",
7346
- chunkAAWNRBRB_cjs.rateLimit({ max: 30, windowMs: 60 * 1e3, keyPrefix: "login" }),
7544
+ chunk4SHNHNRP_cjs.rateLimit({ max: 30, windowMs: 60 * 1e3, keyPrefix: "login" }),
7347
7545
  async (c) => {
7348
7546
  try {
7349
7547
  const formData = await c.req.formData();
@@ -7357,7 +7555,7 @@ authRoutes.post(
7357
7555
  </div>
7358
7556
  `);
7359
7557
  }
7360
- const { createAuth } = await import('./config-ON6FNMYX.cjs');
7558
+ const { createAuth } = await import('./config-OCH7S4WK.cjs');
7361
7559
  const auth = createAuth(c.env);
7362
7560
  const baReq = new Request(new URL("/auth/sign-in/email", c.req.url).href, {
7363
7561
  method: "POST",
@@ -7381,6 +7579,8 @@ authRoutes.post(
7381
7579
  }
7382
7580
  }
7383
7581
  await setCsrfCookie(c);
7582
+ const rawRedirect = c.req.query("redirect");
7583
+ const redirectUrl = rawRedirect && rawRedirect.startsWith("/") ? rawRedirect : "/admin/content";
7384
7584
  return c.html(html.html`
7385
7585
  <div id="form-response">
7386
7586
  <div class="rounded-lg bg-green-100 dark:bg-lime-500/10 p-4 ring-1 ring-green-400 dark:ring-lime-500/20">
@@ -7393,7 +7593,7 @@ authRoutes.post(
7393
7593
  </div>
7394
7594
  </div>
7395
7595
  <script>
7396
- setTimeout(() => { window.location.href = '/admin/content'; }, 500);
7596
+ setTimeout(() => { window.location.href = '${redirectUrl}'; }, 500);
7397
7597
  </script>
7398
7598
  </div>
7399
7599
  </div>
@@ -7410,14 +7610,14 @@ authRoutes.post(
7410
7610
  );
7411
7611
  authRoutes.post(
7412
7612
  "/seed-admin",
7413
- chunkAAWNRBRB_cjs.rateLimit({ max: 10, windowMs: 60 * 1e3, keyPrefix: "seed-admin" }),
7613
+ chunk4SHNHNRP_cjs.rateLimit({ max: 10, windowMs: 60 * 1e3, keyPrefix: "seed-admin" }),
7414
7614
  async (c) => {
7415
7615
  try {
7416
7616
  const db = c.env.DB;
7417
- const rbac = new chunk2CB4KY7I_cjs.RbacService(db);
7617
+ const rbac = new chunkLTZ5WYOK_cjs.RbacService(db);
7418
7618
  const results = [];
7419
7619
  const upsertSeedUser = async (opts) => {
7420
- const passwordHash = await chunkAAWNRBRB_cjs.AuthManager.hashPassword(opts.password);
7620
+ const passwordHash = await chunk4SHNHNRP_cjs.AuthManager.hashPassword(opts.password);
7421
7621
  const nowMs = Date.now();
7422
7622
  const nowSec = Math.floor(nowMs / 1e3);
7423
7623
  const existing = await db.prepare("SELECT id FROM auth_user WHERE email = ?").bind(opts.email).first();
@@ -7642,7 +7842,7 @@ authRoutes.post("/accept-invitation", async (c) => {
7642
7842
  if (invitationAge > maxAge) {
7643
7843
  return c.json({ error: "Invitation has expired" }, 400);
7644
7844
  }
7645
- const passwordHash = await chunkAAWNRBRB_cjs.AuthManager.hashPassword(password);
7845
+ const passwordHash = await chunk4SHNHNRP_cjs.AuthManager.hashPassword(password);
7646
7846
  const updateStmt = db.prepare(`
7647
7847
  UPDATE auth_user SET
7648
7848
  password_hash = ?,
@@ -7659,8 +7859,8 @@ authRoutes.post("/accept-invitation", async (c) => {
7659
7859
  Date.now(),
7660
7860
  invitedUser.id
7661
7861
  ).run();
7662
- const tokenTtl = await chunkAAWNRBRB_cjs.getJwtExpirySecondsFromDb(c.env.DB, c.env);
7663
- const authToken = await chunkAAWNRBRB_cjs.AuthManager.generateToken(invitedUser.id, invitedUser.email, invitedUser.role, c.env.JWT_SECRET, tokenTtl);
7862
+ const tokenTtl = await chunk4SHNHNRP_cjs.getJwtExpirySecondsFromDb(c.env.DB, c.env);
7863
+ const authToken = await chunk4SHNHNRP_cjs.AuthManager.generateToken(invitedUser.id, invitedUser.email, invitedUser.role, c.env.JWT_SECRET, tokenTtl);
7664
7864
  cookie.setCookie(c, "auth_token", authToken, {
7665
7865
  httpOnly: true,
7666
7866
  secure: true,
@@ -7676,7 +7876,7 @@ authRoutes.post("/accept-invitation", async (c) => {
7676
7876
  });
7677
7877
  authRoutes.post(
7678
7878
  "/request-password-reset",
7679
- chunkAAWNRBRB_cjs.rateLimit({ max: 3, windowMs: 15 * 60 * 1e3, keyPrefix: "password-reset" }),
7879
+ chunk4SHNHNRP_cjs.rateLimit({ max: 3, windowMs: 15 * 60 * 1e3, keyPrefix: "password-reset" }),
7680
7880
  async (c) => {
7681
7881
  try {
7682
7882
  const formData = await c.req.formData();
@@ -7913,7 +8113,7 @@ authRoutes.post("/reset-password", async (c) => {
7913
8113
  if (Date.now() > user.password_reset_expires) {
7914
8114
  return c.json({ error: "Reset token has expired" }, 400);
7915
8115
  }
7916
- const newPasswordHash = await chunkAAWNRBRB_cjs.AuthManager.hashPassword(password);
8116
+ const newPasswordHash = await chunk4SHNHNRP_cjs.AuthManager.hashPassword(password);
7917
8117
  try {
7918
8118
  const historyStmt = db.prepare(`
7919
8119
  INSERT INTO auth_password_history (id, user_id, password_hash, created_at)
@@ -8127,7 +8327,7 @@ app.post("/test-seed-defaults", async (c) => {
8127
8327
  var test_cleanup_default = app;
8128
8328
 
8129
8329
  // src/plugins/available/easy-mdx/index.ts
8130
- chunkXW56B23A_cjs.definePlugin({
8330
+ chunk5RSB5SEK_cjs.definePlugin({
8131
8331
  id: "easy-mdx",
8132
8332
  version: "1.0.0",
8133
8333
  name: "EasyMDE Markdown Editor",
@@ -8327,7 +8527,7 @@ function getMDXEditorInitScript(config) {
8327
8527
  }
8328
8528
 
8329
8529
  // src/plugins/available/tinymce-plugin/index.ts
8330
- chunkXW56B23A_cjs.definePlugin({
8530
+ chunk5RSB5SEK_cjs.definePlugin({
8331
8531
  id: "tinymce-plugin",
8332
8532
  version: "1.0.0",
8333
8533
  name: "TinyMCE",
@@ -8597,7 +8797,7 @@ function getQuillCDN(version = "2.0.2") {
8597
8797
  </style>
8598
8798
  `;
8599
8799
  }
8600
- chunkXW56B23A_cjs.definePlugin({
8800
+ chunk5RSB5SEK_cjs.definePlugin({
8601
8801
  id: "quill-editor",
8602
8802
  version: "1.0.0",
8603
8803
  name: "Quill Editor",
@@ -8609,7 +8809,7 @@ chunkXW56B23A_cjs.definePlugin({
8609
8809
  });
8610
8810
 
8611
8811
  // src/templates/pages/admin-content-form.template.ts
8612
- chunkNAVPFIG5_cjs.init_admin_layout_catalyst_template();
8812
+ chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
8613
8813
  function renderContentFormPage(data, opts) {
8614
8814
  const isEdit = data.isEdit || !!data.id;
8615
8815
  const title = isEdit ? `Edit: ${data.title || "Content"}` : `New ${data.collection.display_name}`;
@@ -8691,8 +8891,8 @@ function renderContentFormPage(data, opts) {
8691
8891
  <!-- Form Content -->
8692
8892
  <div class="px-6 py-6">
8693
8893
  <div id="form-messages">
8694
- ${data.error ? chunkMVIZJOO5_cjs.renderAlert({ type: "error", message: data.error, dismissible: true }) : ""}
8695
- ${data.success ? chunkMVIZJOO5_cjs.renderAlert({ type: "success", message: data.success, dismissible: true }) : ""}
8894
+ ${data.error ? chunkPXNTCCPE_cjs.renderAlert({ type: "error", message: data.error, dismissible: true }) : ""}
8895
+ ${data.success ? chunkPXNTCCPE_cjs.renderAlert({ type: "success", message: data.success, dismissible: true }) : ""}
8696
8896
  </div>
8697
8897
 
8698
8898
  <div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
@@ -8928,7 +9128,7 @@ function renderContentFormPage(data, opts) {
8928
9128
  </div>
8929
9129
 
8930
9130
  <!-- Confirmation Dialogs -->
8931
- ${chunkMVIZJOO5_cjs.renderConfirmationDialog({
9131
+ ${chunkPXNTCCPE_cjs.renderConfirmationDialog({
8932
9132
  id: "duplicate-content-confirm",
8933
9133
  title: "Duplicate Content",
8934
9134
  message: "Create a copy of this content?",
@@ -8939,7 +9139,7 @@ function renderContentFormPage(data, opts) {
8939
9139
  onConfirm: "performDuplicateContent()"
8940
9140
  })}
8941
9141
 
8942
- ${chunkMVIZJOO5_cjs.renderConfirmationDialog({
9142
+ ${chunkPXNTCCPE_cjs.renderConfirmationDialog({
8943
9143
  id: "delete-content-confirm",
8944
9144
  title: "Delete Content",
8945
9145
  message: "Are you sure you want to delete this content? This action cannot be undone.",
@@ -8950,7 +9150,7 @@ function renderContentFormPage(data, opts) {
8950
9150
  onConfirm: `performDeleteContent('${data.id}')`
8951
9151
  })}
8952
9152
 
8953
- ${chunkMVIZJOO5_cjs.renderConfirmationDialog({
9153
+ ${chunkPXNTCCPE_cjs.renderConfirmationDialog({
8954
9154
  id: "delete-repeater-item-confirm",
8955
9155
  title: "Delete Item",
8956
9156
  message: "Are you sure you want to delete this item? This action cannot be undone.",
@@ -8961,7 +9161,7 @@ function renderContentFormPage(data, opts) {
8961
9161
  onConfirm: "performRepeaterDelete()"
8962
9162
  })}
8963
9163
 
8964
- ${chunkMVIZJOO5_cjs.renderConfirmationDialog({
9164
+ ${chunkPXNTCCPE_cjs.renderConfirmationDialog({
8965
9165
  id: "delete-block-confirm",
8966
9166
  title: "Delete Block",
8967
9167
  message: "Are you sure you want to delete this block? This action cannot be undone.",
@@ -8972,7 +9172,7 @@ function renderContentFormPage(data, opts) {
8972
9172
  onConfirm: "performRepeaterDelete()"
8973
9173
  })}
8974
9174
 
8975
- ${chunkMVIZJOO5_cjs.getConfirmationDialogScript()}
9175
+ ${chunkPXNTCCPE_cjs.getConfirmationDialogScript()}
8976
9176
 
8977
9177
  ${data.lexicalEnabled ? getLexicalStyles() : "<!-- Lexical plugin not active -->"}
8978
9178
 
@@ -10058,11 +10258,11 @@ function renderContentFormPage(data, opts) {
10058
10258
  content: pageContent,
10059
10259
  version: data.version
10060
10260
  };
10061
- return chunkNAVPFIG5_cjs.renderAdminLayoutCatalyst(layoutData);
10261
+ return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
10062
10262
  }
10063
10263
 
10064
10264
  // src/templates/pages/admin-content-list.template.ts
10065
- chunkNAVPFIG5_cjs.init_admin_layout_catalyst_template();
10265
+ chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
10066
10266
  function renderContentListPage(data) {
10067
10267
  const urlParams = new URLSearchParams();
10068
10268
  if (data.modelName && data.modelName !== "all") urlParams.set("model", data.modelName);
@@ -10496,8 +10696,8 @@ function renderContentListPage(data) {
10496
10696
 
10497
10697
  <!-- Content List -->
10498
10698
  <div id="content-list">
10499
- ${chunkMVIZJOO5_cjs.renderTable(tableData)}
10500
- ${chunkMVIZJOO5_cjs.renderPagination(paginationData)}
10699
+ ${chunkPXNTCCPE_cjs.renderTable(tableData)}
10700
+ ${chunkPXNTCCPE_cjs.renderPagination(paginationData)}
10501
10701
  </div>
10502
10702
 
10503
10703
  </div>
@@ -10707,7 +10907,7 @@ function renderContentListPage(data) {
10707
10907
  </script>
10708
10908
 
10709
10909
  <!-- Confirmation Dialog for Bulk Actions -->
10710
- ${chunkMVIZJOO5_cjs.renderConfirmationDialog({
10910
+ ${chunkPXNTCCPE_cjs.renderConfirmationDialog({
10711
10911
  id: "bulk-action-confirm",
10712
10912
  title: "Confirm Bulk Action",
10713
10913
  message: "Are you sure you want to perform this action? This operation will affect multiple items.",
@@ -10719,7 +10919,7 @@ function renderContentListPage(data) {
10719
10919
  })}
10720
10920
 
10721
10921
  <!-- Confirmation Dialog Script -->
10722
- ${chunkMVIZJOO5_cjs.getConfirmationDialogScript()}
10922
+ ${chunkPXNTCCPE_cjs.getConfirmationDialogScript()}
10723
10923
 
10724
10924
  <!-- Advanced Search Modal -->
10725
10925
  <div id="advancedSearchModal" class="hidden fixed inset-0 z-50 overflow-y-auto" aria-labelledby="modal-title" role="dialog" aria-modal="true">
@@ -11016,7 +11216,7 @@ function renderContentListPage(data) {
11016
11216
  version: data.version,
11017
11217
  content: pageContent
11018
11218
  };
11019
- return chunkNAVPFIG5_cjs.renderAdminLayoutCatalyst(layoutData);
11219
+ return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
11020
11220
  }
11021
11221
 
11022
11222
  // src/routes/admin-content-field-types.ts
@@ -11171,7 +11371,7 @@ function extractFieldData(fields, formData, options = {}) {
11171
11371
  }
11172
11372
  return { data, errors };
11173
11373
  }
11174
- adminContentRoutes.use("*", chunkAAWNRBRB_cjs.requireAuth());
11374
+ adminContentRoutes.use("*", chunk4SHNHNRP_cjs.requireAuth());
11175
11375
  async function getCollectionFields(db, collectionId) {
11176
11376
  console.log(`[getCollectionFields] Loading fields for collection: ${collectionId}`);
11177
11377
  const collectionStmt = db.prepare("SELECT schema, queryable_fields FROM document_types WHERE id = ?");
@@ -11198,7 +11398,7 @@ async function getCollectionFields(db, collectionId) {
11198
11398
  };
11199
11399
  });
11200
11400
  }
11201
- const codeCollections2 = await chunkQAYFOER6_cjs.loadCollectionConfigs();
11401
+ const codeCollections2 = await chunk5ARIHAGN_cjs.loadCollectionConfigs();
11202
11402
  const codeMatch = codeCollections2.find((c) => c.name === collectionId);
11203
11403
  if (codeMatch && codeMatch.schema?.properties) {
11204
11404
  console.log(`[getCollectionFields] DB doc type has no properties \u2014 using code collection schema`);
@@ -11230,7 +11430,7 @@ async function getCollectionFields(db, collectionId) {
11230
11430
  }
11231
11431
  }
11232
11432
  console.log(`[getCollectionFields] Not in database, checking code collections`);
11233
- const codeCollections = await chunkQAYFOER6_cjs.loadCollectionConfigs();
11433
+ const codeCollections = await chunk5ARIHAGN_cjs.loadCollectionConfigs();
11234
11434
  console.log(`[getCollectionFields] Found ${codeCollections.length} code collections`);
11235
11435
  const codeCollection = codeCollections.find((c) => c.name === collectionId);
11236
11436
  if (codeCollection && codeCollection.schema) {
@@ -11266,7 +11466,7 @@ async function getCollectionFields(db, collectionId) {
11266
11466
  }
11267
11467
  async function getCollection(db, collectionId) {
11268
11468
  console.log(`[getCollection] Loading collection by ID: ${collectionId}`);
11269
- const cache = chunkBDDABDAB_cjs.getCacheService(chunkBDDABDAB_cjs.CACHE_CONFIGS.collection);
11469
+ const cache = chunk36Z3AKX3_cjs.getCacheService(chunk36Z3AKX3_cjs.CACHE_CONFIGS.collection);
11270
11470
  return cache.getOrSet(
11271
11471
  cache.generateKey("collection", collectionId),
11272
11472
  async () => {
@@ -11284,7 +11484,7 @@ async function getCollection(db, collectionId) {
11284
11484
  };
11285
11485
  }
11286
11486
  console.log(`[getCollection] Not in database, checking code collections`);
11287
- const codeCollections = await chunkQAYFOER6_cjs.loadCollectionConfigs();
11487
+ const codeCollections = await chunk5ARIHAGN_cjs.loadCollectionConfigs();
11288
11488
  const codeCollection = codeCollections.find((c) => c.name === collectionId);
11289
11489
  if (codeCollection) {
11290
11490
  console.log(`[getCollection] Found code collection: ${collectionId}`);
@@ -11303,7 +11503,7 @@ async function getCollection(db, collectionId) {
11303
11503
  }
11304
11504
  async function getDocBackingType(db, collectionName) {
11305
11505
  if (!collectionName) return null;
11306
- const dt = await new chunkAAWNRBRB_cjs.DocumentTypeRegistry(db).findById(collectionName);
11506
+ const dt = await new chunk4SHNHNRP_cjs.DocumentTypeRegistry(db).findById(collectionName);
11307
11507
  return dt && dt.isActive ? dt : null;
11308
11508
  }
11309
11509
  async function getCollectionByName(db, name) {
@@ -11320,7 +11520,7 @@ async function getCollectionByName(db, name) {
11320
11520
  };
11321
11521
  }
11322
11522
  console.log(`[getCollectionByName] Not in database, checking code collections`);
11323
- const codeCollections = await chunkQAYFOER6_cjs.loadCollectionConfigs();
11523
+ const codeCollections = await chunk5ARIHAGN_cjs.loadCollectionConfigs();
11324
11524
  const codeCollection = codeCollections.find((c) => c.name === name);
11325
11525
  if (codeCollection) {
11326
11526
  console.log(`[getCollectionByName] Found code collection: ${name}`);
@@ -11336,7 +11536,7 @@ async function getCollectionByName(db, name) {
11336
11536
  return null;
11337
11537
  }
11338
11538
  async function loadContentEditorFlags(db) {
11339
- const flags = { workflowEnabled: await chunkAAWNRBRB_cjs.isPluginActive(db, "workflow") };
11539
+ const flags = { workflowEnabled: await chunk4SHNHNRP_cjs.isPluginActive(db, "workflow") };
11340
11540
  const editors = [
11341
11541
  ["tinymce-plugin", "tinymce"],
11342
11542
  ["quill-editor", "quill"],
@@ -11344,10 +11544,10 @@ async function loadContentEditorFlags(db) {
11344
11544
  ["lexical-editor", "lexical"]
11345
11545
  ];
11346
11546
  for (const [plugin, key] of editors) {
11347
- const enabled = await chunkAAWNRBRB_cjs.isPluginActive(db, plugin);
11547
+ const enabled = await chunk4SHNHNRP_cjs.isPluginActive(db, plugin);
11348
11548
  flags[`${key}Enabled`] = enabled;
11349
11549
  if (enabled) {
11350
- const ps = new chunkQAYFOER6_cjs.PluginService(db);
11550
+ const ps = new chunk5ARIHAGN_cjs.PluginService(db);
11351
11551
  const p = await ps.getPlugin(plugin);
11352
11552
  flags[`${key}Settings`] = p?.settings;
11353
11553
  }
@@ -11355,7 +11555,7 @@ async function loadContentEditorFlags(db) {
11355
11555
  return flags;
11356
11556
  }
11357
11557
  function makeDocService(db, docType, tenantId) {
11358
- return new chunk2CB4KY7I_cjs.DocumentsService(db, {
11558
+ return new chunkLTZ5WYOK_cjs.DocumentsService(db, {
11359
11559
  queryableFields: docType.queryableFields ?? [],
11360
11560
  typeSchemaVersion: docType.schemaVersion ?? 1,
11361
11561
  maxVersionsPerRoot: docType.settings?.maxVersionsPerRoot ?? 50,
@@ -11383,9 +11583,9 @@ adminContentRoutes.get("/", async (c) => {
11383
11583
  const offset = (page - 1) * limit;
11384
11584
  const collectionsStmt = db.prepare("SELECT id, name, display_name FROM document_types WHERE is_active = 1 ORDER BY display_name");
11385
11585
  const { results: collectionsResults } = await collectionsStmt.all();
11386
- const codeCollections = await chunkQAYFOER6_cjs.loadCollectionConfigs();
11586
+ const codeCollections = await chunk5ARIHAGN_cjs.loadCollectionConfigs();
11387
11587
  const codeCollectionMap = new Map(codeCollections.map((c2) => [c2.name, c2]));
11388
- const docTypeRegistry = new chunkAAWNRBRB_cjs.DocumentTypeRegistry(db);
11588
+ const docTypeRegistry = new chunk4SHNHNRP_cjs.DocumentTypeRegistry(db);
11389
11589
  const docTypes = (await docTypeRegistry.findAll()).filter((dt) => !dt.settings?.internal && !dt.isAuth);
11390
11590
  const visibleTypeIds = new Set(docTypes.map((dt) => dt.id));
11391
11591
  const allCollections = [
@@ -11397,7 +11597,7 @@ adminContentRoutes.get("/", async (c) => {
11397
11597
  ...allCollections.map((c2) => ({ name: c2.name, displayName: c2.displayName })),
11398
11598
  ...docTypes.filter((dt) => !collectionNames.has(dt.id)).map((dt) => ({ name: `doc:${dt.id}`, displayName: dt.displayName }))
11399
11599
  ];
11400
- const newContentCollections = await chunkQAYFOER6_cjs.getVisibleCollections(db);
11600
+ const newContentCollections = await chunk5ARIHAGN_cjs.getVisibleCollections(db);
11401
11601
  const docBackedCollection = !modelName.startsWith("doc:") && modelName !== "all" ? docTypes.find((dt) => dt.id === modelName) : void 0;
11402
11602
  const isDocModel = modelName.startsWith("doc:") || !!docBackedCollection;
11403
11603
  if (isDocModel) {
@@ -11674,9 +11874,9 @@ adminContentRoutes.get("/new", async (c) => {
11674
11874
  const collectionsStmt = db2.prepare("SELECT id, name, display_name, description FROM document_types WHERE is_active = 1 ORDER BY display_name");
11675
11875
  const { results } = await collectionsStmt.all();
11676
11876
  const visibleTypeIds = new Set(
11677
- (await new chunkAAWNRBRB_cjs.DocumentTypeRegistry(db2).findAll()).filter((dt) => !dt.settings?.internal && !dt.isAuth).map((dt) => dt.id)
11877
+ (await new chunk4SHNHNRP_cjs.DocumentTypeRegistry(db2).findAll()).filter((dt) => !dt.settings?.internal && !dt.isAuth).map((dt) => dt.id)
11678
11878
  );
11679
- const codeCollections = await chunkQAYFOER6_cjs.loadCollectionConfigs();
11879
+ const codeCollections = await chunk5ARIHAGN_cjs.loadCollectionConfigs();
11680
11880
  const dbCollectionNames = new Set((results || []).map((r) => r.name));
11681
11881
  const allCollections = [
11682
11882
  ...codeCollections.filter((c2) => !dbCollectionNames.has(c2.name)).map((c2) => ({
@@ -11742,32 +11942,32 @@ adminContentRoutes.get("/new", async (c) => {
11742
11942
  return c.html(renderContentFormPage(formData2));
11743
11943
  }
11744
11944
  const fields = await getCollectionFields(db, collection.id);
11745
- const workflowEnabled = await chunkAAWNRBRB_cjs.isPluginActive(db, "workflow");
11746
- const tinymceEnabled = await chunkAAWNRBRB_cjs.isPluginActive(db, "tinymce-plugin");
11945
+ const workflowEnabled = await chunk4SHNHNRP_cjs.isPluginActive(db, "workflow");
11946
+ const tinymceEnabled = await chunk4SHNHNRP_cjs.isPluginActive(db, "tinymce-plugin");
11747
11947
  let tinymceSettings;
11748
11948
  if (tinymceEnabled) {
11749
- const pluginService = new chunkQAYFOER6_cjs.PluginService(db);
11949
+ const pluginService = new chunk5ARIHAGN_cjs.PluginService(db);
11750
11950
  const tinymcePlugin2 = await pluginService.getPlugin("tinymce-plugin");
11751
11951
  tinymceSettings = tinymcePlugin2?.settings;
11752
11952
  }
11753
- const quillEnabled = await chunkAAWNRBRB_cjs.isPluginActive(db, "quill-editor");
11953
+ const quillEnabled = await chunk4SHNHNRP_cjs.isPluginActive(db, "quill-editor");
11754
11954
  let quillSettings;
11755
11955
  if (quillEnabled) {
11756
- const pluginService = new chunkQAYFOER6_cjs.PluginService(db);
11956
+ const pluginService = new chunk5ARIHAGN_cjs.PluginService(db);
11757
11957
  const quillPlugin = await pluginService.getPlugin("quill-editor");
11758
11958
  quillSettings = quillPlugin?.settings;
11759
11959
  }
11760
- const mdxeditorEnabled = await chunkAAWNRBRB_cjs.isPluginActive(db, "easy-mdx");
11960
+ const mdxeditorEnabled = await chunk4SHNHNRP_cjs.isPluginActive(db, "easy-mdx");
11761
11961
  let mdxeditorSettings;
11762
11962
  if (mdxeditorEnabled) {
11763
- const pluginService = new chunkQAYFOER6_cjs.PluginService(db);
11963
+ const pluginService = new chunk5ARIHAGN_cjs.PluginService(db);
11764
11964
  const mdxeditorPlugin = await pluginService.getPlugin("easy-mdx");
11765
11965
  mdxeditorSettings = mdxeditorPlugin?.settings;
11766
11966
  }
11767
- const lexicalEnabled = await chunkAAWNRBRB_cjs.isPluginActive(db, "lexical-editor");
11967
+ const lexicalEnabled = await chunk4SHNHNRP_cjs.isPluginActive(db, "lexical-editor");
11768
11968
  let lexicalSettings;
11769
11969
  if (lexicalEnabled) {
11770
- const pluginService = new chunkQAYFOER6_cjs.PluginService(db);
11970
+ const pluginService = new chunk5ARIHAGN_cjs.PluginService(db);
11771
11971
  const lexicalPlugin = await pluginService.getPlugin("lexical-editor");
11772
11972
  lexicalSettings = lexicalPlugin?.settings;
11773
11973
  }
@@ -11858,7 +12058,7 @@ adminContentRoutes.get("/:id/edit", async (c) => {
11858
12058
  } : void 0
11859
12059
  };
11860
12060
  return c.html(renderContentFormPage(notFoundData));
11861
- const cache = chunkBDDABDAB_cjs.getCacheService(chunkBDDABDAB_cjs.CACHE_CONFIGS.content);
12061
+ const cache = chunk36Z3AKX3_cjs.getCacheService(chunk36Z3AKX3_cjs.CACHE_CONFIGS.content);
11862
12062
  const content = await cache.getOrSet(
11863
12063
  cache.generateKey("content", id),
11864
12064
  async () => {
@@ -11895,32 +12095,32 @@ adminContentRoutes.get("/:id/edit", async (c) => {
11895
12095
  };
11896
12096
  const fields = await getCollectionFields(db, content.collection_id);
11897
12097
  const contentData = content.data ? JSON.parse(content.data) : {};
11898
- const workflowEnabled = await chunkAAWNRBRB_cjs.isPluginActive(db, "workflow");
11899
- const tinymceEnabled = await chunkAAWNRBRB_cjs.isPluginActive(db, "tinymce-plugin");
12098
+ const workflowEnabled = await chunk4SHNHNRP_cjs.isPluginActive(db, "workflow");
12099
+ const tinymceEnabled = await chunk4SHNHNRP_cjs.isPluginActive(db, "tinymce-plugin");
11900
12100
  let tinymceSettings;
11901
12101
  if (tinymceEnabled) {
11902
- const pluginService = new chunkQAYFOER6_cjs.PluginService(db);
12102
+ const pluginService = new chunk5ARIHAGN_cjs.PluginService(db);
11903
12103
  const tinymcePlugin2 = await pluginService.getPlugin("tinymce-plugin");
11904
12104
  tinymceSettings = tinymcePlugin2?.settings;
11905
12105
  }
11906
- const quillEnabled = await chunkAAWNRBRB_cjs.isPluginActive(db, "quill-editor");
12106
+ const quillEnabled = await chunk4SHNHNRP_cjs.isPluginActive(db, "quill-editor");
11907
12107
  let quillSettings;
11908
12108
  if (quillEnabled) {
11909
- const pluginService = new chunkQAYFOER6_cjs.PluginService(db);
12109
+ const pluginService = new chunk5ARIHAGN_cjs.PluginService(db);
11910
12110
  const quillPlugin = await pluginService.getPlugin("quill-editor");
11911
12111
  quillSettings = quillPlugin?.settings;
11912
12112
  }
11913
- const mdxeditorEnabled = await chunkAAWNRBRB_cjs.isPluginActive(db, "easy-mdx");
12113
+ const mdxeditorEnabled = await chunk4SHNHNRP_cjs.isPluginActive(db, "easy-mdx");
11914
12114
  let mdxeditorSettings;
11915
12115
  if (mdxeditorEnabled) {
11916
- const pluginService = new chunkQAYFOER6_cjs.PluginService(db);
12116
+ const pluginService = new chunk5ARIHAGN_cjs.PluginService(db);
11917
12117
  const mdxeditorPlugin = await pluginService.getPlugin("easy-mdx");
11918
12118
  mdxeditorSettings = mdxeditorPlugin?.settings;
11919
12119
  }
11920
- const lexicalEnabled = await chunkAAWNRBRB_cjs.isPluginActive(db, "lexical-editor");
12120
+ const lexicalEnabled = await chunk4SHNHNRP_cjs.isPluginActive(db, "lexical-editor");
11921
12121
  let lexicalSettings;
11922
12122
  if (lexicalEnabled) {
11923
- const pluginService = new chunkQAYFOER6_cjs.PluginService(db);
12123
+ const pluginService = new chunk5ARIHAGN_cjs.PluginService(db);
11924
12124
  const lexicalPlugin = await pluginService.getPlugin("lexical-editor");
11925
12125
  lexicalSettings = lexicalPlugin?.settings;
11926
12126
  }
@@ -12041,7 +12241,7 @@ adminContentRoutes.post("/", async (c) => {
12041
12241
  data,
12042
12242
  publishOnCreate: status === "published"
12043
12243
  }), user?.userId);
12044
- const cache2 = chunkBDDABDAB_cjs.getCacheService(chunkBDDABDAB_cjs.CACHE_CONFIGS.content);
12244
+ const cache2 = chunk36Z3AKX3_cjs.getCacheService(chunk36Z3AKX3_cjs.CACHE_CONFIGS.content);
12045
12245
  await cache2.invalidate(`content:list:${collectionId}:*`);
12046
12246
  const redirectUrl2 = `/admin/content/${doc.rootId}/edit?success=Content created successfully!`;
12047
12247
  return c.req.header("HX-Request") === "true" ? c.text("", 200, { "HX-Redirect": redirectUrl2 }) : c.redirect(redirectUrl2);
@@ -12071,7 +12271,7 @@ adminContentRoutes.post("/", async (c) => {
12071
12271
  now,
12072
12272
  now
12073
12273
  ).run();
12074
- const cache = chunkBDDABDAB_cjs.getCacheService(chunkBDDABDAB_cjs.CACHE_CONFIGS.content);
12274
+ const cache = chunk36Z3AKX3_cjs.getCacheService(chunk36Z3AKX3_cjs.CACHE_CONFIGS.content);
12075
12275
  await cache.invalidate(`content:list:${collectionId}:*`);
12076
12276
  const versionStmt = db.prepare(`
12077
12277
  INSERT INTO content_versions (id, content_id, version, data, author_id, created_at)
@@ -12160,7 +12360,7 @@ adminContentRoutes.put("/:id", async (c) => {
12160
12360
  const pub = await db.prepare("SELECT id FROM documents WHERE root_id = ? AND is_published = 1 AND tenant_id = ?").bind(id, tenantId).first();
12161
12361
  if (status2 === "published") await svc.publish(newDraft.id, user?.userId);
12162
12362
  else if (pub) await svc.unpublish(pub.id);
12163
- await chunkBDDABDAB_cjs.getCacheService(chunkBDDABDAB_cjs.CACHE_CONFIGS.content).invalidate(`content:list:*`);
12363
+ await chunk36Z3AKX3_cjs.getCacheService(chunk36Z3AKX3_cjs.CACHE_CONFIGS.content).invalidate(`content:list:*`);
12164
12364
  const redirectUrl2 = `/admin/content/${id}/edit?success=Content updated successfully!`;
12165
12365
  return c.req.header("HX-Request") === "true" ? c.text("", 200, { "HX-Redirect": redirectUrl2 }) : c.redirect(redirectUrl2);
12166
12366
  }
@@ -12241,7 +12441,7 @@ adminContentRoutes.put("/:id", async (c) => {
12241
12441
  now,
12242
12442
  id
12243
12443
  ).run();
12244
- const cache = chunkBDDABDAB_cjs.getCacheService(chunkBDDABDAB_cjs.CACHE_CONFIGS.content);
12444
+ const cache = chunk36Z3AKX3_cjs.getCacheService(chunk36Z3AKX3_cjs.CACHE_CONFIGS.content);
12245
12445
  await cache.delete(cache.generateKey("content", id));
12246
12446
  await cache.invalidate(`content:list:${existingContent.collection_id}:*`);
12247
12447
  const existingData = JSON.parse(existingContent.data || "{}");
@@ -12293,7 +12493,7 @@ adminContentRoutes.put("/:id", async (c) => {
12293
12493
  `);
12294
12494
  }
12295
12495
  });
12296
- adminContentRoutes.post("/preview", chunkAAWNRBRB_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
12496
+ adminContentRoutes.post("/preview", chunk4SHNHNRP_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
12297
12497
  try {
12298
12498
  const formData = await c.req.formData();
12299
12499
  const collectionId = formData.get("collection_id");
@@ -12548,12 +12748,12 @@ adminContentRoutes.post("/bulk-action", async (c) => {
12548
12748
  }
12549
12749
  }
12550
12750
  }
12551
- const cache = chunkBDDABDAB_cjs.getCacheService(chunkBDDABDAB_cjs.CACHE_CONFIGS.content);
12751
+ const cache = chunk36Z3AKX3_cjs.getCacheService(chunk36Z3AKX3_cjs.CACHE_CONFIGS.content);
12552
12752
  for (const contentId of ids) {
12553
12753
  await cache.delete(cache.generateKey("content", contentId));
12554
12754
  }
12555
12755
  await cache.invalidate("content:list:*");
12556
- const apiCache = chunkBDDABDAB_cjs.getCacheService(chunkBDDABDAB_cjs.CACHE_CONFIGS.api);
12756
+ const apiCache = chunk36Z3AKX3_cjs.getCacheService(chunk36Z3AKX3_cjs.CACHE_CONFIGS.api);
12557
12757
  await apiCache.invalidate("content-filtered:*");
12558
12758
  await apiCache.invalidate("collection-content-filtered:*");
12559
12759
  return c.json({ success: true, count: ids.length });
@@ -12572,7 +12772,7 @@ adminContentRoutes.delete("/:id", async (c) => {
12572
12772
  if (docDel && await getDocBackingType(db, docDel.type_id)) {
12573
12773
  const now2 = Math.floor(Date.now() / 1e3);
12574
12774
  await db.prepare("UPDATE documents SET deleted_at = ?, updated_at = ? WHERE root_id = ? AND tenant_id = ?").bind(now2, now2, id, tenantId).run();
12575
- await chunkBDDABDAB_cjs.getCacheService(chunkBDDABDAB_cjs.CACHE_CONFIGS.content).invalidate("content:list:*");
12775
+ await chunk36Z3AKX3_cjs.getCacheService(chunk36Z3AKX3_cjs.CACHE_CONFIGS.content).invalidate("content:list:*");
12576
12776
  return c.html(`
12577
12777
  <div id="content-list" hx-get="/admin/content?model=${docDel.type_id}" hx-trigger="load" hx-swap="outerHTML">
12578
12778
  <div class="flex items-center justify-center p-8"><span class="text-zinc-500">Deleting\u2026</span></div>
@@ -12592,7 +12792,7 @@ adminContentRoutes.delete("/:id", async (c) => {
12592
12792
  WHERE id = ?
12593
12793
  `);
12594
12794
  await deleteStmt.bind(now, id).run();
12595
- const cache = chunkBDDABDAB_cjs.getCacheService(chunkBDDABDAB_cjs.CACHE_CONFIGS.content);
12795
+ const cache = chunk36Z3AKX3_cjs.getCacheService(chunk36Z3AKX3_cjs.CACHE_CONFIGS.content);
12596
12796
  await cache.delete(cache.generateKey("content", id));
12597
12797
  await cache.invalidate("content:list:*");
12598
12798
  return c.html(`
@@ -12612,7 +12812,7 @@ adminContentRoutes.delete("/:id", async (c) => {
12612
12812
  return c.json({ success: false, error: "Failed to delete content" }, 500);
12613
12813
  }
12614
12814
  });
12615
- adminContentRoutes.get("/:id/version/:version/preview", chunkAAWNRBRB_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
12815
+ adminContentRoutes.get("/:id/version/:version/preview", chunk4SHNHNRP_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
12616
12816
  try {
12617
12817
  const id = c.req.param("id");
12618
12818
  const version = parseInt(c.req.param("version") || "0");
@@ -12708,9 +12908,9 @@ function parseDocFormData(formData, queryableFields = []) {
12708
12908
  return { title, slug, data };
12709
12909
  }
12710
12910
  async function getDocService(db, typeId, tenantId) {
12711
- const registry = new chunkAAWNRBRB_cjs.DocumentTypeRegistry(db);
12911
+ const registry = new chunk4SHNHNRP_cjs.DocumentTypeRegistry(db);
12712
12912
  const docType = await registry.findById(typeId);
12713
- const svc = new chunk2CB4KY7I_cjs.DocumentsService(db, {
12913
+ const svc = new chunkLTZ5WYOK_cjs.DocumentsService(db, {
12714
12914
  queryableFields: docType?.queryableFields ?? [],
12715
12915
  typeSchemaVersion: docType?.schemaVersion ?? 1,
12716
12916
  maxVersionsPerRoot: docType?.settings?.maxVersionsPerRoot ?? 50,
@@ -12721,10 +12921,10 @@ async function getDocService(db, typeId, tenantId) {
12721
12921
  }
12722
12922
  adminContentRoutes.get("/documents/:typeId/new", async (c) => {
12723
12923
  const { typeId } = c.req.param();
12724
- const registry = new chunkAAWNRBRB_cjs.DocumentTypeRegistry(c.env.DB);
12924
+ const registry = new chunk4SHNHNRP_cjs.DocumentTypeRegistry(c.env.DB);
12725
12925
  const docType = await registry.findById(typeId);
12726
12926
  if (!docType) return c.html("<p>Unknown document type.</p>", 404);
12727
- return c.html(chunkDNQCEKUK_cjs.renderDocumentFormPage({ docType, isEdit: false, user: userCtx(c) }));
12927
+ return c.html(chunkN32OWET6_cjs.renderDocumentFormPage({ docType, isEdit: false, user: userCtx(c) }));
12728
12928
  });
12729
12929
  adminContentRoutes.post("/documents/:typeId/new", async (c) => {
12730
12930
  const { typeId } = c.req.param();
@@ -12746,17 +12946,17 @@ adminContentRoutes.post("/documents/:typeId/new", async (c) => {
12746
12946
  }), user?.userId);
12747
12947
  return c.redirect(`/admin/content/documents/${typeId}/${doc.rootId}/edit?message=Created+successfully`);
12748
12948
  } catch (err) {
12749
- const registry = new chunkAAWNRBRB_cjs.DocumentTypeRegistry(c.env.DB);
12949
+ const registry = new chunk4SHNHNRP_cjs.DocumentTypeRegistry(c.env.DB);
12750
12950
  const docType = await registry.findById(typeId);
12751
12951
  if (!docType) return c.html("<p>Unknown document type.</p>", 404);
12752
- return c.html(chunkDNQCEKUK_cjs.renderDocumentFormPage({ docType, isEdit: false, user: userCtx(c), message: err?.message ?? "Failed to create", messageType: "error" }));
12952
+ return c.html(chunkN32OWET6_cjs.renderDocumentFormPage({ docType, isEdit: false, user: userCtx(c), message: err?.message ?? "Failed to create", messageType: "error" }));
12753
12953
  }
12754
12954
  });
12755
12955
  adminContentRoutes.get("/documents/:typeId/:rootId/edit", async (c) => {
12756
12956
  const { typeId, rootId } = c.req.param();
12757
12957
  const db = c.env.DB;
12758
12958
  const message = c.req.query("message");
12759
- const registry = new chunkAAWNRBRB_cjs.DocumentTypeRegistry(db);
12959
+ const registry = new chunk4SHNHNRP_cjs.DocumentTypeRegistry(db);
12760
12960
  const docType = await registry.findById(typeId);
12761
12961
  if (!docType) return c.html("<p>Unknown document type.</p>", 404);
12762
12962
  const tenantId = reqTenant(c);
@@ -12803,7 +13003,7 @@ adminContentRoutes.get("/documents/:typeId/:rootId/edit", async (c) => {
12803
13003
  createdAt: draftRow.created_at,
12804
13004
  updatedAt: draftRow.updated_at
12805
13005
  };
12806
- return c.html(chunkDNQCEKUK_cjs.renderDocumentFormPage({ docType, doc, publishedDoc, isEdit: true, message, user: userCtx(c), versioningEnabled: docType?.settings?.versioning === true }));
13006
+ return c.html(chunkN32OWET6_cjs.renderDocumentFormPage({ docType, doc, publishedDoc, isEdit: true, message, user: userCtx(c), versioningEnabled: docType?.settings?.versioning === true }));
12807
13007
  });
12808
13008
  adminContentRoutes.post("/documents/:typeId/:rootId", async (c) => {
12809
13009
  const { typeId, rootId } = c.req.param();
@@ -12868,8 +13068,8 @@ adminContentRoutes.post("/documents/:typeId/:documentId/delete", async (c) => {
12868
13068
  adminContentRoutes.get("/documents/:typeId/:rootId/versions", async (c) => {
12869
13069
  const { typeId, rootId } = c.req.param();
12870
13070
  const db = c.env.DB;
12871
- const { renderVersionHistoryFragment } = await import('./admin-documents-form.template-KN7JF66Q.cjs');
12872
- const registry = new chunkAAWNRBRB_cjs.DocumentTypeRegistry(db);
13071
+ const { renderVersionHistoryFragment } = await import('./admin-documents-form.template-LSZKGA5J.cjs');
13072
+ const registry = new chunk4SHNHNRP_cjs.DocumentTypeRegistry(db);
12873
13073
  const docType = await registry.findById(typeId);
12874
13074
  if (!docType) return c.html("<div>Unknown type.</div>", 404);
12875
13075
  const result = await db.prepare(
@@ -12889,7 +13089,7 @@ adminContentRoutes.get("/documents/:typeId/:rootId/versions", async (c) => {
12889
13089
  var admin_content_default = adminContentRoutes;
12890
13090
 
12891
13091
  // src/templates/pages/admin-profile.template.ts
12892
- chunkNAVPFIG5_cjs.init_admin_layout_catalyst_template();
13092
+ chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
12893
13093
  function renderAvatarImage(avatarUrl, firstName, lastName) {
12894
13094
  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">
12895
13095
  ${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>`}
@@ -12909,8 +13109,8 @@ function renderProfilePage(data) {
12909
13109
  </div>
12910
13110
 
12911
13111
  <!-- Alert Messages -->
12912
- ${data.error ? chunkMVIZJOO5_cjs.renderAlert({ type: "error", message: data.error, dismissible: true }) : ""}
12913
- ${data.success ? chunkMVIZJOO5_cjs.renderAlert({ type: "success", message: data.success, dismissible: true }) : ""}
13112
+ ${data.error ? chunkPXNTCCPE_cjs.renderAlert({ type: "error", message: data.error, dismissible: true }) : ""}
13113
+ ${data.success ? chunkPXNTCCPE_cjs.renderAlert({ type: "success", message: data.success, dismissible: true }) : ""}
12914
13114
 
12915
13115
  <!-- Profile Form -->
12916
13116
  <div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
@@ -13287,7 +13487,7 @@ function renderProfilePage(data) {
13287
13487
  version: data.version,
13288
13488
  content: pageContent
13289
13489
  };
13290
- return chunkNAVPFIG5_cjs.renderAdminLayoutCatalyst(layoutData);
13490
+ return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
13291
13491
  }
13292
13492
 
13293
13493
  // src/templates/pages/admin-activity-logs.template.ts
@@ -13497,7 +13697,7 @@ function renderActivityLogsPage(data) {
13497
13697
  user: data.user,
13498
13698
  content: pageContent
13499
13699
  };
13500
- return chunkMVIZJOO5_cjs.renderAdminLayout(layoutData);
13700
+ return chunkPXNTCCPE_cjs.renderAdminLayout(layoutData);
13501
13701
  }
13502
13702
  function getActionBadgeClass(action) {
13503
13703
  if (action.includes("login") || action.includes("logout")) {
@@ -13517,7 +13717,7 @@ function formatAction(action) {
13517
13717
  }
13518
13718
 
13519
13719
  // src/templates/pages/admin-user-edit.template.ts
13520
- chunkNAVPFIG5_cjs.init_admin_layout_catalyst_template();
13720
+ chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
13521
13721
 
13522
13722
  // src/templates/components/confirmation-dialog.template.ts
13523
13723
  function renderConfirmationDialog2(options) {
@@ -13713,8 +13913,8 @@ function renderUserEditPage(data) {
13713
13913
 
13714
13914
  <!-- Alert Messages -->
13715
13915
  <div id="form-messages" class="mb-6 empty:mb-0">
13716
- ${data.error ? chunkMVIZJOO5_cjs.renderAlert({ type: "error", message: data.error, dismissible: true }) : ""}
13717
- ${data.success ? chunkMVIZJOO5_cjs.renderAlert({ type: "success", message: data.success, dismissible: true }) : ""}
13916
+ ${data.error ? chunkPXNTCCPE_cjs.renderAlert({ type: "error", message: data.error, dismissible: true }) : ""}
13917
+ ${data.success ? chunkPXNTCCPE_cjs.renderAlert({ type: "success", message: data.success, dismissible: true }) : ""}
13718
13918
  </div>
13719
13919
 
13720
13920
  <!-- User Edit Form -->
@@ -14036,11 +14236,11 @@ function renderUserEditPage(data) {
14036
14236
  user: data.user,
14037
14237
  content: pageContent
14038
14238
  };
14039
- return chunkNAVPFIG5_cjs.renderAdminLayoutCatalyst(layoutData);
14239
+ return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
14040
14240
  }
14041
14241
 
14042
14242
  // src/templates/pages/admin-user-new.template.ts
14043
- chunkNAVPFIG5_cjs.init_admin_layout_catalyst_template();
14243
+ chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
14044
14244
  function renderUserNewPage(data) {
14045
14245
  const pageContent = `
14046
14246
  <div>
@@ -14079,8 +14279,8 @@ function renderUserNewPage(data) {
14079
14279
 
14080
14280
  <!-- Alert Messages -->
14081
14281
  <div id="form-messages">
14082
- ${data.error ? chunkMVIZJOO5_cjs.renderAlert({ type: "error", message: data.error, dismissible: true }) : ""}
14083
- ${data.success ? chunkMVIZJOO5_cjs.renderAlert({ type: "success", message: data.success, dismissible: true }) : ""}
14282
+ ${data.error ? chunkPXNTCCPE_cjs.renderAlert({ type: "error", message: data.error, dismissible: true }) : ""}
14283
+ ${data.success ? chunkPXNTCCPE_cjs.renderAlert({ type: "success", message: data.success, dismissible: true }) : ""}
14084
14284
  </div>
14085
14285
 
14086
14286
  <!-- User New Form -->
@@ -14310,11 +14510,11 @@ function renderUserNewPage(data) {
14310
14510
  user: data.user,
14311
14511
  content: pageContent
14312
14512
  };
14313
- return chunkNAVPFIG5_cjs.renderAdminLayoutCatalyst(layoutData);
14513
+ return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
14314
14514
  }
14315
14515
 
14316
14516
  // src/templates/pages/admin-users-list.template.ts
14317
- chunkNAVPFIG5_cjs.init_admin_layout_catalyst_template();
14517
+ chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
14318
14518
  function renderUsersListPage(data) {
14319
14519
  const columns = [
14320
14520
  {
@@ -14470,8 +14670,8 @@ function renderUsersListPage(data) {
14470
14670
  </div>
14471
14671
 
14472
14672
  <!-- Alert Messages -->
14473
- ${data.error ? chunkMVIZJOO5_cjs.renderAlert({ type: "error", message: data.error, dismissible: true }) : ""}
14474
- ${data.success ? chunkMVIZJOO5_cjs.renderAlert({ type: "success", message: data.success, dismissible: true }) : ""}
14673
+ ${data.error ? chunkPXNTCCPE_cjs.renderAlert({ type: "error", message: data.error, dismissible: true }) : ""}
14674
+ ${data.success ? chunkPXNTCCPE_cjs.renderAlert({ type: "success", message: data.success, dismissible: true }) : ""}
14475
14675
 
14476
14676
  <!-- Stats -->
14477
14677
  <div class="mb-6">
@@ -14648,10 +14848,10 @@ function renderUsersListPage(data) {
14648
14848
  </div>
14649
14849
 
14650
14850
  <!-- Users Table -->
14651
- ${chunkMVIZJOO5_cjs.renderTable(tableData)}
14851
+ ${chunkPXNTCCPE_cjs.renderTable(tableData)}
14652
14852
 
14653
14853
  <!-- Pagination -->
14654
- ${data.pagination ? chunkMVIZJOO5_cjs.renderPagination(data.pagination) : ""}
14854
+ ${data.pagination ? chunkPXNTCCPE_cjs.renderPagination(data.pagination) : ""}
14655
14855
  </div>
14656
14856
 
14657
14857
  <script>
@@ -14722,7 +14922,7 @@ function renderUsersListPage(data) {
14722
14922
  version: data.version,
14723
14923
  content: pageContent
14724
14924
  };
14725
- return chunkNAVPFIG5_cjs.renderAdminLayoutCatalyst(layoutData);
14925
+ return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
14726
14926
  }
14727
14927
 
14728
14928
  // src/plugins/core-plugins/multi-tenant-plugin/services/tenant-service.ts
@@ -14741,6 +14941,7 @@ var TenantService = class {
14741
14941
  constructor(db) {
14742
14942
  this.db = db;
14743
14943
  }
14944
+ db;
14744
14945
  async listTenants() {
14745
14946
  const { results } = await this.db.prepare(`
14746
14947
  SELECT * FROM auth_tenant
@@ -14801,7 +15002,7 @@ var TenantService = class {
14801
15002
  SET name = ?, domain = ?, status = ?, notes = ?, updated_at = ?
14802
15003
  WHERE slug = ?
14803
15004
  `).bind(name, domain, status, notes, now, slug).run();
14804
- chunkQAYFOER6_cjs.invalidateTenantCache();
15005
+ chunk5ARIHAGN_cjs.invalidateTenantCache();
14805
15006
  const updated = await this.getTenantBySlug(slug);
14806
15007
  if (!updated) throw new Error("Tenant not found");
14807
15008
  return updated;
@@ -14819,7 +15020,7 @@ var TenantService = class {
14819
15020
  throw new Error(`Tenant '${slug}' still owns ${docCount} document(s). Delete or migrate its content first.`);
14820
15021
  }
14821
15022
  await this.db.prepare(`DELETE FROM auth_tenant WHERE slug = ?`).bind(slug).run();
14822
- chunkQAYFOER6_cjs.invalidateTenantCache();
15023
+ chunk5ARIHAGN_cjs.invalidateTenantCache();
14823
15024
  }
14824
15025
  // ─── Membership (auth_tenant_member) ───────────────────────────────────────
14825
15026
  // Tenant resolution and the admin switcher are gated on membership: an authed user may only
@@ -15063,7 +15264,7 @@ var TenantService = class {
15063
15264
  INSERT INTO auth_tenant (id, name, slug, status, domain, notes, metadata, created_at, updated_at)
15064
15265
  VALUES (?, ?, ?, 'active', ?, ?, '{}', ?, ?)
15065
15266
  `).bind(id, input.name, input.slug, input.domain, input.notes, now, now).run();
15066
- chunkQAYFOER6_cjs.invalidateTenantCache();
15267
+ chunk5ARIHAGN_cjs.invalidateTenantCache();
15067
15268
  const created = await this.getTenantBySlug(input.slug);
15068
15269
  if (!created) throw new Error("Failed to create tenant");
15069
15270
  return created;
@@ -15087,14 +15288,14 @@ function mapRowToTenant(row) {
15087
15288
 
15088
15289
  // src/routes/admin-users.ts
15089
15290
  var userRoutes = new hono.Hono();
15090
- userRoutes.use("*", chunkAAWNRBRB_cjs.requireAuth());
15091
- userRoutes.use("/users/*", chunkAAWNRBRB_cjs.requireRole(["admin"]));
15092
- userRoutes.use("/users", chunkAAWNRBRB_cjs.requireRole(["admin"]));
15093
- userRoutes.use("/invite-user", chunkAAWNRBRB_cjs.requireRole(["admin"]));
15094
- userRoutes.use("/resend-invitation/*", chunkAAWNRBRB_cjs.requireRole(["admin"]));
15095
- userRoutes.use("/cancel-invitation/*", chunkAAWNRBRB_cjs.requireRole(["admin"]));
15096
- userRoutes.use("/activity-logs", chunkAAWNRBRB_cjs.requireRole(["admin"]));
15097
- userRoutes.use("/activity-logs/*", chunkAAWNRBRB_cjs.requireRole(["admin"]));
15291
+ userRoutes.use("*", chunk4SHNHNRP_cjs.requireAuth());
15292
+ userRoutes.use("/users/*", chunk4SHNHNRP_cjs.requireRole(["admin"]));
15293
+ userRoutes.use("/users", chunk4SHNHNRP_cjs.requireRole(["admin"]));
15294
+ userRoutes.use("/invite-user", chunk4SHNHNRP_cjs.requireRole(["admin"]));
15295
+ userRoutes.use("/resend-invitation/*", chunk4SHNHNRP_cjs.requireRole(["admin"]));
15296
+ userRoutes.use("/cancel-invitation/*", chunk4SHNHNRP_cjs.requireRole(["admin"]));
15297
+ userRoutes.use("/activity-logs", chunk4SHNHNRP_cjs.requireRole(["admin"]));
15298
+ userRoutes.use("/activity-logs/*", chunk4SHNHNRP_cjs.requireRole(["admin"]));
15098
15299
  userRoutes.get("/", (c) => {
15099
15300
  return c.redirect("/admin/dashboard");
15100
15301
  });
@@ -15205,7 +15406,7 @@ userRoutes.put("/profile", async (c) => {
15205
15406
  const language = formData.get("language")?.toString() || "en";
15206
15407
  const emailNotifications = formData.get("email_notifications") === "1";
15207
15408
  if (!firstName || !lastName || !email) {
15208
- return c.html(chunkDNQCEKUK_cjs.renderAlert({
15409
+ return c.html(chunkN32OWET6_cjs.renderAlert({
15209
15410
  type: "error",
15210
15411
  message: "First name, last name, and email are required.",
15211
15412
  dismissible: true
@@ -15213,7 +15414,7 @@ userRoutes.put("/profile", async (c) => {
15213
15414
  }
15214
15415
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
15215
15416
  if (!emailRegex.test(email)) {
15216
- return c.html(chunkDNQCEKUK_cjs.renderAlert({
15417
+ return c.html(chunkN32OWET6_cjs.renderAlert({
15217
15418
  type: "error",
15218
15419
  message: "Please enter a valid email address.",
15219
15420
  dismissible: true
@@ -15225,7 +15426,7 @@ userRoutes.put("/profile", async (c) => {
15225
15426
  `);
15226
15427
  const existingUser = await checkStmt.bind(email, user.userId).first();
15227
15428
  if (existingUser) {
15228
- return c.html(chunkDNQCEKUK_cjs.renderAlert({
15429
+ return c.html(chunkN32OWET6_cjs.renderAlert({
15229
15430
  type: "error",
15230
15431
  message: "Email is already taken by another user.",
15231
15432
  dismissible: true
@@ -15257,11 +15458,11 @@ userRoutes.put("/profile", async (c) => {
15257
15458
  const validation = validateCustomData(sanitized, profileConfig);
15258
15459
  if (!validation.valid) {
15259
15460
  const errorMessages = Object.values(validation.errors).join(", ");
15260
- return c.html(chunkDNQCEKUK_cjs.renderAlert({ type: "error", message: errorMessages, dismissible: true }), 400);
15461
+ return c.html(chunkN32OWET6_cjs.renderAlert({ type: "error", message: errorMessages, dismissible: true }), 400);
15261
15462
  }
15262
15463
  await saveCustomData(db, user.userId, sanitized);
15263
15464
  }
15264
- await chunkAAWNRBRB_cjs.logActivity(
15465
+ await chunk4SHNHNRP_cjs.logActivity(
15265
15466
  db,
15266
15467
  user.userId,
15267
15468
  "profile.update",
@@ -15271,14 +15472,14 @@ userRoutes.put("/profile", async (c) => {
15271
15472
  c.req.header("x-forwarded-for") || c.req.header("cf-connecting-ip"),
15272
15473
  c.req.header("user-agent")
15273
15474
  );
15274
- return c.html(chunkDNQCEKUK_cjs.renderAlert({
15475
+ return c.html(chunkN32OWET6_cjs.renderAlert({
15275
15476
  type: "success",
15276
15477
  message: "Profile updated successfully!",
15277
15478
  dismissible: true
15278
15479
  }));
15279
15480
  } catch (error) {
15280
15481
  console.error("Profile update error:", error);
15281
- return c.html(chunkDNQCEKUK_cjs.renderAlert({
15482
+ return c.html(chunkN32OWET6_cjs.renderAlert({
15282
15483
  type: "error",
15283
15484
  message: "Failed to update profile. Please try again.",
15284
15485
  dismissible: true
@@ -15292,7 +15493,7 @@ userRoutes.post("/profile/avatar", async (c) => {
15292
15493
  const formData = await c.req.formData();
15293
15494
  const avatarFile = formData.get("avatar");
15294
15495
  if (!avatarFile || typeof avatarFile === "string" || !avatarFile.name) {
15295
- return c.html(chunkDNQCEKUK_cjs.renderAlert({
15496
+ return c.html(chunkN32OWET6_cjs.renderAlert({
15296
15497
  type: "error",
15297
15498
  message: "Please select an image file.",
15298
15499
  dismissible: true
@@ -15300,7 +15501,7 @@ userRoutes.post("/profile/avatar", async (c) => {
15300
15501
  }
15301
15502
  const allowedTypes = ["image/jpeg", "image/png", "image/gif", "image/webp"];
15302
15503
  if (!allowedTypes.includes(avatarFile.type)) {
15303
- return c.html(chunkDNQCEKUK_cjs.renderAlert({
15504
+ return c.html(chunkN32OWET6_cjs.renderAlert({
15304
15505
  type: "error",
15305
15506
  message: "Please upload a valid image file (JPEG, PNG, GIF, or WebP).",
15306
15507
  dismissible: true
@@ -15308,7 +15509,7 @@ userRoutes.post("/profile/avatar", async (c) => {
15308
15509
  }
15309
15510
  const maxSize = 5 * 1024 * 1024;
15310
15511
  if (avatarFile.size > maxSize) {
15311
- return c.html(chunkDNQCEKUK_cjs.renderAlert({
15512
+ return c.html(chunkN32OWET6_cjs.renderAlert({
15312
15513
  type: "error",
15313
15514
  message: "Image file must be smaller than 5MB.",
15314
15515
  dismissible: true
@@ -15324,7 +15525,7 @@ userRoutes.post("/profile/avatar", async (c) => {
15324
15525
  SELECT first_name, last_name FROM auth_user WHERE id = ?
15325
15526
  `);
15326
15527
  const userData = await userStmt.bind(user.userId).first();
15327
- await chunkAAWNRBRB_cjs.logActivity(
15528
+ await chunk4SHNHNRP_cjs.logActivity(
15328
15529
  db,
15329
15530
  user.userId,
15330
15531
  "profile.avatar_update",
@@ -15334,7 +15535,7 @@ userRoutes.post("/profile/avatar", async (c) => {
15334
15535
  c.req.header("x-forwarded-for") || c.req.header("cf-connecting-ip"),
15335
15536
  c.req.header("user-agent")
15336
15537
  );
15337
- const alertHtml = chunkDNQCEKUK_cjs.renderAlert({
15538
+ const alertHtml = chunkN32OWET6_cjs.renderAlert({
15338
15539
  type: "success",
15339
15540
  message: "Profile picture updated successfully!",
15340
15541
  dismissible: true
@@ -15348,7 +15549,7 @@ userRoutes.post("/profile/avatar", async (c) => {
15348
15549
  return c.html(alertHtml + avatarImageWithOob);
15349
15550
  } catch (error) {
15350
15551
  console.error("Avatar upload error:", error);
15351
- return c.html(chunkDNQCEKUK_cjs.renderAlert({
15552
+ return c.html(chunkN32OWET6_cjs.renderAlert({
15352
15553
  type: "error",
15353
15554
  message: "Failed to upload profile picture. Please try again.",
15354
15555
  dismissible: true
@@ -15364,21 +15565,21 @@ userRoutes.post("/profile/password", async (c) => {
15364
15565
  const newPassword = formData.get("new_password")?.toString() || "";
15365
15566
  const confirmPassword = formData.get("confirm_password")?.toString() || "";
15366
15567
  if (!currentPassword || !newPassword || !confirmPassword) {
15367
- return c.html(chunkDNQCEKUK_cjs.renderAlert({
15568
+ return c.html(chunkN32OWET6_cjs.renderAlert({
15368
15569
  type: "error",
15369
15570
  message: "All password fields are required.",
15370
15571
  dismissible: true
15371
15572
  }));
15372
15573
  }
15373
15574
  if (newPassword !== confirmPassword) {
15374
- return c.html(chunkDNQCEKUK_cjs.renderAlert({
15575
+ return c.html(chunkN32OWET6_cjs.renderAlert({
15375
15576
  type: "error",
15376
15577
  message: "New passwords do not match.",
15377
15578
  dismissible: true
15378
15579
  }));
15379
15580
  }
15380
15581
  if (newPassword.length < 8) {
15381
- return c.html(chunkDNQCEKUK_cjs.renderAlert({
15582
+ return c.html(chunkN32OWET6_cjs.renderAlert({
15382
15583
  type: "error",
15383
15584
  message: "New password must be at least 8 characters long.",
15384
15585
  dismissible: true
@@ -15389,21 +15590,21 @@ userRoutes.post("/profile/password", async (c) => {
15389
15590
  `);
15390
15591
  const userData = await userStmt.bind(user.userId).first();
15391
15592
  if (!userData) {
15392
- return c.html(chunkDNQCEKUK_cjs.renderAlert({
15593
+ return c.html(chunkN32OWET6_cjs.renderAlert({
15393
15594
  type: "error",
15394
15595
  message: "User not found.",
15395
15596
  dismissible: true
15396
15597
  }));
15397
15598
  }
15398
- const validPassword = await chunkAAWNRBRB_cjs.AuthManager.verifyPassword(currentPassword, userData.password_hash);
15599
+ const validPassword = await chunk4SHNHNRP_cjs.AuthManager.verifyPassword(currentPassword, userData.password_hash);
15399
15600
  if (!validPassword) {
15400
- return c.html(chunkDNQCEKUK_cjs.renderAlert({
15601
+ return c.html(chunkN32OWET6_cjs.renderAlert({
15401
15602
  type: "error",
15402
15603
  message: "Current password is incorrect.",
15403
15604
  dismissible: true
15404
15605
  }));
15405
15606
  }
15406
- const newPasswordHash = await chunkAAWNRBRB_cjs.AuthManager.hashPassword(newPassword);
15607
+ const newPasswordHash = await chunk4SHNHNRP_cjs.AuthManager.hashPassword(newPassword);
15407
15608
  const historyStmt = db.prepare(`
15408
15609
  INSERT INTO auth_password_history (id, user_id, password_hash, created_at)
15409
15610
  VALUES (?, ?, ?, ?)
@@ -15419,7 +15620,7 @@ userRoutes.post("/profile/password", async (c) => {
15419
15620
  WHERE id = ?
15420
15621
  `);
15421
15622
  await updateStmt.bind(newPasswordHash, Date.now(), user.userId).run();
15422
- await chunkAAWNRBRB_cjs.logActivity(
15623
+ await chunk4SHNHNRP_cjs.logActivity(
15423
15624
  db,
15424
15625
  user.userId,
15425
15626
  "profile.password_change",
@@ -15429,14 +15630,14 @@ userRoutes.post("/profile/password", async (c) => {
15429
15630
  c.req.header("x-forwarded-for") || c.req.header("cf-connecting-ip"),
15430
15631
  c.req.header("user-agent")
15431
15632
  );
15432
- return c.html(chunkDNQCEKUK_cjs.renderAlert({
15633
+ return c.html(chunkN32OWET6_cjs.renderAlert({
15433
15634
  type: "success",
15434
15635
  message: "Password updated successfully!",
15435
15636
  dismissible: true
15436
15637
  }));
15437
15638
  } catch (error) {
15438
15639
  console.error("Password change error:", error);
15439
- return c.html(chunkDNQCEKUK_cjs.renderAlert({
15640
+ return c.html(chunkN32OWET6_cjs.renderAlert({
15440
15641
  type: "error",
15441
15642
  message: "Failed to update password. Please try again.",
15442
15643
  dismissible: true
@@ -15486,7 +15687,7 @@ userRoutes.get("/users", async (c) => {
15486
15687
  `);
15487
15688
  const countResult = await countStmt.bind(...params).first();
15488
15689
  const totalUsers = countResult?.total || 0;
15489
- await chunkAAWNRBRB_cjs.logActivity(
15690
+ await chunk4SHNHNRP_cjs.logActivity(
15490
15691
  db,
15491
15692
  user.userId,
15492
15693
  "users.list_view",
@@ -15557,7 +15758,7 @@ userRoutes.get("/users", async (c) => {
15557
15758
  if (isApiRequest) {
15558
15759
  return c.json({ error: "Failed to load users" }, 500);
15559
15760
  }
15560
- return c.html(chunkDNQCEKUK_cjs.renderAlert({
15761
+ return c.html(chunkN32OWET6_cjs.renderAlert({
15561
15762
  type: "error",
15562
15763
  message: "Failed to load users. Please try again.",
15563
15764
  dismissible: true
@@ -15588,7 +15789,7 @@ userRoutes.get("/users/new", async (c) => {
15588
15789
  return c.html(renderUserNewPage(pageData));
15589
15790
  } catch (error) {
15590
15791
  console.error("User new page error:", error);
15591
- return c.html(chunkDNQCEKUK_cjs.renderAlert({
15792
+ return c.html(chunkN32OWET6_cjs.renderAlert({
15592
15793
  type: "error",
15593
15794
  message: "Failed to load user creation page. Please try again.",
15594
15795
  dismissible: true
@@ -15622,12 +15823,12 @@ userRoutes.post("/users/new", async (c) => {
15622
15823
  const validation = validateCustomData(sanitized, profileConfig);
15623
15824
  if (!validation.valid) {
15624
15825
  const errorMessages = Object.values(validation.errors).join(", ");
15625
- return c.html(chunkDNQCEKUK_cjs.renderAlert({ type: "error", message: errorMessages, dismissible: true }), 400);
15826
+ return c.html(chunkN32OWET6_cjs.renderAlert({ type: "error", message: errorMessages, dismissible: true }), 400);
15626
15827
  }
15627
15828
  sanitizedRegistrationCustom = sanitized;
15628
15829
  }
15629
15830
  if (!firstName || !lastName || !email || !password) {
15630
- return c.html(chunkDNQCEKUK_cjs.renderAlert({
15831
+ return c.html(chunkN32OWET6_cjs.renderAlert({
15631
15832
  type: "error",
15632
15833
  message: "First name, last name, email, and password are required.",
15633
15834
  dismissible: true
@@ -15635,21 +15836,21 @@ userRoutes.post("/users/new", async (c) => {
15635
15836
  }
15636
15837
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
15637
15838
  if (!emailRegex.test(email)) {
15638
- return c.html(chunkDNQCEKUK_cjs.renderAlert({
15839
+ return c.html(chunkN32OWET6_cjs.renderAlert({
15639
15840
  type: "error",
15640
15841
  message: "Please enter a valid email address.",
15641
15842
  dismissible: true
15642
15843
  }));
15643
15844
  }
15644
15845
  if (password.length < 8) {
15645
- return c.html(chunkDNQCEKUK_cjs.renderAlert({
15846
+ return c.html(chunkN32OWET6_cjs.renderAlert({
15646
15847
  type: "error",
15647
15848
  message: "Password must be at least 8 characters long.",
15648
15849
  dismissible: true
15649
15850
  }));
15650
15851
  }
15651
15852
  if (password !== confirmPassword) {
15652
- return c.html(chunkDNQCEKUK_cjs.renderAlert({
15853
+ return c.html(chunkN32OWET6_cjs.renderAlert({
15653
15854
  type: "error",
15654
15855
  message: "Passwords do not match.",
15655
15856
  dismissible: true
@@ -15661,13 +15862,13 @@ userRoutes.post("/users/new", async (c) => {
15661
15862
  `);
15662
15863
  const existingUser = await checkStmt.bind(email).first();
15663
15864
  if (existingUser) {
15664
- return c.html(chunkDNQCEKUK_cjs.renderAlert({
15865
+ return c.html(chunkN32OWET6_cjs.renderAlert({
15665
15866
  type: "error",
15666
15867
  message: "Email is already taken.",
15667
15868
  dismissible: true
15668
15869
  }));
15669
15870
  }
15670
- const passwordHash = await chunkAAWNRBRB_cjs.AuthManager.hashPassword(password);
15871
+ const passwordHash = await chunk4SHNHNRP_cjs.AuthManager.hashPassword(password);
15671
15872
  const userId = crypto.randomUUID();
15672
15873
  const createStmt = db.prepare(`
15673
15874
  INSERT INTO auth_user (
@@ -15692,7 +15893,7 @@ userRoutes.post("/users/new", async (c) => {
15692
15893
  if (sanitizedRegistrationCustom !== null && Object.keys(sanitizedRegistrationCustom).length > 0) {
15693
15894
  await writeProfileData(db, userId, { custom: sanitizedRegistrationCustom }, user.userId);
15694
15895
  }
15695
- await chunkAAWNRBRB_cjs.logActivity(
15896
+ await chunk4SHNHNRP_cjs.logActivity(
15696
15897
  db,
15697
15898
  user.userId,
15698
15899
  "user!.create",
@@ -15706,7 +15907,7 @@ userRoutes.post("/users/new", async (c) => {
15706
15907
  return c.body(null, 200);
15707
15908
  } catch (error) {
15708
15909
  console.error("User creation error:", error);
15709
- return c.html(chunkDNQCEKUK_cjs.renderAlert({
15910
+ return c.html(chunkN32OWET6_cjs.renderAlert({
15710
15911
  type: "error",
15711
15912
  message: "Failed to create user!. Please try again.",
15712
15913
  dismissible: true
@@ -15731,7 +15932,7 @@ userRoutes.get("/users/:id", async (c) => {
15731
15932
  if (!userRecord) {
15732
15933
  return c.json({ error: "User not found" }, 404);
15733
15934
  }
15734
- await chunkAAWNRBRB_cjs.logActivity(
15935
+ await chunk4SHNHNRP_cjs.logActivity(
15735
15936
  db,
15736
15937
  user.userId,
15737
15938
  "user!.view",
@@ -15776,7 +15977,7 @@ userRoutes.get("/users/:id/edit", async (c) => {
15776
15977
  `);
15777
15978
  const userToEdit = await userStmt.bind(userId).first();
15778
15979
  if (!userToEdit) {
15779
- return c.html(chunkDNQCEKUK_cjs.renderAlert({
15980
+ return c.html(chunkN32OWET6_cjs.renderAlert({
15780
15981
  type: "error",
15781
15982
  message: "User not found",
15782
15983
  dismissible: true
@@ -15846,7 +16047,7 @@ userRoutes.get("/users/:id/edit", async (c) => {
15846
16047
  return c.html(renderUserEditPage(pageData));
15847
16048
  } catch (error) {
15848
16049
  console.error("User edit page error:", error);
15849
- return c.html(chunkDNQCEKUK_cjs.renderAlert({
16050
+ return c.html(chunkN32OWET6_cjs.renderAlert({
15850
16051
  type: "error",
15851
16052
  message: "Failed to load user. Please try again.",
15852
16053
  dismissible: true
@@ -15879,12 +16080,12 @@ userRoutes.put("/users/:id", async (c) => {
15879
16080
  const validation = validateCustomData(sanitized, profileConfig);
15880
16081
  if (!validation.valid) {
15881
16082
  const errorMessages = Object.values(validation.errors).join(", ");
15882
- return c.html(chunkDNQCEKUK_cjs.renderAlert({ type: "error", message: errorMessages, dismissible: true }), 400);
16083
+ return c.html(chunkN32OWET6_cjs.renderAlert({ type: "error", message: errorMessages, dismissible: true }), 400);
15883
16084
  }
15884
16085
  sanitizedCustom = sanitized;
15885
16086
  }
15886
16087
  if (!email) {
15887
- return c.html(chunkDNQCEKUK_cjs.renderAlert({
16088
+ return c.html(chunkN32OWET6_cjs.renderAlert({
15888
16089
  type: "error",
15889
16090
  message: "Email is required.",
15890
16091
  dismissible: true
@@ -15892,7 +16093,7 @@ userRoutes.put("/users/:id", async (c) => {
15892
16093
  }
15893
16094
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
15894
16095
  if (!emailRegex.test(email)) {
15895
- return c.html(chunkDNQCEKUK_cjs.renderAlert({
16096
+ return c.html(chunkN32OWET6_cjs.renderAlert({
15896
16097
  type: "error",
15897
16098
  message: "Please enter a valid email address.",
15898
16099
  dismissible: true
@@ -15900,14 +16101,14 @@ userRoutes.put("/users/:id", async (c) => {
15900
16101
  }
15901
16102
  if (newPassword) {
15902
16103
  if (newPassword.length < 8) {
15903
- return c.html(chunkDNQCEKUK_cjs.renderAlert({
16104
+ return c.html(chunkN32OWET6_cjs.renderAlert({
15904
16105
  type: "error",
15905
16106
  message: "Password must be at least 8 characters long.",
15906
16107
  dismissible: true
15907
16108
  }));
15908
16109
  }
15909
16110
  if (newPassword !== confirmPassword) {
15910
- return c.html(chunkDNQCEKUK_cjs.renderAlert({
16111
+ return c.html(chunkN32OWET6_cjs.renderAlert({
15911
16112
  type: "error",
15912
16113
  message: "Passwords do not match.",
15913
16114
  dismissible: true
@@ -15920,7 +16121,7 @@ userRoutes.put("/users/:id", async (c) => {
15920
16121
  `);
15921
16122
  const existingUser = await checkStmt.bind(email, userId).first();
15922
16123
  if (existingUser) {
15923
- return c.html(chunkDNQCEKUK_cjs.renderAlert({
16124
+ return c.html(chunkN32OWET6_cjs.renderAlert({
15924
16125
  type: "error",
15925
16126
  message: "Email is already taken by another user.",
15926
16127
  dismissible: true
@@ -15945,7 +16146,7 @@ userRoutes.put("/users/:id", async (c) => {
15945
16146
  userId
15946
16147
  ).run();
15947
16148
  if (newPassword) {
15948
- const passwordHash = await chunkAAWNRBRB_cjs.AuthManager.hashPassword(newPassword);
16149
+ const passwordHash = await chunk4SHNHNRP_cjs.AuthManager.hashPassword(newPassword);
15949
16150
  const updatePasswordStmt = db.prepare(`
15950
16151
  UPDATE auth_user SET password_hash = ?, updated_at = ? WHERE id = ?
15951
16152
  `);
@@ -15958,7 +16159,7 @@ userRoutes.put("/users/:id", async (c) => {
15958
16159
  ...sanitizedCustom !== null ? { custom: sanitizedCustom } : {}
15959
16160
  }, user.userId);
15960
16161
  }
15961
- await chunkAAWNRBRB_cjs.logActivity(
16162
+ await chunk4SHNHNRP_cjs.logActivity(
15962
16163
  db,
15963
16164
  user.userId,
15964
16165
  "user.update",
@@ -15968,7 +16169,7 @@ userRoutes.put("/users/:id", async (c) => {
15968
16169
  c.req.header("x-forwarded-for") || c.req.header("cf-connecting-ip"),
15969
16170
  c.req.header("user-agent")
15970
16171
  );
15971
- return c.html(chunkDNQCEKUK_cjs.renderAlert({
16172
+ return c.html(chunkN32OWET6_cjs.renderAlert({
15972
16173
  type: "success",
15973
16174
  message: "User updated successfully!",
15974
16175
  dismissible: true,
@@ -15976,7 +16177,7 @@ userRoutes.put("/users/:id", async (c) => {
15976
16177
  }));
15977
16178
  } catch (error) {
15978
16179
  console.error("User update error:", error);
15979
- return c.html(chunkDNQCEKUK_cjs.renderAlert({
16180
+ return c.html(chunkN32OWET6_cjs.renderAlert({
15980
16181
  type: "error",
15981
16182
  message: "Failed to update user. Please try again.",
15982
16183
  dismissible: true
@@ -16004,7 +16205,7 @@ userRoutes.post("/users/:id/toggle", async (c) => {
16004
16205
  UPDATE auth_user SET is_active = ?, updated_at = ? WHERE id = ?
16005
16206
  `);
16006
16207
  await toggleStmt.bind(active ? 1 : 0, Date.now(), userId).run();
16007
- await chunkAAWNRBRB_cjs.logActivity(
16208
+ await chunk4SHNHNRP_cjs.logActivity(
16008
16209
  db,
16009
16210
  user.userId,
16010
16211
  active ? "user.activate" : "user.deactivate",
@@ -16045,7 +16246,7 @@ userRoutes.delete("/users/:id", async (c) => {
16045
16246
  DELETE FROM auth_user WHERE id = ?
16046
16247
  `);
16047
16248
  await deleteStmt.bind(userId).run();
16048
- await chunkAAWNRBRB_cjs.logActivity(
16249
+ await chunk4SHNHNRP_cjs.logActivity(
16049
16250
  db,
16050
16251
  user.userId,
16051
16252
  "user!.hard_delete",
@@ -16064,7 +16265,7 @@ userRoutes.delete("/users/:id", async (c) => {
16064
16265
  UPDATE auth_user SET is_active = 0, updated_at = ? WHERE id = ?
16065
16266
  `);
16066
16267
  await deleteStmt.bind(Date.now(), userId).run();
16067
- await chunkAAWNRBRB_cjs.logActivity(
16268
+ await chunk4SHNHNRP_cjs.logActivity(
16068
16269
  db,
16069
16270
  user.userId,
16070
16271
  "user!.soft_delete",
@@ -16130,7 +16331,7 @@ userRoutes.post("/invite-user", async (c) => {
16130
16331
  Date.now(),
16131
16332
  Date.now()
16132
16333
  ).run();
16133
- await chunkAAWNRBRB_cjs.logActivity(
16334
+ await chunk4SHNHNRP_cjs.logActivity(
16134
16335
  db,
16135
16336
  user.userId,
16136
16337
  "user!.invite_sent",
@@ -16187,7 +16388,7 @@ userRoutes.post("/resend-invitation/:id", async (c) => {
16187
16388
  Date.now(),
16188
16389
  userId
16189
16390
  ).run();
16190
- await chunkAAWNRBRB_cjs.logActivity(
16391
+ await chunk4SHNHNRP_cjs.logActivity(
16191
16392
  db,
16192
16393
  user.userId,
16193
16394
  "user!.invitation_resent",
@@ -16223,7 +16424,7 @@ userRoutes.delete("/cancel-invitation/:id", async (c) => {
16223
16424
  }
16224
16425
  const deleteStmt = db.prepare(`DELETE FROM auth_user WHERE id = ?`);
16225
16426
  await deleteStmt.bind(userId).run();
16226
- await chunkAAWNRBRB_cjs.logActivity(
16427
+ await chunk4SHNHNRP_cjs.logActivity(
16227
16428
  db,
16228
16429
  user.userId,
16229
16430
  "user!.invitation_cancelled",
@@ -16472,7 +16673,7 @@ function getFileIcon(mimeType) {
16472
16673
  }
16473
16674
 
16474
16675
  // src/templates/pages/admin-media-library.template.ts
16475
- chunkNAVPFIG5_cjs.init_admin_layout_catalyst_template();
16676
+ chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
16476
16677
  function renderMediaLibraryPage(data) {
16477
16678
  const pageContent = `
16478
16679
  <div>
@@ -17407,7 +17608,7 @@ function renderMediaLibraryPage(data) {
17407
17608
  version: data.version,
17408
17609
  content: pageContent
17409
17610
  };
17410
- return chunkNAVPFIG5_cjs.renderAdminLayoutCatalyst(layoutData);
17611
+ return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
17411
17612
  }
17412
17613
 
17413
17614
  // src/templates/components/media-file-details.template.ts
@@ -17604,7 +17805,7 @@ var fileValidationSchema2 = zod.z.object({
17604
17805
  // 50MB max
17605
17806
  });
17606
17807
  var adminMediaRoutes = new hono.Hono();
17607
- adminMediaRoutes.use("*", chunkAAWNRBRB_cjs.requireAuth());
17808
+ adminMediaRoutes.use("*", chunk4SHNHNRP_cjs.requireAuth());
17608
17809
  adminMediaRoutes.get("/", async (c) => {
17609
17810
  try {
17610
17811
  const user = c.get("user");
@@ -17646,7 +17847,7 @@ adminMediaRoutes.get("/selector", async (c) => {
17646
17847
  const { searchParams } = new URL(c.req.url);
17647
17848
  const search = searchParams.get("search") || "";
17648
17849
  const db = c.env.DB;
17649
- const pluginService = new chunkQAYFOER6_cjs.PluginService(db);
17850
+ const pluginService = new chunk5ARIHAGN_cjs.PluginService(db);
17650
17851
  const mediaPlugin = await pluginService.getPlugin("core-media");
17651
17852
  if (!mediaPlugin || mediaPlugin.status !== "active") {
17652
17853
  return c.html(html.html`
@@ -18020,7 +18221,7 @@ adminMediaRoutes.put("/:id", async (c) => {
18020
18221
  `);
18021
18222
  }
18022
18223
  });
18023
- adminMediaRoutes.delete("/cleanup", chunkAAWNRBRB_cjs.requireRole("admin"), async (c) => {
18224
+ adminMediaRoutes.delete("/cleanup", chunk4SHNHNRP_cjs.requireRole("admin"), async (c) => {
18024
18225
  try {
18025
18226
  const db = c.env.DB;
18026
18227
  const allMediaStmt = db.prepare("SELECT id, r2_key, filename FROM media WHERE deleted_at IS NULL");
@@ -18278,7 +18479,7 @@ function generateMediaItemHTML(file) {
18278
18479
  }
18279
18480
 
18280
18481
  // src/templates/pages/admin-plugins-list.template.ts
18281
- chunkNAVPFIG5_cjs.init_admin_layout_catalyst_template();
18482
+ chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
18282
18483
  function renderPluginsListPage(data) {
18283
18484
  const categories = [
18284
18485
  { value: "content", label: "Content Management" },
@@ -18761,7 +18962,7 @@ function renderPluginsListPage(data) {
18761
18962
  version: data.version,
18762
18963
  content: pageContent
18763
18964
  };
18764
- return chunkNAVPFIG5_cjs.renderAdminLayoutCatalyst(layoutData);
18965
+ return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
18765
18966
  }
18766
18967
  function renderPluginCard(plugin) {
18767
18968
  const statusColors = {
@@ -19139,6 +19340,8 @@ function escapeHtmlAttr(value) {
19139
19340
  }
19140
19341
  function renderPluginSettingsPage(data) {
19141
19342
  const { plugin, activity = [], user } = data;
19343
+ const hasUserSettings = Object.keys(plugin.settings || {}).some((k) => !k.startsWith("_"));
19344
+ const defaultTab = hasUserSettings ? "settings" : "info";
19142
19345
  const pageContent = `
19143
19346
  <div class="w-full px-4 sm:px-6 lg:px-8 py-6">
19144
19347
  <!-- Header with Back Button -->
@@ -19149,13 +19352,24 @@ function renderPluginSettingsPage(data) {
19149
19352
  ${plugin.description}
19150
19353
  </p>
19151
19354
  </div>
19152
- <div class="mt-4 sm:mt-0 sm:ml-16 sm:flex-none">
19355
+ <div class="mt-4 sm:mt-0 sm:ml-16 flex items-center gap-3">
19153
19356
  <a href="/admin/plugins" class="inline-flex items-center justify-center rounded-lg bg-white dark:bg-zinc-800 px-3.5 py-2.5 text-sm font-semibold text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 hover:bg-zinc-50 dark:hover:bg-zinc-700 transition-colors shadow-sm">
19154
19357
  <svg class="-ml-0.5 mr-1.5 h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
19155
19358
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"/>
19156
19359
  </svg>
19157
19360
  Back to Plugins
19158
19361
  </a>
19362
+ ${plugin.settings?._adminPath ? `
19363
+ <a
19364
+ href="${plugin.settings._adminPath}"
19365
+ class="inline-flex items-center justify-center gap-1.5 rounded-lg bg-gradient-to-r from-cyan-500 to-purple-600 hover:from-cyan-400 hover:to-purple-500 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm transition-all duration-200"
19366
+ >
19367
+ <svg class="-ml-0.5 h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
19368
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"/>
19369
+ </svg>
19370
+ View Page
19371
+ </a>
19372
+ ` : ""}
19159
19373
  </div>
19160
19374
  </div>
19161
19375
 
@@ -19188,23 +19402,25 @@ function renderPluginSettingsPage(data) {
19188
19402
  <!-- Tabs -->
19189
19403
  <div class="mb-6">
19190
19404
  <nav class="flex space-x-8" aria-label="Tabs">
19191
- <button onclick="showTab('settings')" id="settings-tab" class="tab-button active border-b-2 border-blue-400 py-2 px-1 text-sm font-medium text-blue-400">
19405
+ ${hasUserSettings ? `
19406
+ <a href="#settings" onclick="showTab('settings')" id="settings-tab" class="tab-button border-b-2 border-transparent py-2 px-1 text-sm font-medium text-gray-400 hover:text-gray-300">
19192
19407
  Settings
19193
- </button>
19194
- <button onclick="showTab('activity')" id="activity-tab" class="tab-button border-b-2 border-transparent py-2 px-1 text-sm font-medium text-gray-400 hover:text-gray-300">
19195
- Activity Log
19196
- </button>
19197
- <button onclick="showTab('info')" id="info-tab" class="tab-button border-b-2 border-transparent py-2 px-1 text-sm font-medium text-gray-400 hover:text-gray-300">
19408
+ </a>
19409
+ ` : ""}
19410
+ <a href="#info" onclick="showTab('info')" id="info-tab" class="tab-button border-b-2 border-transparent py-2 px-1 text-sm font-medium text-gray-400 hover:text-gray-300">
19198
19411
  Information
19199
- </button>
19412
+ </a>
19413
+ <a href="#activity" onclick="showTab('activity')" id="activity-tab" class="tab-button border-b-2 border-transparent py-2 px-1 text-sm font-medium text-gray-400 hover:text-gray-300">
19414
+ Activity Log
19415
+ </a>
19200
19416
  </nav>
19201
19417
  </div>
19202
19418
 
19203
19419
  <!-- Tab Content -->
19204
19420
  <div id="tab-content">
19205
19421
  <!-- Settings Tab -->
19206
- <div id="settings-content" class="tab-content">
19207
- ${renderSettingsTab(plugin)}
19422
+ <div id="settings-content" class="tab-content hidden">
19423
+ ${hasUserSettings ? renderSettingsTab(plugin) : ""}
19208
19424
  </div>
19209
19425
 
19210
19426
  <!-- Activity Tab -->
@@ -19220,27 +19436,42 @@ function renderPluginSettingsPage(data) {
19220
19436
  </div>
19221
19437
 
19222
19438
  <script>
19439
+ const VALID_TABS = [${hasUserSettings ? "'settings', " : ""}'activity', 'info'];
19440
+
19223
19441
  function showTab(tabName) {
19224
- // Hide all tab contents
19442
+ if (!VALID_TABS.includes(tabName)) tabName = '${defaultTab}';
19443
+
19225
19444
  document.querySelectorAll('.tab-content').forEach(content => {
19226
19445
  content.classList.add('hidden');
19227
19446
  });
19228
-
19229
- // Remove active class from all tabs
19447
+
19230
19448
  document.querySelectorAll('.tab-button').forEach(tab => {
19231
19449
  tab.classList.remove('active', 'border-blue-400', 'text-blue-400');
19232
19450
  tab.classList.add('border-transparent', 'text-gray-400');
19233
19451
  });
19234
-
19235
- // Show selected tab content
19236
- document.getElementById(tabName + '-content').classList.remove('hidden');
19237
-
19238
- // Add active class to selected tab
19452
+
19453
+ const contentEl = document.getElementById(tabName + '-content');
19454
+ if (contentEl) contentEl.classList.remove('hidden');
19455
+
19239
19456
  const activeTab = document.getElementById(tabName + '-tab');
19240
- activeTab.classList.add('active', 'border-blue-400', 'text-blue-400');
19241
- activeTab.classList.remove('border-transparent', 'text-gray-400');
19457
+ if (activeTab) {
19458
+ activeTab.classList.add('active', 'border-blue-400', 'text-blue-400');
19459
+ activeTab.classList.remove('border-transparent', 'text-gray-400');
19460
+ }
19461
+
19462
+ if (window.location.hash !== '#' + tabName) {
19463
+ history.replaceState(null, '', '#' + tabName);
19464
+ }
19242
19465
  }
19243
19466
 
19467
+ function initTabFromHash() {
19468
+ const hash = window.location.hash.replace('#', '');
19469
+ showTab(VALID_TABS.includes(hash) ? hash : '${defaultTab}');
19470
+ }
19471
+
19472
+ window.addEventListener('hashchange', initTabFromHash);
19473
+ initTabFromHash();
19474
+
19244
19475
  async function togglePlugin(pluginId, action) {
19245
19476
  const button = event.target;
19246
19477
  const originalText = button.textContent;
@@ -19385,7 +19616,7 @@ function renderPluginSettingsPage(data) {
19385
19616
  user,
19386
19617
  content: pageContent
19387
19618
  };
19388
- return chunkMVIZJOO5_cjs.renderAdminLayout(layoutData);
19619
+ return chunkPXNTCCPE_cjs.renderAdminLayout(layoutData);
19389
19620
  }
19390
19621
  function renderStatusBadge(status) {
19391
19622
  const statusColors = {
@@ -19413,6 +19644,7 @@ function renderToggleButton(plugin) {
19413
19644
  function renderSettingsTab(plugin) {
19414
19645
  const settings = plugin.settings || {};
19415
19646
  const pluginId = plugin.id || plugin.name;
19647
+ const hasUserKeys = Object.keys(settings).some((k) => !k.startsWith("_"));
19416
19648
  const customRenderer = pluginSettingsComponents[pluginId];
19417
19649
  if (customRenderer) {
19418
19650
  return `
@@ -19448,9 +19680,9 @@ function renderSettingsTab(plugin) {
19448
19680
  `}
19449
19681
 
19450
19682
  <form id="settings-form" class="space-y-6">
19451
- ${isAuthPlugin && Object.keys(settings).length > 0 ? renderAuthSettingsForm(settings) : isTurnstilePlugin && Object.keys(settings).length > 0 ? renderTurnstileSettingsForm(settings) : Object.keys(settings).length > 0 ? renderSettingsFields(settings) : renderNoSettings(plugin)}
19683
+ ${isAuthPlugin && hasUserKeys ? renderAuthSettingsForm(settings) : isTurnstilePlugin && hasUserKeys ? renderTurnstileSettingsForm(settings) : hasUserKeys ? renderSettingsFields(settings) : renderNoSettings(plugin)}
19452
19684
 
19453
- ${Object.keys(settings).length > 0 ? `
19685
+ ${hasUserKeys ? `
19454
19686
  <div class="flex items-center justify-end pt-6 border-t border-white/10">
19455
19687
  <button
19456
19688
  type="button"
@@ -19467,7 +19699,7 @@ function renderSettingsTab(plugin) {
19467
19699
  `;
19468
19700
  }
19469
19701
  function renderSettingsFields(settings) {
19470
- return Object.entries(settings).map(([key, value]) => {
19702
+ return Object.entries(settings).filter(([key]) => !key.startsWith("_")).map(([key, value]) => {
19471
19703
  const fieldId = `setting_${key}`;
19472
19704
  const displayName = key.replace(/([A-Z])/g, " $1").replace(/^./, (str) => str.toUpperCase());
19473
19705
  if (typeof value === "boolean") {
@@ -19656,6 +19888,38 @@ function renderActivityTab(activity) {
19656
19888
  }
19657
19889
  function renderInformationTab(plugin) {
19658
19890
  return `
19891
+ ${plugin.description ? `
19892
+ <!-- About -->
19893
+ <div class="backdrop-blur-md bg-black/20 rounded-xl border border-white/10 shadow-xl p-6 mb-6">
19894
+ <h2 class="text-xl font-semibold text-white mb-3">About</h2>
19895
+ <p class="text-gray-300 leading-relaxed">${plugin.description}</p>
19896
+ </div>
19897
+ ` : ""}
19898
+
19899
+ ${(plugin.settings?._routes?.length ?? 0) > 0 ? `
19900
+ <!-- Routes -->
19901
+ <div class="backdrop-blur-md bg-black/20 rounded-xl border border-white/10 shadow-xl p-6 mb-6">
19902
+ <h2 class="text-xl font-semibold text-white mb-4">Routes</h2>
19903
+ <div class="space-y-2">
19904
+ ${plugin.settings._routes.map((r) => {
19905
+ const badge = r.method === "GET" ? "bg-emerald-500/20 text-emerald-300 border border-emerald-500/30" : r.method === "POST" ? "bg-blue-500/20 text-blue-300 border border-blue-500/30" : r.method === "DELETE" ? "bg-red-500/20 text-red-300 border border-red-500/30" : "bg-white/10 text-gray-300 border border-white/20";
19906
+ const pathHtml = r.method === "GET" ? `<a href="${r.path}" class="font-mono text-sm text-blue-400 hover:text-blue-300 hover:underline">${r.path}</a>` : `<span class="font-mono text-sm text-gray-200">${r.path}</span>`;
19907
+ const authBadge = r.requiresAuth ? `<span class="ml-2 text-xs text-amber-400/80">\u{1F512} auth</span>` : "";
19908
+ return `
19909
+ <div class="flex items-start gap-3 py-2 border-b border-white/5 last:border-0">
19910
+ <span class="shrink-0 inline-block px-2 py-0.5 rounded text-xs font-bold ${badge}">${r.method}</span>
19911
+ <div class="min-w-0">
19912
+ <div class="flex items-center gap-1 flex-wrap">
19913
+ ${pathHtml}${authBadge}
19914
+ </div>
19915
+ ${r.description ? `<p class="text-xs text-gray-400 mt-0.5">${r.description}</p>` : ""}
19916
+ </div>
19917
+ </div>`;
19918
+ }).join("")}
19919
+ </div>
19920
+ </div>
19921
+ ` : ""}
19922
+
19659
19923
  <div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
19660
19924
  <!-- Plugin Details -->
19661
19925
  <div class="backdrop-blur-md bg-black/20 rounded-xl border border-white/10 shadow-xl p-6">
@@ -20453,8 +20717,8 @@ defineUserProfile({
20453
20717
 
20454
20718
  // src/routes/admin-plugins.ts
20455
20719
  var adminPluginRoutes = new hono.Hono();
20456
- adminPluginRoutes.use("*", chunkAAWNRBRB_cjs.requireAuth());
20457
- var AVAILABLE_PLUGINS = Object.values(chunkQAYFOER6_cjs.PLUGIN_REGISTRY).map((p) => ({
20720
+ adminPluginRoutes.use("*", chunk4SHNHNRP_cjs.requireAuth());
20721
+ var AVAILABLE_PLUGINS = Object.values(chunk5ARIHAGN_cjs.PLUGIN_REGISTRY).map((p) => ({
20458
20722
  id: p.id,
20459
20723
  name: p.codeName,
20460
20724
  display_name: p.displayName,
@@ -20474,7 +20738,7 @@ adminPluginRoutes.get("/", async (c) => {
20474
20738
  if (user?.role !== "admin") {
20475
20739
  return c.text("Access denied", 403);
20476
20740
  }
20477
- const pluginService = new chunkQAYFOER6_cjs.PluginService(db);
20741
+ const pluginService = new chunk5ARIHAGN_cjs.PluginService(db);
20478
20742
  let installedPlugins = [];
20479
20743
  let stats = { total: 0, active: 0, inactive: 0, errors: 0, uninstalled: 0 };
20480
20744
  try {
@@ -20546,10 +20810,10 @@ adminPluginRoutes.get("/:id", async (c) => {
20546
20810
  if (user?.role !== "admin") {
20547
20811
  return c.redirect("/admin/plugins");
20548
20812
  }
20549
- const pluginService = new chunkQAYFOER6_cjs.PluginService(db);
20813
+ const pluginService = new chunk5ARIHAGN_cjs.PluginService(db);
20550
20814
  let plugin = await pluginService.getPlugin(pluginId);
20551
20815
  if (!plugin) {
20552
- const def = chunkXW56B23A_cjs.getPluginDefinition(pluginId);
20816
+ const def = chunk5RSB5SEK_cjs.getPluginDefinition(pluginId);
20553
20817
  if (!def) return c.text("Plugin not found", 404);
20554
20818
  plugin = await pluginService.ensurePlugin(pluginId, {
20555
20819
  displayName: def.displayName ?? pluginId,
@@ -20561,7 +20825,7 @@ adminPluginRoutes.get("/:id", async (c) => {
20561
20825
  const activity = await pluginService.getPluginActivity(pluginId, 20);
20562
20826
  let enrichedSettings = plugin.settings || {};
20563
20827
  if (pluginId === "otp-login") {
20564
- const settingsService = new chunkBDDABDAB_cjs.SettingsService(db);
20828
+ const settingsService = new chunk36Z3AKX3_cjs.SettingsService(db);
20565
20829
  const generalSettings = await settingsService.getGeneralSettings();
20566
20830
  const siteName = generalSettings.siteName || "SonicJS";
20567
20831
  const emailPlugin = await db.prepare(`
@@ -20640,14 +20904,14 @@ adminPluginRoutes.get("/:id/configure", async (c) => {
20640
20904
  const user = c.get("user");
20641
20905
  const pluginId = c.req.param("id");
20642
20906
  if (user?.role !== "admin") return c.redirect("/admin/plugins");
20643
- const def = chunkXW56B23A_cjs.getPluginDefinition(pluginId);
20907
+ const def = chunk5RSB5SEK_cjs.getPluginDefinition(pluginId);
20644
20908
  if (!def?.configSchema) return c.text("No schema-driven settings for this plugin", 404);
20645
20909
  const db = c.env.DB;
20646
- const pluginService = new chunkQAYFOER6_cjs.PluginService(db);
20910
+ const pluginService = new chunk5ARIHAGN_cjs.PluginService(db);
20647
20911
  const plugin = await pluginService.getPlugin(pluginId);
20648
20912
  const stored = plugin?.settings ?? {};
20649
- const values = chunkXW56B23A_cjs.applySchemaDefaults(def.configSchema, stored);
20650
- const fieldsHtml = chunkXW56B23A_cjs.renderSchemaFields(def.configSchema, values);
20913
+ const values = chunk5RSB5SEK_cjs.applySchemaDefaults(def.configSchema, stored);
20914
+ const fieldsHtml = chunk5RSB5SEK_cjs.renderSchemaFields(def.configSchema, values);
20651
20915
  const displayName = plugin?.display_name ?? def.displayName ?? def.id;
20652
20916
  return c.html(`<!DOCTYPE html>
20653
20917
  <html lang="en"><head>
@@ -20674,19 +20938,21 @@ adminPluginRoutes.post("/:id/configure", async (c) => {
20674
20938
  const user = c.get("user");
20675
20939
  const pluginId = c.req.param("id");
20676
20940
  if (user?.role !== "admin") return c.json({ error: "Access denied" }, 403);
20677
- const def = chunkXW56B23A_cjs.getPluginDefinition(pluginId);
20941
+ const def = chunk5RSB5SEK_cjs.getPluginDefinition(pluginId);
20678
20942
  if (!def?.configSchema) return c.text("No schema-driven settings for this plugin", 404);
20679
20943
  const form = await c.req.formData();
20680
- const parsed = chunkXW56B23A_cjs.parseFormDataToSettings(def.configSchema, form);
20944
+ const parsed = chunk5RSB5SEK_cjs.parseFormDataToSettings(def.configSchema, form);
20681
20945
  const db = c.env.DB;
20682
- const pluginService = new chunkQAYFOER6_cjs.PluginService(db);
20946
+ const pluginService = new chunk5ARIHAGN_cjs.PluginService(db);
20683
20947
  await pluginService.ensurePlugin(pluginId, {
20684
20948
  displayName: def.displayName ?? pluginId,
20685
20949
  version: def.version,
20686
20950
  description: def.description,
20687
20951
  author: typeof def.author === "object" ? def.author?.name : def.author
20688
20952
  });
20689
- await pluginService.updatePluginSettings(pluginId, parsed);
20953
+ const existingPlugin = await pluginService.getPlugin(pluginId);
20954
+ const existingSettings = existingPlugin?.settings ?? {};
20955
+ await pluginService.updatePluginSettings(pluginId, { ...existingSettings, ...parsed });
20690
20956
  return c.redirect(`/admin/plugins/${encodeURIComponent(pluginId)}/configure`);
20691
20957
  } catch (error) {
20692
20958
  console.error("Error saving schema settings:", error);
@@ -20701,7 +20967,7 @@ adminPluginRoutes.post("/:id/activate", async (c) => {
20701
20967
  if (user?.role !== "admin") {
20702
20968
  return c.json({ error: "Access denied" }, 403);
20703
20969
  }
20704
- const pluginService = new chunkQAYFOER6_cjs.PluginService(db);
20970
+ const pluginService = new chunk5ARIHAGN_cjs.PluginService(db);
20705
20971
  await pluginService.activatePlugin(pluginId);
20706
20972
  return c.json({ success: true });
20707
20973
  } catch (error) {
@@ -20718,7 +20984,7 @@ adminPluginRoutes.post("/:id/deactivate", async (c) => {
20718
20984
  if (user?.role !== "admin") {
20719
20985
  return c.json({ error: "Access denied" }, 403);
20720
20986
  }
20721
- const pluginService = new chunkQAYFOER6_cjs.PluginService(db);
20987
+ const pluginService = new chunk5ARIHAGN_cjs.PluginService(db);
20722
20988
  await pluginService.deactivatePlugin(pluginId);
20723
20989
  return c.json({ success: true });
20724
20990
  } catch (error) {
@@ -20735,8 +21001,8 @@ adminPluginRoutes.post("/install", async (c) => {
20735
21001
  return c.json({ error: "Access denied" }, 403);
20736
21002
  }
20737
21003
  const body = await c.req.json();
20738
- const pluginService = new chunkQAYFOER6_cjs.PluginService(db);
20739
- const registryEntry = chunkQAYFOER6_cjs.findPluginByCodeName(body.name) || chunkQAYFOER6_cjs.PLUGIN_REGISTRY[body.name] || chunkQAYFOER6_cjs.PLUGIN_REGISTRY[body.id];
21004
+ const pluginService = new chunk5ARIHAGN_cjs.PluginService(db);
21005
+ const registryEntry = chunk5ARIHAGN_cjs.findPluginByCodeName(body.name) || chunk5ARIHAGN_cjs.PLUGIN_REGISTRY[body.name] || chunk5ARIHAGN_cjs.PLUGIN_REGISTRY[body.id];
20740
21006
  if (!registryEntry) {
20741
21007
  return c.json({ error: "Plugin not found in registry" }, 404);
20742
21008
  }
@@ -20769,7 +21035,7 @@ adminPluginRoutes.post("/:id/uninstall", async (c) => {
20769
21035
  if (user?.role !== "admin") {
20770
21036
  return c.json({ error: "Access denied" }, 403);
20771
21037
  }
20772
- const pluginService = new chunkQAYFOER6_cjs.PluginService(db);
21038
+ const pluginService = new chunk5ARIHAGN_cjs.PluginService(db);
20773
21039
  await pluginService.uninstallPlugin(pluginId);
20774
21040
  return c.json({ success: true });
20775
21041
  } catch (error) {
@@ -20787,7 +21053,7 @@ adminPluginRoutes.post("/:id/settings", async (c) => {
20787
21053
  return c.json({ error: "Access denied" }, 403);
20788
21054
  }
20789
21055
  const settings = await c.req.json();
20790
- const pluginService = new chunkQAYFOER6_cjs.PluginService(db);
21056
+ const pluginService = new chunk5ARIHAGN_cjs.PluginService(db);
20791
21057
  await pluginService.updatePluginSettings(pluginId, settings);
20792
21058
  if (pluginId === "core-auth") {
20793
21059
  try {
@@ -20820,7 +21086,7 @@ function formatLastUpdated(timestamp) {
20820
21086
  }
20821
21087
 
20822
21088
  // src/templates/pages/admin-logs-list.template.ts
20823
- chunkNAVPFIG5_cjs.init_admin_layout_catalyst_template();
21089
+ chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
20824
21090
  function renderLogsListPage(data) {
20825
21091
  const { logs, pagination, filters, user } = data;
20826
21092
  const content = `
@@ -21131,7 +21397,7 @@ function renderLogsListPage(data) {
21131
21397
  user,
21132
21398
  content
21133
21399
  };
21134
- return chunkNAVPFIG5_cjs.renderAdminLayoutCatalyst(layoutData);
21400
+ return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
21135
21401
  }
21136
21402
  function renderLogDetailsPage(data) {
21137
21403
  const { log, user } = data;
@@ -21343,7 +21609,7 @@ function renderLogDetailsPage(data) {
21343
21609
  </div>
21344
21610
  </div>
21345
21611
  `;
21346
- return chunkMVIZJOO5_cjs.adminLayoutV2({
21612
+ return chunkPXNTCCPE_cjs.adminLayoutV2({
21347
21613
  title: `Log Details - ${log.id}`,
21348
21614
  user,
21349
21615
  content
@@ -21586,7 +21852,7 @@ function renderLogConfigPage(data) {
21586
21852
 
21587
21853
  <script src="https://unpkg.com/htmx.org@1.9.6"></script>
21588
21854
  `;
21589
- return chunkMVIZJOO5_cjs.adminLayoutV2({
21855
+ return chunkPXNTCCPE_cjs.adminLayoutV2({
21590
21856
  title: "Log Configuration",
21591
21857
  user,
21592
21858
  content
@@ -21595,11 +21861,11 @@ function renderLogConfigPage(data) {
21595
21861
 
21596
21862
  // src/routes/admin-logs.ts
21597
21863
  var adminLogsRoutes = new hono.Hono();
21598
- adminLogsRoutes.use("*", chunkAAWNRBRB_cjs.requireAuth());
21864
+ adminLogsRoutes.use("*", chunk4SHNHNRP_cjs.requireAuth());
21599
21865
  adminLogsRoutes.get("/", async (c) => {
21600
21866
  try {
21601
21867
  const user = c.get("user");
21602
- const logger = chunkBDDABDAB_cjs.getLogger(c.env.DB);
21868
+ const logger = chunk36Z3AKX3_cjs.getLogger(c.env.DB);
21603
21869
  const query = c.req.query();
21604
21870
  const page = parseInt(query.page || "1");
21605
21871
  const limit = parseInt(query.limit || "50");
@@ -21679,7 +21945,7 @@ adminLogsRoutes.get("/:id", async (c) => {
21679
21945
  try {
21680
21946
  const id = c.req.param("id");
21681
21947
  const user = c.get("user");
21682
- const logger = chunkBDDABDAB_cjs.getLogger(c.env.DB);
21948
+ const logger = chunk36Z3AKX3_cjs.getLogger(c.env.DB);
21683
21949
  const { logs } = await logger.getLogs({
21684
21950
  limit: 1,
21685
21951
  offset: 0,
@@ -21716,7 +21982,7 @@ adminLogsRoutes.get("/:id", async (c) => {
21716
21982
  adminLogsRoutes.get("/config", async (c) => {
21717
21983
  try {
21718
21984
  const user = c.get("user");
21719
- const logger = chunkBDDABDAB_cjs.getLogger(c.env.DB);
21985
+ const logger = chunk36Z3AKX3_cjs.getLogger(c.env.DB);
21720
21986
  const configs = await logger.getAllConfigs();
21721
21987
  const pageData = {
21722
21988
  configs,
@@ -21740,7 +22006,7 @@ adminLogsRoutes.post("/config/:category", async (c) => {
21740
22006
  const level = formData.get("level");
21741
22007
  const retention = parseInt(formData.get("retention"));
21742
22008
  const maxSize = parseInt(formData.get("max_size"));
21743
- const logger = chunkBDDABDAB_cjs.getLogger(c.env.DB);
22009
+ const logger = chunk36Z3AKX3_cjs.getLogger(c.env.DB);
21744
22010
  await logger.updateConfig(category, {
21745
22011
  enabled,
21746
22012
  level,
@@ -21769,7 +22035,7 @@ adminLogsRoutes.get("/export", async (c) => {
21769
22035
  const category = query.category;
21770
22036
  const startDate = query.start_date;
21771
22037
  const endDate = query.end_date;
21772
- const logger = chunkBDDABDAB_cjs.getLogger(c.env.DB);
22038
+ const logger = chunk36Z3AKX3_cjs.getLogger(c.env.DB);
21773
22039
  const filter = {
21774
22040
  limit: 1e4,
21775
22041
  // Export up to 10k logs
@@ -21850,7 +22116,7 @@ adminLogsRoutes.post("/cleanup", async (c) => {
21850
22116
  error: "Unauthorized. Admin access required."
21851
22117
  }, 403);
21852
22118
  }
21853
- const logger = chunkBDDABDAB_cjs.getLogger(c.env.DB);
22119
+ const logger = chunk36Z3AKX3_cjs.getLogger(c.env.DB);
21854
22120
  await logger.cleanupByRetention();
21855
22121
  return c.html(html.html`
21856
22122
  <div class="bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded">
@@ -21872,7 +22138,7 @@ adminLogsRoutes.post("/search", async (c) => {
21872
22138
  const search = formData.get("search");
21873
22139
  const level = formData.get("level");
21874
22140
  const category = formData.get("category");
21875
- const logger = chunkBDDABDAB_cjs.getLogger(c.env.DB);
22141
+ const logger = chunk36Z3AKX3_cjs.getLogger(c.env.DB);
21876
22142
  const filter = {
21877
22143
  limit: 20,
21878
22144
  offset: 0,
@@ -21967,7 +22233,7 @@ adminCheckboxRoutes.get("/", (c) => {
21967
22233
  role: user.role
21968
22234
  } : void 0
21969
22235
  };
21970
- return c.html(chunkMVIZJOO5_cjs.renderCheckboxPage(pageData));
22236
+ return c.html(chunkPXNTCCPE_cjs.renderCheckboxPage(pageData));
21971
22237
  });
21972
22238
 
21973
22239
  // src/templates/pages/admin-dashboard.template.ts
@@ -22039,7 +22305,7 @@ function renderDashboardPage(data) {
22039
22305
  version: data.version,
22040
22306
  content: pageContent
22041
22307
  };
22042
- return chunkMVIZJOO5_cjs.renderAdminLayout(layoutData);
22308
+ return chunkPXNTCCPE_cjs.renderAdminLayout(layoutData);
22043
22309
  }
22044
22310
  function renderStatsCards(stats) {
22045
22311
  const cards = [
@@ -22587,9 +22853,9 @@ function renderStorageUsage(databaseSizeBytes, mediaSizeBytes) {
22587
22853
  }
22588
22854
 
22589
22855
  // src/routes/admin-dashboard.ts
22590
- var VERSION = chunkLRZIAW7U_cjs.getCoreVersion();
22856
+ var VERSION = chunkAQJEMVAY_cjs.getCoreVersion();
22591
22857
  var router = new hono.Hono();
22592
- router.use("*", chunkAAWNRBRB_cjs.requireAuth());
22858
+ router.use("*", chunk4SHNHNRP_cjs.requireAuth());
22593
22859
  router.get("/", async (c) => {
22594
22860
  const user = c.get("user");
22595
22861
  try {
@@ -22779,7 +23045,7 @@ router.get("/system-status", async (c) => {
22779
23045
  });
22780
23046
 
22781
23047
  // src/templates/pages/admin-collections-list.template.ts
22782
- chunkNAVPFIG5_cjs.init_admin_layout_catalyst_template();
23048
+ chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
22783
23049
 
22784
23050
  // src/templates/components/table.template.ts
22785
23051
  function renderTable2(data) {
@@ -23261,11 +23527,11 @@ function renderCollectionsListPage(data) {
23261
23527
  version: data.version,
23262
23528
  content: pageContent
23263
23529
  };
23264
- return chunkNAVPFIG5_cjs.renderAdminLayoutCatalyst(layoutData);
23530
+ return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
23265
23531
  }
23266
23532
 
23267
23533
  // src/templates/pages/admin-collections-form.template.ts
23268
- chunkNAVPFIG5_cjs.init_admin_layout_catalyst_template();
23534
+ chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
23269
23535
  function getFieldTypeBadge(fieldType) {
23270
23536
  const typeLabels = {
23271
23537
  "text": "Text",
@@ -23438,8 +23704,8 @@ function renderCollectionFormPage(data) {
23438
23704
  <!-- Form Content -->
23439
23705
  <div class="px-6 py-6">
23440
23706
  <div id="form-messages"></div>
23441
- ${data.error ? chunkDNQCEKUK_cjs.renderAlert({ type: "error", message: data.error, dismissible: true }) : ""}
23442
- ${data.success ? chunkDNQCEKUK_cjs.renderAlert({ type: "success", message: data.success, dismissible: true }) : ""}
23707
+ ${data.error ? chunkN32OWET6_cjs.renderAlert({ type: "error", message: data.error, dismissible: true }) : ""}
23708
+ ${data.success ? chunkN32OWET6_cjs.renderAlert({ type: "success", message: data.success, dismissible: true }) : ""}
23443
23709
 
23444
23710
  <!-- Form Styling -->
23445
23711
  <style>
@@ -23550,7 +23816,7 @@ function renderCollectionFormPage(data) {
23550
23816
  }
23551
23817
  </style>
23552
23818
 
23553
- ${chunkMVIZJOO5_cjs.renderForm(formData)}
23819
+ ${chunkPXNTCCPE_cjs.renderForm(formData)}
23554
23820
 
23555
23821
  ${isEdit && data.managed ? `
23556
23822
  <!-- Read-Only Fields Display for Managed Collections -->
@@ -24548,13 +24814,13 @@ function renderCollectionFormPage(data) {
24548
24814
  version: data.version,
24549
24815
  content: pageContent
24550
24816
  };
24551
- return chunkNAVPFIG5_cjs.renderAdminLayoutCatalyst(layoutData);
24817
+ return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
24552
24818
  }
24553
24819
 
24554
24820
  // src/routes/admin-collections.ts
24555
- chunkNAVPFIG5_cjs.init_admin_layout_catalyst_template();
24821
+ chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
24556
24822
  var adminCollectionsRoutes = new hono.Hono();
24557
- adminCollectionsRoutes.use("*", chunkAAWNRBRB_cjs.requireAuth());
24823
+ adminCollectionsRoutes.use("*", chunk4SHNHNRP_cjs.requireAuth());
24558
24824
  adminCollectionsRoutes.get("/", async (c) => {
24559
24825
  try {
24560
24826
  const user = c.get("user");
@@ -24571,7 +24837,7 @@ adminCollectionsRoutes.get("/", async (c) => {
24571
24837
  results = queryResults.results ?? [];
24572
24838
  } catch (e) {
24573
24839
  }
24574
- const codeCollections = chunkQAYFOER6_cjs.getCollectionRegistry().list();
24840
+ const codeCollections = chunk5ARIHAGN_cjs.getCollectionRegistry().list();
24575
24841
  const codeCollectionsMap = new Map(
24576
24842
  codeCollections.map((cfg) => {
24577
24843
  const fieldCount = cfg.schema?.properties ? Object.keys(cfg.schema.properties).length : 0;
@@ -24585,7 +24851,7 @@ adminCollectionsRoutes.get("/", async (c) => {
24585
24851
  field_count: fieldCount,
24586
24852
  managed: cfg.managed !== false,
24587
24853
  source_type: "code",
24588
- internal: chunkQAYFOER6_cjs.isCodeCollectionInternal(cfg),
24854
+ internal: chunk5ARIHAGN_cjs.isCodeCollectionInternal(cfg),
24589
24855
  versioning: cfg.versioning === true
24590
24856
  }];
24591
24857
  })
@@ -24624,7 +24890,7 @@ adminCollectionsRoutes.get("/", async (c) => {
24624
24890
  field_count: fieldCount,
24625
24891
  managed: false,
24626
24892
  source_type: row.source === "code" || row.source === "system" || row.source === "plugin" ? "code" : "user",
24627
- internal: chunkQAYFOER6_cjs.isDbDocTypeInternal(row.source),
24893
+ internal: chunk5ARIHAGN_cjs.isDbDocTypeInternal(row.source),
24628
24894
  versioning: dbVersioning
24629
24895
  };
24630
24896
  });
@@ -24781,11 +25047,11 @@ export const myPlugin = definePlugin({
24781
25047
  `;
24782
25048
  const u = user;
24783
25049
  return c.html(
24784
- chunkNAVPFIG5_cjs.renderAdminLayoutCatalyst({
25050
+ chunkK623Q6WD_cjs.renderAdminLayoutCatalyst({
24785
25051
  title: "Add a Collection",
24786
25052
  pageTitle: "Add a Collection",
24787
25053
  currentPath: "/admin/collections",
24788
- version: chunkLRZIAW7U_cjs.getCoreVersion(),
25054
+ version: chunkAQJEMVAY_cjs.getCoreVersion(),
24789
25055
  user: u ? { name: u.email ?? "Admin", email: u.email ?? "", role: u.role ?? "admin" } : void 0,
24790
25056
  content
24791
25057
  })
@@ -24802,7 +25068,7 @@ adminCollectionsRoutes.get("/:id", async (c) => {
24802
25068
  collection = await stmt.bind(id).first();
24803
25069
  } catch {
24804
25070
  }
24805
- const registryRecord = chunkQAYFOER6_cjs.getCollectionRegistry().getById(id) ?? chunkQAYFOER6_cjs.getCollectionRegistry().getByName(id);
25071
+ const registryRecord = chunk5ARIHAGN_cjs.getCollectionRegistry().getById(id) ?? chunk5ARIHAGN_cjs.getCollectionRegistry().getByName(id);
24806
25072
  if (!collection && !registryRecord) {
24807
25073
  const formData2 = {
24808
25074
  isEdit: true,
@@ -24849,9 +25115,9 @@ adminCollectionsRoutes.get("/:id", async (c) => {
24849
25115
  isCodeDriven = true;
24850
25116
  }
24851
25117
  const [tinymceActive, quillActive, mdxeditorActive] = await Promise.all([
24852
- chunkAAWNRBRB_cjs.isPluginActive(db, "tinymce-plugin"),
24853
- chunkAAWNRBRB_cjs.isPluginActive(db, "quill-editor"),
24854
- chunkAAWNRBRB_cjs.isPluginActive(db, "easy-mdx")
25118
+ chunk4SHNHNRP_cjs.isPluginActive(db, "tinymce-plugin"),
25119
+ chunk4SHNHNRP_cjs.isPluginActive(db, "quill-editor"),
25120
+ chunk4SHNHNRP_cjs.isPluginActive(db, "easy-mdx")
24855
25121
  ]);
24856
25122
  const displayName = collection?.display_name ?? registryRecord?.displayName ?? id;
24857
25123
  const formData = {
@@ -24871,9 +25137,9 @@ adminCollectionsRoutes.get("/:id", async (c) => {
24871
25137
  console.error("Error fetching collection:", error);
24872
25138
  const user = c.get("user");
24873
25139
  const [tinymceActive, quillActive, mdxeditorActive] = await Promise.all([
24874
- chunkAAWNRBRB_cjs.isPluginActive(db, "tinymce-plugin"),
24875
- chunkAAWNRBRB_cjs.isPluginActive(db, "quill-editor"),
24876
- chunkAAWNRBRB_cjs.isPluginActive(db, "easy-mdx")
25140
+ chunk4SHNHNRP_cjs.isPluginActive(db, "tinymce-plugin"),
25141
+ chunk4SHNHNRP_cjs.isPluginActive(db, "quill-editor"),
25142
+ chunk4SHNHNRP_cjs.isPluginActive(db, "easy-mdx")
24877
25143
  ]);
24878
25144
  const formData = {
24879
25145
  isEdit: true,
@@ -24887,7 +25153,7 @@ adminCollectionsRoutes.get("/:id", async (c) => {
24887
25153
  });
24888
25154
 
24889
25155
  // src/templates/pages/admin-settings.template.ts
24890
- chunkNAVPFIG5_cjs.init_admin_layout_catalyst_template();
25156
+ chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
24891
25157
  function renderSettingsPage(data) {
24892
25158
  const activeTab = data.activeTab || "general";
24893
25159
  const pageContent = `
@@ -25277,7 +25543,7 @@ function renderSettingsPage(data) {
25277
25543
  version: data.version,
25278
25544
  content: pageContent
25279
25545
  };
25280
- return chunkNAVPFIG5_cjs.renderAdminLayoutCatalyst(layoutData);
25546
+ return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
25281
25547
  }
25282
25548
  function renderTabButton(tabId, label, iconPath, activeTab) {
25283
25549
  const isActive = activeTab === tabId;
@@ -25822,7 +26088,7 @@ function renderDatabaseToolsSettings(settings) {
25822
26088
 
25823
26089
  // src/routes/admin-settings.ts
25824
26090
  var adminSettingsRoutes = new hono.Hono();
25825
- adminSettingsRoutes.use("*", chunkAAWNRBRB_cjs.requireAuth());
26091
+ adminSettingsRoutes.use("*", chunk4SHNHNRP_cjs.requireAuth());
25826
26092
  function getMockSettings(user) {
25827
26093
  return {
25828
26094
  general: {
@@ -25856,7 +26122,7 @@ adminSettingsRoutes.get("/", (c) => {
25856
26122
  adminSettingsRoutes.get("/general", async (c) => {
25857
26123
  const user = c.get("user");
25858
26124
  const db = c.env.DB;
25859
- const settingsService = new chunkBDDABDAB_cjs.SettingsService(db);
26125
+ const settingsService = new chunk36Z3AKX3_cjs.SettingsService(db);
25860
26126
  const generalSettings = await settingsService.getGeneralSettings(user?.email);
25861
26127
  const mockSettings = getMockSettings(user);
25862
26128
  mockSettings.general = generalSettings;
@@ -25875,7 +26141,7 @@ adminSettingsRoutes.get("/general", async (c) => {
25875
26141
  adminSettingsRoutes.get("/security", async (c) => {
25876
26142
  const user = c.get("user");
25877
26143
  const db = c.env.DB;
25878
- const settingsService = new chunkBDDABDAB_cjs.SettingsService(db);
26144
+ const settingsService = new chunk36Z3AKX3_cjs.SettingsService(db);
25879
26145
  const persisted = await settingsService.getSecuritySettings();
25880
26146
  const mockSettings = getMockSettings(user);
25881
26147
  mockSettings.security = {
@@ -25925,7 +26191,7 @@ adminSettingsRoutes.get("/database-tools", (c) => {
25925
26191
  adminSettingsRoutes.get("/api/migrations/status", async (c) => {
25926
26192
  try {
25927
26193
  const db = c.env.DB;
25928
- const migrationService = new chunkDSA4UX5B_cjs.MigrationService(db);
26194
+ const migrationService = new chunkTQG5FNNR_cjs.MigrationService(db);
25929
26195
  const status = await migrationService.getMigrationStatus();
25930
26196
  return c.json({
25931
26197
  success: true,
@@ -25965,7 +26231,7 @@ adminSettingsRoutes.post("/api/migrations/run", async (c) => {
25965
26231
  adminSettingsRoutes.get("/api/migrations/validate", async (c) => {
25966
26232
  try {
25967
26233
  const db = c.env.DB;
25968
- const migrationService = new chunkDSA4UX5B_cjs.MigrationService(db);
26234
+ const migrationService = new chunkTQG5FNNR_cjs.MigrationService(db);
25969
26235
  const validation = await migrationService.validateSchema();
25970
26236
  return c.json({
25971
26237
  success: true,
@@ -26134,7 +26400,7 @@ adminSettingsRoutes.post("/general", async (c) => {
26134
26400
  }
26135
26401
  const formData = await c.req.formData();
26136
26402
  const db = c.env.DB;
26137
- const settingsService = new chunkBDDABDAB_cjs.SettingsService(db);
26403
+ const settingsService = new chunk36Z3AKX3_cjs.SettingsService(db);
26138
26404
  const settings = {
26139
26405
  siteName: formData.get("siteName"),
26140
26406
  siteDescription: formData.get("siteDescription"),
@@ -26180,7 +26446,7 @@ adminSettingsRoutes.post("/security", async (c) => {
26180
26446
  }
26181
26447
  const formData = await c.req.formData();
26182
26448
  const db = c.env.DB;
26183
- const settingsService = new chunkBDDABDAB_cjs.SettingsService(db);
26449
+ const settingsService = new chunk36Z3AKX3_cjs.SettingsService(db);
26184
26450
  const jwtExpiresInRaw = formData.get("jwtExpiresIn")?.trim() || "";
26185
26451
  const graceRaw = formData.get("jwtRefreshGraceSeconds")?.trim() || "";
26186
26452
  if (!/^\d+(?:s|m|h|d)?$/i.test(jwtExpiresInRaw)) {
@@ -26223,7 +26489,7 @@ adminSettingsRoutes.post("/", async (c) => {
26223
26489
  });
26224
26490
 
26225
26491
  // src/templates/pages/admin-api-reference.template.ts
26226
- chunkNAVPFIG5_cjs.init_admin_layout_catalyst_template();
26492
+ chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
26227
26493
  function renderAuthBadge(auth) {
26228
26494
  if (auth === true) {
26229
26495
  return `
@@ -26364,7 +26630,7 @@ function renderAPIReferencePage(data) {
26364
26630
  >
26365
26631
  <option value="">All Categories</option>
26366
26632
  ${categories.map((category) => {
26367
- const info = chunkBDDABDAB_cjs.CATEGORY_INFO[category];
26633
+ const info = chunk36Z3AKX3_cjs.CATEGORY_INFO[category];
26368
26634
  const title = info ? info.title : category;
26369
26635
  return `<option value="${category}">${title}</option>`;
26370
26636
  }).join("\n ")}
@@ -26381,7 +26647,7 @@ function renderAPIReferencePage(data) {
26381
26647
  <!-- API Categories -->
26382
26648
  <div class="space-y-6">
26383
26649
  ${Object.entries(endpointsByCategory).map(([category, endpoints]) => {
26384
- const info = chunkBDDABDAB_cjs.CATEGORY_INFO[category] || { title: category, description: "", icon: "&#x1f4cb;" };
26650
+ const info = chunk36Z3AKX3_cjs.CATEGORY_INFO[category] || { title: category, description: "", icon: "&#x1f4cb;" };
26385
26651
  return `
26386
26652
  <div class="api-category" data-category="${category}">
26387
26653
  <div class="rounded-lg bg-white dark:bg-zinc-900 shadow-sm ring-1 ring-zinc-950/5 dark:ring-white/10 overflow-hidden">
@@ -26554,20 +26820,20 @@ function renderAPIReferencePage(data) {
26554
26820
  version: data.version,
26555
26821
  content: pageContent
26556
26822
  };
26557
- return chunkNAVPFIG5_cjs.renderAdminLayoutCatalyst(layoutData);
26823
+ return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
26558
26824
  }
26559
26825
 
26560
26826
  // src/routes/admin-api-reference.ts
26561
- var VERSION2 = chunkLRZIAW7U_cjs.getCoreVersion();
26827
+ var VERSION2 = chunkAQJEMVAY_cjs.getCoreVersion();
26562
26828
  var router2 = new hono.Hono();
26563
- router2.use("*", chunkAAWNRBRB_cjs.requireAuth());
26829
+ router2.use("*", chunk4SHNHNRP_cjs.requireAuth());
26564
26830
  router2.get("/", async (c) => {
26565
26831
  const user = c.get("user");
26566
26832
  try {
26567
- const app2 = chunkBDDABDAB_cjs.getAppInstance();
26568
- const baseEndpoints = chunkBDDABDAB_cjs.buildRouteList(app2);
26833
+ const app2 = chunk36Z3AKX3_cjs.getAppInstance();
26834
+ const baseEndpoints = chunk36Z3AKX3_cjs.buildRouteList(app2);
26569
26835
  const collectionRoutes = [];
26570
- const collections = chunkQAYFOER6_cjs.getCollectionRegistry().listActive().filter((r) => !r.internal);
26836
+ const collections = chunk5ARIHAGN_cjs.getCollectionRegistry().listActive().filter((r) => !r.internal);
26571
26837
  const methodOrder = { GET: 0, POST: 1, PUT: 2, PATCH: 3, DELETE: 4 };
26572
26838
  for (const col of collections) {
26573
26839
  const displayName = col.displayName || col.name;
@@ -26659,6 +26925,7 @@ exports.api_default = api_default;
26659
26925
  exports.api_media_default = api_media_default;
26660
26926
  exports.api_system_default = api_system_default;
26661
26927
  exports.auth_default = auth_default;
26928
+ exports.createDocumentSchema = createDocumentSchema;
26662
26929
  exports.createUserProfilesPlugin = createUserProfilesPlugin;
26663
26930
  exports.defineUserProfile = defineUserProfile;
26664
26931
  exports.denyIfNotAllowed = denyIfNotAllowed;
@@ -26683,5 +26950,5 @@ exports.setVariablesCache = setVariablesCache;
26683
26950
  exports.test_cleanup_default = test_cleanup_default;
26684
26951
  exports.userProfilesPlugin = userProfilesPlugin;
26685
26952
  exports.userRoutes = userRoutes;
26686
- //# sourceMappingURL=chunk-VXE42MYF.cjs.map
26687
- //# sourceMappingURL=chunk-VXE42MYF.cjs.map
26953
+ //# sourceMappingURL=chunk-3E7IROND.cjs.map
26954
+ //# sourceMappingURL=chunk-3E7IROND.cjs.map