Skip to content

Commit e345f9c

Browse files
committed
Fix example and description missing
1 parent 1008eb7 commit e345f9c

File tree

2 files changed

+67
-35
lines changed

2 files changed

+67
-35
lines changed

packages/react-openapi/src/OpenAPISchema.tsx

Lines changed: 12 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@ import clsx from 'clsx';
55
import { Markdown } from './Markdown';
66
import { OpenAPIDisclosure } from './OpenAPIDisclosure';
77
import { OpenAPISchemaName } from './OpenAPISchemaName';
8-
import { stringifyOpenAPI } from './stringifyOpenAPI';
98
import type { OpenAPIClientContext } from './types';
10-
import { checkIsReference, resolveDescription } from './utils';
9+
import { checkIsReference, resolveDescription, resolveFirstExample } from './utils';
1110

1211
type CircularRefsIds = Map<OpenAPIV3.SchemaObject, string>;
1312

@@ -199,30 +198,22 @@ export function OpenAPISchemaEnum(props: { enumValues: any[] }) {
199198
);
200199
}
201200

202-
export function OpenAPISchemaPresentation(props: { property: OpenAPISchemaPropertyEntry }) {
201+
export function OpenAPISchemaPresentation(
202+
props: { property: OpenAPISchemaPropertyEntry } & { showType?: boolean }
203+
) {
203204
const {
204205
property: { schema, propertyName, required },
206+
showType = true,
205207
} = props;
206208

207-
const shouldDisplayExample = (schema: OpenAPIV3.SchemaObject): boolean => {
208-
return (
209-
(typeof schema.example === 'string' && !!schema.example) ||
210-
typeof schema.example === 'number' ||
211-
typeof schema.example === 'boolean' ||
212-
(Array.isArray(schema.example) && schema.example.length > 0) ||
213-
(typeof schema.example === 'object' &&
214-
schema.example !== null &&
215-
Object.keys(schema.example).length > 0)
216-
);
217-
};
218-
219209
const description = resolveDescription(schema);
210+
const example = resolveFirstExample(schema);
220211

221212
return (
222213
<div className="openapi-schema-presentation">
223214
<OpenAPISchemaName
224215
schema={schema}
225-
type={getSchemaTitle(schema)}
216+
type={showType ? getSchemaTitle(schema) : undefined}
226217
propertyName={propertyName}
227218
required={required}
228219
/>
@@ -237,9 +228,9 @@ export function OpenAPISchemaPresentation(props: { property: OpenAPISchemaProper
237228
{description ? (
238229
<Markdown source={description} className="openapi-schema-description" />
239230
) : null}
240-
{shouldDisplayExample(schema) ? (
231+
{example ? (
241232
<div className="openapi-schema-example">
242-
Example: <code>{formatExample(schema.example)}</code>
233+
Example: <code>{example}</code>
243234
</div>
244235
) : null}
245236
{schema.pattern ? (
@@ -257,7 +248,9 @@ export function OpenAPISchemaPresentation(props: { property: OpenAPISchemaProper
257248
/**
258249
* Get the sub-properties of a schema.
259250
*/
260-
function getSchemaProperties(schema: OpenAPIV3.SchemaObject): null | OpenAPISchemaPropertyEntry[] {
251+
export function getSchemaProperties(
252+
schema: OpenAPIV3.SchemaObject
253+
): null | OpenAPISchemaPropertyEntry[] {
261254
// check array AND schema.items as this is sometimes null despite what the type indicates
262255
if (schema.type === 'array' && schema.items && !checkIsReference(schema.items)) {
263256
const items = schema.items;
@@ -418,16 +411,3 @@ function getDisclosureLabel(schema: OpenAPIV3.SchemaObject): string {
418411

419412
return schema.title || 'child attributes';
420413
}
421-
422-
function formatExample(example: any): string {
423-
if (typeof example === 'string') {
424-
return example
425-
.replace(/\n/g, ' ') // Replace newlines with spaces
426-
.replace(/\s+/g, ' ') // Collapse multiple spaces/newlines into a single space
427-
.replace(/([\{\}:,])\s+/g, '$1 ') // Ensure a space after {, }, :, and ,
428-
.replace(/\s+([\{\}:,])/g, ' $1') // Ensure a space before {, }, :, and ,
429-
.trim();
430-
}
431-
432-
return stringifyOpenAPI(example);
433-
}

packages/react-openapi/src/utils.ts

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { AnyObject, OpenAPIV3, OpenAPIV3_1 } from '@gitbook/openapi-parser';
2+
import { stringifyOpenAPI } from './stringifyOpenAPI';
23

34
export function checkIsReference(
45
input: unknown
@@ -10,11 +11,23 @@ export function createStateKey(key: string, scope?: string) {
1011
return scope ? `${scope}_${key}` : key;
1112
}
1213

14+
function hasDescription(object: AnyObject) {
15+
if (Array.isArray(object)) {
16+
return object.some(hasDescription);
17+
}
18+
19+
return 'description' in object || 'x-gitbook-description-html' in object;
20+
}
21+
1322
/**
1423
* Resolve the description of an object.
1524
*/
1625
export function resolveDescription(object: OpenAPIV3.SchemaObject | AnyObject) {
17-
if ('items' in object && object.items) {
26+
if ('items' in object && typeof object.items === 'object' && hasDescription(object.items)) {
27+
if (Array.isArray(object.items)) {
28+
return resolveDescription(object.items[0]);
29+
}
30+
1831
return resolveDescription(object.items);
1932
}
2033

@@ -50,9 +63,20 @@ export function resolveFirstExample(object: AnyObject) {
5063
return object.examples[firstKey];
5164
}
5265
}
53-
if ('example' in object && object.example !== undefined) {
54-
return object.example;
66+
67+
// Resolve top level example first
68+
if (shouldDisplayExample(object)) {
69+
return formatExample(object.example);
70+
}
71+
72+
// Resolve example from items if any
73+
if (object.items && typeof object.items === 'object') {
74+
if (Array.isArray(object.items)) {
75+
return formatExample(object.items[0].example);
76+
}
77+
return formatExample(object.items.example);
5578
}
79+
5680
return undefined;
5781
}
5882

@@ -98,3 +122,31 @@ export function parameterToProperty(
98122
required: parameter.required,
99123
};
100124
}
125+
126+
/**
127+
* Format the example of a schema.
128+
*/
129+
function formatExample(example: unknown): string {
130+
if (typeof example === 'string') {
131+
return example
132+
.replace(/\n/g, ' ') // Replace newlines with spaces
133+
.replace(/\s+/g, ' ') // Collapse multiple spaces/newlines into a single space
134+
.replace(/([\{\}:,])\s+/g, '$1 ') // Ensure a space after {, }, :, and ,
135+
.replace(/\s+([\{\}:,])/g, ' $1') // Ensure a space before {, }, :, and ,
136+
.trim();
137+
}
138+
139+
return stringifyOpenAPI(example);
140+
}
141+
142+
function shouldDisplayExample(schema: OpenAPIV3.SchemaObject): boolean {
143+
return (
144+
(typeof schema.example === 'string' && !!schema.example) ||
145+
typeof schema.example === 'number' ||
146+
typeof schema.example === 'boolean' ||
147+
(Array.isArray(schema.example) && schema.example.length > 0) ||
148+
(typeof schema.example === 'object' &&
149+
schema.example !== null &&
150+
Object.keys(schema.example).length > 0)
151+
);
152+
}

0 commit comments

Comments
 (0)