UNPKG

eas-cli

Version:
101 lines (100 loc) 4.38 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.uploadWithPresignedPostWithRetryAsync = exports.uploadAccountScopedFileAtPathToGCSAsync = exports.uploadFileAtPathToGCSAsync = void 0; const tslib_1 = require("tslib"); const form_data_1 = tslib_1.__importDefault(require("form-data")); const fs_extra_1 = tslib_1.__importDefault(require("fs-extra")); const promise_retry_1 = tslib_1.__importDefault(require("promise-retry")); const fetch_1 = tslib_1.__importDefault(require("./fetch")); const UploadSessionMutation_1 = require("./graphql/mutations/UploadSessionMutation"); async function uploadFileAtPathToGCSAsync(graphqlClient, type, path, handleProgressEvent = () => { }) { const signedUrl = await UploadSessionMutation_1.UploadSessionMutation.createUploadSessionAsync(graphqlClient, type); await uploadWithSignedUrlWithProgressAsync(path, signedUrl, handleProgressEvent); return signedUrl.bucketKey; } exports.uploadFileAtPathToGCSAsync = uploadFileAtPathToGCSAsync; async function uploadAccountScopedFileAtPathToGCSAsync(graphqlClient, { type, accountId, path, handleProgressEvent, }) { const signedUrl = await UploadSessionMutation_1.UploadSessionMutation.createAccountScopedUploadSessionAsync(graphqlClient, { type, accountID: accountId }); await uploadWithSignedUrlWithProgressAsync(path, signedUrl, handleProgressEvent); return signedUrl.bucketKey; } exports.uploadAccountScopedFileAtPathToGCSAsync = uploadAccountScopedFileAtPathToGCSAsync; async function uploadWithPresignedPostWithRetryAsync(file, presignedPost, onAssetUploadBegin) { return await (0, promise_retry_1.default)(async (retry) => { // retry fetch errors (usually connection or DNS errors) let response; try { onAssetUploadBegin(); response = await uploadWithPresignedPostAsync(file, presignedPost); } catch (e) { return retry(e); } // retry 408, 429, 5xx as suggested by google if (response.status === 408 || response.status === 429 || (response.status >= 500 && response.status <= 599)) { return retry(new Error(`Presigned upload responded with a ${response.status} status`)); } // don't retry other errors if (!response.ok) { throw new Error(`Presigned upload responded with a ${response.status} status`); } return response; }, // retry parameters match google suggested defaults: https://cloud.google.com/storage/docs/retry-strategy#node.js { retries: 3, factor: 2, }); } exports.uploadWithPresignedPostWithRetryAsync = uploadWithPresignedPostWithRetryAsync; async function uploadWithPresignedPostAsync(file, presignedPost) { const fileStat = await fs_extra_1.default.stat(file); const fileSize = fileStat.size; const form = new form_data_1.default(); for (const [fieldKey, fieldValue] of Object.entries(presignedPost.fields)) { form.append(fieldKey, fieldValue); } form.append('file', fs_extra_1.default.createReadStream(file), { knownLength: fileSize }); const formHeaders = form.getHeaders(); return await (0, fetch_1.default)(presignedPost.url, { method: 'POST', body: form, headers: { ...formHeaders, }, }); } async function uploadWithSignedUrlWithProgressAsync(file, signedUrl, handleProgressEvent) { const fileStat = await fs_extra_1.default.stat(file); const fileSize = fileStat.size; const readStream = fs_extra_1.default.createReadStream(file); const uploadPromise = (0, fetch_1.default)(signedUrl.url, { method: 'PUT', body: readStream, headers: { ...signedUrl.headers, }, }); let currentSize = 0; readStream.addListener('data', (chunk) => { currentSize += Buffer.byteLength(chunk); handleProgressEvent({ progress: { total: fileSize, percent: currentSize / fileSize, transferred: currentSize, }, }); }); try { const response = await uploadPromise; handleProgressEvent({ isComplete: true }); return response; } catch (error) { handleProgressEvent({ isComplete: true, error }); throw error; } }