@gitbook/react-openapi 0.7.0 → 1.0.0
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 +51 -0
- package/dist/InteractiveSection.d.ts +4 -6
- package/dist/InteractiveSection.jsx +96 -0
- package/dist/Markdown.d.ts +1 -2
- package/dist/Markdown.jsx +5 -0
- package/dist/OpenAPICodeSample.d.ts +2 -4
- package/dist/OpenAPICodeSample.jsx +143 -0
- package/dist/OpenAPIDisclosure.d.ts +12 -0
- package/dist/OpenAPIDisclosure.jsx +32 -0
- package/dist/OpenAPIDisclosureGroup.d.ts +19 -0
- package/dist/OpenAPIDisclosureGroup.jsx +81 -0
- package/dist/OpenAPIOperation.d.ts +2 -4
- package/dist/OpenAPIOperation.jsx +51 -0
- package/dist/OpenAPIOperationContext.d.ts +16 -0
- package/dist/OpenAPIOperationContext.jsx +26 -0
- package/dist/OpenAPIPath.d.ts +8 -0
- package/dist/OpenAPIPath.jsx +54 -0
- package/dist/OpenAPIRequestBody.d.ts +3 -4
- package/dist/OpenAPIRequestBody.jsx +19 -0
- package/dist/OpenAPIResponse.d.ts +4 -4
- package/dist/OpenAPIResponse.jsx +49 -0
- package/dist/OpenAPIResponseExample.d.ts +2 -4
- package/dist/OpenAPIResponseExample.jsx +108 -0
- package/dist/OpenAPIResponses.d.ts +3 -4
- package/dist/OpenAPIResponses.jsx +36 -0
- package/dist/OpenAPISchema.d.ts +11 -8
- package/dist/OpenAPISchema.jsx +295 -0
- package/dist/OpenAPISchemaName.d.ts +12 -0
- package/dist/OpenAPISchemaName.jsx +15 -0
- package/dist/OpenAPISecurities.d.ts +2 -4
- package/dist/OpenAPISecurities.jsx +55 -0
- package/dist/OpenAPIServerURL.d.ts +2 -3
- package/dist/OpenAPIServerURL.jsx +67 -0
- package/dist/OpenAPIServerURLVariable.d.ts +2 -3
- package/dist/OpenAPIServerURLVariable.jsx +8 -0
- package/dist/OpenAPISpec.d.ts +3 -4
- package/dist/OpenAPISpec.jsx +91 -0
- package/dist/OpenAPITabs.d.ts +25 -0
- package/dist/OpenAPITabs.jsx +67 -0
- package/dist/ScalarApiButton.d.ts +5 -2
- package/dist/ScalarApiButton.jsx +51 -0
- package/dist/code-samples.d.ts +4 -0
- package/dist/code-samples.js +103 -38
- package/dist/fetchOpenAPIOperation.d.ts +9 -54
- package/dist/fetchOpenAPIOperation.js +178 -107
- package/dist/generateSchemaExample.d.ts +2 -2
- package/dist/generateSchemaExample.js +28 -100
- package/dist/index.d.ts +3 -2
- package/dist/index.js +2 -1
- package/dist/resolveOpenAPIOperation.d.ts +11 -0
- package/dist/resolveOpenAPIOperation.js +194 -0
- package/dist/stringifyOpenAPI.d.ts +4 -0
- package/dist/stringifyOpenAPI.js +6 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types.d.ts +11 -12
- package/dist/utils.d.ts +6 -1
- package/dist/utils.js +15 -2
- package/package.json +12 -11
- package/src/InteractiveSection.tsx +119 -78
- package/src/Markdown.tsx +2 -3
- package/src/OpenAPICodeSample.tsx +35 -21
- package/src/OpenAPIDisclosure.tsx +50 -0
- package/src/OpenAPIDisclosureGroup.tsx +136 -0
- package/src/OpenAPIOperation.tsx +36 -42
- package/src/OpenAPIOperationContext.tsx +45 -0
- package/src/OpenAPIPath.tsx +65 -0
- package/src/OpenAPIRequestBody.tsx +3 -14
- package/src/OpenAPIResponse.tsx +39 -43
- package/src/OpenAPIResponseExample.tsx +89 -31
- package/src/OpenAPIResponses.tsx +51 -15
- package/src/OpenAPISchema.test.ts +1 -1
- package/src/OpenAPISchema.tsx +124 -92
- package/src/OpenAPISchemaName.tsx +27 -0
- package/src/OpenAPISecurities.tsx +45 -24
- package/src/OpenAPIServerURL.tsx +17 -10
- package/src/OpenAPIServerURLVariable.tsx +2 -4
- package/src/OpenAPISpec.tsx +56 -53
- package/src/OpenAPITabs.tsx +113 -0
- package/src/ScalarApiButton.tsx +86 -6
- package/src/code-samples.test.ts +51 -0
- package/src/code-samples.ts +95 -31
- package/src/generateSchemaExample.ts +25 -151
- package/src/index.ts +3 -2
- package/src/resolveOpenAPIOperation.test.ts +177 -0
- package/src/resolveOpenAPIOperation.ts +163 -0
- package/src/stringifyOpenAPI.ts +6 -0
- package/src/types.ts +17 -10
- package/src/utils.ts +17 -2
- package/dist/InteractiveSection.js +0 -47
- package/dist/Markdown.js +0 -6
- package/dist/OpenAPICodeSample.js +0 -110
- package/dist/OpenAPIOperation.js +0 -38
- package/dist/OpenAPIRequestBody.js +0 -18
- package/dist/OpenAPIResponse.js +0 -32
- package/dist/OpenAPIResponseExample.js +0 -54
- package/dist/OpenAPIResponses.js +0 -18
- package/dist/OpenAPISchema.js +0 -235
- package/dist/OpenAPISchema.test.d.ts +0 -1
- package/dist/OpenAPISchema.test.js +0 -91
- package/dist/OpenAPISecurities.js +0 -42
- package/dist/OpenAPIServerURL.js +0 -51
- package/dist/OpenAPIServerURLVariable.js +0 -10
- package/dist/OpenAPISpec.js +0 -70
- package/dist/ScalarApiButton.js +0 -14
- package/dist/fetchOpenAPIOperation.test.d.ts +0 -1
- package/dist/fetchOpenAPIOperation.test.js +0 -152
- package/dist/resolveOpenAPIPath.d.ts +0 -7
- package/dist/resolveOpenAPIPath.js +0 -112
- package/dist/resolveOpenAPIPath.test.d.ts +0 -1
- package/dist/resolveOpenAPIPath.test.js +0 -39
- package/src/fetchOpenAPIOperation.test.ts +0 -185
- package/src/fetchOpenAPIOperation.ts +0 -230
- package/src/resolveOpenAPIPath.test.ts +0 -60
- package/src/resolveOpenAPIPath.ts +0 -145
package/src/OpenAPIResponses.tsx
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import { OpenAPIV3 } from 'openapi-types';
|
|
4
|
-
import { createStateKey, noReference } from './utils';
|
|
1
|
+
import type { OpenAPIV3, OpenAPIV3_1 } from '@gitbook/openapi-parser';
|
|
2
|
+
import { createStateKey, resolveDescription } from './utils';
|
|
5
3
|
import { OpenAPIResponse } from './OpenAPIResponse';
|
|
6
4
|
import { OpenAPIClientContext } from './types';
|
|
7
5
|
import { InteractiveSection } from './InteractiveSection';
|
|
6
|
+
import { OpenAPIDisclosureGroup } from './OpenAPIDisclosureGroup';
|
|
7
|
+
import { Markdown } from './Markdown';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Display an interactive response body.
|
|
11
11
|
*/
|
|
12
12
|
export function OpenAPIResponses(props: {
|
|
13
|
-
responses: OpenAPIV3.ResponsesObject;
|
|
13
|
+
responses: OpenAPIV3.ResponsesObject | OpenAPIV3_1.ResponsesObject;
|
|
14
14
|
context: OpenAPIClientContext;
|
|
15
15
|
}) {
|
|
16
16
|
const { responses, context } = props;
|
|
@@ -18,15 +18,51 @@ export function OpenAPIResponses(props: {
|
|
|
18
18
|
return (
|
|
19
19
|
<InteractiveSection
|
|
20
20
|
stateKey={createStateKey('response', context.blockKey)}
|
|
21
|
-
header="
|
|
22
|
-
className=
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
21
|
+
header="Responses"
|
|
22
|
+
className="openapi-responses"
|
|
23
|
+
>
|
|
24
|
+
<OpenAPIDisclosureGroup
|
|
25
|
+
allowsMultipleExpanded
|
|
26
|
+
icon={context.icons.chevronRight}
|
|
27
|
+
groups={Object.entries(responses).map(
|
|
28
|
+
([statusCode, response]: [string, OpenAPIV3.ResponseObject]) => {
|
|
29
|
+
const content = Object.entries(response.content ?? {});
|
|
30
|
+
const description = resolveDescription(response);
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
id: statusCode,
|
|
34
|
+
label: (
|
|
35
|
+
<div
|
|
36
|
+
className="openapi-response-tab-content"
|
|
37
|
+
key={`response-${statusCode}`}
|
|
38
|
+
>
|
|
39
|
+
<span className="openapi-response-statuscode">
|
|
40
|
+
{statusCode}
|
|
41
|
+
</span>
|
|
42
|
+
{description ? (
|
|
43
|
+
<Markdown
|
|
44
|
+
source={description}
|
|
45
|
+
className="openapi-response-description"
|
|
46
|
+
/>
|
|
47
|
+
) : null}
|
|
48
|
+
</div>
|
|
49
|
+
),
|
|
50
|
+
tabs: content.map(([contentType, mediaType]) => ({
|
|
51
|
+
id: contentType,
|
|
52
|
+
label: contentType,
|
|
53
|
+
body: (
|
|
54
|
+
<OpenAPIResponse
|
|
55
|
+
key={`$response-${statusCode}-${contentType}`}
|
|
56
|
+
response={response}
|
|
57
|
+
mediaType={mediaType}
|
|
58
|
+
context={context}
|
|
59
|
+
/>
|
|
60
|
+
),
|
|
61
|
+
})),
|
|
62
|
+
};
|
|
63
|
+
},
|
|
64
|
+
)}
|
|
65
|
+
/>
|
|
66
|
+
</InteractiveSection>
|
|
31
67
|
);
|
|
32
68
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { it, describe, expect } from 'bun:test';
|
|
2
2
|
import { getSchemaAlternatives } from './OpenAPISchema';
|
|
3
|
-
import { OpenAPIV3 } from 'openapi-
|
|
3
|
+
import type { OpenAPIV3 } from '@gitbook/openapi-parser';
|
|
4
4
|
|
|
5
5
|
describe('getSchemaAlternatives', () => {
|
|
6
6
|
it('should flatten oneOf', () => {
|
package/src/OpenAPISchema.tsx
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
1
|
+
import type { OpenAPIV3 } from '@gitbook/openapi-parser';
|
|
2
|
+
import clsx from 'clsx';
|
|
3
|
+
import { useId } from 'react';
|
|
4
4
|
|
|
5
5
|
import { InteractiveSection } from './InteractiveSection';
|
|
6
6
|
import { Markdown } from './Markdown';
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
7
|
+
import type { OpenAPIClientContext } from './types';
|
|
8
|
+
import { checkIsReference, noReference, resolveDescription } from './utils';
|
|
9
|
+
import { stringifyOpenAPI } from './stringifyOpenAPI';
|
|
10
|
+
import { OpenAPISchemaName } from './OpenAPISchemaName';
|
|
11
|
+
import { OpenAPIDisclosure } from './OpenAPIDisclosure';
|
|
10
12
|
|
|
11
13
|
type CircularRefsIds = Map<OpenAPIV3.SchemaObject, string>;
|
|
12
14
|
|
|
13
|
-
interface OpenAPISchemaPropertyEntry {
|
|
15
|
+
export interface OpenAPISchemaPropertyEntry {
|
|
14
16
|
propertyName?: string;
|
|
15
17
|
required?: boolean;
|
|
16
18
|
schema: OpenAPIV3.SchemaObject;
|
|
@@ -28,8 +30,6 @@ export function OpenAPISchemaProperty(
|
|
|
28
30
|
},
|
|
29
31
|
) {
|
|
30
32
|
const {
|
|
31
|
-
propertyName,
|
|
32
|
-
required,
|
|
33
33
|
schema,
|
|
34
34
|
circularRefs: parentCircularRefs = new Map<OpenAPIV3.SchemaObject, string>(),
|
|
35
35
|
context,
|
|
@@ -47,71 +47,42 @@ export function OpenAPISchemaProperty(
|
|
|
47
47
|
? null
|
|
48
48
|
: getSchemaAlternatives(schema, new Set(circularRefs.keys()));
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
if ((properties && !!properties.length) || schema.type === 'object') {
|
|
51
51
|
return (
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
<InteractiveSection id={id} className={clsx('openapi-schema', className)}>
|
|
53
|
+
<OpenAPISchemaPresentation {...props} />
|
|
54
|
+
<OpenAPIDisclosure context={context}>
|
|
55
|
+
{properties && properties.length > 0 ? (
|
|
56
|
+
<OpenAPISchemaProperties
|
|
57
|
+
properties={properties}
|
|
58
|
+
circularRefs={circularRefs}
|
|
59
|
+
context={context}
|
|
60
|
+
/>
|
|
61
|
+
) : null}
|
|
62
|
+
</OpenAPIDisclosure>
|
|
63
|
+
</InteractiveSection>
|
|
55
64
|
);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
className={
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
toggleOpenIcon={context.icons.chevronRight}
|
|
64
|
-
toggleCloseIcon={context.icons.chevronDown}
|
|
65
|
-
tabs={alternatives?.[0].map((alternative, index) => ({
|
|
66
|
-
key: `${index}`,
|
|
67
|
-
label: getSchemaTitle(alternative, alternatives[1]),
|
|
68
|
-
body: circularRefs.has(alternative) ? (
|
|
69
|
-
<OpenAPISchemaCircularRef
|
|
70
|
-
id={circularRefs.get(alternative)!}
|
|
71
|
-
schema={alternative}
|
|
72
|
-
/>
|
|
73
|
-
) : (
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (alternatives?.[0]?.length) {
|
|
68
|
+
return (
|
|
69
|
+
<InteractiveSection id={id} className={clsx('openapi-schema', className)}>
|
|
70
|
+
<OpenAPISchemaPresentation {...props} />
|
|
71
|
+
{alternatives[0].map((alternative, index) => (
|
|
74
72
|
<OpenAPISchemaAlternative
|
|
73
|
+
key={index}
|
|
75
74
|
schema={alternative}
|
|
76
75
|
circularRefs={circularRefs}
|
|
77
76
|
context={context}
|
|
78
77
|
/>
|
|
79
|
-
)
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
</span>
|
|
88
|
-
) : null}
|
|
89
|
-
{required ? (
|
|
90
|
-
<span className={classNames('openapi-schema-required')}>*</span>
|
|
91
|
-
) : null}
|
|
92
|
-
<span className={classNames('openapi-schema-type')}>
|
|
93
|
-
{getSchemaTitle(schema)}
|
|
94
|
-
</span>
|
|
95
|
-
</div>
|
|
96
|
-
{schema.description ? (
|
|
97
|
-
<Markdown
|
|
98
|
-
source={schema.description}
|
|
99
|
-
className="openapi-schema-description"
|
|
100
|
-
/>
|
|
101
|
-
) : null}
|
|
102
|
-
{shouldDisplayExample(schema) ? (
|
|
103
|
-
<span className="openapi-schema-example">
|
|
104
|
-
Example: <code>{JSON.stringify(schema.example)}</code>
|
|
105
|
-
</span>
|
|
106
|
-
) : null}
|
|
107
|
-
{schema.pattern ? (
|
|
108
|
-
<div className="openapi-schema-pattern">
|
|
109
|
-
Pattern: <code>{schema.pattern}</code>
|
|
110
|
-
</div>
|
|
111
|
-
) : null}
|
|
112
|
-
</div>
|
|
113
|
-
}
|
|
114
|
-
>
|
|
78
|
+
))}
|
|
79
|
+
</InteractiveSection>
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return (
|
|
84
|
+
<InteractiveSection id={id} className={clsx('openapi-schema', className)}>
|
|
85
|
+
<OpenAPISchemaPresentation {...props} />
|
|
115
86
|
{(properties && properties.length > 0) ||
|
|
116
87
|
(schema.enum && schema.enum.length > 0) ||
|
|
117
88
|
parentCircularRef ? (
|
|
@@ -123,9 +94,6 @@ export function OpenAPISchemaProperty(
|
|
|
123
94
|
context={context}
|
|
124
95
|
/>
|
|
125
96
|
) : null}
|
|
126
|
-
{schema.enum && schema.enum.length > 0 ? (
|
|
127
|
-
<OpenAPISchemaEnum enumValues={schema.enum} />
|
|
128
|
-
) : null}
|
|
129
97
|
{parentCircularRef ? (
|
|
130
98
|
<OpenAPISchemaCircularRef id={parentCircularRef} schema={schema} />
|
|
131
99
|
) : null}
|
|
@@ -151,7 +119,7 @@ export function OpenAPISchemaProperties(props: {
|
|
|
151
119
|
}
|
|
152
120
|
|
|
153
121
|
return (
|
|
154
|
-
<div id={id} className=
|
|
122
|
+
<div id={id} className="openapi-schema-properties">
|
|
155
123
|
{properties.map((property) => (
|
|
156
124
|
<OpenAPISchemaProperty
|
|
157
125
|
key={property.propertyName}
|
|
@@ -200,12 +168,14 @@ function OpenAPISchemaAlternative(props: {
|
|
|
200
168
|
const subProperties = getSchemaProperties(schema);
|
|
201
169
|
|
|
202
170
|
return (
|
|
203
|
-
<
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
171
|
+
<OpenAPIDisclosure context={context}>
|
|
172
|
+
<OpenAPISchemaProperties
|
|
173
|
+
id={id}
|
|
174
|
+
properties={subProperties ?? [{ schema }]}
|
|
175
|
+
circularRefs={subProperties ? new Map(circularRefs).set(schema, id) : circularRefs}
|
|
176
|
+
context={context}
|
|
177
|
+
/>
|
|
178
|
+
</OpenAPIDisclosure>
|
|
209
179
|
);
|
|
210
180
|
}
|
|
211
181
|
|
|
@@ -231,9 +201,73 @@ export function OpenAPISchemaEnum(props: { enumValues: any[] }) {
|
|
|
231
201
|
|
|
232
202
|
return (
|
|
233
203
|
<div className="openapi-schema-enum">
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
204
|
+
<span>
|
|
205
|
+
Options:{' '}
|
|
206
|
+
{enumValues.map((value, index) => (
|
|
207
|
+
<span key={index} className="openapi-schema-enum-value">
|
|
208
|
+
<code>{`${value}`}</code>
|
|
209
|
+
{index < enumValues.length - 1 ? ', ' : ''}
|
|
210
|
+
</span>
|
|
211
|
+
))}
|
|
212
|
+
</span>
|
|
213
|
+
</div>
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
export function OpenAPISchemaPresentation(props: OpenAPISchemaPropertyEntry) {
|
|
218
|
+
const { schema, propertyName, required } = props;
|
|
219
|
+
|
|
220
|
+
const shouldDisplayExample = (schema: OpenAPIV3.SchemaObject): boolean => {
|
|
221
|
+
return (
|
|
222
|
+
typeof schema.example === 'string' ||
|
|
223
|
+
typeof schema.example === 'number' ||
|
|
224
|
+
typeof schema.example === 'boolean' ||
|
|
225
|
+
(Array.isArray(schema.example) && schema.example.length > 0) ||
|
|
226
|
+
(typeof schema.example === 'object' &&
|
|
227
|
+
schema.example !== null &&
|
|
228
|
+
Object.keys(schema.example).length > 0)
|
|
229
|
+
);
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
const description = resolveDescription(schema);
|
|
233
|
+
|
|
234
|
+
return (
|
|
235
|
+
<div className="openapi-schema-presentation">
|
|
236
|
+
<OpenAPISchemaName
|
|
237
|
+
type={getSchemaTitle(schema)}
|
|
238
|
+
propertyName={propertyName}
|
|
239
|
+
required={required}
|
|
240
|
+
deprecated={schema.deprecated}
|
|
241
|
+
/>
|
|
242
|
+
{schema['x-deprecated-sunset'] ? (
|
|
243
|
+
<div className="openapi-deprecated-sunset openapi-schema-description openapi-markdown">
|
|
244
|
+
Sunset date:{' '}
|
|
245
|
+
<span className="openapi-deprecated-sunset-date">
|
|
246
|
+
{schema['x-deprecated-sunset']}
|
|
247
|
+
</span>
|
|
248
|
+
</div>
|
|
249
|
+
) : null}
|
|
250
|
+
{description ? (
|
|
251
|
+
<Markdown source={description} className="openapi-schema-description" />
|
|
252
|
+
) : null}
|
|
253
|
+
{shouldDisplayExample(schema) ? (
|
|
254
|
+
<div className="openapi-schema-example">
|
|
255
|
+
Example:{' '}
|
|
256
|
+
<code>
|
|
257
|
+
{typeof schema.example === 'string'
|
|
258
|
+
? schema.example
|
|
259
|
+
: stringifyOpenAPI(schema.example)}
|
|
260
|
+
</code>
|
|
261
|
+
</div>
|
|
262
|
+
) : null}
|
|
263
|
+
{schema.pattern ? (
|
|
264
|
+
<div className="openapi-schema-pattern">
|
|
265
|
+
Pattern: <code>{schema.pattern}</code>
|
|
266
|
+
</div>
|
|
267
|
+
) : null}
|
|
268
|
+
{schema.enum && schema.enum.length > 0 ? (
|
|
269
|
+
<OpenAPISchemaEnum enumValues={schema.enum} />
|
|
270
|
+
) : null}
|
|
237
271
|
</div>
|
|
238
272
|
);
|
|
239
273
|
}
|
|
@@ -274,10 +308,10 @@ function getSchemaProperties(schema: OpenAPIV3.SchemaObject): null | OpenAPISche
|
|
|
274
308
|
|
|
275
309
|
if (schema.properties) {
|
|
276
310
|
Object.entries(schema.properties).forEach(([propertyName, rawPropertySchema]) => {
|
|
277
|
-
const
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
311
|
+
const isReference = checkIsReference(rawPropertySchema);
|
|
312
|
+
const propertySchema: OpenAPIV3.SchemaObject = isReference
|
|
313
|
+
? { propertyName }
|
|
314
|
+
: rawPropertySchema;
|
|
281
315
|
|
|
282
316
|
result.push({
|
|
283
317
|
propertyName,
|
|
@@ -349,7 +383,7 @@ function flattenAlternatives(
|
|
|
349
383
|
}, [] as OpenAPIV3.SchemaObject[]);
|
|
350
384
|
}
|
|
351
385
|
|
|
352
|
-
function getSchemaTitle(
|
|
386
|
+
export function getSchemaTitle(
|
|
353
387
|
schema: OpenAPIV3.SchemaObject,
|
|
354
388
|
|
|
355
389
|
/** If the title is inferred in a oneOf with discriminator, we can use it to optimize the title */
|
|
@@ -361,7 +395,7 @@ function getSchemaTitle(
|
|
|
361
395
|
}
|
|
362
396
|
|
|
363
397
|
// Try using the discriminator
|
|
364
|
-
if (discriminator && schema.properties) {
|
|
398
|
+
if (discriminator?.propertyName && schema.properties) {
|
|
365
399
|
const discriminatorProperty = noReference(schema.properties[discriminator.propertyName]);
|
|
366
400
|
if (discriminatorProperty) {
|
|
367
401
|
if (discriminatorProperty.enum) {
|
|
@@ -377,12 +411,14 @@ function getSchemaTitle(
|
|
|
377
411
|
type = 'enum';
|
|
378
412
|
// check array AND schema.items as this is sometimes null despite what the type indicates
|
|
379
413
|
} else if (schema.type === 'array' && !!schema.items) {
|
|
380
|
-
type =
|
|
414
|
+
type = `${getSchemaTitle(noReference(schema.items))}[]`;
|
|
415
|
+
} else if (Array.isArray(schema.type)) {
|
|
416
|
+
type = schema.type.join(' | ');
|
|
381
417
|
} else if (schema.type || schema.properties) {
|
|
382
418
|
type = schema.type ?? 'object';
|
|
383
419
|
|
|
384
420
|
if (schema.format) {
|
|
385
|
-
type += `
|
|
421
|
+
type += ` ${schema.format}`;
|
|
386
422
|
}
|
|
387
423
|
} else if ('anyOf' in schema) {
|
|
388
424
|
type = 'any of';
|
|
@@ -394,10 +430,6 @@ function getSchemaTitle(
|
|
|
394
430
|
type = 'not';
|
|
395
431
|
}
|
|
396
432
|
|
|
397
|
-
if (SYMBOL_REF_RESOLVED in schema) {
|
|
398
|
-
type = `${schema[SYMBOL_REF_RESOLVED]} (${type})`;
|
|
399
|
-
}
|
|
400
|
-
|
|
401
433
|
if (schema.nullable) {
|
|
402
434
|
type = `nullable ${type}`;
|
|
403
435
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
interface OpenAPISchemaNameProps {
|
|
2
|
+
propertyName?: string | JSX.Element;
|
|
3
|
+
required?: boolean;
|
|
4
|
+
type?: string;
|
|
5
|
+
deprecated?: boolean;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Display the schema name row.
|
|
10
|
+
* It includes the property name, type, required and deprecated status.
|
|
11
|
+
*/
|
|
12
|
+
export function OpenAPISchemaName(props: OpenAPISchemaNameProps): JSX.Element {
|
|
13
|
+
const { type, propertyName, required, deprecated } = props;
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<div className="openapi-schema-name">
|
|
17
|
+
{propertyName ? (
|
|
18
|
+
<span data-deprecated={deprecated} className="openapi-schema-propertyname">
|
|
19
|
+
{propertyName}
|
|
20
|
+
</span>
|
|
21
|
+
) : null}
|
|
22
|
+
{type ? <span className="openapi-schema-type">{type}</span> : null}
|
|
23
|
+
{required ? <span className="openapi-schema-required">required</span> : null}
|
|
24
|
+
{deprecated ? <span className="openapi-deprecated">Deprecated</span> : null}
|
|
25
|
+
</div>
|
|
26
|
+
);
|
|
27
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import { OpenAPIClientContext } from './types';
|
|
1
|
+
import type { OpenAPIV3_1 } from '@gitbook/openapi-parser';
|
|
2
|
+
import type { OpenAPIClientContext, OpenAPIOperationData } from './types';
|
|
4
3
|
import { InteractiveSection } from './InteractiveSection';
|
|
5
4
|
import { Markdown } from './Markdown';
|
|
6
|
-
import {
|
|
5
|
+
import { OpenAPISchemaName } from './OpenAPISchemaName';
|
|
6
|
+
import { resolveDescription } from './utils';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Present securities authorization that can be used for this operation.
|
|
@@ -20,26 +20,29 @@ export function OpenAPISecurities(props: {
|
|
|
20
20
|
|
|
21
21
|
return (
|
|
22
22
|
<InteractiveSection
|
|
23
|
-
header="
|
|
24
|
-
className="openapi-securities"
|
|
23
|
+
header="Authorizations"
|
|
25
24
|
toggeable
|
|
26
25
|
defaultOpened={false}
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
toggleIcon={context.icons.chevronRight}
|
|
27
|
+
className="openapi-securities"
|
|
29
28
|
tabs={securities.map(([key, security]) => {
|
|
29
|
+
const description = resolveDescription(security);
|
|
30
30
|
return {
|
|
31
31
|
key: key,
|
|
32
32
|
label: key,
|
|
33
33
|
body: (
|
|
34
|
-
|
|
35
|
-
<
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
34
|
+
<div className="openapi-schema-body">
|
|
35
|
+
<div className="openapi-schema-presentation">
|
|
36
|
+
{getLabelForType(security)}
|
|
37
|
+
|
|
38
|
+
{description ? (
|
|
39
|
+
<Markdown
|
|
40
|
+
source={description}
|
|
41
|
+
className="openapi-securities-description"
|
|
42
|
+
/>
|
|
43
|
+
) : null}
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
43
46
|
),
|
|
44
47
|
};
|
|
45
48
|
})}
|
|
@@ -47,24 +50,42 @@ export function OpenAPISecurities(props: {
|
|
|
47
50
|
);
|
|
48
51
|
}
|
|
49
52
|
|
|
50
|
-
function getLabelForType(security:
|
|
53
|
+
function getLabelForType(security: OpenAPIV3_1.SecuritySchemeObject) {
|
|
51
54
|
switch (security.type) {
|
|
52
55
|
case 'apiKey':
|
|
53
|
-
return
|
|
56
|
+
return (
|
|
57
|
+
<OpenAPISchemaName
|
|
58
|
+
propertyName={security.name ?? 'apiKey'}
|
|
59
|
+
type="string"
|
|
60
|
+
required
|
|
61
|
+
/>
|
|
62
|
+
);
|
|
54
63
|
case 'http':
|
|
55
64
|
if (security.scheme === 'basic') {
|
|
56
|
-
return
|
|
65
|
+
return <OpenAPISchemaName propertyName="Authorization" type="string" required />;
|
|
57
66
|
}
|
|
58
67
|
|
|
59
68
|
if (security.scheme == 'bearer') {
|
|
60
|
-
|
|
69
|
+
const description = resolveDescription(security);
|
|
70
|
+
return (
|
|
71
|
+
<>
|
|
72
|
+
<OpenAPISchemaName propertyName="Authorization" type="string" required />
|
|
73
|
+
{/** Show a default description if none is provided */}
|
|
74
|
+
{!description ? (
|
|
75
|
+
<Markdown
|
|
76
|
+
source={`Bearer authentication header of the form Bearer ${`<token>`}.`}
|
|
77
|
+
className="openapi-securities-description"
|
|
78
|
+
/>
|
|
79
|
+
) : null}
|
|
80
|
+
</>
|
|
81
|
+
);
|
|
61
82
|
}
|
|
62
83
|
|
|
63
|
-
return
|
|
84
|
+
return <OpenAPISchemaName propertyName="HTTP" required />;
|
|
64
85
|
case 'oauth2':
|
|
65
|
-
return
|
|
86
|
+
return <OpenAPISchemaName propertyName="OAuth2" required />;
|
|
66
87
|
case 'openIdConnect':
|
|
67
|
-
return
|
|
88
|
+
return <OpenAPISchemaName propertyName="OpenID Connect" required />;
|
|
68
89
|
default:
|
|
69
90
|
// @ts-ignore
|
|
70
91
|
return security.type;
|
package/src/OpenAPIServerURL.tsx
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { OpenAPIV3 } from 'openapi-types';
|
|
1
|
+
import type { OpenAPIV3 } from '@gitbook/openapi-parser';
|
|
3
2
|
import { OpenAPIServerURLVariable } from './OpenAPIServerURLVariable';
|
|
4
3
|
|
|
5
4
|
/**
|
|
@@ -9,6 +8,10 @@ export function OpenAPIServerURL(props: { servers: OpenAPIV3.ServerObject[] }) {
|
|
|
9
8
|
const { servers } = props;
|
|
10
9
|
const server = servers[0];
|
|
11
10
|
|
|
11
|
+
if (!server) {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
|
|
12
15
|
const parts = parseServerURL(server?.url ?? '');
|
|
13
16
|
|
|
14
17
|
return (
|
|
@@ -17,16 +20,13 @@ export function OpenAPIServerURL(props: { servers: OpenAPIV3.ServerObject[] }) {
|
|
|
17
20
|
if (part.kind === 'text') {
|
|
18
21
|
return <span key={i}>{part.text}</span>;
|
|
19
22
|
} else {
|
|
20
|
-
|
|
23
|
+
const variable = server.variables?.[part.name];
|
|
24
|
+
if (!variable) {
|
|
21
25
|
return <span key={i}>{`{${part.name}}`}</span>;
|
|
22
26
|
}
|
|
23
27
|
|
|
24
28
|
return (
|
|
25
|
-
<OpenAPIServerURLVariable
|
|
26
|
-
key={i}
|
|
27
|
-
name={part.name}
|
|
28
|
-
variable={server.variables[part.name]}
|
|
29
|
-
/>
|
|
29
|
+
<OpenAPIServerURLVariable key={i} name={part.name} variable={variable} />
|
|
30
30
|
);
|
|
31
31
|
}
|
|
32
32
|
})}
|
|
@@ -39,6 +39,9 @@ export function OpenAPIServerURL(props: { servers: OpenAPIV3.ServerObject[] }) {
|
|
|
39
39
|
*/
|
|
40
40
|
export function getServersURL(servers: OpenAPIV3.ServerObject[]): string {
|
|
41
41
|
const server = servers[0];
|
|
42
|
+
if (!server) {
|
|
43
|
+
return '';
|
|
44
|
+
}
|
|
42
45
|
const parts = parseServerURL(server?.url ?? '');
|
|
43
46
|
|
|
44
47
|
return parts
|
|
@@ -56,10 +59,14 @@ function parseServerURL(url: string) {
|
|
|
56
59
|
const parts = url.split(/{([^}]+)}/g);
|
|
57
60
|
const result: Array<{ kind: 'variable'; name: string } | { kind: 'text'; text: string }> = [];
|
|
58
61
|
for (let i = 0; i < parts.length; i++) {
|
|
62
|
+
const part = parts[i];
|
|
63
|
+
if (!part) {
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
59
66
|
if (i % 2 === 0) {
|
|
60
|
-
result.push({ kind: 'text', text:
|
|
67
|
+
result.push({ kind: 'text', text: part });
|
|
61
68
|
} else {
|
|
62
|
-
result.push({ kind: 'variable', name:
|
|
69
|
+
result.push({ kind: 'variable', name: part });
|
|
63
70
|
}
|
|
64
71
|
}
|
|
65
72
|
return result;
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
import classNames from 'classnames';
|
|
5
|
-
import { OpenAPIV3 } from 'openapi-types';
|
|
3
|
+
import type { OpenAPIV3 } from '@gitbook/openapi-parser';
|
|
6
4
|
|
|
7
5
|
/**
|
|
8
6
|
* Interactive component to show the value of a server variable and let the user change it.
|
|
@@ -12,5 +10,5 @@ export function OpenAPIServerURLVariable(props: {
|
|
|
12
10
|
variable: OpenAPIV3.ServerVariableObject;
|
|
13
11
|
}) {
|
|
14
12
|
const { variable } = props;
|
|
15
|
-
return <span className=
|
|
13
|
+
return <span className="openapi-url-var">{variable.default}</span>;
|
|
16
14
|
}
|