From b41b181dd0a4ce498142126c3007e6dfa3f158ca Mon Sep 17 00:00:00 2001 From: Roman Hotsiy Date: Mon, 23 Jul 2018 10:47:01 +0300 Subject: [PATCH] fix: server url contains spec name if not specified in the spec --- src/services/models/Operation.ts | 33 +----------------------- src/utils/__tests__/openapi.test.ts | 40 +++++++++++++++++++++++++++++ src/utils/helpers.ts | 4 --- src/utils/openapi.ts | 37 +++++++++++++++++++++++++- 4 files changed, 77 insertions(+), 37 deletions(-) diff --git a/src/services/models/Operation.ts b/src/services/models/Operation.ts index d88059a0..4e103ec7 100644 --- a/src/services/models/Operation.ts +++ b/src/services/models/Operation.ts @@ -1,6 +1,4 @@ import { action, observable } from 'mobx'; -import { join as joinPaths } from 'path'; -import { parse as urlParse } from 'url'; import { IMenuItem } from '../MenuStore'; import { GroupModel } from './Group.model'; @@ -11,13 +9,11 @@ import { OpenAPIExternalDocumentation, OpenAPIServer } from '../../types'; import { getOperationSummary, getStatusCodeType, - IS_BROWSER, - isAbsolutePath, isStatusCode, JsonPointer, mergeParams, + normalizeServers, sortByRequired, - stripTrailingSlash, } from '../../utils'; import { ContentItemModel, ExtendedOpenAPIOperation } from '../MenuBuilder'; import { OpenAPIParser } from '../OpenAPIParser'; @@ -148,30 +144,3 @@ export class OperationModel implements IMenuItem { this.active = false; } } - -function normalizeServers(specUrl: string | undefined, servers: OpenAPIServer[]): OpenAPIServer[] { - const baseUrl = specUrl === undefined ? (IS_BROWSER ? window.location.href : '') : specUrl; - - if (servers.length === 0) { - return [ - { - url: baseUrl, - }, - ]; - } - - function normalizeUrl(url: string): string { - url = isAbsolutePath(url) ? url : joinPaths(baseUrl, url); - return stripTrailingSlash(url.startsWith('//') ? `${specProtocol}${url}` : url); - } - - const { protocol: specProtocol } = urlParse(baseUrl); - - return servers.map(server => { - return { - ...server, - url: normalizeUrl(server.url), - description: server.description || '', - }; - }); -} diff --git a/src/utils/__tests__/openapi.test.ts b/src/utils/__tests__/openapi.test.ts index 36c85e64..e1166c02 100644 --- a/src/utils/__tests__/openapi.test.ts +++ b/src/utils/__tests__/openapi.test.ts @@ -5,6 +5,7 @@ import { isOperationName, isPrimitiveType, mergeParams, + normalizeServers, } from '../'; import { OpenAPIParser } from '../../services'; @@ -222,4 +223,43 @@ describe('Utils', () => { expect(res[2]).toEqual(operationParams[1]); }); }); + + describe('normalize servers', () => { + it('should make url absolute and strip spec name', () => { + const res = normalizeServers('http://base.com/spec.yaml', [ + { + url: '/sandbox/test', + }, + ]); + expect(res).toEqual([{ url: 'http://base.com/sandbox/test', description: '' }]); + }); + + it('should prefer server host over spec`s one', () => { + const res = normalizeServers('http://base.com/spec.yaml', [ + { + url: 'https://otherbase.com/sandbox/test', + }, + ]); + expect(res).toEqual([{ url: 'https://otherbase.com/sandbox/test', description: '' }]); + }); + + it('should strip trailing slash', () => { + const res = normalizeServers('', [ + { + url: 'https://otherbase.com/sandbox/test/', + }, + ]); + expect(res).toEqual([{ url: 'https://otherbase.com/sandbox/test', description: '' }]); + }); + + it('should set correct protocol', () => { + const res = normalizeServers('https://base.com', [ + { + url: '//base.com/sandbox/test', + description: 'test', + }, + ]); + expect(res).toEqual([{ url: 'https://base.com/sandbox/test', description: 'test' }]); + }); + }); }); diff --git a/src/utils/helpers.ts b/src/utils/helpers.ts index 6ab2dbed..0debd57e 100644 --- a/src/utils/helpers.ts +++ b/src/utils/helpers.ts @@ -64,10 +64,6 @@ export function stripTrailingSlash(path: string): string { return path; } -export function isAbsolutePath(path: string): boolean { - return /^(?:[a-z]+:)?/i.test(path); -} - export function isNumeric(n: any): n is number { return !isNaN(parseFloat(n)) && isFinite(n); } diff --git a/src/utils/openapi.ts b/src/utils/openapi.ts index a5aeec9a..651df723 100644 --- a/src/utils/openapi.ts +++ b/src/utils/openapi.ts @@ -1,12 +1,17 @@ +import { dirname } from 'path'; +import { parse as urlParse, resolve as resolveUrl } from 'url'; + import { OpenAPIParser } from '../services/OpenAPIParser'; import { OpenAPIMediaType, OpenAPIOperation, OpenAPIParameter, OpenAPISchema, + OpenAPIServer, Referenced, } from '../types'; -import { isNumeric } from './helpers'; +import { IS_BROWSER } from './dom'; +import { isNumeric, stripTrailingSlash } from './helpers'; function isWildcardStatusCode(statusCode: string | number): statusCode is string { return typeof statusCode === 'string' && /\dxx/i.test(statusCode); @@ -235,4 +240,34 @@ export function mergeSimilarMediaTypes(types: Dict): Dict { + return { + ...server, + url: normalizeUrl(server.url), + description: server.description || '', + }; + }); +} + export const SECURITY_SCHEMES_SECTION = 'section/Authentication/';