UNPKG

@timothy-spaceman/multitrack-vcs

Version:

Version Control System for musicians

73 lines (64 loc) 2.29 kB
import fs from "fs" import path from "node:path" import {FileHandle} from "fs/promises" import {IFile} from "./types.js" import {createHash} from "crypto" export class File implements IFile { path: string name: string extension: string = "" fullPath: string // path + name + extension constructor(fullPath: string) { this.fullPath = fullPath const parts = fullPath.split(path.sep) const fileName = parts.pop() if (!fileName) { throw new Error("Unable to parse file name") } this.name = fileName if (fileName.split(".").length > 1) { this.name = fileName.split(".").slice(0, -1).join(".") this.extension = fileName.split(".").slice(-1).join("") } this.path = parts.join(path.sep) } async readData(): Promise<Buffer> { try { return await fs.promises.readFile(this.fullPath) } catch (err: any) { throw new Error(`Failed to read file content: ${err.message}`) } } async writeData(data: Buffer): Promise<void> { try { return await fs.promises.writeFile(this.fullPath, data) } catch (err: any) { throw new Error(`Failed to write file content: ${err.message}`) } } async getHandle(): Promise<FileHandle> { try { return await fs.promises.open(this.fullPath, "r") } catch (err: any) { throw new Error(`Failed to open file handle: ${err.message}`) } } async getDataHash(algo: string = "sha256"): Promise<string> { const hash = createHash(algo) const bufferSize = 64 * 1024 const buffer = Buffer.allocUnsafe(bufferSize) const fileHandle = await this.getHandle() try { let position = 0 while (true) { const {bytesRead} = await fileHandle.read(buffer, 0, bufferSize, position) if (bytesRead === 0) break hash.update(buffer.subarray(0, bytesRead)) position += bytesRead } } finally { await fileHandle.close() } return hash.digest("hex") } }