api-def 0.5.1 → 0.6.0-alpha11
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/cjs/ApiTypes.d.ts +2 -1
- package/cjs/ApiUtils.d.ts +3 -2
- package/cjs/ApiUtils.js +20 -18
- package/cjs/RequestError.d.ts +1 -0
- package/cjs/RequestError.js +1 -0
- package/cjs/Requester.js +40 -16
- package/cjs/UtilTypes.d.ts +5 -0
- package/cjs/UtilTypes.js +2 -0
- package/cjs/backend/AxiosRequestBackend.d.ts +3 -2
- package/cjs/backend/AxiosRequestBackend.js +3 -0
- package/cjs/backend/FetchRequestBackend.d.ts +2 -3
- package/cjs/backend/FetchRequestBackend.js +39 -39
- package/cjs/backend/MockRequestBackend.d.ts +1 -0
- package/cjs/backend/MockRequestBackend.js +1 -0
- package/cjs/backend/RequestBackend.d.ts +2 -1
- package/cjs/index.d.ts +1 -0
- package/cjs/index.js +1 -0
- package/esm/ApiTypes.d.ts +2 -1
- package/esm/ApiUtils.d.ts +3 -2
- package/esm/ApiUtils.js +18 -16
- package/esm/RequestError.d.ts +1 -0
- package/esm/RequestError.js +1 -0
- package/esm/Requester.js +41 -17
- package/esm/UtilTypes.d.ts +5 -0
- package/esm/UtilTypes.js +1 -0
- package/esm/backend/AxiosRequestBackend.d.ts +3 -2
- package/esm/backend/AxiosRequestBackend.js +3 -0
- package/esm/backend/FetchRequestBackend.d.ts +2 -3
- package/esm/backend/FetchRequestBackend.js +39 -39
- package/esm/backend/MockRequestBackend.d.ts +1 -0
- package/esm/backend/MockRequestBackend.js +1 -0
- package/esm/backend/RequestBackend.d.ts +2 -1
- package/esm/index.d.ts +1 -0
- package/esm/index.js +1 -0
- package/package.json +1 -1
package/cjs/ApiTypes.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { CacheSource, EventResultType, RequestEvent, RequestMethod, ResponseType
|
|
|
4
4
|
export declare type AcceptableStatus = number | [min: number, max: number];
|
|
5
5
|
export declare type Headers = Record<string, string | number | boolean | null | undefined>;
|
|
6
6
|
export declare type Params = string;
|
|
7
|
-
export declare type Query = Record<string,
|
|
7
|
+
export declare type Query = Record<string, any>;
|
|
8
8
|
export declare type Body = string | number | Record<string, any>;
|
|
9
9
|
export interface ApiResponse<T = any> {
|
|
10
10
|
status: number;
|
|
@@ -17,6 +17,7 @@ export interface BaseRequestConfig {
|
|
|
17
17
|
retry?: number | false;
|
|
18
18
|
headers?: Readonly<Headers>;
|
|
19
19
|
acceptableStatus?: AcceptableStatus[];
|
|
20
|
+
queryParser?: (query: any) => string;
|
|
20
21
|
}
|
|
21
22
|
export declare type RequestConfig<P extends Params | undefined = Params | undefined, Q extends Query | undefined = Query | undefined, B extends Body | undefined = Body | undefined> = (P extends undefined ? {
|
|
22
23
|
params?: never;
|
package/cjs/ApiUtils.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { AcceptableStatus,
|
|
1
|
+
import { AcceptableStatus, CancelledRequestError } from "./ApiTypes";
|
|
2
|
+
import { ResponseType } from "./ApiConstants";
|
|
2
3
|
export declare const isCancelledError: (error: Error) => error is CancelledRequestError;
|
|
3
4
|
export declare const isNetworkError: (error: Error) => boolean;
|
|
4
|
-
export declare const parseResponseDataToObject: (response: ApiResponse) => void;
|
|
5
5
|
export declare const isAcceptableStatus: (status: number, acceptableStatus?: AcceptableStatus[] | undefined) => boolean;
|
|
6
|
+
export declare const inferResponseType: (contentType: string | null | undefined) => ResponseType;
|
package/cjs/ApiUtils.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
var TextDecoding_1 = require("./TextDecoding");
|
|
3
|
+
exports.inferResponseType = exports.isAcceptableStatus = exports.isNetworkError = exports.isCancelledError = void 0;
|
|
5
4
|
var isCancelledError = function (error) {
|
|
6
5
|
return "isCancelledRequest" in error;
|
|
7
6
|
};
|
|
@@ -13,22 +12,6 @@ var isNetworkError = function (error) {
|
|
|
13
12
|
((_a = error.constructor) === null || _a === void 0 ? void 0 : _a.name) === "NetworkError");
|
|
14
13
|
};
|
|
15
14
|
exports.isNetworkError = isNetworkError;
|
|
16
|
-
var parseResponseDataToObject = function (response) {
|
|
17
|
-
if (response.data &&
|
|
18
|
-
typeof response.data === "object") {
|
|
19
|
-
var data = response.data;
|
|
20
|
-
if (data.constructor && data.constructor.name === "ArrayBuffer") {
|
|
21
|
-
try {
|
|
22
|
-
var decodedData = (response.data = TextDecoding_1.textDecode(data));
|
|
23
|
-
response.data = JSON.parse(decodedData);
|
|
24
|
-
}
|
|
25
|
-
catch (e) {
|
|
26
|
-
console.warn("Couldn't parse array buffer content to JSON response", e);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
exports.parseResponseDataToObject = parseResponseDataToObject;
|
|
32
15
|
var DEFAULT_ACCEPTABLE_STATUS = [[200, 299], 304];
|
|
33
16
|
var isAcceptableStatus = function (status, acceptableStatus) {
|
|
34
17
|
var acceptable = acceptableStatus !== null && acceptableStatus !== void 0 ? acceptableStatus : DEFAULT_ACCEPTABLE_STATUS;
|
|
@@ -49,3 +32,22 @@ var isAcceptableStatus = function (status, acceptableStatus) {
|
|
|
49
32
|
return (false);
|
|
50
33
|
};
|
|
51
34
|
exports.isAcceptableStatus = isAcceptableStatus;
|
|
35
|
+
var TEXT_CONTENT_TYPES = ["text/plain"];
|
|
36
|
+
var JSON_CONTENT_TYPES = ["text/json", "application/json"];
|
|
37
|
+
var ARRRAY_BUFFER_CONTENT_TYPES = ["application/octet-stream"];
|
|
38
|
+
var inferResponseType = function (contentType) {
|
|
39
|
+
var contentTypePart = contentType === null || contentType === void 0 ? void 0 : contentType.split(";")[0].trim();
|
|
40
|
+
if (contentTypePart) {
|
|
41
|
+
if (TEXT_CONTENT_TYPES.includes(contentTypePart)) {
|
|
42
|
+
return "text";
|
|
43
|
+
}
|
|
44
|
+
else if (JSON_CONTENT_TYPES.includes(contentTypePart)) {
|
|
45
|
+
return "json";
|
|
46
|
+
}
|
|
47
|
+
else if (ARRRAY_BUFFER_CONTENT_TYPES.includes(contentTypePart)) {
|
|
48
|
+
return "arraybuffer";
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return "text";
|
|
52
|
+
};
|
|
53
|
+
exports.inferResponseType = inferResponseType;
|
package/cjs/RequestError.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export declare const RequestErrorCode: {
|
|
|
5
5
|
readonly REQUEST_NETWORK_ERROR: "request/network-error";
|
|
6
6
|
readonly REQUEST_INVALID_STATUS: "request/invalid-status";
|
|
7
7
|
readonly REQUEST_INVALID_CONFIG: "request/invalid-config";
|
|
8
|
+
readonly REQUEST_MISMATCH_RESPONSE_TYPE: "request/mismatch-response-type";
|
|
8
9
|
};
|
|
9
10
|
export declare type RequestErrorCode = EnumOf<typeof RequestErrorCode>;
|
|
10
11
|
export interface RequestError extends Error {
|
package/cjs/RequestError.js
CHANGED
|
@@ -6,6 +6,7 @@ exports.RequestErrorCode = {
|
|
|
6
6
|
REQUEST_NETWORK_ERROR: "request/network-error",
|
|
7
7
|
REQUEST_INVALID_STATUS: "request/invalid-status",
|
|
8
8
|
REQUEST_INVALID_CONFIG: "request/invalid-config",
|
|
9
|
+
REQUEST_MISMATCH_RESPONSE_TYPE: "request/mismatch-response-type",
|
|
9
10
|
};
|
|
10
11
|
var isRequestError = function (error) {
|
|
11
12
|
return "isRequestError" in error;
|
package/cjs/Requester.js
CHANGED
|
@@ -56,11 +56,12 @@ var ApiConstants_1 = require("./ApiConstants");
|
|
|
56
56
|
var retry_1 = require("./util/retry");
|
|
57
57
|
var MockRequestBackend_1 = require("./backend/MockRequestBackend");
|
|
58
58
|
var RequestError_1 = require("./RequestError");
|
|
59
|
+
var TextDecoding_1 = require("./TextDecoding");
|
|
59
60
|
var locks = {};
|
|
60
61
|
var runningOperations = {};
|
|
61
62
|
var MOCK_REQUEST_BACKEND = new MockRequestBackend_1.default();
|
|
62
63
|
var submit = function (host, config, mocking) { return __awaiter(void 0, void 0, void 0, function () {
|
|
63
|
-
var computedConfig, backend, context, key,
|
|
64
|
+
var computedConfig, backend, context, key, lock, lockedContext, response, successEventResult, error_1;
|
|
64
65
|
return __generator(this, function (_a) {
|
|
65
66
|
switch (_a.label) {
|
|
66
67
|
case 0:
|
|
@@ -71,10 +72,6 @@ var submit = function (host, config, mocking) { return __awaiter(void 0, void 0,
|
|
|
71
72
|
}
|
|
72
73
|
context = new RequestContext_1.default(backend, host, computedConfig, host.computePath(host.path, config), mocking);
|
|
73
74
|
key = context.key;
|
|
74
|
-
sameRequest = runningOperations[key];
|
|
75
|
-
if (sameRequest) {
|
|
76
|
-
return [2 /*return*/, sameRequest];
|
|
77
|
-
}
|
|
78
75
|
lock = (context.computedConfig || {}).lock;
|
|
79
76
|
if (lock) {
|
|
80
77
|
lockedContext = locks[lock];
|
|
@@ -122,6 +119,7 @@ var makeRequest = function (context) { return __awaiter(void 0, void 0, void 0,
|
|
|
122
119
|
if (process.env.NODE_ENV === "development") {
|
|
123
120
|
if (Api.isRequestBackendDefault() && !defaultBackendMessageShown) {
|
|
124
121
|
defaultBackendMessageShown = true;
|
|
122
|
+
// eslint-disable-next-line
|
|
125
123
|
console.warn("[api-def] Using default fetch backend, you can use a different one with 'setRequestBackend()' (dev only message)");
|
|
126
124
|
}
|
|
127
125
|
}
|
|
@@ -177,10 +175,6 @@ var makeRequest = function (context) { return __awaiter(void 0, void 0, void 0,
|
|
|
177
175
|
error = _b.sent();
|
|
178
176
|
context.error = error;
|
|
179
177
|
context.response = error.response;
|
|
180
|
-
// transform array buffer responses to objs
|
|
181
|
-
if (context.response) {
|
|
182
|
-
ApiUtils.parseResponseDataToObject(context.response);
|
|
183
|
-
}
|
|
184
178
|
return [4 /*yield*/, context.triggerEvent(ApiConstants_1.RequestEvent.Error)];
|
|
185
179
|
case 6:
|
|
186
180
|
errorEventResult = _b.sent();
|
|
@@ -217,16 +211,46 @@ var makeRequest = function (context) { return __awaiter(void 0, void 0, void 0,
|
|
|
217
211
|
});
|
|
218
212
|
}); };
|
|
219
213
|
var parseResponse = function (context, response, error) { return __awaiter(void 0, void 0, void 0, function () {
|
|
220
|
-
var parsedResponse;
|
|
221
|
-
|
|
222
|
-
|
|
214
|
+
var parsedResponse, contentType, inferredResponseType, data, decodedData;
|
|
215
|
+
var _a;
|
|
216
|
+
return __generator(this, function (_b) {
|
|
217
|
+
switch (_b.label) {
|
|
223
218
|
case 0:
|
|
224
219
|
if (!response) return [3 /*break*/, 2];
|
|
225
|
-
return [4 /*yield*/, context.backend.convertResponse(context, response
|
|
220
|
+
return [4 /*yield*/, context.backend.convertResponse(context, response)];
|
|
226
221
|
case 1:
|
|
227
|
-
parsedResponse =
|
|
228
|
-
|
|
229
|
-
|
|
222
|
+
parsedResponse = _b.sent();
|
|
223
|
+
contentType = response.headers.get("Content-Type");
|
|
224
|
+
inferredResponseType = ApiUtils_1.inferResponseType(contentType);
|
|
225
|
+
if (!error) {
|
|
226
|
+
// expand to array buffer once we support that in inferResponseType
|
|
227
|
+
if (inferredResponseType === "text" && context.responseType === "json") {
|
|
228
|
+
throw RequestError_1.convertToRequestError({
|
|
229
|
+
error: new Error("[api-def] Expected '" + context.responseType + "' response, got '" + inferredResponseType + "' (from 'Content-Type' of '" + contentType + "')"),
|
|
230
|
+
code: RequestError_1.RequestErrorCode.REQUEST_MISMATCH_RESPONSE_TYPE,
|
|
231
|
+
response: parsedResponse,
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
// transform arrayBuffer to json
|
|
235
|
+
if (inferredResponseType === "arraybuffer" && context.responseType === "json") {
|
|
236
|
+
if (parsedResponse.data &&
|
|
237
|
+
typeof parsedResponse.data === "object") {
|
|
238
|
+
data = response.data;
|
|
239
|
+
if (((_a = data.constructor) === null || _a === void 0 ? void 0 : _a.name) === "ArrayBuffer") {
|
|
240
|
+
try {
|
|
241
|
+
decodedData = (response.data = TextDecoding_1.textDecode(data));
|
|
242
|
+
response.data = JSON.parse(decodedData);
|
|
243
|
+
}
|
|
244
|
+
catch (e) {
|
|
245
|
+
throw RequestError_1.convertToRequestError({
|
|
246
|
+
error: new Error("[api-def] Expected '" + context.responseType + "' response, got '" + inferredResponseType + "' (from 'Content-Type' of '" + contentType + "')"),
|
|
247
|
+
code: RequestError_1.RequestErrorCode.REQUEST_MISMATCH_RESPONSE_TYPE,
|
|
248
|
+
response: parsedResponse,
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
230
254
|
}
|
|
231
255
|
return [2 /*return*/, parsedResponse];
|
|
232
256
|
case 2: return [2 /*return*/, response];
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import Endpoint from "./Endpoint";
|
|
2
|
+
export declare type ResponseOf<E extends Endpoint<any, any, any, any>> = E extends Endpoint<infer R, any, any, any> ? R : never;
|
|
3
|
+
export declare type ParamsOf<E extends Endpoint<any, any, any, any>> = E extends Endpoint<any, infer P, any, any> ? P : never;
|
|
4
|
+
export declare type QueryOf<E extends Endpoint<any, any, any, any>> = E extends Endpoint<any, any, infer Q, any> ? Q : never;
|
|
5
|
+
export declare type BodyOf<E extends Endpoint<any, any, any, any>> = E extends Endpoint<any, any, any, infer B> ? B : never;
|
package/cjs/UtilTypes.js
ADDED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import RequestBackend, { RequestBackendErrorInfo, RequestOperation } from "./RequestBackend";
|
|
2
2
|
import { ApiResponse } from "../ApiTypes";
|
|
3
|
-
import type { AxiosError, AxiosResponse
|
|
3
|
+
import type { AxiosError, AxiosResponse } 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
|
-
|
|
7
|
+
readonly id = "axios";
|
|
8
|
+
constructor(axiosLibrary: any);
|
|
8
9
|
extractResponseFromError(error: Error): Promise<AxiosResponse | null | undefined>;
|
|
9
10
|
convertResponse<T>(context: RequestContext, response: AxiosResponse): Promise<ApiResponse<T>>;
|
|
10
11
|
makeRequest(context: RequestContext): RequestOperation<AxiosResponse>;
|
|
@@ -43,7 +43,9 @@ var isAxiosError = function (error) {
|
|
|
43
43
|
};
|
|
44
44
|
exports.isAxiosError = isAxiosError;
|
|
45
45
|
var AxiosRequestBackend = /** @class */ (function () {
|
|
46
|
+
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
46
47
|
function AxiosRequestBackend(axiosLibrary) {
|
|
48
|
+
this.id = "axios";
|
|
47
49
|
axios = axiosLibrary;
|
|
48
50
|
}
|
|
49
51
|
AxiosRequestBackend.prototype.extractResponseFromError = function (error) {
|
|
@@ -77,6 +79,7 @@ var AxiosRequestBackend = /** @class */ (function () {
|
|
|
77
79
|
cancelToken: new axios.CancelToken(function (cancellerFunc) {
|
|
78
80
|
canceler = cancellerFunc;
|
|
79
81
|
}),
|
|
82
|
+
paramsSerializer: context.computedConfig.queryParser,
|
|
80
83
|
});
|
|
81
84
|
return {
|
|
82
85
|
promise: promise,
|
|
@@ -2,15 +2,14 @@ import RequestBackend, { RequestBackendErrorInfo, RequestOperation } from "./Req
|
|
|
2
2
|
import { ApiResponse } from "../ApiTypes";
|
|
3
3
|
import RequestContext from "../RequestContext";
|
|
4
4
|
import { Fetch } from "../Utils";
|
|
5
|
-
import { ResponseType } from "../ApiConstants";
|
|
6
5
|
export default class FetchRequestBackend implements RequestBackend<Response> {
|
|
7
6
|
fetch: (((input: RequestInfo, init?: RequestInit | undefined) => Promise<Response>) & typeof fetch) | undefined;
|
|
7
|
+
readonly id = "fetch";
|
|
8
8
|
constructor(fetchLibrary?: Fetch);
|
|
9
9
|
extractResponseFromError(error: Error): Promise<Response | null | undefined>;
|
|
10
|
-
inferResponseType(response: Response): ResponseType;
|
|
11
10
|
convertResponse<T>(context: RequestContext, response: Response & {
|
|
12
11
|
__text?: string;
|
|
13
|
-
}
|
|
12
|
+
}): Promise<ApiResponse<T>>;
|
|
14
13
|
makeRequest(context: RequestContext): RequestOperation<Response>;
|
|
15
14
|
getErrorInfo(error: Error, response: ApiResponse | undefined | null): RequestBackendErrorInfo | undefined;
|
|
16
15
|
}
|
|
@@ -54,6 +54,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
54
54
|
var Utils = require("../Utils");
|
|
55
55
|
var Utils_1 = require("../Utils");
|
|
56
56
|
var ApiConstants_1 = require("../ApiConstants");
|
|
57
|
+
var ApiUtils_1 = require("../ApiUtils");
|
|
57
58
|
var FetchError = /** @class */ (function (_super) {
|
|
58
59
|
__extends(FetchError, _super);
|
|
59
60
|
function FetchError() {
|
|
@@ -64,6 +65,7 @@ var FetchError = /** @class */ (function (_super) {
|
|
|
64
65
|
var FetchRequestBackend = /** @class */ (function () {
|
|
65
66
|
function FetchRequestBackend(fetchLibrary) {
|
|
66
67
|
this.fetch = Utils_1.getGlobalFetch();
|
|
68
|
+
this.id = "fetch";
|
|
67
69
|
if (fetchLibrary !== undefined) {
|
|
68
70
|
this.fetch = fetchLibrary;
|
|
69
71
|
}
|
|
@@ -80,57 +82,47 @@ var FetchRequestBackend = /** @class */ (function () {
|
|
|
80
82
|
});
|
|
81
83
|
});
|
|
82
84
|
};
|
|
83
|
-
FetchRequestBackend.prototype.
|
|
84
|
-
var contentType = response.headers.get("Content-Type");
|
|
85
|
-
if (contentType === null || contentType === void 0 ? void 0 : contentType.startsWith("json")) {
|
|
86
|
-
return "json";
|
|
87
|
-
}
|
|
88
|
-
return "text";
|
|
89
|
-
};
|
|
90
|
-
FetchRequestBackend.prototype.convertResponse = function (context, response, error) {
|
|
85
|
+
FetchRequestBackend.prototype.convertResponse = function (context, response) {
|
|
91
86
|
return __awaiter(this, void 0, void 0, function () {
|
|
92
|
-
var
|
|
87
|
+
var contentType, responseType, _a, data, status, headers, error_1;
|
|
93
88
|
return __generator(this, function (_b) {
|
|
94
89
|
switch (_b.label) {
|
|
95
90
|
case 0:
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
_b.trys.push([1, 8, , 9]);
|
|
100
|
-
if (!!response.__text) return [3 /*break*/, 3];
|
|
91
|
+
contentType = response.headers.get("Content-Type");
|
|
92
|
+
responseType = ApiUtils_1.inferResponseType(contentType);
|
|
93
|
+
if (!!response.__text) return [3 /*break*/, 2];
|
|
101
94
|
_a = response;
|
|
102
95
|
return [4 /*yield*/, response.clone().text()];
|
|
103
|
-
case
|
|
96
|
+
case 1:
|
|
104
97
|
_a.__text = _b.sent();
|
|
98
|
+
_b.label = 2;
|
|
99
|
+
case 2:
|
|
100
|
+
data = response.__text;
|
|
101
|
+
status = response.status, headers = response.headers;
|
|
105
102
|
_b.label = 3;
|
|
106
103
|
case 3:
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
return [3 /*break*/, 7];
|
|
110
|
-
case 4:
|
|
111
|
-
if (!(responseType === ApiConstants_1.ResponseType.ArrayBuffer)) return [3 /*break*/, 6];
|
|
104
|
+
_b.trys.push([3, 7, , 8]);
|
|
105
|
+
if (!(responseType === ApiConstants_1.ResponseType.ArrayBuffer)) return [3 /*break*/, 5];
|
|
112
106
|
return [4 /*yield*/, response.clone().arrayBuffer()];
|
|
113
|
-
case
|
|
107
|
+
case 4:
|
|
114
108
|
data = _b.sent();
|
|
115
|
-
return [3 /*break*/,
|
|
116
|
-
case
|
|
109
|
+
return [3 /*break*/, 6];
|
|
110
|
+
case 5:
|
|
117
111
|
if (responseType === ApiConstants_1.ResponseType.Json) {
|
|
118
112
|
data = JSON.parse(response.__text);
|
|
119
113
|
}
|
|
120
|
-
_b.label =
|
|
121
|
-
case
|
|
122
|
-
case
|
|
114
|
+
_b.label = 6;
|
|
115
|
+
case 6: return [3 /*break*/, 8];
|
|
116
|
+
case 7:
|
|
123
117
|
error_1 = _b.sent();
|
|
124
118
|
throw Object.assign(new Error("[api-def] Invalid '" + context.responseType + "' response, got: '" + response.__text + "'"), {
|
|
125
119
|
response: response,
|
|
126
120
|
});
|
|
127
|
-
case
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
headers: response.headers,
|
|
133
|
-
}];
|
|
121
|
+
case 8: return [2 /*return*/, {
|
|
122
|
+
data: data,
|
|
123
|
+
status: status,
|
|
124
|
+
headers: headers,
|
|
125
|
+
}];
|
|
134
126
|
}
|
|
135
127
|
});
|
|
136
128
|
});
|
|
@@ -147,12 +139,21 @@ var FetchRequestBackend = /** @class */ (function () {
|
|
|
147
139
|
path += context.computedPath.startsWith("/")
|
|
148
140
|
? context.computedPath.substring(1)
|
|
149
141
|
: context.computedPath;
|
|
150
|
-
var
|
|
142
|
+
var origin = undefined;
|
|
143
|
+
if (typeof window !== "undefined") {
|
|
144
|
+
origin = window.origin;
|
|
145
|
+
}
|
|
146
|
+
var url = new URL(path, origin);
|
|
151
147
|
if (computedConfig.query) {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
148
|
+
if (context.computedConfig.queryParser) {
|
|
149
|
+
url.search = context.computedConfig.queryParser(computedConfig.query);
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
var queryKeys = Object.keys(computedConfig.query);
|
|
153
|
+
for (var i = 0; i < queryKeys.length; i++) {
|
|
154
|
+
var key = queryKeys[i];
|
|
155
|
+
url.searchParams.append(key, ((_a = computedConfig.query[key]) === null || _a === void 0 ? void 0 : _a.toString()) || "");
|
|
156
|
+
}
|
|
156
157
|
}
|
|
157
158
|
}
|
|
158
159
|
// abort controller is a newer feature than fetch
|
|
@@ -195,7 +196,6 @@ var FetchRequestBackend = /** @class */ (function () {
|
|
|
195
196
|
canceler: abortSignal
|
|
196
197
|
? function () { return !responded && abortController.abort(); }
|
|
197
198
|
: function () {
|
|
198
|
-
console.warn("Request aborted");
|
|
199
199
|
softAbort = true;
|
|
200
200
|
},
|
|
201
201
|
};
|
|
@@ -2,6 +2,7 @@ import RequestBackend, { RequestBackendErrorInfo, RequestOperation } from "./Req
|
|
|
2
2
|
import { ApiResponse } from "../ApiTypes";
|
|
3
3
|
import RequestContext from "../RequestContext";
|
|
4
4
|
export default class MockRequestBackend implements RequestBackend<ApiResponse> {
|
|
5
|
+
readonly id = "mock";
|
|
5
6
|
convertResponse<T>(context: RequestContext, response: ApiResponse, error?: boolean): Promise<ApiResponse<T>>;
|
|
6
7
|
extractResponseFromError(error: Error): Promise<ApiResponse | null | undefined>;
|
|
7
8
|
private runRequest;
|
|
@@ -41,6 +41,7 @@ var Utils_1 = require("../Utils");
|
|
|
41
41
|
var RequestError_1 = require("../RequestError");
|
|
42
42
|
var MockRequestBackend = /** @class */ (function () {
|
|
43
43
|
function MockRequestBackend() {
|
|
44
|
+
this.id = "mock";
|
|
44
45
|
}
|
|
45
46
|
MockRequestBackend.prototype.convertResponse = function (context, response, error) {
|
|
46
47
|
return __awaiter(this, void 0, void 0, function () {
|
|
@@ -8,8 +8,9 @@ export interface RequestBackendErrorInfo {
|
|
|
8
8
|
code: string;
|
|
9
9
|
}
|
|
10
10
|
export default interface RequestBackend<R = any> {
|
|
11
|
+
readonly id: string;
|
|
11
12
|
makeRequest(context: RequestContext): RequestOperation<R>;
|
|
12
|
-
convertResponse<T>(context: RequestContext, response: R
|
|
13
|
+
convertResponse<T>(context: RequestContext, response: R): Promise<ApiResponse<T>>;
|
|
13
14
|
extractResponseFromError(error: Error): Promise<R | null | undefined>;
|
|
14
15
|
getErrorInfo(error: Error, response: ApiResponse | undefined | null): RequestBackendErrorInfo | undefined;
|
|
15
16
|
}
|
package/cjs/index.d.ts
CHANGED
package/cjs/index.js
CHANGED
|
@@ -14,6 +14,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
14
14
|
exports.LoggingMiddleware = exports.CacheMiddleware = exports.FetchRequestBackend = exports.AxiosRequestBackend = exports.LocaleForageCacheBackend = exports.LocalStorageCacheBackend = exports.setCacheBackend = exports.clearCache = exports.isRequestError = void 0;
|
|
15
15
|
__exportStar(require("./Api"), exports);
|
|
16
16
|
__exportStar(require("./ApiTypes"), exports);
|
|
17
|
+
__exportStar(require("./UtilTypes"), exports);
|
|
17
18
|
__exportStar(require("./ApiConstants"), exports);
|
|
18
19
|
var RequestError_1 = require("./RequestError");
|
|
19
20
|
Object.defineProperty(exports, "isRequestError", { enumerable: true, get: function () { return RequestError_1.isRequestError; } });
|
package/esm/ApiTypes.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { CacheSource, EventResultType, RequestEvent, RequestMethod, ResponseType
|
|
|
4
4
|
export declare type AcceptableStatus = number | [min: number, max: number];
|
|
5
5
|
export declare type Headers = Record<string, string | number | boolean | null | undefined>;
|
|
6
6
|
export declare type Params = string;
|
|
7
|
-
export declare type Query = Record<string,
|
|
7
|
+
export declare type Query = Record<string, any>;
|
|
8
8
|
export declare type Body = string | number | Record<string, any>;
|
|
9
9
|
export interface ApiResponse<T = any> {
|
|
10
10
|
status: number;
|
|
@@ -17,6 +17,7 @@ export interface BaseRequestConfig {
|
|
|
17
17
|
retry?: number | false;
|
|
18
18
|
headers?: Readonly<Headers>;
|
|
19
19
|
acceptableStatus?: AcceptableStatus[];
|
|
20
|
+
queryParser?: (query: any) => string;
|
|
20
21
|
}
|
|
21
22
|
export declare type RequestConfig<P extends Params | undefined = Params | undefined, Q extends Query | undefined = Query | undefined, B extends Body | undefined = Body | undefined> = (P extends undefined ? {
|
|
22
23
|
params?: never;
|
package/esm/ApiUtils.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { AcceptableStatus,
|
|
1
|
+
import { AcceptableStatus, CancelledRequestError } from "./ApiTypes";
|
|
2
|
+
import { ResponseType } from "./ApiConstants";
|
|
2
3
|
export declare const isCancelledError: (error: Error) => error is CancelledRequestError;
|
|
3
4
|
export declare const isNetworkError: (error: Error) => boolean;
|
|
4
|
-
export declare const parseResponseDataToObject: (response: ApiResponse) => void;
|
|
5
5
|
export declare const isAcceptableStatus: (status: number, acceptableStatus?: AcceptableStatus[] | undefined) => boolean;
|
|
6
|
+
export declare const inferResponseType: (contentType: string | null | undefined) => ResponseType;
|
package/esm/ApiUtils.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { textDecode } from "./TextDecoding";
|
|
2
1
|
export var isCancelledError = function (error) {
|
|
3
2
|
return "isCancelledRequest" in error;
|
|
4
3
|
};
|
|
@@ -8,21 +7,6 @@ export var isNetworkError = function (error) {
|
|
|
8
7
|
error.message === "Network Error" ||
|
|
9
8
|
((_a = error.constructor) === null || _a === void 0 ? void 0 : _a.name) === "NetworkError");
|
|
10
9
|
};
|
|
11
|
-
export var parseResponseDataToObject = function (response) {
|
|
12
|
-
if (response.data &&
|
|
13
|
-
typeof response.data === "object") {
|
|
14
|
-
var data = response.data;
|
|
15
|
-
if (data.constructor && data.constructor.name === "ArrayBuffer") {
|
|
16
|
-
try {
|
|
17
|
-
var decodedData = (response.data = textDecode(data));
|
|
18
|
-
response.data = JSON.parse(decodedData);
|
|
19
|
-
}
|
|
20
|
-
catch (e) {
|
|
21
|
-
console.warn("Couldn't parse array buffer content to JSON response", e);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
};
|
|
26
10
|
var DEFAULT_ACCEPTABLE_STATUS = [[200, 299], 304];
|
|
27
11
|
export var isAcceptableStatus = function (status, acceptableStatus) {
|
|
28
12
|
var acceptable = acceptableStatus !== null && acceptableStatus !== void 0 ? acceptableStatus : DEFAULT_ACCEPTABLE_STATUS;
|
|
@@ -42,3 +26,21 @@ export var isAcceptableStatus = function (status, acceptableStatus) {
|
|
|
42
26
|
}
|
|
43
27
|
return (false);
|
|
44
28
|
};
|
|
29
|
+
var TEXT_CONTENT_TYPES = ["text/plain"];
|
|
30
|
+
var JSON_CONTENT_TYPES = ["text/json", "application/json"];
|
|
31
|
+
var ARRRAY_BUFFER_CONTENT_TYPES = ["application/octet-stream"];
|
|
32
|
+
export var inferResponseType = function (contentType) {
|
|
33
|
+
var contentTypePart = contentType === null || contentType === void 0 ? void 0 : contentType.split(";")[0].trim();
|
|
34
|
+
if (contentTypePart) {
|
|
35
|
+
if (TEXT_CONTENT_TYPES.includes(contentTypePart)) {
|
|
36
|
+
return "text";
|
|
37
|
+
}
|
|
38
|
+
else if (JSON_CONTENT_TYPES.includes(contentTypePart)) {
|
|
39
|
+
return "json";
|
|
40
|
+
}
|
|
41
|
+
else if (ARRRAY_BUFFER_CONTENT_TYPES.includes(contentTypePart)) {
|
|
42
|
+
return "arraybuffer";
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return "text";
|
|
46
|
+
};
|
package/esm/RequestError.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export declare const RequestErrorCode: {
|
|
|
5
5
|
readonly REQUEST_NETWORK_ERROR: "request/network-error";
|
|
6
6
|
readonly REQUEST_INVALID_STATUS: "request/invalid-status";
|
|
7
7
|
readonly REQUEST_INVALID_CONFIG: "request/invalid-config";
|
|
8
|
+
readonly REQUEST_MISMATCH_RESPONSE_TYPE: "request/mismatch-response-type";
|
|
8
9
|
};
|
|
9
10
|
export declare type RequestErrorCode = EnumOf<typeof RequestErrorCode>;
|
|
10
11
|
export interface RequestError extends Error {
|
package/esm/RequestError.js
CHANGED
|
@@ -3,6 +3,7 @@ export var RequestErrorCode = {
|
|
|
3
3
|
REQUEST_NETWORK_ERROR: "request/network-error",
|
|
4
4
|
REQUEST_INVALID_STATUS: "request/invalid-status",
|
|
5
5
|
REQUEST_INVALID_CONFIG: "request/invalid-config",
|
|
6
|
+
REQUEST_MISMATCH_RESPONSE_TYPE: "request/mismatch-response-type",
|
|
6
7
|
};
|
|
7
8
|
export var isRequestError = function (error) {
|
|
8
9
|
return "isRequestError" in error;
|
package/esm/Requester.js
CHANGED
|
@@ -46,18 +46,19 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
46
46
|
}
|
|
47
47
|
};
|
|
48
48
|
import * as ApiUtils from "./ApiUtils";
|
|
49
|
-
import { isAcceptableStatus, isNetworkError } from "./ApiUtils";
|
|
49
|
+
import { inferResponseType, isAcceptableStatus, isNetworkError } from "./ApiUtils";
|
|
50
50
|
import RequestContext from "./RequestContext";
|
|
51
51
|
import * as Api from "./Api";
|
|
52
52
|
import { EventResultType, RequestEvent } from "./ApiConstants";
|
|
53
53
|
import retry from "./util/retry";
|
|
54
54
|
import MockRequestBackend from "./backend/MockRequestBackend";
|
|
55
55
|
import { convertToRequestError, isRequestError, RequestErrorCode } from "./RequestError";
|
|
56
|
+
import { textDecode } from "./TextDecoding";
|
|
56
57
|
var locks = {};
|
|
57
58
|
var runningOperations = {};
|
|
58
59
|
var MOCK_REQUEST_BACKEND = new MockRequestBackend();
|
|
59
60
|
export var submit = function (host, config, mocking) { return __awaiter(void 0, void 0, void 0, function () {
|
|
60
|
-
var computedConfig, backend, context, key,
|
|
61
|
+
var computedConfig, backend, context, key, lock, lockedContext, response, successEventResult, error_1;
|
|
61
62
|
return __generator(this, function (_a) {
|
|
62
63
|
switch (_a.label) {
|
|
63
64
|
case 0:
|
|
@@ -68,10 +69,6 @@ export var submit = function (host, config, mocking) { return __awaiter(void 0,
|
|
|
68
69
|
}
|
|
69
70
|
context = new RequestContext(backend, host, computedConfig, host.computePath(host.path, config), mocking);
|
|
70
71
|
key = context.key;
|
|
71
|
-
sameRequest = runningOperations[key];
|
|
72
|
-
if (sameRequest) {
|
|
73
|
-
return [2 /*return*/, sameRequest];
|
|
74
|
-
}
|
|
75
72
|
lock = (context.computedConfig || {}).lock;
|
|
76
73
|
if (lock) {
|
|
77
74
|
lockedContext = locks[lock];
|
|
@@ -118,6 +115,7 @@ var makeRequest = function (context) { return __awaiter(void 0, void 0, void 0,
|
|
|
118
115
|
if (process.env.NODE_ENV === "development") {
|
|
119
116
|
if (Api.isRequestBackendDefault() && !defaultBackendMessageShown) {
|
|
120
117
|
defaultBackendMessageShown = true;
|
|
118
|
+
// eslint-disable-next-line
|
|
121
119
|
console.warn("[api-def] Using default fetch backend, you can use a different one with 'setRequestBackend()' (dev only message)");
|
|
122
120
|
}
|
|
123
121
|
}
|
|
@@ -173,10 +171,6 @@ var makeRequest = function (context) { return __awaiter(void 0, void 0, void 0,
|
|
|
173
171
|
error = _b.sent();
|
|
174
172
|
context.error = error;
|
|
175
173
|
context.response = error.response;
|
|
176
|
-
// transform array buffer responses to objs
|
|
177
|
-
if (context.response) {
|
|
178
|
-
ApiUtils.parseResponseDataToObject(context.response);
|
|
179
|
-
}
|
|
180
174
|
return [4 /*yield*/, context.triggerEvent(RequestEvent.Error)];
|
|
181
175
|
case 6:
|
|
182
176
|
errorEventResult = _b.sent();
|
|
@@ -213,16 +207,46 @@ var makeRequest = function (context) { return __awaiter(void 0, void 0, void 0,
|
|
|
213
207
|
});
|
|
214
208
|
}); };
|
|
215
209
|
var parseResponse = function (context, response, error) { return __awaiter(void 0, void 0, void 0, function () {
|
|
216
|
-
var parsedResponse;
|
|
217
|
-
|
|
218
|
-
|
|
210
|
+
var parsedResponse, contentType, inferredResponseType, data, decodedData;
|
|
211
|
+
var _a;
|
|
212
|
+
return __generator(this, function (_b) {
|
|
213
|
+
switch (_b.label) {
|
|
219
214
|
case 0:
|
|
220
215
|
if (!response) return [3 /*break*/, 2];
|
|
221
|
-
return [4 /*yield*/, context.backend.convertResponse(context, response
|
|
216
|
+
return [4 /*yield*/, context.backend.convertResponse(context, response)];
|
|
222
217
|
case 1:
|
|
223
|
-
parsedResponse =
|
|
224
|
-
|
|
225
|
-
|
|
218
|
+
parsedResponse = _b.sent();
|
|
219
|
+
contentType = response.headers.get("Content-Type");
|
|
220
|
+
inferredResponseType = inferResponseType(contentType);
|
|
221
|
+
if (!error) {
|
|
222
|
+
// expand to array buffer once we support that in inferResponseType
|
|
223
|
+
if (inferredResponseType === "text" && context.responseType === "json") {
|
|
224
|
+
throw convertToRequestError({
|
|
225
|
+
error: new Error("[api-def] Expected '" + context.responseType + "' response, got '" + inferredResponseType + "' (from 'Content-Type' of '" + contentType + "')"),
|
|
226
|
+
code: RequestErrorCode.REQUEST_MISMATCH_RESPONSE_TYPE,
|
|
227
|
+
response: parsedResponse,
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
// transform arrayBuffer to json
|
|
231
|
+
if (inferredResponseType === "arraybuffer" && context.responseType === "json") {
|
|
232
|
+
if (parsedResponse.data &&
|
|
233
|
+
typeof parsedResponse.data === "object") {
|
|
234
|
+
data = response.data;
|
|
235
|
+
if (((_a = data.constructor) === null || _a === void 0 ? void 0 : _a.name) === "ArrayBuffer") {
|
|
236
|
+
try {
|
|
237
|
+
decodedData = (response.data = textDecode(data));
|
|
238
|
+
response.data = JSON.parse(decodedData);
|
|
239
|
+
}
|
|
240
|
+
catch (e) {
|
|
241
|
+
throw convertToRequestError({
|
|
242
|
+
error: new Error("[api-def] Expected '" + context.responseType + "' response, got '" + inferredResponseType + "' (from 'Content-Type' of '" + contentType + "')"),
|
|
243
|
+
code: RequestErrorCode.REQUEST_MISMATCH_RESPONSE_TYPE,
|
|
244
|
+
response: parsedResponse,
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
226
250
|
}
|
|
227
251
|
return [2 /*return*/, parsedResponse];
|
|
228
252
|
case 2: return [2 /*return*/, response];
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import Endpoint from "./Endpoint";
|
|
2
|
+
export declare type ResponseOf<E extends Endpoint<any, any, any, any>> = E extends Endpoint<infer R, any, any, any> ? R : never;
|
|
3
|
+
export declare type ParamsOf<E extends Endpoint<any, any, any, any>> = E extends Endpoint<any, infer P, any, any> ? P : never;
|
|
4
|
+
export declare type QueryOf<E extends Endpoint<any, any, any, any>> = E extends Endpoint<any, any, infer Q, any> ? Q : never;
|
|
5
|
+
export declare type BodyOf<E extends Endpoint<any, any, any, any>> = E extends Endpoint<any, any, any, infer B> ? B : never;
|
package/esm/UtilTypes.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import RequestBackend, { RequestBackendErrorInfo, RequestOperation } from "./RequestBackend";
|
|
2
2
|
import { ApiResponse } from "../ApiTypes";
|
|
3
|
-
import type { AxiosError, AxiosResponse
|
|
3
|
+
import type { AxiosError, AxiosResponse } 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
|
-
|
|
7
|
+
readonly id = "axios";
|
|
8
|
+
constructor(axiosLibrary: any);
|
|
8
9
|
extractResponseFromError(error: Error): Promise<AxiosResponse | null | undefined>;
|
|
9
10
|
convertResponse<T>(context: RequestContext, response: AxiosResponse): Promise<ApiResponse<T>>;
|
|
10
11
|
makeRequest(context: RequestContext): RequestOperation<AxiosResponse>;
|
|
@@ -39,7 +39,9 @@ export var isAxiosError = function (error) {
|
|
|
39
39
|
return "isAxiosError" in error;
|
|
40
40
|
};
|
|
41
41
|
var AxiosRequestBackend = /** @class */ (function () {
|
|
42
|
+
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
42
43
|
function AxiosRequestBackend(axiosLibrary) {
|
|
44
|
+
this.id = "axios";
|
|
43
45
|
axios = axiosLibrary;
|
|
44
46
|
}
|
|
45
47
|
AxiosRequestBackend.prototype.extractResponseFromError = function (error) {
|
|
@@ -73,6 +75,7 @@ var AxiosRequestBackend = /** @class */ (function () {
|
|
|
73
75
|
cancelToken: new axios.CancelToken(function (cancellerFunc) {
|
|
74
76
|
canceler = cancellerFunc;
|
|
75
77
|
}),
|
|
78
|
+
paramsSerializer: context.computedConfig.queryParser,
|
|
76
79
|
});
|
|
77
80
|
return {
|
|
78
81
|
promise: promise,
|
|
@@ -2,15 +2,14 @@ import RequestBackend, { RequestBackendErrorInfo, RequestOperation } from "./Req
|
|
|
2
2
|
import { ApiResponse } from "../ApiTypes";
|
|
3
3
|
import RequestContext from "../RequestContext";
|
|
4
4
|
import { Fetch } from "../Utils";
|
|
5
|
-
import { ResponseType } from "../ApiConstants";
|
|
6
5
|
export default class FetchRequestBackend implements RequestBackend<Response> {
|
|
7
6
|
fetch: (((input: RequestInfo, init?: RequestInit | undefined) => Promise<Response>) & typeof fetch) | undefined;
|
|
7
|
+
readonly id = "fetch";
|
|
8
8
|
constructor(fetchLibrary?: Fetch);
|
|
9
9
|
extractResponseFromError(error: Error): Promise<Response | null | undefined>;
|
|
10
|
-
inferResponseType(response: Response): ResponseType;
|
|
11
10
|
convertResponse<T>(context: RequestContext, response: Response & {
|
|
12
11
|
__text?: string;
|
|
13
|
-
}
|
|
12
|
+
}): Promise<ApiResponse<T>>;
|
|
14
13
|
makeRequest(context: RequestContext): RequestOperation<Response>;
|
|
15
14
|
getErrorInfo(error: Error, response: ApiResponse | undefined | null): RequestBackendErrorInfo | undefined;
|
|
16
15
|
}
|
|
@@ -52,6 +52,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
52
52
|
import * as Utils from "../Utils";
|
|
53
53
|
import { getGlobalFetch } from "../Utils";
|
|
54
54
|
import { ResponseType } from "../ApiConstants";
|
|
55
|
+
import { inferResponseType } from "../ApiUtils";
|
|
55
56
|
var FetchError = /** @class */ (function (_super) {
|
|
56
57
|
__extends(FetchError, _super);
|
|
57
58
|
function FetchError() {
|
|
@@ -62,6 +63,7 @@ var FetchError = /** @class */ (function (_super) {
|
|
|
62
63
|
var FetchRequestBackend = /** @class */ (function () {
|
|
63
64
|
function FetchRequestBackend(fetchLibrary) {
|
|
64
65
|
this.fetch = getGlobalFetch();
|
|
66
|
+
this.id = "fetch";
|
|
65
67
|
if (fetchLibrary !== undefined) {
|
|
66
68
|
this.fetch = fetchLibrary;
|
|
67
69
|
}
|
|
@@ -78,57 +80,47 @@ var FetchRequestBackend = /** @class */ (function () {
|
|
|
78
80
|
});
|
|
79
81
|
});
|
|
80
82
|
};
|
|
81
|
-
FetchRequestBackend.prototype.
|
|
82
|
-
var contentType = response.headers.get("Content-Type");
|
|
83
|
-
if (contentType === null || contentType === void 0 ? void 0 : contentType.startsWith("json")) {
|
|
84
|
-
return "json";
|
|
85
|
-
}
|
|
86
|
-
return "text";
|
|
87
|
-
};
|
|
88
|
-
FetchRequestBackend.prototype.convertResponse = function (context, response, error) {
|
|
83
|
+
FetchRequestBackend.prototype.convertResponse = function (context, response) {
|
|
89
84
|
return __awaiter(this, void 0, void 0, function () {
|
|
90
|
-
var
|
|
85
|
+
var contentType, responseType, _a, data, status, headers, error_1;
|
|
91
86
|
return __generator(this, function (_b) {
|
|
92
87
|
switch (_b.label) {
|
|
93
88
|
case 0:
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
_b.trys.push([1, 8, , 9]);
|
|
98
|
-
if (!!response.__text) return [3 /*break*/, 3];
|
|
89
|
+
contentType = response.headers.get("Content-Type");
|
|
90
|
+
responseType = inferResponseType(contentType);
|
|
91
|
+
if (!!response.__text) return [3 /*break*/, 2];
|
|
99
92
|
_a = response;
|
|
100
93
|
return [4 /*yield*/, response.clone().text()];
|
|
101
|
-
case
|
|
94
|
+
case 1:
|
|
102
95
|
_a.__text = _b.sent();
|
|
96
|
+
_b.label = 2;
|
|
97
|
+
case 2:
|
|
98
|
+
data = response.__text;
|
|
99
|
+
status = response.status, headers = response.headers;
|
|
103
100
|
_b.label = 3;
|
|
104
101
|
case 3:
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
return [3 /*break*/, 7];
|
|
108
|
-
case 4:
|
|
109
|
-
if (!(responseType === ResponseType.ArrayBuffer)) return [3 /*break*/, 6];
|
|
102
|
+
_b.trys.push([3, 7, , 8]);
|
|
103
|
+
if (!(responseType === ResponseType.ArrayBuffer)) return [3 /*break*/, 5];
|
|
110
104
|
return [4 /*yield*/, response.clone().arrayBuffer()];
|
|
111
|
-
case
|
|
105
|
+
case 4:
|
|
112
106
|
data = _b.sent();
|
|
113
|
-
return [3 /*break*/,
|
|
114
|
-
case
|
|
107
|
+
return [3 /*break*/, 6];
|
|
108
|
+
case 5:
|
|
115
109
|
if (responseType === ResponseType.Json) {
|
|
116
110
|
data = JSON.parse(response.__text);
|
|
117
111
|
}
|
|
118
|
-
_b.label =
|
|
119
|
-
case
|
|
120
|
-
case
|
|
112
|
+
_b.label = 6;
|
|
113
|
+
case 6: return [3 /*break*/, 8];
|
|
114
|
+
case 7:
|
|
121
115
|
error_1 = _b.sent();
|
|
122
116
|
throw Object.assign(new Error("[api-def] Invalid '" + context.responseType + "' response, got: '" + response.__text + "'"), {
|
|
123
117
|
response: response,
|
|
124
118
|
});
|
|
125
|
-
case
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
headers: response.headers,
|
|
131
|
-
}];
|
|
119
|
+
case 8: return [2 /*return*/, {
|
|
120
|
+
data: data,
|
|
121
|
+
status: status,
|
|
122
|
+
headers: headers,
|
|
123
|
+
}];
|
|
132
124
|
}
|
|
133
125
|
});
|
|
134
126
|
});
|
|
@@ -145,12 +137,21 @@ var FetchRequestBackend = /** @class */ (function () {
|
|
|
145
137
|
path += context.computedPath.startsWith("/")
|
|
146
138
|
? context.computedPath.substring(1)
|
|
147
139
|
: context.computedPath;
|
|
148
|
-
var
|
|
140
|
+
var origin = undefined;
|
|
141
|
+
if (typeof window !== "undefined") {
|
|
142
|
+
origin = window.origin;
|
|
143
|
+
}
|
|
144
|
+
var url = new URL(path, origin);
|
|
149
145
|
if (computedConfig.query) {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
146
|
+
if (context.computedConfig.queryParser) {
|
|
147
|
+
url.search = context.computedConfig.queryParser(computedConfig.query);
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
var queryKeys = Object.keys(computedConfig.query);
|
|
151
|
+
for (var i = 0; i < queryKeys.length; i++) {
|
|
152
|
+
var key = queryKeys[i];
|
|
153
|
+
url.searchParams.append(key, ((_a = computedConfig.query[key]) === null || _a === void 0 ? void 0 : _a.toString()) || "");
|
|
154
|
+
}
|
|
154
155
|
}
|
|
155
156
|
}
|
|
156
157
|
// abort controller is a newer feature than fetch
|
|
@@ -193,7 +194,6 @@ var FetchRequestBackend = /** @class */ (function () {
|
|
|
193
194
|
canceler: abortSignal
|
|
194
195
|
? function () { return !responded && abortController.abort(); }
|
|
195
196
|
: function () {
|
|
196
|
-
console.warn("Request aborted");
|
|
197
197
|
softAbort = true;
|
|
198
198
|
},
|
|
199
199
|
};
|
|
@@ -2,6 +2,7 @@ import RequestBackend, { RequestBackendErrorInfo, RequestOperation } from "./Req
|
|
|
2
2
|
import { ApiResponse } from "../ApiTypes";
|
|
3
3
|
import RequestContext from "../RequestContext";
|
|
4
4
|
export default class MockRequestBackend implements RequestBackend<ApiResponse> {
|
|
5
|
+
readonly id = "mock";
|
|
5
6
|
convertResponse<T>(context: RequestContext, response: ApiResponse, error?: boolean): Promise<ApiResponse<T>>;
|
|
6
7
|
extractResponseFromError(error: Error): Promise<ApiResponse | null | undefined>;
|
|
7
8
|
private runRequest;
|
|
@@ -39,6 +39,7 @@ import { delayThenReturn, randInt } from "../Utils";
|
|
|
39
39
|
import { convertToRequestError, RequestErrorCode } from "../RequestError";
|
|
40
40
|
var MockRequestBackend = /** @class */ (function () {
|
|
41
41
|
function MockRequestBackend() {
|
|
42
|
+
this.id = "mock";
|
|
42
43
|
}
|
|
43
44
|
MockRequestBackend.prototype.convertResponse = function (context, response, error) {
|
|
44
45
|
return __awaiter(this, void 0, void 0, function () {
|
|
@@ -8,8 +8,9 @@ export interface RequestBackendErrorInfo {
|
|
|
8
8
|
code: string;
|
|
9
9
|
}
|
|
10
10
|
export default interface RequestBackend<R = any> {
|
|
11
|
+
readonly id: string;
|
|
11
12
|
makeRequest(context: RequestContext): RequestOperation<R>;
|
|
12
|
-
convertResponse<T>(context: RequestContext, response: R
|
|
13
|
+
convertResponse<T>(context: RequestContext, response: R): Promise<ApiResponse<T>>;
|
|
13
14
|
extractResponseFromError(error: Error): Promise<R | null | undefined>;
|
|
14
15
|
getErrorInfo(error: Error, response: ApiResponse | undefined | null): RequestBackendErrorInfo | undefined;
|
|
15
16
|
}
|
package/esm/index.d.ts
CHANGED
package/esm/index.js
CHANGED