feat(adapter-drizzle): add option to pass in schema
โ๏ธ Reasoning
In other adapters, the adapter returns the entire table so if you have additional fields they will also be returned when the adapter queries the table. A good example here is if your user tables contains an additional field defaultCurrency, this "should" be returned from the adapter.
With drizzle, this isn't the case since the adapter is using it's own tables. This means additional fields aren't returned. This PR aims to provide an API to allow the user to pass custom tables to the adapter which will make it so the entire table is returned by the adapter and can be used in callbacks to create a session object containing the additional field(s).
I've made the changes so that they are backwards compatible. The downside to this is that if you're using custom table fn, you'll need to pass in all the tables to the object, and not just the table you have custom fields in. A perhaps better API would be
adapter: DrizzleAdapter(db, {
tableFn: myTableFn,
schemaOverrides: { users }
}),
but that would require a breaking change, which might be okay given the adapter is still at a 0.x version? What do you think @balazsorban44 ?
My current "workaround" is to override the getUserAndSession function to use my own table, but would be nicer to have this work ootb
import { sessions, table, users } from "~/db/schema";
export const {
handlers: { GET, POST },
auth,
CSRF_experimental,
} = NextAuth({
adapter: {
...DrizzleAdapter(db, table),
async getSessionAndUser(data) {
const sessionAndUsers = await db
.select({
session: sessions,
user: users,
})
.from(sessions)
.where(eq(sessions.sessionToken, data))
.innerJoin(users, eq(users.id, sessions.userId));
return sessionAndUsers[0] ?? null;
},
},
// ...
});
๐งข Checklist
- [x] Documentation
- [ ] Tests (I set one up to test the types, but unsure how to test runtime behavior, I tested runtime by patching a local app to use the diff from this PR: https://github.com/juliusmarminge/time-report/pull/4)
- [x] Ready to be merged
๐ซ Affected issues
Please scout and link issues that might be solved by this PR.
Fixes: INSERT_ISSUE_LINK_HERE
๐ Resources
The latest updates on your projects. Learn more about Vercel for Git โ๏ธ
| Name | Status | Preview | Comments | Updated (UTC) |
|---|---|---|---|---|
| auth-docs | โ Ready (Inspect) | Visit Preview | ๐ฌ Add feedback | Dec 13, 2023 0:11am |
1 Ignored Deployment
| Name | Status | Preview | Comments | Updated (UTC) |
|---|---|---|---|---|
| next-auth-docs | โฌ๏ธ Ignored (Inspect) | Visit Preview | Dec 13, 2023 0:11am |
@juliusmarminge is attempting to deploy a commit to the authjs Team on Vercel.
A member of the Team first needs to authorize it.
Following the workaround in the first comment until the Drizzle adapter supports custom tables.
If I added a new column called document to the users table.
To remove all Typescript errors, I'm using this interface:
import { type InferSelectModel } from "drizzle-orm";
import { users } from "@/server/db/schema";
declare module "@auth/core/adapters" {
interface AdapterUser extends InferSelectModel<typeof users> {
// ...other properties
document: string | null;
}
}
This is quite an essential feature when you want to add roles to a user. The workaround works for retrieving them. But if you want to store extra fields you also have to override the correct write functions. So yes ๐๐ป
Can't wait for this to be implemented. Spent hours figuring out why some profile data wasn't being inserted into my custom fields ๐คฆโโ๏ธ
Sorry for the ping @balazsorban44, but could we get some eyes on this?
+1 on this one, was confused as to why my additional columns on my Users table weren't being returned.
Using the workaround for now.
man why is this not merged yet :(
This similar PR adds support for custom table naming schema and a custom tableFn as well: https://github.com/nextauthjs/next-auth/pull/8344
@ndom91 looks like you're a codeowner, anything blocking this PR from going through? Happy to help fix anything if necessary
BTW, one potential issue with this PR: getUserByAccount, specifically:
return dbAccount.user;
assumes that the table name is user. In my case, I'm trying to make it users to follow convention
For anyone having a similar issue, you can use you own table definitions like this:
// @ts-expect-error DrizzleAdapter expects a TableFn<SqlFlavor> but we're using a table defined in our schema
adapter: DrizzleAdapter(db, (name: string) => {
return {
user: users,
account: accounts,
session: sessions,
verificationToken: verificationTokens,
}[name];
}),
I'm sorry for the @ts-expect-error but I don't have time to create a PR for this now in the open-source project.
It looks like this issue did not receive any activity for 60 days. It will be closed in 7 days if no further activity occurs. If you think your issue is still relevant, commenting will keep it open. Thanks!