@auth/drizzle-adapter 1.0.0 → 1.1.0

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/src/lib/mysql.ts CHANGED
@@ -1,114 +1,123 @@
1
- import { and, eq } from "drizzle-orm"
1
+ import { and, eq, getTableColumns } from "drizzle-orm"
2
2
  import {
3
- int,
4
- timestamp,
5
- primaryKey,
6
- varchar,
3
+ MySqlColumn,
7
4
  MySqlDatabase,
8
- mysqlTable,
9
5
  MySqlTableWithColumns,
10
- TableConfig,
11
- QueryResultHKT,
12
6
  PreparedQueryHKTBase,
13
- index,
7
+ QueryResultHKT,
8
+ int,
9
+ mysqlTable,
10
+ primaryKey,
11
+ timestamp,
12
+ varchar,
14
13
  } from "drizzle-orm/mysql-core"
15
14
 
16
15
  import type {
17
16
  Adapter,
18
- AdapterUser,
19
17
  AdapterAccount,
18
+ AdapterAccountType,
20
19
  AdapterSession,
20
+ AdapterUser,
21
21
  VerificationToken,
22
22
  } from "@auth/core/adapters"
23
23
 
24
- import { randomUUID } from "crypto"
24
+ export function defineTables(
25
+ schema: Partial<DefaultMySqlSchema> = {}
26
+ ): Required<DefaultMySqlSchema> {
27
+ const usersTable =
28
+ schema.usersTable ??
29
+ (mysqlTable("user", {
30
+ id: varchar("id", { length: 255 })
31
+ .primaryKey()
32
+ .$defaultFn(() => crypto.randomUUID()),
33
+ name: varchar("name", { length: 255 }),
34
+ email: varchar("email", { length: 255 }).notNull(),
35
+ emailVerified: timestamp("emailVerified", { mode: "date", fsp: 3 }),
36
+ image: varchar("image", { length: 255 }),
37
+ }) satisfies DefaultMySqlUsersTable)
25
38
 
26
- export const mysqlUsersTable = mysqlTable("user" as string, {
27
- id: varchar("id", { length: 255 })
28
- .primaryKey()
29
- .$defaultFn(() => randomUUID()),
30
- name: varchar("name", { length: 255 }),
31
- email: varchar("email", { length: 255 }).notNull().unique(),
32
- emailVerified: timestamp("emailVerified", { mode: "date", fsp: 3 }),
33
- image: varchar("image", { length: 255 }),
34
- })
39
+ const accountsTable =
40
+ schema.accountsTable ??
41
+ (mysqlTable(
42
+ "account",
43
+ {
44
+ userId: varchar("userId", { length: 255 })
45
+ .notNull()
46
+ .references(() => usersTable.id, { onDelete: "cascade" }),
47
+ type: varchar("type", { length: 255 })
48
+ .$type<AdapterAccountType>()
49
+ .notNull(),
50
+ provider: varchar("provider", { length: 255 }).notNull(),
51
+ providerAccountId: varchar("providerAccountId", {
52
+ length: 255,
53
+ }).notNull(),
54
+ refresh_token: varchar("refresh_token", { length: 255 }),
55
+ access_token: varchar("access_token", { length: 255 }),
56
+ expires_at: int("expires_at"),
57
+ token_type: varchar("token_type", { length: 255 }),
58
+ scope: varchar("scope", { length: 255 }),
59
+ id_token: varchar("id_token", { length: 2048 }),
60
+ session_state: varchar("session_state", { length: 255 }),
61
+ },
62
+ (account) => ({
63
+ compositePk: primaryKey({
64
+ columns: [account.provider, account.providerAccountId],
65
+ }),
66
+ })
67
+ ) satisfies DefaultMySqlAccountsTable)
35
68
 
36
- export const mysqlAccountsTable = mysqlTable(
37
- "account" as string,
38
- {
39
- userId: varchar("userId", { length: 255 })
40
- .notNull()
41
- .references(() => mysqlUsersTable.id, { onDelete: "cascade" }),
42
- type: varchar("type", { length: 255 }).notNull(),
43
- provider: varchar("provider", { length: 255 }).notNull(),
44
- providerAccountId: varchar("providerAccountId", { length: 255 }).notNull(),
45
- refresh_token: varchar("refresh_token", { length: 255 }),
46
- access_token: varchar("access_token", { length: 255 }),
47
- expires_at: int("expires_at"),
48
- token_type: varchar("token_type", { length: 255 }),
49
- scope: varchar("scope", { length: 255 }),
50
- id_token: varchar("id_token", { length: 2048 }),
51
- session_state: varchar("session_state", { length: 255 }),
52
- },
53
- (account) => ({
54
- compositePk: primaryKey({
55
- columns: [account.provider, account.providerAccountId],
56
- }),
57
- userIdIdx: index("Account_userId_index").on(account.userId),
58
- })
59
- )
69
+ const sessionsTable =
70
+ schema.sessionsTable ??
71
+ (mysqlTable("session", {
72
+ sessionToken: varchar("sessionToken", { length: 255 }).primaryKey(),
73
+ userId: varchar("userId", { length: 255 })
74
+ .notNull()
75
+ .references(() => usersTable.id, { onDelete: "cascade" }),
76
+ expires: timestamp("expires", { mode: "date" }).notNull(),
77
+ }) satisfies DefaultMySqlSessionsTable)
60
78
 
61
- export const mysqlSessionsTable = mysqlTable(
62
- "session" as string,
63
- {
64
- id: varchar("id", { length: 255 })
65
- .primaryKey()
66
- .$defaultFn(() => randomUUID()),
67
- sessionToken: varchar("sessionToken", { length: 255 }).notNull().unique(),
68
- userId: varchar("userId", { length: 255 })
69
- .notNull()
70
- .references(() => mysqlUsersTable.id, { onDelete: "cascade" }),
71
- expires: timestamp("expires", { mode: "date" }).notNull(),
72
- },
73
- (session) => ({
74
- userIdIdx: index("Session_userId_index").on(session.userId),
75
- })
76
- )
79
+ const verificationTokensTable =
80
+ schema.verificationTokensTable ??
81
+ (mysqlTable(
82
+ "verificationToken",
83
+ {
84
+ identifier: varchar("identifier", { length: 255 }).notNull(),
85
+ token: varchar("token", { length: 255 }).notNull(),
86
+ expires: timestamp("expires", { mode: "date" }).notNull(),
87
+ },
88
+ (vt) => ({
89
+ compositePk: primaryKey({ columns: [vt.identifier, vt.token] }),
90
+ })
91
+ ) satisfies DefaultMySqlVerificationTokenTable)
77
92
 
78
- export const mysqlVerificationTokensTable = mysqlTable(
79
- "verificationToken" as string,
80
- {
81
- identifier: varchar("identifier", { length: 255 }).notNull(),
82
- token: varchar("token", { length: 255 }).notNull().unique(),
83
- expires: timestamp("expires", { mode: "date" }).notNull(),
84
- },
85
- (vt) => ({
86
- compositePk: primaryKey({ columns: [vt.identifier, vt.token] }),
87
- })
88
- )
93
+ return {
94
+ usersTable,
95
+ accountsTable,
96
+ sessionsTable,
97
+ verificationTokensTable,
98
+ }
99
+ }
89
100
 
