From d03b044fe0c1438e00aa4ab94975044aa09bf700 Mon Sep 17 00:00:00 2001 From: Brandon Weber Date: Wed, 30 Nov 2022 10:51:55 -0600 Subject: [PATCH] feat: add new proxy transform attributes (#252) --- src/common/utils.ts | 34 +++++++++++++- src/proxies/BasisTheoryProxies.ts | 28 +++++++++++- src/types/models/proxies.ts | 16 ++++++- src/types/models/reactors.ts | 2 +- test/proxies.test.ts | 73 +++++++++++++++++++++++++------ 5 files changed, 135 insertions(+), 18 deletions(-) diff --git a/src/common/utils.ts b/src/common/utils.ts index 39afdf8a..f6748d05 100644 --- a/src/common/utils.ts +++ b/src/common/utils.ts @@ -9,7 +9,7 @@ import os from 'os'; import { snakeCase } from 'snake-case'; import snakecaseKeys from 'snakecase-keys'; import type { RequestTransformers } from '@/service'; -import type { Reactor, Token, TokenBase } from '@/types/models'; +import type { Reactor, Proxy, Token, TokenBase } from '@/types/models'; import type { ApplicationInfo, ClientUserAgent, @@ -61,6 +61,21 @@ const transformReactorRequestSnakeCase: AxiosTransformer = ( } as Reactor; }; +const transformProxyRequestSnakeCase: AxiosTransformer = ( + proxy: Proxy +): Proxy | undefined => { + if (typeof proxy === 'undefined') { + return undefined; + } + + return { + ...snakecaseKeys(proxy, { deep: true }), + ...(proxy.configuration !== undefined + ? { configuration: proxy.configuration } + : {}), + } as Proxy; +}; + const transformAtomicRequestSnakeCase: AxiosTransformer = < T extends TokenBase, S extends TokenBase @@ -120,6 +135,21 @@ const transformReactorResponseCamelCase: AxiosTransformer = ( } as Reactor; }; +const transformProxyResponseCamelCase: AxiosTransformer = ( + proxy: Proxy +): Proxy | undefined => { + if (typeof proxy === 'undefined') { + return undefined; + } + + return { + ...camelcaseKeys(proxy, { deep: true }), + ...(proxy.configuration !== undefined + ? { configuration: proxy.configuration } + : {}), + } as Proxy; +}; + const transformResponseCamelCase: AxiosTransformer = ( data: T ): C | undefined => { @@ -370,10 +400,12 @@ export { transformRequestSnakeCase, proxyRaw, transformReactorRequestSnakeCase, + transformProxyRequestSnakeCase, transformAtomicRequestSnakeCase, transformTokenRequestSnakeCase, transformTokenResponseCamelCase, transformReactorResponseCamelCase, + transformProxyResponseCamelCase, transformResponseCamelCase, transformAtomicResponseCamelCase, dataExtractor, diff --git a/src/proxies/BasisTheoryProxies.ts b/src/proxies/BasisTheoryProxies.ts index b3f29005..b0d980f9 100644 --- a/src/proxies/BasisTheoryProxies.ts +++ b/src/proxies/BasisTheoryProxies.ts @@ -1,10 +1,36 @@ +import type { AxiosTransformer } from 'axios'; +import { + transformProxyResponseCamelCase, + transformProxyRequestSnakeCase, +} from '@/common/utils'; import { BasisTheoryService } from '@/service'; +import type { BasisTheoryServiceOptions } from '@/service'; import { CrudBuilder } from '@/service/CrudBuilder'; import type { CreateProxy, UpdateProxy, Proxy } from '@/types/models'; import type { ListProxyQuery } from '@/types/sdk'; export const BasisTheoryProxies = new CrudBuilder( - class BasisTheoryProxies extends BasisTheoryService {} + class BasisTheoryProxies extends BasisTheoryService { + public constructor(options: BasisTheoryServiceOptions) { + const _options = { + ...options, + }; + + // eslint-disable-next-line unicorn/prefer-spread + _options.transformRequest = ([] as AxiosTransformer[]).concat( + transformProxyRequestSnakeCase, + options.transformRequest || [] + ); + + // eslint-disable-next-line unicorn/prefer-spread + _options.transformResponse = ([] as AxiosTransformer[]).concat( + transformProxyResponseCamelCase, + options.transformResponse || [] + ); + + super(_options); + } + } ) .create() .retrieve() diff --git a/src/types/models/proxies.ts b/src/types/models/proxies.ts index 4e93991d..259ed715 100644 --- a/src/types/models/proxies.ts +++ b/src/types/models/proxies.ts @@ -1,3 +1,4 @@ +import type { Application } from './applications'; import type { Auditable } from './shared'; interface Proxy extends Auditable { @@ -8,17 +9,30 @@ interface Proxy extends Auditable { destinationUrl: string; requestReactorId?: string; responseReactorId?: string; + requestTransform?: ProxyTransform; + responseTransform?: ProxyTransform; + applicationId?: string; + configuration?: Record; requireAuth?: boolean; } +interface ProxyTransform { + code: string; +} + type CreateProxy = Pick< Proxy, | 'name' | 'destinationUrl' | 'requestReactorId' | 'responseReactorId' + | 'requestTransform' + | 'responseTransform' + | 'configuration' | 'requireAuth' ->; +> & { + application?: Pick; +}; type UpdateProxy = CreateProxy; diff --git a/src/types/models/reactors.ts b/src/types/models/reactors.ts index 4ec64596..72c3e8a0 100644 --- a/src/types/models/reactors.ts +++ b/src/types/models/reactors.ts @@ -8,7 +8,7 @@ interface Reactor extends Auditable { name: string; formula: ReactorFormula; application?: Application; - configuration: Record; + configuration?: Record; } type CreateReactor = Pick & { diff --git a/test/proxies.test.ts b/test/proxies.test.ts index b565938a..0d44f145 100644 --- a/test/proxies.test.ts +++ b/test/proxies.test.ts @@ -1,6 +1,7 @@ import type MockAdapter from 'axios-mock-adapter'; import { Chance } from 'chance'; import { BasisTheory } from '@/BasisTheory'; +import { transformProxyRequestSnakeCase } from '@/common/utils'; import type { BasisTheory as IBasisTheory } from '@/types/sdk'; import { mockServiceClient, testCRUD } from './setup/utils'; @@ -23,23 +24,67 @@ describe('Proxies', () => { }); describe('CRUD', () => { + const _chance = new Chance(); + + const createPayload = { + name: _chance.animal(), + destinationUrl: _chance.url(), + requestReactorId: _chance.guid(), + responseReactorId: _chance.guid(), + requestTransform: { + code: _chance.string(), + }, + responseTransform: { + code: _chance.string(), + }, + application: { + id: _chance.guid(), + }, + configuration: { + // eslint-disable-next-line camelcase + snake_case: _chance.string(), + camelCase: _chance.string(), + }, + requireAuth: _chance.bool(), + }; + + const updatePayload = { + name: _chance.animal(), + destinationUrl: _chance.url(), + requestReactorId: _chance.guid(), + responseReactorId: _chance.guid(), + requestTransform: { + code: _chance.word(), + }, + responseTransform: { + code: _chance.word(), + }, + application: { + id: _chance.guid(), + }, + configuration: { + // eslint-disable-next-line camelcase + snake_case: _chance.string(), + camelCase: _chance.string(), + }, + requireAuth: _chance.bool(), + }; + + const transformedCreatePayload = transformProxyRequestSnakeCase( + createPayload + ); + + const transformedUpdatePayload = transformProxyRequestSnakeCase( + updatePayload + ); + testCRUD(() => ({ service: bt.proxies, client, - createPayload: { - name: chance.animal(), - destinationUrl: chance.url(), - requestReactorId: chance.guid(), - responseReactorId: chance.guid(), - requireAuth: chance.bool(), - }, - updatePayload: { - name: chance.animal(), - destinationUrl: chance.url(), - requestReactorId: chance.guid(), - responseReactorId: chance.guid(), - requireAuth: chance.bool(), - }, + createPayload, + transformedCreatePayload, + updatePayload, + transformedUpdatePayload, })); }); });