api-def 0.4.1-alpha3 → 0.5.1

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.
Files changed (167) hide show
  1. package/README.md +1 -1
  2. package/cjs/Api.d.ts +13 -15
  3. package/cjs/Api.js +28 -41
  4. package/cjs/ApiConstants.d.ts +28 -0
  5. package/cjs/ApiConstants.js +28 -0
  6. package/cjs/ApiTypes.d.ts +2 -7
  7. package/cjs/ApiUtils.d.ts +2 -10
  8. package/cjs/ApiUtils.js +24 -37
  9. package/cjs/Endpoint.d.ts +21 -5
  10. package/cjs/Endpoint.js +16 -31
  11. package/cjs/MockingTypes.d.ts +28 -0
  12. package/cjs/{lib/Utils.js → MockingTypes.js} +0 -0
  13. package/cjs/RequestContext.d.ts +9 -4
  14. package/cjs/RequestContext.js +4 -2
  15. package/cjs/RequestError.d.ts +21 -0
  16. package/cjs/RequestError.js +23 -0
  17. package/cjs/Requester.d.ts +2 -1
  18. package/cjs/Requester.js +153 -67
  19. package/cjs/TextDecoding.d.ts +1 -0
  20. package/cjs/TextDecoding.js +139 -0
  21. package/cjs/Utils.d.ts +9 -0
  22. package/cjs/Utils.js +30 -1
  23. package/cjs/backend/AxiosRequestBackend.d.ts +4 -3
  24. package/cjs/backend/AxiosRequestBackend.js +3 -0
  25. package/cjs/backend/FetchRequestBackend.d.ts +2 -1
  26. package/cjs/backend/FetchRequestBackend.js +12 -7
  27. package/cjs/backend/MockRequestBackend.d.ts +10 -0
  28. package/cjs/backend/MockRequestBackend.js +149 -0
  29. package/cjs/backend/RequestBackend.d.ts +4 -0
  30. package/cjs/cache/LocalForageCacheBackend.js +1 -0
  31. package/cjs/index.d.ts +1 -1
  32. package/cjs/index.js +2 -2
  33. package/cjs/util/retry/index.d.ts +3 -0
  34. package/cjs/util/retry/index.js +52 -0
  35. package/cjs/util/retry/lib/retry.d.ts +3 -0
  36. package/cjs/util/retry/lib/retry.js +54 -0
  37. package/cjs/util/retry/lib/retryOperation.d.ts +27 -0
  38. package/cjs/util/retry/lib/retryOperation.js +134 -0
  39. package/esm/Api.d.ts +13 -15
  40. package/esm/Api.js +24 -39
  41. package/esm/ApiConstants.d.ts +28 -0
  42. package/esm/ApiConstants.js +28 -0
  43. package/esm/ApiTypes.d.ts +2 -7
  44. package/esm/ApiUtils.d.ts +2 -10
  45. package/esm/ApiUtils.js +22 -35
  46. package/esm/Endpoint.d.ts +21 -5
  47. package/esm/Endpoint.js +16 -31
  48. package/esm/MockingTypes.d.ts +28 -0
  49. package/esm/{lib/backend/RequestBackend.js → MockingTypes.js} +0 -0
  50. package/esm/RequestContext.d.ts +9 -4
  51. package/esm/RequestContext.js +4 -2
  52. package/esm/RequestError.d.ts +21 -0
  53. package/esm/RequestError.js +18 -0
  54. package/esm/Requester.d.ts +2 -1
  55. package/esm/Requester.js +153 -67
  56. package/esm/TextDecoding.d.ts +1 -0
  57. package/esm/TextDecoding.js +135 -0
  58. package/esm/Utils.d.ts +9 -0
  59. package/esm/Utils.js +26 -0
  60. package/esm/backend/AxiosRequestBackend.d.ts +4 -3
  61. package/esm/backend/AxiosRequestBackend.js +3 -0
  62. package/esm/backend/FetchRequestBackend.d.ts +2 -1
  63. package/esm/backend/FetchRequestBackend.js +12 -7
  64. package/esm/backend/MockRequestBackend.d.ts +10 -0
  65. package/esm/backend/MockRequestBackend.js +147 -0
  66. package/esm/backend/RequestBackend.d.ts +4 -0
  67. package/esm/cache/LocalForageCacheBackend.js +1 -0
  68. package/esm/index.d.ts +1 -1
  69. package/esm/index.js +1 -1
  70. package/esm/util/retry/index.d.ts +3 -0
  71. package/esm/util/retry/index.js +50 -0
  72. package/esm/util/retry/lib/retry.d.ts +3 -0
  73. package/esm/util/retry/lib/retry.js +50 -0
  74. package/esm/util/retry/lib/retryOperation.d.ts +27 -0
  75. package/esm/util/retry/lib/retryOperation.js +132 -0
  76. package/package.json +29 -19
  77. package/CHANGELOG.md +0 -39
  78. package/cjs/Mocking.d.ts +0 -23
  79. package/cjs/Mocking.js +0 -81
  80. package/cjs/__tests__/mock/ExampleApis.d.ts +0 -3
  81. package/cjs/__tests__/mock/ExampleApis.js +0 -19
  82. package/cjs/lib/Api.d.ts +0 -32
  83. package/cjs/lib/Api.js +0 -126
  84. package/cjs/lib/ApiTypes.d.ts +0 -102
  85. package/cjs/lib/ApiTypes.js +0 -31
  86. package/cjs/lib/ApiUtils.d.ts +0 -13
  87. package/cjs/lib/ApiUtils.js +0 -60
  88. package/cjs/lib/Caching.d.ts +0 -9
  89. package/cjs/lib/Caching.js +0 -85
  90. package/cjs/lib/Endpoint.d.ts +0 -30
  91. package/cjs/lib/Endpoint.js +0 -121
  92. package/cjs/lib/EndpointBuilder.d.ts +0 -12
  93. package/cjs/lib/EndpointBuilder.js +0 -27
  94. package/cjs/lib/Mocking.d.ts +0 -23
  95. package/cjs/lib/Mocking.js +0 -80
  96. package/cjs/lib/RequestContext.d.ts +0 -28
  97. package/cjs/lib/RequestContext.js +0 -166
  98. package/cjs/lib/Requester.d.ts +0 -2
  99. package/cjs/lib/Requester.js +0 -164
  100. package/cjs/lib/Utils.d.ts +0 -1
  101. package/cjs/lib/backend/AxiosBackend.d.ts +0 -10
  102. package/cjs/lib/backend/AxiosBackend.js +0 -98
  103. package/cjs/lib/backend/AxiosRequestBackend.d.ts +0 -11
  104. package/cjs/lib/backend/AxiosRequestBackend.js +0 -99
  105. package/cjs/lib/backend/FetchBackend.d.ts +0 -8
  106. package/cjs/lib/backend/FetchBackend.js +0 -145
  107. package/cjs/lib/backend/FetchRequestBackend.d.ts +0 -9
  108. package/cjs/lib/backend/FetchRequestBackend.js +0 -150
  109. package/cjs/lib/backend/RequestBackend.d.ts +0 -11
  110. package/cjs/lib/backend/RequestBackend.js +0 -2
  111. package/cjs/lib/cache/CacheBackend.d.ts +0 -6
  112. package/cjs/lib/cache/CacheBackend.js +0 -2
  113. package/cjs/lib/cache/Caching.d.ts +0 -10
  114. package/cjs/lib/cache/Caching.js +0 -84
  115. package/cjs/lib/cache/LocalForageCacheBackend.d.ts +0 -9
  116. package/cjs/lib/cache/LocalForageCacheBackend.js +0 -25
  117. package/cjs/lib/cache/LocalStorageCacheBackend.d.ts +0 -7
  118. package/cjs/lib/cache/LocalStorageCacheBackend.js +0 -78
  119. package/cjs/lib/middleware/CacheMiddleware.d.ts +0 -7
  120. package/cjs/lib/middleware/CacheMiddleware.js +0 -107
  121. package/cjs/lib/middleware/LoggingMiddleware.d.ts +0 -7
  122. package/cjs/lib/middleware/LoggingMiddleware.js +0 -95
  123. package/esm/Mocking.d.ts +0 -23
  124. package/esm/Mocking.js +0 -77
  125. package/esm/__tests__/mock/ExampleApis.d.ts +0 -3
  126. package/esm/__tests__/mock/ExampleApis.js +0 -16
  127. package/esm/lib/Api.d.ts +0 -32
  128. package/esm/lib/Api.js +0 -123
  129. package/esm/lib/ApiTypes.d.ts +0 -102
  130. package/esm/lib/ApiTypes.js +0 -28
  131. package/esm/lib/ApiUtils.d.ts +0 -13
  132. package/esm/lib/ApiUtils.js +0 -57
  133. package/esm/lib/Caching.d.ts +0 -9
  134. package/esm/lib/Caching.js +0 -82
  135. package/esm/lib/Endpoint.d.ts +0 -30
  136. package/esm/lib/Endpoint.js +0 -119
  137. package/esm/lib/EndpointBuilder.d.ts +0 -12
  138. package/esm/lib/EndpointBuilder.js +0 -25
  139. package/esm/lib/Mocking.d.ts +0 -23
  140. package/esm/lib/Mocking.js +0 -77
  141. package/esm/lib/RequestContext.d.ts +0 -28
  142. package/esm/lib/RequestContext.js +0 -164
  143. package/esm/lib/Requester.d.ts +0 -2
  144. package/esm/lib/Requester.js +0 -161
  145. package/esm/lib/Utils.d.ts +0 -1
  146. package/esm/lib/Utils.js +0 -0
  147. package/esm/lib/backend/AxiosBackend.d.ts +0 -10
  148. package/esm/lib/backend/AxiosBackend.js +0 -95
  149. package/esm/lib/backend/AxiosRequestBackend.d.ts +0 -11
  150. package/esm/lib/backend/AxiosRequestBackend.js +0 -96
  151. package/esm/lib/backend/FetchBackend.d.ts +0 -8
  152. package/esm/lib/backend/FetchBackend.js +0 -143
  153. package/esm/lib/backend/FetchRequestBackend.d.ts +0 -9
  154. package/esm/lib/backend/FetchRequestBackend.js +0 -148
  155. package/esm/lib/backend/RequestBackend.d.ts +0 -11
  156. package/esm/lib/cache/CacheBackend.d.ts +0 -6
  157. package/esm/lib/cache/CacheBackend.js +0 -1
  158. package/esm/lib/cache/Caching.d.ts +0 -10
  159. package/esm/lib/cache/Caching.js +0 -81
  160. package/esm/lib/cache/LocalForageCacheBackend.d.ts +0 -9
  161. package/esm/lib/cache/LocalForageCacheBackend.js +0 -23
  162. package/esm/lib/cache/LocalStorageCacheBackend.d.ts +0 -7
  163. package/esm/lib/cache/LocalStorageCacheBackend.js +0 -76
  164. package/esm/lib/middleware/CacheMiddleware.d.ts +0 -7
  165. package/esm/lib/middleware/CacheMiddleware.js +0 -105
  166. package/esm/lib/middleware/LoggingMiddleware.d.ts +0 -7
  167. package/esm/lib/middleware/LoggingMiddleware.js +0 -92
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.convertToRequestError = exports.isRequestError = exports.RequestErrorCode = void 0;
4
+ exports.RequestErrorCode = {
5
+ MISC_UNKNOWN_ERROR: "misc/unknown-error",
6
+ REQUEST_NETWORK_ERROR: "request/network-error",
7
+ REQUEST_INVALID_STATUS: "request/invalid-status",
8
+ REQUEST_INVALID_CONFIG: "request/invalid-config",
9
+ };
10
+ var isRequestError = function (error) {
11
+ return "isRequestError" in error;
12
+ };
13
+ exports.isRequestError = isRequestError;
14
+ var convertToRequestError = function (config) {
15
+ var error = config.error, response = config.response, code = config.code;
16
+ return Object.assign(error, {
17
+ name: error.name === "Error" ? "RequestError" : error.name,
18
+ response: response,
19
+ code: code,
20
+ isRequestError: true,
21
+ });
22
+ };
23
+ exports.convertToRequestError = convertToRequestError;
@@ -1,2 +1,3 @@
1
1
  import { ApiResponse, Body, Query, RequestConfig, RequestHost } from "./ApiTypes";
