mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-12 05:48:57 +00:00
Fix XML in code sample (#3030)
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@gitbook/react-openapi': patch
|
||||
---
|
||||
|
||||
Fix XML in code sample
|
||||
@@ -110,6 +110,23 @@ describe('curL code sample generator', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should convert json to xml body properly', () => {
|
||||
const input: CodeSampleInput = {
|
||||
method: 'GET',
|
||||
url: 'https://example.com/path',
|
||||
headers: {
|
||||
'Content-Type': 'application/xml',
|
||||
},
|
||||
body: '{ "key": "value" }',
|
||||
};
|
||||
|
||||
const output = generator?.generate(input);
|
||||
|
||||
expect(output).toBe(
|
||||
"curl -L \\\n --url 'https://example.com/path' \\\n --header 'Content-Type: application/xml' \\\n --data-binary $'<?xml version=1.0?>\n <key>value</key>\n '"
|
||||
);
|
||||
});
|
||||
|
||||
it('should format application/graphql body properly', () => {
|
||||
const input: CodeSampleInput = {
|
||||
method: 'GET',
|
||||
@@ -258,6 +275,23 @@ describe('javascript code sample generator', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should convert json to xml body properly', () => {
|
||||
const input: CodeSampleInput = {
|
||||
method: 'GET',
|
||||
url: 'https://example.com/path',
|
||||
headers: {
|
||||
'Content-Type': 'application/xml',
|
||||
},
|
||||
body: '{ "key": "value" }',
|
||||
};
|
||||
|
||||
const output = generator?.generate(input);
|
||||
|
||||
expect(output).toBe(
|
||||
'const xml = `\n <?xml version=1.0?>\n <key>value</key>\n`;\n\nconst response = await fetch(\'https://example.com/path\', {\n method: \'GET\',\n headers: {\n "Content-Type": "application/xml"\n },\n body: xml\n});\n\nconst data = await response.json();'
|
||||
);
|
||||
});
|
||||
|
||||
it('should format application/graphql body properly', () => {
|
||||
const input: CodeSampleInput = {
|
||||
method: 'GET',
|
||||
@@ -406,6 +440,23 @@ describe('python code sample generator', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should convert json to xml body properly', () => {
|
||||
const input: CodeSampleInput = {
|
||||
method: 'GET',
|
||||
url: 'https://example.com/path',
|
||||
headers: {
|
||||
'Content-Type': 'application/xml',
|
||||
},
|
||||
body: '{ "key": "value" }',
|
||||
};
|
||||
|
||||
const output = generator?.generate(input);
|
||||
|
||||
expect(output).toBe(
|
||||
'import requests\n\nresponse = requests.get(\n "https://example.com/path",\n headers={"Content-Type":"application/xml"},\n data="<?xml version=1.0?>\\n<key>value</key>\\n"\n)\n\ndata = response.json()'
|
||||
);
|
||||
});
|
||||
|
||||
it('should format application/graphql body properly', () => {
|
||||
const input: CodeSampleInput = {
|
||||
method: 'GET',
|
||||
@@ -514,7 +565,7 @@ describe('http code sample generator', () => {
|
||||
const output = generator?.generate(input);
|
||||
|
||||
expect(output).toBe(
|
||||
'GET /path HTTP/1.1\nHost: example.com\nContent-Type: application/x-www-form-urlencoded\nContent-Length: 15\nAccept: */*\n\n"key=value"'
|
||||
'GET /path HTTP/1.1\nHost: example.com\nContent-Type: application/x-www-form-urlencoded\nContent-Length: 15\nAccept: */*\n\n"key=\'value\'"'
|
||||
);
|
||||
});
|
||||
|
||||
@@ -554,6 +605,23 @@ describe('http code sample generator', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should convert json to xml body properly', () => {
|
||||
const input: CodeSampleInput = {
|
||||
method: 'GET',
|
||||
url: 'https://example.com/path',
|
||||
headers: {
|
||||
'Content-Type': 'application/xml',
|
||||
},
|
||||
body: '{ "key": "value" }',
|
||||
};
|
||||
|
||||
const output = generator?.generate(input);
|
||||
|
||||
expect(output).toBe(
|
||||
'GET /path HTTP/1.1\nHost: example.com\nContent-Type: application/xml\nContent-Length: 24\nAccept: */*\n\n"<?xml version=1.0?>\n<key>value</key>\n"'
|
||||
);
|
||||
});
|
||||
|
||||
it('should format application/graphql body properly', () => {
|
||||
const input: CodeSampleInput = {
|
||||
method: 'GET',
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
isText,
|
||||
isXML,
|
||||
} from './contentTypeChecks';
|
||||
import { json2xml } from './json2xml';
|
||||
import { stringifyOpenAPI } from './stringifyOpenAPI';
|
||||
|
||||
export interface CodeSampleInput {
|
||||
@@ -238,7 +239,10 @@ const BodyGenerators = {
|
||||
: String(body);
|
||||
} else if (isText(contentType)) {
|
||||
body = `--data '${String(body).replace(/"/g, '')}'`;
|
||||
} else if (isXML(contentType) || isCSV(contentType)) {
|
||||
} else if (isXML(contentType)) {
|
||||
// Convert to XML and ensure proper formatting
|
||||
body = `--data-binary $'${convertBodyToXML(body)}'`;
|
||||
} else if (isCSV(contentType)) {
|
||||
// We use --data-binary to avoid cURL converting newlines to \r\n
|
||||
body = `--data-binary $'${stringifyOpenAPI(body).replace(/"/g, '').replace(/\\n/g, '\n')}'`;
|
||||
} else if (isGraphQL(contentType)) {
|
||||
@@ -312,7 +316,9 @@ const BodyGenerators = {
|
||||
body = 'formData';
|
||||
} else if (isXML(contentType)) {
|
||||
code += 'const xml = `\n';
|
||||
code += indent(String(body), 4);
|
||||
|
||||
// Convert JSON to XML if needed
|
||||
code += indent(convertBodyToXML(body), 4);
|
||||
code += '`;\n\n';
|
||||
body = 'xml';
|
||||
} else if (isText(contentType)) {
|
||||
@@ -346,6 +352,11 @@ const BodyGenerators = {
|
||||
body = 'files';
|
||||
}
|
||||
|
||||
if (isXML(contentType)) {
|
||||
// Convert JSON to XML if needed
|
||||
body = convertBodyToXML(body);
|
||||
}
|
||||
|
||||
return { body, code, headers };
|
||||
},
|
||||
getHTTPBody: (body: any, headers?: Record<string, string>) => {
|
||||
@@ -358,23 +369,48 @@ const BodyGenerators = {
|
||||
formUrlEncoded: () => {
|
||||
const encoded = isPlainObject(body)
|
||||
? Object.entries(body)
|
||||
.map(([key, value]) => `${key}=${String(value)}`)
|
||||
.map(([key, value]) => `${key}=${stringifyOpenAPI(value)}`)
|
||||
.join('&')
|
||||
: String(body);
|
||||
return `"${encoded}"`;
|
||||
: stringifyOpenAPI(body);
|
||||
return `"${encoded.replace(/"/g, "'")}"`;
|
||||
},
|
||||
text: () => `"${String(body)}"`,
|
||||
xmlOrCsv: () => `"${stringifyOpenAPI(body).replace(/"/g, '')}"`,
|
||||
xml: () => {
|
||||
// Convert JSON to XML if needed
|
||||
return `"${convertBodyToXML(body)}"`;
|
||||
},
|
||||
csv: () => `"${stringifyOpenAPI(body).replace(/"/g, '')}"`,
|
||||
default: () => `${stringifyOpenAPI(body, null, 2)}`,
|
||||
};
|
||||
|
||||
if (isPDF(contentType)) return typeHandlers.pdf();
|
||||
if (isFormUrlEncoded(contentType)) return typeHandlers.formUrlEncoded();
|
||||
if (isText(contentType)) return typeHandlers.text();
|
||||
if (isXML(contentType) || isCSV(contentType)) {
|
||||
return typeHandlers.xmlOrCsv();
|
||||
}
|
||||
if (isXML(contentType)) return typeHandlers.xml();
|
||||
if (isCSV(contentType)) return typeHandlers.csv();
|
||||
|
||||
return typeHandlers.default();
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts a body to XML format
|
||||
*/
|
||||
function convertBodyToXML(body: any): string {
|
||||
// If body is already a string and looks like XML, return it as is
|
||||
if (typeof body === 'string' && body.trim().startsWith('<')) {
|
||||
return body;
|
||||
}
|
||||
|
||||
// If body is not an object, try to parse it as JSON
|
||||
if (typeof body !== 'object' || body === null) {
|
||||
try {
|
||||
body = JSON.parse(body);
|
||||
} catch {
|
||||
// If parsing fails, return the original body
|
||||
return body;
|
||||
}
|
||||
}
|
||||
|
||||
return json2xml(body).replace(/"/g, '').replace(/\\n/g, '\n').replace(/\\t/g, '\t');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user