@auth/drizzle-adapter 0.9.0 → 1.0.1
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/README.md +1 -1
- package/index.d.ts +81 -64
- package/index.d.ts.map +1 -1
- package/index.js +86 -69
- package/lib/mysql.d.ts +477 -296
- package/lib/mysql.d.ts.map +1 -1
- package/lib/mysql.js +131 -143
- package/lib/pg.d.ts +476 -296
- package/lib/pg.d.ts.map +1 -1
- package/lib/pg.js +121 -124
- package/lib/sqlite.d.ts +476 -296
- package/lib/sqlite.d.ts.map +1 -1
- package/lib/sqlite.js +106 -107
- package/lib/utils.d.ts +10 -21
- package/lib/utils.d.ts.map +1 -1
- package/lib/utils.js +1 -7
- package/package.json +9 -9
- package/src/index.ts +90 -74
- package/src/lib/mysql.ts +378 -195
- package/src/lib/pg.ts +363 -162
- package/src/lib/sqlite.ts +345 -135
- package/src/lib/utils.ts +25 -43
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<p align="center">
|
|
2
2
|
<br/>
|
|
3
3
|
<a href="https://authjs.dev" target="_blank">
|
|
4
|
-
<img height="64px" src="https://authjs.dev/img/logo
|
|
4
|
+
<img height="64px" src="https://authjs.dev/img/logo-sm.png" />
|
|
5
5
|
</a>
|
|
6
6
|
<a href="https://github.com/drizzle-team/drizzle-orm" target="_blank">
|
|
7
7
|
<img height="64px" src="https://authjs.dev/img/adapters/drizzle-orm.png"/>
|
package/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* <div style={{display: "flex", justifyContent: "space-between", alignItems: "center", padding: 16}}>
|
|
3
3
|
* <p style={{fontWeight: "normal"}}>Official <a href="https://orm.drizzle.team">Drizzle ORM</a> adapter for Auth.js / NextAuth.js.</p>
|
|
4
4
|
* <a href="https://orm.drizzle.team">
|
|
5
|
-
* <img style={{display: "block"}} src="/img/adapters/drizzle
|
|
5
|
+
* <img style={{display: "block"}} src="/img/adapters/drizzle.svg" width="38" />
|
|
6
6
|
* </a>
|
|
7
7
|
* </div>
|
|
8
8
|
*
|
|
@@ -15,32 +15,46 @@
|
|
|
15
15
|
*
|
|
16
16
|
* @module @auth/drizzle-adapter
|
|
17
17
|
*/
|
|
18
|
-
import {
|
|
18
|
+
import { DefaultSchema, SqlFlavorOptions } from "./lib/utils.js";
|
|
19
19
|
import type { Adapter } from "@auth/core/adapters";
|
|
20
20
|
/**
|
|
21
|
-
* Add
|
|
21
|
+
* Create db instance and pass it to adapter. Add this adapter to your `auth.ts` Auth.js configuration object:
|
|
22
22
|
*
|
|
23
|
-
* ```ts title="
|
|
23
|
+
* ```ts title="auth.ts"
|
|
24
24
|
* import NextAuth from "next-auth"
|
|
25
|
-
* import
|
|
25
|
+
* import Google from "next-auth/providers/google"
|
|
26
26
|
* import { DrizzleAdapter } from "@auth/drizzle-adapter"
|
|
27
|
-
* import { db } from "./
|
|
27
|
+
* import { db } from "./db.ts"
|
|
28
28
|
*
|
|
29
|
-
* export
|
|
29
|
+
* export const { handlers, auth } = NextAuth({
|
|
30
30
|
* adapter: DrizzleAdapter(db),
|
|
31
31
|
* providers: [
|
|
32
|
-
*
|
|
33
|
-
* clientId: process.env.GOOGLE_CLIENT_ID,
|
|
34
|
-
* clientSecret: process.env.GOOGLE_CLIENT_SECRET,
|
|
35
|
-
* }),
|
|
32
|
+
* Google,
|
|
36
33
|
* ],
|
|
37
34
|
* })
|
|
38
35
|
* ```
|
|
39
36
|
*
|
|
37
|
+
* Follow the Drizzle documentation for [PostgreSQL setup](https://orm.drizzle.team/docs/get-started-postgresql), [MySQL setup](https://orm.drizzle.team/docs/get-started-mysql) and [SQLite setup](https://orm.drizzle.team/docs/get-started-sqlite).
|
|
38
|
+
*
|
|
40
39
|
* :::info
|
|
41
|
-
* If you
|
|
40
|
+
* If you want to use your own tables, you can pass them as a second argument. If you add non-nullable columns, make sure to provide a default value or rewrite functions to handle the missing values.
|
|
42
41
|
* :::
|
|
43
42
|
*
|
|
43
|
+
* ```ts title="auth.ts"
|
|
44
|
+
* import NextAuth from "next-auth"
|
|
45
|
+
* import Google from "next-auth/providers/google"
|
|
46
|
+
* import { DrizzleAdapter } from "@auth/drizzle-adapter"
|
|
47
|
+
* import { accounts, sessions, users, verificationTokens } from "./schema"
|
|
48
|
+
* import { db } from "./db.ts"
|
|
49
|
+
*
|
|
50
|
+
* export const { handlers, auth } = NextAuth({
|
|
51
|
+
* adapter: DrizzleAdapter(db, { usersTable: users, accountsTable: accounts, sessionsTable: sessions, verificationTokensTable: verificationTokens }),
|
|
52
|
+
* providers: [
|
|
53
|
+
* Google,
|
|
54
|
+
* ],
|
|
55
|
+
* })
|
|
56
|
+
* ```
|
|
57
|
+
*
|
|
44
58
|
* ## Setup
|
|
45
59
|
*
|
|
46
60
|
* First, create a schema that includes [the minimum requirements for a `next-auth` adapter](/reference/core/adapters#models). You can select your favorite SQL flavor below and copy it.
|
|
@@ -61,9 +75,10 @@ import type { Adapter } from "@auth/core/adapters";
|
|
|
61
75
|
* integer
|
|
62
76
|
* } from "drizzle-orm/pg-core"
|
|
63
77
|
* import type { AdapterAccount } from '@auth/core/adapters'
|
|
78
|
+
* import { randomUUID } from "crypto"
|
|
64
79
|
*
|
|
65
80
|
* export const users = pgTable("user", {
|
|
66
|
-
* id: text("id").
|
|
81
|
+
* id: text("id").primaryKey().$defaultFn(() => randomUUID()),
|
|
67
82
|
* name: text("name"),
|
|
68
83
|
* email: text("email").notNull(),
|
|
69
84
|
* emailVerified: timestamp("emailVerified", { mode: "date" }),
|
|
@@ -76,7 +91,7 @@ import type { Adapter } from "@auth/core/adapters";
|
|
|
76
91
|
* userId: text("userId")
|
|
77
92
|
* .notNull()
|
|
78
93
|
* .references(() => users.id, { onDelete: "cascade" }),
|
|
79
|
-
* type: text("type")
|
|
94
|
+
* type: text("type").notNull(),
|
|
80
95
|
* provider: text("provider").notNull(),
|
|
81
96
|
* providerAccountId: text("providerAccountId").notNull(),
|
|
82
97
|
* refresh_token: text("refresh_token"),
|
|
@@ -93,7 +108,7 @@ import type { Adapter } from "@auth/core/adapters";
|
|
|
93
108
|
* )
|
|
94
109
|
*
|
|
95
110
|
* export const sessions = pgTable("session", {
|
|
96
|
-
* sessionToken: text("sessionToken").
|
|
111
|
+
* sessionToken: text("sessionToken").primaryKey(),
|
|
97
112
|
* userId: text("userId")
|
|
98
113
|
* .notNull()
|
|
99
114
|
* .references(() => users.id, { onDelete: "cascade" }),
|
|
@@ -115,6 +130,8 @@ import type { Adapter } from "@auth/core/adapters";
|
|
|
115
130
|
*
|
|
116
131
|
* ### MySQL
|
|
117
132
|
*
|
|
133
|
+
* In MySQL, there's no `returning` clause, so in the `createUser` function, we first insert a new user and then search by `email` to get the user's data. To make the search faster, we suggest adding an index to the `email` column.
|
|
134
|
+
*
|
|
118
135
|
* ```ts title="schema.ts"
|
|
119
136
|
* import {
|
|
120
137
|
* int,
|
|
@@ -126,39 +143,39 @@ import type { Adapter } from "@auth/core/adapters";
|
|
|
126
143
|
* import type { AdapterAccount } from "@auth/core/adapters"
|
|
127
144
|
*
|
|
128
145
|
* export const users = mysqlTable("user", {
|
|
129
|
-
* id: varchar("id", { length: 255 }).
|
|
146
|
+
* id: varchar("id", { length: 255 }).primaryKey().$defaultFn(() => randomUUID()),
|
|
130
147
|
* name: varchar("name", { length: 255 }),
|
|
131
148
|
* email: varchar("email", { length: 255 }).notNull(),
|
|
132
|
-
*
|
|
149
|
+
* emailVerified: timestamp("emailVerified", { mode: "date", fsp: 3 }),
|
|
133
150
|
* image: varchar("image", { length: 255 }),
|
|
134
151
|
* })
|
|
135
152
|
*
|
|
136
153
|
* export const accounts = mysqlTable(
|
|
137
154
|
* "account",
|
|
138
155
|
* {
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
*
|
|
156
|
+
* userId: varchar("userId", { length: 255 })
|
|
157
|
+
* .notNull()
|
|
158
|
+
* .references(() => users.id, { onDelete: "cascade" }),
|
|
159
|
+
* type: varchar("type", { length: 255 }).notNull(),
|
|
143
160
|
* provider: varchar("provider", { length: 255 }).notNull(),
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
*
|
|
147
|
-
*
|
|
148
|
-
*
|
|
149
|
-
*
|
|
150
|
-
*
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
*
|
|
154
|
-
*
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
*
|
|
161
|
+
* providerAccountId: varchar("providerAccountId", { length: 255 }).notNull(),
|
|
162
|
+
* refresh_token: varchar("refresh_token", { length: 255 }),
|
|
163
|
+
* access_token: varchar("access_token", { length: 255 }),
|
|
164
|
+
* expires_at: int("expires_at"),
|
|
165
|
+
* token_type: varchar("token_type", { length: 255 }),
|
|
166
|
+
* scope: varchar("scope", { length: 255 }),
|
|
167
|
+
* id_token: varchar("id_token", { length: 2048 }),
|
|
168
|
+
* session_state: varchar("session_state", { length: 255 }),
|
|
169
|
+
* },
|
|
170
|
+
* (account) => ({
|
|
171
|
+
* compoundKey: primaryKey({
|
|
172
|
+
columns: [account.provider, account.providerAccountId],
|
|
173
|
+
})
|
|
174
|
+
* })
|
|
158
175
|
* )
|
|
159
176
|
*
|
|
160
177
|
* export const sessions = mysqlTable("session", {
|
|
161
|
-
* sessionToken: varchar("sessionToken", { length: 255 }).
|
|
178
|
+
* sessionToken: varchar("sessionToken", { length: 255 }).primaryKey(),
|
|
162
179
|
* userId: varchar("userId", { length: 255 })
|
|
163
180
|
* .notNull()
|
|
164
181
|
* .references(() => users.id, { onDelete: "cascade" }),
|
|
@@ -166,15 +183,15 @@ import type { Adapter } from "@auth/core/adapters";
|
|
|
166
183
|
* })
|
|
167
184
|
*
|
|
168
185
|
* export const verificationTokens = mysqlTable(
|
|
169
|
-
*
|
|
170
|
-
*
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
*
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
*
|
|
186
|
+
* "verificationToken",
|
|
187
|
+
* {
|
|
188
|
+
* identifier: varchar("identifier", { length: 255 }).notNull(),
|
|
189
|
+
* token: varchar("token", { length: 255 }).notNull(),
|
|
190
|
+
* expires: timestamp("expires", { mode: "date" }).notNull(),
|
|
191
|
+
* },
|
|
192
|
+
* (vt) => ({
|
|
193
|
+
* compoundKey: primaryKey({ columns: [vt.identifier, vt.token] }),
|
|
194
|
+
* })
|
|
178
195
|
* )
|
|
179
196
|
* ```
|
|
180
197
|
*
|
|
@@ -185,7 +202,7 @@ import type { Adapter } from "@auth/core/adapters";
|
|
|
185
202
|
* import type { AdapterAccount } from "@auth/core/adapters"
|
|
186
203
|
*
|
|
187
204
|
* export const users = sqliteTable("user", {
|
|
188
|
-
* id: text("id").
|
|
205
|
+
* id: text("id").primaryKey().$defaultFn(() => randomUUID()),
|
|
189
206
|
* name: text("name"),
|
|
190
207
|
* email: text("email").notNull(),
|
|
191
208
|
* emailVerified: integer("emailVerified", { mode: "timestamp_ms" }),
|
|
@@ -198,7 +215,7 @@ import type { Adapter } from "@auth/core/adapters";
|
|
|
198
215
|
* userId: text("userId")
|
|
199
216
|
* .notNull()
|
|
200
217
|
* .references(() => users.id, { onDelete: "cascade" }),
|
|
201
|
-
* type: text("type")
|
|
218
|
+
* type: text("type").notNull(),
|
|
202
219
|
* provider: text("provider").notNull(),
|
|
203
220
|
* providerAccountId: text("providerAccountId").notNull(),
|
|
204
221
|
* refresh_token: text("refresh_token"),
|
|
@@ -212,38 +229,38 @@ import type { Adapter } from "@auth/core/adapters";
|
|
|
212
229
|
* (account) => ({
|
|
213
230
|
* compoundKey: primaryKey({
|
|
214
231
|
columns: [account.provider, account.providerAccountId],
|
|
215
|
-
})
|
|
232
|
+
})
|
|
216
233
|
* })
|
|
217
234
|
* )
|
|
218
235
|
*
|
|
219
236
|
* export const sessions = sqliteTable("session", {
|
|
220
|
-
*
|
|
221
|
-
*
|
|
222
|
-
*
|
|
223
|
-
*
|
|
224
|
-
*
|
|
237
|
+
* sessionToken: text("sessionToken").primaryKey(),
|
|
238
|
+
* userId: text("userId")
|
|
239
|
+
* .notNull()
|
|
240
|
+
* .references(() => users.id, { onDelete: "cascade" }),
|
|
241
|
+
* expires: integer("expires", { mode: "timestamp_ms" }).notNull(),
|
|
225
242
|
* })
|
|
226
243
|
*
|
|
227
244
|
* export const verificationTokens = sqliteTable(
|
|
228
|
-
*
|
|
229
|
-
*
|
|
230
|
-
*
|
|
231
|
-
*
|
|
232
|
-
*
|
|
233
|
-
*
|
|
234
|
-
*
|
|
235
|
-
*
|
|
236
|
-
*
|
|
245
|
+
* "verificationToken",
|
|
246
|
+
* {
|
|
247
|
+
* identifier: text("identifier").notNull(),
|
|
248
|
+
* token: text("token").notNull(),
|
|
249
|
+
* expires: integer("expires", { mode: "timestamp_ms" }).notNull(),
|
|
250
|
+
* },
|
|
251
|
+
* (vt) => ({
|
|
252
|
+
* compoundKey: primaryKey({ columns: [vt.identifier, vt.token] }),
|
|
253
|
+
* })
|
|
237
254
|
* )
|
|
238
255
|
* ```
|
|
239
256
|
*
|
|
240
257
|
* ## Migrating your database
|
|
241
258
|
* With your schema now described in your code, you'll need to migrate your database to your schema.
|
|
242
259
|
*
|
|
243
|
-
* For full documentation on how to run migrations with Drizzle, [visit the Drizzle documentation](https://orm.drizzle.team/kit-docs/overview#running-migrations).
|
|
260
|
+
* For full documentation on how to run migrations with Drizzle, [visit the Drizzle documentation](https://orm.drizzle.team/kit-docs/overview#running-migrations) or check how to apply changes directly to the database with [push command](https://orm.drizzle.team/kit-docs/overview#prototyping-with-db-push).
|
|
244
261
|
*
|
|
245
262
|
* ---
|
|
246
263
|
*
|
|
247
264
|
**/
|
|
248
|
-
export declare function DrizzleAdapter<SqlFlavor extends SqlFlavorOptions>(db: SqlFlavor,
|
|
265
|
+
export declare function DrizzleAdapter<SqlFlavor extends SqlFlavorOptions>(db: SqlFlavor, schema?: DefaultSchema<SqlFlavor>): Adapter;
|
|
249
266
|
//# sourceMappingURL=index.d.ts.map
|
package/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AASH,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAEhE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAoPI;AACJ,wBAAgB,cAAc,CAAC,SAAS,SAAS,gBAAgB,EAC/D,EAAE,EAAE,SAAS,EACb,MAAM,CAAC,EAAE,aAAa,CAAC,SAAS,CAAC,GAChC,OAAO,CAYT"}
|
package/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* <div style={{display: "flex", justifyContent: "space-between", alignItems: "center", padding: 16}}>
|
|
3
3
|
* <p style={{fontWeight: "normal"}}>Official <a href="https://orm.drizzle.team">Drizzle ORM</a> adapter for Auth.js / NextAuth.js.</p>
|
|
4
4
|
* <a href="https://orm.drizzle.team">
|
|
5
|
-
* <img style={{display: "block"}} src="/img/adapters/drizzle
|
|
5
|
+
* <img style={{display: "block"}} src="/img/adapters/drizzle.svg" width="38" />
|
|
6
6
|
* </a>
|
|
7
7
|
* </div>
|
|
8
8
|
*
|
|
@@ -15,37 +15,51 @@
|
|
|
15
15
|
*
|
|
16
16
|
* @module @auth/drizzle-adapter
|
|
17
17
|
*/
|
|
18
|
+
import { is } from "drizzle-orm";
|
|
18
19
|
import { MySqlDatabase } from "drizzle-orm/mysql-core";
|
|
19
20
|
import { PgDatabase } from "drizzle-orm/pg-core";
|
|
20
21
|
import { BaseSQLiteDatabase } from "drizzle-orm/sqlite-core";
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
22
|
+
import { MySqlDrizzleAdapter } from "./lib/mysql.js";
|
|
23
|
+
import { PostgresDrizzleAdapter } from "./lib/pg.js";
|
|
23
24
|
import { SQLiteDrizzleAdapter } from "./lib/sqlite.js";
|
|
24
|
-
import { is } from "drizzle-orm";
|
|
25
25
|
/**
|
|
26
|
-
* Add
|
|
26
|
+
* Create db instance and pass it to adapter. Add this adapter to your `auth.ts` Auth.js configuration object:
|
|
27
27
|
*
|
|
28
|
-
* ```ts title="
|
|
28
|
+
* ```ts title="auth.ts"
|
|
29
29
|
* import NextAuth from "next-auth"
|
|
30
|
-
* import
|
|
30
|
+
* import Google from "next-auth/providers/google"
|
|
31
31
|
* import { DrizzleAdapter } from "@auth/drizzle-adapter"
|
|
32
|
-
* import { db } from "./
|
|
32
|
+
* import { db } from "./db.ts"
|
|
33
33
|
*
|
|
34
|
-
* export
|
|
34
|
+
* export const { handlers, auth } = NextAuth({
|
|
35
35
|
* adapter: DrizzleAdapter(db),
|
|
36
36
|
* providers: [
|
|
37
|
-
*
|
|
38
|
-
* clientId: process.env.GOOGLE_CLIENT_ID,
|
|
39
|
-
* clientSecret: process.env.GOOGLE_CLIENT_SECRET,
|
|
40
|
-
* }),
|
|
37
|
+
* Google,
|
|
41
38
|
* ],
|
|
42
39
|
* })
|
|
43
40
|
* ```
|
|
44
41
|
*
|
|
42
|
+
* Follow the Drizzle documentation for [PostgreSQL setup](https://orm.drizzle.team/docs/get-started-postgresql), [MySQL setup](https://orm.drizzle.team/docs/get-started-mysql) and [SQLite setup](https://orm.drizzle.team/docs/get-started-sqlite).
|
|
43
|
+
*
|
|
45
44
|
* :::info
|
|
46
|
-
* If you
|
|
45
|
+
* If you want to use your own tables, you can pass them as a second argument. If you add non-nullable columns, make sure to provide a default value or rewrite functions to handle the missing values.
|
|
47
46
|
* :::
|
|
48
47
|
*
|
|
48
|
+
* ```ts title="auth.ts"
|
|
49
|
+
* import NextAuth from "next-auth"
|
|
50
|
+
* import Google from "next-auth/providers/google"
|
|
51
|
+
* import { DrizzleAdapter } from "@auth/drizzle-adapter"
|
|
52
|
+
* import { accounts, sessions, users, verificationTokens } from "./schema"
|
|
53
|
+
* import { db } from "./db.ts"
|
|
54
|
+
*
|
|
55
|
+
* export const { handlers, auth } = NextAuth({
|
|
56
|
+
* adapter: DrizzleAdapter(db, { usersTable: users, accountsTable: accounts, sessionsTable: sessions, verificationTokensTable: verificationTokens }),
|
|
57
|
+
* providers: [
|
|
58
|
+
* Google,
|
|
59
|
+
* ],
|
|
60
|
+
* })
|
|
61
|
+
* ```
|
|
62
|
+
*
|
|
49
63
|
* ## Setup
|
|
50
64
|
*
|
|
51
65
|
* First, create a schema that includes [the minimum requirements for a `next-auth` adapter](/reference/core/adapters#models). You can select your favorite SQL flavor below and copy it.
|
|
@@ -66,9 +80,10 @@ import { is } from "drizzle-orm";
|
|
|
66
80
|
* integer
|
|
67
81
|
* } from "drizzle-orm/pg-core"
|
|
68
82
|
* import type { AdapterAccount } from '@auth/core/adapters'
|
|
83
|
+
* import { randomUUID } from "crypto"
|
|
69
84
|
*
|
|
70
85
|
* export const users = pgTable("user", {
|
|
71
|
-
* id: text("id").
|
|
86
|
+
* id: text("id").primaryKey().$defaultFn(() => randomUUID()),
|
|
72
87
|
* name: text("name"),
|
|
73
88
|
* email: text("email").notNull(),
|
|
74
89
|
* emailVerified: timestamp("emailVerified", { mode: "date" }),
|
|
@@ -81,7 +96,7 @@ import { is } from "drizzle-orm";
|
|
|
81
96
|
* userId: text("userId")
|
|
82
97
|
* .notNull()
|
|
83
98
|
* .references(() => users.id, { onDelete: "cascade" }),
|
|
84
|
-
* type: text("type")
|
|
99
|
+
* type: text("type").notNull(),
|
|
85
100
|
* provider: text("provider").notNull(),
|
|
86
101
|
* providerAccountId: text("providerAccountId").notNull(),
|
|
87
102
|
* refresh_token: text("refresh_token"),
|
|
@@ -98,7 +113,7 @@ import { is } from "drizzle-orm";
|
|
|
98
113
|
* )
|
|
99
114
|
*
|
|
100
115
|
* export const sessions = pgTable("session", {
|
|
101
|
-
* sessionToken: text("sessionToken").
|
|
116
|
+
* sessionToken: text("sessionToken").primaryKey(),
|
|
102
117
|
* userId: text("userId")
|
|
103
118
|
* .notNull()
|
|
104
119
|
* .references(() => users.id, { onDelete: "cascade" }),
|
|
@@ -120,6 +135,8 @@ import { is } from "drizzle-orm";
|
|
|
120
135
|
*
|
|
121
136
|
* ### MySQL
|
|
122
137
|
*
|
|
138
|
+
* In MySQL, there's no `returning` clause, so in the `createUser` function, we first insert a new user and then search by `email` to get the user's data. To make the search faster, we suggest adding an index to the `email` column.
|
|
139
|
+
*
|
|
123
140
|
* ```ts title="schema.ts"
|
|
124
141
|
* import {
|
|
125
142
|
* int,
|
|
@@ -131,39 +148,39 @@ import { is } from "drizzle-orm";
|
|
|
131
148
|
* import type { AdapterAccount } from "@auth/core/adapters"
|
|
132
149
|
*
|
|
133
150
|
* export const users = mysqlTable("user", {
|
|
134
|
-
* id: varchar("id", { length: 255 }).
|
|
151
|
+
* id: varchar("id", { length: 255 }).primaryKey().$defaultFn(() => randomUUID()),
|
|
135
152
|
* name: varchar("name", { length: 255 }),
|
|
136
153
|
* email: varchar("email", { length: 255 }).notNull(),
|
|
137
|
-
*
|
|
154
|
+
* emailVerified: timestamp("emailVerified", { mode: "date", fsp: 3 }),
|
|
138
155
|
* image: varchar("image", { length: 255 }),
|
|
139
156
|
* })
|
|
140
157
|
*
|
|
141
158
|
* export const accounts = mysqlTable(
|
|
142
159
|
* "account",
|
|
143
160
|
* {
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
*
|
|
147
|
-
*
|
|
161
|
+
* userId: varchar("userId", { length: 255 })
|
|
162
|
+
* .notNull()
|
|
163
|
+
* .references(() => users.id, { onDelete: "cascade" }),
|
|
164
|
+
* type: varchar("type", { length: 255 }).notNull(),
|
|
148
165
|
* provider: varchar("provider", { length: 255 }).notNull(),
|
|
149
|
-
*
|
|
150
|
-
*
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
*
|
|
154
|
-
*
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
*
|
|
166
|
+
* providerAccountId: varchar("providerAccountId", { length: 255 }).notNull(),
|
|
167
|
+
* refresh_token: varchar("refresh_token", { length: 255 }),
|
|
168
|
+
* access_token: varchar("access_token", { length: 255 }),
|
|
169
|
+
* expires_at: int("expires_at"),
|
|
170
|
+
* token_type: varchar("token_type", { length: 255 }),
|
|
171
|
+
* scope: varchar("scope", { length: 255 }),
|
|
172
|
+
* id_token: varchar("id_token", { length: 2048 }),
|
|
173
|
+
* session_state: varchar("session_state", { length: 255 }),
|
|
174
|
+
* },
|
|
175
|
+
* (account) => ({
|
|
176
|
+
* compoundKey: primaryKey({
|
|
177
|
+
columns: [account.provider, account.providerAccountId],
|
|
178
|
+
})
|
|
179
|
+
* })
|
|
163
180
|
* )
|
|
164
181
|
*
|
|
165
182
|
* export const sessions = mysqlTable("session", {
|
|
166
|
-
* sessionToken: varchar("sessionToken", { length: 255 }).
|
|
183
|
+
* sessionToken: varchar("sessionToken", { length: 255 }).primaryKey(),
|
|
167
184
|
* userId: varchar("userId", { length: 255 })
|
|
168
185
|
* .notNull()
|
|
169
186
|
* .references(() => users.id, { onDelete: "cascade" }),
|
|
@@ -171,15 +188,15 @@ import { is } from "drizzle-orm";
|
|
|
171
188
|
* })
|
|
172
189
|
*
|
|
173
190
|
* export const verificationTokens = mysqlTable(
|
|
174
|
-
*
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
*
|
|
178
|
-
*
|
|
179
|
-
*
|
|
180
|
-
*
|
|
181
|
-
*
|
|
182
|
-
*
|
|
191
|
+
* "verificationToken",
|
|
192
|
+
* {
|
|
193
|
+
* identifier: varchar("identifier", { length: 255 }).notNull(),
|
|
194
|
+
* token: varchar("token", { length: 255 }).notNull(),
|
|
195
|
+
* expires: timestamp("expires", { mode: "date" }).notNull(),
|
|
196
|
+
* },
|
|
197
|
+
* (vt) => ({
|
|
198
|
+
* compoundKey: primaryKey({ columns: [vt.identifier, vt.token] }),
|
|
199
|
+
* })
|
|
183
200
|
* )
|
|
184
201
|
* ```
|
|
185
202
|
*
|
|
@@ -190,7 +207,7 @@ import { is } from "drizzle-orm";
|
|
|
190
207
|
* import type { AdapterAccount } from "@auth/core/adapters"
|
|
191
208
|
*
|
|
192
209
|
* export const users = sqliteTable("user", {
|
|
193
|
-
* id: text("id").
|
|
210
|
+
* id: text("id").primaryKey().$defaultFn(() => randomUUID()),
|
|
194
211
|
* name: text("name"),
|
|
195
212
|
* email: text("email").notNull(),
|
|
196
213
|
* emailVerified: integer("emailVerified", { mode: "timestamp_ms" }),
|
|
@@ -203,7 +220,7 @@ import { is } from "drizzle-orm";
|
|
|
203
220
|
* userId: text("userId")
|
|
204
221
|
* .notNull()
|
|
205
222
|
* .references(() => users.id, { onDelete: "cascade" }),
|
|
206
|
-
* type: text("type")
|
|
223
|
+
* type: text("type").notNull(),
|
|
207
224
|
* provider: text("provider").notNull(),
|
|
208
225
|
* providerAccountId: text("providerAccountId").notNull(),
|
|
209
226
|
* refresh_token: text("refresh_token"),
|
|
@@ -217,48 +234,48 @@ import { is } from "drizzle-orm";
|
|
|
217
234
|
* (account) => ({
|
|
218
235
|
* compoundKey: primaryKey({
|
|
219
236
|
columns: [account.provider, account.providerAccountId],
|
|
220
|
-
})
|
|
237
|
+
})
|
|
221
238
|
* })
|
|
222
239
|
* )
|
|
223
240
|
*
|
|
224
241
|
* export const sessions = sqliteTable("session", {
|
|
225
|
-
*
|
|
226
|
-
*
|
|
227
|
-
*
|
|
228
|
-
*
|
|
229
|
-
*
|
|
242
|
+
* sessionToken: text("sessionToken").primaryKey(),
|
|
243
|
+
* userId: text("userId")
|
|
244
|
+
* .notNull()
|
|
245
|
+
* .references(() => users.id, { onDelete: "cascade" }),
|
|
246
|
+
* expires: integer("expires", { mode: "timestamp_ms" }).notNull(),
|
|
230
247
|
* })
|
|
231
248
|
*
|
|
232
249
|
* export const verificationTokens = sqliteTable(
|
|
233
|
-
*
|
|
234
|
-
*
|
|
235
|
-
*
|
|
236
|
-
*
|
|
237
|
-
*
|
|
238
|
-
*
|
|
239
|
-
*
|
|
240
|
-
*
|
|
241
|
-
*
|
|
250
|
+
* "verificationToken",
|
|
251
|
+
* {
|
|
252
|
+
* identifier: text("identifier").notNull(),
|
|
253
|
+
* token: text("token").notNull(),
|
|
254
|
+
* expires: integer("expires", { mode: "timestamp_ms" }).notNull(),
|
|
255
|
+
* },
|
|
256
|
+
* (vt) => ({
|
|
257
|
+
* compoundKey: primaryKey({ columns: [vt.identifier, vt.token] }),
|
|
258
|
+
* })
|
|
242
259
|
* )
|
|
243
260
|
* ```
|
|
244
261
|
*
|
|
245
262
|
* ## Migrating your database
|
|
246
263
|
* With your schema now described in your code, you'll need to migrate your database to your schema.
|
|
247
264
|
*
|
|
248
|
-
* For full documentation on how to run migrations with Drizzle, [visit the Drizzle documentation](https://orm.drizzle.team/kit-docs/overview#running-migrations).
|
|
265
|
+
* For full documentation on how to run migrations with Drizzle, [visit the Drizzle documentation](https://orm.drizzle.team/kit-docs/overview#running-migrations) or check how to apply changes directly to the database with [push command](https://orm.drizzle.team/kit-docs/overview#prototyping-with-db-push).
|
|
249
266
|
*
|
|
250
267
|
* ---
|
|
251
268
|
*
|
|
252
269
|
**/
|
|
253
|
-
export function DrizzleAdapter(db,
|
|
270
|
+
export function DrizzleAdapter(db, schema) {
|
|
254
271
|
if (is(db, MySqlDatabase)) {
|
|
255
|
-
return
|
|
272
|
+
return MySqlDrizzleAdapter(db, schema);
|
|
256
273
|
}
|
|
257
274
|
else if (is(db, PgDatabase)) {
|
|
258
|
-
return
|
|
275
|
+
return PostgresDrizzleAdapter(db, schema);
|
|
259
276
|
}
|
|
260
277
|
else if (is(db, BaseSQLiteDatabase)) {
|
|
261
|
-
return SQLiteDrizzleAdapter(db,
|
|
278
|
+
return SQLiteDrizzleAdapter(db, schema);
|
|
262
279
|
}
|
|
263
280
|
throw new Error(`Unsupported database type (${typeof db}) in Auth.js Drizzle adapter.`);
|
|
264
281
|
}
|