@sonicjs-cms/core 3.0.0-beta.14 → 3.0.0-beta.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/dist/{app-Bo0X1OWX.d.ts → app-01M0dIwt.d.ts} +1 -1
  2. package/dist/{app-Do66yCcV.d.cts → app-aj39TGHB.d.cts} +1 -1
  3. package/dist/{chunk-SIPBHWMG.cjs → chunk-3XFA3E2F.cjs} +4 -4
  4. package/dist/{chunk-SIPBHWMG.cjs.map → chunk-3XFA3E2F.cjs.map} +1 -1
  5. package/dist/{chunk-QNPT6BQP.js → chunk-7P2IJM4K.js} +3 -3
  6. package/dist/{chunk-QNPT6BQP.js.map → chunk-7P2IJM4K.js.map} +1 -1
  7. package/dist/{chunk-32SDMKZ7.js → chunk-HYO2MSFI.js} +2 -2
  8. package/dist/{chunk-32SDMKZ7.js.map → chunk-HYO2MSFI.js.map} +1 -1
  9. package/dist/{chunk-H5FB6GKR.cjs → chunk-IA24HACT.cjs} +2 -2
  10. package/dist/{chunk-H5FB6GKR.cjs.map → chunk-IA24HACT.cjs.map} +1 -1
  11. package/dist/{chunk-75JKPNUZ.js → chunk-IQZA2OY5.js} +3 -3
  12. package/dist/{chunk-75JKPNUZ.js.map → chunk-IQZA2OY5.js.map} +1 -1
  13. package/dist/{chunk-5L6EMI7A.js → chunk-IXUNNFZZ.js} +6 -5
  14. package/dist/chunk-IXUNNFZZ.js.map +1 -0
  15. package/dist/{chunk-U7T5EOHJ.js → chunk-JRMBHDGM.js} +4 -4
  16. package/dist/{chunk-U7T5EOHJ.js.map → chunk-JRMBHDGM.js.map} +1 -1
  17. package/dist/{chunk-INE5E3SL.js → chunk-KIB7K5LV.js} +27 -2
  18. package/dist/chunk-KIB7K5LV.js.map +1 -0
  19. package/dist/{chunk-ZTEJHSYS.cjs → chunk-KMCLNO4K.cjs} +5 -5
  20. package/dist/{chunk-ZTEJHSYS.cjs.map → chunk-KMCLNO4K.cjs.map} +1 -1
  21. package/dist/{chunk-L3KHLEHL.cjs → chunk-KMM45BTY.cjs} +53 -15
  22. package/dist/chunk-KMM45BTY.cjs.map +1 -0
  23. package/dist/{chunk-4YRYGDCQ.cjs → chunk-KOXFYFOF.cjs} +4 -4
  24. package/dist/{chunk-4YRYGDCQ.cjs.map → chunk-KOXFYFOF.cjs.map} +1 -1
  25. package/dist/{chunk-WIV3R2MJ.cjs → chunk-KZIBF2EV.cjs} +27 -2
  26. package/dist/chunk-KZIBF2EV.cjs.map +1 -0
  27. package/dist/{chunk-G5LC7MYH.cjs → chunk-LXYDJU6U.cjs} +12 -11
  28. package/dist/chunk-LXYDJU6U.cjs.map +1 -0
  29. package/dist/{chunk-O32IZ6JS.js → chunk-PA2UIFB7.js} +43 -5
  30. package/dist/chunk-PA2UIFB7.js.map +1 -0
  31. package/dist/{chunk-SSOP7G4R.cjs → chunk-SC2WZFNQ.cjs} +309 -243
  32. package/dist/chunk-SC2WZFNQ.cjs.map +1 -0
  33. package/dist/{chunk-HNUGMALL.js → chunk-UOFRE5PY.js} +104 -39
  34. package/dist/chunk-UOFRE5PY.js.map +1 -0
  35. package/dist/{chunk-IESEVHXL.js → chunk-VVYVFCML.js} +12 -3
  36. package/dist/chunk-VVYVFCML.js.map +1 -0
  37. package/dist/{chunk-HIKBY7MS.cjs → chunk-XWVDSM2L.cjs} +12 -3
  38. package/dist/chunk-XWVDSM2L.cjs.map +1 -0
  39. package/dist/config-SM2UWSDN.js +6 -0
  40. package/dist/{config-PLJTDINX.js.map → config-SM2UWSDN.js.map} +1 -1
  41. package/dist/config-YCRSU7ZP.cjs +19 -0
  42. package/dist/{config-FLOUCYHH.cjs.map → config-YCRSU7ZP.cjs.map} +1 -1
  43. package/dist/{define-plugin-BzNHc1ZI.d.ts → define-plugin-BYIey6sp.d.ts} +1 -1
  44. package/dist/{define-plugin-IWDKYaVm.d.cts → define-plugin-DsKiGu1q.d.cts} +1 -1
  45. package/dist/index.cjs +775 -297
  46. package/dist/index.cjs.map +1 -1
  47. package/dist/index.d.cts +194 -7
  48. package/dist/index.d.ts +194 -7
  49. package/dist/index.js +527 -59
  50. package/dist/index.js.map +1 -1
  51. package/dist/middleware.cjs +33 -33
  52. package/dist/middleware.d.cts +2 -2
  53. package/dist/middleware.d.ts +2 -2
  54. package/dist/middleware.js +4 -4
  55. package/dist/migrations-F4LBAHQN.js +4 -0
  56. package/dist/{migrations-DOPZXFK3.js.map → migrations-F4LBAHQN.js.map} +1 -1
  57. package/dist/migrations-KMCULV6H.cjs +13 -0
  58. package/dist/{migrations-TYYC66P4.cjs.map → migrations-KMCULV6H.cjs.map} +1 -1
  59. package/dist/plugins.cjs +40 -40
  60. package/dist/plugins.d.cts +2 -2
  61. package/dist/plugins.d.ts +2 -2
  62. package/dist/plugins.js +3 -3
  63. package/dist/routes.cjs +27 -27
  64. package/dist/routes.d.cts +2 -2
  65. package/dist/routes.d.ts +2 -2
  66. package/dist/routes.js +7 -7
  67. package/dist/services.cjs +18 -18
  68. package/dist/services.js +2 -2
  69. package/dist/{types-Dea1eNxU.d.cts → types-DT7XN5TX.d.cts} +1 -1
  70. package/dist/{types-Dea1eNxU.d.ts → types-DT7XN5TX.d.ts} +1 -1
  71. package/dist/utils.cjs +3 -3
  72. package/dist/utils.js +1 -1
  73. package/package.json +2 -2
  74. package/dist/chunk-5L6EMI7A.js.map +0 -1
  75. package/dist/chunk-G5LC7MYH.cjs.map +0 -1
  76. package/dist/chunk-HIKBY7MS.cjs.map +0 -1
  77. package/dist/chunk-HNUGMALL.js.map +0 -1
  78. package/dist/chunk-IESEVHXL.js.map +0 -1
  79. package/dist/chunk-INE5E3SL.js.map +0 -1
  80. package/dist/chunk-L3KHLEHL.cjs.map +0 -1
  81. package/dist/chunk-O32IZ6JS.js.map +0 -1
  82. package/dist/chunk-SSOP7G4R.cjs.map +0 -1
  83. package/dist/chunk-WIV3R2MJ.cjs.map +0 -1
  84. package/dist/config-FLOUCYHH.cjs +0 -19
  85. package/dist/config-PLJTDINX.js +0 -6
  86. package/dist/migrations-DOPZXFK3.js +0 -4
  87. package/dist/migrations-TYYC66P4.cjs +0 -13
package/dist/index.cjs CHANGED
@@ -1,27 +1,27 @@
1
1
  'use strict';
2
2
 
3
- var chunkZTEJHSYS_cjs = require('./chunk-ZTEJHSYS.cjs');
4
- var chunkSSOP7G4R_cjs = require('./chunk-SSOP7G4R.cjs');
5
- require('./chunk-HIKBY7MS.cjs');
3
+ var chunkKMCLNO4K_cjs = require('./chunk-KMCLNO4K.cjs');
4
+ var chunkSC2WZFNQ_cjs = require('./chunk-SC2WZFNQ.cjs');
5
+ require('./chunk-XWVDSM2L.cjs');
6
6
  require('./chunk-N32OWET6.cjs');
7
7
  var chunk4BTBSXMR_cjs = require('./chunk-4BTBSXMR.cjs');
8
8
  var chunkYA3TJ65D_cjs = require('./chunk-YA3TJ65D.cjs');
9
9
  var chunkYP7GW2G5_cjs = require('./chunk-YP7GW2G5.cjs');
10
- var chunkL3KHLEHL_cjs = require('./chunk-L3KHLEHL.cjs');
10
+ var chunkKMM45BTY_cjs = require('./chunk-KMM45BTY.cjs');
11
11
  var chunkW36OZTJ5_cjs = require('./chunk-W36OZTJ5.cjs');
12
12
  var chunkJEQ7FLOD_cjs = require('./chunk-JEQ7FLOD.cjs');
13
- var chunkWIV3R2MJ_cjs = require('./chunk-WIV3R2MJ.cjs');
14
- var chunkH5FB6GKR_cjs = require('./chunk-H5FB6GKR.cjs');
13
+ var chunkKZIBF2EV_cjs = require('./chunk-KZIBF2EV.cjs');
14
+ var chunkIA24HACT_cjs = require('./chunk-IA24HACT.cjs');
15
15
  var chunkCRGUD4KC_cjs = require('./chunk-CRGUD4KC.cjs');
16
16
  var chunkPXNTCCPE_cjs = require('./chunk-PXNTCCPE.cjs');
17
17
  var chunkK623Q6WD_cjs = require('./chunk-K623Q6WD.cjs');
18
- var chunkG5LC7MYH_cjs = require('./chunk-G5LC7MYH.cjs');
19
- var chunk4YRYGDCQ_cjs = require('./chunk-4YRYGDCQ.cjs');
18
+ var chunkLXYDJU6U_cjs = require('./chunk-LXYDJU6U.cjs');
19
+ var chunkKOXFYFOF_cjs = require('./chunk-KOXFYFOF.cjs');
20
20
  var chunkJ6JTWD2A_cjs = require('./chunk-J6JTWD2A.cjs');
21
21
  var chunkIXUHXTHW_cjs = require('./chunk-IXUHXTHW.cjs');
22
22
  var chunkRCQ2HIQD_cjs = require('./chunk-RCQ2HIQD.cjs');
23
23
  require('./chunk-P3XDZL6Q.cjs');
