import Agenda , { Job } from "agenda" ; import { AWS_CLOUDFRONT_DISTRIBUTION_ID } from "../util/secrets" ; import AWS from "aws-sdk" ; import { CreateInvalidationRequest } from "aws-sdk/clients/cloudfront" ; import { getAllApiKeysByOrganization } from "../services/apiKey" ; const INVALIDATE_JOB_NAME = "fireInvalidate" ; type InvalidateJob = Job < { url : string ; } > ; let agenda ; export default function ( ag ) { agenda = ag ; agenda . define ( INVALIDATE_JOB_NAME , async ( job ) => { if ( ! job . attrs . data ) return ; const { url } = job . attrs . data ; if ( ! url ) return ; if ( ! AWS_CLOUDFRONT_DISTRIBUTION_ID ) return ; const cloudfront = new AWS . CloudFront ( ) ; const params = { DistributionId : AWS_CLOUDFRONT_DISTRIBUTION_ID , InvalidationBatch : { CallerReference : "" + Date . now ( ) , Paths : { Quantity : 1 , Items : [ url ] , } , } , } ; await new Promise < void > ( ( resolve , reject ) => { cloudfront . createInvalidation ( params , function ( err ) { if ( err ) { console . error ( "Error invalidating CDN" , url , err ) ; reject ( err ) ; } else { resolve ( ) ; } } ) ; } ) ; } ) ; } export async function queueCDNInvalidate ( organization , getUrl ) { if ( ! AWS_CLOUDFRONT_DISTRIBUTION_ID ) return ; const apiKeys = await getAllApiKeysByOrganization ( organization ) ; if ( ! apiKeys || ! apiKeys . length ) return ; for ( const k of apiKeys ) { const url = getUrl ( k . key ) ; const job = agenda . create ( INVALIDATE_JOB_NAME , { url , } ) as InvalidateJob ; job . unique ( { url } ) ; job . schedule ( new Date ( ) ) ; await job . save ( ) ; } }