docs: fix DatabaseTable type mapping and correct schema mismatches (#8611)

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Taesu <bytaesu@users.noreply.github.com>
This commit is contained in:
Taesu
2026-03-17 19:00:55 +09:00
committed by GitHub
parent 884e14a388
commit 6b921ed252
14 changed files with 148 additions and 117 deletions

View File

@@ -337,6 +337,7 @@ Table Name: `user`
name: "email",
type: "string",
description: "User's email address for communication and login",
isUnique: true,
},
{
name: "emailVerified",

View File

@@ -291,18 +291,19 @@ Table Name: `rateLimit`
isPrimaryKey: true
},
{
name: "key",
type: "string",
name: "key",
type: "string",
description: "Unique identifier for each rate limit key",
isUnique: true,
},
{
name: "count",
type: "integer",
description: "Time window in seconds"
name: "count",
type: "integer",
description: "Number of requests made in the current window"
},
{
name: "lastRequest",
type: "bigint",
description: "Max requests in the window"
{
name: "lastRequest",
type: "bigint",
description: "Timestamp of the last request (epoch ms)"
}]}
/>

View File

@@ -382,6 +382,7 @@ Just like Auth.js has database models, Better Auth also has a core schema. In th
name: "email",
type: "string",
description: "User's email address for communication and login",
isUnique: true,
},
{
name: "emailVerified",

View File

@@ -500,8 +500,8 @@ Table: `twoFactor`
fields={[
{ name: "id", type: "string", description: "The ID of the two factor authentication.", isPrimaryKey: true },
{ name: "userId", type: "string", description: "The ID of the user", isForeignKey: true },
{ name: "secret", type: "string", description: "The secret used to generate the TOTP code.", isOptional: true },
{ name: "backupCodes", type: "string", description: "The backup codes used to recover access to the account if the user loses access to their phone or email.", isOptional: true },
{ name: "secret", type: "string", description: "The secret used to generate the TOTP code." },
{ name: "backupCodes", type: "string", description: "The backup codes used to recover access to the account if the user loses access to their phone or email." },
]}
/>

View File

@@ -497,11 +497,13 @@ Table: `apikey`
name: "enabled",
type: "boolean",
description: "Whether the API key is enabled.",
isOptional: true,
},
{
name: "rateLimitEnabled",
type: "boolean",
description: "Whether the API key has rate limiting enabled.",
isOptional: true,
},
{
name: "rateLimitTimeWindow",
@@ -521,6 +523,7 @@ Table: `apikey`
type: "number",
description:
"The number of requests made within the rate limit time window.",
isOptional: true,
},
{
name: "remaining",
@@ -558,7 +561,7 @@ Table: `apikey`
},
{
name: "metadata",
type: "Object",
type: "string",
isOptional: true,
description: "Any additional metadata you want to store with the key.",
},

View File

@@ -611,12 +611,11 @@ Table Name: `deviceCode`
type: "string",
description: "The user-friendly code for verification",
},
{
name: "userId",
type: "string",
{
name: "userId",
type: "string",
description: "The ID of the user who approved/denied",
isOptional: true,
isForeignKey: true
isOptional: true
},
{
name: "clientId",
@@ -652,15 +651,5 @@ Table Name: `deviceCode`
description: "Minimum seconds between polls",
isOptional: true
},
{
name: "createdAt",
type: "Date",
description: "When the request was created",
},
{
name: "updatedAt",
type: "Date",
description: "When the request was last updated",
}
]}
/>

View File

