UNPKG

@opengis/fastify-table

Version:

core-plugins

62 lines (61 loc) 2.57 kB
import path from "node:path"; import { existsSync } from "node:fs"; import { readFile, writeFile } from "node:fs/promises"; import { prefix, metaDir, fetchTimeoutMs, uploadChunkDirectory, } from "./index.js"; import uploadFile from "../file/uploadFile.js"; import applyHook from "../hook/applyHook.js"; export default async function uploadChunk({ host, id, body, offset, end, size, }) { if (!host) { const metaExists = existsSync(path.join(metaDir, `${id}.json`)); if (!metaExists) { return { error: "File not found", code: 404 }; } const meta = JSON.parse(await readFile(path.join(metaDir, `${id}.json`), "utf8")); if (size !== meta.size) { return { error: "Total size mismatch", code: 400 }; } if (offset !== meta.uploaded) { return { error: "Wrong offset", expected: meta.uploaded, code: 409 }; } if (body?.length !== end - offset + 1) { return { error: "Chunk size mismatch", code: 400 }; } // append chunk to existing file await uploadFile(path .join(uploadChunkDirectory, `${id}.${meta.extension}`) .replace(/\\/g, "/"), body); meta.uploaded = end + 1; // update metadata for resumable upload await writeFile(path.join(metaDir, `${id}.json`), JSON.stringify(meta, null, 2)); const finished = meta.uploaded === meta.size; if (finished) { const metaData = { ...meta, uploadDate: new Date().toISOString(), exists: true, finished: true, }; // save metadata const fileBytes = Buffer.from(JSON.stringify(metaData, null, 2)); await writeFile(path.join(metaDir, `${id}.json`), fileBytes); const payload = { uploaded: meta.uploaded, finished }; const hookData = await applyHook("afterChunkedUpload", { id, meta }); return hookData || payload; } return { uploaded: meta.uploaded, finished }; } if (!end || !size) { return { error: "not enough params: offset/end/size", code: 400 }; } const res = await fetch(`${host}/${prefix}/${id}`, { method: "PATCH", headers: { "Content-Range": `bytes ${offset || 0}-${end}/${size}`, }, body, signal: AbortSignal.timeout(fetchTimeoutMs), }).catch((err) => ({ json: () => Promise.resolve({ error: err.toString(), code: 501 }), })); return res.json(); }