@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/sqlite.ts CHANGED
@@ -1,103 +1,113 @@
1
- import { eq, and } from "drizzle-orm"
1
+ import { and, eq, getTableColumns } from "drizzle-orm"
2
2
  import {
3
+ BaseSQLiteDatabase,
4
+ SQLiteColumn,
5
+ SQLiteTableWithColumns,
3
6
  integer,
4
- text,
5
7
  primaryKey,
6
- BaseSQLiteDatabase,
7
8
  sqliteTable,
8
- index,
9
- TableConfig,
10
- SQLiteTableWithColumns,
9
+ text,
11
10
  } from "drizzle-orm/sqlite-core"
12
11
 
13
12
  import type {
14
13
  Adapter,
15
14
  AdapterAccount,
16
- AdapterUser,
15
+ AdapterAccountType,
17
16
  AdapterSession,
17
+ AdapterUser,
18
18
  VerificationToken,
19
19
  } from "@auth/core/adapters"
20
- import { randomUUID } from "crypto"
21
-
22
- export const sqliteUsersTable = sqliteTable("user" as string, {
23
- id: text("id")
24
- .primaryKey()
25
- .$defaultFn(() => randomUUID()),
26
- name: text("name"),
27
- email: text("email").notNull().unique(),
28
- emailVerified: integer("emailVerified", { mode: "timestamp_ms" }),
29
- image: text("image"),
30
- })
31
-
32
- export const sqliteAccountsTable = sqliteTable(
33
- "account" as string,
34
- {
35
- userId: text("userId")
36
- .notNull()
37
- .references(() => sqliteUsersTable.id, { onDelete: "cascade" }),
38
- type: text("type").notNull(),
39
- provider: text("provider").notNull(),
40
- providerAccountId: text("providerAccountId").notNull(),
41
- refresh_token: text("refresh_token"),
42
- access_token: text("access_token"),
43
- expires_at: integer("expires_at"),
44
- token_type: text("token_type"),
45
- scope: text("scope"),
46
- id_token: text("id_token"),
47
- session_state: text("session_state"),
48
- },
49
- (account) => ({
50
- userIdIdx: index("Account_userId_index").on(account.userId),
51
- compositePk: primaryKey({
52
- columns: [account.provider, account.providerAccountId],
53
- }),
54
- })
55
- )
56
-
57
- export const sqliteSessionsTable = sqliteTable(
58
- "session" as string,
59
- {
60
- id: text("id")
61
- .primaryKey()
62
- .$defaultFn(() => randomUUID()),
63
- sessionToken: text("sessionToken").notNull().unique(),
64
- userId: text("userId")
65
- .notNull()
66
- .references(() => sqliteUsersTable.id, { onDelete: "cascade" }),
67
- expires: integer("expires", { mode: "timestamp_ms" }).notNull(),
68
- },
69
- (table) => ({
70
- userIdIdx: index("Session_userId_index").on(table.userId),
71
- })
72
- )
73
-
74
- export const sqliteVerificationTokensTable = sqliteTable(
75
- "verificationToken" as string,
76
- {
77
- identifier: text("identifier").notNull(),
78
- token: text("token").notNull().unique(),
79
- expires: integer("expires", { mode: "timestamp_ms" }).notNull(),
80
- },
81
- (vt) => ({
82
- compositePk: primaryKey({ columns: [vt.identifier, vt.token] }),
83
- })
84
- )
20
+
21
+ export function defineTables(
22
+ schema: Partial<DefaultSQLiteSchema> = {}
23
+ ): Required<DefaultSQLiteSchema> {
24
+ const usersTable =
25
+ schema.usersTable ??
26
+ (sqliteTable("user", {
27
+ id: text("id")
28
+ .primaryKey()
29
+ .$defaultFn(() => crypto.randomUUID()),
30
+ name: text("name"),
31
+ email: text("email").notNull(),
32
+ emailVerified: integer("emailVerified", { mode: "timestamp_ms" }),
33
+ image: text("image"),
34
+ }) satisfies DefaultSQLiteUsersTable)
35
+
36
+ const accountsTable =
37
+ schema.accountsTable ??
38
+ (sqliteTable(
39
+ "account",
40
+ {
41
+ userId: text("userId")
42
+ .notNull()
43
+ .references(() => usersTable.id, { onDelete: "cascade" }),
44
+ type: text("type").$type<AdapterAccountType>().notNull(),
45
+ provider: text("provider").notNull(),
46
+ providerAccountId: text("providerAccountId").notNull(),
47
+ refresh_token: text("refresh_token"),
48
+ access_token: text("access_token"),
49
+ expires_at: integer("expires_at"),
50
+ token_type: text("token_type"),
51
+ scope: text("scope"),
52
+ id_token: text("id_token"),
53
+ session_state: text("session_state"),
54
+ },
55
+ (account) => ({
56
+ compositePk: primaryKey({
57
+ columns: [account.provider, account.providerAccountId],
58
+ }),
59
+ })
60
+ ) satisfies DefaultSQLiteAccountsTable)
61
+
62
+ const sessionsTable =
63
+ schema.sessionsTable ??
64
+ (sqliteTable("session", {
65
+ sessionToken: text("sessionToken").primaryKey(),
66
+ userId: text("userId")
67
+ .notNull()
68
+ .references(() => usersTable.id, { onDelete: "cascade" }),
69
+ expires: integer("expires", { mode: "timestamp_ms" }).notNull(),
70
+ }) satisfies DefaultSQLiteSessionsTable)
71
+
72
+ const verificationTokensTable =
73
+ schema.verificationTokensTable ??
74
+ (sqliteTable(
75
+ "verificationToken",
76
+ {
77
+ identifier: text("identifier").notNull(),
78
+ token: text("token").notNull(),
79
+ expires: integer("expires", { mode: "timestamp_ms" }).notNull(),
80
+ },
81
+ (vt) => ({
82
+ compositePk: primaryKey({ columns: [vt.identifier, vt.token] }),
83
+ })
84
+ ) satisfies DefaultSQLiteVerificationTokenTable)
85
+
86
+ return {
87
+ usersTable,
88
+ accountsTable,
89
+ sessionsTable,
90
+ verificationTokensTable,
91
+ }
92
+ }
85
93
 
