diff --git a/auth.config.ts b/auth.config.ts index 80f0a66..8897213 100644 --- a/auth.config.ts +++ b/auth.config.ts @@ -4,7 +4,13 @@ import GitHub from "next-auth/providers/github" import Google from "next-auth/providers/google" import { HttpEmailProvider } from "@/lib/auth/http-email-provider" -import { db, pgTable } from "@/lib/db" +import { + accountsTable, + db, + sessionsTable, + usersTable, + verificationTokensTable +} from "@/lib/db" /** * https://auth-docs-git-feat-nextjs-auth-authjs.vercel.app/guides/upgrade-to-v5#edge-compatibility @@ -13,7 +19,12 @@ export default { /** * https://authjs.dev/reference/adapter/drizzle */ - adapter: DrizzleAdapter(db, pgTable), + adapter: DrizzleAdapter(db, undefined, { + users: usersTable, + accounts: accountsTable, + sessions: sessionsTable, + verificationTokens: verificationTokensTable + }), /** * diff --git a/drizzle/0000_wild_dark_beast.sql b/drizzle/0000_flashy_mantis.sql similarity index 63% rename from drizzle/0000_wild_dark_beast.sql rename to drizzle/0000_flashy_mantis.sql index 7f339d8..9414c9e 100644 --- a/drizzle/0000_wild_dark_beast.sql +++ b/drizzle/0000_flashy_mantis.sql @@ -1,10 +1,10 @@ CREATE EXTENSION IF NOT EXISTS "citext"; CREATE TABLE IF NOT EXISTS "accounts" ( - "userId" text NOT NULL, + "user_id" text NOT NULL, "type" text NOT NULL, "provider" text NOT NULL, - "providerAccountId" text NOT NULL, + "provider_account_id" text NOT NULL, "refresh_token" text, "access_token" text, "expires_at" integer, @@ -12,12 +12,12 @@ CREATE TABLE IF NOT EXISTS "accounts" ( "scope" text, "id_token" text, "session_state" text, - CONSTRAINT accounts_provider_providerAccountId PRIMARY KEY("provider","providerAccountId") + CONSTRAINT accounts_provider_provider_account_id PRIMARY KEY("provider","provider_account_id") ); --> statement-breakpoint CREATE TABLE IF NOT EXISTS "sessions" ( - "sessionToken" text PRIMARY KEY NOT NULL, - "userId" text NOT NULL, + "session_token" text PRIMARY KEY NOT NULL, + "user_id" text NOT NULL, "expires" timestamp NOT NULL ); --> statement-breakpoint @@ -25,7 +25,7 @@ CREATE TABLE IF NOT EXISTS "users" ( "id" text PRIMARY KEY NOT NULL, "name" text, "email" "citext" NOT NULL, - "emailVerified" timestamp, + "email_verified" timestamp, "image" text, CONSTRAINT "users_email_unique" UNIQUE("email") ); @@ -38,13 +38,13 @@ CREATE TABLE IF NOT EXISTS "verification_tokens" ( ); --> statement-breakpoint DO $$ BEGIN - ALTER TABLE "accounts" ADD CONSTRAINT "accounts_userId_users_id_fk" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE cascade ON UPDATE no action; + ALTER TABLE "accounts" ADD CONSTRAINT "accounts_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE cascade ON UPDATE no action; EXCEPTION WHEN duplicate_object THEN null; END $$; --> statement-breakpoint DO $$ BEGIN - ALTER TABLE "sessions" ADD CONSTRAINT "sessions_userId_users_id_fk" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE cascade ON UPDATE no action; + ALTER TABLE "sessions" ADD CONSTRAINT "sessions_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE cascade ON UPDATE no action; EXCEPTION WHEN duplicate_object THEN null; END $$; diff --git a/drizzle/meta/0000_snapshot.json b/drizzle/meta/0000_snapshot.json index 8ce19fc..85c6601 100644 --- a/drizzle/meta/0000_snapshot.json +++ b/drizzle/meta/0000_snapshot.json @@ -1,15 +1,15 @@ { "version": "5", "dialect": "pg", - "id": "57d3b764-7ffe-4d06-b34d-9ea9e5605840", + "id": "0c494241-df41-44f7-a705-29ce1c53abe3", "prevId": "00000000-0000-0000-0000-000000000000", "tables": { "accounts": { "name": "accounts", "schema": "", "columns": { - "userId": { - "name": "userId", + "user_id": { + "name": "user_id", "type": "text", "primaryKey": false, "notNull": true @@ -26,8 +26,8 @@ "primaryKey": false, "notNull": true }, - "providerAccountId": { - "name": "providerAccountId", + "provider_account_id": { + "name": "provider_account_id", "type": "text", "primaryKey": false, "notNull": true @@ -77,20 +77,20 @@ }, "indexes": {}, "foreignKeys": { - "accounts_userId_users_id_fk": { - "name": "accounts_userId_users_id_fk", + "accounts_user_id_users_id_fk": { + "name": "accounts_user_id_users_id_fk", "tableFrom": "accounts", "tableTo": "users", - "columnsFrom": ["userId"], + "columnsFrom": ["user_id"], "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } }, "compositePrimaryKeys": { - "accounts_provider_providerAccountId": { - "name": "accounts_provider_providerAccountId", - "columns": ["provider", "providerAccountId"] + "accounts_provider_provider_account_id": { + "name": "accounts_provider_provider_account_id", + "columns": ["provider", "provider_account_id"] } }, "uniqueConstraints": {} @@ -99,14 +99,14 @@ "name": "sessions", "schema": "", "columns": { - "sessionToken": { - "name": "sessionToken", + "session_token": { + "name": "session_token", "type": "text", "primaryKey": true, "notNull": true }, - "userId": { - "name": "userId", + "user_id": { + "name": "user_id", "type": "text", "primaryKey": false, "notNull": true @@ -120,11 +120,11 @@ }, "indexes": {}, "foreignKeys": { - "sessions_userId_users_id_fk": { - "name": "sessions_userId_users_id_fk", + "sessions_user_id_users_id_fk": { + "name": "sessions_user_id_users_id_fk", "tableFrom": "sessions", "tableTo": "users", - "columnsFrom": ["userId"], + "columnsFrom": ["user_id"], "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" @@ -155,8 +155,8 @@ "primaryKey": false, "notNull": true }, - "emailVerified": { - "name": "emailVerified", + "email_verified": { + "name": "email_verified", "type": "timestamp", "primaryKey": false, "notNull": false diff --git a/drizzle/meta/_journal.json b/drizzle/meta/_journal.json index ad9e40d..b3c9865 100644 --- a/drizzle/meta/_journal.json +++ b/drizzle/meta/_journal.json @@ -5,8 +5,8 @@ { "idx": 0, "version": "5", - "when": 1692498355601, - "tag": "0000_wild_dark_beast", + "when": 1694913558730, + "tag": "0000_flashy_mantis", "breakpoints": true } ] diff --git a/lib/db/schema.ts b/lib/db/schema.ts index 454ee5d..8ad3492 100644 --- a/lib/db/schema.ts +++ b/lib/db/schema.ts @@ -2,7 +2,7 @@ import { type AdapterAccount } from "@auth/core/adapters" import { createId } from "@paralleldrive/cuid2" import { integer, - pgTableCreator, + pgTable, primaryKey, text, timestamp @@ -10,44 +10,26 @@ import { import { citext } from "./custom-types/citext" -/** - * Modify the default Auth.js tables to be snake case and plural. - */ -export const pgTable = pgTableCreator((name) => { - switch (name) { - case "user": - return "users" - case "account": - return "accounts" - case "session": - return "sessions" - case "verificationToken": - return "verification_tokens" - default: - return name - } -}) - -export const usersTable = pgTable("user", { +export const usersTable = pgTable("users", { id: text("id") .notNull() .primaryKey() .$defaultFn(() => createId()), name: text("name"), email: citext("email").notNull().unique(), - emailVerified: timestamp("emailVerified", { mode: "date" }), + emailVerified: timestamp("email_verified", { mode: "date" }), image: text("image") }) export const accountsTable = pgTable( - "account", + "accounts", { - userId: text("userId") + userId: text("user_id") .notNull() .references(() => usersTable.id, { onDelete: "cascade" }), type: text("type").$type().notNull(), provider: text("provider").notNull(), - providerAccountId: text("providerAccountId").notNull(), + providerAccountId: text("provider_account_id").notNull(), refresh_token: text("refresh_token"), access_token: text("access_token"), expires_at: integer("expires_at"), @@ -61,16 +43,16 @@ export const accountsTable = pgTable( }) ) -export const sessionsTable = pgTable("session", { - sessionToken: text("sessionToken").notNull().primaryKey(), - userId: text("userId") +export const sessionsTable = pgTable("sessions", { + sessionToken: text("session_token").notNull().primaryKey(), + userId: text("user_id") .notNull() .references(() => usersTable.id, { onDelete: "cascade" }), expires: timestamp("expires", { mode: "date" }).notNull() }) export const verificationTokensTable = pgTable( - "verificationToken", + "verification_tokens", { identifier: text("identifier").notNull(), token: text("token").notNull(), diff --git a/patches/@auth+drizzle-adapter+0.3.2.patch b/patches/@auth+drizzle-adapter+0.3.2.patch new file mode 100644 index 0000000..4d12c26 --- /dev/null +++ b/patches/@auth+drizzle-adapter+0.3.2.patch @@ -0,0 +1,71 @@ +diff --git a/node_modules/@auth/drizzle-adapter/index.d.ts b/node_modules/@auth/drizzle-adapter/index.d.ts +index 00166e5..8a3f0cc 100644 +--- a/node_modules/@auth/drizzle-adapter/index.d.ts ++++ b/node_modules/@auth/drizzle-adapter/index.d.ts +@@ -15,7 +15,7 @@ + * + * @module @auth/drizzle-adapter + */ +-import { SqlFlavorOptions, TableFn } from "./lib/utils.js"; ++import { SqlFlavorOptions, TableFn, MinimumSchema } from "./lib/utils.js"; + import type { Adapter } from "@auth/core/adapters"; + /** + * Add the adapter to your `pages/api/[...nextauth].ts` next-auth configuration object. +@@ -241,5 +241,5 @@ import type { Adapter } from "@auth/core/adapters"; + * --- + * + **/ +-export declare function DrizzleAdapter(db: SqlFlavor, table?: TableFn): Adapter; ++export declare function DrizzleAdapter(db: SqlFlavor, table?: TableFn, tables?: MinimumSchema["pg"]): Adapter; + //# sourceMappingURL=index.d.ts.map +diff --git a/node_modules/@auth/drizzle-adapter/index.js b/node_modules/@auth/drizzle-adapter/index.js +index ebe29a9..f4e7dea 100644 +--- a/node_modules/@auth/drizzle-adapter/index.js ++++ b/node_modules/@auth/drizzle-adapter/index.js +@@ -246,12 +246,12 @@ import { is } from "drizzle-orm"; + * --- + * + **/ +-export function DrizzleAdapter(db, table) { ++export function DrizzleAdapter(db, table, tables) { + if (is(db, MySqlDatabase)) { + return mySqlDrizzleAdapter(db, table); + } + else if (is(db, PgDatabase)) { +- return pgDrizzleAdapter(db, table); ++ return pgDrizzleAdapter(db, table, tables); + } + else if (is(db, BaseSQLiteDatabase)) { + return SQLiteDrizzleAdapter(db, table); +diff --git a/node_modules/@auth/drizzle-adapter/lib/pg.d.ts b/node_modules/@auth/drizzle-adapter/lib/pg.d.ts +index 1d710fa..4ef8957 100644 +--- a/node_modules/@auth/drizzle-adapter/lib/pg.d.ts ++++ b/node_modules/@auth/drizzle-adapter/lib/pg.d.ts +@@ -221,5 +221,5 @@ export declare function createTables(pgTable: PgTableFn): { + }>; + }; + export type DefaultSchema = ReturnType; +-export declare function pgDrizzleAdapter(client: InstanceType, tableFn?: PgTableFn): Adapter; ++export declare function pgDrizzleAdapter(client: InstanceType, tableFn?: PgTableFn, tables?: DefaultSchema): Adapter; + //# sourceMappingURL=pg.d.ts.map +diff --git a/node_modules/@auth/drizzle-adapter/lib/pg.js b/node_modules/@auth/drizzle-adapter/lib/pg.js +index f3d333f..647fd60 100644 +--- a/node_modules/@auth/drizzle-adapter/lib/pg.js ++++ b/node_modules/@auth/drizzle-adapter/lib/pg.js +@@ -41,13 +41,13 @@ export function createTables(pgTable) { + })); + return { users, accounts, sessions, verificationTokens }; + } +-export function pgDrizzleAdapter(client, tableFn = defaultPgTableFn) { +- const { users, accounts, sessions, verificationTokens } = createTables(tableFn); ++export function pgDrizzleAdapter(client, tableFn = defaultPgTableFn, tables = undefined) { ++ const { users, accounts, sessions, verificationTokens } = tables || createTables(tableFn); + return { + async createUser(data) { + return await client + .insert(users) +- .values({ ...data, id: crypto.randomUUID() }) ++ .values(data) + .returning() + .then((res) => res[0] ?? null); + },