diff --git a/packages/strapi-bookshelf/lib/index.js b/packages/strapi-bookshelf/lib/index.js index b6f12cb8d0..c1f9cd1947 100755 --- a/packages/strapi-bookshelf/lib/index.js +++ b/packages/strapi-bookshelf/lib/index.js @@ -176,6 +176,7 @@ module.exports = function(strapi) { attrs[association.alias] = attrs[association.alias].related; break; case 'manyMorphToOne': + case 'manyMorphToMany': attrs[association.alias] = attrs[association.alias].map(obj => obj.related); break; default: @@ -226,7 +227,6 @@ module.exports = function(strapi) { const association = definition.associations .filter(association => association.nature.toLowerCase().indexOf('morph') !== -1) .filter(association => association.alias === path || association.via === path)[0]; - if (association) { // Override on polymorphic path only. if (_.isString(path) && path === association.via) { diff --git a/packages/strapi-plugin-content-manager/config/queries/bookshelf.js b/packages/strapi-plugin-content-manager/config/queries/bookshelf.js index d841a02cf2..22b70e1fdb 100755 --- a/packages/strapi-plugin-content-manager/config/queries/bookshelf.js +++ b/packages/strapi-plugin-content-manager/config/queries/bookshelf.js @@ -29,16 +29,37 @@ module.exports = { .count(); }, - findOne: async function (params) { + findOne: async function (params, populate, raw = true) { const record = await this .forge({ [this.primaryKey]: params[this.primaryKey] }) .fetch({ - withRelated: this.associations.map(x => x.alias) + withRelated: populate || this.associations.map(x => x.alias) }); - return record ? record.toJSON() : record; + const data = record ? record.toJSON() : record; + + // Retrieve data manually. + if (_.isEmpty(populate)) { + const arrayOfPromises = this.associations + .filter(association => ['manyMorphToOne', 'manyMorphToMany'].includes(association.nature)) + .map(association => { + return this.morph.forge() + .where({ + [`${this.collectionName}_id`]: params[this.primaryKey] + }) + .fetchAll() + }); + + const related = await Promise.all(arrayOfPromises); + + related.forEach((value, index) => { + data[this.associations[index].alias] = value ? value.toJSON() : value; + }); + } + + return data; }, create: async function (params) { diff --git a/packages/strapi-plugin-graphql/services/GraphQL.js b/packages/strapi-plugin-graphql/services/GraphQL.js index eeafa1d270..5c0c409a9e 100644 --- a/packages/strapi-plugin-graphql/services/GraphQL.js +++ b/packages/strapi-plugin-graphql/services/GraphQL.js @@ -475,31 +475,38 @@ module.exports = { acc.resolver[globalId] = {}; } - if (association.nature === 'manyMorphToMany') { - return _.merge(acc.resolver[globalId], { - [association.alias]: async (obj, options, context) => { - const [ withRelated, withoutRelated ] = await Promise.all([ - resolvers.fetch({ - id: obj[model.primaryKey], - model: name - }, plugin, [association.alias], false), - resolvers.fetch({ - id: obj[model.primaryKey], - model: name - }, plugin, []) - ]); + switch (association.nature) { + case 'manyMorphToOne': + case 'manyMorphToMany': + return _.merge(acc.resolver[globalId], { + [association.alias]: async (obj, options, context) => { + const [ withRelated, withoutRelated ] = await Promise.all([ + resolvers.fetch({ + id: obj[model.primaryKey], + model: name + }, plugin, [association.alias], false), + resolvers.fetch({ + id: obj[model.primaryKey], + model: name + }, plugin, []) + ]); - const entry = withRelated.toJSON ? withRelated.toJSON() : withRelated; + const entry = withRelated.toJSON ? withRelated.toJSON() : withRelated; - entry[association.alias].map((entry, index) => { - entry._type = withoutRelated[association.alias][index].kind; + entry[association.alias].map((entry, index) => { + const type = withoutRelated[association.alias][index].kind || + _.upperFirst(_.camelCase(withoutRelated[association.alias][index][`${association.alias}_type`])); - return entry; - }); + entry._type = type; - return entry[association.alias]; - } - }); + return entry; + }); + + return entry[association.alias]; + } + }); + break; + default: } // TODO: @@ -520,13 +527,13 @@ module.exports = { } else { // Get attribute. const attr = association.plugin ? - strapi.plugins[association.plugin].models[association.collection].attributes[association.via]: - strapi.models[association.collection].attributes[association.via]; + strapi.plugins[association.plugin].models[params.model].attributes[association.via]: + strapi.models[params.model].attributes[association.via]; // Get refering model. const ref = attr.plugin ? - strapi.plugins[attr.plugin].models[attr.model || attr.collection]: - strapi.models[attr.model || attr.collection]; + strapi.plugins[attr.plugin].models[params.model]: + strapi.models[params.model]; // Apply optional arguments to make more precise nested request. const convertedParams = strapi.utils.models.convertParams(name, this.convertToParams(options)); @@ -668,7 +675,7 @@ module.exports = { polymorphicDef: `union Morph = ${types.join(' | ')}`, polymorphicResolver: { Morph: { - __resolveType(obj, context, info){ + __resolveType(obj, context, info) { return obj.kind || obj._type; } } diff --git a/packages/strapi-plugin-users-permissions/config/schema.graphql b/packages/strapi-plugin-users-permissions/config/schema.graphql new file mode 100644 index 0000000000..d9eb0f4d3f --- /dev/null +++ b/packages/strapi-plugin-users-permissions/config/schema.graphql @@ -0,0 +1,25 @@ +module.exports = { + type: { + UsersPermissionsPermission: false // Make this type NOT queriable. + }, + resolver: { + Query: { + role: { + resolverOf: 'UsersPermissions.getRole', + resolver: async (obj, options, ctx) => { + await strapi.plugins['users-permissions'].controllers.userspermissions.getRole(ctx); + + return ctx.body.role; + } + }, + roles: { + resolverOf: 'UsersPermissions.getRoles', // Apply the `getRoles` permissions on the resolver. + resolver: async (obj, options, ctx) => { + await strapi.plugins['users-permissions'].controllers.userspermissions.getRoles(ctx); + + return ctx.body.roles; + } + } + } + } +};