@@ -1601,7 +1601,7 @@ Table Name: `oauthClient`
name: "clientId",
type: "string",
description: "Unique identifier for each OAuth client",
isPrimaryKey: true,
isUnique: true,
},
{
name: "clientSecret",
@@ -1652,17 +1652,18 @@ Table Name: `oauthClient`
type: "string",
description: "ID of the reference of the client owner if not a user. (optional)",
isOptional: true,
isForeignKey: true,
},
{
name: "createdAt",
type: "Date",
description: "Timestamp of when the OAuth client was created",
isOptional: true,
},
{
name: "updatedAt",
type: "Date",
description: "Timestamp of when the OAuth client was last updated",
isOptional: true,
},
{
name: "name",
@@ -1722,7 +1723,12 @@ Table Name: `oauthClient`
name: "redirectUris",
type: "string[]",
description: "Array of of redirect uris",
isRequired: true,
},
{
name: "postLogoutRedirectUris",
type: "string[]",
description: "Array of post-logout redirect URIs",
isOptional: true,
},
{
name: "tokenEndpointAuthMethod",
@@ -1754,6 +1760,12 @@ Table Name: `oauthClient`
description: "Type of OAuth client. Supports: ['web', 'native', 'user-agent-based']",
isOptional: true,
},
{
name: "requirePKCE",
type: "boolean",
description: "Whether PKCE is required for this client",
isOptional: true,
},
{
name: "metadata",
type: "json",
@@ -1779,14 +1791,12 @@ Table Name: `oauthRefreshToken`
name: "token",
type: "string",
description: "Hashed/encrypted refresh token",
isRequired: true,
},
{
name: "clientId",
type: "string",
description: "ID of the OAuth client",
isForeignKey: true,
isRequired: true,
references: { model: "oauthClient", field: "clientId" },
},
{
@@ -1794,7 +1804,7 @@ Table Name: `oauthRefreshToken`
type: "string",
description: "ID of the session used at issuance of the token (and still active)",
isForeignKey: true,
isRequired: false,
isOptional: true,
references: { model: "session", field: "id" },
},
{
@@ -1802,7 +1812,6 @@ Table Name: `oauthRefreshToken`
type: "string",
description: "ID of the user associated with the token",
isForeignKey: true,
isRequired: true,
references: { model: "user", field: "id" },
},
{
@@ -1810,13 +1819,11 @@ Table Name: `oauthRefreshToken`
type: "string",
description: "ID of the consented reference",
isOptional: true,
isForeignKey: true,
},
{
name: "scopes",
type: "string[]",
description: "Array of granted scopes",
isRequired: true,
},
{
name: "revoked",
@@ -1859,14 +1866,13 @@ Table Name: `oauthAccessToken`
name: "token",
type: "string",
description: "Hashed/encrypted access token",
isRequired: true,
isUnique: true,
},
{
name: "clientId",
type: "string",
description: "ID of the OAuth client",
isForeignKey: true,
isRequired: true,
references: { model: "oauthClient", field: "clientId" }
},
{
@@ -1898,18 +1904,16 @@ Table Name: `oauthAccessToken`
type: "string",
description: "ID of the consented reference",
isOptional: true,
isForeignKey: true,
},
{
name: "scopes",
type: "string[]",
description: "Array of granted scopes",
isRequired: true,
},
{
name: "createdAt",
type: "Date",
description: "Timestamp when the token was created"
description: "Timestamp when the token was created",
},
{
name: "expiresAt",
@@ -1950,23 +1954,21 @@ Table Name: `oauthConsent`
type: "string",
description: "ID of the consented reference",
isOptional: true,
isForeignKey: true,
},
{
name: "scopes",
type: "string",
description: "Comma-separated list of scopes consented to",
isRequired: true
type: "string[]",
description: "Array of scopes consented to",
},
{
name: "createdAt",
type: "Date",
description: "Timestamp of when the consent was given"
description: "Timestamp of when the consent was given",
},
{
name: "updatedAt",
type: "Date",
description: "Timestamp of when the consent was last updated"
description: "Timestamp of when the consent was last updated",
},
]}
/>

View File

