auth 1.5.0 → 1.5.1-beta.2

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/index.mjs CHANGED
@@ -1,5 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import { a as getPackageInfo, c as spawnCommand, d as generateDrizzleSchema, i as findMonorepoRoot, l as tryCatch, n as generateSchema, o as hasDependency, r as generatePrismaSchema, s as generateSecretHash$1 } from "./generators-YiCQyoNc.mjs";
3
2
  import { Command } from "commander";
4
3
  import * as fs$2 from "node:fs";
5
4
  import fs, { existsSync, readFileSync, readdirSync } from "node:fs";
@@ -11,10 +10,14 @@ import { getAdapter } from "better-auth/db/adapter";
11
10
  import chalk from "chalk";
12
11
  import prompts from "prompts";
13
12
  import yoctoSpinner from "yocto-spinner";
14
- import * as z$1 from "zod/v4";
15
- import { format } from "prettier";
13
+ import * as z from "zod";
14
+ import { initGetFieldName, initGetModelName } from "better-auth/adapters";
15
+ import { getAuthTables } from "better-auth/db";
16
+ import prettier, { format } from "prettier";
16
17
  import { getMigrations } from "better-auth/db/migration";
17
- import { exec, execSync } from "node:child_process";
18
+ import { capitalizeFirstLetter } from "@better-auth/core/utils/string";
19
+ import { produceSchema } from "@mrleebo/prisma-ast";
20
+ import { exec, execSync, spawn } from "node:child_process";
18
21
  import Crypto from "node:crypto";
19
22
  import babelPresetReact from "@babel/preset-react";
20
23
  import babelPresetTypeScript from "@babel/preset-typescript";
@@ -23,13 +26,673 @@ import { loadConfig } from "c12";
23
26
  import * as os$1 from "node:os";
24
27
  import os from "node:os";
25
28
  import open from "open";
26
- import z from "zod";
27
29
  import { env } from "@better-auth/core/env";
28
30
  import { log } from "@clack/prompts";
29
31
  import { base64 } from "@better-auth/utils/base64";
30
32
  import * as semver from "semver";
31
33
  import "dotenv/config";
32
34
 
