@sonicjs-cms/core 2.8.3 → 2.9.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 (81) hide show
  1. package/dist/{app-DnQ26Lho.d.cts → app-Ozl9agJG.d.cts} +1 -1
  2. package/dist/{app-DnQ26Lho.d.ts → app-Ozl9agJG.d.ts} +1 -1
  3. package/dist/{chunk-Y3VMEGY2.js → chunk-25YNV4RK.js} +3 -3
  4. package/dist/{chunk-Y3VMEGY2.js.map → chunk-25YNV4RK.js.map} +1 -1
  5. package/dist/{chunk-CH5UHZVM.js → chunk-2JGQKF7B.js} +184 -298
  6. package/dist/chunk-2JGQKF7B.js.map +1 -0
  7. package/dist/{chunk-5XAI2XUF.js → chunk-3FHMXGLF.js} +7 -5
  8. package/dist/chunk-3FHMXGLF.js.map +1 -0
  9. package/dist/{chunk-VNLR35GO.cjs → chunk-64APW3DW.cjs} +339 -2
  10. package/dist/chunk-64APW3DW.cjs.map +1 -0
  11. package/dist/{chunk-G44QUVNM.js → chunk-7JMMLHPQ.js} +337 -4
  12. package/dist/chunk-7JMMLHPQ.js.map +1 -0
  13. package/dist/chunk-CJYFSKH7.js +54 -54
  14. package/dist/chunk-CJYFSKH7.js.map +1 -1
  15. package/dist/{chunk-K4Q4SFJJ.cjs → chunk-DQZVU3WB.cjs} +4 -4
  16. package/dist/{chunk-K4Q4SFJJ.cjs.map → chunk-DQZVU3WB.cjs.map} +1 -1
  17. package/dist/{chunk-R4WR3VTN.cjs → chunk-KSB6FXOP.cjs} +285 -399
  18. package/dist/chunk-KSB6FXOP.cjs.map +1 -0
  19. package/dist/{chunk-HXHVU5GM.cjs → chunk-LDFMYRG6.cjs} +2 -2
  20. package/dist/{chunk-HXHVU5GM.cjs.map → chunk-LDFMYRG6.cjs.map} +1 -1
  21. package/dist/chunk-MNFY6DWY.cjs +54 -54
  22. package/dist/chunk-MNFY6DWY.cjs.map +1 -1
  23. package/dist/{chunk-JDIM5AG7.cjs → chunk-SHU7Q66Q.cjs} +7 -5
  24. package/dist/chunk-SHU7Q66Q.cjs.map +1 -0
  25. package/dist/{chunk-GTFMI24U.js → chunk-STTZVLY2.js} +2 -2
  26. package/dist/{chunk-GTFMI24U.js.map → chunk-STTZVLY2.js.map} +1 -1
  27. package/dist/{collection-config-i8EaAF7z.d.cts → collection-config-DckWhkdL.d.cts} +2 -2
  28. package/dist/{collection-config-i8EaAF7z.d.ts → collection-config-DckWhkdL.d.ts} +2 -2
  29. package/dist/{filter-bar.template-Daw8ZDoq.d.cts → filter-bar.template-DlVYMk-T.d.cts} +1 -1
  30. package/dist/{filter-bar.template-Daw8ZDoq.d.ts → filter-bar.template-DlVYMk-T.d.ts} +1 -1
  31. package/dist/index.cjs +128 -127
  32. package/dist/index.cjs.map +1 -1
  33. package/dist/index.d.cts +8 -8
  34. package/dist/index.d.ts +8 -8
  35. package/dist/index.js +10 -9
  36. package/dist/index.js.map +1 -1
  37. package/dist/middleware.cjs +28 -28
  38. package/dist/middleware.d.cts +1 -1
  39. package/dist/middleware.d.ts +1 -1
  40. package/dist/middleware.js +2 -2
  41. package/dist/migrations-QQWGDWGB.cjs +13 -0
  42. package/dist/{migrations-7X4RPH7O.cjs.map → migrations-QQWGDWGB.cjs.map} +1 -1
  43. package/dist/migrations-SZSR3C3G.js +4 -0
  44. package/dist/{migrations-KHWFJ2HN.js.map → migrations-SZSR3C3G.js.map} +1 -1
  45. package/dist/{plugin-zvZpaiP5.d.cts → plugin-0Xogrln-.d.cts} +1 -1
  46. package/dist/{plugin-zvZpaiP5.d.ts → plugin-0Xogrln-.d.ts} +1 -1
  47. package/dist/{plugin-bootstrap-CJozpgmI.d.cts → plugin-bootstrap-BAz7NY0H.d.cts} +2 -2
  48. package/dist/{plugin-bootstrap-DU5VmuHZ.d.ts → plugin-bootstrap-Cz3-bj8X.d.ts} +2 -2
  49. package/dist/{plugin-manager-Baa6xXqB.d.ts → plugin-manager-Clf2gXwj.d.ts} +2 -2
  50. package/dist/{plugin-manager-vBal9Zip.d.cts → plugin-manager-GcIeb226.d.cts} +2 -2
  51. package/dist/plugins.d.cts +2 -2
  52. package/dist/plugins.d.ts +2 -2
  53. package/dist/routes.cjs +28 -28
  54. package/dist/routes.d.cts +1 -1
  55. package/dist/routes.d.ts +1 -1
  56. package/dist/routes.js +5 -5
  57. package/dist/services.cjs +30 -14
  58. package/dist/services.d.cts +29 -4
  59. package/dist/services.d.ts +29 -4
  60. package/dist/services.js +2 -2
  61. package/dist/{telemetry-UiD1i9GS.d.cts → telemetry-B9vIV4wh.d.cts} +1 -1
  62. package/dist/{telemetry-UiD1i9GS.d.ts → telemetry-B9vIV4wh.d.ts} +1 -1
  63. package/dist/templates.d.cts +1 -1
  64. package/dist/templates.d.ts +1 -1
  65. package/dist/types.d.cts +3 -3
  66. package/dist/types.d.ts +3 -3
  67. package/dist/utils.cjs +11 -11
  68. package/dist/utils.d.cts +3 -3
  69. package/dist/utils.d.ts +3 -3
  70. package/dist/utils.js +1 -1
  71. package/dist/{version-C_CXrN_T.d.cts → version-ChpccWQ1.d.cts} +1 -1
  72. package/dist/{version-C_CXrN_T.d.ts → version-ChpccWQ1.d.ts} +1 -1
  73. package/package.json +5 -3
  74. package/dist/chunk-5XAI2XUF.js.map +0 -1
  75. package/dist/chunk-CH5UHZVM.js.map +0 -1
  76. package/dist/chunk-G44QUVNM.js.map +0 -1
  77. package/dist/chunk-JDIM5AG7.cjs.map +0 -1
  78. package/dist/chunk-R4WR3VTN.cjs.map +0 -1
  79. package/dist/chunk-VNLR35GO.cjs.map +0 -1
  80. package/dist/migrations-7X4RPH7O.cjs +0 -13
  81. package/dist/migrations-KHWFJ2HN.js +0 -4
@@ -1,12 +1,12 @@
1
1
  'use strict';
2
2
 
3
- var chunkVNLR35GO_cjs = require('./chunk-VNLR35GO.cjs');
4
- var chunkK4Q4SFJJ_cjs = require('./chunk-K4Q4SFJJ.cjs');
3
+ var chunk64APW3DW_cjs = require('./chunk-64APW3DW.cjs');
4
+ var chunkDQZVU3WB_cjs = require('./chunk-DQZVU3WB.cjs');
5
5
  var chunkMPT5PA6U_cjs = require('./chunk-MPT5PA6U.cjs');
6
- var chunkHXHVU5GM_cjs = require('./chunk-HXHVU5GM.cjs');
6
+ var chunkLDFMYRG6_cjs = require('./chunk-LDFMYRG6.cjs');
7
7
  var chunkLTKV7AE5_cjs = require('./chunk-LTKV7AE5.cjs');
8
8
  var chunk6FHNRRJ3_cjs = require('./chunk-6FHNRRJ3.cjs');
