76 lines
1.7 KiB
JavaScript
76 lines
1.7 KiB
JavaScript
const fs = require("fs");
|
|
const path = require("path");
|
|
|
|
const MIME_TYPES = {
|
|
pdf: "application/pdf",
|
|
csv: "text/csv",
|
|
json: "application/json",
|
|
html: "text/html",
|
|
txt: "text/plain",
|
|
md: "text/markdown",
|
|
png: "image/png",
|
|
jpg: "image/jpeg",
|
|
jpeg: "image/jpeg",
|
|
svg: "image/svg+xml",
|
|
zip: "application/zip",
|
|
};
|
|
|
|
function safeFilename(filename) {
|
|
return String(filename || "").replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
}
|
|
|
|
function fileExtensionMismatch(filepath, ext) {
|
|
let fd;
|
|
try {
|
|
const head = Buffer.alloc(8);
|
|
fd = fs.openSync(filepath, "r");
|
|
fs.readSync(fd, head, 0, head.length, 0);
|
|
|
|
if (ext === "pdf" && !head.subarray(0, 5).equals(Buffer.from("%PDF-"))) {
|
|
return "expected PDF bytes";
|
|
}
|
|
if (
|
|
ext === "png" &&
|
|
!head.equals(
|
|
Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]),
|
|
)
|
|
) {
|
|
return "expected PNG bytes";
|
|
}
|
|
if (
|
|
(ext === "jpg" || ext === "jpeg") &&
|
|
!(head[0] === 0xff && head[1] === 0xd8 && head[2] === 0xff)
|
|
) {
|
|
return "expected JPEG bytes";
|
|
}
|
|
} catch {
|
|
return null;
|
|
} finally {
|
|
if (fd !== undefined) {
|
|
try {
|
|
fs.closeSync(fd);
|
|
} catch {}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
function readManifest(deliverablesDir) {
|
|
const manifest = path.join(deliverablesDir, ".manifest.json");
|
|
if (!fs.existsSync(manifest)) return [];
|
|
return JSON.parse(fs.readFileSync(manifest, "utf8"));
|
|
}
|
|
|
|
function writeManifest(deliverablesDir, entries) {
|
|
const manifest = path.join(deliverablesDir, ".manifest.json");
|
|
fs.writeFileSync(manifest, JSON.stringify(entries, null, 2), "utf8");
|
|
}
|
|
|
|
module.exports = {
|
|
MIME_TYPES,
|
|
fileExtensionMismatch,
|
|
readManifest,
|
|
safeFilename,
|
|
writeManifest,
|
|
};
|