@gitbook/react-openapi 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/dist/InteractiveSection.d.ts +0 -2
- package/dist/InteractiveSection.jsx +8 -44
- package/dist/OpenAPICodeSample.jsx +12 -12
- package/dist/OpenAPIOperation.jsx +8 -5
- package/dist/OpenAPIRequestBody.d.ts +2 -2
- package/dist/OpenAPIRequestBody.jsx +5 -2
- package/dist/OpenAPIResponse.jsx +17 -25
- package/dist/OpenAPIResponseExample.jsx +157 -48
- package/dist/OpenAPIResponses.jsx +2 -3
- package/dist/OpenAPISchema.d.ts +2 -2
- package/dist/OpenAPISchema.jsx +28 -29
- package/dist/OpenAPISpec.jsx +4 -28
- package/dist/OpenAPITabs.d.ts +1 -0
- package/dist/OpenAPITabs.jsx +52 -16
- package/dist/generateSchemaExample.d.ts +5 -6
- package/dist/generateSchemaExample.js +15 -11
- package/dist/json2xml.d.ts +4 -0
- package/dist/json2xml.js +7 -0
- package/dist/resolveOpenAPIOperation.js +4 -4
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/types.d.ts +4 -0
- package/dist/useSyncedTabsGlobalState.d.ts +1 -0
- package/dist/useSyncedTabsGlobalState.js +16 -0
- package/dist/utils.d.ts +26 -3
- package/dist/utils.js +72 -9
- package/package.json +4 -2
- package/src/InteractiveSection.tsx +4 -41
- package/src/OpenAPICodeSample.tsx +12 -12
- package/src/OpenAPIOperation.tsx +8 -5
- package/src/OpenAPIRequestBody.tsx +7 -3
- package/src/OpenAPIResponse.tsx +7 -27
- package/src/OpenAPIResponseExample.tsx +237 -70
- package/src/OpenAPIResponses.tsx +2 -7
- package/src/OpenAPISchema.tsx +34 -33
- package/src/OpenAPISpec.tsx +4 -22
- package/src/OpenAPITabs.tsx +63 -23
- package/src/__snapshots__/json2xml.test.ts.snap +18 -0
- package/src/generateSchemaExample.ts +11 -10
- package/src/json2xml.test.ts +46 -0
- package/src/json2xml.ts +8 -0
- package/src/resolveOpenAPIOperation.test.ts +1 -1
- package/src/resolveOpenAPIOperation.ts +8 -7
- package/src/types.ts +1 -0
- package/src/useSyncedTabsGlobalState.ts +23 -0
- package/src/utils.ts +81 -13
- package/dist/fetchOpenAPIOperation.d.ts +0 -27
- package/dist/fetchOpenAPIOperation.js +0 -195
- package/dist/tsconfig.tsbuildinfo +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# @gitbook/react-openapi
|
|
2
2
|
|
|
3
|
+
## 1.0.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- bb5c6a4: Support multiple response media types and examples
|
|
8
|
+
- a3f1fea: Fix display of OpenAPI header description
|
|
9
|
+
- 6157583: Improve Markdown parsing
|
|
10
|
+
- 7419ee7: Show additional fields in OpenAPI block
|
|
11
|
+
- 82cd9f2: Add support for anchor links in OpenAPI blocks
|
|
12
|
+
- Updated dependencies [6157583]
|
|
13
|
+
- @gitbook/openapi-parser@1.0.1
|
|
14
|
+
|
|
15
|
+
## 1.0.1
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- f8d4c76: Sync tabs across all OpenAPI blocks
|
|
20
|
+
- dddb4ec: Fix long tab group description
|
|
21
|
+
- f8d4c76: Support for OpenAPI references
|
|
22
|
+
|
|
3
23
|
## 1.0.0
|
|
4
24
|
|
|
5
25
|
### Major Changes
|
|
@@ -27,7 +27,5 @@ export declare function InteractiveSection(props: {
|
|
|
27
27
|
children?: React.ReactNode;
|
|
28
28
|
/** Children to display within the container */
|
|
29
29
|
overlay?: React.ReactNode;
|
|
30
|
-
/** An optional key referencing a value in global state */
|
|
31
|
-
stateKey?: string;
|
|
32
30
|
}): import("react").JSX.Element;
|
|
33
31
|
export {};
|
|
@@ -1,55 +1,25 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
var __assign = (this && this.__assign) || function () {
|
|
3
|
-
__assign = Object.assign || function(t) {
|
|
4
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
-
s = arguments[i];
|
|
6
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
-
t[p] = s[p];
|
|
8
|
-
}
|
|
9
|
-
return t;
|
|
10
|
-
};
|
|
11
|
-
return __assign.apply(this, arguments);
|
|
12
|
-
};
|
|
13
2
|
import clsx from 'clsx';
|
|
14
|
-
import {
|
|
3
|
+
import { useRef, useState } from 'react';
|
|
15
4
|
import { mergeProps, useButton, useDisclosure, useFocusRing } from 'react-aria';
|
|
16
5
|
import { useDisclosureState } from 'react-stately';
|
|
17
|
-
var globalState = {};
|
|
18
|
-
var listeners = new Set();
|
|
19
|
-
function useSyncedTabsGlobalState() {
|
|
20
|
-
var subscribe = useCallback(function (callback) {
|
|
21
|
-
listeners.add(callback);
|
|
22
|
-
return function () { return listeners.delete(callback); };
|
|
23
|
-
}, []);
|
|
24
|
-
var getSnapshot = useCallback(function () { return globalState; }, []);
|
|
25
|
-
var setSyncedTabs = useCallback(function (updater) {
|
|
26
|
-
globalState = updater(globalState);
|
|
27
|
-
listeners.forEach(function (listener) { return listener(); });
|
|
28
|
-
}, []);
|
|
29
|
-
var tabs = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
30
|
-
return [tabs, setSyncedTabs];
|
|
31
|
-
}
|
|
32
6
|
/**
|
|
33
7
|
* To optimize rendering, most of the components are server-components,
|
|
34
8
|
* and the interactiveness is mainly handled by a few key components like this one.
|
|
35
9
|
*/
|
|
36
10
|
export function InteractiveSection(props) {
|
|
37
|
-
var _a, _b, _c
|
|
38
|
-
var id = props.id, className = props.className,
|
|
39
|
-
var
|
|
40
|
-
var
|
|
41
|
-
? tabs.find(function (tab) { return tab.key === syncedTabs[stateKey]; })
|
|
42
|
-
: undefined;
|
|
43
|
-
var _l = useState((_b = tabFromState === null || tabFromState === void 0 ? void 0 : tabFromState.key) !== null && _b !== void 0 ? _b : defaultTab), selectedTabKey = _l[0], setSelectedTab = _l[1];
|
|
44
|
-
var selectedTab = (_c = tabFromState !== null && tabFromState !== void 0 ? tabFromState : tabs.find(function (tab) { return tab.key === selectedTabKey; })) !== null && _c !== void 0 ? _c : tabs[0];
|
|
11
|
+
var _a, _b, _c;
|
|
12
|
+
var id = props.id, className = props.className, _d = props.toggeable, toggeable = _d === void 0 ? false : _d, _e = props.defaultOpened, defaultOpened = _e === void 0 ? true : _e, _f = props.tabs, tabs = _f === void 0 ? [] : _f, _g = props.defaultTab, defaultTab = _g === void 0 ? (_a = tabs[0]) === null || _a === void 0 ? void 0 : _a.key : _g, header = props.header, children = props.children, overlay = props.overlay, _h = props.toggleIcon, toggleIcon = _h === void 0 ? '▶' : _h;
|
|
13
|
+
var _j = useState(defaultTab), selectedTabKey = _j[0], setSelectedTab = _j[1];
|
|
14
|
+
var selectedTab = (_b = tabs.find(function (tab) { return tab.key === selectedTabKey; })) !== null && _b !== void 0 ? _b : tabs[0];
|
|
45
15
|
var state = useDisclosureState({
|
|
46
16
|
defaultExpanded: defaultOpened,
|
|
47
17
|
});
|
|
48
18
|
var panelRef = useRef(null);
|
|
49
19
|
var triggerRef = useRef(null);
|
|
50
|
-
var
|
|
20
|
+
var _k = useDisclosure({}, state, panelRef), triggerProps = _k.buttonProps, panelProps = _k.panelProps;
|
|
51
21
|
var buttonProps = useButton(triggerProps, triggerRef).buttonProps;
|
|
52
|
-
var
|
|
22
|
+
var _l = useFocusRing(), isFocusVisible = _l.isFocusVisible, focusProps = _l.focusProps;
|
|
53
23
|
return (<div id={id} className={clsx('openapi-section', toggeable ? 'openapi-section-toggeable' : null, className, toggeable ? "".concat(className, "-").concat(state.isExpanded ? 'opened' : 'closed') : null)}>
|
|
54
24
|
{header ? (<div onClick={function () {
|
|
55
25
|
if (toggeable) {
|
|
@@ -69,14 +39,8 @@ export function InteractiveSection(props) {
|
|
|
69
39
|
<div className={clsx('openapi-section-header-controls', "".concat(className, "-header-controls"))} onClick={function (event) {
|
|
70
40
|
event.stopPropagation();
|
|
71
41
|
}}>
|
|
72
|
-
{tabs.length > 1 ? (<select className={clsx('openapi-section-select', 'openapi-select', "".concat(className, "-tabs-select"))} value={(
|
|
42
|
+
{tabs.length > 1 ? (<select className={clsx('openapi-section-select', 'openapi-select', "".concat(className, "-tabs-select"))} value={(_c = selectedTab === null || selectedTab === void 0 ? void 0 : selectedTab.key) !== null && _c !== void 0 ? _c : ''} onChange={function (event) {
|
|
73
43
|
setSelectedTab(event.target.value);
|
|
74
|
-
if (stateKey) {
|
|
75
|
-
setSyncedTabs(function (state) {
|
|
76
|
-
var _a;
|
|
77
|
-
return (__assign(__assign({}, state), (_a = {}, _a[stateKey] = event.target.value, _a)));
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
44
|
state.expand();
|
|
81
45
|
}}>
|
|
82
46
|
{tabs.map(function (tab) { return (<option key={tab.key} value={tab.key}>
|
|
@@ -13,9 +13,10 @@ import { codeSampleGenerators } from './code-samples';
|
|
|
13
13
|
import { generateMediaTypeExample, generateSchemaExample } from './generateSchemaExample';
|
|
14
14
|
import { InteractiveSection } from './InteractiveSection';
|
|
15
15
|
import { getServersURL } from './OpenAPIServerURL';
|
|
16
|
-
import {
|
|
16
|
+
import { createStateKey } from './utils';
|
|
17
17
|
import { stringifyOpenAPI } from './stringifyOpenAPI';
|
|
18
18
|
import { OpenAPITabs, OpenAPITabsList, OpenAPITabsPanels } from './OpenAPITabs';
|
|
19
|
+
import { checkIsReference } from './utils';
|
|
19
20
|
/**
|
|
20
21
|
* Display code samples to execute the operation.
|
|
21
22
|
* It supports the Redocly custom syntax as well (https://redocly.com/docs/api-reference-docs/specification-extensions/x-code-samples/)
|
|
@@ -25,30 +26,27 @@ export function OpenAPICodeSample(props) {
|
|
|
25
26
|
var data = props.data, context = props.context;
|
|
26
27
|
var searchParams = new URLSearchParams();
|
|
27
28
|
var headersObject = {};
|
|
28
|
-
(_a = data.operation.parameters) === null || _a === void 0 ? void 0 : _a.forEach(function (
|
|
29
|
-
var param = noReference(rawParam);
|
|
29
|
+
(_a = data.operation.parameters) === null || _a === void 0 ? void 0 : _a.forEach(function (param) {
|
|
30
30
|
if (!param) {
|
|
31
31
|
return;
|
|
32
32
|
}
|
|
33
33
|
if (param.in === 'header' && param.required) {
|
|
34
|
-
var example = param.schema
|
|
35
|
-
? generateSchemaExample(noReference(param.schema))
|
|
36
|
-
: undefined;
|
|
34
|
+
var example = param.schema ? generateSchemaExample(param.schema) : undefined;
|
|
37
35
|
if (example !== undefined && param.name) {
|
|
38
36
|
headersObject[param.name] =
|
|
39
37
|
typeof example !== 'string' ? stringifyOpenAPI(example) : example;
|
|
40
38
|
}
|
|
41
39
|
}
|
|
42
40
|
else if (param.in === 'query' && param.required) {
|
|
43
|
-
var example = param.schema
|
|
44
|
-
? generateSchemaExample(noReference(param.schema))
|
|
45
|
-
: undefined;
|
|
41
|
+
var example = param.schema ? generateSchemaExample(param.schema) : undefined;
|
|
46
42
|
if (example !== undefined && param.name) {
|
|
47
43
|
searchParams.append(param.name, String(Array.isArray(example) ? example[0] : example));
|
|
48
44
|
}
|
|
49
45
|
}
|
|
50
46
|
});
|
|
51
|
-
var requestBody =
|
|
47
|
+
var requestBody = !checkIsReference(data.operation.requestBody)
|
|
48
|
+
? data.operation.requestBody
|
|
49
|
+
: undefined;
|
|
52
50
|
var requestBodyContentEntries = (requestBody === null || requestBody === void 0 ? void 0 : requestBody.content)
|
|
53
51
|
? Object.entries(requestBody.content)
|
|
54
52
|
: undefined;
|
|
@@ -59,7 +57,9 @@ export function OpenAPICodeSample(props) {
|
|
|
59
57
|
(searchParams.size ? "?".concat(searchParams.toString()) : ''),
|
|
60
58
|
method: data.method,
|
|
61
59
|
body: requestBodyContent
|
|
62
|
-
? generateMediaTypeExample(requestBodyContent[1], {
|
|
60
|
+
? generateMediaTypeExample(requestBodyContent[1], {
|
|
61
|
+
omitEmptyAndOptionalProperties: true,
|
|
62
|
+
})
|
|
63
63
|
: undefined,
|
|
64
64
|
headers: __assign(__assign(__assign({}, getSecurityHeaders(data.securities)), headersObject), (requestBodyContent
|
|
65
65
|
? {
|
|
@@ -97,7 +97,7 @@ export function OpenAPICodeSample(props) {
|
|
|
97
97
|
if (samples.length === 0) {
|
|
98
98
|
return null;
|
|
99
99
|
}
|
|
100
|
-
return (<OpenAPITabs items={samples}>
|
|
100
|
+
return (<OpenAPITabs stateKey={createStateKey('codesample')} items={samples}>
|
|
101
101
|
<InteractiveSection header={<OpenAPITabsList />} className="openapi-codesample">
|
|
102
102
|
<OpenAPITabsPanels />
|
|
103
103
|
</InteractiveSection>
|
|
@@ -17,12 +17,15 @@ export function OpenAPIOperation(props) {
|
|
|
17
17
|
icons: context.icons,
|
|
18
18
|
blockKey: context.blockKey,
|
|
19
19
|
};
|
|
20
|
-
var description =
|
|
20
|
+
var description = resolveDescription(operation);
|
|
21
21
|
return (<div className={clsx('openapi-operation', className)}>
|
|
22
|
-
<div className="openapi-summary"
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
<div className="openapi-summary">
|
|
23
|
+
{operation.summary
|
|
24
|
+
? context.renderHeading({
|
|
25
|
+
deprecated: (_a = operation.deprecated) !== null && _a !== void 0 ? _a : false,
|
|
26
|
+
title: operation.summary,
|
|
27
|
+
})
|
|
28
|
+
: null}
|
|
26
29
|
{operation.deprecated && <div className="openapi-deprecated">Deprecated</div>}
|
|
27
30
|
</div>
|
|
28
31
|
<div className="openapi-columns">
|
|
@@ -4,6 +4,6 @@ import type { OpenAPIClientContext } from './types';
|
|
|
4
4
|
* Display an interactive request body.
|
|
5
5
|
*/
|
|
6
6
|
export declare function OpenAPIRequestBody(props: {
|
|
7
|
-
requestBody: OpenAPIV3.RequestBodyObject;
|
|
7
|
+
requestBody: OpenAPIV3.RequestBodyObject | OpenAPIV3.ReferenceObject;
|
|
8
8
|
context: OpenAPIClientContext;
|
|
9
|
-
}): import("react").JSX.Element;
|
|
9
|
+
}): import("react").JSX.Element | null;
|
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
import { OpenAPIRootSchema } from './OpenAPISchema';
|
|
2
|
-
import { noReference } from './utils';
|
|
3
2
|
import { InteractiveSection } from './InteractiveSection';
|
|
3
|
+
import { checkIsReference } from './utils';
|
|
4
4
|
/**
|
|
5
5
|
* Display an interactive request body.
|
|
6
6
|
*/
|
|
7
7
|
export function OpenAPIRequestBody(props) {
|
|
8
8
|
var _a;
|
|
9
9
|
var requestBody = props.requestBody, context = props.context;
|
|
10
|
+
if (checkIsReference(requestBody)) {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
10
13
|
return (<InteractiveSection header="Body" className="openapi-requestbody" tabs={Object.entries((_a = requestBody.content) !== null && _a !== void 0 ? _a : {}).map(function (_a) {
|
|
11
14
|
var _b;
|
|
12
15
|
var contentType = _a[0], mediaTypeObject = _a[1];
|
|
13
16
|
return {
|
|
14
17
|
key: contentType,
|
|
15
18
|
label: contentType,
|
|
16
|
-
body: (<OpenAPIRootSchema schema={(_b =
|
|
19
|
+
body: (<OpenAPIRootSchema schema={(_b = mediaTypeObject.schema) !== null && _b !== void 0 ? _b : {}} context={context}/>),
|
|
17
20
|
};
|
|
18
21
|
})}/>);
|
|
19
22
|
}
|
package/dist/OpenAPIResponse.jsx
CHANGED
|
@@ -1,16 +1,26 @@
|
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
|
2
|
+
__assign = Object.assign || function(t) {
|
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
+
s = arguments[i];
|
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
+
t[p] = s[p];
|
|
7
|
+
}
|
|
8
|
+
return t;
|
|
9
|
+
};
|
|
10
|
+
return __assign.apply(this, arguments);
|
|
11
|
+
};
|
|
1
12
|
import { OpenAPISchemaProperties } from './OpenAPISchema';
|
|
2
|
-
import {
|
|
13
|
+
import { parameterToProperty, resolveDescription } from './utils';
|
|
3
14
|
import { OpenAPIDisclosure } from './OpenAPIDisclosure';
|
|
4
15
|
/**
|
|
5
16
|
* Display an interactive response body.
|
|
6
17
|
*/
|
|
7
18
|
export function OpenAPIResponse(props) {
|
|
8
|
-
var _a, _b
|
|
19
|
+
var _a, _b;
|
|
9
20
|
var response = props.response, context = props.context, mediaType = props.mediaType;
|
|
10
21
|
var headers = Object.entries((_a = response.headers) !== null && _a !== void 0 ? _a : {}).map(function (_a) {
|
|
11
|
-
var _b;
|
|
12
22
|
var name = _a[0], header = _a[1];
|
|
13
|
-
return [name,
|
|
23
|
+
return [name, header !== null && header !== void 0 ? header : {}];
|
|
14
24
|
});
|
|
15
25
|
var content = Object.entries((_b = mediaType.schema) !== null && _b !== void 0 ? _b : {});
|
|
16
26
|
var description = resolveDescription(response);
|
|
@@ -18,32 +28,14 @@ export function OpenAPIResponse(props) {
|
|
|
18
28
|
return null;
|
|
19
29
|
}
|
|
20
30
|
return (<div className="openapi-response-body">
|
|
21
|
-
{headers.length > 0 ? (<OpenAPIDisclosure context={context} label=
|
|
31
|
+
{headers.length > 0 ? (<OpenAPIDisclosure context={context} label="Headers">
|
|
22
32
|
<OpenAPISchemaProperties properties={headers.map(function (_a) {
|
|
23
|
-
var _b;
|
|
24
33
|
var name = _a[0], header = _a[1];
|
|
25
|
-
return ({
|
|
26
|
-
propertyName: name,
|
|
27
|
-
schema: (_b = noReference(header.schema)) !== null && _b !== void 0 ? _b : {},
|
|
28
|
-
required: header.required,
|
|
29
|
-
});
|
|
34
|
+
return parameterToProperty(__assign({ name: name }, header));
|
|
30
35
|
})} context={context}/>
|
|
31
36
|
</OpenAPIDisclosure>) : null}
|
|
32
37
|
<div className="openapi-responsebody">
|
|
33
|
-
<OpenAPISchemaProperties id={"response-".concat(context.blockKey)} properties={[
|
|
34
|
-
{
|
|
35
|
-
schema: (_c = handleUnresolvedReference(mediaType.schema)) !== null && _c !== void 0 ? _c : {},
|
|
36
|
-
},
|
|
37
|
-
]} context={context}/>
|
|
38
|
+
<OpenAPISchemaProperties id={"response-".concat(context.blockKey)} properties={mediaType.schema ? [{ schema: mediaType.schema }] : []} context={context}/>
|
|
38
39
|
</div>
|
|
39
40
|
</div>);
|
|
40
41
|
}
|
|
41
|
-
function handleUnresolvedReference(input) {
|
|
42
|
-
var isReference = checkIsReference(input);
|
|
43
|
-
if (isReference || input === undefined) {
|
|
44
|
-
// If we find a reference that wasn't resolved or needed to be resolved externally, do not try to render it.
|
|
45
|
-
// Instead we render `any`
|
|
46
|
-
return {};
|
|
47
|
-
}
|
|
48
|
-
return input;
|
|
49
|
-
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { generateSchemaExample } from './generateSchemaExample';
|
|
2
|
-
import { checkIsReference,
|
|
3
|
-
import { stringifyOpenAPI } from './stringifyOpenAPI';
|
|
2
|
+
import { checkIsReference, createStateKey, resolveDescription } from './utils';
|
|
4
3
|
import { OpenAPITabs, OpenAPITabsList, OpenAPITabsPanels } from './OpenAPITabs';
|
|
5
4
|
import { InteractiveSection } from './InteractiveSection';
|
|
5
|
+
import { json2xml } from './json2xml';
|
|
6
6
|
/**
|
|
7
7
|
* Display an example of the response content.
|
|
8
8
|
*/
|
|
@@ -31,78 +31,187 @@ export function OpenAPIResponseExample(props) {
|
|
|
31
31
|
}
|
|
32
32
|
return Number(a) - Number(b);
|
|
33
33
|
});
|
|
34
|
-
var
|
|
34
|
+
var tabs = responses
|
|
35
35
|
.map(function (_a) {
|
|
36
|
-
var key = _a[0],
|
|
37
|
-
var
|
|
38
|
-
|
|
39
|
-
var _a;
|
|
40
|
-
if (!responseObject.content) {
|
|
41
|
-
return null;
|
|
42
|
-
}
|
|
43
|
-
var key = Object.keys(responseObject.content)[0];
|
|
44
|
-
return ((_a = responseObject.content['application/json']) !== null && _a !== void 0 ? _a : (key ? responseObject.content[key] : null));
|
|
45
|
-
})();
|
|
46
|
-
if (!mediaTypeObject) {
|
|
36
|
+
var key = _a[0], responseObject = _a[1];
|
|
37
|
+
var description = resolveDescription(responseObject);
|
|
38
|
+
if (checkIsReference(responseObject)) {
|
|
47
39
|
return {
|
|
48
40
|
key: key,
|
|
49
41
|
label: key,
|
|
50
|
-
description:
|
|
42
|
+
description: description,
|
|
43
|
+
body: (<OpenAPIExample example={getExampleFromReference(responseObject)} context={context} syntax="json"/>),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
if (!responseObject.content || Object.keys(responseObject.content).length === 0) {
|
|
47
|
+
return {
|
|
48
|
+
key: key,
|
|
49
|
+
label: key,
|
|
50
|
+
description: description,
|
|
51
51
|
body: <OpenAPIEmptyResponseExample />,
|
|
52
52
|
};
|
|
53
53
|
}
|
|
54
|
-
var example = handleUnresolvedReference((function () {
|
|
55
|
-
var examples = mediaTypeObject.examples, example = mediaTypeObject.example;
|
|
56
|
-
if (examples) {
|
|
57
|
-
var key_1 = Object.keys(examples)[0];
|
|
58
|
-
if (key_1) {
|
|
59
|
-
// @TODO handle multiple examples
|
|
60
|
-
var firstExample = noReference(examples[key_1]);
|
|
61
|
-
if (firstExample) {
|
|
62
|
-
return firstExample;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
if (example) {
|
|
67
|
-
return { value: example };
|
|
68
|
-
}
|
|
69
|
-
var schema = noReference(mediaTypeObject.schema);
|
|
70
|
-
if (!schema) {
|
|
71
|
-
return null;
|
|
72
|
-
}
|
|
73
|
-
return { value: generateSchemaExample(schema) };
|
|
74
|
-
})());
|
|
75
54
|
return {
|
|
76
55
|
key: key,
|
|
77
56
|
label: key,
|
|
78
57
|
description: resolveDescription(responseObject),
|
|
79
|
-
body:
|
|
80
|
-
? example.value
|
|
81
|
-
: stringifyOpenAPI(example.value, null, 2)} syntax="json"/>) : (<OpenAPIEmptyResponseExample />),
|
|
58
|
+
body: <OpenAPIResponse context={context} content={responseObject.content}/>,
|
|
82
59
|
};
|
|
83
60
|
})
|
|
84
61
|
.filter(function (val) {
|
|
85
62
|
return Boolean(val);
|
|
86
63
|
});
|
|
87
|
-
if (
|
|
64
|
+
if (tabs.length === 0) {
|
|
88
65
|
return null;
|
|
89
66
|
}
|
|
90
|
-
return (<OpenAPITabs items={
|
|
67
|
+
return (<OpenAPITabs stateKey={createStateKey('response-example')} items={tabs}>
|
|
91
68
|
<InteractiveSection header={<OpenAPITabsList />} className="openapi-response-example">
|
|
92
69
|
<OpenAPITabsPanels />
|
|
93
70
|
</InteractiveSection>
|
|
94
71
|
</OpenAPITabs>);
|
|
95
72
|
}
|
|
73
|
+
function OpenAPIResponse(props) {
|
|
74
|
+
var context = props.context, content = props.content;
|
|
75
|
+
var entries = Object.entries(content);
|
|
76
|
+
var firstEntry = entries[0];
|
|
77
|
+
if (!firstEntry) {
|
|
78
|
+
throw new Error('One media type is required');
|
|
79
|
+
}
|
|
80
|
+
if (entries.length === 1) {
|
|
81
|
+
var mediaType = firstEntry[0], mediaTypeObject = firstEntry[1];
|
|
82
|
+
return (<OpenAPIResponseMediaType context={context} mediaType={mediaType} mediaTypeObject={mediaTypeObject}/>);
|
|
83
|
+
}
|
|
84
|
+
var tabs = entries.map(function (entry) {
|
|
85
|
+
var mediaType = entry[0], mediaTypeObject = entry[1];
|
|
86
|
+
return {
|
|
87
|
+
key: mediaType,
|
|
88
|
+
label: mediaType,
|
|
89
|
+
body: (<OpenAPIResponseMediaType context={context} mediaType={mediaType} mediaTypeObject={mediaTypeObject}/>),
|
|
90
|
+
};
|
|
91
|
+
});
|
|
92
|
+
return (<OpenAPITabs stateKey={createStateKey('response-media-types')} items={tabs}>
|
|
93
|
+
<InteractiveSection header={<OpenAPITabsList />} className="openapi-response-media-types">
|
|
94
|
+
<OpenAPITabsPanels />
|
|
95
|
+
</InteractiveSection>
|
|
96
|
+
</OpenAPITabs>);
|
|
97
|
+
}
|
|
98
|
+
function OpenAPIResponseMediaType(props) {
|
|
99
|
+
var mediaTypeObject = props.mediaTypeObject, mediaType = props.mediaType;
|
|
100
|
+
var examples = getExamplesFromMediaTypeObject({ mediaTypeObject: mediaTypeObject, mediaType: mediaType });
|
|
101
|
+
var syntax = getSyntaxFromMediaType(mediaType);
|
|
102
|
+
var firstExample = examples[0];
|
|
103
|
+
if (!firstExample) {
|
|
104
|
+
return <OpenAPIEmptyResponseExample />;
|
|
105
|
+
}
|
|
106
|
+
if (examples.length === 1) {
|
|
107
|
+
return (<OpenAPIExample example={firstExample.example} context={props.context} syntax={syntax}/>);
|
|
108
|
+
}
|
|
109
|
+
var tabs = examples.map(function (example) {
|
|
110
|
+
return {
|
|
111
|
+
key: example.key,
|
|
112
|
+
label: example.example.summary || example.key,
|
|
113
|
+
body: (<OpenAPIExample example={firstExample.example} context={props.context} syntax={syntax}/>),
|
|
114
|
+
};
|
|
115
|
+
});
|
|
116
|
+
return (<OpenAPITabs stateKey={createStateKey('response-media-type-examples')} items={tabs}>
|
|
117
|
+
<InteractiveSection header={<OpenAPITabsList />} className="openapi-response-media-type-examples">
|
|
118
|
+
<OpenAPITabsPanels />
|
|
119
|
+
</InteractiveSection>
|
|
120
|
+
</OpenAPITabs>);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Display an example.
|
|
124
|
+
*/
|
|
125
|
+
function OpenAPIExample(props) {
|
|
126
|
+
var example = props.example, context = props.context, syntax = props.syntax;
|
|
127
|
+
var code = stringifyExample({ example: example, xml: syntax === 'xml' });
|
|
128
|
+
if (code === null) {
|
|
129
|
+
return <OpenAPIEmptyResponseExample />;
|
|
130
|
+
}
|
|
131
|
+
return <context.CodeBlock code={code} syntax={syntax}/>;
|
|
132
|
+
}
|
|
133
|
+
function stringifyExample(args) {
|
|
134
|
+
var example = args.example, xml = args.xml;
|
|
135
|
+
if (!example.value) {
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
if (typeof example.value === 'string') {
|
|
139
|
+
return example.value;
|
|
140
|
+
}
|
|
141
|
+
if (xml) {
|
|
142
|
+
return json2xml(example.value);
|
|
143
|
+
}
|
|
144
|
+
return JSON.stringify(example.value, null, 2);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Get the syntax from a media type.
|
|
148
|
+
*/
|
|
149
|
+
function getSyntaxFromMediaType(mediaType) {
|
|
150
|
+
if (mediaType.includes('json')) {
|
|
151
|
+
return 'json';
|
|
152
|
+
}
|
|
153
|
+
if (mediaType === 'application/xml') {
|
|
154
|
+
return 'xml';
|
|
155
|
+
}
|
|
156
|
+
return 'text';
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Get examples from a media type object.
|
|
160
|
+
*/
|
|
161
|
+
function getExamplesFromMediaTypeObject(args) {
|
|
162
|
+
var _a;
|
|
163
|
+
var _b, _c;
|
|
164
|
+
var mediaTypeObject = args.mediaTypeObject, mediaType = args.mediaType;
|
|
165
|
+
if (mediaTypeObject.examples) {
|
|
166
|
+
return Object.entries(mediaTypeObject.examples).map(function (_a) {
|
|
167
|
+
var key = _a[0], example = _a[1];
|
|
168
|
+
return {
|
|
169
|
+
key: key,
|
|
170
|
+
example: checkIsReference(example) ? getExampleFromReference(example) : example,
|
|
171
|
+
};
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
if (mediaTypeObject.example) {
|
|
175
|
+
return [{ key: 'default', example: { value: mediaTypeObject.example } }];
|
|
176
|
+
}
|
|
177
|
+
if (mediaTypeObject.schema) {
|
|
178
|
+
if (mediaType === 'application/xml') {
|
|
179
|
+
// @TODO normally we should use the name of the schema but we don't have it
|
|
180
|
+
// fix it when we got the reference name
|
|
181
|
+
var root = (_c = (_b = mediaTypeObject.schema.xml) === null || _b === void 0 ? void 0 : _b.name) !== null && _c !== void 0 ? _c : 'object';
|
|
182
|
+
return [
|
|
183
|
+
{
|
|
184
|
+
key: 'default',
|
|
185
|
+
example: {
|
|
186
|
+
value: (_a = {},
|
|
187
|
+
_a[root] = generateSchemaExample(mediaTypeObject.schema, {
|
|
188
|
+
xml: mediaType === 'application/xml',
|
|
189
|
+
}),
|
|
190
|
+
_a),
|
|
191
|
+
},
|
|
192
|
+
},
|
|
193
|
+
];
|
|
194
|
+
}
|
|
195
|
+
return [
|
|
196
|
+
{
|
|
197
|
+
key: 'default',
|
|
198
|
+
example: { value: generateSchemaExample(mediaTypeObject.schema) },
|
|
199
|
+
},
|
|
200
|
+
];
|
|
201
|
+
}
|
|
202
|
+
return [];
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Empty response example.
|
|
206
|
+
*/
|
|
96
207
|
function OpenAPIEmptyResponseExample() {
|
|
97
208
|
return (<pre className="openapi-response-example-empty">
|
|
98
209
|
<p>No body</p>
|
|
99
210
|
</pre>);
|
|
100
211
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}
|
|
107
|
-
return input;
|
|
212
|
+
/**
|
|
213
|
+
* Generate an example from a reference object.
|
|
214
|
+
*/
|
|
215
|
+
function getExampleFromReference(ref) {
|
|
216
|
+
return { summary: 'Unresolved reference', value: { $ref: ref.$ref } };
|
|
108
217
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { createStateKey, resolveDescription } from './utils';
|
|
2
1
|
import { OpenAPIResponse } from './OpenAPIResponse';
|
|
3
2
|
import { InteractiveSection } from './InteractiveSection';
|
|
4
3
|
import { OpenAPIDisclosureGroup } from './OpenAPIDisclosureGroup';
|
|
@@ -8,12 +7,12 @@ import { Markdown } from './Markdown';
|
|
|
8
7
|
*/
|
|
9
8
|
export function OpenAPIResponses(props) {
|
|
10
9
|
var responses = props.responses, context = props.context;
|
|
11
|
-
return (<InteractiveSection
|
|
10
|
+
return (<InteractiveSection header="Responses" className="openapi-responses">
|
|
12
11
|
<OpenAPIDisclosureGroup allowsMultipleExpanded icon={context.icons.chevronRight} groups={Object.entries(responses).map(function (_a) {
|
|
13
12
|
var _b;
|
|
14
13
|
var statusCode = _a[0], response = _a[1];
|
|
15
14
|
var content = Object.entries((_b = response.content) !== null && _b !== void 0 ? _b : {});
|
|
16
|
-
var description =
|
|
15
|
+
var description = response.description;
|
|
17
16
|
return {
|
|
18
17
|
id: statusCode,
|
|
19
18
|
label: (<div className="openapi-response-tab-content" key={"response-".concat(statusCode)}>
|
package/dist/OpenAPISchema.d.ts
CHANGED
|
@@ -2,8 +2,8 @@ import type { OpenAPIV3 } from '@gitbook/openapi-parser';
|
|
|
2
2
|
import type { OpenAPIClientContext } from './types';
|
|
3
3
|
type CircularRefsIds = Map<OpenAPIV3.SchemaObject, string>;
|
|
4
4
|
export interface OpenAPISchemaPropertyEntry {
|
|
5
|
-
propertyName?: string;
|
|
6
|
-
required?: boolean;
|
|
5
|
+
propertyName?: string | undefined;
|
|
6
|
+
required?: boolean | undefined;
|
|
7
7
|
schema: OpenAPIV3.SchemaObject;
|
|
8
8
|
}
|
|
9
9
|
/**
|