UNPKG

@datocms/cma-client-node

Version:
78 lines 3.48 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; import { createReadStream, promises } from 'node:fs'; import { Readable } from 'node:stream'; import { CanceledPromiseError, getFetchFn, makeCancelablePromise, } from '@datocms/rest-client-utils'; import mime from 'mime-types'; export function uploadLocalFileToS3(filePath, url, { onProgress, additionalHeaders, fetchFn: customFetchFn } = {}) { const fetchFn = getFetchFn(customFetchFn); const controller = new AbortController(); return makeCancelablePromise(() => __awaiter(this, void 0, void 0, function* () { if (controller.signal.aborted) { throw new CanceledPromiseError(); } const { size: totalLength } = yield promises.stat(filePath); if (controller.signal.aborted) { throw new CanceledPromiseError(); } // Create a readable stream from file let body = Readable.toWeb(createReadStream(filePath)); // Wrap the stream to track progress if needed. if (onProgress) { body = createProgressReadableStream(body, totalLength, onProgress); } const response = yield fetchFn(url, { method: 'PUT', headers: Object.assign(Object.assign({}, (additionalHeaders || {})), { 'Content-Type': mime.lookup(filePath) || 'application/octet-stream', 'Content-Length': `${totalLength}` }), body, // @ts-expect-error - Types are outdated duplex: 'half', signal: controller.signal, redirect: 'follow', }); // Check for non-2xx responses. if (!response.ok) { throw new Error(`Upload of ${filePath} failed with status ${response.status}: ${response.statusText}`); } }), () => { controller.abort(); }); } /** * Wraps a ReadableStream to report upload progress. */ function createProgressReadableStream(stream, totalLength, onProgress) { let uploaded = 0; const reader = stream.getReader(); return new ReadableStream({ pull(controller) { return __awaiter(this, void 0, void 0, function* () { const { done, value } = yield reader.read(); if (done) { controller.close(); return; } if (value) { uploaded += value.length; const percent = uploaded / totalLength; onProgress({ type: 'UPLOADING_FILE', payload: { progress: Math.round(percent * 100) }, }); controller.enqueue(value); } }); }, cancel(reason) { return reader.cancel(reason); }, }); } //# sourceMappingURL=uploadLocalFileToS3.js.map