Jean-Sébastien Herbaux 357fd163b0
V4/graphql customization (#10850)
* Add basic implementation for the graphql extension service

* Add createPolicyContext in @strapi/utils

* policiesMiddleware implementation for graphql

* wrapResolvers first implementation (authentication, middlewares, policies)

* move the content API schema build from /generators to /content-api. Extract types' register functions into a dedicated folder

* fix schema generation on bootstrap

* update the graphql service file to match new services arch

* fix single type queries

* simplify entity's resolver

* use apollo graphql conventions for resolver's args naming

* use the graphql extension system in i18n to add a locale arg to localized queries & mutations
2021-09-01 12:06:51 +02:00

125 lines
3.4 KiB
JavaScript

'use strict';
const { entries, mapValues, omit } = require('lodash/fp');
const {
pagination: { withDefaultPagination },
contentTypes: { hasDraftAndPublish },
} = require('@strapi/utils');
module.exports = ({ strapi }) => {
const getGraphQLService = strapi.plugin('graphql').service;
return {
/**
* Get every args for a given content type
* @param {object} contentType
* @param {object} options
* @param {boolean} options.multiple
* @return {object}
*/
getContentTypeArgs(contentType, { multiple = true } = {}) {
const { naming } = getGraphQLService('utils');
const { args } = getGraphQLService('internals');
const { kind, modelType } = contentType;
// Components
if (modelType === 'component') {
return {
filters: naming.getFiltersInputTypeName(contentType),
pagination: args.PaginationArg,
sort: args.SortArg,
};
}
// Collection Types
else if (kind === 'collectionType') {
// hasDraftAndPublish
if (!multiple) {
return { id: 'ID' };
}
const params = {
filters: naming.getFiltersInputTypeName(contentType),
pagination: args.PaginationArg,
sort: args.SortArg,
};
if (hasDraftAndPublish(contentType)) {
Object.assign(params, { publicationState: args.PublicationStateArg });
}
return params;
}
// Single Types
else if (kind === 'singleType') {
const params = { id: 'ID' };
if (hasDraftAndPublish(contentType)) {
Object.assign(params, { publicationState: args.PublicationStateArg });
}
return params;
}
},
/**
* Filter an object entries and keep only those whose value is a unique scalar attribute
* @param {object} attributes
* @return {Object<string, object>}
*/
getUniqueScalarAttributes: attributes => {
const { isStrapiScalar } = getGraphQLService('utils').attributes;
const uniqueAttributes = entries(attributes).filter(
([, attribute]) => isStrapiScalar(attribute) && attribute.unique
);
return Object.fromEntries(uniqueAttributes);
},
/**
* Map each value from an attribute to a FiltersInput type name
* @param {object} attributes - The attributes object to transform
* @return {Object<string, string>}
*/
scalarAttributesToFiltersMap: mapValues(attribute => {
const { mappers, naming } = getGraphQLService('utils');
const gqlScalar = mappers.strapiScalarToGraphQLScalar(attribute.type);
return naming.getScalarFilterInputTypeName(gqlScalar);
}),
/**
* Apply basic transform to GQL args
*/
transformArgs(args, { contentType, usePagination = false } = {}) {
const { mappers } = getGraphQLService('utils');
const { pagination = {}, filters = {} } = args;
// Init
const newArgs = omit(['pagination', 'filters'], args);
// Pagination
if (usePagination) {
Object.assign(
newArgs,
withDefaultPagination(pagination /*, config.get(graphql.pagination.defaults)*/)
);
}
// Filters
if (args.filters) {
Object.assign(newArgs, {
filters: mappers.graphQLFiltersToStrapiQuery(filters, contentType),
});
}
return newArgs;
},
};
};