Skip to content

Commit

Permalink
feat: simple variable substitution support
Browse files Browse the repository at this point in the history
fixes #565
  • Loading branch information
RomanHotsiy committed Jul 23, 2018
1 parent 59e05fb commit 9d6b30c
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 7 deletions.
48 changes: 48 additions & 0 deletions src/utils/__tests__/openapi.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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', [
{
Expand Down Expand Up @@ -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');
});
});
});
28 changes: 28 additions & 0 deletions src/utils/helpers.ts
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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);
}
19 changes: 12 additions & 7 deletions src/utils/openapi.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { dirname } from 'path';
import { parse as urlParse, resolve as resolveUrl } from 'url';

import { OpenAPIParser } from '../services/OpenAPIParser';
import {
Expand All @@ -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);
Expand Down Expand Up @@ -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[],
Expand All @@ -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 || '',
};
});
Expand Down

0 comments on commit 9d6b30c

Please sign in to comment.