diff --git a/README.md b/README.md index b31f18c..7e7d6fc 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ A small library for [AWS Lambda](https://aws.amazon.com/lambda/details) providin ## Features * Easy Handling of [ANY method](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-method-settings-method-request.html#setup-method-add-http-method) in API Gateways -* Simplifies writing lambda handlers (in nodejs) +* Simplifies writing lambda handlers (in nodejs > 8) * Lambda Proxy Resource support for AWS API Gateway * Enable CORS for requests * No external dependencies @@ -19,6 +19,7 @@ A small library for [AWS Lambda](https://aws.amazon.com/lambda/details) providin * SNS * SQS * S3 +* Compatibility with Typescript >= 3.5 ## Installation @@ -54,7 +55,7 @@ export const handler = router.handler({ } ] } -} +}) ``` ## Proxy path support (work in progress) @@ -94,6 +95,36 @@ exports.handler = router.handler({ } ] } +}) +``` + +Typescript example: +```ts +import * as router from 'aws-lambda-router' +import { ProxyIntegrationEvent } from 'aws-lambda-router/lib/proxyIntegration' + +export const handler = router.handler({ + proxyIntegration: { + routes: [ + { + path: '/saveExample', + method: 'POST', + // request.body needs type assertion, because it defaults to type unknown (user input should be checked): + action: (request, context) => { + const { text } = request.body as { text: string } + return `You called me with: ${text}` + } + }, + { + path: '/saveExample2', + method: 'POST', + // it's also possible to set a type (no type check): + action: (request: ProxyIntegrationEvent<{ text: string }>, context) => { + return `You called me with: ${request.body.text}` + } + } + ] + } } ``` @@ -120,7 +151,7 @@ export const handler = router.handler({ } ] } -}); +}) ``` If CORS is activated, these default headers will be sent on every response: @@ -152,7 +183,7 @@ export const handler = router.handler({ 'ServerError': 500 } } -}); +}) function doThrowAnException(body) { throw {reason: 'MyCustomError', message: 'Throw an error for this example'} @@ -187,7 +218,7 @@ export const handler = router.handler({ } ] } -}); +}) ``` ## SQS to Lambda Integrations @@ -214,7 +245,7 @@ export const handler = router.handler({ } ] } -}); +}) ``` An SQS message always contains an array of records. In each SQS record there is the message in the body JSON key. @@ -291,7 +322,7 @@ export const handler = router.handler({ ], debug: true } -}); +}) ``` Per s3 event there can be several records per event. The action methods are called one after the other record. The result of the action method is an array with objects insides. @@ -328,13 +359,16 @@ See here: https://yarnpkg.com/en/docs/cli/link ## Release History - -* 0.7.2 +* 0.8.0 + * fix: changed ProxyIntegrationEvent body type to be generic but defaults to unknown + * fix: changed @types/aws-lambda from devDependency to dependency + * **breaking**: error response objects (thrown or rejected) now need to set `statusCode` instead of `status` (consistent with response) +* 0.7.1 * code style cleanup * fix: hosted package on npmjs should now worked * 0.7.0 * migrate to typescript - * using aws-lambda typings + * using @types/aws-lambda typings * proxyIntegration: cors is now optional (default: false) * removed use of aws lambda handler callback function (using Promise instead) * experimental _proxy path support_ (thanks to [@swaner](https://github.com/swaner)) diff --git a/lib/proxyIntegration.ts b/lib/proxyIntegration.ts index 6bf5257..5d6680c 100644 --- a/lib/proxyIntegration.ts +++ b/lib/proxyIntegration.ts @@ -1,19 +1,22 @@ import { APIGatewayEventRequestContext, APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda' import { ProcessMethod } from './EventProcessor' -export type ProxyIntegrationEvent = APIGatewayProxyEvent type ProxyIntegrationParams = { paths?: { [paramId: string]: string } } -export type ProxyIntegrationEventWithParams = APIGatewayProxyEvent & ProxyIntegrationParams +type ProxyIntegrationBody = { + body: T +} +export type ProxyIntegrationEvent = Omit & ProxyIntegrationParams & ProxyIntegrationBody +export type ProxyIntegrationResult = Omit & { statusCode?: APIGatewayProxyResult['statusCode'] } export interface ProxyIntegrationRoute { path: string method: string action: ( - request: ProxyIntegrationEventWithParams, + request: ProxyIntegrationEvent, context: APIGatewayEventRequestContext - ) => APIGatewayProxyResult | Promise + ) => ProxyIntegrationResult | Promise | string | Promise } export type ProxyIntegrationErrorMapping = { @@ -21,7 +24,7 @@ export type ProxyIntegrationErrorMapping = { } export type ProxyIntegrationError = { - status: APIGatewayProxyResult['statusCode'], + statusCode: APIGatewayProxyResult['statusCode'], message: string } | { reason: string, @@ -37,7 +40,7 @@ export interface ProxyIntegrationConfig { proxyPath?: string } -const NO_MATCHING_ACTION = (request: APIGatewayProxyEvent) => { +const NO_MATCHING_ACTION = (request: ProxyIntegrationEvent) => { throw { reason: 'NO_MATCHING_ACTION', message: `Could not find matching action for ${request.path} and method ${request.httpMethod}` @@ -51,17 +54,15 @@ const addCorsHeaders = (toAdd: APIGatewayProxyResult['headers'] = {}) => { return toAdd } -const processActionAndReturn = async (actionConfig: Pick, event: ProxyIntegrationEventWithParams, - context: APIGatewayEventRequestContext, headers: APIGatewayProxyResult['headers']) => { +const processActionAndReturn = async (actionConfig: Pick, event: ProxyIntegrationEvent, + context: APIGatewayEventRequestContext, headers: APIGatewayProxyResult['headers']) => { const res = await actionConfig.action(event, context) - if (!res || !res.body) { - const consolidateBody = res && JSON.stringify(res) || '{}' - + if (!res || typeof res !== 'object' || typeof res.body !== 'string') { return { statusCode: 200, headers, - body: consolidateBody + body: JSON.stringify(res) || '{}' } } @@ -75,7 +76,7 @@ const processActionAndReturn = async (actionConfig: Pick = +export const process: ProcessMethod = (proxyIntegrationConfig, event, context) => { if (proxyIntegrationConfig.debug) { @@ -112,10 +113,11 @@ export const process: ProcessMethod { + return processActionAndReturn(actionConfig, proxyEvent, context, headers).catch(error => { console.log('Error while handling action function.', error) return convertError(error, errorMapping, headers) }) @@ -154,12 +158,12 @@ const normalizeRequestPath = (event: APIGatewayProxyEvent): string => { return event.path } - // ugly hack: if host is from API-Gateway 'Custom Domain Name Mapping', then event.path has the value '/basepath/resource-path/'; + // ugly hack: if host is from API-Gateway 'Custom Domain Name Mapping', then event.path has the value '/basepath/resource-path/' // if host is from amazonaws.com, then event.path is just '/resource-path': const apiId = event.requestContext ? event.requestContext.apiId : null // the apiId that is the first part of the amazonaws.com-host if ((apiId && event.headers && event.headers.Host && event.headers.Host.substring(0, apiId.length) !== apiId)) { // remove first path element: - const groups: any = /\/[^\/]+(.*)/.exec(event.path) || [null, null] + const groups = /\/[^\/]+(.*)/.exec(event.path) || [null, null] return groups[1] || '/' } @@ -167,7 +171,7 @@ const normalizeRequestPath = (event: APIGatewayProxyEvent): string => { } const hasReason = (error: any): error is { reason: string } => typeof error.reason === 'string' -const hasStatus = (error: any): error is { status: number } => typeof error.status === 'number' +const hasStatus = (error: any): error is { statusCode: number } => typeof error.statusCode === 'number' const convertError = (error: ProxyIntegrationError | Error, errorMapping?: ProxyIntegrationErrorMapping, headers?: APIGatewayProxyResult['headers']) => { if (hasReason(error) && errorMapping && errorMapping[error.reason]) { @@ -178,8 +182,8 @@ const convertError = (error: ProxyIntegrationError | Error, errorMapping?: Proxy } } else if (hasStatus(error)) { return { - statusCode: error.status, - body: JSON.stringify({ message: error.message, error: error.status }), + statusCode: error.statusCode, + body: JSON.stringify({ message: error.message, error: error.statusCode }), headers: addCorsHeaders({}) } } @@ -189,12 +193,11 @@ const convertError = (error: ProxyIntegrationError | Error, errorMapping?: Proxy body: JSON.stringify({ error: 'ServerError', message: `Generic error:${JSON.stringify(error)}` }), headers: addCorsHeaders({}) } - } catch (stringifyError) { - } + } catch (stringifyError) { } return { statusCode: 500, - body: JSON.stringify({ error: 'ServerError', message: `Generic error` }) + body: JSON.stringify({ error: 'ServerError', message: 'Generic error' }) } } diff --git a/package.json b/package.json index 0cdd923..3306e7a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "aws-lambda-router", - "version": "0.7.2", + "version": "0.8.0", "description": "AWS lambda router", "main": "index.js", "types": "index.d.ts", @@ -30,13 +30,14 @@ }, "homepage": "https://github.com/spring-media/aws-lambda-router#readme", "devDependencies": { - "@types/aws-lambda": "^8.10.39", - "@types/jest": "^24.0.25", + "@types/jest": "^24.9.0", "@types/node": "^8.10.59", - "codecov": "^3.6.1", + "codecov": "^3.6.2", "jest": "24.9.0", "ts-jest": "24.2.0", - "typescript": "3.7.4" + "typescript": "3.7.5" }, - "dependencies": {} + "dependencies": { + "@types/aws-lambda": "^8.10.40" + } } diff --git a/test/proxyIntegration.test.ts b/test/proxyIntegration.test.ts index 6aed42d..bb439a5 100644 --- a/test/proxyIntegration.test.ts +++ b/test/proxyIntegration.test.ts @@ -2,7 +2,7 @@ import { process as proxyIntegration, ProxyIntegrationConfig } from '../lib/proxyIntegration' import { APIGatewayProxyEvent } from 'aws-lambda' -function forEach (arrayOfArrays: any) { +function forEach(arrayOfArrays: any) { return { it: (description: string, testCaseFunction: (...args: any[]) => void | Promise) => { arrayOfArrays.forEach((innerArray: any) => { @@ -374,7 +374,7 @@ describe('proxyIntegration.routeHandler', () => { }) it('should pass through error statuscode', async () => { - const statusCodeError = { status: 666, message: { reason: 'oops' } } + const statusCodeError = { statusCode: 666, message: { reason: 'oops' } } const routeConfig = { routes: [ { @@ -515,10 +515,21 @@ describe('proxyIntegration.routeHandler.returnvalues', () => { }) }) - it('should return async result', async () => { + forEach([ + [{ foo: 'bar' }, JSON.stringify({ foo: 'bar' })], + [{ body: 1234 }, JSON.stringify({ body: 1234 })], + [{ body: '1234' }, '1234'], + ['', '""'], + ['abc', '"abc"'], + [false, 'false'], + [true, 'true'], + [null, 'null'], + [1234, '1234'], + [undefined, '{}'] + ]).it('should return async result', async (returnValue, expectedBody) => { const routeConfig = { routes: [ - { method: 'GET', path: '/', action: () => Promise.resolve({ foo: 'bar' } as any) } + { method: 'GET', path: '/', action: () => Promise.resolve(returnValue) } ] } const result = await proxyIntegration(routeConfig, { @@ -528,7 +539,7 @@ describe('proxyIntegration.routeHandler.returnvalues', () => { expect(result).toEqual({ statusCode: 200, headers: jasmine.anything(), - body: JSON.stringify({ foo: 'bar' }) + body: expectedBody }) }) diff --git a/yarn.lock b/yarn.lock index 1b824f2..3913ce5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9,6 +9,13 @@ dependencies: "@babel/highlight" "^7.0.0" +"@babel/code-frame@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.8.3.tgz#33e25903d7481181534e12ec0a25f16b6fcf419e" + integrity sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g== + dependencies: + "@babel/highlight" "^7.8.3" + "@babel/core@^7.1.0": version "7.7.5" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.7.5.tgz#ae1323cd035b5160293307f50647e83f8ba62f7e" @@ -29,7 +36,17 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.4.0", "@babel/generator@^7.7.4": +"@babel/generator@^7.4.0", "@babel/generator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.8.3.tgz#0e22c005b0a94c1c74eafe19ef78ce53a4d45c03" + integrity sha512-WjoPk8hRpDRqqzRpvaR8/gDUPkrnOOeuT2m8cNICJtZH6mwaCo3v0OKMI7Y6SM1pBtyijnLtAL0HDi41pf41ug== + dependencies: + "@babel/types" "^7.8.3" + jsesc "^2.5.1" + lodash "^4.17.13" + source-map "^0.5.0" + +"@babel/generator@^7.7.4": version "7.7.4" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.7.4.tgz#db651e2840ca9aa66f327dcec1dc5f5fa9611369" integrity sha512-m5qo2WgdOJeyYngKImbkyQrnUN1mPceaG5BV+G0E3gWsa4l/jCSryWJdM2x8OuGAOyh+3d5pVYfZWCiNFtynxg== @@ -48,6 +65,15 @@ "@babel/template" "^7.7.4" "@babel/types" "^7.7.4" +"@babel/helper-function-name@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz#eeeb665a01b1f11068e9fb86ad56a1cb1a824cca" + integrity sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA== + dependencies: + "@babel/helper-get-function-arity" "^7.8.3" + "@babel/template" "^7.8.3" + "@babel/types" "^7.8.3" + "@babel/helper-get-function-arity@^7.7.4": version "7.7.4" resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.4.tgz#cb46348d2f8808e632f0ab048172130e636005f0" @@ -55,6 +81,13 @@ dependencies: "@babel/types" "^7.7.4" +"@babel/helper-get-function-arity@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz#b894b947bd004381ce63ea1db9f08547e920abd5" + integrity sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA== + dependencies: + "@babel/types" "^7.8.3" + "@babel/helper-plugin-utils@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz#bbb3fbee98661c569034237cc03967ba99b4f250" @@ -67,6 +100,13 @@ dependencies: "@babel/types" "^7.7.4" +"@babel/helper-split-export-declaration@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz#31a9f30070f91368a7182cf05f831781065fc7a9" + integrity sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA== + dependencies: + "@babel/types" "^7.8.3" + "@babel/helpers@^7.7.4": version "7.7.4" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.7.4.tgz#62c215b9e6c712dadc15a9a0dcab76c92a940302" @@ -85,11 +125,25 @@ esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.7.4", "@babel/parser@^7.7.5": +"@babel/highlight@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.8.3.tgz#28f173d04223eaaa59bc1d439a3836e6d1265797" + integrity sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg== + dependencies: + chalk "^2.0.0" + esutils "^2.0.2" + js-tokens "^4.0.0" + +"@babel/parser@^7.1.0", "@babel/parser@^7.7.4", "@babel/parser@^7.7.5": version "7.7.5" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.7.5.tgz#cbf45321619ac12d83363fcf9c94bb67fa646d71" integrity sha512-KNlOe9+/nk4i29g0VXgl8PEXIRms5xKLJeuZ6UptN0fHv+jDiriG+y94X6qAgWTR0h3KaoM1wK5G5h7MHFRSig== +"@babel/parser@^7.4.3", "@babel/parser@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.8.3.tgz#790874091d2001c9be6ec426c2eed47bc7679081" + integrity sha512-/V72F4Yp/qmHaTALizEm9Gf2eQHV3QyTL3K0cNfijwnMnb1L+LDlAubb/ZnSdGAVzVSWakujHYs1I26x66sMeQ== + "@babel/plugin-syntax-object-rest-spread@^7.0.0": version "7.7.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.7.4.tgz#47cf220d19d6d0d7b154304701f468fc1cc6ff46" @@ -97,7 +151,16 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/template@^7.4.0", "@babel/template@^7.7.4": +"@babel/template@^7.4.0", "@babel/template@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.8.3.tgz#e02ad04fe262a657809327f578056ca15fd4d1b8" + integrity sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ== + dependencies: + "@babel/code-frame" "^7.8.3" + "@babel/parser" "^7.8.3" + "@babel/types" "^7.8.3" + +"@babel/template@^7.7.4": version "7.7.4" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.7.4.tgz#428a7d9eecffe27deac0a98e23bf8e3675d2a77b" integrity sha512-qUzihgVPguAzXCK7WXw8pqs6cEwi54s3E+HrejlkuWO6ivMKx9hZl3Y2fSXp9i5HgyWmj7RKP+ulaYnKM4yYxw== @@ -106,7 +169,7 @@ "@babel/parser" "^7.7.4" "@babel/types" "^7.7.4" -"@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.7.4": +"@babel/traverse@^7.1.0", "@babel/traverse@^7.7.4": version "7.7.4" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.7.4.tgz#9c1e7c60fb679fe4fcfaa42500833333c2058558" integrity sha512-P1L58hQyupn8+ezVA2z5KBm4/Zr4lCC8dwKCMYzsa5jFMDMQAzaBNy9W5VjB+KAmBjb40U7a/H6ao+Xo+9saIw== @@ -121,7 +184,22 @@ globals "^11.1.0" lodash "^4.17.13" -"@babel/types@^7.0.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.7.4": +"@babel/traverse@^7.4.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.8.3.tgz#a826215b011c9b4f73f3a893afbc05151358bf9a" + integrity sha512-we+a2lti+eEImHmEXp7bM9cTxGzxPmBiVJlLVD+FuuQMeeO7RaDbutbgeheDkw+Xe3mCfJHnGOWLswT74m2IPg== + dependencies: + "@babel/code-frame" "^7.8.3" + "@babel/generator" "^7.8.3" + "@babel/helper-function-name" "^7.8.3" + "@babel/helper-split-export-declaration" "^7.8.3" + "@babel/parser" "^7.8.3" + "@babel/types" "^7.8.3" + debug "^4.1.0" + globals "^11.1.0" + lodash "^4.17.13" + +"@babel/types@^7.0.0", "@babel/types@^7.3.0", "@babel/types@^7.7.4": version "7.7.4" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.7.4.tgz#516570d539e44ddf308c07569c258ff94fde9193" integrity sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA== @@ -130,6 +208,15 @@ lodash "^4.17.13" to-fast-properties "^2.0.0" +"@babel/types@^7.4.0", "@babel/types@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.8.3.tgz#5a383dffa5416db1b73dedffd311ffd0788fb31c" + integrity sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg== + dependencies: + esutils "^2.0.2" + lodash "^4.17.13" + to-fast-properties "^2.0.0" + "@cnakazawa/watch@^1.0.3": version "1.0.3" resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.3.tgz#099139eaec7ebf07a27c1786a3ff64f39464d2ef" @@ -286,10 +373,10 @@ "@types/istanbul-reports" "^1.1.1" "@types/yargs" "^13.0.0" -"@types/aws-lambda@^8.10.39": - version "8.10.39" - resolved "https://registry.yarnpkg.com/@types/aws-lambda/-/aws-lambda-8.10.39.tgz#da83cf7a82695a8904e383d705829fecf96b7db2" - integrity sha512-6qxQ4wS636AapVvDbzltI/Xn69QWxjcvohvxd/+MTWzdE9Vqz1xgERr38jEbBGEkyyG8y819nAhjGsiY6KNh1A== +"@types/aws-lambda@^8.10.40": + version "8.10.40" + resolved "https://registry.yarnpkg.com/@types/aws-lambda/-/aws-lambda-8.10.40.tgz#d60b912a9425f74f60c57667a8c6b99d58df4ada" + integrity sha512-D0hOUw2y6in/cPWv0JMMCBnO3Hc/DNeLi8QQ1wymwk9Eixh6IFgVnCGJnUHefjxKEAVxL7z6LKBsFUrIjKygRg== "@types/babel__core@^7.1.0": version "7.1.3" @@ -344,10 +431,10 @@ "@types/istanbul-lib-coverage" "*" "@types/istanbul-lib-report" "*" -"@types/jest@^24.0.25": - version "24.0.25" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-24.0.25.tgz#2aba377824ce040114aa906ad2cac2c85351360f" - integrity sha512-hnP1WpjN4KbGEK4dLayul6lgtys6FPz0UfxMeMQCv0M+sTnzN3ConfiO72jHgLxl119guHgI8gLqDOrRLsyp2g== +"@types/jest@^24.9.0": + version "24.9.1" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-24.9.1.tgz#02baf9573c78f1b9974a5f36778b366aa77bd534" + integrity sha512-Fb38HkXSVA4L8fGKEZ6le5bB8r6MRWlOCZbVuWZcmOMSCd2wCYOwN1ibj8daIoV9naq7aaOZjrLCoCMptKU/4Q== dependencies: jest-diff "^24.3.0" @@ -736,15 +823,16 @@ co@^4.6.0: integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= codecov@^3.6.1: - version "3.6.1" - resolved "https://registry.yarnpkg.com/codecov/-/codecov-3.6.1.tgz#f39fc49413445555f81f8e3ca5730992843b4517" - integrity sha512-IUJB6WG47nWK7o50etF8jBadxdMw7DmoQg05yIljstXFBGB6clOZsIj6iD4P82T2YaIU3qq+FFu8K9pxgkCJDQ== + version "3.6.2" + resolved "https://registry.yarnpkg.com/codecov/-/codecov-3.6.2.tgz#9503533d744233f6864f8f3ead9435d285ed3f47" + integrity sha512-i1VYZYY3M8Lodk/QRsIWYVimkuhl0oMSiM2itxbTbEIjB0PCSWP1cI7cscu5P0MayggoTl6I/jkXV2go8Ub8/Q== dependencies: argv "^0.0.2" ignore-walk "^3.0.1" js-yaml "^3.13.1" teeny-request "^3.11.3" urlgrey "^0.4.4" + validator "^12.1.0" collection-visit@^1.0.0: version "1.0.0" @@ -773,11 +861,6 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" -commander@~2.20.3: - version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - component-emitter@^1.2.1: version "1.3.0" resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" @@ -1001,23 +1084,18 @@ escape-string-regexp@^1.0.5: integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= escodegen@^1.9.1: - version "1.12.0" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.12.0.tgz#f763daf840af172bb3a2b6dd7219c0e17f7ff541" - integrity sha512-TuA+EhsanGcme5T3R0L80u4t8CpbXQjegRmf7+FPTJrtCTErXFeelblRgHQa1FofEzqYYJmJ/OqjTwREp9qgmg== + version "1.13.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.13.0.tgz#c7adf9bd3f3cc675bb752f202f79a720189cab29" + integrity sha512-eYk2dCkxR07DsHA/X2hRBj0CFAZeri/LyDMc0C8JT1Hqi6JnVpMhJ7XFITbb0+yZS3lVkaPL2oCkZ3AVmeVbMw== dependencies: - esprima "^3.1.3" + esprima "^4.0.1" estraverse "^4.2.0" esutils "^2.0.2" optionator "^0.8.1" optionalDependencies: source-map "~0.6.1" -esprima@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" - integrity sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM= - -esprima@^4.0.0: +esprima@^4.0.0, esprima@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== @@ -1274,17 +1352,6 @@ growly@^1.3.0: resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= -handlebars@^4.1.2: - version "4.5.3" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.5.3.tgz#5cf75bd8714f7605713511a56be7c349becb0482" - integrity sha512-3yPecJoJHK/4c6aZhSvxOyG4vJKDshV36VHp0iVCDVh7o9w2vwi3NSnL2MMPj3YdduqaBcu7cGbggJQM0br9xA== - dependencies: - neo-async "^2.6.0" - optimist "^0.6.1" - source-map "^0.6.1" - optionalDependencies: - uglify-js "^3.1.4" - har-schema@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" @@ -1358,6 +1425,11 @@ html-encoding-sniffer@^1.0.2: dependencies: whatwg-encoding "^1.0.1" +html-escaper@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.0.tgz#71e87f931de3fe09e56661ab9a29aadec707b491" + integrity sha512-a4u9BeERWGu/S8JiWEAQcdrg9v4QArtP9keViQjGMdff20fBdd8waotXaNmODqBe6uZ3Nafi7K/ho4gCQHV3Ig== + http-signature@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" @@ -1629,11 +1701,11 @@ istanbul-lib-source-maps@^3.0.1: source-map "^0.6.1" istanbul-reports@^2.2.6: - version "2.2.6" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-2.2.6.tgz#7b4f2660d82b29303a8fe6091f8ca4bf058da1af" - integrity sha512-SKi4rnMyLBKe0Jy2uUdx28h8oG7ph2PPuQPvIAh31d+Ci+lSiEu4C+h3oBPuJ9+mPKhOyW0M8gY4U5NM1WLeXA== + version "2.2.7" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-2.2.7.tgz#5d939f6237d7b48393cc0959eab40cd4fd056931" + integrity sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg== dependencies: - handlebars "^4.1.2" + html-escaper "^2.0.0" jest-changed-files@^24.9.0: version "24.9.0" @@ -2252,11 +2324,6 @@ minimist@^1.1.1, minimist@^1.2.0: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= -minimist@~0.0.1: - version "0.0.10" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" - integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= - mixin-deep@^1.2.0: version "1.3.2" resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" @@ -2309,11 +2376,6 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= -neo-async@^2.6.0: - version "2.6.1" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c" - integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw== - nice-try@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" @@ -2436,14 +2498,6 @@ once@^1.3.0, once@^1.3.1, once@^1.4.0: dependencies: wrappy "1" -optimist@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" - integrity sha1-2j6nRob6IaGaERwybpDrFaAZZoY= - dependencies: - minimist "~0.0.1" - wordwrap "~0.0.2" - optionator@^0.8.1: version "0.8.3" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" @@ -2469,9 +2523,9 @@ p-finally@^1.0.0: integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= p-limit@^2.0.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.1.tgz#aa07a788cc3151c939b5131f63570f0dd2009537" - integrity sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg== + version "2.2.2" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.2.tgz#61279b67721f5287aa1c13a9a7fbbc48c9291b1e" + integrity sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ== dependencies: p-try "^2.0.0" @@ -2751,13 +2805,20 @@ resolve@1.1.7: resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= -resolve@1.x, resolve@^1.10.0, resolve@^1.3.2: +resolve@1.x, resolve@^1.3.2: version "1.13.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.13.1.tgz#be0aa4c06acd53083505abb35f4d66932ab35d16" integrity sha512-CxqObCX8K8YtAhOBRg+lrcdn+LK+WYOS8tSjqSFbjtrI5PnS63QPhZl4+yKfrU9tdsbMu9Anr/amegT87M9Z6w== dependencies: path-parse "^1.0.6" +resolve@^1.10.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.0.tgz#1b7ca96073ebb52e741ffd799f6b39ea462c67f5" + integrity sha512-+hTmAldEGE80U2wJJDC1lebb5jWqvTYAfm3YZ1ckk1gBr0MnCqUKlwK1e+anaFljIl+F5tR5IoZcm4ZDA1zMQw== + dependencies: + path-parse "^1.0.6" + ret@~0.1.10: version "0.1.15" resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" @@ -3167,10 +3228,10 @@ tr46@^1.0.1: dependencies: punycode "^2.1.0" -ts-jest@24.2.0: - version "24.2.0" - resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-24.2.0.tgz#7abca28c2b4b0a1fdd715cd667d65d047ea4e768" - integrity sha512-Yc+HLyldlIC9iIK8xEN7tV960Or56N49MDP7hubCZUeI7EbIOTsas6rXCMB4kQjLACJ7eDOF4xWEO5qumpKsag== +ts-jest@24.3.0: + version "24.3.0" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-24.3.0.tgz#b97814e3eab359ea840a1ac112deae68aa440869" + integrity sha512-Hb94C/+QRIgjVZlJyiWwouYUF+siNJHJHknyspaOcZ+OQAIdFG/UrdQVXw/0B8Z3No34xkUXZJpOTy9alOWdVQ== dependencies: bs-logger "0.x" buffer-from "1.x" @@ -3202,18 +3263,10 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" -typescript@3.7.4: - version "3.7.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.7.4.tgz#1743a5ec5fef6a1fa9f3e4708e33c81c73876c19" - integrity sha512-A25xv5XCtarLwXpcDNZzCGvW2D1S3/bACratYBx2sax8PefsFhlYmkQicKHvpYflFS8if4zne5zT5kpJ7pzuvw== - -uglify-js@^3.1.4: - version "3.7.2" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.7.2.tgz#cb1a601e67536e9ed094a92dd1e333459643d3f9" - integrity sha512-uhRwZcANNWVLrxLfNFEdltoPNhECUR3lc+UdJoG9CBpMcSnKyWA94tc3eAujB1GcMY5Uwq8ZMp4qWpxWYDQmaA== - dependencies: - commander "~2.20.3" - source-map "~0.6.1" +typescript@3.7.5: + version "3.7.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.7.5.tgz#0692e21f65fd4108b9330238aac11dd2e177a1ae" + integrity sha512-/P5lkRXkWHNAbcJIiHPfRoKqyd7bsyCma1hZNUGfn20qm64T6ZBlrzprymeu918H+mB/0rIg2gGK/BXkhhYgBw== union-value@^1.0.0: version "1.0.1" @@ -3276,6 +3329,11 @@ validate-npm-package-license@^3.0.1: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" +validator@^12.1.0: + version "12.1.0" + resolved "https://registry.yarnpkg.com/validator/-/validator-12.1.0.tgz#a3a7315d5238cbc15e46ad8d5e479aafa7119925" + integrity sha512-gIC2RBuFRi574Rb9vewGCJ7TCLxHXNx6EKthEgs+Iz0pYa9a9Te1VLG/bGLsAyGWrqR5FfR7tbFUI7FEF2LiGA== + verror@1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" @@ -3351,11 +3409,6 @@ word-wrap@~1.2.3: resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== -wordwrap@~0.0.2: - version "0.0.3" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" - integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc= - wrap-ansi@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09"