| 
									
										
										
										
											2018-02-08 12:01:06 +01:00
										 |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Upload.js service | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @description: A set of functions similar to controller's actions to avoid code duplication. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-19 14:26:20 +01:00
										 |  |  | const fs = require('fs'); | 
					
						
							| 
									
										
										
										
											2018-09-17 15:50:13 +08:00
										 |  |  | const crypto = require('crypto'); | 
					
						
							| 
									
										
										
										
											2018-04-30 18:00:01 +02:00
										 |  |  | const _ = require('lodash'); | 
					
						
							| 
									
										
										
										
											2018-02-19 14:26:20 +01:00
										 |  |  | const toArray = require('stream-to-array'); | 
					
						
							|  |  |  | const uuid = require('uuid/v4'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-17 15:50:13 +08:00
										 |  |  | function niceHash(buffer) { | 
					
						
							|  |  |  |   return crypto | 
					
						
							|  |  |  |     .createHash('sha256') | 
					
						
							|  |  |  |     .update(buffer) | 
					
						
							|  |  |  |     .digest('base64') | 
					
						
							|  |  |  |     .replace(/=/g, '') | 
					
						
							|  |  |  |     .replace(/\//g, '-') | 
					
						
							|  |  |  |     .replace(/\+/, '_'); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-08 12:01:06 +01:00
										 |  |  | module.exports = { | 
					
						
							| 
									
										
										
										
											2018-02-27 11:52:18 +01:00
										 |  |  |   bufferize: async files => { | 
					
						
							|  |  |  |     if (_.isEmpty(files) === 0) { | 
					
						
							| 
									
										
										
										
											2018-02-19 14:26:20 +01:00
										 |  |  |       throw 'Missing files.'; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-21 17:18:33 +01:00
										 |  |  |     // files is always an array to map on
 | 
					
						
							| 
									
										
										
										
											2018-02-27 11:52:18 +01:00
										 |  |  |     files = _.isArray(files) ? files : [files]; | 
					
						
							| 
									
										
										
										
											2018-02-19 14:26:20 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-01 08:52:35 +02:00
										 |  |  |     const createBuffer = async stream => { | 
					
						
							|  |  |  |       const parts = await toArray(fs.createReadStream(stream.path)); | 
					
						
							|  |  |  |       const buffers = parts.map(part => | 
					
						
							|  |  |  |         _.isBuffer(part) ? part : Buffer.from(part) | 
					
						
							|  |  |  |       ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const buffer = Buffer.concat(buffers); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return { | 
					
						
							|  |  |  |         tmpPath: stream.path, | 
					
						
							|  |  |  |         name: stream.name, | 
					
						
							|  |  |  |         sha256: niceHash(buffer), | 
					
						
							|  |  |  |         hash: uuid().replace(/-/g, ''), | 
					
						
							|  |  |  |         ext: | 
					
						
							|  |  |  |           stream.name.split('.').length > 1 | 
					
						
							|  |  |  |             ? `.${_.last(stream.name.split('.'))}` | 
					
						
							|  |  |  |             : '', | 
					
						
							|  |  |  |         buffer, | 
					
						
							|  |  |  |         mime: stream.type, | 
					
						
							|  |  |  |         size: (stream.size / 1000).toFixed(2), | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-21 17:18:33 +01:00
										 |  |  |     // transform all files in buffer
 | 
					
						
							| 
									
										
										
										
											2019-08-01 08:52:35 +02:00
										 |  |  |     return Promise.all(files.map(stream => createBuffer(stream))); | 
					
						
							| 
									
										
										
										
											2018-02-19 14:26:20 +01:00
										 |  |  |   }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-15 18:41:23 +02:00
										 |  |  |   upload(files, config) { | 
					
						
							| 
									
										
										
										
											2018-02-27 16:53:06 +01:00
										 |  |  |     // Get upload provider settings to configure the provider to use.
 | 
					
						
							| 
									
										
										
										
											2018-09-10 16:05:00 +08:00
										 |  |  |     const provider = _.find(strapi.plugins.upload.config.providers, { | 
					
						
							|  |  |  |       provider: config.provider, | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2018-03-06 15:49:11 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (!provider) { | 
					
						
							| 
									
										
										
										
											2018-09-10 16:05:00 +08:00
										 |  |  |       throw new Error( | 
					
						
							| 
									
										
										
										
											2019-07-15 16:25:45 +02:00
										 |  |  |         `The provider package isn't installed. Please run \`npm install strapi-provider-upload-${config.provider}\`` | 
					
						
							| 
									
										
										
										
											2018-09-10 16:05:00 +08:00
										 |  |  |       ); | 
					
						
							| 
									
										
										
										
											2018-03-06 15:49:11 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 16:53:06 +01:00
										 |  |  |     const actions = provider.init(config); | 
					
						
							| 
									
										
										
										
											2018-02-20 17:10:25 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-15 18:41:23 +02:00
										 |  |  |     // upload a single file
 | 
					
						
							|  |  |  |     const uploadFile = async file => { | 
					
						
							|  |  |  |       await actions.upload(file); | 
					
						
							| 
									
										
										
										
											2018-02-19 15:41:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-15 18:41:23 +02:00
										 |  |  |       // Remove buffer to don't save it.
 | 
					
						
							|  |  |  |       delete file.buffer; | 
					
						
							|  |  |  |       file.provider = provider.provider; | 
					
						
							| 
									
										
										
										
											2018-02-19 15:41:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-15 18:41:23 +02:00
										 |  |  |       const res = await strapi.plugins['upload'].services.upload.add(file); | 
					
						
							| 
									
										
										
										
											2018-03-07 14:18:15 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-15 18:41:23 +02:00
										 |  |  |       // Remove temp file
 | 
					
						
							| 
									
										
										
										
											2019-08-21 11:05:33 +02:00
										 |  |  |       if (file.tmpPath) { | 
					
						
							|  |  |  |         fs.unlinkSync(file.tmpPath); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-07-15 18:41:23 +02:00
										 |  |  |       return res; | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2019-02-04 13:17:59 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-15 18:41:23 +02:00
										 |  |  |     // Execute upload function of the provider for all files.
 | 
					
						
							|  |  |  |     return Promise.all(files.map(file => uploadFile(file))); | 
					
						
							| 
									
										
										
										
											2018-02-19 15:41:26 +01:00
										 |  |  |   }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-15 16:54:35 +02:00
										 |  |  |   add(values) { | 
					
						
							| 
									
										
										
										
											2019-07-15 16:25:45 +02:00
										 |  |  |     return strapi.query('file', 'upload').create(values); | 
					
						
							| 
									
										
										
										
											2018-02-19 15:41:26 +01:00
										 |  |  |   }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-15 16:25:45 +02:00
										 |  |  |   fetch(params) { | 
					
						
							|  |  |  |     return strapi.query('file', 'upload').findOne({ | 
					
						
							| 
									
										
										
										
											2019-08-13 16:31:29 +02:00
										 |  |  |       id: params.id, | 
					
						
							| 
									
										
										
										
											2019-07-15 16:25:45 +02:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2018-02-19 15:41:26 +01:00
										 |  |  |   }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-15 16:25:45 +02:00
										 |  |  |   fetchAll(params) { | 
					
						
							|  |  |  |     return strapi.query('file', 'upload').find(params); | 
					
						
							| 
									
										
										
										
											2018-02-19 15:41:26 +01:00
										 |  |  |   }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-15 18:41:23 +02:00
										 |  |  |   count(params) { | 
					
						
							| 
									
										
										
										
											2019-07-15 18:28:56 +02:00
										 |  |  |     return strapi.query('file', 'upload').count(params); | 
					
						
							| 
									
										
										
										
											2018-02-19 19:54:45 +01:00
										 |  |  |   }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-15 18:28:56 +02:00
										 |  |  |   async remove(file, config) { | 
					
						
							| 
									
										
										
										
											2018-02-21 17:18:33 +01:00
										 |  |  |     // get upload provider settings to configure the provider to use
 | 
					
						
							| 
									
										
										
										
											2018-09-10 16:05:00 +08:00
										 |  |  |     const provider = _.cloneDeep( | 
					
						
							|  |  |  |       _.find(strapi.plugins.upload.config.providers, { | 
					
						
							|  |  |  |         provider: config.provider, | 
					
						
							| 
									
										
										
										
											2019-07-15 16:25:45 +02:00
										 |  |  |       }) | 
					
						
							| 
									
										
										
										
											2018-09-10 16:05:00 +08:00
										 |  |  |     ); | 
					
						
							| 
									
										
										
										
											2018-02-20 17:10:25 +01:00
										 |  |  |     _.assign(provider, config); | 
					
						
							| 
									
										
										
										
											2018-03-07 14:18:15 +01:00
										 |  |  |     const actions = provider.init(config); | 
					
						
							| 
									
										
										
										
											2018-02-20 17:10:25 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-21 17:18:33 +01:00
										 |  |  |     // execute delete function of the provider
 | 
					
						
							| 
									
										
										
										
											2018-03-07 14:18:15 +01:00
										 |  |  |     if (file.provider === provider.provider) { | 
					
						
							|  |  |  |       await actions.delete(file); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-19 16:00:37 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-15 18:28:56 +02:00
										 |  |  |     return strapi.query('file', 'upload').delete({ id: file.id }); | 
					
						
							| 
									
										
										
										
											2018-02-28 12:33:32 +01:00
										 |  |  |   }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-15 16:25:45 +02:00
										 |  |  |   async uploadToEntity(params, files, source) { | 
					
						
							| 
									
										
										
										
											2018-02-28 15:49:28 +01:00
										 |  |  |     // Retrieve provider settings from database.
 | 
					
						
							| 
									
										
										
										
											2018-09-10 16:05:00 +08:00
										 |  |  |     const config = await strapi | 
					
						
							|  |  |  |       .store({ | 
					
						
							|  |  |  |         environment: strapi.config.environment, | 
					
						
							|  |  |  |         type: 'plugin', | 
					
						
							|  |  |  |         name: 'upload', | 
					
						
							|  |  |  |       }) | 
					
						
							|  |  |  |       .get({ key: 'provider' }); | 
					
						
							| 
									
										
										
										
											2018-02-28 12:33:32 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-01 08:52:35 +02:00
										 |  |  |     const model = strapi.getModel(params.model, source); | 
					
						
							| 
									
										
										
										
											2018-02-28 12:33:32 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-28 15:49:28 +01:00
										 |  |  |     // Asynchronous upload.
 | 
					
						
							| 
									
										
										
										
											2019-08-01 08:52:35 +02:00
										 |  |  |     return await Promise.all( | 
					
						
							| 
									
										
										
										
											2018-09-10 16:05:00 +08:00
										 |  |  |       Object.keys(files).map(async attribute => { | 
					
						
							|  |  |  |         // Bufferize files per attribute.
 | 
					
						
							|  |  |  |         const buffers = await this.bufferize(files[attribute]); | 
					
						
							|  |  |  |         const enhancedFiles = buffers.map(file => { | 
					
						
							|  |  |  |           const details = model.attributes[attribute]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           // Add related information to be able to make
 | 
					
						
							|  |  |  |           // the relationships later.
 | 
					
						
							|  |  |  |           file[details.via] = [ | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2018-02-28 12:33:32 +01:00
										 |  |  |               refId: params.id, | 
					
						
							|  |  |  |               ref: params.model, | 
					
						
							|  |  |  |               source, | 
					
						
							|  |  |  |               field: attribute, | 
					
						
							| 
									
										
										
										
											2018-09-10 16:05:00 +08:00
										 |  |  |             }, | 
					
						
							|  |  |  |           ]; | 
					
						
							| 
									
										
										
										
											2018-02-28 12:33:32 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-10 16:05:00 +08:00
										 |  |  |           return file; | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2018-02-28 12:33:32 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-10 16:05:00 +08:00
										 |  |  |         // Make upload async.
 | 
					
						
							|  |  |  |         return this.upload(enhancedFiles, config); | 
					
						
							| 
									
										
										
										
											2019-07-15 16:25:45 +02:00
										 |  |  |       }) | 
					
						
							| 
									
										
										
										
											2018-02-28 12:33:32 +01:00
										 |  |  |     ); | 
					
						
							| 
									
										
										
										
											2018-09-10 16:05:00 +08:00
										 |  |  |   }, | 
					
						
							| 
									
										
										
										
											2019-07-15 16:25:45 +02:00
										 |  |  | }; |