auth 1.7.0-beta.8 → 1.7.0-rc.0

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.d.mts CHANGED
@@ -26,7 +26,7 @@ declare const generateSchema: (opts: {
26
26
  adapter: DBAdapter$1;
27
27
  file?: string;
28
28
  options: BetterAuthOptions;
29
- }) => Promise<SchemaGeneratorResult> | Promise<{
29
+ }) => Promise<SchemaGeneratorResult | {
30
30
  code: string;
31
31
  fileName: string;
32
32
  overwrite: boolean | undefined;
package/dist/api.mjs CHANGED
@@ -26,12 +26,22 @@ const generateDrizzleSchema = async ({ options, file, adapter }) => {
26
26
  schema: tables,
27
27
  usePlural: adapter.options?.adapterConfig?.usePlural
28
28
  });
29
+ const getSingularModelName = initGetModelName({
30
+ schema: tables,
31
+ usePlural: false
32
+ });
29
33
  const getFieldName = initGetFieldName({
30
34
  schema: tables,
31
35
  usePlural: adapter.options?.adapterConfig?.usePlural
32
36
  });
37
+ const isMigrationDisabled = (model) => Object.entries(tables).some(([tableKey, table]) => {
38
+ if (table.disableMigrations !== true) return false;
39
+ const customModelName = table.modelName || tableKey;
40
+ return model === tableKey || model === customModelName || model === getModelName(tableKey) || model === getModelName(customModelName);
41
+ });
33
42
  for (const tableKey in tables) {
34
43
  const table = tables[tableKey];
44
+ if (isMigrationDisabled(tableKey)) continue;
35
45
  const modelName = getModelName(tableKey);
36
46
  const fields = table.fields;
37
47
  function getType(name, field) {
@@ -51,9 +61,9 @@ const generateDrizzleSchema = async ({ options, file, adapter }) => {
51
61
  }
52
62
  const type = field.type;
53
63
  if (typeof type !== "string") if (Array.isArray(type) && type.every((x) => typeof x === "string")) return {
54
- sqlite: `text({ enum: [${type.map((x) => `'${x}'`).join(", ")}] })`,
64
+ sqlite: `text('${name}', { enum: [${type.map((x) => `'${x}'`).join(", ")}] })`,
55
65
  pg: `text('${name}', { enum: [${type.map((x) => `'${x}'`).join(", ")}] })`,
56
- mysql: `mysqlEnum([${type.map((x) => `'${x}'`).join(", ")}])`
66
+ mysql: `mysqlEnum('${name}', [${type.map((x) => `'${x}'`).join(", ")}])`
57
67
  }[databaseType];
58
68
  else throw new TypeError(`Invalid field type for field ${name} in model ${modelName}`);
59
69
  const dbTypeMap = {
@@ -141,7 +151,8 @@ const generateDrizzleSchema = async ({ options, file, adapter }) => {
141
151
  if (attr.onUpdate && attr.type === "date") {
142
152
  if (typeof attr.onUpdate === "function") type += `.$onUpdate(${attr.onUpdate})`;
143
153
  }
144
- return `${fieldName}: ${type}${attr.required !== false ? ".notNull()" : ""}${attr.unique ? ".unique()" : ""}${attr.references ? `.references(()=> ${getModelName(attr.references.model)}.${getFieldName({
154
+ const referencesDisabledModel = attr.references && isMigrationDisabled(attr.references.model);
155
+ return `${fieldName}: ${type}${attr.required !== false ? ".notNull()" : ""}${attr.unique ? ".unique()" : ""}${attr.references && !referencesDisabledModel ? `.references(()=> ${getModelName(attr.references.model)}.${getFieldName({
145
156
  model: attr.references.model,
146
157
  field: attr.references.field
147
158
  })}, { onDelete: '${attr.references.onDelete || "cascade"}' })` : ""}`;
@@ -152,6 +163,7 @@ const generateDrizzleSchema = async ({ options, file, adapter }) => {
152
163
  let relationsString = "";
153
164
  for (const tableKey in tables) {
154
165
  const table = tables[tableKey];
166
+ if (isMigrationDisabled(tableKey)) continue;
155
167
  const modelName = getModelName(tableKey);
156
168
  const oneRelations = [];
157
169
  const manyRelations = [];
@@ -159,7 +171,8 @@ const generateDrizzleSchema = async ({ options, file, adapter }) => {
159
171
  const foreignFields = Object.entries(table.fields).filter(([_, field]) => field.references);
160
172
  for (const [fieldName, field] of foreignFields) {
161
173
  const referencedModel = field.references.model;
162
- const relationKey = getModelName(referencedModel);
174
+ if (isMigrationDisabled(referencedModel)) continue;
175
+ const relationKey = getSingularModelName(referencedModel);
163
176
  const fieldRef = `${getModelName(tableKey)}.${getFieldName({
164
177
  model: tableKey,
165
178
  field: fieldName
@@ -179,7 +192,7 @@ const generateDrizzleSchema = async ({ options, file, adapter }) => {
179
192
  }
180
193
  });
181
194
  }
182
- const otherModels = Object.entries(tables).filter(([modelName]) => modelName !== tableKey);
195
+ const otherModels = Object.entries(tables).filter(([modelName, otherTable]) => modelName !== tableKey && !otherTable.disableMigrations);
183
196
  const modelRelationsMap = /* @__PURE__ */ new Map();
184
197
  for (const [modelName, otherTable] of otherModels) {
185
198
  const foreignKeysPointingHere = Object.entries(otherTable.fields).filter(([_, field]) => field.references?.model === tableKey || field.references?.model === getModelName(tableKey));
@@ -340,6 +353,11 @@ const generatePrismaSchema = async ({ adapter, options, file }) => {
340
353
  schema: getAuthTables(options),
341
354
  usePlural: false
342
355
  });
356
+ const isMigrationDisabled = (model) => Object.entries(tables).some(([tableKey, table]) => {
357
+ if (table.disableMigrations !== true) return false;
358
+ const customModelName = table.modelName || tableKey;
359
+ return model === tableKey || model === customModelName || model === getModelName(tableKey) || model === getModelName(customModelName);
360
+ });
343
361
  let schemaPrisma = "";
344
362
  if (schemaPrismaExist) schemaPrisma = await fs.readFile(path.join(process.cwd(), filePath), "utf-8");
345
363
  else schemaPrisma = getNewPrisma(provider, process.cwd());
@@ -358,11 +376,13 @@ const generatePrismaSchema = async ({ adapter, options, file }) => {
358
376
  });
359
377
  const manyToManyRelations = /* @__PURE__ */ new Map();
360
378
  for (const table in tables) {
379
+ if (isMigrationDisabled(table)) continue;
361
380
  const fields = tables[table]?.fields;
362
381
  for (const field in fields) {
363
382
  const attr = fields[field];
364
383
  if (attr.references) {
365
384
  const referencedOriginalModel = attr.references.model;
385
+ if (isMigrationDisabled(referencedOriginalModel)) continue;
366
386
  const referencedModelNameCap = capitalizeFirstLetter(getModelName(tables[referencedOriginalModel]?.modelName || referencedOriginalModel));
367
387
  if (!manyToManyRelations.has(referencedModelNameCap)) manyToManyRelations.set(referencedModelNameCap, /* @__PURE__ */ new Set());
368
388
  const currentModelNameCap = capitalizeFirstLetter(getModelName(tables[table]?.modelName || table));
@@ -385,6 +405,7 @@ const generatePrismaSchema = async ({ adapter, options, file }) => {
385
405
  }
386
406
  const schema = produceSchema(schemaPrisma, (builder) => {
387
407
  for (const table in tables) {
408
+ if (isMigrationDisabled(table)) continue;
388
409
  const originalTableName = table;
389
410
  const customModelName = tables[table]?.modelName || table;
390
411
  const modelName = capitalizeFirstLetter(getModelName(customModelName));
@@ -505,8 +526,9 @@ const generatePrismaSchema = async ({ adapter, options, file }) => {
505
526
  if (field === "updatedAt" && attr.onUpdate) fieldBuilder.attribute("updatedAt");
506
527
  else if (attr.onUpdate) {}
507
528
  if (attr.references) {
508
- if (useUUIDs && provider === "postgresql" && attr.references?.field === "id") builder.model(modelName).field(fieldName).attribute(`db.Uuid`);
509
529
  const referencedOriginalModelName = getModelName(attr.references.model);
530
+ if (isMigrationDisabled(referencedOriginalModelName) || isMigrationDisabled(attr.references.model)) continue;
531
+ if (useUUIDs && provider === "postgresql" && attr.references?.field === "id") builder.model(modelName).field(fieldName).attribute(`db.Uuid`);
510
532
  const referencedCustomModelName = tables[referencedOriginalModelName]?.modelName || referencedOriginalModelName;
511
533
  let action = "Cascade";
512
534
  if (attr.references.onDelete === "no action") action = "NoAction";
@@ -592,16 +614,16 @@ const adapters = {
592
614
  drizzle: generateDrizzleSchema,
593
615
  kysely: generateKyselySchema
594
616
  };
595
- const generateSchema = (opts) => {
617
+ const generateSchema = async (opts) => {
596
618
  const adapter = opts.adapter;
597
- const generator = adapter.id in adapters ? adapters[adapter.id] : null;
598
- if (generator) return generator(opts);
599
619
  if (adapter.createSchema) return adapter.createSchema(opts.options, opts.file).then(({ code, path: fileName, overwrite }) => ({
600
620
  code,
601
621
  fileName,
602
622
  overwrite
603
623
  }));
604
- throw new Error(`${adapter.id} is not supported. If it is a custom adapter, please request the maintainer to implement createSchema`);
624
+ const generator = adapters[adapter.id] ?? null;
625
+ if (generator) return await generator(opts);
626
+ throw new Error(`${adapter.id} is not supported. If it is a custom adapter, please request the maintainer to implement the "createSchema" method on the adapter.`);
605
627
  };
606
628
  //#endregion
607
629
  export { adapters, generateDrizzleSchema, generateKyselySchema, generatePrismaSchema, generateSchema };
package/dist/index.mjs CHANGED
@@ -1303,12 +1303,22 @@ const generateDrizzleSchema = async ({ options, file, adapter }) => {
1303
1303
  schema: tables,
1304
1304
  usePlural: adapter.options?.adapterConfig?.usePlural
1305
1305
  });
1306
+ const getSingularModelName = initGetModelName({
1307
+ schema: tables,
1308
+ usePlural: false
1309
+ });
1306
1310
  const getFieldName = initGetFieldName({
1307
1311
  schema: tables,
1308
1312
  usePlural: adapter.options?.adapterConfig?.usePlural
1309
1313
  });
1314
+ const isMigrationDisabled = (model) => Object.entries(tables).some(([tableKey, table]) => {
1315
+ if (table.disableMigrations !== true) return false;
1316
+ const customModelName = table.modelName || tableKey;
1317
+ return model === tableKey || model === customModelName || model === getModelName(tableKey) || model === getModelName(customModelName);
1318
+ });
1310
1319
  for (const tableKey in tables) {
1311
1320
  const table = tables[tableKey];
1321
+ if (isMigrationDisabled(tableKey)) continue;
1312
1322
  const modelName = getModelName(tableKey);
1313
1323
  const fields = table.fields;
1314
1324
  function getType(name, field) {
@@ -1328,9 +1338,9 @@ const generateDrizzleSchema = async ({ options, file, adapter }) => {
1328
1338
  }
1329
1339
  const type = field.type;
1330
1340
  if (typeof type !== "string") if (Array.isArray(type) && type.every((x) => typeof x === "string")) return {
1331
- sqlite: `text({ enum: [${type.map((x) => `'${x}'`).join(", ")}] })`,
1341
+ sqlite: `text('${name}', { enum: [${type.map((x) => `'${x}'`).join(", ")}] })`,
1332
1342
  pg: `text('${name}', { enum: [${type.map((x) => `'${x}'`).join(", ")}] })`,
1333
- mysql: `mysqlEnum([${type.map((x) => `'${x}'`).join(", ")}])`
1343
+ mysql: `mysqlEnum('${name}', [${type.map((x) => `'${x}'`).join(", ")}])`
1334
1344
  }[databaseType];
1335
1345
  else throw new TypeError(`Invalid field type for field ${name} in model ${modelName}`);
1336
1346
  const dbTypeMap = {
@@ -1418,7 +1428,8 @@ const generateDrizzleSchema = async ({ options, file, adapter }) => {
1418
1428
  if (attr.onUpdate && attr.type === "date") {
1419
1429
  if (typeof attr.onUpdate === "function") type += `.$onUpdate(${attr.onUpdate})`;
1420
1430
  }
1421
- return `${fieldName}: ${type}${attr.required !== false ? ".notNull()" : ""}${attr.unique ? ".unique()" : ""}${attr.references ? `.references(()=> ${getModelName(attr.references.model)}.${getFieldName({
1431
+ const referencesDisabledModel = attr.references && isMigrationDisabled(attr.references.model);
1432
+ return `${fieldName}: ${type}${attr.required !== false ? ".notNull()" : ""}${attr.unique ? ".unique()" : ""}${attr.references && !referencesDisabledModel ? `.references(()=> ${getModelName(attr.references.model)}.${getFieldName({
1422
1433
  model: attr.references.model,
1423
1434
  field: attr.references.field
1424
1435
  })}, { onDelete: '${attr.references.onDelete || "cascade"}' })` : ""}`;
@@ -1429,6 +1440,7 @@ const generateDrizzleSchema = async ({ options, file, adapter }) => {
1429
1440
  let relationsString = "";
1430
1441
  for (const tableKey in tables) {
1431
1442
  const table = tables[tableKey];
1443
+ if (isMigrationDisabled(tableKey)) continue;
1432
1444
  const modelName = getModelName(tableKey);
1433
1445
  const oneRelations = [];
1434
1446
  const manyRelations = [];
@@ -1436,7 +1448,8 @@ const generateDrizzleSchema = async ({ options, file, adapter }) => {
1436
1448
  const foreignFields = Object.entries(table.fields).filter(([_, field]) => field.references);
1437
1449
  for (const [fieldName, field] of foreignFields) {
1438
1450
  const referencedModel = field.references.model;
1439
- const relationKey = getModelName(referencedModel);
1451
+ if (isMigrationDisabled(referencedModel)) continue;
1452
+ const relationKey = getSingularModelName(referencedModel);
1440
1453
  const fieldRef = `${getModelName(tableKey)}.${getFieldName({
1441
1454
  model: tableKey,
1442
1455
  field: fieldName
@@ -1456,7 +1469,7 @@ const generateDrizzleSchema = async ({ options, file, adapter }) => {
1456
1469
  }
1457
1470
  });
1458
1471
  }
1459
- const otherModels = Object.entries(tables).filter(([modelName]) => modelName !== tableKey);
1472
+ const otherModels = Object.entries(tables).filter(([modelName, otherTable]) => modelName !== tableKey && !otherTable.disableMigrations);
1460
1473
  const modelRelationsMap = /* @__PURE__ */ new Map();
1461
1474
  for (const [modelName, otherTable] of otherModels) {
1462
1475
  const foreignKeysPointingHere = Object.entries(otherTable.fields).filter(([_, field]) => field.references?.model === tableKey || field.references?.model === getModelName(tableKey));
@@ -1601,7 +1614,7 @@ async function tryCatch(promise) {
1601
1614
  }
1602
1615
  }
1603
1616
  const generateSecretHash = () => {
1604
- return Crypto.randomBytes(16).toString("hex");
1617
+ return Crypto.randomBytes(32).toString("hex");
1605
1618
  };
1606
1619
  const spawnCommand = (cmd, cwd = process.cwd()) => new Promise((resolve, reject) => {
1607
1620
  const child = spawn(cmd, {
@@ -1702,6 +1715,11 @@ const generatePrismaSchema = async ({ adapter, options, file }) => {
1702
1715
  schema: getAuthTables(options),
1703
1716
  usePlural: false
1704
1717
  });
1718
+ const isMigrationDisabled = (model) => Object.entries(tables).some(([tableKey, table]) => {
1719
+ if (table.disableMigrations !== true) return false;
1720
+ const customModelName = table.modelName || tableKey;
1721
+ return model === tableKey || model === customModelName || model === getModelName(tableKey) || model === getModelName(customModelName);
1722
+ });
1705
1723
  let schemaPrisma = "";
1706
1724
  if (schemaPrismaExist) schemaPrisma = await fs$1.readFile(path.join(process.cwd(), filePath), "utf-8");
1707
1725
  else schemaPrisma = getNewPrisma(provider, process.cwd());
@@ -1720,11 +1738,13 @@ const generatePrismaSchema = async ({ adapter, options, file }) => {
1720
1738
  });
1721
1739
  const manyToManyRelations = /* @__PURE__ */ new Map();
1722
1740
  for (const table in tables) {
1741
+ if (isMigrationDisabled(table)) continue;
1723
1742
  const fields = tables[table]?.fields;
1724
1743
  for (const field in fields) {
1725
1744
  const attr = fields[field];
1726
1745
  if (attr.references) {
1727
1746
  const referencedOriginalModel = attr.references.model;
1747
+ if (isMigrationDisabled(referencedOriginalModel)) continue;
1728
1748
  const referencedModelNameCap = capitalizeFirstLetter(getModelName(tables[referencedOriginalModel]?.modelName || referencedOriginalModel));
1729
1749
  if (!manyToManyRelations.has(referencedModelNameCap)) manyToManyRelations.set(referencedModelNameCap, /* @__PURE__ */ new Set());
1730
1750
  const currentModelNameCap = capitalizeFirstLetter(getModelName(tables[table]?.modelName || table));
@@ -1747,6 +1767,7 @@ const generatePrismaSchema = async ({ adapter, options, file }) => {
1747
1767
  }
1748
1768
  const schema = produceSchema(schemaPrisma, (builder) => {
1749
1769
  for (const table in tables) {
1770
+ if (isMigrationDisabled(table)) continue;
1750
1771
  const originalTableName = table;
1751
1772
  const customModelName = tables[table]?.modelName || table;
1752
1773
  const modelName = capitalizeFirstLetter(getModelName(customModelName));
@@ -1867,8 +1888,9 @@ const generatePrismaSchema = async ({ adapter, options, file }) => {
1867
1888
  if (field === "updatedAt" && attr.onUpdate) fieldBuilder.attribute("updatedAt");
1868
1889
  else if (attr.onUpdate) {}
1869
1890
  if (attr.references) {
1870
- if (useUUIDs && provider === "postgresql" && attr.references?.field === "id") builder.model(modelName).field(fieldName).attribute(`db.Uuid`);
1871
1891
  const referencedOriginalModelName = getModelName(attr.references.model);
1892
+ if (isMigrationDisabled(referencedOriginalModelName) || isMigrationDisabled(attr.references.model)) continue;
1893
+ if (useUUIDs && provider === "postgresql" && attr.references?.field === "id") builder.model(modelName).field(fieldName).attribute(`db.Uuid`);
1872
1894
  const referencedCustomModelName = tables[referencedOriginalModelName]?.modelName || referencedOriginalModelName;
1873
1895
  let action = "Cascade";
1874
1896
  if (attr.references.onDelete === "no action") action = "NoAction";
@@ -1954,16 +1976,16 @@ const adapters = {
1954
1976
  drizzle: generateDrizzleSchema,
1955
1977
  kysely: generateKyselySchema
1956
1978
  };
1957
- const generateSchema = (opts) => {
1979
+ const generateSchema = async (opts) => {
1958
1980
  const adapter = opts.adapter;
1959
- const generator = adapter.id in adapters ? adapters[adapter.id] : null;
1960
- if (generator) return generator(opts);
1961
1981
  if (adapter.createSchema) return adapter.createSchema(opts.options, opts.file).then(({ code, path: fileName, overwrite }) => ({
1962
1982
  code,
1963
1983
  fileName,
1964
1984
  overwrite
1965
1985
  }));
1966
- throw new Error(`${adapter.id} is not supported. If it is a custom adapter, please request the maintainer to implement createSchema`);
1986
+ const generator = adapters[adapter.id] ?? null;
1987
+ if (generator) return await generator(opts);
1988
+ throw new Error(`${adapter.id} is not supported. If it is a custom adapter, please request the maintainer to implement the "createSchema" method on the adapter.`);
1967
1989
  };
1968
1990
  //#endregion
1969
1991
  //#region src/commands/generate.ts
package/package.json CHANGED
@@ -1,9 +1,12 @@
1
1
  {
2
2
  "name": "auth",
3
- "version": "1.7.0-beta.8",
3
+ "version": "1.7.0-rc.0",
4
4
  "description": "The CLI for Better Auth",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
+ "engines": {
8
+ "node": ">=22.12.0"
9
+ },
7
10
  "homepage": "https://www.better-auth.com/docs/concepts/cli",
8
11
  "repository": {
9
12
  "type": "git",
@@ -47,35 +50,35 @@
47
50
  "@babel/preset-react": "^7.28.5",
48
51
  "@babel/preset-typescript": "^7.28.5",
49
52
  "@better-auth/utils": "0.4.2",
50
- "@clack/prompts": "^0.11.0",
51
- "@mrleebo/prisma-ast": "^0.13.1",
53
+ "@clack/prompts": "^1.5.1",
54
+ "@mrleebo/prisma-ast": "^0.16.0",
52
55
  "c12": "^4.0.0-beta.5",
53
56
  "chalk": "^5.6.2",
54
- "commander": "^12.1.0",
57
+ "commander": "^15.0.0",
55
58
  "dotenv": "^17.3.1",
56
- "get-tsconfig": "^4.13.6",
59
+ "get-tsconfig": "^4.14.0",
57
60
  "jiti": "^2.7.0",
58
- "open": "^10.2.0",
61
+ "open": "^11.0.0",
59
62
  "prettier": "^3.8.1",
60
63
  "prompts": "^2.4.2",
61
- "semver": "^7.7.4",
62
- "yocto-spinner": "^0.2.3",
64
+ "semver": "^7.8.4",
65
+ "yocto-spinner": "^1.2.0",
63
66
  "zod": "^4.3.6",
64
- "@better-auth/core": "1.7.0-beta.8",
65
- "@better-auth/telemetry": "1.7.0-beta.8",
66
- "better-auth": "1.7.0-beta.8"
67
+ "@better-auth/core": "1.7.0-rc.0",
68
+ "@better-auth/telemetry": "1.7.0-rc.0",
69
+ "better-auth": "1.7.0-rc.0"
67
70
  },
68
71
  "devDependencies": {
69
72
  "@types/better-sqlite3": "^7.6.13",
70
73
  "@types/prompts": "^2.4.9",
71
74
  "@types/semver": "^7.7.1",
72
- "better-sqlite3": "^12.6.2",
75
+ "better-sqlite3": "^12.11.1",
73
76
  "memfs": "^4.56.10",
74
77
  "tsdown": "0.21.1",
75
78
  "tsx": "^4.21.0",
76
- "type-fest": "^5.4.4",
79
+ "type-fest": "^5.7.0",
77
80
  "typescript": "^5.9.3",
78
- "@better-auth/passkey": "1.7.0-beta.8"
81
+ "@better-auth/passkey": "1.7.0-rc.0"
79
82
  },
80
83
  "scripts": {
81
84
  "build": "tsdown",