24
- var chunkSIPBHWMG_cjs = require('./chunk-SIPBHWMG.cjs');
24
+ var chunk3XFA3E2F_cjs = require('./chunk-3XFA3E2F.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');
@@ -574,7 +574,7 @@ function formatCellValue(value) {
574
574
  // src/plugins/core-plugins/database-tools-plugin/admin-routes.ts
575
575
  function createDatabaseToolsAdminRoutes() {
576
576
  const router3 = new hono.Hono();
577
- router3.use("*", chunkL3KHLEHL_cjs.requireAuth());
577
+ router3.use("*", chunkKMM45BTY_cjs.requireAuth());
578
578
  router3.get("/api/stats", async (c) => {
579
579
  try {
580
580
  const user = c.get("user");
@@ -977,7 +977,7 @@ var SiteConfigService = class {
977
977
 
978
978
  // src/plugins/core-plugins/email-plugin/routes/admin.ts
979
979
  var adminRoutes = new hono.Hono();
980
- adminRoutes.use("*", chunkL3KHLEHL_cjs.requireAuth());
980
+ adminRoutes.use("*", chunkKMM45BTY_cjs.requireAuth());
981
981
  adminRoutes.post("/settings", async (c) => {
982
982
  if (c.get("user")?.role !== "admin") {
983
983
  return c.json({ error: "admin role required" }, 403);
@@ -1015,7 +1015,7 @@ adminRoutes.post("/test", async (c) => {
1015
1015
  const { subject, html: html4, text } = renderTestEmail({ siteName });
1016
1016
  try {
1017
1017
  const settingsLoaded = await settings.load();
1018
- const result = await chunkSSOP7G4R_cjs.getEmailService().send({
1018
+ const result = await chunkSC2WZFNQ_cjs.getEmailService().send({
1019
1019
  to,
1020
1020
  subject,
1021
1021
  html: html4,
@@ -1097,7 +1097,7 @@ function makeOnRegistrationCompleted(env) {
1097
1097
  siteName,
1098
1098
  loginUrl: siteConfig.buildLoginUrl(siteUrl)
1099
1099
  });
1100
- const result = await chunkSSOP7G4R_cjs.getEmailService().send({
1100
+ const result = await chunkSC2WZFNQ_cjs.getEmailService().send({
1101
1101
  to: user.email,
1102
1102
  subject,
1103
1103
  html: html4,
@@ -1171,7 +1171,7 @@ function makeOnPasswordResetRequested(env) {
1171
1171
  expiresAt: Date.now() + DEFAULT_EXPIRY_MS,
1172
1172
  siteName
1173
1173
  });
1174
- const result = await chunkSSOP7G4R_cjs.getEmailService().send({
1174
+ const result = await chunkSC2WZFNQ_cjs.getEmailService().send({
1175
1175
  to: user.email,
1176
1176
  subject,
1177
1177
  html: html4,
@@ -1239,7 +1239,7 @@ function makeOnPasswordResetCompleted(env) {
1239
1239
  supportEmail,
1240
1240
  when: Date.now()
1241
1241
  });
1242
- const result = await chunkSSOP7G4R_cjs.getEmailService().send({
1242
+ const result = await chunkSC2WZFNQ_cjs.getEmailService().send({
1243
1243
  to: user.email,
1244
1244
  subject,
1245
1245
  html: html4,
@@ -1971,7 +1971,7 @@ var CloudflareEmailProvider = class {
1971
1971
  }
1972
1972
  }
1973
1973
  };
1974
- var emailPluginV3 = chunk4YRYGDCQ_cjs.definePlugin({
1974
+ var emailPluginV3 = chunkKOXFYFOF_cjs.definePlugin({
1975
1975
  id: "email",
1976
1976
  version: "1.0.0",
1977
1977
  name: "Email",
@@ -1985,7 +1985,7 @@ var emailPluginV3 = chunk4YRYGDCQ_cjs.definePlugin({
1985
1985
  const db = env.DB;
1986
1986
  if (db) {
1987
1987
  try {
1988
- const typeRegistry = new chunkL3KHLEHL_cjs.DocumentTypeRegistry(db);
1988
+ const typeRegistry = new chunkKMM45BTY_cjs.DocumentTypeRegistry(db);
1989
1989
  await typeRegistry.register({
1990
1990
  id: "email_log",
1991
1991
  name: "email_log",
@@ -2000,7 +2000,7 @@ var emailPluginV3 = chunk4YRYGDCQ_cjs.definePlugin({
2000
2000
  } catch {
2001
2001
  }
2002
2002
  }
2003
- if (!chunkSSOP7G4R_cjs.hasEmailService()) {
2003
+ if (!chunkSC2WZFNQ_cjs.hasEmailService()) {
2004
2004
  const settings = db ? await new EmailSettingsService(db).load() : {};
2005
2005
  const envResendKey = typeof env.RESEND_API_KEY === "string" && env.RESEND_API_KEY ? env.RESEND_API_KEY : void 0;
2006
2006
  const cfEmailBinding = env.EMAIL;
@@ -2018,7 +2018,7 @@ var emailPluginV3 = chunk4YRYGDCQ_cjs.definePlugin({
2018
2018
  } else {
2019
2019
  provider = resolveEmailProvider({ env });
2020
2020
  }
2021
- chunkSSOP7G4R_cjs.setEmailService(new EmailService({ ...serviceOpts, provider }));
2021
+ chunkSC2WZFNQ_cjs.setEmailService(new EmailService({ ...serviceOpts, provider }));
2022
2022
  }
2023
2023
  ctx.hooks.on("auth:registration:completed", makeOnRegistrationCompleted(env));
2024
2024
  ctx.hooks.on("auth:password-reset:requested", makeOnPasswordResetRequested(env));
@@ -2029,7 +2029,7 @@ var emailPluginV3 = chunk4YRYGDCQ_cjs.definePlugin({
2029
2029
  var BATCH_SIZE = 100;
2030
2030
  ({
2031
2031
  schema: zod.z.record(zod.z.string(), zod.z.unknown())});
2032
- var emailReconciliationPlugin = chunk4YRYGDCQ_cjs.definePlugin({
2032
+ var emailReconciliationPlugin = chunkKOXFYFOF_cjs.definePlugin({
2033
2033
  id: "email-reconciliation",
2034
2034
  version: "1.0.0",
2035
2035
  description: "Hourly cron that backfills email delivery state from provider status APIs. Only active for providers that implement EmailProvider.reconcile().",
@@ -2050,11 +2050,11 @@ var emailReconciliationPlugin = chunk4YRYGDCQ_cjs.definePlugin({
2050
2050
  console.warn("[email-reconciliation] No DB binding in cron env \u2014 skipping.");
2051
2051
  return;
2052
2052
  }
2053
- if (!chunkSSOP7G4R_cjs.hasEmailService()) {
2053
+ if (!chunkSC2WZFNQ_cjs.hasEmailService()) {
2054
2054
  console.warn("[email-reconciliation] EmailService not initialized \u2014 skipping.");
2055
2055
  return;
2056
2056
  }
2057
- const emailService = chunkSSOP7G4R_cjs.getEmailService();
2057
+ const emailService = chunkSC2WZFNQ_cjs.getEmailService();
2058
2058
  let rows = [];
2059
2059
  try {
2060
2060
  const result = await db.prepare(
@@ -2540,8 +2540,8 @@ function buildOtpApi() {
2540
2540
  loginUrl: settings.loginUrl || "",
2541
2541
  loginButtonText: settings.loginButtonText || ""
2542
2542
  });
2543
- if (chunkSSOP7G4R_cjs.hasEmailService()) {
2544
- const sent = await chunkSSOP7G4R_cjs.getEmailService().send({
2543
+ if (chunkSC2WZFNQ_cjs.hasEmailService()) {
2544
+ const sent = await chunkSC2WZFNQ_cjs.getEmailService().send({
2545
2545
  to: normalizedEmail,
2546
2546
  subject: `Your login code for ${siteName}`,
2547
2547
  flow: "otp",
@@ -2643,21 +2643,21 @@ function buildOtpApi() {
2643
2643
  error: "Account is deactivated"
2644
2644
  }, 403);
2645
2645
  }
2646
- const tokenTtl = await chunkL3KHLEHL_cjs.getJwtExpirySecondsFromDb(db, c.env);
2647
- const token = await chunkL3KHLEHL_cjs.AuthManager.generateToken(user.id, user.email, user.role, c.env.JWT_SECRET, tokenTtl);
2646
+ const tokenTtl = await chunkKMM45BTY_cjs.getJwtExpirySecondsFromDb(db, c.env);
2647
+ const token = await chunkKMM45BTY_cjs.AuthManager.generateToken(user.id, user.email, user.role, c.env.JWT_SECRET, tokenTtl);
2648
2648
  cookie.setCookie(c, "auth_token", token, {
2649
2649
  httpOnly: true,
2650
2650
  secure: true,
2651
2651
  sameSite: "Strict",
2652
2652
  maxAge: tokenTtl
2653
2653
  });
2654
- chunkSSOP7G4R_cjs.dispatchHookEvent(
2654
+ chunkSC2WZFNQ_cjs.dispatchHookEvent(
2655
2655
  c,
2656
2656
  "auth:otp:verified",
2657
2657
  { user: { id: user.id, email: user.email, role: user.role } },
2658
2658
  "fire-and-forget"
2659
2659
  );
2660
- const customData = await chunkSSOP7G4R_cjs.getCustomData(db, user.id);
2660
+ const customData = await chunkSC2WZFNQ_cjs.getCustomData(db, user.id);
2661
2661
  const { is_active: _isActive, ...publicUser } = user;
2662
2662
  return c.json({
2663
2663
  success: true,
@@ -2702,7 +2702,7 @@ function buildOtpApi() {
2702
2702
  });
2703
2703
  return otpAPI;
2704
2704
  }
2705
- var otpLoginPlugin = chunk4YRYGDCQ_cjs.definePlugin({
2705
+ var otpLoginPlugin = chunkKOXFYFOF_cjs.definePlugin({
2706
2706
  id: "otp-login",
2707
2707
  version: "1.0.0",
2708
2708
  name: "OTP Login",
@@ -3099,15 +3099,15 @@ function buildOauthApi() {
3099
3099
  if (!user || !user.is_active) {
3100
3100
  return c.redirect("/auth/login?error=Account is deactivated");
3101
3101
  }
3102
- const tokenTtl2 = await chunkL3KHLEHL_cjs.getJwtExpirySecondsFromDb(c.env.DB, c.env);
3103
- const jwt2 = await chunkL3KHLEHL_cjs.AuthManager.generateToken(
3102
+ const tokenTtl2 = await chunkKMM45BTY_cjs.getJwtExpirySecondsFromDb(c.env.DB, c.env);
3103
+ const jwt2 = await chunkKMM45BTY_cjs.AuthManager.generateToken(
3104
3104
  user.id,
3105
3105
  user.email,
3106
3106
  user.role,
3107
3107
  c.env.JWT_SECRET,
3108
3108
  tokenTtl2
3109
3109
  );
3110
- chunkL3KHLEHL_cjs.AuthManager.setAuthCookie(c, jwt2, { sameSite: "Lax", maxAge: tokenTtl2 });
3110
+ chunkKMM45BTY_cjs.AuthManager.setAuthCookie(c, jwt2, { sameSite: "Lax", maxAge: tokenTtl2 });
3111
3111
  return c.redirect("/admin");
3112
3112
  }
3113
3113
  const existingUser = await oauthService.findUserByEmail(profile.email);
@@ -3124,15 +3124,15 @@ function buildOauthApi() {
3124
3124
  tokenExpiresAt: tokenExpiresAt ?? void 0,
3125
3125
  profileData: JSON.stringify(profile)
3126
3126
  });
3127
- const tokenTtl2 = await chunkL3KHLEHL_cjs.getJwtExpirySecondsFromDb(c.env.DB, c.env);
3128
- const jwt2 = await chunkL3KHLEHL_cjs.AuthManager.generateToken(
3127
+ const tokenTtl2 = await chunkKMM45BTY_cjs.getJwtExpirySecondsFromDb(c.env.DB, c.env);
3128
+ const jwt2 = await chunkKMM45BTY_cjs.AuthManager.generateToken(
3129
3129
  existingUser.id,
3130
3130
  existingUser.email,
3131
3131
  existingUser.role,
3132
3132
  c.env.JWT_SECRET,
3133
3133
  tokenTtl2
3134
3134
  );
3135
- chunkL3KHLEHL_cjs.AuthManager.setAuthCookie(c, jwt2, { sameSite: "Lax", maxAge: tokenTtl2 });
3135
+ chunkKMM45BTY_cjs.AuthManager.setAuthCookie(c, jwt2, { sameSite: "Lax", maxAge: tokenTtl2 });
3136
3136
  return c.redirect("/admin");
3137
3137
  }
3138
3138
  const newUserId = await oauthService.createUserFromOAuth(profile);
@@ -3145,15 +3145,15 @@ function buildOauthApi() {
3145
3145
  tokenExpiresAt: tokenExpiresAt ?? void 0,
3146
3146
  profileData: JSON.stringify(profile)
3147
3147
  });
3148
- const tokenTtl = await chunkL3KHLEHL_cjs.getJwtExpirySecondsFromDb(c.env.DB, c.env);
3149
- const jwt = await chunkL3KHLEHL_cjs.AuthManager.generateToken(
3148
+ const tokenTtl = await chunkKMM45BTY_cjs.getJwtExpirySecondsFromDb(c.env.DB, c.env);
3149
+ const jwt = await chunkKMM45BTY_cjs.AuthManager.generateToken(
3150
3150
  newUserId,
3151
3151
  profile.email.toLowerCase(),
3152
3152
  "viewer",
3153
3153
  c.env.JWT_SECRET,
3154
3154
  tokenTtl
3155
3155
  );
3156
- chunkL3KHLEHL_cjs.AuthManager.setAuthCookie(c, jwt, { sameSite: "Lax", maxAge: tokenTtl });
3156
+ chunkKMM45BTY_cjs.AuthManager.setAuthCookie(c, jwt, { sameSite: "Lax", maxAge: tokenTtl });
3157
3157
  return c.redirect("/admin");
3158
3158
  } catch (error) {
3159
3159
  console.error("OAuth callback error:", error);
@@ -3248,7 +3248,7 @@ function buildOauthApi() {
3248
3248
  });
3249
3249
  return oauthAPI;
3250
3250
  }
3251
- var oauthProvidersPlugin = chunk4YRYGDCQ_cjs.definePlugin({
3251
+ var oauthProvidersPlugin = chunkKOXFYFOF_cjs.definePlugin({
3252
3252
  id: "oauth-providers",
3253
3253
  version: "1.0.0",
3254
3254
  name: "OAuth Providers",
@@ -3825,7 +3825,7 @@ var AISearchService = class {
3825
3825
  */
3826
3826
  async detectNewCollections() {
3827
3827
  try {
3828
- const allCollections = chunkWIV3R2MJ_cjs.getCollectionRegistry().listActive().filter((r) => !r.internal).map((r) => ({
3828
+ const allCollections = chunkKZIBF2EV_cjs.getCollectionRegistry().listActive().filter((r) => !r.internal).map((r) => ({
3829
3829
  id: r.id,
3830
3830
  name: r.name,
3831
3831
  display_name: r.displayName,
@@ -3877,7 +3877,7 @@ var AISearchService = class {
3877
3877
  */
3878
3878
  async getAllCollections() {
3879
3879
  try {
3880
- const allCollections = chunkWIV3R2MJ_cjs.getCollectionRegistry().listActive().filter((r) => !r.internal).sort((a, b) => a.displayName.localeCompare(b.displayName)).map((r) => ({
3880
+ const allCollections = chunkKZIBF2EV_cjs.getCollectionRegistry().listActive().filter((r) => !r.internal).sort((a, b) => a.displayName.localeCompare(b.displayName)).map((r) => ({
3881
3881
  id: r.id,
3882
3882
  name: r.name,
3883
3883
  display_name: r.displayName,
@@ -4213,7 +4213,7 @@ var IndexManager = class {
4213
4213
  */
4214
4214
  async indexCollection(collectionId) {
4215
4215
  try {
4216
- const registry = chunkWIV3R2MJ_cjs.getCollectionRegistry();
4216
+ const registry = chunkKZIBF2EV_cjs.getCollectionRegistry();
4217
4217
  const record = registry.getById(collectionId) ?? registry.getByName(collectionId);
4218
4218
  if (!record) {
4219
4219
  throw new Error(`Collection ${collectionId} not found`);
@@ -4840,7 +4840,7 @@ function renderSettingsPage(data) {
4840
4840
 
4841
4841
  // src/plugins/core-plugins/ai-search-plugin/routes/admin.ts
4842
4842
  var adminRoutes2 = new hono.Hono();
4843
- adminRoutes2.use("*", chunkL3KHLEHL_cjs.requireAuth());
4843
+ adminRoutes2.use("*", chunkKMM45BTY_cjs.requireAuth());
4844
4844
  adminRoutes2.get("/", async (c) => {
4845
4845
  try {
4846
4846
  const user = c.get("user");
@@ -5081,7 +5081,7 @@ var manifest_default = {
5081
5081
  author: "SonicJS"};
5082
5082
 
5083
5083
  // src/plugins/core-plugins/ai-search-plugin/index.ts
5084
- var aiSearchPlugin = chunk4YRYGDCQ_cjs.definePlugin({
5084
+ var aiSearchPlugin = chunkKOXFYFOF_cjs.definePlugin({
5085
5085
  id: manifest_default.id,
5086
5086
  version: manifest_default.version,
5087
5087
  name: manifest_default.name,
@@ -5952,7 +5952,7 @@ function renderSecuritySettingsPage(data) {
5952
5952
 
5953
5953
  // src/plugins/core-plugins/security-audit-plugin/routes/admin.ts
5954
5954
  var adminRoutes3 = new hono.Hono();
5955
- adminRoutes3.use("*", chunkL3KHLEHL_cjs.requireAuth());
5955
+ adminRoutes3.use("*", chunkKMM45BTY_cjs.requireAuth());
5956
5956
  adminRoutes3.use("*", async (c, next) => {
5957
5957
  const user = c.get("user");
5958
5958
  if (user?.role !== "admin") {
@@ -5962,7 +5962,7 @@ adminRoutes3.use("*", async (c, next) => {
5962
5962
  });
5963
5963
  async function getSettings(db) {
5964
5964
  try {
5965
- const pluginService = new chunkWIV3R2MJ_cjs.PluginService(db);
5965
+ const pluginService = new chunkKZIBF2EV_cjs.PluginService(db);
5966
5966
  const plugin2 = await pluginService.getPlugin("security-audit");
5967
5967
  if (plugin2?.settings) {
5968
5968
  const settings = typeof plugin2.settings === "string" ? JSON.parse(plugin2.settings) : plugin2.settings;
@@ -6067,7 +6067,7 @@ adminRoutes3.post("/settings", async (c) => {
6067
6067
  autoPurge: body["retention.autoPurge"] === "true"
6068
6068
  }
6069
6069
  };
6070
- const pluginService = new chunkWIV3R2MJ_cjs.PluginService(db);
6070
+ const pluginService = new chunkKZIBF2EV_cjs.PluginService(db);
6071
6071
  await pluginService.updatePluginSettings("security-audit", settings);
6072
6072
  if (c.req.header("HX-Request")) {
6073
6073
  return c.json({ success: true });
@@ -6228,7 +6228,7 @@ var BruteForceDetector = class {
6228
6228
 
6229
6229
  // src/plugins/core-plugins/security-audit-plugin/routes/api.ts
6230
6230
  var apiRoutes2 = new hono.Hono();
6231
- apiRoutes2.use("*", chunkL3KHLEHL_cjs.requireAuth());
6231
+ apiRoutes2.use("*", chunkKMM45BTY_cjs.requireAuth());
6232
6232
  apiRoutes2.use("*", async (c, next) => {
6233
6233
  const user = c.get("user");
6234
6234
  if (user?.role !== "admin") {
@@ -6238,7 +6238,7 @@ apiRoutes2.use("*", async (c, next) => {
6238
6238
  });
6239
6239
  async function getSettings2(db) {
6240
6240
  try {
6241
- const pluginService = new chunkWIV3R2MJ_cjs.PluginService(db);
6241
+ const pluginService = new chunkKZIBF2EV_cjs.PluginService(db);
6242
6242
  const plugin2 = await pluginService.getPlugin("security-audit");
6243
6243
  if (plugin2?.settings) {
6244
6244
  const settings = typeof plugin2.settings === "string" ? JSON.parse(plugin2.settings) : plugin2.settings;
@@ -6386,7 +6386,7 @@ function generateFingerprint(ip, userAgent) {
6386
6386
  }
6387
6387
  async function getPluginSettings(db) {
6388
6388
  try {
6389
- const pluginService = new chunkWIV3R2MJ_cjs.PluginService(db);
6389
+ const pluginService = new chunkKZIBF2EV_cjs.PluginService(db);
6390
6390
  const plugin2 = await pluginService.getPlugin("security-audit");
6391
6391
  if (plugin2?.settings) {
6392
6392
  const settings = typeof plugin2.settings === "string" ? JSON.parse(plugin2.settings) : plugin2.settings;
@@ -6617,7 +6617,7 @@ async function logAuthEvent(c, db, settings, ip, userAgent, countryCode, fingerp
6617
6617
 
6618
6618
  // src/plugins/core-plugins/security-audit-plugin/index.ts
6619
6619
  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>`;
6620
- var securityAuditPlugin = chunk4YRYGDCQ_cjs.definePlugin({
6620
+ var securityAuditPlugin = chunkKOXFYFOF_cjs.definePlugin({
6621
6621
  id: "security-audit",
6622
6622
  version: "1.0.0",
6623
6623
  name: "Security Audit",
@@ -6635,6 +6635,457 @@ var securityAuditPlugin = chunk4YRYGDCQ_cjs.definePlugin({
6635
6635
  deactivate: async () => console.log("[SecurityAudit] Plugin deactivated")
6636
6636
  });
6637
6637
 
6638
+ // src/plugins/core-plugins/api-keys-plugin/services/api-key-service.ts
6639
+ var API_KEY_QUERYABLE = [
6640
+ { name: "keyHash", kind: "scalar", type: "text", column: "q_apikey_hash" },
6641
+ { name: "userId", kind: "scalar", type: "text", column: "q_apikey_user_id" },
6642
+ { name: "revoked", kind: "scalar", type: "integer", column: "q_apikey_revoked" }
6643
+ ];
6644
+ var KEY_PREFIX = "sk_";
6645
+ var KEY_BYTES = 24;
6646
+ var DISPLAY_PREFIX_LEN = KEY_PREFIX.length + 8;
6647
+ function generateApiKeySecret() {
6648
+ const bytes = new Uint8Array(KEY_BYTES);
6649
+ crypto.getRandomValues(bytes);
6650
+ let hex = "";
6651
+ for (const b of bytes) hex += b.toString(16).padStart(2, "0");
6652
+ return KEY_PREFIX + hex;
6653
+ }
6654
+ async function hashApiKey(secret) {
6655
+ const data = new TextEncoder().encode(secret);
6656
+ const digest = await crypto.subtle.digest("SHA-256", data);
6657
+ const view = new Uint8Array(digest);
6658
+ let hex = "";
6659
+ for (const b of view) hex += b.toString(16).padStart(2, "0");
6660
+ return hex;
6661
+ }
6662
+ var ApiKeyService = class {
6663
+ constructor(db, tenantId = "default") {
6664
+ this.db = db;
6665
+ this.tenantId = tenantId;
6666
+ }
6667
+ docService() {
6668
+ return new chunkW36OZTJ5_cjs.DocumentsService(this.db, {
6669
+ queryableFields: API_KEY_QUERYABLE,
6670
+ tenantId: this.tenantId,
6671
+ maxVersionsPerRoot: 1
6672
+ });
6673
+ }
6674
+ /** Count a user's active (non-revoked) keys — used to enforce the per-user cap. */
6675
+ async countForUser(userId) {
6676
+ const row = await this.db.prepare(
6677
+ `SELECT COUNT(*) AS c FROM documents
6678
+ WHERE type_id = 'api_key' AND tenant_id = ? AND is_current_draft = 1
6679
+ AND deleted_at IS NULL AND q_apikey_user_id = ? AND q_apikey_revoked = 0`
6680
+ ).bind(this.tenantId, userId).first();
6681
+ return row?.c ?? 0;
6682
+ }
6683
+ /**
6684
+ * Mint a new key for a user. The returned `key` is the only time the plaintext
6685
+ * exists outside the caller — it is hashed before storage.
6686
+ */
6687
+ async create(input) {
6688
+ const name = input.name.trim() || "API Key";
6689
+ const secret = generateApiKeySecret();
6690
+ const keyHash = await hashApiKey(secret);
6691
+ const prefix = secret.slice(0, DISPLAY_PREFIX_LEN);
6692
+ const expiresAt = input.expiresAt ?? null;
6693
+ const doc = await this.docService().create(
6694
+ chunkSC2WZFNQ_cjs.createDocumentSchema.parse({
6695
+ typeId: "api_key",
6696
+ tenantId: this.tenantId,
6697
+ title: name,
6698
+ ownerId: input.userId,
6699
+ publishOnCreate: true,
6700
+ data: {
6701
+ name,
6702
+ userId: input.userId,
6703
+ keyHash,
6704
+ keyPrefix: prefix,
6705
+ revoked: 0,
6706
+ lastUsedAt: null,
6707
+ expiresAt
6708
+ }
6709
+ }),
6710
+ input.userId
6711
+ );
6712
+ return { id: doc.rootId, key: secret, name, prefix, expiresAt };
6713
+ }
6714
+ /** List a user's non-revoked keys (metadata only — never the secret or hash). */
6715
+ async list(userId) {
6716
+ const res = await this.db.prepare(
6717
+ `SELECT root_id, data, created_at FROM documents
6718
+ WHERE type_id = 'api_key' AND tenant_id = ? AND is_current_draft = 1
6719
+ AND deleted_at IS NULL AND q_apikey_user_id = ? AND q_apikey_revoked = 0
6720
+ ORDER BY created_at DESC`
6721
+ ).bind(this.tenantId, userId).all();
6722
+ return (res.results ?? []).map((row) => {
6723
+ const d = JSON.parse(row.data);
6724
+ return {
6725
+ id: row.root_id,
6726
+ name: d.name ?? "API Key",
6727
+ prefix: d.keyPrefix ?? "",
6728
+ createdAt: row.created_at,
6729
+ lastUsedAt: d.lastUsedAt ?? null,
6730
+ expiresAt: d.expiresAt ?? null
6731
+ };
6732
+ });
6733
+ }
6734
+ /**
6735
+ * Revoke (hard-delete) a key owned by `userId`. Credentials are erased, not
6736
+ * soft-flagged. Returns false if the key does not exist or is not owned by
6737
+ * the caller (no information leak about other users' keys).
6738
+ */
6739
+ async revoke(rootId, userId) {
6740
+ const row = await this.db.prepare(
6741
+ `SELECT q_apikey_user_id AS owner FROM documents
6742
+ WHERE root_id = ? AND tenant_id = ? AND type_id = 'api_key' AND is_current_draft = 1 AND deleted_at IS NULL`
6743
+ ).bind(rootId, this.tenantId).first();
6744
+ if (!row || row.owner !== userId) return false;
6745
+ await this.docService().erase(rootId, this.tenantId);
6746
+ return true;
6747
+ }
6748
+ /**
6749
+ * Resolve a presented secret to its owning user, or null. Rejects unknown,
6750
+ * revoked, expired keys and inactive users. Best-effort updates lastUsedAt.
6751
+ */
6752
+ async resolve(secret) {
6753
+ if (!secret || !secret.startsWith(KEY_PREFIX)) return null;
6754
+ const keyHash = await hashApiKey(secret);
6755
+ const keyRow2 = await this.db.prepare(
6756
+ `SELECT root_id, data FROM documents
6757
+ WHERE type_id = 'api_key' AND tenant_id = ? AND is_current_draft = 1 AND deleted_at IS NULL
6758
+ AND q_apikey_hash = ? AND q_apikey_revoked = 0
6759
+ LIMIT 1`
6760
+ ).bind(this.tenantId, keyHash).first();
6761
+ if (!keyRow2) return null;
6762
+ const d = JSON.parse(keyRow2.data);
6763
+ if (d.expiresAt != null && Date.now() > Number(d.expiresAt)) return null;
6764
+ const user = await this.db.prepare(`SELECT id, email, role, is_active, is_super_admin FROM auth_user WHERE id = ?`).bind(d.userId).first();
6765
+ if (!user || user.is_active !== 1) return null;
6766
+ try {
6767
+ await this.touchLastUsed(keyRow2.root_id, d);
6768
+ } catch {
6769
+ }
6770
+ return {
6771
+ userId: user.id,
6772
+ email: user.email,
6773
+ role: user.role ?? "viewer",
6774
+ isSuperAdmin: user.is_super_admin === 1
6775
+ };
6776
+ }
6777
+ /** Update lastUsedAt in-place (single-version type, no history churn). */
6778
+ async touchLastUsed(rootId, data) {
6779
+ const next = JSON.stringify({ ...data, lastUsedAt: Date.now() });
6780
+ await this.db.prepare(
6781
+ `UPDATE documents SET data = ? WHERE root_id = ? AND tenant_id = ? AND type_id = 'api_key' AND is_current_draft = 1`
6782
+ ).bind(next, rootId, this.tenantId).run();
6783
+ }
6784
+ };
6785
+
6786
+ // src/plugins/core-plugins/api-keys-plugin/components/keys-page.ts
6787
+ chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
6788
+ function fmtDate(ms) {
6789
+ if (!ms) return "\u2014";
6790
+ try {
6791
+ return new Date(ms).toISOString().slice(0, 10);
6792
+ } catch {
6793
+ return "\u2014";
6794
+ }
6795
+ }
6796
+ function keyRow(k) {
6797
+ const name = chunkMNWKYY5E_cjs.escapeHtml(k.name);
6798
+ const prefix = chunkMNWKYY5E_cjs.escapeHtml(k.prefix);
6799
+ const id = chunkMNWKYY5E_cjs.escapeHtml(k.id);
6800
+ return `
6801
+ <tr class="border-t border-zinc-950/5 dark:border-white/10" data-key-id="${id}">
6802
+ <td class="py-3 pr-4 text-sm font-medium text-zinc-950 dark:text-white">${name}</td>
6803
+ <td class="py-3 pr-4 text-sm font-mono text-zinc-500 dark:text-zinc-400">${prefix}\u2026</td>
6804
+ <td class="py-3 pr-4 text-sm text-zinc-500 dark:text-zinc-400">${fmtDate(k.createdAt ? k.createdAt * 1e3 : null)}</td>
6805
+ <td class="py-3 pr-4 text-sm text-zinc-500 dark:text-zinc-400">${k.lastUsedAt ? fmtDate(k.lastUsedAt) : "Never"}</td>
6806
+ <td class="py-3 pr-4 text-sm text-zinc-500 dark:text-zinc-400">${k.expiresAt ? fmtDate(k.expiresAt) : "Never"}</td>
6807
+ <td class="py-3 text-right">
6808
+ <button type="button" onclick="revokeApiKey('${id}', '${name.replace(/'/g, "\\'")}')"
6809
+ 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">
6810
+ Revoke
6811
+ </button>
6812
+ </td>
6813
+ </tr>`;
6814
+ }
6815
+ function renderApiKeysPage(data) {
6816
+ const { keys, user, version, dynamicMenuItems } = data;
6817
+ 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>`;
6818
+ const content2 = `
6819
+ <div>
6820
+ <div class="sm:flex sm:items-center sm:justify-between mb-6">
6821
+ <div class="sm:flex-auto">
6822
+ <h1 class="text-2xl/8 font-semibold text-zinc-950 dark:text-white sm:text-xl/8">API Keys</h1>
6823
+ <p class="mt-2 text-sm/6 text-zinc-500 dark:text-zinc-400">
6824
+ Long-lived secrets for headless / server-to-server REST access. Send a key as the
6825
+ <code class="font-mono">x-api-key</code> header or <code class="font-mono">Authorization: Bearer &lt;key&gt;</code>.
6826
+ The secret is shown once at creation \u2014 store it now.
6827
+ </p>
6828
+ </div>
6829
+ <div class="mt-4 sm:mt-0 sm:ml-16">
6830
+ <button type="button" onclick="document.getElementById('create-key-modal').classList.remove('hidden')"
6831
+ 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">
6832
+ Create API key
6833
+ </button>
6834
+ </div>
6835
+ </div>
6836
+
6837
+ <!-- Newly-created secret banner (populated by JS, shown once) -->
6838
+ <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">
6839
+ <p class="text-sm font-medium text-emerald-800 dark:text-emerald-300 mb-2">
6840
+ Copy your new key now \u2014 it will not be shown again.
6841
+ </p>
6842
+ <div class="flex items-center gap-2">
6843
+ <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>
6844
+ <button type="button" onclick="copyNewKey()"
6845
+ class="rounded-lg bg-emerald-600 px-3 py-2 text-sm font-semibold text-white hover:bg-emerald-500 transition-colors">
6846
+ Copy
6847
+ </button>
6848
+ </div>
6849
+ </div>
6850
+
6851
+ <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">
6852
+ <table class="w-full text-left">
6853
+ <thead>
6854
+ <tr class="text-xs font-semibold uppercase tracking-wide text-zinc-500 dark:text-zinc-400">
6855
+ <th class="pb-2 pr-4">Name</th>
6856
+ <th class="pb-2 pr-4">Prefix</th>
6857
+ <th class="pb-2 pr-4">Created</th>
6858
+ <th class="pb-2 pr-4">Last used</th>
6859
+ <th class="pb-2 pr-4">Expires</th>
6860
+ <th class="pb-2 text-right">Actions</th>
6861
+ </tr>
6862
+ </thead>
6863
+ <tbody id="keys-tbody">${rows}</tbody>
6864
+ </table>
6865
+ </div>
6866
+ </div>
6867
+
6868
+ <!-- Create modal -->
6869
+ <div id="create-key-modal" class="hidden fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4">
6870
+ <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">
6871
+ <h2 class="text-base font-semibold text-zinc-950 dark:text-white mb-4">Create API key</h2>
6872
+ <label class="block text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-1">Name</label>
6873
+ <input id="new-key-name" type="text" placeholder="e.g. CI deploy token"
6874
+ 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">
6875
+ <label class="block text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-1">Expires in (days, optional)</label>
6876
+ <input id="new-key-expiry" type="number" min="1" max="3650" placeholder="Never"
6877
+ 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">
6878
+ <div class="flex justify-end gap-2">
6879
+ <button type="button" onclick="document.getElementById('create-key-modal').classList.add('hidden')"
6880
+ 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">
6881
+ Cancel
6882
+ </button>
6883
+ <button type="button" onclick="createApiKey()"
6884
+ class="rounded-lg bg-cyan-600 px-4 py-2 text-sm font-semibold text-white hover:bg-cyan-500 transition-colors">
6885
+ Create
6886
+ </button>
6887
+ </div>
6888
+ </div>
6889
+ </div>
6890
+
6891
+ <script>
6892
+ // CSRF: the csrf_token cookie is JS-readable (httpOnly:false); echo it back
6893
+ // as X-CSRF-Token on state-changing requests (signed double-submit).
6894
+ function csrfHeader() {
6895
+ const m = document.cookie.match(/(?:^|; )csrf_token=([^;]+)/)
6896
+ return m ? { 'X-CSRF-Token': decodeURIComponent(m[1]) } : {}
6897
+ }
6898
+ async function createApiKey() {
6899
+ const name = document.getElementById('new-key-name').value.trim()
6900
+ if (!name) { window.showNotification && window.showNotification('Name is required', 'error'); return }
6901
+ const expiry = parseInt(document.getElementById('new-key-expiry').value, 10)
6902
+ const body = { name }
6903
+ if (Number.isFinite(expiry) && expiry > 0) body.expiresInDays = expiry
6904
+ const res = await fetch('/admin/plugins/api-keys/api/keys', {
6905
+ method: 'POST',
6906
+ headers: { 'Content-Type': 'application/json', ...csrfHeader() },
6907
+ body: JSON.stringify(body),
6908
+ })
6909
+ if (!res.ok) {
6910
+ const e = await res.json().catch(() => ({}))
6911
+ window.showNotification && window.showNotification(e.error || 'Failed to create key', 'error')
6912
+ return
6913
+ }
6914
+ const { apiKey } = await res.json()
6915
+ document.getElementById('create-key-modal').classList.add('hidden')
6916
+ document.getElementById('new-key-value').textContent = apiKey.key
6917
+ document.getElementById('new-key-banner').classList.remove('hidden')
6918
+ setTimeout(() => location.reload(), 1500)
6919
+ }
6920
+ function copyNewKey() {
6921
+ const v = document.getElementById('new-key-value').textContent
6922
+ navigator.clipboard.writeText(v).then(() => window.showNotification && window.showNotification('Copied', 'success'))
6923
+ }
6924
+ async function revokeApiKey(id, name) {
6925
+ if (!confirm('Revoke "' + name + '"? This cannot be undone and will break any client using it.')) return
6926
+ const res = await fetch('/admin/plugins/api-keys/api/keys/' + id, { method: 'DELETE', headers: { ...csrfHeader() } })
6927
+ if (res.ok) {
6928
+ const row = document.querySelector('[data-key-id="' + id + '"]')
6929
+ if (row) row.remove()
6930
+ window.showNotification && window.showNotification('Key revoked', 'success')
6931
+ } else {
6932
+ window.showNotification && window.showNotification('Failed to revoke', 'error')
6933
+ }
6934
+ }
6935
+ </script>`;
6936
+ const layoutData = {
6937
+ title: "API Keys",
6938
+ pageTitle: "API Keys",
6939
+ currentPath: "/admin/plugins/api-keys",
6940
+ user,
6941
+ content: content2,
6942
+ version,
6943
+ dynamicMenuItems
6944
+ };
6945
+ return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
6946
+ }
6947
+
6948
+ // src/plugins/core-plugins/api-keys-plugin/types.ts
6949
+ var DEFAULT_SETTINGS3 = {
6950
+ maxKeysPerUser: 50,
6951
+ defaultExpiryDays: 0
6952
+ };
6953
+
6954
+ // src/plugins/core-plugins/api-keys-plugin/routes/admin.ts
6955
+ var adminRoutes4 = new hono.Hono();
6956
+ var DAY_MS = 24 * 60 * 60 * 1e3;
6957
+ var createSchema = zod.z.object({
6958
+ name: zod.z.string().min(1).max(100),
6959
+ // Optional lifetime in days; omitted/null → plugin default (which may be "never").
6960
+ expiresInDays: zod.z.number().int().positive().max(3650).nullish()
6961
+ });
6962
+ async function getSettings3(db) {
6963
+ try {
6964
+ const plugin2 = await new chunkKZIBF2EV_cjs.PluginService(db).getPlugin("api-keys");
6965
+ if (plugin2?.settings) {
6966
+ const s = typeof plugin2.settings === "string" ? JSON.parse(plugin2.settings) : plugin2.settings;
6967
+ return { ...DEFAULT_SETTINGS3, ...s };
6968
+ }
6969
+ } catch {
6970
+ }
6971
+ return DEFAULT_SETTINGS3;
6972
+ }
6973
+ adminRoutes4.use("*", chunkKMM45BTY_cjs.requireAuth());
6974
+ adminRoutes4.use("*", async (c, next) => {
6975
+ const user = c.get("user");
6976
+ if (user?.role !== "admin") {
6977
+ return c.json({ error: "Access denied" }, 403);
6978
+ }
6979
+ return next();
6980
+ });
6981
+ adminRoutes4.get("/", async (c) => {
6982
+ const user = c.get("user");
6983
+ const tenantId = c.get("tenantId") || "default";
6984
+ const keys = await new ApiKeyService(c.env.DB, tenantId).list(user.userId);
6985
+ return c.html(
6986
+ renderApiKeysPage({
6987
+ keys,
6988
+ user: { name: user.email, email: user.email, role: user.role },
6989
+ version: c.get("appVersion"),
6990
+ dynamicMenuItems: c.get("pluginMenuItems")
6991
+ })
6992
+ );
6993
+ });
6994
+ adminRoutes4.get("/api/keys", async (c) => {
6995
+ const user = c.get("user");
6996
+ const tenantId = c.get("tenantId") || "default";
6997
+ const keys = await new ApiKeyService(c.env.DB, tenantId).list(user.userId);
6998
+ return c.json({ keys });
6999
+ });
7000
+ adminRoutes4.post("/api/keys", async (c) => {
7001
+ const user = c.get("user");
7002
+ const tenantId = c.get("tenantId") || "default";
7003
+ const body = await c.req.json().catch(() => ({}));
7004
+ const parsed = createSchema.safeParse(body);
7005
+ if (!parsed.success) {
7006
+ return c.json({ error: "Invalid request", details: parsed.error.flatten() }, 400);
7007
+ }
7008
+ const settings = await getSettings3(c.env.DB);
7009
+ const svc = new ApiKeyService(c.env.DB, tenantId);
7010
+ if (await svc.countForUser(user.userId) >= settings.maxKeysPerUser) {
7011
+ return c.json({ error: `API key limit reached (max ${settings.maxKeysPerUser})` }, 409);
7012
+ }
7013
+ const days = parsed.data.expiresInDays ?? (settings.defaultExpiryDays > 0 ? settings.defaultExpiryDays : null);
7014
+ const expiresAt = days ? Date.now() + days * DAY_MS : null;
7015
+ const created = await svc.create({ userId: user.userId, name: parsed.data.name, expiresAt });
7016
+ return c.json({ apiKey: created }, 201);
7017
+ });
7018
+ adminRoutes4.delete("/api/keys/:id", async (c) => {
7019
+ const user = c.get("user");
7020
+ const tenantId = c.get("tenantId") || "default";
7021
+ const ok = await new ApiKeyService(c.env.DB, tenantId).revoke(c.req.param("id") ?? "", user.userId);
7022
+ if (!ok) return c.json({ error: "API key not found" }, 404);
7023
+ return c.json({ success: true });
7024
+ });
7025
+
7026
+ // src/plugins/core-plugins/api-keys-plugin/middleware/api-key-auth.ts
7027
+ function apiKeyAuthMiddleware() {
7028
+ return async (c, next) => {
7029
+ if (!c.get("user")) {
7030
+ const authz = c.req.header("authorization") || "";
7031
+ const bearer = authz.toLowerCase().startsWith("bearer ") ? authz.slice(7).trim() : "";
7032
+ const presented = c.req.header("x-api-key") || (bearer.startsWith("sk_") ? bearer : "");
7033
+ if (presented) {
7034
+ try {
7035
+ const tenantId = c.get("tenantId") || "default";
7036
+ const resolved = await new ApiKeyService(c.env.DB, tenantId).resolve(presented);
7037
+ if (resolved) {
7038
+ c.set("user", {
7039
+ userId: resolved.userId,
7040
+ email: resolved.email,
7041
+ role: resolved.role,
7042
+ isSuperAdmin: resolved.isSuperAdmin,
7043
+ // API keys are stateless bearer creds — no session window.
7044
+ exp: 0,
7045
+ iat: 0
7046
+ });
7047
+ }
7048
+ } catch {
7049
+ }
7050
+ }
7051
+ }
7052
+ await next();
7053
+ };
7054
+ }
7055
+
7056
+ // src/plugins/core-plugins/api-keys-plugin/index.ts
7057
+ 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>`;
7058
+ var apiKeysPlugin = chunkKOXFYFOF_cjs.definePlugin({
7059
+ id: "api-keys",
7060
+ version: "1.0.0-beta.1",
7061
+ name: "API Keys",
7062
+ description: "Programmatic API access keys for headless / server-to-server REST access.",
7063
+ sonicjsVersionRange: "^3.0.0",
7064
+ author: { name: "SonicJS Team" },
7065
+ register(app2) {
7066
+ app2.route("/admin/plugins/api-keys", adminRoutes4);
7067
+ },
7068
+ menu: [
7069
+ { label: "API Keys", path: "/admin/plugins/api-keys", icon: KEY_ICON, order: 86 }
7070
+ ],
7071
+ configSchema: {
7072
+ maxKeysPerUser: {
7073
+ type: "number",
7074
+ label: "Max keys per user",
7075
+ description: "Hard cap on active keys a single user may hold.",
7076
+ default: 50
7077
+ },
7078
+ defaultExpiryDays: {
7079
+ type: "number",
7080
+ label: "Default expiry (days)",
7081
+ description: "Lifetime applied to new keys when no explicit expiry is given. 0 = never expires.",
7082
+ default: 0
7083
+ }
7084
+ },
7085
+ activate: async () => console.log("[ApiKeys] Plugin activated"),
7086
+ deactivate: async () => console.log("[ApiKeys] Plugin deactivated")
7087
+ });
7088
+
6638
7089
  // src/plugins/core-plugins/stripe-plugin/services/subscription-service.ts
6639
7090
  var SubscriptionService = class {
6640
7091
  constructor(db) {
@@ -7362,7 +7813,7 @@ function renderEventPagination(page, totalPages, type, status) {
7362
7813
  }
7363
7814
 
7364
7815
  // src/plugins/core-plugins/stripe-plugin/types.ts
7365
- var DEFAULT_SETTINGS3 = {
7816
+ var DEFAULT_SETTINGS4 = {
7366
7817
  stripePublishableKey: "",
7367
7818
  stripeSecretKey: "",
7368
7819
  stripeWebhookSecret: "",
@@ -7372,28 +7823,28 @@ var DEFAULT_SETTINGS3 = {
7372
7823
  };
7373
7824
 
7374
7825
  // src/plugins/core-plugins/stripe-plugin/routes/admin.ts
7375
- var adminRoutes4 = new hono.Hono();
7376
- adminRoutes4.use("*", chunkL3KHLEHL_cjs.requireAuth());
7377
- adminRoutes4.use("*", async (c, next) => {
7826
+ var adminRoutes5 = new hono.Hono();
7827
+ adminRoutes5.use("*", chunkKMM45BTY_cjs.requireAuth());
7828
+ adminRoutes5.use("*", async (c, next) => {
7378
7829
  const user = c.get("user");
7379
7830
  if (user?.role !== "admin") {
7380
7831
  return c.text("Access denied", 403);
7381
7832
  }
7382
7833
  return next();
7383
7834
  });
7384
- async function getSettings3(db) {
7835
+ async function getSettings4(db) {
7385
7836
  try {
7386
- const pluginService = new chunkWIV3R2MJ_cjs.PluginService(db);
7837
+ const pluginService = new chunkKZIBF2EV_cjs.PluginService(db);
7387
7838
  const plugin2 = await pluginService.getPlugin("stripe");
7388
7839
  if (plugin2?.settings) {
7389
7840
  const settings = typeof plugin2.settings === "string" ? JSON.parse(plugin2.settings) : plugin2.settings;
7390
- return { ...DEFAULT_SETTINGS3, ...settings };
7841
+ return { ...DEFAULT_SETTINGS4, ...settings };
7391
7842
  }
7392
7843
  } catch {
7393
7844
  }
7394
- return DEFAULT_SETTINGS3;
7845
+ return DEFAULT_SETTINGS4;
7395
7846
  }
7396
- adminRoutes4.get("/", async (c) => {
7847
+ adminRoutes5.get("/", async (c) => {
7397
7848
  const db = c.env.DB;
7398
7849
  const user = c.get("user");
7399
7850
  const subscriptionService = new SubscriptionService(db);
@@ -7416,7 +7867,7 @@ adminRoutes4.get("/", async (c) => {
7416
7867
  });
7417
7868
  return c.html(html4);
7418
7869
  });
7419
- adminRoutes4.get("/events", async (c) => {
7870
+ adminRoutes5.get("/events", async (c) => {
7420
7871
  const db = c.env.DB;
7421
7872
  const user = c.get("user");
7422
7873
  const eventService = new StripeEventService(db);
@@ -7442,10 +7893,10 @@ adminRoutes4.get("/events", async (c) => {
7442
7893
  });
7443
7894
  return c.html(html4);
7444
7895
  });
7445
- adminRoutes4.get("/settings", async (c) => {
7896
+ adminRoutes5.get("/settings", async (c) => {
7446
7897
  const db = c.env.DB;
7447
7898
  const user = c.get("user");
7448
- const settings = await getSettings3(db);
7899
+ const settings = await getSettings4(db);
7449
7900
  const { renderAdminLayoutCatalyst: renderAdminLayoutCatalyst2 } = await import('./admin-layout-catalyst.template-KDHKVLXR.cjs');
7450
7901
  const content2 = `
7451
7902
  <div>
@@ -7552,7 +8003,7 @@ adminRoutes4.get("/settings", async (c) => {
7552
8003
  dynamicMenuItems: c.get("pluginMenuItems")
7553
8004
  }));
7554
8005
  });
7555
- adminRoutes4.post("/settings", async (c) => {
8006
+ adminRoutes5.post("/settings", async (c) => {
7556
8007
  try {
7557
8008
  const body = await c.req.json();
7558
8009
  const db = c.env.DB;
@@ -7703,17 +8154,17 @@ function timingSafeEqual(a, b) {
7703
8154
 
7704
8155
  // src/plugins/core-plugins/stripe-plugin/routes/api.ts
7705
8156
  var apiRoutes3 = new hono.Hono();
7706
- async function getSettings4(db) {
8157
+ async function getSettings5(db) {
7707
8158
  try {
7708
- const pluginService = new chunkWIV3R2MJ_cjs.PluginService(db);
8159
+ const pluginService = new chunkKZIBF2EV_cjs.PluginService(db);
7709
8160
  const plugin2 = await pluginService.getPlugin("stripe");
7710
8161
  if (plugin2?.settings) {
7711
8162
  const settings = typeof plugin2.settings === "string" ? JSON.parse(plugin2.settings) : plugin2.settings;
7712
- return { ...DEFAULT_SETTINGS3, ...settings };
8163
+ return { ...DEFAULT_SETTINGS4, ...settings };
7713
8164
  }
7714
8165
  } catch {
7715
8166
  }
7716
- return DEFAULT_SETTINGS3;
8167
+ return DEFAULT_SETTINGS4;
7717
8168
  }
7718
8169
  function mapStripeStatus(status) {
7719
8170
  const map = {
@@ -7730,7 +8181,7 @@ function mapStripeStatus(status) {
7730
8181
  }
7731
8182
  apiRoutes3.post("/webhook", async (c) => {
7732
8183
  const db = c.env.DB;
7733
- const settings = await getSettings4(db);
8184
+ const settings = await getSettings5(db);
7734
8185
  if (!settings.stripeWebhookSecret) {
7735
8186
  return c.json({ error: "Webhook secret not configured" }, 500);
7736
8187
  }
@@ -7856,11 +8307,11 @@ apiRoutes3.post("/webhook", async (c) => {
7856
8307
  }
7857
8308
  return c.json({ received: true });
7858
8309
  });
7859
- apiRoutes3.post("/create-checkout-session", chunkL3KHLEHL_cjs.requireAuth(), async (c) => {
8310
+ apiRoutes3.post("/create-checkout-session", chunkKMM45BTY_cjs.requireAuth(), async (c) => {
7860
8311
  const db = c.env.DB;
7861
8312
  const user = c.get("user");
7862
8313
  if (!user) return c.json({ error: "Unauthorized" }, 401);
7863
- const settings = await getSettings4(db);
8314
+ const settings = await getSettings5(db);
7864
8315
  if (!settings.stripeSecretKey) {
7865
8316
  return c.json({ error: "Stripe not configured" }, 500);
7866
8317
  }
@@ -7896,7 +8347,7 @@ apiRoutes3.post("/create-checkout-session", chunkL3KHLEHL_cjs.requireAuth(), asy
7896
8347
  });
7897
8348
  return c.json({ sessionId: session.id, url: session.url });
7898
8349
  });
7899
- apiRoutes3.get("/subscription", chunkL3KHLEHL_cjs.requireAuth(), async (c) => {
8350
+ apiRoutes3.get("/subscription", chunkKMM45BTY_cjs.requireAuth(), async (c) => {
7900
8351
  const user = c.get("user");
7901
8352
  if (!user) return c.json({ error: "Unauthorized" }, 401);
7902
8353
  const db = c.env.DB;
@@ -7908,7 +8359,7 @@ apiRoutes3.get("/subscription", chunkL3KHLEHL_cjs.requireAuth(), async (c) => {
7908
8359
  }
7909
8360
  return c.json({ subscription });
7910
8361
  });
7911
- apiRoutes3.get("/subscriptions", chunkL3KHLEHL_cjs.requireAuth(), async (c) => {
8362
+ apiRoutes3.get("/subscriptions", chunkKMM45BTY_cjs.requireAuth(), async (c) => {
7912
8363
  const user = c.get("user");
7913
8364
  if (user?.role !== "admin") return c.json({ error: "Access denied" }, 403);
7914
8365
  const db = c.env.DB;
@@ -7924,7 +8375,7 @@ apiRoutes3.get("/subscriptions", chunkL3KHLEHL_cjs.requireAuth(), async (c) => {
7924
8375
  const result = await subscriptionService.list(filters);
7925
8376
  return c.json(result);
7926
8377
  });
7927
- apiRoutes3.get("/stats", chunkL3KHLEHL_cjs.requireAuth(), async (c) => {
8378
+ apiRoutes3.get("/stats", chunkKMM45BTY_cjs.requireAuth(), async (c) => {
7928
8379
  const user = c.get("user");
7929
8380
  if (user?.role !== "admin") return c.json({ error: "Access denied" }, 403);
7930
8381
  const db = c.env.DB;
@@ -7933,11 +8384,11 @@ apiRoutes3.get("/stats", chunkL3KHLEHL_cjs.requireAuth(), async (c) => {
7933
8384
  const stats = await subscriptionService.getStats();
7934
8385
  return c.json(stats);
7935
8386
  });
7936
- apiRoutes3.post("/sync-subscriptions", chunkL3KHLEHL_cjs.requireAuth(), async (c) => {
8387
+ apiRoutes3.post("/sync-subscriptions", chunkKMM45BTY_cjs.requireAuth(), async (c) => {
7937
8388
  const user = c.get("user");
7938
8389
  if (user?.role !== "admin") return c.json({ error: "Access denied" }, 403);
7939
8390
  const db = c.env.DB;
7940
- const settings = await getSettings4(db);
8391
+ const settings = await getSettings5(db);
7941
8392
  if (!settings.stripeSecretKey) {
7942
8393
  return c.json({ error: "Stripe secret key not configured" }, 400);
7943
8394
  }
@@ -7981,7 +8432,7 @@ apiRoutes3.post("/sync-subscriptions", chunkL3KHLEHL_cjs.requireAuth(), async (c
7981
8432
  }, 500);
7982
8433
  }
7983
8434
  });
7984
- apiRoutes3.get("/events", chunkL3KHLEHL_cjs.requireAuth(), async (c) => {
8435
+ apiRoutes3.get("/events", chunkKMM45BTY_cjs.requireAuth(), async (c) => {
7985
8436
  const user = c.get("user");
7986
8437
  if (user?.role !== "admin") return c.json({ error: "Access denied" }, 403);
7987
8438
  const db = c.env.DB;
@@ -8004,7 +8455,7 @@ apiRoutes3.get("/events", chunkL3KHLEHL_cjs.requireAuth(), async (c) => {
8004
8455
 
8005
8456
  // src/plugins/core-plugins/stripe-plugin/index.ts
8006
8457
  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>`;
8007
- var stripePlugin = chunk4YRYGDCQ_cjs.definePlugin({
8458
+ var stripePlugin = chunkKOXFYFOF_cjs.definePlugin({
8008
8459
  id: "stripe",
8009
8460
  version: "1.0.0",
8010
8461
  name: "Stripe",
@@ -8012,7 +8463,7 @@ var stripePlugin = chunk4YRYGDCQ_cjs.definePlugin({
8012
8463
  sonicjsVersionRange: "^3.0.0",
8013
8464
  author: { name: "SonicJS Team" },
8014
8465
  register(app2) {
8015
- app2.route("/admin/plugins/stripe", adminRoutes4);
8466
+ app2.route("/admin/plugins/stripe", adminRoutes5);
8016
8467
  app2.route("/api/stripe", apiRoutes3);
8017
8468
  },
8018
8469
  menu: [
@@ -8277,7 +8728,7 @@ function renderFormsListPage(data) {
8277
8728
 
8278
8729
  <!-- Forms Table -->
8279
8730
  <div class="bg-white dark:bg-zinc-900 rounded-lg border border-zinc-950/5 dark:border-white/10 overflow-hidden">
8280
- ${chunkSSOP7G4R_cjs.renderTable(tableData)}
8731
+ ${chunkSC2WZFNQ_cjs.renderTable(tableData)}
8281
8732
  </div>
8282
8733
  </div>
8283
8734
  `;
@@ -9707,7 +10158,7 @@ function renderFormCreatePage(data) {
9707
10158
  // src/routes/admin-forms.ts
9708
10159
  var isTableMissing = (err) => String(err?.message ?? err?.cause?.message ?? "").includes("no such table: forms");
9709
10160
  var adminFormsRoutes = new hono.Hono();
9710
- adminFormsRoutes.use("*", chunkL3KHLEHL_cjs.requireAuth());
10161
+ adminFormsRoutes.use("*", chunkKMM45BTY_cjs.requireAuth());
9711
10162
  adminFormsRoutes.get("/", async (c) => {
9712
10163
  try {
9713
10164
  const user = c.get("user");
@@ -9880,7 +10331,7 @@ adminFormsRoutes.get("/:id/builder", async (c) => {
9880
10331
  if (!form) {
9881
10332
  return c.html("<p>Form not found</p>", 404);
9882
10333
  }
9883
- const turnstileService = new chunkG5LC7MYH_cjs.TurnstileService(db);
10334
+ const turnstileService = new chunkLXYDJU6U_cjs.TurnstileService(db);
9884
10335
  const turnstileSettings = await turnstileService.getSettings();
9885
10336
  const pageData = {
9886
10337
  id: form.id,
@@ -10049,7 +10500,7 @@ publicFormsRoutes.get("/:identifier/turnstile-config", async (c) => {
10049
10500
  if (!form) {
10050
10501
  return c.json({ error: "Form not found" }, 404);
10051
10502
  }
10052
- const turnstileService = new chunkG5LC7MYH_cjs.TurnstileService(db);
10503
+ const turnstileService = new chunkLXYDJU6U_cjs.TurnstileService(db);
10053
10504
  const globalSettings = await turnstileService.getSettings();
10054
10505
  const formSettings = form.turnstile_settings ? JSON.parse(form.turnstile_settings) : { inherit: true };
10055
10506
  const enabled = form.turnstile_enabled === 1 || formSettings.inherit && globalSettings?.enabled;
@@ -10479,7 +10930,7 @@ publicFormsRoutes.post("/:identifier/submit", async (c) => {
10479
10930
  const turnstileEnabled = form.turnstile_enabled === 1;
10480
10931
  const turnstileSettings = form.turnstile_settings ? JSON.parse(form.turnstile_settings) : { inherit: true };
10481
10932
  if (turnstileEnabled || turnstileSettings.inherit) {
10482
- const turnstileService = new chunkG5LC7MYH_cjs.TurnstileService(db);
10933
+ const turnstileService = new chunkLXYDJU6U_cjs.TurnstileService(db);
10483
10934
  const globalEnabled = await turnstileService.isEnabled();
10484
10935
  if (globalEnabled || turnstileEnabled) {
10485
10936
  const turnstileToken = body.data?.turnstile || body.turnstile;
@@ -10541,7 +10992,7 @@ publicFormsRoutes.post("/:identifier/submit", async (c) => {
10541
10992
  });
10542
10993
 
10543
10994
  // src/plugins/core-plugins/forms-plugin/index.ts
10544
- var formsPlugin = chunk4YRYGDCQ_cjs.definePlugin({
10995
+ var formsPlugin = chunkKOXFYFOF_cjs.definePlugin({
10545
10996
  id: "forms",
10546
10997
  version: "1.0.0",
10547
10998
  name: "Forms",
@@ -10561,7 +11012,7 @@ var formsPlugin = chunk4YRYGDCQ_cjs.definePlugin({
10561
11012
  });
10562
11013
  chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
10563
11014
  var adminRbacRoutes = new hono.Hono();
10564
- adminRbacRoutes.use("*", chunkL3KHLEHL_cjs.requireRbac("rbac", "manage"));
11015
+ adminRbacRoutes.use("*", chunkKMM45BTY_cjs.requireRbac("rbac", "manage"));
10565
11016
  var esc = (s) => String(s).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
10566
11017
  var TABS2 = `
10567
11018
  <div class="border-b border-zinc-950/10 dark:border-white/10 mb-6">
@@ -10869,7 +11320,7 @@ adminRbacRoutes.get("/", async (c) => {
10869
11320
  title: "Roles & Permissions",
10870
11321
  pageTitle: "Roles & Permissions",
10871
11322
  currentPath: "/admin/users",
10872
- version: chunkSIPBHWMG_cjs.getCoreVersion(),
11323
+ version: chunk3XFA3E2F_cjs.getCoreVersion(),
10873
11324
  user: u ? { name: u.email || "Admin", email: u.email || "", role: u.role || "admin" } : void 0,
10874
11325
  content: content2
10875
11326
  })
@@ -11006,7 +11457,7 @@ adminRbacRoutes.get("/check", async (c) => {
11006
11457
  });
11007
11458
 
11008
11459
  // src/middleware/plugin-menu.ts
11009
- var REGISTRY_MENU_PLUGINS = Object.values(chunkWIV3R2MJ_cjs.PLUGIN_REGISTRY).filter((p) => p.adminMenu !== null).map((p) => ({
11460
+ var REGISTRY_MENU_PLUGINS = Object.values(chunkKZIBF2EV_cjs.PLUGIN_REGISTRY).filter((p) => p.adminMenu !== null).map((p) => ({
11010
11461
  id: p.id,
11011
11462
  label: p.adminMenu.label,
11012
11463
  path: p.adminMenu.path,
@@ -11084,7 +11535,16 @@ function pluginMenuMiddleware() {
11084
11535
  }
11085
11536
  } catch {
11086
11537
  }
11087
- c.set("pluginMenuItems", activeMenuItems.map((m) => ({ label: m.label, path: m.path, icon: resolveIcon(m.icon) || "" })));
11538
+ const user = c.get("user");
11539
+ const singletonItems = chunkLXYDJU6U_cjs.resolvePluginMenuItems(user ? { role: user.role } : void 0);
11540
+ const existingPaths = new Set(activeMenuItems.map((i) => i.path));
11541
+ for (const item of singletonItems) {
11542
+ if (!existingPaths.has(item.path)) {
11543
+ activeMenuItems.push({ label: item.label, path: item.path, icon: item.icon, order: item.order });
11544
+ }
11545
+ }
11546
+ activeMenuItems.sort((a, b) => a.order - b.order);
11547
+ c.set("pluginMenuItems", activeMenuItems.map((m) => ({ label: m.label, path: m.path, icon: resolveIcon(m.icon) || m.icon || "" })));
11088
11548
  await next();
11089
11549
  const finalItems = c.get("pluginMenuItems") ?? [];
11090
11550
  if (finalItems.length > 0 && c.res.headers.get("content-type")?.includes("text/html")) {
@@ -11102,16 +11562,16 @@ function pluginMenuMiddleware() {
11102
11562
  };
11103
11563
  }
11104
11564
  chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
11105
- var adminRoutes5 = new hono.Hono();
11106
- adminRoutes5.use("*", chunkL3KHLEHL_cjs.requireAuth());
11107
- adminRoutes5.use("*", async (c, next) => {
11565
+ var adminRoutes6 = new hono.Hono();
11566
+ adminRoutes6.use("*", chunkKMM45BTY_cjs.requireAuth());
11567
+ adminRoutes6.use("*", async (c, next) => {
11108
11568
  const user = c.get("user");
11109
11569
  if (user?.role !== "admin") {
11110
11570
  return c.text("Access denied", 403);
11111
11571
  }
11112
11572
  return next();
11113
11573
  });
11114
- adminRoutes5.get("/", async (c) => {
11574
+ adminRoutes6.get("/", async (c) => {
11115
11575
  const user = c.get("user");
11116
11576
  const db = c.env.DB;
11117
11577
  let totalRequests = 0;
@@ -11458,7 +11918,7 @@ apiRoutes4.get("/stats", async (c) => {
11458
11918
  });
11459
11919
 
11460
11920
  // src/plugins/core-plugins/analytics/index.ts
11461
- var analyticsPlugin = chunk4YRYGDCQ_cjs.definePlugin({
11921
+ var analyticsPlugin = chunkKOXFYFOF_cjs.definePlugin({
11462
11922
  id: "core-analytics",
11463
11923
  version: "1.0.0",
11464
11924
  name: "Analytics",
@@ -11467,7 +11927,7 @@ var analyticsPlugin = chunk4YRYGDCQ_cjs.definePlugin({
11467
11927
  author: { name: "SonicJS Team", email: "team@sonicjs.com" },
11468
11928
  register(app2) {
11469
11929
  app2.route("/api/events", apiRoutes4);
11470
- app2.route("/admin/analytics", adminRoutes5);
11930
+ app2.route("/admin/analytics", adminRoutes6);
11471
11931
  },
11472
11932
  menu: [
11473
11933
  {
@@ -11605,7 +12065,7 @@ function esc2(s) {
11605
12065
  return (s || "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
11606
12066
  }
11607
12067
  async function getVariablesMap(db) {
11608
- let variables = chunkSSOP7G4R_cjs.getVariablesCached();
12068
+ let variables = chunkSC2WZFNQ_cjs.getVariablesCached();
11609
12069
  if (variables) return variables;
11610
12070
  try {
11611
12071
  const { results } = await db.prepare(
@@ -11615,7 +12075,7 @@ async function getVariablesMap(db) {
11615
12075
  for (const row of results || []) {
11616
12076
  variables.set(row.key, row.value);
11617
12077
  }
11618
- chunkSSOP7G4R_cjs.setVariablesCache(variables);
12078
+ chunkSC2WZFNQ_cjs.setVariablesCache(variables);
11619
12079
  return variables;
11620
12080
  } catch {
11621
12081
  return /* @__PURE__ */ new Map();
@@ -11684,7 +12144,7 @@ apiRoutes5.post("/", async (c) => {
11684
12144
  await db.prepare(
11685
12145
  "INSERT INTO global_variables (key, value, description, category, is_active) VALUES (?, ?, ?, ?, ?)"
11686
12146
  ).bind(key, value || "", description || "", category || "general", isActive !== false ? 1 : 0).run();
11687
- chunkSSOP7G4R_cjs.invalidateVariablesCache();
12147
+ chunkSC2WZFNQ_cjs.invalidateVariablesCache();
11688
12148
  const created = await db.prepare("SELECT * FROM global_variables WHERE key = ?").bind(key).first();
11689
12149
  return c.json({ success: true, data: formatVariable(created) }, 201);
11690
12150
  } catch {
@@ -11729,7 +12189,7 @@ apiRoutes5.put("/:id", async (c) => {
11729
12189
  updates.push("updated_at = strftime('%s', 'now')");
11730
12190
  params.push(id);
11731
12191
  await db.prepare(`UPDATE global_variables SET ${updates.join(", ")} WHERE id = ?`).bind(...params).run();
11732
- chunkSSOP7G4R_cjs.invalidateVariablesCache();
12192
+ chunkSC2WZFNQ_cjs.invalidateVariablesCache();
11733
12193
  const updated = await db.prepare("SELECT * FROM global_variables WHERE id = ?").bind(id).first();
11734
12194
  return c.json({ success: true, data: formatVariable(updated) });
11735
12195
  } catch {
@@ -11743,14 +12203,14 @@ apiRoutes5.delete("/:id", async (c) => {
11743
12203
  const existing = await db.prepare("SELECT id FROM global_variables WHERE id = ?").bind(id).first();
11744
12204
  if (!existing) return c.json({ error: "Variable not found" }, 404);
11745
12205
  await db.prepare("DELETE FROM global_variables WHERE id = ?").bind(id).run();
11746
- chunkSSOP7G4R_cjs.invalidateVariablesCache();
12206
+ chunkSC2WZFNQ_cjs.invalidateVariablesCache();
11747
12207
  return c.json({ success: true });
11748
12208
  } catch {
11749
12209
  return c.json({ success: false, error: "Failed to delete variable" }, 500);
11750
12210
  }
11751
12211
  });
11752
- var adminRoutes6 = new hono.Hono();
11753
- adminRoutes6.use("*", async (c, next) => {
12212
+ var adminRoutes7 = new hono.Hono();
12213
+ adminRoutes7.use("*", async (c, next) => {
11754
12214
  try {
11755
12215
  const db = c.env?.DB;
11756
12216
  if (db) {
@@ -11761,7 +12221,7 @@ adminRoutes6.use("*", async (c, next) => {
11761
12221
  }
11762
12222
  await next();
11763
12223
  });
11764
- adminRoutes6.get("/", async (c) => {
12224
+ adminRoutes7.get("/", async (c) => {
11765
12225
  const db = c.env.DB;
11766
12226
  let variables = [];
11767
12227
  try {
@@ -11791,7 +12251,7 @@ adminRoutes6.get("/", async (c) => {
11791
12251
  }
11792
12252
  return c.html(renderAdminPage(variables, { editorActive, activeEditorName, enableEditorIntegration }));
11793
12253
  });
11794
- adminRoutes6.put("/:id", async (c) => {
12254
+ adminRoutes7.put("/:id", async (c) => {
11795
12255
  const db = c.env.DB;
11796
12256
  const id = c.req.param("id");
11797
12257
  let body;
@@ -11803,19 +12263,19 @@ adminRoutes6.put("/:id", async (c) => {
11803
12263
  const value = body.value;
11804
12264
  if (value !== void 0) {
11805
12265
  await db.prepare("UPDATE global_variables SET value = ?, updated_at = strftime('%s', 'now') WHERE id = ?").bind(value, id).run();
11806
- chunkSSOP7G4R_cjs.invalidateVariablesCache();
12266
+ chunkSC2WZFNQ_cjs.invalidateVariablesCache();
11807
12267
  }
11808
12268
  return c.html('<span class="text-green-400 text-xs">Saved</span>');
11809
12269
  });
11810
- adminRoutes6.post("/:id/toggle", async (c) => {
12270
+ adminRoutes7.post("/:id/toggle", async (c) => {
11811
12271
  const db = c.env.DB;
11812
12272
  const id = c.req.param("id");
11813
12273
  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();
11814
- chunkSSOP7G4R_cjs.invalidateVariablesCache();
12274
+ chunkSC2WZFNQ_cjs.invalidateVariablesCache();
11815
12275
  c.header("HX-Redirect", "/admin/global-variables");
11816
12276
  return c.body(null, 204);
11817
12277
  });
11818
- adminRoutes6.post("/", async (c) => {
12278
+ adminRoutes7.post("/", async (c) => {
11819
12279
  const db = c.env.DB;
11820
12280
  const form = await c.req.parseBody();
11821
12281
  const key = (form.key || "").trim();
@@ -11832,11 +12292,11 @@ adminRoutes6.post("/", async (c) => {
11832
12292
  await db.prepare(
11833
12293
  "INSERT INTO global_variables (key, value, description, category) VALUES (?, ?, ?, ?)"
11834
12294
  ).bind(key, value, description, category).run();
11835
- chunkSSOP7G4R_cjs.invalidateVariablesCache();
12295
+ chunkSC2WZFNQ_cjs.invalidateVariablesCache();
11836
12296
  c.header("HX-Redirect", "/admin/global-variables");
11837
12297
  return c.body(null, 204);
11838
12298
  });
11839
- adminRoutes6.post("/settings/editor-integration", async (c) => {
12299
+ adminRoutes7.post("/settings/editor-integration", async (c) => {
11840
12300
  const db = c.env.DB;
11841
12301
  try {
11842
12302
  const row = await db.prepare("SELECT settings FROM plugins WHERE id = 'global-variables'").first();
@@ -11848,10 +12308,10 @@ adminRoutes6.post("/settings/editor-integration", async (c) => {
11848
12308
  return c.json({ success: false, error: "Failed to update setting" }, 500);
11849
12309
  }
11850
12310
  });
11851
- adminRoutes6.delete("/:id", async (c) => {
12311
+ adminRoutes7.delete("/:id", async (c) => {
11852
12312
  const db = c.env.DB;
11853
12313
  await db.prepare("DELETE FROM global_variables WHERE id = ?").bind(c.req.param("id")).run();
11854
- chunkSSOP7G4R_cjs.invalidateVariablesCache();
12314
+ chunkSC2WZFNQ_cjs.invalidateVariablesCache();
11855
12315
  return c.html("");
11856
12316
  });
11857
12317
  function renderAdminPage(variables, editorStatus = { editorActive: false, activeEditorName: "", enableEditorIntegration: true }) {
@@ -12169,7 +12629,7 @@ function renderAdminPage(variables, editorStatus = { editorActive: false, active
12169
12629
  </div>
12170
12630
  ` });
12171
12631
  }
12172
- var globalVariablesPlugin = chunk4YRYGDCQ_cjs.definePlugin({
12632
+ var globalVariablesPlugin = chunkKOXFYFOF_cjs.definePlugin({
12173
12633
  id: "global-variables",
12174
12634
  version: "1.1.0",
12175
12635
  name: "Global Variables",
@@ -12179,7 +12639,7 @@ var globalVariablesPlugin = chunk4YRYGDCQ_cjs.definePlugin({
12179
12639
  capabilities: ["hooks.content:subscribe"],
12180
12640
  register(app2) {
12181
12641
  app2.route("/api/global-variables", apiRoutes5);
12182
- app2.route("/admin/global-variables", adminRoutes6);
12642
+ app2.route("/admin/global-variables", adminRoutes7);
12183
12643
  },
12184
12644
  menu: [
12185
12645
  { label: "Global Variables", path: "/admin/global-variables", icon: "bolt", order: 45, permissions: ["global-variables:view"] }
@@ -12192,7 +12652,7 @@ var globalVariablesPlugin = chunk4YRYGDCQ_cjs.definePlugin({
12192
12652
  if (!db || !data) return data;
12193
12653
  const variables = await getVariablesMap(db);
12194
12654
  if (variables.size === 0) return data;
12195
- return chunkSSOP7G4R_cjs.resolveVariablesInObject(data, variables);
12655
+ return chunkSC2WZFNQ_cjs.resolveVariablesInObject(data, variables);
12196
12656
  } catch {
12197
12657
  return data;
12198
12658
  }
@@ -12210,7 +12670,7 @@ var globalVariablesPlugin = chunk4YRYGDCQ_cjs.definePlugin({
12210
12670
  },
12211
12671
  activate: async () => console.info("[GlobalVariables] Plugin activated"),
12212
12672
  deactivate: async () => {
12213
- chunkSSOP7G4R_cjs.invalidateVariablesCache();
12673
+ chunkSC2WZFNQ_cjs.invalidateVariablesCache();
12214
12674
  console.info("[GlobalVariables] Plugin deactivated, cache cleared");
12215
12675
  },
12216
12676
  uninstall: async (ctx) => {
@@ -12500,8 +12960,8 @@ apiRoutes6.delete("/:id", async (c) => {
12500
12960
  return c.json({ success: false, error: "Failed to delete shortcode" }, 500);
12501
12961
  }
12502
12962
  });
12503
- var adminRoutes7 = new hono.Hono();
12504
- adminRoutes7.use("*", async (c, next) => {
12963
+ var adminRoutes8 = new hono.Hono();
12964
+ adminRoutes8.use("*", async (c, next) => {
12505
12965
  try {
12506
12966
  const db = c.env?.DB;
12507
12967
  if (db) {
@@ -12512,7 +12972,7 @@ adminRoutes7.use("*", async (c, next) => {
12512
12972
  }
12513
12973
  await next();
12514
12974
  });
12515
- adminRoutes7.get("/", async (c) => {
12975
+ adminRoutes8.get("/", async (c) => {
12516
12976
  const db = c.env.DB;
12517
12977
  let shortcodes = [];
12518
12978
  try {
@@ -12542,7 +13002,7 @@ adminRoutes7.get("/", async (c) => {
12542
13002
  }
12543
13003
  return c.html(renderAdminPage2(shortcodes, { editorActive, activeEditorName, enableEditorIntegration }));
12544
13004
  });
12545
- adminRoutes7.post("/", async (c) => {
13005
+ adminRoutes8.post("/", async (c) => {
12546
13006
  const db = c.env.DB;
12547
13007
  const form = await c.req.parseBody();
12548
13008
  const name = (form.name || "").trim();
@@ -12563,7 +13023,7 @@ adminRoutes7.post("/", async (c) => {
12563
13023
  c.header("HX-Redirect", "/admin/shortcodes");
12564
13024
  return c.body(null, 204);
12565
13025
  });
12566
- adminRoutes7.post("/settings/editor-integration", async (c) => {
13026
+ adminRoutes8.post("/settings/editor-integration", async (c) => {
12567
13027
  const db = c.env.DB;
12568
13028
  try {
12569
13029
  const row = await db.prepare("SELECT settings FROM plugins WHERE id = 'shortcodes'").first();
@@ -12575,7 +13035,7 @@ adminRoutes7.post("/settings/editor-integration", async (c) => {
12575
13035
  return c.json({ success: false, error: "Failed to update setting" }, 500);
12576
13036
  }
12577
13037
  });
12578
- adminRoutes7.delete("/:id", async (c) => {
13038
+ adminRoutes8.delete("/:id", async (c) => {
12579
13039
  await c.env.DB.prepare("DELETE FROM shortcodes WHERE id = ?").bind(c.req.param("id")).run();
12580
13040
  return c.html("");
12581
13041
  });
@@ -12776,7 +13236,7 @@ function renderAdminPage2(shortcodes, editorStatus = { editorActive: false, acti
12776
13236
  </div>
12777
13237
  ` });
12778
13238
  }
12779
- var shortcodesPlugin = chunk4YRYGDCQ_cjs.definePlugin({
13239
+ var shortcodesPlugin = chunkKOXFYFOF_cjs.definePlugin({
12780
13240
  id: "shortcodes",
12781
13241
  version: "1.0.0",
12782
13242
  name: "Shortcodes",
@@ -12786,7 +13246,7 @@ var shortcodesPlugin = chunk4YRYGDCQ_cjs.definePlugin({
12786
13246
  capabilities: ["hooks.content:subscribe"],
12787
13247
  register(app2) {
12788
13248
  app2.route("/api/shortcodes", apiRoutes6);
12789
- app2.route("/admin/shortcodes", adminRoutes7);
13249
+ app2.route("/admin/shortcodes", adminRoutes8);
12790
13250
  },
12791
13251
  menu: [
12792
13252
  { label: "Shortcodes", path: "/admin/shortcodes", icon: "bolt", order: 46, permissions: ["shortcodes:view"] }
@@ -12860,7 +13320,7 @@ helloWorldRoutes.get("/", async (c) => {
12860
13320
  </html>
12861
13321
  `);
12862
13322
  });
12863
- var helloWorldPlugin = chunk4YRYGDCQ_cjs.definePlugin({
13323
+ var helloWorldPlugin = chunkKOXFYFOF_cjs.definePlugin({
12864
13324
  id: "hello-world",
12865
13325
  version: "1.0.0",
12866
13326
  name: "Hello World",
@@ -12895,6 +13355,9 @@ var helloWorldPlugin = chunk4YRYGDCQ_cjs.definePlugin({
12895
13355
  console.info("\u274C Hello World plugin deactivated");
12896
13356
  }
12897
13357
  });
13358
+ function createHelloWorldPlugin() {
13359
+ return helloWorldPlugin;
13360
+ }
12898
13361
 
12899
13362
  // src/plugins/core-plugins/multi-tenant-plugin/manifest.json
12900
13363
  var manifest_default2 = {
@@ -13088,7 +13551,7 @@ function renderTenantForm(data) {
13088
13551
  // src/plugins/core-plugins/multi-tenant-plugin/templates/tenant-members.template.ts
13089
13552
  chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
13090
13553
  function roleOptions(selected) {
13091
- return chunkSSOP7G4R_cjs.VALID_MEMBER_ROLES.map(
13554
+ return chunkSC2WZFNQ_cjs.VALID_MEMBER_ROLES.map(
13092
13555
  (r) => `<option value="${r}" ${r === selected ? "selected" : ""}>${r}</option>`
13093
13556
  ).join("");
13094
13557
  }
@@ -13150,7 +13613,7 @@ function renderInvitations(slug, invitations) {
13150
13613
  <div>
13151
13614
  <label for="invite-role" class="mb-1 block text-xs font-medium text-zinc-500 dark:text-zinc-400">Role</label>
13152
13615
  <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">
13153
- ${chunkSSOP7G4R_cjs.VALID_MEMBER_ROLES.map((r) => `<option value="${r}" ${r === "viewer" ? "selected" : ""}>${r}</option>`).join("")}
13616
+ ${chunkSC2WZFNQ_cjs.VALID_MEMBER_ROLES.map((r) => `<option value="${r}" ${r === "viewer" ? "selected" : ""}>${r}</option>`).join("")}
13154
13617
  </select>
13155
13618
  </div>
13156
13619
  <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>
@@ -13246,7 +13709,7 @@ function renderTenantMembers(data) {
13246
13709
  // src/plugins/core-plugins/multi-tenant-plugin/templates/user-memberships.template.ts
13247
13710
  chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
13248
13711
  function roleOptions2(selected) {
13249
- return chunkSSOP7G4R_cjs.VALID_MEMBER_ROLES.map(
13712
+ return chunkSC2WZFNQ_cjs.VALID_MEMBER_ROLES.map(
13250
13713
  (r) => `<option value="${r}" ${r === selected ? "selected" : ""}>${r}</option>`
13251
13714
  ).join("");
13252
13715
  }
@@ -13408,7 +13871,7 @@ function zodToFieldErrors(error) {
13408
13871
  }
13409
13872
  async function isMultiTenantActive(db) {
13410
13873
  try {
13411
- const plugin2 = await new chunkWIV3R2MJ_cjs.PluginService(db).getPlugin(chunkWIV3R2MJ_cjs.MULTI_TENANT_PLUGIN_ID);
13874
+ const plugin2 = await new chunkKZIBF2EV_cjs.PluginService(db).getPlugin(chunkKZIBF2EV_cjs.MULTI_TENANT_PLUGIN_ID);
13412
13875
  return plugin2?.status === "active";
13413
13876
  } catch {
13414
13877
  return false;
@@ -13416,7 +13879,7 @@ async function isMultiTenantActive(db) {
13416
13879
  }
13417
13880
  function createTenantAdminRoutes() {
13418
13881
  const routes2 = new hono.Hono();
13419
- routes2.use("*", chunkL3KHLEHL_cjs.requireAuth());
13882
+ routes2.use("*", chunkKMM45BTY_cjs.requireAuth());
13420
13883
  routes2.use("*", async (c, next) => {
13421
13884
  const user = c.get("user");
13422
13885
  if (user?.role !== "admin") {
@@ -13430,7 +13893,7 @@ function createTenantAdminRoutes() {
13430
13893
  const form = await c.req.formData();
13431
13894
  const slug = String(form.get("tenant") ?? "").trim().toLowerCase();
13432
13895
  const redirect = String(form.get("redirect") ?? "");
13433
- const svc = new chunkSSOP7G4R_cjs.TenantService(db);
13896
+ const svc = new chunkSC2WZFNQ_cjs.TenantService(db);
13434
13897
  const tenant = await svc.getTenantBySlug(slug);
13435
13898
  if (!tenant || tenant.status !== "active") {
13436
13899
  return c.json({ error: "Unknown or inactive tenant" }, 400);
@@ -13440,7 +13903,7 @@ function createTenantAdminRoutes() {
13440
13903
  if (!user.isSuperAdmin && !await svc.isMember(user.userId, slug)) {
13441
13904
  return c.json({ error: "You are not a member of this tenant" }, 403);
13442
13905
  }
13443
- cookie.setCookie(c, chunkWIV3R2MJ_cjs.TENANT_COOKIE, slug, {
13906
+ cookie.setCookie(c, chunkKZIBF2EV_cjs.TENANT_COOKIE, slug, {
13444
13907
  path: "/",
13445
13908
  httpOnly: true,
13446
13909
  sameSite: "Lax",
@@ -13457,7 +13920,7 @@ function createTenantAdminRoutes() {
13457
13920
  if (!user) return c.redirect("/auth/login");
13458
13921
  const token = c.req.query("token") ?? "";
13459
13922
  try {
13460
- const { slug } = await new chunkSSOP7G4R_cjs.TenantService(db).acceptInvitation(token, user.userId, user.email);
13923
+ const { slug } = await new chunkSC2WZFNQ_cjs.TenantService(db).acceptInvitation(token, user.userId, user.email);
13461
13924
  return c.redirect(`/admin/tenants/${slug}/members?message=Invitation accepted`);
13462
13925
  } catch (error) {
13463
13926
  const message = error instanceof Error ? error.message : "Failed to accept invitation";
@@ -13485,7 +13948,7 @@ function createTenantAdminRoutes() {
13485
13948
  const userId = c.req.param("userId");
13486
13949
  const target = await db.prepare("SELECT id, email FROM auth_user WHERE id = ?").bind(userId).first();
13487
13950
  if (!target?.id) return c.redirect("/admin/users?message=User not found&type=error");
13488
- const svc = new chunkSSOP7G4R_cjs.TenantService(db);
13951
+ const svc = new chunkSC2WZFNQ_cjs.TenantService(db);
13489
13952
  const [memberships, allTenants] = await Promise.all([svc.listUserMemberships(userId), svc.listTenants()]);
13490
13953
  const memberSlugs = new Set(memberships.map((m) => m.slug));
13491
13954
  const availableTenants = allTenants.filter((t) => t.status === "active" && !memberSlugs.has(t.slug)).map((t) => ({ slug: t.slug, name: t.name }));
@@ -13510,10 +13973,10 @@ function createTenantAdminRoutes() {
13510
13973
  const slug = String(form.get("slug") ?? "").trim().toLowerCase();
13511
13974
  const role = String(form.get("role") ?? "viewer");
13512
13975
  const redirectTo = String(form.get("_redirect") ?? "") || `/admin/tenants/users/${userId}`;
13513
- if (!chunkSSOP7G4R_cjs.isValidMemberRole(role)) throw new Error(`Invalid role '${role}'`);
13976
+ if (!chunkSC2WZFNQ_cjs.isValidMemberRole(role)) throw new Error(`Invalid role '${role}'`);
13514
13977
  const target = await db.prepare("SELECT email FROM auth_user WHERE id = ?").bind(userId).first();
13515
13978
  if (!target) throw new Error("User not found");
13516
- const svc = new chunkSSOP7G4R_cjs.TenantService(db);
13979
+ const svc = new chunkSC2WZFNQ_cjs.TenantService(db);
13517
13980
  if (!await svc.getTenantBySlug(slug)) throw new Error("Tenant not found");
13518
13981
  if (await svc.isMember(userId, slug)) throw new Error(`Already a member of '${slug}'`);
13519
13982
  await svc.addMember(slug, userId, role, target.email ?? null);
@@ -13532,7 +13995,7 @@ function createTenantAdminRoutes() {
13532
13995
  const form = await c.req.formData();
13533
13996
  const role = String(form.get("role") ?? "");
13534
13997
  const redirectTo = String(form.get("_redirect") ?? "") || `/admin/tenants/users/${userId}`;
13535
- await new chunkSSOP7G4R_cjs.TenantService(db).setMemberRole(slug, userId, role);
13998
+ await new chunkSC2WZFNQ_cjs.TenantService(db).setMemberRole(slug, userId, role);
13536
13999
  return c.redirect(`${redirectTo}?message=Role updated`);
13537
14000
  } catch (error) {
13538
14001
  const message = error instanceof Error ? error.message : "Failed to update role";
@@ -13547,7 +14010,7 @@ function createTenantAdminRoutes() {
13547
14010
  try {
13548
14011
  const form = await c.req.formData();
13549
14012
  const redirectTo = String(form.get("_redirect") ?? "") || `/admin/tenants/users/${userId}`;
13550
- await new chunkSSOP7G4R_cjs.TenantService(db).removeMember(slug, userId);
14013
+ await new chunkSC2WZFNQ_cjs.TenantService(db).removeMember(slug, userId);
13551
14014
  return c.redirect(`${redirectTo}?message=Removed from ${encodeURIComponent(slug)}`);
13552
14015
  } catch (error) {
13553
14016
  const message = error instanceof Error ? error.message : "Failed to remove membership";
@@ -13562,7 +14025,7 @@ function createTenantAdminRoutes() {
13562
14025
  return c.html(renderTenantsInactive({ user: userShape(cur), version }));
13563
14026
  }
13564
14027
  const roleName = c.req.param("roleName");
13565
- const assignments = await new chunkSSOP7G4R_cjs.TenantService(db).listAssignmentsByRole(roleName);
14028
+ const assignments = await new chunkSC2WZFNQ_cjs.TenantService(db).listAssignmentsByRole(roleName);
13566
14029
  return c.html(renderRoleUsage({ roleName, assignments, user: userShape(cur), version }));
13567
14030
  });
13568
14031
  routes2.get("/", async (c) => {
@@ -13572,7 +14035,7 @@ function createTenantAdminRoutes() {
13572
14035
  if (!await isMultiTenantActive(db)) {
13573
14036
  return c.html(renderTenantsInactive({ user: userShape(user), version }));
13574
14037
  }
13575
- const svc = new chunkSSOP7G4R_cjs.TenantService(db);
14038
+ const svc = new chunkSC2WZFNQ_cjs.TenantService(db);
13576
14039
  await svc.ensureDefaultTenant();
13577
14040
  const tenants = await svc.listTenants();
13578
14041
  const [docRes, memberRes] = await db.batch([
@@ -13611,7 +14074,7 @@ function createTenantAdminRoutes() {
13611
14074
  formEntries = Object.fromEntries(form.entries());
13612
14075
  const validated = tenantFormSchema.parse(formEntries);
13613
14076
  if (!validated.slug) throw new zod.z.ZodError([{ code: "custom", message: "Slug is required", path: ["slug"] }]);
13614
- const svc = new chunkSSOP7G4R_cjs.TenantService(db);
14077
+ const svc = new chunkSC2WZFNQ_cjs.TenantService(db);
13615
14078
  await svc.createTenant({
13616
14079
  name: validated.name,
13617
14080
  slug: validated.slug,
@@ -13636,7 +14099,7 @@ function createTenantAdminRoutes() {
13636
14099
  if (!await isMultiTenantActive(db)) {
13637
14100
  return c.html(renderTenantsInactive({ user: userShape(user), version }));
13638
14101
  }
13639
- const tenant = await new chunkSSOP7G4R_cjs.TenantService(db).getTenantBySlug(c.req.param("slug"));
14102
+ const tenant = await new chunkSC2WZFNQ_cjs.TenantService(db).getTenantBySlug(c.req.param("slug"));
13640
14103
  if (!tenant) return c.redirect("/admin/tenants?message=Tenant not found&type=error");
13641
14104
  return c.html(renderTenantForm({ tenant, isEdit: true, user: userShape(user), version }));
13642
14105
  });
@@ -13646,7 +14109,7 @@ function createTenantAdminRoutes() {
13646
14109
  const version = c.get("appVersion");
13647
14110
  const slug = c.req.param("slug");
13648
14111
  if (!await isMultiTenantActive(db)) return c.json({ error: "Multi-tenant plugin is not active" }, 403);
13649
- const svc = new chunkSSOP7G4R_cjs.TenantService(db);
14112
+ const svc = new chunkSC2WZFNQ_cjs.TenantService(db);
13650
14113
  try {
13651
14114
  const form = await c.req.formData();
13652
14115
  const validated = tenantFormSchema.parse(Object.fromEntries(form.entries()));
@@ -13671,7 +14134,7 @@ function createTenantAdminRoutes() {
13671
14134
  const slug = c.req.param("slug");
13672
14135
  if (!await isMultiTenantActive(db)) return c.json({ error: "Multi-tenant plugin is not active" }, 403);
13673
14136
  try {
13674
- await new chunkSSOP7G4R_cjs.TenantService(db).deleteTenant(slug);
14137
+ await new chunkSC2WZFNQ_cjs.TenantService(db).deleteTenant(slug);
13675
14138
  return c.redirect("/admin/tenants?message=Tenant deleted successfully");
13676
14139
  } catch (error) {
13677
14140
  const message = error instanceof Error ? error.message : "Failed to delete tenant";
@@ -13686,7 +14149,7 @@ function createTenantAdminRoutes() {
13686
14149
  return c.html(renderTenantsInactive({ user: userShape(user), version }));
13687
14150
  }
13688
14151
  const slug = c.req.param("slug");
13689
- const svc = new chunkSSOP7G4R_cjs.TenantService(db);
14152
+ const svc = new chunkSC2WZFNQ_cjs.TenantService(db);
13690
14153
  const tenant = await svc.getTenantBySlug(slug);
13691
14154
  if (!tenant) return c.redirect("/admin/tenants?message=Tenant not found&type=error");
13692
14155
  const [members, invitations] = await Promise.all([svc.listMembers(slug), svc.listInvitations(slug)]);
@@ -13712,7 +14175,7 @@ function createTenantAdminRoutes() {
13712
14175
  const form = await c.req.formData();
13713
14176
  const email = String(form.get("email") ?? "");
13714
14177
  const role = String(form.get("role") ?? "viewer");
13715
- await new chunkSSOP7G4R_cjs.TenantService(db).addMemberByEmail(slug, email, role);
14178
+ await new chunkSC2WZFNQ_cjs.TenantService(db).addMemberByEmail(slug, email, role);
13716
14179
  return c.redirect(`/admin/tenants/${slug}/members?message=Member added`);
13717
14180
  } catch (error) {
13718
14181
  const message = error instanceof Error ? error.message : "Failed to add member";
@@ -13727,7 +14190,7 @@ function createTenantAdminRoutes() {
13727
14190
  try {
13728
14191
  const form = await c.req.formData();
13729
14192
  const role = String(form.get("role") ?? "");
13730
- await new chunkSSOP7G4R_cjs.TenantService(db).setMemberRole(slug, userId, role);
14193
+ await new chunkSC2WZFNQ_cjs.TenantService(db).setMemberRole(slug, userId, role);
13731
14194
  return c.redirect(`/admin/tenants/${slug}/members?message=Role updated`);
13732
14195
  } catch (error) {
13733
14196
  const message = error instanceof Error ? error.message : "Failed to update role";
@@ -13740,7 +14203,7 @@ function createTenantAdminRoutes() {
13740
14203
  const userId = c.req.param("userId");
13741
14204
  if (!await isMultiTenantActive(db)) return c.json({ error: "Multi-tenant plugin is not active" }, 403);
13742
14205
  try {
13743
- await new chunkSSOP7G4R_cjs.TenantService(db).removeMember(slug, userId);
14206
+ await new chunkSC2WZFNQ_cjs.TenantService(db).removeMember(slug, userId);
13744
14207
  return c.redirect(`/admin/tenants/${slug}/members?message=Member removed`);
13745
14208
  } catch (error) {
13746
14209
  const message = error instanceof Error ? error.message : "Failed to remove member";
@@ -13756,12 +14219,12 @@ function createTenantAdminRoutes() {
13756
14219
  const form = await c.req.formData();
13757
14220
  const email = String(form.get("email") ?? "");
13758
14221
  const role = String(form.get("role") ?? "viewer");
13759
- const token = await new chunkSSOP7G4R_cjs.TenantService(db).createInvitation(slug, email, role, user?.userId ?? null);
14222
+ const token = await new chunkSC2WZFNQ_cjs.TenantService(db).createInvitation(slug, email, role, user?.userId ?? null);
13760
14223
  const origin = c.req.header("origin") || new URL(c.req.url).origin;
13761
14224
  const acceptUrl = `${origin}/join/invite?token=${encodeURIComponent(token)}`;
13762
14225
  let note;
13763
14226
  let noteType = "";
13764
- const svc2 = chunkSSOP7G4R_cjs.hasEmailService() ? chunkSSOP7G4R_cjs.getEmailService() : null;
14227
+ const svc2 = chunkSC2WZFNQ_cjs.hasEmailService() ? chunkSC2WZFNQ_cjs.getEmailService() : null;
13765
14228
  const hasRealProvider = !!svc2 && svc2.getProviderName() !== "console";
13766
14229
  if (hasRealProvider) {
13767
14230
  const result = await svc2.send({
@@ -13802,7 +14265,7 @@ function createTenantAdminRoutes() {
13802
14265
  WHERE i.id = ? AND t.slug = ? AND i.status = 'pending'`
13803
14266
  ).bind(id, slug).first();
13804
14267
  if (!inv) throw new Error("Invitation not found or already used");
13805
- const svc2 = chunkSSOP7G4R_cjs.hasEmailService() ? chunkSSOP7G4R_cjs.getEmailService() : null;
14268
+ const svc2 = chunkSC2WZFNQ_cjs.hasEmailService() ? chunkSC2WZFNQ_cjs.getEmailService() : null;
13806
14269
  const hasRealProvider = !!svc2 && svc2.getProviderName() !== "console";
13807
14270
  if (!hasRealProvider) throw new Error("No email plugin active");
13808
14271
  const origin = c.req.header("origin") || new URL(c.req.url).origin;
@@ -13827,7 +14290,7 @@ function createTenantAdminRoutes() {
13827
14290
  const id = c.req.param("id");
13828
14291
  if (!await isMultiTenantActive(db)) return c.json({ error: "Multi-tenant plugin is not active" }, 403);
13829
14292
  try {
13830
- await new chunkSSOP7G4R_cjs.TenantService(db).revokeInvitation(slug, id);
14293
+ await new chunkSC2WZFNQ_cjs.TenantService(db).revokeInvitation(slug, id);
13831
14294
  return c.redirect(`/admin/tenants/${slug}/members?message=Invitation revoked`);
13832
14295
  } catch (error) {
13833
14296
  const message = error instanceof Error ? error.message : "Failed to revoke invitation";
@@ -14057,7 +14520,7 @@ function createJoinRoutes() {
14057
14520
  if (existing) return rerender("An account with this email already exists. Please sign in instead.");
14058
14521
  try {
14059
14522
  const userId = crypto.randomUUID();
14060
- const passwordHash = await chunkL3KHLEHL_cjs.AuthManager.hashPassword(password);
14523
+ const passwordHash = await chunkKMM45BTY_cjs.AuthManager.hashPassword(password);
14061
14524
  const now = Date.now();
14062
14525
  const nowSec = Math.floor(now / 1e3);
14063
14526
  await db.batch([
@@ -14070,8 +14533,8 @@ function createJoinRoutes() {
14070
14533
  VALUES (?, ?, ?, 'credential', ?, ?, ?)`
14071
14534
  ).bind(`cred-${userId}`, userId, userId, passwordHash, nowSec, nowSec)
14072
14535
  ]);
14073
- await new chunkSSOP7G4R_cjs.TenantService(db).acceptInvitation(token, userId, inv.email);
14074
- const auth = chunkZTEJHSYS_cjs.createAuth(c.env);
14536
+ await new chunkSC2WZFNQ_cjs.TenantService(db).acceptInvitation(token, userId, inv.email);
14537
+ const auth = chunkKMCLNO4K_cjs.createAuth(c.env);
14075
14538
  const origin = new URL(c.req.url).origin;
14076
14539
  const baReq = new Request(`${origin}/auth/sign-in/email`, {
14077
14540
  method: "POST",
@@ -14126,7 +14589,7 @@ function createJoinRoutes() {
14126
14589
  version
14127
14590
  }), 400);
14128
14591
  try {
14129
- const auth = chunkZTEJHSYS_cjs.createAuth(c.env);
14592
+ const auth = chunkKMCLNO4K_cjs.createAuth(c.env);
14130
14593
  const origin = new URL(c.req.url).origin;
14131
14594
  const baReq = new Request(`${origin}/auth/sign-in/email`, {
14132
14595
  method: "POST",
@@ -14138,7 +14601,7 @@ function createJoinRoutes() {
14138
14601
  const baBody = await baRes.json();
14139
14602
  const userId = baBody?.user?.id;
14140
14603
  if (!userId) return rerender("Sign-in succeeded but could not read user ID.");
14141
- await new chunkSSOP7G4R_cjs.TenantService(db).acceptInvitation(token, userId, inv.email);
14604
+ await new chunkSC2WZFNQ_cjs.TenantService(db).acceptInvitation(token, userId, inv.email);
14142
14605
  const headers = new Headers({ Location: "/admin?message=Welcome! You have joined " + encodeURIComponent(inv.tenantName) });
14143
14606
  copyBaCookies(baRes, headers);
14144
14607
  return new Response(null, { status: 302, headers });
@@ -14152,7 +14615,7 @@ function createJoinRoutes() {
14152
14615
 
14153
14616
  // src/plugins/core-plugins/multi-tenant-plugin/index.ts
14154
14617
  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>`;
14155
- var multiTenantPlugin = chunk4YRYGDCQ_cjs.definePlugin({
14618
+ var multiTenantPlugin = chunkKOXFYFOF_cjs.definePlugin({
14156
14619
  id: manifest_default2.id,
14157
14620
  version: "1.0.0",
14158
14621
  name: manifest_default2.name,
@@ -14167,30 +14630,30 @@ var multiTenantPlugin = chunk4YRYGDCQ_cjs.definePlugin({
14167
14630
  { label: "Tenants", path: "/admin/tenants", icon: TENANT_ICON, order: 80 }
14168
14631
  ],
14169
14632
  activate: async () => {
14170
- chunkWIV3R2MJ_cjs.invalidateTenantCache();
14633
+ chunkKZIBF2EV_cjs.invalidateTenantCache();
14171
14634
  console.info("\u2705 Multi-Tenant plugin activated");
14172
14635
  },
14173
14636
  deactivate: async () => {
14174
- chunkWIV3R2MJ_cjs.invalidateTenantCache();
14637
+ chunkKZIBF2EV_cjs.invalidateTenantCache();
14175
14638
  console.info("\u274C Multi-Tenant plugin deactivated");
14176
14639
  }
14177
14640
  });
14178
14641
  var routes = new hono.Hono();
14179
- routes.use("*", chunkL3KHLEHL_cjs.requireAuth());
14180
- routes.use("*", chunkL3KHLEHL_cjs.requireRole(["admin", "editor"]));
14642
+ routes.use("*", chunkKMM45BTY_cjs.requireAuth());
14643
+ routes.use("*", chunkKMM45BTY_cjs.requireRole(["admin", "editor"]));
14181
14644
  routes.get("/:rootId", async (c) => {
14182
14645
  const { rootId } = c.req.param();
14183
14646
  const db = c.env.DB;
14184
- const scope = await chunkSSOP7G4R_cjs.resolveDocScope(c, db, { rootId });
14647
+ const scope = await chunkSC2WZFNQ_cjs.resolveDocScope(c, db, { rootId });
14185
14648
  if (!scope) {
14186
14649
  return c.html('<p class="text-zinc-500 dark:text-zinc-400 p-4">Document not found.</p>', 404);
14187
14650
  }
14188
14651
  if (!scope.docType?.settings?.versioning) {
14189
14652
  return c.html('<p class="text-zinc-500 dark:text-zinc-400 p-4">Versioning not enabled for this type.</p>', 404);
14190
14653
  }
14191
- const denied = await chunkSSOP7G4R_cjs.denyIfNotAllowed(c, db, rootId, "read", scope.docType?.settings, scope.tenantId);
14654
+ const denied = await chunkSC2WZFNQ_cjs.denyIfNotAllowed(c, db, rootId, "read", scope.docType?.settings, scope.tenantId);
14192
14655
  if (denied) return denied;
14193
- const repo = new chunkSSOP7G4R_cjs.DocumentRepository(db, scope.tenantId);
14656
+ const repo = new chunkSC2WZFNQ_cjs.DocumentRepository(db, scope.tenantId);
14194
14657
  const versions = await repo.getVersionHistory(rootId);
14195
14658
  const safeRootIdAttr = chunkMNWKYY5E_cjs.escapeHtml(rootId);
14196
14659
  const rows = versions.map((v) => {
@@ -14283,14 +14746,14 @@ routes.post("/:rootId/restore/:versionNumber", async (c) => {
14283
14746
  const { rootId, versionNumber } = c.req.param();
14284
14747
  const db = c.env.DB;
14285
14748
  const user = c.get("user");
14286
- const scope = await chunkSSOP7G4R_cjs.resolveDocScope(c, db, { rootId });
14749
+ const scope = await chunkSC2WZFNQ_cjs.resolveDocScope(c, db, { rootId });
14287
14750
  if (!scope) {
14288
14751
  return c.json({ error: "Document not found" }, 404);
14289
14752
  }
14290
14753
  if (!scope.docType?.settings?.versioning) {
14291
14754
  return c.json({ error: "Versioning not enabled for this type" }, 404);
14292
14755
  }
14293
- const denied = await chunkSSOP7G4R_cjs.denyIfNotAllowed(c, db, rootId, "update", scope.docType?.settings, scope.tenantId);
14756
+ const denied = await chunkSC2WZFNQ_cjs.denyIfNotAllowed(c, db, rootId, "update", scope.docType?.settings, scope.tenantId);
14294
14757
  if (denied) return denied;
14295
14758
  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();
14296
14759
  if (!row) {
@@ -14313,7 +14776,7 @@ routes.post("/:rootId/restore/:versionNumber", async (c) => {
14313
14776
  var routes_default = routes;
14314
14777
 
14315
14778
  // src/plugins/core-plugins/versioning-plugin/index.ts
14316
- var versioningPlugin = chunk4YRYGDCQ_cjs.definePlugin({
14779
+ var versioningPlugin = chunkKOXFYFOF_cjs.definePlugin({
14317
14780
  id: "versioning",
14318
14781
  version: "1.0.0",
14319
14782
  name: "Versioning",
@@ -14390,8 +14853,8 @@ function createMagicLinkAuthPlugin() {
14390
14853
  const baseUrl = new URL(c.req.url).origin;
14391
14854
  const magicLink = `${baseUrl}/auth/magic-link/verify?token=${token}`;
14392
14855
  try {
14393
- if (chunkSSOP7G4R_cjs.hasEmailService()) {
14394
- await chunkSSOP7G4R_cjs.getEmailService().send({
14856
+ if (chunkSC2WZFNQ_cjs.hasEmailService()) {
14857
+ await chunkSC2WZFNQ_cjs.getEmailService().send({
14395
14858
  to: normalizedEmail,
14396
14859
  subject: "Your Magic Link to Sign In",
14397
14860
  flow: "magic-link",
@@ -14468,19 +14931,19 @@ function createMagicLinkAuthPlugin() {
14468
14931
  SET used = 1, used_at = ?
14469
14932
  WHERE id = ?
14470
14933
  `).bind(Date.now(), magicLink.id).run();
14471
- const tokenTtl = await chunkL3KHLEHL_cjs.getJwtExpirySecondsFromDb(c.env.DB, c.env);
14472
- const jwtToken = await chunkL3KHLEHL_cjs.AuthManager.generateToken(
14934
+ const tokenTtl = await chunkKMM45BTY_cjs.getJwtExpirySecondsFromDb(c.env.DB, c.env);
14935
+ const jwtToken = await chunkKMM45BTY_cjs.AuthManager.generateToken(
14473
14936
  user.id,
14474
14937
  user.email,
14475
14938
  user.role,
14476
14939
  c.env.JWT_SECRET,
14477
14940
  tokenTtl
14478
14941
  );
14479
- chunkL3KHLEHL_cjs.AuthManager.setAuthCookie(c, jwtToken, { maxAge: tokenTtl });
14942
+ chunkKMM45BTY_cjs.AuthManager.setAuthCookie(c, jwtToken, { maxAge: tokenTtl });
14480
14943
  await db.prepare(`
14481
14944
  UPDATE auth_user SET last_login_at = ? WHERE id = ?
14482
14945
  `).bind(Date.now(), user.id).run();
14483
- chunkSSOP7G4R_cjs.dispatchHookEvent(
14946
+ chunkSC2WZFNQ_cjs.dispatchHookEvent(
14484
14947
  c,
14485
14948
  "auth:magic-link:consumed",
14486
14949
  { user: { id: user.id, email: user.email, role: user.role } },
@@ -14965,7 +15428,7 @@ async function warmCollections(db) {
14965
15428
  const collectionCache = chunkYA3TJ65D_cjs.getCacheService(config);
14966
15429
  let count = 0;
14967
15430
  try {
14968
- const results = chunkWIV3R2MJ_cjs.getCollectionRegistry().listActive().map(chunkWIV3R2MJ_cjs.collectionRecordToRow);
15431
+ const results = chunkKZIBF2EV_cjs.getCollectionRegistry().listActive().map(chunkKZIBF2EV_cjs.collectionRecordToRow);
14969
15432
  for (const collection of results) {
14970
15433
  const key = collectionCache.generateKey("item", collection.id);
14971
15434
  await collectionCache.set(key, collection);
@@ -15236,7 +15699,7 @@ function renderCacheDashboard(data) {
15236
15699
  </script>
15237
15700
 
15238
15701
  <!-- Confirmation Dialogs -->
15239
- ${chunkSSOP7G4R_cjs.renderConfirmationDialog({
15702
+ ${chunkSC2WZFNQ_cjs.renderConfirmationDialog({
15240
15703
  id: "clear-all-cache-confirm",
15241
15704
  title: "Clear All Cache",
15242
15705
  message: "Are you sure you want to clear all cache entries? This cannot be undone.",
@@ -15247,7 +15710,7 @@ function renderCacheDashboard(data) {
15247
15710
  onConfirm: "performClearAllCaches()"
15248
15711
  })}
15249
15712
 
15250
- ${chunkSSOP7G4R_cjs.renderConfirmationDialog({
15713
+ ${chunkSC2WZFNQ_cjs.renderConfirmationDialog({
15251
15714
  id: "clear-namespace-cache-confirm",
15252
15715
  title: "Clear Namespace Cache",
15253
15716
  message: "Clear cache for this namespace?",
@@ -15258,7 +15721,7 @@ function renderCacheDashboard(data) {
15258
15721
  onConfirm: "performClearNamespaceCache()"
15259
15722
  })}
15260
15723
 
15261
- ${chunkSSOP7G4R_cjs.getConfirmationDialogScript()}
15724
+ ${chunkSC2WZFNQ_cjs.getConfirmationDialogScript()}
15262
15725
  `;
15263
15726
  const layoutData = {
15264
15727
  title: "Cache System",
@@ -15524,7 +15987,7 @@ app.get("/", async (c) => {
15524
15987
  const totalRequests = totalHits + totalMisses;
15525
15988
  const overallHitRate = totalRequests > 0 ? totalHits / totalRequests * 100 : 0;
15526
15989
  const DEFAULT_TTL = chunkYA3TJ65D_cjs.CACHE_CONFIGS.api?.ttl ?? 300;
15527
- const collections = chunkWIV3R2MJ_cjs.getCollectionRegistry().listActive().filter((r) => !r.internal).map((r) => {
15990
+ const collections = chunkKZIBF2EV_cjs.getCollectionRegistry().listActive().filter((r) => !r.internal).map((r) => {
15528
15991
  const cacheOverride = r.cache;
15529
15992
  const cacheEnabled = cacheOverride?.enabled !== false;
15530
15993
  const hasCustomTtl = typeof cacheOverride?.ttl === "number";
@@ -16061,16 +16524,17 @@ var faviconSvg = `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
16061
16524
  // src/app.ts
16062
16525
  function createSonicJSApp(config = {}) {
16063
16526
  const app2 = new hono.Hono();
16064
- const appVersion = config.version || chunkSIPBHWMG_cjs.getCoreVersion();
16527
+ const appVersion = config.version || chunk3XFA3E2F_cjs.getCoreVersion();
16065
16528
  const appName = config.name || "SonicJS AI";
16066
- const hookSystem = new chunkG5LC7MYH_cjs.HookSystemImpl();
16529
+ const hookSystem = new chunkLXYDJU6U_cjs.HookSystemImpl();
16067
16530
  chunkJ6JTWD2A_cjs.setHookSystem(hookSystem);
16068
16531
  const magicLinkPlugin = createMagicLinkAuthPlugin();
16069
16532
  const corePluginsBeforeCatchAll = [
16070
16533
  securityAuditPlugin,
16534
+ apiKeysPlugin,
16071
16535
  aiSearchPlugin,
16072
16536
  oauthProvidersPlugin,
16073
- chunkSSOP7G4R_cjs.userProfilesPlugin,
16537
+ chunkSC2WZFNQ_cjs.userProfilesPlugin,
16074
16538
  otpLoginPlugin,
16075
16539
  analyticsPlugin,
16076
16540
  stripePlugin,
@@ -16080,23 +16544,23 @@ function createSonicJSApp(config = {}) {
16080
16544
  shortcodesPlugin,
16081
16545
  helloWorldPlugin,
16082
16546
  multiTenantPlugin,
16083
- chunkSSOP7G4R_cjs.lexicalEditorPlugin,
16547
+ chunkSC2WZFNQ_cjs.lexicalEditorPlugin,
16084
16548
  versioningPlugin
16085
16549
  ];
16086
16550
  const corePluginsAfterCatchAll = [emailPluginV3, magicLinkPlugin, emailReconciliationPlugin];
16087
- const wirePlugins = chunkG5LC7MYH_cjs.createPluginWirer(
16551
+ const wirePlugins = chunkLXYDJU6U_cjs.createPluginWirer(
16088
16552
  () => [...corePluginsBeforeCatchAll, ...corePluginsAfterCatchAll, ...config.plugins?.register ?? []],
16089
16553
  // The capability-gated `ctx.cap.email` resolves to the app EmailService, which
16090
16554
  // is initialized (below) just before wiring on the first request.
16091
16555
  () => ({
16092
16556
  hooks: hookSystem,
16093
16557
  env: firstRequestEnv,
16094
- providers: { email: () => chunkSSOP7G4R_cjs.getEmailService() }
16558
+ providers: { email: () => chunkSC2WZFNQ_cjs.getEmailService() }
16095
16559
  })
16096
16560
  );
16097
16561
  let firstRequestEnv;
16098
16562
  const initEmailService = async (env = {}) => {
16099
- if (chunkSSOP7G4R_cjs.hasEmailService()) return;
16563
+ if (chunkSC2WZFNQ_cjs.hasEmailService()) return;
16100
16564
  let provider;
16101
16565
  let defaultFrom = config.email?.from;
16102
16566
  let defaultReplyTo;
@@ -16131,14 +16595,14 @@ function createSonicJSApp(config = {}) {
16131
16595
  }
16132
16596
  }
16133
16597
  defaultFrom = defaultFrom || env.DEFAULT_FROM_EMAIL || "noreply@sonicjs.local";
16134
- chunkSSOP7G4R_cjs.setEmailService(new EmailService({ provider, defaultFrom, defaultReplyTo, db: env.DB }));
16598
+ chunkSC2WZFNQ_cjs.setEmailService(new EmailService({ provider, defaultFrom, defaultReplyTo, db: env.DB }));
16135
16599
  };
16136
16600
  app2.use("*", async (c, next) => {
16137
16601
  c.set("appVersion", appVersion);
16138
16602
  await next();
16139
16603
  });
16140
- app2.use("*", chunkL3KHLEHL_cjs.metricsMiddleware());
16141
- app2.use("*", chunkL3KHLEHL_cjs.bootstrapMiddleware(config));
16604
+ app2.use("*", chunkKMM45BTY_cjs.metricsMiddleware());
16605
+ app2.use("*", chunkKMM45BTY_cjs.bootstrapMiddleware(config));
16142
16606
  const boot = async (env) => {
16143
16607
  if (config.plugins?.disableAll) return;
16144
16608
  firstRequestEnv = env;
@@ -16176,13 +16640,13 @@ function createSonicJSApp(config = {}) {
16176
16640
  allowHeaders: ["Content-Type", "Authorization", "X-API-Key"],
16177
16641
  credentials: true
16178
16642
  }));
16179
- app2.use("*", chunkL3KHLEHL_cjs.securityHeadersMiddleware());
16180
- app2.use("*", chunkL3KHLEHL_cjs.csrfProtection());
16643
+ app2.use("*", chunkKMM45BTY_cjs.securityHeadersMiddleware());
16644
+ app2.use("*", chunkKMM45BTY_cjs.csrfProtection());
16181
16645
  app2.use("*", async (c, next) => {
16182
16646
  try {
16183
16647
  const reqUrl = new URL(c.req.url);
16184
16648
  const requestBaseURL = `${reqUrl.protocol}//${reqUrl.host}`;
16185
- const auth = chunkZTEJHSYS_cjs.createAuth(c.env, config.auth?.extendBetterAuth, requestBaseURL);
16649
+ const auth = chunkKMCLNO4K_cjs.createAuth(c.env, config.auth?.extendBetterAuth, requestBaseURL);
16186
16650
  const session = await auth.api.getSession({ headers: c.req.raw.headers });
16187
16651
  if (session?.user) {
16188
16652
  const u = session.user;
@@ -16209,14 +16673,15 @@ function createSonicJSApp(config = {}) {
16209
16673
  }
16210
16674
  await next();
16211
16675
  });
16676
+ app2.use("*", apiKeyAuthMiddleware());
16212
16677
  if (config.middleware?.afterAuth) {
16213
16678
  for (const middleware of config.middleware.afterAuth) {
16214
16679
  app2.use("*", middleware);
16215
16680
  }
16216
16681
  }
16217
- app2.use("*", chunkWIV3R2MJ_cjs.tenantMiddleware());
16218
- app2.use("/admin/*", chunkL3KHLEHL_cjs.requireAuth());
16219
- app2.use("/admin/*", chunkL3KHLEHL_cjs.requireRbac("portal", "access"));
16682
+ app2.use("*", chunkKZIBF2EV_cjs.tenantMiddleware());
16683
+ app2.use("/admin/*", chunkKMM45BTY_cjs.requireAuth());
16684
+ app2.use("/admin/*", chunkKMM45BTY_cjs.requireRbac("portal", "access"));
16220
16685
  app2.use("/admin/*", pluginMenuMiddleware());
16221
16686
  const NAV_LANDING = [
16222
16687
  { path: "/admin/content", perm: "content:read" },
@@ -16262,43 +16727,43 @@ function createSonicJSApp(config = {}) {
16262
16727
  });
16263
16728
  app2.route("/api/security-audit", apiRoutes2);
16264
16729
  app2.route("/admin/plugins/security-audit", adminRoutes3);
16265
- app2.route("/api/media", chunkSSOP7G4R_cjs.api_media_default);
16266
- app2.route("/api/system", chunkSSOP7G4R_cjs.api_system_default);
16267
- app2.route("/api/documents", chunkSSOP7G4R_cjs.apiDocumentsRoutes);
16268
- app2.route("/api", chunkSSOP7G4R_cjs.api_default);
16269
- app2.route("/admin/documents", chunkSSOP7G4R_cjs.adminDocumentsRoutes);
16270
- chunkG5LC7MYH_cjs.registerPluginRoutes(app2, [formsPlugin], { source: "core" });
16271
- app2.route("/admin/api", chunkSSOP7G4R_cjs.admin_api_default);
16272
- app2.route("/admin/collections", chunkSSOP7G4R_cjs.adminCollectionsRoutes);
16273
- app2.route("/admin/settings", chunkSSOP7G4R_cjs.adminSettingsRoutes);
16274
- app2.route("/admin/api-reference", chunkSSOP7G4R_cjs.router2);
16730
+ app2.route("/api/media", chunkSC2WZFNQ_cjs.api_media_default);
16731
+ app2.route("/api/system", chunkSC2WZFNQ_cjs.api_system_default);
16732
+ app2.route("/api/documents", chunkSC2WZFNQ_cjs.apiDocumentsRoutes);
16733
+ app2.route("/api", chunkSC2WZFNQ_cjs.api_default);
16734
+ app2.route("/admin/documents", chunkSC2WZFNQ_cjs.adminDocumentsRoutes);
16735
+ chunkLXYDJU6U_cjs.registerPluginRoutes(app2, [formsPlugin], { source: "core" });
16736
+ app2.route("/admin/api", chunkSC2WZFNQ_cjs.admin_api_default);
16737
+ app2.route("/admin/collections", chunkSC2WZFNQ_cjs.adminCollectionsRoutes);
16738
+ app2.route("/admin/settings", chunkSC2WZFNQ_cjs.adminSettingsRoutes);
16739
+ app2.route("/admin/api-reference", chunkSC2WZFNQ_cjs.router2);
16275
16740
  app2.route("/admin/database-tools", createDatabaseToolsAdminRoutes());
16276
- app2.route("/admin/content", chunkSSOP7G4R_cjs.admin_content_default);
16277
- app2.route("/admin/media", chunkSSOP7G4R_cjs.adminMediaRoutes);
16741
+ app2.route("/admin/content", chunkSC2WZFNQ_cjs.admin_content_default);
16742
+ app2.route("/admin/media", chunkSC2WZFNQ_cjs.adminMediaRoutes);
16278
16743
  app2.use("/auth/*", securityAuditMiddleware());
16279
16744
  if (!config.plugins?.disableAll) {
16280
- chunkG5LC7MYH_cjs.registerPluginRoutes(app2, corePluginsBeforeCatchAll, { source: "core" });
16745
+ chunkLXYDJU6U_cjs.registerPluginRoutes(app2, corePluginsBeforeCatchAll, { source: "core" });
16281
16746
  app2.route("/admin/cache", cache_default.getRoutes());
16282
16747
  if (config.plugins?.register && config.plugins.register.length > 0) {
16283
- chunkG5LC7MYH_cjs.registerPluginRoutes(app2, config.plugins.register, { source: "user" });
16748
+ chunkLXYDJU6U_cjs.registerPluginRoutes(app2, config.plugins.register, { source: "user" });
16284
16749
  }
16285
16750
  }
16286
16751
  app2.route("/api/events", apiRoutes4);
16287
- app2.route("/admin/dashboard", chunkSSOP7G4R_cjs.router);
16288
- app2.route("/admin/plugins", chunkSSOP7G4R_cjs.adminPluginRoutes);
16289
- app2.route("/admin/logs", chunkSSOP7G4R_cjs.adminLogsRoutes);
16752
+ app2.route("/admin/dashboard", chunkSC2WZFNQ_cjs.router);
16753
+ app2.route("/admin/plugins", chunkSC2WZFNQ_cjs.adminPluginRoutes);
16754
+ app2.route("/admin/logs", chunkSC2WZFNQ_cjs.adminLogsRoutes);
16290
16755
  app2.route("/admin/rbac", adminRbacRoutes);
16291
- app2.route("/admin", chunkSSOP7G4R_cjs.userRoutes);
16292
- app2.route("/auth", chunkSSOP7G4R_cjs.auth_default);
16756
+ app2.route("/admin", chunkSC2WZFNQ_cjs.userRoutes);
16757
+ app2.route("/auth", chunkSC2WZFNQ_cjs.auth_default);
16293
16758
  app2.on(["GET", "POST"], "/auth/*", (c) => {
16294
16759
  const reqUrl = new URL(c.req.url);
16295
16760
  const requestBaseURL = `${reqUrl.protocol}//${reqUrl.host}`;
16296
- const auth = chunkZTEJHSYS_cjs.createAuth(c.env, config.auth?.extendBetterAuth, requestBaseURL);
16761
+ const auth = chunkKMCLNO4K_cjs.createAuth(c.env, config.auth?.extendBetterAuth, requestBaseURL);
16297
16762
  return auth.handler(c.req.raw);
16298
16763
  });
16299
- app2.route("/", chunkSSOP7G4R_cjs.test_cleanup_default);
16764
+ app2.route("/", chunkSC2WZFNQ_cjs.test_cleanup_default);
16300
16765
  if (!config.plugins?.disableAll) {
16301
- chunkG5LC7MYH_cjs.registerPluginRoutes(app2, corePluginsAfterCatchAll, { source: "core" });
16766
+ chunkLXYDJU6U_cjs.registerPluginRoutes(app2, corePluginsAfterCatchAll, { source: "core" });
16302
16767
  }
16303
16768
  if (!config.plugins?.disableAll) {
16304
16769
  const allMountedPlugins = [
@@ -16307,8 +16772,11 @@ function createSonicJSApp(config = {}) {
16307
16772
  ...corePluginsAfterCatchAll,
16308
16773
  ...config.plugins?.register ?? []
16309
16774
  ];
16310
- chunkG5LC7MYH_cjs.setPluginMenu(allMountedPlugins.flatMap((p) => p.menu ?? []));
16311
- chunk4YRYGDCQ_cjs.setPluginDefinitions(allMountedPlugins);
16775
+ const userPlugins = (config.plugins?.register ?? []).filter(
16776
+ (p) => !chunkKZIBF2EV_cjs.PLUGIN_REGISTRY[p.id]
16777
+ );
16778
+ chunkLXYDJU6U_cjs.setPluginMenu(userPlugins.flatMap((p) => p.menu ?? []));
16779
+ chunkKOXFYFOF_cjs.setPluginDefinitions(allMountedPlugins);
16312
16780
  }
16313
16781
  app2.get("/favicon.svg", (c) => {
16314
16782
  return new Response(faviconSvg, {
@@ -19800,7 +20268,7 @@ function createRedirectApiRoutes() {
19800
20268
  });
19801
20269
  return api;
19802
20270
  }
19803
- var redirectPlugin = chunk4YRYGDCQ_cjs.definePlugin({
20271
+ var redirectPlugin = chunkKOXFYFOF_cjs.definePlugin({
19804
20272
  id: manifest_default3.id,
19805
20273
  version: manifest_default3.version,
19806
20274
  name: manifest_default3.name,
@@ -19818,7 +20286,7 @@ var redirectPlugin = chunk4YRYGDCQ_cjs.definePlugin({
19818
20286
  async onBoot(ctx) {
19819
20287
  const db = ctx.env?.DB;
19820
20288
  if (!db) return;
19821
- const registry = new chunkL3KHLEHL_cjs.DocumentTypeRegistry(db);
20289
+ const registry = new chunkKMM45BTY_cjs.DocumentTypeRegistry(db);
19822
20290
  await registry.register({
19823
20291
  id: "redirect",
19824
20292
  name: "redirect",
@@ -19934,87 +20402,91 @@ function createDb(d1$1) {
19934
20402
  }
19935
20403
 
19936
20404
  // src/index.ts
19937
- var VERSION = chunkSIPBHWMG_cjs.package_default.version;
20405
+ var VERSION = chunk3XFA3E2F_cjs.package_default.version;
19938
20406
 
20407
+ Object.defineProperty(exports, "DocumentRepository", {
20408
+ enumerable: true,
20409
+ get: function () { return chunkSC2WZFNQ_cjs.DocumentRepository; }
20410
+ });
19939
20411
  Object.defineProperty(exports, "ROUTES_INFO", {
19940
20412
  enumerable: true,
19941
- get: function () { return chunkSSOP7G4R_cjs.ROUTES_INFO; }
20413
+ get: function () { return chunkSC2WZFNQ_cjs.ROUTES_INFO; }
19942
20414
  });
19943
20415
  Object.defineProperty(exports, "adminApiRoutes", {
19944
20416
  enumerable: true,
19945
- get: function () { return chunkSSOP7G4R_cjs.admin_api_default; }
20417
+ get: function () { return chunkSC2WZFNQ_cjs.admin_api_default; }
19946
20418
  });
19947
20419
  Object.defineProperty(exports, "adminCheckboxRoutes", {
19948
20420
  enumerable: true,
19949
- get: function () { return chunkSSOP7G4R_cjs.adminCheckboxRoutes; }
20421
+ get: function () { return chunkSC2WZFNQ_cjs.adminCheckboxRoutes; }
19950
20422
  });
19951
20423
  Object.defineProperty(exports, "adminCollectionsRoutes", {
19952
20424
  enumerable: true,
19953
- get: function () { return chunkSSOP7G4R_cjs.adminCollectionsRoutes; }
20425
+ get: function () { return chunkSC2WZFNQ_cjs.adminCollectionsRoutes; }
19954
20426
  });
19955
20427
  Object.defineProperty(exports, "adminContentRoutes", {
19956
20428
  enumerable: true,
19957
- get: function () { return chunkSSOP7G4R_cjs.admin_content_default; }
20429
+ get: function () { return chunkSC2WZFNQ_cjs.admin_content_default; }
19958
20430
  });
19959
20431
  Object.defineProperty(exports, "adminDashboardRoutes", {
19960
20432
  enumerable: true,
19961
- get: function () { return chunkSSOP7G4R_cjs.router; }
20433
+ get: function () { return chunkSC2WZFNQ_cjs.router; }
19962
20434
  });
19963
20435
  Object.defineProperty(exports, "adminLogsRoutes", {
19964
20436
  enumerable: true,
19965
- get: function () { return chunkSSOP7G4R_cjs.adminLogsRoutes; }
20437
+ get: function () { return chunkSC2WZFNQ_cjs.adminLogsRoutes; }
19966
20438
  });
19967
20439
  Object.defineProperty(exports, "adminMediaRoutes", {
19968
20440
  enumerable: true,
19969
- get: function () { return chunkSSOP7G4R_cjs.adminMediaRoutes; }
20441
+ get: function () { return chunkSC2WZFNQ_cjs.adminMediaRoutes; }
19970
20442
  });
19971
20443
  Object.defineProperty(exports, "adminPluginRoutes", {
19972
20444
  enumerable: true,
19973
- get: function () { return chunkSSOP7G4R_cjs.adminPluginRoutes; }
20445
+ get: function () { return chunkSC2WZFNQ_cjs.adminPluginRoutes; }
19974
20446
  });
19975
20447
  Object.defineProperty(exports, "adminSettingsRoutes", {
19976
20448
  enumerable: true,
19977
- get: function () { return chunkSSOP7G4R_cjs.adminSettingsRoutes; }
20449
+ get: function () { return chunkSC2WZFNQ_cjs.adminSettingsRoutes; }
19978
20450
  });
19979
20451
  Object.defineProperty(exports, "adminUsersRoutes", {
19980
20452
  enumerable: true,
19981
- get: function () { return chunkSSOP7G4R_cjs.userRoutes; }
20453
+ get: function () { return chunkSC2WZFNQ_cjs.userRoutes; }
19982
20454
  });
19983
20455
  Object.defineProperty(exports, "apiContentCrudRoutes", {
19984
20456
  enumerable: true,
19985
- get: function () { return chunkSSOP7G4R_cjs.api_content_crud_default; }
20457
+ get: function () { return chunkSC2WZFNQ_cjs.api_content_crud_default; }
19986
20458
  });
19987
20459
  Object.defineProperty(exports, "apiMediaRoutes", {
19988
20460
  enumerable: true,
19989
- get: function () { return chunkSSOP7G4R_cjs.api_media_default; }
20461
+ get: function () { return chunkSC2WZFNQ_cjs.api_media_default; }
19990
20462
  });
19991
20463
  Object.defineProperty(exports, "apiRoutes", {
19992
20464
  enumerable: true,
19993
- get: function () { return chunkSSOP7G4R_cjs.api_default; }
20465
+ get: function () { return chunkSC2WZFNQ_cjs.api_default; }
19994
20466
  });
19995
20467
  Object.defineProperty(exports, "apiSystemRoutes", {
19996
20468
  enumerable: true,
19997
- get: function () { return chunkSSOP7G4R_cjs.api_system_default; }
20469
+ get: function () { return chunkSC2WZFNQ_cjs.api_system_default; }
19998
20470
  });
19999
20471
  Object.defineProperty(exports, "authRoutes", {
20000
20472
  enumerable: true,
20001
- get: function () { return chunkSSOP7G4R_cjs.auth_default; }
20473
+ get: function () { return chunkSC2WZFNQ_cjs.auth_default; }
20002
20474
  });
20003
20475
  Object.defineProperty(exports, "createUserProfilesPlugin", {
20004
20476
  enumerable: true,
20005
- get: function () { return chunkSSOP7G4R_cjs.createUserProfilesPlugin; }
20477
+ get: function () { return chunkSC2WZFNQ_cjs.createUserProfilesPlugin; }
20006
20478
  });
20007
20479
  Object.defineProperty(exports, "defineUserProfile", {
20008
20480
  enumerable: true,
20009
- get: function () { return chunkSSOP7G4R_cjs.defineUserProfile; }
20481
+ get: function () { return chunkSC2WZFNQ_cjs.defineUserProfile; }
20010
20482
  });
20011
20483
  Object.defineProperty(exports, "getUserProfileConfig", {
20012
20484
  enumerable: true,
20013
- get: function () { return chunkSSOP7G4R_cjs.getUserProfileConfig; }
20485
+ get: function () { return chunkSC2WZFNQ_cjs.getUserProfileConfig; }
20014
20486
  });
20015
20487
  Object.defineProperty(exports, "userProfilesPlugin", {
20016
20488
  enumerable: true,
20017
- get: function () { return chunkSSOP7G4R_cjs.userProfilesPlugin; }
20489
+ get: function () { return chunkSC2WZFNQ_cjs.userProfilesPlugin; }
20018
20490
  });
20019
20491
  Object.defineProperty(exports, "Logger", {
20020
20492
  enumerable: true,
@@ -20170,87 +20642,91 @@ Object.defineProperty(exports, "workflowHistory", {
20170
20642
  });
20171
20643
  Object.defineProperty(exports, "AuthManager", {
20172
20644
  enumerable: true,
20173
- get: function () { return chunkL3KHLEHL_cjs.AuthManager; }
20645
+ get: function () { return chunkKMM45BTY_cjs.AuthManager; }
20174
20646
  });
20175
20647
  Object.defineProperty(exports, "PermissionManager", {
20176
20648
  enumerable: true,
20177
- get: function () { return chunkL3KHLEHL_cjs.PermissionManager; }
20649
+ get: function () { return chunkKMM45BTY_cjs.PermissionManager; }
20178
20650
  });
20179
20651
  Object.defineProperty(exports, "bootstrapDocumentTypes", {
20180
20652
  enumerable: true,
20181
- get: function () { return chunkL3KHLEHL_cjs.bootstrapDocumentTypes; }
20653
+ get: function () { return chunkKMM45BTY_cjs.bootstrapDocumentTypes; }
20182
20654
  });
20183
20655
  Object.defineProperty(exports, "bootstrapMiddleware", {
20184
20656
  enumerable: true,
20185
- get: function () { return chunkL3KHLEHL_cjs.bootstrapMiddleware; }
20657
+ get: function () { return chunkKMM45BTY_cjs.bootstrapMiddleware; }
20186
20658
  });
20187
20659
  Object.defineProperty(exports, "cacheHeaders", {
20188
20660
  enumerable: true,
20189
- get: function () { return chunkL3KHLEHL_cjs.cacheHeaders; }
20661
+ get: function () { return chunkKMM45BTY_cjs.cacheHeaders; }
20190
20662
  });
20191
20663
  Object.defineProperty(exports, "compressionMiddleware", {
20192
20664
  enumerable: true,
20193
- get: function () { return chunkL3KHLEHL_cjs.compressionMiddleware; }
20665
+ get: function () { return chunkKMM45BTY_cjs.compressionMiddleware; }
20194
20666
  });
20195
20667
  Object.defineProperty(exports, "detailedLoggingMiddleware", {
20196
20668
  enumerable: true,
20197
- get: function () { return chunkL3KHLEHL_cjs.detailedLoggingMiddleware; }
20669
+ get: function () { return chunkKMM45BTY_cjs.detailedLoggingMiddleware; }
20198
20670
  });
20199
20671
  Object.defineProperty(exports, "getActivePlugins", {
20200
20672
  enumerable: true,
20201
- get: function () { return chunkL3KHLEHL_cjs.getActivePlugins; }
20673
+ get: function () { return chunkKMM45BTY_cjs.getActivePlugins; }
20202
20674
  });
20203
20675
  Object.defineProperty(exports, "isPluginActive", {
20204
20676
  enumerable: true,
20205
- get: function () { return chunkL3KHLEHL_cjs.isPluginActive; }
20677
+ get: function () { return chunkKMM45BTY_cjs.isPluginActive; }
20206
20678
  });
20207
20679
  Object.defineProperty(exports, "logActivity", {
20208
20680
  enumerable: true,
20209
- get: function () { return chunkL3KHLEHL_cjs.logActivity; }
20681
+ get: function () { return chunkKMM45BTY_cjs.logActivity; }
20210
20682
  });
20211
20683
  Object.defineProperty(exports, "loggingMiddleware", {
20212
20684
  enumerable: true,
20213
- get: function () { return chunkL3KHLEHL_cjs.loggingMiddleware; }
20685
+ get: function () { return chunkKMM45BTY_cjs.loggingMiddleware; }
20214
20686
  });
20215
20687
  Object.defineProperty(exports, "optionalAuth", {
20216
20688
  enumerable: true,
20217
- get: function () { return chunkL3KHLEHL_cjs.optionalAuth; }
20689
+ get: function () { return chunkKMM45BTY_cjs.optionalAuth; }
20218
20690
  });
20219
20691
  Object.defineProperty(exports, "performanceLoggingMiddleware", {
20220
20692
  enumerable: true,
20221
- get: function () { return chunkL3KHLEHL_cjs.performanceLoggingMiddleware; }
20693
+ get: function () { return chunkKMM45BTY_cjs.performanceLoggingMiddleware; }
20222
20694
  });
20223
20695
  Object.defineProperty(exports, "requireActivePlugin", {
20224
20696
  enumerable: true,
20225
- get: function () { return chunkL3KHLEHL_cjs.requireActivePlugin; }
20697
+ get: function () { return chunkKMM45BTY_cjs.requireActivePlugin; }
20226
20698
  });
20227
20699
  Object.defineProperty(exports, "requireActivePlugins", {
20228
20700
  enumerable: true,
20229
- get: function () { return chunkL3KHLEHL_cjs.requireActivePlugins; }
20701
+ get: function () { return chunkKMM45BTY_cjs.requireActivePlugins; }
20230
20702
  });
20231
20703
  Object.defineProperty(exports, "requireAnyPermission", {
20232
20704
  enumerable: true,
20233
- get: function () { return chunkL3KHLEHL_cjs.requireAnyPermission; }
20705
+ get: function () { return chunkKMM45BTY_cjs.requireAnyPermission; }
20234
20706
  });
20235
20707
  Object.defineProperty(exports, "requireAuth", {
20236
20708
  enumerable: true,
20237
- get: function () { return chunkL3KHLEHL_cjs.requireAuth; }
20709
+ get: function () { return chunkKMM45BTY_cjs.requireAuth; }
20238
20710
  });
20239
20711
  Object.defineProperty(exports, "requirePermission", {
20240
20712
  enumerable: true,
20241
- get: function () { return chunkL3KHLEHL_cjs.requirePermission; }
20713
+ get: function () { return chunkKMM45BTY_cjs.requirePermission; }
20242
20714
  });
20243
20715
  Object.defineProperty(exports, "requireRole", {
20244
20716
  enumerable: true,
20245
- get: function () { return chunkL3KHLEHL_cjs.requireRole; }
20717
+ get: function () { return chunkKMM45BTY_cjs.requireRole; }
20246
20718
  });
20247
20719
  Object.defineProperty(exports, "securityHeaders", {
20248
20720
  enumerable: true,
20249
- get: function () { return chunkL3KHLEHL_cjs.securityHeadersMiddleware; }
20721
+ get: function () { return chunkKMM45BTY_cjs.securityHeadersMiddleware; }
20250
20722
  });
20251
20723
  Object.defineProperty(exports, "securityLoggingMiddleware", {
20252
20724
  enumerable: true,
20253
- get: function () { return chunkL3KHLEHL_cjs.securityLoggingMiddleware; }
20725
+ get: function () { return chunkKMM45BTY_cjs.securityLoggingMiddleware; }
20726
+ });
20727
+ Object.defineProperty(exports, "DocumentsService", {
20728
+ enumerable: true,
20729
+ get: function () { return chunkW36OZTJ5_cjs.DocumentsService; }
20254
20730
  });
20255
20731
  Object.defineProperty(exports, "RbacService", {
20256
20732
  enumerable: true,
@@ -20258,35 +20734,35 @@ Object.defineProperty(exports, "RbacService", {
20258
20734
  });
20259
20735
  Object.defineProperty(exports, "PluginBootstrapService", {
20260
20736
  enumerable: true,
20261
- get: function () { return chunkWIV3R2MJ_cjs.PluginBootstrapService; }
20737
+ get: function () { return chunkKZIBF2EV_cjs.PluginBootstrapService; }
20262
20738
  });
20263
20739
  Object.defineProperty(exports, "PluginServiceClass", {
20264
20740
  enumerable: true,
20265
- get: function () { return chunkWIV3R2MJ_cjs.PluginService; }
20741
+ get: function () { return chunkKZIBF2EV_cjs.PluginService; }
20266
20742
  });
20267
20743
  Object.defineProperty(exports, "getAvailableCollectionNames", {
20268
20744
  enumerable: true,
20269
- get: function () { return chunkWIV3R2MJ_cjs.getAvailableCollectionNames; }
20745
+ get: function () { return chunkKZIBF2EV_cjs.getAvailableCollectionNames; }
20270
20746
  });
20271
20747
  Object.defineProperty(exports, "loadCollectionConfig", {
20272
20748
  enumerable: true,
20273
- get: function () { return chunkWIV3R2MJ_cjs.loadCollectionConfig; }
20749
+ get: function () { return chunkKZIBF2EV_cjs.loadCollectionConfig; }
20274
20750
  });
20275
20751
  Object.defineProperty(exports, "loadCollectionConfigs", {
20276
20752
  enumerable: true,
20277
- get: function () { return chunkWIV3R2MJ_cjs.loadCollectionConfigs; }
20753
+ get: function () { return chunkKZIBF2EV_cjs.loadCollectionConfigs; }
20278
20754
  });
20279
20755
  Object.defineProperty(exports, "registerCollections", {
20280
20756
  enumerable: true,
20281
- get: function () { return chunkWIV3R2MJ_cjs.registerCollections; }
20757
+ get: function () { return chunkKZIBF2EV_cjs.registerCollections; }
20282
20758
  });
20283
20759
  Object.defineProperty(exports, "validateCollectionConfig", {
20284
20760
  enumerable: true,
20285
- get: function () { return chunkWIV3R2MJ_cjs.validateCollectionConfig; }
20761
+ get: function () { return chunkKZIBF2EV_cjs.validateCollectionConfig; }
20286
20762
  });
20287
20763
  Object.defineProperty(exports, "MigrationService", {
20288
20764
  enumerable: true,
20289
- get: function () { return chunkH5FB6GKR_cjs.MigrationService; }
20765
+ get: function () { return chunkIA24HACT_cjs.MigrationService; }
20290
20766
  });
20291
20767
  Object.defineProperty(exports, "renderFilterBar", {
20292
20768
  enumerable: true,
@@ -20326,99 +20802,99 @@ Object.defineProperty(exports, "renderAdminLayoutCatalyst", {
20326
20802
  });
20327
20803
  Object.defineProperty(exports, "HookSystemImpl", {
20328
20804
  enumerable: true,
20329
- get: function () { return chunkG5LC7MYH_cjs.HookSystemImpl; }
20805
+ get: function () { return chunkLXYDJU6U_cjs.HookSystemImpl; }
20330
20806
  });
20331
20807
  Object.defineProperty(exports, "HookUtils", {
20332
20808
  enumerable: true,
20333
- get: function () { return chunkG5LC7MYH_cjs.HookUtils; }
20809
+ get: function () { return chunkLXYDJU6U_cjs.HookUtils; }
20334
20810
  });
20335
20811
  Object.defineProperty(exports, "PluginDependencyCycleError", {
20336
20812
  enumerable: true,
20337
- get: function () { return chunkG5LC7MYH_cjs.PluginDependencyCycleError; }
20813
+ get: function () { return chunkLXYDJU6U_cjs.PluginDependencyCycleError; }
20338
20814
  });
20339
20815
  Object.defineProperty(exports, "PluginManagerClass", {
20340
20816
  enumerable: true,
20341
- get: function () { return chunkG5LC7MYH_cjs.PluginManager; }
20817
+ get: function () { return chunkLXYDJU6U_cjs.PluginManager; }
20342
20818
  });
20343
20819
  Object.defineProperty(exports, "PluginRegistryImpl", {
20344
20820
  enumerable: true,
20345
- get: function () { return chunkG5LC7MYH_cjs.PluginRegistryImpl; }
20821
+ get: function () { return chunkLXYDJU6U_cjs.PluginRegistryImpl; }
20346
20822
  });
20347
20823
  Object.defineProperty(exports, "PluginValidatorClass", {
20348
20824
  enumerable: true,
20349
- get: function () { return chunkG5LC7MYH_cjs.PluginValidator; }
20825
+ get: function () { return chunkLXYDJU6U_cjs.PluginValidator; }
20350
20826
  });
20351
20827
  Object.defineProperty(exports, "RegisterPluginsError", {
20352
20828
  enumerable: true,
20353
- get: function () { return chunkG5LC7MYH_cjs.RegisterPluginsError; }
20829
+ get: function () { return chunkLXYDJU6U_cjs.RegisterPluginsError; }
20354
20830
  });
20355
20831
  Object.defineProperty(exports, "ScopedHookSystemClass", {
20356
20832
  enumerable: true,
20357
- get: function () { return chunkG5LC7MYH_cjs.ScopedHookSystem; }
20833
+ get: function () { return chunkLXYDJU6U_cjs.ScopedHookSystem; }
20358
20834
  });
20359
20835
  Object.defineProperty(exports, "collectCronSchedules", {
20360
20836
  enumerable: true,
20361
- get: function () { return chunkG5LC7MYH_cjs.collectCronSchedules; }
20837
+ get: function () { return chunkLXYDJU6U_cjs.collectCronSchedules; }
20362
20838
  });
20363
20839
  Object.defineProperty(exports, "collectCrons", {
20364
20840
  enumerable: true,
20365
- get: function () { return chunkG5LC7MYH_cjs.collectCrons; }
20841
+ get: function () { return chunkLXYDJU6U_cjs.collectCrons; }
20366
20842
  });
20367
20843
  Object.defineProperty(exports, "createScheduledHandler", {
20368
20844
  enumerable: true,
20369
- get: function () { return chunkG5LC7MYH_cjs.createScheduledHandler; }
20845
+ get: function () { return chunkLXYDJU6U_cjs.createScheduledHandler; }
20370
20846
  });
20371
20847
  Object.defineProperty(exports, "dispatchCronTick", {
20372
20848
  enumerable: true,
20373
- get: function () { return chunkG5LC7MYH_cjs.dispatchCronTick; }
20849
+ get: function () { return chunkLXYDJU6U_cjs.dispatchCronTick; }
20374
20850
  });
20375
20851
  Object.defineProperty(exports, "getPluginMenu", {
20376
20852
  enumerable: true,
20377
- get: function () { return chunkG5LC7MYH_cjs.getPluginMenu; }
20853
+ get: function () { return chunkLXYDJU6U_cjs.getPluginMenu; }
20378
20854
  });
20379
20855
  Object.defineProperty(exports, "registerPlugins", {
20380
20856
  enumerable: true,
20381
- get: function () { return chunkG5LC7MYH_cjs.registerPlugins; }
20857
+ get: function () { return chunkLXYDJU6U_cjs.registerPlugins; }
20382
20858
  });
20383
20859
  Object.defineProperty(exports, "resetPluginMenu", {
20384
20860
  enumerable: true,
20385
- get: function () { return chunkG5LC7MYH_cjs.resetPluginMenu; }
20861
+ get: function () { return chunkLXYDJU6U_cjs.resetPluginMenu; }
20386
20862
  });
20387
20863
  Object.defineProperty(exports, "resolvePluginMenuItems", {
20388
20864
  enumerable: true,
20389
- get: function () { return chunkG5LC7MYH_cjs.resolvePluginMenuItems; }
20865
+ get: function () { return chunkLXYDJU6U_cjs.resolvePluginMenuItems; }
20390
20866
  });
20391
20867
  Object.defineProperty(exports, "setPluginMenu", {
20392
20868
  enumerable: true,
20393
- get: function () { return chunkG5LC7MYH_cjs.setPluginMenu; }
20869
+ get: function () { return chunkLXYDJU6U_cjs.setPluginMenu; }
20394
20870
  });
20395
20871
  Object.defineProperty(exports, "topoSort", {
20396
20872
  enumerable: true,
20397
- get: function () { return chunkG5LC7MYH_cjs.topoSort; }
20873
+ get: function () { return chunkLXYDJU6U_cjs.topoSort; }
20398
20874
  });
20399
20875
  Object.defineProperty(exports, "applySchemaDefaults", {
20400
20876
  enumerable: true,
20401
- get: function () { return chunk4YRYGDCQ_cjs.applySchemaDefaults; }
20877
+ get: function () { return chunkKOXFYFOF_cjs.applySchemaDefaults; }
20402
20878
  });
20403
20879
  Object.defineProperty(exports, "definePlugin", {
20404
20880
  enumerable: true,
20405
- get: function () { return chunk4YRYGDCQ_cjs.definePlugin; }
20881
+ get: function () { return chunkKOXFYFOF_cjs.definePlugin; }
20406
20882
  });
20407
20883
  Object.defineProperty(exports, "isDefinedPlugin", {
20408
20884
  enumerable: true,
20409
- get: function () { return chunk4YRYGDCQ_cjs.isDefinedPlugin; }
20885
+ get: function () { return chunkKOXFYFOF_cjs.isDefinedPlugin; }
20410
20886
  });
20411
20887
  Object.defineProperty(exports, "parseConfigSchema", {
20412
20888
  enumerable: true,
20413
- get: function () { return chunk4YRYGDCQ_cjs.parseConfigSchema; }
20889
+ get: function () { return chunkKOXFYFOF_cjs.parseConfigSchema; }
20414
20890
  });
20415
20891
  Object.defineProperty(exports, "parseFormDataToSettings", {
20416
20892
  enumerable: true,
20417
- get: function () { return chunk4YRYGDCQ_cjs.parseFormDataToSettings; }
20893
+ get: function () { return chunkKOXFYFOF_cjs.parseFormDataToSettings; }
20418
20894
  });
20419
20895
  Object.defineProperty(exports, "renderSchemaFields", {
20420
20896
  enumerable: true,
20421
- get: function () { return chunk4YRYGDCQ_cjs.renderSchemaFields; }
20897
+ get: function () { return chunkKOXFYFOF_cjs.renderSchemaFields; }
20422
20898
  });
20423
20899
  Object.defineProperty(exports, "getHookSystem", {
20424
20900
  enumerable: true,
@@ -20466,11 +20942,11 @@ Object.defineProperty(exports, "metricsTracker", {
20466
20942
  });
20467
20943
  Object.defineProperty(exports, "SONICJS_VERSION", {
20468
20944
  enumerable: true,
20469
- get: function () { return chunkSIPBHWMG_cjs.SONICJS_VERSION; }
20945
+ get: function () { return chunk3XFA3E2F_cjs.SONICJS_VERSION; }
20470
20946
  });
20471
20947
  Object.defineProperty(exports, "getCoreVersion", {
20472
20948
  enumerable: true,
20473
- get: function () { return chunkSIPBHWMG_cjs.getCoreVersion; }
20949
+ get: function () { return chunk3XFA3E2F_cjs.getCoreVersion; }
20474
20950
  });
20475
20951
  Object.defineProperty(exports, "escapeHtml", {
20476
20952
  enumerable: true,
@@ -20493,11 +20969,13 @@ exports.CloudflareEmailProvider = CloudflareEmailProvider2;
20493
20969
  exports.OAuthService = OAuthService;
20494
20970
  exports.VERSION = VERSION;
20495
20971
  exports.createDb = createDb;
20972
+ exports.createHelloWorldPlugin = createHelloWorldPlugin;
20496
20973
  exports.createOAuthProvidersPlugin = createOAuthProvidersPlugin;
20497
20974
  exports.createRedirectPlugin = createRedirectPlugin;
20498
20975
  exports.createSonicJSApp = createSonicJSApp;
20499
20976
  exports.emailReconciliationPlugin = emailReconciliationPlugin;
20500
20977
  exports.generateTriggersComment = generateTriggersComment;
20978
+ exports.helloWorldPlugin = helloWorldPlugin;
20501
20979
  exports.oauthProvidersPlugin = oauthProvidersPlugin;
20502
20980
  exports.parseCronTriggers = parseCronTriggers;
20503
20981
  exports.redirectPlugin = redirectPlugin;