import { ApolloServer } from 'apollo-server-lambda' ; import { APIGatewayProxyEvent , APIGatewayProxyHandler , APIGatewayProxyResult , Context , } from 'aws-lambda' ; import { APIGatewayProxyCallbackV2 , APIGatewayProxyEventV2 } from 'aws-lambda/trigger/api-gateway-proxy' ; import schemaCreator from './api' ; import apolloErrorHandler from './api/apolloErrorHandler' ; import applicationErrorHandler from './api/applicationErrorHandler' ; import authorizerV1 from './api/authorizer/v1' ; import authorizerV2 from './api/authorizer/v2' ; import userRest from './api/user/rest' ; import EventPublisher from './application/eventPublisher' ; import UserService from './application/user/userService' ; import { Dictionary } from './domain/declarations' ; import { IUserRepo } from './domain/user/IUserRepo' ; import infraServicesCreator from './infrastructure' ; import ILogger from './infrastructure/logger/ILogger' ; import { loadSecrets } from './infrastructure/secrets' ; import isRunningInLocalStack from './infrastructure/utils/isRunningInLocalStack' ; console . log ( `Booting SLS-NODE-TS in ${ process . env . NODE_ENV } NODE_ENV and in ${ process . env . ENV } ENV.` ) ; type ApolloHandler = ( event : APIGatewayProxyEventV2 , context : Context , callback : APIGatewayProxyCallbackV2 ) => void ; let apolloHandler ; let logger ; let restHandlers ; let services ; /**
 * Create the Service Instances to be shared amongst the Lambda Functions.
 */ const createServiceInstances = async ( accountId ) => { if ( services ) { return services ; } const loadFromAWSSecrets = [ 'production' , 'staging' ] . includes ( process . env . ENV || 'development' ) ; await loadSecrets ( loadFromAWSSecrets ) ; let infraServices ; try { infraServices = await infraServicesCreator ( accountId ) ; logger = infraServices . logger ; } catch ( e ) { console . error ( 'Error on infrastructure services startup' , e ) ; throw e ; } const userService = new UserService ( infraServices . userRepo , infraServices . eventPublisher ) ; services = { userService , } ; return services ; } ; /**
 * Create the Apollo Handler at cold start.
 */ const createApolloHandler = async ( accountId ) : Promise < ApolloHandler > => { if ( apolloHandler ) { return apolloHandler ; } const { userService } = services ? services : await createServiceInstances ( accountId ) ; const schema = schemaCreator ( { userService } ) ; const server = new ApolloServer ( { context : ( { event , context } ) => ( { context , event , headers : event . headers , } ) , formatError : apolloErrorHandler ( logger ) , introspection : true , schema , } ) ; return server . createHandler ( { expressGetMiddlewareOptions : { cors : { allowedHeaders : '*' , credentials : true , origin : '*' , } , } , } ) ; } ; /**
 * Create the REST Handlers at cold start.
 */ const createRESTHandlers = async ( accountId ) => { if ( restHandlers ) { return restHandlers ; } const { userService } = services ? services : await createServiceInstances ( accountId ) ; restHandlers = { ... userRest ( userService , logger ) , } ; return restHandlers ; } ; export const graphqlHandler = async ( lambdaEvent , lambdaContext ) => { see https if ( isRunningInLocalStack ) { lambdaEvent . version = '2.0' ; lambdaEvent . rawPath = '/graphql' ; lambdaEvent . requestContext . http = { method : 'POST' , path : '/graphql' , protocol : 'HTTP/1.1' , sourceIp : 'IP' , userAgent : 'agent' , } ; } see https return ( await createApolloHandler ( 'ciaone' ) ) ( lambdaEvent , lambdaContext ) ; } ; see https see https export { authorizerV1 } ; see https export { authorizerV2 } ; const getCorsHeaders = ( ) => { return { 'Access-Control-Allow-Credentials' : true , 'Access-Control-Allow-Headers' : '*' , 'Access-Control-Allow-Origin' : '*' , } ; } ; export const getUsers = async ( event , context ) => { try { await createRESTHandlers ( event . requestContext . accountId ) ; const responseBody = await restHandlers . getUsers ( event , context ) as APIGatewayProxyResult ; return { ... responseBody , headers : getCorsHeaders ( ) , } ; } catch ( err ) { return applicationErrorHandler ( err , logger ) ; } } ;