@opengis/fastify-table
Version:
core-plugins
62 lines (61 loc) • 2.57 kB
JavaScript
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();
}