api-def 0.4.1-alpha3 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/cjs/Api.d.ts +13 -15
- package/cjs/Api.js +28 -41
- package/cjs/ApiConstants.d.ts +28 -0
- package/cjs/ApiConstants.js +28 -0
- package/cjs/ApiTypes.d.ts +2 -7
- package/cjs/ApiUtils.d.ts +2 -10
- package/cjs/ApiUtils.js +24 -37
- package/cjs/Endpoint.d.ts +21 -5
- package/cjs/Endpoint.js +16 -31
- package/cjs/MockingTypes.d.ts +28 -0
- package/cjs/{lib/Utils.js → MockingTypes.js} +0 -0
- package/cjs/RequestContext.d.ts +9 -4
- package/cjs/RequestContext.js +4 -2
- package/cjs/RequestError.d.ts +21 -0
- package/cjs/RequestError.js +23 -0
- package/cjs/Requester.d.ts +2 -1
- package/cjs/Requester.js +153 -67
- package/cjs/TextDecoding.d.ts +1 -0
- package/cjs/TextDecoding.js +139 -0
- package/cjs/Utils.d.ts +9 -0
- package/cjs/Utils.js +30 -1
- package/cjs/backend/AxiosRequestBackend.d.ts +4 -3
- package/cjs/backend/AxiosRequestBackend.js +3 -0
- package/cjs/backend/FetchRequestBackend.d.ts +2 -1
- package/cjs/backend/FetchRequestBackend.js +12 -7
- package/cjs/backend/MockRequestBackend.d.ts +10 -0
- package/cjs/backend/MockRequestBackend.js +149 -0
- package/cjs/backend/RequestBackend.d.ts +4 -0
- package/cjs/cache/LocalForageCacheBackend.js +1 -0
- package/cjs/index.d.ts +1 -1
- package/cjs/index.js +2 -2
- package/cjs/util/retry/index.d.ts +3 -0
- package/cjs/util/retry/index.js +52 -0
- package/cjs/util/retry/lib/retry.d.ts +3 -0
- package/cjs/util/retry/lib/retry.js +54 -0
- package/cjs/util/retry/lib/retryOperation.d.ts +27 -0
- package/cjs/util/retry/lib/retryOperation.js +134 -0
- package/esm/Api.d.ts +13 -15
- package/esm/Api.js +24 -39
- package/esm/ApiConstants.d.ts +28 -0
- package/esm/ApiConstants.js +28 -0
- package/esm/ApiTypes.d.ts +2 -7
- package/esm/ApiUtils.d.ts +2 -10
- package/esm/ApiUtils.js +22 -35
- package/esm/Endpoint.d.ts +21 -5
- package/esm/Endpoint.js +16 -31
- package/esm/MockingTypes.d.ts +28 -0
- package/esm/{lib/backend/RequestBackend.js → MockingTypes.js} +0 -0
- package/esm/RequestContext.d.ts +9 -4
- package/esm/RequestContext.js +4 -2
- package/esm/RequestError.d.ts +21 -0
- package/esm/RequestError.js +18 -0
- package/esm/Requester.d.ts +2 -1
- package/esm/Requester.js +153 -67
- package/esm/TextDecoding.d.ts +1 -0
- package/esm/TextDecoding.js +135 -0
- package/esm/Utils.d.ts +9 -0
- package/esm/Utils.js +26 -0
- package/esm/backend/AxiosRequestBackend.d.ts +4 -3
- package/esm/backend/AxiosRequestBackend.js +3 -0
- package/esm/backend/FetchRequestBackend.d.ts +2 -1
- package/esm/backend/FetchRequestBackend.js +12 -7
- package/esm/backend/MockRequestBackend.d.ts +10 -0
- package/esm/backend/MockRequestBackend.js +147 -0
- package/esm/backend/RequestBackend.d.ts +4 -0
- package/esm/cache/LocalForageCacheBackend.js +1 -0
- package/esm/index.d.ts +1 -1
- package/esm/index.js +1 -1
- package/esm/util/retry/index.d.ts +3 -0
- package/esm/util/retry/index.js +50 -0
- package/esm/util/retry/lib/retry.d.ts +3 -0
- package/esm/util/retry/lib/retry.js +50 -0
- package/esm/util/retry/lib/retryOperation.d.ts +27 -0
- package/esm/util/retry/lib/retryOperation.js +132 -0
- package/package.json +29 -19
- package/CHANGELOG.md +0 -39
- package/cjs/Mocking.d.ts +0 -23
- package/cjs/Mocking.js +0 -81
- package/cjs/__tests__/mock/ExampleApis.d.ts +0 -3
- package/cjs/__tests__/mock/ExampleApis.js +0 -19
- package/cjs/lib/Api.d.ts +0 -32
- package/cjs/lib/Api.js +0 -126
- package/cjs/lib/ApiTypes.d.ts +0 -102
- package/cjs/lib/ApiTypes.js +0 -31
- package/cjs/lib/ApiUtils.d.ts +0 -13
- package/cjs/lib/ApiUtils.js +0 -60
- package/cjs/lib/Caching.d.ts +0 -9
- package/cjs/lib/Caching.js +0 -85
- package/cjs/lib/Endpoint.d.ts +0 -30
- package/cjs/lib/Endpoint.js +0 -121
- package/cjs/lib/EndpointBuilder.d.ts +0 -12
- package/cjs/lib/EndpointBuilder.js +0 -27
- package/cjs/lib/Mocking.d.ts +0 -23
- package/cjs/lib/Mocking.js +0 -80
- package/cjs/lib/RequestContext.d.ts +0 -28
- package/cjs/lib/RequestContext.js +0 -166
- package/cjs/lib/Requester.d.ts +0 -2
- package/cjs/lib/Requester.js +0 -164
- package/cjs/lib/Utils.d.ts +0 -1
- package/cjs/lib/backend/AxiosBackend.d.ts +0 -10
- package/cjs/lib/backend/AxiosBackend.js +0 -98
- package/cjs/lib/backend/AxiosRequestBackend.d.ts +0 -11
- package/cjs/lib/backend/AxiosRequestBackend.js +0 -99
- package/cjs/lib/backend/FetchBackend.d.ts +0 -8
- package/cjs/lib/backend/FetchBackend.js +0 -145
- package/cjs/lib/backend/FetchRequestBackend.d.ts +0 -9
- package/cjs/lib/backend/FetchRequestBackend.js +0 -150
- package/cjs/lib/backend/RequestBackend.d.ts +0 -11
- package/cjs/lib/backend/RequestBackend.js +0 -2
- package/cjs/lib/cache/CacheBackend.d.ts +0 -6
- package/cjs/lib/cache/CacheBackend.js +0 -2
- package/cjs/lib/cache/Caching.d.ts +0 -10
- package/cjs/lib/cache/Caching.js +0 -84
- package/cjs/lib/cache/LocalForageCacheBackend.d.ts +0 -9
- package/cjs/lib/cache/LocalForageCacheBackend.js +0 -25
- package/cjs/lib/cache/LocalStorageCacheBackend.d.ts +0 -7
- package/cjs/lib/cache/LocalStorageCacheBackend.js +0 -78
- package/cjs/lib/middleware/CacheMiddleware.d.ts +0 -7
- package/cjs/lib/middleware/CacheMiddleware.js +0 -107
- package/cjs/lib/middleware/LoggingMiddleware.d.ts +0 -7
- package/cjs/lib/middleware/LoggingMiddleware.js +0 -95
- package/esm/Mocking.d.ts +0 -23
- package/esm/Mocking.js +0 -77
- package/esm/__tests__/mock/ExampleApis.d.ts +0 -3
- package/esm/__tests__/mock/ExampleApis.js +0 -16
- package/esm/lib/Api.d.ts +0 -32
- package/esm/lib/Api.js +0 -123
- package/esm/lib/ApiTypes.d.ts +0 -102
- package/esm/lib/ApiTypes.js +0 -28
- package/esm/lib/ApiUtils.d.ts +0 -13
- package/esm/lib/ApiUtils.js +0 -57
- package/esm/lib/Caching.d.ts +0 -9
- package/esm/lib/Caching.js +0 -82
- package/esm/lib/Endpoint.d.ts +0 -30
- package/esm/lib/Endpoint.js +0 -119
- package/esm/lib/EndpointBuilder.d.ts +0 -12
- package/esm/lib/EndpointBuilder.js +0 -25
- package/esm/lib/Mocking.d.ts +0 -23
- package/esm/lib/Mocking.js +0 -77
- package/esm/lib/RequestContext.d.ts +0 -28
- package/esm/lib/RequestContext.js +0 -164
- package/esm/lib/Requester.d.ts +0 -2
- package/esm/lib/Requester.js +0 -161
- package/esm/lib/Utils.d.ts +0 -1
- package/esm/lib/Utils.js +0 -0
- package/esm/lib/backend/AxiosBackend.d.ts +0 -10
- package/esm/lib/backend/AxiosBackend.js +0 -95
- package/esm/lib/backend/AxiosRequestBackend.d.ts +0 -11
- package/esm/lib/backend/AxiosRequestBackend.js +0 -96
- package/esm/lib/backend/FetchBackend.d.ts +0 -8
- package/esm/lib/backend/FetchBackend.js +0 -143
- package/esm/lib/backend/FetchRequestBackend.d.ts +0 -9
- package/esm/lib/backend/FetchRequestBackend.js +0 -148
- package/esm/lib/backend/RequestBackend.d.ts +0 -11
- package/esm/lib/cache/CacheBackend.d.ts +0 -6
- package/esm/lib/cache/CacheBackend.js +0 -1
- package/esm/lib/cache/Caching.d.ts +0 -10
- package/esm/lib/cache/Caching.js +0 -81
- package/esm/lib/cache/LocalForageCacheBackend.d.ts +0 -9
- package/esm/lib/cache/LocalForageCacheBackend.js +0 -23
- package/esm/lib/cache/LocalStorageCacheBackend.d.ts +0 -7
- package/esm/lib/cache/LocalStorageCacheBackend.js +0 -76
- package/esm/lib/middleware/CacheMiddleware.d.ts +0 -7
- package/esm/lib/middleware/CacheMiddleware.js +0 -105
- package/esm/lib/middleware/LoggingMiddleware.d.ts +0 -7
- package/esm/lib/middleware/LoggingMiddleware.js +0 -92
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
11
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
12
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
13
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
14
|
+
function step(op) {
|
|
15
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
16
|
+
while (_) try {
|
|
17
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
18
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
19
|
+
switch (op[0]) {
|
|
20
|
+
case 0: case 1: t = op; break;
|
|
21
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
22
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
23
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
24
|
+
default:
|
|
25
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
26
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
27
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
28
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
29
|
+
if (t[2]) _.ops.pop();
|
|
30
|
+
_.trys.pop(); continue;
|
|
31
|
+
}
|
|
32
|
+
op = body.call(thisArg, _);
|
|
33
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
34
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
import * as Utils from "../Utils";
|
|
38
|
+
import { delayThenReturn, randInt } from "../Utils";
|
|
39
|
+
import { convertToRequestError, RequestErrorCode } from "../RequestError";
|
|
40
|
+
var MockRequestBackend = /** @class */ (function () {
|
|
41
|
+
function MockRequestBackend() {
|
|
42
|
+
}
|
|
43
|
+
MockRequestBackend.prototype.convertResponse = function (context, response, error) {
|
|
44
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
45
|
+
return __generator(this, function (_a) {
|
|
46
|
+
return [2 /*return*/, response];
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
MockRequestBackend.prototype.extractResponseFromError = function (error) {
|
|
51
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
52
|
+
var fetchError;
|
|
53
|
+
return __generator(this, function (_a) {
|
|
54
|
+
if ("response" in error) {
|
|
55
|
+
fetchError = error;
|
|
56
|
+
return [2 /*return*/, fetchError.response ? fetchError.response : null];
|
|
57
|
+
}
|
|
58
|
+
return [2 /*return*/, undefined];
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
};
|
|
62
|
+
MockRequestBackend.prototype.runRequest = function (context) {
|
|
63
|
+
var _a, _b, _c, _d;
|
|
64
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
65
|
+
var mockingFunc, req, res, delay, delayMs, min, max, _e;
|
|
66
|
+
return __generator(this, function (_f) {
|
|
67
|
+
switch (_f.label) {
|
|
68
|
+
case 0:
|
|
69
|
+
mockingFunc = (_a = context.mocking) === null || _a === void 0 ? void 0 : _a.handler;
|
|
70
|
+
if (!mockingFunc) {
|
|
71
|
+
throw convertToRequestError({
|
|
72
|
+
error: new Error("[api-def] Attempted to run mocked request without mocking function"),
|
|
73
|
+
code: RequestErrorCode.REQUEST_INVALID_CONFIG,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
req = {
|
|
77
|
+
body: context.computedConfig.body,
|
|
78
|
+
params: (_b = context.computedConfig.params) !== null && _b !== void 0 ? _b : {},
|
|
79
|
+
query: context.computedConfig.query,
|
|
80
|
+
headers: (_c = context.computedConfig.headers) !== null && _c !== void 0 ? _c : {},
|
|
81
|
+
};
|
|
82
|
+
res = {
|
|
83
|
+
statusCode: -1,
|
|
84
|
+
response: undefined,
|
|
85
|
+
status: function (statusCode) {
|
|
86
|
+
res.statusCode = statusCode;
|
|
87
|
+
return res;
|
|
88
|
+
},
|
|
89
|
+
send: function (response) {
|
|
90
|
+
res.response = response;
|
|
91
|
+
return res;
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
if (!((_d = context.mocking) === null || _d === void 0 ? void 0 : _d.delay)) return [3 /*break*/, 3];
|
|
95
|
+
delay = context.mocking.delay;
|
|
96
|
+
delayMs = void 0;
|
|
97
|
+
if (typeof delay === "number") {
|
|
98
|
+
delayMs = delay;
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
min = delay[0], max = delay[1];
|
|
102
|
+
if (min > max) {
|
|
103
|
+
throw convertToRequestError({
|
|
104
|
+
error: new Error("[api-def] Min delay cannot be greater than max delay"),
|
|
105
|
+
code: RequestErrorCode.REQUEST_INVALID_CONFIG,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
delayMs = randInt(min, max);
|
|
109
|
+
}
|
|
110
|
+
_e = delayThenReturn;
|
|
111
|
+
return [4 /*yield*/, mockingFunc(req, res)];
|
|
112
|
+
case 1: return [4 /*yield*/, _e.apply(void 0, [_f.sent(), delayMs])];
|
|
113
|
+
case 2:
|
|
114
|
+
_f.sent();
|
|
115
|
+
return [3 /*break*/, 5];
|
|
116
|
+
case 3: return [4 /*yield*/, mockingFunc(req, res)];
|
|
117
|
+
case 4:
|
|
118
|
+
_f.sent();
|
|
119
|
+
_f.label = 5;
|
|
120
|
+
case 5:
|
|
121
|
+
if (res.response === undefined) {
|
|
122
|
+
throw convertToRequestError({
|
|
123
|
+
error: new Error("[api-def] Mocked API did not respond"),
|
|
124
|
+
code: RequestErrorCode.REQUEST_INVALID_CONFIG,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
return [2 /*return*/, {
|
|
128
|
+
headers: {},
|
|
129
|
+
data: res.response,
|
|
130
|
+
status: res.statusCode,
|
|
131
|
+
}];
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
};
|
|
136
|
+
MockRequestBackend.prototype.makeRequest = function (context) {
|
|
137
|
+
return {
|
|
138
|
+
canceler: Utils.noop,
|
|
139
|
+
promise: this.runRequest(context),
|
|
140
|
+
};
|
|
141
|
+
};
|
|
142
|
+
MockRequestBackend.prototype.getErrorInfo = function (error, response) {
|
|
143
|
+
return undefined;
|
|
144
|
+
};
|
|
145
|
+
return MockRequestBackend;
|
|
146
|
+
}());
|
|
147
|
+
export default MockRequestBackend;
|
|
@@ -4,8 +4,12 @@ export interface RequestOperation<R> {
|
|
|
4
4
|
promise: Promise<R>;
|
|
5
5
|
canceler: () => void;
|
|
6
6
|
}
|
|
7
|
+
export interface RequestBackendErrorInfo {
|
|
8
|
+
code: string;
|
|
9
|
+
}
|
|
7
10
|
export default interface RequestBackend<R = any> {
|
|
8
11
|
makeRequest(context: RequestContext): RequestOperation<R>;
|
|
9
12
|
convertResponse<T>(context: RequestContext, response: R, error?: boolean): Promise<ApiResponse<T>>;
|
|
10
13
|
extractResponseFromError(error: Error): Promise<R | null | undefined>;
|
|
14
|
+
getErrorInfo(error: Error, response: ApiResponse | undefined | null): RequestBackendErrorInfo | undefined;
|
|
11
15
|
}
|
package/esm/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export * from "./Api";
|
|
2
2
|
export * from "./ApiTypes";
|
|
3
3
|
export * from "./ApiConstants";
|
|
4
|
-
export { isRequestError } from "./
|
|
4
|
+
export { isRequestError } from "./RequestError";
|
|
5
5
|
export { clearCache, setCacheBackend } from "./cache/Caching";
|
|
6
6
|
export { default as LocalStorageCacheBackend } from "./cache/LocalStorageCacheBackend";
|
|
7
7
|
export { default as LocaleForageCacheBackend } from "./cache/LocalForageCacheBackend";
|
package/esm/index.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
export * from "./Api";
|
|
4
4
|
export * from "./ApiTypes";
|
|
5
5
|
export * from "./ApiConstants";
|
|
6
|
-
export { isRequestError } from "./
|
|
6
|
+
export { isRequestError } from "./RequestError";
|
|
7
7
|
export { clearCache, setCacheBackend } from "./cache/Caching";
|
|
8
8
|
export { default as LocalStorageCacheBackend } from "./cache/LocalStorageCacheBackend";
|
|
9
9
|
export { default as LocaleForageCacheBackend } from "./cache/LocalForageCacheBackend";
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import * as retrier from "./lib/retry";
|
|
2
|
+
// Retry is just transplanted from here:
|
|
3
|
+
// https://www.npmjs.com/package/retry (lib), and
|
|
4
|
+
// https://www.npmjs.com/package/async-retry (RetryFunction)
|
|
5
|
+
// ---
|
|
6
|
+
var retry = function (fn, opts) {
|
|
7
|
+
return new Promise(function (resolve, reject) {
|
|
8
|
+
var options = opts || {};
|
|
9
|
+
if (!("randomize" in options)) {
|
|
10
|
+
options.randomize = true;
|
|
11
|
+
}
|
|
12
|
+
var op = retrier.operation(options);
|
|
13
|
+
// We allow the user to abort retrying
|
|
14
|
+
// this makes sense in the cases where
|
|
15
|
+
// knowledge is obtained that retrying
|
|
16
|
+
// would be futile (e.g.: auth errors)
|
|
17
|
+
var bail = function (err) {
|
|
18
|
+
reject(err || new Error("Aborted"));
|
|
19
|
+
};
|
|
20
|
+
var onError = function (err, num) {
|
|
21
|
+
if (err.bail) {
|
|
22
|
+
bail(err);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if (!op.retry(err)) {
|
|
26
|
+
reject(op.mainError());
|
|
27
|
+
}
|
|
28
|
+
else if (options.onRetry) {
|
|
29
|
+
options.onRetry(err, num);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
var runAttempt = function (num) {
|
|
33
|
+
var val;
|
|
34
|
+
try {
|
|
35
|
+
val = fn(bail, num);
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
onError(err, num);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
Promise.resolve(val)
|
|
42
|
+
.then(resolve)
|
|
43
|
+
.catch(function catchIt(err) {
|
|
44
|
+
onError(err, num);
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
op.attempt(runAttempt);
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
export default retry;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
|
2
|
+
__assign = Object.assign || function(t) {
|
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
+
s = arguments[i];
|
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
+
t[p] = s[p];
|
|
7
|
+
}
|
|
8
|
+
return t;
|
|
9
|
+
};
|
|
10
|
+
return __assign.apply(this, arguments);
|
|
11
|
+
};
|
|
12
|
+
import RetryOperation from "./retryOperation";
|
|
13
|
+
export var operation = function (options) {
|
|
14
|
+
var timeouts = _timeouts(options);
|
|
15
|
+
return (new RetryOperation(timeouts, {
|
|
16
|
+
forever: options && (options.forever || options.retries === Infinity),
|
|
17
|
+
unref: options && options.unref,
|
|
18
|
+
maxRetryTime: options && options.maxRetryTime,
|
|
19
|
+
}));
|
|
20
|
+
};
|
|
21
|
+
var _timeouts = function (options) {
|
|
22
|
+
var _a;
|
|
23
|
+
var createTimeout = function (attempt, opts) {
|
|
24
|
+
var random = (opts.randomize)
|
|
25
|
+
? (Math.random() + 1)
|
|
26
|
+
: 1;
|
|
27
|
+
var timeout = Math.round(random * Math.max(opts.minTimeout, 1) * Math.pow(opts.factor, attempt));
|
|
28
|
+
timeout = Math.min(timeout, opts.maxTimeout);
|
|
29
|
+
return (timeout);
|
|
30
|
+
};
|
|
31
|
+
var defaultRetries = 10;
|
|
32
|
+
var opts = __assign({ retries: defaultRetries, factor: 2, minTimeout: 1 * 1000, maxTimeout: Infinity, randomize: false }, options);
|
|
33
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
34
|
+
if (opts.minTimeout > opts.maxTimeout) {
|
|
35
|
+
throw new Error("minTimeout is greater than maxTimeout");
|
|
36
|
+
}
|
|
37
|
+
var timeouts = [];
|
|
38
|
+
var numRetries = (_a = opts.retries) !== null && _a !== void 0 ? _a : defaultRetries;
|
|
39
|
+
for (var i = 0; i < numRetries; i++) {
|
|
40
|
+
timeouts.push(createTimeout(i, opts));
|
|
41
|
+
}
|
|
42
|
+
if (options && options.forever && !timeouts.length) {
|
|
43
|
+
timeouts.push(createTimeout(numRetries, opts));
|
|
44
|
+
}
|
|
45
|
+
// sort the array numerically ascending
|
|
46
|
+
timeouts.sort(function (a, b) {
|
|
47
|
+
return a - b;
|
|
48
|
+
});
|
|
49
|
+
return (timeouts);
|
|
50
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export default RetryOperation;
|
|
2
|
+
declare function RetryOperation(timeouts: any, options: any): void;
|
|
3
|
+
declare class RetryOperation {
|
|
4
|
+
constructor(timeouts: any, options: any);
|
|
5
|
+
_originalTimeouts: any;
|
|
6
|
+
_timeouts: any;
|
|
7
|
+
_options: any;
|
|
8
|
+
_maxRetryTime: any;
|
|
9
|
+
_fn: any;
|
|
10
|
+
_errors: any[];
|
|
11
|
+
_attempts: number;
|
|
12
|
+
_operationTimeout: any;
|
|
13
|
+
_operationTimeoutCb: any;
|
|
14
|
+
_timeout: NodeJS.Timeout | null;
|
|
15
|
+
_operationStart: number | null;
|
|
16
|
+
_timer: NodeJS.Timeout | null;
|
|
17
|
+
_cachedTimeouts: any;
|
|
18
|
+
reset(): void;
|
|
19
|
+
stop(): void;
|
|
20
|
+
retry(err: any): boolean;
|
|
21
|
+
attempt(fn: any, timeoutOps: any): void;
|
|
22
|
+
try(fn: any): void;
|
|
23
|
+
start: (fn: any) => void;
|
|
24
|
+
errors(): any[];
|
|
25
|
+
attempts(): number;
|
|
26
|
+
mainError(): any;
|
|
27
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
function RetryOperation(timeouts, options) {
|
|
2
|
+
// Compatibility for the old (timeouts, retryForever) signature
|
|
3
|
+
if (typeof options === "boolean") {
|
|
4
|
+
options = { forever: options };
|
|
5
|
+
}
|
|
6
|
+
this._originalTimeouts = JSON.parse(JSON.stringify(timeouts));
|
|
7
|
+
this._timeouts = timeouts;
|
|
8
|
+
this._options = options || {};
|
|
9
|
+
this._maxRetryTime = options && options.maxRetryTime || Infinity;
|
|
10
|
+
this._fn = null;
|
|
11
|
+
this._errors = [];
|
|
12
|
+
this._attempts = 1;
|
|
13
|
+
this._operationTimeout = null;
|
|
14
|
+
this._operationTimeoutCb = null;
|
|
15
|
+
this._timeout = null;
|
|
16
|
+
this._operationStart = null;
|
|
17
|
+
this._timer = null;
|
|
18
|
+
if (this._options.forever) {
|
|
19
|
+
this._cachedTimeouts = this._timeouts.slice(0);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
RetryOperation.prototype.reset = function () {
|
|
23
|
+
this._attempts = 1;
|
|
24
|
+
this._timeouts = this._originalTimeouts.slice(0);
|
|
25
|
+
};
|
|
26
|
+
RetryOperation.prototype.stop = function () {
|
|
27
|
+
if (this._timeout) {
|
|
28
|
+
clearTimeout(this._timeout);
|
|
29
|
+
}
|
|
30
|
+
if (this._timer) {
|
|
31
|
+
clearTimeout(this._timer);
|
|
32
|
+
}
|
|
33
|
+
this._timeouts = [];
|
|
34
|
+
this._cachedTimeouts = null;
|
|
35
|
+
};
|
|
36
|
+
RetryOperation.prototype.retry = function (err) {
|
|
37
|
+
if (this._timeout) {
|
|
38
|
+
clearTimeout(this._timeout);
|
|
39
|
+
}
|
|
40
|
+
if (!err) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
var currentTime = new Date().getTime();
|
|
44
|
+
if (err && currentTime - this._operationStart >= this._maxRetryTime) {
|
|
45
|
+
this._errors.push(err);
|
|
46
|
+
this._errors.unshift(new Error("RetryOperation timeout occurred"));
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
this._errors.push(err);
|
|
50
|
+
var timeout = this._timeouts.shift();
|
|
51
|
+
if (timeout === undefined) {
|
|
52
|
+
if (this._cachedTimeouts) {
|
|
53
|
+
// retry forever, only keep last error
|
|
54
|
+
this._errors.splice(0, this._errors.length - 1);
|
|
55
|
+
timeout = this._cachedTimeouts.slice(-1);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
var self = this;
|
|
62
|
+
this._timer = setTimeout(function () {
|
|
63
|
+
self._attempts++;
|
|
64
|
+
if (self._operationTimeoutCb) {
|
|
65
|
+
self._timeout = setTimeout(function () {
|
|
66
|
+
self._operationTimeoutCb(self._attempts);
|
|
67
|
+
}, self._operationTimeout);
|
|
68
|
+
if (self._options.unref) {
|
|
69
|
+
self._timeout.unref();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
self._fn(self._attempts);
|
|
73
|
+
}, timeout);
|
|
74
|
+
if (this._options.unref) {
|
|
75
|
+
this._timer.unref();
|
|
76
|
+
}
|
|
77
|
+
return true;
|
|
78
|
+
};
|
|
79
|
+
RetryOperation.prototype.attempt = function (fn, timeoutOps) {
|
|
80
|
+
this._fn = fn;
|
|
81
|
+
if (timeoutOps) {
|
|
82
|
+
if (timeoutOps.timeout) {
|
|
83
|
+
this._operationTimeout = timeoutOps.timeout;
|
|
84
|
+
}
|
|
85
|
+
if (timeoutOps.cb) {
|
|
86
|
+
this._operationTimeoutCb = timeoutOps.cb;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
var self = this;
|
|
90
|
+
if (this._operationTimeoutCb) {
|
|
91
|
+
this._timeout = setTimeout(function () {
|
|
92
|
+
self._operationTimeoutCb();
|
|
93
|
+
}, self._operationTimeout);
|
|
94
|
+
}
|
|
95
|
+
this._operationStart = new Date().getTime();
|
|
96
|
+
this._fn(this._attempts);
|
|
97
|
+
};
|
|
98
|
+
RetryOperation.prototype.try = function (fn) {
|
|
99
|
+
// console.log("Using RetryOperation.try() is deprecated");
|
|
100
|
+
this.attempt(fn);
|
|
101
|
+
};
|
|
102
|
+
RetryOperation.prototype.start = function (fn) {
|
|
103
|
+
// console.log("Using RetryOperation.start() is deprecated");
|
|
104
|
+
this.attempt(fn);
|
|
105
|
+
};
|
|
106
|
+
RetryOperation.prototype.start = RetryOperation.prototype.try;
|
|
107
|
+
RetryOperation.prototype.errors = function () {
|
|
108
|
+
return this._errors;
|
|
109
|
+
};
|
|
110
|
+
RetryOperation.prototype.attempts = function () {
|
|
111
|
+
return this._attempts;
|
|
112
|
+
};
|
|
113
|
+
RetryOperation.prototype.mainError = function () {
|
|
114
|
+
if (this._errors.length === 0) {
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
var counts = {};
|
|
118
|
+
var mainError = null;
|
|
119
|
+
var mainErrorCount = 0;
|
|
120
|
+
for (var i = 0; i < this._errors.length; i++) {
|
|
121
|
+
var error = this._errors[i];
|
|
122
|
+
var message = error.message;
|
|
123
|
+
var count = (counts[message] || 0) + 1;
|
|
124
|
+
counts[message] = count;
|
|
125
|
+
if (count >= mainErrorCount) {
|
|
126
|
+
mainError = error;
|
|
127
|
+
mainErrorCount = count;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return mainError;
|
|
131
|
+
};
|
|
132
|
+
export default RetryOperation;
|
package/package.json
CHANGED
|
@@ -1,18 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "api-def",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.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
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"
|
|
10
|
+
"test": "npm run test:types && npm run test:lint && npm run test:unit",
|
|
11
|
+
"test:unit": "cross-env NODE_ENV=test jest",
|
|
12
|
+
"test:lint": "npm run lint:strict",
|
|
13
|
+
"test:types": "tsc --noEmit -p .",
|
|
14
|
+
"example:start": "cd example && npm run start",
|
|
15
|
+
"lint": "esw --ext .tsx,.ts src",
|
|
16
|
+
"lint:watch": "npm run lint -- --watch",
|
|
17
|
+
"lint:fix": "npm run lint -- --fix",
|
|
18
|
+
"lint:strict": "npm run lint -- --max-warnings 0",
|
|
19
|
+
"cleanup": "rimraf esm && rimraf cjs",
|
|
20
|
+
"build": "npm run cleanup && npm run build:esm && npm run build:cjs",
|
|
21
|
+
"build:esm": "tsc --module es2015 --target es5 --outDir esm --preserveWatchOutput",
|
|
22
|
+
"build:cjs": "tsc --module commonjs --target es5 --outDir cjs --preserveWatchOutput",
|
|
23
|
+
"build:watch": "npm-run-all -p \"build:esm -- -w\" \"build:cjs -- -w\" \"lint:watch\"",
|
|
16
24
|
"website:dev": "cd website && npm run start",
|
|
17
25
|
"website:deploy": "cd website && npm run deploy"
|
|
18
26
|
},
|
|
@@ -38,16 +46,18 @@
|
|
|
38
46
|
],
|
|
39
47
|
"repository": "https://github.com/Censkh/api-def",
|
|
40
48
|
"devDependencies": {
|
|
41
|
-
"@
|
|
42
|
-
"@
|
|
43
|
-
"@
|
|
44
|
-
"@
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"typescript": "
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
"
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
"@babel/preset-env": "7.14.8",
|
|
50
|
+
"@babel/preset-typescript": "7.14.5",
|
|
51
|
+
"@types/axios": "0.14.0",
|
|
52
|
+
"@types/jest": "26.0.24",
|
|
53
|
+
"@types/node": "16.4.6",
|
|
54
|
+
"@typescript-eslint/eslint-plugin": "4.28.5",
|
|
55
|
+
"@typescript-eslint/parser": "4.28.5",
|
|
56
|
+
"cross-env": "7.0.3",
|
|
57
|
+
"eslint": "7.31.0",
|
|
58
|
+
"eslint-watch": "7.0.0",
|
|
59
|
+
"jest": "27.0.6",
|
|
60
|
+
"npm-run-all": "4.1.5",
|
|
61
|
+
"typescript": "4.3.5"
|
|
62
|
+
}
|
|
53
63
|
}
|
package/CHANGELOG.md
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
# 0.4.1
|
|
2
|
-
|
|
3
|
-
- add better error handling on parse
|
|
4
|
-
|
|
5
|
-
# 0.4.0
|
|
6
|
-
|
|
7
|
-
## Breaking Changes
|
|
8
|
-
|
|
9
|
-
- Move config values from options object up one layer
|
|
10
|
-
- In config `retries` -> `retry`
|
|
11
|
-
- `defaults` -> `config`
|
|
12
|
-
|
|
13
|
-
## Changes
|
|
14
|
-
|
|
15
|
-
- Remove need for enum imports
|
|
16
|
-
- Make `name` and `description` optional in endpoint definition
|
|
17
|
-
|
|
18
|
-
# 0.3.11
|
|
19
|
-
|
|
20
|
-
## Changes
|
|
21
|
-
|
|
22
|
-
- Make fetch backend default if fetch is present
|
|
23
|
-
- Fix fetch backends text response type support
|
|
24
|
-
|
|
25
|
-
# 0.3.0
|
|
26
|
-
|
|
27
|
-
## Features
|
|
28
|
-
|
|
29
|
-
- allow defaults to be a function on api
|
|
30
|
-
- add content type header in fetch backend to match axios backend
|
|
31
|
-
- remove `flatted`
|
|
32
|
-
- polyfill object.assign for ie
|
|
33
|
-
- change retry logic so that if a middleware event responds with Retry we always attempt a retry
|
|
34
|
-
|
|
35
|
-
# 0.2.5
|
|
36
|
-
|
|
37
|
-
## Changes
|
|
38
|
-
|
|
39
|
-
- Remove `window` usages to allow node support
|
package/cjs/Mocking.d.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { ApiResponse, Body, ModulePossiblyDefault, Params, Query, RequestConfig } from "./ApiTypes";
|
|
2
|
-
import Endpoint from "./Endpoint";
|
|
3
|
-
export interface MockingConfig {
|
|
4
|
-
loader?: () => Promise<ModulePossiblyDefault<any>>;
|
|
5
|
-
predicate: () => boolean;
|
|
6
|
-
}
|
|
7
|
-
export interface EndpointMockingInfo<R = any, P extends Params | undefined = Params | undefined, Q extends Query | undefined = Query | undefined, B extends Body | undefined = Body | undefined> {
|
|
8
|
-
func?: MockingFunction<R, P, Q, B>;
|
|
9
|
-
bypass?: boolean;
|
|
10
|
-
}
|
|
11
|
-
export interface MockRequest<R = any, P extends Params | undefined = Params | undefined, Q extends Query | undefined = Query | undefined, B extends Body | undefined = Body | undefined> {
|
|
12
|
-
params: P extends Params ? Record<P, string> : {};
|
|
13
|
-
body: B;
|
|
14
|
-
query: Q;
|
|
15
|
-
}
|
|
16
|
-
export interface MockResponse<R = any, P extends Params | undefined = Params | undefined, Q extends Query | undefined = Query | undefined, B extends Body | undefined = Body | undefined> {
|
|
17
|
-
statusCode: number;
|
|
18
|
-
response: R | undefined;
|
|
19
|
-
status(statusCode: number): this;
|
|
20
|
-
send(response: R): this;
|
|
21
|
-
}
|
|
22
|
-
export declare type MockingFunction<R = any, P extends Params | undefined = Params | undefined, Q extends Query | undefined = Query | undefined, B extends Body | undefined = Body | undefined> = (req: MockRequest<R, P, Q, B>, res: MockResponse<R, P, Q, B>) => void;
|
|
23
|
-
export declare const mockRequest: <R = any, P extends string | undefined = string | undefined, Q extends Query | undefined = Query | undefined, B extends Body | undefined = Body | undefined>(endpoint: Endpoint<R, P, Q, B>, config: RequestConfig<P, Q, B>) => Promise<ApiResponse<R>>;
|