@kyro-cms/core 0.9.8 → 0.9.9

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 (67) hide show
  1. package/dist/api-handler-graphql.cjs +18 -13
  2. package/dist/api-handler-graphql.cjs.map +1 -1
  3. package/dist/api-handler-graphql.js +14 -9
  4. package/dist/api-handler-graphql.js.map +1 -1
  5. package/dist/api-handler-trpc.cjs +9 -9
  6. package/dist/api-handler-trpc.js +7 -7
  7. package/dist/api-handler.cjs +10 -10
  8. package/dist/api-handler.js +7 -7
  9. package/dist/{chunk-2GXALYKV.js → chunk-3AKCVYDB.js} +4 -109
  10. package/dist/chunk-3AKCVYDB.js.map +1 -0
  11. package/dist/{chunk-KGJRJ7CU.cjs → chunk-4OCMVGEY.cjs} +4 -110
  12. package/dist/chunk-4OCMVGEY.cjs.map +1 -0
  13. package/dist/{chunk-HA4MGAZJ.js → chunk-5RFGYEQ3.js} +109 -28
  14. package/dist/chunk-5RFGYEQ3.js.map +1 -0
  15. package/dist/chunk-5RPRLTTN.js +861 -0
  16. package/dist/chunk-5RPRLTTN.js.map +1 -0
  17. package/dist/{chunk-EQTMBMDR.js → chunk-BVUDFKKS.js} +16 -3
  18. package/dist/chunk-BVUDFKKS.js.map +1 -0
  19. package/dist/{chunk-OVZO4KB6.cjs → chunk-E4JZ73FY.cjs} +34 -25
  20. package/dist/chunk-E4JZ73FY.cjs.map +1 -0
  21. package/dist/{chunk-2CBCU5ML.cjs → chunk-IEIHABVR.cjs} +129 -48
  22. package/dist/chunk-IEIHABVR.cjs.map +1 -0
  23. package/dist/{chunk-Z7OH3MWT.cjs → chunk-LNTFRAHF.cjs} +110 -2
  24. package/dist/chunk-LNTFRAHF.cjs.map +1 -0
  25. package/dist/chunk-N4GN6Q3V.cjs +869 -0
  26. package/dist/chunk-N4GN6Q3V.cjs.map +1 -0
  27. package/dist/{chunk-65DSXNQL.js → chunk-OX6GOIPH.js} +4 -4
  28. package/dist/{chunk-65DSXNQL.js.map → chunk-OX6GOIPH.js.map} +1 -1
  29. package/dist/{chunk-PJ7F4TCC.cjs → chunk-OXYSOU6Z.cjs} +18 -5
  30. package/dist/chunk-OXYSOU6Z.cjs.map +1 -0
  31. package/dist/{chunk-ZFHTJ2YX.js → chunk-OYCICW4B.js} +16 -7
  32. package/dist/chunk-OYCICW4B.js.map +1 -0
  33. package/dist/{chunk-W3GT55TY.cjs → chunk-TQG7G7YI.cjs} +13 -13
  34. package/dist/{chunk-W3GT55TY.cjs.map → chunk-TQG7G7YI.cjs.map} +1 -1
  35. package/dist/{chunk-2Z7YAJBS.js → chunk-WDTTHKDS.js} +109 -3
  36. package/dist/chunk-WDTTHKDS.js.map +1 -0
  37. package/dist/cli/index.cjs +148 -14
  38. package/dist/cli/index.cjs.map +1 -1
  39. package/dist/cli/index.js +148 -14
  40. package/dist/cli/index.js.map +1 -1
  41. package/dist/graphql/index.cjs +7 -7
  42. package/dist/graphql/index.d.cts +21 -13
  43. package/dist/graphql/index.d.ts +21 -13
  44. package/dist/graphql/index.js +2 -2
  45. package/dist/index.cjs +70 -70
  46. package/dist/index.d.cts +6 -5
  47. package/dist/index.d.ts +6 -5
  48. package/dist/index.js +7 -7
  49. package/dist/rest/index.cjs +5 -5
  50. package/dist/rest/index.js +3 -3
  51. package/dist/trpc/index.cjs +12 -12
  52. package/dist/trpc/index.js +3 -3
  53. package/package.json +1 -1
  54. package/dist/chunk-2CBCU5ML.cjs.map +0 -1
  55. package/dist/chunk-2GXALYKV.js.map +0 -1
  56. package/dist/chunk-2Z7YAJBS.js.map +0 -1
  57. package/dist/chunk-6DURKQ6W.js +0 -1072
  58. package/dist/chunk-6DURKQ6W.js.map +0 -1
  59. package/dist/chunk-EQTMBMDR.js.map +0 -1
  60. package/dist/chunk-HA4MGAZJ.js.map +0 -1
  61. package/dist/chunk-KGJRJ7CU.cjs.map +0 -1
  62. package/dist/chunk-OVZO4KB6.cjs.map +0 -1
  63. package/dist/chunk-PF642V5O.cjs +0 -1080
  64. package/dist/chunk-PF642V5O.cjs.map +0 -1
  65. package/dist/chunk-PJ7F4TCC.cjs.map +0 -1
  66. package/dist/chunk-Z7OH3MWT.cjs.map +0 -1
  67. package/dist/chunk-ZFHTJ2YX.js.map +0 -1
@@ -4,8 +4,8 @@ var chunkY7AQK4R4_cjs = require('./chunk-Y7AQK4R4.cjs');
4
4
  var chunkKC2GDBLS_cjs = require('./chunk-KC2GDBLS.cjs');
5
5
  var chunkIDVRRRAK_cjs = require('./chunk-IDVRRRAK.cjs');
6
6
  var chunkADLJSJSN_cjs = require('./chunk-ADLJSJSN.cjs');
7
- var chunkZ7OH3MWT_cjs = require('./chunk-Z7OH3MWT.cjs');
8
- var chunkKGJRJ7CU_cjs = require('./chunk-KGJRJ7CU.cjs');
7
+ var chunkLNTFRAHF_cjs = require('./chunk-LNTFRAHF.cjs');
8
+ var chunk4OCMVGEY_cjs = require('./chunk-4OCMVGEY.cjs');
9
9
  var chunkRFFSZSCL_cjs = require('./chunk-RFFSZSCL.cjs');
10
10
  var chunk7OS7TX2Q_cjs = require('./chunk-7OS7TX2Q.cjs');
11
11
  var chunkQ23GAMLE_cjs = require('./chunk-Q23GAMLE.cjs');
@@ -391,14 +391,14 @@ function createAuthMiddleware(config) {
391
391
  userLookup
392
392
  } = config;
393
393
  return async function authMiddleware(req) {
394
- const apiKeyRaw = chunkKGJRJ7CU_cjs.extractApiKeyFromRequest(req);
394
+ const apiKeyRaw = chunk4OCMVGEY_cjs.extractApiKeyFromRequest(req);
395
395
  if (apiKeyRaw && db) {
396
- const result = await chunkKGJRJ7CU_cjs.validateApiKey(apiKeyRaw, db, userLookup);
396
+ const result = await chunk4OCMVGEY_cjs.validateApiKey(apiKeyRaw, db, userLookup);
397
397
  if (result.valid && result.user) {
398
398
  return {
399
399
  user: result.user,
400
400
  tenantContext: createTenantContextFromUser(result.user),
401
- apiKeyContext: chunkKGJRJ7CU_cjs.createApiKeyContext(result),
401
+ apiKeyContext: chunk4OCMVGEY_cjs.createApiKeyContext(result),
402
402
  status: 200,
403
403
  authType: "apikey"
404
404
  };
@@ -2958,7 +2958,7 @@ var MediaService = class _MediaService {
2958
2958
  const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
2959
2959
  return { where, params: p, orderBy: sortDir, sortCol };
2960
2960
  }
2961
- rowToMedia(row) {
2961
+ rowToMedia(row, origin) {
2962
2962
  return {
2963
2963
  id: row.id,
2964
2964
  filename: row.filename,
@@ -2968,8 +2968,8 @@ var MediaService = class _MediaService {
2968
2968
  fileSize: row.file_size ?? row.fileSize,
2969
2969
  width: row.width ?? null,
2970
2970
  height: row.height ?? null,
2971
- url: row.url,
2972
- thumbnailUrl: row.thumbnail_url ?? row.thumbnailUrl ?? null,
2971
+ url: _MediaService.resolveMediaUrl(row.url, origin),
2972
+ thumbnailUrl: _MediaService.resolveMediaUrl(row.thumbnail_url ?? row.thumbnailUrl ?? null, origin),
2973
2973
  folder: row.folder ?? null,
2974
2974
  provider: row.provider,
2975
2975
  alt: row.alt ?? null,
@@ -2979,6 +2979,12 @@ var MediaService = class _MediaService {
2979
2979
  updatedAt: row.updated_at ?? row.updatedAt
2980
2980
  };
2981
2981
  }
2982
+ static resolveMediaUrl(url, origin) {
2983
+ if (!url) return null;
2984
+ if (url.startsWith("http://") || url.startsWith("https://") || url.startsWith("blob:") || url.startsWith("data:")) return url;
2985
+ const base = (process.env.KYRO_BASE_URL || origin || "http://localhost:4321").replace(/\/+$/, "");
2986
+ return `${base}${url.startsWith("/") ? "" : "/"}${url}`;
2987
+ }
2982
2988
  async sqliteRun(sql, params = []) {
2983
2989
  const stmt = this.db.prepare(sql);
2984
2990
  const sqlLower = sql.trim().toLowerCase();
@@ -3106,17 +3112,19 @@ var MediaService = class _MediaService {
3106
3112
  const file = new File([blob], originalName, { type: mimeType });
3107
3113
  return this.upload(file, folder);
3108
3114
  }
3109
- async delete(id) {
3115
+ async delete(id, origin) {
3110
3116
  let item = null;
3111
3117
  if (this.dialect === "sqlite") {
3112
- item = this.sqliteGet(`SELECT * FROM ${this.mediaTable} WHERE id = ?`, [
3113
- id
3114
- ]);
3118
+ const row = this.sqliteGet(
3119
+ `SELECT * FROM ${this.mediaTable} WHERE id = ?`,
3120
+ [id]
3121
+ );
3122
+ if (row) item = this.rowToMedia(row, origin);
3115
3123
  } else {
3116
3124
  const { media: mediaSchema } = await import('./media-TUSLVRQ6.cjs');
3117
3125
  const { eq } = await import('drizzle-orm');
3118
3126
  const [row] = await this.db.select().from(mediaSchema).where(eq(mediaSchema.id, id));
3119
- if (row) item = this.rowToMedia(row);
3127
+ if (row) item = this.rowToMedia(row, origin);
3120
3128
  }
3121
3129
  if (!item) return;
3122
3130
  await this.deleteFile(item.url);
@@ -3137,7 +3145,7 @@ var MediaService = class _MediaService {
3137
3145
  async deleteFile(url) {
3138
3146
  await this.storage.delete(url);
3139
3147
  }
3140
- async rename(id, newKey) {
3148
+ async rename(id, newKey, origin) {
3141
3149
  let item = null;
3142
3150
  if (this.dialect === "sqlite") {
3143
3151
  item = this.sqliteGet(`SELECT * FROM ${this.mediaTable} WHERE id = ?`, [
@@ -3147,7 +3155,7 @@ var MediaService = class _MediaService {
3147
3155
  const { media: mediaSchema } = await import('./media-TUSLVRQ6.cjs');
3148
3156
  const { eq } = await import('drizzle-orm');
3149
3157
  const [row] = await this.db.select().from(mediaSchema).where(eq(mediaSchema.id, id));
3150
- if (row) item = this.rowToMedia(row);
3158
+ if (row) item = this.rowToMedia(row, origin);
3151
3159
  }
3152
3160
  if (!item) return null;
3153
3161
  const newUrl = await this.storage.rename(item.url, newKey);
@@ -3190,20 +3198,20 @@ var MediaService = class _MediaService {
3190
3198
  thumbnailUrl: updateData.thumbnailUrl ?? null
3191
3199
  };
3192
3200
  }
3193
- async findById(id) {
3201
+ async findById(id, origin) {
3194
3202
  if (this.dialect === "sqlite") {
3195
3203
  const row2 = this.sqliteGet(
3196
3204
  `SELECT * FROM ${this.mediaTable} WHERE id = ?`,
3197
3205
  [id]
3198
3206
  );
3199
- return row2 ? this.rowToMedia(row2) : null;
3207
+ return row2 ? this.rowToMedia(row2, origin) : null;
3200
3208
  }
3201
3209
  const { media: mediaSchema } = await import('./media-TUSLVRQ6.cjs');
3202
3210
  const { eq } = await import('drizzle-orm');
3203
3211
  const [row] = await this.db.select().from(mediaSchema).where(eq(mediaSchema.id, id));
3204
- return row ? this.rowToMedia(row) : null;
3212
+ return row ? this.rowToMedia(row, origin) : null;
3205
3213
  }
3206
- async find(params = {}) {
3214
+ async find(params = {}, origin) {
3207
3215
  const {
3208
3216
  page = 1,
3209
3217
  limit = 30,
@@ -3239,7 +3247,7 @@ var MediaService = class _MediaService {
3239
3247
  [...p, limit, offset]
3240
3248
  );
3241
3249
  return {
3242
- docs: rows.map((r) => this.rowToMedia(r)),
3250
+ docs: rows.map((r) => this.rowToMedia(r, origin)),
3243
3251
  totalDocs: totalDocs2,
3244
3252
  page,
3245
3253
  limit,
@@ -3286,14 +3294,14 @@ var MediaService = class _MediaService {
3286
3294
  const [{ count }] = await this.db.select({ count: sql`count(*)` }).from(mediaSchema).where(whereClause);
3287
3295
  const totalDocs = Number(count);
3288
3296
  return {
3289
- docs: docs.map((r) => this.rowToMedia(r)),
3297
+ docs: docs.map((r) => this.rowToMedia(r, origin)),
3290
3298
  totalDocs,
3291
3299
  page,
3292
3300
  limit,
3293
3301
  totalPages: Math.ceil(totalDocs / limit)
3294
3302
  };
3295
3303
  }
3296
- async update(id, data) {
3304
+ async update(id, data, origin) {
3297
3305
  const now = this.now();
3298
3306
  if (this.dialect === "sqlite") {
3299
3307
  const sets = ["updated_at = ?"];
@@ -3312,7 +3320,7 @@ var MediaService = class _MediaService {
3312
3320
  }
3313
3321
  if (data.folder !== void 0) {
3314
3322
  sets.push("folder = ?");
3315
- p.push(data.folder || null);
3323
+ p.push(data.folder);
3316
3324
  }
3317
3325
  p.push(id);
3318
3326
  await this.sqliteRun(
@@ -3323,12 +3331,12 @@ var MediaService = class _MediaService {
3323
3331
  `SELECT * FROM ${this.mediaTable} WHERE id = ?`,
3324
3332
  [id]
3325
3333
  );
3326
- return row ? this.rowToMedia(row) : null;
3334
+ return row ? this.rowToMedia(row, origin) : null;
3327
3335
  }
3328
3336
  const { media: mediaSchema } = await import('./media-TUSLVRQ6.cjs');
3329
3337
  const { eq } = await import('drizzle-orm');
3330
3338
  const [updated] = await this.db.update(mediaSchema).set({ ...data, updatedAt: /* @__PURE__ */ new Date() }).where(eq(mediaSchema.id, id)).returning();
3331
- return updated ? this.rowToMedia(updated) : null;
3339
+ return updated ? this.rowToMedia(updated, origin) : null;
3332
3340
  }
3333
3341
  async updateMany(ids, data) {
3334
3342
  const now = this.now();
@@ -3485,9 +3493,9 @@ function convertRichtextFields(fields, data) {
3485
3493
  }
3486
3494
  var COLLECTION_EVENT_MAP = {
3487
3495
  _media: {
3488
- create: chunkZ7OH3MWT_cjs.WEBHOOK_EVENTS.MEDIA_UPLOAD,
3489
- update: chunkZ7OH3MWT_cjs.WEBHOOK_EVENTS.MEDIA_UPLOAD,
3490
- delete: chunkZ7OH3MWT_cjs.WEBHOOK_EVENTS.MEDIA_DELETE
3496
+ create: chunkLNTFRAHF_cjs.WEBHOOK_EVENTS.MEDIA_UPLOAD,
3497
+ update: chunkLNTFRAHF_cjs.WEBHOOK_EVENTS.MEDIA_UPLOAD,
3498
+ delete: chunkLNTFRAHF_cjs.WEBHOOK_EVENTS.MEDIA_DELETE
3491
3499
  }
3492
3500
  };
3493
3501
  function getWebhookEvent(collection, operation) {
@@ -3535,7 +3543,7 @@ function buildConflictResponse(expectedUpdatedAt, currentDoc) {
3535
3543
  };
3536
3544
  }
3537
3545
  async function checkCollectionAccess2(collection, operation, req, ctxUser, ctxTenantID, apiKeyContext, enablePublicAccess = true, defaultCollectionAccess = "none") {
3538
- const result = await chunkKGJRJ7CU_cjs.checkCollectionAccess(collection, operation, {
3546
+ const result = await chunkLNTFRAHF_cjs.checkCollectionAccess(collection, operation, {
3539
3547
  user: ctxUser,
3540
3548
  req,
3541
3549
  tenantID: ctxTenantID,
@@ -3547,7 +3555,7 @@ async function checkCollectionAccess2(collection, operation, req, ctxUser, ctxTe
3547
3555
  return result;
3548
3556
  }
3549
3557
  async function checkGlobalAccess2(global, operation, req, ctxUser, ctxTenantID, enablePublicAccess = true) {
3550
- const result = await chunkKGJRJ7CU_cjs.checkGlobalAccess(global, operation, {
3558
+ const result = await chunkLNTFRAHF_cjs.checkGlobalAccess(global, operation, {
3551
3559
  user: ctxUser,
3552
3560
  req,
3553
3561
  tenantID: ctxTenantID
@@ -4115,12 +4123,13 @@ function createHonoApp(options) {
4115
4123
  const { user: ctxUser } = await resolveAuthContext(c.req.raw, authMw, user, tenantID);
4116
4124
  if (!ctxUser) return c.json({ error: "Authentication required" }, 401);
4117
4125
  const service = await getMedia();
4126
+ const origin = new URL(c.req.url).origin;
4118
4127
  const page = parseInt(c.req.query("page") || "1");
4119
4128
  const limit = parseInt(c.req.query("limit") || "30");
4120
4129
  const search = c.req.query("search") || "";
4121
4130
  const type = c.req.query("type") || "";
4122
4131
  const folder = c.req.query("folder") || "";
4123
- const result = await service.find({ page, limit, search, type, folder });
4132
+ const result = await service.find({ page, limit, search, type, folder }, origin);
4124
4133
  return c.json(result);
4125
4134
  } catch (error) {
4126
4135
  console.error("[Media] find error:", error);
@@ -4204,7 +4213,8 @@ function createHonoApp(options) {
4204
4213
  if (!ctxUser) return c.json({ error: "Authentication required" }, 401);
4205
4214
  const service = await getMedia();
4206
4215
  const id = c.req.param("id");
4207
- await service.delete(id);
4216
+ const origin = new URL(c.req.url).origin;
4217
+ await service.delete(id, origin);
4208
4218
  return c.json({ success: true });
4209
4219
  } catch (error) {
4210
4220
  console.error("[Media] delete error:", error);
@@ -4260,7 +4270,8 @@ function createHonoApp(options) {
4260
4270
  if (!ctxUser) return c.json({ error: "Authentication required" }, 401);
4261
4271
  const service = await getMedia();
4262
4272
  const id = c.req.param("id");
4263
- const doc = await service.findById(id);
4273
+ const origin = new URL(c.req.url).origin;
4274
+ const doc = await service.findById(id, origin);
4264
4275
  if (!doc) return c.json({ error: "Media not found" }, 404);
4265
4276
  return c.json(doc);
4266
4277
  } catch (error) {
@@ -4275,8 +4286,9 @@ function createHonoApp(options) {
4275
4286
  const service = await getMedia();
4276
4287
  const id = c.req.param("id");
4277
4288
  const body = await c.req.json();
4289
+ const origin = new URL(c.req.url).origin;
4278
4290
  if (body.folder !== void 0) {
4279
- const updated = await service.update(id, { folder: body.folder });
4291
+ const updated = await service.update(id, { folder: body.folder }, origin);
4280
4292
  return c.json({ doc: updated });
4281
4293
  }
4282
4294
  return c.json({ error: "No valid fields to update" }, 400);
@@ -4782,7 +4794,7 @@ function createHonoApp(options) {
4782
4794
  }
4783
4795
  const page = parseInt(c.req.query("page") || "1");
4784
4796
  const limit = Math.min(parseInt(c.req.query("limit") || "50"), 100);
4785
- const result = await db.find({ collection: chunkKGJRJ7CU_cjs.API_KEY_COLLECTION, where: {}, page, limit, tenantID: ctxTenantID });
4797
+ const result = await db.find({ collection: chunk4OCMVGEY_cjs.API_KEY_COLLECTION, where: {}, page, limit, tenantID: ctxTenantID });
4786
4798
  const docs = (result.docs || []).map((doc) => ({
4787
4799
  id: doc.id,
4788
4800
  name: doc.name,
@@ -4807,14 +4819,14 @@ function createHonoApp(options) {
4807
4819
  if (!body.name || typeof body.name !== "string") {
4808
4820
  return c.json({ error: "name is required" }, 400);
4809
4821
  }
4810
- const rawKey = chunkKGJRJ7CU_cjs.generateApiKey();
4822
+ const rawKey = chunk4OCMVGEY_cjs.generateApiKey();
4811
4823
  const doc = await db.create({
4812
- collection: chunkKGJRJ7CU_cjs.API_KEY_COLLECTION,
4824
+ collection: chunk4OCMVGEY_cjs.API_KEY_COLLECTION,
4813
4825
  data: {
4814
4826
  userId: ctxUser.id,
4815
4827
  name: body.name,
4816
4828
  key: rawKey,
4817
- keyPrefix: chunkKGJRJ7CU_cjs.generateApiKeyPrefix(rawKey),
4829
+ keyPrefix: chunk4OCMVGEY_cjs.generateApiKeyPrefix(rawKey),
4818
4830
  permissions: Array.isArray(body.permissions) ? body.permissions : ["*"],
4819
4831
  expiresAt: body.expiresAt || null,
4820
4832
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
@@ -4845,9 +4857,9 @@ function createHonoApp(options) {
4845
4857
  return c.json({ error: "Forbidden" }, 403);
4846
4858
  }
4847
4859
  const id = c.req.param("id");
4848
- const existing = await db.findByID({ collection: chunkKGJRJ7CU_cjs.API_KEY_COLLECTION, id });
4860
+ const existing = await db.findByID({ collection: chunk4OCMVGEY_cjs.API_KEY_COLLECTION, id });
4849
4861
  if (!existing) return c.json({ error: "API key not found" }, 404);
4850
- await db.delete({ collection: chunkKGJRJ7CU_cjs.API_KEY_COLLECTION, id });
4862
+ await db.delete({ collection: chunk4OCMVGEY_cjs.API_KEY_COLLECTION, id });
4851
4863
  await sessionAuthAdapter?.createAuditLog({
4852
4864
  action: "api_key_delete",
4853
4865
  userId: ctxUser.id,
@@ -4870,14 +4882,14 @@ function createHonoApp(options) {
4870
4882
  }
4871
4883
  const id = c.req.param("id");
4872
4884
  const body = await c.req.json();
4873
- const existing = await db.findByID({ collection: chunkKGJRJ7CU_cjs.API_KEY_COLLECTION, id });
4885
+ const existing = await db.findByID({ collection: chunk4OCMVGEY_cjs.API_KEY_COLLECTION, id });
4874
4886
  if (!existing) return c.json({ error: "API key not found" }, 404);
4875
4887
  const updateData = {};
4876
4888
  if (typeof body.name === "string" && body.name.trim()) updateData.name = body.name.trim();
4877
4889
  if (Array.isArray(body.permissions)) updateData.permissions = body.permissions;
4878
4890
  if (body.expiresAt !== void 0) updateData.expiresAt = body.expiresAt || null;
4879
4891
  if (Object.keys(updateData).length === 0) return c.json({ error: "Nothing to update" }, 400);
4880
- const updated = await db.update({ collection: chunkKGJRJ7CU_cjs.API_KEY_COLLECTION, id, data: updateData });
4892
+ const updated = await db.update({ collection: chunk4OCMVGEY_cjs.API_KEY_COLLECTION, id, data: updateData });
4881
4893
  return c.json({ ...updated, keyPrefix: existing.keyPrefix });
4882
4894
  } catch (error) {
4883
4895
  console.error("[ApiKeys] PATCH error:", error);
@@ -4891,15 +4903,15 @@ function createHonoApp(options) {
4891
4903
  return c.json({ error: "Forbidden" }, 403);
4892
4904
  }
4893
4905
  const id = c.req.param("id");
4894
- const existing = await db.findByID({ collection: chunkKGJRJ7CU_cjs.API_KEY_COLLECTION, id });
4906
+ const existing = await db.findByID({ collection: chunk4OCMVGEY_cjs.API_KEY_COLLECTION, id });
4895
4907
  if (!existing) return c.json({ error: "API key not found" }, 404);
4896
- const rawKey = chunkKGJRJ7CU_cjs.generateApiKey();
4908
+ const rawKey = chunk4OCMVGEY_cjs.generateApiKey();
4897
4909
  const updated = await db.update({
4898
- collection: chunkKGJRJ7CU_cjs.API_KEY_COLLECTION,
4910
+ collection: chunk4OCMVGEY_cjs.API_KEY_COLLECTION,
4899
4911
  id,
4900
4912
  data: {
4901
4913
  key: rawKey,
4902
- keyPrefix: chunkKGJRJ7CU_cjs.generateApiKeyPrefix(rawKey),
4914
+ keyPrefix: chunk4OCMVGEY_cjs.generateApiKeyPrefix(rawKey),
4903
4915
  lastUsedAt: null
4904
4916
  }
4905
4917
  });
@@ -5057,6 +5069,75 @@ function createHonoApp(options) {
5057
5069
  return c.json({ error: error.message }, 500);
5058
5070
  }
5059
5071
  });
5072
+ function serializeField(field) {
5073
+ const safe = {};
5074
+ const keys = [
5075
+ "name",
5076
+ "type",
5077
+ "required",
5078
+ "hasMany",
5079
+ "relationTo",
5080
+ "options",
5081
+ "min",
5082
+ "max",
5083
+ "minLength",
5084
+ "maxLength",
5085
+ "defaultValue",
5086
+ "label",
5087
+ "localized",
5088
+ "admin",
5089
+ "unique",
5090
+ "index",
5091
+ "hidden",
5092
+ "readOnly",
5093
+ "deprecated"
5094
+ ];
5095
+ for (const k of keys) {
5096
+ if (k in field) safe[k] = field[k];
5097
+ }
5098
+ if (field.fields) {
5099
+ safe.fields = field.fields.map(serializeField);
5100
+ }
5101
+ if (field.tabs) {
5102
+ safe.tabs = field.tabs.map((t) => ({
5103
+ label: t.label,
5104
+ name: t.name,
5105
+ fields: t.fields.map(serializeField)
5106
+ }));
5107
+ }
5108
+ return safe;
5109
+ }
5110
+ app.get("/api/__schema", async (c) => {
5111
+ try {
5112
+ const { user: ctxUser, apiKeyContext } = await resolveAuthContext(
5113
+ c.req.raw,
5114
+ authMw,
5115
+ user,
5116
+ tenantID
5117
+ );
5118
+ if (!ctxUser && !apiKeyContext) {
5119
+ return c.json({ error: "Unauthorized" }, 401);
5120
+ }
5121
+ const cols = registry.getCollections().filter(
5122
+ (col) => col.slug !== "users" && col.slug !== "audit_logs"
5123
+ );
5124
+ const serialized = cols.map((col) => ({
5125
+ slug: col.slug,
5126
+ label: col.label,
5127
+ labelPlural: col.labelPlural,
5128
+ singularLabel: col.singularLabel,
5129
+ timestamps: col.timestamps,
5130
+ auth: !!col.auth,
5131
+ tenantScoped: !!col.tenantScoped,
5132
+ upload: col.upload ? { staticDir: col.upload.staticDir, imageSizes: col.upload.imageSizes, mimeTypes: col.upload.mimeTypes } : void 0,
5133
+ fields: col.fields.map(serializeField)
5134
+ }));
5135
+ return c.json(serialized);
5136
+ } catch (error) {
5137
+ console.error("[Schema] error:", error);
5138
+ return c.json({ error: error.message }, 500);
5139
+ }
5140
+ });
5060
5141
  const collections = registry.getCollections();
5061
5142
  for (const collection of collections) {
5062
5143
  let computeDiff2 = function(a, b) {
@@ -6419,5 +6500,5 @@ exports.init_secret = init_secret;
6419
6500
  exports.loadSecrets = loadSecrets;
6420
6501
  exports.resolveProvider = resolveProvider;
6421
6502
  exports.setDbAdapter = setDbAdapter;
6422
- //# sourceMappingURL=chunk-2CBCU5ML.cjs.map
6423
- //# sourceMappingURL=chunk-2CBCU5ML.cjs.map
6503
+ //# sourceMappingURL=chunk-IEIHABVR.cjs.map
6504
+ //# sourceMappingURL=chunk-IEIHABVR.cjs.map