box-ui-elements-mlh
Version:
394 lines (323 loc) • 11.7 kB
JavaScript
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
/**
*
* @file Utility functions for uploads
* @author Box
*/
import getProp from 'lodash/get';
import Browser from './Browser';
var DEFAULT_API_OPTIONS = {};
/**
* Returns true if file contains API options
*
* @param {UploadFile | UploadFileWithAPIOptions} item
* @returns {boolean}
*/
function doesFileContainAPIOptions(file) {
// $FlowFixMe UploadFileWithAPIOptions has `file` and `options` properties
return !!(file.options && file.file);
}
/**
* Returns true if item contains API options
*
* @param {DataTransferItem | UploadDataTransferItemWithAPIOptions} item
* @returns {boolean}
*/
function doesDataTransferItemContainAPIOptions(item) {
// $FlowFixMe UploadDataTransferItemWithAPIOptions has `item` and `options` properties
return !!(item.options && item.item);
}
/**
* Converts UploadFile or UploadFileWithAPIOptions to UploadFile
*
* @param {UploadFile | UploadFileWithAPIOptions} file
* @returns {UploadFile}
*/
function getFile(file) {
if (doesFileContainAPIOptions(file)) {
return file.file;
}
return file;
}
/**
* Converts DataTransferItem or UploadDataTransferItemWithAPIOptions to DataTransferItem
*
* @param {DataTransferItem | UploadDataTransferItemWithAPIOptions} item
* @returns {DataTransferItem}
*/
function getDataTransferItem(item) {
if (doesDataTransferItemContainAPIOptions(item)) {
return item.item;
}
return item;
}
/**
* Get API Options from file
*
* @param {UploadFile | UploadFileWithAPIOptions} file
* @returns {UploadItemAPIOptions}
*/
function getFileAPIOptions(file) {
if (doesFileContainAPIOptions(file)) {
return file.options || DEFAULT_API_OPTIONS;
}
return DEFAULT_API_OPTIONS;
}
/**
* Get API Options from item
*
* @param {DataTransferItem | UploadDataTransferItemWithAPIOptions} item
* @returns {UploadItemAPIOptions}
*/
function getDataTransferItemAPIOptions(item) {
if (doesDataTransferItemContainAPIOptions(item)) {
return item.options || DEFAULT_API_OPTIONS;
}
return DEFAULT_API_OPTIONS;
}
/**
* Returns true if the given object is a Date instance encoding a valid date
* (i.e. new Date('this is not a timestamp') should return false).
*
* Code adapted from
* http://stackoverflow.com/questions/1353684/detecting-an-invalid-date-date-instance-in-javascript
*
* @param {Date} date
* @return {boolean}
*/
function isValidDateObject(date) {
return Object.prototype.toString.call(date) === '[object Date]' && !Number.isNaN(date.getTime());
}
/**
* Remove milliseconds from date time string
*
* @param {Date} date
* @return {string}
*/
function toISOStringNoMS(date) {
return date.toISOString().replace(/\.[0-9]{3}/, '');
}
/**
* Returns the file's last modified date as an ISO string with no MS component (e.g.
* '2017-04-18T17:14:27Z'), or null if no such date can be extracted from the file object.
* (Nothing on the Internet guarantees that the file object has this info.)
*
* @param {UploadFile} file
* @return {?string}
*/
function getFileLastModifiedAsISONoMSIfPossible(file) {
// The compatibility chart at https://developer.mozilla.org/en-US/docs/Web/API/File/lastModified#Browser_compatibility
// is not up to date as of 12-13-2018. Edge & ie11 do not support lastModified, but support lastModifiedDate.
var lastModified = file.lastModified || file.lastModifiedDate;
if (lastModified && (typeof lastModified === 'string' || typeof lastModified === 'number' || lastModified instanceof Date)) {
var lastModifiedDate = new Date(lastModified);
if (isValidDateObject(lastModifiedDate)) {
return toISOStringNoMS(lastModifiedDate);
}
}
return null;
}
/**
* If maybeJson is valid JSON string, return the result of calling JSON.parse
* on it. Otherwise, return null.
*
* @param {string} maybeJson
* @return {?Object}
*/
function tryParseJson(maybeJson) {
try {
return JSON.parse(maybeJson);
} catch (e) {
return null;
}
}
/**
* Get bounded exponential backoff retry delay
*
* @param {number} initialRetryDelay
* @param {number} maxRetryDelay
* @param {number} retryNum - Current retry number (first retry will have value of 0).
* @return {number}
*/
function getBoundedExpBackoffRetryDelay(initialRetryDelay, maxRetryDelay, retryNum) {
var delay = initialRetryDelay * Math.pow(retryNum, 2);
return delay > maxRetryDelay ? maxRetryDelay : delay;
}
/**
* Get entry from dataTransferItem
*
* @param {DataTransferItem} item
* @returns {FileSystemFileEntry}
*/
function getEntryFromDataTransferItem(item) {
var entry = // $FlowFixMe
item.webkitGetAsEntry || item.mozGetAsEntry || item.getAsEntry;
return entry.call(item);
}
/**
* Check if a dataTransferItem is a folder
*
* @param {UploadDataTransferItemWithAPIOptions | DataTransferItem} itemData
* @returns {boolean}
*/
function isDataTransferItemAFolder(itemData) {
var item = getDataTransferItem(itemData);
var entry = getEntryFromDataTransferItem(item);
if (!entry) {
return false;
}
return entry.isDirectory;
}
/**
* Check if a dataTransfer item is a macOS "package file"
* @see https://en.wikipedia.org/wiki/Package_(macOS)
*
* @returns {boolean}
*/
function isDataTransferItemAPackage(itemData) {
var item = getDataTransferItem(itemData);
var isDirectory = isDataTransferItemAFolder(item);
return isDirectory && item.type === 'application/zip' && item.kind === 'file';
}
/**
* Get file from FileSystemFileEntry
*
* @param {FileSystemFileEntry} entry
* @returns {Promise<UploadFile>}
*/
function getFileFromEntry(entry) {
return new Promise(function (resolve) {
entry.file(function (file) {
resolve(file);
});
});
}
/**
* Get file from DataTransferItem or UploadDataTransferItemWithAPIOptions
*
* @param {UploadDataTransferItemWithAPIOptions | DataTransferItem} itemData
* @returns {Promise<UploadFile | UploadFileWithAPIOptions | null>}
*/
function getFileFromDataTransferItem(_x) {
return _getFileFromDataTransferItem.apply(this, arguments);
}
/**
* Get file from DataTransferItem or UploadDataTransferItemWithAPIOptions
* Uses `entry`'s `getAsFile` method for retrieving package information as a single file.
* @see https://en.wikipedia.org/wiki/Package_(macOS)
*
* @param {UploadDataTransferItemWithAPIOptions | DataTransferItem} itemData
* @returns {?UploadFile | ?UploadFileWithAPIOptions | null}
*/
function _getFileFromDataTransferItem() {
_getFileFromDataTransferItem = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(itemData) {
var item, entry, file;
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
item = getDataTransferItem(itemData);
entry = getEntryFromDataTransferItem(item);
if (entry) {
_context.next = 4;
break;
}
return _context.abrupt("return", null);
case 4:
_context.next = 6;
return getFileFromEntry(entry);
case 6:
file = _context.sent;
if (!doesDataTransferItemContainAPIOptions(itemData)) {
_context.next = 9;
break;
}
return _context.abrupt("return", {
file: file,
options: getDataTransferItemAPIOptions(itemData)
});
case 9:
return _context.abrupt("return", file);
case 10:
case "end":
return _context.stop();
}
}
}, _callee);
}));
return _getFileFromDataTransferItem.apply(this, arguments);
}
function getPackageFileFromDataTransferItem(itemData) {
var item = getDataTransferItem(itemData);
var entry = getEntryFromDataTransferItem(item);
if (!entry) {
return null;
}
var itemFile = item.getAsFile();
if (doesDataTransferItemContainAPIOptions(itemData)) {
return {
file: itemFile,
options: getDataTransferItemAPIOptions(itemData)
};
}
return itemFile;
}
/**
* Generates file id based on file properties
*
* When folderId or uploadInitTimestamp is missing from file options, file name is returned as file id.
* Otherwise, fileName_folderId_uploadInitTimestamp is used as file id.
*
* @param {UploadFileWithAPIOptions | UploadFile} file
* @param {string} rootFolderId
* @returns {string}
*/
function getFileId(file, rootFolderId) {
if (!doesFileContainAPIOptions(file)) {
return file.name;
}
var fileWithOptions = file;
var folderId = getProp(fileWithOptions, 'options.folderId', rootFolderId);
var uploadInitTimestamp = getProp(fileWithOptions, 'options.uploadInitTimestamp', Date.now());
var fileName = fileWithOptions.file.webkitRelativePath || fileWithOptions.file.name;
return "".concat(fileName, "_").concat(folderId, "_").concat(uploadInitTimestamp);
}
/**
* Generates item id based on item properties
*
* When item options including folderId or uploadInitTimestamp are missing, item name is returned as item id.
* Otherwise, item properties are used as item id.
* E.g., folder1_0_123124124
*
* @param {DataTransferItem | UploadDataTransferItemWithAPIOptions} itemData
* @param {string} rootFolderId
* @returns {string}
*/
function getDataTransferItemId(itemData, rootFolderId) {
var item = getDataTransferItem(itemData);
var _getEntryFromDataTran = getEntryFromDataTransferItem(item),
name = _getEntryFromDataTran.name;
if (!doesDataTransferItemContainAPIOptions(itemData)) {
return name;
}
var _getDataTransferItemA = getDataTransferItemAPIOptions(itemData),
_getDataTransferItemA2 = _getDataTransferItemA.folderId,
folderId = _getDataTransferItemA2 === void 0 ? rootFolderId : _getDataTransferItemA2,
_getDataTransferItemA3 = _getDataTransferItemA.uploadInitTimestamp,
uploadInitTimestamp = _getDataTransferItemA3 === void 0 ? Date.now() : _getDataTransferItemA3;
return "".concat(name, "_").concat(folderId, "_").concat(uploadInitTimestamp);
}
/**
* Multiput uploads require the use of crypto, which is only supported in secure contexts.
* Multiput uploads is not supported on mobile iOS Safari.
*/
function isMultiputSupported() {
var cryptoObj = window.crypto || window.msCrypto;
if (Browser.isMobileSafari() || Browser.isMobileChromeOniOS()) {
return false;
}
return window.location.protocol === 'https:' && cryptoObj && cryptoObj.subtle;
}
export { DEFAULT_API_OPTIONS, doesDataTransferItemContainAPIOptions, doesFileContainAPIOptions, getBoundedExpBackoffRetryDelay, getDataTransferItem, getDataTransferItemAPIOptions, getDataTransferItemId, getEntryFromDataTransferItem, getFile, getFileAPIOptions, getFileFromDataTransferItem, getPackageFileFromDataTransferItem, getFileFromEntry, getFileId, getFileLastModifiedAsISONoMSIfPossible, isDataTransferItemAFolder, isDataTransferItemAPackage, isMultiputSupported, toISOStringNoMS, tryParseJson };
//# sourceMappingURL=uploads.js.map