9
- var chunkJDIM5AG7_cjs = require('./chunk-JDIM5AG7.cjs');
9
+ var chunkSHU7Q66Q_cjs = require('./chunk-SHU7Q66Q.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("/", chunkK4Q4SFJJ_cjs.requireAuth(), async (c) => {
124
+ apiContentCrudRoutes.post("/", chunkDQZVU3WB_cjs.requireAuth(), async (c) => {
125
125
  try {
126
126
  const db = c.env.DB;
127
127
  const user = c.get("user");
@@ -162,7 +162,7 @@ apiContentCrudRoutes.post("/", chunkK4Q4SFJJ_cjs.requireAuth(), async (c) => {
162
162
  now,
163
163
  now
164
164
  ).run();
165
- const cache = chunkVNLR35GO_cjs.getCacheService(chunkVNLR35GO_cjs.CACHE_CONFIGS.api);
165
+ const cache = chunk64APW3DW_cjs.getCacheService(chunk64APW3DW_cjs.CACHE_CONFIGS.api);
166
166
  await cache.invalidate(`content:list:${collectionId}:*`);
167
167
  await cache.invalidate("content-filtered:*");
168
168
  const getStmt = db.prepare("SELECT * FROM content WHERE id = ?");
@@ -187,7 +187,7 @@ apiContentCrudRoutes.post("/", chunkK4Q4SFJJ_cjs.requireAuth(), async (c) => {
187
187
  }, 500);
188
188
  }
189
189
  });
190
- apiContentCrudRoutes.put("/:id", chunkK4Q4SFJJ_cjs.requireAuth(), async (c) => {
190
+ apiContentCrudRoutes.put("/:id", chunkDQZVU3WB_cjs.requireAuth(), async (c) => {
191
191
  try {
192
192
  const id = c.req.param("id");
193
193
  const db = c.env.DB;
@@ -225,7 +225,7 @@ apiContentCrudRoutes.put("/:id", chunkK4Q4SFJJ_cjs.requireAuth(), async (c) => {
225
225
  WHERE id = ?
226
226
  `);
227
227
  await updateStmt.bind(...params).run();
228
- const cache = chunkVNLR35GO_cjs.getCacheService(chunkVNLR35GO_cjs.CACHE_CONFIGS.api);
228
+ const cache = chunk64APW3DW_cjs.getCacheService(chunk64APW3DW_cjs.CACHE_CONFIGS.api);
229
229
  await cache.delete(cache.generateKey("content", id));
230
230
  await cache.invalidate(`content:list:${existing.collection_id}:*`);
231
231
  await cache.invalidate("content-filtered:*");
@@ -251,7 +251,7 @@ apiContentCrudRoutes.put("/:id", chunkK4Q4SFJJ_cjs.requireAuth(), async (c) => {
251
251
  }, 500);
252
252
  }
253
253
  });
254
- apiContentCrudRoutes.delete("/:id", chunkK4Q4SFJJ_cjs.requireAuth(), async (c) => {
254
+ apiContentCrudRoutes.delete("/:id", chunkDQZVU3WB_cjs.requireAuth(), async (c) => {
255
255
  try {
256
256
  const id = c.req.param("id");
257
257
  const db = c.env.DB;
@@ -262,7 +262,7 @@ apiContentCrudRoutes.delete("/:id", chunkK4Q4SFJJ_cjs.requireAuth(), async (c) =
262
262
  }
263
263
  const deleteStmt = db.prepare("DELETE FROM content WHERE id = ?");
264
264
  await deleteStmt.bind(id).run();
265
- const cache = chunkVNLR35GO_cjs.getCacheService(chunkVNLR35GO_cjs.CACHE_CONFIGS.api);
265
+ const cache = chunk64APW3DW_cjs.getCacheService(chunk64APW3DW_cjs.CACHE_CONFIGS.api);
266
266
  await cache.delete(cache.generateKey("content", id));
267
267
  await cache.invalidate(`content:list:${existing.collection_id}:*`);
268
268
  await cache.invalidate("content-filtered:*");
@@ -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 chunkK4Q4SFJJ_cjs.isPluginActive(c.env.DB, "core-cache");
290
+ const cacheEnabled = await chunkDQZVU3WB_cjs.isPluginActive(c.env.DB, "core-cache");
291
291
  c.set("cacheEnabled", cacheEnabled);
292
292
  await next();
293
293
  });
@@ -724,7 +724,7 @@ apiRoutes.get("/collections", async (c) => {
724
724
  try {
725
725
  const db = c.env.DB;
726
726
  const cacheEnabled = c.get("cacheEnabled");
727
- const cache = chunkVNLR35GO_cjs.getCacheService(chunkVNLR35GO_cjs.CACHE_CONFIGS.api);
727
+ const cache = chunk64APW3DW_cjs.getCacheService(chunk64APW3DW_cjs.CACHE_CONFIGS.api);
728
728
  const cacheKey = cache.generateKey("collections", "all");
729
729
  if (cacheEnabled) {
730
730
  const cacheResult = await cache.getWithSource(cacheKey);
@@ -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", chunkK4Q4SFJJ_cjs.optionalAuth(), async (c) => {
781
+ apiRoutes.get("/content", chunkDQZVU3WB_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", chunkK4Q4SFJJ_cjs.optionalAuth(), async (c) => {
801
801
  });
802
802
  }
803
803
  }
804
- const filter = chunkJDIM5AG7_cjs.QueryFilterBuilder.parseFromQuery(queryParams);
804
+ const filter = chunkSHU7Q66Q_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 chunkJDIM5AG7_cjs.QueryFilterBuilder();
810
+ const builder3 = new chunkSHU7Q66Q_cjs.QueryFilterBuilder();
811
811
  const queryResult = builder3.build("content", normalizedFilter);
812
812
  if (queryResult.errors.length > 0) {
813
813
  return c.json({
@@ -816,7 +816,7 @@ apiRoutes.get("/content", chunkK4Q4SFJJ_cjs.optionalAuth(), async (c) => {
816
816
  }, 400);
817
817
  }
818
818
  const cacheEnabled = c.get("cacheEnabled");
819
- const cache = chunkVNLR35GO_cjs.getCacheService(chunkVNLR35GO_cjs.CACHE_CONFIGS.api);
819
+ const cache = chunk64APW3DW_cjs.getCacheService(chunk64APW3DW_cjs.CACHE_CONFIGS.api);
820
820
  const cacheKey = cache.generateKey("content-filtered", JSON.stringify({ filter: normalizedFilter, query: queryResult.sql }));
821
821
  if (cacheEnabled) {
822
822
  const cacheResult = await cache.getWithSource(cacheKey);
@@ -879,7 +879,7 @@ apiRoutes.get("/content", chunkK4Q4SFJJ_cjs.optionalAuth(), async (c) => {
879
879
  }, 500);
880
880
  }
881
881
  });
882
- apiRoutes.get("/collections/:collection/content", chunkK4Q4SFJJ_cjs.optionalAuth(), async (c) => {
882
+ apiRoutes.get("/collections/:collection/content", chunkDQZVU3WB_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", chunkK4Q4SFJJ_cjs.optionalAuth
890
890
  if (!collectionResult) {
891
891
  return c.json({ error: "Collection not found" }, 404);
892
892
  }
893
- const filter = chunkJDIM5AG7_cjs.QueryFilterBuilder.parseFromQuery(queryParams);
893
+ const filter = chunkSHU7Q66Q_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", chunkK4Q4SFJJ_cjs.optionalAuth
907
907
  normalizedFilter.limit = 50;
908
908
  }
909
909
  normalizedFilter.limit = Math.min(normalizedFilter.limit, 1e3);
910
- const builder3 = new chunkJDIM5AG7_cjs.QueryFilterBuilder();
910
+ const builder3 = new chunkSHU7Q66Q_cjs.QueryFilterBuilder();
911
911
  const queryResult = builder3.build("content", normalizedFilter);
912
912
  if (queryResult.errors.length > 0) {
913
913
  return c.json({
@@ -916,7 +916,7 @@ apiRoutes.get("/collections/:collection/content", chunkK4Q4SFJJ_cjs.optionalAuth
916
916
  }, 400);
917
917
  }
918
918
  const cacheEnabled = c.get("cacheEnabled");
919
- const cache = chunkVNLR35GO_cjs.getCacheService(chunkVNLR35GO_cjs.CACHE_CONFIGS.api);
919
+ const cache = chunk64APW3DW_cjs.getCacheService(chunk64APW3DW_cjs.CACHE_CONFIGS.api);
920
920
  const cacheKey = cache.generateKey("collection-content-filtered", `${collection}:${JSON.stringify({ filter: normalizedFilter, query: queryResult.sql })}`);
921
921
  if (cacheEnabled) {
922
922
  const cacheResult = await cache.getWithSource(cacheKey);
@@ -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("*", chunkK4Q4SFJJ_cjs.requireAuth());
1031
+ apiMediaRoutes.use("*", chunkDQZVU3WB_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("*", chunkK4Q4SFJJ_cjs.requireAuth());
1776
- adminApiRoutes.use("*", chunkK4Q4SFJJ_cjs.requireRole(["admin", "editor"]));
1775
+ adminApiRoutes.use("*", chunkDQZVU3WB_cjs.requireAuth());
1776
+ adminApiRoutes.use("*", chunkDQZVU3WB_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-7X4RPH7O.cjs');
2286
+ const { MigrationService: MigrationService2 } = await import('./migrations-QQWGDWGB.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-7X4RPH7O.cjs');
2311
+ const { MigrationService: MigrationService2 } = await import('./migrations-QQWGDWGB.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-7X4RPH7O.cjs');
2330
+ const { MigrationService: MigrationService2 } = await import('./migrations-QQWGDWGB.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 chunkK4Q4SFJJ_cjs.generateCsrfToken(secret);
2741
+ const csrfToken = await chunkDQZVU3WB_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
- chunkK4Q4SFJJ_cjs.rateLimit({ max: 3, windowMs: 60 * 1e3, keyPrefix: "register" }),
2798
+ chunkDQZVU3WB_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 chunkK4Q4SFJJ_cjs.AuthManager.hashPassword(password);
2835
+ const passwordHash = await chunkDQZVU3WB_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 chunkK4Q4SFJJ_cjs.AuthManager.generateToken(userId, normalizedEmail, "viewer", c.env.JWT_SECRET);
2855
+ const token = await chunkDQZVU3WB_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
- chunkK4Q4SFJJ_cjs.rateLimit({ max: 5, windowMs: 60 * 1e3, keyPrefix: "login" }),
2889
+ chunkDQZVU3WB_cjs.rateLimit({ max: 5, windowMs: 60 * 1e3, keyPrefix: "login" }),
2890
2890
  async (c) => {
2891
2891
  try {
2892
2892
  const body = await c.req.json();
@@ -2897,7 +2897,7 @@ authRoutes.post(
2897
2897
  const { email, password } = validation.data;
2898
2898
  const db = c.env.DB;
2899
2899
  const normalizedEmail = email.toLowerCase();
2900
- const cache = chunkVNLR35GO_cjs.getCacheService(chunkVNLR35GO_cjs.CACHE_CONFIGS.user);
2900
+ const cache = chunk64APW3DW_cjs.getCacheService(chunk64APW3DW_cjs.CACHE_CONFIGS.user);
2901
2901
  let user = await cache.get(cache.generateKey("user", `email:${normalizedEmail}`));
2902
2902
  if (!user) {
2903
2903
  user = await db.prepare("SELECT * FROM users WHERE email = ? AND is_active = 1").bind(normalizedEmail).first();
@@ -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 chunkK4Q4SFJJ_cjs.AuthManager.verifyPassword(password, user.password_hash);
2912
+ const isValidPassword = await chunkDQZVU3WB_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 (chunkK4Q4SFJJ_cjs.AuthManager.isLegacyHash(user.password_hash)) {
2916
+ if (chunkDQZVU3WB_cjs.AuthManager.isLegacyHash(user.password_hash)) {
2917
2917
  try {
2918
- const newHash = await chunkK4Q4SFJJ_cjs.AuthManager.hashPassword(password);
2918
+ const newHash = await chunkDQZVU3WB_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 chunkK4Q4SFJJ_cjs.AuthManager.generateToken(user.id, user.email, user.role, c.env.JWT_SECRET);
2924
+ const token = await chunkDQZVU3WB_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", chunkK4Q4SFJJ_cjs.requireAuth(), async (c) => {
2977
+ authRoutes.get("/me", chunkDQZVU3WB_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", chunkK4Q4SFJJ_cjs.requireAuth(), async (c) => {
2991
2991
  return c.json({ error: "Failed to get user" }, 500);
2992
2992
  }
2993
2993
  });
2994
- authRoutes.post("/refresh", chunkK4Q4SFJJ_cjs.requireAuth(), async (c) => {
2994
+ authRoutes.post("/refresh", chunkDQZVU3WB_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 chunkK4Q4SFJJ_cjs.AuthManager.generateToken(user.userId, user.email, user.role, c.env.JWT_SECRET);
3000
+ const token = await chunkDQZVU3WB_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", chunkK4Q4SFJJ_cjs.requireAuth(), async (c) => {
3014
3014
  });
3015
3015
  authRoutes.post(
3016
3016
  "/register/form",
3017
- chunkK4Q4SFJJ_cjs.rateLimit({ max: 3, windowMs: 60 * 1e3, keyPrefix: "register" }),
3017
+ chunkDQZVU3WB_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 chunkK4Q4SFJJ_cjs.AuthManager.hashPassword(password);
3064
+ const passwordHash = await chunkDQZVU3WB_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 chunkK4Q4SFJJ_cjs.AuthManager.generateToken(userId, normalizedEmail, role, c.env.JWT_SECRET);
3084
+ const token = await chunkDQZVU3WB_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
- chunkK4Q4SFJJ_cjs.rateLimit({ max: 5, windowMs: 60 * 1e3, keyPrefix: "login" }),
3117
+ chunkDQZVU3WB_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 chunkK4Q4SFJJ_cjs.AuthManager.verifyPassword(password, user.password_hash);
3141
+ const isValidPassword = await chunkDQZVU3WB_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 (chunkK4Q4SFJJ_cjs.AuthManager.isLegacyHash(user.password_hash)) {
3149
+ if (chunkDQZVU3WB_cjs.AuthManager.isLegacyHash(user.password_hash)) {
3150
3150
  try {
3151
- const newHash = await chunkK4Q4SFJJ_cjs.AuthManager.hashPassword(password);
3151
+ const newHash = await chunkDQZVU3WB_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 chunkK4Q4SFJJ_cjs.AuthManager.generateToken(user.id, user.email, user.role, c.env.JWT_SECRET);
3157
+ const token = await chunkDQZVU3WB_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
- chunkK4Q4SFJJ_cjs.rateLimit({ max: 2, windowMs: 60 * 1e3, keyPrefix: "seed-admin" }),
3199
+ chunkDQZVU3WB_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 chunkK4Q4SFJJ_cjs.AuthManager.hashPassword("sonicjs!");
3221
+ const passwordHash2 = await chunkDQZVU3WB_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 chunkK4Q4SFJJ_cjs.AuthManager.hashPassword("sonicjs!");
3233
+ const passwordHash = await chunkDQZVU3WB_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 chunkK4Q4SFJJ_cjs.AuthManager.hashPassword(password);
3454
+ const passwordHash = await chunkDQZVU3WB_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 chunkK4Q4SFJJ_cjs.AuthManager.generateToken(invitedUser.id, invitedUser.email, invitedUser.role, c.env.JWT_SECRET);
3473
+ const authToken = await chunkDQZVU3WB_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
- chunkK4Q4SFJJ_cjs.rateLimit({ max: 3, windowMs: 15 * 60 * 1e3, keyPrefix: "password-reset" }),
3490
+ chunkDQZVU3WB_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 chunkK4Q4SFJJ_cjs.AuthManager.hashPassword(password);
3708
+ const newPasswordHash = await chunkDQZVU3WB_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)
@@ -4286,7 +4286,7 @@ function getMDXEditorInitScript(config) {
4286
4286
  const toolbar = config?.toolbar || "full";
4287
4287
  const placeholder = config?.placeholder || "Start writing your content...";
4288
4288
  return `
4289
- // Initialize EasyMDE (Markdown Editor) for all richtext fields
4289
+ // Initialize EasyMDE (Markdown Editor) only for markdown-marked fields
4290
4290
  function initializeMDXEditor() {
4291
4291
  if (typeof EasyMDE === 'undefined') {
4292
4292
  console.warn('EasyMDE not loaded yet, retrying...');
@@ -4295,7 +4295,7 @@ function getMDXEditorInitScript(config) {
4295
4295
  }
4296
4296
 
4297
4297
  // Find all textareas that need EasyMDE
4298
- document.querySelectorAll('.richtext-container textarea').forEach((textarea) => {
4298
+ document.querySelectorAll('.richtext-container[data-editor-provider="easymde"] textarea').forEach((textarea) => {
4299
4299
  // Skip if already initialized
4300
4300
  if (textarea.dataset.mdxeditorInitialized === 'true') {
4301
4301
  return;
@@ -4394,11 +4394,11 @@ function getTinyMCEInitScript(config) {
4394
4394
  const contentCss = skin.includes("dark") ? "dark" : "default";
4395
4395
  const defaultHeight = config?.defaultHeight || 300;
4396
4396
  return `
4397
- // Initialize TinyMCE for all richtext fields
4397
+ // Initialize TinyMCE only for TinyMCE-backed richtext fields
4398
4398
  function initializeTinyMCE() {
4399
4399
  if (typeof tinymce !== 'undefined') {
4400
4400
  // Find all textareas that need TinyMCE
4401
- document.querySelectorAll('.richtext-container textarea').forEach((textarea) => {
4401
+ document.querySelectorAll('.richtext-container[data-editor-provider="tinymce"] textarea').forEach((textarea) => {
4402
4402
  // Skip if already initialized
4403
4403
  if (tinymce.get(textarea.id)) {
4404
4404
  return;
@@ -4835,6 +4835,24 @@ function getReadFieldValueScript() {
4835
4835
  </script>
4836
4836
  `;
4837
4837
  }
4838
+ function isMarkdownEditorFieldType(fieldType) {
4839
+ return fieldType === "markdown" || fieldType === "mdxeditor" || fieldType === "easymde";
4840
+ }
4841
+ function getEditorMetadata(fieldType) {
4842
+ if (fieldType === "richtext" || fieldType === "tinymce") {
4843
+ return {
4844
+ family: "richtext",
4845
+ provider: "tinymce"
4846
+ };
4847
+ }
4848
+ if (isMarkdownEditorFieldType(fieldType)) {
4849
+ return {
4850
+ family: "markdown",
4851
+ provider: "easymde"
4852
+ };
4853
+ }
4854
+ return null;
4855
+ }
4838
4856
  function renderDynamicField(field, options = {}) {
4839
4857
  const { value = "", errors = [], disabled = false, className = "", pluginStatuses = {}, collectionId = "", contentId = "" } = options;
4840
4858
  const opts = field.field_options || {};
@@ -4848,10 +4866,10 @@ function renderDynamicField(field, options = {}) {
4848
4866
  if (field.field_type === "quill" && !pluginStatuses.quillEnabled) {
4849
4867
  fallbackToTextarea = true;
4850
4868
  fallbackWarning = "\u26A0\uFE0F Quill Editor plugin is inactive. Using textarea fallback.";
4851
- } else if ((field.field_type === "mdxeditor" || field.field_type === "easymde" || field.field_type === "markdown") && !pluginStatuses.mdxeditorEnabled) {
4869
+ } else if (isMarkdownEditorFieldType(field.field_type) && !pluginStatuses.mdxeditorEnabled) {
4852
4870
  fallbackToTextarea = true;
4853
- fallbackWarning = "\u26A0\uFE0F EasyMDE plugin is inactive. Using textarea fallback.";
4854
- } else if (field.field_type === "tinymce" && !pluginStatuses.tinymceEnabled) {
4871
+ fallbackWarning = "\u26A0\uFE0F Markdown editor plugin is inactive. Using textarea fallback.";
4872
+ } else if ((field.field_type === "richtext" || field.field_type === "tinymce") && !pluginStatuses.tinymceEnabled) {
4855
4873
  fallbackToTextarea = true;
4856
4874
  fallbackWarning = "\u26A0\uFE0F TinyMCE plugin is inactive. Using textarea fallback.";
4857
4875
  }
@@ -4973,8 +4991,10 @@ function renderDynamicField(field, options = {}) {
4973
4991
  `;
4974
4992
  break;
4975
4993
  case "richtext":
4994
+ case "tinymce": {
4995
+ const editorMetadata = getEditorMetadata(field.field_type);
4976
4996
  fieldHTML = `
4977
- <div class="richtext-container" data-height="${opts.height || 300}" data-toolbar="${opts.toolbar || "full"}">
4997
+ <div class="richtext-container" data-height="${opts.height || 300}" data-toolbar="${opts.toolbar || "full"}" data-editor-family="${editorMetadata?.family || ""}" data-editor-provider="${editorMetadata?.provider || ""}">
4978
4998
  <textarea
4979
4999
  id="${fieldId}"
4980
5000
  name="${fieldName}"
@@ -4985,6 +5005,7 @@ function renderDynamicField(field, options = {}) {
4985
5005
  </div>
4986
5006
  `;
4987
5007
  break;
5008
+ }
4988
5009
  case "quill":
4989
5010
  fieldHTML = `
4990
5011
  <div class="quill-editor-container" data-field-id="${fieldId}">
@@ -5008,12 +5029,12 @@ function renderDynamicField(field, options = {}) {
5008
5029
  </div>
5009
5030
  `;
5010
5031
  break;
5011
- case "mdxeditor":
5012
- case "tinymce":
5013
- case "easymde":
5014
5032
  case "markdown":
5033
+ case "mdxeditor":
5034
+ case "easymde": {
5035
+ const editorMetadata = getEditorMetadata(field.field_type);
5015
5036
  fieldHTML = `
5016
- <div class="richtext-container" data-height="${opts.height || 300}" data-toolbar="${opts.toolbar || "full"}">
5037
+ <div class="richtext-container" data-height="${opts.height || 300}" data-toolbar="${opts.toolbar || "full"}" data-editor-family="${editorMetadata?.family || ""}" data-editor-provider="${editorMetadata?.provider || ""}">
5017
5038
  <textarea
5018
5039
  id="${fieldId}"
5019
5040
  name="${fieldName}"
@@ -5024,6 +5045,7 @@ function renderDynamicField(field, options = {}) {
5024
5045
  </div>
5025
5046
  `;
5026
5047
  break;
5048
+ }
5027
5049
  case "number":
5028
5050
  fieldHTML = `
5029
5051
  <input
@@ -8242,15 +8264,49 @@ function renderContentListPage(data) {
8242
8264
  return chunkLTKV7AE5_cjs.renderAdminLayoutCatalyst(layoutData);
8243
8265
  }
8244
8266
 
8267
+ // src/routes/admin-content-field-types.ts
8268
+ function resolveSchemaFieldType(fieldConfig) {
8269
+ if (fieldConfig.type === "slug" || fieldConfig.format === "slug") {
8270
+ return "slug";
8271
+ }
8272
+ if (fieldConfig.type && fieldConfig.type !== "string") {
8273
+ return fieldConfig.type;
8274
+ }
8275
+ if (fieldConfig.format === "richtext") {
8276
+ return "richtext";
8277
+ }
8278
+ if (fieldConfig.format === "media") {
8279
+ return "media";
8280
+ }
8281
+ if (fieldConfig.format === "date-time") {
8282
+ return "date";
8283
+ }
8284
+ if (Array.isArray(fieldConfig.enum)) {
8285
+ return "select";
8286
+ }
8287
+ return fieldConfig.type || "string";
8288
+ }
8289
+ function buildSchemaFieldOptions(fieldConfig) {
8290
+ const fieldOptions = { ...fieldConfig };
8291
+ const resolvedFieldType = resolveSchemaFieldType(fieldConfig);
8292
+ if (resolvedFieldType === "select" && Array.isArray(fieldConfig.enum)) {
8293
+ fieldOptions.options = fieldConfig.enum.map((value, index) => ({
8294
+ value,
8295
+ label: fieldConfig.enumLabels?.[index] || value
8296
+ }));
8297
+ }
8298
+ return fieldOptions;
8299
+ }
8300
+
8245
8301
  // src/routes/admin-content.ts
8246
8302
  var adminContentRoutes = new hono.Hono();
8247
8303
  function parseFieldValue(field, formData, options = {}) {
8248
8304
  const { skipValidation = false } = options;
8249
8305
  const value = formData.get(field.field_name);
8250
8306
  const errors = [];
8251
- const blocksConfig = chunkJDIM5AG7_cjs.getBlocksFieldConfig(field.field_options);
8307
+ const blocksConfig = chunkSHU7Q66Q_cjs.getBlocksFieldConfig(field.field_options);
8252
8308
  if (blocksConfig) {
8253
- const parsed = chunkJDIM5AG7_cjs.parseBlocksValue(value, blocksConfig);
8309
+ const parsed = chunkSHU7Q66Q_cjs.parseBlocksValue(value, blocksConfig);
8254
8310
  if (!skipValidation && field.is_required && parsed.value.length === 0) {
8255
8311
  parsed.errors.push(`${field.field_label} is required`);
8256
8312
  }
@@ -8360,9 +8416,9 @@ function extractFieldData(fields, formData, options = {}) {
8360
8416
  }
8361
8417
  return { data, errors };
8362
8418
  }
8363
- adminContentRoutes.use("*", chunkK4Q4SFJJ_cjs.requireAuth());
8419
+ adminContentRoutes.use("*", chunkDQZVU3WB_cjs.requireAuth());
8364
8420
  async function getCollectionFields(db, collectionId) {
8365
- const cache = chunkVNLR35GO_cjs.getCacheService(chunkVNLR35GO_cjs.CACHE_CONFIGS.collection);
8421
+ const cache = chunk64APW3DW_cjs.getCacheService(chunk64APW3DW_cjs.CACHE_CONFIGS.collection);
8366
8422
  return cache.getOrSet(
8367
8423
  cache.generateKey("fields", collectionId),
8368
8424
  async () => {
@@ -8374,17 +8430,11 @@ async function getCollectionFields(db, collectionId) {
8374
8430
  if (schema && schema.properties) {
8375
8431
  let fieldOrder = 0;
8376
8432
  return Object.entries(schema.properties).map(([fieldName, fieldConfig]) => {
8377
- let fieldOptions = { ...fieldConfig };
8378
- if (fieldConfig.type === "select" && fieldConfig.enum) {
8379
- fieldOptions.options = fieldConfig.enum.map((value, index) => ({
8380
- value,
8381
- label: fieldConfig.enumLabels?.[index] || value
8382
- }));
8383
- }
8433
+ const fieldOptions = buildSchemaFieldOptions(fieldConfig);
8384
8434
  return {
8385
8435
  id: `schema-${fieldName}`,
8386
8436
  field_name: fieldName,
8387
- field_type: fieldConfig.type || "string",
8437
+ field_type: resolveSchemaFieldType(fieldConfig),
8388
8438
  field_label: fieldConfig.title || fieldName,
8389
8439
  field_options: fieldOptions,
8390
8440
  field_order: fieldOrder++,
@@ -8417,7 +8467,7 @@ async function getCollectionFields(db, collectionId) {
8417
8467
  );
8418
8468
  }
8419
8469
  async function getCollection(db, collectionId) {
8420
- const cache = chunkVNLR35GO_cjs.getCacheService(chunkVNLR35GO_cjs.CACHE_CONFIGS.collection);
8470
+ const cache = chunk64APW3DW_cjs.getCacheService(chunk64APW3DW_cjs.CACHE_CONFIGS.collection);
8421
8471
  return cache.getOrSet(
8422
8472
  cache.generateKey("collection", collectionId),
8423
8473
  async () => {
@@ -8706,7 +8756,7 @@ adminContentRoutes.get("/:id/edit", async (c) => {
8706
8756
  const db = c.env.DB;
8707
8757
  const url = new URL(c.req.url);
8708
8758
  const referrerParams = url.searchParams.get("ref") || "";
8709
- const cache = chunkVNLR35GO_cjs.getCacheService(chunkVNLR35GO_cjs.CACHE_CONFIGS.content);
8759
+ const cache = chunk64APW3DW_cjs.getCacheService(chunk64APW3DW_cjs.CACHE_CONFIGS.content);
8710
8760
  const content = await cache.getOrSet(
8711
8761
  cache.generateKey("content", id),
8712
8762
  async () => {
@@ -8882,7 +8932,7 @@ adminContentRoutes.post("/", async (c) => {
8882
8932
  now,
8883
8933
  now
8884
8934
  ).run();
8885
- const cache = chunkVNLR35GO_cjs.getCacheService(chunkVNLR35GO_cjs.CACHE_CONFIGS.content);
8935
+ const cache = chunk64APW3DW_cjs.getCacheService(chunk64APW3DW_cjs.CACHE_CONFIGS.content);
8886
8936
  await cache.invalidate(`content:list:${collectionId}:*`);
8887
8937
  const versionStmt = db.prepare(`
8888
8938
  INSERT INTO content_versions (id, content_id, version, data, author_id, created_at)
@@ -9001,7 +9051,7 @@ adminContentRoutes.put("/:id", async (c) => {
9001
9051
  now,
9002
9052
  id
9003
9053
  ).run();
9004
- const cache = chunkVNLR35GO_cjs.getCacheService(chunkVNLR35GO_cjs.CACHE_CONFIGS.content);
9054
+ const cache = chunk64APW3DW_cjs.getCacheService(chunk64APW3DW_cjs.CACHE_CONFIGS.content);
9005
9055
  await cache.delete(cache.generateKey("content", id));
9006
9056
  await cache.invalidate(`content:list:${existingContent.collection_id}:*`);
9007
9057
  const existingData = JSON.parse(existingContent.data || "{}");
@@ -9056,7 +9106,7 @@ adminContentRoutes.put("/:id", async (c) => {
9056
9106
  `);
9057
9107
  }
9058
9108
  });
9059
- adminContentRoutes.post("/preview", chunkK4Q4SFJJ_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
9109
+ adminContentRoutes.post("/preview", chunkDQZVU3WB_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
9060
9110
  try {
9061
9111
  const formData = await c.req.formData();
9062
9112
  const collectionId = formData.get("collection_id");
@@ -9278,7 +9328,7 @@ adminContentRoutes.post("/bulk-action", async (c) => {
9278
9328
  } else {
9279
9329
  return c.json({ success: false, error: "Invalid action" });
9280
9330
  }
9281
- const cache = chunkVNLR35GO_cjs.getCacheService(chunkVNLR35GO_cjs.CACHE_CONFIGS.content);
9331
+ const cache = chunk64APW3DW_cjs.getCacheService(chunk64APW3DW_cjs.CACHE_CONFIGS.content);
9282
9332
  for (const contentId of ids) {
9283
9333
  await cache.delete(cache.generateKey("content", contentId));
9284
9334
  }
@@ -9306,7 +9356,7 @@ adminContentRoutes.delete("/:id", async (c) => {
9306
9356
  WHERE id = ?
9307
9357
  `);
9308
9358
  await deleteStmt.bind(now, id).run();
9309
- const cache = chunkVNLR35GO_cjs.getCacheService(chunkVNLR35GO_cjs.CACHE_CONFIGS.content);
9359
+ const cache = chunk64APW3DW_cjs.getCacheService(chunk64APW3DW_cjs.CACHE_CONFIGS.content);
9310
9360
  await cache.delete(cache.generateKey("content", id));
9311
9361
  await cache.invalidate("content:list:*");
9312
9362
  return c.html(`
@@ -9434,7 +9484,7 @@ adminContentRoutes.post("/:id/restore/:version", async (c) => {
9434
9484
  return c.json({ success: false, error: "Failed to restore version" });
9435
9485
  }
9436
9486
  });
9437
- adminContentRoutes.get("/:id/version/:version/preview", chunkK4Q4SFJJ_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
9487
+ adminContentRoutes.get("/:id/version/:version/preview", chunkDQZVU3WB_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
9438
9488
  try {
9439
9489
  const id = c.req.param("id");
9440
9490
  const version = parseInt(c.req.param("version") || "0");
@@ -11401,7 +11451,7 @@ function renderUsersListPage(data) {
11401
11451
 
11402
11452
  // src/routes/admin-users.ts
11403
11453
  var userRoutes = new hono.Hono();
11404
- userRoutes.use("*", chunkK4Q4SFJJ_cjs.requireAuth());
11454
+ userRoutes.use("*", chunkDQZVU3WB_cjs.requireAuth());
11405
11455
  userRoutes.get("/", (c) => {
11406
11456
  return c.redirect("/admin/dashboard");
11407
11457
  });
@@ -11556,7 +11606,7 @@ userRoutes.put("/profile", async (c) => {
11556
11606
  Date.now(),
11557
11607
  user.userId
11558
11608
  ).run();
11559
- await chunkK4Q4SFJJ_cjs.logActivity(
11609
+ await chunkDQZVU3WB_cjs.logActivity(
11560
11610
  db,
11561
11611
  user.userId,
11562
11612
  "profile.update",
@@ -11619,7 +11669,7 @@ userRoutes.post("/profile/avatar", async (c) => {
11619
11669
  SELECT first_name, last_name FROM users WHERE id = ?
11620
11670
  `);
11621
11671
  const userData = await userStmt.bind(user.userId).first();
11622
- await chunkK4Q4SFJJ_cjs.logActivity(
11672
+ await chunkDQZVU3WB_cjs.logActivity(
11623
11673
  db,
11624
11674
  user.userId,
11625
11675
  "profile.avatar_update",
@@ -11690,7 +11740,7 @@ userRoutes.post("/profile/password", async (c) => {
11690
11740
  dismissible: true
11691
11741
  }));
11692
11742
  }
11693
- const validPassword = await chunkK4Q4SFJJ_cjs.AuthManager.verifyPassword(currentPassword, userData.password_hash);
11743
+ const validPassword = await chunkDQZVU3WB_cjs.AuthManager.verifyPassword(currentPassword, userData.password_hash);
11694
11744
  if (!validPassword) {
11695
11745
  return c.html(renderAlert2({
11696
11746
  type: "error",
@@ -11698,7 +11748,7 @@ userRoutes.post("/profile/password", async (c) => {
11698
11748
  dismissible: true
11699
11749
  }));
11700
11750
  }
11701
- const newPasswordHash = await chunkK4Q4SFJJ_cjs.AuthManager.hashPassword(newPassword);
11751
+ const newPasswordHash = await chunkDQZVU3WB_cjs.AuthManager.hashPassword(newPassword);
11702
11752
  const historyStmt = db.prepare(`
11703
11753
  INSERT INTO password_history (id, user_id, password_hash, created_at)
11704
11754
  VALUES (?, ?, ?, ?)
@@ -11714,7 +11764,7 @@ userRoutes.post("/profile/password", async (c) => {
11714
11764
  WHERE id = ?
11715
11765
  `);
11716
11766
  await updateStmt.bind(newPasswordHash, Date.now(), user.userId).run();
11717
- await chunkK4Q4SFJJ_cjs.logActivity(
11767
+ await chunkDQZVU3WB_cjs.logActivity(
11718
11768
  db,
11719
11769
  user.userId,
11720
11770
  "profile.password_change",
@@ -11781,7 +11831,7 @@ userRoutes.get("/users", async (c) => {
11781
11831
  `);
11782
11832
  const countResult = await countStmt.bind(...params).first();
11783
11833
  const totalUsers = countResult?.total || 0;
11784
- await chunkK4Q4SFJJ_cjs.logActivity(
11834
+ await chunkDQZVU3WB_cjs.logActivity(
11785
11835
  db,
11786
11836
  user.userId,
11787
11837
  "users.list_view",
@@ -11935,7 +11985,7 @@ userRoutes.post("/users/new", async (c) => {
11935
11985
  dismissible: true
11936
11986
  }));
11937
11987
  }
11938
- const passwordHash = await chunkK4Q4SFJJ_cjs.AuthManager.hashPassword(password);
11988
+ const passwordHash = await chunkDQZVU3WB_cjs.AuthManager.hashPassword(password);
11939
11989
  const userId = crypto.randomUUID();
11940
11990
  const createStmt = db.prepare(`
11941
11991
  INSERT INTO users (
@@ -11958,7 +12008,7 @@ userRoutes.post("/users/new", async (c) => {
11958
12008
  Date.now(),
11959
12009
  Date.now()
11960
12010
  ).run();
11961
- await chunkK4Q4SFJJ_cjs.logActivity(
12011
+ await chunkDQZVU3WB_cjs.logActivity(
11962
12012
  db,
11963
12013
  user.userId,
11964
12014
  "user!.create",
@@ -11996,7 +12046,7 @@ userRoutes.get("/users/:id", async (c) => {
11996
12046
  if (!userRecord) {
11997
12047
  return c.json({ error: "User not found" }, 404);
11998
12048
  }
11999
- await chunkK4Q4SFJJ_cjs.logActivity(
12049
+ await chunkDQZVU3WB_cjs.logActivity(
12000
12050
  db,
12001
12051
  user.userId,
12002
12052
  "user!.view",
@@ -12221,7 +12271,7 @@ userRoutes.put("/users/:id", async (c) => {
12221
12271
  ).run();
12222
12272
  }
12223
12273
  }
12224
- await chunkK4Q4SFJJ_cjs.logActivity(
12274
+ await chunkDQZVU3WB_cjs.logActivity(
12225
12275
  db,
12226
12276
  user.userId,
12227
12277
  "user.update",
@@ -12266,7 +12316,7 @@ userRoutes.post("/users/:id/toggle", async (c) => {
12266
12316
  UPDATE users SET is_active = ?, updated_at = ? WHERE id = ?
12267
12317
  `);
12268
12318
  await toggleStmt.bind(active ? 1 : 0, Date.now(), userId).run();
12269
- await chunkK4Q4SFJJ_cjs.logActivity(
12319
+ await chunkDQZVU3WB_cjs.logActivity(
12270
12320
  db,
12271
12321
  user.userId,
12272
12322
  active ? "user.activate" : "user.deactivate",
@@ -12307,7 +12357,7 @@ userRoutes.delete("/users/:id", async (c) => {
12307
12357
  DELETE FROM users WHERE id = ?
12308
12358
  `);
12309
12359
  await deleteStmt.bind(userId).run();
12310
- await chunkK4Q4SFJJ_cjs.logActivity(
12360
+ await chunkDQZVU3WB_cjs.logActivity(
12311
12361
  db,
12312
12362
  user.userId,
12313
12363
  "user!.hard_delete",
@@ -12326,7 +12376,7 @@ userRoutes.delete("/users/:id", async (c) => {
12326
12376
  UPDATE users SET is_active = 0, updated_at = ? WHERE id = ?
12327
12377
  `);
12328
12378
  await deleteStmt.bind(Date.now(), userId).run();
12329
- await chunkK4Q4SFJJ_cjs.logActivity(
12379
+ await chunkDQZVU3WB_cjs.logActivity(
12330
12380
  db,
12331
12381
  user.userId,
12332
12382
  "user!.soft_delete",
@@ -12392,7 +12442,7 @@ userRoutes.post("/invite-user", async (c) => {
12392
12442
  Date.now(),
12393
12443
  Date.now()
12394
12444
  ).run();
12395
- await chunkK4Q4SFJJ_cjs.logActivity(
12445
+ await chunkDQZVU3WB_cjs.logActivity(
12396
12446
  db,
12397
12447
  user.userId,
12398
12448
  "user!.invite_sent",
@@ -12449,7 +12499,7 @@ userRoutes.post("/resend-invitation/:id", async (c) => {
12449
12499
  Date.now(),
12450
12500
  userId
12451
12501
  ).run();
12452
- await chunkK4Q4SFJJ_cjs.logActivity(
12502
+ await chunkDQZVU3WB_cjs.logActivity(
12453
12503
  db,
12454
12504
  user.userId,
12455
12505
  "user!.invitation_resent",
@@ -12485,7 +12535,7 @@ userRoutes.delete("/cancel-invitation/:id", async (c) => {
12485
12535
  }
12486
12536
  const deleteStmt = db.prepare(`DELETE FROM users WHERE id = ?`);
12487
12537
  await deleteStmt.bind(userId).run();
12488
- await chunkK4Q4SFJJ_cjs.logActivity(
12538
+ await chunkDQZVU3WB_cjs.logActivity(
12489
12539
  db,
12490
12540
  user.userId,
12491
12541
  "user!.invitation_cancelled",
@@ -12568,7 +12618,7 @@ userRoutes.get("/activity-logs", async (c) => {
12568
12618
  ...log,
12569
12619
  details: log.details ? JSON.parse(log.details) : null
12570
12620
  }));
12571
- await chunkK4Q4SFJJ_cjs.logActivity(
12621
+ await chunkDQZVU3WB_cjs.logActivity(
12572
12622
  db,
12573
12623
  user.userId,
12574
12624
  "activity.logs_viewed",
@@ -12675,7 +12725,7 @@ userRoutes.get("/activity-logs/export", async (c) => {
12675
12725
  csvRows.push(row.join(","));
12676
12726
  }
12677
12727
  const csvContent = csvRows.join("\n");
12678
- await chunkK4Q4SFJJ_cjs.logActivity(
12728
+ await chunkDQZVU3WB_cjs.logActivity(
12679
12729
  db,
12680
12730
  user.userId,
12681
12731
  "activity.logs_exported",
@@ -14014,7 +14064,7 @@ var fileValidationSchema2 = zod.z.object({
14014
14064
  // 50MB max
14015
14065
  });
14016
14066
  var adminMediaRoutes = new hono.Hono();
14017
- adminMediaRoutes.use("*", chunkK4Q4SFJJ_cjs.requireAuth());
14067
+ adminMediaRoutes.use("*", chunkDQZVU3WB_cjs.requireAuth());
14018
14068
  adminMediaRoutes.get("/", async (c) => {
14019
14069
  try {
14020
14070
  const user = c.get("user");
@@ -14600,7 +14650,7 @@ adminMediaRoutes.put("/:id", async (c) => {
14600
14650
  `);
14601
14651
  }
14602
14652
  });
14603
- adminMediaRoutes.delete("/cleanup", chunkK4Q4SFJJ_cjs.requireRole("admin"), async (c) => {
14653
+ adminMediaRoutes.delete("/cleanup", chunkDQZVU3WB_cjs.requireRole("admin"), async (c) => {
14604
14654
  try {
14605
14655
  const db = c.env.DB;
14606
14656
  const allMediaStmt = db.prepare("SELECT id, r2_key, filename FROM media WHERE deleted_at IS NULL");
@@ -16823,7 +16873,7 @@ function renderEmailSettingsContent(plugin, settings) {
16823
16873
 
16824
16874
  // src/routes/admin-plugins.ts
16825
16875
  var adminPluginRoutes = new hono.Hono();
16826
- adminPluginRoutes.use("*", chunkK4Q4SFJJ_cjs.requireAuth());
16876
+ adminPluginRoutes.use("*", chunkDQZVU3WB_cjs.requireAuth());
16827
16877
  var AVAILABLE_PLUGINS = [
16828
16878
  {
16829
16879
  id: "third-party-faq",
@@ -18228,11 +18278,11 @@ function renderLogConfigPage(data) {
18228
18278
 
18229
18279
  // src/routes/admin-logs.ts
18230
18280
  var adminLogsRoutes = new hono.Hono();
18231
- adminLogsRoutes.use("*", chunkK4Q4SFJJ_cjs.requireAuth());
18281
+ adminLogsRoutes.use("*", chunkDQZVU3WB_cjs.requireAuth());
18232
18282
  adminLogsRoutes.get("/", async (c) => {
18233
18283
  try {
18234
18284
  const user = c.get("user");
18235
- const logger = chunkVNLR35GO_cjs.getLogger(c.env.DB);
18285
+ const logger = chunk64APW3DW_cjs.getLogger(c.env.DB);
18236
18286
  const query = c.req.query();
18237
18287
  const page = parseInt(query.page || "1");
18238
18288
  const limit = parseInt(query.limit || "50");
@@ -18312,7 +18362,7 @@ adminLogsRoutes.get("/:id", async (c) => {
18312
18362
  try {
18313
18363
  const id = c.req.param("id");
18314
18364
  const user = c.get("user");
18315
- const logger = chunkVNLR35GO_cjs.getLogger(c.env.DB);
18365
+ const logger = chunk64APW3DW_cjs.getLogger(c.env.DB);
18316
18366
  const { logs } = await logger.getLogs({
18317
18367
  limit: 1,
18318
18368
  offset: 0,
@@ -18349,7 +18399,7 @@ adminLogsRoutes.get("/:id", async (c) => {
18349
18399
  adminLogsRoutes.get("/config", async (c) => {
18350
18400
  try {
18351
18401
  const user = c.get("user");
18352
- const logger = chunkVNLR35GO_cjs.getLogger(c.env.DB);
18402
+ const logger = chunk64APW3DW_cjs.getLogger(c.env.DB);
18353
18403
  const configs = await logger.getAllConfigs();
18354
18404
  const pageData = {
18355
18405
  configs,
@@ -18373,7 +18423,7 @@ adminLogsRoutes.post("/config/:category", async (c) => {
18373
18423
  const level = formData.get("level");
18374
18424
  const retention = parseInt(formData.get("retention"));
18375
18425
  const maxSize = parseInt(formData.get("max_size"));
18376
- const logger = chunkVNLR35GO_cjs.getLogger(c.env.DB);
18426
+ const logger = chunk64APW3DW_cjs.getLogger(c.env.DB);
18377
18427
  await logger.updateConfig(category, {
18378
18428
  enabled,
18379
18429
  level,
@@ -18402,7 +18452,7 @@ adminLogsRoutes.get("/export", async (c) => {
18402
18452
  const category = query.category;
18403
18453
  const startDate = query.start_date;
18404
18454
  const endDate = query.end_date;
18405
- const logger = chunkVNLR35GO_cjs.getLogger(c.env.DB);
18455
+ const logger = chunk64APW3DW_cjs.getLogger(c.env.DB);
18406
18456
  const filter = {
18407
18457
  limit: 1e4,
18408
18458
  // Export up to 10k logs
@@ -18483,7 +18533,7 @@ adminLogsRoutes.post("/cleanup", async (c) => {
18483
18533
  error: "Unauthorized. Admin access required."
18484
18534
  }, 403);
18485
18535
  }
18486
- const logger = chunkVNLR35GO_cjs.getLogger(c.env.DB);
18536
+ const logger = chunk64APW3DW_cjs.getLogger(c.env.DB);
18487
18537
  await logger.cleanupByRetention();
18488
18538
  return c.html(html.html`
18489
18539
  <div class="bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded">
@@ -18505,7 +18555,7 @@ adminLogsRoutes.post("/search", async (c) => {
18505
18555
  const search = formData.get("search");
18506
18556
  const level = formData.get("level");
18507
18557
  const category = formData.get("category");
18508
- const logger = chunkVNLR35GO_cjs.getLogger(c.env.DB);
18558
+ const logger = chunk64APW3DW_cjs.getLogger(c.env.DB);
18509
18559
  const filter = {
18510
18560
  limit: 20,
18511
18561
  offset: 0,
@@ -20556,9 +20606,9 @@ function renderStorageUsage(databaseSizeBytes, mediaSizeBytes) {
20556
20606
  }
20557
20607
 
20558
20608
  // src/routes/admin-dashboard.ts
20559
- var VERSION = chunkJDIM5AG7_cjs.getCoreVersion();
20609
+ var VERSION = chunkSHU7Q66Q_cjs.getCoreVersion();
20560
20610
  var router = new hono.Hono();
20561
- router.use("*", chunkK4Q4SFJJ_cjs.requireAuth());
20611
+ router.use("*", chunkDQZVU3WB_cjs.requireAuth());
20562
20612
  router.get("/", async (c) => {
20563
20613
  const user = c.get("user");
20564
20614
  try {
@@ -20782,6 +20832,20 @@ router.get("/system-status", async (c) => {
20782
20832
  }
20783
20833
  });
20784
20834
 
20835
+ // src/routes/admin-collections-field-types.ts
20836
+ function isMarkdownEditorType(fieldType) {
20837
+ return fieldType === "markdown" || fieldType === "mdxeditor" || fieldType === "easymde";
20838
+ }
20839
+ function normalizeFieldType(fieldType) {
20840
+ if (isMarkdownEditorType(fieldType)) {
20841
+ return "markdown";
20842
+ }
20843
+ if (fieldType === "tinymce") {
20844
+ return "richtext";
20845
+ }
20846
+ return fieldType;
20847
+ }
20848
+
20785
20849
  // src/templates/pages/admin-collections-list.template.ts
20786
20850
  chunkLTKV7AE5_cjs.init_admin_layout_catalyst_template();
20787
20851
 
@@ -21268,7 +21332,9 @@ function getFieldTypeBadge(fieldType) {
21268
21332
  "slug": "URL Slug",
21269
21333
  "richtext": "Rich Text (TinyMCE)",
21270
21334
  "quill": "Rich Text (Quill)",
21271
- "mdxeditor": "EasyMDX",
21335
+ "markdown": "Markdown",
21336
+ "mdxeditor": "Markdown",
21337
+ "easymde": "Markdown",
21272
21338
  "number": "Number",
21273
21339
  "boolean": "Boolean",
21274
21340
  "date": "Date",
@@ -21281,7 +21347,9 @@ function getFieldTypeBadge(fieldType) {
21281
21347
  "slug": "bg-sky-500/10 dark:bg-sky-400/10 text-sky-700 dark:text-sky-300 ring-sky-500/20 dark:ring-sky-400/20",
21282
21348
  "richtext": "bg-purple-500/10 dark:bg-purple-400/10 text-purple-700 dark:text-purple-300 ring-purple-500/20 dark:ring-purple-400/20",
21283
21349
  "quill": "bg-purple-500/10 dark:bg-purple-400/10 text-purple-700 dark:text-purple-300 ring-purple-500/20 dark:ring-purple-400/20",
21350
+ "markdown": "bg-purple-500/10 dark:bg-purple-400/10 text-purple-700 dark:text-purple-300 ring-purple-500/20 dark:ring-purple-400/20",
21284
21351
  "mdxeditor": "bg-purple-500/10 dark:bg-purple-400/10 text-purple-700 dark:text-purple-300 ring-purple-500/20 dark:ring-purple-400/20",
21352
+ "easymde": "bg-purple-500/10 dark:bg-purple-400/10 text-purple-700 dark:text-purple-300 ring-purple-500/20 dark:ring-purple-400/20",
21285
21353
  "number": "bg-green-500/10 dark:bg-green-400/10 text-green-700 dark:text-green-300 ring-green-500/20 dark:ring-green-400/20",
21286
21354
  "boolean": "bg-amber-500/10 dark:bg-amber-400/10 text-amber-700 dark:text-amber-300 ring-amber-500/20 dark:ring-amber-400/20",
21287
21355
  "date": "bg-cyan-500/10 dark:bg-cyan-400/10 text-cyan-700 dark:text-cyan-300 ring-cyan-500/20 dark:ring-cyan-400/20",
@@ -21762,7 +21830,7 @@ function renderCollectionFormPage(data) {
21762
21830
  <option value="slug">URL Slug</option>
21763
21831
  ${data.editorPlugins?.tinymce ? '<option value="richtext">Rich Text (TinyMCE)</option>' : ""}
21764
21832
  ${data.editorPlugins?.quill ? '<option value="quill">Rich Text (Quill)</option>' : ""}
21765
- ${data.editorPlugins?.easyMdx ? '<option value="mdxeditor">EasyMDX</option>' : ""}
21833
+ ${data.editorPlugins?.easyMdx ? '<option value="markdown">Markdown</option>' : ""}
21766
21834
  <option value="number">Number</option>
21767
21835
  <option value="boolean">Boolean</option>
21768
21836
  <option value="date">Date</option>
@@ -21987,7 +22055,7 @@ function renderCollectionFormPage(data) {
21987
22055
  // Check if it's a schema field with field_options that might indicate the actual type
21988
22056
  if (field.field_options && typeof field.field_options === 'object') {
21989
22057
  // Only convert to richtext if type is explicitly 'string' and format is richtext
21990
- // Don't convert if it's already a specific editor type like 'mdxeditor', 'quill', etc.
22058
+ // Don't convert if it's already a specific editor type like 'markdown', 'quill', etc.
21991
22059
  if (field.field_options.format === 'richtext' && uiFieldType === 'string') {
21992
22060
  uiFieldType = 'richtext';
21993
22061
  }
@@ -22008,6 +22076,12 @@ function renderCollectionFormPage(data) {
22008
22076
  uiFieldType = typeMapping[uiFieldType];
22009
22077
  }
22010
22078
 
22079
+ if (uiFieldType === 'mdxeditor' || uiFieldType === 'easymde') {
22080
+ uiFieldType = 'markdown';
22081
+ } else if (uiFieldType === 'tinymce') {
22082
+ uiFieldType = 'richtext';
22083
+ }
22084
+
22011
22085
  // Log all available options
22012
22086
  const availableOptions = Array.from(fieldTypeSelect.options).map(opt => ({ value: opt.value, text: opt.text }));
22013
22087
  console.log('Available dropdown options:', availableOptions);
@@ -22094,7 +22168,7 @@ function renderCollectionFormPage(data) {
22094
22168
 
22095
22169
  console.log('[Edit Field] Showing options for field type:', fieldType, '(original:', field.field_type, ')');
22096
22170
 
22097
- if (['select', 'radio', 'media', 'richtext', 'reference'].includes(fieldType)) {
22171
+ if (['select', 'radio', 'media', 'richtext', 'markdown', 'reference'].includes(fieldType)) {
22098
22172
  optionsContainer.classList.remove('hidden');
22099
22173
 
22100
22174
  // Set help text based on type
@@ -22111,6 +22185,9 @@ function renderCollectionFormPage(data) {
22111
22185
  case 'richtext':
22112
22186
  helpText.textContent = 'Full-featured WYSIWYG text editor with formatting options';
22113
22187
  break;
22188
+ case 'markdown':
22189
+ helpText.textContent = 'Markdown editor with live preview powered by the EasyMDE plugin';
22190
+ break;
22114
22191
  case 'reference':
22115
22192
  helpText.textContent = 'Link to content from other collections';
22116
22193
  break;
@@ -22251,7 +22328,7 @@ function renderCollectionFormPage(data) {
22251
22328
  const fieldNameInput = document.getElementById('modal-field-name');
22252
22329
 
22253
22330
  // Show/hide options based on field type
22254
- if (['select', 'radio', 'media', 'richtext', 'guid', 'reference'].includes(this.value)) {
22331
+ if (['select', 'radio', 'media', 'richtext', 'markdown', 'guid', 'reference'].includes(this.value)) {
22255
22332
  optionsContainer.classList.remove('hidden');
22256
22333
 
22257
22334
  // Set default options and help text based on type
@@ -22272,6 +22349,10 @@ function renderCollectionFormPage(data) {
22272
22349
  fieldOptions.value = '{"toolbar": "full", "height": 400}';
22273
22350
  helpText.textContent = 'Full-featured WYSIWYG text editor with formatting options';
22274
22351
  break;
22352
+ case 'markdown':
22353
+ fieldOptions.value = '{"toolbar": "full", "height": 400}';
22354
+ helpText.textContent = 'Markdown editor with live preview powered by the EasyMDE plugin';
22355
+ break;
22275
22356
  case 'reference':
22276
22357
  fieldOptions.value = '{"collection": ["pages", "posts"]}';
22277
22358
  helpText.textContent = 'Link to content from other collections';
@@ -22346,7 +22427,7 @@ function renderCollectionFormPage(data) {
22346
22427
 
22347
22428
  // src/routes/admin-collections.ts
22348
22429
  var adminCollectionsRoutes = new hono.Hono();
22349
- adminCollectionsRoutes.use("*", chunkK4Q4SFJJ_cjs.requireAuth());
22430
+ adminCollectionsRoutes.use("*", chunkDQZVU3WB_cjs.requireAuth());
22350
22431
  adminCollectionsRoutes.get("/", async (c) => {
22351
22432
  try {
22352
22433
  const user = c.get("user");
@@ -22832,11 +22913,12 @@ adminCollectionsRoutes.post("/:id/fields", async (c) => {
22832
22913
  searchable: isSearchable,
22833
22914
  ...parsedOptions
22834
22915
  };
22835
- if (fieldType === "richtext") {
22916
+ const normalizedFieldType = normalizeFieldType(fieldType);
22917
+ if (normalizedFieldType === "richtext") {
22836
22918
  fieldConfig.format = "richtext";
22837
- } else if (fieldType === "date") {
22919
+ } else if (normalizedFieldType === "date") {
22838
22920
  fieldConfig.format = "date-time";
22839
- } else if (fieldType === "select") {
22921
+ } else if (normalizedFieldType === "select") {
22840
22922
  fieldConfig.enum = parsedOptions.options || [];
22841
22923
  } else if (fieldType === "radio") {
22842
22924
  fieldConfig.type = "radio";
@@ -22845,20 +22927,14 @@ adminCollectionsRoutes.post("/:id/fields", async (c) => {
22845
22927
  }
22846
22928
  } else if (fieldType === "media") {
22847
22929
  fieldConfig.format = "media";
22848
- } else if (fieldType === "slug") {
22930
+ } else if (normalizedFieldType === "slug") {
22849
22931
  fieldConfig.type = "slug";
22850
22932
  fieldConfig.format = "slug";
22851
- } else if (fieldType === "quill") {
22933
+ } else if (normalizedFieldType === "quill") {
22852
22934
  fieldConfig.type = "quill";
22853
- } else if (fieldType === "mdxeditor") {
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") {
22935
+ } else if (normalizedFieldType === "markdown") {
22860
22936
  fieldConfig.type = "markdown";
22861
- } else if (fieldType === "reference") {
22937
+ } else if (normalizedFieldType === "reference") {
22862
22938
  fieldConfig.type = "reference";
22863
22939
  }
22864
22940
  schema.properties[fieldName] = fieldConfig;
@@ -24546,7 +24622,7 @@ function renderDatabaseToolsSettings(settings) {
24546
24622
 
24547
24623
  // src/routes/admin-settings.ts
24548
24624
  var adminSettingsRoutes = new hono.Hono();
24549
- adminSettingsRoutes.use("*", chunkK4Q4SFJJ_cjs.requireAuth());
24625
+ adminSettingsRoutes.use("*", chunkDQZVU3WB_cjs.requireAuth());
24550
24626
  function getMockSettings(user) {
24551
24627
  return {
24552
24628
  general: {
@@ -24611,7 +24687,7 @@ adminSettingsRoutes.get("/", (c) => {
24611
24687
  adminSettingsRoutes.get("/general", async (c) => {
24612
24688
  const user = c.get("user");
24613
24689
  const db = c.env.DB;
24614
- const settingsService = new chunkVNLR35GO_cjs.SettingsService(db);
24690
+ const settingsService = new chunk64APW3DW_cjs.SettingsService(db);
24615
24691
  const generalSettings = await settingsService.getGeneralSettings(user?.email);
24616
24692
  const mockSettings = getMockSettings(user);
24617
24693
  mockSettings.general = generalSettings;
@@ -24714,7 +24790,7 @@ adminSettingsRoutes.get("/database-tools", (c) => {
24714
24790
  adminSettingsRoutes.get("/api/migrations/status", async (c) => {
24715
24791
  try {
24716
24792
  const db = c.env.DB;
24717
- const migrationService = new chunkHXHVU5GM_cjs.MigrationService(db);
24793
+ const migrationService = new chunkLDFMYRG6_cjs.MigrationService(db);
24718
24794
  const status = await migrationService.getMigrationStatus();
24719
24795
  return c.json({
24720
24796
  success: true,
@@ -24738,7 +24814,7 @@ adminSettingsRoutes.post("/api/migrations/run", async (c) => {
24738
24814
  }, 403);
24739
24815
  }
24740
24816
  const db = c.env.DB;
24741
- const migrationService = new chunkHXHVU5GM_cjs.MigrationService(db);
24817
+ const migrationService = new chunkLDFMYRG6_cjs.MigrationService(db);
24742
24818
  const result = await migrationService.runPendingMigrations();
24743
24819
  return c.json({
24744
24820
  success: result.success,
@@ -24756,7 +24832,7 @@ adminSettingsRoutes.post("/api/migrations/run", async (c) => {
24756
24832
  adminSettingsRoutes.get("/api/migrations/validate", async (c) => {
24757
24833
  try {
24758
24834
  const db = c.env.DB;
24759
- const migrationService = new chunkHXHVU5GM_cjs.MigrationService(db);
24835
+ const migrationService = new chunkLDFMYRG6_cjs.MigrationService(db);
24760
24836
  const validation = await migrationService.validateSchema();
24761
24837
  return c.json({
24762
24838
  success: true,
@@ -24925,7 +25001,7 @@ adminSettingsRoutes.post("/general", async (c) => {
24925
25001
  }
24926
25002
  const formData = await c.req.formData();
24927
25003
  const db = c.env.DB;
24928
- const settingsService = new chunkVNLR35GO_cjs.SettingsService(db);
25004
+ const settingsService = new chunk64APW3DW_cjs.SettingsService(db);
24929
25005
  const settings = {
24930
25006
  siteName: formData.get("siteName"),
24931
25007
  siteDescription: formData.get("siteDescription"),
@@ -26646,7 +26722,7 @@ function renderFormCreatePage(data) {
26646
26722
 
26647
26723
  // src/routes/admin-forms.ts
26648
26724
  var adminFormsRoutes = new hono.Hono();
26649
- adminFormsRoutes.use("*", chunkK4Q4SFJJ_cjs.requireAuth());
26725
+ adminFormsRoutes.use("*", chunkDQZVU3WB_cjs.requireAuth());
26650
26726
  adminFormsRoutes.get("/", async (c) => {
26651
26727
  try {
26652
26728
  const user = c.get("user");
@@ -27463,6 +27539,33 @@ var public_forms_default = publicFormsRoutes;
27463
27539
 
27464
27540
  // src/templates/pages/admin-api-reference.template.ts
27465
27541
  chunkLTKV7AE5_cjs.init_admin_layout_catalyst_template();
27542
+ function renderAuthBadge(auth) {
27543
+ if (auth === true) {
27544
+ return `
27545
+ <span class="shrink-0 inline-flex items-center gap-x-1 rounded-md bg-amber-50 dark:bg-amber-500/10 px-2 py-1 text-xs font-medium text-amber-700 dark:text-amber-300 ring-1 ring-inset ring-amber-700/10 dark:ring-amber-400/20">
27546
+ <svg class="h-3 w-3" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2">
27547
+ <path stroke-linecap="round" stroke-linejoin="round" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"/>
27548
+ </svg>
27549
+ Auth
27550
+ </span>`;
27551
+ }
27552
+ if (auth === false) {
27553
+ return `
27554
+ <span class="shrink-0 inline-flex items-center gap-x-1 rounded-md bg-lime-50 dark:bg-lime-500/10 px-2 py-1 text-xs font-medium text-lime-700 dark:text-lime-300 ring-1 ring-inset ring-lime-700/10 dark:ring-lime-400/20">
27555
+ <svg class="h-3 w-3" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2">
27556
+ <path stroke-linecap="round" stroke-linejoin="round" d="M3.055 11H5a2 2 0 012 2v1a2 2 0 002 2 2 2 0 012 2v2.945M8 3.935V5.5A2.5 2.5 0 0010.5 8h.5a2 2 0 012 2 2 2 0 104 0 2 2 0 012-2h1.064M15 20.488V18a2 2 0 012-2h3.064M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
27557
+ </svg>
27558
+ Public
27559
+ </span>`;
27560
+ }
27561
+ return `
27562
+ <span class="shrink-0 inline-flex items-center gap-x-1 rounded-md bg-zinc-50 dark:bg-zinc-500/10 px-2 py-1 text-xs font-medium text-zinc-500 dark:text-zinc-400 ring-1 ring-inset ring-zinc-500/10 dark:ring-zinc-400/20">
27563
+ <svg class="h-3 w-3" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2">
27564
+ <path stroke-linecap="round" stroke-linejoin="round" d="M8.228 9c.549-1.165 2.03-2 3.772-2 2.21 0 4 1.343 4 3 0 1.4-1.278 2.575-3.006 2.907-.542.104-.994.54-.994 1.093m0 3h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
27565
+ </svg>
27566
+ Unknown
27567
+ </span>`;
27568
+ }
27466
27569
  function renderAPIReferencePage(data) {
27467
27570
  const endpointsByCategory = data.endpoints.reduce((acc, endpoint) => {
27468
27571
  if (!acc[endpoint.category]) {
@@ -27471,40 +27574,18 @@ function renderAPIReferencePage(data) {
27471
27574
  acc[endpoint.category].push(endpoint);
27472
27575
  return acc;
27473
27576
  }, {});
27474
- const categoryInfo = {
27475
- "Auth": {
27476
- title: "Authentication",
27477
- description: "User authentication and authorization endpoints",
27478
- icon: "\u{1F510}"
27479
- },
27480
- "Content": {
27481
- title: "Content Management",
27482
- description: "Content creation, retrieval, and management",
27483
- icon: "\u{1F4DD}"
27484
- },
27485
- "Media": {
27486
- title: "Media Management",
27487
- description: "File upload, storage, and media operations",
27488
- icon: "\u{1F5BC}\uFE0F"
27489
- },
27490
- "Admin": {
27491
- title: "Admin Interface",
27492
- description: "Administrative panel and management features",
27493
- icon: "\u2699\uFE0F"
27494
- },
27495
- "System": {
27496
- title: "System",
27497
- description: "Health checks and system information",
27498
- icon: "\u{1F527}"
27499
- }
27500
- };
27577
+ const categories = Object.keys(endpointsByCategory);
27578
+ const totalEndpoints = data.endpoints.length;
27579
+ const publicEndpoints = data.endpoints.filter((e) => e.authentication === false).length;
27580
+ const protectedEndpoints = data.endpoints.filter((e) => e.authentication === true).length;
27581
+ const undocumentedCount = data.endpoints.filter((e) => e.documented === false).length;
27501
27582
  const pageContent = `
27502
27583
  <div class="space-y-6">
27503
27584
  <!-- Header -->
27504
27585
  <div class="flex flex-col sm:flex-row sm:items-center sm:justify-between">
27505
27586
  <div>
27506
27587
  <h1 class="text-2xl/8 font-semibold text-zinc-950 dark:text-white sm:text-xl/8">API Reference</h1>
27507
- <p class="mt-2 text-sm/6 text-zinc-500 dark:text-zinc-400">Complete documentation of all available API endpoints</p>
27588
+ <p class="mt-2 text-sm/6 text-zinc-500 dark:text-zinc-400">Auto-discovered documentation of all registered API endpoints</p>
27508
27589
  </div>
27509
27590
  <div class="mt-4 sm:mt-0 sm:ml-16 sm:flex-none">
27510
27591
  <a href="/api" target="_blank" class="inline-flex items-center justify-center gap-x-1.5 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">
@@ -27517,29 +27598,35 @@ function renderAPIReferencePage(data) {
27517
27598
  </div>
27518
27599
 
27519
27600
  <!-- Stats -->
27520
- <dl class="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4">
27601
+ <dl class="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-5">
27521
27602
  <div class="rounded-lg bg-white dark:bg-zinc-900 shadow-sm ring-1 ring-zinc-950/5 dark:ring-white/10 px-6 py-5">
27522
27603
  <dt class="text-sm/6 font-medium text-zinc-500 dark:text-zinc-400">Total Endpoints</dt>
27523
27604
  <dd class="mt-2 flex items-baseline gap-x-2">
27524
- <span class="text-4xl font-semibold tracking-tight text-zinc-950 dark:text-white">${data.endpoints.length}</span>
27605
+ <span class="text-4xl font-semibold tracking-tight text-zinc-950 dark:text-white">${totalEndpoints}</span>
27525
27606
  </dd>
27526
27607
  </div>
27527
27608
  <div class="rounded-lg bg-white dark:bg-zinc-900 shadow-sm ring-1 ring-zinc-950/5 dark:ring-white/10 px-6 py-5">
27528
27609
  <dt class="text-sm/6 font-medium text-zinc-500 dark:text-zinc-400">Public Endpoints</dt>
27529
27610
  <dd class="mt-2 flex items-baseline gap-x-2">
27530
- <span class="text-4xl font-semibold tracking-tight text-lime-600 dark:text-lime-400">${data.endpoints.filter((e) => !e.authentication).length}</span>
27611
+ <span class="text-4xl font-semibold tracking-tight text-lime-600 dark:text-lime-400">${publicEndpoints}</span>
27531
27612
  </dd>
27532
27613
  </div>
27533
27614
  <div class="rounded-lg bg-white dark:bg-zinc-900 shadow-sm ring-1 ring-zinc-950/5 dark:ring-white/10 px-6 py-5">
27534
27615
  <dt class="text-sm/6 font-medium text-zinc-500 dark:text-zinc-400">Protected Endpoints</dt>
27535
27616
  <dd class="mt-2 flex items-baseline gap-x-2">
27536
- <span class="text-4xl font-semibold tracking-tight text-amber-600 dark:text-amber-400">${data.endpoints.filter((e) => e.authentication).length}</span>
27617
+ <span class="text-4xl font-semibold tracking-tight text-amber-600 dark:text-amber-400">${protectedEndpoints}</span>
27537
27618
  </dd>
27538
27619
  </div>
27539
27620
  <div class="rounded-lg bg-white dark:bg-zinc-900 shadow-sm ring-1 ring-zinc-950/5 dark:ring-white/10 px-6 py-5">
27540
27621
  <dt class="text-sm/6 font-medium text-zinc-500 dark:text-zinc-400">Categories</dt>
27541
27622
  <dd class="mt-2 flex items-baseline gap-x-2">
27542
- <span class="text-4xl font-semibold tracking-tight text-cyan-600 dark:text-cyan-400">${Object.keys(endpointsByCategory).length}</span>
27623
+ <span class="text-4xl font-semibold tracking-tight text-cyan-600 dark:text-cyan-400">${categories.length}</span>
27624
+ </dd>
27625
+ </div>
27626
+ <div class="rounded-lg bg-white dark:bg-zinc-900 shadow-sm ring-1 ring-zinc-950/5 dark:ring-white/10 px-6 py-5">
27627
+ <dt class="text-sm/6 font-medium text-zinc-500 dark:text-zinc-400">Undocumented</dt>
27628
+ <dd class="mt-2 flex items-baseline gap-x-2">
27629
+ <span class="text-4xl font-semibold tracking-tight ${undocumentedCount > 0 ? "text-zinc-400 dark:text-zinc-500" : "text-lime-600 dark:text-lime-400"}">${undocumentedCount}</span>
27543
27630
  </dd>
27544
27631
  </div>
27545
27632
  </dl>
@@ -27591,9 +27678,11 @@ function renderAPIReferencePage(data) {
27591
27678
  class="col-start-1 row-start-1 w-full appearance-none rounded-lg bg-white dark:bg-zinc-800 py-2 pl-3 pr-8 text-sm text-zinc-950 dark:text-white outline outline-1 -outline-offset-1 outline-zinc-950/10 dark:outline-white/10 *:bg-white dark:*:bg-zinc-800 focus:outline focus:outline-2 focus:-outline-offset-2 focus:outline-zinc-950 dark:focus:outline-white min-w-[200px]"
27592
27679
  >
27593
27680
  <option value="">All Categories</option>
27594
- ${Object.keys(categoryInfo).map((category) => `
27595
- <option value="${category}">${categoryInfo[category].title}</option>
27596
- `).join("")}
27681
+ ${categories.map((category) => {
27682
+ const info = chunk64APW3DW_cjs.CATEGORY_INFO[category];
27683
+ const title = info ? info.title : category;
27684
+ return `<option value="${category}">${title}</option>`;
27685
+ }).join("\n ")}
27597
27686
  </select>
27598
27687
  <svg viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" class="pointer-events-none col-start-1 row-start-1 mr-2 size-5 self-center justify-self-end text-zinc-500 dark:text-zinc-400 sm:size-4">
27599
27688
  <path d="M4.22 6.22a.75.75 0 0 1 1.06 0L8 8.94l2.72-2.72a.75.75 0 1 1 1.06 1.06l-3.25 3.25a.75.75 0 0 1-1.06 0L4.22 7.28a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd" fill-rule="evenodd" />
@@ -27607,7 +27696,7 @@ function renderAPIReferencePage(data) {
27607
27696
  <!-- API Categories -->
27608
27697
  <div class="space-y-6">
27609
27698
  ${Object.entries(endpointsByCategory).map(([category, endpoints]) => {
27610
- const info = categoryInfo[category] || { title: category, description: "", icon: "\u{1F4CB}" };
27699
+ const info = chunk64APW3DW_cjs.CATEGORY_INFO[category] || { title: category, description: "", icon: "&#x1f4cb;" };
27611
27700
  return `
27612
27701
  <div class="api-category" data-category="${category}">
27613
27702
  <div class="rounded-lg bg-white dark:bg-zinc-900 shadow-sm ring-1 ring-zinc-950/5 dark:ring-white/10 overflow-hidden">
@@ -27641,23 +27730,14 @@ function renderAPIReferencePage(data) {
27641
27730
  <div class="flex-1 min-w-0">
27642
27731
  <div class="flex items-center gap-x-2 mb-2">
27643
27732
  <code class="text-zinc-950 dark:text-white text-sm font-mono font-medium break-all">${endpoint.path}</code>
27644
- ${endpoint.authentication ? `
27645
- <span class="shrink-0 inline-flex items-center gap-x-1 rounded-md bg-amber-50 dark:bg-amber-500/10 px-2 py-1 text-xs font-medium text-amber-700 dark:text-amber-300 ring-1 ring-inset ring-amber-700/10 dark:ring-amber-400/20">
27646
- <svg class="h-3 w-3" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2">
27647
- <path stroke-linecap="round" stroke-linejoin="round" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"/>
27648
- </svg>
27649
- Auth
27650
- </span>
27651
- ` : `
27652
- <span class="shrink-0 inline-flex items-center gap-x-1 rounded-md bg-lime-50 dark:bg-lime-500/10 px-2 py-1 text-xs font-medium text-lime-700 dark:text-lime-300 ring-1 ring-inset ring-lime-700/10 dark:ring-lime-400/20">
27653
- <svg class="h-3 w-3" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2">
27654
- <path stroke-linecap="round" stroke-linejoin="round" d="M3.055 11H5a2 2 0 012 2v1a2 2 0 002 2 2 2 0 012 2v2.945M8 3.935V5.5A2.5 2.5 0 0010.5 8h.5a2 2 0 012 2 2 2 0 104 0 2 2 0 012-2h1.064M15 20.488V18a2 2 0 012-2h3.064M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
27655
- </svg>
27656
- Public
27733
+ ${renderAuthBadge(endpoint.authentication)}
27734
+ ${endpoint.documented === false ? `
27735
+ <span class="shrink-0 inline-flex items-center rounded-md bg-zinc-50 dark:bg-zinc-800 px-2 py-1 text-xs font-medium text-zinc-400 dark:text-zinc-500 ring-1 ring-inset ring-zinc-200 dark:ring-zinc-700">
27736
+ Auto-discovered
27657
27737
  </span>
27658
- `}
27738
+ ` : ""}
27659
27739
  </div>
27660
- <p class="text-zinc-600 dark:text-zinc-400 text-sm leading-6">${endpoint.description}</p>
27740
+ <p class="text-zinc-600 dark:text-zinc-400 text-sm leading-6">${endpoint.description || '<em class="text-zinc-400 dark:text-zinc-500">No description available</em>'}</p>
27661
27741
  </div>
27662
27742
  </div>
27663
27743
  </div>
@@ -27735,8 +27815,8 @@ function renderAPIReferencePage(data) {
27735
27815
  const path = endpoint.dataset.path.toLowerCase();
27736
27816
  const description = endpoint.dataset.description.toLowerCase();
27737
27817
 
27738
- const matchesSearch = !searchTerm ||
27739
- path.includes(searchTerm) ||
27818
+ const matchesSearch = !searchTerm ||
27819
+ path.includes(searchTerm) ||
27740
27820
  description.includes(searchTerm);
27741
27821
  const matchesMethod = !selectedMethod || method === selectedMethod;
27742
27822
 
@@ -27793,210 +27873,16 @@ function renderAPIReferencePage(data) {
27793
27873
  }
27794
27874
 
27795
27875
  // src/routes/admin-api-reference.ts
27796
- var VERSION2 = chunkJDIM5AG7_cjs.getCoreVersion();
27876
+ var VERSION2 = chunkSHU7Q66Q_cjs.getCoreVersion();
27797
27877
  var router2 = new hono.Hono();
27798
- router2.use("*", chunkK4Q4SFJJ_cjs.requireAuth());
27799
- var apiEndpoints = [
27800
- // Auth endpoints
27801
- {
27802
- method: "POST",
27803
- path: "/auth/login",
27804
- description: "Authenticate user with email and password",
27805
- authentication: false,
27806
- category: "Auth"
27807
- },
27808
- {
27809
- method: "POST",
27810
- path: "/auth/register",
27811
- description: "Register a new user account",
27812
- authentication: false,
27813
- category: "Auth"
27814
- },
27815
- {
27816
- method: "POST",
27817
- path: "/auth/logout",
27818
- description: "Log out the current user and invalidate session",
27819
- authentication: true,
27820
- category: "Auth"
27821
- },
27822
- {
27823
- method: "GET",
27824
- path: "/auth/me",
27825
- description: "Get current authenticated user information",
27826
- authentication: true,
27827
- category: "Auth"
27828
- },
27829
- {
27830
- method: "POST",
27831
- path: "/auth/refresh",
27832
- description: "Refresh authentication token",
27833
- authentication: true,
27834
- category: "Auth"
27835
- },
27836
- // Content endpoints
27837
- {
27838
- method: "GET",
27839
- path: "/api/collections",
27840
- description: "List all available collections",
27841
- authentication: false,
27842
- category: "Content"
27843
- },
27844
- {
27845
- method: "GET",
27846
- path: "/api/collections/:collection/content",
27847
- description: "Get all content items from a specific collection",
27848
- authentication: false,
27849
- category: "Content"
27850
- },
27851
- {
27852
- method: "GET",
27853
- path: "/api/content/:id",
27854
- description: "Get a specific content item by ID",
27855
- authentication: false,
27856
- category: "Content"
27857
- },
27858
- {
27859
- method: "POST",
27860
- path: "/api/content",
27861
- description: "Create a new content item",
27862
- authentication: true,
27863
- category: "Content"
27864
- },
27865
- {
27866
- method: "PUT",
27867
- path: "/api/content/:id",
27868
- description: "Update an existing content item",
27869
- authentication: true,
27870
- category: "Content"
27871
- },
27872
- {
27873
- method: "DELETE",
27874
- path: "/api/content/:id",
27875
- description: "Delete a content item",
27876
- authentication: true,
27877
- category: "Content"
27878
- },
27879
- // Media endpoints
27880
- {
27881
- method: "GET",
27882
- path: "/api/media",
27883
- description: "List all media files with pagination",
27884
- authentication: false,
27885
- category: "Media"
27886
- },
27887
- {
27888
- method: "GET",
27889
- path: "/api/media/:id",
27890
- description: "Get a specific media file by ID",
27891
- authentication: false,
27892
- category: "Media"
27893
- },
27894
- {
27895
- method: "POST",
27896
- path: "/api/media/upload",
27897
- description: "Upload a new media file to R2 storage",
27898
- authentication: true,
27899
- category: "Media"
27900
- },
27901
- {
27902
- method: "DELETE",
27903
- path: "/api/media/:id",
27904
- description: "Delete a media file from storage",
27905
- authentication: true,
27906
- category: "Media"
27907
- },
27908
- // Admin endpoints
27909
- {
27910
- method: "GET",
27911
- path: "/admin/api/stats",
27912
- description: "Get dashboard statistics (collections, content, media, users)",
27913
- authentication: true,
27914
- category: "Admin"
27915
- },
27916
- {
27917
- method: "GET",
27918
- path: "/admin/api/storage",
27919
- description: "Get storage usage information",
27920
- authentication: true,
27921
- category: "Admin"
27922
- },
27923
- {
27924
- method: "GET",
27925
- path: "/admin/api/activity",
27926
- description: "Get recent activity logs",
27927
- authentication: true,
27928
- category: "Admin"
27929
- },
27930
- {
27931
- method: "GET",
27932
- path: "/admin/api/collections",
27933
- description: "List all collections with field counts",
27934
- authentication: true,
27935
- category: "Admin"
27936
- },
27937
- {
27938
- method: "POST",
27939
- path: "/admin/api/collections",
27940
- description: "Create a new collection",
27941
- authentication: true,
27942
- category: "Admin"
27943
- },
27944
- {
27945
- method: "PATCH",
27946
- path: "/admin/api/collections/:id",
27947
- description: "Update an existing collection",
27948
- authentication: true,
27949
- category: "Admin"
27950
- },
27951
- {
27952
- method: "DELETE",
27953
- path: "/admin/api/collections/:id",
27954
- description: "Delete a collection (must be empty)",
27955
- authentication: true,
27956
- category: "Admin"
27957
- },
27958
- {
27959
- method: "GET",
27960
- path: "/admin/api/migrations/status",
27961
- description: "Get database migration status",
27962
- authentication: true,
27963
- category: "Admin"
27964
- },
27965
- {
27966
- method: "POST",
27967
- path: "/admin/api/migrations/run",
27968
- description: "Run pending database migrations",
27969
- authentication: true,
27970
- category: "Admin"
27971
- },
27972
- // System endpoints
27973
- {
27974
- method: "GET",
27975
- path: "/health",
27976
- description: "Health check endpoint for monitoring",
27977
- authentication: false,
27978
- category: "System"
27979
- },
27980
- {
27981
- method: "GET",
27982
- path: "/api/health",
27983
- description: "API health check with schema information",
27984
- authentication: false,
27985
- category: "System"
27986
- },
27987
- {
27988
- method: "GET",
27989
- path: "/api",
27990
- description: "API root - returns API information and OpenAPI spec",
27991
- authentication: false,
27992
- category: "System"
27993
- }
27994
- ];
27878
+ router2.use("*", chunkDQZVU3WB_cjs.requireAuth());
27995
27879
  router2.get("/", async (c) => {
27996
27880
  const user = c.get("user");
27997
27881
  try {
27882
+ const app2 = chunk64APW3DW_cjs.getAppInstance();
27883
+ const endpoints = chunk64APW3DW_cjs.buildRouteList(app2);
27998
27884
  const pageData = {
27999
- endpoints: apiEndpoints,
27885
+ endpoints,
28000
27886
  user: user ? {
28001
27887
  name: user.email.split("@")[0] || user.email,
28002
27888
  email: user.email,
@@ -28076,5 +27962,5 @@ exports.router = router;
28076
27962
  exports.router2 = router2;
28077
27963
  exports.test_cleanup_default = test_cleanup_default;
28078
27964
  exports.userRoutes = userRoutes;
28079
- //# sourceMappingURL=chunk-R4WR3VTN.cjs.map
28080
- //# sourceMappingURL=chunk-R4WR3VTN.cjs.map
27965
+ //# sourceMappingURL=chunk-KSB6FXOP.cjs.map
27966
+ //# sourceMappingURL=chunk-KSB6FXOP.cjs.map