UNPKG

@codice-progressio/easy-images

Version:

Subida de imagenes facil a google cloud storage con firebase

132 lines (120 loc) 3.95 kB
const { Storage } = require("@google-cloud/storage") const Sharp = require("sharp") //El receptor de ficheros const multer = require("multer") const ObjectId = require("mongoose").Types.ObjectId const parametros = { GCLOUD_PROJECT_ID: "", GCLOUD_APPLICATION_CREDENTIALS: "", GCLOUD_STORAGE_BUCKET_URL: "", } var storage = null var bucket = null module.exports.config = function (param = param) { Object.keys(parametros).forEach(x => { if (!param[x]) throw new Error(msj("[ easy-images ]", `Parametro no definido: ${x}`)) }) Object.assign(parametros, param) storage = new Storage({ projectId: parametros.GCLOUD_PROJECT_ID, credentials: JSON.parse(parametros.GCLOUD_APPLICATION_CREDENTIALS), }) bucket = storage.bucket(parametros.GCLOUD_STORAGE_BUCKET_URL) } // Filtro para multer para las extenciones deseadas. const fileFilter = (req, file, cb) => { if ( file.mimetype === "image/jpg" || file.mimetype === "image/jpeg" || file.mimetype === "image/png" ) { cb(null, true) } else { cb(`La imagen ${file.originalname} no es de tipo jpg/jpeg or png`, false) } } /** * Con la ayuda de multer prepara un middleware para la recepcion de una * imagen que no sea mayor 5MB * * @param {*} buffer * @returns Retorna un un objeto de multer con el que se pondran las opciones. */ module.exports.recibirImagen = multer({ fileFilter, storage: multer.memoryStorage(), limits: { fileSize: 5 * 1024 * 1024, //tamaño < 5 MB }, }) /** * Crea un middleware de redimencion para reducir el tamaño de la imagen a max * 1200 px por lado y calidad 80 * @param {*} req * @param {*} params * @param {*} next */ module.exports.redimencionarMiddleware = (req, params, next) => { // Con este middleware redimiensionamos el tamaño de // imagen para que no mida mas de 1000 Sharp(req.file.buffer) // El maximo tamaño horizontal de las imagenes debe ser 1200 .resize(1200, 1200, { withoutEnlargement: true, fit: Sharp.fit.inside }) .jpeg({ quality: 80 }) .toBuffer() .then(data => { req.file.buffer = data return next() }) .catch(err => next(err)) } /** * Elimina una imagen de la nube y retorna una promesa con la respuesta. * @param {*} nombre */ module.exports.eliminarImagenDeBucket = function (nombre) { const file = bucket.file(nombre) return file.delete() } /** *Sube una imagen al google cloud-storage de firebase. Solo hay * que pasarle el buffer de la imagen que se quiere subir. * * @param {*} buffer * @returns Retorna la url publica de la imagen en el bucket de google * para guardarlo en nuestra imagen */ module.exports.subirImagen = function (file) { if (!bucket) throw new Error(msj("[ easy-images ]", `Parametro no definido: ${x}`)) return new Promise((resolve, reject) => { // Generamos un nuevo nombre con el object is const nuevoNombre = ObjectId() + "" // Creamos el nuevo archivo para subir con el nombre que queremos. const blob = bucket.file(nuevoNombre) const blobStream = blob.createWriteStream({ metadata: { // Important: You need to pass the file mimetype as metadata to createWriteStream() otherwise your file won’t be stored in the proper format and won’t be readable. contentType: file.mimetype, }, }) // If all is good and done blobStream.on("finish", () => { // Assemble the file public URL const publicUrl = `https://firebasestorage.googleapis.com/v0/b/${ bucket.name }/o/${encodeURI(blob.name)}?alt=media` // Return the file name and its public URL // for you to store in your own database resolve({ publicUrl, nuevoNombre }) }) blobStream.end(file.buffer) // If there's an error blobStream.on("error", err => reject(err)) }) } module.exports.bucket = bucket function msj(textRed, text) { return `\x1b[0m\x1b[31m\x1b[40m${textRed}\x1b[0m${text}` }