fix(open-api): mark model ids as required (#9704)

This commit is contained in:
Gautam Manchandani
2026-06-11 17:01:24 -07:00
committed by GitHub
parent 108aadd251
commit 3310ebc4a0
3 changed files with 28 additions and 6 deletions
@@ -22,6 +22,7 @@ exports[`open-api > should generate OpenAPI schema > openAPISchema 1`] = `
"type": "string",
},
"id": {
"readOnly": true,
"type": "string",
},
"idToken": {
@@ -52,6 +53,7 @@ exports[`open-api > should generate OpenAPI schema > openAPISchema 1`] = `
},
},
"required": [
"id",
"accountId",
"providerId",
"userId",
@@ -72,6 +74,7 @@ exports[`open-api > should generate OpenAPI schema > openAPISchema 1`] = `
"type": "string",
},
"id": {
"readOnly": true,
"type": "string",
},
"ipAddress": {
@@ -92,6 +95,7 @@ exports[`open-api > should generate OpenAPI schema > openAPISchema 1`] = `
},
},
"required": [
"id",
"expiresAt",
"token",
"createdAt",
@@ -116,6 +120,7 @@ exports[`open-api > should generate OpenAPI schema > openAPISchema 1`] = `
"type": "boolean",
},
"id": {
"readOnly": true,
"type": "string",
},
"image": {
@@ -138,8 +143,10 @@ exports[`open-api > should generate OpenAPI schema > openAPISchema 1`] = `
},
},
"required": [
"id",
"name",
"email",
"emailVerified",
"createdAt",
"updatedAt",
"role",
@@ -158,6 +165,7 @@ exports[`open-api > should generate OpenAPI schema > openAPISchema 1`] = `
"type": "string",
},
"id": {
"readOnly": true,
"type": "string",
},
"identifier": {
@@ -173,6 +181,7 @@ exports[`open-api > should generate OpenAPI schema > openAPISchema 1`] = `
},
},
"required": [
"id",
"identifier",
"value",
"expiresAt",
@@ -387,15 +387,15 @@ export async function generator(ctx: AuthContext, options: BetterAuthOptions) {
>((acc, [key, value]) => {
const modelName = key.charAt(0).toUpperCase() + key.slice(1);
const fields = value.fields;
const required: string[] = [];
const required = new Set<string>(["id"]);
const properties: Record<string, FieldSchema> = {
id: { type: "string" },
id: { type: "string", readOnly: true },
};
Object.entries(fields).forEach(([fieldKey, fieldValue]) => {
if (!fieldValue) return;
properties[fieldKey] = getFieldSchema(fieldValue);
if (fieldValue.required && fieldValue.input !== false) {
required.push(fieldKey);
if (fieldValue.required && fieldValue.returned !== false) {
required.add(fieldKey);
}
});
@@ -408,7 +408,7 @@ export async function generator(ctx: AuthContext, options: BetterAuthOptions) {
acc[modelName] = {
type: "object",
properties,
required,
required: Array.from(required),
};
return acc;
}, {});
@@ -26,15 +26,28 @@ describe("open-api", async () => {
expect(schema).toMatchSnapshot("openAPISchema");
});
it("should have an id field in the User schema", async () => {
it("should mark model id fields as required and read-only", async () => {
const schema = await auth.api.generateOpenAPISchema();
const schemas = schema.components.schemas as Record<
string,
Record<string, any>
>;
expect(schemas["User"]!.properties.id).toEqual({
readOnly: true,
type: "string",
});
expect(schemas["User"]!.required).toContain("id");
expect(schemas["User"]!.properties.emailVerified).toEqual({
default: false,
readOnly: true,
type: "boolean",
});
expect(schemas["User"]!.required).toContain("emailVerified");
expect(schemas["Session"]!.properties.id).toEqual({
readOnly: true,
type: "string",
});
expect(schemas["Session"]!.required).toContain("id");
});
it("should include additionalFields in the User schema", async () => {