UNPKG

taglib-wasm

Version:

TagLib for TypeScript platforms: Deno, Node.js, Bun, Electron, browsers, and Cloudflare Workers

172 lines (171 loc) 5.5 kB
import { EnvironmentError, FileOperationError } from "../errors.js"; async function readFileData(file) { if (file instanceof Uint8Array) { return file; } if (file instanceof ArrayBuffer) { return new Uint8Array(file); } if (typeof File !== "undefined" && file instanceof File) { return new Uint8Array(await file.arrayBuffer()); } if (typeof file === "string") { const hasDeno = typeof globalThis.Deno !== "undefined"; const hasNode = typeof globalThis.process !== "undefined" && globalThis.process.versions && globalThis.process.versions.node; const hasBun = typeof globalThis.Bun !== "undefined"; if (!hasDeno && !hasNode && !hasBun) { const env = "Browser"; throw new EnvironmentError( env, "does not support file path reading", "filesystem access" ); } try { if (hasDeno) { return await globalThis.Deno.readFile(file); } if (hasNode) { const { readFile } = await import("fs/promises"); return new Uint8Array(await readFile(file)); } if (hasBun) { const bunFile = globalThis.Bun.file(file); return new Uint8Array(await bunFile.arrayBuffer()); } } catch (error) { throw new FileOperationError( "read", error.message, file ); } } const inputType = Object.prototype.toString.call(file); throw new FileOperationError( "read", `Invalid file input type: ${inputType}. Expected string path, Uint8Array, ArrayBuffer, or File object.` ); } async function getFileSize(path) { const hasDeno = typeof globalThis.Deno !== "undefined"; const hasNode = typeof globalThis.process !== "undefined" && globalThis.process.versions && globalThis.process.versions.node; const hasBun = typeof globalThis.Bun !== "undefined"; if (!hasDeno && !hasNode && !hasBun) { throw new EnvironmentError( "Browser", "does not support file path operations", "filesystem access" ); } try { if (hasDeno) { const stat = await globalThis.Deno.stat(path); return stat.size; } if (hasNode) { const { stat } = await import("fs/promises"); const stats = await stat(path); return stats.size; } if (hasBun) { const bunFile = globalThis.Bun.file(path); return bunFile.size; } } catch (error) { throw new FileOperationError( "stat", error.message, path ); } throw new EnvironmentError( "Unknown", "No runtime detected", "filesystem access" ); } async function readPartialFileData(path, headerSize, footerSize) { const hasDeno = typeof globalThis.Deno !== "undefined"; const hasNode = typeof globalThis.process !== "undefined" && globalThis.process.versions && globalThis.process.versions.node; if (!hasDeno && !hasNode) { throw new EnvironmentError( "Browser/Bun", "does not support partial file reading", "filesystem access with seek support" ); } try { if (hasDeno) { const file = await globalThis.Deno.open(path, { read: true }); try { const stat = await file.stat(); const fileSize = stat.size; const actualHeaderSize = Math.min(headerSize, fileSize); const header = new Uint8Array(actualHeaderSize); await file.read(header); const actualFooterSize = Math.min(footerSize, fileSize); const footerStart = Math.max(0, fileSize - actualFooterSize); if (footerStart <= actualHeaderSize) { return header.slice(0, fileSize); } await file.seek(footerStart, globalThis.Deno.SeekMode.Start); const footer = new Uint8Array(actualFooterSize); await file.read(footer); const combined = new Uint8Array(actualHeaderSize + actualFooterSize); combined.set(header, 0); combined.set(footer, actualHeaderSize); return combined; } finally { file.close(); } } if (hasNode) { const { open } = await import("fs/promises"); const file = await open(path, "r"); try { const stats = await file.stat(); const fileSize = stats.size; const actualHeaderSize = Math.min(headerSize, fileSize); const { Buffer } = await import("buffer"); const header = Buffer.alloc(actualHeaderSize); await file.read(header, 0, actualHeaderSize, 0); const actualFooterSize = Math.min(footerSize, fileSize); const footerStart = Math.max(0, fileSize - actualFooterSize); if (footerStart <= actualHeaderSize) { return new Uint8Array(header.buffer, 0, fileSize); } const footer = Buffer.alloc(actualFooterSize); await file.read(footer, 0, actualFooterSize, footerStart); const combined = new Uint8Array(actualHeaderSize + actualFooterSize); combined.set( new Uint8Array(header.buffer, header.byteOffset, header.byteLength), 0 ); combined.set( new Uint8Array(footer.buffer, footer.byteOffset, footer.byteLength), actualHeaderSize ); return combined; } finally { await file.close(); } } } catch (error) { throw new FileOperationError( "read", error.message, path ); } throw new EnvironmentError( "Unknown", "No runtime detected", "filesystem access" ); } export { getFileSize, readFileData, readPartialFileData };