@kyro-cms/core 0.9.1 → 0.9.2

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 (180) hide show
  1. package/README.md +0 -6
  2. package/dist/{WebhookService-Yg2UEOB4.d.cts → WebhookService-BKszZlG0.d.cts} +1 -1
  3. package/dist/{WebhookService-CUTb9XOy.d.ts → WebhookService-Ccf1j-IN.d.ts} +1 -1
  4. package/dist/api-handler-graphql.cjs +17 -17
  5. package/dist/api-handler-graphql.js +13 -13
  6. package/dist/api-handler-trpc.cjs +15 -15
  7. package/dist/api-handler-trpc.js +13 -13
  8. package/dist/api-handler.cjs +16 -16
  9. package/dist/api-handler.js +13 -13
  10. package/dist/{base-DaqY2GhA.d.ts → base-CIuXkrH4.d.cts} +3 -5
  11. package/dist/{base-B71y_EAF.d.cts → base-fFo4lqER.d.ts} +3 -5
  12. package/dist/bootstrap-3PV3GJ3S.js +7 -0
  13. package/dist/{bootstrap-T5BK77LD.js.map → bootstrap-3PV3GJ3S.js.map} +1 -1
  14. package/dist/bootstrap-4CELFLJO.cjs +32 -0
  15. package/dist/{bootstrap-5NLASFOG.cjs.map → bootstrap-4CELFLJO.cjs.map} +1 -1
  16. package/dist/{chunk-Z6ZWNWWR.js → chunk-4CV4JOE5.js} +3 -9
  17. package/dist/{chunk-Z6ZWNWWR.js.map → chunk-4CV4JOE5.js.map} +1 -1
  18. package/dist/{chunk-5EPFQUQD.js → chunk-53NYVYVX.js} +6 -6
  19. package/dist/chunk-53NYVYVX.js.map +1 -0
  20. package/dist/{chunk-22M4O4ZJ.js → chunk-5H3MWQJS.js} +129 -143
  21. package/dist/chunk-5H3MWQJS.js.map +1 -0
  22. package/dist/{chunk-RAMGUDJN.cjs → chunk-5PMQQFRE.cjs} +5 -5
  23. package/dist/{chunk-RAMGUDJN.cjs.map → chunk-5PMQQFRE.cjs.map} +1 -1
  24. package/dist/{chunk-TXSZFA4G.js → chunk-6UNONDW7.js} +93 -9
  25. package/dist/chunk-6UNONDW7.js.map +1 -0
  26. package/dist/{chunk-C36TMDTY.cjs → chunk-7OS7TX2Q.cjs} +49 -48
  27. package/dist/chunk-7OS7TX2Q.cjs.map +1 -0
  28. package/dist/{chunk-3TPQ2BU6.js → chunk-BYBMTIMT.js} +2 -6
  29. package/dist/chunk-BYBMTIMT.js.map +1 -0
  30. package/dist/{chunk-FOPGUM27.js → chunk-CJX74IYK.js} +5 -4
  31. package/dist/chunk-CJX74IYK.js.map +1 -0
  32. package/dist/{chunk-RSF3UU7H.cjs → chunk-CNKT4PME.cjs} +196 -200
  33. package/dist/chunk-CNKT4PME.cjs.map +1 -0
  34. package/dist/{chunk-G7VZBCD6.cjs → chunk-CZLDE2OZ.cjs} +2 -9
  35. package/dist/{chunk-G7VZBCD6.cjs.map → chunk-CZLDE2OZ.cjs.map} +1 -1
  36. package/dist/{chunk-JOPVMWTM.cjs → chunk-DPA3KWPY.cjs} +3 -3
  37. package/dist/chunk-DPA3KWPY.cjs.map +1 -0
  38. package/dist/{chunk-ROJHKAQ4.cjs → chunk-E2763JUP.cjs} +143 -157
  39. package/dist/chunk-E2763JUP.cjs.map +1 -0
  40. package/dist/{chunk-FAXU7BMP.js → chunk-E5UJBLQ7.js} +2 -2
  41. package/dist/chunk-E5UJBLQ7.js.map +1 -0
  42. package/dist/{chunk-DVD5P72E.cjs → chunk-EEJUFDMF.cjs} +2 -6
  43. package/dist/chunk-EEJUFDMF.cjs.map +1 -0
  44. package/dist/{chunk-2HZRBATX.cjs → chunk-FSKONGCX.cjs} +2 -2
  45. package/dist/chunk-FSKONGCX.cjs.map +1 -0
  46. package/dist/{chunk-P2HKJ7P5.js → chunk-GAAHG2Z4.js} +3 -3
  47. package/dist/{chunk-P2HKJ7P5.js.map → chunk-GAAHG2Z4.js.map} +1 -1
  48. package/dist/{chunk-PI73NNOK.cjs → chunk-GUUB5EAG.cjs} +2 -2
  49. package/dist/chunk-GUUB5EAG.cjs.map +1 -0
  50. package/dist/{chunk-PU2Z5VWF.js → chunk-IPTZM3VE.js} +183 -187
  51. package/dist/chunk-IPTZM3VE.js.map +1 -0
  52. package/dist/{chunk-UERVXYVK.cjs → chunk-NWUEVLQT.cjs} +13 -13
  53. package/dist/{chunk-UERVXYVK.cjs.map → chunk-NWUEVLQT.cjs.map} +1 -1
  54. package/dist/{chunk-KPA4AN4R.js → chunk-OHC6UHFY.js} +86 -12
  55. package/dist/chunk-OHC6UHFY.js.map +1 -0
  56. package/dist/{chunk-DEVFAKCQ.cjs → chunk-PHJRNPHY.cjs} +6 -6
  57. package/dist/chunk-PHJRNPHY.cjs.map +1 -0
  58. package/dist/{chunk-VO35MNPH.js → chunk-PQ72Z6WC.js} +67 -105
  59. package/dist/chunk-PQ72Z6WC.js.map +1 -0
  60. package/dist/{chunk-KNRSROWB.cjs → chunk-PV2I2KMI.cjs} +86 -12
  61. package/dist/chunk-PV2I2KMI.cjs.map +1 -0
  62. package/dist/{chunk-V2TVSCV5.cjs → chunk-Q23GAMLE.cjs} +71 -109
  63. package/dist/chunk-Q23GAMLE.cjs.map +1 -0
  64. package/dist/{chunk-COIASRDK.cjs → chunk-RFFSZSCL.cjs} +107 -171
  65. package/dist/chunk-RFFSZSCL.cjs.map +1 -0
  66. package/dist/{chunk-AL5KX63J.js → chunk-UUDTPZX6.js} +3 -3
  67. package/dist/chunk-UUDTPZX6.js.map +1 -0
  68. package/dist/{chunk-EJN2PAOE.js → chunk-V7KZQIZ6.js} +102 -166
  69. package/dist/chunk-V7KZQIZ6.js.map +1 -0
  70. package/dist/{chunk-DYTZ6FQ7.js → chunk-WXVB364T.js} +2 -2
  71. package/dist/chunk-WXVB364T.js.map +1 -0
  72. package/dist/{chunk-WNCYAKF3.cjs → chunk-Y7AQK4R4.cjs} +93 -9
  73. package/dist/chunk-Y7AQK4R4.cjs.map +1 -0
  74. package/dist/{chunk-SPBTLUN6.js → chunk-YFAVQQTU.js} +7 -7
  75. package/dist/{chunk-SPBTLUN6.js.map → chunk-YFAVQQTU.js.map} +1 -1
  76. package/dist/cli/index.cjs +5 -5
  77. package/dist/cli/index.js +5 -5
  78. package/dist/client.cjs +4 -4
  79. package/dist/client.d.cts +2 -2
  80. package/dist/client.d.ts +2 -2
  81. package/dist/client.js +2 -2
  82. package/dist/drizzle/index.cjs +14 -14
  83. package/dist/drizzle/index.d.cts +4 -10
  84. package/dist/drizzle/index.d.ts +4 -10
  85. package/dist/drizzle/index.js +5 -5
  86. package/dist/fields/index.cjs +22 -22
  87. package/dist/fields/index.d.cts +1 -1
  88. package/dist/fields/index.d.ts +1 -1
  89. package/dist/fields/index.js +2 -2
  90. package/dist/graphql/index.cjs +1 -1
  91. package/dist/graphql/index.d.cts +3 -3
  92. package/dist/graphql/index.d.ts +3 -3
  93. package/dist/graphql/index.js +1 -1
  94. package/dist/{index-CaTNnLGd.d.cts → index-BKta3cBH.d.cts} +3 -2
  95. package/dist/{index-CJXPB_ot.d.ts → index-ClOqnkTO.d.ts} +3 -2
  96. package/dist/index.cjs +117 -117
  97. package/dist/index.d.cts +10 -15
  98. package/dist/index.d.ts +10 -15
  99. package/dist/index.js +18 -18
  100. package/dist/integration.cjs +1 -1
  101. package/dist/integration.js +1 -1
  102. package/dist/media-7WDX4BDJ.js +4 -0
  103. package/dist/{media-GPPTZ43E.js.map → media-7WDX4BDJ.js.map} +1 -1
  104. package/dist/{media-XNTUFJZR.cjs → media-TUSLVRQ6.cjs} +3 -3
  105. package/dist/{media-XNTUFJZR.cjs.map → media-TUSLVRQ6.cjs.map} +1 -1
  106. package/dist/{mongo-auth-adapter-ISOM7FSS.cjs → mongo-auth-adapter-GT4S7SCU.cjs} +3 -3
  107. package/dist/{mongo-auth-adapter-ISOM7FSS.cjs.map → mongo-auth-adapter-GT4S7SCU.cjs.map} +1 -1
  108. package/dist/mongo-auth-adapter-M7VV4LNB.js +4 -0
  109. package/dist/{mongo-auth-adapter-MO6STCV3.js.map → mongo-auth-adapter-M7VV4LNB.js.map} +1 -1
  110. package/dist/mongodb/index.cjs +5 -5
  111. package/dist/mongodb/index.d.cts +4 -9
  112. package/dist/mongodb/index.d.ts +4 -9
  113. package/dist/mongodb/index.js +3 -3
  114. package/dist/postgres-auth-adapter-AFAPISH7.js +5 -0
  115. package/dist/{postgres-auth-adapter-DWDR7P5G.js.map → postgres-auth-adapter-AFAPISH7.js.map} +1 -1
  116. package/dist/postgres-auth-adapter-SFDTLONT.cjs +14 -0
  117. package/dist/{postgres-auth-adapter-WRWSJD4E.cjs.map → postgres-auth-adapter-SFDTLONT.cjs.map} +1 -1
  118. package/dist/{redis-adapter-KJ3YOOT6.cjs → redis-adapter-UQX4EE3B.cjs} +3 -3
  119. package/dist/{redis-adapter-KJ3YOOT6.cjs.map → redis-adapter-UQX4EE3B.cjs.map} +1 -1
  120. package/dist/redis-adapter-XALOGWY3.js +4 -0
  121. package/dist/{redis-adapter-HGTPWIGV.js.map → redis-adapter-XALOGWY3.js.map} +1 -1
  122. package/dist/rest/index.cjs +10 -10
  123. package/dist/rest/index.d.cts +4 -4
  124. package/dist/rest/index.d.ts +4 -4
  125. package/dist/rest/index.js +8 -8
  126. package/dist/{schema-TTFE4467.cjs → schema-6QL3USNB.cjs} +15 -15
  127. package/dist/{schema-TTFE4467.cjs.map → schema-6QL3USNB.cjs.map} +1 -1
  128. package/dist/{schema-6I5OFR4Z.js → schema-FNNWEAAW.js} +4 -4
  129. package/dist/{schema-6I5OFR4Z.js.map → schema-FNNWEAAW.js.map} +1 -1
  130. package/dist/{sqlite-adapter-CSIZE5SX.cjs → sqlite-adapter-AQB5TCGV.cjs} +3 -3
  131. package/dist/{sqlite-adapter-CSIZE5SX.cjs.map → sqlite-adapter-AQB5TCGV.cjs.map} +1 -1
  132. package/dist/sqlite-adapter-N5H6IM2X.js +4 -0
  133. package/dist/{sqlite-adapter-6GEUSVXQ.js.map → sqlite-adapter-N5H6IM2X.js.map} +1 -1
  134. package/dist/templates/index.cjs +49 -49
  135. package/dist/templates/index.d.cts +2 -2
  136. package/dist/templates/index.d.ts +2 -2
  137. package/dist/templates/index.js +2 -2
  138. package/dist/trpc/index.cjs +11 -11
  139. package/dist/trpc/index.d.cts +3 -3
  140. package/dist/trpc/index.d.ts +3 -3
  141. package/dist/trpc/index.js +2 -2
  142. package/dist/{types-Z6FBiqa2.d.cts → types-DeSApf9T.d.cts} +1 -0
  143. package/dist/{types-Z6FBiqa2.d.ts → types-DeSApf9T.d.ts} +1 -0
  144. package/dist/{types-CyCQ6SAI.d.ts → types-Dgzlftb7.d.ts} +6 -28
  145. package/dist/{types-DJxD9394.d.cts → types-Ds0tCA3L.d.cts} +6 -28
  146. package/dist/ws/index.cjs +6 -6
  147. package/dist/ws/index.js +2 -2
  148. package/package.json +1 -1
  149. package/dist/bootstrap-5NLASFOG.cjs +0 -32
  150. package/dist/bootstrap-T5BK77LD.js +0 -7
  151. package/dist/chunk-22M4O4ZJ.js.map +0 -1
  152. package/dist/chunk-2HZRBATX.cjs.map +0 -1
  153. package/dist/chunk-3TPQ2BU6.js.map +0 -1
  154. package/dist/chunk-5EPFQUQD.js.map +0 -1
  155. package/dist/chunk-AL5KX63J.js.map +0 -1
  156. package/dist/chunk-C36TMDTY.cjs.map +0 -1
  157. package/dist/chunk-COIASRDK.cjs.map +0 -1
  158. package/dist/chunk-DEVFAKCQ.cjs.map +0 -1
  159. package/dist/chunk-DVD5P72E.cjs.map +0 -1
  160. package/dist/chunk-DYTZ6FQ7.js.map +0 -1
  161. package/dist/chunk-EJN2PAOE.js.map +0 -1
  162. package/dist/chunk-FAXU7BMP.js.map +0 -1
  163. package/dist/chunk-FOPGUM27.js.map +0 -1
  164. package/dist/chunk-JOPVMWTM.cjs.map +0 -1
  165. package/dist/chunk-KNRSROWB.cjs.map +0 -1
  166. package/dist/chunk-KPA4AN4R.js.map +0 -1
  167. package/dist/chunk-PI73NNOK.cjs.map +0 -1
  168. package/dist/chunk-PU2Z5VWF.js.map +0 -1
  169. package/dist/chunk-ROJHKAQ4.cjs.map +0 -1
  170. package/dist/chunk-RSF3UU7H.cjs.map +0 -1
  171. package/dist/chunk-TXSZFA4G.js.map +0 -1
  172. package/dist/chunk-V2TVSCV5.cjs.map +0 -1
  173. package/dist/chunk-VO35MNPH.js.map +0 -1
  174. package/dist/chunk-WNCYAKF3.cjs.map +0 -1
  175. package/dist/media-GPPTZ43E.js +0 -4
  176. package/dist/mongo-auth-adapter-MO6STCV3.js +0 -4
  177. package/dist/postgres-auth-adapter-DWDR7P5G.js +0 -5
  178. package/dist/postgres-auth-adapter-WRWSJD4E.cjs +0 -14
  179. package/dist/redis-adapter-HGTPWIGV.js +0 -4
  180. package/dist/sqlite-adapter-6GEUSVXQ.js +0 -4
