UNPKG

upload-js

Version:

File Upload Library — Upload.js gives developers AJAX multipart file uploading via XHR 🚀 Comes with Cloud Storage 🌐

1,192 lines (969 loc) 42.2 kB
module.exports = /******/ (function() { // webpackBootstrap /******/ "use strict"; /******/ var __webpack_modules__ = ({ /***/ "./src/index.ts": /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { // ESM COMPAT FLAG __webpack_require__.r(__webpack_exports__); // EXPORTS __webpack_require__.d(__webpack_exports__, { "Upload": function() { return /* reexport */ Upload; }, "UploadApiError": function() { return /* reexport */ UploadApiError; } }); ;// CONCATENATED MODULE: external "@upload-io/upload-api-client-upload-js" var upload_api_client_upload_js_namespaceObject = require("@upload-io/upload-api-client-upload-js");; ;// CONCATENATED MODULE: ./src/Mutex.ts /** * A lightweight mutex. (Other libraries contain too many features and we want to keep the size upload-js down). * * Characteristics: * - Non-reentrant. * - Unfair. (Multiple callers awaiting 'acquire' will be granted the mutex in no order.) * - When calling `safe` consecutively with no 'awaits' in-between, the current context will synchronously acquire * the mutex every time. */ function _call(body, then, direct) { if (direct) { return then ? then(body()) : body(); } try { var result = Promise.resolve(body()); return then ? result.then(then) : result; } catch (e) { return Promise.reject(e); } } function _rethrow(thrown, value) { if (thrown) throw value; return value; } function _finallyRethrows(body, finalizer) { try { var result = body(); } catch (e) { return finalizer(true, e); } if (result && result.then) { return result.then(finalizer.bind(null, false), finalizer.bind(null, true)); } return finalizer(false, result); } function _empty() {} function _awaitIgnored(value, direct) { if (!direct) { return value && value.then ? value.then(_empty) : Promise.resolve(); } } function _settle(pact, state, value) { if (!pact.s) { if (value instanceof _Pact) { if (value.s) { if (state & 1) { state = value.s; } value = value.v; } else { value.o = _settle.bind(null, pact, state); return; } } if (value && value.then) { value.then(_settle.bind(null, pact, state), _settle.bind(null, pact, 2)); return; } pact.s = state; pact.v = value; var observer = pact.o; if (observer) { observer(pact); } } } var _Pact = /*#__PURE__*/function () { function _Pact() {} _Pact.prototype.then = function (onFulfilled, onRejected) { var result = new _Pact(); var state = this.s; if (state) { var callback = state & 1 ? onFulfilled : onRejected; if (callback) { try { _settle(result, 1, callback(this.v)); } catch (e) { _settle(result, 2, e); } return result; } else { return this; } } this.o = function (_this) { try { var value = _this.v; if (_this.s & 1) { _settle(result, 1, onFulfilled ? onFulfilled(value) : value); } else if (onRejected) { _settle(result, 1, onRejected(value)); } else { _settle(result, 2, value); } } catch (e) { _settle(result, 2, e); } }; return result; }; return _Pact; }(); function _isSettledPact(thenable) { return thenable instanceof _Pact && thenable.s & 1; } function _for(test, update, body) { var stage; for (;;) { var shouldContinue = test(); if (_isSettledPact(shouldContinue)) { shouldContinue = shouldContinue.v; } if (!shouldContinue) { return result; } if (shouldContinue.then) { stage = 0; break; } var result = body(); if (result && result.then) { if (_isSettledPact(result)) { result = result.s; } else { stage = 1; break; } } if (update) { var updateValue = update(); if (updateValue && updateValue.then && !_isSettledPact(updateValue)) { stage = 2; break; } } } var pact = new _Pact(); var reject = _settle.bind(null, pact, 2); (stage === 0 ? shouldContinue.then(_resumeAfterTest) : stage === 1 ? result.then(_resumeAfterBody) : updateValue.then(_resumeAfterUpdate)).then(void 0, reject); return pact; function _resumeAfterBody(value) { result = value; do { if (update) { updateValue = update(); if (updateValue && updateValue.then && !_isSettledPact(updateValue)) { updateValue.then(_resumeAfterUpdate).then(void 0, reject); return; } } shouldContinue = test(); if (!shouldContinue || _isSettledPact(shouldContinue) && !shouldContinue.v) { _settle(pact, 1, result); return; } if (shouldContinue.then) { shouldContinue.then(_resumeAfterTest).then(void 0, reject); return; } result = body(); if (_isSettledPact(result)) { result = result.v; } } while (!result || !result.then); result.then(_resumeAfterBody).then(void 0, reject); } function _resumeAfterTest(shouldContinue) { if (shouldContinue) { result = body(); if (result && result.then) { result.then(_resumeAfterBody).then(void 0, reject); } else { _resumeAfterBody(result); } } else { _settle(pact, 1, result); } } function _resumeAfterUpdate() { if (shouldContinue = test()) { if (shouldContinue.then) { shouldContinue.then(_resumeAfterTest).then(void 0, reject); } else { _resumeAfterTest(shouldContinue); } } else { _settle(pact, 1, result); } } } function _continue(value, then) { return value && value.then ? value.then(then) : then(value); } function _async(f) { return function () { for (var args = [], i = 0; i < arguments.length; i++) { args[i] = arguments[i]; } try { return Promise.resolve(f.apply(this, args)); } catch (e) { return Promise.reject(e); } }; } function Mutex() { var mutex; var resolver; var safe = function safe(callback) { return _call(acquire, function () { return _finallyRethrows(callback, function (_wasThrown, _result) { release(); return _rethrow(_wasThrown, _result); }); }); }; var acquire = _async(function () { // Loop necessary for when multiple calls are made to 'acquire' before a 'release' is called, else the call to // 'release' will resume every caller currently waiting on 'acquire'. // eslint-disable-next-line no-unmodified-loop-condition return _continue(_for(function () { return mutex !== undefined; }, void 0, function () { return _awaitIgnored(mutex); }), function () { mutex = new Promise(function (resolve) { resolver = resolve; }); }); }); var release = function release() { if (resolver === undefined) { throw new Error("Unable to release mutex: already released."); } resolver(); resolver = undefined; mutex = undefined; }; return { safe: safe }; } ;// CONCATENATED MODULE: external "progress-smoother" var external_progress_smoother_namespaceObject = require("progress-smoother");; ;// CONCATENATED MODULE: ./src/UploadApiError.ts function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); } function _construct(Parent, args, Class) { if (_isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } function _isNativeFunction(fn) { return Function.toString.call(fn).indexOf("[native code]") !== -1; } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } var UploadApiError = /*#__PURE__*/function (_Error) { _inherits(UploadApiError, _Error); var _super = _createSuper(UploadApiError); function UploadApiError(response) { var _this; _classCallCheck(this, UploadApiError); _this = _super.call(this, response.error.message); _this.errorCode = response.error.code; _this.details = response.error.details; return _this; } return _createClass(UploadApiError); }( /*#__PURE__*/_wrapNativeSuper(Error)); ;// CONCATENATED MODULE: ./src/Upload.ts function Upload_rethrow(thrown, value) { if (thrown) throw value; return value; } function Upload_finallyRethrows(body, finalizer) { try { var result = body(); } catch (e) { return finalizer(true, e); } if (result && result.then) { return result.then(finalizer.bind(null, false), finalizer.bind(null, true)); } return finalizer(false, result); } function _continueIgnored(value) { if (value && value.then) { return value.then(Upload_empty); } } function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); } function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } function Upload_empty() {} var accountIdLength = 7; // Sync with: upload/shared/**/AccountIdUtils function Upload_awaitIgnored(value, direct) { if (!direct) { return value && value.then ? value.then(Upload_empty) : Promise.resolve(); } } var specialApiKeyAccountId = "W142hJk"; function Upload_async(f) { return function () { for (var args = [], i = 0; i < arguments.length; i++) { args[i] = arguments[i]; } try { return Promise.resolve(f.apply(this, args)); } catch (e) { return Promise.reject(e); } }; } var specialApiKeys = ["free", "demo"]; function _await(value, then, direct) { if (direct) { return then ? then(value) : value; } if (!value || !value.then) { value = Promise.resolve(value); } return then ? value.then(then) : value; } var apiKeyPrefix = "public_"; function Upload_call(body, then, direct) { if (direct) { return then ? then(body()) : body(); } try { var result = Promise.resolve(body()); return then ? result.then(then) : result; } catch (e) { return Promise.reject(e); } } var maxUploadConcurrency = 5; function _callIgnored(body, direct) { return Upload_call(body, Upload_empty, direct); } var refreshBeforeExpirySeconds = 20; function _catch(body, recover) { try { var result = body(); } catch (e) { return recover(e); } if (result && result.then) { return result.then(void 0, recover); } return result; } var onProgressInterval = 100; function _invokeIgnored(body) { var result = body(); if (result && result.then) { return result.then(Upload_empty); } } var retryAuthAfterErrorSeconds = 5; var minJwtTtlSeconds = 10; var maxJwtTtlSeconds = 2147483; // Max value for window.setTimeout is 2147483647ms -- if we go over this, the timeout fires immediately. var accessTokenPathBase = "/api/v1/access_tokens/"; var logPrefix = "[upload-js] "; /** * You should instantiate one instance of this class in your web app. * * Try using: * * Upload({apiKey: "free"}) * * If multiple instances exist, then all '*AuthSession' calls will be forwarded to the first instance that had an * '*AuthSession' call invoked on it. */ function Upload(config) { // ---------------- // READONLY MEMBERS // ---------------- var _a, _b, _c, _d, _e, _f, _g, _h, _j; var accountId; var authMutex = Mutex(); var apiUrl = (_b = (_a = config.internal) === null || _a === void 0 ? void 0 : _a.apiUrl) !== null && _b !== void 0 ? _b : "https://api.bytescale.com"; var cdnUrl = (_d = (_c = config.internal) === null || _c === void 0 ? void 0 : _c.cdnUrl) !== null && _d !== void 0 ? _d : "https://upcdn.io"; var authenticateWithApiKey = (_f = (_e = config.internal) === null || _e === void 0 ? void 0 : _e.authenticateWithApiKey) !== null && _f !== void 0 ? _f : true; var headers = (_g = config.internal) === null || _g === void 0 ? void 0 : _g.headers; var debugMode = config.debug === true; var wasCalled = " was called."; // ------------------ // READ/WRITE MEMBERS // ------------------ var lastAuthSession; // ---------------- // CONSTRUCTOR // ---------------- if ((config !== null && config !== void 0 ? config : undefined) === undefined) { throw new Error("".concat(logPrefix, "Config parameter required.")); } if (config.debug === true) { console.log("".concat(logPrefix, "Initialized with API key '").concat(config.apiKey, "'")); } if (((_h = config.apiKey) !== null && _h !== void 0 ? _h : undefined) === undefined) { throw new Error("".concat(logPrefix, "Please provide an API key via the 'apiKey' config parameter.")); } if (config.apiKey.trim() !== config.apiKey) { // We do not support API keys with whitespace (by trimming ourselves) because otherwise we'd need to support this // everywhere in perpetuity (since removing the trimming would be a breaking change). throw new Error("".concat(logPrefix, "API key needs trimming (whitespace detected).")); } // Non-api-key authentication is required by Bytescale Dashboard, which uses bearer tokens instead of API keys because // the user may not have any active API keys, but might still want to upload files via the Bytescale Dashboard. if (((_j = config.internal) === null || _j === void 0 ? void 0 : _j.authenticateWithApiKey) === false) { accountId = config.internal.accountId; } else { if (specialApiKeys.includes(config.apiKey)) { accountId = specialApiKeyAccountId; } else { if (!config.apiKey.startsWith(apiKeyPrefix)) { throw new Error("".concat(logPrefix, "API key must begin with \"").concat(apiKeyPrefix, "\".")); } accountId = config.apiKey.substr(apiKeyPrefix.length, accountIdLength); if (accountId.length !== accountIdLength) { throw new Error("".concat(logPrefix, "API key is too short!")); } } } var accessTokenUrl = "".concat(cdnUrl).concat(accessTokenPathBase).concat(accountId); // ---------------- // PUBLIC METHODS // ---------------- var beginAuthSession = Upload_async(function (authUrl, authHeaders) { return Upload_awaitIgnored(callAuthMethod(Upload_async(function (x) { return x.beginAuthSession(authUrl, authHeaders); }), Upload_async(function () { debug("'beginAuthSession'".concat(wasCalled)); // Explanation: // - Prevents restarting the auth session on accidental double-calls to 'beginAuthSession': in some users' code, // this happens accidentally every second, so we want to bail-out if we detect this is occurring. // - We only check 'authUrl' to determine if the 'same call' is being made, since 'authHeaders' is a function // and therefore its body can be switched-out by the user's code if they desire a change to its behaviour, so // don't need to call 'beginAuthSession' just to update it. if ((lastAuthSession === null || lastAuthSession === void 0 ? void 0 : lastAuthSession.authUrl) === authUrl) { error("'beginAuthSession' already called. Ignoring this call. Hint: call 'endAuthSession' and then 'beginAuthSession' if you want to restart the auth session."); return; } return Upload_call(doEndAuthSession, function () { var authSession = { accessToken: undefined, accessTokenRefreshHandle: undefined, isActive: true, authUrl: authUrl }; // Does not need to be inside the mutex since the environment is single-threaded, and we have not async-yielded // since the mutex from 'endAuthSession' was relinquished (meaning we still have execution, // so we know a) nothing can interject and b) nothing has interjected since the lock was relinquished). lastAuthSession = authSession; return Upload_awaitIgnored(refreshAccessToken(authUrl, authHeaders, authSession)); }); }))); }); var endAuthSession = Upload_async(function () { return Upload_awaitIgnored(callAuthMethod(Upload_async(function (x) { return x.endAuthSession(); }), Upload_async(function () { debug("'endAuthSession'".concat(wasCalled)); return _callIgnored(doEndAuthSession); }))); }); var uploadFile = Upload_async(function (file) { var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; debug("'uploadFile'".concat(wasCalled)); // Initial progress (raised immediately and synchronously). var cancellationHandlers = []; var addCancellationHandler = function addCancellationHandler(ca) { cancellationHandlers.push(ca); }; var cancel = function cancel() { return cancellationHandlers.forEach(function (x) { return x(); }); }; if (params.onBegin !== undefined) { params.onBegin({ cancel: cancel }); } return _catch(function () { return _await(beginFileUpload(file, params, addCancellationHandler)); }, function (e) { cancel(); throw e; }); }); var url = function url(filePath, transformationOrParams) { var _a; var defaultSlug = "raw"; var params = typeof transformationOrParams === "string" ? { transformation: transformationOrParams } : transformationOrParams; return "".concat(cdnUrl, "/").concat(accountId, "/").concat((_a = params === null || params === void 0 ? void 0 : params.transformation) !== null && _a !== void 0 ? _a : defaultSlug).concat(filePath).concat((params === null || params === void 0 ? void 0 : params.auth) === true ? "?_auth=true" : ""); }; var self = { beginAuthSession: beginAuthSession, endAuthSession: endAuthSession, uploadFile: uploadFile, url: url }; // ---------------- // PRIVATE METHODS // ---------------- var doEndAuthSession = Upload_async(function () { return Upload_awaitIgnored(authMutex.safe(Upload_async(function () { if (lastAuthSession === undefined) { return; } var authSession = lastAuthSession; lastAuthSession = undefined; if (authSession.accessTokenRefreshHandle !== undefined) { clearTimeout(authSession.accessTokenRefreshHandle); } authSession.isActive = false; return _callIgnored(deleteAccessToken); }))); }); var beginFileUpload = Upload_async(function (file, params, addCancellationHandler) { var progressSmoother = (0,external_progress_smoother_namespaceObject.ProgressSmoother)({ maxValue: file.size, teardownTime: 1000, minDelayUntilFirstValue: 2000, valueIncreaseDelta: 200 * 1024, valueIncreaseRatePerSecond: 50 * 1024, averageTimeBetweenValues: 1000 // When running, XHR should (hopefully) report at least every second, regardless of connection speed. }); var reportProgress = function reportProgress(stopReportingProgress) { if (params.onProgress === undefined) { stopReportingProgress(); // Important to call this, as outer function awaits this call when the download ends. } else { var bytesSent = progressSmoother.smoothedValue(); var bytesTotal = file.size; if (bytesSent === bytesTotal) { stopReportingProgress(); } params.onProgress({ bytesSent: bytesSent, bytesTotal: bytesTotal, progress: Math.round(bytesSent / bytesTotal * 100) }); } }; return withProgressReporting(onProgressInterval, reportProgress, Upload_async(function () { var uploadRequest = { path: params.path, metadata: params.metadata, mime: normalizeMimeType(file.type), originalFileName: file.name, protocol: "1.1", size: file.size, tags: params.tags }; debug("Initiating file upload. Params = ".concat(JSON.stringify(uploadRequest))); return _await((0,upload_api_client_upload_js_namespaceObject.beginMultipartUpload)(getConfig(), accountId, uploadRequest), function (_beginMultipartUpload) { var uploadMetadata = handleApiResult(_beginMultipartUpload); debug("Initiated file upload. Metadata = ".concat(JSON.stringify(uploadMetadata))); var incUploadIndex = function () { var lastUploadIndex = 0; return function () { if (lastUploadIndex === uploadMetadata.uploadParts.count - 1) { return undefined; } return ++lastUploadIndex; }; }(); var nextPartQueue = [uploadMetadata.uploadParts.first]; var getNextPart = Upload_async(function (workerIndex) { var nextPart = nextPartQueue.pop(); if (nextPart !== undefined) { debug("Dequeued part ".concat(nextPart.uploadPartIndex, "."), workerIndex); return nextPart; } var uploadPartIndex = incUploadIndex(); if (uploadPartIndex === undefined) { debug("No parts remaining.", workerIndex); return undefined; } debug("Fetching metadata for part ".concat(uploadPartIndex, "."), workerIndex); return _await((0,upload_api_client_upload_js_namespaceObject.getUploadPart)(getConfig(), accountId, uploadMetadata.uploadId, uploadPartIndex), handleApiResult); }); var bytesSentByEachWorker = []; var uploadNextPart = function uploadNextPart(workerIndex) { return _await(getNextPart(workerIndex), function (nextPart) { return _invokeIgnored(function () { if (nextPart !== undefined) { var lastBytesSent = 0; var progress = function progress(_ref) { var bytesSent = _ref.bytesSent; if (bytesSentByEachWorker[workerIndex] === undefined) { bytesSentByEachWorker[workerIndex] = bytesSent; } else { bytesSentByEachWorker[workerIndex] -= lastBytesSent; bytesSentByEachWorker[workerIndex] += bytesSent; } lastBytesSent = bytesSent; var totalBytesSent = bytesSentByEachWorker.reduce(function (a, b) { return a + b; }); progressSmoother.setValue(totalBytesSent); }; return _await(uploadPart(file, nextPart, progress, addCancellationHandler, workerIndex), function () { return Upload_awaitIgnored(uploadNextPart(workerIndex)); }); } }); }); }; return _await(Promise.all(_toConsumableArray(Array(maxUploadConcurrency).keys()).map(function (workerIndex) { return _await(uploadNextPart(workerIndex)); })), function () { var uploadedFile = Object.assign({ accountId: accountId, file: file }, uploadMetadata.file); debug("File upload completed."); return uploadedFile; }); }); })); }); var putUploadPart = Upload_async(function (url, content, progress, addCancellationHandler) { var xhr = new XMLHttpRequest(); var pending = true; addCancellationHandler(function () { if (pending) { xhr.abort(); } }); return Upload_finallyRethrows(function () { return _await(new Promise(function (resolve, reject) { xhr.upload.addEventListener("progress", function (evt) { if (evt.lengthComputable) { progress({ bytesSent: evt.loaded, bytesTotal: evt.total }); } }, false); xhr.addEventListener("load", function () { // Ensure we always report the progress of a finished upload as 100%. progress({ bytesSent: content.size, bytesTotal: content.size }); if (Math.floor(xhr.status / 100) === 2) { var etag = xhr.getResponseHeader("etag"); if (etag === null || etag === undefined) { reject(new Error("File upload error: no etag header in upload response.")); } else { resolve({ etag: etag }); } } else { reject(new Error("File upload error: status code ".concat(xhr.status))); } }); xhr.onabort = function () { return reject(new Error("File upload cancelled.")); }; xhr.onerror = function () { return reject(new Error("File upload error.")); }; xhr.ontimeout = function () { return reject(new Error("File upload timeout.")); }; xhr.open("PUT", url); xhr.send(content); })); }, function (_wasThrown, _result) { pending = false; return Upload_rethrow(_wasThrown, _result); }); }); var uploadPart = Upload_async(function (file, part, progress, addCancellationHandler, workerIndex) { var content = part.range.inclusiveEnd === -1 ? new Blob() : file.slice(part.range.inclusiveStart, part.range.inclusiveEnd + 1); debug("Uploading part ".concat(part.uploadPartIndex, "."), workerIndex); return _await(putUploadPart(part.uploadUrl, content, progress, addCancellationHandler), function (_ref2) { var etag = _ref2.etag; return _await((0,upload_api_client_upload_js_namespaceObject.completeUploadPart)(getConfig(), accountId, part.uploadId, part.uploadPartIndex, { etag: etag }), function (_completeUploadPart) { handleApiResult(_completeUploadPart); debug("Uploaded part ".concat(part.uploadPartIndex, "."), workerIndex); }); }); }); var withProgressReporting = Upload_async(function (tickInterval, tick, scope) { var whileReportingResolved; var whileReporting = new Promise(function (resolve) { whileReportingResolved = resolve; }); var isReporting = true; var stopReporting = function stopReporting() { if (isReporting) { whileReportingResolved(); clearInterval(intervalHandle); isReporting = false; } }; var intervalHandle = setInterval(function () { return tick(stopReporting); }, tickInterval); return Upload_finallyRethrows(function () { return Upload_call(scope, function (result) { return _await(whileReporting, function () { return result; }); }); }, function (_wasThrown2, _result2) { stopReporting(); return Upload_rethrow(_wasThrown2, _result2); }); }); var deleteAccessToken = Upload_async(function () { return Upload_awaitIgnored(deleteNoResponse(accessTokenUrl, {}, true // Required, else CDN response's `Set-Cookie` header will be silently ignored. )); }); /** * Calls the given auth method on the canonical auth instance. */ var callAuthMethod = Upload_async(function (other, me) { var authInstance = getAuthInstance(); return _invokeIgnored(function () { if (authInstance !== self) { // Forward call to global auth instance. return Upload_awaitIgnored(other(authInstance)); } else { return _callIgnored(me); } }); }); /** * Returns a single global instance of Upload.js for all auth calls. * If we require multiple instances in the future, we can provide a parameter to disable this behaviour. */ var getAuthInstance = function getAuthInstance() { var globalKey = "uploadJsAuthInstance"; var globalAuthInstance = window[globalKey]; if (globalAuthInstance === undefined) { globalAuthInstance = self; window[globalKey] = self; } return globalAuthInstance; }; var refreshAccessToken = Upload_async(function (authUrl, authHeaders, authSession) { return _continueIgnored(_catch(function () { return Upload_awaitIgnored(authMutex.safe(Upload_async(function () { // Session may have been ended while timer was waiting. if (!authSession.isActive) { return; } return Upload_call(authHeaders, function (_authHeaders) { return _await(getAccessToken(authUrl, _authHeaders), function (token) { return _await(putJsonGetJson(accessTokenUrl, {}, { accessToken: token }, true // Required, else CDN response's `Set-Cookie` header will be silently ignored. ), function (setTokenResult) { var desiredTtlSeconds = setTokenResult.ttlSeconds - refreshBeforeExpirySeconds; if (desiredTtlSeconds < minJwtTtlSeconds) { warn("JWT expiration is too short: waiting for ".concat(minJwtTtlSeconds, " seconds before refreshing.")); } authSession.accessToken = setTokenResult.accessToken; authSession.accessTokenRefreshHandle = window.setTimeout(function () { refreshAccessToken(authUrl, authHeaders, authSession).then(function () {}, function (e) { return error("Permanent error when refreshing access token: ".concat(e)); }); }, Math.min(maxJwtTtlSeconds, Math.max(minJwtTtlSeconds, desiredTtlSeconds)) * 1000); }); }); }); }))); }, function (e) { // Use 'error' instead of 'debug' so that the user sees error messages. error("Error when refreshing access token: ".concat(e)); // Perform attempts as part of same promise, rather than via a 'setTimeout' so that the 'beginAuthSession' only // returns once an auth session has been successfully established. return _await(new Promise(function (resolve) { return setTimeout(resolve, retryAuthAfterErrorSeconds * 1000); }), function () { // Todo: is this stack safe? return Upload_awaitIgnored(refreshAccessToken(authUrl, authHeaders, authSession)); }); })); }); var putJsonGetJson = Upload_async(function (url, headers, requestBody, withCredentials) { return _await(nonUploadApiRequest({ method: "PUT", path: url, headers: headers, body: requestBody }, withCredentials), function (_nonUploadApiRequest) { return _await(handleApiResult(_nonUploadApiRequest)); }); }); var getAccessToken = Upload_async(function (authUrl, headers) { var endpointName = "Your auth API endpoint"; return _await(nonUploadApiRequest({ method: "GET", path: authUrl, headers: headers }, false), function (result) { if (!result.ok) { throw new Error("".concat(logPrefix).concat(endpointName, " returned a failed response. Please ensure the endpoint's status code is 200.")); } var jwt = result.body; if (typeof jwt !== "string") { // We will receive 'null' if there was no content-type response header. throw new Error("".concat(logPrefix).concat(endpointName, " returned an unsupported response. Please ensure: 1) 'Content-Type: text/plain' is in the HTTP response headers 2) the status code is 200.")); } if (jwt.length === 0) { throw new Error("".concat(logPrefix).concat(endpointName, " returned an empty string. Please return a valid JWT instead.")); } if (jwt.trim().length !== jwt.length) { // Whitespace can be a nightmare to spot/debug, so we fail early here. throw new Error("".concat(logPrefix).concat(endpointName, " returned whitespace around the JWT, please remove it.")); } return jwt; }); }); var deleteNoResponse = Upload_async(function (url, headers, withCredentials) { return _await(nonUploadApiRequest({ method: "DELETE", path: url, headers: headers }, withCredentials), function (_nonUploadApiRequest2) { handleApiResult(_nonUploadApiRequest2); }); }); var handleApiResult = function handleApiResult(result) { var _a; if (result.ok) { return result.body; } var errorResponseMaybe = result.body; if (typeof ((_a = errorResponseMaybe === null || errorResponseMaybe === void 0 ? void 0 : errorResponseMaybe.error) === null || _a === void 0 ? void 0 : _a.code) === "string") { throw new UploadApiError(errorResponseMaybe); } throw new Error("".concat(logPrefix, "Network error. If problem persists, and your network connectivity is healthy, please contact support@bytescale.com and provide: (a) time of failed request in UTC (b) screenshot of failed network response body (c) screenshot of failed network response header (d) browser + version.")); }; var nonUploadApiRequest = Upload_async(function (options, withCredentials) { return (0,upload_api_client_upload_js_namespaceObject.request)({ BASE: options.path, WITH_CREDENTIALS: withCredentials }, Object.assign(Object.assign({}, options), { path: "" // We set to "" because we're using "BASE" above instead. })); }); var getConfig = function getConfig() { var apiConfig = { BASE: apiUrl, WITH_CREDENTIALS: true }; if (authenticateWithApiKey) { apiConfig.USERNAME = "apikey"; apiConfig.PASSWORD = config.apiKey; } var accessToken = lastAuthSession === null || lastAuthSession === void 0 ? void 0 : lastAuthSession.accessToken; if (headers !== undefined || accessToken !== undefined) { apiConfig.HEADERS = Upload_async(function () { return _await(headers === undefined ? {} : headers(), function (headersFromConfig) { var accessToken = lastAuthSession === null || lastAuthSession === void 0 ? void 0 : lastAuthSession.accessToken; // Re-fetch as there's been an async boundary so state may have changed. return Object.assign(Object.assign({}, headersFromConfig), accessToken === undefined ? {} : { "authorization-token": accessToken }); }, headers === undefined); }); } return apiConfig; }; var normalizeMimeType = function normalizeMimeType(mime) { var normal = mime.toLowerCase(); var regex = /^[a-z0-9]+\/[a-z0-9+\-._]+(?:;[^=]+=[^;]+)*$/; // Sync with 'MimeTypeUnboxed' in 'upload/api'. return regex.test(normal) ? normal : undefined; }; var debug = function debug(message, workerIndex) { if (debugMode) { console.log("".concat(logPrefix).concat(message).concat(workerIndex !== undefined ? " (Worker ".concat(workerIndex, ")") : "")); } }; var error = function error(message) { console.error("".concat(logPrefix).concat(message)); }; var warn = function warn(message) { console.warn("".concat(logPrefix).concat(message)); }; return self; } ;// CONCATENATED MODULE: ./src/index.ts /***/ }) /******/ }); /************************************************************************/ /******/ // The module cache /******/ var __webpack_module_cache__ = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ if(__webpack_module_cache__[moduleId]) { /******/ return __webpack_module_cache__[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { /******/ // no module.id needed /******/ // no module.loaded needed /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /************************************************************************/ /******/ /* webpack/runtime/define property getters */ /******/ !function() { /******/ // define getter functions for harmony exports /******/ __webpack_require__.d = function(exports, definition) { /******/ for(var key in definition) { /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); /******/ } /******/ } /******/ }; /******/ }(); /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ !function() { /******/ __webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); } /******/ }(); /******/ /******/ /* webpack/runtime/make namespace object */ /******/ !function() { /******/ // define __esModule on exports /******/ __webpack_require__.r = function(exports) { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ }(); /******/ /************************************************************************/ /******/ // module exports must be returned from runtime so entry inlining is disabled /******/ // startup /******/ // Load entry module and return exports /******/ return __webpack_require__("./src/index.ts"); /******/ })() ;