@better-auth/drizzle-adapter 1.7.5 → 1.7.7

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/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { a as insensitiveInArray, c as buildRelationKeysByModel, i as insensitiveIlike, l as getOneToOneRelationKey, o as insensitiveNe, r as insensitiveEq, s as insensitiveNotInArray, t as findDrizzleSchemaProblems } from "./schema-check-_Aj1MGau.mjs";
1
+ import { a as insensitiveInArray, c as buildRelationKeysByModel, i as insensitiveIlike, l as getOneToOneRelationKey, o as insensitiveNe, r as insensitiveEq, s as insensitiveNotInArray, t as findDrizzleSchemaProblems } from "./schema-check-DFZjRat1.mjs";
2
2
  import { createAdapterFactory } from "@better-auth/core/db/adapter";
3
3
  import { checksSchema, createSchemaCheck, registerSchemaCheck } from "@better-auth/core/db/internal";
4
4
  import { logger } from "@better-auth/core/env";
@@ -63,10 +63,10 @@ const drizzleAdapter = (db, config) => {
63
63
  if (!schemaModel) throw new BetterAuthError(`[# Drizzle Adapter]: The model "${model}" was not found in the schema object. Please pass the schema directly to the adapter options.`);
64
64
  return schemaModel;
65
65
  }
66
- const withReturning = async (model, builder, data, where) => {
66
+ const withReturning = async (model, modelKey, builder, data, where) => {
67
67
  if (config.provider !== "mysql") return (await builder.returning())[0];
68
68
  await builder.execute();
69
- const schemaModel = getSchema(model);
69
+ const table = getSchema(model);
70
70
  const builderVal = builder.config?.values;
71
71
  if (where?.length) {
72
72
  const clause = convertWhereClause(where.map((w) => {
@@ -75,39 +75,39 @@ const drizzleAdapter = (db, config) => {
75
75
  value: data[w.field]
76
76
  };
77
77
  return w;
78
- }), model);
79
- return (await db.select().from(schemaModel).where(...clause))[0];
78
+ }), model, modelKey);
79
+ return (await db.select().from(table).where(...clause))[0];
80
80
  }
