import * as Types from './json-types' ; /**
 * Helpers to create various fake things for Alexa requests.
 */ export const Fake = Object . freeze ( { timestamp : ( ) => new Date ( ) . toISOString ( ) , userId : ( ) => 'amzn1.ask.account.FAKEACCOUNTID' , requestId : ( ) => 'amzn1.echo-api.request.d15314a4-3a86-4d5a-90b0-5adb6a5b5ce7' , sessionId : ( ) => 'amzn1.echo-api.session.bcea274f-0dd8-43ac-8369-e102f881b42e' , applicationId : ( ) => 'amzn1.ask.skill.659a0b41-d887-45b0-a158-01b3d2214d5a' , /**
     * Create a version 1.0 Alexa request
     */ requestBody : ( session , request , context ) : Types . RequestBody => ( { version : '1.0' , session : session , request : request , context : context , } ) , launchRequest : ( ) : Types . LaunchRequest => ( { type : 'LaunchRequest' , requestId : Fake . requestId ( ) , timeStamp : Fake . timestamp ( ) , } ) , intentRequest : ( intent , slots ? ) : Types . IntentRequest => ( { type : 'IntentRequest' , requestId : Fake . requestId ( ) , timeStamp : Fake . timestamp ( ) , intent : { name : intent , slots : slots || { } , } , } ) , sessionEnded : ( reason ? ) : Types . SessionEndedRequest => ( { type : 'SessionEndedRequest' , reason : reason || 'USER_INITIATED' , requestId : Fake . requestId ( ) , timeStamp : Fake . timestamp ( ) , } ) , session : ( ) : Types . Session => ( { sessionId : Fake . sessionId ( ) , application : { applicationId : Fake . applicationId ( ) , } , attributes : { } , user : { userId : Fake . userId ( ) , } , new : true , } ) , requestContext : ( ) : Types . RequestContext => ( { AudioPlayer : { playerActivity : 'IDLE' , } , System : { apiEndpoint : 'https://api.amazonalexa.com' , application : { applicationId : Fake . applicationId ( ) , } , device : { deviceId : 'string' , supportedInterfaces : { AudioPlayer : { } , } , } , user : { userId : Fake . userId ( ) , accessToken : undefined , } , } , } ) , lambdaContext : ( ) : Types . Context => ( { awsRequestId : 'e0aa9f2d-5f4a-4ae8-a7b9-bb1a79ed91f6' , functionName : 'test-function' , callbackWaitsForEmptyEventLoop : true , functionVersion : '$LATEST' , invokeid : 'invokeid' , logGroupName : 'logGroupName' , logStreamName : 'logStreamName' , memoryLimitInMB : '128' , } ) , } ) ; type ExecuteRequest = ( request : Types . RequestBody ) => Promise < Types . ResponseBody > ; export const configure = ( handler , lambdaContext ? ) : ExecuteRequest => { const lambdaContextOrDefault = typeof lambdaContext === 'undefined' ? Fake . lambdaContext ( ) : lambdaContext ; return request => new Promise ( ( resolve , reject ) => handler ( request , lambdaContextOrDefault , ( err , res ) => { if ( err ) { reject ( err ) ; } else { resolve ( res ) ; } } ) ) ; } ; export interface Builders { LaunchRequest : ( ) => Types . LaunchRequest ; IntentRequest : ( name : string , slots ? : any ) => Types . IntentRequest ; SessionEndedRequest : ( reason ? : Types . SessionEndedReason ) => Types . SessionEndedRequest ; Session : ( ) => Types . Session ; Context : ( ) => Types . RequestContext ; } const defaultBuilders = ( ) : Builders => ( { LaunchRequest : Fake . launchRequest , IntentRequest : Fake . intentRequest , SessionEndedRequest : Fake . sessionEnded , Session : Fake . session , Context : Fake . requestContext , } ) ; const extendBuilders = ( custom ? ) : Builders => { const builders = defaultBuilders ( ) ; if ( typeof custom === 'undefined' ) { return builders ; } Object . keys ( custom ) . forEach ( key => { builders [ key ] = custom [ key ] ; } ) ; return builders ; } ; /**
 * Mock session for an Alexa lambda
 */ export class Session { private execute : ExecuteRequest ; private session : Types . Session ; private builders : Builders ; private context : Types . RequestContext ; param lambda param builders constructor ( lambda , builders ? ) { this . execute = configure ( lambda ) ; this . builders = extendBuilders ( builders ) ; this . session = this . builders . Session ( ) ; this . context = this . builders . Context ( ) ; this . context . System . user = this . session . user ; } LinkAccount ( accessToken ) { this . session . user . accessToken = accessToken ; return this ; } LaunchSkill ( ) { return this . Request ( Fake . requestBody ( this . session , this . builders . LaunchRequest ( ) , this . context ) ) ; } RequestIntent ( name , slots ? ) { return this . Request ( Fake . requestBody ( this . session , this . builders . IntentRequest ( name , slots ) , this . context ) ) ; } EndSession ( reason ? ) { return this . Request ( Fake . requestBody ( this . session , this . builders . SessionEndedRequest ( reason ) , this . context ) ) ; } Request ( request ) { return this . execute ( request ) . then ( response => { this . session . new = false ; if ( response && response . sessionAttributes && Object . getOwnPropertyNames ( response . sessionAttributes ) . length > 0 ) { this . session . attributes = response . sessionAttributes ; } return response ; } ) ; } }