@gitbook/react-openapi 1.0.4 → 1.1.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 +22 -0
- package/dist/InteractiveSection.jsx +10 -9
- package/dist/OpenAPICodeSample.jsx +3 -3
- package/dist/OpenAPIDisclosure.d.ts +5 -9
- package/dist/OpenAPIDisclosure.jsx +25 -27
- package/dist/OpenAPIDisclosureGroup.d.ts +2 -2
- package/dist/OpenAPIDisclosureGroup.jsx +6 -5
- package/dist/OpenAPIPath.jsx +5 -1
- package/dist/OpenAPIResponseExample.jsx +8 -8
- package/dist/OpenAPIResponses.jsx +3 -3
- package/dist/OpenAPISchema.d.ts +3 -26
- package/dist/OpenAPISchema.jsx +80 -131
- package/dist/OpenAPISpec.jsx +3 -4
- package/dist/OpenAPITabs.jsx +51 -47
- package/dist/ScalarApiButton.d.ts +3 -2
- package/dist/ScalarApiButton.jsx +22 -18
- package/dist/StaticSection.d.ts +10 -0
- package/dist/StaticSection.jsx +23 -0
- package/dist/dereference.d.ts +5 -0
- package/dist/dereference.js +68 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +2 -1
- package/dist/models/OpenAPIModels.d.ts +9 -0
- package/dist/models/OpenAPIModels.jsx +62 -0
- package/dist/models/index.d.ts +2 -0
- package/dist/models/index.js +2 -0
- package/dist/models/resolveOpenAPIModels.d.ts +7 -0
- package/dist/models/resolveOpenAPIModels.js +73 -0
- package/dist/resolveOpenAPIOperation.d.ts +2 -2
- package/dist/resolveOpenAPIOperation.js +3 -34
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/types.d.ts +8 -0
- package/dist/useSyncedTabsGlobalState.d.ts +10 -1
- package/dist/useSyncedTabsGlobalState.js +19 -15
- package/dist/utils.js +42 -3
- package/package.json +3 -3
- package/src/InteractiveSection.tsx +10 -18
- package/src/OpenAPICodeSample.tsx +3 -3
- package/src/OpenAPIDisclosure.tsx +35 -42
- package/src/OpenAPIDisclosureGroup.tsx +13 -11
- package/src/OpenAPIPath.tsx +7 -1
- package/src/OpenAPIResponseExample.tsx +8 -15
- package/src/OpenAPIResponses.tsx +3 -3
- package/src/OpenAPISchema.test.ts +26 -35
- package/src/OpenAPISchema.tsx +138 -227
- package/src/OpenAPISpec.tsx +3 -5
- package/src/OpenAPITabs.tsx +52 -63
- package/src/ScalarApiButton.tsx +26 -28
- package/src/StaticSection.tsx +59 -0
- package/src/dereference.ts +29 -0
- package/src/index.ts +3 -2
- package/src/models/OpenAPIModels.tsx +89 -0
- package/src/models/index.ts +2 -0
- package/src/models/resolveOpenAPIModels.ts +35 -0
- package/src/resolveOpenAPIOperation.ts +8 -36
- package/src/types.ts +10 -0
- package/src/useSyncedTabsGlobalState.ts +33 -21
- package/src/utils.ts +51 -3
package/dist/types.d.ts
CHANGED
|
@@ -51,3 +51,11 @@ export interface OpenAPIOperationData extends OpenAPICustomSpecProperties {
|
|
|
51
51
|
/** Securities that should be used for this operation */
|
|
52
52
|
securities: [string, OpenAPIV3.SecuritySchemeObject][];
|
|
53
53
|
}
|
|
54
|
+
export type OpenAPIModel = {
|
|
55
|
+
name: string;
|
|
56
|
+
schema: OpenAPIV3.SchemaObject;
|
|
57
|
+
};
|
|
58
|
+
export interface OpenAPIModelsData {
|
|
59
|
+
/** Components schemas to be used for models */
|
|
60
|
+
models: OpenAPIModel[];
|
|
61
|
+
}
|
|
@@ -1 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
type Key = string | number;
|
|
2
|
+
type TabState = {
|
|
3
|
+
tabKey: Key | null;
|
|
4
|
+
};
|
|
5
|
+
type TabActions = {
|
|
6
|
+
setTabKey: (tab: Key | null) => void;
|
|
7
|
+
};
|
|
8
|
+
type TabStore = TabState & TabActions;
|
|
9
|
+
export declare const getOrCreateTabStoreByKey: (storeKey: string, initialKey?: Key) => import("zustand").StoreApi<TabStore>;
|
|
10
|
+
export {};
|
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import {
|
|
3
|
-
var
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
2
|
+
import { createStore } from 'zustand';
|
|
3
|
+
var createTabStore = function (initialTab) {
|
|
4
|
+
return createStore()(function (set) { return ({
|
|
5
|
+
tabKey: initialTab !== null && initialTab !== void 0 ? initialTab : null,
|
|
6
|
+
setTabKey: function (tabKey) {
|
|
7
|
+
set(function () { return ({ tabKey: tabKey }); });
|
|
8
|
+
},
|
|
9
|
+
}); });
|
|
10
|
+
};
|
|
11
|
+
var defaultTabStores = new Map();
|
|
12
|
+
var createTabStoreFactory = function (stores) {
|
|
13
|
+
return function (storeKey, initialKey) {
|
|
14
|
+
if (!stores.has(storeKey)) {
|
|
15
|
+
stores.set(storeKey, createTabStore(initialKey));
|
|
16
|
+
}
|
|
17
|
+
return stores.get(storeKey);
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
export var getOrCreateTabStoreByKey = createTabStoreFactory(defaultTabStores);
|
package/dist/utils.js
CHANGED
|
@@ -9,17 +9,25 @@ var __assign = (this && this.__assign) || function () {
|
|
|
9
9
|
};
|
|
10
10
|
return __assign.apply(this, arguments);
|
|
11
11
|
};
|
|
12
|
+
import { stringifyOpenAPI } from './stringifyOpenAPI';
|
|
12
13
|
export function checkIsReference(input) {
|
|
13
14
|
return typeof input === 'object' && !!input && '$ref' in input;
|
|
14
15
|
}
|
|
15
16
|
export function createStateKey(key, scope) {
|
|
16
17
|
return scope ? "".concat(scope, "_").concat(key) : key;
|
|
17
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* Check if an object has a description. Either at the root level or in items.
|
|
21
|
+
*/
|
|
22
|
+
function hasDescription(object) {
|
|
23
|
+
return 'description' in object || 'x-gitbook-description-html' in object;
|
|
24
|
+
}
|
|
18
25
|
/**
|
|
19
26
|
* Resolve the description of an object.
|
|
20
27
|
*/
|
|
21
28
|
export function resolveDescription(object) {
|
|
22
|
-
|
|
29
|
+
// If the object has items and has a description, we resolve the description from items
|
|
30
|
+
if ('items' in object && typeof object.items === 'object' && hasDescription(object.items)) {
|
|
23
31
|
return resolveDescription(object.items);
|
|
24
32
|
}
|
|
25
33
|
return 'x-gitbook-description-html' in object &&
|
|
@@ -51,8 +59,13 @@ export function resolveFirstExample(object) {
|
|
|
51
59
|
return object.examples[firstKey];
|
|
52
60
|
}
|
|
53
61
|
}
|
|
54
|
-
|
|
55
|
-
|
|
62
|
+
// Resolve top level example first
|
|
63
|
+
if (shouldDisplayExample(object)) {
|
|
64
|
+
return formatExample(object.example);
|
|
65
|
+
}
|
|
66
|
+
// Resolve example from items if it exists
|
|
67
|
+
if (object.items && typeof object.items === 'object') {
|
|
68
|
+
return formatExample(object.items.example);
|
|
56
69
|
}
|
|
57
70
|
return undefined;
|
|
58
71
|
}
|
|
@@ -84,3 +97,29 @@ export function parameterToProperty(parameter) {
|
|
|
84
97
|
required: parameter.required,
|
|
85
98
|
};
|
|
86
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* Format the example of a schema.
|
|
102
|
+
*/
|
|
103
|
+
function formatExample(example) {
|
|
104
|
+
if (typeof example === 'string') {
|
|
105
|
+
return example
|
|
106
|
+
.replace(/\n/g, ' ') // Replace newlines with spaces
|
|
107
|
+
.replace(/\s+/g, ' ') // Collapse multiple spaces/newlines into a single space
|
|
108
|
+
.replace(/([\{\}:,])\s+/g, '$1 ') // Ensure a space after {, }, :, and ,
|
|
109
|
+
.replace(/\s+([\{\}:,])/g, ' $1') // Ensure a space before {, }, :, and ,
|
|
110
|
+
.trim();
|
|
111
|
+
}
|
|
112
|
+
return stringifyOpenAPI(example);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Check if an example should be displayed.
|
|
116
|
+
*/
|
|
117
|
+
function shouldDisplayExample(schema) {
|
|
118
|
+
return ((typeof schema.example === 'string' && !!schema.example) ||
|
|
119
|
+
typeof schema.example === 'number' ||
|
|
120
|
+
typeof schema.example === 'boolean' ||
|
|
121
|
+
(Array.isArray(schema.example) && schema.example.length > 0) ||
|
|
122
|
+
(typeof schema.example === 'object' &&
|
|
123
|
+
schema.example !== null &&
|
|
124
|
+
Object.keys(schema.example).length > 0));
|
|
125
|
+
}
|
package/package.json
CHANGED
|
@@ -8,12 +8,12 @@
|
|
|
8
8
|
"default": "./dist/index.js"
|
|
9
9
|
}
|
|
10
10
|
},
|
|
11
|
-
"version": "1.0
|
|
11
|
+
"version": "1.1.0",
|
|
12
12
|
"sideEffects": false,
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"@gitbook/openapi-parser": "workspace:*",
|
|
15
|
-
"@scalar/api-client-react": "1.
|
|
16
|
-
"@scalar/oas-utils": "^0.2.
|
|
15
|
+
"@scalar/api-client-react": "^1.1.36",
|
|
16
|
+
"@scalar/oas-utils": "^0.2.110",
|
|
17
17
|
"clsx": "^2.1.1",
|
|
18
18
|
"flatted": "^3.2.9",
|
|
19
19
|
"json-xml-parse": "^1.3.0",
|
|
@@ -4,6 +4,7 @@ import clsx from 'clsx';
|
|
|
4
4
|
import { useRef, useState } from 'react';
|
|
5
5
|
import { mergeProps, useButton, useDisclosure, useFocusRing } from 'react-aria';
|
|
6
6
|
import { useDisclosureState } from 'react-stately';
|
|
7
|
+
import { Section, SectionBody, SectionHeader, SectionHeaderContent } from './StaticSection';
|
|
7
8
|
|
|
8
9
|
interface InteractiveSectionTab {
|
|
9
10
|
key: string;
|
|
@@ -63,7 +64,7 @@ export function InteractiveSection(props: {
|
|
|
63
64
|
const { isFocusVisible, focusProps } = useFocusRing();
|
|
64
65
|
|
|
65
66
|
return (
|
|
66
|
-
<
|
|
67
|
+
<Section
|
|
67
68
|
id={id}
|
|
68
69
|
className={clsx(
|
|
69
70
|
'openapi-section',
|
|
@@ -73,20 +74,15 @@ export function InteractiveSection(props: {
|
|
|
73
74
|
)}
|
|
74
75
|
>
|
|
75
76
|
{header ? (
|
|
76
|
-
<
|
|
77
|
+
<SectionHeader
|
|
77
78
|
onClick={() => {
|
|
78
79
|
if (toggeable) {
|
|
79
80
|
state.toggle();
|
|
80
81
|
}
|
|
81
82
|
}}
|
|
82
|
-
className={
|
|
83
|
+
className={className}
|
|
83
84
|
>
|
|
84
|
-
<
|
|
85
|
-
className={clsx(
|
|
86
|
-
'openapi-section-header-content',
|
|
87
|
-
`${className}-header-content`
|
|
88
|
-
)}
|
|
89
|
-
>
|
|
85
|
+
<SectionHeaderContent className={className}>
|
|
90
86
|
{(children || selectedTab?.body) && toggeable ? (
|
|
91
87
|
<button
|
|
92
88
|
{...mergeProps(buttonProps, focusProps)}
|
|
@@ -102,7 +98,7 @@ export function InteractiveSection(props: {
|
|
|
102
98
|
</button>
|
|
103
99
|
) : null}
|
|
104
100
|
{header}
|
|
105
|
-
</
|
|
101
|
+
</SectionHeaderContent>
|
|
106
102
|
<div
|
|
107
103
|
className={clsx(
|
|
108
104
|
'openapi-section-header-controls',
|
|
@@ -133,23 +129,19 @@ export function InteractiveSection(props: {
|
|
|
133
129
|
</select>
|
|
134
130
|
) : null}
|
|
135
131
|
</div>
|
|
136
|
-
</
|
|
132
|
+
</SectionHeader>
|
|
137
133
|
) : null}
|
|
138
134
|
{(!toggeable || state.isExpanded) && (children || selectedTab?.body) ? (
|
|
139
|
-
<
|
|
140
|
-
ref={panelRef}
|
|
141
|
-
{...panelProps}
|
|
142
|
-
className={clsx('openapi-section-body', `${className}-body`)}
|
|
143
|
-
>
|
|
135
|
+
<SectionBody ref={panelRef} {...panelProps} className={className}>
|
|
144
136
|
{children}
|
|
145
137
|
{selectedTab?.body}
|
|
146
|
-
</
|
|
138
|
+
</SectionBody>
|
|
147
139
|
) : null}
|
|
148
140
|
{overlay ? (
|
|
149
141
|
<div className={clsx('openapi-section-overlay', `${className}-overlay`)}>
|
|
150
142
|
{overlay}
|
|
151
143
|
</div>
|
|
152
144
|
) : null}
|
|
153
|
-
</
|
|
145
|
+
</Section>
|
|
154
146
|
);
|
|
155
147
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { InteractiveSection } from './InteractiveSection';
|
|
2
1
|
import { OpenAPITabs, OpenAPITabsList, OpenAPITabsPanels } from './OpenAPITabs';
|
|
2
|
+
import { StaticSection } from './StaticSection';
|
|
3
3
|
import { type CodeSampleInput, codeSampleGenerators } from './code-samples';
|
|
4
4
|
import { generateMediaTypeExample, generateSchemaExample } from './generateSchemaExample';
|
|
5
5
|
import { stringifyOpenAPI } from './stringifyOpenAPI';
|
|
@@ -117,9 +117,9 @@ export function OpenAPICodeSample(props: {
|
|
|
117
117
|
|
|
118
118
|
return (
|
|
119
119
|
<OpenAPITabs stateKey={createStateKey('codesample')} items={samples}>
|
|
120
|
-
<
|
|
120
|
+
<StaticSection header={<OpenAPITabsList />} className="openapi-codesample">
|
|
121
121
|
<OpenAPITabsPanels />
|
|
122
|
-
</
|
|
122
|
+
</StaticSection>
|
|
123
123
|
</OpenAPITabs>
|
|
124
124
|
);
|
|
125
125
|
}
|
|
@@ -1,51 +1,44 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { useDisclosureState } from 'react-stately';
|
|
1
|
+
'use client';
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { Button, Disclosure, DisclosurePanel, Heading } from 'react-aria-components';
|
|
5
4
|
import type { OpenAPIClientContext } from './types';
|
|
6
5
|
|
|
7
|
-
interface Props {
|
|
8
|
-
context: OpenAPIClientContext;
|
|
9
|
-
children: React.ReactNode;
|
|
10
|
-
label?: string;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
6
|
/**
|
|
14
7
|
* Display an interactive OpenAPI disclosure.
|
|
15
|
-
* The label is optional and defaults to "child attributes".
|
|
16
8
|
*/
|
|
17
|
-
export function OpenAPIDisclosure(
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const {
|
|
23
|
-
const
|
|
9
|
+
export function OpenAPIDisclosure(props: {
|
|
10
|
+
context: OpenAPIClientContext;
|
|
11
|
+
children: React.ReactNode;
|
|
12
|
+
label: string;
|
|
13
|
+
}): React.JSX.Element {
|
|
14
|
+
const { context, children, label } = props;
|
|
15
|
+
const [isExpanded, setIsExpanded] = useState(false);
|
|
24
16
|
|
|
25
17
|
return (
|
|
26
|
-
<
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
18
|
+
<Disclosure
|
|
19
|
+
className="openapi-disclosure"
|
|
20
|
+
isExpanded={isExpanded}
|
|
21
|
+
onExpandedChange={setIsExpanded}
|
|
22
|
+
>
|
|
23
|
+
<Heading>
|
|
24
|
+
<Button
|
|
25
|
+
slot="trigger"
|
|
26
|
+
className="openapi-disclosure-trigger"
|
|
27
|
+
style={({ isFocusVisible }) => ({
|
|
28
|
+
outline: isFocusVisible
|
|
29
|
+
? '2px solid rgb(var(--primary-color-500) / 0.4)'
|
|
30
|
+
: 'none',
|
|
31
|
+
})}
|
|
32
|
+
>
|
|
33
|
+
{context.icons.plus}
|
|
34
|
+
<span>
|
|
35
|
+
{isExpanded ? 'Hide' : 'Show'} {label}
|
|
36
|
+
</span>
|
|
37
|
+
</Button>
|
|
38
|
+
</Heading>
|
|
39
|
+
<DisclosurePanel className="openapi-disclosure-panel">
|
|
40
|
+
{isExpanded ? children : null}
|
|
41
|
+
</DisclosurePanel>
|
|
42
|
+
</Disclosure>
|
|
50
43
|
);
|
|
51
44
|
}
|
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { createContext, useContext, useRef, useState } from 'react';
|
|
4
|
+
import { mergeProps, useButton, useDisclosure, useFocusRing, useId } from 'react-aria';
|
|
5
|
+
import {
|
|
6
|
+
type DisclosureGroupProps,
|
|
7
|
+
type DisclosureGroupState,
|
|
8
|
+
useDisclosureGroupState,
|
|
9
|
+
useDisclosureState,
|
|
10
|
+
} from 'react-stately';
|
|
11
|
+
|
|
1
12
|
interface Props {
|
|
2
13
|
groups: TDisclosureGroup[];
|
|
3
14
|
icon?: React.ReactNode;
|
|
@@ -8,20 +19,11 @@ type TDisclosureGroup = {
|
|
|
8
19
|
label: string | React.ReactNode;
|
|
9
20
|
tabs?: {
|
|
10
21
|
id: string;
|
|
11
|
-
label
|
|
22
|
+
label?: string | React.ReactNode;
|
|
12
23
|
body?: React.ReactNode;
|
|
13
24
|
}[];
|
|
14
25
|
};
|
|
15
26
|
|
|
16
|
-
import { createContext, useContext, useRef, useState } from 'react';
|
|
17
|
-
import { mergeProps, useButton, useDisclosure, useFocusRing, useId } from 'react-aria';
|
|
18
|
-
import {
|
|
19
|
-
type DisclosureGroupProps,
|
|
20
|
-
type DisclosureGroupState,
|
|
21
|
-
useDisclosureGroupState,
|
|
22
|
-
useDisclosureState,
|
|
23
|
-
} from 'react-stately';
|
|
24
|
-
|
|
25
27
|
const DisclosureGroupStateContext = createContext<DisclosureGroupState | null>(null);
|
|
26
28
|
|
|
27
29
|
/**
|
|
@@ -119,7 +121,7 @@ function DisclosureItem(props: { group: TDisclosureGroup; icon?: React.ReactNode
|
|
|
119
121
|
</option>
|
|
120
122
|
))}
|
|
121
123
|
</select>
|
|
122
|
-
) : group.tabs[0] ? (
|
|
124
|
+
) : group.tabs[0]?.label ? (
|
|
123
125
|
<span>{group.tabs[0].label}</span>
|
|
124
126
|
) : null}
|
|
125
127
|
</div>
|
package/src/OpenAPIPath.tsx
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { OpenAPIV3_1 } from '@gitbook/openapi-parser';
|
|
1
2
|
import type React from 'react';
|
|
2
3
|
import { ScalarApiButton } from './ScalarApiButton';
|
|
3
4
|
import type { OpenAPIContextProps, OpenAPIOperationData } from './types';
|
|
@@ -12,6 +13,7 @@ export function OpenAPIPath(props: {
|
|
|
12
13
|
const { data, context } = props;
|
|
13
14
|
const { method, path } = data;
|
|
14
15
|
const { specUrl } = context;
|
|
16
|
+
const hideTryItPanel = data['x-hideTryItPanel'] || data.operation['x-hideTryItPanel'];
|
|
15
17
|
|
|
16
18
|
return (
|
|
17
19
|
<div className="openapi-path">
|
|
@@ -19,13 +21,17 @@ export function OpenAPIPath(props: {
|
|
|
19
21
|
<div className="openapi-path-title" data-deprecated={data.operation.deprecated}>
|
|
20
22
|
<p>{formatPath(path)}</p>
|
|
21
23
|
</div>
|
|
22
|
-
{
|
|
24
|
+
{!hideTryItPanel && validateHttpMethod(method) && (
|
|
23
25
|
<ScalarApiButton method={method} path={path} specUrl={specUrl} />
|
|
24
26
|
)}
|
|
25
27
|
</div>
|
|
26
28
|
);
|
|
27
29
|
}
|
|
28
30
|
|
|
31
|
+
function validateHttpMethod(method: string): method is OpenAPIV3_1.HttpMethods {
|
|
32
|
+
return ['get', 'post', 'put', 'delete', 'patch', 'head', 'options', 'trace'].includes(method);
|
|
33
|
+
}
|
|
34
|
+
|
|
29
35
|
// Format the path to highlight placeholders
|
|
30
36
|
function formatPath(path: string) {
|
|
31
37
|
// Matches placeholders like {id}, {userId}, etc.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { OpenAPIV3 } from '@gitbook/openapi-parser';
|
|
2
|
-
import { InteractiveSection } from './InteractiveSection';
|
|
3
2
|
import { OpenAPITabs, OpenAPITabsList, OpenAPITabsPanels } from './OpenAPITabs';
|
|
3
|
+
import { StaticSection } from './StaticSection';
|
|
4
4
|
import { generateSchemaExample } from './generateSchemaExample';
|
|
5
5
|
import { json2xml } from './json2xml';
|
|
6
6
|
import { stringifyOpenAPI } from './stringifyOpenAPI';
|
|
@@ -84,9 +84,9 @@ export function OpenAPIResponseExample(props: {
|
|
|
84
84
|
|
|
85
85
|
return (
|
|
86
86
|
<OpenAPITabs stateKey={createStateKey('response-example')} items={tabs}>
|
|
87
|
-
<
|
|
87
|
+
<StaticSection header={<OpenAPITabsList />} className="openapi-response-example">
|
|
88
88
|
<OpenAPITabsPanels />
|
|
89
|
-
</
|
|
89
|
+
</StaticSection>
|
|
90
90
|
</OpenAPITabs>
|
|
91
91
|
);
|
|
92
92
|
}
|
|
@@ -134,12 +134,9 @@ function OpenAPIResponse(props: {
|
|
|
134
134
|
|
|
135
135
|
return (
|
|
136
136
|
<OpenAPITabs stateKey={createStateKey('response-media-types')} items={tabs}>
|
|
137
|
-
<
|
|
138
|
-
header={<OpenAPITabsList />}
|
|
139
|
-
className="openapi-response-media-types"
|
|
140
|
-
>
|
|
137
|
+
<StaticSection header={<OpenAPITabsList />} className="openapi-response-media-types">
|
|
141
138
|
<OpenAPITabsPanels />
|
|
142
|
-
</
|
|
139
|
+
</StaticSection>
|
|
143
140
|
</OpenAPITabs>
|
|
144
141
|
);
|
|
145
142
|
}
|
|
@@ -173,23 +170,19 @@ function OpenAPIResponseMediaType(props: {
|
|
|
173
170
|
key: example.key,
|
|
174
171
|
label: example.example.summary || example.key,
|
|
175
172
|
body: (
|
|
176
|
-
<OpenAPIExample
|
|
177
|
-
example={firstExample.example}
|
|
178
|
-
context={props.context}
|
|
179
|
-
syntax={syntax}
|
|
180
|
-
/>
|
|
173
|
+
<OpenAPIExample example={example.example} context={props.context} syntax={syntax} />
|
|
181
174
|
),
|
|
182
175
|
};
|
|
183
176
|
});
|
|
184
177
|
|
|
185
178
|
return (
|
|
186
179
|
<OpenAPITabs stateKey={createStateKey('response-media-type-examples')} items={tabs}>
|
|
187
|
-
<
|
|
180
|
+
<StaticSection
|
|
188
181
|
header={<OpenAPITabsList />}
|
|
189
182
|
className="openapi-response-media-type-examples"
|
|
190
183
|
>
|
|
191
184
|
<OpenAPITabsPanels />
|
|
192
|
-
</
|
|
185
|
+
</StaticSection>
|
|
193
186
|
</OpenAPITabs>
|
|
194
187
|
);
|
|
195
188
|
}
|
package/src/OpenAPIResponses.tsx
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { OpenAPIV3, OpenAPIV3_1 } from '@gitbook/openapi-parser';
|
|
2
|
-
import { InteractiveSection } from './InteractiveSection';
|
|
3
2
|
import { Markdown } from './Markdown';
|
|
4
3
|
import { OpenAPIDisclosureGroup } from './OpenAPIDisclosureGroup';
|
|
5
4
|
import { OpenAPIResponse } from './OpenAPIResponse';
|
|
5
|
+
import { StaticSection } from './StaticSection';
|
|
6
6
|
import type { OpenAPIClientContext } from './types';
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -15,7 +15,7 @@ export function OpenAPIResponses(props: {
|
|
|
15
15
|
const { responses, context } = props;
|
|
16
16
|
|
|
17
17
|
return (
|
|
18
|
-
<
|
|
18
|
+
<StaticSection header="Responses" className="openapi-responses">
|
|
19
19
|
<OpenAPIDisclosureGroup
|
|
20
20
|
allowsMultipleExpanded
|
|
21
21
|
icon={context.icons.chevronRight}
|
|
@@ -58,6 +58,6 @@ export function OpenAPIResponses(props: {
|
|
|
58
58
|
}
|
|
59
59
|
)}
|
|
60
60
|
/>
|
|
61
|
-
</
|
|
61
|
+
</StaticSection>
|
|
62
62
|
);
|
|
63
63
|
}
|
|
@@ -23,18 +23,15 @@ describe('getSchemaAlternatives', () => {
|
|
|
23
23
|
],
|
|
24
24
|
})
|
|
25
25
|
).toEqual([
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
},
|
|
36
|
-
],
|
|
37
|
-
undefined,
|
|
26
|
+
{
|
|
27
|
+
type: 'number',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
type: 'boolean',
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
type: 'string',
|
|
34
|
+
},
|
|
38
35
|
]);
|
|
39
36
|
});
|
|
40
37
|
|
|
@@ -58,22 +55,19 @@ describe('getSchemaAlternatives', () => {
|
|
|
58
55
|
],
|
|
59
56
|
})
|
|
60
57
|
).toEqual([
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
},
|
|
75
|
-
],
|
|
76
|
-
undefined,
|
|
58
|
+
{
|
|
59
|
+
allOf: [
|
|
60
|
+
{
|
|
61
|
+
type: 'number',
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
type: 'boolean',
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
type: 'string',
|
|
70
|
+
},
|
|
77
71
|
]);
|
|
78
72
|
});
|
|
79
73
|
|
|
@@ -89,13 +83,10 @@ describe('getSchemaAlternatives', () => {
|
|
|
89
83
|
a.anyOf?.push(a);
|
|
90
84
|
|
|
91
85
|
expect(getSchemaAlternatives(a)).toEqual([
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
a,
|
|
97
|
-
],
|
|
98
|
-
undefined,
|
|
86
|
+
{
|
|
87
|
+
type: 'string',
|
|
88
|
+
},
|
|
89
|
+
a,
|
|
99
90
|
]);
|
|
100
91
|
});
|
|
101
92
|
});
|