35
+ //#region src/generators/drizzle.ts
36
+ function convertToSnakeCase(str, camelCase) {
37
+ if (camelCase) return str;
38
+ return str.replace(/([A-Z]+)([A-Z][a-z])/g, "$1_$2").replace(/([a-z\d])([A-Z])/g, "$1_$2").toLowerCase();
39
+ }
40
+ const generateDrizzleSchema = async ({ options, file, adapter }) => {
41
+ const tables = getAuthTables(options);
42
+ const filePath = file || "./auth-schema.ts";
43
+ const databaseType = adapter.options?.provider;
44
+ if (!databaseType) throw new Error(`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`);
45
+ const fileExist = existsSync(filePath);
46
+ let code = generateImport({
47
+ databaseType,
48
+ tables,
49
+ options
50
+ });
51
+ const getModelName = initGetModelName({
52
+ schema: tables,
53
+ usePlural: adapter.options?.adapterConfig?.usePlural
54
+ });
55
+ const getFieldName = initGetFieldName({
56
+ schema: tables,
57
+ usePlural: adapter.options?.adapterConfig?.usePlural
58
+ });
59
+ for (const tableKey in tables) {
60
+ const table = tables[tableKey];
61
+ const modelName = getModelName(tableKey);
62
+ const fields = table.fields;
63
+ function getType(name, field) {
64
+ if (!databaseType) throw new Error(`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`);
65
+ name = convertToSnakeCase(name, adapter.options?.camelCase);
66
+ if (field.references?.field === "id") {
67
+ const useNumberId = options.advanced?.database?.generateId === "serial";
68
+ const useUUIDs = options.advanced?.database?.generateId === "uuid";
69
+ if (useNumberId) if (databaseType === "pg") return `integer('${name}')`;
70
+ else if (databaseType === "mysql") return `int('${name}')`;
71
+ else return `integer('${name}')`;
72
+ if (useUUIDs && databaseType === "pg") return `uuid('${name}')`;
73
+ if (field.references.field) {
74
+ if (databaseType === "mysql") return `varchar('${name}', { length: 36 })`;
75
+ }
76
+ return `text('${name}')`;
77
+ }
78
+ const type = field.type;
79
+ if (typeof type !== "string") if (Array.isArray(type) && type.every((x) => typeof x === "string")) return {
80
+ sqlite: `text({ enum: [${type.map((x) => `'${x}'`).join(", ")}] })`,
81
+ pg: `text('${name}', { enum: [${type.map((x) => `'${x}'`).join(", ")}] })`,
82
+ mysql: `mysqlEnum([${type.map((x) => `'${x}'`).join(", ")}])`
83
+ }[databaseType];
84
+ else throw new TypeError(`Invalid field type for field ${name} in model ${modelName}`);
85
+ const dbTypeMap = {
86
+ string: {
87
+ sqlite: `text('${name}')`,
88
+ pg: `text('${name}')`,
89
+ mysql: field.unique ? `varchar('${name}', { length: 255 })` : field.references ? `varchar('${name}', { length: 36 })` : field.sortable ? `varchar('${name}', { length: 255 })` : field.index ? `varchar('${name}', { length: 255 })` : `text('${name}')`
90
+ },
91
+ boolean: {
92
+ sqlite: `integer('${name}', { mode: 'boolean' })`,
93
+ pg: `boolean('${name}')`,
94
+ mysql: `boolean('${name}')`
95
+ },
96
+ number: {
97
+ sqlite: `integer('${name}')`,
98
+ pg: field.bigint ? `bigint('${name}', { mode: 'number' })` : `integer('${name}')`,
99
+ mysql: field.bigint ? `bigint('${name}', { mode: 'number' })` : `int('${name}')`
100
+ },
101
+ date: {
102
+ sqlite: `integer('${name}', { mode: 'timestamp_ms' })`,
103
+ pg: `timestamp('${name}')`,
104
+ mysql: `timestamp('${name}', { fsp: 3 })`
105
+ },
106
+ "number[]": {
107
+ sqlite: `text('${name}', { mode: "json" })`,
108
+ pg: field.bigint ? `bigint('${name}', { mode: 'number' }).array()` : `integer('${name}').array()`,
109
+ mysql: `text('${name}', { mode: 'json' })`
110
+ },
111
+ "string[]": {
112
+ sqlite: `text('${name}', { mode: "json" })`,
113
+ pg: `text('${name}').array()`,
114
+ mysql: `text('${name}', { mode: "json" })`
115
+ },
116
+ json: {
117
+ sqlite: `text('${name}', { mode: "json" })`,
118
+ pg: `jsonb('${name}')`,
119
+ mysql: `json('${name}', { mode: "json" })`
120
+ }
121
+ }[type];
122
+ if (!dbTypeMap) throw new Error(`Unsupported field type '${field.type}' for field '${name}'.`);
123
+ return dbTypeMap[databaseType];
124
+ }
125
+ let id = "";
126
+ const useNumberId = options.advanced?.database?.generateId === "serial";
127
+ if (options.advanced?.database?.generateId === "uuid" && databaseType === "pg") id = `uuid("id").default(sql\`pg_catalog.gen_random_uuid()\`).primaryKey()`;
128
+ else if (useNumberId) if (databaseType === "pg") id = `integer("id").generatedByDefaultAsIdentity().primaryKey()`;
129
+ else if (databaseType === "sqlite") id = `integer("id", { mode: "number" }).primaryKey({ autoIncrement: true })`;
130
+ else id = `int("id").autoincrement().primaryKey()`;
131
+ else if (databaseType === "mysql") id = `varchar('id', { length: 36 }).primaryKey()`;
132
+ else if (databaseType === "pg") id = `text('id').primaryKey()`;
133
+ else id = `text('id').primaryKey()`;
134
+ const indexes = [];
135
+ const assignIndexes = (indexes) => {
136
+ if (!indexes.length) return "";
137
+ const code = [`, (table) => [`];
138
+ for (const index of indexes) code.push(` ${index.type}("${index.name}").on(table.${index.on}),`);
139
+ code.push(`]`);
140
+ return code.join("\n");
141
+ };
142
+ const schema = `export const ${modelName} = ${databaseType}Table("${convertToSnakeCase(modelName, adapter.options?.camelCase)}", {
143
+ id: ${id},
144
+ ${Object.keys(fields).map((field) => {
145
+ const attr = fields[field];
146
+ const fieldName = attr.fieldName || field;
147
+ let type = getType(fieldName, attr);
148
+ if (attr.index && !attr.unique) indexes.push({
149
+ type: "index",
150
+ name: `${modelName}_${fieldName}_idx`,
151
+ on: fieldName
152
+ });
153
+ else if (attr.index && attr.unique) indexes.push({
154
+ type: "uniqueIndex",
155
+ name: `${modelName}_${fieldName}_uidx`,
156
+ on: fieldName
157
+ });
158
+ if (attr.defaultValue !== null && typeof attr.defaultValue !== "undefined") if (typeof attr.defaultValue === "function") {
159
+ if (attr.type === "date" && attr.defaultValue.toString().includes("new Date()")) if (databaseType === "sqlite") type += `.default(sql\`(cast(unixepoch('subsecond') * 1000 as integer))\`)`;
160
+ else type += `.defaultNow()`;
161
+ } else if (typeof attr.defaultValue === "string") type += `.default("${attr.defaultValue}")`;
162
+ else type += `.default(${attr.defaultValue})`;
163
+ if (attr.onUpdate && attr.type === "date") {
164
+ if (typeof attr.onUpdate === "function") type += `.$onUpdate(${attr.onUpdate})`;
165
+ }
166
+ return `${fieldName}: ${type}${attr.required ? ".notNull()" : ""}${attr.unique ? ".unique()" : ""}${attr.references ? `.references(()=> ${getModelName(attr.references.model)}.${getFieldName({
167
+ model: attr.references.model,
168
+ field: attr.references.field
169
+ })}, { onDelete: '${attr.references.onDelete || "cascade"}' })` : ""}`;
170
+ }).join(",\n ")}
171
+ }${assignIndexes(indexes)});`;
172
+ code += `\n${schema}\n`;
173
+ }
174
+ let relationsString = "";
175
+ for (const tableKey in tables) {
176
+ const table = tables[tableKey];
177
+ const modelName = getModelName(tableKey);
178
+ const oneRelations = [];
179
+ const manyRelations = [];
180
+ const manyRelationsSet = /* @__PURE__ */ new Set();
181
+ const foreignFields = Object.entries(table.fields).filter(([_, field]) => field.references);
182
+ for (const [fieldName, field] of foreignFields) {
183
+ const referencedModel = field.references.model;
184
+ const relationKey = getModelName(referencedModel);
185
+ const fieldRef = `${getModelName(tableKey)}.${getFieldName({
186
+ model: tableKey,
187
+ field: fieldName
188
+ })}`;
189
+ const referenceRef = `${getModelName(referencedModel)}.${getFieldName({
190
+ model: referencedModel,
191
+ field: field.references.field || "id"
192
+ })}`;
193
+ oneRelations.push({
194
+ key: relationKey,
195
+ model: getModelName(referencedModel),
196
+ type: "one",
197
+ reference: {
198
+ field: fieldRef,
199
+ references: referenceRef,
200
+ fieldName
201
+ }
202
+ });
203
+ }
204
+ const otherModels = Object.entries(tables).filter(([modelName]) => modelName !== tableKey);
205
+ const modelRelationsMap = /* @__PURE__ */ new Map();
206
+ for (const [modelName, otherTable] of otherModels) {
207
+ const foreignKeysPointingHere = Object.entries(otherTable.fields).filter(([_, field]) => field.references?.model === tableKey || field.references?.model === getModelName(tableKey));
208
+ if (foreignKeysPointingHere.length === 0) continue;
209
+ const hasUnique = foreignKeysPointingHere.some(([_, field]) => !!field.unique);
210
+ const hasMany = foreignKeysPointingHere.some(([_, field]) => !field.unique);
211
+ modelRelationsMap.set(modelName, {
212
+ modelName,
213
+ hasUnique,
214
+ hasMany
215
+ });
216
+ }
217
+ for (const { modelName, hasMany } of modelRelationsMap.values()) {
218
+ const relationType = hasMany ? "many" : "one";
219
+ let relationKey = getModelName(modelName);
220
+ if (!adapter.options?.adapterConfig?.usePlural && relationType === "many") relationKey = `${relationKey}s`;
221
+ if (!manyRelationsSet.has(relationKey)) {
222
+ manyRelationsSet.add(relationKey);
223
+ manyRelations.push({
224
+ key: relationKey,
225
+ model: getModelName(modelName),
226
+ type: relationType
227
+ });
228
+ }
229
+ }
230
+ const relationsByModel = /* @__PURE__ */ new Map();
231
+ for (const relation of oneRelations) if (relation.reference) {
232
+ const modelKey = relation.key;
233
+ if (!relationsByModel.has(modelKey)) relationsByModel.set(modelKey, []);
234
+ relationsByModel.get(modelKey).push(relation);
235
+ }
236
+ const duplicateRelations = [];
237
+ const singleRelations = [];
238
+ for (const [_modelKey, relations] of relationsByModel.entries()) if (relations.length > 1) duplicateRelations.push(...relations);
239
+ else singleRelations.push(relations[0]);
240
+ for (const relation of duplicateRelations) if (relation.reference) {
241
+ const fieldName = relation.reference.fieldName;
242
+ const tableRelation = `export const ${`${modelName}${fieldName.charAt(0).toUpperCase() + fieldName.slice(1)}Relations`} = relations(${getModelName(table.modelName)}, ({ one }) => ({
243
+ ${relation.key}: one(${relation.model}, {
244
+ fields: [${relation.reference.field}],
245
+ references: [${relation.reference.references}],
246
+ })
247
+ }))`;
248
+ relationsString += `\n${tableRelation}\n`;
249
+ }
250
+ const hasOne = singleRelations.length > 0;
251
+ const hasMany = manyRelations.length > 0;
252
+ if (hasOne && hasMany) {
253
+ const tableRelation = `export const ${modelName}Relations = relations(${getModelName(table.modelName)}, ({ one, many }) => ({
254
+ ${singleRelations.map((relation) => relation.reference ? ` ${relation.key}: one(${relation.model}, {
255
+ fields: [${relation.reference.field}],
256
+ references: [${relation.reference.references}],
257
+ })` : "").filter((x) => x !== "").join(",\n ")}${singleRelations.length > 0 && manyRelations.length > 0 ? "," : ""}
258
+ ${manyRelations.map(({ key, model }) => ` ${key}: many(${model})`).join(",\n ")}
259
+ }))`;
260
+ relationsString += `\n${tableRelation}\n`;
261
+ } else if (hasOne) {
262
+ const tableRelation = `export const ${modelName}Relations = relations(${getModelName(table.modelName)}, ({ one }) => ({
263
+ ${singleRelations.map((relation) => relation.reference ? ` ${relation.key}: one(${relation.model}, {
264
+ fields: [${relation.reference.field}],
265
+ references: [${relation.reference.references}],
266
+ })` : "").filter((x) => x !== "").join(",\n ")}
267
+ }))`;
268
+ relationsString += `\n${tableRelation}\n`;
269
+ } else if (hasMany) {
270
+ const tableRelation = `export const ${modelName}Relations = relations(${getModelName(table.modelName)}, ({ many }) => ({
271
+ ${manyRelations.map(({ key, model }) => ` ${key}: many(${model})`).join(",\n ")}
272
+ }))`;
273
+ relationsString += `\n${tableRelation}\n`;
274
+ }
275
+ }
276
+ code += `\n${relationsString}`;
277
+ return {
278
+ code: await prettier.format(code, { parser: "typescript" }),
279
+ fileName: filePath,
280
+ overwrite: fileExist
281
+ };
282
+ };
283
+ function generateImport({ databaseType, tables, options }) {
284
+ const rootImports = ["relations"];
285
+ const coreImports = [];
286
+ let hasBigint = false;
287
+ let hasJson = false;
288
+ for (const table of Object.values(tables)) {
289
+ for (const field of Object.values(table.fields)) {
290
+ if (field.bigint) hasBigint = true;
291
+ if (field.type === "json") hasJson = true;
292
+ }
293
+ if (hasJson && hasBigint) break;
294
+ }
295
+ const useNumberId = options.advanced?.database?.generateId === "serial";
296
+ const useUUIDs = options.advanced?.database?.generateId === "uuid";
297
+ coreImports.push(`${databaseType}Table`);
298
+ coreImports.push(databaseType === "mysql" ? "varchar, text" : databaseType === "pg" ? "text" : "text");
299
+ coreImports.push(hasBigint ? databaseType !== "sqlite" ? "bigint" : "" : "");
300
+ coreImports.push(databaseType !== "sqlite" ? "timestamp, boolean" : "");
301
+ if (databaseType === "mysql") {
302
+ const hasNonBigintNumber = Object.values(tables).some((table) => Object.values(table.fields).some((field) => (field.type === "number" || field.type === "number[]") && !field.bigint));
303
+ if (useNumberId || hasNonBigintNumber) coreImports.push("int");
304
+ if (Object.values(tables).some((table) => Object.values(table.fields).some((field) => typeof field.type !== "string" && Array.isArray(field.type) && field.type.every((x) => typeof x === "string")))) coreImports.push("mysqlEnum");
305
+ } else if (databaseType === "pg") {
306
+ if (useUUIDs) rootImports.push("sql");
307
+ const hasNonBigintNumber = Object.values(tables).some((table) => Object.values(table.fields).some((field) => (field.type === "number" || field.type === "number[]") && !field.bigint));
308
+ const hasFkToId = Object.values(tables).some((table) => Object.values(table.fields).some((field) => field.references?.field === "id"));
309
+ if (hasNonBigintNumber || options.advanced?.database?.generateId === "serial" && hasFkToId) coreImports.push("integer");
310
+ } else coreImports.push("integer");
311
+ if (databaseType === "pg" && useUUIDs) coreImports.push("uuid");
312
+ if (hasJson) {
313
+ if (databaseType === "pg") coreImports.push("jsonb");
314
+ if (databaseType === "mysql") coreImports.push("json");
315
+ }
316
+ if (databaseType === "sqlite" && Object.values(tables).some((table) => Object.values(table.fields).some((field) => field.type === "date" && field.defaultValue && typeof field.defaultValue === "function" && field.defaultValue.toString().includes("new Date()")))) rootImports.push("sql");
317
+ const hasIndexes = Object.values(tables).some((table) => Object.values(table.fields).some((field) => field.index && !field.unique));
318
+ const hasUniqueIndexes = Object.values(tables).some((table) => Object.values(table.fields).some((field) => field.unique && field.index));
319
+ if (hasIndexes) coreImports.push("index");
320
+ if (hasUniqueIndexes) coreImports.push("uniqueIndex");
321
+ 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`;
322
+ }
323
+
324
+ //#endregion
325
+ //#region src/generators/kysely.ts
326
+ const generateKyselySchema = async ({ options, file }) => {
327
+ const { compileMigrations } = await getMigrations(options);
328
+ const migrations = await compileMigrations();
329
+ return {
330
+ code: migrations.trim() === ";" ? "" : migrations,
331
+ fileName: file || `./better-auth_migrations/${(/* @__PURE__ */ new Date()).toISOString().replace(/:/g, "-")}.sql`
332
+ };
333
+ };
334
+
335
+ //#endregion
336
+ //#region src/utils/helper.ts
337
+ async function tryCatch(promise) {
338
+ try {
339
+ return {
340
+ data: await promise,
341
+ error: null
342
+ };
343
+ } catch (error) {
344
+ return {
345
+ data: null,
346
+ error
347
+ };
348
+ }
349
+ }
350
+ const generateSecretHash$1 = () => {
351
+ return Crypto.randomBytes(16).toString("hex");
352
+ };
353
+ const spawnCommand = (cmd, cwd = process.cwd()) => new Promise((resolve, reject) => {
354
+ const child = spawn(cmd, {
355
+ cwd,
356
+ stdio: "inherit",
357
+ shell: true
358
+ });
359
+ child.on("close", (code, signal) => {
360
+ if (code !== 0 && code !== null) reject(/* @__PURE__ */ new Error(`Exited with code ${code}`));
361
+ else if (signal) reject(/* @__PURE__ */ new Error(`Killed with signal ${signal}`));
362
+ else resolve();
363
+ });
364
+ child.on("error", reject);
365
+ });
366
+
367
+ //#endregion
368
+ //#region src/utils/get-package-info.ts
369
+ function getPackageInfo(cwd) {
370
+ const packageJsonPath = cwd ? path.join(cwd, "package.json") : path.join("package.json");
371
+ return JSON.parse(readFileSync(packageJsonPath, "utf-8"));
372
+ }
373
+ function getPrismaVersion(cwd) {
374
+ try {
375
+ const packageInfo = getPackageInfo(cwd);
376
+ const prismaVersion = packageInfo.dependencies?.prisma || packageInfo.devDependencies?.prisma || packageInfo.dependencies?.["@prisma/client"] || packageInfo.devDependencies?.["@prisma/client"];
377
+ if (!prismaVersion) return null;
378
+ const match = prismaVersion.match(/(\d+)/);
379
+ return match ? parseInt(match[1], 10) : null;
380
+ } catch {
381
+ return null;
382
+ }
383
+ }
384
+ /**
385
+ * Checks if a package has a specific dependency.
386
+ *
387
+ * @param packageJson The package.json object
388
+ * @param dependency The dependency to check for
389
+ * @returns true if the package has the dependency
390
+ */
391
+ function hasDependency(packageJson, dependency) {
392
+ let hasDependency = false;
393
+ if (packageJson.dependencies?.[dependency] || packageJson.devDependencies?.[dependency] || packageJson.peerDependencies?.[dependency] || packageJson.optionalDependencies?.[dependency]) hasDependency = true;
394
+ return hasDependency;
395
+ }
396
+ /**
397
+ * Checks if a directory is a monorepo root by looking for common monorepo indicators.
398
+ *
399
+ * @param dir Directory to check
400
+ * @returns true if the directory appears to be a monorepo root
401
+ */
402
+ async function isMonorepoRoot(dir) {
403
+ const { data: files } = await tryCatch(fs$1.readdir(dir, "utf-8"));
404
+ if (!files) return false;
405
+ if (files.includes("pnpm-workspace.yaml")) return true;
406
+ if (files.includes("package.json")) {
407
+ const packageJsonPath = path.join(dir, "package.json");
408
+ const { data } = await tryCatch(fs$1.readFile(packageJsonPath, "utf-8"));
409
+ if (data) try {
410
+ const packageJson = JSON.parse(data);
411
+ if (packageJson.workspaces && (Array.isArray(packageJson.workspaces) || typeof packageJson.workspaces === "object")) return true;
412
+ } catch {}
413
+ }
414
+ return [
415
+ "lerna.json",
416
+ "turbo.json",
417
+ "nx.json",
418
+ "rush.json"
419
+ ].some((indicator) => files.includes(indicator));
420
+ }
421
+ /**
422
+ * Finds the monorepo root by walking up the directory tree.
423
+ *
424
+ * @param startDir Starting directory
425
+ * @returns Path to monorepo root, or null if not found
426
+ */
427
+ async function findMonorepoRoot(startDir) {
428
+ let currentDir = path.resolve(startDir);
429
+ const root = path.parse(currentDir).root;
430
+ while (currentDir !== root) {
431
+ if (await isMonorepoRoot(currentDir)) return currentDir;
432
+ const parentDir = path.dirname(currentDir);
433
+ if (parentDir === currentDir) break;
434
+ currentDir = parentDir;
435
+ }
436
+ return null;
437
+ }
438
+
439
+ //#endregion
440
+ //#region src/generators/prisma.ts
441
+ const generatePrismaSchema = async ({ adapter, options, file }) => {
442
+ const provider = adapter.options?.provider || "postgresql";
443
+ const tables = getAuthTables(options);
444
+ const filePath = file || "./prisma/schema.prisma";
445
+ const schemaPrismaExist = existsSync(path.join(process.cwd(), filePath));
446
+ const getModelName = initGetModelName({
447
+ schema: getAuthTables(options),
448
+ usePlural: adapter.options?.adapterConfig?.usePlural
449
+ });
450
+ const getFieldName = initGetFieldName({
451
+ schema: getAuthTables(options),
452
+ usePlural: false
453
+ });
454
+ let schemaPrisma = "";
455
+ if (schemaPrismaExist) schemaPrisma = await fs$1.readFile(path.join(process.cwd(), filePath), "utf-8");
456
+ else schemaPrisma = getNewPrisma(provider, process.cwd());
457
+ const prismaVersion = getPrismaVersion(process.cwd());
458
+ if (prismaVersion && prismaVersion >= 7 && schemaPrismaExist) schemaPrisma = produceSchema(schemaPrisma, (builder) => {
459
+ const generator = builder.findByType("generator", { name: "client" });
460
+ if (generator && generator.properties) {
461
+ const providerProp = generator.properties.find((prop) => prop.type === "assignment" && prop.key === "provider");
462
+ if (providerProp && providerProp.value === "\"prisma-client-js\"") providerProp.value = "\"prisma-client\"";
463
+ }
464
+ const datasource = builder.findByType("datasource", { name: "db" });
465
+ if (datasource && datasource.properties) {
466
+ const urlIndex = datasource.properties.findIndex((prop) => prop.type === "assignment" && prop.key === "url");
467
+ if (urlIndex !== -1) datasource.properties.splice(urlIndex, 1);
468
+ }
469
+ });
470
+ const manyToManyRelations = /* @__PURE__ */ new Map();
471
+ for (const table in tables) {
472
+ const fields = tables[table]?.fields;
473
+ for (const field in fields) {
474
+ const attr = fields[field];
475
+ if (attr.references) {
476
+ const referencedOriginalModel = attr.references.model;
477
+ const referencedModelNameCap = capitalizeFirstLetter(getModelName(tables[referencedOriginalModel]?.modelName || referencedOriginalModel));
478
+ if (!manyToManyRelations.has(referencedModelNameCap)) manyToManyRelations.set(referencedModelNameCap, /* @__PURE__ */ new Set());
479
+ const currentModelNameCap = capitalizeFirstLetter(getModelName(tables[table]?.modelName || table));
480
+ manyToManyRelations.get(referencedModelNameCap).add(currentModelNameCap);
481
+ }
482
+ }
483
+ }
484
+ const indexedFields = /* @__PURE__ */ new Map();
485
+ for (const table in tables) {
486
+ const fields = tables[table]?.fields;
487
+ const modelName = capitalizeFirstLetter(getModelName(tables[table]?.modelName || table));
488
+ indexedFields.set(modelName, []);
489
+ for (const field in fields) {
490
+ const attr = fields[field];
491
+ if (attr.index && !attr.unique) {
492
+ const fieldName = attr.fieldName || field;
493
+ indexedFields.get(modelName).push(fieldName);
494
+ }
495
+ }
496
+ }
497
+ const schema = produceSchema(schemaPrisma, (builder) => {
498
+ for (const table in tables) {
499
+ const originalTableName = table;
500
+ const customModelName = tables[table]?.modelName || table;
501
+ const modelName = capitalizeFirstLetter(getModelName(customModelName));
502
+ const fields = tables[table]?.fields;
503
+ function getType({ isBigint, isOptional, type }) {
504
+ if (type === "string") return isOptional ? "String?" : "String";
505
+ if (type === "number" && isBigint) return isOptional ? "BigInt?" : "BigInt";
506
+ if (type === "number") return isOptional ? "Int?" : "Int";
507
+ if (type === "boolean") return isOptional ? "Boolean?" : "Boolean";
508
+ if (type === "date") return isOptional ? "DateTime?" : "DateTime";
509
+ if (type === "json") {
510
+ if (provider === "sqlite" || provider === "mysql") return isOptional ? "String?" : "String";
511
+ return isOptional ? "Json?" : "Json";
512
+ }
513
+ if (type === "string[]") {
514
+ if (provider === "sqlite" || provider === "mysql") return isOptional ? "String?" : "String";
515
+ return "String[]";
516
+ }
517
+ if (type === "number[]") {
518
+ if (provider === "sqlite" || provider === "mysql") return "String";
519
+ return "Int[]";
520
+ }
521
+ }
522
+ const prismaModel = builder.findByType("model", { name: modelName });
523
+ if (!prismaModel) if (provider === "mongodb") builder.model(modelName).field("id", "String").attribute("id").attribute(`map("_id")`);
524
+ else {
525
+ const useNumberId = options.advanced?.database?.generateId === "serial";
526
+ const useUUIDs = options.advanced?.database?.generateId === "uuid";
527
+ if (useNumberId) builder.model(modelName).field("id", "Int").attribute("id").attribute("default(autoincrement())");
528
+ else if (useUUIDs && provider === "postgresql") builder.model(modelName).field("id", "String").attribute("id").attribute("default(dbgenerated(\"pg_catalog.gen_random_uuid()\"))").attribute("db.Uuid");
529
+ else builder.model(modelName).field("id", "String").attribute("id");
530
+ }
531
+ for (const field in fields) {
532
+ const attr = fields[field];
533
+ const fieldName = attr.fieldName || field;
534
+ if (prismaModel) {
535
+ if (builder.findByType("field", {
536
+ name: fieldName,
537
+ within: prismaModel.properties
538
+ })) continue;
539
+ }
540
+ const useUUIDs = options.advanced?.database?.generateId === "uuid";
541
+ const useNumberId = options.advanced?.database?.generateId === "serial";
542
+ const fieldBuilder = builder.model(modelName).field(fieldName, field === "id" && useNumberId ? getType({
543
+ isBigint: false,
544
+ isOptional: false,
545
+ type: "number"
546
+ }) : getType({
547
+ isBigint: attr?.bigint || false,
548
+ isOptional: !attr?.required,
549
+ type: attr.references?.field === "id" ? useNumberId ? "number" : "string" : attr.type
550
+ }));
551
+ if (field === "id") {
552
+ fieldBuilder.attribute("id");
553
+ if (provider === "mongodb") fieldBuilder.attribute(`map("_id")`);
554
+ }
555
+ if (attr.unique) builder.model(modelName).blockAttribute(`unique([${fieldName}])`);
556
+ if (attr.defaultValue !== void 0) {
557
+ if (Array.isArray(attr.defaultValue)) {
558
+ if (attr.type === "json") {
559
+ if (Object.prototype.toString.call(attr.defaultValue[0]) === "[object Object]") {
560
+ fieldBuilder.attribute(`default("${JSON.stringify(attr.defaultValue).replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}")`);
561
+ continue;
562
+ }
563
+ const jsonArray = [];
564
+ for (const value of attr.defaultValue) jsonArray.push(value);
565
+ fieldBuilder.attribute(`default("${JSON.stringify(jsonArray).replace(/"/g, "\\\"")}")`);
566
+ continue;
567
+ }
568
+ if (attr.defaultValue.length === 0) {
569
+ fieldBuilder.attribute(`default([])`);
570
+ continue;
571
+ } else if (typeof attr.defaultValue[0] === "string" && attr.type === "string[]") {
572
+ const valueArray = [];
573
+ for (const value of attr.defaultValue) valueArray.push(JSON.stringify(value));
574
+ fieldBuilder.attribute(`default([${valueArray}])`);
575
+ } else if (typeof attr.defaultValue[0] === "number") {
576
+ const valueArray = [];
577
+ for (const value of attr.defaultValue) valueArray.push(`${value}`);
578
+ fieldBuilder.attribute(`default([${valueArray}])`);
579
+ }
580
+ } else if (typeof attr.defaultValue === "object" && !Array.isArray(attr.defaultValue) && attr.defaultValue !== null) {
581
+ if (Object.entries(attr.defaultValue).length === 0) {
582
+ fieldBuilder.attribute(`default("{}")`);
583
+ continue;
584
+ }
585
+ fieldBuilder.attribute(`default("${JSON.stringify(attr.defaultValue).replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}")`);
586
+ }
587
+ if (field === "createdAt") fieldBuilder.attribute("default(now())");
588
+ else if (typeof attr.defaultValue === "string" && provider !== "mysql") fieldBuilder.attribute(`default("${attr.defaultValue}")`);
589
+ else if (typeof attr.defaultValue === "boolean" || typeof attr.defaultValue === "number") fieldBuilder.attribute(`default(${attr.defaultValue})`);
590
+ else if (typeof attr.defaultValue === "function") {}
591
+ }
592
+ if (field === "updatedAt" && attr.onUpdate) fieldBuilder.attribute("updatedAt");
593
+ else if (attr.onUpdate) {}
594
+ if (attr.references) {
595
+ if (useUUIDs && provider === "postgresql" && attr.references?.field === "id") builder.model(modelName).field(fieldName).attribute(`db.Uuid`);
596
+ const referencedOriginalModelName = getModelName(attr.references.model);
597
+ const referencedCustomModelName = tables[referencedOriginalModelName]?.modelName || referencedOriginalModelName;
598
+ let action = "Cascade";
599
+ if (attr.references.onDelete === "no action") action = "NoAction";
600
+ else if (attr.references.onDelete === "set null") action = "SetNull";
601
+ else if (attr.references.onDelete === "set default") action = "SetDefault";
602
+ else if (attr.references.onDelete === "restrict") action = "Restrict";
603
+ const relationField = `relation(fields: [${getFieldName({
604
+ model: originalTableName,
605
+ field: fieldName
606
+ })}], references: [${getFieldName({
607
+ model: attr.references.model,
608
+ field: attr.references.field
609
+ })}], onDelete: ${action})`;
610
+ builder.model(modelName).field(referencedCustomModelName.toLowerCase(), `${capitalizeFirstLetter(referencedCustomModelName)}${!attr.required ? "?" : ""}`).attribute(relationField);
611
+ }
612
+ if (!attr.unique && !attr.references && provider === "mysql" && attr.type === "string") builder.model(modelName).field(fieldName).attribute("db.Text");
613
+ }
614
+ if (manyToManyRelations.has(modelName)) for (const relatedModel of manyToManyRelations.get(modelName)) {
615
+ const relatedTableName = Object.keys(tables).find((key) => capitalizeFirstLetter(tables[key]?.modelName || key) === relatedModel);
616
+ const relatedFields = relatedTableName ? tables[relatedTableName]?.fields : {};
617
+ const [_fieldKey, fkFieldAttr] = Object.entries(relatedFields || {}).find(([_fieldName, fieldAttr]) => fieldAttr.references && getModelName(fieldAttr.references.model) === getModelName(originalTableName)) || [];
618
+ const isUnique = fkFieldAttr?.unique === true;
619
+ const fieldName = isUnique || adapter.options?.usePlural === true ? `${relatedModel.toLowerCase()}` : `${relatedModel.toLowerCase()}s`;
620
+ if (!builder.findByType("field", {
621
+ name: fieldName,
622
+ within: prismaModel?.properties
623
+ })) builder.model(modelName).field(fieldName, `${relatedModel}${isUnique ? "?" : "[]"}`);
624
+ }
625
+ const indexedFieldsForModel = indexedFields.get(modelName);
626
+ if (indexedFieldsForModel && indexedFieldsForModel.length > 0) for (const fieldName of indexedFieldsForModel) {
627
+ if (prismaModel) {
628
+ if (prismaModel.properties.some((v) => v.type === "attribute" && v.name === "index" && JSON.stringify(v.args[0]?.value).includes(fieldName))) continue;
629
+ }
630
+ const field = Object.entries(fields).find(([key, attr]) => (attr.fieldName || key) === fieldName)?.[1];
631
+ let indexField = fieldName;
632
+ if (provider === "mysql" && field && field.type === "string") {
633
+ const useNumberId = options.advanced?.database?.generateId === "serial";
634
+ const useUUIDs = options.advanced?.database?.generateId === "uuid";
635
+ if (field.references?.field === "id" && (useNumberId || useUUIDs)) indexField = `${fieldName}`;
636
+ else indexField = `${fieldName}(length: 191)`;
637
+ }
638
+ builder.model(modelName).blockAttribute(`index([${indexField}])`);
639
+ }
640
+ const hasAttribute = builder.findByType("attribute", {
641
+ name: "map",
642
+ within: prismaModel?.properties
643
+ });
644
+ const hasChanged = customModelName !== originalTableName;
645
+ if (!hasAttribute) builder.model(modelName).blockAttribute("map", `${getModelName(hasChanged ? customModelName : originalTableName)}`);
646
+ }
647
+ });
648
+ const schemaChanged = schema.trim() !== schemaPrisma.trim();
649
+ return {
650
+ code: schemaChanged ? schema : "",
651
+ fileName: filePath,
652
+ overwrite: schemaPrismaExist && schemaChanged
653
+ };
654
+ };
655
+ const getNewPrisma = (provider, cwd) => {
656
+ const prismaVersion = getPrismaVersion(cwd);
657
+ const isV7 = prismaVersion && prismaVersion >= 7;
658
+ const clientProvider = isV7 ? "prisma-client" : "prisma-client-js";
659
+ if (isV7) return `generator client {
660
+ provider = "${clientProvider}"
661
+ }
662
+
663
+ datasource db {
664
+ provider = "${provider}"
665
+ }`;
666
+ return `generator client {
667
+ provider = "${clientProvider}"
668
+ }
669
+
670
+ datasource db {
671
+ provider = "${provider}"
672
+ url = ${provider === "sqlite" ? `"file:./dev.db"` : `env("DATABASE_URL")`}
673
+ }`;
674
+ };
675
+
676
+ //#endregion
677
+ //#region src/generators/index.ts
678
+ const adapters = {
679
+ prisma: generatePrismaSchema,
680
+ drizzle: generateDrizzleSchema,
681
+ kysely: generateKyselySchema
682
+ };
683
+ const generateSchema = (opts) => {
684
+ const adapter = opts.adapter;
685
+ const generator = adapter.id in adapters ? adapters[adapter.id] : null;
686
+ if (generator) return generator(opts);
687
+ if (adapter.createSchema) return adapter.createSchema(opts.options, opts.file).then(({ code, path: fileName, overwrite }) => ({
688
+ code,
689
+ fileName,
690
+ overwrite
691
+ }));
692
+ throw new Error(`${adapter.id} is not supported. If it is a custom adapter, please request the maintainer to implement createSchema`);
693
+ };
694
+
695
+ //#endregion
33
696
  //#region src/utils/add-cloudflare-modules.ts
