mirror of
https://github.com/strapi/strapi.git
synced 2025-10-29 17:04:13 +00:00
Implement file replace
Signed-off-by: Alexandre Bodin <bodin.alex@gmail.com>
This commit is contained in:
parent
7cd34b725a
commit
c722b0db00
@ -29,15 +29,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"method": "POST",
|
|
||||||
"path": "/files/replace/:id",
|
|
||||||
"handler": "Upload.replaceFile",
|
|
||||||
"config": {
|
|
||||||
"policies": [],
|
|
||||||
"description": "Replace a file"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"method": "GET",
|
"method": "GET",
|
||||||
"path": "/files/count",
|
"path": "/files/count",
|
||||||
|
|||||||
@ -23,7 +23,9 @@ module.exports = {
|
|||||||
resolver: async (obj, { file: upload, ...fields }) => {
|
resolver: async (obj, { file: upload, ...fields }) => {
|
||||||
const file = await formatFile(upload, fields);
|
const file = await formatFile(upload, fields);
|
||||||
|
|
||||||
const uploadedFiles = await strapi.plugins.upload.services.upload.upload([file]);
|
const uploadedFiles = await strapi.plugins.upload.services.upload.uploadFileAndPersist(
|
||||||
|
file
|
||||||
|
);
|
||||||
|
|
||||||
// Return response.
|
// Return response.
|
||||||
return uploadedFiles.length === 1 ? uploadedFiles[0] : uploadedFiles;
|
return uploadedFiles.length === 1 ? uploadedFiles[0] : uploadedFiles;
|
||||||
@ -35,10 +37,9 @@ module.exports = {
|
|||||||
resolver: async (obj, { files: uploads, ...fields }) => {
|
resolver: async (obj, { files: uploads, ...fields }) => {
|
||||||
const files = await Promise.all(uploads.map(upload => formatFile(upload, fields)));
|
const files = await Promise.all(uploads.map(upload => formatFile(upload, fields)));
|
||||||
|
|
||||||
const uploadedFiles = await strapi.plugins.upload.services.upload.upload(files);
|
const uploadService = strapi.plugins.upload.services.upload;
|
||||||
|
|
||||||
// Return response.
|
return Promise.all(files.map(file => uploadService.uploadFileAndPersist(file)));
|
||||||
return uploadedFiles;
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -55,8 +56,8 @@ const formatFile = async (upload, metas) => {
|
|||||||
|
|
||||||
const buffer = Buffer.concat(buffers);
|
const buffer = Buffer.concat(buffers);
|
||||||
|
|
||||||
const { formatFileInfo } = strapi.plugins.upload.services.upload;
|
const uploadService = strapi.plugins.upload.services.upload;
|
||||||
const fileInfo = formatFileInfo(
|
const fileInfo = uploadService.formatFileInfo(
|
||||||
{
|
{
|
||||||
filename,
|
filename,
|
||||||
type: mimetype,
|
type: mimetype,
|
||||||
|
|||||||
@ -29,53 +29,50 @@ const validateUploadBody = (schema, data = {}) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const isUploadDisabled = () => _.get(strapi.plugins, 'upload.config.enabled', true) === false;
|
||||||
|
|
||||||
|
const disabledPluginError = () =>
|
||||||
|
strapi.errors.badRequest(null, {
|
||||||
|
errors: [{ id: 'Upload.status.disabled', message: 'File upload is disabled' }],
|
||||||
|
});
|
||||||
|
|
||||||
|
const emptyFileError = () =>
|
||||||
|
strapi.errors.badRequest(null, {
|
||||||
|
errors: [{ id: 'Upload.status.empty', message: 'Files are empty' }],
|
||||||
|
});
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
async upload(ctx) {
|
async upload(ctx) {
|
||||||
const uploadService = strapi.plugins.upload.services.upload;
|
if (isUploadDisabled()) {
|
||||||
|
throw disabledPluginError();
|
||||||
// Retrieve provider configuration.
|
|
||||||
const { enabled } = strapi.plugins.upload.config;
|
|
||||||
|
|
||||||
// Verify if the file upload is enable.
|
|
||||||
if (enabled === false) {
|
|
||||||
throw strapi.errors.badRequest(null, {
|
|
||||||
errors: [{ id: 'Upload.status.disabled', message: 'File upload is disabled' }],
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const files = _.get(ctx.request.files, 'files');
|
const files = _.get(ctx.request.files, 'files');
|
||||||
|
|
||||||
if (_.isEmpty(files)) {
|
if (_.isEmpty(files)) {
|
||||||
throw strapi.errors.badRequest(null, {
|
throw emptyFileError();
|
||||||
errors: [{ id: 'Upload.status.empty', message: 'Files are empty' }],
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let data;
|
const { id } = ctx.query;
|
||||||
if (Array.isArray(files)) {
|
|
||||||
data = await validateUploadBody(multiUploadSchema, ctx.request.body);
|
const uploadService = strapi.plugins.upload.services.upload;
|
||||||
|
|
||||||
|
const validationSchema = Array.isArray(files) ? multiUploadSchema : uploadSchema;
|
||||||
|
const data = await validateUploadBody(validationSchema, ctx.request.body);
|
||||||
|
|
||||||
|
if (id) {
|
||||||
|
// cannot replace with more than one file
|
||||||
|
if (Array.isArray(files)) {
|
||||||
|
throw strapi.errors.badRequest(null, {
|
||||||
|
errors: [
|
||||||
|
{ id: 'Upload.replace.single', message: 'Cannot replace a file with multiple ones' },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.body = await uploadService.replace(id, { data, file: files });
|
||||||
} else {
|
} else {
|
||||||
data = await validateUploadBody(uploadSchema, ctx.request.body);
|
ctx.body = await uploadService.upload({ data, files });
|
||||||
}
|
}
|
||||||
|
|
||||||
const { refId, ref, source, field, path, fileInfo } = data;
|
|
||||||
|
|
||||||
const fileArray = Array.isArray(files) ? files : [files];
|
|
||||||
const fileInfoArray = Array.isArray(fileInfo) ? fileInfo : [fileInfo];
|
|
||||||
|
|
||||||
// Transform stream files to buffer
|
|
||||||
const enhancedFiles = await Promise.all(
|
|
||||||
fileArray.map((file, idx) => {
|
|
||||||
const fileInfo = fileInfoArray[idx] || {};
|
|
||||||
|
|
||||||
return uploadService.enhanceFile(file, fileInfo, { refId, ref, source, field, path });
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
const uploadedFiles = await uploadService.upload(enhancedFiles);
|
|
||||||
|
|
||||||
// Send 200 `ok`
|
|
||||||
ctx.send(uploadedFiles);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
async getSettings(ctx) {
|
async getSettings(ctx) {
|
||||||
|
|||||||
@ -58,7 +58,7 @@ module.exports = {
|
|||||||
return entity;
|
return entity;
|
||||||
},
|
},
|
||||||
|
|
||||||
async enhanceFile(file, fileInfo, metas) {
|
async enhanceFile(file, fileInfo = {}, metas = {}) {
|
||||||
const parts = await toArray(fs.createReadStream(file.path));
|
const parts = await toArray(fs.createReadStream(file.path));
|
||||||
const buffers = parts.map(part => (_.isBuffer(part) ? part : Buffer.from(part)));
|
const buffers = parts.map(part => (_.isBuffer(part) ? part : Buffer.from(part)));
|
||||||
|
|
||||||
@ -79,31 +79,52 @@ module.exports = {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
async upload(files) {
|
async upload({ data, files }) {
|
||||||
const config = strapi.plugins.upload.config;
|
const { fileInfo, ...metas } = data;
|
||||||
|
|
||||||
// upload a single file
|
const fileArray = Array.isArray(files) ? files : [files];
|
||||||
const uploadFile = async file => {
|
const fileInfoArray = Array.isArray(fileInfo) ? fileInfo : [fileInfo];
|
||||||
await strapi.plugins.upload.provider.upload(file);
|
|
||||||
|
|
||||||
delete file.buffer;
|
const doUpload = async (file, fileInfo) => {
|
||||||
file.provider = config.provider;
|
const fileData = await this.enhanceFile(file, fileInfo, metas);
|
||||||
|
|
||||||
const res = await this.add(file);
|
return this.uploadFileAndPersist(fileData);
|
||||||
|
|
||||||
strapi.eventHub.emit('media.create', { media: res });
|
|
||||||
return res;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Execute upload function of the provider for all files.
|
return await Promise.all(
|
||||||
return Promise.all(files.map(file => uploadFile(file)));
|
fileArray.map((file, idx) => doUpload(file, fileInfoArray[idx] || {}))
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
async replace(dbFile, file) {
|
async uploadFileAndPersist(fileData) {
|
||||||
|
const config = strapi.plugins.upload.config;
|
||||||
|
await strapi.plugins.upload.provider.upload(fileData);
|
||||||
|
|
||||||
|
delete fileData.buffer;
|
||||||
|
fileData.provider = config.provider;
|
||||||
|
|
||||||
|
const res = await this.add(fileData);
|
||||||
|
|
||||||
|
strapi.eventHub.emit('media.create', { media: res });
|
||||||
|
return res;
|
||||||
|
},
|
||||||
|
|
||||||
|
async replace(id, { data, file }) {
|
||||||
const config = strapi.plugins.upload.config;
|
const config = strapi.plugins.upload.config;
|
||||||
|
|
||||||
|
const dbFile = await this.fetch({ id });
|
||||||
|
|
||||||
|
if (!dbFile) {
|
||||||
|
throw new Error('file not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
const { fileInfo } = data;
|
||||||
|
const fileData = await this.enhanceFile(file, fileInfo);
|
||||||
|
|
||||||
|
// TODO: maybe check if same extension ??
|
||||||
|
|
||||||
// keep a constant hash
|
// keep a constant hash
|
||||||
_.assign(file, {
|
_.assign(fileData, {
|
||||||
hash: dbFile.hash,
|
hash: dbFile.hash,
|
||||||
ext: dbFile.ext,
|
ext: dbFile.ext,
|
||||||
});
|
});
|
||||||
@ -113,19 +134,19 @@ module.exports = {
|
|||||||
await strapi.plugins.upload.provider.delete(dbFile);
|
await strapi.plugins.upload.provider.delete(dbFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
await strapi.plugins.upload.provider.upload(file);
|
await strapi.plugins.upload.provider.upload(fileData);
|
||||||
|
|
||||||
delete file.buffer;
|
delete fileData.buffer;
|
||||||
file.provider = config.provider;
|
fileData.provider = config.provider;
|
||||||
|
|
||||||
const res = await this.update({ id: dbFile.id }, {});
|
const res = await this.update({ id }, fileData);
|
||||||
strapi.eventHub.emit('media.update', { media: res });
|
strapi.eventHub.emit('media.update', { media: res });
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
},
|
},
|
||||||
|
|
||||||
update(id, values) {
|
update(params, values) {
|
||||||
return strapi.query('file', 'upload').update({ id }, values);
|
return strapi.query('file', 'upload').update(params, values);
|
||||||
},
|
},
|
||||||
|
|
||||||
add(values) {
|
add(values) {
|
||||||
@ -133,9 +154,7 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
fetch(params) {
|
fetch(params) {
|
||||||
return strapi.query('file', 'upload').findOne({
|
return strapi.query('file', 'upload').findOne(params);
|
||||||
id: params.id,
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
fetchAll(params) {
|
fetchAll(params) {
|
||||||
@ -180,7 +199,7 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
).then(files => this.upload(files));
|
).then(files => this.uploadFileAndPersist(files));
|
||||||
},
|
},
|
||||||
|
|
||||||
async getConfig() {
|
async getConfig() {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user