Created
December 5, 2016 21:17
-
-
Save thebigredgeek/1b061644fd3e4f475574e71838bfd178 to your computer and use it in GitHub Desktop.
Breed-able Resolvers
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { AlreadyAuthenticatedError, NotAuthenticatedError, NotAuthorizedError } from '../errors/functional'; | |
import createResolver from '../lib/createResolver'; | |
export const baseResolver = createResolver(); | |
export const isAuthenticatedResolver = baseResolver.createResolver( | |
(root, args, context) => { | |
if (!context.user || !context.user.id) throw new NotAuthenticatedError(); | |
} | |
); | |
export const isNotAuthenticatedResolver = baseResolver.createResolver( | |
(roor, args, context) => { | |
if (context.user && context.user.id) throw new AlreadyAuthenticatedError(); | |
} | |
) | |
export const isExpertResolver = isAuthenticatedResolver.createResolver( | |
async (root, args, context) => { | |
const expert = await context.user.getExpert(); | |
if (!expert) throw new NotAuthorizedError(); | |
context.user.Expert = expert; | |
} | |
) | |
export const isCustomerResolver = isAuthenticatedResolver.createResolver( | |
async (root, args, context) => { | |
const customer = await context.user.getCustomer(); | |
if (!customer) throw new NotAuthorizedError(); | |
context.user.Customer = customer; | |
} | |
); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import _ from 'underscore'; | |
import objectPath from 'object-path'; | |
import { createError } from 'apollo-errors'; | |
const pathExists = (key = '', obj = {}) => { | |
if (key.indexOf('&&') !== -1) return key.split(/\s*\&\&\s*/).reduce((bool, key) => bool && pathExists(key.trim(), obj), true); | |
if (key.indexOf('||') !== -1) return key.split(/\s*\|\|\s*/).reduce((bool, key) => bool || pathExists(key.trim(), obj), false); | |
key = key.replace(/\[(\w+)\]/g, '.$1') // convert indexes to properties | |
return !!objectPath.get(obj, key); | |
}; | |
export const createRequiredFieldsValidator = (argKey = '', fields = {}) => { | |
const Errors = Object.keys(fields) | |
.reduce((hash, key) => ({ | |
...hash, | |
[key]: createError(`FieldsRequiredError`, { | |
message: fields[key], | |
data: { | |
path: key | |
} | |
}) | |
}), {}); | |
return (root, args, context) => { | |
Object.keys(fields).forEach(key => { | |
if (!pathExists(args, key)) throw new Errors[key](); | |
}); | |
}; | |
}; | |
const createResolver = (resFn, errFn) => { | |
const baseResolver = async (root, args = {}, context = {}) => { | |
try { | |
if (!_.isFunction(resFn)) return null; | |
return await resFn(root, args, context); | |
} catch (err) { | |
if (!_.isFunction(errFn)) throw err; | |
const parsedError = await errFn(root, args, context, err) | |
throw parsedError || err; | |
} | |
}; | |
baseResolver.createResolver = (cResFn, cErrFn) => createResolver( | |
async (root, args, context) => { | |
const r = _.isFunction(resFn) ? await resFn(root, args, context) : null; | |
if (r) return r; | |
return _.isFunction(cResFn) ? await cResFn(root, args, context) : null; | |
}, | |
async (root, args, context, err) => { | |
const r = _.isFunction(errFn) ? await errFn(root, args, context, err) : null; | |
if (r) throw r; | |
const cR = _.isFunction(cErrFn) ? await cErrFn(root, args, context, err) : null; | |
throw cR || err; | |
} | |
); | |
baseResolver.requireArgs = (argKey = '', fields = {}) => { | |
const validator = createRequiredFieldsValidator(argKey, fields) | |
return createResolver( | |
async (root, args, context) => { | |
await validator(root, args, context); | |
return _.isFunction(resFn) ? await resFn(root, args, context) : null; | |
} | |
) | |
}; | |
return baseResolver; | |
}; | |
export default createResolver; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { isNotAuthenticatedResolver } from './_base'; | |
import { LoginFailedError } from '../errors/functional'; | |
export const loginUser = isNotAuthenticatedResolver.createResolver( | |
async (root, { user: { email, password } }, context) => { | |
const { models: { User } } = context; | |
const { user, token } = await User.login({ email, password }); | |
if (!user) throw new LoginFailedError(); | |
context.user = user; //attach user to context for subsequent requests | |
return { | |
...user.toJSON(), | |
token | |
} | |
} | |
); | |
export default { | |
User: { | |
CurrentLocation: user => user.getCurrentLocation(), | |
HomeLocation: user => user.getHomeLocation(), | |
Resume: user => user.getResume(), | |
Avatar: user => user.getAvatar(), | |
Customer: user => user.getCustomer(), | |
Expert: (user, args, context) => context.models.User.rebuild(user).getExpert(), | |
PastPositions: d => d, | |
CurrentPosition: user => user.getCurrentPosition(), | |
Skills: user => user.getSkills(), | |
//Emails: d => d | |
}, | |
Mutation: { | |
loginUser | |
}, | |
Query: { | |
getMyUser: (r, a, { user }) => user | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment