Last active
December 5, 2017 18:43
-
-
Save giautm/d402c8f9131156f56a441477b47657c7 to your computer and use it in GitHub Desktop.
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 { | |
defaultFieldResolver, | |
DirectiveNode, | |
GraphQLField, | |
GraphQLFieldResolver, | |
GraphQLResolveInfo, | |
GraphQLSchema, | |
} from 'graphql'; | |
import { forEachField } from 'graphql-tools'; | |
import { getArgumentValues } from 'graphql/execution/values'; | |
export type NextResolverFn = () => Promise<any>; | |
export type DirectiveResolverFn<TSource, TContext> = ( | |
next: NextResolverFn, | |
source: TSource, | |
args: { [argName: string]: any }, | |
context: TContext, | |
info: GraphQLResolveInfo, | |
) => any; | |
export interface IDirectiveResolvers<TSource, TContext> { | |
[directiveName: string]: DirectiveResolverFn<TSource, TContext>; | |
} | |
/** | |
* Attach directive resolvers to Schema | |
* https://github.com/apollographql/graphql-tools/issues/212#issuecomment-324447078 | |
* | |
* @author Agon Bina <[email protected]> | |
* @author Giau. Tran Minh <[email protected]> | |
* @param resolvers: resolvers of directive | |
* @param schema: GraphQL schema to attach directive resolvers | |
*/ | |
export function attachDirectiveResolvers( | |
schema: GraphQLSchema, | |
directiveResolvers: IDirectiveResolvers<any, any>, | |
) { | |
if (typeof directiveResolvers !== 'object') { | |
throw new Error( | |
`Expected directiveResolvers to be of type object, got ${typeof directiveResolvers}`, | |
); | |
} | |
if (Array.isArray(directiveResolvers)) { | |
throw new Error('Expected directiveResolvers to be of type object, got Array'); | |
} | |
forEachField(schema, (field: GraphQLField<any, any>) => { | |
const directives = field.astNode.directives; | |
directives.forEach((directive: DirectiveNode) => { | |
const directiveName = directive.name.value; | |
const resolver = directiveResolvers[directiveName]; | |
if (resolver) { | |
const originalResolver = field.resolve || defaultFieldResolver; | |
const Directive = schema.getDirective(directiveName); | |
if (typeof Directive === 'undefined') { | |
throw new Error(`Directive @${directiveName} is undefined. ` + | |
'Please define in schema before using'); | |
} | |
const directiveArgs = getArgumentValues(Directive, directive); | |
field.resolve = (...args: any[]) => { | |
const [source, , context, info] = args; | |
return resolver(() => { | |
try { | |
const promise = originalResolver.call(field, ...args); | |
if (promise instanceof Promise) { | |
return promise; | |
} | |
return Promise.resolve(promise); | |
} catch (error) { | |
return Promise.reject(error); | |
} | |
}, source, directiveArgs, context, info); | |
}; | |
} | |
}); | |
}); | |
} |
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 jwt from 'jsonwebtoken'; | |
import { AuthorizationError } from './../errors'; | |
import { NextResolver } from './attachDirectives'; | |
export { attachDirectives } from './attachDirectives'; | |
export const directiveResolvers = { | |
upperCase(next: NextResolver, source, args, context) { | |
return next().then((r) => { | |
if (typeof(r) === 'string') { | |
return r.toUpperCase(); | |
} | |
return r; | |
}); | |
}, | |
auth(next: NextResolver, source, args, { auth, scopes }) { | |
if (auth) { | |
const expected = args.scope; | |
if (expected.length() === 0 || expected.some((e) => scopes.includes(e))) { | |
return next(); | |
} | |
throw new AuthorizationError({ | |
message: `You are not authorized. Expected scopes: ${expected.join(', ')}`, | |
}); | |
} | |
throw new AuthorizationError({ | |
message: 'You must supply a JWT for authorization!', | |
}); | |
}, | |
}; |
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
directive @auth(scope: [String]) on QUERY | FIELD | |
directive @upperCase on QUERY | FIELD | |
# this is needed for upload to work | |
scalar Upload | |
type Query { | |
uploads: [File] | |
hello: String @upperCase | |
} | |
type Mutation { | |
singleUpload(file: Upload!): File! @auth | |
multipleUpload (files: [Upload!]!): [File!]! | |
} | |
type File { | |
id: ID! | |
path: String! | |
filename: String! | |
mimetype: String! | |
encoding: String! | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment