@kyro-cms/core 0.9.8 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. package/dist/api-handler-graphql.cjs +22 -17
  2. package/dist/api-handler-graphql.cjs.map +1 -1
  3. package/dist/api-handler-graphql.js +18 -13
  4. package/dist/api-handler-graphql.js.map +1 -1
  5. package/dist/api-handler-trpc.cjs +13 -13
  6. package/dist/api-handler-trpc.js +11 -11
  7. package/dist/api-handler.cjs +14 -14
  8. package/dist/api-handler.js +11 -11
  9. package/dist/{bootstrap-4CELFLJO.cjs → bootstrap-FUAPY2OF.cjs} +9 -9
  10. package/dist/{bootstrap-4CELFLJO.cjs.map → bootstrap-FUAPY2OF.cjs.map} +1 -1
  11. package/dist/bootstrap-OXNVM7FP.js +7 -0
  12. package/dist/{bootstrap-3PV3GJ3S.js.map → bootstrap-OXNVM7FP.js.map} +1 -1
  13. package/dist/{chunk-HA4MGAZJ.js → chunk-354ISGA4.js} +112 -49
  14. package/dist/chunk-354ISGA4.js.map +1 -0
  15. package/dist/{chunk-2GXALYKV.js → chunk-3AKCVYDB.js} +4 -109
  16. package/dist/chunk-3AKCVYDB.js.map +1 -0
  17. package/dist/{chunk-OVZO4KB6.cjs → chunk-3P5AHK2U.cjs} +34 -38
  18. package/dist/chunk-3P5AHK2U.cjs.map +1 -0
  19. package/dist/{chunk-KGJRJ7CU.cjs → chunk-4OCMVGEY.cjs} +4 -110
  20. package/dist/chunk-4OCMVGEY.cjs.map +1 -0
  21. package/dist/{chunk-EQTMBMDR.js → chunk-526M5MOA.js} +19 -8
  22. package/dist/chunk-526M5MOA.js.map +1 -0
  23. package/dist/{chunk-5PMQQFRE.cjs → chunk-5GFQPHGT.cjs} +6 -9
  24. package/dist/chunk-5GFQPHGT.cjs.map +1 -0
  25. package/dist/chunk-5RPRLTTN.js +861 -0
  26. package/dist/chunk-5RPRLTTN.js.map +1 -0
  27. package/dist/{chunk-ZFHTJ2YX.js → chunk-AN2L2CJZ.js} +16 -20
  28. package/dist/chunk-AN2L2CJZ.js.map +1 -0
  29. package/dist/{chunk-RFFSZSCL.cjs → chunk-GYIJ3JJM.cjs} +3 -11
  30. package/dist/chunk-GYIJ3JJM.cjs.map +1 -0
  31. package/dist/{chunk-PQ72Z6WC.js → chunk-GZS4LMR7.js} +2 -5
  32. package/dist/chunk-GZS4LMR7.js.map +1 -0
  33. package/dist/{chunk-GAAHG2Z4.js → chunk-HY6B7B5A.js} +4 -7
  34. package/dist/chunk-HY6B7B5A.js.map +1 -0
  35. package/dist/{chunk-2CBCU5ML.cjs → chunk-ISKYUUP4.cjs} +142 -79
  36. package/dist/chunk-ISKYUUP4.cjs.map +1 -0
  37. package/dist/{chunk-Z7OH3MWT.cjs → chunk-LNTFRAHF.cjs} +110 -2
  38. package/dist/chunk-LNTFRAHF.cjs.map +1 -0
  39. package/dist/chunk-N4GN6Q3V.cjs +869 -0
  40. package/dist/chunk-N4GN6Q3V.cjs.map +1 -0
  41. package/dist/{chunk-6UNONDW7.js → chunk-N5QSHUA6.js} +2 -11
  42. package/dist/chunk-N5QSHUA6.js.map +1 -0
  43. package/dist/{chunk-PJ7F4TCC.cjs → chunk-NQJJYRLP.cjs} +24 -13
  44. package/dist/chunk-NQJJYRLP.cjs.map +1 -0
  45. package/dist/{chunk-65DSXNQL.js → chunk-OX6GOIPH.js} +4 -4
  46. package/dist/{chunk-65DSXNQL.js.map → chunk-OX6GOIPH.js.map} +1 -1
  47. package/dist/{chunk-Q23GAMLE.cjs → chunk-THBQG64D.cjs} +2 -5
  48. package/dist/chunk-THBQG64D.cjs.map +1 -0
  49. package/dist/{chunk-W3GT55TY.cjs → chunk-TQG7G7YI.cjs} +13 -13
  50. package/dist/{chunk-W3GT55TY.cjs.map → chunk-TQG7G7YI.cjs.map} +1 -1
  51. package/dist/{chunk-Y7AQK4R4.cjs → chunk-VKREAIBA.cjs} +2 -11
  52. package/dist/chunk-VKREAIBA.cjs.map +1 -0
  53. package/dist/{chunk-2Z7YAJBS.js → chunk-WDTTHKDS.js} +109 -3
  54. package/dist/chunk-WDTTHKDS.js.map +1 -0
  55. package/dist/{chunk-V7KZQIZ6.js → chunk-XHAAAEXX.js} +2 -10
  56. package/dist/chunk-XHAAAEXX.js.map +1 -0
  57. package/dist/cli/index.cjs +145 -51
  58. package/dist/cli/index.cjs.map +1 -1
  59. package/dist/cli/index.js +145 -51
  60. package/dist/cli/index.js.map +1 -1
  61. package/dist/drizzle/index.cjs +9 -9
  62. package/dist/drizzle/index.js +1 -1
  63. package/dist/graphql/index.cjs +7 -7
  64. package/dist/graphql/index.d.cts +21 -13
  65. package/dist/graphql/index.d.ts +21 -13
  66. package/dist/graphql/index.js +2 -2
  67. package/dist/index.cjs +92 -94
  68. package/dist/index.cjs.map +1 -1
  69. package/dist/index.d.cts +6 -5
  70. package/dist/index.d.ts +6 -5
  71. package/dist/index.js +12 -14
  72. package/dist/index.js.map +1 -1
  73. package/dist/mongodb/index.cjs +3 -3
  74. package/dist/mongodb/index.js +1 -1
  75. package/dist/rest/index.cjs +8 -8
  76. package/dist/rest/index.js +6 -6
  77. package/dist/trpc/index.cjs +12 -12
  78. package/dist/trpc/index.js +3 -3
  79. package/package.json +1 -1
  80. package/dist/bootstrap-3PV3GJ3S.js +0 -7
  81. package/dist/chunk-2CBCU5ML.cjs.map +0 -1
  82. package/dist/chunk-2GXALYKV.js.map +0 -1
  83. package/dist/chunk-2Z7YAJBS.js.map +0 -1
  84. package/dist/chunk-5PMQQFRE.cjs.map +0 -1
  85. package/dist/chunk-6DURKQ6W.js +0 -1072
  86. package/dist/chunk-6DURKQ6W.js.map +0 -1
  87. package/dist/chunk-6UNONDW7.js.map +0 -1
  88. package/dist/chunk-EQTMBMDR.js.map +0 -1
  89. package/dist/chunk-GAAHG2Z4.js.map +0 -1
  90. package/dist/chunk-HA4MGAZJ.js.map +0 -1
  91. package/dist/chunk-KGJRJ7CU.cjs.map +0 -1
  92. package/dist/chunk-OVZO4KB6.cjs.map +0 -1
  93. package/dist/chunk-PF642V5O.cjs +0 -1080
  94. package/dist/chunk-PF642V5O.cjs.map +0 -1
  95. package/dist/chunk-PJ7F4TCC.cjs.map +0 -1
  96. package/dist/chunk-PQ72Z6WC.js.map +0 -1
  97. package/dist/chunk-Q23GAMLE.cjs.map +0 -1
  98. package/dist/chunk-RFFSZSCL.cjs.map +0 -1
  99. package/dist/chunk-V7KZQIZ6.js.map +0 -1
  100. package/dist/chunk-Y7AQK4R4.cjs.map +0 -1
  101. package/dist/chunk-Z7OH3MWT.cjs.map +0 -1
  102. package/dist/chunk-ZFHTJ2YX.js.map +0 -1
