UNPKG

loopback-graphql-relay

Version:

Add Relay based Apollo Server or GraphQL queries on your Loopback server

106 lines (88 loc) 2.54 kB
const _ = require('lodash'); const { connectionArgs, } = require('graphql-relay'); const { GraphQLObjectType } = require('graphql'); const { getType, getConnection } = require('../../types/type'); const { findAllRelated } = require('../../db'); const { connectionFromPromisedArray } = require('../../db/resolveConnection'); /** * Finds a user from an access token * @param {*} accessToken * @param {*} UserModel */ function findUserFromAccessToken(accessToken, UserModel) { if (!accessToken) return null; return UserModel.findById(accessToken.userId).then((user) => { if (!user) return Promise.reject(new Error('No user with this access token was found.')); return Promise.resolve(user); }); } /** * Adds fields of all relationed models * @param {*} models */ function getRelatedModelFields(User) { const fields = {}; _.forEach(User.relations, (relation) => { const model = relation.modelTo; fields[_.lowerFirst(relation.name)] = { args: Object.assign({ where: { type: getType('JSON'), }, order: { type: getType('JSON'), }, }, connectionArgs), type: getConnection(model.modelName), resolve: (obj, args, context) => { if (!context.req || !context.req.accessToken) return null; return findUserFromAccessToken(context.req.accessToken, User) .then(user => connectionFromPromisedArray(findAllRelated(User, user, relation.name, args, context), args, model)); }, }; }); return fields; } /** * Create a me field for a given user model * @param {*} User */ function getMeField(User) { return { me: { type: getType(User.modelName), resolve: (obj, args, { req }) => { if (!req.accessToken) return null; return findUserFromAccessToken(req.accessToken, User); }, }, }; } /** * Generates Viewer query * @param {*} models */ module.exports = function (models, options) { const opts = Object.assign({}, { AccessTokenModel: 'AccessToken', relation: 'user', UserModel: 'User', }, options.viewer || {}); const User = _.find(models, model => model.modelName === opts.UserModel); const Viewer = { resolve: () => ({}), type: new GraphQLObjectType({ name: 'Viewer', description: 'Viewer', // interfaces: () => [nodeDefinitions.nodeInterface], fields: () => Object.assign( {}, getMeField(User), getRelatedModelFields(User), ), }), }; return Viewer; };