import {unlink, write, copyFile} from 'fs'; import sharp from 'sharp'; import headers from './headers.js'; import blur from './preview.js'; const fit = sharp.fit.inside; const withoutEnlargement = true; const optimize = (args, source, dest) => new Promise((res, rej) => { sharp(source).jpeg(args).toFile(dest).then( () => res(dest), () => { copyFile(source, dest, err => { /* istanbul ignore else */ if (err) rej(err); else res(dest); }); } ); }); /** * Create a file after optimizing via `sharp`. * @param {string} source The source JPG/JPEG file to optimize. * @param {string} dest The optimized destination file. * @param {Options} [options] Options to deal with extra computation. * @return {Promise<string>} A promise that resolves with the destination file. */ export default (source, dest, /* istanbul ignore next */ options = {}) => new Promise((res, rej) => { const {maxWidth: width, maxHeight: height, createFiles, preview} = options; const done = () => res(dest); const walkThrough = () => { if (createFiles) writeHeaders(dest).then( () => { if (preview) blur(dest).then(dest => writeHeaders(dest).then(done, rej), rej); else done(); }, rej ); /* istanbul ignore next */ else if (preview) blur(dest).then(done, rej); else done(); }; const writeHeaders = dest => headers(source, dest, options.headers); const args = {progressive: !preview}; if (width || height) { sharp(source) .resize({width, height, fit, withoutEnlargement}) .toFile(`${dest}.resized.jpg`) .then( () => optimize(args, `${dest}.resized.jpg`, dest).then( () => { unlink(`${dest}.resized.jpg`, err => { /* istanbul ignore if */ if (err) rej(err); else walkThrough(); }); }, rej ), rej ) ; } else optimize(args, source, dest).then(walkThrough, rej); });