diff --git a/packages/cli/src/generators/drizzle.ts b/packages/cli/src/generators/drizzle.ts index fc95f2e873..9d0c4f3c40 100644 --- a/packages/cli/src/generators/drizzle.ts +++ b/packages/cli/src/generators/drizzle.ts @@ -169,7 +169,11 @@ export const generateDrizzleSchema: SchemaGenerator = async ({ attr.type === "date" && attr.defaultValue.toString().includes("new Date()") ) { - type += `.defaultNow()`; + if (databaseType === "sqlite") { + type += `.default(sql\`(current_timestamp)\`)`; + } else { + type += `.defaultNow()`; + } } else { type += `.$defaultFn(${attr.defaultValue})`; } @@ -223,7 +227,8 @@ function generateImport({ tables: BetterAuthDbSchema; options: BetterAuthOptions; }) { - let imports: string[] = []; + const rootImports: string[] = []; + const coreImports: string[] = []; let hasBigint = false; let hasJson = false; @@ -238,16 +243,18 @@ function generateImport({ const useNumberId = options.advanced?.database?.useNumberId; - imports.push(`${databaseType}Table`); - imports.push( + coreImports.push(`${databaseType}Table`); + coreImports.push( databaseType === "mysql" ? "varchar, text" : databaseType === "pg" ? "text" : "text", ); - imports.push(hasBigint ? (databaseType !== "sqlite" ? "bigint" : "") : ""); - imports.push(databaseType !== "sqlite" ? "timestamp, boolean" : ""); + coreImports.push( + hasBigint ? (databaseType !== "sqlite" ? "bigint" : "") : "", + ); + coreImports.push(databaseType !== "sqlite" ? "timestamp, boolean" : ""); if (databaseType === "mysql") { // Only include int for MySQL if actually needed const hasNonBigintNumber = Object.values(tables).some((table) => @@ -259,7 +266,7 @@ function generateImport({ ); const needsInt = !!useNumberId || hasNonBigintNumber; if (needsInt) { - imports.push("int"); + coreImports.push("int"); } } else if (databaseType === "pg") { // Only include integer for PG if actually needed @@ -280,21 +287,38 @@ function generateImport({ hasNonBigintNumber || (options.advanced?.database?.useNumberId && hasFkToId); if (needsInteger) { - imports.push("integer"); + coreImports.push("integer"); } } else { - imports.push("integer"); + coreImports.push("integer"); } - imports.push(useNumberId ? (databaseType === "pg" ? "serial" : "") : ""); + coreImports.push(useNumberId ? (databaseType === "pg" ? "serial" : "") : ""); //handle json last on the import order if (hasJson) { - if (databaseType === "pg") imports.push("jsonb"); - if (databaseType === "mysql") imports.push("json"); + if (databaseType === "pg") coreImports.push("jsonb"); + if (databaseType === "mysql") coreImports.push("json"); // sqlite uses text for JSON, so there's no need to handle this case } - return `import { ${imports + // Add sql import for SQLite timestamps with defaultNow + const hasSQLiteTimestamp = + databaseType === "sqlite" && + Object.values(tables).some((table) => + Object.values(table.fields).some( + (field) => + field.type === "date" && + field.defaultValue && + typeof field.defaultValue === "function" && + field.defaultValue.toString().includes("new Date()"), + ), + ); + + if (hasSQLiteTimestamp) { + rootImports.push("sql"); + } + + return `${rootImports.length > 0 ? `import { ${rootImports.join(", ")} } from "drizzle-orm";\n` : ""}import { ${coreImports .map((x) => x.trim()) .filter((x) => x !== "") .join(", ")} } from "drizzle-orm/${databaseType}-core";\n`; diff --git a/packages/cli/test/__snapshots__/auth-schema-sqlite-number-id.txt b/packages/cli/test/__snapshots__/auth-schema-sqlite-number-id.txt index 7dff206230..49e1d905d7 100644 --- a/packages/cli/test/__snapshots__/auth-schema-sqlite-number-id.txt +++ b/packages/cli/test/__snapshots__/auth-schema-sqlite-number-id.txt @@ -1,3 +1,4 @@ +import { sql } from "drizzle-orm"; import { sqliteTable, text, integer } from "drizzle-orm/sqlite-core"; export const custom_user = sqliteTable("custom_user", { @@ -9,10 +10,10 @@ export const custom_user = sqliteTable("custom_user", { .notNull(), image: text("image"), createdAt: integer("created_at", { mode: "timestamp" }) - .defaultNow() + .default(sql`(current_timestamp)`) .notNull(), updatedAt: integer("updated_at", { mode: "timestamp" }) - .defaultNow() + .default(sql`(current_timestamp)`) .$onUpdate(() => /* @__PURE__ */ new Date()) .notNull(), twoFactorEnabled: integer("two_factor_enabled", { mode: "boolean" }).default( @@ -27,7 +28,7 @@ export const custom_session = sqliteTable("custom_session", { expiresAt: integer("expires_at", { mode: "timestamp" }).notNull(), token: text("token").notNull().unique(), createdAt: integer("created_at", { mode: "timestamp" }) - .defaultNow() + .default(sql`(current_timestamp)`) .notNull(), updatedAt: integer("updated_at", { mode: "timestamp" }) .$onUpdate(() => /* @__PURE__ */ new Date()) @@ -58,7 +59,7 @@ export const custom_account = sqliteTable("custom_account", { scope: text("scope"), password: text("password"), createdAt: integer("created_at", { mode: "timestamp" }) - .defaultNow() + .default(sql`(current_timestamp)`) .notNull(), updatedAt: integer("updated_at", { mode: "timestamp" }) .$onUpdate(() => /* @__PURE__ */ new Date()) @@ -71,10 +72,10 @@ export const custom_verification = sqliteTable("custom_verification", { value: text("value").notNull(), expiresAt: integer("expires_at", { mode: "timestamp" }).notNull(), createdAt: integer("created_at", { mode: "timestamp" }) - .defaultNow() + .default(sql`(current_timestamp)`) .notNull(), updatedAt: integer("updated_at", { mode: "timestamp" }) - .defaultNow() + .default(sql`(current_timestamp)`) .$onUpdate(() => /* @__PURE__ */ new Date()) .notNull(), }); diff --git a/packages/cli/test/__snapshots__/auth-schema-sqlite-passkey-number-id.txt b/packages/cli/test/__snapshots__/auth-schema-sqlite-passkey-number-id.txt index c644580dc1..edbebcf569 100644 --- a/packages/cli/test/__snapshots__/auth-schema-sqlite-passkey-number-id.txt +++ b/packages/cli/test/__snapshots__/auth-schema-sqlite-passkey-number-id.txt @@ -1,3 +1,4 @@ +import { sql } from "drizzle-orm"; import { sqliteTable, text, integer } from "drizzle-orm/sqlite-core"; export const custom_user = sqliteTable("custom_user", { @@ -9,10 +10,10 @@ export const custom_user = sqliteTable("custom_user", { .notNull(), image: text("image"), createdAt: integer("created_at", { mode: "timestamp" }) - .defaultNow() + .default(sql`(current_timestamp)`) .notNull(), updatedAt: integer("updated_at", { mode: "timestamp" }) - .defaultNow() + .default(sql`(current_timestamp)`) .$onUpdate(() => /* @__PURE__ */ new Date()) .notNull(), }); @@ -22,7 +23,7 @@ export const custom_session = sqliteTable("custom_session", { expiresAt: integer("expires_at", { mode: "timestamp" }).notNull(), token: text("token").notNull().unique(), createdAt: integer("created_at", { mode: "timestamp" }) - .defaultNow() + .default(sql`(current_timestamp)`) .notNull(), updatedAt: integer("updated_at", { mode: "timestamp" }) .$onUpdate(() => /* @__PURE__ */ new Date()) @@ -53,7 +54,7 @@ export const custom_account = sqliteTable("custom_account", { scope: text("scope"), password: text("password"), createdAt: integer("created_at", { mode: "timestamp" }) - .defaultNow() + .default(sql`(current_timestamp)`) .notNull(), updatedAt: integer("updated_at", { mode: "timestamp" }) .$onUpdate(() => /* @__PURE__ */ new Date()) @@ -66,10 +67,10 @@ export const custom_verification = sqliteTable("custom_verification", { value: text("value").notNull(), expiresAt: integer("expires_at", { mode: "timestamp" }).notNull(), createdAt: integer("created_at", { mode: "timestamp" }) - .defaultNow() + .default(sql`(current_timestamp)`) .notNull(), updatedAt: integer("updated_at", { mode: "timestamp" }) - .defaultNow() + .default(sql`(current_timestamp)`) .$onUpdate(() => /* @__PURE__ */ new Date()) .notNull(), }); diff --git a/packages/cli/test/__snapshots__/auth-schema-sqlite-passkey.txt b/packages/cli/test/__snapshots__/auth-schema-sqlite-passkey.txt index 5f08e677f8..779f13defa 100644 --- a/packages/cli/test/__snapshots__/auth-schema-sqlite-passkey.txt +++ b/packages/cli/test/__snapshots__/auth-schema-sqlite-passkey.txt @@ -1,3 +1,4 @@ +import { sql } from "drizzle-orm"; import { sqliteTable, text, integer } from "drizzle-orm/sqlite-core"; export const custom_user = sqliteTable("custom_user", { @@ -9,10 +10,10 @@ export const custom_user = sqliteTable("custom_user", { .notNull(), image: text("image"), createdAt: integer("created_at", { mode: "timestamp" }) - .defaultNow() + .default(sql`(current_timestamp)`) .notNull(), updatedAt: integer("updated_at", { mode: "timestamp" }) - .defaultNow() + .default(sql`(current_timestamp)`) .$onUpdate(() => /* @__PURE__ */ new Date()) .notNull(), }); @@ -22,7 +23,7 @@ export const custom_session = sqliteTable("custom_session", { expiresAt: integer("expires_at", { mode: "timestamp" }).notNull(), token: text("token").notNull().unique(), createdAt: integer("created_at", { mode: "timestamp" }) - .defaultNow() + .default(sql`(current_timestamp)`) .notNull(), updatedAt: integer("updated_at", { mode: "timestamp" }) .$onUpdate(() => /* @__PURE__ */ new Date()) @@ -53,7 +54,7 @@ export const custom_account = sqliteTable("custom_account", { scope: text("scope"), password: text("password"), createdAt: integer("created_at", { mode: "timestamp" }) - .defaultNow() + .default(sql`(current_timestamp)`) .notNull(), updatedAt: integer("updated_at", { mode: "timestamp" }) .$onUpdate(() => /* @__PURE__ */ new Date()) @@ -66,10 +67,10 @@ export const custom_verification = sqliteTable("custom_verification", { value: text("value").notNull(), expiresAt: integer("expires_at", { mode: "timestamp" }).notNull(), createdAt: integer("created_at", { mode: "timestamp" }) - .defaultNow() + .default(sql`(current_timestamp)`) .notNull(), updatedAt: integer("updated_at", { mode: "timestamp" }) - .defaultNow() + .default(sql`(current_timestamp)`) .$onUpdate(() => /* @__PURE__ */ new Date()) .notNull(), }); diff --git a/packages/cli/test/__snapshots__/auth-schema-sqlite.txt b/packages/cli/test/__snapshots__/auth-schema-sqlite.txt index ebb4a9cde1..4b3b7bdc7f 100644 --- a/packages/cli/test/__snapshots__/auth-schema-sqlite.txt +++ b/packages/cli/test/__snapshots__/auth-schema-sqlite.txt @@ -1,3 +1,4 @@ +import { sql } from "drizzle-orm"; import { sqliteTable, text, integer } from "drizzle-orm/sqlite-core"; export const custom_user = sqliteTable("custom_user", { @@ -9,10 +10,10 @@ export const custom_user = sqliteTable("custom_user", { .notNull(), image: text("image"), createdAt: integer("created_at", { mode: "timestamp" }) - .defaultNow() + .default(sql`(current_timestamp)`) .notNull(), updatedAt: integer("updated_at", { mode: "timestamp" }) - .defaultNow() + .default(sql`(current_timestamp)`) .$onUpdate(() => /* @__PURE__ */ new Date()) .notNull(), twoFactorEnabled: integer("two_factor_enabled", { mode: "boolean" }).default( @@ -27,7 +28,7 @@ export const custom_session = sqliteTable("custom_session", { expiresAt: integer("expires_at", { mode: "timestamp" }).notNull(), token: text("token").notNull().unique(), createdAt: integer("created_at", { mode: "timestamp" }) - .defaultNow() + .default(sql`(current_timestamp)`) .notNull(), updatedAt: integer("updated_at", { mode: "timestamp" }) .$onUpdate(() => /* @__PURE__ */ new Date()) @@ -58,7 +59,7 @@ export const custom_account = sqliteTable("custom_account", { scope: text("scope"), password: text("password"), createdAt: integer("created_at", { mode: "timestamp" }) - .defaultNow() + .default(sql`(current_timestamp)`) .notNull(), updatedAt: integer("updated_at", { mode: "timestamp" }) .$onUpdate(() => /* @__PURE__ */ new Date()) @@ -71,10 +72,10 @@ export const custom_verification = sqliteTable("custom_verification", { value: text("value").notNull(), expiresAt: integer("expires_at", { mode: "timestamp" }).notNull(), createdAt: integer("created_at", { mode: "timestamp" }) - .defaultNow() + .default(sql`(current_timestamp)`) .notNull(), updatedAt: integer("updated_at", { mode: "timestamp" }) - .defaultNow() + .default(sql`(current_timestamp)`) .$onUpdate(() => /* @__PURE__ */ new Date()) .notNull(), });