81
81
  const fetchInserted = async (tx) => {
82
82
  const builderId = builderVal?.[0]?.id?.value;
83
- if (builderId) return (await tx.select().from(schemaModel).where(eq(schemaModel.id, builderId)).limit(1).execute())[0] ?? null;
84
- if (data.id) return (await tx.select().from(schemaModel).where(eq(schemaModel.id, data.id)).limit(1).execute())[0] ?? null;
85
- if (options.advanced?.database?.generateId === "serial" && schemaModel.id) {
86
- const lastId = (await tx.select({ id: sql`LAST_INSERT_ID()` }).from(schemaModel).limit(1).execute())[0]?.id;
87
- if (lastId) return (await tx.select().from(schemaModel).where(eq(schemaModel.id, lastId)).limit(1).execute())[0] ?? null;
83
+ if (builderId) return (await tx.select().from(table).where(eq(table.id, builderId)).limit(1).execute())[0] ?? null;
84
+ if (data.id) return (await tx.select().from(table).where(eq(table.id, data.id)).limit(1).execute())[0] ?? null;
85
+ if (options.advanced?.database?.generateId === "serial" && table.id) {
86
+ const lastId = (await tx.select({ id: sql`LAST_INSERT_ID()` }).from(table).limit(1).execute())[0]?.id;
87
+ if (lastId) return (await tx.select().from(table).where(eq(table.id, lastId)).limit(1).execute())[0] ?? null;
88
88
  }
89
- const modelSchema = baSchema[getDefaultModelName(model)]?.fields;
89
+ const modelSchema = baSchema[modelKey]?.fields;
90
90
  if (modelSchema) for (const [fieldKey, fieldAttr] of Object.entries(modelSchema)) {
91
91
  if (!fieldAttr.unique) continue;
92
92
  const dbFieldName = getFieldName({
93
- model,
93
+ model: modelKey,
94
94
  field: fieldKey
95
95
  });
96
96
  const val = data[dbFieldName];
97
97
  if (val === void 0 || val === null) continue;
98
- if (!schemaModel[dbFieldName]) continue;
99
- const res = await tx.select().from(schemaModel).where(eq(schemaModel[dbFieldName], val)).limit(1).execute();
98
+ if (!table[dbFieldName]) continue;
99
+ const res = await tx.select().from(table).where(eq(table[dbFieldName], val)).limit(1).execute();
100
100
  if (res[0]) return res[0];
101
101
  }
102
102
  const conditions = [];
103
103
  for (const [key, val] of Object.entries(data)) {
104
- if (val === void 0 || !schemaModel[key]) continue;
105
- conditions.push(val === null ? isNull(schemaModel[key]) : eq(schemaModel[key], val));
104
+ if (val === void 0 || !table[key]) continue;
105
+ conditions.push(val === null ? isNull(table[key]) : eq(table[key], val));
106
106
  }
107
107
  if (conditions.length > 0) {
108
108
  const combined = and(...conditions);
109
109
  if (combined) {
110
- const res = await tx.select().from(schemaModel).where(combined).limit(2).execute();
110
+ const res = await tx.select().from(table).where(combined).limit(2).execute();
111
111
  if (res.length === 1) return res[0];
112
112
  }
113
113
  }
@@ -116,11 +116,11 @@ const drizzleAdapter = (db, config) => {
116
116
  };
117
117
  return inTransaction ? fetchInserted(db) : db.transaction(fetchInserted);
118
118
  };
119
- function convertWhereClause(where, model) {
119
+ function convertWhereClause(where, model, modelKey) {
120
120
  const schemaModel = getSchema(model);
121
121
  const resolveFieldName = (where) => {
122
122
  const field = getFieldName({
123
- model,
123
+ model: modelKey,
124
124
  field: where.field
125
125
  });
126
126
  if (!is(schemaModel[field], Column)) throw new BetterAuthError(`The field "${where.field}" does not exist in the schema for the model "${model}". Please update your schema.`);
@@ -295,10 +295,12 @@ const drizzleAdapter = (db, config) => {
295
295
  }
296
296
  return null;
297
297
  }
298
- function getJoinRelationKey(baseModel, joinModel, relationKeys, isUnique) {
298
+ function getJoinRelationKey(baseModel, joinModel, baseModelKey, joinModelKey, relationKeys, isUnique) {
299
299
  if (isUnique) return getOneToOneRelationKey({
300
300
  baseModel,
301
301
  joinModel,
302
+ baseModelKey,
303
+ joinModelKey,
302
304
  relationKeys,
303
305
  schema: baSchema,
304
306
  getDefaultModelName
@@ -306,14 +308,14 @@ const drizzleAdapter = (db, config) => {
306
308
  return config.usePlural ? joinModel : `${joinModel}s`;
307
309
  }
308
310
  return {
309
- async create({ model, data: values }) {
310
- const schemaModel = getSchema(model);
311
- checkMissingFields(schemaModel, model, values);
312
- return await withReturning(model, db.insert(schemaModel).values(values), values);
311
+ async create({ model, modelKey = model, data: values }) {
312
+ const table = getSchema(model);
313
+ checkMissingFields(table, modelKey, values);
314
+ return await withReturning(model, modelKey, db.insert(table).values(values), values);
313
315
  },
314
- async findOne({ model, where, select, join }) {
315
- const schemaModel = getSchema(model);
316
- const clause = convertWhereClause(where, model);
316
+ async findOne({ model, modelKey = model, where, select, join }) {
317
+ const table = getSchema(model);
318
+ const clause = convertWhereClause(where, model, modelKey);
317
319
  if (join) {
318
320
  const queryModel = getQueryModel(model);
319
321
  if (!db.query || !queryModel) {
@@ -328,7 +330,7 @@ const drizzleAdapter = (db, config) => {
328
330
  for (const [joinModel, joinAttr] of joinEntries) {
329
331
  const limit = joinAttr.limit ?? options.advanced?.database?.defaultFindManyLimit ?? 100;
330
332
  const isUnique = joinAttr.relation === "one-to-one";
331
- const relationKey = getJoinRelationKey(model, joinModel, relationKeys, isUnique);
333
+ const relationKey = getJoinRelationKey(model, joinModel, modelKey, joinAttr.modelKey ?? joinModel, relationKeys, isUnique);
332
334
  includes[relationKey] = isUnique ? true : { limit };
333
335
  if (relationKey !== joinModel) renamedJoinResults.push({
334
336
  key: relationKey,
@@ -339,7 +341,7 @@ const drizzleAdapter = (db, config) => {
339
341
  where: clause[0],
340
342
  columns: select?.length && select.length > 0 ? select.reduce((acc, field) => {
341
343
  acc[getFieldName({
342
- model,
344
+ model: modelKey,
343
345
  field
344
346
  })] = true;
345
347
  return acc;
@@ -355,20 +357,20 @@ const drizzleAdapter = (db, config) => {
355
357
  }
356
358
  const res = await db.select(select?.length && select.length > 0 ? select.reduce((acc, field) => {
357
359
  const fieldName = getFieldName({
358
- model,
360
+ model: modelKey,
359
361
  field
360
362
  });
361
363
  return {
362
364
  ...acc,
363
- [fieldName]: schemaModel[fieldName]
365
+ [fieldName]: table[fieldName]
364
366
  };
365
- }, {}) : void 0).from(schemaModel).where(...clause);
367
+ }, {}) : void 0).from(table).where(...clause);
366
368
  if (!res.length) return null;
367
369
  return res[0];
368
370
  },
369
- async findMany({ model, where, sortBy, limit, select, offset, join }) {
370
- const schemaModel = getSchema(model);
371
- const clause = where ? convertWhereClause(where, model) : [];
371
+ async findMany({ model, modelKey = model, where, sortBy, limit, select, offset, join }) {
372
+ const table = getSchema(model);
373
+ const clause = where ? convertWhereClause(where, model, modelKey) : [];
372
374
  const sortFn = sortBy?.direction === "desc" ? desc : asc;
373
375
  if (join) {
374
376
  const queryModel = getQueryModel(model);
@@ -384,7 +386,7 @@ const drizzleAdapter = (db, config) => {
384
386
  for (const [joinModel, joinAttr] of joinEntries) {
385
387
  const isUnique = joinAttr.relation === "one-to-one";
386
388
  const limit = joinAttr.limit ?? options.advanced?.database?.defaultFindManyLimit ?? 100;
387
- const relationKey = getJoinRelationKey(model, joinModel, relationKeys, isUnique);
389
+ const relationKey = getJoinRelationKey(model, joinModel, modelKey, joinAttr.modelKey ?? joinModel, relationKeys, isUnique);
388
390
  includes[relationKey] = isUnique ? true : { limit };
389
391
  if (relationKey !== joinModel) renamedJoinResults.push({
390
392
  key: relationKey,
@@ -392,8 +394,8 @@ const drizzleAdapter = (db, config) => {
392
394
  });
393
395
  }
394
396
  let orderBy = void 0;
395
- if (sortBy?.field) orderBy = [sortFn(schemaModel[getFieldName({
396
- model,
397
+ if (sortBy?.field) orderBy = [sortFn(table[getFieldName({
398
+ model: modelKey,
397
399
  field: sortBy?.field
398
400
  })])];
399
401
  const res = await db.query[queryModel].findMany({
@@ -401,7 +403,7 @@ const drizzleAdapter = (db, config) => {
401
403
  with: includes,
402
404
  columns: select?.length && select.length > 0 ? select.reduce((acc, field) => {
403
405
  acc[getFieldName({
404
- model,
406
+ model: modelKey,
405
407
  field
406
408
  })] = true;
407
409
  return acc;
@@ -419,70 +421,70 @@ const drizzleAdapter = (db, config) => {
419
421
  }
420
422
  let builder = db.select(select?.length && select.length > 0 ? select.reduce((acc, field) => {
421
423
  const fieldName = getFieldName({
422
- model,
424
+ model: modelKey,
423
425
  field
424
426
  });
425
427
  return {
426
428
  ...acc,
427
- [fieldName]: schemaModel[fieldName]
429
+ [fieldName]: table[fieldName]
428
430
  };
429
- }, {}) : void 0).from(schemaModel);
431
+ }, {}) : void 0).from(table);
430
432
  const effectiveLimit = limit;
431
433
  const effectiveOffset = offset;
432
434
  if (typeof effectiveLimit !== "undefined") builder = builder.limit(effectiveLimit);
433
435
  if (typeof effectiveOffset !== "undefined") builder = builder.offset(effectiveOffset);
434
- if (sortBy?.field) builder = builder.orderBy(sortFn(schemaModel[getFieldName({
435
- model,
436
+ if (sortBy?.field) builder = builder.orderBy(sortFn(table[getFieldName({
437
+ model: modelKey,
436
438
  field: sortBy?.field
437
439
  })]));
438
440
  return await builder.where(...clause);
439
441
  },
440
- async count({ model, where }) {
441
- const schemaModel = getSchema(model);
442
- const clause = where ? convertWhereClause(where, model) : [];
443
- return (await db.select({ count: count() }).from(schemaModel).where(...clause))[0].count;
442
+ async count({ model, modelKey = model, where }) {
443
+ const table = getSchema(model);
444
+ const clause = where ? convertWhereClause(where, model, modelKey) : [];
445
+ return (await db.select({ count: count() }).from(table).where(...clause))[0].count;
444
446
  },
445
- async update({ model, where, update: values }) {
446
- const schemaModel = getSchema(model);
447
- const clause = convertWhereClause(where, model);
448
- return await withReturning(model, db.update(schemaModel).set(values).where(...clause), values, where);
447
+ async update({ model, modelKey = model, where, update: values }) {
448
+ const table = getSchema(model);
449
+ const clause = convertWhereClause(where, model, modelKey);
450
+ return await withReturning(model, modelKey, db.update(table).set(values).where(...clause), values, where);
449
451
  },
450
- async updateMany({ model, where, update: values }) {
451
- const schemaModel = getSchema(model);
452
- const clause = convertWhereClause(where, model);
453
- return getAffectedRowCount(await db.update(schemaModel).set(values).where(...clause), "updateMany", {
452
+ async updateMany({ model, modelKey = model, where, update: values }) {
453
+ const table = getSchema(model);
454
+ const clause = convertWhereClause(where, model, modelKey);
455
+ return getAffectedRowCount(await db.update(table).set(values).where(...clause), "updateMany", {
454
456
  model,
455
457
  where
456
458
  });
457
459
  },
458
- async delete({ model, where }) {
459
- const schemaModel = getSchema(model);
460
- const clause = convertWhereClause(where, model);
461
- return await db.delete(schemaModel).where(...clause);
460
+ async delete({ model, modelKey = model, where }) {
461
+ const table = getSchema(model);
462
+ const clause = convertWhereClause(where, model, modelKey);
463
+ return await db.delete(table).where(...clause);
462
464
  },
463
- async deleteMany({ model, where }) {
464
- const schemaModel = getSchema(model);
465
- const clause = convertWhereClause(where, model);
466
- return getAffectedRowCount(await db.delete(schemaModel).where(...clause), "deleteMany", {
465
+ async deleteMany({ model, modelKey = model, where }) {
466
+ const table = getSchema(model);
467
+ const clause = convertWhereClause(where, model, modelKey);
468
+ return getAffectedRowCount(await db.delete(table).where(...clause), "deleteMany", {
467
469
  model,
468
470
  where
469
471
  });
470
472
  },
471
- async consumeOne({ model, where }) {
472
- const schemaModel = getSchema(model);
473
- const clause = convertWhereClause(where, model);
473
+ async consumeOne({ model, modelKey = model, where }) {
474
+ const table = getSchema(model);
475
+ const clause = convertWhereClause(where, model, modelKey);
474
476
  const idField = getFieldName({
475
- model,
477
+ model: modelKey,
476
478
  field: "id"
477
479
  });
478
- const idColumn = schemaModel[idField];
480
+ const idColumn = table[idField];
479
481
  if (config.provider === "mysql") {
480
482
  const claimFromTransaction = async (tx) => {
481
- const target = (await tx.select().from(schemaModel).where(...clause).for("update").limit(1))[0];
483
+ const target = (await tx.select().from(table).where(...clause).for("update").limit(1))[0];
482
484
  if (!target) return null;
483
485
  const targetId = target[idField] ?? target.id;
484
486
  if (targetId === void 0 || targetId === null || !idColumn) return null;
485
- return getAffectedRowCount(await tx.delete(schemaModel).where(eq(idColumn, targetId)).execute(), "consumeOne", {
487
+ return getAffectedRowCount(await tx.delete(table).where(eq(idColumn, targetId)).execute(), "consumeOne", {
486
488
  model,
487
489
  where
488
490
  }) > 0 ? target : null;
@@ -490,49 +492,49 @@ const drizzleAdapter = (db, config) => {
490
492
  return inTransaction ? claimFromTransaction(db) : db.transaction(claimFromTransaction);
491
493
  }
492
494
  if (!idColumn) return null;
493
- const targetIds = db.select({ id: idColumn }).from(schemaModel).where(...clause).limit(1);
494
- return (await db.delete(schemaModel).where(inArray(idColumn, targetIds)).returning())[0] ?? null;
495
+ const targetIds = db.select({ id: idColumn }).from(table).where(...clause).limit(1);
496
+ return (await db.delete(table).where(inArray(idColumn, targetIds)).returning())[0] ?? null;
495
497
  },
496
- async incrementOne({ model, where, increment, set }) {
497
- const schemaModel = getSchema(model);
498
- const clause = convertWhereClause(where, model);
498
+ async incrementOne({ model, modelKey = model, where, increment, set }) {
499
+ const table = getSchema(model);
500
+ const clause = convertWhereClause(where, model, modelKey);
499
501
  const idField = getFieldName({
500
- model,
502
+ model: modelKey,
501
503
  field: "id"
502
504
  });
503
- const idColumn = schemaModel[idField];
505
+ const idColumn = table[idField];
504
506
  const assignments = {};
505
507
  for (const [field, delta] of Object.entries(increment)) {
506
508
  const columnName = getFieldName({
507
- model,
509
+ model: modelKey,
508
510
  field
509
511
  });
510
- const column = schemaModel[columnName];
512
+ const column = table[columnName];
511
513
  if (!column) throw new BetterAuthError(`The field "${field}" does not exist in the schema for the model "${model}". Please update your schema.`);
512
514
  assignments[columnName] = sql`${column} + ${sql.param(delta)}`;
513
515
  }
514
516
  if (set) for (const [field, value] of Object.entries(set)) {
515
517
  const columnName = getFieldName({
516
- model,
518
+ model: modelKey,
517
519
  field
518
520
  });
519
- if (!schemaModel[columnName]) throw new BetterAuthError(`The field "${field}" does not exist in the schema for the model "${model}". Please update your schema.`);
521
+ if (!table[columnName]) throw new BetterAuthError(`The field "${field}" does not exist in the schema for the model "${model}". Please update your schema.`);
520
522
  assignments[columnName] = value;
521
523
  }
522
524
  if (config.provider === "mysql") {
523
525
  const mutateInTransaction = async (tx) => {
524
- const target = (await tx.select().from(schemaModel).where(...clause).for("update").limit(1))[0];
526
+ const target = (await tx.select().from(table).where(...clause).for("update").limit(1))[0];
525
527
  if (!target) return null;
526
528
  const targetId = target[idField] ?? target.id;
527
529
  if (targetId === void 0 || targetId === null || !idColumn) return null;
528
- await tx.update(schemaModel).set(assignments).where(eq(idColumn, targetId)).execute();
529
- return (await tx.select().from(schemaModel).where(eq(idColumn, targetId)).limit(1).execute())[0] ?? null;
530
+ await tx.update(table).set(assignments).where(eq(idColumn, targetId)).execute();
531
+ return (await tx.select().from(table).where(eq(idColumn, targetId)).limit(1).execute())[0] ?? null;
530
532
  };
531
533
  return inTransaction ? mutateInTransaction(db) : db.transaction(mutateInTransaction);
532
534
  }
533
535
  if (!idColumn) return null;
534
- const targetIds = db.select({ id: idColumn }).from(schemaModel).where(...clause).limit(1);
535
- return (await db.update(schemaModel).set(assignments).where(inArray(idColumn, targetIds)).returning())[0] ?? null;
536
+ const targetIds = db.select({ id: idColumn }).from(table).where(...clause).limit(1);
537
+ return (await db.update(table).set(assignments).where(and(...clause, inArray(idColumn, targetIds))).returning())[0] ?? null;
536
538
  },
537
539
  options: config
538
540
  };
@@ -570,7 +572,7 @@ const drizzleAdapter = (db, config) => {
570
572
  return (options) => {
571
573
  lazyOptions = options;
572
574
  const instance = adapter(options);
573
- if (checksSchema(options)) registerSchemaCheck(instance, createSchemaCheck(async () => findDrizzleSchemaProblems(config.schema ?? db._?.fullSchema ?? {}, options, config.usePlural), "drizzle"));
575
+ registerSchemaCheck(instance, createSchemaCheck(() => findDrizzleSchemaProblems(config.schema ?? db._?.fullSchema ?? {}, options, config.usePlural), "drizzle"), { runtimeEnabled: checksSchema(options) });
574
576
  return instance;
575
577
  };
576
578
  };
@@ -1,4 +1,4 @@
1
- import { a as insensitiveInArray, c as buildRelationKeysByModel, l as getOneToOneRelationKey, n as escapedLike, o as insensitiveNe, r as insensitiveEq, s as insensitiveNotInArray, t as findDrizzleSchemaProblems } from "../schema-check-_Aj1MGau.mjs";
1
+ import { a as insensitiveInArray, c as buildRelationKeysByModel, l as getOneToOneRelationKey, n as escapedLike, o as insensitiveNe, r as insensitiveEq, s as insensitiveNotInArray, t as findDrizzleSchemaProblems } from "../schema-check-DFZjRat1.mjs";
2
2
  import { createAdapterFactory } from "@better-auth/core/db/adapter";
3
3
  import { checksSchema, createSchemaCheck, registerSchemaCheck } from "@better-auth/core/db/internal";
4
4
  import { logger } from "@better-auth/core/env";
@@ -110,10 +110,12 @@ const drizzleAdapter = (db, config) => {
110
110
  }
111
111
  return null;
112
112
  }
113
- function getJoinRelationKey(baseModel, joinModel, relationKeys, isUnique) {
113
+ function getJoinRelationKey(baseModel, joinModel, baseModelKey, joinModelKey, relationKeys, isUnique) {
114
114
  if (isUnique) return getOneToOneRelationKey({
115
115
  baseModel,
116
116
  joinModel,
117
+ baseModelKey,
118
+ joinModelKey,
117
119
  relationKeys,
118
120
  schema: baSchema,
119
121
  getDefaultModelName
@@ -121,7 +123,7 @@ const drizzleAdapter = (db, config) => {
121
123
  if (config.usePlural || joinModel.endsWith("s")) return joinModel;
122
124
  return `${joinModel}s`;
123
125
  }
124
- const withReturning = async (model, builder, data, where) => {
126
+ const withReturning = async (model, modelKey, builder, data, where) => {
125
127
  if (config.provider !== "mysql") return (await builder.returning())[0];
126
128
  const isSerialInsert = where === void 0 && options.advanced?.database?.generateId === "serial";
127
129
  const insertResult = isSerialInsert ? await builder.$returningId().execute() : await builder.execute();
@@ -134,7 +136,7 @@ const drizzleAdapter = (db, config) => {
134
136
  value: data[w.field]
135
137
  };
136
138
  return w;
137
- }), model);
139
+ }), model, modelKey);
138
140
  return (await db.select().from(schemaModel).where(...clause))[0];
139
141
  }
140
142
  const fetchInserted = async (tx) => {
@@ -143,11 +145,11 @@ const drizzleAdapter = (db, config) => {
143
145
  if (data.id) return (await tx.select().from(schemaModel).where(eq(schemaModel.id, data.id)).limit(1).execute())[0] ?? null;
144
146
  const insertId = isSerialInsert ? insertResult?.[0]?.id : void 0;
145
147
  if (insertId && schemaModel.id) return (await tx.select().from(schemaModel).where(eq(schemaModel.id, insertId)).limit(1).execute())[0] ?? null;
146
- const modelSchema = baSchema[getDefaultModelName(model)]?.fields;
148
+ const modelSchema = baSchema[modelKey]?.fields;
147
149
  if (modelSchema) for (const [fieldKey, fieldAttr] of Object.entries(modelSchema)) {
148
150
  if (!fieldAttr.unique) continue;
149
151
  const dbFieldName = getFieldName({
150
- model,
152
+ model: modelKey,
151
153
  field: fieldKey
152
154
  });
153
155
  const val = data[dbFieldName];
@@ -173,10 +175,10 @@ const drizzleAdapter = (db, config) => {
173
175
  };
174
176
  return inTransaction ? fetchInserted(db) : db.transaction(fetchInserted);
175
177
  };
176
- function resolveColumn(model, w) {
178
+ function resolveColumn(model, modelKey, w) {
177
179
  const schemaModel = getSchema(model);
178
180
  const field = getFieldName({
179
- model,
181
+ model: modelKey,
180
182
  field: w.field
181
183
  });
182
184
  if (!schemaModel[field]) throw new BetterAuthError(`The field "${w.field}" does not exist in the schema for the model "${model}". Please update your schema.`);
@@ -185,32 +187,32 @@ const drizzleAdapter = (db, config) => {
185
187
  field
186
188
  };
187
189
  }
188
- function convertWhereClause(where, model) {
190
+ function convertWhereClause(where, model, modelKey) {
189
191
  if (!where) return [];
190
192
  if (where.length === 1) {
191
193
  const w = where[0];
192
194
  if (!w) return [];
193
- const { column } = resolveColumn(model, w);
195
+ const { column } = resolveColumn(model, modelKey, w);
194
196
  return [applyWhereOperator(column, w, w.field, config.provider)];
195
197
  }
196
198
  const andGroup = where.filter((w) => w.connector === "AND" || !w.connector);
197
199
  const orGroup = where.filter((w) => w.connector === "OR");
198
200
  const combined = and(and(...andGroup.map((w) => {
199
- const { column } = resolveColumn(model, w);
201
+ const { column } = resolveColumn(model, modelKey, w);
200
202
  return applyWhereOperator(column, w, w.field, config.provider);
201
203
  })), or(...orGroup.map((w) => {
202
- const { column } = resolveColumn(model, w);
204
+ const { column } = resolveColumn(model, modelKey, w);
203
205
  return applyWhereOperator(column, w, w.field, config.provider);
204
206
  })));
205
207
  return combined ? [combined] : [];
206
208
  }
207
- function convertNewWhereClause(where, model) {
209
+ function convertNewWhereClause(where, model, modelKey) {
208
210
  const schemaModel = getSchema(model);
209
211
  if (!where || where.length === 0) return {};
210
212
  const rawCondition = (w, field) => ({ RAW: (table) => applyWhereOperator(table[field], w, w.field, config.provider) });
211
213
  const convertWhereToColumn = (w) => {
212
214
  const field = getFieldName({
213
- model,
215
+ model: modelKey,
214
216
  field: w.field
215
217
  });
216
218
  if (!schemaModel[field]) throw new BetterAuthError(`The field "${w.field}" does not exist in the schema for the model "${model}". Please update your schema.`);
@@ -278,14 +280,14 @@ const drizzleAdapter = (db, config) => {
278
280
  for (const key in values) if (!schema[key]) throw new BetterAuthError(`The field "${key}" does not exist in the "${model}" Drizzle schema. Please update your drizzle schema or re-generate using "npx auth@latest generate".`);
279
281
  }
280
282
  return {
281
- async create({ model, data: values }) {
282
- const schemaModel = getSchema(model);
283
- checkMissingFields(schemaModel, model, values);
284
- return await withReturning(model, db.insert(schemaModel).values(values), values);
283
+ async create({ model, modelKey = model, data: values }) {
284
+ const table = getSchema(model);
285
+ checkMissingFields(table, modelKey, values);
286
+ return await withReturning(model, modelKey, db.insert(table).values(values), values);
285
287
  },
286
- async findOne({ model, where, select, join }) {
287
- const schemaModel = getSchema(model);
288
- const clause = convertWhereClause(where, model);
288
+ async findOne({ model, modelKey = model, where, select, join }) {
289
+ const table = getSchema(model);
290
+ const clause = convertWhereClause(where, model, modelKey);
289
291
  if (join) {
290
292
  const queryModel = getQueryModel(model);
291
293
  if (!db.query || !queryModel) {
@@ -300,19 +302,19 @@ const drizzleAdapter = (db, config) => {
300
302
  for (const [joinModel, joinAttr] of joinEntries) {
301
303
  const limit = joinAttr.limit ?? options.advanced?.database?.defaultFindManyLimit ?? 100;
302
304
  const isUnique = joinAttr.relation === "one-to-one";
303
- const relationKey = getJoinRelationKey(model, joinModel, relationKeys, isUnique);
305
+ const relationKey = getJoinRelationKey(model, joinModel, modelKey, joinAttr.modelKey ?? joinModel, relationKeys, isUnique);
304
306
  includes[relationKey] = isUnique ? true : { limit };
305
307
  if (relationKey !== joinModel) renamedJoinResults.push({
306
308
  key: relationKey,
307
309
  target: joinModel
308
310
  });
309
311
  }
310
- const clause = convertNewWhereClause(where, model);
312
+ const clause = convertNewWhereClause(where, model, modelKey);
311
313
  const res = await db.query[queryModel].findFirst({
312
314
  where: clause,
313
315
  columns: select?.length && select.length > 0 ? select.reduce((acc, field) => {
314
316
  acc[getFieldName({
315
- model,
317
+ model: modelKey,
316
318
  field
317
319
  })] = true;
318
320
  return acc;
@@ -328,20 +330,20 @@ const drizzleAdapter = (db, config) => {
328
330
  }
329
331
  const res = await db.select(select?.length && select.length > 0 ? select.reduce((acc, field) => {
330
332
  const fieldName = getFieldName({
331
- model,
333
+ model: modelKey,
332
334
  field
333
335
  });
334
336
  return {
335
337
  ...acc,
336
- [fieldName]: schemaModel[fieldName]
338
+ [fieldName]: table[fieldName]
337
339
  };
338
- }, {}) : void 0).from(schemaModel).where(...clause);
340
+ }, {}) : void 0).from(table).where(...clause);
339
341
  if (!res.length) return null;
340
342
  return res[0];
341
343
  },
342
- async findMany({ model, where, sortBy, limit, select, offset, join }) {
343
- const schemaModel = getSchema(model);
344
- const clause = where ? convertWhereClause(where, model) : [];
344
+ async findMany({ model, modelKey = model, where, sortBy, limit, select, offset, join }) {
345
+ const table = getSchema(model);
346
+ const clause = where ? convertWhereClause(where, model, modelKey) : [];
345
347
  const sortFn = sortBy?.direction === "desc" ? desc : asc;
346
348
  if (join) {
347
349
  const queryModel = getQueryModel(model);
@@ -357,7 +359,7 @@ const drizzleAdapter = (db, config) => {
357
359
  for (const [joinModel, joinAttr] of joinEntries) {
358
360
  const isUnique = joinAttr.relation === "one-to-one";
359
361
  const limit = joinAttr.limit ?? options.advanced?.database?.defaultFindManyLimit ?? 100;
360
- const relationKey = getJoinRelationKey(model, joinModel, relationKeys, isUnique);
362
+ const relationKey = getJoinRelationKey(model, joinModel, modelKey, joinAttr.modelKey ?? joinModel, relationKeys, isUnique);
361
363
  includes[relationKey] = isUnique ? true : { limit };
362
364
  if (relationKey !== joinModel) renamedJoinResults.push({
363
365
  key: relationKey,
@@ -366,15 +368,15 @@ const drizzleAdapter = (db, config) => {
366
368
  }
367
369
  let orderBy = void 0;
368
370
  if (sortBy?.field) orderBy = { [getFieldName({
369
- model,
371
+ model: modelKey,
370
372
  field: sortBy.field
371
373
  })]: sortBy.direction === "desc" ? "desc" : "asc" };
372
374
  const res = await db.query[queryModel].findMany({
373
- where: where ? convertNewWhereClause(where, model) : void 0,
375
+ where: where ? convertNewWhereClause(where, model, modelKey) : void 0,
374
376
  with: includes,
375
377
  columns: select?.length && select.length > 0 ? select.reduce((acc, field) => {
376
378
  acc[getFieldName({
377
- model,
379
+ model: modelKey,
378
380
  field
379
381
  })] = true;
380
382
  return acc;
@@ -392,70 +394,70 @@ const drizzleAdapter = (db, config) => {
392
394
  }
393
395
  let builder = db.select(select?.length && select.length > 0 ? select.reduce((acc, field) => {
394
396
  const fieldName = getFieldName({
395
- model,
397
+ model: modelKey,
396
398
  field
397
399
  });
398
400
  return {
399
401
  ...acc,
400
- [fieldName]: schemaModel[fieldName]
402
+ [fieldName]: table[fieldName]
401
403
  };
402
- }, {}) : void 0).from(schemaModel);
404
+ }, {}) : void 0).from(table);
403
405
  const effectiveLimit = limit;
404
406
  const effectiveOffset = offset;
405
407
  if (typeof effectiveLimit !== "undefined") builder = builder.limit(effectiveLimit);
406
408
  if (typeof effectiveOffset !== "undefined") builder = builder.offset(effectiveOffset);
407
- if (sortBy?.field) builder = builder.orderBy(sortFn(schemaModel[getFieldName({
408
- model,
409
+ if (sortBy?.field) builder = builder.orderBy(sortFn(table[getFieldName({
410
+ model: modelKey,
409
411
  field: sortBy?.field
410
412
  })]));
411
413
  return await builder.where(...clause);
412
414
  },
413
- async count({ model, where }) {
414
- const schemaModel = getSchema(model);
415
- const clause = where ? convertWhereClause(where, model) : [];
416
- return (await db.select({ count: count() }).from(schemaModel).where(...clause))[0].count;
415
+ async count({ model, modelKey = model, where }) {
416
+ const table = getSchema(model);
417
+ const clause = where ? convertWhereClause(where, model, modelKey) : [];
418
+ return (await db.select({ count: count() }).from(table).where(...clause))[0].count;
417
419
  },
418
- async update({ model, where, update: values }) {
419
- const schemaModel = getSchema(model);
420
- const clause = convertWhereClause(where, model);
421
- return await withReturning(model, db.update(schemaModel).set(values).where(...clause), values, where);
420
+ async update({ model, modelKey = model, where, update: values }) {
421
+ const table = getSchema(model);
422
+ const clause = convertWhereClause(where, model, modelKey);
423
+ return await withReturning(model, modelKey, db.update(table).set(values).where(...clause), values, where);
422
424
  },
423
- async updateMany({ model, where, update: values }) {
424
- const schemaModel = getSchema(model);
425
- const clause = convertWhereClause(where, model);
426
- return getAffectedRowCount(await db.update(schemaModel).set(values).where(...clause), "updateMany", {
425
+ async updateMany({ model, modelKey = model, where, update: values }) {
426
+ const table = getSchema(model);
427
+ const clause = convertWhereClause(where, model, modelKey);
428
+ return getAffectedRowCount(await db.update(table).set(values).where(...clause), "updateMany", {
427
429
  model,
428
430
  where
429
431
  });
430
432
  },
431
- async delete({ model, where }) {
432
- const schemaModel = getSchema(model);
433
- const clause = convertWhereClause(where, model);
434
- return await db.delete(schemaModel).where(...clause);
433
+ async delete({ model, modelKey = model, where }) {
434
+ const table = getSchema(model);
435
+ const clause = convertWhereClause(where, model, modelKey);
436
+ return await db.delete(table).where(...clause);
435
437
  },
436
- async deleteMany({ model, where }) {
437
- const schemaModel = getSchema(model);
438
- const clause = convertWhereClause(where, model);
439
- return getAffectedRowCount(await db.delete(schemaModel).where(...clause), "deleteMany", {
438
+ async deleteMany({ model, modelKey = model, where }) {
439
+ const table = getSchema(model);
440
+ const clause = convertWhereClause(where, model, modelKey);
441
+ return getAffectedRowCount(await db.delete(table).where(...clause), "deleteMany", {
440
442
  model,
441
443
  where
442
444
  });
443
445
  },
444
- async consumeOne({ model, where }) {
445
- const schemaModel = getSchema(model);
446
- const clause = convertWhereClause(where, model);
446
+ async consumeOne({ model, modelKey = model, where }) {
447
+ const table = getSchema(model);
448
+ const clause = convertWhereClause(where, model, modelKey);
447
449
  const idField = getFieldName({
448
- model,
450
+ model: modelKey,
449
451
  field: "id"
450
452
  });
451
- const idColumn = schemaModel[idField];
453
+ const idColumn = table[idField];
452
454
  if (config.provider === "mysql") {
453
455
  const claimFromTransaction = async (tx) => {
454
- const target = (await tx.select().from(schemaModel).where(...clause).for("update").limit(1))[0];
456
+ const target = (await tx.select().from(table).where(...clause).for("update").limit(1))[0];
455
457
  if (!target) return null;
456
458
  const targetId = target[idField] ?? target.id;
457
459
  if (targetId === void 0 || targetId === null || !idColumn) return null;
458
- return getAffectedRowCount(await tx.delete(schemaModel).where(eq(idColumn, targetId)).execute(), "consumeOne", {
460
+ return getAffectedRowCount(await tx.delete(table).where(eq(idColumn, targetId)).execute(), "consumeOne", {
459
461
  model,
460
462
  where
461
463
  }) > 0 ? target : null;
@@ -463,49 +465,49 @@ const drizzleAdapter = (db, config) => {
463
465
  return inTransaction ? claimFromTransaction(db) : db.transaction(claimFromTransaction);
464
466
  }
465
467
  if (!idColumn) return null;
466
- const targetIds = db.select({ id: idColumn }).from(schemaModel).where(...clause).limit(1);
467
- return (await db.delete(schemaModel).where(inArray(idColumn, targetIds)).returning())[0] ?? null;
468
+ const targetIds = db.select({ id: idColumn }).from(table).where(...clause).limit(1);
469
+ return (await db.delete(table).where(inArray(idColumn, targetIds)).returning())[0] ?? null;
468
470
  },
469
- async incrementOne({ model, where, increment, set }) {
470
- const schemaModel = getSchema(model);
471
- const clause = convertWhereClause(where, model);
471
+ async incrementOne({ model, modelKey = model, where, increment, set }) {
472
+ const table = getSchema(model);
473
+ const clause = convertWhereClause(where, model, modelKey);
472
474
  const idField = getFieldName({
473
- model,
475
+ model: modelKey,
474
476
  field: "id"
475
477
  });
476
- const idColumn = schemaModel[idField];
478
+ const idColumn = table[idField];
477
479
  const assignments = {};
478
480
  for (const [field, delta] of Object.entries(increment)) {
479
481
  const columnName = getFieldName({
480
- model,
482
+ model: modelKey,
481
483
  field
482
484
  });
483
- const column = schemaModel[columnName];
485
+ const column = table[columnName];
484
486
  if (!column) throw new BetterAuthError(`The field "${field}" does not exist in the schema for the model "${model}". Please update your schema.`);
485
487
  assignments[columnName] = sql`${column} + ${sql.param(delta)}`;
486
488
  }
487
489
  if (set) for (const [field, value] of Object.entries(set)) {
488
490
  const columnName = getFieldName({
489
- model,
491
+ model: modelKey,
490
492
  field
491
493
  });
492
- if (!schemaModel[columnName]) throw new BetterAuthError(`The field "${field}" does not exist in the schema for the model "${model}". Please update your schema.`);
494
+ if (!table[columnName]) throw new BetterAuthError(`The field "${field}" does not exist in the schema for the model "${model}". Please update your schema.`);
493
495
  assignments[columnName] = value;
494
496
  }
495
497
  if (config.provider === "mysql") {
496
498
  const mutateInTransaction = async (tx) => {
497
- const target = (await tx.select().from(schemaModel).where(...clause).for("update").limit(1))[0];
499
+ const target = (await tx.select().from(table).where(...clause).for("update").limit(1))[0];
498
500
  if (!target) return null;
499
501
  const targetId = target[idField] ?? target.id;
500
502
  if (targetId === void 0 || targetId === null || !idColumn) return null;
501
- await tx.update(schemaModel).set(assignments).where(eq(idColumn, targetId)).execute();
502
- return (await tx.select().from(schemaModel).where(eq(idColumn, targetId)).limit(1).execute())[0] ?? null;
503
+ await tx.update(table).set(assignments).where(eq(idColumn, targetId)).execute();
504
+ return (await tx.select().from(table).where(eq(idColumn, targetId)).limit(1).execute())[0] ?? null;
503
505
  };
504
506
  return inTransaction ? mutateInTransaction(db) : db.transaction(mutateInTransaction);
505
507
  }
506
508
  if (!idColumn) return null;
507
- const targetIds = db.select({ id: idColumn }).from(schemaModel).where(...clause).limit(1);
508
- return (await db.update(schemaModel).set(assignments).where(inArray(idColumn, targetIds)).returning())[0] ?? null;
509
+ const targetIds = db.select({ id: idColumn }).from(table).where(...clause).limit(1);
510
+ return (await db.update(table).set(assignments).where(and(...clause, inArray(idColumn, targetIds))).returning())[0] ?? null;
509
511
  },
510
512
  async createSchema(props) {
511
513
  const { generateDrizzleSchema } = await import("../generate-drizzle-schema-iWvrXnu0.mjs");
@@ -547,14 +549,14 @@ const drizzleAdapter = (db, config) => {
547
549
  return (options) => {
548
550
  lazyOptions = options;
549
551
  const instance = adapter(options);
550
- if (checksSchema(options)) registerSchemaCheck(instance, createSchemaCheck(async () => {
552
+ registerSchemaCheck(instance, createSchemaCheck(() => {
551
553
  const relations = db._?.relations ?? {};
552
554
  return findDrizzleSchemaProblems({
553
555
  ...db._?.fullSchema,
554
556
  ...Object.fromEntries(Object.entries(relations).map(([name, relation]) => [name, relation.table])),
555
557
  ...config.schema
556
558
  }, options, config.usePlural);
557
- }, "drizzle"));
559
+ }, "drizzle"), { runtimeEnabled: checksSchema(options) });
558
560
  return instance;
559
561
  };
560
562
  };
@@ -15,9 +15,9 @@ function buildRelationKeysByModel(relationRegistry) {
15
15
  }
16
16
  return relationKeysByModel;
17
17
  }
18
- function getOneToOneRelationKey({ baseModel, joinModel, relationKeys, schema, getDefaultModelName }) {
19
- const defaultBaseModelName = getDefaultModelName(baseModel);
20
- const defaultJoinModelName = getDefaultModelName(joinModel);
18
+ function getOneToOneRelationKey({ baseModel, joinModel, baseModelKey, joinModelKey, relationKeys, schema, getDefaultModelName }) {
19
+ const defaultBaseModelName = baseModelKey ?? getDefaultModelName(baseModel);
20
+ const defaultJoinModelName = joinModelKey ?? getDefaultModelName(joinModel);
21
21
  const joinModelFields = schema[defaultJoinModelName]?.fields ?? {};
22
22
  const generatedRelationKey = Object.values(joinModelFields).some((field) => field.references && getDefaultModelName(field.references.model) === defaultBaseModelName) ? joinModel : schema[defaultJoinModelName]?.modelName ?? defaultJoinModelName;
23
23
  if (!relationKeys?.size) return joinModel;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@better-auth/drizzle-adapter",
3
- "version": "1.7.5",
3
+ "version": "1.7.7",
4
4
  "bugs": {
5
5
  "url": "https://github.com/better-auth/better-auth/issues"
6
6
  },
@@ -45,7 +45,7 @@
45
45
  "peerDependencies": {
46
46
  "@better-auth/utils": "0.4.2",
47
47
  "drizzle-orm": "^0.45.2 || >=1.0.0-rc.1 <2.0.0",
48
- "@better-auth/core": "^1.7.5"
48
+ "@better-auth/core": "^1.7.7"
49
49
  },
50
50
  "peerDependenciesMeta": {
51
51
  "drizzle-orm": {
@@ -57,7 +57,7 @@
57
57
  "drizzle-orm": "^0.45.2",
58
58
  "tsdown": "0.21.10",
59
59
  "typescript": "^6.0.3",
60
- "@better-auth/core": "1.7.5"
60
+ "@better-auth/core": "1.7.7"
61
61
  },
62
62
  "scripts": {
63
63
  "build": "tsdown",