64 lines
2.8 KiB
JavaScript
64 lines
2.8 KiB
JavaScript
import { streamCollector } from "@smithy/fetch-http-handler";
|
|
import { toBase64 } from "@smithy/util-base64";
|
|
import { toHex } from "@smithy/util-hex-encoding";
|
|
import { toUtf8 } from "@smithy/util-utf8";
|
|
const ERR_MSG_STREAM_HAS_BEEN_TRANSFORMED = "The stream has already been transformed.";
|
|
export const sdkStreamMixin = (stream) => {
|
|
if (!isBlobInstance(stream) && !isReadableStreamInstance(stream)) {
|
|
const name = stream?.__proto__?.constructor?.name || stream;
|
|
throw new Error(`Unexpected stream implementation, expect Blob or ReadableStream, got ${name}`);
|
|
}
|
|
let transformed = false;
|
|
const transformToByteArray = async () => {
|
|
if (transformed) {
|
|
throw new Error(ERR_MSG_STREAM_HAS_BEEN_TRANSFORMED);
|
|
}
|
|
transformed = true;
|
|
return await streamCollector(stream);
|
|
};
|
|
const blobToWebStream = (blob) => {
|
|
if (typeof blob.stream !== "function") {
|
|
throw new Error("Cannot transform payload Blob to web stream. Please make sure the Blob.stream() is polyfilled.\n" +
|
|
"If you are using React Native, this API is not yet supported, see: https://react-native.canny.io/feature-requests/p/fetch-streaming-body");
|
|
}
|
|
return blob.stream();
|
|
};
|
|
return Object.assign(stream, {
|
|
transformToByteArray: transformToByteArray,
|
|
transformToString: async (encoding) => {
|
|
const buf = await transformToByteArray();
|
|
if (encoding === "base64") {
|
|
return toBase64(buf);
|
|
}
|
|
else if (encoding === "hex") {
|
|
return toHex(buf);
|
|
}
|
|
else if (encoding === undefined || encoding === "utf8" || encoding === "utf-8") {
|
|
return toUtf8(buf);
|
|
}
|
|
else if (typeof TextDecoder === "function") {
|
|
return new TextDecoder(encoding).decode(buf);
|
|
}
|
|
else {
|
|
throw new Error("TextDecoder is not available, please make sure polyfill is provided.");
|
|
}
|
|
},
|
|
transformToWebStream: () => {
|
|
if (transformed) {
|
|
throw new Error(ERR_MSG_STREAM_HAS_BEEN_TRANSFORMED);
|
|
}
|
|
transformed = true;
|
|
if (isBlobInstance(stream)) {
|
|
return blobToWebStream(stream);
|
|
}
|
|
else if (isReadableStreamInstance(stream)) {
|
|
return stream;
|
|
}
|
|
else {
|
|
throw new Error(`Cannot transform payload to web stream, got ${stream}`);
|
|
}
|
|
},
|
|
});
|
|
};
|
|
const isBlobInstance = (stream) => typeof Blob === "function" && stream instanceof Blob;
|
|
const isReadableStreamInstance = (stream) => typeof ReadableStream === "function" && stream instanceof ReadableStream;
|