Created
April 21, 2023 09:22
-
-
Save Andersgee/1439dd648eb1ff60855275fef78cb8e5 to your computer and use it in GitHub Desktop.
KyselyAdapter
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import type { Kysely } from "kysely"; | |
import type { Adapter } from "next-auth/adapters"; | |
import type { DB } from "kysely-codegen"; | |
/** | |
* mostly copy pasted from the unmerged kysely adapter PR to next-auth repo | |
* | |
* assumes Account, User and Session ids are Int (not String). | |
* | |
* converts to/from string only because Adapter expects it that way. | |
*/ | |
export function KyselyAdapter(db: Kysely<DB>): Adapter { | |
const adapter = db.getExecutor().adapter; | |
const supportsReturning = adapter.supportsReturning; | |
return { | |
async createUser(user) { | |
const query = db.insertInto("User").values(user); | |
const result = supportsReturning | |
? await query.returningAll().executeTakeFirstOrThrow() | |
: await query.executeTakeFirstOrThrow().then(async () => { | |
return await db | |
.selectFrom("User") | |
.selectAll() | |
.where("email", "=", `${user.email}`) | |
.executeTakeFirstOrThrow(); | |
}); | |
return { ...result, id: String(result.id) }; | |
}, | |
async getUser(id) { | |
const intId = parseInt(id, 10); | |
const result = | |
(await db | |
.selectFrom("User") | |
.selectAll() | |
.where("id", "=", intId) | |
.executeTakeFirst()) ?? null; | |
if (!result) return null; | |
return { ...result, id: String(result.id) }; | |
}, | |
async getUserByEmail(email) { | |
const result = | |
(await db | |
.selectFrom("User") | |
.selectAll() | |
.where("email", "=", email) | |
.executeTakeFirst()) ?? null; | |
if (!result) return null; | |
return { ...result, id: String(result.id) }; | |
}, | |
async getUserByAccount({ providerAccountId, provider }) { | |
const result = | |
(await db | |
.selectFrom("User") | |
.innerJoin("Account", "User.id", "Account.userId") | |
.selectAll("User") | |
.where("Account.providerAccountId", "=", providerAccountId) | |
.where("Account.provider", "=", provider) | |
.executeTakeFirst()) ?? null; | |
if (!result) return null; | |
return { ...result, id: String(result.id) }; | |
}, | |
async updateUser({ id, ...user }) { | |
if (!id) throw new Error("User not found"); | |
const intId = parseInt(id, 10); | |
const query = db.updateTable("User").set(user).where("id", "=", intId); | |
const result = supportsReturning | |
? await query.returningAll().executeTakeFirstOrThrow() | |
: await query.executeTakeFirstOrThrow().then(async () => { | |
return await db | |
.selectFrom("User") | |
.selectAll() | |
.where("id", "=", intId) | |
.executeTakeFirstOrThrow(); | |
}); | |
return { ...result, id: String(result.id) }; | |
}, | |
async deleteUser(id) { | |
const intId = parseInt(id, 10); | |
await db.deleteFrom("User").where("User.id", "=", intId).execute(); | |
}, | |
async linkAccount(account) { | |
const acc = { ...account, userId: Number(account.userId) }; | |
await db.insertInto("Account").values(acc).executeTakeFirstOrThrow(); | |
}, | |
async unlinkAccount({ providerAccountId, provider }) { | |
await db | |
.deleteFrom("Account") | |
.where("Account.providerAccountId", "=", providerAccountId) | |
.where("Account.provider", "=", provider) | |
.executeTakeFirstOrThrow(); | |
}, | |
async createSession(session) { | |
const sess = { ...session, userId: Number(session.userId) }; | |
const query = db.insertInto("Session").values(sess); | |
const result = supportsReturning | |
? await query.returningAll().executeTakeFirstOrThrow() | |
: await (async () => { | |
await query.executeTakeFirstOrThrow(); | |
return await db | |
.selectFrom("Session") | |
.selectAll() | |
.where("sessionToken", "=", sess.sessionToken) | |
.executeTakeFirstOrThrow(); | |
})(); | |
return { | |
...result, | |
id: String(result.id), | |
userId: String(result.userId), | |
}; | |
}, | |
async getSessionAndUser(sessionTokenString) { | |
const result = await db | |
.selectFrom("Session") | |
.innerJoin("User", "User.id", "Session.userId") | |
.selectAll("User") | |
.select([ | |
"Session.id as sessionId", | |
"Session.userId", | |
"Session.sessionToken", | |
"Session.expires", | |
]) | |
.where("Session.sessionToken", "=", sessionTokenString) | |
.executeTakeFirst(); | |
if (!result) return null; | |
const { sessionId, userId, sessionToken, expires, ...user } = result; | |
return { | |
user: { ...user, id: String(userId) }, | |
session: { | |
id: String(sessionId), | |
userId: String(userId), | |
sessionToken, | |
expires, | |
}, | |
}; | |
}, | |
async updateSession(session) { | |
const sess = { ...session, userId: Number(session.userId) }; | |
const query = db | |
.updateTable("Session") | |
.set(sess) | |
.where("Session.sessionToken", "=", session.sessionToken); | |
const result = supportsReturning | |
? await query.returningAll().executeTakeFirstOrThrow() | |
: await query.executeTakeFirstOrThrow().then(async () => { | |
return await db | |
.selectFrom("Session") | |
.selectAll() | |
.where("Session.sessionToken", "=", sess.sessionToken) | |
.executeTakeFirstOrThrow(); | |
}); | |
return { | |
...result, | |
id: String(result.id), | |
userId: String(result.userId), | |
}; | |
}, | |
async deleteSession(sessionToken) { | |
await db | |
.deleteFrom("Session") | |
.where("Session.sessionToken", "=", sessionToken) | |
.executeTakeFirstOrThrow(); | |
}, | |
async createVerificationToken(verificationToken) { | |
const query = db | |
.insertInto("VerificationToken") | |
.values(verificationToken); | |
const result = supportsReturning | |
? await query.returningAll().executeTakeFirstOrThrow() | |
: await query.executeTakeFirstOrThrow().then(async () => { | |
return await db | |
.selectFrom("VerificationToken") | |
.selectAll() | |
.where("token", "=", verificationToken.token) | |
.executeTakeFirstOrThrow(); | |
}); | |
return result; | |
}, | |
async useVerificationToken({ identifier, token }) { | |
const query = db | |
.deleteFrom("VerificationToken") | |
.where("VerificationToken.token", "=", token) | |
.where("VerificationToken.identifier", "=", identifier); | |
const result = supportsReturning | |
? (await query.returningAll().executeTakeFirst()) ?? null | |
: await db | |
.selectFrom("VerificationToken") | |
.selectAll() | |
.where("token", "=", token) | |
.executeTakeFirst() | |
.then(async (res) => { | |
await query.executeTakeFirst(); | |
return res; | |
}); | |
if (!result) return null; | |
return result; | |
}, | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment