211 lines
6.3 KiB
JavaScript
Raw Normal View History

'use strict';
2023-05-25 14:36:50 +02:00
const { omit } = require('lodash/fp');
2021-04-29 13:51:12 +02:00
const strapiUtils = require('@strapi/utils');
const { mapAsync } = require('@strapi/utils');
2021-10-20 17:30:05 +02:00
const { ApplicationError } = require('@strapi/utils').errors;
2023-05-26 17:26:55 +02:00
const { getService } = require('../utils');
2022-10-05 18:42:50 +02:00
const { getDeepPopulate, getDeepPopulateDraftCount } = require('./utils/populate');
const { getDeepRelationsCount } = require('./utils/count');
2022-10-05 18:42:50 +02:00
const { sumDraftCounts } = require('./utils/draft');
2023-05-26 17:26:55 +02:00
const { isWebhooksPopulateRelationsEnabled } = require('./utils/populate');
2022-10-05 18:42:50 +02:00
const { hasDraftAndPublish } = strapiUtils.contentTypes;
2023-05-25 14:36:50 +02:00
const { PUBLISHED_AT_ATTRIBUTE } = strapiUtils.contentTypes.constants;
const { ENTRY_PUBLISH, ENTRY_UNPUBLISH } = strapiUtils.webhook.webhookEvents;
const omitPublishedAtField = omit(PUBLISHED_AT_ATTRIBUTE);
2023-01-30 16:35:45 +01:00
const emitEvent = async (event, entity, modelUid) => {
const modelDef = strapi.getModel(modelUid);
2021-11-10 17:08:54 +01:00
const sanitizedEntity = await strapiUtils.sanitize.sanitizers.defaultSanitizeOutput(
modelDef,
entity
);
strapi.eventHub.emit(event, {
model: modelDef.modelName,
entry: sanitizedEntity,
});
};
2023-05-26 12:35:22 +02:00
const buildCreateOrUpdatePopulate = (uid) => {
// User can configure to populate relations, so downstream services can use them.
// They will be transformed into counts later if this is set to true.
2023-05-26 17:26:55 +02:00
return getService('populate-builder')(uid)
2023-05-26 12:35:22 +02:00
.populateDeep(Infinity)
2023-05-26 17:26:55 +02:00
.countRelationsIf(isWebhooksPopulateRelationsEnabled(uid))
2023-05-26 12:35:22 +02:00
.build();
};
/**
* @type {import('./entity-manager').default}
*/
2021-07-13 18:46:36 +02:00
module.exports = ({ strapi }) => ({
/**
* Extend this function from other plugins to add custom mapping of entity
* responses
* @param {Object} entity
* @returns
*/
mapEntity(entity) {
return entity;
},
2023-02-27 11:50:49 +00:00
/**
2023-03-01 11:31:52 +00:00
* Some entity manager functions may return multiple entities or one entity.
2023-02-27 11:50:49 +00:00
* This function maps the response in both cases
* @param {Array|Object|null} entities
* @param {string} uid
*/
2023-03-01 11:31:52 +00:00
async mapEntitiesResponse(entities, uid) {
2023-02-27 11:50:49 +00:00
if (entities?.results) {
const mappedResults = await mapAsync(entities.results, (entity) =>
this.mapEntity(entity, uid)
);
return { ...entities, results: mappedResults };
}
// if entity is single type
return this.mapEntity(entities, uid);
},
async find(opts, uid) {
const params = { ...opts, populate: getDeepPopulate(uid) };
const entities = await strapi.entityService.findMany(uid, params);
2023-03-01 11:31:52 +00:00
return this.mapEntitiesResponse(entities, uid);
},
async findPage(opts, uid) {
2023-05-25 14:36:50 +02:00
const entities = await strapi.entityService.findPage(uid, opts);
2023-03-01 11:31:52 +00:00
return this.mapEntitiesResponse(entities, uid);
2020-12-16 15:28:11 +01:00
},
2023-05-25 14:36:50 +02:00
async findOne(id, uid, opts = {}) {
return strapi.entityService
2023-05-25 14:36:50 +02:00
.findOne(uid, id, opts)
.then((entity) => this.mapEntity(entity, uid));
2022-08-26 10:41:31 +02:00
},
2023-05-26 12:35:22 +02:00
async create(body, uid) {
2021-06-30 20:00:03 +02:00
const modelDef = strapi.getModel(uid);
const publishData = { ...body };
2023-05-26 12:35:22 +02:00
const populate = await buildCreateOrUpdatePopulate(uid);
if (hasDraftAndPublish(modelDef)) {
publishData[PUBLISHED_AT_ATTRIBUTE] = null;
}
2023-05-26 12:35:22 +02:00
const params = { data: publishData, populate };
2021-07-08 18:15:32 +02:00
const entity = await strapi.entityService
.create(uid, params)
.then((entity) => this.mapEntity(entity, uid));
2023-05-26 17:26:55 +02:00
if (isWebhooksPopulateRelationsEnabled(uid)) {
return getDeepRelationsCount(entity, uid);
}
2023-02-14 18:20:16 +01:00
return entity;
},
2023-05-26 12:35:22 +02:00
async update(entity, body, uid) {
const publishData = omitPublishedAtField(body);
2023-05-26 12:35:22 +02:00
const populate = await buildCreateOrUpdatePopulate(uid);
const params = { data: publishData, populate };
2021-07-08 18:15:32 +02:00
const updatedEntity = await strapi.entityService
.update(uid, entity.id, params)
.then((entity) => this.mapEntity(entity, uid));
2023-05-26 17:26:55 +02:00
if (isWebhooksPopulateRelationsEnabled(uid)) {
return getDeepRelationsCount(updatedEntity, uid);
}
return updatedEntity;
},
2023-05-25 14:36:50 +02:00
async delete(entity, uid, opts = {}) {
const deletedEntity = await strapi.entityService.delete(uid, entity.id, opts);
2023-01-30 16:35:45 +01:00
// If relations were populated, relations count will be returned instead of the array of relations.
2023-05-26 17:26:55 +02:00
if (isWebhooksPopulateRelationsEnabled(uid)) {
return getDeepRelationsCount(deletedEntity, uid);
}
return deletedEntity;
},
2021-07-08 18:15:32 +02:00
// FIXME: handle relations
2021-07-05 23:31:23 +02:00
deleteMany(opts, uid) {
2023-05-25 14:36:50 +02:00
return strapi.entityService.deleteMany(uid, opts);
},
2023-05-26 12:35:22 +02:00
async publish(entity, body = {}, uid) {
if (entity[PUBLISHED_AT_ATTRIBUTE]) {
2021-10-20 17:30:05 +02:00
throw new ApplicationError('already.published');
}
// validate the entity is valid for publication
await strapi.entityValidator.validateEntityCreation(
strapi.getModel(uid),
entity,
undefined,
entity
);
const data = { ...body, [PUBLISHED_AT_ATTRIBUTE]: new Date() };
2023-05-26 12:35:22 +02:00
const populate = await buildCreateOrUpdatePopulate(uid);
2023-05-25 14:36:50 +02:00
2023-05-26 12:35:22 +02:00
const params = { data, populate };
2021-07-08 18:15:32 +02:00
2023-01-30 16:35:45 +01:00
const updatedEntity = await strapi.entityService.update(uid, entity.id, params);
2023-03-03 14:02:56 +01:00
await emitEvent(ENTRY_PUBLISH, updatedEntity, uid);
2023-01-30 16:35:45 +01:00
const mappedEntity = await this.mapEntity(updatedEntity, uid);
2023-01-30 16:35:45 +01:00
// If relations were populated, relations count will be returned instead of the array of relations.
2023-05-26 17:26:55 +02:00
if (isWebhooksPopulateRelationsEnabled(uid)) {
return getDeepRelationsCount(mappedEntity, uid);
2023-01-30 16:35:45 +01:00
}
return mappedEntity;
2023-01-30 16:35:45 +01:00
},
2023-01-30 16:35:45 +01:00
async unpublish(entity, body = {}, uid) {
if (!entity[PUBLISHED_AT_ATTRIBUTE]) {
2021-10-20 17:30:05 +02:00
throw new ApplicationError('already.draft');
}
const data = { ...body, [PUBLISHED_AT_ATTRIBUTE]: null };
2023-05-26 12:35:22 +02:00
const populate = await buildCreateOrUpdatePopulate(uid);
2023-05-26 12:35:22 +02:00
const params = { data, populate };
2021-07-08 18:15:32 +02:00
2023-01-30 16:35:45 +01:00
const updatedEntity = await strapi.entityService.update(uid, entity.id, params);
await emitEvent(ENTRY_UNPUBLISH, updatedEntity, uid);
2023-01-30 16:35:45 +01:00
const mappedEntity = await this.mapEntity(updatedEntity, uid);
2023-01-30 16:35:45 +01:00
// If relations were populated, relations count will be returned instead of the array of relations.
2023-05-26 17:26:55 +02:00
if (isWebhooksPopulateRelationsEnabled(uid)) {
return getDeepRelationsCount(mappedEntity, uid);
2023-01-30 16:35:45 +01:00
}
return mappedEntity;
2023-01-30 16:35:45 +01:00
},
2022-10-05 18:42:50 +02:00
async getNumberOfDraftRelations(id, uid) {
const { populate, hasRelations } = getDeepPopulateDraftCount(uid);
if (!hasRelations) {
return 0;
}
const entity = await strapi.entityService.findOne(uid, id, { populate });
return sumDraftCounts(entity, uid);
},
2021-07-13 18:46:36 +02:00
});