mirror of
https://github.com/Redocly/redoc.git
synced 2025-01-31 10:04:08 +03:00
parent
59e05fbe75
commit
9d6b30c55a
|
@ -234,6 +234,24 @@ describe('Utils', () => {
|
|||
expect(res).toEqual([{ url: 'http://base.com/sandbox/test', description: '' }]);
|
||||
});
|
||||
|
||||
it('should correcly resolve url with server relative path', () => {
|
||||
const res = normalizeServers('http://base.com/subpath/spec.yaml', [
|
||||
{
|
||||
url: '/sandbox/test',
|
||||
},
|
||||
]);
|
||||
expect(res).toEqual([{ url: 'http://base.com/sandbox/test', description: '' }]);
|
||||
});
|
||||
|
||||
it('should correcly resolve url with relative path', () => {
|
||||
const res = normalizeServers('http://base.com/subpath/spec.yaml', [
|
||||
{
|
||||
url: 'sandbox/test',
|
||||
},
|
||||
]);
|
||||
expect(res).toEqual([{ url: 'http://base.com/subpath/sandbox/test', description: '' }]);
|
||||
});
|
||||
|
||||
it('should prefer server host over spec`s one', () => {
|
||||
const res = normalizeServers('http://base.com/spec.yaml', [
|
||||
{
|
||||
|
@ -261,5 +279,35 @@ describe('Utils', () => {
|
|||
]);
|
||||
expect(res).toEqual([{ url: 'https://base.com/sandbox/test', description: 'test' }]);
|
||||
});
|
||||
|
||||
it('should expand variables', () => {
|
||||
const servers = normalizeServers('', [
|
||||
{
|
||||
url: '{protocol}{host}{basePath}',
|
||||
variables: {
|
||||
protocol: {
|
||||
default: 'http://',
|
||||
},
|
||||
host: {
|
||||
default: '127.0.0.1',
|
||||
},
|
||||
basePath: {
|
||||
default: '/path/to/endpoint',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
url: 'http://127.0.0.2:{port}',
|
||||
variables: {},
|
||||
},
|
||||
{
|
||||
url: 'http://127.0.0.3',
|
||||
},
|
||||
]);
|
||||
|
||||
expect(servers[0].url).toEqual('http://127.0.0.1/path/to/endpoint');
|
||||
expect(servers[1].url).toEqual('http://127.0.0.2:{port}');
|
||||
expect(servers[2].url).toEqual('http://127.0.0.3');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import slugify from 'slugify';
|
||||
import { format, parse } from 'url';
|
||||
|
||||
/**
|
||||
* Maps over array passing `isLast` bool to iterator as the second arguemnt
|
||||
|
@ -133,3 +134,30 @@ export function safeSlugify(value: string): string {
|
|||
.replace(/-+$/, '')
|
||||
); // Trim - from end of text
|
||||
}
|
||||
|
||||
export function isAbsoluteUrl(url: string) {
|
||||
return /(?:^[a-z][a-z0-9+.-]*:|\/\/)/i.test(url);
|
||||
}
|
||||
|
||||
/**
|
||||
* simple resolve URL which doesn't break on strings with url fragments
|
||||
* e.g. resolveUrl('http://test.com:{port}', 'path') results in http://test.com:{port}/path
|
||||
*/
|
||||
export function resolveUrl(url: string, to: string) {
|
||||
let res;
|
||||
if (to.startsWith('//')) {
|
||||
const { protocol: specProtocol } = parse(url);
|
||||
res = `${specProtocol}${to}`;
|
||||
} else if (isAbsoluteUrl(to)) {
|
||||
res = to;
|
||||
} else if (!to.startsWith('/')) {
|
||||
res = stripTrailingSlash(url) + '/' + to;
|
||||
} else {
|
||||
const urlObj = parse(url);
|
||||
res = format({
|
||||
...urlObj,
|
||||
pathname: to,
|
||||
});
|
||||
}
|
||||
return stripTrailingSlash(res);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { dirname } from 'path';
|
||||
import { parse as urlParse, resolve as resolveUrl } from 'url';
|
||||
|
||||
import { OpenAPIParser } from '../services/OpenAPIParser';
|
||||
import {
|
||||
|
@ -11,7 +10,7 @@ import {
|
|||
Referenced,
|
||||
} from '../types';
|
||||
import { IS_BROWSER } from './dom';
|
||||
import { isNumeric, stripTrailingSlash } from './helpers';
|
||||
import { isNumeric, resolveUrl } from './helpers';
|
||||
|
||||
function isWildcardStatusCode(statusCode: string | number): statusCode is string {
|
||||
return typeof statusCode === 'string' && /\dxx/i.test(statusCode);
|
||||
|
@ -240,6 +239,13 @@ export function mergeSimilarMediaTypes(types: Dict<OpenAPIMediaType>): Dict<Open
|
|||
return mergedTypes;
|
||||
}
|
||||
|
||||
function expandVariables(url: string, variables: object = {}) {
|
||||
return url.replace(
|
||||
/(?:{)(\w+)(?:})/g,
|
||||
(match, name) => (variables[name] && variables[name].default) || match,
|
||||
);
|
||||
}
|
||||
|
||||
export function normalizeServers(
|
||||
specUrl: string | undefined,
|
||||
servers: OpenAPIServer[],
|
||||
|
@ -254,17 +260,16 @@ export function normalizeServers(
|
|||
},
|
||||
];
|
||||
}
|
||||
const { protocol: specProtocol } = urlParse(baseUrl);
|
||||
|
||||
function normalizeUrl(url: string): string {
|
||||
url = resolveUrl(baseUrl, url);
|
||||
return stripTrailingSlash(url.startsWith('//') ? `${specProtocol}${url}` : url);
|
||||
function normalizeUrl(url: string, variables: object | undefined): string {
|
||||
url = expandVariables(url, variables);
|
||||
return resolveUrl(baseUrl, url);
|
||||
}
|
||||
|
||||
return servers.map(server => {
|
||||
return {
|
||||
...server,
|
||||
url: normalizeUrl(server.url),
|
||||
url: normalizeUrl(server.url, server.variables),
|
||||
description: server.description || '',
|
||||
};
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue
Block a user