@sonicjs-cms/core 2.13.0 → 2.15.0

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 (83) hide show
  1. package/dist/admin-layout-catalyst.template-HFD37TY5.cjs +17 -0
  2. package/dist/admin-layout-catalyst.template-HFD37TY5.cjs.map +1 -0
  3. package/dist/admin-layout-catalyst.template-UMTIN66R.js +7 -0
  4. package/dist/admin-layout-catalyst.template-UMTIN66R.js.map +1 -0
  5. package/dist/{chunk-HVTSE2SF.cjs → chunk-26HYU7MX.cjs} +233 -660
  6. package/dist/chunk-26HYU7MX.cjs.map +1 -0
  7. package/dist/{chunk-DB2GJJTM.js → chunk-2BL2A62D.js} +4 -4
  8. package/dist/{chunk-DB2GJJTM.js.map → chunk-2BL2A62D.js.map} +1 -1
  9. package/dist/{chunk-I6FFGQIT.cjs → chunk-43AB4EH4.cjs} +723 -211
  10. package/dist/chunk-43AB4EH4.cjs.map +1 -0
  11. package/dist/{chunk-3QCEYJLK.cjs → chunk-4ZSNJDLS.cjs} +9 -9
  12. package/dist/{chunk-3QCEYJLK.cjs.map → chunk-4ZSNJDLS.cjs.map} +1 -1
  13. package/dist/chunk-55RDMDOP.js +684 -0
  14. package/dist/chunk-55RDMDOP.js.map +1 -0
  15. package/dist/{chunk-3VAKUFNQ.js → chunk-5SOFMH66.js} +22 -5
  16. package/dist/chunk-5SOFMH66.js.map +1 -0
  17. package/dist/{chunk-6FHNRRJ3.cjs → chunk-635JAMSE.cjs} +76 -17
  18. package/dist/chunk-635JAMSE.cjs.map +1 -0
  19. package/dist/{chunk-IYFSNRZN.js → chunk-7MMD5WMK.js} +49 -476
  20. package/dist/chunk-7MMD5WMK.js.map +1 -0
  21. package/dist/{chunk-56GUBLJE.cjs → chunk-ABB34XUS.cjs} +13 -13
  22. package/dist/{chunk-56GUBLJE.cjs.map → chunk-ABB34XUS.cjs.map} +1 -1
  23. package/dist/{chunk-CO4B5EYF.js → chunk-EWXV2KG2.js} +3 -3
  24. package/dist/{chunk-CO4B5EYF.js.map → chunk-EWXV2KG2.js.map} +1 -1
  25. package/dist/{chunk-J5WGMRSU.js → chunk-EXNEW5US.js} +76 -17
  26. package/dist/chunk-EXNEW5US.js.map +1 -0
  27. package/dist/{chunk-H3XXBAMO.js → chunk-G7XSN72O.js} +722 -212
  28. package/dist/chunk-G7XSN72O.js.map +1 -0
  29. package/dist/{chunk-QP3OHHON.cjs → chunk-OHYBNCVL.cjs} +18 -696
  30. package/dist/chunk-OHYBNCVL.cjs.map +1 -0
  31. package/dist/{chunk-CB7ONLGB.js → chunk-ON5ZMSU4.js} +3 -3
  32. package/dist/{chunk-CB7ONLGB.js.map → chunk-ON5ZMSU4.js.map} +1 -1
  33. package/dist/{chunk-SER23XI4.cjs → chunk-RVD7PLMU.cjs} +22 -5
  34. package/dist/chunk-RVD7PLMU.cjs.map +1 -0
  35. package/dist/{chunk-2MXF4RYZ.js → chunk-TFNTM3OA.js} +3 -3
  36. package/dist/{chunk-2MXF4RYZ.js.map → chunk-TFNTM3OA.js.map} +1 -1
  37. package/dist/{chunk-EGUDIX6Q.cjs → chunk-UFPT5KCQ.cjs} +8 -8
  38. package/dist/{chunk-EGUDIX6Q.cjs.map → chunk-UFPT5KCQ.cjs.map} +1 -1
  39. package/dist/chunk-UYJ6TJHX.cjs +691 -0
  40. package/dist/chunk-UYJ6TJHX.cjs.map +1 -0
  41. package/dist/{chunk-XCP5GCBE.cjs → chunk-VUISYUHY.cjs} +3 -3
  42. package/dist/{chunk-XCP5GCBE.cjs.map → chunk-VUISYUHY.cjs.map} +1 -1
  43. package/dist/{chunk-JTUCC6WZ.js → chunk-XWIA3HVX.js} +9 -683
  44. package/dist/chunk-XWIA3HVX.js.map +1 -0
  45. package/dist/index.cjs +1604 -173
  46. package/dist/index.cjs.map +1 -1
  47. package/dist/index.d.cts +2 -2
  48. package/dist/index.d.ts +2 -2
  49. package/dist/index.js +1461 -30
  50. package/dist/index.js.map +1 -1
  51. package/dist/middleware.cjs +29 -29
  52. package/dist/middleware.js +3 -3
  53. package/dist/migrations-APFGYCB6.cjs +13 -0
  54. package/dist/{migrations-GMHTJI7D.cjs.map → migrations-APFGYCB6.cjs.map} +1 -1
  55. package/dist/migrations-YB52SLW7.js +4 -0
  56. package/dist/{migrations-IVFIDOSO.js.map → migrations-YB52SLW7.js.map} +1 -1
  57. package/dist/{plugin-bootstrap-DVGLQrcO.d.cts → plugin-bootstrap-DfVerYV4.d.cts} +3 -1
  58. package/dist/{plugin-bootstrap-CZ1GDum7.d.ts → plugin-bootstrap-P_ciLp_C.d.ts} +3 -1
  59. package/dist/plugins.cjs +11 -11
  60. package/dist/plugins.js +2 -2
  61. package/dist/routes.cjs +31 -30
  62. package/dist/routes.js +8 -7
  63. package/dist/services.cjs +23 -23
  64. package/dist/services.d.cts +1 -1
  65. package/dist/services.d.ts +1 -1
  66. package/dist/services.js +2 -2
  67. package/dist/templates.cjs +26 -25
  68. package/dist/templates.js +3 -2
  69. package/dist/utils.cjs +11 -11
  70. package/dist/utils.js +1 -1
  71. package/package.json +1 -1
  72. package/dist/chunk-3VAKUFNQ.js.map +0 -1
  73. package/dist/chunk-6FHNRRJ3.cjs.map +0 -1
  74. package/dist/chunk-H3XXBAMO.js.map +0 -1
  75. package/dist/chunk-HVTSE2SF.cjs.map +0 -1
  76. package/dist/chunk-I6FFGQIT.cjs.map +0 -1
  77. package/dist/chunk-IYFSNRZN.js.map +0 -1
  78. package/dist/chunk-J5WGMRSU.js.map +0 -1
  79. package/dist/chunk-JTUCC6WZ.js.map +0 -1
  80. package/dist/chunk-QP3OHHON.cjs.map +0 -1
  81. package/dist/chunk-SER23XI4.cjs.map +0 -1
  82. package/dist/migrations-GMHTJI7D.cjs +0 -13
  83. package/dist/migrations-IVFIDOSO.js +0 -4
package/dist/index.cjs CHANGED
@@ -1,15 +1,16 @@
1
1
  'use strict';
2
2
 
3
- var chunkHVTSE2SF_cjs = require('./chunk-HVTSE2SF.cjs');
3
+ var chunk26HYU7MX_cjs = require('./chunk-26HYU7MX.cjs');
4
4
  var chunkNZWFCUDA_cjs = require('./chunk-NZWFCUDA.cjs');
5
- var chunkEGUDIX6Q_cjs = require('./chunk-EGUDIX6Q.cjs');
6
- var chunkI6FFGQIT_cjs = require('./chunk-I6FFGQIT.cjs');
7
- var chunkSER23XI4_cjs = require('./chunk-SER23XI4.cjs');
8
- var chunk3QCEYJLK_cjs = require('./chunk-3QCEYJLK.cjs');
9
- var chunkQP3OHHON_cjs = require('./chunk-QP3OHHON.cjs');
10
- var chunk56GUBLJE_cjs = require('./chunk-56GUBLJE.cjs');
11
- var chunk6FHNRRJ3_cjs = require('./chunk-6FHNRRJ3.cjs');
12
- var chunkXCP5GCBE_cjs = require('./chunk-XCP5GCBE.cjs');
5
+ var chunkUFPT5KCQ_cjs = require('./chunk-UFPT5KCQ.cjs');
6
+ var chunk43AB4EH4_cjs = require('./chunk-43AB4EH4.cjs');
7
+ var chunkRVD7PLMU_cjs = require('./chunk-RVD7PLMU.cjs');
8
+ var chunk4ZSNJDLS_cjs = require('./chunk-4ZSNJDLS.cjs');
9
+ var chunkOHYBNCVL_cjs = require('./chunk-OHYBNCVL.cjs');
10
+ var chunkUYJ6TJHX_cjs = require('./chunk-UYJ6TJHX.cjs');
11
+ var chunkABB34XUS_cjs = require('./chunk-ABB34XUS.cjs');
12
+ var chunk635JAMSE_cjs = require('./chunk-635JAMSE.cjs');
13
+ var chunkVUISYUHY_cjs = require('./chunk-VUISYUHY.cjs');
13
14
  require('./chunk-P3XDZL6Q.cjs');
14
15
  var chunkRCQ2HIQD_cjs = require('./chunk-RCQ2HIQD.cjs');
15
16
  var chunkMNWKYY5E_cjs = require('./chunk-MNWKYY5E.cjs');
@@ -235,7 +236,7 @@ var DatabaseToolsService = class {
235
236
  };
236
237
 
237
238
  // src/templates/pages/admin-database-table.template.ts
238
- chunkQP3OHHON_cjs.init_admin_layout_catalyst_template();
239
+ chunkUYJ6TJHX_cjs.init_admin_layout_catalyst_template();
239
240
  function renderDatabaseTablePage(data) {
240
241
  const totalPages = Math.ceil(data.totalRows / data.pageSize);
241
242
  const startRow = (data.currentPage - 1) * data.pageSize + 1;
@@ -484,7 +485,7 @@ function renderDatabaseTablePage(data) {
484
485
  user: data.user,
485
486
  content: pageContent
486
487
  };
487
- return chunkQP3OHHON_cjs.renderAdminLayoutCatalyst(layoutData);
488
+ return chunkUYJ6TJHX_cjs.renderAdminLayoutCatalyst(layoutData);
488
489
  }
