88 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			88 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|  | import { getName, makeFile, isAsyncIterable } from "./uploads.mjs"; | ||
|  | import { checkFileSupport } from "./uploads.mjs"; | ||
|  | /** | ||
|  |  * This check adds the arrayBuffer() method type because it is available and used at runtime | ||
|  |  */ | ||
|  | const isBlobLike = (value) => value != null && | ||
|  |     typeof value === 'object' && | ||
|  |     typeof value.size === 'number' && | ||
|  |     typeof value.type === 'string' && | ||
|  |     typeof value.text === 'function' && | ||
|  |     typeof value.slice === 'function' && | ||
|  |     typeof value.arrayBuffer === 'function'; | ||
|  | /** | ||
|  |  * This check adds the arrayBuffer() method type because it is available and used at runtime | ||
|  |  */ | ||
|  | const isFileLike = (value) => value != null && | ||
|  |     typeof value === 'object' && | ||
|  |     typeof value.name === 'string' && | ||
|  |     typeof value.lastModified === 'number' && | ||
|  |     isBlobLike(value); | ||
|  | const isResponseLike = (value) => value != null && | ||
|  |     typeof value === 'object' && | ||
|  |     typeof value.url === 'string' && | ||
|  |     typeof value.blob === 'function'; | ||
|  | /** | ||
|  |  * Helper for creating a {@link File} to pass to an SDK upload method from a variety of different data formats | ||
|  |  * @param value the raw content of the file.  Can be an {@link Uploadable}, {@link BlobLikePart}, or {@link AsyncIterable} of {@link BlobLikePart}s | ||
|  |  * @param {string=} name the name of the file. If omitted, toFile will try to determine a file name from bits if possible | ||
|  |  * @param {Object=} options additional properties | ||
|  |  * @param {string=} options.type the MIME type of the content | ||
|  |  * @param {number=} options.lastModified the last modified timestamp | ||
|  |  * @returns a {@link File} with the given properties | ||
|  |  */ | ||
|  | export async function toFile(value, name, options) { | ||
|  |     checkFileSupport(); | ||
|  |     // If it's a promise, resolve it.
 | ||
|  |     value = await value; | ||
|  |     // If we've been given a `File` we don't need to do anything
 | ||
|  |     if (isFileLike(value)) { | ||
|  |         if (value instanceof File) { | ||
|  |             return value; | ||
|  |         } | ||
|  |         return makeFile([await value.arrayBuffer()], value.name); | ||
|  |     } | ||
|  |     if (isResponseLike(value)) { | ||
|  |         const blob = await value.blob(); | ||
|  |         name || (name = new URL(value.url).pathname.split(/[\\/]/).pop()); | ||
|  |         return makeFile(await getBytes(blob), name, options); | ||
|  |     } | ||
|  |     const parts = await getBytes(value); | ||
|  |     name || (name = getName(value)); | ||
|  |     if (!options?.type) { | ||
|  |         const type = parts.find((part) => typeof part === 'object' && 'type' in part && part.type); | ||
|  |         if (typeof type === 'string') { | ||
|  |             options = { ...options, type }; | ||
|  |         } | ||
|  |     } | ||
|  |     return makeFile(parts, name, options); | ||
|  | } | ||
|  | async function getBytes(value) { | ||
|  |     let parts = []; | ||
|  |     if (typeof value === 'string' || | ||
|  |         ArrayBuffer.isView(value) || // includes Uint8Array, Buffer, etc.
 | ||
|  |         value instanceof ArrayBuffer) { | ||
|  |         parts.push(value); | ||
|  |     } | ||
|  |     else if (isBlobLike(value)) { | ||
|  |         parts.push(value instanceof Blob ? value : await value.arrayBuffer()); | ||
|  |     } | ||
|  |     else if (isAsyncIterable(value) // includes Readable, ReadableStream, etc.
 | ||
|  |     ) { | ||
|  |         for await (const chunk of value) { | ||
|  |             parts.push(...(await getBytes(chunk))); // TODO, consider validating?
 | ||
|  |         } | ||
|  |     } | ||
|  |     else { | ||
|  |         const constructor = value?.constructor?.name; | ||
|  |         throw new Error(`Unexpected data type: ${typeof value}${constructor ? `; constructor: ${constructor}` : ''}${propsForError(value)}`); | ||
|  |     } | ||
|  |     return parts; | ||
|  | } | ||
|  | function propsForError(value) { | ||
|  |     if (typeof value !== 'object' || value === null) | ||
|  |         return ''; | ||
|  |     const props = Object.getOwnPropertyNames(value); | ||
|  |     return `; props: [${props.map((p) => `"${p}"`).join(', ')}]`; | ||
|  | } | ||
|  | //# sourceMappingURL=to-file.mjs.map
 |