@gitbook/react-openapi 1.0.2 → 1.0.3
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 +16 -0
- package/dist/OpenAPICodeSample.jsx +11 -9
- package/dist/OpenAPIOperation.jsx +19 -5
- package/dist/OpenAPIResponseExample.jsx +3 -2
- package/dist/OpenAPISchema.jsx +47 -45
- package/dist/OpenAPISchemaName.d.ts +2 -1
- package/dist/OpenAPISchemaName.jsx +25 -4
- package/dist/OpenAPITabs.jsx +6 -2
- package/dist/code-samples.js +232 -10
- package/dist/contentTypeChecks.d.ts +9 -0
- package/dist/contentTypeChecks.js +27 -0
- package/dist/generateSchemaExample.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/{OpenAPIServerURL.jsx → util/server.js} +7 -28
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js +3 -0
- package/package.json +2 -2
- package/src/OpenAPICodeSample.tsx +11 -9
- package/src/OpenAPIOperation.tsx +30 -8
- package/src/OpenAPIResponseExample.tsx +3 -2
- package/src/OpenAPISchema.tsx +73 -62
- package/src/OpenAPISchemaName.tsx +37 -5
- package/src/OpenAPITabs.tsx +8 -2
- package/src/code-samples.test.ts +594 -2
- package/src/code-samples.ts +231 -10
- package/src/contentTypeChecks.ts +35 -0
- package/src/generateSchemaExample.ts +20 -16
- 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 +48 -0
- package/src/utils.ts +5 -1
- package/dist/OpenAPIServerURL.d.ts +0 -11
- 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
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 { isFormData, isPDF, isFormUrlEncoded, isText, isXML, isCSV, isGraphQL, isPlainObject, } 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,14 +55,23 @@ 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 += "});\n";
|
|
74
|
+
code += "});\n\n";
|
|
53
75
|
code += "const data = await response.json();";
|
|
54
76
|
return code;
|
|
55
77
|
},
|
|
@@ -61,15 +83,29 @@ 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';
|
|
108
|
+
code += ')\n\n';
|
|
73
109
|
code += "data = response.json()";
|
|
74
110
|
return code;
|
|
75
111
|
},
|
|
@@ -86,6 +122,10 @@ 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')) {
|
|
@@ -99,7 +139,7 @@ export var codeSampleGenerators = [
|
|
|
99
139
|
})
|
|
100
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
|
},
|
|
@@ -132,3 +172,185 @@ export function parseHostAndPath(url) {
|
|
|
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 += 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 += 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
|
+
}
|
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
|
}
|