'use strict'; const { PayloadTooLargeError } = require('@strapi/utils/lib/errors'); const _ = require('lodash'); const registerUploadMiddleware = require('./middlewares/upload'); const { kbytesToBytes } = require('./utils/file'); /** * Register upload plugin * @param {{ strapi: import('@strapi/strapi').Strapi }} */ module.exports = async ({ strapi }) => { strapi.plugin('upload').provider = createProvider(strapi.config.get('plugin.upload', {})); await registerUploadMiddleware({ strapi }); if (strapi.plugin('graphql')) { require('./graphql')({ strapi }); } }; const createProvider = (config) => { const { providerOptions, actionOptions = {} } = config; const providerName = _.toLower(config.provider); let provider; let modulePath; try { modulePath = require.resolve(`@strapi/provider-upload-${providerName}`); } catch (error) { if (error.code === 'MODULE_NOT_FOUND') { modulePath = providerName; } else { throw error; } } try { provider = require(modulePath); } catch (err) { const newError = new Error(`Could not load upload provider "${providerName}".`); newError.stack = err.stack; throw newError; } const providerInstance = provider.init(providerOptions); if (!providerInstance.delete) { throw new Error(`The upload provider "${providerName}" doesn't implement the delete method.`); } if (!providerInstance.upload && !providerInstance.uploadStream) { throw new Error( `The upload provider "${providerName}" doesn't implement the uploadStream nor the upload method.` ); } if (!providerInstance.uploadStream) { process.emitWarning( `The upload provider "${providerName}" doesn't implement the uploadStream function. Strapi will fallback on the upload method. Some performance issues may occur.` ); } const wrappedProvider = _.mapValues(providerInstance, (method, methodName) => { return async (file, options = actionOptions[methodName]) => providerInstance[methodName](file, options); }); const baseProvider = { extend(obj) { Object.assign(this, obj); }, checkFileSize(file) { const fileSize = kbytesToBytes(file.size); if (config.sizeLimit && fileSize > config.sizeLimit) { throw new PayloadTooLargeError(); } }, }; return Object.assign(Object.create(baseProvider), wrappedProvider); };