Skip to content

Commit dedb612

Browse files
committed
Fix examples webhook
1 parent 904476b commit dedb612

8 files changed

+169
-333
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
import type { OpenAPIV3 } from '@gitbook/openapi-parser';
2-
import { generateSchemaExample } from './generateSchemaExample';
32
import { json2xml } from './json2xml';
43
import { stringifyOpenAPI } from './stringifyOpenAPI';
54
import type { OpenAPIContext } from './types';
6-
import { checkIsReference } from './utils';
75

86
/**
97
* Display an example.
@@ -51,79 +49,3 @@ export function OpenAPIEmptyExample() {
5149
</pre>
5250
);
5351
}
54-
55-
/**
56-
* Generate an example from a reference object.
57-
*/
58-
export function getExampleFromReference(ref: OpenAPIV3.ReferenceObject): OpenAPIV3.ExampleObject {
59-
return { summary: 'Unresolved reference', value: { $ref: ref.$ref } };
60-
}
61-
62-
/**
63-
* Get examples from a media type object.
64-
*/
65-
export function getExamplesFromMediaTypeObject(args: {
66-
mediaType: string;
67-
mediaTypeObject: OpenAPIV3.MediaTypeObject;
68-
}): { key: string; example: OpenAPIV3.ExampleObject }[] {
69-
const { mediaTypeObject, mediaType } = args;
70-
if (mediaTypeObject.examples) {
71-
return Object.entries(mediaTypeObject.examples).map(([key, example]) => {
72-
return {
73-
key,
74-
example: checkIsReference(example) ? getExampleFromReference(example) : example,
75-
};
76-
});
77-
}
78-
79-
if (mediaTypeObject.example) {
80-
return [{ key: 'default', example: { value: mediaTypeObject.example } }];
81-
}
82-
83-
if (mediaTypeObject.schema) {
84-
if (mediaType === 'application/xml') {
85-
// @TODO normally we should use the name of the schema but we don't have it
86-
// fix it when we got the reference name
87-
const root = mediaTypeObject.schema.xml?.name ?? 'object';
88-
return [
89-
{
90-
key: 'default',
91-
example: {
92-
value: {
93-
[root]: generateSchemaExample(mediaTypeObject.schema, {
94-
xml: mediaType === 'application/xml',
95-
mode: 'read',
96-
}),
97-
},
98-
},
99-
},
100-
];
101-
}
102-
return [
103-
{
104-
key: 'default',
105-
example: {
106-
value: generateSchemaExample(mediaTypeObject.schema, {
107-
mode: 'read',
108-
}),
109-
},
110-
},
111-
];
112-
}
113-
return [];
114-
}
115-
116-
/**
117-
* Get example from a schema object.
118-
*/
119-
export function getExampleFromSchema(args: {
120-
schema: OpenAPIV3.SchemaObject;
121-
}): OpenAPIV3.ExampleObject {
122-
const { schema } = args;
123-
124-
if (schema.example) {
125-
return { value: schema.example };
126-
}
127-
128-
return { value: generateSchemaExample(schema, { mode: 'read' }) };
129-
}

packages/react-openapi/src/OpenAPIResponseMediaType.tsx renamed to packages/react-openapi/src/OpenAPIMediaType.tsx

+29-47
Original file line numberDiff line numberDiff line change
@@ -3,37 +3,30 @@ import type { Key } from 'react-aria';
33
import { OpenAPIEmptyExample } from './OpenAPIExample';
44
import { OpenAPISelect, OpenAPISelectItem, useSelectState } from './OpenAPISelect';
55
import { StaticSection } from './StaticSection';
6-
import { createStateKey } from './utils';
76

