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.
- package/README.md +1 -1
- package/cjs/Api.d.ts +13 -15
- package/cjs/Api.js +28 -41
- package/cjs/ApiConstants.d.ts +28 -0
- package/cjs/ApiConstants.js +28 -0
- package/cjs/ApiTypes.d.ts +2 -7
- package/cjs/ApiUtils.d.ts +2 -10
- package/cjs/ApiUtils.js +24 -37
- package/cjs/Endpoint.d.ts +21 -5
- package/cjs/Endpoint.js +16 -31
- package/cjs/MockingTypes.d.ts +28 -0
- package/cjs/{lib/Utils.js → MockingTypes.js} +0 -0
- package/cjs/RequestContext.d.ts +9 -4
- package/cjs/RequestContext.js +4 -2
- package/cjs/RequestError.d.ts +21 -0
- package/cjs/RequestError.js +23 -0
- package/cjs/Requester.d.ts +2 -1
- package/cjs/Requester.js +153 -67
- package/cjs/TextDecoding.d.ts +1 -0
- package/cjs/TextDecoding.js +139 -0
- package/cjs/Utils.d.ts +9 -0
- package/cjs/Utils.js +30 -1
- package/cjs/backend/AxiosRequestBackend.d.ts +4 -3
- package/cjs/backend/AxiosRequestBackend.js +3 -0
- package/cjs/backend/FetchRequestBackend.d.ts +2 -1
- package/cjs/backend/FetchRequestBackend.js +12 -7
- package/cjs/backend/MockRequestBackend.d.ts +10 -0
- package/cjs/backend/MockRequestBackend.js +149 -0
- package/cjs/backend/RequestBackend.d.ts +4 -0
- package/cjs/cache/LocalForageCacheBackend.js +1 -0
- package/cjs/index.d.ts +1 -1
- package/cjs/index.js +2 -2
- package/cjs/util/retry/index.d.ts +3 -0
- package/cjs/util/retry/index.js +52 -0
- package/cjs/util/retry/lib/retry.d.ts +3 -0
- package/cjs/util/retry/lib/retry.js +54 -0
- package/cjs/util/retry/lib/retryOperation.d.ts +27 -0
- package/cjs/util/retry/lib/retryOperation.js +134 -0
- package/esm/Api.d.ts +13 -15
- package/esm/Api.js +24 -39
- package/esm/ApiConstants.d.ts +28 -0
- package/esm/ApiConstants.js +28 -0
- package/esm/ApiTypes.d.ts +2 -7
- package/esm/ApiUtils.d.ts +2 -10
- package/esm/ApiUtils.js +22 -35
- package/esm/Endpoint.d.ts +21 -5
- package/esm/Endpoint.js +16 -31
- package/esm/MockingTypes.d.ts +28 -0
- package/esm/{lib/backend/RequestBackend.js → MockingTypes.js} +0 -0
- package/esm/RequestContext.d.ts +9 -4
- package/esm/RequestContext.js +4 -2
- package/esm/RequestError.d.ts +21 -0
- package/esm/RequestError.js +18 -0
- package/esm/Requester.d.ts +2 -1
- package/esm/Requester.js +153 -67
- package/esm/TextDecoding.d.ts +1 -0
- package/esm/TextDecoding.js +135 -0
- package/esm/Utils.d.ts +9 -0
- package/esm/Utils.js +26 -0
- package/esm/backend/AxiosRequestBackend.d.ts +4 -3
- package/esm/backend/AxiosRequestBackend.js +3 -0
- package/esm/backend/FetchRequestBackend.d.ts +2 -1
- package/esm/backend/FetchRequestBackend.js +12 -7
- package/esm/backend/MockRequestBackend.d.ts +10 -0
- package/esm/backend/MockRequestBackend.js +147 -0
- package/esm/backend/RequestBackend.d.ts +4 -0
- package/esm/cache/LocalForageCacheBackend.js +1 -0
- package/esm/index.d.ts +1 -1
- package/esm/index.js +1 -1
- package/esm/util/retry/index.d.ts +3 -0
- package/esm/util/retry/index.js +50 -0
- package/esm/util/retry/lib/retry.d.ts +3 -0
- package/esm/util/retry/lib/retry.js +50 -0
- package/esm/util/retry/lib/retryOperation.d.ts +27 -0
- package/esm/util/retry/lib/retryOperation.js +132 -0
- package/package.json +29 -19
- package/CHANGELOG.md +0 -39
- package/cjs/Mocking.d.ts +0 -23
- package/cjs/Mocking.js +0 -81
- package/cjs/__tests__/mock/ExampleApis.d.ts +0 -3
- package/cjs/__tests__/mock/ExampleApis.js +0 -19
- package/cjs/lib/Api.d.ts +0 -32
- package/cjs/lib/Api.js +0 -126
- package/cjs/lib/ApiTypes.d.ts +0 -102
- package/cjs/lib/ApiTypes.js +0 -31
- package/cjs/lib/ApiUtils.d.ts +0 -13
- package/cjs/lib/ApiUtils.js +0 -60
- package/cjs/lib/Caching.d.ts +0 -9
- package/cjs/lib/Caching.js +0 -85
- package/cjs/lib/Endpoint.d.ts +0 -30
- package/cjs/lib/Endpoint.js +0 -121
- package/cjs/lib/EndpointBuilder.d.ts +0 -12
- package/cjs/lib/EndpointBuilder.js +0 -27
- package/cjs/lib/Mocking.d.ts +0 -23
- package/cjs/lib/Mocking.js +0 -80
- package/cjs/lib/RequestContext.d.ts +0 -28
- package/cjs/lib/RequestContext.js +0 -166
- package/cjs/lib/Requester.d.ts +0 -2
- package/cjs/lib/Requester.js +0 -164
- package/cjs/lib/Utils.d.ts +0 -1
- package/cjs/lib/backend/AxiosBackend.d.ts +0 -10
- package/cjs/lib/backend/AxiosBackend.js +0 -98
- package/cjs/lib/backend/AxiosRequestBackend.d.ts +0 -11
- package/cjs/lib/backend/AxiosRequestBackend.js +0 -99
- package/cjs/lib/backend/FetchBackend.d.ts +0 -8
- package/cjs/lib/backend/FetchBackend.js +0 -145
- package/cjs/lib/backend/FetchRequestBackend.d.ts +0 -9
- package/cjs/lib/backend/FetchRequestBackend.js +0 -150
- package/cjs/lib/backend/RequestBackend.d.ts +0 -11
- package/cjs/lib/backend/RequestBackend.js +0 -2
- package/cjs/lib/cache/CacheBackend.d.ts +0 -6
- package/cjs/lib/cache/CacheBackend.js +0 -2
- package/cjs/lib/cache/Caching.d.ts +0 -10
- package/cjs/lib/cache/Caching.js +0 -84
- package/cjs/lib/cache/LocalForageCacheBackend.d.ts +0 -9
- package/cjs/lib/cache/LocalForageCacheBackend.js +0 -25
- package/cjs/lib/cache/LocalStorageCacheBackend.d.ts +0 -7
- package/cjs/lib/cache/LocalStorageCacheBackend.js +0 -78
- package/cjs/lib/middleware/CacheMiddleware.d.ts +0 -7
- package/cjs/lib/middleware/CacheMiddleware.js +0 -107
- package/cjs/lib/middleware/LoggingMiddleware.d.ts +0 -7
- package/cjs/lib/middleware/LoggingMiddleware.js +0 -95
- package/esm/Mocking.d.ts +0 -23
- package/esm/Mocking.js +0 -77
- package/esm/__tests__/mock/ExampleApis.d.ts +0 -3
- package/esm/__tests__/mock/ExampleApis.js +0 -16
- package/esm/lib/Api.d.ts +0 -32
- package/esm/lib/Api.js +0 -123
- package/esm/lib/ApiTypes.d.ts +0 -102
- package/esm/lib/ApiTypes.js +0 -28
- package/esm/lib/ApiUtils.d.ts +0 -13
- package/esm/lib/ApiUtils.js +0 -57
- package/esm/lib/Caching.d.ts +0 -9
- package/esm/lib/Caching.js +0 -82
- package/esm/lib/Endpoint.d.ts +0 -30
- package/esm/lib/Endpoint.js +0 -119
- package/esm/lib/EndpointBuilder.d.ts +0 -12
- package/esm/lib/EndpointBuilder.js +0 -25
- package/esm/lib/Mocking.d.ts +0 -23
- package/esm/lib/Mocking.js +0 -77
- package/esm/lib/RequestContext.d.ts +0 -28
- package/esm/lib/RequestContext.js +0 -164
- package/esm/lib/Requester.d.ts +0 -2
- package/esm/lib/Requester.js +0 -161
- package/esm/lib/Utils.d.ts +0 -1
- package/esm/lib/Utils.js +0 -0
- package/esm/lib/backend/AxiosBackend.d.ts +0 -10
- package/esm/lib/backend/AxiosBackend.js +0 -95
- package/esm/lib/backend/AxiosRequestBackend.d.ts +0 -11
- package/esm/lib/backend/AxiosRequestBackend.js +0 -96
- package/esm/lib/backend/FetchBackend.d.ts +0 -8
- package/esm/lib/backend/FetchBackend.js +0 -143
- package/esm/lib/backend/FetchRequestBackend.d.ts +0 -9
- package/esm/lib/backend/FetchRequestBackend.js +0 -148
- package/esm/lib/backend/RequestBackend.d.ts +0 -11
- package/esm/lib/cache/CacheBackend.d.ts +0 -6
- package/esm/lib/cache/CacheBackend.js +0 -1
- package/esm/lib/cache/Caching.d.ts +0 -10
- package/esm/lib/cache/Caching.js +0 -81
- package/esm/lib/cache/LocalForageCacheBackend.d.ts +0 -9
- package/esm/lib/cache/LocalForageCacheBackend.js +0 -23
- package/esm/lib/cache/LocalStorageCacheBackend.d.ts +0 -7
- package/esm/lib/cache/LocalStorageCacheBackend.js +0 -76
- package/esm/lib/middleware/CacheMiddleware.d.ts +0 -7
- package/esm/lib/middleware/CacheMiddleware.js +0 -105
- package/esm/lib/middleware/LoggingMiddleware.d.ts +0 -7
- 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;
|
package/cjs/Requester.d.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
import { ApiResponse, Body, Query, RequestConfig, RequestHost } from "./ApiTypes";
|
|
2
|
-
|
|
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
|
|
47
|
-
|
|
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
|
-
|
|
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
|
|
98
|
-
var
|
|
99
|
-
return __generator(this, function (
|
|
100
|
-
switch (
|
|
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.
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
return [4 /*yield*/,
|
|
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
|
-
|
|
128
|
-
|
|
251
|
+
errorResponse = _a.sent();
|
|
252
|
+
_a.label = 4;
|
|
129
253
|
case 4:
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
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
|
-
|
|
177
|
-
|
|
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:
|
|
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:
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
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
|
+
}
|