@kyro-cms/core 0.6.0 → 0.7.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
@@ -1,6 +1,7 @@
1
- import { AbstractBaseAdapter } from './chunk-A4USRVTQ.js';
2
- import { sql, eq, desc, and } from 'drizzle-orm';
3
- import { text, uuid, jsonb, timestamp, boolean, decimal, integer, varchar, pgTable } from 'drizzle-orm/pg-core';
1
+ import { AbstractBaseAdapter, applyRLS, DEFAULT_RLS_CONFIG, canAccessDocument } from './chunk-3ZFYL34R.js';
2
+ import { sql, eq, desc, and, or, ne, inArray, like, gt, gte, lt, lte } from 'drizzle-orm';
3
+ import { text, uuid, jsonb, timestamp, boolean, decimal, integer as integer$1, varchar, pgTable } from 'drizzle-orm/pg-core';
4
+ import { text as text$1, integer, numeric, sqliteTable } from 'drizzle-orm/sqlite-core';
4
5
  import { drizzle } from 'drizzle-orm/postgres-js';
5
6
  import postgres from 'postgres';
6
7
  import { randomBytes } from 'crypto';
@@ -85,6 +86,13 @@ var DrizzleAdapter = class extends AbstractBaseAdapter {
85
86
  connectionString;
86
87
  draftsTableReady = false;
87
88
  versionsTableReady = false;
89
+ tenantContext;
90
+ setTenantContext(context) {
91
+ this.tenantContext = context;
92
+ }
93
+ getTenantContext() {
94
+ return this.tenantContext;
95
+ }
88
96
  constructor(options) {
89
97
  super();
90
98
  this.schema = options.schema || {};
@@ -93,8 +101,10 @@ var DrizzleAdapter = class extends AbstractBaseAdapter {
93
101
  const connStr = options.connectionString.toLowerCase();
94
102
  if (connStr.startsWith("postgres://") || connStr.startsWith("postgresql://")) {
95
103
  this.dialect = "postgres";
96
- } else {
104
+ } else if (connStr.includes(".db") || connStr.includes("sqlite") || connStr.includes("file:")) {
97
105
  this.dialect = "sqlite";
106
+ } else {
107
+ this.dialect = options.type || "postgres";
98
108
  }
99
109
  } else {
100
110
  this.client = options.client;
@@ -110,7 +120,7 @@ var DrizzleAdapter = class extends AbstractBaseAdapter {
110
120
  result.updatedAt = new Date(result.updatedAt);
111
121
  }
112
122
  for (const field of config.fields) {
113
- const dbType = fieldToDrizzleType(field, "postgres");
123
+ const dbType = fieldToDrizzleType(field, this.dialect);
114
124
  const isJsonb = dbType === "jsonb";
115
125
  if (field.type === "tabs" && "tabs" in field && field.name) {
116
126
  const tabData = data[field.name];
@@ -141,18 +151,28 @@ var DrizzleAdapter = class extends AbstractBaseAdapter {
141
151
  }
142
152
  async connect() {
143
153
  if (this.connectionString && !this.client) {
144
- const { default: postgres2 } = await import('postgres');
145
- const { drizzle: drizzle2 } = await import('drizzle-orm/postgres-js');
146
- const sql2 = postgres2(this.connectionString, { onnotice: () => {
147
- } });
148
- this.client = drizzle2(sql2, { schema: this.schema });
154
+ if (this.dialect === "postgres") {
155
+ const { default: postgres2 } = await import('postgres');
156
+ const { drizzle: drizzle2 } = await import('drizzle-orm/postgres-js');
157
+ const sql2 = postgres2(this.connectionString, { onnotice: () => {
158
+ } });
159
+ this.client = drizzle2(sql2, { schema: this.schema });
160
+ } else if (this.dialect === "sqlite") {
161
+ const { default: betterSqlite3 } = await import('better-sqlite3');
162
+ const { drizzle: drizzle2 } = await import('drizzle-orm/better-sqlite3');
163
+ const db = new betterSqlite3(this.connectionString.replace("file:", ""));
164
+ this.client = drizzle2(db, { schema: this.schema });
165
+ }
149
166
  }
150
167
  this.connected = true;
151
168
  console.log(`[DrizzleAdapter] Connected to ${this.dialect}`);
152
169
  }
153
170
  async init(collections, globals = []) {
154
171
  await super.init(collections, globals);
155
- if (this.dialect === "postgres" && this.client && !_schemaEnsured) {
172
+ if (this.connectionString && !this.client) {
173
+ await this.connect();
174
+ }
175
+ if (this.client && !_schemaEnsured) {
156
176
  for (const config of collections) {
157
177
  const tableName = this.getTableName(config.slug);
158
178
  if (!this.schema[tableName]) {
@@ -185,91 +205,168 @@ var DrizzleAdapter = class extends AbstractBaseAdapter {
185
205
  };
186
206
  for (const field of config.fields) {
187
207
  if (!field.name || field.name === "id") continue;
188
- const dbType = fieldToDrizzleType(field, "postgres");
208
+ const dbType = fieldToDrizzleType(field, this.dialect);
189
209
  const propName = field.name.replace(/-/g, "_");
190
210
  const sqlName = propName.replace(/([A-Z])/g, "_$1").toLowerCase();
191
211
  let col;
192
- switch (dbType) {
193
- case "varchar":
194
- col = varchar(sqlName, { length: 255 });
195
- break;
196
- case "integer":
197
- col = integer(sqlName);
198
- break;
199
- case "decimal":
200
- col = decimal(sqlName);
201
- break;
202
- case "boolean":
203
- col = boolean(sqlName);
204
- break;
205
- case "timestamp":
206
- col = timestamp(sqlName);
207
- break;
208
- case "jsonb":
209
- col = jsonb(sqlName);
210
- break;
211
- default:
212
- col = text(sqlName);
212
+ if (this.dialect === "sqlite") {
213
+ switch (dbType) {
214
+ case "varchar":
215
+ case "text":
216
+ col = text$1(sqlName);
217
+ break;
218
+ case "integer":
219
+ col = integer(sqlName);
220
+ break;
221
+ case "decimal":
222
+ case "numeric":
223
+ col = numeric(sqlName);
224
+ break;
225
+ case "boolean":
226
+ col = integer(sqlName, { mode: "boolean" });
227
+ break;
228
+ case "timestamp":
229
+ col = text$1(sqlName);
230
+ break;
231
+ case "jsonb":
232
+ col = text$1(sqlName);
233
+ break;
234
+ default:
235
+ col = text$1(sqlName);
236
+ }
237
+ } else {
238
+ switch (dbType) {
239
+ case "varchar":
240
+ col = varchar(sqlName, { length: 255 });
241
+ break;
242
+ case "integer":
243
+ col = integer$1(sqlName);
244
+ break;
245
+ case "decimal":
246
+ col = decimal(sqlName);
247
+ break;
248
+ case "boolean":
249
+ col = boolean(sqlName);
250
+ break;
251
+ case "timestamp":
252
+ col = timestamp(sqlName);
253
+ break;
254
+ case "jsonb":
255
+ col = jsonb(sqlName);
256
+ break;
257
+ default:
258
+ col = text(sqlName);
259
+ }
213
260
  }
214
261
  if (!field.required) col = col.default(null);
215
262
  columns[propName] = col;
216
263
  }
217
- if (!columns.createdAt) columns.createdAt = timestamp("created_at").defaultNow();
218
- if (!columns.updatedAt) columns.updatedAt = timestamp("updated_at").defaultNow();
219
- columns._status = varchar("_status", { length: 20 }).default("published");
220
- columns._has_draft = boolean("_has_draft").default(false);
221
- return pgTable(tableName, columns);
264
+ if (!columns.createdAt) columns.createdAt = this.dialect === "sqlite" ? text$1("created_at").default((/* @__PURE__ */ new Date()).toISOString()) : timestamp("created_at").defaultNow();
265
+ if (!columns.updatedAt) columns.updatedAt = this.dialect === "sqlite" ? text$1("updated_at").default((/* @__PURE__ */ new Date()).toISOString()) : timestamp("updated_at").defaultNow();
266
+ columns._status = this.dialect === "sqlite" ? text$1("_status").default("published") : varchar("_status", { length: 20 }).default("published");
267
+ columns._has_draft = this.dialect === "sqlite" ? integer("_has_draft", { mode: "boolean" }).default(false) : boolean("_has_draft").default(false);
268
+ return this.dialect === "sqlite" ? sqliteTable(tableName, columns) : pgTable(tableName, columns);
222
269
  }
223
270
  async ensureCollectionTables(collections) {
271
+ const statements = [];
224
272
  for (const config of collections) {
225
273
  const isGlobal = config.slug.startsWith("_globals_");
226
274
  const tableName = this.getTableName(config.slug);
227
- const tableIdent = sql.identifier(tableName);
228
275
  const colDefs = this.generateCreateColumns(config);
229
276
  const hasCreated = config.fields.some((f) => f.name === "createdAt");
230
277
  const hasUpdated = config.fields.some((f) => f.name === "updatedAt");
231
- const idCol = isGlobal ? '"id" TEXT PRIMARY KEY' : '"id" UUID PRIMARY KEY DEFAULT gen_random_uuid()';
232
- await this.client.execute(sql`
233
- CREATE TABLE IF NOT EXISTS ${tableIdent} (
234
- ${sql.raw(idCol)},
235
- ${sql.raw(colDefs)}
236
- ${hasCreated ? sql.raw("") : sql.raw('"created_at" TIMESTAMP NOT NULL DEFAULT NOW(),')}
237
- ${hasUpdated ? sql.raw("") : sql.raw('"updated_at" TIMESTAMP NOT NULL DEFAULT NOW(),')}
238
- "_status" VARCHAR(20) DEFAULT 'published',
239
- "_has_draft" BOOLEAN DEFAULT false
240
- )
241
- `);
278
+ if (this.dialect === "postgres") {
279
+ const idCol = isGlobal ? '"id" TEXT PRIMARY KEY' : '"id" UUID PRIMARY KEY DEFAULT gen_random_uuid()';
280
+ statements.push(`
281
+ CREATE TABLE IF NOT EXISTS "${tableName}" (
282
+ ${idCol},
283
+ ${colDefs}
284
+ ${hasCreated ? "" : '"created_at" TIMESTAMP NOT NULL DEFAULT NOW(),'}
285
+ ${hasUpdated ? "" : '"updated_at" TIMESTAMP NOT NULL DEFAULT NOW(),'}
286
+ "_status" VARCHAR(20) DEFAULT 'published',
287
+ "_has_draft" BOOLEAN DEFAULT false
288
+ )
289
+ `);
290
+ } else {
291
+ const idCol = isGlobal ? '"id" TEXT PRIMARY KEY' : '"id" TEXT PRIMARY KEY';
292
+ statements.push(`
293
+ CREATE TABLE IF NOT EXISTS "${tableName}" (
294
+ ${idCol},
295
+ ${colDefs}
296
+ ${hasCreated ? "" : `"created_at" TEXT NOT NULL DEFAULT (datetime('now')),`}
297
+ ${hasUpdated ? "" : `"updated_at" TEXT NOT NULL DEFAULT (datetime('now')),`}
298
+ "_status" TEXT DEFAULT 'published',
299
+ "_has_draft" INTEGER DEFAULT 0
300
+ )
301
+ `);
302
+ }
303
+ }
304
+ if (statements.length > 0) {
305
+ if (this.dialect === "postgres") {
306
+ await this.client.execute(sql.raw(statements.join(";\n")));
307
+ } else {
308
+ for (const stmt of statements) {
309
+ await this.client.execute(sql.raw(stmt));
310
+ }
311
+ }
242
312
  }
243
313
  }
244
314
  generateCreateColumns(config) {
245
315
  const cols = [];
246
316
  for (const field of config.fields) {
247
317
  if (!field.name || field.name === "id") continue;
248
- const dbType = fieldToDrizzleType(field, "postgres");
318
+ const dbType = fieldToDrizzleType(field, this.dialect);
249
319
  const sqlName = field.name.replace(/-/g, "_").replace(/([A-Z])/g, "_$1").toLowerCase();
250
320
  const nullable = field.required ? "NOT NULL" : "DEFAULT NULL";
251
321
  let sqlType;
252
- switch (dbType) {
253
- case "varchar":
254
- sqlType = `VARCHAR(255) ${nullable}`;
255
- break;
256
- case "integer":
257
- sqlType = `INTEGER ${nullable}`;
258
- break;
259
- case "decimal":
260
- sqlType = `DECIMAL ${nullable}`;
261
- break;
262
- case "boolean":
263
- sqlType = `BOOLEAN ${nullable}`;
264
- break;
265
- case "timestamp":
266
- sqlType = `TIMESTAMP ${nullable}`;
267
- break;
268
- case "jsonb":
269
- sqlType = `JSONB ${nullable}`;
270
- break;
271
- default:
272
- sqlType = `TEXT ${nullable}`;
322
+ if (this.dialect === "sqlite") {
323
+ switch (dbType) {
324
+ case "varchar":
325
+ case "text":
326
+ sqlType = `TEXT ${nullable}`;
327
+ break;
328
+ case "integer":
329
+ sqlType = `INTEGER ${nullable}`;
330
+ break;
331
+ case "decimal":
332
+ case "numeric":
333
+ sqlType = `NUMERIC ${nullable}`;
334
+ break;
335
+ case "boolean":
336
+ sqlType = `INTEGER ${nullable}`;
337
+ break;
338
+ case "timestamp":
339
+ sqlType = `TEXT ${nullable}`;
340
+ break;
341
+ case "jsonb":
342
+ sqlType = `TEXT ${nullable}`;
343
+ break;
344
+ default:
345
+ sqlType = `TEXT ${nullable}`;
346
+ }
347
+ } else {
348
+ switch (dbType) {
349
+ case "varchar":
350
+ sqlType = `VARCHAR(255) ${nullable}`;
351
+ break;
352
+ case "integer":
353
+ sqlType = `INTEGER ${nullable}`;
354
+ break;
355
+ case "decimal":
356
+ sqlType = `DECIMAL ${nullable}`;
357
+ break;
358
+ case "boolean":
359
+ sqlType = `BOOLEAN ${nullable}`;
360
+ break;
361
+ case "timestamp":
362
+ sqlType = `TIMESTAMP ${nullable}`;
363
+ break;
364
+ case "jsonb":
365
+ sqlType = `JSONB ${nullable}`;
366
+ break;
367
+ default:
368
+ sqlType = `TEXT ${nullable}`;
369
+ }
273
370
  }
274
371
  cols.push(`"${sqlName}" ${sqlType}`);
275
372
  }
@@ -283,22 +380,34 @@ var DrizzleAdapter = class extends AbstractBaseAdapter {
283
380
  const { collection: slug, where = {}, sort, limit = 10, page = 1, tenantID, select, draft } = args;
284
381
  const config = this.getCollection(slug);
285
382
  const table = this.getTable(slug);
286
- const filters = this.buildWhereClause(where, config, table, tenantID) || [];
383
+ let effectiveWhere = { ...where };
384
+ if (this.tenantContext && config.tenantScoped) {
385
+ const rlsQuery = applyRLS({ where: effectiveWhere }, slug, this.tenantContext, DEFAULT_RLS_CONFIG);
386
+ effectiveWhere = rlsQuery.where || {};
387
+ }
388
+ const filters = this.buildWhereClause(effectiveWhere, config, table, tenantID);
287
389
  if (!draft && table._status) {
288
390
  filters.push(eq(table._status, "published"));
289
391
  }
290
392
  const sortOption = this.parseSort(sort);
291
- const totalDocs = await this.count({ collection: slug, where: { ...where, _status: draft ? void 0 : "published" }, tenantID });
393
+ const totalDocs = await this.count({ collection: slug, where: effectiveWhere, tenantID });
292
394
  const offset = (page - 1) * limit;
293
395
  let results = [];
294
396
  try {
295
397
  const sortCol = table[sortOption.field] || table.createdAt || table.id;
296
398
  const sorted = sortOption.direction === "asc" ? sortCol : desc(sortCol);
297
- results = await this.client.select().from(table).where(filters).orderBy(sorted).limit(limit).offset(offset);
399
+ let query = this.client.select().from(table);
400
+ if (filters.length > 0) {
401
+ query = query.where(and(...filters));
402
+ }
403
+ results = await query.orderBy(sorted).limit(limit).offset(offset);
298
404
  } catch (error) {
299
405
  console.error(`[DrizzleAdapter] Query error:`, error);
300
406
  }
301
407
  let docs = results.map((doc) => this.processResult(doc, config));
408
+ if (this.tenantContext && !this.tenantContext.isSuperAdmin) {
409
+ docs = docs.filter((doc) => canAccessDocument(doc, slug, this.tenantContext, DEFAULT_RLS_CONFIG));
410
+ }
302
411
  if (draft) {
303
412
  docs = await Promise.all(docs.map(async (doc) => {
304
413
  if (doc._has_draft) {
@@ -324,6 +433,12 @@ var DrizzleAdapter = class extends AbstractBaseAdapter {
324
433
  const { collection: slug, id, tenantID, draft } = args;
325
434
  const config = this.getCollection(slug);
326
435
  const table = this.getTable(slug);
436
+ if (this.tenantContext && config.tenantScoped) {
437
+ const tempDoc = { id, tenantId: this.tenantContext.tenantId };
438
+ if (!canAccessDocument(tempDoc, slug, this.tenantContext, DEFAULT_RLS_CONFIG)) {
439
+ return null;
440
+ }
441
+ }
327
442
  const conditions = [eq(table.id, id)];
328
443
  if (tenantID && table.tenantId) conditions.push(eq(table.tenantId, tenantID));
329
444
  if (!draft && table._status) conditions.push(eq(table._status, "published"));
@@ -386,8 +501,12 @@ var DrizzleAdapter = class extends AbstractBaseAdapter {
386
501
  const table = this.getTable(slug);
387
502
  const filters = this.buildWhereClause(where, config, table, tenantID);
388
503
  try {
389
- const result = await this.client.select({ count: `count(*)` }).from(table).where(filters || void 0);
390
- return parseInt(result[0]?.count || "0");
504
+ let query = this.client.select({ count: sql`count(*)` }).from(table);
505
+ if (filters.length > 0) {
506
+ query = query.where(and(...filters));
507
+ }
508
+ const result = await query;
509
+ return Number(result[0]?.count || 0);
391
510
  } catch {
392
511
  return 0;
393
512
  }
@@ -593,32 +712,38 @@ var DrizzleAdapter = class extends AbstractBaseAdapter {
593
712
  }
594
713
  buildWhereClause(where, config, table, tenantID) {
595
714
  const conditions = [];
596
- if (tenantID && config.tenantScoped) {
597
- conditions.push({ tenantId: tenantID });
715
+ if (tenantID && config.tenantScoped && table.tenantId) {
716
+ conditions.push(eq(table.tenantId, tenantID));
598
717
  }
599
718
  for (const [key, value] of Object.entries(where)) {
600
719
  if (key === "AND" && Array.isArray(value)) {
601
- for (const subCondition of value) {
602
- conditions.push(...Object.entries(subCondition).map(([k, v]) => ({ [k]: v })));
720
+ const andConditions = value.map((sub) => this.buildWhereClause(sub, config, table)).flat().filter(Boolean);
721
+ if (andConditions.length > 0) {
722
+ conditions.push(and(...andConditions));
603
723
  }
604
724
  } else if (key === "OR" && Array.isArray(value)) {
605
- conditions.push(...value.flatMap(
606
- (v) => Object.entries(v).map(([k, val]) => ({ [k]: val }))
607
- ));
608
- } else if (typeof value === "object" && value !== null) {
609
- if (value.equals !== void 0) conditions.push(eq(table[key], value.equals));
610
- if (value.not_equals !== void 0) conditions.push({ [key]: { not: value.not_equals } });
611
- if (value.in) conditions.push({ [key]: { in: value.in } });
612
- if (value.like) conditions.push({ [key]: { like: value.like } });
613
- if (value.greater_than !== void 0) conditions.push({ [key]: { gt: value.greater_than } });
614
- if (value.greater_than_equal !== void 0) conditions.push({ [key]: { gte: value.greater_than_equal } });
615
- if (value.less_than !== void 0) conditions.push({ [key]: { lt: value.less_than } });
616
- if (value.less_than_equal !== void 0) conditions.push({ [key]: { lte: value.less_than_equal } });
725
+ const orConditions = value.map((sub) => this.buildWhereClause(sub, config, table)).flat().filter(Boolean);
726
+ if (orConditions.length > 0) {
727
+ conditions.push(or(...orConditions));
728
+ }
729
+ } else if (typeof value === "object" && value !== null && !Array.isArray(value)) {
730
+ const col = table[key];
731
+ if (!col) continue;
732
+ if (value.equals !== void 0) conditions.push(eq(col, value.equals));
733
+ if (value.not_equals !== void 0) conditions.push(ne(col, value.not_equals));
734
+ if (value.in && Array.isArray(value.in)) conditions.push(inArray(col, value.in));
735
+ if (value.like !== void 0) conditions.push(like(col, value.like));
736
+ if (value.contains !== void 0) conditions.push(like(col, `%${value.contains}%`));
737
+ if (value.greater_than !== void 0) conditions.push(gt(col, value.greater_than));
738
+ if (value.greater_than_equal !== void 0) conditions.push(gte(col, value.greater_than_equal));
739
+ if (value.less_than !== void 0) conditions.push(lt(col, value.less_than));
740
+ if (value.less_than_equal !== void 0) conditions.push(lte(col, value.less_than_equal));
617
741
  } else {
618
- conditions.push({ [key]: value });
742
+ const col = table[key];
743
+ if (col) conditions.push(eq(col, value));
619
744
  }
620
745
  }
621
- return conditions.length > 0 ? conditions : void 0;
746
+ return conditions;
622
747
  }
623
748
  processResult(data, config) {
624
749
  if (!data) return null;
@@ -690,39 +815,74 @@ var DrizzleAdapter = class extends AbstractBaseAdapter {
690
815
  }
691
816
  async ensureDraftsTable() {
692
817
  if (_schemaEnsured || this.draftsTableReady) return;
693
- const createTableSQL = sql.raw(`
694
- CREATE TABLE IF NOT EXISTS kyro_drafts (
695
- id text PRIMARY KEY,
696
- collection_slug text NOT NULL,
697
- document_id text NOT NULL,
698
- tenant_id text,
699
- data text NOT NULL,
700
- base_updated_at text,
701
- draft_updated_at text NOT NULL,
702
- created_at text NOT NULL,
703
- updated_at text NOT NULL
704
- )
705
- `);
706
- await this.executeRaw(createTableSQL);
818
+ let createTableSQL;
819
+ if (this.dialect === "sqlite") {
820
+ createTableSQL = `
821
+ CREATE TABLE IF NOT EXISTS kyro_drafts (
822
+ id text PRIMARY KEY,
823
+ collection_slug text NOT NULL,
824
+ document_id text NOT NULL,
825
+ tenant_id text,
826
+ data text NOT NULL,
827
+ base_updated_at text,
828
+ draft_updated_at text NOT NULL,
829
+ created_at text DEFAULT (datetime('now')),
830
+ updated_at text DEFAULT (datetime('now'))
831
+ )
832
+ `;
833
+ } else {
834
+ createTableSQL = `
835
+ CREATE TABLE IF NOT EXISTS kyro_drafts (
836
+ id text PRIMARY KEY,
837
+ collection_slug text NOT NULL,
838
+ document_id text NOT NULL,
839
+ tenant_id text,
840
+ data text NOT NULL,
841
+ base_updated_at text,
842
+ draft_updated_at text NOT NULL,
843
+ created_at text NOT NULL,
844
+ updated_at text NOT NULL
845
+ )
846
+ `;
847
+ }
848
+ await this.executeRaw(sql.raw(createTableSQL));
707
849
  this.draftsTableReady = true;
708
850
  }
709
851
  async ensureVersionsTable() {
710
852
  if (_schemaEnsured || this.versionsTableReady) return;
711
- const createTableSQL = sql.raw(`
712
- CREATE TABLE IF NOT EXISTS kyro_versions (
713
- id text PRIMARY KEY,
714
- collection_slug text NOT NULL,
715
- document_id text NOT NULL,
716
- tenant_id text,
717
- data text NOT NULL,
718
- status text NOT NULL,
719
- created_by text,
720
- change_description text,
721
- created_at text NOT NULL,
722
- updated_at text NOT NULL
723
- )
724
- `);
725
- await this.executeRaw(createTableSQL);
853
+ let createTableSQL;
854
+ if (this.dialect === "sqlite") {
855
+ createTableSQL = `
856
+ CREATE TABLE IF NOT EXISTS kyro_versions (
857
+ id text PRIMARY KEY,
858
+ collection_slug text NOT NULL,
859
+ document_id text NOT NULL,
860
+ tenant_id text,
861
+ data text NOT NULL,
862
+ status text NOT NULL DEFAULT 'draft',
863
+ created_by text,
864
+ change_description text,
865
+ created_at text DEFAULT (datetime('now')),
866
+ updated_at text DEFAULT (datetime('now'))
867
+ )
868
+ `;
869
+ } else {
870
+ createTableSQL = `
871
+ CREATE TABLE IF NOT EXISTS kyro_versions (
872
+ id text PRIMARY KEY,
873
+ collection_slug text NOT NULL,
874
+ document_id text NOT NULL,
875
+ tenant_id text,
876
+ data text NOT NULL,
877
+ status text NOT NULL,
878
+ created_by text,
879
+ change_description text,
880
+ created_at text NOT NULL,
881
+ updated_at text NOT NULL
882
+ )
883
+ `;
884
+ }
885
+ await this.executeRaw(sql.raw(createTableSQL));
726
886
  this.versionsTableReady = true;
727
887
  }
728
888
  getDraftId(collection, documentId, tenantID) {
@@ -807,5 +967,5 @@ async function seedDefaultRoles(db) {
807
967
  }
808
968
 
809
969
  export { DrizzleAdapter, collectionToDrizzleSchema, createDatabase, createDrizzleAdapter, fieldToDrizzleType, genId, runMigrations, seedDefaultRoles };
810
- //# sourceMappingURL=chunk-6WXQRYTW.js.map
811
- //# sourceMappingURL=chunk-6WXQRYTW.js.map
970
+ //# sourceMappingURL=chunk-QPPDLRNR.js.map
971
+ //# sourceMappingURL=chunk-QPPDLRNR.js.map