Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 4927e96

Browse files
Add support for YAML content type in request body/example (#3612)
1 parent 262a9b1 commit 4927e96

File tree

7 files changed

+33
-6
lines changed

7 files changed

+33
-6
lines changed

‎.changeset/funny-falcons-brush.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@gitbook/react-openapi": patch
3+
---
4+
5+
Add support for YAML content type in request body/example

‎bun.lock

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,13 +267,15 @@
267267
"@scalar/oas-utils": "^0.2.130",
268268
"clsx": "^2.1.1",
269269
"flatted": "^3.2.9",
270+
"js-yaml": "^4.1.0",
270271
"json-xml-parse": "^1.3.0",
271272
"react-aria": "^3.37.0",
272273
"react-aria-components": "^1.6.0",
273274
"usehooks-ts": "^3.1.0",
274275
"zustand": "^5.0.3",
275276
},
276277
"devDependencies": {
278+
"@types/js-yaml": "^4.0.9",
277279
"bun-types": "^1.1.20",
278280
"typescript": "^5.5.3",
279281
},
@@ -1377,6 +1379,8 @@
13771379

13781380
"@types/js-cookie": ["@types/js-cookie@3.0.6", "", {}, "sha512-wkw9yd1kEXOPnvEeEV1Go1MmxtBJL0RR79aOTAApecWFVu7w0NNXNqhcWgvw2YgZDYadliXkl14pa3WXw5jlCQ=="],
13791381

1382+
"@types/js-yaml": ["@types/js-yaml@4.0.9", "", {}, "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg=="],
1383+
13801384
"@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
13811385

13821386
"@types/jsontoxml": ["@types/jsontoxml@1.0.6", "", {}, "sha512-SoeEpHuqdZcpLxZr5uzpB6A/ICmzBOfluwMm59Bm6vDuiSRSv4M/z8hvS+YCRw4ZyGO5BhJ5oeJnrurSigg3Vw=="],

‎packages/react-openapi/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,11 @@
2020
"react-aria-components": "^1.6.0",
2121
"react-aria": "^3.37.0",
2222
"usehooks-ts": "^3.1.0",
23-
"zustand": "^5.0.3"
23+
"zustand": "^5.0.3",
24+
"js-yaml": "^4.1.0"
2425
},
2526
"devDependencies": {
27+
"@types/js-yaml": "^4.0.9",
2628
"bun-types": "^1.1.20",
2729
"typescript": "^5.5.3"
2830
},

