UNPKG

@foal/storage

Version:

Storage components for FoalTS

119 lines (118 loc) 4.13 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Disk = exports.FileDoesNotExist = void 0; exports.isFileDoesNotExist = isFileDoesNotExist; // std const path_1 = require("path"); // 3p const core_1 = require("@foal/core"); const mime_1 = require("mime"); /** * Error thrown by the file storage (disk) if the file could * not be found. * * @export * @class FileDoesNotExist * @extends {Error} */ class FileDoesNotExist extends Error { filename; name = 'FileDoesNotExist'; constructor(filename) { super(`The file "${filename}" does not exist.`); this.filename = filename; } } exports.FileDoesNotExist = FileDoesNotExist; /** * Check if an object is an instance of FileDoesNotExist. * * This function is a help when you have several packages using @foal/storage. * Npm can install the package several times, which leads to duplicate class * definitions. If this is the case, the keyword `instanceof` may return false * while the object is an instance of the class. This function fixes this * problem. * * @export * @param {*} obj - The object to check. * @returns {obj is FileDoesNotExist} - True if the error is an instance of FileDoesNotExist. False otherwise. */ function isFileDoesNotExist(obj) { return obj instanceof FileDoesNotExist || (typeof obj === 'object' && obj !== null && obj.name === 'FileDoesNotExist'); } /** * Agnostic file storage. * * @export * @abstract * @class Disk */ class Disk { static concreteClassConfigPath = 'settings.disk.driver'; static concreteClassName = 'ConcreteDisk'; static defaultConcreteClassPath = (0, path_1.join)(__dirname, './local-disk.service'); /** * Create a directory if it does not exist. * * Depending on the storage system, the concept of directory may not exist. In this case, * the method should do nothing, which is the default behavior. * * @param dirname Name or path of the directory to create. * @returns {Promise<void>} */ async mkdirIfNotExists(dirname) { // Do nothing by default. } /** * Create an HttpResponse object to download or display the file in the * browser. * * @param {string} path - The path of the file. * @param {{ forceDownload?: boolean, filename?: string }} [options={}] * @param {boolean} [options.forceDownload=false] - Indicate if the browser should download * the file directly without trying to display it in the window. * @param {filename} [options.string=options.file] - Default name used by the browser when * saving the file to the disk. * @returns {Promise<HttpResponse>} * @memberof Disk */ async createHttpResponse(path, options = {}) { const { file, size } = await this.read(path, 'stream'); const response = new core_1.HttpResponseOK(file, { stream: true }); if (options.cache) { response.setHeader('Cache-Control', options.cache); } const mimeType = (0, mime_1.getType)(path) || 'application/octet-stream'; return response .setHeader('Content-Type', mimeType) .setHeader('Content-Length', size.toString()) .setHeader('Content-Disposition', (options.forceDownload ? 'attachment' : 'inline') + `; filename="${options.filename || (0, path_1.basename)(path)}"`); } /** * Returns true if the write options has a "name" property. * * @protected * @param {*} options - Write options. * @returns {options is { name: string }} True or false. * @memberof Disk */ hasName(options) { // options.name === '' returns false; return !!options.name; } /** * Returns true if the write options has a "extension" property. * * @protected * @param {*} options - Write options. * @returns {options is { extension: string }} True or false. * @memberof Disk */ hasExtension(options) { // options.extension === '' returns false; return !!options.extension; } } exports.Disk = Disk;