mirror of
https://github.com/better-auth/better-auth.git
synced 2026-08-28 14:45:40 -05:00
117 lines
3.5 KiB
TypeScript
117 lines
3.5 KiB
TypeScript
import type { Resolver } from "../types";
|
|
import { getTypeFactory } from "../utils";
|
|
|
|
export type DrizzleResolverOptions = {
|
|
/**
|
|
* @default "pg"
|
|
*/
|
|
provider?: "pg" | "mysql" | "sqlite";
|
|
usePlural?: boolean;
|
|
camelCase?: boolean;
|
|
};
|
|
|
|
function convertToSnakeCase(str: string, camelCase?: boolean) {
|
|
if (camelCase) {
|
|
return str;
|
|
}
|
|
return str
|
|
.replace(/([A-Z]+)([A-Z][a-z])/g, "$1_$2")
|
|
.replace(/([a-z\d])([A-Z])/g, "$1_$2")
|
|
.toLowerCase();
|
|
}
|
|
|
|
export const drizzleResolver = (options: DrizzleResolverOptions): Resolver => {
|
|
const provider = options.provider ?? "pg";
|
|
|
|
return {
|
|
language: "typescript",
|
|
handler: (ctx) => {
|
|
const corePath = `${provider}-core`;
|
|
const tableFnName = `${provider}Table`;
|
|
const imports = [
|
|
`import { ${tableFnName} } from "drizzle-orm/${corePath}";`,
|
|
`import * as t from "drizzle-orm/${corePath}";`,
|
|
];
|
|
const getType = getTypeFactory((field) => {
|
|
const fieldName = convertToSnakeCase(
|
|
field.fieldName,
|
|
options.camelCase,
|
|
);
|
|
const number = field.bigint
|
|
? provider === "sqlite"
|
|
? `t.blob("${fieldName}", { mode: "bigint" })`
|
|
: `t.bigint("${fieldName}")`
|
|
: provider === "mysql"
|
|
? `t.int("${fieldName}")`
|
|
: `t.integer("${fieldName}")`;
|
|
|
|
return {
|
|
string:
|
|
provider === "sqlite"
|
|
? `t.text("${fieldName}")`
|
|
: field.unique
|
|
? `t.varchar("${fieldName}", { length: 255 })`
|
|
: field.references
|
|
? `t.varchar("${fieldName}", { length: 36 })`
|
|
: `t.text("${fieldName}")`,
|
|
boolean:
|
|
provider === "sqlite"
|
|
? `t.integer("${fieldName}")`
|
|
: `t.boolean("${fieldName}")`,
|
|
number,
|
|
date:
|
|
provider === "pg"
|
|
? `t.timestamp("${fieldName}", { precision: 6, withTimezone: true })`
|
|
: provider === "sqlite"
|
|
? `t.integer("${fieldName}", { mode: "timestamp_ms" })`
|
|
: `t.timestamp("${fieldName}", { mode: "date", fsp: 3 })`,
|
|
json:
|
|
provider === "pg"
|
|
? `t.jsonb("${fieldName}")`
|
|
: provider === "sqlite"
|
|
? `t.text("${fieldName}", { mode: "json" })`
|
|
: `t.json("${fieldName}")`,
|
|
id: ctx.useNumberId
|
|
? provider === "pg"
|
|
? `t.serial("${fieldName}").primaryKey()`
|
|
: `t.integer("${fieldName}").primaryKey${provider === "sqlite" ? "({ autoIncrement: true })" : "().autoincrement()"}`
|
|
: provider === "mysql"
|
|
? `t.varchar("${fieldName}", { length: 36 }).primaryKey()`
|
|
: `t.text("${fieldName}").primaryKey()`,
|
|
foreignKeyId: ctx.useNumberId
|
|
? `t.integer("${fieldName}")`
|
|
: `t.text("${fieldName}")`,
|
|
"number[]": `${number}.array()`,
|
|
"string[]": `t.text("${fieldName}").array()`,
|
|
};
|
|
});
|
|
|
|
const table = [
|
|
`export const ${ctx.schema.modelName} = ${tableFnName}("${convertToSnakeCase(ctx.schema.modelName, options.camelCase)}${options.usePlural ? "s" : ""}", {`,
|
|
];
|
|
|
|
if (ctx.mode === "alter") {
|
|
table.push("\t// ...existing fields");
|
|
}
|
|
|
|
for (const field of ctx.schema.fields) {
|
|
let value = getType(field);
|
|
if (field.required !== false && field.fieldName !== "id") {
|
|
value += ".notNull()";
|
|
}
|
|
if (field.unique) {
|
|
value += ".unique()";
|
|
}
|
|
if (field.references) {
|
|
value += `.references(() => ${field.references.model}.${convertToSnakeCase(field.references.field, options.camelCase)}${field.references.onDelete ? `, { onDelete: "${field.references.onDelete}" }` : ""})`;
|
|
}
|
|
table.push(`\t${field.fieldName}: ${value},`);
|
|
}
|
|
|
|
table.push("});");
|
|
|
|
return [...imports, "", ...table].join("\n");
|
|
},
|
|
};
|
|
};
|