86 lines
2.9 KiB
JavaScript
Raw Normal View History

'use strict';
const { get } = require('lodash/fp');
const utils = require('@strapi/utils');
const { sanitize, pipeAsync } = utils;
const { ApplicationError } = utils.errors;
module.exports = ({ strapi }) => {
const { service: getGraphQLService } = strapi.plugin('graphql');
const { isMorphRelation, isMedia } = getGraphQLService('utils').attributes;
const { transformArgs } = getGraphQLService('builders').utils;
const { toEntityResponse, toEntityResponseCollection } = getGraphQLService('format').returnTypes;
return {
buildAssociationResolver({ contentTypeUID, attributeName }) {
const contentType = strapi.getModel(contentTypeUID);
const attribute = contentType.attributes[attributeName];
if (!attribute) {
2021-10-27 18:54:58 +02:00
throw new ApplicationError(
`Failed to build an association resolver for ${contentTypeUID}::${attributeName}`
);
}
const isMediaAttribute = isMedia(attribute);
const isMorphAttribute = isMorphRelation(attribute);
const targetUID = isMediaAttribute ? 'plugins::upload.file' : attribute.target;
const isToMany = isMediaAttribute ? attribute.multiple : attribute.relation.endsWith('Many');
const targetContentType = strapi.getModel(targetUID);
2022-08-08 23:33:39 +02:00
return async (parent, args = {}, context = {}) => {
const { auth } = context.state;
const transformedArgs = transformArgs(args, {
contentType: targetContentType,
usePagination: true,
});
const data = await strapi.entityService.load(
contentTypeUID,
parent,
attributeName,
transformedArgs
);
const info = {
args: transformedArgs,
resourceUID: targetUID,
};
// 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.
if (isMorphAttribute) {
// Helpers used for the data cleanup
2022-08-08 23:33:39 +02:00
const wrapData = (dataToWrap) => ({ [attributeName]: dataToWrap });
const sanitizeData = (dataToSanitize) => {
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);
return sanitizeMorphAttribute(data);
}
// 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) {
return toEntityResponseCollection(data, info);
}
// Else, it returns an object that matches
// what the entity-response's resolvers expect
return toEntityResponse(data, info);
};
},
};
};