@sonicjs-cms/core 2.8.2 → 2.8.3

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 (47) hide show
  1. package/dist/{chunk-WI5ESQKT.js → chunk-5XAI2XUF.js} +3 -3
  2. package/dist/{chunk-WI5ESQKT.js.map → chunk-5XAI2XUF.js.map} +1 -1
  3. package/dist/{chunk-4Z5BQZT6.js → chunk-CH5UHZVM.js} +160 -23
  4. package/dist/chunk-CH5UHZVM.js.map +1 -0
  5. package/dist/{chunk-I6REMSMF.js → chunk-GTFMI24U.js} +2 -2
  6. package/dist/{chunk-I6REMSMF.js.map → chunk-GTFMI24U.js.map} +1 -1
  7. package/dist/{chunk-VGSZWZP3.cjs → chunk-HXHVU5GM.cjs} +2 -2
  8. package/dist/{chunk-VGSZWZP3.cjs.map → chunk-HXHVU5GM.cjs.map} +1 -1
  9. package/dist/{chunk-JSHIGVIF.cjs → chunk-JDIM5AG7.cjs} +3 -3
  10. package/dist/{chunk-JSHIGVIF.cjs.map → chunk-JDIM5AG7.cjs.map} +1 -1
  11. package/dist/{chunk-ZWKCL46S.cjs → chunk-K4Q4SFJJ.cjs} +4 -4
  12. package/dist/{chunk-ZWKCL46S.cjs.map → chunk-K4Q4SFJJ.cjs.map} +1 -1
  13. package/dist/{chunk-3U5YHS4G.cjs → chunk-R4WR3VTN.cjs} +238 -101
  14. package/dist/chunk-R4WR3VTN.cjs.map +1 -0
  15. package/dist/{chunk-FUUVSYVQ.js → chunk-Y3VMEGY2.js} +3 -3
  16. package/dist/{chunk-FUUVSYVQ.js.map → chunk-Y3VMEGY2.js.map} +1 -1
  17. package/dist/{collection-config-BF95LgQb.d.cts → collection-config-i8EaAF7z.d.cts} +2 -1
  18. package/dist/{collection-config-BF95LgQb.d.ts → collection-config-i8EaAF7z.d.ts} +2 -1
  19. package/dist/index.cjs +83 -83
  20. package/dist/index.d.cts +3 -3
  21. package/dist/index.d.ts +3 -3
  22. package/dist/index.js +7 -7
  23. package/dist/middleware.cjs +28 -28
  24. package/dist/middleware.js +2 -2
  25. package/dist/migrations-7X4RPH7O.cjs +13 -0
  26. package/dist/{migrations-F3G6CTRS.cjs.map → migrations-7X4RPH7O.cjs.map} +1 -1
  27. package/dist/migrations-KHWFJ2HN.js +4 -0
  28. package/dist/{migrations-LLNEST75.js.map → migrations-KHWFJ2HN.js.map} +1 -1
  29. package/dist/{plugin-bootstrap-C7Mj00Ud.d.ts → plugin-bootstrap-CJozpgmI.d.cts} +1 -1
  30. package/dist/{plugin-bootstrap-DKB5f8-E.d.cts → plugin-bootstrap-DU5VmuHZ.d.ts} +1 -1
  31. package/dist/routes.cjs +27 -27
  32. package/dist/routes.js +4 -4
  33. package/dist/services.cjs +2 -2
  34. package/dist/services.d.cts +2 -2
  35. package/dist/services.d.ts +2 -2
  36. package/dist/services.js +1 -1
  37. package/dist/types.d.cts +1 -1
  38. package/dist/types.d.ts +1 -1
  39. package/dist/utils.cjs +11 -11
  40. package/dist/utils.d.cts +1 -1
  41. package/dist/utils.d.ts +1 -1
  42. package/dist/utils.js +1 -1
  43. package/package.json +1 -1
  44. package/dist/chunk-3U5YHS4G.cjs.map +0 -1
  45. package/dist/chunk-4Z5BQZT6.js.map +0 -1
  46. package/dist/migrations-F3G6CTRS.cjs +0 -13
  47. package/dist/migrations-LLNEST75.js +0 -4
@@ -1,12 +1,12 @@
1
1
  'use strict';
2
2
 
3
3
  var chunkVNLR35GO_cjs = require('./chunk-VNLR35GO.cjs');
4
- var chunkZWKCL46S_cjs = require('./chunk-ZWKCL46S.cjs');
4
+ var chunkK4Q4SFJJ_cjs = require('./chunk-K4Q4SFJJ.cjs');
5
5
  var chunkMPT5PA6U_cjs = require('./chunk-MPT5PA6U.cjs');
6
- var chunkVGSZWZP3_cjs = require('./chunk-VGSZWZP3.cjs');
6
+ var chunkHXHVU5GM_cjs = require('./chunk-HXHVU5GM.cjs');
7
7
  var chunkLTKV7AE5_cjs = require('./chunk-LTKV7AE5.cjs');
8
8
  var chunk6FHNRRJ3_cjs = require('./chunk-6FHNRRJ3.cjs');
9
- var chunkJSHIGVIF_cjs = require('./chunk-JSHIGVIF.cjs');
9
+ var chunkJDIM5AG7_cjs = require('./chunk-JDIM5AG7.cjs');
10
10
  var chunkRCQ2HIQD_cjs = require('./chunk-RCQ2HIQD.cjs');
11
11
  var chunkMNWKYY5E_cjs = require('./chunk-MNWKYY5E.cjs');
12
12
  var hono = require('hono');
@@ -121,7 +121,7 @@ apiContentCrudRoutes.get("/:id", async (c) => {
121
121
  }, 500);
122
122
  }
123
123
  });
