200 lines
5.3 KiB
JavaScript
Raw Normal View History

'use strict';
const { assoc, has, prop, omit } = require('lodash/fp');
2021-04-29 13:51:12 +02:00
const strapiUtils = require('@strapi/utils');
const { sanitizeEntity } = strapiUtils;
const { hasDraftAndPublish } = strapiUtils.contentTypes;
const { PUBLISHED_AT_ATTRIBUTE, CREATED_BY_ATTRIBUTE } = strapiUtils.contentTypes.constants;
const { ENTRY_PUBLISH, ENTRY_UNPUBLISH } = strapiUtils.webhook.webhookEvents;
const omitPublishedAtField = omit(PUBLISHED_AT_ATTRIBUTE);
const emitEvent = (event, fn) => async (entity, model) => {
const result = await fn(entity, model);
const modelDef = strapi.getModel(model);
strapi.eventHub.emit(event, {
model: modelDef.modelName,
entry: sanitizeEntity(result, { model: modelDef }),
});
return result;
};
const findCreatorRoles = entity => {
const createdByPath = `${CREATED_BY_ATTRIBUTE}.id`;
if (has(createdByPath, entity)) {
const creatorId = prop(createdByPath, entity);
2021-06-22 17:13:11 +02:00
return strapi.query('strapi::role').findMany({ where: { users: { id: creatorId } } });
}
return [];
};
2021-07-28 15:32:21 +02:00
// TODO: define when we use this one vs basic populate
const getDeepPopulate = (uid, populate, depth = 0) => {
if (populate) {
return populate;
}
if (depth > 2) {
return {};
}
const { attributes } = strapi.getModel(uid);
return Object.keys(attributes).reduce((populateAcc, attributeName) => {
const attribute = attributes[attributeName];
if (attribute.type === 'relation') {
populateAcc[attributeName] = attribute.target
? { populate: getDeepPopulate(attribute.target, null, depth + 1) }
: true;
}
if (attribute.type === 'component') {
populateAcc[attributeName] = {
populate: getDeepPopulate(attribute.component, null, depth + 1),
};
}
if (attribute.type === 'dynamiczone') {
populateAcc[attributeName] = {
populate: (attribute.components || []).reduce((acc, componentUID) => {
return Object.assign(acc, getDeepPopulate(componentUID, null, depth + 1));
}, {}),
};
}
return populateAcc;
}, {});
};
// TODO: define when we use this one vs deep populate
const getBasePopulate = (uid, populate) => {
if (populate) {
return populate;
}
2021-07-08 18:15:32 +02:00
const { attributes } = strapi.getModel(uid);
return Object.keys(attributes).filter(attributeName => {
2021-07-08 21:53:30 +02:00
return ['relation', 'component', 'dynamiczone'].includes(attributes[attributeName].type);
2021-07-08 18:15:32 +02:00
});
};
module.exports = {
async assocCreatorRoles(entity) {
if (!entity) {
return entity;
}
const roles = await findCreatorRoles(entity);
return assoc(`${CREATED_BY_ATTRIBUTE}.roles`, roles, entity);
},
2021-06-30 20:00:03 +02:00
find(opts, uid, populate) {
2021-07-28 15:32:21 +02:00
const params = { ...opts, populate: getDeepPopulate(uid, populate) };
2021-06-30 20:00:03 +02:00
return strapi.entityService.find(uid, { params });
},
2021-06-30 20:00:03 +02:00
findPage(opts, uid, populate) {
2021-07-28 15:32:21 +02:00
const params = { ...opts, populate: getBasePopulate(uid, populate) };
2021-06-30 20:00:03 +02:00
return strapi.entityService.findPage(uid, { params });
},
2021-06-30 20:00:03 +02:00
findWithRelationCounts(opts, uid, populate) {
2021-07-28 15:32:21 +02:00
const params = { ...opts, populate: getBasePopulate(uid, populate) };
2021-06-30 20:00:03 +02:00
return strapi.entityService.findWithRelationCounts(uid, { params });
2020-12-16 15:28:11 +01:00
},
2021-06-30 20:00:03 +02:00
count(opts, uid) {
const params = { ...opts };
return strapi.entityService.count(uid, { params });
},
2021-06-30 20:00:03 +02:00
async findOne(id, uid, populate) {
2021-07-28 15:32:21 +02:00
const params = { populate: getBasePopulate(uid, populate) };
2021-07-08 18:15:32 +02:00
2021-07-05 23:31:23 +02:00
return strapi.entityService.findOne(uid, id, { params });
},
2021-06-30 20:00:03 +02:00
async findOneWithCreatorRoles(id, uid, populate) {
const entity = await this.findOne(id, uid, populate);
if (!entity) {
return entity;
}
return this.assocCreatorRoles(entity);
},
2021-06-30 20:00:03 +02:00
async create(body, uid) {
const modelDef = strapi.getModel(uid);
const publishData = { ...body };
if (hasDraftAndPublish(modelDef)) {
publishData[PUBLISHED_AT_ATTRIBUTE] = null;
}
2021-07-28 15:32:21 +02:00
const params = { populate: getBasePopulate(uid) };
2021-07-08 18:15:32 +02:00
return strapi.entityService.create(uid, { params, data: publishData });
},
2021-06-30 20:00:03 +02:00
update(entity, body, uid) {
const publishData = omitPublishedAtField(body);
2021-07-28 15:32:21 +02:00
const params = { populate: getBasePopulate(uid) };
2021-07-08 18:15:32 +02:00
return strapi.entityService.update(uid, entity.id, { params, data: publishData });
},
2021-06-30 20:00:03 +02:00
delete(entity, uid) {
2021-07-28 15:32:21 +02:00
const params = { populate: getBasePopulate(uid) };
2021-07-08 18:15:32 +02:00
return strapi.entityService.delete(uid, entity.id, { params });
},
2021-07-08 18:15:32 +02:00
// FIXME: handle relations
2021-07-05 23:31:23 +02:00
deleteMany(opts, uid) {
2021-06-30 20:00:03 +02:00
const params = { ...opts };
2021-07-05 23:31:23 +02:00
return strapi.entityService.deleteMany(uid, { params });
},
2021-06-30 20:00:03 +02:00
publish: emitEvent(ENTRY_PUBLISH, async (entity, uid) => {
if (entity[PUBLISHED_AT_ATTRIBUTE]) {
throw strapi.errors.badRequest('already.published');
}
// validate the entity is valid for publication
2021-06-30 20:00:03 +02:00
await strapi.entityValidator.validateEntityCreation(strapi.getModel(uid), entity);
const data = { [PUBLISHED_AT_ATTRIBUTE]: new Date() };
2021-07-28 15:32:21 +02:00
const params = { populate: getBasePopulate(uid) };
2021-07-08 18:15:32 +02:00
return strapi.entityService.update(uid, entity.id, { params, data });
}),
2021-06-30 20:00:03 +02:00
unpublish: emitEvent(ENTRY_UNPUBLISH, (entity, uid) => {
if (!entity[PUBLISHED_AT_ATTRIBUTE]) {
throw strapi.errors.badRequest('already.draft');
}
const data = { [PUBLISHED_AT_ATTRIBUTE]: null };
2021-07-28 15:32:21 +02:00
const params = { populate: getBasePopulate(uid) };
2021-07-08 18:15:32 +02:00
return strapi.entityService.update(uid, entity.id, { params, data });
}),
};