@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
package/dist/index.cjs CHANGED
@@ -1,31 +1,32 @@
1
1
  'use strict';
2
2
 
3
- var chunkNUKJ54GA_cjs = require('./chunk-NUKJ54GA.cjs');
4
- var chunkVXE42MYF_cjs = require('./chunk-VXE42MYF.cjs');
5
- require('./chunk-HIKBY7MS.cjs');
6
- require('./chunk-DNQCEKUK.cjs');
7
- var chunkBDDABDAB_cjs = require('./chunk-BDDABDAB.cjs');
3
+ var chunkGMMCCIQO_cjs = require('./chunk-GMMCCIQO.cjs');
4
+ var chunk3E7IROND_cjs = require('./chunk-3E7IROND.cjs');
5
+ require('./chunk-XWVDSM2L.cjs');
6
+ require('./chunk-N32OWET6.cjs');
7
+ var chunk36Z3AKX3_cjs = require('./chunk-36Z3AKX3.cjs');
8
8
  var chunkYA3TJ65D_cjs = require('./chunk-YA3TJ65D.cjs');
9
9
  var chunkYP7GW2G5_cjs = require('./chunk-YP7GW2G5.cjs');
10
- var chunkAAWNRBRB_cjs = require('./chunk-AAWNRBRB.cjs');
11
- var chunk2CB4KY7I_cjs = require('./chunk-2CB4KY7I.cjs');
12
- var chunkJEQ7FLOD_cjs = require('./chunk-JEQ7FLOD.cjs');
13
- var chunkQAYFOER6_cjs = require('./chunk-QAYFOER6.cjs');
14
- var chunkDSA4UX5B_cjs = require('./chunk-DSA4UX5B.cjs');
15
- var chunkWULONYGB_cjs = require('./chunk-WULONYGB.cjs');
16
- var chunkMVIZJOO5_cjs = require('./chunk-MVIZJOO5.cjs');
17
- var chunkNAVPFIG5_cjs = require('./chunk-NAVPFIG5.cjs');
18
- var chunkH2AXVCLS_cjs = require('./chunk-H2AXVCLS.cjs');
19
- var chunkXW56B23A_cjs = require('./chunk-XW56B23A.cjs');
10
+ var chunk4SHNHNRP_cjs = require('./chunk-4SHNHNRP.cjs');
11
+ var chunkLTZ5WYOK_cjs = require('./chunk-LTZ5WYOK.cjs');
12
+ var chunkKIGVVO6N_cjs = require('./chunk-KIGVVO6N.cjs');
13
+ var chunk5ARIHAGN_cjs = require('./chunk-5ARIHAGN.cjs');
14
+ var chunkTQG5FNNR_cjs = require('./chunk-TQG5FNNR.cjs');
15
+ var chunkCRGUD4KC_cjs = require('./chunk-CRGUD4KC.cjs');
16
+ var chunkPXNTCCPE_cjs = require('./chunk-PXNTCCPE.cjs');
17
+ var chunkK623Q6WD_cjs = require('./chunk-K623Q6WD.cjs');
18
+ var chunkDTGCXWWM_cjs = require('./chunk-DTGCXWWM.cjs');
19
+ var chunk5RSB5SEK_cjs = require('./chunk-5RSB5SEK.cjs');
20
20
  var chunkJ6JTWD2A_cjs = require('./chunk-J6JTWD2A.cjs');
21
21
  var chunkIXUHXTHW_cjs = require('./chunk-IXUHXTHW.cjs');
22
- require('./chunk-P3XDZL6Q.cjs');
23
22
  var chunkRCQ2HIQD_cjs = require('./chunk-RCQ2HIQD.cjs');
24
- var chunkLRZIAW7U_cjs = require('./chunk-LRZIAW7U.cjs');
23
+ require('./chunk-P3XDZL6Q.cjs');
24
+ var chunkAQJEMVAY_cjs = require('./chunk-AQJEMVAY.cjs');
25
25
  var chunkMNWKYY5E_cjs = require('./chunk-MNWKYY5E.cjs');
26
26
  var chunkQTFKZBLC_cjs = require('./chunk-QTFKZBLC.cjs');
27
27
  require('./chunk-IGJUBJBW.cjs');
28
28
  var hono = require('hono');
29
+ var cors = require('hono/cors');
29
30
  var zod = require('zod');
30
31
  var cookie = require('hono/cookie');
31
32
  var html = require('hono/html');
