From 82bef3e848833e5df9af95e18e0e40504fc9d363 Mon Sep 17 00:00:00 2001 From: Nolann Biron Date: Fri, 2 May 2025 09:39:54 +0200 Subject: [PATCH] Missing top-level required OpenAPI alternatives --- .changeset/shy-plums-deny.md | 5 +++ packages/react-openapi/src/OpenAPISchema.tsx | 38 ++++++++++++++++++-- 2 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 .changeset/shy-plums-deny.md diff --git a/.changeset/shy-plums-deny.md b/.changeset/shy-plums-deny.md new file mode 100644 index 0000000000..22193b58e1 --- /dev/null +++ b/.changeset/shy-plums-deny.md @@ -0,0 +1,5 @@ +--- +'@gitbook/react-openapi': patch +--- + +Missing top-level required OpenAPI alternatives diff --git a/packages/react-openapi/src/OpenAPISchema.tsx b/packages/react-openapi/src/OpenAPISchema.tsx index 007c335cf8..7841b1c0f0 100644 --- a/packages/react-openapi/src/OpenAPISchema.tsx +++ b/packages/react-openapi/src/OpenAPISchema.tsx @@ -572,6 +572,9 @@ function flattenAlternatives( schemasOrRefs: (OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject)[], ancestors: Set ): OpenAPIV3.SchemaObject[] { + // Get the parent schema's required fields from the most recent ancestor + const latestAncestor = Array.from(ancestors).pop(); + return schemasOrRefs.reduce((acc, schemaOrRef) => { if (checkIsReference(schemaOrRef)) { return acc; @@ -580,16 +583,47 @@ function flattenAlternatives( if (schemaOrRef[alternativeType] && !ancestors.has(schemaOrRef)) { const schemas = getSchemaAlternatives(schemaOrRef, ancestors); if (schemas) { - acc.push(...schemas); + acc.push( + ...schemas.map((schema) => ({ + ...schema, + required: mergeRequiredFields(schema, latestAncestor), + })) + ); } return acc; } - acc.push(schemaOrRef); + // For direct schemas, handle required fields + const schema = { + ...schemaOrRef, + required: mergeRequiredFields(schemaOrRef, latestAncestor), + }; + + acc.push(schema); return acc; }, []); } +/** + * Merge the required fields of a schema with the required fields of its latest ancestor. + */ +function mergeRequiredFields( + schemaOrRef: OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject, + latestAncestor: OpenAPIV3.SchemaObject | undefined +) { + if (!schemaOrRef.required && !latestAncestor?.required) { + return undefined; + } + + if (checkIsReference(schemaOrRef)) { + return latestAncestor?.required; + } + + return Array.from( + new Set([...(latestAncestor?.required || []), ...(schemaOrRef.required || [])]) + ); +} + function getSchemaTitle(schema: OpenAPIV3.SchemaObject): string { // Otherwise try to infer a nice title let type = 'any';