api-def 0.6.0-alpha9 → 0.6.2-alpha.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/LICENSE +20 -20
- package/README.md +34 -34
- package/cjs/Api.d.ts +1 -0
- package/cjs/Api.js +2 -1
- package/cjs/ApiConstants.d.ts +1 -0
- package/cjs/ApiConstants.js +1 -0
- package/cjs/ApiUtils.d.ts +2 -3
- package/cjs/ApiUtils.js +13 -21
- package/cjs/Endpoint.js +4 -4
- package/cjs/MockingTypes.d.ts +1 -0
- package/cjs/RequestContext.d.ts +3 -0
- package/cjs/RequestContext.js +29 -2
- package/cjs/RequestError.js +4 -1
- package/cjs/Requester.js +52 -20
- package/cjs/backend/AxiosRequestBackend.d.ts +3 -3
- package/cjs/backend/AxiosRequestBackend.js +8 -15
- package/cjs/backend/FetchRequestBackend.d.ts +3 -3
- package/cjs/backend/FetchRequestBackend.js +27 -39
- package/cjs/backend/MockRequestBackend.js +15 -7
- package/cjs/backend/RequestBackend.d.ts +4 -1
- package/cjs/cache/Caching.d.ts +1 -1
- package/cjs/index.js +5 -1
- package/cjs/middleware/LoggingMiddleware.js +7 -7
- package/esm/Api.d.ts +1 -0
- package/esm/Api.js +2 -1
- package/esm/ApiConstants.d.ts +1 -0
- package/esm/ApiConstants.js +1 -0
- package/esm/ApiUtils.d.ts +2 -3
- package/esm/ApiUtils.js +12 -19
- package/esm/Endpoint.js +4 -4
- package/esm/MockingTypes.d.ts +1 -0
- package/esm/RequestContext.d.ts +3 -0
- package/esm/RequestContext.js +29 -2
- package/esm/RequestError.js +4 -1
- package/esm/Requester.js +46 -14
- package/esm/backend/AxiosRequestBackend.d.ts +3 -3
- package/esm/backend/AxiosRequestBackend.js +7 -14
- package/esm/backend/FetchRequestBackend.d.ts +3 -3
- package/esm/backend/FetchRequestBackend.js +26 -38
- package/esm/backend/MockRequestBackend.js +11 -3
- package/esm/backend/RequestBackend.d.ts +4 -1
- package/esm/cache/Caching.d.ts +1 -1
- package/esm/middleware/LoggingMiddleware.js +7 -7
- package/package.json +17 -5
- package/CHANGELOG.md +0 -71
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2019 James Waterhouse
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2019 James Waterhouse
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
21
|
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
# [api-def](https://github.com/Censkh/api-def/) · [](https://github.com/Censkh/api-def/blob/master/LICENSE) [](https://www.npmjs.com/package/api-def) [](https://github.com/Censkh/api-def/actions)
|
|
2
|
-
|
|
3
|
-
Typed APIs with middleware support
|
|
4
|
-
|
|
5
|
-
API def provides a unified way to type your endpoints allowing for compile time checking of query, body, response and even url parameters
|
|
6
|
-
|
|
7
|
-
``` npm i api-def ```
|
|
8
|
-
|
|
9
|
-
- [Documentation](https://censkh.github.io/api-def/)
|
|
10
|
-
|
|
11
|
-
```typescript
|
|
12
|
-
import {Api} from "api-def";
|
|
13
|
-
|
|
14
|
-
const api = new Api({
|
|
15
|
-
baseUrl: "https://my-api/",
|
|
16
|
-
name: "My API",
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
const fetchData = api.endpoint()
|
|
20
|
-
.queryOf<{ includeAwesome: boolean; }>()
|
|
21
|
-
.responseOf<{ data: {awesome: boolean; } }>()
|
|
22
|
-
.build({
|
|
23
|
-
id: "fetch_data",
|
|
24
|
-
method: "get",
|
|
25
|
-
path: "/data"
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
// calls GET https://my-api/data?includeAwesome=true
|
|
29
|
-
const res = await fetchData.submit({
|
|
30
|
-
query: {includeAwesome: true}
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
console.log(res.data); // { data: { awesome: true } }
|
|
34
|
-
```
|
|
1
|
+
# [api-def](https://github.com/Censkh/api-def/) · [](https://github.com/Censkh/api-def/blob/master/LICENSE) [](https://www.npmjs.com/package/api-def) [](https://github.com/Censkh/api-def/actions)
|
|
2
|
+
|
|
3
|
+
Typed APIs with middleware support
|
|
4
|
+
|
|
5
|
+
API def provides a unified way to type your endpoints allowing for compile time checking of query, body, response and even url parameters
|
|
6
|
+
|
|
7
|
+
``` npm i api-def ```
|
|
8
|
+
|
|
9
|
+
- [Documentation](https://censkh.github.io/api-def/)
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
import {Api} from "api-def";
|
|
13
|
+
|
|
14
|
+
const api = new Api({
|
|
15
|
+
baseUrl: "https://my-api/",
|
|
16
|
+
name: "My API",
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
const fetchData = api.endpoint()
|
|
20
|
+
.queryOf<{ includeAwesome: boolean; }>()
|
|
21
|
+
.responseOf<{ data: {awesome: boolean; } }>()
|
|
22
|
+
.build({
|
|
23
|
+
id: "fetch_data",
|
|
24
|
+
method: "get",
|
|
25
|
+
path: "/data"
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
// calls GET https://my-api/data?includeAwesome=true
|
|
29
|
+
const res = await fetchData.submit({
|
|
30
|
+
query: {includeAwesome: true}
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
console.log(res.data); // { data: { awesome: true } }
|
|
34
|
+
```
|
package/cjs/Api.d.ts
CHANGED
|
@@ -28,4 +28,5 @@ export declare class Api implements ApiInfo {
|
|
|
28
28
|
post: <R = unknown>(path: string, config: RequestConfig) => Promise<ApiResponse<R>>;
|
|
29
29
|
put: <R = unknown>(path: string, config: RequestConfig) => Promise<ApiResponse<R>>;
|
|
30
30
|
delete: <R = unknown>(path: string, config: RequestConfig) => Promise<ApiResponse<R>>;
|
|
31
|
+
patch: <R = unknown>(path: string, config: RequestConfig) => Promise<ApiResponse<R>>;
|
|
31
32
|
}
|
package/cjs/Api.js
CHANGED
|
@@ -77,7 +77,7 @@ var HotRequestHost = /** @class */ (function () {
|
|
|
77
77
|
return Utils.assign({}, apiDefaults, config);
|
|
78
78
|
};
|
|
79
79
|
HotRequestHost.prototype.computePath = function (path, config) {
|
|
80
|
-
return path.startsWith("/") ? path : "/"
|
|
80
|
+
return path.startsWith("/") ? path : "/".concat(path);
|
|
81
81
|
};
|
|
82
82
|
return HotRequestHost;
|
|
83
83
|
}());
|
|
@@ -98,6 +98,7 @@ var Api = /** @class */ (function () {
|
|
|
98
98
|
this.post = this.hotRequest(ApiConstants_1.RequestMethod.POST);
|
|
99
99
|
this.put = this.hotRequest(ApiConstants_1.RequestMethod.PUT);
|
|
100
100
|
this.delete = this.hotRequest(ApiConstants_1.RequestMethod.DELETE);
|
|
101
|
+
this.patch = this.hotRequest(ApiConstants_1.RequestMethod.PATCH);
|
|
101
102
|
this.name = info.name;
|
|
102
103
|
this.baseUrl = info.baseUrl;
|
|
103
104
|
this.middleware = info.middleware || [];
|
package/cjs/ApiConstants.d.ts
CHANGED
package/cjs/ApiConstants.js
CHANGED
package/cjs/ApiUtils.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { AcceptableStatus,
|
|
1
|
+
import { AcceptableStatus, CancelledRequestError } from "./ApiTypes";
|
|
2
2
|
import { ResponseType } from "./ApiConstants";
|
|
3
3
|
export declare const isCancelledError: (error: Error) => error is CancelledRequestError;
|
|
4
4
|
export declare const isNetworkError: (error: Error) => boolean;
|
|
5
|
-
export declare const
|
|
6
|
-
export declare const isAcceptableStatus: (status: number, acceptableStatus?: AcceptableStatus[] | undefined) => boolean;
|
|
5
|
+
export declare const isAcceptableStatus: (status: number, acceptableStatus?: AcceptableStatus[]) => boolean;
|
|
7
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.inferResponseType = exports.isAcceptableStatus = 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,23 +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
|
-
// eslint-disable-next-line
|
|
27
|
-
console.warn("[api-def] Couldn't parse array buffer content to JSON response", e);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
};
|
|
32
|
-
exports.parseResponseDataToObject = parseResponseDataToObject;
|
|
33
15
|
var DEFAULT_ACCEPTABLE_STATUS = [[200, 299], 304];
|
|
34
16
|
var isAcceptableStatus = function (status, acceptableStatus) {
|
|
35
17
|
var acceptable = acceptableStatus !== null && acceptableStatus !== void 0 ? acceptableStatus : DEFAULT_ACCEPTABLE_STATUS;
|
|
@@ -50,11 +32,21 @@ var isAcceptableStatus = function (status, acceptableStatus) {
|
|
|
50
32
|
return (false);
|
|
51
33
|
};
|
|
52
34
|
exports.isAcceptableStatus = isAcceptableStatus;
|
|
35
|
+
var TEXT_CONTENT_TYPES = ["text/plain"];
|
|
53
36
|
var JSON_CONTENT_TYPES = ["text/json", "application/json"];
|
|
37
|
+
var ARRRAY_BUFFER_CONTENT_TYPES = ["application/octet-stream"];
|
|
54
38
|
var inferResponseType = function (contentType) {
|
|
55
39
|
var contentTypePart = contentType === null || contentType === void 0 ? void 0 : contentType.split(";")[0].trim();
|
|
56
|
-
if (contentTypePart
|
|
57
|
-
|
|
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
|
+
}
|
|
58
50
|
}
|
|
59
51
|
return "text";
|
|
60
52
|
};
|
package/cjs/Endpoint.js
CHANGED
|
@@ -62,7 +62,7 @@ var Endpoint = /** @class */ (function () {
|
|
|
62
62
|
mockingEnabled = (_a = (typeof apiMocking.enabled === "function" ? apiMocking.enabled() : apiMocking.enabled)) !== null && _a !== void 0 ? _a : false;
|
|
63
63
|
if (mockingEnabled) {
|
|
64
64
|
if (!((_b = this.mocking) === null || _b === void 0 ? void 0 : _b.handler)) {
|
|
65
|
-
throw new Error("[api-def] Endpoint for '"
|
|
65
|
+
throw new Error("[api-def] Endpoint for '".concat(this.path, "' has no mocking"));
|
|
66
66
|
}
|
|
67
67
|
mock = true;
|
|
68
68
|
}
|
|
@@ -72,16 +72,16 @@ var Endpoint = /** @class */ (function () {
|
|
|
72
72
|
});
|
|
73
73
|
};
|
|
74
74
|
Endpoint.prototype.computePath = function (path, request) {
|
|
75
|
-
var computedPath = path.startsWith("/") ? path : "/"
|
|
75
|
+
var computedPath = path.startsWith("/") ? path : "/".concat(path);
|
|
76
76
|
if (request.params) {
|
|
77
77
|
var keys = Object.keys(request.params);
|
|
78
78
|
for (var i = 0; i < keys.length; i++) {
|
|
79
79
|
var argName = keys[i];
|
|
80
|
-
computedPath = computedPath.replace(":"
|
|
80
|
+
computedPath = computedPath.replace(":".concat(argName), request.params[argName]);
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
83
|
if (computedPath.includes(":")) {
|
|
84
|
-
throw new Error("[api-def] Not all path params have been resolved: '"
|
|
84
|
+
throw new Error("[api-def] Not all path params have been resolved: '".concat(computedPath, "'"));
|
|
85
85
|
}
|
|
86
86
|
return computedPath;
|
|
87
87
|
};
|
package/cjs/MockingTypes.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export interface MockRequest<R = any, P extends Params | undefined = Params | un
|
|
|
11
11
|
export interface MockResponse<R = any, P extends Params | undefined = Params | undefined, Q extends Query | undefined = Query | undefined, B extends Body | undefined = Body | undefined> {
|
|
12
12
|
statusCode: number;
|
|
13
13
|
response: R | undefined;
|
|
14
|
+
headers: Headers;
|
|
14
15
|
status(statusCode: number): this;
|
|
15
16
|
send(response: R): this;
|
|
16
17
|
}
|
package/cjs/RequestContext.d.ts
CHANGED
|
@@ -19,6 +19,7 @@ export default class RequestContext<R = any, P extends Params | undefined = Para
|
|
|
19
19
|
cancelled: boolean;
|
|
20
20
|
readonly computedConfig: RequestConfig<P, Q, B>;
|
|
21
21
|
readonly mocking: EndpointMockingConfig<R, P, Q, B> | null | undefined;
|
|
22
|
+
private parsedBody;
|
|
22
23
|
constructor(backend: RequestBackend, host: RequestHost, config: RequestConfig<P, Q, B>, computedPath: string, mocking: EndpointMockingConfig<R, P, Q, B> | null | undefined);
|
|
23
24
|
get method(): RequestMethod;
|
|
24
25
|
get api(): Api;
|
|
@@ -27,6 +28,8 @@ export default class RequestContext<R = any, P extends Params | undefined = Para
|
|
|
27
28
|
private initMiddleware;
|
|
28
29
|
private generateKey;
|
|
29
30
|
updateHeaders(newHeaders: Headers): this;
|
|
31
|
+
private parseRequestBody;
|
|
32
|
+
getParsedBody(): any;
|
|
30
33
|
updateQuery(newQuery: Partial<Q>): this;
|
|
31
34
|
triggerEvent(eventType: RequestEvent): Promise<EventResult<R> | undefined>;
|
|
32
35
|
addCanceller(canceler: () => void): void;
|
package/cjs/RequestContext.js
CHANGED
|
@@ -37,6 +37,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
39
|
var Utils = require("./Utils");
|
|
40
|
+
var url_1 = require("url");
|
|
40
41
|
var contextIdCounter = 0;
|
|
41
42
|
var RequestContext = /** @class */ (function () {
|
|
42
43
|
function RequestContext(backend, host, config, computedPath, mocking) {
|
|
@@ -49,7 +50,7 @@ var RequestContext = /** @class */ (function () {
|
|
|
49
50
|
this.id = contextIdCounter++;
|
|
50
51
|
this.host = host;
|
|
51
52
|
this.computedConfig = config;
|
|
52
|
-
Utils.assign({}, this.computedConfig.headers
|
|
53
|
+
Utils.assign({}, this.computedConfig.headers);
|
|
53
54
|
this.computedPath = computedPath;
|
|
54
55
|
this.key = this.generateKey();
|
|
55
56
|
this.stats = {
|
|
@@ -59,6 +60,7 @@ var RequestContext = /** @class */ (function () {
|
|
|
59
60
|
this.eventHandlers = {};
|
|
60
61
|
this.mocking = mocking;
|
|
61
62
|
this.initMiddleware();
|
|
63
|
+
this.parseRequestBody();
|
|
62
64
|
}
|
|
63
65
|
Object.defineProperty(RequestContext.prototype, "method", {
|
|
64
66
|
get: function () {
|
|
@@ -111,7 +113,7 @@ var RequestContext = /** @class */ (function () {
|
|
|
111
113
|
var queryKeys = Object.keys(computedConfig.query);
|
|
112
114
|
for (var i = 0; i < queryKeys.length; i++) {
|
|
113
115
|
var queryKey = queryKeys[i];
|
|
114
|
-
queryStrings.push(queryKey
|
|
116
|
+
queryStrings.push("".concat(queryKey, "=").concat(computedConfig.query[queryKey]));
|
|
115
117
|
}
|
|
116
118
|
}
|
|
117
119
|
if (queryStrings.length > 0) {
|
|
@@ -121,8 +123,33 @@ var RequestContext = /** @class */ (function () {
|
|
|
121
123
|
};
|
|
122
124
|
RequestContext.prototype.updateHeaders = function (newHeaders) {
|
|
123
125
|
this.computedConfig.headers = Utils.assign({}, this.computedConfig.headers, newHeaders);
|
|
126
|
+
this.parseRequestBody();
|
|
124
127
|
return this;
|
|
125
128
|
};
|
|
129
|
+
RequestContext.prototype.parseRequestBody = function () {
|
|
130
|
+
if (this.computedConfig.body && this.computedConfig.headers) {
|
|
131
|
+
var contentTypeKey = Object.keys(this.computedConfig.headers).find(function (key) { return key.toLowerCase() === "content-type"; });
|
|
132
|
+
var contentType = contentTypeKey && this.computedConfig.headers[contentTypeKey];
|
|
133
|
+
if (typeof contentType === "string" && contentType.toLowerCase() === "multipart/form-data") {
|
|
134
|
+
var searchParams = new url_1.URLSearchParams();
|
|
135
|
+
for (var _i = 0, _a = Object.keys(this.computedConfig.body); _i < _a.length; _i++) {
|
|
136
|
+
var key = _a[_i];
|
|
137
|
+
var value = this.computedConfig.body[key];
|
|
138
|
+
searchParams.set(key, value === null || value === void 0 ? void 0 : value.toString());
|
|
139
|
+
}
|
|
140
|
+
this.parsedBody = searchParams.toString();
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
this.parsedBody = this.computedConfig.body;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
this.parsedBody = undefined;
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
RequestContext.prototype.getParsedBody = function () {
|
|
151
|
+
return this.parsedBody;
|
|
152
|
+
};
|
|
126
153
|
RequestContext.prototype.updateQuery = function (newQuery) {
|
|
127
154
|
this.computedConfig.query = Utils.assign(this.computedConfig.query || {}, newQuery);
|
|
128
155
|
return this;
|
package/cjs/RequestError.js
CHANGED
|
@@ -15,10 +15,13 @@ exports.isRequestError = isRequestError;
|
|
|
15
15
|
var convertToRequestError = function (config) {
|
|
16
16
|
var error = config.error, response = config.response, code = config.code;
|
|
17
17
|
return Object.assign(error, {
|
|
18
|
-
name:
|
|
18
|
+
name: "RequestError",
|
|
19
19
|
response: response,
|
|
20
20
|
code: code,
|
|
21
21
|
isRequestError: true,
|
|
22
|
+
config: undefined,
|
|
23
|
+
request: undefined,
|
|
24
|
+
toJSON: undefined,
|
|
22
25
|
});
|
|
23
26
|
};
|
|
24
27
|
exports.convertToRequestError = convertToRequestError;
|
package/cjs/Requester.js
CHANGED
|
@@ -56,6 +56,7 @@ 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();
|
|
@@ -155,9 +156,9 @@ var makeRequest = function (context) { return __awaiter(void 0, void 0, void 0,
|
|
|
155
156
|
return [4 /*yield*/, parseResponse(context, response_1)];
|
|
156
157
|
case 3:
|
|
157
158
|
parsedResponse = (_b.sent());
|
|
158
|
-
if (!ApiUtils_1.isAcceptableStatus(parsedResponse.status, context.computedConfig.acceptableStatus)) {
|
|
159
|
-
throw RequestError_1.convertToRequestError({
|
|
160
|
-
error: new Error("[api-def] Invalid response status code '"
|
|
159
|
+
if (!(0, ApiUtils_1.isAcceptableStatus)(parsedResponse.status, context.computedConfig.acceptableStatus)) {
|
|
160
|
+
throw (0, RequestError_1.convertToRequestError)({
|
|
161
|
+
error: new Error("[api-def] Invalid response status code '".concat(parsedResponse.status, "'")),
|
|
161
162
|
response: parsedResponse,
|
|
162
163
|
code: RequestError_1.RequestErrorCode.REQUEST_INVALID_STATUS,
|
|
163
164
|
});
|
|
@@ -174,10 +175,6 @@ var makeRequest = function (context) { return __awaiter(void 0, void 0, void 0,
|
|
|
174
175
|
error = _b.sent();
|
|
175
176
|
context.error = error;
|
|
176
177
|
context.response = error.response;
|
|
177
|
-
// transform array buffer responses to objs
|
|
178
|
-
if (context.response) {
|
|
179
|
-
ApiUtils.parseResponseDataToObject(context.response);
|
|
180
|
-
}
|
|
181
178
|
return [4 /*yield*/, context.triggerEvent(ApiConstants_1.RequestEvent.Error)];
|
|
182
179
|
case 6:
|
|
183
180
|
errorEventResult = _b.sent();
|
|
@@ -206,7 +203,7 @@ var makeRequest = function (context) { return __awaiter(void 0, void 0, void 0,
|
|
|
206
203
|
}
|
|
207
204
|
});
|
|
208
205
|
}); };
|
|
209
|
-
return [4 /*yield*/, retry_1.default(performRequest, retryOpts)];
|
|
206
|
+
return [4 /*yield*/, (0, retry_1.default)(performRequest, retryOpts)];
|
|
210
207
|
case 2:
|
|
211
208
|
response = _b.sent();
|
|
212
209
|
return [2 /*return*/, (response)];
|
|
@@ -214,18 +211,53 @@ var makeRequest = function (context) { return __awaiter(void 0, void 0, void 0,
|
|
|
214
211
|
});
|
|
215
212
|
}); };
|
|
216
213
|
var parseResponse = function (context, response, error) { return __awaiter(void 0, void 0, void 0, function () {
|
|
217
|
-
var
|
|
218
|
-
|
|
219
|
-
|
|
214
|
+
var parsedResponse_1, contentType, inferredResponseType, data, decodedData;
|
|
215
|
+
var _a;
|
|
216
|
+
return __generator(this, function (_b) {
|
|
217
|
+
switch (_b.label) {
|
|
220
218
|
case 0:
|
|
221
219
|
if (!response) return [3 /*break*/, 2];
|
|
222
|
-
return [4 /*yield*/, context.backend.convertResponse(context, response
|
|
220
|
+
return [4 /*yield*/, context.backend.convertResponse(context, response)];
|
|
223
221
|
case 1:
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
222
|
+
parsedResponse_1 = _b.sent();
|
|
223
|
+
// lowercase all header names
|
|
224
|
+
parsedResponse_1.headers = parsedResponse_1.__lowercaseHeaders || Object.keys(parsedResponse_1.headers).reduce(function (headers, header) {
|
|
225
|
+
headers[header.toLowerCase()] = parsedResponse_1.headers[header];
|
|
226
|
+
return headers;
|
|
227
|
+
}, {});
|
|
228
|
+
contentType = parsedResponse_1.headers["content-type"];
|
|
229
|
+
inferredResponseType = (0, ApiUtils_1.inferResponseType)(contentType);
|
|
230
|
+
if (!error) {
|
|
231
|
+
// expand to array buffer once we support that in inferResponseType
|
|
232
|
+
if (inferredResponseType === "text" && context.responseType === "json") {
|
|
233
|
+
throw (0, RequestError_1.convertToRequestError)({
|
|
234
|
+
error: new Error("[api-def] Expected '".concat(context.responseType, "' response, got '").concat(inferredResponseType, "' (from 'Content-Type' of '").concat(contentType, "')")),
|
|
235
|
+
code: RequestError_1.RequestErrorCode.REQUEST_MISMATCH_RESPONSE_TYPE,
|
|
236
|
+
response: parsedResponse_1,
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
// transform arrayBuffer to json
|
|
240
|
+
if (inferredResponseType === "arraybuffer" && context.responseType === "json") {
|
|
241
|
+
if (parsedResponse_1.data &&
|
|
242
|
+
typeof parsedResponse_1.data === "object") {
|
|
243
|
+
data = response.data;
|
|
244
|
+
if (((_a = data.constructor) === null || _a === void 0 ? void 0 : _a.name) === "ArrayBuffer") {
|
|
245
|
+
try {
|
|
246
|
+
decodedData = (response.data = (0, TextDecoding_1.textDecode)(data));
|
|
247
|
+
response.data = JSON.parse(decodedData);
|
|
248
|
+
}
|
|
249
|
+
catch (e) {
|
|
250
|
+
throw (0, RequestError_1.convertToRequestError)({
|
|
251
|
+
error: new Error("[api-def] Expected '".concat(context.responseType, "' response, got '").concat(inferredResponseType, "' (from 'Content-Type' of '").concat(contentType, "')")),
|
|
252
|
+
code: RequestError_1.RequestErrorCode.REQUEST_MISMATCH_RESPONSE_TYPE,
|
|
253
|
+
response: parsedResponse_1,
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
227
259
|
}
|
|
228
|
-
return [2 /*return*/,
|
|
260
|
+
return [2 /*return*/, parsedResponse_1];
|
|
229
261
|
case 2: return [2 /*return*/, response];
|
|
230
262
|
}
|
|
231
263
|
});
|
|
@@ -235,7 +267,7 @@ var parseError = function (context, rawError) { return __awaiter(void 0, void 0,
|
|
|
235
267
|
return __generator(this, function (_a) {
|
|
236
268
|
switch (_a.label) {
|
|
237
269
|
case 0:
|
|
238
|
-
if (!RequestError_1.isRequestError(rawError)) return [3 /*break*/, 1];
|
|
270
|
+
if (!(0, RequestError_1.isRequestError)(rawError)) return [3 /*break*/, 1];
|
|
239
271
|
error = rawError;
|
|
240
272
|
return [3 /*break*/, 5];
|
|
241
273
|
case 1: return [4 /*yield*/, context.backend.extractResponseFromError(rawError)];
|
|
@@ -248,14 +280,14 @@ var parseError = function (context, rawError) { return __awaiter(void 0, void 0,
|
|
|
248
280
|
errorResponse = _a.sent();
|
|
249
281
|
_a.label = 4;
|
|
250
282
|
case 4:
|
|
251
|
-
code = ApiUtils_1.isNetworkError(rawError) ? RequestError_1.RequestErrorCode.REQUEST_NETWORK_ERROR : RequestError_1.RequestErrorCode.MISC_UNKNOWN_ERROR;
|
|
283
|
+
code = (0, ApiUtils_1.isNetworkError)(rawError) ? RequestError_1.RequestErrorCode.REQUEST_NETWORK_ERROR : RequestError_1.RequestErrorCode.MISC_UNKNOWN_ERROR;
|
|
252
284
|
if (errorResponse) {
|
|
253
|
-
if (!ApiUtils_1.isAcceptableStatus(errorResponse.status, context.computedConfig.acceptableStatus)) {
|
|
285
|
+
if (!(0, ApiUtils_1.isAcceptableStatus)(errorResponse.status, context.computedConfig.acceptableStatus)) {
|
|
254
286
|
code = RequestError_1.RequestErrorCode.REQUEST_INVALID_STATUS;
|
|
255
287
|
}
|
|
256
288
|
}
|
|
257
289
|
errorInfo = context.backend.getErrorInfo(rawError, errorResponse);
|
|
258
|
-
error = RequestError_1.convertToRequestError(__assign({ error: rawError, response: errorResponse, code: code }, errorInfo));
|
|
290
|
+
error = (0, RequestError_1.convertToRequestError)(__assign({ error: rawError, response: errorResponse, code: code }, errorInfo));
|
|
259
291
|
_a.label = 5;
|
|
260
292
|
case 5: return [2 /*return*/, error];
|
|
261
293
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import RequestBackend, { RequestBackendErrorInfo, RequestOperation } from "./RequestBackend";
|
|
1
|
+
import RequestBackend, { ConvertedApiResponse, RequestBackendErrorInfo, RequestOperation } from "./RequestBackend";
|
|
2
2
|
import { ApiResponse } from "../ApiTypes";
|
|
3
3
|
import type { AxiosError, AxiosResponse } from "axios";
|
|
4
4
|
import RequestContext from "../RequestContext";
|
|
5
|
-
export declare const isAxiosError: (error: Error) => error is AxiosError<any>;
|
|
5
|
+
export declare const isAxiosError: (error: Error) => error is AxiosError<unknown, any>;
|
|
6
6
|
export default class AxiosRequestBackend implements RequestBackend<AxiosResponse> {
|
|
7
7
|
readonly id = "axios";
|
|
8
8
|
constructor(axiosLibrary: any);
|
|
9
9
|
extractResponseFromError(error: Error): Promise<AxiosResponse | null | undefined>;
|
|
10
|
-
convertResponse<T>(context: RequestContext, response: AxiosResponse): Promise<
|
|
10
|
+
convertResponse<T>(context: RequestContext, response: AxiosResponse): Promise<ConvertedApiResponse<T>>;
|
|
11
11
|
makeRequest(context: RequestContext): RequestOperation<AxiosResponse>;
|
|
12
12
|
getErrorInfo(error: Error, response: ApiResponse | undefined | null): RequestBackendErrorInfo | undefined;
|
|
13
13
|
}
|
|
@@ -37,8 +37,6 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
39
|
exports.isAxiosError = void 0;
|
|
40
|
-
var ApiUtils_1 = require("../ApiUtils");
|
|
41
|
-
var RequestError_1 = require("../RequestError");
|
|
42
40
|
var axios;
|
|
43
41
|
var isAxiosError = function (error) {
|
|
44
42
|
return "isAxiosError" in error;
|
|
@@ -53,7 +51,7 @@ var AxiosRequestBackend = /** @class */ (function () {
|
|
|
53
51
|
AxiosRequestBackend.prototype.extractResponseFromError = function (error) {
|
|
54
52
|
return __awaiter(this, void 0, void 0, function () {
|
|
55
53
|
return __generator(this, function (_a) {
|
|
56
|
-
if (exports.isAxiosError(error)) {
|
|
54
|
+
if ((0, exports.isAxiosError)(error)) {
|
|
57
55
|
return [2 /*return*/, error.response ? error.response : null];
|
|
58
56
|
}
|
|
59
57
|
return [2 /*return*/, undefined];
|
|
@@ -62,18 +60,13 @@ var AxiosRequestBackend = /** @class */ (function () {
|
|
|
62
60
|
};
|
|
63
61
|
AxiosRequestBackend.prototype.convertResponse = function (context, response) {
|
|
64
62
|
return __awaiter(this, void 0, void 0, function () {
|
|
65
|
-
var contentType, inferredResponseType;
|
|
66
63
|
return __generator(this, function (_a) {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
code: RequestError_1.RequestErrorCode.REQUEST_MISMATCH_RESPONSE_TYPE,
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
return [2 /*return*/, response];
|
|
64
|
+
return [2 /*return*/, {
|
|
65
|
+
data: response.data,
|
|
66
|
+
headers: response.headers,
|
|
67
|
+
status: response.status,
|
|
68
|
+
__lowercaseHeaders: response._lowerCaseResponseHeaders,
|
|
69
|
+
}];
|
|
77
70
|
});
|
|
78
71
|
});
|
|
79
72
|
};
|
|
@@ -84,7 +77,7 @@ var AxiosRequestBackend = /** @class */ (function () {
|
|
|
84
77
|
method: context.method,
|
|
85
78
|
baseURL: context.baseUrl,
|
|
86
79
|
url: context.computedPath,
|
|
87
|
-
data:
|
|
80
|
+
data: context.getParsedBody() || {},
|
|
88
81
|
params: computedConfig.query || {},
|
|
89
82
|
headers: computedConfig.headers || {},
|
|
90
83
|
responseType: context.responseType,
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import RequestBackend, { RequestBackendErrorInfo, RequestOperation } from "./RequestBackend";
|
|
1
|
+
import RequestBackend, { ConvertedApiResponse, RequestBackendErrorInfo, RequestOperation } from "./RequestBackend";
|
|
2
2
|
import { ApiResponse } from "../ApiTypes";
|
|
3
3
|
import RequestContext from "../RequestContext";
|
|
4
4
|
import { Fetch } from "../Utils";
|
|
5
5
|
export default class FetchRequestBackend implements RequestBackend<Response> {
|
|
6
|
-
fetch: (((input: RequestInfo, init?: RequestInit | undefined) => Promise<Response>) & typeof fetch) | undefined;
|
|
6
|
+
fetch: (((input: RequestInfo | URL, init?: RequestInit | undefined) => Promise<Response>) & typeof fetch) | undefined;
|
|
7
7
|
readonly id = "fetch";
|
|
8
8
|
constructor(fetchLibrary?: Fetch);
|
|
9
9
|
extractResponseFromError(error: Error): Promise<Response | null | undefined>;
|
|
10
10
|
convertResponse<T>(context: RequestContext, response: Response & {
|
|
11
11
|
__text?: string;
|
|
12
|
-
}
|
|
12
|
+
}): Promise<ConvertedApiResponse<T>>;
|
|
13
13
|
makeRequest(context: RequestContext): RequestOperation<Response>;
|
|
14
14
|
getErrorInfo(error: Error, response: ApiResponse | undefined | null): RequestBackendErrorInfo | undefined;
|
|
15
15
|
}
|