@@ -1,17 +1,17 @@
1
1
  'use strict';
2
2
 
3
- var chunkWNCYAKF3_cjs = require('./chunk-WNCYAKF3.cjs');
3
+ 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
7
  var chunkQFLB4EIJ_cjs = require('./chunk-QFLB4EIJ.cjs');
8
8
  var chunk4M7X5HAB_cjs = require('./chunk-4M7X5HAB.cjs');
9
- var chunkCOIASRDK_cjs = require('./chunk-COIASRDK.cjs');
10
- var chunkC36TMDTY_cjs = require('./chunk-C36TMDTY.cjs');
11
- var chunkV2TVSCV5_cjs = require('./chunk-V2TVSCV5.cjs');
9
+ var chunkRFFSZSCL_cjs = require('./chunk-RFFSZSCL.cjs');
10
+ var chunk7OS7TX2Q_cjs = require('./chunk-7OS7TX2Q.cjs');
11
+ var chunkQ23GAMLE_cjs = require('./chunk-Q23GAMLE.cjs');
12
12
  var chunkGXFOGU7N_cjs = require('./chunk-GXFOGU7N.cjs');
13
13
  var chunkNKPKR5BW_cjs = require('./chunk-NKPKR5BW.cjs');
14
- var chunkG7VZBCD6_cjs = require('./chunk-G7VZBCD6.cjs');
14
+ var chunkCZLDE2OZ_cjs = require('./chunk-CZLDE2OZ.cjs');
15
15
  var crypto = require('crypto');
