@auth/drizzle-adapter 0.3.0 → 0.3.2
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/index.d.ts.map +1 -1
- package/index.js +8 -6
- package/lib/mysql.d.ts +225 -0
- package/lib/mysql.d.ts.map +1 -0
- package/lib/mysql.js +189 -0
- package/lib/pg.d.ts +225 -0
- package/lib/pg.d.ts.map +1 -0
- package/lib/pg.js +180 -0
- package/lib/sqlite.d.ts +225 -0
- package/lib/sqlite.d.ts.map +1 -0
- package/lib/sqlite.js +154 -0
- package/lib/utils.d.ts +21 -0
- package/lib/utils.d.ts.map +1 -0
- package/lib/utils.js +1 -0
- package/package.json +3 -3
- package/src/index.ts +11 -19
- package/src/lib/mysql.ts +3 -6
- package/src/lib/pg.ts +2 -2
- package/src/lib/sqlite.ts +1 -1
- package/src/lib/utils.ts +0 -14
package/lib/pg.js
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { and, eq } from "drizzle-orm";
|
|
2
|
+
import { timestamp, pgTable as defaultPgTableFn, text, primaryKey, integer, } from "drizzle-orm/pg-core";
|
|
3
|
+
export function createTables(pgTable) {
|
|
4
|
+
const users = pgTable("user", {
|
|
5
|
+
id: text("id").notNull().primaryKey(),
|
|
6
|
+
name: text("name"),
|
|
7
|
+
email: text("email").notNull(),
|
|
8
|
+
emailVerified: timestamp("emailVerified", { mode: "date" }),
|
|
9
|
+
image: text("image"),
|
|
10
|
+
});
|
|
11
|
+
const accounts = pgTable("account", {
|
|
12
|
+
userId: text("userId")
|
|
13
|
+
.notNull()
|
|
14
|
+
.references(() => users.id, { onDelete: "cascade" }),
|
|
15
|
+
type: text("type").$type().notNull(),
|
|
16
|
+
provider: text("provider").notNull(),
|
|
17
|
+
providerAccountId: text("providerAccountId").notNull(),
|
|
18
|
+
refresh_token: text("refresh_token"),
|
|
19
|
+
access_token: text("access_token"),
|
|
20
|
+
expires_at: integer("expires_at"),
|
|
21
|
+
token_type: text("token_type"),
|
|
22
|
+
scope: text("scope"),
|
|
23
|
+
id_token: text("id_token"),
|
|
24
|
+
session_state: text("session_state"),
|
|
25
|
+
}, (account) => ({
|
|
26
|
+
compoundKey: primaryKey(account.provider, account.providerAccountId),
|
|
27
|
+
}));
|
|
28
|
+
const sessions = pgTable("session", {
|
|
29
|
+
sessionToken: text("sessionToken").notNull().primaryKey(),
|
|
30
|
+
userId: text("userId")
|
|
31
|
+
.notNull()
|
|
32
|
+
.references(() => users.id, { onDelete: "cascade" }),
|
|
33
|
+
expires: timestamp("expires", { mode: "date" }).notNull(),
|
|
34
|
+
});
|
|
35
|
+
const verificationTokens = pgTable("verificationToken", {
|
|
36
|
+
identifier: text("identifier").notNull(),
|
|
37
|
+
token: text("token").notNull(),
|
|
38
|
+
expires: timestamp("expires", { mode: "date" }).notNull(),
|
|
39
|
+
}, (vt) => ({
|
|
40
|
+
compoundKey: primaryKey(vt.identifier, vt.token),
|
|
41
|
+
}));
|
|
42
|
+
return { users, accounts, sessions, verificationTokens };
|
|
43
|
+
}
|
|
44
|
+
export function pgDrizzleAdapter(client, tableFn = defaultPgTableFn) {
|
|
45
|
+
const { users, accounts, sessions, verificationTokens } = createTables(tableFn);
|
|
46
|
+
return {
|
|
47
|
+
async createUser(data) {
|
|
48
|
+
return await client
|
|
49
|
+
.insert(users)
|
|
50
|
+
.values({ ...data, id: crypto.randomUUID() })
|
|
51
|
+
.returning()
|
|
52
|
+
.then((res) => res[0] ?? null);
|
|
53
|
+
},
|
|
54
|
+
async getUser(data) {
|
|
55
|
+
return await client
|
|
56
|
+
.select()
|
|
57
|
+
.from(users)
|
|
58
|
+
.where(eq(users.id, data))
|
|
59
|
+
.then((res) => res[0] ?? null);
|
|
60
|
+
},
|
|
61
|
+
async getUserByEmail(data) {
|
|
62
|
+
return await client
|
|
63
|
+
.select()
|
|
64
|
+
.from(users)
|
|
65
|
+
.where(eq(users.email, data))
|
|
66
|
+
.then((res) => res[0] ?? null);
|
|
67
|
+
},
|
|
68
|
+
async createSession(data) {
|
|
69
|
+
return await client
|
|
70
|
+
.insert(sessions)
|
|
71
|
+
.values(data)
|
|
72
|
+
.returning()
|
|
73
|
+
.then((res) => res[0]);
|
|
74
|
+
},
|
|
75
|
+
async getSessionAndUser(data) {
|
|
76
|
+
return await client
|
|
77
|
+
.select({
|
|
78
|
+
session: sessions,
|
|
79
|
+
user: users,
|
|
80
|
+
})
|
|
81
|
+
.from(sessions)
|
|
82
|
+
.where(eq(sessions.sessionToken, data))
|
|
83
|
+
.innerJoin(users, eq(users.id, sessions.userId))
|
|
84
|
+
.then((res) => res[0] ?? null);
|
|
85
|
+
},
|
|
86
|
+
async updateUser(data) {
|
|
87
|
+
if (!data.id) {
|
|
88
|
+
throw new Error("No user id.");
|
|
89
|
+
}
|
|
90
|
+
return await client
|
|
91
|
+
.update(users)
|
|
92
|
+
.set(data)
|
|
93
|
+
.where(eq(users.id, data.id))
|
|
94
|
+
.returning()
|
|
95
|
+
.then((res) => res[0]);
|
|
96
|
+
},
|
|
97
|
+
async updateSession(data) {
|
|
98
|
+
return await client
|
|
99
|
+
.update(sessions)
|
|
100
|
+
.set(data)
|
|
101
|
+
.where(eq(sessions.sessionToken, data.sessionToken))
|
|
102
|
+
.returning()
|
|
103
|
+
.then((res) => res[0]);
|
|
104
|
+
},
|
|
105
|
+
async linkAccount(rawAccount) {
|
|
106
|
+
const updatedAccount = await client
|
|
107
|
+
.insert(accounts)
|
|
108
|
+
.values(rawAccount)
|
|
109
|
+
.returning()
|
|
110
|
+
.then((res) => res[0]);
|
|
111
|
+
// Drizzle will return `null` for fields that are not defined.
|
|
112
|
+
// However, the return type is expecting `undefined`.
|
|
113
|
+
const account = {
|
|
114
|
+
...updatedAccount,
|
|
115
|
+
access_token: updatedAccount.access_token ?? undefined,
|
|
116
|
+
token_type: updatedAccount.token_type ?? undefined,
|
|
117
|
+
id_token: updatedAccount.id_token ?? undefined,
|
|
118
|
+
refresh_token: updatedAccount.refresh_token ?? undefined,
|
|
119
|
+
scope: updatedAccount.scope ?? undefined,
|
|
120
|
+
expires_at: updatedAccount.expires_at ?? undefined,
|
|
121
|
+
session_state: updatedAccount.session_state ?? undefined,
|
|
122
|
+
};
|
|
123
|
+
return account;
|
|
124
|
+
},
|
|
125
|
+
async getUserByAccount(account) {
|
|
126
|
+
const dbAccount = (await client
|
|
127
|
+
.select()
|
|
128
|
+
.from(accounts)
|
|
129
|
+
.where(and(eq(accounts.providerAccountId, account.providerAccountId), eq(accounts.provider, account.provider)))
|
|
130
|
+
.leftJoin(users, eq(accounts.userId, users.id))
|
|
131
|
+
.then((res) => res[0])) ?? null;
|
|
132
|
+
if (!dbAccount) {
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
return dbAccount.user;
|
|
136
|
+
},
|
|
137
|
+
async deleteSession(sessionToken) {
|
|
138
|
+
const session = await client
|
|
139
|
+
.delete(sessions)
|
|
140
|
+
.where(eq(sessions.sessionToken, sessionToken))
|
|
141
|
+
.returning()
|
|
142
|
+
.then((res) => res[0] ?? null);
|
|
143
|
+
return session;
|
|
144
|
+
},
|
|
145
|
+
async createVerificationToken(token) {
|
|
146
|
+
return await client
|
|
147
|
+
.insert(verificationTokens)
|
|
148
|
+
.values(token)
|
|
149
|
+
.returning()
|
|
150
|
+
.then((res) => res[0]);
|
|
151
|
+
},
|
|
152
|
+
async useVerificationToken(token) {
|
|
153
|
+
try {
|
|
154
|
+
return await client
|
|
155
|
+
.delete(verificationTokens)
|
|
156
|
+
.where(and(eq(verificationTokens.identifier, token.identifier), eq(verificationTokens.token, token.token)))
|
|
157
|
+
.returning()
|
|
158
|
+
.then((res) => res[0] ?? null);
|
|
159
|
+
}
|
|
160
|
+
catch (err) {
|
|
161
|
+
throw new Error("No verification token found.");
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
async deleteUser(id) {
|
|
165
|
+
await client
|
|
166
|
+
.delete(users)
|
|
167
|
+
.where(eq(users.id, id))
|
|
168
|
+
.returning()
|
|
169
|
+
.then((res) => res[0] ?? null);
|
|
170
|
+
},
|
|
171
|
+
async unlinkAccount(account) {
|
|
172
|
+
const { type, provider, providerAccountId, userId } = await client
|
|
173
|
+
.delete(accounts)
|
|
174
|
+
.where(and(eq(accounts.providerAccountId, account.providerAccountId), eq(accounts.provider, account.provider)))
|
|
175
|
+
.returning()
|
|
176
|
+
.then((res) => res[0] ?? null);
|
|
177
|
+
return { provider, type, providerAccountId, userId };
|
|
178
|
+
},
|
|
179
|
+
};
|
|
180
|
+
}
|
package/lib/sqlite.d.ts
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import { BaseSQLiteDatabase, SQLiteTableFn } from "drizzle-orm/sqlite-core";
|
|
2
|
+
import type { Adapter } from "@auth/core/adapters";
|
|
3
|
+
export declare function createTables(sqliteTable: SQLiteTableFn): {
|
|
4
|
+
users: import("drizzle-orm/db.d-b5fdf746").ag<{
|
|
5
|
+
name: "user";
|
|
6
|
+
schema: undefined;
|
|
7
|
+
columns: {
|
|
8
|
+
id: import("drizzle-orm/sqlite-core").SQLiteText<{
|
|
9
|
+
tableName: "user";
|
|
10
|
+
enumValues: [string, ...string[]];
|
|
11
|
+
name: "id";
|
|
12
|
+
data: string;
|
|
13
|
+
driverParam: string;
|
|
14
|
+
hasDefault: false;
|
|
15
|
+
notNull: true;
|
|
16
|
+
}>;
|
|
17
|
+
name: import("drizzle-orm/sqlite-core").SQLiteText<{
|
|
18
|
+
tableName: "user";
|
|
19
|
+
name: "name";
|
|
20
|
+
data: string;
|
|
21
|
+
driverParam: string;
|
|
22
|
+
enumValues: [string, ...string[]];
|
|
23
|
+
notNull: false;
|
|
24
|
+
hasDefault: false;
|
|
25
|
+
}>;
|
|
26
|
+
email: import("drizzle-orm/sqlite-core").SQLiteText<{
|
|
27
|
+
tableName: "user";
|
|
28
|
+
enumValues: [string, ...string[]];
|
|
29
|
+
name: "email";
|
|
30
|
+
data: string;
|
|
31
|
+
driverParam: string;
|
|
32
|
+
hasDefault: false;
|
|
33
|
+
notNull: true;
|
|
34
|
+
}>;
|
|
35
|
+
emailVerified: import("drizzle-orm/sqlite-core").SQLiteTimestamp<{
|
|
36
|
+
tableName: "user";
|
|
37
|
+
name: "emailVerified";
|
|
38
|
+
data: Date;
|
|
39
|
+
driverParam: number;
|
|
40
|
+
notNull: false;
|
|
41
|
+
hasDefault: false;
|
|
42
|
+
}>;
|
|
43
|
+
image: import("drizzle-orm/sqlite-core").SQLiteText<{
|
|
44
|
+
tableName: "user";
|
|
45
|
+
name: "image";
|
|
46
|
+
data: string;
|
|
47
|
+
driverParam: string;
|
|
48
|
+
enumValues: [string, ...string[]];
|
|
49
|
+
notNull: false;
|
|
50
|
+
hasDefault: false;
|
|
51
|
+
}>;
|
|
52
|
+
};
|
|
53
|
+
}>;
|
|
54
|
+
accounts: import("drizzle-orm/db.d-b5fdf746").ag<{
|
|
55
|
+
name: "account";
|
|
56
|
+
schema: undefined;
|
|
57
|
+
columns: {
|
|
58
|
+
userId: import("drizzle-orm/sqlite-core").SQLiteText<{
|
|
59
|
+
tableName: "account";
|
|
60
|
+
enumValues: [string, ...string[]];
|
|
61
|
+
name: "userId";
|
|
62
|
+
data: string;
|
|
63
|
+
driverParam: string;
|
|
64
|
+
hasDefault: false;
|
|
65
|
+
notNull: true;
|
|
66
|
+
}>;
|
|
67
|
+
type: import("drizzle-orm/sqlite-core").SQLiteText<{
|
|
68
|
+
tableName: "account";
|
|
69
|
+
enumValues: [string, ...string[]];
|
|
70
|
+
name: "type";
|
|
71
|
+
data: "email" | "oidc" | "oauth";
|
|
72
|
+
driverParam: string;
|
|
73
|
+
hasDefault: false;
|
|
74
|
+
notNull: true;
|
|
75
|
+
}>;
|
|
76
|
+
provider: import("drizzle-orm/sqlite-core").SQLiteText<{
|
|
77
|
+
tableName: "account";
|
|
78
|
+
enumValues: [string, ...string[]];
|
|
79
|
+
name: "provider";
|
|
80
|
+
data: string;
|
|
81
|
+
driverParam: string;
|
|
82
|
+
hasDefault: false;
|
|
83
|
+
notNull: true;
|
|
84
|
+
}>;
|
|
85
|
+
providerAccountId: import("drizzle-orm/sqlite-core").SQLiteText<{
|
|
86
|
+
tableName: "account";
|
|
87
|
+
enumValues: [string, ...string[]];
|
|
88
|
+
name: "providerAccountId";
|
|
89
|
+
data: string;
|
|
90
|
+
driverParam: string;
|
|
91
|
+
hasDefault: false;
|
|
92
|
+
notNull: true;
|
|
93
|
+
}>;
|
|
94
|
+
refresh_token: import("drizzle-orm/sqlite-core").SQLiteText<{
|
|
95
|
+
tableName: "account";
|
|
96
|
+
name: "refresh_token";
|
|
97
|
+
data: string;
|
|
98
|
+
driverParam: string;
|
|
99
|
+
enumValues: [string, ...string[]];
|
|
100
|
+
notNull: false;
|
|
101
|
+
hasDefault: false;
|
|
102
|
+
}>;
|
|
103
|
+
access_token: import("drizzle-orm/sqlite-core").SQLiteText<{
|
|
104
|
+
tableName: "account";
|
|
105
|
+
name: "access_token";
|
|
106
|
+
data: string;
|
|
107
|
+
driverParam: string;
|
|
108
|
+
enumValues: [string, ...string[]];
|
|
109
|
+
notNull: false;
|
|
110
|
+
hasDefault: false;
|
|
111
|
+
}>;
|
|
112
|
+
expires_at: import("drizzle-orm/sqlite-core").SQLiteInteger<{
|
|
113
|
+
tableName: "account";
|
|
114
|
+
name: "expires_at";
|
|
115
|
+
data: number;
|
|
116
|
+
driverParam: number;
|
|
117
|
+
notNull: false;
|
|
118
|
+
hasDefault: false;
|
|
119
|
+
}>;
|
|
120
|
+
token_type: import("drizzle-orm/sqlite-core").SQLiteText<{
|
|
121
|
+
tableName: "account";
|
|
122
|
+
name: "token_type";
|
|
123
|
+
data: string;
|
|
124
|
+
driverParam: string;
|
|
125
|
+
enumValues: [string, ...string[]];
|
|
126
|
+
notNull: false;
|
|
127
|
+
hasDefault: false;
|
|
128
|
+
}>;
|
|
129
|
+
scope: import("drizzle-orm/sqlite-core").SQLiteText<{
|
|
130
|
+
tableName: "account";
|
|
131
|
+
name: "scope";
|
|
132
|
+
data: string;
|
|
133
|
+
driverParam: string;
|
|
134
|
+
enumValues: [string, ...string[]];
|
|
135
|
+
notNull: false;
|
|
136
|
+
hasDefault: false;
|
|
137
|
+
}>;
|
|
138
|
+
id_token: import("drizzle-orm/sqlite-core").SQLiteText<{
|
|
139
|
+
tableName: "account";
|
|
140
|
+
name: "id_token";
|
|
141
|
+
data: string;
|
|
142
|
+
driverParam: string;
|
|
143
|
+
enumValues: [string, ...string[]];
|
|
144
|
+
notNull: false;
|
|
145
|
+
hasDefault: false;
|
|
146
|
+
}>;
|
|
147
|
+
session_state: import("drizzle-orm/sqlite-core").SQLiteText<{
|
|
148
|
+
tableName: "account";
|
|
149
|
+
name: "session_state";
|
|
150
|
+
data: string;
|
|
151
|
+
driverParam: string;
|
|
152
|
+
enumValues: [string, ...string[]];
|
|
153
|
+
notNull: false;
|
|
154
|
+
hasDefault: false;
|
|
155
|
+
}>;
|
|
156
|
+
};
|
|
157
|
+
}>;
|
|
158
|
+
sessions: import("drizzle-orm/db.d-b5fdf746").ag<{
|
|
159
|
+
name: "session";
|
|
160
|
+
schema: undefined;
|
|
161
|
+
columns: {
|
|
162
|
+
sessionToken: import("drizzle-orm/sqlite-core").SQLiteText<{
|
|
163
|
+
tableName: "session";
|
|
164
|
+
enumValues: [string, ...string[]];
|
|
165
|
+
name: "sessionToken";
|
|
166
|
+
data: string;
|
|
167
|
+
driverParam: string;
|
|
168
|
+
hasDefault: false;
|
|
169
|
+
notNull: true;
|
|
170
|
+
}>;
|
|
171
|
+
userId: import("drizzle-orm/sqlite-core").SQLiteText<{
|
|
172
|
+
tableName: "session";
|
|
173
|
+
enumValues: [string, ...string[]];
|
|
174
|
+
name: "userId";
|
|
175
|
+
data: string;
|
|
176
|
+
driverParam: string;
|
|
177
|
+
hasDefault: false;
|
|
178
|
+
notNull: true;
|
|
179
|
+
}>;
|
|
180
|
+
expires: import("drizzle-orm/sqlite-core").SQLiteTimestamp<{
|
|
181
|
+
tableName: "session";
|
|
182
|
+
name: "expires";
|
|
183
|
+
data: Date;
|
|
184
|
+
driverParam: number;
|
|
185
|
+
hasDefault: false;
|
|
186
|
+
notNull: true;
|
|
187
|
+
}>;
|
|
188
|
+
};
|
|
189
|
+
}>;
|
|
190
|
+
verificationTokens: import("drizzle-orm/db.d-b5fdf746").ag<{
|
|
191
|
+
name: "verificationToken";
|
|
192
|
+
schema: undefined;
|
|
193
|
+
columns: {
|
|
194
|
+
identifier: import("drizzle-orm/sqlite-core").SQLiteText<{
|
|
195
|
+
tableName: "verificationToken";
|
|
196
|
+
enumValues: [string, ...string[]];
|
|
197
|
+
name: "identifier";
|
|
198
|
+
data: string;
|
|
199
|
+
driverParam: string;
|
|
200
|
+
hasDefault: false;
|
|
201
|
+
notNull: true;
|
|
202
|
+
}>;
|
|
203
|
+
token: import("drizzle-orm/sqlite-core").SQLiteText<{
|
|
204
|
+
tableName: "verificationToken";
|
|
205
|
+
enumValues: [string, ...string[]];
|
|
206
|
+
name: "token";
|
|
207
|
+
data: string;
|
|
208
|
+
driverParam: string;
|
|
209
|
+
hasDefault: false;
|
|
210
|
+
notNull: true;
|
|
211
|
+
}>;
|
|
212
|
+
expires: import("drizzle-orm/sqlite-core").SQLiteTimestamp<{
|
|
213
|
+
tableName: "verificationToken";
|
|
214
|
+
name: "expires";
|
|
215
|
+
data: Date;
|
|
216
|
+
driverParam: number;
|
|
217
|
+
hasDefault: false;
|
|
218
|
+
notNull: true;
|
|
219
|
+
}>;
|
|
220
|
+
};
|
|
221
|
+
}>;
|
|
222
|
+
};
|
|
223
|
+
export type DefaultSchema = ReturnType<typeof createTables>;
|
|
224
|
+
export declare function SQLiteDrizzleAdapter(client: InstanceType<typeof BaseSQLiteDatabase>, tableFn?: SQLiteTableFn<undefined>): Adapter;
|
|
225
|
+
//# sourceMappingURL=sqlite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../src/lib/sqlite.ts"],"names":[],"mappings":"AACA,OAAO,EAKL,kBAAkB,EAClB,aAAa,EACd,MAAM,yBAAyB,CAAA;AAEhC,OAAO,KAAK,EAAE,OAAO,EAAkB,MAAM,qBAAqB,CAAA;AAElE,wBAAgB,YAAY,CAAC,WAAW,EAAE,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoDtD;AAED,MAAM,MAAM,aAAa,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAA;AAE3D,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,YAAY,CAAC,OAAO,kBAAkB,CAAC,EAC/C,OAAO,2BAAuB,GAC7B,OAAO,CA2IT"}
|
package/lib/sqlite.js
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { eq, and } from "drizzle-orm";
|
|
2
|
+
import { integer, sqliteTable as defaultSqliteTableFn, text, primaryKey, } from "drizzle-orm/sqlite-core";
|
|
3
|
+
export function createTables(sqliteTable) {
|
|
4
|
+
const users = sqliteTable("user", {
|
|
5
|
+
id: text("id").notNull().primaryKey(),
|
|
6
|
+
name: text("name"),
|
|
7
|
+
email: text("email").notNull(),
|
|
8
|
+
emailVerified: integer("emailVerified", { mode: "timestamp_ms" }),
|
|
9
|
+
image: text("image"),
|
|
10
|
+
});
|
|
11
|
+
const accounts = sqliteTable("account", {
|
|
12
|
+
userId: text("userId")
|
|
13
|
+
.notNull()
|
|
14
|
+
.references(() => users.id, { onDelete: "cascade" }),
|
|
15
|
+
type: text("type").$type().notNull(),
|
|
16
|
+
provider: text("provider").notNull(),
|
|
17
|
+
providerAccountId: text("providerAccountId").notNull(),
|
|
18
|
+
refresh_token: text("refresh_token"),
|
|
19
|
+
access_token: text("access_token"),
|
|
20
|
+
expires_at: integer("expires_at"),
|
|
21
|
+
token_type: text("token_type"),
|
|
22
|
+
scope: text("scope"),
|
|
23
|
+
id_token: text("id_token"),
|
|
24
|
+
session_state: text("session_state"),
|
|
25
|
+
}, (account) => ({
|
|
26
|
+
compoundKey: primaryKey(account.provider, account.providerAccountId),
|
|
27
|
+
}));
|
|
28
|
+
const sessions = sqliteTable("session", {
|
|
29
|
+
sessionToken: text("sessionToken").notNull().primaryKey(),
|
|
30
|
+
userId: text("userId")
|
|
31
|
+
.notNull()
|
|
32
|
+
.references(() => users.id, { onDelete: "cascade" }),
|
|
33
|
+
expires: integer("expires", { mode: "timestamp_ms" }).notNull(),
|
|
34
|
+
});
|
|
35
|
+
const verificationTokens = sqliteTable("verificationToken", {
|
|
36
|
+
identifier: text("identifier").notNull(),
|
|
37
|
+
token: text("token").notNull(),
|
|
38
|
+
expires: integer("expires", { mode: "timestamp_ms" }).notNull(),
|
|
39
|
+
}, (vt) => ({
|
|
40
|
+
compoundKey: primaryKey(vt.identifier, vt.token),
|
|
41
|
+
}));
|
|
42
|
+
return { users, accounts, sessions, verificationTokens };
|
|
43
|
+
}
|
|
44
|
+
export function SQLiteDrizzleAdapter(client, tableFn = defaultSqliteTableFn) {
|
|
45
|
+
const { users, accounts, sessions, verificationTokens } = createTables(tableFn);
|
|
46
|
+
return {
|
|
47
|
+
createUser(data) {
|
|
48
|
+
return client
|
|
49
|
+
.insert(users)
|
|
50
|
+
.values({ ...data, id: crypto.randomUUID() })
|
|
51
|
+
.returning()
|
|
52
|
+
.get();
|
|
53
|
+
},
|
|
54
|
+
getUser(data) {
|
|
55
|
+
return client.select().from(users).where(eq(users.id, data)).get() ?? null;
|
|
56
|
+
},
|
|
57
|
+
getUserByEmail(data) {
|
|
58
|
+
return (client.select().from(users).where(eq(users.email, data)).get() ?? null);
|
|
59
|
+
},
|
|
60
|
+
createSession(data) {
|
|
61
|
+
return client.insert(sessions).values(data).returning().get();
|
|
62
|
+
},
|
|
63
|
+
getSessionAndUser(data) {
|
|
64
|
+
return (client
|
|
65
|
+
.select({
|
|
66
|
+
session: sessions,
|
|
67
|
+
user: users,
|
|
68
|
+
})
|
|
69
|
+
.from(sessions)
|
|
70
|
+
.where(eq(sessions.sessionToken, data))
|
|
71
|
+
.innerJoin(users, eq(users.id, sessions.userId))
|
|
72
|
+
.get() ?? null);
|
|
73
|
+
},
|
|
74
|
+
updateUser(data) {
|
|
75
|
+
if (!data.id) {
|
|
76
|
+
throw new Error("No user id.");
|
|
77
|
+
}
|
|
78
|
+
return client
|
|
79
|
+
.update(users)
|
|
80
|
+
.set(data)
|
|
81
|
+
.where(eq(users.id, data.id))
|
|
82
|
+
.returning()
|
|
83
|
+
.get();
|
|
84
|
+
},
|
|
85
|
+
updateSession(data) {
|
|
86
|
+
return client
|
|
87
|
+
.update(sessions)
|
|
88
|
+
.set(data)
|
|
89
|
+
.where(eq(sessions.sessionToken, data.sessionToken))
|
|
90
|
+
.returning()
|
|
91
|
+
.get();
|
|
92
|
+
},
|
|
93
|
+
linkAccount(rawAccount) {
|
|
94
|
+
const updatedAccount = client
|
|
95
|
+
.insert(accounts)
|
|
96
|
+
.values(rawAccount)
|
|
97
|
+
.returning()
|
|
98
|
+
.get();
|
|
99
|
+
const account = {
|
|
100
|
+
...updatedAccount,
|
|
101
|
+
type: updatedAccount.type,
|
|
102
|
+
access_token: updatedAccount.access_token ?? undefined,
|
|
103
|
+
token_type: updatedAccount.token_type ?? undefined,
|
|
104
|
+
id_token: updatedAccount.id_token ?? undefined,
|
|
105
|
+
refresh_token: updatedAccount.refresh_token ?? undefined,
|
|
106
|
+
scope: updatedAccount.scope ?? undefined,
|
|
107
|
+
expires_at: updatedAccount.expires_at ?? undefined,
|
|
108
|
+
session_state: updatedAccount.session_state ?? undefined,
|
|
109
|
+
};
|
|
110
|
+
return account;
|
|
111
|
+
},
|
|
112
|
+
getUserByAccount(account) {
|
|
113
|
+
const results = client
|
|
114
|
+
.select()
|
|
115
|
+
.from(accounts)
|
|
116
|
+
.leftJoin(users, eq(users.id, accounts.userId))
|
|
117
|
+
.where(and(eq(accounts.provider, account.provider), eq(accounts.providerAccountId, account.providerAccountId)))
|
|
118
|
+
.get();
|
|
119
|
+
return results?.user ?? null;
|
|
120
|
+
},
|
|
121
|
+
deleteSession(sessionToken) {
|
|
122
|
+
return (client
|
|
123
|
+
.delete(sessions)
|
|
124
|
+
.where(eq(sessions.sessionToken, sessionToken))
|
|
125
|
+
.returning()
|
|
126
|
+
.get() ?? null);
|
|
127
|
+
},
|
|
128
|
+
createVerificationToken(token) {
|
|
129
|
+
return client.insert(verificationTokens).values(token).returning().get();
|
|
130
|
+
},
|
|
131
|
+
useVerificationToken(token) {
|
|
132
|
+
try {
|
|
133
|
+
return (client
|
|
134
|
+
.delete(verificationTokens)
|
|
135
|
+
.where(and(eq(verificationTokens.identifier, token.identifier), eq(verificationTokens.token, token.token)))
|
|
136
|
+
.returning()
|
|
137
|
+
.get() ?? null);
|
|
138
|
+
}
|
|
139
|
+
catch (err) {
|
|
140
|
+
throw new Error("No verification token found.");
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
deleteUser(id) {
|
|
144
|
+
return client.delete(users).where(eq(users.id, id)).returning().get();
|
|
145
|
+
},
|
|
146
|
+
unlinkAccount(account) {
|
|
147
|
+
client
|
|
148
|
+
.delete(accounts)
|
|
149
|
+
.where(and(eq(accounts.providerAccountId, account.providerAccountId), eq(accounts.provider, account.provider)))
|
|
150
|
+
.run();
|
|
151
|
+
return undefined;
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
}
|
package/lib/utils.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
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
|
+
import type { AnyMySqlTable, MySqlTableFn } from "drizzle-orm/mysql-core";
|
|
5
|
+
import type { AnyPgTable, PgTableFn } from "drizzle-orm/pg-core";
|
|
6
|
+
import type { AnySQLiteTable, SQLiteTableFn } from "drizzle-orm/sqlite-core";
|
|
7
|
+
import type { DefaultSchema as PgSchema } from "./pg.js";
|
|
8
|
+
import type { DefaultSchema as MySqlSchema } from "./mysql.js";
|
|
9
|
+
import type { DefaultSchema as SQLiteSchema } from "./sqlite.js";
|
|
10
|
+
export type AnyMySqlDatabase = MySqlDatabase<any, any>;
|
|
11
|
+
export type AnyPgDatabase = PgDatabase<any, any, any>;
|
|
12
|
+
export type AnySQLiteDatabase = BaseSQLiteDatabase<any, any, any, any>;
|
|
13
|
+
export interface MinimumSchema {
|
|
14
|
+
mysql: MySqlSchema & Record<string, AnyMySqlTable>;
|
|
15
|
+
pg: PgSchema & Record<string, AnyPgTable>;
|
|
16
|
+
sqlite: SQLiteSchema & Record<string, AnySQLiteTable>;
|
|
17
|
+
}
|
|
18
|
+
export type SqlFlavorOptions = AnyMySqlDatabase | AnyPgDatabase | AnySQLiteDatabase;
|
|
19
|
+
export type ClientFlavors<Flavor> = Flavor extends AnyMySqlDatabase ? MinimumSchema["mysql"] : Flavor extends AnyPgDatabase ? MinimumSchema["pg"] : Flavor extends AnySQLiteDatabase ? MinimumSchema["sqlite"] : never;
|
|
20
|
+
export type TableFn<Flavor> = Flavor extends AnyMySqlDatabase ? MySqlTableFn : Flavor extends AnyPgDatabase ? PgTableFn : Flavor extends AnySQLiteDatabase ? SQLiteTableFn : AnySQLiteTable;
|
|
21
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/lib/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAE5D,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AACzE,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAChE,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAA;AAC5E,OAAO,KAAK,EAAE,aAAa,IAAI,QAAQ,EAAE,MAAM,SAAS,CAAA;AACxD,OAAO,KAAK,EAAE,aAAa,IAAI,WAAW,EAAE,MAAM,YAAY,CAAA;AAC9D,OAAO,KAAK,EAAE,aAAa,IAAI,YAAY,EAAE,MAAM,aAAa,CAAA;AAEhE,MAAM,MAAM,gBAAgB,GAAG,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;AACtD,MAAM,MAAM,aAAa,GAAG,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;AACrD,MAAM,MAAM,iBAAiB,GAAG,kBAAkB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;AAEtE,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;IAClD,EAAE,EAAE,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;IACzC,MAAM,EAAE,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAA;CACtD;AAED,MAAM,MAAM,gBAAgB,GACxB,gBAAgB,GAChB,aAAa,GACb,iBAAiB,CAAA;AAErB,MAAM,MAAM,aAAa,CAAC,MAAM,IAAI,MAAM,SAAS,gBAAgB,GAC/D,aAAa,CAAC,OAAO,CAAC,GACtB,MAAM,SAAS,aAAa,GAC5B,aAAa,CAAC,IAAI,CAAC,GACnB,MAAM,SAAS,iBAAiB,GAChC,aAAa,CAAC,QAAQ,CAAC,GACvB,KAAK,CAAA;AAET,MAAM,MAAM,OAAO,CAAC,MAAM,IAAI,MAAM,SAAS,gBAAgB,GACzD,YAAY,GACZ,MAAM,SAAS,aAAa,GAC5B,SAAS,GACT,MAAM,SAAS,iBAAiB,GAChC,aAAa,GACb,cAAc,CAAA"}
|
package/lib/utils.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@auth/drizzle-adapter",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "Drizzle adapter for Auth.js.",
|
|
5
5
|
"homepage": "https://authjs.dev",
|
|
6
6
|
"repository": "https://github.com/nextauthjs/next-auth",
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
"type": "module",
|
|
12
12
|
"types": "./index.d.ts",
|
|
13
13
|
"files": [
|
|
14
|
-
"*.js",
|
|
15
14
|
"*.d.ts*",
|
|
15
|
+
"*.js",
|
|
16
16
|
"lib",
|
|
17
17
|
"src"
|
|
18
18
|
],
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"access": "public"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@auth/core": "0.
|
|
39
|
+
"@auth/core": "0.12.0"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@types/better-sqlite3": "^7.6.4",
|
package/src/index.ts
CHANGED
|
@@ -16,19 +16,14 @@
|
|
|
16
16
|
* @module @auth/drizzle-adapter
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
import { MySqlTableFn } from "drizzle-orm/mysql-core
|
|
20
|
-
import { PgTableFn } from "drizzle-orm/pg-core
|
|
21
|
-
import { SQLiteTableFn } from "drizzle-orm/sqlite-core
|
|
19
|
+
import { MySqlDatabase, MySqlTableFn } from "drizzle-orm/mysql-core"
|
|
20
|
+
import { PgDatabase, PgTableFn } from "drizzle-orm/pg-core"
|
|
21
|
+
import { BaseSQLiteDatabase, SQLiteTableFn } from "drizzle-orm/sqlite-core"
|
|
22
22
|
import { mySqlDrizzleAdapter } from "./lib/mysql.js"
|
|
23
23
|
import { pgDrizzleAdapter } from "./lib/pg.js"
|
|
24
24
|
import { SQLiteDrizzleAdapter } from "./lib/sqlite.js"
|
|
25
|
-
import {
|
|
26
|
-
|
|
27
|
-
isPgDatabase,
|
|
28
|
-
isSQLiteDatabase,
|
|
29
|
-
SqlFlavorOptions,
|
|
30
|
-
TableFn,
|
|
31
|
-
} from "./lib/utils.js"
|
|
25
|
+
import { SqlFlavorOptions, TableFn } from "./lib/utils.js"
|
|
26
|
+
import { is } from "drizzle-orm"
|
|
32
27
|
|
|
33
28
|
import type { Adapter } from "@auth/core/adapters"
|
|
34
29
|
|
|
@@ -260,18 +255,15 @@ export function DrizzleAdapter<SqlFlavor extends SqlFlavorOptions>(
|
|
|
260
255
|
db: SqlFlavor,
|
|
261
256
|
table?: TableFn<SqlFlavor>
|
|
262
257
|
): Adapter {
|
|
263
|
-
if (
|
|
264
|
-
// We need to cast to unknown since the type overlaps (PScale is MySQL based)
|
|
258
|
+
if (is(db, MySqlDatabase)) {
|
|
265
259
|
return mySqlDrizzleAdapter(db, table as MySqlTableFn)
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
if (isPgDatabase(db)) {
|
|
260
|
+
} else if (is(db, PgDatabase)) {
|
|
269
261
|
return pgDrizzleAdapter(db, table as PgTableFn)
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
if (isSQLiteDatabase(db)) {
|
|
262
|
+
} else if (is(db, BaseSQLiteDatabase)) {
|
|
273
263
|
return SQLiteDrizzleAdapter(db, table as SQLiteTableFn)
|
|
274
264
|
}
|
|
275
265
|
|
|
276
|
-
throw new Error(
|
|
266
|
+
throw new Error(
|
|
267
|
+
`Unsupported database type (${typeof db}) in Auth.js Drizzle adapter.`
|
|
268
|
+
)
|
|
277
269
|
}
|