UNPKG

graphql-bookshelfjs

Version:
75 lines (66 loc) 2.34 kB
'use strict'; const loaders = require('./loaders'); /** * Quick workaround allowing GraphQL to access model attributes directly * (to access a bookshelf model attribute (like model.name), we have to use the .get() method) * * @param {object} collection * @returns {*} */ function exposeAttributes(collection) { function exposeModelAttributes(item) { // Make sure that relations are excluded return Object.assign(item, item.serialize({ shallow: true })); } if (collection) { if (collection.hasOwnProperty('length')) { return collection.map((item) => { return exposeModelAttributes(item); }); } return exposeModelAttributes(collection); } return collection; } module.exports = { /** * * @returns {function} */ getLoaders() { return loaders; }, /** * * @param {function} Model * @returns {function} */ resolverFactory(Model) { return function resolver(modelInstance, args, context, info, extra) { const isAssociation = (typeof Model.prototype[info.fieldName] === 'function'); const model = isAssociation ? modelInstance.related(info.fieldName) : new Model(); for (const key in args) { model.where(`${model.tableName}.${key}`, args[key]); } if (extra) { switch (typeof extra) { case 'function': extra(model); break; case 'object': for (const key in extra) { model[key](...extra[key]); delete extra[key]; } break; default: return Promise.reject('Parameter [extra] should be either a function or an object'); } } if (isAssociation) { context && context.loaders && context.loaders(model); return model.fetch().then((c) => { return exposeAttributes(c); }); } const fn = (info.returnType.constructor.name === 'GraphQLList') ? 'fetchAll' : 'fetch'; return model[fn]().then((c) => { return exposeAttributes(c); }); }; }, };