@@ -39,6 +40,7 @@ var DatabaseToolsService = class {
39
40
  constructor(db) {
40
41
  this.db = db;
41
42
  }
43
+ db;
42
44
  /**
43
45
  * Get database statistics
44
46
  */
@@ -249,7 +251,7 @@ var DatabaseToolsService = class {
249
251
  };
250
252
 
251
253
  // src/templates/pages/admin-database-table.template.ts
252
- chunkNAVPFIG5_cjs.init_admin_layout_catalyst_template();
254
+ chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
253
255
  function renderDatabaseTablePage(data) {
254
256
  const totalPages = Math.ceil(data.totalRows / data.pageSize);
255
257
  const startRow = (data.currentPage - 1) * data.pageSize + 1;
@@ -498,7 +500,7 @@ function renderDatabaseTablePage(data) {
498
500
  user: data.user,
499
501
  content: pageContent
500
502
  };
501
- return chunkNAVPFIG5_cjs.renderAdminLayoutCatalyst(layoutData);
503
+ return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
502
504
  }
503
505
  function generatePageNumbers(currentPage, totalPages) {
504
506
  const pages = [];
@@ -573,7 +575,7 @@ function formatCellValue(value) {
573
575
  // src/plugins/core-plugins/database-tools-plugin/admin-routes.ts
574
576
  function createDatabaseToolsAdminRoutes() {
575
577
  const router3 = new hono.Hono();
576
- router3.use("*", chunkAAWNRBRB_cjs.requireAuth());
578
+ router3.use("*", chunk4SHNHNRP_cjs.requireAuth());
577
579
  router3.get("/api/stats", async (c) => {
578
580
  try {
579
581
  const user = c.get("user");
@@ -897,6 +899,7 @@ var EmailSettingsService = class {
897
899
  constructor(db) {
898
900
  this.db = db;
899
901
  }
902
+ db;
900
903
  async load() {
901
904
  let row = null;
902
905
  try {
@@ -925,8 +928,10 @@ var SiteConfigService = class {
925
928
  this.db = db;
926
929
  this.env = env;
927
930
  }
931
+ db;
932
+ env;
928
933
  async load() {
929
- const settings = new chunkBDDABDAB_cjs.SettingsService(this.db);
934
+ const settings = new chunk36Z3AKX3_cjs.SettingsService(this.db);
930
935
  const general = await settings.getGeneralSettings();
931
936
  const siteUrl = this.env.PUBLIC_URL || "http://localhost:8787";
932
937
  return {
@@ -976,7 +981,7 @@ var SiteConfigService = class {
976
981
 
977
982
  // src/plugins/core-plugins/email-plugin/routes/admin.ts
978
983
  var adminRoutes = new hono.Hono();
979
- adminRoutes.use("*", chunkAAWNRBRB_cjs.requireAuth());
984
+ adminRoutes.use("*", chunk4SHNHNRP_cjs.requireAuth());
980
985
  adminRoutes.post("/settings", async (c) => {
981
986
  if (c.get("user")?.role !== "admin") {
982
987
  return c.json({ error: "admin role required" }, 403);
@@ -1014,7 +1019,7 @@ adminRoutes.post("/test", async (c) => {
1014
1019
  const { subject, html: html4, text } = renderTestEmail({ siteName });
1015
1020
  try {
1016
1021
  const settingsLoaded = await settings.load();
1017
- const result = await chunkVXE42MYF_cjs.getEmailService().send({
1022
+ const result = await chunk3E7IROND_cjs.getEmailService().send({
1018
1023
  to,
1019
1024
  subject,
1020
1025
  html: html4,
@@ -1096,7 +1101,7 @@ function makeOnRegistrationCompleted(env) {
1096
1101
  siteName,
1097
1102
  loginUrl: siteConfig.buildLoginUrl(siteUrl)
1098
1103
  });
1099
- const result = await chunkVXE42MYF_cjs.getEmailService().send({
1104
+ const result = await chunk3E7IROND_cjs.getEmailService().send({
1100
1105
  to: user.email,
1101
1106
  subject,
1102
1107
  html: html4,
@@ -1170,7 +1175,7 @@ function makeOnPasswordResetRequested(env) {
1170
1175
  expiresAt: Date.now() + DEFAULT_EXPIRY_MS,
1171
1176
  siteName
1172
1177
  });
1173
- const result = await chunkVXE42MYF_cjs.getEmailService().send({
1178
+ const result = await chunk3E7IROND_cjs.getEmailService().send({
1174
1179
  to: user.email,
1175
1180
  subject,
1176
1181
  html: html4,
@@ -1238,7 +1243,7 @@ function makeOnPasswordResetCompleted(env) {
1238
1243
  supportEmail,
1239
1244
  when: Date.now()
1240
1245
  });
1241
- const result = await chunkVXE42MYF_cjs.getEmailService().send({
1246
+ const result = await chunk3E7IROND_cjs.getEmailService().send({
1242
1247
  to: user.email,
1243
1248
  subject,
1244
1249
  html: html4,
@@ -1262,6 +1267,8 @@ var EmailValidationError = class extends Error {
1262
1267
  this.reason = reason;
1263
1268
  this.name = "EmailValidationError";
1264
1269
  }
1270
+ field;
1271
+ reason;
1265
1272
  code = "EMAIL_VALIDATION_FAILED";
1266
1273
  };
1267
1274
 
@@ -1297,6 +1304,9 @@ var CfGraphqlClient = class {
1297
1304
  throw new EmailValidationError("apiToken", "EMAIL_API_TOKEN is required for GraphQL queries");
1298
1305
  }
1299
1306
  }
1307
+ zoneId;
1308
+ apiToken;
1309
+ fetchImpl;
1300
1310
  async queryEmailSends(input) {
1301
1311
  const startIso = new Date(input.startSeconds * 1e3).toISOString();
1302
1312
  const endIso = new Date(input.endSeconds * 1e3).toISOString();
@@ -1359,6 +1369,7 @@ var EmailLogService = class {
1359
1369
  constructor(db) {
1360
1370
  this.db = db;
1361
1371
  }
1372
+ db;
1362
1373
  /**
1363
1374
  * Records a successful submission to CF Email Service. `status` =
1364
1375
  * `'submitted'`, `delivery_state` remains NULL until reconciliation runs.
@@ -1532,6 +1543,8 @@ var ReconciliationService = class {
1532
1543
  this.graphql = graphql;
1533
1544
  this.emailLog = emailLog;
1534
1545
  }
1546
+ graphql;
1547
+ emailLog;
1535
1548
  async run(input = {}) {
1536
1549
  const windowHours = input.windowHours ?? 24;
1537
1550
  const nowMs = input.now ?? Date.now();
@@ -1940,6 +1953,7 @@ var CloudflareEmailProvider = class {
1940
1953
  constructor(binding) {
1941
1954
  this.binding = binding;
1942
1955
  }
1956
+ binding;
1943
1957
  name = "cloudflare";
1944
1958
  isConfigured() {
1945
1959
  return !!this.binding;
@@ -1970,7 +1984,7 @@ var CloudflareEmailProvider = class {
1970
1984
  }
1971
1985
  }
1972
1986
  };
1973
- var emailPluginV3 = chunkXW56B23A_cjs.definePlugin({
1987
+ var emailPluginV3 = chunk5RSB5SEK_cjs.definePlugin({
1974
1988
  id: "email",
1975
1989
  version: "1.0.0",
1976
1990
  name: "Email",
@@ -1984,7 +1998,7 @@ var emailPluginV3 = chunkXW56B23A_cjs.definePlugin({
1984
1998
  const db = env.DB;
1985
1999
  if (db) {
1986
2000
  try {
1987
- const typeRegistry = new chunkAAWNRBRB_cjs.DocumentTypeRegistry(db);
2001
+ const typeRegistry = new chunk4SHNHNRP_cjs.DocumentTypeRegistry(db);
1988
2002
  await typeRegistry.register({
1989
2003
  id: "email_log",
1990
2004
  name: "email_log",
@@ -1999,7 +2013,7 @@ var emailPluginV3 = chunkXW56B23A_cjs.definePlugin({
1999
2013
  } catch {
2000
2014
  }
2001
2015
  }
2002
- if (!chunkVXE42MYF_cjs.hasEmailService()) {
2016
+ if (!chunk3E7IROND_cjs.hasEmailService()) {
2003
2017
  const settings = db ? await new EmailSettingsService(db).load() : {};
2004
2018
  const envResendKey = typeof env.RESEND_API_KEY === "string" && env.RESEND_API_KEY ? env.RESEND_API_KEY : void 0;
2005
2019
  const cfEmailBinding = env.EMAIL;
@@ -2017,7 +2031,7 @@ var emailPluginV3 = chunkXW56B23A_cjs.definePlugin({
2017
2031
  } else {
2018
2032
  provider = resolveEmailProvider({ env });
2019
2033
  }
2020
- chunkVXE42MYF_cjs.setEmailService(new EmailService({ ...serviceOpts, provider }));
2034
+ chunk3E7IROND_cjs.setEmailService(new EmailService({ ...serviceOpts, provider }));
2021
2035
  }
2022
2036
  ctx.hooks.on("auth:registration:completed", makeOnRegistrationCompleted(env));
2023
2037
  ctx.hooks.on("auth:password-reset:requested", makeOnPasswordResetRequested(env));
@@ -2028,7 +2042,7 @@ var emailPluginV3 = chunkXW56B23A_cjs.definePlugin({
2028
2042
  var BATCH_SIZE = 100;
2029
2043
  ({
2030
2044
  schema: zod.z.record(zod.z.string(), zod.z.unknown())});
2031
- var emailReconciliationPlugin = chunkXW56B23A_cjs.definePlugin({
2045
+ var emailReconciliationPlugin = chunk5RSB5SEK_cjs.definePlugin({
2032
2046
  id: "email-reconciliation",
2033
2047
  version: "1.0.0",
2034
2048
  description: "Hourly cron that backfills email delivery state from provider status APIs. Only active for providers that implement EmailProvider.reconcile().",
@@ -2049,11 +2063,11 @@ var emailReconciliationPlugin = chunkXW56B23A_cjs.definePlugin({
2049
2063
  console.warn("[email-reconciliation] No DB binding in cron env \u2014 skipping.");
2050
2064
  return;
2051
2065
  }
2052
- if (!chunkVXE42MYF_cjs.hasEmailService()) {
2066
+ if (!chunk3E7IROND_cjs.hasEmailService()) {
2053
2067
  console.warn("[email-reconciliation] EmailService not initialized \u2014 skipping.");
2054
2068
  return;
2055
2069
  }
2056
- const emailService = chunkVXE42MYF_cjs.getEmailService();
2070
+ const emailService = chunk3E7IROND_cjs.getEmailService();
2057
2071
  let rows = [];
2058
2072
  try {
2059
2073
  const result = await db.prepare(
@@ -2122,6 +2136,7 @@ var OTPService = class {
2122
2136
  constructor(db) {
2123
2137
  this.db = db;
2124
2138
  }
2139
+ db;
2125
2140
  /**
2126
2141
  * Generate a secure random OTP code
2127
2142
  */
@@ -2485,7 +2500,7 @@ function buildOtpApi() {
2485
2500
  console.warn("Failed to parse OTP plugin settings, using defaults");
2486
2501
  }
2487
2502
  }
2488
- const settingsService = new chunkBDDABDAB_cjs.SettingsService(db);
2503
+ const settingsService = new chunk36Z3AKX3_cjs.SettingsService(db);
2489
2504
  const generalSettings = await settingsService.getGeneralSettings();
2490
2505
  const siteName = generalSettings.siteName;
2491
2506
  const canRequest = await otpService.checkRateLimit(normalizedEmail, settings);
@@ -2539,8 +2554,8 @@ function buildOtpApi() {
2539
2554
  loginUrl: settings.loginUrl || "",
2540
2555
  loginButtonText: settings.loginButtonText || ""
2541
2556
  });
2542
- if (chunkVXE42MYF_cjs.hasEmailService()) {
2543
- const sent = await chunkVXE42MYF_cjs.getEmailService().send({
2557
+ if (chunk3E7IROND_cjs.hasEmailService()) {
2558
+ const sent = await chunk3E7IROND_cjs.getEmailService().send({
2544
2559
  to: normalizedEmail,
2545
2560
  subject: `Your login code for ${siteName}`,
2546
2561
  flow: "otp",
@@ -2642,21 +2657,21 @@ function buildOtpApi() {
2642
2657
  error: "Account is deactivated"
2643
2658
  }, 403);
2644
2659
  }
2645
- const tokenTtl = await chunkAAWNRBRB_cjs.getJwtExpirySecondsFromDb(db, c.env);
2646
- const token = await chunkAAWNRBRB_cjs.AuthManager.generateToken(user.id, user.email, user.role, c.env.JWT_SECRET, tokenTtl);
2660
+ const tokenTtl = await chunk4SHNHNRP_cjs.getJwtExpirySecondsFromDb(db, c.env);
2661
+ const token = await chunk4SHNHNRP_cjs.AuthManager.generateToken(user.id, user.email, user.role, c.env.JWT_SECRET, tokenTtl);
2647
2662
  cookie.setCookie(c, "auth_token", token, {
2648
2663
  httpOnly: true,
2649
2664
  secure: true,
2650
2665
  sameSite: "Strict",
2651
2666
  maxAge: tokenTtl
2652
2667
  });
2653
- chunkVXE42MYF_cjs.dispatchHookEvent(
2668
+ chunk3E7IROND_cjs.dispatchHookEvent(
2654
2669
  c,
2655
2670
  "auth:otp:verified",
2656
2671
  { user: { id: user.id, email: user.email, role: user.role } },
2657
2672
  "fire-and-forget"
2658
2673
  );
2659
- const customData = await chunkVXE42MYF_cjs.getCustomData(db, user.id);
2674
+ const customData = await chunk3E7IROND_cjs.getCustomData(db, user.id);
2660
2675
  const { is_active: _isActive, ...publicUser } = user;
2661
2676
  return c.json({
2662
2677
  success: true,
@@ -2701,7 +2716,7 @@ function buildOtpApi() {
2701
2716
  });
2702
2717
  return otpAPI;
2703
2718
  }
2704
- var otpLoginPlugin = chunkXW56B23A_cjs.definePlugin({
2719
+ var otpLoginPlugin = chunk5RSB5SEK_cjs.definePlugin({
2705
2720
  id: "otp-login",
2706
2721
  version: "1.0.0",
2707
2722
  name: "OTP Login",
@@ -2756,6 +2771,7 @@ var OAuthService = class {
2756
2771
  constructor(db) {
2757
2772
  this.db = db;
2758
2773
  }
2774
+ db;
2759
2775
  /**
2760
2776
  * Build the authorization redirect URL for a provider.
2761
2777
  */
@@ -3098,15 +3114,15 @@ function buildOauthApi() {
3098
3114
  if (!user || !user.is_active) {
3099
3115
  return c.redirect("/auth/login?error=Account is deactivated");
3100
3116
  }
3101
- const tokenTtl2 = await chunkAAWNRBRB_cjs.getJwtExpirySecondsFromDb(c.env.DB, c.env);
3102
- const jwt2 = await chunkAAWNRBRB_cjs.AuthManager.generateToken(
3117
+ const tokenTtl2 = await chunk4SHNHNRP_cjs.getJwtExpirySecondsFromDb(c.env.DB, c.env);
3118
+ const jwt2 = await chunk4SHNHNRP_cjs.AuthManager.generateToken(
3103
3119
  user.id,
3104
3120
  user.email,
3105
3121
  user.role,
3106
3122
  c.env.JWT_SECRET,
3107
3123
  tokenTtl2
3108
3124
  );
3109
- chunkAAWNRBRB_cjs.AuthManager.setAuthCookie(c, jwt2, { sameSite: "Lax", maxAge: tokenTtl2 });
3125
+ chunk4SHNHNRP_cjs.AuthManager.setAuthCookie(c, jwt2, { sameSite: "Lax", maxAge: tokenTtl2 });
3110
3126
  return c.redirect("/admin");
3111
3127
  }
3112
3128
  const existingUser = await oauthService.findUserByEmail(profile.email);
@@ -3123,15 +3139,15 @@ function buildOauthApi() {
3123
3139
  tokenExpiresAt: tokenExpiresAt ?? void 0,
3124
3140
  profileData: JSON.stringify(profile)
3125
3141
  });
3126
- const tokenTtl2 = await chunkAAWNRBRB_cjs.getJwtExpirySecondsFromDb(c.env.DB, c.env);
3127
- const jwt2 = await chunkAAWNRBRB_cjs.AuthManager.generateToken(
3142
+ const tokenTtl2 = await chunk4SHNHNRP_cjs.getJwtExpirySecondsFromDb(c.env.DB, c.env);
3143
+ const jwt2 = await chunk4SHNHNRP_cjs.AuthManager.generateToken(
3128
3144
  existingUser.id,
3129
3145
  existingUser.email,
3130
3146
  existingUser.role,
3131
3147
  c.env.JWT_SECRET,
3132
3148
  tokenTtl2
3133
3149
  );
3134
- chunkAAWNRBRB_cjs.AuthManager.setAuthCookie(c, jwt2, { sameSite: "Lax", maxAge: tokenTtl2 });
3150
+ chunk4SHNHNRP_cjs.AuthManager.setAuthCookie(c, jwt2, { sameSite: "Lax", maxAge: tokenTtl2 });
3135
3151
  return c.redirect("/admin");
3136
3152
  }
3137
3153
  const newUserId = await oauthService.createUserFromOAuth(profile);
@@ -3144,15 +3160,15 @@ function buildOauthApi() {
3144
3160
  tokenExpiresAt: tokenExpiresAt ?? void 0,
3145
3161
  profileData: JSON.stringify(profile)
3146
3162
  });
3147
- const tokenTtl = await chunkAAWNRBRB_cjs.getJwtExpirySecondsFromDb(c.env.DB, c.env);
3148
- const jwt = await chunkAAWNRBRB_cjs.AuthManager.generateToken(
3163
+ const tokenTtl = await chunk4SHNHNRP_cjs.getJwtExpirySecondsFromDb(c.env.DB, c.env);
3164
+ const jwt = await chunk4SHNHNRP_cjs.AuthManager.generateToken(
3149
3165
  newUserId,
3150
3166
  profile.email.toLowerCase(),
3151
3167
  "viewer",
3152
3168
  c.env.JWT_SECRET,
3153
3169
  tokenTtl
3154
3170
  );
3155
- chunkAAWNRBRB_cjs.AuthManager.setAuthCookie(c, jwt, { sameSite: "Lax", maxAge: tokenTtl });
3171
+ chunk4SHNHNRP_cjs.AuthManager.setAuthCookie(c, jwt, { sameSite: "Lax", maxAge: tokenTtl });
3156
3172
  return c.redirect("/admin");
3157
3173
  } catch (error) {
3158
3174
  console.error("OAuth callback error:", error);
@@ -3247,7 +3263,7 @@ function buildOauthApi() {
3247
3263
  });
3248
3264
  return oauthAPI;
3249
3265
  }
3250
- var oauthProvidersPlugin = chunkXW56B23A_cjs.definePlugin({
3266
+ var oauthProvidersPlugin = chunk5RSB5SEK_cjs.definePlugin({
3251
3267
  id: "oauth-providers",
3252
3268
  version: "1.0.0",
3253
3269
  name: "OAuth Providers",
@@ -3272,6 +3288,7 @@ var EmbeddingService = class {
3272
3288
  constructor(ai) {
3273
3289
  this.ai = ai;
3274
3290
  }
3291
+ ai;
3275
3292
  /**
3276
3293
  * Generate embedding for a single text
3277
3294
  */
@@ -3476,6 +3493,9 @@ var CustomRAGService = class {
3476
3493
  this.embeddingService = new EmbeddingService(ai);
3477
3494
  this.chunkingService = new ChunkingService();
3478
3495
  }
3496
+ db;
3497
+ ai;
3498
+ vectorize;
3479
3499
  embeddingService;
3480
3500
  chunkingService;
3481
3501
  /**
@@ -3766,6 +3786,9 @@ var AISearchService = class {
3766
3786
  console.log("[AISearchService] Custom RAG not available, using keyword search only");
3767
3787
  }
3768
3788
  }
3789
+ db;
3790
+ ai;
3791
+ vectorize;
3769
3792
  customRAG;
3770
3793
  /**
3771
3794
  * Get plugin settings
@@ -3824,7 +3847,7 @@ var AISearchService = class {
3824
3847
  */
3825
3848
  async detectNewCollections() {
3826
3849
  try {
3827
- const allCollections = chunkQAYFOER6_cjs.getCollectionRegistry().listActive().filter((r) => !r.internal).map((r) => ({
3850
+ const allCollections = chunk5ARIHAGN_cjs.getCollectionRegistry().listActive().filter((r) => !r.internal).map((r) => ({
3828
3851
  id: r.id,
3829
3852
  name: r.name,
3830
3853
  display_name: r.displayName,
@@ -3876,7 +3899,7 @@ var AISearchService = class {
3876
3899
  */
3877
3900
  async getAllCollections() {
3878
3901
  try {
3879
- const allCollections = chunkQAYFOER6_cjs.getCollectionRegistry().listActive().filter((r) => !r.internal).sort((a, b) => a.displayName.localeCompare(b.displayName)).map((r) => ({
3902
+ const allCollections = chunk5ARIHAGN_cjs.getCollectionRegistry().listActive().filter((r) => !r.internal).sort((a, b) => a.displayName.localeCompare(b.displayName)).map((r) => ({
3880
3903
  id: r.id,
3881
3904
  name: r.name,
3882
3905
  display_name: r.displayName,
@@ -4206,13 +4229,16 @@ var IndexManager = class {
4206
4229
  console.log("[IndexManager] Custom RAG initialized");
4207
4230
  }
4208
4231
  }
4232
+ db;
4233
+ ai;
4234
+ vectorize;
4209
4235
  customRAG;
4210
4236
  /**
4211
4237
  * Index all content items within a collection using Custom RAG
4212
4238
  */
4213
4239
  async indexCollection(collectionId) {
4214
4240
  try {
4215
- const registry = chunkQAYFOER6_cjs.getCollectionRegistry();
4241
+ const registry = chunk5ARIHAGN_cjs.getCollectionRegistry();
4216
4242
  const record = registry.getById(collectionId) ?? registry.getByName(collectionId);
4217
4243
  if (!record) {
4218
4244
  throw new Error(`Collection ${collectionId} not found`);
@@ -4828,7 +4854,7 @@ function renderSettingsPage(data) {
4828
4854
  }, 30000);
4829
4855
  </script>
4830
4856
  `;
4831
- return chunkMVIZJOO5_cjs.renderAdminLayout({
4857
+ return chunkPXNTCCPE_cjs.renderAdminLayout({
4832
4858
  title: "AI Search Settings",
4833
4859
  pageTitle: "AI Search Settings",
4834
4860
  currentPath: "/admin/plugins/ai-search/settings",
@@ -4839,7 +4865,7 @@ function renderSettingsPage(data) {
4839
4865
 
4840
4866
  // src/plugins/core-plugins/ai-search-plugin/routes/admin.ts
4841
4867
  var adminRoutes2 = new hono.Hono();
4842
- adminRoutes2.use("*", chunkAAWNRBRB_cjs.requireAuth());
4868
+ adminRoutes2.use("*", chunk4SHNHNRP_cjs.requireAuth());
4843
4869
  adminRoutes2.get("/", async (c) => {
4844
4870
  try {
4845
4871
  const user = c.get("user");
@@ -5080,7 +5106,7 @@ var manifest_default = {
5080
5106
  author: "SonicJS"};
5081
5107
 
5082
5108
  // src/plugins/core-plugins/ai-search-plugin/index.ts
5083
- var aiSearchPlugin = chunkXW56B23A_cjs.definePlugin({
5109
+ var aiSearchPlugin = chunk5RSB5SEK_cjs.definePlugin({
5084
5110
  id: manifest_default.id,
5085
5111
  version: manifest_default.version,
5086
5112
  name: manifest_default.name,
@@ -5133,12 +5159,14 @@ var SecurityAuditService = class {
5133
5159
  constructor(db, settings = DEFAULT_SETTINGS2) {
5134
5160
  this.db = db;
5135
5161
  this.settings = settings;
5136
- this.docsService = new chunk2CB4KY7I_cjs.DocumentsService(db, {
5162
+ this.docsService = new chunkLTZ5WYOK_cjs.DocumentsService(db, {
5137
5163
  queryableFields: QUERYABLE_FIELDS,
5138
5164
  maxVersionsPerRoot: 1,
5139
5165
  tenantId: TENANT
5140
5166
  });
5141
5167
  }
5168
+ db;
5169
+ settings;
5142
5170
  docsService;
5143
5171
  async logEvent(event) {
5144
5172
  const doc = await this.docsService.create({
@@ -5379,7 +5407,7 @@ function rowToEvent(row) {
5379
5407
  }
5380
5408
 
5381
5409
  // src/plugins/core-plugins/security-audit-plugin/components/dashboard-page.ts
5382
- chunkNAVPFIG5_cjs.init_admin_layout_catalyst_template();
5410
+ chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
5383
5411
  function formatTimestamp(ts) {
5384
5412
  const date = new Date(ts);
5385
5413
  const now = Date.now();
@@ -5578,11 +5606,11 @@ function renderSecurityDashboard(data) {
5578
5606
  version,
5579
5607
  dynamicMenuItems
5580
5608
  };
5581
- return chunkNAVPFIG5_cjs.renderAdminLayoutCatalyst(layoutData);
5609
+ return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
5582
5610
  }
5583
5611
 
5584
5612
  // src/plugins/core-plugins/security-audit-plugin/components/event-log-page.ts
5585
- chunkNAVPFIG5_cjs.init_admin_layout_catalyst_template();
5613
+ chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
5586
5614
  function formatTimestamp2(ts) {
5587
5615
  const date = new Date(ts);
5588
5616
  return date.toLocaleDateString("en-US", {
@@ -5789,11 +5817,11 @@ function renderEventLogPage(data) {
5789
5817
  version,
5790
5818
  dynamicMenuItems
5791
5819
  };
5792
- return chunkNAVPFIG5_cjs.renderAdminLayoutCatalyst(layoutData);
5820
+ return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
5793
5821
  }
5794
5822
 
5795
5823
  // src/plugins/core-plugins/security-audit-plugin/components/settings-page.ts
5796
- chunkNAVPFIG5_cjs.init_admin_layout_catalyst_template();
5824
+ chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
5797
5825
  function renderSecuritySettingsPage(data) {
5798
5826
  const { settings, user, version, message, dynamicMenuItems } = data;
5799
5827
  const content2 = `
@@ -5946,12 +5974,12 @@ function renderSecuritySettingsPage(data) {
5946
5974
  version,
5947
5975
  dynamicMenuItems
5948
5976
  };
5949
- return chunkNAVPFIG5_cjs.renderAdminLayoutCatalyst(layoutData);
5977
+ return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
5950
5978
  }
5951
5979
 
5952
5980
  // src/plugins/core-plugins/security-audit-plugin/routes/admin.ts
5953
5981
  var adminRoutes3 = new hono.Hono();
5954
- adminRoutes3.use("*", chunkAAWNRBRB_cjs.requireAuth());
5982
+ adminRoutes3.use("*", chunk4SHNHNRP_cjs.requireAuth());
5955
5983
  adminRoutes3.use("*", async (c, next) => {
5956
5984
  const user = c.get("user");
5957
5985
  if (user?.role !== "admin") {
@@ -5961,7 +5989,7 @@ adminRoutes3.use("*", async (c, next) => {
5961
5989
  });
5962
5990
  async function getSettings(db) {
5963
5991
  try {
5964
- const pluginService = new chunkQAYFOER6_cjs.PluginService(db);
5992
+ const pluginService = new chunk5ARIHAGN_cjs.PluginService(db);
5965
5993
  const plugin2 = await pluginService.getPlugin("security-audit");
5966
5994
  if (plugin2?.settings) {
5967
5995
  const settings = typeof plugin2.settings === "string" ? JSON.parse(plugin2.settings) : plugin2.settings;
@@ -6066,7 +6094,7 @@ adminRoutes3.post("/settings", async (c) => {
6066
6094
  autoPurge: body["retention.autoPurge"] === "true"
6067
6095
  }
6068
6096
  };
6069
- const pluginService = new chunkQAYFOER6_cjs.PluginService(db);
6097
+ const pluginService = new chunk5ARIHAGN_cjs.PluginService(db);
6070
6098
  await pluginService.updatePluginSettings("security-audit", settings);
6071
6099
  if (c.req.header("HX-Request")) {
6072
6100
  return c.json({ success: true });
@@ -6082,6 +6110,7 @@ var BruteForceDetector = class {
6082
6110
  this.kv = kv;
6083
6111
  this.settings = settings || DEFAULT_SETTINGS2.bruteForce;
6084
6112
  }
6113
+ kv;
6085
6114
  settings;
6086
6115
  async recordFailedAttempt(ip, email) {
6087
6116
  if (!this.settings.enabled || !this.kv) {
@@ -6227,7 +6256,7 @@ var BruteForceDetector = class {
6227
6256
 
6228
6257
  // src/plugins/core-plugins/security-audit-plugin/routes/api.ts
6229
6258
  var apiRoutes2 = new hono.Hono();
6230
- apiRoutes2.use("*", chunkAAWNRBRB_cjs.requireAuth());
6259
+ apiRoutes2.use("*", chunk4SHNHNRP_cjs.requireAuth());
6231
6260
  apiRoutes2.use("*", async (c, next) => {
6232
6261
  const user = c.get("user");
6233
6262
  if (user?.role !== "admin") {
@@ -6237,7 +6266,7 @@ apiRoutes2.use("*", async (c, next) => {
6237
6266
  });
6238
6267
  async function getSettings2(db) {
6239
6268
  try {
6240
- const pluginService = new chunkQAYFOER6_cjs.PluginService(db);
6269
+ const pluginService = new chunk5ARIHAGN_cjs.PluginService(db);
6241
6270
  const plugin2 = await pluginService.getPlugin("security-audit");
6242
6271
  if (plugin2?.settings) {
6243
6272
  const settings = typeof plugin2.settings === "string" ? JSON.parse(plugin2.settings) : plugin2.settings;
@@ -6385,7 +6414,7 @@ function generateFingerprint(ip, userAgent) {
6385
6414
  }
6386
6415
  async function getPluginSettings(db) {
6387
6416
  try {
6388
- const pluginService = new chunkQAYFOER6_cjs.PluginService(db);
6417
+ const pluginService = new chunk5ARIHAGN_cjs.PluginService(db);
6389
6418
  const plugin2 = await pluginService.getPlugin("security-audit");
6390
6419
  if (plugin2?.settings) {
6391
6420
  const settings = typeof plugin2.settings === "string" ? JSON.parse(plugin2.settings) : plugin2.settings;
@@ -6616,7 +6645,7 @@ async function logAuthEvent(c, db, settings, ip, userAgent, countryCode, fingerp
6616
6645
 
6617
6646
  // src/plugins/core-plugins/security-audit-plugin/index.ts
6618
6647
  var SECURITY_ICON = `<svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"/></svg>`;
6619
- var securityAuditPlugin = chunkXW56B23A_cjs.definePlugin({
6648
+ var securityAuditPlugin = chunk5RSB5SEK_cjs.definePlugin({
6620
6649
  id: "security-audit",
6621
6650
  version: "1.0.0",
6622
6651
  name: "Security Audit",
@@ -6634,11 +6663,465 @@ var securityAuditPlugin = chunkXW56B23A_cjs.definePlugin({
6634
6663
  deactivate: async () => console.log("[SecurityAudit] Plugin deactivated")
6635
6664
  });
6636
6665
 
6666
+ // src/plugins/core-plugins/api-keys-plugin/services/api-key-service.ts
6667
+ var API_KEY_QUERYABLE = [
6668
+ { name: "keyHash", kind: "scalar", type: "text", column: "q_apikey_hash" },
6669
+ { name: "userId", kind: "scalar", type: "text", column: "q_apikey_user_id" },
6670
+ { name: "revoked", kind: "scalar", type: "integer", column: "q_apikey_revoked" }
6671
+ ];
6672
+ var KEY_PREFIX = "sk_";
6673
+ var KEY_BYTES = 24;
6674
+ var DISPLAY_PREFIX_LEN = KEY_PREFIX.length + 8;
6675
+ function generateApiKeySecret() {
6676
+ const bytes = new Uint8Array(KEY_BYTES);
6677
+ crypto.getRandomValues(bytes);
6678
+ let hex = "";
6679
+ for (const b of bytes) hex += b.toString(16).padStart(2, "0");
6680
+ return KEY_PREFIX + hex;
6681
+ }
6682
+ async function hashApiKey(secret) {
6683
+ const data = new TextEncoder().encode(secret);
6684
+ const digest = await crypto.subtle.digest("SHA-256", data);
6685
+ const view = new Uint8Array(digest);
6686
+ let hex = "";
6687
+ for (const b of view) hex += b.toString(16).padStart(2, "0");
6688
+ return hex;
6689
+ }
6690
+ var ApiKeyService = class {
6691
+ constructor(db, tenantId = "default") {
6692
+ this.db = db;
6693
+ this.tenantId = tenantId;
6694
+ }
6695
+ db;
6696
+ tenantId;
6697
+ docService() {
6698
+ return new chunkLTZ5WYOK_cjs.DocumentsService(this.db, {
6699
+ queryableFields: API_KEY_QUERYABLE,
6700
+ tenantId: this.tenantId,
6701
+ maxVersionsPerRoot: 1
6702
+ });
6703
+ }
6704
+ /** Count a user's active (non-revoked) keys — used to enforce the per-user cap. */
6705
+ async countForUser(userId) {
6706
+ const row = await this.db.prepare(
6707
+ `SELECT COUNT(*) AS c FROM documents
6708
+ WHERE type_id = 'api_key' AND tenant_id = ? AND is_current_draft = 1
6709
+ AND deleted_at IS NULL AND q_apikey_user_id = ? AND q_apikey_revoked = 0`
6710
+ ).bind(this.tenantId, userId).first();
6711
+ return row?.c ?? 0;
6712
+ }
6713
+ /**
6714
+ * Mint a new key for a user. The returned `key` is the only time the plaintext
6715
+ * exists outside the caller — it is hashed before storage.
6716
+ */
6717
+ async create(input) {
6718
+ const name = input.name.trim() || "API Key";
6719
+ const secret = generateApiKeySecret();
6720
+ const keyHash = await hashApiKey(secret);
6721
+ const prefix = secret.slice(0, DISPLAY_PREFIX_LEN);
6722
+ const expiresAt = input.expiresAt ?? null;
6723
+ const doc = await this.docService().create(
6724
+ chunk3E7IROND_cjs.createDocumentSchema.parse({
6725
+ typeId: "api_key",
6726
+ tenantId: this.tenantId,
6727
+ title: name,
6728
+ ownerId: input.userId,
6729
+ publishOnCreate: true,
6730
+ data: {
6731
+ name,
6732
+ userId: input.userId,
6733
+ keyHash,
6734
+ keyPrefix: prefix,
6735
+ revoked: 0,
6736
+ lastUsedAt: null,
6737
+ expiresAt
6738
+ }
6739
+ }),
6740
+ input.userId
6741
+ );
6742
+ return { id: doc.rootId, key: secret, name, prefix, expiresAt };
6743
+ }
6744
+ /** List a user's non-revoked keys (metadata only — never the secret or hash). */
6745
+ async list(userId) {
6746
+ const res = await this.db.prepare(
6747
+ `SELECT root_id, data, created_at FROM documents
6748
+ WHERE type_id = 'api_key' AND tenant_id = ? AND is_current_draft = 1
6749
+ AND deleted_at IS NULL AND q_apikey_user_id = ? AND q_apikey_revoked = 0
6750
+ ORDER BY created_at DESC`
6751
+ ).bind(this.tenantId, userId).all();
6752
+ return (res.results ?? []).map((row) => {
6753
+ const d = JSON.parse(row.data);
6754
+ return {
6755
+ id: row.root_id,
6756
+ name: d.name ?? "API Key",
6757
+ prefix: d.keyPrefix ?? "",
6758
+ createdAt: row.created_at,
6759
+ lastUsedAt: d.lastUsedAt ?? null,
6760
+ expiresAt: d.expiresAt ?? null
6761
+ };
6762
+ });
6763
+ }
6764
+ /**
6765
+ * Revoke (hard-delete) a key owned by `userId`. Credentials are erased, not
6766
+ * soft-flagged. Returns false if the key does not exist or is not owned by
6767
+ * the caller (no information leak about other users' keys).
6768
+ */
6769
+ async revoke(rootId, userId) {
6770
+ const row = await this.db.prepare(
6771
+ `SELECT q_apikey_user_id AS owner FROM documents
6772
+ WHERE root_id = ? AND tenant_id = ? AND type_id = 'api_key' AND is_current_draft = 1 AND deleted_at IS NULL`
6773
+ ).bind(rootId, this.tenantId).first();
6774
+ if (!row || row.owner !== userId) return false;
6775
+ await this.docService().erase(rootId, this.tenantId);
6776
+ return true;
6777
+ }
6778
+ /**
6779
+ * Resolve a presented secret to its owning user, or null. Rejects unknown,
6780
+ * revoked, expired keys and inactive users. Best-effort updates lastUsedAt.
6781
+ */
6782
+ async resolve(secret) {
6783
+ if (!secret || !secret.startsWith(KEY_PREFIX)) return null;
6784
+ const keyHash = await hashApiKey(secret);
6785
+ const keyRow2 = await this.db.prepare(
6786
+ `SELECT root_id, data FROM documents
6787
+ WHERE type_id = 'api_key' AND tenant_id = ? AND is_current_draft = 1 AND deleted_at IS NULL
6788
+ AND q_apikey_hash = ? AND q_apikey_revoked = 0
6789
+ LIMIT 1`
6790
+ ).bind(this.tenantId, keyHash).first();
6791
+ if (!keyRow2) return null;
6792
+ const d = JSON.parse(keyRow2.data);
6793
+ if (d.expiresAt != null && Date.now() > Number(d.expiresAt)) return null;
6794
+ const user = await this.db.prepare(`SELECT id, email, role, is_active, is_super_admin FROM auth_user WHERE id = ?`).bind(d.userId).first();
6795
+ if (!user || user.is_active !== 1) return null;
6796
+ try {
6797
+ await this.touchLastUsed(keyRow2.root_id, d);
6798
+ } catch {
6799
+ }
6800
+ return {
6801
+ userId: user.id,
6802
+ email: user.email,
6803
+ role: user.role ?? "viewer",
6804
+ isSuperAdmin: user.is_super_admin === 1
6805
+ };
6806
+ }
6807
+ /** Update lastUsedAt in-place (single-version type, no history churn). */
6808
+ async touchLastUsed(rootId, data) {
6809
+ const next = JSON.stringify({ ...data, lastUsedAt: Date.now() });
6810
+ await this.db.prepare(
6811
+ `UPDATE documents SET data = ? WHERE root_id = ? AND tenant_id = ? AND type_id = 'api_key' AND is_current_draft = 1`
6812
+ ).bind(next, rootId, this.tenantId).run();
6813
+ }
6814
+ };
6815
+
6816
+ // src/plugins/core-plugins/api-keys-plugin/components/keys-page.ts
6817
+ chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
6818
+ function fmtDate(ms) {
6819
+ if (!ms) return "\u2014";
6820
+ try {
6821
+ return new Date(ms).toISOString().slice(0, 10);
6822
+ } catch {
6823
+ return "\u2014";
6824
+ }
6825
+ }
6826
+ function keyRow(k) {
6827
+ const name = chunkMNWKYY5E_cjs.escapeHtml(k.name);
6828
+ const prefix = chunkMNWKYY5E_cjs.escapeHtml(k.prefix);
6829
+ const id = chunkMNWKYY5E_cjs.escapeHtml(k.id);
6830
+ return `
6831
+ <tr class="border-t border-zinc-950/5 dark:border-white/10" data-key-id="${id}">
6832
+ <td class="py-3 pr-4 text-sm font-medium text-zinc-950 dark:text-white">${name}</td>
6833
+ <td class="py-3 pr-4 text-sm font-mono text-zinc-500 dark:text-zinc-400">${prefix}\u2026</td>
6834
+ <td class="py-3 pr-4 text-sm text-zinc-500 dark:text-zinc-400">${fmtDate(k.createdAt ? k.createdAt * 1e3 : null)}</td>
6835
+ <td class="py-3 pr-4 text-sm text-zinc-500 dark:text-zinc-400">${k.lastUsedAt ? fmtDate(k.lastUsedAt) : "Never"}</td>
6836
+ <td class="py-3 pr-4 text-sm text-zinc-500 dark:text-zinc-400">${k.expiresAt ? fmtDate(k.expiresAt) : "Never"}</td>
6837
+ <td class="py-3 text-right">
6838
+ <button type="button" onclick="revokeApiKey('${id}', '${name.replace(/'/g, "\\'")}')"
6839
+ class="rounded-lg bg-red-50 dark:bg-red-900/20 px-3 py-1.5 text-sm font-medium text-red-700 dark:text-red-400 hover:bg-red-100 dark:hover:bg-red-900/40 ring-1 ring-red-200 dark:ring-red-800 transition-colors">
6840
+ Revoke
6841
+ </button>
6842
+ </td>
6843
+ </tr>`;
6844
+ }
6845
+ function renderApiKeysPage(data) {
6846
+ const { keys, user, version, dynamicMenuItems } = data;
6847
+ const rows = keys.length ? keys.map(keyRow).join("") : `<tr><td colspan="6" class="py-8 text-center text-sm text-zinc-500 dark:text-zinc-400">No API keys yet. Create one to enable programmatic access.</td></tr>`;
6848
+ const content2 = `
6849
+ <div>
6850
+ <div class="sm:flex sm:items-center sm:justify-between mb-6">
6851
+ <div class="sm:flex-auto">
6852
+ <h1 class="text-2xl/8 font-semibold text-zinc-950 dark:text-white sm:text-xl/8">API Keys</h1>
6853
+ <p class="mt-2 text-sm/6 text-zinc-500 dark:text-zinc-400">
6854
+ Long-lived secrets for headless / server-to-server REST access. Send a key as the
6855
+ <code class="font-mono">x-api-key</code> header or <code class="font-mono">Authorization: Bearer &lt;key&gt;</code>.
6856
+ The secret is shown once at creation \u2014 store it now.
6857
+ </p>
6858
+ </div>
6859
+ <div class="mt-4 sm:mt-0 sm:ml-16">
6860
+ <button type="button" onclick="document.getElementById('create-key-modal').classList.remove('hidden')"
6861
+ class="inline-flex items-center justify-center rounded-lg bg-cyan-600 px-4 py-2.5 text-sm font-semibold text-white hover:bg-cyan-500 transition-colors shadow-sm">
6862
+ Create API key
6863
+ </button>
6864
+ </div>
6865
+ </div>
6866
+
6867
+ <!-- Newly-created secret banner (populated by JS, shown once) -->
6868
+ <div id="new-key-banner" class="hidden mb-6 rounded-xl bg-emerald-50 dark:bg-emerald-900/20 p-4 ring-1 ring-emerald-200 dark:ring-emerald-800">
6869
+ <p class="text-sm font-medium text-emerald-800 dark:text-emerald-300 mb-2">
6870
+ Copy your new key now \u2014 it will not be shown again.
6871
+ </p>
6872
+ <div class="flex items-center gap-2">
6873
+ <code id="new-key-value" class="flex-1 rounded-lg bg-white dark:bg-zinc-900 px-3 py-2 text-sm font-mono text-zinc-950 dark:text-white ring-1 ring-zinc-950/10 dark:ring-white/10 break-all"></code>
6874
+ <button type="button" onclick="copyNewKey()"
6875
+ class="rounded-lg bg-emerald-600 px-3 py-2 text-sm font-semibold text-white hover:bg-emerald-500 transition-colors">
6876
+ Copy
6877
+ </button>
6878
+ </div>
6879
+ </div>
6880
+
6881
+ <div class="rounded-xl bg-white/80 dark:bg-zinc-900/80 backdrop-blur-xl p-6 ring-1 ring-zinc-950/5 dark:ring-white/10 shadow-sm overflow-x-auto">
6882
+ <table class="w-full text-left">
6883
+ <thead>
6884
+ <tr class="text-xs font-semibold uppercase tracking-wide text-zinc-500 dark:text-zinc-400">
6885
+ <th class="pb-2 pr-4">Name</th>
6886
+ <th class="pb-2 pr-4">Prefix</th>
6887
+ <th class="pb-2 pr-4">Created</th>
6888
+ <th class="pb-2 pr-4">Last used</th>
6889
+ <th class="pb-2 pr-4">Expires</th>
6890
+ <th class="pb-2 text-right">Actions</th>
6891
+ </tr>
6892
+ </thead>
6893
+ <tbody id="keys-tbody">${rows}</tbody>
6894
+ </table>
6895
+ </div>
6896
+ </div>
6897
+
6898
+ <!-- Create modal -->
6899
+ <div id="create-key-modal" class="hidden fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4">
6900
+ <div class="w-full max-w-md rounded-xl bg-white dark:bg-zinc-900 p-6 ring-1 ring-zinc-950/10 dark:ring-white/10 shadow-xl">
6901
+ <h2 class="text-base font-semibold text-zinc-950 dark:text-white mb-4">Create API key</h2>
6902
+ <label class="block text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-1">Name</label>
6903
+ <input id="new-key-name" type="text" placeholder="e.g. CI deploy token"
6904
+ class="w-full rounded-lg border-zinc-300 dark:border-zinc-700 bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white mb-4 ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10">
6905
+ <label class="block text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-1">Expires in (days, optional)</label>
6906
+ <input id="new-key-expiry" type="number" min="1" max="3650" placeholder="Never"
6907
+ class="w-full rounded-lg border-zinc-300 dark:border-zinc-700 bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white mb-4 ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10">
6908
+ <div class="flex justify-end gap-2">
6909
+ <button type="button" onclick="document.getElementById('create-key-modal').classList.add('hidden')"
6910
+ class="rounded-lg bg-white dark:bg-zinc-800 px-4 py-2 text-sm font-semibold text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10">
6911
+ Cancel
6912
+ </button>
6913
+ <button type="button" onclick="createApiKey()"
6914
+ class="rounded-lg bg-cyan-600 px-4 py-2 text-sm font-semibold text-white hover:bg-cyan-500 transition-colors">
6915
+ Create
6916
+ </button>
6917
+ </div>
6918
+ </div>
6919
+ </div>
6920
+
6921
+ <script>
6922
+ // CSRF: the csrf_token cookie is JS-readable (httpOnly:false); echo it back
6923
+ // as X-CSRF-Token on state-changing requests (signed double-submit).
6924
+ function csrfHeader() {
6925
+ const m = document.cookie.match(/(?:^|; )csrf_token=([^;]+)/)
6926
+ return m ? { 'X-CSRF-Token': decodeURIComponent(m[1]) } : {}
6927
+ }
6928
+ async function createApiKey() {
6929
+ const name = document.getElementById('new-key-name').value.trim()
6930
+ if (!name) { window.showNotification && window.showNotification('Name is required', 'error'); return }
6931
+ const expiry = parseInt(document.getElementById('new-key-expiry').value, 10)
6932
+ const body = { name }
6933
+ if (Number.isFinite(expiry) && expiry > 0) body.expiresInDays = expiry
6934
+ const res = await fetch('/admin/plugins/api-keys/api/keys', {
6935
+ method: 'POST',
6936
+ headers: { 'Content-Type': 'application/json', ...csrfHeader() },
6937
+ body: JSON.stringify(body),
6938
+ })
6939
+ if (!res.ok) {
6940
+ const e = await res.json().catch(() => ({}))
6941
+ window.showNotification && window.showNotification(e.error || 'Failed to create key', 'error')
6942
+ return
6943
+ }
6944
+ const { apiKey } = await res.json()
6945
+ document.getElementById('create-key-modal').classList.add('hidden')
6946
+ document.getElementById('new-key-value').textContent = apiKey.key
6947
+ document.getElementById('new-key-banner').classList.remove('hidden')
6948
+ setTimeout(() => location.reload(), 1500)
6949
+ }
6950
+ function copyNewKey() {
6951
+ const v = document.getElementById('new-key-value').textContent
6952
+ navigator.clipboard.writeText(v).then(() => window.showNotification && window.showNotification('Copied', 'success'))
6953
+ }
6954
+ async function revokeApiKey(id, name) {
6955
+ if (!confirm('Revoke "' + name + '"? This cannot be undone and will break any client using it.')) return
6956
+ const res = await fetch('/admin/plugins/api-keys/api/keys/' + id, { method: 'DELETE', headers: { ...csrfHeader() } })
6957
+ if (res.ok) {
6958
+ const row = document.querySelector('[data-key-id="' + id + '"]')
6959
+ if (row) row.remove()
6960
+ window.showNotification && window.showNotification('Key revoked', 'success')
6961
+ } else {
6962
+ window.showNotification && window.showNotification('Failed to revoke', 'error')
6963
+ }
6964
+ }
6965
+ </script>`;
6966
+ const layoutData = {
6967
+ title: "API Keys",
6968
+ pageTitle: "API Keys",
6969
+ currentPath: "/admin/plugins/api-keys",
6970
+ user,
6971
+ content: content2,
6972
+ version,
6973
+ dynamicMenuItems
6974
+ };
6975
+ return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
6976
+ }
6977
+
6978
+ // src/plugins/core-plugins/api-keys-plugin/types.ts
6979
+ var DEFAULT_SETTINGS3 = {
6980
+ maxKeysPerUser: 50,
6981
+ defaultExpiryDays: 0
6982
+ };
6983
+
6984
+ // src/plugins/core-plugins/api-keys-plugin/routes/admin.ts
6985
+ var adminRoutes4 = new hono.Hono();
6986
+ var DAY_MS = 24 * 60 * 60 * 1e3;
6987
+ var createSchema = zod.z.object({
6988
+ name: zod.z.string().min(1).max(100),
6989
+ // Optional lifetime in days; omitted/null → plugin default (which may be "never").
6990
+ expiresInDays: zod.z.number().int().positive().max(3650).nullish()
6991
+ });
6992
+ async function getSettings3(db) {
6993
+ try {
6994
+ const plugin2 = await new chunk5ARIHAGN_cjs.PluginService(db).getPlugin("api-keys");
6995
+ if (plugin2?.settings) {
6996
+ const s = typeof plugin2.settings === "string" ? JSON.parse(plugin2.settings) : plugin2.settings;
6997
+ return { ...DEFAULT_SETTINGS3, ...s };
6998
+ }
6999
+ } catch {
7000
+ }
7001
+ return DEFAULT_SETTINGS3;
7002
+ }
7003
+ adminRoutes4.use("*", chunk4SHNHNRP_cjs.requireAuth());
7004
+ adminRoutes4.use("*", async (c, next) => {
7005
+ const user = c.get("user");
7006
+ if (user?.role !== "admin") {
7007
+ return c.json({ error: "Access denied" }, 403);
7008
+ }
7009
+ return next();
7010
+ });
7011
+ adminRoutes4.get("/", async (c) => {
7012
+ const user = c.get("user");
7013
+ const tenantId = c.get("tenantId") || "default";
7014
+ const keys = await new ApiKeyService(c.env.DB, tenantId).list(user.userId);
7015
+ return c.html(
7016
+ renderApiKeysPage({
7017
+ keys,
7018
+ user: { name: user.email, email: user.email, role: user.role },
7019
+ version: c.get("appVersion"),
7020
+ dynamicMenuItems: c.get("pluginMenuItems")
7021
+ })
7022
+ );
7023
+ });
7024
+ adminRoutes4.get("/api/keys", async (c) => {
7025
+ const user = c.get("user");
7026
+ const tenantId = c.get("tenantId") || "default";
7027
+ const keys = await new ApiKeyService(c.env.DB, tenantId).list(user.userId);
7028
+ return c.json({ keys });
7029
+ });
7030
+ adminRoutes4.post("/api/keys", async (c) => {
7031
+ const user = c.get("user");
7032
+ const tenantId = c.get("tenantId") || "default";
7033
+ const body = await c.req.json().catch(() => ({}));
7034
+ const parsed = createSchema.safeParse(body);
7035
+ if (!parsed.success) {
7036
+ return c.json({ error: "Invalid request", details: parsed.error.flatten() }, 400);
7037
+ }
7038
+ const settings = await getSettings3(c.env.DB);
7039
+ const svc = new ApiKeyService(c.env.DB, tenantId);
7040
+ if (await svc.countForUser(user.userId) >= settings.maxKeysPerUser) {
7041
+ return c.json({ error: `API key limit reached (max ${settings.maxKeysPerUser})` }, 409);
7042
+ }
7043
+ const days = parsed.data.expiresInDays ?? (settings.defaultExpiryDays > 0 ? settings.defaultExpiryDays : null);
7044
+ const expiresAt = days ? Date.now() + days * DAY_MS : null;
7045
+ const created = await svc.create({ userId: user.userId, name: parsed.data.name, expiresAt });
7046
+ return c.json({ apiKey: created }, 201);
7047
+ });
7048
+ adminRoutes4.delete("/api/keys/:id", async (c) => {
7049
+ const user = c.get("user");
7050
+ const tenantId = c.get("tenantId") || "default";
7051
+ const ok = await new ApiKeyService(c.env.DB, tenantId).revoke(c.req.param("id") ?? "", user.userId);
7052
+ if (!ok) return c.json({ error: "API key not found" }, 404);
7053
+ return c.json({ success: true });
7054
+ });
7055
+
7056
+ // src/plugins/core-plugins/api-keys-plugin/middleware/api-key-auth.ts
7057
+ function apiKeyAuthMiddleware() {
7058
+ return async (c, next) => {
7059
+ if (!c.get("user")) {
7060
+ const authz = c.req.header("authorization") || "";
7061
+ const bearer = authz.toLowerCase().startsWith("bearer ") ? authz.slice(7).trim() : "";
7062
+ const presented = c.req.header("x-api-key") || (bearer.startsWith("sk_") ? bearer : "");
7063
+ if (presented) {
7064
+ try {
7065
+ const tenantId = c.get("tenantId") || "default";
7066
+ const resolved = await new ApiKeyService(c.env.DB, tenantId).resolve(presented);
7067
+ if (resolved) {
7068
+ c.set("user", {
7069
+ userId: resolved.userId,
7070
+ email: resolved.email,
7071
+ role: resolved.role,
7072
+ isSuperAdmin: resolved.isSuperAdmin,
7073
+ // API keys are stateless bearer creds — no session window.
7074
+ exp: 0,
7075
+ iat: 0
7076
+ });
7077
+ }
7078
+ } catch {
7079
+ }
7080
+ }
7081
+ }
7082
+ await next();
7083
+ };
7084
+ }
7085
+
7086
+ // src/plugins/core-plugins/api-keys-plugin/index.ts
7087
+ var KEY_ICON = `<svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z"/></svg>`;
7088
+ var apiKeysPlugin = chunk5RSB5SEK_cjs.definePlugin({
7089
+ id: "api-keys",
7090
+ version: "1.0.0-beta.1",
7091
+ name: "API Keys",
7092
+ description: "Programmatic API access keys for headless / server-to-server REST access.",
7093
+ sonicjsVersionRange: "^3.0.0",
7094
+ author: { name: "SonicJS Team" },
7095
+ register(app2) {
7096
+ app2.route("/admin/plugins/api-keys", adminRoutes4);
7097
+ },
7098
+ menu: [
7099
+ { label: "API Keys", path: "/admin/plugins/api-keys", icon: KEY_ICON, order: 86 }
7100
+ ],
7101
+ configSchema: {
7102
+ maxKeysPerUser: {
7103
+ type: "number",
7104
+ label: "Max keys per user",
7105
+ description: "Hard cap on active keys a single user may hold.",
7106
+ default: 50
7107
+ },
7108
+ defaultExpiryDays: {
7109
+ type: "number",
7110
+ label: "Default expiry (days)",
7111
+ description: "Lifetime applied to new keys when no explicit expiry is given. 0 = never expires.",
7112
+ default: 0
7113
+ }
7114
+ },
7115
+ activate: async () => console.log("[ApiKeys] Plugin activated"),
7116
+ deactivate: async () => console.log("[ApiKeys] Plugin deactivated")
7117
+ });
7118
+
6637
7119
  // src/plugins/core-plugins/stripe-plugin/services/subscription-service.ts
6638
7120
  var SubscriptionService = class {
6639
7121
  constructor(db) {
6640
7122
  this.db = db;
6641
7123
  }
7124
+ db;
6642
7125
  /**
6643
7126
  * Ensure the subscriptions table exists
6644
7127
  */
@@ -6877,6 +7360,7 @@ var StripeEventService = class {
6877
7360
  constructor(db) {
6878
7361
  this.db = db;
6879
7362
  }
7363
+ db;
6880
7364
  async ensureTable() {
6881
7365
  await this.db.prepare(`
6882
7366
  CREATE TABLE IF NOT EXISTS stripe_events (
@@ -6987,7 +7471,7 @@ var StripeEventService = class {
6987
7471
  };
6988
7472
 
6989
7473
  // src/plugins/core-plugins/stripe-plugin/components/subscriptions-page.ts
6990
- chunkNAVPFIG5_cjs.init_admin_layout_catalyst_template();
7474
+ chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
6991
7475
 
6992
7476
  // src/plugins/core-plugins/stripe-plugin/components/tab-bar.ts
6993
7477
  var TABS = [
@@ -7120,7 +7604,7 @@ function renderSubscriptionsPage(data) {
7120
7604
  version,
7121
7605
  dynamicMenuItems
7122
7606
  };
7123
- return chunkNAVPFIG5_cjs.renderAdminLayoutCatalyst(layoutData);
7607
+ return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
7124
7608
  }
7125
7609
  function statsCard(label, value, colorClass) {
7126
7610
  return `
@@ -7200,7 +7684,7 @@ function renderPagination2(page, totalPages, status) {
7200
7684
  }
7201
7685
 
7202
7686
  // src/plugins/core-plugins/stripe-plugin/components/events-page.ts
7203
- chunkNAVPFIG5_cjs.init_admin_layout_catalyst_template();
7687
+ chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
7204
7688
  function renderEventsPage(data) {
7205
7689
  const { events, stats, types, filters, user, version, dynamicMenuItems } = data;
7206
7690
  const content2 = `
@@ -7273,7 +7757,7 @@ function renderEventsPage(data) {
7273
7757
  version,
7274
7758
  dynamicMenuItems
7275
7759
  };
7276
- return chunkNAVPFIG5_cjs.renderAdminLayoutCatalyst(layoutData);
7760
+ return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
7277
7761
  }
7278
7762
  function eventStatsCard(label, value, colorClass) {
7279
7763
  return `
@@ -7361,7 +7845,7 @@ function renderEventPagination(page, totalPages, type, status) {
7361
7845
  }
7362
7846
 
7363
7847
  // src/plugins/core-plugins/stripe-plugin/types.ts
7364
- var DEFAULT_SETTINGS3 = {
7848
+ var DEFAULT_SETTINGS4 = {
7365
7849
  stripePublishableKey: "",
7366
7850
  stripeSecretKey: "",
7367
7851
  stripeWebhookSecret: "",
@@ -7371,28 +7855,28 @@ var DEFAULT_SETTINGS3 = {
7371
7855
  };
7372
7856
 
7373
7857
  // src/plugins/core-plugins/stripe-plugin/routes/admin.ts
7374
- var adminRoutes4 = new hono.Hono();
7375
- adminRoutes4.use("*", chunkAAWNRBRB_cjs.requireAuth());
7376
- adminRoutes4.use("*", async (c, next) => {
7858
+ var adminRoutes5 = new hono.Hono();
7859
+ adminRoutes5.use("*", chunk4SHNHNRP_cjs.requireAuth());
7860
+ adminRoutes5.use("*", async (c, next) => {
7377
7861
  const user = c.get("user");
7378
7862
  if (user?.role !== "admin") {
7379
7863
  return c.text("Access denied", 403);
7380
7864
  }
7381
7865
  return next();
7382
7866
  });
7383
- async function getSettings3(db) {
7867
+ async function getSettings4(db) {
7384
7868
  try {
7385
- const pluginService = new chunkQAYFOER6_cjs.PluginService(db);
7869
+ const pluginService = new chunk5ARIHAGN_cjs.PluginService(db);
7386
7870
  const plugin2 = await pluginService.getPlugin("stripe");
7387
7871
  if (plugin2?.settings) {
7388
7872
  const settings = typeof plugin2.settings === "string" ? JSON.parse(plugin2.settings) : plugin2.settings;
7389
- return { ...DEFAULT_SETTINGS3, ...settings };
7873
+ return { ...DEFAULT_SETTINGS4, ...settings };
7390
7874
  }
7391
7875
  } catch {
7392
7876
  }
7393
- return DEFAULT_SETTINGS3;
7877
+ return DEFAULT_SETTINGS4;
7394
7878
  }
7395
- adminRoutes4.get("/", async (c) => {
7879
+ adminRoutes5.get("/", async (c) => {
7396
7880
  const db = c.env.DB;
7397
7881
  const user = c.get("user");
7398
7882
  const subscriptionService = new SubscriptionService(db);
@@ -7415,7 +7899,7 @@ adminRoutes4.get("/", async (c) => {
7415
7899
  });
7416
7900
  return c.html(html4);
7417
7901
  });
7418
- adminRoutes4.get("/events", async (c) => {
7902
+ adminRoutes5.get("/events", async (c) => {
7419
7903
  const db = c.env.DB;
7420
7904
  const user = c.get("user");
7421
7905
  const eventService = new StripeEventService(db);
@@ -7441,11 +7925,11 @@ adminRoutes4.get("/events", async (c) => {
7441
7925
  });
7442
7926
  return c.html(html4);
7443
7927
  });
7444
- adminRoutes4.get("/settings", async (c) => {
7928
+ adminRoutes5.get("/settings", async (c) => {
7445
7929
  const db = c.env.DB;
7446
7930
  const user = c.get("user");
7447
- const settings = await getSettings3(db);
7448
- const { renderAdminLayoutCatalyst: renderAdminLayoutCatalyst2 } = await import('./admin-layout-catalyst.template-ZK5HD545.cjs');
7931
+ const settings = await getSettings4(db);
7932
+ const { renderAdminLayoutCatalyst: renderAdminLayoutCatalyst2 } = await import('./admin-layout-catalyst.template-KDHKVLXR.cjs');
7449
7933
  const content2 = `
7450
7934
  <div>
7451
7935
  <div class="mb-6">
@@ -7551,7 +8035,7 @@ adminRoutes4.get("/settings", async (c) => {
7551
8035
  dynamicMenuItems: c.get("pluginMenuItems")
7552
8036
  }));
7553
8037
  });
7554
- adminRoutes4.post("/settings", async (c) => {
8038
+ adminRoutes5.post("/settings", async (c) => {
7555
8039
  try {
7556
8040
  const body = await c.req.json();
7557
8041
  const db = c.env.DB;
@@ -7573,6 +8057,7 @@ var StripeAPI = class {
7573
8057
  constructor(secretKey) {
7574
8058
  this.secretKey = secretKey;
7575
8059
  }
8060
+ secretKey;
7576
8061
  baseUrl = "https://api.stripe.com/v1";
7577
8062
  /**
7578
8063
  * Verify a webhook signature
@@ -7702,17 +8187,17 @@ function timingSafeEqual(a, b) {
7702
8187
 
7703
8188
  // src/plugins/core-plugins/stripe-plugin/routes/api.ts
7704
8189
  var apiRoutes3 = new hono.Hono();
7705
- async function getSettings4(db) {
8190
+ async function getSettings5(db) {
7706
8191
  try {
7707
- const pluginService = new chunkQAYFOER6_cjs.PluginService(db);
8192
+ const pluginService = new chunk5ARIHAGN_cjs.PluginService(db);
7708
8193
  const plugin2 = await pluginService.getPlugin("stripe");
7709
8194
  if (plugin2?.settings) {
7710
8195
  const settings = typeof plugin2.settings === "string" ? JSON.parse(plugin2.settings) : plugin2.settings;
7711
- return { ...DEFAULT_SETTINGS3, ...settings };
8196
+ return { ...DEFAULT_SETTINGS4, ...settings };
7712
8197
  }
7713
8198
  } catch {
7714
8199
  }
7715
- return DEFAULT_SETTINGS3;
8200
+ return DEFAULT_SETTINGS4;
7716
8201
  }
7717
8202
  function mapStripeStatus(status) {
7718
8203
  const map = {
@@ -7729,7 +8214,7 @@ function mapStripeStatus(status) {
7729
8214
  }
7730
8215
  apiRoutes3.post("/webhook", async (c) => {
7731
8216
  const db = c.env.DB;
7732
- const settings = await getSettings4(db);
8217
+ const settings = await getSettings5(db);
7733
8218
  if (!settings.stripeWebhookSecret) {
7734
8219
  return c.json({ error: "Webhook secret not configured" }, 500);
7735
8220
  }
@@ -7855,11 +8340,11 @@ apiRoutes3.post("/webhook", async (c) => {
7855
8340
  }
7856
8341
  return c.json({ received: true });
7857
8342
  });
7858
- apiRoutes3.post("/create-checkout-session", chunkAAWNRBRB_cjs.requireAuth(), async (c) => {
8343
+ apiRoutes3.post("/create-checkout-session", chunk4SHNHNRP_cjs.requireAuth(), async (c) => {
7859
8344
  const db = c.env.DB;
7860
8345
  const user = c.get("user");
7861
8346
  if (!user) return c.json({ error: "Unauthorized" }, 401);
7862
- const settings = await getSettings4(db);
8347
+ const settings = await getSettings5(db);
7863
8348
  if (!settings.stripeSecretKey) {
7864
8349
  return c.json({ error: "Stripe not configured" }, 500);
7865
8350
  }
@@ -7895,7 +8380,7 @@ apiRoutes3.post("/create-checkout-session", chunkAAWNRBRB_cjs.requireAuth(), asy
7895
8380
  });
7896
8381
  return c.json({ sessionId: session.id, url: session.url });
7897
8382
  });
7898
- apiRoutes3.get("/subscription", chunkAAWNRBRB_cjs.requireAuth(), async (c) => {
8383
+ apiRoutes3.get("/subscription", chunk4SHNHNRP_cjs.requireAuth(), async (c) => {
7899
8384
  const user = c.get("user");
7900
8385
  if (!user) return c.json({ error: "Unauthorized" }, 401);
7901
8386
  const db = c.env.DB;
@@ -7907,7 +8392,7 @@ apiRoutes3.get("/subscription", chunkAAWNRBRB_cjs.requireAuth(), async (c) => {
7907
8392
  }
7908
8393
  return c.json({ subscription });
7909
8394
  });
7910
- apiRoutes3.get("/subscriptions", chunkAAWNRBRB_cjs.requireAuth(), async (c) => {
8395
+ apiRoutes3.get("/subscriptions", chunk4SHNHNRP_cjs.requireAuth(), async (c) => {
7911
8396
  const user = c.get("user");
7912
8397
  if (user?.role !== "admin") return c.json({ error: "Access denied" }, 403);
7913
8398
  const db = c.env.DB;
@@ -7923,7 +8408,7 @@ apiRoutes3.get("/subscriptions", chunkAAWNRBRB_cjs.requireAuth(), async (c) => {
7923
8408
  const result = await subscriptionService.list(filters);
7924
8409
  return c.json(result);
7925
8410
  });
7926
- apiRoutes3.get("/stats", chunkAAWNRBRB_cjs.requireAuth(), async (c) => {
8411
+ apiRoutes3.get("/stats", chunk4SHNHNRP_cjs.requireAuth(), async (c) => {
7927
8412
  const user = c.get("user");
7928
8413
  if (user?.role !== "admin") return c.json({ error: "Access denied" }, 403);
7929
8414
  const db = c.env.DB;
@@ -7932,11 +8417,11 @@ apiRoutes3.get("/stats", chunkAAWNRBRB_cjs.requireAuth(), async (c) => {
7932
8417
  const stats = await subscriptionService.getStats();
7933
8418
  return c.json(stats);
7934
8419
  });
7935
- apiRoutes3.post("/sync-subscriptions", chunkAAWNRBRB_cjs.requireAuth(), async (c) => {
8420
+ apiRoutes3.post("/sync-subscriptions", chunk4SHNHNRP_cjs.requireAuth(), async (c) => {
7936
8421
  const user = c.get("user");
7937
8422
  if (user?.role !== "admin") return c.json({ error: "Access denied" }, 403);
7938
8423
  const db = c.env.DB;
7939
- const settings = await getSettings4(db);
8424
+ const settings = await getSettings5(db);
7940
8425
  if (!settings.stripeSecretKey) {
7941
8426
  return c.json({ error: "Stripe secret key not configured" }, 400);
7942
8427
  }
@@ -7980,7 +8465,7 @@ apiRoutes3.post("/sync-subscriptions", chunkAAWNRBRB_cjs.requireAuth(), async (c
7980
8465
  }, 500);
7981
8466
  }
7982
8467
  });
7983
- apiRoutes3.get("/events", chunkAAWNRBRB_cjs.requireAuth(), async (c) => {
8468
+ apiRoutes3.get("/events", chunk4SHNHNRP_cjs.requireAuth(), async (c) => {
7984
8469
  const user = c.get("user");
7985
8470
  if (user?.role !== "admin") return c.json({ error: "Access denied" }, 403);
7986
8471
  const db = c.env.DB;
@@ -8003,7 +8488,7 @@ apiRoutes3.get("/events", chunkAAWNRBRB_cjs.requireAuth(), async (c) => {
8003
8488
 
8004
8489
  // src/plugins/core-plugins/stripe-plugin/index.ts
8005
8490
  var STRIPE_ICON = `<svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z"/></svg>`;
8006
- var stripePlugin = chunkXW56B23A_cjs.definePlugin({
8491
+ var stripePlugin = chunk5RSB5SEK_cjs.definePlugin({
8007
8492
  id: "stripe",
8008
8493
  version: "1.0.0",
8009
8494
  name: "Stripe",
@@ -8011,7 +8496,7 @@ var stripePlugin = chunkXW56B23A_cjs.definePlugin({
8011
8496
  sonicjsVersionRange: "^3.0.0",
8012
8497
  author: { name: "SonicJS Team" },
8013
8498
  register(app2) {
8014
- app2.route("/admin/plugins/stripe", adminRoutes4);
8499
+ app2.route("/admin/plugins/stripe", adminRoutes5);
8015
8500
  app2.route("/api/stripe", apiRoutes3);
8016
8501
  },
8017
8502
  menu: [
@@ -8024,7 +8509,7 @@ var stripePlugin = chunkXW56B23A_cjs.definePlugin({
8024
8509
  });
8025
8510
 
8026
8511
  // src/templates/pages/admin-forms-list.template.ts
8027
- chunkNAVPFIG5_cjs.init_admin_layout_catalyst_template();
8512
+ chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
8028
8513
  function renderFormsListPage(data) {
8029
8514
  const tableData = {
8030
8515
  tableId: "forms-table",
@@ -8276,7 +8761,7 @@ function renderFormsListPage(data) {
8276
8761
 
8277
8762
  <!-- Forms Table -->
8278
8763
  <div class="bg-white dark:bg-zinc-900 rounded-lg border border-zinc-950/5 dark:border-white/10 overflow-hidden">
8279
- ${chunkVXE42MYF_cjs.renderTable(tableData)}
8764
+ ${chunk3E7IROND_cjs.renderTable(tableData)}
8280
8765
  </div>
8281
8766
  </div>
8282
8767
  `;
@@ -8286,11 +8771,11 @@ function renderFormsListPage(data) {
8286
8771
  user: data.user,
8287
8772
  version: data.version
8288
8773
  };
8289
- return chunkNAVPFIG5_cjs.renderAdminLayoutCatalyst(layoutData);
8774
+ return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
8290
8775
  }
8291
8776
 
8292
8777
  // src/templates/pages/admin-forms-builder.template.ts
8293
- chunkNAVPFIG5_cjs.init_admin_layout_catalyst_template();
8778
+ chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
8294
8779
  function getTurnstileComponentScript() {
8295
8780
  return `
8296
8781
  (function() {
@@ -9503,11 +9988,11 @@ ${getTurnstileComponentScript()}
9503
9988
  user: data.user,
9504
9989
  version: data.version
9505
9990
  };
9506
- return chunkNAVPFIG5_cjs.renderAdminLayoutCatalyst(layoutData);
9991
+ return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
9507
9992
  }
9508
9993
 
9509
9994
  // src/templates/pages/admin-forms-create.template.ts
9510
- chunkNAVPFIG5_cjs.init_admin_layout_catalyst_template();
9995
+ chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
9511
9996
  function renderFormCreatePage(data) {
9512
9997
  const pageContent = `
9513
9998
  <div class="max-w-3xl mx-auto">
@@ -9700,12 +10185,13 @@ function renderFormCreatePage(data) {
9700
10185
  user: data.user,
9701
10186
  version: data.version
9702
10187
  };
9703
- return chunkNAVPFIG5_cjs.renderAdminLayoutCatalyst(layoutData);
10188
+ return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
9704
10189
  }
9705
10190
 
9706
10191
  // src/routes/admin-forms.ts
10192
+ var isTableMissing = (err) => String(err?.message ?? err?.cause?.message ?? "").includes("no such table: forms");
9707
10193
  var adminFormsRoutes = new hono.Hono();
9708
- adminFormsRoutes.use("*", chunkAAWNRBRB_cjs.requireAuth());
10194
+ adminFormsRoutes.use("*", chunk4SHNHNRP_cjs.requireAuth());
9709
10195
  adminFormsRoutes.get("/", async (c) => {
9710
10196
  try {
9711
10197
  const user = c.get("user");
@@ -9745,6 +10231,14 @@ adminFormsRoutes.get("/", async (c) => {
9745
10231
  };
9746
10232
  return c.html(renderFormsListPage(pageData));
9747
10233
  } catch (error) {
10234
+ if (isTableMissing(error)) {
10235
+ const user = c.get("user");
10236
+ return c.html(renderFormsListPage({
10237
+ forms: [],
10238
+ user: user ? { name: user.email, email: user.email, role: user.role } : void 0,
10239
+ version: c.get("appVersion")
10240
+ }));
10241
+ }
9748
10242
  console.error("Error listing forms:", error);
9749
10243
  return c.html("<p>Error loading forms</p>", 500);
9750
10244
  }
@@ -9855,6 +10349,7 @@ adminFormsRoutes.post("/", async (c) => {
9855
10349
  ).run();
9856
10350
  return c.redirect(`/admin/forms/${formId}/builder`);
9857
10351
  } catch (error) {
10352
+ if (isTableMissing(error)) return c.json({ error: "Forms storage not configured \u2014 run database migrations" }, 503);
9858
10353
  console.error("Error creating form:", error);
9859
10354
  return c.json({ error: "Failed to create form" }, 500);
9860
10355
  }
@@ -9869,7 +10364,7 @@ adminFormsRoutes.get("/:id/builder", async (c) => {
9869
10364
  if (!form) {
9870
10365
  return c.html("<p>Form not found</p>", 404);
9871
10366
  }
9872
- const turnstileService = new chunkH2AXVCLS_cjs.TurnstileService(db);
10367
+ const turnstileService = new chunkDTGCXWWM_cjs.TurnstileService(db);
9873
10368
  const turnstileSettings = await turnstileService.getSettings();
9874
10369
  const pageData = {
9875
10370
  id: form.id,
@@ -9892,6 +10387,7 @@ adminFormsRoutes.get("/:id/builder", async (c) => {
9892
10387
  };
9893
10388
  return c.html(renderFormBuilderPage(pageData));
9894
10389
  } catch (error) {
10390
+ if (isTableMissing(error)) return c.html("<p>Forms storage not configured \u2014 run database migrations</p>", 503);
9895
10391
  console.error("Error showing form builder:", error);
9896
10392
  return c.html("<p>Error loading form builder</p>", 500);
9897
10393
  }
@@ -9921,6 +10417,7 @@ adminFormsRoutes.put("/:id", async (c) => {
9921
10417
  ).run();
9922
10418
  return c.json({ success: true, message: "Form saved successfully" });
9923
10419
  } catch (error) {
10420
+ if (isTableMissing(error)) return c.json({ error: "Forms storage not configured \u2014 run database migrations" }, 503);
9924
10421
  console.error("Error updating form:", error);
9925
10422
  return c.json({ error: "Failed to save form" }, 500);
9926
10423
  }
@@ -9942,6 +10439,7 @@ adminFormsRoutes.delete("/:id", async (c) => {
9942
10439
  await db.prepare("DELETE FROM forms WHERE id = ?").bind(formId).run();
9943
10440
  return c.json({ success: true, message: "Form deleted successfully" });
9944
10441
  } catch (error) {
10442
+ if (isTableMissing(error)) return c.json({ error: "Forms storage not configured \u2014 run database migrations" }, 503);
9945
10443
  console.error("Error deleting form:", error);
9946
10444
  return c.json({ error: "Failed to delete form" }, 500);
9947
10445
  }
@@ -10002,6 +10500,7 @@ adminFormsRoutes.get("/:id/submissions", async (c) => {
10002
10500
  `;
10003
10501
  return c.html(html4);
10004
10502
  } catch (error) {
10503
+ if (isTableMissing(error)) return c.html("<p>Forms storage not configured \u2014 run database migrations</p>", 503);
10005
10504
  console.error("Error loading submissions:", error);
10006
10505
  return c.html("<p>Error loading submissions</p>", 500);
10007
10506
  }
@@ -10022,6 +10521,7 @@ function sanitizeDeep(value) {
10022
10521
  }
10023
10522
  return value;
10024
10523
  }
10524
+ var isTableMissing2 = (err) => String(err?.message ?? err?.cause?.message ?? "").includes("no such table: form");
10025
10525
  var publicFormsRoutes = new hono.Hono();
10026
10526
  publicFormsRoutes.get("/:identifier/turnstile-config", async (c) => {
10027
10527
  try {
@@ -10033,7 +10533,7 @@ publicFormsRoutes.get("/:identifier/turnstile-config", async (c) => {
10033
10533
  if (!form) {
10034
10534
  return c.json({ error: "Form not found" }, 404);
10035
10535
  }
10036
- const turnstileService = new chunkH2AXVCLS_cjs.TurnstileService(db);
10536
+ const turnstileService = new chunkDTGCXWWM_cjs.TurnstileService(db);
10037
10537
  const globalSettings = await turnstileService.getSettings();
10038
10538
  const formSettings = form.turnstile_settings ? JSON.parse(form.turnstile_settings) : { inherit: true };
10039
10539
  const enabled = form.turnstile_enabled === 1 || formSettings.inherit && globalSettings?.enabled;
@@ -10049,6 +10549,7 @@ publicFormsRoutes.get("/:identifier/turnstile-config", async (c) => {
10049
10549
  appearance: formSettings.appearance || globalSettings.appearance || "always"
10050
10550
  });
10051
10551
  } catch (error) {
10552
+ if (isTableMissing2(error)) return c.json({ enabled: false });
10052
10553
  console.error("Error fetching Turnstile config:", error);
10053
10554
  return c.json({ error: "Failed to fetch config" }, 500);
10054
10555
  }
@@ -10076,6 +10577,7 @@ publicFormsRoutes.get("/:identifier/schema", async (c) => {
10076
10577
  submitUrl: `/api/forms/${form.id}/submit`
10077
10578
  });
10078
10579
  } catch (error) {
10580
+ if (isTableMissing2(error)) return c.json({ error: "Form not found" }, 404);
10079
10581
  console.error("Error fetching form schema:", error);
10080
10582
  return c.json({ error: "Failed to fetch form schema" }, 500);
10081
10583
  }
@@ -10442,6 +10944,7 @@ publicFormsRoutes.get("/:name", async (c) => {
10442
10944
  `;
10443
10945
  return c.html(html4);
10444
10946
  } catch (error) {
10947
+ if (isTableMissing2(error)) return c.html("<h1>Form not found</h1><p>This form does not exist or is not publicly available.</p>", 404);
10445
10948
  console.error("Error rendering form:", error);
10446
10949
  return c.html("<p>Error loading form</p>", 500);
10447
10950
  }
@@ -10460,7 +10963,7 @@ publicFormsRoutes.post("/:identifier/submit", async (c) => {
10460
10963
  const turnstileEnabled = form.turnstile_enabled === 1;
10461
10964
  const turnstileSettings = form.turnstile_settings ? JSON.parse(form.turnstile_settings) : { inherit: true };
10462
10965
  if (turnstileEnabled || turnstileSettings.inherit) {
10463
- const turnstileService = new chunkH2AXVCLS_cjs.TurnstileService(db);
10966
+ const turnstileService = new chunkDTGCXWWM_cjs.TurnstileService(db);
10464
10967
  const globalEnabled = await turnstileService.isEnabled();
10465
10968
  if (globalEnabled || turnstileEnabled) {
10466
10969
  const turnstileToken = body.data?.turnstile || body.turnstile;
@@ -10515,13 +11018,14 @@ publicFormsRoutes.post("/:identifier/submit", async (c) => {
10515
11018
  message: "Form submitted successfully"
10516
11019
  });
10517
11020
  } catch (error) {
11021
+ if (isTableMissing2(error)) return c.json({ error: "Form not found" }, 404);
10518
11022
  console.error("Error submitting form:", error);
10519
11023
  return c.json({ error: "Failed to submit form" }, 500);
10520
11024
  }
10521
11025
  });
10522
11026
 
10523
11027
  // src/plugins/core-plugins/forms-plugin/index.ts
10524
- var formsPlugin = chunkXW56B23A_cjs.definePlugin({
11028
+ var formsPlugin = chunk5RSB5SEK_cjs.definePlugin({
10525
11029
  id: "forms",
10526
11030
  version: "1.0.0",
10527
11031
  name: "Forms",
@@ -10539,9 +11043,9 @@ var formsPlugin = chunkXW56B23A_cjs.definePlugin({
10539
11043
  activate: async () => console.info("\u2705 Forms plugin activated"),
10540
11044
  deactivate: async () => console.info("\u274C Forms plugin deactivated")
10541
11045
  });
10542
- chunkNAVPFIG5_cjs.init_admin_layout_catalyst_template();
11046
+ chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
10543
11047
  var adminRbacRoutes = new hono.Hono();
10544
- adminRbacRoutes.use("*", chunkAAWNRBRB_cjs.requireRbac("rbac", "manage"));
11048
+ adminRbacRoutes.use("*", chunk4SHNHNRP_cjs.requireRbac("rbac", "manage"));
10545
11049
  var esc = (s) => String(s).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
10546
11050
  var TABS2 = `
10547
11051
  <div class="border-b border-zinc-950/10 dark:border-white/10 mb-6">
@@ -10551,7 +11055,7 @@ var TABS2 = `
10551
11055
  </nav>
10552
11056
  </div>`;
10553
11057
  adminRbacRoutes.get("/", async (c) => {
10554
- const rbac = new chunk2CB4KY7I_cjs.RbacService(c.env.DB);
11058
+ const rbac = new chunkLTZ5WYOK_cjs.RbacService(c.env.DB);
10555
11059
  const [roles, verbs, resources, grants] = await Promise.all([
10556
11060
  rbac.getRoles(),
10557
11061
  rbac.getVerbs(),
@@ -10662,7 +11166,7 @@ adminRbacRoutes.get("/", async (c) => {
10662
11166
  ${r.is_system ? `<code class="text-xs text-zinc-500 dark:text-zinc-400">${esc(r.name)}</code><span class="rounded-full bg-zinc-100 dark:bg-white/10 px-2 py-0.5 text-[11px] text-zinc-500 dark:text-zinc-400">system</span>` : `<input form="roles-bulk-form" class="${inpSm} w-28" name="name_${esc(r.id)}" value="${esc(r.name)}" required>`}
10663
11167
  <label class="ml-auto inline-flex items-center gap-2 rounded-md bg-white/5 px-2.5 py-1 text-xs font-medium text-zinc-700 dark:text-zinc-300 ring-1 ring-inset ring-zinc-500/20">
10664
11168
  <input form="roles-bulk-form" type="checkbox" name="portal_${esc(r.id)}" value="1" ${portalChecked ? "checked" : ""} ${portalDisabled ? "disabled" : ""} class="h-3.5 w-3.5 rounded border-zinc-400 text-cyan-600 focus:ring-cyan-500">
10665
- Access portal
11169
+ Admin Panel
10666
11170
  </label>
10667
11171
  <a href="/admin/tenants/roles/${esc(r.name)}" data-role-tenants="${esc(r.name)}" class="text-xs text-cyan-600 dark:text-cyan-400 hover:underline" title="Per-tenant assignments of this role">tenants</a>
10668
11172
  ${r.is_system ? "" : `<button form="delete-role-${esc(r.id)}" type="submit" onclick="return confirm('Delete role ${esc(r.name)}?')" class="text-xs text-red-600 dark:text-red-400 hover:underline">delete</button>`}
@@ -10766,7 +11270,7 @@ adminRbacRoutes.get("/", async (c) => {
10766
11270
  <div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-6">
10767
11271
  <div class="${card}">
10768
11272
  <h3 class="text-base font-semibold text-zinc-950 dark:text-white mb-3">Roles</h3>
10769
- <p class="mb-3 text-xs text-zinc-500 dark:text-zinc-400">Use <strong>Access portal</strong> to allow a role into the admin backend. Resource permissions are configured in the <strong>Matrix</strong> tab.</p>
11273
+ <p class="mb-3 text-xs text-zinc-500 dark:text-zinc-400">Use <strong>Admin Panel</strong> to allow a role into the admin backend. Resource permissions are configured in the <strong>Matrix</strong> tab.</p>
10770
11274
  ${roleList}
10771
11275
  </div>
10772
11276
  <div class="${card}">
@@ -10845,11 +11349,11 @@ adminRbacRoutes.get("/", async (c) => {
10845
11349
  </script>`;
10846
11350
  const u = c.get("user");
10847
11351
  return c.html(
10848
- chunkNAVPFIG5_cjs.renderAdminLayoutCatalyst({
11352
+ chunkK623Q6WD_cjs.renderAdminLayoutCatalyst({
10849
11353
  title: "Roles & Permissions",
10850
11354
  pageTitle: "Roles & Permissions",
10851
11355
  currentPath: "/admin/users",
10852
- version: chunkLRZIAW7U_cjs.getCoreVersion(),
11356
+ version: chunkAQJEMVAY_cjs.getCoreVersion(),
10853
11357
  user: u ? { name: u.email || "Admin", email: u.email || "", role: u.role || "admin" } : void 0,
10854
11358
  content: content2
10855
11359
  })
@@ -10873,7 +11377,7 @@ adminRbacRoutes.post("/grants", async (c) => {
10873
11377
  pairsByRole.get(roleId).push({ resource, verb, scope });
10874
11378
  }
10875
11379
  }
10876
- const rbac = new chunk2CB4KY7I_cjs.RbacService(c.env.DB);
11380
+ const rbac = new chunkLTZ5WYOK_cjs.RbacService(c.env.DB);
10877
11381
  for (const id of saveRoleIds) {
10878
11382
  await rbac.setRoleGrants(id, pairsByRole.get(id) || []);
10879
11383
  }
@@ -10894,7 +11398,7 @@ adminRbacRoutes.post("/grants", async (c) => {
10894
11398
  adminRbacRoutes.post("/roles/bulk", async (c) => {
10895
11399
  const form = await c.req.formData();
10896
11400
  const roleIds = String(form.get("role_ids") || "").split(",").filter(Boolean);
10897
- const rbac = new chunk2CB4KY7I_cjs.RbacService(c.env.DB);
11401
+ const rbac = new chunkLTZ5WYOK_cjs.RbacService(c.env.DB);
10898
11402
  for (const roleId of roleIds) {
10899
11403
  const displayName = String(form.get(`display_name_${roleId}`) || "").trim();
10900
11404
  const nameVal = form.get(`name_${roleId}`) ? String(form.get(`name_${roleId}`)).trim() : void 0;
@@ -10919,7 +11423,7 @@ adminRbacRoutes.post("/roles", async (c) => {
10919
11423
  const displayName = String(form.get("display_name") || "").trim();
10920
11424
  if (name && displayName) {
10921
11425
  try {
10922
- await new chunk2CB4KY7I_cjs.RbacService(c.env.DB).createRole(name, displayName);
11426
+ await new chunkLTZ5WYOK_cjs.RbacService(c.env.DB).createRole(name, displayName);
10923
11427
  } catch {
10924
11428
  }
10925
11429
  }
@@ -10934,7 +11438,7 @@ adminRbacRoutes.post("/roles/:id", async (c) => {
10934
11438
  const portalAccess = form.get("portal_access") === "1";
10935
11439
  if (displayName) {
10936
11440
  try {
10937
- const rbac = new chunk2CB4KY7I_cjs.RbacService(c.env.DB);
11441
+ const rbac = new chunkLTZ5WYOK_cjs.RbacService(c.env.DB);
10938
11442
  if (roleId !== "role-admin") {
10939
11443
  await rbac.updateRoleAndPortalAccess(roleId, displayName, name, portalAccess, description);
10940
11444
  } else {
@@ -10946,7 +11450,7 @@ adminRbacRoutes.post("/roles/:id", async (c) => {
10946
11450
  return c.redirect(`/admin/rbac#roles-verbs`);
10947
11451
  });
10948
11452
  adminRbacRoutes.post("/roles/:id/delete", async (c) => {
10949
- await new chunk2CB4KY7I_cjs.RbacService(c.env.DB).deleteRole(c.req.param("id"));
11453
+ await new chunkLTZ5WYOK_cjs.RbacService(c.env.DB).deleteRole(c.req.param("id"));
10950
11454
  return c.redirect("/admin/rbac#roles-verbs");
10951
11455
  });
10952
11456
  adminRbacRoutes.post("/verbs", async (c) => {
@@ -10954,18 +11458,18 @@ adminRbacRoutes.post("/verbs", async (c) => {
10954
11458
  const name = String(form.get("name") || "").trim();
10955
11459
  if (name) {
10956
11460
  try {
10957
- await new chunk2CB4KY7I_cjs.RbacService(c.env.DB).createVerb(name);
11461
+ await new chunkLTZ5WYOK_cjs.RbacService(c.env.DB).createVerb(name);
10958
11462
  } catch {
10959
11463
  }
10960
11464
  }
10961
11465
  return c.redirect("/admin/rbac#roles-verbs");
10962
11466
  });
10963
11467
  adminRbacRoutes.post("/verbs/:id/delete", async (c) => {
10964
- await new chunk2CB4KY7I_cjs.RbacService(c.env.DB).deleteVerb(c.req.param("id"));
11468
+ await new chunkLTZ5WYOK_cjs.RbacService(c.env.DB).deleteVerb(c.req.param("id"));
10965
11469
  return c.redirect("/admin/rbac#roles-verbs");
10966
11470
  });
10967
11471
  adminRbacRoutes.get("/check", async (c) => {
10968
- const rbac = new chunk2CB4KY7I_cjs.RbacService(c.env.DB);
11472
+ const rbac = new chunkLTZ5WYOK_cjs.RbacService(c.env.DB);
10969
11473
  const resource = c.req.query("resource") || "";
10970
11474
  const verb = c.req.query("verb") || "";
10971
11475
  const roleId = c.req.query("role");
@@ -10986,7 +11490,7 @@ adminRbacRoutes.get("/check", async (c) => {
10986
11490
  });
10987
11491
 
10988
11492
  // src/middleware/plugin-menu.ts
10989
- var REGISTRY_MENU_PLUGINS = Object.values(chunkQAYFOER6_cjs.PLUGIN_REGISTRY).filter((p) => p.adminMenu !== null).map((p) => ({
11493
+ var REGISTRY_MENU_PLUGINS = Object.values(chunk5ARIHAGN_cjs.PLUGIN_REGISTRY).filter((p) => p.adminMenu !== null).map((p) => ({
10990
11494
  id: p.id,
10991
11495
  label: p.adminMenu.label,
10992
11496
  path: p.adminMenu.path,
@@ -11064,14 +11568,24 @@ function pluginMenuMiddleware() {
11064
11568
  }
11065
11569
  } catch {
11066
11570
  }
11067
- c.set("pluginMenuItems", activeMenuItems.map((m) => ({ label: m.label, path: m.path, icon: resolveIcon(m.icon) || "" })));
11571
+ const user = c.get("user");
11572
+ const singletonItems = chunkDTGCXWWM_cjs.resolvePluginMenuItems(user ? { role: user.role } : void 0);
11573
+ const existingPaths = new Set(activeMenuItems.map((i) => i.path));
11574
+ for (const item of singletonItems) {
11575
+ if (!existingPaths.has(item.path)) {
11576
+ activeMenuItems.push({ label: item.label, path: item.path, icon: item.icon, order: item.order });
11577
+ }
11578
+ }
11579
+ activeMenuItems.sort((a, b) => a.order - b.order);
11580
+ c.set("pluginMenuItems", activeMenuItems.map((m) => ({ label: m.label, path: m.path, icon: resolveIcon(m.icon) || m.icon || "" })));
11068
11581
  await next();
11069
- if (activeMenuItems.length > 0 && c.res.headers.get("content-type")?.includes("text/html")) {
11582
+ const finalItems = c.get("pluginMenuItems") ?? [];
11583
+ if (finalItems.length > 0 && c.res.headers.get("content-type")?.includes("text/html")) {
11070
11584
  const status = c.res.status;
11071
11585
  const headers = new Headers(c.res.headers);
11072
11586
  const html4 = await c.res.text();
11073
11587
  if (html4.includes(MARKER)) {
11074
- const renderedItems = activeMenuItems.map((item) => renderMenuItem(item, path)).join("");
11588
+ const renderedItems = finalItems.map((item) => renderMenuItem(item, path)).join("");
11075
11589
  const newHtml = html4.split(MARKER).join(renderedItems);
11076
11590
  c.res = new Response(newHtml, { status, headers });
11077
11591
  } else {
@@ -11080,17 +11594,17 @@ function pluginMenuMiddleware() {
11080
11594
  }
11081
11595
  };
11082
11596
  }
11083
- chunkNAVPFIG5_cjs.init_admin_layout_catalyst_template();
11084
- var adminRoutes5 = new hono.Hono();
11085
- adminRoutes5.use("*", chunkAAWNRBRB_cjs.requireAuth());
11086
- adminRoutes5.use("*", async (c, next) => {
11597
+ chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
11598
+ var adminRoutes6 = new hono.Hono();
11599
+ adminRoutes6.use("*", chunk4SHNHNRP_cjs.requireAuth());
11600
+ adminRoutes6.use("*", async (c, next) => {
11087
11601
  const user = c.get("user");
11088
11602
  if (user?.role !== "admin") {
11089
11603
  return c.text("Access denied", 403);
11090
11604
  }
11091
11605
  return next();
11092
11606
  });
11093
- adminRoutes5.get("/", async (c) => {
11607
+ adminRoutes6.get("/", async (c) => {
11094
11608
  const user = c.get("user");
11095
11609
  const db = c.env.DB;
11096
11610
  let totalRequests = 0;
@@ -11198,7 +11712,7 @@ adminRoutes5.get("/", async (c) => {
11198
11712
  </div>
11199
11713
  </div>
11200
11714
  `;
11201
- return c.html(chunkNAVPFIG5_cjs.renderAdminLayoutCatalyst({
11715
+ return c.html(chunkK623Q6WD_cjs.renderAdminLayoutCatalyst({
11202
11716
  title: "Analytics",
11203
11717
  pageTitle: "Analytics Dashboard",
11204
11718
  currentPath: "/admin/analytics",
@@ -11229,12 +11743,13 @@ var QUERYABLE_FIELDS2 = [
11229
11743
  var EventTrackingService = class {
11230
11744
  constructor(db) {
11231
11745
  this.db = db;
11232
- this.docsService = new chunk2CB4KY7I_cjs.DocumentsService(db, {
11746
+ this.docsService = new chunkLTZ5WYOK_cjs.DocumentsService(db, {
11233
11747
  queryableFields: QUERYABLE_FIELDS2,
11234
11748
  maxVersionsPerRoot: 1,
11235
11749
  tenantId: TENANT2
11236
11750
  });
11237
11751
  }
11752
+ db;
11238
11753
  docsService;
11239
11754
  async trackEvent(input) {
11240
11755
  const doc = await this.docsService.create({
@@ -11437,7 +11952,7 @@ apiRoutes4.get("/stats", async (c) => {
11437
11952
  });
11438
11953
 
11439
11954
  // src/plugins/core-plugins/analytics/index.ts
11440
- var analyticsPlugin = chunkXW56B23A_cjs.definePlugin({
11955
+ var analyticsPlugin = chunk5RSB5SEK_cjs.definePlugin({
11441
11956
  id: "core-analytics",
11442
11957
  version: "1.0.0",
11443
11958
  name: "Analytics",
@@ -11446,7 +11961,7 @@ var analyticsPlugin = chunkXW56B23A_cjs.definePlugin({
11446
11961
  author: { name: "SonicJS Team", email: "team@sonicjs.com" },
11447
11962
  register(app2) {
11448
11963
  app2.route("/api/events", apiRoutes4);
11449
- app2.route("/admin/analytics", adminRoutes5);
11964
+ app2.route("/admin/analytics", adminRoutes6);
11450
11965
  },
11451
11966
  menu: [
11452
11967
  {
@@ -11584,7 +12099,7 @@ function esc2(s) {
11584
12099
  return (s || "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
11585
12100
  }
11586
12101
  async function getVariablesMap(db) {
11587
- let variables = chunkVXE42MYF_cjs.getVariablesCached();
12102
+ let variables = chunk3E7IROND_cjs.getVariablesCached();
11588
12103
  if (variables) return variables;
11589
12104
  try {
11590
12105
  const { results } = await db.prepare(
@@ -11594,7 +12109,7 @@ async function getVariablesMap(db) {
11594
12109
  for (const row of results || []) {
11595
12110
  variables.set(row.key, row.value);
11596
12111
  }
11597
- chunkVXE42MYF_cjs.setVariablesCache(variables);
12112
+ chunk3E7IROND_cjs.setVariablesCache(variables);
11598
12113
  return variables;
11599
12114
  } catch {
11600
12115
  return /* @__PURE__ */ new Map();
@@ -11663,7 +12178,7 @@ apiRoutes5.post("/", async (c) => {
11663
12178
  await db.prepare(
11664
12179
  "INSERT INTO global_variables (key, value, description, category, is_active) VALUES (?, ?, ?, ?, ?)"
11665
12180
  ).bind(key, value || "", description || "", category || "general", isActive !== false ? 1 : 0).run();
11666
- chunkVXE42MYF_cjs.invalidateVariablesCache();
12181
+ chunk3E7IROND_cjs.invalidateVariablesCache();
11667
12182
  const created = await db.prepare("SELECT * FROM global_variables WHERE key = ?").bind(key).first();
11668
12183
  return c.json({ success: true, data: formatVariable(created) }, 201);
11669
12184
  } catch {
@@ -11708,7 +12223,7 @@ apiRoutes5.put("/:id", async (c) => {
11708
12223
  updates.push("updated_at = strftime('%s', 'now')");
11709
12224
  params.push(id);
11710
12225
  await db.prepare(`UPDATE global_variables SET ${updates.join(", ")} WHERE id = ?`).bind(...params).run();
11711
- chunkVXE42MYF_cjs.invalidateVariablesCache();
12226
+ chunk3E7IROND_cjs.invalidateVariablesCache();
11712
12227
  const updated = await db.prepare("SELECT * FROM global_variables WHERE id = ?").bind(id).first();
11713
12228
  return c.json({ success: true, data: formatVariable(updated) });
11714
12229
  } catch {
@@ -11722,14 +12237,14 @@ apiRoutes5.delete("/:id", async (c) => {
11722
12237
  const existing = await db.prepare("SELECT id FROM global_variables WHERE id = ?").bind(id).first();
11723
12238
  if (!existing) return c.json({ error: "Variable not found" }, 404);
11724
12239
  await db.prepare("DELETE FROM global_variables WHERE id = ?").bind(id).run();
11725
- chunkVXE42MYF_cjs.invalidateVariablesCache();
12240
+ chunk3E7IROND_cjs.invalidateVariablesCache();
11726
12241
  return c.json({ success: true });
11727
12242
  } catch {
11728
12243
  return c.json({ success: false, error: "Failed to delete variable" }, 500);
11729
12244
  }
11730
12245
  });
11731
- var adminRoutes6 = new hono.Hono();
11732
- adminRoutes6.use("*", async (c, next) => {
12246
+ var adminRoutes7 = new hono.Hono();
12247
+ adminRoutes7.use("*", async (c, next) => {
11733
12248
  try {
11734
12249
  const db = c.env?.DB;
11735
12250
  if (db) {
@@ -11740,7 +12255,7 @@ adminRoutes6.use("*", async (c, next) => {
11740
12255
  }
11741
12256
  await next();
11742
12257
  });
11743
- adminRoutes6.get("/", async (c) => {
12258
+ adminRoutes7.get("/", async (c) => {
11744
12259
  const db = c.env.DB;
11745
12260
  let variables = [];
11746
12261
  try {
@@ -11770,7 +12285,7 @@ adminRoutes6.get("/", async (c) => {
11770
12285
  }
11771
12286
  return c.html(renderAdminPage(variables, { editorActive, activeEditorName, enableEditorIntegration }));
11772
12287
  });
11773
- adminRoutes6.put("/:id", async (c) => {
12288
+ adminRoutes7.put("/:id", async (c) => {
11774
12289
  const db = c.env.DB;
11775
12290
  const id = c.req.param("id");
11776
12291
  let body;
@@ -11782,19 +12297,19 @@ adminRoutes6.put("/:id", async (c) => {
11782
12297
  const value = body.value;
11783
12298
  if (value !== void 0) {
11784
12299
  await db.prepare("UPDATE global_variables SET value = ?, updated_at = strftime('%s', 'now') WHERE id = ?").bind(value, id).run();
11785
- chunkVXE42MYF_cjs.invalidateVariablesCache();
12300
+ chunk3E7IROND_cjs.invalidateVariablesCache();
11786
12301
  }
11787
12302
  return c.html('<span class="text-green-400 text-xs">Saved</span>');
11788
12303
  });
11789
- adminRoutes6.post("/:id/toggle", async (c) => {
12304
+ adminRoutes7.post("/:id/toggle", async (c) => {
11790
12305
  const db = c.env.DB;
11791
12306
  const id = c.req.param("id");
11792
12307
  await db.prepare("UPDATE global_variables SET is_active = CASE WHEN is_active = 1 THEN 0 ELSE 1 END, updated_at = strftime('%s', 'now') WHERE id = ?").bind(id).run();
11793
- chunkVXE42MYF_cjs.invalidateVariablesCache();
12308
+ chunk3E7IROND_cjs.invalidateVariablesCache();
11794
12309
  c.header("HX-Redirect", "/admin/global-variables");
11795
12310
  return c.body(null, 204);
11796
12311
  });
11797
- adminRoutes6.post("/", async (c) => {
12312
+ adminRoutes7.post("/", async (c) => {
11798
12313
  const db = c.env.DB;
11799
12314
  const form = await c.req.parseBody();
11800
12315
  const key = (form.key || "").trim();
@@ -11811,11 +12326,11 @@ adminRoutes6.post("/", async (c) => {
11811
12326
  await db.prepare(
11812
12327
  "INSERT INTO global_variables (key, value, description, category) VALUES (?, ?, ?, ?)"
11813
12328
  ).bind(key, value, description, category).run();
11814
- chunkVXE42MYF_cjs.invalidateVariablesCache();
12329
+ chunk3E7IROND_cjs.invalidateVariablesCache();
11815
12330
  c.header("HX-Redirect", "/admin/global-variables");
11816
12331
  return c.body(null, 204);
11817
12332
  });
11818
- adminRoutes6.post("/settings/editor-integration", async (c) => {
12333
+ adminRoutes7.post("/settings/editor-integration", async (c) => {
11819
12334
  const db = c.env.DB;
11820
12335
  try {
11821
12336
  const row = await db.prepare("SELECT settings FROM plugins WHERE id = 'global-variables'").first();
@@ -11827,10 +12342,10 @@ adminRoutes6.post("/settings/editor-integration", async (c) => {
11827
12342
  return c.json({ success: false, error: "Failed to update setting" }, 500);
11828
12343
  }
11829
12344
  });
11830
- adminRoutes6.delete("/:id", async (c) => {
12345
+ adminRoutes7.delete("/:id", async (c) => {
11831
12346
  const db = c.env.DB;
11832
12347
  await db.prepare("DELETE FROM global_variables WHERE id = ?").bind(c.req.param("id")).run();
11833
- chunkVXE42MYF_cjs.invalidateVariablesCache();
12348
+ chunk3E7IROND_cjs.invalidateVariablesCache();
11834
12349
  return c.html("");
11835
12350
  });
11836
12351
  function renderAdminPage(variables, editorStatus = { editorActive: false, activeEditorName: "", enableEditorIntegration: true }) {
@@ -12148,7 +12663,7 @@ function renderAdminPage(variables, editorStatus = { editorActive: false, active
12148
12663
  </div>
12149
12664
  ` });
12150
12665
  }
12151
- var globalVariablesPlugin = chunkXW56B23A_cjs.definePlugin({
12666
+ var globalVariablesPlugin = chunk5RSB5SEK_cjs.definePlugin({
12152
12667
  id: "global-variables",
12153
12668
  version: "1.1.0",
12154
12669
  name: "Global Variables",
@@ -12158,7 +12673,7 @@ var globalVariablesPlugin = chunkXW56B23A_cjs.definePlugin({
12158
12673
  capabilities: ["hooks.content:subscribe"],
12159
12674
  register(app2) {
12160
12675
  app2.route("/api/global-variables", apiRoutes5);
12161
- app2.route("/admin/global-variables", adminRoutes6);
12676
+ app2.route("/admin/global-variables", adminRoutes7);
12162
12677
  },
12163
12678
  menu: [
12164
12679
  { label: "Global Variables", path: "/admin/global-variables", icon: "bolt", order: 45, permissions: ["global-variables:view"] }
@@ -12171,7 +12686,7 @@ var globalVariablesPlugin = chunkXW56B23A_cjs.definePlugin({
12171
12686
  if (!db || !data) return data;
12172
12687
  const variables = await getVariablesMap(db);
12173
12688
  if (variables.size === 0) return data;
12174
- return chunkVXE42MYF_cjs.resolveVariablesInObject(data, variables);
12689
+ return chunk3E7IROND_cjs.resolveVariablesInObject(data, variables);
12175
12690
  } catch {
12176
12691
  return data;
12177
12692
  }
@@ -12189,7 +12704,7 @@ var globalVariablesPlugin = chunkXW56B23A_cjs.definePlugin({
12189
12704
  },
12190
12705
  activate: async () => console.info("[GlobalVariables] Plugin activated"),
12191
12706
  deactivate: async () => {
12192
- chunkVXE42MYF_cjs.invalidateVariablesCache();
12707
+ chunk3E7IROND_cjs.invalidateVariablesCache();
12193
12708
  console.info("[GlobalVariables] Plugin deactivated, cache cleared");
12194
12709
  },
12195
12710
  uninstall: async (ctx) => {
@@ -12479,8 +12994,8 @@ apiRoutes6.delete("/:id", async (c) => {
12479
12994
  return c.json({ success: false, error: "Failed to delete shortcode" }, 500);
12480
12995
  }
12481
12996
  });
12482
- var adminRoutes7 = new hono.Hono();
12483
- adminRoutes7.use("*", async (c, next) => {
12997
+ var adminRoutes8 = new hono.Hono();
12998
+ adminRoutes8.use("*", async (c, next) => {
12484
12999
  try {
12485
13000
  const db = c.env?.DB;
12486
13001
  if (db) {
@@ -12491,7 +13006,7 @@ adminRoutes7.use("*", async (c, next) => {
12491
13006
  }
12492
13007
  await next();
12493
13008
  });
12494
- adminRoutes7.get("/", async (c) => {
13009
+ adminRoutes8.get("/", async (c) => {
12495
13010
  const db = c.env.DB;
12496
13011
  let shortcodes = [];
12497
13012
  try {
@@ -12521,7 +13036,7 @@ adminRoutes7.get("/", async (c) => {
12521
13036
  }
12522
13037
  return c.html(renderAdminPage2(shortcodes, { editorActive, activeEditorName, enableEditorIntegration }));
12523
13038
  });
12524
- adminRoutes7.post("/", async (c) => {
13039
+ adminRoutes8.post("/", async (c) => {
12525
13040
  const db = c.env.DB;
12526
13041
  const form = await c.req.parseBody();
12527
13042
  const name = (form.name || "").trim();
@@ -12542,7 +13057,7 @@ adminRoutes7.post("/", async (c) => {
12542
13057
  c.header("HX-Redirect", "/admin/shortcodes");
12543
13058
  return c.body(null, 204);
12544
13059
  });
12545
- adminRoutes7.post("/settings/editor-integration", async (c) => {
13060
+ adminRoutes8.post("/settings/editor-integration", async (c) => {
12546
13061
  const db = c.env.DB;
12547
13062
  try {
12548
13063
  const row = await db.prepare("SELECT settings FROM plugins WHERE id = 'shortcodes'").first();
@@ -12554,7 +13069,7 @@ adminRoutes7.post("/settings/editor-integration", async (c) => {
12554
13069
  return c.json({ success: false, error: "Failed to update setting" }, 500);
12555
13070
  }
12556
13071
  });
12557
- adminRoutes7.delete("/:id", async (c) => {
13072
+ adminRoutes8.delete("/:id", async (c) => {
12558
13073
  await c.env.DB.prepare("DELETE FROM shortcodes WHERE id = ?").bind(c.req.param("id")).run();
12559
13074
  return c.html("");
12560
13075
  });
@@ -12755,7 +13270,7 @@ function renderAdminPage2(shortcodes, editorStatus = { editorActive: false, acti
12755
13270
  </div>
12756
13271
  ` });
12757
13272
  }
12758
- var shortcodesPlugin = chunkXW56B23A_cjs.definePlugin({
13273
+ var shortcodesPlugin = chunk5RSB5SEK_cjs.definePlugin({
12759
13274
  id: "shortcodes",
12760
13275
  version: "1.0.0",
12761
13276
  name: "Shortcodes",
@@ -12765,7 +13280,7 @@ var shortcodesPlugin = chunkXW56B23A_cjs.definePlugin({
12765
13280
  capabilities: ["hooks.content:subscribe"],
12766
13281
  register(app2) {
12767
13282
  app2.route("/api/shortcodes", apiRoutes6);
12768
- app2.route("/admin/shortcodes", adminRoutes7);
13283
+ app2.route("/admin/shortcodes", adminRoutes8);
12769
13284
  },
12770
13285
  menu: [
12771
13286
  { label: "Shortcodes", path: "/admin/shortcodes", icon: "bolt", order: 46, permissions: ["shortcodes:view"] }
@@ -12839,7 +13354,7 @@ helloWorldRoutes.get("/", async (c) => {
12839
13354
  </html>
12840
13355
  `);
12841
13356
  });
12842
- var helloWorldPlugin = chunkXW56B23A_cjs.definePlugin({
13357
+ var helloWorldPlugin = chunk5RSB5SEK_cjs.definePlugin({
12843
13358
  id: "hello-world",
12844
13359
  version: "1.0.0",
12845
13360
  name: "Hello World",
@@ -12874,6 +13389,9 @@ var helloWorldPlugin = chunkXW56B23A_cjs.definePlugin({
12874
13389
  console.info("\u274C Hello World plugin deactivated");
12875
13390
  }
12876
13391
  });
13392
+ function createHelloWorldPlugin() {
13393
+ return helloWorldPlugin;
13394
+ }
12877
13395
 
12878
13396
  // src/plugins/core-plugins/multi-tenant-plugin/manifest.json
12879
13397
  var manifest_default2 = {
@@ -12883,7 +13401,7 @@ var manifest_default2 = {
12883
13401
  author: "SonicJS Team"};
12884
13402
 
12885
13403
  // src/plugins/core-plugins/multi-tenant-plugin/templates/tenants-list.template.ts
12886
- chunkNAVPFIG5_cjs.init_admin_layout_catalyst_template();
13404
+ chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
12887
13405
  function statusBadge2(status) {
12888
13406
  return status === "active" ? '<span class="inline-flex items-center rounded-md bg-emerald-500/10 px-2 py-1 text-xs font-medium text-emerald-600 dark:text-emerald-400">Active</span>' : '<span class="inline-flex items-center rounded-md bg-zinc-500/10 px-2 py-1 text-xs font-medium text-zinc-600 dark:text-zinc-400">Inactive</span>';
12889
13407
  }
@@ -12956,7 +13474,7 @@ function renderTenantsList(data) {
12956
13474
  </table>
12957
13475
  </div>
12958
13476
  </div>`;
12959
- return chunkNAVPFIG5_cjs.renderAdminLayoutCatalyst({
13477
+ return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst({
12960
13478
  title: "Tenants - SonicJS",
12961
13479
  pageTitle: "Tenants",
12962
13480
  currentPath: "/admin/tenants",
@@ -12975,7 +13493,7 @@ function renderTenantsInactive(data) {
12975
13493
  <a href="/admin/plugins" class="mt-6 inline-flex items-center rounded-lg bg-zinc-950 px-3.5 py-2 text-sm font-semibold text-white hover:bg-zinc-800 dark:bg-white dark:text-zinc-950 dark:hover:bg-zinc-200">Go to Plugins</a>
12976
13494
  </div>
12977
13495
  </div>`;
12978
- return chunkNAVPFIG5_cjs.renderAdminLayoutCatalyst({
13496
+ return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst({
12979
13497
  title: "Tenants - SonicJS",
12980
13498
  pageTitle: "Tenants",
12981
13499
  currentPath: "/admin/tenants",
@@ -12986,7 +13504,7 @@ function renderTenantsInactive(data) {
12986
13504
  }
12987
13505
 
12988
13506
  // src/plugins/core-plugins/multi-tenant-plugin/templates/tenant-form.template.ts
12989
- chunkNAVPFIG5_cjs.init_admin_layout_catalyst_template();
13507
+ chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
12990
13508
  function fieldErrors(errors, field) {
12991
13509
  const list = errors?.[field];
12992
13510
  if (!list || list.length === 0) return "";
@@ -13054,7 +13572,7 @@ function renderTenantForm(data) {
13054
13572
  </form>
13055
13573
  </div>
13056
13574
  </div>`;
13057
- return chunkNAVPFIG5_cjs.renderAdminLayoutCatalyst({
13575
+ return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst({
13058
13576
  title: `${data.isEdit ? "Edit Tenant" : "New Tenant"} - SonicJS`,
13059
13577
  pageTitle: data.isEdit ? "Edit Tenant" : "New Tenant",
13060
13578
  currentPath: "/admin/tenants",
@@ -13065,9 +13583,9 @@ function renderTenantForm(data) {
13065
13583
  }
13066
13584
 
13067
13585
  // src/plugins/core-plugins/multi-tenant-plugin/templates/tenant-members.template.ts
13068
- chunkNAVPFIG5_cjs.init_admin_layout_catalyst_template();
13586
+ chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
13069
13587
  function roleOptions(selected) {
13070
- return chunkVXE42MYF_cjs.VALID_MEMBER_ROLES.map(
13588
+ return chunk3E7IROND_cjs.VALID_MEMBER_ROLES.map(
13071
13589
  (r) => `<option value="${r}" ${r === selected ? "selected" : ""}>${r}</option>`
13072
13590
  ).join("");
13073
13591
  }
@@ -13129,7 +13647,7 @@ function renderInvitations(slug, invitations) {
13129
13647
  <div>
13130
13648
  <label for="invite-role" class="mb-1 block text-xs font-medium text-zinc-500 dark:text-zinc-400">Role</label>
13131
13649
  <select id="invite-role" name="role" class="rounded-lg border border-zinc-950/10 bg-white px-2 py-2 text-sm text-zinc-950 dark:border-white/10 dark:bg-zinc-800 dark:text-white">
13132
- ${chunkVXE42MYF_cjs.VALID_MEMBER_ROLES.map((r) => `<option value="${r}" ${r === "viewer" ? "selected" : ""}>${r}</option>`).join("")}
13650
+ ${chunk3E7IROND_cjs.VALID_MEMBER_ROLES.map((r) => `<option value="${r}" ${r === "viewer" ? "selected" : ""}>${r}</option>`).join("")}
13133
13651
  </select>
13134
13652
  </div>
13135
13653
  <button type="submit" data-send-invite class="rounded-lg bg-zinc-950 px-3.5 py-2 text-sm font-semibold text-white hover:bg-zinc-800 dark:bg-white dark:text-zinc-950 dark:hover:bg-zinc-200">Invite</button>
@@ -13212,7 +13730,7 @@ function renderTenantMembers(data) {
13212
13730
 
13213
13731
  ${renderInvitations(data.slug, data.invitations)}
13214
13732
  </div>`;
13215
- return chunkNAVPFIG5_cjs.renderAdminLayoutCatalyst({
13733
+ return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst({
13216
13734
  title: `Members - ${data.tenantName} - SonicJS`,
13217
13735
  pageTitle: "Tenant Members",
13218
13736
  currentPath: "/admin/tenants",
@@ -13223,9 +13741,9 @@ function renderTenantMembers(data) {
13223
13741
  }
13224
13742
 
13225
13743
  // src/plugins/core-plugins/multi-tenant-plugin/templates/user-memberships.template.ts
13226
- chunkNAVPFIG5_cjs.init_admin_layout_catalyst_template();
13744
+ chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
13227
13745
  function roleOptions2(selected) {
13228
- return chunkVXE42MYF_cjs.VALID_MEMBER_ROLES.map(
13746
+ return chunk3E7IROND_cjs.VALID_MEMBER_ROLES.map(
13229
13747
  (r) => `<option value="${r}" ${r === selected ? "selected" : ""}>${r}</option>`
13230
13748
  ).join("");
13231
13749
  }
@@ -13298,7 +13816,7 @@ function renderUserMemberships(data) {
13298
13816
  </table>
13299
13817
  </div>
13300
13818
  </div>`;
13301
- return chunkNAVPFIG5_cjs.renderAdminLayoutCatalyst({
13819
+ return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst({
13302
13820
  title: `Tenant memberships - ${data.userEmail} - SonicJS`,
13303
13821
  pageTitle: "Tenant memberships",
13304
13822
  currentPath: "/admin/users",
@@ -13309,7 +13827,7 @@ function renderUserMemberships(data) {
13309
13827
  }
13310
13828
 
13311
13829
  // src/plugins/core-plugins/multi-tenant-plugin/templates/role-usage.template.ts
13312
- chunkNAVPFIG5_cjs.init_admin_layout_catalyst_template();
13830
+ chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
13313
13831
  function renderRoleUsage(data) {
13314
13832
  const role = chunkMNWKYY5E_cjs.escapeHtml(data.roleName);
13315
13833
  const rows = data.assignments.length ? data.assignments.map((a) => `
@@ -13344,7 +13862,7 @@ function renderRoleUsage(data) {
13344
13862
  </table>
13345
13863
  </div>
13346
13864
  </div>`;
13347
- return chunkNAVPFIG5_cjs.renderAdminLayoutCatalyst({
13865
+ return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst({
13348
13866
  title: `Role usage - ${data.roleName} - SonicJS`,
13349
13867
  pageTitle: "Role usage",
13350
13868
  currentPath: "/admin/tenants",
@@ -13387,7 +13905,7 @@ function zodToFieldErrors(error) {
13387
13905
  }
13388
13906
  async function isMultiTenantActive(db) {
13389
13907
  try {
13390
- const plugin2 = await new chunkQAYFOER6_cjs.PluginService(db).getPlugin(chunkQAYFOER6_cjs.MULTI_TENANT_PLUGIN_ID);
13908
+ const plugin2 = await new chunk5ARIHAGN_cjs.PluginService(db).getPlugin(chunk5ARIHAGN_cjs.MULTI_TENANT_PLUGIN_ID);
13391
13909
  return plugin2?.status === "active";
13392
13910
  } catch {
13393
13911
  return false;
@@ -13395,7 +13913,7 @@ async function isMultiTenantActive(db) {
13395
13913
  }
13396
13914
  function createTenantAdminRoutes() {
13397
13915
  const routes2 = new hono.Hono();
13398
- routes2.use("*", chunkAAWNRBRB_cjs.requireAuth());
13916
+ routes2.use("*", chunk4SHNHNRP_cjs.requireAuth());
13399
13917
  routes2.use("*", async (c, next) => {
13400
13918
  const user = c.get("user");
13401
13919
  if (user?.role !== "admin") {
@@ -13409,7 +13927,7 @@ function createTenantAdminRoutes() {
13409
13927
  const form = await c.req.formData();
13410
13928
  const slug = String(form.get("tenant") ?? "").trim().toLowerCase();
13411
13929
  const redirect = String(form.get("redirect") ?? "");
13412
- const svc = new chunkVXE42MYF_cjs.TenantService(db);
13930
+ const svc = new chunk3E7IROND_cjs.TenantService(db);
13413
13931
  const tenant = await svc.getTenantBySlug(slug);
13414
13932
  if (!tenant || tenant.status !== "active") {
13415
13933
  return c.json({ error: "Unknown or inactive tenant" }, 400);
@@ -13419,7 +13937,7 @@ function createTenantAdminRoutes() {
13419
13937
  if (!user.isSuperAdmin && !await svc.isMember(user.userId, slug)) {
13420
13938
  return c.json({ error: "You are not a member of this tenant" }, 403);
13421
13939
  }
13422
- cookie.setCookie(c, chunkQAYFOER6_cjs.TENANT_COOKIE, slug, {
13940
+ cookie.setCookie(c, chunk5ARIHAGN_cjs.TENANT_COOKIE, slug, {
13423
13941
  path: "/",
13424
13942
  httpOnly: true,
13425
13943
  sameSite: "Lax",
@@ -13436,7 +13954,7 @@ function createTenantAdminRoutes() {
13436
13954
  if (!user) return c.redirect("/auth/login");
13437
13955
  const token = c.req.query("token") ?? "";
13438
13956
  try {
13439
- const { slug } = await new chunkVXE42MYF_cjs.TenantService(db).acceptInvitation(token, user.userId, user.email);
13957
+ const { slug } = await new chunk3E7IROND_cjs.TenantService(db).acceptInvitation(token, user.userId, user.email);
13440
13958
  return c.redirect(`/admin/tenants/${slug}/members?message=Invitation accepted`);
13441
13959
  } catch (error) {
13442
13960
  const message = error instanceof Error ? error.message : "Failed to accept invitation";
@@ -13464,7 +13982,7 @@ function createTenantAdminRoutes() {
13464
13982
  const userId = c.req.param("userId");
13465
13983
  const target = await db.prepare("SELECT id, email FROM auth_user WHERE id = ?").bind(userId).first();
13466
13984
  if (!target?.id) return c.redirect("/admin/users?message=User not found&type=error");
13467
- const svc = new chunkVXE42MYF_cjs.TenantService(db);
13985
+ const svc = new chunk3E7IROND_cjs.TenantService(db);
13468
13986
  const [memberships, allTenants] = await Promise.all([svc.listUserMemberships(userId), svc.listTenants()]);
13469
13987
  const memberSlugs = new Set(memberships.map((m) => m.slug));
13470
13988
  const availableTenants = allTenants.filter((t) => t.status === "active" && !memberSlugs.has(t.slug)).map((t) => ({ slug: t.slug, name: t.name }));
@@ -13489,10 +14007,10 @@ function createTenantAdminRoutes() {
13489
14007
  const slug = String(form.get("slug") ?? "").trim().toLowerCase();
13490
14008
  const role = String(form.get("role") ?? "viewer");
13491
14009
  const redirectTo = String(form.get("_redirect") ?? "") || `/admin/tenants/users/${userId}`;
13492
- if (!chunkVXE42MYF_cjs.isValidMemberRole(role)) throw new Error(`Invalid role '${role}'`);
14010
+ if (!chunk3E7IROND_cjs.isValidMemberRole(role)) throw new Error(`Invalid role '${role}'`);
13493
14011
  const target = await db.prepare("SELECT email FROM auth_user WHERE id = ?").bind(userId).first();
13494
14012
  if (!target) throw new Error("User not found");
13495
- const svc = new chunkVXE42MYF_cjs.TenantService(db);
14013
+ const svc = new chunk3E7IROND_cjs.TenantService(db);
13496
14014
  if (!await svc.getTenantBySlug(slug)) throw new Error("Tenant not found");
13497
14015
  if (await svc.isMember(userId, slug)) throw new Error(`Already a member of '${slug}'`);
13498
14016
  await svc.addMember(slug, userId, role, target.email ?? null);
@@ -13511,7 +14029,7 @@ function createTenantAdminRoutes() {
13511
14029
  const form = await c.req.formData();
13512
14030
  const role = String(form.get("role") ?? "");
13513
14031
  const redirectTo = String(form.get("_redirect") ?? "") || `/admin/tenants/users/${userId}`;
13514
- await new chunkVXE42MYF_cjs.TenantService(db).setMemberRole(slug, userId, role);
14032
+ await new chunk3E7IROND_cjs.TenantService(db).setMemberRole(slug, userId, role);
13515
14033
  return c.redirect(`${redirectTo}?message=Role updated`);
13516
14034
  } catch (error) {
13517
14035
  const message = error instanceof Error ? error.message : "Failed to update role";
@@ -13526,7 +14044,7 @@ function createTenantAdminRoutes() {
13526
14044
  try {
13527
14045
  const form = await c.req.formData();
13528
14046
  const redirectTo = String(form.get("_redirect") ?? "") || `/admin/tenants/users/${userId}`;
13529
- await new chunkVXE42MYF_cjs.TenantService(db).removeMember(slug, userId);
14047
+ await new chunk3E7IROND_cjs.TenantService(db).removeMember(slug, userId);
13530
14048
  return c.redirect(`${redirectTo}?message=Removed from ${encodeURIComponent(slug)}`);
13531
14049
  } catch (error) {
13532
14050
  const message = error instanceof Error ? error.message : "Failed to remove membership";
@@ -13541,7 +14059,7 @@ function createTenantAdminRoutes() {
13541
14059
  return c.html(renderTenantsInactive({ user: userShape(cur), version }));
13542
14060
  }
13543
14061
  const roleName = c.req.param("roleName");
13544
- const assignments = await new chunkVXE42MYF_cjs.TenantService(db).listAssignmentsByRole(roleName);
14062
+ const assignments = await new chunk3E7IROND_cjs.TenantService(db).listAssignmentsByRole(roleName);
13545
14063
  return c.html(renderRoleUsage({ roleName, assignments, user: userShape(cur), version }));
13546
14064
  });
13547
14065
  routes2.get("/", async (c) => {
@@ -13551,7 +14069,7 @@ function createTenantAdminRoutes() {
13551
14069
  if (!await isMultiTenantActive(db)) {
13552
14070
  return c.html(renderTenantsInactive({ user: userShape(user), version }));
13553
14071
  }
13554
- const svc = new chunkVXE42MYF_cjs.TenantService(db);
14072
+ const svc = new chunk3E7IROND_cjs.TenantService(db);
13555
14073
  await svc.ensureDefaultTenant();
13556
14074
  const tenants = await svc.listTenants();
13557
14075
  const [docRes, memberRes] = await db.batch([
@@ -13590,7 +14108,7 @@ function createTenantAdminRoutes() {
13590
14108
  formEntries = Object.fromEntries(form.entries());
13591
14109
  const validated = tenantFormSchema.parse(formEntries);
13592
14110
  if (!validated.slug) throw new zod.z.ZodError([{ code: "custom", message: "Slug is required", path: ["slug"] }]);
13593
- const svc = new chunkVXE42MYF_cjs.TenantService(db);
14111
+ const svc = new chunk3E7IROND_cjs.TenantService(db);
13594
14112
  await svc.createTenant({
13595
14113
  name: validated.name,
13596
14114
  slug: validated.slug,
@@ -13615,7 +14133,7 @@ function createTenantAdminRoutes() {
13615
14133
  if (!await isMultiTenantActive(db)) {
13616
14134
  return c.html(renderTenantsInactive({ user: userShape(user), version }));
13617
14135
  }
13618
- const tenant = await new chunkVXE42MYF_cjs.TenantService(db).getTenantBySlug(c.req.param("slug"));
14136
+ const tenant = await new chunk3E7IROND_cjs.TenantService(db).getTenantBySlug(c.req.param("slug"));
13619
14137
  if (!tenant) return c.redirect("/admin/tenants?message=Tenant not found&type=error");
13620
14138
  return c.html(renderTenantForm({ tenant, isEdit: true, user: userShape(user), version }));
13621
14139
  });
@@ -13625,7 +14143,7 @@ function createTenantAdminRoutes() {
13625
14143
  const version = c.get("appVersion");
13626
14144
  const slug = c.req.param("slug");
13627
14145
  if (!await isMultiTenantActive(db)) return c.json({ error: "Multi-tenant plugin is not active" }, 403);
13628
- const svc = new chunkVXE42MYF_cjs.TenantService(db);
14146
+ const svc = new chunk3E7IROND_cjs.TenantService(db);
13629
14147
  try {
13630
14148
  const form = await c.req.formData();
13631
14149
  const validated = tenantFormSchema.parse(Object.fromEntries(form.entries()));
@@ -13650,7 +14168,7 @@ function createTenantAdminRoutes() {
13650
14168
  const slug = c.req.param("slug");
13651
14169
  if (!await isMultiTenantActive(db)) return c.json({ error: "Multi-tenant plugin is not active" }, 403);
13652
14170
  try {
13653
- await new chunkVXE42MYF_cjs.TenantService(db).deleteTenant(slug);
14171
+ await new chunk3E7IROND_cjs.TenantService(db).deleteTenant(slug);
13654
14172
  return c.redirect("/admin/tenants?message=Tenant deleted successfully");
13655
14173
  } catch (error) {
13656
14174
  const message = error instanceof Error ? error.message : "Failed to delete tenant";
@@ -13665,7 +14183,7 @@ function createTenantAdminRoutes() {
13665
14183
  return c.html(renderTenantsInactive({ user: userShape(user), version }));
13666
14184
  }
13667
14185
  const slug = c.req.param("slug");
13668
- const svc = new chunkVXE42MYF_cjs.TenantService(db);
14186
+ const svc = new chunk3E7IROND_cjs.TenantService(db);
13669
14187
  const tenant = await svc.getTenantBySlug(slug);
13670
14188
  if (!tenant) return c.redirect("/admin/tenants?message=Tenant not found&type=error");
13671
14189
  const [members, invitations] = await Promise.all([svc.listMembers(slug), svc.listInvitations(slug)]);
@@ -13691,7 +14209,7 @@ function createTenantAdminRoutes() {
13691
14209
  const form = await c.req.formData();
13692
14210
  const email = String(form.get("email") ?? "");
13693
14211
  const role = String(form.get("role") ?? "viewer");
13694
- await new chunkVXE42MYF_cjs.TenantService(db).addMemberByEmail(slug, email, role);
14212
+ await new chunk3E7IROND_cjs.TenantService(db).addMemberByEmail(slug, email, role);
13695
14213
  return c.redirect(`/admin/tenants/${slug}/members?message=Member added`);
13696
14214
  } catch (error) {
13697
14215
  const message = error instanceof Error ? error.message : "Failed to add member";
@@ -13706,7 +14224,7 @@ function createTenantAdminRoutes() {
13706
14224
  try {
13707
14225
  const form = await c.req.formData();
13708
14226
  const role = String(form.get("role") ?? "");
13709
- await new chunkVXE42MYF_cjs.TenantService(db).setMemberRole(slug, userId, role);
14227
+ await new chunk3E7IROND_cjs.TenantService(db).setMemberRole(slug, userId, role);
13710
14228
  return c.redirect(`/admin/tenants/${slug}/members?message=Role updated`);
13711
14229
  } catch (error) {
13712
14230
  const message = error instanceof Error ? error.message : "Failed to update role";
@@ -13719,7 +14237,7 @@ function createTenantAdminRoutes() {
13719
14237
  const userId = c.req.param("userId");
13720
14238
  if (!await isMultiTenantActive(db)) return c.json({ error: "Multi-tenant plugin is not active" }, 403);
13721
14239
  try {
13722
- await new chunkVXE42MYF_cjs.TenantService(db).removeMember(slug, userId);
14240
+ await new chunk3E7IROND_cjs.TenantService(db).removeMember(slug, userId);
13723
14241
  return c.redirect(`/admin/tenants/${slug}/members?message=Member removed`);
13724
14242
  } catch (error) {
13725
14243
  const message = error instanceof Error ? error.message : "Failed to remove member";
@@ -13735,12 +14253,12 @@ function createTenantAdminRoutes() {
13735
14253
  const form = await c.req.formData();
13736
14254
  const email = String(form.get("email") ?? "");
13737
14255
  const role = String(form.get("role") ?? "viewer");
13738
- const token = await new chunkVXE42MYF_cjs.TenantService(db).createInvitation(slug, email, role, user?.userId ?? null);
14256
+ const token = await new chunk3E7IROND_cjs.TenantService(db).createInvitation(slug, email, role, user?.userId ?? null);
13739
14257
  const origin = c.req.header("origin") || new URL(c.req.url).origin;
13740
14258
  const acceptUrl = `${origin}/join/invite?token=${encodeURIComponent(token)}`;
13741
14259
  let note;
13742
14260
  let noteType = "";
13743
- const svc2 = chunkVXE42MYF_cjs.hasEmailService() ? chunkVXE42MYF_cjs.getEmailService() : null;
14261
+ const svc2 = chunk3E7IROND_cjs.hasEmailService() ? chunk3E7IROND_cjs.getEmailService() : null;
13744
14262
  const hasRealProvider = !!svc2 && svc2.getProviderName() !== "console";
13745
14263
  if (hasRealProvider) {
13746
14264
  const result = await svc2.send({
@@ -13781,7 +14299,7 @@ function createTenantAdminRoutes() {
13781
14299
  WHERE i.id = ? AND t.slug = ? AND i.status = 'pending'`
13782
14300
  ).bind(id, slug).first();
13783
14301
  if (!inv) throw new Error("Invitation not found or already used");
13784
- const svc2 = chunkVXE42MYF_cjs.hasEmailService() ? chunkVXE42MYF_cjs.getEmailService() : null;
14302
+ const svc2 = chunk3E7IROND_cjs.hasEmailService() ? chunk3E7IROND_cjs.getEmailService() : null;
13785
14303
  const hasRealProvider = !!svc2 && svc2.getProviderName() !== "console";
13786
14304
  if (!hasRealProvider) throw new Error("No email plugin active");
13787
14305
  const origin = c.req.header("origin") || new URL(c.req.url).origin;
@@ -13806,7 +14324,7 @@ function createTenantAdminRoutes() {
13806
14324
  const id = c.req.param("id");
13807
14325
  if (!await isMultiTenantActive(db)) return c.json({ error: "Multi-tenant plugin is not active" }, 403);
13808
14326
  try {
13809
- await new chunkVXE42MYF_cjs.TenantService(db).revokeInvitation(slug, id);
14327
+ await new chunk3E7IROND_cjs.TenantService(db).revokeInvitation(slug, id);
13810
14328
  return c.redirect(`/admin/tenants/${slug}/members?message=Invitation revoked`);
13811
14329
  } catch (error) {
13812
14330
  const message = error instanceof Error ? error.message : "Failed to revoke invitation";
@@ -14036,7 +14554,7 @@ function createJoinRoutes() {
14036
14554
  if (existing) return rerender("An account with this email already exists. Please sign in instead.");
14037
14555
  try {
14038
14556
  const userId = crypto.randomUUID();
14039
- const passwordHash = await chunkAAWNRBRB_cjs.AuthManager.hashPassword(password);
14557
+ const passwordHash = await chunk4SHNHNRP_cjs.AuthManager.hashPassword(password);
14040
14558
  const now = Date.now();
14041
14559
  const nowSec = Math.floor(now / 1e3);
14042
14560
  await db.batch([
@@ -14049,8 +14567,8 @@ function createJoinRoutes() {
14049
14567
  VALUES (?, ?, ?, 'credential', ?, ?, ?)`
14050
14568
  ).bind(`cred-${userId}`, userId, userId, passwordHash, nowSec, nowSec)
14051
14569
  ]);
14052
- await new chunkVXE42MYF_cjs.TenantService(db).acceptInvitation(token, userId, inv.email);
14053
- const auth = chunkNUKJ54GA_cjs.createAuth(c.env);
14570
+ await new chunk3E7IROND_cjs.TenantService(db).acceptInvitation(token, userId, inv.email);
14571
+ const auth = chunkGMMCCIQO_cjs.createAuth(c.env);
14054
14572
  const origin = new URL(c.req.url).origin;
14055
14573
  const baReq = new Request(`${origin}/auth/sign-in/email`, {
14056
14574
  method: "POST",
@@ -14105,7 +14623,7 @@ function createJoinRoutes() {
14105
14623
  version
14106
14624
  }), 400);
14107
14625
  try {
14108
- const auth = chunkNUKJ54GA_cjs.createAuth(c.env);
14626
+ const auth = chunkGMMCCIQO_cjs.createAuth(c.env);
14109
14627
  const origin = new URL(c.req.url).origin;
14110
14628
  const baReq = new Request(`${origin}/auth/sign-in/email`, {
14111
14629
  method: "POST",
@@ -14117,7 +14635,7 @@ function createJoinRoutes() {
14117
14635
  const baBody = await baRes.json();
14118
14636
  const userId = baBody?.user?.id;
14119
14637
  if (!userId) return rerender("Sign-in succeeded but could not read user ID.");
14120
- await new chunkVXE42MYF_cjs.TenantService(db).acceptInvitation(token, userId, inv.email);
14638
+ await new chunk3E7IROND_cjs.TenantService(db).acceptInvitation(token, userId, inv.email);
14121
14639
  const headers = new Headers({ Location: "/admin?message=Welcome! You have joined " + encodeURIComponent(inv.tenantName) });
14122
14640
  copyBaCookies(baRes, headers);
14123
14641
  return new Response(null, { status: 302, headers });
@@ -14131,7 +14649,7 @@ function createJoinRoutes() {
14131
14649
 
14132
14650
  // src/plugins/core-plugins/multi-tenant-plugin/index.ts
14133
14651
  var TENANT_ICON = `<svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3.75 21h16.5M4.5 3h15M5.25 3v18m13.5-18v18M9 6.75h1.5m-1.5 3h1.5m-1.5 3h1.5m3-6H15m-1.5 3H15m-1.5 3H15M9 21v-3.375c0-.621.504-1.125 1.125-1.125h3.75c.621 0 1.125.504 1.125 1.125V21"/></svg>`;
14134
- var multiTenantPlugin = chunkXW56B23A_cjs.definePlugin({
14652
+ var multiTenantPlugin = chunk5RSB5SEK_cjs.definePlugin({
14135
14653
  id: manifest_default2.id,
14136
14654
  version: "1.0.0",
14137
14655
  name: manifest_default2.name,
@@ -14146,30 +14664,30 @@ var multiTenantPlugin = chunkXW56B23A_cjs.definePlugin({
14146
14664
  { label: "Tenants", path: "/admin/tenants", icon: TENANT_ICON, order: 80 }
14147
14665
  ],
14148
14666
  activate: async () => {
14149
- chunkQAYFOER6_cjs.invalidateTenantCache();
14667
+ chunk5ARIHAGN_cjs.invalidateTenantCache();
14150
14668
  console.info("\u2705 Multi-Tenant plugin activated");
14151
14669
  },
14152
14670
  deactivate: async () => {
14153
- chunkQAYFOER6_cjs.invalidateTenantCache();
14671
+ chunk5ARIHAGN_cjs.invalidateTenantCache();
14154
14672
  console.info("\u274C Multi-Tenant plugin deactivated");
14155
14673
  }
14156
14674
  });
14157
14675
  var routes = new hono.Hono();
14158
- routes.use("*", chunkAAWNRBRB_cjs.requireAuth());
14159
- routes.use("*", chunkAAWNRBRB_cjs.requireRole(["admin", "editor"]));
14676
+ routes.use("*", chunk4SHNHNRP_cjs.requireAuth());
14677
+ routes.use("*", chunk4SHNHNRP_cjs.requireRole(["admin", "editor"]));
14160
14678
  routes.get("/:rootId", async (c) => {
14161
14679
  const { rootId } = c.req.param();
14162
14680
  const db = c.env.DB;
14163
- const scope = await chunkVXE42MYF_cjs.resolveDocScope(c, db, { rootId });
14681
+ const scope = await chunk3E7IROND_cjs.resolveDocScope(c, db, { rootId });
14164
14682
  if (!scope) {
14165
14683
  return c.html('<p class="text-zinc-500 dark:text-zinc-400 p-4">Document not found.</p>', 404);
14166
14684
  }
14167
14685
  if (!scope.docType?.settings?.versioning) {
14168
14686
  return c.html('<p class="text-zinc-500 dark:text-zinc-400 p-4">Versioning not enabled for this type.</p>', 404);
14169
14687
  }
14170
- const denied = await chunkVXE42MYF_cjs.denyIfNotAllowed(c, db, rootId, "read", scope.docType?.settings, scope.tenantId);
14688
+ const denied = await chunk3E7IROND_cjs.denyIfNotAllowed(c, db, rootId, "read", scope.docType?.settings, scope.tenantId);
14171
14689
  if (denied) return denied;
14172
- const repo = new chunkVXE42MYF_cjs.DocumentRepository(db, scope.tenantId);
14690
+ const repo = new chunk3E7IROND_cjs.DocumentRepository(db, scope.tenantId);
14173
14691
  const versions = await repo.getVersionHistory(rootId);
14174
14692
  const safeRootIdAttr = chunkMNWKYY5E_cjs.escapeHtml(rootId);
14175
14693
  const rows = versions.map((v) => {
@@ -14262,14 +14780,14 @@ routes.post("/:rootId/restore/:versionNumber", async (c) => {
14262
14780
  const { rootId, versionNumber } = c.req.param();
14263
14781
  const db = c.env.DB;
14264
14782
  const user = c.get("user");
14265
- const scope = await chunkVXE42MYF_cjs.resolveDocScope(c, db, { rootId });
14783
+ const scope = await chunk3E7IROND_cjs.resolveDocScope(c, db, { rootId });
14266
14784
  if (!scope) {
14267
14785
  return c.json({ error: "Document not found" }, 404);
14268
14786
  }
14269
14787
  if (!scope.docType?.settings?.versioning) {
14270
14788
  return c.json({ error: "Versioning not enabled for this type" }, 404);
14271
14789
  }
14272
- const denied = await chunkVXE42MYF_cjs.denyIfNotAllowed(c, db, rootId, "update", scope.docType?.settings, scope.tenantId);
14790
+ const denied = await chunk3E7IROND_cjs.denyIfNotAllowed(c, db, rootId, "update", scope.docType?.settings, scope.tenantId);
14273
14791
  if (denied) return denied;
14274
14792
  const row = await db.prepare("SELECT * FROM documents WHERE root_id = ? AND tenant_id = ? AND version_number = ? LIMIT 1").bind(rootId, scope.tenantId, Number(versionNumber)).first();
14275
14793
  if (!row) {
@@ -14279,7 +14797,7 @@ routes.post("/:rootId/restore/:versionNumber", async (c) => {
14279
14797
  const title = row.title ?? null;
14280
14798
  const slug = row.slug ?? null;
14281
14799
  const docType = scope.docType;
14282
- const svc = new chunk2CB4KY7I_cjs.DocumentsService(db, {
14800
+ const svc = new chunkLTZ5WYOK_cjs.DocumentsService(db, {
14283
14801
  queryableFields: docType?.queryableFields ?? [],
14284
14802
  typeSchemaVersion: docType?.schemaVersion ?? 1,
14285
14803
  maxVersionsPerRoot: docType?.settings?.maxVersionsPerRoot ?? 50,
@@ -14292,7 +14810,7 @@ routes.post("/:rootId/restore/:versionNumber", async (c) => {
14292
14810
  var routes_default = routes;
14293
14811
 
14294
14812
  // src/plugins/core-plugins/versioning-plugin/index.ts
14295
- var versioningPlugin = chunkXW56B23A_cjs.definePlugin({
14813
+ var versioningPlugin = chunk5RSB5SEK_cjs.definePlugin({
14296
14814
  id: "versioning",
14297
14815
  version: "1.0.0",
14298
14816
  name: "Versioning",
@@ -14369,8 +14887,8 @@ function createMagicLinkAuthPlugin() {
14369
14887
  const baseUrl = new URL(c.req.url).origin;
14370
14888
  const magicLink = `${baseUrl}/auth/magic-link/verify?token=${token}`;
14371
14889
  try {
14372
- if (chunkVXE42MYF_cjs.hasEmailService()) {
14373
- await chunkVXE42MYF_cjs.getEmailService().send({
14890
+ if (chunk3E7IROND_cjs.hasEmailService()) {
14891
+ await chunk3E7IROND_cjs.getEmailService().send({
14374
14892
  to: normalizedEmail,
14375
14893
  subject: "Your Magic Link to Sign In",
14376
14894
  flow: "magic-link",
@@ -14447,19 +14965,19 @@ function createMagicLinkAuthPlugin() {
14447
14965
  SET used = 1, used_at = ?
14448
14966
  WHERE id = ?
14449
14967
  `).bind(Date.now(), magicLink.id).run();
14450
- const tokenTtl = await chunkAAWNRBRB_cjs.getJwtExpirySecondsFromDb(c.env.DB, c.env);
14451
- const jwtToken = await chunkAAWNRBRB_cjs.AuthManager.generateToken(
14968
+ const tokenTtl = await chunk4SHNHNRP_cjs.getJwtExpirySecondsFromDb(c.env.DB, c.env);
14969
+ const jwtToken = await chunk4SHNHNRP_cjs.AuthManager.generateToken(
14452
14970
  user.id,
14453
14971
  user.email,
14454
14972
  user.role,
14455
14973
  c.env.JWT_SECRET,
14456
14974
  tokenTtl
14457
14975
  );
14458
- chunkAAWNRBRB_cjs.AuthManager.setAuthCookie(c, jwtToken, { maxAge: tokenTtl });
14976
+ chunk4SHNHNRP_cjs.AuthManager.setAuthCookie(c, jwtToken, { maxAge: tokenTtl });
14459
14977
  await db.prepare(`
14460
14978
  UPDATE auth_user SET last_login_at = ? WHERE id = ?
14461
14979
  `).bind(Date.now(), user.id).run();
14462
- chunkVXE42MYF_cjs.dispatchHookEvent(
14980
+ chunk3E7IROND_cjs.dispatchHookEvent(
14463
14981
  c,
14464
14982
  "auth:magic-link:consumed",
14465
14983
  { user: { id: user.id, email: user.email, role: user.role } },
@@ -14944,7 +15462,7 @@ async function warmCollections(db) {
14944
15462
  const collectionCache = chunkYA3TJ65D_cjs.getCacheService(config);
14945
15463
  let count = 0;
14946
15464
  try {
14947
- const results = chunkQAYFOER6_cjs.getCollectionRegistry().listActive().map(chunkQAYFOER6_cjs.collectionRecordToRow);
15465
+ const results = chunk5ARIHAGN_cjs.getCollectionRegistry().listActive().map(chunk5ARIHAGN_cjs.collectionRecordToRow);
14948
15466
  for (const collection of results) {
14949
15467
  const key = collectionCache.generateKey("item", collection.id);
14950
15468
  await collectionCache.set(key, collection);
@@ -15011,7 +15529,7 @@ async function warmNamespace(namespace, entries) {
15011
15529
  }
15012
15530
 
15013
15531
  // src/templates/pages/admin-cache.template.ts
15014
- chunkNAVPFIG5_cjs.init_admin_layout_catalyst_template();
15532
+ chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
15015
15533
  function renderCacheDashboard(data) {
15016
15534
  const pageContent = `
15017
15535
  <div class="space-y-6">
@@ -15215,7 +15733,7 @@ function renderCacheDashboard(data) {
15215
15733
  </script>
15216
15734
 
15217
15735
  <!-- Confirmation Dialogs -->
15218
- ${chunkVXE42MYF_cjs.renderConfirmationDialog({
15736
+ ${chunk3E7IROND_cjs.renderConfirmationDialog({
15219
15737
  id: "clear-all-cache-confirm",
15220
15738
  title: "Clear All Cache",
15221
15739
  message: "Are you sure you want to clear all cache entries? This cannot be undone.",
@@ -15226,7 +15744,7 @@ function renderCacheDashboard(data) {
15226
15744
  onConfirm: "performClearAllCaches()"
15227
15745
  })}
15228
15746
 
15229
- ${chunkVXE42MYF_cjs.renderConfirmationDialog({
15747
+ ${chunk3E7IROND_cjs.renderConfirmationDialog({
15230
15748
  id: "clear-namespace-cache-confirm",
15231
15749
  title: "Clear Namespace Cache",
15232
15750
  message: "Clear cache for this namespace?",
@@ -15237,7 +15755,7 @@ function renderCacheDashboard(data) {
15237
15755
  onConfirm: "performClearNamespaceCache()"
15238
15756
  })}
15239
15757
 
15240
- ${chunkVXE42MYF_cjs.getConfirmationDialogScript()}
15758
+ ${chunk3E7IROND_cjs.getConfirmationDialogScript()}
15241
15759
  `;
15242
15760
  const layoutData = {
15243
15761
  title: "Cache System",
@@ -15247,7 +15765,7 @@ function renderCacheDashboard(data) {
15247
15765
  version: data.version,
15248
15766
  content: pageContent
15249
15767
  };
15250
- return chunkNAVPFIG5_cjs.renderAdminLayoutCatalyst(layoutData);
15768
+ return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
15251
15769
  }
15252
15770
  function renderCollectionSettingsTab(collections) {
15253
15771
  if (collections.length === 0) {
@@ -15503,7 +16021,7 @@ app.get("/", async (c) => {
15503
16021
  const totalRequests = totalHits + totalMisses;
15504
16022
  const overallHitRate = totalRequests > 0 ? totalHits / totalRequests * 100 : 0;
15505
16023
  const DEFAULT_TTL = chunkYA3TJ65D_cjs.CACHE_CONFIGS.api?.ttl ?? 300;
15506
- const collections = chunkQAYFOER6_cjs.getCollectionRegistry().listActive().filter((r) => !r.internal).map((r) => {
16024
+ const collections = chunk5ARIHAGN_cjs.getCollectionRegistry().listActive().filter((r) => !r.internal).map((r) => {
15507
16025
  const cacheOverride = r.cache;
15508
16026
  const cacheEnabled = cacheOverride?.enabled !== false;
15509
16027
  const hasCustomTtl = typeof cacheOverride?.ttl === "number";
@@ -16040,16 +16558,17 @@ var faviconSvg = `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
16040
16558
  // src/app.ts
16041
16559
  function createSonicJSApp(config = {}) {
16042
16560
  const app2 = new hono.Hono();
16043
- const appVersion = config.version || chunkLRZIAW7U_cjs.getCoreVersion();
16561
+ const appVersion = config.version || chunkAQJEMVAY_cjs.getCoreVersion();
16044
16562
  const appName = config.name || "SonicJS AI";
16045
- const hookSystem = new chunkH2AXVCLS_cjs.HookSystemImpl();
16563
+ const hookSystem = new chunkDTGCXWWM_cjs.HookSystemImpl();
16046
16564
  chunkJ6JTWD2A_cjs.setHookSystem(hookSystem);
16047
16565
  const magicLinkPlugin = createMagicLinkAuthPlugin();
16048
16566
  const corePluginsBeforeCatchAll = [
16049
16567
  securityAuditPlugin,
16568
+ apiKeysPlugin,
16050
16569
  aiSearchPlugin,
16051
16570
  oauthProvidersPlugin,
16052
- chunkVXE42MYF_cjs.userProfilesPlugin,
16571
+ chunk3E7IROND_cjs.userProfilesPlugin,
16053
16572
  otpLoginPlugin,
16054
16573
  analyticsPlugin,
16055
16574
  stripePlugin,
@@ -16059,23 +16578,23 @@ function createSonicJSApp(config = {}) {
16059
16578
  shortcodesPlugin,
16060
16579
  helloWorldPlugin,
16061
16580
  multiTenantPlugin,
16062
- chunkVXE42MYF_cjs.lexicalEditorPlugin,
16581
+ chunk3E7IROND_cjs.lexicalEditorPlugin,
16063
16582
  versioningPlugin
16064
16583
  ];
16065
16584
  const corePluginsAfterCatchAll = [emailPluginV3, magicLinkPlugin, emailReconciliationPlugin];
16066
- const wirePlugins = chunkH2AXVCLS_cjs.createPluginWirer(
16585
+ const wirePlugins = chunkDTGCXWWM_cjs.createPluginWirer(
16067
16586
  () => [...corePluginsBeforeCatchAll, ...corePluginsAfterCatchAll, ...config.plugins?.register ?? []],
16068
16587
  // The capability-gated `ctx.cap.email` resolves to the app EmailService, which
16069
16588
  // is initialized (below) just before wiring on the first request.
16070
16589
  () => ({
16071
16590
  hooks: hookSystem,
16072
16591
  env: firstRequestEnv,
16073
- providers: { email: () => chunkVXE42MYF_cjs.getEmailService() }
16592
+ providers: { email: () => chunk3E7IROND_cjs.getEmailService() }
16074
16593
  })
16075
16594
  );
16076
16595
  let firstRequestEnv;
16077
16596
  const initEmailService = async (env = {}) => {
16078
- if (chunkVXE42MYF_cjs.hasEmailService()) return;
16597
+ if (chunk3E7IROND_cjs.hasEmailService()) return;
16079
16598
  let provider;
16080
16599
  let defaultFrom = config.email?.from;
16081
16600
  let defaultReplyTo;
@@ -16110,14 +16629,14 @@ function createSonicJSApp(config = {}) {
16110
16629
  }
16111
16630
  }
16112
16631
  defaultFrom = defaultFrom || env.DEFAULT_FROM_EMAIL || "noreply@sonicjs.local";
16113
- chunkVXE42MYF_cjs.setEmailService(new EmailService({ provider, defaultFrom, defaultReplyTo, db: env.DB }));
16632
+ chunk3E7IROND_cjs.setEmailService(new EmailService({ provider, defaultFrom, defaultReplyTo, db: env.DB }));
16114
16633
  };
16115
16634
  app2.use("*", async (c, next) => {
16116
16635
  c.set("appVersion", appVersion);
16117
16636
  await next();
16118
16637
  });
16119
- app2.use("*", chunkAAWNRBRB_cjs.metricsMiddleware());
16120
- app2.use("*", chunkAAWNRBRB_cjs.bootstrapMiddleware(config));
16638
+ app2.use("*", chunk4SHNHNRP_cjs.metricsMiddleware());
16639
+ app2.use("*", chunk4SHNHNRP_cjs.bootstrapMiddleware(config));
16121
16640
  const boot = async (env) => {
16122
16641
  if (config.plugins?.disableAll) return;
16123
16642
  firstRequestEnv = env;
@@ -16144,13 +16663,24 @@ function createSonicJSApp(config = {}) {
16144
16663
  app2.use("*", async (_c, next) => {
16145
16664
  await next();
16146
16665
  });
16147
- app2.use("*", chunkAAWNRBRB_cjs.securityHeadersMiddleware());
16148
- app2.use("*", chunkAAWNRBRB_cjs.csrfProtection());
16666
+ app2.use("*", cors.cors({
16667
+ origin: (origin, c) => {
16668
+ const allowed = c.env?.CORS_ORIGINS;
16669
+ if (!allowed) return null;
16670
+ const list = allowed.split(",").map((s) => s.trim());
16671
+ return list.includes(origin) ? origin : null;
16672
+ },
16673
+ allowMethods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
16674
+ allowHeaders: ["Content-Type", "Authorization", "X-API-Key"],
16675
+ credentials: true
16676
+ }));
16677
+ app2.use("*", chunk4SHNHNRP_cjs.securityHeadersMiddleware());
16678
+ app2.use("*", chunk4SHNHNRP_cjs.csrfProtection());
16149
16679
  app2.use("*", async (c, next) => {
16150
16680
  try {
16151
16681
  const reqUrl = new URL(c.req.url);
16152
16682
  const requestBaseURL = `${reqUrl.protocol}//${reqUrl.host}`;
16153
- const auth = chunkNUKJ54GA_cjs.createAuth(c.env, config.auth?.extendBetterAuth, requestBaseURL);
16683
+ const auth = chunkGMMCCIQO_cjs.createAuth(c.env, config.auth?.extendBetterAuth, requestBaseURL);
16154
16684
  const session = await auth.api.getSession({ headers: c.req.raw.headers });
16155
16685
  if (session?.user) {
16156
16686
  const u = session.user;
@@ -16177,14 +16707,15 @@ function createSonicJSApp(config = {}) {
16177
16707
  }
16178
16708
  await next();
16179
16709
  });
16710
+ app2.use("*", apiKeyAuthMiddleware());
16180
16711
  if (config.middleware?.afterAuth) {
16181
16712
  for (const middleware of config.middleware.afterAuth) {
16182
16713
  app2.use("*", middleware);
16183
16714
  }
16184
16715
  }
16185
- app2.use("*", chunkQAYFOER6_cjs.tenantMiddleware());
16186
- app2.use("/admin/*", chunkAAWNRBRB_cjs.requireAuth());
16187
- app2.use("/admin/*", chunkAAWNRBRB_cjs.requireRbac("portal", "access"));
16716
+ app2.use("*", chunk5ARIHAGN_cjs.tenantMiddleware());
16717
+ app2.use("/admin/*", chunk4SHNHNRP_cjs.requireAuth());
16718
+ app2.use("/admin/*", chunk4SHNHNRP_cjs.requireRbac("portal", "access"));
16188
16719
  app2.use("/admin/*", pluginMenuMiddleware());
16189
16720
  const NAV_LANDING = [
16190
16721
  { path: "/admin/content", perm: "content:read" },
@@ -16201,7 +16732,7 @@ function createSonicJSApp(config = {}) {
16201
16732
  if (!user?.userId) return next();
16202
16733
  let perms = [];
16203
16734
  try {
16204
- const { RbacService: RbacService2 } = await import('./rbac-VONLJJKB.cjs');
16735
+ const { RbacService: RbacService2 } = await import('./rbac-7QZ4JZ2E.cjs');
16205
16736
  perms = await new RbacService2(c.env.DB, c.env.CACHE_KV).permissionsForUser(user.userId);
16206
16737
  } catch {
16207
16738
  return next();
@@ -16230,43 +16761,43 @@ function createSonicJSApp(config = {}) {
16230
16761
  });
16231
16762
  app2.route("/api/security-audit", apiRoutes2);
16232
16763
  app2.route("/admin/plugins/security-audit", adminRoutes3);
16233
- app2.route("/api/media", chunkVXE42MYF_cjs.api_media_default);
16234
- app2.route("/api/system", chunkVXE42MYF_cjs.api_system_default);
16235
- app2.route("/api/documents", chunkVXE42MYF_cjs.apiDocumentsRoutes);
16236
- app2.route("/api", chunkVXE42MYF_cjs.api_default);
16237
- app2.route("/admin/documents", chunkVXE42MYF_cjs.adminDocumentsRoutes);
16238
- chunkH2AXVCLS_cjs.registerPluginRoutes(app2, [formsPlugin], { source: "core" });
16239
- app2.route("/admin/api", chunkVXE42MYF_cjs.admin_api_default);
16240
- app2.route("/admin/collections", chunkVXE42MYF_cjs.adminCollectionsRoutes);
16241
- app2.route("/admin/settings", chunkVXE42MYF_cjs.adminSettingsRoutes);
16242
- app2.route("/admin/api-reference", chunkVXE42MYF_cjs.router2);
16764
+ app2.route("/api/media", chunk3E7IROND_cjs.api_media_default);
16765
+ app2.route("/api/system", chunk3E7IROND_cjs.api_system_default);
16766
+ app2.route("/api/documents", chunk3E7IROND_cjs.apiDocumentsRoutes);
16767
+ app2.route("/api", chunk3E7IROND_cjs.api_default);
16768
+ app2.route("/admin/documents", chunk3E7IROND_cjs.adminDocumentsRoutes);
16769
+ chunkDTGCXWWM_cjs.registerPluginRoutes(app2, [formsPlugin], { source: "core" });
16770
+ app2.route("/admin/api", chunk3E7IROND_cjs.admin_api_default);
16771
+ app2.route("/admin/collections", chunk3E7IROND_cjs.adminCollectionsRoutes);
16772
+ app2.route("/admin/settings", chunk3E7IROND_cjs.adminSettingsRoutes);
16773
+ app2.route("/admin/api-reference", chunk3E7IROND_cjs.router2);
16243
16774
  app2.route("/admin/database-tools", createDatabaseToolsAdminRoutes());
16244
- app2.route("/admin/content", chunkVXE42MYF_cjs.admin_content_default);
16245
- app2.route("/admin/media", chunkVXE42MYF_cjs.adminMediaRoutes);
16775
+ app2.route("/admin/content", chunk3E7IROND_cjs.admin_content_default);
16776
+ app2.route("/admin/media", chunk3E7IROND_cjs.adminMediaRoutes);
16246
16777
  app2.use("/auth/*", securityAuditMiddleware());
16247
16778
  if (!config.plugins?.disableAll) {
16248
- chunkH2AXVCLS_cjs.registerPluginRoutes(app2, corePluginsBeforeCatchAll, { source: "core" });
16779
+ chunkDTGCXWWM_cjs.registerPluginRoutes(app2, corePluginsBeforeCatchAll, { source: "core" });
16249
16780
  app2.route("/admin/cache", cache_default.getRoutes());
16250
16781
  if (config.plugins?.register && config.plugins.register.length > 0) {
16251
- chunkH2AXVCLS_cjs.registerPluginRoutes(app2, config.plugins.register, { source: "user" });
16782
+ chunkDTGCXWWM_cjs.registerPluginRoutes(app2, config.plugins.register, { source: "user" });
16252
16783
  }
16253
16784
  }
16254
16785
  app2.route("/api/events", apiRoutes4);
16255
- app2.route("/admin/dashboard", chunkVXE42MYF_cjs.router);
16256
- app2.route("/admin/plugins", chunkVXE42MYF_cjs.adminPluginRoutes);
16257
- app2.route("/admin/logs", chunkVXE42MYF_cjs.adminLogsRoutes);
16786
+ app2.route("/admin/dashboard", chunk3E7IROND_cjs.router);
16787
+ app2.route("/admin/plugins", chunk3E7IROND_cjs.adminPluginRoutes);
16788
+ app2.route("/admin/logs", chunk3E7IROND_cjs.adminLogsRoutes);
16258
16789
  app2.route("/admin/rbac", adminRbacRoutes);
16259
- app2.route("/admin", chunkVXE42MYF_cjs.userRoutes);
16260
- app2.route("/auth", chunkVXE42MYF_cjs.auth_default);
16790
+ app2.route("/admin", chunk3E7IROND_cjs.userRoutes);
16791
+ app2.route("/auth", chunk3E7IROND_cjs.auth_default);
16261
16792
  app2.on(["GET", "POST"], "/auth/*", (c) => {
16262
16793
  const reqUrl = new URL(c.req.url);
16263
16794
  const requestBaseURL = `${reqUrl.protocol}//${reqUrl.host}`;
16264
- const auth = chunkNUKJ54GA_cjs.createAuth(c.env, config.auth?.extendBetterAuth, requestBaseURL);
16795
+ const auth = chunkGMMCCIQO_cjs.createAuth(c.env, config.auth?.extendBetterAuth, requestBaseURL);
16265
16796
  return auth.handler(c.req.raw);
16266
16797
  });
16267
- app2.route("/", chunkVXE42MYF_cjs.test_cleanup_default);
16798
+ app2.route("/", chunk3E7IROND_cjs.test_cleanup_default);
16268
16799
  if (!config.plugins?.disableAll) {
16269
- chunkH2AXVCLS_cjs.registerPluginRoutes(app2, corePluginsAfterCatchAll, { source: "core" });
16800
+ chunkDTGCXWWM_cjs.registerPluginRoutes(app2, corePluginsAfterCatchAll, { source: "core" });
16270
16801
  }
16271
16802
  if (!config.plugins?.disableAll) {
16272
16803
  const allMountedPlugins = [
@@ -16275,8 +16806,11 @@ function createSonicJSApp(config = {}) {
16275
16806
  ...corePluginsAfterCatchAll,
16276
16807
  ...config.plugins?.register ?? []
16277
16808
  ];
16278
- chunkH2AXVCLS_cjs.setPluginMenu(allMountedPlugins.flatMap((p) => p.menu ?? []));
16279
- chunkXW56B23A_cjs.setPluginDefinitions(allMountedPlugins);
16809
+ const userPlugins = (config.plugins?.register ?? []).filter(
16810
+ (p) => !chunk5ARIHAGN_cjs.PLUGIN_REGISTRY[p.id]
16811
+ );
16812
+ chunkDTGCXWWM_cjs.setPluginMenu(userPlugins.flatMap((p) => p.menu ?? []));
16813
+ chunk5RSB5SEK_cjs.setPluginDefinitions(allMountedPlugins);
16280
16814
  }
16281
16815
  app2.get("/favicon.svg", (c) => {
16282
16816
  return new Response(faviconSvg, {
@@ -16329,7 +16863,7 @@ function createSonicJSApp(config = {}) {
16329
16863
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
16330
16864
  });
16331
16865
  });
16332
- chunkBDDABDAB_cjs.setAppInstance(app2);
16866
+ chunk36Z3AKX3_cjs.setAppInstance(app2);
16333
16867
  app2.notFound((c) => {
16334
16868
  return c.json({ error: "Not Found", status: 404 }, 404);
16335
16869
  });
@@ -17140,9 +17674,11 @@ var RedirectService = class {
17140
17674
  this.cloudflareService = new CloudflareBulkService(env);
17141
17675
  }
17142
17676
  }
17677
+ db;
17678
+ env;
17143
17679
  cloudflareService = null;
17144
17680
  getDocService() {
17145
- return new chunk2CB4KY7I_cjs.DocumentsService(this.db, {
17681
+ return new chunkLTZ5WYOK_cjs.DocumentsService(this.db, {
17146
17682
  queryableFields: REDIRECT_QUERYABLE_FIELDS,
17147
17683
  maxVersionsPerRoot: 1,
17148
17684
  tenantId: TENANT3
@@ -17258,7 +17794,7 @@ var RedirectService = class {
17258
17794
  async batchCreate(rows, userId) {
17259
17795
  const now = Math.floor(Date.now() / 1e3);
17260
17796
  const statements = rows.map((r) => {
17261
- const id = chunkJEQ7FLOD_cjs.nanoid();
17797
+ const id = chunkKIGVVO6N_cjs.nanoid();
17262
17798
  const data = JSON.stringify({
17263
17799
  source: r.source,
17264
17800
  destination: r.destination,
@@ -18445,7 +18981,7 @@ function renderLayout(title, content2) {
18445
18981
  }
18446
18982
  </style>
18447
18983
  `;
18448
- return chunkNAVPFIG5_cjs.renderAdminLayoutCatalyst({
18984
+ return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst({
18449
18985
  title,
18450
18986
  currentPath: "/admin/redirects",
18451
18987
  content: customStyles + content2.toString()
@@ -18810,7 +19346,7 @@ function getFormScripts() {
18810
19346
  `;
18811
19347
  }
18812
19348
  function renderLayout2(title, content2) {
18813
- return chunkNAVPFIG5_cjs.renderAdminLayoutCatalyst({
19349
+ return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst({
18814
19350
  title,
18815
19351
  currentPath: "/admin/redirects",
18816
19352
  content: content2.toString()
@@ -19768,7 +20304,7 @@ function createRedirectApiRoutes() {
19768
20304
  });
19769
20305
  return api;
19770
20306
  }
19771
- var redirectPlugin = chunkXW56B23A_cjs.definePlugin({
20307
+ var redirectPlugin = chunk5RSB5SEK_cjs.definePlugin({
19772
20308
  id: manifest_default3.id,
19773
20309
  version: manifest_default3.version,
19774
20310
  name: manifest_default3.name,
@@ -19786,7 +20322,7 @@ var redirectPlugin = chunkXW56B23A_cjs.definePlugin({
19786
20322
  async onBoot(ctx) {
19787
20323
  const db = ctx.env?.DB;
19788
20324
  if (!db) return;
19789
- const registry = new chunkAAWNRBRB_cjs.DocumentTypeRegistry(db);
20325
+ const registry = new chunk4SHNHNRP_cjs.DocumentTypeRegistry(db);
19790
20326
  await registry.register({
19791
20327
  id: "redirect",
19792
20328
  name: "redirect",
@@ -19902,99 +20438,103 @@ function createDb(d1$1) {
19902
20438
  }
19903
20439
 
19904
20440
  // src/index.ts
19905
- var VERSION = chunkLRZIAW7U_cjs.package_default.version;
20441
+ var VERSION = chunkAQJEMVAY_cjs.package_default.version;
19906
20442
 
20443
+ Object.defineProperty(exports, "DocumentRepository", {
20444
+ enumerable: true,
20445
+ get: function () { return chunk3E7IROND_cjs.DocumentRepository; }
20446
+ });
19907
20447
  Object.defineProperty(exports, "ROUTES_INFO", {
19908
20448
  enumerable: true,
19909
- get: function () { return chunkVXE42MYF_cjs.ROUTES_INFO; }
20449
+ get: function () { return chunk3E7IROND_cjs.ROUTES_INFO; }
19910
20450
  });
19911
20451
  Object.defineProperty(exports, "adminApiRoutes", {
19912
20452
  enumerable: true,
19913
- get: function () { return chunkVXE42MYF_cjs.admin_api_default; }
20453
+ get: function () { return chunk3E7IROND_cjs.admin_api_default; }
19914
20454
  });
19915
20455
  Object.defineProperty(exports, "adminCheckboxRoutes", {
19916
20456
  enumerable: true,
19917
- get: function () { return chunkVXE42MYF_cjs.adminCheckboxRoutes; }
20457
+ get: function () { return chunk3E7IROND_cjs.adminCheckboxRoutes; }
19918
20458
  });
19919
20459
  Object.defineProperty(exports, "adminCollectionsRoutes", {
19920
20460
  enumerable: true,
19921
- get: function () { return chunkVXE42MYF_cjs.adminCollectionsRoutes; }
20461
+ get: function () { return chunk3E7IROND_cjs.adminCollectionsRoutes; }
19922
20462
  });
19923
20463
  Object.defineProperty(exports, "adminContentRoutes", {
19924
20464
  enumerable: true,
19925
- get: function () { return chunkVXE42MYF_cjs.admin_content_default; }
20465
+ get: function () { return chunk3E7IROND_cjs.admin_content_default; }
19926
20466
  });
19927
20467
  Object.defineProperty(exports, "adminDashboardRoutes", {
19928
20468
  enumerable: true,
19929
- get: function () { return chunkVXE42MYF_cjs.router; }
20469
+ get: function () { return chunk3E7IROND_cjs.router; }
19930
20470
  });
19931
20471
  Object.defineProperty(exports, "adminLogsRoutes", {
19932
20472
  enumerable: true,
19933
- get: function () { return chunkVXE42MYF_cjs.adminLogsRoutes; }
20473
+ get: function () { return chunk3E7IROND_cjs.adminLogsRoutes; }
19934
20474
  });
19935
20475
  Object.defineProperty(exports, "adminMediaRoutes", {
19936
20476
  enumerable: true,
19937
- get: function () { return chunkVXE42MYF_cjs.adminMediaRoutes; }
20477
+ get: function () { return chunk3E7IROND_cjs.adminMediaRoutes; }
19938
20478
  });
19939
20479
  Object.defineProperty(exports, "adminPluginRoutes", {
19940
20480
  enumerable: true,
19941
- get: function () { return chunkVXE42MYF_cjs.adminPluginRoutes; }
20481
+ get: function () { return chunk3E7IROND_cjs.adminPluginRoutes; }
19942
20482
  });
19943
20483
  Object.defineProperty(exports, "adminSettingsRoutes", {
19944
20484
  enumerable: true,
19945
- get: function () { return chunkVXE42MYF_cjs.adminSettingsRoutes; }
20485
+ get: function () { return chunk3E7IROND_cjs.adminSettingsRoutes; }
19946
20486
  });
19947
20487
  Object.defineProperty(exports, "adminUsersRoutes", {
19948
20488
  enumerable: true,
19949
- get: function () { return chunkVXE42MYF_cjs.userRoutes; }
20489
+ get: function () { return chunk3E7IROND_cjs.userRoutes; }
19950
20490
  });
19951
20491
  Object.defineProperty(exports, "apiContentCrudRoutes", {
19952
20492
  enumerable: true,
19953
- get: function () { return chunkVXE42MYF_cjs.api_content_crud_default; }
20493
+ get: function () { return chunk3E7IROND_cjs.api_content_crud_default; }
19954
20494
  });
19955
20495
  Object.defineProperty(exports, "apiMediaRoutes", {
19956
20496
  enumerable: true,
19957
- get: function () { return chunkVXE42MYF_cjs.api_media_default; }
20497
+ get: function () { return chunk3E7IROND_cjs.api_media_default; }
19958
20498
  });
19959
20499
  Object.defineProperty(exports, "apiRoutes", {
19960
20500
  enumerable: true,
19961
- get: function () { return chunkVXE42MYF_cjs.api_default; }
20501
+ get: function () { return chunk3E7IROND_cjs.api_default; }
19962
20502
  });
19963
20503
  Object.defineProperty(exports, "apiSystemRoutes", {
19964
20504
  enumerable: true,
19965
- get: function () { return chunkVXE42MYF_cjs.api_system_default; }
20505
+ get: function () { return chunk3E7IROND_cjs.api_system_default; }
19966
20506
  });
19967
20507
  Object.defineProperty(exports, "authRoutes", {
19968
20508
  enumerable: true,
19969
- get: function () { return chunkVXE42MYF_cjs.auth_default; }
20509
+ get: function () { return chunk3E7IROND_cjs.auth_default; }
19970
20510
  });
19971
20511
  Object.defineProperty(exports, "createUserProfilesPlugin", {
19972
20512
  enumerable: true,
19973
- get: function () { return chunkVXE42MYF_cjs.createUserProfilesPlugin; }
20513
+ get: function () { return chunk3E7IROND_cjs.createUserProfilesPlugin; }
19974
20514
  });
19975
20515
  Object.defineProperty(exports, "defineUserProfile", {
19976
20516
  enumerable: true,
19977
- get: function () { return chunkVXE42MYF_cjs.defineUserProfile; }
20517
+ get: function () { return chunk3E7IROND_cjs.defineUserProfile; }
19978
20518
  });
19979
20519
  Object.defineProperty(exports, "getUserProfileConfig", {
19980
20520
  enumerable: true,
19981
- get: function () { return chunkVXE42MYF_cjs.getUserProfileConfig; }
20521
+ get: function () { return chunk3E7IROND_cjs.getUserProfileConfig; }
19982
20522
  });
19983
20523
  Object.defineProperty(exports, "userProfilesPlugin", {
19984
20524
  enumerable: true,
19985
- get: function () { return chunkVXE42MYF_cjs.userProfilesPlugin; }
20525
+ get: function () { return chunk3E7IROND_cjs.userProfilesPlugin; }
19986
20526
  });
19987
20527
  Object.defineProperty(exports, "Logger", {
19988
20528
  enumerable: true,
19989
- get: function () { return chunkBDDABDAB_cjs.Logger; }
20529
+ get: function () { return chunk36Z3AKX3_cjs.Logger; }
19990
20530
  });
19991
20531
  Object.defineProperty(exports, "getLogger", {
19992
20532
  enumerable: true,
19993
- get: function () { return chunkBDDABDAB_cjs.getLogger; }
20533
+ get: function () { return chunk36Z3AKX3_cjs.getLogger; }
19994
20534
  });
19995
20535
  Object.defineProperty(exports, "initLogger", {
19996
20536
  enumerable: true,
19997
- get: function () { return chunkBDDABDAB_cjs.initLogger; }
20537
+ get: function () { return chunk36Z3AKX3_cjs.initLogger; }
19998
20538
  });
19999
20539
  Object.defineProperty(exports, "apiTokens", {
20000
20540
  enumerable: true,
@@ -20138,251 +20678,259 @@ Object.defineProperty(exports, "workflowHistory", {
20138
20678
  });
20139
20679
  Object.defineProperty(exports, "AuthManager", {
20140
20680
  enumerable: true,
20141
- get: function () { return chunkAAWNRBRB_cjs.AuthManager; }
20681
+ get: function () { return chunk4SHNHNRP_cjs.AuthManager; }
20142
20682
  });
20143
20683
  Object.defineProperty(exports, "PermissionManager", {
20144
20684
  enumerable: true,
20145
- get: function () { return chunkAAWNRBRB_cjs.PermissionManager; }
20685
+ get: function () { return chunk4SHNHNRP_cjs.PermissionManager; }
20146
20686
  });
20147
20687
  Object.defineProperty(exports, "bootstrapDocumentTypes", {
20148
20688
  enumerable: true,
20149
- get: function () { return chunkAAWNRBRB_cjs.bootstrapDocumentTypes; }
20689
+ get: function () { return chunk4SHNHNRP_cjs.bootstrapDocumentTypes; }
20150
20690
  });
20151
20691
  Object.defineProperty(exports, "bootstrapMiddleware", {
20152
20692
  enumerable: true,
20153
- get: function () { return chunkAAWNRBRB_cjs.bootstrapMiddleware; }
20693
+ get: function () { return chunk4SHNHNRP_cjs.bootstrapMiddleware; }
20154
20694
  });
20155
20695
  Object.defineProperty(exports, "cacheHeaders", {
20156
20696
  enumerable: true,
20157
- get: function () { return chunkAAWNRBRB_cjs.cacheHeaders; }
20697
+ get: function () { return chunk4SHNHNRP_cjs.cacheHeaders; }
20158
20698
  });
20159
20699
  Object.defineProperty(exports, "compressionMiddleware", {
20160
20700
  enumerable: true,
20161
- get: function () { return chunkAAWNRBRB_cjs.compressionMiddleware; }
20701
+ get: function () { return chunk4SHNHNRP_cjs.compressionMiddleware; }
20162
20702
  });
20163
20703
  Object.defineProperty(exports, "detailedLoggingMiddleware", {
20164
20704
  enumerable: true,
20165
- get: function () { return chunkAAWNRBRB_cjs.detailedLoggingMiddleware; }
20705
+ get: function () { return chunk4SHNHNRP_cjs.detailedLoggingMiddleware; }
20166
20706
  });
20167
20707
  Object.defineProperty(exports, "getActivePlugins", {
20168
20708
  enumerable: true,
20169
- get: function () { return chunkAAWNRBRB_cjs.getActivePlugins; }
20709
+ get: function () { return chunk4SHNHNRP_cjs.getActivePlugins; }
20170
20710
  });
20171
20711
  Object.defineProperty(exports, "isPluginActive", {
20172
20712
  enumerable: true,
20173
- get: function () { return chunkAAWNRBRB_cjs.isPluginActive; }
20713
+ get: function () { return chunk4SHNHNRP_cjs.isPluginActive; }
20174
20714
  });
20175
20715
  Object.defineProperty(exports, "logActivity", {
20176
20716
  enumerable: true,
20177
- get: function () { return chunkAAWNRBRB_cjs.logActivity; }
20717
+ get: function () { return chunk4SHNHNRP_cjs.logActivity; }
20178
20718
  });
20179
20719
  Object.defineProperty(exports, "loggingMiddleware", {
20180
20720
  enumerable: true,
20181
- get: function () { return chunkAAWNRBRB_cjs.loggingMiddleware; }
20721
+ get: function () { return chunk4SHNHNRP_cjs.loggingMiddleware; }
20182
20722
  });
20183
20723
  Object.defineProperty(exports, "optionalAuth", {
20184
20724
  enumerable: true,
20185
- get: function () { return chunkAAWNRBRB_cjs.optionalAuth; }
20725
+ get: function () { return chunk4SHNHNRP_cjs.optionalAuth; }
20186
20726
  });
20187
20727
  Object.defineProperty(exports, "performanceLoggingMiddleware", {
20188
20728
  enumerable: true,
20189
- get: function () { return chunkAAWNRBRB_cjs.performanceLoggingMiddleware; }
20729
+ get: function () { return chunk4SHNHNRP_cjs.performanceLoggingMiddleware; }
20190
20730
  });
20191
20731
  Object.defineProperty(exports, "requireActivePlugin", {
20192
20732
  enumerable: true,
20193
- get: function () { return chunkAAWNRBRB_cjs.requireActivePlugin; }
20733
+ get: function () { return chunk4SHNHNRP_cjs.requireActivePlugin; }
20194
20734
  });
20195
20735
  Object.defineProperty(exports, "requireActivePlugins", {
20196
20736
  enumerable: true,
20197
- get: function () { return chunkAAWNRBRB_cjs.requireActivePlugins; }
20737
+ get: function () { return chunk4SHNHNRP_cjs.requireActivePlugins; }
20198
20738
  });
20199
20739
  Object.defineProperty(exports, "requireAnyPermission", {
20200
20740
  enumerable: true,
20201
- get: function () { return chunkAAWNRBRB_cjs.requireAnyPermission; }
20741
+ get: function () { return chunk4SHNHNRP_cjs.requireAnyPermission; }
20202
20742
  });
20203
20743
  Object.defineProperty(exports, "requireAuth", {
20204
20744
  enumerable: true,
20205
- get: function () { return chunkAAWNRBRB_cjs.requireAuth; }
20745
+ get: function () { return chunk4SHNHNRP_cjs.requireAuth; }
20206
20746
  });
20207
20747
  Object.defineProperty(exports, "requirePermission", {
20208
20748
  enumerable: true,
20209
- get: function () { return chunkAAWNRBRB_cjs.requirePermission; }
20749
+ get: function () { return chunk4SHNHNRP_cjs.requirePermission; }
20210
20750
  });
20211
20751
  Object.defineProperty(exports, "requireRole", {
20212
20752
  enumerable: true,
20213
- get: function () { return chunkAAWNRBRB_cjs.requireRole; }
20753
+ get: function () { return chunk4SHNHNRP_cjs.requireRole; }
20214
20754
  });
20215
20755
  Object.defineProperty(exports, "securityHeaders", {
20216
20756
  enumerable: true,
20217
- get: function () { return chunkAAWNRBRB_cjs.securityHeadersMiddleware; }
20757
+ get: function () { return chunk4SHNHNRP_cjs.securityHeadersMiddleware; }
20218
20758
  });
20219
20759
  Object.defineProperty(exports, "securityLoggingMiddleware", {
20220
20760
  enumerable: true,
20221
- get: function () { return chunkAAWNRBRB_cjs.securityLoggingMiddleware; }
20761
+ get: function () { return chunk4SHNHNRP_cjs.securityLoggingMiddleware; }
20762
+ });
20763
+ Object.defineProperty(exports, "DocumentsService", {
20764
+ enumerable: true,
20765
+ get: function () { return chunkLTZ5WYOK_cjs.DocumentsService; }
20222
20766
  });
20223
20767
  Object.defineProperty(exports, "RbacService", {
20224
20768
  enumerable: true,
20225
- get: function () { return chunk2CB4KY7I_cjs.RbacService; }
20769
+ get: function () { return chunkLTZ5WYOK_cjs.RbacService; }
20226
20770
  });
20227
20771
  Object.defineProperty(exports, "PluginBootstrapService", {
20228
20772
  enumerable: true,
20229
- get: function () { return chunkQAYFOER6_cjs.PluginBootstrapService; }
20773
+ get: function () { return chunk5ARIHAGN_cjs.PluginBootstrapService; }
20230
20774
  });
20231
20775
  Object.defineProperty(exports, "PluginServiceClass", {
20232
20776
  enumerable: true,
20233
- get: function () { return chunkQAYFOER6_cjs.PluginService; }
20777
+ get: function () { return chunk5ARIHAGN_cjs.PluginService; }
20234
20778
  });
20235
20779
  Object.defineProperty(exports, "getAvailableCollectionNames", {
20236
20780
  enumerable: true,
20237
- get: function () { return chunkQAYFOER6_cjs.getAvailableCollectionNames; }
20781
+ get: function () { return chunk5ARIHAGN_cjs.getAvailableCollectionNames; }
20238
20782
  });
20239
20783
  Object.defineProperty(exports, "loadCollectionConfig", {
20240
20784
  enumerable: true,
20241
- get: function () { return chunkQAYFOER6_cjs.loadCollectionConfig; }
20785
+ get: function () { return chunk5ARIHAGN_cjs.loadCollectionConfig; }
20242
20786
  });
20243
20787
  Object.defineProperty(exports, "loadCollectionConfigs", {
20244
20788
  enumerable: true,
20245
- get: function () { return chunkQAYFOER6_cjs.loadCollectionConfigs; }
20789
+ get: function () { return chunk5ARIHAGN_cjs.loadCollectionConfigs; }
20246
20790
  });
20247
20791
  Object.defineProperty(exports, "registerCollections", {
20248
20792
  enumerable: true,
20249
- get: function () { return chunkQAYFOER6_cjs.registerCollections; }
20793
+ get: function () { return chunk5ARIHAGN_cjs.registerCollections; }
20250
20794
  });
20251
20795
  Object.defineProperty(exports, "validateCollectionConfig", {
20252
20796
  enumerable: true,
20253
- get: function () { return chunkQAYFOER6_cjs.validateCollectionConfig; }
20797
+ get: function () { return chunk5ARIHAGN_cjs.validateCollectionConfig; }
20254
20798
  });
20255
20799
  Object.defineProperty(exports, "MigrationService", {
20256
20800
  enumerable: true,
20257
- get: function () { return chunkDSA4UX5B_cjs.MigrationService; }
20801
+ get: function () { return chunkTQG5FNNR_cjs.MigrationService; }
20258
20802
  });
20259
20803
  Object.defineProperty(exports, "renderFilterBar", {
20260
20804
  enumerable: true,
20261
- get: function () { return chunkWULONYGB_cjs.renderFilterBar; }
20805
+ get: function () { return chunkCRGUD4KC_cjs.renderFilterBar; }
20262
20806
  });
20263
20807
  Object.defineProperty(exports, "getConfirmationDialogScript", {
20264
20808
  enumerable: true,
20265
- get: function () { return chunkMVIZJOO5_cjs.getConfirmationDialogScript; }
20809
+ get: function () { return chunkPXNTCCPE_cjs.getConfirmationDialogScript; }
20266
20810
  });
20267
20811
  Object.defineProperty(exports, "renderAlert", {
20268
20812
  enumerable: true,
20269
- get: function () { return chunkMVIZJOO5_cjs.renderAlert; }
20813
+ get: function () { return chunkPXNTCCPE_cjs.renderAlert; }
20270
20814
  });
20271
20815
  Object.defineProperty(exports, "renderConfirmationDialog", {
20272
20816
  enumerable: true,
20273
- get: function () { return chunkMVIZJOO5_cjs.renderConfirmationDialog; }
20817
+ get: function () { return chunkPXNTCCPE_cjs.renderConfirmationDialog; }
20274
20818
  });
20275
20819
  Object.defineProperty(exports, "renderForm", {
20276
20820
  enumerable: true,
20277
- get: function () { return chunkMVIZJOO5_cjs.renderForm; }
20821
+ get: function () { return chunkPXNTCCPE_cjs.renderForm; }
20278
20822
  });
20279
20823
  Object.defineProperty(exports, "renderFormField", {
20280
20824
  enumerable: true,
20281
- get: function () { return chunkMVIZJOO5_cjs.renderFormField; }
20825
+ get: function () { return chunkPXNTCCPE_cjs.renderFormField; }
20282
20826
  });
20283
20827
  Object.defineProperty(exports, "renderPagination", {
20284
20828
  enumerable: true,
20285
- get: function () { return chunkMVIZJOO5_cjs.renderPagination; }
20829
+ get: function () { return chunkPXNTCCPE_cjs.renderPagination; }
20286
20830
  });
20287
20831
  Object.defineProperty(exports, "renderTable", {
20288
20832
  enumerable: true,
20289
- get: function () { return chunkMVIZJOO5_cjs.renderTable; }
20833
+ get: function () { return chunkPXNTCCPE_cjs.renderTable; }
20834
+ });
20835
+ Object.defineProperty(exports, "renderAdminLayoutCatalyst", {
20836
+ enumerable: true,
20837
+ get: function () { return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst; }
20290
20838
  });
20291
20839
  Object.defineProperty(exports, "HookSystemImpl", {
20292
20840
  enumerable: true,
20293
- get: function () { return chunkH2AXVCLS_cjs.HookSystemImpl; }
20841
+ get: function () { return chunkDTGCXWWM_cjs.HookSystemImpl; }
20294
20842
  });
20295
20843
  Object.defineProperty(exports, "HookUtils", {
20296
20844
  enumerable: true,
20297
- get: function () { return chunkH2AXVCLS_cjs.HookUtils; }
20845
+ get: function () { return chunkDTGCXWWM_cjs.HookUtils; }
20298
20846
  });
20299
20847
  Object.defineProperty(exports, "PluginDependencyCycleError", {
20300
20848
  enumerable: true,
20301
- get: function () { return chunkH2AXVCLS_cjs.PluginDependencyCycleError; }
20849
+ get: function () { return chunkDTGCXWWM_cjs.PluginDependencyCycleError; }
20302
20850
  });
20303
20851
  Object.defineProperty(exports, "PluginManagerClass", {
20304
20852
  enumerable: true,
20305
- get: function () { return chunkH2AXVCLS_cjs.PluginManager; }
20853
+ get: function () { return chunkDTGCXWWM_cjs.PluginManager; }
20306
20854
  });
20307
20855
  Object.defineProperty(exports, "PluginRegistryImpl", {
20308
20856
  enumerable: true,
20309
- get: function () { return chunkH2AXVCLS_cjs.PluginRegistryImpl; }
20857
+ get: function () { return chunkDTGCXWWM_cjs.PluginRegistryImpl; }
20310
20858
  });
20311
20859
  Object.defineProperty(exports, "PluginValidatorClass", {
20312
20860
  enumerable: true,
20313
- get: function () { return chunkH2AXVCLS_cjs.PluginValidator; }
20861
+ get: function () { return chunkDTGCXWWM_cjs.PluginValidator; }
20314
20862
  });
20315
20863
  Object.defineProperty(exports, "RegisterPluginsError", {
20316
20864
  enumerable: true,
20317
- get: function () { return chunkH2AXVCLS_cjs.RegisterPluginsError; }
20865
+ get: function () { return chunkDTGCXWWM_cjs.RegisterPluginsError; }
20318
20866
  });
20319
20867
  Object.defineProperty(exports, "ScopedHookSystemClass", {
20320
20868
  enumerable: true,
20321
- get: function () { return chunkH2AXVCLS_cjs.ScopedHookSystem; }
20869
+ get: function () { return chunkDTGCXWWM_cjs.ScopedHookSystem; }
20322
20870
  });
20323
20871
  Object.defineProperty(exports, "collectCronSchedules", {
20324
20872
  enumerable: true,
20325
- get: function () { return chunkH2AXVCLS_cjs.collectCronSchedules; }
20873
+ get: function () { return chunkDTGCXWWM_cjs.collectCronSchedules; }
20326
20874
  });
20327
20875
  Object.defineProperty(exports, "collectCrons", {
20328
20876
  enumerable: true,
20329
- get: function () { return chunkH2AXVCLS_cjs.collectCrons; }
20877
+ get: function () { return chunkDTGCXWWM_cjs.collectCrons; }
20330
20878
  });
20331
20879
  Object.defineProperty(exports, "createScheduledHandler", {
20332
20880
  enumerable: true,
20333
- get: function () { return chunkH2AXVCLS_cjs.createScheduledHandler; }
20881
+ get: function () { return chunkDTGCXWWM_cjs.createScheduledHandler; }
20334
20882
  });
20335
20883
  Object.defineProperty(exports, "dispatchCronTick", {
20336
20884
  enumerable: true,
20337
- get: function () { return chunkH2AXVCLS_cjs.dispatchCronTick; }
20885
+ get: function () { return chunkDTGCXWWM_cjs.dispatchCronTick; }
20338
20886
  });
20339
20887
  Object.defineProperty(exports, "getPluginMenu", {
20340
20888
  enumerable: true,
20341
- get: function () { return chunkH2AXVCLS_cjs.getPluginMenu; }
20889
+ get: function () { return chunkDTGCXWWM_cjs.getPluginMenu; }
20342
20890
  });
20343
20891
  Object.defineProperty(exports, "registerPlugins", {
20344
20892
  enumerable: true,
20345
- get: function () { return chunkH2AXVCLS_cjs.registerPlugins; }
20893
+ get: function () { return chunkDTGCXWWM_cjs.registerPlugins; }
20346
20894
  });
20347
20895
  Object.defineProperty(exports, "resetPluginMenu", {
20348
20896
  enumerable: true,
20349
- get: function () { return chunkH2AXVCLS_cjs.resetPluginMenu; }
20897
+ get: function () { return chunkDTGCXWWM_cjs.resetPluginMenu; }
20350
20898
  });
20351
20899
  Object.defineProperty(exports, "resolvePluginMenuItems", {
20352
20900
  enumerable: true,
20353
- get: function () { return chunkH2AXVCLS_cjs.resolvePluginMenuItems; }
20901
+ get: function () { return chunkDTGCXWWM_cjs.resolvePluginMenuItems; }
20354
20902
  });
20355
20903
  Object.defineProperty(exports, "setPluginMenu", {
20356
20904
  enumerable: true,
20357
- get: function () { return chunkH2AXVCLS_cjs.setPluginMenu; }
20905
+ get: function () { return chunkDTGCXWWM_cjs.setPluginMenu; }
20358
20906
  });
20359
20907
  Object.defineProperty(exports, "topoSort", {
20360
20908
  enumerable: true,
20361
- get: function () { return chunkH2AXVCLS_cjs.topoSort; }
20909
+ get: function () { return chunkDTGCXWWM_cjs.topoSort; }
20362
20910
  });
20363
20911
  Object.defineProperty(exports, "applySchemaDefaults", {
20364
20912
  enumerable: true,
20365
- get: function () { return chunkXW56B23A_cjs.applySchemaDefaults; }
20913
+ get: function () { return chunk5RSB5SEK_cjs.applySchemaDefaults; }
20366
20914
  });
20367
20915
  Object.defineProperty(exports, "definePlugin", {
20368
20916
  enumerable: true,
20369
- get: function () { return chunkXW56B23A_cjs.definePlugin; }
20917
+ get: function () { return chunk5RSB5SEK_cjs.definePlugin; }
20370
20918
  });
20371
20919
  Object.defineProperty(exports, "isDefinedPlugin", {
20372
20920
  enumerable: true,
20373
- get: function () { return chunkXW56B23A_cjs.isDefinedPlugin; }
20921
+ get: function () { return chunk5RSB5SEK_cjs.isDefinedPlugin; }
20374
20922
  });
20375
20923
  Object.defineProperty(exports, "parseConfigSchema", {
20376
20924
  enumerable: true,
20377
- get: function () { return chunkXW56B23A_cjs.parseConfigSchema; }
20925
+ get: function () { return chunk5RSB5SEK_cjs.parseConfigSchema; }
20378
20926
  });
20379
20927
  Object.defineProperty(exports, "parseFormDataToSettings", {
20380
20928
  enumerable: true,
20381
- get: function () { return chunkXW56B23A_cjs.parseFormDataToSettings; }
20929
+ get: function () { return chunk5RSB5SEK_cjs.parseFormDataToSettings; }
20382
20930
  });
20383
20931
  Object.defineProperty(exports, "renderSchemaFields", {
20384
20932
  enumerable: true,
20385
- get: function () { return chunkXW56B23A_cjs.renderSchemaFields; }
20933
+ get: function () { return chunk5RSB5SEK_cjs.renderSchemaFields; }
20386
20934
  });
20387
20935
  Object.defineProperty(exports, "getHookSystem", {
20388
20936
  enumerable: true,
@@ -20430,11 +20978,11 @@ Object.defineProperty(exports, "metricsTracker", {
20430
20978
  });
20431
20979
  Object.defineProperty(exports, "SONICJS_VERSION", {
20432
20980
  enumerable: true,
20433
- get: function () { return chunkLRZIAW7U_cjs.SONICJS_VERSION; }
20981
+ get: function () { return chunkAQJEMVAY_cjs.SONICJS_VERSION; }
20434
20982
  });
20435
20983
  Object.defineProperty(exports, "getCoreVersion", {
20436
20984
  enumerable: true,
20437
- get: function () { return chunkLRZIAW7U_cjs.getCoreVersion; }
20985
+ get: function () { return chunkAQJEMVAY_cjs.getCoreVersion; }
20438
20986
  });
20439
20987
  Object.defineProperty(exports, "escapeHtml", {
20440
20988
  enumerable: true,
@@ -20457,11 +21005,13 @@ exports.CloudflareEmailProvider = CloudflareEmailProvider2;
20457
21005
  exports.OAuthService = OAuthService;
20458
21006
  exports.VERSION = VERSION;
20459
21007
  exports.createDb = createDb;
21008
+ exports.createHelloWorldPlugin = createHelloWorldPlugin;
20460
21009
  exports.createOAuthProvidersPlugin = createOAuthProvidersPlugin;
20461
21010
  exports.createRedirectPlugin = createRedirectPlugin;
20462
21011
  exports.createSonicJSApp = createSonicJSApp;
20463
21012
  exports.emailReconciliationPlugin = emailReconciliationPlugin;
20464
21013
  exports.generateTriggersComment = generateTriggersComment;
21014
+ exports.helloWorldPlugin = helloWorldPlugin;
20465
21015
  exports.oauthProvidersPlugin = oauthProvidersPlugin;
20466
21016
  exports.parseCronTriggers = parseCronTriggers;
20467
21017
  exports.redirectPlugin = redirectPlugin;