‎packages/react-openapi/src/InteractiveSection.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ export function InteractiveSection(props: {
112112
event.stopPropagation();
113113
}}
114114
>
115-
{tabs.length > 1 ? (
115+
{tabs.length > 0 ? (
116116
<OpenAPISelect
117117
stateKey={stateKey}
118118
items={tabs}

‎packages/react-openapi/src/code-samples.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ describe('python code sample generator', () => {
406406

407407
it('should format application/json body properly', () => {
408408
const input: CodeSampleInput = {
409-
method: 'GET',
409+
method: 'POST',
410410
url: 'https://example.com/path',
411411
headers: {
412412
'Content-Type': 'application/json',
@@ -422,7 +422,7 @@ describe('python code sample generator', () => {
422422
const output = generator?.generate(input);
423423

424424
expect(output).toBe(
425-
'import requests\n\nresponse = requests.get(\n "https://example.com/path",\n headers={"Content-Type":"application/json"},\n data=json.dumps({\n "key": "value",\n "truethy": True,\n "falsey": False,\n "nullish": None\n })\n)\n\ndata = response.json()'
425+
'import json\nimport requests\n\nresponse = requests.post(\n "https://example.com/path",\n headers={"Content-Type":"application/json"},\n data=json.dumps({\n "key": "value",\n "truethy": True,\n "falsey": False,\n "nullish": None\n })\n)\n\ndata = response.json()'
426426
);
427427
});
428428

‎packages/react-openapi/src/code-samples.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import yaml from 'js-yaml';
12
import {
23
isCSV,
34
isFormData,
@@ -8,6 +9,7 @@ import {
89
isPlainObject,
910
isText,
1011
isXML,
12+
isYAML,
1113
} from './contentTypeChecks';
1214
import { json2xml } from './json2xml';
1315
import { stringifyOpenAPI } from './stringifyOpenAPI';
@@ -154,7 +156,8 @@ ${headerString}${bodyString}`;
154156
label: 'Python',
155157
syntax: 'python',
156158
generate: ({ method, url, headers, body }) => {
157-
let code = 'import requests\n\n';
159+
const contentType = headers?.['Content-Type'];
160+
let code = `${isJSON(contentType) ? 'import json\n' : ''}import requests\n\n`;
158161

159162
if (body) {
160163
const lines = BodyGenerators.getPythonBody(body, headers);
@@ -174,7 +177,6 @@ ${headerString}${bodyString}`;
174177
code += indent(`headers=${stringifyOpenAPI(headers)},\n`, 4);
175178
}
176179

177-
const contentType = headers?.['Content-Type'];
178180
if (body) {
179181
if (body === 'files') {
180182
code += indent(`files=${body}\n`, 4);
@@ -256,6 +258,8 @@ const BodyGenerators = {
256258
} else if (isPDF(contentType)) {
257259
// We use --data-binary to avoid cURL converting newlines to \r\n
258260
body = `--data-binary '@${String(body)}'`;
261+
} else if (isYAML(contentType)) {
262+
body = `--data-binary $'${yaml.dump(body).replace(/'/g, '').replace(/\\n/g, '\n')}'`;
259263
} else {
260264
body = `--data '${stringifyOpenAPI(body, null, 2).replace(/\\n/g, '\n')}'`;
261265
}
@@ -325,6 +329,9 @@ const BodyGenerators = {
325329
code += indent(convertBodyToXML(body), 4);
326330
code += '`;\n\n';
327331
body = 'xml';
332+
} else if (isYAML(contentType)) {
333+
code += `const yamlBody = \`\n${indent(yaml.dump(body), 4)}\`;\n\n`;
334+
body = 'yamlBody';
328335
} else if (isText(contentType)) {
329336
body = stringifyOpenAPI(body, null, 2);
330337
} else {
@@ -355,6 +362,9 @@ const BodyGenerators = {
355362
} else if (isXML(contentType)) {
356363
// Convert JSON to XML if needed
357364
body = JSON.stringify(convertBodyToXML(body));
365+
} else if (isYAML(contentType)) {
366+
code += `yamlBody = \"\"\"\n${indent(yaml.dump(body), 4)}\"\"\"\n\n`;
367+
body = 'yamlBody';
358368
} else {
359369
body = stringifyOpenAPI(
360370
body,
@@ -399,6 +409,7 @@ const BodyGenerators = {
399409
// Convert JSON to XML if needed
400410
return `"${convertBodyToXML(body)}"`;
401411
},
412+
yaml: () => `"${yaml.dump(body).replace(/"/g, '\\"')}"`,
402413
csv: () => `"${stringifyOpenAPI(body).replace(/"/g, '')}"`,
403414
default: () => `${stringifyOpenAPI(body, null, 2)}`,
404415
};
@@ -407,6 +418,7 @@ const BodyGenerators = {
407418
if (isFormUrlEncoded(contentType)) return typeHandlers.formUrlEncoded();
408419
if (isText(contentType)) return typeHandlers.text();
409420
if (isXML(contentType)) return typeHandlers.xml();
421+
if (isYAML(contentType)) return typeHandlers.yaml();
410422
if (isCSV(contentType)) return typeHandlers.csv();
411423

412424
return typeHandlers.default();

‎packages/react-openapi/src/contentTypeChecks.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ export function isXML(contentType?: string): boolean {
66
return contentType?.toLowerCase().includes('application/xml') || false;
77
}
88

9+
export function isYAML(contentType?: string): boolean {
10+
return contentType?.toLowerCase().includes('application/yaml') || false;
11+
}
12+
913
export function isGraphQL(contentType?: string): boolean {
1014
return contentType?.toLowerCase().includes('application/graphql') || false;
1115
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /