taglib-wasm
Version:
TagLib for TypeScript platforms: Deno, Node.js, Bun, Electron, browsers, and Cloudflare Workers
172 lines (171 loc) • 5.5 kB
JavaScript
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
};