@kyro-cms/core 0.6.0 → 0.8.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 (145) hide show
  1. package/dist/api-handler.cjs +75 -35
  2. package/dist/api-handler.cjs.map +1 -1
  3. package/dist/api-handler.d.cts +2 -5
  4. package/dist/api-handler.d.ts +2 -5
  5. package/dist/api-handler.js +75 -36
  6. package/dist/api-handler.js.map +1 -1
  7. package/dist/bootstrap-AKAUP6F6.cjs +32 -0
  8. package/dist/{bootstrap-EE6BJZWL.cjs.map → bootstrap-AKAUP6F6.cjs.map} +1 -1
  9. package/dist/bootstrap-JCML6NFO.js +7 -0
  10. package/dist/{bootstrap-4MH44YKG.js.map → bootstrap-JCML6NFO.js.map} +1 -1
  11. package/dist/{chunk-WVPOPOEQ.cjs → chunk-2KVHZE6O.cjs} +286 -126
  12. package/dist/chunk-2KVHZE6O.cjs.map +1 -0
  13. package/dist/{chunk-RALQO47U.cjs → chunk-2OL4O2TH.cjs} +55 -2
  14. package/dist/chunk-2OL4O2TH.cjs.map +1 -0
  15. package/dist/{chunk-XU7AFF6V.js → chunk-35U3FROB.js} +982 -4
  16. package/dist/chunk-35U3FROB.js.map +1 -0
  17. package/dist/{chunk-WSCJQI2B.js → chunk-3J4MFTI3.js} +27 -11
  18. package/dist/chunk-3J4MFTI3.js.map +1 -0
  19. package/dist/chunk-3ZFYL34R.js +391 -0
  20. package/dist/chunk-3ZFYL34R.js.map +1 -0
  21. package/dist/chunk-4DA7QPLA.cjs +356 -0
  22. package/dist/chunk-4DA7QPLA.cjs.map +1 -0
  23. package/dist/{chunk-TP5YQFIX.js → chunk-57P6MJKC.js} +3 -715
  24. package/dist/chunk-57P6MJKC.js.map +1 -0
  25. package/dist/{chunk-R2YHJN6W.cjs → chunk-5KVM3WEY.cjs} +34 -208
  26. package/dist/chunk-5KVM3WEY.cjs.map +1 -0
  27. package/dist/{chunk-Z2OVHWHB.cjs → chunk-6IMPH6WV.cjs} +28 -11
  28. package/dist/chunk-6IMPH6WV.cjs.map +1 -0
  29. package/dist/{chunk-QKVA2SOG.js → chunk-DXHRBMGB.js} +27 -284
  30. package/dist/chunk-DXHRBMGB.js.map +1 -0
  31. package/dist/{chunk-E3BZLMX6.js → chunk-ES5HNFFT.js} +43 -2
  32. package/dist/chunk-ES5HNFFT.js.map +1 -0
  33. package/dist/{chunk-QYZKIPSD.js → chunk-FXYP2HA6.js} +34 -3
  34. package/dist/chunk-FXYP2HA6.js.map +1 -0
  35. package/dist/chunk-H727JIG7.js +809 -0
  36. package/dist/chunk-H727JIG7.js.map +1 -0
  37. package/dist/{chunk-AM4JKIPP.js → chunk-HXRD4B37.js} +9 -183
  38. package/dist/chunk-HXRD4B37.js.map +1 -0
  39. package/dist/chunk-I7HHI6QV.cjs +816 -0
  40. package/dist/chunk-I7HHI6QV.cjs.map +1 -0
  41. package/dist/{chunk-RDRJVCL5.cjs → chunk-IA6AU5PI.cjs} +2 -720
  42. package/dist/chunk-IA6AU5PI.cjs.map +1 -0
  43. package/dist/{chunk-55BNRTLW.cjs → chunk-LINKCEG4.cjs} +985 -4
  44. package/dist/chunk-LINKCEG4.cjs.map +1 -0
  45. package/dist/{chunk-TVVYZ2TH.js → chunk-OHVB4AJ7.js} +56 -3
  46. package/dist/chunk-OHVB4AJ7.js.map +1 -0
  47. package/dist/{chunk-XAEBVZTI.cjs → chunk-PDYFVNUX.cjs} +26 -289
  48. package/dist/chunk-PDYFVNUX.cjs.map +1 -0
  49. package/dist/{chunk-6WXQRYTW.js → chunk-QPPDLRNR.js} +286 -126
  50. package/dist/chunk-QPPDLRNR.js.map +1 -0
  51. package/dist/{chunk-WBCIEYHC.cjs → chunk-QUW2RZTM.cjs} +35 -4
  52. package/dist/chunk-QUW2RZTM.cjs.map +1 -0
  53. package/dist/chunk-SA7NSSIQ.cjs +397 -0
  54. package/dist/chunk-SA7NSSIQ.cjs.map +1 -0
  55. package/dist/{chunk-H4XCAPA6.cjs → chunk-V3LKPM3O.cjs} +43 -2
  56. package/dist/chunk-V3LKPM3O.cjs.map +1 -0
  57. package/dist/chunk-Y3N7UUDO.js +349 -0
  58. package/dist/chunk-Y3N7UUDO.js.map +1 -0
  59. package/dist/{chunk-S3FG2NY7.js → chunk-Y3QQN7PN.js} +4 -3
  60. package/dist/chunk-Y3QQN7PN.js.map +1 -0
  61. package/dist/{chunk-5HA5OMFH.cjs → chunk-YVUJBEXE.cjs} +7 -6
  62. package/dist/chunk-YVUJBEXE.cjs.map +1 -0
  63. package/dist/cli/index.cjs +103 -20
  64. package/dist/cli/index.cjs.map +1 -1
  65. package/dist/cli/index.js +103 -20
  66. package/dist/cli/index.js.map +1 -1
  67. package/dist/client.d.cts +1 -1
  68. package/dist/client.d.ts +1 -1
  69. package/dist/drizzle/index.cjs +12 -12
  70. package/dist/drizzle/index.d.cts +23 -2
  71. package/dist/drizzle/index.d.ts +23 -2
  72. package/dist/drizzle/index.js +3 -3
  73. package/dist/index.cjs +174 -1054
  74. package/dist/index.cjs.map +1 -1
  75. package/dist/index.d.cts +85 -7
  76. package/dist/index.d.ts +85 -7
  77. package/dist/index.js +91 -980
  78. package/dist/index.js.map +1 -1
  79. package/dist/integration.cjs +2 -2
  80. package/dist/integration.d.cts +3 -16
  81. package/dist/integration.d.ts +3 -16
  82. package/dist/integration.js +1 -1
  83. package/dist/mongo-auth-adapter-NHHUJHVH.cjs +17 -0
  84. package/dist/mongo-auth-adapter-NHHUJHVH.cjs.map +1 -0
  85. package/dist/mongo-auth-adapter-NJQUUCTP.js +4 -0
  86. package/dist/mongo-auth-adapter-NJQUUCTP.js.map +1 -0
  87. package/dist/mongodb/index.cjs +9 -8
  88. package/dist/mongodb/index.d.cts +86 -5
  89. package/dist/mongodb/index.d.ts +86 -5
  90. package/dist/mongodb/index.js +3 -2
  91. package/dist/postgres-auth-adapter-3T2NKTSE.js +5 -0
  92. package/dist/{postgres-auth-adapter-B65BULNS.js.map → postgres-auth-adapter-3T2NKTSE.js.map} +1 -1
  93. package/dist/postgres-auth-adapter-7IEENCKQ.cjs +14 -0
  94. package/dist/{postgres-auth-adapter-6742WDCF.cjs.map → postgres-auth-adapter-7IEENCKQ.cjs.map} +1 -1
  95. package/dist/redis-adapter-D2E2S3GB.cjs +13 -0
  96. package/dist/{redis-adapter-LPUWLE4Y.cjs.map → redis-adapter-D2E2S3GB.cjs.map} +1 -1
  97. package/dist/redis-adapter-VQXD7ESY.js +4 -0
  98. package/dist/{redis-adapter-THYDCGQR.js.map → redis-adapter-VQXD7ESY.js.map} +1 -1
  99. package/dist/rest/index.cjs +10 -8
  100. package/dist/rest/index.js +8 -6
  101. package/dist/sqlite-adapter-LVK5PS4T.cjs +13 -0
  102. package/dist/sqlite-adapter-LVK5PS4T.cjs.map +1 -0
  103. package/dist/sqlite-adapter-TR3U3W6Q.js +4 -0
  104. package/dist/sqlite-adapter-TR3U3W6Q.js.map +1 -0
  105. package/dist/templates/index.cjs +31 -27
  106. package/dist/templates/index.d.cts +8 -5
  107. package/dist/templates/index.d.ts +8 -5
  108. package/dist/templates/index.js +1 -1
  109. package/dist/{base-eVegJ_Pr.d.ts → tenant-B1YB0Jy8.d.ts} +10 -1
  110. package/dist/{base-DvvNqnM-.d.cts → tenant-Cpeveji6.d.cts} +10 -1
  111. package/dist/{types-DqN4ckOC.d.cts → types-D6ZLRGbH.d.cts} +19 -1
  112. package/dist/{types-DqN4ckOC.d.ts → types-D6ZLRGbH.d.ts} +19 -1
  113. package/package.json +56 -9
  114. package/dist/adapter-BSvBudTG.d.cts +0 -65
  115. package/dist/adapter-CXGB2Elb.d.ts +0 -65
  116. package/dist/bootstrap-4MH44YKG.js +0 -6
  117. package/dist/bootstrap-EE6BJZWL.cjs +0 -31
  118. package/dist/chunk-55BNRTLW.cjs.map +0 -1
  119. package/dist/chunk-5HA5OMFH.cjs.map +0 -1
  120. package/dist/chunk-6WXQRYTW.js.map +0 -1
  121. package/dist/chunk-A4USRVTQ.js +0 -115
  122. package/dist/chunk-A4USRVTQ.js.map +0 -1
  123. package/dist/chunk-AM4JKIPP.js.map +0 -1
  124. package/dist/chunk-E3BZLMX6.js.map +0 -1
  125. package/dist/chunk-H4XCAPA6.cjs.map +0 -1
  126. package/dist/chunk-KOCTZKPV.cjs +0 -117
  127. package/dist/chunk-KOCTZKPV.cjs.map +0 -1
  128. package/dist/chunk-QKVA2SOG.js.map +0 -1
  129. package/dist/chunk-QYZKIPSD.js.map +0 -1
  130. package/dist/chunk-R2YHJN6W.cjs.map +0 -1
  131. package/dist/chunk-RALQO47U.cjs.map +0 -1
  132. package/dist/chunk-RDRJVCL5.cjs.map +0 -1
  133. package/dist/chunk-S3FG2NY7.js.map +0 -1
  134. package/dist/chunk-TP5YQFIX.js.map +0 -1
  135. package/dist/chunk-TVVYZ2TH.js.map +0 -1
  136. package/dist/chunk-WBCIEYHC.cjs.map +0 -1
  137. package/dist/chunk-WSCJQI2B.js.map +0 -1
  138. package/dist/chunk-WVPOPOEQ.cjs.map +0 -1
  139. package/dist/chunk-XAEBVZTI.cjs.map +0 -1
  140. package/dist/chunk-XU7AFF6V.js.map +0 -1
  141. package/dist/chunk-Z2OVHWHB.cjs.map +0 -1
  142. package/dist/postgres-auth-adapter-6742WDCF.cjs +0 -14
  143. package/dist/postgres-auth-adapter-B65BULNS.js +0 -5
  144. package/dist/redis-adapter-LPUWLE4Y.cjs +0 -13
  145. package/dist/redis-adapter-THYDCGQR.js +0 -4
