@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.
- package/dist/{app-DnQ26Lho.d.cts → app-Ozl9agJG.d.cts} +1 -1
- package/dist/{app-DnQ26Lho.d.ts → app-Ozl9agJG.d.ts} +1 -1
- package/dist/{chunk-Y3VMEGY2.js → chunk-25YNV4RK.js} +3 -3
- package/dist/{chunk-Y3VMEGY2.js.map → chunk-25YNV4RK.js.map} +1 -1
- package/dist/{chunk-CH5UHZVM.js → chunk-2JGQKF7B.js} +184 -298
- package/dist/chunk-2JGQKF7B.js.map +1 -0
- package/dist/{chunk-5XAI2XUF.js → chunk-3FHMXGLF.js} +7 -5
- package/dist/chunk-3FHMXGLF.js.map +1 -0
- package/dist/{chunk-VNLR35GO.cjs → chunk-64APW3DW.cjs} +339 -2
- package/dist/chunk-64APW3DW.cjs.map +1 -0
- package/dist/{chunk-G44QUVNM.js → chunk-7JMMLHPQ.js} +337 -4
- package/dist/chunk-7JMMLHPQ.js.map +1 -0
- package/dist/chunk-CJYFSKH7.js +54 -54
- package/dist/chunk-CJYFSKH7.js.map +1 -1
- package/dist/{chunk-K4Q4SFJJ.cjs → chunk-DQZVU3WB.cjs} +4 -4
- package/dist/{chunk-K4Q4SFJJ.cjs.map → chunk-DQZVU3WB.cjs.map} +1 -1
- package/dist/{chunk-R4WR3VTN.cjs → chunk-KSB6FXOP.cjs} +285 -399
- package/dist/chunk-KSB6FXOP.cjs.map +1 -0
- package/dist/{chunk-HXHVU5GM.cjs → chunk-LDFMYRG6.cjs} +2 -2
- package/dist/{chunk-HXHVU5GM.cjs.map → chunk-LDFMYRG6.cjs.map} +1 -1
- package/dist/chunk-MNFY6DWY.cjs +54 -54
- package/dist/chunk-MNFY6DWY.cjs.map +1 -1
- package/dist/{chunk-JDIM5AG7.cjs → chunk-SHU7Q66Q.cjs} +7 -5
- package/dist/chunk-SHU7Q66Q.cjs.map +1 -0
- package/dist/{chunk-GTFMI24U.js → chunk-STTZVLY2.js} +2 -2
- package/dist/{chunk-GTFMI24U.js.map → chunk-STTZVLY2.js.map} +1 -1
- package/dist/{collection-config-i8EaAF7z.d.cts → collection-config-DckWhkdL.d.cts} +2 -2
- package/dist/{collection-config-i8EaAF7z.d.ts → collection-config-DckWhkdL.d.ts} +2 -2
- package/dist/{filter-bar.template-Daw8ZDoq.d.cts → filter-bar.template-DlVYMk-T.d.cts} +1 -1
- package/dist/{filter-bar.template-Daw8ZDoq.d.ts → filter-bar.template-DlVYMk-T.d.ts} +1 -1
- package/dist/index.cjs +128 -127
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -8
- package/dist/index.d.ts +8 -8
- package/dist/index.js +10 -9
- package/dist/index.js.map +1 -1
- package/dist/middleware.cjs +28 -28
- package/dist/middleware.d.cts +1 -1
- package/dist/middleware.d.ts +1 -1
- package/dist/middleware.js +2 -2
- package/dist/migrations-QQWGDWGB.cjs +13 -0
- package/dist/{migrations-7X4RPH7O.cjs.map → migrations-QQWGDWGB.cjs.map} +1 -1
- package/dist/migrations-SZSR3C3G.js +4 -0
- package/dist/{migrations-KHWFJ2HN.js.map → migrations-SZSR3C3G.js.map} +1 -1
- package/dist/{plugin-zvZpaiP5.d.cts → plugin-0Xogrln-.d.cts} +1 -1
- package/dist/{plugin-zvZpaiP5.d.ts → plugin-0Xogrln-.d.ts} +1 -1
- package/dist/{plugin-bootstrap-CJozpgmI.d.cts → plugin-bootstrap-BAz7NY0H.d.cts} +2 -2
- package/dist/{plugin-bootstrap-DU5VmuHZ.d.ts → plugin-bootstrap-Cz3-bj8X.d.ts} +2 -2
- package/dist/{plugin-manager-Baa6xXqB.d.ts → plugin-manager-Clf2gXwj.d.ts} +2 -2
- package/dist/{plugin-manager-vBal9Zip.d.cts → plugin-manager-GcIeb226.d.cts} +2 -2
- package/dist/plugins.d.cts +2 -2
- package/dist/plugins.d.ts +2 -2
- package/dist/routes.cjs +28 -28
- package/dist/routes.d.cts +1 -1
- package/dist/routes.d.ts +1 -1
- package/dist/routes.js +5 -5
- package/dist/services.cjs +30 -14
- package/dist/services.d.cts +29 -4
- package/dist/services.d.ts +29 -4
- package/dist/services.js +2 -2
- package/dist/{telemetry-UiD1i9GS.d.cts → telemetry-B9vIV4wh.d.cts} +1 -1
- package/dist/{telemetry-UiD1i9GS.d.ts → telemetry-B9vIV4wh.d.ts} +1 -1
- package/dist/templates.d.cts +1 -1
- package/dist/templates.d.ts +1 -1
- package/dist/types.d.cts +3 -3
- package/dist/types.d.ts +3 -3
- package/dist/utils.cjs +11 -11
- package/dist/utils.d.cts +3 -3
- package/dist/utils.d.ts +3 -3
- package/dist/utils.js +1 -1
- package/dist/{version-C_CXrN_T.d.cts → version-ChpccWQ1.d.cts} +1 -1
- package/dist/{version-C_CXrN_T.d.ts → version-ChpccWQ1.d.ts} +1 -1
- package/package.json +5 -3
- package/dist/chunk-5XAI2XUF.js.map +0 -1
- package/dist/chunk-CH5UHZVM.js.map +0 -1
- package/dist/chunk-G44QUVNM.js.map +0 -1
- package/dist/chunk-JDIM5AG7.cjs.map +0 -1
- package/dist/chunk-R4WR3VTN.cjs.map +0 -1
- package/dist/chunk-VNLR35GO.cjs.map +0 -1
- package/dist/migrations-7X4RPH7O.cjs +0 -13
- package/dist/migrations-KHWFJ2HN.js +0 -4
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
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
|
|
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
|
|
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("/",
|
|
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 =
|
|
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",
|
|
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 =
|
|
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",
|
|
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 =
|
|
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
|
|
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 =
|
|
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",
|
|
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 =
|
|
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
|
|
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 =
|
|
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",
|
|
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 =
|
|
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
|
|
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 =
|
|
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("*",
|
|
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("*",
|
|
1776
|
-
adminApiRoutes.use("*",
|
|
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-
|
|
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-
|
|
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-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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 =
|
|
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
|
|
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 (
|
|
2916
|
+
if (chunkDQZVU3WB_cjs.AuthManager.isLegacyHash(user.password_hash)) {
|
|
2917
2917
|
try {
|
|
2918
|
-
const newHash = await
|
|
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
|
|
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",
|
|
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",
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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 (
|
|
3149
|
+
if (chunkDQZVU3WB_cjs.AuthManager.isLegacyHash(user.password_hash)) {
|
|
3150
3150
|
try {
|
|
3151
|
-
const newHash = await
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
4869
|
+
} else if (isMarkdownEditorFieldType(field.field_type) && !pluginStatuses.mdxeditorEnabled) {
|
|
4852
4870
|
fallbackToTextarea = true;
|
|
4853
|
-
fallbackWarning = "\u26A0\uFE0F
|
|
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 =
|
|
8307
|
+
const blocksConfig = chunkSHU7Q66Q_cjs.getBlocksFieldConfig(field.field_options);
|
|
8252
8308
|
if (blocksConfig) {
|
|
8253
|
-
const parsed =
|
|
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("*",
|
|
8419
|
+
adminContentRoutes.use("*", chunkDQZVU3WB_cjs.requireAuth());
|
|
8364
8420
|
async function getCollectionFields(db, collectionId) {
|
|
8365
|
-
const cache =
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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",
|
|
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 =
|
|
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 =
|
|
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",
|
|
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("*",
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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("*",
|
|
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",
|
|
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("*",
|
|
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("*",
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
20609
|
+
var VERSION = chunkSHU7Q66Q_cjs.getCoreVersion();
|
|
20560
20610
|
var router = new hono.Hono();
|
|
20561
|
-
router.use("*",
|
|
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
|
-
"
|
|
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="
|
|
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 '
|
|
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("*",
|
|
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
|
-
|
|
22916
|
+
const normalizedFieldType = normalizeFieldType(fieldType);
|
|
22917
|
+
if (normalizedFieldType === "richtext") {
|
|
22836
22918
|
fieldConfig.format = "richtext";
|
|
22837
|
-
} else if (
|
|
22919
|
+
} else if (normalizedFieldType === "date") {
|
|
22838
22920
|
fieldConfig.format = "date-time";
|
|
22839
|
-
} else if (
|
|
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 (
|
|
22930
|
+
} else if (normalizedFieldType === "slug") {
|
|
22849
22931
|
fieldConfig.type = "slug";
|
|
22850
22932
|
fieldConfig.format = "slug";
|
|
22851
|
-
} else if (
|
|
22933
|
+
} else if (normalizedFieldType === "quill") {
|
|
22852
22934
|
fieldConfig.type = "quill";
|
|
22853
|
-
} else if (
|
|
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 (
|
|
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("*",
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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("*",
|
|
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
|
|
27475
|
-
|
|
27476
|
-
|
|
27477
|
-
|
|
27478
|
-
|
|
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">
|
|
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-
|
|
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">${
|
|
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">${
|
|
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">${
|
|
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">${
|
|
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
|
-
${
|
|
27595
|
-
|
|
27596
|
-
|
|
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 =
|
|
27699
|
+
const info = chunk64APW3DW_cjs.CATEGORY_INFO[category] || { title: category, description: "", icon: "📋" };
|
|
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
|
-
|
|
27646
|
-
|
|
27647
|
-
|
|
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 =
|
|
27876
|
+
var VERSION2 = chunkSHU7Q66Q_cjs.getCoreVersion();
|
|
27797
27877
|
var router2 = new hono.Hono();
|
|
27798
|
-
router2.use("*",
|
|
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
|
|
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-
|
|
28080
|
-
//# sourceMappingURL=chunk-
|
|
27965
|
+
//# sourceMappingURL=chunk-KSB6FXOP.cjs.map
|
|
27966
|
+
//# sourceMappingURL=chunk-KSB6FXOP.cjs.map
|