@gitbook/react-openapi 1.0.3 → 1.0.5
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 +15 -0
- package/dist/InteractiveSection.jsx +10 -9
- package/dist/OpenAPICodeSample.jsx +8 -9
- package/dist/OpenAPIDisclosure.d.ts +2 -1
- package/dist/OpenAPIDisclosure.jsx +2 -1
- package/dist/OpenAPIDisclosureGroup.d.ts +1 -1
- package/dist/OpenAPIDisclosureGroup.jsx +3 -2
- package/dist/OpenAPIOperation.jsx +2 -2
- package/dist/OpenAPIPath.d.ts +3 -2
- package/dist/OpenAPIPath.jsx +4 -15
- package/dist/OpenAPIRequestBody.jsx +1 -1
- package/dist/OpenAPIResponse.jsx +1 -1
- package/dist/OpenAPIResponseExample.jsx +10 -10
- package/dist/OpenAPIResponses.d.ts +1 -1
- package/dist/OpenAPIResponses.jsx +5 -5
- package/dist/OpenAPISchema.d.ts +5 -1
- package/dist/OpenAPISchema.jsx +30 -21
- package/dist/OpenAPISchemaName.d.ts +4 -3
- package/dist/OpenAPISchemaName.jsx +1 -1
- package/dist/OpenAPISecurities.jsx +2 -2
- package/dist/OpenAPISpec.jsx +3 -4
- package/dist/OpenAPITabs.d.ts +3 -3
- package/dist/OpenAPITabs.jsx +52 -49
- package/dist/ScalarApiButton.jsx +1 -1
- package/dist/StaticSection.d.ts +10 -0
- package/dist/StaticSection.jsx +23 -0
- package/dist/code-samples.js +11 -11
- package/dist/generateSchemaExample.js +2 -1
- package/dist/resolveOpenAPIOperation.d.ts +3 -3
- package/dist/resolveOpenAPIOperation.js +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/useSyncedTabsGlobalState.d.ts +10 -1
- package/dist/useSyncedTabsGlobalState.js +19 -15
- package/dist/util/server.d.ts +1 -1
- package/dist/util/server.js +1 -3
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js +4 -6
- package/package.json +2 -7
- package/src/InteractiveSection.tsx +13 -21
- package/src/OpenAPICodeSample.tsx +11 -12
- package/src/OpenAPIDisclosure.tsx +5 -3
- package/src/OpenAPIDisclosureGroup.tsx +13 -11
- package/src/OpenAPIOperation.tsx +3 -3
- package/src/OpenAPIOperationContext.tsx +1 -1
- package/src/OpenAPIPath.tsx +11 -10
- package/src/OpenAPIRequestBody.tsx +2 -2
- package/src/OpenAPIResponse.tsx +3 -3
- package/src/OpenAPIResponseExample.tsx +12 -19
- package/src/OpenAPIResponses.tsx +7 -7
- package/src/OpenAPISchema.test.ts +5 -5
- package/src/OpenAPISchema.tsx +77 -27
- package/src/OpenAPISchemaName.tsx +5 -4
- package/src/OpenAPISecurities.tsx +3 -3
- package/src/OpenAPISpec.tsx +3 -5
- package/src/OpenAPITabs.tsx +56 -67
- package/src/ScalarApiButton.tsx +3 -3
- package/src/StaticSection.tsx +59 -0
- package/src/code-samples.test.ts +66 -66
- package/src/code-samples.ts +14 -14
- package/src/generateSchemaExample.ts +3 -3
- package/src/json2xml.test.ts +1 -1
- package/src/resolveOpenAPIOperation.test.ts +6 -6
- package/src/resolveOpenAPIOperation.ts +7 -7
- package/src/stringifyOpenAPI.ts +1 -1
- package/src/useSyncedTabsGlobalState.ts +33 -21
- package/src/util/server.test.ts +3 -3
- package/src/util/server.ts +2 -3
- package/src/utils.ts +4 -4
|
@@ -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/util/server.d.ts
CHANGED
package/dist/util/server.js
CHANGED
|
@@ -21,9 +21,7 @@ export function interpolateServerURL(server) {
|
|
|
21
21
|
if (part.kind === 'text') {
|
|
22
22
|
return part.text;
|
|
23
23
|
}
|
|
24
|
-
|
|
25
|
-
return (_c = (_b = (_a = server.variables) === null || _a === void 0 ? void 0 : _a[part.name]) === null || _b === void 0 ? void 0 : _b.default) !== null && _c !== void 0 ? _c : "{".concat(part.name, "}");
|
|
26
|
-
}
|
|
24
|
+
return (_c = (_b = (_a = server.variables) === null || _a === void 0 ? void 0 : _a[part.name]) === null || _b === void 0 ? void 0 : _b.default) !== null && _c !== void 0 ? _c : "{".concat(part.name, "}");
|
|
27
25
|
})
|
|
28
26
|
.join('');
|
|
29
27
|
}
|
package/dist/utils.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ export declare function resolveDescription(object: OpenAPIV3.SchemaObject | AnyO
|
|
|
10
10
|
*/
|
|
11
11
|
export declare function extractDescriptions(object: AnyObject): {
|
|
12
12
|
description: any;
|
|
13
|
-
|
|
13
|
+
'x-gitbook-description-html': any;
|
|
14
14
|
};
|
|
15
15
|
/**
|
|
16
16
|
* Resolve the first example from an object.
|
package/dist/utils.js
CHANGED
|
@@ -33,14 +33,12 @@ export function resolveDescription(object) {
|
|
|
33
33
|
* Extract descriptions from an object.
|
|
34
34
|
*/
|
|
35
35
|
export function extractDescriptions(object) {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
},
|
|
40
|
-
_a['x-gitbook-description-html'] = 'x-gitbook-description-html' in object
|
|
36
|
+
return {
|
|
37
|
+
description: object.description,
|
|
38
|
+
'x-gitbook-description-html': 'x-gitbook-description-html' in object
|
|
41
39
|
? object['x-gitbook-description-html']
|
|
42
40
|
: undefined,
|
|
43
|
-
|
|
41
|
+
};
|
|
44
42
|
}
|
|
45
43
|
/**
|
|
46
44
|
* Resolve the first example from an object.
|
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.5",
|
|
12
12
|
"sideEffects": false,
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"@gitbook/openapi-parser": "workspace:*",
|
|
@@ -36,10 +36,5 @@
|
|
|
36
36
|
"dev": "bun run build -- --watch",
|
|
37
37
|
"clean": "rm -rf ./dist"
|
|
38
38
|
},
|
|
39
|
-
"files": [
|
|
40
|
-
"dist",
|
|
41
|
-
"src",
|
|
42
|
-
"README.md",
|
|
43
|
-
"CHANGELOG.md"
|
|
44
|
-
]
|
|
39
|
+
"files": ["dist", "src", "README.md", "CHANGELOG.md"]
|
|
45
40
|
}
|
|
@@ -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,30 +64,25 @@ 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',
|
|
70
71
|
toggeable ? 'openapi-section-toggeable' : null,
|
|
71
72
|
className,
|
|
72
|
-
toggeable ? `${className}-${state.isExpanded ? 'opened' : 'closed'}` : null
|
|
73
|
+
toggeable ? `${className}-${state.isExpanded ? 'opened' : 'closed'}` : null
|
|
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,11 +98,11 @@ 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',
|
|
109
|
-
`${className}-header-controls
|
|
105
|
+
`${className}-header-controls`
|
|
110
106
|
)}
|
|
111
107
|
onClick={(event) => {
|
|
112
108
|
event.stopPropagation();
|
|
@@ -117,7 +113,7 @@ export function InteractiveSection(props: {
|
|
|
117
113
|
className={clsx(
|
|
118
114
|
'openapi-section-select',
|
|
119
115
|
'openapi-select',
|
|
120
|
-
`${className}-tabs-select
|
|
116
|
+
`${className}-tabs-select`
|
|
121
117
|
)}
|
|
122
118
|
value={selectedTab?.key ?? ''}
|
|
123
119
|
onChange={(event) => {
|
|
@@ -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,12 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { OpenAPITabs, OpenAPITabsList, OpenAPITabsPanels } from './OpenAPITabs';
|
|
2
|
+
import { StaticSection } from './StaticSection';
|
|
3
|
+
import { type CodeSampleInput, codeSampleGenerators } from './code-samples';
|
|
2
4
|
import { generateMediaTypeExample, generateSchemaExample } from './generateSchemaExample';
|
|
3
|
-
import { InteractiveSection } from './InteractiveSection';
|
|
4
|
-
import type { OpenAPIContextProps, OpenAPIOperationData } from './types';
|
|
5
|
-
import { createStateKey } from './utils';
|
|
6
5
|
import { stringifyOpenAPI } from './stringifyOpenAPI';
|
|
7
|
-
import {
|
|
8
|
-
import { checkIsReference } from './utils';
|
|
6
|
+
import type { OpenAPIContextProps, OpenAPIOperationData } from './types';
|
|
9
7
|
import { getDefaultServerURL } from './util/server';
|
|
8
|
+
import { checkIsReference, createStateKey } from './utils';
|
|
10
9
|
|
|
11
10
|
/**
|
|
12
11
|
* Display code samples to execute the operation.
|
|
@@ -37,7 +36,7 @@ export function OpenAPICodeSample(props: {
|
|
|
37
36
|
if (example !== undefined && param.name) {
|
|
38
37
|
searchParams.append(
|
|
39
38
|
param.name,
|
|
40
|
-
String(Array.isArray(example) ? example[0] : example)
|
|
39
|
+
String(Array.isArray(example) ? example[0] : example)
|
|
41
40
|
);
|
|
42
41
|
}
|
|
43
42
|
}
|
|
@@ -95,8 +94,8 @@ export function OpenAPICodeSample(props: {
|
|
|
95
94
|
typeof sample.lang === 'string'
|
|
96
95
|
);
|
|
97
96
|
})
|
|
98
|
-
.map((sample) => ({
|
|
99
|
-
key: `redocly-${sample.lang}`,
|
|
97
|
+
.map((sample, index) => ({
|
|
98
|
+
key: `redocly-${sample.lang}-${index}`,
|
|
100
99
|
label: sample.label,
|
|
101
100
|
body: context.renderCodeBlock({
|
|
102
101
|
code: sample.source,
|
|
@@ -118,9 +117,9 @@ export function OpenAPICodeSample(props: {
|
|
|
118
117
|
|
|
119
118
|
return (
|
|
120
119
|
<OpenAPITabs stateKey={createStateKey('codesample')} items={samples}>
|
|
121
|
-
<
|
|
120
|
+
<StaticSection header={<OpenAPITabsList />} className="openapi-codesample">
|
|
122
121
|
<OpenAPITabsPanels />
|
|
123
|
-
</
|
|
122
|
+
</StaticSection>
|
|
124
123
|
</OpenAPITabs>
|
|
125
124
|
);
|
|
126
125
|
}
|
|
@@ -149,7 +148,7 @@ function getSecurityHeaders(securities: OpenAPIOperationData['securities']): {
|
|
|
149
148
|
}
|
|
150
149
|
|
|
151
150
|
return {
|
|
152
|
-
Authorization: scheme
|
|
151
|
+
Authorization: `${scheme} ${format}`,
|
|
153
152
|
};
|
|
154
153
|
}
|
|
155
154
|
case 'apiKey': {
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import type React from 'react';
|
|
1
3
|
import { useRef } from 'react';
|
|
2
|
-
import type { OpenAPIClientContext } from './types';
|
|
3
4
|
import { mergeProps, useButton, useDisclosure, useFocusRing } from 'react-aria';
|
|
4
5
|
import { useDisclosureState } from 'react-stately';
|
|
6
|
+
import type { OpenAPIClientContext } from './types';
|
|
5
7
|
|
|
6
8
|
interface Props {
|
|
7
9
|
context: OpenAPIClientContext;
|
|
@@ -13,7 +15,7 @@ interface Props {
|
|
|
13
15
|
* Display an interactive OpenAPI disclosure.
|
|
14
16
|
* The label is optional and defaults to "child attributes".
|
|
15
17
|
*/
|
|
16
|
-
export function OpenAPIDisclosure({ context, children, label }: Props): JSX.Element {
|
|
18
|
+
export function OpenAPIDisclosure({ context, children, label }: Props): React.JSX.Element {
|
|
17
19
|
const state = useDisclosureState({});
|
|
18
20
|
const panelRef = useRef<HTMLDivElement | null>(null);
|
|
19
21
|
const triggerRef = useRef<HTMLButtonElement | null>(null);
|
|
@@ -36,7 +38,7 @@ export function OpenAPIDisclosure({ context, children, label }: Props): JSX.Elem
|
|
|
36
38
|
>
|
|
37
39
|
{context.icons.plus}
|
|
38
40
|
<span>
|
|
39
|
-
{`${state.isExpanded ? 'Hide' : 'Show'} ${label ? label :
|
|
41
|
+
{`${state.isExpanded ? 'Hide' : 'Show'} ${label ? label : 'child attributes'}`}
|
|
40
42
|
</span>
|
|
41
43
|
</button>
|
|
42
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;
|
|
@@ -13,15 +24,6 @@ type TDisclosureGroup = {
|
|
|
13
24
|
}[];
|
|
14
25
|
};
|
|
15
26
|
|
|
16
|
-
import { mergeProps, useButton, useDisclosure, useFocusRing, useId } from 'react-aria';
|
|
17
|
-
import {
|
|
18
|
-
DisclosureGroupProps,
|
|
19
|
-
DisclosureGroupState,
|
|
20
|
-
useDisclosureGroupState,
|
|
21
|
-
useDisclosureState,
|
|
22
|
-
} from 'react-stately';
|
|
23
|
-
import { createContext, useContext, useRef, useState } from 'react';
|
|
24
|
-
|
|
25
27
|
const DisclosureGroupStateContext = createContext<DisclosureGroupState | null>(null);
|
|
26
28
|
|
|
27
29
|
/**
|
|
@@ -67,7 +69,7 @@ function DisclosureItem(props: { group: TDisclosureGroup; icon?: React.ReactNode
|
|
|
67
69
|
isDisabled,
|
|
68
70
|
},
|
|
69
71
|
state,
|
|
70
|
-
panelRef
|
|
72
|
+
panelRef
|
|
71
73
|
);
|
|
72
74
|
const { buttonProps } = useButton(triggerProps, triggerRef);
|
|
73
75
|
const { isFocusVisible, focusProps } = useFocusRing();
|
|
@@ -119,7 +121,7 @@ function DisclosureItem(props: { group: TDisclosureGroup; icon?: React.ReactNode
|
|
|
119
121
|
</option>
|
|
120
122
|
))}
|
|
121
123
|
</select>
|
|
122
|
-
) :
|
|
124
|
+
) : group.tabs[0] ? (
|
|
123
125
|
<span>{group.tabs[0].label}</span>
|
|
124
126
|
) : null}
|
|
125
127
|
</div>
|
package/src/OpenAPIOperation.tsx
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import clsx from 'clsx';
|
|
2
2
|
|
|
3
|
+
import type { OpenAPICustomOperationProperties, OpenAPIV3 } from '@gitbook/openapi-parser';
|
|
3
4
|
import { Markdown } from './Markdown';
|
|
4
5
|
import { OpenAPICodeSample } from './OpenAPICodeSample';
|
|
6
|
+
import { OpenAPIPath } from './OpenAPIPath';
|
|
5
7
|
import { OpenAPIResponseExample } from './OpenAPIResponseExample';
|
|
6
8
|
import { OpenAPISpec } from './OpenAPISpec';
|
|
7
9
|
import type { OpenAPIClientContext, OpenAPIContextProps, OpenAPIOperationData } from './types';
|
|
8
|
-
import { OpenAPIPath } from './OpenAPIPath';
|
|
9
10
|
import { resolveDescription } from './utils';
|
|
10
|
-
import { OpenAPICustomOperationProperties, OpenAPIV3 } from '@gitbook/openapi-parser';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Display an interactive OpenAPI operation.
|
|
@@ -45,7 +45,7 @@ export function OpenAPIOperation(props: {
|
|
|
45
45
|
<span className="openapi-deprecated-sunset-date">
|
|
46
46
|
{operation['x-deprecated-sunset']}
|
|
47
47
|
</span>
|
|
48
|
-
{
|
|
48
|
+
{'.'}
|
|
49
49
|
</div>
|
|
50
50
|
) : null}
|
|
51
51
|
<OpenAPIOperationDescription operation={operation} context={context} />
|
|
@@ -20,7 +20,7 @@ const OpenAPIOperationContext = createContext<OpenAPIOperationContextValue>({
|
|
|
20
20
|
* Provider for the OpenAPIOperationContext.
|
|
21
21
|
*/
|
|
22
22
|
export function OpenAPIOperationContextProvider(
|
|
23
|
-
props: React.PropsWithChildren<Partial<OpenAPIOperationContextValue
|
|
23
|
+
props: React.PropsWithChildren<Partial<OpenAPIOperationContextValue>>
|
|
24
24
|
) {
|
|
25
25
|
const { children } = props;
|
|
26
26
|
|
package/src/OpenAPIPath.tsx
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import type React from 'react';
|
|
1
2
|
import { ScalarApiButton } from './ScalarApiButton';
|
|
2
|
-
import type {
|
|
3
|
+
import type { OpenAPIContextProps, OpenAPIOperationData } from './types';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Display the path of an operation.
|
|
@@ -7,7 +8,7 @@ import type { OpenAPIOperationData, OpenAPIContextProps } from './types';
|
|
|
7
8
|
export function OpenAPIPath(props: {
|
|
8
9
|
data: OpenAPIOperationData;
|
|
9
10
|
context: OpenAPIContextProps;
|
|
10
|
-
})
|
|
11
|
+
}) {
|
|
11
12
|
const { data, context } = props;
|
|
12
13
|
const { method, path } = data;
|
|
13
14
|
const { specUrl } = context;
|
|
@@ -30,7 +31,7 @@ function formatPath(path: string) {
|
|
|
30
31
|
// Matches placeholders like {id}, {userId}, etc.
|
|
31
32
|
const regex = /\{(\w+)\}/g;
|
|
32
33
|
|
|
33
|
-
const parts: (string | JSX.Element)[] = [];
|
|
34
|
+
const parts: (string | React.JSX.Element)[] = [];
|
|
34
35
|
let lastIndex = 0;
|
|
35
36
|
|
|
36
37
|
// Replace placeholders with <em> tags
|
|
@@ -48,17 +49,17 @@ function formatPath(path: string) {
|
|
|
48
49
|
const formattedPath = parts.reduce(
|
|
49
50
|
(acc, part, index) => {
|
|
50
51
|
if (typeof part === 'string' && index > 0 && part === '/') {
|
|
51
|
-
|
|
52
|
-
...acc,
|
|
52
|
+
acc.push(
|
|
53
53
|
<span className="openapi-path-separator" key={`sep-${index}`}>
|
|
54
54
|
/
|
|
55
|
-
</span
|
|
56
|
-
|
|
57
|
-
];
|
|
55
|
+
</span>
|
|
56
|
+
);
|
|
58
57
|
}
|
|
59
|
-
|
|
58
|
+
|
|
59
|
+
acc.push(part);
|
|
60
|
+
return acc;
|
|
60
61
|
},
|
|
61
|
-
[] as (string | JSX.Element)[]
|
|
62
|
+
[] as (string | React.JSX.Element)[]
|
|
62
63
|
);
|
|
63
64
|
|
|
64
65
|
return <span>{formattedPath}</span>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { OpenAPIV3 } from '@gitbook/openapi-parser';
|
|
2
|
+
import { InteractiveSection } from './InteractiveSection';
|
|
2
3
|
import { OpenAPIRootSchema } from './OpenAPISchema';
|
|
3
4
|
import type { OpenAPIClientContext } from './types';
|
|
4
|
-
import { InteractiveSection } from './InteractiveSection';
|
|
5
5
|
import { checkIsReference } from './utils';
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -33,7 +33,7 @@ export function OpenAPIRequestBody(props: {
|
|
|
33
33
|
/>
|
|
34
34
|
),
|
|
35
35
|
};
|
|
36
|
-
}
|
|
36
|
+
}
|
|
37
37
|
)}
|
|
38
38
|
/>
|
|
39
39
|
);
|
package/src/OpenAPIResponse.tsx
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { OpenAPIV3 } from '@gitbook/openapi-parser';
|
|
2
|
+
import { OpenAPIDisclosure } from './OpenAPIDisclosure';
|
|
2
3
|
import { OpenAPISchemaProperties } from './OpenAPISchema';
|
|
3
|
-
import { parameterToProperty, resolveDescription } from './utils';
|
|
4
4
|
import type { OpenAPIClientContext } from './types';
|
|
5
|
-
import {
|
|
5
|
+
import { parameterToProperty, resolveDescription } from './utils';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Display an interactive response body.
|
|
@@ -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, header ?? {}] as const
|
|
17
|
+
([name, header]) => [name, header ?? {}] as const
|
|
18
18
|
);
|
|
19
19
|
const content = Object.entries(mediaType.schema ?? {});
|
|
20
20
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { OpenAPIV3 } from '@gitbook/openapi-parser';
|
|
2
|
-
import { generateSchemaExample } from './generateSchemaExample';
|
|
3
|
-
import type { OpenAPIContextProps, OpenAPIOperationData } from './types';
|
|
4
|
-
import { checkIsReference, createStateKey, resolveDescription } from './utils';
|
|
5
2
|
import { OpenAPITabs, OpenAPITabsList, OpenAPITabsPanels } from './OpenAPITabs';
|
|
6
|
-
import {
|
|
3
|
+
import { StaticSection } from './StaticSection';
|
|
4
|
+
import { generateSchemaExample } from './generateSchemaExample';
|
|
7
5
|
import { json2xml } from './json2xml';
|
|
8
6
|
import { stringifyOpenAPI } from './stringifyOpenAPI';
|
|
7
|
+
import type { OpenAPIContextProps, OpenAPIOperationData } from './types';
|
|
8
|
+
import { checkIsReference, createStateKey, resolveDescription } from './utils';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Display an example of the response content.
|
|
@@ -75,7 +75,7 @@ export function OpenAPIResponseExample(props: {
|
|
|
75
75
|
};
|
|
76
76
|
})
|
|
77
77
|
.filter((val): val is { key: string; label: string; body: any; description: string } =>
|
|
78
|
-
Boolean(val)
|
|
78
|
+
Boolean(val)
|
|
79
79
|
);
|
|
80
80
|
|
|
81
81
|
if (tabs.length === 0) {
|
|
@@ -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,9 +1,9 @@
|
|
|
1
1
|
import type { OpenAPIV3, OpenAPIV3_1 } from '@gitbook/openapi-parser';
|
|
2
|
-
import { OpenAPIResponse } from './OpenAPIResponse';
|
|
3
|
-
import { OpenAPIClientContext } from './types';
|
|
4
|
-
import { InteractiveSection } from './InteractiveSection';
|
|
5
|
-
import { OpenAPIDisclosureGroup } from './OpenAPIDisclosureGroup';
|
|
6
2
|
import { Markdown } from './Markdown';
|
|
3
|
+
import { OpenAPIDisclosureGroup } from './OpenAPIDisclosureGroup';
|
|
4
|
+
import { OpenAPIResponse } from './OpenAPIResponse';
|
|
5
|
+
import { StaticSection } from './StaticSection';
|
|
6
|
+
import type { OpenAPIClientContext } from './types';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Display an interactive response body.
|
|
@@ -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}
|
|
@@ -55,9 +55,9 @@ export function OpenAPIResponses(props: {
|
|
|
55
55
|
),
|
|
56
56
|
})),
|
|
57
57
|
};
|
|
58
|
-
}
|
|
58
|
+
}
|
|
59
59
|
)}
|
|
60
60
|
/>
|
|
61
|
-
</
|
|
61
|
+
</StaticSection>
|
|
62
62
|
);
|
|
63
63
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { getSchemaAlternatives } from './OpenAPISchema';
|
|
1
|
+
import { describe, expect, it } from 'bun:test';
|
|
3
2
|
import type { OpenAPIV3 } from '@gitbook/openapi-parser';
|
|
3
|
+
import { getSchemaAlternatives } from './OpenAPISchema';
|
|
4
4
|
|
|
5
5
|
describe('getSchemaAlternatives', () => {
|
|
6
6
|
it('should flatten oneOf', () => {
|
|
@@ -21,7 +21,7 @@ describe('getSchemaAlternatives', () => {
|
|
|
21
21
|
type: 'string',
|
|
22
22
|
},
|
|
23
23
|
],
|
|
24
|
-
})
|
|
24
|
+
})
|
|
25
25
|
).toEqual([
|
|
26
26
|
[
|
|
27
27
|
{
|
|
@@ -56,7 +56,7 @@ describe('getSchemaAlternatives', () => {
|
|
|
56
56
|
type: 'string',
|
|
57
57
|
},
|
|
58
58
|
],
|
|
59
|
-
})
|
|
59
|
+
})
|
|
60
60
|
).toEqual([
|
|
61
61
|
[
|
|
62
62
|
{
|
|
@@ -86,7 +86,7 @@ describe('getSchemaAlternatives', () => {
|
|
|
86
86
|
],
|
|
87
87
|
};
|
|
88
88
|
|
|
89
|
-
a.anyOf
|
|
89
|
+
a.anyOf?.push(a);
|
|
90
90
|
|
|
91
91
|
expect(getSchemaAlternatives(a)).toEqual([
|
|
92
92
|
[
|