Skip to content

Instantly share code, notes, and snippets.

@thebigredgeek
Created December 5, 2016 21:17
Show Gist options
  • Select an option

  • Save thebigredgeek/1b061644fd3e4f475574e71838bfd178 to your computer and use it in GitHub Desktop.

Select an option

Save thebigredgeek/1b061644fd3e4f475574e71838bfd178 to your computer and use it in GitHub Desktop.

Revisions

  1. thebigredgeek created this gist Dec 5, 2016.
    37 changes: 37 additions & 0 deletions baseResolvers.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,37 @@
    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;
    }
    );
    71 changes: 71 additions & 0 deletions createResolver.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,71 @@
    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;
    36 changes: 36 additions & 0 deletions userResolver.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,36 @@
    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
    }
    }