2021-08-24 12:10:47 +02:00
|
|
|
'use strict';
|
|
|
|
|
2021-11-04 15:47:53 +01:00
|
|
|
const { get } = require('lodash/fp');
|
|
|
|
|
2021-11-05 10:40:11 +01:00
|
|
|
const utils = require('@strapi/utils');
|
|
|
|
|
2021-11-08 15:53:58 +01:00
|
|
|
const { sanitize, pipeAsync } = utils;
|
2021-11-05 10:40:11 +01:00
|
|
|
const { ApplicationError } = utils.errors;
|
2021-11-04 15:47:53 +01:00
|
|
|
|
2021-08-24 17:56:44 +02:00
|
|
|
module.exports = ({ strapi }) => {
|
2021-09-22 14:39:36 +02:00
|
|
|
const { service: getGraphQLService } = strapi.plugin('graphql');
|
|
|
|
|
|
|
|
const { isMorphRelation, isMedia } = getGraphQLService('utils').attributes;
|
|
|
|
const { transformArgs } = getGraphQLService('builders').utils;
|
|
|
|
const { toEntityResponse, toEntityResponseCollection } = getGraphQLService('format').returnTypes;
|
2021-08-24 12:10:47 +02:00
|
|
|
|
2021-08-24 17:56:44 +02:00
|
|
|
return {
|
2021-09-22 14:39:36 +02:00
|
|
|
buildAssociationResolver({ contentTypeUID, attributeName }) {
|
2021-08-24 17:56:44 +02:00
|
|
|
const contentType = strapi.getModel(contentTypeUID);
|
|
|
|
const attribute = contentType.attributes[attributeName];
|
2021-08-24 12:10:47 +02:00
|
|
|
|
2021-08-24 17:56:44 +02:00
|
|
|
if (!attribute) {
|
2021-10-27 18:54:58 +02:00
|
|
|
throw new ApplicationError(
|
2021-08-24 17:56:44 +02:00
|
|
|
`Failed to build an association resolver for ${contentTypeUID}::${attributeName}`
|
|
|
|
);
|
|
|
|
}
|
2021-08-24 12:10:47 +02:00
|
|
|
|
2021-08-24 17:56:44 +02:00
|
|
|
const isMediaAttribute = isMedia(attribute);
|
|
|
|
const isMorphAttribute = isMorphRelation(attribute);
|
2021-08-24 12:10:47 +02:00
|
|
|
|
2021-08-24 17:56:44 +02:00
|
|
|
const targetUID = isMediaAttribute ? 'plugins::upload.file' : attribute.target;
|
|
|
|
const isToMany = isMediaAttribute ? attribute.multiple : attribute.relation.endsWith('Many');
|
2021-08-24 12:10:47 +02:00
|
|
|
|
2021-08-24 17:56:44 +02:00
|
|
|
const targetContentType = strapi.getModel(targetUID);
|
2021-08-24 12:10:47 +02:00
|
|
|
|
2022-08-08 23:33:39 +02:00
|
|
|
return async (parent, args = {}, context = {}) => {
|
2021-11-04 15:47:53 +01:00
|
|
|
const { auth } = context.state;
|
|
|
|
|
2021-08-24 17:56:44 +02:00
|
|
|
const transformedArgs = transformArgs(args, {
|
|
|
|
contentType: targetContentType,
|
|
|
|
usePagination: true,
|
|
|
|
});
|
2021-08-24 12:10:47 +02:00
|
|
|
|
2023-02-09 11:35:50 +01:00
|
|
|
const sanitizedQuery = await sanitize.contentAPI.query(transformedArgs, targetContentType, {
|
|
|
|
auth,
|
|
|
|
});
|
|
|
|
|
2021-09-10 10:24:33 +02:00
|
|
|
const data = await strapi.entityService.load(
|
2021-08-24 17:56:44 +02:00
|
|
|
contentTypeUID,
|
2021-09-01 12:06:51 +02:00
|
|
|
parent,
|
2021-08-24 17:56:44 +02:00
|
|
|
attributeName,
|
2023-02-09 11:35:50 +01:00
|
|
|
sanitizedQuery
|
2021-08-24 17:56:44 +02:00
|
|
|
);
|
2021-08-24 12:10:47 +02:00
|
|
|
|
2021-09-22 14:39:36 +02:00
|
|
|
const info = {
|
2023-02-09 11:35:50 +01:00
|
|
|
args: sanitizedQuery,
|
2021-09-22 14:39:36 +02:00
|
|
|
resourceUID: targetUID,
|
|
|
|
};
|
|
|
|
|
2021-11-04 15:47:53 +01:00
|
|
|
// If this a polymorphic association, it sanitizes & returns the raw data
|
|
|
|
// Note: The value needs to be wrapped in a fake object that represents its parent
|
|
|
|
// so that the sanitize util can work properly.
|
2021-08-24 17:56:44 +02:00
|
|
|
if (isMorphAttribute) {
|
2021-11-04 15:47:53 +01:00
|
|
|
// Helpers used for the data cleanup
|
2022-08-08 23:33:39 +02:00
|
|
|
const wrapData = (dataToWrap) => ({ [attributeName]: dataToWrap });
|
|
|
|
const sanitizeData = (dataToSanitize) => {
|
2021-11-04 15:47:53 +01:00
|
|
|
return sanitize.contentAPI.output(dataToSanitize, contentType, { auth });
|
|
|
|
};
|
|
|
|
const unwrapData = get(attributeName);
|
|
|
|
|
|
|
|
// Sanitizer definition
|
2021-11-04 16:43:27 +01:00
|
|
|
const sanitizeMorphAttribute = pipeAsync(wrapData, sanitizeData, unwrapData);
|
2021-11-04 15:47:53 +01:00
|
|
|
|
|
|
|
return sanitizeMorphAttribute(data);
|
2021-08-24 17:56:44 +02:00
|
|
|
}
|
2021-08-24 12:10:47 +02:00
|
|
|
|
2021-08-24 17:56:44 +02:00
|
|
|
// If this is a to-many relation, it returns an object that
|
|
|
|
// matches what the entity-response-collection's resolvers expect
|
2022-08-08 15:50:34 +02:00
|
|
|
if (isToMany) {
|
2021-09-22 14:39:36 +02:00
|
|
|
return toEntityResponseCollection(data, info);
|
2021-08-24 17:56:44 +02:00
|
|
|
}
|
2021-08-24 12:10:47 +02:00
|
|
|
|
2021-08-24 17:56:44 +02:00
|
|
|
// Else, it returns an object that matches
|
|
|
|
// what the entity-response's resolvers expect
|
2021-09-22 14:39:36 +02:00
|
|
|
return toEntityResponse(data, info);
|
2021-08-24 17:56:44 +02:00
|
|
|
};
|
|
|
|
},
|
|
|
|
};
|
|
|
|
};
|