Fix component assoc resolvers in graphql (#9660)

This commit is contained in:
Alexandre BODIN 2021-03-10 10:46:46 +01:00 committed by GitHub
parent 9e22c280de
commit b3635962a3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 29 additions and 32 deletions

View File

@ -189,6 +189,22 @@ module.exports = async ({ models, target }, ctx) => {
};
};
const parseComponentRef = el => {
if (el.ref instanceof mongoose.Types.ObjectId) {
return el.ref.toString();
} else {
return el.ref;
}
};
const parseDynamicZoneRef = el => {
if (el.ref instanceof mongoose.Types.ObjectId) {
return { id: el.ref.toString() };
} else {
return el.ref;
}
};
schema.options.toObject = schema.options.toJSON = {
virtuals: true,
transform: function(doc, returned) {
@ -232,7 +248,7 @@ module.exports = async ({ models, target }, ctx) => {
if (type === 'component') {
if (Array.isArray(returned[name])) {
const components = returned[name].map(el => el.ref);
const components = returned[name].map(parseComponentRef);
// Reformat data by bypassing the many-to-many relationship.
returned[name] =
attribute.repeatable === true ? components : _.first(components) || null;
@ -246,7 +262,7 @@ module.exports = async ({ models, target }, ctx) => {
.map(el => {
return {
__component: findComponentByGlobalId(el.kind).uid,
...el.ref,
...parseDynamicZoneRef(el),
};
});
}

View File

@ -120,9 +120,7 @@ const generateDynamicZoneDefinitions = (attributes, globalId, schema) => {
if (components.length === 0) {
// Create dummy type because graphql doesn't support empty ones
schema.definition += `type ${typeName} { _:Boolean}`;
schema.definition += `\nscalar EmptyQuery\n`;
} else {
const componentsTypeNames = components.map(componentUID => {
const compo = strapi.components[componentUID];
@ -202,6 +200,11 @@ const buildAssocResolvers = model => {
}
default: {
resolver[alias] = async (obj, options) => {
// force component relations to be refetched
if (model.modelType === 'component') {
obj[alias] = _.get(obj[alias], targetModel.primaryKey, obj[alias]);
}
const loader = strapi.plugins.graphql.services['data-loaders'].loaders[targetModel.uid];
const localId = obj[model.primaryKey];
@ -311,6 +314,8 @@ const buildModels = models => {
const buildModelDefinition = (model, globalType = {}) => {
const { globalId, primaryKey } = model;
const typeDefObj = buildTypeDefObj(model);
const schema = {
definition: '',
query: {},
@ -323,10 +328,9 @@ const buildModelDefinition = (model, globalType = {}) => {
...buildAssocResolvers(model),
},
},
typeDefObj,
};
const typeDefObj = buildTypeDefObj(model);
schema.definition += generateEnumDefinitions(model.attributes, globalId);
generateDynamicZoneDefinitions(model.attributes, globalId, schema);
@ -397,7 +401,7 @@ const buildSingleType = model => {
};
const buildCollectionType = model => {
const { globalId, plugin, modelName, uid } = model;
const { plugin, modelName, uid } = model;
const singularName = toSingular(modelName);
const pluralName = toPlural(modelName);
@ -406,31 +410,8 @@ const buildCollectionType = model => {
const globalType = _.get(_schema, `type.${model.globalId}`, {});
const localSchema = {
definition: '',
query: {},
mutation: {},
resolvers: {
Query: {},
Mutation: {},
// define default resolver for this model
[globalId]: {
id: parent => parent[model.primaryKey] || parent.id,
...buildAssocResolvers(model),
},
},
};
const typeDefObj = buildTypeDefObj(model);
localSchema.definition += generateEnumDefinitions(model.attributes, globalId);
generateDynamicZoneDefinitions(model.attributes, globalId, localSchema);
const description = getTypeDescription(globalType, model);
const fields = toSDL(typeDefObj, globalType, model);
const typeDef = `${description}type ${globalId} {${fields}}\n`;
localSchema.definition += typeDef;
const localSchema = buildModelDefinition(model, globalType);
const { typeDefObj } = localSchema;
// Add definition to the schema but this type won't be "queriable" or "mutable".
if (globalType === false) {