mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-12 05:48:57 +00:00
Add HTTP examples to API blocks (#2759)
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@gitbook/react-openapi': minor
|
||||
---
|
||||
|
||||
Add in HTTP example code blocks
|
||||
@@ -0,0 +1,51 @@
|
||||
import { it, expect } from 'bun:test';
|
||||
import { parseHostAndPath } from './code-samples';
|
||||
|
||||
it('should parse host and path on url strings properly', () => {
|
||||
const testUrls = [
|
||||
'//example.com/path',
|
||||
'//sub.example.com',
|
||||
'//example:8080/v1/test',
|
||||
'ftp://domain.com',
|
||||
'//example.com/com.example',
|
||||
'https://example.com/path.com/another.com',
|
||||
'example.com/firstPath/secondPath',
|
||||
];
|
||||
|
||||
expect(testUrls.map(parseHostAndPath)).toEqual([
|
||||
{
|
||||
host: 'example.com',
|
||||
path: '/path',
|
||||
},
|
||||
|
||||
{
|
||||
host: 'sub.example.com',
|
||||
path: '/',
|
||||
},
|
||||
|
||||
{
|
||||
host: 'example:8080',
|
||||
path: '/v1/test',
|
||||
},
|
||||
|
||||
{
|
||||
host: 'domain.com',
|
||||
path: '/',
|
||||
},
|
||||
|
||||
{
|
||||
host: 'example.com',
|
||||
path: '/com.example',
|
||||
},
|
||||
|
||||
{
|
||||
host: 'example.com',
|
||||
path: '/path.com/another.com',
|
||||
},
|
||||
|
||||
{
|
||||
host: 'example.com',
|
||||
path: '/firstPath/secondPath',
|
||||
},
|
||||
]);
|
||||
});
|
||||
@@ -84,6 +84,46 @@ export const codeSampleGenerators: CodeSampleGenerator[] = [
|
||||
return code;
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'http',
|
||||
label: 'HTTP',
|
||||
syntax: 'bash',
|
||||
generate: ({ method, url, headers = {}, body }: CodeSampleInput) => {
|
||||
const { host, path } = parseHostAndPath(url);
|
||||
|
||||
if (body) {
|
||||
// if we had a body add a content length header
|
||||
const bodyContent = body ? JSON.stringify(body) : '';
|
||||
// handle unicode chars with a text encoder
|
||||
const encoder = new TextEncoder();
|
||||
|
||||
headers = {
|
||||
...headers,
|
||||
'Content-Length': encoder.encode(bodyContent).length.toString(),
|
||||
};
|
||||
}
|
||||
|
||||
if (!headers.hasOwnProperty('Accept')) {
|
||||
headers.Accept = '*/*';
|
||||
}
|
||||
|
||||
const headerString = headers
|
||||
? Object.entries(headers)
|
||||
.map(([key, value]) =>
|
||||
key.toLowerCase() !== 'host' ? `${key}: ${value}` : ``,
|
||||
)
|
||||
.join('\n') + '\n'
|
||||
: '';
|
||||
|
||||
const bodyString = body ? `\n${JSON.stringify(body, null, 2)}` : '';
|
||||
|
||||
const httpRequest = `${method.toUpperCase()} ${decodeURI(path)} HTTP/1.1
|
||||
Host: ${host}
|
||||
${headerString}${bodyString}`;
|
||||
|
||||
return httpRequest;
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
function indent(code: string, spaces: number) {
|
||||
@@ -93,3 +133,24 @@ function indent(code: string, spaces: number) {
|
||||
.map((line) => (line ? indent + line : ''))
|
||||
.join('\n');
|
||||
}
|
||||
|
||||
export function parseHostAndPath(url: string) {
|
||||
try {
|
||||
const urlObj = new URL(url);
|
||||
const path = urlObj.pathname || '/';
|
||||
return { host: urlObj.host, path };
|
||||
} catch (e) {
|
||||
// If the URL was invalid do our best to parse the URL.
|
||||
// Check for the protocol part and pull it off to grab the host
|
||||
const fullUrl = url.match(/\/\//) ? url.split('//')[1] : url;
|
||||
|
||||
// separate paths from the first element (host)
|
||||
const parts = fullUrl.split('/');
|
||||
// pull off the host (mutates)
|
||||
const host = parts.shift();
|
||||
// add a leading slash and join the paths again
|
||||
const path = '/' + parts.join('/');
|
||||
|
||||
return { host, path };
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user