2
- export declare const submit: <R, P extends string | undefined, Q extends Query | undefined, B extends Body | undefined>(host: RequestHost, config: RequestConfig<P, Q, B>) => Promise<ApiResponse<R>>;
2
+ import { EndpointMockingConfig } from "./MockingTypes";
3
+ export declare const submit: <R, P extends string | undefined, Q extends Query | undefined, B extends Body | undefined>(host: RequestHost, config: RequestConfig<P, Q, B>, mocking: EndpointMockingConfig<R, P, Q, B> | null | undefined) => Promise<ApiResponse<R>>;
package/cjs/Requester.js CHANGED
@@ -1,4 +1,15 @@
1
1
  "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
2
13
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
14
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
15
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -38,18 +49,27 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
38
49
  Object.defineProperty(exports, "__esModule", { value: true });
39
50
  exports.submit = void 0;
40
51
  var ApiUtils = require("./ApiUtils");
52
+ var ApiUtils_1 = require("./ApiUtils");
41
53
  var RequestContext_1 = require("./RequestContext");
42
54
  var Api = require("./Api");
43
55
  var ApiConstants_1 = require("./ApiConstants");
56
+ var retry_1 = require("./util/retry");
57
+ var MockRequestBackend_1 = require("./backend/MockRequestBackend");
58
+ var RequestError_1 = require("./RequestError");
44
59
  var locks = {};
