@datocms/cma-client-node
Version:
NodeJS client for DatoCMS REST Content Management API
87 lines • 3.94 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());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.downloadFile = void 0;
const node_fs_1 = require("node:fs");
const node_path_1 = require("node:path");
const node_url_1 = require("node:url");
const rest_client_utils_1 = require("@datocms/rest-client-utils");
const tmp_promise_1 = require("tmp-promise");
function downloadFile(url, { onProgress, 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 { path: tmpDir, cleanup: deleteTmpDir } = yield (0, tmp_promise_1.dir)({
unsafeCleanup: true,
});
if (controller.signal.aborted) {
yield deleteTmpDir();
throw new rest_client_utils_1.CanceledPromiseError();
}
const res = yield fetchFn(url, {
signal: controller.signal,
redirect: 'follow',
});
if (!res.ok) {
throw new Error(`Failed to download ${url}: ${res.status} ${res.statusText}`);
}
const filePath = (0, node_path_1.join)(tmpDir, (0, node_path_1.basename)(new node_url_1.URL(url).pathname));
if (res.body) {
const fileStream = (0, node_fs_1.createWriteStream)(filePath);
const reader = res.body.getReader();
const contentLengthHeader = res.headers.get('content-length');
const total = contentLengthHeader
? Number.parseInt(contentLengthHeader, 10)
: null;
let receivedLength = 0;
while (true) {
if (controller.signal.aborted) {
throw new rest_client_utils_1.CanceledPromiseError();
}
const { done, value } = yield reader.read();
if (done)
break;
receivedLength += value.length;
fileStream.write(Buffer.from(value));
if (onProgress && total !== null) {
onProgress({
type: 'DOWNLOADING_FILE',
payload: {
url,
progress: Math.round((receivedLength / total) * 100),
},
});
}
}
yield new Promise((resolve, reject) => {
fileStream.on('error', reject);
fileStream.on('finish', () => resolve(undefined));
fileStream.end();
});
}
else {
const arrayBuffer = yield res.arrayBuffer();
yield node_fs_1.promises.writeFile(filePath, Buffer.from(arrayBuffer));
}
if (controller.signal.aborted)
throw new rest_client_utils_1.CanceledPromiseError();
return {
filePath,
deleteFile: deleteTmpDir,
};
}), () => {
controller.abort();
});
}
exports.downloadFile = downloadFile;
//# sourceMappingURL=downloadFile.js.map