@scaleway/sdk-std 1.0.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 +191 -0
- package/dist/index.gen.cjs +1 -0
- package/dist/index.gen.d.ts +1 -0
- package/dist/index.gen.js +1 -0
- package/dist/types.gen.d.ts +2 -0
- package/node_modules/@scaleway/sdk-client/README.md +36 -0
- package/node_modules/@scaleway/sdk-client/dist/bridge.d.ts +12 -0
- package/node_modules/@scaleway/sdk-client/dist/helpers/is-browser.cjs +4 -0
- package/node_modules/@scaleway/sdk-client/dist/helpers/is-browser.d.ts +1 -0
- package/node_modules/@scaleway/sdk-client/dist/helpers/is-browser.js +4 -0
- package/node_modules/@scaleway/sdk-client/dist/helpers/is-response.cjs +4 -0
- package/node_modules/@scaleway/sdk-client/dist/helpers/is-response.d.ts +8 -0
- package/node_modules/@scaleway/sdk-client/dist/helpers/is-response.js +4 -0
- package/node_modules/@scaleway/sdk-client/dist/helpers/json.cjs +47 -0
- package/node_modules/@scaleway/sdk-client/dist/helpers/json.d.ts +32 -0
- package/node_modules/@scaleway/sdk-client/dist/helpers/json.js +47 -0
- package/node_modules/@scaleway/sdk-client/dist/helpers/marshalling.cjs +76 -0
- package/node_modules/@scaleway/sdk-client/dist/helpers/marshalling.d.ts +60 -0
- package/node_modules/@scaleway/sdk-client/dist/helpers/marshalling.js +76 -0
- package/node_modules/@scaleway/sdk-client/dist/index.cjs +56 -0
- package/node_modules/@scaleway/sdk-client/dist/index.d.ts +16 -0
- package/node_modules/@scaleway/sdk-client/dist/index.js +56 -0
- package/node_modules/@scaleway/sdk-client/dist/internal/async/interval-retrier.cjs +53 -0
- package/node_modules/@scaleway/sdk-client/dist/internal/async/interval-retrier.d.ts +111 -0
- package/node_modules/@scaleway/sdk-client/dist/internal/async/interval-retrier.js +53 -0
- package/node_modules/@scaleway/sdk-client/dist/internal/async/sleep.cjs +6 -0
- package/node_modules/@scaleway/sdk-client/dist/internal/async/sleep.d.ts +9 -0
- package/node_modules/@scaleway/sdk-client/dist/internal/async/sleep.js +6 -0
- package/node_modules/@scaleway/sdk-client/dist/internal/interceptors/composer.cjs +25 -0
- package/node_modules/@scaleway/sdk-client/dist/internal/interceptors/composer.d.ts +25 -0
- package/node_modules/@scaleway/sdk-client/dist/internal/interceptors/composer.js +25 -0
- package/node_modules/@scaleway/sdk-client/dist/internal/interceptors/helpers.cjs +12 -0
- package/node_modules/@scaleway/sdk-client/dist/internal/interceptors/helpers.d.ts +21 -0
- package/node_modules/@scaleway/sdk-client/dist/internal/interceptors/helpers.js +12 -0
- package/node_modules/@scaleway/sdk-client/dist/internal/interceptors/types.d.ts +89 -0
- package/node_modules/@scaleway/sdk-client/dist/internal/logger/console-logger.cjs +24 -0
- package/node_modules/@scaleway/sdk-client/dist/internal/logger/console-logger.d.ts +23 -0
- package/node_modules/@scaleway/sdk-client/dist/internal/logger/console-logger.js +24 -0
- package/node_modules/@scaleway/sdk-client/dist/internal/logger/index.cjs +12 -0
- package/node_modules/@scaleway/sdk-client/dist/internal/logger/index.d.ts +25 -0
- package/node_modules/@scaleway/sdk-client/dist/internal/logger/index.js +12 -0
- package/node_modules/@scaleway/sdk-client/dist/internal/logger/level-resolver.cjs +13 -0
- package/node_modules/@scaleway/sdk-client/dist/internal/logger/level-resolver.d.ts +9 -0
- package/node_modules/@scaleway/sdk-client/dist/internal/logger/level-resolver.js +13 -0
- package/node_modules/@scaleway/sdk-client/dist/internal/logger/logger.d.ts +13 -0
- package/node_modules/@scaleway/sdk-client/dist/internal/validations/string-validation.cjs +30 -0
- package/node_modules/@scaleway/sdk-client/dist/internal/validations/string-validation.d.ts +18 -0
- package/node_modules/@scaleway/sdk-client/dist/internal/validations/string-validation.js +30 -0
- package/node_modules/@scaleway/sdk-client/dist/internals.d.ts +10 -0
- package/node_modules/@scaleway/sdk-client/dist/package.json.cjs +8 -0
- package/node_modules/@scaleway/sdk-client/dist/package.json.js +8 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/api.cjs +8 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/api.d.ts +10 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/api.js +8 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/auth.cjs +25 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/auth.d.ts +70 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/auth.js +25 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/client-ini-factory.cjs +66 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/client-ini-factory.d.ts +111 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/client-ini-factory.js +66 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/client-ini-profile.cjs +23 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/client-ini-profile.d.ts +82 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/client-ini-profile.js +23 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/client-settings.cjs +51 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/client-settings.d.ts +59 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/client-settings.js +51 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/client.cjs +31 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/client.d.ts +71 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/client.js +31 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/constants.cjs +11 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/constants.d.ts +4 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/constants.js +11 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/custom-marshalling.cjs +152 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/custom-marshalling.d.ts +104 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/custom-marshalling.js +152 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/custom-types.cjs +11 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/custom-types.d.ts +74 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/custom-types.js +11 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/error-parser.cjs +76 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/error-parser.d.ts +12 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/error-parser.js +76 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/non-standard/invalid-request-mapper.cjs +36 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/non-standard/invalid-request-mapper.d.ts +12 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/non-standard/invalid-request-mapper.js +36 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/non-standard/unknown-resource-mapper.cjs +23 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/non-standard/unknown-resource-mapper.d.ts +11 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/non-standard/unknown-resource-mapper.js +23 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/scw-error-from-json.d.ts +10 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/scw-error.cjs +43 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/scw-error.d.ts +25 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/scw-error.js +43 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/standard/already-exists-error.cjs +31 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/standard/already-exists-error.d.ts +16 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/standard/already-exists-error.js +31 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/standard/denied-authentication-error.cjs +37 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/standard/denied-authentication-error.d.ts +15 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/standard/denied-authentication-error.js +37 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/standard/index.cjs +28 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/standard/index.d.ts +17 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/standard/index.js +28 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/standard/invalid-arguments-error.cjs +54 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/standard/invalid-arguments-error.d.ts +24 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/standard/invalid-arguments-error.js +54 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/standard/out-of-stock-error.cjs +17 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/standard/out-of-stock-error.d.ts +14 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/standard/out-of-stock-error.js +17 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/standard/permissions-denied-error.cjs +29 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/standard/permissions-denied-error.d.ts +23 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/standard/permissions-denied-error.js +29 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/standard/precondition-failed-error.cjs +32 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/standard/precondition-failed-error.d.ts +15 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/standard/precondition-failed-error.js +32 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/standard/quotas-exceeded-error.cjs +43 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/standard/quotas-exceeded-error.d.ts +34 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/standard/quotas-exceeded-error.js +43 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/standard/resource-expired-error.cjs +31 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/standard/resource-expired-error.d.ts +16 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/standard/resource-expired-error.js +31 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/standard/resource-locked-error.cjs +20 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/standard/resource-locked-error.d.ts +15 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/standard/resource-locked-error.js +20 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/standard/resource-not-found-error.cjs +24 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/standard/resource-not-found-error.d.ts +15 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/standard/resource-not-found-error.js +24 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/standard/too-many-requests-error.cjs +58 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/standard/too-many-requests-error.d.ts +32 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/standard/too-many-requests-error.js +58 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/standard/transient-state-error.cjs +31 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/standard/transient-state-error.d.ts +16 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/standard/transient-state-error.js +31 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/types.cjs +15 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/types.d.ts +9 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/errors/types.js +15 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/fetch/build-fetcher.cjs +60 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/fetch/build-fetcher.d.ts +23 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/fetch/build-fetcher.js +60 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/fetch/http-dumper.cjs +20 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/fetch/http-dumper.d.ts +18 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/fetch/http-dumper.js +20 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/fetch/http-interceptors.cjs +43 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/fetch/http-interceptors.d.ts +38 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/fetch/http-interceptors.js +43 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/fetch/resource-paginator.cjs +36 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/fetch/resource-paginator.d.ts +47 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/fetch/resource-paginator.js +36 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/fetch/response-parser.cjs +55 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/fetch/response-parser.d.ts +25 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/fetch/response-parser.js +55 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/fetch/types.d.ts +16 -0
- package/node_modules/@scaleway/sdk-client/dist/scw/locality.d.ts +2 -0
- package/node_modules/@scaleway/sdk-client/dist/vendor/base64/index.cjs +46 -0
- package/node_modules/@scaleway/sdk-client/dist/vendor/base64/index.js +46 -0
- package/node_modules/@scaleway/sdk-client/package.json +36 -0
- package/package.json +41 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Settings } from '../client-settings.js';
|
|
2
|
+
import type { ResponseUnmarshaller, ScwRequest } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Builds Request from {@link ScwRequest} & {@link Settings}.
|
|
5
|
+
*
|
|
6
|
+
* @param request - A scaleway request
|
|
7
|
+
* @param settings - The settings
|
|
8
|
+
* @returns A fetch Request
|
|
9
|
+
*
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
export declare const buildRequest: (request: Readonly<ScwRequest>, settings: Readonly<Settings>) => Request;
|
|
13
|
+
export type Fetcher = <T>(request: Readonly<ScwRequest>, unwrapper?: ResponseUnmarshaller<T>) => Promise<T>;
|
|
14
|
+
/**
|
|
15
|
+
* Builds a resource fetcher.
|
|
16
|
+
*
|
|
17
|
+
* @param settings - The {@link Settings} object
|
|
18
|
+
* @param httpClient - The HTTP client that should be used to call the API
|
|
19
|
+
* @returns The fetcher
|
|
20
|
+
*
|
|
21
|
+
* @internal
|
|
22
|
+
*/
|
|
23
|
+
export declare const buildFetcher: (settings: Settings, httpClient: typeof fetch) => <T>(request: Readonly<ScwRequest>, unwrapper?: ResponseUnmarshaller<T>) => Promise<T>;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { isBrowser } from "../../helpers/is-browser.js";
|
|
2
|
+
import { composeRequestInterceptors, composeResponseInterceptors, composeResponseErrorInterceptors } from "../../internal/interceptors/composer.js";
|
|
3
|
+
import { obfuscateAuthHeadersEntry } from "../auth.js";
|
|
4
|
+
import { logRequest, logResponse, obfuscateInterceptor } from "./http-interceptors.js";
|
|
5
|
+
import { responseParser } from "./response-parser.js";
|
|
6
|
+
const buildRequest = (request, settings) => {
|
|
7
|
+
let { path } = request;
|
|
8
|
+
if (request.urlParams instanceof URLSearchParams) {
|
|
9
|
+
path = path.concat(`?${request.urlParams.toString()}`);
|
|
10
|
+
}
|
|
11
|
+
return new Request(`${settings.apiURL}${path}`, {
|
|
12
|
+
body: request.body,
|
|
13
|
+
headers: {
|
|
14
|
+
Accept: "application/json",
|
|
15
|
+
.../* istanbul ignore next */
|
|
16
|
+
!isBrowser() ? { "User-Agent": settings.userAgent } : {},
|
|
17
|
+
...request.headers
|
|
18
|
+
},
|
|
19
|
+
method: request.method
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
const asIs = (response) => response;
|
|
23
|
+
const buildFetcher = (settings, httpClient) => {
|
|
24
|
+
let requestNumber = 0;
|
|
25
|
+
const prepareRequest = (requestId) => composeRequestInterceptors([
|
|
26
|
+
...settings.interceptors.map((obj) => obj.request).filter((obj) => obj),
|
|
27
|
+
logRequest(requestId, obfuscateInterceptor(obfuscateAuthHeadersEntry))
|
|
28
|
+
]);
|
|
29
|
+
const prepareResponse = (requestId) => composeResponseInterceptors([
|
|
30
|
+
...settings.interceptors.map((obj) => obj.response).filter((obj) => obj),
|
|
31
|
+
logResponse(requestId)
|
|
32
|
+
]);
|
|
33
|
+
const prepareResponseErrors = () => composeResponseErrorInterceptors(
|
|
34
|
+
settings.interceptors.map((obj) => obj.responseError).filter((obj) => obj)
|
|
35
|
+
);
|
|
36
|
+
return async (request, unwrapper = asIs) => {
|
|
37
|
+
const requestId = `${requestNumber += 1}`;
|
|
38
|
+
const reqInterceptors = prepareRequest(requestId);
|
|
39
|
+
const finalRequest = await reqInterceptors(buildRequest(request, settings));
|
|
40
|
+
try {
|
|
41
|
+
const response = await httpClient(finalRequest);
|
|
42
|
+
const resInterceptors = prepareResponse(requestId);
|
|
43
|
+
const finalResponse = await resInterceptors(response);
|
|
44
|
+
const resUnmarshaller = responseParser(
|
|
45
|
+
unwrapper,
|
|
46
|
+
request.responseType ?? "json"
|
|
47
|
+
);
|
|
48
|
+
const unmarshaledResponse = await resUnmarshaller(finalResponse);
|
|
49
|
+
return unmarshaledResponse;
|
|
50
|
+
} catch (err) {
|
|
51
|
+
const resErrorInterceptors = prepareResponseErrors();
|
|
52
|
+
const handledError = await resErrorInterceptors(finalRequest, err);
|
|
53
|
+
return unwrapper(handledError);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
export {
|
|
58
|
+
buildFetcher,
|
|
59
|
+
buildRequest
|
|
60
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const toPascalCase = (str) => str.replace(
|
|
4
|
+
/\w+/g,
|
|
5
|
+
(word) => `${word[0].toUpperCase()}${word.slice(1).toLowerCase()}`
|
|
6
|
+
);
|
|
7
|
+
const serializeHeadersEntry = ([name, value]) => `${toPascalCase(name)}: ${value}`;
|
|
8
|
+
const serializeHeaders = (headers) => Array.from(headers.entries(), serializeHeadersEntry);
|
|
9
|
+
const dumpRequest = async (request) => [
|
|
10
|
+
`${request.method.toUpperCase()}: ${request.url}`,
|
|
11
|
+
...serializeHeaders(request.headers),
|
|
12
|
+
await request.clone().text()
|
|
13
|
+
].join("\r\n");
|
|
14
|
+
const dumpResponse = async (response) => [
|
|
15
|
+
`HTTP ${response.status} ${response.ok ? "OK" : "NOK"}`,
|
|
16
|
+
...serializeHeaders(response.headers),
|
|
17
|
+
await response.clone().text()
|
|
18
|
+
].join("\r\n");
|
|
19
|
+
exports.dumpRequest = dumpRequest;
|
|
20
|
+
exports.dumpResponse = dumpResponse;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dumps a Request into a readable string.
|
|
3
|
+
*
|
|
4
|
+
* @param request - The request
|
|
5
|
+
* @returns The readable string
|
|
6
|
+
*
|
|
7
|
+
* @internal
|
|
8
|
+
*/
|
|
9
|
+
export declare const dumpRequest: (request: Readonly<Request>) => Promise<string>;
|
|
10
|
+
/**
|
|
11
|
+
* Dumps a Response into a readable string.
|
|
12
|
+
*
|
|
13
|
+
* @param response - The response
|
|
14
|
+
* @returns The readable string
|
|
15
|
+
*
|
|
16
|
+
* @internal
|
|
17
|
+
*/
|
|
18
|
+
export declare const dumpResponse: (response: Readonly<Response>) => Promise<string>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const toPascalCase = (str) => str.replace(
|
|
2
|
+
/\w+/g,
|
|
3
|
+
(word) => `${word[0].toUpperCase()}${word.slice(1).toLowerCase()}`
|
|
4
|
+
);
|
|
5
|
+
const serializeHeadersEntry = ([name, value]) => `${toPascalCase(name)}: ${value}`;
|
|
6
|
+
const serializeHeaders = (headers) => Array.from(headers.entries(), serializeHeadersEntry);
|
|
7
|
+
const dumpRequest = async (request) => [
|
|
8
|
+
`${request.method.toUpperCase()}: ${request.url}`,
|
|
9
|
+
...serializeHeaders(request.headers),
|
|
10
|
+
await request.clone().text()
|
|
11
|
+
].join("\r\n");
|
|
12
|
+
const dumpResponse = async (response) => [
|
|
13
|
+
`HTTP ${response.status} ${response.ok ? "OK" : "NOK"}`,
|
|
14
|
+
...serializeHeaders(response.headers),
|
|
15
|
+
await response.clone().text()
|
|
16
|
+
].join("\r\n");
|
|
17
|
+
export {
|
|
18
|
+
dumpRequest,
|
|
19
|
+
dumpResponse
|
|
20
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const index = require("../../internal/logger/index.cjs");
|
|
4
|
+
const levelResolver = require("../../internal/logger/level-resolver.cjs");
|
|
5
|
+
const httpDumper = require("./http-dumper.cjs");
|
|
6
|
+
class ObfuscatedRequest extends Request {
|
|
7
|
+
constructor(request, obfuscate) {
|
|
8
|
+
super(request);
|
|
9
|
+
this.request = request;
|
|
10
|
+
this.obfuscate = obfuscate;
|
|
11
|
+
}
|
|
12
|
+
get headers() {
|
|
13
|
+
return new Headers(Array.from(this.request.headers, this.obfuscate));
|
|
14
|
+
}
|
|
15
|
+
clone() {
|
|
16
|
+
return new ObfuscatedRequest(this.request, this.obfuscate);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
const obfuscateInterceptor = (obfuscate) => ({ request }) => new ObfuscatedRequest(request, obfuscate);
|
|
20
|
+
const identity = ({ request }) => request;
|
|
21
|
+
const logRequest = (identifier, obfuscate = identity) => async ({ request }) => {
|
|
22
|
+
if (levelResolver.shouldLog(levelResolver.LevelResolver[index.getLogger().logLevel], "debug")) {
|
|
23
|
+
index.getLogger().debug(
|
|
24
|
+
`--------------- Scaleway SDK REQUEST ${identifier} ---------------
|
|
25
|
+
${await httpDumper.dumpRequest(await obfuscate({ request }))}
|
|
26
|
+
---------------------------------------------------------`
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
return request;
|
|
30
|
+
};
|
|
31
|
+
const logResponse = (identifier) => async ({ response }) => {
|
|
32
|
+
if (levelResolver.shouldLog(levelResolver.LevelResolver[index.getLogger().logLevel], "debug")) {
|
|
33
|
+
index.getLogger().debug(
|
|
34
|
+
`--------------- Scaleway SDK RESPONSE ${identifier} ---------------
|
|
35
|
+
${await httpDumper.dumpResponse(response)}
|
|
36
|
+
---------------------------------------------------------`
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
return response;
|
|
40
|
+
};
|
|
41
|
+
exports.logRequest = logRequest;
|
|
42
|
+
exports.logResponse = logResponse;
|
|
43
|
+
exports.obfuscateInterceptor = obfuscateInterceptor;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { RequestInterceptor, ResponseInterceptor } from '../../internal/interceptors/types';
|
|
2
|
+
/**
|
|
3
|
+
* Mapper of an header entry.
|
|
4
|
+
*
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
7
|
+
interface HeaderEntryMapper {
|
|
8
|
+
(entry: [string, string]): [string, string];
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Creates an interceptor to obfuscate the requests.
|
|
12
|
+
*
|
|
13
|
+
* @param obfuscate - The Header entries obfuscator mapper
|
|
14
|
+
* @returns The obfuscated Request
|
|
15
|
+
*
|
|
16
|
+
* @internal
|
|
17
|
+
*/
|
|
18
|
+
export declare const obfuscateInterceptor: (obfuscate: HeaderEntryMapper) => RequestInterceptor;
|
|
19
|
+
/**
|
|
20
|
+
* Creates an interceptor to log the requests.
|
|
21
|
+
*
|
|
22
|
+
* @param identifier - The request identifier
|
|
23
|
+
* @param obfuscate - The obfuscation interceptor
|
|
24
|
+
* @returns The interceptor
|
|
25
|
+
*
|
|
26
|
+
* @internal
|
|
27
|
+
*/
|
|
28
|
+
export declare const logRequest: (identifier: string, obfuscate?: RequestInterceptor) => RequestInterceptor;
|
|
29
|
+
/**
|
|
30
|
+
* Creates an interceptor to log the responses.
|
|
31
|
+
*
|
|
32
|
+
* @param identifier - The request identifier
|
|
33
|
+
* @returns The interceptor
|
|
34
|
+
*
|
|
35
|
+
* @internal
|
|
36
|
+
*/
|
|
37
|
+
export declare const logResponse: (identifier: string) => ResponseInterceptor;
|
|
38
|
+
export {};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { getLogger } from "../../internal/logger/index.js";
|
|
2
|
+
import { shouldLog, LevelResolver } from "../../internal/logger/level-resolver.js";
|
|
3
|
+
import { dumpRequest, dumpResponse } from "./http-dumper.js";
|
|
4
|
+
class ObfuscatedRequest extends Request {
|
|
5
|
+
constructor(request, obfuscate) {
|
|
6
|
+
super(request);
|
|
7
|
+
this.request = request;
|
|
8
|
+
this.obfuscate = obfuscate;
|
|
9
|
+
}
|
|
10
|
+
get headers() {
|
|
11
|
+
return new Headers(Array.from(this.request.headers, this.obfuscate));
|
|
12
|
+
}
|
|
13
|
+
clone() {
|
|
14
|
+
return new ObfuscatedRequest(this.request, this.obfuscate);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
const obfuscateInterceptor = (obfuscate) => ({ request }) => new ObfuscatedRequest(request, obfuscate);
|
|
18
|
+
const identity = ({ request }) => request;
|
|
19
|
+
const logRequest = (identifier, obfuscate = identity) => async ({ request }) => {
|
|
20
|
+
if (shouldLog(LevelResolver[getLogger().logLevel], "debug")) {
|
|
21
|
+
getLogger().debug(
|
|
22
|
+
`--------------- Scaleway SDK REQUEST ${identifier} ---------------
|
|
23
|
+
${await dumpRequest(await obfuscate({ request }))}
|
|
24
|
+
---------------------------------------------------------`
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
return request;
|
|
28
|
+
};
|
|
29
|
+
const logResponse = (identifier) => async ({ response }) => {
|
|
30
|
+
if (shouldLog(LevelResolver[getLogger().logLevel], "debug")) {
|
|
31
|
+
getLogger().debug(
|
|
32
|
+
`--------------- Scaleway SDK RESPONSE ${identifier} ---------------
|
|
33
|
+
${await dumpResponse(response)}
|
|
34
|
+
---------------------------------------------------------`
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
return response;
|
|
38
|
+
};
|
|
39
|
+
export {
|
|
40
|
+
logRequest,
|
|
41
|
+
logResponse,
|
|
42
|
+
obfuscateInterceptor
|
|
43
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const extract = (key) => (result) => result[key];
|
|
4
|
+
function* pages(key, fetcher, request, firstPage) {
|
|
5
|
+
if (!Array.isArray(firstPage[key])) {
|
|
6
|
+
throw new Error(`Property ${key} is not a list in paginated result`);
|
|
7
|
+
}
|
|
8
|
+
const getList = extract(key);
|
|
9
|
+
let page = request.page || 1;
|
|
10
|
+
if (page === 1) {
|
|
11
|
+
yield Promise.resolve(getList(firstPage));
|
|
12
|
+
page += 1;
|
|
13
|
+
}
|
|
14
|
+
const { length } = firstPage[key];
|
|
15
|
+
if (!length) return;
|
|
16
|
+
const { totalCount } = firstPage;
|
|
17
|
+
while (page <= Math.floor((totalCount + length - 1) / length)) {
|
|
18
|
+
yield fetcher({ ...request, page }).then(getList);
|
|
19
|
+
page += 1;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
async function* fetchPaginated(key, fetcher, request, initial = fetcher(request)) {
|
|
23
|
+
yield* pages(key, fetcher, request, await initial);
|
|
24
|
+
}
|
|
25
|
+
const fetchAll = async (key, fetcher, request, initial = fetcher(request)) => (await Promise.all(Array.from(pages(key, fetcher, request, await initial)))).flat();
|
|
26
|
+
const enrichForPagination = (key, fetcher, request) => {
|
|
27
|
+
const firstPage = fetcher(request);
|
|
28
|
+
return Object.assign(firstPage, {
|
|
29
|
+
all: () => fetchAll(key, fetcher, request, firstPage),
|
|
30
|
+
[Symbol.asyncIterator]: () => fetchPaginated(key, fetcher, request, firstPage)
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
exports.enrichForPagination = enrichForPagination;
|
|
34
|
+
exports.extract = extract;
|
|
35
|
+
exports.fetchAll = fetchAll;
|
|
36
|
+
exports.fetchPaginated = fetchPaginated;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
interface PaginationOptions {
|
|
2
|
+
page?: number;
|
|
3
|
+
pageSize?: number;
|
|
4
|
+
}
|
|
5
|
+
interface PaginatedResponse {
|
|
6
|
+
totalCount: number;
|
|
7
|
+
}
|
|
8
|
+
export type PaginatedFetcher<T, R extends PaginationOptions = PaginationOptions> = (request: R) => Promise<T>;
|
|
9
|
+
export type PaginatedContent<K extends string, T = unknown> = PaginatedResponse & {
|
|
10
|
+
[key in K]: T[];
|
|
11
|
+
};
|
|
12
|
+
export declare const extract: <K extends string>(key: K) => <T extends PaginatedContent<K>>(result: T) => T[K];
|
|
13
|
+
/**
|
|
14
|
+
* Fetches a paginated resource.
|
|
15
|
+
*
|
|
16
|
+
* @param key - The resource key of values list
|
|
17
|
+
* @param fetcher - The method to retrieve paginated resources
|
|
18
|
+
* @param request - A request with pagination options
|
|
19
|
+
* @param initial - The first page
|
|
20
|
+
* @returns An async generator of resources arrays
|
|
21
|
+
*/
|
|
22
|
+
export declare function fetchPaginated<K extends string, T extends PaginatedContent<K>, R extends PaginationOptions>(key: K, fetcher: PaginatedFetcher<T, R>, request: R, initial?: Promise<T>): AsyncGenerator<T[K], void, void>;
|
|
23
|
+
/**
|
|
24
|
+
* Fetches all paginated resource.
|
|
25
|
+
*
|
|
26
|
+
* @param key - The resource key of values list
|
|
27
|
+
* @param fetcher - The method to retrieve paginated resources
|
|
28
|
+
* @param request - A request with pagination options
|
|
29
|
+
* @param initial - The first page
|
|
30
|
+
* @returns A resources array Promise
|
|
31
|
+
*/
|
|
32
|
+
export declare const fetchAll: <K extends string, T extends PaginatedContent<K>, R extends PaginationOptions>(key: K, fetcher: PaginatedFetcher<T, R>, request: R, initial?: Promise<T>) => Promise<(Awaited<T[K]> extends infer T_1 ? T_1 extends Awaited<T[K]> ? T_1 extends readonly (infer InnerArr)[] ? InnerArr : T_1 : never : never)[]>;
|
|
33
|
+
/**
|
|
34
|
+
* Enriches a listing method with helpers.
|
|
35
|
+
*
|
|
36
|
+
* @param key - The resource key of values list
|
|
37
|
+
* @param fetcher - The method to retrieve paginated resources
|
|
38
|
+
* @param request - A request with pagination options
|
|
39
|
+
* @returns A resource Promise with the pagination helpers
|
|
40
|
+
*
|
|
41
|
+
* @internal
|
|
42
|
+
*/
|
|
43
|
+
export declare const enrichForPagination: <K extends string, T extends PaginatedContent<K>, R extends PaginationOptions>(key: K, fetcher: PaginatedFetcher<T, R>, request: R) => Promise<T> & {
|
|
44
|
+
all: () => Promise<(Awaited<T[K]> extends infer T_1 ? T_1 extends Awaited<T[K]> ? T_1 extends readonly (infer InnerArr)[] ? InnerArr : T_1 : never : never)[]>;
|
|
45
|
+
[Symbol.asyncIterator]: () => AsyncGenerator<T[K], void, void>;
|
|
46
|
+
};
|
|
47
|
+
export {};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
const extract = (key) => (result) => result[key];
|
|
2
|
+
function* pages(key, fetcher, request, firstPage) {
|
|
3
|
+
if (!Array.isArray(firstPage[key])) {
|
|
4
|
+
throw new Error(`Property ${key} is not a list in paginated result`);
|
|
5
|
+
}
|
|
6
|
+
const getList = extract(key);
|
|
7
|
+
let page = request.page || 1;
|
|
8
|
+
if (page === 1) {
|
|
9
|
+
yield Promise.resolve(getList(firstPage));
|
|
10
|
+
page += 1;
|
|
11
|
+
}
|
|
12
|
+
const { length } = firstPage[key];
|
|
13
|
+
if (!length) return;
|
|
14
|
+
const { totalCount } = firstPage;
|
|
15
|
+
while (page <= Math.floor((totalCount + length - 1) / length)) {
|
|
16
|
+
yield fetcher({ ...request, page }).then(getList);
|
|
17
|
+
page += 1;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
async function* fetchPaginated(key, fetcher, request, initial = fetcher(request)) {
|
|
21
|
+
yield* pages(key, fetcher, request, await initial);
|
|
22
|
+
}
|
|
23
|
+
const fetchAll = async (key, fetcher, request, initial = fetcher(request)) => (await Promise.all(Array.from(pages(key, fetcher, request, await initial)))).flat();
|
|
24
|
+
const enrichForPagination = (key, fetcher, request) => {
|
|
25
|
+
const firstPage = fetcher(request);
|
|
26
|
+
return Object.assign(firstPage, {
|
|
27
|
+
all: () => fetchAll(key, fetcher, request, firstPage),
|
|
28
|
+
[Symbol.asyncIterator]: () => fetchPaginated(key, fetcher, request, firstPage)
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
export {
|
|
32
|
+
enrichForPagination,
|
|
33
|
+
extract,
|
|
34
|
+
fetchAll,
|
|
35
|
+
fetchPaginated
|
|
36
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const isResponse = require("../../helpers/is-response.cjs");
|
|
4
|
+
const json = require("../../helpers/json.cjs");
|
|
5
|
+
const errorParser = require("../errors/error-parser.cjs");
|
|
6
|
+
const scwError = require("../errors/scw-error.cjs");
|
|
7
|
+
const X_TOTAL_COUNT_HEADER_KEY = "x-total-count";
|
|
8
|
+
const TOTAL_COUNT_RES_KEY = "total_count";
|
|
9
|
+
const fixLegacyTotalCount = (obj, headers) => {
|
|
10
|
+
const headerVal = headers.get(X_TOTAL_COUNT_HEADER_KEY);
|
|
11
|
+
if (!headerVal) {
|
|
12
|
+
return obj;
|
|
13
|
+
}
|
|
14
|
+
const totalCount = parseInt(headerVal, 10);
|
|
15
|
+
if (Number.isNaN(totalCount)) {
|
|
16
|
+
return obj;
|
|
17
|
+
}
|
|
18
|
+
if (json.isJSONObject(obj) && !(TOTAL_COUNT_RES_KEY in obj)) {
|
|
19
|
+
return Object.assign(obj, { [TOTAL_COUNT_RES_KEY]: totalCount });
|
|
20
|
+
}
|
|
21
|
+
return obj;
|
|
22
|
+
};
|
|
23
|
+
const responseParser = (unmarshaller, responseType) => async (response) => {
|
|
24
|
+
if (!isResponse.isResponse(response)) {
|
|
25
|
+
throw new TypeError("Invalid response object");
|
|
26
|
+
}
|
|
27
|
+
if (response.ok) {
|
|
28
|
+
if (response.status === 204) return unmarshaller(void 0);
|
|
29
|
+
const contentType = response.headers.get("Content-Type");
|
|
30
|
+
try {
|
|
31
|
+
if (responseType === "json" && contentType === "application/json") {
|
|
32
|
+
return unmarshaller(
|
|
33
|
+
fixLegacyTotalCount(await response.json(), response.headers)
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
if (responseType === "blob") {
|
|
37
|
+
return unmarshaller(await response.blob());
|
|
38
|
+
}
|
|
39
|
+
return unmarshaller(await response.text());
|
|
40
|
+
} catch (err) {
|
|
41
|
+
throw new scwError.ScalewayError(
|
|
42
|
+
response.status,
|
|
43
|
+
`could not parse '${contentType ?? ""}' response${err instanceof Error ? `: ${err.message}` : ""}`
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const error = await response.clone().json().catch(() => response.text());
|
|
48
|
+
if (json.isJSONObject(error)) throw errorParser.parseScalewayError(response.status, error);
|
|
49
|
+
throw new scwError.ScalewayError(
|
|
50
|
+
response.status,
|
|
51
|
+
typeof error === "string" ? error : "cannot read error response body"
|
|
52
|
+
);
|
|
53
|
+
};
|
|
54
|
+
exports.fixLegacyTotalCount = fixLegacyTotalCount;
|
|
55
|
+
exports.responseParser = responseParser;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ResponseUnmarshaller } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Fixes the totalCount property for old APIs.
|
|
4
|
+
*
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
7
|
+
export declare const fixLegacyTotalCount: <T>(obj: T, headers: Headers) => T;
|
|
8
|
+
/**
|
|
9
|
+
* Makes response parser.
|
|
10
|
+
*
|
|
11
|
+
* @param unmarshaller - The response payload unmarshaller
|
|
12
|
+
* @returns An async converter of HTTP Response to desired result
|
|
13
|
+
*
|
|
14
|
+
* @throws {@link ScalewayError}
|
|
15
|
+
* Thrown by the API if the request couldn't be completed.
|
|
16
|
+
*
|
|
17
|
+
* @throws TypeError
|
|
18
|
+
* Thrown if the response parameter isn't of the expected type.
|
|
19
|
+
*
|
|
20
|
+
* @throws Error
|
|
21
|
+
* JSON parsing could trigger an error.
|
|
22
|
+
*
|
|
23
|
+
* @internal
|
|
24
|
+
*/
|
|
25
|
+
export declare const responseParser: <T>(unmarshaller: ResponseUnmarshaller<T>, responseType: "json" | "text" | "blob") => (response: Response) => Promise<T>;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { isResponse } from "../../helpers/is-response.js";
|
|
2
|
+
import { isJSONObject } from "../../helpers/json.js";
|
|
3
|
+
import { parseScalewayError } from "../errors/error-parser.js";
|
|
4
|
+
import { ScalewayError } from "../errors/scw-error.js";
|
|
5
|
+
const X_TOTAL_COUNT_HEADER_KEY = "x-total-count";
|
|
6
|
+
const TOTAL_COUNT_RES_KEY = "total_count";
|
|
7
|
+
const fixLegacyTotalCount = (obj, headers) => {
|
|
8
|
+
const headerVal = headers.get(X_TOTAL_COUNT_HEADER_KEY);
|
|
9
|
+
if (!headerVal) {
|
|
10
|
+
return obj;
|
|
11
|
+
}
|
|
12
|
+
const totalCount = parseInt(headerVal, 10);
|
|
13
|
+
if (Number.isNaN(totalCount)) {
|
|
14
|
+
return obj;
|
|
15
|
+
}
|
|
16
|
+
if (isJSONObject(obj) && !(TOTAL_COUNT_RES_KEY in obj)) {
|
|
17
|
+
return Object.assign(obj, { [TOTAL_COUNT_RES_KEY]: totalCount });
|
|
18
|
+
}
|
|
19
|
+
return obj;
|
|
20
|
+
};
|
|
21
|
+
const responseParser = (unmarshaller, responseType) => async (response) => {
|
|
22
|
+
if (!isResponse(response)) {
|
|
23
|
+
throw new TypeError("Invalid response object");
|
|
24
|
+
}
|
|
25
|
+
if (response.ok) {
|
|
26
|
+
if (response.status === 204) return unmarshaller(void 0);
|
|
27
|
+
const contentType = response.headers.get("Content-Type");
|
|
28
|
+
try {
|
|
29
|
+
if (responseType === "json" && contentType === "application/json") {
|
|
30
|
+
return unmarshaller(
|
|
31
|
+
fixLegacyTotalCount(await response.json(), response.headers)
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
if (responseType === "blob") {
|
|
35
|
+
return unmarshaller(await response.blob());
|
|
36
|
+
}
|
|
37
|
+
return unmarshaller(await response.text());
|
|
38
|
+
} catch (err) {
|
|
39
|
+
throw new ScalewayError(
|
|
40
|
+
response.status,
|
|
41
|
+
`could not parse '${contentType ?? ""}' response${err instanceof Error ? `: ${err.message}` : ""}`
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
const error = await response.clone().json().catch(() => response.text());
|
|
46
|
+
if (isJSONObject(error)) throw parseScalewayError(response.status, error);
|
|
47
|
+
throw new ScalewayError(
|
|
48
|
+
response.status,
|
|
49
|
+
typeof error === "string" ? error : "cannot read error response body"
|
|
50
|
+
);
|
|
51
|
+
};
|
|
52
|
+
export {
|
|
53
|
+
fixLegacyTotalCount,
|
|
54
|
+
responseParser
|
|
55
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** Scaleway Request. */
|
|
2
|
+
export interface ScwRequest {
|
|
3
|
+
method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
|
|
4
|
+
path: string;
|
|
5
|
+
headers?: Record<string, string>;
|
|
6
|
+
body?: string;
|
|
7
|
+
urlParams?: URLSearchParams;
|
|
8
|
+
responseType?: 'json' | 'text' | 'blob';
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* A factory to unmarshal a response.
|
|
12
|
+
*
|
|
13
|
+
* @param obj - The input object.
|
|
14
|
+
* @returns The output object
|
|
15
|
+
*/
|
|
16
|
+
export type ResponseUnmarshaller<T> = (obj: unknown) => T;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
var lookup = [];
|
|
4
|
+
var code = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
5
|
+
for (var i = 0, len = code.length; i < len; ++i) {
|
|
6
|
+
lookup[i] = code[i];
|
|
7
|
+
}
|
|
8
|
+
function tripletToBase64(num) {
|
|
9
|
+
return lookup[num >> 18 & 63] + lookup[num >> 12 & 63] + lookup[num >> 6 & 63] + lookup[num & 63];
|
|
10
|
+
}
|
|
11
|
+
function encodeChunk(uint8, start, end) {
|
|
12
|
+
var tmp;
|
|
13
|
+
var output = [];
|
|
14
|
+
for (var i = start; i < end; i += 3) {
|
|
15
|
+
tmp = (uint8[i] << 16 & 16711680) + (uint8[i + 1] << 8 & 65280) + (uint8[i + 2] & 255);
|
|
16
|
+
output.push(tripletToBase64(tmp));
|
|
17
|
+
}
|
|
18
|
+
return output.join("");
|
|
19
|
+
}
|
|
20
|
+
function fromByteArray(uint8) {
|
|
21
|
+
var tmp;
|
|
22
|
+
var len = uint8.length;
|
|
23
|
+
var extraBytes = len % 3;
|
|
24
|
+
var parts = [];
|
|
25
|
+
var maxChunkLength = 16383;
|
|
26
|
+
for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
|
|
27
|
+
parts.push(
|
|
28
|
+
encodeChunk(
|
|
29
|
+
uint8,
|
|
30
|
+
i,
|
|
31
|
+
i + maxChunkLength > len2 ? len2 : i + maxChunkLength
|
|
32
|
+
)
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
if (extraBytes === 1) {
|
|
36
|
+
tmp = uint8[len - 1];
|
|
37
|
+
parts.push(lookup[tmp >> 2] + lookup[tmp << 4 & 63] + "==");
|
|
38
|
+
} else if (extraBytes === 2) {
|
|
39
|
+
tmp = (uint8[len - 2] << 8) + uint8[len - 1];
|
|
40
|
+
parts.push(
|
|
41
|
+
lookup[tmp >> 10] + lookup[tmp >> 4 & 63] + lookup[tmp << 2 & 63] + "="
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
return parts.join("");
|
|
45
|
+
}
|
|
46
|
+
exports.fromByteArray = fromByteArray;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
var lookup = [];
|
|
2
|
+
var code = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
3
|
+
for (var i = 0, len = code.length; i < len; ++i) {
|
|
4
|
+
lookup[i] = code[i];
|
|
5
|
+
}
|
|
6
|
+
function tripletToBase64(num) {
|
|
7
|
+
return lookup[num >> 18 & 63] + lookup[num >> 12 & 63] + lookup[num >> 6 & 63] + lookup[num & 63];
|
|
8
|
+
}
|
|
9
|
+
function encodeChunk(uint8, start, end) {
|
|
10
|
+
var tmp;
|
|
11
|
+
var output = [];
|
|
12
|
+
for (var i = start; i < end; i += 3) {
|
|
13
|
+
tmp = (uint8[i] << 16 & 16711680) + (uint8[i + 1] << 8 & 65280) + (uint8[i + 2] & 255);
|
|
14
|
+
output.push(tripletToBase64(tmp));
|
|
15
|
+
}
|
|
16
|
+
return output.join("");
|
|
17
|
+
}
|
|
18
|
+
function fromByteArray(uint8) {
|
|
19
|
+
var tmp;
|
|
20
|
+
var len = uint8.length;
|
|
21
|
+
var extraBytes = len % 3;
|
|
22
|
+
var parts = [];
|
|
23
|
+
var maxChunkLength = 16383;
|
|
24
|
+
for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
|
|
25
|
+
parts.push(
|
|
26
|
+
encodeChunk(
|
|
27
|
+
uint8,
|
|
28
|
+
i,
|
|
29
|
+
i + maxChunkLength > len2 ? len2 : i + maxChunkLength
|
|
30
|
+
)
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
if (extraBytes === 1) {
|
|
34
|
+
tmp = uint8[len - 1];
|
|
35
|
+
parts.push(lookup[tmp >> 2] + lookup[tmp << 4 & 63] + "==");
|
|
36
|
+
} else if (extraBytes === 2) {
|
|
37
|
+
tmp = (uint8[len - 2] << 8) + uint8[len - 1];
|
|
38
|
+
parts.push(
|
|
39
|
+
lookup[tmp >> 10] + lookup[tmp >> 4 & 63] + lookup[tmp << 2 & 63] + "="
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
return parts.join("");
|
|
43
|
+
}
|
|
44
|
+
export {
|
|
45
|
+
fromByteArray
|
|
46
|
+
};
|