@gitbook/react-openapi 1.1.5 → 1.1.7
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 +34 -0
- package/dist/InteractiveSection.d.ts +0 -2
- package/dist/InteractiveSection.jsx +3 -4
- package/dist/OpenAPICodeSample.d.ts +9 -0
- package/dist/OpenAPICodeSample.jsx +117 -58
- package/dist/OpenAPICodeSampleInteractive.d.ts +11 -0
- package/dist/OpenAPICodeSampleInteractive.jsx +85 -0
- 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 +8 -6
- 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.d.ts +1 -2
- package/dist/code-samples.js +46 -11
- package/dist/decycle.d.ts +2 -0
- package/dist/decycle.js +70 -0
- package/dist/generateSchemaExample.d.ts +31 -2
- package/dist/generateSchemaExample.js +307 -24
- package/dist/schemas/OpenAPISchemas.jsx +1 -1
- 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/dist/utils.d.ts +1 -1
- package/dist/utils.js +11 -7
- package/package.json +3 -3
- package/src/InteractiveSection.tsx +2 -6
- package/src/OpenAPICodeSample.tsx +187 -78
- package/src/OpenAPICodeSampleInteractive.tsx +139 -0
- 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 +14 -6
- 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 +48 -12
- package/src/decycle.ts +68 -0
- package/src/generateSchemaExample.ts +412 -25
- package/src/resolveOpenAPIOperation.test.ts +6 -6
- package/src/schemas/OpenAPISchemas.tsx +1 -1
- package/src/schemas/resolveOpenAPISchemas.ts +3 -31
- package/src/types.ts +6 -6
- package/src/utils.ts +13 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,39 @@
|
|
|
1
1
|
# @gitbook/react-openapi
|
|
2
2
|
|
|
3
|
+
## 1.1.7
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- bd35348: Fix missing alternative schemas
|
|
8
|
+
- ae78fc5: Fix XML in code sample
|
|
9
|
+
- 7bb37c7: Move filterSelectedOpenAPISchemas to @gitbook/openapi-parser
|
|
10
|
+
- 373183a: Safe parse OpenAPI JSON schema
|
|
11
|
+
- 1505ddb: Fix multiple request examples selector not showing
|
|
12
|
+
- 61db166: Add OpenAPI write-only indicator
|
|
13
|
+
- 5b1e01c: Support for x-stability property
|
|
14
|
+
- cd99ed5: Fix spec properties rendering and missing keys
|
|
15
|
+
- 813b2af: Support for x-enumDescriptions and x-gitbook-enum
|
|
16
|
+
- a25fded: Replace $ref with $reference in json-decycle
|
|
17
|
+
- Updated dependencies [7bb37c7]
|
|
18
|
+
- Updated dependencies [5b1e01c]
|
|
19
|
+
- Updated dependencies [813b2af]
|
|
20
|
+
- @gitbook/openapi-parser@2.1.2
|
|
21
|
+
|
|
22
|
+
## 1.1.6
|
|
23
|
+
|
|
24
|
+
### Patch Changes
|
|
25
|
+
|
|
26
|
+
- 6eae764: Support body examples
|
|
27
|
+
- 7212973: Update scalar
|
|
28
|
+
- d2facb2: Mark properties as optional if not required
|
|
29
|
+
- 73e2b47: Fix write only properties in request example
|
|
30
|
+
- 70be2c6: Stringify default value
|
|
31
|
+
- fc00b51: Remove default value in generateSchemaExample
|
|
32
|
+
- a84b06b: Update resolveDescription and add minItems/maxItems
|
|
33
|
+
- Updated dependencies [48c18c0]
|
|
34
|
+
- Updated dependencies [7212973]
|
|
35
|
+
- @gitbook/openapi-parser@2.1.1
|
|
36
|
+
|
|
3
37
|
## 1.1.5
|
|
4
38
|
|
|
5
39
|
### 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"))}>
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { OpenAPIV3 } from '@gitbook/openapi-parser';
|
|
1
2
|
import type { OpenAPIContextProps, OpenAPIOperationData } from './types';
|
|
2
3
|
/**
|
|
3
4
|
* Display code samples to execute the operation.
|
|
@@ -7,3 +8,11 @@ export declare function OpenAPICodeSample(props: {
|
|
|
7
8
|
data: OpenAPIOperationData;
|
|
8
9
|
context: OpenAPIContextProps;
|
|
9
10
|
}): import("react").JSX.Element | null;
|
|
11
|
+
export interface MediaTypeRenderer {
|
|
12
|
+
mediaType: string;
|
|
13
|
+
element: React.ReactNode;
|
|
14
|
+
examples: Array<{
|
|
15
|
+
example: OpenAPIV3.ExampleObject;
|
|
16
|
+
element: React.ReactNode;
|
|
17
|
+
}>;
|
|
18
|
+
}
|
|
@@ -9,20 +9,47 @@ var __assign = (this && this.__assign) || function () {
|
|
|
9
9
|
};
|
|
10
10
|
return __assign.apply(this, arguments);
|
|
11
11
|
};
|
|
12
|
+
import { OpenAPIMediaTypeExamplesBody, OpenAPIMediaTypeExamplesSelector, } from './OpenAPICodeSampleInteractive';
|
|
12
13
|
import { OpenAPITabs, OpenAPITabsList, OpenAPITabsPanels } from './OpenAPITabs';
|
|
13
14
|
import { ScalarApiButton } from './ScalarApiButton';
|
|
14
15
|
import { StaticSection } from './StaticSection';
|
|
15
16
|
import { codeSampleGenerators } from './code-samples';
|
|
16
|
-
import {
|
|
17
|
+
import { generateMediaTypeExamples, generateSchemaExample } from './generateSchemaExample';
|
|
17
18
|
import { stringifyOpenAPI } from './stringifyOpenAPI';
|
|
18
19
|
import { getDefaultServerURL } from './util/server';
|
|
19
20
|
import { checkIsReference, createStateKey } from './utils';
|
|
21
|
+
var CUSTOM_CODE_SAMPLES_KEYS = ['x-custom-examples', 'x-code-samples', 'x-codeSamples'];
|
|
20
22
|
/**
|
|
21
23
|
* Display code samples to execute the operation.
|
|
22
24
|
* It supports the Redocly custom syntax as well (https://redocly.com/docs/api-reference-docs/specification-extensions/x-code-samples/)
|
|
23
25
|
*/
|
|
24
26
|
export function OpenAPICodeSample(props) {
|
|
25
|
-
var
|
|
27
|
+
var data = props.data;
|
|
28
|
+
// If code samples are disabled at operation level, we don't display the code samples.
|
|
29
|
+
if (data.operation['x-codeSamples'] === false) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
var customCodeSamples = getCustomCodeSamples(props);
|
|
33
|
+
// If code samples are disabled at the top-level and not custom code samples are defined,
|
|
34
|
+
// we don't display the code samples.
|
|
35
|
+
if (data['x-codeSamples'] === false && !customCodeSamples) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
var samples = customCodeSamples !== null && customCodeSamples !== void 0 ? customCodeSamples : generateCodeSamples(props);
|
|
39
|
+
if (samples.length === 0) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
return (<OpenAPITabs stateKey={createStateKey('codesample')} items={samples}>
|
|
43
|
+
<StaticSection header={<OpenAPITabsList />} className="openapi-codesample">
|
|
44
|
+
<OpenAPITabsPanels />
|
|
45
|
+
</StaticSection>
|
|
46
|
+
</OpenAPITabs>);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Generate code samples for the operation.
|
|
50
|
+
*/
|
|
51
|
+
function generateCodeSamples(props) {
|
|
52
|
+
var _a, _b;
|
|
26
53
|
var data = props.data, context = props.context;
|
|
27
54
|
var searchParams = new URLSearchParams();
|
|
28
55
|
var headersObject = {};
|
|
@@ -51,34 +78,92 @@ export function OpenAPICodeSample(props) {
|
|
|
51
78
|
var requestBody = !checkIsReference(data.operation.requestBody)
|
|
52
79
|
? data.operation.requestBody
|
|
53
80
|
: undefined;
|
|
54
|
-
var
|
|
55
|
-
|
|
56
|
-
:
|
|
57
|
-
var
|
|
58
|
-
var
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
81
|
+
var url = getDefaultServerURL(data.servers) +
|
|
82
|
+
data.path +
|
|
83
|
+
(searchParams.size ? "?".concat(searchParams.toString()) : '');
|
|
84
|
+
var genericHeaders = __assign(__assign({}, getSecurityHeaders(data.securities)), headersObject);
|
|
85
|
+
var mediaTypeRendererFactories = Object.entries((_b = requestBody === null || requestBody === void 0 ? void 0 : requestBody.content) !== null && _b !== void 0 ? _b : {}).map(function (_a) {
|
|
86
|
+
var mediaType = _a[0], mediaTypeObject = _a[1];
|
|
87
|
+
return function (generator) {
|
|
88
|
+
var mediaTypeHeaders = __assign(__assign({}, genericHeaders), { 'Content-Type': mediaType });
|
|
89
|
+
return {
|
|
90
|
+
mediaType: mediaType,
|
|
91
|
+
element: context.renderCodeBlock({
|
|
92
|
+
code: generator.generate({
|
|
93
|
+
url: url,
|
|
94
|
+
method: data.method,
|
|
95
|
+
body: undefined,
|
|
96
|
+
headers: mediaTypeHeaders,
|
|
97
|
+
}),
|
|
98
|
+
syntax: generator.syntax,
|
|
99
|
+
}),
|
|
100
|
+
examples: generateMediaTypeExamples(mediaTypeObject, {
|
|
101
|
+
mode: 'write',
|
|
102
|
+
}).map(function (example) { return ({
|
|
103
|
+
example: example,
|
|
104
|
+
element: context.renderCodeBlock({
|
|
105
|
+
code: generator.generate({
|
|
106
|
+
url: url,
|
|
107
|
+
method: data.method,
|
|
108
|
+
body: example.value,
|
|
109
|
+
headers: mediaTypeHeaders,
|
|
110
|
+
}),
|
|
111
|
+
syntax: generator.syntax,
|
|
112
|
+
}),
|
|
113
|
+
}); }),
|
|
114
|
+
};
|
|
115
|
+
};
|
|
116
|
+
});
|
|
117
|
+
return codeSampleGenerators.map(function (generator) {
|
|
118
|
+
if (mediaTypeRendererFactories.length > 0) {
|
|
119
|
+
var renderers = mediaTypeRendererFactories.map(function (generate) { return generate(generator); });
|
|
120
|
+
return {
|
|
121
|
+
key: "default-".concat(generator.id),
|
|
122
|
+
label: generator.label,
|
|
123
|
+
body: (<OpenAPIMediaTypeExamplesBody method={data.method} path={data.path} renderers={renderers}/>),
|
|
124
|
+
footer: (<OpenAPICodeSampleFooter renderers={renderers} data={data} context={context}/>),
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
key: "default-".concat(generator.id),
|
|
129
|
+
label: generator.label,
|
|
130
|
+
body: context.renderCodeBlock({
|
|
131
|
+
code: generator.generate({
|
|
132
|
+
url: url,
|
|
133
|
+
method: data.method,
|
|
134
|
+
body: undefined,
|
|
135
|
+
headers: genericHeaders,
|
|
136
|
+
}),
|
|
137
|
+
syntax: generator.syntax,
|
|
138
|
+
}),
|
|
139
|
+
footer: <OpenAPICodeSampleFooter data={data} renderers={[]} context={context}/>,
|
|
140
|
+
};
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
function OpenAPICodeSampleFooter(props) {
|
|
144
|
+
var data = props.data, context = props.context, renderers = props.renderers;
|
|
145
|
+
var method = data.method, path = data.path;
|
|
146
|
+
var specUrl = context.specUrl;
|
|
147
|
+
var hideTryItPanel = data['x-hideTryItPanel'] || data.operation['x-hideTryItPanel'];
|
|
148
|
+
var hasMultipleMediaTypes = renderers.length > 1 || renderers.some(function (renderer) { return renderer.examples.length > 0; });
|
|
149
|
+
if (hideTryItPanel && !hasMultipleMediaTypes) {
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
if (!validateHttpMethod(method)) {
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
return (<div className="openapi-codesample-footer">
|
|
156
|
+
{hasMultipleMediaTypes ? (<OpenAPIMediaTypeExamplesSelector method={data.method} path={data.path} renderers={renderers}/>) : (<span />)}
|
|
157
|
+
{!hideTryItPanel && <ScalarApiButton method={method} path={path} specUrl={specUrl}/>}
|
|
158
|
+
</div>);
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Get custom code samples for the operation.
|
|
162
|
+
*/
|
|
163
|
+
function getCustomCodeSamples(props) {
|
|
164
|
+
var data = props.data, context = props.context;
|
|
80
165
|
var customCodeSamples = null;
|
|
81
|
-
|
|
166
|
+
CUSTOM_CODE_SAMPLES_KEYS.forEach(function (key) {
|
|
82
167
|
var customSamples = data.operation[key];
|
|
83
168
|
if (customSamples && Array.isArray(customSamples)) {
|
|
84
169
|
customCodeSamples = customSamples
|
|
@@ -88,43 +173,17 @@ export function OpenAPICodeSample(props) {
|
|
|
88
173
|
typeof sample.lang === 'string');
|
|
89
174
|
})
|
|
90
175
|
.map(function (sample, index) { return ({
|
|
91
|
-
key: "
|
|
176
|
+
key: "custom-sample-".concat(sample.lang, "-").concat(index),
|
|
92
177
|
label: sample.label,
|
|
93
178
|
body: context.renderCodeBlock({
|
|
94
179
|
code: sample.source,
|
|
95
180
|
syntax: sample.lang,
|
|
96
181
|
}),
|
|
97
|
-
footer: <OpenAPICodeSampleFooter data={data} context={context}
|
|
182
|
+
footer: (<OpenAPICodeSampleFooter renderers={[]} data={data} context={context}/>),
|
|
98
183
|
}); });
|
|
99
184
|
}
|
|
100
185
|
});
|
|
101
|
-
|
|
102
|
-
// If code samples are defined at the operation level, it will override the top-level setting
|
|
103
|
-
var codeSamplesDisabled = data['x-codeSamples'] === false || data.operation['x-codeSamples'] === false;
|
|
104
|
-
var samples = customCodeSamples !== null && customCodeSamples !== void 0 ? customCodeSamples : (!codeSamplesDisabled ? autoCodeSamples : []);
|
|
105
|
-
if (samples.length === 0) {
|
|
106
|
-
return null;
|
|
107
|
-
}
|
|
108
|
-
return (<OpenAPITabs stateKey={createStateKey('codesample')} items={samples}>
|
|
109
|
-
<StaticSection header={<OpenAPITabsList />} className="openapi-codesample">
|
|
110
|
-
<OpenAPITabsPanels />
|
|
111
|
-
</StaticSection>
|
|
112
|
-
</OpenAPITabs>);
|
|
113
|
-
}
|
|
114
|
-
function OpenAPICodeSampleFooter(props) {
|
|
115
|
-
var data = props.data, context = props.context;
|
|
116
|
-
var method = data.method, path = data.path;
|
|
117
|
-
var specUrl = context.specUrl;
|
|
118
|
-
var hideTryItPanel = data['x-hideTryItPanel'] || data.operation['x-hideTryItPanel'];
|
|
119
|
-
if (hideTryItPanel) {
|
|
120
|
-
return null;
|
|
121
|
-
}
|
|
122
|
-
if (!validateHttpMethod(method)) {
|
|
123
|
-
return null;
|
|
124
|
-
}
|
|
125
|
-
return (<div className="openapi-codesample-footer">
|
|
126
|
-
<ScalarApiButton method={method} path={path} specUrl={specUrl}/>
|
|
127
|
-
</div>);
|
|
186
|
+
return customCodeSamples;
|
|
128
187
|
}
|
|
129
188
|
function getSecurityHeaders(securities) {
|
|
130
189
|
var _a;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { MediaTypeRenderer } from './OpenAPICodeSample';
|
|
2
|
+
export declare function OpenAPIMediaTypeExamplesSelector(props: {
|
|
3
|
+
method: string;
|
|
4
|
+
path: string;
|
|
5
|
+
renderers: MediaTypeRenderer[];
|
|
6
|
+
}): import("react").JSX.Element;
|
|
7
|
+
export declare function OpenAPIMediaTypeExamplesBody(props: {
|
|
8
|
+
method: string;
|
|
9
|
+
path: string;
|
|
10
|
+
renderers: MediaTypeRenderer[];
|
|
11
|
+
}): string | number | boolean | Iterable<import("react").ReactNode> | import("react").JSX.Element | null | undefined;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import clsx from 'clsx';
|
|
3
|
+
import { useCallback } from 'react';
|
|
4
|
+
import { useStore } from 'zustand';
|
|
5
|
+
import { getOrCreateTabStoreByKey } from './useSyncedTabsGlobalState';
|
|
6
|
+
function useMediaTypeState(data, defaultKey) {
|
|
7
|
+
var method = data.method, path = data.path;
|
|
8
|
+
var store = useStore(getOrCreateTabStoreByKey("media-type-".concat(method, "-").concat(path), defaultKey));
|
|
9
|
+
if (typeof store.tabKey !== 'string') {
|
|
10
|
+
throw new Error('Media type key is not a string');
|
|
11
|
+
}
|
|
12
|
+
return {
|
|
13
|
+
mediaType: store.tabKey,
|
|
14
|
+
setMediaType: useCallback(function (index) { return store.setTabKey(index); }, [store.setTabKey]),
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function useMediaTypeSampleIndexState(data, mediaType) {
|
|
18
|
+
var method = data.method, path = data.path;
|
|
19
|
+
var store = useStore(getOrCreateTabStoreByKey("media-type-sample-".concat(mediaType, "-").concat(method, "-").concat(path), 0));
|
|
20
|
+
if (typeof store.tabKey !== 'number') {
|
|
21
|
+
throw new Error('Example key is not a number');
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
index: store.tabKey,
|
|
25
|
+
setIndex: useCallback(function (index) { return store.setTabKey(index); }, [store.setTabKey]),
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export function OpenAPIMediaTypeExamplesSelector(props) {
|
|
29
|
+
var method = props.method, path = props.path, renderers = props.renderers;
|
|
30
|
+
if (!renderers[0]) {
|
|
31
|
+
throw new Error('No renderers provided');
|
|
32
|
+
}
|
|
33
|
+
var state = useMediaTypeState({ method: method, path: path }, renderers[0].mediaType);
|
|
34
|
+
var selected = renderers.find(function (r) { return r.mediaType === state.mediaType; }) || renderers[0];
|
|
35
|
+
return (<div className="openapi-codesample-selectors">
|
|
36
|
+
<MediaTypeSelector state={state} renderers={renderers}/>
|
|
37
|
+
<ExamplesSelector method={method} path={path} renderer={selected}/>
|
|
38
|
+
</div>);
|
|
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
|
+
}
|
|
51
|
+
function ExamplesSelector(props) {
|
|
52
|
+
var method = props.method, path = props.path, renderer = props.renderer;
|
|
53
|
+
var state = useMediaTypeSampleIndexState({ method: method, path: path }, renderer.mediaType);
|
|
54
|
+
if (renderer.examples.length < 2) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
return (<select className={clsx('openapi-select')} value={String(state.index)} onChange={function (e) { return state.setIndex(Number(e.target.value)); }}>
|
|
58
|
+
{renderer.examples.map(function (example, index) { return (<option key={index} value={index}>
|
|
59
|
+
{example.example.summary || "Example ".concat(index + 1)}
|
|
60
|
+
</option>); })}
|
|
61
|
+
</select>);
|
|
62
|
+
}
|
|
63
|
+
export function OpenAPIMediaTypeExamplesBody(props) {
|
|
64
|
+
var _a;
|
|
65
|
+
var renderers = props.renderers, method = props.method, path = props.path;
|
|
66
|
+
if (!renderers[0]) {
|
|
67
|
+
throw new Error('No renderers provided');
|
|
68
|
+
}
|
|
69
|
+
var mediaTypeState = useMediaTypeState({ method: method, path: path }, renderers[0].mediaType);
|
|
70
|
+
var selected = (_a = renderers.find(function (r) { return r.mediaType === mediaTypeState.mediaType; })) !== null && _a !== void 0 ? _a : renderers[0];
|
|
71
|
+
if (selected.examples.length === 0) {
|
|
72
|
+
return selected.element;
|
|
73
|
+
}
|
|
74
|
+
return <ExamplesBody method={method} path={path} renderer={selected}/>;
|
|
75
|
+
}
|
|
76
|
+
function ExamplesBody(props) {
|
|
77
|
+
var _a;
|
|
78
|
+
var method = props.method, path = props.path, renderer = props.renderer;
|
|
79
|
+
var exampleState = useMediaTypeSampleIndexState({ method: method, path: path }, renderer.mediaType);
|
|
80
|
+
var example = (_a = renderer.examples[exampleState.index]) !== null && _a !== void 0 ? _a : renderer.examples[0];
|
|
81
|
+
if (!example) {
|
|
82
|
+
throw new Error("No example found for index ".concat(exampleState.index));
|
|
83
|
+
}
|
|
84
|
+
return example.element;
|
|
85
|
+
}
|
|
@@ -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 {};
|