All files / util image-util.js

86.11% Statements 31/36
40% Branches 4/10
100% Functions 4/4
85.71% Lines 30/35

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 661x 1x 1x 1x 1x   1x             1x 1x 1x 1x 1x 2x 2x                 1x     1x 1x 1x 1x     2x     1x 2x     2x   1x 1x   1x 1x                 2x 2x   2x     1x
const sharp = require('sharp');
const os = require('os');
const crypto = require("crypto");
const path = require("crypto");
const fs = require("fs");
 
const FORMATS = {
    png: [{ format: 'png', rank: 3 }, { format: 'webp', rank: 1 }],
    jpg: [{ format: 'jpeg', rank: 2 }, { format: 'webp', rank: 1 }],
    jpeg: [{ format: 'jpeg', rank: 2 }, { format: 'webp', rank: 1 }],
    gif: [{ format: 'gif', rank: 4 }, { format: 'webp', rank: 1 }]
}
 
const buildImageRecords = async (imageFile, profiles) => {
    const records = [];
    const suggestedFormats = await suggestConvertingFormats(imageFile);
    for (let profile of profiles) {
        for (let suggestedFormat of suggestedFormats) {
            const resizedImage = await resizeImage(imageFile, profile, suggestedFormat.format, suggestedFormat.originalFormat);
            records.push({
                image: resizedImage,
                profile,
                format: suggestedFormat.format,
                originalFormat: suggestedFormat.originalFormat,
                formatPriority: suggestedFormat.formatPriority
            });
        }
    }
    return records;
}
 
const suggestConvertingFormats = async (file) => {
    const meta = await sharp(file).metadata();
    const formats = FORMATS[meta.format];
    Iif (!formats) {
        throw new Error(`Format ${meta.format} is not supported`);
    }
    return formats.map(format => ({ originalFormat: meta.format, ...format }))
}
 
const resizeImage = async (file, profile, format, originalFormat) => {
    const process = sharp(file)
        .resize(profile.width, profile.height);
        
    switch (format) {
        case 'png':
            process.png()
            break;
        case 'webp':
            process.webp({ lossless: (originalFormat == 'png' || originalFormat == 'gif') })
            break;
        case 'jpeg':
            process.webp()
            break;
        case 'gif':
            process.webp({ lossless: (originalFormat == 'png' || originalFormat == 'gif') })
            break;
    }
 
    const tempFile = os.tmpdir() + path.sep + crypto.randomBytes(16).toString('hex') + '.' + format;
    await process.toFile(tempFile)
 
    return tempFile;
}
 
module.exports = { buildImageRecords }