UNPKG

@jrmc/adonis-attachment

Version:

Turn any field on your Lucid model to an attachment data type

204 lines (203 loc) 5.89 kB
/** * @jrmc/adonis-attachment * * @license MIT * @copyright Jeremy Chaufourier <jeremy@chaufourier.fr> */ import string from '@adonisjs/core/helpers/string'; import path from 'node:path'; import { cuid } from '@adonisjs/core/helpers'; import { defaultOptionsDecorator } from '../utils/default_values.js'; import { extractPathParameters } from '../utils/helpers.js'; export class AttachmentBase { drive; input; #keyId; #name; #folder; size; extname; mimeType; meta; originalPath; url; options; constructor(drive, attributes, input) { this.input = input; this.size = attributes.size; this.meta = attributes.meta; this.extname = attributes.extname; this.mimeType = attributes.mimeType; this.originalPath = attributes.path; this.#folder = attributes.folder; this.setOptions({ folder: attributes.folder }); if (attributes.name) { this.#name = attributes.name; } else { this.#name = `${cuid()}.${this.extname}`; } this.options = defaultOptionsDecorator; this.drive = drive; } /** * Getters / Setters */ get name() { return this.#name; } set name(name) { this.#name = name; } get folder() { if (this.#folder) { return this.#folder; } if (typeof this.options.folder === 'string') { const parameters = extractPathParameters(this.options.folder); if (!parameters.length) { return this.options.folder; } } } get path() { if (!this.folder && this.originalPath) { return this.originalPath; } return path.join(this.folder, this.name); } /** * Methods */ getDisk() { return this.drive.use(this.options?.disk); } getBytes() { return this.getDisk().getBytes(this.path); } async getBuffer() { const arrayBuffer = await this.getBytes(); return Buffer.from(arrayBuffer); } getStream() { return this.getDisk().getStream(this.path); } getUrl() { return this.getDisk().getUrl(this.path); } getSignedUrl(signedUrlOptions) { return this.getDisk().getSignedUrl(this.path, signedUrlOptions); } getKeyId() { return this.#keyId; } setKeyId(keyId) { this.#keyId = keyId; return this; } setOptions(options) { this.options = { ...this.options, ...options, }; return this; } /** * Actions */ async computeUrl(signedUrlOptions) { const disk = this.getDisk(); const fileVisibility = await disk.getVisibility(this.path); if (fileVisibility === 'private') { this.url = await this.getSignedUrl(signedUrlOptions); } else { this.url = await this.getUrl(); } } async preComputeUrl() { if (this.options?.preComputeUrl === false) { return; } await this.computeUrl(); } async makeName(record, attributeName, originalName) { if (typeof this.options.rename === 'function' && record) { this.#name = (await this.options.rename(record, attributeName, originalName)); } else if (originalName && this.options.rename === false) { this.#name = originalName; } if (this.#name && record) { const parameters = extractPathParameters(this.#name); if (parameters) { parameters.forEach((parameter) => { const attribute = record.$attributes[parameter]; if (typeof attribute === 'string') { const name = string.slug(string.noCase(string.escapeHTML(attribute.toLowerCase()))); this.#name = this.#name?.replace(`:${parameter}`, name); } }); } } return this; } async makeFolder(record) { if (typeof this.options.folder === 'function' && record) { this.#folder = (await this.options.folder(record)); } else if (this.options.folder) { this.#folder = this.options.folder; } if (this.#folder && record) { const parameters = extractPathParameters(this.#folder); if (parameters) { parameters.forEach((parameter) => { const attribute = record.$attributes[parameter]; if (typeof attribute === 'string') { const name = string.slug(string.noCase(string.escapeHTML(attribute.toLowerCase()))); this.#folder = this.#folder?.replace(`:${parameter}`, name); } }); } } return this; } async put() { if (Buffer.isBuffer(this.input)) { await this.getDisk().put(this.path, this.input); } else if (this.input) { await this.getDisk().copyFromFs(this.input, this.path); } } async remove() { await this.getDisk().delete(this.path); if (this.originalPath) { await this.getDisk().delete(this.originalPath); } } /** * */ toObject() { return { keyId: this.getKeyId(), name: this.name, extname: this.extname, size: this.size, meta: this.meta, mimeType: this.mimeType, path: this.path, }; } toJSON() { if (this.url) { return { ...this.toObject(), url: this.url, }; } return this.toObject(); } }