@gitbook/react-openapi 0.7.1 → 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 +41 -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 +3 -3
- 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 +11 -10
- 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 +84 -7
- 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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,46 @@
|
|
|
1
1
|
# @gitbook/react-openapi
|
|
2
2
|
|
|
3
|
+
## 1.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- 727bde2: Improve and split OpenAPI parser into its own package
|
|
8
|
+
- 12c7862: Use `@scalar/openapi-parser` to be more resilient and perf on OpenAPI spec parsing:
|
|
9
|
+
|
|
10
|
+
- `fetcher.fetch` must now returns a valid OpenAPI document
|
|
11
|
+
- `parseOpenAPIV3` has been replaced by `parseOpenAPI`
|
|
12
|
+
|
|
13
|
+
### Minor Changes
|
|
14
|
+
|
|
15
|
+
- 162b4b7: Add in HTTP example code blocks
|
|
16
|
+
- e4e2f52: Add an optional client context to get a callback called when the Scalar client is opened for a block.
|
|
17
|
+
- eb7c22f: Revert scalar to 1.0.87 to mitigate an issue with ApiClientModalProvider
|
|
18
|
+
- 160fca1: new OpenAPI blocks design
|
|
19
|
+
- e721f17: Use `@scalar/oas-utils` getExampleFromSchema to generate OpenAPI examples
|
|
20
|
+
- fe8acc9: Fix an issue where a missing OpenAPI example would crash the page.
|
|
21
|
+
- 1823101: Fix internal properties appearing in OpenAPI docs.
|
|
22
|
+
|
|
23
|
+
### Patch Changes
|
|
24
|
+
|
|
25
|
+
- d9029c7: Support apiKey in CodeSample security headers
|
|
26
|
+
- 6e54a06: Support response examples
|
|
27
|
+
- 0c03676: Better securities sample and headers
|
|
28
|
+
- 3e5e458: Handle isArray schema type
|
|
29
|
+
- 46edde9: Improve the OpenAPI package API
|
|
30
|
+
- d9c8d57: Do not dereference before caching OpenAPI spec.
|
|
31
|
+
- ccf2cff: Fix an issue where a response object using a special ref would crash the page.
|
|
32
|
+
- dda0cc6: Flatten OpenAPI security object
|
|
33
|
+
- f92e906: Prevent codemirror from loading multiple versions in scalar
|
|
34
|
+
- dff08ae: Improve performances by loading Scalar API Client only when the button is clicked
|
|
35
|
+
- fc7b16f: Updated scalar depdenency
|
|
36
|
+
- a652958: Fix error on unresolvable refs by replacing with property name and any type
|
|
37
|
+
- 2f73db7: Support non primitive examples in OpenAPI block
|
|
38
|
+
- 160fca1: Support deprecated and x-deprecated-sunset in OpenAPI spec
|
|
39
|
+
- b41d425: Improve OpenAPI rendering performances by caching markdown parsing
|
|
40
|
+
- Updated dependencies [46edde9]
|
|
41
|
+
- Updated dependencies [727bde2]
|
|
42
|
+
- @gitbook/openapi-parser@1.0.0
|
|
43
|
+
|
|
3
44
|
## 0.7.1
|
|
4
45
|
|
|
5
46
|
### Patch Changes
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
1
|
interface InteractiveSectionTab {
|
|
3
2
|
key: string;
|
|
4
3
|
label: string;
|
|
@@ -16,20 +15,19 @@ export declare function InteractiveSection(props: {
|
|
|
16
15
|
toggeable?: boolean;
|
|
17
16
|
/** Default state of the toggle */
|
|
18
17
|
defaultOpened?: boolean;
|
|
19
|
-
/**
|
|
20
|
-
|
|
21
|
-
toggleCloseIcon?: React.ReactNode;
|
|
18
|
+
/** Icon to display for the toggle */
|
|
19
|
+
toggleIcon?: React.ReactNode;
|
|
22
20
|
/** Tabs of content to display */
|
|
23
21
|
tabs?: Array<InteractiveSectionTab>;
|
|
24
22
|
/** Default tab to have opened */
|
|
25
23
|
defaultTab?: string;
|
|
26
24
|
/** Content of the header */
|
|
27
|
-
header
|
|
25
|
+
header?: React.ReactNode;
|
|
28
26
|
/** Body of the section */
|
|
29
27
|
children?: React.ReactNode;
|
|
30
28
|
/** Children to display within the container */
|
|
31
29
|
overlay?: React.ReactNode;
|
|
32
30
|
/** An optional key referencing a value in global state */
|
|
33
31
|
stateKey?: string;
|
|
34
|
-
}):
|
|
32
|
+
}): import("react").JSX.Element;
|
|
35
33
|
export {};
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
var __assign = (this && this.__assign) || function () {
|
|
3
|
+
__assign = Object.assign || function(t) {
|
|
4
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
+
s = arguments[i];
|
|
6
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
+
t[p] = s[p];
|
|
8
|
+
}
|
|
9
|
+
return t;
|
|
10
|
+
};
|
|
11
|
+
return __assign.apply(this, arguments);
|
|
12
|
+
};
|
|
13
|
+
import clsx from 'clsx';
|
|
14
|
+
import { useCallback, useRef, useState, useSyncExternalStore } from 'react';
|
|
15
|
+
import { mergeProps, useButton, useDisclosure, useFocusRing } from 'react-aria';
|
|
16
|
+
import { useDisclosureState } from 'react-stately';
|
|
17
|
+
var globalState = {};
|
|
18
|
+
var listeners = new Set();
|
|
19
|
+
function useSyncedTabsGlobalState() {
|
|
20
|
+
var subscribe = useCallback(function (callback) {
|
|
21
|
+
listeners.add(callback);
|
|
22
|
+
return function () { return listeners.delete(callback); };
|
|
23
|
+
}, []);
|
|
24
|
+
var getSnapshot = useCallback(function () { return globalState; }, []);
|
|
25
|
+
var setSyncedTabs = useCallback(function (updater) {
|
|
26
|
+
globalState = updater(globalState);
|
|
27
|
+
listeners.forEach(function (listener) { return listener(); });
|
|
28
|
+
}, []);
|
|
29
|
+
var tabs = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
30
|
+
return [tabs, setSyncedTabs];
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* To optimize rendering, most of the components are server-components,
|
|
34
|
+
* and the interactiveness is mainly handled by a few key components like this one.
|
|
35
|
+
*/
|
|
36
|
+
export function InteractiveSection(props) {
|
|
37
|
+
var _a, _b, _c, _d;
|
|
38
|
+
var id = props.id, className = props.className, _e = props.toggeable, toggeable = _e === void 0 ? false : _e, _f = props.defaultOpened, defaultOpened = _f === void 0 ? true : _f, _g = props.tabs, tabs = _g === void 0 ? [] : _g, _h = props.defaultTab, defaultTab = _h === void 0 ? (_a = tabs[0]) === null || _a === void 0 ? void 0 : _a.key : _h, header = props.header, children = props.children, overlay = props.overlay, _j = props.toggleIcon, toggleIcon = _j === void 0 ? '▶' : _j, stateKey = props.stateKey;
|
|
39
|
+
var _k = useSyncedTabsGlobalState(), syncedTabs = _k[0], setSyncedTabs = _k[1];
|
|
40
|
+
var tabFromState = stateKey && stateKey in syncedTabs
|
|
41
|
+
? tabs.find(function (tab) { return tab.key === syncedTabs[stateKey]; })
|
|
42
|
+
: undefined;
|
|
43
|
+
var _l = useState((_b = tabFromState === null || tabFromState === void 0 ? void 0 : tabFromState.key) !== null && _b !== void 0 ? _b : defaultTab), selectedTabKey = _l[0], setSelectedTab = _l[1];
|
|
44
|
+
var selectedTab = (_c = tabFromState !== null && tabFromState !== void 0 ? tabFromState : tabs.find(function (tab) { return tab.key === selectedTabKey; })) !== null && _c !== void 0 ? _c : tabs[0];
|
|
45
|
+
var state = useDisclosureState({
|
|
46
|
+
defaultExpanded: defaultOpened,
|
|
47
|
+
});
|
|
48
|
+
var panelRef = useRef(null);
|
|
49
|
+
var triggerRef = useRef(null);
|
|
50
|
+
var _m = useDisclosure({}, state, panelRef), triggerProps = _m.buttonProps, panelProps = _m.panelProps;
|
|
51
|
+
var buttonProps = useButton(triggerProps, triggerRef).buttonProps;
|
|
52
|
+
var _o = useFocusRing(), isFocusVisible = _o.isFocusVisible, focusProps = _o.focusProps;
|
|
53
|
+
return (<div id={id} className={clsx('openapi-section', toggeable ? 'openapi-section-toggeable' : null, className, toggeable ? "".concat(className, "-").concat(state.isExpanded ? 'opened' : 'closed') : null)}>
|
|
54
|
+
{header ? (<div onClick={function () {
|
|
55
|
+
if (toggeable) {
|
|
56
|
+
state.toggle();
|
|
57
|
+
}
|
|
58
|
+
}} className={clsx('openapi-section-header', "".concat(className, "-header"))}>
|
|
59
|
+
<div className={clsx('openapi-section-header-content', "".concat(className, "-header-content"))}>
|
|
60
|
+
{(children || (selectedTab === null || selectedTab === void 0 ? void 0 : selectedTab.body)) && toggeable ? (<button {...mergeProps(buttonProps, focusProps)} ref={triggerRef} className={clsx('openapi-section-toggle', "".concat(className, "-toggle"))} style={{
|
|
61
|
+
outline: isFocusVisible
|
|
62
|
+
? '2px solid rgb(var(--primary-color-500) / 0.4)'
|
|
63
|
+
: 'none',
|
|
64
|
+
}}>
|
|
65
|
+
{toggleIcon}
|
|
66
|
+
</button>) : null}
|
|
67
|
+
{header}
|
|
68
|
+
</div>
|
|
69
|
+
<div className={clsx('openapi-section-header-controls', "".concat(className, "-header-controls"))} onClick={function (event) {
|
|
70
|
+
event.stopPropagation();
|
|
71
|
+
}}>
|
|
72
|
+
{tabs.length > 1 ? (<select className={clsx('openapi-section-select', 'openapi-select', "".concat(className, "-tabs-select"))} value={(_d = selectedTab === null || selectedTab === void 0 ? void 0 : selectedTab.key) !== null && _d !== void 0 ? _d : ''} onChange={function (event) {
|
|
73
|
+
setSelectedTab(event.target.value);
|
|
74
|
+
if (stateKey) {
|
|
75
|
+
setSyncedTabs(function (state) {
|
|
76
|
+
var _a;
|
|
77
|
+
return (__assign(__assign({}, state), (_a = {}, _a[stateKey] = event.target.value, _a)));
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
state.expand();
|
|
81
|
+
}}>
|
|
82
|
+
{tabs.map(function (tab) { return (<option key={tab.key} value={tab.key}>
|
|
83
|
+
{tab.label}
|
|
84
|
+
</option>); })}
|
|
85
|
+
</select>) : null}
|
|
86
|
+
</div>
|
|
87
|
+
</div>) : null}
|
|
88
|
+
{(!toggeable || state.isExpanded) && (children || (selectedTab === null || selectedTab === void 0 ? void 0 : selectedTab.body)) ? (<div ref={panelRef} {...panelProps} className={clsx('openapi-section-body', "".concat(className, "-body"))}>
|
|
89
|
+
{children}
|
|
90
|
+
{selectedTab === null || selectedTab === void 0 ? void 0 : selectedTab.body}
|
|
91
|
+
</div>) : null}
|
|
92
|
+
{overlay ? (<div className={clsx('openapi-section-overlay', "".concat(className, "-overlay"))}>
|
|
93
|
+
{overlay}
|
|
94
|
+
</div>) : null}
|
|
95
|
+
</div>);
|
|
96
|
+
}
|
package/dist/Markdown.d.ts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { OpenAPIOperationData } from './fetchOpenAPIOperation';
|
|
3
|
-
import { OpenAPIContextProps } from './types';
|
|
1
|
+
import type { OpenAPIContextProps, OpenAPIOperationData } from './types';
|
|
4
2
|
/**
|
|
5
3
|
* Display code samples to execute the operation.
|
|
6
4
|
* It supports the Redocly custom syntax as well (https://redocly.com/docs/api-reference-docs/specification-extensions/x-code-samples/)
|
|
@@ -8,4 +6,4 @@ import { OpenAPIContextProps } from './types';
|
|
|
8
6
|
export declare function OpenAPICodeSample(props: {
|
|
9
7
|
data: OpenAPIOperationData;
|
|
10
8
|
context: OpenAPIContextProps;
|
|
11
|
-
}):
|
|
9
|
+
}): import("react").JSX.Element | null;
|
|
@@ -0,0 +1,143 @@
|
|
|
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
|
+
};
|
|
12
|
+
import { codeSampleGenerators } from './code-samples';
|
|
13
|
+
import { generateMediaTypeExample, generateSchemaExample } from './generateSchemaExample';
|
|
14
|
+
import { InteractiveSection } from './InteractiveSection';
|
|
15
|
+
import { getServersURL } from './OpenAPIServerURL';
|
|
16
|
+
import { noReference } from './utils';
|
|
17
|
+
import { stringifyOpenAPI } from './stringifyOpenAPI';
|
|
18
|
+
import { OpenAPITabs, OpenAPITabsList, OpenAPITabsPanels } from './OpenAPITabs';
|
|
19
|
+
/**
|
|
20
|
+
* Display code samples to execute the operation.
|
|
21
|
+
* It supports the Redocly custom syntax as well (https://redocly.com/docs/api-reference-docs/specification-extensions/x-code-samples/)
|
|
22
|
+
*/
|
|
23
|
+
export function OpenAPICodeSample(props) {
|
|
24
|
+
var _a;
|
|
25
|
+
var data = props.data, context = props.context;
|
|
26
|
+
var searchParams = new URLSearchParams();
|
|
27
|
+
var headersObject = {};
|
|
28
|
+
(_a = data.operation.parameters) === null || _a === void 0 ? void 0 : _a.forEach(function (rawParam) {
|
|
29
|
+
var param = noReference(rawParam);
|
|
30
|
+
if (!param) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
if (param.in === 'header' && param.required) {
|
|
34
|
+
var example = param.schema
|
|
35
|
+
? generateSchemaExample(noReference(param.schema))
|
|
36
|
+
: undefined;
|
|
37
|
+
if (example !== undefined && param.name) {
|
|
38
|
+
headersObject[param.name] =
|
|
39
|
+
typeof example !== 'string' ? stringifyOpenAPI(example) : example;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
else if (param.in === 'query' && param.required) {
|
|
43
|
+
var example = param.schema
|
|
44
|
+
? generateSchemaExample(noReference(param.schema))
|
|
45
|
+
: undefined;
|
|
46
|
+
if (example !== undefined && param.name) {
|
|
47
|
+
searchParams.append(param.name, String(Array.isArray(example) ? example[0] : example));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
var requestBody = noReference(data.operation.requestBody);
|
|
52
|
+
var requestBodyContentEntries = (requestBody === null || requestBody === void 0 ? void 0 : requestBody.content)
|
|
53
|
+
? Object.entries(requestBody.content)
|
|
54
|
+
: undefined;
|
|
55
|
+
var requestBodyContent = requestBodyContentEntries === null || requestBodyContentEntries === void 0 ? void 0 : requestBodyContentEntries[0];
|
|
56
|
+
var input = {
|
|
57
|
+
url: getServersURL(data.servers) +
|
|
58
|
+
data.path +
|
|
59
|
+
(searchParams.size ? "?".concat(searchParams.toString()) : ''),
|
|
60
|
+
method: data.method,
|
|
61
|
+
body: requestBodyContent
|
|
62
|
+
? generateMediaTypeExample(requestBodyContent[1], { onlyRequired: true })
|
|
63
|
+
: undefined,
|
|
64
|
+
headers: __assign(__assign(__assign({}, getSecurityHeaders(data.securities)), headersObject), (requestBodyContent
|
|
65
|
+
? {
|
|
66
|
+
'Content-Type': requestBodyContent[0],
|
|
67
|
+
}
|
|
68
|
+
: undefined)),
|
|
69
|
+
};
|
|
70
|
+
var autoCodeSamples = codeSampleGenerators.map(function (generator) { return ({
|
|
71
|
+
key: "default-".concat(generator.id),
|
|
72
|
+
label: generator.label,
|
|
73
|
+
body: <context.CodeBlock code={generator.generate(input)} syntax={generator.syntax}/>,
|
|
74
|
+
}); });
|
|
75
|
+
// Use custom samples if defined
|
|
76
|
+
var customCodeSamples = null;
|
|
77
|
+
['x-custom-examples', 'x-code-samples', 'x-codeSamples'].forEach(function (key) {
|
|
78
|
+
var customSamples = data.operation[key];
|
|
79
|
+
if (customSamples && Array.isArray(customSamples)) {
|
|
80
|
+
customCodeSamples = customSamples
|
|
81
|
+
.filter(function (sample) {
|
|
82
|
+
return (typeof sample.label === 'string' &&
|
|
83
|
+
typeof sample.source === 'string' &&
|
|
84
|
+
typeof sample.lang === 'string');
|
|
85
|
+
})
|
|
86
|
+
.map(function (sample) { return ({
|
|
87
|
+
key: "redocly-".concat(sample.lang),
|
|
88
|
+
label: sample.label,
|
|
89
|
+
body: <context.CodeBlock code={sample.source} syntax={sample.lang}/>,
|
|
90
|
+
}); });
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
// Code samples can be disabled at the top-level or at the operation level
|
|
94
|
+
// If code samples are defined at the operation level, it will override the top-level setting
|
|
95
|
+
var codeSamplesDisabled = data['x-codeSamples'] === false || data.operation['x-codeSamples'] === false;
|
|
96
|
+
var samples = customCodeSamples !== null && customCodeSamples !== void 0 ? customCodeSamples : (!codeSamplesDisabled ? autoCodeSamples : []);
|
|
97
|
+
if (samples.length === 0) {
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
return (<OpenAPITabs items={samples}>
|
|
101
|
+
<InteractiveSection header={<OpenAPITabsList />} className="openapi-codesample">
|
|
102
|
+
<OpenAPITabsPanels />
|
|
103
|
+
</InteractiveSection>
|
|
104
|
+
</OpenAPITabs>);
|
|
105
|
+
}
|
|
106
|
+
function getSecurityHeaders(securities) {
|
|
107
|
+
var _a;
|
|
108
|
+
var _b, _c;
|
|
109
|
+
var security = securities[0];
|
|
110
|
+
if (!security) {
|
|
111
|
+
return {};
|
|
112
|
+
}
|
|
113
|
+
switch (security[1].type) {
|
|
114
|
+
case 'http': {
|
|
115
|
+
var scheme = security[1].scheme;
|
|
116
|
+
var format = (_b = security[1].bearerFormat) !== null && _b !== void 0 ? _b : 'YOUR_SECRET_TOKEN';
|
|
117
|
+
if (scheme === null || scheme === void 0 ? void 0 : scheme.includes('bearer')) {
|
|
118
|
+
scheme = 'Bearer';
|
|
119
|
+
}
|
|
120
|
+
else if (scheme === null || scheme === void 0 ? void 0 : scheme.includes('basic')) {
|
|
121
|
+
scheme = 'Basic';
|
|
122
|
+
format = 'username:password';
|
|
123
|
+
}
|
|
124
|
+
else if (scheme === null || scheme === void 0 ? void 0 : scheme.includes('token')) {
|
|
125
|
+
scheme = 'Token';
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
Authorization: scheme + ' ' + format,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
case 'apiKey': {
|
|
132
|
+
if (security[1].in !== 'header')
|
|
133
|
+
return {};
|
|
134
|
+
var name_1 = (_c = security[1].name) !== null && _c !== void 0 ? _c : 'Authorization';
|
|
135
|
+
return _a = {},
|
|
136
|
+
_a[name_1] = 'YOUR_API_KEY',
|
|
137
|
+
_a;
|
|
138
|
+
}
|
|
139
|
+
default: {
|
|
140
|
+
return {};
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { OpenAPIClientContext } from './types';
|
|
2
|
+
interface Props {
|
|
3
|
+
context: OpenAPIClientContext;
|
|
4
|
+
children: React.ReactNode;
|
|
5
|
+
label?: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Display an interactive OpenAPI disclosure.
|
|
9
|
+
* The label is optional and defaults to "child attributes".
|
|
10
|
+
*/
|
|
11
|
+
export declare function OpenAPIDisclosure({ context, children, label }: Props): JSX.Element;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { useRef } from 'react';
|
|
2
|
+
import { mergeProps, useButton, useDisclosure, useFocusRing } from 'react-aria';
|
|
3
|
+
import { useDisclosureState } from 'react-stately';
|
|
4
|
+
/**
|
|
5
|
+
* Display an interactive OpenAPI disclosure.
|
|
6
|
+
* The label is optional and defaults to "child attributes".
|
|
7
|
+
*/
|
|
8
|
+
export function OpenAPIDisclosure(_a) {
|
|
9
|
+
var context = _a.context, children = _a.children, label = _a.label;
|
|
10
|
+
var state = useDisclosureState({});
|
|
11
|
+
var panelRef = useRef(null);
|
|
12
|
+
var triggerRef = useRef(null);
|
|
13
|
+
var _b = useDisclosure({}, state, panelRef), triggerProps = _b.buttonProps, panelProps = _b.panelProps;
|
|
14
|
+
var buttonProps = useButton(triggerProps, triggerRef).buttonProps;
|
|
15
|
+
var _c = useFocusRing(), isFocusVisible = _c.isFocusVisible, focusProps = _c.focusProps;
|
|
16
|
+
return (<div className="openapi-disclosure">
|
|
17
|
+
<button ref={triggerRef} {...mergeProps(buttonProps, focusProps)} slot="trigger" className="openapi-disclosure-trigger" style={{
|
|
18
|
+
outline: isFocusVisible
|
|
19
|
+
? '2px solid rgb(var(--primary-color-500) / 0.4)'
|
|
20
|
+
: 'none',
|
|
21
|
+
}}>
|
|
22
|
+
{context.icons.plus}
|
|
23
|
+
<span>
|
|
24
|
+
{"".concat(state.isExpanded ? 'Hide' : 'Show', " ").concat(label ? label : "child attributes")}
|
|
25
|
+
</span>
|
|
26
|
+
</button>
|
|
27
|
+
|
|
28
|
+
{state.isExpanded && (<div ref={panelRef} {...panelProps} className="openapi-disclosure-panel">
|
|
29
|
+
{children}
|
|
30
|
+
</div>)}
|
|
31
|
+
</div>);
|
|
32
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
groups: TDisclosureGroup[];
|
|
3
|
+
icon?: React.ReactNode;
|
|
4
|
+
}
|
|
5
|
+
type TDisclosureGroup = {
|
|
6
|
+
id: string;
|
|
7
|
+
label: string | React.ReactNode;
|
|
8
|
+
tabs?: {
|
|
9
|
+
id: string;
|
|
10
|
+
label: string | React.ReactNode;
|
|
11
|
+
body?: React.ReactNode;
|
|
12
|
+
}[];
|
|
13
|
+
};
|
|
14
|
+
import { DisclosureGroupProps } from 'react-stately';
|
|
15
|
+
/**
|
|
16
|
+
* Display an interactive OpenAPI disclosure group.
|
|
17
|
+
*/
|
|
18
|
+
export declare function OpenAPIDisclosureGroup(props: DisclosureGroupProps & Props): import("react").JSX.Element;
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,81 @@
|
|
|
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
|
+
};
|
|
12
|
+
import { mergeProps, useButton, useDisclosure, useFocusRing, useId } from 'react-aria';
|
|
13
|
+
import { useDisclosureGroupState, useDisclosureState, } from 'react-stately';
|
|
14
|
+
import { createContext, useContext, useRef, useState } from 'react';
|
|
15
|
+
var DisclosureGroupStateContext = createContext(null);
|
|
16
|
+
/**
|
|
17
|
+
* Display an interactive OpenAPI disclosure group.
|
|
18
|
+
*/
|
|
19
|
+
export function OpenAPIDisclosureGroup(props) {
|
|
20
|
+
var icon = props.icon, groups = props.groups;
|
|
21
|
+
var state = useDisclosureGroupState(props);
|
|
22
|
+
return (<DisclosureGroupStateContext.Provider value={state}>
|
|
23
|
+
{groups.map(function (group) { return (<DisclosureItem icon={icon} key={group.id} group={group}/>); })}
|
|
24
|
+
</DisclosureGroupStateContext.Provider>);
|
|
25
|
+
}
|
|
26
|
+
function DisclosureItem(props) {
|
|
27
|
+
var _a, _b, _c, _d, _e;
|
|
28
|
+
var icon = props.icon, group = props.group;
|
|
29
|
+
var defaultId = useId();
|
|
30
|
+
var id = group.id || defaultId;
|
|
31
|
+
var groupState = useContext(DisclosureGroupStateContext);
|
|
32
|
+
var isExpanded = (groupState === null || groupState === void 0 ? void 0 : groupState.expandedKeys.has(id)) || false;
|
|
33
|
+
var state = useDisclosureState({
|
|
34
|
+
isExpanded: isExpanded,
|
|
35
|
+
onExpandedChange: function () {
|
|
36
|
+
if (groupState) {
|
|
37
|
+
groupState.toggleKey(id);
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
var panelRef = useRef(null);
|
|
42
|
+
var triggerRef = useRef(null);
|
|
43
|
+
var isDisabled = (groupState === null || groupState === void 0 ? void 0 : groupState.isDisabled) || !((_a = group.tabs) === null || _a === void 0 ? void 0 : _a.length) || false;
|
|
44
|
+
var _f = useDisclosure(__assign(__assign({}, props), { isExpanded: isExpanded, isDisabled: isDisabled }), state, panelRef), triggerProps = _f.buttonProps, panelProps = _f.panelProps;
|
|
45
|
+
var buttonProps = useButton(triggerProps, triggerRef).buttonProps;
|
|
46
|
+
var _g = useFocusRing(), isFocusVisible = _g.isFocusVisible, focusProps = _g.focusProps;
|
|
47
|
+
var defaultTab = ((_c = (_b = group.tabs) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.id) || '';
|
|
48
|
+
var _h = useState(defaultTab), selectedTabKey = _h[0], setSelectedTabKey = _h[1];
|
|
49
|
+
var selectedTab = (_d = group.tabs) === null || _d === void 0 ? void 0 : _d.find(function (tab) { return tab.id === selectedTabKey; });
|
|
50
|
+
return (<div className="openapi-disclosure-group" aria-expanded={state.isExpanded}>
|
|
51
|
+
<div className="openapi-disclosure-group-header">
|
|
52
|
+
<button slot="trigger" ref={triggerRef} {...mergeProps(buttonProps, focusProps)} disabled={isDisabled} style={{
|
|
53
|
+
outline: isFocusVisible
|
|
54
|
+
? '2px solid rgb(var(--primary-color-500)/0.4)'
|
|
55
|
+
: 'none',
|
|
56
|
+
}} className="openapi-disclosure-group-trigger">
|
|
57
|
+
<div className="openapi-disclosure-group-icon">
|
|
58
|
+
{icon || (<svg viewBox="0 0 24 24" className="openapi-disclosure-group-icon">
|
|
59
|
+
<path d="m8.25 4.5 7.5 7.5-7.5 7.5"/>
|
|
60
|
+
</svg>)}
|
|
61
|
+
</div>
|
|
62
|
+
|
|
63
|
+
{group.label}
|
|
64
|
+
</button>
|
|
65
|
+
{group.tabs ? (<div className="openapi-disclosure-group-mediatype">
|
|
66
|
+
{((_e = group.tabs) === null || _e === void 0 ? void 0 : _e.length) > 1 ? (<select className="openapi-section-select openapi-select openapi-disclosure-group-tabs-select" onClick={function (event) { return event.stopPropagation(); }} value={selectedTab === null || selectedTab === void 0 ? void 0 : selectedTab.id} onChange={function (event) {
|
|
67
|
+
setSelectedTabKey(event.target.value);
|
|
68
|
+
state.expand();
|
|
69
|
+
}}>
|
|
70
|
+
{group.tabs.map(function (tab) { return (<option key={tab.id} value={tab.id}>
|
|
71
|
+
{tab.label}
|
|
72
|
+
</option>); })}
|
|
73
|
+
</select>) : !!group.tabs[0] ? (<span>{group.tabs[0].label}</span>) : null}
|
|
74
|
+
</div>) : null}
|
|
75
|
+
</div>
|
|
76
|
+
|
|
77
|
+
{state.isExpanded && selectedTab && (<div className="openapi-disclosure-group-panel" ref={panelRef} {...panelProps}>
|
|
78
|
+
{selectedTab.body}
|
|
79
|
+
</div>)}
|
|
80
|
+
</div>);
|
|
81
|
+
}
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { OpenAPIOperationData } from './fetchOpenAPIOperation';
|
|
3
|
-
import { OpenAPIContextProps } from './types';
|
|
1
|
+
import type { OpenAPIContextProps, OpenAPIOperationData } from './types';
|
|
4
2
|
/**
|
|
5
3
|
* Display an interactive OpenAPI operation.
|
|
6
4
|
*/
|
|
@@ -8,4 +6,4 @@ export declare function OpenAPIOperation(props: {
|
|
|
8
6
|
className?: string;
|
|
9
7
|
data: OpenAPIOperationData;
|
|
10
8
|
context: OpenAPIContextProps;
|
|
11
|
-
}):
|
|
9
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import clsx from 'clsx';
|
|
2
|
+
import { Markdown } from './Markdown';
|
|
3
|
+
import { OpenAPICodeSample } from './OpenAPICodeSample';
|
|
4
|
+
import { OpenAPIResponseExample } from './OpenAPIResponseExample';
|
|
5
|
+
import { OpenAPISpec } from './OpenAPISpec';
|
|
6
|
+
import { OpenAPIPath } from './OpenAPIPath';
|
|
7
|
+
import { resolveDescription } from './utils';
|
|
8
|
+
/**
|
|
9
|
+
* Display an interactive OpenAPI operation.
|
|
10
|
+
*/
|
|
11
|
+
export function OpenAPIOperation(props) {
|
|
12
|
+
var _a;
|
|
13
|
+
var className = props.className, data = props.data, context = props.context;
|
|
14
|
+
var operation = data.operation;
|
|
15
|
+
var clientContext = {
|
|
16
|
+
defaultInteractiveOpened: context.defaultInteractiveOpened,
|
|
17
|
+
icons: context.icons,
|
|
18
|
+
blockKey: context.blockKey,
|
|
19
|
+
};
|
|
20
|
+
var description = (_a = resolveDescription(operation)) === null || _a === void 0 ? void 0 : _a.trim();
|
|
21
|
+
return (<div className={clsx('openapi-operation', className)}>
|
|
22
|
+
<div className="openapi-summary" id={context.id}>
|
|
23
|
+
<h2 className="openapi-summary-title" data-deprecated={operation.deprecated}>
|
|
24
|
+
{operation.summary}
|
|
25
|
+
</h2>
|
|
26
|
+
{operation.deprecated && <div className="openapi-deprecated">Deprecated</div>}
|
|
27
|
+
</div>
|
|
28
|
+
<div className="openapi-columns">
|
|
29
|
+
<div className="openapi-column-spec">
|
|
30
|
+
{operation['x-deprecated-sunset'] ? (<div className="openapi-deprecated-sunset openapi-description openapi-markdown">
|
|
31
|
+
This operation is deprecated and will be sunset on{' '}
|
|
32
|
+
<span className="openapi-deprecated-sunset-date">
|
|
33
|
+
{operation['x-deprecated-sunset']}
|
|
34
|
+
</span>
|
|
35
|
+
{"."}
|
|
36
|
+
</div>) : null}
|
|
37
|
+
{description ? (<div className="openapi-intro">
|
|
38
|
+
<Markdown className="openapi-description" source={description}/>
|
|
39
|
+
</div>) : null}
|
|
40
|
+
<OpenAPIPath data={data} context={context}/>
|
|
41
|
+
<OpenAPISpec data={data} context={clientContext}/>
|
|
42
|
+
</div>
|
|
43
|
+
<div className="openapi-column-preview">
|
|
44
|
+
<div className="openapi-column-preview-body">
|
|
45
|
+
<OpenAPICodeSample {...props}/>
|
|
46
|
+
<OpenAPIResponseExample {...props}/>
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
49
|
+
</div>
|
|
50
|
+
</div>);
|
|
51
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
interface OpenAPIOperationPointer {
|
|
2
|
+
path: string;
|
|
3
|
+
method: string;
|
|
4
|
+
}
|
|
5
|
+
interface OpenAPIOperationContextValue {
|
|
6
|
+
onOpenClient: (pointer: OpenAPIOperationPointer) => void;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Provider for the OpenAPIOperationContext.
|
|
10
|
+
*/
|
|
11
|
+
export declare function OpenAPIOperationContextProvider(props: React.PropsWithChildren<Partial<OpenAPIOperationContextValue>>): import("react").JSX.Element;
|
|
12
|
+
/**
|
|
13
|
+
* Hook to access the OpenAPIOperationContext.
|
|
14
|
+
*/
|
|
15
|
+
export declare function useOpenAPIOperationContext(): OpenAPIOperationContextValue;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { createContext, useContext, useMemo } from 'react';
|
|
3
|
+
import { useEventCallback } from 'usehooks-ts';
|
|
4
|
+
var OpenAPIOperationContext = createContext({
|
|
5
|
+
onOpenClient: function () { },
|
|
6
|
+
});
|
|
7
|
+
/**
|
|
8
|
+
* Provider for the OpenAPIOperationContext.
|
|
9
|
+
*/
|
|
10
|
+
export function OpenAPIOperationContextProvider(props) {
|
|
11
|
+
var children = props.children;
|
|
12
|
+
var onOpenClient = useEventCallback(function (pointer) {
|
|
13
|
+
var _a;
|
|
14
|
+
(_a = props.onOpenClient) === null || _a === void 0 ? void 0 : _a.call(props, pointer);
|
|
15
|
+
});
|
|
16
|
+
var value = useMemo(function () { return ({ onOpenClient: onOpenClient }); }, [onOpenClient]);
|
|
17
|
+
return (<OpenAPIOperationContext.Provider value={value}>
|
|
18
|
+
{children}
|
|
19
|
+
</OpenAPIOperationContext.Provider>);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Hook to access the OpenAPIOperationContext.
|
|
23
|
+
*/
|
|
24
|
+
export function useOpenAPIOperationContext() {
|
|
25
|
+
return useContext(OpenAPIOperationContext);
|
|
26
|
+
}
|