45
60
  var runningOperations = {};
46
- var submit = function (host, config) { return __awaiter(void 0, void 0, void 0, function () {
47
- var computedConfig, context, key, sameRequest, lock, lockedContext, response, successEventResult, error_1;
61
+ var MOCK_REQUEST_BACKEND = new MockRequestBackend_1.default();
62
+ var submit = function (host, config, mocking) { return __awaiter(void 0, void 0, void 0, function () {
63
+ var computedConfig, backend, context, key, sameRequest, lock, lockedContext, response, successEventResult, error_1;
48
64
  return __generator(this, function (_a) {
49
65
  switch (_a.label) {
50
66
  case 0:
51
67
  computedConfig = host.computeConfig(config);
52
- context = new RequestContext_1.default(host, computedConfig, host.computePath(host.path, config));
68
+ backend = mocking ? MOCK_REQUEST_BACKEND : Api.getRequestBackend();
69
+ if (!backend) {
70
+ throw new Error("[api-def] Please specify a backend you wish to use, this can be done either with 'setRequestBackend()'");
71
+ }
72
+ context = new RequestContext_1.default(backend, host, computedConfig, host.computePath(host.path, config), mocking);
53
73
  key = context.key;
54
74
  sameRequest = runningOperations[key];
55
75
  if (sameRequest) {
@@ -94,87 +114,153 @@ var submit = function (host, config) { return __awaiter(void 0, void 0, void 0,
94
114
  exports.submit = submit;
95
115
  var defaultBackendMessageShown = false;
96
116
  var makeRequest = function (context) { return __awaiter(void 0, void 0, void 0, function () {
97
- var backend, beforeSendEventResult, _a, promise, canceler, response, parsedResponse, error_2, errorResponse, _b, errorEventResult, retry, shouldNaturallyRetry, shouldRetry, unrecoverableErrorEventResult;
98
- var _c;
99
- return __generator(this, function (_d) {
100
- switch (_d.label) {
117
+ var beforeSendEventResult, maxRetries, retryOpts, performRequest, response;
118
+ var _a;
119
+ return __generator(this, function (_b) {
120
+ switch (_b.label) {
101
121
  case 0:
102
- backend = Api.requestBackend;
103
- if (!backend) {
104
- throw new Error("[api-def] Please specify a backend you wish to use, this can be done either with 'setRequestBackend()'");
105
- }
106
122
  if (process.env.NODE_ENV === "development") {
107
- if (Api.requestBackendIsDefault && !defaultBackendMessageShown) {
123
+ if (Api.isRequestBackendDefault() && !defaultBackendMessageShown) {
108
124
  defaultBackendMessageShown = true;
109
125
  console.warn("[api-def] Using default fetch backend, you can use a different one with 'setRequestBackend()' (dev only message)");
110
126
  }
111
127
  }
112
- context.stats.attempt++;
113
128
  return [4 /*yield*/, context.triggerEvent(ApiConstants_1.RequestEvent.BeforeSend)];
114
129
  case 1:
115
- beforeSendEventResult = _d.sent();
130
+ beforeSendEventResult = _b.sent();
116
131
  if (beforeSendEventResult &&
117
132
  beforeSendEventResult.type === ApiConstants_1.EventResultType.Respond) {
118
133
  return [2 /*return*/, (context.response = beforeSendEventResult.response)];
119
134
  }
120
- _d.label = 2;
135
+ maxRetries = ((_a = context.computedConfig) === null || _a === void 0 ? void 0 : _a.retry) || 0;
136
+ retryOpts = {
137
+ retries: maxRetries,
138
+ // assume most users won't want to tune the delay between retries
139
+ minTimeout: 1 * 1000,
140
+ maxTimeout: 5 * 1000,
141
+ randomize: true,
142
+ };
143
+ context.stats.attempt = 0;
144
+ performRequest = function (fnBail, attemptCount) { return __awaiter(void 0, void 0, void 0, function () {
145
+ var _a, promise, canceler, response_1, parsedResponse, rawError_1, error, errorEventResult, shouldNaturallyRetry, forceRetry, unrecoverableErrorEventResult;
146
+ return __generator(this, function (_b) {
147
+ switch (_b.label) {
148
+ case 0:
149
+ context.stats.attempt++;
150
+ _b.label = 1;
151
+ case 1:
152
+ _b.trys.push([1, 4, , 8]);
153
+ _a = context.backend.makeRequest(context), promise = _a.promise, canceler = _a.canceler;
154
+ context.addCanceller(canceler);
155
+ return [4 /*yield*/, promise];
156
+ case 2:
157
+ response_1 = _b.sent();
158
+ return [4 /*yield*/, parseResponse(context, response_1)];
159
+ case 3:
160
+ parsedResponse = (_b.sent());
161
+ if (!ApiUtils_1.isAcceptableStatus(parsedResponse.status, context.computedConfig.acceptableStatus)) {
162
+ throw RequestError_1.convertToRequestError({
163
+ error: new Error("[api-def] Invalid response status code '" + parsedResponse.status + "'"),
164
+ response: parsedResponse,
165
+ code: RequestError_1.RequestErrorCode.REQUEST_INVALID_STATUS,
166
+ });
167
+ }
168
+ context.response = parsedResponse;
169
+ return [2 /*return*/, (parsedResponse)];
170
+ case 4:
171
+ rawError_1 = _b.sent();
172
+ if (context.cancelled) {
173
+ rawError_1.isCancelledRequest = true;
174
+ }
175
+ return [4 /*yield*/, parseError(context, rawError_1)];
176
+ case 5:
177
+ error = _b.sent();
178
+ context.error = error;
179
+ context.response = error.response;
180
+ // transform array buffer responses to objs
181
+ if (context.response) {
182
+ ApiUtils.parseResponseDataToObject(context.response);
183
+ }
184
+ return [4 /*yield*/, context.triggerEvent(ApiConstants_1.RequestEvent.Error)];
185
+ case 6:
186
+ errorEventResult = _b.sent();
187
+ if ((errorEventResult === null || errorEventResult === void 0 ? void 0 : errorEventResult.type) === ApiConstants_1.EventResultType.Respond) {
188
+ return [2 /*return*/, errorEventResult.response];
189
+ }
190
+ shouldNaturallyRetry = ApiUtils.isNetworkError(error);
191
+ if (shouldNaturallyRetry) {
192
+ throw error;
193
+ }
194
+ forceRetry = (errorEventResult === null || errorEventResult === void 0 ? void 0 : errorEventResult.type) === ApiConstants_1.EventResultType.Retry;
195
+ if (forceRetry) {
196
+ return [2 /*return*/, performRequest(fnBail, attemptCount)];
197
+ }
198
+ return [4 /*yield*/, context.triggerEvent(ApiConstants_1.RequestEvent.UnrecoverableError)];
199
+ case 7:
200
+ unrecoverableErrorEventResult = _b.sent();
201
+ if (unrecoverableErrorEventResult) {
202
+ if (unrecoverableErrorEventResult.type === ApiConstants_1.EventResultType.Respond) {
203
+ return [2 /*return*/, unrecoverableErrorEventResult.response];
204
+ }
205
+ }
206
+ fnBail(error);
207
+ return [3 /*break*/, 8];
208
+ case 8: return [2 /*return*/];
209
+ }
210
+ });
211
+ }); };
212
+ return [4 /*yield*/, retry_1.default(performRequest, retryOpts)];
213
+ case 2:
214
+ response = _b.sent();
215
+ return [2 /*return*/, (response)];
216
+ }
217
+ });
218
+ }); };
219
+ var parseResponse = function (context, response, error) { return __awaiter(void 0, void 0, void 0, function () {
220
+ var parsedResponse;
221
+ return __generator(this, function (_a) {
222
+ switch (_a.label) {
223
+ case 0:
224
+ if (!response) return [3 /*break*/, 2];
225
+ return [4 /*yield*/, context.backend.convertResponse(context, response, error)];
226
+ case 1:
227
+ parsedResponse = _a.sent();
228
+ if (parsedResponse) {
229
+ ApiUtils.parseResponseDataToObject(parsedResponse);
230
+ }
231
+ return [2 /*return*/, parsedResponse];
232
+ case 2: return [2 /*return*/, response];
233
+ }
234
+ });
235
+ }); };
236
+ var parseError = function (context, rawError) { return __awaiter(void 0, void 0, void 0, function () {
237
+ var error, extractedResponse, errorResponse, code, errorInfo;
238
+ return __generator(this, function (_a) {
239
+ switch (_a.label) {
240
+ case 0:
241
+ if (!RequestError_1.isRequestError(rawError)) return [3 /*break*/, 1];
242
+ error = rawError;
243
+ return [3 /*break*/, 5];
244
+ case 1: return [4 /*yield*/, context.backend.extractResponseFromError(rawError)];
121
245
  case 2:
122
- _d.trys.push([2, 5, , 11]);
123
- _a = backend.makeRequest(context), promise = _a.promise, canceler = _a.canceler;
124
- context.addCanceller(canceler);
125
- return [4 /*yield*/, promise];
246
+ extractedResponse = _a.sent();
247
+ errorResponse = undefined;
248
+ if (!(extractedResponse !== undefined)) return [3 /*break*/, 4];
249
+ return [4 /*yield*/, parseResponse(context, extractedResponse, true)];
126
250
  case 3:
127
- response = _d.sent();
128
- return [4 /*yield*/, backend.convertResponse(context, response)];
251
+ errorResponse = _a.sent();
252
+ _a.label = 4;
129
253
  case 4:
130
- parsedResponse = _d.sent();
131
- context.response = parsedResponse;
132
- return [2 /*return*/, parsedResponse];
133
- case 5:
134
- error_2 = _d.sent();
135
- if (context.cancelled) {
136
- error_2.isCancelledRequest = true;
137
- }
138
- context.error = error_2;
139
- return [4 /*yield*/, backend.extractResponseFromError(error_2)];
140
- case 6:
141
- errorResponse = _d.sent();
142
- if (!(errorResponse !== undefined)) return [3 /*break*/, 8];
143
- _b = context;
144
- return [4 /*yield*/, backend.convertResponse(context, errorResponse, true)];
145
- case 7:
146
- _b.response = _d.sent();
147
- error_2.response = context.response;
148
- _d.label = 8;
149
- case 8:
150
- // transform array buffer responses to objs
151
- if (context.response) {
152
- ApiUtils.parseResponseDataToObject(context.response);
153
- }
154
- return [4 /*yield*/, context.triggerEvent(ApiConstants_1.RequestEvent.Error)];
155
- case 9:
156
- errorEventResult = _d.sent();
157
- if ((errorEventResult === null || errorEventResult === void 0 ? void 0 : errorEventResult.type) === ApiConstants_1.EventResultType.Respond) {
158
- return [2 /*return*/, errorEventResult.response];
159
- }
160
- retry = (_c = context.computedConfig) === null || _c === void 0 ? void 0 : _c.retry;
161
- shouldNaturallyRetry = ApiUtils.isNetworkError(error_2) && retry && context.stats.attempt < retry;
162
- shouldRetry = (errorEventResult === null || errorEventResult === void 0 ? void 0 : errorEventResult.type) === ApiConstants_1.EventResultType.Retry ||
163
- shouldNaturallyRetry;
164
- // retry request with same config
165
- if (shouldRetry) {
166
- return [2 /*return*/, makeRequest(context)];
167
- }
168
- return [4 /*yield*/, context.triggerEvent(ApiConstants_1.RequestEvent.UnrecoverableError)];
169
- case 10:
170
- unrecoverableErrorEventResult = _d.sent();
171
- if (unrecoverableErrorEventResult) {
172
- if (unrecoverableErrorEventResult.type === ApiConstants_1.EventResultType.Respond) {
173
- return [2 /*return*/, unrecoverableErrorEventResult.response];
254
+ code = ApiUtils_1.isNetworkError(rawError) ? RequestError_1.RequestErrorCode.REQUEST_NETWORK_ERROR : RequestError_1.RequestErrorCode.MISC_UNKNOWN_ERROR;
255
+ if (errorResponse) {
256
+ if (!ApiUtils_1.isAcceptableStatus(errorResponse.status, context.computedConfig.acceptableStatus)) {
257
+ code = RequestError_1.RequestErrorCode.REQUEST_INVALID_STATUS;
174
258
  }
175
259
  }
176
- throw error_2;
177
- case 11: return [2 /*return*/];
260
+ errorInfo = context.backend.getErrorInfo(rawError, errorResponse);
261
+ error = RequestError_1.convertToRequestError(__assign({ error: rawError, response: errorResponse, code: code }, errorInfo));
262
+ _a.label = 5;
263
+ case 5: return [2 /*return*/, error];
178
264
  }
179
265
  });
180
266
  }); };
@@ -0,0 +1 @@
1
+ export declare const textDecode: (inputArrayOrBuffer: any, options?: any) => string;
@@ -0,0 +1,139 @@
1
+ "use strict";
2
+ /* eslint-disable prefer-const */
3
+ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.textDecode = void 0;
6
+ // polyfill from https://github.com/anonyco/FastestSmallestTextEncoderDecoder/blob/master/EncoderDecoderTogether.src.js
7
+ var textDecode = function (inputArrayOrBuffer, options) {
8
+ if (typeof TextDecoder !== "undefined") {
9
+ return new TextDecoder("utf-8").decode(inputArrayOrBuffer);
10
+ }
11
+ var fromCharCode = String.fromCharCode;
12
+ var Object_prototype_toString = ({}).toString;
13
+ var sharedArrayBufferString = Object_prototype_toString.call(window["SharedArrayBuffer"]);
14
+ var undefinedObjectString = Object_prototype_toString();
15
+ var NativeUint8Array = window.Uint8Array;
16
+ var patchedU8Array = NativeUint8Array || Array;
17
+ var nativeArrayBuffer = NativeUint8Array ? ArrayBuffer : patchedU8Array;
18
+ var arrayBuffer_isView = nativeArrayBuffer.isView || function (x) {
19
+ return x && "length" in x;
20
+ };
21
+ var arrayBufferString = Object_prototype_toString.call(nativeArrayBuffer.prototype);
22
+ var tmpBufferU16 = new (NativeUint8Array ? Uint16Array : patchedU8Array)(32);
23
+ var inputAs8 = inputArrayOrBuffer;
24
+ var asObjectString;
25
+ if (!arrayBuffer_isView(inputAs8)) {
26
+ asObjectString = Object_prototype_toString.call(inputAs8);
27
+ if (asObjectString !== arrayBufferString && asObjectString !== sharedArrayBufferString && asObjectString !== undefinedObjectString)
28
+ throw TypeError("Failed to execute 'decode' on 'TextDecoder': The provided value is not of type '(ArrayBuffer or ArrayBufferView)'");
29
+ inputAs8 = NativeUint8Array ? new patchedU8Array(inputAs8) : inputAs8 || [];
30
+ }
31
+ var resultingString = "", tmpStr = "", index = 0, len = inputAs8.length | 0, lenMinus32 = len - 32 | 0, nextEnd = 0, cp0 = 0, codePoint = 0, minBits = 0, cp1 = 0, pos = 0, tmp = -1;
32
+ // Note that tmp represents the 2nd half of a surrogate pair incase a surrogate gets divided between blocks
33
+ for (; index < len;) {
34
+ nextEnd = index <= lenMinus32 ? 32 : len - index | 0;
35
+ for (; pos < nextEnd; index = index + 1 | 0, pos = pos + 1 | 0) {
36
+ cp0 = inputAs8[index] & 0xff;
37
+ switch (cp0 >> 4) {
38
+ case 15:
39
+ cp1 = inputAs8[index = index + 1 | 0] & 0xff;
40
+ if ((cp1 >> 6) !== 2 || 247 < cp0) {
41
+ index = index - 1 | 0;
42
+ break;
43
+ }
44
+ codePoint = ((cp0 & 7) << 6) | (cp1 & 63);
45
+ minBits = 5; // 20 ensures it never passes -> all invalid replacements
46
+ cp0 = 0x100; // keep track of th bit size
47
+ // eslint-disable-next-line no-fallthrough
48
+ case 14:
49
+ cp1 = inputAs8[index = index + 1 | 0] & 0xff;
50
+ codePoint <<= 6;
51
+ codePoint |= ((cp0 & 15) << 6) | (cp1 & 63);
52
+ minBits = (cp1 >> 6) === 2 ? minBits + 4 | 0 : 24; // 24 ensures it never passes -> all invalid replacements
53
+ cp0 = (cp0 + 0x100) & 0x300; // keep track of th bit size
54
+ // eslint-disable-next-line no-fallthrough
55
+ case 13:
56
+ case 12:
57
+ cp1 = inputAs8[index = index + 1 | 0] & 0xff;
58
+ codePoint <<= 6;
59
+ codePoint |= ((cp0 & 31) << 6) | cp1 & 63;
60
+ minBits = minBits + 7 | 0;
61
+ // Now, process the code point
62
+ if (index < len && (cp1 >> 6) === 2 && (codePoint >> minBits) && codePoint < 0x110000) {
63
+ cp0 = codePoint;
64
+ codePoint = codePoint - 0x10000 | 0;
65
+ if (0 <= codePoint /*0xffff < codePoint*/) { // BMP code point
66
+ //nextEnd = nextEnd - 1|0;
67
+ tmp = (codePoint >> 10) + 0xD800 | 0; // highSurrogate
68
+ cp0 = (codePoint & 0x3ff) + 0xDC00 | 0; // lowSurrogate (will be inserted later in the switch-statement)
69
+ if (pos < 31) { // notice 31 instead of 32
70
+ tmpBufferU16[pos] = tmp;
71
+ pos = pos + 1 | 0;
72
+ tmp = -1;
73
+ }
74
+ else { // else, we are at the end of the inputAs8 and let tmp0 be filled in later on
75
+ // NOTE that cp1 is being used as a temporary variable for the swapping of tmp with cp0
76
+ cp1 = tmp;
77
+ tmp = cp0;
78
+ cp0 = cp1;
79
+ }
80
+ }
81
+ else
82
+ nextEnd = nextEnd + 1 | 0; // because we are advancing i without advancing pos
83
+ }
84
+ else {
85
+ // invalid code point means replacing the whole thing with null replacement characters
86
+ cp0 >>= 8;
87
+ index = index - cp0 - 1 | 0; // reset index back to what it was before
88
+ cp0 = 0xfffd;
89
+ }
90
+ // Finally, reset the variables for the next go-around
91
+ minBits = 0;
92
+ codePoint = 0;
93
+ nextEnd = index <= lenMinus32 ? 32 : len - index | 0;
94
+ /*case 11:
95
+ case 10:
96
+ case 9:
97
+ case 8:
98
+ codePoint ? codePoint = 0 : cp0 = 0xfffd; // fill with invalid replacement character
99
+ case 7:
100
+ case 6:
101
+ case 5:
102
+ case 4:
103
+ case 3:
104
+ case 2:
105
+ case 1:
106
+ case 0:
107
+ tmpBufferU16[pos] = cp0;
108
+ continue;*/
109
+ // eslint-disable-next-line no-fallthrough
110
+ default:
111
+ tmpBufferU16[pos] = cp0; // fill with invalid replacement character
112
+ continue;
113
+ case 11:
114
+ case 10:
115
+ case 9:
116
+ case 8:
117
+ }
118
+ tmpBufferU16[pos] = 0xfffd; // fill with invalid replacement character
119
+ }
120
+ tmpStr += fromCharCode(tmpBufferU16[0], tmpBufferU16[1], tmpBufferU16[2], tmpBufferU16[3], tmpBufferU16[4], tmpBufferU16[5], tmpBufferU16[6], tmpBufferU16[7], tmpBufferU16[8], tmpBufferU16[9], tmpBufferU16[10], tmpBufferU16[11], tmpBufferU16[12], tmpBufferU16[13], tmpBufferU16[14], tmpBufferU16[15], tmpBufferU16[16], tmpBufferU16[17], tmpBufferU16[18], tmpBufferU16[19], tmpBufferU16[20], tmpBufferU16[21], tmpBufferU16[22], tmpBufferU16[23], tmpBufferU16[24], tmpBufferU16[25], tmpBufferU16[26], tmpBufferU16[27], tmpBufferU16[28], tmpBufferU16[29], tmpBufferU16[30], tmpBufferU16[31]);
121
+ if (pos < 32)
122
+ tmpStr = tmpStr.slice(0, pos - 32 | 0); //-(32-pos));
123
+ if (index < len) {
124
+ //fromCharCode.apply(0, tmpBufferU16 : NativeUint8Array ? tmpBufferU16.subarray(0,pos) : tmpBufferU16.slice(0,pos));
125
+ tmpBufferU16[0] = tmp;
126
+ pos = (~tmp) >>> 31; //tmp !== -1 ? 1 : 0;
127
+ tmp = -1;
128
+ if (tmpStr.length < resultingString.length)
129
+ continue;
130
+ }
131
+ else if (tmp !== -1) {
132
+ tmpStr += fromCharCode(tmp);
133
+ }
134
+ resultingString += tmpStr;
135
+ tmpStr = "";
136
+ }
137
+ return (resultingString);
138
+ };
139
+ exports.textDecode = textDecode;
package/cjs/Utils.d.ts CHANGED
@@ -3,3 +3,12 @@ export declare const padNumber: (stringOrNumber: string | number, maxLength: num
3
3
  export declare type EnumOf<T extends Record<string, any>> = T[keyof T];
4
4
  export declare type Fetch = typeof window.fetch;
5
5
  export declare const getGlobalFetch: () => Fetch | undefined;
6
+ export declare const noop: () => void;
7
+ /**
8
+ * Just used to simulate lag, or loading times.
9
+ * @param value The value you want to return after the delay
10
+ * @param delayMs The delay in ms
11
+ * @returns The `value` param as a Promise
12
+ */
13
+ export declare const delayThenReturn: <T>(value: T, delayMs: number) => Promise<T>;
14
+ export declare const randInt: (min: number, max: number) => number;
package/cjs/Utils.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getGlobalFetch = exports.padNumber = exports.assign = void 0;
3
+ exports.randInt = exports.delayThenReturn = exports.noop = exports.getGlobalFetch = exports.padNumber = exports.assign = void 0;
4
4
  // polyfill from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
5
5
  exports.assign = Object.assign || function (target, varArgs) {
6
6
  if (target === null || target === undefined) {
@@ -35,3 +35,32 @@ var getGlobalFetch = function () {
35
35
  return window.fetch.bind(window);
36
36
  };
37
37
  exports.getGlobalFetch = getGlobalFetch;
38
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
39
+ var noop = function () {
40
+ };
41
+ exports.noop = noop;
42
+ /**
43
+ * Just used to simulate lag, or loading times.
44
+ * @param value The value you want to return after the delay
45
+ * @param delayMs The delay in ms
46
+ * @returns The `value` param as a Promise
47
+ */
48
+ var delayThenReturn = function (value, delayMs) {
49
+ return (new Promise(function (resolve) {
50
+ if (delayMs > 0) {
51
+ setTimeout(function () {
52
+ resolve(value);
53
+ }, delayMs);
54
+ }
55
+ else {
56
+ resolve(value);
57
+ }
58
+ }));
59
+ };
60
+ exports.delayThenReturn = delayThenReturn;
61
+ var randInt = function (min, max) {
62
+ var minI = Math.ceil(min);
63
+ var maxI = Math.floor(max);
64
+ return (Math.floor(Math.random() * (maxI - minI + 1)) + minI);
65
+ };
66
+ exports.randInt = randInt;
@@ -1,11 +1,12 @@
1
- import RequestBackend, { RequestOperation } from "./RequestBackend";
1
+ import RequestBackend, { RequestBackendErrorInfo, RequestOperation } from "./RequestBackend";
2
2
  import { ApiResponse } from "../ApiTypes";
3
- import type { AxiosError, AxiosResponse } from "axios";
3
+ import type { AxiosError, AxiosResponse, AxiosStatic } from "axios";
4
4
  import RequestContext from "../RequestContext";
5
5
  export declare const isAxiosError: (error: Error) => error is AxiosError<any>;
6
6
  export default class AxiosRequestBackend implements RequestBackend<AxiosResponse> {
7
- constructor(axiosLibrary: any);
7
+ constructor(axiosLibrary: AxiosStatic);
8
8
  extractResponseFromError(error: Error): Promise<AxiosResponse | null | undefined>;
9
9
  convertResponse<T>(context: RequestContext, response: AxiosResponse): Promise<ApiResponse<T>>;
10
10
  makeRequest(context: RequestContext): RequestOperation<AxiosResponse>;
11
+ getErrorInfo(error: Error, response: ApiResponse | undefined | null): RequestBackendErrorInfo | undefined;
11
12
  }
@@ -83,6 +83,9 @@ var AxiosRequestBackend = /** @class */ (function () {
83
83
  canceler: function () { return canceler && canceler(); },
84
84
  };
85
85
  };
86
+ AxiosRequestBackend.prototype.getErrorInfo = function (error, response) {
87
+ return undefined;
88
+ };
86
89
  return AxiosRequestBackend;
87
90
  }());
88
91
  exports.default = AxiosRequestBackend;
@@ -1,4 +1,4 @@
1
- import RequestBackend, { RequestOperation } from "./RequestBackend";
1
+ import RequestBackend, { RequestBackendErrorInfo, RequestOperation } from "./RequestBackend";
2
2
  import { ApiResponse } from "../ApiTypes";
3
3
  import RequestContext from "../RequestContext";
4
4
  import { Fetch } from "../Utils";
@@ -12,4 +12,5 @@ export default class FetchRequestBackend implements RequestBackend<Response> {
12
12
  __text?: string;
13
13
  }, error?: boolean): Promise<ApiResponse<T>>;
14
14
  makeRequest(context: RequestContext): RequestOperation<Response>;
15
+ getErrorInfo(error: Error, response: ApiResponse | undefined | null): RequestBackendErrorInfo | undefined;
15
16
  }
@@ -89,7 +89,7 @@ var FetchRequestBackend = /** @class */ (function () {
89
89
  };
90
90
  FetchRequestBackend.prototype.convertResponse = function (context, response, error) {
91
91
  return __awaiter(this, void 0, void 0, function () {
92
- var data, responseType, _a, error_1;
92
+ var data, responseType, _a, error_1, status;
93
93
  return __generator(this, function (_b) {
94
94
  switch (_b.label) {
95
95
  case 0:
@@ -124,11 +124,13 @@ var FetchRequestBackend = /** @class */ (function () {
124
124
  throw Object.assign(new Error("[api-def] Invalid '" + context.responseType + "' response, got: '" + response.__text + "'"), {
125
125
  response: response,
126
126
  });
127
- case 9: return [2 /*return*/, {
128
- data: data,
129
- status: response.status,
130
- headers: response.headers,
131
- }];
127
+ case 9:
128
+ status = response.status;
129
+ return [2 /*return*/, {
130
+ data: data,
131
+ status: status,
132
+ headers: response.headers,
133
+ }];
132
134
  }
133
135
  });
134
136
  });
@@ -184,7 +186,7 @@ var FetchRequestBackend = /** @class */ (function () {
184
186
  throw error;
185
187
  }
186
188
  if (softAbort) {
187
- throw new Error("Request was aborted");
189
+ throw new Error("[api-def] Request was aborted");
188
190
  }
189
191
  return response;
190
192
  });
@@ -198,6 +200,9 @@ var FetchRequestBackend = /** @class */ (function () {
198
200
  },
199
201
  };
200
202
  };
203
+ FetchRequestBackend.prototype.getErrorInfo = function (error, response) {
204
+ return undefined;
205
+ };
201
206
  return FetchRequestBackend;
202
207
  }());
203
208
  exports.default = FetchRequestBackend;
@@ -0,0 +1,10 @@
1
+ import RequestBackend, { RequestBackendErrorInfo, RequestOperation } from "./RequestBackend";
2
+ import { ApiResponse } from "../ApiTypes";
3
+ import RequestContext from "../RequestContext";
4
+ export default class MockRequestBackend implements RequestBackend<ApiResponse> {
5
+ convertResponse<T>(context: RequestContext, response: ApiResponse, error?: boolean): Promise<ApiResponse<T>>;
6
+ extractResponseFromError(error: Error): Promise<ApiResponse | null | undefined>;
7
+ private runRequest;
8
+ makeRequest(context: RequestContext): RequestOperation<ApiResponse>;
9
+ getErrorInfo(error: Error, response: ApiResponse | undefined | null): RequestBackendErrorInfo | undefined;
10
+ }