UNPKG

@tldraw/utils

Version:

tldraw infinite canvas SDK (private utilities).

8 lines (7 loc) 8.74 kB
{ "version": 3, "sources": ["../../src/lib/file.ts"], "sourcesContent": ["import { fetch } from './network'\n\n/**\n * Utility class providing helper methods for file and blob operations.\n *\n * FileHelpers contains static methods for common file operations including\n * URL fetching, format conversion, and MIME type manipulation. All methods work with\n * web APIs like fetch, FileReader, and Blob/File objects.\n *\n * @example\n * ```ts\n * // Fetch and convert a remote image to data URL\n * const dataUrl = await FileHelpers.urlToDataUrl('https://example.com/image.png')\n *\n * // Convert user-selected file to text\n * const text = await FileHelpers.blobToText(userFile)\n *\n * // Change file MIME type\n * const newFile = FileHelpers.rewriteMimeType(originalFile, 'application/json')\n * ```\n *\n * @public\n */\nexport class FileHelpers {\n\t/**\n\t * Converts a URL to an ArrayBuffer by fetching the resource.\n\t *\n\t * Fetches the resource at the given URL and returns its content as an ArrayBuffer.\n\t * This is useful for loading binary data like images, videos, or other file types.\n\t *\n\t * @param url - The URL of the file to fetch\n\t * @returns Promise that resolves to the file content as an ArrayBuffer\n\t * @example\n\t * ```ts\n\t * const buffer = await FileHelpers.urlToArrayBuffer('https://example.com/image.png')\n\t * console.log(buffer.byteLength) // Size of the file in bytes\n\t * ```\n\t * @public\n\t */\n\tstatic async urlToArrayBuffer(url: string) {\n\t\tconst response = await fetch(url)\n\t\treturn await response.arrayBuffer()\n\t}\n\n\t/**\n\t * Converts a URL to a Blob by fetching the resource.\n\t *\n\t * Fetches the resource at the given URL and returns its content as a Blob object.\n\t * Blobs are useful for handling file data in web applications.\n\t *\n\t * @param url - The URL of the file to fetch\n\t * @returns Promise that resolves to the file content as a Blob\n\t * @example\n\t * ```ts\n\t * const blob = await FileHelpers.urlToBlob('https://example.com/document.pdf')\n\t * console.log(blob.type) // 'application/pdf'\n\t * console.log(blob.size) // Size in bytes\n\t * ```\n\t * @public\n\t */\n\tstatic async urlToBlob(url: string) {\n\t\tconst response = await fetch(url)\n\t\treturn await response.blob()\n\t}\n\n\t/**\n\t * Converts a URL to a data URL by fetching the resource.\n\t *\n\t * Fetches the resource at the given URL and converts it to a base64-encoded data URL.\n\t * If the URL is already a data URL, it returns the URL unchanged. This is useful for embedding\n\t * resources directly in HTML or CSS.\n\t *\n\t * @param url - The URL of the file to convert, or an existing data URL\n\t * @returns Promise that resolves to a data URL string\n\t * @example\n\t * ```ts\n\t * const dataUrl = await FileHelpers.urlToDataUrl('https://example.com/image.jpg')\n\t * // Returns: 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEA...'\n\t *\n\t * const existing = await FileHelpers.urlToDataUrl('data:text/plain;base64,SGVsbG8=')\n\t * // Returns the same data URL unchanged\n\t * ```\n\t * @public\n\t */\n\tstatic async urlToDataUrl(url: string) {\n\t\tif (url.startsWith('data:')) return url\n\t\tconst blob = await FileHelpers.urlToBlob(url)\n\t\treturn await FileHelpers.blobToDataUrl(blob)\n\t}\n\n\t/**\n\t * Convert a Blob to a base64 encoded data URL.\n\t *\n\t * Converts a Blob object to a base64-encoded data URL using the FileReader API.\n\t * This is useful for displaying images or embedding file content directly in HTML.\n\t *\n\t * @param file - The Blob object to convert\n\t * @returns Promise that resolves to a base64-encoded data URL string\n\t * @example\n\t * ```ts\n\t * const blob = new Blob(['Hello World'], { type: 'text/plain' })\n\t * const dataUrl = await FileHelpers.blobToDataUrl(blob)\n\t * // Returns: 'data:text/plain;base64,SGVsbG8gV29ybGQ='\n\t *\n\t * // With an image file\n\t * const imageDataUrl = await FileHelpers.blobToDataUrl(myImageFile)\n\t * // Can be used directly in img src attribute\n\t * ```\n\t * @public\n\t */\n\tstatic async blobToDataUrl(file: Blob): Promise<string> {\n\t\treturn await new Promise((resolve, reject) => {\n\t\t\tif (file) {\n\t\t\t\tconst reader = new FileReader()\n\t\t\t\treader.onload = () => resolve(reader.result as string)\n\t\t\t\treader.onerror = (error) => reject(error)\n\t\t\t\treader.onabort = (error) => reject(error)\n\t\t\t\treader.readAsDataURL(file)\n\t\t\t}\n\t\t})\n\t}\n\n\t/**\n\t * Convert a Blob to a unicode text string.\n\t *\n\t * Reads the content of a Blob object as a UTF-8 text string using the FileReader API.\n\t * This is useful for reading text files or extracting text content from blobs.\n\t *\n\t * @param file - The Blob object to convert to text\n\t * @returns Promise that resolves to the text content as a string\n\t * @example\n\t * ```ts\n\t * const textBlob = new Blob(['Hello World'], { type: 'text/plain' })\n\t * const text = await FileHelpers.blobToText(textBlob)\n\t * console.log(text) // 'Hello World'\n\t *\n\t * // With a text file from user input\n\t * const content = await FileHelpers.blobToText(myTextFile)\n\t * console.log(content) // File content as string\n\t * ```\n\t * @public\n\t */\n\tstatic async blobToText(file: Blob): Promise<string> {\n\t\treturn await new Promise((resolve, reject) => {\n\t\t\tif (file) {\n\t\t\t\tconst reader = new FileReader()\n\t\t\t\treader.onload = () => resolve(reader.result as string)\n\t\t\t\treader.onerror = (error) => reject(error)\n\t\t\t\treader.onabort = (error) => reject(error)\n\t\t\t\treader.readAsText(file)\n\t\t\t}\n\t\t})\n\t}\n\n\t/**\n\t * Creates a new Blob or File with a different MIME type.\n\t *\n\t * Creates a copy of the given Blob or File with a new MIME type while preserving\n\t * all other properties. If the current MIME type already matches the new one, returns the\n\t * original object unchanged. For File objects, preserves the filename.\n\t *\n\t * @param blob - The Blob or File object to modify\n\t * @param newMimeType - The new MIME type to assign\n\t * @returns A new Blob or File with the updated MIME type\n\t * @example\n\t * ```ts\n\t * // Change a generic blob to a specific image type\n\t * const blob = new Blob([imageData])\n\t * const imageBlob = FileHelpers.rewriteMimeType(blob, 'image/png')\n\t *\n\t * // Change a file's MIME type while preserving filename\n\t * const file = new File([data], 'document.txt', { type: 'text/plain' })\n\t * const jsonFile = FileHelpers.rewriteMimeType(file, 'application/json')\n\t * console.log(jsonFile.name) // 'document.txt' (preserved)\n\t * console.log(jsonFile.type) // 'application/json' (updated)\n\t * ```\n\t * @public\n\t */\n\tstatic rewriteMimeType(blob: Blob, newMimeType: string): Blob\n\tstatic rewriteMimeType(blob: File, newMimeType: string): File\n\tstatic rewriteMimeType(blob: Blob | File, newMimeType: string): Blob | File {\n\t\tif (blob.type === newMimeType) return blob\n\t\tif (blob instanceof File) {\n\t\t\treturn new File([blob], blob.name, { type: newMimeType })\n\t\t}\n\t\treturn new Blob([blob], { type: newMimeType })\n\t}\n}\n"], "mappings": "AAAA,SAAS,aAAa;AAuBf,MAAM,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBxB,aAAa,iBAAiB,KAAa;AAC1C,UAAM,WAAW,MAAM,MAAM,GAAG;AAChC,WAAO,MAAM,SAAS,YAAY;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,aAAa,UAAU,KAAa;AACnC,UAAM,WAAW,MAAM,MAAM,GAAG;AAChC,WAAO,MAAM,SAAS,KAAK;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBA,aAAa,aAAa,KAAa;AACtC,QAAI,IAAI,WAAW,OAAO,EAAG,QAAO;AACpC,UAAM,OAAO,MAAM,YAAY,UAAU,GAAG;AAC5C,WAAO,MAAM,YAAY,cAAc,IAAI;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAsBA,aAAa,cAAc,MAA6B;AACvD,WAAO,MAAM,IAAI,QAAQ,CAAC,SAAS,WAAW;AAC7C,UAAI,MAAM;AACT,cAAM,SAAS,IAAI,WAAW;AAC9B,eAAO,SAAS,MAAM,QAAQ,OAAO,MAAgB;AACrD,eAAO,UAAU,CAAC,UAAU,OAAO,KAAK;AACxC,eAAO,UAAU,CAAC,UAAU,OAAO,KAAK;AACxC,eAAO,cAAc,IAAI;AAAA,MAC1B;AAAA,IACD,CAAC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAsBA,aAAa,WAAW,MAA6B;AACpD,WAAO,MAAM,IAAI,QAAQ,CAAC,SAAS,WAAW;AAC7C,UAAI,MAAM;AACT,cAAM,SAAS,IAAI,WAAW;AAC9B,eAAO,SAAS,MAAM,QAAQ,OAAO,MAAgB;AACrD,eAAO,UAAU,CAAC,UAAU,OAAO,KAAK;AACxC,eAAO,UAAU,CAAC,UAAU,OAAO,KAAK;AACxC,eAAO,WAAW,IAAI;AAAA,MACvB;AAAA,IACD,CAAC;AAAA,EACF;AAAA,EA4BA,OAAO,gBAAgB,MAAmB,aAAkC;AAC3E,QAAI,KAAK,SAAS,YAAa,QAAO;AACtC,QAAI,gBAAgB,MAAM;AACzB,aAAO,IAAI,KAAK,CAAC,IAAI,GAAG,KAAK,MAAM,EAAE,MAAM,YAAY,CAAC;AAAA,IACzD;AACA,WAAO,IAAI,KAAK,CAAC,IAAI,GAAG,EAAE,MAAM,YAAY,CAAC;AAAA,EAC9C;AACD;", "names": [] }