import aws , { CloudFront } from 'aws-sdk' ; import fs from 'fs-extra' ; import { log } from './utils' ; export const updateLambda = async ( package_path , accessKeyId , secretAccessKey , lambda_arn , region ) => { log ( `Updating Lambda` ) ; const package_contents = await fs . readFile ( package_path ) ; log . tick ( `Read lambda package. Uploading...` ) ; const lambda = new aws . Lambda ( { accessKeyId , secretAccessKey , region , } ) ; const params = { FunctionName : lambda_arn , ZipFile : package_contents , Publish : true , } ; const response = await lambda . updateFunctionCode ( params ) . promise ( ) ; log ( `💚✔💚 Updated lambda 💛${ response . FunctionName }💛 🖤(version ${ response . Version })🖤` ) ; let state = undefined ; while ( state !== 'Active' ) { await new Promise ( ( resolve ) => setTimeout ( resolve , 5000 ) ) ; const functionResponse = await lambda . getFunction ( { FunctionName : `${ lambda_arn }:${ response . Version }` } ) . promise ( ) ; log ( `Waiting on lambda 💛${ response . FunctionName }💛 status to be Active 🖤currently ${ state }🖤` ) ; state = functionResponse . Configuration ?. State ; } log . tick ( `Lambda is Active` ) ; return response . Version ; } ; export const updateCloudFront = async ( accessKeyId , secretAccessKey , lambda_arn , cf_distribution_id , region , version , routes_for_invalidation = [ '/' ] ) => { const cloudfront = new aws . CloudFront ( { accessKeyId , secretAccessKey , region , } ) ; log ( `Getting CloudFront distribution id 💛${ cf_distribution_id }💛` ) ; const config = await cloudfront . getDistributionConfig ( { Id : cf_distribution_id } ) . promise ( ) ; log ( `💚✔💚 Done.${ config . DistributionConfig ?. Comment ? ` Found distribution comment: '💛${ config . DistributionConfig . Comment }💛'` : '' }` ) ; const LambdaFunctionARN = `${ lambda_arn }:${ version }` ; config . DefaultCacheBehavior . LambdaFunctionAssociations = { Quantity : 1 , Items : [ { LambdaFunctionARN , EventType : 'origin-request' , } , ] , } ; const params = { DistributionConfig : config . DistributionConfig as CloudFront . Types . DistributionConfig , Id : cf_distribution_id , IfMatch : config . ETag , } ; log ( `Updating distribution to 💛${ LambdaFunctionARN }💛` ) ; const update_response = await cloudfront . updateDistribution ( params ) . promise ( ) ; const domains = [ update_response . Distribution ?. DomainName , ... ( config . DistributionConfig ?. Aliases ?. Items || [ ] ) , ] ; log . tick ( `Done.` ) ; log ( `Got response status: 💛${ update_response . Distribution ?. Status }💛
    🖤(CloudFront can take a few minutes to update)🖤` ) ; const num_invalidations = routes_for_invalidation . length ; log ( `Invalidating ${ num_invalidations } route${ num_invalidations === 1 ? '' : 's' }: ${ ( num_invalidations > 4 ? routes_for_invalidation . slice ( 0 , 4 ) . concat ( '...' ) : routes_for_invalidation ) . map ( ( r ) => `💛${ r }💛` ) . join ( ', ' ) }` ) ; try { await cloudfront . createInvalidation ( { DistributionId : cf_distribution_id , InvalidationBatch : { CallerReference : '' + new Date ( ) , Paths : { Quantity : num_invalidations , Items : routes_for_invalidation , } , } , } ) . promise ( ) ; log . tick ( `Done.` ) ; } catch ( e ) { log . cross ( `Invalidation failed. Could be a permissions issue?` ) ; } log ( `Updated the following domain names:
    ${ domains . map ( ( d ) => `💛  ${ d }💛` ) . join ( '\n' ) }
  ` ) ; return `https://${ domains [ domains . length - 1 ] }` ; } ;