@blocklet/images
Version:
support functions for blocklet image validation
77 lines (76 loc) • 4.25 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.validateScreenshots = void 0;
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const image_size_1 = __importDefault(require("image-size"));
const image_type_1 = __importDefault(require("image-type"));
const is_svg_1 = __importDefault(require("is-svg"));
const ordinal_suffix_1 = require("./ordinal-suffix");
const ASPECT_RATIO = 16 / 9;
const ASPECT_RATIO_THRESHOLD = 0.05;
const validateScreenshots = (screenshots, options) => {
const { extractedFilepath, minCount, maxCount, maxSize, minWidth, minHeight } = options;
const errorMessages = [];
const screenshotList = [];
screenshots.forEach((screenshot, index) => {
if (screenshotList.includes(screenshot)) {
errorMessages.push(`The ${(0, ordinal_suffix_1.ordinalSuffix)(index + 1)} screenshot(${screenshot}) is duplicated with the ${(0, ordinal_suffix_1.ordinalSuffix)(screenshotList.indexOf(screenshot) + 1)} screenshot.`);
}
else {
screenshotList.push(screenshot);
}
});
if (minCount && screenshotList.length < minCount) {
errorMessages.unshift(`At least ${minCount} screenshots are required, but just got ${screenshotList.length}.`);
}
else if (maxCount && screenshotList.length > maxCount) {
errorMessages.unshift(`At most ${maxCount} screenshots are supported, but just got ${screenshotList.length}.`);
}
const asyncErrors = {};
screenshotList.forEach((screenshot, index) => {
const screenshotsPath = path_1.default.join(extractedFilepath, 'screenshots', screenshot);
const preMessage = `The ${(0, ordinal_suffix_1.ordinalSuffix)(index + 1)}[${screenshot}] screenshot`;
asyncErrors[screenshot] = [];
if (!fs_1.default.existsSync(screenshotsPath)) {
asyncErrors[screenshot].push(`${preMessage} file not found.`);
return;
}
const screenshotsStats = fs_1.default.statSync(screenshotsPath);
if (maxSize && screenshotsStats.size > maxSize * 1024 * 1024) {
asyncErrors[screenshot].push(`${preMessage} size exceeds ${maxSize} MB, but got ${(screenshotsStats.size / 1024 / 1024).toFixed(2)} MB.`);
}
const isSvgFile = (0, is_svg_1.default)(fs_1.default.readFileSync(screenshotsPath));
if (!isSvgFile) {
const imgType = (0, image_type_1.default)(fs_1.default.readFileSync(screenshotsPath));
if (!imgType) {
asyncErrors[screenshot].push(`${preMessage} is not a valid image file.`);
return;
}
const screenshotExt = path_1.default.extname(screenshotsPath);
if (`.${imgType.ext}` !== screenshotExt && screenshotExt !== '.jpeg') {
asyncErrors[screenshot].push(`${preMessage} extension is not match the real file extension [.${imgType.ext}].`);
}
const imageMeta = (0, image_size_1.default)(screenshotsPath);
const aspectRatio = imageMeta.width / imageMeta.height;
const width = minWidth || (minHeight && Math.round(minHeight * ASPECT_RATIO));
const height = minHeight || (width && Math.round(width / ASPECT_RATIO));
if (imageMeta.width < width || imageMeta.height < height) {
asyncErrors[screenshot].push(`${preMessage} minimum size must be ${width}x${height}, but got ${imageMeta.width}x${imageMeta.height}.`);
}
if (Math.abs(aspectRatio - ASPECT_RATIO) > ASPECT_RATIO_THRESHOLD) {
asyncErrors[screenshot].push(`${preMessage} aspect ratio must be approximately 16:9, but got 16:${parseFloat((imageMeta.height / (imageMeta.width / 16)).toFixed(2))} (${imageMeta.width}x${imageMeta.height}).`);
}
}
});
screenshotList.forEach((screenshot) => {
if (asyncErrors[screenshot].length) {
errorMessages.push(...asyncErrors[screenshot]);
}
});
return errorMessages;
};
exports.validateScreenshots = validateScreenshots;