api-def 0.6.1 → 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 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/) · [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/Censkh/api-def/blob/master/LICENSE) [![npm version](https://img.shields.io/npm/v/api-def.svg?style=flat)](https://www.npmjs.com/package/api-def) [![build status](https://img.shields.io/github/workflow/status/censkh/api-def/Node.js%20CI)](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/) &middot; [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/Censkh/api-def/blob/master/LICENSE) [![npm version](https://img.shields.io/npm/v/api-def.svg?style=flat)](https://www.npmjs.com/package/api-def) [![build status](https://img.shields.io/github/workflow/status/censkh/api-def/Node.js%20CI)](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.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 : "/" + path;
80
+ return path.startsWith("/") ? path : "/".concat(path);
81
81
  };
82
82
  return HotRequestHost;
83
83
  }());
package/cjs/ApiUtils.d.ts CHANGED
@@ -2,5 +2,5 @@ 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 isAcceptableStatus: (status: number, acceptableStatus?: AcceptableStatus[] | undefined) => boolean;
5
+ export declare const isAcceptableStatus: (status: number, acceptableStatus?: AcceptableStatus[]) => boolean;
6
6
  export declare const inferResponseType: (contentType: string | null | undefined) => ResponseType;
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 '" + this.path + "' has no mocking");
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 : "/" + 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(":" + argName, request.params[argName]);
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: '" + computedPath + "'");
84
+ throw new Error("[api-def] Not all path params have been resolved: '".concat(computedPath, "'"));
85
85
  }
86
86
  return computedPath;
87
87
  };
@@ -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
  }
@@ -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;
@@ -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, { "Request-Id": this.id });
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 + "=" + computedConfig.query[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/Requester.js CHANGED
@@ -156,9 +156,9 @@ var makeRequest = function (context) { return __awaiter(void 0, void 0, void 0,
156
156
  return [4 /*yield*/, parseResponse(context, response_1)];
157
157
  case 3:
158
158
  parsedResponse = (_b.sent());
159
- if (!ApiUtils_1.isAcceptableStatus(parsedResponse.status, context.computedConfig.acceptableStatus)) {
160
- throw RequestError_1.convertToRequestError({
161
- error: new Error("[api-def] Invalid response status code '" + parsedResponse.status + "'"),
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, "'")),
162
162
  response: parsedResponse,
163
163
  code: RequestError_1.RequestErrorCode.REQUEST_INVALID_STATUS,
164
164
  });
@@ -203,7 +203,7 @@ var makeRequest = function (context) { return __awaiter(void 0, void 0, void 0,
203
203
  }
204
204
  });
205
205
  }); };
206
- return [4 /*yield*/, retry_1.default(performRequest, retryOpts)];
206
+ return [4 /*yield*/, (0, retry_1.default)(performRequest, retryOpts)];
207
207
  case 2:
208
208
  response = _b.sent();
209
209
  return [2 /*return*/, (response)];
@@ -226,12 +226,12 @@ var parseResponse = function (context, response, error) { return __awaiter(void
226
226
  return headers;
227
227
  }, {});
228
228
  contentType = parsedResponse_1.headers["content-type"];