90
101
  export function MySqlDrizzleAdapter(
91
102
  client: MySqlDatabase<QueryResultHKT, PreparedQueryHKTBase, any>,
92
- schema: DefaultMySqlSchema = {
93
- usersTable: mysqlUsersTable,
94
- accountsTable: mysqlAccountsTable,
95
- sessionsTable: mysqlSessionsTable,
96
- verificationTokensTable: mysqlVerificationTokensTable,
97
- }
103
+ schema?: DefaultMySqlSchema
98
104
  ): Adapter {
99
105
  const { usersTable, accountsTable, sessionsTable, verificationTokensTable } =
100
- schema
106
+ defineTables(schema)
101
107
 
102
108
  return {
103
- async createUser(data: Omit<AdapterUser, "id">) {
104
- const id = randomUUID()
109
+ async createUser(data: AdapterUser) {
110
+ const { id, ...insertData } = data
111
+ const hasDefaultId = getTableColumns(usersTable)["id"]["hasDefault"]
105
112
 
106
- await client.insert(usersTable).values({ ...data, id })
113
+ await client
114
+ .insert(usersTable)
115
+ .values(hasDefaultId ? insertData : { ...insertData, id })
107
116
 
108
117
  return client
109
118
  .select()
110
119
  .from(usersTable)
111
- .where(eq(usersTable.id, id))
120
+ .where(eq(usersTable.email, data.email))
112
121
  .then((res) => res[0])
113
122
  },
114
123
  async getUser(userId: string) {
@@ -130,14 +139,12 @@ export function MySqlDrizzleAdapter(
130
139
  userId: string
131
140
  expires: Date
132
141
  }) {
133
- const id = randomUUID()
134
-
135
- await client.insert(sessionsTable).values({ ...data, id })
142
+ await client.insert(sessionsTable).values(data)
136
143
 
137
144
  return client
138
145
  .select()
139
146
  .from(sessionsTable)
140
- .where(eq(sessionsTable.id, id))
147
+ .where(eq(sessionsTable.sessionToken, data.sessionToken))
141
148
  .then((res) => res[0])
142
149
  },
143
150
  async getSessionAndUser(sessionToken: string) {
@@ -266,18 +273,193 @@ export function MySqlDrizzleAdapter(
266
273
  }
267
274
  }
268
275
 
269
- export type MySqlTableFn<T extends TableConfig> = MySqlTableWithColumns<{
270
- name: T["name"]
271
- columns: T["columns"]
272
- dialect: T["dialect"]
276
+ type DefaultMyqlColumn<
277
+ T extends {
278
+ data: string | number | Date
279
+ dataType: "string" | "number" | "date"
280
+ notNull: boolean
281
+ columnType: "MySqlVarChar" | "MySqlText" | "MySqlTimestamp" | "MySqlInt"
282
+ },
283
+ > = MySqlColumn<{
284
+ name: string
285
+ columnType: T["columnType"]
286
+ data: T["data"]
287
+ driverParam: string | number
288
+ notNull: T["notNull"]
289
+ hasDefault: boolean
290
+ enumValues: any
291
+ dataType: T["dataType"]
292
+ tableName: string
293
+ }>
294
+
295
+ export type DefaultMySqlUsersTable = MySqlTableWithColumns<{
296
+ name: string
297
+ columns: {
298
+ id: DefaultMyqlColumn<{
299
+ data: string
300
+ dataType: "string"
301
+ notNull: true
302
+ columnType: "MySqlVarChar" | "MySqlText"
303
+ }>
304
+ name: DefaultMyqlColumn<{
305
+ data: string
306
+ dataType: "string"
307
+ notNull: boolean
308
+ columnType: "MySqlVarChar" | "MySqlText"
309
+ }>
310
+ email: DefaultMyqlColumn<{
311
+ data: string
312
+ dataType: "string"
313
+ notNull: true
314
+ columnType: "MySqlVarChar" | "MySqlText"
315
+ }>
316
+ emailVerified: DefaultMyqlColumn<{
317
+ data: Date
318
+ dataType: "date"
319
+ notNull: boolean
320
+ columnType: "MySqlTimestamp"
321
+ }>
322
+ image: DefaultMyqlColumn<{
323
+ data: string
324
+ dataType: "string"
325
+ notNull: boolean
326
+ columnType: "MySqlVarChar" | "MySqlText"
327
+ }>
328
+ }
329
+ dialect: "mysql"
330
+ schema: string | undefined
331
+ }>
332
+
333
+ export type DefaultMySqlAccountsTable = MySqlTableWithColumns<{
334
+ name: string
335
+ columns: {
336
+ userId: DefaultMyqlColumn<{
337
+ columnType: "MySqlVarChar" | "MySqlText"
338
+ data: string
339
+ notNull: true
340
+ dataType: "string"
341
+ }>
342
+ type: DefaultMyqlColumn<{
343
+ columnType: "MySqlVarChar" | "MySqlText"
344
+ data: string
345
+ notNull: true
346
+ dataType: "string"
347
+ }>
348
+ provider: DefaultMyqlColumn<{
349
+ columnType: "MySqlVarChar" | "MySqlText"
350
+ data: string
351
+ notNull: true
352
+ dataType: "string"
353
+ }>
354
+ providerAccountId: DefaultMyqlColumn<{
355
+ dataType: "string"
356
+ columnType: "MySqlVarChar" | "MySqlText"
357
+ data: string
358
+ notNull: true
359
+ }>
360
+ refresh_token: DefaultMyqlColumn<{
361
+ dataType: "string"
362
+ columnType: "MySqlVarChar" | "MySqlText"
363
+ data: string
364
+ notNull: boolean
365
+ }>
366
+ access_token: DefaultMyqlColumn<{
367
+ dataType: "string"
368
+ columnType: "MySqlVarChar" | "MySqlText"
369
+ data: string
370
+ driverParam: string | number
371
+ notNull: boolean
372
+ }>
373
+ expires_at: DefaultMyqlColumn<{
374
+ dataType: "number"
375
+ columnType: "MySqlInt"
376
+ data: number
377
+ notNull: boolean
378
+ }>
379
+ token_type: DefaultMyqlColumn<{
380
+ dataType: "string"
381
+ columnType: "MySqlVarChar" | "MySqlText"
382
+ data: string
383
+ notNull: boolean
384
+ }>
385
+ scope: DefaultMyqlColumn<{
386
+ dataType: "string"
387
+ columnType: "MySqlVarChar" | "MySqlText"
388
+ data: string
389
+ notNull: boolean
390
+ }>
391
+ id_token: DefaultMyqlColumn<{
392
+ dataType: "string"
393
+ columnType: "MySqlVarChar" | "MySqlText"
394
+ data: string
395
+ notNull: boolean
396
+ }>
397
+ session_state: DefaultMyqlColumn<{
398
+ dataType: "string"
399
+ columnType: "MySqlVarChar" | "MySqlText"
400
+ data: string
401
+ notNull: boolean
402
+ }>
403
+ }
404
+ dialect: "mysql"
405
+ schema: string | undefined
406
+ }>
407
+
408
+ export type DefaultMySqlSessionsTable = MySqlTableWithColumns<{
409
+ name: string
410
+ columns: {
411
+ sessionToken: DefaultMyqlColumn<{
412
+ columnType: "MySqlVarChar" | "MySqlText"
413
+ data: string
414
+ notNull: true
415
+ dataType: "string"
416
+ }>
417
+ userId: DefaultMyqlColumn<{
418
+ columnType: "MySqlVarChar" | "MySqlText"
419
+ data: string
420
+ notNull: true
421
+ dataType: "string"
422
+ }>
423
+ expires: DefaultMyqlColumn<{
424
+ dataType: "date"
425
+ columnType: "MySqlTimestamp"
426
+ data: Date
427
+ notNull: true
428
+ }>
429
+ }
430
+ dialect: "mysql"
431
+ schema: string | undefined
432
+ }>
433
+
434
+ export type DefaultMySqlVerificationTokenTable = MySqlTableWithColumns<{
435
+ name: string
436
+ columns: {
437
+ identifier: DefaultMyqlColumn<{
438
+ columnType: "MySqlVarChar" | "MySqlText"
439
+ data: string
440
+ notNull: true
441
+ dataType: "string"
442
+ }>
443
+ token: DefaultMyqlColumn<{
444
+ columnType: "MySqlVarChar" | "MySqlText"
445
+ data: string
446
+ notNull: true
447
+ dataType: "string"
448
+ }>
449
+ expires: DefaultMyqlColumn<{
450
+ dataType: "date"
451
+ columnType: "MySqlTimestamp"
452
+ data: Date
453
+ notNull: true
454
+ }>
455
+ }
456
+ dialect: "mysql"
273
457
  schema: string | undefined
274
458
  }>
275
459
 
276
460
  export type DefaultMySqlSchema = {
277
- usersTable: MySqlTableFn<(typeof mysqlUsersTable)["_"]["config"]>
278
- accountsTable: MySqlTableFn<(typeof mysqlAccountsTable)["_"]["config"]>
279
- sessionsTable: MySqlTableFn<(typeof mysqlSessionsTable)["_"]["config"]>
280
- verificationTokensTable: MySqlTableFn<
281
- (typeof mysqlVerificationTokensTable)["_"]["config"]
282
- >
461
+ usersTable: DefaultMySqlUsersTable
462
+ accountsTable: DefaultMySqlAccountsTable
463
+ sessionsTable?: DefaultMySqlSessionsTable
464
+ verificationTokensTable?: DefaultMySqlVerificationTokenTable
283
465
  }