better-auth 0.2.3-beta.8 → 0.2.4

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.
package/dist/adapters.js CHANGED
@@ -1,22 +1,1163 @@
1
- import{existsSync as K}from"fs";import E from"path";var C=e=>{let o=e.plugins?.reduce((c,l)=>{let d=l.schema;if(!d)return c;for(let[u,p]of Object.entries(d))c[u]={fields:{...c[u]?.fields,...p.fields},tableName:u};return c},{}),a=e.rateLimit?.storage==="database",r={rateLimit:{tableName:e.rateLimit?.tableName||"rateLimit",fields:{key:{type:"string"},count:{type:"number"},lastRequest:{type:"number"}}}},{user:s,session:t,account:n,...i}=o||{};return{user:{tableName:e.user?.modelName||"user",fields:{name:{type:"string",required:!0},email:{type:"string",unique:!0,required:!0},emailVerified:{type:"boolean",defaultValue:()=>!1,required:!0},image:{type:"string",required:!1},createdAt:{type:"date",defaultValue:()=>new Date,required:!0},updatedAt:{type:"date",defaultValue:()=>new Date,required:!0},...s?.fields},order:0},session:{tableName:e.session?.modelName||"session",fields:{expiresAt:{type:"date",required:!0},ipAddress:{type:"string",required:!1},userAgent:{type:"string",required:!1},userId:{type:"string",references:{model:"user",field:"id",onDelete:"cascade"},required:!0},...t?.fields},order:1},account:{tableName:e.account?.modelName||"account",fields:{accountId:{type:"string",required:!0},providerId:{type:"string",required:!0},userId:{type:"string",references:{model:"user",field:"id",onDelete:"cascade"},required:!0},accessToken:{type:"string",required:!1},refreshToken:{type:"string",required:!1},idToken:{type:"string",required:!1},expiresAt:{type:"date",required:!1},password:{type:"string",required:!1},...n?.fields},order:2},...i,...a?r:{}}};import W from"fs/promises";import{produceSchema as H}from"@mrleebo/prisma-ast";var w=class extends Error{constructor(o,a,r){super(o),this.name="BetterAuthError",this.message=o,this.cause=a}};import{TimeSpan as he}from"oslo";import{alphabet as ke,generateRandomString as Ce}from"oslo/crypto";import{createConsola as V}from"consola";var k=V({formatOptions:{date:!1,colors:!0,compact:!0},defaults:{tag:"Better Auth"}}),G=e=>({log:(...o)=>{!e?.disabled&&k.log("",...o)},error:(...o)=>{!e?.disabled&&k.error("",...o)},warn:(...o)=>{!e?.disabled&&k.warn("",...o)},info:(...o)=>{!e?.disabled&&k.info("",...o)},debug:(...o)=>{!e?.disabled&&k.debug("",...o)},box:(...o)=>{!e?.disabled&&k.box("",...o)},success:(...o)=>{!e?.disabled&&k.success("",...o)},break:(...o)=>{!e?.disabled&&console.log(`
2
- `)}}),N=G();function D(e){return e.charAt(0).toUpperCase()+e.slice(1)}import{generateState as De}from"oslo/oauth2";import{z as Pe}from"zod";function O(e){if(!e)return{};if(e.length===1){let t=e[0];return t?{[t.field]:t.value}:void 0}let o=e.filter(t=>t.connector==="AND"||!t.connector),a=e.filter(t=>t.connector==="OR"),r=o.map(t=>({[t.field]:t.operator==="eq"||!t.operator?t.value:{[t.operator]:t.value}})),s=a.map(t=>({[t.field]:{[t.operator||"eq"]:t.value}}));return{AND:r.length?r:void 0,OR:s.length?s:void 0}}var nt=({db:e,provider:o})=>{let a=e;return{id:"prisma",async create(r){let{model:s,data:t,select:n}=r;return await a[s].create({data:t,...n?.length?{select:n.reduce((i,c)=>({...i,[c]:!0}),{})}:{}})},async findOne(r){let{model:s,where:t,select:n}=r,i=O(t);return await a[s].findFirst({where:i,...n?.length?{select:n.reduce((c,l)=>({...c,[l]:!0}),{})}:{}})},async findMany(r){let{model:s,where:t}=r,n=O(t);return await a[s].findMany({where:n})},async update(r){let{model:s,where:t,update:n}=r,i=O(t);return await a[s].update({where:i,data:n})},async delete(r){let{model:s,where:t}=r,n=O(t);return await a[s].delete({where:n})},async createSchema(r,s){let t=C(r),n=s||"./prisma/schema.prisma",i=K(E.join(process.cwd(),n)),c="";return i?c=await W.readFile(E.join(process.cwd(),n),"utf-8"):c=X(o),{code:H(c,d=>{for(let p in t){let b=function(y,h){if(y==="string")return h?"String?":"String";if(y==="number")return h?"Int?":"Int";if(y==="boolean")return h?"Boolean?":"Boolean";if(y==="date")return h?"DateTime?":"DateTime"};var u=b;let g=t[p].fields,m=t[p].tableName,f=d.findByType("model",{name:m});!f&&d.model(m).field("id","String").attribute("id");for(let y in g){let h=g[y];if(f){let A=d.findByType("field",{name:y,within:f.properties});if(console.log(y,"exists"),A)continue}d.model(m).field(y,b(h.type,!h.required)),h.unique&&d.model(m).blockAttribute(`unique([${y}])`),h.references&&d.model(m).field(D(h.references.model),h.references.model).attribute(`relation(fields: [${y}], references: [${h.references.field}], onDelete: Cascade)`)}}}),fileName:n}}}},X=e=>`generator client {
1
+ // src/adapters/prisma-adapter/index.ts
2
+ import { existsSync } from "fs";
3
+ import path from "path";
4
+
5
+ // src/db/get-tables.ts
6
+ var getAuthTables = (options) => {
7
+ const pluginSchema = options.plugins?.reduce(
8
+ (acc, plugin) => {
9
+ const schema = plugin.schema;
10
+ if (!schema) return acc;
11
+ for (const [key, value] of Object.entries(schema)) {
12
+ acc[key] = {
13
+ fields: {
14
+ ...acc[key]?.fields,
15
+ ...value.fields
16
+ },
17
+ tableName: key
18
+ };
19
+ }
20
+ return acc;
21
+ },
22
+ {}
23
+ );
24
+ const shouldAddRateLimitTable = options.rateLimit?.storage === "database";
25
+ const rateLimitTable = {
26
+ rateLimit: {
27
+ tableName: options.rateLimit?.tableName || "rateLimit",
28
+ fields: {
29
+ key: {
30
+ type: "string"
31
+ },
32
+ count: {
33
+ type: "number"
34
+ },
35
+ lastRequest: {
36
+ type: "number"
37
+ }
38
+ }
39
+ }
40
+ };
41
+ const { user, session, account, ...pluginTables } = pluginSchema || {};
42
+ return {
43
+ user: {
44
+ tableName: options.user?.modelName || "user",
45
+ fields: {
46
+ name: {
47
+ type: "string",
48
+ required: true
49
+ },
50
+ email: {
51
+ type: "string",
52
+ unique: true,
53
+ required: true
54
+ },
55
+ emailVerified: {
56
+ type: "boolean",
57
+ defaultValue: () => false,
58
+ required: true
59
+ },
60
+ image: {
61
+ type: "string",
62
+ required: false
63
+ },
64
+ createdAt: {
65
+ type: "date",
66
+ defaultValue: () => /* @__PURE__ */ new Date(),
67
+ required: true
68
+ },
69
+ updatedAt: {
70
+ type: "date",
71
+ defaultValue: () => /* @__PURE__ */ new Date(),
72
+ required: true
73
+ },
74
+ ...user?.fields
75
+ },
76
+ order: 0
77
+ },
78
+ session: {
79
+ tableName: options.session?.modelName || "session",
80
+ fields: {
81
+ expiresAt: {
82
+ type: "date",
83
+ required: true
84
+ },
85
+ ipAddress: {
86
+ type: "string",
87
+ required: false
88
+ },
89
+ userAgent: {
90
+ type: "string",
91
+ required: false
92
+ },
93
+ userId: {
94
+ type: "string",
95
+ references: {
96
+ model: "user",
97
+ field: "id",
98
+ onDelete: "cascade"
99
+ },
100
+ required: true
101
+ },
102
+ ...session?.fields
103
+ },
104
+ order: 1
105
+ },
106
+ account: {
107
+ tableName: options.account?.modelName || "account",
108
+ fields: {
109
+ accountId: {
110
+ type: "string",
111
+ required: true
112
+ },
113
+ providerId: {
114
+ type: "string",
115
+ required: true
116
+ },
117
+ userId: {
118
+ type: "string",
119
+ references: {
120
+ model: "user",
121
+ field: "id",
122
+ onDelete: "cascade"
123
+ },
124
+ required: true
125
+ },
126
+ accessToken: {
127
+ type: "string",
128
+ required: false
129
+ },
130
+ refreshToken: {
131
+ type: "string",
132
+ required: false
133
+ },
134
+ idToken: {
135
+ type: "string",
136
+ required: false
137
+ },
138
+ expiresAt: {
139
+ type: "date",
140
+ required: false
141
+ },
142
+ password: {
143
+ type: "string",
144
+ required: false
145
+ },
146
+ ...account?.fields
147
+ },
148
+ order: 2
149
+ },
150
+ ...pluginTables,
151
+ ...shouldAddRateLimitTable ? rateLimitTable : {}
152
+ };
153
+ };
154
+
155
+ // src/adapters/prisma-adapter/index.ts
156
+ import fs from "fs/promises";
157
+ import { produceSchema } from "@mrleebo/prisma-ast";
158
+
159
+ // src/error/better-auth-error.ts
160
+ var BetterAuthError = class extends Error {
161
+ constructor(message, cause, docsLink) {
162
+ super(message);
163
+ this.name = "BetterAuthError";
164
+ this.message = message;
165
+ this.cause = cause;
166
+ this.stack = "";
167
+ }
168
+ };
169
+ var MissingDependencyError = class extends BetterAuthError {
170
+ constructor(pkgName) {
171
+ super(
172
+ `The package "${pkgName}" is required. Make sure it is installed.`,
173
+ pkgName
174
+ );
175
+ }
176
+ };
177
+
178
+ // src/utils/cookies.ts
179
+ import { TimeSpan } from "oslo";
180
+
181
+ // src/utils/id.ts
182
+ import { alphabet, generateRandomString } from "oslo/crypto";
183
+
184
+ // src/utils/logger.ts
185
+ import { createConsola } from "consola";
186
+ var consola = createConsola({
187
+ formatOptions: {
188
+ date: false,
189
+ colors: true,
190
+ compact: true
191
+ },
192
+ defaults: {
193
+ tag: "Better Auth"
194
+ }
195
+ });
196
+ var createLogger = (options) => {
197
+ return {
198
+ log: (...args) => {
199
+ !options?.disabled && consola.log("", ...args);
200
+ },
201
+ error: (...args) => {
202
+ !options?.disabled && consola.error("", ...args);
203
+ },
204
+ warn: (...args) => {
205
+ !options?.disabled && consola.warn("", ...args);
206
+ },
207
+ info: (...args) => {
208
+ !options?.disabled && consola.info("", ...args);
209
+ },
210
+ debug: (...args) => {
211
+ !options?.disabled && consola.debug("", ...args);
212
+ },
213
+ box: (...args) => {
214
+ !options?.disabled && consola.box("", ...args);
215
+ },
216
+ success: (...args) => {
217
+ !options?.disabled && consola.success("", ...args);
218
+ },
219
+ break: (...args) => {
220
+ !options?.disabled && console.log("\n");
221
+ }
222
+ };
223
+ };
224
+ var logger = createLogger();
225
+
226
+ // src/utils/misc.ts
227
+ function capitalizeFirstLetter(str) {
228
+ return str.charAt(0).toUpperCase() + str.slice(1);
229
+ }
230
+
231
+ // src/utils/state.ts
232
+ import { generateState as generateStateOAuth } from "oslo/oauth2";
233
+ import { z } from "zod";
234
+
235
+ // src/adapters/prisma-adapter/index.ts
236
+ function whereConvertor(where) {
237
+ if (!where) return {};
238
+ if (where.length === 1) {
239
+ const w = where[0];
240
+ if (!w) {
241
+ return;
242
+ }
243
+ return {
244
+ [w.field]: w.value
245
+ };
246
+ }
247
+ const and2 = where.filter((w) => w.connector === "AND" || !w.connector);
248
+ const or2 = where.filter((w) => w.connector === "OR");
249
+ const andClause = and2.map((w) => {
250
+ return {
251
+ [w.field]: w.operator === "eq" || !w.operator ? w.value : {
252
+ [w.operator]: w.value
253
+ }
254
+ };
255
+ });
256
+ const orClause = or2.map((w) => {
257
+ return {
258
+ [w.field]: {
259
+ [w.operator || "eq"]: w.value
260
+ }
261
+ };
262
+ });
263
+ return {
264
+ AND: andClause.length ? andClause : void 0,
265
+ OR: orClause.length ? orClause : void 0
266
+ };
267
+ }
268
+ var prismaAdapter = (prisma, {
269
+ provider
270
+ }) => {
271
+ const db = prisma;
272
+ return {
273
+ id: "prisma",
274
+ async create(data) {
275
+ const { model, data: val, select } = data;
276
+ return await db[model].create({
277
+ data: val,
278
+ ...select?.length ? {
279
+ select: select.reduce((prev, cur) => {
280
+ return {
281
+ ...prev,
282
+ [cur]: true
283
+ };
284
+ }, {})
285
+ } : {}
286
+ });
287
+ },
288
+ async findOne(data) {
289
+ const { model, where, select } = data;
290
+ const whereClause = whereConvertor(where);
291
+ return await db[model].findFirst({
292
+ where: whereClause,
293
+ ...select?.length ? {
294
+ select: select.reduce((prev, cur) => {
295
+ return {
296
+ ...prev,
297
+ [cur]: true
298
+ };
299
+ }, {})
300
+ } : {}
301
+ });
302
+ },
303
+ async findMany(data) {
304
+ const { model, where } = data;
305
+ const whereClause = whereConvertor(where);
306
+ return await db[model].findMany({ where: whereClause });
307
+ },
308
+ async update(data) {
309
+ const { model, where, update } = data;
310
+ const whereClause = whereConvertor(where);
311
+ return await db[model].update({
312
+ where: whereClause,
313
+ data: update
314
+ });
315
+ },
316
+ async delete(data) {
317
+ const { model, where } = data;
318
+ const whereClause = whereConvertor(where);
319
+ return await db[model].delete({ where: whereClause });
320
+ },
321
+ async createSchema(options, file) {
322
+ const tables = getAuthTables(options);
323
+ const filePath = file || "./prisma/schema.prisma";
324
+ const schemaPrismaExist = existsSync(path.join(process.cwd(), filePath));
325
+ let schemaPrisma = "";
326
+ if (schemaPrismaExist) {
327
+ schemaPrisma = await fs.readFile(
328
+ path.join(process.cwd(), filePath),
329
+ "utf-8"
330
+ );
331
+ } else {
332
+ schemaPrisma = getNewPrisma(provider);
333
+ }
334
+ const schema = produceSchema(schemaPrisma, (builder) => {
335
+ for (const table in tables) {
336
+ let getType2 = function(type, isOptional) {
337
+ if (type === "string") {
338
+ return isOptional ? "String?" : "String";
339
+ }
340
+ if (type === "number") {
341
+ return isOptional ? "Int?" : "Int";
342
+ }
343
+ if (type === "boolean") {
344
+ return isOptional ? "Boolean?" : "Boolean";
345
+ }
346
+ if (type === "date") {
347
+ return isOptional ? "DateTime?" : "DateTime";
348
+ }
349
+ };
350
+ var getType = getType2;
351
+ const fields = tables[table].fields;
352
+ const tableName = tables[table].tableName;
353
+ const prismaModel = builder.findByType("model", {
354
+ name: tableName
355
+ });
356
+ !prismaModel && builder.model(tableName).field("id", "String").attribute("id");
357
+ for (const field in fields) {
358
+ const attr = fields[field];
359
+ if (prismaModel) {
360
+ const isAlreadyExist = builder.findByType("field", {
361
+ name: field,
362
+ within: prismaModel.properties
363
+ });
364
+ console.log(field, "exists");
365
+ if (isAlreadyExist) {
366
+ continue;
367
+ }
368
+ }
369
+ builder.model(tableName).field(field, getType2(attr.type, !attr.required));
370
+ if (attr.unique) {
371
+ builder.model(tableName).blockAttribute(`unique([${field}])`);
372
+ }
373
+ if (attr.references) {
374
+ builder.model(tableName).field(
375
+ capitalizeFirstLetter(attr.references.model),
376
+ attr.references.model
377
+ ).attribute(
378
+ `relation(fields: [${field}], references: [${attr.references.field}], onDelete: Cascade)`
379
+ );
380
+ }
381
+ }
382
+ }
383
+ });
384
+ return {
385
+ code: schema.trim() === schemaPrisma.trim() ? "" : schema,
386
+ fileName: filePath
387
+ };
388
+ }
389
+ };
390
+ };
391
+ var getNewPrisma = (provider) => `generator client {
3
392
  provider = "prisma-client-js"
4
393
  }
