UNPKG

@metamask/snaps-utils

Version:
71 lines 3.08 kB
// TODO(ritave): Move into separate package @metamask/vfile / @metamask/utils + @metamask/to-vfile when passes code review // TODO(ritave): Streaming vfile contents similar to vinyl maybe? // TODO(ritave): Move fixing manifest in cli and bundler plugins to write messages to vfile // similar to unified instead of throwing "ProgrammaticallyFixableErrors". // // Using https://github.com/vfile/vfile would be helpful, but they only support ESM and we need to support CommonJS. // https://github.com/gulpjs/vinyl is also good, but they normalize paths, which we can't do, because // we're calculating checksums based on original path. import { assert, bytesToHex } from "@metamask/utils"; import { base64 } from "@scure/base"; import { deepClone } from "../deep-clone.mjs"; export class VirtualFile { constructor(value) { let options; if (typeof value === 'string' || value instanceof Uint8Array) { options = { value }; } else { options = value; } this.value = options?.value ?? ''; // This situations happens when there's no .result used, // we expect the file to have default generic in that situation: // VirtualFile<unknown> which will handle undefined properly // // While not 100% type safe, it'll be way less frustrating to work with. // The alternative would be to have VirtualFile.result be Result | undefined // and that would result in needing to branch out and check in all situations. // // In short, optimizing for most common use case. this.result = options?.result ?? undefined; this.data = options?.data ?? {}; this.path = options?.path ?? '/'; } get size() { return typeof this.value === 'string' ? this.value.length : this.value.byteLength; } toString(encoding) { if (typeof this.value === 'string') { assert(encoding === undefined, 'Tried to encode string.'); return this.value; } else if (this.value instanceof Uint8Array && encoding === 'hex') { return bytesToHex(this.value); } else if (this.value instanceof Uint8Array && encoding === 'base64') { // For large files, this is quite slow, instead use `encodeBase64()` // TODO: Use @metamask/utils for this return base64.encode(this.value); } const decoder = new TextDecoder(encoding); return decoder.decode(this.value); } clone() { const vfile = new VirtualFile(); if (typeof this.value === 'string') { vfile.value = this.value; } else { // deep-clone doesn't clone Buffer properly, even if it's a sub-class of Uint8Array vfile.value = this.value.slice(0); } vfile.result = deepClone(this.result); vfile.data = deepClone(this.data); vfile.path = this.path; return vfile; } } //# sourceMappingURL=VirtualFile.mjs.map