auth 1.5.6 → 1.5.7-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/api.mjs CHANGED
@@ -7,7 +7,6 @@ import fs from "node:fs/promises";
7
7
  import path from "node:path";
8
8
  import { capitalizeFirstLetter } from "@better-auth/core/utils/string";
9
9
  import { produceSchema } from "@mrleebo/prisma-ast";
10
-
11
10
  //#region src/generators/drizzle.ts
12
11
  function convertToSnakeCase(str, camelCase) {
13
12
  if (camelCase) return str;
@@ -139,7 +138,7 @@ const generateDrizzleSchema = async ({ options, file, adapter }) => {
139
138
  if (attr.onUpdate && attr.type === "date") {
140
139
  if (typeof attr.onUpdate === "function") type += `.$onUpdate(${attr.onUpdate})`;
141
140
  }
142
- return `${fieldName}: ${type}${attr.required ? ".notNull()" : ""}${attr.unique ? ".unique()" : ""}${attr.references ? `.references(()=> ${getModelName(attr.references.model)}.${getFieldName({
141
+ return `${fieldName}: ${type}${attr.required !== false ? ".notNull()" : ""}${attr.unique ? ".unique()" : ""}${attr.references ? `.references(()=> ${getModelName(attr.references.model)}.${getFieldName({
143
142
  model: attr.references.model,
144
143
  field: attr.references.field
145
144
  })}, { onDelete: '${attr.references.onDelete || "cascade"}' })` : ""}`;
@@ -296,7 +295,6 @@ function generateImport({ databaseType, tables, options }) {
296
295
  if (hasUniqueIndexes) coreImports.push("uniqueIndex");
297
296
  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`;
298
297
  }
299
-
300
298
  //#endregion
301
299
  //#region src/generators/kysely.ts
302
300
  const generateKyselySchema = async ({ options, file }) => {
@@ -307,7 +305,6 @@ const generateKyselySchema = async ({ options, file }) => {
307
305
  fileName: file || `./better-auth_migrations/${(/* @__PURE__ */ new Date()).toISOString().replace(/:/g, "-")}.sql`
308
306
  };
309
307
  };
310
-
311
308
  //#endregion
312
309
  //#region src/utils/get-package-info.ts
313
310
  function getPackageInfo(cwd) {
@@ -325,7 +322,6 @@ function getPrismaVersion(cwd) {
325
322
  return null;
326
323
  }
327
324
  }
328
-
329
325
  //#endregion
330
326
  //#region src/generators/prisma.ts
331
327
  const generatePrismaSchema = async ({ adapter, options, file }) => {
@@ -435,7 +431,7 @@ const generatePrismaSchema = async ({ adapter, options, file }) => {
435
431
  type: "number"
436
432
  }) : getType({
437
433
  isBigint: attr?.bigint || false,
438
- isOptional: !attr?.required,
434
+ isOptional: attr?.required === false,
439
435
  type: attr.references?.field === "id" ? useNumberId ? "number" : "string" : attr.type
440
436
  }));
441
437
  if (field === "id") {
@@ -497,7 +493,7 @@ const generatePrismaSchema = async ({ adapter, options, file }) => {
497
493
  model: attr.references.model,
498
494
  field: attr.references.field
499
495
  })}], onDelete: ${action})`;
500
- builder.model(modelName).field(referencedCustomModelName.toLowerCase(), `${capitalizeFirstLetter(referencedCustomModelName)}${!attr.required ? "?" : ""}`).attribute(relationField);
496
+ builder.model(modelName).field(referencedCustomModelName.toLowerCase(), `${capitalizeFirstLetter(referencedCustomModelName)}${attr.required === false ? "?" : ""}`).attribute(relationField);
501
497
  }
502
498
  if (!attr.unique && !attr.references && provider === "mysql" && attr.type === "string") builder.model(modelName).field(fieldName).attribute("db.Text");
503
499
  }
@@ -562,7 +558,6 @@ const getNewPrisma = (provider, cwd) => {
562
558
  url = ${provider === "sqlite" ? `"file:./dev.db"` : `env("DATABASE_URL")`}
563
559
  }`;
564
560
  };
565
-
566
561
  //#endregion
567
562
  //#region src/generators/index.ts
568
563
  const adapters = {
@@ -581,7 +576,7 @@ const generateSchema = (opts) => {
581
576
  }));
582
577
  throw new Error(`${adapter.id} is not supported. If it is a custom adapter, please request the maintainer to implement createSchema`);
583
578
  };
584
-
585
579
  //#endregion
586
580
  export { adapters, generateDrizzleSchema, generateKyselySchema, generatePrismaSchema, generateSchema };
581
+
587
582
  //# sourceMappingURL=api.mjs.map
package/dist/api.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"api.mjs","names":[],"sources":["../src/generators/drizzle.ts","../src/generators/kysely.ts","../src/utils/get-package-info.ts","../src/generators/prisma.ts","../src/generators/index.ts"],"sourcesContent":["import { existsSync } from \"node:fs\";\nimport { initGetFieldName, initGetModelName } from \"better-auth/adapters\";\nimport type { BetterAuthDBSchema, DBFieldAttribute } from \"better-auth/db\";\nimport { getAuthTables } from \"better-auth/db\";\nimport type { BetterAuthOptions } from \"better-auth/types\";\nimport prettier from \"prettier\";\nimport type { SchemaGenerator } from \"./types\";\n\nfunction convertToSnakeCase(str: string, camelCase?: boolean) {\n\tif (camelCase) {\n\t\treturn str;\n\t}\n\t// Handle consecutive capitals (like ID, URL, API) by treating them as a single word\n\treturn str\n\t\t.replace(/([A-Z]+)([A-Z][a-z])/g, \"$1_$2\") // Handle AABb -> AA_Bb\n\t\t.replace(/([a-z\\d])([A-Z])/g, \"$1_$2\") // Handle aBb -> a_Bb\n\t\t.toLowerCase();\n}\n\nexport const generateDrizzleSchema: SchemaGenerator = async ({\n\toptions,\n\tfile,\n\tadapter,\n}) => {\n\tconst tables = getAuthTables(options);\n\tconst filePath = file || \"./auth-schema.ts\";\n\tconst databaseType: \"sqlite\" | \"mysql\" | \"pg\" | undefined =\n\t\tadapter.options?.provider;\n\n\tif (!databaseType) {\n\t\tthrow new Error(\n\t\t\t`Database provider type is undefined during Drizzle schema generation. Please define a \\`provider\\` in the Drizzle adapter config. Read more at https://better-auth.com/docs/adapters/drizzle`,\n\t\t);\n\t}\n\tconst fileExist = existsSync(filePath);\n\n\tlet code: string = generateImport({\n\t\tdatabaseType,\n\t\ttables,\n\t\toptions,\n\t});\n\n\tconst getModelName = initGetModelName({\n\t\tschema: tables,\n\t\tusePlural: adapter.options?.adapterConfig?.usePlural,\n\t});\n\n\tconst getFieldName = initGetFieldName({\n\t\tschema: tables,\n\t\tusePlural: adapter.options?.adapterConfig?.usePlural,\n\t});\n\n\tfor (const tableKey in tables) {\n\t\tconst table = tables[tableKey]!;\n\t\tconst modelName = getModelName(tableKey);\n\t\tconst fields = table.fields;\n\n\t\tfunction getType(name: string, field: DBFieldAttribute) {\n\t\t\t// Not possible to reach, it's here to make typescript happy\n\t\t\tif (!databaseType) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Database provider type is undefined during Drizzle schema generation. Please define a \\`provider\\` in the Drizzle adapter config. Read more at https://better-auth.com/docs/adapters/drizzle`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tname = convertToSnakeCase(name, adapter.options?.camelCase);\n\t\t\tif (field.references?.field === \"id\") {\n\t\t\t\tconst useNumberId = options.advanced?.database?.generateId === \"serial\";\n\t\t\t\tconst useUUIDs = options.advanced?.database?.generateId === \"uuid\";\n\t\t\t\tif (useNumberId) {\n\t\t\t\t\tif (databaseType === \"pg\") {\n\t\t\t\t\t\treturn `integer('${name}')`;\n\t\t\t\t\t} else if (databaseType === \"mysql\") {\n\t\t\t\t\t\treturn `int('${name}')`;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// using sqlite\n\t\t\t\t\t\treturn `integer('${name}')`;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (useUUIDs && databaseType === \"pg\") {\n\t\t\t\t\treturn `uuid('${name}')`;\n\t\t\t\t}\n\t\t\t\tif (field.references.field) {\n\t\t\t\t\tif (databaseType === \"mysql\") {\n\t\t\t\t\t\treturn `varchar('${name}', { length: 36 })`;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn `text('${name}')`;\n\t\t\t}\n\t\t\tconst type = field.type;\n\t\t\tif (typeof type !== \"string\") {\n\t\t\t\tif (Array.isArray(type) && type.every((x) => typeof x === \"string\")) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tsqlite: `text({ enum: [${type.map((x) => `'${x}'`).join(\", \")}] })`,\n\t\t\t\t\t\tpg: `text('${name}', { enum: [${type.map((x) => `'${x}'`).join(\", \")}] })`,\n\t\t\t\t\t\tmysql: `mysqlEnum([${type.map((x) => `'${x}'`).join(\", \")}])`,\n\t\t\t\t\t}[databaseType];\n\t\t\t\t} else {\n\t\t\t\t\tthrow new TypeError(\n\t\t\t\t\t\t`Invalid field type for field ${name} in model ${modelName}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst typeMap: Record<\n\t\t\t\ttypeof type,\n\t\t\t\tRecord<typeof databaseType, string>\n\t\t\t> = {\n\t\t\t\tstring: {\n\t\t\t\t\tsqlite: `text('${name}')`,\n\t\t\t\t\tpg: `text('${name}')`,\n\t\t\t\t\tmysql: field.unique\n\t\t\t\t\t\t? `varchar('${name}', { length: 255 })`\n\t\t\t\t\t\t: field.references\n\t\t\t\t\t\t\t? `varchar('${name}', { length: 36 })`\n\t\t\t\t\t\t\t: field.sortable\n\t\t\t\t\t\t\t\t? `varchar('${name}', { length: 255 })`\n\t\t\t\t\t\t\t\t: field.index\n\t\t\t\t\t\t\t\t\t? `varchar('${name}', { length: 255 })`\n\t\t\t\t\t\t\t\t\t: `text('${name}')`,\n\t\t\t\t},\n\t\t\t\tboolean: {\n\t\t\t\t\tsqlite: `integer('${name}', { mode: 'boolean' })`,\n\t\t\t\t\tpg: `boolean('${name}')`,\n\t\t\t\t\tmysql: `boolean('${name}')`,\n\t\t\t\t},\n\t\t\t\tnumber: {\n\t\t\t\t\tsqlite: `integer('${name}')`,\n\t\t\t\t\tpg: field.bigint\n\t\t\t\t\t\t? `bigint('${name}', { mode: 'number' })`\n\t\t\t\t\t\t: `integer('${name}')`,\n\t\t\t\t\tmysql: field.bigint\n\t\t\t\t\t\t? `bigint('${name}', { mode: 'number' })`\n\t\t\t\t\t\t: `int('${name}')`,\n\t\t\t\t},\n\t\t\t\tdate: {\n\t\t\t\t\tsqlite: `integer('${name}', { mode: 'timestamp_ms' })`,\n\t\t\t\t\tpg: `timestamp('${name}')`,\n\t\t\t\t\tmysql: `timestamp('${name}', { fsp: 3 })`,\n\t\t\t\t},\n\t\t\t\t\"number[]\": {\n\t\t\t\t\tsqlite: `text('${name}', { mode: \"json\" })`,\n\t\t\t\t\tpg: field.bigint\n\t\t\t\t\t\t? `bigint('${name}', { mode: 'number' }).array()`\n\t\t\t\t\t\t: `integer('${name}').array()`,\n\t\t\t\t\tmysql: `text('${name}', { mode: 'json' })`,\n\t\t\t\t},\n\t\t\t\t\"string[]\": {\n\t\t\t\t\tsqlite: `text('${name}', { mode: \"json\" })`,\n\t\t\t\t\tpg: `text('${name}').array()`,\n\t\t\t\t\tmysql: `text('${name}', { mode: \"json\" })`,\n\t\t\t\t},\n\t\t\t\tjson: {\n\t\t\t\t\tsqlite: `text('${name}', { mode: \"json\" })`,\n\t\t\t\t\tpg: `jsonb('${name}')`,\n\t\t\t\t\tmysql: `json('${name}', { mode: \"json\" })`,\n\t\t\t\t},\n\t\t\t} as const;\n\t\t\tconst dbTypeMap = (\n\t\t\t\ttypeMap as Record<string, Record<typeof databaseType, string>>\n\t\t\t)[type as string];\n\t\t\tif (!dbTypeMap) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Unsupported field type '${field.type}' for field '${name}'.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn dbTypeMap[databaseType];\n\t\t}\n\n\t\tlet id: string = \"\";\n\n\t\tconst useNumberId = options.advanced?.database?.generateId === \"serial\";\n\t\tconst useUUIDs = options.advanced?.database?.generateId === \"uuid\";\n\n\t\tif (useUUIDs && databaseType === \"pg\") {\n\t\t\tid = `uuid(\"id\").default(sql\\`pg_catalog.gen_random_uuid()\\`).primaryKey()`;\n\t\t} else if (useNumberId) {\n\t\t\tif (databaseType === \"pg\") {\n\t\t\t\tid = `integer(\"id\").generatedByDefaultAsIdentity().primaryKey()`;\n\t\t\t} else if (databaseType === \"sqlite\") {\n\t\t\t\tid = `integer(\"id\", { mode: \"number\" }).primaryKey({ autoIncrement: true })`;\n\t\t\t} else {\n\t\t\t\tid = `int(\"id\").autoincrement().primaryKey()`;\n\t\t\t}\n\t\t} else {\n\t\t\tif (databaseType === \"mysql\") {\n\t\t\t\tid = `varchar('id', { length: 36 }).primaryKey()`;\n\t\t\t} else if (databaseType === \"pg\") {\n\t\t\t\tid = `text('id').primaryKey()`;\n\t\t\t} else {\n\t\t\t\tid = `text('id').primaryKey()`;\n\t\t\t}\n\t\t}\n\n\t\ttype Index = { type: \"uniqueIndex\" | \"index\"; name: string; on: string };\n\n\t\tconst indexes: Index[] = [];\n\n\t\tconst assignIndexes = (indexes: Index[]): string => {\n\t\t\tif (!indexes.length) return \"\";\n\n\t\t\tconst code: string[] = [`, (table) => [`];\n\n\t\t\tfor (const index of indexes) {\n\t\t\t\tcode.push(` ${index.type}(\"${index.name}\").on(table.${index.on}),`);\n\t\t\t}\n\n\t\t\tcode.push(`]`);\n\n\t\t\treturn code.join(\"\\n\");\n\t\t};\n\n\t\tconst schema = `export const ${modelName} = ${databaseType}Table(\"${convertToSnakeCase(\n\t\t\tmodelName,\n\t\t\tadapter.options?.camelCase,\n\t\t)}\", {\n\t\t\t\t\tid: ${id},\n\t\t\t\t\t${Object.keys(fields)\n\t\t\t\t\t\t.map((field) => {\n\t\t\t\t\t\t\tconst attr = fields[field]!;\n\t\t\t\t\t\t\tconst fieldName = attr.fieldName || field;\n\t\t\t\t\t\t\tlet type = getType(fieldName, attr);\n\n\t\t\t\t\t\t\tif (attr.index && !attr.unique) {\n\t\t\t\t\t\t\t\tindexes.push({\n\t\t\t\t\t\t\t\t\ttype: \"index\",\n\t\t\t\t\t\t\t\t\tname: `${modelName}_${fieldName}_idx`,\n\t\t\t\t\t\t\t\t\ton: fieldName,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t} else if (attr.index && attr.unique) {\n\t\t\t\t\t\t\t\tindexes.push({\n\t\t\t\t\t\t\t\t\ttype: \"uniqueIndex\",\n\t\t\t\t\t\t\t\t\tname: `${modelName}_${fieldName}_uidx`,\n\t\t\t\t\t\t\t\t\ton: fieldName,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tattr.defaultValue !== null &&\n\t\t\t\t\t\t\t\ttypeof attr.defaultValue !== \"undefined\"\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tif (typeof attr.defaultValue === \"function\") {\n\t\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t\tattr.type === \"date\" &&\n\t\t\t\t\t\t\t\t\t\tattr.defaultValue.toString().includes(\"new Date()\")\n\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\tif (databaseType === \"sqlite\") {\n\t\t\t\t\t\t\t\t\t\t\ttype += `.default(sql\\`(cast(unixepoch('subsecond') * 1000 as integer))\\`)`;\n\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\ttype += `.defaultNow()`;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t// we are intentionally not adding .$defaultFn(${attr.defaultValue})\n\t\t\t\t\t\t\t\t\t\t// this is because if the defaultValue is a function, it could have\n\t\t\t\t\t\t\t\t\t\t// custom logic within that function that might not work in drizzle's context.\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} else if (typeof attr.defaultValue === \"string\") {\n\t\t\t\t\t\t\t\t\ttype += `.default(\"${attr.defaultValue}\")`;\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\ttype += `.default(${attr.defaultValue})`;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// Add .$onUpdate() for fields with onUpdate property\n\t\t\t\t\t\t\t// Supported for all database types: PostgreSQL, MySQL, and SQLite\n\t\t\t\t\t\t\tif (attr.onUpdate && attr.type === \"date\") {\n\t\t\t\t\t\t\t\tif (typeof attr.onUpdate === \"function\") {\n\t\t\t\t\t\t\t\t\ttype += `.$onUpdate(${attr.onUpdate})`;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\treturn `${fieldName}: ${type}${attr.required ? \".notNull()\" : \"\"}${\n\t\t\t\t\t\t\t\tattr.unique ? \".unique()\" : \"\"\n\t\t\t\t\t\t\t}${\n\t\t\t\t\t\t\t\tattr.references\n\t\t\t\t\t\t\t\t\t? `.references(()=> ${getModelName(\n\t\t\t\t\t\t\t\t\t\t\tattr.references.model,\n\t\t\t\t\t\t\t\t\t\t)}.${getFieldName({ model: attr.references.model, field: attr.references.field })}, { onDelete: '${\n\t\t\t\t\t\t\t\t\t\t\tattr.references.onDelete || \"cascade\"\n\t\t\t\t\t\t\t\t\t\t}' })`\n\t\t\t\t\t\t\t\t\t: \"\"\n\t\t\t\t\t\t\t}`;\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.join(\",\\n \")}\n\t\t\t\t\t}${assignIndexes(indexes)});`;\n\t\tcode += `\\n${schema}\\n`;\n\t}\n\n\tlet relationsString: string = \"\";\n\tfor (const tableKey in tables) {\n\t\tconst table = tables[tableKey]!;\n\t\tconst modelName = getModelName(tableKey);\n\n\t\ttype Relation = {\n\t\t\t/**\n\t\t\t * The key of the relation that will be defined in the Drizzle schema.\n\t\t\t * For \"one\" relations: singular (e.g., \"user\")\n\t\t\t * For \"many\" relations: plural (e.g., \"posts\")\n\t\t\t */\n\t\t\tkey: string;\n\t\t\t/**\n\t\t\t * The model name being referenced.\n\t\t\t */\n\t\t\tmodel: string;\n\t\t\t/**\n\t\t\t * The type of the relation: \"one\" (many-to-one) or \"many\" (one-to-many).\n\t\t\t */\n\t\t\ttype: \"one\" | \"many\";\n\t\t\t/**\n\t\t\t * Foreign key field name and reference details (only for \"one\" relations).\n\t\t\t */\n\t\t\treference?: {\n\t\t\t\tfield: string;\n\t\t\t\treferences: string;\n\t\t\t\tfieldName: string; // Original field name for generating unique relation export names\n\t\t\t};\n\t\t};\n\n\t\tconst oneRelations: Relation[] = [];\n\t\tconst manyRelations: Relation[] = [];\n\t\t// Set to track \"many\" relations by key to prevent duplicates\n\t\tconst manyRelationsSet = new Set<string>();\n\n\t\t// 1. Find all foreign keys in THIS table (creates \"one\" relations)\n\t\tconst fields = Object.entries(table.fields);\n\t\tconst foreignFields = fields.filter(([_, field]) => field.references);\n\n\t\tfor (const [fieldName, field] of foreignFields) {\n\t\t\tconst referencedModel = field.references!.model;\n\t\t\tconst relationKey = getModelName(referencedModel);\n\t\t\tconst fieldRef = `${getModelName(tableKey)}.${getFieldName({ model: tableKey, field: fieldName })}`;\n\t\t\tconst referenceRef = `${getModelName(referencedModel)}.${getFieldName({ model: referencedModel, field: field.references!.field || \"id\" })}`;\n\n\t\t\t// Create a separate relation for each foreign key\n\t\t\toneRelations.push({\n\t\t\t\tkey: relationKey,\n\t\t\t\tmodel: getModelName(referencedModel),\n\t\t\t\ttype: \"one\",\n\t\t\t\treference: {\n\t\t\t\t\tfield: fieldRef,\n\t\t\t\t\treferences: referenceRef,\n\t\t\t\t\tfieldName: fieldName,\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\n\t\t// 2. Find all OTHER tables that reference THIS table (creates \"many\" relations)\n\t\tconst otherModels = Object.entries(tables).filter(\n\t\t\t([modelName]) => modelName !== tableKey,\n\t\t);\n\n\t\t// Map to track relations by model name to determine if unique or many\n\t\tconst modelRelationsMap = new Map<\n\t\t\tstring,\n\t\t\t{\n\t\t\t\tmodelName: string;\n\t\t\t\thasUnique: boolean;\n\t\t\t\thasMany: boolean;\n\t\t\t}\n\t\t>();\n\n\t\tfor (const [modelName, otherTable] of otherModels) {\n\t\t\tconst foreignKeysPointingHere = Object.entries(otherTable.fields).filter(\n\t\t\t\t([_, field]) =>\n\t\t\t\t\tfield.references?.model === tableKey ||\n\t\t\t\t\tfield.references?.model === getModelName(tableKey),\n\t\t\t);\n\n\t\t\tif (foreignKeysPointingHere.length === 0) continue;\n\n\t\t\t// Check if any foreign key is unique\n\t\t\tconst hasUnique = foreignKeysPointingHere.some(\n\t\t\t\t([_, field]) => !!field.unique,\n\t\t\t);\n\t\t\tconst hasMany = foreignKeysPointingHere.some(\n\t\t\t\t([_, field]) => !field.unique,\n\t\t\t);\n\n\t\t\tmodelRelationsMap.set(modelName, {\n\t\t\t\tmodelName,\n\t\t\t\thasUnique,\n\t\t\t\thasMany,\n\t\t\t});\n\t\t}\n\n\t\t// Add relations, deduplicating by relationKey\n\t\tfor (const { modelName, hasMany } of modelRelationsMap.values()) {\n\t\t\t// Determine relation type: if all are unique, it's \"one\", otherwise \"many\"\n\t\t\tconst relationType = hasMany ? \"many\" : \"one\";\n\t\t\tlet relationKey = getModelName(modelName);\n\n\t\t\t// We have to apply this after checking if they have usePlural because otherwise they will end up seeing:\n\t\t\t/* cspell:disable-next-line */\n\t\t\t// \"sesionss\", or \"accountss\" - double s's.\n\t\t\tif (\n\t\t\t\t!adapter.options?.adapterConfig?.usePlural &&\n\t\t\t\trelationType === \"many\"\n\t\t\t) {\n\t\t\t\trelationKey = `${relationKey}s`;\n\t\t\t}\n\n\t\t\t// Only add if we haven't seen this key before\n\t\t\tif (!manyRelationsSet.has(relationKey)) {\n\t\t\t\tmanyRelationsSet.add(relationKey);\n\t\t\t\tmanyRelations.push({\n\t\t\t\t\tkey: relationKey,\n\t\t\t\t\tmodel: getModelName(modelName),\n\t\t\t\t\ttype: relationType,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// Group \"one\" relations by referenced model to detect duplicates\n\t\tconst relationsByModel = new Map<string, Relation[]>();\n\t\tfor (const relation of oneRelations) {\n\t\t\tif (relation.reference) {\n\t\t\t\tconst modelKey = relation.key;\n\t\t\t\tif (!relationsByModel.has(modelKey)) {\n\t\t\t\t\trelationsByModel.set(modelKey, []);\n\t\t\t\t}\n\t\t\t\trelationsByModel.get(modelKey)!.push(relation);\n\t\t\t}\n\t\t}\n\n\t\t// Separate relations with duplicates (same model) from those without\n\t\tconst duplicateRelations: Relation[] = [];\n\t\tconst singleRelations: Relation[] = [];\n\n\t\tfor (const [_modelKey, relations] of relationsByModel.entries()) {\n\t\t\tif (relations.length > 1) {\n\t\t\t\t// Multiple relations to the same model - these need field-specific naming\n\t\t\t\tduplicateRelations.push(...relations);\n\t\t\t} else {\n\t\t\t\t// Single relation to this model - can be combined with others\n\t\t\t\tsingleRelations.push(relations[0]!);\n\t\t\t}\n\t\t}\n\n\t\t// Generate field-specific exports for duplicate relations\n\t\tfor (const relation of duplicateRelations) {\n\t\t\tif (relation.reference) {\n\t\t\t\tconst fieldName = relation.reference.fieldName;\n\t\t\t\tconst relationExportName = `${modelName}${fieldName.charAt(0).toUpperCase() + fieldName.slice(1)}Relations`;\n\n\t\t\t\tconst tableRelation = `export const ${relationExportName} = relations(${getModelName(\n\t\t\t\t\ttable.modelName,\n\t\t\t\t)}, ({ one }) => ({\n\t\t\t\t${relation.key}: one(${relation.model}, {\n\t\t\t\t\tfields: [${relation.reference.field}],\n\t\t\t\t\treferences: [${relation.reference.references}],\n\t\t\t\t})\n\t\t\t}))`;\n\n\t\t\t\trelationsString += `\\n${tableRelation}\\n`;\n\t\t\t}\n\t\t}\n\n\t\t// Combine all single \"one\" relations and \"many\" relations into exports\n\t\tconst hasOne = singleRelations.length > 0;\n\t\tconst hasMany = manyRelations.length > 0;\n\n\t\tif (hasOne && hasMany) {\n\t\t\t// Both \"one\" and \"many\" relations exist - combine in one export\n\t\t\tconst tableRelation = `export const ${modelName}Relations = relations(${getModelName(\n\t\t\t\ttable.modelName,\n\t\t\t)}, ({ one, many }) => ({\n\t\t\t\t${singleRelations\n\t\t\t\t\t.map((relation) =>\n\t\t\t\t\t\trelation.reference\n\t\t\t\t\t\t\t? ` ${relation.key}: one(${relation.model}, {\n\t\t\t\t\tfields: [${relation.reference.field}],\n\t\t\t\t\treferences: [${relation.reference.references}],\n\t\t\t\t})`\n\t\t\t\t\t\t\t: \"\",\n\t\t\t\t\t)\n\t\t\t\t\t.filter((x) => x !== \"\")\n\t\t\t\t\t.join(\",\\n \")}${\n\t\t\t\t\tsingleRelations.length > 0 && manyRelations.length > 0 ? \",\" : \"\"\n\t\t\t\t}\n\t\t\t\t${manyRelations\n\t\t\t\t\t.map(({ key, model }) => ` ${key}: many(${model})`)\n\t\t\t\t\t.join(\",\\n \")}\n\t\t\t}))`;\n\n\t\t\trelationsString += `\\n${tableRelation}\\n`;\n\t\t} else if (hasOne) {\n\t\t\t// Only \"one\" relations exist\n\t\t\tconst tableRelation = `export const ${modelName}Relations = relations(${getModelName(\n\t\t\t\ttable.modelName,\n\t\t\t)}, ({ one }) => ({\n\t\t\t\t${singleRelations\n\t\t\t\t\t.map((relation) =>\n\t\t\t\t\t\trelation.reference\n\t\t\t\t\t\t\t? ` ${relation.key}: one(${relation.model}, {\n\t\t\t\t\tfields: [${relation.reference.field}],\n\t\t\t\t\treferences: [${relation.reference.references}],\n\t\t\t\t})`\n\t\t\t\t\t\t\t: \"\",\n\t\t\t\t\t)\n\t\t\t\t\t.filter((x) => x !== \"\")\n\t\t\t\t\t.join(\",\\n \")}\n\t\t\t}))`;\n\n\t\t\trelationsString += `\\n${tableRelation}\\n`;\n\t\t} else if (hasMany) {\n\t\t\t// Only \"many\" relations exist\n\t\t\tconst tableRelation = `export const ${modelName}Relations = relations(${getModelName(\n\t\t\t\ttable.modelName,\n\t\t\t)}, ({ many }) => ({\n\t\t\t\t${manyRelations\n\t\t\t\t\t.map(({ key, model }) => ` ${key}: many(${model})`)\n\t\t\t\t\t.join(\",\\n \")}\n\t\t\t}))`;\n\n\t\t\trelationsString += `\\n${tableRelation}\\n`;\n\t\t}\n\t}\n\tcode += `\\n${relationsString}`;\n\n\tconst formattedCode = await prettier.format(code, {\n\t\tparser: \"typescript\",\n\t});\n\treturn {\n\t\tcode: formattedCode,\n\t\tfileName: filePath,\n\t\toverwrite: fileExist,\n\t};\n};\n\nfunction generateImport({\n\tdatabaseType,\n\ttables,\n\toptions,\n}: {\n\tdatabaseType: \"sqlite\" | \"mysql\" | \"pg\";\n\ttables: BetterAuthDBSchema;\n\toptions: BetterAuthOptions;\n}) {\n\tconst rootImports: string[] = [\"relations\"];\n\tconst coreImports: string[] = [];\n\n\tlet hasBigint = false;\n\tlet hasJson = false;\n\n\tfor (const table of Object.values(tables)) {\n\t\tfor (const field of Object.values(table.fields)) {\n\t\t\tif (field.bigint) hasBigint = true;\n\t\t\tif (field.type === \"json\") hasJson = true;\n\t\t}\n\t\tif (hasJson && hasBigint) break;\n\t}\n\n\tconst useNumberId = options.advanced?.database?.generateId === \"serial\";\n\n\tconst useUUIDs = options.advanced?.database?.generateId === \"uuid\";\n\n\tcoreImports.push(`${databaseType}Table`);\n\tcoreImports.push(\n\t\tdatabaseType === \"mysql\"\n\t\t\t? \"varchar, text\"\n\t\t\t: databaseType === \"pg\"\n\t\t\t\t? \"text\"\n\t\t\t\t: \"text\",\n\t);\n\tcoreImports.push(\n\t\thasBigint ? (databaseType !== \"sqlite\" ? \"bigint\" : \"\") : \"\",\n\t);\n\tcoreImports.push(databaseType !== \"sqlite\" ? \"timestamp, boolean\" : \"\");\n\tif (databaseType === \"mysql\") {\n\t\t// Only include int for MySQL if actually needed\n\t\tconst hasNonBigintNumber = Object.values(tables).some((table) =>\n\t\t\tObject.values(table.fields).some(\n\t\t\t\t(field) =>\n\t\t\t\t\t(field.type === \"number\" || field.type === \"number[]\") &&\n\t\t\t\t\t!field.bigint,\n\t\t\t),\n\t\t);\n\t\tconst needsInt = useNumberId || hasNonBigintNumber;\n\t\tif (needsInt) {\n\t\t\tcoreImports.push(\"int\");\n\t\t}\n\t\tconst hasEnum = Object.values(tables).some((table) =>\n\t\t\tObject.values(table.fields).some(\n\t\t\t\t(field) =>\n\t\t\t\t\ttypeof field.type !== \"string\" &&\n\t\t\t\t\tArray.isArray(field.type) &&\n\t\t\t\t\tfield.type.every((x) => typeof x === \"string\"),\n\t\t\t),\n\t\t);\n\t\tif (hasEnum) {\n\t\t\tcoreImports.push(\"mysqlEnum\");\n\t\t}\n\t} else if (databaseType === \"pg\") {\n\t\tif (useUUIDs) {\n\t\t\trootImports.push(\"sql\");\n\t\t}\n\n\t\t// Only include integer for PG if actually needed\n\t\tconst hasNonBigintNumber = Object.values(tables).some((table) =>\n\t\t\tObject.values(table.fields).some(\n\t\t\t\t(field) =>\n\t\t\t\t\t(field.type === \"number\" || field.type === \"number[]\") &&\n\t\t\t\t\t!field.bigint,\n\t\t\t),\n\t\t);\n\t\tconst hasFkToId = Object.values(tables).some((table) =>\n\t\t\tObject.values(table.fields).some(\n\t\t\t\t(field) => field.references?.field === \"id\",\n\t\t\t),\n\t\t);\n\t\t// handles the references field with useNumberId\n\t\tconst needsInteger =\n\t\t\thasNonBigintNumber ||\n\t\t\t(options.advanced?.database?.generateId === \"serial\" && hasFkToId);\n\t\tif (needsInteger) {\n\t\t\tcoreImports.push(\"integer\");\n\t\t}\n\t} else {\n\t\tcoreImports.push(\"integer\");\n\t}\n\tif (databaseType === \"pg\" && useUUIDs) {\n\t\tcoreImports.push(\"uuid\");\n\t}\n\n\t//handle json last on the import order\n\tif (hasJson) {\n\t\tif (databaseType === \"pg\") coreImports.push(\"jsonb\");\n\t\tif (databaseType === \"mysql\") coreImports.push(\"json\");\n\t\t// sqlite uses text for JSON, so there's no need to handle this case\n\t}\n\n\t// Add sql import for SQLite timestamps with defaultNow\n\tconst hasSQLiteTimestamp =\n\t\tdatabaseType === \"sqlite\" &&\n\t\tObject.values(tables).some((table) =>\n\t\t\tObject.values(table.fields).some(\n\t\t\t\t(field) =>\n\t\t\t\t\tfield.type === \"date\" &&\n\t\t\t\t\tfield.defaultValue &&\n\t\t\t\t\ttypeof field.defaultValue === \"function\" &&\n\t\t\t\t\tfield.defaultValue.toString().includes(\"new Date()\"),\n\t\t\t),\n\t\t);\n\n\tif (hasSQLiteTimestamp) {\n\t\trootImports.push(\"sql\");\n\t}\n\n\t//handle indexes\n\tconst hasIndexes = Object.values(tables).some((table) =>\n\t\tObject.values(table.fields).some((field) => field.index && !field.unique),\n\t);\n\tconst hasUniqueIndexes = Object.values(tables).some((table) =>\n\t\tObject.values(table.fields).some((field) => field.unique && field.index),\n\t);\n\tif (hasIndexes) {\n\t\tcoreImports.push(\"index\");\n\t}\n\tif (hasUniqueIndexes) {\n\t\tcoreImports.push(\"uniqueIndex\");\n\t}\n\n\treturn `${rootImports.length > 0 ? `import { ${rootImports.join(\", \")} } from \"drizzle-orm\";\\n` : \"\"}import { ${coreImports\n\t\t.map((x) => x.trim())\n\t\t.filter((x) => x !== \"\")\n\t\t.join(\", \")} } from \"drizzle-orm/${databaseType}-core\";\\n`;\n}\n","import { getMigrations } from \"better-auth/db/migration\";\nimport type { SchemaGenerator } from \"./types\";\n\nexport const generateKyselySchema: SchemaGenerator = async ({\n\toptions,\n\tfile,\n}) => {\n\tconst { compileMigrations } = await getMigrations(options);\n\tconst migrations = await compileMigrations();\n\treturn {\n\t\tcode: migrations.trim() === \";\" ? \"\" : migrations,\n\t\tfileName:\n\t\t\tfile ||\n\t\t\t`./better-auth_migrations/${new Date()\n\t\t\t\t.toISOString()\n\t\t\t\t.replace(/:/g, \"-\")}.sql`,\n\t};\n};\n","import { readFileSync } from \"node:fs\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { tryCatch } from \"./helper\";\n\nexport function getPackageInfo(cwd?: string) {\n\tconst packageJsonPath = cwd\n\t\t? path.join(cwd, \"package.json\")\n\t\t: path.join(\"package.json\");\n\treturn JSON.parse(readFileSync(packageJsonPath, \"utf-8\"));\n}\n\nexport function getPrismaVersion(cwd?: string): number | null {\n\ttry {\n\t\tconst packageInfo = getPackageInfo(cwd);\n\t\tconst prismaVersion =\n\t\t\tpackageInfo.dependencies?.prisma ||\n\t\t\tpackageInfo.devDependencies?.prisma ||\n\t\t\tpackageInfo.dependencies?.[\"@prisma/client\"] ||\n\t\t\tpackageInfo.devDependencies?.[\"@prisma/client\"];\n\n\t\tif (!prismaVersion) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Extract major version number from version string\n\t\t// Handles versions like \"^5.0.0\", \"~7.1.0\", \"7.0.0\", etc.\n\t\tconst match = prismaVersion.match(/(\\d+)/);\n\t\treturn match ? parseInt(match[1], 10) : null;\n\t} catch {\n\t\t// If package.json doesn't exist or can't be read, return null\n\t\treturn null;\n\t}\n}\n\n/**\n * Checks if a package has a specific dependency.\n *\n * @param packageJson The package.json object\n * @param dependency The dependency to check for\n * @returns true if the package has the dependency\n */\nexport function hasDependency(packageJson: any, dependency: string) {\n\tlet hasDependency = false;\n\n\tif (\n\t\tpackageJson.dependencies?.[dependency] ||\n\t\tpackageJson.devDependencies?.[dependency] ||\n\t\tpackageJson.peerDependencies?.[dependency] ||\n\t\tpackageJson.optionalDependencies?.[dependency]\n\t) {\n\t\thasDependency = true;\n\t}\n\n\treturn hasDependency;\n}\n\n/**\n * Checks if a directory is a monorepo root by looking for common monorepo indicators.\n *\n * @param dir Directory to check\n * @returns true if the directory appears to be a monorepo root\n */\nasync function isMonorepoRoot(dir: string) {\n\tconst { data: files } = await tryCatch(fs.readdir(dir, \"utf-8\"));\n\tif (!files) return false;\n\n\t// Check for pnpm workspace\n\tif (files.includes(\"pnpm-workspace.yaml\")) {\n\t\treturn true;\n\t}\n\n\t// Check for yarn/npm workspaces in package.json\n\tif (files.includes(\"package.json\")) {\n\t\tconst packageJsonPath = path.join(dir, \"package.json\");\n\t\tconst { data } = await tryCatch(fs.readFile(packageJsonPath, \"utf-8\"));\n\t\tif (data) {\n\t\t\ttry {\n\t\t\t\tconst packageJson = JSON.parse(data);\n\t\t\t\t// Check for workspaces field (npm/yarn workspaces)\n\t\t\t\t// Workspaces can be an array or an object\n\t\t\t\tif (\n\t\t\t\t\tpackageJson.workspaces &&\n\t\t\t\t\t(Array.isArray(packageJson.workspaces) ||\n\t\t\t\t\t\ttypeof packageJson.workspaces === \"object\")\n\t\t\t\t) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Ignore JSON parse errors\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check for other monorepo indicators\n\tconst monorepoIndicators = [\n\t\t\"lerna.json\", // Lerna\n\t\t/* cSpell:disable */\n\t\t\"turbo.json\", // Turborepo\n\t\t\"nx.json\", // Nx\n\t\t\"rush.json\", // Rush\n\t];\n\n\treturn monorepoIndicators.some((indicator) => files.includes(indicator));\n}\n\n/**\n * Finds the monorepo root by walking up the directory tree.\n *\n * @param startDir Starting directory\n * @returns Path to monorepo root, or null if not found\n */\nexport async function findMonorepoRoot(\n\tstartDir: string,\n): Promise<string | null> {\n\tlet currentDir = path.resolve(startDir);\n\tconst root = path.parse(currentDir).root;\n\n\twhile (currentDir !== root) {\n\t\tif (await isMonorepoRoot(currentDir)) {\n\t\t\treturn currentDir;\n\t\t}\n\t\tconst parentDir = path.dirname(currentDir);\n\t\tif (parentDir === currentDir) {\n\t\t\tbreak;\n\t\t}\n\t\tcurrentDir = parentDir;\n\t}\n\n\treturn null;\n}\n","import { existsSync } from \"node:fs\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { capitalizeFirstLetter } from \"@better-auth/core/utils/string\";\nimport { produceSchema } from \"@mrleebo/prisma-ast\";\nimport { initGetFieldName, initGetModelName } from \"better-auth/adapters\";\nimport type { DBFieldType } from \"better-auth/db\";\nimport { getAuthTables } from \"better-auth/db\";\nimport { getPrismaVersion } from \"../utils/get-package-info\";\nimport type { SchemaGenerator } from \"./types\";\n\nexport const generatePrismaSchema: SchemaGenerator = async ({\n\tadapter,\n\toptions,\n\tfile,\n}) => {\n\tconst provider: \"sqlite\" | \"postgresql\" | \"mysql\" | \"mongodb\" =\n\t\tadapter.options?.provider || \"postgresql\";\n\tconst tables = getAuthTables(options);\n\tconst filePath = file || \"./prisma/schema.prisma\";\n\tconst schemaPrismaExist = existsSync(path.join(process.cwd(), filePath));\n\n\tconst getModelName = initGetModelName({\n\t\tschema: getAuthTables(options),\n\t\tusePlural: adapter.options?.adapterConfig?.usePlural,\n\t});\n\tconst getFieldName = initGetFieldName({\n\t\tschema: getAuthTables(options),\n\t\tusePlural: false,\n\t});\n\n\tlet schemaPrisma = \"\";\n\tif (schemaPrismaExist) {\n\t\tschemaPrisma = await fs.readFile(\n\t\t\tpath.join(process.cwd(), filePath),\n\t\t\t\"utf-8\",\n\t\t);\n\t} else {\n\t\tschemaPrisma = getNewPrisma(provider, process.cwd());\n\t}\n\n\t// Update generator and datasource blocks for Prisma v7+ in existing schemas\n\tconst prismaVersion = getPrismaVersion(process.cwd());\n\tif (prismaVersion && prismaVersion >= 7 && schemaPrismaExist) {\n\t\tschemaPrisma = produceSchema(schemaPrisma, (builder) => {\n\t\t\tconst generator: any = builder.findByType(\"generator\", {\n\t\t\t\tname: \"client\",\n\t\t\t});\n\t\t\tif (generator && generator.properties) {\n\t\t\t\tconst providerProp = generator.properties.find(\n\t\t\t\t\t(prop: any) => prop.type === \"assignment\" && prop.key === \"provider\",\n\t\t\t\t);\n\t\t\t\tif (providerProp && providerProp.value === '\"prisma-client-js\"') {\n\t\t\t\t\tproviderProp.value = '\"prisma-client\"';\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Remove url from datasource block (now configured in prisma.config.ts)\n\t\t\tconst datasource: any = builder.findByType(\"datasource\", {\n\t\t\t\tname: \"db\",\n\t\t\t});\n\t\t\tif (datasource && datasource.properties) {\n\t\t\t\tconst urlIndex = datasource.properties.findIndex(\n\t\t\t\t\t(prop: any) => prop.type === \"assignment\" && prop.key === \"url\",\n\t\t\t\t);\n\t\t\t\tif (urlIndex !== -1) {\n\t\t\t\t\tdatasource.properties.splice(urlIndex, 1);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\n\tconst manyToManyRelations = new Map();\n\n\tfor (const table in tables) {\n\t\tconst fields = tables[table]?.fields;\n\t\tfor (const field in fields) {\n\t\t\tconst attr = fields[field]!;\n\t\t\tif (attr.references) {\n\t\t\t\tconst referencedOriginalModel = attr.references.model;\n\t\t\t\tconst referencedCustomModel =\n\t\t\t\t\ttables[referencedOriginalModel]?.modelName || referencedOriginalModel;\n\t\t\t\tconst referencedModelNameCap = capitalizeFirstLetter(\n\t\t\t\t\tgetModelName(referencedCustomModel),\n\t\t\t\t);\n\n\t\t\t\tif (!manyToManyRelations.has(referencedModelNameCap)) {\n\t\t\t\t\tmanyToManyRelations.set(referencedModelNameCap, new Set());\n\t\t\t\t}\n\n\t\t\t\tconst currentCustomModel = tables[table]?.modelName || table;\n\t\t\t\tconst currentModelNameCap = capitalizeFirstLetter(\n\t\t\t\t\tgetModelName(currentCustomModel),\n\t\t\t\t);\n\n\t\t\t\tmanyToManyRelations\n\t\t\t\t\t.get(referencedModelNameCap)\n\t\t\t\t\t.add(currentModelNameCap);\n\t\t\t}\n\t\t}\n\t}\n\n\tconst indexedFields = new Map<string, string[]>();\n\tfor (const table in tables) {\n\t\tconst fields = tables[table]?.fields;\n\t\tconst customModelName = tables[table]?.modelName || table;\n\t\tconst modelName = capitalizeFirstLetter(getModelName(customModelName));\n\t\tindexedFields.set(modelName, []);\n\n\t\tfor (const field in fields) {\n\t\t\tconst attr = fields[field]!;\n\t\t\tif (attr.index && !attr.unique) {\n\t\t\t\tconst fieldName = attr.fieldName || field;\n\t\t\t\tindexedFields.get(modelName)!.push(fieldName);\n\t\t\t}\n\t\t}\n\t}\n\n\tconst schema = produceSchema(schemaPrisma, (builder) => {\n\t\tfor (const table in tables) {\n\t\t\tconst originalTableName = table;\n\t\t\tconst customModelName = tables[table]?.modelName || table;\n\t\t\tconst modelName = capitalizeFirstLetter(getModelName(customModelName));\n\t\t\tconst fields = tables[table]?.fields;\n\t\t\tfunction getType({\n\t\t\t\tisBigint,\n\t\t\t\tisOptional,\n\t\t\t\ttype,\n\t\t\t}: {\n\t\t\t\ttype: DBFieldType;\n\t\t\t\tisOptional: boolean;\n\t\t\t\tisBigint: boolean;\n\t\t\t}) {\n\t\t\t\tif (type === \"string\") {\n\t\t\t\t\treturn isOptional ? \"String?\" : \"String\";\n\t\t\t\t}\n\t\t\t\tif (type === \"number\" && isBigint) {\n\t\t\t\t\treturn isOptional ? \"BigInt?\" : \"BigInt\";\n\t\t\t\t}\n\t\t\t\tif (type === \"number\") {\n\t\t\t\t\treturn isOptional ? \"Int?\" : \"Int\";\n\t\t\t\t}\n\t\t\t\tif (type === \"boolean\") {\n\t\t\t\t\treturn isOptional ? \"Boolean?\" : \"Boolean\";\n\t\t\t\t}\n\t\t\t\tif (type === \"date\") {\n\t\t\t\t\treturn isOptional ? \"DateTime?\" : \"DateTime\";\n\t\t\t\t}\n\t\t\t\tif (type === \"json\") {\n\t\t\t\t\tif (provider === \"sqlite\" || provider === \"mysql\") {\n\t\t\t\t\t\treturn isOptional ? \"String?\" : \"String\";\n\t\t\t\t\t}\n\t\t\t\t\treturn isOptional ? \"Json?\" : \"Json\";\n\t\t\t\t}\n\t\t\t\tif (type === \"string[]\") {\n\t\t\t\t\t// SQLite and MySQL don't support array of strings, so we use string instead\n\t\t\t\t\t// adapter should handle JSON.stringify and JSON.parse conversion for these fields\n\t\t\t\t\tif (provider === \"sqlite\" || provider === \"mysql\") {\n\t\t\t\t\t\treturn isOptional ? \"String?\" : \"String\";\n\t\t\t\t\t}\n\t\t\t\t\treturn \"String[]\";\n\t\t\t\t}\n\t\t\t\tif (type === \"number[]\") {\n\t\t\t\t\t// SQLite and MySQL don't support array of numbers, so we use int instead\n\t\t\t\t\t// adapter should handle JSON.stringify and JSON.parse conversion for these fields\n\t\t\t\t\tif (provider === \"sqlite\" || provider === \"mysql\") {\n\t\t\t\t\t\treturn \"String\";\n\t\t\t\t\t}\n\t\t\t\t\treturn \"Int[]\";\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst prismaModel = builder.findByType(\"model\", {\n\t\t\t\tname: modelName,\n\t\t\t});\n\n\t\t\tif (!prismaModel) {\n\t\t\t\tif (provider === \"mongodb\") {\n\t\t\t\t\t// Mongo DB doesn't support auto increment, so just use their normal _id.\n\t\t\t\t\tbuilder\n\t\t\t\t\t\t.model(modelName)\n\t\t\t\t\t\t.field(\"id\", \"String\")\n\t\t\t\t\t\t.attribute(\"id\")\n\t\t\t\t\t\t.attribute(`map(\"_id\")`);\n\t\t\t\t} else {\n\t\t\t\t\tconst useNumberId =\n\t\t\t\t\t\toptions.advanced?.database?.generateId === \"serial\";\n\t\t\t\t\tconst useUUIDs = options.advanced?.database?.generateId === \"uuid\";\n\t\t\t\t\tif (useNumberId) {\n\t\t\t\t\t\tbuilder\n\t\t\t\t\t\t\t.model(modelName)\n\t\t\t\t\t\t\t.field(\"id\", \"Int\")\n\t\t\t\t\t\t\t.attribute(\"id\")\n\t\t\t\t\t\t\t.attribute(\"default(autoincrement())\");\n\t\t\t\t\t} else if (useUUIDs && provider === \"postgresql\") {\n\t\t\t\t\t\tbuilder\n\t\t\t\t\t\t\t.model(modelName)\n\t\t\t\t\t\t\t.field(\"id\", \"String\")\n\t\t\t\t\t\t\t.attribute(\"id\")\n\t\t\t\t\t\t\t.attribute('default(dbgenerated(\"pg_catalog.gen_random_uuid()\"))')\n\t\t\t\t\t\t\t.attribute(\"db.Uuid\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbuilder.model(modelName).field(\"id\", \"String\").attribute(\"id\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const field in fields) {\n\t\t\t\tconst attr = fields[field]!;\n\t\t\t\tconst fieldName = attr.fieldName || field;\n\n\t\t\t\tif (prismaModel) {\n\t\t\t\t\tconst isAlreadyExist = builder.findByType(\"field\", {\n\t\t\t\t\t\tname: fieldName,\n\t\t\t\t\t\twithin: prismaModel.properties,\n\t\t\t\t\t});\n\t\t\t\t\tif (isAlreadyExist) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst useUUIDs = options.advanced?.database?.generateId === \"uuid\";\n\t\t\t\tconst useNumberId = options.advanced?.database?.generateId === \"serial\";\n\t\t\t\tconst fieldBuilder = builder.model(modelName).field(\n\t\t\t\t\tfieldName,\n\t\t\t\t\tfield === \"id\" && useNumberId\n\t\t\t\t\t\t? getType({\n\t\t\t\t\t\t\t\tisBigint: false,\n\t\t\t\t\t\t\t\tisOptional: false,\n\t\t\t\t\t\t\t\ttype: \"number\",\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t: getType({\n\t\t\t\t\t\t\t\tisBigint: attr?.bigint || false,\n\t\t\t\t\t\t\t\tisOptional: !attr?.required,\n\t\t\t\t\t\t\t\ttype:\n\t\t\t\t\t\t\t\t\tattr.references?.field === \"id\"\n\t\t\t\t\t\t\t\t\t\t? useNumberId\n\t\t\t\t\t\t\t\t\t\t\t? \"number\"\n\t\t\t\t\t\t\t\t\t\t\t: \"string\"\n\t\t\t\t\t\t\t\t\t\t: attr.type,\n\t\t\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\tif (field === \"id\") {\n\t\t\t\t\tfieldBuilder.attribute(\"id\");\n\t\t\t\t\tif (provider === \"mongodb\") {\n\t\t\t\t\t\tfieldBuilder.attribute(`map(\"_id\")`);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (attr.unique) {\n\t\t\t\t\tbuilder.model(modelName).blockAttribute(`unique([${fieldName}])`);\n\t\t\t\t}\n\n\t\t\t\tif (attr.defaultValue !== undefined) {\n\t\t\t\t\tif (Array.isArray(attr.defaultValue)) {\n\t\t\t\t\t\t// for json objects and array of object\n\n\t\t\t\t\t\tif (attr.type === \"json\") {\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tObject.prototype.toString.call(attr.defaultValue[0]) ===\n\t\t\t\t\t\t\t\t\"[object Object]\"\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tfieldBuilder.attribute(\n\t\t\t\t\t\t\t\t\t`default(\"${JSON.stringify(attr.defaultValue).replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"')}\")`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst jsonArray = [];\n\t\t\t\t\t\t\tfor (const value of attr.defaultValue) jsonArray.push(value);\n\t\t\t\t\t\t\tfieldBuilder.attribute(\n\t\t\t\t\t\t\t\t`default(\"${JSON.stringify(jsonArray).replace(/\"/g, '\\\\\"')}\")`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (attr.defaultValue.length === 0) {\n\t\t\t\t\t\t\tfieldBuilder.attribute(`default([])`);\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\ttypeof attr.defaultValue[0] === \"string\" &&\n\t\t\t\t\t\t\tattr.type === \"string[]\"\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tconst valueArray = [];\n\t\t\t\t\t\t\tfor (const value of attr.defaultValue)\n\t\t\t\t\t\t\t\tvalueArray.push(JSON.stringify(value));\n\t\t\t\t\t\t\tfieldBuilder.attribute(`default([${valueArray}])`);\n\t\t\t\t\t\t} else if (typeof attr.defaultValue[0] === \"number\") {\n\t\t\t\t\t\t\tconst valueArray = [];\n\t\t\t\t\t\t\tfor (const value of attr.defaultValue)\n\t\t\t\t\t\t\t\tvalueArray.push(`${value}`);\n\t\t\t\t\t\t\tfieldBuilder.attribute(`default([${valueArray}])`);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// for json objects\n\t\t\t\t\telse if (\n\t\t\t\t\t\ttypeof attr.defaultValue === \"object\" &&\n\t\t\t\t\t\t!Array.isArray(attr.defaultValue) &&\n\t\t\t\t\t\tattr.defaultValue !== null\n\t\t\t\t\t) {\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tObject.entries(attr.defaultValue as Record<string, any>)\n\t\t\t\t\t\t\t\t.length === 0\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tfieldBuilder.attribute(`default(\"{}\")`);\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfieldBuilder.attribute(\n\t\t\t\t\t\t\t`default(\"${JSON.stringify(attr.defaultValue).replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"')}\")`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tif (field === \"createdAt\") {\n\t\t\t\t\t\tfieldBuilder.attribute(\"default(now())\");\n\t\t\t\t\t} else if (\n\t\t\t\t\t\ttypeof attr.defaultValue === \"string\" &&\n\t\t\t\t\t\tprovider !== \"mysql\"\n\t\t\t\t\t) {\n\t\t\t\t\t\tfieldBuilder.attribute(`default(\"${attr.defaultValue}\")`);\n\t\t\t\t\t} else if (\n\t\t\t\t\t\ttypeof attr.defaultValue === \"boolean\" ||\n\t\t\t\t\t\ttypeof attr.defaultValue === \"number\"\n\t\t\t\t\t) {\n\t\t\t\t\t\tfieldBuilder.attribute(`default(${attr.defaultValue})`);\n\t\t\t\t\t} else if (typeof attr.defaultValue === \"function\") {\n\t\t\t\t\t\t// we are intentionally not adding the default value here\n\t\t\t\t\t\t// this is because if the defaultValue is a function, it could have\n\t\t\t\t\t\t// custom logic within that function that might not work in prisma's context.\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// This is a special handling for updatedAt fields\n\t\t\t\tif (field === \"updatedAt\" && attr.onUpdate) {\n\t\t\t\t\tfieldBuilder.attribute(\"updatedAt\");\n\t\t\t\t} else if (attr.onUpdate) {\n\t\t\t\t\t// we are intentionally not adding the onUpdate value here\n\t\t\t\t\t// this is because if the onUpdate is a function, it could have\n\t\t\t\t\t// custom logic within that function that might not work in prisma's context.\n\t\t\t\t}\n\n\t\t\t\tif (attr.references) {\n\t\t\t\t\tif (\n\t\t\t\t\t\tuseUUIDs &&\n\t\t\t\t\t\tprovider === \"postgresql\" &&\n\t\t\t\t\t\tattr.references?.field === \"id\"\n\t\t\t\t\t) {\n\t\t\t\t\t\tbuilder.model(modelName).field(fieldName).attribute(`db.Uuid`);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst referencedOriginalModelName = getModelName(\n\t\t\t\t\t\tattr.references.model,\n\t\t\t\t\t);\n\t\t\t\t\tconst referencedCustomModelName =\n\t\t\t\t\t\ttables[referencedOriginalModelName]?.modelName ||\n\t\t\t\t\t\treferencedOriginalModelName;\n\t\t\t\t\tlet action = \"Cascade\";\n\t\t\t\t\tif (attr.references.onDelete === \"no action\") action = \"NoAction\";\n\t\t\t\t\telse if (attr.references.onDelete === \"set null\") action = \"SetNull\";\n\t\t\t\t\telse if (attr.references.onDelete === \"set default\")\n\t\t\t\t\t\taction = \"SetDefault\";\n\t\t\t\t\telse if (attr.references.onDelete === \"restrict\") action = \"Restrict\";\n\n\t\t\t\t\tconst relationField = `relation(fields: [${getFieldName({ model: originalTableName, field: fieldName })}], references: [${getFieldName({ model: attr.references.model, field: attr.references.field })}], onDelete: ${action})`;\n\t\t\t\t\tbuilder\n\t\t\t\t\t\t.model(modelName)\n\t\t\t\t\t\t.field(\n\t\t\t\t\t\t\treferencedCustomModelName.toLowerCase(),\n\t\t\t\t\t\t\t`${capitalizeFirstLetter(referencedCustomModelName)}${\n\t\t\t\t\t\t\t\t!attr.required ? \"?\" : \"\"\n\t\t\t\t\t\t\t}`,\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.attribute(relationField);\n\t\t\t\t}\n\t\t\t\tif (\n\t\t\t\t\t!attr.unique &&\n\t\t\t\t\t!attr.references &&\n\t\t\t\t\tprovider === \"mysql\" &&\n\t\t\t\t\tattr.type === \"string\"\n\t\t\t\t) {\n\t\t\t\t\tbuilder.model(modelName).field(fieldName).attribute(\"db.Text\");\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add many-to-many fields\n\t\t\tif (manyToManyRelations.has(modelName)) {\n\t\t\t\tfor (const relatedModel of manyToManyRelations.get(modelName)) {\n\t\t\t\t\t// Find the FK field on the related model that points to this model\n\t\t\t\t\tconst relatedTableName = Object.keys(tables).find(\n\t\t\t\t\t\t(key) =>\n\t\t\t\t\t\t\tcapitalizeFirstLetter(tables[key]?.modelName || key) ===\n\t\t\t\t\t\t\trelatedModel,\n\t\t\t\t\t);\n\t\t\t\t\tconst relatedFields = relatedTableName\n\t\t\t\t\t\t? tables[relatedTableName]?.fields\n\t\t\t\t\t\t: {};\n\t\t\t\t\tconst fkField = Object.entries(relatedFields || {}).find(\n\t\t\t\t\t\t([_fieldName, fieldAttr]: any) =>\n\t\t\t\t\t\t\tfieldAttr.references &&\n\t\t\t\t\t\t\tgetModelName(fieldAttr.references.model) ===\n\t\t\t\t\t\t\t\tgetModelName(originalTableName),\n\t\t\t\t\t);\n\t\t\t\t\tconst [_fieldKey, fkFieldAttr] = fkField || [];\n\t\t\t\t\tconst isUnique = fkFieldAttr?.unique === true;\n\n\t\t\t\t\tconst fieldName =\n\t\t\t\t\t\tisUnique || adapter.options?.usePlural === true\n\t\t\t\t\t\t\t? `${relatedModel.toLowerCase()}`\n\t\t\t\t\t\t\t: `${relatedModel.toLowerCase()}s`;\n\t\t\t\t\tconst existingField = builder.findByType(\"field\", {\n\t\t\t\t\t\tname: fieldName,\n\t\t\t\t\t\twithin: prismaModel?.properties,\n\t\t\t\t\t});\n\t\t\t\t\tif (!existingField) {\n\t\t\t\t\t\tbuilder\n\t\t\t\t\t\t\t.model(modelName)\n\t\t\t\t\t\t\t.field(fieldName, `${relatedModel}${isUnique ? \"?\" : \"[]\"}`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add indexes\n\t\t\tconst indexedFieldsForModel = indexedFields.get(modelName);\n\t\t\tif (indexedFieldsForModel && indexedFieldsForModel.length > 0) {\n\t\t\t\tfor (const fieldName of indexedFieldsForModel) {\n\t\t\t\t\tif (prismaModel) {\n\t\t\t\t\t\tconst indexExist = prismaModel.properties.some(\n\t\t\t\t\t\t\t(v) =>\n\t\t\t\t\t\t\t\tv.type === \"attribute\" &&\n\t\t\t\t\t\t\t\tv.name === \"index\" &&\n\t\t\t\t\t\t\t\tJSON.stringify(v.args[0]?.value).includes(fieldName),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (indexExist) {\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tconst field = Object.entries(fields!).find(\n\t\t\t\t\t\t([key, attr]) => (attr.fieldName || key) === fieldName,\n\t\t\t\t\t)?.[1];\n\n\t\t\t\t\tlet indexField = fieldName;\n\t\t\t\t\tif (provider === \"mysql\" && field && field.type === \"string\") {\n\t\t\t\t\t\tconst useNumberId =\n\t\t\t\t\t\t\toptions.advanced?.database?.generateId === \"serial\";\n\t\t\t\t\t\tconst useUUIDs = options.advanced?.database?.generateId === \"uuid\";\n\t\t\t\t\t\tif (field.references?.field === \"id\" && (useNumberId || useUUIDs)) {\n\t\t\t\t\t\t\tindexField = `${fieldName}`;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tindexField = `${fieldName}(length: 191)`; // length of 191 because String in Prisma is varchar(191)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tbuilder.model(modelName).blockAttribute(`index([${indexField}])`);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst hasAttribute = builder.findByType(\"attribute\", {\n\t\t\t\tname: \"map\",\n\t\t\t\twithin: prismaModel?.properties,\n\t\t\t});\n\t\t\tconst hasChanged = customModelName !== originalTableName;\n\t\t\tif (!hasAttribute) {\n\t\t\t\tbuilder\n\t\t\t\t\t.model(modelName)\n\t\t\t\t\t.blockAttribute(\n\t\t\t\t\t\t\"map\",\n\t\t\t\t\t\t`${getModelName(hasChanged ? customModelName : originalTableName)}`,\n\t\t\t\t\t);\n\t\t\t}\n\t\t}\n\t});\n\n\tconst schemaChanged = schema.trim() !== schemaPrisma.trim();\n\n\treturn {\n\t\tcode: schemaChanged ? schema : \"\",\n\t\tfileName: filePath,\n\t\toverwrite: schemaPrismaExist && schemaChanged,\n\t};\n};\n\nconst getNewPrisma = (provider: string, cwd?: string) => {\n\tconst prismaVersion = getPrismaVersion(cwd);\n\tconst isV7 = prismaVersion && prismaVersion >= 7;\n\t// Use \"prisma-client\" for Prisma v7+, otherwise use \"prisma-client-js\"\n\tconst clientProvider = isV7 ? \"prisma-client\" : \"prisma-client-js\";\n\n\t// In Prisma v7+, the url is configured in prisma.config.ts instead of the schema\n\tif (isV7) {\n\t\treturn `generator client {\n provider = \"${clientProvider}\"\n }\n\n datasource db {\n provider = \"${provider}\"\n }`;\n\t}\n\n\treturn `generator client {\n provider = \"${clientProvider}\"\n }\n\n datasource db {\n provider = \"${provider}\"\n url = ${\n\t\t\tprovider === \"sqlite\" ? `\"file:./dev.db\"` : `env(\"DATABASE_URL\")`\n\t\t}\n }`;\n};\n","import type { BetterAuthOptions } from \"@better-auth/core\";\nimport type { DBAdapter } from \"@better-auth/core/db/adapter\";\nimport { generateDrizzleSchema } from \"./drizzle\";\nimport { generateKyselySchema } from \"./kysely\";\nimport { generatePrismaSchema } from \"./prisma\";\n\nexport const adapters = {\n\tprisma: generatePrismaSchema,\n\tdrizzle: generateDrizzleSchema,\n\tkysely: generateKyselySchema,\n};\n\nexport const generateSchema = (opts: {\n\tadapter: DBAdapter;\n\tfile?: string;\n\toptions: BetterAuthOptions;\n}) => {\n\tconst adapter = opts.adapter;\n\tconst generator =\n\t\tadapter.id in adapters\n\t\t\t? adapters[adapter.id as keyof typeof adapters]\n\t\t\t: null;\n\tif (generator) {\n\t\t// generator from the built-in list above\n\t\treturn generator(opts);\n\t}\n\tif (adapter.createSchema) {\n\t\t// use the custom adapter's createSchema method\n\t\treturn adapter\n\t\t\t.createSchema(opts.options, opts.file)\n\t\t\t.then(({ code, path: fileName, overwrite }) => ({\n\t\t\t\tcode,\n\t\t\t\tfileName,\n\t\t\t\toverwrite,\n\t\t\t}));\n\t}\n\n\tthrow new Error(\n\t\t`${adapter.id} is not supported. If it is a custom adapter, please request the maintainer to implement createSchema`,\n\t);\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"api.mjs","names":[],"sources":["../src/generators/drizzle.ts","../src/generators/kysely.ts","../src/utils/get-package-info.ts","../src/generators/prisma.ts","../src/generators/index.ts"],"sourcesContent":["import { existsSync } from \"node:fs\";\nimport { initGetFieldName, initGetModelName } from \"better-auth/adapters\";\nimport type { BetterAuthDBSchema, DBFieldAttribute } from \"better-auth/db\";\nimport { getAuthTables } from \"better-auth/db\";\nimport type { BetterAuthOptions } from \"better-auth/types\";\nimport prettier from \"prettier\";\nimport type { SchemaGenerator } from \"./types\";\n\nfunction convertToSnakeCase(str: string, camelCase?: boolean) {\n\tif (camelCase) {\n\t\treturn str;\n\t}\n\t// Handle consecutive capitals (like ID, URL, API) by treating them as a single word\n\treturn str\n\t\t.replace(/([A-Z]+)([A-Z][a-z])/g, \"$1_$2\") // Handle AABb -> AA_Bb\n\t\t.replace(/([a-z\\d])([A-Z])/g, \"$1_$2\") // Handle aBb -> a_Bb\n\t\t.toLowerCase();\n}\n\nexport const generateDrizzleSchema: SchemaGenerator = async ({\n\toptions,\n\tfile,\n\tadapter,\n}) => {\n\tconst tables = getAuthTables(options);\n\tconst filePath = file || \"./auth-schema.ts\";\n\tconst databaseType: \"sqlite\" | \"mysql\" | \"pg\" | undefined =\n\t\tadapter.options?.provider;\n\n\tif (!databaseType) {\n\t\tthrow new Error(\n\t\t\t`Database provider type is undefined during Drizzle schema generation. Please define a \\`provider\\` in the Drizzle adapter config. Read more at https://better-auth.com/docs/adapters/drizzle`,\n\t\t);\n\t}\n\tconst fileExist = existsSync(filePath);\n\n\tlet code: string = generateImport({\n\t\tdatabaseType,\n\t\ttables,\n\t\toptions,\n\t});\n\n\tconst getModelName = initGetModelName({\n\t\tschema: tables,\n\t\tusePlural: adapter.options?.adapterConfig?.usePlural,\n\t});\n\n\tconst getFieldName = initGetFieldName({\n\t\tschema: tables,\n\t\tusePlural: adapter.options?.adapterConfig?.usePlural,\n\t});\n\n\tfor (const tableKey in tables) {\n\t\tconst table = tables[tableKey]!;\n\t\tconst modelName = getModelName(tableKey);\n\t\tconst fields = table.fields;\n\n\t\tfunction getType(name: string, field: DBFieldAttribute) {\n\t\t\t// Not possible to reach, it's here to make typescript happy\n\t\t\tif (!databaseType) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Database provider type is undefined during Drizzle schema generation. Please define a \\`provider\\` in the Drizzle adapter config. Read more at https://better-auth.com/docs/adapters/drizzle`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tname = convertToSnakeCase(name, adapter.options?.camelCase);\n\t\t\tif (field.references?.field === \"id\") {\n\t\t\t\tconst useNumberId = options.advanced?.database?.generateId === \"serial\";\n\t\t\t\tconst useUUIDs = options.advanced?.database?.generateId === \"uuid\";\n\t\t\t\tif (useNumberId) {\n\t\t\t\t\tif (databaseType === \"pg\") {\n\t\t\t\t\t\treturn `integer('${name}')`;\n\t\t\t\t\t} else if (databaseType === \"mysql\") {\n\t\t\t\t\t\treturn `int('${name}')`;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// using sqlite\n\t\t\t\t\t\treturn `integer('${name}')`;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (useUUIDs && databaseType === \"pg\") {\n\t\t\t\t\treturn `uuid('${name}')`;\n\t\t\t\t}\n\t\t\t\tif (field.references.field) {\n\t\t\t\t\tif (databaseType === \"mysql\") {\n\t\t\t\t\t\treturn `varchar('${name}', { length: 36 })`;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn `text('${name}')`;\n\t\t\t}\n\t\t\tconst type = field.type;\n\t\t\tif (typeof type !== \"string\") {\n\t\t\t\tif (Array.isArray(type) && type.every((x) => typeof x === \"string\")) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tsqlite: `text({ enum: [${type.map((x) => `'${x}'`).join(\", \")}] })`,\n\t\t\t\t\t\tpg: `text('${name}', { enum: [${type.map((x) => `'${x}'`).join(\", \")}] })`,\n\t\t\t\t\t\tmysql: `mysqlEnum([${type.map((x) => `'${x}'`).join(\", \")}])`,\n\t\t\t\t\t}[databaseType];\n\t\t\t\t} else {\n\t\t\t\t\tthrow new TypeError(\n\t\t\t\t\t\t`Invalid field type for field ${name} in model ${modelName}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst typeMap: Record<\n\t\t\t\ttypeof type,\n\t\t\t\tRecord<typeof databaseType, string>\n\t\t\t> = {\n\t\t\t\tstring: {\n\t\t\t\t\tsqlite: `text('${name}')`,\n\t\t\t\t\tpg: `text('${name}')`,\n\t\t\t\t\tmysql: field.unique\n\t\t\t\t\t\t? `varchar('${name}', { length: 255 })`\n\t\t\t\t\t\t: field.references\n\t\t\t\t\t\t\t? `varchar('${name}', { length: 36 })`\n\t\t\t\t\t\t\t: field.sortable\n\t\t\t\t\t\t\t\t? `varchar('${name}', { length: 255 })`\n\t\t\t\t\t\t\t\t: field.index\n\t\t\t\t\t\t\t\t\t? `varchar('${name}', { length: 255 })`\n\t\t\t\t\t\t\t\t\t: `text('${name}')`,\n\t\t\t\t},\n\t\t\t\tboolean: {\n\t\t\t\t\tsqlite: `integer('${name}', { mode: 'boolean' })`,\n\t\t\t\t\tpg: `boolean('${name}')`,\n\t\t\t\t\tmysql: `boolean('${name}')`,\n\t\t\t\t},\n\t\t\t\tnumber: {\n\t\t\t\t\tsqlite: `integer('${name}')`,\n\t\t\t\t\tpg: field.bigint\n\t\t\t\t\t\t? `bigint('${name}', { mode: 'number' })`\n\t\t\t\t\t\t: `integer('${name}')`,\n\t\t\t\t\tmysql: field.bigint\n\t\t\t\t\t\t? `bigint('${name}', { mode: 'number' })`\n\t\t\t\t\t\t: `int('${name}')`,\n\t\t\t\t},\n\t\t\t\tdate: {\n\t\t\t\t\tsqlite: `integer('${name}', { mode: 'timestamp_ms' })`,\n\t\t\t\t\tpg: `timestamp('${name}')`,\n\t\t\t\t\tmysql: `timestamp('${name}', { fsp: 3 })`,\n\t\t\t\t},\n\t\t\t\t\"number[]\": {\n\t\t\t\t\tsqlite: `text('${name}', { mode: \"json\" })`,\n\t\t\t\t\tpg: field.bigint\n\t\t\t\t\t\t? `bigint('${name}', { mode: 'number' }).array()`\n\t\t\t\t\t\t: `integer('${name}').array()`,\n\t\t\t\t\tmysql: `text('${name}', { mode: 'json' })`,\n\t\t\t\t},\n\t\t\t\t\"string[]\": {\n\t\t\t\t\tsqlite: `text('${name}', { mode: \"json\" })`,\n\t\t\t\t\tpg: `text('${name}').array()`,\n\t\t\t\t\tmysql: `text('${name}', { mode: \"json\" })`,\n\t\t\t\t},\n\t\t\t\tjson: {\n\t\t\t\t\tsqlite: `text('${name}', { mode: \"json\" })`,\n\t\t\t\t\tpg: `jsonb('${name}')`,\n\t\t\t\t\tmysql: `json('${name}', { mode: \"json\" })`,\n\t\t\t\t},\n\t\t\t} as const;\n\t\t\tconst dbTypeMap = (\n\t\t\t\ttypeMap as Record<string, Record<typeof databaseType, string>>\n\t\t\t)[type as string];\n\t\t\tif (!dbTypeMap) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Unsupported field type '${field.type}' for field '${name}'.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn dbTypeMap[databaseType];\n\t\t}\n\n\t\tlet id: string = \"\";\n\n\t\tconst useNumberId = options.advanced?.database?.generateId === \"serial\";\n\t\tconst useUUIDs = options.advanced?.database?.generateId === \"uuid\";\n\n\t\tif (useUUIDs && databaseType === \"pg\") {\n\t\t\tid = `uuid(\"id\").default(sql\\`pg_catalog.gen_random_uuid()\\`).primaryKey()`;\n\t\t} else if (useNumberId) {\n\t\t\tif (databaseType === \"pg\") {\n\t\t\t\tid = `integer(\"id\").generatedByDefaultAsIdentity().primaryKey()`;\n\t\t\t} else if (databaseType === \"sqlite\") {\n\t\t\t\tid = `integer(\"id\", { mode: \"number\" }).primaryKey({ autoIncrement: true })`;\n\t\t\t} else {\n\t\t\t\tid = `int(\"id\").autoincrement().primaryKey()`;\n\t\t\t}\n\t\t} else {\n\t\t\tif (databaseType === \"mysql\") {\n\t\t\t\tid = `varchar('id', { length: 36 }).primaryKey()`;\n\t\t\t} else if (databaseType === \"pg\") {\n\t\t\t\tid = `text('id').primaryKey()`;\n\t\t\t} else {\n\t\t\t\tid = `text('id').primaryKey()`;\n\t\t\t}\n\t\t}\n\n\t\ttype Index = { type: \"uniqueIndex\" | \"index\"; name: string; on: string };\n\n\t\tconst indexes: Index[] = [];\n\n\t\tconst assignIndexes = (indexes: Index[]): string => {\n\t\t\tif (!indexes.length) return \"\";\n\n\t\t\tconst code: string[] = [`, (table) => [`];\n\n\t\t\tfor (const index of indexes) {\n\t\t\t\tcode.push(` ${index.type}(\"${index.name}\").on(table.${index.on}),`);\n\t\t\t}\n\n\t\t\tcode.push(`]`);\n\n\t\t\treturn code.join(\"\\n\");\n\t\t};\n\n\t\tconst schema = `export const ${modelName} = ${databaseType}Table(\"${convertToSnakeCase(\n\t\t\tmodelName,\n\t\t\tadapter.options?.camelCase,\n\t\t)}\", {\n\t\t\t\t\tid: ${id},\n\t\t\t\t\t${Object.keys(fields)\n\t\t\t\t\t\t.map((field) => {\n\t\t\t\t\t\t\tconst attr = fields[field]!;\n\t\t\t\t\t\t\tconst fieldName = attr.fieldName || field;\n\t\t\t\t\t\t\tlet type = getType(fieldName, attr);\n\n\t\t\t\t\t\t\tif (attr.index && !attr.unique) {\n\t\t\t\t\t\t\t\tindexes.push({\n\t\t\t\t\t\t\t\t\ttype: \"index\",\n\t\t\t\t\t\t\t\t\tname: `${modelName}_${fieldName}_idx`,\n\t\t\t\t\t\t\t\t\ton: fieldName,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t} else if (attr.index && attr.unique) {\n\t\t\t\t\t\t\t\tindexes.push({\n\t\t\t\t\t\t\t\t\ttype: \"uniqueIndex\",\n\t\t\t\t\t\t\t\t\tname: `${modelName}_${fieldName}_uidx`,\n\t\t\t\t\t\t\t\t\ton: fieldName,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tattr.defaultValue !== null &&\n\t\t\t\t\t\t\t\ttypeof attr.defaultValue !== \"undefined\"\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tif (typeof attr.defaultValue === \"function\") {\n\t\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t\tattr.type === \"date\" &&\n\t\t\t\t\t\t\t\t\t\tattr.defaultValue.toString().includes(\"new Date()\")\n\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\tif (databaseType === \"sqlite\") {\n\t\t\t\t\t\t\t\t\t\t\ttype += `.default(sql\\`(cast(unixepoch('subsecond') * 1000 as integer))\\`)`;\n\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\ttype += `.defaultNow()`;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t// we are intentionally not adding .$defaultFn(${attr.defaultValue})\n\t\t\t\t\t\t\t\t\t\t// this is because if the defaultValue is a function, it could have\n\t\t\t\t\t\t\t\t\t\t// custom logic within that function that might not work in drizzle's context.\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} else if (typeof attr.defaultValue === \"string\") {\n\t\t\t\t\t\t\t\t\ttype += `.default(\"${attr.defaultValue}\")`;\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\ttype += `.default(${attr.defaultValue})`;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// Add .$onUpdate() for fields with onUpdate property\n\t\t\t\t\t\t\t// Supported for all database types: PostgreSQL, MySQL, and SQLite\n\t\t\t\t\t\t\tif (attr.onUpdate && attr.type === \"date\") {\n\t\t\t\t\t\t\t\tif (typeof attr.onUpdate === \"function\") {\n\t\t\t\t\t\t\t\t\ttype += `.$onUpdate(${attr.onUpdate})`;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\treturn `${fieldName}: ${type}${attr.required !== false ? \".notNull()\" : \"\"}${\n\t\t\t\t\t\t\t\tattr.unique ? \".unique()\" : \"\"\n\t\t\t\t\t\t\t}${\n\t\t\t\t\t\t\t\tattr.references\n\t\t\t\t\t\t\t\t\t? `.references(()=> ${getModelName(\n\t\t\t\t\t\t\t\t\t\t\tattr.references.model,\n\t\t\t\t\t\t\t\t\t\t)}.${getFieldName({ model: attr.references.model, field: attr.references.field })}, { onDelete: '${\n\t\t\t\t\t\t\t\t\t\t\tattr.references.onDelete || \"cascade\"\n\t\t\t\t\t\t\t\t\t\t}' })`\n\t\t\t\t\t\t\t\t\t: \"\"\n\t\t\t\t\t\t\t}`;\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.join(\",\\n \")}\n\t\t\t\t\t}${assignIndexes(indexes)});`;\n\t\tcode += `\\n${schema}\\n`;\n\t}\n\n\tlet relationsString: string = \"\";\n\tfor (const tableKey in tables) {\n\t\tconst table = tables[tableKey]!;\n\t\tconst modelName = getModelName(tableKey);\n\n\t\ttype Relation = {\n\t\t\t/**\n\t\t\t * The key of the relation that will be defined in the Drizzle schema.\n\t\t\t * For \"one\" relations: singular (e.g., \"user\")\n\t\t\t * For \"many\" relations: plural (e.g., \"posts\")\n\t\t\t */\n\t\t\tkey: string;\n\t\t\t/**\n\t\t\t * The model name being referenced.\n\t\t\t */\n\t\t\tmodel: string;\n\t\t\t/**\n\t\t\t * The type of the relation: \"one\" (many-to-one) or \"many\" (one-to-many).\n\t\t\t */\n\t\t\ttype: \"one\" | \"many\";\n\t\t\t/**\n\t\t\t * Foreign key field name and reference details (only for \"one\" relations).\n\t\t\t */\n\t\t\treference?: {\n\t\t\t\tfield: string;\n\t\t\t\treferences: string;\n\t\t\t\tfieldName: string; // Original field name for generating unique relation export names\n\t\t\t};\n\t\t};\n\n\t\tconst oneRelations: Relation[] = [];\n\t\tconst manyRelations: Relation[] = [];\n\t\t// Set to track \"many\" relations by key to prevent duplicates\n\t\tconst manyRelationsSet = new Set<string>();\n\n\t\t// 1. Find all foreign keys in THIS table (creates \"one\" relations)\n\t\tconst fields = Object.entries(table.fields);\n\t\tconst foreignFields = fields.filter(([_, field]) => field.references);\n\n\t\tfor (const [fieldName, field] of foreignFields) {\n\t\t\tconst referencedModel = field.references!.model;\n\t\t\tconst relationKey = getModelName(referencedModel);\n\t\t\tconst fieldRef = `${getModelName(tableKey)}.${getFieldName({ model: tableKey, field: fieldName })}`;\n\t\t\tconst referenceRef = `${getModelName(referencedModel)}.${getFieldName({ model: referencedModel, field: field.references!.field || \"id\" })}`;\n\n\t\t\t// Create a separate relation for each foreign key\n\t\t\toneRelations.push({\n\t\t\t\tkey: relationKey,\n\t\t\t\tmodel: getModelName(referencedModel),\n\t\t\t\ttype: \"one\",\n\t\t\t\treference: {\n\t\t\t\t\tfield: fieldRef,\n\t\t\t\t\treferences: referenceRef,\n\t\t\t\t\tfieldName: fieldName,\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\n\t\t// 2. Find all OTHER tables that reference THIS table (creates \"many\" relations)\n\t\tconst otherModels = Object.entries(tables).filter(\n\t\t\t([modelName]) => modelName !== tableKey,\n\t\t);\n\n\t\t// Map to track relations by model name to determine if unique or many\n\t\tconst modelRelationsMap = new Map<\n\t\t\tstring,\n\t\t\t{\n\t\t\t\tmodelName: string;\n\t\t\t\thasUnique: boolean;\n\t\t\t\thasMany: boolean;\n\t\t\t}\n\t\t>();\n\n\t\tfor (const [modelName, otherTable] of otherModels) {\n\t\t\tconst foreignKeysPointingHere = Object.entries(otherTable.fields).filter(\n\t\t\t\t([_, field]) =>\n\t\t\t\t\tfield.references?.model === tableKey ||\n\t\t\t\t\tfield.references?.model === getModelName(tableKey),\n\t\t\t);\n\n\t\t\tif (foreignKeysPointingHere.length === 0) continue;\n\n\t\t\t// Check if any foreign key is unique\n\t\t\tconst hasUnique = foreignKeysPointingHere.some(\n\t\t\t\t([_, field]) => !!field.unique,\n\t\t\t);\n\t\t\tconst hasMany = foreignKeysPointingHere.some(\n\t\t\t\t([_, field]) => !field.unique,\n\t\t\t);\n\n\t\t\tmodelRelationsMap.set(modelName, {\n\t\t\t\tmodelName,\n\t\t\t\thasUnique,\n\t\t\t\thasMany,\n\t\t\t});\n\t\t}\n\n\t\t// Add relations, deduplicating by relationKey\n\t\tfor (const { modelName, hasMany } of modelRelationsMap.values()) {\n\t\t\t// Determine relation type: if all are unique, it's \"one\", otherwise \"many\"\n\t\t\tconst relationType = hasMany ? \"many\" : \"one\";\n\t\t\tlet relationKey = getModelName(modelName);\n\n\t\t\t// We have to apply this after checking if they have usePlural because otherwise they will end up seeing:\n\t\t\t/* cspell:disable-next-line */\n\t\t\t// \"sesionss\", or \"accountss\" - double s's.\n\t\t\tif (\n\t\t\t\t!adapter.options?.adapterConfig?.usePlural &&\n\t\t\t\trelationType === \"many\"\n\t\t\t) {\n\t\t\t\trelationKey = `${relationKey}s`;\n\t\t\t}\n\n\t\t\t// Only add if we haven't seen this key before\n\t\t\tif (!manyRelationsSet.has(relationKey)) {\n\t\t\t\tmanyRelationsSet.add(relationKey);\n\t\t\t\tmanyRelations.push({\n\t\t\t\t\tkey: relationKey,\n\t\t\t\t\tmodel: getModelName(modelName),\n\t\t\t\t\ttype: relationType,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// Group \"one\" relations by referenced model to detect duplicates\n\t\tconst relationsByModel = new Map<string, Relation[]>();\n\t\tfor (const relation of oneRelations) {\n\t\t\tif (relation.reference) {\n\t\t\t\tconst modelKey = relation.key;\n\t\t\t\tif (!relationsByModel.has(modelKey)) {\n\t\t\t\t\trelationsByModel.set(modelKey, []);\n\t\t\t\t}\n\t\t\t\trelationsByModel.get(modelKey)!.push(relation);\n\t\t\t}\n\t\t}\n\n\t\t// Separate relations with duplicates (same model) from those without\n\t\tconst duplicateRelations: Relation[] = [];\n\t\tconst singleRelations: Relation[] = [];\n\n\t\tfor (const [_modelKey, relations] of relationsByModel.entries()) {\n\t\t\tif (relations.length > 1) {\n\t\t\t\t// Multiple relations to the same model - these need field-specific naming\n\t\t\t\tduplicateRelations.push(...relations);\n\t\t\t} else {\n\t\t\t\t// Single relation to this model - can be combined with others\n\t\t\t\tsingleRelations.push(relations[0]!);\n\t\t\t}\n\t\t}\n\n\t\t// Generate field-specific exports for duplicate relations\n\t\tfor (const relation of duplicateRelations) {\n\t\t\tif (relation.reference) {\n\t\t\t\tconst fieldName = relation.reference.fieldName;\n\t\t\t\tconst relationExportName = `${modelName}${fieldName.charAt(0).toUpperCase() + fieldName.slice(1)}Relations`;\n\n\t\t\t\tconst tableRelation = `export const ${relationExportName} = relations(${getModelName(\n\t\t\t\t\ttable.modelName,\n\t\t\t\t)}, ({ one }) => ({\n\t\t\t\t${relation.key}: one(${relation.model}, {\n\t\t\t\t\tfields: [${relation.reference.field}],\n\t\t\t\t\treferences: [${relation.reference.references}],\n\t\t\t\t})\n\t\t\t}))`;\n\n\t\t\t\trelationsString += `\\n${tableRelation}\\n`;\n\t\t\t}\n\t\t}\n\n\t\t// Combine all single \"one\" relations and \"many\" relations into exports\n\t\tconst hasOne = singleRelations.length > 0;\n\t\tconst hasMany = manyRelations.length > 0;\n\n\t\tif (hasOne && hasMany) {\n\t\t\t// Both \"one\" and \"many\" relations exist - combine in one export\n\t\t\tconst tableRelation = `export const ${modelName}Relations = relations(${getModelName(\n\t\t\t\ttable.modelName,\n\t\t\t)}, ({ one, many }) => ({\n\t\t\t\t${singleRelations\n\t\t\t\t\t.map((relation) =>\n\t\t\t\t\t\trelation.reference\n\t\t\t\t\t\t\t? ` ${relation.key}: one(${relation.model}, {\n\t\t\t\t\tfields: [${relation.reference.field}],\n\t\t\t\t\treferences: [${relation.reference.references}],\n\t\t\t\t})`\n\t\t\t\t\t\t\t: \"\",\n\t\t\t\t\t)\n\t\t\t\t\t.filter((x) => x !== \"\")\n\t\t\t\t\t.join(\",\\n \")}${\n\t\t\t\t\tsingleRelations.length > 0 && manyRelations.length > 0 ? \",\" : \"\"\n\t\t\t\t}\n\t\t\t\t${manyRelations\n\t\t\t\t\t.map(({ key, model }) => ` ${key}: many(${model})`)\n\t\t\t\t\t.join(\",\\n \")}\n\t\t\t}))`;\n\n\t\t\trelationsString += `\\n${tableRelation}\\n`;\n\t\t} else if (hasOne) {\n\t\t\t// Only \"one\" relations exist\n\t\t\tconst tableRelation = `export const ${modelName}Relations = relations(${getModelName(\n\t\t\t\ttable.modelName,\n\t\t\t)}, ({ one }) => ({\n\t\t\t\t${singleRelations\n\t\t\t\t\t.map((relation) =>\n\t\t\t\t\t\trelation.reference\n\t\t\t\t\t\t\t? ` ${relation.key}: one(${relation.model}, {\n\t\t\t\t\tfields: [${relation.reference.field}],\n\t\t\t\t\treferences: [${relation.reference.references}],\n\t\t\t\t})`\n\t\t\t\t\t\t\t: \"\",\n\t\t\t\t\t)\n\t\t\t\t\t.filter((x) => x !== \"\")\n\t\t\t\t\t.join(\",\\n \")}\n\t\t\t}))`;\n\n\t\t\trelationsString += `\\n${tableRelation}\\n`;\n\t\t} else if (hasMany) {\n\t\t\t// Only \"many\" relations exist\n\t\t\tconst tableRelation = `export const ${modelName}Relations = relations(${getModelName(\n\t\t\t\ttable.modelName,\n\t\t\t)}, ({ many }) => ({\n\t\t\t\t${manyRelations\n\t\t\t\t\t.map(({ key, model }) => ` ${key}: many(${model})`)\n\t\t\t\t\t.join(\",\\n \")}\n\t\t\t}))`;\n\n\t\t\trelationsString += `\\n${tableRelation}\\n`;\n\t\t}\n\t}\n\tcode += `\\n${relationsString}`;\n\n\tconst formattedCode = await prettier.format(code, {\n\t\tparser: \"typescript\",\n\t});\n\treturn {\n\t\tcode: formattedCode,\n\t\tfileName: filePath,\n\t\toverwrite: fileExist,\n\t};\n};\n\nfunction generateImport({\n\tdatabaseType,\n\ttables,\n\toptions,\n}: {\n\tdatabaseType: \"sqlite\" | \"mysql\" | \"pg\";\n\ttables: BetterAuthDBSchema;\n\toptions: BetterAuthOptions;\n}) {\n\tconst rootImports: string[] = [\"relations\"];\n\tconst coreImports: string[] = [];\n\n\tlet hasBigint = false;\n\tlet hasJson = false;\n\n\tfor (const table of Object.values(tables)) {\n\t\tfor (const field of Object.values(table.fields)) {\n\t\t\tif (field.bigint) hasBigint = true;\n\t\t\tif (field.type === \"json\") hasJson = true;\n\t\t}\n\t\tif (hasJson && hasBigint) break;\n\t}\n\n\tconst useNumberId = options.advanced?.database?.generateId === \"serial\";\n\n\tconst useUUIDs = options.advanced?.database?.generateId === \"uuid\";\n\n\tcoreImports.push(`${databaseType}Table`);\n\tcoreImports.push(\n\t\tdatabaseType === \"mysql\"\n\t\t\t? \"varchar, text\"\n\t\t\t: databaseType === \"pg\"\n\t\t\t\t? \"text\"\n\t\t\t\t: \"text\",\n\t);\n\tcoreImports.push(\n\t\thasBigint ? (databaseType !== \"sqlite\" ? \"bigint\" : \"\") : \"\",\n\t);\n\tcoreImports.push(databaseType !== \"sqlite\" ? \"timestamp, boolean\" : \"\");\n\tif (databaseType === \"mysql\") {\n\t\t// Only include int for MySQL if actually needed\n\t\tconst hasNonBigintNumber = Object.values(tables).some((table) =>\n\t\t\tObject.values(table.fields).some(\n\t\t\t\t(field) =>\n\t\t\t\t\t(field.type === \"number\" || field.type === \"number[]\") &&\n\t\t\t\t\t!field.bigint,\n\t\t\t),\n\t\t);\n\t\tconst needsInt = useNumberId || hasNonBigintNumber;\n\t\tif (needsInt) {\n\t\t\tcoreImports.push(\"int\");\n\t\t}\n\t\tconst hasEnum = Object.values(tables).some((table) =>\n\t\t\tObject.values(table.fields).some(\n\t\t\t\t(field) =>\n\t\t\t\t\ttypeof field.type !== \"string\" &&\n\t\t\t\t\tArray.isArray(field.type) &&\n\t\t\t\t\tfield.type.every((x) => typeof x === \"string\"),\n\t\t\t),\n\t\t);\n\t\tif (hasEnum) {\n\t\t\tcoreImports.push(\"mysqlEnum\");\n\t\t}\n\t} else if (databaseType === \"pg\") {\n\t\tif (useUUIDs) {\n\t\t\trootImports.push(\"sql\");\n\t\t}\n\n\t\t// Only include integer for PG if actually needed\n\t\tconst hasNonBigintNumber = Object.values(tables).some((table) =>\n\t\t\tObject.values(table.fields).some(\n\t\t\t\t(field) =>\n\t\t\t\t\t(field.type === \"number\" || field.type === \"number[]\") &&\n\t\t\t\t\t!field.bigint,\n\t\t\t),\n\t\t);\n\t\tconst hasFkToId = Object.values(tables).some((table) =>\n\t\t\tObject.values(table.fields).some(\n\t\t\t\t(field) => field.references?.field === \"id\",\n\t\t\t),\n\t\t);\n\t\t// handles the references field with useNumberId\n\t\tconst needsInteger =\n\t\t\thasNonBigintNumber ||\n\t\t\t(options.advanced?.database?.generateId === \"serial\" && hasFkToId);\n\t\tif (needsInteger) {\n\t\t\tcoreImports.push(\"integer\");\n\t\t}\n\t} else {\n\t\tcoreImports.push(\"integer\");\n\t}\n\tif (databaseType === \"pg\" && useUUIDs) {\n\t\tcoreImports.push(\"uuid\");\n\t}\n\n\t//handle json last on the import order\n\tif (hasJson) {\n\t\tif (databaseType === \"pg\") coreImports.push(\"jsonb\");\n\t\tif (databaseType === \"mysql\") coreImports.push(\"json\");\n\t\t// sqlite uses text for JSON, so there's no need to handle this case\n\t}\n\n\t// Add sql import for SQLite timestamps with defaultNow\n\tconst hasSQLiteTimestamp =\n\t\tdatabaseType === \"sqlite\" &&\n\t\tObject.values(tables).some((table) =>\n\t\t\tObject.values(table.fields).some(\n\t\t\t\t(field) =>\n\t\t\t\t\tfield.type === \"date\" &&\n\t\t\t\t\tfield.defaultValue &&\n\t\t\t\t\ttypeof field.defaultValue === \"function\" &&\n\t\t\t\t\tfield.defaultValue.toString().includes(\"new Date()\"),\n\t\t\t),\n\t\t);\n\n\tif (hasSQLiteTimestamp) {\n\t\trootImports.push(\"sql\");\n\t}\n\n\t//handle indexes\n\tconst hasIndexes = Object.values(tables).some((table) =>\n\t\tObject.values(table.fields).some((field) => field.index && !field.unique),\n\t);\n\tconst hasUniqueIndexes = Object.values(tables).some((table) =>\n\t\tObject.values(table.fields).some((field) => field.unique && field.index),\n\t);\n\tif (hasIndexes) {\n\t\tcoreImports.push(\"index\");\n\t}\n\tif (hasUniqueIndexes) {\n\t\tcoreImports.push(\"uniqueIndex\");\n\t}\n\n\treturn `${rootImports.length > 0 ? `import { ${rootImports.join(\", \")} } from \"drizzle-orm\";\\n` : \"\"}import { ${coreImports\n\t\t.map((x) => x.trim())\n\t\t.filter((x) => x !== \"\")\n\t\t.join(\", \")} } from \"drizzle-orm/${databaseType}-core\";\\n`;\n}\n","import { getMigrations } from \"better-auth/db/migration\";\nimport type { SchemaGenerator } from \"./types\";\n\nexport const generateKyselySchema: SchemaGenerator = async ({\n\toptions,\n\tfile,\n}) => {\n\tconst { compileMigrations } = await getMigrations(options);\n\tconst migrations = await compileMigrations();\n\treturn {\n\t\tcode: migrations.trim() === \";\" ? \"\" : migrations,\n\t\tfileName:\n\t\t\tfile ||\n\t\t\t`./better-auth_migrations/${new Date()\n\t\t\t\t.toISOString()\n\t\t\t\t.replace(/:/g, \"-\")}.sql`,\n\t};\n};\n","import { readFileSync } from \"node:fs\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { tryCatch } from \"./helper\";\n\nexport function getPackageInfo(cwd?: string) {\n\tconst packageJsonPath = cwd\n\t\t? path.join(cwd, \"package.json\")\n\t\t: path.join(\"package.json\");\n\treturn JSON.parse(readFileSync(packageJsonPath, \"utf-8\"));\n}\n\nexport function getPrismaVersion(cwd?: string): number | null {\n\ttry {\n\t\tconst packageInfo = getPackageInfo(cwd);\n\t\tconst prismaVersion =\n\t\t\tpackageInfo.dependencies?.prisma ||\n\t\t\tpackageInfo.devDependencies?.prisma ||\n\t\t\tpackageInfo.dependencies?.[\"@prisma/client\"] ||\n\t\t\tpackageInfo.devDependencies?.[\"@prisma/client\"];\n\n\t\tif (!prismaVersion) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Extract major version number from version string\n\t\t// Handles versions like \"^5.0.0\", \"~7.1.0\", \"7.0.0\", etc.\n\t\tconst match = prismaVersion.match(/(\\d+)/);\n\t\treturn match ? parseInt(match[1], 10) : null;\n\t} catch {\n\t\t// If package.json doesn't exist or can't be read, return null\n\t\treturn null;\n\t}\n}\n\n/**\n * Checks if a package has a specific dependency.\n *\n * @param packageJson The package.json object\n * @param dependency The dependency to check for\n * @returns true if the package has the dependency\n */\nexport function hasDependency(packageJson: any, dependency: string) {\n\tlet hasDependency = false;\n\n\tif (\n\t\tpackageJson.dependencies?.[dependency] ||\n\t\tpackageJson.devDependencies?.[dependency] ||\n\t\tpackageJson.peerDependencies?.[dependency] ||\n\t\tpackageJson.optionalDependencies?.[dependency]\n\t) {\n\t\thasDependency = true;\n\t}\n\n\treturn hasDependency;\n}\n\n/**\n * Checks if a directory is a monorepo root by looking for common monorepo indicators.\n *\n * @param dir Directory to check\n * @returns true if the directory appears to be a monorepo root\n */\nasync function isMonorepoRoot(dir: string) {\n\tconst { data: files } = await tryCatch(fs.readdir(dir, \"utf-8\"));\n\tif (!files) return false;\n\n\t// Check for pnpm workspace\n\tif (files.includes(\"pnpm-workspace.yaml\")) {\n\t\treturn true;\n\t}\n\n\t// Check for yarn/npm workspaces in package.json\n\tif (files.includes(\"package.json\")) {\n\t\tconst packageJsonPath = path.join(dir, \"package.json\");\n\t\tconst { data } = await tryCatch(fs.readFile(packageJsonPath, \"utf-8\"));\n\t\tif (data) {\n\t\t\ttry {\n\t\t\t\tconst packageJson = JSON.parse(data);\n\t\t\t\t// Check for workspaces field (npm/yarn workspaces)\n\t\t\t\t// Workspaces can be an array or an object\n\t\t\t\tif (\n\t\t\t\t\tpackageJson.workspaces &&\n\t\t\t\t\t(Array.isArray(packageJson.workspaces) ||\n\t\t\t\t\t\ttypeof packageJson.workspaces === \"object\")\n\t\t\t\t) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Ignore JSON parse errors\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check for other monorepo indicators\n\tconst monorepoIndicators = [\n\t\t\"lerna.json\", // Lerna\n\t\t/* cSpell:disable */\n\t\t\"turbo.json\", // Turborepo\n\t\t\"nx.json\", // Nx\n\t\t\"rush.json\", // Rush\n\t];\n\n\treturn monorepoIndicators.some((indicator) => files.includes(indicator));\n}\n\n/**\n * Finds the monorepo root by walking up the directory tree.\n *\n * @param startDir Starting directory\n * @returns Path to monorepo root, or null if not found\n */\nexport async function findMonorepoRoot(\n\tstartDir: string,\n): Promise<string | null> {\n\tlet currentDir = path.resolve(startDir);\n\tconst root = path.parse(currentDir).root;\n\n\twhile (currentDir !== root) {\n\t\tif (await isMonorepoRoot(currentDir)) {\n\t\t\treturn currentDir;\n\t\t}\n\t\tconst parentDir = path.dirname(currentDir);\n\t\tif (parentDir === currentDir) {\n\t\t\tbreak;\n\t\t}\n\t\tcurrentDir = parentDir;\n\t}\n\n\treturn null;\n}\n","import { existsSync } from \"node:fs\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { capitalizeFirstLetter } from \"@better-auth/core/utils/string\";\nimport { produceSchema } from \"@mrleebo/prisma-ast\";\nimport { initGetFieldName, initGetModelName } from \"better-auth/adapters\";\nimport type { DBFieldType } from \"better-auth/db\";\nimport { getAuthTables } from \"better-auth/db\";\nimport { getPrismaVersion } from \"../utils/get-package-info\";\nimport type { SchemaGenerator } from \"./types\";\n\nexport const generatePrismaSchema: SchemaGenerator = async ({\n\tadapter,\n\toptions,\n\tfile,\n}) => {\n\tconst provider: \"sqlite\" | \"postgresql\" | \"mysql\" | \"mongodb\" =\n\t\tadapter.options?.provider || \"postgresql\";\n\tconst tables = getAuthTables(options);\n\tconst filePath = file || \"./prisma/schema.prisma\";\n\tconst schemaPrismaExist = existsSync(path.join(process.cwd(), filePath));\n\n\tconst getModelName = initGetModelName({\n\t\tschema: getAuthTables(options),\n\t\tusePlural: adapter.options?.adapterConfig?.usePlural,\n\t});\n\tconst getFieldName = initGetFieldName({\n\t\tschema: getAuthTables(options),\n\t\tusePlural: false,\n\t});\n\n\tlet schemaPrisma = \"\";\n\tif (schemaPrismaExist) {\n\t\tschemaPrisma = await fs.readFile(\n\t\t\tpath.join(process.cwd(), filePath),\n\t\t\t\"utf-8\",\n\t\t);\n\t} else {\n\t\tschemaPrisma = getNewPrisma(provider, process.cwd());\n\t}\n\n\t// Update generator and datasource blocks for Prisma v7+ in existing schemas\n\tconst prismaVersion = getPrismaVersion(process.cwd());\n\tif (prismaVersion && prismaVersion >= 7 && schemaPrismaExist) {\n\t\tschemaPrisma = produceSchema(schemaPrisma, (builder) => {\n\t\t\tconst generator: any = builder.findByType(\"generator\", {\n\t\t\t\tname: \"client\",\n\t\t\t});\n\t\t\tif (generator && generator.properties) {\n\t\t\t\tconst providerProp = generator.properties.find(\n\t\t\t\t\t(prop: any) => prop.type === \"assignment\" && prop.key === \"provider\",\n\t\t\t\t);\n\t\t\t\tif (providerProp && providerProp.value === '\"prisma-client-js\"') {\n\t\t\t\t\tproviderProp.value = '\"prisma-client\"';\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Remove url from datasource block (now configured in prisma.config.ts)\n\t\t\tconst datasource: any = builder.findByType(\"datasource\", {\n\t\t\t\tname: \"db\",\n\t\t\t});\n\t\t\tif (datasource && datasource.properties) {\n\t\t\t\tconst urlIndex = datasource.properties.findIndex(\n\t\t\t\t\t(prop: any) => prop.type === \"assignment\" && prop.key === \"url\",\n\t\t\t\t);\n\t\t\t\tif (urlIndex !== -1) {\n\t\t\t\t\tdatasource.properties.splice(urlIndex, 1);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\n\tconst manyToManyRelations = new Map();\n\n\tfor (const table in tables) {\n\t\tconst fields = tables[table]?.fields;\n\t\tfor (const field in fields) {\n\t\t\tconst attr = fields[field]!;\n\t\t\tif (attr.references) {\n\t\t\t\tconst referencedOriginalModel = attr.references.model;\n\t\t\t\tconst referencedCustomModel =\n\t\t\t\t\ttables[referencedOriginalModel]?.modelName || referencedOriginalModel;\n\t\t\t\tconst referencedModelNameCap = capitalizeFirstLetter(\n\t\t\t\t\tgetModelName(referencedCustomModel),\n\t\t\t\t);\n\n\t\t\t\tif (!manyToManyRelations.has(referencedModelNameCap)) {\n\t\t\t\t\tmanyToManyRelations.set(referencedModelNameCap, new Set());\n\t\t\t\t}\n\n\t\t\t\tconst currentCustomModel = tables[table]?.modelName || table;\n\t\t\t\tconst currentModelNameCap = capitalizeFirstLetter(\n\t\t\t\t\tgetModelName(currentCustomModel),\n\t\t\t\t);\n\n\t\t\t\tmanyToManyRelations\n\t\t\t\t\t.get(referencedModelNameCap)\n\t\t\t\t\t.add(currentModelNameCap);\n\t\t\t}\n\t\t}\n\t}\n\n\tconst indexedFields = new Map<string, string[]>();\n\tfor (const table in tables) {\n\t\tconst fields = tables[table]?.fields;\n\t\tconst customModelName = tables[table]?.modelName || table;\n\t\tconst modelName = capitalizeFirstLetter(getModelName(customModelName));\n\t\tindexedFields.set(modelName, []);\n\n\t\tfor (const field in fields) {\n\t\t\tconst attr = fields[field]!;\n\t\t\tif (attr.index && !attr.unique) {\n\t\t\t\tconst fieldName = attr.fieldName || field;\n\t\t\t\tindexedFields.get(modelName)!.push(fieldName);\n\t\t\t}\n\t\t}\n\t}\n\n\tconst schema = produceSchema(schemaPrisma, (builder) => {\n\t\tfor (const table in tables) {\n\t\t\tconst originalTableName = table;\n\t\t\tconst customModelName = tables[table]?.modelName || table;\n\t\t\tconst modelName = capitalizeFirstLetter(getModelName(customModelName));\n\t\t\tconst fields = tables[table]?.fields;\n\t\t\tfunction getType({\n\t\t\t\tisBigint,\n\t\t\t\tisOptional,\n\t\t\t\ttype,\n\t\t\t}: {\n\t\t\t\ttype: DBFieldType;\n\t\t\t\tisOptional: boolean;\n\t\t\t\tisBigint: boolean;\n\t\t\t}) {\n\t\t\t\tif (type === \"string\") {\n\t\t\t\t\treturn isOptional ? \"String?\" : \"String\";\n\t\t\t\t}\n\t\t\t\tif (type === \"number\" && isBigint) {\n\t\t\t\t\treturn isOptional ? \"BigInt?\" : \"BigInt\";\n\t\t\t\t}\n\t\t\t\tif (type === \"number\") {\n\t\t\t\t\treturn isOptional ? \"Int?\" : \"Int\";\n\t\t\t\t}\n\t\t\t\tif (type === \"boolean\") {\n\t\t\t\t\treturn isOptional ? \"Boolean?\" : \"Boolean\";\n\t\t\t\t}\n\t\t\t\tif (type === \"date\") {\n\t\t\t\t\treturn isOptional ? \"DateTime?\" : \"DateTime\";\n\t\t\t\t}\n\t\t\t\tif (type === \"json\") {\n\t\t\t\t\tif (provider === \"sqlite\" || provider === \"mysql\") {\n\t\t\t\t\t\treturn isOptional ? \"String?\" : \"String\";\n\t\t\t\t\t}\n\t\t\t\t\treturn isOptional ? \"Json?\" : \"Json\";\n\t\t\t\t}\n\t\t\t\tif (type === \"string[]\") {\n\t\t\t\t\t// SQLite and MySQL don't support array of strings, so we use string instead\n\t\t\t\t\t// adapter should handle JSON.stringify and JSON.parse conversion for these fields\n\t\t\t\t\tif (provider === \"sqlite\" || provider === \"mysql\") {\n\t\t\t\t\t\treturn isOptional ? \"String?\" : \"String\";\n\t\t\t\t\t}\n\t\t\t\t\treturn \"String[]\";\n\t\t\t\t}\n\t\t\t\tif (type === \"number[]\") {\n\t\t\t\t\t// SQLite and MySQL don't support array of numbers, so we use int instead\n\t\t\t\t\t// adapter should handle JSON.stringify and JSON.parse conversion for these fields\n\t\t\t\t\tif (provider === \"sqlite\" || provider === \"mysql\") {\n\t\t\t\t\t\treturn \"String\";\n\t\t\t\t\t}\n\t\t\t\t\treturn \"Int[]\";\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst prismaModel = builder.findByType(\"model\", {\n\t\t\t\tname: modelName,\n\t\t\t});\n\n\t\t\tif (!prismaModel) {\n\t\t\t\tif (provider === \"mongodb\") {\n\t\t\t\t\t// Mongo DB doesn't support auto increment, so just use their normal _id.\n\t\t\t\t\tbuilder\n\t\t\t\t\t\t.model(modelName)\n\t\t\t\t\t\t.field(\"id\", \"String\")\n\t\t\t\t\t\t.attribute(\"id\")\n\t\t\t\t\t\t.attribute(`map(\"_id\")`);\n\t\t\t\t} else {\n\t\t\t\t\tconst useNumberId =\n\t\t\t\t\t\toptions.advanced?.database?.generateId === \"serial\";\n\t\t\t\t\tconst useUUIDs = options.advanced?.database?.generateId === \"uuid\";\n\t\t\t\t\tif (useNumberId) {\n\t\t\t\t\t\tbuilder\n\t\t\t\t\t\t\t.model(modelName)\n\t\t\t\t\t\t\t.field(\"id\", \"Int\")\n\t\t\t\t\t\t\t.attribute(\"id\")\n\t\t\t\t\t\t\t.attribute(\"default(autoincrement())\");\n\t\t\t\t\t} else if (useUUIDs && provider === \"postgresql\") {\n\t\t\t\t\t\tbuilder\n\t\t\t\t\t\t\t.model(modelName)\n\t\t\t\t\t\t\t.field(\"id\", \"String\")\n\t\t\t\t\t\t\t.attribute(\"id\")\n\t\t\t\t\t\t\t.attribute('default(dbgenerated(\"pg_catalog.gen_random_uuid()\"))')\n\t\t\t\t\t\t\t.attribute(\"db.Uuid\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbuilder.model(modelName).field(\"id\", \"String\").attribute(\"id\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const field in fields) {\n\t\t\t\tconst attr = fields[field]!;\n\t\t\t\tconst fieldName = attr.fieldName || field;\n\n\t\t\t\tif (prismaModel) {\n\t\t\t\t\tconst isAlreadyExist = builder.findByType(\"field\", {\n\t\t\t\t\t\tname: fieldName,\n\t\t\t\t\t\twithin: prismaModel.properties,\n\t\t\t\t\t});\n\t\t\t\t\tif (isAlreadyExist) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst useUUIDs = options.advanced?.database?.generateId === \"uuid\";\n\t\t\t\tconst useNumberId = options.advanced?.database?.generateId === \"serial\";\n\t\t\t\tconst fieldBuilder = builder.model(modelName).field(\n\t\t\t\t\tfieldName,\n\t\t\t\t\tfield === \"id\" && useNumberId\n\t\t\t\t\t\t? getType({\n\t\t\t\t\t\t\t\tisBigint: false,\n\t\t\t\t\t\t\t\tisOptional: false,\n\t\t\t\t\t\t\t\ttype: \"number\",\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t: getType({\n\t\t\t\t\t\t\t\tisBigint: attr?.bigint || false,\n\t\t\t\t\t\t\t\tisOptional: attr?.required === false,\n\t\t\t\t\t\t\t\ttype:\n\t\t\t\t\t\t\t\t\tattr.references?.field === \"id\"\n\t\t\t\t\t\t\t\t\t\t? useNumberId\n\t\t\t\t\t\t\t\t\t\t\t? \"number\"\n\t\t\t\t\t\t\t\t\t\t\t: \"string\"\n\t\t\t\t\t\t\t\t\t\t: attr.type,\n\t\t\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\tif (field === \"id\") {\n\t\t\t\t\tfieldBuilder.attribute(\"id\");\n\t\t\t\t\tif (provider === \"mongodb\") {\n\t\t\t\t\t\tfieldBuilder.attribute(`map(\"_id\")`);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (attr.unique) {\n\t\t\t\t\tbuilder.model(modelName).blockAttribute(`unique([${fieldName}])`);\n\t\t\t\t}\n\n\t\t\t\tif (attr.defaultValue !== undefined) {\n\t\t\t\t\tif (Array.isArray(attr.defaultValue)) {\n\t\t\t\t\t\t// for json objects and array of object\n\n\t\t\t\t\t\tif (attr.type === \"json\") {\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tObject.prototype.toString.call(attr.defaultValue[0]) ===\n\t\t\t\t\t\t\t\t\"[object Object]\"\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tfieldBuilder.attribute(\n\t\t\t\t\t\t\t\t\t`default(\"${JSON.stringify(attr.defaultValue).replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"')}\")`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst jsonArray = [];\n\t\t\t\t\t\t\tfor (const value of attr.defaultValue) jsonArray.push(value);\n\t\t\t\t\t\t\tfieldBuilder.attribute(\n\t\t\t\t\t\t\t\t`default(\"${JSON.stringify(jsonArray).replace(/\"/g, '\\\\\"')}\")`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (attr.defaultValue.length === 0) {\n\t\t\t\t\t\t\tfieldBuilder.attribute(`default([])`);\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\ttypeof attr.defaultValue[0] === \"string\" &&\n\t\t\t\t\t\t\tattr.type === \"string[]\"\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tconst valueArray = [];\n\t\t\t\t\t\t\tfor (const value of attr.defaultValue)\n\t\t\t\t\t\t\t\tvalueArray.push(JSON.stringify(value));\n\t\t\t\t\t\t\tfieldBuilder.attribute(`default([${valueArray}])`);\n\t\t\t\t\t\t} else if (typeof attr.defaultValue[0] === \"number\") {\n\t\t\t\t\t\t\tconst valueArray = [];\n\t\t\t\t\t\t\tfor (const value of attr.defaultValue)\n\t\t\t\t\t\t\t\tvalueArray.push(`${value}`);\n\t\t\t\t\t\t\tfieldBuilder.attribute(`default([${valueArray}])`);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// for json objects\n\t\t\t\t\telse if (\n\t\t\t\t\t\ttypeof attr.defaultValue === \"object\" &&\n\t\t\t\t\t\t!Array.isArray(attr.defaultValue) &&\n\t\t\t\t\t\tattr.defaultValue !== null\n\t\t\t\t\t) {\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tObject.entries(attr.defaultValue as Record<string, any>)\n\t\t\t\t\t\t\t\t.length === 0\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tfieldBuilder.attribute(`default(\"{}\")`);\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfieldBuilder.attribute(\n\t\t\t\t\t\t\t`default(\"${JSON.stringify(attr.defaultValue).replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"')}\")`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tif (field === \"createdAt\") {\n\t\t\t\t\t\tfieldBuilder.attribute(\"default(now())\");\n\t\t\t\t\t} else if (\n\t\t\t\t\t\ttypeof attr.defaultValue === \"string\" &&\n\t\t\t\t\t\tprovider !== \"mysql\"\n\t\t\t\t\t) {\n\t\t\t\t\t\tfieldBuilder.attribute(`default(\"${attr.defaultValue}\")`);\n\t\t\t\t\t} else if (\n\t\t\t\t\t\ttypeof attr.defaultValue === \"boolean\" ||\n\t\t\t\t\t\ttypeof attr.defaultValue === \"number\"\n\t\t\t\t\t) {\n\t\t\t\t\t\tfieldBuilder.attribute(`default(${attr.defaultValue})`);\n\t\t\t\t\t} else if (typeof attr.defaultValue === \"function\") {\n\t\t\t\t\t\t// we are intentionally not adding the default value here\n\t\t\t\t\t\t// this is because if the defaultValue is a function, it could have\n\t\t\t\t\t\t// custom logic within that function that might not work in prisma's context.\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// This is a special handling for updatedAt fields\n\t\t\t\tif (field === \"updatedAt\" && attr.onUpdate) {\n\t\t\t\t\tfieldBuilder.attribute(\"updatedAt\");\n\t\t\t\t} else if (attr.onUpdate) {\n\t\t\t\t\t// we are intentionally not adding the onUpdate value here\n\t\t\t\t\t// this is because if the onUpdate is a function, it could have\n\t\t\t\t\t// custom logic within that function that might not work in prisma's context.\n\t\t\t\t}\n\n\t\t\t\tif (attr.references) {\n\t\t\t\t\tif (\n\t\t\t\t\t\tuseUUIDs &&\n\t\t\t\t\t\tprovider === \"postgresql\" &&\n\t\t\t\t\t\tattr.references?.field === \"id\"\n\t\t\t\t\t) {\n\t\t\t\t\t\tbuilder.model(modelName).field(fieldName).attribute(`db.Uuid`);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst referencedOriginalModelName = getModelName(\n\t\t\t\t\t\tattr.references.model,\n\t\t\t\t\t);\n\t\t\t\t\tconst referencedCustomModelName =\n\t\t\t\t\t\ttables[referencedOriginalModelName]?.modelName ||\n\t\t\t\t\t\treferencedOriginalModelName;\n\t\t\t\t\tlet action = \"Cascade\";\n\t\t\t\t\tif (attr.references.onDelete === \"no action\") action = \"NoAction\";\n\t\t\t\t\telse if (attr.references.onDelete === \"set null\") action = \"SetNull\";\n\t\t\t\t\telse if (attr.references.onDelete === \"set default\")\n\t\t\t\t\t\taction = \"SetDefault\";\n\t\t\t\t\telse if (attr.references.onDelete === \"restrict\") action = \"Restrict\";\n\n\t\t\t\t\tconst relationField = `relation(fields: [${getFieldName({ model: originalTableName, field: fieldName })}], references: [${getFieldName({ model: attr.references.model, field: attr.references.field })}], onDelete: ${action})`;\n\t\t\t\t\tbuilder\n\t\t\t\t\t\t.model(modelName)\n\t\t\t\t\t\t.field(\n\t\t\t\t\t\t\treferencedCustomModelName.toLowerCase(),\n\t\t\t\t\t\t\t`${capitalizeFirstLetter(referencedCustomModelName)}${\n\t\t\t\t\t\t\t\tattr.required === false ? \"?\" : \"\"\n\t\t\t\t\t\t\t}`,\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.attribute(relationField);\n\t\t\t\t}\n\t\t\t\tif (\n\t\t\t\t\t!attr.unique &&\n\t\t\t\t\t!attr.references &&\n\t\t\t\t\tprovider === \"mysql\" &&\n\t\t\t\t\tattr.type === \"string\"\n\t\t\t\t) {\n\t\t\t\t\tbuilder.model(modelName).field(fieldName).attribute(\"db.Text\");\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add many-to-many fields\n\t\t\tif (manyToManyRelations.has(modelName)) {\n\t\t\t\tfor (const relatedModel of manyToManyRelations.get(modelName)) {\n\t\t\t\t\t// Find the FK field on the related model that points to this model\n\t\t\t\t\tconst relatedTableName = Object.keys(tables).find(\n\t\t\t\t\t\t(key) =>\n\t\t\t\t\t\t\tcapitalizeFirstLetter(tables[key]?.modelName || key) ===\n\t\t\t\t\t\t\trelatedModel,\n\t\t\t\t\t);\n\t\t\t\t\tconst relatedFields = relatedTableName\n\t\t\t\t\t\t? tables[relatedTableName]?.fields\n\t\t\t\t\t\t: {};\n\t\t\t\t\tconst fkField = Object.entries(relatedFields || {}).find(\n\t\t\t\t\t\t([_fieldName, fieldAttr]: any) =>\n\t\t\t\t\t\t\tfieldAttr.references &&\n\t\t\t\t\t\t\tgetModelName(fieldAttr.references.model) ===\n\t\t\t\t\t\t\t\tgetModelName(originalTableName),\n\t\t\t\t\t);\n\t\t\t\t\tconst [_fieldKey, fkFieldAttr] = fkField || [];\n\t\t\t\t\tconst isUnique = fkFieldAttr?.unique === true;\n\n\t\t\t\t\tconst fieldName =\n\t\t\t\t\t\tisUnique || adapter.options?.usePlural === true\n\t\t\t\t\t\t\t? `${relatedModel.toLowerCase()}`\n\t\t\t\t\t\t\t: `${relatedModel.toLowerCase()}s`;\n\t\t\t\t\tconst existingField = builder.findByType(\"field\", {\n\t\t\t\t\t\tname: fieldName,\n\t\t\t\t\t\twithin: prismaModel?.properties,\n\t\t\t\t\t});\n\t\t\t\t\tif (!existingField) {\n\t\t\t\t\t\tbuilder\n\t\t\t\t\t\t\t.model(modelName)\n\t\t\t\t\t\t\t.field(fieldName, `${relatedModel}${isUnique ? \"?\" : \"[]\"}`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add indexes\n\t\t\tconst indexedFieldsForModel = indexedFields.get(modelName);\n\t\t\tif (indexedFieldsForModel && indexedFieldsForModel.length > 0) {\n\t\t\t\tfor (const fieldName of indexedFieldsForModel) {\n\t\t\t\t\tif (prismaModel) {\n\t\t\t\t\t\tconst indexExist = prismaModel.properties.some(\n\t\t\t\t\t\t\t(v) =>\n\t\t\t\t\t\t\t\tv.type === \"attribute\" &&\n\t\t\t\t\t\t\t\tv.name === \"index\" &&\n\t\t\t\t\t\t\t\tJSON.stringify(v.args[0]?.value).includes(fieldName),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (indexExist) {\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tconst field = Object.entries(fields!).find(\n\t\t\t\t\t\t([key, attr]) => (attr.fieldName || key) === fieldName,\n\t\t\t\t\t)?.[1];\n\n\t\t\t\t\tlet indexField = fieldName;\n\t\t\t\t\tif (provider === \"mysql\" && field && field.type === \"string\") {\n\t\t\t\t\t\tconst useNumberId =\n\t\t\t\t\t\t\toptions.advanced?.database?.generateId === \"serial\";\n\t\t\t\t\t\tconst useUUIDs = options.advanced?.database?.generateId === \"uuid\";\n\t\t\t\t\t\tif (field.references?.field === \"id\" && (useNumberId || useUUIDs)) {\n\t\t\t\t\t\t\tindexField = `${fieldName}`;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tindexField = `${fieldName}(length: 191)`; // length of 191 because String in Prisma is varchar(191)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tbuilder.model(modelName).blockAttribute(`index([${indexField}])`);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst hasAttribute = builder.findByType(\"attribute\", {\n\t\t\t\tname: \"map\",\n\t\t\t\twithin: prismaModel?.properties,\n\t\t\t});\n\t\t\tconst hasChanged = customModelName !== originalTableName;\n\t\t\tif (!hasAttribute) {\n\t\t\t\tbuilder\n\t\t\t\t\t.model(modelName)\n\t\t\t\t\t.blockAttribute(\n\t\t\t\t\t\t\"map\",\n\t\t\t\t\t\t`${getModelName(hasChanged ? customModelName : originalTableName)}`,\n\t\t\t\t\t);\n\t\t\t}\n\t\t}\n\t});\n\n\tconst schemaChanged = schema.trim() !== schemaPrisma.trim();\n\n\treturn {\n\t\tcode: schemaChanged ? schema : \"\",\n\t\tfileName: filePath,\n\t\toverwrite: schemaPrismaExist && schemaChanged,\n\t};\n};\n\nconst getNewPrisma = (provider: string, cwd?: string) => {\n\tconst prismaVersion = getPrismaVersion(cwd);\n\tconst isV7 = prismaVersion && prismaVersion >= 7;\n\t// Use \"prisma-client\" for Prisma v7+, otherwise use \"prisma-client-js\"\n\tconst clientProvider = isV7 ? \"prisma-client\" : \"prisma-client-js\";\n\n\t// In Prisma v7+, the url is configured in prisma.config.ts instead of the schema\n\tif (isV7) {\n\t\treturn `generator client {\n provider = \"${clientProvider}\"\n }\n\n datasource db {\n provider = \"${provider}\"\n }`;\n\t}\n\n\treturn `generator client {\n provider = \"${clientProvider}\"\n }\n\n datasource db {\n provider = \"${provider}\"\n url = ${\n\t\t\tprovider === \"sqlite\" ? `\"file:./dev.db\"` : `env(\"DATABASE_URL\")`\n\t\t}\n }`;\n};\n","import type { BetterAuthOptions } from \"@better-auth/core\";\nimport type { DBAdapter } from \"@better-auth/core/db/adapter\";\nimport { generateDrizzleSchema } from \"./drizzle\";\nimport { generateKyselySchema } from \"./kysely\";\nimport { generatePrismaSchema } from \"./prisma\";\n\nexport const adapters = {\n\tprisma: generatePrismaSchema,\n\tdrizzle: generateDrizzleSchema,\n\tkysely: generateKyselySchema,\n};\n\nexport const generateSchema = (opts: {\n\tadapter: DBAdapter;\n\tfile?: string;\n\toptions: BetterAuthOptions;\n}) => {\n\tconst adapter = opts.adapter;\n\tconst generator =\n\t\tadapter.id in adapters\n\t\t\t? adapters[adapter.id as keyof typeof adapters]\n\t\t\t: null;\n\tif (generator) {\n\t\t// generator from the built-in list above\n\t\treturn generator(opts);\n\t}\n\tif (adapter.createSchema) {\n\t\t// use the custom adapter's createSchema method\n\t\treturn adapter\n\t\t\t.createSchema(opts.options, opts.file)\n\t\t\t.then(({ code, path: fileName, overwrite }) => ({\n\t\t\t\tcode,\n\t\t\t\tfileName,\n\t\t\t\toverwrite,\n\t\t\t}));\n\t}\n\n\tthrow new Error(\n\t\t`${adapter.id} is not supported. If it is a custom adapter, please request the maintainer to implement createSchema`,\n\t);\n};\n"],"mappings":"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"}