5
394
 
6
395
  datasource db {
7
- provider = "${e}"
8
- url = ${e==="sqlite"?'"file:./dev.db"':'env("DATABASE_URL")'}
9
- }`;import{and as Q,eq as B,or as J}from"drizzle-orm";import*as P from"prettier";import{existsSync as Y}from"fs";import Z from"fs/promises";function T(e,o){let a=Object.keys(o).find(r=>{let s=o[r].name;return s===s});if(!a)throw new Error("Model not found");return o[a]}function q(e,o){if(!e)return[];if(e.length===1){let i=e[0];return i?[B(o[i.field],i.value)]:[]}let a=e.filter(i=>i.connector==="AND"||!i.connector),r=e.filter(i=>i.connector==="OR"),s=Q(...a.map(i=>B(o[i.field],i.value))),t=J(...r.map(i=>B(o[i.field],i.value))),n=[];return a.length&&n.push(s),r.length&&n.push(t),n}var ut=(e,o)=>{let a=o?.schema||e._.schema;if(!a)throw new w("Drizzle adapter failed to initialize. Schema not found. Please provide a schema object in the adapter options object.");let r=o?.provider;return{id:"drizzle",async create(s){let{model:t,data:n}=s,i=T(t,a);return(await e.insert(i).values(n).returning())[0]},async findOne(s){let{model:t,where:n,select:i}=s,c=T(t,a),l=q(n,c),d=null;return i?.length?d=await e.select(...i.map(u=>({[u]:c[u]}))).from(c).where(...l):d=await e.select().from(c).where(...l),d.length?d[0]:null},async findMany(s){let{model:t,where:n}=s,i=T(t,a),c=n?q(n,i):[];return await e.select().from(i).findMany(...c)},async update(s){let{model:t,where:n,update:i}=s,c=T(t,a),l=q(n,c);return(await e.update(c).set(i).where(...l).returning())[0]},async delete(s){let{model:t,where:n}=s,i=T(t,a),c=q(n,i);return(await e.delete(i).where(...c))[0]},async createSchema(s,t){let n=C(s),i=t||"./schema.ts",c=r!=="sqlite"?"timestamp, boolean":"",l=r==="mysql"?"int":"integer",d="",u=Y(i);if(u){let m=await Z.readFile(i,"utf-8");m.includes("import")?d=m:d=`import { ${r}Table, text, ${l}, ${c} } from "drizzle-orm/${r}-core";
10
- `}else d=`import { ${r}Table, text, ${l}, ${c} } from "drizzle-orm/${r}-core";
11
- `;for(let m in n){let y=function(A,x){if(x==="string")return`text('${A}')`;if(x==="number")return`${l}('${A}')`;if(x==="boolean")return r==="sqlite"?`integer('${A}', {
396
+ provider = "${provider}"
397
+ url = ${provider === "sqlite" ? `"file:./dev.db"` : `env("DATABASE_URL")`}
398
+ }`;
399
+
400
+ // src/adapters/drizzle-adapter/index.ts
401
+ import { and, eq, or } from "drizzle-orm";
402
+ import * as prettier from "prettier";
403
+ import { existsSync as existsSync2 } from "fs";
404
+ import fs2 from "fs/promises";
405
+ function getSchema(modelName, schema) {
406
+ const key = Object.keys(schema).find((key2) => {
407
+ const modelName2 = schema[key2].name;
408
+ return modelName2 === modelName2;
409
+ });
410
+ if (!key) {
411
+ throw new Error("Model not found");
412
+ }
413
+ return schema[key];
414
+ }
415
+ function whereConvertor2(where, schemaModel) {
416
+ if (!where) return [];
417
+ if (where.length === 1) {
418
+ const w = where[0];
419
+ if (!w) {
420
+ return [];
421
+ }
422
+ return [eq(schemaModel[w.field], w.value)];
423
+ }
424
+ const andGroup = where.filter((w) => w.connector === "AND" || !w.connector);
425
+ const orGroup = where.filter((w) => w.connector === "OR");
426
+ const andClause = and(
427
+ ...andGroup.map((w) => {
428
+ return eq(schemaModel[w.field], w.value);
429
+ })
430
+ );
431
+ const orClause = or(
432
+ ...orGroup.map((w) => {
433
+ return eq(schemaModel[w.field], w.value);
434
+ })
435
+ );
436
+ const clause = [];
437
+ if (andGroup.length) clause.push(andClause);
438
+ if (orGroup.length) clause.push(orClause);
439
+ return clause;
440
+ }
441
+ var drizzleAdapter = (db, options) => {
442
+ const schema = options?.schema || db._.schema;
443
+ if (!schema) {
444
+ throw new BetterAuthError(
445
+ "Drizzle adapter failed to initialize. Schema not found. Please provide a schema object in the adapter options object."
446
+ );
447
+ }
448
+ const databaseType = options?.provider;
449
+ return {
450
+ id: "drizzle",
451
+ async create(data) {
452
+ const { model, data: val } = data;
453
+ const schemaModel = getSchema(model, schema);
454
+ const res = await db.insert(schemaModel).values(val).returning();
455
+ return res[0];
456
+ },
457
+ async findOne(data) {
458
+ const { model, where, select: included } = data;
459
+ const schemaModel = getSchema(model, schema);
460
+ const wheres = whereConvertor2(where, schemaModel);
461
+ let res = null;
462
+ if (!!included?.length) {
463
+ res = await db.select(
464
+ ...included.map((include) => {
465
+ return {
466
+ [include]: schemaModel[include]
467
+ };
468
+ })
469
+ ).from(schemaModel).where(...wheres);
470
+ } else {
471
+ res = await db.select().from(schemaModel).where(...wheres);
472
+ }
473
+ if (!!res.length) return res[0];
474
+ else return null;
475
+ },
476
+ async findMany(data) {
477
+ const { model, where } = data;
478
+ const schemaModel = getSchema(model, schema);
479
+ const wheres = where ? whereConvertor2(where, schemaModel) : [];
480
+ return await db.select().from(schemaModel).findMany(...wheres);
481
+ },
482
+ async update(data) {
483
+ const { model, where, update } = data;
484
+ const schemaModel = getSchema(model, schema);
485
+ const wheres = whereConvertor2(where, schemaModel);
486
+ const res = await db.update(schemaModel).set(update).where(...wheres).returning();
487
+ return res[0];
488
+ },
489
+ async delete(data) {
490
+ const { model, where } = data;
491
+ const schemaModel = getSchema(model, schema);
492
+ const wheres = whereConvertor2(where, schemaModel);
493
+ const res = await db.delete(schemaModel).where(...wheres);
494
+ return res[0];
495
+ },
496
+ async createSchema(options2, file) {
497
+ const tables = getAuthTables(options2);
498
+ const filePath = file || "./schema.ts";
499
+ const timestampAndBoolean = databaseType !== "sqlite" ? "timestamp, boolean" : "";
500
+ const int = databaseType === "mysql" ? "int" : "integer";
501
+ let code = `import { ${databaseType}Table, text, ${int}, ${timestampAndBoolean} } from "drizzle-orm/${databaseType}-core";
502
+ `;
503
+ const fileExist = existsSync2(filePath);
504
+ let fileContent = await fs2.readFile(filePath, "utf-8");
505
+ for (const table in tables) {
506
+ let getType2 = function(name, type) {
507
+ if (type === "string") {
508
+ return `text('${name}')`;
509
+ }
510
+ if (type === "number") {
511
+ return `${int}('${name}')`;
512
+ }
513
+ if (type === "boolean") {
514
+ if (databaseType === "sqlite") {
515
+ return `integer('${name}', {
12
516
  mode: "boolean"
13
- })`:`boolean('${A}')`;if(x==="date")return r==="sqlite"?`integer('${A}', {
517
+ })`;
518
+ }
519
+ return `boolean('${name}')`;
520
+ }
521
+ if (type === "date") {
522
+ if (databaseType === "sqlite") {
523
+ return `integer('${name}', {
14
524
  mode: "timestamp"
15
- })`:`timestamp('${A}')`};var g=y;let b=n[m].tableName,f=n[m].fields,h=`export const ${m} = ${r}Table("${b}", {
525
+ })`;
526
+ }
527
+ return `timestamp('${name}')`;
528
+ }
529
+ };
530
+ var getType = getType2;
531
+ const tableName = tables[table].tableName;
532
+ const fields = tables[table].fields;
533
+ const schema2 = `export const ${table} = ${databaseType}Table("${tableName}", {
16
534
  id: text("id").primaryKey(),
17
- ${Object.keys(f).map(A=>{let x=f[A];return`${A}: ${y(A,x.type)}${x.required?".notNull()":""}${x.unique?".unique()":""}${x.references?`.references(()=> ${x.references.model}.${x.references.field})`:""}`}).join()}
18
- });`;d+=`
19
- ${h}
20
- `}return{code:await P.format(d,{semi:!0,parser:"typescript",tabWidth:4}),fileName:i,append:u}}}};function $(e){if(!e)return{};if(e.length===1){let n=e[0];return n?{[n.field]:n.value}:void 0}let o=e.filter(n=>n.connector==="AND"||!n.connector),a=e.filter(n=>n.connector==="OR"),r=o.map(n=>({[n.field]:n.operator==="eq"||!n.operator?n.value:{[n.field]:n.value}})),s=a.map(n=>({[n.field]:n.value})),t={};return r.length&&(t={...t,$and:r}),s.length&&(t={...t,$or:s}),t}function S(e){let{_id:o,...a}=e;return a}function ee(e){return e.reduce((a,r)=>(a[r]=1,a),{})}var pt=e=>{let o=e;return{id:"mongodb",async create(a){let{model:r,data:s}=a,i={id:(await o.collection(r).insertOne({...s})).insertedId,...s};return S(i)},async findOne(a){let{model:r,where:s,select:t}=a,n=$(s),i={};t&&(i=ee(t));let l=(await o.collection(r).find({...n},{projection:i}).toArray())[0];return l?S(l):null},async findMany(a){let{model:r,where:s}=a,t=$(s),n=await o.collection(r).findMany(t);return S(n)},async update(a){let{model:r,where:s,update:t}=a,n=$(s),i=await o.collection(r).findOneAndUpdate(n,{$set:t},{returnDocument:"after"});return S(i)},async delete(a){let{model:r,where:s}=a,t=$(s);return await o.collection(r).findOneAndDelete(t)}}};import"kysely";function te(e){return e.plugins?.flatMap(a=>Object.keys(a.schema||{}).map(r=>{let t=(a.schema||{})[r];if(!t?.disableMigration)return{tableName:r,fields:t?.fields}}).filter(r=>r!==void 0))||[]}function _(e){let o=C(e),a=te(e);return[o.user,o.session,o.account,...a].reduce((s,t)=>(s[t.tableName]={fields:{...s[t.tableName]?.fields,...t.fields}},s),{})}import{Kysely as re}from"kysely";import{MysqlDialect as L,PostgresDialect as M,SqliteDialect as F}from"kysely";var ne=async e=>{if(!e.database)return;if("createDriver"in e.database)return e.database;let o;if("provider"in e.database){let a=e.database.provider,r=e.database?.url?.trim();if(a==="postgres"){let t=(await import("pg").catch(n=>{throw new w("Please install `pg` to use postgres database")})).Pool;o=new M({pool:new t({connectionString:r})})}if(a==="mysql")try{let{createPool:s}=await import("mysql2/promise").catch(i=>{throw new w("Please install `mysql2` to use mysql database")}),t=new URL(r),n=s({host:t.hostname,user:t.username,password:t.password,database:t.pathname.split("/")[1],port:Number(t.port)});o=new L({pool:n})}catch(s){if(s instanceof TypeError)throw new w("Invalid database URL")}if(a==="sqlite")try{let s=await import("better-sqlite3").catch(i=>{throw new w("Please install `better-sqlite3` to use sqlite database")}),t=s.default||s;if(!t)throw new w("Failed to import better-sqlite3. Please ensure `better-sqlite3` is properly installed.");let n=new t(r);o=new F({database:n})}catch(s){throw console.error(s),new w("Failed to initialize SQLite. Please ensure `better-sqlite3` is properly installed.")}}return o},I=async e=>{let o=await ne(e);return o&&new re({dialect:o})},U=e=>{if("provider"in e.database)return e.database.provider;if("dialect"in e.database){if(e.database.dialect instanceof M)return"postgres";if(e.database.dialect instanceof L)return"mysql";if(e.database.dialect instanceof F)return"sqlite"}return"sqlite"};var oe={string:["character varying","text"],number:["int4","integer","bigint","smallint","numeric","real","double precision"],boolean:["bool","boolean"],date:["timestamp","date"]},se={string:["varchar","text"],number:["integer","int","bigint","smallint","decimal","float","double"],boolean:["boolean"],date:["date","datetime"]},ae={string:["TEXT"],number:["INTEGER","REAL"],boolean:["INTEGER","BOOLEAN"],date:["DATE","INTEGER"]},ie={postgres:oe,mysql:se,sqlite:ae};function ce(e,o,a){return ie[a][o].map(n=>n.toLowerCase()).includes(e.toLowerCase())}async function j(e){let o=_(e),a=U(e),r=await I(e);r||(N.error("Invalid database configuration."),process.exit(1));let s=await r.introspection.getTables(),t=[],n=[];for(let[u,p]of Object.entries(o)){let g=s.find(b=>b.name===u);if(!g){let b=t.findIndex(h=>h.table===u),f={table:u,fields:p.fields,order:p.order||1/0},y=t.findIndex(h=>(h.order||1/0)>f.order);y===-1?b===-1?t.push(f):t[b].fields={...t[b].fields,...p.fields}:t.splice(y,0,f);continue}let m={};for(let[b,f]of Object.entries(p.fields)){let y=g.columns.find(h=>h.name===b);if(!y){m[b]=f;continue}ce(y.dataType,f.type,a)||N.warn(`Field ${b} in table ${u} has a different type in the database. Expected ${f.type} but got ${y.dataType}.`)}Object.keys(m).length>0&&n.push({table:u,fields:m,order:p.order||1/0})}let i=[];function c(u){let p={string:"text",boolean:"boolean",number:"integer",date:"date"};return a==="mysql"&&u==="string"?"varchar(255)":p[u]}if(n.length)for(let u of n)for(let[p,g]of Object.entries(u.fields)){let m=c(g.type),b=r.schema.alterTable(u.table).addColumn(p,m,f=>(f=g.required!==!1?f.notNull():f,g.references&&(f=f.references(`${g.references.model}.${g.references.field}`)),f));i.push(b)}if(t.length)for(let u of t){let p=r.schema.createTable(u.table).addColumn("id",c("string"),g=>g.primaryKey());for(let[g,m]of Object.entries(u.fields)){let b=c(m.type);p=p.addColumn(g,b,f=>(f=m.required!==!1?f.notNull():f,m.references&&(f=f.references(`${m.references.model}.${m.references.field}`)),m.unique&&(f=f.unique()),f))}i.push(p)}async function l(){for(let u of i)await u.execute()}async function d(){return i.map(p=>p.compile().sql).join(`;
535
+ ${Object.keys(fields).map((field) => {
536
+ const attr = fields[field];
537
+ return `${field}: ${getType2(field, attr.type)}${attr.required ? ".notNull()" : ""}${attr.unique ? ".unique()" : ""}${attr.references ? `.references(()=> ${attr.references.model}.${attr.references.field})` : ""}`;
538
+ }).join()}
539
+ });`;
540
+ code += `
541
+ ${schema2}
542
+ `;
543
+ }
544
+ if (fileExist) {
545
+ if (fileContent.includes(code)) {
546
+ return {
547
+ code: "",
548
+ fileName: filePath,
549
+ append: false
550
+ };
551
+ }
552
+ if (fileContent.includes("import")) {
553
+ code = code.replace(/import {.*?} from "drizzle-orm\/.*?";/, "");
554
+ }
555
+ }
556
+ const formattedCode = await prettier.format(code, {
557
+ semi: true,
558
+ parser: "typescript",
559
+ tabWidth: 4
560
+ });
561
+ return {
562
+ code: formattedCode,
563
+ fileName: filePath,
564
+ append: fileExist
565
+ };
566
+ }
567
+ };
568
+ };
21
569
 
22
- `)}return{toBeCreated:t,toBeAdded:n,runMigrations:l,compileMigrations:d}}function v(e){if(!e)return{and:null,or:null};let o=e?.filter(r=>r.connector==="AND"||!r.connector).reduce((r,s)=>({...r,[s.field]:s.value}),{}),a=e?.filter(r=>r.connector==="OR").reduce((r,s)=>({...r,[s.field]:s.value}),{});return{and:Object.keys(o).length?o:null,or:Object.keys(a).length?a:null}}function R(e,o,a){for(let r in e)e[r]===0&&o[r]?.type==="boolean"&&a?.boolean&&(e[r]=!1),e[r]===1&&o[r]?.type==="boolean"&&a?.boolean&&(e[r]=!0),o[r]?.type==="date"&&(e[r]instanceof Date||(e[r]=new Date(e[r])));return e}function z(e,o){for(let a in e)typeof e[a]=="boolean"&&o?.boolean&&(e[a]=e[a]?1:0),e[a]instanceof Date&&(e[a]=e[a].toISOString());return e}var St=(e,o)=>({id:"kysely",async create(a){let{model:r,data:s,select:t}=a;o?.transform&&(s=z(s,o.transform));let n=await e.insertInto(r).values(s).returningAll().executeTakeFirst();if(o?.transform){let i=o.transform.schema[r];n=i?R(s,i,o.transform):n}return t?.length&&(n=n?t.reduce((c,l)=>n?.[l]?{...c,[l]:n[l]}:c,{}):null),n},async findOne(a){let{model:r,where:s,select:t}=a,{and:n,or:i}=v(s),c=e.selectFrom(r).selectAll();i&&(c=c.where(d=>d.or(i))),n&&(c=c.where(d=>d.and(n)));let l=await c.executeTakeFirst();if(t?.length&&(l=l?t.reduce((u,p)=>l?.[p]?{...u,[p]:l[p]}:u,{}):null),o?.transform){let d=o.transform.schema[r];return l=l&&d?R(l,d,o.transform):l,l||null}return l||null},async findMany(a){let{model:r,where:s}=a,t=e.selectFrom(r),{and:n,or:i}=v(s);n&&(t=t.where(l=>l.and(n))),i&&(t=t.where(l=>l.or(i)));let c=await t.selectAll().execute();if(o?.transform){let l=o.transform.schema[r];return l?c.map(d=>R(d,l,o.transform)):c}return c},async update(a){let{model:r,where:s,update:t}=a,{and:n,or:i}=v(s);o?.transform&&(t=z(t,o.transform));let c=e.updateTable(r).set(t);n&&(c=c.where(d=>d.and(n))),i&&(c=c.where(d=>d.or(i)));let l=await c.returningAll().executeTakeFirst()||null;if(o?.transform){let d=o.transform.schema[r];return d?R(l,d,o.transform):l}return l},async delete(a){let{model:r,where:s}=a,{and:t,or:n}=v(s),i=e.deleteFrom(r);t&&(i=i.where(c=>c.and(t))),n&&(i=i.where(c=>c.or(n))),await i.execute()},async createSchema(a){let{compileMigrations:r}=await j(a);return console.log(r),{code:await r(),fileName:`./better-auth_migrations/${new Date().toISOString()}.sql`}}});export{ut as drizzleAdapter,St as kyselyAdapter,pt as mongodbAdapter,nt as prismaAdapter};
570
+ // src/adapters/mongodb-adapter/index.ts
571
+ function whereConvertor3(where) {
572
+ if (!where) return {};
573
+ if (where.length === 1) {
574
+ const w = where[0];
575
+ if (!w) {
576
+ return;
577
+ }
578
+ return {
579
+ [w.field]: w.value
580
+ };
581
+ }
582
+ const and2 = where.filter((w) => w.connector === "AND" || !w.connector);
583
+ const or2 = where.filter((w) => w.connector === "OR");
584
+ const andClause = and2.map((w) => {
585
+ return {
586
+ [w.field]: w.operator === "eq" || !w.operator ? w.value : {
587
+ [w.field]: w.value
588
+ }
589
+ };
590
+ });
591
+ const orClause = or2.map((w) => {
592
+ return {
593
+ [w.field]: w.value
594
+ };
595
+ });
596
+ let clause = {};
597
+ if (andClause.length) {
598
+ clause = { ...clause, $and: andClause };
599
+ }
600
+ if (orClause.length) {
601
+ clause = { ...clause, $or: orClause };
602
+ }
603
+ return clause;
604
+ }
605
+ function removeMongoId(data) {
606
+ const { _id, ...rest } = data;
607
+ return rest;
608
+ }
609
+ function selectConvertor(selects) {
610
+ const selectConstruct = selects.reduce((acc, field) => {
611
+ acc[field] = 1;
612
+ return acc;
613
+ }, {});
614
+ return selectConstruct;
615
+ }
616
+ var mongodbAdapter = (mongo) => {
617
+ const db = mongo;
618
+ return {
619
+ id: "mongodb",
620
+ async create(data) {
621
+ const { model, data: val } = data;
622
+ const res = await db.collection(model).insertOne({
623
+ ...val
624
+ });
625
+ const id_ = res.insertedId;
626
+ const returned = { id: id_, ...val };
627
+ return removeMongoId(returned);
628
+ },
629
+ async findOne(data) {
630
+ const { model, where, select } = data;
631
+ const wheres = whereConvertor3(where);
632
+ let selects = {};
633
+ if (select) {
634
+ selects = selectConvertor(select);
635
+ }
636
+ const res = await db.collection(model).find({ ...wheres }, { projection: selects }).toArray();
637
+ const result = res[0];
638
+ if (!result) {
639
+ return null;
640
+ }
641
+ return removeMongoId(result);
642
+ },
643
+ async findMany(data) {
644
+ const { model, where } = data;
645
+ const wheres = whereConvertor3(where);
646
+ const toReturn = await db.collection(model).findMany(wheres);
647
+ return removeMongoId(toReturn);
648
+ },
649
+ async update(data) {
650
+ const { model, where, update } = data;
651
+ const wheres = whereConvertor3(where);
652
+ const res = await db.collection(model).findOneAndUpdate(
653
+ wheres,
654
+ {
655
+ $set: update
656
+ },
657
+ { returnDocument: "after" }
658
+ );
659
+ return removeMongoId(res);
660
+ },
661
+ async delete(data) {
662
+ const { model, where } = data;
663
+ const wheres = whereConvertor3(where);
664
+ const res = await db.collection(model).findOneAndDelete(wheres);
665
+ return res;
666
+ }
667
+ };
668
+ };
669
+
670
+ // src/cli/utils/get-migration.ts
671
+ import "kysely";
672
+
673
+ // src/cli/utils/get-schema.ts
674
+ function getPluginTable(config) {
675
+ const pluginsMigrations = config.plugins?.flatMap(
676
+ (plugin) => Object.keys(plugin.schema || {}).map((key) => {
677
+ const schema = plugin.schema || {};
678
+ const table = schema[key];
679
+ if (table?.disableMigration) {
680
+ return;
681
+ }
682
+ return {
683
+ tableName: key,
684
+ fields: table?.fields
685
+ };
686
+ }).filter((value) => value !== void 0)
687
+ ) || [];
688
+ return pluginsMigrations;
689
+ }
690
+ function getSchema2(config) {
691
+ const baseSchema = getAuthTables(config);
692
+ const pluginSchema = getPluginTable(config);
693
+ const schema = [
694
+ baseSchema.user,
695
+ baseSchema.session,
696
+ baseSchema.account,
697
+ ...pluginSchema
698
+ ].reduce((acc, curr) => {
699
+ acc[curr.tableName] = {
700
+ fields: {
701
+ ...acc[curr.tableName]?.fields,
702
+ ...curr.fields
703
+ }
704
+ };
705
+ return acc;
706
+ }, {});
707
+ return schema;
708
+ }
709
+
710
+ // src/adapters/kysely-adapter/dialect.ts
711
+ import { Kysely } from "kysely";
712
+ import {
713
+ MysqlDialect,
714
+ PostgresDialect,
715
+ SqliteDialect
716
+ } from "kysely";
717
+ import "execa";
718
+ import "prompts";
719
+
720
+ // src/cli/utils/get-package-manager.ts
721
+ import { detect } from "@antfu/ni";
722
+
723
+ // src/adapters/kysely-adapter/dialect.ts
724
+ import "ora";
725
+ var getDialect = async (config, isCli) => {
726
+ if (!config.database) {
727
+ return void 0;
728
+ }
729
+ if ("createDriver" in config.database) {
730
+ return config.database;
731
+ }
732
+ let dialect = void 0;
733
+ if ("provider" in config.database) {
734
+ const provider = config.database.provider;
735
+ const connectionString = config.database?.url?.trim();
736
+ if (provider === "postgres") {
737
+ const pg = await import("pg").catch(async (e) => {
738
+ throw new MissingDependencyError("pg");
739
+ });
740
+ const Pool = pg.default?.Pool || pg.Pool;
741
+ const pool = new Pool({
742
+ connectionString
743
+ });
744
+ dialect = new PostgresDialect({
745
+ pool
746
+ });
747
+ }
748
+ if (provider === "mysql") {
749
+ try {
750
+ const { createPool } = await import("mysql2/promise").catch(
751
+ async (e) => {
752
+ throw new MissingDependencyError("mysql2");
753
+ }
754
+ );
755
+ const params = new URL(connectionString);
756
+ const pool = createPool({
757
+ host: params.hostname,
758
+ user: params.username,
759
+ password: params.password,
760
+ database: params.pathname.split("/")[1],
761
+ port: Number(params.port)
762
+ });
763
+ dialect = new MysqlDialect({ pool });
764
+ } catch (e) {
765
+ if (e instanceof TypeError) {
766
+ throw new BetterAuthError("Invalid database URL");
767
+ }
768
+ throw e;
769
+ }
770
+ }
771
+ if (provider === "sqlite") {
772
+ try {
773
+ const database = await import("better-sqlite3").catch(async (e) => {
774
+ throw new MissingDependencyError("better-sqlite3");
775
+ });
776
+ const Database = database.default || database;
777
+ const db = new Database(connectionString);
778
+ dialect = new SqliteDialect({
779
+ database: db
780
+ });
781
+ } catch (e) {
782
+ console.error(e);
783
+ throw new BetterAuthError(
784
+ "Failed to initialize SQLite. Make sure `better-sqlite3` is properly installed."
785
+ );
786
+ }
787
+ }
788
+ }
789
+ return dialect;
790
+ };
791
+ var createKyselyAdapter = async (config, isCli) => {
792
+ const dialect = await getDialect(config, isCli);
793
+ if (!dialect) {
794
+ return dialect;
795
+ }
796
+ const db = new Kysely({
797
+ dialect
798
+ });
799
+ return db;
800
+ };
801
+ var getDatabaseType = (config) => {
802
+ if ("provider" in config.database) {
803
+ return config.database.provider;
804
+ }
805
+ if ("dialect" in config.database) {
806
+ if (config.database.dialect instanceof PostgresDialect) {
807
+ return "postgres";
808
+ }
809
+ if (config.database.dialect instanceof MysqlDialect) {
810
+ return "mysql";
811
+ }
812
+ if (config.database.dialect instanceof SqliteDialect) {
813
+ return "sqlite";
814
+ }
815
+ }
816
+ return "sqlite";
817
+ };
818
+
819
+ // src/cli/utils/get-migration.ts
820
+ var postgresMap = {
821
+ string: ["character varying", "text"],
822
+ number: [
823
+ "int4",
824
+ "integer",
825
+ "bigint",
826
+ "smallint",
827
+ "numeric",
828
+ "real",
829
+ "double precision"
830
+ ],
831
+ boolean: ["bool", "boolean"],
832
+ date: ["timestamp", "date"]
833
+ };
834
+ var mysqlMap = {
835
+ string: ["varchar", "text"],
836
+ number: [
837
+ "integer",
838
+ "int",
839
+ "bigint",
840
+ "smallint",
841
+ "decimal",
842
+ "float",
843
+ "double"
844
+ ],
845
+ boolean: ["boolean"],
846
+ date: ["date", "datetime"]
847
+ };
848
+ var sqliteMap = {
849
+ string: ["TEXT"],
850
+ number: ["INTEGER", "REAL"],
851
+ boolean: ["INTEGER", "BOOLEAN"],
852
+ // 0 or 1
853
+ date: ["DATE", "INTEGER"]
854
+ };
855
+ var map = {
856
+ postgres: postgresMap,
857
+ mysql: mysqlMap,
858
+ sqlite: sqliteMap
859
+ };
860
+ function matchType(columnDataType, fieldType, dbType) {
861
+ const types = map[dbType];
862
+ const type = types[fieldType].map((t) => t.toLowerCase());
863
+ const matches = type.includes(columnDataType.toLowerCase());
864
+ return matches;
865
+ }
866
+ async function getMigrations(config) {
867
+ const betterAuthSchema = getSchema2(config);
868
+ const dbType = getDatabaseType(config);
869
+ const db = await createKyselyAdapter(config);
870
+ if (!db) {
871
+ logger.error("Invalid database configuration.");
872
+ process.exit(1);
873
+ }
874
+ const tableMetadata = await db.introspection.getTables();
875
+ const toBeCreated = [];
876
+ const toBeAdded = [];
877
+ for (const [key, value] of Object.entries(betterAuthSchema)) {
878
+ const table = tableMetadata.find((t) => t.name === key);
879
+ if (!table) {
880
+ const tIndex = toBeCreated.findIndex((t) => t.table === key);
881
+ const tableData = {
882
+ table: key,
883
+ fields: value.fields,
884
+ order: value.order || Infinity
885
+ };
886
+ const insertIndex = toBeCreated.findIndex(
887
+ (t) => (t.order || Infinity) > tableData.order
888
+ );
889
+ if (insertIndex === -1) {
890
+ if (tIndex === -1) {
891
+ toBeCreated.push(tableData);
892
+ } else {
893
+ toBeCreated[tIndex].fields = {
894
+ ...toBeCreated[tIndex].fields,
895
+ ...value.fields
896
+ };
897
+ }
898
+ } else {
899
+ toBeCreated.splice(insertIndex, 0, tableData);
900
+ }
901
+ continue;
902
+ }
903
+ let toBeAddedFields = {};
904
+ for (const [fieldName, field] of Object.entries(value.fields)) {
905
+ const column = table.columns.find((c) => c.name === fieldName);
906
+ if (!column) {
907
+ toBeAddedFields[fieldName] = field;
908
+ continue;
909
+ }
910
+ if (matchType(column.dataType, field.type, dbType)) {
911
+ continue;
912
+ } else {
913
+ logger.warn(
914
+ `Field ${fieldName} in table ${key} has a different type in the database. Expected ${field.type} but got ${column.dataType}.`
915
+ );
916
+ }
917
+ }
918
+ if (Object.keys(toBeAddedFields).length > 0) {
919
+ toBeAdded.push({
920
+ table: key,
921
+ fields: toBeAddedFields,
922
+ order: value.order || Infinity
923
+ });
924
+ }
925
+ }
926
+ const migrations = [];
927
+ function getType(type) {
928
+ const typeMap = {
929
+ string: "text",
930
+ boolean: "boolean",
931
+ number: "integer",
932
+ date: "date"
933
+ };
934
+ if (dbType === "mysql" && type === "string") {
935
+ return "varchar(255)";
936
+ }
937
+ return typeMap[type];
938
+ }
939
+ if (toBeAdded.length) {
940
+ for (const table of toBeAdded) {
941
+ for (const [fieldName, field] of Object.entries(table.fields)) {
942
+ const type = getType(field.type);
943
+ const exec = db.schema.alterTable(table.table).addColumn(fieldName, type, (col) => {
944
+ col = field.required !== false ? col.notNull() : col;
945
+ if (field.references) {
946
+ col = col.references(
947
+ `${field.references.model}.${field.references.field}`
948
+ );
949
+ }
950
+ return col;
951
+ });
952
+ migrations.push(exec);
953
+ }
954
+ }
955
+ }
956
+ if (toBeCreated.length) {
957
+ for (const table of toBeCreated) {
958
+ let dbT = db.schema.createTable(table.table).addColumn("id", getType("string"), (col) => col.primaryKey());
959
+ for (const [fieldName, field] of Object.entries(table.fields)) {
960
+ const type = getType(field.type);
961
+ dbT = dbT.addColumn(fieldName, type, (col) => {
962
+ col = field.required !== false ? col.notNull() : col;
963
+ if (field.references) {
964
+ col = col.references(
965
+ `${field.references.model}.${field.references.field}`
966
+ );
967
+ }
968
+ if (field.unique) {
969
+ col = col.unique();
970
+ }
971
+ return col;
972
+ });
973
+ }
974
+ migrations.push(dbT);
975
+ }
976
+ }
977
+ async function runMigrations() {
978
+ for (const migration of migrations) {
979
+ await migration.execute();
980
+ }
981
+ }
982
+ async function compileMigrations() {
983
+ const compiled = migrations.map((m) => m.compile().sql);
984
+ return compiled.join(";\n\n");
985
+ }
986
+ return { toBeCreated, toBeAdded, runMigrations, compileMigrations };
987
+ }
988
+
989
+ // src/adapters/kysely-adapter/index.ts
990
+ function convertWhere(w) {
991
+ if (!w)
992
+ return {
993
+ and: null,
994
+ or: null
995
+ };
996
+ const and2 = w?.filter((w2) => w2.connector === "AND" || !w2.connector).reduce(
997
+ (acc, w2) => ({
998
+ ...acc,
999
+ [w2.field]: w2.value
1000
+ }),
1001
+ {}
1002
+ );
1003
+ const or2 = w?.filter((w2) => w2.connector === "OR").reduce(
1004
+ (acc, w2) => ({
1005
+ ...acc,
1006
+ [w2.field]: w2.value
1007
+ }),
1008
+ {}
1009
+ );
1010
+ return {
1011
+ and: Object.keys(and2).length ? and2 : null,
1012
+ or: Object.keys(or2).length ? or2 : null
1013
+ };
1014
+ }
1015
+ function transformTo(val, fields, transform) {
1016
+ for (const key in val) {
1017
+ if (val[key] === 0 && fields[key]?.type === "boolean" && transform?.boolean) {
1018
+ val[key] = false;
1019
+ }
1020
+ if (val[key] === 1 && fields[key]?.type === "boolean" && transform?.boolean) {
1021
+ val[key] = true;
1022
+ }
1023
+ if (fields[key]?.type === "date") {
1024
+ if (!(val[key] instanceof Date)) {
1025
+ val[key] = new Date(val[key]);
1026
+ }
1027
+ }
1028
+ }
1029
+ return val;
1030
+ }
1031
+ function transformFrom(val, transform) {
1032
+ for (const key in val) {
1033
+ if (typeof val[key] === "boolean" && transform?.boolean) {
1034
+ val[key] = val[key] ? 1 : 0;
1035
+ }
1036
+ if (val[key] instanceof Date) {
1037
+ val[key] = val[key].toISOString();
1038
+ }
1039
+ }
1040
+ return val;
1041
+ }
1042
+ var kyselyAdapter = (db, config) => {
1043
+ return {
1044
+ id: "kysely",
1045
+ async create(data) {
1046
+ let { model, data: val, select } = data;
1047
+ if (config?.transform) {
1048
+ val = transformFrom(val, config.transform);
1049
+ }
1050
+ let res = await db.insertInto(model).values(val).returningAll().executeTakeFirst();
1051
+ if (config?.transform) {
1052
+ const schema = config.transform.schema[model];
1053
+ res = schema ? transformTo(val, schema, config.transform) : res;
1054
+ }
1055
+ if (select?.length) {
1056
+ const data2 = res ? select.reduce((acc, cur) => {
1057
+ if (res?.[cur]) {
1058
+ return {
1059
+ ...acc,
1060
+ [cur]: res[cur]
1061
+ };
1062
+ }
1063
+ return acc;
1064
+ }, {}) : null;
1065
+ res = data2;
1066
+ }
1067
+ return res;
1068
+ },
1069
+ async findOne(data) {
1070
+ const { model, where, select } = data;
1071
+ const { and: and2, or: or2 } = convertWhere(where);
1072
+ let query = db.selectFrom(model).selectAll();
1073
+ if (or2) {
1074
+ query = query.where((eb) => eb.or(or2));
1075
+ }
1076
+ if (and2) {
1077
+ query = query.where((eb) => eb.and(and2));
1078
+ }
1079
+ let res = await query.executeTakeFirst();
1080
+ if (select?.length) {
1081
+ const data2 = res ? select.reduce((acc, cur) => {
1082
+ if (res?.[cur]) {
1083
+ return {
1084
+ ...acc,
1085
+ [cur]: res[cur]
1086
+ };
1087
+ }
1088
+ return acc;
1089
+ }, {}) : null;
1090
+ res = data2;
1091
+ }
1092
+ if (config?.transform) {
1093
+ const schema = config.transform.schema[model];
1094
+ res = res && schema ? transformTo(res, schema, config.transform) : res;
1095
+ return res || null;
1096
+ }
1097
+ return res || null;
1098
+ },
1099
+ async findMany(data) {
1100
+ const { model, where } = data;
1101
+ let query = db.selectFrom(model);
1102
+ const { and: and2, or: or2 } = convertWhere(where);
1103
+ if (and2) {
1104
+ query = query.where((eb) => eb.and(and2));
1105
+ }
1106
+ if (or2) {
1107
+ query = query.where((eb) => eb.or(or2));
1108
+ }
1109
+ const res = await query.selectAll().execute();
1110
+ if (config?.transform) {
1111
+ const schema = config.transform.schema[model];
1112
+ return schema ? res.map((v) => transformTo(v, schema, config.transform)) : res;
1113
+ }
1114
+ return res;
1115
+ },
1116
+ async update(data) {
1117
+ let { model, where, update: val } = data;
1118
+ const { and: and2, or: or2 } = convertWhere(where);
1119
+ if (config?.transform) {
1120
+ val = transformFrom(val, config.transform);
1121
+ }
1122
+ let query = db.updateTable(model).set(val);
1123
+ if (and2) {
1124
+ query = query.where((eb) => eb.and(and2));
1125
+ }
1126
+ if (or2) {
1127
+ query = query.where((eb) => eb.or(or2));
1128
+ }
1129
+ const res = await query.returningAll().executeTakeFirst() || null;
1130
+ if (config?.transform) {
1131
+ const schema = config.transform.schema[model];
1132
+ return schema ? transformTo(res, schema, config.transform) : res;
1133
+ }
1134
+ return res;
1135
+ },
1136
+ async delete(data) {
1137
+ const { model, where } = data;
1138
+ const { and: and2, or: or2 } = convertWhere(where);
1139
+ let query = db.deleteFrom(model);
1140
+ if (and2) {
1141
+ query = query.where((eb) => eb.and(and2));
1142
+ }
1143
+ if (or2) {
1144
+ query = query.where((eb) => eb.or(or2));
1145
+ }
1146
+ await query.execute();
1147
+ },
1148
+ async createSchema(options) {
1149
+ const { compileMigrations } = await getMigrations(options);
1150
+ const migrations = await compileMigrations();
1151
+ return {
1152
+ code: migrations,
1153
+ fileName: `./better-auth_migrations/${(/* @__PURE__ */ new Date()).toISOString()}.sql`
1154
+ };
1155
+ }
1156
+ };
1157
+ };
1158
+ export {
1159
+ drizzleAdapter,
1160
+ kyselyAdapter,
1161
+ mongodbAdapter,
1162
+ prismaAdapter
1163
+ };