api-def 0.12.1 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/README.md +3 -0
  2. package/bin/index.js +312 -313
  3. package/cjs/Api.d.ts +1 -1
  4. package/cjs/Api.js +99 -145
  5. package/cjs/ApiTypes.d.ts +1 -1
  6. package/cjs/ApiUtils.js +30 -32
  7. package/cjs/Endpoint.d.ts +1 -1
  8. package/cjs/Endpoint.js +112 -175
  9. package/cjs/EndpointBuilder.js +23 -32
  10. package/cjs/QueryHandling.js +12 -13
  11. package/cjs/RequestConfig.js +54 -36
  12. package/cjs/RequestContext.d.ts +1 -1
  13. package/cjs/RequestContext.js +125 -180
  14. package/cjs/RequestError.js +16 -19
  15. package/cjs/Requester.js +230 -312
  16. package/cjs/TextDecoding.js +31 -31
  17. package/cjs/Utils.js +20 -23
  18. package/cjs/backend/AxiosRequestBackend.d.ts +1 -1
  19. package/cjs/backend/AxiosRequestBackend.js +65 -172
  20. package/cjs/backend/FetchRequestBackend.d.ts +1 -1
  21. package/cjs/backend/FetchRequestBackend.js +108 -154
  22. package/cjs/backend/MockRequestBackend.d.ts +1 -1
  23. package/cjs/backend/MockRequestBackend.js +146 -208
  24. package/cjs/cache/ClientCaching.js +26 -74
  25. package/cjs/cache/LocalForageClientCacheBackend.js +15 -83
  26. package/cjs/cache/LocalStorageClientCacheBackend.js +14 -73
  27. package/cjs/index.d.ts +11 -11
  28. package/cjs/index.js +24 -21
  29. package/cjs/middleware/ClientCacheMiddleware.js +80 -103
  30. package/cjs/middleware/LoggingMiddleware.js +71 -42
  31. package/cjs/util/retry/index.js +42 -9
  32. package/cjs/util/retry/lib/retry.js +25 -27
  33. package/cjs/util/retry/lib/retryOperation.d.ts +1 -26
  34. package/cjs/util/retry/lib/retryOperation.js +21 -23
  35. package/esm/Api.d.ts +6 -6
  36. package/esm/Api.js +12 -25
  37. package/esm/ApiConstants.d.ts +1 -1
  38. package/esm/ApiTypes.d.ts +5 -5
  39. package/esm/ApiUtils.d.ts +2 -2
  40. package/esm/ApiUtils.js +4 -5
  41. package/esm/Endpoint.d.ts +6 -6
  42. package/esm/Endpoint.js +22 -28
  43. package/esm/EndpointBuilder.d.ts +4 -4
  44. package/esm/EndpointBuilder.js +2 -2
  45. package/esm/MockingTypes.d.ts +1 -1
  46. package/esm/QueryHandling.d.ts +1 -1
  47. package/esm/QueryHandling.js +2 -3
  48. package/esm/RequestConfig.d.ts +1 -1
  49. package/esm/RequestConfig.js +6 -7
  50. package/esm/RequestContext.d.ts +7 -7
  51. package/esm/RequestContext.js +15 -27
  52. package/esm/RequestError.d.ts +3 -3
  53. package/esm/RequestError.js +2 -3
  54. package/esm/Requester.d.ts +2 -2
  55. package/esm/Requester.js +44 -50
  56. package/esm/UtilTypes.d.ts +1 -1
  57. package/esm/Utils.js +2 -1
  58. package/esm/Validation.d.ts +1 -1
  59. package/esm/backend/AxiosRequestBackend.d.ts +4 -4
  60. package/esm/backend/AxiosRequestBackend.js +47 -84
  61. package/esm/backend/FetchRequestBackend.d.ts +5 -5
  62. package/esm/backend/FetchRequestBackend.js +49 -63
  63. package/esm/backend/MockRequestBackend.d.ts +4 -4
  64. package/esm/backend/MockRequestBackend.js +105 -136
  65. package/esm/backend/RequestBackend.d.ts +2 -2
  66. package/esm/cache/ClientCaching.d.ts +1 -1
  67. package/esm/cache/ClientCaching.js +8 -17
  68. package/esm/cache/LocalForageClientCacheBackend.d.ts +1 -1
  69. package/esm/cache/LocalForageClientCacheBackend.js +8 -25
  70. package/esm/cache/LocalStorageClientCacheBackend.d.ts +1 -1
  71. package/esm/cache/LocalStorageClientCacheBackend.js +9 -26
  72. package/esm/index.d.ts +16 -16
  73. package/esm/index.js +15 -15
  74. package/esm/middleware/ClientCacheMiddleware.d.ts +1 -1
  75. package/esm/middleware/ClientCacheMiddleware.js +8 -17
  76. package/esm/middleware/LoggingMiddleware.d.ts +1 -1
  77. package/esm/middleware/LoggingMiddleware.js +5 -6
  78. package/esm/util/retry/index.js +1 -1
  79. package/esm/util/retry/lib/retry.d.ts +1 -1
  80. package/esm/util/retry/lib/retry.js +13 -7
  81. package/esm/util/retry/lib/retryOperation.d.ts +1 -26
  82. package/esm/util/retry/lib/retryOperation.js +1 -1
  83. package/package.json +66 -28
