Refactor code structure for improved readability and maintainability
Test Suite / test (24.15.0) (push) Has been cancelled

This commit is contained in:
Nils-Johan Gynther
2026-05-06 07:37:59 +02:00
parent e4f201ea36
commit 969dafdbc6
273 changed files with 11357 additions and 39 deletions
+64
View File
@@ -0,0 +1,64 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.downloadAndOptimizeImage = downloadAndOptimizeImage;
const fs = require("fs");
const path = require("path");
const sharp = require("sharp");
const uuid_1 = require("uuid");
const BLOCKED_HOSTNAMES = /^(localhost|127\.|10\.|172\.(1[6-9]|2\d|3[01])\.|192\.168\.|0\.0\.0\.0|::1|fc00:|fe80:)/i;
async function downloadAndOptimizeImage(sourceUrl, destDir) {
const raw = sourceUrl.trim();
const protocolNormalized = raw.startsWith('//') ? `https:${raw}` : raw;
let parsedUrl;
try {
parsedUrl = new URL(protocolNormalized);
}
catch {
throw new Error('Ogiltig bild-URL');
}
if (parsedUrl.protocol !== 'https:') {
throw new Error('Bild-URL måste använda https://');
}
const hostname = parsedUrl.hostname;
if (BLOCKED_HOSTNAMES.test(hostname)) {
throw new Error('Bild-URL pekar på ett blockerat nätverk');
}
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 10_000);
let response;
try {
response = await fetch(parsedUrl.toString(), {
signal: controller.signal,
headers: { 'User-Agent': 'Mozilla/5.0 (compatible; RecipeApp/1.0)' },
});
}
finally {
clearTimeout(timeout);
}
if (!response.ok) {
throw new Error(`HTTP ${response.status} vid nedladdning av bild`);
}
const contentType = response.headers.get('content-type') ?? '';
if (!contentType.startsWith('image/')) {
throw new Error(`Ogiltig content-type: ${contentType}`);
}
const arrayBuffer = await response.arrayBuffer();
if (arrayBuffer.byteLength > 5 * 1024 * 1024) {
throw new Error('Bilden är för stor (max 5 MB)');
}
const imageBuffer = Buffer.from(arrayBuffer);
if (!fs.existsSync(destDir)) {
fs.mkdirSync(destDir, { recursive: true });
}
const filename = `${(0, uuid_1.v4)()}.jpg`;
const outputPath = path.join(destDir, filename);
await sharp(imageBuffer)
.resize(1200, 800, {
fit: 'inside',
withoutEnlargement: true,
})
.jpeg({ quality: 80 })
.toFile(outputPath);
return `/images/${filename}`;
}
//# sourceMappingURL=download-image.js.map