package/dist/index.cjs CHANGED
@@ -1,30 +1,31 @@
1
1
  'use strict';
2
2
 
3
- var chunkH4XCAPA6_cjs = require('./chunk-H4XCAPA6.cjs');
4
- var chunkZ2OVHWHB_cjs = require('./chunk-Z2OVHWHB.cjs');
5
- var chunkWBCIEYHC_cjs = require('./chunk-WBCIEYHC.cjs');
6
- var chunk55BNRTLW_cjs = require('./chunk-55BNRTLW.cjs');
7
- var chunk5HA5OMFH_cjs = require('./chunk-5HA5OMFH.cjs');
3
+ var chunkV3LKPM3O_cjs = require('./chunk-V3LKPM3O.cjs');
4
+ var chunk6IMPH6WV_cjs = require('./chunk-6IMPH6WV.cjs');
5
+ var chunkQUW2RZTM_cjs = require('./chunk-QUW2RZTM.cjs');
6
+ var chunkLINKCEG4_cjs = require('./chunk-LINKCEG4.cjs');
7
+ var chunkYVUJBEXE_cjs = require('./chunk-YVUJBEXE.cjs');
8
8
  var chunkN4H37VN4_cjs = require('./chunk-N4H37VN4.cjs');
9
9
  var chunkATBOUGQP_cjs = require('./chunk-ATBOUGQP.cjs');
10
10
  var chunkK7JPTH3G_cjs = require('./chunk-K7JPTH3G.cjs');
11
- var chunkR2YHJN6W_cjs = require('./chunk-R2YHJN6W.cjs');
12
- var chunkRDRJVCL5_cjs = require('./chunk-RDRJVCL5.cjs');
11
+ var chunk5KVM3WEY_cjs = require('./chunk-5KVM3WEY.cjs');
12
+ var chunkIA6AU5PI_cjs = require('./chunk-IA6AU5PI.cjs');
13
13
  require('./chunk-4PWRCMTQ.cjs');
14
+ var chunkI7HHI6QV_cjs = require('./chunk-I7HHI6QV.cjs');
14
15
  require('./chunk-ADLJSJSN.cjs');
15
16
  var chunkIBG6V56E_cjs = require('./chunk-IBG6V56E.cjs');
16
17
  var chunkVJT6P4N6_cjs = require('./chunk-VJT6P4N6.cjs');
17
18
  var chunkR3XIBBAW_cjs = require('./chunk-R3XIBBAW.cjs');
18
19
  var chunkDVD5P72E_cjs = require('./chunk-DVD5P72E.cjs');
19
20
  require('./chunk-3YELQL7Z.cjs');
20
- var chunkWVPOPOEQ_cjs = require('./chunk-WVPOPOEQ.cjs');
21
- var chunkRALQO47U_cjs = require('./chunk-RALQO47U.cjs');
21
+ var chunk2KVHZE6O_cjs = require('./chunk-2KVHZE6O.cjs');
22
+ var chunk2OL4O2TH_cjs = require('./chunk-2OL4O2TH.cjs');
22
23
  require('./chunk-WQBRWOQT.cjs');
23
24
  require('./chunk-MTIRYI7F.cjs');
24
- var chunkXAEBVZTI_cjs = require('./chunk-XAEBVZTI.cjs');
25
- var chunkKOCTZKPV_cjs = require('./chunk-KOCTZKPV.cjs');
25
+ var chunkPDYFVNUX_cjs = require('./chunk-PDYFVNUX.cjs');
26
+ var chunk4DA7QPLA_cjs = require('./chunk-4DA7QPLA.cjs');
27
+ var chunkSA7NSSIQ_cjs = require('./chunk-SA7NSSIQ.cjs');
26
28
  require('./chunk-G7VZBCD6.cjs');
27
- var module$1 = require('module');
28
29
  var crypto2 = require('crypto');
29
30
  var fs = require('fs');
30
31
  var path = require('path');
@@ -33,7 +34,6 @@ var unstorage = require('unstorage');
33
34
  var indexedbDriver = require('unstorage/drivers/indexedb');
34
35
  var fsDriver = require('unstorage/drivers/fs');
35
36
 
36
- var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
37
37
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
38
38
 
39
39
  var crypto2__default = /*#__PURE__*/_interopDefault(crypto2);