489
490
  function generatePageNumbers(currentPage, totalPages) {
490
491
  const pages = [];
@@ -559,7 +560,7 @@ function formatCellValue(value) {
559
560
  // src/plugins/core-plugins/database-tools-plugin/admin-routes.ts
560
561
  function createDatabaseToolsAdminRoutes() {
561
562
  const router3 = new hono.Hono();
562
- router3.use("*", chunkEGUDIX6Q_cjs.requireAuth());
563
+ router3.use("*", chunkUFPT5KCQ_cjs.requireAuth());
563
564
  router3.get("/api/stats", async (c) => {
564
565
  try {
565
566
  const user = c.get("user");
@@ -1307,7 +1308,7 @@ function createSeedDataAdminRoutes() {
1307
1308
  return routes;
1308
1309
  }
1309
1310
  function createEmailPlugin() {
1310
- const builder = chunk6FHNRRJ3_cjs.PluginBuilder.create({
1311
+ const builder = chunk635JAMSE_cjs.PluginBuilder.create({
1311
1312
  name: "email",
1312
1313
  version: "1.0.0-beta.1",
1313
1314
  description: "Send transactional emails using Resend"
@@ -1736,7 +1737,7 @@ var DEFAULT_SETTINGS = {
1736
1737
  allowNewUserRegistration: false
1737
1738
  };
1738
1739
  function createOTPLoginPlugin() {
1739
- const builder = chunk6FHNRRJ3_cjs.PluginBuilder.create({
1740
+ const builder = chunk635JAMSE_cjs.PluginBuilder.create({
1740
1741
  name: "otp-login",
1741
1742
  version: "1.0.0-beta.1",
1742
1743
  description: "Passwordless authentication via email one-time codes"
@@ -1938,7 +1939,7 @@ function createOTPLoginPlugin() {
1938
1939
  error: "Account is deactivated"
1939
1940
  }, 403);
1940
1941
  }
1941
- const token = await chunkEGUDIX6Q_cjs.AuthManager.generateToken(user.id, user.email, user.role, c.env.JWT_SECRET);
1942
+ const token = await chunkUFPT5KCQ_cjs.AuthManager.generateToken(user.id, user.email, user.role, c.env.JWT_SECRET);
1942
1943
  cookie.setCookie(c, "auth_token", token, {
1943
1944
  httpOnly: true,
1944
1945
  secure: true,
@@ -2272,7 +2273,7 @@ var OAuthService = class {
2272
2273
  var STATE_COOKIE_NAME = "oauth_state";
2273
2274
  var STATE_COOKIE_MAX_AGE = 600;
2274
2275
  function createOAuthProvidersPlugin() {
2275
- const builder = chunk6FHNRRJ3_cjs.PluginBuilder.create({
2276
+ const builder = chunk635JAMSE_cjs.PluginBuilder.create({
2276
2277
  name: "oauth-providers",
2277
2278
  version: "1.0.0-beta.1",
2278
2279
  description: "OAuth2/OIDC social login with GitHub, Google, and more"
@@ -2408,13 +2409,13 @@ function createOAuthProvidersPlugin() {
2408
2409
  if (!user || !user.is_active) {
2409
2410
  return c.redirect("/auth/login?error=Account is deactivated");
2410
2411
  }
2411
- const jwt2 = await chunkEGUDIX6Q_cjs.AuthManager.generateToken(
2412
+ const jwt2 = await chunkUFPT5KCQ_cjs.AuthManager.generateToken(
2412
2413
  user.id,
2413
2414
  user.email,
2414
2415
  user.role,
2415
2416
  c.env.JWT_SECRET
2416
2417
  );
2417
- chunkEGUDIX6Q_cjs.AuthManager.setAuthCookie(c, jwt2, { sameSite: "Lax" });
2418
+ chunkUFPT5KCQ_cjs.AuthManager.setAuthCookie(c, jwt2, { sameSite: "Lax" });
2418
2419
  return c.redirect("/admin");
2419
2420
  }
2420
2421
  const existingUser = await oauthService.findUserByEmail(profile.email);
@@ -2431,13 +2432,13 @@ function createOAuthProvidersPlugin() {
2431
2432
  tokenExpiresAt: tokenExpiresAt ?? void 0,
2432
2433
  profileData: JSON.stringify(profile)
2433
2434
  });
2434
- const jwt2 = await chunkEGUDIX6Q_cjs.AuthManager.generateToken(
2435
+ const jwt2 = await chunkUFPT5KCQ_cjs.AuthManager.generateToken(
2435
2436
  existingUser.id,
2436
2437
  existingUser.email,
2437
2438
  existingUser.role,
2438
2439
  c.env.JWT_SECRET
2439
2440
  );
2440
- chunkEGUDIX6Q_cjs.AuthManager.setAuthCookie(c, jwt2, { sameSite: "Lax" });
2441
+ chunkUFPT5KCQ_cjs.AuthManager.setAuthCookie(c, jwt2, { sameSite: "Lax" });
2441
2442
  return c.redirect("/admin");
2442
2443
  }
2443
2444
  const newUserId = await oauthService.createUserFromOAuth(profile);
@@ -2450,13 +2451,13 @@ function createOAuthProvidersPlugin() {
2450
2451
  tokenExpiresAt: tokenExpiresAt ?? void 0,
2451
2452
  profileData: JSON.stringify(profile)
2452
2453
  });
2453
- const jwt = await chunkEGUDIX6Q_cjs.AuthManager.generateToken(
2454
+ const jwt = await chunkUFPT5KCQ_cjs.AuthManager.generateToken(
2454
2455
  newUserId,
2455
2456
  profile.email.toLowerCase(),
2456
2457
  "viewer",
2457
2458
  c.env.JWT_SECRET
2458
2459
  );
2459
- chunkEGUDIX6Q_cjs.AuthManager.setAuthCookie(c, jwt, { sameSite: "Lax" });
2460
+ chunkUFPT5KCQ_cjs.AuthManager.setAuthCookie(c, jwt, { sameSite: "Lax" });
2460
2461
  return c.redirect("/admin");
2461
2462
  } catch (error) {
2462
2463
  console.error("OAuth callback error:", error);
@@ -3896,7 +3897,7 @@ function renderSettingsPage(data) {
3896
3897
  const indexStatusMap = data.indexStatus || {};
3897
3898
  const status = indexStatusMap[collectionId];
3898
3899
  const isNew = collection.is_new === true && !isDismissed && !status;
3899
- const statusBadge = status && isChecked ? `<span class="ml-2 px-2 py-1 text-xs rounded-full ${status.status === "completed" ? "bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-300" : status.status === "indexing" ? "bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-300" : status.status === "error" ? "bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-300" : "bg-gray-100 text-gray-800 dark:bg-gray-800 dark:text-gray-300"}">${status.status}</span>` : "";
3900
+ const statusBadge2 = status && isChecked ? `<span class="ml-2 px-2 py-1 text-xs rounded-full ${status.status === "completed" ? "bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-300" : status.status === "indexing" ? "bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-300" : status.status === "error" ? "bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-300" : "bg-gray-100 text-gray-800 dark:bg-gray-800 dark:text-gray-300"}">${status.status}</span>` : "";
3900
3901
  return `<div class="flex items-start gap-3 p-3 rounded-lg border border-zinc-200 dark:border-zinc-700 ${isNew ? "bg-blue-50 dark:bg-blue-900/10 border-blue-200 dark:border-blue-800" : "hover:bg-zinc-50 dark:hover:bg-zinc-800"}">
3901
3902
  <input
3902
3903
  type="checkbox"
@@ -3911,7 +3912,7 @@ function renderSettingsPage(data) {
3911
3912
  <label for="collection_${collectionId}" class="text-sm font-medium text-zinc-950 dark:text-white select-none cursor-pointer flex items-center">
3912
3913
  ${collection.display_name || collection.name || "Unnamed Collection"}
3913
3914
  ${isNew ? '<span class="ml-2 px-2 py-0.5 text-xs rounded-full bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-300">NEW</span>' : ""}
3914
- ${statusBadge}
3915
+ ${statusBadge2}
3915
3916
  </label>
3916
3917
  <p class="text-xs text-zinc-500 dark:text-zinc-400 mt-1">
3917
3918
  ${collection.description || collection.name || "No description"} \u2022 ${collection.item_count || 0} items
@@ -4138,7 +4139,7 @@ function renderSettingsPage(data) {
4138
4139
  }, 30000);
4139
4140
  </script>
4140
4141
  `;
4141
- return chunkQP3OHHON_cjs.renderAdminLayout({
4142
+ return chunkOHYBNCVL_cjs.renderAdminLayout({
4142
4143
  title: "AI Search Settings",
4143
4144
  pageTitle: "AI Search Settings",
4144
4145
  currentPath: "/admin/plugins/ai-search/settings",
@@ -4149,7 +4150,7 @@ function renderSettingsPage(data) {
4149
4150
 
4150
4151
  // src/plugins/core-plugins/ai-search-plugin/routes/admin.ts
4151
4152
  var adminRoutes = new hono.Hono();
4152
- adminRoutes.use("*", chunkEGUDIX6Q_cjs.requireAuth());
4153
+ adminRoutes.use("*", chunkUFPT5KCQ_cjs.requireAuth());
4153
4154
  adminRoutes.get("/", async (c) => {
4154
4155
  try {
4155
4156
  const user = c.get("user");
@@ -4395,7 +4396,7 @@ var manifest_default = {
4395
4396
  author: "SonicJS"};
4396
4397
 
4397
4398
  // src/plugins/core-plugins/ai-search-plugin/index.ts
4398
- var aiSearchPlugin = new chunk6FHNRRJ3_cjs.PluginBuilder({
4399
+ var aiSearchPlugin = new chunk635JAMSE_cjs.PluginBuilder({
4399
4400
  name: manifest_default.name,
4400
4401
  version: manifest_default.version,
4401
4402
  description: manifest_default.description,
@@ -4550,13 +4551,13 @@ function createMagicLinkAuthPlugin() {
4550
4551
  SET used = 1, used_at = ?
4551
4552
  WHERE id = ?
4552
4553
  `).bind(Date.now(), magicLink.id).run();
4553
- const jwtToken = await chunkEGUDIX6Q_cjs.AuthManager.generateToken(
4554
+ const jwtToken = await chunkUFPT5KCQ_cjs.AuthManager.generateToken(
4554
4555
  user.id,
4555
4556
  user.email,
4556
4557
  user.role,
4557
4558
  c.env.JWT_SECRET
4558
4559
  );
4559
- chunkEGUDIX6Q_cjs.AuthManager.setAuthCookie(c, jwtToken);
4560
+ chunkUFPT5KCQ_cjs.AuthManager.setAuthCookie(c, jwtToken);
4560
4561
  await db.prepare(`
4561
4562
  UPDATE users SET last_login_at = ? WHERE id = ?
4562
4563
  `).bind(Date.now(), user.id).run();
@@ -4994,7 +4995,7 @@ var SecurityAuditService = class {
4994
4995
  };
4995
4996
 
4996
4997
  // src/plugins/core-plugins/security-audit-plugin/components/dashboard-page.ts
4997
- chunkQP3OHHON_cjs.init_admin_layout_catalyst_template();
4998
+ chunkUYJ6TJHX_cjs.init_admin_layout_catalyst_template();
4998
4999
  function formatTimestamp(ts) {
4999
5000
  const date = new Date(ts);
5000
5001
  const now = Date.now();
@@ -5193,11 +5194,11 @@ function renderSecurityDashboard(data) {
5193
5194
  version,
5194
5195
  dynamicMenuItems
5195
5196
  };
5196
- return chunkQP3OHHON_cjs.renderAdminLayoutCatalyst(layoutData);
5197
+ return chunkUYJ6TJHX_cjs.renderAdminLayoutCatalyst(layoutData);
5197
5198
  }
5198
5199
 
5199
5200
  // src/plugins/core-plugins/security-audit-plugin/components/event-log-page.ts
5200
- chunkQP3OHHON_cjs.init_admin_layout_catalyst_template();
5201
+ chunkUYJ6TJHX_cjs.init_admin_layout_catalyst_template();
5201
5202
  function formatTimestamp2(ts) {
5202
5203
  const date = new Date(ts);
5203
5204
  return date.toLocaleDateString("en-US", {
@@ -5404,11 +5405,11 @@ function renderEventLogPage(data) {
5404
5405
  version,
5405
5406
  dynamicMenuItems
5406
5407
  };
5407
- return chunkQP3OHHON_cjs.renderAdminLayoutCatalyst(layoutData);
5408
+ return chunkUYJ6TJHX_cjs.renderAdminLayoutCatalyst(layoutData);
5408
5409
  }
5409
5410
 
5410
5411
  // src/plugins/core-plugins/security-audit-plugin/components/settings-page.ts
5411
- chunkQP3OHHON_cjs.init_admin_layout_catalyst_template();
5412
+ chunkUYJ6TJHX_cjs.init_admin_layout_catalyst_template();
5412
5413
  function renderSecuritySettingsPage(data) {
5413
5414
  const { settings, user, version, message, dynamicMenuItems } = data;
5414
5415
  const content2 = `
@@ -5561,12 +5562,12 @@ function renderSecuritySettingsPage(data) {
5561
5562
  version,
5562
5563
  dynamicMenuItems
5563
5564
  };
5564
- return chunkQP3OHHON_cjs.renderAdminLayoutCatalyst(layoutData);
5565
+ return chunkUYJ6TJHX_cjs.renderAdminLayoutCatalyst(layoutData);
5565
5566
  }
5566
5567
 
5567
5568
  // src/plugins/core-plugins/security-audit-plugin/routes/admin.ts
5568
5569
  var adminRoutes2 = new hono.Hono();
5569
- adminRoutes2.use("*", chunkEGUDIX6Q_cjs.requireAuth());
5570
+ adminRoutes2.use("*", chunkUFPT5KCQ_cjs.requireAuth());
5570
5571
  adminRoutes2.use("*", async (c, next) => {
5571
5572
  const user = c.get("user");
5572
5573
  if (user?.role !== "admin") {
@@ -5576,7 +5577,7 @@ adminRoutes2.use("*", async (c, next) => {
5576
5577
  });
5577
5578
  async function getSettings(db) {
5578
5579
  try {
5579
- const pluginService = new chunkI6FFGQIT_cjs.PluginService(db);
5580
+ const pluginService = new chunk43AB4EH4_cjs.PluginService(db);
5580
5581
  const plugin2 = await pluginService.getPlugin("security-audit");
5581
5582
  if (plugin2?.settings) {
5582
5583
  const settings = typeof plugin2.settings === "string" ? JSON.parse(plugin2.settings) : plugin2.settings;
@@ -5681,7 +5682,7 @@ adminRoutes2.post("/settings", async (c) => {
5681
5682
  autoPurge: body["retention.autoPurge"] === "true"
5682
5683
  }
5683
5684
  };
5684
- const pluginService = new chunkI6FFGQIT_cjs.PluginService(db);
5685
+ const pluginService = new chunk43AB4EH4_cjs.PluginService(db);
5685
5686
  await pluginService.updatePluginSettings("security-audit", settings);
5686
5687
  if (c.req.header("HX-Request")) {
5687
5688
  return c.json({ success: true });
@@ -5836,7 +5837,7 @@ var BruteForceDetector = class {
5836
5837
 
5837
5838
  // src/plugins/core-plugins/security-audit-plugin/routes/api.ts
5838
5839
  var apiRoutes2 = new hono.Hono();
5839
- apiRoutes2.use("*", chunkEGUDIX6Q_cjs.requireAuth());
5840
+ apiRoutes2.use("*", chunkUFPT5KCQ_cjs.requireAuth());
5840
5841
  apiRoutes2.use("*", async (c, next) => {
5841
5842
  const user = c.get("user");
5842
5843
  if (user?.role !== "admin") {
@@ -5846,7 +5847,7 @@ apiRoutes2.use("*", async (c, next) => {
5846
5847
  });
5847
5848
  async function getSettings2(db) {
5848
5849
  try {
5849
- const pluginService = new chunkI6FFGQIT_cjs.PluginService(db);
5850
+ const pluginService = new chunk43AB4EH4_cjs.PluginService(db);
5850
5851
  const plugin2 = await pluginService.getPlugin("security-audit");
5851
5852
  if (plugin2?.settings) {
5852
5853
  const settings = typeof plugin2.settings === "string" ? JSON.parse(plugin2.settings) : plugin2.settings;
@@ -5994,7 +5995,7 @@ function generateFingerprint(ip, userAgent) {
5994
5995
  }
5995
5996
  async function getPluginSettings(db) {
5996
5997
  try {
5997
- const pluginService = new chunkI6FFGQIT_cjs.PluginService(db);
5998
+ const pluginService = new chunk43AB4EH4_cjs.PluginService(db);
5998
5999
  const plugin2 = await pluginService.getPlugin("security-audit");
5999
6000
  if (plugin2?.settings) {
6000
6001
  const settings = typeof plugin2.settings === "string" ? JSON.parse(plugin2.settings) : plugin2.settings;
@@ -6225,7 +6226,7 @@ async function logAuthEvent(c, db, settings, ip, userAgent, countryCode, fingerp
6225
6226
 
6226
6227
  // src/plugins/core-plugins/security-audit-plugin/index.ts
6227
6228
  function createSecurityAuditPlugin() {
6228
- const builder = chunk6FHNRRJ3_cjs.PluginBuilder.create({
6229
+ const builder = chunk635JAMSE_cjs.PluginBuilder.create({
6229
6230
  name: "security-audit",
6230
6231
  version: "1.0.0-beta.1",
6231
6232
  description: "Security event logging, brute-force detection, and analytics dashboard"
@@ -6266,14 +6267,1434 @@ function createSecurityAuditPlugin() {
6266
6267
  }
6267
6268
  var securityAuditPlugin = createSecurityAuditPlugin();
6268
6269
 
6269
- // src/middleware/plugin-menu.ts
6270
- var MENU_PLUGINS = [
6271
- securityAuditPlugin
6270
+ // src/plugins/core-plugins/stripe-plugin/services/subscription-service.ts
6271
+ var SubscriptionService = class {
6272
+ constructor(db) {
6273
+ this.db = db;
6274
+ }
6275
+ /**
6276
+ * Ensure the subscriptions table exists
6277
+ */
6278
+ async ensureTable() {
6279
+ await this.db.prepare(`
6280
+ CREATE TABLE IF NOT EXISTS subscriptions (
6281
+ id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
6282
+ user_id TEXT NOT NULL,
6283
+ stripe_customer_id TEXT NOT NULL,
6284
+ stripe_subscription_id TEXT NOT NULL UNIQUE,
6285
+ stripe_price_id TEXT NOT NULL,
6286
+ status TEXT NOT NULL DEFAULT 'incomplete',
6287
+ current_period_start INTEGER NOT NULL DEFAULT 0,
6288
+ current_period_end INTEGER NOT NULL DEFAULT 0,
6289
+ cancel_at_period_end INTEGER NOT NULL DEFAULT 0,
6290
+ created_at INTEGER NOT NULL DEFAULT (unixepoch()),
6291
+ updated_at INTEGER NOT NULL DEFAULT (unixepoch())
6292
+ )
6293
+ `).run();
6294
+ await this.db.prepare(`
6295
+ CREATE INDEX IF NOT EXISTS idx_subscriptions_user_id ON subscriptions(user_id)
6296
+ `).run();
6297
+ await this.db.prepare(`
6298
+ CREATE INDEX IF NOT EXISTS idx_subscriptions_stripe_customer_id ON subscriptions(stripe_customer_id)
6299
+ `).run();
6300
+ await this.db.prepare(`
6301
+ CREATE INDEX IF NOT EXISTS idx_subscriptions_stripe_subscription_id ON subscriptions(stripe_subscription_id)
6302
+ `).run();
6303
+ await this.db.prepare(`
6304
+ CREATE INDEX IF NOT EXISTS idx_subscriptions_status ON subscriptions(status)
6305
+ `).run();
6306
+ }
6307
+ /**
6308
+ * Create a new subscription record
6309
+ */
6310
+ async create(data) {
6311
+ const result = await this.db.prepare(`
6312
+ INSERT INTO subscriptions (user_id, stripe_customer_id, stripe_subscription_id, stripe_price_id, status, current_period_start, current_period_end, cancel_at_period_end)
6313
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)
6314
+ RETURNING *
6315
+ `).bind(
6316
+ data.userId,
6317
+ data.stripeCustomerId,
6318
+ data.stripeSubscriptionId,
6319
+ data.stripePriceId,
6320
+ data.status,
6321
+ data.currentPeriodStart,
6322
+ data.currentPeriodEnd,
6323
+ data.cancelAtPeriodEnd ? 1 : 0
6324
+ ).first();
6325
+ return this.mapRow(result);
6326
+ }
6327
+ /**
6328
+ * Upsert a subscription by stripe_subscription_id (INSERT or UPDATE on conflict)
6329
+ */
6330
+ async upsert(data) {
6331
+ const result = await this.db.prepare(`
6332
+ INSERT INTO subscriptions (user_id, stripe_customer_id, stripe_subscription_id, stripe_price_id, status, current_period_start, current_period_end, cancel_at_period_end)
6333
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)
6334
+ ON CONFLICT(stripe_subscription_id) DO UPDATE SET
6335
+ status = excluded.status,
6336
+ stripe_price_id = excluded.stripe_price_id,
6337
+ current_period_start = excluded.current_period_start,
6338
+ current_period_end = excluded.current_period_end,
6339
+ cancel_at_period_end = excluded.cancel_at_period_end,
6340
+ updated_at = unixepoch()
6341
+ RETURNING *
6342
+ `).bind(
6343
+ data.userId,
6344
+ data.stripeCustomerId,
6345
+ data.stripeSubscriptionId,
6346
+ data.stripePriceId,
6347
+ data.status,
6348
+ data.currentPeriodStart,
6349
+ data.currentPeriodEnd,
6350
+ data.cancelAtPeriodEnd ? 1 : 0
6351
+ ).first();
6352
+ return this.mapRow(result);
6353
+ }
6354
+ /**
6355
+ * Update a subscription by its Stripe subscription ID
6356
+ */
6357
+ async updateByStripeId(stripeSubscriptionId, data) {
6358
+ const sets = [];
6359
+ const values = [];
6360
+ if (data.status !== void 0) {
6361
+ sets.push("status = ?");
6362
+ values.push(data.status);
6363
+ }
6364
+ if (data.stripePriceId !== void 0) {
6365
+ sets.push("stripe_price_id = ?");
6366
+ values.push(data.stripePriceId);
6367
+ }
6368
+ if (data.currentPeriodStart !== void 0) {
6369
+ sets.push("current_period_start = ?");
6370
+ values.push(data.currentPeriodStart);
6371
+ }
6372
+ if (data.currentPeriodEnd !== void 0) {
6373
+ sets.push("current_period_end = ?");
6374
+ values.push(data.currentPeriodEnd);
6375
+ }
6376
+ if (data.cancelAtPeriodEnd !== void 0) {
6377
+ sets.push("cancel_at_period_end = ?");
6378
+ values.push(data.cancelAtPeriodEnd ? 1 : 0);
6379
+ }
6380
+ if (sets.length === 0) return this.getByStripeSubscriptionId(stripeSubscriptionId);
6381
+ sets.push("updated_at = unixepoch()");
6382
+ values.push(stripeSubscriptionId);
6383
+ const result = await this.db.prepare(`
6384
+ UPDATE subscriptions SET ${sets.join(", ")} WHERE stripe_subscription_id = ? RETURNING *
6385
+ `).bind(...values).first();
6386
+ return result ? this.mapRow(result) : null;
6387
+ }
6388
+ /**
6389
+ * Get subscription by Stripe subscription ID
6390
+ */
6391
+ async getByStripeSubscriptionId(stripeSubscriptionId) {
6392
+ const result = await this.db.prepare(
6393
+ "SELECT * FROM subscriptions WHERE stripe_subscription_id = ?"
6394
+ ).bind(stripeSubscriptionId).first();
6395
+ return result ? this.mapRow(result) : null;
6396
+ }
6397
+ /**
6398
+ * Get the active subscription for a user
6399
+ */
6400
+ async getByUserId(userId) {
6401
+ const result = await this.db.prepare(
6402
+ "SELECT * FROM subscriptions WHERE user_id = ? ORDER BY CASE WHEN status = 'active' THEN 0 WHEN status = 'trialing' THEN 1 ELSE 2 END, updated_at DESC LIMIT 1"
6403
+ ).bind(userId).first();
6404
+ return result ? this.mapRow(result) : null;
6405
+ }
6406
+ /**
6407
+ * Get subscription by Stripe customer ID
6408
+ */
6409
+ async getByStripeCustomerId(stripeCustomerId) {
6410
+ const result = await this.db.prepare(
6411
+ "SELECT * FROM subscriptions WHERE stripe_customer_id = ? ORDER BY updated_at DESC LIMIT 1"
6412
+ ).bind(stripeCustomerId).first();
6413
+ return result ? this.mapRow(result) : null;
6414
+ }
6415
+ /**
6416
+ * Find the userId linked to a Stripe customer ID
6417
+ */
6418
+ async getUserIdByStripeCustomer(stripeCustomerId) {
6419
+ const result = await this.db.prepare(
6420
+ "SELECT user_id FROM subscriptions WHERE stripe_customer_id = ? LIMIT 1"
6421
+ ).bind(stripeCustomerId).first();
6422
+ return result?.user_id ?? null;
6423
+ }
6424
+ /**
6425
+ * List subscriptions with filters and pagination
6426
+ */
6427
+ async list(filters = {}) {
6428
+ const where = [];
6429
+ const values = [];
6430
+ if (filters.status) {
6431
+ where.push("status = ?");
6432
+ values.push(filters.status);
6433
+ }
6434
+ if (filters.userId) {
6435
+ where.push("user_id = ?");
6436
+ values.push(filters.userId);
6437
+ }
6438
+ if (filters.stripeCustomerId) {
6439
+ where.push("stripe_customer_id = ?");
6440
+ values.push(filters.stripeCustomerId);
6441
+ }
6442
+ const whereClause = where.length > 0 ? `WHERE ${where.join(" AND ")}` : "";
6443
+ const sortBy = filters.sortBy || "created_at";
6444
+ const sortOrder = filters.sortOrder || "desc";
6445
+ const limit = Math.min(filters.limit || 50, 100);
6446
+ const page = filters.page || 1;
6447
+ const offset = (page - 1) * limit;
6448
+ const countResult = await this.db.prepare(
6449
+ `SELECT COUNT(*) as count FROM subscriptions ${whereClause}`
6450
+ ).bind(...values).first();
6451
+ const results = await this.db.prepare(
6452
+ `SELECT s.*, u.email as user_email FROM subscriptions s LEFT JOIN users u ON s.user_id = u.id ${whereClause} ORDER BY ${sortBy} ${sortOrder} LIMIT ? OFFSET ?`
6453
+ ).bind(...values, limit, offset).all();
6454
+ return {
6455
+ subscriptions: (results.results || []).map((r) => this.mapRow(r)),
6456
+ total: countResult?.count || 0
6457
+ };
6458
+ }
6459
+ /**
6460
+ * Get subscription stats
6461
+ */
6462
+ async getStats() {
6463
+ const result = await this.db.prepare(`
6464
+ SELECT
6465
+ COUNT(*) as total,
6466
+ SUM(CASE WHEN status = 'active' THEN 1 ELSE 0 END) as active,
6467
+ SUM(CASE WHEN status = 'canceled' THEN 1 ELSE 0 END) as canceled,
6468
+ SUM(CASE WHEN status = 'past_due' THEN 1 ELSE 0 END) as past_due,
6469
+ SUM(CASE WHEN status = 'trialing' THEN 1 ELSE 0 END) as trialing
6470
+ FROM subscriptions
6471
+ `).first();
6472
+ return {
6473
+ total: result?.total || 0,
6474
+ active: result?.active || 0,
6475
+ canceled: result?.canceled || 0,
6476
+ pastDue: result?.past_due || 0,
6477
+ trialing: result?.trialing || 0
6478
+ };
6479
+ }
6480
+ /**
6481
+ * Delete a subscription record by Stripe subscription ID
6482
+ */
6483
+ async deleteByStripeId(stripeSubscriptionId) {
6484
+ const result = await this.db.prepare(
6485
+ "DELETE FROM subscriptions WHERE stripe_subscription_id = ?"
6486
+ ).bind(stripeSubscriptionId).run();
6487
+ return (result.meta?.changes || 0) > 0;
6488
+ }
6489
+ mapRow(row) {
6490
+ return {
6491
+ id: row.id,
6492
+ userId: row.user_id,
6493
+ stripeCustomerId: row.stripe_customer_id,
6494
+ stripeSubscriptionId: row.stripe_subscription_id,
6495
+ stripePriceId: row.stripe_price_id,
6496
+ status: row.status,
6497
+ currentPeriodStart: row.current_period_start,
6498
+ currentPeriodEnd: row.current_period_end,
6499
+ cancelAtPeriodEnd: !!row.cancel_at_period_end,
6500
+ createdAt: row.created_at,
6501
+ updatedAt: row.updated_at,
6502
+ // Attach email if joined
6503
+ ...row.user_email ? { userEmail: row.user_email } : {}
6504
+ };
6505
+ }
6506
+ };
6507
+
6508
+ // src/plugins/core-plugins/stripe-plugin/services/stripe-event-service.ts
6509
+ var StripeEventService = class {
6510
+ constructor(db) {
6511
+ this.db = db;
6512
+ }
6513
+ async ensureTable() {
6514
+ await this.db.prepare(`
6515
+ CREATE TABLE IF NOT EXISTS stripe_events (
6516
+ id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
6517
+ stripe_event_id TEXT NOT NULL UNIQUE,
6518
+ type TEXT NOT NULL,
6519
+ object_id TEXT NOT NULL DEFAULT '',
6520
+ object_type TEXT NOT NULL DEFAULT '',
6521
+ data TEXT NOT NULL DEFAULT '{}',
6522
+ processed_at INTEGER NOT NULL DEFAULT (unixepoch()),
6523
+ status TEXT NOT NULL DEFAULT 'processed',
6524
+ error TEXT
6525
+ )
6526
+ `).run();
6527
+ await this.db.prepare(`
6528
+ CREATE INDEX IF NOT EXISTS idx_stripe_events_type ON stripe_events(type)
6529
+ `).run();
6530
+ await this.db.prepare(`
6531
+ CREATE INDEX IF NOT EXISTS idx_stripe_events_status ON stripe_events(status)
6532
+ `).run();
6533
+ await this.db.prepare(`
6534
+ CREATE INDEX IF NOT EXISTS idx_stripe_events_processed_at ON stripe_events(processed_at DESC)
6535
+ `).run();
6536
+ }
6537
+ async log(event) {
6538
+ await this.db.prepare(`
6539
+ INSERT INTO stripe_events (stripe_event_id, type, object_id, object_type, data, status, error)
6540
+ VALUES (?, ?, ?, ?, ?, ?, ?)
6541
+ ON CONFLICT(stripe_event_id) DO UPDATE SET
6542
+ status = excluded.status,
6543
+ error = excluded.error,
6544
+ processed_at = unixepoch()
6545
+ `).bind(
6546
+ event.stripeEventId,
6547
+ event.type,
6548
+ event.objectId,
6549
+ event.objectType,
6550
+ JSON.stringify(event.data),
6551
+ event.status,
6552
+ event.error || null
6553
+ ).run();
6554
+ }
6555
+ async list(filters = {}) {
6556
+ const where = [];
6557
+ const values = [];
6558
+ if (filters.type) {
6559
+ where.push("type = ?");
6560
+ values.push(filters.type);
6561
+ }
6562
+ if (filters.status) {
6563
+ where.push("status = ?");
6564
+ values.push(filters.status);
6565
+ }
6566
+ if (filters.objectId) {
6567
+ where.push("object_id = ?");
6568
+ values.push(filters.objectId);
6569
+ }
6570
+ const whereClause = where.length > 0 ? `WHERE ${where.join(" AND ")}` : "";
6571
+ const limit = Math.min(filters.limit || 50, 100);
6572
+ const page = filters.page || 1;
6573
+ const offset = (page - 1) * limit;
6574
+ const countResult = await this.db.prepare(
6575
+ `SELECT COUNT(*) as count FROM stripe_events ${whereClause}`
6576
+ ).bind(...values).first();
6577
+ const results = await this.db.prepare(
6578
+ `SELECT * FROM stripe_events ${whereClause} ORDER BY processed_at DESC LIMIT ? OFFSET ?`
6579
+ ).bind(...values, limit, offset).all();
6580
+ return {
6581
+ events: (results.results || []).map((r) => this.mapRow(r)),
6582
+ total: countResult?.count || 0
6583
+ };
6584
+ }
6585
+ async getStats() {
6586
+ const result = await this.db.prepare(`
6587
+ SELECT
6588
+ COUNT(*) as total,
6589
+ SUM(CASE WHEN status = 'processed' THEN 1 ELSE 0 END) as processed,
6590
+ SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) as failed,
6591
+ SUM(CASE WHEN status = 'ignored' THEN 1 ELSE 0 END) as ignored
6592
+ FROM stripe_events
6593
+ `).first();
6594
+ return {
6595
+ total: result?.total || 0,
6596
+ processed: result?.processed || 0,
6597
+ failed: result?.failed || 0,
6598
+ ignored: result?.ignored || 0
6599
+ };
6600
+ }
6601
+ async getDistinctTypes() {
6602
+ const results = await this.db.prepare(
6603
+ "SELECT DISTINCT type FROM stripe_events ORDER BY type"
6604
+ ).all();
6605
+ return (results.results || []).map((r) => r.type);
6606
+ }
6607
+ mapRow(row) {
6608
+ return {
6609
+ id: row.id,
6610
+ stripeEventId: row.stripe_event_id,
6611
+ type: row.type,
6612
+ objectId: row.object_id,
6613
+ objectType: row.object_type,
6614
+ data: row.data,
6615
+ processedAt: row.processed_at,
6616
+ status: row.status,
6617
+ error: row.error || void 0
6618
+ };
6619
+ }
6620
+ };
6621
+
6622
+ // src/plugins/core-plugins/stripe-plugin/components/subscriptions-page.ts
6623
+ chunkUYJ6TJHX_cjs.init_admin_layout_catalyst_template();
6624
+
6625
+ // src/plugins/core-plugins/stripe-plugin/components/tab-bar.ts
6626
+ var TABS = [
6627
+ { label: "Subscriptions", path: "/admin/plugins/stripe" },
6628
+ { label: "Events", path: "/admin/plugins/stripe/events" },
6629
+ { label: "Settings", path: "/admin/plugins/stripe/settings" }
6272
6630
  ];
6631
+ function renderStripeTabBar(currentPath) {
6632
+ const tabs = TABS.map((tab) => {
6633
+ const isActive = currentPath === tab.path || tab.path === "/admin/plugins/stripe" && currentPath === "/admin/plugins/stripe/";
6634
+ return `
6635
+ <a href="${tab.path}"
6636
+ class="${isActive ? "border-cyan-500 text-zinc-950 dark:text-white" : "border-transparent text-zinc-500 dark:text-zinc-400 hover:text-zinc-700 dark:hover:text-zinc-300 hover:border-zinc-300 dark:hover:border-zinc-600"} whitespace-nowrap border-b-2 px-4 py-3 text-sm font-medium transition-colors">
6637
+ ${tab.label}
6638
+ </a>`;
6639
+ }).join("");
6640
+ return `
6641
+ <div class="border-b border-zinc-950/5 dark:border-white/10 mb-6">
6642
+ <nav class="-mb-px flex gap-x-2" aria-label="Stripe tabs">
6643
+ ${tabs}
6644
+ </nav>
6645
+ </div>
6646
+ `;
6647
+ }
6648
+
6649
+ // src/plugins/core-plugins/stripe-plugin/components/subscriptions-page.ts
6650
+ function renderSubscriptionsPage(data) {
6651
+ const { subscriptions, stats, filters, user, version, dynamicMenuItems } = data;
6652
+ const content2 = `
6653
+ <div>
6654
+ <div class="sm:flex sm:items-center sm:justify-between mb-6">
6655
+ <div class="sm:flex-auto">
6656
+ <h1 class="text-2xl/8 font-semibold text-zinc-950 dark:text-white sm:text-xl/8">Stripe</h1>
6657
+ <p class="mt-2 text-sm/6 text-zinc-500 dark:text-zinc-400">
6658
+ Manage subscriptions, view billing status, and monitor payment events.
6659
+ </p>
6660
+ </div>
6661
+ <div class="mt-4 sm:mt-0 sm:ml-16">
6662
+ <button id="sync-btn" onclick="syncSubscriptions()"
6663
+ class="inline-flex items-center justify-center rounded-lg bg-zinc-950 dark:bg-white px-3.5 py-2.5 text-sm font-semibold text-white dark:text-zinc-950 hover:bg-zinc-800 dark:hover:bg-zinc-100 transition-colors shadow-sm">
6664
+ Sync from Stripe
6665
+ </button>
6666
+ </div>
6667
+ </div>
6668
+
6669
+ ${renderStripeTabBar("/admin/plugins/stripe")}
6670
+
6671
+ <!-- Stats Cards -->
6672
+ <div class="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-5 mb-6">
6673
+ ${statsCard("Total", stats.total, "text-zinc-950 dark:text-white")}
6674
+ ${statsCard("Active", stats.active, "text-emerald-600 dark:text-emerald-400")}
6675
+ ${statsCard("Trialing", stats.trialing, "text-blue-600 dark:text-blue-400")}
6676
+ ${statsCard("Past Due", stats.pastDue, "text-amber-600 dark:text-amber-400")}
6677
+ ${statsCard("Canceled", stats.canceled, "text-red-600 dark:text-red-400")}
6678
+ </div>
6679
+
6680
+ <!-- Filters -->
6681
+ <div class="rounded-xl bg-white/80 dark:bg-zinc-900/80 backdrop-blur-xl p-4 ring-1 ring-zinc-950/5 dark:ring-white/10 shadow-sm mb-6">
6682
+ <form method="GET" class="flex items-center gap-4">
6683
+ <label class="text-sm font-medium text-zinc-500 dark:text-zinc-400">Status:</label>
6684
+ <select name="status" class="rounded-lg border-0 bg-white dark:bg-zinc-800 px-3 py-1.5 text-sm text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10" onchange="this.form.submit()">
6685
+ <option value="">All</option>
6686
+ ${statusOption("active", filters.status)}
6687
+ ${statusOption("trialing", filters.status)}
6688
+ ${statusOption("past_due", filters.status)}
6689
+ ${statusOption("canceled", filters.status)}
6690
+ ${statusOption("unpaid", filters.status)}
6691
+ ${statusOption("paused", filters.status)}
6692
+ </select>
6693
+ </form>
6694
+ </div>
6695
+
6696
+ <!-- Subscriptions Table -->
6697
+ <div class="rounded-xl bg-white/80 dark:bg-zinc-900/80 backdrop-blur-xl ring-1 ring-zinc-950/5 dark:ring-white/10 shadow-sm overflow-hidden">
6698
+ <table class="min-w-full divide-y divide-zinc-950/5 dark:divide-white/5">
6699
+ <thead>
6700
+ <tr>
6701
+ <th class="px-6 py-3 text-left text-xs font-medium text-zinc-500 dark:text-zinc-400 uppercase tracking-wider">User</th>
6702
+ <th class="px-6 py-3 text-left text-xs font-medium text-zinc-500 dark:text-zinc-400 uppercase tracking-wider">Status</th>
6703
+ <th class="px-6 py-3 text-left text-xs font-medium text-zinc-500 dark:text-zinc-400 uppercase tracking-wider">Price ID</th>
6704
+ <th class="px-6 py-3 text-left text-xs font-medium text-zinc-500 dark:text-zinc-400 uppercase tracking-wider">Current Period</th>
6705
+ <th class="px-6 py-3 text-left text-xs font-medium text-zinc-500 dark:text-zinc-400 uppercase tracking-wider">Cancel at End</th>
6706
+ <th class="px-6 py-3 text-left text-xs font-medium text-zinc-500 dark:text-zinc-400 uppercase tracking-wider">Stripe</th>
6707
+ </tr>
6708
+ </thead>
6709
+ <tbody class="divide-y divide-zinc-950/5 dark:divide-white/5">
6710
+ ${subscriptions.length === 0 ? '<tr><td colspan="6" class="px-6 py-8 text-center text-zinc-500 dark:text-zinc-400">No subscriptions found</td></tr>' : subscriptions.map(renderRow).join("")}
6711
+ </tbody>
6712
+ </table>
6713
+
6714
+ ${renderPagination2(filters.page, filters.totalPages, filters.status)}
6715
+ </div>
6716
+
6717
+ <div id="sync-message" class="hidden mt-4 rounded-lg p-4 text-sm"></div>
6718
+ </div>
6719
+
6720
+ <script>
6721
+ async function syncSubscriptions() {
6722
+ const btn = document.getElementById('sync-btn')
6723
+ const msg = document.getElementById('sync-message')
6724
+ btn.disabled = true
6725
+ btn.textContent = 'Syncing...'
6726
+ msg.className = 'hidden mt-4 rounded-lg p-4 text-sm'
6727
+ try {
6728
+ const res = await fetch('/api/stripe/sync-subscriptions', { method: 'POST' })
6729
+ const result = await res.json()
6730
+ if (result.success) {
6731
+ msg.className = 'mt-4 rounded-lg p-4 text-sm bg-emerald-400/10 text-emerald-500 dark:text-emerald-400 ring-1 ring-inset ring-emerald-400/20'
6732
+ msg.textContent = 'Synced ' + result.synced + ' of ' + result.total + ' subscriptions from Stripe.' + (result.errors > 0 ? ' (' + result.errors + ' errors)' : '')
6733
+ setTimeout(() => location.reload(), 1500)
6734
+ } else {
6735
+ msg.className = 'mt-4 rounded-lg p-4 text-sm bg-red-400/10 text-red-500 dark:text-red-400 ring-1 ring-inset ring-red-400/20'
6736
+ msg.textContent = result.error || 'Sync failed.'
6737
+ }
6738
+ } catch {
6739
+ msg.className = 'mt-4 rounded-lg p-4 text-sm bg-red-400/10 text-red-500 dark:text-red-400 ring-1 ring-inset ring-red-400/20'
6740
+ msg.textContent = 'Network error. Please try again.'
6741
+ }
6742
+ btn.disabled = false
6743
+ btn.textContent = 'Sync from Stripe'
6744
+ }
6745
+ </script>
6746
+ `;
6747
+ const layoutData = {
6748
+ title: "Stripe Subscriptions",
6749
+ pageTitle: "Stripe Subscriptions",
6750
+ currentPath: "/admin/plugins/stripe",
6751
+ user,
6752
+ content: content2,
6753
+ version,
6754
+ dynamicMenuItems
6755
+ };
6756
+ return chunkUYJ6TJHX_cjs.renderAdminLayoutCatalyst(layoutData);
6757
+ }
6758
+ function statsCard(label, value, colorClass) {
6759
+ return `
6760
+ <div class="rounded-xl bg-white/80 dark:bg-zinc-900/80 backdrop-blur-xl p-5 ring-1 ring-zinc-950/5 dark:ring-white/10 shadow-sm">
6761
+ <p class="text-sm font-medium text-zinc-500 dark:text-zinc-400">${label}</p>
6762
+ <p class="mt-2 text-3xl font-bold ${colorClass}">${value}</p>
6763
+ </div>
6764
+ `;
6765
+ }
6766
+ function statusOption(value, current) {
6767
+ const selected = value === current ? "selected" : "";
6768
+ const label = value.replace("_", " ").replace(/\b\w/g, (c) => c.toUpperCase());
6769
+ return `<option value="${value}" ${selected}>${label}</option>`;
6770
+ }
6771
+ function statusBadge(status) {
6772
+ const colors = {
6773
+ active: "bg-emerald-400/10 text-emerald-500 dark:text-emerald-400 ring-emerald-400/20",
6774
+ trialing: "bg-blue-400/10 text-blue-500 dark:text-blue-400 ring-blue-400/20",
6775
+ past_due: "bg-amber-400/10 text-amber-500 dark:text-amber-400 ring-amber-400/20",
6776
+ canceled: "bg-red-400/10 text-red-500 dark:text-red-400 ring-red-400/20",
6777
+ unpaid: "bg-orange-400/10 text-orange-500 dark:text-orange-400 ring-orange-400/20",
6778
+ paused: "bg-zinc-400/10 text-zinc-500 dark:text-zinc-400 ring-zinc-400/20",
6779
+ incomplete: "bg-zinc-400/10 text-zinc-500 dark:text-zinc-400 ring-zinc-400/20",
6780
+ incomplete_expired: "bg-red-400/10 text-red-500 dark:text-red-400 ring-red-400/20"
6781
+ };
6782
+ const color = colors[status] || "bg-zinc-400/10 text-zinc-500 ring-zinc-400/20";
6783
+ const label = status.replace("_", " ");
6784
+ return `<span class="inline-flex items-center rounded-full px-2 py-1 text-xs font-medium ring-1 ring-inset ${color}">${label}</span>`;
6785
+ }
6786
+ function formatDate(timestamp) {
6787
+ if (!timestamp) return "-";
6788
+ return new Date(timestamp * 1e3).toLocaleDateString("en-US", {
6789
+ month: "short",
6790
+ day: "numeric",
6791
+ year: "numeric"
6792
+ });
6793
+ }
6794
+ function renderRow(sub) {
6795
+ return `
6796
+ <tr class="hover:bg-zinc-950/[0.025] dark:hover:bg-white/[0.025]">
6797
+ <td class="px-6 py-4 whitespace-nowrap">
6798
+ <div class="text-sm font-medium text-zinc-950 dark:text-white">${sub.userEmail || sub.userId}</div>
6799
+ <div class="text-xs text-zinc-500 dark:text-zinc-400">${sub.stripeCustomerId}</div>
6800
+ </td>
6801
+ <td class="px-6 py-4 whitespace-nowrap">${statusBadge(sub.status)}</td>
6802
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-zinc-500 dark:text-zinc-400">${sub.stripePriceId}</td>
6803
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-zinc-500 dark:text-zinc-400">
6804
+ ${formatDate(sub.currentPeriodStart)} - ${formatDate(sub.currentPeriodEnd)}
6805
+ </td>
6806
+ <td class="px-6 py-4 whitespace-nowrap text-sm">
6807
+ ${sub.cancelAtPeriodEnd ? '<span class="text-amber-500 dark:text-amber-400 font-medium">Yes</span>' : '<span class="text-zinc-400 dark:text-zinc-500">No</span>'}
6808
+ </td>
6809
+ <td class="px-6 py-4 whitespace-nowrap text-sm">
6810
+ <a href="https://dashboard.stripe.com/subscriptions/${sub.stripeSubscriptionId}"
6811
+ target="_blank" rel="noopener noreferrer"
6812
+ class="text-cyan-600 dark:text-cyan-400 hover:text-cyan-500 dark:hover:text-cyan-300">
6813
+ View in Stripe
6814
+ </a>
6815
+ </td>
6816
+ </tr>
6817
+ `;
6818
+ }
6819
+ function renderPagination2(page, totalPages, status) {
6820
+ if (totalPages <= 1) return "";
6821
+ const params = status ? `&status=${status}` : "";
6822
+ return `
6823
+ <div class="px-6 py-3 flex items-center justify-between border-t border-zinc-950/5 dark:border-white/5">
6824
+ <div class="text-sm text-zinc-500 dark:text-zinc-400">
6825
+ Page ${page} of ${totalPages}
6826
+ </div>
6827
+ <div class="flex gap-2">
6828
+ ${page > 1 ? `<a href="?page=${page - 1}${params}" class="px-3 py-1 rounded-lg text-sm text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 hover:bg-zinc-50 dark:hover:bg-zinc-800">Previous</a>` : ""}
6829
+ ${page < totalPages ? `<a href="?page=${page + 1}${params}" class="px-3 py-1 rounded-lg text-sm text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 hover:bg-zinc-50 dark:hover:bg-zinc-800">Next</a>` : ""}
6830
+ </div>
6831
+ </div>
6832
+ `;
6833
+ }
6834
+
6835
+ // src/plugins/core-plugins/stripe-plugin/components/events-page.ts
6836
+ chunkUYJ6TJHX_cjs.init_admin_layout_catalyst_template();
6837
+ function renderEventsPage(data) {
6838
+ const { events, stats, types, filters, user, version, dynamicMenuItems } = data;
6839
+ const content2 = `
6840
+ <div>
6841
+ <div class="sm:flex sm:items-center sm:justify-between mb-6">
6842
+ <div class="sm:flex-auto">
6843
+ <h1 class="text-2xl/8 font-semibold text-zinc-950 dark:text-white sm:text-xl/8">Stripe</h1>
6844
+ <p class="mt-2 text-sm/6 text-zinc-500 dark:text-zinc-400">
6845
+ Webhook event log showing all processed, failed, and ignored Stripe events.
6846
+ </p>
6847
+ </div>
6848
+ </div>
6849
+
6850
+ ${renderStripeTabBar("/admin/plugins/stripe/events")}
6851
+
6852
+ <!-- Stats Cards -->
6853
+ <div class="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4 mb-6">
6854
+ ${eventStatsCard("Total Events", stats.total, "text-zinc-950 dark:text-white")}
6855
+ ${eventStatsCard("Processed", stats.processed, "text-emerald-600 dark:text-emerald-400")}
6856
+ ${eventStatsCard("Failed", stats.failed, "text-red-600 dark:text-red-400")}
6857
+ ${eventStatsCard("Ignored", stats.ignored, "text-zinc-500 dark:text-zinc-400")}
6858
+ </div>
6859
+
6860
+ <!-- Filters -->
6861
+ <div class="rounded-xl bg-white/80 dark:bg-zinc-900/80 backdrop-blur-xl p-4 ring-1 ring-zinc-950/5 dark:ring-white/10 shadow-sm mb-6">
6862
+ <form method="GET" class="flex items-center gap-4 flex-wrap">
6863
+ <label class="text-sm font-medium text-zinc-500 dark:text-zinc-400">Type:</label>
6864
+ <select name="type" class="rounded-lg border-0 bg-white dark:bg-zinc-800 px-3 py-1.5 text-sm text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10" onchange="this.form.submit()">
6865
+ <option value="">All</option>
6866
+ ${types.map((t) => `<option value="${t}" ${t === filters.type ? "selected" : ""}>${t}</option>`).join("")}
6867
+ </select>
6868
+
6869
+ <label class="text-sm font-medium text-zinc-500 dark:text-zinc-400">Status:</label>
6870
+ <select name="status" class="rounded-lg border-0 bg-white dark:bg-zinc-800 px-3 py-1.5 text-sm text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10" onchange="this.form.submit()">
6871
+ <option value="">All</option>
6872
+ ${eventStatusOption("processed", filters.status)}
6873
+ ${eventStatusOption("failed", filters.status)}
6874
+ ${eventStatusOption("ignored", filters.status)}
6875
+ </select>
6876
+ </form>
6877
+ </div>
6878
+
6879
+ <!-- Events Table -->
6880
+ <div class="rounded-xl bg-white/80 dark:bg-zinc-900/80 backdrop-blur-xl ring-1 ring-zinc-950/5 dark:ring-white/10 shadow-sm overflow-hidden">
6881
+ <table class="min-w-full divide-y divide-zinc-950/5 dark:divide-white/5">
6882
+ <thead>
6883
+ <tr>
6884
+ <th class="px-6 py-3 text-left text-xs font-medium text-zinc-500 dark:text-zinc-400 uppercase tracking-wider">Time</th>
6885
+ <th class="px-6 py-3 text-left text-xs font-medium text-zinc-500 dark:text-zinc-400 uppercase tracking-wider">Type</th>
6886
+ <th class="px-6 py-3 text-left text-xs font-medium text-zinc-500 dark:text-zinc-400 uppercase tracking-wider">Object</th>
6887
+ <th class="px-6 py-3 text-left text-xs font-medium text-zinc-500 dark:text-zinc-400 uppercase tracking-wider">Status</th>
6888
+ <th class="px-6 py-3 text-left text-xs font-medium text-zinc-500 dark:text-zinc-400 uppercase tracking-wider">Event ID</th>
6889
+ </tr>
6890
+ </thead>
6891
+ <tbody class="divide-y divide-zinc-950/5 dark:divide-white/5">
6892
+ ${events.length === 0 ? '<tr><td colspan="5" class="px-6 py-8 text-center text-zinc-500 dark:text-zinc-400">No events recorded yet</td></tr>' : events.map(renderEventRow).join("")}
6893
+ </tbody>
6894
+ </table>
6895
+
6896
+ ${renderEventPagination(filters.page, filters.totalPages, filters.type, filters.status)}
6897
+ </div>
6898
+ </div>
6899
+ `;
6900
+ const layoutData = {
6901
+ title: "Stripe Events",
6902
+ pageTitle: "Stripe Events",
6903
+ currentPath: "/admin/plugins/stripe",
6904
+ user,
6905
+ content: content2,
6906
+ version,
6907
+ dynamicMenuItems
6908
+ };
6909
+ return chunkUYJ6TJHX_cjs.renderAdminLayoutCatalyst(layoutData);
6910
+ }
6911
+ function eventStatsCard(label, value, colorClass) {
6912
+ return `
6913
+ <div class="rounded-xl bg-white/80 dark:bg-zinc-900/80 backdrop-blur-xl p-5 ring-1 ring-zinc-950/5 dark:ring-white/10 shadow-sm">
6914
+ <p class="text-sm font-medium text-zinc-500 dark:text-zinc-400">${label}</p>
6915
+ <p class="mt-2 text-3xl font-bold ${colorClass}">${value}</p>
6916
+ </div>
6917
+ `;
6918
+ }
6919
+ function eventStatusOption(value, current) {
6920
+ const selected = value === current ? "selected" : "";
6921
+ const label = value.charAt(0).toUpperCase() + value.slice(1);
6922
+ return `<option value="${value}" ${selected}>${label}</option>`;
6923
+ }
6924
+ function eventStatusBadge(status) {
6925
+ const colors = {
6926
+ processed: "bg-emerald-400/10 text-emerald-500 dark:text-emerald-400 ring-emerald-400/20",
6927
+ failed: "bg-red-400/10 text-red-500 dark:text-red-400 ring-red-400/20",
6928
+ ignored: "bg-zinc-400/10 text-zinc-500 dark:text-zinc-400 ring-zinc-400/20"
6929
+ };
6930
+ const color = colors[status] || "bg-zinc-400/10 text-zinc-500 ring-zinc-400/20";
6931
+ return `<span class="inline-flex items-center rounded-full px-2 py-1 text-xs font-medium ring-1 ring-inset ${color}">${status}</span>`;
6932
+ }
6933
+ function formatTimestamp3(timestamp) {
6934
+ if (!timestamp) return "-";
6935
+ const d = new Date(timestamp * 1e3);
6936
+ return d.toLocaleString("en-US", {
6937
+ month: "short",
6938
+ day: "numeric",
6939
+ year: "numeric",
6940
+ hour: "2-digit",
6941
+ minute: "2-digit",
6942
+ second: "2-digit"
6943
+ });
6944
+ }
6945
+ function renderEventRow(event) {
6946
+ const errorTooltip = event.error ? ` title="${event.error.replace(/"/g, "&quot;")}"` : "";
6947
+ return `
6948
+ <tr class="hover:bg-zinc-950/[0.025] dark:hover:bg-white/[0.025]"${errorTooltip}>
6949
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-zinc-500 dark:text-zinc-400">
6950
+ ${formatTimestamp3(event.processedAt)}
6951
+ </td>
6952
+ <td class="px-6 py-4 whitespace-nowrap">
6953
+ <span class="text-sm font-mono text-zinc-950 dark:text-white">${event.type}</span>
6954
+ </td>
6955
+ <td class="px-6 py-4 whitespace-nowrap">
6956
+ <div class="text-sm font-mono text-zinc-500 dark:text-zinc-400">${event.objectId || "-"}</div>
6957
+ <div class="text-xs text-zinc-400 dark:text-zinc-500">${event.objectType}</div>
6958
+ </td>
6959
+ <td class="px-6 py-4 whitespace-nowrap">${eventStatusBadge(event.status)}</td>
6960
+ <td class="px-6 py-4 whitespace-nowrap text-xs font-mono text-zinc-400 dark:text-zinc-500">${event.stripeEventId}</td>
6961
+ </tr>
6962
+ `;
6963
+ }
6964
+ function renderEventPagination(page, totalPages, type, status) {
6965
+ if (totalPages <= 1) return "";
6966
+ const params = [];
6967
+ if (type) params.push(`type=${type}`);
6968
+ if (status) params.push(`status=${status}`);
6969
+ const extra = params.length > 0 ? `&${params.join("&")}` : "";
6970
+ return `
6971
+ <div class="px-6 py-3 flex items-center justify-between border-t border-zinc-950/5 dark:border-white/5">
6972
+ <div class="text-sm text-zinc-500 dark:text-zinc-400">
6973
+ Page ${page} of ${totalPages}
6974
+ </div>
6975
+ <div class="flex gap-2">
6976
+ ${page > 1 ? `<a href="?page=${page - 1}${extra}" class="px-3 py-1 rounded-lg text-sm text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 hover:bg-zinc-50 dark:hover:bg-zinc-800">Previous</a>` : ""}
6977
+ ${page < totalPages ? `<a href="?page=${page + 1}${extra}" class="px-3 py-1 rounded-lg text-sm text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 hover:bg-zinc-50 dark:hover:bg-zinc-800">Next</a>` : ""}
6978
+ </div>
6979
+ </div>
6980
+ `;
6981
+ }
6982
+
6983
+ // src/plugins/core-plugins/stripe-plugin/types.ts
6984
+ var DEFAULT_SETTINGS3 = {
6985
+ stripePublishableKey: "",
6986
+ stripeSecretKey: "",
6987
+ stripeWebhookSecret: "",
6988
+ stripePriceId: "",
6989
+ successUrl: "/admin/dashboard",
6990
+ cancelUrl: "/admin/dashboard"
6991
+ };
6992
+
6993
+ // src/plugins/core-plugins/stripe-plugin/routes/admin.ts
6994
+ var adminRoutes3 = new hono.Hono();
6995
+ adminRoutes3.use("*", chunkUFPT5KCQ_cjs.requireAuth());
6996
+ adminRoutes3.use("*", async (c, next) => {
6997
+ const user = c.get("user");
6998
+ if (user?.role !== "admin") {
6999
+ return c.text("Access denied", 403);
7000
+ }
7001
+ return next();
7002
+ });
7003
+ async function getSettings3(db) {
7004
+ try {
7005
+ const pluginService = new chunk43AB4EH4_cjs.PluginService(db);
7006
+ const plugin2 = await pluginService.getPlugin("stripe");
7007
+ if (plugin2?.settings) {
7008
+ const settings = typeof plugin2.settings === "string" ? JSON.parse(plugin2.settings) : plugin2.settings;
7009
+ return { ...DEFAULT_SETTINGS3, ...settings };
7010
+ }
7011
+ } catch {
7012
+ }
7013
+ return DEFAULT_SETTINGS3;
7014
+ }
7015
+ adminRoutes3.get("/", async (c) => {
7016
+ const db = c.env.DB;
7017
+ const user = c.get("user");
7018
+ const subscriptionService = new SubscriptionService(db);
7019
+ await subscriptionService.ensureTable();
7020
+ const page = parseInt(c.req.query("page") || "1");
7021
+ const limit = 50;
7022
+ const statusFilter = c.req.query("status");
7023
+ const [{ subscriptions, total }, stats] = await Promise.all([
7024
+ subscriptionService.list({ status: statusFilter, page, limit }),
7025
+ subscriptionService.getStats()
7026
+ ]);
7027
+ const totalPages = Math.ceil(total / limit);
7028
+ const html = renderSubscriptionsPage({
7029
+ subscriptions,
7030
+ stats,
7031
+ filters: { status: statusFilter, page, totalPages },
7032
+ user: user ? { name: user.email, email: user.email, role: user.role } : void 0,
7033
+ version: c.get("appVersion"),
7034
+ dynamicMenuItems: c.get("pluginMenuItems")
7035
+ });
7036
+ return c.html(html);
7037
+ });
7038
+ adminRoutes3.get("/events", async (c) => {
7039
+ const db = c.env.DB;
7040
+ const user = c.get("user");
7041
+ const eventService = new StripeEventService(db);
7042
+ await eventService.ensureTable();
7043
+ const page = parseInt(c.req.query("page") || "1");
7044
+ const limit = 50;
7045
+ const typeFilter = c.req.query("type") || void 0;
7046
+ const statusFilter = c.req.query("status");
7047
+ const [{ events, total }, stats, types] = await Promise.all([
7048
+ eventService.list({ type: typeFilter, status: statusFilter, page, limit }),
7049
+ eventService.getStats(),
7050
+ eventService.getDistinctTypes()
7051
+ ]);
7052
+ const totalPages = Math.ceil(total / limit);
7053
+ const html = renderEventsPage({
7054
+ events,
7055
+ stats,
7056
+ types,
7057
+ filters: { type: typeFilter, status: statusFilter, page, totalPages },
7058
+ user: user ? { name: user.email, email: user.email, role: user.role } : void 0,
7059
+ version: c.get("appVersion"),
7060
+ dynamicMenuItems: c.get("pluginMenuItems")
7061
+ });
7062
+ return c.html(html);
7063
+ });
7064
+ adminRoutes3.get("/settings", async (c) => {
7065
+ const db = c.env.DB;
7066
+ const user = c.get("user");
7067
+ const settings = await getSettings3(db);
7068
+ const { renderAdminLayoutCatalyst: renderAdminLayoutCatalyst2 } = await import('./admin-layout-catalyst.template-HFD37TY5.cjs');
7069
+ const content2 = `
7070
+ <div>
7071
+ <div class="mb-6">
7072
+ <h1 class="text-2xl/8 font-semibold text-zinc-950 dark:text-white sm:text-xl/8">Stripe</h1>
7073
+ <p class="mt-2 text-sm/6 text-zinc-500 dark:text-zinc-400">
7074
+ Configure your Stripe API keys and checkout options.
7075
+ </p>
7076
+ </div>
7077
+
7078
+ ${renderStripeTabBar("/admin/plugins/stripe/settings")}
7079
+
7080
+ <div id="settings-message" class="hidden mb-4 rounded-lg p-4 text-sm"></div>
7081
+
7082
+ <form id="stripe-settings-form" class="rounded-xl bg-white/80 dark:bg-zinc-900/80 backdrop-blur-xl ring-1 ring-zinc-950/5 dark:ring-white/10 shadow-sm divide-y divide-zinc-950/5 dark:divide-white/5">
7083
+ <div class="p-6 space-y-5">
7084
+ <div>
7085
+ <label class="block text-sm font-medium text-zinc-950 dark:text-white mb-1.5">Publishable Key</label>
7086
+ <input type="text" name="stripePublishableKey" value="${settings.stripePublishableKey}"
7087
+ placeholder="pk_..."
7088
+ class="w-full rounded-lg border-0 bg-white dark:bg-zinc-800 px-3.5 py-2 text-sm text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:ring-2 focus:ring-cyan-500" />
7089
+ <p class="mt-1 text-xs text-zinc-500 dark:text-zinc-400">Your Stripe publishable key (starts with pk_)</p>
7090
+ </div>
7091
+
7092
+ <div>
7093
+ <label class="block text-sm font-medium text-zinc-950 dark:text-white mb-1.5">Secret Key</label>
7094
+ <input type="password" name="stripeSecretKey" value="${settings.stripeSecretKey}"
7095
+ placeholder="sk_..."
7096
+ class="w-full rounded-lg border-0 bg-white dark:bg-zinc-800 px-3.5 py-2 text-sm text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:ring-2 focus:ring-cyan-500" />
7097
+ <p class="mt-1 text-xs text-zinc-500 dark:text-zinc-400">Your Stripe secret API key (starts with sk_)</p>
7098
+ </div>
7099
+
7100
+ <div>
7101
+ <label class="block text-sm font-medium text-zinc-950 dark:text-white mb-1.5">Webhook Signing Secret</label>
7102
+ <input type="password" name="stripeWebhookSecret" value="${settings.stripeWebhookSecret}"
7103
+ placeholder="whsec_..."
7104
+ class="w-full rounded-lg border-0 bg-white dark:bg-zinc-800 px-3.5 py-2 text-sm text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:ring-2 focus:ring-cyan-500" />
7105
+ <p class="mt-1 text-xs text-zinc-500 dark:text-zinc-400">Stripe webhook endpoint signing secret (starts with whsec_)</p>
7106
+ </div>
7107
+
7108
+ <div>
7109
+ <label class="block text-sm font-medium text-zinc-950 dark:text-white mb-1.5">Default Price ID</label>
7110
+ <input type="text" name="stripePriceId" value="${settings.stripePriceId || ""}"
7111
+ placeholder="price_..."
7112
+ class="w-full rounded-lg border-0 bg-white dark:bg-zinc-800 px-3.5 py-2 text-sm text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:ring-2 focus:ring-cyan-500" />
7113
+ <p class="mt-1 text-xs text-zinc-500 dark:text-zinc-400">Default Stripe Price ID for checkout sessions (optional)</p>
7114
+ </div>
7115
+
7116
+ <div>
7117
+ <label class="block text-sm font-medium text-zinc-950 dark:text-white mb-1.5">Checkout Success URL</label>
7118
+ <input type="text" name="successUrl" value="${settings.successUrl}"
7119
+ class="w-full rounded-lg border-0 bg-white dark:bg-zinc-800 px-3.5 py-2 text-sm text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:ring-2 focus:ring-cyan-500" />
7120
+ <p class="mt-1 text-xs text-zinc-500 dark:text-zinc-400">Redirect URL after successful checkout</p>
7121
+ </div>
7122
+
7123
+ <div>
7124
+ <label class="block text-sm font-medium text-zinc-950 dark:text-white mb-1.5">Checkout Cancel URL</label>
7125
+ <input type="text" name="cancelUrl" value="${settings.cancelUrl}"
7126
+ class="w-full rounded-lg border-0 bg-white dark:bg-zinc-800 px-3.5 py-2 text-sm text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:ring-2 focus:ring-cyan-500" />
7127
+ <p class="mt-1 text-xs text-zinc-500 dark:text-zinc-400">Redirect URL if checkout is cancelled</p>
7128
+ </div>
7129
+ </div>
7130
+
7131
+ <div class="px-6 py-4 flex justify-end">
7132
+ <button type="submit"
7133
+ class="inline-flex items-center justify-center rounded-lg bg-zinc-950 dark:bg-white px-3.5 py-2.5 text-sm font-semibold text-white dark:text-zinc-950 hover:bg-zinc-800 dark:hover:bg-zinc-100 transition-colors shadow-sm">
7134
+ Save Settings
7135
+ </button>
7136
+ </div>
7137
+ </form>
7138
+ </div>
7139
+
7140
+ <script>
7141
+ document.getElementById('stripe-settings-form').addEventListener('submit', async (e) => {
7142
+ e.preventDefault()
7143
+ const form = e.target
7144
+ const data = Object.fromEntries(new FormData(form))
7145
+ const msg = document.getElementById('settings-message')
7146
+ try {
7147
+ const res = await fetch('/admin/plugins/stripe/settings', {
7148
+ method: 'POST',
7149
+ headers: { 'Content-Type': 'application/json' },
7150
+ body: JSON.stringify(data)
7151
+ })
7152
+ const result = await res.json()
7153
+ msg.className = result.success
7154
+ ? 'mb-4 rounded-lg p-4 text-sm bg-emerald-400/10 text-emerald-500 dark:text-emerald-400 ring-1 ring-inset ring-emerald-400/20'
7155
+ : 'mb-4 rounded-lg p-4 text-sm bg-red-400/10 text-red-500 dark:text-red-400 ring-1 ring-inset ring-red-400/20'
7156
+ msg.textContent = result.success ? 'Settings saved successfully.' : (result.error || 'Failed to save settings.')
7157
+ } catch {
7158
+ msg.className = 'mb-4 rounded-lg p-4 text-sm bg-red-400/10 text-red-500 dark:text-red-400 ring-1 ring-inset ring-red-400/20'
7159
+ msg.textContent = 'Network error. Please try again.'
7160
+ }
7161
+ })
7162
+ </script>
7163
+ `;
7164
+ return c.html(renderAdminLayoutCatalyst2({
7165
+ title: "Stripe Settings",
7166
+ pageTitle: "Stripe Settings",
7167
+ currentPath: "/admin/plugins/stripe",
7168
+ user: user ? { name: user.email, email: user.email, role: user.role } : void 0,
7169
+ content: content2,
7170
+ version: c.get("appVersion"),
7171
+ dynamicMenuItems: c.get("pluginMenuItems")
7172
+ }));
7173
+ });
7174
+ adminRoutes3.post("/settings", async (c) => {
7175
+ try {
7176
+ const body = await c.req.json();
7177
+ const db = c.env.DB;
7178
+ await db.prepare(`
7179
+ UPDATE plugins
7180
+ SET settings = ?,
7181
+ updated_at = unixepoch()
7182
+ WHERE id = 'stripe'
7183
+ `).bind(JSON.stringify(body)).run();
7184
+ return c.json({ success: true });
7185
+ } catch (error) {
7186
+ console.error("Error saving Stripe settings:", error);
7187
+ return c.json({ success: false, error: "Failed to save settings" }, 500);
7188
+ }
7189
+ });
7190
+
7191
+ // src/plugins/core-plugins/stripe-plugin/services/stripe-api.ts
7192
+ var StripeAPI = class {
7193
+ constructor(secretKey) {
7194
+ this.secretKey = secretKey;
7195
+ }
7196
+ baseUrl = "https://api.stripe.com/v1";
7197
+ /**
7198
+ * Verify a webhook signature
7199
+ * Implements Stripe's v1 signature scheme using Web Crypto API
7200
+ */
7201
+ async verifyWebhookSignature(payload, sigHeader, secret) {
7202
+ const parts = sigHeader.split(",");
7203
+ const timestamp = parts.find((p) => p.startsWith("t="))?.split("=")[1];
7204
+ const signatures = parts.filter((p) => p.startsWith("v1=")).map((p) => p.substring(3));
7205
+ if (!timestamp || signatures.length === 0) return false;
7206
+ const now = Math.floor(Date.now() / 1e3);
7207
+ if (Math.abs(now - parseInt(timestamp)) > 300) return false;
7208
+ const signedPayload = `${timestamp}.${payload}`;
7209
+ const encoder = new TextEncoder();
7210
+ const key = await crypto.subtle.importKey(
7211
+ "raw",
7212
+ encoder.encode(secret),
7213
+ { name: "HMAC", hash: "SHA-256" },
7214
+ false,
7215
+ ["sign"]
7216
+ );
7217
+ const signatureBuffer = await crypto.subtle.sign("HMAC", key, encoder.encode(signedPayload));
7218
+ const expectedSignature = Array.from(new Uint8Array(signatureBuffer)).map((b) => b.toString(16).padStart(2, "0")).join("");
7219
+ return signatures.some((sig) => timingSafeEqual(sig, expectedSignature));
7220
+ }
7221
+ /**
7222
+ * Create a Checkout Session
7223
+ */
7224
+ async createCheckoutSession(params) {
7225
+ const body = new URLSearchParams();
7226
+ body.append("mode", "subscription");
7227
+ body.append("line_items[0][price]", params.priceId);
7228
+ body.append("line_items[0][quantity]", "1");
7229
+ body.append("success_url", params.successUrl);
7230
+ body.append("cancel_url", params.cancelUrl);
7231
+ if (params.customerId) {
7232
+ body.append("customer", params.customerId);
7233
+ } else if (params.customerEmail) {
7234
+ body.append("customer_email", params.customerEmail);
7235
+ }
7236
+ if (params.metadata) {
7237
+ for (const [key, value] of Object.entries(params.metadata)) {
7238
+ body.append(`metadata[${key}]`, value);
7239
+ }
7240
+ }
7241
+ const response = await this.request("POST", "/checkout/sessions", body);
7242
+ return { id: response.id, url: response.url };
7243
+ }
7244
+ /**
7245
+ * Retrieve a Stripe subscription
7246
+ */
7247
+ async getSubscription(subscriptionId) {
7248
+ return this.request("GET", `/subscriptions/${subscriptionId}`);
7249
+ }
7250
+ /**
7251
+ * Create a Stripe customer
7252
+ */
7253
+ async createCustomer(params) {
7254
+ const body = new URLSearchParams();
7255
+ body.append("email", params.email);
7256
+ if (params.metadata) {
7257
+ for (const [key, value] of Object.entries(params.metadata)) {
7258
+ body.append(`metadata[${key}]`, value);
7259
+ }
7260
+ }
7261
+ return this.request("POST", "/customers", body);
7262
+ }
7263
+ /**
7264
+ * List subscriptions with pagination (auto-expands across pages)
7265
+ */
7266
+ async listSubscriptions(params) {
7267
+ const qs = new URLSearchParams();
7268
+ qs.append("limit", String(params?.limit || 100));
7269
+ if (params?.status) qs.append("status", params.status);
7270
+ if (params?.startingAfter) qs.append("starting_after", params.startingAfter);
7271
+ return this.request("GET", `/subscriptions?${qs.toString()}`);
7272
+ }
7273
+ /**
7274
+ * Fetch ALL subscriptions from Stripe (handles pagination automatically)
7275
+ */
7276
+ async listAllSubscriptions() {
7277
+ const all = [];
7278
+ let startingAfter;
7279
+ while (true) {
7280
+ const result = await this.listSubscriptions({ limit: 100, startingAfter });
7281
+ all.push(...result.data);
7282
+ if (!result.has_more || result.data.length === 0) break;
7283
+ startingAfter = result.data[result.data.length - 1].id;
7284
+ }
7285
+ return all;
7286
+ }
7287
+ /**
7288
+ * Search for a customer by email
7289
+ */
7290
+ async findCustomerByEmail(email) {
7291
+ const params = new URLSearchParams();
7292
+ params.append("query", `email:'${email}'`);
7293
+ params.append("limit", "1");
7294
+ const result = await this.request("GET", `/customers/search?${params.toString()}`);
7295
+ return result.data?.[0] || null;
7296
+ }
7297
+ async request(method, path, body) {
7298
+ const url = path.startsWith("http") ? path : `${this.baseUrl}${path}`;
7299
+ const response = await fetch(url, {
7300
+ method,
7301
+ headers: {
7302
+ "Authorization": `Bearer ${this.secretKey}`,
7303
+ ...body ? { "Content-Type": "application/x-www-form-urlencoded" } : {}
7304
+ },
7305
+ ...body ? { body: body.toString() } : {}
7306
+ });
7307
+ const data = await response.json();
7308
+ if (!response.ok) {
7309
+ throw new Error(`Stripe API error: ${data.error?.message || response.statusText}`);
7310
+ }
7311
+ return data;
7312
+ }
7313
+ };
7314
+ function timingSafeEqual(a, b) {
7315
+ if (a.length !== b.length) return false;
7316
+ let result = 0;
7317
+ for (let i = 0; i < a.length; i++) {
7318
+ result |= a.charCodeAt(i) ^ b.charCodeAt(i);
7319
+ }
7320
+ return result === 0;
7321
+ }
7322
+
7323
+ // src/plugins/core-plugins/stripe-plugin/routes/api.ts
7324
+ var apiRoutes3 = new hono.Hono();
7325
+ async function getSettings4(db) {
7326
+ try {
7327
+ const pluginService = new chunk43AB4EH4_cjs.PluginService(db);
7328
+ const plugin2 = await pluginService.getPlugin("stripe");
7329
+ if (plugin2?.settings) {
7330
+ const settings = typeof plugin2.settings === "string" ? JSON.parse(plugin2.settings) : plugin2.settings;
7331
+ return { ...DEFAULT_SETTINGS3, ...settings };
7332
+ }
7333
+ } catch {
7334
+ }
7335
+ return DEFAULT_SETTINGS3;
7336
+ }
7337
+ function mapStripeStatus(status) {
7338
+ const map = {
7339
+ active: "active",
7340
+ canceled: "canceled",
7341
+ past_due: "past_due",
7342
+ trialing: "trialing",
7343
+ unpaid: "unpaid",
7344
+ paused: "paused",
7345
+ incomplete: "incomplete",
7346
+ incomplete_expired: "incomplete_expired"
7347
+ };
7348
+ return map[status] || "incomplete";
7349
+ }
7350
+ apiRoutes3.post("/webhook", async (c) => {
7351
+ const db = c.env.DB;
7352
+ const settings = await getSettings4(db);
7353
+ if (!settings.stripeWebhookSecret) {
7354
+ return c.json({ error: "Webhook secret not configured" }, 500);
7355
+ }
7356
+ const rawBody = await c.req.text();
7357
+ const sigHeader = c.req.header("stripe-signature") || "";
7358
+ const stripeApi = new StripeAPI(settings.stripeSecretKey);
7359
+ const isValid = await stripeApi.verifyWebhookSignature(rawBody, sigHeader, settings.stripeWebhookSecret);
7360
+ if (!isValid) {
7361
+ return c.json({ error: "Invalid signature" }, 400);
7362
+ }
7363
+ const event = JSON.parse(rawBody);
7364
+ const subscriptionService = new SubscriptionService(db);
7365
+ const eventService = new StripeEventService(db);
7366
+ await Promise.all([subscriptionService.ensureTable(), eventService.ensureTable()]);
7367
+ const obj = event.data.object;
7368
+ const objectId = obj?.id || "";
7369
+ const objectType = obj?.object || event.type.split(".")[0] || "";
7370
+ try {
7371
+ switch (event.type) {
7372
+ case "customer.subscription.created": {
7373
+ const sub = event.data.object;
7374
+ const userId = sub.metadata?.sonicjs_user_id || await subscriptionService.getUserIdByStripeCustomer(sub.customer) || "";
7375
+ await subscriptionService.create({
7376
+ userId,
7377
+ stripeCustomerId: sub.customer,
7378
+ stripeSubscriptionId: sub.id,
7379
+ stripePriceId: sub.items.data[0]?.price.id || "",
7380
+ status: mapStripeStatus(sub.status),
7381
+ currentPeriodStart: sub.current_period_start,
7382
+ currentPeriodEnd: sub.current_period_end,
7383
+ cancelAtPeriodEnd: sub.cancel_at_period_end
7384
+ });
7385
+ console.log(`[Stripe] Subscription created: ${sub.id}`);
7386
+ break;
7387
+ }
7388
+ case "customer.subscription.updated": {
7389
+ const sub = event.data.object;
7390
+ await subscriptionService.updateByStripeId(sub.id, {
7391
+ status: mapStripeStatus(sub.status),
7392
+ stripePriceId: sub.items.data[0]?.price.id || void 0,
7393
+ currentPeriodStart: sub.current_period_start,
7394
+ currentPeriodEnd: sub.current_period_end,
7395
+ cancelAtPeriodEnd: sub.cancel_at_period_end
7396
+ });
7397
+ console.log(`[Stripe] Subscription updated: ${sub.id} -> ${sub.status}`);
7398
+ break;
7399
+ }
7400
+ case "customer.subscription.deleted": {
7401
+ const sub = event.data.object;
7402
+ await subscriptionService.updateByStripeId(sub.id, {
7403
+ status: "canceled"
7404
+ });
7405
+ console.log(`[Stripe] Subscription deleted: ${sub.id}`);
7406
+ break;
7407
+ }
7408
+ case "checkout.session.completed": {
7409
+ const session = event.data.object;
7410
+ const userId = session.metadata?.sonicjs_user_id;
7411
+ if (userId && session.subscription) {
7412
+ const existing = await subscriptionService.getByStripeSubscriptionId(session.subscription);
7413
+ if (existing && !existing.userId) {
7414
+ await subscriptionService.updateByStripeId(session.subscription, {
7415
+ userId
7416
+ });
7417
+ }
7418
+ }
7419
+ console.log(`[Stripe] Checkout completed: ${session.id}`);
7420
+ break;
7421
+ }
7422
+ case "invoice.payment_succeeded": {
7423
+ const invoice = event.data.object;
7424
+ if (invoice.subscription) {
7425
+ await subscriptionService.updateByStripeId(invoice.subscription, {
7426
+ status: "active"
7427
+ });
7428
+ }
7429
+ console.log(`[Stripe] Payment succeeded for invoice: ${invoice.id}`);
7430
+ break;
7431
+ }
7432
+ case "invoice.payment_failed": {
7433
+ const invoice = event.data.object;
7434
+ if (invoice.subscription) {
7435
+ await subscriptionService.updateByStripeId(invoice.subscription, {
7436
+ status: "past_due"
7437
+ });
7438
+ }
7439
+ console.log(`[Stripe] Payment failed for invoice: ${invoice.id}`);
7440
+ break;
7441
+ }
7442
+ default:
7443
+ console.log(`[Stripe] Unhandled event type: ${event.type}`);
7444
+ await eventService.log({
7445
+ stripeEventId: event.id,
7446
+ type: event.type,
7447
+ objectId,
7448
+ objectType,
7449
+ data: event.data.object,
7450
+ status: "ignored"
7451
+ });
7452
+ return c.json({ received: true });
7453
+ }
7454
+ await eventService.log({
7455
+ stripeEventId: event.id,
7456
+ type: event.type,
7457
+ objectId,
7458
+ objectType,
7459
+ data: event.data.object,
7460
+ status: "processed"
7461
+ });
7462
+ } catch (error) {
7463
+ await eventService.log({
7464
+ stripeEventId: event.id,
7465
+ type: event.type,
7466
+ objectId,
7467
+ objectType,
7468
+ data: event.data.object,
7469
+ status: "failed",
7470
+ error: error instanceof Error ? error.message : String(error)
7471
+ }).catch(() => {
7472
+ });
7473
+ console.error(`[Stripe] Error processing webhook event ${event.type}:`, error);
7474
+ return c.json({ error: "Webhook processing failed" }, 500);
7475
+ }
7476
+ return c.json({ received: true });
7477
+ });
7478
+ apiRoutes3.post("/create-checkout-session", chunkUFPT5KCQ_cjs.requireAuth(), async (c) => {
7479
+ const db = c.env.DB;
7480
+ const user = c.get("user");
7481
+ if (!user) return c.json({ error: "Unauthorized" }, 401);
7482
+ const settings = await getSettings4(db);
7483
+ if (!settings.stripeSecretKey) {
7484
+ return c.json({ error: "Stripe not configured" }, 500);
7485
+ }
7486
+ const body = await c.req.json().catch(() => ({}));
7487
+ const priceId = body.priceId || settings.stripePriceId;
7488
+ if (!priceId) {
7489
+ return c.json({ error: "No price ID specified" }, 400);
7490
+ }
7491
+ const stripeApi = new StripeAPI(settings.stripeSecretKey);
7492
+ const subscriptionService = new SubscriptionService(db);
7493
+ await subscriptionService.ensureTable();
7494
+ const existingSub = await subscriptionService.getByUserId(user.userId);
7495
+ let customerId = existingSub?.stripeCustomerId;
7496
+ if (!customerId) {
7497
+ const existing = await stripeApi.findCustomerByEmail(user.email);
7498
+ if (existing) {
7499
+ customerId = existing.id;
7500
+ } else {
7501
+ const customer = await stripeApi.createCustomer({
7502
+ email: user.email,
7503
+ metadata: { sonicjs_user_id: user.userId }
7504
+ });
7505
+ customerId = customer.id;
7506
+ }
7507
+ }
7508
+ const origin = new URL(c.req.url).origin;
7509
+ const session = await stripeApi.createCheckoutSession({
7510
+ priceId,
7511
+ customerId,
7512
+ successUrl: `${origin}${settings.successUrl}?session_id={CHECKOUT_SESSION_ID}`,
7513
+ cancelUrl: `${origin}${settings.cancelUrl}`,
7514
+ metadata: { sonicjs_user_id: user.userId }
7515
+ });
7516
+ return c.json({ sessionId: session.id, url: session.url });
7517
+ });
7518
+ apiRoutes3.get("/subscription", chunkUFPT5KCQ_cjs.requireAuth(), async (c) => {
7519
+ const user = c.get("user");
7520
+ if (!user) return c.json({ error: "Unauthorized" }, 401);
7521
+ const db = c.env.DB;
7522
+ const subscriptionService = new SubscriptionService(db);
7523
+ await subscriptionService.ensureTable();
7524
+ const subscription = await subscriptionService.getByUserId(user.userId);
7525
+ if (!subscription) {
7526
+ return c.json({ subscription: null });
7527
+ }
7528
+ return c.json({ subscription });
7529
+ });
7530
+ apiRoutes3.get("/subscriptions", chunkUFPT5KCQ_cjs.requireAuth(), async (c) => {
7531
+ const user = c.get("user");
7532
+ if (user?.role !== "admin") return c.json({ error: "Access denied" }, 403);
7533
+ const db = c.env.DB;
7534
+ const subscriptionService = new SubscriptionService(db);
7535
+ await subscriptionService.ensureTable();
7536
+ const filters = {
7537
+ status: c.req.query("status"),
7538
+ page: c.req.query("page") ? parseInt(c.req.query("page")) : 1,
7539
+ limit: c.req.query("limit") ? parseInt(c.req.query("limit")) : 50,
7540
+ sortBy: c.req.query("sortBy") || "created_at",
7541
+ sortOrder: c.req.query("sortOrder") || "desc"
7542
+ };
7543
+ const result = await subscriptionService.list(filters);
7544
+ return c.json(result);
7545
+ });
7546
+ apiRoutes3.get("/stats", chunkUFPT5KCQ_cjs.requireAuth(), async (c) => {
7547
+ const user = c.get("user");
7548
+ if (user?.role !== "admin") return c.json({ error: "Access denied" }, 403);
7549
+ const db = c.env.DB;
7550
+ const subscriptionService = new SubscriptionService(db);
7551
+ await subscriptionService.ensureTable();
7552
+ const stats = await subscriptionService.getStats();
7553
+ return c.json(stats);
7554
+ });
7555
+ apiRoutes3.post("/sync-subscriptions", chunkUFPT5KCQ_cjs.requireAuth(), async (c) => {
7556
+ const user = c.get("user");
7557
+ if (user?.role !== "admin") return c.json({ error: "Access denied" }, 403);
7558
+ const db = c.env.DB;
7559
+ const settings = await getSettings4(db);
7560
+ if (!settings.stripeSecretKey) {
7561
+ return c.json({ error: "Stripe secret key not configured" }, 400);
7562
+ }
7563
+ const stripeApi = new StripeAPI(settings.stripeSecretKey);
7564
+ const subscriptionService = new SubscriptionService(db);
7565
+ await subscriptionService.ensureTable();
7566
+ try {
7567
+ const allSubs = await stripeApi.listAllSubscriptions();
7568
+ let synced = 0;
7569
+ let errors = 0;
7570
+ for (const sub of allSubs) {
7571
+ try {
7572
+ const userId = sub.metadata?.sonicjs_user_id || await subscriptionService.getUserIdByStripeCustomer(sub.customer) || "";
7573
+ await subscriptionService.upsert({
7574
+ userId,
7575
+ stripeCustomerId: typeof sub.customer === "string" ? sub.customer : sub.customer.id,
7576
+ stripeSubscriptionId: sub.id,
7577
+ stripePriceId: sub.items?.data?.[0]?.price?.id || "",
7578
+ status: mapStripeStatus(sub.status),
7579
+ currentPeriodStart: sub.current_period_start,
7580
+ currentPeriodEnd: sub.current_period_end,
7581
+ cancelAtPeriodEnd: sub.cancel_at_period_end
7582
+ });
7583
+ synced++;
7584
+ } catch (err) {
7585
+ console.error(`[Stripe Sync] Failed to upsert subscription ${sub.id}:`, err);
7586
+ errors++;
7587
+ }
7588
+ }
7589
+ return c.json({
7590
+ success: true,
7591
+ total: allSubs.length,
7592
+ synced,
7593
+ errors
7594
+ });
7595
+ } catch (error) {
7596
+ console.error("[Stripe Sync] Error:", error);
7597
+ return c.json({
7598
+ success: false,
7599
+ error: error instanceof Error ? error.message : "Sync failed"
7600
+ }, 500);
7601
+ }
7602
+ });
7603
+ apiRoutes3.get("/events", chunkUFPT5KCQ_cjs.requireAuth(), async (c) => {
7604
+ const user = c.get("user");
7605
+ if (user?.role !== "admin") return c.json({ error: "Access denied" }, 403);
7606
+ const db = c.env.DB;
7607
+ const eventService = new StripeEventService(db);
7608
+ await eventService.ensureTable();
7609
+ const filters = {
7610
+ type: c.req.query("type") || void 0,
7611
+ status: c.req.query("status") || void 0,
7612
+ objectId: c.req.query("objectId") || void 0,
7613
+ page: c.req.query("page") ? parseInt(c.req.query("page")) : 1,
7614
+ limit: c.req.query("limit") ? parseInt(c.req.query("limit")) : 50
7615
+ };
7616
+ const [result, stats, types] = await Promise.all([
7617
+ eventService.list(filters),
7618
+ eventService.getStats(),
7619
+ eventService.getDistinctTypes()
7620
+ ]);
7621
+ return c.json({ ...result, stats, types });
7622
+ });
7623
+
7624
+ // src/plugins/core-plugins/stripe-plugin/index.ts
7625
+ function createStripePlugin() {
7626
+ const builder = chunk635JAMSE_cjs.PluginBuilder.create({
7627
+ name: "stripe",
7628
+ version: "1.0.0-beta.1",
7629
+ description: "Stripe subscription management with webhook handling, checkout sessions, and subscription gating"
7630
+ });
7631
+ builder.metadata({
7632
+ author: { name: "SonicJS Team" },
7633
+ license: "MIT"
7634
+ });
7635
+ builder.addRoute("/admin/plugins/stripe", adminRoutes3, {
7636
+ description: "Stripe subscriptions admin dashboard",
7637
+ requiresAuth: true,
7638
+ priority: 50
7639
+ });
7640
+ builder.addRoute("/api/stripe", apiRoutes3, {
7641
+ description: "Stripe API endpoints (webhook, checkout, subscription)",
7642
+ requiresAuth: false,
7643
+ // Webhook route handles its own auth via signature
7644
+ priority: 50
7645
+ });
7646
+ builder.addMenuItem("Stripe", "/admin/plugins/stripe", {
7647
+ 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>`,
7648
+ order: 75
7649
+ });
7650
+ builder.lifecycle({
7651
+ install: async () => {
7652
+ console.log("[Stripe] Plugin installed");
7653
+ },
7654
+ activate: async () => {
7655
+ console.log("[Stripe] Plugin activated");
7656
+ },
7657
+ deactivate: async () => {
7658
+ console.log("[Stripe] Plugin deactivated");
7659
+ },
7660
+ uninstall: async () => {
7661
+ console.log("[Stripe] Plugin uninstalled");
7662
+ }
7663
+ });
7664
+ return builder.build();
7665
+ }
7666
+ var stripePlugin = createStripePlugin();
7667
+
7668
+ // src/middleware/plugin-menu.ts
7669
+ var REGISTRY_MENU_PLUGINS = Object.values(chunk43AB4EH4_cjs.PLUGIN_REGISTRY).filter((p) => p.adminMenu !== null).map((p) => ({
7670
+ codeName: p.codeName,
7671
+ label: p.adminMenu.label,
7672
+ path: p.adminMenu.path,
7673
+ icon: p.adminMenu.icon,
7674
+ order: p.adminMenu.order
7675
+ }));
7676
+ var ICON_SVG = {
7677
+ "magnifying-glass": '<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="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z"/></svg>',
7678
+ "chart-bar": '<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 13.125C3 12.504 3.504 12 4.125 12h2.25c.621 0 1.125.504 1.125 1.125v6.75C7.5 20.496 6.996 21 6.375 21h-2.25A1.125 1.125 0 0 1 3 19.875v-6.75ZM9.75 8.625c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125v11.25c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V8.625ZM16.5 4.125c0-.621.504-1.125 1.125-1.125h2.25C20.496 3 21 3.504 21 4.125v15.75c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V4.125Z"/></svg>',
7679
+ "image": '<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="m2.25 15.75 5.159-5.159a2.25 2.25 0 0 1 3.182 0l5.159 5.159m-1.5-1.5 1.409-1.409a2.25 2.25 0 0 1 3.182 0l2.909 2.909m-18 3.75h16.5a1.5 1.5 0 0 0 1.5-1.5V6a1.5 1.5 0 0 0-1.5-1.5H3.75A1.5 1.5 0 0 0 2.25 6v12a1.5 1.5 0 0 0 1.5 1.5Zm10.5-11.25h.008v.008h-.008V8.25Zm.375 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Z"/></svg>',
7680
+ "palette": '<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="M4.098 19.902a3.75 3.75 0 0 0 5.304 0l6.401-6.402M6.75 21A3.75 3.75 0 0 1 3 17.25V4.125C3 3.504 3.504 3 4.125 3h5.25c.621 0 1.125.504 1.125 1.125v4.072M6.75 21a3.75 3.75 0 0 0 3.75-3.75V8.197M6.75 21h13.125c.621 0 1.125-.504 1.125-1.125v-5.25c0-.621-.504-1.125-1.125-1.125h-4.072M10.5 8.197l2.88-2.88c.438-.439 1.15-.439 1.59 0l3.712 3.713c.44.44.44 1.152 0 1.59l-2.879 2.88M6.75 17.25h.008v.008H6.75v-.008Z"/></svg>',
7681
+ "envelope": '<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="M21.75 6.75v10.5a2.25 2.25 0 0 1-2.25 2.25h-15a2.25 2.25 0 0 1-2.25-2.25V6.75m19.5 0A2.25 2.25 0 0 0 19.5 4.5h-15a2.25 2.25 0 0 0-2.25 2.25m19.5 0v.243a2.25 2.25 0 0 1-1.07 1.916l-7.5 4.615a2.25 2.25 0 0 1-2.36 0L3.32 8.91a2.25 2.25 0 0 1-1.07-1.916V6.75"/></svg>',
7682
+ "hand-raised": '<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="M10.05 4.575a1.575 1.575 0 1 0-3.15 0v3m3.15-3v-1.5a1.575 1.575 0 0 1 3.15 0v1.5m-3.15 0 .075 5.925m3.075-5.925v2.925m0-2.925a1.575 1.575 0 0 1 3.15 0V9.9m-3.15-2.4v5.325M16.5 9.9a1.575 1.575 0 0 1 3.15 0V15a6.15 6.15 0 0 1-6.15 6.15H12A6.15 6.15 0 0 1 5.85 15V9.525"/></svg>',
7683
+ "key": '<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.75 5.25a3 3 0 0 1 3 3m3 0a6 6 0 0 1-7.029 5.912c-.563-.097-1.159.026-1.563.43L10.5 17.25H8.25v2.25H6v2.25H2.25v-2.818c0-.597.237-1.17.659-1.591l6.499-6.499c.404-.404.527-1 .43-1.563A6 6 0 1 1 21.75 8.25Z"/></svg>',
7684
+ "arrow-right": '<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="M13.5 4.5 21 12m0 0-7.5 7.5M21 12H3"/></svg>',
7685
+ "shield-check": '<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>',
7686
+ "credit-card": '<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="M2.25 8.25h19.5M2.25 9h19.5m-16.5 5.25h6m-6 2.25h3m-3.75 3h15a2.25 2.25 0 0 0 2.25-2.25V6.75A2.25 2.25 0 0 0 19.5 4.5h-15a2.25 2.25 0 0 0-2.25 2.25v10.5A2.25 2.25 0 0 0 4.5 19.5Z"/></svg>'
7687
+ };
7688
+ function resolveIcon(iconName) {
7689
+ if (!iconName) return "";
7690
+ if (iconName.startsWith("<svg") || iconName.startsWith("<")) return iconName;
7691
+ return ICON_SVG[iconName] || "";
7692
+ }
6273
7693
  var MARKER = "<!-- DYNAMIC_PLUGIN_MENU -->";
6274
7694
  function renderMenuItem(item, currentPath) {
6275
7695
  const isActive = currentPath === item.path || currentPath.startsWith(item.path);
6276
7696
  const fallbackIcon = `<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="M13 10V3L4 14h7v7l9-11h-7z"/></svg>`;
7697
+ const resolvedIcon = resolveIcon(item.icon) || fallbackIcon;
6277
7698
  return `
6278
7699
  <span class="relative">
6279
7700
  ${isActive ? '<span class="absolute inset-y-2 -left-4 w-0.5 rounded-full bg-cyan-500 dark:bg-cyan-400"></span>' : ""}
@@ -6283,7 +7704,7 @@ function renderMenuItem(item, currentPath) {
6283
7704
  ${isActive ? 'data-current="true"' : ""}
6284
7705
  >
6285
7706
  <span class="shrink-0 ${isActive ? "fill-zinc-950 dark:fill-white" : "fill-zinc-500 dark:fill-zinc-400"}">
6286
- ${item.icon || fallbackIcon}
7707
+ ${resolvedIcon}
6287
7708
  </span>
6288
7709
  <span class="truncate">${item.label}</span>
6289
7710
  </a>
@@ -6298,23 +7719,28 @@ function pluginMenuMiddleware() {
6298
7719
  let activeMenuItems = [];
6299
7720
  try {
6300
7721
  const db = c.env.DB;
6301
- const pluginNames = MENU_PLUGINS.map((p) => p.name);
6302
- if (pluginNames.length > 0) {
6303
- const placeholders = pluginNames.map(() => "?").join(",");
7722
+ const pluginCodeNames = REGISTRY_MENU_PLUGINS.map((p) => p.codeName);
7723
+ if (pluginCodeNames.length > 0) {
7724
+ const placeholders = pluginCodeNames.map(() => "?").join(",");
6304
7725
  const result = await db.prepare(
6305
7726
  `SELECT name FROM plugins WHERE name IN (${placeholders}) AND status = 'active'`
6306
- ).bind(...pluginNames).all();
7727
+ ).bind(...pluginCodeNames).all();
6307
7728
  const activeNames = new Set((result.results || []).map((r) => r.name));
6308
- for (const plugin2 of MENU_PLUGINS) {
6309
- if (activeNames.has(plugin2.name) && plugin2.menuItems) {
6310
- activeMenuItems.push(...plugin2.menuItems);
7729
+ for (const plugin2 of REGISTRY_MENU_PLUGINS) {
7730
+ if (activeNames.has(plugin2.codeName)) {
7731
+ activeMenuItems.push({
7732
+ label: plugin2.label,
7733
+ path: plugin2.path,
7734
+ icon: plugin2.icon,
7735
+ order: plugin2.order
7736
+ });
6311
7737
  }
6312
7738
  }
6313
- activeMenuItems.sort((a, b) => (a.order || 0) - (b.order || 0));
7739
+ activeMenuItems.sort((a, b) => a.order - b.order);
6314
7740
  }
6315
7741
  } catch {
6316
7742
  }
6317
- c.set("pluginMenuItems", activeMenuItems.map((m) => ({ label: m.label, path: m.path, icon: m.icon || "" })));
7743
+ c.set("pluginMenuItems", activeMenuItems.map((m) => ({ label: m.label, path: m.path, icon: resolveIcon(m.icon) || "" })));
6318
7744
  await next();
6319
7745
  if (activeMenuItems.length > 0 && c.res.headers.get("content-type")?.includes("text/html")) {
6320
7746
  const status = c.res.status;
@@ -7293,7 +8719,7 @@ async function warmNamespace(namespace, entries) {
7293
8719
  }
7294
8720
 
7295
8721
  // src/templates/pages/admin-cache.template.ts
7296
- chunkQP3OHHON_cjs.init_admin_layout_catalyst_template();
8722
+ chunkUYJ6TJHX_cjs.init_admin_layout_catalyst_template();
7297
8723
  function renderCacheDashboard(data) {
7298
8724
  const pageContent = `
7299
8725
  <div class="space-y-6">
@@ -7472,7 +8898,7 @@ function renderCacheDashboard(data) {
7472
8898
  </script>
7473
8899
 
7474
8900
  <!-- Confirmation Dialogs -->
7475
- ${chunkHVTSE2SF_cjs.renderConfirmationDialog({
8901
+ ${chunk26HYU7MX_cjs.renderConfirmationDialog({
7476
8902
  id: "clear-all-cache-confirm",
7477
8903
  title: "Clear All Cache",
7478
8904
  message: "Are you sure you want to clear all cache entries? This cannot be undone.",
@@ -7483,7 +8909,7 @@ function renderCacheDashboard(data) {
7483
8909
  onConfirm: "performClearAllCaches()"
7484
8910
  })}
7485
8911
 
7486
- ${chunkHVTSE2SF_cjs.renderConfirmationDialog({
8912
+ ${chunk26HYU7MX_cjs.renderConfirmationDialog({
7487
8913
  id: "clear-namespace-cache-confirm",
7488
8914
  title: "Clear Namespace Cache",
7489
8915
  message: "Clear cache for this namespace?",
@@ -7494,7 +8920,7 @@ function renderCacheDashboard(data) {
7494
8920
  onConfirm: "performClearNamespaceCache()"
7495
8921
  })}
7496
8922
 
7497
- ${chunkHVTSE2SF_cjs.getConfirmationDialogScript()}
8923
+ ${chunk26HYU7MX_cjs.getConfirmationDialogScript()}
7498
8924
  `;
7499
8925
  const layoutData = {
7500
8926
  title: "Cache System",
@@ -7504,7 +8930,7 @@ function renderCacheDashboard(data) {
7504
8930
  version: data.version,
7505
8931
  content: pageContent
7506
8932
  };
7507
- return chunkQP3OHHON_cjs.renderAdminLayoutCatalyst(layoutData);
8933
+ return chunkUYJ6TJHX_cjs.renderAdminLayoutCatalyst(layoutData);
7508
8934
  }
7509
8935
  function renderStatCard(label, value, color, icon, colorOverride) {
7510
8936
  const finalColor = colorOverride || color;
@@ -8180,14 +9606,14 @@ var faviconSvg = `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
8180
9606
  // src/app.ts
8181
9607
  function createSonicJSApp(config = {}) {
8182
9608
  const app2 = new hono.Hono();
8183
- const appVersion = config.version || chunkXCP5GCBE_cjs.getCoreVersion();
9609
+ const appVersion = config.version || chunkVUISYUHY_cjs.getCoreVersion();
8184
9610
  const appName = config.name || "SonicJS AI";
8185
9611
  app2.use("*", async (c, next) => {
8186
9612
  c.set("appVersion", appVersion);
8187
9613
  await next();
8188
9614
  });
8189
- app2.use("*", chunkEGUDIX6Q_cjs.metricsMiddleware());
8190
- app2.use("*", chunkEGUDIX6Q_cjs.bootstrapMiddleware(config));
9615
+ app2.use("*", chunkUFPT5KCQ_cjs.metricsMiddleware());
9616
+ app2.use("*", chunkUFPT5KCQ_cjs.bootstrapMiddleware(config));
8191
9617
  if (config.middleware?.beforeAuth) {
8192
9618
  for (const middleware of config.middleware.beforeAuth) {
8193
9619
  app2.use("*", middleware);
@@ -8196,29 +9622,29 @@ function createSonicJSApp(config = {}) {
8196
9622
  app2.use("*", async (_c, next) => {
8197
9623
  await next();
8198
9624
  });
8199
- app2.use("*", chunkEGUDIX6Q_cjs.securityHeadersMiddleware());
8200
- app2.use("*", chunkEGUDIX6Q_cjs.csrfProtection());
9625
+ app2.use("*", chunkUFPT5KCQ_cjs.securityHeadersMiddleware());
9626
+ app2.use("*", chunkUFPT5KCQ_cjs.csrfProtection());
8201
9627
  if (config.middleware?.afterAuth) {
8202
9628
  for (const middleware of config.middleware.afterAuth) {
8203
9629
  app2.use("*", middleware);
8204
9630
  }
8205
9631
  }
8206
9632
  app2.use("/admin/*", pluginMenuMiddleware());
8207
- app2.route("/api", chunkHVTSE2SF_cjs.api_default);
8208
- app2.route("/api/media", chunkHVTSE2SF_cjs.api_media_default);
8209
- app2.route("/api/system", chunkHVTSE2SF_cjs.api_system_default);
8210
- app2.route("/admin/api", chunkHVTSE2SF_cjs.admin_api_default);
8211
- app2.route("/admin/dashboard", chunkHVTSE2SF_cjs.router);
8212
- app2.route("/admin/collections", chunkHVTSE2SF_cjs.adminCollectionsRoutes);
8213
- app2.route("/admin/forms", chunkHVTSE2SF_cjs.adminFormsRoutes);
8214
- app2.route("/admin/settings", chunkHVTSE2SF_cjs.adminSettingsRoutes);
8215
- app2.route("/forms", chunkHVTSE2SF_cjs.public_forms_default);
8216
- app2.route("/api/forms", chunkHVTSE2SF_cjs.public_forms_default);
8217
- app2.route("/admin/api-reference", chunkHVTSE2SF_cjs.router2);
9633
+ app2.route("/api", chunk26HYU7MX_cjs.api_default);
9634
+ app2.route("/api/media", chunk26HYU7MX_cjs.api_media_default);
9635
+ app2.route("/api/system", chunk26HYU7MX_cjs.api_system_default);
9636
+ app2.route("/admin/api", chunk26HYU7MX_cjs.admin_api_default);
9637
+ app2.route("/admin/dashboard", chunk26HYU7MX_cjs.router);
9638
+ app2.route("/admin/collections", chunk26HYU7MX_cjs.adminCollectionsRoutes);
9639
+ app2.route("/admin/forms", chunk26HYU7MX_cjs.adminFormsRoutes);
9640
+ app2.route("/admin/settings", chunk26HYU7MX_cjs.adminSettingsRoutes);
9641
+ app2.route("/forms", chunk26HYU7MX_cjs.public_forms_default);
9642
+ app2.route("/api/forms", chunk26HYU7MX_cjs.public_forms_default);
9643
+ app2.route("/admin/api-reference", chunk26HYU7MX_cjs.router2);
8218
9644
  app2.route("/admin/database-tools", createDatabaseToolsAdminRoutes());
8219
9645
  app2.route("/admin/seed-data", createSeedDataAdminRoutes());
8220
- app2.route("/admin/content", chunkHVTSE2SF_cjs.admin_content_default);
8221
- app2.route("/admin/media", chunkHVTSE2SF_cjs.adminMediaRoutes);
9646
+ app2.route("/admin/content", chunk26HYU7MX_cjs.admin_content_default);
9647
+ app2.route("/admin/media", chunk26HYU7MX_cjs.adminMediaRoutes);
8222
9648
  app2.use("/auth/*", securityAuditMiddleware());
8223
9649
  if (securityAuditPlugin.routes && securityAuditPlugin.routes.length > 0) {
8224
9650
  for (const route of securityAuditPlugin.routes) {
@@ -8236,8 +9662,8 @@ function createSonicJSApp(config = {}) {
8236
9662
  app2.route(route.path, route.handler);
8237
9663
  }
8238
9664
  }
8239
- if (chunkHVTSE2SF_cjs.userProfilesPlugin.routes && chunkHVTSE2SF_cjs.userProfilesPlugin.routes.length > 0) {
8240
- for (const route of chunkHVTSE2SF_cjs.userProfilesPlugin.routes) {
9665
+ if (chunk26HYU7MX_cjs.userProfilesPlugin.routes && chunk26HYU7MX_cjs.userProfilesPlugin.routes.length > 0) {
9666
+ for (const route of chunk26HYU7MX_cjs.userProfilesPlugin.routes) {
8241
9667
  app2.route(route.path, route.handler);
8242
9668
  }
8243
9669
  }
@@ -8246,11 +9672,16 @@ function createSonicJSApp(config = {}) {
8246
9672
  app2.route(route.path, route.handler);
8247
9673
  }
8248
9674
  }
8249
- app2.route("/admin/plugins", chunkHVTSE2SF_cjs.adminPluginRoutes);
8250
- app2.route("/admin/logs", chunkHVTSE2SF_cjs.adminLogsRoutes);
8251
- app2.route("/admin", chunkHVTSE2SF_cjs.userRoutes);
8252
- app2.route("/auth", chunkHVTSE2SF_cjs.auth_default);
8253
- app2.route("/", chunkHVTSE2SF_cjs.test_cleanup_default);
9675
+ if (stripePlugin.routes && stripePlugin.routes.length > 0) {
9676
+ for (const route of stripePlugin.routes) {
9677
+ app2.route(route.path, route.handler);
9678
+ }
9679
+ }
9680
+ app2.route("/admin/plugins", chunk26HYU7MX_cjs.adminPluginRoutes);
9681
+ app2.route("/admin/logs", chunk26HYU7MX_cjs.adminLogsRoutes);
9682
+ app2.route("/admin", chunk26HYU7MX_cjs.userRoutes);
9683
+ app2.route("/auth", chunk26HYU7MX_cjs.auth_default);
9684
+ app2.route("/", chunk26HYU7MX_cjs.test_cleanup_default);
8254
9685
  if (emailPlugin.routes && emailPlugin.routes.length > 0) {
8255
9686
  for (const route of emailPlugin.routes) {
8256
9687
  app2.route(route.path, route.handler);
@@ -8334,99 +9765,99 @@ function createDb(d1$1) {
8334
9765
  }
8335
9766
 
8336
9767
  // src/index.ts
8337
- var VERSION = chunkXCP5GCBE_cjs.package_default.version;
9768
+ var VERSION = chunkVUISYUHY_cjs.package_default.version;
8338
9769
 
8339
9770
  Object.defineProperty(exports, "ROUTES_INFO", {
8340
9771
  enumerable: true,
8341
- get: function () { return chunkHVTSE2SF_cjs.ROUTES_INFO; }
9772
+ get: function () { return chunk26HYU7MX_cjs.ROUTES_INFO; }
8342
9773
  });
8343
9774
  Object.defineProperty(exports, "adminApiRoutes", {
8344
9775
  enumerable: true,
8345
- get: function () { return chunkHVTSE2SF_cjs.admin_api_default; }
9776
+ get: function () { return chunk26HYU7MX_cjs.admin_api_default; }
8346
9777
  });
8347
9778
  Object.defineProperty(exports, "adminCheckboxRoutes", {
8348
9779
  enumerable: true,
8349
- get: function () { return chunkHVTSE2SF_cjs.adminCheckboxRoutes; }
9780
+ get: function () { return chunk26HYU7MX_cjs.adminCheckboxRoutes; }
8350
9781
  });
8351
9782
  Object.defineProperty(exports, "adminCodeExamplesRoutes", {
8352
9783
  enumerable: true,
8353
- get: function () { return chunkHVTSE2SF_cjs.admin_code_examples_default; }
9784
+ get: function () { return chunk26HYU7MX_cjs.admin_code_examples_default; }
8354
9785
  });
8355
9786
  Object.defineProperty(exports, "adminCollectionsRoutes", {
8356
9787
  enumerable: true,
8357
- get: function () { return chunkHVTSE2SF_cjs.adminCollectionsRoutes; }
9788
+ get: function () { return chunk26HYU7MX_cjs.adminCollectionsRoutes; }
8358
9789
  });
8359
9790
  Object.defineProperty(exports, "adminContentRoutes", {
8360
9791
  enumerable: true,
8361
- get: function () { return chunkHVTSE2SF_cjs.admin_content_default; }
9792
+ get: function () { return chunk26HYU7MX_cjs.admin_content_default; }
8362
9793
  });
8363
9794
  Object.defineProperty(exports, "adminDashboardRoutes", {
8364
9795
  enumerable: true,
8365
- get: function () { return chunkHVTSE2SF_cjs.router; }
9796
+ get: function () { return chunk26HYU7MX_cjs.router; }
8366
9797
  });
8367
9798
  Object.defineProperty(exports, "adminDesignRoutes", {
8368
9799
  enumerable: true,
8369
- get: function () { return chunkHVTSE2SF_cjs.adminDesignRoutes; }
9800
+ get: function () { return chunk26HYU7MX_cjs.adminDesignRoutes; }
8370
9801
  });
8371
9802
  Object.defineProperty(exports, "adminLogsRoutes", {
8372
9803
  enumerable: true,
8373
- get: function () { return chunkHVTSE2SF_cjs.adminLogsRoutes; }
9804
+ get: function () { return chunk26HYU7MX_cjs.adminLogsRoutes; }
8374
9805
  });
8375
9806
  Object.defineProperty(exports, "adminMediaRoutes", {
8376
9807
  enumerable: true,
8377
- get: function () { return chunkHVTSE2SF_cjs.adminMediaRoutes; }
9808
+ get: function () { return chunk26HYU7MX_cjs.adminMediaRoutes; }
8378
9809
  });
8379
9810
  Object.defineProperty(exports, "adminPluginRoutes", {
8380
9811
  enumerable: true,
8381
- get: function () { return chunkHVTSE2SF_cjs.adminPluginRoutes; }
9812
+ get: function () { return chunk26HYU7MX_cjs.adminPluginRoutes; }
8382
9813
  });
8383
9814
  Object.defineProperty(exports, "adminSettingsRoutes", {
8384
9815
  enumerable: true,
8385
- get: function () { return chunkHVTSE2SF_cjs.adminSettingsRoutes; }
9816
+ get: function () { return chunk26HYU7MX_cjs.adminSettingsRoutes; }
8386
9817
  });
8387
9818
  Object.defineProperty(exports, "adminTestimonialsRoutes", {
8388
9819
  enumerable: true,
8389
- get: function () { return chunkHVTSE2SF_cjs.admin_testimonials_default; }
9820
+ get: function () { return chunk26HYU7MX_cjs.admin_testimonials_default; }
8390
9821
  });
8391
9822
  Object.defineProperty(exports, "adminUsersRoutes", {
8392
9823
  enumerable: true,
8393
- get: function () { return chunkHVTSE2SF_cjs.userRoutes; }
9824
+ get: function () { return chunk26HYU7MX_cjs.userRoutes; }
8394
9825
  });
8395
9826
  Object.defineProperty(exports, "apiContentCrudRoutes", {
8396
9827
  enumerable: true,
8397
- get: function () { return chunkHVTSE2SF_cjs.api_content_crud_default; }
9828
+ get: function () { return chunk26HYU7MX_cjs.api_content_crud_default; }
8398
9829
  });
8399
9830
  Object.defineProperty(exports, "apiMediaRoutes", {
8400
9831
  enumerable: true,
8401
- get: function () { return chunkHVTSE2SF_cjs.api_media_default; }
9832
+ get: function () { return chunk26HYU7MX_cjs.api_media_default; }
8402
9833
  });
8403
9834
  Object.defineProperty(exports, "apiRoutes", {
8404
9835
  enumerable: true,
8405
- get: function () { return chunkHVTSE2SF_cjs.api_default; }
9836
+ get: function () { return chunk26HYU7MX_cjs.api_default; }
8406
9837
  });
8407
9838
  Object.defineProperty(exports, "apiSystemRoutes", {
8408
9839
  enumerable: true,
8409
- get: function () { return chunkHVTSE2SF_cjs.api_system_default; }
9840
+ get: function () { return chunk26HYU7MX_cjs.api_system_default; }
8410
9841
  });
8411
9842
  Object.defineProperty(exports, "authRoutes", {
8412
9843
  enumerable: true,
8413
- get: function () { return chunkHVTSE2SF_cjs.auth_default; }
9844
+ get: function () { return chunk26HYU7MX_cjs.auth_default; }
8414
9845
  });
8415
9846
  Object.defineProperty(exports, "createUserProfilesPlugin", {
8416
9847
  enumerable: true,
8417
- get: function () { return chunkHVTSE2SF_cjs.createUserProfilesPlugin; }
9848
+ get: function () { return chunk26HYU7MX_cjs.createUserProfilesPlugin; }
8418
9849
  });
8419
9850
  Object.defineProperty(exports, "defineUserProfile", {
8420
9851
  enumerable: true,
8421
- get: function () { return chunkHVTSE2SF_cjs.defineUserProfile; }
9852
+ get: function () { return chunk26HYU7MX_cjs.defineUserProfile; }
8422
9853
  });
8423
9854
  Object.defineProperty(exports, "getUserProfileConfig", {
8424
9855
  enumerable: true,
8425
- get: function () { return chunkHVTSE2SF_cjs.getUserProfileConfig; }
9856
+ get: function () { return chunk26HYU7MX_cjs.getUserProfileConfig; }
8426
9857
  });
8427
9858
  Object.defineProperty(exports, "userProfilesPlugin", {
8428
9859
  enumerable: true,
8429
- get: function () { return chunkHVTSE2SF_cjs.userProfilesPlugin; }
9860
+ get: function () { return chunk26HYU7MX_cjs.userProfilesPlugin; }
8430
9861
  });
8431
9862
  Object.defineProperty(exports, "Logger", {
8432
9863
  enumerable: true,
@@ -8594,259 +10025,259 @@ Object.defineProperty(exports, "workflowHistory", {
8594
10025
  });
8595
10026
  Object.defineProperty(exports, "AuthManager", {
8596
10027
  enumerable: true,
8597
- get: function () { return chunkEGUDIX6Q_cjs.AuthManager; }
10028
+ get: function () { return chunkUFPT5KCQ_cjs.AuthManager; }
8598
10029
  });
8599
10030
  Object.defineProperty(exports, "PermissionManager", {
8600
10031
  enumerable: true,
8601
- get: function () { return chunkEGUDIX6Q_cjs.PermissionManager; }
10032
+ get: function () { return chunkUFPT5KCQ_cjs.PermissionManager; }
8602
10033
  });
8603
10034
  Object.defineProperty(exports, "bootstrapMiddleware", {
8604
10035
  enumerable: true,
8605
- get: function () { return chunkEGUDIX6Q_cjs.bootstrapMiddleware; }
10036
+ get: function () { return chunkUFPT5KCQ_cjs.bootstrapMiddleware; }
8606
10037
  });
8607
10038
  Object.defineProperty(exports, "cacheHeaders", {
8608
10039
  enumerable: true,
8609
- get: function () { return chunkEGUDIX6Q_cjs.cacheHeaders; }
10040
+ get: function () { return chunkUFPT5KCQ_cjs.cacheHeaders; }
8610
10041
  });
8611
10042
  Object.defineProperty(exports, "compressionMiddleware", {
8612
10043
  enumerable: true,
8613
- get: function () { return chunkEGUDIX6Q_cjs.compressionMiddleware; }
10044
+ get: function () { return chunkUFPT5KCQ_cjs.compressionMiddleware; }
8614
10045
  });
8615
10046
  Object.defineProperty(exports, "detailedLoggingMiddleware", {
8616
10047
  enumerable: true,
8617
- get: function () { return chunkEGUDIX6Q_cjs.detailedLoggingMiddleware; }
10048
+ get: function () { return chunkUFPT5KCQ_cjs.detailedLoggingMiddleware; }
8618
10049
  });
8619
10050
  Object.defineProperty(exports, "getActivePlugins", {
8620
10051
  enumerable: true,
8621
- get: function () { return chunkEGUDIX6Q_cjs.getActivePlugins; }
10052
+ get: function () { return chunkUFPT5KCQ_cjs.getActivePlugins; }
8622
10053
  });
8623
10054
  Object.defineProperty(exports, "isPluginActive", {
8624
10055
  enumerable: true,
8625
- get: function () { return chunkEGUDIX6Q_cjs.isPluginActive; }
10056
+ get: function () { return chunkUFPT5KCQ_cjs.isPluginActive; }
8626
10057
  });
8627
10058
  Object.defineProperty(exports, "logActivity", {
8628
10059
  enumerable: true,
8629
- get: function () { return chunkEGUDIX6Q_cjs.logActivity; }
10060
+ get: function () { return chunkUFPT5KCQ_cjs.logActivity; }
8630
10061
  });
8631
10062
  Object.defineProperty(exports, "loggingMiddleware", {
8632
10063
  enumerable: true,
8633
- get: function () { return chunkEGUDIX6Q_cjs.loggingMiddleware; }
10064
+ get: function () { return chunkUFPT5KCQ_cjs.loggingMiddleware; }
8634
10065
  });
8635
10066
  Object.defineProperty(exports, "optionalAuth", {
8636
10067
  enumerable: true,
8637
- get: function () { return chunkEGUDIX6Q_cjs.optionalAuth; }
10068
+ get: function () { return chunkUFPT5KCQ_cjs.optionalAuth; }
8638
10069
  });
8639
10070
  Object.defineProperty(exports, "performanceLoggingMiddleware", {
8640
10071
  enumerable: true,
8641
- get: function () { return chunkEGUDIX6Q_cjs.performanceLoggingMiddleware; }
10072
+ get: function () { return chunkUFPT5KCQ_cjs.performanceLoggingMiddleware; }
8642
10073
  });
8643
10074
  Object.defineProperty(exports, "requireActivePlugin", {
8644
10075
  enumerable: true,
8645
- get: function () { return chunkEGUDIX6Q_cjs.requireActivePlugin; }
10076
+ get: function () { return chunkUFPT5KCQ_cjs.requireActivePlugin; }
8646
10077
  });
8647
10078
  Object.defineProperty(exports, "requireActivePlugins", {
8648
10079
  enumerable: true,
8649
- get: function () { return chunkEGUDIX6Q_cjs.requireActivePlugins; }
10080
+ get: function () { return chunkUFPT5KCQ_cjs.requireActivePlugins; }
8650
10081
  });
8651
10082
  Object.defineProperty(exports, "requireAnyPermission", {
8652
10083
  enumerable: true,
8653
- get: function () { return chunkEGUDIX6Q_cjs.requireAnyPermission; }
10084
+ get: function () { return chunkUFPT5KCQ_cjs.requireAnyPermission; }
8654
10085
  });
8655
10086
  Object.defineProperty(exports, "requireAuth", {
8656
10087
  enumerable: true,
8657
- get: function () { return chunkEGUDIX6Q_cjs.requireAuth; }
10088
+ get: function () { return chunkUFPT5KCQ_cjs.requireAuth; }
8658
10089
  });
8659
10090
  Object.defineProperty(exports, "requirePermission", {
8660
10091
  enumerable: true,
8661
- get: function () { return chunkEGUDIX6Q_cjs.requirePermission; }
10092
+ get: function () { return chunkUFPT5KCQ_cjs.requirePermission; }
8662
10093
  });
8663
10094
  Object.defineProperty(exports, "requireRole", {
8664
10095
  enumerable: true,
8665
- get: function () { return chunkEGUDIX6Q_cjs.requireRole; }
10096
+ get: function () { return chunkUFPT5KCQ_cjs.requireRole; }
8666
10097
  });
8667
10098
  Object.defineProperty(exports, "securityHeaders", {
8668
10099
  enumerable: true,
8669
- get: function () { return chunkEGUDIX6Q_cjs.securityHeadersMiddleware; }
10100
+ get: function () { return chunkUFPT5KCQ_cjs.securityHeadersMiddleware; }
8670
10101
  });
8671
10102
  Object.defineProperty(exports, "securityLoggingMiddleware", {
8672
10103
  enumerable: true,
8673
- get: function () { return chunkEGUDIX6Q_cjs.securityLoggingMiddleware; }
10104
+ get: function () { return chunkUFPT5KCQ_cjs.securityLoggingMiddleware; }
8674
10105
  });
8675
10106
  Object.defineProperty(exports, "PluginBootstrapService", {
8676
10107
  enumerable: true,
8677
- get: function () { return chunkI6FFGQIT_cjs.PluginBootstrapService; }
10108
+ get: function () { return chunk43AB4EH4_cjs.PluginBootstrapService; }
8678
10109
  });
8679
10110
  Object.defineProperty(exports, "PluginServiceClass", {
8680
10111
  enumerable: true,
8681
- get: function () { return chunkI6FFGQIT_cjs.PluginService; }
10112
+ get: function () { return chunk43AB4EH4_cjs.PluginService; }
8682
10113
  });
8683
10114
  Object.defineProperty(exports, "backfillFormSubmissions", {
8684
10115
  enumerable: true,
8685
- get: function () { return chunkI6FFGQIT_cjs.backfillFormSubmissions; }
10116
+ get: function () { return chunk43AB4EH4_cjs.backfillFormSubmissions; }
8686
10117
  });
8687
10118
  Object.defineProperty(exports, "cleanupRemovedCollections", {
8688
10119
  enumerable: true,
8689
- get: function () { return chunkI6FFGQIT_cjs.cleanupRemovedCollections; }
10120
+ get: function () { return chunk43AB4EH4_cjs.cleanupRemovedCollections; }
8690
10121
  });
8691
10122
  Object.defineProperty(exports, "createContentFromSubmission", {
8692
10123
  enumerable: true,
8693
- get: function () { return chunkI6FFGQIT_cjs.createContentFromSubmission; }
10124
+ get: function () { return chunk43AB4EH4_cjs.createContentFromSubmission; }
8694
10125
  });
8695
10126
  Object.defineProperty(exports, "deriveCollectionSchemaFromFormio", {
8696
10127
  enumerable: true,
8697
- get: function () { return chunkI6FFGQIT_cjs.deriveCollectionSchemaFromFormio; }
10128
+ get: function () { return chunk43AB4EH4_cjs.deriveCollectionSchemaFromFormio; }
8698
10129
  });
8699
10130
  Object.defineProperty(exports, "deriveSubmissionTitle", {
8700
10131
  enumerable: true,
8701
- get: function () { return chunkI6FFGQIT_cjs.deriveSubmissionTitle; }
10132
+ get: function () { return chunk43AB4EH4_cjs.deriveSubmissionTitle; }
8702
10133
  });
8703
10134
  Object.defineProperty(exports, "fullCollectionSync", {
8704
10135
  enumerable: true,
8705
- get: function () { return chunkI6FFGQIT_cjs.fullCollectionSync; }
10136
+ get: function () { return chunk43AB4EH4_cjs.fullCollectionSync; }
8706
10137
  });
8707
10138
  Object.defineProperty(exports, "getAvailableCollectionNames", {
8708
10139
  enumerable: true,
8709
- get: function () { return chunkI6FFGQIT_cjs.getAvailableCollectionNames; }
10140
+ get: function () { return chunk43AB4EH4_cjs.getAvailableCollectionNames; }
8710
10141
  });
8711
10142
  Object.defineProperty(exports, "getManagedCollections", {
8712
10143
  enumerable: true,
8713
- get: function () { return chunkI6FFGQIT_cjs.getManagedCollections; }
10144
+ get: function () { return chunk43AB4EH4_cjs.getManagedCollections; }
8714
10145
  });
8715
10146
  Object.defineProperty(exports, "isCollectionManaged", {
8716
10147
  enumerable: true,
8717
- get: function () { return chunkI6FFGQIT_cjs.isCollectionManaged; }
10148
+ get: function () { return chunk43AB4EH4_cjs.isCollectionManaged; }
8718
10149
  });
8719
10150
  Object.defineProperty(exports, "loadCollectionConfig", {
8720
10151
  enumerable: true,
8721
- get: function () { return chunkI6FFGQIT_cjs.loadCollectionConfig; }
10152
+ get: function () { return chunk43AB4EH4_cjs.loadCollectionConfig; }
8722
10153
  });
8723
10154
  Object.defineProperty(exports, "loadCollectionConfigs", {
8724
10155
  enumerable: true,
8725
- get: function () { return chunkI6FFGQIT_cjs.loadCollectionConfigs; }
10156
+ get: function () { return chunk43AB4EH4_cjs.loadCollectionConfigs; }
8726
10157
  });
8727
10158
  Object.defineProperty(exports, "mapFormStatusToContentStatus", {
8728
10159
  enumerable: true,
8729
- get: function () { return chunkI6FFGQIT_cjs.mapFormStatusToContentStatus; }
10160
+ get: function () { return chunk43AB4EH4_cjs.mapFormStatusToContentStatus; }
8730
10161
  });
8731
10162
  Object.defineProperty(exports, "registerCollections", {
8732
10163
  enumerable: true,
8733
- get: function () { return chunkI6FFGQIT_cjs.registerCollections; }
10164
+ get: function () { return chunk43AB4EH4_cjs.registerCollections; }
8734
10165
  });
8735
10166
  Object.defineProperty(exports, "syncAllFormCollections", {
8736
10167
  enumerable: true,
8737
- get: function () { return chunkI6FFGQIT_cjs.syncAllFormCollections; }
10168
+ get: function () { return chunk43AB4EH4_cjs.syncAllFormCollections; }
8738
10169
  });
8739
10170
  Object.defineProperty(exports, "syncCollection", {
8740
10171
  enumerable: true,
8741
- get: function () { return chunkI6FFGQIT_cjs.syncCollection; }
10172
+ get: function () { return chunk43AB4EH4_cjs.syncCollection; }
8742
10173
  });
8743
10174
  Object.defineProperty(exports, "syncCollections", {
8744
10175
  enumerable: true,
8745
- get: function () { return chunkI6FFGQIT_cjs.syncCollections; }
10176
+ get: function () { return chunk43AB4EH4_cjs.syncCollections; }
8746
10177
  });
8747
10178
  Object.defineProperty(exports, "syncFormCollection", {
8748
10179
  enumerable: true,
8749
- get: function () { return chunkI6FFGQIT_cjs.syncFormCollection; }
10180
+ get: function () { return chunk43AB4EH4_cjs.syncFormCollection; }
8750
10181
  });
8751
10182
  Object.defineProperty(exports, "validateCollectionConfig", {
8752
10183
  enumerable: true,
8753
- get: function () { return chunkI6FFGQIT_cjs.validateCollectionConfig; }
10184
+ get: function () { return chunk43AB4EH4_cjs.validateCollectionConfig; }
8754
10185
  });
8755
10186
  Object.defineProperty(exports, "MigrationService", {
8756
10187
  enumerable: true,
8757
- get: function () { return chunkSER23XI4_cjs.MigrationService; }
10188
+ get: function () { return chunkRVD7PLMU_cjs.MigrationService; }
8758
10189
  });
8759
10190
  Object.defineProperty(exports, "renderFilterBar", {
8760
10191
  enumerable: true,
8761
- get: function () { return chunk3QCEYJLK_cjs.renderFilterBar; }
10192
+ get: function () { return chunk4ZSNJDLS_cjs.renderFilterBar; }
8762
10193
  });
8763
10194
  Object.defineProperty(exports, "getConfirmationDialogScript", {
8764
10195
  enumerable: true,
8765
- get: function () { return chunkQP3OHHON_cjs.getConfirmationDialogScript; }
10196
+ get: function () { return chunkOHYBNCVL_cjs.getConfirmationDialogScript; }
8766
10197
  });
8767
10198
  Object.defineProperty(exports, "renderAlert", {
8768
10199
  enumerable: true,
8769
- get: function () { return chunkQP3OHHON_cjs.renderAlert; }
10200
+ get: function () { return chunkOHYBNCVL_cjs.renderAlert; }
8770
10201
  });
8771
10202
  Object.defineProperty(exports, "renderConfirmationDialog", {
8772
10203
  enumerable: true,
8773
- get: function () { return chunkQP3OHHON_cjs.renderConfirmationDialog; }
10204
+ get: function () { return chunkOHYBNCVL_cjs.renderConfirmationDialog; }
8774
10205
  });
8775
10206
  Object.defineProperty(exports, "renderForm", {
8776
10207
  enumerable: true,
8777
- get: function () { return chunkQP3OHHON_cjs.renderForm; }
10208
+ get: function () { return chunkOHYBNCVL_cjs.renderForm; }
8778
10209
  });
8779
10210
  Object.defineProperty(exports, "renderFormField", {
8780
10211
  enumerable: true,
8781
- get: function () { return chunkQP3OHHON_cjs.renderFormField; }
10212
+ get: function () { return chunkOHYBNCVL_cjs.renderFormField; }
8782
10213
  });
8783
10214
  Object.defineProperty(exports, "renderPagination", {
8784
10215
  enumerable: true,
8785
- get: function () { return chunkQP3OHHON_cjs.renderPagination; }
10216
+ get: function () { return chunkOHYBNCVL_cjs.renderPagination; }
8786
10217
  });
8787
10218
  Object.defineProperty(exports, "renderTable", {
8788
10219
  enumerable: true,
8789
- get: function () { return chunkQP3OHHON_cjs.renderTable; }
10220
+ get: function () { return chunkOHYBNCVL_cjs.renderTable; }
8790
10221
  });
8791
10222
  Object.defineProperty(exports, "HookSystemImpl", {
8792
10223
  enumerable: true,
8793
- get: function () { return chunk56GUBLJE_cjs.HookSystemImpl; }
10224
+ get: function () { return chunkABB34XUS_cjs.HookSystemImpl; }
8794
10225
  });
8795
10226
  Object.defineProperty(exports, "HookUtils", {
8796
10227
  enumerable: true,
8797
- get: function () { return chunk56GUBLJE_cjs.HookUtils; }
10228
+ get: function () { return chunkABB34XUS_cjs.HookUtils; }
8798
10229
  });
8799
10230
  Object.defineProperty(exports, "PluginManagerClass", {
8800
10231
  enumerable: true,
8801
- get: function () { return chunk56GUBLJE_cjs.PluginManager; }
10232
+ get: function () { return chunkABB34XUS_cjs.PluginManager; }
8802
10233
  });
8803
10234
  Object.defineProperty(exports, "PluginRegistryImpl", {
8804
10235
  enumerable: true,
8805
- get: function () { return chunk56GUBLJE_cjs.PluginRegistryImpl; }
10236
+ get: function () { return chunkABB34XUS_cjs.PluginRegistryImpl; }
8806
10237
  });
8807
10238
  Object.defineProperty(exports, "PluginValidatorClass", {
8808
10239
  enumerable: true,
8809
- get: function () { return chunk56GUBLJE_cjs.PluginValidator; }
10240
+ get: function () { return chunkABB34XUS_cjs.PluginValidator; }
8810
10241
  });
8811
10242
  Object.defineProperty(exports, "ScopedHookSystemClass", {
8812
10243
  enumerable: true,
8813
- get: function () { return chunk56GUBLJE_cjs.ScopedHookSystem; }
10244
+ get: function () { return chunkABB34XUS_cjs.ScopedHookSystem; }
8814
10245
  });
8815
10246
  Object.defineProperty(exports, "PluginBuilder", {
8816
10247
  enumerable: true,
8817
- get: function () { return chunk6FHNRRJ3_cjs.PluginBuilder; }
10248
+ get: function () { return chunk635JAMSE_cjs.PluginBuilder; }
8818
10249
  });
8819
10250
  Object.defineProperty(exports, "PluginHelpers", {
8820
10251
  enumerable: true,
8821
- get: function () { return chunk6FHNRRJ3_cjs.PluginHelpers; }
10252
+ get: function () { return chunk635JAMSE_cjs.PluginHelpers; }
8822
10253
  });
8823
10254
  Object.defineProperty(exports, "QueryFilterBuilder", {
8824
10255
  enumerable: true,
8825
- get: function () { return chunkXCP5GCBE_cjs.QueryFilterBuilder; }
10256
+ get: function () { return chunkVUISYUHY_cjs.QueryFilterBuilder; }
8826
10257
  });
8827
10258
  Object.defineProperty(exports, "SONICJS_VERSION", {
8828
10259
  enumerable: true,
8829
- get: function () { return chunkXCP5GCBE_cjs.SONICJS_VERSION; }
10260
+ get: function () { return chunkVUISYUHY_cjs.SONICJS_VERSION; }
8830
10261
  });
8831
10262
  Object.defineProperty(exports, "TemplateRenderer", {
8832
10263
  enumerable: true,
8833
- get: function () { return chunkXCP5GCBE_cjs.TemplateRenderer; }
10264
+ get: function () { return chunkVUISYUHY_cjs.TemplateRenderer; }
8834
10265
  });
8835
10266
  Object.defineProperty(exports, "buildQuery", {
8836
10267
  enumerable: true,
8837
- get: function () { return chunkXCP5GCBE_cjs.buildQuery; }
10268
+ get: function () { return chunkVUISYUHY_cjs.buildQuery; }
8838
10269
  });
8839
10270
  Object.defineProperty(exports, "getCoreVersion", {
8840
10271
  enumerable: true,
8841
- get: function () { return chunkXCP5GCBE_cjs.getCoreVersion; }
10272
+ get: function () { return chunkVUISYUHY_cjs.getCoreVersion; }
8842
10273
  });
8843
10274
  Object.defineProperty(exports, "renderTemplate", {
8844
10275
  enumerable: true,
8845
- get: function () { return chunkXCP5GCBE_cjs.renderTemplate; }
10276
+ get: function () { return chunkVUISYUHY_cjs.renderTemplate; }
8846
10277
  });
8847
10278
  Object.defineProperty(exports, "templateRenderer", {
8848
10279
  enumerable: true,
8849
- get: function () { return chunkXCP5GCBE_cjs.templateRenderer; }
10280
+ get: function () { return chunkVUISYUHY_cjs.templateRenderer; }
8850
10281
  });
8851
10282
  Object.defineProperty(exports, "metricsTracker", {
8852
10283
  enumerable: true,