@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/dist/types.d.ts
CHANGED
|
@@ -4,6 +4,10 @@ export interface OpenAPIContextProps extends OpenAPIClientContext {
|
|
|
4
4
|
code: string;
|
|
5
5
|
syntax: string;
|
|
6
6
|
}>;
|
|
7
|
+
renderHeading: (props: {
|
|
8
|
+
deprecated: boolean;
|
|
9
|
+
title: string;
|
|
10
|
+
}) => React.ReactNode;
|
|
7
11
|
/** Spec url for the Scalar Api Client */
|
|
8
12
|
specUrl: string;
|
|
9
13
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function useSyncedTabsGlobalState<T>(): readonly [Map<string, T>, (updater: (tabs: Map<string, T>) => Map<string, T>) => void];
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { create } from 'zustand';
|
|
3
|
+
var useSyncedTabsStore = create()(function (set) { return ({
|
|
4
|
+
tabs: new Map(),
|
|
5
|
+
setTabs: function (updater) {
|
|
6
|
+
return set(function (state) { return ({
|
|
7
|
+
tabs: updater(new Map(state.tabs)), // Ensure a new Map is created for reactivity
|
|
8
|
+
}); });
|
|
9
|
+
},
|
|
10
|
+
}); });
|
|
11
|
+
// Selector for better performance - only re-renders when tabs change
|
|
12
|
+
export function useSyncedTabsGlobalState() {
|
|
13
|
+
var tabs = useSyncedTabsStore(function (state) { return state.tabs; });
|
|
14
|
+
var setTabs = useSyncedTabsStore(function (state) { return state.setTabs; });
|
|
15
|
+
return [tabs, setTabs];
|
|
16
|
+
}
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,8 +1,31 @@
|
|
|
1
|
-
import type { AnyObject, OpenAPIV3 } from '@gitbook/openapi-parser';
|
|
2
|
-
export declare function
|
|
3
|
-
export declare function checkIsReference(input: unknown): input is OpenAPIV3.ReferenceObject;
|
|
1
|
+
import type { AnyObject, OpenAPIV3, OpenAPIV3_1 } from '@gitbook/openapi-parser';
|
|
2
|
+
export declare function checkIsReference(input: unknown): input is OpenAPIV3.ReferenceObject | OpenAPIV3_1.ReferenceObject;
|
|
4
3
|
export declare function createStateKey(key: string, scope?: string): string;
|
|
5
4
|
/**
|
|
6
5
|
* Resolve the description of an object.
|
|
7
6
|
*/
|
|
8
7
|
export declare function resolveDescription(object: AnyObject): string | undefined;
|
|
8
|
+
/**
|
|
9
|
+
* Extract descriptions from an object.
|
|
10
|
+
*/
|
|
11
|
+
export declare function extractDescriptions(object: AnyObject): {
|
|
12
|
+
description: any;
|
|
13
|
+
"x-gitbook-description-html": any;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Resolve the first example from an object.
|
|
17
|
+
*/
|
|
18
|
+
export declare function resolveFirstExample(object: AnyObject): any;
|
|
19
|
+
/**
|
|
20
|
+
* Resolve the schema of a parameter.
|
|
21
|
+
* Extract the description, example and deprecated from parameter.
|
|
22
|
+
*/
|
|
23
|
+
export declare function resolveParameterSchema(parameter: OpenAPIV3.ParameterBaseObject): OpenAPIV3.SchemaObject;
|
|
24
|
+
/**
|
|
25
|
+
* Transform a parameter object to a property object.
|
|
26
|
+
*/
|
|
27
|
+
export declare function parameterToProperty(parameter: OpenAPIV3.ParameterObject | OpenAPIV3.ReferenceObject | OpenAPIV3_1.ReferenceObject): {
|
|
28
|
+
propertyName: string | undefined;
|
|
29
|
+
schema: OpenAPIV3.SchemaObject;
|
|
30
|
+
required: boolean | undefined;
|
|
31
|
+
};
|
package/dist/utils.js
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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
|
+
};
|
|
7
12
|
export function checkIsReference(input) {
|
|
8
13
|
return typeof input === 'object' && !!input && '$ref' in input;
|
|
9
14
|
}
|
|
@@ -14,9 +19,67 @@ export function createStateKey(key, scope) {
|
|
|
14
19
|
* Resolve the description of an object.
|
|
15
20
|
*/
|
|
16
21
|
export function resolveDescription(object) {
|
|
17
|
-
return 'x-description-html' in object &&
|
|
18
|
-
|
|
22
|
+
return 'x-gitbook-description-html' in object &&
|
|
23
|
+
typeof object['x-gitbook-description-html'] === 'string'
|
|
24
|
+
? object['x-gitbook-description-html'].trim()
|
|
19
25
|
: typeof object.description === 'string'
|
|
20
|
-
? object.description
|
|
26
|
+
? object.description.trim()
|
|
21
27
|
: undefined;
|
|
22
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* Extract descriptions from an object.
|
|
31
|
+
*/
|
|
32
|
+
export function extractDescriptions(object) {
|
|
33
|
+
var _a;
|
|
34
|
+
return _a = {
|
|
35
|
+
description: object.description
|
|
36
|
+
},
|
|
37
|
+
_a['x-gitbook-description-html'] = 'x-gitbook-description-html' in object
|
|
38
|
+
? object['x-gitbook-description-html']
|
|
39
|
+
: undefined,
|
|
40
|
+
_a;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Resolve the first example from an object.
|
|
44
|
+
*/
|
|
45
|
+
export function resolveFirstExample(object) {
|
|
46
|
+
if ('examples' in object && typeof object.examples === 'object' && object.examples) {
|
|
47
|
+
var keys = Object.keys(object.examples);
|
|
48
|
+
var firstKey = keys[0];
|
|
49
|
+
if (firstKey && object.examples[firstKey]) {
|
|
50
|
+
return object.examples[firstKey];
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if ('example' in object && object.example !== undefined) {
|
|
54
|
+
return object.example;
|
|
55
|
+
}
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Resolve the schema of a parameter.
|
|
60
|
+
* Extract the description, example and deprecated from parameter.
|
|
61
|
+
*/
|
|
62
|
+
export function resolveParameterSchema(parameter) {
|
|
63
|
+
var schema = checkIsReference(parameter.schema) ? undefined : parameter.schema;
|
|
64
|
+
return __assign(__assign(__assign({}, extractDescriptions(parameter)), { example: resolveFirstExample(parameter),
|
|
65
|
+
// Deprecated can be defined at the parameter level
|
|
66
|
+
deprecated: parameter.deprecated }), schema);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Transform a parameter object to a property object.
|
|
70
|
+
*/
|
|
71
|
+
export function parameterToProperty(parameter) {
|
|
72
|
+
var _a;
|
|
73
|
+
if (checkIsReference(parameter)) {
|
|
74
|
+
return {
|
|
75
|
+
propertyName: (_a = parameter.$ref) !== null && _a !== void 0 ? _a : 'Unknown ref',
|
|
76
|
+
schema: {},
|
|
77
|
+
required: undefined,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
return {
|
|
81
|
+
propertyName: parameter.name,
|
|
82
|
+
schema: resolveParameterSchema(parameter),
|
|
83
|
+
required: parameter.required,
|
|
84
|
+
};
|
|
85
|
+
}
|
package/package.json
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"default": "./dist/index.js"
|
|
9
9
|
}
|
|
10
10
|
},
|
|
11
|
-
"version": "1.0.
|
|
11
|
+
"version": "1.0.2",
|
|
12
12
|
"sideEffects": false,
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"@gitbook/openapi-parser": "workspace:*",
|
|
@@ -16,9 +16,11 @@
|
|
|
16
16
|
"@scalar/oas-utils": "^0.2.101",
|
|
17
17
|
"clsx": "^2.1.1",
|
|
18
18
|
"flatted": "^3.2.9",
|
|
19
|
+
"json-xml-parse": "^1.3.0",
|
|
19
20
|
"react-aria-components": "^1.6.0",
|
|
20
21
|
"react-aria": "^3.37.0",
|
|
21
|
-
"usehooks-ts": "^3.1.0"
|
|
22
|
+
"usehooks-ts": "^3.1.0",
|
|
23
|
+
"zustand": "^5.0.3"
|
|
22
24
|
},
|
|
23
25
|
"devDependencies": {
|
|
24
26
|
"bun-types": "^1.1.20",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import clsx from 'clsx';
|
|
4
|
-
import {
|
|
4
|
+
import { useRef, useState } from 'react';
|
|
5
5
|
import { mergeProps, useButton, useDisclosure, useFocusRing } from 'react-aria';
|
|
6
6
|
import { useDisclosureState } from 'react-stately';
|
|
7
7
|
|
|
@@ -11,30 +11,6 @@ interface InteractiveSectionTab {
|
|
|
11
11
|
body: React.ReactNode;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
let globalState: Record<string, string> = {};
|
|
15
|
-
const listeners = new Set<() => void>();
|
|
16
|
-
|
|
17
|
-
function useSyncedTabsGlobalState() {
|
|
18
|
-
const subscribe = useCallback((callback: () => void) => {
|
|
19
|
-
listeners.add(callback);
|
|
20
|
-
return () => listeners.delete(callback);
|
|
21
|
-
}, []);
|
|
22
|
-
|
|
23
|
-
const getSnapshot = useCallback(() => globalState, []);
|
|
24
|
-
|
|
25
|
-
const setSyncedTabs = useCallback(
|
|
26
|
-
(updater: (tabs: Record<string, string>) => Record<string, string>) => {
|
|
27
|
-
globalState = updater(globalState);
|
|
28
|
-
listeners.forEach((listener) => listener());
|
|
29
|
-
},
|
|
30
|
-
[],
|
|
31
|
-
);
|
|
32
|
-
|
|
33
|
-
const tabs = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
34
|
-
|
|
35
|
-
return [tabs, setSyncedTabs] as const;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
14
|
/**
|
|
39
15
|
* To optimize rendering, most of the components are server-components,
|
|
40
16
|
* and the interactiveness is mainly handled by a few key components like this one.
|
|
@@ -59,8 +35,6 @@ export function InteractiveSection(props: {
|
|
|
59
35
|
children?: React.ReactNode;
|
|
60
36
|
/** Children to display within the container */
|
|
61
37
|
overlay?: React.ReactNode;
|
|
62
|
-
/** An optional key referencing a value in global state */
|
|
63
|
-
stateKey?: string;
|
|
64
38
|
}) {
|
|
65
39
|
const {
|
|
66
40
|
id,
|
|
@@ -73,16 +47,11 @@ export function InteractiveSection(props: {
|
|
|
73
47
|
children,
|
|
74
48
|
overlay,
|
|
75
49
|
toggleIcon = '▶',
|
|
76
|
-
stateKey,
|
|
77
50
|
} = props;
|
|
78
|
-
|
|
79
|
-
const
|
|
80
|
-
stateKey && stateKey in syncedTabs
|
|
81
|
-
? tabs.find((tab) => tab.key === syncedTabs[stateKey])
|
|
82
|
-
: undefined;
|
|
83
|
-
const [selectedTabKey, setSelectedTab] = useState(tabFromState?.key ?? defaultTab);
|
|
51
|
+
|
|
52
|
+
const [selectedTabKey, setSelectedTab] = useState(defaultTab);
|
|
84
53
|
const selectedTab: InteractiveSectionTab | undefined =
|
|
85
|
-
|
|
54
|
+
tabs.find((tab) => tab.key === selectedTabKey) ?? tabs[0];
|
|
86
55
|
|
|
87
56
|
const state = useDisclosureState({
|
|
88
57
|
defaultExpanded: defaultOpened,
|
|
@@ -153,12 +122,6 @@ export function InteractiveSection(props: {
|
|
|
153
122
|
value={selectedTab?.key ?? ''}
|
|
154
123
|
onChange={(event) => {
|
|
155
124
|
setSelectedTab(event.target.value);
|
|
156
|
-
if (stateKey) {
|
|
157
|
-
setSyncedTabs((state) => ({
|
|
158
|
-
...state,
|
|
159
|
-
[stateKey]: event.target.value,
|
|
160
|
-
}));
|
|
161
|
-
}
|
|
162
125
|
state.expand();
|
|
163
126
|
}}
|
|
164
127
|
>
|
|
@@ -3,9 +3,10 @@ import { generateMediaTypeExample, generateSchemaExample } from './generateSchem
|
|
|
3
3
|
import { InteractiveSection } from './InteractiveSection';
|
|
4
4
|
import { getServersURL } from './OpenAPIServerURL';
|
|
5
5
|
import type { OpenAPIContextProps, OpenAPIOperationData } from './types';
|
|
6
|
-
import {
|
|
6
|
+
import { createStateKey } from './utils';
|
|
7
7
|
import { stringifyOpenAPI } from './stringifyOpenAPI';
|
|
8
8
|
import { OpenAPITabs, OpenAPITabsList, OpenAPITabsPanels } from './OpenAPITabs';
|
|
9
|
+
import { checkIsReference } from './utils';
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Display code samples to execute the operation.
|
|
@@ -20,24 +21,19 @@ export function OpenAPICodeSample(props: {
|
|
|
20
21
|
const searchParams = new URLSearchParams();
|
|
21
22
|
const headersObject: { [k: string]: string } = {};
|
|
22
23
|
|
|
23
|
-
data.operation.parameters?.forEach((
|
|
24
|
-
const param = noReference(rawParam);
|
|
24
|
+
data.operation.parameters?.forEach((param) => {
|
|
25
25
|
if (!param) {
|
|
26
26
|
return;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
if (param.in === 'header' && param.required) {
|
|
30
|
-
const example = param.schema
|
|
31
|
-
? generateSchemaExample(noReference(param.schema))
|
|
32
|
-
: undefined;
|
|
30
|
+
const example = param.schema ? generateSchemaExample(param.schema) : undefined;
|
|
33
31
|
if (example !== undefined && param.name) {
|
|
34
32
|
headersObject[param.name] =
|
|
35
33
|
typeof example !== 'string' ? stringifyOpenAPI(example) : example;
|
|
36
34
|
}
|
|
37
35
|
} else if (param.in === 'query' && param.required) {
|
|
38
|
-
const example = param.schema
|
|
39
|
-
? generateSchemaExample(noReference(param.schema))
|
|
40
|
-
: undefined;
|
|
36
|
+
const example = param.schema ? generateSchemaExample(param.schema) : undefined;
|
|
41
37
|
if (example !== undefined && param.name) {
|
|
42
38
|
searchParams.append(
|
|
43
39
|
param.name,
|
|
@@ -47,7 +43,9 @@ export function OpenAPICodeSample(props: {
|
|
|
47
43
|
}
|
|
48
44
|
});
|
|
49
45
|
|
|
50
|
-
const requestBody =
|
|
46
|
+
const requestBody = !checkIsReference(data.operation.requestBody)
|
|
47
|
+
? data.operation.requestBody
|
|
48
|
+
: undefined;
|
|
51
49
|
const requestBodyContentEntries = requestBody?.content
|
|
52
50
|
? Object.entries(requestBody.content)
|
|
53
51
|
: undefined;
|
|
@@ -60,7 +58,9 @@ export function OpenAPICodeSample(props: {
|
|
|
60
58
|
(searchParams.size ? `?${searchParams.toString()}` : ''),
|
|
61
59
|
method: data.method,
|
|
62
60
|
body: requestBodyContent
|
|
63
|
-
? generateMediaTypeExample(requestBodyContent[1], {
|
|
61
|
+
? generateMediaTypeExample(requestBodyContent[1], {
|
|
62
|
+
omitEmptyAndOptionalProperties: true,
|
|
63
|
+
})
|
|
64
64
|
: undefined,
|
|
65
65
|
headers: {
|
|
66
66
|
...getSecurityHeaders(data.securities),
|
|
@@ -115,7 +115,7 @@ export function OpenAPICodeSample(props: {
|
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
return (
|
|
118
|
-
<OpenAPITabs items={samples}>
|
|
118
|
+
<OpenAPITabs stateKey={createStateKey('codesample')} items={samples}>
|
|
119
119
|
<InteractiveSection header={<OpenAPITabsList />} className="openapi-codesample">
|
|
120
120
|
<OpenAPITabsPanels />
|
|
121
121
|
</InteractiveSection>
|
package/src/OpenAPIOperation.tsx
CHANGED
|
@@ -25,14 +25,17 @@ export function OpenAPIOperation(props: {
|
|
|
25
25
|
blockKey: context.blockKey,
|
|
26
26
|
};
|
|
27
27
|
|
|
28
|
-
const description = resolveDescription(operation)
|
|
28
|
+
const description = resolveDescription(operation);
|
|
29
29
|
|
|
30
30
|
return (
|
|
31
31
|
<div className={clsx('openapi-operation', className)}>
|
|
32
|
-
<div className="openapi-summary"
|
|
33
|
-
|
|
34
|
-
{
|
|
35
|
-
|
|
32
|
+
<div className="openapi-summary">
|
|
33
|
+
{operation.summary
|
|
34
|
+
? context.renderHeading({
|
|
35
|
+
deprecated: operation.deprecated ?? false,
|
|
36
|
+
title: operation.summary,
|
|
37
|
+
})
|
|
38
|
+
: null}
|
|
36
39
|
{operation.deprecated && <div className="openapi-deprecated">Deprecated</div>}
|
|
37
40
|
</div>
|
|
38
41
|
<div className="openapi-columns">
|
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
import type { OpenAPIV3 } from '@gitbook/openapi-parser';
|
|
2
2
|
import { OpenAPIRootSchema } from './OpenAPISchema';
|
|
3
|
-
import { noReference } from './utils';
|
|
4
3
|
import type { OpenAPIClientContext } from './types';
|
|
5
4
|
import { InteractiveSection } from './InteractiveSection';
|
|
5
|
+
import { checkIsReference } from './utils';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Display an interactive request body.
|
|
9
9
|
*/
|
|
10
10
|
export function OpenAPIRequestBody(props: {
|
|
11
|
-
requestBody: OpenAPIV3.RequestBodyObject;
|
|
11
|
+
requestBody: OpenAPIV3.RequestBodyObject | OpenAPIV3.ReferenceObject;
|
|
12
12
|
context: OpenAPIClientContext;
|
|
13
13
|
}) {
|
|
14
14
|
const { requestBody, context } = props;
|
|
15
15
|
|
|
16
|
+
if (checkIsReference(requestBody)) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
|
|
16
20
|
return (
|
|
17
21
|
<InteractiveSection
|
|
18
22
|
header="Body"
|
|
@@ -24,7 +28,7 @@ export function OpenAPIRequestBody(props: {
|
|
|
24
28
|
label: contentType,
|
|
25
29
|
body: (
|
|
26
30
|
<OpenAPIRootSchema
|
|
27
|
-
schema={
|
|
31
|
+
schema={mediaTypeObject.schema ?? {}}
|
|
28
32
|
context={context}
|
|
29
33
|
/>
|
|
30
34
|
),
|
package/src/OpenAPIResponse.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { OpenAPIV3 } from '@gitbook/openapi-parser';
|
|
2
2
|
import { OpenAPISchemaProperties } from './OpenAPISchema';
|
|
3
|
-
import {
|
|
3
|
+
import { parameterToProperty, resolveDescription } from './utils';
|
|
4
4
|
import type { OpenAPIClientContext } from './types';
|
|
5
5
|
import { OpenAPIDisclosure } from './OpenAPIDisclosure';
|
|
6
6
|
|
|
@@ -14,7 +14,7 @@ export function OpenAPIResponse(props: {
|
|
|
14
14
|
}) {
|
|
15
15
|
const { response, context, mediaType } = props;
|
|
16
16
|
const headers = Object.entries(response.headers ?? {}).map(
|
|
17
|
-
([name, header]) => [name,
|
|
17
|
+
([name, header]) => [name, header ?? {}] as const,
|
|
18
18
|
);
|
|
19
19
|
const content = Object.entries(mediaType.schema ?? {});
|
|
20
20
|
|
|
@@ -27,13 +27,11 @@ export function OpenAPIResponse(props: {
|
|
|
27
27
|
return (
|
|
28
28
|
<div className="openapi-response-body">
|
|
29
29
|
{headers.length > 0 ? (
|
|
30
|
-
<OpenAPIDisclosure context={context} label=
|
|
30
|
+
<OpenAPIDisclosure context={context} label="Headers">
|
|
31
31
|
<OpenAPISchemaProperties
|
|
32
|
-
properties={headers.map(([name, header]) =>
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
required: header.required,
|
|
36
|
-
}))}
|
|
32
|
+
properties={headers.map(([name, header]) => {
|
|
33
|
+
return parameterToProperty({ name, ...header });
|
|
34
|
+
})}
|
|
37
35
|
context={context}
|
|
38
36
|
/>
|
|
39
37
|
</OpenAPIDisclosure>
|
|
@@ -41,28 +39,10 @@ export function OpenAPIResponse(props: {
|
|
|
41
39
|
<div className="openapi-responsebody">
|
|
42
40
|
<OpenAPISchemaProperties
|
|
43
41
|
id={`response-${context.blockKey}`}
|
|
44
|
-
properties={[
|
|
45
|
-
{
|
|
46
|
-
schema: handleUnresolvedReference(mediaType.schema) ?? {},
|
|
47
|
-
},
|
|
48
|
-
]}
|
|
42
|
+
properties={mediaType.schema ? [{ schema: mediaType.schema }] : []}
|
|
49
43
|
context={context}
|
|
50
44
|
/>
|
|
51
45
|
</div>
|
|
52
46
|
</div>
|
|
53
47
|
);
|
|
54
48
|
}
|
|
55
|
-
|
|
56
|
-
function handleUnresolvedReference(
|
|
57
|
-
input: OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject | undefined,
|
|
58
|
-
): OpenAPIV3.SchemaObject {
|
|
59
|
-
const isReference = checkIsReference(input);
|
|
60
|
-
|
|
61
|
-
if (isReference || input === undefined) {
|
|
62
|
-
// If we find a reference that wasn't resolved or needed to be resolved externally, do not try to render it.
|
|
63
|
-
// Instead we render `any`
|
|
64
|
-
return {};
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
return input;
|
|
68
|
-
}
|