"use strict"; // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. Object.defineProperty(exports, "__esModule", { value: true }); exports.hasRawContent = hasRawContent; exports.getRawContent = getRawContent; exports.createFileFromStream = createFileFromStream; exports.createFile = createFile; const core_util_1 = require("@azure/core-util"); function isNodeReadableStream(x) { return Boolean(x && typeof x["pipe"] === "function"); } const unimplementedMethods = { arrayBuffer: () => { throw new Error("Not implemented"); }, bytes: () => { throw new Error("Not implemented"); }, slice: () => { throw new Error("Not implemented"); }, text: () => { throw new Error("Not implemented"); }, }; /** * Private symbol used as key on objects created using createFile containing the * original source of the file object. * * This is used in Node to access the original Node stream without using Blob#stream, which * returns a web stream. This is done to avoid a couple of bugs to do with Blob#stream and * Readable#to/fromWeb in Node versions we support: * - https://github.com/nodejs/node/issues/42694 (fixed in Node 18.14) * - https://github.com/nodejs/node/issues/48916 (fixed in Node 20.6) * * Once these versions are no longer supported, we may be able to stop doing this. * * @internal */ const rawContent = Symbol("rawContent"); /** * Type guard to check if a given object is a blob-like object with a raw content property. */ function hasRawContent(x) { return typeof x[rawContent] === "function"; } /** * Extract the raw content from a given blob-like object. If the input was created using createFile * or createFileFromStream, the exact content passed into createFile/createFileFromStream will be used. * For true instances of Blob and File, returns the actual blob. * * @internal */ function getRawContent(blob) { if (hasRawContent(blob)) { return blob[rawContent](); } else { return blob; } } /** * Create an object that implements the File interface. This object is intended to be * passed into RequestBodyType.formData, and is not guaranteed to work as expected in * other situations. * * Use this function to: * - Create a File object for use in RequestBodyType.formData in environments where the * global File object is unavailable. * - Create a File-like object from a readable stream without reading the stream into memory. * * @param stream - the content of the file as a callback returning a stream. When a File object made using createFile is * passed in a request's form data map, the stream will not be read into memory * and instead will be streamed when the request is made. In the event of a retry, the * stream needs to be read again, so this callback SHOULD return a fresh stream if possible. * @param name - the name of the file. * @param options - optional metadata about the file, e.g. file name, file size, MIME type. */ function createFileFromStream(stream, name, options = {}) { return { ...unimplementedMethods, type: options.type ?? "", lastModified: options.lastModified ?? new Date().getTime(), webkitRelativePath: options.webkitRelativePath ?? "", size: options.size ?? -1, name, stream: () => { const s = stream(); if (isNodeReadableStream(s)) { throw new Error("Not supported: a Node stream was provided as input to createFileFromStream."); } return s; }, [rawContent]: stream, }; } /** * Create an object that implements the File interface. This object is intended to be * passed into RequestBodyType.formData, and is not guaranteed to work as expected in * other situations. * * Use this function create a File object for use in RequestBodyType.formData in environments where the global File object is unavailable. * * @param content - the content of the file as a Uint8Array in memory. * @param name - the name of the file. * @param options - optional metadata about the file, e.g. file name, file size, MIME type. */ function createFile(content, name, options = {}) { if (core_util_1.isNodeLike) { return { ...unimplementedMethods, type: options.type ?? "", lastModified: options.lastModified ?? new Date().getTime(), webkitRelativePath: options.webkitRelativePath ?? "", size: content.byteLength, name, arrayBuffer: async () => content.buffer, stream: () => new Blob([toArrayBuffer(content)]).stream(), [rawContent]: () => content, }; } else { return new File([toArrayBuffer(content)], name, options); } } function toArrayBuffer(source) { if ("resize" in source.buffer) { // ArrayBuffer return source; } // SharedArrayBuffer return source.map((x) => x); } //# sourceMappingURL=file.js.map