UNPKG

@nexide/strapi-provider-bunny

Version:
151 lines (133 loc) 4.52 kB
import { errors } from '@strapi/utils'; import axios from 'axios'; import { Buffer } from 'buffer'; import { getMimeType } from './utils/index.js'; const { ApplicationError } = errors; /** * Initialize Bunny CDN Storage integration. * * @param {Object} config - The configuration object for Bunny CDN. * @param {string} config.api_key - The API key for Bunny CDN. * @param {string} config.storage_zone - The storage zone name in Bunny CDN. * @param {string} config.pull_zone - The pull zone name in Bunny CDN. * @param {string} config.hostname - The region of the Bunny CDN storage. * @param {string?} config.upload_path - The default upload path, optional * @returns {Object} The initialized upload, download, and delete methods. */ const init = ({ api_key, storage_zone, pull_zone, hostname, upload_path }) => { if (!api_key || !storage_zone || !pull_zone || !hostname) { throw new ApplicationError( "BUNNY_API_KEY, BUNNY_HOSTNAME, BUNNY_STORAGE_ZONE or BUNNY_PULL_ZONE can't be null or undefined.", ); } /** * Uploads a file to Bunny CDN. * * @param {Object} file - The file object to upload. * @param {Buffer|Stream} file.stream - The file data as a stream or buffer. * @param {string} file.hash - The hash of the file. * @param {string} file.ext - The file extension. * @returns {Promise<void>} A promise that resolves when the file is uploaded. */ const upload = async (file) => { const data = file.stream || Buffer.from(file.buffer, 'binary'); const path = upload_path ? `${upload_path}/` : ''; try { const response = await axios.put( `https://${hostname}/${storage_zone}/${path}${file.hash}${file.ext}`, data, { headers: { AccessKey: api_key, 'content-type': 'application/octet-stream', }, }, ); if (response.data.HttpCode !== 201) { throw new ApplicationError( `Error uploading to Bunny.net: ${response.data.Message}`, ); } file.url = `https://${pull_zone}/${path}${file.hash}${file.ext}`; } catch (error) { throw new ApplicationError( `Error uploading to Bunny.net: ${error.message}`, ); } }; /** * Downloads a file from Bunny CDN. * * @param {Object} file - The file object to download. * @param {string} file.hash - The hash of the file. * @param {string} file.ext - The file extension. * @returns {Promise<Object>} A promise that resolves with the downloaded file data. */ const download = async (file) => { try { const path = upload_path ? `${upload_path}/` : ''; const response = await axios.get( `https://${hostname}/${storage_zone}/${path}${file.hash}${file.ext}`, { headers: { AccessKey: api_key, }, responseType: 'arraybuffer', // Para manejar diferentes tipos de archivos }, ); const type = getMimeType(file.ext); let body; if (/^text(\/|$)/.test(type)) { body = response.data.toString('utf8'); } else if (type === 'application/json') { body = JSON.parse(response.data.toString('utf8')); } else { body = Buffer.from(response.data); } return { type, body }; } catch (error) { throw new ApplicationError( `Error downloading from Bunny.net: ${error.message}`, ); } }; /** * Deletes a file from Bunny CDN. * * @param {Object} file - The file object to delete. * @param {string} file.hash - The hash of the file. * @param {string} file.ext - The file extension. * @returns {Promise<void>} A promise that resolves when the file is deleted. */ const deleteFile = async (file) => { try { const path = upload_path ? `${upload_path}/` : ''; const response = await axios.delete( `https://${hostname}/${storage_zone}/${path}${file.hash}${file.ext}`, { headers: { AccessKey: api_key, }, }, ); if (response.data.HttpCode !== 200) { console.error( 'Soft Error: Failed to delete file; has it already been deleted?', response.data, ); } } catch (error) { console.error( 'Soft Error: Failed to delete file; has it already been deleted?', error.message, ); } }; return { upload, download, delete: deleteFile, uploadStream: upload, }; }; export { init };