229
- inferredResponseType = ApiUtils_1.inferResponseType(contentType);
229
+ inferredResponseType = (0, ApiUtils_1.inferResponseType)(contentType);
230
230
  if (!error) {
231
231
  // expand to array buffer once we support that in inferResponseType
232
232
  if (inferredResponseType === "text" && context.responseType === "json") {
233
- throw RequestError_1.convertToRequestError({
234
- error: new Error("[api-def] Expected '" + context.responseType + "' response, got '" + inferredResponseType + "' (from 'Content-Type' of '" + contentType + "')"),
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
235
  code: RequestError_1.RequestErrorCode.REQUEST_MISMATCH_RESPONSE_TYPE,
236
236
  response: parsedResponse_1,
237
237
  });
@@ -243,12 +243,12 @@ var parseResponse = function (context, response, error) { return __awaiter(void
243
243
  data = response.data;
244
244
  if (((_a = data.constructor) === null || _a === void 0 ? void 0 : _a.name) === "ArrayBuffer") {
245
245
  try {
246
- decodedData = (response.data = TextDecoding_1.textDecode(data));
246
+ decodedData = (response.data = (0, TextDecoding_1.textDecode)(data));
247
247
  response.data = JSON.parse(decodedData);
248
248
  }
249
249
  catch (e) {
250
- throw RequestError_1.convertToRequestError({
251
- error: new Error("[api-def] Expected '" + context.responseType + "' response, got '" + inferredResponseType + "' (from 'Content-Type' of '" + contentType + "')"),
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
252
  code: RequestError_1.RequestErrorCode.REQUEST_MISMATCH_RESPONSE_TYPE,
253
253
  response: parsedResponse_1,
254
254
  });
@@ -267,7 +267,7 @@ var parseError = function (context, rawError) { return __awaiter(void 0, void 0,
267
267
  return __generator(this, function (_a) {
268
268
  switch (_a.label) {
269
269
  case 0:
270
- if (!RequestError_1.isRequestError(rawError)) return [3 /*break*/, 1];
270
+ if (!(0, RequestError_1.isRequestError)(rawError)) return [3 /*break*/, 1];
271
271
  error = rawError;
272
272
  return [3 /*break*/, 5];
273
273
  case 1: return [4 /*yield*/, context.backend.extractResponseFromError(rawError)];
@@ -280,14 +280,14 @@ var parseError = function (context, rawError) { return __awaiter(void 0, void 0,
280
280
  errorResponse = _a.sent();
281
281
  _a.label = 4;
282
282
  case 4:
283
- 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;
284
284
  if (errorResponse) {
285
- if (!ApiUtils_1.isAcceptableStatus(errorResponse.status, context.computedConfig.acceptableStatus)) {
285
+ if (!(0, ApiUtils_1.isAcceptableStatus)(errorResponse.status, context.computedConfig.acceptableStatus)) {
286
286
  code = RequestError_1.RequestErrorCode.REQUEST_INVALID_STATUS;
287
287
  }
288
288
  }
289
289
  errorInfo = context.backend.getErrorInfo(rawError, errorResponse);
290
- 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));
291
291
  _a.label = 5;
292
292
  case 5: return [2 /*return*/, error];
293
293
  }
@@ -2,7 +2,7 @@ import RequestBackend, { ConvertedApiResponse, RequestBackendErrorInfo, RequestO
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);
@@ -51,7 +51,7 @@ var AxiosRequestBackend = /** @class */ (function () {
51
51
  AxiosRequestBackend.prototype.extractResponseFromError = function (error) {
52
52
  return __awaiter(this, void 0, void 0, function () {
53
53
  return __generator(this, function (_a) {
54
- if (exports.isAxiosError(error)) {
54
+ if ((0, exports.isAxiosError)(error)) {
55
55
  return [2 /*return*/, error.response ? error.response : null];
56
56
  }
57
57
  return [2 /*return*/, undefined];
@@ -77,7 +77,7 @@ var AxiosRequestBackend = /** @class */ (function () {
77
77
  method: context.method,
78
78
  baseURL: context.baseUrl,
79
79
  url: context.computedPath,
80
- data: computedConfig.body || {},
80
+ data: context.getParsedBody() || {},
81
81
  params: computedConfig.query || {},
82
82
  headers: computedConfig.headers || {},
83
83
  responseType: context.responseType,
@@ -3,7 +3,7 @@ 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>;
@@ -64,7 +64,7 @@ var FetchError = /** @class */ (function (_super) {
64
64
  }(Error));
65
65
  var FetchRequestBackend = /** @class */ (function () {
66
66
  function FetchRequestBackend(fetchLibrary) {
67
- this.fetch = Utils_1.getGlobalFetch();
67
+ this.fetch = (0, Utils_1.getGlobalFetch)();
68
68
  this.id = "fetch";
69
69
  if (fetchLibrary !== undefined) {
70
70
  this.fetch = fetchLibrary;
@@ -89,7 +89,7 @@ var FetchRequestBackend = /** @class */ (function () {
89
89
  switch (_b.label) {
90
90
  case 0:
91
91
  contentType = response.headers.get("Content-Type");
92
- responseType = ApiUtils_1.inferResponseType(contentType);
92
+ responseType = (0, ApiUtils_1.inferResponseType)(contentType);
93
93
  if (!!response.__text) return [3 /*break*/, 2];
94
94
  _a = response;
95
95
  return [4 /*yield*/, response.clone().text()];
@@ -115,7 +115,7 @@ var FetchRequestBackend = /** @class */ (function () {
115
115
  case 6: return [3 /*break*/, 8];
116
116
  case 7:
117
117
  error_1 = _b.sent();
118
- throw Object.assign(new Error("[api-def] Invalid '" + context.responseType + "' response, got: '" + response.__text + "'"), {
118
+ throw Object.assign(new Error("[api-def] Invalid '".concat(context.responseType, "' response, got: '").concat(response.__text, "'")), {
119
119
  response: response,
120
120
  });
121
121
  case 8: return [2 /*return*/, {
@@ -161,7 +161,8 @@ var FetchRequestBackend = /** @class */ (function () {
161
161
  var abortSignal = abortController ? abortController.signal : undefined;
162
162
  var softAbort = false;
163
163
  var responded = false;
164
- var bodyJsonify = computedConfig.body !== null && typeof computedConfig.body === "object";
164
+ var body = context.getParsedBody();
165
+ var bodyJsonify = body !== null && typeof body === "object";
165
166
  var headers = Utils.assign({
166
167
  // logic from axios
167
168
  "Content-Type": bodyJsonify ? "application/json;charset=utf-8" : "application/x-www-form-urlencoded",
@@ -175,7 +176,7 @@ var FetchRequestBackend = /** @class */ (function () {
175
176
  }, {});
176
177
  var promise = this.fetch(url.href, {
177
178
  method: context.method,
178
- body: bodyJsonify ? JSON.stringify(computedConfig.body) : computedConfig.body,
179
+ body: bodyJsonify ? JSON.stringify(body) : body,
179
180
  headers: parsedHeaders,
180
181
  mode: "cors",
181
182
  signal: abortSignal,
@@ -65,25 +65,26 @@ var MockRequestBackend = /** @class */ (function () {
65
65
  MockRequestBackend.prototype.runRequest = function (context) {
66
66
  var _a, _b, _c, _d;
67
67
  return __awaiter(this, void 0, void 0, function () {
68
- var mockingFunc, req, res, delay, delayMs, min, max, _e;
68
+ var mockingFunc, req, res, delay, delayMs, min, max, _e, parsedHeaders;
69
69
  return __generator(this, function (_f) {
70
70
  switch (_f.label) {
71
71
  case 0:
72
72
  mockingFunc = (_a = context.mocking) === null || _a === void 0 ? void 0 : _a.handler;
73
73
  if (!mockingFunc) {
74
- throw RequestError_1.convertToRequestError({
74
+ throw (0, RequestError_1.convertToRequestError)({
75
75
  error: new Error("[api-def] Attempted to run mocked request without mocking function"),
76
76
  code: RequestError_1.RequestErrorCode.REQUEST_INVALID_CONFIG,
77
77
  });
78
78
  }
79
79
  req = {
80
- body: context.computedConfig.body,
80
+ body: context.getParsedBody(),
81
81
  params: (_b = context.computedConfig.params) !== null && _b !== void 0 ? _b : {},
82
82
  query: context.computedConfig.query,
83
83
  headers: (_c = context.computedConfig.headers) !== null && _c !== void 0 ? _c : {},
84
84
  };
85
85
  res = {
86
86
  statusCode: -1,
87
+ headers: {},
87
88
  response: undefined,
88
89
  status: function (statusCode) {
89
90
  res.statusCode = statusCode;
@@ -91,6 +92,9 @@ var MockRequestBackend = /** @class */ (function () {
91
92
  },
92
93
  send: function (response) {
93
94
  res.response = response;
95
+ if (response && typeof response === "object") {
96
+ res.headers["Content-Type"] = "application/json";
97
+ }
94
98
  return res;
95
99
  },
96
100
  };
@@ -103,12 +107,12 @@ var MockRequestBackend = /** @class */ (function () {
103
107
  else {
104
108
  min = delay[0], max = delay[1];
105
109
  if (min > max) {
106
- throw RequestError_1.convertToRequestError({
110
+ throw (0, RequestError_1.convertToRequestError)({
107
111
  error: new Error("[api-def] Min delay cannot be greater than max delay"),
108
112
  code: RequestError_1.RequestErrorCode.REQUEST_INVALID_CONFIG,
109
113
  });
110
114
  }
111
- delayMs = Utils_1.randInt(min, max);
115
+ delayMs = (0, Utils_1.randInt)(min, max);
112
116
  }
113
117
  _e = Utils_1.delayThenReturn;
114
118
  return [4 /*yield*/, mockingFunc(req, res)];
@@ -122,13 +126,17 @@ var MockRequestBackend = /** @class */ (function () {
122
126
  _f.label = 5;
123
127
  case 5:
124
128
  if (res.response === undefined) {
125
- throw RequestError_1.convertToRequestError({
129
+ throw (0, RequestError_1.convertToRequestError)({
126
130
  error: new Error("[api-def] Mocked API did not respond"),
127
131
  code: RequestError_1.RequestErrorCode.REQUEST_INVALID_CONFIG,
128
132
  });
129
133
  }
134
+ parsedHeaders = Object.keys(res.headers).reduce(function (parsedHeaders, key) {
135
+ parsedHeaders[key] = res.headers[key].toString();
136
+ return parsedHeaders;
137
+ }, {});
130
138
  return [2 /*return*/, {
131
- headers: {},
139
+ headers: parsedHeaders,
132
140
  data: res.response,
133
141
  status: res.statusCode,
134
142
  }];
@@ -6,5 +6,5 @@ export interface CacheEntry {
6
6
  data: any;
7
7
  expiry: number | null;
8
8
  }
9
- export declare const setCachedItem: <T>(key: string, value: T, expiry?: number | undefined) => Promise<T>;
9
+ export declare const setCachedItem: <T>(key: string, value: T, expiry?: number) => Promise<T>;
10
10
  export declare const getCachedItem: <T = any>(key: string) => Promise<T | undefined>;
package/cjs/index.js CHANGED
@@ -2,7 +2,11 @@
2
2
  "use strict";
3
3
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
4
  if (k2 === undefined) k2 = k;
5
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
6
10
  }) : (function(o, m, k, k2) {
7
11
  if (k2 === undefined) k2 = k;
8
12
  o[k2] = m[k];
@@ -30,12 +30,12 @@ var diagnoseError = function (error) {
30
30
  var _a = error.response, status = _a.status, data = _a.data;
31
31
  var code = data === null || data === void 0 ? void 0 : data.code;
32
32
  return {
33
- message: "responded with " + status + (code ? " (" + code + ")" : ""),
33
+ message: "responded with ".concat(status).concat(code ? " (".concat(code, ")") : ""),
34
34
  response: error.response,
35
35
  };
36
36
  };
37
37
  var formatTime = function (time) {
38
- return Utils.padNumber(time.getHours(), 2) + ":" + Utils.padNumber(time.getMinutes(), 2) + ":" + Utils.padNumber(time.getSeconds(), 2) + "." + Utils.padNumber(time.getMilliseconds(), 3);
38
+ return "".concat(Utils.padNumber(time.getHours(), 2), ":").concat(Utils.padNumber(time.getMinutes(), 2), ":").concat(Utils.padNumber(time.getSeconds(), 2), ".").concat(Utils.padNumber(time.getMilliseconds(), 3));
39
39
  };
40
40
  var log = function (context, type, message, config, objects) {
41
41
  if (typeof config.predicate === "function" && !config.predicate()) {
@@ -45,10 +45,10 @@ var log = function (context, type, message, config, objects) {
45
45
  var color = COLOR_MAP[type];
46
46
  var timestamp = formatTime(new Date());
47
47
  var args = [
48
- "%cnetwork %c[" + context.api.name + "] " + context.method.toUpperCase() + " " + computedPath + " %c" + message + " %c@ " + timestamp,
48
+ "%cnetwork %c[".concat(context.api.name, "] ").concat(context.method.toUpperCase(), " ").concat(computedPath, " %c").concat(message, " %c@ ").concat(timestamp),
49
49
  "color:gray",
50
50
  "color:auto",
51
- "color:" + color,
51
+ "color:".concat(color),
52
52
  "color:gray",
53
53
  ];
54
54
  /* eslint-disable-next-line no-console */
@@ -68,18 +68,18 @@ var LoggingMiddleware = function (config) {
68
68
  _a[ApiConstants_1.RequestEvent.Success] = function (context) {
69
69
  var _a;
70
70
  var cacheSource = context.cacheInfo.source;
71
- log(context, LogType.Success, "responded with " + ((_a = context.response) === null || _a === void 0 ? void 0 : _a.status) + (cacheSource ? " (cached by " + cacheSource + ")" : ""), config);
71
+ log(context, LogType.Success, "responded with ".concat((_a = context.response) === null || _a === void 0 ? void 0 : _a.status).concat(cacheSource ? " (cached by ".concat(cacheSource, ")") : ""), config);
72
72
  },
73
73
  _a[ApiConstants_1.RequestEvent.Error] = function (context) {
74
74
  if (context.error) {
75
75
  var _a = diagnoseError(context.error), error = _a.error, message = _a.message;
76
- log(context, LogType.Warn, "error on attempt " + context.stats.attempt + " - " + message, config, { error: error });
76
+ log(context, LogType.Warn, "error on attempt ".concat(context.stats.attempt, " - ").concat(message), config, { error: error });
77
77
  }
78
78
  },
79
79
  _a[ApiConstants_1.RequestEvent.UnrecoverableError] = function (context) {
80
80
  if (context.error) {
81
81
  var _a = diagnoseError(context.error), error = _a.error, message = _a.message;
82
- log(context, LogType.Error, "failed - " + message, config, {
82
+ log(context, LogType.Error, "failed - ".concat(message), config, {
83
83
  error: error,
84
84
  });
85
85
  }
package/esm/Api.js CHANGED
@@ -71,7 +71,7 @@ var HotRequestHost = /** @class */ (function () {
71
71
  return Utils.assign({}, apiDefaults, config);
72
72
  };
73
73
  HotRequestHost.prototype.computePath = function (path, config) {
74
- return path.startsWith("/") ? path : "/" + path;
74
+ return path.startsWith("/") ? path : "/".concat(path);
75
75
  };
76
76
  return HotRequestHost;
77
77
  }());
package/esm/ApiUtils.d.ts CHANGED
@@ -2,5 +2,5 @@ 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 isAcceptableStatus: (status: number, acceptableStatus?: AcceptableStatus[] | undefined) => boolean;
5
+ export declare const isAcceptableStatus: (status: number, acceptableStatus?: AcceptableStatus[]) => boolean;
6
6
  export declare const inferResponseType: (contentType: string | null | undefined) => ResponseType;
package/esm/Endpoint.js CHANGED
@@ -60,7 +60,7 @@ var Endpoint = /** @class */ (function () {
60
60
  mockingEnabled = (_a = (typeof apiMocking.enabled === "function" ? apiMocking.enabled() : apiMocking.enabled)) !== null && _a !== void 0 ? _a : false;
61
61
  if (mockingEnabled) {
62
62
  if (!((_b = this.mocking) === null || _b === void 0 ? void 0 : _b.handler)) {
63
- throw new Error("[api-def] Endpoint for '" + this.path + "' has no mocking");
63
+ throw new Error("[api-def] Endpoint for '".concat(this.path, "' has no mocking"));
64
64
  }
65
65
  mock = true;
66
66
  }
@@ -70,16 +70,16 @@ var Endpoint = /** @class */ (function () {
70
70
  });
71
71
  };
72
72
  Endpoint.prototype.computePath = function (path, request) {
73
- var computedPath = path.startsWith("/") ? path : "/" + path;
73
+ var computedPath = path.startsWith("/") ? path : "/".concat(path);
74
74
  if (request.params) {
75
75
  var keys = Object.keys(request.params);
76
76
  for (var i = 0; i < keys.length; i++) {
77
77
  var argName = keys[i];
78
- computedPath = computedPath.replace(":" + argName, request.params[argName]);
78
+ computedPath = computedPath.replace(":".concat(argName), request.params[argName]);
79
79
  }
80
80
  }
81
81
  if (computedPath.includes(":")) {
82
- throw new Error("[api-def] Not all path params have been resolved: '" + computedPath + "'");
82
+ throw new Error("[api-def] Not all path params have been resolved: '".concat(computedPath, "'"));
83
83
  }
84
84
  return computedPath;
85
85
  };
@@ -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
  }
@@ -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;
@@ -35,6 +35,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
35
35
  }
36
36
  };
37
37
  import * as Utils from "./Utils";
38
+ import { URLSearchParams } from "url";
38
39
  var contextIdCounter = 0;
39
40
  var RequestContext = /** @class */ (function () {
40
41
  function RequestContext(backend, host, config, computedPath, mocking) {
@@ -47,7 +48,7 @@ var RequestContext = /** @class */ (function () {
47
48
  this.id = contextIdCounter++;
48
49
  this.host = host;
49
50
  this.computedConfig = config;
50
- Utils.assign({}, this.computedConfig.headers, { "Request-Id": this.id });
51
+ Utils.assign({}, this.computedConfig.headers);
51
52
  this.computedPath = computedPath;
52
53
  this.key = this.generateKey();
53
54
  this.stats = {
@@ -57,6 +58,7 @@ var RequestContext = /** @class */ (function () {
57
58
  this.eventHandlers = {};
58
59
  this.mocking = mocking;
59
60
  this.initMiddleware();
61
+ this.parseRequestBody();
60
62
  }
61
63
  Object.defineProperty(RequestContext.prototype, "method", {
62
64
  get: function () {
@@ -109,7 +111,7 @@ var RequestContext = /** @class */ (function () {
109
111
  var queryKeys = Object.keys(computedConfig.query);
110
112
  for (var i = 0; i < queryKeys.length; i++) {
111
113
  var queryKey = queryKeys[i];
112
- queryStrings.push(queryKey + "=" + computedConfig.query[queryKey]);
114
+ queryStrings.push("".concat(queryKey, "=").concat(computedConfig.query[queryKey]));
113
115
  }
114
116
  }
115
117
  if (queryStrings.length > 0) {
@@ -119,8 +121,33 @@ var RequestContext = /** @class */ (function () {
119
121
  };
120
122
  RequestContext.prototype.updateHeaders = function (newHeaders) {
121
123
  this.computedConfig.headers = Utils.assign({}, this.computedConfig.headers, newHeaders);
124
+ this.parseRequestBody();
122
125
  return this;
123
126
  };
127
+ RequestContext.prototype.parseRequestBody = function () {
128
+ if (this.computedConfig.body && this.computedConfig.headers) {
129
+ var contentTypeKey = Object.keys(this.computedConfig.headers).find(function (key) { return key.toLowerCase() === "content-type"; });
130
+ var contentType = contentTypeKey && this.computedConfig.headers[contentTypeKey];
131
+ if (typeof contentType === "string" && contentType.toLowerCase() === "multipart/form-data") {
132
+ var searchParams = new URLSearchParams();
133
+ for (var _i = 0, _a = Object.keys(this.computedConfig.body); _i < _a.length; _i++) {
134
+ var key = _a[_i];
135
+ var value = this.computedConfig.body[key];
136
+ searchParams.set(key, value === null || value === void 0 ? void 0 : value.toString());
137
+ }
138
+ this.parsedBody = searchParams.toString();
139
+ }
140
+ else {
141
+ this.parsedBody = this.computedConfig.body;
142
+ }
143
+ }
144
+ else {
145
+ this.parsedBody = undefined;
146
+ }
147
+ };
148
+ RequestContext.prototype.getParsedBody = function () {
149
+ return this.parsedBody;
150
+ };
124
151
  RequestContext.prototype.updateQuery = function (newQuery) {
125
152
  this.computedConfig.query = Utils.assign(this.computedConfig.query || {}, newQuery);
126
153
  return this;
package/esm/Requester.js CHANGED
@@ -154,7 +154,7 @@ var makeRequest = function (context) { return __awaiter(void 0, void 0, void 0,
154
154
  parsedResponse = (_b.sent());
155
155
  if (!isAcceptableStatus(parsedResponse.status, context.computedConfig.acceptableStatus)) {
156
156
  throw convertToRequestError({
157
- error: new Error("[api-def] Invalid response status code '" + parsedResponse.status + "'"),
157
+ error: new Error("[api-def] Invalid response status code '".concat(parsedResponse.status, "'")),
158
158
  response: parsedResponse,
159
159
  code: RequestErrorCode.REQUEST_INVALID_STATUS,
160
160
  });
@@ -227,7 +227,7 @@ var parseResponse = function (context, response, error) { return __awaiter(void
227
227
  // expand to array buffer once we support that in inferResponseType
228
228
  if (inferredResponseType === "text" && context.responseType === "json") {
229
229
  throw convertToRequestError({
230
- error: new Error("[api-def] Expected '" + context.responseType + "' response, got '" + inferredResponseType + "' (from 'Content-Type' of '" + contentType + "')"),
230
+ error: new Error("[api-def] Expected '".concat(context.responseType, "' response, got '").concat(inferredResponseType, "' (from 'Content-Type' of '").concat(contentType, "')")),
231
231
  code: RequestErrorCode.REQUEST_MISMATCH_RESPONSE_TYPE,
232
232
  response: parsedResponse_1,
233
233
  });
@@ -244,7 +244,7 @@ var parseResponse = function (context, response, error) { return __awaiter(void
244
244
  }
245
245
  catch (e) {
246
246
  throw convertToRequestError({
247
- error: new Error("[api-def] Expected '" + context.responseType + "' response, got '" + inferredResponseType + "' (from 'Content-Type' of '" + contentType + "')"),
247
+ error: new Error("[api-def] Expected '".concat(context.responseType, "' response, got '").concat(inferredResponseType, "' (from 'Content-Type' of '").concat(contentType, "')")),
248
248
  code: RequestErrorCode.REQUEST_MISMATCH_RESPONSE_TYPE,
249
249
  response: parsedResponse_1,
250
250
  });
@@ -2,7 +2,7 @@ import RequestBackend, { ConvertedApiResponse, RequestBackendErrorInfo, RequestO
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);
@@ -73,7 +73,7 @@ var AxiosRequestBackend = /** @class */ (function () {
73
73
  method: context.method,
74
74
  baseURL: context.baseUrl,
75
75
  url: context.computedPath,
76
- data: computedConfig.body || {},
76
+ data: context.getParsedBody() || {},
77
77
  params: computedConfig.query || {},
78
78
  headers: computedConfig.headers || {},
79
79
  responseType: context.responseType,
@@ -3,7 +3,7 @@ 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>;
@@ -113,7 +113,7 @@ var FetchRequestBackend = /** @class */ (function () {
113
113
  case 6: return [3 /*break*/, 8];
114
114
  case 7:
115
115
  error_1 = _b.sent();
116
- throw Object.assign(new Error("[api-def] Invalid '" + context.responseType + "' response, got: '" + response.__text + "'"), {
116
+ throw Object.assign(new Error("[api-def] Invalid '".concat(context.responseType, "' response, got: '").concat(response.__text, "'")), {
117
117
  response: response,
118
118
  });
119
119
  case 8: return [2 /*return*/, {
@@ -159,7 +159,8 @@ var FetchRequestBackend = /** @class */ (function () {
159
159
  var abortSignal = abortController ? abortController.signal : undefined;
160
160
  var softAbort = false;
161
161
  var responded = false;
162
- var bodyJsonify = computedConfig.body !== null && typeof computedConfig.body === "object";
162
+ var body = context.getParsedBody();
163
+ var bodyJsonify = body !== null && typeof body === "object";
163
164
  var headers = Utils.assign({
164
165
  // logic from axios
165
166
  "Content-Type": bodyJsonify ? "application/json;charset=utf-8" : "application/x-www-form-urlencoded",
@@ -173,7 +174,7 @@ var FetchRequestBackend = /** @class */ (function () {
173
174
  }, {});
174
175
  var promise = this.fetch(url.href, {
175
176
  method: context.method,
176
- body: bodyJsonify ? JSON.stringify(computedConfig.body) : computedConfig.body,
177
+ body: bodyJsonify ? JSON.stringify(body) : body,
177
178
  headers: parsedHeaders,
178
179
  mode: "cors",
179
180
  signal: abortSignal,
@@ -63,7 +63,7 @@ var MockRequestBackend = /** @class */ (function () {
63
63
  MockRequestBackend.prototype.runRequest = function (context) {
64
64
  var _a, _b, _c, _d;
65
65
  return __awaiter(this, void 0, void 0, function () {
66
- var mockingFunc, req, res, delay, delayMs, min, max, _e;
66
+ var mockingFunc, req, res, delay, delayMs, min, max, _e, parsedHeaders;
67
67
  return __generator(this, function (_f) {
68
68
  switch (_f.label) {
69
69
  case 0:
@@ -75,13 +75,14 @@ var MockRequestBackend = /** @class */ (function () {
75
75
  });
76
76
  }
77
77
  req = {
78
- body: context.computedConfig.body,
78
+ body: context.getParsedBody(),
79
79
  params: (_b = context.computedConfig.params) !== null && _b !== void 0 ? _b : {},
80
80
  query: context.computedConfig.query,
81
81
  headers: (_c = context.computedConfig.headers) !== null && _c !== void 0 ? _c : {},
82
82
  };
83
83
  res = {
84
84
  statusCode: -1,
85
+ headers: {},
85
86
  response: undefined,
86
87
  status: function (statusCode) {
87
88
  res.statusCode = statusCode;
@@ -89,6 +90,9 @@ var MockRequestBackend = /** @class */ (function () {
89
90
  },
90
91
  send: function (response) {
91
92
  res.response = response;
93
+ if (response && typeof response === "object") {
94
+ res.headers["Content-Type"] = "application/json";
95
+ }
92
96
  return res;
93
97
  },
94
98
  };
@@ -125,8 +129,12 @@ var MockRequestBackend = /** @class */ (function () {
125
129
  code: RequestErrorCode.REQUEST_INVALID_CONFIG,
126
130
  });
127
131
  }
132
+ parsedHeaders = Object.keys(res.headers).reduce(function (parsedHeaders, key) {
133
+ parsedHeaders[key] = res.headers[key].toString();
134
+ return parsedHeaders;
135
+ }, {});
128
136
  return [2 /*return*/, {
129
- headers: {},
137
+ headers: parsedHeaders,
130
138
  data: res.response,
131
139
  status: res.statusCode,
132
140
  }];
@@ -6,5 +6,5 @@ export interface CacheEntry {
6
6
  data: any;
7
7
  expiry: number | null;
8
8
  }
9
- export declare const setCachedItem: <T>(key: string, value: T, expiry?: number | undefined) => Promise<T>;
9
+ export declare const setCachedItem: <T>(key: string, value: T, expiry?: number) => Promise<T>;
10
10
  export declare const getCachedItem: <T = any>(key: string) => Promise<T | undefined>;
@@ -28,12 +28,12 @@ var diagnoseError = function (error) {
28
28
  var _a = error.response, status = _a.status, data = _a.data;
29
29
  var code = data === null || data === void 0 ? void 0 : data.code;
30
30
  return {
31
- message: "responded with " + status + (code ? " (" + code + ")" : ""),
31
+ message: "responded with ".concat(status).concat(code ? " (".concat(code, ")") : ""),
32
32
  response: error.response,
33
33
  };
34
34
  };
35
35
  var formatTime = function (time) {
36
- return Utils.padNumber(time.getHours(), 2) + ":" + Utils.padNumber(time.getMinutes(), 2) + ":" + Utils.padNumber(time.getSeconds(), 2) + "." + Utils.padNumber(time.getMilliseconds(), 3);
36
+ return "".concat(Utils.padNumber(time.getHours(), 2), ":").concat(Utils.padNumber(time.getMinutes(), 2), ":").concat(Utils.padNumber(time.getSeconds(), 2), ".").concat(Utils.padNumber(time.getMilliseconds(), 3));
37
37
  };
38
38
  var log = function (context, type, message, config, objects) {
39
39
  if (typeof config.predicate === "function" && !config.predicate()) {
@@ -43,10 +43,10 @@ var log = function (context, type, message, config, objects) {
43
43
  var color = COLOR_MAP[type];
44
44
  var timestamp = formatTime(new Date());
45
45
  var args = [
46
- "%cnetwork %c[" + context.api.name + "] " + context.method.toUpperCase() + " " + computedPath + " %c" + message + " %c@ " + timestamp,
46
+ "%cnetwork %c[".concat(context.api.name, "] ").concat(context.method.toUpperCase(), " ").concat(computedPath, " %c").concat(message, " %c@ ").concat(timestamp),
47
47
  "color:gray",
48
48
  "color:auto",
49
- "color:" + color,
49
+ "color:".concat(color),
50
50
  "color:gray",
51
51
  ];
52
52
  /* eslint-disable-next-line no-console */
@@ -66,18 +66,18 @@ var LoggingMiddleware = function (config) {
66
66
  _a[RequestEvent.Success] = function (context) {
67
67
  var _a;
68
68
  var cacheSource = context.cacheInfo.source;
69
- log(context, LogType.Success, "responded with " + ((_a = context.response) === null || _a === void 0 ? void 0 : _a.status) + (cacheSource ? " (cached by " + cacheSource + ")" : ""), config);
69
+ log(context, LogType.Success, "responded with ".concat((_a = context.response) === null || _a === void 0 ? void 0 : _a.status).concat(cacheSource ? " (cached by ".concat(cacheSource, ")") : ""), config);
70
70
  },
71
71
  _a[RequestEvent.Error] = function (context) {
72
72
  if (context.error) {
73
73
  var _a = diagnoseError(context.error), error = _a.error, message = _a.message;
74
- log(context, LogType.Warn, "error on attempt " + context.stats.attempt + " - " + message, config, { error: error });
74
+ log(context, LogType.Warn, "error on attempt ".concat(context.stats.attempt, " - ").concat(message), config, { error: error });
75
75
  }
76
76
  },
77
77
  _a[RequestEvent.UnrecoverableError] = function (context) {
78
78
  if (context.error) {
79
79
  var _a = diagnoseError(context.error), error = _a.error, message = _a.message;
80
- log(context, LogType.Error, "failed - " + message, config, {
80
+ log(context, LogType.Error, "failed - ".concat(message), config, {
81
81
  error: error,
82
82
  });
83
83
  }
package/package.json CHANGED
@@ -1,14 +1,15 @@
1
1
  {
2
2
  "name": "api-def",
3
- "version": "0.6.1",
3
+ "version": "0.6.2-alpha.1",
4
4
  "description": "Typed API definitions with middleware support",
5
5
  "main": "cjs/index.js",
6
6
  "types": "esm/index.d.ts",
7
7
  "module": "esm/index.js",
8
8
  "sideEffects": false,
9
9
  "scripts": {
10
+ "prepublishOnly": "npm run test && npm run build",
10
11
  "test": "npm run test:types && npm run test:lint && npm run test:unit",
11
- "test:unit": "cross-env NODE_ENV=test jest",
12
+ "test:unit": "ava",
12
13
  "test:lint": "npm run lint:strict",
13
14
  "test:types": "tsc --noEmit -p .",
14
15
  "example:start": "cd example && npm run start",
@@ -45,19 +46,30 @@
45
46
  "cjs/"
46
47
  ],
47
48
  "repository": "https://github.com/Censkh/api-def",
49
+ "ava": {
50
+ "extensions": [
51
+ "ts"
52
+ ],
53
+ "files": [
54
+ "src/tests/**/*.test.ts"
55
+ ],
56
+ "nodeArguments": [
57
+ "--require=@esbuild-kit/cjs-loader"
58
+ ]
59
+ },
48
60
  "devDependencies": {
49
61
  "@babel/preset-env": "7.14.8",
50
62
  "@babel/preset-typescript": "7.14.5",
63
+ "@esbuild-kit/cjs-loader": "2.4.0",
51
64
  "@types/axios": "0.14.0",
52
- "@types/jest": "26.0.24",
53
65
  "@types/node": "16.4.6",
54
66
  "@typescript-eslint/eslint-plugin": "4.28.5",
55
67
  "@typescript-eslint/parser": "4.28.5",
68
+ "ava": "5.0.1",
56
69
  "cross-env": "7.0.3",
57
70
  "eslint": "7.31.0",
58
71
  "eslint-watch": "7.0.0",
59
- "jest": "27.0.6",
60
72
  "npm-run-all": "4.1.5",
61
- "typescript": "4.3.5"
73
+ "typescript": "4.8.4"
62
74
  }
63
75
  }