124
- apiContentCrudRoutes.post("/", chunkZWKCL46S_cjs.requireAuth(), async (c) => {
124
+ apiContentCrudRoutes.post("/", chunkK4Q4SFJJ_cjs.requireAuth(), async (c) => {
125
125
  try {
126
126
  const db = c.env.DB;
127
127
  const user = c.get("user");
@@ -187,7 +187,7 @@ apiContentCrudRoutes.post("/", chunkZWKCL46S_cjs.requireAuth(), async (c) => {
187
187
  }, 500);
188
188
  }
189
189
  });
190
- apiContentCrudRoutes.put("/:id", chunkZWKCL46S_cjs.requireAuth(), async (c) => {
190
+ apiContentCrudRoutes.put("/:id", chunkK4Q4SFJJ_cjs.requireAuth(), async (c) => {
191
191
  try {
192
192
  const id = c.req.param("id");
193
193
  const db = c.env.DB;
@@ -251,7 +251,7 @@ apiContentCrudRoutes.put("/:id", chunkZWKCL46S_cjs.requireAuth(), async (c) => {
251
251
  }, 500);
252
252
  }
253
253
  });
254
- apiContentCrudRoutes.delete("/:id", chunkZWKCL46S_cjs.requireAuth(), async (c) => {
254
+ apiContentCrudRoutes.delete("/:id", chunkK4Q4SFJJ_cjs.requireAuth(), async (c) => {
255
255
  try {
256
256
  const id = c.req.param("id");
257
257
  const db = c.env.DB;
@@ -287,7 +287,7 @@ apiRoutes.use("*", async (c, next) => {
287
287
  c.header("X-Response-Time", `${totalTime}ms`);
288
288
  });
289
289
  apiRoutes.use("*", async (c, next) => {
290
- const cacheEnabled = await chunkZWKCL46S_cjs.isPluginActive(c.env.DB, "core-cache");
290
+ const cacheEnabled = await chunkK4Q4SFJJ_cjs.isPluginActive(c.env.DB, "core-cache");
291
291
  c.set("cacheEnabled", cacheEnabled);
292
292
  await next();
293
293
  });
@@ -778,7 +778,7 @@ apiRoutes.get("/collections", async (c) => {
778
778
  return c.json({ error: "Failed to fetch collections" }, 500);
779
779
  }
780
780
  });
781
- apiRoutes.get("/content", chunkZWKCL46S_cjs.optionalAuth(), async (c) => {
781
+ apiRoutes.get("/content", chunkK4Q4SFJJ_cjs.optionalAuth(), async (c) => {
782
782
  const executionStart = Date.now();
783
783
  try {
784
784
  const db = c.env.DB;
@@ -801,13 +801,13 @@ apiRoutes.get("/content", chunkZWKCL46S_cjs.optionalAuth(), async (c) => {
801
801
  });
802
802
  }
803
803
  }
804
- const filter = chunkJSHIGVIF_cjs.QueryFilterBuilder.parseFromQuery(queryParams);
804
+ const filter = chunkJDIM5AG7_cjs.QueryFilterBuilder.parseFromQuery(queryParams);
805
805
  const normalizedFilter = normalizePublicContentFilter(filter, c.get("user")?.role);
806
806
  if (!normalizedFilter.limit) {
807
807
  normalizedFilter.limit = 50;
808
808
  }
809
809
  normalizedFilter.limit = Math.min(normalizedFilter.limit, 1e3);
810
- const builder3 = new chunkJSHIGVIF_cjs.QueryFilterBuilder();
810
+ const builder3 = new chunkJDIM5AG7_cjs.QueryFilterBuilder();
811
811
  const queryResult = builder3.build("content", normalizedFilter);
812
812
  if (queryResult.errors.length > 0) {
813
813
  return c.json({
@@ -879,7 +879,7 @@ apiRoutes.get("/content", chunkZWKCL46S_cjs.optionalAuth(), async (c) => {
879
879
  }, 500);
880
880
  }
881
881
  });
882
- apiRoutes.get("/collections/:collection/content", chunkZWKCL46S_cjs.optionalAuth(), async (c) => {
882
+ apiRoutes.get("/collections/:collection/content", chunkK4Q4SFJJ_cjs.optionalAuth(), async (c) => {
883
883
  const executionStart = Date.now();
884
884
  try {
885
885
  const collection = c.req.param("collection");
@@ -890,7 +890,7 @@ apiRoutes.get("/collections/:collection/content", chunkZWKCL46S_cjs.optionalAuth
890
890
  if (!collectionResult) {
891
891
  return c.json({ error: "Collection not found" }, 404);
892
892
  }
893
- const filter = chunkJSHIGVIF_cjs.QueryFilterBuilder.parseFromQuery(queryParams);
893
+ const filter = chunkJDIM5AG7_cjs.QueryFilterBuilder.parseFromQuery(queryParams);
894
894
  const normalizedFilter = normalizePublicContentFilter(filter, c.get("user")?.role);
895
895
  if (!normalizedFilter.where) {
896
896
  normalizedFilter.where = { and: [] };
@@ -907,7 +907,7 @@ apiRoutes.get("/collections/:collection/content", chunkZWKCL46S_cjs.optionalAuth
907
907
  normalizedFilter.limit = 50;
908
908
  }
909
909
  normalizedFilter.limit = Math.min(normalizedFilter.limit, 1e3);
910
- const builder3 = new chunkJSHIGVIF_cjs.QueryFilterBuilder();
910
+ const builder3 = new chunkJDIM5AG7_cjs.QueryFilterBuilder();
911
911
  const queryResult = builder3.build("content", normalizedFilter);
912
912
  if (queryResult.errors.length > 0) {
913
913
  return c.json({
@@ -1028,7 +1028,7 @@ var fileValidationSchema = zod.z.object({
1028
1028
  // 50MB max
1029
1029
  });
1030
1030
  var apiMediaRoutes = new hono.Hono();
1031
- apiMediaRoutes.use("*", chunkZWKCL46S_cjs.requireAuth());
1031
+ apiMediaRoutes.use("*", chunkK4Q4SFJJ_cjs.requireAuth());
1032
1032
  apiMediaRoutes.post("/upload", async (c) => {
1033
1033
  try {
1034
1034
  const user = c.get("user");
@@ -1772,8 +1772,8 @@ apiSystemRoutes.get("/env", (c) => {
1772
1772
  });
1773
1773
  var api_system_default = apiSystemRoutes;
1774
1774
  var adminApiRoutes = new hono.Hono();
1775
- adminApiRoutes.use("*", chunkZWKCL46S_cjs.requireAuth());
1776
- adminApiRoutes.use("*", chunkZWKCL46S_cjs.requireRole(["admin", "editor"]));
1775
+ adminApiRoutes.use("*", chunkK4Q4SFJJ_cjs.requireAuth());
1776
+ adminApiRoutes.use("*", chunkK4Q4SFJJ_cjs.requireRole(["admin", "editor"]));
1777
1777
  adminApiRoutes.get("/stats", async (c) => {
1778
1778
  try {
1779
1779
  const db = c.env.DB;
@@ -2283,7 +2283,7 @@ adminApiRoutes.delete("/collections/:id", async (c) => {
2283
2283
  });
2284
2284
  adminApiRoutes.get("/migrations/status", async (c) => {
2285
2285
  try {
2286
- const { MigrationService: MigrationService2 } = await import('./migrations-F3G6CTRS.cjs');
2286
+ const { MigrationService: MigrationService2 } = await import('./migrations-7X4RPH7O.cjs');
2287
2287
  const db = c.env.DB;
2288
2288
  const migrationService = new MigrationService2(db);
2289
2289
  const status = await migrationService.getMigrationStatus();
@@ -2308,7 +2308,7 @@ adminApiRoutes.post("/migrations/run", async (c) => {
2308
2308
  error: "Unauthorized. Admin access required."
2309
2309
  }, 403);
2310
2310
  }
2311
- const { MigrationService: MigrationService2 } = await import('./migrations-F3G6CTRS.cjs');
2311
+ const { MigrationService: MigrationService2 } = await import('./migrations-7X4RPH7O.cjs');
2312
2312
  const db = c.env.DB;
2313
2313
  const migrationService = new MigrationService2(db);
2314
2314
  const result = await migrationService.runPendingMigrations();
@@ -2327,7 +2327,7 @@ adminApiRoutes.post("/migrations/run", async (c) => {
2327
2327
  });
2328
2328
  adminApiRoutes.get("/migrations/validate", async (c) => {
2329
2329
  try {
2330
- const { MigrationService: MigrationService2 } = await import('./migrations-F3G6CTRS.cjs');
2330
+ const { MigrationService: MigrationService2 } = await import('./migrations-7X4RPH7O.cjs');
2331
2331
  const db = c.env.DB;
2332
2332
  const migrationService = new MigrationService2(db);
2333
2333
  const validation = await migrationService.validateSchema();
@@ -2738,7 +2738,7 @@ var JWT_SECRET_FALLBACK = "your-super-secret-jwt-key-change-in-production";
2738
2738
  async function setCsrfCookie(c) {
2739
2739
  const secret = c.env?.JWT_SECRET || JWT_SECRET_FALLBACK;
2740
2740
  const isDev = c.env?.ENVIRONMENT === "development" || !c.env?.ENVIRONMENT;
2741
- const csrfToken = await chunkZWKCL46S_cjs.generateCsrfToken(secret);
2741
+ const csrfToken = await chunkK4Q4SFJJ_cjs.generateCsrfToken(secret);
2742
2742
  cookie.setCookie(c, "csrf_token", csrfToken, {
2743
2743
  httpOnly: false,
2744
2744
  secure: !isDev,
@@ -2795,7 +2795,7 @@ var loginSchema = zod.z.object({
2795
2795
  });
2796
2796
  authRoutes.post(
2797
2797
  "/register",
2798
- chunkZWKCL46S_cjs.rateLimit({ max: 3, windowMs: 60 * 1e3, keyPrefix: "register" }),
2798
+ chunkK4Q4SFJJ_cjs.rateLimit({ max: 3, windowMs: 60 * 1e3, keyPrefix: "register" }),
2799
2799
  async (c) => {
2800
2800
  try {
2801
2801
  const db = c.env.DB;
@@ -2832,7 +2832,7 @@ authRoutes.post(
2832
2832
  if (existingUser) {
2833
2833
  return c.json({ error: "User with this email or username already exists" }, 400);
2834
2834
  }
2835
- const passwordHash = await chunkZWKCL46S_cjs.AuthManager.hashPassword(password);
2835
+ const passwordHash = await chunkK4Q4SFJJ_cjs.AuthManager.hashPassword(password);
2836
2836
  const userId = crypto.randomUUID();
2837
2837
  const now = /* @__PURE__ */ new Date();
2838
2838
  await db.prepare(`
@@ -2852,7 +2852,7 @@ authRoutes.post(
2852
2852
  now.getTime(),
2853
2853
  now.getTime()
2854
2854
  ).run();
2855
- const token = await chunkZWKCL46S_cjs.AuthManager.generateToken(userId, normalizedEmail, "viewer", c.env.JWT_SECRET);
2855
+ const token = await chunkK4Q4SFJJ_cjs.AuthManager.generateToken(userId, normalizedEmail, "viewer", c.env.JWT_SECRET);
2856
2856
  cookie.setCookie(c, "auth_token", token, {
2857
2857
  httpOnly: true,
2858
2858
  secure: true,
@@ -2886,7 +2886,7 @@ authRoutes.post(
2886
2886
  );
2887
2887
  authRoutes.post(
2888
2888
  "/login",
2889
- chunkZWKCL46S_cjs.rateLimit({ max: 5, windowMs: 60 * 1e3, keyPrefix: "login" }),
2889
+ chunkK4Q4SFJJ_cjs.rateLimit({ max: 5, windowMs: 60 * 1e3, keyPrefix: "login" }),
2890
2890
  async (c) => {
2891
2891
  try {
2892
2892
  const body = await c.req.json();
@@ -2909,19 +2909,19 @@ authRoutes.post(
2909
2909
  if (!user) {
2910
2910
  return c.json({ error: "Invalid email or password" }, 401);
2911
2911
  }
2912
- const isValidPassword = await chunkZWKCL46S_cjs.AuthManager.verifyPassword(password, user.password_hash);
2912
+ const isValidPassword = await chunkK4Q4SFJJ_cjs.AuthManager.verifyPassword(password, user.password_hash);
2913
2913
  if (!isValidPassword) {
2914
2914
  return c.json({ error: "Invalid email or password" }, 401);
2915
2915
  }
2916
- if (chunkZWKCL46S_cjs.AuthManager.isLegacyHash(user.password_hash)) {
2916
+ if (chunkK4Q4SFJJ_cjs.AuthManager.isLegacyHash(user.password_hash)) {
2917
2917
  try {
2918
- const newHash = await chunkZWKCL46S_cjs.AuthManager.hashPassword(password);
2918
+ const newHash = await chunkK4Q4SFJJ_cjs.AuthManager.hashPassword(password);
2919
2919
  await db.prepare("UPDATE users SET password_hash = ?, updated_at = ? WHERE id = ?").bind(newHash, Date.now(), user.id).run();
2920
2920
  } catch (rehashError) {
2921
2921
  console.error("Password rehash failed (non-fatal):", rehashError);
2922
2922
  }
2923
2923
  }
2924
- const token = await chunkZWKCL46S_cjs.AuthManager.generateToken(user.id, user.email, user.role, c.env.JWT_SECRET);
2924
+ const token = await chunkK4Q4SFJJ_cjs.AuthManager.generateToken(user.id, user.email, user.role, c.env.JWT_SECRET);
2925
2925
  cookie.setCookie(c, "auth_token", token, {
2926
2926
  httpOnly: true,
2927
2927
  secure: true,
@@ -2974,7 +2974,7 @@ authRoutes.get("/logout", (c) => {
2974
2974
  clearCsrfCookie(c);
2975
2975
  return c.redirect("/auth/login?message=You have been logged out successfully");
2976
2976
  });
2977
- authRoutes.get("/me", chunkZWKCL46S_cjs.requireAuth(), async (c) => {
2977
+ authRoutes.get("/me", chunkK4Q4SFJJ_cjs.requireAuth(), async (c) => {
2978
2978
  try {
2979
2979
  const user = c.get("user");
2980
2980
  if (!user) {
@@ -2991,13 +2991,13 @@ authRoutes.get("/me", chunkZWKCL46S_cjs.requireAuth(), async (c) => {
2991
2991
  return c.json({ error: "Failed to get user" }, 500);
2992
2992
  }
2993
2993
  });
2994
- authRoutes.post("/refresh", chunkZWKCL46S_cjs.requireAuth(), async (c) => {
2994
+ authRoutes.post("/refresh", chunkK4Q4SFJJ_cjs.requireAuth(), async (c) => {
2995
2995
  try {
2996
2996
  const user = c.get("user");
2997
2997
  if (!user) {
2998
2998
  return c.json({ error: "Not authenticated" }, 401);
2999
2999
  }
3000
- const token = await chunkZWKCL46S_cjs.AuthManager.generateToken(user.userId, user.email, user.role, c.env.JWT_SECRET);
3000
+ const token = await chunkK4Q4SFJJ_cjs.AuthManager.generateToken(user.userId, user.email, user.role, c.env.JWT_SECRET);
3001
3001
  cookie.setCookie(c, "auth_token", token, {
3002
3002
  httpOnly: true,
3003
3003
  secure: true,
@@ -3014,7 +3014,7 @@ authRoutes.post("/refresh", chunkZWKCL46S_cjs.requireAuth(), async (c) => {
3014
3014
  });
3015
3015
  authRoutes.post(
3016
3016
  "/register/form",
3017
- chunkZWKCL46S_cjs.rateLimit({ max: 3, windowMs: 60 * 1e3, keyPrefix: "register" }),
3017
+ chunkK4Q4SFJJ_cjs.rateLimit({ max: 3, windowMs: 60 * 1e3, keyPrefix: "register" }),
3018
3018
  async (c) => {
3019
3019
  try {
3020
3020
  const db = c.env.DB;
@@ -3061,7 +3061,7 @@ authRoutes.post(
3061
3061
  </div>
3062
3062
  `);
3063
3063
  }
3064
- const passwordHash = await chunkZWKCL46S_cjs.AuthManager.hashPassword(password);
3064
+ const passwordHash = await chunkK4Q4SFJJ_cjs.AuthManager.hashPassword(password);
3065
3065
  const role = isFirstUser ? "admin" : "viewer";
3066
3066
  const userId = crypto.randomUUID();
3067
3067
  const now = /* @__PURE__ */ new Date();
@@ -3081,7 +3081,7 @@ authRoutes.post(
3081
3081
  now.getTime(),
3082
3082
  now.getTime()
3083
3083
  ).run();
3084
- const token = await chunkZWKCL46S_cjs.AuthManager.generateToken(userId, normalizedEmail, role, c.env.JWT_SECRET);
3084
+ const token = await chunkK4Q4SFJJ_cjs.AuthManager.generateToken(userId, normalizedEmail, role, c.env.JWT_SECRET);
3085
3085
  cookie.setCookie(c, "auth_token", token, {
3086
3086
  httpOnly: true,
3087
3087
  secure: false,
@@ -3114,7 +3114,7 @@ authRoutes.post(
3114
3114
  );
3115
3115
  authRoutes.post(
3116
3116
  "/login/form",
3117
- chunkZWKCL46S_cjs.rateLimit({ max: 5, windowMs: 60 * 1e3, keyPrefix: "login" }),
3117
+ chunkK4Q4SFJJ_cjs.rateLimit({ max: 5, windowMs: 60 * 1e3, keyPrefix: "login" }),
3118
3118
  async (c) => {
3119
3119
  try {
3120
3120
  const formData = await c.req.formData();
@@ -3138,7 +3138,7 @@ authRoutes.post(
3138
3138
  </div>
3139
3139
  `);
3140
3140
  }
3141
- const isValidPassword = await chunkZWKCL46S_cjs.AuthManager.verifyPassword(password, user.password_hash);
3141
+ const isValidPassword = await chunkK4Q4SFJJ_cjs.AuthManager.verifyPassword(password, user.password_hash);
3142
3142
  if (!isValidPassword) {
3143
3143
  return c.html(html.html`
3144
3144
  <div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded">
@@ -3146,15 +3146,15 @@ authRoutes.post(
3146
3146
  </div>
3147
3147
  `);
3148
3148
  }
3149
- if (chunkZWKCL46S_cjs.AuthManager.isLegacyHash(user.password_hash)) {
3149
+ if (chunkK4Q4SFJJ_cjs.AuthManager.isLegacyHash(user.password_hash)) {
3150
3150
  try {
3151
- const newHash = await chunkZWKCL46S_cjs.AuthManager.hashPassword(password);
3151
+ const newHash = await chunkK4Q4SFJJ_cjs.AuthManager.hashPassword(password);
3152
3152
  await db.prepare("UPDATE users SET password_hash = ?, updated_at = ? WHERE id = ?").bind(newHash, Date.now(), user.id).run();
3153
3153
  } catch (rehashError) {
3154
3154
  console.error("Password rehash failed (non-fatal):", rehashError);
3155
3155
  }
3156
3156
  }
3157
- const token = await chunkZWKCL46S_cjs.AuthManager.generateToken(user.id, user.email, user.role, c.env.JWT_SECRET);
3157
+ const token = await chunkK4Q4SFJJ_cjs.AuthManager.generateToken(user.id, user.email, user.role, c.env.JWT_SECRET);
3158
3158
  cookie.setCookie(c, "auth_token", token, {
3159
3159
  httpOnly: true,
3160
3160
  secure: false,
@@ -3196,7 +3196,7 @@ authRoutes.post(
3196
3196
  );
3197
3197
  authRoutes.post(
3198
3198
  "/seed-admin",
3199
- chunkZWKCL46S_cjs.rateLimit({ max: 2, windowMs: 60 * 1e3, keyPrefix: "seed-admin" }),
3199
+ chunkK4Q4SFJJ_cjs.rateLimit({ max: 2, windowMs: 60 * 1e3, keyPrefix: "seed-admin" }),
3200
3200
  async (c) => {
3201
3201
  try {
3202
3202
  const db = c.env.DB;
@@ -3218,7 +3218,7 @@ authRoutes.post(
3218
3218
  `).run();
3219
3219
  const existingAdmin = await db.prepare("SELECT id FROM users WHERE email = ? OR username = ?").bind("admin@sonicjs.com", "admin").first();
3220
3220
  if (existingAdmin) {
3221
- const passwordHash2 = await chunkZWKCL46S_cjs.AuthManager.hashPassword("sonicjs!");
3221
+ const passwordHash2 = await chunkK4Q4SFJJ_cjs.AuthManager.hashPassword("sonicjs!");
3222
3222
  await db.prepare("UPDATE users SET password_hash = ?, updated_at = ? WHERE id = ?").bind(passwordHash2, Date.now(), existingAdmin.id).run();
3223
3223
  return c.json({
3224
3224
  message: "Admin user already exists (password updated)",
@@ -3230,7 +3230,7 @@ authRoutes.post(
3230
3230
  }
3231
3231
  });
3232
3232
  }
3233
- const passwordHash = await chunkZWKCL46S_cjs.AuthManager.hashPassword("sonicjs!");
3233
+ const passwordHash = await chunkK4Q4SFJJ_cjs.AuthManager.hashPassword("sonicjs!");
3234
3234
  const userId = "admin-user-id";
3235
3235
  const now = Date.now();
3236
3236
  const adminEmail = "admin@sonicjs.com".toLowerCase();
@@ -3451,7 +3451,7 @@ authRoutes.post("/accept-invitation", async (c) => {
3451
3451
  if (existingUsername) {
3452
3452
  return c.json({ error: "Username is already taken" }, 400);
3453
3453
  }
3454
- const passwordHash = await chunkZWKCL46S_cjs.AuthManager.hashPassword(password);
3454
+ const passwordHash = await chunkK4Q4SFJJ_cjs.AuthManager.hashPassword(password);
3455
3455
  const updateStmt = db.prepare(`
3456
3456
  UPDATE users SET
3457
3457
  username = ?,
@@ -3470,7 +3470,7 @@ authRoutes.post("/accept-invitation", async (c) => {
3470
3470
  Date.now(),
3471
3471
  invitedUser.id
3472
3472
  ).run();
3473
- const authToken = await chunkZWKCL46S_cjs.AuthManager.generateToken(invitedUser.id, invitedUser.email, invitedUser.role, c.env.JWT_SECRET);
3473
+ const authToken = await chunkK4Q4SFJJ_cjs.AuthManager.generateToken(invitedUser.id, invitedUser.email, invitedUser.role, c.env.JWT_SECRET);
3474
3474
  cookie.setCookie(c, "auth_token", authToken, {
3475
3475
  httpOnly: true,
3476
3476
  secure: true,
@@ -3487,7 +3487,7 @@ authRoutes.post("/accept-invitation", async (c) => {
3487
3487
  });
3488
3488
  authRoutes.post(
3489
3489
  "/request-password-reset",
3490
- chunkZWKCL46S_cjs.rateLimit({ max: 3, windowMs: 15 * 60 * 1e3, keyPrefix: "password-reset" }),
3490
+ chunkK4Q4SFJJ_cjs.rateLimit({ max: 3, windowMs: 15 * 60 * 1e3, keyPrefix: "password-reset" }),
3491
3491
  async (c) => {
3492
3492
  try {
3493
3493
  const formData = await c.req.formData();
@@ -3705,7 +3705,7 @@ authRoutes.post("/reset-password", async (c) => {
3705
3705
  if (Date.now() > user.password_reset_expires) {
3706
3706
  return c.json({ error: "Reset token has expired" }, 400);
3707
3707
  }
3708
- const newPasswordHash = await chunkZWKCL46S_cjs.AuthManager.hashPassword(password);
3708
+ const newPasswordHash = await chunkK4Q4SFJJ_cjs.AuthManager.hashPassword(password);
3709
3709
  try {
3710
3710
  const historyStmt = db.prepare(`
3711
3711
  INSERT INTO password_history (id, user_id, password_hash, created_at)
@@ -4782,6 +4782,7 @@ function getReadFieldValueScript() {
4782
4782
  const textarea = fieldWrapper.querySelector('textarea');
4783
4783
  const inputs = Array.from(fieldWrapper.querySelectorAll('input'));
4784
4784
  const checkbox = inputs.find((input) => input.type === 'checkbox');
4785
+ const checkedRadio = inputs.find((input) => input.type === 'radio' && input.checked);
4785
4786
  const nonHiddenInput = inputs.find((input) => input.type !== 'hidden' && input.type !== 'checkbox');
4786
4787
  const hiddenInput = inputs.find((input) => input.type === 'hidden');
4787
4788
 
@@ -4804,6 +4805,10 @@ function getReadFieldValueScript() {
4804
4805
  return checkbox.checked;
4805
4806
  }
4806
4807
 
4808
+ if (fieldType === 'radio') {
4809
+ return checkedRadio ? checkedRadio.value : '';
4810
+ }
4811
+
4807
4812
  if (select) {
4808
4813
  if (select.multiple) {
4809
4814
  return Array.from(select.selectedOptions).map((option) => option.value);
@@ -4843,9 +4848,9 @@ function renderDynamicField(field, options = {}) {
4843
4848
  if (field.field_type === "quill" && !pluginStatuses.quillEnabled) {
4844
4849
  fallbackToTextarea = true;
4845
4850
  fallbackWarning = "\u26A0\uFE0F Quill Editor plugin is inactive. Using textarea fallback.";
4846
- } else if (field.field_type === "mdxeditor" && !pluginStatuses.mdxeditorEnabled) {
4851
+ } else if ((field.field_type === "mdxeditor" || field.field_type === "easymde" || field.field_type === "markdown") && !pluginStatuses.mdxeditorEnabled) {
4847
4852
  fallbackToTextarea = true;
4848
- fallbackWarning = "\u26A0\uFE0F MDXEditor plugin is inactive. Using textarea fallback.";
4853
+ fallbackWarning = "\u26A0\uFE0F EasyMDE plugin is inactive. Using textarea fallback.";
4849
4854
  } else if (field.field_type === "tinymce" && !pluginStatuses.tinymceEnabled) {
4850
4855
  fallbackToTextarea = true;
4851
4856
  fallbackWarning = "\u26A0\uFE0F TinyMCE plugin is inactive. Using textarea fallback.";
@@ -5004,6 +5009,9 @@ function renderDynamicField(field, options = {}) {
5004
5009
  `;
5005
5010
  break;
5006
5011
  case "mdxeditor":
5012
+ case "tinymce":
5013
+ case "easymde":
5014
+ case "markdown":
5007
5015
  fieldHTML = `
5008
5016
  <div class="richtext-container" data-height="${opts.height || 300}" data-toolbar="${opts.toolbar || "full"}">
5009
5017
  <textarea
@@ -5285,6 +5293,39 @@ function renderDynamicField(field, options = {}) {
5285
5293
  ` : ""}
5286
5294
  `;
5287
5295
  break;
5296
+ case "radio":
5297
+ const radioOptions = opts.options || (Array.isArray(opts.enum) ? opts.enum.map((optionValue, index) => ({
5298
+ value: optionValue,
5299
+ label: opts.enumLabels?.[index] || optionValue
5300
+ })) : []);
5301
+ const selectedRadioValue = value !== void 0 && value !== null ? String(value) : opts.default ? String(opts.default) : "";
5302
+ const isInline = opts.inline === true;
5303
+ fieldHTML = `
5304
+ <div class="${isInline ? "flex flex-wrap gap-4" : "space-y-3"}">
5305
+ ${radioOptions.map((option, index) => {
5306
+ const optionValue = typeof option === "string" ? option : option.value;
5307
+ const optionLabel = typeof option === "string" ? option : option.label;
5308
+ const inputId = `${fieldId}-option-${index}`;
5309
+ const checked2 = selectedRadioValue === String(optionValue) ? "checked" : "";
5310
+ return `
5311
+ <label for="${inputId}" class="flex items-center gap-3 text-sm text-zinc-700 dark:text-zinc-300">
5312
+ <input
5313
+ type="radio"
5314
+ id="${inputId}"
5315
+ name="${fieldName}"
5316
+ value="${escapeHtml3(optionValue)}"
5317
+ class="h-4 w-4 text-zinc-900 focus:ring-zinc-400 dark:text-white dark:focus:ring-white"
5318
+ ${checked2}
5319
+ ${required}
5320
+ ${disabled ? "disabled" : ""}
5321
+ >
5322
+ <span>${escapeHtml3(optionLabel)}</span>
5323
+ </label>
5324
+ `;
5325
+ }).join("")}
5326
+ </div>
5327
+ `;
5328
+ break;
5288
5329
  case "reference":
5289
5330
  let referenceCollections = [];
5290
5331
  if (Array.isArray(opts.collection)) {
@@ -5555,8 +5596,19 @@ function renderStructuredArrayField(field, options, baseClasses, errorClasses) {
5555
5596
  const fieldId = `field-${field.field_name}`;
5556
5597
  const fieldName = field.field_name;
5557
5598
  const arrayValue = normalizeStructuredArrayValue(value);
5599
+ const arrayTitle = opts.itemLabel || field.field_label || "Items";
5600
+ const hasItemTitle = typeof opts.itemTitle === "string" && opts.itemTitle.trim() !== "";
5601
+ const arrayItemTitle = hasItemTitle ? opts.itemTitle.trim() : "Item";
5602
+ const addItemLabel = hasItemTitle ? `Add ${arrayItemTitle}` : "Add item";
5558
5603
  const items = arrayValue.map(
5559
- (itemValue, index) => renderStructuredArrayItem(field, itemsConfig, String(index), itemValue, pluginStatuses)
5604
+ (itemValue, index) => renderStructuredArrayItem(
5605
+ field,
5606
+ itemsConfig,
5607
+ String(index),
5608
+ itemValue,
5609
+ pluginStatuses,
5610
+ arrayItemTitle
5611
+ )
5560
5612
  ).join("");
5561
5613
  const emptyState = arrayValue.length === 0 ? `
5562
5614
  <div class="rounded-lg border border-dashed border-zinc-200 dark:border-white/10 px-4 py-6 text-center text-sm text-zinc-500 dark:text-zinc-400" data-structured-empty>
@@ -5569,14 +5621,14 @@ function renderStructuredArrayField(field, options, baseClasses, errorClasses) {
5569
5621
 
5570
5622
  <div class="flex items-center justify-between gap-3">
5571
5623
  <div class="text-sm text-zinc-500 dark:text-zinc-400">
5572
- ${escapeHtml3(opts.itemLabel || "Items")}
5624
+ ${escapeHtml3(arrayTitle)}
5573
5625
  </div>
5574
5626
  <button
5575
5627
  type="button"
5576
5628
  data-action="add-item"
5577
5629
  class="inline-flex items-center justify-center rounded-lg bg-zinc-900 px-3 py-2 text-sm font-semibold text-white hover:bg-zinc-800 dark:bg-white/10 dark:hover:bg-white/20"
5578
5630
  >
5579
- Add item
5631
+ ${escapeHtml3(addItemLabel)}
5580
5632
  </button>
5581
5633
  </div>
5582
5634
 
@@ -5585,14 +5637,21 @@ function renderStructuredArrayField(field, options, baseClasses, errorClasses) {
5585
5637
  </div>
5586
5638
 
5587
5639
  <template data-structured-array-template>
5588
- ${renderStructuredArrayItem(field, itemsConfig, "__INDEX__", {}, pluginStatuses)}
5640
+ ${renderStructuredArrayItem(
5641
+ field,
5642
+ itemsConfig,
5643
+ "__INDEX__",
5644
+ {},
5645
+ pluginStatuses,
5646
+ arrayItemTitle
5647
+ )}
5589
5648
  </template>
5590
5649
  </div>
5591
5650
  ${getDragSortableScript()}
5592
5651
  ${getStructuredFieldScript()}
5593
5652
  `;
5594
5653
  }
5595
- function renderStructuredArrayItem(field, itemConfig, index, itemValue, pluginStatuses) {
5654
+ function renderStructuredArrayItem(field, itemConfig, index, itemValue, pluginStatuses, arrayItemTitle) {
5596
5655
  const itemFields = renderStructuredItemFields(field, itemConfig, index, itemValue, pluginStatuses);
5597
5656
  return `
5598
5657
  <div class="structured-array-item rounded-lg border border-zinc-200 dark:border-white/10 bg-white/60 dark:bg-white/5 p-4 shadow-sm" data-array-index="${escapeHtml3(index)}" draggable="true">
@@ -5603,8 +5662,8 @@ function renderStructuredArrayItem(field, itemConfig, index, itemValue, pluginSt
5603
5662
  <path stroke-linecap="round" stroke-linejoin="round" d="M4 8h16M4 16h16"/>
5604
5663
  </svg>
5605
5664
  </div>
5606
- <div class="text-sm font-semibold text-zinc-900 dark:text-white">
5607
- Item <span class="ml-2 text-xs font-normal text-zinc-500 dark:text-zinc-400" data-array-order-label></span>
5665
+ <div class="text-sm font-semibold text-zinc-900 dark:text-white cursor-pointer" data-action="toggle-item">
5666
+ ${escapeHtml3(arrayItemTitle)} <span class="ml-2 text-xs font-normal text-zinc-500 dark:text-zinc-400" data-array-order-label></span>
5608
5667
  </div>
5609
5668
  </div>
5610
5669
  <div class="flex flex-wrap gap-2 text-xs">
@@ -5960,8 +6019,15 @@ function getStructuredFieldScript() {
5960
6019
  if (!item || !list) return;
5961
6020
 
5962
6021
  if (action === 'remove-item') {
5963
- item.remove();
5964
- updateHiddenInput();
6022
+ if (typeof requestRepeaterDelete === 'function') {
6023
+ requestRepeaterDelete(() => {
6024
+ item.remove();
6025
+ updateHiddenInput();
6026
+ });
6027
+ } else {
6028
+ item.remove();
6029
+ updateHiddenInput();
6030
+ }
5965
6031
  return;
5966
6032
  }
5967
6033
 
@@ -6152,8 +6218,15 @@ function getBlocksFieldScript() {
6152
6218
  if (!item || !list) return;
6153
6219
 
6154
6220
  if (action === 'remove-block') {
6155
- item.remove();
6156
- updateHiddenInput();
6221
+ if (typeof requestRepeaterDelete === 'function') {
6222
+ requestRepeaterDelete(() => {
6223
+ item.remove();
6224
+ updateHiddenInput();
6225
+ }, 'block');
6226
+ } else {
6227
+ item.remove();
6228
+ updateHiddenInput();
6229
+ }
6157
6230
  return;
6158
6231
  }
6159
6232
 
@@ -6562,6 +6635,28 @@ function renderContentFormPage(data) {
6562
6635
  onConfirm: `performDeleteContent('${data.id}')`
6563
6636
  })}
6564
6637
 
6638
+ ${chunkLTKV7AE5_cjs.renderConfirmationDialog({
6639
+ id: "delete-repeater-item-confirm",
6640
+ title: "Delete Item",
6641
+ message: "Are you sure you want to delete this item? This action cannot be undone.",
6642
+ confirmText: "Delete",
6643
+ cancelText: "Cancel",
6644
+ iconColor: "red",
6645
+ confirmClass: "bg-red-500 hover:bg-red-400",
6646
+ onConfirm: "performRepeaterDelete()"
6647
+ })}
6648
+
6649
+ ${chunkLTKV7AE5_cjs.renderConfirmationDialog({
6650
+ id: "delete-block-confirm",
6651
+ title: "Delete Block",
6652
+ message: "Are you sure you want to delete this block? This action cannot be undone.",
6653
+ confirmText: "Delete",
6654
+ cancelText: "Cancel",
6655
+ iconColor: "red",
6656
+ confirmClass: "bg-red-500 hover:bg-red-400",
6657
+ onConfirm: "performRepeaterDelete()"
6658
+ })}
6659
+
6565
6660
  ${chunkLTKV7AE5_cjs.getConfirmationDialogScript()}
6566
6661
 
6567
6662
  ${data.tinymceEnabled ? getTinyMCEScript(data.tinymceSettings?.apiKey) : "<!-- TinyMCE plugin not active -->"}
@@ -7118,6 +7213,29 @@ function renderContentFormPage(data) {
7118
7213
  });
7119
7214
  }
7120
7215
 
7216
+ // Repeater/blocks delete confirmation
7217
+ let pendingRepeaterDelete = null;
7218
+ function requestRepeaterDelete(callback, type = 'item') {
7219
+ pendingRepeaterDelete = callback;
7220
+ if (typeof showConfirmDialog === 'function') {
7221
+ showConfirmDialog(type === 'block' ? 'delete-block-confirm' : 'delete-repeater-item-confirm');
7222
+ return;
7223
+ }
7224
+ if (confirm('Remove this item? This action cannot be undone.')) {
7225
+ if (typeof pendingRepeaterDelete === 'function') {
7226
+ pendingRepeaterDelete();
7227
+ }
7228
+ }
7229
+ pendingRepeaterDelete = null;
7230
+ }
7231
+
7232
+ function performRepeaterDelete() {
7233
+ if (typeof pendingRepeaterDelete === 'function') {
7234
+ pendingRepeaterDelete();
7235
+ }
7236
+ pendingRepeaterDelete = null;
7237
+ }
7238
+
7121
7239
  function showVersionHistory(contentId) {
7122
7240
  // Create and show version history modal
7123
7241
  const modal = document.createElement('div');
@@ -8130,9 +8248,9 @@ function parseFieldValue(field, formData, options = {}) {
8130
8248
  const { skipValidation = false } = options;
8131
8249
  const value = formData.get(field.field_name);
8132
8250
  const errors = [];
8133
- const blocksConfig = chunkJSHIGVIF_cjs.getBlocksFieldConfig(field.field_options);
8251
+ const blocksConfig = chunkJDIM5AG7_cjs.getBlocksFieldConfig(field.field_options);
8134
8252
  if (blocksConfig) {
8135
- const parsed = chunkJSHIGVIF_cjs.parseBlocksValue(value, blocksConfig);
8253
+ const parsed = chunkJDIM5AG7_cjs.parseBlocksValue(value, blocksConfig);
8136
8254
  if (!skipValidation && field.is_required && parsed.value.length === 0) {
8137
8255
  parsed.errors.push(`${field.field_label} is required`);
8138
8256
  }
@@ -8242,7 +8360,7 @@ function extractFieldData(fields, formData, options = {}) {
8242
8360
  }
8243
8361
  return { data, errors };
8244
8362
  }
8245
- adminContentRoutes.use("*", chunkZWKCL46S_cjs.requireAuth());
8363
+ adminContentRoutes.use("*", chunkK4Q4SFJJ_cjs.requireAuth());
8246
8364
  async function getCollectionFields(db, collectionId) {
8247
8365
  const cache = chunkVNLR35GO_cjs.getCacheService(chunkVNLR35GO_cjs.CACHE_CONFIGS.collection);
8248
8366
  return cache.getOrSet(
@@ -8938,7 +9056,7 @@ adminContentRoutes.put("/:id", async (c) => {
8938
9056
  `);
8939
9057
  }
8940
9058
  });
8941
- adminContentRoutes.post("/preview", chunkZWKCL46S_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
9059
+ adminContentRoutes.post("/preview", chunkK4Q4SFJJ_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
8942
9060
  try {
8943
9061
  const formData = await c.req.formData();
8944
9062
  const collectionId = formData.get("collection_id");
@@ -9316,7 +9434,7 @@ adminContentRoutes.post("/:id/restore/:version", async (c) => {
9316
9434
  return c.json({ success: false, error: "Failed to restore version" });
9317
9435
  }
9318
9436
  });
9319
- adminContentRoutes.get("/:id/version/:version/preview", chunkZWKCL46S_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
9437
+ adminContentRoutes.get("/:id/version/:version/preview", chunkK4Q4SFJJ_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
9320
9438
  try {
9321
9439
  const id = c.req.param("id");
9322
9440
  const version = parseInt(c.req.param("version") || "0");
@@ -11283,7 +11401,7 @@ function renderUsersListPage(data) {
11283
11401
 
11284
11402
  // src/routes/admin-users.ts
11285
11403
  var userRoutes = new hono.Hono();
11286
- userRoutes.use("*", chunkZWKCL46S_cjs.requireAuth());
11404
+ userRoutes.use("*", chunkK4Q4SFJJ_cjs.requireAuth());
11287
11405
  userRoutes.get("/", (c) => {
11288
11406
  return c.redirect("/admin/dashboard");
11289
11407
  });
@@ -11438,7 +11556,7 @@ userRoutes.put("/profile", async (c) => {
11438
11556
  Date.now(),
11439
11557
  user.userId
11440
11558
  ).run();
11441
- await chunkZWKCL46S_cjs.logActivity(
11559
+ await chunkK4Q4SFJJ_cjs.logActivity(
11442
11560
  db,
11443
11561
  user.userId,
11444
11562
  "profile.update",
@@ -11501,7 +11619,7 @@ userRoutes.post("/profile/avatar", async (c) => {
11501
11619
  SELECT first_name, last_name FROM users WHERE id = ?
11502
11620
  `);
11503
11621
  const userData = await userStmt.bind(user.userId).first();
11504
- await chunkZWKCL46S_cjs.logActivity(
11622
+ await chunkK4Q4SFJJ_cjs.logActivity(
11505
11623
  db,
11506
11624
  user.userId,
11507
11625
  "profile.avatar_update",
@@ -11572,7 +11690,7 @@ userRoutes.post("/profile/password", async (c) => {
11572
11690
  dismissible: true
11573
11691
  }));
11574
11692
  }
11575
- const validPassword = await chunkZWKCL46S_cjs.AuthManager.verifyPassword(currentPassword, userData.password_hash);
11693
+ const validPassword = await chunkK4Q4SFJJ_cjs.AuthManager.verifyPassword(currentPassword, userData.password_hash);
11576
11694
  if (!validPassword) {
11577
11695
  return c.html(renderAlert2({
11578
11696
  type: "error",
@@ -11580,7 +11698,7 @@ userRoutes.post("/profile/password", async (c) => {
11580
11698
  dismissible: true
11581
11699
  }));
11582
11700
  }
11583
- const newPasswordHash = await chunkZWKCL46S_cjs.AuthManager.hashPassword(newPassword);
11701
+ const newPasswordHash = await chunkK4Q4SFJJ_cjs.AuthManager.hashPassword(newPassword);
11584
11702
  const historyStmt = db.prepare(`
11585
11703
  INSERT INTO password_history (id, user_id, password_hash, created_at)
11586
11704
  VALUES (?, ?, ?, ?)
@@ -11596,7 +11714,7 @@ userRoutes.post("/profile/password", async (c) => {
11596
11714
  WHERE id = ?
11597
11715
  `);
11598
11716
  await updateStmt.bind(newPasswordHash, Date.now(), user.userId).run();
11599
- await chunkZWKCL46S_cjs.logActivity(
11717
+ await chunkK4Q4SFJJ_cjs.logActivity(
11600
11718
  db,
11601
11719
  user.userId,
11602
11720
  "profile.password_change",
@@ -11663,7 +11781,7 @@ userRoutes.get("/users", async (c) => {
11663
11781
  `);
11664
11782
  const countResult = await countStmt.bind(...params).first();
11665
11783
  const totalUsers = countResult?.total || 0;
11666
- await chunkZWKCL46S_cjs.logActivity(
11784
+ await chunkK4Q4SFJJ_cjs.logActivity(
11667
11785
  db,
11668
11786
  user.userId,
11669
11787
  "users.list_view",
@@ -11817,7 +11935,7 @@ userRoutes.post("/users/new", async (c) => {
11817
11935
  dismissible: true
11818
11936
  }));
11819
11937
  }
11820
- const passwordHash = await chunkZWKCL46S_cjs.AuthManager.hashPassword(password);
11938
+ const passwordHash = await chunkK4Q4SFJJ_cjs.AuthManager.hashPassword(password);
11821
11939
  const userId = crypto.randomUUID();
11822
11940
  const createStmt = db.prepare(`
11823
11941
  INSERT INTO users (
@@ -11840,7 +11958,7 @@ userRoutes.post("/users/new", async (c) => {
11840
11958
  Date.now(),
11841
11959
  Date.now()
11842
11960
  ).run();
11843
- await chunkZWKCL46S_cjs.logActivity(
11961
+ await chunkK4Q4SFJJ_cjs.logActivity(
11844
11962
  db,
11845
11963
  user.userId,
11846
11964
  "user!.create",
@@ -11878,7 +11996,7 @@ userRoutes.get("/users/:id", async (c) => {
11878
11996
  if (!userRecord) {
11879
11997
  return c.json({ error: "User not found" }, 404);
11880
11998
  }
11881
- await chunkZWKCL46S_cjs.logActivity(
11999
+ await chunkK4Q4SFJJ_cjs.logActivity(
11882
12000
  db,
11883
12001
  user.userId,
11884
12002
  "user!.view",
@@ -12103,7 +12221,7 @@ userRoutes.put("/users/:id", async (c) => {
12103
12221
  ).run();
12104
12222
  }
12105
12223
  }
12106
- await chunkZWKCL46S_cjs.logActivity(
12224
+ await chunkK4Q4SFJJ_cjs.logActivity(
12107
12225
  db,
12108
12226
  user.userId,
12109
12227
  "user.update",
@@ -12148,7 +12266,7 @@ userRoutes.post("/users/:id/toggle", async (c) => {
12148
12266
  UPDATE users SET is_active = ?, updated_at = ? WHERE id = ?
12149
12267
  `);
12150
12268
  await toggleStmt.bind(active ? 1 : 0, Date.now(), userId).run();
12151
- await chunkZWKCL46S_cjs.logActivity(
12269
+ await chunkK4Q4SFJJ_cjs.logActivity(
12152
12270
  db,
12153
12271
  user.userId,
12154
12272
  active ? "user.activate" : "user.deactivate",
@@ -12189,7 +12307,7 @@ userRoutes.delete("/users/:id", async (c) => {
12189
12307
  DELETE FROM users WHERE id = ?
12190
12308
  `);
12191
12309
  await deleteStmt.bind(userId).run();
12192
- await chunkZWKCL46S_cjs.logActivity(
12310
+ await chunkK4Q4SFJJ_cjs.logActivity(
12193
12311
  db,
12194
12312
  user.userId,
12195
12313
  "user!.hard_delete",
@@ -12208,7 +12326,7 @@ userRoutes.delete("/users/:id", async (c) => {
12208
12326
  UPDATE users SET is_active = 0, updated_at = ? WHERE id = ?
12209
12327
  `);
12210
12328
  await deleteStmt.bind(Date.now(), userId).run();
12211
- await chunkZWKCL46S_cjs.logActivity(
12329
+ await chunkK4Q4SFJJ_cjs.logActivity(
12212
12330
  db,
12213
12331
  user.userId,
12214
12332
  "user!.soft_delete",
@@ -12274,7 +12392,7 @@ userRoutes.post("/invite-user", async (c) => {
12274
12392
  Date.now(),
12275
12393
  Date.now()
12276
12394
  ).run();
12277
- await chunkZWKCL46S_cjs.logActivity(
12395
+ await chunkK4Q4SFJJ_cjs.logActivity(
12278
12396
  db,
12279
12397
  user.userId,
12280
12398
  "user!.invite_sent",
@@ -12331,7 +12449,7 @@ userRoutes.post("/resend-invitation/:id", async (c) => {
12331
12449
  Date.now(),
12332
12450
  userId
12333
12451
  ).run();
12334
- await chunkZWKCL46S_cjs.logActivity(
12452
+ await chunkK4Q4SFJJ_cjs.logActivity(
12335
12453
  db,
12336
12454
  user.userId,
12337
12455
  "user!.invitation_resent",
@@ -12367,7 +12485,7 @@ userRoutes.delete("/cancel-invitation/:id", async (c) => {
12367
12485
  }
12368
12486
  const deleteStmt = db.prepare(`DELETE FROM users WHERE id = ?`);
12369
12487
  await deleteStmt.bind(userId).run();
12370
- await chunkZWKCL46S_cjs.logActivity(
12488
+ await chunkK4Q4SFJJ_cjs.logActivity(
12371
12489
  db,
12372
12490
  user.userId,
12373
12491
  "user!.invitation_cancelled",
@@ -12450,7 +12568,7 @@ userRoutes.get("/activity-logs", async (c) => {
12450
12568
  ...log,
12451
12569
  details: log.details ? JSON.parse(log.details) : null
12452
12570
  }));
12453
- await chunkZWKCL46S_cjs.logActivity(
12571
+ await chunkK4Q4SFJJ_cjs.logActivity(
12454
12572
  db,
12455
12573
  user.userId,
12456
12574
  "activity.logs_viewed",
@@ -12557,7 +12675,7 @@ userRoutes.get("/activity-logs/export", async (c) => {
12557
12675
  csvRows.push(row.join(","));
12558
12676
  }
12559
12677
  const csvContent = csvRows.join("\n");
12560
- await chunkZWKCL46S_cjs.logActivity(
12678
+ await chunkK4Q4SFJJ_cjs.logActivity(
12561
12679
  db,
12562
12680
  user.userId,
12563
12681
  "activity.logs_exported",
@@ -13896,7 +14014,7 @@ var fileValidationSchema2 = zod.z.object({
13896
14014
  // 50MB max
13897
14015
  });
13898
14016
  var adminMediaRoutes = new hono.Hono();
13899
- adminMediaRoutes.use("*", chunkZWKCL46S_cjs.requireAuth());
14017
+ adminMediaRoutes.use("*", chunkK4Q4SFJJ_cjs.requireAuth());
13900
14018
  adminMediaRoutes.get("/", async (c) => {
13901
14019
  try {
13902
14020
  const user = c.get("user");
@@ -14482,7 +14600,7 @@ adminMediaRoutes.put("/:id", async (c) => {
14482
14600
  `);
14483
14601
  }
14484
14602
  });
14485
- adminMediaRoutes.delete("/cleanup", chunkZWKCL46S_cjs.requireRole("admin"), async (c) => {
14603
+ adminMediaRoutes.delete("/cleanup", chunkK4Q4SFJJ_cjs.requireRole("admin"), async (c) => {
14486
14604
  try {
14487
14605
  const db = c.env.DB;
14488
14606
  const allMediaStmt = db.prepare("SELECT id, r2_key, filename FROM media WHERE deleted_at IS NULL");
@@ -16705,7 +16823,7 @@ function renderEmailSettingsContent(plugin, settings) {
16705
16823
 
16706
16824
  // src/routes/admin-plugins.ts
16707
16825
  var adminPluginRoutes = new hono.Hono();
16708
- adminPluginRoutes.use("*", chunkZWKCL46S_cjs.requireAuth());
16826
+ adminPluginRoutes.use("*", chunkK4Q4SFJJ_cjs.requireAuth());
16709
16827
  var AVAILABLE_PLUGINS = [
16710
16828
  {
16711
16829
  id: "third-party-faq",
@@ -18110,7 +18228,7 @@ function renderLogConfigPage(data) {
18110
18228
 
18111
18229
  // src/routes/admin-logs.ts
18112
18230
  var adminLogsRoutes = new hono.Hono();
18113
- adminLogsRoutes.use("*", chunkZWKCL46S_cjs.requireAuth());
18231
+ adminLogsRoutes.use("*", chunkK4Q4SFJJ_cjs.requireAuth());
18114
18232
  adminLogsRoutes.get("/", async (c) => {
18115
18233
  try {
18116
18234
  const user = c.get("user");
@@ -20438,9 +20556,9 @@ function renderStorageUsage(databaseSizeBytes, mediaSizeBytes) {
20438
20556
  }
20439
20557
 
20440
20558
  // src/routes/admin-dashboard.ts
20441
- var VERSION = chunkJSHIGVIF_cjs.getCoreVersion();
20559
+ var VERSION = chunkJDIM5AG7_cjs.getCoreVersion();
20442
20560
  var router = new hono.Hono();
20443
- router.use("*", chunkZWKCL46S_cjs.requireAuth());
20561
+ router.use("*", chunkK4Q4SFJJ_cjs.requireAuth());
20444
20562
  router.get("/", async (c) => {
20445
20563
  const user = c.get("user");
20446
20564
  try {
@@ -21648,6 +21766,7 @@ function renderCollectionFormPage(data) {
21648
21766
  <option value="number">Number</option>
21649
21767
  <option value="boolean">Boolean</option>
21650
21768
  <option value="date">Date</option>
21769
+ <option value="radio">Radio</option>
21651
21770
  <option value="select">Select</option>
21652
21771
  <option value="media">Media</option>
21653
21772
  <option value="reference">Reference</option>
@@ -21975,7 +22094,7 @@ function renderCollectionFormPage(data) {
21975
22094
 
21976
22095
  console.log('[Edit Field] Showing options for field type:', fieldType, '(original:', field.field_type, ')');
21977
22096
 
21978
- if (['select', 'media', 'richtext', 'reference'].includes(fieldType)) {
22097
+ if (['select', 'radio', 'media', 'richtext', 'reference'].includes(fieldType)) {
21979
22098
  optionsContainer.classList.remove('hidden');
21980
22099
 
21981
22100
  // Set help text based on type
@@ -21983,6 +22102,9 @@ function renderCollectionFormPage(data) {
21983
22102
  case 'select':
21984
22103
  helpText.textContent = 'Create a dropdown select field with custom options';
21985
22104
  break;
22105
+ case 'radio':
22106
+ helpText.textContent = 'Single selection from a list of radio options';
22107
+ break;
21986
22108
  case 'media':
21987
22109
  helpText.textContent = 'Upload and manage media files (images, videos, documents)';
21988
22110
  break;
@@ -22129,7 +22251,7 @@ function renderCollectionFormPage(data) {
22129
22251
  const fieldNameInput = document.getElementById('modal-field-name');
22130
22252
 
22131
22253
  // Show/hide options based on field type
22132
- if (['select', 'media', 'richtext', 'guid', 'reference'].includes(this.value)) {
22254
+ if (['select', 'radio', 'media', 'richtext', 'guid', 'reference'].includes(this.value)) {
22133
22255
  optionsContainer.classList.remove('hidden');
22134
22256
 
22135
22257
  // Set default options and help text based on type
@@ -22138,6 +22260,10 @@ function renderCollectionFormPage(data) {
22138
22260
  fieldOptions.value = '{"options": ["Option 1", "Option 2"], "multiple": false}';
22139
22261
  helpText.textContent = 'Create a dropdown select field with custom options';
22140
22262
  break;
22263
+ case 'radio':
22264
+ fieldOptions.value = '{"enum": ["Option 1", "Option 2"], "enumLabels": ["Option 1", "Option 2"], "default": "Option 1", "inline": false}';
22265
+ helpText.textContent = 'Single selection from a list of radio options';
22266
+ break;
22141
22267
  case 'media':
22142
22268
  fieldOptions.value = '{"accept": "image/*", "maxSize": "10MB"}';
22143
22269
  helpText.textContent = 'Upload and manage media files (images, videos, documents)';
@@ -22220,7 +22346,7 @@ function renderCollectionFormPage(data) {
22220
22346
 
22221
22347
  // src/routes/admin-collections.ts
22222
22348
  var adminCollectionsRoutes = new hono.Hono();
22223
- adminCollectionsRoutes.use("*", chunkZWKCL46S_cjs.requireAuth());
22349
+ adminCollectionsRoutes.use("*", chunkK4Q4SFJJ_cjs.requireAuth());
22224
22350
  adminCollectionsRoutes.get("/", async (c) => {
22225
22351
  try {
22226
22352
  const user = c.get("user");
@@ -22712,6 +22838,11 @@ adminCollectionsRoutes.post("/:id/fields", async (c) => {
22712
22838
  fieldConfig.format = "date-time";
22713
22839
  } else if (fieldType === "select") {
22714
22840
  fieldConfig.enum = parsedOptions.options || [];
22841
+ } else if (fieldType === "radio") {
22842
+ fieldConfig.type = "radio";
22843
+ if (!parsedOptions.enum && parsedOptions.options) {
22844
+ fieldConfig.enum = parsedOptions.options;
22845
+ }
22715
22846
  } else if (fieldType === "media") {
22716
22847
  fieldConfig.format = "media";
22717
22848
  } else if (fieldType === "slug") {
@@ -22721,6 +22852,12 @@ adminCollectionsRoutes.post("/:id/fields", async (c) => {
22721
22852
  fieldConfig.type = "quill";
22722
22853
  } else if (fieldType === "mdxeditor") {
22723
22854
  fieldConfig.type = "mdxeditor";
22855
+ } else if (fieldType === "tinymce") {
22856
+ fieldConfig.type = "tinymce";
22857
+ } else if (fieldType === "easymde") {
22858
+ fieldConfig.type = "easymde";
22859
+ } else if (fieldType === "markdown") {
22860
+ fieldConfig.type = "markdown";
22724
22861
  } else if (fieldType === "reference") {
22725
22862
  fieldConfig.type = "reference";
22726
22863
  }
@@ -24409,7 +24546,7 @@ function renderDatabaseToolsSettings(settings) {
24409
24546
 
24410
24547
  // src/routes/admin-settings.ts
24411
24548
  var adminSettingsRoutes = new hono.Hono();
24412
- adminSettingsRoutes.use("*", chunkZWKCL46S_cjs.requireAuth());
24549
+ adminSettingsRoutes.use("*", chunkK4Q4SFJJ_cjs.requireAuth());
24413
24550
  function getMockSettings(user) {
24414
24551
  return {
24415
24552
  general: {
@@ -24577,7 +24714,7 @@ adminSettingsRoutes.get("/database-tools", (c) => {
24577
24714
  adminSettingsRoutes.get("/api/migrations/status", async (c) => {
24578
24715
  try {
24579
24716
  const db = c.env.DB;
24580
- const migrationService = new chunkVGSZWZP3_cjs.MigrationService(db);
24717
+ const migrationService = new chunkHXHVU5GM_cjs.MigrationService(db);
24581
24718
  const status = await migrationService.getMigrationStatus();
24582
24719
  return c.json({
24583
24720
  success: true,
@@ -24601,7 +24738,7 @@ adminSettingsRoutes.post("/api/migrations/run", async (c) => {
24601
24738
  }, 403);
24602
24739
  }
24603
24740
  const db = c.env.DB;
24604
- const migrationService = new chunkVGSZWZP3_cjs.MigrationService(db);
24741
+ const migrationService = new chunkHXHVU5GM_cjs.MigrationService(db);
24605
24742
  const result = await migrationService.runPendingMigrations();
24606
24743
  return c.json({
24607
24744
  success: result.success,
@@ -24619,7 +24756,7 @@ adminSettingsRoutes.post("/api/migrations/run", async (c) => {
24619
24756
  adminSettingsRoutes.get("/api/migrations/validate", async (c) => {
24620
24757
  try {
24621
24758
  const db = c.env.DB;
24622
- const migrationService = new chunkVGSZWZP3_cjs.MigrationService(db);
24759
+ const migrationService = new chunkHXHVU5GM_cjs.MigrationService(db);
24623
24760
  const validation = await migrationService.validateSchema();
24624
24761
  return c.json({
24625
24762
  success: true,
@@ -26509,7 +26646,7 @@ function renderFormCreatePage(data) {
26509
26646
 
26510
26647
  // src/routes/admin-forms.ts
26511
26648
  var adminFormsRoutes = new hono.Hono();
26512
- adminFormsRoutes.use("*", chunkZWKCL46S_cjs.requireAuth());
26649
+ adminFormsRoutes.use("*", chunkK4Q4SFJJ_cjs.requireAuth());
26513
26650
  adminFormsRoutes.get("/", async (c) => {
26514
26651
  try {
26515
26652
  const user = c.get("user");
@@ -27656,9 +27793,9 @@ function renderAPIReferencePage(data) {
27656
27793
  }
27657
27794
 
27658
27795
  // src/routes/admin-api-reference.ts
27659
- var VERSION2 = chunkJSHIGVIF_cjs.getCoreVersion();
27796
+ var VERSION2 = chunkJDIM5AG7_cjs.getCoreVersion();
27660
27797
  var router2 = new hono.Hono();
27661
- router2.use("*", chunkZWKCL46S_cjs.requireAuth());
27798
+ router2.use("*", chunkK4Q4SFJJ_cjs.requireAuth());
27662
27799
  var apiEndpoints = [
27663
27800
  // Auth endpoints
27664
27801
  {
@@ -27939,5 +28076,5 @@ exports.router = router;
27939
28076
  exports.router2 = router2;
27940
28077
  exports.test_cleanup_default = test_cleanup_default;
27941
28078
  exports.userRoutes = userRoutes;
27942
- //# sourceMappingURL=chunk-3U5YHS4G.cjs.map
27943
- //# sourceMappingURL=chunk-3U5YHS4G.cjs.map
28079
+ //# sourceMappingURL=chunk-R4WR3VTN.cjs.map
28080
+ //# sourceMappingURL=chunk-R4WR3VTN.cjs.map