mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-28 13:08:57 +00:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 50cafe9ec6 | |||
| 2f05549c72 | |||
| 2da0ccf4ba |
@@ -37,30 +37,31 @@ export const codeSampleGenerators: CodeSampleGenerator[] = [
|
|||||||
label: 'HTTP',
|
label: 'HTTP',
|
||||||
syntax: 'http',
|
syntax: 'http',
|
||||||
generate: ({ method, url: { origin, path }, headers = {}, body }: CodeSampleInput) => {
|
generate: ({ method, url: { origin, path }, headers = {}, body }: CodeSampleInput) => {
|
||||||
|
// Process URL and headers to use consistent placeholder format
|
||||||
|
const processedPath = convertPathParametersToPlaceholders(path);
|
||||||
|
const processedHeaders = processHeadersWithPlaceholders(headers);
|
||||||
|
|
||||||
if (body) {
|
if (body) {
|
||||||
// if we had a body add a content length header
|
// if we had a body add a content length header
|
||||||
const bodyContent = body ? stringifyOpenAPI(body) : '';
|
const bodyContent = body ? stringifyOpenAPI(body) : '';
|
||||||
// handle unicode chars with a text encoder
|
// handle unicode chars with a text encoder
|
||||||
const encoder = new TextEncoder();
|
const encoder = new TextEncoder();
|
||||||
|
|
||||||
const bodyString = BodyGenerators.getHTTPBody(body, headers);
|
const bodyString = BodyGenerators.getHTTPBody(body, processedHeaders);
|
||||||
|
|
||||||
if (bodyString) {
|
if (bodyString) {
|
||||||
body = bodyString;
|
body = bodyString;
|
||||||
}
|
}
|
||||||
|
|
||||||
headers = {
|
processedHeaders['Content-Length'] = encoder.encode(bodyContent).length.toString();
|
||||||
...headers,
|
|
||||||
'Content-Length': encoder.encode(bodyContent).length.toString(),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!headers.hasOwnProperty('Accept')) {
|
if (!processedHeaders.hasOwnProperty('Accept')) {
|
||||||
headers.Accept = '*/*';
|
processedHeaders.Accept = '*/*';
|
||||||
}
|
}
|
||||||
|
|
||||||
const headerString = headers
|
const headerString = processedHeaders
|
||||||
? `${Object.entries(headers)
|
? `${Object.entries(processedHeaders)
|
||||||
.map(([key, value]) =>
|
.map(([key, value]) =>
|
||||||
key.toLowerCase() !== 'host' ? `${key}: ${value}` : ''
|
key.toLowerCase() !== 'host' ? `${key}: ${value}` : ''
|
||||||
)
|
)
|
||||||
@@ -69,8 +70,8 @@ export const codeSampleGenerators: CodeSampleGenerator[] = [
|
|||||||
|
|
||||||
const bodyString = body ? `\n${body}` : '';
|
const bodyString = body ? `\n${body}` : '';
|
||||||
|
|
||||||
const httpRequest = `${method.toUpperCase()} ${decodeURI(path)} HTTP/1.1
|
const httpRequest = `${method.toUpperCase()} ${decodeURI(processedPath)} HTTP/1.1
|
||||||
Host: ${origin.replaceAll(/https*:\/\//g, '')}
|
Host: ${origin.replace(/https*:\/\//g, '')}
|
||||||
${headerString}${bodyString}`;
|
${headerString}${bodyString}`;
|
||||||
|
|
||||||
return httpRequest;
|
return httpRequest;
|
||||||
@@ -87,15 +88,23 @@ ${headerString}${bodyString}`;
|
|||||||
lines.push(`--request ${method.toUpperCase()}`);
|
lines.push(`--request ${method.toUpperCase()}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
lines.push(`--url '${origin}${path}'`);
|
// Process URL and headers to use consistent placeholder format
|
||||||
|
const processedUrl = convertPathParametersToPlaceholders(origin + path);
|
||||||
|
const processedHeaders = processHeadersWithPlaceholders(headers);
|
||||||
|
|
||||||
|
lines.push(`--url '${processedUrl}'`);
|
||||||
|
|
||||||
if (body) {
|
if (body) {
|
||||||
const bodyContent = BodyGenerators.getCurlBody(body, headers);
|
const bodyContent = BodyGenerators.getCurlBody(body, processedHeaders);
|
||||||
|
|
||||||
if (bodyContent) {
|
if (bodyContent) {
|
||||||
body = bodyContent.body;
|
body = bodyContent.body;
|
||||||
headers = bodyContent.headers;
|
headers = bodyContent.headers;
|
||||||
|
} else {
|
||||||
|
headers = processedHeaders;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
headers = processedHeaders;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (headers && Object.keys(headers).length > 0) {
|
if (headers && Object.keys(headers).length > 0) {
|
||||||
@@ -122,18 +131,26 @@ ${headerString}${bodyString}`;
|
|||||||
generate: ({ method, url: { origin, path }, headers, body }) => {
|
generate: ({ method, url: { origin, path }, headers, body }) => {
|
||||||
let code = '';
|
let code = '';
|
||||||
|
|
||||||
|
// Process URL and headers to use consistent placeholder format
|
||||||
|
const processedUrl = convertPathParametersToPlaceholders(origin + path);
|
||||||
|
const processedHeaders = processHeadersWithPlaceholders(headers);
|
||||||
|
|
||||||
if (body) {
|
if (body) {
|
||||||
const lines = BodyGenerators.getJavaScriptBody(body, headers);
|
const lines = BodyGenerators.getJavaScriptBody(body, processedHeaders);
|
||||||
|
|
||||||
if (lines) {
|
if (lines) {
|
||||||
// add the generated code to the top
|
// add the generated code to the top
|
||||||
code += lines.code;
|
code += lines.code;
|
||||||
body = lines.body;
|
body = lines.body;
|
||||||
headers = lines.headers;
|
headers = lines.headers;
|
||||||
|
} else {
|
||||||
|
headers = processedHeaders;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
headers = processedHeaders;
|
||||||
}
|
}
|
||||||
|
|
||||||
code += `const response = await fetch('${origin}${path}', {
|
code += `const response = await fetch('${processedUrl}', {
|
||||||
method: '${method.toUpperCase()}',\n`;
|
method: '${method.toUpperCase()}',\n`;
|
||||||
|
|
||||||
if (headers && Object.keys(headers).length > 0) {
|
if (headers && Object.keys(headers).length > 0) {
|
||||||
@@ -156,7 +173,19 @@ ${headerString}${bodyString}`;
|
|||||||
syntax: 'python',
|
syntax: 'python',
|
||||||
generate: ({ method, url: { origin, path }, headers, body }) => {
|
generate: ({ method, url: { origin, path }, headers, body }) => {
|
||||||
const contentType = headers?.['Content-Type'];
|
const contentType = headers?.['Content-Type'];
|
||||||
let code = `${isJSON(contentType) ? 'import json\n' : ''}import requests\n\n`;
|
const needsJsonImport = body && isJSON(contentType) && typeof body === 'string';
|
||||||
|
|
||||||
|
let code = '';
|
||||||
|
|
||||||
|
// Import statements
|
||||||
|
if (needsJsonImport) {
|
||||||
|
code += 'import json\n';
|
||||||
|
}
|
||||||
|
code += 'import requests\n\n';
|
||||||
|
|
||||||
|
// Process headers and URL to use consistent placeholder format
|
||||||
|
const processedUrl = convertPathParametersToPlaceholders(origin + path);
|
||||||
|
const processedHeaders = processHeadersWithPlaceholders(headers);
|
||||||
|
|
||||||
if (body) {
|
if (body) {
|
||||||
const lines = BodyGenerators.getPythonBody(body, headers);
|
const lines = BodyGenerators.getPythonBody(body, headers);
|
||||||
@@ -170,16 +199,25 @@ ${headerString}${bodyString}`;
|
|||||||
}
|
}
|
||||||
|
|
||||||
code += `response = requests.${method.toLowerCase()}(\n`;
|
code += `response = requests.${method.toLowerCase()}(\n`;
|
||||||
code += indent(`"${origin}${path}",\n`, 4);
|
code += indent(`"${processedUrl}",\n`, 4);
|
||||||
|
|
||||||
if (headers && Object.keys(headers).length > 0) {
|
if (processedHeaders && Object.keys(processedHeaders).length > 0) {
|
||||||
code += indent(`headers=${stringifyOpenAPI(headers)},\n`, 4);
|
code += indent(`headers={\n`, 4);
|
||||||
|
Object.entries(processedHeaders).forEach(([key, value], index, array) => {
|
||||||
|
const isLast = index === array.length - 1;
|
||||||
|
code += indent(`"${key}": "${value}"${isLast ? '' : ','}\n`, 8);
|
||||||
|
});
|
||||||
|
code += indent(`},\n`, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (body) {
|
if (body) {
|
||||||
if (body === 'files') {
|
if (body === 'files') {
|
||||||
code += indent(`files=${body}\n`, 4);
|
code += indent(`files=${body}\n`, 4);
|
||||||
} else if (isJSON(contentType)) {
|
} else if (isJSON(contentType) && isPlainObject(body)) {
|
||||||
|
// Use json parameter for dict objects
|
||||||
|
code += indent(`json=${body}\n`, 4);
|
||||||
|
} else if (isJSON(contentType) && needsJsonImport) {
|
||||||
|
// Use data=json.dumps() for JSON strings
|
||||||
code += indent(`data=json.dumps(${body})\n`, 4);
|
code += indent(`data=json.dumps(${body})\n`, 4);
|
||||||
} else {
|
} else {
|
||||||
code += indent(`data=${body}\n`, 4);
|
code += indent(`data=${body}\n`, 4);
|
||||||
@@ -372,7 +410,8 @@ const BodyGenerators = {
|
|||||||
} else if (isYAML(contentType)) {
|
} else if (isYAML(contentType)) {
|
||||||
code += `yamlBody = \"\"\"\n${indent(yaml.dump(body), 4)}\"\"\"\n\n`;
|
code += `yamlBody = \"\"\"\n${indent(yaml.dump(body), 4)}\"\"\"\n\n`;
|
||||||
body = 'yamlBody';
|
body = 'yamlBody';
|
||||||
} else {
|
} else if (isJSON(contentType) && isPlainObject(body)) {
|
||||||
|
// For dict objects, return as-is to use with json= parameter
|
||||||
body = stringifyOpenAPI(
|
body = stringifyOpenAPI(
|
||||||
body,
|
body,
|
||||||
(_key, value) => {
|
(_key, value) => {
|
||||||
@@ -389,9 +428,30 @@ const BodyGenerators = {
|
|||||||
},
|
},
|
||||||
2
|
2
|
||||||
)
|
)
|
||||||
.replaceAll('"$$__TRUE__$$"', 'True')
|
.replace(/"\\$\\$__TRUE__\\$\\$"/g, 'True')
|
||||||
.replaceAll('"$$__FALSE__$$"', 'False')
|
.replace(/"\\$\\$__FALSE__\\$\\$"/g, 'False')
|
||||||
.replaceAll('"$$__NULL__$$"', 'None');
|
.replace(/"\\$\\$__NULL__\\$\\$"/g, 'None');
|
||||||
|
} else {
|
||||||
|
// For everything else (including JSON strings)
|
||||||
|
body = stringifyOpenAPI(
|
||||||
|
body,
|
||||||
|
(_key, value) => {
|
||||||
|
switch (value) {
|
||||||
|
case true:
|
||||||
|
return '$$__TRUE__$$';
|
||||||
|
case false:
|
||||||
|
return '$$__FALSE__$$';
|
||||||
|
case null:
|
||||||
|
return '$$__NULL__$$';
|
||||||
|
default:
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
2
|
||||||
|
)
|
||||||
|
.replace(/"\\$\\$__TRUE__\\$\\$"/g, 'True')
|
||||||
|
.replace(/"\\$\\$__FALSE__\\$\\$"/g, 'False')
|
||||||
|
.replace(/"\\$\\$__NULL__\\$\\$"/g, 'None');
|
||||||
}
|
}
|
||||||
|
|
||||||
return { body, code, headers };
|
return { body, code, headers };
|
||||||
@@ -487,3 +547,44 @@ function buildHeredoc(lines: string[]): string {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts path parameters from {paramName} to YOUR_PARAM_NAME format
|
||||||
|
*/
|
||||||
|
function convertPathParametersToPlaceholders(urlPath: string): string {
|
||||||
|
return urlPath.replace(/\{([^}]+)\}/g, (match, paramName) => {
|
||||||
|
// Convert camelCase to UPPER_SNAKE_CASE
|
||||||
|
const placeholder = paramName.replace(/([a-z])([A-Z])/g, '$1_$2').toUpperCase();
|
||||||
|
return `YOUR_${placeholder}`;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes headers to use consistent placeholder format
|
||||||
|
*/
|
||||||
|
function processHeadersWithPlaceholders(headers?: Record<string, string>): Record<string, string> {
|
||||||
|
if (!headers) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
const processedHeaders: Record<string, string> = {};
|
||||||
|
|
||||||
|
Object.entries(headers).forEach(([key, value]) => {
|
||||||
|
if (key === 'Authorization' && value.includes('Bearer')) {
|
||||||
|
processedHeaders[key] = 'Bearer YOUR_API_TOKEN';
|
||||||
|
} else if (key === 'Authorization' && value.includes('Basic')) {
|
||||||
|
processedHeaders[key] = 'Basic YOUR_API_TOKEN';
|
||||||
|
} else if (value.includes('YOUR_') || value.includes('TOKEN')) {
|
||||||
|
// Already in correct format or generic token
|
||||||
|
processedHeaders[key] = value.replace(
|
||||||
|
/YOUR_SECRET_TOKEN|YOUR_TOKEN/g,
|
||||||
|
'YOUR_API_TOKEN'
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// Regular headers - keep as-is
|
||||||
|
processedHeaders[key] = value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return processedHeaders;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user