import { PassThrough } from 'stream' ; import archiver = require ( 'archiver' ) ; import { s3 , ONE_WEEK , Bucket } from '../../../utils/s3' ; import { getMatchingObjects } from './lister' ; const replaceImageUrls = ( html ) : string => { return html . replace ( /https:\/\/i.guim.co.uk\/img\//g , `../media/images/` ) ; } ; export const zip = async ( name , prefixes , options , bucket ) => { const output = new PassThrough ( ) ; const upload = s3 . upload ( { Bucket : bucket . name , Key : `zips/${ name }.zip` , Body : output , ACL : 'public-read' , ContentType : 'application/zip' , CacheControl : `max-age=${ ONE_WEEK }` , } ) . promise ( ) ; const files = await getMatchingObjects ( prefixes , bucket ) ; const archive = archiver ( 'zip' ) ; archive . on ( 'warning' , err => { console . error ( 'Error in attempting to compress' , err ) ; } ) ; archive . pipe ( output ) ; await Promise . all ( files . map ( async ( file ) => { const path = options . removeFromOutputPath ? file . replace ( `${ options . removeFromOutputPath }` , '' ) : file ; console . log ( `fetching file from s3: ${ file }` ) ; const s3response = await s3 . getObject ( { Bucket : bucket . name , Key : file } ) . promise ( ) ; if ( s3response . Body == null ) return false ; const zipPath = options . replaceImageSize ? path . replace ( `/${ options . replaceImageSize }/` , '/images/' ) : path ; const shouldReplaceImagePath = options . replaceImagePathInDataBundle && file . indexOf ( 'html/assets/' ) == - 1 ; let bufferedData ; if ( shouldReplaceImagePath ) { const articleHtml = s3response . Body . toString ( 'utf-8' ) ; const articleWithRelativeImgUrl = replaceImageUrls ( articleHtml ) ; bufferedData = Buffer . from ( articleWithRelativeImgUrl ) ; } else { bufferedData = s3response . Body as Buffer ; } archive . append ( bufferedData , { name : zipPath , } ) ; } ) ) ; console . log ( `Finished adding to zip ${ name }.zip, finalizing.` ) ; await archive . finalize ( ) ; return upload ; } ;