package/cjs/Requester.js CHANGED
@@ -1,109 +1,61 @@
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
- };
13
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
- return new (P || (P = Promise))(function (resolve, reject) {
16
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
17
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
19
- step((generator = generator.apply(thisArg, _arguments || [])).next());
20
- });
21
- };
22
- var __generator = (this && this.__generator) || function (thisArg, body) {
23
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
24
- return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25
- function verb(n) { return function (v) { return step([n, v]); }; }
26
- function step(op) {
27
- if (f) throw new TypeError("Generator is already executing.");
28
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
29
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
30
- if (y = 0, t) op = [op[0] & 2, t.value];
31
- switch (op[0]) {
32
- case 0: case 1: t = op; break;
33
- case 4: _.label++; return { value: op[1], done: false };
34
- case 5: _.label++; y = op[1]; op = [0]; continue;
35
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
36
- default:
37
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41
- if (t[2]) _.ops.pop();
42
- _.trys.pop(); continue;
43
- }
44
- op = body.call(thisArg, _);
45
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47
- }
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
48
4
  };
49
5
  Object.defineProperty(exports, "__esModule", { value: true });
50
6
  exports.submit = void 0;
51
- var ApiConstants_1 = require("./ApiConstants");
52
- var ApiUtils_1 = require("./ApiUtils");
53
- var RequestContext_1 = require("./RequestContext");
54
- var RequestError_1 = require("./RequestError");
55
- var TextDecoding_1 = require("./TextDecoding");
56
- var MockRequestBackend_1 = require("./backend/MockRequestBackend");
57
- var retry_1 = require("./util/retry");
58
- var locks = {};
59
- var runningOperations = {};
60
- var MOCK_REQUEST_BACKEND = new MockRequestBackend_1.default();
61
- var submit = function (host, config, mocking) { return __awaiter(void 0, void 0, void 0, function () {
62
- var computedConfig, backend, context, key, lock, lockedContext, response, successEventResult, error_1;
63
- return __generator(this, function (_a) {
64
- switch (_a.label) {
65
- case 0:
66
- computedConfig = host.computeConfig(config);
67
- backend = mocking ? MOCK_REQUEST_BACKEND : host.getRequestBackend();
68
- context = new RequestContext_1.default(backend, host, computedConfig, host.path, mocking);
69
- key = context.key;
70
- lock = (context.requestConfig || {}).lock;
71
- if (typeof lock === "string") {
72
- lockedContext = locks[lock];
73
- if (lockedContext && lockedContext.id !== context.id) {
74
- lockedContext.cancel();
75
- }
76
- locks[lock] = context;
77
- }
78
- _a.label = 1;
79
- case 1:
80
- _a.trys.push([1, 4, 5, 6]);
81
- return [4 /*yield*/, (runningOperations[key] = makeRequest(context))];
82
- case 2:
83
- response = _a.sent();
84
- return [4 /*yield*/, context.triggerEvent(ApiConstants_1.RequestEvent.SUCCESS)];
85
- case 3:
86
- successEventResult = _a.sent();
87
- if (successEventResult && successEventResult.type === ApiConstants_1.EventResultType.RESPOND) {
88
- context.response = response = successEventResult.response;
89
- }
90
- delete runningOperations[key];
91
- return [2 /*return*/, response];
92
- case 4:
93
- error_1 = _a.sent();
94
- delete runningOperations[key];
95
- throw error_1;
96
- case 5:
97
- if (typeof lock === "string") {
98
- delete locks[lock];
99
- }
100
- return [7 /*endfinally*/];
101
- case 6: return [2 /*return*/];
7
+ const ApiConstants_1 = require("./ApiConstants");
8
+ const ApiUtils_1 = require("./ApiUtils");
9
+ const MockRequestBackend_1 = __importDefault(require("./backend/MockRequestBackend"));
10
+ const RequestContext_1 = __importDefault(require("./RequestContext"));
11
+ const RequestError_1 = require("./RequestError");
12
+ const TextDecoding_1 = require("./TextDecoding");
13
+ const retry_1 = __importDefault(require("./util/retry"));
14
+ const locks = {};
15
+ const runningOperations = {};
16
+ const MOCK_REQUEST_BACKEND = new MockRequestBackend_1.default();
17
+ const submit = async (host, config, mocking) => {
18
+ const computedConfig = host.computeConfig(config);
19
+ const backend = mocking ? MOCK_REQUEST_BACKEND : host.getRequestBackend();
20
+ const context = new RequestContext_1.default(backend, host, computedConfig, host.path, mocking);
21
+ const { key } = context;
22
+ // don't do this -- should only be for GET requests anyway and should be opt-in
23
+ /*
24
+ // if we are already running this request just return the same promise, no need to do it again
25
+ const sameRequest = runningOperations[key];
26
+ if (sameRequest) {
27
+ return sameRequest;
28
+ }
29
+ */
30
+ const { lock } = context.requestConfig || {};
31
+ if (typeof lock === "string") {
32
+ const lockedContext = locks[lock];
33
+ if (lockedContext && lockedContext.id !== context.id) {
34
+ lockedContext.cancel();
35
+ }
36
+ locks[lock] = context;
37
+ }
38
+ try {
39
+ let response = await (runningOperations[key] = makeRequest(context));
40
+ const successEventResult = await context.triggerEvent(ApiConstants_1.RequestEvent.SUCCESS);
41
+ if (successEventResult && successEventResult.type === ApiConstants_1.EventResultType.RESPOND) {
42
+ context.response = response = successEventResult.response;
102
43
  }
103
- });
104
- }); };
44
+ delete runningOperations[key];
45
+ return response;
46
+ }
47
+ catch (error) {
48
+ delete runningOperations[key];
49
+ throw error;
50
+ }
51
+ finally {
52
+ if (typeof lock === "string") {
53
+ delete locks[lock];
54
+ }
55
+ }
56
+ };
105
57
  exports.submit = submit;
106
- var parseRetryOptions = function (retryConfig) {
58
+ const parseRetryOptions = (retryConfig) => {
107
59
  if (retryConfig && typeof retryConfig === "object") {
108
60
  return retryConfig;
109
61
  }
@@ -112,222 +64,188 @@ var parseRetryOptions = function (retryConfig) {
112
64
  }
113
65
  return { maxAttempts: 0 };
114
66
  };
115
- var makeRequest = function (context) { return __awaiter(void 0, void 0, void 0, function () {
116
- var beforeSendEventResult, retryOptions, internalRetryOptions, performRequest, response;
117
- var _a, _b, _c;
118
- return __generator(this, function (_d) {
119
- switch (_d.label) {
120
- case 0: return [4 /*yield*/, context.triggerEvent(ApiConstants_1.RequestEvent.BEFORE_SEND)];
121
- case 1:
122
- beforeSendEventResult = _d.sent();
123
- if (beforeSendEventResult && beforeSendEventResult.type === ApiConstants_1.EventResultType.RESPOND) {
124
- return [2 /*return*/, (context.response = beforeSendEventResult.response)];
125
- }
126
- context.validatePath();
127
- // validation
128
- if (context.validation.query) {
129
- try {
130
- context.requestConfig.queryObject = context.validation.query.parse(context.requestConfig.queryObject);
131
- }
132
- catch (error) {
133
- throw (0, RequestError_1.convertToRequestError)({
134
- error: error,
135
- code: RequestError_1.RequestErrorCode.VALIDATION_QUERY_VALIDATE_ERROR,
136
- context: context,
137
- });
138
- }
139
- }
140
- if (context.validation.body) {
141
- try {
142
- context.requestConfig.body = context.validation.body.parse(context.requestConfig.body);
143
- }
144
- catch (error) {
145
- throw (0, RequestError_1.convertToRequestError)({
146
- error: error,
147
- code: RequestError_1.RequestErrorCode.VALIDATION_BODY_VALIDATE_ERROR,
148
- context: context,
149
- });
150
- }
151
- }
152
- retryOptions = parseRetryOptions((_a = context.requestConfig) === null || _a === void 0 ? void 0 : _a.retry);
153
- internalRetryOptions = {
154
- retries: retryOptions.maxAttempts,
155
- // assume most users won't want to tune the delay between retries
156
- minTimeout: (_b = retryOptions.minDelay) !== null && _b !== void 0 ? _b : 200,
157
- maxTimeout: (_c = retryOptions.maxDelay) !== null && _c !== void 0 ? _c : 1000,
158
- randomize: true,
159
- };
160
- context.stats.attempt = 0;
161
- performRequest = function (fnBail, attemptCount) { return __awaiter(void 0, void 0, void 0, function () {
162
- var _a, promise, canceler, response_1, parsedResponse, rawError_1, error, errorEventResult, forceRetry, unrecoverableErrorEventResult;
163
- return __generator(this, function (_b) {
164
- switch (_b.label) {
165
- case 0:
166
- context.stats.attempt++;
167
- _b.label = 1;
168
- case 1:
169
- _b.trys.push([1, 4, , 8]);
170
- _a = context.backend.makeRequest(context), promise = _a.promise, canceler = _a.canceler;
171
- context.addCanceller(canceler);
172
- return [4 /*yield*/, promise];
173
- case 2:
174
- response_1 = _b.sent();
175
- return [4 /*yield*/, parseResponse(context, response_1)];
176
- case 3:
177
- parsedResponse = (_b.sent());
178
- if (!(0, ApiUtils_1.isAcceptableStatus)(parsedResponse.status, context.requestConfig.acceptableStatus)) {
179
- throw (0, RequestError_1.convertToRequestError)({
180
- error: new Error("[api-def] Invalid response status code '".concat(parsedResponse.status, "'")),
181
- response: parsedResponse,
182
- code: RequestError_1.RequestErrorCode.REQUEST_INVALID_STATUS,
183
- context: context,
184
- });
185
- }
186
- context.response = parsedResponse;
187
- context.stats.endTimestamp = Date.now();
188
- return [2 /*return*/, parsedResponse];
189
- case 4:
190
- rawError_1 = _b.sent();
191
- if (context.cancelled) {
192
- rawError_1.isCancelledRequest = true;
193
- }
194
- return [4 /*yield*/, parseError(context, rawError_1)];
195
- case 5:
196
- error = _b.sent();
197
- context.error = error;
198
- context.response = error.response;
199
- context.stats.endTimestamp = Date.now();
200
- return [4 /*yield*/, context.triggerEvent(ApiConstants_1.RequestEvent.ERROR)];
201
- case 6:
202
- errorEventResult = _b.sent();
203
- if ((errorEventResult === null || errorEventResult === void 0 ? void 0 : errorEventResult.type) === ApiConstants_1.EventResultType.RESPOND) {
204
- return [2 /*return*/, errorEventResult.response];
205
- }
206
- forceRetry = (errorEventResult === null || errorEventResult === void 0 ? void 0 : errorEventResult.type) === ApiConstants_1.EventResultType.RETRY;
207
- if (forceRetry) {
208
- return [2 /*return*/, performRequest(fnBail, attemptCount)];
209
- }
210
- // allow retry logic to handle
211
- if (!retryOptions.shouldRetry || retryOptions.shouldRetry(error)) {
212
- throw error;
213
- }
214
- return [4 /*yield*/, context.triggerEvent(ApiConstants_1.RequestEvent.UNRECOVERABLE_ERROR)];
215
- case 7:
216
- unrecoverableErrorEventResult = _b.sent();
217
- if (unrecoverableErrorEventResult) {
218
- if (unrecoverableErrorEventResult.type === ApiConstants_1.EventResultType.RESPOND) {
219
- return [2 /*return*/, unrecoverableErrorEventResult.response];
220
- }
221
- }
222
- fnBail(error);
223
- return [3 /*break*/, 8];
224
- case 8: return [2 /*return*/];
225
- }
226
- });
227
- }); };
228
- return [4 /*yield*/, (0, retry_1.default)(performRequest, internalRetryOptions)];
229
- case 2:
230
- response = _d.sent();
231
- if (context.validation.response) {
232
- try {
233
- response.data = context.validation.response.parse(response.data);
234
- }
235
- catch (error) {
236
- throw (0, RequestError_1.convertToRequestError)({
237
- error: error,
238
- code: RequestError_1.RequestErrorCode.VALIDATION_RESPONSE_VALIDATE_ERROR,
239
- context: context,
240
- });
241
- }
67
+ const makeRequest = async (context) => {
68
+ const beforeSendEventResult = await context.triggerEvent(ApiConstants_1.RequestEvent.BEFORE_SEND);
69
+ if (beforeSendEventResult && beforeSendEventResult.type === ApiConstants_1.EventResultType.RESPOND) {
70
+ return (context.response = beforeSendEventResult.response);
71
+ }
72
+ context.validatePath();
73
+ // validation
74
+ if (context.validation.query) {
75
+ try {
76
+ context.requestConfig.queryObject = context.validation.query.parse(context.requestConfig.queryObject);
77
+ }
78
+ catch (error) {
79
+ throw (0, RequestError_1.convertToRequestError)({
80
+ error: error,
81
+ code: RequestError_1.RequestErrorCode.VALIDATION_QUERY_VALIDATE_ERROR,
82
+ context: context,
83
+ });
84
+ }
85
+ }
86
+ if (context.validation.body) {
87
+ try {
88
+ context.requestConfig.body = context.validation.body.parse(context.requestConfig.body);
89
+ }
90
+ catch (error) {
91
+ throw (0, RequestError_1.convertToRequestError)({
92
+ error: error,
93
+ code: RequestError_1.RequestErrorCode.VALIDATION_BODY_VALIDATE_ERROR,
94
+ context: context,
95
+ });
96
+ }
97
+ }
98
+ const retryOptions = parseRetryOptions(context.requestConfig?.retry);
99
+ const internalRetryOptions = {
100
+ retries: retryOptions.maxAttempts,
101
+ // assume most users won't want to tune the delay between retries
102
+ minTimeout: retryOptions.minDelay ?? 200,
103
+ maxTimeout: retryOptions.maxDelay ?? 1000,
104
+ randomize: true,
105
+ };
106
+ context.stats.attempt = 0;
107
+ const performRequest = async (fnBail, attemptCount) => {
108
+ context.stats.attempt++;
109
+ try {
110
+ const { promise, canceler } = context.backend.makeRequest(context);
111
+ context.addCanceller(canceler);
112
+ const response = await promise;
113
+ const parsedResponse = (await parseResponse(context, response));
114
+ if (!(0, ApiUtils_1.isAcceptableStatus)(parsedResponse.status, context.requestConfig.acceptableStatus)) {
115
+ throw (0, RequestError_1.convertToRequestError)({
116
+ error: new Error(`[api-def] Invalid response status code '${parsedResponse.status}'`),
117
+ response: parsedResponse,
118
+ code: RequestError_1.RequestErrorCode.REQUEST_INVALID_STATUS,
119
+ context: context,
120
+ });
121
+ }
122
+ context.response = parsedResponse;
123
+ context.stats.endTimestamp = Date.now();
124
+ return parsedResponse;
125
+ }
126
+ catch (rawError) {
127
+ if (context.cancelled) {
128
+ rawError.isCancelledRequest = true;
129
+ }
130
+ const error = await parseError(context, rawError);
131
+ context.error = error;
132
+ context.response = error.response;
133
+ context.stats.endTimestamp = Date.now();
134
+ const errorEventResult = await context.triggerEvent(ApiConstants_1.RequestEvent.ERROR);
135
+ if (errorEventResult?.type === ApiConstants_1.EventResultType.RESPOND) {
136
+ return errorEventResult.response;
137
+ }
138
+ // allow retry logic to handle network errors
139
+ //const shouldNaturallyRetry = ApiUtils.isNetworkError(error);
140
+ //if (shouldNaturallyRetry) {
141
+ // throw error;
142
+ //}
143
+ // if we have an event that tells us to retry, we must do it
144
+ const forceRetry = errorEventResult?.type === ApiConstants_1.EventResultType.RETRY;
145
+ if (forceRetry) {
146
+ return performRequest(fnBail, attemptCount);
147
+ }
148
+ // allow retry logic to handle
149
+ if (!retryOptions.shouldRetry || retryOptions.shouldRetry(error)) {
150
+ throw error;
151
+ }
152
+ // error is unrecoverable, bail
153
+ const unrecoverableErrorEventResult = await context.triggerEvent(ApiConstants_1.RequestEvent.UNRECOVERABLE_ERROR);
154
+ if (unrecoverableErrorEventResult) {
155
+ if (unrecoverableErrorEventResult.type === ApiConstants_1.EventResultType.RESPOND) {
156
+ return unrecoverableErrorEventResult.response;
242
157
  }
243
- return [2 /*return*/, response];
158
+ }
159
+ fnBail(error);
244
160
  }
245
- });
246
- }); };
247
- var parseResponse = function (context, response, error) { return __awaiter(void 0, void 0, void 0, function () {
248
- var parsedResponse, contentType, inferredResponseType, data, decodedData;
249
- var _a;
250
- return __generator(this, function (_b) {
251
- switch (_b.label) {
252
- case 0:
253
- if (!response) return [3 /*break*/, 2];
254
- return [4 /*yield*/, context.backend.convertResponse(context, response)];
255
- case 1:
256
- parsedResponse = _b.sent();
257
- contentType = parsedResponse.headers.get("content-type");
258
- inferredResponseType = (0, ApiUtils_1.inferResponseType)(contentType);
259
- if (!error) {
260
- // expand to array buffer once we support that in inferResponseType
261
- if (inferredResponseType === "text" && context.responseType === "json") {
262
- throw (0, RequestError_1.convertToRequestError)({
263
- error: new Error("[api-def] Expected '".concat(context.responseType, "' response, got '").concat(inferredResponseType, "' (from 'Content-Type' of '").concat(contentType, "')")),
264
- code: RequestError_1.RequestErrorCode.REQUEST_MISMATCH_RESPONSE_TYPE,
265
- response: parsedResponse,
266
- context: context,
267
- });
268
- }
269
- // transform arrayBuffer to json
270
- if (inferredResponseType === "arraybuffer" && context.responseType === "json") {
271
- if (parsedResponse.data && typeof parsedResponse.data === "object") {
272
- data = response.data;
273
- if (((_a = data.constructor) === null || _a === void 0 ? void 0 : _a.name) === "ArrayBuffer") {
274
- try {
275
- decodedData = (response.data = (0, TextDecoding_1.textDecode)(data));
276
- response.data = JSON.parse(decodedData);
277
- }
278
- catch (e) {
279
- throw (0, RequestError_1.convertToRequestError)({
280
- error: new Error("[api-def] Expected '".concat(context.responseType, "' response, got '").concat(inferredResponseType, "' (from 'Content-Type' of '").concat(contentType, "')")),
281
- code: RequestError_1.RequestErrorCode.REQUEST_MISMATCH_RESPONSE_TYPE,
282
- response: parsedResponse,
283
- context: context,
284
- });
285
- }
286
- }
161
+ };
162
+ const response = await (0, retry_1.default)(performRequest, internalRetryOptions);
163
+ if (context.validation.response) {
164
+ try {
165
+ response.data = context.validation.response.parse(response.data);
166
+ }
167
+ catch (error) {
168
+ throw (0, RequestError_1.convertToRequestError)({
169
+ error: error,
170
+ code: RequestError_1.RequestErrorCode.VALIDATION_RESPONSE_VALIDATE_ERROR,
171
+ context: context,
172
+ });
173
+ }
174
+ }
175
+ return response;
176
+ };
177
+ const parseResponse = async (context, response, error) => {
178
+ if (response) {
179
+ const parsedResponse = await context.backend.convertResponse(context, response);
180
+ const contentType = parsedResponse.headers.get("content-type");
181
+ const inferredResponseType = (0, ApiUtils_1.inferResponseType)(contentType);
182
+ if (!error) {
183
+ // expand to array buffer once we support that in inferResponseType
184
+ if (inferredResponseType === "text" && context.responseType === "json") {
185
+ throw (0, RequestError_1.convertToRequestError)({
186
+ error: new Error(`[api-def] Expected '${context.responseType}' response, got '${inferredResponseType}' (from 'Content-Type' of '${contentType}')`),
187
+ code: RequestError_1.RequestErrorCode.REQUEST_MISMATCH_RESPONSE_TYPE,
188
+ response: parsedResponse,
189
+ context: context,
190
+ });
191
+ }
192
+ // transform arrayBuffer to json
193
+ if (inferredResponseType === "arraybuffer" && context.responseType === "json") {
194
+ if (parsedResponse.data && typeof parsedResponse.data === "object") {
195
+ const data = response.data;
196
+ if (data.constructor?.name === "ArrayBuffer") {
197
+ try {
198
+ const decodedData = (response.data = (0, TextDecoding_1.textDecode)(data));
199
+ response.data = JSON.parse(decodedData);
200
+ }
201
+ catch (e) {
202
+ throw (0, RequestError_1.convertToRequestError)({
203
+ error: new Error(`[api-def] Expected '${context.responseType}' response, got '${inferredResponseType}' (from 'Content-Type' of '${contentType}')`),
204
+ code: RequestError_1.RequestErrorCode.REQUEST_MISMATCH_RESPONSE_TYPE,
205
+ response: parsedResponse,
206
+ context: context,
207
+ });
287
208
  }
288
209
  }
289
210
  }
290
- return [2 /*return*/, parsedResponse];
291
- case 2: return [2 /*return*/, response];
211
+ }
292
212
  }
293
- });
294
- }); };
295
- var parseError = function (context, rawError) { return __awaiter(void 0, void 0, void 0, function () {
296
- var error, extractedResponse, errorResponse, code, errorInfo;
297
- var _a;
298
- return __generator(this, function (_b) {
299
- switch (_b.label) {
300
- case 0:
301
- if (!(0, RequestError_1.isRequestError)(rawError)) return [3 /*break*/, 1];
302
- error = rawError;
303
- return [3 /*break*/, 5];
304
- case 1: return [4 /*yield*/, context.backend.extractResponseFromError(rawError)];
305
- case 2:
306
- extractedResponse = _b.sent();
307
- errorResponse = undefined;
308
- if (!(extractedResponse !== undefined)) return [3 /*break*/, 4];
309
- return [4 /*yield*/, parseResponse(context, extractedResponse, true)];
310
- case 3:
311
- errorResponse = _b.sent();
312
- _b.label = 4;
313
- case 4:
314
- code = (0, ApiUtils_1.isNetworkError)(rawError)
315
- ? RequestError_1.RequestErrorCode.REQUEST_NETWORK_ERROR
316
- : RequestError_1.RequestErrorCode.MISC_UNKNOWN_ERROR;
317
- if (errorResponse) {
318
- if (!(0, ApiUtils_1.isAcceptableStatus)(errorResponse.status, context.requestConfig.acceptableStatus)) {
319
- code = RequestError_1.RequestErrorCode.REQUEST_INVALID_STATUS;
320
- }
321
- }
322
- else {
323
- if (rawError.code === "ENOTFOUND" || ((_a = rawError.cause) === null || _a === void 0 ? void 0 : _a.code) === "ENOTFOUND") {
324
- code = RequestError_1.RequestErrorCode.REQUEST_HOST_NAME_NOT_FOUND;
325
- }
326
- }
327
- errorInfo = context.backend.getErrorInfo(rawError, errorResponse);
328
- error = (0, RequestError_1.convertToRequestError)(__assign({ error: rawError, response: errorResponse, code: code, context: context }, errorInfo));
329
- _b.label = 5;
330
- case 5: return [2 /*return*/, error];
213
+ return parsedResponse;
214
+ }
215
+ return response;
216
+ };
217
+ const parseError = async (context, rawError) => {
218
+ let error;
219
+ if ((0, RequestError_1.isRequestError)(rawError)) {
220
+ error = rawError;
221
+ }
222
+ else {
223
+ const extractedResponse = await context.backend.extractResponseFromError(rawError);
224
+ let errorResponse;
225
+ if (extractedResponse !== undefined) {
226
+ errorResponse = await parseResponse(context, extractedResponse, true);
227
+ }
228
+ let code = (0, ApiUtils_1.isNetworkError)(rawError)
229
+ ? RequestError_1.RequestErrorCode.REQUEST_NETWORK_ERROR
230
+ : RequestError_1.RequestErrorCode.MISC_UNKNOWN_ERROR;
231
+ if (errorResponse) {
232
+ if (!(0, ApiUtils_1.isAcceptableStatus)(errorResponse.status, context.requestConfig.acceptableStatus)) {
233
+ code = RequestError_1.RequestErrorCode.REQUEST_INVALID_STATUS;
234
+ }
331
235
  }
332
- });
333
- }); };
236
+ else {
237
+ if (rawError.code === "ENOTFOUND" || rawError.cause?.code === "ENOTFOUND") {
238
+ code = RequestError_1.RequestErrorCode.REQUEST_HOST_NAME_NOT_FOUND;
239
+ }
240
+ }
241
+ const errorInfo = context.backend.getErrorInfo(rawError, errorResponse);
242
+ error = (0, RequestError_1.convertToRequestError)({
243
+ error: rawError,
244
+ response: errorResponse,
245
+ code: code,
246
+ context: context,
247
+ ...errorInfo,
248
+ });
249
+ }
250
+ return error;
251
+ };