diff options
Diffstat (limited to 'lib/upload.ts')
| -rw-r--r-- | lib/upload.ts | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/lib/upload.ts b/lib/upload.ts new file mode 100644 index 00000000..0fb31ea5 --- /dev/null +++ b/lib/upload.ts @@ -0,0 +1,70 @@ +import { fileTypeFromStream } from "file-type"; +import pump from "pump"; +import Clone from "readable-stream-clone"; +import fs from "fs"; +import path from "path"; +import { pipeline } from "stream"; +import { g, s, db } from "$lib/db"; +import { bail, fail } from "$lib/utils"; +import crypto from "crypto"; +import { err } from "$lib/logging"; + +async function getSha256Hash(stream) { + return new Promise((resolve, reject) => { + const hash = crypto.createHash("sha256"); + stream.pipe(hash); + + let hashValue; + hash.on("data", (data) => { + hashValue = data.toString("hex"); + }); + + hash.on("end", () => { + resolve(hashValue); + }); + + hash.on("error", reject); + }); +} + +export default async (req, res) => { + try { + let { + params: { type }, + } = req; + + let width = type === "banner" ? 1920 : 240; + + let data = await req.file(); + let s1 = new Clone(data.file); + let s2 = new Clone(data.file); + + let [format, ext] = (await fileTypeFromStream(s1)).mime.split("/"); + + if (format !== "image" && !["jpg", "jpeg", "png"].includes(ext)) + fail("unsupported file type"); + + let processedBuffer = await streamToBuffer(s2.pipe(t)); + let hash = crypto + .createHash("sha256") + .update(processedBuffer) + .digest("hex"); + + let filePath = `/home/bun/app/data/uploads/${hash}.webp`; + fs.writeFileSync(filePath, processedBuffer); + + res.send({ hash }); + } catch (e) { + err("problem uploading", e.message); + bail(res, e.message); + } +}; + +function streamToBuffer(stream) { + return new Promise((resolve, reject) => { + const chunks = []; + stream.on("data", (chunk) => chunks.push(chunk)); + stream.on("end", () => resolve(Buffer.concat(chunks))); + stream.on("error", reject); + }); +} |