@@ -453,11 +453,11 @@ Table Name: `oauthApplication`
description: "Database ID of the OAuth client",
isPrimaryKey: true
},
{
name: "clientId",
type: "string",
{
name: "clientId",
type: "string",
description: "Unique identifier for each OAuth client",
isPrimaryKey: true
isUnique: true
},
{
name: "clientSecret",
@@ -465,17 +465,21 @@ Table Name: `oauthApplication`
description: "Secret key for the OAuth client. Optional for public clients using PKCE.",
isOptional: true
},
{
name: "name",
type: "string",
description: "Name of the OAuth client",
isRequired: true
{
name: "icon",
type: "string",
description: "Icon of the OAuth client",
isOptional: true
},
{
name: "name",
type: "string",
description: "Name of the OAuth client"
},
{
name: "redirectUrls",
type: "string",
description: "Comma-separated list of redirect URLs",
isRequired: true
description: "Comma-separated list of redirect URLs"
},
{
name: "metadata",
@@ -486,26 +490,26 @@ Table Name: `oauthApplication`
{
name: "type",
type: "string",
description: "Type of OAuth client (e.g., web, mobile)",
isRequired: true
description: "Type of OAuth client (e.g., web, mobile)"
},
{
name: "disabled",
type: "boolean",
{
name: "disabled",
type: "boolean",
description: "Indicates if the client is disabled",
isRequired: true
isOptional: true
},
{
name: "userId",
type: "string",
name: "userId",
type: "string",
description: "ID of the user who owns the client. (optional)",
isOptional: true,
isForeignKey: true,
references: { model: "user", field: "id" }
},
{
name: "createdAt",
type: "Date",
description: "Timestamp of when the OAuth client was created"
{
name: "createdAt",
type: "Date",
description: "Timestamp of when the OAuth client was created"
},
{
name: "updatedAt",
@@ -528,27 +532,26 @@ Table Name: `oauthAccessToken`
isPrimaryKey: true
},
{
name: "accessToken",
type: "string",
name: "accessToken",
type: "string",
description: "Access token issued to the client",
isUnique: true
},
{
name: "refreshToken",
type: "string",
name: "refreshToken",
type: "string",
description: "Refresh token issued to the client",
isRequired: true
isUnique: true
},
{
name: "accessTokenExpiresAt",
type: "Date",
description: "Expiration date of the access token",
isRequired: true
description: "Expiration date of the access token"
},
{
name: "refreshTokenExpiresAt",
type: "Date",
description: "Expiration date of the refresh token",
isRequired: true
description: "Expiration date of the refresh token"
},
{
name: "clientId",
@@ -558,22 +561,22 @@ Table Name: `oauthAccessToken`
references: { model: "oauthApplication", field: "clientId" }
},
{
name: "userId",
type: "string",
name: "userId",
type: "string",
description: "ID of the user associated with the token",
isOptional: true,
isForeignKey: true,
references: { model: "user", field: "id" }
},
{
name: "scopes",
type: "string",
description: "Comma-separated list of scopes granted",
isRequired: true
description: "Comma-separated list of scopes granted"
},
{
name: "createdAt",
type: "Date",
description: "Timestamp of when the access token was created"
{
name: "createdAt",
type: "Date",
description: "Timestamp of when the access token was created"
},
{
name: "updatedAt",
@@ -612,19 +615,17 @@ Table Name: `oauthConsent`
{
name: "scopes",
type: "string",
description: "Comma-separated list of scopes consented to",
isRequired: true
description: "Comma-separated list of scopes consented to"
},
{
name: "consentGiven",
type: "boolean",
description: "Indicates if consent was given",
isRequired: true
description: "Indicates if consent was given"
},
{
name: "createdAt",
type: "Date",
description: "Timestamp of when the consent was given"
{
name: "createdAt",
type: "Date",
description: "Timestamp of when the consent was given"
},
{
name: "updatedAt",

View File

@@ -2138,6 +2138,7 @@ Table Name: `teamMember`
name: "createdAt",
type: "Date",
description: "Timestamp of when the team member was created",
isOptional: true,
},
]}
/>
@@ -2167,6 +2168,7 @@ Table Name: `organization`
name: "slug",
type: "string",
description: "The slug of the organization",
isUnique: true,
},
{
name: "logo",
@@ -2258,6 +2260,7 @@ Table Name: `invitation`
name: "role",
type: "string",
description: "The role of the user in the organization",
isOptional: true,
},
{
name: "status",
@@ -2349,6 +2352,7 @@ Table Name: `organizationRole`
name: "updatedAt",
type: "Date",
description: "Timestamp of when the organization role was updated",
isOptional: true,
},
]}
/>
@@ -2416,6 +2420,7 @@ Table Name: `teamMember`
name: "createdAt",
type: "Date",
description: "Timestamp of when the team member was created",
isOptional: true,
},
]}
/>

View File

@@ -455,11 +455,11 @@ The plugin requires additional fields in the `scimProvider` table to store the p
<DatabaseTable
fields={[
{
name: "id", type: "string", description: "A database identifier", isRequired: true, isPrimaryKey: true,
name: "id", type: "string", description: "A database identifier", isPrimaryKey: true,
},
{ name: "providerId", type: "string", description: "The provider ID. Used to identify a provider and to generate a redirect URL.", isRequired: true, isUnique: true },
{ name: "scimToken", type: "string", description: "The SCIM bearer token. Used by your identity provider to authenticate against your server", isRequired: true, isUnique: true },
{ name: "organizationId", type: "string", description: "The organization Id. If provider is linked to an organization.", isRequired: false },
{ name: "providerId", type: "string", description: "The provider ID. Used to identify a provider and to generate a redirect URL.", isUnique: true },
{ name: "scimToken", type: "string", description: "The SCIM bearer token. Used by your identity provider to authenticate against your server", isUnique: true },
{ name: "organizationId", type: "string", description: "The organization Id. If provider is linked to an organization.", isOptional: true },
]}
/>
@@ -469,7 +469,7 @@ The `scimProvider` schema is extended as follows:
<DatabaseTable
fields={[
{ name: "userId", type: "string", description: "The user id of the connection owner. Set automatically when generating a token via the API.", isRequired: false },
{ name: "userId", type: "string", description: "The user id of the connection owner. Set automatically when generating a token via the API.", isOptional: true },
]}
/>

