Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(adapter-drizzle): add option to pass in schema #8561

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

juliusmarminge
Copy link
Contributor

@juliusmarminge juliusmarminge commented Sep 11, 2023

☕️ 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

🎫 Affected issues

Please scout and link issues that might be solved by this PR.

Fixes: INSERT_ISSUE_LINK_HERE

📌 Resources

@vercel
Copy link

vercel bot commented Sep 11, 2023

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

@vercel
Copy link

vercel bot commented Sep 11, 2023

@juliusmarminge is attempting to deploy a commit to the authjs Team on Vercel.

A member of the Team first needs to authorize it.

@juliusmarminge juliusmarminge changed the title add option to pass in schema feat(adapter-drizzle): add option to pass in schema Sep 11, 2023
@github-actions github-actions bot added the adapters Changes related to the core code concerning database adapters label Sep 11, 2023
@nicoandrade
Copy link

nicoandrade commented Sep 12, 2023

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;
    }
}

@geoffreydhuyvetters
Copy link

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 👍🏻

@yandearta
Copy link

Can't wait for this to be implemented. Spent hours figuring out why some profile data wasn't being inserted into my custom fields 🤦‍♂️

@juliusmarminge
Copy link
Contributor Author

juliusmarminge commented Oct 12, 2023

Sorry for the ping @balazsorban44, but could we get some eyes on this?

@iFallUpHill
Copy link

+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.

@statusunknown418
Copy link

man why is this not merged yet :(

@ndom91
Copy link
Member

ndom91 commented Jan 12, 2024

This similar PR adds support for custom table naming schema and a custom tableFn as well: #8344

@nahtnam
Copy link

nahtnam commented Jan 21, 2024

@ndom91 looks like you're a codeowner, anything blocking this PR from going through? Happy to help fix anything if necessary

@nahtnam
Copy link

nahtnam commented Jan 21, 2024

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

@paupenin
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
adapters Changes related to the core code concerning database adapters drizzle @auth/drizzle-adapter
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

10 participants