/** * */ import { KushkiError } from "@kushki/core"; import { APIGatewayProxyResult } from "aws-lambda"; import { Lambda } from "aws-sdk"; import * as LambdaType from "aws-sdk/clients/lambda"; import { IDENTIFIERS } from "constant/Identifiers"; import { ErrorCode, ERRORS } from "infrastructure/ErrorEnum"; import { inject, injectable } from "inversify"; import { ILambdaGateway } from "repository/ILambdaGateway"; import { Observable, of } from "rxjs"; import { tag } from "rxjs-spy/operators"; import { concatMap, map } from "rxjs/operators"; import tsLogClass from "ts-log-class"; interface ILambdaError { code: string; message: string; body: { code: string; message: string }; } /** * Gateway to send data do call a Lambda function */ @injectable() @tsLogClass() export class LambdaGateway implements ILambdaGateway { private _lambda: Lambda; constructor(@inject(IDENTIFIERS.AwsLambda) lambda: Lambda) { this._lambda = lambda; } public invokeFunction( functionName: string, payload: object ): Observable { return this._invokeFunctionWithPromise(functionName, payload).pipe( map((x: T) => x), tag("LambdaGateway | invokeFunction") ); } private _invokeFunctionWithPromise( functionName: string, payload: object ): Observable { let payload_res: T; const params: Lambda.Types.InvocationRequest = { FunctionName: functionName, Payload: JSON.stringify(payload), }; return of(1).pipe( concatMap(async () => this._lambda.invoke(params).promise()), tag("LambdaGateway | invokeFunctionWithPromise - AWS response"), map((res: LambdaType.Types.InvocationResponse) => { if (res.Payload === null) throw new Error("Lambda response is null"); payload_res = JSON.parse(res.Payload); if ("body" in payload_res) (payload_res).body = JSON.parse( (payload_res).body ); if ( "statusCode" in payload_res && [500, 400].indexOf( (<{ statusCode: number }>payload_res).statusCode ) !== -1 ) throw LambdaGateway._getError(payload_res); return payload_res; }), tag("LambdaGateway | invokeFunctionWithPromise") ); } private static _getError(error: ILambdaError): KushkiError | Error { const code: string = (error.body !== undefined ? error.body.code : error.code ).replace("T", "E"); const message: string = error.body !== undefined ? error.body.message : error.message; if (Object.values(ErrorCode).includes(code)) return new KushkiError(ERRORS[code], message); return new Error( error.body !== undefined ? error.body.message : error.message ); } }