Initial
This commit is contained in:
118
resources/app/node_modules/@smithy/fetch-http-handler/dist-es/fetch-http-handler.js
generated
vendored
Normal file
118
resources/app/node_modules/@smithy/fetch-http-handler/dist-es/fetch-http-handler.js
generated
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
import { HttpResponse } from "@smithy/protocol-http";
|
||||
import { buildQueryString } from "@smithy/querystring-builder";
|
||||
import { requestTimeout } from "./request-timeout";
|
||||
export const keepAliveSupport = {
|
||||
supported: Boolean(typeof Request !== "undefined" && "keepalive" in new Request("https://[::1]")),
|
||||
};
|
||||
export class FetchHttpHandler {
|
||||
static create(instanceOrOptions) {
|
||||
if (typeof instanceOrOptions?.handle === "function") {
|
||||
return instanceOrOptions;
|
||||
}
|
||||
return new FetchHttpHandler(instanceOrOptions);
|
||||
}
|
||||
constructor(options) {
|
||||
if (typeof options === "function") {
|
||||
this.configProvider = options().then((opts) => opts || {});
|
||||
}
|
||||
else {
|
||||
this.config = options ?? {};
|
||||
this.configProvider = Promise.resolve(this.config);
|
||||
}
|
||||
}
|
||||
destroy() {
|
||||
}
|
||||
async handle(request, { abortSignal } = {}) {
|
||||
if (!this.config) {
|
||||
this.config = await this.configProvider;
|
||||
}
|
||||
const requestTimeoutInMs = this.config.requestTimeout;
|
||||
const keepAlive = this.config.keepAlive === true;
|
||||
if (abortSignal?.aborted) {
|
||||
const abortError = new Error("Request aborted");
|
||||
abortError.name = "AbortError";
|
||||
return Promise.reject(abortError);
|
||||
}
|
||||
let path = request.path;
|
||||
const queryString = buildQueryString(request.query || {});
|
||||
if (queryString) {
|
||||
path += `?${queryString}`;
|
||||
}
|
||||
if (request.fragment) {
|
||||
path += `#${request.fragment}`;
|
||||
}
|
||||
let auth = "";
|
||||
if (request.username != null || request.password != null) {
|
||||
const username = request.username ?? "";
|
||||
const password = request.password ?? "";
|
||||
auth = `${username}:${password}@`;
|
||||
}
|
||||
const { port, method } = request;
|
||||
const url = `${request.protocol}//${auth}${request.hostname}${port ? `:${port}` : ""}${path}`;
|
||||
const body = method === "GET" || method === "HEAD" ? undefined : request.body;
|
||||
const requestOptions = {
|
||||
body,
|
||||
headers: new Headers(request.headers),
|
||||
method: method,
|
||||
};
|
||||
if (body) {
|
||||
requestOptions.duplex = "half";
|
||||
}
|
||||
if (typeof AbortController !== "undefined") {
|
||||
requestOptions.signal = abortSignal;
|
||||
}
|
||||
if (keepAliveSupport.supported) {
|
||||
requestOptions.keepalive = keepAlive;
|
||||
}
|
||||
const fetchRequest = new Request(url, requestOptions);
|
||||
const raceOfPromises = [
|
||||
fetch(fetchRequest).then((response) => {
|
||||
const fetchHeaders = response.headers;
|
||||
const transformedHeaders = {};
|
||||
for (const pair of fetchHeaders.entries()) {
|
||||
transformedHeaders[pair[0]] = pair[1];
|
||||
}
|
||||
const hasReadableStream = response.body != undefined;
|
||||
if (!hasReadableStream) {
|
||||
return response.blob().then((body) => ({
|
||||
response: new HttpResponse({
|
||||
headers: transformedHeaders,
|
||||
reason: response.statusText,
|
||||
statusCode: response.status,
|
||||
body,
|
||||
}),
|
||||
}));
|
||||
}
|
||||
return {
|
||||
response: new HttpResponse({
|
||||
headers: transformedHeaders,
|
||||
reason: response.statusText,
|
||||
statusCode: response.status,
|
||||
body: response.body,
|
||||
}),
|
||||
};
|
||||
}),
|
||||
requestTimeout(requestTimeoutInMs),
|
||||
];
|
||||
if (abortSignal) {
|
||||
raceOfPromises.push(new Promise((resolve, reject) => {
|
||||
abortSignal.onabort = () => {
|
||||
const abortError = new Error("Request aborted");
|
||||
abortError.name = "AbortError";
|
||||
reject(abortError);
|
||||
};
|
||||
}));
|
||||
}
|
||||
return Promise.race(raceOfPromises);
|
||||
}
|
||||
updateHttpClientConfig(key, value) {
|
||||
this.config = undefined;
|
||||
this.configProvider = this.configProvider.then((config) => {
|
||||
config[key] = value;
|
||||
return config;
|
||||
});
|
||||
}
|
||||
httpHandlerConfigs() {
|
||||
return this.config ?? {};
|
||||
}
|
||||
}
|
||||
2
resources/app/node_modules/@smithy/fetch-http-handler/dist-es/index.js
generated
vendored
Normal file
2
resources/app/node_modules/@smithy/fetch-http-handler/dist-es/index.js
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from "./fetch-http-handler";
|
||||
export * from "./stream-collector";
|
||||
11
resources/app/node_modules/@smithy/fetch-http-handler/dist-es/request-timeout.js
generated
vendored
Normal file
11
resources/app/node_modules/@smithy/fetch-http-handler/dist-es/request-timeout.js
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
export function requestTimeout(timeoutInMs = 0) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (timeoutInMs) {
|
||||
setTimeout(() => {
|
||||
const timeoutError = new Error(`Request did not complete within ${timeoutInMs} ms`);
|
||||
timeoutError.name = "TimeoutError";
|
||||
reject(timeoutError);
|
||||
}, timeoutInMs);
|
||||
}
|
||||
});
|
||||
}
|
||||
50
resources/app/node_modules/@smithy/fetch-http-handler/dist-es/stream-collector.js
generated
vendored
Normal file
50
resources/app/node_modules/@smithy/fetch-http-handler/dist-es/stream-collector.js
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
import { fromBase64 } from "@smithy/util-base64";
|
||||
export const streamCollector = (stream) => {
|
||||
if (typeof Blob === "function" && stream instanceof Blob) {
|
||||
return collectBlob(stream);
|
||||
}
|
||||
return collectStream(stream);
|
||||
};
|
||||
async function collectBlob(blob) {
|
||||
const base64 = await readToBase64(blob);
|
||||
const arrayBuffer = fromBase64(base64);
|
||||
return new Uint8Array(arrayBuffer);
|
||||
}
|
||||
async function collectStream(stream) {
|
||||
const chunks = [];
|
||||
const reader = stream.getReader();
|
||||
let isDone = false;
|
||||
let length = 0;
|
||||
while (!isDone) {
|
||||
const { done, value } = await reader.read();
|
||||
if (value) {
|
||||
chunks.push(value);
|
||||
length += value.length;
|
||||
}
|
||||
isDone = done;
|
||||
}
|
||||
const collected = new Uint8Array(length);
|
||||
let offset = 0;
|
||||
for (const chunk of chunks) {
|
||||
collected.set(chunk, offset);
|
||||
offset += chunk.length;
|
||||
}
|
||||
return collected;
|
||||
}
|
||||
function readToBase64(blob) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
reader.onloadend = () => {
|
||||
if (reader.readyState !== 2) {
|
||||
return reject(new Error("Reader aborted too early"));
|
||||
}
|
||||
const result = (reader.result ?? "");
|
||||
const commaIndex = result.indexOf(",");
|
||||
const dataOffset = commaIndex > -1 ? commaIndex + 1 : result.length;
|
||||
resolve(result.substring(dataOffset));
|
||||
};
|
||||
reader.onabort = () => reject(new Error("Read aborted"));
|
||||
reader.onerror = () => reject(reader.error);
|
||||
reader.readAsDataURL(blob);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user