@selkirk-systems/fetch 0.1.5 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.babelrc ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "presets": [
3
+ "@babel/preset-env"
4
+ ],
5
+ "plugins": []
6
+ }
@@ -0,0 +1 @@
1
+ export const ADD_ERROR = "ADD_ERROR";
@@ -0,0 +1,187 @@
1
+ "use strict";
2
+
3
+ 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); }
4
+ /* eslint-disable no-undef */
5
+ /* eslint-disable no-restricted-globals */
6
+
7
+ //download.js v4.21, by dandavis; 2008-2018. [MIT] see http://danml.com/download.html for tests/usage
8
+ // v1 landed a FF+Chrome compatible way of downloading strings to local un-named files, upgraded to use a hidden frame and optional mime
9
+ // v2 added named files via a[download], msSaveBlob, IE (10+) support, and window.URL support for larger+faster saves than dataURLs
10
+ // v3 added dataURL and Blob Input, bind-toggle arity, and legacy dataURL fallback was improved with force-download mime and base64 support. 3.1 improved safari handling.
11
+ // v4 adds AMD/UMD, commonJS, and plain browser support
12
+ // v4.1 adds url download capability via solo URL argument (same domain/CORS only)
13
+ // v4.2 adds semantic variable names, long (over 2MB) dataURL support, and hidden by default temp anchors
14
+ // https://github.com/rndme/download
15
+
16
+ (function (root, factory) {
17
+ if (typeof define === 'function' && define.amd) {
18
+ // AMD. Register as an anonymous module.
19
+ define([], factory);
20
+ } else if ((typeof exports === "undefined" ? "undefined" : _typeof(exports)) === 'object') {
21
+ // Node. Does not work with strict CommonJS, but
22
+ // only CommonJS-like environments that support module.exports,
23
+ // like Node.
24
+ module.exports = factory();
25
+ } else {
26
+ // Browser globals (root is window)
27
+ root.download = factory();
28
+ }
29
+ })(void 0, function () {
30
+ return function download(data, strFileName, strMimeType) {
31
+ var self = window,
32
+ // this script is only for browsers anyway...
33
+ defaultMime = "application/octet-stream",
34
+ // this default mime also triggers iframe downloads
35
+ mimeType = strMimeType || defaultMime,
36
+ payload = data,
37
+ url = !strFileName && !strMimeType && payload,
38
+ anchor = document.createElement("a"),
39
+ toString = function toString(a) {
40
+ return String(a);
41
+ },
42
+ myBlob = self.Blob || self.MozBlob || self.WebKitBlob || toString,
43
+ fileName = strFileName || "download",
44
+ blob,
45
+ reader;
46
+ myBlob = myBlob.call ? myBlob.bind(self) : Blob;
47
+ if (String(this) === "true") {
48
+ //reverse arguments, allowing download.bind(true, "text/xml", "export.xml") to act as a callback
49
+ payload = [payload, mimeType];
50
+ mimeType = payload[0];
51
+ payload = payload[1];
52
+ }
53
+ if (url && url.length < 2048) {
54
+ // if no filename and no mime, assume a url was passed as the only argument
55
+ fileName = url.split("/").pop().split("?")[0];
56
+ anchor.href = url; // assign href prop to temp anchor
57
+ if (anchor.href.indexOf(url) !== -1) {
58
+ // if the browser determines that it's a potentially valid url path:
59
+ var ajax = new XMLHttpRequest();
60
+ ajax.open("GET", url, true);
61
+ ajax.responseType = 'blob';
62
+ ajax.onload = function (e) {
63
+ download(e.target.response, fileName, defaultMime);
64
+ };
65
+ setTimeout(function () {
66
+ ajax.send();
67
+ }, 0); // allows setting custom ajax headers using the return:
68
+ return ajax;
69
+ } // end if valid url?
70
+ } // end if url?
71
+
72
+ //go ahead and download dataURLs right away
73
+ if (/^data:([\w+-]+\/[\w+.-]+)?[,;]/.test(payload)) {
74
+ if (payload.length > 1024 * 1024 * 1.999 && myBlob !== toString) {
75
+ payload = dataUrlToBlob(payload);
76
+ mimeType = payload.type || defaultMime;
77
+ } else {
78
+ return navigator.msSaveBlob ?
79
+ // IE10 can't do a[download], only Blobs:
80
+ navigator.msSaveBlob(dataUrlToBlob(payload), fileName) : saver(payload); // everyone else can save dataURLs un-processed
81
+ }
82
+ } else {
83
+ //not data url, is it a string with special needs?
84
+ if (/([\x80-\xff])/.test(payload)) {
85
+ var i = 0,
86
+ tempUiArr = new Uint8Array(payload.length),
87
+ mx = tempUiArr.length;
88
+ for (i; i < mx; ++i) tempUiArr[i] = payload.charCodeAt(i);
89
+ payload = new myBlob([tempUiArr], {
90
+ type: mimeType
91
+ });
92
+ }
93
+ }
94
+ blob = payload instanceof myBlob ? payload : new myBlob([payload], {
95
+ type: mimeType
96
+ });
97
+ function dataUrlToBlob(strUrl) {
98
+ var parts = strUrl.split(/[:;,]/),
99
+ type = parts[1],
100
+ indexDecoder = strUrl.indexOf("charset") > 0 ? 3 : 2,
101
+ decoder = parts[indexDecoder] == "base64" ? atob : decodeURIComponent,
102
+ binData = decoder(parts.pop()),
103
+ mx = binData.length,
104
+ i = 0,
105
+ uiArr = new Uint8Array(mx);
106
+ for (i; i < mx; ++i) uiArr[i] = binData.charCodeAt(i);
107
+ return new myBlob([uiArr], {
108
+ type: type
109
+ });
110
+ }
111
+ function saver(url, winMode) {
112
+ if ('download' in anchor) {
113
+ //html5 A[download]
114
+ anchor.href = url;
115
+ anchor.setAttribute("download", fileName);
116
+ anchor.className = "download-js-link";
117
+ anchor.innerHTML = "downloading...";
118
+ anchor.style.display = "none";
119
+ anchor.addEventListener('click', function (e) {
120
+ e.stopPropagation();
121
+ this.removeEventListener('click', arguments.callee);
122
+ });
123
+ document.body.appendChild(anchor);
124
+ setTimeout(function () {
125
+ anchor.click();
126
+ document.body.removeChild(anchor);
127
+ if (winMode === true) {
128
+ setTimeout(function () {
129
+ self.URL.revokeObjectURL(anchor.href);
130
+ }, 250);
131
+ }
132
+ }, 66);
133
+ return true;
134
+ }
135
+
136
+ // handle non-a[download] safari as best we can:
137
+ if (/(Version)\/(\d+)\.(\d+)(?:\.(\d+))?.*Safari\//.test(navigator.userAgent)) {
138
+ if (/^data:/.test(url)) url = "data:" + url.replace(/^data:([\w\/\-\+]+)/, defaultMime);
139
+ if (!window.open(url)) {
140
+ // popup blocked, offer direct download:
141
+ if (confirm("Displaying New Document\n\nUse Save As... to download, then click back to return to this page.")) {
142
+ location.href = url;
143
+ }
144
+ }
145
+ return true;
146
+ }
147
+
148
+ //do iframe dataURL download (old ch+FF):
149
+ var f = document.createElement("iframe");
150
+ document.body.appendChild(f);
151
+ if (!winMode && /^data:/.test(url)) {
152
+ // force a mime that will download:
153
+ url = "data:" + url.replace(/^data:([\w\/\-\+]+)/, defaultMime);
154
+ }
155
+ f.src = url;
156
+ setTimeout(function () {
157
+ document.body.removeChild(f);
158
+ }, 333);
159
+ } //end saver
160
+
161
+ if (navigator.msSaveBlob) {
162
+ // IE10+ : (has Blob, but not a[download] or URL)
163
+ return navigator.msSaveBlob(blob, fileName);
164
+ }
165
+ if (self.URL) {
166
+ // simple fast and modern way using Blob and URL:
167
+ saver(self.URL.createObjectURL(blob), true);
168
+ } else {
169
+ // handle non-Blob()+non-URL browsers:
170
+ if (typeof blob === "string" || blob.constructor === toString) {
171
+ try {
172
+ return saver("data:" + mimeType + ";base64," + self.btoa(blob));
173
+ } catch (y) {
174
+ return saver("data:" + mimeType + "," + encodeURIComponent(blob));
175
+ }
176
+ }
177
+
178
+ // Blob but not URL support:
179
+ reader = new FileReader();
180
+ reader.onload = function (e) {
181
+ saver(this.result);
182
+ };
183
+ reader.readAsDataURL(blob);
184
+ }
185
+ return true;
186
+ }; /* end download() */
187
+ });
package/dist/Fetch.js ADDED
@@ -0,0 +1,463 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.applyMiddleware = applyMiddleware;
7
+ exports["default"] = Fetch;
8
+ var _Download = _interopRequireDefault(require("./Download"));
9
+ var _FetchErrorHandler = _interopRequireDefault(require("../middleware/FetchErrorHandler"));
10
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
11
+ 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); }
12
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
13
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
14
+ 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); }
15
+ 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; }
16
+ function _iterableToArrayLimit(arr, i) { var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"]; if (null != _i) { var _s, _e, _x, _r, _arr = [], _n = !0, _d = !1; try { if (_x = (_i = _i.call(arr)).next, 0 === i) { if (Object(_i) !== _i) return; _n = !1; } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0); } catch (err) { _d = !0, _e = err; } finally { try { if (!_n && null != _i["return"] && (_r = _i["return"](), Object(_r) !== _r)) return; } finally { if (_d) throw _e; } } return _arr; } }
17
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
18
+ function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return exports; }; var exports = {}, Op = Object.prototype, hasOwn = Op.hasOwnProperty, defineProperty = Object.defineProperty || function (obj, key, desc) { obj[key] = desc.value; }, $Symbol = "function" == typeof Symbol ? Symbol : {}, iteratorSymbol = $Symbol.iterator || "@@iterator", asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator", toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; function define(obj, key, value) { return Object.defineProperty(obj, key, { value: value, enumerable: !0, configurable: !0, writable: !0 }), obj[key]; } try { define({}, ""); } catch (err) { define = function define(obj, key, value) { return obj[key] = value; }; } function wrap(innerFn, outerFn, self, tryLocsList) { var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator, generator = Object.create(protoGenerator.prototype), context = new Context(tryLocsList || []); return defineProperty(generator, "_invoke", { value: makeInvokeMethod(innerFn, self, context) }), generator; } function tryCatch(fn, obj, arg) { try { return { type: "normal", arg: fn.call(obj, arg) }; } catch (err) { return { type: "throw", arg: err }; } } exports.wrap = wrap; var ContinueSentinel = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var IteratorPrototype = {}; define(IteratorPrototype, iteratorSymbol, function () { return this; }); var getProto = Object.getPrototypeOf, NativeIteratorPrototype = getProto && getProto(getProto(values([]))); NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol) && (IteratorPrototype = NativeIteratorPrototype); var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype); function defineIteratorMethods(prototype) { ["next", "throw", "return"].forEach(function (method) { define(prototype, method, function (arg) { return this._invoke(method, arg); }); }); } function AsyncIterator(generator, PromiseImpl) { function invoke(method, arg, resolve, reject) { var record = tryCatch(generator[method], generator, arg); if ("throw" !== record.type) { var result = record.arg, value = result.value; return value && "object" == _typeof(value) && hasOwn.call(value, "__await") ? PromiseImpl.resolve(value.__await).then(function (value) { invoke("next", value, resolve, reject); }, function (err) { invoke("throw", err, resolve, reject); }) : PromiseImpl.resolve(value).then(function (unwrapped) { result.value = unwrapped, resolve(result); }, function (error) { return invoke("throw", error, resolve, reject); }); } reject(record.arg); } var previousPromise; defineProperty(this, "_invoke", { value: function value(method, arg) { function callInvokeWithMethodAndArg() { return new PromiseImpl(function (resolve, reject) { invoke(method, arg, resolve, reject); }); } return previousPromise = previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(innerFn, self, context) { var state = "suspendedStart"; return function (method, arg) { if ("executing" === state) throw new Error("Generator is already running"); if ("completed" === state) { if ("throw" === method) throw arg; return doneResult(); } for (context.method = method, context.arg = arg;;) { var delegate = context.delegate; if (delegate) { var delegateResult = maybeInvokeDelegate(delegate, context); if (delegateResult) { if (delegateResult === ContinueSentinel) continue; return delegateResult; } } if ("next" === context.method) context.sent = context._sent = context.arg;else if ("throw" === context.method) { if ("suspendedStart" === state) throw state = "completed", context.arg; context.dispatchException(context.arg); } else "return" === context.method && context.abrupt("return", context.arg); state = "executing"; var record = tryCatch(innerFn, self, context); if ("normal" === record.type) { if (state = context.done ? "completed" : "suspendedYield", record.arg === ContinueSentinel) continue; return { value: record.arg, done: context.done }; } "throw" === record.type && (state = "completed", context.method = "throw", context.arg = record.arg); } }; } function maybeInvokeDelegate(delegate, context) { var methodName = context.method, method = delegate.iterator[methodName]; if (undefined === method) return context.delegate = null, "throw" === methodName && delegate.iterator["return"] && (context.method = "return", context.arg = undefined, maybeInvokeDelegate(delegate, context), "throw" === context.method) || "return" !== methodName && (context.method = "throw", context.arg = new TypeError("The iterator does not provide a '" + methodName + "' method")), ContinueSentinel; var record = tryCatch(method, delegate.iterator, context.arg); if ("throw" === record.type) return context.method = "throw", context.arg = record.arg, context.delegate = null, ContinueSentinel; var info = record.arg; return info ? info.done ? (context[delegate.resultName] = info.value, context.next = delegate.nextLoc, "return" !== context.method && (context.method = "next", context.arg = undefined), context.delegate = null, ContinueSentinel) : info : (context.method = "throw", context.arg = new TypeError("iterator result is not an object"), context.delegate = null, ContinueSentinel); } function pushTryEntry(locs) { var entry = { tryLoc: locs[0] }; 1 in locs && (entry.catchLoc = locs[1]), 2 in locs && (entry.finallyLoc = locs[2], entry.afterLoc = locs[3]), this.tryEntries.push(entry); } function resetTryEntry(entry) { var record = entry.completion || {}; record.type = "normal", delete record.arg, entry.completion = record; } function Context(tryLocsList) { this.tryEntries = [{ tryLoc: "root" }], tryLocsList.forEach(pushTryEntry, this), this.reset(!0); } function values(iterable) { if (iterable) { var iteratorMethod = iterable[iteratorSymbol]; if (iteratorMethod) return iteratorMethod.call(iterable); if ("function" == typeof iterable.next) return iterable; if (!isNaN(iterable.length)) { var i = -1, next = function next() { for (; ++i < iterable.length;) if (hasOwn.call(iterable, i)) return next.value = iterable[i], next.done = !1, next; return next.value = undefined, next.done = !0, next; }; return next.next = next; } } return { next: doneResult }; } function doneResult() { return { value: undefined, done: !0 }; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, defineProperty(Gp, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), defineProperty(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"), exports.isGeneratorFunction = function (genFun) { var ctor = "function" == typeof genFun && genFun.constructor; return !!ctor && (ctor === GeneratorFunction || "GeneratorFunction" === (ctor.displayName || ctor.name)); }, exports.mark = function (genFun) { return Object.setPrototypeOf ? Object.setPrototypeOf(genFun, GeneratorFunctionPrototype) : (genFun.__proto__ = GeneratorFunctionPrototype, define(genFun, toStringTagSymbol, "GeneratorFunction")), genFun.prototype = Object.create(Gp), genFun; }, exports.awrap = function (arg) { return { __await: arg }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, asyncIteratorSymbol, function () { return this; }), exports.AsyncIterator = AsyncIterator, exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) { void 0 === PromiseImpl && (PromiseImpl = Promise); var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl); return exports.isGeneratorFunction(outerFn) ? iter : iter.next().then(function (result) { return result.done ? result.value : iter.next(); }); }, defineIteratorMethods(Gp), define(Gp, toStringTagSymbol, "Generator"), define(Gp, iteratorSymbol, function () { return this; }), define(Gp, "toString", function () { return "[object Generator]"; }), exports.keys = function (val) { var object = Object(val), keys = []; for (var key in object) keys.push(key); return keys.reverse(), function next() { for (; keys.length;) { var key = keys.pop(); if (key in object) return next.value = key, next.done = !1, next; } return next.done = !0, next; }; }, exports.values = values, Context.prototype = { constructor: Context, reset: function reset(skipTempReset) { if (this.prev = 0, this.next = 0, this.sent = this._sent = undefined, this.done = !1, this.delegate = null, this.method = "next", this.arg = undefined, this.tryEntries.forEach(resetTryEntry), !skipTempReset) for (var name in this) "t" === name.charAt(0) && hasOwn.call(this, name) && !isNaN(+name.slice(1)) && (this[name] = undefined); }, stop: function stop() { this.done = !0; var rootRecord = this.tryEntries[0].completion; if ("throw" === rootRecord.type) throw rootRecord.arg; return this.rval; }, dispatchException: function dispatchException(exception) { if (this.done) throw exception; var context = this; function handle(loc, caught) { return record.type = "throw", record.arg = exception, context.next = loc, caught && (context.method = "next", context.arg = undefined), !!caught; } for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i], record = entry.completion; if ("root" === entry.tryLoc) return handle("end"); if (entry.tryLoc <= this.prev) { var hasCatch = hasOwn.call(entry, "catchLoc"), hasFinally = hasOwn.call(entry, "finallyLoc"); if (hasCatch && hasFinally) { if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); } else if (hasCatch) { if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); } else { if (!hasFinally) throw new Error("try statement without catch or finally"); if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); } } } }, abrupt: function abrupt(type, arg) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) { var finallyEntry = entry; break; } } finallyEntry && ("break" === type || "continue" === type) && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc && (finallyEntry = null); var record = finallyEntry ? finallyEntry.completion : {}; return record.type = type, record.arg = arg, finallyEntry ? (this.method = "next", this.next = finallyEntry.finallyLoc, ContinueSentinel) : this.complete(record); }, complete: function complete(record, afterLoc) { if ("throw" === record.type) throw record.arg; return "break" === record.type || "continue" === record.type ? this.next = record.arg : "return" === record.type ? (this.rval = this.arg = record.arg, this.method = "return", this.next = "end") : "normal" === record.type && afterLoc && (this.next = afterLoc), ContinueSentinel; }, finish: function finish(finallyLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.finallyLoc === finallyLoc) return this.complete(entry.completion, entry.afterLoc), resetTryEntry(entry), ContinueSentinel; } }, "catch": function _catch(tryLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc === tryLoc) { var record = entry.completion; if ("throw" === record.type) { var thrown = record.arg; resetTryEntry(entry); } return thrown; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(iterable, resultName, nextLoc) { return this.delegate = { iterator: values(iterable), resultName: resultName, nextLoc: nextLoc }, "next" === this.method && (this.arg = undefined), ContinueSentinel; } }, exports; }
19
+ 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); } }
20
+ 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); }); }; }
21
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
22
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
23
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
24
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
25
+ function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } //Inspired by https://www.bennadel.com/blog/4180-canceling-api-requests-using-fetch-and-abortcontroller-in-javascript.htm
26
+ // Regular expression patterns for testing content-type response headers.
27
+ var RE_CONTENT_TYPE_JSON = /^application\/(x-)?json/i;
28
+ var RE_CONTENT_TYPE_TEXT = /"^text\/"/i;
29
+ var RE_QUERY_STRING = /\/.+\?/;
30
+ var UNEXPECTED_ERROR_MESSAGE = "An unexpected error occurred while processing your request.";
31
+ var CONTENT_TYPE_DOWNLOADS = {
32
+ 'application/pdf': true,
33
+ 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': true
34
+ };
35
+ //We store the original promise.catch so we can override it in some
36
+ //scenarios when we want to swallow errors vs bubble them up.
37
+ var ORIGINAL_CATCH_FN = Promise.prototype["catch"];
38
+
39
+ //Auto applied middleware that dispatches all errors so any UI's can respond.
40
+ var _middlewares = [_FetchErrorHandler["default"]];
41
+
42
+ //Cache of request AbortController signals for auto request aborting.
43
+ var _requests = {};
44
+
45
+ /**
46
+ * PUBLIC: Apply custom middleware to act on any fetch responses and errors.
47
+ *
48
+ * NOTE: Middleware can handle errors and swallow them by passing back a new error object.
49
+ *
50
+ * @param {array} middleware
51
+ */
52
+ function applyMiddleware() {
53
+ var middleware = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
54
+ _middlewares = middleware;
55
+ _middlewares.push(_FetchErrorHandler["default"]);
56
+ }
57
+
58
+ /**
59
+ * Make the fetch request with the given configuration options.
60
+ *
61
+ * GUARANTEE: All errors produced by this method will have consistent structure, even
62
+ * if they are low-level networking errors. At a minimum, every Promise rejection will
63
+ * have the following properties:
64
+ *
65
+ * TODO: Add support for multi-form uploads (images, files etc)
66
+ *
67
+ * - data.type
68
+ * - data.message
69
+ * - status.code
70
+ * - status.text
71
+ * - status.isAbort
72
+ */
73
+ function Fetch(url) {
74
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
75
+ var config = _objectSpread(_objectSpread({
76
+ downloadFileName: null,
77
+ contentType: "application/json",
78
+ headers: {
79
+ accept: "*/*"
80
+ },
81
+ credentials: "same-origin",
82
+ url: url || "",
83
+ urlTemplateData: {},
84
+ method: "GET",
85
+ params: {},
86
+ form: null,
87
+ json: null,
88
+ body: null,
89
+ signal: new AbortController()
90
+ }, options), {}, {
91
+ _hasCatch: false,
92
+ _promiseChain: null,
93
+ _userSignal: Boolean(options.signal)
94
+ });
95
+ var finalHeaders, finalMethod, finalUrl, finalBody, finalSignal, request;
96
+ try {
97
+ finalHeaders = buildHeaders(config.headers);
98
+ finalMethod = config.method;
99
+ finalUrl = buildURL(config.url, config.urlTemplateData, config.params);
100
+ finalBody = config.body;
101
+ finalSignal = config.signal;
102
+
103
+ // Bail out early if url contains url params,
104
+ //these should be set via the options.params object.
105
+ if (!config.url.href && RE_QUERY_STRING.test(config.url)) {
106
+ return Promise.reject(normalizeError({
107
+ type: "INVALID_URL",
108
+ message: "".concat(config.url, " contains query parameters: please use options.params object for this purpose.")
109
+ }, {}, {}));
110
+ }
111
+ if (CONTENT_TYPE_DOWNLOADS[config.contentType] && finalMethod === "GET") {
112
+ finalHeaders.credentials = "same-origin";
113
+ finalHeaders.accept = "*/*";
114
+ }
115
+ if (config.form) {
116
+ // For form data posts, we want the browser to build the Content-
117
+ // Type for us so that it puts in both the "multipart/form-data" plus the
118
+ // correct, auto-generated field delimiter.
119
+ delete finalHeaders["content-type"];
120
+ finalMethod = "POST";
121
+ finalBody = buildFormData(config.form);
122
+ } else if (config.json) {
123
+ finalHeaders["content-type"] = config.contentType || "application/x-json";
124
+ finalBody = JSON.stringify(config.json);
125
+ } else if (config.body) {
126
+ finalHeaders["content-type"] = config.contentType || "application/octet-stream";
127
+ } else {
128
+ finalHeaders["content-type"] = config.contentType;
129
+ }
130
+ request = new window.Request(finalUrl, {
131
+ headers: finalHeaders,
132
+ method: finalMethod,
133
+ body: finalBody,
134
+ signal: finalSignal.signal
135
+ });
136
+
137
+ //Check if a pending request is in-flight, if so and it is the exact same url abort it.
138
+ if (_requests[finalUrl]) {
139
+ _requests[finalUrl].abort();
140
+ }
141
+
142
+ //Cache requests abort signal by url
143
+ cacheRequestSignal(finalUrl, finalSignal);
144
+ config._promiseChain = Promise.resolve(window.fetch(request)).then( /*#__PURE__*/function () {
145
+ var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(response) {
146
+ var data, nextResp;
147
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
148
+ while (1) switch (_context.prev = _context.next) {
149
+ case 0:
150
+ deleteCachedRequestSignal(finalUrl);
151
+ _context.next = 3;
152
+ return unwrapResponseData(response);
153
+ case 3:
154
+ data = _context.sent;
155
+ if (!response.ok) {
156
+ _context.next = 8;
157
+ break;
158
+ }
159
+ //Run response through middleware
160
+ nextResp = _applyMiddleware(null, response, config);
161
+ if (config.downloadFileName) {
162
+ presetBrowserDownloadDialog(data, config);
163
+ }
164
+ return _context.abrupt("return", [{
165
+ request: request,
166
+ response: nextResp || response,
167
+ data: data
168
+ }, false]);
169
+ case 8:
170
+ return _context.abrupt("return", handleError(normalizeError(data, request, response), config));
171
+ case 9:
172
+ case "end":
173
+ return _context.stop();
174
+ }
175
+ }, _callee);
176
+ }));
177
+ return function (_x) {
178
+ return _ref.apply(this, arguments);
179
+ };
180
+ }())["catch"](function (err) {
181
+ deleteCachedRequestSignal(finalUrl);
182
+ var error = isNormalizedError(err) ? err : normalizeTransportError(err);
183
+ return handleError(error, config);
184
+ });
185
+ } catch (err) {
186
+ deleteCachedRequestSignal(finalUrl);
187
+ return handleError(normalizeTransportError(err), config);
188
+ }
189
+ if (config._promiseChain) {
190
+ //If catch is added outside, then assume they want to handle errors and
191
+ //not have them swallowed
192
+
193
+ config._promiseChain["catch"] = function () {
194
+ config._hasCatch = true;
195
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
196
+ args[_key] = arguments[_key];
197
+ }
198
+ return ORIGINAL_CATCH_FN.apply(this, args);
199
+ };
200
+ }
201
+ return config._promiseChain;
202
+ }
203
+
204
+ /**
205
+ * Shows the browser download dialog
206
+ * @param {response.blob} blob
207
+ * @param {object} config
208
+ * @returns
209
+ */
210
+ function presetBrowserDownloadDialog(blob, config) {
211
+ return (0, _Download["default"])(blob, config.downloadFileName, config.contentType);
212
+ }
213
+
214
+ /**
215
+ * Stores a ref to the abort signal
216
+ * @param {string} url
217
+ * @param {AbortController.signal} signal
218
+ */
219
+ function cacheRequestSignal(url, signal) {
220
+ _requests[url] = signal;
221
+ }
222
+
223
+ /**
224
+ * Deletes a req from the cached requests
225
+ * @param {string} url
226
+ */
227
+ function deleteCachedRequestSignal(url) {
228
+ delete _requests[url];
229
+ }
230
+
231
+ /**
232
+ * Checks if the error structure mimics ours and has already been normalized.
233
+ * @param {Object} err
234
+ * @returns
235
+ */
236
+ function isNormalizedError(err) {
237
+ return err.hasOwnProperty("status") && err.hasOwnProperty("data");
238
+ }
239
+
240
+ /**
241
+ * Handles errors by passing them through any middleware and finally throwing them or swallowing them.
242
+ * @param {object} normalizedError
243
+ * @param {object} config
244
+ * @returns
245
+ */
246
+ function handleError(normalizedError, config) {
247
+ var hasCatch = config._hasCatch;
248
+ var promiseChain = config._promiseChain;
249
+ var nextErr = _applyMiddleware(normalizedError, null, config);
250
+
251
+ //Only swallow errors if they have been handled by middleware AND they have not
252
+ //Added a catch outside
253
+ if (!hasCatch && !nextErr) {
254
+ if (promiseChain && promiseChain.cancel) promiseChain.cancel();
255
+ return Promise.resolve([null, true]);
256
+ }
257
+
258
+ // The request failed in a critical way; the content of this error will be
259
+ // entirely unpredictable.
260
+ return Promise.reject(nextErr || normalizedError);
261
+ }
262
+
263
+ /**
264
+ * Passes any errors, responses through configured middleware
265
+ *
266
+ * @param {ErrorEvent} err the error.
267
+ * @param {Object} response the network response.
268
+ * @param {Object} options the request options.
269
+ * @returns null
270
+ */
271
+ function _applyMiddleware(err, response, options) {
272
+ var i = -1;
273
+ var next = function next(nextErr, nextState) {
274
+ i++;
275
+ var middleware = _middlewares[i];
276
+ if (!middleware) return nextErr || nextState;
277
+ return middleware(nextErr)(nextState)(options)(next);
278
+ };
279
+ return next(err, response);
280
+ }
281
+
282
+ /**
283
+ * Unwrap the response payload from the given response based on the reported
284
+ * content-type.
285
+ */
286
+ function unwrapResponseData(_x2) {
287
+ return _unwrapResponseData.apply(this, arguments);
288
+ }
289
+ /**
290
+ * FormData instance from the given object.
291
+ *
292
+ * NOTE: At this time, only simple values (ie, no files) are supported.
293
+ */
294
+ function _unwrapResponseData() {
295
+ _unwrapResponseData = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(response) {
296
+ var contentType;
297
+ return _regeneratorRuntime().wrap(function _callee2$(_context2) {
298
+ while (1) switch (_context2.prev = _context2.next) {
299
+ case 0:
300
+ contentType = response.headers.has("content-type") ? response.headers.get("content-type") : "";
301
+ if (!RE_CONTENT_TYPE_JSON.test(contentType)) {
302
+ _context2.next = 5;
303
+ break;
304
+ }
305
+ return _context2.abrupt("return", response.json());
306
+ case 5:
307
+ if (!RE_CONTENT_TYPE_TEXT.test(contentType)) {
308
+ _context2.next = 9;
309
+ break;
310
+ }
311
+ return _context2.abrupt("return", response.text());
312
+ case 9:
313
+ return _context2.abrupt("return", response.blob());
314
+ case 10:
315
+ case "end":
316
+ return _context2.stop();
317
+ }
318
+ }, _callee2);
319
+ }));
320
+ return _unwrapResponseData.apply(this, arguments);
321
+ }
322
+ function buildFormData(form) {
323
+ var formData = new FormData();
324
+ Object.entries(form).forEach(function (_ref2) {
325
+ var _ref3 = _slicedToArray(_ref2, 2),
326
+ key = _ref3[0],
327
+ value = _ref3[1];
328
+ formData.append(key, value);
329
+ });
330
+ return formData;
331
+ }
332
+
333
+ /**
334
+ * Supports url or url with template identifiers,creates a url with optional query parameters.
335
+ * @param {string} url
336
+ * @param {object} templateData
337
+ * @param {object} params
338
+ * @returns
339
+ */
340
+ function buildURL(url, templateData, params) {
341
+ if (url.href) return url;
342
+ var formattedUrl = buildURLTemplate(url, templateData);
343
+ var finalUrl = new URL(formattedUrl, "".concat(window.location.origin).concat(window.baseUrl || ""));
344
+ var searchParams = new URLSearchParams();
345
+ Object.entries(params).forEach(function (_ref4) {
346
+ var _ref5 = _slicedToArray(_ref4, 2),
347
+ key = _ref5[0],
348
+ value = _ref5[1];
349
+ if (Array.isArray(value)) {
350
+ for (var i = 0; i < value.length; i++) {
351
+ var e = value[i];
352
+ searchParams.append(key, e);
353
+ }
354
+ return;
355
+ }
356
+ searchParams.append(key, value);
357
+ });
358
+ finalUrl.search = searchParams;
359
+ return finalUrl;
360
+ }
361
+
362
+ /**
363
+ * Builds a urls tring using template identifiers.
364
+ * @param {string} url
365
+ * @param {object} templateData
366
+ */
367
+ function buildURLTemplate(url, templateData) {
368
+ Object.entries(templateData).forEach(function (_ref6) {
369
+ var _ref7 = _slicedToArray(_ref6, 2),
370
+ key = _ref7[0],
371
+ value = _ref7[1];
372
+ url = url.replace(new RegExp("{".concat(key, "}"), "ig"), value.toString());
373
+ });
374
+ return url;
375
+ }
376
+
377
+ /**
378
+ * Transform the collection of HTTP headers into a like collection wherein the names
379
+ * of the headers have been lower-cased. This way, if we need to manipulate the
380
+ * collection prior to transport, we'll know what key-casing to use.
381
+ */
382
+ function buildHeaders(headers) {
383
+ var lowercaseHeaders = {};
384
+ Object.entries(headers).forEach(function (_ref8) {
385
+ var _ref9 = _slicedToArray(_ref8, 2),
386
+ key = _ref9[0],
387
+ value = _ref9[1];
388
+ lowercaseHeaders[key.toLowerCase()] = value;
389
+ });
390
+ return lowercaseHeaders;
391
+ }
392
+
393
+ /**
394
+ * At a minimum, we want every error to have the following properties:
395
+ *
396
+ * - data.type
397
+ * - data.message
398
+ * - status.code
399
+ * - status.text
400
+ * - status.isAbort
401
+ *
402
+ * These are the keys that the calling context will depend on; and, are the minimum
403
+ * keys that the server is expected to return when it throws domain errors.
404
+ */
405
+ function normalizeError(data, request, response) {
406
+ var error = {
407
+ data: {
408
+ type: "ServerError",
409
+ message: UNEXPECTED_ERROR_MESSAGE
410
+ },
411
+ status: {
412
+ code: response.status,
413
+ text: response.statusText,
414
+ isAbort: false
415
+ },
416
+ // The following data is being provided to make debugging AJAX errors easier.
417
+ request: request,
418
+ response: response
419
+ };
420
+
421
+ // If the error data is an Object (which it should be if the server responded
422
+ // with a domain-based error), then it should have "type" and "message"
423
+ // properties within it. That said, just because this isn't a transport error, it
424
+ // doesn't mean that this error is actually being returned by our application.
425
+ if (typeof (data === null || data === void 0 ? void 0 : data.type) === "string" && typeof (data === null || data === void 0 ? void 0 : data.message) === "string") {
426
+ Object.assign(error.data, data);
427
+
428
+ // If the error data has any other shape, it means that an unexpected error
429
+ // occurred on the server (or somewhere in transit). Let's pass that raw error
430
+ // through as the rootCause, using the default error structure.
431
+ } else {
432
+ error.data.rootCause = data;
433
+ }
434
+ return error;
435
+ }
436
+
437
+ /**
438
+ * If our request never makes it to the server (or the round-trip is interrupted
439
+ * somehow), we still want the error response to have a consistent structure with the
440
+ * application errors returned by the server. At a minimum, we want every error to
441
+ * have the following properties:
442
+ *
443
+ * - data.type
444
+ * - data.message
445
+ * - status.code
446
+ * - status.text
447
+ * - status.isAbort
448
+ */
449
+ function normalizeTransportError(transportError) {
450
+ var isAbort = transportError.name === "AbortError";
451
+ return {
452
+ data: {
453
+ type: "TransportError",
454
+ message: isAbort ? "Network Request Aborted" : UNEXPECTED_ERROR_MESSAGE,
455
+ rootCause: transportError
456
+ },
457
+ status: {
458
+ code: 0,
459
+ text: "Unknown",
460
+ isAbort: isAbort
461
+ }
462
+ };
463
+ }