mirror of
https://github.com/strapi/strapi.git
synced 2025-07-24 17:40:18 +00:00
Remove multipart
Signed-off-by: Alexandre Bodin <bodin.alex@gmail.com>
This commit is contained in:
parent
f1789cc1b9
commit
02c7d97ffc
@ -2,9 +2,6 @@
|
||||
|
||||
const _ = require('lodash');
|
||||
|
||||
const parseMultipartBody = require('../../utils/parse-multipart');
|
||||
const uploadFiles = require('../../utils/upload-files');
|
||||
|
||||
module.exports = async (ctx, next) => {
|
||||
const { model } = ctx.params;
|
||||
|
||||
@ -22,24 +19,6 @@ module.exports = async (ctx, next) => {
|
||||
const [controller, action] = _.get(target, actionPath, []).split('.');
|
||||
|
||||
if (controller && action) {
|
||||
if (ctx.is('multipart')) {
|
||||
const { data, files } = parseMultipartBody(ctx);
|
||||
ctx.request.body = data;
|
||||
ctx.request.files = {};
|
||||
|
||||
await target.controllers[controller.toLowerCase()][action](ctx);
|
||||
const resBody = ctx.body;
|
||||
|
||||
if (ctx.status >= 300) return;
|
||||
|
||||
await uploadFiles(resBody, files, {
|
||||
model: ct.modelName,
|
||||
source: ct.plugin,
|
||||
});
|
||||
|
||||
return ctx.send(resBody);
|
||||
}
|
||||
|
||||
return await target.controllers[controller.toLowerCase()][action](ctx);
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ const { has, pipe } = require('lodash/fp');
|
||||
const {
|
||||
getService,
|
||||
wrapBadRequest,
|
||||
parseBody,
|
||||
setCreatorFields,
|
||||
pickWritableAttributes,
|
||||
} = require('../utils');
|
||||
@ -16,6 +15,7 @@ module.exports = {
|
||||
const { model } = ctx.params;
|
||||
const { query } = ctx.request;
|
||||
|
||||
const entityManager = getService('entity-manager');
|
||||
const permissionChecker = getService('permission-checker').create({ userAbility, model });
|
||||
|
||||
if (permissionChecker.cannot.read()) {
|
||||
@ -26,10 +26,7 @@ module.exports = {
|
||||
|
||||
const permissionQuery = permissionChecker.buildPermissionQuery(query);
|
||||
|
||||
const { results, pagination } = await getService('entity-manager')[method](
|
||||
permissionQuery,
|
||||
model
|
||||
);
|
||||
const { results, pagination } = await entityManager[method](permissionQuery, model);
|
||||
|
||||
ctx.body = {
|
||||
results: results.map(entity => permissionChecker.sanitizeOutput(entity)),
|
||||
@ -41,13 +38,14 @@ module.exports = {
|
||||
const { userAbility } = ctx.state;
|
||||
const { model, id } = ctx.params;
|
||||
|
||||
const entityManager = getService('entity-manager');
|
||||
const permissionChecker = getService('permission-checker').create({ userAbility, model });
|
||||
|
||||
if (permissionChecker.cannot.read()) {
|
||||
return ctx.forbidden();
|
||||
}
|
||||
|
||||
const entity = await getService('entity-manager').findOneWithCreatorRoles(id, model);
|
||||
const entity = await entityManager.findOneWithCreatorRoles(id, model);
|
||||
|
||||
if (!entity) {
|
||||
return ctx.notFound();
|
||||
@ -63,8 +61,9 @@ module.exports = {
|
||||
async create(ctx) {
|
||||
const { userAbility, user } = ctx.state;
|
||||
const { model } = ctx.params;
|
||||
const { files, data } = parseBody(ctx);
|
||||
const { body } = ctx.request;
|
||||
|
||||
const entityManager = getService('entity-manager');
|
||||
const permissionChecker = getService('permission-checker').create({ userAbility, model });
|
||||
|
||||
if (permissionChecker.cannot.create()) {
|
||||
@ -78,10 +77,7 @@ module.exports = {
|
||||
const sanitizeFn = pipe([pickWritables, pickPermittedFields, setCreator]);
|
||||
|
||||
await wrapBadRequest(async () => {
|
||||
const entity = await getService('entity-manager').create(
|
||||
{ data: sanitizeFn(data), files },
|
||||
model
|
||||
);
|
||||
const entity = await entityManager.create(sanitizeFn(body), model);
|
||||
ctx.body = permissionChecker.sanitizeOutput(entity);
|
||||
|
||||
await strapi.telemetry.send('didCreateFirstContentTypeEntry', { model });
|
||||
@ -91,15 +87,16 @@ module.exports = {
|
||||
async update(ctx) {
|
||||
const { userAbility, user } = ctx.state;
|
||||
const { id, model } = ctx.params;
|
||||
const { files, data } = parseBody(ctx);
|
||||
const { body } = ctx.request;
|
||||
|
||||
const entityManager = getService('entity-manager');
|
||||
const permissionChecker = getService('permission-checker').create({ userAbility, model });
|
||||
|
||||
if (permissionChecker.cannot.update()) {
|
||||
return ctx.forbidden();
|
||||
}
|
||||
|
||||
const entity = await getService('entity-manager').findOneWithCreatorRoles(id, model);
|
||||
const entity = await entityManager.findOneWithCreatorRoles(id, model);
|
||||
|
||||
if (!entity) {
|
||||
return ctx.notFound();
|
||||
@ -116,11 +113,7 @@ module.exports = {
|
||||
const sanitizeFn = pipe([pickWritables, pickPermittedFields, setCreator]);
|
||||
|
||||
await wrapBadRequest(async () => {
|
||||
const updatedEntity = await getService('entity-manager').update(
|
||||
entity,
|
||||
{ data: sanitizeFn(data), files },
|
||||
model
|
||||
);
|
||||
const updatedEntity = await entityManager.update(entity, sanitizeFn(body), model);
|
||||
|
||||
ctx.body = permissionChecker.sanitizeOutput(updatedEntity);
|
||||
})();
|
||||
@ -130,13 +123,14 @@ module.exports = {
|
||||
const { userAbility } = ctx.state;
|
||||
const { id, model } = ctx.params;
|
||||
|
||||
const entityManager = getService('entity-manager');
|
||||
const permissionChecker = getService('permission-checker').create({ userAbility, model });
|
||||
|
||||
if (permissionChecker.cannot.delete()) {
|
||||
return ctx.forbidden();
|
||||
}
|
||||
|
||||
const entity = await getService('entity-manager').findOneWithCreatorRoles(id, model);
|
||||
const entity = await entityManager.findOneWithCreatorRoles(id, model);
|
||||
|
||||
if (!entity) {
|
||||
return ctx.notFound();
|
||||
@ -146,7 +140,7 @@ module.exports = {
|
||||
return ctx.forbidden();
|
||||
}
|
||||
|
||||
const result = await getService('entity-manager').delete(entity, model);
|
||||
const result = await entityManager.delete(entity, model);
|
||||
|
||||
ctx.body = permissionChecker.sanitizeOutput(result);
|
||||
},
|
||||
@ -155,13 +149,14 @@ module.exports = {
|
||||
const { userAbility } = ctx.state;
|
||||
const { id, model } = ctx.params;
|
||||
|
||||
const entityManager = getService('entity-manager');
|
||||
const permissionChecker = getService('permission-checker').create({ userAbility, model });
|
||||
|
||||
if (permissionChecker.cannot.publish()) {
|
||||
return ctx.forbidden();
|
||||
}
|
||||
|
||||
const entity = await getService('entity-manager').findOneWithCreatorRoles(id, model);
|
||||
const entity = await entityManager.findOneWithCreatorRoles(id, model);
|
||||
|
||||
if (!entity) {
|
||||
return ctx.notFound();
|
||||
@ -171,7 +166,7 @@ module.exports = {
|
||||
return ctx.forbidden();
|
||||
}
|
||||
|
||||
const result = await getService('entity-manager').publish(entity, model);
|
||||
const result = await entityManager.publish(entity, model);
|
||||
|
||||
ctx.body = permissionChecker.sanitizeOutput(result);
|
||||
},
|
||||
@ -180,13 +175,14 @@ module.exports = {
|
||||
const { userAbility } = ctx.state;
|
||||
const { id, model } = ctx.params;
|
||||
|
||||
const entityManager = getService('entity-manager');
|
||||
const permissionChecker = getService('permission-checker').create({ userAbility, model });
|
||||
|
||||
if (permissionChecker.cannot.unpublish()) {
|
||||
return ctx.forbidden();
|
||||
}
|
||||
|
||||
const entity = await getService('entity-manager').findOneWithCreatorRoles(id, model);
|
||||
const entity = await entityManager.findOneWithCreatorRoles(id, model);
|
||||
|
||||
if (!entity) {
|
||||
return ctx.notFound();
|
||||
@ -196,7 +192,7 @@ module.exports = {
|
||||
return ctx.forbidden();
|
||||
}
|
||||
|
||||
const result = await getService('entity-manager').unpublish(entity, model);
|
||||
const result = await entityManager.unpublish(entity, model);
|
||||
|
||||
ctx.body = permissionChecker.sanitizeOutput(result);
|
||||
},
|
||||
@ -207,6 +203,7 @@ module.exports = {
|
||||
const { query, body } = ctx.request;
|
||||
const { ids } = body;
|
||||
|
||||
const entityManager = getService('entity-manager');
|
||||
const permissionChecker = getService('permission-checker').create({ userAbility, model });
|
||||
|
||||
if (permissionChecker.cannot.delete()) {
|
||||
@ -222,7 +219,7 @@ module.exports = {
|
||||
_where: [idsWhereClause].concat(permissionQuery._where || {}),
|
||||
};
|
||||
|
||||
const results = await strapi.entityService.delete({ params }, { model });
|
||||
const results = await entityManager.findAndDelete(params, model);
|
||||
|
||||
ctx.body = results.map(result => permissionChecker.sanitizeOutput(result));
|
||||
},
|
||||
|
@ -4,7 +4,6 @@ const { pipe } = require('lodash/fp');
|
||||
const {
|
||||
getService,
|
||||
wrapBadRequest,
|
||||
parseBody,
|
||||
setCreatorFields,
|
||||
pickWritableAttributes,
|
||||
} = require('../utils');
|
||||
@ -48,9 +47,9 @@ module.exports = {
|
||||
async createOrUpdate(ctx) {
|
||||
const { user, userAbility } = ctx.state;
|
||||
const { model } = ctx.params;
|
||||
const { body } = ctx.request;
|
||||
|
||||
const { data, files } = parseBody(ctx);
|
||||
|
||||
const entityManager = getService('entity-manager');
|
||||
const permissionChecker = getService('permission-checker').create({ userAbility, model });
|
||||
|
||||
if (permissionChecker.cannot.create() && permissionChecker.cannot.update()) {
|
||||
@ -73,11 +72,7 @@ module.exports = {
|
||||
|
||||
await wrapBadRequest(async () => {
|
||||
if (!entity) {
|
||||
const entity = await getService('entity-manager').create(
|
||||
{ data: sanitizeFn(data), files },
|
||||
model
|
||||
);
|
||||
|
||||
const entity = await entityManager.create(sanitizeFn(body), model);
|
||||
ctx.body = permissionChecker.sanitizeOutput(entity);
|
||||
|
||||
await strapi.telemetry.send('didCreateFirstContentTypeEntry', { model });
|
||||
@ -88,12 +83,7 @@ module.exports = {
|
||||
return ctx.forbidden();
|
||||
}
|
||||
|
||||
const updatedEntity = await getService('entity-manager').update(
|
||||
entity,
|
||||
{ data: sanitizeFn(data), files },
|
||||
model
|
||||
);
|
||||
|
||||
const updatedEntity = await entityManager.update(entity, sanitizeFn(body), model);
|
||||
ctx.body = permissionChecker.sanitizeOutput(updatedEntity);
|
||||
})();
|
||||
},
|
||||
@ -102,6 +92,7 @@ module.exports = {
|
||||
const { userAbility } = ctx.state;
|
||||
const { model } = ctx.params;
|
||||
|
||||
const entityManager = getService('entity-manager');
|
||||
const permissionChecker = getService('permission-checker').create({ userAbility, model });
|
||||
|
||||
if (permissionChecker.cannot.delete()) {
|
||||
@ -118,7 +109,7 @@ module.exports = {
|
||||
return ctx.forbidden();
|
||||
}
|
||||
|
||||
const deletedEntity = await getService('entity-manager').delete(entity, model);
|
||||
const deletedEntity = await entityManager.delete(entity, model);
|
||||
|
||||
ctx.body = permissionChecker.sanitizeOutput(deletedEntity);
|
||||
},
|
||||
@ -127,6 +118,7 @@ module.exports = {
|
||||
const { userAbility } = ctx.state;
|
||||
const { model } = ctx.params;
|
||||
|
||||
const entityManager = getService('entity-manager');
|
||||
const permissionChecker = getService('permission-checker').create({ userAbility, model });
|
||||
|
||||
if (permissionChecker.cannot.publish()) {
|
||||
@ -143,7 +135,7 @@ module.exports = {
|
||||
return ctx.forbidden();
|
||||
}
|
||||
|
||||
const publishedEntity = await getService('entity-manager').publish(entity, model);
|
||||
const publishedEntity = await entityManager.publish(entity, model);
|
||||
|
||||
ctx.body = permissionChecker.sanitizeOutput(publishedEntity);
|
||||
},
|
||||
@ -152,6 +144,7 @@ module.exports = {
|
||||
const { userAbility } = ctx.state;
|
||||
const { model } = ctx.params;
|
||||
|
||||
const entityManager = getService('entity-manager');
|
||||
const permissionChecker = getService('permission-checker').create({ userAbility, model });
|
||||
|
||||
if (permissionChecker.cannot.unpublish()) {
|
||||
@ -168,7 +161,7 @@ module.exports = {
|
||||
return ctx.forbidden();
|
||||
}
|
||||
|
||||
const unpublishedEntity = await getService('entity-manager').unpublish(entity, model);
|
||||
const unpublishedEntity = await entityManager.unpublish(entity, model);
|
||||
|
||||
ctx.body = permissionChecker.sanitizeOutput(unpublishedEntity);
|
||||
},
|
||||
|
@ -79,23 +79,21 @@ module.exports = {
|
||||
},
|
||||
|
||||
async create(body, model) {
|
||||
const { data, files } = body;
|
||||
|
||||
const modelDef = strapi.getModel(model);
|
||||
const publishData = { ...data };
|
||||
const publishData = { ...body };
|
||||
|
||||
if (hasDraftAndPublish(modelDef)) {
|
||||
publishData[PUBLISHED_AT_ATTRIBUTE] = null;
|
||||
}
|
||||
|
||||
return strapi.entityService.create({ data: publishData, files }, { model });
|
||||
return strapi.entityService.create({ data: publishData }, { model });
|
||||
},
|
||||
|
||||
update(entity, { data, files }, model) {
|
||||
update(entity, body, model) {
|
||||
const params = { id: entity.id };
|
||||
const publishData = omitPublishedAtField(data);
|
||||
const publishData = omitPublishedAtField(body);
|
||||
|
||||
return strapi.entityService.update({ params, data: publishData, files }, { model });
|
||||
return strapi.entityService.update({ params, data: publishData }, { model });
|
||||
},
|
||||
|
||||
delete(entity, model) {
|
||||
@ -103,6 +101,10 @@ module.exports = {
|
||||
return strapi.entityService.delete({ params }, { model });
|
||||
},
|
||||
|
||||
findAnddelete(params, model) {
|
||||
return strapi.entityService.delete({ params }, { model });
|
||||
},
|
||||
|
||||
publish: emitEvent(ENTRY_PUBLISH, async (entity, model) => {
|
||||
if (entity[PUBLISHED_AT_ATTRIBUTE]) {
|
||||
throw strapi.errors.badRequest('already.published');
|
||||
|
@ -1,7 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
const { prop } = require('lodash/fp');
|
||||
const parseBody = require('./parse-body');
|
||||
const wrapBadRequest = require('./wrap-bad-request');
|
||||
const setCreatorFields = require('./set-creator-fields');
|
||||
const pickWritableAttributes = require('./pick-writable-attributes');
|
||||
@ -13,7 +12,6 @@ const getService = name => {
|
||||
|
||||
module.exports = {
|
||||
getService,
|
||||
parseBody,
|
||||
wrapBadRequest,
|
||||
setCreatorFields,
|
||||
pickWritableAttributes,
|
||||
|
@ -1,8 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const parseMultipartBody = require('./parse-multipart');
|
||||
|
||||
module.exports = ctx => {
|
||||
const { body } = ctx.request;
|
||||
return ctx.is('multipart') ? parseMultipartBody(ctx) : { data: body };
|
||||
};
|
@ -1,41 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const _ = require('lodash');
|
||||
|
||||
module.exports = ctx => {
|
||||
const { body = {}, files = {} } = ctx.request;
|
||||
|
||||
if (!body.data) {
|
||||
throw strapi.errors.badRequest(
|
||||
`When using multipart/form-data you need to provide your data in a JSON 'data' field.`
|
||||
);
|
||||
}
|
||||
|
||||
let data;
|
||||
try {
|
||||
data = JSON.parse(body.data);
|
||||
} catch (error) {
|
||||
throw strapi.errors.badRequest(
|
||||
`Invalid 'data' field. 'data' should be a valid JSON.`
|
||||
);
|
||||
}
|
||||
|
||||
const filesToUpload = Object.keys(files).reduce((acc, key) => {
|
||||
const fullPath = _.toPath(key);
|
||||
|
||||
if (fullPath.length <= 1 || fullPath[0] !== 'files') {
|
||||
throw strapi.errors.badRequest(
|
||||
`When using multipart/form-data you need to provide your files by prefixing them witht the 'files'.`
|
||||
);
|
||||
}
|
||||
|
||||
const path = _.tail(fullPath);
|
||||
acc[path.join('.')] = files[key];
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
return {
|
||||
data,
|
||||
files: filesToUpload,
|
||||
};
|
||||
};
|
@ -1,71 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const _ = require('lodash');
|
||||
|
||||
module.exports = async (entry, files, { model, source }) => {
|
||||
const entity = strapi.getModel(model, source);
|
||||
|
||||
if (!_.has(strapi.plugins, 'upload')) return entry;
|
||||
|
||||
const uploadService = strapi.plugins.upload.services.upload;
|
||||
|
||||
const findModelFromUploadPath = path => {
|
||||
if (path.length === 0) return { model, source };
|
||||
|
||||
let currentPath = [];
|
||||
let tmpModel = entity;
|
||||
let modelName = model;
|
||||
let sourceName;
|
||||
|
||||
for (let i = 0; i < path.length; i++) {
|
||||
if (!tmpModel) return {};
|
||||
const part = path[i];
|
||||
const attr = tmpModel.attributes[part];
|
||||
|
||||
currentPath.push(part);
|
||||
|
||||
// ignore array indexes => handled in the dynamic zone section
|
||||
if (_.isFinite(_.toNumber(path[i]))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!attr) return {};
|
||||
|
||||
if (attr.type === 'component') {
|
||||
modelName = attr.component;
|
||||
tmpModel = strapi.components[attr.component];
|
||||
} else if (attr.type === 'dynamiczone') {
|
||||
const entryIdx = path[i + 1]; // get component index
|
||||
const value = _.get(entry, [...currentPath, entryIdx]);
|
||||
|
||||
if (!value) return {};
|
||||
|
||||
modelName = value.__component; // get component type
|
||||
tmpModel = strapi.components[modelName];
|
||||
} else if (_.has(attr, 'model') || _.has(attr, 'collection')) {
|
||||
sourceName = attr.plugin;
|
||||
modelName = attr.model || attr.collection;
|
||||
tmpModel = strapi.getModel(attr.model || attr.collection, source);
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
return { model: modelName, source: sourceName };
|
||||
};
|
||||
|
||||
const doUpload = async (key, files) => {
|
||||
const parts = key.split('.');
|
||||
const [path, field] = [_.initial(parts), _.last(parts)];
|
||||
|
||||
const { model, source } = findModelFromUploadPath(path);
|
||||
|
||||
if (model) {
|
||||
const id = _.get(entry, path.concat('id'));
|
||||
|
||||
return uploadService.uploadToEntity({ id, model, field }, files, source);
|
||||
}
|
||||
};
|
||||
|
||||
await Promise.all(Object.keys(files).map(key => doUpload(key, files[key])));
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user