/**
 * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * This module defines the InvokeContext and supporting functions. The
 * InvokeContext is responsible for pulling information from the invoke headers
 * and for wrapping the Runtime Client object's error and response functions.
 */ "use strict" ; import { strict as assert } from "assert" ; import { IncomingHttpHeaders } from "http" ; import { ICallbackContext , IHeaderData , IEnvironmentData , INVOKE_HEADER , } from "../Common" ; import LogPatch from "../utils/LogPatch" ; const setCurrentRequestId = LogPatch . setCurrentRequestId ; export default class InvokeContext { headers : IncomingHttpHeaders ; constructor ( headers ) { this . headers = _enforceLowercaseKeys ( headers ) ; } private getHeaderValue ( key ) { const headerVal = this . headers [ key ] ; switch ( typeof headerVal ) { case "undefined" : return undefined ; case "string" : return headerVal ; default : if ( headerVal . length == 0 ) { return undefined ; } return headerVal [ 0 ] ; } } /**
     * The invokeId for this request.
     */ get invokeId ( ) : string { const id = this . getHeaderValue ( INVOKE_HEADER . AWSRequestId ) ; assert . ok ( id , "invocation id is missing or invalid" ) ; return id ; } /**
     * The header data for this request.
     */ get headerData ( ) : IHeaderData { return this . _headerData ( ) ; } /**
     * Push relevant invoke data into the logging context.
     */ updateLoggingContext ( ) { setCurrentRequestId ( this . invokeId ) ; } param callbackContext { Object } return { Object } attachEnvironmentData ( callbackContext ) { this . _forwardXRay ( ) ; return Object . assign ( callbackContext , this . _environmentalData ( ) , this . _headerData ( ) ) ; } /**
     * All parts of the user-facing context object which are provided through
     * environment variables.
     */ private _environmentalData ( ) { return { functionVersion : process . env [ "AWS_LAMBDA_FUNCTION_VERSION" ] , functionName : process . env [ "AWS_LAMBDA_FUNCTION_NAME" ] , memoryLimitInMB : process . env [ "AWS_LAMBDA_FUNCTION_MEMORY_SIZE" ] , logGroupName : process . env [ "AWS_LAMBDA_LOG_GROUP_NAME" ] , logStreamName : process . env [ "AWS_LAMBDA_LOG_STREAM_NAME" ] , } ; } /**
     * All parts of the user-facing context object which are provided through
     * request headers.
     */ private _headerData ( ) { const deadline = parseInt ( this . getHeaderValue ( INVOKE_HEADER . DeadlineMs ) || "" ) ; return { clientContext : _parseJson ( this . getHeaderValue ( INVOKE_HEADER . ClientContext ) , "ClientContext" ) , identity : _parseJson ( this . getHeaderValue ( INVOKE_HEADER . CognitoIdentity ) , "CognitoIdentity" ) , invokedFunctionArn : this . getHeaderValue ( INVOKE_HEADER . ARN ) , awsRequestId : this . getHeaderValue ( INVOKE_HEADER . AWSRequestId ) , getRemainingTimeInMillis : function ( ) { return deadline - Date . now ( ) ; } , } ; } /**
     * Forward the XRay header into the environment variable.
     */ private _forwardXRay ( ) { if ( this . getHeaderValue ( INVOKE_HEADER . XRayTrace ) ) { process . env [ "_X_AMZN_TRACE_ID" ] = this . getHeaderValue ( INVOKE_HEADER . XRayTrace ) ; } else { delete process . env [ "_X_AMZN_TRACE_ID" ] ; } } } param jsonString { string } param name { string } return throws function _parseJson ( jsonString ? , name ? ) { if ( jsonString !== undefined ) { try { return JSON . parse ( jsonString ) ; } catch ( err ) { throw new Error ( `Cannot parse ${ name } as json: ${ err . toString ( ) }` ) ; } } else { return undefined ; } } /**
 * Construct a copy of an object such that all of its keys are lowercase.
 */ function _enforceLowercaseKeys ( original ) { return Object . keys ( original ) . reduce ( ( enforced , originalKey ) => { enforced [ originalKey . toLowerCase ( ) ] = original [ originalKey ] ; return enforced ; } , { } as IncomingHttpHeaders ) ; }