@@ -1,14 +1,14 @@
1
1
  'use strict';
2
2
 
3
- var chunkY7AQK4R4_cjs = require('./chunk-Y7AQK4R4.cjs');
3
+ var chunkVKREAIBA_cjs = require('./chunk-VKREAIBA.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');
9
- var chunkRFFSZSCL_cjs = require('./chunk-RFFSZSCL.cjs');
7
+ var chunkLNTFRAHF_cjs = require('./chunk-LNTFRAHF.cjs');
8
+ var chunk4OCMVGEY_cjs = require('./chunk-4OCMVGEY.cjs');
9
+ var chunkGYIJ3JJM_cjs = require('./chunk-GYIJ3JJM.cjs');
10
10
  var chunk7OS7TX2Q_cjs = require('./chunk-7OS7TX2Q.cjs');
11
- var chunkQ23GAMLE_cjs = require('./chunk-Q23GAMLE.cjs');
11
+ var chunkTHBQG64D_cjs = require('./chunk-THBQG64D.cjs');
12
12
  var chunkGXFOGU7N_cjs = require('./chunk-GXFOGU7N.cjs');
13
13
  var chunkNKPKR5BW_cjs = require('./chunk-NKPKR5BW.cjs');
14
14
  var chunkCZLDE2OZ_cjs = require('./chunk-CZLDE2OZ.cjs');
@@ -54,11 +54,9 @@ async function loadSecrets() {
54
54
  maxSessionsPerUser: result.maxSessionsPerUser || 3
55
55
  } : null
56
56
  };
57
- console.log("\u{1F510} Loaded secrets from database");
58
57
  return;
59
58
  }
