├── .gitignore ├── index.js └── package-lock.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # TypeScript v1 declaration files 45 | typings/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | 78 | # Next.js build output 79 | .next 80 | 81 | # Nuxt.js build / generate output 82 | .nuxt 83 | dist 84 | 85 | # Gatsby files 86 | .cache/ 87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 88 | # https://nextjs.org/blog/next-9-1#public-directory-support 89 | # public 90 | 91 | # vuepress build output 92 | .vuepress/dist 93 | 94 | # Serverless directories 95 | .serverless/ 96 | 97 | # FuseBox cache 98 | .fusebox/ 99 | 100 | # DynamoDB Local files 101 | .dynamodb/ 102 | 103 | # TernJS port file 104 | .tern-port 105 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const baseProvider = { 4 | extend (obj) { 5 | Object.assign(this, obj) 6 | }, 7 | upload () { 8 | throw new Error('Provider upload method is not implemented') 9 | }, 10 | delete () { 11 | throw new Error('Provider delete method is not implemented') 12 | } 13 | } 14 | 15 | const { convertToStrapiError } = require('../strapi-plugin-upload/errors') 16 | 17 | const wrapFunctionForErrors = fn => async (...args) => { 18 | try { 19 | return await fn(...args) 20 | } catch (err) { 21 | throw convertToStrapiError(err) 22 | } 23 | } 24 | 25 | const getProviderData = (file, options) => { 26 | if (!options.selectProvider || typeof options.selectProvider !== 'function') { 27 | const msg = `config must define a selectProvider function` 28 | strapi.log.error(msg) 29 | throw new Error(msg) 30 | } 31 | 32 | let providerKey 33 | try { 34 | providerKey = options.selectProvider(file) 35 | } catch (err) { 36 | const msg = `The function selectProvider generated error` 37 | strapi.log.error(msg) 38 | strapi.log.error(err) 39 | throw new Error(msg) 40 | } 41 | 42 | if (!options.providers) { 43 | const msg = `You must set providers object in providerOptions of config/plugins.js` 44 | strapi.log.error(msg) 45 | throw new Error(msg) 46 | } 47 | 48 | const p = options.providers[providerKey] 49 | if (!p) { 50 | const msg = `The upload provider selector with key '${providerKey}' not found` 51 | strapi.log.error(msg) 52 | throw new Error(msg) 53 | } 54 | 55 | let providerInstance 56 | try { 57 | providerInstance = require(`strapi-provider-upload-${p.provider}`).init( 58 | p.options 59 | ) 60 | } catch (err) { 61 | const msg = `The provider package isn't installed. Please run \`npm install strapi-provider-upload-${p.provider}\`` 62 | strapi.log.error(msg) 63 | throw new Error(msg) 64 | } 65 | 66 | const providerFunctions = Object.assign(Object.create(baseProvider), { 67 | ...providerInstance, 68 | upload: wrapFunctionForErrors(file => { 69 | return providerInstance.upload(file, p.options) 70 | }), 71 | delete: wrapFunctionForErrors(file => { 72 | return providerInstance.delete(file, p.options) 73 | }) 74 | }) 75 | 76 | return { providerFunctions, providerOptions: p.options } 77 | } 78 | 79 | module.exports = { 80 | init (options) { 81 | return { 82 | upload (file) { 83 | try { 84 | const { providerFunctions, providerOptions } = getProviderData( 85 | file, 86 | options 87 | ) 88 | return providerFunctions.upload(file, providerOptions) 89 | } catch (err) { 90 | return null 91 | } 92 | }, 93 | delete (file) { 94 | try { 95 | const { providerFunctions, providerOptions } = getProviderData( 96 | file, 97 | options 98 | ) 99 | return providerFunctions.delete(file, providerOptions) 100 | } catch (err) { 101 | return null 102 | } 103 | } 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "strapi-provider-upload-multiple-provider", 3 | "version": "1.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "version": "1.0.0", 9 | "license": "ISC" 10 | } 11 | } 12 | } 13 | --------------------------------------------------------------------------------