Kysely 配接器
資源
設定
安裝
npm install kysely @auth/kysely-adapter
環境變數
DATABASE_HOST=
DATABASE_NAME=
DATABASE_USER=
DATABASE_PASSWORD=
組態
此配接器支援 Kysely (截至 v0.24.2) 所支援的相同第一方方言:PostgreSQL、MySQL 和 SQLite。以下範例使用 PostgreSQL 與 pg 客戶端。
npm install pg
npm install --save-dev @types/pg
./auth.ts
import NextAuth from "next-auth"
import { KyselyAdapter } from "@auth/kysely-adapter"
import { db } from "../../../db"
export const { handlers, auth, signIn, signOut } = NextAuth({
adapter: KyselyAdapter(db),
providers: [],
})
Kysely 的建構函式需要一個資料庫介面,其中包含一個具有每個資料表介面的項目。您可以手動定義這些類型,或使用 kysely-codegen
/ prisma-kysely
自動產生它們。請查看 Auth.js 所需的預設模型。
db.ts
import { PostgresDialect } from "kysely"
import { Pool } from "pg"
// This adapter exports a wrapper of the original `Kysely` class called `KyselyAuth`,
// that can be used to provide additional type-safety.
// While using it isn't required, it is recommended as it will verify
// that the database interface has all the fields that Auth.js expects.
import { KyselyAuth } from "@auth/kysely-adapter"
import type { GeneratedAlways } from "kysely"
interface Database {
User: {
id: GeneratedAlways<string>
name: string | null
email: string
emailVerified: Date | null
image: string | null
}
Account: {
id: GeneratedAlways<string>
userId: string
type: string
provider: string
providerAccountId: string
refresh_token: string | null
access_token: string | null
expires_at: number | null
token_type: string | null
scope: string | null
id_token: string | null
session_state: string | null
}
Session: {
id: GeneratedAlways<string>
userId: string
sessionToken: string
expires: Date
}
VerificationToken: {
identifier: string
token: string
expires: Date
}
}
export const db = new KyselyAuth<Database>({
dialect: new PostgresDialect({
pool: new Pool({
host: process.env.DATABASE_HOST,
database: process.env.DATABASE_NAME,
user: process.env.DATABASE_USER,
password: process.env.DATABASE_PASSWORD,
}),
}),
})
💡
手動定義類型的替代方案是使用 kysely-codegen 從資料庫結構描述產生類型,或使用 prisma-kysely 從 Prisma 結構描述產生類型。當使用 KyselyAuth
產生類型時,匯入 Codegen
並將其作為第二個泛型參數傳遞
import type { Codegen } from "@auth/kysely-adapter"
new KyselyAuth<Database, Codegen>()
結構描述
db/migrations/001_create_db.ts
import { Kysely, sql } from "kysely"
export async function up(db: Kysely<any>): Promise<void> {
await db.schema
.createTable("User")
.addColumn("id", "uuid", (col) =>
col.primaryKey().defaultTo(sql`gen_random_uuid()`)
)
.addColumn("name", "text")
.addColumn("email", "text", (col) => col.unique().notNull())
.addColumn("emailVerified", "timestamptz")
.addColumn("image", "text")
.execute()
await db.schema
.createTable("Account")
.addColumn("id", "uuid", (col) =>
col.primaryKey().defaultTo(sql`gen_random_uuid()`)
)
.addColumn("userId", "uuid", (col) =>
col.references("User.id").onDelete("cascade").notNull()
)
.addColumn("type", "text", (col) => col.notNull())
.addColumn("provider", "text", (col) => col.notNull())
.addColumn("providerAccountId", "text", (col) => col.notNull())
.addColumn("refresh_token", "text")
.addColumn("access_token", "text")
.addColumn("expires_at", "bigint")
.addColumn("token_type", "text")
.addColumn("scope", "text")
.addColumn("id_token", "text")
.addColumn("session_state", "text")
.execute()
await db.schema
.createTable("Session")
.addColumn("id", "uuid", (col) =>
col.primaryKey().defaultTo(sql`gen_random_uuid()`)
)
.addColumn("userId", "uuid", (col) =>
col.references("User.id").onDelete("cascade").notNull()
)
.addColumn("sessionToken", "text", (col) => col.notNull().unique())
.addColumn("expires", "timestamptz", (col) => col.notNull())
.execute()
await db.schema
.createTable("VerificationToken")
.addColumn("identifier", "text", (col) => col.notNull())
.addColumn("token", "text", (col) => col.notNull().unique())
.addColumn("expires", "timestamptz", (col) => col.notNull())
.execute()
await db.schema
.createIndex("Account_userId_index")
.on("Account")
.column("userId")
.execute()
await db.schema
.createIndex("Session_userId_index")
.on("Session")
.column("userId")
.execute()
}
export async function down(db: Kysely<any>): Promise<void> {
await db.schema.dropTable("Account").ifExists().execute()
await db.schema.dropTable("Session").ifExists().execute()
await db.schema.dropTable("User").ifExists().execute()
await db.schema.dropTable("VerificationToken").ifExists().execute()
}
此結構描述適用於 Kysely 中,並且基於我們的主要結構描述。
如需更多關於使用 Kysely 建立和執行遷移的資訊,請參閱Kysely 遷移文件。
命名慣例
如果混合 snake_case 和 camelCase 欄名稱對您和/或您的底層資料庫系統來說是個問題,我們建議使用 Kysely 的 CamelCasePlugin
功能 (請參閱此處的文件) 來變更欄位名稱。這不會影響 NextAuth.js,但會讓您在使用 Kysely 時擁有一致的大小寫。