From 904d21da8a59af8dfefd6161e8dee678d5144c2a Mon Sep 17 00:00:00 2001 From: Corjen Moll Date: Wed, 9 May 2018 21:34:11 +0200 Subject: [PATCH 1/3] Add 4th info parameter (and test cases) to resolvers --- src/resolver.ts | 8 +++---- test/unit/resolver_spec.js | 45 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/src/resolver.ts b/src/resolver.ts index e3359f8..61c4957 100644 --- a/src/resolver.ts +++ b/src/resolver.ts @@ -4,10 +4,10 @@ import { isFunction, Promisify, isNotNullOrUndefined } from './util'; export const createResolver = (resFn, errFn) => { const Promise = getPromise(); - const baseResolver = (root, args = {}, context = {}) => { + const baseResolver = (root, args = {}, context = {}, info = {}) => { // Return resolving promise with `null` if the resolver function param is not a function if (!isFunction(resFn)) return Promise.resolve(null); - return Promisify(resFn)(root, args, context).catch(e => { + return Promisify(resFn)(root, args, context, info).catch(e => { // On error, check if there is an error handler. If not, throw the original error if (!isFunction(errFn)) throw e; // Call the error handler. @@ -23,9 +23,9 @@ export const createResolver = (resFn, errFn) => { baseResolver['createResolver'] = (cResFn, cErrFn) => { const Promise = getPromise(); - const childResFn = (root, args, context) => { + const childResFn = (root, args, context, info = {}) => { // Start with either the parent resolver function or a no-op (returns null) - const entry = isFunction(resFn) ? Promisify(resFn)(root, args, context) : Promise.resolve(null); + const entry = isFunction(resFn) ? Promisify(resFn)(root, args, context, info) : Promise.resolve(null); return entry.then(r => { // If the parent returns a value, continue if (isNotNullOrUndefined(r)) return r; diff --git a/test/unit/resolver_spec.js b/test/unit/resolver_spec.js index 1eb31a4..eb3d17b 100644 --- a/test/unit/resolver_spec.js +++ b/test/unit/resolver_spec.js @@ -141,4 +141,49 @@ describe('(unit) dist/resolver.js', () => { }); }) }); + describe('info parameter', () => { + it('info parameter should be an empty object', () => { + const r1 = { + handle: (root, args, context, info) => { + expect(typeof info).to.equal('object') + expect(Object.keys(info).length).to.equal(0) + }, + }; + const resolver = createResolver(r1.handle); + + resolver(null, null, null) + }) + it('should pass the info parameter', () => { + const r1 = { + handle: (root, args, context, info) => { + expect(typeof info).to.equal('object') + expect(info.info).to.equal('info') + }, + }; + const resolver = createResolver(r1.handle); + + resolver(null, null, null, { info: 'info' }) + }) + it('should pass the info parameter on a chained resolver', () => { + const r1 = { + handle: (root, args, context, info) => { + expect(typeof info).to.equal('object') + expect(info.info).to.equal('info') + }, + }; + + const r2 = { + handle: (root, args, context, info) => { + expect(typeof info).to.equal('object') + expect(info.chained).to.equal('info') + }, + }; + + const baseResolver = createResolver(r1.handle); + const chainedResolver = createResolver(r2.handle) + + baseResolver(null, null, null, { info: 'info' }) + chainedResolver(null, null, null, { chained: 'info' }) + }) + }) }); From 118ef92ae2f7849be3bb832b9770dbca873f01c2 Mon Sep 17 00:00:00 2001 From: Corjen Moll Date: Wed, 9 May 2018 21:34:20 +0200 Subject: [PATCH 2/3] New build --- dist/resolver.d.ts | 2 +- dist/resolver.js | 8 ++++---- dist/resolver.js.map | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dist/resolver.d.ts b/dist/resolver.d.ts index a00a739..0f966db 100644 --- a/dist/resolver.d.ts +++ b/dist/resolver.d.ts @@ -1 +1 @@ -export declare const createResolver: (resFn: any, errFn: any) => (root: any, args?: {}, context?: {}) => Promise; +export declare const createResolver: (resFn: any, errFn: any) => (root: any, args?: {}, context?: {}, info?: {}) => Promise; diff --git a/dist/resolver.js b/dist/resolver.js index e9e54af..d505d4d 100644 --- a/dist/resolver.js +++ b/dist/resolver.js @@ -4,11 +4,11 @@ const promise_1 = require("./promise"); const util_1 = require("./util"); exports.createResolver = (resFn, errFn) => { const Promise = promise_1.getPromise(); - const baseResolver = (root, args = {}, context = {}) => { + const baseResolver = (root, args = {}, context = {}, info = {}) => { // Return resolving promise with `null` if the resolver function param is not a function if (!util_1.isFunction(resFn)) return Promise.resolve(null); - return util_1.Promisify(resFn)(root, args, context).catch(e => { + return util_1.Promisify(resFn)(root, args, context, info).catch(e => { // On error, check if there is an error handler. If not, throw the original error if (!util_1.isFunction(errFn)) throw e; @@ -24,9 +24,9 @@ exports.createResolver = (resFn, errFn) => { }; baseResolver['createResolver'] = (cResFn, cErrFn) => { const Promise = promise_1.getPromise(); - const childResFn = (root, args, context) => { + const childResFn = (root, args, context, info = {}) => { // Start with either the parent resolver function or a no-op (returns null) - const entry = util_1.isFunction(resFn) ? util_1.Promisify(resFn)(root, args, context) : Promise.resolve(null); + const entry = util_1.isFunction(resFn) ? util_1.Promisify(resFn)(root, args, context, info) : Promise.resolve(null); return entry.then(r => { // If the parent returns a value, continue if (util_1.isNotNullOrUndefined(r)) diff --git a/dist/resolver.js.map b/dist/resolver.js.map index c8c9729..ef15a6c 100644 --- a/dist/resolver.js.map +++ b/dist/resolver.js.map @@ -1 +1 @@ -{"version":3,"file":"resolver.js","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"resolver.js","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"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"} \ No newline at end of file From 75b3dccbab724052402473c20300824aea6555fe Mon Sep 17 00:00:00 2001 From: Corjen Moll Date: Wed, 9 May 2018 21:34:34 +0200 Subject: [PATCH 3/3] Update readme with 4th info parameter --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 1551d31..beffcf0 100644 --- a/README.md +++ b/README.md @@ -65,14 +65,14 @@ const AuthenticationRequiredError = createError('AuthenticationRequiredError', { export const isAuthenticatedResolver = baseResolver.createResolver( // Extract the user from context (undefined if non-existent) - (root, args, { user }) => { + (root, args, { user }, info) => { if (!user) throw new AuthenticationRequiredError(); } ); export const isAdminResolver = isAuthenticatedResolver.createResolver( // Extract the user and make sure they are an admin - (root, args, { user }) => { + (root, args, { user }, info) => { /* If thrown, this error will bubble up to baseResolver's error callback (if present). If unhandled, the error is returned to @@ -100,7 +100,7 @@ const NotYourUserError = createError('NotYourUserError', { }); const updateMyProfile = isAuthenticatedResolver.createResolver( - (root, { input }, { user, models: { UserModel } }) => { + (root, { input }, { user, models: { UserModel } }, info) => { /* If thrown, this error will bubble up to isAuthenticatedResolver's error callback (if present) and then to baseResolver's error callback. If unhandled, the error @@ -128,7 +128,7 @@ const ExposedError = createError('ExposedError', { }); const banUser = isAdminResolver.createResolver( - (root, { input }, { models: { UserModel } }) => UserModel.ban(input), + (root, { input }, { models: { UserModel } }, info) => UserModel.ban(input), (root, args, context, error) => { /* For admin users, let's tell the user what actually broke @@ -175,7 +175,7 @@ import { and, or } from 'apollo-resolvers'; import isFooResolver from './foo'; import isBarResolver from './bar'; -const banResolver = (root, { input }, { models: { UserModel } })=> UserModel.ban(input); +const banResolver = (root, { input }, { models: { UserModel } }, info)=> UserModel.ban(input); // Will execute banResolver if either isFooResolver or isBarResolver successfully resolve // If none of the resolvers succeed, the error from the last conditional resolver will