@better-auth/drizzle-adapter 1.6.10 → 1.6.12
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 +75 -15
- package/package.json +5 -5
package/dist/index.mjs
CHANGED
|
@@ -40,7 +40,12 @@ function insensitiveNe(column, value) {
|
|
|
40
40
|
//#region src/drizzle-adapter.ts
|
|
41
41
|
const drizzleAdapter = (db, config) => {
|
|
42
42
|
let lazyOptions = null;
|
|
43
|
-
|
|
43
|
+
let mysqlNoIdWarned = false;
|
|
44
|
+
const createCustomAdapter = (db, inTransaction = false) => ({ getFieldName, getDefaultFieldName, getDefaultModelName, options, schema: baSchema }) => {
|
|
45
|
+
if (config.provider === "mysql" && options.advanced?.database?.generateId === false && !mysqlNoIdWarned) {
|
|
46
|
+
mysqlNoIdWarned = true;
|
|
47
|
+
logger.warn("[Drizzle Adapter] MySQL does not support INSERT...RETURNING. With generateId set to false, the adapter uses best-effort fallback strategies (unique columns, full-field match) to retrieve inserted rows. For reliable behavior, use Better Auth's default ID generation, a custom generateId function, or generateId: \"serial\" for auto-increment.");
|
|
48
|
+
}
|
|
44
49
|
function getSchema(model) {
|
|
45
50
|
const schema = config.schema || db._.fullSchema;
|
|
46
51
|
if (!schema) throw new BetterAuthError("Drizzle adapter failed to initialize. Schema not found. Please provide a schema object in the adapter options object.");
|
|
@@ -62,15 +67,44 @@ const drizzleAdapter = (db, config) => {
|
|
|
62
67
|
return w;
|
|
63
68
|
}), model);
|
|
64
69
|
return (await db.select().from(schemaModel).where(...clause))[0];
|
|
65
|
-
} else if (builderVal && builderVal[0]?.id?.value) {
|
|
66
|
-
let tId = builderVal[0]?.id?.value;
|
|
67
|
-
if (!tId) tId = (await db.select({ id: sql`LAST_INSERT_ID()` }).from(schemaModel).orderBy(desc(schemaModel.id)).limit(1))[0].id;
|
|
68
|
-
return (await db.select().from(schemaModel).where(eq(schemaModel.id, tId)).limit(1).execute())[0];
|
|
69
|
-
} else if (data.id) return (await db.select().from(schemaModel).where(eq(schemaModel.id, data.id)).limit(1).execute())[0];
|
|
70
|
-
else {
|
|
71
|
-
if (!("id" in schemaModel)) throw new BetterAuthError(`The model "${model}" does not have an "id" field. Please use the "id" field as your primary key.`);
|
|
72
|
-
return (await db.select().from(schemaModel).orderBy(desc(schemaModel.id)).limit(1).execute())[0];
|
|
73
70
|
}
|
|
71
|
+
const fetchInserted = async (tx) => {
|
|
72
|
+
const builderId = builderVal?.[0]?.id?.value;
|
|
73
|
+
if (builderId) return (await tx.select().from(schemaModel).where(eq(schemaModel.id, builderId)).limit(1).execute())[0] ?? null;
|
|
74
|
+
if (data.id) return (await tx.select().from(schemaModel).where(eq(schemaModel.id, data.id)).limit(1).execute())[0] ?? null;
|
|
75
|
+
if (options.advanced?.database?.generateId === "serial" && schemaModel.id) {
|
|
76
|
+
const lastId = (await tx.select({ id: sql`LAST_INSERT_ID()` }).from(schemaModel).limit(1).execute())[0]?.id;
|
|
77
|
+
if (lastId) return (await tx.select().from(schemaModel).where(eq(schemaModel.id, lastId)).limit(1).execute())[0] ?? null;
|
|
78
|
+
}
|
|
79
|
+
const modelSchema = baSchema[getDefaultModelName(model)]?.fields;
|
|
80
|
+
if (modelSchema) for (const [fieldKey, fieldAttr] of Object.entries(modelSchema)) {
|
|
81
|
+
if (!fieldAttr.unique) continue;
|
|
82
|
+
const dbFieldName = getFieldName({
|
|
83
|
+
model,
|
|
84
|
+
field: fieldKey
|
|
85
|
+
});
|
|
86
|
+
const val = data[dbFieldName];
|
|
87
|
+
if (val === void 0 || val === null) continue;
|
|
88
|
+
if (!schemaModel[dbFieldName]) continue;
|
|
89
|
+
const res = await tx.select().from(schemaModel).where(eq(schemaModel[dbFieldName], val)).limit(1).execute();
|
|
90
|
+
if (res[0]) return res[0];
|
|
91
|
+
}
|
|
92
|
+
const conditions = [];
|
|
93
|
+
for (const [key, val] of Object.entries(data)) {
|
|
94
|
+
if (val === void 0 || !schemaModel[key]) continue;
|
|
95
|
+
conditions.push(val === null ? isNull(schemaModel[key]) : eq(schemaModel[key], val));
|
|
96
|
+
}
|
|
97
|
+
if (conditions.length > 0) {
|
|
98
|
+
const combined = and(...conditions);
|
|
99
|
+
if (combined) {
|
|
100
|
+
const res = await tx.select().from(schemaModel).where(combined).limit(2).execute();
|
|
101
|
+
if (res.length === 1) return res[0];
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
logger.warn(`[Drizzle Adapter] Unable to safely identify the inserted "${model}" row on MySQL. Enable Better Auth ID generation or use generateId: "serial" for reliable behavior.`);
|
|
105
|
+
return null;
|
|
106
|
+
};
|
|
107
|
+
return inTransaction ? fetchInserted(db) : db.transaction(fetchInserted);
|
|
74
108
|
};
|
|
75
109
|
function convertWhereClause(where, model) {
|
|
76
110
|
const schemaModel = getSchema(model);
|
|
@@ -204,10 +238,10 @@ const drizzleAdapter = (db, config) => {
|
|
|
204
238
|
if (isInsensitive && typeof w.value === "string") return insensitiveEq(schemaModel[field], w.value);
|
|
205
239
|
return eq(schemaModel[field], w.value);
|
|
206
240
|
}));
|
|
207
|
-
|
|
208
|
-
if (andGroup.length)
|
|
209
|
-
if (orGroup.length)
|
|
210
|
-
return
|
|
241
|
+
if (andGroup.length && orGroup.length) return [and(andClause, orClause)];
|
|
242
|
+
if (andGroup.length) return [andClause];
|
|
243
|
+
if (orGroup.length) return [orClause];
|
|
244
|
+
return [];
|
|
211
245
|
}
|
|
212
246
|
function checkMissingFields(schema, model, values) {
|
|
213
247
|
if (!schema) throw new BetterAuthError("Drizzle adapter failed to initialize. Drizzle Schema not found. Please provide a schema object in the adapter options object.");
|
|
@@ -419,6 +453,29 @@ const drizzleAdapter = (db, config) => {
|
|
|
419
453
|
});
|
|
420
454
|
return count;
|
|
421
455
|
},
|
|
456
|
+
async consumeOne({ model, where }) {
|
|
457
|
+
const schemaModel = getSchema(model);
|
|
458
|
+
const clause = convertWhereClause(where, model);
|
|
459
|
+
const idField = getFieldName({
|
|
460
|
+
model,
|
|
461
|
+
field: "id"
|
|
462
|
+
});
|
|
463
|
+
const idColumn = schemaModel[idField];
|
|
464
|
+
if (config.provider === "mysql") {
|
|
465
|
+
const claimFromTransaction = async (tx) => {
|
|
466
|
+
const target = (await tx.select().from(schemaModel).where(...clause).for("update").limit(1))[0];
|
|
467
|
+
if (!target) return null;
|
|
468
|
+
const targetId = target[idField] ?? target.id;
|
|
469
|
+
if (targetId === void 0 || targetId === null || !idColumn) return null;
|
|
470
|
+
const delRes = await tx.delete(schemaModel).where(eq(idColumn, targetId)).execute();
|
|
471
|
+
return ((delRes && (delRes.rowsAffected ?? delRes.affectedRows ?? delRes.changes)) ?? 0) > 0 ? target : null;
|
|
472
|
+
};
|
|
473
|
+
return inTransaction ? claimFromTransaction(db) : db.transaction(claimFromTransaction);
|
|
474
|
+
}
|
|
475
|
+
if (!idColumn) return null;
|
|
476
|
+
const targetIds = db.select({ id: idColumn }).from(schemaModel).where(...clause).limit(1);
|
|
477
|
+
return (await db.delete(schemaModel).where(inArray(idColumn, targetIds)).returning())[0] ?? null;
|
|
478
|
+
},
|
|
422
479
|
options: config
|
|
423
480
|
};
|
|
424
481
|
};
|
|
@@ -441,8 +498,11 @@ const drizzleAdapter = (db, config) => {
|
|
|
441
498
|
},
|
|
442
499
|
transaction: config.transaction ?? false ? (cb) => db.transaction((tx) => {
|
|
443
500
|
return cb(createAdapterFactory({
|
|
444
|
-
config:
|
|
445
|
-
|
|
501
|
+
config: {
|
|
502
|
+
...adapterOptions.config,
|
|
503
|
+
transaction: false
|
|
504
|
+
},
|
|
505
|
+
adapter: createCustomAdapter(tx, true)
|
|
446
506
|
})(lazyOptions));
|
|
447
507
|
}) : false
|
|
448
508
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@better-auth/drizzle-adapter",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.12",
|
|
4
4
|
"description": "Drizzle adapter for Better Auth",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -35,9 +35,9 @@
|
|
|
35
35
|
}
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
|
-
"@better-auth/utils": "0.4.
|
|
38
|
+
"@better-auth/utils": "0.4.1",
|
|
39
39
|
"drizzle-orm": "^0.45.2",
|
|
40
|
-
"@better-auth/core": "^1.6.
|
|
40
|
+
"@better-auth/core": "^1.6.12"
|
|
41
41
|
},
|
|
42
42
|
"peerDependenciesMeta": {
|
|
43
43
|
"drizzle-orm": {
|
|
@@ -45,11 +45,11 @@
|
|
|
45
45
|
}
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@better-auth/utils": "0.4.
|
|
48
|
+
"@better-auth/utils": "0.4.1",
|
|
49
49
|
"drizzle-orm": "^0.45.2",
|
|
50
50
|
"tsdown": "0.21.1",
|
|
51
51
|
"typescript": "^5.9.3",
|
|
52
|
-
"@better-auth/core": "1.6.
|
|
52
|
+
"@better-auth/core": "1.6.12"
|
|
53
53
|
},
|
|
54
54
|
"scripts": {
|
|
55
55
|
"build": "tsdown",
|