@datocms/cma-client-node
Version:
NodeJS client for DatoCMS REST Content Management API
85 lines • 3.91 kB
JavaScript
;
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());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.uploadLocalFileToS3 = void 0;
const node_fs_1 = require("node:fs");
const node_stream_1 = require("node:stream");
const rest_client_utils_1 = require("@datocms/rest-client-utils");
const mime_types_1 = __importDefault(require("mime-types"));
function uploadLocalFileToS3(filePath, url, { onProgress, additionalHeaders, fetchFn: customFetchFn } = {}) {
const fetchFn = (0, rest_client_utils_1.getFetchFn)(customFetchFn);
const controller = new AbortController();
return (0, rest_client_utils_1.makeCancelablePromise)(() => __awaiter(this, void 0, void 0, function* () {
if (controller.signal.aborted) {
throw new rest_client_utils_1.CanceledPromiseError();
}
const { size: totalLength } = yield node_fs_1.promises.stat(filePath);
if (controller.signal.aborted) {
throw new rest_client_utils_1.CanceledPromiseError();
}
// Create a readable stream from file
let body = node_stream_1.Readable.toWeb((0, node_fs_1.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_types_1.default.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();
});
}
exports.uploadLocalFileToS3 = uploadLocalFileToS3;
/**
* 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