eas-cli
Version:
EAS command line tool
101 lines (100 loc) • 4.38 kB
JavaScript
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;
}
}
;