diff --git a/.changeset/green-moles-camp.md b/.changeset/green-moles-camp.md
new file mode 100644
index 000000000..b0596261a
--- /dev/null
+++ b/.changeset/green-moles-camp.md
@@ -0,0 +1,5 @@
+---
+'@gitbook/react-openapi': patch
+---
+
+Fix display of OpenAPI header description
diff --git a/packages/react-openapi/src/OpenAPIResponse.tsx b/packages/react-openapi/src/OpenAPIResponse.tsx
index f72b9ed75..0d3e36c39 100644
--- a/packages/react-openapi/src/OpenAPIResponse.tsx
+++ b/packages/react-openapi/src/OpenAPIResponse.tsx
@@ -1,6 +1,6 @@
import type { OpenAPIV3 } from '@gitbook/openapi-parser';
import { OpenAPISchemaProperties } from './OpenAPISchema';
-import { resolveDescription } from './utils';
+import { parameterToProperty, resolveDescription } from './utils';
import type { OpenAPIClientContext } from './types';
import { OpenAPIDisclosure } from './OpenAPIDisclosure';
@@ -27,13 +27,11 @@ export function OpenAPIResponse(props: {
return (
{headers.length > 0 ? (
-
+
({
- propertyName: name,
- schema: header.schema ?? {},
- required: header.required,
- }))}
+ properties={headers.map(([name, header]) => {
+ return parameterToProperty({ name, ...header });
+ })}
context={context}
/>
@@ -41,11 +39,7 @@ export function OpenAPIResponse(props: {
diff --git a/packages/react-openapi/src/OpenAPISchema.tsx b/packages/react-openapi/src/OpenAPISchema.tsx
index bc2693661..d364a96af 100644
--- a/packages/react-openapi/src/OpenAPISchema.tsx
+++ b/packages/react-openapi/src/OpenAPISchema.tsx
@@ -13,8 +13,8 @@ import { OpenAPIDisclosure } from './OpenAPIDisclosure';
type CircularRefsIds = Map;
export interface OpenAPISchemaPropertyEntry {
- propertyName?: string;
- required?: boolean;
+ propertyName?: string | undefined;
+ required?: boolean | undefined;
schema: OpenAPIV3.SchemaObject;
}
@@ -47,7 +47,7 @@ export function OpenAPISchemaProperty(
? null
: getSchemaAlternatives(schema, new Set(circularRefs.keys()));
- if ((properties && !!properties.length) || schema.type === 'object') {
+ if ((properties && properties.length > 0) || schema.type === 'object') {
return (
diff --git a/packages/react-openapi/src/OpenAPISpec.tsx b/packages/react-openapi/src/OpenAPISpec.tsx
index c4a2571ed..29b43846b 100644
--- a/packages/react-openapi/src/OpenAPISpec.tsx
+++ b/packages/react-openapi/src/OpenAPISpec.tsx
@@ -8,7 +8,7 @@ import { OpenAPIResponses } from './OpenAPIResponses';
import { OpenAPISchemaProperties } from './OpenAPISchema';
import { OpenAPISecurities } from './OpenAPISecurities';
import type { OpenAPIClientContext, OpenAPIOperationData } from './types';
-import { resolveDescription } from './utils';
+import { parameterToProperty } from './utils';
/**
* Client component to render the spec for the request and response.
@@ -38,22 +38,7 @@ export function OpenAPISpec(props: { data: OpenAPIOperationData; context: OpenAP
header={group.label}
>
{
- const description = resolveDescription(parameter);
- return {
- propertyName: parameter.name,
- schema: {
- // Description of the parameter is defined at the parameter level
- // we use display it if the schema doesn't override it
- description: description,
- example: parameter.example,
- // Deprecated can be defined at the parameter level
- deprecated: parameter.deprecated,
- ...(parameter.schema ?? {}),
- },
- required: parameter.required,
- };
- })}
+ properties={group.parameters.map(parameterToProperty)}
context={context}
/>
diff --git a/packages/react-openapi/src/utils.ts b/packages/react-openapi/src/utils.ts
index c3a45a578..6bebf2f58 100644
--- a/packages/react-openapi/src/utils.ts
+++ b/packages/react-openapi/src/utils.ts
@@ -1,6 +1,8 @@
-import type { AnyObject, OpenAPIV3 } from '@gitbook/openapi-parser';
+import type { AnyObject, OpenAPIV3, OpenAPIV3_1 } from '@gitbook/openapi-parser';
-export function checkIsReference(input: unknown): input is OpenAPIV3.ReferenceObject {
+export function checkIsReference(
+ input: unknown,
+): input is OpenAPIV3.ReferenceObject | OpenAPIV3_1.ReferenceObject {
return typeof input === 'object' && !!input && '$ref' in input;
}
@@ -19,3 +21,76 @@ export function resolveDescription(object: AnyObject) {
? object.description
: undefined;
}
+
+/**
+ * Extract descriptions from an object.
+ */
+export function extractDescriptions(object: AnyObject) {
+ return {
+ description: object.description,
+ ['x-gitbook-description-html']:
+ 'x-gitbook-description-html' in object
+ ? object['x-gitbook-description-html']
+ : undefined,
+ };
+}
+
+/**
+ * Resolve the first example from an object.
+ */
+export function resolveFirstExample(object: AnyObject) {
+ if ('examples' in object && typeof object.examples === 'object' && object.examples) {
+ const keys = Object.keys(object.examples);
+ const firstKey = keys[0];
+ if (firstKey && object.examples[firstKey]) {
+ return object.examples[firstKey];
+ }
+ }
+ if ('example' in object && object.example !== undefined) {
+ return object.example;
+ }
+ return undefined;
+}
+
+/**
+ * Resolve the schema of a parameter.
+ * Extract the description, example and deprecated from parameter.
+ */
+export function resolveParameterSchema(
+ parameter: OpenAPIV3.ParameterBaseObject,
+): OpenAPIV3.SchemaObject {
+ const schema = checkIsReference(parameter.schema) ? undefined : parameter.schema;
+ return {
+ // Description of the parameter is defined at the parameter level
+ // we use display it if the schema doesn't override it
+ ...extractDescriptions(parameter),
+ example: resolveFirstExample(parameter),
+ // Deprecated can be defined at the parameter level
+ deprecated: parameter.deprecated,
+ ...schema,
+ };
+}
+
+/**
+ * Transform a parameter object to a property object.
+ */
+export function parameterToProperty(
+ parameter: OpenAPIV3.ParameterObject | OpenAPIV3.ReferenceObject | OpenAPIV3_1.ReferenceObject,
+): {
+ propertyName: string | undefined;
+ schema: OpenAPIV3.SchemaObject;
+ required: boolean | undefined;
+} {
+ if (checkIsReference(parameter)) {
+ return {
+ propertyName: parameter.$ref ?? 'Unknown ref',
+ schema: {},
+ required: undefined,
+ };
+ }
+ return {
+ propertyName: parameter.name,
+ schema: resolveParameterSchema(parameter),
+ required: parameter.required,
+ };
+}