@scaleway/sdk-client 2.1.0 → 2.2.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/dist/_virtual/_rolldown/runtime.js +11 -0
- package/dist/helpers/is-browser.js +1 -3
- package/dist/helpers/is-response.js +8 -3
- package/dist/helpers/json.js +47 -40
- package/dist/helpers/marshalling.js +88 -59
- package/dist/index.js +6 -47
- package/dist/internal/async/interval-retrier.js +64 -49
- package/dist/internal/async/sleep.js +10 -4
- package/dist/internal/interceptors/composer.js +34 -23
- package/dist/internal/interceptors/helpers.js +22 -9
- package/dist/internal/logger/console-logger.js +27 -22
- package/dist/internal/logger/index.js +23 -7
- package/dist/internal/logger/level-resolver.js +9 -12
- package/dist/internal/validations/string-validation.js +20 -21
- package/dist/internals.js +8 -0
- package/dist/package.js +32 -0
- package/dist/scw/api.js +10 -7
- package/dist/scw/auth.js +60 -17
- package/dist/scw/client-ini-factory.js +127 -57
- package/dist/scw/client-ini-profile.js +23 -19
- package/dist/scw/client-settings.js +25 -49
- package/dist/scw/client.js +76 -25
- package/dist/scw/constants.js +3 -8
- package/dist/scw/custom-marshalling.js +147 -121
- package/dist/scw/custom-types.js +11 -10
- package/dist/scw/errors/error-parser.js +83 -61
- package/dist/scw/errors/non-standard/invalid-request-mapper.js +20 -29
- package/dist/scw/errors/non-standard/unknown-resource-mapper.js +9 -16
- package/dist/scw/errors/scw-error.js +42 -39
- package/dist/scw/errors/standard/already-exists-error.js +20 -29
- package/dist/scw/errors/standard/denied-authentication-error.js +43 -34
- package/dist/scw/errors/standard/index.js +20 -18
- package/dist/scw/errors/standard/invalid-arguments-error.js +51 -50
- package/dist/scw/errors/standard/out-of-stock-error.js +18 -15
- package/dist/scw/errors/standard/permissions-denied-error.js +30 -26
- package/dist/scw/errors/standard/precondition-failed-error.js +32 -29
- package/dist/scw/errors/standard/quotas-exceeded-error.js +43 -38
- package/dist/scw/errors/standard/resource-expired-error.js +20 -29
- package/dist/scw/errors/standard/resource-locked-error.js +19 -18
- package/dist/scw/errors/standard/resource-not-found-error.js +19 -22
- package/dist/scw/errors/standard/too-many-requests-error.js +41 -54
- package/dist/scw/errors/standard/transient-state-error.js +20 -29
- package/dist/scw/errors/types.js +12 -12
- package/dist/scw/fetch/build-fetcher.js +49 -54
- package/dist/scw/fetch/http-dumper.js +50 -16
- package/dist/scw/fetch/http-interceptors.d.ts +1 -3
- package/dist/scw/fetch/http-interceptors.js +52 -34
- package/dist/scw/fetch/resource-paginator.js +52 -28
- package/dist/scw/fetch/response-parser.js +48 -49
- package/dist/scw/locality.js +12 -14
- package/dist/vendor/base64/index.js +31 -39
- package/package.json +1 -1
- package/dist/package.json.js +0 -8
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __exportAll = (all, no_symbols) => {
|
|
3
|
+
let target = {};
|
|
4
|
+
for (var name in all) __defProp(target, name, {
|
|
5
|
+
get: all[name],
|
|
6
|
+
enumerable: true
|
|
7
|
+
});
|
|
8
|
+
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
9
|
+
return target;
|
|
10
|
+
};
|
|
11
|
+
export { __exportAll };
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validates an object is of type Response without using `instanceof`.
|
|
3
|
+
*
|
|
4
|
+
* @remarks Check issue #509 for more context.
|
|
5
|
+
*
|
|
6
|
+
* @internal
|
|
7
|
+
*/
|
|
1
8
|
const isResponse = (obj) => obj !== null && obj !== void 0 && typeof obj === "object" && "status" in obj && typeof obj.status === "number" && "statusText" in obj && typeof obj.statusText === "string" && "headers" in obj && typeof obj.headers === "object" && "body" in obj && typeof obj.body !== "undefined";
|
|
2
|
-
export {
|
|
3
|
-
isResponse
|
|
4
|
-
};
|
|
9
|
+
export { isResponse };
|
package/dist/helpers/json.js
CHANGED
|
@@ -1,46 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validates an unknown object is a JSON Object.
|
|
3
|
+
*
|
|
4
|
+
* @internal
|
|
5
|
+
*/
|
|
1
6
|
const isJSONObject = (obj) => {
|
|
2
|
-
|
|
3
|
-
|
|
7
|
+
const objT = typeof obj;
|
|
8
|
+
return obj !== void 0 && obj !== null && objT !== "string" && objT !== "number" && objT !== "boolean" && !Array.isArray(obj) && objT === "object";
|
|
4
9
|
};
|
|
10
|
+
/**
|
|
11
|
+
* Camelizes a string.
|
|
12
|
+
*
|
|
13
|
+
* @param str - The string to camelize
|
|
14
|
+
* @returns The camelized string
|
|
15
|
+
*
|
|
16
|
+
* @internal
|
|
17
|
+
*/
|
|
5
18
|
const camelize = (str) => {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
} else if (char >= "A" && char <= "Z") {
|
|
20
|
-
out += char;
|
|
21
|
-
} else if (char >= "0" && char <= "9") {
|
|
22
|
-
out += char;
|
|
23
|
-
}
|
|
24
|
-
capNext = char === "_" || char === " " || char === "-" || char === ".";
|
|
25
|
-
}
|
|
26
|
-
return out.charAt(0).toLowerCase() + out.substring(1);
|
|
19
|
+
const strLength = str.length;
|
|
20
|
+
if (strLength <= 0) return str;
|
|
21
|
+
let out = "";
|
|
22
|
+
for (let capNext = false, index = 0; index < strLength; index += 1) {
|
|
23
|
+
const char = str.charAt(index);
|
|
24
|
+
if (char >= "a" && char <= "z") if (capNext) out += char.toUpperCase();
|
|
25
|
+
else out += char;
|
|
26
|
+
else if (char >= "A" && char <= "Z") out += char;
|
|
27
|
+
else if (char >= "0" && char <= "9") out += char;
|
|
28
|
+
capNext = char === "_" || char === " " || char === "-" || char === ".";
|
|
29
|
+
}
|
|
30
|
+
return out.charAt(0).toLowerCase() + out.substring(1);
|
|
27
31
|
};
|
|
32
|
+
/**
|
|
33
|
+
* Camelizes keys of an object (deeply).
|
|
34
|
+
*
|
|
35
|
+
* @param obj - The object
|
|
36
|
+
* @param ignoreKeys - The keys to ignore
|
|
37
|
+
* @returns The object with camelized keys
|
|
38
|
+
*
|
|
39
|
+
* @internal
|
|
40
|
+
*/
|
|
28
41
|
const camelizeKeys = (obj, ignoreKeys = []) => {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
return obj;
|
|
41
|
-
};
|
|
42
|
-
export {
|
|
43
|
-
camelize,
|
|
44
|
-
camelizeKeys,
|
|
45
|
-
isJSONObject
|
|
42
|
+
if (Array.isArray(obj)) return obj.map((v) => camelizeKeys(v, ignoreKeys));
|
|
43
|
+
if (obj && typeof obj === "object" && !(obj instanceof Date)) {
|
|
44
|
+
const result = {};
|
|
45
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
46
|
+
const outKey = camelize(key);
|
|
47
|
+
result[outKey] = ignoreKeys.includes(key) ? value : camelizeKeys(value, ignoreKeys);
|
|
48
|
+
}
|
|
49
|
+
return result;
|
|
50
|
+
}
|
|
51
|
+
return obj;
|
|
46
52
|
};
|
|
53
|
+
export { camelizeKeys, isJSONObject };
|
|
@@ -1,72 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns the parameter if it's valid as path parameter
|
|
3
|
+
* (string and not empty, or number), else throws an exception.
|
|
4
|
+
*
|
|
5
|
+
* @param name - The parameter name
|
|
6
|
+
* @param param - The parameter value
|
|
7
|
+
* @returns The parameter value
|
|
8
|
+
*
|
|
9
|
+
* @throws TypeError
|
|
10
|
+
* Thrown if the parameter is invalid.
|
|
11
|
+
*
|
|
12
|
+
* @internal
|
|
13
|
+
*/
|
|
1
14
|
function validatePathParam(name, param) {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
15
|
+
if (typeof param === "string" && param.length > 0) return param;
|
|
16
|
+
if (typeof param === "number") return param.toString();
|
|
17
|
+
throw new TypeError(`param ${name} cannot be empty in request`);
|
|
5
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* Resolves the ideal parameter and value amongst an optional list.
|
|
21
|
+
*
|
|
22
|
+
* @param list - The list to be looking into
|
|
23
|
+
* @param isRequired - If at least one "one-of" should be found, false by default
|
|
24
|
+
* @returns The parameter and value
|
|
25
|
+
*
|
|
26
|
+
* @throws TypeError
|
|
27
|
+
* Thrown if isRequired is true, and no value or default value is specified.
|
|
28
|
+
*
|
|
29
|
+
* @internal
|
|
30
|
+
*/
|
|
6
31
|
const resolveOneOf = (list, isRequired = false) => {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
return {};
|
|
32
|
+
const elt = list.find((obj) => obj.value !== void 0) ?? list.find((obj) => obj.default !== void 0);
|
|
33
|
+
const value = elt?.value ?? elt?.default;
|
|
34
|
+
if (elt && value !== void 0) return { [elt.param]: value };
|
|
35
|
+
if (isRequired) {
|
|
36
|
+
const keyList = list.map((obj) => obj.param).join(" or ");
|
|
37
|
+
throw new TypeError(`one of ${keyList} must be indicated in the request`);
|
|
38
|
+
}
|
|
39
|
+
return {};
|
|
17
40
|
};
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
41
|
+
/**
|
|
42
|
+
* Filters defined parameters tuples and converts them to URLSearchParams.
|
|
43
|
+
*
|
|
44
|
+
* @param paramTuples - The key/value pairs
|
|
45
|
+
* @returns URLSearchParams
|
|
46
|
+
*
|
|
47
|
+
* @internal
|
|
48
|
+
*/
|
|
49
|
+
var toParamString = (v) => {
|
|
50
|
+
if (v === null) return null;
|
|
51
|
+
if (v instanceof Date) return v.toISOString();
|
|
52
|
+
return v.toString();
|
|
22
53
|
};
|
|
23
54
|
const urlParams = (...paramTuples) => {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
55
|
+
const params = new URLSearchParams();
|
|
56
|
+
for (const [key, value] of paramTuples) {
|
|
57
|
+
if (typeof key !== "string" || value == null) continue;
|
|
58
|
+
if (Array.isArray(value)) {
|
|
59
|
+
for (const inner of value) {
|
|
60
|
+
const s = toParamString(inner);
|
|
61
|
+
if (s !== null) params.append(key, s);
|
|
62
|
+
}
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
const s = toParamString(value);
|
|
66
|
+
if (s !== null) params.append(key, s);
|
|
67
|
+
}
|
|
68
|
+
return params;
|
|
38
69
|
};
|
|
70
|
+
/**
|
|
71
|
+
* Unmarshals data to Date object.
|
|
72
|
+
*
|
|
73
|
+
* @internal
|
|
74
|
+
*/
|
|
39
75
|
const unmarshalDate = (data) => {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
if (Number.isNaN(date.getTime())) {
|
|
45
|
-
return void 0;
|
|
46
|
-
}
|
|
47
|
-
return date;
|
|
76
|
+
if (typeof data !== "string") return;
|
|
77
|
+
const date = new Date(data);
|
|
78
|
+
if (Number.isNaN(date.getTime())) return;
|
|
79
|
+
return date;
|
|
48
80
|
};
|
|
81
|
+
/**
|
|
82
|
+
* Unmarshals array of object.
|
|
83
|
+
*
|
|
84
|
+
* @internal
|
|
85
|
+
*/
|
|
49
86
|
const unmarshalArrayOfObject = (data, unmarshaller, emptyFallback = true) => {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
return data.map((elt) => unmarshaller(elt));
|
|
87
|
+
if (!Array.isArray(data)) return emptyFallback ? [] : void 0;
|
|
88
|
+
return data.map((elt) => unmarshaller(elt));
|
|
54
89
|
};
|
|
90
|
+
/**
|
|
91
|
+
* Unmarshals map of object.
|
|
92
|
+
*
|
|
93
|
+
* @internal
|
|
94
|
+
*/
|
|
55
95
|
const unmarshalMapOfObject = (data, unmarshaller, emptyFallback = true) => {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
for (const [key, value] of Object.entries(data)) {
|
|
61
|
-
out[key] = unmarshaller(value);
|
|
62
|
-
}
|
|
63
|
-
return out;
|
|
64
|
-
};
|
|
65
|
-
export {
|
|
66
|
-
resolveOneOf,
|
|
67
|
-
unmarshalArrayOfObject,
|
|
68
|
-
unmarshalDate,
|
|
69
|
-
unmarshalMapOfObject,
|
|
70
|
-
urlParams,
|
|
71
|
-
validatePathParam
|
|
96
|
+
if (!data || typeof data !== "object" || !(data instanceof Object) || Array.isArray(data)) return emptyFallback ? {} : void 0;
|
|
97
|
+
const out = {};
|
|
98
|
+
for (const [key, value] of Object.entries(data)) out[key] = unmarshaller(value);
|
|
99
|
+
return out;
|
|
72
100
|
};
|
|
101
|
+
export { resolveOneOf, unmarshalArrayOfObject, unmarshalDate, unmarshalMapOfObject, urlParams, validatePathParam };
|
package/dist/index.js
CHANGED
|
@@ -4,55 +4,14 @@ import { resolveOneOf, unmarshalArrayOfObject, unmarshalDate, unmarshalMapOfObje
|
|
|
4
4
|
import { createExponentialBackoffStrategy, tryAtIntervals, waitForResource } from "./internal/async/interval-retrier.js";
|
|
5
5
|
import { addAsyncHeaderInterceptor } from "./internal/interceptors/helpers.js";
|
|
6
6
|
import { API } from "./scw/api.js";
|
|
7
|
+
import { AUTH_HEADER_KEY, SESSION_HEADER_KEY } from "./scw/constants.js";
|
|
7
8
|
import { authenticateWithSessionToken } from "./scw/auth.js";
|
|
9
|
+
import { Decimal } from "./scw/custom-types.js";
|
|
8
10
|
import { marshalBlobToScwFile, marshalDecimal, marshalMoney, marshalScwFile, marshalTimeSeries, unmarshalAnyRes, unmarshalDecimal, unmarshalMoney, unmarshalScwFile, unmarshalServiceInfo, unmarshalTimeSeries, unmarshalTimeSeriesPoint } from "./scw/custom-marshalling.js";
|
|
9
11
|
import { enrichForPagination } from "./scw/fetch/resource-paginator.js";
|
|
10
|
-
import
|
|
12
|
+
import "./internals.js";
|
|
11
13
|
import { withAdditionalInterceptors, withDefaultPageSize, withHTTPClient, withProfile, withUserAgent, withUserAgentSuffix } from "./scw/client-ini-factory.js";
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import * as index from "./scw/errors/standard/index.js";
|
|
14
|
+
import { createAdvancedClient, createClient } from "./scw/client.js";
|
|
15
|
+
import { standard_exports } from "./scw/errors/standard/index.js";
|
|
15
16
|
import { toApiLocality } from "./scw/locality.js";
|
|
16
|
-
export {
|
|
17
|
-
API,
|
|
18
|
-
AUTH_HEADER_KEY,
|
|
19
|
-
Decimal,
|
|
20
|
-
index as Errors,
|
|
21
|
-
SESSION_HEADER_KEY,
|
|
22
|
-
addAsyncHeaderInterceptor,
|
|
23
|
-
authenticateWithSessionToken,
|
|
24
|
-
createAdvancedClient,
|
|
25
|
-
createClient,
|
|
26
|
-
createExponentialBackoffStrategy,
|
|
27
|
-
enableConsoleLogger,
|
|
28
|
-
enrichForPagination,
|
|
29
|
-
isJSONObject,
|
|
30
|
-
marshalBlobToScwFile,
|
|
31
|
-
marshalDecimal,
|
|
32
|
-
marshalMoney,
|
|
33
|
-
marshalScwFile,
|
|
34
|
-
marshalTimeSeries,
|
|
35
|
-
resolveOneOf,
|
|
36
|
-
setLogger,
|
|
37
|
-
toApiLocality,
|
|
38
|
-
tryAtIntervals,
|
|
39
|
-
unmarshalAnyRes,
|
|
40
|
-
unmarshalArrayOfObject,
|
|
41
|
-
unmarshalDate,
|
|
42
|
-
unmarshalDecimal,
|
|
43
|
-
unmarshalMapOfObject,
|
|
44
|
-
unmarshalMoney,
|
|
45
|
-
unmarshalScwFile,
|
|
46
|
-
unmarshalServiceInfo,
|
|
47
|
-
unmarshalTimeSeries,
|
|
48
|
-
unmarshalTimeSeriesPoint,
|
|
49
|
-
urlParams,
|
|
50
|
-
validatePathParam,
|
|
51
|
-
waitForResource,
|
|
52
|
-
withAdditionalInterceptors,
|
|
53
|
-
withDefaultPageSize,
|
|
54
|
-
withHTTPClient,
|
|
55
|
-
withProfile,
|
|
56
|
-
withUserAgent,
|
|
57
|
-
withUserAgentSuffix
|
|
58
|
-
};
|
|
17
|
+
export { API, AUTH_HEADER_KEY, Decimal, standard_exports as Errors, SESSION_HEADER_KEY, addAsyncHeaderInterceptor, authenticateWithSessionToken, createAdvancedClient, createClient, createExponentialBackoffStrategy, enableConsoleLogger, enrichForPagination, isJSONObject, marshalBlobToScwFile, marshalDecimal, marshalMoney, marshalScwFile, marshalTimeSeries, resolveOneOf, setLogger, toApiLocality, tryAtIntervals, unmarshalAnyRes, unmarshalArrayOfObject, unmarshalDate, unmarshalDecimal, unmarshalMapOfObject, unmarshalMoney, unmarshalScwFile, unmarshalServiceInfo, unmarshalTimeSeries, unmarshalTimeSeriesPoint, urlParams, validatePathParam, waitForResource, withAdditionalInterceptors, withDefaultPageSize, withHTTPClient, withProfile, withUserAgent, withUserAgentSuffix };
|
|
@@ -1,54 +1,69 @@
|
|
|
1
1
|
import { sleep } from "./sleep.js";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
var DEFAULT_TIMEOUT_SECONDS = 300;
|
|
3
|
+
var DEFAULT_MIN_DELAY_SECONDS = 1;
|
|
4
|
+
var DEFAULT_MAX_DELAY_SECONDS = 30;
|
|
5
|
+
/**
|
|
6
|
+
* Creates an exponential backoff interval strategy.
|
|
7
|
+
*
|
|
8
|
+
* @param minDelay - The minimum delay before the next try in seconds
|
|
9
|
+
* @param maxDelay - The maximum delay before the next try in seconds
|
|
10
|
+
* @returns An exponential backoff generator
|
|
11
|
+
*
|
|
12
|
+
* @internal
|
|
13
|
+
*/
|
|
5
14
|
function* createExponentialBackoffStrategy(minDelay, maxDelay) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
if (attempt > ceiling) {
|
|
16
|
-
yield maxDelay;
|
|
17
|
-
} else {
|
|
18
|
-
yield randomInRange(minDelay, minDelay * 2 ** (attempt - 1));
|
|
19
|
-
}
|
|
20
|
-
attempt += 1;
|
|
21
|
-
}
|
|
15
|
+
if (minDelay < 1 || maxDelay < 1 || minDelay > maxDelay) throw new Error("Waiter: minDelay must be >= 1 and maxDelay must be >= minDelay");
|
|
16
|
+
let attempt = 1;
|
|
17
|
+
const ceiling = Math.log(maxDelay / minDelay) / Math.log(2) + 1;
|
|
18
|
+
const randomInRange = (min, max) => min + Math.random() * (max - min);
|
|
19
|
+
while (true) {
|
|
20
|
+
if (attempt > ceiling) yield maxDelay;
|
|
21
|
+
else yield randomInRange(minDelay, minDelay * 2 ** (attempt - 1));
|
|
22
|
+
attempt += 1;
|
|
23
|
+
}
|
|
22
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* Tries a specific logic several times until it succeeds, timeouts, or throws an exception.
|
|
27
|
+
*
|
|
28
|
+
* @param retry - The function to retry logic between each interval
|
|
29
|
+
* @param strategy - A generated interval strategy iterator
|
|
30
|
+
* @param timeout - The maximum time elapsed before timeout error
|
|
31
|
+
*
|
|
32
|
+
* @throws An timeout exception or error thrown by the logic being run
|
|
33
|
+
*
|
|
34
|
+
* @internal
|
|
35
|
+
*/
|
|
23
36
|
const tryAtIntervals = async (retry, strategy, timeout = DEFAULT_TIMEOUT_SECONDS) => {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
};
|
|
36
|
-
const waitForResource = (stop, fetcher, request, options, strategy = createExponentialBackoffStrategy(
|
|
37
|
-
options?.minDelay ?? DEFAULT_MIN_DELAY_SECONDS,
|
|
38
|
-
options?.maxDelay ?? DEFAULT_MAX_DELAY_SECONDS
|
|
39
|
-
)) => tryAtIntervals(
|
|
40
|
-
async () => {
|
|
41
|
-
const value = await fetcher(request);
|
|
42
|
-
return {
|
|
43
|
-
done: await stop(value),
|
|
44
|
-
value
|
|
45
|
-
};
|
|
46
|
-
},
|
|
47
|
-
strategy,
|
|
48
|
-
options?.timeout
|
|
49
|
-
);
|
|
50
|
-
export {
|
|
51
|
-
createExponentialBackoffStrategy,
|
|
52
|
-
tryAtIntervals,
|
|
53
|
-
waitForResource
|
|
37
|
+
const timeoutTimestamp = Date.now() + timeout * 1e3;
|
|
38
|
+
let retryCount = 0;
|
|
39
|
+
while (Date.now() <= timeoutTimestamp) {
|
|
40
|
+
retryCount += 1;
|
|
41
|
+
const delay = strategy.next(retryCount).value * 1e3;
|
|
42
|
+
if (timeoutTimestamp <= Date.now() + delay) break;
|
|
43
|
+
await sleep(delay);
|
|
44
|
+
const { value, done } = await retry();
|
|
45
|
+
if (done) return value;
|
|
46
|
+
}
|
|
47
|
+
throw new Error(`Timeout after ${timeout}s`);
|
|
54
48
|
};
|
|
49
|
+
/**
|
|
50
|
+
* Fetches resource several times until an expected condition is reached, timeouts, or throws an exception.
|
|
51
|
+
*
|
|
52
|
+
* @param stop - The condition to stop waiting
|
|
53
|
+
* @param fetcher - The method to retrieve resource
|
|
54
|
+
* @param request - The resource request options
|
|
55
|
+
* @param options - The retry strategy options
|
|
56
|
+
* @param strategy - An optional custom strategy
|
|
57
|
+
*
|
|
58
|
+
* @returns A promise of resource
|
|
59
|
+
*
|
|
60
|
+
* @public
|
|
61
|
+
*/
|
|
62
|
+
const waitForResource = (stop, fetcher, request, options, strategy = createExponentialBackoffStrategy(options?.minDelay ?? DEFAULT_MIN_DELAY_SECONDS, options?.maxDelay ?? DEFAULT_MAX_DELAY_SECONDS)) => tryAtIntervals(async () => {
|
|
63
|
+
const value = await fetcher(request);
|
|
64
|
+
return {
|
|
65
|
+
done: await stop(value),
|
|
66
|
+
value
|
|
67
|
+
};
|
|
68
|
+
}, strategy, options?.timeout);
|
|
69
|
+
export { createExponentialBackoffStrategy, tryAtIntervals, waitForResource };
|
|
@@ -1,6 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sleep for a specified number of time.
|
|
3
|
+
*
|
|
4
|
+
* @param ms - The number of milliseconds
|
|
5
|
+
* @returns The sleep promise
|
|
6
|
+
*
|
|
7
|
+
* @internal
|
|
8
|
+
*/
|
|
1
9
|
const sleep = (ms) => new Promise((resolve) => {
|
|
2
|
-
|
|
10
|
+
setTimeout(resolve, ms);
|
|
3
11
|
});
|
|
4
|
-
export {
|
|
5
|
-
sleep
|
|
6
|
-
};
|
|
12
|
+
export { sleep };
|
|
@@ -1,25 +1,36 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Composes request interceptors.
|
|
3
|
+
*
|
|
4
|
+
* @param interceptors - A list of request interceptors
|
|
5
|
+
* @returns An async composed interceptor
|
|
6
|
+
*
|
|
7
|
+
* @internal
|
|
8
|
+
*/
|
|
9
|
+
const composeRequestInterceptors = (interceptors) => async (request) => interceptors.reduce(async (asyncResult, interceptor) => interceptor({ request: await asyncResult }), Promise.resolve(request));
|
|
10
|
+
/**
|
|
11
|
+
* Composes response interceptors.
|
|
12
|
+
*
|
|
13
|
+
* @param interceptors - A list of response interceptors
|
|
14
|
+
* @returns An async composed interceptor
|
|
15
|
+
*
|
|
16
|
+
* @internal
|
|
17
|
+
*/
|
|
18
|
+
const composeResponseInterceptors = (interceptors) => async (response) => interceptors.reduce(async (asyncResult, interceptor) => interceptor({ response: await asyncResult }), Promise.resolve(response));
|
|
19
|
+
/**
|
|
20
|
+
* Compose response error interceptors.
|
|
21
|
+
*
|
|
22
|
+
* @internal
|
|
23
|
+
*/
|
|
9
24
|
const composeResponseErrorInterceptors = (interceptors) => async (request, error) => {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
};
|
|
21
|
-
export {
|
|
22
|
-
composeRequestInterceptors,
|
|
23
|
-
composeResponseErrorInterceptors,
|
|
24
|
-
composeResponseInterceptors
|
|
25
|
+
let prevError = error;
|
|
26
|
+
for (const interceptor of interceptors) try {
|
|
27
|
+
return await interceptor({
|
|
28
|
+
request,
|
|
29
|
+
error: prevError
|
|
30
|
+
});
|
|
31
|
+
} catch (err) {
|
|
32
|
+
prevError = err;
|
|
33
|
+
}
|
|
34
|
+
throw prevError;
|
|
25
35
|
};
|
|
36
|
+
export { composeRequestInterceptors, composeResponseErrorInterceptors, composeResponseInterceptors };
|
|
@@ -1,12 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adds an header to a request through an interceptor.
|
|
3
|
+
*
|
|
4
|
+
* @param key - The header key
|
|
5
|
+
* @param value - The header value
|
|
6
|
+
* @returns The Request interceptor
|
|
7
|
+
*
|
|
8
|
+
* @internal
|
|
9
|
+
*/
|
|
1
10
|
const addHeaderInterceptor = (key, value) => ({ request }) => {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
}
|
|
6
|
-
return clone;
|
|
11
|
+
const clone = request.clone();
|
|
12
|
+
if (value !== void 0) clone.headers.append(key, value);
|
|
13
|
+
return clone;
|
|
7
14
|
};
|
|
15
|
+
/**
|
|
16
|
+
* Adds asynchronously an header to a request through an interceptor.
|
|
17
|
+
*
|
|
18
|
+
* @param key - The header key
|
|
19
|
+
* @param value - The header value as a Promise
|
|
20
|
+
* @returns The Request interceptor
|
|
21
|
+
*
|
|
22
|
+
* @internal
|
|
23
|
+
*/
|
|
8
24
|
const addAsyncHeaderInterceptor = (key, getter) => async (request) => addHeaderInterceptor(key, await getter())(request);
|
|
9
|
-
export {
|
|
10
|
-
addAsyncHeaderInterceptor,
|
|
11
|
-
addHeaderInterceptor
|
|
12
|
-
};
|
|
25
|
+
export { addAsyncHeaderInterceptor, addHeaderInterceptor };
|
|
@@ -1,24 +1,29 @@
|
|
|
1
1
|
import { LevelResolver, shouldLog } from "./level-resolver.js";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
|
|
2
|
+
/**
|
|
3
|
+
* A Logger using console output.
|
|
4
|
+
*
|
|
5
|
+
* @param logLevel - The logger level name
|
|
6
|
+
* @param prefix - An optional logger message prefix
|
|
7
|
+
* @param output - The output to print logs, using by default the global console object
|
|
8
|
+
*
|
|
9
|
+
* @internal
|
|
10
|
+
*/
|
|
11
|
+
var ConsoleLogger = class {
|
|
12
|
+
level;
|
|
13
|
+
constructor(logLevel, prefix = "", output = console) {
|
|
14
|
+
this.logLevel = logLevel;
|
|
15
|
+
this.prefix = prefix;
|
|
16
|
+
this.output = output;
|
|
17
|
+
this.level = LevelResolver[this.logLevel];
|
|
18
|
+
}
|
|
19
|
+
makeMethod(method) {
|
|
20
|
+
return (message) => {
|
|
21
|
+
if (shouldLog(this.level, method)) this.output[method](this.prefix ? `${this.prefix} ${message}` : message);
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
debug = this.makeMethod("debug");
|
|
25
|
+
error = this.makeMethod("error");
|
|
26
|
+
info = this.makeMethod("info");
|
|
27
|
+
warn = this.makeMethod("warn");
|
|
24
28
|
};
|
|
29
|
+
export { ConsoleLogger };
|