UNPKG

@foal/storage

Version:

Storage components for FoalTS

102 lines (101 loc) 3.58 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ConcreteDisk = exports.LocalDisk = void 0; // std const fs_1 = require("fs"); const promises_1 = require("node:fs/promises"); const path_1 = require("path"); const stream_1 = require("stream"); const util_1 = require("util"); const node_fs_1 = require("node:fs"); // 3p const core_1 = require("@foal/core"); // FoalTS const disk_service_1 = require("./disk.service"); /** * File storage to write, read and delete files in the local file system. * * @export * @class LocalDisk * @extends {Disk} */ class LocalDisk extends disk_service_1.Disk { async mkdirIfNotExists(dirname) { const dirPath = this.getPath(dirname); if (!(0, node_fs_1.existsSync)(dirPath)) { await (0, promises_1.mkdir)(dirPath, { recursive: true }); } } async write(dirname, content, options = {}) { let name = this.hasName(options) ? options.name : await (0, core_1.generateToken)(); if (this.hasExtension(options)) { name = `${name}.${options.extension}`; } const path = (0, path_1.join)(dirname, name); if (content instanceof Buffer) { await (0, promises_1.writeFile)(this.getPath(path), content); } else { await (0, util_1.promisify)(stream_1.pipeline)(content, (0, fs_1.createWriteStream)(this.getPath(path))); } return { path }; } async read(path, content) { try { const { size } = await (0, promises_1.stat)(this.getPath(path)); if (content === 'buffer') { return { file: await (0, promises_1.readFile)(this.getPath(path)), size }; } return { file: (0, fs_1.createReadStream)(this.getPath(path)) // Do not kill the process (and crash the server) if the stream emits an error. // Note: users can still add other listeners to the stream to "catch" the error. // Note: error streams are unlikely to occur (most "createWriteStream" errors are simply thrown). // TODO: test this line. .on('error', () => { }), size }; } catch (error) { if (error.code === 'ENOENT') { throw new disk_service_1.FileDoesNotExist(path); } // TODO: test this line. throw error; } } async readSize(path) { try { const { size } = await (0, promises_1.stat)(this.getPath(path)); return size; } catch (error) { if (error.code === 'ENOENT') { throw new disk_service_1.FileDoesNotExist(path); } // TODO: test this line. throw error; } } async delete(path) { try { await (0, promises_1.unlink)(this.getPath(path)); } catch (error) { if (error.code === 'ENOENT') { throw new disk_service_1.FileDoesNotExist(path); } // TODO: test this line. throw error; } } getPath(path) { const directory = core_1.Config.getOrThrow('settings.disk.local.directory', 'string', 'You must provide a directory name when using local file storage (LocalDisk).'); return (0, path_1.join)(directory, path); } } exports.LocalDisk = LocalDisk; exports.ConcreteDisk = LocalDisk;