@selkirk-systems/fetch 1.0.0 → 1.0.2
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/README.md +17 -0
- package/dist/Download.js +4 -8
- package/dist/FetchWrapper.js +389 -0
- package/dist/constants/ErrorConstants.js +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +3 -0
- package/dist/middleware/FetchErrorHandler.js +37 -0
- package/dist/middleware/FetchLogger.js +29 -0
- package/lib/Download.js +175 -0
- package/lib/FetchWrapper.js +515 -0
- package/lib/index.js +3 -0
- package/{middleware → lib/middleware}/FetchErrorHandler.js +1 -1
- package/package.json +39 -19
- package/.babelrc +0 -6
- package/dist/Fetch.js +0 -463
- package/index.js +0 -2
- package/middleware/FetchValidationHandler.js +0 -22
- package/tests/Fetch.test.js +0 -114
- package/tests/files/test.pdf +0 -0
- package/tests/mocks/handlers.js +0 -75
- package/tests/mocks/server.js +0 -7
- /package/{constants → lib/constants}/ErrorConstants.js +0 -0
- /package/{middleware → lib/middleware}/FetchLogger.js +0 -0
package/package.json
CHANGED
|
@@ -1,19 +1,39 @@
|
|
|
1
|
-
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@selkirk-systems/fetch",
|
|
3
|
+
"version": "1.0.2",
|
|
4
|
+
"description": "Abortable fetch library",
|
|
5
|
+
"keywords": [],
|
|
6
|
+
"author": "Marcos Bernal <mbernal@selkirksystems.com>",
|
|
7
|
+
"license": "ISC",
|
|
8
|
+
"main": "dist/index.js",
|
|
9
|
+
"module": "dist/index.js",
|
|
10
|
+
"directories": {
|
|
11
|
+
"dist": "dist",
|
|
12
|
+
"lib": "lib",
|
|
13
|
+
"test": "__tests__"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist/**",
|
|
17
|
+
"lib/**"
|
|
18
|
+
],
|
|
19
|
+
"publishConfig": {
|
|
20
|
+
"access": "public"
|
|
21
|
+
},
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "git+https://galderak@bitbucket.org/selkirk/web-component-library.git"
|
|
25
|
+
},
|
|
26
|
+
"scripts": {
|
|
27
|
+
"test": "node ./__tests__/**",
|
|
28
|
+
"docs": "jsdoc --configure ../../jsdoc.json -r ./lib -d docs",
|
|
29
|
+
"build": "del dist && cross-env CI=false NODE_ENV=production babel lib --out-dir dist --copy-files --ignore __tests__,spec.js,test.js,__snapshots__"
|
|
30
|
+
},
|
|
31
|
+
"bugs": {
|
|
32
|
+
"url": "https://bitbucket.org/selkirk/web-component-library/issues"
|
|
33
|
+
},
|
|
34
|
+
"homepage": "https://bitbucket.org/selkirk/web-component-library#readme",
|
|
35
|
+
"peerDependencies": {
|
|
36
|
+
"@selkirk-systems/state-management": "^1.0.0"
|
|
37
|
+
},
|
|
38
|
+
"gitHead": "5c983164ac8e9ba82f7029463483fe5635987802"
|
|
39
|
+
}
|
package/.babelrc
DELETED
package/dist/Fetch.js
DELETED
|
@@ -1,463 +0,0 @@
|
|
|
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
|
-
}
|
package/index.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { enqueueSnackbar } from "@@/actions/SnackbarActions";
|
|
2
|
-
import React from 'react'
|
|
3
|
-
import ValidationErrors from "@@/components/snackbars/ValidationErrorsSnackbar";
|
|
4
|
-
|
|
5
|
-
const handler = (err) => (response) => (options) => (next) => {
|
|
6
|
-
if (response && response.validationErrors && response.validationErrors.length) {
|
|
7
|
-
enqueueSnackbar('Validation Errors', {
|
|
8
|
-
persist: true,
|
|
9
|
-
content: (key, message) => (
|
|
10
|
-
<ValidationErrors
|
|
11
|
-
id={key}
|
|
12
|
-
message={`${message} (${response.validationErrors.length})`}
|
|
13
|
-
validationErrors={response.validationErrors} />
|
|
14
|
-
),
|
|
15
|
-
});
|
|
16
|
-
return next(err,response);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
return next(err,response);
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
export default handler;
|