View File

@@ -1406,15 +1406,15 @@ The plugin requires additional fields in the `ssoProvider` table to store the pr
<DatabaseTable
fields={[
{
name: "id", type: "string", description: "A database identifier", isRequired: true, isPrimaryKey: true,
name: "id", type: "string", description: "A database identifier", isPrimaryKey: true,
},
{ name: "issuer", type: "string", description: "The issuer identifier", isRequired: true },
{ name: "domain", type: "string", description: "The domain of the provider", isRequired: true },
{ name: "oidcConfig", type: "string", description: "The OIDC configuration (JSON string)", isRequired: false },
{ name: "samlConfig", type: "string", description: "The SAML configuration (JSON string)", isRequired: false },
{ name: "userId", type: "string", description: "The user ID", isRequired: true, references: { model: "user", field: "id" } },
{ name: "providerId", type: "string", description: "The provider ID. Used to identify a provider and to generate a redirect URL.", isRequired: true, isUnique: true },
{ name: "organizationId", type: "string", description: "The organization Id. If provider is linked to an organization.", isRequired: false }
{ name: "issuer", type: "string", description: "The issuer identifier" },
{ name: "domain", type: "string", description: "The domain of the provider" },
{ name: "oidcConfig", type: "string", description: "The OIDC configuration (JSON string)", isOptional: true },
{ name: "samlConfig", type: "string", description: "The SAML configuration (JSON string)", isOptional: true },
{ name: "userId", type: "string", description: "The user ID", isForeignKey: true },
{ name: "providerId", type: "string", description: "The provider ID. Used to identify a provider and to generate a redirect URL.", isUnique: true },
{ name: "organizationId", type: "string", description: "The organization Id. If provider is linked to an organization.", isOptional: true }
]}
/>
@@ -1424,7 +1424,7 @@ The `ssoProvider` schema is extended as follows:
<DatabaseTable
fields={[
{ name: "domainVerified", type: "boolean", description: "A flag indicating whether the provider domain has been verified.", isRequired: false },
{ name: "domainVerified", type: "boolean", description: "A flag indicating whether the provider domain has been verified.", isOptional: true },
]}
/>

View File

@@ -739,9 +739,9 @@ Table Name: `subscription`
description: "The Stripe subscription ID",
isOptional: true
},
{
name: "status",
type: "string",
{
name: "status",
type: "string",
description: "The status of the subscription (active, canceled, etc.)",
defaultValue: "incomplete"
},

View File

@@ -345,13 +345,14 @@ The plugin requires 2 fields to be added to the user table:
name: "username",
type: "string",
description: "The username of the user",
isUnique: true
isUnique: true,
isOptional: true
},
{
name: "displayUsername",
type: "string",
description: "Non normalized username of the user",
isUnique: true
isOptional: true
},
]}
/>

View File

@@ -95,10 +95,26 @@ interface Field {
isPrimaryKey?: boolean;
isForeignKey?: boolean;
isOptional?: boolean;
isUnique?: boolean;
}
const typeAliases: Record<string, string> = {
text: "string",
integer: "number",
int: "number",
bigint: "number",
float: "number",
double: "number",
decimal: "number",
bool: "boolean",
object: "json",
timestamp: "date",
datetime: "date",
};
function TypeIcon({ type }: { type: string }) {
const t = type.toLowerCase().replace("[]", "");
const raw = type.toLowerCase().replace("[]", "");
const t = typeAliases[raw] ?? raw;
const className = "size-3 shrink-0";
if (t === "string" || t === "text") {
@@ -202,7 +218,17 @@ type DrizzleProvider = "pg" | "mysql" | "sqlite";
function fieldToDBField(field: Field): DBFieldAttribute {
const t = field.type.toLowerCase();
const type = (t === "text" ? "string" : t) as DBFieldAttribute["type"];
const isArray = t.endsWith("[]");
const raw = isArray ? t.slice(0, -2) : t;
const aliased = typeAliases[raw] ?? raw;
const type = (
isArray && (aliased === "string" || aliased === "number")
? `${aliased}[]`
: isArray
? t
: aliased
) as DBFieldAttribute["type"];
const bigint = raw === "bigint";
let references: DBFieldAttribute["references"] | undefined;
if (field.isForeignKey && field.name.endsWith("Id")) {
@@ -218,7 +244,8 @@ function fieldToDBField(field: Field): DBFieldAttribute {
type,
required: field.isPrimaryKey ? true : !field.isOptional,
references,
unique: false,
unique: field.isUnique ?? false,
bigint,
};
}