@gitbook/react-openapi 1.1.6 → 1.1.8
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 +25 -0
- package/dist/InteractiveSection.d.ts +0 -2
- package/dist/InteractiveSection.jsx +3 -4
- package/dist/OpenAPICodeSample.jsx +4 -4
- package/dist/OpenAPICodeSampleInteractive.d.ts +4 -3
- package/dist/OpenAPICodeSampleInteractive.jsx +22 -15
- package/dist/OpenAPICopyButton.d.ts +7 -0
- package/dist/OpenAPICopyButton.jsx +6 -6
- package/dist/OpenAPIOperation.jsx +21 -1
- package/dist/OpenAPIPath.jsx +2 -2
- package/dist/OpenAPIRequestBody.jsx +1 -1
- package/dist/OpenAPIResponse.jsx +1 -1
- package/dist/OpenAPIResponses.jsx +2 -2
- package/dist/OpenAPISchema.d.ts +5 -14
- package/dist/OpenAPISchema.jsx +79 -28
- package/dist/OpenAPISchemaName.jsx +1 -0
- package/dist/OpenAPISchemaServer.d.ts +12 -0
- package/dist/OpenAPISchemaServer.jsx +8 -0
- package/dist/OpenAPISpec.d.ts +0 -6
- package/dist/OpenAPISpec.jsx +5 -11
- package/dist/OpenAPITabs.jsx +3 -11
- package/dist/code-samples.js +44 -9
- package/dist/decycle.d.ts +2 -0
- package/dist/decycle.js +70 -0
- package/dist/schemas/OpenAPISchemas.d.ts +4 -0
- package/dist/schemas/OpenAPISchemas.jsx +6 -6
- package/dist/schemas/resolveOpenAPISchemas.d.ts +2 -6
- package/dist/schemas/resolveOpenAPISchemas.js +1 -21
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/types.d.ts +2 -5
- package/package.json +1 -1
- package/src/InteractiveSection.tsx +2 -6
- package/src/OpenAPICodeSample.tsx +16 -5
- package/src/OpenAPICodeSampleInteractive.tsx +53 -28
- package/src/OpenAPICopyButton.tsx +17 -4
- package/src/OpenAPIOperation.tsx +39 -2
- package/src/OpenAPIPath.tsx +2 -2
- package/src/OpenAPIRequestBody.tsx +1 -1
- package/src/OpenAPIResponse.tsx +4 -4
- package/src/OpenAPIResponses.tsx +1 -5
- package/src/OpenAPISchema.tsx +152 -58
- package/src/OpenAPISchemaName.tsx +3 -0
- package/src/OpenAPISchemaServer.tsx +34 -0
- package/src/OpenAPISpec.tsx +13 -11
- package/src/OpenAPITabs.tsx +3 -13
- package/src/code-samples.test.ts +69 -1
- package/src/code-samples.ts +45 -9
- package/src/decycle.ts +68 -0
- package/src/schemas/OpenAPISchemas.tsx +11 -6
- package/src/schemas/resolveOpenAPISchemas.ts +3 -31
- package/src/types.ts +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# @gitbook/react-openapi
|
|
2
2
|
|
|
3
|
+
## 1.1.8
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 7d0b422: Handle grouped OpenAPISchemas
|
|
8
|
+
|
|
9
|
+
## 1.1.7
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- bd35348: Fix missing alternative schemas
|
|
14
|
+
- ae78fc5: Fix XML in code sample
|
|
15
|
+
- 7bb37c7: Move filterSelectedOpenAPISchemas to @gitbook/openapi-parser
|
|
16
|
+
- 373183a: Safe parse OpenAPI JSON schema
|
|
17
|
+
- 1505ddb: Fix multiple request examples selector not showing
|
|
18
|
+
- 61db166: Add OpenAPI write-only indicator
|
|
19
|
+
- 5b1e01c: Support for x-stability property
|
|
20
|
+
- cd99ed5: Fix spec properties rendering and missing keys
|
|
21
|
+
- 813b2af: Support for x-enumDescriptions and x-gitbook-enum
|
|
22
|
+
- a25fded: Replace $ref with $reference in json-decycle
|
|
23
|
+
- Updated dependencies [7bb37c7]
|
|
24
|
+
- Updated dependencies [5b1e01c]
|
|
25
|
+
- Updated dependencies [813b2af]
|
|
26
|
+
- @gitbook/openapi-parser@2.1.2
|
|
27
|
+
|
|
3
28
|
## 1.1.6
|
|
4
29
|
|
|
5
30
|
### Patch Changes
|
|
@@ -23,8 +23,6 @@ export declare function InteractiveSection(props: {
|
|
|
23
23
|
defaultTab?: string;
|
|
24
24
|
/** Content of the header */
|
|
25
25
|
header?: React.ReactNode;
|
|
26
|
-
/** Body of the section */
|
|
27
|
-
children?: React.ReactNode;
|
|
28
26
|
/** Children to display within the container */
|
|
29
27
|
overlay?: React.ReactNode;
|
|
30
28
|
}): import("react").JSX.Element;
|
|
@@ -10,7 +10,7 @@ import { Section, SectionBody, SectionHeader, SectionHeaderContent } from './Sta
|
|
|
10
10
|
*/
|
|
11
11
|
export function InteractiveSection(props) {
|
|
12
12
|
var _a, _b, _c;
|
|
13
|
-
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,
|
|
13
|
+
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, overlay = props.overlay, _h = props.toggleIcon, toggleIcon = _h === void 0 ? '▶' : _h;
|
|
14
14
|
var _j = useState(defaultTab), selectedTabKey = _j[0], setSelectedTab = _j[1];
|
|
15
15
|
var selectedTab = (_b = tabs.find(function (tab) { return tab.key === selectedTabKey; })) !== null && _b !== void 0 ? _b : tabs[0];
|
|
16
16
|
var state = useDisclosureState({
|
|
@@ -28,7 +28,7 @@ export function InteractiveSection(props) {
|
|
|
28
28
|
}
|
|
29
29
|
}} className={className}>
|
|
30
30
|
<SectionHeaderContent className={className}>
|
|
31
|
-
{(
|
|
31
|
+
{(selectedTab === null || selectedTab === void 0 ? void 0 : selectedTab.body) && toggeable ? (<button {...mergeProps(buttonProps, focusProps)} ref={triggerRef} className={clsx('openapi-section-toggle', "".concat(className, "-toggle"))} style={{
|
|
32
32
|
outline: isFocusVisible
|
|
33
33
|
? '2px solid rgb(var(--primary-color-500) / 0.4)'
|
|
34
34
|
: 'none',
|
|
@@ -50,8 +50,7 @@ export function InteractiveSection(props) {
|
|
|
50
50
|
</select>) : null}
|
|
51
51
|
</div>
|
|
52
52
|
</SectionHeader>) : null}
|
|
53
|
-
{(!toggeable || state.isExpanded) && (
|
|
54
|
-
{children}
|
|
53
|
+
{(!toggeable || state.isExpanded) && (selectedTab === null || selectedTab === void 0 ? void 0 : selectedTab.body) ? (<SectionBody ref={panelRef} {...panelProps} className={className}>
|
|
55
54
|
{selectedTab === null || selectedTab === void 0 ? void 0 : selectedTab.body}
|
|
56
55
|
</SectionBody>) : null}
|
|
57
56
|
{overlay ? (<div className={clsx('openapi-section-overlay', "".concat(className, "-overlay"))}>
|
|
@@ -120,7 +120,7 @@ function generateCodeSamples(props) {
|
|
|
120
120
|
return {
|
|
121
121
|
key: "default-".concat(generator.id),
|
|
122
122
|
label: generator.label,
|
|
123
|
-
body: <OpenAPIMediaTypeExamplesBody data={data} renderers={renderers}
|
|
123
|
+
body: (<OpenAPIMediaTypeExamplesBody method={data.method} path={data.path} renderers={renderers}/>),
|
|
124
124
|
footer: (<OpenAPICodeSampleFooter renderers={renderers} data={data} context={context}/>),
|
|
125
125
|
};
|
|
126
126
|
}
|
|
@@ -145,15 +145,15 @@ function OpenAPICodeSampleFooter(props) {
|
|
|
145
145
|
var method = data.method, path = data.path;
|
|
146
146
|
var specUrl = context.specUrl;
|
|
147
147
|
var hideTryItPanel = data['x-hideTryItPanel'] || data.operation['x-hideTryItPanel'];
|
|
148
|
-
var
|
|
149
|
-
if (hideTryItPanel && !
|
|
148
|
+
var hasMultipleMediaTypes = renderers.length > 1 || renderers.some(function (renderer) { return renderer.examples.length > 0; });
|
|
149
|
+
if (hideTryItPanel && !hasMultipleMediaTypes) {
|
|
150
150
|
return null;
|
|
151
151
|
}
|
|
152
152
|
if (!validateHttpMethod(method)) {
|
|
153
153
|
return null;
|
|
154
154
|
}
|
|
155
155
|
return (<div className="openapi-codesample-footer">
|
|
156
|
-
{
|
|
156
|
+
{hasMultipleMediaTypes ? (<OpenAPIMediaTypeExamplesSelector method={data.method} path={data.path} renderers={renderers}/>) : (<span />)}
|
|
157
157
|
{!hideTryItPanel && <ScalarApiButton method={method} path={path} specUrl={specUrl}/>}
|
|
158
158
|
</div>);
|
|
159
159
|
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import type { MediaTypeRenderer } from './OpenAPICodeSample';
|
|
2
|
-
import type { OpenAPIOperationData } from './types';
|
|
3
2
|
export declare function OpenAPIMediaTypeExamplesSelector(props: {
|
|
4
|
-
|
|
3
|
+
method: string;
|
|
4
|
+
path: string;
|
|
5
5
|
renderers: MediaTypeRenderer[];
|
|
6
6
|
}): import("react").JSX.Element;
|
|
7
7
|
export declare function OpenAPIMediaTypeExamplesBody(props: {
|
|
8
|
-
|
|
8
|
+
method: string;
|
|
9
|
+
path: string;
|
|
9
10
|
renderers: MediaTypeRenderer[];
|
|
10
11
|
}): string | number | boolean | Iterable<import("react").ReactNode> | import("react").JSX.Element | null | undefined;
|
|
@@ -26,24 +26,31 @@ function useMediaTypeSampleIndexState(data, mediaType) {
|
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
28
|
export function OpenAPIMediaTypeExamplesSelector(props) {
|
|
29
|
-
var
|
|
29
|
+
var method = props.method, path = props.path, renderers = props.renderers;
|
|
30
30
|
if (!renderers[0]) {
|
|
31
31
|
throw new Error('No renderers provided');
|
|
32
32
|
}
|
|
33
|
-
var state = useMediaTypeState(
|
|
33
|
+
var state = useMediaTypeState({ method: method, path: path }, renderers[0].mediaType);
|
|
34
34
|
var selected = renderers.find(function (r) { return r.mediaType === state.mediaType; }) || renderers[0];
|
|
35
35
|
return (<div className="openapi-codesample-selectors">
|
|
36
|
-
<
|
|
37
|
-
|
|
38
|
-
{renderer.mediaType}
|
|
39
|
-
</option>); })}
|
|
40
|
-
</select>
|
|
41
|
-
<ExamplesSelector data={data} renderer={selected}/>
|
|
36
|
+
<MediaTypeSelector state={state} renderers={renderers}/>
|
|
37
|
+
<ExamplesSelector method={method} path={path} renderer={selected}/>
|
|
42
38
|
</div>);
|
|
43
39
|
}
|
|
40
|
+
function MediaTypeSelector(props) {
|
|
41
|
+
var renderers = props.renderers, state = props.state;
|
|
42
|
+
if (renderers.length < 2) {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
return (<select className={clsx('openapi-select')} value={state.mediaType} onChange={function (e) { return state.setMediaType(e.target.value); }}>
|
|
46
|
+
{renderers.map(function (renderer) { return (<option key={renderer.mediaType} value={renderer.mediaType}>
|
|
47
|
+
{renderer.mediaType}
|
|
48
|
+
</option>); })}
|
|
49
|
+
</select>);
|
|
50
|
+
}
|
|
44
51
|
function ExamplesSelector(props) {
|
|
45
|
-
var
|
|
46
|
-
var state = useMediaTypeSampleIndexState(
|
|
52
|
+
var method = props.method, path = props.path, renderer = props.renderer;
|
|
53
|
+
var state = useMediaTypeSampleIndexState({ method: method, path: path }, renderer.mediaType);
|
|
47
54
|
if (renderer.examples.length < 2) {
|
|
48
55
|
return null;
|
|
49
56
|
}
|
|
@@ -55,21 +62,21 @@ function ExamplesSelector(props) {
|
|
|
55
62
|
}
|
|
56
63
|
export function OpenAPIMediaTypeExamplesBody(props) {
|
|
57
64
|
var _a;
|
|
58
|
-
var renderers = props.renderers,
|
|
65
|
+
var renderers = props.renderers, method = props.method, path = props.path;
|
|
59
66
|
if (!renderers[0]) {
|
|
60
67
|
throw new Error('No renderers provided');
|
|
61
68
|
}
|
|
62
|
-
var mediaTypeState = useMediaTypeState(
|
|
69
|
+
var mediaTypeState = useMediaTypeState({ method: method, path: path }, renderers[0].mediaType);
|
|
63
70
|
var selected = (_a = renderers.find(function (r) { return r.mediaType === mediaTypeState.mediaType; })) !== null && _a !== void 0 ? _a : renderers[0];
|
|
64
71
|
if (selected.examples.length === 0) {
|
|
65
72
|
return selected.element;
|
|
66
73
|
}
|
|
67
|
-
return <ExamplesBody
|
|
74
|
+
return <ExamplesBody method={method} path={path} renderer={selected}/>;
|
|
68
75
|
}
|
|
69
76
|
function ExamplesBody(props) {
|
|
70
77
|
var _a;
|
|
71
|
-
var
|
|
72
|
-
var exampleState = useMediaTypeSampleIndexState(
|
|
78
|
+
var method = props.method, path = props.path, renderer = props.renderer;
|
|
79
|
+
var exampleState = useMediaTypeSampleIndexState({ method: method, path: path }, renderer.mediaType);
|
|
73
80
|
var example = (_a = renderer.examples[exampleState.index]) !== null && _a !== void 0 ? _a : renderer.examples[0];
|
|
74
81
|
if (!example) {
|
|
75
82
|
throw new Error("No example found for index ".concat(exampleState.index));
|
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
import { type ButtonProps } from 'react-aria-components';
|
|
2
2
|
export declare function OpenAPICopyButton(props: ButtonProps & {
|
|
3
3
|
value: string;
|
|
4
|
+
children: React.ReactNode;
|
|
5
|
+
label?: string;
|
|
6
|
+
/**
|
|
7
|
+
* Whether to show a tooltip.
|
|
8
|
+
* @default true
|
|
9
|
+
*/
|
|
10
|
+
withTooltip?: boolean;
|
|
4
11
|
}): import("react").JSX.Element;
|
|
@@ -2,10 +2,9 @@
|
|
|
2
2
|
import { useState } from 'react';
|
|
3
3
|
import { Button, Tooltip, TooltipTrigger } from 'react-aria-components';
|
|
4
4
|
export function OpenAPICopyButton(props) {
|
|
5
|
-
var value = props.value;
|
|
6
|
-
var
|
|
7
|
-
var
|
|
8
|
-
var _b = useState(false), isOpen = _b[0], setIsOpen = _b[1];
|
|
5
|
+
var value = props.value, label = props.label, children = props.children, onPress = props.onPress, className = props.className, _a = props.withTooltip, withTooltip = _a === void 0 ? true : _a;
|
|
6
|
+
var _b = useState(false), copied = _b[0], setCopied = _b[1];
|
|
7
|
+
var _c = useState(false), isOpen = _c[0], setIsOpen = _c[1];
|
|
9
8
|
var handleCopy = function () {
|
|
10
9
|
if (!value)
|
|
11
10
|
return;
|
|
@@ -14,10 +13,11 @@ export function OpenAPICopyButton(props) {
|
|
|
14
13
|
setCopied(true);
|
|
15
14
|
setTimeout(function () {
|
|
16
15
|
setCopied(false);
|
|
16
|
+
setIsOpen(false);
|
|
17
17
|
}, 2000);
|
|
18
18
|
});
|
|
19
19
|
};
|
|
20
|
-
return (<TooltipTrigger isOpen={isOpen} onOpenChange={setIsOpen} closeDelay={200} delay={200}>
|
|
20
|
+
return (<TooltipTrigger isOpen={isOpen} onOpenChange={setIsOpen} isDisabled={!withTooltip} closeDelay={200} delay={200}>
|
|
21
21
|
<Button type="button" preventFocusOnPress onPress={function (e) {
|
|
22
22
|
handleCopy();
|
|
23
23
|
onPress === null || onPress === void 0 ? void 0 : onPress(e);
|
|
@@ -26,7 +26,7 @@ export function OpenAPICopyButton(props) {
|
|
|
26
26
|
</Button>
|
|
27
27
|
|
|
28
28
|
<Tooltip isOpen={isOpen} onOpenChange={setIsOpen} placement="top" offset={4} className="openapi-tooltip">
|
|
29
|
-
{copied ? 'Copied' : 'Copy to clipboard'}
|
|
29
|
+
{copied ? 'Copied' : label || 'Copy to clipboard'}
|
|
30
30
|
</Tooltip>
|
|
31
31
|
</TooltipTrigger>);
|
|
32
32
|
}
|
|
@@ -19,14 +19,18 @@ export function OpenAPIOperation(props) {
|
|
|
19
19
|
};
|
|
20
20
|
return (<div className={clsx('openapi-operation', className)}>
|
|
21
21
|
<div className="openapi-summary" id={operation.summary ? undefined : context.id}>
|
|
22
|
+
{(operation.deprecated || operation['x-stability']) && (<div className="openapi-summary-tags">
|
|
23
|
+
{operation.deprecated && (<div className="openapi-deprecated">Deprecated</div>)}
|
|
24
|
+
{operation['x-stability'] && (<OpenAPIOperationStability stability={operation['x-stability']}/>)}
|
|
25
|
+
</div>)}
|
|
22
26
|
{operation.summary
|
|
23
27
|
? context.renderHeading({
|
|
24
28
|
deprecated: (_a = operation.deprecated) !== null && _a !== void 0 ? _a : false,
|
|
29
|
+
stability: operation['x-stability'],
|
|
25
30
|
title: operation.summary,
|
|
26
31
|
})
|
|
27
32
|
: null}
|
|
28
33
|
<OpenAPIPath data={data} context={context}/>
|
|
29
|
-
{operation.deprecated && <div className="openapi-deprecated">Deprecated</div>}
|
|
30
34
|
</div>
|
|
31
35
|
<div className="openapi-columns">
|
|
32
36
|
<div className="openapi-column-spec">
|
|
@@ -66,3 +70,19 @@ function OpenAPIOperationDescription(props) {
|
|
|
66
70
|
<Markdown className="openapi-description" source={description}/>
|
|
67
71
|
</div>);
|
|
68
72
|
}
|
|
73
|
+
var stabilityEnum = {
|
|
74
|
+
experimental: 'Experimental',
|
|
75
|
+
alpha: 'Alpha',
|
|
76
|
+
beta: 'Beta',
|
|
77
|
+
stable: 'Stable',
|
|
78
|
+
};
|
|
79
|
+
function OpenAPIOperationStability(props) {
|
|
80
|
+
var stability = props.stability;
|
|
81
|
+
var foundStability = stabilityEnum[stability];
|
|
82
|
+
if (!foundStability) {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
return (<div className={"openapi-stability openapi-stability-".concat(foundStability.toLowerCase())}>
|
|
86
|
+
{foundStability}
|
|
87
|
+
</div>);
|
|
88
|
+
}
|
package/dist/OpenAPIPath.jsx
CHANGED
|
@@ -30,7 +30,7 @@ function formatPath(path) {
|
|
|
30
30
|
if (offset > lastIndex) {
|
|
31
31
|
parts.push(path.slice(lastIndex, offset));
|
|
32
32
|
}
|
|
33
|
-
parts.push(<span key={offset} className="openapi-path-variable">
|
|
33
|
+
parts.push(<span key={"offset-".concat(offset)} className="openapi-path-variable">
|
|
34
34
|
{match}
|
|
35
35
|
</span>);
|
|
36
36
|
lastIndex = offset + match.length;
|
|
@@ -41,7 +41,7 @@ function formatPath(path) {
|
|
|
41
41
|
}
|
|
42
42
|
var formattedPath = parts.map(function (part, index) {
|
|
43
43
|
if (typeof part === 'string') {
|
|
44
|
-
return <span key={index}>{part}</span>;
|
|
44
|
+
return <span key={"part-".concat(index)}>{part}</span>;
|
|
45
45
|
}
|
|
46
46
|
return part;
|
|
47
47
|
});
|
package/dist/OpenAPIResponse.jsx
CHANGED
|
@@ -10,7 +10,7 @@ var __assign = (this && this.__assign) || function () {
|
|
|
10
10
|
return __assign.apply(this, arguments);
|
|
11
11
|
};
|
|
12
12
|
import { OpenAPIDisclosure } from './OpenAPIDisclosure';
|
|
13
|
-
import { OpenAPISchemaProperties } from './
|
|
13
|
+
import { OpenAPISchemaProperties } from './OpenAPISchemaServer';
|
|
14
14
|
import { parameterToProperty, resolveDescription } from './utils';
|
|
15
15
|
/**
|
|
16
16
|
* Display an interactive response body.
|
|
@@ -15,7 +15,7 @@ export function OpenAPIResponses(props) {
|
|
|
15
15
|
var description = response.description;
|
|
16
16
|
return {
|
|
17
17
|
id: statusCode,
|
|
18
|
-
label: (<div className="openapi-response-tab-content"
|
|
18
|
+
label: (<div className="openapi-response-tab-content">
|
|
19
19
|
<span className="openapi-response-statuscode">
|
|
20
20
|
{statusCode}
|
|
21
21
|
</span>
|
|
@@ -26,7 +26,7 @@ export function OpenAPIResponses(props) {
|
|
|
26
26
|
return ({
|
|
27
27
|
id: contentType,
|
|
28
28
|
label: contentType,
|
|
29
|
-
body: (<OpenAPIResponse
|
|
29
|
+
body: (<OpenAPIResponse response={response} mediaType={mediaType} context={context}/>),
|
|
30
30
|
});
|
|
31
31
|
}),
|
|
32
32
|
};
|
package/dist/OpenAPISchema.d.ts
CHANGED
|
@@ -1,29 +1,20 @@
|
|
|
1
1
|
import type { OpenAPIV3 } from '@gitbook/openapi-parser';
|
|
2
2
|
import type { OpenAPIClientContext } from './types';
|
|
3
|
-
|
|
4
|
-
interface OpenAPISchemaPropertyEntry {
|
|
3
|
+
export interface OpenAPISchemaPropertyEntry {
|
|
5
4
|
propertyName?: string | undefined;
|
|
6
5
|
required?: boolean | undefined;
|
|
7
6
|
schema: OpenAPIV3.SchemaObject;
|
|
8
7
|
}
|
|
9
|
-
|
|
10
|
-
* Render a set of properties of an OpenAPI schema.
|
|
11
|
-
*/
|
|
12
|
-
export declare function OpenAPISchemaProperties(props: {
|
|
8
|
+
export declare function OpenAPISchemaPropertiesFromServer(props: {
|
|
13
9
|
id?: string;
|
|
14
|
-
properties:
|
|
15
|
-
circularRefs?: CircularRefsIds;
|
|
10
|
+
properties: string;
|
|
16
11
|
context: OpenAPIClientContext;
|
|
17
12
|
}): import("react").JSX.Element;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
*/
|
|
21
|
-
export declare function OpenAPIRootSchema(props: {
|
|
22
|
-
schema: OpenAPIV3.SchemaObject;
|
|
13
|
+
export declare function OpenAPIRootSchemaFromServer(props: {
|
|
14
|
+
schema: string;
|
|
23
15
|
context: OpenAPIClientContext;
|
|
24
16
|
}): import("react").JSX.Element;
|
|
25
17
|
/**
|
|
26
18
|
* Get the alternatives to display for a schema.
|
|
27
19
|
*/
|
|
28
20
|
export declare function getSchemaAlternatives(schema: OpenAPIV3.SchemaObject, ancestors?: Set<OpenAPIV3.SchemaObject>): OpenAPIV3.SchemaObject[] | null;
|
|
29
|
-
export {};
|
package/dist/OpenAPISchema.jsx
CHANGED
|
@@ -1,55 +1,74 @@
|
|
|
1
|
+
'use client';
|
|
1
2
|
import { useId } from 'react';
|
|
2
3
|
import clsx from 'clsx';
|
|
3
4
|
import { Markdown } from './Markdown';
|
|
5
|
+
import { OpenAPICopyButton } from './OpenAPICopyButton';
|
|
4
6
|
import { OpenAPIDisclosure } from './OpenAPIDisclosure';
|
|
5
7
|
import { OpenAPISchemaName } from './OpenAPISchemaName';
|
|
8
|
+
import { retrocycle } from './decycle';
|
|
6
9
|
import { checkIsReference, resolveDescription, resolveFirstExample } from './utils';
|
|
7
10
|
/**
|
|
8
11
|
* Render a property of an OpenAPI schema.
|
|
9
12
|
*/
|
|
10
13
|
function OpenAPISchemaProperty(props) {
|
|
11
|
-
var
|
|
14
|
+
var parentCircularRefs = props.circularRefs, context = props.context, className = props.className, property = props.property;
|
|
12
15
|
var schema = property.schema;
|
|
13
16
|
var id = useId();
|
|
14
17
|
return (<div id={id} className={clsx('openapi-schema', className)}>
|
|
15
18
|
<OpenAPISchemaPresentation property={property}/>
|
|
16
19
|
{(function () {
|
|
17
|
-
var
|
|
20
|
+
var circularRefId = parentCircularRefs.get(schema);
|
|
18
21
|
// Avoid recursing infinitely, and instead render a link to the parent schema
|
|
19
|
-
if (
|
|
20
|
-
return <OpenAPISchemaCircularRef id={
|
|
22
|
+
if (circularRefId) {
|
|
23
|
+
return <OpenAPISchemaCircularRef id={circularRefId} schema={schema}/>;
|
|
21
24
|
}
|
|
22
|
-
var circularRefs = parentCircularRefs
|
|
25
|
+
var circularRefs = new Map(parentCircularRefs);
|
|
26
|
+
circularRefs.set(schema, id);
|
|
23
27
|
var properties = getSchemaProperties(schema);
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
if (properties === null || properties === void 0 ? void 0 : properties.length) {
|
|
29
|
+
return (<OpenAPIDisclosure context={context} label={getDisclosureLabel(schema)}>
|
|
30
|
+
<OpenAPISchemaProperties properties={properties} circularRefs={circularRefs} context={context}/>
|
|
31
|
+
</OpenAPIDisclosure>);
|
|
32
|
+
}
|
|
33
|
+
var ancestors = new Set(circularRefs.keys());
|
|
34
|
+
var alternatives = getSchemaAlternatives(schema, ancestors);
|
|
35
|
+
if (alternatives) {
|
|
36
|
+
return alternatives.map(function (schema, index) { return (<OpenAPISchemaAlternative key={index} schema={schema} circularRefs={circularRefs} context={context}/>); });
|
|
37
|
+
}
|
|
38
|
+
return null;
|
|
31
39
|
})()}
|
|
32
40
|
</div>);
|
|
33
41
|
}
|
|
34
42
|
/**
|
|
35
43
|
* Render a set of properties of an OpenAPI schema.
|
|
36
44
|
*/
|
|
37
|
-
|
|
38
|
-
var id = props.id, properties = props.properties,
|
|
45
|
+
function OpenAPISchemaProperties(props) {
|
|
46
|
+
var id = props.id, properties = props.properties, _a = props.circularRefs, circularRefs = _a === void 0 ? new Map() : _a, context = props.context;
|
|
39
47
|
return (<div id={id} className="openapi-schema-properties">
|
|
40
|
-
{properties.map(function (property, index) {
|
|
48
|
+
{properties.map(function (property, index) {
|
|
49
|
+
return (<OpenAPISchemaProperty key={index} circularRefs={circularRefs} property={property} context={context}/>);
|
|
50
|
+
})}
|
|
41
51
|
</div>);
|
|
42
52
|
}
|
|
53
|
+
export function OpenAPISchemaPropertiesFromServer(props) {
|
|
54
|
+
return (<OpenAPISchemaProperties id={props.id} properties={JSON.parse(props.properties, retrocycle())} context={props.context}/>);
|
|
55
|
+
}
|
|
43
56
|
/**
|
|
44
57
|
* Render a root schema (such as the request body or response body).
|
|
45
58
|
*/
|
|
46
|
-
|
|
47
|
-
var schema = props.schema, context = props.context;
|
|
59
|
+
function OpenAPIRootSchema(props) {
|
|
60
|
+
var schema = props.schema, context = props.context, _a = props.circularRefs, parentCircularRefs = _a === void 0 ? new Map() : _a;
|
|
61
|
+
var id = useId();
|
|
48
62
|
var properties = getSchemaProperties(schema);
|
|
49
63
|
if (properties === null || properties === void 0 ? void 0 : properties.length) {
|
|
50
|
-
|
|
64
|
+
var circularRefs = new Map(parentCircularRefs);
|
|
65
|
+
circularRefs.set(schema, id);
|
|
66
|
+
return (<OpenAPISchemaProperties properties={properties} circularRefs={circularRefs} context={context}/>);
|
|
51
67
|
}
|
|
52
|
-
return (<OpenAPISchemaProperty className="openapi-schema-root" property={{ schema: schema }} context={context}/>);
|
|
68
|
+
return (<OpenAPISchemaProperty className="openapi-schema-root" property={{ schema: schema }} context={context} circularRefs={parentCircularRefs}/>);
|
|
69
|
+
}
|
|
70
|
+
export function OpenAPIRootSchemaFromServer(props) {
|
|
71
|
+
return (<OpenAPIRootSchema schema={JSON.parse(props.schema, retrocycle())} context={props.context}/>);
|
|
53
72
|
}
|
|
54
73
|
/**
|
|
55
74
|
* Render a tab for an alternative schema.
|
|
@@ -81,15 +100,47 @@ function OpenAPISchemaCircularRef(props) {
|
|
|
81
100
|
* Render the enum value for a schema.
|
|
82
101
|
*/
|
|
83
102
|
function OpenAPISchemaEnum(props) {
|
|
84
|
-
var
|
|
103
|
+
var schema = props.schema;
|
|
104
|
+
var enumValues = (function () {
|
|
105
|
+
var _a;
|
|
106
|
+
// Render x-gitbook-enum first, as it has a different format
|
|
107
|
+
if (schema['x-gitbook-enum']) {
|
|
108
|
+
return Object.entries(schema['x-gitbook-enum']).map(function (_a) {
|
|
109
|
+
var name = _a[0], description = _a[1].description;
|
|
110
|
+
return {
|
|
111
|
+
value: name,
|
|
112
|
+
description: description,
|
|
113
|
+
};
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
if (schema['x-enumDescriptions']) {
|
|
117
|
+
return Object.entries(schema['x-enumDescriptions']).map(function (_a) {
|
|
118
|
+
var value = _a[0], description = _a[1];
|
|
119
|
+
return {
|
|
120
|
+
value: value,
|
|
121
|
+
description: description,
|
|
122
|
+
};
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
return (_a = schema.enum) === null || _a === void 0 ? void 0 : _a.map(function (value) {
|
|
126
|
+
return {
|
|
127
|
+
value: value,
|
|
128
|
+
description: undefined,
|
|
129
|
+
};
|
|
130
|
+
});
|
|
131
|
+
})();
|
|
132
|
+
if (!(enumValues === null || enumValues === void 0 ? void 0 : enumValues.length)) {
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
85
135
|
return (<div className="openapi-schema-enum">
|
|
86
|
-
<span>
|
|
87
|
-
|
|
88
|
-
{enumValues.map(function (
|
|
89
|
-
<
|
|
90
|
-
|
|
136
|
+
<span>Available options:</span>
|
|
137
|
+
<div className="openapi-schema-enum-list">
|
|
138
|
+
{enumValues.map(function (item, index) { return (<span key={index} className="openapi-schema-enum-value">
|
|
139
|
+
<OpenAPICopyButton value={item.value} label={item.description} withTooltip={!!item.description}>
|
|
140
|
+
<code>{"".concat(item.value)}</code>
|
|
141
|
+
</OpenAPICopyButton>
|
|
91
142
|
</span>); })}
|
|
92
|
-
</
|
|
143
|
+
</div>
|
|
93
144
|
</div>);
|
|
94
145
|
}
|
|
95
146
|
/**
|
|
@@ -114,7 +165,7 @@ function OpenAPISchemaPresentation(props) {
|
|
|
114
165
|
{schema.pattern ? (<div className="openapi-schema-pattern">
|
|
115
166
|
Pattern: <code>{schema.pattern}</code>
|
|
116
167
|
</div>) : null}
|
|
117
|
-
|
|
168
|
+
<OpenAPISchemaEnum schema={schema}/>
|
|
118
169
|
</div>);
|
|
119
170
|
}
|
|
120
171
|
/**
|
|
@@ -208,7 +259,7 @@ function getSchemaTitle(schema) {
|
|
|
208
259
|
var _a;
|
|
209
260
|
// Otherwise try to infer a nice title
|
|
210
261
|
var type = 'any';
|
|
211
|
-
if (schema.enum) {
|
|
262
|
+
if (schema.enum || schema['x-enumDescriptions'] || schema['x-gitbook-enum']) {
|
|
212
263
|
type = "".concat(schema.type, " \u00B7 enum");
|
|
213
264
|
// check array AND schema.items as this is sometimes null despite what the type indicates
|
|
214
265
|
}
|
|
@@ -15,6 +15,7 @@ export function OpenAPISchemaName(props) {
|
|
|
15
15
|
{additionalItems ? (<span className="openapi-schema-type">{additionalItems}</span>) : null}
|
|
16
16
|
</span>
|
|
17
17
|
{(schema === null || schema === void 0 ? void 0 : schema.readOnly) ? <span className="openapi-schema-readonly">read-only</span> : null}
|
|
18
|
+
{(schema === null || schema === void 0 ? void 0 : schema.writeOnly) ? (<span className="openapi-schema-writeonly">write-only</span>) : null}
|
|
18
19
|
{required ? (<span className="openapi-schema-required">required</span>) : (<span className="openapi-schema-optional">optional</span>)}
|
|
19
20
|
{(schema === null || schema === void 0 ? void 0 : schema.deprecated) ? <span className="openapi-deprecated">Deprecated</span> : null}
|
|
20
21
|
</div>);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { OpenAPIV3 } from '@gitbook/openapi-parser';
|
|
2
|
+
import { type OpenAPISchemaPropertyEntry } from './OpenAPISchema';
|
|
3
|
+
import type { OpenAPIClientContext } from './types';
|
|
4
|
+
export declare function OpenAPISchemaProperties(props: {
|
|
5
|
+
id?: string;
|
|
6
|
+
properties: OpenAPISchemaPropertyEntry[];
|
|
7
|
+
context: OpenAPIClientContext;
|
|
8
|
+
}): import("react").JSX.Element;
|
|
9
|
+
export declare function OpenAPIRootSchema(props: {
|
|
10
|
+
schema: OpenAPIV3.SchemaObject;
|
|
11
|
+
context: OpenAPIClientContext;
|
|
12
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { OpenAPIRootSchemaFromServer, OpenAPISchemaPropertiesFromServer, } from './OpenAPISchema';
|
|
2
|
+
import { decycle } from './decycle';
|
|
3
|
+
export function OpenAPISchemaProperties(props) {
|
|
4
|
+
return (<OpenAPISchemaPropertiesFromServer id={props.id} properties={JSON.stringify(props.properties, decycle())} context={props.context}/>);
|
|
5
|
+
}
|
|
6
|
+
export function OpenAPIRootSchema(props) {
|
|
7
|
+
return (<OpenAPIRootSchemaFromServer schema={JSON.stringify(props.schema, decycle())} context={props.context}/>);
|
|
8
|
+
}
|
package/dist/OpenAPISpec.d.ts
CHANGED
|
@@ -1,10 +1,4 @@
|
|
|
1
1
|
import type { OpenAPIClientContext, OpenAPIOperationData } from './types';
|
|
2
|
-
/**
|
|
3
|
-
* Client component to render the spec for the request and response.
|
|
4
|
-
*
|
|
5
|
-
* We use a client component as rendering recursive JSON schema in the server is expensive
|
|
6
|
-
* (the entire schema is rendered at once, while the client component only renders the visible part)
|
|
7
|
-
*/
|
|
8
2
|
export declare function OpenAPISpec(props: {
|
|
9
3
|
data: OpenAPIOperationData;
|
|
10
4
|
context: OpenAPIClientContext;
|
package/dist/OpenAPISpec.jsx
CHANGED
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
import { OpenAPIRequestBody } from './OpenAPIRequestBody';
|
|
2
2
|
import { OpenAPIResponses } from './OpenAPIResponses';
|
|
3
|
-
import { OpenAPISchemaProperties } from './
|
|
3
|
+
import { OpenAPISchemaProperties } from './OpenAPISchemaServer';
|
|
4
4
|
import { OpenAPISecurities } from './OpenAPISecurities';
|
|
5
5
|
import { StaticSection } from './StaticSection';
|
|
6
6
|
import { parameterToProperty } from './utils';
|
|
7
|
-
/**
|
|
8
|
-
* Client component to render the spec for the request and response.
|
|
9
|
-
*
|
|
10
|
-
* We use a client component as rendering recursive JSON schema in the server is expensive
|
|
11
|
-
* (the entire schema is rendered at once, while the client component only renders the visible part)
|
|
12
|
-
*/
|
|
13
7
|
export function OpenAPISpec(props) {
|
|
14
8
|
var _a;
|
|
15
9
|
var data = props.data, context = props.context;
|
|
@@ -17,16 +11,16 @@ export function OpenAPISpec(props) {
|
|
|
17
11
|
var parameters = (_a = operation.parameters) !== null && _a !== void 0 ? _a : [];
|
|
18
12
|
var parameterGroups = groupParameters(parameters);
|
|
19
13
|
return (<>
|
|
20
|
-
{securities.length > 0 ? (<OpenAPISecurities securities={securities} context={context}/>) : null}
|
|
14
|
+
{securities.length > 0 ? (<OpenAPISecurities key="securities" securities={securities} context={context}/>) : null}
|
|
21
15
|
|
|
22
16
|
{parameterGroups.map(function (group) {
|
|
23
|
-
return (<StaticSection key={group.key} className="openapi-parameters" header={group.label}>
|
|
17
|
+
return (<StaticSection key={"parameter-".concat(group.key)} className="openapi-parameters" header={group.label}>
|
|
24
18
|
<OpenAPISchemaProperties properties={group.parameters.map(parameterToProperty)} context={context}/>
|
|
25
19
|
</StaticSection>);
|
|
26
20
|
})}
|
|
27
21
|
|
|
28
|
-
{operation.requestBody ? (<OpenAPIRequestBody requestBody={operation.requestBody} context={context}/>) : null}
|
|
29
|
-
{operation.responses ? (<OpenAPIResponses responses={operation.responses} context={context}/>) : null}
|
|
22
|
+
{operation.requestBody ? (<OpenAPIRequestBody key="body" requestBody={operation.requestBody} context={context}/>) : null}
|
|
23
|
+
{operation.responses ? (<OpenAPIResponses key="responses" responses={operation.responses} context={context}/>) : null}
|
|
30
24
|
</>);
|
|
31
25
|
}
|
|
32
26
|
function groupParameters(parameters) {
|
package/dist/OpenAPITabs.jsx
CHANGED
|
@@ -102,16 +102,8 @@ export function OpenAPITabsPanels() {
|
|
|
102
102
|
return null;
|
|
103
103
|
}
|
|
104
104
|
var key = selectedTab.key.toString();
|
|
105
|
-
return (<TabPanel
|
|
106
|
-
{selectedTab.body}
|
|
107
|
-
{selectedTab.footer ? (<
|
|
105
|
+
return (<TabPanel id={key} className="openapi-tabs-panel">
|
|
106
|
+
<div className="openapi-tabs-body">{selectedTab.body}</div>
|
|
107
|
+
{selectedTab.footer ? (<div className="openapi-tabs-footer">{selectedTab.footer}</div>) : null}
|
|
108
108
|
</TabPanel>);
|
|
109
109
|
}
|
|
110
|
-
/**
|
|
111
|
-
* The OpenAPI Tabs panel footer component.
|
|
112
|
-
* This component should be used as a child of the OpenAPITabs component.
|
|
113
|
-
*/
|
|
114
|
-
function OpenAPITabsPanelFooter(props) {
|
|
115
|
-
var children = props.children;
|
|
116
|
-
return <div className="openapi-tabs-footer">{children}</div>;
|
|
117
|
-
}
|