From 554c48aca4f37718a21beff7536cacf690be7be3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ro=C5=BCek?= Date: Wed, 20 Sep 2023 16:40:55 +0200 Subject: [PATCH] feat(oas): support new IHttpService security BREAKING CHANGE: IHttpService['security'] is a 2D array now --- package.json | 2 +- src/oas2/__tests__/bundle.test.ts | 22 +++++++------- src/oas2/__tests__/service.test.ts | 2 +- src/oas2/service.ts | 46 ++++++++++++++++-------------- src/oas3/__tests__/bundle.test.ts | 22 +++++++------- src/oas3/__tests__/service.test.ts | 2 +- src/oas3/service.ts | 46 ++++++++++++++++-------------- yarn.lock | 16 +++++------ 8 files changed, 83 insertions(+), 75 deletions(-) diff --git a/package.json b/package.json index bbe27f2..f282e6c 100644 --- a/package.json +++ b/package.json @@ -75,7 +75,7 @@ "dependencies": { "@stoplight/json": "^3.18.1", "@stoplight/json-schema-generator": "1.0.2", - "@stoplight/types": "^13.19.0", + "@stoplight/types": "14.0.0-beta.1", "@types/json-schema": "7.0.11", "@types/swagger-schema-official": "~2.0.22", "@types/type-is": "^1.6.3", diff --git a/src/oas2/__tests__/bundle.test.ts b/src/oas2/__tests__/bundle.test.ts index 9ef87d8..0ad7602 100644 --- a/src/oas2/__tests__/bundle.test.ts +++ b/src/oas2/__tests__/bundle.test.ts @@ -317,18 +317,20 @@ describe('bundleOas2Service', () => { }, ], security: [ - { - extensions: { - 'x-security-extension': { - hello: 'world', + [ + { + extensions: { + 'x-security-extension': { + hello: 'world', + }, }, + id: 'http_security-abc-scheme-api-key', + in: 'query', + key: 'api-key', + name: 'API Key', + type: 'apiKey', }, - id: 'http_security-abc-scheme-api-key', - in: 'query', - key: 'api-key', - name: 'API Key', - type: 'apiKey', - }, + ], ], }); }); diff --git a/src/oas2/__tests__/service.test.ts b/src/oas2/__tests__/service.test.ts index 89926fd..a70e3b7 100644 --- a/src/oas2/__tests__/service.test.ts +++ b/src/oas2/__tests__/service.test.ts @@ -111,7 +111,7 @@ describe('oas2 service', () => { }; const transformed = transformOas2Service({ document }); - expect(transformed).toHaveProperty(['security', 0, 'flows', 'implicit', 'scopes'], { scope_1: '' }); + expect(transformed).toHaveProperty(['security', 0, 0, 'flows', 'implicit', 'scopes'], { scope_1: '' }); }); it('should handle x-internal property', () => { diff --git a/src/oas2/service.ts b/src/oas2/service.ts index 91f245c..910c9bf 100644 --- a/src/oas2/service.ts +++ b/src/oas2/service.ts @@ -83,33 +83,35 @@ export const transformOas2Service: Oas2HttpServiceTransformer = ({ document, ctx const security = Array.isArray(document.security) ? document.security - .flatMap(sec => { + .map(sec => { if (!isPlainObject(sec)) return null; - return Object.keys(sec).map(key => { - const ss = securitySchemes.find(securityScheme => securityScheme.key === key); - if (ss && ss.type === 'oauth2') { - const flows = {}; - for (const flowKey in ss.flows) { - const flow = ss.flows[flowKey]; - flows[flowKey] = { - ...flow, - scopes: pickBy(flow.scopes, (_val: string, scopeKey: string) => { - const secKey = sec[key]; - if (secKey) return secKey.includes(scopeKey); - return undefined; - }), + return Object.keys(sec) + .map(key => { + const ss = securitySchemes.find(securityScheme => securityScheme.key === key); + if (ss?.type === 'oauth2') { + const flows = {}; + for (const flowKey in ss.flows) { + const flow = ss.flows[flowKey]; + flows[flowKey] = { + ...flow, + scopes: pickBy(flow.scopes, (_val: string, scopeKey: string) => { + const secKey = sec[key]; + if (secKey) return secKey.includes(scopeKey); + return undefined; + }), + }; + } + + return { + ...ss, + flows, }; } - return { - ...ss, - flows, - }; - } - - return ss; - }); + return ss; + }) + .filter(isNonNullable); }) .filter(isNonNullable) : []; diff --git a/src/oas3/__tests__/bundle.test.ts b/src/oas3/__tests__/bundle.test.ts index 2aa477f..48dd2cc 100644 --- a/src/oas3/__tests__/bundle.test.ts +++ b/src/oas3/__tests__/bundle.test.ts @@ -905,18 +905,20 @@ describe('bundleOas3Service', () => { ], }, security: [ - { - extensions: { - 'x-security-extension': { - hello: 'world', + [ + { + extensions: { + 'x-security-extension': { + hello: 'world', + }, }, + id: 'http_security-abc-scheme-api-key', + in: 'query', + key: 'api-key', + name: 'API Key', + type: 'apiKey', }, - id: 'http_security-abc-scheme-api-key', - in: 'query', - key: 'api-key', - name: 'API Key', - type: 'apiKey', - }, + ], ], tags: [ { diff --git a/src/oas3/__tests__/service.test.ts b/src/oas3/__tests__/service.test.ts index 0e9341f..0508f6a 100644 --- a/src/oas3/__tests__/service.test.ts +++ b/src/oas3/__tests__/service.test.ts @@ -305,7 +305,7 @@ describe('oas3 service', () => { }; const transformed = transformOas3Service({ document }); - expect(transformed).toHaveProperty(['security', 0, 'flows', 'implicit', 'scopes'], { scope_1: '' }); + expect(transformed).toHaveProperty(['security', 0, 0, 'flows', 'implicit', 'scopes'], { scope_1: '' }); }); describe('OAS 3.1 support', () => { diff --git a/src/oas3/service.ts b/src/oas3/service.ts index 72b70c2..5e65bbb 100644 --- a/src/oas3/service.ts +++ b/src/oas3/service.ts @@ -87,33 +87,35 @@ export const transformOas3Service: Oas3HttpServiceTransformer = ({ } const security = (Array.isArray(document.security) ? document.security : []) - .flatMap(sec => { + .map(sec => { if (!isPlainObject(sec)) return null; - return Object.keys(sec).map(key => { - const ss = securitySchemes.find(securityScheme => securityScheme.key === key); - if (ss && ss.type === 'oauth2') { - const flows = {}; - for (const flowKey in ss.flows) { - const flow = ss.flows[flowKey]; - flows[flowKey] = { - ...flow, - scopes: pickBy(flow.scopes, (_val: string, scopeKey: string) => { - const secKey = sec[key]; - if (secKey) return secKey.includes(scopeKey); - return false; - }), + return Object.keys(sec) + .map(key => { + const ss = securitySchemes.find(securityScheme => securityScheme.key === key); + if (ss?.type === 'oauth2') { + const flows = {}; + for (const flowKey in ss.flows) { + const flow = ss.flows[flowKey]; + flows[flowKey] = { + ...flow, + scopes: pickBy(flow.scopes, (_val: string, scopeKey: string) => { + const secKey = sec[key]; + if (secKey) return secKey.includes(scopeKey); + return false; + }), + }; + } + + return { + ...ss, + flows, }; } - return { - ...ss, - flows, - }; - } - - return ss; - }); + return ss; + }) + .filter(isNonNullable); }) .filter(isNonNullable); diff --git a/yarn.lock b/yarn.lock index d47faf6..f3e6caa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1483,18 +1483,18 @@ resolved "https://registry.yarnpkg.com/@stoplight/test-utils/-/test-utils-0.0.1.tgz#b0d38c8a0abebda2dacbc2aa6a4f9bec44878e7b" integrity sha512-Cj3waLFR9bYLG8yvgkjXMxOfiVdewRyrKdH5RQpttVNfKj5UF+mElofPcHn/UfiOuxK3t5rbsdMfS26LK5tdQg== -"@stoplight/types@^13.0.0": - version "13.3.0" - resolved "https://registry.yarnpkg.com/@stoplight/types/-/types-13.3.0.tgz#17ba488e7e65d8d5b98d86df9564a2a24ef84652" - integrity sha512-1DuqsnlKXF6Cf4PAJyJKMSt73Y+54AR+x+mt1Z3XxfHaSl/m2z7dHhLqLlTRHNqB3GOOoLgYzfuzEwHuYKIXRw== +"@stoplight/types@14.0.0-beta.1": + version "14.0.0-beta.1" + resolved "https://registry.yarnpkg.com/@stoplight/types/-/types-14.0.0-beta.1.tgz#9eee1811a03749d9b63a9f003897c6ee5005698c" + integrity sha512-TypAJM0SLIc42uMgKRAipecind5vjEYVRL7iCrLMCdgpliLWXwsaEKYgNTtGS7NeQ6159arvi5cNVnEQu2460w== dependencies: "@types/json-schema" "^7.0.4" utility-types "^3.10.0" -"@stoplight/types@^13.19.0": - version "13.20.0" - resolved "https://registry.yarnpkg.com/@stoplight/types/-/types-13.20.0.tgz#d42682f1e3a14a3c60bdf0df08bff4023518763d" - integrity sha512-2FNTv05If7ib79VPDA/r9eUet76jewXFH2y2K5vuge6SXbRHtWBhcaRmu+6QpF4/WRNoJj5XYRSwLGXDxysBGA== +"@stoplight/types@^13.0.0": + version "13.3.0" + resolved "https://registry.yarnpkg.com/@stoplight/types/-/types-13.3.0.tgz#17ba488e7e65d8d5b98d86df9564a2a24ef84652" + integrity sha512-1DuqsnlKXF6Cf4PAJyJKMSt73Y+54AR+x+mt1Z3XxfHaSl/m2z7dHhLqLlTRHNqB3GOOoLgYzfuzEwHuYKIXRw== dependencies: "@types/json-schema" "^7.0.4" utility-types "^3.10.0"