86
94
  export function SQLiteDrizzleAdapter(
87
95
  client: BaseSQLiteDatabase<"sync" | "async", any, any>,
88
- schema: DefaultSQLiteSchema = {
89
- usersTable: sqliteUsersTable,
90
- accountsTable: sqliteAccountsTable,
91
- sessionsTable: sqliteSessionsTable,
92
- verificationTokensTable: sqliteVerificationTokensTable,
93
- }
96
+ schema?: DefaultSQLiteSchema
94
97
  ): Adapter {
95
98
  const { usersTable, accountsTable, sessionsTable, verificationTokensTable } =
96
- schema
99
+ defineTables(schema)
97
100
 
98
101
  return {
99
- async createUser(data: Omit<AdapterUser, "id">) {
100
- return client.insert(usersTable).values(data).returning().get()
102
+ async createUser(data: AdapterUser) {
103
+ const { id, ...insertData } = data
104
+ const hasDefaultId = getTableColumns(usersTable)["id"]["hasDefault"]
105
+
106
+ return client
107
+ .insert(usersTable)
108
+ .values(hasDefaultId ? insertData : { ...insertData, id })
109
+ .returning()
110
+ .get()
101
111
  },
102
112
  async getUser(userId: string) {
103
113
  const result = await client
@@ -236,18 +246,192 @@ export function SQLiteDrizzleAdapter(
236
246
  }
237
247
  }
238
248
 
239
- export type SQLiteTableFn<T extends TableConfig> = SQLiteTableWithColumns<{
240
- name: T["name"]
241
- columns: T["columns"]
242
- dialect: T["dialect"]
249
+ type DefaultSQLiteColumn<
250
+ T extends {
251
+ data: string | number | Date
252
+ dataType: "string" | "number" | "date"
253
+ notNull: boolean
254
+ columnType: "SQLiteText" | "SQLiteTimestamp" | "SQLiteInteger"
255
+ },
256
+ > = SQLiteColumn<{
257
+ name: string
258
+ columnType: T["columnType"]
259
+ data: T["data"]
260
+ driverParam: string | number
261
+ notNull: T["notNull"]
262
+ hasDefault: boolean
263
+ enumValues: any
264
+ dataType: T["dataType"]
265
+ tableName: string
266
+ }>
267
+
268
+ export type DefaultSQLiteUsersTable = SQLiteTableWithColumns<{
269
+ name: string
270
+ columns: {
271
+ id: DefaultSQLiteColumn<{
272
+ columnType: "SQLiteText"
273
+ data: string
274
+ notNull: true
275
+ dataType: "string"
276
+ }>
277
+ name: DefaultSQLiteColumn<{
278
+ columnType: "SQLiteText"
279
+ data: string
280
+ notNull: boolean
281
+ dataType: "string"
282
+ }>
283
+ email: DefaultSQLiteColumn<{
284
+ columnType: "SQLiteText"
285
+ data: string
286
+ notNull: true
287
+ dataType: "string"
288
+ }>
289
+ emailVerified: DefaultSQLiteColumn<{
290
+ dataType: "date"
291
+ columnType: "SQLiteTimestamp"
292
+ data: Date
293
+ notNull: boolean
294
+ }>
295
+ image: DefaultSQLiteColumn<{
296
+ dataType: "string"
297
+ columnType: "SQLiteText"
298
+ data: string
299
+ notNull: boolean
300
+ }>
301
+ }
302
+ dialect: "sqlite"
303
+ schema: string | undefined
304
+ }>
305
+
306
+ export type DefaultSQLiteAccountsTable = SQLiteTableWithColumns<{
307
+ name: string
308
+ columns: {
309
+ userId: DefaultSQLiteColumn<{
310
+ columnType: "SQLiteText"
311
+ data: string
312
+ notNull: true
313
+ dataType: "string"
314
+ }>
315
+ type: DefaultSQLiteColumn<{
316
+ columnType: "SQLiteText"
317
+ data: string
318
+ notNull: true
319
+ dataType: "string"
320
+ }>
321
+ provider: DefaultSQLiteColumn<{
322
+ columnType: "SQLiteText"
323
+ data: string
324
+ notNull: true
325
+ dataType: "string"
326
+ }>
327
+ providerAccountId: DefaultSQLiteColumn<{
328
+ dataType: "string"
329
+ columnType: "SQLiteText"
330
+ data: string
331
+ notNull: true
332
+ }>
333
+ refresh_token: DefaultSQLiteColumn<{
334
+ dataType: "string"
335
+ columnType: "SQLiteText"
336
+ data: string
337
+ notNull: boolean
338
+ }>
339
+ access_token: DefaultSQLiteColumn<{
340
+ dataType: "string"
341
+ columnType: "SQLiteText"
342
+ data: string
343
+ notNull: boolean
344
+ }>
345
+ expires_at: DefaultSQLiteColumn<{
346
+ dataType: "number"
347
+ columnType: "SQLiteInteger"
348
+ data: number
349
+ notNull: boolean
350
+ }>
351
+ token_type: DefaultSQLiteColumn<{
352
+ dataType: "string"
353
+ columnType: "SQLiteText"
354
+ data: string
355
+ notNull: boolean
356
+ }>
357
+ scope: DefaultSQLiteColumn<{
358
+ dataType: "string"
359
+ columnType: "SQLiteText"
360
+ data: string
361
+ notNull: boolean
362
+ }>
363
+ id_token: DefaultSQLiteColumn<{
364
+ dataType: "string"
365
+ columnType: "SQLiteText"
366
+ data: string
367
+ notNull: boolean
368
+ }>
369
+ session_state: DefaultSQLiteColumn<{
370
+ dataType: "string"
371
+ columnType: "SQLiteText"
372
+ data: string
373
+ notNull: boolean
374
+ }>
375
+ }
376
+ dialect: "sqlite"
377
+ schema: string | undefined
378
+ }>
379
+
380
+ export type DefaultSQLiteSessionsTable = SQLiteTableWithColumns<{
381
+ name: string
382
+ columns: {
383
+ sessionToken: DefaultSQLiteColumn<{
384
+ columnType: "SQLiteText"
385
+ data: string
386
+ notNull: true
387
+ dataType: "string"
388
+ }>
389
+ userId: DefaultSQLiteColumn<{
390
+ columnType: "SQLiteText"
391
+ data: string
392
+ notNull: true
393
+ dataType: "string"
394
+ }>
395
+ expires: DefaultSQLiteColumn<{
396
+ dataType: "date"
397
+ columnType: "SQLiteTimestamp"
398
+ data: Date
399
+ notNull: true
400
+ }>
401
+ }
402
+ dialect: "sqlite"
403
+ schema: string | undefined
404
+ }>
405
+
406
+ export type DefaultSQLiteVerificationTokenTable = SQLiteTableWithColumns<{
407
+ name: string
408
+ columns: {
409
+ identifier: DefaultSQLiteColumn<{
410
+ columnType: "SQLiteText"
411
+ data: string
412
+ notNull: true
413
+ dataType: "string"
414
+ }>
415
+ token: DefaultSQLiteColumn<{
416
+ columnType: "SQLiteText"
417
+ data: string
418
+ notNull: true
419
+ dataType: "string"
420
+ }>
421
+ expires: DefaultSQLiteColumn<{
422
+ dataType: "date"
423
+ columnType: "SQLiteTimestamp"
424
+ data: Date
425
+ notNull: true
426
+ }>
427
+ }
428
+ dialect: "sqlite"
243
429
  schema: string | undefined
244
430
  }>
245
431
 
246
432
  export type DefaultSQLiteSchema = {
247
- usersTable: SQLiteTableFn<(typeof sqliteUsersTable)["_"]["config"]>
248
- accountsTable: SQLiteTableFn<(typeof sqliteAccountsTable)["_"]["config"]>
249
- sessionsTable: SQLiteTableFn<(typeof sqliteSessionsTable)["_"]["config"]>
250
- verificationTokensTable: SQLiteTableFn<
251
- (typeof sqliteVerificationTokensTable)["_"]["config"]
252
- >
433
+ usersTable: DefaultSQLiteUsersTable
434
+ accountsTable: DefaultSQLiteAccountsTable
435
+ sessionsTable?: DefaultSQLiteSessionsTable
436
+ verificationTokensTable?: DefaultSQLiteVerificationTokenTable
253
437
  }
package/src/lib/utils.ts CHANGED
@@ -1,14 +1,14 @@
1
- import { MySqlDatabase } from "drizzle-orm/mysql-core"
2
- import { PgDatabase } from "drizzle-orm/pg-core"
3
- import { BaseSQLiteDatabase } from "drizzle-orm/sqlite-core"
4
1
  import type {
5
2
  QueryResultHKT as MySQLQueryResultHKT,
6
3
  PreparedQueryHKTBase,
7
4
  } from "drizzle-orm/mysql-core"
5
+ import { MySqlDatabase } from "drizzle-orm/mysql-core"
8
6
  import type { QueryResultHKT as PostgresQueryResultHKT } from "drizzle-orm/pg-core"
9
- import { DefaultSQLiteSchema } from "./sqlite"
10
- import { DefaultPostgresSchema } from "./pg"
11
- import { DefaultMySqlSchema } from "./mysql"
7
+ import { PgDatabase } from "drizzle-orm/pg-core"
8
+ import { BaseSQLiteDatabase } from "drizzle-orm/sqlite-core"
9
+ import { DefaultMySqlSchema } from "./mysql.js"
10
+ import { DefaultPostgresSchema } from "./pg.js"
11
+ import { DefaultSQLiteSchema } from "./sqlite.js"
12
12
 
13
13
  type AnyPostgresDatabase = PgDatabase<PostgresQueryResultHKT, any>
14
14
  type AnyMySqlDatabase = MySqlDatabase<
@@ -23,10 +23,11 @@ export type SqlFlavorOptions =
23
23
  | AnyMySqlDatabase
24
24
  | AnySQLiteDatabase
25
25
 
26
- export type DefaultSchema<Flavor> = Flavor extends AnyMySqlDatabase
27
- ? DefaultMySqlSchema
28
- : Flavor extends AnyPostgresDatabase
29
- ? DefaultPostgresSchema
30
- : Flavor extends AnySQLiteDatabase
31
- ? DefaultSQLiteSchema
32
- : never
26
+ export type DefaultSchema<Flavor extends SqlFlavorOptions> =
27
+ Flavor extends AnyMySqlDatabase
28
+ ? DefaultMySqlSchema
29
+ : Flavor extends AnyPostgresDatabase
30
+ ? DefaultPostgresSchema
31
+ : Flavor extends AnySQLiteDatabase
32
+ ? DefaultSQLiteSchema
33
+ : never