1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-01-25 00:07:47 +01:00

fix: openapi spec should only include base path once (#1755)

* fix: openapi spec should only include base path once
This commit is contained in:
Christopher Kolstad 2022-06-27 15:39:08 +02:00 committed by GitHub
parent f2257eb45b
commit 54d28471f7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 139349 additions and 9127 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -843,73 +843,73 @@ components:
type: string
responses:
successResponse:
description: "Successful response"
description: 'Successful response'
content:
application/json:
schema:
$ref: '#/components/schemas/200'
notAuthorizedResponse:
description: "Not authorized"
description: 'Not authorized'
content:
application/json:
schema:
$ref: '#/components/schemas/401'
clientResponse:
description: "Successful response"
description: 'Successful response'
content:
application/json:
schema:
$ref: '#/components/schemas/200Client'
strategyExistsResponse:
description: "Strategy already exists"
description: 'Strategy already exists'
content:
application/json:
schema:
$ref: '#/components/schemas/409'
strategyResponse:
description: "Successful response"
description: 'Successful response'
content:
application/json:
schema:
$ref: '#/components/schemas/200strategy'
seenTogglesResponse:
description: "Successful response"
description: 'Successful response'
content:
application/json:
schema:
$ref: '#/components/schemas/200seen'
featureAccessResponse:
description: "Successful response"
description: 'Successful response'
content:
application/json:
schema:
$ref: '#/components/schemas/200feature'
appDetailsResponse:
description: "Successful response"
description: 'Successful response'
content:
application/json:
schema:
$ref: '#/components/schemas/200appdetails'
applicationsResponse:
description: "Successful response"
description: 'Successful response'
content:
application/json:
schema:
$ref: '#/components/schemas/applicationArray'
eventsResponse:
description: "Successful response"
description: 'Successful response'
content:
application/json:
schema:
$ref: '#/components/schemas/200-events'
exportResponse:
description: "Successful response"
description: 'Successful response'
content:
application/json:
schema:
$ref: '#/components/schemas/200export'
featureTypeResponse:
description: "Successful response"
description: 'Successful response'
content:
application/json:
schema:
@ -1205,7 +1205,7 @@ components:
type: string
example: '2016-12-09T14:56:36.730Z'
updatedAt:
description: 'The last time the application ''talked'' to Unleash (sent metrics, registered, fetched feature toggles) - in [ISO8601 format](https://www.w3.org/TR/NOTE-datetime)'
description: "The last time the application 'talked' to Unleash (sent metrics, registered, fetched feature toggles) - in [ISO8601 format](https://www.w3.org/TR/NOTE-datetime)"
type: string
example: '2020-11-14T09:55:23.653Z'
description:
@ -1222,7 +1222,7 @@ components:
description: Deprecated. Do not use
type: string
icon:
description: 'The application''s icon. Must be one of the [Material Design icon names](https://material.io/resources/icons/?style=baseline)'
description: "The application's icon. Must be one of the [Material Design icon names](https://material.io/resources/icons/?style=baseline)"
type: string
example: comment_bank
x-tags:
@ -1270,7 +1270,7 @@ components:
minLength: 1
example: '::ffff:127.0.0.1'
lastSeen:
description: 'The last time the application ''talked'' to Unleash (sent metrics, registered, fetched feature toggles) - in [ISO8601 format](https://www.w3.org/TR/NOTE-datetime)'
description: "The last time the application 'talked' to Unleash (sent metrics, registered, fetched feature toggles) - in [ISO8601 format](https://www.w3.org/TR/NOTE-datetime)"
type: string
minLength: 1
example: '2020-11-14T11:17:24.482Z'

View File

@ -39,7 +39,6 @@ export default async function getApp(
app.disable('x-powered-by');
app.set('port', config.server.port);
app.locals.baseUriPath = baseUriPath;
if (config.server.serverMetrics && config.eventBus) {
app.use(responseTimeMetrics(config.eventBus));
}

View File

@ -72,8 +72,46 @@ test('removeJsonSchemaProps', () => {
`);
});
describe('createOpenApiSchema', () => {
test('createOpenApiSchema url', () => {
expect(createOpenApiSchema('https://example.com').servers[0].url).toEqual(
'https://example.com',
);
expect(
createOpenApiSchema({
unleashUrl: 'https://example.com',
baseUriPath: '',
}).servers[0].url,
).toEqual('https://example.com');
});
test('if baseurl is set strips from serverUrl', () => {
expect(
createOpenApiSchema({
unleashUrl: 'https://example.com/demo2',
baseUriPath: '/demo2',
}).servers[0].url,
).toEqual('https://example.com');
});
test('if baseurl does not end with suffix, cowardly refuses to strip', () => {
expect(
createOpenApiSchema({
unleashUrl: 'https://example.com/demo2',
baseUriPath: 'example',
}).servers[0].url,
).toEqual('https://example.com/demo2');
});
test('avoids double trailing slash', () => {
expect(
createOpenApiSchema({
unleashUrl: 'https://example.com/example/',
baseUriPath: 'example',
}).servers[0].url,
).toEqual('https://example.com');
expect(
createOpenApiSchema({
unleashUrl: 'https://example.com/example/',
baseUriPath: '/example',
}).servers[0].url,
).toEqual('https://example.com');
});
});

View File

@ -83,6 +83,8 @@ import { strategySchema } from './spec/strategy-schema';
import { strategiesSchema } from './spec/strategies-schema';
import { upsertStrategySchema } from './spec/upsert-strategy-schema';
import { clientApplicationSchema } from './spec/client-application-schema';
import { IServerOption } from '../types';
import { URL } from 'url';
// All schemas in `openapi/spec` should be listed here.
export const schemas = {
@ -226,12 +228,31 @@ export const removeJsonSchemaProps = <T extends JsonSchemaProps>(
return omitKeys(schema, '$id', 'components');
};
export const createOpenApiSchema = (
serverUrl?: string,
): Omit<OpenAPIV3.Document, 'paths'> => {
const findRootUrl: (unleashUrl: string, baseUriPath: string) => string = (
unleashUrl: string,
baseUriPath?: string,
) => {
if (!baseUriPath) {
return unleashUrl;
}
const baseUrl = new URL(unleashUrl);
if (baseUrl.pathname.indexOf(baseUriPath) >= 0) {
return `${baseUrl.protocol}//${baseUrl.host}`;
}
return baseUrl.toString();
};
export const createOpenApiSchema = ({
unleashUrl,
baseUriPath,
}: Pick<IServerOption, 'unleashUrl' | 'baseUriPath'>): Omit<
OpenAPIV3.Document,
'paths'
> => {
const url = findRootUrl(unleashUrl, baseUriPath);
return {
openapi: '3.0.3',
servers: serverUrl ? [{ url: serverUrl }] : [],
servers: url ? [{ url }] : [],
info: {
title: 'Unleash API',
version: process.env.npm_package_version!,

View File

@ -24,7 +24,7 @@ export class OpenApiService {
this.api = openapi(
this.docsPath(),
createOpenApiSchema(config.server?.unleashUrl),
createOpenApiSchema(config.server),
{ coerce: true },
);
}