@@ -58,967 +58,6 @@ async function runHooks(hooks, args) {
58
58
  async function runFieldHooks(hooks, args) {
59
59
  return runHooks(hooks, args);
60
60
  }
61
- var _require = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)));
62
- var modPath = "node:sqlite";
63
- var { DatabaseSync } = _require(modPath);
64
- function flattenFields(fields) {
65
- const result = [];
66
- for (const field of fields) {
67
- if (field.type === "tabs" && "tabs" in field) {
68
- for (const tab of field.tabs) {
69
- result.push(...flattenFields(tab.fields));
70
- }
71
- } else if (field.type === "row" && "fields" in field) {
72
- result.push(...flattenFields(field.fields));
73
- } else if (field.type === "collapsible" && "fields" in field) {
74
- result.push(...flattenFields(field.fields));
75
- } else {
76
- result.push(field);
77
- }
78
- }
79
- return result;
80
- }
81
- function processFieldValue(row, field) {
82
- const f = field;
83
- let value = row[f.name];
84
- if (f.type === "json" || f.type === "richtext" || f.type === "array" || f.type === "group" || f.type === "blocks" || f.type === "list" || f.type === "relationship-block") {
85
- try {
86
- value = value ? JSON.parse(value) : null;
87
- } catch {
88
- value = null;
89
- }
90
- }
91
- if (f.type === "checkbox") {
92
- value = Boolean(value);
93
- }
94
- if (f.type === "date" && value) {
95
- try {
96
- const d = new Date(value);
97
- if (isNaN(d.getTime())) {
98
- value = null;
99
- } else {
100
- value = d.toISOString();
101
- }
102
- } catch {
103
- value = null;
104
- }
105
- }
106
- if ((f.type === "upload" || f.type === "image") && value) {
107
- try {
108
- const parsed = JSON.parse(value);
109
- if (Array.isArray(parsed)) {
110
- value = parsed.map((item) => {
111
- if (typeof item === "object" && item !== null) {
112
- return item;
113
- }
114
- return { id: item };
115
- });
116
- } else {
117
- value = typeof parsed === "object" ? parsed : { id: parsed };
118
- }
119
- } catch {
120
- value = { id: value };
121
- }
122
- }
123
- if (f.type === "relationship" && value) {
124
- try {
125
- const parsed = JSON.parse(value);
126
- if (Array.isArray(parsed)) {
127
- value = parsed;
128
- } else {
129
- value = parsed;
130
- }
131
- } catch {
132
- value = { relationTo: Array.isArray(f.relationTo) ? f.relationTo[0] : f.relationTo, value };
133
- }
134
- }
135
- if (f.type === "list" && value) {
136
- try {
137
- const parsed = JSON.parse(value);
138
- value = Array.isArray(parsed) ? parsed : [];
139
- } catch {
140
- value = [];
141
- }
142
- }
143
- if (f.type === "relationship-block" && value) {
144
- try {
145
- const parsed = JSON.parse(value);
146
- value = Array.isArray(parsed) ? parsed : [];
147
- } catch {
148
- value = [];
149
- }
150
- }
151
- return value;
152
- }
153
- function getTableColumns(db, tableName) {
154
- try {
155
- const rows = db.prepare(`PRAGMA table_info(${tableName})`).all();
156
- return rows.map((r) => r.name);
157
- } catch {
158
- return [];
159
- }
160
- }
161
- var LocalAdapter = class extends chunkKOCTZKPV_cjs.AbstractBaseAdapter {
162
- db;
163
- path;
164
- migrations = /* @__PURE__ */ new Map();
165
- draftsTableName = "kyro_drafts";
166
- versionsTableName = "kyro_versions";
167
- constructor(options) {
168
- super();
169
- this.path = options.path;
170
- if (options.db) {
171
- this.db = options.db;
172
- } else {
173
- this.db = null;
174
- }
175
- }
176
- async connect() {
177
- if (!this.db) {
178
- this.db = new DatabaseSync(this.path || ":memory:");
179
- }
180
- this.db.exec("PRAGMA journal_mode = WAL");
181
- this.db.exec("PRAGMA foreign_keys = ON");
182
- this.connected = true;
183
- console.log(
184
- `[LocalAdapter] Connected to SQLite (${this.path || "memory"})`
185
- );
186
- }
187
- async disconnect() {
188
- if (this.db) {
189
- this.db.close();
190
- }
191
- this.connected = false;
192
- console.log("[LocalAdapter] Disconnected");
193
- }
194
- // ========================================================================
195
- // Schema Management
196
- // ========================================================================
197
- ensureTable(config, tableName) {
198
- const name = tableName || this.getTableNameFor(config.slug);
199
- const columns = [`id TEXT PRIMARY KEY`];
200
- for (const field of flattenFields(config.fields)) {
201
- if (!field.name || field.name === "id") continue;
202
- const colDef = this.fieldToSQL(field);
203
- if (colDef) columns.push(colDef);
204
- }
205
- columns.push(`${this.col("createdAt")} TEXT DEFAULT (datetime('now'))`);
206
- columns.push(`${this.col("updatedAt")} TEXT DEFAULT (datetime('now'))`);
207
- columns.push(`_status TEXT DEFAULT 'published'`);
208
- columns.push(`_has_draft INTEGER DEFAULT 0`);
209
- if (config.tenantScoped) {
210
- columns.push(`tenant_id TEXT NOT NULL`);
211
- }
212
- const existingColumns = getTableColumns(this.db, name);
213
- if (existingColumns.length === 0) {
214
- const createSQL = `CREATE TABLE IF NOT EXISTS ${name} (${columns.join(", ")})`;
215
- this.db.exec(createSQL);
216
- this.db.exec(`CREATE INDEX IF NOT EXISTS idx_${name}__status ON ${name}(_status)`);
217
- for (const field of flattenFields(config.fields)) {
218
- if (field.name && field.indexed) {
219
- this.db.exec(
220
- `CREATE INDEX IF NOT EXISTS idx_${name}_${field.name} ON ${name}(${this.col(field.name)})`
221
- );
222
- }
223
- if (field.name && field.unique) {
224
- this.db.exec(
225
- `CREATE UNIQUE INDEX IF NOT EXISTS idx_${name}_${field.name}_unique ON ${name}(${this.col(field.name)})`
226
- );
227
- }
228
- }
229
- } else {
230
- const existingSet = new Set(existingColumns);
231
- for (const colDef of columns) {
232
- const colName = colDef.split(" ")[0].replace(/^"/, "").replace(/"$/, "");
233
- if (!existingSet.has(colName) && colName !== "id") {
234
- try {
235
- if (colName === "_status") {
236
- this.db.exec(`ALTER TABLE ${name} ADD COLUMN ${this.col(colName)} TEXT DEFAULT 'published'`);
237
- } else if (colName === "_has_draft") {
238
- this.db.exec(`ALTER TABLE ${name} ADD COLUMN ${this.col(colName)} INTEGER DEFAULT 0`);
239
- } else {
240
- this.db.exec(`ALTER TABLE ${name} ADD COLUMN ${this.col(colName)} TEXT`);
241
- }
242
- } catch {
243
- }
244
- }
245
- }
246
- }
247
- this.migrations.set(name, true);
248
- }
249
- ensureVersionsTable() {
250
- this.db.exec(`
251
- CREATE TABLE IF NOT EXISTS ${this.versionsTableName} (
252
- id TEXT PRIMARY KEY,
253
- collection_slug TEXT NOT NULL,
254
- document_id TEXT NOT NULL,
255
- tenant_id TEXT,
256
- version INTEGER NOT NULL,
257
- status TEXT NOT NULL DEFAULT 'draft',
258
- data TEXT NOT NULL,
259
- created_by TEXT,
260
- change_description TEXT,
261
- published_at TEXT,
262
- created_at TEXT DEFAULT (datetime('now')),
263
- updated_at TEXT DEFAULT (datetime('now'))
264
- )
265
- `);
266
- this.db.exec(
267
- `CREATE INDEX IF NOT EXISTS idx_${this.versionsTableName}_doc ON ${this.versionsTableName}(collection_slug, document_id)`
268
- );
269
- this.db.exec(
270
- `CREATE INDEX IF NOT EXISTS idx_${this.versionsTableName}_status ON ${this.versionsTableName}(status)`
271
- );
272
- }
273
- ensureDraftsTable() {
274
- this.db.exec(`
275
- CREATE TABLE IF NOT EXISTS ${this.draftsTableName} (
276
- id TEXT PRIMARY KEY,
277
- collection_slug TEXT NOT NULL,
278
- document_id TEXT NOT NULL,
279
- tenant_id TEXT,
280
- data TEXT NOT NULL,
281
- base_updated_at TEXT,
282
- draft_updated_at TEXT NOT NULL,
283
- created_at TEXT DEFAULT (datetime('now')),
284
- updated_at TEXT DEFAULT (datetime('now'))
285
- )
286
- `);
287
- this.db.exec(
288
- `CREATE UNIQUE INDEX IF NOT EXISTS idx_${this.draftsTableName}_document ON ${this.draftsTableName}(collection_slug, document_id, tenant_id)`
289
- );
290
- }
291
- // ========================================================================
292
- // SQL Quoting
293
- // ========================================================================
294
- col(name) {
295
- return `"${name}"`;
296
- }
297
- fieldToSQL(field) {
298
- switch (field.type) {
299
- case "text":
300
- case "email":
301
- case "password":
302
- case "textarea":
303
- case "color":
304
- case "code":
305
- case "markdown":
306
- case "url":
307
- return this.col(field.name) + " TEXT";
308
- case "number":
309
- return this.col(field.name) + " REAL";
310
- case "checkbox":
311
- return this.col(field.name) + " INTEGER DEFAULT 0";
312
- case "date":
313
- return this.col(field.name) + " TEXT";
314
- case "select":
315
- case "radio":
316
- return this.col(field.name) + " TEXT";
317
- case "relationship":
318
- case "upload":
319
- return this.col(field.name) + " TEXT";
320
- case "json":
321
- case "richtext":
322
- case "array":
323
- case "group":
324
- case "blocks":
325
- return this.col(field.name) + " TEXT";
326
- default:
327
- return null;
328
- }
329
- }
330
- // ========================================================================
331
- // CRUD Operations
332
- // ========================================================================
333
- parseGlobalsSlug(slug) {
334
- if (slug.startsWith("_globals_")) {
335
- const globalSlug = slug.replace("_globals_", "");
336
- return {
337
- isGlobal: true,
338
- globalSlug,
339
- tableName: `global_${globalSlug.replace(/-/g, "_")}`
340
- };
341
- }
342
- return {
343
- isGlobal: false,
344
- globalSlug: "",
345
- tableName: this.getTableNameFor(slug)
346
- };
347
- }
348
- async find(args) {
349
- const {
350
- collection: slug,
351
- where = {},
352
- sort,
353
- limit = 10,
354
- page = 1,
355
- tenantID,
356
- draft = false
357
- } = args;
358
- const parsed = this.parseGlobalsSlug(slug);
359
- const config = parsed.isGlobal ? this.globals.get(parsed.globalSlug) : this.getCollection(slug);
360
- this.ensureTable(config, parsed.tableName);
361
- const tableName = parsed.tableName;
362
- let sql = `SELECT * FROM ${tableName}`;
363
- const params = [];
364
- const conditions = [];
365
- if (!draft && config.versions?.drafts) {
366
- conditions.push(`_status = ?`);
367
- params.push("published");
368
- }
369
- if (tenantID && config.tenantScoped) {
370
- conditions.push(`tenant_id = ?`);
371
- params.push(tenantID);
372
- }
373
- for (const [key, value] of Object.entries(where)) {
374
- if (key === "AND" || key === "OR") continue;
375
- if (typeof value === "object" && value !== null) {
376
- if (value.equals !== void 0) {
377
- conditions.push(`${this.col(key)} = ?`);
378
- params.push(value.equals);
379
- }
380
- if (value.in !== void 0) {
381
- conditions.push(`${this.col(key)} IN (${value.in.map(() => "?").join(", ")})`);
382
- params.push(...value.in);
383
- }
384
- if (value.not_equals !== void 0) {
385
- conditions.push(`${this.col(key)} != ?`);
386
- params.push(value.not_equals);
387
- }
388
- } else {
389
- conditions.push(`${this.col(key)} = ?`);
390
- params.push(value);
391
- }
392
- }
393
- if (conditions.length > 0) {
394
- sql += ` WHERE ${conditions.join(" AND ")}`;
395
- }
396
- const sortField = this.col(sort?.replace("-", "") || "createdAt");
397
- const sortDir = sort?.startsWith("-") ? "DESC" : "ASC";
398
- sql += ` ORDER BY ${sortField} ${sortDir}`;
399
- const countSql = sql.replace("SELECT *", "SELECT COUNT(*) as count");
400
- const countResult = this.db.prepare(countSql).get(...params);
401
- const totalDocs = countResult?.count || 0;
402
- sql += ` LIMIT ? OFFSET ?`;
403
- params.push(limit, (page - 1) * limit);
404
- const rows = this.db.prepare(sql).all(...params);
405
- let docs = rows.map((row) => this.rowToDoc(row, config));
406
- if (draft) {
407
- docs = await Promise.all(docs.map(async (doc) => {
408
- if (doc._has_draft) {
409
- const versions = await this.findVersions({
410
- collection: slug,
411
- documentId: doc.id,
412
- limit: 1,
413
- sort: "-createdAt"
414
- });
415
- if (versions.docs.length > 0 && versions.docs[0].status === "draft") {
416
- return { ...doc, ...versions.docs[0].data, _has_draft: true, _status: doc._status };
417
- }
418
- }
419
- return doc;
420
- }));
421
- }
422
- return {
423
- docs,
424
- totalDocs,
425
- limit,
426
- totalPages: Math.ceil(totalDocs / limit),
427
- page,
428
- pagingCounter: (page - 1) * limit + 1,
429
- hasPrevPage: page > 1,
430
- hasNextPage: page < Math.ceil(totalDocs / limit),
431
- prevPage: page > 1 ? page - 1 : null,
432
- nextPage: page < Math.ceil(totalDocs / limit) ? page + 1 : null
433
- };
434
- }
435
- async findByID(args) {
436
- const { collection: slug, id, tenantID, draft = false } = args;
437
- const parsed = this.parseGlobalsSlug(slug);
438
- const config = parsed.isGlobal ? this.globals.get(parsed.globalSlug) : this.getCollection(slug);
439
- this.ensureTable(config, parsed.tableName);
440
- const tableName = parsed.tableName;
441
- let sql = `SELECT * FROM ${tableName} WHERE id = ?`;
442
- const params = [id];
443
- if (!draft && config.versions?.drafts) {
444
- sql += ` AND _status = ?`;
445
- params.push("published");
446
- }
447
- if (tenantID && config.tenantScoped) {
448
- sql += ` AND tenant_id = ?`;
449
- params.push(tenantID);
450
- }
451
- const row = this.db.prepare(sql).get(...params);
452
- if (!row) return null;
453
- let doc = this.rowToDoc(row, config);
454
- if (draft && doc._has_draft) {
455
- const versions = await this.findVersions({
456
- collection: slug,
457
- documentId: doc.id,
458
- limit: 1,
459
- sort: "-createdAt"
460
- });
461
- if (versions.docs.length > 0 && versions.docs[0].status === "draft") {
462
- doc = { ...doc, ...versions.docs[0].data, _has_draft: true, _status: doc._status };
463
- }
464
- }
465
- return doc;
466
- }
467
- async create(args) {
468
- const { collection: slug, data, tenantID } = args;
469
- const parsed = this.parseGlobalsSlug(slug);
470
- const config = parsed.isGlobal ? this.globals.get(parsed.globalSlug) : this.getCollection(slug);
471
- this.ensureTable(config, parsed.tableName);
472
- const tableName = parsed.tableName;
473
- const id = parsed.isGlobal ? parsed.globalSlug : data.id || this.generateId();
474
- const insertData = this.prepareData(data, config);
475
- insertData.id = id;
476
- insertData.created_at = (/* @__PURE__ */ new Date()).toISOString();
477
- insertData.updated_at = (/* @__PURE__ */ new Date()).toISOString();
478
- if (tenantID && config.tenantScoped) {
479
- insertData.tenant_id = tenantID;
480
- }
481
- const columns = Object.keys(insertData);
482
- const validColumns = getTableColumns(this.db, tableName);
483
- const filteredData = {};
484
- for (const key of columns) {
485
- if (validColumns.includes(key)) {
486
- filteredData[key] = insertData[key];
487
- }
488
- }
489
- const filteredColumns = Object.keys(filteredData);
490
- const quotedColumns = filteredColumns.map((c) => this.col(c));
491
- const placeholders = filteredColumns.map(() => "?").join(", ");
492
- const values = Object.values(filteredData).map(
493
- (v) => typeof v === "object" ? JSON.stringify(v) : v
494
- );
495
- this.db.prepare(
496
- `INSERT OR REPLACE INTO ${tableName} (${quotedColumns.join(", ")}) VALUES (${placeholders})`
497
- ).run(...values);
498
- return this.findByID({ collection: slug, id, tenantID });
499
- }
500
- async update(args) {
501
- const { collection: slug, id, data, tenantID } = args;
502
- const parsed = this.parseGlobalsSlug(slug);
503
- const config = parsed.isGlobal ? this.globals.get(parsed.globalSlug) : this.getCollection(slug);
504
- this.ensureTable(config, parsed.tableName);
505
- const tableName = parsed.tableName;
506
- const updateData = this.prepareData(data, config);
507
- updateData.updated_at = (/* @__PURE__ */ new Date()).toISOString();
508
- const validColumns = getTableColumns(this.db, tableName);
509
- const filteredData = {};
510
- for (const key of Object.keys(updateData)) {
511
- if (validColumns.includes(key)) {
512
- filteredData[key] = updateData[key];
513
- }
514
- }
515
- const columns = Object.keys(filteredData);
516
- const setClause = columns.map((c) => `${this.col(c)} = ?`).join(", ");
517
- const values = Object.values(filteredData).map(
518
- (v) => v !== null && typeof v === "object" ? JSON.stringify(v) : v
519
- );
520
- let sql = `UPDATE ${tableName} SET ${setClause} WHERE id = ?`;
521
- const params = [...values, id];
522
- console.log(`[LocalAdapter] update sql="${sql}", params=${JSON.stringify(params)}`);
523
- if (tenantID && config.tenantScoped) {
524
- sql += ` AND tenant_id = ?`;
525
- params.push(tenantID);
526
- }
527
- this.db.prepare(sql).run(...params);
528
- return this.findByID({ collection: slug, id, tenantID, draft: true });
529
- }
530
- async delete(args) {
531
- const { collection: slug, id, tenantID } = args;
532
- const parsed = this.parseGlobalsSlug(slug);
533
- const config = parsed.isGlobal ? this.globals.get(parsed.globalSlug) : this.getCollection(slug);
534
- this.ensureTable(config, parsed.tableName);
535
- const doc = await this.findByID({ collection: slug, id, tenantID });
536
- if (!doc) throw new Error(`Document not found: ${slug}/${id}`);
537
- const tableName = parsed.tableName;
538
- let sql = `DELETE FROM ${tableName} WHERE id = ?`;
539
- const params = [id];
540
- if (tenantID && config.tenantScoped) {
541
- sql += ` AND tenant_id = ?`;
542
- params.push(tenantID);
543
- }
544
- this.db.prepare(sql).run(...params);
545
- return doc;
546
- }
547
- async count(args) {
548
- const { collection: slug, tenantID } = args;
549
- const parsed = this.parseGlobalsSlug(slug);
550
- const config = parsed.isGlobal ? this.globals.get(parsed.globalSlug) : this.getCollection(slug);
551
- this.ensureTable(config, parsed.tableName);
552
- const tableName = parsed.tableName;
553
- let sql = `SELECT COUNT(*) as count FROM ${tableName}`;
554
- const params = [];
555
- if (tenantID && config.tenantScoped) {
556
- sql += ` WHERE tenant_id = ?`;
557
- params.push(tenantID);
558
- }
559
- const result = this.db.prepare(sql).get(...params);
560
- return result?.count || 0;
561
- }
562
- async findOne(args) {
563
- const parsed = this.parseGlobalsSlug(args.collection);
564
- if (parsed.isGlobal) {
565
- const globalConfig = this.globals.get(parsed.globalSlug);
566
- if (!globalConfig) {
567
- throw new Error(`Global "${parsed.globalSlug}" not found in adapter`);
568
- }
569
- this.ensureTable(globalConfig, parsed.tableName);
570
- let sql = `SELECT * FROM ${parsed.tableName}`;
571
- const conditions = [];
572
- const params = [];
573
- if (!args.draft && globalConfig.versions) {
574
- conditions.push("_status = 'published'");
575
- }
576
- if (conditions.length > 0) {
577
- sql += ` WHERE ${conditions.join(" AND ")}`;
578
- }
579
- sql += " LIMIT 1";
580
- const result2 = this.db.prepare(sql).get(...params);
581
- if (result2) {
582
- let doc = this.rowToDoc(result2, globalConfig);
583
- if (args.draft && doc._has_draft) {
584
- const versions = await this.findVersions({
585
- collection: args.collection,
586
- documentId: parsed.globalSlug,
587
- limit: 1,
588
- sort: "-createdAt"
589
- });
590
- if (versions.docs.length > 0 && versions.docs[0].status === "draft") {
591
- doc = { ...doc, ...versions.docs[0].data, _has_draft: true, _status: doc._status };
592
- }
593
- }
594
- return doc;
595
- }
596
- return null;
597
- }
598
- const result = await this.find({ ...args, limit: 1 });
599
- return result.docs[0] || null;
600
- }
601
- // ========================================================================
602
- // Version History
603
- // ========================================================================
604
- async findVersions(args) {
605
- this.ensureVersionsTable();
606
- const { collection, documentId, tenantID, limit = 20, page = 1 } = args;
607
- const conditions = [`collection_slug = ?`, `document_id = ?`];
608
- const params = [collection, documentId];
609
- if (tenantID) {
610
- conditions.push(`tenant_id = ?`);
611
- params.push(tenantID);
612
- } else {
613
- conditions.push(`tenant_id IS NULL`);
614
- }
615
- const where = `WHERE ${conditions.join(" AND ")}`;
616
- const countResult = this.db.prepare(`SELECT COUNT(*) as count FROM ${this.versionsTableName} ${where}`).get(...params);
617
- const totalDocs = countResult?.count || 0;
618
- const offset = (page - 1) * limit;
619
- const rows = this.db.prepare(`SELECT * FROM ${this.versionsTableName} ${where} ORDER BY version DESC LIMIT ? OFFSET ?`).all(...params, limit, offset);
620
- const docs = rows.map((r) => this.rowToVersion(r));
621
- return {
622
- docs,
623
- totalDocs,
624
- limit,
625
- totalPages: Math.ceil(totalDocs / limit),
626
- page,
627
- pagingCounter: (page - 1) * limit + 1,
628
- hasPrevPage: page > 1,
629
- hasNextPage: page < Math.ceil(totalDocs / limit),
630
- prevPage: page > 1 ? page - 1 : null,
631
- nextPage: page < Math.ceil(totalDocs / limit) ? page + 1 : null
632
- };
633
- }
634
- async findVersionByID(args) {
635
- this.ensureVersionsTable();
636
- const row = this.db.prepare(`SELECT * FROM ${this.versionsTableName} WHERE id = ? AND collection_slug = ? LIMIT 1`).get(args.versionId, args.collection);
637
- return row ? this.rowToVersion(row) : null;
638
- }
639
- async createVersion(args) {
640
- this.ensureVersionsTable();
641
- const now = (/* @__PURE__ */ new Date()).toISOString();
642
- const id = this.generateId();
643
- const latestRow = this.db.prepare(`SELECT version FROM ${this.versionsTableName} WHERE collection_slug = ? AND document_id = ? ORDER BY version DESC LIMIT 1`).get(args.collection, args.documentId);
644
- const nextVersion = (latestRow?.version ?? 0) + 1;
645
- this.db.prepare(
646
- `INSERT INTO ${this.versionsTableName} (
647
- id, collection_slug, document_id, tenant_id, version, status, data, created_by, change_description, published_at, created_at, updated_at
648
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
649
- ).run(
650
- id,
651
- args.collection,
652
- args.documentId,
653
- args.tenantID ?? null,
654
- nextVersion,
655
- args.status,
656
- JSON.stringify(args.data),
657
- args.createdBy ?? null,
658
- args.changeDescription ?? null,
659
- args.status === "published" ? now : null,
660
- now,
661
- now
662
- );
663
- const collectionConfig = this.collections.get(args.collection);
664
- const maxPerDoc = collectionConfig?.versions?.maxPerDoc;
665
- if (maxPerDoc && maxPerDoc > 0) {
666
- await this.deleteVersions({ collection: args.collection, documentId: args.documentId, keepLatest: maxPerDoc, tenantID: args.tenantID });
667
- }
668
- const saved = await this.findVersionByID({ collection: args.collection, versionId: id });
669
- return saved;
670
- }
671
- async deleteVersions(args) {
672
- this.ensureVersionsTable();
673
- const { collection, documentId, keepLatest, tenantID } = args;
674
- if (keepLatest && keepLatest > 0) {
675
- const rows = this.db.prepare(`SELECT id, status FROM ${this.versionsTableName} WHERE collection_slug = ? AND document_id = ? ORDER BY version DESC`).all(collection, documentId);
676
- let draftCount = 0;
677
- const toDelete = [];
678
- for (const row of rows) {
679
- if (row.status === "published") continue;
680
- draftCount++;
681
- if (draftCount > keepLatest) toDelete.push(row.id);
682
- }
683
- for (const vid of toDelete) {
684
- this.db.prepare(`DELETE FROM ${this.versionsTableName} WHERE id = ?`).run(vid);
685
- }
686
- } else {
687
- let sql = `DELETE FROM ${this.versionsTableName} WHERE collection_slug = ? AND document_id = ?`;
688
- const params = [collection, documentId];
689
- if (tenantID) {
690
- sql += ` AND tenant_id = ?`;
691
- params.push(tenantID);
692
- }
693
- this.db.prepare(sql).run(...params);
694
- }
695
- }
696
- rowToVersion(row) {
697
- return {
698
- id: String(row.id),
699
- collection: row.collection_slug,
700
- documentId: row.document_id,
701
- version: row.version,
702
- status: row.status,
703
- data: row.data ? JSON.parse(row.data) : {},
704
- createdBy: row.created_by ?? void 0,
705
- changeDescription: row.change_description ?? void 0,
706
- publishedAt: row.published_at ?? null,
707
- createdAt: row.created_at,
708
- updatedAt: row.updated_at
709
- };
710
- }
711
- async findDraft(args) {
712
- this.ensureDraftsTable();
713
- let sql = `SELECT * FROM ${this.draftsTableName} WHERE collection_slug = ? AND document_id = ?`;
714
- const params = [args.collection, args.documentId];
715
- if (args.tenantID) {
716
- sql += ` AND tenant_id = ?`;
717
- params.push(args.tenantID);
718
- } else {
719
- sql += ` AND tenant_id IS NULL`;
720
- }
721
- sql += ` LIMIT 1`;
722
- const row = this.db.prepare(sql).get(...params);
723
- if (!row) return null;
724
- return this.rowToDraft(row);
725
- }
726
- async upsertDraft(args) {
727
- this.ensureDraftsTable();
728
- const existing = await this.findDraft(args);
729
- const now = (/* @__PURE__ */ new Date()).toISOString();
730
- const draftUpdatedAt = args.draftUpdatedAt || now;
731
- const id = existing?.id || this.generateId();
732
- this.db.prepare(
733
- `INSERT OR REPLACE INTO ${this.draftsTableName} (
734
- id, collection_slug, document_id, tenant_id, data, base_updated_at, draft_updated_at, created_at, updated_at
735
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`
736
- ).run(
737
- id,
738
- args.collection,
739
- args.documentId,
740
- args.tenantID ?? null,
741
- JSON.stringify(args.data),
742
- args.baseUpdatedAt ?? null,
743
- draftUpdatedAt,
744
- existing?.createdAt || now,
745
- now
746
- );
747
- const saved = await this.findDraft(args);
748
- if (!saved) {
749
- throw new Error("Failed to persist draft snapshot");
750
- }
751
- return saved;
752
- }
753
- async deleteDraft(args) {
754
- this.ensureDraftsTable();
755
- let sql = `DELETE FROM ${this.draftsTableName} WHERE collection_slug = ? AND document_id = ?`;
756
- const params = [args.collection, args.documentId];
757
- if (args.tenantID) {
758
- sql += ` AND tenant_id = ?`;
759
- params.push(args.tenantID);
760
- } else {
761
- sql += ` AND tenant_id IS NULL`;
762
- }
763
- this.db.prepare(sql).run(...params);
764
- }
765
- // ========================================================================
766
- // Helpers
767
- // ========================================================================
768
- prepareData(data, config) {
769
- const result = {};
770
- const fields = flattenFields(config.fields);
771
- const processValue = (field, value) => {
772
- const f = field;
773
- if (f.type === "json" || f.type === "richtext" || f.type === "array" || f.type === "group" || f.type === "blocks" || f.type === "list" || f.type === "relationship-block") {
774
- if (f.name === "content" && Array.isArray(value)) {
775
- console.log("[processValue] content blocks before stringify - first block id:", value[0]?.id, "first block:", JSON.stringify(value[0]));
776
- }
777
- return value !== null && value !== void 0 ? JSON.stringify(value) : null;
778
- } else if (f.type === "checkbox") {
779
- return value ? 1 : 0;
780
- } else if (f.type === "number") {
781
- return value !== null && value !== "" ? Number(value) : null;
782
- } else if (f.type === "upload" || f.type === "image") {
783
- if (value === null || value === void 0) return null;
784
- if (Array.isArray(value)) {
785
- const items = value.map((v) => {
786
- if (typeof v === "string") return v;
787
- if (typeof v === "object") return v.id || v._id || v;
788
- return String(v);
789
- });
790
- return JSON.stringify(items);
791
- }
792
- if (typeof value === "string") return value;
793
- if (typeof value === "object") return JSON.stringify(value);
794
- return String(value);
795
- } else if (field.type === "relationship") {
796
- if (value === null || value === void 0) return null;
797
- if (Array.isArray(value)) {
798
- const rels = value.map((v) => {
799
- if (typeof v === "string") return v;
800
- if (typeof v === "object") return JSON.stringify({ relationTo: field.relationTo, value: v.id || v });
801
- return String(v);
802
- });
803
- return JSON.stringify(rels);
804
- }
805
- if (typeof value === "string") return value;
806
- if (typeof value === "object") return JSON.stringify({ relationTo: field.relationTo, value: value.id || value });
807
- return String(value);
808
- }
809
- return value;
810
- };
811
- for (const field of fields) {
812
- if (!field.name || field.name === "id") continue;
813
- const isInTab = config.fields.some(
814
- (f) => f.type === "tabs" && "tabs" in f && f.tabs.some((t) => t.fields.some((tf) => tf.name === field.name))
815
- );
816
- if (isInTab) continue;
817
- const value = data[field.name];
818
- if (value !== void 0) {
819
- result[field.name] = processValue(field, value);
820
- }
821
- }
822
- for (const field of config.fields) {
823
- if (field.type === "tabs" && "tabs" in field && field.name) {
824
- const tabData = data[field.name];
825
- if (tabData && typeof tabData === "object") {
826
- for (const tab of field.tabs) {
827
- for (const tabField of tab.fields) {
828
- if (tabField.name && tabField.name !== "id") {
829
- const value = tabData[tabField.name];
830
- if (value !== void 0) {
831
- result[tabField.name] = processValue(tabField, value);
832
- }
833
- }
834
- }
835
- }
836
- }
837
- }
838
- }
839
- return result;
840
- }
841
- rowToDoc(row, config) {
842
- const doc = { id: row.id };
843
- for (const field of flattenFields(config.fields)) {
844
- if (!field.name || field.name === "id") continue;
845
- const f = field;
846
- let value = row[f.name];
847
- if (f.type === "json" || f.type === "richtext" || f.type === "array" || f.type === "group" || f.type === "blocks" || f.type === "list" || f.type === "relationship-block") {
848
- if (f.name === "content" && value) {
849
- console.log("[rowToDoc] RAW content from DB (first 300 chars):", JSON.stringify(value).slice(0, 300));
850
- }
851
- try {
852
- value = value ? JSON.parse(value) : null;
853
- } catch {
854
- value = null;
855
- }
856
- }
857
- if (field.type === "checkbox") {
858
- value = Boolean(value);
859
- }
860
- if (field.type === "date" && value) {
861
- try {
862
- const d = new Date(value);
863
- if (isNaN(d.getTime())) {
864
- console.warn(`[LocalAdapter] Invalid date value for field "${field.name}":`, value);
865
- value = null;
866
- } else {
867
- value = d.toISOString();
868
- }
869
- } catch {
870
- value = null;
871
- }
872
- }
873
- if ((field.type === "upload" || field.type === "image") && value) {
874
- try {
875
- const parsed = JSON.parse(value);
876
- if (Array.isArray(parsed)) {
877
- value = parsed.map((item) => {
878
- if (typeof item === "object" && item !== null) {
879
- return item;
880
- }
881
- return { id: item };
882
- });
883
- } else {
884
- value = typeof parsed === "object" ? parsed : { id: parsed };
885
- }
886
- } catch {
887
- value = { id: value };
888
- }
889
- }
890
- if (field.type === "relationship" && value) {
891
- try {
892
- const parsed = JSON.parse(value);
893
- if (Array.isArray(parsed)) {
894
- value = parsed;
895
- } else {
896
- value = parsed;
897
- }
898
- } catch {
899
- value = { relationTo: Array.isArray(field.relationTo) ? field.relationTo[0] : field.relationTo, value };
900
- }
901
- }
902
- doc[field.name] = value;
903
- }
904
- for (const field of config.fields) {
905
- if (!field.name || field.name === "id" || field.name === "row" || field.name === "collapsible") continue;
906
- if (field.type === "tabs" && "tabs" in field) {
907
- const tabData = {};
908
- for (const tab of field.tabs) {
909
- for (const tabField of tab.fields) {
910
- if (tabField.name && tabField.name !== "id") {
911
- tabData[tabField.name] = processFieldValue(row, tabField);
912
- }
913
- }
914
- }
915
- doc[field.name] = tabData;
916
- }
917
- }
918
- if (config.timestamps) {
919
- const cAt = row.createdAt || row.created_at;
920
- const uAt = row.updatedAt || row.updated_at;
921
- if (cAt) {
922
- try {
923
- const d = new Date(cAt);
924
- if (!isNaN(d.getTime())) doc.createdAt = d.toISOString();
925
- } catch {
926
- }
927
- }
928
- if (uAt) {
929
- try {
930
- const d = new Date(uAt);
931
- if (!isNaN(d.getTime())) doc.updatedAt = d.toISOString();
932
- } catch {
933
- }
934
- }
935
- }
936
- if (config.tenantScoped) {
937
- doc.tenantID = row.tenant_id;
938
- }
939
- return doc;
940
- }
941
- generateId() {
942
- const timestamp = Date.now().toString(16).padStart(12, "0");
943
- const random = crypto2.randomBytes(6).toString("hex");
944
- return timestamp + random;
945
- }
946
- getMediaById(mediaId) {
947
- try {
948
- const tableName = this.getTableNameFor("media");
949
- const row = this.db.prepare(`SELECT id, url, thumbnail_url FROM ${tableName} WHERE id = ?`).get(mediaId);
950
- if (row) {
951
- return {
952
- id: row.id,
953
- url: row.url,
954
- thumbnailUrl: row.thumbnail_url || row.url
955
- };
956
- }
957
- } catch (err) {
958
- }
959
- return null;
960
- }
961
- getTableNameFor(slug) {
962
- return slug.replace(/-/g, "_");
963
- }
964
- rowToDraft(row) {
965
- return {
966
- id: row.id,
967
- collection: row.collection_slug,
968
- documentId: row.document_id,
969
- tenantID: row.tenant_id ?? void 0,
970
- data: row.data ? JSON.parse(row.data) : {},
971
- baseUpdatedAt: row.base_updated_at ?? null,
972
- draftUpdatedAt: row.draft_updated_at,
973
- createdAt: row.created_at,
974
- updatedAt: row.updated_at
975
- };
976
- }
977
- // ========================================================================
978
- // Migrations
979
- // ========================================================================
980
- async migrate() {
981
- for (const config of this.collections.values()) {
982
- this.ensureTable(config);
983
- }
984
- this.ensureDraftsTable();
985
- console.log("[LocalAdapter] Migrations complete");
986
- }
987
- async rollback() {
988
- console.log("[LocalAdapter] Rollback not supported for schema changes");
989
- }
990
- // ========================================================================
991
- // Transaction Support
992
- // ========================================================================
993
- async transaction(fn) {
994
- return new Promise((resolve2, reject) => {
995
- const tx = this.db.transaction(async () => {
996
- return fn({ db: this.db });
997
- });
998
- try {
999
- const result = tx();
1000
- resolve2(result);
1001
- } catch (error) {
1002
- reject(error);
1003
- }
1004
- });
1005
- }
1006
- // ========================================================================
1007
- // Direct DB Access
1008
- // ========================================================================
1009
- getDatabase() {
1010
- return this.db;
1011
- }
1012
- exec(sql) {
1013
- this.db.exec(sql);
1014
- }
1015
- prepare(sql) {
1016
- return this.db.prepare(sql);
1017
- }
1018
- };
1019
- function createLocalAdapter(options) {
1020
- return new LocalAdapter(options || {});
1021
- }
1022
61
 
1023
62
  // src/plugins/index.ts
1024
63
  var KyroPlugin = class {
@@ -1592,6 +631,8 @@ var InMemoryAuthAdapter = class {
1592
631
  refreshTokens = /* @__PURE__ */ new Map();
1593
632
  emailToUserId = /* @__PURE__ */ new Map();
1594
633
  passwordHistory = /* @__PURE__ */ new Map();
634
+ emailVerificationTokens = /* @__PURE__ */ new Map();
635
+ passwordResetTokens = /* @__PURE__ */ new Map();
1595
636
  auditLogs = [];
1596
637
  externalDb = false;
1597
638
  constructor() {
@@ -1749,6 +790,42 @@ var InMemoryAuthAdapter = class {
1749
790
  }
1750
791
  return false;
1751
792
  }
793
+ async createEmailVerificationToken(userId) {
794
+ const token = crypto2.randomBytes(32).toString("hex");
795
+ const expiresAt = new Date(Date.now() + 24 * 60 * 60 * 1e3);
796
+ this.emailVerificationTokens.set(token, { userId, expiresAt });
797
+ return { token, expiresAt };
798
+ }
799
+ async verifyEmailToken(token) {
800
+ const data = this.emailVerificationTokens.get(token);
801
+ if (!data || data.expiresAt < /* @__PURE__ */ new Date()) {
802
+ this.emailVerificationTokens.delete(token);
803
+ return { success: false, error: "Invalid or expired token" };
804
+ }
805
+ this.emailVerificationTokens.delete(token);
806
+ return { success: true, userId: data.userId };
807
+ }
808
+ async createPasswordResetToken(email) {
809
+ const user = await this.findUserByEmail(email);
810
+ if (!user) {
811
+ return { token: "", expiresAt: /* @__PURE__ */ new Date(), error: "User not found" };
812
+ }
813
+ const token = crypto2.randomBytes(32).toString("hex");
814
+ const expiresAt = new Date(Date.now() + 60 * 60 * 1e3);
815
+ this.passwordResetTokens.set(token, { userId: user.id, expiresAt });
816
+ return { token, expiresAt };
817
+ }
818
+ async resetPasswordWithToken(token, newPassword) {
819
+ const data = this.passwordResetTokens.get(token);
820
+ if (!data || data.expiresAt < /* @__PURE__ */ new Date()) {
821
+ this.passwordResetTokens.delete(token);
822
+ return { success: false, error: "Invalid or expired token" };
823
+ }
824
+ const passwordHash = await this.hashPassword(newPassword);
825
+ await this.updateUser(data.userId, { passwordHash });
826
+ this.passwordResetTokens.delete(token);
827
+ return { success: true };
828
+ }
1752
829
  async hasAnyUsers() {
1753
830
  return this.users.size > 0;
1754
831
  }
@@ -1965,7 +1042,7 @@ async function createAuthAdapter(databaseType) {
1965
1042
  const defaultAuthDbPath = path.resolve(rootDir, "data", "auth.db");
1966
1043
  switch (databaseType) {
1967
1044
  case "sqlite":
1968
- return new chunkRDRJVCL5_cjs.SQLiteAuthAdapter({
1045
+ return new chunkI7HHI6QV_cjs.SQLiteAuthAdapter({
1969
1046
  path: getEnv("KYRO_AUTH_DB_PATH", defaultAuthDbPath)
1970
1047
  });
1971
1048
  case "postgres": {
@@ -1977,12 +1054,12 @@ async function createAuthAdapter(databaseType) {
1977
1054
  const sql = postgres.default(databaseUrl, { onnotice: () => {
1978
1055
  } });
1979
1056
  const drizzleDb = drizzle(sql);
1980
- return new chunkRALQO47U_cjs.PostgresAuthAdapter({ db: drizzleDb });
1057
+ return new chunk2OL4O2TH_cjs.PostgresAuthAdapter({ db: drizzleDb });
1981
1058
  }
1982
1059
  } catch (e) {
1983
1060
  console.warn("[Auth] Could not create PostgresAuthAdapter, falling back to SQLite auth adapter.");
1984
1061
  }
1985
- return new chunkRDRJVCL5_cjs.SQLiteAuthAdapter({
1062
+ return new chunkI7HHI6QV_cjs.SQLiteAuthAdapter({
1986
1063
  path: getEnv("KYRO_AUTH_DB_PATH", defaultAuthDbPath)
1987
1064
  });
1988
1065
  }
@@ -1996,12 +1073,12 @@ async function createAuthAdapter(databaseType) {
1996
1073
  const url = new URL(mongoUri);
1997
1074
  const dbName = url.pathname.replace(/^\//, "") || "kyro_cms";
1998
1075
  const mongoDb = client.db(dbName);
1999
- return new chunkXAEBVZTI_cjs.MongoDBAuthAdapter({ db: mongoDb });
1076
+ return new chunk4DA7QPLA_cjs.MongoDBAuthAdapter({ db: mongoDb });
2000
1077
  }
2001
1078
  } catch (e) {
2002
1079
  console.warn("[Auth] Could not create MongoDBAuthAdapter, falling back to SQLite auth adapter.");
2003
1080
  }
2004
- return new chunkRDRJVCL5_cjs.SQLiteAuthAdapter({
1081
+ return new chunkI7HHI6QV_cjs.SQLiteAuthAdapter({
2005
1082
  path: getEnv("KYRO_AUTH_DB_PATH", defaultAuthDbPath)
2006
1083
  });
2007
1084
  }
@@ -2014,7 +1091,7 @@ async function createAuthConfig(databaseType) {
2014
1091
  const distributed = getEnvBool("KYRO_DISTRIBUTED", false);
2015
1092
  let authAdapter;
2016
1093
  if (distributed) {
2017
- const { RedisAuthAdapter: RedisAuthAdapter2 } = await import('./redis-adapter-LPUWLE4Y.cjs');
1094
+ const { RedisAuthAdapter: RedisAuthAdapter2 } = await import('./redis-adapter-D2E2S3GB.cjs');
2018
1095
  const redisUrl = getEnv("REDIS_URL", "redis://localhost:6379");
2019
1096
  const redisTls = getEnvBool("REDIS_TLS", false);
2020
1097
  const redisAdapter = new RedisAuthAdapter2({ url: redisUrl, tls: redisTls });
@@ -2027,8 +1104,8 @@ async function createAuthConfig(databaseType) {
2027
1104
  await authAdapter.connect();
2028
1105
  }
2029
1106
  }
2030
- const email = chunkRDRJVCL5_cjs.EmailTransport.fromEnv() || void 0;
2031
- const passwordPolicy = new chunkRDRJVCL5_cjs.PasswordPolicy({
1107
+ const email = chunkIA6AU5PI_cjs.EmailTransport.fromEnv() || void 0;
1108
+ const passwordPolicy = new chunkIA6AU5PI_cjs.PasswordPolicy({
2032
1109
  minLength: getEnvNum("PASSWORD_MIN_LENGTH", 12),
2033
1110
  requireUppercase: getEnvBool("PASSWORD_REQUIRE_UPPERCASE", true),
2034
1111
  requireLowercase: getEnvBool("PASSWORD_REQUIRE_LOWERCASE", true),
@@ -2057,7 +1134,7 @@ async function createAuthConfig(databaseType) {
2057
1134
  max: getEnvNum("RATE_LIMIT_MAX_REQUESTS", 100)
2058
1135
  }
2059
1136
  });
2060
- auditLogger = new chunkR2YHJN6W_cjs.AuditLogger(
1137
+ auditLogger = new chunk5KVM3WEY_cjs.AuditLogger(
2061
1138
  redisClient,
2062
1139
  getEnvNum("AUDIT_LOG_RETENTION_DAYS", 30)
2063
1140
  );
@@ -2066,7 +1143,7 @@ async function createAuthConfig(databaseType) {
2066
1143
  maxAttempts: getEnvNum("LOCKOUT_MAX_ATTEMPTS", 5),
2067
1144
  lockDuration: getEnvNum("LOCKOUT_DURATION_MINUTES", 15) * 60 * 1e3
2068
1145
  });
2069
- rateLimiter = new chunkR2YHJN6W_cjs.InMemoryRateLimiter({
1146
+ rateLimiter = new chunk5KVM3WEY_cjs.InMemoryRateLimiter({
2070
1147
  "auth:login": {
2071
1148
  window: getEnvNum("RATE_LIMIT_AUTH_WINDOW_MS", 9e5),
2072
1149
  max: getEnvNum("RATE_LIMIT_AUTH_MAX_REQUESTS", 10)
@@ -2076,9 +1153,9 @@ async function createAuthConfig(databaseType) {
2076
1153
  max: getEnvNum("RATE_LIMIT_MAX_REQUESTS", 100)
2077
1154
  }
2078
1155
  });
2079
- auditLogger = getEnvBool("AUDIT_LOG_ENABLED", true) ? new chunkR2YHJN6W_cjs.InMemoryAuditLogger(getEnvNum("AUDIT_LOG_RETENTION_DAYS", 30)) : void 0;
1156
+ auditLogger = getEnvBool("AUDIT_LOG_ENABLED", true) ? new chunk5KVM3WEY_cjs.InMemoryAuditLogger(getEnvNum("AUDIT_LOG_RETENTION_DAYS", 30)) : void 0;
2080
1157
  }
2081
- const routes = new chunkR2YHJN6W_cjs.AuthRoutes({
1158
+ const routes = new chunk5KVM3WEY_cjs.AuthRoutes({
2082
1159
  redis: authAdapter,
2083
1160
  email,
2084
1161
  jwtSecret: getEnv("APP_SECRET", "change-me"),
@@ -2227,6 +1304,39 @@ var Auth = class {
2227
1304
  return { success: false, error: String(error) };
2228
1305
  }
2229
1306
  }
1307
+ async sendEmailVerification(userId) {
1308
+ try {
1309
+ const { token, expiresAt } = await this.adapter.createEmailVerificationToken(userId);
1310
+ return { success: true };
1311
+ } catch (error) {
1312
+ return { success: false, error: String(error) };
1313
+ }
1314
+ }
1315
+ async verifyEmail(token) {
1316
+ try {
1317
+ return await this.adapter.verifyEmailToken(token);
1318
+ } catch (error) {
1319
+ return { success: false, error: String(error) };
1320
+ }
1321
+ }
1322
+ async requestPasswordReset(email) {
1323
+ try {
1324
+ const result = await this.adapter.createPasswordResetToken(email);
1325
+ if (result.error) {
1326
+ return { success: false, error: result.error };
1327
+ }
1328
+ return { success: true };
1329
+ } catch (error) {
1330
+ return { success: false, error: String(error) };
1331
+ }
1332
+ }
1333
+ async resetPasswordWithToken(token, newPassword) {
1334
+ try {
1335
+ return await this.adapter.resetPasswordWithToken(token, newPassword);
1336
+ } catch (error) {
1337
+ return { success: false, error: String(error) };
1338
+ }
1339
+ }
2230
1340
  async deleteAccount(userId) {
2231
1341
  try {
2232
1342
  const user = await this.adapter.findUserById(userId);
@@ -2693,139 +1803,147 @@ async function createAuthStorage(config) {
2693
1803
  }
2694
1804
 
2695
1805
  // src/index.ts
2696
- chunkR2YHJN6W_cjs.init_secret();
1806
+ chunk5KVM3WEY_cjs.init_secret();
2697
1807
 
2698
1808
  Object.defineProperty(exports, "RedisAuthAdapter", {
2699
1809
  enumerable: true,
2700
- get: function () { return chunkH4XCAPA6_cjs.RedisAuthAdapter; }
1810
+ get: function () { return chunkV3LKPM3O_cjs.RedisAuthAdapter; }
2701
1811
  });
2702
1812
  Object.defineProperty(exports, "allSettingsGlobals", {
2703
1813
  enumerable: true,
2704
- get: function () { return chunkZ2OVHWHB_cjs.allSettingsGlobals; }
1814
+ get: function () { return chunk6IMPH6WV_cjs.allSettingsGlobals; }
2705
1815
  });
2706
1816
  Object.defineProperty(exports, "blogCollections", {
2707
1817
  enumerable: true,
2708
- get: function () { return chunkZ2OVHWHB_cjs.blogCollections; }
1818
+ get: function () { return chunk6IMPH6WV_cjs.blogCollections; }
2709
1819
  });
2710
1820
  Object.defineProperty(exports, "blogGlobals", {
2711
1821
  enumerable: true,
2712
- get: function () { return chunkZ2OVHWHB_cjs.blogGlobals; }
1822
+ get: function () { return chunk6IMPH6WV_cjs.blogGlobals; }
2713
1823
  });
2714
1824
  Object.defineProperty(exports, "coreSettingsGlobals", {
2715
1825
  enumerable: true,
2716
- get: function () { return chunkZ2OVHWHB_cjs.coreSettingsGlobals; }
1826
+ get: function () { return chunk6IMPH6WV_cjs.coreSettingsGlobals; }
2717
1827
  });
2718
1828
  Object.defineProperty(exports, "createTemplateConfig", {
2719
1829
  enumerable: true,
2720
- get: function () { return chunkZ2OVHWHB_cjs.createTemplateConfig; }
1830
+ get: function () { return chunk6IMPH6WV_cjs.createTemplateConfig; }
2721
1831
  });
2722
1832
  Object.defineProperty(exports, "ecommerceCollections", {
2723
1833
  enumerable: true,
2724
- get: function () { return chunkZ2OVHWHB_cjs.ecommerceCollections; }
1834
+ get: function () { return chunk6IMPH6WV_cjs.ecommerceCollections; }
2725
1835
  });
2726
1836
  Object.defineProperty(exports, "ecommerceGlobals", {
2727
1837
  enumerable: true,
2728
- get: function () { return chunkZ2OVHWHB_cjs.ecommerceGlobals; }
2729
- });
2730
- Object.defineProperty(exports, "ecommerceSettingsGlobals", {
2731
- enumerable: true,
2732
- get: function () { return chunkZ2OVHWHB_cjs.ecommerceSettingsGlobals; }
1838
+ get: function () { return chunk6IMPH6WV_cjs.ecommerceGlobals; }
2733
1839
  });
2734
1840
  Object.defineProperty(exports, "kitchenSinkCollections", {
2735
1841
  enumerable: true,
2736
- get: function () { return chunkZ2OVHWHB_cjs.kitchenSinkCollections; }
1842
+ get: function () { return chunk6IMPH6WV_cjs.kitchenSinkCollections; }
2737
1843
  });
2738
1844
  Object.defineProperty(exports, "mediaCollections", {
2739
1845
  enumerable: true,
2740
- get: function () { return chunkZ2OVHWHB_cjs.mediaCollections; }
1846
+ get: function () { return chunk6IMPH6WV_cjs.mediaCollections; }
2741
1847
  });
2742
1848
  Object.defineProperty(exports, "minimalCollections", {
2743
1849
  enumerable: true,
2744
- get: function () { return chunkZ2OVHWHB_cjs.minimalCollections; }
1850
+ get: function () { return chunk6IMPH6WV_cjs.minimalCollections; }
2745
1851
  });
2746
1852
  Object.defineProperty(exports, "kyro", {
2747
1853
  enumerable: true,
2748
- get: function () { return chunkWBCIEYHC_cjs.kyro; }
1854
+ get: function () { return chunkQUW2RZTM_cjs.kyro; }
2749
1855
  });
2750
1856
  Object.defineProperty(exports, "ConfigValidationError", {
2751
1857
  enumerable: true,
2752
- get: function () { return chunk55BNRTLW_cjs.ConfigValidationError; }
1858
+ get: function () { return chunkLINKCEG4_cjs.ConfigValidationError; }
2753
1859
  });
2754
1860
  Object.defineProperty(exports, "Kyro", {
2755
1861
  enumerable: true,
2756
- get: function () { return chunk55BNRTLW_cjs.Kyro; }
1862
+ get: function () { return chunkLINKCEG4_cjs.Kyro; }
1863
+ });
1864
+ Object.defineProperty(exports, "LocalAdapter", {
1865
+ enumerable: true,
1866
+ get: function () { return chunkLINKCEG4_cjs.LocalAdapter; }
2757
1867
  });
2758
1868
  Object.defineProperty(exports, "Registry", {
2759
1869
  enumerable: true,
2760
- get: function () { return chunk55BNRTLW_cjs.Registry; }
1870
+ get: function () { return chunkLINKCEG4_cjs.Registry; }
2761
1871
  });
2762
1872
  Object.defineProperty(exports, "collectionToCreateZod", {
2763
1873
  enumerable: true,
2764
- get: function () { return chunk55BNRTLW_cjs.collectionToCreateZod; }
1874
+ get: function () { return chunkLINKCEG4_cjs.collectionToCreateZod; }
2765
1875
  });
2766
1876
  Object.defineProperty(exports, "collectionToUpdateZod", {
2767
1877
  enumerable: true,
2768
- get: function () { return chunk55BNRTLW_cjs.collectionToUpdateZod; }
1878
+ get: function () { return chunkLINKCEG4_cjs.collectionToUpdateZod; }
2769
1879
  });
2770
1880
  Object.defineProperty(exports, "collectionToWhereZod", {
2771
1881
  enumerable: true,
2772
- get: function () { return chunk55BNRTLW_cjs.collectionToWhereZod; }
1882
+ get: function () { return chunkLINKCEG4_cjs.collectionToWhereZod; }
2773
1883
  });
2774
1884
  Object.defineProperty(exports, "collectionToZod", {
2775
1885
  enumerable: true,
2776
- get: function () { return chunk55BNRTLW_cjs.collectionToZod; }
1886
+ get: function () { return chunkLINKCEG4_cjs.collectionToZod; }
2777
1887
  });
2778
1888
  Object.defineProperty(exports, "createKyro", {
2779
1889
  enumerable: true,
2780
- get: function () { return chunk55BNRTLW_cjs.createKyro; }
1890
+ get: function () { return chunkLINKCEG4_cjs.createKyro; }
1891
+ });
1892
+ Object.defineProperty(exports, "createLocalAdapter", {
1893
+ enumerable: true,
1894
+ get: function () { return chunkLINKCEG4_cjs.createLocalAdapter; }
2781
1895
  });
2782
1896
  Object.defineProperty(exports, "createRegistry", {
2783
1897
  enumerable: true,
2784
- get: function () { return chunk55BNRTLW_cjs.createRegistry; }
1898
+ get: function () { return chunkLINKCEG4_cjs.createRegistry; }
2785
1899
  });
2786
1900
  Object.defineProperty(exports, "fieldToZod", {
2787
1901
  enumerable: true,
2788
- get: function () { return chunk55BNRTLW_cjs.fieldToZod; }
1902
+ get: function () { return chunkLINKCEG4_cjs.fieldToZod; }
2789
1903
  });
2790
1904
  Object.defineProperty(exports, "getRegistry", {
2791
1905
  enumerable: true,
2792
- get: function () { return chunk55BNRTLW_cjs.getRegistry; }
1906
+ get: function () { return chunkLINKCEG4_cjs.getRegistry; }
2793
1907
  });
2794
1908
  Object.defineProperty(exports, "globalToZod", {
2795
1909
  enumerable: true,
2796
- get: function () { return chunk55BNRTLW_cjs.globalToZod; }
1910
+ get: function () { return chunkLINKCEG4_cjs.globalToZod; }
2797
1911
  });
2798
1912
  Object.defineProperty(exports, "resetRegistry", {
2799
1913
  enumerable: true,
2800
- get: function () { return chunk55BNRTLW_cjs.resetRegistry; }
1914
+ get: function () { return chunkLINKCEG4_cjs.resetRegistry; }
2801
1915
  });
2802
1916
  Object.defineProperty(exports, "validateCollection", {
2803
1917
  enumerable: true,
2804
- get: function () { return chunk55BNRTLW_cjs.validateCollection; }
1918
+ get: function () { return chunkLINKCEG4_cjs.validateCollection; }
2805
1919
  });
2806
1920
  Object.defineProperty(exports, "validateConfig", {
2807
1921
  enumerable: true,
2808
- get: function () { return chunk55BNRTLW_cjs.validateConfig; }
1922
+ get: function () { return chunkLINKCEG4_cjs.validateConfig; }
2809
1923
  });
2810
1924
  Object.defineProperty(exports, "validateFields", {
2811
1925
  enumerable: true,
2812
- get: function () { return chunk55BNRTLW_cjs.validateFields; }
1926
+ get: function () { return chunkLINKCEG4_cjs.validateFields; }
2813
1927
  });
2814
1928
  Object.defineProperty(exports, "validateGlobal", {
2815
1929
  enumerable: true,
2816
- get: function () { return chunk55BNRTLW_cjs.validateGlobal; }
1930
+ get: function () { return chunkLINKCEG4_cjs.validateGlobal; }
2817
1931
  });
2818
1932
  Object.defineProperty(exports, "autoBootstrap", {
2819
1933
  enumerable: true,
2820
- get: function () { return chunk5HA5OMFH_cjs.autoBootstrap; }
1934
+ get: function () { return chunkYVUJBEXE_cjs.autoBootstrap; }
2821
1935
  });
2822
1936
  Object.defineProperty(exports, "bootstrapAdmin", {
2823
1937
  enumerable: true,
2824
- get: function () { return chunk5HA5OMFH_cjs.bootstrapAdmin; }
1938
+ get: function () { return chunkYVUJBEXE_cjs.bootstrapAdmin; }
1939
+ });
1940
+ Object.defineProperty(exports, "bootstrapWithRetry", {
1941
+ enumerable: true,
1942
+ get: function () { return chunkYVUJBEXE_cjs.bootstrapWithRetry; }
2825
1943
  });
2826
1944
  Object.defineProperty(exports, "getBootstrapFromEnv", {
2827
1945
  enumerable: true,
2828
- get: function () { return chunk5HA5OMFH_cjs.getBootstrapFromEnv; }
1946
+ get: function () { return chunkYVUJBEXE_cjs.getBootstrapFromEnv; }
2829
1947
  });
2830
1948
  Object.defineProperty(exports, "CSSGenerator", {
2831
1949
  enumerable: true,
@@ -2981,75 +2099,75 @@ Object.defineProperty(exports, "createUpdateProcedure", {
2981
2099
  });
2982
2100
  Object.defineProperty(exports, "AuditLogger", {
2983
2101
  enumerable: true,
2984
- get: function () { return chunkR2YHJN6W_cjs.AuditLogger; }
2102
+ get: function () { return chunk5KVM3WEY_cjs.AuditLogger; }
2985
2103
  });
2986
2104
  Object.defineProperty(exports, "InMemoryAuditLogger", {
2987
2105
  enumerable: true,
2988
- get: function () { return chunkR2YHJN6W_cjs.InMemoryAuditLogger; }
2106
+ get: function () { return chunk5KVM3WEY_cjs.InMemoryAuditLogger; }
2989
2107
  });
2990
2108
  Object.defineProperty(exports, "InMemoryRateLimiter", {
2991
2109
  enumerable: true,
2992
- get: function () { return chunkR2YHJN6W_cjs.InMemoryRateLimiter; }
2110
+ get: function () { return chunk5KVM3WEY_cjs.InMemoryRateLimiter; }
2993
2111
  });
2994
2112
  Object.defineProperty(exports, "MediaService", {
2995
2113
  enumerable: true,
2996
- get: function () { return chunkR2YHJN6W_cjs.MediaService; }
2114
+ get: function () { return chunk5KVM3WEY_cjs.MediaService; }
2997
2115
  });
2998
2116
  Object.defineProperty(exports, "createAuditContext", {
2999
2117
  enumerable: true,
3000
- get: function () { return chunkR2YHJN6W_cjs.createAuditContext; }
2118
+ get: function () { return chunk5KVM3WEY_cjs.createAuditContext; }
3001
2119
  });
3002
2120
  Object.defineProperty(exports, "createHonoApp", {
3003
2121
  enumerable: true,
3004
- get: function () { return chunkR2YHJN6W_cjs.createHonoApp; }
2122
+ get: function () { return chunk5KVM3WEY_cjs.createHonoApp; }
3005
2123
  });
3006
2124
  Object.defineProperty(exports, "createLocalStorage", {
3007
2125
  enumerable: true,
3008
- get: function () { return chunkR2YHJN6W_cjs.createLocalStorage; }
2126
+ get: function () { return chunk5KVM3WEY_cjs.createLocalStorage; }
3009
2127
  });
3010
2128
  Object.defineProperty(exports, "createRESTAPI", {
3011
2129
  enumerable: true,
3012
- get: function () { return chunkR2YHJN6W_cjs.createRESTAPI; }
2130
+ get: function () { return chunk5KVM3WEY_cjs.createRESTAPI; }
3013
2131
  });
3014
2132
  Object.defineProperty(exports, "getAppSecret", {
3015
2133
  enumerable: true,
3016
- get: function () { return chunkR2YHJN6W_cjs.getAppSecret; }
2134
+ get: function () { return chunk5KVM3WEY_cjs.getAppSecret; }
3017
2135
  });
3018
2136
  Object.defineProperty(exports, "getEncryptionKey", {
3019
2137
  enumerable: true,
3020
- get: function () { return chunkR2YHJN6W_cjs.getEncryptionKey; }
2138
+ get: function () { return chunk5KVM3WEY_cjs.getEncryptionKey; }
3021
2139
  });
3022
2140
  Object.defineProperty(exports, "getSessionConfig", {
3023
2141
  enumerable: true,
3024
- get: function () { return chunkR2YHJN6W_cjs.getSessionConfig; }
2142
+ get: function () { return chunk5KVM3WEY_cjs.getSessionConfig; }
3025
2143
  });
3026
2144
  Object.defineProperty(exports, "loadSecrets", {
3027
2145
  enumerable: true,
3028
- get: function () { return chunkR2YHJN6W_cjs.loadSecrets; }
2146
+ get: function () { return chunk5KVM3WEY_cjs.loadSecrets; }
3029
2147
  });
3030
2148
  Object.defineProperty(exports, "resolveProvider", {
3031
2149
  enumerable: true,
3032
- get: function () { return chunkR2YHJN6W_cjs.resolveProvider; }
2150
+ get: function () { return chunk5KVM3WEY_cjs.resolveProvider; }
3033
2151
  });
3034
2152
  Object.defineProperty(exports, "setDbAdapter", {
3035
2153
  enumerable: true,
3036
- get: function () { return chunkR2YHJN6W_cjs.setDbAdapter; }
2154
+ get: function () { return chunk5KVM3WEY_cjs.setDbAdapter; }
3037
2155
  });
3038
2156
  Object.defineProperty(exports, "ConfigService", {
3039
2157
  enumerable: true,
3040
- get: function () { return chunkRDRJVCL5_cjs.ConfigService; }
2158
+ get: function () { return chunkIA6AU5PI_cjs.ConfigService; }
3041
2159
  });
3042
2160
  Object.defineProperty(exports, "EmailTransport", {
3043
2161
  enumerable: true,
3044
- get: function () { return chunkRDRJVCL5_cjs.EmailTransport; }
2162
+ get: function () { return chunkIA6AU5PI_cjs.EmailTransport; }
3045
2163
  });
3046
2164
  Object.defineProperty(exports, "PasswordPolicy", {
3047
2165
  enumerable: true,
3048
- get: function () { return chunkRDRJVCL5_cjs.PasswordPolicy; }
2166
+ get: function () { return chunkIA6AU5PI_cjs.PasswordPolicy; }
3049
2167
  });
3050
2168
  Object.defineProperty(exports, "SQLiteAuthAdapter", {
3051
2169
  enumerable: true,
3052
- get: function () { return chunkRDRJVCL5_cjs.SQLiteAuthAdapter; }
2170
+ get: function () { return chunkI7HHI6QV_cjs.SQLiteAuthAdapter; }
3053
2171
  });
3054
2172
  Object.defineProperty(exports, "ALL_WEBHOOK_EVENTS", {
3055
2173
  enumerable: true,
@@ -3137,47 +2255,51 @@ Object.defineProperty(exports, "createWSServer", {
3137
2255
  });
3138
2256
  Object.defineProperty(exports, "DrizzleAdapter", {
3139
2257
  enumerable: true,
3140
- get: function () { return chunkWVPOPOEQ_cjs.DrizzleAdapter; }
2258
+ get: function () { return chunk2KVHZE6O_cjs.DrizzleAdapter; }
3141
2259
  });
3142
2260
  Object.defineProperty(exports, "collectionToDrizzleSchema", {
3143
2261
  enumerable: true,
3144
- get: function () { return chunkWVPOPOEQ_cjs.collectionToDrizzleSchema; }
2262
+ get: function () { return chunk2KVHZE6O_cjs.collectionToDrizzleSchema; }
3145
2263
  });
3146
2264
  Object.defineProperty(exports, "createDatabase", {
3147
2265
  enumerable: true,
3148
- get: function () { return chunkWVPOPOEQ_cjs.createDatabase; }
2266
+ get: function () { return chunk2KVHZE6O_cjs.createDatabase; }
3149
2267
  });
3150
2268
  Object.defineProperty(exports, "createDrizzleAdapter", {
3151
2269
  enumerable: true,
3152
- get: function () { return chunkWVPOPOEQ_cjs.createDrizzleAdapter; }
2270
+ get: function () { return chunk2KVHZE6O_cjs.createDrizzleAdapter; }
3153
2271
  });
3154
2272
  Object.defineProperty(exports, "fieldToDrizzleType", {
3155
2273
  enumerable: true,
3156
- get: function () { return chunkWVPOPOEQ_cjs.fieldToDrizzleType; }
2274
+ get: function () { return chunk2KVHZE6O_cjs.fieldToDrizzleType; }
3157
2275
  });
3158
2276
  Object.defineProperty(exports, "runMigrations", {
3159
2277
  enumerable: true,
3160
- get: function () { return chunkWVPOPOEQ_cjs.runMigrations; }
2278
+ get: function () { return chunk2KVHZE6O_cjs.runMigrations; }
3161
2279
  });
3162
2280
  Object.defineProperty(exports, "seedDefaultRoles", {
3163
2281
  enumerable: true,
3164
- get: function () { return chunkWVPOPOEQ_cjs.seedDefaultRoles; }
2282
+ get: function () { return chunk2KVHZE6O_cjs.seedDefaultRoles; }
3165
2283
  });
3166
2284
  Object.defineProperty(exports, "PostgresAuthAdapter", {
3167
2285
  enumerable: true,
3168
- get: function () { return chunkRALQO47U_cjs.PostgresAuthAdapter; }
2286
+ get: function () { return chunk2OL4O2TH_cjs.PostgresAuthAdapter; }
3169
2287
  });
3170
2288
  Object.defineProperty(exports, "MongoDBAdapter", {
3171
2289
  enumerable: true,
3172
- get: function () { return chunkXAEBVZTI_cjs.MongoDBAdapter; }
2290
+ get: function () { return chunkPDYFVNUX_cjs.MongoDBAdapter; }
3173
2291
  });
3174
2292
  Object.defineProperty(exports, "createMongoDBAdapter", {
3175
2293
  enumerable: true,
3176
- get: function () { return chunkXAEBVZTI_cjs.createMongoDBAdapter; }
2294
+ get: function () { return chunkPDYFVNUX_cjs.createMongoDBAdapter; }
2295
+ });
2296
+ Object.defineProperty(exports, "MongoDBAuthAdapter", {
2297
+ enumerable: true,
2298
+ get: function () { return chunk4DA7QPLA_cjs.MongoDBAuthAdapter; }
3177
2299
  });
3178
2300
  Object.defineProperty(exports, "AbstractBaseAdapter", {
3179
2301
  enumerable: true,
3180
- get: function () { return chunkKOCTZKPV_cjs.AbstractBaseAdapter; }
2302
+ get: function () { return chunkSA7NSSIQ_cjs.AbstractBaseAdapter; }
3181
2303
  });
3182
2304
  Object.defineProperty(exports, "z", {
3183
2305
  enumerable: true,
@@ -3190,7 +2312,6 @@ exports.CommentsPlugin = CommentsPlugin;
3190
2312
  exports.InMemoryAccountLockout = InMemoryAccountLockout;
3191
2313
  exports.InMemoryAuthAdapter = InMemoryAuthAdapter;
3192
2314
  exports.KyroPlugin = KyroPlugin;
3193
- exports.LocalAdapter = LocalAdapter;
3194
2315
  exports.PluginManager = PluginManager;
3195
2316
  exports.RateLimiter = RateLimiter;
3196
2317
  exports.ReviewsPlugin = ReviewsPlugin;
@@ -3201,7 +2322,6 @@ exports.authConfig = authConfig;
3201
2322
  exports.createAuth = createAuth;
3202
2323
  exports.createAuthConfig = createAuthConfig;
3203
2324
  exports.createAuthStorage = createAuthStorage;
3204
- exports.createLocalAdapter = createLocalAdapter;
3205
2325
  exports.createStorage = createStorage3;
3206
2326
  exports.createVersionManager = createVersionManager;
3207
2327
  exports.defineConfig = defineConfig;