better-auth-studio 1.1.3-beta.9 → 1.1.3

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 (196) hide show
  1. package/README.md +145 -16
  2. package/dist/adapters/astro.d.ts +0 -1
  3. package/dist/adapters/astro.js +5 -2
  4. package/dist/adapters/cloudflare-workers.d.ts +101 -0
  5. package/dist/adapters/cloudflare-workers.js +494 -0
  6. package/dist/adapters/elysia.d.ts +0 -1
  7. package/dist/adapters/elysia.js +7 -33
  8. package/dist/adapters/express.d.ts +0 -1
  9. package/dist/adapters/express.js +4 -1
  10. package/dist/adapters/hono.d.ts +0 -1
  11. package/dist/adapters/hono.js +7 -27
  12. package/dist/adapters/nextjs.d.ts +0 -1
  13. package/dist/adapters/nextjs.js +5 -2
  14. package/dist/adapters/nuxt.d.ts +0 -1
  15. package/dist/adapters/nuxt.js +5 -2
  16. package/dist/adapters/remix.d.ts +0 -1
  17. package/dist/adapters/remix.js +5 -2
  18. package/dist/adapters/solid-start.d.ts +0 -1
  19. package/dist/adapters/solid-start.js +5 -2
  20. package/dist/adapters/svelte-kit.d.ts +0 -1
  21. package/dist/adapters/svelte-kit.js +5 -2
  22. package/dist/adapters/tanstack-start.d.ts +0 -1
  23. package/dist/adapters/tanstack-start.js +36 -8
  24. package/dist/add-svelte-kit-env-modules.d.ts +0 -1
  25. package/dist/add-svelte-kit-env-modules.js +0 -1
  26. package/dist/auth-adapter.d.ts +5 -2
  27. package/dist/auth-adapter.js +39 -4
  28. package/dist/cli/commands/init.d.ts +0 -1
  29. package/dist/cli/commands/init.js +0 -1
  30. package/dist/cli.d.ts +0 -1
  31. package/dist/cli.js +6 -1
  32. package/dist/config.d.ts +0 -1
  33. package/dist/config.js +0 -1
  34. package/dist/core/handler.d.ts +0 -1
  35. package/dist/core/handler.js +36 -5
  36. package/dist/data.d.ts +10 -4
  37. package/dist/data.js +40 -6
  38. package/dist/geo-service.d.ts +0 -1
  39. package/dist/geo-service.js +0 -1
  40. package/dist/get-tsconfig-info.d.ts +0 -1
  41. package/dist/get-tsconfig-info.js +0 -1
  42. package/dist/index.d.ts +0 -1
  43. package/dist/index.js +0 -1
  44. package/dist/providers/events/helpers.d.ts +3 -2
  45. package/dist/providers/events/helpers.js +303 -93
  46. package/dist/public/assets/main-C-R_HO98.css +1 -0
  47. package/dist/public/assets/main-DDypFItU.js +1302 -0
  48. package/dist/public/index.html +2 -2
  49. package/dist/public/shaders.png +0 -0
  50. package/dist/routes/api-router.d.ts +2 -3
  51. package/dist/routes/api-router.js +0 -1
  52. package/dist/routes.d.ts +2 -3
  53. package/dist/routes.js +813 -172
  54. package/dist/studio.d.ts +0 -1
  55. package/dist/studio.js +6 -4
  56. package/dist/types/events.d.ts +0 -1
  57. package/dist/types/events.js +0 -1
  58. package/dist/types/handler.d.ts +13 -3
  59. package/dist/types/handler.js +0 -1
  60. package/dist/types/index.d.ts +0 -1
  61. package/dist/types/index.js +0 -1
  62. package/dist/utils/access-rules.d.ts +19 -0
  63. package/dist/utils/access-rules.js +126 -0
  64. package/dist/utils/auth-callbacks-injector.d.ts +0 -1
  65. package/dist/utils/auth-callbacks-injector.js +0 -1
  66. package/dist/utils/database-detection.d.ts +0 -1
  67. package/dist/utils/database-detection.js +33 -4
  68. package/dist/utils/event-ingestion.d.ts +0 -1
  69. package/dist/utils/event-ingestion.js +1 -1
  70. package/dist/utils/hook-injector.d.ts +0 -1
  71. package/dist/utils/hook-injector.js +2 -2
  72. package/dist/utils/html-injector.d.ts +1 -7
  73. package/dist/utils/html-injector.js +15 -1
  74. package/dist/utils/org-hooks-injector.d.ts +0 -1
  75. package/dist/utils/org-hooks-injector.js +0 -1
  76. package/dist/utils/package-json.d.ts +1 -1
  77. package/dist/utils/package-json.js +21 -1
  78. package/dist/utils/paths.d.ts +0 -1
  79. package/dist/utils/paths.js +0 -1
  80. package/dist/utils/reason-messages.d.ts +0 -1
  81. package/dist/utils/reason-messages.js +0 -1
  82. package/dist/utils/session.d.ts +0 -1
  83. package/dist/utils/session.js +0 -1
  84. package/dist/utils.d.ts +0 -1
  85. package/dist/utils.js +0 -1
  86. package/package.json +30 -39
  87. package/dist/adapters/astro.d.ts.map +0 -1
  88. package/dist/adapters/astro.js.map +0 -1
  89. package/dist/adapters/elysia.d.ts.map +0 -1
  90. package/dist/adapters/elysia.js.map +0 -1
  91. package/dist/adapters/express.d.ts.map +0 -1
  92. package/dist/adapters/express.js.map +0 -1
  93. package/dist/adapters/hono.d.ts.map +0 -1
  94. package/dist/adapters/hono.js.map +0 -1
  95. package/dist/adapters/nextjs.d.ts.map +0 -1
  96. package/dist/adapters/nextjs.js.map +0 -1
  97. package/dist/adapters/nuxt.d.ts.map +0 -1
  98. package/dist/adapters/nuxt.js.map +0 -1
  99. package/dist/adapters/remix.d.ts.map +0 -1
  100. package/dist/adapters/remix.js.map +0 -1
  101. package/dist/adapters/solid-start.d.ts.map +0 -1
  102. package/dist/adapters/solid-start.js.map +0 -1
  103. package/dist/adapters/svelte-kit.d.ts.map +0 -1
  104. package/dist/adapters/svelte-kit.js.map +0 -1
  105. package/dist/adapters/tanstack-start.d.ts.map +0 -1
  106. package/dist/adapters/tanstack-start.js.map +0 -1
  107. package/dist/add-svelte-kit-env-modules.d.ts.map +0 -1
  108. package/dist/add-svelte-kit-env-modules.js.map +0 -1
  109. package/dist/auth-adapter.d.ts.map +0 -1
  110. package/dist/auth-adapter.js.map +0 -1
  111. package/dist/cli/commands/init.d.ts.map +0 -1
  112. package/dist/cli/commands/init.js.map +0 -1
  113. package/dist/cli.d.ts.map +0 -1
  114. package/dist/cli.js.map +0 -1
  115. package/dist/config.d.ts.map +0 -1
  116. package/dist/config.js.map +0 -1
  117. package/dist/core/handler.d.ts.map +0 -1
  118. package/dist/core/handler.js.map +0 -1
  119. package/dist/data.d.ts.map +0 -1
  120. package/dist/data.js.map +0 -1
  121. package/dist/geo-service.d.ts.map +0 -1
  122. package/dist/geo-service.js.map +0 -1
  123. package/dist/get-tsconfig-info.d.ts.map +0 -1
  124. package/dist/get-tsconfig-info.js.map +0 -1
  125. package/dist/index.d.ts.map +0 -1
  126. package/dist/index.js.map +0 -1
  127. package/dist/providers/events/helpers.d.ts.map +0 -1
  128. package/dist/providers/events/helpers.js.map +0 -1
  129. package/dist/public/assets/main-D7_GjGqW.js +0 -1216
  130. package/dist/public/assets/main-Ru3ybjQp.css +0 -1
  131. package/dist/routes/api-router.d.ts.map +0 -1
  132. package/dist/routes/api-router.js.map +0 -1
  133. package/dist/routes.d.ts.map +0 -1
  134. package/dist/routes.js.map +0 -1
  135. package/dist/studio.d.ts.map +0 -1
  136. package/dist/studio.js.map +0 -1
  137. package/dist/types/events.d.ts.map +0 -1
  138. package/dist/types/events.js.map +0 -1
  139. package/dist/types/handler.d.ts.map +0 -1
  140. package/dist/types/handler.js.map +0 -1
  141. package/dist/types/index.d.ts.map +0 -1
  142. package/dist/types/index.js.map +0 -1
  143. package/dist/utils/auth-callbacks-injector.d.ts.map +0 -1
  144. package/dist/utils/auth-callbacks-injector.js.map +0 -1
  145. package/dist/utils/auth-callbacks-wrapper.d.ts +0 -7
  146. package/dist/utils/auth-callbacks-wrapper.d.ts.map +0 -1
  147. package/dist/utils/auth-callbacks-wrapper.js +0 -133
  148. package/dist/utils/auth-callbacks-wrapper.js.map +0 -1
  149. package/dist/utils/database-detection.d.ts.map +0 -1
  150. package/dist/utils/database-detection.js.map +0 -1
  151. package/dist/utils/database-hook-injector.d.ts +0 -3
  152. package/dist/utils/database-hook-injector.d.ts.map +0 -1
  153. package/dist/utils/database-hook-injector.js +0 -145
  154. package/dist/utils/database-hook-injector.js.map +0 -1
  155. package/dist/utils/email-otp-hooks-injector.d.ts +0 -45
  156. package/dist/utils/email-otp-hooks-injector.d.ts.map +0 -1
  157. package/dist/utils/email-otp-hooks-injector.js +0 -141
  158. package/dist/utils/email-otp-hooks-injector.js.map +0 -1
  159. package/dist/utils/event-ingestion.d.ts.map +0 -1
  160. package/dist/utils/event-ingestion.js.map +0 -1
  161. package/dist/utils/hook-injector.d.ts.map +0 -1
  162. package/dist/utils/hook-injector.js.map +0 -1
  163. package/dist/utils/html-injector.d.ts.map +0 -1
  164. package/dist/utils/html-injector.js.map +0 -1
  165. package/dist/utils/org-hooks-injector.d.ts.map +0 -1
  166. package/dist/utils/org-hooks-injector.js.map +0 -1
  167. package/dist/utils/org-hooks-wrapper.d.ts +0 -80
  168. package/dist/utils/org-hooks-wrapper.d.ts.map +0 -1
  169. package/dist/utils/org-hooks-wrapper.js +0 -807
  170. package/dist/utils/org-hooks-wrapper.js.map +0 -1
  171. package/dist/utils/organization-hooks-wrapper.d.ts +0 -44
  172. package/dist/utils/organization-hooks-wrapper.d.ts.map +0 -1
  173. package/dist/utils/organization-hooks-wrapper.js +0 -345
  174. package/dist/utils/organization-hooks-wrapper.js.map +0 -1
  175. package/dist/utils/package-json.d.ts.map +0 -1
  176. package/dist/utils/package-json.js.map +0 -1
  177. package/dist/utils/paths.d.ts.map +0 -1
  178. package/dist/utils/paths.js.map +0 -1
  179. package/dist/utils/reason-messages.d.ts.map +0 -1
  180. package/dist/utils/reason-messages.js.map +0 -1
  181. package/dist/utils/server-init.d.ts +0 -10
  182. package/dist/utils/server-init.d.ts.map +0 -1
  183. package/dist/utils/server-init.js +0 -40
  184. package/dist/utils/server-init.js.map +0 -1
  185. package/dist/utils/session.d.ts.map +0 -1
  186. package/dist/utils/session.js.map +0 -1
  187. package/dist/utils.d.ts.map +0 -1
  188. package/dist/utils.js.map +0 -1
  189. package/public/assets/main-D7_GjGqW.js +0 -1216
  190. package/public/assets/main-Ru3ybjQp.css +0 -1
  191. package/public/favicon.svg +0 -6
  192. package/public/index.html +0 -14
  193. package/public/logo.png +0 -0
  194. package/public/vite.svg +0 -5
  195. package/scripts/download-geolite2.js +0 -42
  196. package/scripts/generate-default-db.js +0 -462
@@ -1,3 +1,37 @@
1
+ function isKyselyClient(client, clientType) {
2
+ const hasExecuteQuery = typeof client?.executeQuery === "function";
3
+ if (clientType === "kysely") {
4
+ return hasExecuteQuery;
5
+ }
6
+ return hasExecuteQuery && typeof client?.selectFrom === "function";
7
+ }
8
+ function createKyselyCompiledQuery(sql, parameters = []) {
9
+ return {
10
+ sql,
11
+ parameters,
12
+ queryId: { queryId: `bas_${Date.now()}_${Math.random().toString(36).slice(2)}` },
13
+ };
14
+ }
15
+ async function executeKyselyQuery(client, query, params = []) {
16
+ return await client.executeQuery(createKyselyCompiledQuery(query, params));
17
+ }
18
+ function getEventInsertParams(event) {
19
+ return [
20
+ event.id,
21
+ event.type,
22
+ event.timestamp,
23
+ event.status || "success",
24
+ event.userId || null,
25
+ event.sessionId || null,
26
+ event.organizationId || null,
27
+ JSON.stringify(event.metadata || {}),
28
+ event.ipAddress || null,
29
+ event.userAgent || null,
30
+ event.source,
31
+ event.display?.message || null,
32
+ event.display?.severity || null,
33
+ ];
34
+ }
1
35
  export function createPostgresProvider(options) {
2
36
  const { client, tableName = "auth_events", schema = "public", clientType } = options;
3
37
  // Validate client is provided
@@ -18,12 +52,15 @@ export function createPostgresProvider(options) {
18
52
  const hasExecuteRaw = client?.$executeRaw;
19
53
  const hasExecute = client?.execute;
20
54
  const hasUnsafe = actualClient?.unsafe || client?.$client?.unsafe || client?.unsafe;
21
- if (!hasQuery && !hasExecuteRaw && !hasExecute && !hasUnsafe) {
55
+ const hasKysely = isKyselyClient(client, clientType);
56
+ if (!hasQuery && !hasExecuteRaw && !hasExecute && !hasUnsafe && !hasKysely) {
22
57
  const errorMessage = clientType === "prisma"
23
58
  ? "Invalid Prisma client. Client must have a `$executeRaw` method."
24
59
  : clientType === "drizzle"
25
60
  ? "Invalid Drizzle client. Drizzle instance must wrap a postgres-js (with `unsafe` method) or pg (with `query` method) client."
26
- : "Invalid Postgres client. Client must have either a `query` method (pg Pool/Client) or `$executeRaw` method (Prisma client).";
61
+ : clientType === "kysely"
62
+ ? "Invalid Kysely client. Client must have an `executeQuery` method."
63
+ : "Invalid Postgres client. Client must have either a `query` method (pg Pool/Client), `$executeRaw` method (Prisma client), or `executeQuery` method (Kysely client).";
27
64
  throw new Error(errorMessage);
28
65
  }
29
66
  // Ensure table exists
@@ -39,6 +76,11 @@ export function createPostgresProvider(options) {
39
76
  return await client.$executeRawUnsafe(query);
40
77
  };
41
78
  }
79
+ else if (hasKysely) {
80
+ executeQuery = async (query) => {
81
+ return await executeKyselyQuery(client, query);
82
+ };
83
+ }
42
84
  else if (clientType === "drizzle") {
43
85
  // Drizzle client - use $client which exposes the underlying client
44
86
  if (actualClient?.unsafe) {
@@ -69,7 +111,7 @@ export function createPostgresProvider(options) {
69
111
  };
70
112
  }
71
113
  else {
72
- throw new Error(`Postgres client doesn't support $executeRaw or query method. Available properties: ${Object.keys(client).join(", ")}`);
114
+ throw new Error(`Postgres client doesn't support $executeRaw, executeQuery, or query method. Available properties: ${Object.keys(client).join(", ")}`);
73
115
  }
74
116
  // Use CREATE TABLE IF NOT EXISTS (simpler and more reliable)
75
117
  const createTableQuery = `
@@ -141,7 +183,32 @@ export function createPostgresProvider(options) {
141
183
  return {
142
184
  async ingest(event) {
143
185
  await ensureTableSync();
144
- if (clientType === "prisma" || client.$executeRaw) {
186
+ if (hasKysely) {
187
+ try {
188
+ await executeKyselyQuery(client, `INSERT INTO ${schema}.${tableName}
189
+ (id, type, timestamp, status, user_id, session_id, organization_id, metadata, ip_address, user_agent, source, display_message, display_severity)
190
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)`, getEventInsertParams(event));
191
+ }
192
+ catch (error) {
193
+ console.error(`Failed to insert event (${event.type}) into ${schema}.${tableName}:`, error);
194
+ if (error.code === "42P01") {
195
+ tableEnsured = false;
196
+ await ensureTableSync();
197
+ try {
198
+ await executeKyselyQuery(client, `INSERT INTO ${schema}.${tableName}
199
+ (id, type, timestamp, status, user_id, session_id, organization_id, metadata, ip_address, user_agent, source, display_message, display_severity)
200
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)`, getEventInsertParams(event));
201
+ return;
202
+ }
203
+ catch (retryError) {
204
+ console.error(`Retry after table creation also failed:`, retryError);
205
+ throw retryError;
206
+ }
207
+ }
208
+ throw error;
209
+ }
210
+ }
211
+ else if (clientType === "prisma" || client.$executeRaw) {
145
212
  const query = `
146
213
  INSERT INTO ${schema}.${tableName}
147
214
  (id, type, timestamp, status, user_id, session_id, organization_id, metadata, ip_address, user_agent, source, display_message, display_severity)
@@ -176,7 +243,7 @@ export function createPostgresProvider(options) {
176
243
  if (useUnsafe) {
177
244
  // postgres-js client - use unsafe() for raw SQL
178
245
  const query = `
179
- INSERT INTO ${schema}.${tableName}
246
+ INSERT INTO ${schema}.${tableName}
180
247
  (id, type, timestamp, status, user_id, session_id, organization_id, metadata, ip_address, user_agent, source, display_message, display_severity)
181
248
  VALUES ('${event.id}'::uuid, '${event.type}', '${event.timestamp.toISOString()}', '${event.status || "success"}', ${event.userId ? `'${event.userId.replace(/'/g, "''")}'` : "NULL"}, ${event.sessionId ? `'${event.sessionId.replace(/'/g, "''")}'` : "NULL"}, ${event.organizationId ? `'${event.organizationId.replace(/'/g, "''")}'` : "NULL"}, '${JSON.stringify(event.metadata || {}).replace(/'/g, "''")}'::jsonb, ${event.ipAddress ? `'${event.ipAddress.replace(/'/g, "''")}'` : "NULL"}, ${event.userAgent ? `'${event.userAgent.replace(/'/g, "''")}'` : "NULL"}, '${event.source}', ${event.display?.message ? `'${event.display.message.replace(/'/g, "''")}'` : "NULL"}, ${event.display?.severity ? `'${event.display.severity}'` : "NULL"})
182
249
  `;
@@ -205,21 +272,7 @@ export function createPostgresProvider(options) {
205
272
  try {
206
273
  await queryClient.query(`INSERT INTO ${schema}.${tableName}
207
274
  (id, type, timestamp, status, user_id, session_id, organization_id, metadata, ip_address, user_agent, source, display_message, display_severity)
208
- VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)`, [
209
- event.id,
210
- event.type,
211
- event.timestamp,
212
- event.status || "success",
213
- event.userId || null,
214
- event.sessionId || null,
215
- event.organizationId || null,
216
- JSON.stringify(event.metadata || {}),
217
- event.ipAddress || null,
218
- event.userAgent || null,
219
- event.source,
220
- event.display?.message || null,
221
- event.display?.severity || null,
222
- ]);
275
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)`, [...getEventInsertParams(event)]);
223
276
  }