34
697
  const createModule = () => {
35
698
  return `data:text/javascript;charset=utf-8,${encodeURIComponent(`
@@ -481,14 +1144,14 @@ function createMockAdapter$1(adapterId, dialect) {
481
1144
  };
482
1145
  }
483
1146
  async function generateAction(opts) {
484
- const options = z$1.object({
485
- cwd: z$1.string(),
486
- config: z$1.string().optional(),
487
- output: z$1.string().optional(),
488
- adapter: z$1.string().optional(),
489
- dialect: z$1.string().optional(),
490
- y: z$1.boolean().optional(),
491
- yes: z$1.boolean().optional()
1147
+ const options = z.object({
1148
+ cwd: z.string(),
1149
+ config: z.string().optional(),
1150
+ output: z.string().optional(),
1151
+ adapter: z.string().optional(),
1152
+ dialect: z.string().optional(),
1153
+ y: z.boolean().optional(),
1154
+ yes: z.boolean().optional()
492
1155
  }).parse(opts);
493
1156
  const cwd = path.resolve(options.cwd);
494
1157
  if (!existsSync(cwd)) {
@@ -1764,7 +2427,7 @@ const tempPluginsConfig = {
1764
2427
  argument: {
1765
2428
  index: 0,
1766
2429
  isProperty: "issuer",
1767
- schema: z$1.coerce.string().optional()
2430
+ schema: z.coerce.string().optional()
1768
2431
  }
1769
2432
  },
1770
2433
  {
@@ -1776,7 +2439,7 @@ const tempPluginsConfig = {
1776
2439
  argument: {
1777
2440
  index: 0,
1778
2441
  isProperty: "skipVerificationOnEnable",
1779
- schema: z$1.coerce.boolean().optional()
2442
+ schema: z.coerce.boolean().optional()
1780
2443
  }
1781
2444
  },
1782
2445
  {
@@ -1793,7 +2456,7 @@ const tempPluginsConfig = {
1793
2456
  argument: {
1794
2457
  index: 0,
1795
2458
  isProperty: "digits",
1796
- schema: z$1.coerce.number().positive().optional()
2459
+ schema: z.coerce.number().positive().optional()
1797
2460
  }
1798
2461
  }, {
1799
2462
  flag: "totp-otp-period",
@@ -1804,7 +2467,7 @@ const tempPluginsConfig = {
1804
2467
  argument: {
1805
2468
  index: 0,
1806
2469
  isProperty: "period",
1807
- schema: z$1.coerce.number().positive().optional()
2470
+ schema: z.coerce.number().positive().optional()
1808
2471
  }
1809
2472
  }],
1810
2473
  argument: {
@@ -1826,7 +2489,7 @@ const tempPluginsConfig = {
1826
2489
  argument: {
1827
2490
  index: 0,
1828
2491
  isProperty: "period",
1829
- schema: z$1.coerce.number().positive().optional()
2492
+ schema: z.coerce.number().positive().optional()
1830
2493
  }
1831
2494
  }, {
1832
2495
  flag: "otp-store-otp",
@@ -1851,7 +2514,7 @@ const tempPluginsConfig = {
1851
2514
  argument: {
1852
2515
  index: 0,
1853
2516
  isProperty: "storeOTP",
1854
- schema: z$1.enum([
2517
+ schema: z.enum([
1855
2518
  "plain",
1856
2519
  "encrypted",
1857
2520
  "hashed"
@@ -1876,7 +2539,7 @@ const tempPluginsConfig = {
1876
2539
  argument: {
1877
2540
  index: 0,
1878
2541
  isProperty: "amount",
1879
- schema: z$1.coerce.number().positive().optional()
2542
+ schema: z.coerce.number().positive().optional()
1880
2543
  }
1881
2544
  }, {
1882
2545
  flag: "backup-code-length",
@@ -1887,7 +2550,7 @@ const tempPluginsConfig = {
1887
2550
  argument: {
1888
2551
  index: 0,
1889
2552
  isProperty: "length",
1890
- schema: z$1.coerce.number().positive().optional()
2553
+ schema: z.coerce.number().positive().optional()
1891
2554
  }
1892
2555
  }],
1893
2556
  argument: {
@@ -1912,7 +2575,7 @@ const tempPluginsConfig = {
1912
2575
  argument: {
1913
2576
  index: 0,
1914
2577
  isProperty: "twoFactorTable",
1915
- schema: z$1.coerce.string().optional()
2578
+ schema: z.coerce.string().optional()
1916
2579
  }
1917
2580
  }]
1918
2581
  }
@@ -1946,7 +2609,7 @@ const tempPluginsConfig = {
1946
2609
  argument: {
1947
2610
  index: 0,
1948
2611
  isProperty: "maxUsernameLength",
1949
- schema: z$1.coerce.number().min(0).positive().optional()
2612
+ schema: z.coerce.number().min(0).positive().optional()
1950
2613
  }
1951
2614
  },
1952
2615
  {
@@ -1958,7 +2621,7 @@ const tempPluginsConfig = {
1958
2621
  argument: {
1959
2622
  index: 0,
1960
2623
  isProperty: "minUsernameLength",
1961
- schema: z$1.coerce.number().min(0).positive().optional()
2624
+ schema: z.coerce.number().min(0).positive().optional()
1962
2625
  }
1963
2626
  },
1964
2627
  {
@@ -1981,7 +2644,7 @@ const tempPluginsConfig = {
1981
2644
  argument: {
1982
2645
  index: 0,
1983
2646
  isProperty: "username",
1984
- schema: z$1.enum(["pre-normalization", "post-normalization"]).optional()
2647
+ schema: z.enum(["pre-normalization", "post-normalization"]).optional()
1985
2648
  }
1986
2649
  }, {
1987
2650
  flag: "username-validation-order-display-username",
@@ -1999,7 +2662,7 @@ const tempPluginsConfig = {
1999
2662
  argument: {
2000
2663
  index: 0,
2001
2664
  isProperty: "displayUsername",
2002
- schema: z$1.enum(["pre-normalization", "post-normalization"]).optional()
2665
+ schema: z.enum(["pre-normalization", "post-normalization"]).optional()
2003
2666
  }
2004
2667
  }],
2005
2668
  argument: {
@@ -2038,7 +2701,7 @@ const tempPluginsConfig = {
2038
2701
  argument: {
2039
2702
  index: 0,
2040
2703
  isProperty: "expiresIn",
2041
- schema: z$1.coerce.number().optional()
2704
+ schema: z.coerce.number().optional()
2042
2705
  }
2043
2706
  },
2044
2707
  {
@@ -2053,7 +2716,7 @@ const tempPluginsConfig = {
2053
2716
  argument: {
2054
2717
  index: 0,
2055
2718
  isProperty: "sendMagicLink",
2056
- schema: z$1.coerce.string()
2719
+ schema: z.coerce.string()
2057
2720
  }
2058
2721
  },
2059
2722
  {
@@ -2070,7 +2733,7 @@ const tempPluginsConfig = {
2070
2733
  argument: {
2071
2734
  index: 0,
2072
2735
  isProperty: "window",
2073
- schema: z$1.coerce.number().optional()
2736
+ schema: z.coerce.number().optional()
2074
2737
  }
2075
2738
  }, {
2076
2739
  flag: "magic-link-rate-limit-max",
@@ -2082,7 +2745,7 @@ const tempPluginsConfig = {
2082
2745
  argument: {
2083
2746
  index: 0,
2084
2747
  isProperty: "max",
2085
- schema: z$1.coerce.number().optional()
2748
+ schema: z.coerce.number().optional()
2086
2749
  }
2087
2750
  }],
2088
2751
  argument: {
@@ -2106,7 +2769,7 @@ const tempPluginsConfig = {
2106
2769
  argument: {
2107
2770
  index: 0,
2108
2771
  isProperty: "storeToken",
2109
- schema: z$1.enum(["plain", "hashed"]).optional()
2772
+ schema: z.enum(["plain", "hashed"]).optional()
2110
2773
  }
2111
2774
  }
2112
2775
  ]
@@ -2142,7 +2805,7 @@ const tempPluginsConfig = {
2142
2805
  argument: {
2143
2806
  index: 0,
2144
2807
  isProperty: "sendVerificationOTP",
2145
- schema: z$1.coerce.string()
2808
+ schema: z.coerce.string()
2146
2809
  }
2147
2810
  },
2148
2811
  {
@@ -2155,7 +2818,7 @@ const tempPluginsConfig = {
2155
2818
  argument: {
2156
2819
  index: 0,
2157
2820
  isProperty: "otpLength",
2158
- schema: z$1.coerce.number().optional()
2821
+ schema: z.coerce.number().optional()
2159
2822
  }
2160
2823
  },
2161
2824
  {
@@ -2168,7 +2831,7 @@ const tempPluginsConfig = {
2168
2831
  argument: {
2169
2832
  index: 0,
2170
2833
  isProperty: "expiresIn",
2171
- schema: z$1.coerce.number().optional()
2834
+ schema: z.coerce.number().optional()
2172
2835
  }
2173
2836
  },
2174
2837
  {
@@ -2181,7 +2844,7 @@ const tempPluginsConfig = {
2181
2844
  argument: {
2182
2845
  index: 0,
2183
2846
  isProperty: "sendVerificationOnSignUp",
2184
- schema: z$1.coerce.boolean().optional()
2847
+ schema: z.coerce.boolean().optional()
2185
2848
  }
2186
2849
  },
2187
2850
  {
@@ -2194,7 +2857,7 @@ const tempPluginsConfig = {
2194
2857
  argument: {
2195
2858
  index: 0,
2196
2859
  isProperty: "disableSignUp",
2197
- schema: z$1.coerce.boolean().optional()
2860
+ schema: z.coerce.boolean().optional()
2198
2861
  }
2199
2862
  },
2200
2863
  {
@@ -2207,7 +2870,7 @@ const tempPluginsConfig = {
2207
2870
  argument: {
2208
2871
  index: 0,
2209
2872
  isProperty: "allowedAttempts",
2210
- schema: z$1.coerce.number().optional()
2873
+ schema: z.coerce.number().optional()
2211
2874
  }
2212
2875
  },
2213
2876
  {
@@ -2233,7 +2896,7 @@ const tempPluginsConfig = {
2233
2896
  argument: {
2234
2897
  index: 0,
2235
2898
  isProperty: "storeOTP",
2236
- schema: z$1.enum([
2899
+ schema: z.enum([
2237
2900
  "plain",
2238
2901
  "encrypted",
2239
2902
  "hashed"
@@ -2250,7 +2913,7 @@ const tempPluginsConfig = {
2250
2913
  argument: {
2251
2914
  index: 0,
2252
2915
  isProperty: "overrideDefaultEmailVerification",
2253
- schema: z$1.coerce.boolean().optional()
2916
+ schema: z.coerce.boolean().optional()
2254
2917
  }
2255
2918
  }
2256
2919
  ]
@@ -2377,7 +3040,7 @@ const tempPluginsConfig = {
2377
3040
  argument: {
2378
3041
  index: 0,
2379
3042
  isProperty: "defaultRole",
2380
- schema: z$1.coerce.string().optional()
3043
+ schema: z.coerce.string().optional()
2381
3044
  }
2382
3045
  }, {
2383
3046
  flag: "admin-roles",
@@ -2388,7 +3051,7 @@ const tempPluginsConfig = {
2388
3051
  argument: {
2389
3052
  index: 0,
2390
3053
  isProperty: "adminRoles",
2391
- schema: z$1.array(z$1.string()).optional()
3054
+ schema: z.array(z.string()).optional()
2392
3055
  }
2393
3056
  }]
2394
3057
  },
@@ -2420,7 +3083,7 @@ const tempPluginsConfig = {
2420
3083
  argument: {
2421
3084
  index: 0,
2422
3085
  isProperty: "apiKeyHeaders",
2423
- schema: z$1.coerce.string().optional()
3086
+ schema: z.coerce.string().optional()
2424
3087
  }
2425
3088
  },
2426
3089
  {
@@ -2433,7 +3096,7 @@ const tempPluginsConfig = {
2433
3096
  argument: {
2434
3097
  index: 0,
2435
3098
  isProperty: "defaultKeyLength",
2436
- schema: z$1.coerce.number().positive().optional()
3099
+ schema: z.coerce.number().positive().optional()
2437
3100
  }
2438
3101
  },
2439
3102
  {
@@ -2445,7 +3108,7 @@ const tempPluginsConfig = {
2445
3108
  argument: {
2446
3109
  index: 0,
2447
3110
  isProperty: "disableKeyHashing",
2448
- schema: z$1.coerce.boolean().optional()
3111
+ schema: z.coerce.boolean().optional()
2449
3112
  }
2450
3113
  },
2451
3114
  {
@@ -2457,7 +3120,7 @@ const tempPluginsConfig = {
2457
3120
  argument: {
2458
3121
  index: 0,
2459
3122
  isProperty: "enableMetadata",
2460
- schema: z$1.coerce.boolean().optional()
3123
+ schema: z.coerce.boolean().optional()
2461
3124
  }
2462
3125
  },
2463
3126
  {
@@ -2469,7 +3132,7 @@ const tempPluginsConfig = {
2469
3132
  argument: {
2470
3133
  index: 0,
2471
3134
  isProperty: "enableSessionForAPIKeys",
2472
- schema: z$1.coerce.boolean().optional()
3135
+ schema: z.coerce.boolean().optional()
2473
3136
  }
2474
3137
  }
2475
3138
  ]
@@ -2501,7 +3164,7 @@ const tempPluginsConfig = {
2501
3164
  argument: {
2502
3165
  index: 0,
2503
3166
  isProperty: "requireSignature",
2504
- schema: z$1.coerce.boolean().optional()
3167
+ schema: z.coerce.boolean().optional()
2505
3168
  }
2506
3169
  }]
2507
3170
  },
@@ -2542,7 +3205,7 @@ const tempPluginsConfig = {
2542
3205
  argument: {
2543
3206
  index: 0,
2544
3207
  isProperty: "provider",
2545
- schema: z$1.enum([
3208
+ schema: z.enum([
2546
3209
  "google-recaptcha",
2547
3210
  "cloudflare-turnstile",
2548
3211
  "hcaptcha",
@@ -2557,7 +3220,7 @@ const tempPluginsConfig = {
2557
3220
  argument: {
2558
3221
  index: 0,
2559
3222
  isProperty: "secretKey",
2560
- schema: z$1.coerce.string()
3223
+ schema: z.coerce.string()
2561
3224
  }
2562
3225
  },
2563
3226
  {
@@ -2568,7 +3231,7 @@ const tempPluginsConfig = {
2568
3231
  argument: {
2569
3232
  index: 0,
2570
3233
  isProperty: "siteKey",
2571
- schema: z$1.coerce.string().optional()
3234
+ schema: z.coerce.string().optional()
2572
3235
  }
2573
3236
  },
2574
3237
  {
@@ -2581,7 +3244,7 @@ const tempPluginsConfig = {
2581
3244
  argument: {
2582
3245
  index: 0,
2583
3246
  isProperty: "minScore",
2584
- schema: z$1.coerce.number().min(0).max(1).optional()
3247
+ schema: z.coerce.number().min(0).max(1).optional()
2585
3248
  }
2586
3249
  }
2587
3250
  ]
@@ -2606,7 +3269,7 @@ const tempPluginsConfig = {
2606
3269
  argument: {
2607
3270
  index: 0,
2608
3271
  isProperty: "shouldMutateListDeviceSessionsEndpoint",
2609
- schema: z$1.coerce.boolean().optional()
3272
+ schema: z.coerce.boolean().optional()
2610
3273
  }
2611
3274
  }]
2612
3275
  },
@@ -2638,7 +3301,7 @@ const tempPluginsConfig = {
2638
3301
  argument: {
2639
3302
  index: 0,
2640
3303
  isProperty: "expiresIn",
2641
- schema: z$1.coerce.string().optional()
3304
+ schema: z.coerce.string().optional()
2642
3305
  }
2643
3306
  },
2644
3307
  {
@@ -2650,7 +3313,7 @@ const tempPluginsConfig = {
2650
3313
  argument: {
2651
3314
  index: 0,
2652
3315
  isProperty: "interval",
2653
- schema: z$1.coerce.string().optional()
3316
+ schema: z.coerce.string().optional()
2654
3317
  }
2655
3318
  },
2656
3319
  {
@@ -2663,7 +3326,7 @@ const tempPluginsConfig = {
2663
3326
  argument: {
2664
3327
  index: 0,
2665
3328
  isProperty: "deviceCodeLength",
2666
- schema: z$1.coerce.number().positive().optional()
3329
+ schema: z.coerce.number().positive().optional()
2667
3330
  }
2668
3331
  },
2669
3332
  {
@@ -2676,7 +3339,7 @@ const tempPluginsConfig = {
2676
3339
  argument: {
2677
3340
  index: 0,
2678
3341
  isProperty: "userCodeLength",
2679
- schema: z$1.coerce.number().positive().optional()
3342
+ schema: z.coerce.number().positive().optional()
2680
3343
  }
2681
3344
  }
2682
3345
  ]
@@ -2707,7 +3370,7 @@ const tempPluginsConfig = {
2707
3370
  argument: {
2708
3371
  index: 0,
2709
3372
  isProperty: "customPasswordCompromisedMessage",
2710
- schema: z$1.coerce.string().optional()
3373
+ schema: z.coerce.string().optional()
2711
3374
  }
2712
3375
  }]
2713
3376
  },
@@ -2731,7 +3394,7 @@ const tempPluginsConfig = {
2731
3394
  argument: {
2732
3395
  index: 0,
2733
3396
  isProperty: "disableSettingJwtHeader",
2734
- schema: z$1.coerce.boolean().optional()
3397
+ schema: z.coerce.boolean().optional()
2735
3398
  }
2736
3399
  }]
2737
3400
  },
@@ -2763,7 +3426,7 @@ const tempPluginsConfig = {
2763
3426
  argument: {
2764
3427
  index: 0,
2765
3428
  isProperty: "cookieName",
2766
- schema: z$1.coerce.string().optional()
3429
+ schema: z.coerce.string().optional()
2767
3430
  }
2768
3431
  },
2769
3432
  {
@@ -2776,7 +3439,7 @@ const tempPluginsConfig = {
2776
3439
  argument: {
2777
3440
  index: 0,
2778
3441
  isProperty: "maxAge",
2779
- schema: z$1.coerce.number().positive().optional()
3442
+ schema: z.coerce.number().positive().optional()
2780
3443
  }
2781
3444
  },
2782
3445
  {
@@ -2788,7 +3451,7 @@ const tempPluginsConfig = {
2788
3451
  argument: {
2789
3452
  index: 0,
2790
3453
  isProperty: "storeInDatabase",
2791
- schema: z$1.coerce.boolean().optional()
3454
+ schema: z.coerce.boolean().optional()
2792
3455
  }
2793
3456
  }
2794
3457
  ]
@@ -2818,7 +3481,7 @@ const tempPluginsConfig = {
2818
3481
  argument: {
2819
3482
  index: 0,
2820
3483
  isProperty: "loginPage",
2821
- schema: z$1.coerce.string()
3484
+ schema: z.coerce.string()
2822
3485
  }
2823
3486
  }, {
2824
3487
  flag: "mcp-resource",
@@ -2828,7 +3491,7 @@ const tempPluginsConfig = {
2828
3491
  argument: {
2829
3492
  index: 0,
2830
3493
  isProperty: "resource",
2831
- schema: z$1.coerce.string().optional()
3494
+ schema: z.coerce.string().optional()
2832
3495
  }
2833
3496
  }]
2834
3497
  },
@@ -2853,7 +3516,7 @@ const tempPluginsConfig = {
2853
3516
  argument: {
2854
3517
  index: 0,
2855
3518
  isProperty: "maximumSessions",
2856
- schema: z$1.coerce.number().positive().optional()
3519
+ schema: z.coerce.number().positive().optional()
2857
3520
  }
2858
3521
  }]
2859
3522
  },
@@ -2883,7 +3546,7 @@ const tempPluginsConfig = {
2883
3546
  argument: {
2884
3547
  index: 0,
2885
3548
  isProperty: "currentURL",
2886
- schema: z$1.coerce.string().optional()
3549
+ schema: z.coerce.string().optional()
2887
3550
  }
2888
3551
  }, {
2889
3552
  flag: "oauth-proxy-production-url",
@@ -2893,7 +3556,7 @@ const tempPluginsConfig = {
2893
3556
  argument: {
2894
3557
  index: 0,
2895
3558
  isProperty: "productionURL",
2896
- schema: z$1.coerce.string().optional()
3559
+ schema: z.coerce.string().optional()
2897
3560
  }
2898
3561
  }]
2899
3562
  },
@@ -2917,7 +3580,7 @@ const tempPluginsConfig = {
2917
3580
  argument: {
2918
3581
  index: 0,
2919
3582
  isProperty: "disableSignup",
2920
- schema: z$1.coerce.boolean().optional()
3583
+ schema: z.coerce.boolean().optional()
2921
3584
  }
2922
3585
  }, {
2923
3586
  flag: "one-tap-client-id",
@@ -2927,7 +3590,7 @@ const tempPluginsConfig = {
2927
3590
  argument: {
2928
3591
  index: 0,
2929
3592
  isProperty: "clientId",
2930
- schema: z$1.coerce.string().optional()
3593
+ schema: z.coerce.string().optional()
2931
3594
  }
2932
3595
  }]
2933
3596
  },
@@ -2960,7 +3623,7 @@ const tempPluginsConfig = {
2960
3623
  argument: {
2961
3624
  index: 0,
2962
3625
  isProperty: "expiresIn",
2963
- schema: z$1.coerce.number().positive().optional()
3626
+ schema: z.coerce.number().positive().optional()
2964
3627
  }
2965
3628
  },
2966
3629
  {
@@ -2972,7 +3635,7 @@ const tempPluginsConfig = {
2972
3635
  argument: {
2973
3636
  index: 0,
2974
3637
  isProperty: "disableClientRequest",
2975
- schema: z$1.coerce.boolean().optional()
3638
+ schema: z.coerce.boolean().optional()
2976
3639
  }
2977
3640
  },
2978
3641
  {
@@ -2991,7 +3654,7 @@ const tempPluginsConfig = {
2991
3654
  argument: {
2992
3655
  index: 0,
2993
3656
  isProperty: "storeToken",
2994
- schema: z$1.enum(["plain", "hashed"]).optional()
3657
+ schema: z.enum(["plain", "hashed"]).optional()
2995
3658
  }
2996
3659
  }
2997
3660
  ]
@@ -3024,7 +3687,7 @@ const tempPluginsConfig = {
3024
3687
  argument: {
3025
3688
  index: 0,
3026
3689
  isProperty: "path",
3027
- schema: z$1.coerce.string().optional()
3690
+ schema: z.coerce.string().optional()
3028
3691
  }
3029
3692
  },
3030
3693
  {
@@ -3036,7 +3699,7 @@ const tempPluginsConfig = {
3036
3699
  argument: {
3037
3700
  index: 0,
3038
3701
  isProperty: "disableDefaultReference",
3039
- schema: z$1.coerce.boolean().optional()
3702
+ schema: z.coerce.boolean().optional()
3040
3703
  }
3041
3704
  },
3042
3705
  {
@@ -3098,7 +3761,7 @@ const tempPluginsConfig = {
3098
3761
  argument: {
3099
3762
  index: 0,
3100
3763
  isProperty: "theme",
3101
- schema: z$1.enum([
3764
+ schema: z.enum([
3102
3765
  "alternate",
3103
3766
  "default",
3104
3767
  "moon",
@@ -3137,7 +3800,7 @@ const tempPluginsConfig = {
3137
3800
  argument: {
3138
3801
  index: 0,
3139
3802
  isProperty: "allowUserToCreateOrganization",
3140
- schema: z$1.coerce.boolean().optional()
3803
+ schema: z.coerce.boolean().optional()
3141
3804
  }
3142
3805
  },
3143
3806
  {
@@ -3149,7 +3812,7 @@ const tempPluginsConfig = {
3149
3812
  argument: {
3150
3813
  index: 0,
3151
3814
  isProperty: "creatorRole",
3152
- schema: z$1.coerce.string().optional()
3815
+ schema: z.coerce.string().optional()
3153
3816
  }
3154
3817
  },
3155
3818
  {
@@ -3162,7 +3825,7 @@ const tempPluginsConfig = {
3162
3825
  argument: {
3163
3826
  index: 0,
3164
3827
  isProperty: "membershipLimit",
3165
- schema: z$1.coerce.number().positive().optional()
3828
+ schema: z.coerce.number().positive().optional()
3166
3829
  }
3167
3830
  }
3168
3831
  ]
@@ -3193,7 +3856,7 @@ const tempPluginsConfig = {
3193
3856
  argument: {
3194
3857
  index: 0,
3195
3858
  isProperty: "domain",
3196
- schema: z$1.coerce.string()
3859
+ schema: z.coerce.string()
3197
3860
  }
3198
3861
  },
3199
3862
  {
@@ -3204,7 +3867,7 @@ const tempPluginsConfig = {
3204
3867
  argument: {
3205
3868
  index: 0,
3206
3869
  isProperty: "emailDomainName",
3207
- schema: z$1.coerce.string().optional()
3870
+ schema: z.coerce.string().optional()
3208
3871
  }
3209
3872
  },
3210
3873
  {
@@ -3216,7 +3879,7 @@ const tempPluginsConfig = {
3216
3879
  argument: {
3217
3880
  index: 0,
3218
3881
  isProperty: "anonymous",
3219
- schema: z$1.coerce.boolean().optional()
3882
+ schema: z.coerce.boolean().optional()
3220
3883
  }
3221
3884
  }
3222
3885
  ]
@@ -3271,7 +3934,7 @@ const tempPluginsConfig = {
3271
3934
  argument: {
3272
3935
  index: 0,
3273
3936
  isProperty: "defaultOverrideUserInfo",
3274
- schema: z$1.coerce.boolean().optional()
3937
+ schema: z.coerce.boolean().optional()
3275
3938
  }
3276
3939
  },
3277
3940
  {
@@ -3284,7 +3947,7 @@ const tempPluginsConfig = {
3284
3947
  argument: {
3285
3948
  index: 0,
3286
3949
  isProperty: "disableImplicitSignUp",
3287
- schema: z$1.coerce.boolean().optional()
3950
+ schema: z.coerce.boolean().optional()
3288
3951
  }
3289
3952
  },
3290
3953
  {
@@ -3298,7 +3961,7 @@ const tempPluginsConfig = {
3298
3961
  argument: {
3299
3962
  index: 0,
3300
3963
  isProperty: "providersLimit",
3301
- schema: z$1.coerce.number().int().positive().optional()
3964
+ schema: z.coerce.number().int().positive().optional()
3302
3965
  }
3303
3966
  },
3304
3967
  {
@@ -3311,7 +3974,7 @@ const tempPluginsConfig = {
3311
3974
  argument: {
3312
3975
  index: 0,
3313
3976
  isProperty: "trustEmailVerified",
3314
- schema: z$1.coerce.boolean().optional()
3977
+ schema: z.coerce.boolean().optional()
3315
3978
  }
3316
3979
  },
3317
3980
  {
@@ -3322,7 +3985,7 @@ const tempPluginsConfig = {
3322
3985
  argument: {
3323
3986
  index: 0,
3324
3987
  isProperty: "domainVerification",
3325
- schema: z$1.object({ enabled: z$1.coerce.boolean().optional() }).optional()
3988
+ schema: z.object({ enabled: z.coerce.boolean().optional() }).optional()
3326
3989
  },
3327
3990
  isNestedObject: [{
3328
3991
  flag: "sso-domain-verification-enabled",
@@ -3334,7 +3997,7 @@ const tempPluginsConfig = {
3334
3997
  argument: {
3335
3998
  index: 0,
3336
3999
  isProperty: "enabled",
3337
- schema: z$1.coerce.boolean().optional()
4000
+ schema: z.coerce.boolean().optional()
3338
4001
  }
3339
4002
  }]
3340
4003
  }
@@ -3355,7 +4018,7 @@ const tempPluginsConfig = {
3355
4018
  argument: {
3356
4019
  index: 0,
3357
4020
  isProperty: "domainVerification",
3358
- schema: z$1.object({ enabled: z$1.coerce.boolean().optional() }).optional()
4021
+ schema: z.object({ enabled: z.coerce.boolean().optional() }).optional()
3359
4022
  },
3360
4023
  isNestedObject: [{
3361
4024
  flag: "sso-client-domain-verification-enabled",
@@ -3367,7 +4030,7 @@ const tempPluginsConfig = {
3367
4030
  argument: {
3368
4031
  index: 0,
3369
4032
  isProperty: "enabled",
3370
- schema: z$1.coerce.boolean().optional()
4033
+ schema: z.coerce.boolean().optional()
3371
4034
  }
3372
4035
  }]
3373
4036
  }]
@@ -5345,7 +6008,7 @@ export const auth = betterAuth({
5345
6008
  return;
5346
6009
  }
5347
6010
  if (connectResponse.connect) {
5348
- await open("https://beta.better-auth.com/onboarding");
6011
+ await open("https://better-auth.com/onboarding");
5349
6012
  console.log(chalk.cyan("\n→ ") + "Opening Better Auth onboarding in your browser...\n");
5350
6013
  }
5351
6014
  console.log(chalk.green(`\n✔ `) + chalk.bold("Success! ") + "Project setup complete.\n");
@@ -5583,11 +6246,11 @@ const mcp = new Command("mcp").description("Add Better Auth MCP server to MCP Cl
5583
6246
  //#region src/commands/migrate.ts
5584
6247
  /** @internal */
5585
6248
  async function migrateAction(opts) {
5586
- const options = z$1.object({
5587
- cwd: z$1.string(),
5588
- config: z$1.string().optional(),
5589
- y: z$1.boolean().optional(),
5590
- yes: z$1.boolean().optional()
6249
+ const options = z.object({
6250
+ cwd: z.string(),
6251
+ config: z.string().optional(),
6252
+ y: z.boolean().optional(),
6253
+ yes: z.boolean().optional()
5591
6254
  }).parse(opts);
5592
6255
  const cwd = path.resolve(options.cwd);
5593
6256
  if (!existsSync(cwd)) {
@@ -5739,9 +6402,9 @@ function isBetterAuthPackage(name) {
5739
6402
  return name === "better-auth" || name.startsWith("@better-auth/");
5740
6403
  }
5741
6404
  async function upgradeAction(opts) {
5742
- const options = z$1.object({
5743
- cwd: z$1.string(),
5744
- yes: z$1.boolean().optional()
6405
+ const options = z.object({
6406
+ cwd: z.string(),
6407
+ yes: z.boolean().optional()
5745
6408
  }).parse(opts);
5746
6409
  const cwd = path.resolve(options.cwd);
5747
6410
  if (!existsSync(cwd)) {