mirror of
https://github.com/better-auth/better-auth.git
synced 2026-10-19 23:53:17 -05:00
fix(drizzle-cli): use serial as PK when useNumberId is enabled (#3228)
This commit is contained in:
@@ -3,6 +3,7 @@ import {
|
||||
type BetterAuthDbSchema,
|
||||
type FieldAttribute,
|
||||
} from "better-auth/db";
|
||||
import type { BetterAuthOptions } from "better-auth/types";
|
||||
import { existsSync } from "fs";
|
||||
import type { SchemaGenerator } from "./types";
|
||||
|
||||
@@ -27,7 +28,7 @@ export const generateDrizzleSchema: SchemaGenerator = async ({
|
||||
}
|
||||
const fileExist = existsSync(filePath);
|
||||
|
||||
let code: string = generateImport({ databaseType, tables });
|
||||
let code: string = generateImport({ databaseType, tables, options });
|
||||
|
||||
for (const tableKey in tables) {
|
||||
const table = tables[tableKey]!;
|
||||
@@ -117,7 +118,11 @@ export const generateDrizzleSchema: SchemaGenerator = async ({
|
||||
let id: string = "";
|
||||
|
||||
if (options.advanced?.database?.useNumberId) {
|
||||
id = `int("id").autoincrement.primaryKey()`;
|
||||
if (databaseType === "pg") {
|
||||
id = `serial("id").primaryKey()`;
|
||||
} else {
|
||||
id = `int("id").autoincrement.primaryKey()`;
|
||||
}
|
||||
} else {
|
||||
if (databaseType === "mysql") {
|
||||
id = `varchar('id', { length: 36 }).primaryKey()`;
|
||||
@@ -173,13 +178,20 @@ export const generateDrizzleSchema: SchemaGenerator = async ({
|
||||
function generateImport({
|
||||
databaseType,
|
||||
tables,
|
||||
}: { databaseType: "sqlite" | "mysql" | "pg"; tables: BetterAuthDbSchema }) {
|
||||
options,
|
||||
}: {
|
||||
databaseType: "sqlite" | "mysql" | "pg";
|
||||
tables: BetterAuthDbSchema;
|
||||
options: BetterAuthOptions;
|
||||
}) {
|
||||
let imports: string[] = [];
|
||||
|
||||
const hasBigint = Object.values(tables).some((table) =>
|
||||
Object.values(table.fields).some((field) => field.bigint),
|
||||
);
|
||||
|
||||
const useNumberId = options.advanced?.database?.useNumberId;
|
||||
|
||||
imports.push(`${databaseType}Table`);
|
||||
imports.push(
|
||||
databaseType === "mysql"
|
||||
@@ -191,6 +203,7 @@ function generateImport({
|
||||
imports.push(hasBigint ? (databaseType !== "sqlite" ? "bigint" : "") : "");
|
||||
imports.push(databaseType !== "sqlite" ? "timestamp, boolean" : "");
|
||||
imports.push(databaseType === "mysql" ? "int" : "integer");
|
||||
imports.push(useNumberId ? (databaseType === "pg" ? "serial" : "") : "");
|
||||
|
||||
return `import { ${imports
|
||||
.map((x) => x.trim())
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
import { pgTable, text, timestamp, boolean, integer, serial } from "drizzle-orm/pg-core";
|
||||
|
||||
export const user = pgTable("user", {
|
||||
id: serial("id").primaryKey(),
|
||||
name: text('name').notNull(),
|
||||
email: text('email').notNull().unique(),
|
||||
emailVerified: boolean('email_verified').$defaultFn(() => false).notNull(),
|
||||
image: text('image'),
|
||||
createdAt: timestamp('created_at').$defaultFn(() => /* @__PURE__ */ new Date()).notNull(),
|
||||
updatedAt: timestamp('updated_at').$defaultFn(() => /* @__PURE__ */ new Date()).notNull(),
|
||||
twoFactorEnabled: boolean('two_factor_enabled'),
|
||||
username: text('username').unique(),
|
||||
displayUsername: text('display_username')
|
||||
});
|
||||
|
||||
export const session = pgTable("session", {
|
||||
id: serial("id").primaryKey(),
|
||||
expiresAt: timestamp('expires_at').notNull(),
|
||||
token: text('token').notNull().unique(),
|
||||
createdAt: timestamp('created_at').notNull(),
|
||||
updatedAt: timestamp('updated_at').notNull(),
|
||||
ipAddress: text('ip_address'),
|
||||
userAgent: text('user_agent'),
|
||||
userId: serial('user_id').primaryKey().notNull().references(()=> user.id, { onDelete: 'cascade' })
|
||||
});
|
||||
|
||||
export const account = pgTable("account", {
|
||||
id: serial("id").primaryKey(),
|
||||
accountId: text('account_id').notNull(),
|
||||
providerId: text('provider_id').notNull(),
|
||||
userId: serial('user_id').primaryKey().notNull().references(()=> user.id, { onDelete: 'cascade' }),
|
||||
accessToken: text('access_token'),
|
||||
refreshToken: text('refresh_token'),
|
||||
idToken: text('id_token'),
|
||||
accessTokenExpiresAt: timestamp('access_token_expires_at'),
|
||||
refreshTokenExpiresAt: timestamp('refresh_token_expires_at'),
|
||||
scope: text('scope'),
|
||||
password: text('password'),
|
||||
createdAt: timestamp('created_at').notNull(),
|
||||
updatedAt: timestamp('updated_at').notNull()
|
||||
});
|
||||
|
||||
export const verification = pgTable("verification", {
|
||||
id: serial("id").primaryKey(),
|
||||
identifier: text('identifier').notNull(),
|
||||
value: text('value').notNull(),
|
||||
expiresAt: timestamp('expires_at').notNull(),
|
||||
createdAt: timestamp('created_at').$defaultFn(() => /* @__PURE__ */ new Date()),
|
||||
updatedAt: timestamp('updated_at').$defaultFn(() => /* @__PURE__ */ new Date())
|
||||
});
|
||||
|
||||
export const twoFactor = pgTable("two_factor", {
|
||||
id: serial("id").primaryKey(),
|
||||
secret: text('secret').notNull(),
|
||||
backupCodes: text('backup_codes').notNull(),
|
||||
userId: serial('user_id').primaryKey().notNull().references(()=> user.id, { onDelete: 'cascade' })
|
||||
});
|
||||
@@ -132,6 +132,37 @@ describe("generate", async () => {
|
||||
expect(schema.code).toMatchFileSnapshot("./__snapshots__/auth-schema.txt");
|
||||
});
|
||||
|
||||
it("should generate drizzle schema with number id", async () => {
|
||||
const schema = await generateDrizzleSchema({
|
||||
file: "test.drizzle",
|
||||
adapter: drizzleAdapter(
|
||||
{},
|
||||
{
|
||||
provider: "pg",
|
||||
schema: {},
|
||||
},
|
||||
)({} as BetterAuthOptions),
|
||||
options: {
|
||||
database: drizzleAdapter(
|
||||
{},
|
||||
{
|
||||
provider: "pg",
|
||||
schema: {},
|
||||
},
|
||||
),
|
||||
plugins: [twoFactor(), username()],
|
||||
advanced: {
|
||||
database: {
|
||||
useNumberId: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(schema.code).toMatchFileSnapshot(
|
||||
"./__snapshots__/auth-schema-number-id.txt",
|
||||
);
|
||||
});
|
||||
|
||||
it("should generate kysely schema", async () => {
|
||||
const schema = await generateMigrations({
|
||||
file: "test.sql",
|
||||
|
||||
Reference in New Issue
Block a user