UNPKG

@lyleunderwood/filereader-polyfill

Version:

W3C File API specification compliant FileReader polyfill for Node.js environments

99 lines 3.94 kB
import { basename } from 'path'; export class File extends Blob { constructor(fileBitsOrPath, fileName, options) { if (typeof fileBitsOrPath === 'string') { // File path constructor - defer file system access const filePath = fileBitsOrPath; super([], { type: '' }); // Will be overridden by file content this.name = basename(filePath); this.lastModified = Date.now(); // Will be updated when file is accessed this._path = filePath; } else { // Standard Web API constructor super(fileBitsOrPath, options); this.name = fileName || ''; this.lastModified = options?.lastModified ?? Date.now(); } } get path() { return this._path; } // Helper method to get file stats and update lastModified async _getFileStats() { if (!this._path) return null; try { const { stat } = await import('fs/promises'); const stats = await stat(this._path); // Update lastModified with actual file time (mutating readonly property) this.lastModified = stats.mtime.getTime(); return stats; } catch (error) { throw new DOMException(`Failed to read file: ${error}`, 'NotReadableError'); } } // Override arrayBuffer to read from file if path is available async arrayBuffer() { if (this._path) { await this._getFileStats(); // This will throw DOMException if file doesn't exist try { const { readFile } = await import('fs/promises'); const buffer = await readFile(this._path); return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength); } catch (error) { throw new DOMException(`Failed to read file: ${error}`, 'NotReadableError'); } } return super.arrayBuffer(); } // Override stream to read from file if path is available stream() { if (this._path) { const filePath = this._path; const self = this; return new ReadableStream({ async start(controller) { try { await self._getFileStats(); // This will throw DOMException if file doesn't exist const { createReadStream } = require('fs'); const nodeStream = createReadStream(filePath); nodeStream.on('data', (chunk) => { controller.enqueue(new Uint8Array(chunk)); }); nodeStream.on('end', () => { controller.close(); }); nodeStream.on('error', (error) => { controller.error(new DOMException(`Failed to read file: ${error}`, 'NotReadableError')); }); } catch (error) { controller.error(error); } }, cancel() { // Stream will be cleaned up automatically } }); } return super.stream(); } // Override text to read from file if path is available async text() { if (this._path) { await this._getFileStats(); // This will throw DOMException if file doesn't exist try { const { readFile } = await import('fs/promises'); return readFile(this._path, 'utf8'); } catch (error) { throw new DOMException(`Failed to read file: ${error}`, 'NotReadableError'); } } return super.text(); } } //# sourceMappingURL=File.js.map