16
16
  var unstorage = require('unstorage');
17
17
  var fsDriver = require('unstorage/drivers/fs');
@@ -22,6 +22,7 @@ var sharp = require('sharp');
22
22
  var promises = require('fs/promises');
23
23
  var process2 = require('process');
24
24
  var clientS3 = require('@aws-sdk/client-s3');
25
+ var nodeHttpHandler = require('@smithy/node-http-handler');
25
26
  var stream = require('stream');
26
27
  var basicFtp = require('basic-ftp');
27
28
  var zodToJsonSchema = require('zod-to-json-schema');
@@ -41,8 +42,8 @@ async function loadSecrets() {
41
42
  if (dbAdapter) {
42
43
  try {
43
44
  const result = await dbAdapter.findOne({
44
- collection: "_globals",
45
- where: { slug: "system" }
45
+ collection: "_globals_system",
46
+ where: {}
46
47
  });
47
48
  if (result) {
48
49
  cachedSecrets = {
@@ -91,7 +92,7 @@ function getSessionConfig() {
91
92
  };
92
93
  }
93
94
  var dbAdapter, cachedSecrets;
94
- var init_secret = chunkG7VZBCD6_cjs.__esm({
95
+ var init_secret = chunkCZLDE2OZ_cjs.__esm({
95
96
  "src/lib/secret.ts"() {
96
97
  dbAdapter = null;
97
98
  cachedSecrets = null;
@@ -100,7 +101,7 @@ var init_secret = chunkG7VZBCD6_cjs.__esm({
100
101
 
101
102
  // src/api/rest/auth-session.ts
102
103
  var auth_session_exports = {};
103
- chunkG7VZBCD6_cjs.__export(auth_session_exports, {
104
+ chunkCZLDE2OZ_cjs.__export(auth_session_exports, {
104
105
  SESSION_CONFIG: () => SESSION_CONFIG,
105
106
  clearSessionCookie: () => clearSessionCookie,
106
107
  createSession: () => createSession,
@@ -366,7 +367,7 @@ async function getCurrentUser(request) {
366
367
  return session;
367
368
  }
368
369
  var sessionConfig, SESSION_CONFIG, SESSION_COOKIE_NAME, storage;
369
- var init_auth_session = chunkG7VZBCD6_cjs.__esm({
370
+ var init_auth_session = chunkCZLDE2OZ_cjs.__esm({
370
371
  "src/api/rest/auth-session.ts"() {
371
372
  init_secret();
372
373
  sessionConfig = getSessionConfig();
@@ -452,6 +453,9 @@ function createTenantContextFromUser(user) {
452
453
  };
453
454
  }
454
455
 
456
+ // src/api/rest/hono-app.ts
457
+ init_secret();
458
+
455
459
  // src/auth/security/in-memory-rate-limit.ts
456
460
  var InMemoryRateLimiter = class {
457
461
  storage = /* @__PURE__ */ new Map();
@@ -959,7 +963,7 @@ var AuthRoutes = class {
959
963
  constructor(config) {
960
964
  this.authAdapter = config.redis;
961
965
  this.email = config.email;
962
- this.passwordPolicy = config.passwordPolicy || new chunkWNCYAKF3_cjs.PasswordPolicy();
966
+ this.passwordPolicy = config.passwordPolicy || new chunkY7AQK4R4_cjs.PasswordPolicy();
963
967
  this.lockout = config.lockout;
964
968
  this.rateLimiter = config.rateLimiter;
965
969
  this.auditLogger = config.auditLogger;
@@ -1450,7 +1454,7 @@ var AuthRoutes = class {
1450
1454
  return this.errorResponse("No session", 401);
1451
1455
  }
1452
1456
  try {
1453
- const updatedSession = await (init_auth_session(), chunkG7VZBCD6_cjs.__toCommonJS(auth_session_exports)).refreshSession(sessionId, req);
1457
+ const updatedSession = await (init_auth_session(), chunkCZLDE2OZ_cjs.__toCommonJS(auth_session_exports)).refreshSession(sessionId, req);
1454
1458
  if (!updatedSession) {
1455
1459
  return this.errorResponse("Session not found", 404);
1456
1460
  }
@@ -2233,7 +2237,7 @@ function createS3Storage(config) {
2233
2237
  tls: true,
2234
2238
  // R2 requires specific SSL configuration
2235
2239
  ...config.provider === "r2" && {
2236
- requestHandler: new (chunkG7VZBCD6_cjs.__require("@smithy/node-http-handler")).NodeHttpHandler({
2240
+ requestHandler: new nodeHttpHandler.NodeHttpHandler({
2237
2241
  connectionTimeout: 1e4,
2238
2242
  socketTimeout: 1e4
2239
2243
  })
@@ -2848,17 +2852,15 @@ var MediaService = class _MediaService {
2848
2852
  this.db = db;
2849
2853
  this.storage = storage2;
2850
2854
  this.dialect = options?.dialect || "sqlite";
2851
- this.genId = options?.genId || chunkCOIASRDK_cjs.genId;
2855
+ this.genId = options?.genId || chunkRFFSZSCL_cjs.genId;
2852
2856
  }
2853
2857
  static async init(db, options) {
2854
2858
  let storage2;
2855
2859
  if (options?.storageConfig) {
2856
2860
  storage2 = await resolveProviderWithConfig(options.storageConfig);
2857
2861
  } else {
2858
- const configService = new chunkWNCYAKF3_cjs.ConfigService(db);
2859
- if (typeof db?.select === "function") {
2860
- await configService.load();
2861
- }
2862
+ const configService = new chunkY7AQK4R4_cjs.ConfigService(db);
2863
+ await configService.load();
2862
2864
  storage2 = await resolveProvider(configService);
2863
2865
  }
2864
2866
  const service = new _MediaService(db, storage2, options);
@@ -3060,7 +3062,7 @@ var MediaService = class _MediaService {
3060
3062
  ]
3061
3063
  );
3062
3064
  } else {
3063
- const { media: mediaSchema } = await import('./media-XNTUFJZR.cjs');
3065
+ const { media: mediaSchema } = await import('./media-TUSLVRQ6.cjs');
3064
3066
  const mime = storageResult.mimeType;
3065
3067
  const mediaType = mime.startsWith("image/") ? "image" : mime.startsWith("video/") ? "video" : mime.startsWith("audio/") ? "audio" : mime.startsWith("application/pdf") ? "document" : ["application/zip", "application/x-zip", "application/x-tar", "application/gzip", "application/x-7z"].includes(mime) ? "archive" : "other";
3066
3068
  await this.db.insert(mediaSchema).values({
@@ -3122,7 +3124,7 @@ var MediaService = class _MediaService {
3122
3124
  id
3123
3125
  ]);
3124
3126
  } else {
3125
- const { media: mediaSchema } = await import('./media-XNTUFJZR.cjs');
3127
+ const { media: mediaSchema } = await import('./media-TUSLVRQ6.cjs');
3126
3128
  const { eq } = await import('drizzle-orm');
3127
3129
  const [row] = await this.db.select().from(mediaSchema).where(eq(mediaSchema.id, id));
3128
3130
  if (row) item = this.rowToMedia(row);
@@ -3138,7 +3140,7 @@ var MediaService = class _MediaService {
3138
3140
  if (this.dialect === "sqlite") {
3139
3141
  await this.sqliteRun(`DELETE FROM ${this.mediaTable} WHERE id = ?`, [id]);
3140
3142
  } else {
3141
- const { media: mediaSchema } = await import('./media-XNTUFJZR.cjs');
3143
+ const { media: mediaSchema } = await import('./media-TUSLVRQ6.cjs');
3142
3144
  const { eq } = await import('drizzle-orm');
3143
3145
  await this.db.delete(mediaSchema).where(eq(mediaSchema.id, id));
3144
3146
  }
@@ -3153,7 +3155,7 @@ var MediaService = class _MediaService {
3153
3155
  id
3154
3156
  ]);
3155
3157
  } else {
3156
- const { media: mediaSchema } = await import('./media-XNTUFJZR.cjs');
3158
+ const { media: mediaSchema } = await import('./media-TUSLVRQ6.cjs');
3157
3159
  const { eq } = await import('drizzle-orm');
3158
3160
  const [row] = await this.db.select().from(mediaSchema).where(eq(mediaSchema.id, id));
3159
3161
  if (row) item = this.rowToMedia(row);
@@ -3188,7 +3190,7 @@ var MediaService = class _MediaService {
3188
3190
  [...vals, this.now(), id]
3189
3191
  );
3190
3192
  } else {
3191
- const { media: mediaSchema } = await import('./media-XNTUFJZR.cjs');
3193
+ const { media: mediaSchema } = await import('./media-TUSLVRQ6.cjs');
3192
3194
  const { eq } = await import('drizzle-orm');
3193
3195
  await this.db.update(mediaSchema).set({ ...updateData, updatedAt: this.now() }).where(eq(mediaSchema.id, id));
3194
3196
  }
@@ -3207,7 +3209,7 @@ var MediaService = class _MediaService {
3207
3209
  );
3208
3210
  return row2 ? this.rowToMedia(row2) : null;
3209
3211
  }
3210
- const { media: mediaSchema } = await import('./media-XNTUFJZR.cjs');
3212
+ const { media: mediaSchema } = await import('./media-TUSLVRQ6.cjs');
3211
3213
  const { eq } = await import('drizzle-orm');
3212
3214
  const [row] = await this.db.select().from(mediaSchema).where(eq(mediaSchema.id, id));
3213
3215
  return row ? this.rowToMedia(row) : null;
@@ -3255,7 +3257,7 @@ var MediaService = class _MediaService {
3255
3257
  totalPages: Math.ceil(totalDocs2 / limit)
3256
3258
  };
3257
3259
  }
3258
- const { media: mediaSchema } = await import('./media-XNTUFJZR.cjs');
3260
+ const { media: mediaSchema } = await import('./media-TUSLVRQ6.cjs');
3259
3261
  const { like, or, and, asc, desc, eq, sql } = await import('drizzle-orm');
3260
3262
  const conditions = [];
3261
3263
  if (search) {
@@ -3334,7 +3336,7 @@ var MediaService = class _MediaService {
3334
3336
  );
3335
3337
  return row ? this.rowToMedia(row) : null;
3336
3338
  }
3337
- const { media: mediaSchema } = await import('./media-XNTUFJZR.cjs');
3339
+ const { media: mediaSchema } = await import('./media-TUSLVRQ6.cjs');
3338
3340
  const { eq } = await import('drizzle-orm');
3339
3341
  const [updated] = await this.db.update(mediaSchema).set({ ...data, updatedAt: /* @__PURE__ */ new Date() }).where(eq(mediaSchema.id, id)).returning();
3340
3342
  return updated ? this.rowToMedia(updated) : null;
@@ -3356,7 +3358,7 @@ var MediaService = class _MediaService {
3356
3358
  );
3357
3359
  }
3358
3360
  } else {
3359
- const { media: mediaSchema } = await import('./media-XNTUFJZR.cjs');
3361
+ const { media: mediaSchema } = await import('./media-TUSLVRQ6.cjs');
3360
3362
  const { eq } = await import('drizzle-orm');
3361
3363
  for (const id of ids) {
3362
3364
  await this.db.update(mediaSchema).set({ ...data, updatedAt: /* @__PURE__ */ new Date() }).where(eq(mediaSchema.id, id));
@@ -3371,7 +3373,7 @@ var MediaService = class _MediaService {
3371
3373
  );
3372
3374
  return rows.map((r) => r.path).filter((f) => f && f !== "").sort();
3373
3375
  }
3374
- const { media: mediaSchema, mediaFolders: folderSchema } = await import('./media-XNTUFJZR.cjs');
3376
+ const { media: mediaSchema, mediaFolders: folderSchema } = await import('./media-TUSLVRQ6.cjs');
3375
3377
  const { eq, sql } = await import('drizzle-orm');
3376
3378
  const fromMedia = await this.db.select({ folder: mediaSchema.folder }).from(mediaSchema).groupBy(mediaSchema.folder);
3377
3379
  const fromFolders = await this.db.select({ path: folderSchema.path }).from(folderSchema);
@@ -3391,7 +3393,7 @@ var MediaService = class _MediaService {
3391
3393
  [fullPath, name, parentPath || null, now]
3392
3394
  );
3393
3395
  } else {
3394
- const { mediaFolders: folderSchema } = await import('./media-XNTUFJZR.cjs');
3396
+ const { mediaFolders: folderSchema } = await import('./media-TUSLVRQ6.cjs');
3395
3397
  await this.db.insert(folderSchema).values({
3396
3398
  path: fullPath,
3397
3399
  name,
@@ -3412,7 +3414,7 @@ var MediaService = class _MediaService {
3412
3414
  [folder, `${folder}/%`]
3413
3415
  );
3414
3416
  } else {
3415
- const { mediaFolders: folderSchema } = await import('./media-XNTUFJZR.cjs');
3417
+ const { mediaFolders: folderSchema } = await import('./media-TUSLVRQ6.cjs');
3416
3418
  const { like, or, eq } = await import('drizzle-orm');
3417
3419
  await this.db.delete(folderSchema).where(
3418
3420
  or(
@@ -3426,6 +3428,38 @@ var MediaService = class _MediaService {
3426
3428
  function formatZodErrors(errors) {
3427
3429
  return errors.map((e) => `${e.path.join(".")}: ${e.message}`).join(", ");
3428
3430
  }
3431
+ function normalizeEmptyStrings(data, fields) {
3432
+ if (!data || typeof data !== "object") return;
3433
+ for (const field of fields) {
3434
+ if (!field.name || !(field.name in data)) continue;
3435
+ const val = data[field.name];
3436
+ if (val === "") {
3437
+ const isTextual = field.type === "text" || field.type === "textarea" || field.type === "code" || field.type === "markdown" || field.type === "email" || field.type === "password" || field.type === "color";
3438
+ if (!isTextual) data[field.name] = null;
3439
+ }
3440
+ if (field.type === "tabs" && field.name && Array.isArray(field.tabs) && data[field.name] && typeof data[field.name] === "object") {
3441
+ for (const tab of field.tabs) {
3442
+ if (Array.isArray(tab.fields)) normalizeEmptyStrings(data[field.name], tab.fields);
3443
+ }
3444
+ } else if ((field.type === "group" || field.type === "collapsible") && field.name && Array.isArray(field.fields) && data[field.name] && typeof data[field.name] === "object") {
3445
+ normalizeEmptyStrings(data[field.name], field.fields);
3446
+ } else if (field.type === "array" && field.name && Array.isArray(field.fields) && Array.isArray(data[field.name])) {
3447
+ for (const item of data[field.name]) {
3448
+ if (item && typeof item === "object") normalizeEmptyStrings(item, field.fields);
3449
+ }
3450
+ } else if (field.type === "blocks" && field.name && Array.isArray(field.blocks) && Array.isArray(data[field.name])) {
3451
+ for (const item of data[field.name]) {
3452
+ if (!item || typeof item !== "object") continue;
3453
+ const blockTypeStr = item.type || item.blockType;
3454
+ if (!blockTypeStr) continue;
3455
+ const blockDef = field.blocks.find((b) => b.slug === blockTypeStr);
3456
+ if (!blockDef || !Array.isArray(blockDef.fields)) continue;
3457
+ const target = item.data && typeof item.data === "object" ? item.data : item;
3458
+ normalizeEmptyStrings(target, blockDef.fields);
3459
+ }
3460
+ }
3461
+ }
3462
+ }
3429
3463
  function convertRichtextFields(fields, data) {
3430
3464
  if (!data || typeof data !== "object") return;
3431
3465
  for (const field of fields) {
@@ -3447,6 +3481,16 @@ function convertRichtextFields(fields, data) {
3447
3481
  for (const item of data[field.name]) {
3448
3482
  if (item && typeof item === "object") convertRichtextFields(field.fields, item);
3449
3483
  }
3484
+ } else if (field.type === "blocks" && field.name && Array.isArray(field.blocks) && Array.isArray(data[field.name])) {
3485
+ for (const item of data[field.name]) {
3486
+ if (!item || typeof item !== "object") continue;
3487
+ const blockTypeStr = item.type || item.blockType;
3488
+ if (!blockTypeStr) continue;
3489
+ const blockDef = field.blocks.find((b) => b.slug === blockTypeStr);
3490
+ if (!blockDef || !Array.isArray(blockDef.fields)) continue;
3491
+ const target = item.data && typeof item.data === "object" ? item.data : item;
3492
+ convertRichtextFields(blockDef.fields, target);
3493
+ }
3450
3494
  }
3451
3495
  }
3452
3496
  }
@@ -3543,7 +3587,7 @@ async function checkCollectionAccess(collection, operation, req, ctxUser, ctxTen
3543
3587
  };
3544
3588
  }
3545
3589
  }
3546
- if (ctxUser) {
3590
+ if (ctxUser && !(apiKeyContext?.permissions?.length > 0)) {
3547
3591
  const resource = collection.slug;
3548
3592
  const action = operation === "read" ? "read" : operation === "create" ? "create" : operation === "update" ? "update" : "delete";
3549
3593
  const permission = `${resource}:${action}`;
@@ -3629,10 +3673,10 @@ async function resolveAuthContext(req, authMw, staticUser, staticTenantID) {
3629
3673
  };
3630
3674
  }
3631
3675
  function createDefaultAuthAdapter(db, rootDir) {
3632
- if (db instanceof chunkCOIASRDK_cjs.DrizzleAdapter && db.dialect === "postgres") {
3633
- return new chunkC36TMDTY_cjs.PostgresAuthAdapter({ db: db.client });
3676
+ if (db instanceof chunkRFFSZSCL_cjs.DrizzleAdapter && db.dialect === "postgres") {
3677
+ return new chunk7OS7TX2Q_cjs.PostgresAuthAdapter({ db: db.client });
3634
3678
  }
3635
- if (db instanceof chunkV2TVSCV5_cjs.MongoDBAdapter) {
3679
+ if (db instanceof chunkQ23GAMLE_cjs.MongoDBAdapter) {
3636
3680
  return new chunkGXFOGU7N_cjs.MongoDBAuthAdapter({ db: db.db });
3637
3681
  }
3638
3682
  const defaultAuthDbPath = path.resolve(rootDir, "data", "kyro.db");
@@ -3739,6 +3783,13 @@ function createHonoApp(options) {
3739
3783
  baseUrl: process.env.KYRO_BASE_URL || "http://localhost:4321",
3740
3784
  rateLimiter
3741
3785
  });
3786
+ chunkY7AQK4R4_cjs.EmailTransport.fromConfig(db).then((transport) => {
3787
+ if (transport) {
3788
+ authRoutes.email = transport;
3789
+ }
3790
+ }).catch((err) => {
3791
+ console.error("[Email] Failed to initialize transport from config:", err);
3792
+ });
3742
3793
  app.post("/api/auth/login", async (c) => authRoutes.login(c.req.raw));
3743
3794
  app.post("/api/auth/register", async (c) => authRoutes.register(c.req.raw));
3744
3795
  app.post("/api/auth/logout", async (c) => authRoutes.logout(c.req.raw));
@@ -4137,8 +4188,8 @@ function createHonoApp(options) {
4137
4188
  }
4138
4189
  if (!mediaService) {
4139
4190
  try {
4140
- const dialect = db instanceof chunkCOIASRDK_cjs.DrizzleAdapter ? db.dialect : "sqlite";
4141
- const mediaDb = dialect === "postgres" && db instanceof chunkCOIASRDK_cjs.DrizzleAdapter ? db.client : db;
4191
+ const dialect = db instanceof chunkRFFSZSCL_cjs.DrizzleAdapter ? db.dialect : "sqlite";
4192
+ const mediaDb = dialect === "postgres" && db instanceof chunkRFFSZSCL_cjs.DrizzleAdapter ? db.client : db;
4142
4193
  mediaService = await MediaService.init(mediaDb, { dialect });
4143
4194
  } catch (error) {
4144
4195
  console.error("[getMedia] Init error:", error);
@@ -4814,15 +4865,13 @@ function createHonoApp(options) {
4814
4865
  });
4815
4866
  app.get("/api/keys", async (c) => {
4816
4867
  try {
4817
- const { user: ctxUser } = await resolveAuthContext(c.req.raw, authMw, user, tenantID);
4868
+ const { user: ctxUser, tenantID: ctxTenantID } = await resolveAuthContext(c.req.raw, authMw, user, tenantID);
4818
4869
  if (!ctxUser || !chunkNKPKR5BW_cjs.hasPermission(ctxUser, "users:read")) {
4819
4870
  return c.json({ error: "Forbidden" }, 403);
4820
4871
  }
4821
4872
  const page = parseInt(c.req.query("page") || "1");
4822
4873
  const limit = Math.min(parseInt(c.req.query("limit") || "50"), 100);
4823
- console.log("[ApiKeys] Querying", chunk4M7X5HAB_cjs.API_KEY_COLLECTION, { page, limit });
4824
- const result = await db.find({ collection: chunk4M7X5HAB_cjs.API_KEY_COLLECTION, where: {}, page, limit });
4825
- console.log("[ApiKeys] Result:", result);
4874
+ const result = await db.find({ collection: chunk4M7X5HAB_cjs.API_KEY_COLLECTION, where: {}, page, limit, tenantID: ctxTenantID });
4826
4875
  const docs = (result.docs || []).map((doc) => ({
4827
4876
  id: doc.id,
4828
4877
  name: doc.name,
@@ -5215,36 +5264,6 @@ function createHonoApp(options) {
5215
5264
  return c.json({ error: error.message }, 500);
5216
5265
  }
5217
5266
  });
5218
- app.get(`${basePath}/:id/draft`, async (c) => {
5219
- try {
5220
- const {
5221
- user: ctxUser,
5222
- tenantID: ctxTenantID,
5223
- apiKeyContext
5224
- } = await resolveAuthContext(c.req.raw, authMw, user, tenantID);
5225
- const access = await checkCollectionAccess(
5226
- collection,
5227
- "read",
5228
- c.req.raw,
5229
- ctxUser,
5230
- ctxTenantID,
5231
- apiKeyContext,
5232
- enablePublicAccess,
5233
- defaultCollectionAccess
5234
- );
5235
- if (!access.allowed) {
5236
- return c.json({ error: access.error }, access.status || 403);
5237
- }
5238
- const draft = await db.findDraft({
5239
- collection: slug,
5240
- documentId: c.req.param("id"),
5241
- tenantID: ctxTenantID
5242
- });
5243
- return c.json({ data: draft });
5244
- } catch (error) {
5245
- return c.json({ error: error.message }, 500);
5246
- }
5247
- });
5248
5267
  app.put(`${basePath}/:id/draft`, async (c) => {
5249
5268
  try {
5250
5269
  const {
@@ -5283,13 +5302,12 @@ function createHonoApp(options) {
5283
5302
  } else {
5284
5303
  finalData = body.data ?? omitRevisionFields(body);
5285
5304
  }
5286
- const draft = await db.upsertDraft({
5305
+ const version = await db.updateLatestVersion({
5287
5306
  collection: slug,
5288
5307
  documentId: id,
5289
- tenantID: ctxTenantID,
5290
5308
  data: finalData,
5291
- baseUpdatedAt,
5292
- draftUpdatedAt: body.draftUpdatedAt
5309
+ status: "draft",
5310
+ tenantID: ctxTenantID
5293
5311
  });
5294
5312
  if (ctxUser) {
5295
5313
  sessionAuthAdapter?.createAuditLog({
@@ -5301,7 +5319,7 @@ function createHonoApp(options) {
5301
5319
  metadata: { type: "draft_save" }
5302
5320
  });
5303
5321
  }
5304
- return c.json({ data: draft, message: "Draft saved successfully" });
5322
+ return c.json({ data: version, message: "Draft saved successfully" });
5305
5323
  } catch (error) {
5306
5324
  return c.json({ error: error.message }, 500);
5307
5325
  }
@@ -5326,11 +5344,6 @@ function createHonoApp(options) {
5326
5344
  if (!access.allowed) {
5327
5345
  return c.json({ error: access.error }, access.status || 403);
5328
5346
  }
5329
- await db.deleteDraft({
5330
- collection: slug,
5331
- documentId: c.req.param("id"),
5332
- tenantID: ctxTenantID
5333
- });
5334
5347
  if (ctxUser) {
5335
5348
  sessionAuthAdapter?.createAuditLog({
5336
5349
  action: "document_update",
@@ -5422,14 +5435,7 @@ function createHonoApp(options) {
5422
5435
  auditApiKeyUsage(sessionAuthAdapter, apiKeyContext, basePath, "POST", c.req.raw);
5423
5436
  const body = await c.req.json();
5424
5437
  let validated = body;
5425
- for (const field of collection.fields) {
5426
- if (field.name && validated[field.name] === "") {
5427
- const isTextual = field.type === "text" || field.type === "textarea" || field.type === "code" || field.type === "markdown" || field.type === "email" || field.type === "password" || field.type === "color";
5428
- if (!isTextual) {
5429
- validated[field.name] = null;
5430
- }
5431
- }
5432
- }
5438
+ normalizeEmptyStrings(validated, collection.fields);
5433
5439
  convertRichtextFields(collection.fields, validated);
5434
5440
  const hookReq = c.req.raw;
5435
5441
  if (collection.hooks?.beforeValidate) {
@@ -5455,10 +5461,7 @@ function createHonoApp(options) {
5455
5461
  validated.tenantID = ctxTenantID;
5456
5462
  }
5457
5463
  const isDraftEnabled = collection.versions?.drafts === true;
5458
- if (isDraftEnabled) {
5459
- validated.publishStatus = "draft";
5460
- validated.hasDraft = false;
5461
- }
5464
+ validated.status = isDraftEnabled ? "draft" : "published";
5462
5465
  if (collection.hooks?.beforeChange) {
5463
5466
  for (const hook of collection.hooks.beforeChange) {
5464
5467
  const hookResult = await hook({
@@ -5477,6 +5480,17 @@ function createHonoApp(options) {
5477
5480
  data: validated,
5478
5481
  tenantID: ctxTenantID
5479
5482
  });
5483
+ if (isDraftEnabled) {
5484
+ await db.createVersion({
5485
+ collection: slug,
5486
+ documentId: doc.id,
5487
+ data: validated,
5488
+ status: "draft",
5489
+ createdBy: ctxUser?.id,
5490
+ changeDescription: "Created",
5491
+ tenantID: ctxTenantID
5492
+ });
5493
+ }
5480
5494
  if (collection.hooks?.afterChange) {
5481
5495
  for (const hook of collection.hooks.afterChange) {
5482
5496
  await hook({
@@ -5542,11 +5556,6 @@ function createHonoApp(options) {
5542
5556
  const id = c.req.param("id");
5543
5557
  const body = await c.req.json();
5544
5558
  const baseUpdatedAt = readBaseUpdatedAt(body);
5545
- console.log(`[PATCH] ${slug}/${id}`, {
5546
- baseUpdatedAt,
5547
- bodyKeys: Object.keys(body),
5548
- tenantID: ctxTenantID
5549
- });
5550
5559
  const originalDoc = await db.findByID({
5551
5560
  collection: slug,
5552
5561
  id,
@@ -5564,14 +5573,7 @@ function createHonoApp(options) {
5564
5573
  ([_, v]) => v !== "null" && v !== void 0
5565
5574
  )
5566
5575
  );
5567
- for (const field of collection.fields) {
5568
- if (field.name && validated[field.name] === "") {
5569
- const isTextual = field.type === "text" || field.type === "textarea" || field.type === "code" || field.type === "markdown" || field.type === "email" || field.type === "password" || field.type === "color";
5570
- if (!isTextual) {
5571
- validated[field.name] = null;
5572
- }
5573
- }
5574
- }
5576
+ normalizeEmptyStrings(validated, collection.fields);
5575
5577
  convertRichtextFields(collection.fields, validated);
5576
5578
  const hookReq = c.req.raw;
5577
5579
  if (collection.hooks?.beforeValidate) {
@@ -5604,37 +5606,44 @@ function createHonoApp(options) {
5604
5606
  if (hookResult) Object.assign(validated, hookResult);
5605
5607
  }
5606
5608
  }
5607
- console.log(`[PATCH] Validated data:`, Object.keys(validated));
5609
+ const isDraft = c.req.header("X-Draft") === "true";
5608
5610
  const isDraftEnabled = collection.versions?.drafts === true;
5609
- const isAlreadyPublished = originalDoc.publishStatus === "published";
5611
+ const isAutosave = c.req.query("autosave") === "true";
5610
5612
  let doc;
5611
- if (isDraftEnabled && isAlreadyPublished) {
5613
+ if (isDraftEnabled && isDraft) {
5612
5614
  await db.createVersion({
5613
5615
  collection: slug,
5614
5616
  documentId: id,
5615
5617
  data: validated,
5616
5618
  status: "draft",
5619
+ autosave: isAutosave,
5617
5620
  createdBy: ctxUser?.id,
5618
- changeDescription: "Manual save (Draft)",
5621
+ changeDescription: isAutosave ? "Autosave" : "Draft saved",
5619
5622
  tenantID: ctxTenantID
5620
5623
  });
5624
+ } else if (isDraftEnabled) {
5621
5625
  await db.update({
5622
5626
  collection: slug,
5623
5627
  id,
5624
- data: { hasDraft: true },
5625
- // Keep old data, just set flag
5628
+ data: { ...validated, status: "published" },
5629
+ tenantID: ctxTenantID
5630
+ });
5631
+ await db.createVersion({
5632
+ collection: slug,
5633
+ documentId: id,
5634
+ data: validated,
5635
+ status: "published",
5636
+ createdBy: ctxUser?.id,
5637
+ changeDescription: "Published",
5626
5638
  tenantID: ctxTenantID
5627
5639
  });
5628
5640
  } else {
5629
- const saveData = isDraftEnabled ? { ...validated, publishStatus: "draft", hasDraft: false } : validated;
5630
- console.log(`[PATCH] About to call db.update for ${slug}/${id} with keys:`, Object.keys(saveData));
5631
5641
  await db.update({
5632
5642
  collection: slug,
5633
5643
  id,
5634
- data: saveData,
5644
+ data: validated,
5635
5645
  tenantID: ctxTenantID
5636
5646
  });
5637
- console.log(`[PATCH] db.update SUCCEEDED for ${slug}/${id}`);
5638
5647
  }
5639
5648
  doc = await db.findByID({
5640
5649
  collection: slug,
@@ -5642,25 +5651,6 @@ function createHonoApp(options) {
5642
5651
  tenantID: ctxTenantID,
5643
5652
  draft: true
5644
5653
  });
5645
- if (isDraftEnabled) {
5646
- if (!isAlreadyPublished) {
5647
- await db.createVersion({
5648
- collection: slug,
5649
- documentId: id,
5650
- data: validated,
5651
- status: "draft",
5652
- createdBy: ctxUser?.id,
5653
- changeDescription: "Manual save",
5654
- tenantID: ctxTenantID
5655
- });
5656
- }
5657
- } else {
5658
- await db.deleteDraft({
5659
- collection: slug,
5660
- documentId: id,
5661
- tenantID: ctxTenantID
5662
- });
5663
- }
5664
5654
  if (collection.hooks?.afterChange) {
5665
5655
  for (const hook of collection.hooks.afterChange) {
5666
5656
  await hook({
@@ -5732,7 +5722,6 @@ function createHonoApp(options) {
5732
5722
  db.setTenantContext({ tenantId: ctxTenantID, userId: ctxUser?.id ?? "", role: ctxUser?.role, isSuperAdmin: ctxUser?.role === "super_admin" });
5733
5723
  }
5734
5724
  const id = c.req.param("id");
5735
- console.log(`[DELETE] Deleting ${slug}/${id}`);
5736
5725
  const hookReq = c.req.raw;
5737
5726
  const originalDoc = await db.findByID({
5738
5727
  collection: slug,
@@ -5760,11 +5749,6 @@ function createHonoApp(options) {
5760
5749
  id,
5761
5750
  tenantID: ctxTenantID
5762
5751
  });
5763
- await db.deleteDraft({
5764
- collection: slug,
5765
- documentId: id,
5766
- tenantID: ctxTenantID
5767
- });
5768
5752
  if (collection.hooks?.afterDelete) {
5769
5753
  for (const hook of collection.hooks.afterDelete) {
5770
5754
  await hook({
@@ -5806,7 +5790,6 @@ function createHonoApp(options) {
5806
5790
  });
5807
5791
  app.post(`${basePath}/:id/duplicate`, async (c) => {
5808
5792
  try {
5809
- console.log(`[Duplicate] Request for ${slug}`);
5810
5793
  const {
5811
5794
  user: ctxUser,
5812
5795
  tenantID: ctxTenantID,
@@ -5823,11 +5806,9 @@ function createHonoApp(options) {
5823
5806
  defaultCollectionAccess
5824
5807
  );
5825
5808
  if (!access.allowed) {
5826
- console.log("[Duplicate] Access denied:", access.error);
5827
5809
  return c.json({ error: access.error }, access.status || 403);
5828
5810
  }
5829
5811
  const id = c.req.param("id");
5830
- console.log(`[Duplicate] ID: ${id}`);
5831
5812
  const originalDoc = await db.findByID({
5832
5813
  collection: slug,
5833
5814
  id,
@@ -5835,14 +5816,11 @@ function createHonoApp(options) {
5835
5816
  draft: true
5836
5817
  });
5837
5818
  if (!originalDoc) {
5838
- console.log("[Duplicate] Document not found");
5839
5819
  return c.json({ error: "Document not found" }, 404);
5840
5820
  }
5841
- console.log(`[Duplicate] Original doc:`, originalDoc);
5842
5821
  const { id: _oldId, createdAt: _oldCreated, updatedAt: _oldUpdated, ...docData } = originalDoc;
5843
5822
  const timestamp = Date.now().toString(36);
5844
5823
  const newSlug = `${originalDoc.slug || "document"}-copy-${timestamp}`;
5845
- console.log(`[Duplicate] New slug: ${newSlug}`);
5846
5824
  const newDoc = await db.create({
5847
5825
  collection: slug,
5848
5826
  data: {
@@ -5852,7 +5830,6 @@ function createHonoApp(options) {
5852
5830
  },
5853
5831
  tenantID: ctxTenantID
5854
5832
  });
5855
- console.log(`[Duplicate] Created successfully:`, newDoc.id);
5856
5833
  return c.json({ data: newDoc, message: "Document duplicated successfully" });
5857
5834
  } catch (error) {
5858
5835
  console.error("[Duplicate] Error:", error);
@@ -5892,7 +5869,7 @@ function createHonoApp(options) {
5892
5869
  const doc = await db.update({
5893
5870
  collection: slug,
5894
5871
  id,
5895
- data: { ...version.data, publishStatus: "draft", hasDraft: false },
5872
+ data: { ...version.data, status: "draft" },
5896
5873
  tenantID: ctxTenantID
5897
5874
  });
5898
5875
  return c.json({
@@ -5937,7 +5914,7 @@ function createHonoApp(options) {
5937
5914
  const doc = await db.update({
5938
5915
  collection: slug,
5939
5916
  id: c.req.param("id"),
5940
- data: { ...version.data, publishStatus: "draft", hasDraft: false },
5917
+ data: { ...version.data, status: "draft" },
5941
5918
  tenantID: ctxTenantID
5942
5919
  });
5943
5920
  return c.json({
@@ -5988,9 +5965,9 @@ function createHonoApp(options) {
5988
5965
  if (baseUpdatedAt && originalDoc.updatedAt && baseUpdatedAt !== originalDoc.updatedAt) {
5989
5966
  return c.json(buildConflictResponse(baseUpdatedAt, originalDoc), 409);
5990
5967
  }
5991
- let publishData = { publishStatus: "published", hasDraft: false };
5968
+ let publishData = { status: "published" };
5992
5969
  let finalContent = originalDoc;
5993
- if (originalDoc.hasDraft) {
5970
+ if (collection.versions?.drafts) {
5994
5971
  const versions = await db.findVersions({
5995
5972
  collection: slug,
5996
5973
  documentId: id,
@@ -5998,9 +5975,10 @@ function createHonoApp(options) {
5998
5975
  sort: "-createdAt",
5999
5976
  tenantID: ctxTenantID
6000
5977
  });
6001
- if (versions.docs.length > 0 && versions.docs[0].status === "draft") {
6002
- finalContent = { ...originalDoc, ...versions.docs[0].data };
6003
- publishData = { ...versions.docs[0].data, ...publishData };
5978
+ if (versions.docs.length > 0) {
5979
+ const latestVersion = versions.docs[0];
5980
+ finalContent = { ...originalDoc, ...latestVersion.data };
5981
+ publishData = { ...latestVersion.data, ...publishData };
6004
5982
  }
6005
5983
  }
6006
5984
  const doc = await db.update({
@@ -6013,18 +5991,13 @@ function createHonoApp(options) {
6013
5991
  await db.createVersion({
6014
5992
  collection: slug,
6015
5993
  documentId: id,
6016
- data: { ...finalContent, publishStatus: "published" },
5994
+ data: { ...finalContent, status: "published" },
6017
5995
  status: "published",
6018
5996
  createdBy: ctxUser?.id,
6019
5997
  changeDescription: "Published",
6020
5998
  tenantID: ctxTenantID
6021
5999
  });
6022
6000
  }
6023
- await db.deleteDraft({
6024
- collection: slug,
6025
- documentId: id,
6026
- tenantID: ctxTenantID
6027
- });
6028
6001
  if (webhookService) {
6029
6002
  webhookService.trigger(getWebhookEvent(slug, "update"), {
6030
6003
  collection: slug,
@@ -6072,7 +6045,7 @@ function createHonoApp(options) {
6072
6045
  const doc = await db.update({
6073
6046
  collection: slug,
6074
6047
  id,
6075
- data: { publishStatus: "draft" },
6048
+ data: { status: "draft" },
6076
6049
  tenantID: ctxTenantID
6077
6050
  });
6078
6051
  if (webhookService) {
@@ -6107,7 +6080,7 @@ function createHonoApp(options) {
6107
6080
  if (!access.allowed) {
6108
6081
  return c.json({ error: access.error }, access.status || 403);
6109
6082
  }
6110
- const isDraftRequest = c.req.query("draft") === "true" && !!ctxUser;
6083
+ const isDraftRequest = !!ctxUser;
6111
6084
  let doc = await db.findOne({
6112
6085
  collection: `_globals_${slug}`,
6113
6086
  where: {},
@@ -6155,23 +6128,16 @@ function createHonoApp(options) {
6155
6128
  const cleaned = Object.fromEntries(
6156
6129
  Object.entries(body).filter(([_, v]) => v !== null && v !== "null" && v !== void 0)
6157
6130
  );
6158
- for (const field of globalConfig.fields) {
6159
- if (field.name && cleaned[field.name] === "") {
6160
- const isTextual = field.type === "text" || field.type === "textarea" || field.type === "code" || field.type === "markdown" || field.type === "email" || field.type === "password" || field.type === "color";
6161
- if (!isTextual) {
6162
- cleaned[field.name] = null;
6163
- }
6164
- }
6165
- }
6131
+ normalizeEmptyStrings(cleaned, globalConfig.fields);
6166
6132
  convertRichtextFields(globalConfig.fields, cleaned);
6167
- const schema = registry.getZodSchema(slug);
6133
+ const schema = registry.getUpdateZodSchema(slug);
6168
6134
  let validated;
6169
6135
  try {
6170
6136
  validated = schema.parse(cleaned);
6171
6137
  } catch (zodErr) {
6172
6138
  return c.json({ error: `Validation failed: ${formatZodErrors(zodErr.errors)}`, details: zodErr.errors }, 400);
6173
6139
  }
6174
- const SYSTEM_FIELDS = /* @__PURE__ */ new Set(["id", "createdAt", "updatedAt", "publishStatus", "hasDraft", "baseUpdatedAt", "_baseUpdatedAt"]);
6140
+ const SYSTEM_FIELDS = /* @__PURE__ */ new Set(["id", "createdAt", "updatedAt", "status", "baseUpdatedAt", "_baseUpdatedAt"]);
6175
6141
  const userData = Object.fromEntries(
6176
6142
  Object.entries(validated).filter(([k]) => !SYSTEM_FIELDS.has(k))
6177
6143
  );
@@ -6182,49 +6148,68 @@ function createHonoApp(options) {
6182
6148
  tenantID: ctxTenantID,
6183
6149
  draft: true
6184
6150
  });
6151
+ const isDraft = c.req.header("X-Draft") === "true";
6185
6152
  const isDraftEnabled = globalConfig.versions?.drafts === true;
6186
- const isAlreadyPublished = originalDoc?.publishStatus === "published";
6153
+ const isAutosave = c.req.query("autosave") === "true";
6187
6154
  let doc;
6188
- if (isDraftEnabled && isAlreadyPublished) {
6155
+ if (isDraftEnabled && isDraft) {
6189
6156
  await db.createVersion({
6190
6157
  collection: collectionSlug,
6191
6158
  documentId: slug,
6192
6159
  data: userData,
6193
6160
  status: "draft",
6161
+ autosave: isAutosave,
6194
6162
  createdBy: ctxUser?.id,
6195
- changeDescription: "Manual save (Draft)",
6163
+ changeDescription: isAutosave ? "Autosave" : "Manual save",
6196
6164
  tenantID: ctxTenantID
6197
6165
  });
6198
- doc = await db.update({
6199
- collection: collectionSlug,
6200
- id: slug,
6201
- data: { hasDraft: true },
6202
- tenantID: ctxTenantID
6203
- });
6204
- } else {
6205
- const saveData = isDraftEnabled ? { ...userData, publishStatus: "draft", hasDraft: false } : { ...userData, publishStatus: "published", hasDraft: false };
6166
+ if (!originalDoc) {
6167
+ doc = await db.create({
6168
+ collection: collectionSlug,
6169
+ data: { ...userData, id: slug, status: "draft" },
6170
+ tenantID: ctxTenantID
6171
+ });
6172
+ } else {
6173
+ doc = originalDoc;
6174
+ }
6175
+ } else if (isDraftEnabled && !isDraft) {
6176
+ const publishStatus = "published";
6206
6177
  if (originalDoc) {
6207
6178
  doc = await db.update({
6208
6179
  collection: collectionSlug,
6209
6180
  id: slug,
6210
- data: saveData,
6181
+ data: { ...userData, status: publishStatus },
6211
6182
  tenantID: ctxTenantID
6212
6183
  });
6213
6184
  } else {
6214
6185
  doc = await db.create({
6215
6186
  collection: collectionSlug,
6216
- data: { ...saveData, id: slug },
6187
+ data: { ...userData, id: slug, status: publishStatus },
6217
6188
  tenantID: ctxTenantID
6218
6189
  });
6219
6190
  }
6220
- if (isDraftEnabled) {
6221
- await db.createVersion({
6191
+ await db.createVersion({
6192
+ collection: collectionSlug,
6193
+ documentId: slug,
6194
+ data: userData,
6195
+ status: publishStatus,
6196
+ autosave: false,
6197
+ createdBy: ctxUser?.id,
6198
+ changeDescription: "Published",
6199
+ tenantID: ctxTenantID
6200
+ });
6201
+ } else {
6202
+ if (originalDoc) {
6203
+ doc = await db.update({
6222
6204
  collection: collectionSlug,
6223
- documentId: slug,
6205
+ id: slug,
6224
6206
  data: userData,
6225
- status: "draft",
6226
- createdBy: ctxUser?.id,
6227
- changeDescription: "Manual save",
6207
+ tenantID: ctxTenantID
6208
+ });
6209
+ } else {
6210
+ doc = await db.create({
6211
+ collection: collectionSlug,
6212
+ data: { ...userData, id: slug },
6228
6213
  tenantID: ctxTenantID
6229
6214
  });
6230
6215
  }
@@ -6233,6 +6218,13 @@ function createHonoApp(options) {
6233
6218
  mediaService = null;
6234
6219
  mediaServiceInitError = null;
6235
6220
  }
6221
+ if (slug === "email-settings") {
6222
+ const newEmailTransport = await chunkY7AQK4R4_cjs.EmailTransport.fromConfig(db);
6223
+ authRoutes.email = newEmailTransport || void 0;
6224
+ }
6225
+ if (slug === "system") {
6226
+ await loadSecrets();
6227
+ }
6236
6228
  if (ctxUser) {
6237
6229
  sessionAuthAdapter?.createAuditLog({
6238
6230
  action: "settings_change",
@@ -6266,9 +6258,9 @@ function createHonoApp(options) {
6266
6258
  draft: true
6267
6259
  });
6268
6260
  if (!originalDoc) return c.json({ error: "Global not found" }, 404);
6269
- let publishData = { publishStatus: "published", hasDraft: false };
6261
+ let publishData = { status: "published" };
6270
6262
  let finalContent = originalDoc;
6271
- if (originalDoc.hasDraft) {
6263
+ if (globalConfig.versions?.drafts) {
6272
6264
  const versions = await db.findVersions({
6273
6265
  collection: collectionSlug,
6274
6266
  documentId: slug,
@@ -6276,7 +6268,7 @@ function createHonoApp(options) {
6276
6268
  sort: "-createdAt",
6277
6269
  tenantID: ctxTenantID
6278
6270
  });
6279
- if (versions.docs.length > 0 && versions.docs[0].status === "draft") {
6271
+ if (versions.docs.length > 0) {
6280
6272
  finalContent = { ...originalDoc, ...versions.docs[0].data };
6281
6273
  publishData = { ...versions.docs[0].data, ...publishData };
6282
6274
  }
@@ -6291,7 +6283,7 @@ function createHonoApp(options) {
6291
6283
  await db.createVersion({
6292
6284
  collection: collectionSlug,
6293
6285
  documentId: slug,
6294
- data: { ...finalContent, publishStatus: "published" },
6286
+ data: { ...finalContent, status: "published" },
6295
6287
  status: "published",
6296
6288
  createdBy: ctxUser?.id,
6297
6289
  changeDescription: "Published",
@@ -6311,7 +6303,7 @@ function createHonoApp(options) {
6311
6303
  const doc = await db.update({
6312
6304
  collection: `_globals_${slug}`,
6313
6305
  id: slug,
6314
- data: { publishStatus: "draft", hasDraft: false },
6306
+ data: { status: "draft" },
6315
6307
  tenantID: ctxTenantID
6316
6308
  });
6317
6309
  return c.json({ data: doc, message: "Unpublished successfully" });
@@ -6371,9 +6363,13 @@ function createHonoApp(options) {
6371
6363
  const doc = await db.update({
6372
6364
  collection: collectionSlug,
6373
6365
  id: slug,
6374
- data: { ...version.data, publishStatus: "draft", hasDraft: false },
6366
+ data: { ...version.data, status: "draft" },
6375
6367
  tenantID: ctxTenantID
6376
6368
  });
6369
+ return c.json({
6370
+ data: doc,
6371
+ message: "Version restored successfully"
6372
+ });
6377
6373
  return c.json({ data: doc, message: "Restored successfully" });
6378
6374
  } catch (error) {
6379
6375
  return c.json({ error: error.message }, 500);
@@ -6417,7 +6413,7 @@ function createHonoApp(options) {
6417
6413
  mailgun: body.mailgun,
6418
6414
  ses: body.ses
6419
6415
  };
6420
- const transport = new chunkWNCYAKF3_cjs.EmailTransport(transportConfig);
6416
+ const transport = new chunkY7AQK4R4_cjs.EmailTransport(transportConfig);
6421
6417
  const recipient = body.testEmail || body.testEmailSection && body.testEmailSection.testEmail;
6422
6418
  if (!recipient) {
6423
6419
  return c.json({ error: "No test recipient email provided" }, 400);
@@ -6495,5 +6491,5 @@ exports.init_secret = init_secret;
6495
6491
  exports.loadSecrets = loadSecrets;
6496
6492
  exports.resolveProvider = resolveProvider;
6497
6493
  exports.setDbAdapter = setDbAdapter;
6498
- //# sourceMappingURL=chunk-RSF3UU7H.cjs.map
6499
- //# sourceMappingURL=chunk-RSF3UU7H.cjs.map
6494
+ //# sourceMappingURL=chunk-CNKT4PME.cjs.map
6495
+ //# sourceMappingURL=chunk-CNKT4PME.cjs.map