60
59
  } catch (e) {
61
- console.log("\u26A0\uFE0F Could not load system settings from DB, using env fallback");
62
60
  }
63
61
  }
64
62
  cachedSecrets = {
@@ -391,14 +389,14 @@ function createAuthMiddleware(config) {
391
389
  userLookup
392
390
  } = config;
393
391
  return async function authMiddleware(req) {
394
- const apiKeyRaw = chunkKGJRJ7CU_cjs.extractApiKeyFromRequest(req);
392
+ const apiKeyRaw = chunk4OCMVGEY_cjs.extractApiKeyFromRequest(req);
395
393
  if (apiKeyRaw && db) {
396
- const result = await chunkKGJRJ7CU_cjs.validateApiKey(apiKeyRaw, db, userLookup);
394
+ const result = await chunk4OCMVGEY_cjs.validateApiKey(apiKeyRaw, db, userLookup);
397
395
  if (result.valid && result.user) {
398
396
  return {
399
397
  user: result.user,
400
398
  tenantContext: createTenantContextFromUser(result.user),
401
- apiKeyContext: chunkKGJRJ7CU_cjs.createApiKeyContext(result),
399
+ apiKeyContext: chunk4OCMVGEY_cjs.createApiKeyContext(result),
402
400
  status: 200,
403
401
  authType: "apikey"
404
402
  };
@@ -963,7 +961,7 @@ var AuthRoutes = class {
963
961
  constructor(config) {
964
962
  this.authAdapter = config.redis;
965
963
  this.email = config.email;
966
- this.passwordPolicy = config.passwordPolicy || new chunkY7AQK4R4_cjs.PasswordPolicy();
964
+ this.passwordPolicy = config.passwordPolicy || new chunkVKREAIBA_cjs.PasswordPolicy();
967
965
  this.lockout = config.lockout;
968
966
  this.rateLimiter = config.rateLimiter;
969
967
  this.auditLogger = config.auditLogger;
@@ -2207,14 +2205,6 @@ function getDisplayName(provider) {
2207
2205
  }
2208
2206
  }
2209
2207
  function createS3Storage(config) {
2210
- console.log("[createS3Storage] Creating provider:", config.provider);
2211
- console.log("[createS3Storage] Credentials:", {
2212
- accessKeyId: config.accessKeyId ? "SET" : "UNDEFINED",
2213
- secretAccessKey: config.secretAccessKey ? "SET" : "UNDEFINED",
2214
- bucket: config.bucket,
2215
- accountId: config.accountId,
2216
- endpoint: config.endpoint
2217
- });
2218
2208
  const client = new clientS3.S3Client({
2219
2209
  region: config.region || "auto",
2220
2210
  endpoint: config.endpoint,
@@ -2550,13 +2540,6 @@ function createCloudinaryStorage(config) {
2550
2540
  folder = folderParts.length > 1 ? folderParts.slice(0, -1).join("/") : "";
2551
2541
  const newFilename = newKey.replace(/\.[^.]+$/, "");
2552
2542
  newPublicId = folder ? `${folder}/${newFilename}` : newFilename;
2553
- console.log("[Cloudinary rename]", {
2554
- urlPath,
2555
- version,
2556
- publicIdWithoutVersion,
2557
- folder,
2558
- newPublicId
2559
- });
2560
2543
  const timestamp = Math.round(Date.now() / 1e3);
2561
2544
  const signatureParams = {
2562
2545
  from_public_id: publicIdWithoutVersion,
@@ -2581,7 +2564,6 @@ function createCloudinaryStorage(config) {
2581
2564
  );
2582
2565
  if (response.ok) {
2583
2566
  const data = await response.json();
2584
- console.log("[Cloudinary rename] Success:", data.secure_url);
2585
2567
  return data.secure_url;
2586
2568
  } else {
2587
2569
  const error = await response.json();
@@ -2841,14 +2823,14 @@ var MediaService = class _MediaService {
2841
2823
  this.db = db;
2842
2824
  this.storage = storage2;
2843
2825
  this.dialect = options?.dialect || "sqlite";
2844
- this.genId = options?.genId || chunkRFFSZSCL_cjs.genId;
2826
+ this.genId = options?.genId || chunkGYIJ3JJM_cjs.genId;
2845
2827
  }
2846
2828
  static async init(db, options) {
2847
2829
  let storage2;
2848
2830
  if (options?.storageConfig) {
2849
2831
  storage2 = await resolveProviderWithConfig(options.storageConfig);
2850
2832
  } else {
2851
- const configService = new chunkY7AQK4R4_cjs.ConfigService(db);
2833
+ const configService = new chunkVKREAIBA_cjs.ConfigService(db);
2852
2834
  await configService.load();
2853
2835
  storage2 = await resolveProvider(configService);
2854
2836
  }
@@ -2958,7 +2940,7 @@ var MediaService = class _MediaService {
2958
2940
  const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
2959
2941
  return { where, params: p, orderBy: sortDir, sortCol };
2960
2942
  }
2961
- rowToMedia(row) {
2943
+ rowToMedia(row, origin) {
2962
2944
  return {
2963
2945
  id: row.id,
2964
2946
  filename: row.filename,
@@ -2968,8 +2950,8 @@ var MediaService = class _MediaService {
2968
2950
  fileSize: row.file_size ?? row.fileSize,
2969
2951
  width: row.width ?? null,
2970
2952
  height: row.height ?? null,
2971
- url: row.url,
2972
- thumbnailUrl: row.thumbnail_url ?? row.thumbnailUrl ?? null,
2953
+ url: _MediaService.resolveMediaUrl(row.url, origin),
2954
+ thumbnailUrl: _MediaService.resolveMediaUrl(row.thumbnail_url ?? row.thumbnailUrl ?? null, origin),
2973
2955
  folder: row.folder ?? null,
2974
2956
  provider: row.provider,
2975
2957
  alt: row.alt ?? null,
@@ -2979,6 +2961,12 @@ var MediaService = class _MediaService {
2979
2961
  updatedAt: row.updated_at ?? row.updatedAt
2980
2962
  };
2981
2963
  }
2964
+ static resolveMediaUrl(url, origin) {
2965
+ if (!url) return null;
2966
+ if (url.startsWith("http://") || url.startsWith("https://") || url.startsWith("blob:") || url.startsWith("data:")) return url;
2967
+ const base = (process.env.KYRO_BASE_URL || origin || "http://localhost:4321").replace(/\/+$/, "");
2968
+ return `${base}${url.startsWith("/") ? "" : "/"}${url}`;
2969
+ }
2982
2970
  async sqliteRun(sql, params = []) {
2983
2971
  const stmt = this.db.prepare(sql);
2984
2972
  const sqlLower = sql.trim().toLowerCase();
@@ -3106,17 +3094,19 @@ var MediaService = class _MediaService {
3106
3094
  const file = new File([blob], originalName, { type: mimeType });
3107
3095
  return this.upload(file, folder);
3108
3096
  }
3109
- async delete(id) {
3097
+ async delete(id, origin) {
3110
3098
  let item = null;
3111
3099
  if (this.dialect === "sqlite") {
3112
- item = this.sqliteGet(`SELECT * FROM ${this.mediaTable} WHERE id = ?`, [
3113
- id
3114
- ]);
3100
+ const row = this.sqliteGet(
3101
+ `SELECT * FROM ${this.mediaTable} WHERE id = ?`,
3102
+ [id]
3103
+ );
3104
+ if (row) item = this.rowToMedia(row, origin);
3115
3105
  } else {
3116
3106
  const { media: mediaSchema } = await import('./media-TUSLVRQ6.cjs');
3117
3107
  const { eq } = await import('drizzle-orm');
3118
3108
  const [row] = await this.db.select().from(mediaSchema).where(eq(mediaSchema.id, id));
3119
- if (row) item = this.rowToMedia(row);
3109
+ if (row) item = this.rowToMedia(row, origin);
3120
3110
  }
3121
3111
  if (!item) return;
3122
3112
  await this.deleteFile(item.url);
@@ -3137,7 +3127,7 @@ var MediaService = class _MediaService {
3137
3127
  async deleteFile(url) {
3138
3128
  await this.storage.delete(url);
3139
3129
  }
3140
- async rename(id, newKey) {
3130
+ async rename(id, newKey, origin) {
3141
3131
  let item = null;
3142
3132
  if (this.dialect === "sqlite") {
3143
3133
  item = this.sqliteGet(`SELECT * FROM ${this.mediaTable} WHERE id = ?`, [
@@ -3147,7 +3137,7 @@ var MediaService = class _MediaService {
3147
3137
  const { media: mediaSchema } = await import('./media-TUSLVRQ6.cjs');
3148
3138
  const { eq } = await import('drizzle-orm');
3149
3139
  const [row] = await this.db.select().from(mediaSchema).where(eq(mediaSchema.id, id));
3150
- if (row) item = this.rowToMedia(row);
3140
+ if (row) item = this.rowToMedia(row, origin);
3151
3141
  }
3152
3142
  if (!item) return null;
3153
3143
  const newUrl = await this.storage.rename(item.url, newKey);
@@ -3190,20 +3180,20 @@ var MediaService = class _MediaService {
3190
3180
  thumbnailUrl: updateData.thumbnailUrl ?? null
3191
3181
  };
3192
3182
  }
3193
- async findById(id) {
3183
+ async findById(id, origin) {
3194
3184
  if (this.dialect === "sqlite") {
3195
3185
  const row2 = this.sqliteGet(
3196
3186
  `SELECT * FROM ${this.mediaTable} WHERE id = ?`,
3197
3187
  [id]
3198
3188
  );
3199
- return row2 ? this.rowToMedia(row2) : null;
3189
+ return row2 ? this.rowToMedia(row2, origin) : null;
3200
3190
  }
3201
3191
  const { media: mediaSchema } = await import('./media-TUSLVRQ6.cjs');
3202
3192
  const { eq } = await import('drizzle-orm');
3203
3193
  const [row] = await this.db.select().from(mediaSchema).where(eq(mediaSchema.id, id));
3204
- return row ? this.rowToMedia(row) : null;
3194
+ return row ? this.rowToMedia(row, origin) : null;
3205
3195
  }
3206
- async find(params = {}) {
3196
+ async find(params = {}, origin) {
3207
3197
  const {
3208
3198
  page = 1,
3209
3199
  limit = 30,
@@ -3239,7 +3229,7 @@ var MediaService = class _MediaService {
3239
3229
  [...p, limit, offset]
3240
3230
  );
3241
3231
  return {
3242
- docs: rows.map((r) => this.rowToMedia(r)),
3232
+ docs: rows.map((r) => this.rowToMedia(r, origin)),
3243
3233
  totalDocs: totalDocs2,
3244
3234
  page,
3245
3235
  limit,
@@ -3286,14 +3276,14 @@ var MediaService = class _MediaService {
3286
3276
  const [{ count }] = await this.db.select({ count: sql`count(*)` }).from(mediaSchema).where(whereClause);
3287
3277
  const totalDocs = Number(count);
3288
3278
  return {
3289
- docs: docs.map((r) => this.rowToMedia(r)),
3279
+ docs: docs.map((r) => this.rowToMedia(r, origin)),
3290
3280
  totalDocs,
3291
3281
  page,
3292
3282
  limit,
3293
3283
  totalPages: Math.ceil(totalDocs / limit)
3294
3284
  };
3295
3285
  }
3296
- async update(id, data) {
3286
+ async update(id, data, origin) {
3297
3287
  const now = this.now();
3298
3288
  if (this.dialect === "sqlite") {
3299
3289
  const sets = ["updated_at = ?"];
@@ -3312,7 +3302,7 @@ var MediaService = class _MediaService {
3312
3302
  }
3313
3303
  if (data.folder !== void 0) {
3314
3304
  sets.push("folder = ?");
3315
- p.push(data.folder || null);
3305
+ p.push(data.folder);
3316
3306
  }
3317
3307
  p.push(id);
3318
3308
  await this.sqliteRun(
@@ -3323,12 +3313,12 @@ var MediaService = class _MediaService {
3323
3313
  `SELECT * FROM ${this.mediaTable} WHERE id = ?`,
3324
3314
  [id]
3325
3315
  );
3326
- return row ? this.rowToMedia(row) : null;
3316
+ return row ? this.rowToMedia(row, origin) : null;
3327
3317
  }
3328
3318
  const { media: mediaSchema } = await import('./media-TUSLVRQ6.cjs');
3329
3319
  const { eq } = await import('drizzle-orm');
3330
3320
  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;
3321
+ return updated ? this.rowToMedia(updated, origin) : null;
3332
3322
  }
3333
3323
  async updateMany(ids, data) {
3334
3324
  const now = this.now();
@@ -3485,9 +3475,9 @@ function convertRichtextFields(fields, data) {
3485
3475
  }
3486
3476
  var COLLECTION_EVENT_MAP = {
3487
3477
  _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
3478
+ create: chunkLNTFRAHF_cjs.WEBHOOK_EVENTS.MEDIA_UPLOAD,
3479
+ update: chunkLNTFRAHF_cjs.WEBHOOK_EVENTS.MEDIA_UPLOAD,
3480
+ delete: chunkLNTFRAHF_cjs.WEBHOOK_EVENTS.MEDIA_DELETE
3491
3481
  }
3492
3482
  };
3493
3483
  function getWebhookEvent(collection, operation) {
@@ -3535,7 +3525,7 @@ function buildConflictResponse(expectedUpdatedAt, currentDoc) {
3535
3525
  };
3536
3526
  }
3537
3527
  async function checkCollectionAccess2(collection, operation, req, ctxUser, ctxTenantID, apiKeyContext, enablePublicAccess = true, defaultCollectionAccess = "none") {
3538
- const result = await chunkKGJRJ7CU_cjs.checkCollectionAccess(collection, operation, {
3528
+ const result = await chunkLNTFRAHF_cjs.checkCollectionAccess(collection, operation, {
3539
3529
  user: ctxUser,
3540
3530
  req,
3541
3531
  tenantID: ctxTenantID,
@@ -3547,7 +3537,7 @@ async function checkCollectionAccess2(collection, operation, req, ctxUser, ctxTe
3547
3537
  return result;
3548
3538
  }
3549
3539
  async function checkGlobalAccess2(global, operation, req, ctxUser, ctxTenantID, enablePublicAccess = true) {
3550
- const result = await chunkKGJRJ7CU_cjs.checkGlobalAccess(global, operation, {
3540
+ const result = await chunkLNTFRAHF_cjs.checkGlobalAccess(global, operation, {
3551
3541
  user: ctxUser,
3552
3542
  req,
3553
3543
  tenantID: ctxTenantID
@@ -3584,10 +3574,10 @@ async function resolveAuthContext(req, authMw, staticUser, staticTenantID) {
3584
3574
  };
3585
3575
  }
3586
3576
  function createDefaultAuthAdapter(db, rootDir) {
3587
- if (db instanceof chunkRFFSZSCL_cjs.DrizzleAdapter && db.dialect === "postgres") {
3577
+ if (db instanceof chunkGYIJ3JJM_cjs.DrizzleAdapter && db.dialect === "postgres") {
3588
3578
  return new chunk7OS7TX2Q_cjs.PostgresAuthAdapter({ db: db.client });
3589
3579
  }
3590
- if (db instanceof chunkQ23GAMLE_cjs.MongoDBAdapter) {
3580
+ if (db instanceof chunkTHBQG64D_cjs.MongoDBAdapter) {
3591
3581
  return new chunkGXFOGU7N_cjs.MongoDBAuthAdapter({ db: db.db });
3592
3582
  }
3593
3583
  const defaultAuthDbPath = path.resolve(rootDir, "data", "kyro.db");
@@ -3694,7 +3684,7 @@ function createHonoApp(options) {
3694
3684
  baseUrl: process.env.KYRO_BASE_URL || "http://localhost:4321",
3695
3685
  rateLimiter
3696
3686
  });
3697
- chunkY7AQK4R4_cjs.EmailTransport.fromConfig(db).then((transport) => {
3687
+ chunkVKREAIBA_cjs.EmailTransport.fromConfig(db).then((transport) => {
3698
3688
  if (transport) {
3699
3689
  authRoutes.email = transport;
3700
3690
  }
@@ -4099,8 +4089,8 @@ function createHonoApp(options) {
4099
4089
  }
4100
4090
  if (!mediaService) {
4101
4091
  try {
4102
- const dialect = db instanceof chunkRFFSZSCL_cjs.DrizzleAdapter ? db.dialect : "sqlite";
4103
- const mediaDb = dialect === "postgres" && db instanceof chunkRFFSZSCL_cjs.DrizzleAdapter ? db.client : db;
4092
+ const dialect = db instanceof chunkGYIJ3JJM_cjs.DrizzleAdapter ? db.dialect : "sqlite";
4093
+ const mediaDb = dialect === "postgres" && db instanceof chunkGYIJ3JJM_cjs.DrizzleAdapter ? db.client : db;
4104
4094
  mediaService = await MediaService.init(mediaDb, { dialect });
4105
4095
  } catch (error) {
4106
4096
  console.error("[getMedia] Init error:", error);
@@ -4115,12 +4105,13 @@ function createHonoApp(options) {
4115
4105
  const { user: ctxUser } = await resolveAuthContext(c.req.raw, authMw, user, tenantID);
4116
4106
  if (!ctxUser) return c.json({ error: "Authentication required" }, 401);
4117
4107
  const service = await getMedia();
4108
+ const origin = new URL(c.req.url).origin;
4118
4109
  const page = parseInt(c.req.query("page") || "1");
4119
4110
  const limit = parseInt(c.req.query("limit") || "30");
4120
4111
  const search = c.req.query("search") || "";
4121
4112
  const type = c.req.query("type") || "";
4122
4113
  const folder = c.req.query("folder") || "";
4123
- const result = await service.find({ page, limit, search, type, folder });
4114
+ const result = await service.find({ page, limit, search, type, folder }, origin);
4124
4115
  return c.json(result);
4125
4116
  } catch (error) {
4126
4117
  console.error("[Media] find error:", error);
@@ -4204,7 +4195,8 @@ function createHonoApp(options) {
4204
4195
  if (!ctxUser) return c.json({ error: "Authentication required" }, 401);
4205
4196
  const service = await getMedia();
4206
4197
  const id = c.req.param("id");
4207
- await service.delete(id);
4198
+ const origin = new URL(c.req.url).origin;
4199
+ await service.delete(id, origin);
4208
4200
  return c.json({ success: true });
4209
4201
  } catch (error) {
4210
4202
  console.error("[Media] delete error:", error);
@@ -4260,7 +4252,8 @@ function createHonoApp(options) {
4260
4252
  if (!ctxUser) return c.json({ error: "Authentication required" }, 401);
4261
4253
  const service = await getMedia();
4262
4254
  const id = c.req.param("id");
4263
- const doc = await service.findById(id);
4255
+ const origin = new URL(c.req.url).origin;
4256
+ const doc = await service.findById(id, origin);
4264
4257
  if (!doc) return c.json({ error: "Media not found" }, 404);
4265
4258
  return c.json(doc);
4266
4259
  } catch (error) {
@@ -4275,8 +4268,9 @@ function createHonoApp(options) {
4275
4268
  const service = await getMedia();
4276
4269
  const id = c.req.param("id");
4277
4270
  const body = await c.req.json();
4271
+ const origin = new URL(c.req.url).origin;
4278
4272
  if (body.folder !== void 0) {
4279
- const updated = await service.update(id, { folder: body.folder });
4273
+ const updated = await service.update(id, { folder: body.folder }, origin);
4280
4274
  return c.json({ doc: updated });
4281
4275
  }
4282
4276
  return c.json({ error: "No valid fields to update" }, 400);
@@ -4782,7 +4776,7 @@ function createHonoApp(options) {
4782
4776
  }
4783
4777
  const page = parseInt(c.req.query("page") || "1");
4784
4778
  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 });
4779
+ const result = await db.find({ collection: chunk4OCMVGEY_cjs.API_KEY_COLLECTION, where: {}, page, limit, tenantID: ctxTenantID });
4786
4780
  const docs = (result.docs || []).map((doc) => ({
4787
4781
  id: doc.id,
4788
4782
  name: doc.name,
@@ -4807,14 +4801,14 @@ function createHonoApp(options) {
4807
4801
  if (!body.name || typeof body.name !== "string") {
4808
4802
  return c.json({ error: "name is required" }, 400);
4809
4803
  }
4810
- const rawKey = chunkKGJRJ7CU_cjs.generateApiKey();
4804
+ const rawKey = chunk4OCMVGEY_cjs.generateApiKey();
4811
4805
  const doc = await db.create({
4812
- collection: chunkKGJRJ7CU_cjs.API_KEY_COLLECTION,
4806
+ collection: chunk4OCMVGEY_cjs.API_KEY_COLLECTION,
4813
4807
  data: {
4814
4808
  userId: ctxUser.id,
4815
4809
  name: body.name,
4816
4810
  key: rawKey,
4817
- keyPrefix: chunkKGJRJ7CU_cjs.generateApiKeyPrefix(rawKey),
4811
+ keyPrefix: chunk4OCMVGEY_cjs.generateApiKeyPrefix(rawKey),
4818
4812
  permissions: Array.isArray(body.permissions) ? body.permissions : ["*"],
4819
4813
  expiresAt: body.expiresAt || null,
4820
4814
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
@@ -4845,9 +4839,9 @@ function createHonoApp(options) {
4845
4839
  return c.json({ error: "Forbidden" }, 403);
4846
4840
  }
4847
4841
  const id = c.req.param("id");
4848
- const existing = await db.findByID({ collection: chunkKGJRJ7CU_cjs.API_KEY_COLLECTION, id });
4842
+ const existing = await db.findByID({ collection: chunk4OCMVGEY_cjs.API_KEY_COLLECTION, id });
4849
4843
  if (!existing) return c.json({ error: "API key not found" }, 404);
4850
- await db.delete({ collection: chunkKGJRJ7CU_cjs.API_KEY_COLLECTION, id });
4844
+ await db.delete({ collection: chunk4OCMVGEY_cjs.API_KEY_COLLECTION, id });
4851
4845
  await sessionAuthAdapter?.createAuditLog({
4852
4846
  action: "api_key_delete",
4853
4847
  userId: ctxUser.id,
@@ -4870,14 +4864,14 @@ function createHonoApp(options) {
4870
4864
  }
4871
4865
  const id = c.req.param("id");
4872
4866
  const body = await c.req.json();
4873
- const existing = await db.findByID({ collection: chunkKGJRJ7CU_cjs.API_KEY_COLLECTION, id });
4867
+ const existing = await db.findByID({ collection: chunk4OCMVGEY_cjs.API_KEY_COLLECTION, id });
4874
4868
  if (!existing) return c.json({ error: "API key not found" }, 404);
4875
4869
  const updateData = {};
4876
4870
  if (typeof body.name === "string" && body.name.trim()) updateData.name = body.name.trim();
4877
4871
  if (Array.isArray(body.permissions)) updateData.permissions = body.permissions;
4878
4872
  if (body.expiresAt !== void 0) updateData.expiresAt = body.expiresAt || null;
4879
4873
  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 });
4874
+ const updated = await db.update({ collection: chunk4OCMVGEY_cjs.API_KEY_COLLECTION, id, data: updateData });
4881
4875
  return c.json({ ...updated, keyPrefix: existing.keyPrefix });
4882
4876
  } catch (error) {
4883
4877
  console.error("[ApiKeys] PATCH error:", error);
@@ -4891,15 +4885,15 @@ function createHonoApp(options) {
4891
4885
  return c.json({ error: "Forbidden" }, 403);
4892
4886
  }
4893
4887
  const id = c.req.param("id");
4894
- const existing = await db.findByID({ collection: chunkKGJRJ7CU_cjs.API_KEY_COLLECTION, id });
4888
+ const existing = await db.findByID({ collection: chunk4OCMVGEY_cjs.API_KEY_COLLECTION, id });
4895
4889
  if (!existing) return c.json({ error: "API key not found" }, 404);
4896
- const rawKey = chunkKGJRJ7CU_cjs.generateApiKey();
4890
+ const rawKey = chunk4OCMVGEY_cjs.generateApiKey();
4897
4891
  const updated = await db.update({
4898
- collection: chunkKGJRJ7CU_cjs.API_KEY_COLLECTION,
4892
+ collection: chunk4OCMVGEY_cjs.API_KEY_COLLECTION,
4899
4893
  id,
4900
4894
  data: {
4901
4895
  key: rawKey,
4902
- keyPrefix: chunkKGJRJ7CU_cjs.generateApiKeyPrefix(rawKey),
4896
+ keyPrefix: chunk4OCMVGEY_cjs.generateApiKeyPrefix(rawKey),
4903
4897
  lastUsedAt: null
4904
4898
  }
4905
4899
  });
@@ -5057,6 +5051,75 @@ function createHonoApp(options) {
5057
5051
  return c.json({ error: error.message }, 500);
5058
5052
  }
5059
5053
  });
5054
+ function serializeField(field) {
5055
+ const safe = {};
5056
+ const keys = [
5057
+ "name",
5058
+ "type",
5059
+ "required",
5060
+ "hasMany",
5061
+ "relationTo",
5062
+ "options",
5063
+ "min",
5064
+ "max",
5065
+ "minLength",
5066
+ "maxLength",
5067
+ "defaultValue",
5068
+ "label",
5069
+ "localized",
5070
+ "admin",
5071
+ "unique",
5072
+ "index",
5073
+ "hidden",
5074
+ "readOnly",
5075
+ "deprecated"
5076
+ ];
5077
+ for (const k of keys) {
5078
+ if (k in field) safe[k] = field[k];
5079
+ }
5080
+ if (field.fields) {
5081
+ safe.fields = field.fields.map(serializeField);
5082
+ }
5083
+ if (field.tabs) {
5084
+ safe.tabs = field.tabs.map((t) => ({
5085
+ label: t.label,
5086
+ name: t.name,
5087
+ fields: t.fields.map(serializeField)
5088
+ }));
5089
+ }
5090
+ return safe;
5091
+ }
5092
+ app.get("/api/__schema", async (c) => {
5093
+ try {
5094
+ const { user: ctxUser, apiKeyContext } = await resolveAuthContext(
5095
+ c.req.raw,
5096
+ authMw,
5097
+ user,
5098
+ tenantID
5099
+ );
5100
+ if (!ctxUser && !apiKeyContext) {
5101
+ return c.json({ error: "Unauthorized" }, 401);
5102
+ }
5103
+ const cols = registry.getCollections().filter(
5104
+ (col) => col.slug !== "users" && col.slug !== "audit_logs"
5105
+ );
5106
+ const serialized = cols.map((col) => ({
5107
+ slug: col.slug,
5108
+ label: col.label,
5109
+ labelPlural: col.labelPlural,
5110
+ singularLabel: col.singularLabel,
5111
+ timestamps: col.timestamps,
5112
+ auth: !!col.auth,
5113
+ tenantScoped: !!col.tenantScoped,
5114
+ upload: col.upload ? { staticDir: col.upload.staticDir, imageSizes: col.upload.imageSizes, mimeTypes: col.upload.mimeTypes } : void 0,
5115
+ fields: col.fields.map(serializeField)
5116
+ }));
5117
+ return c.json(serialized);
5118
+ } catch (error) {
5119
+ console.error("[Schema] error:", error);
5120
+ return c.json({ error: error.message }, 500);
5121
+ }
5122
+ });
5060
5123
  const collections = registry.getCollections();
5061
5124
  for (const collection of collections) {
5062
5125
  let computeDiff2 = function(a, b) {
@@ -6141,7 +6204,7 @@ function createHonoApp(options) {
6141
6204
  mediaServiceInitError = null;
6142
6205
  }
6143
6206
  if (slug === "email-settings") {
6144
- const newEmailTransport = await chunkY7AQK4R4_cjs.EmailTransport.fromConfig(db);
6207
+ const newEmailTransport = await chunkVKREAIBA_cjs.EmailTransport.fromConfig(db);
6145
6208
  authRoutes.email = newEmailTransport || void 0;
6146
6209
  }
6147
6210
  if (slug === "system") {
@@ -6334,7 +6397,7 @@ function createHonoApp(options) {
6334
6397
  mailgun: body.mailgun,
6335
6398
  ses: body.ses
6336
6399
  };
6337
- const transport = new chunkY7AQK4R4_cjs.EmailTransport(transportConfig);
6400
+ const transport = new chunkVKREAIBA_cjs.EmailTransport(transportConfig);
6338
6401
  const recipient = body.testEmail || body.testEmailSection && body.testEmailSection.testEmail;
6339
6402
  if (!recipient) {
6340
6403
  return c.json({ error: "No test recipient email provided" }, 400);
@@ -6419,5 +6482,5 @@ exports.init_secret = init_secret;
6419
6482
  exports.loadSecrets = loadSecrets;
6420
6483
  exports.resolveProvider = resolveProvider;
6421
6484
  exports.setDbAdapter = setDbAdapter;
6422
- //# sourceMappingURL=chunk-2CBCU5ML.cjs.map
6423
- //# sourceMappingURL=chunk-2CBCU5ML.cjs.map
6485
+ //# sourceMappingURL=chunk-ISKYUUP4.cjs.map
6486
+ //# sourceMappingURL=chunk-ISKYUUP4.cjs.map