Optimize CMS images during builds
This commit is contained in:
@@ -2,6 +2,7 @@ import Ajv2020 from 'ajv/dist/2020.js';
|
||||
import addFormats from 'ajv-formats';
|
||||
import { readdir, readFile, stat } from 'node:fs/promises';
|
||||
import { extname, join, relative, sep } from 'node:path';
|
||||
import { allowedUploadExtensions, maxSourceImageBytes } from './image-policy.mjs';
|
||||
|
||||
const readJson = async (path) => JSON.parse(await readFile(path, 'utf8'));
|
||||
const ajv = new Ajv2020({ allErrors: true, strict: true });
|
||||
@@ -36,7 +37,6 @@ async function filesUnder(directory) {
|
||||
}
|
||||
|
||||
const uploadRoot = join('public', 'images', 'uploads');
|
||||
const allowedUploadExtensions = new Set(['.jpg', '.jpeg', '.png', '.webp', '.avif']);
|
||||
const ascii = (value) => Buffer.from(value, 'ascii');
|
||||
const startsWith = (buffer, signature) => buffer.subarray(0, signature.length).equals(signature);
|
||||
const isRasterForExtension = (buffer, extension) => {
|
||||
@@ -55,11 +55,10 @@ const isRasterForExtension = (buffer, extension) => {
|
||||
for (const path of await filesUnder('public/images')) {
|
||||
const imagePath = relative('public/images', path).split(sep).join('/');
|
||||
const info = await stat(path);
|
||||
if (info.size > 500 * 1024) throw new Error(`Image exceeds the 500 KiB pilot limit: ${imagePath}`);
|
||||
|
||||
const uploadPath = relative(uploadRoot, path);
|
||||
const isUpload = uploadPath !== '..' && !uploadPath.startsWith(`..${sep}`);
|
||||
if (!isUpload) continue;
|
||||
if (info.size > maxSourceImageBytes) throw new Error(`CMS image exceeds the 25 MiB source safety limit: ${imagePath}`);
|
||||
if (uploadPath.includes(sep)) throw new Error(`Nested CMS media paths are not allowed: ${imagePath}`);
|
||||
const extension = extname(uploadPath).toLowerCase();
|
||||
if (!allowedUploadExtensions.has(extension)) throw new Error(`CMS media is not an allowed raster extension: ${imagePath}`);
|
||||
|
||||
Reference in New Issue
Block a user