8-
type OpenAPIResponseMediaTypeItem = OpenAPISelectItem & {
7+
type OpenAPIMediaTypeItem = OpenAPISelectItem & {
98
body: React.ReactNode;
10-
examples?: OpenAPIResponseMediaTypeItem[];
9+
examples?: OpenAPIMediaTypeItem[];
1110
};
1211

1312
/**
1413
* Get the state of the response examples select.
1514
*/
16-
export function useResponseMediaTypesState(
17-
blockKey: string | undefined,
18-
initialKey: Key = 'default'
19-
) {
20-
return useSelectState(getResponseMediaTypeStateKey(blockKey), initialKey);
15+
export function useMediaTypesState(stateKey: string | undefined, initialKey: Key = 'default') {
16+
return useSelectState(stateKey, initialKey);
2117
}
2218

23-
function useResponseMediaTypeExamplesState(
24-
blockKey: string | undefined,
25-
initialKey: Key = 'default'
26-
) {
27-
return useSelectState(getResponseMediaTypeExamplesStateKey(blockKey), initialKey);
19+
function useMediaTypeExamplesState(stateKey: string | undefined, initialKey: Key = 'default') {
20+
return useSelectState(stateKey, initialKey);
2821
}
2922

30-
export function OpenAPIResponseMediaTypeContent(props: {
31-
items: OpenAPIResponseMediaTypeItem[];
32-
blockKey?: string;
23+
export function OpenAPIMediaTypeContent(props: {
24+
items: OpenAPIMediaTypeItem[];
3325
selectIcon?: React.ReactNode;
26+
stateKey: string;
3427
}) {
35-
const { blockKey, items, selectIcon } = props;
36-
const state = useResponseMediaTypesState(blockKey, items[0]?.key);
28+
const { stateKey, items, selectIcon } = props;
29+
const state = useMediaTypesState(stateKey, items[0]?.key);
3730

3831
const examples = items.find((item) => item.key === state.key)?.examples ?? [];
3932

@@ -45,36 +38,36 @@ export function OpenAPIResponseMediaTypeContent(props: {
4538
<StaticSection
4639
footer={
4740
items.length > 1 || examples.length > 1 ? (
48-
<OpenAPIResponseMediaTypeFooter
49-
blockKey={blockKey}
41+
<OpenAPIMediaTypeFooter
5042
items={items}
5143
examples={examples}
5244
selectIcon={selectIcon}
45+
stateKey={stateKey}
5346
/>
5447
) : null
5548
}
5649
className="openapi-response-media-types-examples"
5750
>
58-
<OpenAPIResponseMediaTypeBody blockKey={blockKey} items={items} examples={examples} />
51+
<OpenAPIMediaTypeBody stateKey={stateKey} items={items} examples={examples} />
5952
</StaticSection>
6053
);
6154
}
6255

63-
function OpenAPIResponseMediaTypeFooter(props: {
64-
items: OpenAPIResponseMediaTypeItem[];
65-
examples?: OpenAPIResponseMediaTypeItem[];
66-
blockKey?: string;
56+
function OpenAPIMediaTypeFooter(props: {
57+
items: OpenAPIMediaTypeItem[];
58+
examples?: OpenAPIMediaTypeItem[];
6759
selectIcon?: React.ReactNode;
60+
stateKey: string;
6861
}) {
69-
const { items, examples, blockKey, selectIcon } = props;
62+
const { items, examples, stateKey, selectIcon } = props;
7063

7164
return (
7265
<>
7366
{items.length > 1 && (
7467
<OpenAPISelect
7568
icon={selectIcon}
7669
items={items}
77-
stateKey={getResponseMediaTypeStateKey(blockKey)}
70+
stateKey={stateKey}
7871
placement="bottom start"
7972
>
8073
{items.map((item) => (
@@ -89,7 +82,7 @@ function OpenAPIResponseMediaTypeFooter(props: {
8982
<OpenAPISelect
9083
icon={selectIcon}
9184
items={examples}
92-
stateKey={getResponseMediaTypeExamplesStateKey(blockKey)}
85+
stateKey={`${stateKey}-examples`}
9386
placement="bottom start"
9487
>
9588
{examples.map((example) => (
@@ -103,18 +96,18 @@ function OpenAPIResponseMediaTypeFooter(props: {
10396
);
10497
}
10598

106-
function OpenAPIResponseMediaTypeBody(props: {
107-
items: OpenAPIResponseMediaTypeItem[];
108-
examples?: OpenAPIResponseMediaTypeItem[];
109-
blockKey?: string;
99+
function OpenAPIMediaTypeBody(props: {
100+
items: OpenAPIMediaTypeItem[];
101+
examples?: OpenAPIMediaTypeItem[];
102+
stateKey: string;
110103
}) {
111-
const { blockKey, items, examples } = props;
112-
const state = useResponseMediaTypesState(blockKey, items[0]?.key);
104+
const { stateKey, items, examples } = props;
105+
const state = useMediaTypesState(stateKey, items[0]?.key);
113106

114107
const selectedItem = items.find((item) => item.key === state.key) ?? items[0];
115108

116-
const exampleState = useResponseMediaTypeExamplesState(
117-
blockKey,
109+
const exampleState = useMediaTypeExamplesState(
110+
`${stateKey}-examples`,
118111
selectedItem?.examples?.[0]?.key
119112
);
120113

@@ -135,14 +128,3 @@ function OpenAPIResponseMediaTypeBody(props: {
135128

136129
return selectedItem.body;
137130
}
138-
139-
/**
140-
* Return the state key for the response media types.
141-
*/
142-
function getResponseMediaTypeStateKey(blockKey: string | undefined) {
143-
return createStateKey('response-media-types', blockKey);
144-
}
145-
146-
function getResponseMediaTypeExamplesStateKey(blockKey: string | undefined) {
147-
return createStateKey('response-media-types-examples', blockKey);
148-
}

packages/react-openapi/src/OpenAPIResponseExample.tsx

+6-30
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
11
import type { OpenAPIV3 } from '@gitbook/openapi-parser';
22
import { Markdown } from './Markdown';
3-
import {
4-
OpenAPIEmptyExample,
5-
OpenAPIExample,
6-
getExampleFromReference,
7-
getExamplesFromMediaTypeObject,
8-
} from './OpenAPIExample';
3+
import { OpenAPIEmptyExample, OpenAPIExample } from './OpenAPIExample';
4+
import { OpenAPIMediaTypeContent } from './OpenAPIMediaType';
95
import { OpenAPIResponseExampleContent } from './OpenAPIResponseExampleContent';
10-
import { OpenAPIResponseMediaTypeContent } from './OpenAPIResponseMediaType';
116
import type { OpenAPIContext, OpenAPIOperationData, OpenAPIWebhookData } from './types';
12-
import { getStatusCodeDefaultLabel, getSyntaxFromMediaType } from './utils';
7+
import { getExampleFromReference, getExamples } from './util/example';
8+
import { createStateKey, getStatusCodeDefaultLabel } from './utils';
139
import { checkIsReference, resolveDescription } from './utils';
1410

1511
/**
@@ -127,30 +123,10 @@ function OpenAPIResponse(props: {
127123
});
128124

129125
return (
130-
<OpenAPIResponseMediaTypeContent
126+
<OpenAPIMediaTypeContent
131127
selectIcon={context.icons.chevronDown}
132-
blockKey={context.blockKey}
128+
stateKey={createStateKey('response-media-types', context.blockKey)}
133129
items={tabs}
134130
/>
135131
);
136132
}
137-
138-
function getExamples(props: {
139-
mediaTypeObject: OpenAPIV3.MediaTypeObject;
140-
mediaType: string;
141-
context: OpenAPIContext;
142-
}) {
143-
const { mediaTypeObject, mediaType } = props;
144-
const examples = getExamplesFromMediaTypeObject({ mediaTypeObject, mediaType });
145-
const syntax = getSyntaxFromMediaType(mediaType);
146-
147-
return examples.map((example) => {
148-
return {
149-
key: example.key,
150-
label: example.example.summary || example.key,
151-
body: (
152-
<OpenAPIExample example={example.example} context={props.context} syntax={syntax} />
153-
),
154-
};
155-
});
156-
}

packages/react-openapi/src/schemas/OpenAPISchemas.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import type { OpenAPISchema } from '@gitbook/openapi-parser';
22
import clsx from 'clsx';
33
import { OpenAPIDisclosure } from '../OpenAPIDisclosure';
4-
import { OpenAPIExample, getExampleFromSchema } from '../OpenAPIExample';
4+
import { OpenAPIExample } from '../OpenAPIExample';
55
import { OpenAPIRootSchema } from '../OpenAPISchemaServer';
66
import { Section, SectionBody, StaticSection } from '../StaticSection';
77
import { getOpenAPIClientContext } from '../context';
88
import type { OpenAPIContext } from '../types';
9+
import { getExampleFromSchema } from '../util/example';
910

1011
/**
1112
* OpenAPI Schemas component.

0 commit comments

Comments
 (0)