@gitbook/react-openapi 1.0.2 → 1.0.4
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 +24 -0
- package/dist/OpenAPICodeSample.jsx +17 -16
- package/dist/OpenAPIDisclosure.d.ts +2 -1
- package/dist/OpenAPIDisclosure.jsx +1 -1
- package/dist/OpenAPIDisclosureGroup.d.ts +1 -1
- package/dist/OpenAPIDisclosureGroup.jsx +2 -2
- package/dist/OpenAPIOperation.jsx +21 -7
- 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 +6 -5
- package/dist/OpenAPIResponses.d.ts +1 -1
- package/dist/OpenAPIResponses.jsx +2 -2
- package/dist/OpenAPISchema.d.ts +5 -1
- package/dist/OpenAPISchema.jsx +72 -61
- package/dist/OpenAPISchemaName.d.ts +5 -3
- package/dist/OpenAPISchemaName.jsx +25 -4
- package/dist/OpenAPISecurities.jsx +2 -2
- package/dist/OpenAPITabs.d.ts +3 -3
- package/dist/OpenAPITabs.jsx +17 -14
- package/dist/ScalarApiButton.jsx +1 -1
- package/dist/code-samples.js +239 -17
- package/dist/contentTypeChecks.d.ts +9 -0
- package/dist/contentTypeChecks.js +27 -0
- package/dist/generateSchemaExample.js +2 -1
- package/dist/resolveOpenAPIOperation.d.ts +3 -3
- package/dist/resolveOpenAPIOperation.js +1 -1
- package/dist/stringifyOpenAPI.d.ts +1 -1
- package/dist/stringifyOpenAPI.js +8 -2
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/types.d.ts +14 -2
- package/dist/util/server.d.ts +9 -0
- package/dist/util/server.js +44 -0
- package/dist/utils.d.ts +2 -2
- package/dist/utils.js +7 -6
- package/package.json +3 -8
- package/src/InteractiveSection.tsx +4 -4
- package/src/OpenAPICodeSample.tsx +20 -19
- package/src/OpenAPIDisclosure.tsx +4 -3
- package/src/OpenAPIDisclosureGroup.tsx +5 -5
- package/src/OpenAPIOperation.tsx +32 -10
- 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 +7 -6
- package/src/OpenAPIResponses.tsx +4 -4
- package/src/OpenAPISchema.test.ts +5 -5
- package/src/OpenAPISchema.tsx +134 -73
- package/src/OpenAPISchemaName.tsx +40 -7
- package/src/OpenAPISecurities.tsx +3 -3
- package/src/OpenAPITabs.tsx +23 -17
- package/src/ScalarApiButton.tsx +3 -3
- package/src/code-samples.test.ts +594 -2
- package/src/code-samples.ts +238 -17
- package/src/contentTypeChecks.ts +35 -0
- package/src/generateSchemaExample.ts +22 -18
- package/src/json2xml.test.ts +1 -1
- package/src/resolveOpenAPIOperation.test.ts +6 -6
- package/src/resolveOpenAPIOperation.ts +7 -7
- package/src/stringifyOpenAPI.ts +13 -2
- package/src/types.ts +11 -1
- package/src/util/server.test.ts +58 -0
- package/src/util/server.ts +47 -0
- package/src/utils.ts +9 -5
- package/dist/OpenAPIServerURL.d.ts +0 -11
- package/dist/OpenAPIServerURL.jsx +0 -67
- package/dist/OpenAPIServerURLVariable.d.ts +0 -8
- package/dist/OpenAPIServerURLVariable.jsx +0 -8
- package/src/OpenAPIServerURL.tsx +0 -73
- package/src/OpenAPIServerURLVariable.tsx +0 -14
|
@@ -35,12 +35,12 @@ function getLabelForType(security) {
|
|
|
35
35
|
if (security.scheme === 'basic') {
|
|
36
36
|
return <OpenAPISchemaName propertyName="Authorization" type="string" required/>;
|
|
37
37
|
}
|
|
38
|
-
if (security.scheme
|
|
38
|
+
if (security.scheme === 'bearer') {
|
|
39
39
|
var description = resolveDescription(security);
|
|
40
40
|
return (<>
|
|
41
41
|
<OpenAPISchemaName propertyName="Authorization" type="string" required/>
|
|
42
42
|
{/** Show a default description if none is provided */}
|
|
43
|
-
{!description ? (<Markdown source={"Bearer authentication header of the form Bearer ".concat(
|
|
43
|
+
{!description ? (<Markdown source={"Bearer authentication header of the form Bearer ".concat('<token>', ".")} className="openapi-securities-description"/>) : null}
|
|
44
44
|
</>);
|
|
45
45
|
}
|
|
46
46
|
return <OpenAPISchemaName propertyName="HTTP" required/>;
|
package/dist/OpenAPITabs.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Key, TabsProps } from 'react-aria-components';
|
|
2
|
-
export type
|
|
1
|
+
import { type Key, type TabsProps } from 'react-aria-components';
|
|
2
|
+
export type TabItem = {
|
|
3
3
|
key: Key;
|
|
4
4
|
label: string;
|
|
5
5
|
body: React.ReactNode;
|
|
@@ -9,7 +9,7 @@ export type Tab = {
|
|
|
9
9
|
* The OpenAPI Tabs wrapper component.
|
|
10
10
|
*/
|
|
11
11
|
export declare function OpenAPITabs(props: React.PropsWithChildren<TabsProps & {
|
|
12
|
-
items:
|
|
12
|
+
items: TabItem[];
|
|
13
13
|
stateKey?: string;
|
|
14
14
|
}>): import("react").JSX.Element;
|
|
15
15
|
/**
|
package/dist/OpenAPITabs.jsx
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { createContext, useContext, useEffect, useMemo, useState } from 'react';
|
|
3
3
|
import { Tab, TabList, TabPanel, Tabs } from 'react-aria-components';
|
|
4
|
+
import { useIntersectionObserver } from 'usehooks-ts';
|
|
4
5
|
import { Markdown } from './Markdown';
|
|
5
6
|
import { useSyncedTabsGlobalState } from './useSyncedTabsGlobalState';
|
|
6
|
-
import { useIntersectionObserver } from 'usehooks-ts';
|
|
7
7
|
var OpenAPITabsContext = createContext(null);
|
|
8
8
|
function useOpenAPITabsContext() {
|
|
9
9
|
var context = useContext(OpenAPITabsContext);
|
|
@@ -17,23 +17,22 @@ function useOpenAPITabsContext() {
|
|
|
17
17
|
*/
|
|
18
18
|
export function OpenAPITabs(props) {
|
|
19
19
|
var children = props.children, items = props.items, stateKey = props.stateKey;
|
|
20
|
-
var
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
: true;
|
|
20
|
+
var _a = useIntersectionObserver({
|
|
21
|
+
threshold: 0.1,
|
|
22
|
+
rootMargin: '200px',
|
|
23
|
+
}), ref = _a[0], isIntersectionVisible = _a[1];
|
|
24
|
+
var isVisible = stateKey ? isIntersectionVisible : true;
|
|
26
25
|
var defaultTab = items[0];
|
|
27
|
-
var
|
|
28
|
-
var
|
|
26
|
+
var _b = useSyncedTabsGlobalState(), syncedTabs = _b[0], setSyncedTabs = _b[1];
|
|
27
|
+
var _c = useState(function () {
|
|
29
28
|
var _a, _b, _c;
|
|
30
29
|
if (isVisible && stateKey && syncedTabs && syncedTabs.has(stateKey)) {
|
|
31
30
|
var tabFromState = syncedTabs.get(stateKey);
|
|
32
31
|
return (_a = tabFromState === null || tabFromState === void 0 ? void 0 : tabFromState.key) !== null && _a !== void 0 ? _a : (_b = items[0]) === null || _b === void 0 ? void 0 : _b.key;
|
|
33
32
|
}
|
|
34
33
|
return (_c = items[0]) === null || _c === void 0 ? void 0 : _c.key;
|
|
35
|
-
}), selectedTabKey =
|
|
36
|
-
var
|
|
34
|
+
}), selectedTabKey = _c[0], setSelectedTabKey = _c[1];
|
|
35
|
+
var _d = useState(defaultTab), selectedTab = _d[0], setSelectedTab = _d[1];
|
|
37
36
|
var handleSelectionChange = function (key) {
|
|
38
37
|
setSelectedTabKey(key);
|
|
39
38
|
if (stateKey) {
|
|
@@ -52,16 +51,20 @@ export function OpenAPITabs(props) {
|
|
|
52
51
|
if (isVisible && stateKey && syncedTabs && syncedTabs.has(stateKey)) {
|
|
53
52
|
var tabFromState_1 = syncedTabs.get(stateKey);
|
|
54
53
|
if (!items.some(function (item) { return item.key === (tabFromState_1 === null || tabFromState_1 === void 0 ? void 0 : tabFromState_1.key); })) {
|
|
55
|
-
return;
|
|
54
|
+
return setSelectedTab(defaultTab);
|
|
56
55
|
}
|
|
57
56
|
if (tabFromState_1 && (tabFromState_1 === null || tabFromState_1 === void 0 ? void 0 : tabFromState_1.key) !== (selectedTab === null || selectedTab === void 0 ? void 0 : selectedTab.key)) {
|
|
58
|
-
|
|
57
|
+
var tabFromItems = items.find(function (item) { return item.key === tabFromState_1.key; });
|
|
58
|
+
if (!tabFromItems) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
setSelectedTab(tabFromItems);
|
|
59
62
|
}
|
|
60
63
|
}
|
|
61
64
|
}, [isVisible, stateKey, syncedTabs, selectedTabKey]);
|
|
62
65
|
var contextValue = useMemo(function () { return ({ items: items, selectedTab: selectedTab }); }, [items, selectedTab]);
|
|
63
66
|
return (<OpenAPITabsContext.Provider value={contextValue}>
|
|
64
|
-
<Tabs className="openapi-tabs" onSelectionChange={handleSelectionChange} selectedKey={selectedTab === null || selectedTab === void 0 ? void 0 : selectedTab.key}>
|
|
67
|
+
<Tabs ref={ref} className="openapi-tabs" onSelectionChange={handleSelectionChange} selectedKey={selectedTab === null || selectedTab === void 0 ? void 0 : selectedTab.key}>
|
|
65
68
|
{children}
|
|
66
69
|
</Tabs>
|
|
67
70
|
</OpenAPITabsContext.Provider>);
|
package/dist/ScalarApiButton.jsx
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
import { ApiClientModalProvider, useApiClientModal } from '@scalar/api-client-react';
|
|
3
3
|
import { useEffect, useImperativeHandle, useRef, useState } from 'react';
|
|
4
4
|
import { createPortal } from 'react-dom';
|
|
5
|
-
import { useOpenAPIOperationContext } from './OpenAPIOperationContext';
|
|
6
5
|
import { useEventCallback } from 'usehooks-ts';
|
|
6
|
+
import { useOpenAPIOperationContext } from './OpenAPIOperationContext';
|
|
7
7
|
/**
|
|
8
8
|
* Button which launches the Scalar API Client
|
|
9
9
|
*/
|
package/dist/code-samples.js
CHANGED
|
@@ -9,6 +9,7 @@ var __assign = (this && this.__assign) || function () {
|
|
|
9
9
|
};
|
|
10
10
|
return __assign.apply(this, arguments);
|
|
11
11
|
};
|
|
12
|
+
import { isCSV, isFormData, isFormUrlEncoded, isGraphQL, isPDF, isPlainObject, isText, isXML, } from './contentTypeChecks';
|
|
12
13
|
import { stringifyOpenAPI } from './stringifyOpenAPI';
|
|
13
14
|
export var codeSampleGenerators = [
|
|
14
15
|
{
|
|
@@ -23,14 +24,26 @@ export var codeSampleGenerators = [
|
|
|
23
24
|
lines.push("--request ".concat(method.toUpperCase()));
|
|
24
25
|
}
|
|
25
26
|
lines.push("--url '".concat(url, "'"));
|
|
26
|
-
if (
|
|
27
|
+
if (body) {
|
|
28
|
+
var bodyContent = BodyGenerators.getCurlBody(body, headers);
|
|
29
|
+
if (bodyContent) {
|
|
30
|
+
body = bodyContent.body;
|
|
31
|
+
headers = bodyContent.headers;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (headers && Object.keys(headers).length > 0) {
|
|
27
35
|
Object.entries(headers).forEach(function (_a) {
|
|
28
36
|
var key = _a[0], value = _a[1];
|
|
29
37
|
lines.push("--header '".concat(key, ": ").concat(value, "'"));
|
|
30
38
|
});
|
|
31
39
|
}
|
|
32
|
-
if (body
|
|
33
|
-
|
|
40
|
+
if (body) {
|
|
41
|
+
if (Array.isArray(body)) {
|
|
42
|
+
lines.push.apply(lines, body);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
lines.push(body);
|
|
46
|
+
}
|
|
34
47
|
}
|
|
35
48
|
return lines.map(function (line, index) { return (index > 0 ? indent(line, 2) : line); }).join(separator);
|
|
36
49
|
},
|
|
@@ -42,15 +55,24 @@ export var codeSampleGenerators = [
|
|
|
42
55
|
generate: function (_a) {
|
|
43
56
|
var method = _a.method, url = _a.url, headers = _a.headers, body = _a.body;
|
|
44
57
|
var code = '';
|
|
58
|
+
if (body) {
|
|
59
|
+
var lines = BodyGenerators.getJavaScriptBody(body, headers);
|
|
60
|
+
if (lines) {
|
|
61
|
+
// add the generated code to the top
|
|
62
|
+
code += lines.code;
|
|
63
|
+
body = lines.body;
|
|
64
|
+
headers = lines.headers;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
45
67
|
code += "const response = await fetch('".concat(url, "', {\n method: '").concat(method.toUpperCase(), "',\n");
|
|
46
|
-
if (headers) {
|
|
68
|
+
if (headers && Object.keys(headers).length > 0) {
|
|
47
69
|
code += indent("headers: ".concat(stringifyOpenAPI(headers, null, 2), ",\n"), 4);
|
|
48
70
|
}
|
|
49
71
|
if (body) {
|
|
50
|
-
code += indent("body:
|
|
72
|
+
code += indent("body: ".concat(body, "\n"), 4);
|
|
51
73
|
}
|
|
52
|
-
code +=
|
|
53
|
-
code +=
|
|
74
|
+
code += '});\n\n';
|
|
75
|
+
code += 'const data = await response.json();';
|
|
54
76
|
return code;
|
|
55
77
|
},
|
|
56
78
|
},
|
|
@@ -61,16 +83,30 @@ export var codeSampleGenerators = [
|
|
|
61
83
|
generate: function (_a) {
|
|
62
84
|
var method = _a.method, url = _a.url, headers = _a.headers, body = _a.body;
|
|
63
85
|
var code = 'import requests\n\n';
|
|
86
|
+
if (body) {
|
|
87
|
+
var lines = BodyGenerators.getPythonBody(body, headers);
|
|
88
|
+
// add the generated code to the top
|
|
89
|
+
if (lines) {
|
|
90
|
+
code += lines.code;
|
|
91
|
+
body = lines.body;
|
|
92
|
+
headers = lines.headers;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
64
95
|
code += "response = requests.".concat(method.toLowerCase(), "(\n");
|
|
65
96
|
code += indent("\"".concat(url, "\",\n"), 4);
|
|
66
|
-
if (headers) {
|
|
97
|
+
if (headers && Object.keys(headers).length > 0) {
|
|
67
98
|
code += indent("headers=".concat(stringifyOpenAPI(headers), ",\n"), 4);
|
|
68
99
|
}
|
|
69
100
|
if (body) {
|
|
70
|
-
|
|
101
|
+
if (body === 'files') {
|
|
102
|
+
code += indent("files=".concat(body, "\n"), 4);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
code += indent("data=".concat(stringifyOpenAPI(body), "\n"), 4);
|
|
106
|
+
}
|
|
71
107
|
}
|
|
72
|
-
code += ')\n';
|
|
73
|
-
code +=
|
|
108
|
+
code += ')\n\n';
|
|
109
|
+
code += 'data = response.json()';
|
|
74
110
|
return code;
|
|
75
111
|
},
|
|
76
112
|
},
|
|
@@ -86,20 +122,24 @@ export var codeSampleGenerators = [
|
|
|
86
122
|
var bodyContent = body ? stringifyOpenAPI(body) : '';
|
|
87
123
|
// handle unicode chars with a text encoder
|
|
88
124
|
var encoder = new TextEncoder();
|
|
125
|
+
var bodyString_1 = BodyGenerators.getHTTPBody(body, headers);
|
|
126
|
+
if (bodyString_1) {
|
|
127
|
+
body = bodyString_1;
|
|
128
|
+
}
|
|
89
129
|
headers = __assign(__assign({}, headers), { 'Content-Length': encoder.encode(bodyContent).length.toString() });
|
|
90
130
|
}
|
|
91
131
|
if (!headers.hasOwnProperty('Accept')) {
|
|
92
132
|
headers.Accept = '*/*';
|
|
93
133
|
}
|
|
94
134
|
var headerString = headers
|
|
95
|
-
? Object.entries(headers)
|
|
135
|
+
? "".concat(Object.entries(headers)
|
|
96
136
|
.map(function (_a) {
|
|
97
137
|
var key = _a[0], value = _a[1];
|
|
98
|
-
return key.toLowerCase() !== 'host' ? "".concat(key, ": ").concat(value) :
|
|
138
|
+
return key.toLowerCase() !== 'host' ? "".concat(key, ": ").concat(value) : '';
|
|
99
139
|
})
|
|
100
|
-
.join('\n')
|
|
140
|
+
.join('\n'), "\n")
|
|
101
141
|
: '';
|
|
102
|
-
var bodyString = body ? "\n".concat(
|
|
142
|
+
var bodyString = body ? "\n".concat(body) : '';
|
|
103
143
|
var httpRequest = "".concat(method.toUpperCase(), " ").concat(decodeURI(path), " HTTP/1.1\nHost: ").concat(host, "\n").concat(headerString).concat(bodyString);
|
|
104
144
|
return httpRequest;
|
|
105
145
|
},
|
|
@@ -118,7 +158,7 @@ export function parseHostAndPath(url) {
|
|
|
118
158
|
var path = urlObj.pathname || '/';
|
|
119
159
|
return { host: urlObj.host, path: path };
|
|
120
160
|
}
|
|
121
|
-
catch (
|
|
161
|
+
catch (_e) {
|
|
122
162
|
// If the URL was invalid do our best to parse the URL.
|
|
123
163
|
// Check for the protocol part and pull it off to grab the host
|
|
124
164
|
var splitted = url.split('//');
|
|
@@ -128,7 +168,189 @@ export function parseHostAndPath(url) {
|
|
|
128
168
|
// pull off the host (mutates)
|
|
129
169
|
var host = parts.shift();
|
|
130
170
|
// add a leading slash and join the paths again
|
|
131
|
-
var path =
|
|
171
|
+
var path = "/".concat(parts.join('/'));
|
|
132
172
|
return { host: host, path: path };
|
|
133
173
|
}
|
|
134
174
|
}
|
|
175
|
+
// Body Generators
|
|
176
|
+
var BodyGenerators = {
|
|
177
|
+
getCurlBody: function (body, headers) {
|
|
178
|
+
if (!body || !headers)
|
|
179
|
+
return undefined;
|
|
180
|
+
// Copy headers to avoid mutating the original object
|
|
181
|
+
var headersCopy = __assign({}, headers);
|
|
182
|
+
var contentType = headersCopy['Content-Type'] || '';
|
|
183
|
+
if (isFormData(contentType)) {
|
|
184
|
+
body = isPlainObject(body)
|
|
185
|
+
? Object.entries(body).map(function (_a) {
|
|
186
|
+
var key = _a[0], value = _a[1];
|
|
187
|
+
return "--form '".concat(key, "=").concat(String(value), "'");
|
|
188
|
+
})
|
|
189
|
+
: "--form 'file=@".concat(body, "'");
|
|
190
|
+
}
|
|
191
|
+
else if (isFormUrlEncoded(contentType)) {
|
|
192
|
+
body = isPlainObject(body)
|
|
193
|
+
? "--data '".concat(Object.entries(body)
|
|
194
|
+
.map(function (_a) {
|
|
195
|
+
var key = _a[0], value = _a[1];
|
|
196
|
+
return "".concat(key, "=").concat(String(value));
|
|
197
|
+
})
|
|
198
|
+
.join('&'), "'")
|
|
199
|
+
: String(body);
|
|
200
|
+
}
|
|
201
|
+
else if (isText(contentType)) {
|
|
202
|
+
body = "--data '".concat(String(body).replace(/"/g, ''), "'");
|
|
203
|
+
}
|
|
204
|
+
else if (isXML(contentType) || isCSV(contentType)) {
|
|
205
|
+
// We use --data-binary to avoid cURL converting newlines to \r\n
|
|
206
|
+
body = "--data-binary $'".concat(stringifyOpenAPI(body).replace(/"/g, ''), "'");
|
|
207
|
+
}
|
|
208
|
+
else if (isGraphQL(contentType)) {
|
|
209
|
+
body = "--data '".concat(stringifyOpenAPI(body), "'");
|
|
210
|
+
// Set Content-Type to application/json for GraphQL, recommended by GraphQL spec
|
|
211
|
+
headersCopy['Content-Type'] = 'application/json';
|
|
212
|
+
}
|
|
213
|
+
else if (isPDF(contentType)) {
|
|
214
|
+
// We use --data-binary to avoid cURL converting newlines to \r\n
|
|
215
|
+
body = "--data-binary '@".concat(String(body), "'");
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
body = "--data '".concat(stringifyOpenAPI(body, null, 2), "'");
|
|
219
|
+
}
|
|
220
|
+
return {
|
|
221
|
+
body: body,
|
|
222
|
+
headers: headersCopy,
|
|
223
|
+
};
|
|
224
|
+
},
|
|
225
|
+
getJavaScriptBody: function (body, headers) {
|
|
226
|
+
if (!body || !headers)
|
|
227
|
+
return;
|
|
228
|
+
var code = '';
|
|
229
|
+
// Copy headers to avoid mutating the original object
|
|
230
|
+
var headersCopy = __assign({}, headers);
|
|
231
|
+
var contentType = headersCopy['Content-Type'] || '';
|
|
232
|
+
// Use FormData for file uploads
|
|
233
|
+
if (isFormData(contentType)) {
|
|
234
|
+
code += 'const formData = new FormData();\n\n';
|
|
235
|
+
if (isPlainObject(body)) {
|
|
236
|
+
Object.entries(body).forEach(function (_a) {
|
|
237
|
+
var key = _a[0], value = _a[1];
|
|
238
|
+
code += "formData.append(\"".concat(key, "\", \"").concat(String(value), "\");\n");
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
else if (typeof body === 'string') {
|
|
242
|
+
code += "formData.append(\"file\", \"".concat(body, "\");\n");
|
|
243
|
+
}
|
|
244
|
+
code += '\n';
|
|
245
|
+
body = 'formData';
|
|
246
|
+
}
|
|
247
|
+
else if (isFormUrlEncoded(contentType)) {
|
|
248
|
+
// Use URLSearchParams for form-urlencoded data
|
|
249
|
+
code += 'const params = new URLSearchParams();\n\n';
|
|
250
|
+
if (isPlainObject(body)) {
|
|
251
|
+
Object.entries(body).forEach(function (_a) {
|
|
252
|
+
var key = _a[0], value = _a[1];
|
|
253
|
+
code += "params.append(\"".concat(key, "\", \"").concat(String(value), "\");\n");
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
code += '\n';
|
|
257
|
+
body = 'params.toString()';
|
|
258
|
+
}
|
|
259
|
+
else if (isGraphQL(contentType)) {
|
|
260
|
+
if (isPlainObject(body)) {
|
|
261
|
+
Object.entries(body).forEach(function (_a) {
|
|
262
|
+
var key = _a[0], value = _a[1];
|
|
263
|
+
code += "const ".concat(key, " = `\n").concat(indent(String(value), 4), "`;\n\n");
|
|
264
|
+
});
|
|
265
|
+
body = "JSON.stringify({ ".concat(Object.keys(body).join(', '), " })");
|
|
266
|
+
// Set Content-Type to application/json for GraphQL, recommended by GraphQL spec
|
|
267
|
+
headersCopy['Content-Type'] = 'application/json';
|
|
268
|
+
}
|
|
269
|
+
else {
|
|
270
|
+
code += "const query = `\n".concat(indent(String(body), 4), "`;\n\n");
|
|
271
|
+
body = 'JSON.stringify(query)';
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
else if (isCSV(contentType)) {
|
|
275
|
+
code += 'const csv = `\n';
|
|
276
|
+
code += indent(String(body), 4);
|
|
277
|
+
code += '`;\n\n';
|
|
278
|
+
body = 'csv';
|
|
279
|
+
}
|
|
280
|
+
else if (isPDF(contentType)) {
|
|
281
|
+
// Use FormData to upload PDF files
|
|
282
|
+
code += 'const formData = new FormData();\n\n';
|
|
283
|
+
code += "formData.append(\"file\", \"".concat(body, "\");\n\n");
|
|
284
|
+
body = 'formData';
|
|
285
|
+
}
|
|
286
|
+
else if (isXML(contentType)) {
|
|
287
|
+
code += 'const xml = `\n';
|
|
288
|
+
code += indent(String(body), 4);
|
|
289
|
+
code += '`;\n\n';
|
|
290
|
+
body = 'xml';
|
|
291
|
+
}
|
|
292
|
+
else if (isText(contentType)) {
|
|
293
|
+
body = stringifyOpenAPI(body, null, 2);
|
|
294
|
+
}
|
|
295
|
+
else {
|
|
296
|
+
body = "JSON.stringify(".concat(stringifyOpenAPI(body, null, 2), ")");
|
|
297
|
+
}
|
|
298
|
+
return { body: body, code: code, headers: headersCopy };
|
|
299
|
+
},
|
|
300
|
+
getPythonBody: function (body, headers) {
|
|
301
|
+
if (!body || !headers)
|
|
302
|
+
return;
|
|
303
|
+
var code = '';
|
|
304
|
+
var contentType = headers['Content-Type'] || '';
|
|
305
|
+
if (isFormData(contentType)) {
|
|
306
|
+
code += 'files = {\n';
|
|
307
|
+
if (isPlainObject(body)) {
|
|
308
|
+
Object.entries(body).forEach(function (_a) {
|
|
309
|
+
var key = _a[0], value = _a[1];
|
|
310
|
+
code += "".concat(indent("\"".concat(key, "\": \"").concat(String(value), "\","), 4), "\n");
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
code += '}\n\n';
|
|
314
|
+
body = 'files';
|
|
315
|
+
}
|
|
316
|
+
if (isPDF(contentType)) {
|
|
317
|
+
code += 'files = {\n';
|
|
318
|
+
code += "".concat(indent("\"file\": \"".concat(body, "\","), 4), "\n");
|
|
319
|
+
code += '}\n\n';
|
|
320
|
+
body = 'files';
|
|
321
|
+
}
|
|
322
|
+
return { body: body, code: code, headers: headers };
|
|
323
|
+
},
|
|
324
|
+
getHTTPBody: function (body, headers) {
|
|
325
|
+
if (!body || !headers)
|
|
326
|
+
return undefined;
|
|
327
|
+
var contentType = headers['Content-Type'] || '';
|
|
328
|
+
var typeHandlers = {
|
|
329
|
+
pdf: function () { return "".concat(stringifyOpenAPI(body, null, 2)); },
|
|
330
|
+
formUrlEncoded: function () {
|
|
331
|
+
var encoded = isPlainObject(body)
|
|
332
|
+
? Object.entries(body)
|
|
333
|
+
.map(function (_a) {
|
|
334
|
+
var key = _a[0], value = _a[1];
|
|
335
|
+
return "".concat(key, "=").concat(String(value));
|
|
336
|
+
})
|
|
337
|
+
.join('&')
|
|
338
|
+
: String(body);
|
|
339
|
+
return "\"".concat(encoded, "\"");
|
|
340
|
+
},
|
|
341
|
+
text: function () { return "\"".concat(String(body), "\""); },
|
|
342
|
+
xmlOrCsv: function () { return "\"".concat(stringifyOpenAPI(body).replace(/"/g, ''), "\""); },
|
|
343
|
+
default: function () { return "".concat(stringifyOpenAPI(body, null, 2)); },
|
|
344
|
+
};
|
|
345
|
+
if (isPDF(contentType))
|
|
346
|
+
return typeHandlers.pdf();
|
|
347
|
+
if (isFormUrlEncoded(contentType))
|
|
348
|
+
return typeHandlers.formUrlEncoded();
|
|
349
|
+
if (isText(contentType))
|
|
350
|
+
return typeHandlers.text();
|
|
351
|
+
if (isXML(contentType) || isCSV(contentType)) {
|
|
352
|
+
return typeHandlers.xmlOrCsv();
|
|
353
|
+
}
|
|
354
|
+
return typeHandlers.default();
|
|
355
|
+
},
|
|
356
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare function isJSON(contentType?: string): boolean;
|
|
2
|
+
export declare function isXML(contentType?: string): boolean;
|
|
3
|
+
export declare function isGraphQL(contentType?: string): boolean;
|
|
4
|
+
export declare function isCSV(contentType?: string): boolean;
|
|
5
|
+
export declare function isPDF(contentType?: string): boolean;
|
|
6
|
+
export declare function isText(contentType?: string): boolean;
|
|
7
|
+
export declare function isFormUrlEncoded(contentType?: string): boolean;
|
|
8
|
+
export declare function isFormData(contentType?: string): boolean;
|
|
9
|
+
export declare function isPlainObject(value: unknown): boolean;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export function isJSON(contentType) {
|
|
2
|
+
return (contentType === null || contentType === void 0 ? void 0 : contentType.toLowerCase().includes('application/json')) || false;
|
|
3
|
+
}
|
|
4
|
+
export function isXML(contentType) {
|
|
5
|
+
return (contentType === null || contentType === void 0 ? void 0 : contentType.toLowerCase().includes('application/xml')) || false;
|
|
6
|
+
}
|
|
7
|
+
export function isGraphQL(contentType) {
|
|
8
|
+
return (contentType === null || contentType === void 0 ? void 0 : contentType.toLowerCase().includes('application/graphql')) || false;
|
|
9
|
+
}
|
|
10
|
+
export function isCSV(contentType) {
|
|
11
|
+
return (contentType === null || contentType === void 0 ? void 0 : contentType.toLowerCase().includes('text/csv')) || false;
|
|
12
|
+
}
|
|
13
|
+
export function isPDF(contentType) {
|
|
14
|
+
return (contentType === null || contentType === void 0 ? void 0 : contentType.toLowerCase().includes('application/pdf')) || false;
|
|
15
|
+
}
|
|
16
|
+
export function isText(contentType) {
|
|
17
|
+
return (contentType === null || contentType === void 0 ? void 0 : contentType.toLowerCase().includes('text/plain')) || false;
|
|
18
|
+
}
|
|
19
|
+
export function isFormUrlEncoded(contentType) {
|
|
20
|
+
return (contentType === null || contentType === void 0 ? void 0 : contentType.toLowerCase().includes('application/x-www-form-urlencoded')) || false;
|
|
21
|
+
}
|
|
22
|
+
export function isFormData(contentType) {
|
|
23
|
+
return !!contentType && contentType.toLowerCase().includes('multipart/form-data');
|
|
24
|
+
}
|
|
25
|
+
export function isPlainObject(value) {
|
|
26
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
27
|
+
}
|
|
@@ -26,7 +26,8 @@ export function generateSchemaExample(schema, options) {
|
|
|
26
26
|
binary: 'binary',
|
|
27
27
|
byte: 'Ynl0ZXM=',
|
|
28
28
|
password: 'password',
|
|
29
|
-
} }, options)
|
|
29
|
+
} }, options), 3 // Max depth for circular references
|
|
30
|
+
);
|
|
30
31
|
}
|
|
31
32
|
/**
|
|
32
33
|
* Generate an example for a media type.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { type
|
|
3
|
-
import { OpenAPIOperationData } from './types';
|
|
1
|
+
import { fromJSON, toJSON } from 'flatted';
|
|
2
|
+
import { type Filesystem, type OpenAPIV3xDocument } from '@gitbook/openapi-parser';
|
|
3
|
+
import type { OpenAPIOperationData } from './types';
|
|
4
4
|
export { toJSON, fromJSON };
|
|
5
5
|
/**
|
|
6
6
|
* Resolve an OpenAPI operation in a file and compile it to a more usable format.
|
|
@@ -54,7 +54,7 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
|
54
54
|
}
|
|
55
55
|
return to.concat(ar || Array.prototype.slice.call(from));
|
|
56
56
|
};
|
|
57
|
-
import {
|
|
57
|
+
import { fromJSON, toJSON } from 'flatted';
|
|
58
58
|
import { dereference, } from '@gitbook/openapi-parser';
|
|
59
59
|
import { checkIsReference } from './utils';
|
|
60
60
|
export { toJSON, fromJSON };
|
package/dist/stringifyOpenAPI.js
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Stringify an OpenAPI object. Same API as JSON.stringify.
|
|
3
3
|
*/
|
|
4
|
-
export function stringifyOpenAPI(body,
|
|
5
|
-
return JSON.stringify(body,
|
|
4
|
+
export function stringifyOpenAPI(body, _, indent) {
|
|
5
|
+
return JSON.stringify(body, function (key, value) {
|
|
6
|
+
// Ignore internal keys
|
|
7
|
+
if (key.startsWith('x-gitbook-')) {
|
|
8
|
+
return undefined;
|
|
9
|
+
}
|
|
10
|
+
return value;
|
|
11
|
+
}, indent);
|
|
6
12
|
}
|