224
277
  catch (error) {
225
278
  console.error(`Failed to insert event (${event.type}) into ${schema}.${tableName}:`, error);
@@ -229,21 +282,7 @@ export function createPostgresProvider(options) {
229
282
  try {
230
283
  await queryClient.query(`INSERT INTO ${schema}.${tableName}
231
284
  (id, type, timestamp, status, user_id, session_id, organization_id, metadata, ip_address, user_agent, source, display_message, display_severity)
232
- VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)`, [
233
- event.id,
234
- event.type,
235
- event.timestamp,
236
- event.status || "success",
237
- event.userId || null,
238
- event.sessionId || null,
239
- event.organizationId || null,
240
- JSON.stringify(event.metadata || {}),
241
- event.ipAddress || null,
242
- event.userAgent || null,
243
- event.source,
244
- event.display?.message || null,
245
- event.display?.severity || null,
246
- ]);
285
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)`, [...getEventInsertParams(event)]);
247
286
  return;
248
287
  }
249
288
  catch (retryError) {
@@ -271,7 +310,34 @@ export function createPostgresProvider(options) {
271
310
  return;
272
311
  await ensureTableSync();
273
312
  // Support Prisma client ($executeRaw), Drizzle instance, or standard pg client (query)
274
- if (clientType === "prisma" || client.$executeRaw) {
313
+ if (hasKysely) {
314
+ const PARAMS_PER_EVENT = 13;
315
+ const MAX_PARAMS = 65535;
316
+ const CHUNK_SIZE = Math.floor(MAX_PARAMS / PARAMS_PER_EVENT) - 1;
317
+ for (let chunkStart = 0; chunkStart < events.length; chunkStart += CHUNK_SIZE) {
318
+ const chunk = events.slice(chunkStart, chunkStart + CHUNK_SIZE);
319
+ const values = chunk
320
+ .map((_, i) => {
321
+ const base = i * PARAMS_PER_EVENT;
322
+ return `($${base + 1}, $${base + 2}, $${base + 3}, $${base + 4}, $${base + 5}, $${base + 6}, $${base + 7}, $${base + 8}, $${base + 9}, $${base + 10}, $${base + 11}, $${base + 12}, $${base + 13})`;
323
+ })
324
+ .join(", ");
325
+ const query = `
326
+ INSERT INTO ${schema}.${tableName}
327
+ (id, type, timestamp, status, user_id, session_id, organization_id, metadata, ip_address, user_agent, source, display_message, display_severity)
328
+ VALUES ${values}
329
+ `;
330
+ const params = chunk.flatMap((event) => getEventInsertParams(event));
331
+ try {
332
+ await executeKyselyQuery(client, query, params);
333
+ }
334
+ catch (error) {
335
+ console.error(`Failed to insert batch chunk (${chunk.length} events) into ${schema}.${tableName}:`, error);
336
+ throw error;
337
+ }
338
+ }
339
+ }
340
+ else if (clientType === "prisma" || client.$executeRaw) {
275
341
  // Prisma client - use $executeRawUnsafe for batch inserts
276
342
  const CHUNK_SIZE = 500; // Reasonable chunk size for string-based queries
277
343
  for (let i = 0; i < events.length; i += CHUNK_SIZE) {
@@ -339,21 +405,7 @@ export function createPostgresProvider(options) {
339
405
  (id, type, timestamp, status, user_id, session_id, organization_id, metadata, ip_address, user_agent, source, display_message, display_severity)
340
406
  VALUES ${values}
341
407
  `;
342
- const params = chunk.flatMap((event) => [
343
- event.id,
344
- event.type,
345
- event.timestamp,
346
- event.status || "success",
347
- event.userId || null,
348
- event.sessionId || null,
349
- event.organizationId || null,
350
- JSON.stringify(event.metadata || {}),
351
- event.ipAddress || null,
352
- event.userAgent || null,
353
- event.source,
354
- event.display?.message || null,
355
- event.display?.severity || null,
356
- ]);
408
+ const params = chunk.flatMap((event) => getEventInsertParams(event));
357
409
  try {
358
410
  await batchQueryClient.query(query, params);
359
411
  }
@@ -376,7 +428,7 @@ export function createPostgresProvider(options) {
376
428
  }
377
429
  },
378
430
  async query(options) {
379
- const { limit = 20, after, sort = "desc", type, userId, since } = options;
431
+ const { limit = 20, offset, after, sort = "desc", type, userId, since } = options;
380
432
  let queryFn;
381
433
  if (client.$executeRaw) {
382
434
  // Prisma client
@@ -401,6 +453,11 @@ export function createPostgresProvider(options) {
401
453
  }
402
454
  };
403
455
  }
456
+ else if (hasKysely) {
457
+ queryFn = async (query, params) => {
458
+ return await executeKyselyQuery(client, query, params || []);
459
+ };
460
+ }
404
461
  else if (client.query) {
405
462
  // Standard pg client (Pool or Client)
406
463
  queryFn = async (query, params) => {
@@ -427,6 +484,9 @@ export function createPostgresProvider(options) {
427
484
  .replace("$2", `'${tableName}'`);
428
485
  checkResult = await client.$queryRawUnsafe(prismaQuery);
429
486
  }
487
+ else if (hasKysely) {
488
+ checkResult = await queryFn(checkTableQuery, [schema, tableName]);
489
+ }
430
490
  else {
431
491
  // Standard pg client
432
492
  checkResult = await queryFn(checkTableQuery, [schema, tableName]);
@@ -448,8 +508,8 @@ export function createPostgresProvider(options) {
448
508
  const whereClauses = [];
449
509
  const params = [];
450
510
  let paramIndex = 1;
451
- // Cursor-based pagination
452
- if (after) {
511
+ // Use cursor-based pagination only when offset is not provided
512
+ if (offset == null && after) {
453
513
  if (sort === "desc") {
454
514
  whereClauses.push(`id < $${paramIndex++}`);
455
515
  params.push(after);
@@ -473,15 +533,29 @@ export function createPostgresProvider(options) {
473
533
  }
474
534
  const whereClause = whereClauses.length > 0 ? `WHERE ${whereClauses.join(" AND ")}` : "";
475
535
  const orderDirection = sort === "desc" ? "DESC" : "ASC";
476
- const query = `
477
- SELECT id, type, timestamp, status, user_id, session_id, organization_id,
478
- metadata, ip_address, user_agent, source, display_message, display_severity
479
- FROM ${schema}.${tableName}
480
- ${whereClause}
481
- ORDER BY timestamp ${orderDirection}, id ${orderDirection}
482
- LIMIT $${paramIndex++}
483
- `;
484
- params.push(limit + 1); // Get one extra to check hasMore
536
+ let query;
537
+ if (offset != null && offset > 0) {
538
+ query = `
539
+ SELECT id, type, timestamp, status, user_id, session_id, organization_id,
540
+ metadata, ip_address, user_agent, source, display_message, display_severity
541
+ FROM ${schema}.${tableName}
542
+ ${whereClause}
543
+ ORDER BY timestamp ${orderDirection}, id ${orderDirection}
544
+ LIMIT $${paramIndex++} OFFSET $${paramIndex++}
545
+ `;
546
+ params.push(limit + 1, offset);
547
+ }
548
+ else {
549
+ query = `
550
+ SELECT id, type, timestamp, status, user_id, session_id, organization_id,
551
+ metadata, ip_address, user_agent, source, display_message, display_severity
552
+ FROM ${schema}.${tableName}
553
+ ${whereClause}
554
+ ORDER BY timestamp ${orderDirection}, id ${orderDirection}
555
+ LIMIT $${paramIndex++}
556
+ `;
557
+ params.push(limit + 1);
558
+ }
485
559
  try {
486
560
  const result = await queryFn(query, params);
487
561
  const rows = result.rows || result || [];
@@ -698,7 +772,7 @@ export function createSqliteProvider(options) {
698
772
  }
699
773
  },
700
774
  async query(options) {
701
- const { limit = 20, after, sort = "desc", type, userId, since } = options;
775
+ const { limit = 20, offset, after, sort = "desc", type, userId, since } = options;
702
776
  await ensureTableSync();
703
777
  try {
704
778
  let query = `SELECT * FROM ${tableName} WHERE 1=1`;
@@ -715,13 +789,20 @@ export function createSqliteProvider(options) {
715
789
  query += ` AND timestamp >= ?`;
716
790
  params.push(since instanceof Date ? since.toISOString() : since);
717
791
  }
718
- if (after) {
719
- query += sort === "desc" ? ` AND id < ?` : ` AND id > ?`;
720
- params.push(after);
792
+ if (offset != null && offset > 0) {
793
+ query += ` ORDER BY timestamp ${sort === "desc" ? "DESC" : "ASC"}`;
794
+ query += ` LIMIT ? OFFSET ?`;
795
+ params.push(limit + 1, offset);
796
+ }
797
+ else {
798
+ if (after) {
799
+ query += sort === "desc" ? ` AND id < ?` : ` AND id > ?`;
800
+ params.push(after);
801
+ }
802
+ query += ` ORDER BY timestamp ${sort === "desc" ? "DESC" : "ASC"}`;
803
+ query += ` LIMIT ?`;
804
+ params.push(limit + 1);
721
805
  }
722
- query += ` ORDER BY timestamp ${sort === "desc" ? "DESC" : "ASC"}`;
723
- query += ` LIMIT ?`;
724
- params.push(limit + 1); // Fetch one extra to check if there are more
725
806
  const stmt = actualClient.prepare(query);
726
807
  const rows = stmt.all(...params);
727
808
  const hasMore = rows.length > limit;
@@ -1154,7 +1235,7 @@ export function createClickHouseProvider(options) {
1154
1235
  await ingestBatchFn(events);
1155
1236
  },
1156
1237
  async query(options) {
1157
- const { limit = 20, after, sort = "desc", type, userId, since } = options;
1238
+ const { limit = 20, offset, after, sort = "desc", type, userId, since } = options;
1158
1239
  const tableFullName = database ? `${database}.${table}` : table;
1159
1240
  try {
1160
1241
  const checkTableQuery = `EXISTS TABLE ${tableFullName}`;
@@ -1269,7 +1350,7 @@ export function createClickHouseProvider(options) {
1269
1350
  }
1270
1351
  }
1271
1352
  const whereClauses = [];
1272
- if (after) {
1353
+ if (offset == null && after) {
1273
1354
  if (sort === "desc") {
1274
1355
  whereClauses.push(`id < '${String(after).replace(/'/g, "''")}'`);
1275
1356
  }
@@ -1285,13 +1366,12 @@ export function createClickHouseProvider(options) {
1285
1366
  }
1286
1367
  if (since) {
1287
1368
  const sinceDate = since instanceof Date ? since : new Date(since);
1288
- // ClickHouse requires DateTime type, so we need to cast the string to DateTime
1289
- // Format: 'YYYY-MM-DD HH:MM:SS' or use toDateTime() function
1290
1369
  const isoString = sinceDate.toISOString().replace("T", " ").slice(0, 19);
1291
1370
  whereClauses.push(`timestamp >= toDateTime('${isoString.replace(/'/g, "''")}')`);
1292
1371
  }
1293
1372
  const whereClause = whereClauses.length > 0 ? `WHERE ${whereClauses.join(" AND ")}` : "";
1294
1373
  const orderDirection = sort === "desc" ? "DESC" : "ASC";
1374
+ const offsetClause = offset != null && offset > 0 ? `OFFSET ${offset}` : "";
1295
1375
  let query = `
1296
1376
  SELECT id, type, timestamp, status, user_id, session_id, organization_id,
1297
1377
  metadata, ip_address, user_agent, source, display_message, display_severity
@@ -1299,6 +1379,7 @@ export function createClickHouseProvider(options) {
1299
1379
  ${whereClause}
1300
1380
  ORDER BY timestamp ${orderDirection}, id ${orderDirection}
1301
1381
  LIMIT ${limit + 1}
1382
+ ${offsetClause}
1302
1383
  `;
1303
1384
  let result;
1304
1385
  let hasStatusColumn = true;
@@ -1412,6 +1493,132 @@ export function createStorageProvider(options) {
1412
1493
  const { adapter, tableName = "auth_events" } = options;
1413
1494
  let tableEnsured = false;
1414
1495
  let tableEnsuringPromise = null;
1496
+ let resolvedModelName = null;
1497
+ const isMissingModelError = (error) => error?.message?.includes("not found in schema") ||
1498
+ error?.message?.includes("not found in model") ||
1499
+ error?.message?.includes("Model") ||
1500
+ error?.code === "P2025" ||
1501
+ error?.code === "42P01";
1502
+ const toCamelCase = (value) => value.replace(/[_-]([a-z])/g, (_match, char) => char.toUpperCase());
1503
+ const getModelCandidates = () => {
1504
+ const candidates = new Set();
1505
+ const addForms = (value) => {
1506
+ const normalized = value?.trim();
1507
+ if (!normalized)
1508
+ return;
1509
+ const snake = normalized.replace(/-/g, "_");
1510
+ const singularSnake = snake.endsWith("s") ? snake.slice(0, -1) : snake;
1511
+ const pluralSnake = snake.endsWith("s") ? snake : `${snake}s`;
1512
+ const singularCamel = toCamelCase(singularSnake);
1513
+ const pluralCamel = toCamelCase(pluralSnake);
1514
+ [
1515
+ normalized,
1516
+ snake,
1517
+ singularSnake,
1518
+ pluralSnake,
1519
+ singularCamel,
1520
+ pluralCamel,
1521
+ singularCamel.charAt(0).toUpperCase() + singularCamel.slice(1),
1522
+ pluralCamel.charAt(0).toUpperCase() + pluralCamel.slice(1),
1523
+ ].forEach((candidate) => {
1524
+ if (candidate) {
1525
+ candidates.add(candidate);
1526
+ }
1527
+ });
1528
+ };
1529
+ addForms(tableName);
1530
+ addForms(tableName === "auth_events" ? "auth_event" : "auth_events");
1531
+ return Array.from(candidates);
1532
+ };
1533
+ const withResolvedModel = async (callback) => {
1534
+ const candidates = Array.from(new Set([resolvedModelName, ...getModelCandidates()].filter(Boolean)));
1535
+ let lastLookupError = null;
1536
+ for (const modelName of candidates) {
1537
+ try {
1538
+ const result = await callback(modelName);
1539
+ resolvedModelName = modelName;
1540
+ return result;
1541
+ }
1542
+ catch (error) {
1543
+ if (isMissingModelError(error)) {
1544
+ lastLookupError = error;
1545
+ continue;
1546
+ }
1547
+ throw error;
1548
+ }
1549
+ }
1550
+ if (lastLookupError) {
1551
+ throw lastLookupError;
1552
+ }
1553
+ throw new Error(`No event model candidates available for "${tableName}"`);
1554
+ };
1555
+ const getFieldCandidates = (field) => {
1556
+ switch (field) {
1557
+ case "userId":
1558
+ return ["userId", "user_id"];
1559
+ case "sessionId":
1560
+ return ["sessionId", "session_id"];
1561
+ case "organizationId":
1562
+ return ["organizationId", "organization_id"];
1563
+ case "ipAddress":
1564
+ return ["ipAddress", "ip_address"];
1565
+ case "userAgent":
1566
+ return ["userAgent", "user_agent"];
1567
+ case "displayMessage":
1568
+ return ["displayMessage", "display_message"];
1569
+ case "displaySeverity":
1570
+ return ["displaySeverity", "display_severity"];
1571
+ case "createdAt":
1572
+ return ["createdAt", "created_at"];
1573
+ default:
1574
+ return field ? [field] : [];
1575
+ }
1576
+ };
1577
+ const getWhereCandidates = (where) => {
1578
+ if (!Array.isArray(where) || where.length === 0) {
1579
+ return {
1580
+ whereCandidates: [undefined],
1581
+ hasAliasedFields: false,
1582
+ };
1583
+ }
1584
+ let hasAliasedFields = false;
1585
+ let combinations = [[]];
1586
+ for (const clause of where) {
1587
+ const fieldCandidates = getFieldCandidates(clause?.field);
1588
+ if (fieldCandidates.length > 1) {
1589
+ hasAliasedFields = true;
1590
+ }
1591
+ const nextCombinations = fieldCandidates.flatMap((fieldName) => combinations.map((existing) => [...existing, { ...clause, field: fieldName }]));
1592
+ if (nextCombinations.length > 0) {
1593
+ combinations = nextCombinations;
1594
+ }
1595
+ }
1596
+ return {
1597
+ whereCandidates: combinations.length > 0 ? combinations : [where],
1598
+ hasAliasedFields,
1599
+ };
1600
+ };
1601
+ const findManyWithResolvedModel = async (options) => {
1602
+ const { where, ...restOptions } = options;
1603
+ const { whereCandidates, hasAliasedFields } = getWhereCandidates(where);
1604
+ let lastSuccessfulEmptyResult = null;
1605
+ for (let index = 0; index < whereCandidates.length; index += 1) {
1606
+ const result = (await withResolvedModel((modelName) => adapter.findMany({
1607
+ ...restOptions,
1608
+ ...(whereCandidates[index] ? { where: whereCandidates[index] } : {}),
1609
+ model: modelName,
1610
+ })));
1611
+ if (Array.isArray(result) &&
1612
+ result.length === 0 &&
1613
+ hasAliasedFields &&
1614
+ index < whereCandidates.length - 1) {
1615
+ lastSuccessfulEmptyResult = result;
1616
+ continue;
1617
+ }
1618
+ return Array.isArray(result) ? result : [];
1619
+ }
1620
+ return lastSuccessfulEmptyResult ?? [];
1621
+ };
1415
1622
  const ensureTable = async () => {
1416
1623
  if (!adapter)
1417
1624
  return;
@@ -1423,10 +1630,10 @@ export function createStorageProvider(options) {
1423
1630
  try {
1424
1631
  if (adapter.findMany) {
1425
1632
  // Try to query the table to see if it exists
1426
- await adapter.findMany({
1427
- model: tableName,
1633
+ await withResolvedModel((modelName) => adapter.findMany({
1634
+ model: modelName,
1428
1635
  limit: 1,
1429
- });
1636
+ }));
1430
1637
  tableEnsured = true;
1431
1638
  return;
1432
1639
  }
@@ -1496,8 +1703,8 @@ export function createStorageProvider(options) {
1496
1703
  return {
1497
1704
  async ingest(event) {
1498
1705
  if (adapter.create) {
1499
- await adapter.create({
1500
- model: tableName,
1706
+ await withResolvedModel((modelName) => adapter.create({
1707
+ model: modelName,
1501
1708
  data: {
1502
1709
  id: event.id,
1503
1710
  type: event.type,
@@ -1513,7 +1720,7 @@ export function createStorageProvider(options) {
1513
1720
  displayMessage: event.display?.message,
1514
1721
  displaySeverity: event.display?.severity,
1515
1722
  },
1516
- });
1723
+ }));
1517
1724
  }
1518
1725
  else if (adapter.insert) {
1519
1726
  await adapter.insert({
@@ -1540,8 +1747,8 @@ export function createStorageProvider(options) {
1540
1747
  // Ensure table exists before ingesting
1541
1748
  await ensureTable();
1542
1749
  if (adapter.createMany) {
1543
- await adapter.createMany({
1544
- model: tableName,
1750
+ await withResolvedModel((modelName) => adapter.createMany({
1751
+ model: modelName,
1545
1752
  data: events.map((event) => ({
1546
1753
  id: event.id,
1547
1754
  type: event.type,
@@ -1557,21 +1764,21 @@ export function createStorageProvider(options) {
1557
1764
  displayMessage: event.display?.message,
1558
1765
  displaySeverity: event.display?.severity,
1559
1766
  })),
1560
- });
1767
+ }));
1561
1768
  }
1562
1769
  else {
1563
1770
  await Promise.all(events.map((event) => this.ingest(event)));
1564
1771
  }
1565
1772
  },
1566
1773
  async query(options) {
1567
- const { limit = 20, after, sort = "desc", type, userId, since } = options;
1774
+ const { limit = 20, offset, after, sort = "desc", type, userId, since } = options;
1568
1775
  // Ensure table exists before querying
1569
1776
  await ensureTable();
1570
1777
  // First, try findMany (normal path)
1571
1778
  if (adapter && adapter.findMany) {
1572
1779
  try {
1573
1780
  const where = [];
1574
- if (after) {
1781
+ if (offset == null && after) {
1575
1782
  if (sort === "desc") {
1576
1783
  where.push({ field: "id", operator: "<", value: after });
1577
1784
  }
@@ -1589,12 +1796,15 @@ export function createStorageProvider(options) {
1589
1796
  const sinceDate = since instanceof Date ? since : new Date(since);
1590
1797
  where.push({ field: "timestamp", operator: ">=", value: sinceDate });
1591
1798
  }
1592
- const events = await adapter.findMany({
1593
- model: tableName,
1799
+ const findManyOptions = {
1594
1800
  where,
1595
1801
  orderBy: [{ field: "timestamp", direction: sort === "desc" ? "desc" : "asc" }],
1596
- limit: limit + 1, // Get one extra to check hasMore
1597
- });
1802
+ limit: limit + 1,
1803
+ };
1804
+ if (offset != null && offset > 0) {
1805
+ findManyOptions.offset = offset;
1806
+ }
1807
+ const events = await findManyWithResolvedModel(findManyOptions);
1598
1808
  const hasMore = events.length > limit;
1599
1809
  const paginatedEvents = events.slice(0, limit).map((event) => ({
1600
1810
  id: event.id,
@@ -1657,7 +1867,7 @@ export function createStorageProvider(options) {
1657
1867
  const whereConditions = [];
1658
1868
  const params = [];
1659
1869
  let paramIndex = 1;
1660
- if (after) {
1870
+ if (offset == null && after) {
1661
1871
  if (sort === "desc") {
1662
1872
  whereConditions.push(`id < $${paramIndex}`);
1663
1873
  }
@@ -1683,12 +1893,13 @@ export function createStorageProvider(options) {
1683
1893
  paramIndex++;
1684
1894
  }
1685
1895
  const whereClause = whereConditions.length > 0 ? `WHERE ${whereConditions.join(" AND ")}` : "";
1896
+ const offsetSql = offset != null && offset > 0 ? ` OFFSET ${offset}` : "";
1686
1897
  const orderDirection = sort === "desc" ? "DESC" : "ASC";
1687
1898
  // Use appropriate raw SQL method
1688
1899
  let queryFn;
1689
1900
  if (sqlAdapter.$queryRawUnsafe || adapter.$queryRawUnsafe) {
1690
1901
  // Prisma - build query with parameters embedded
1691
- let query = `SELECT * FROM ${tableName} ${whereClause} ORDER BY timestamp ${orderDirection}, id ${orderDirection} LIMIT ${limit + 1}`;
1902
+ let query = `SELECT * FROM ${tableName} ${whereClause} ORDER BY timestamp ${orderDirection}, id ${orderDirection} LIMIT ${limit + 1}${offsetSql}`;
1692
1903
  // Replace $1, $2, etc. with actual values for Prisma
1693
1904
  params.forEach((param, index) => {
1694
1905
  const placeholder = `$${index + 1}`;
@@ -1732,7 +1943,7 @@ export function createStorageProvider(options) {
1732
1943
  }
1733
1944
  else {
1734
1945
  // Other adapters - use parameterized query
1735
- const query = `SELECT * FROM ${tableName} ${whereClause} ORDER BY timestamp ${orderDirection}, id ${orderDirection} LIMIT $${paramIndex}`;
1946
+ const query = `SELECT * FROM ${tableName} ${whereClause} ORDER BY timestamp ${orderDirection}, id ${orderDirection} LIMIT $${paramIndex}${offsetSql}`;
1736
1947
  params.push(limit + 1);
1737
1948
  if (sqlAdapter.$queryRaw || adapter.$queryRaw) {
1738
1949
  const queryMethod = sqlAdapter.$queryRaw || adapter.$queryRaw;
@@ -1788,4 +1999,3 @@ export function createStorageProvider(options) {
1788
1999
  },
1789
2000
  };
1790
2001
  }
1791
- //# sourceMappingURL=helpers.js.map