Files
better-auth/packages/cli/test/generate.test.ts
2025-09-14 13:27:13 -07:00

364 lines
7.9 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { prismaAdapter } from "better-auth/adapters/prisma";
import { generatePrismaSchema } from "../src/generators/prisma";
import { organization, twoFactor, username } from "better-auth/plugins";
import { generateDrizzleSchema } from "../src/generators/drizzle";
import { drizzleAdapter } from "better-auth/adapters/drizzle";
import { generateMigrations } from "../src/generators/kysely";
import Database from "better-sqlite3";
import type { BetterAuthOptions } from "better-auth";
import { generateAuthConfig } from "../src/generators/auth-config";
import type { SupportedPlugin } from "../src/commands/init";
describe("generate", async () => {
it("should generate prisma schema", async () => {
const schema = await generatePrismaSchema({
file: "test.prisma",
adapter: prismaAdapter(
{},
{
provider: "postgresql",
},
)({} as BetterAuthOptions),
options: {
database: prismaAdapter(
{},
{
provider: "postgresql",
},
),
plugins: [twoFactor(), username()],
},
});
expect(schema.code).toMatchFileSnapshot("./__snapshots__/schema.prisma");
});
it("should generate prisma schema with number id", async () => {
const schema = await generatePrismaSchema({
file: "test.prisma",
adapter: prismaAdapter(
{},
{
provider: "postgresql",
},
)({} as BetterAuthOptions),
options: {
database: prismaAdapter(
{},
{
provider: "postgresql",
},
),
plugins: [twoFactor(), username()],
advanced: {
database: {
useNumberId: true,
},
},
},
});
expect(schema.code).toMatchFileSnapshot(
"./__snapshots__/schema-numberid.prisma",
);
});
it("should generate prisma schema for mongodb", async () => {
const schema = await generatePrismaSchema({
file: "test.prisma",
adapter: prismaAdapter(
{},
{
provider: "mongodb",
},
)({} as BetterAuthOptions),
options: {
database: prismaAdapter(
{},
{
provider: "mongodb",
},
),
plugins: [twoFactor(), username()],
},
});
expect(schema.code).toMatchFileSnapshot(
"./__snapshots__/schema-mongodb.prisma",
);
});
it("should generate prisma schema for mysql", async () => {
const schema = await generatePrismaSchema({
file: "test.prisma",
adapter: prismaAdapter(
{},
{
provider: "mysql",
},
)({} as BetterAuthOptions),
options: {
database: prismaAdapter(
{},
{
provider: "mongodb",
},
),
plugins: [twoFactor(), username()],
},
});
expect(schema.code).toMatchFileSnapshot(
"./__snapshots__/schema-mysql.prisma",
);
});
it("should generate prisma schema for mysql with custom model names", async () => {
const schema = await generatePrismaSchema({
file: "test.prisma",
adapter: prismaAdapter(
{},
{
provider: "mysql",
},
)({} as BetterAuthOptions),
options: {
database: prismaAdapter(
{},
{
provider: "mongodb",
},
),
plugins: [
twoFactor(),
username(),
organization({
schema: {
organization: {
modelName: "workspace",
},
invitation: {
modelName: "workspaceInvitation",
},
},
}),
],
},
});
expect(schema.code).toMatchFileSnapshot(
"./__snapshots__/schema-mysql-custom.prisma",
);
});
it("should generate drizzle schema", async () => {
const schema = await generateDrizzleSchema({
file: "test.drizzle",
adapter: drizzleAdapter(
{},
{
provider: "pg",
schema: {},
},
)({} as BetterAuthOptions),
options: {
database: drizzleAdapter(
{},
{
provider: "pg",
schema: {},
},
),
plugins: [twoFactor(), username()],
user: {
modelName: "custom_user",
},
account: {
modelName: "custom_account",
},
session: {
modelName: "custom_session",
},
verification: {
modelName: "custom_verification",
},
},
});
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,
},
},
user: {
modelName: "custom_user",
},
account: {
modelName: "custom_account",
},
session: {
modelName: "custom_session",
},
verification: {
modelName: "custom_verification",
},
},
});
expect(schema.code).toMatchFileSnapshot(
"./__snapshots__/auth-schema-number-id.txt",
);
});
it("should generate kysely schema", async () => {
const schema = await generateMigrations({
file: "test.sql",
options: {
database: new Database(":memory:"),
},
adapter: {} as any,
});
expect(schema.code).toMatchFileSnapshot("./__snapshots__/migrations.sql");
});
it("should add plugin to empty plugins array without leading comma", async () => {
const initialConfig = `export const auth = betterAuth({
plugins: []
});`;
const mockFormat = (code: string) => Promise.resolve(code);
const mockSpinner = { stop: () => {} };
const plugins: SupportedPlugin[] = [
{
id: "next-cookies",
name: "nextCookies",
path: "better-auth/next-js",
clientName: undefined,
clientPath: undefined,
},
];
const result = await generateAuthConfig({
format: mockFormat,
current_user_config: initialConfig,
spinner: mockSpinner as any,
plugins,
database: null,
});
expect(result.generatedCode).toContain(`plugins: [nextCookies()]`);
expect(result.generatedCode).not.toContain(`plugins: [, nextCookies()]`);
});
});
describe("JSON field support in CLI generators", () => {
it("should generate Drizzle schema with JSON fields for PostgreSQL", async () => {
const schema = await generateDrizzleSchema({
file: "test.drizzle",
adapter: {
id: "drizzle",
options: {
provider: "pg",
schema: {},
},
} as any,
options: {
database: {} as any,
user: {
additionalFields: {
preferences: {
type: "json",
},
},
},
} as BetterAuthOptions,
});
expect(schema.code).toContain("preferences: jsonb(");
});
it("should generate Drizzle schema with JSON fields for MySQL", async () => {
const schema = await generateDrizzleSchema({
file: "test.drizzle",
adapter: {
id: "drizzle",
options: {
provider: "mysql",
schema: {},
},
} as any,
options: {
database: {} as any,
user: {
additionalFields: {
preferences: {
type: "json",
},
},
},
} as BetterAuthOptions,
});
expect(schema.code).toContain("preferences: json(");
});
it("should generate Drizzle schema with JSON fields for SQLite", async () => {
const schema = await generateDrizzleSchema({
file: "test.drizzle",
adapter: {
id: "drizzle",
options: {
provider: "sqlite",
schema: {},
},
} as any,
options: {
database: {} as any,
user: {
additionalFields: {
preferences: {
type: "json",
},
},
},
} as BetterAuthOptions,
});
expect(schema.code).toContain("preferences: text(");
});
it("should generate Prisma schema with JSON fields", async () => {
const schema = await generatePrismaSchema({
file: "test.prisma",
adapter: {
id: "prisma",
options: {},
} as any,
options: {
database: {} as any,
user: {
additionalFields: {
preferences: {
type: "json",
},
},
},
} as BetterAuthOptions,
});
expect(schema.code).toContain("preferences Json?");
});
});