graphql-extensions
Advanced tools
Comparing version 0.0.10 to 0.1.0-beta.0
import { GraphQLSchema, GraphQLField, GraphQLResolveInfo } from 'graphql'; | ||
export declare type EndHandler = () => void; | ||
export declare class GraphQLExtension<TContext = any> { | ||
requestDidStart?(): void; | ||
parsingDidStart?(): void; | ||
parsingDidEnd?(): void; | ||
validationDidStart?(): void; | ||
validationDidEnd?(): void; | ||
executionDidStart?(): void; | ||
requestDidStart?(): EndHandler | void; | ||
parsingDidStart?(): EndHandler | void; | ||
validationDidStart?(): EndHandler | void; | ||
executionDidStart?(): EndHandler | void; | ||
willResolveField?(source: any, args: { | ||
[argName: string]: any; | ||
}, context: TContext, info: GraphQLResolveInfo): ((result: any) => void) | void; | ||
executionDidEnd?(): void; | ||
requestDidEnd?(): void; | ||
format?(): [string, any] | undefined; | ||
@@ -18,15 +15,12 @@ } | ||
private extensions; | ||
constructor(extensions: (typeof GraphQLExtension | GraphQLExtension)[]); | ||
requestDidStart(): void; | ||
parsingDidStart(): void; | ||
parsingDidEnd(): void; | ||
validationDidStart(): void; | ||
validationDidEnd(): void; | ||
executionDidStart(): void; | ||
constructor(extensions: GraphQLExtension<TContext>[]); | ||
requestDidStart(): (() => void); | ||
parsingDidStart(): (() => void); | ||
validationDidStart(): (() => void); | ||
executionDidStart(): (() => void); | ||
willResolveField(source: any, args: { | ||
[argName: string]: any; | ||
}, context: TContext, info: GraphQLResolveInfo): (result: any) => void; | ||
executionDidEnd(): void; | ||
requestDidEnd(): void; | ||
format(): {}; | ||
private handleDidStart(selectHandler); | ||
} | ||
@@ -33,0 +27,0 @@ export declare function enableGraphQLExtensions(schema: GraphQLSchema & { |
104
lib/index.js
@@ -12,57 +12,22 @@ "use strict"; | ||
function GraphQLExtensionStack(extensions) { | ||
this.extensions = extensions.map(function (extension) { | ||
return typeof extension === 'function' ? new extension() : extension; | ||
}); | ||
this.extensions = extensions; | ||
} | ||
GraphQLExtensionStack.prototype.requestDidStart = function () { | ||
for (var _i = 0, _a = this.extensions; _i < _a.length; _i++) { | ||
var extension = _a[_i]; | ||
if (extension.requestDidStart) { | ||
extension.requestDidStart(); | ||
} | ||
} | ||
return this.handleDidStart(function (ext) { return ext.requestDidStart; }); | ||
}; | ||
GraphQLExtensionStack.prototype.parsingDidStart = function () { | ||
for (var _i = 0, _a = this.extensions; _i < _a.length; _i++) { | ||
var extension = _a[_i]; | ||
if (extension.parsingDidStart) { | ||
extension.parsingDidStart(); | ||
} | ||
} | ||
return this.handleDidStart(function (ext) { return ext.parsingDidStart; }); | ||
}; | ||
GraphQLExtensionStack.prototype.parsingDidEnd = function () { | ||
for (var _i = 0, _a = this.extensions; _i < _a.length; _i++) { | ||
var extension = _a[_i]; | ||
if (extension.parsingDidEnd) { | ||
extension.parsingDidEnd(); | ||
} | ||
} | ||
}; | ||
GraphQLExtensionStack.prototype.validationDidStart = function () { | ||
for (var _i = 0, _a = this.extensions; _i < _a.length; _i++) { | ||
var extension = _a[_i]; | ||
if (extension.validationDidStart) { | ||
extension.validationDidStart(); | ||
} | ||
} | ||
return this.handleDidStart(function (ext) { return ext.validationDidStart; }); | ||
}; | ||
GraphQLExtensionStack.prototype.validationDidEnd = function () { | ||
for (var _i = 0, _a = this.extensions; _i < _a.length; _i++) { | ||
var extension = _a[_i]; | ||
if (extension.validationDidEnd) { | ||
extension.validationDidEnd(); | ||
} | ||
} | ||
}; | ||
GraphQLExtensionStack.prototype.executionDidStart = function () { | ||
for (var _i = 0, _a = this.extensions; _i < _a.length; _i++) { | ||
var extension = _a[_i]; | ||
if (extension.executionDidStart) { | ||
extension.executionDidStart(); | ||
} | ||
} | ||
return this.handleDidStart(function (ext) { return ext.executionDidStart; }); | ||
}; | ||
GraphQLExtensionStack.prototype.willResolveField = function (source, args, context, info) { | ||
var handlers = this.extensions | ||
.map(function (extension) { return extension.willResolveField && extension.willResolveField(source, args, context, info); }) | ||
.map(function (extension) { | ||
return extension.willResolveField && | ||
extension.willResolveField(source, args, context, info); | ||
}) | ||
.filter(function (x) { return x; }); | ||
@@ -76,20 +41,6 @@ return function (result) { | ||
}; | ||
GraphQLExtensionStack.prototype.executionDidEnd = function () { | ||
for (var _i = 0, _a = this.extensions; _i < _a.length; _i++) { | ||
var extension = _a[_i]; | ||
if (extension.executionDidEnd) { | ||
extension.executionDidEnd(); | ||
} | ||
} | ||
}; | ||
GraphQLExtensionStack.prototype.requestDidEnd = function () { | ||
for (var _i = 0, _a = this.extensions; _i < _a.length; _i++) { | ||
var extension = _a[_i]; | ||
if (extension.requestDidEnd) { | ||
extension.requestDidEnd(); | ||
} | ||
} | ||
}; | ||
GraphQLExtensionStack.prototype.format = function () { | ||
return this.extensions.map(function (extension) { return extension.format && extension.format(); }).filter(function (x) { return x; }).reduce(function (extensions, _a) { | ||
return this.extensions | ||
.map(function (extension) { return extension.format && extension.format(); }) | ||
.filter(function (x) { return x; }).reduce(function (extensions, _a) { | ||
var key = _a[0], value = _a[1]; | ||
@@ -100,2 +51,21 @@ return Object.assign(extensions, (_b = {}, _b[key] = value, _b)); | ||
}; | ||
GraphQLExtensionStack.prototype.handleDidStart = function (selectHandler) { | ||
var endHandlers = []; | ||
this.extensions.forEach(function (extension) { | ||
var startHandler = selectHandler(extension); | ||
if (startHandler) { | ||
var endHandler = startHandler(); | ||
if (endHandler) { | ||
endHandlers.push(endHandler); | ||
} | ||
} | ||
}); | ||
return function () { | ||
// We run end handlers in reverse order of start handlers. That way, the | ||
// first handler in the stack "surrounds" the entire event's process | ||
// (helpful for tracing/reporting!) | ||
endHandlers.reverse(); | ||
endHandlers.forEach(function (endHandler) { return endHandler(); }); | ||
}; | ||
}; | ||
return GraphQLExtensionStack; | ||
@@ -117,3 +87,4 @@ }()); | ||
var extensionStack = context && context._extensionStack; | ||
var handler = extensionStack && extensionStack.willResolveField(source, args, context, info); | ||
var handler = extensionStack && | ||
extensionStack.willResolveField(source, args, context, info); | ||
// If no resolver has been defined for a field, use the default field resolver | ||
@@ -125,3 +96,4 @@ // (which matches the behavior of graphql-js when there is no explicit resolve function defined). | ||
whenResultIsFinished(result_1, function () { | ||
handler && handler(result_1); | ||
if (handler) | ||
handler(result_1); | ||
}); | ||
@@ -131,3 +103,4 @@ return result_1; | ||
catch (error) { | ||
handler && handler(); | ||
if (handler) | ||
handler(); | ||
throw error; | ||
@@ -166,3 +139,4 @@ } | ||
var type = typeMap[typeName]; | ||
if (!graphql_1.getNamedType(type).name.startsWith('__') && type instanceof graphql_1.GraphQLObjectType) { | ||
if (!graphql_1.getNamedType(type).name.startsWith('__') && | ||
type instanceof graphql_1.GraphQLObjectType) { | ||
var fields_1 = type.getFields(); | ||
@@ -169,0 +143,0 @@ Object.keys(fields_1).forEach(function (fieldName) { |
{ | ||
"name": "graphql-extensions", | ||
"version": "0.0.10", | ||
"version": "0.1.0-beta.0", | ||
"description": "Add extensions to GraphQL servers", | ||
@@ -12,3 +12,5 @@ "main": "./lib/index.js", | ||
"prepare": "npm run clean && npm run compile", | ||
"test": "./node_modules/.bin/jest" | ||
"test": "./node_modules/.bin/jest", | ||
"lint": "prettier -l 'src/**/*.ts' && tslint -p tsconfig.json 'src/**/*.ts'", | ||
"lint-fix": "prettier --write 'src/**/*.ts' && tslint --fix -p tsconfig.json 'src/**/*.ts'" | ||
}, | ||
@@ -38,5 +40,11 @@ "repository": { | ||
"jest-matcher-utils": "^22.4.3", | ||
"prettier": "^1.12.1", | ||
"ts-jest": "^22.4.2", | ||
"typescript": "^2.7.2" | ||
"tslint": "^5.10.0", | ||
"typescript": "^2.8.3" | ||
}, | ||
"prettier": { | ||
"trailingComma": "all", | ||
"singleQuote": true | ||
}, | ||
"jest": { | ||
@@ -43,0 +51,0 @@ "testEnvironment": "node", |
174
src/index.ts
@@ -7,95 +7,59 @@ import { | ||
defaultFieldResolver, | ||
GraphQLResolveInfo | ||
GraphQLResolveInfo, | ||
} from 'graphql'; | ||
export type EndHandler = () => void; | ||
type StartHandler = () => EndHandler | void; | ||
type HandlerSelector<TContext = any> = ( | ||
ext: GraphQLExtension<TContext>, | ||
) => StartHandler | void; | ||
export class GraphQLExtension<TContext = any> { | ||
requestDidStart?(): void; | ||
public requestDidStart?(): EndHandler | void; | ||
public parsingDidStart?(): EndHandler | void; | ||
public validationDidStart?(): EndHandler | void; | ||
public executionDidStart?(): EndHandler | void; | ||
parsingDidStart?(): void; | ||
parsingDidEnd?(): void; | ||
validationDidStart?(): void; | ||
validationDidEnd?(): void; | ||
executionDidStart?(): void; | ||
willResolveField?( | ||
public willResolveField?( | ||
source: any, | ||
args: { [argName: string]: any }, | ||
context: TContext, | ||
info: GraphQLResolveInfo | ||
info: GraphQLResolveInfo, | ||
): ((result: any) => void) | void; | ||
executionDidEnd?(): void; | ||
requestDidEnd?(): void; | ||
format?(): [string, any] | undefined; | ||
public format?(): [string, any] | undefined; | ||
} | ||
export class GraphQLExtensionStack<TContext = any> { | ||
private extensions: GraphQLExtension[]; | ||
private extensions: GraphQLExtension<TContext>[]; | ||
constructor(extensions: (typeof GraphQLExtension | GraphQLExtension)[]) { | ||
this.extensions = extensions.map(extension => { | ||
return typeof extension === 'function' ? new extension() : extension; | ||
}); | ||
constructor(extensions: GraphQLExtension<TContext>[]) { | ||
this.extensions = extensions; | ||
} | ||
requestDidStart(): void { | ||
for (const extension of this.extensions) { | ||
if (extension.requestDidStart) { | ||
extension.requestDidStart(); | ||
} | ||
} | ||
public requestDidStart(): (() => void) { | ||
return this.handleDidStart(ext => ext.requestDidStart); | ||
} | ||
parsingDidStart() { | ||
for (const extension of this.extensions) { | ||
if (extension.parsingDidStart) { | ||
extension.parsingDidStart(); | ||
} | ||
} | ||
public parsingDidStart(): (() => void) { | ||
return this.handleDidStart(ext => ext.parsingDidStart); | ||
} | ||
parsingDidEnd() { | ||
for (const extension of this.extensions) { | ||
if (extension.parsingDidEnd) { | ||
extension.parsingDidEnd(); | ||
} | ||
} | ||
public validationDidStart(): (() => void) { | ||
return this.handleDidStart(ext => ext.validationDidStart); | ||
} | ||
validationDidStart() { | ||
for (const extension of this.extensions) { | ||
if (extension.validationDidStart) { | ||
extension.validationDidStart(); | ||
} | ||
} | ||
public executionDidStart(): (() => void) { | ||
return this.handleDidStart(ext => ext.executionDidStart); | ||
} | ||
validationDidEnd() { | ||
for (const extension of this.extensions) { | ||
if (extension.validationDidEnd) { | ||
extension.validationDidEnd(); | ||
} | ||
} | ||
} | ||
executionDidStart() { | ||
for (const extension of this.extensions) { | ||
if (extension.executionDidStart) { | ||
extension.executionDidStart(); | ||
} | ||
} | ||
} | ||
willResolveField( | ||
public willResolveField( | ||
source: any, | ||
args: { [argName: string]: any }, | ||
context: TContext, | ||
info: GraphQLResolveInfo | ||
info: GraphQLResolveInfo, | ||
) { | ||
const handlers = this.extensions | ||
.map(extension => extension.willResolveField && extension.willResolveField(source, args, context, info)) | ||
.map( | ||
extension => | ||
extension.willResolveField && | ||
extension.willResolveField(source, args, context, info), | ||
) | ||
.filter(x => x) as ((result: any) => void)[]; | ||
@@ -107,30 +71,38 @@ | ||
} | ||
} | ||
}; | ||
} | ||
executionDidEnd() { | ||
for (const extension of this.extensions) { | ||
if (extension.executionDidEnd) { | ||
extension.executionDidEnd(); | ||
} | ||
} | ||
public format() { | ||
return (this.extensions | ||
.map(extension => extension.format && extension.format()) | ||
.filter(x => x) as [string, any][]).reduce( | ||
(extensions, [key, value]) => Object.assign(extensions, { [key]: value }), | ||
{}, | ||
); | ||
} | ||
requestDidEnd() { | ||
for (const extension of this.extensions) { | ||
if (extension.requestDidEnd) { | ||
extension.requestDidEnd(); | ||
private handleDidStart(selectHandler: HandlerSelector): EndHandler { | ||
const endHandlers: EndHandler[] = []; | ||
this.extensions.forEach(extension => { | ||
const startHandler = selectHandler(extension); | ||
if (startHandler) { | ||
const endHandler = startHandler(); | ||
if (endHandler) { | ||
endHandlers.push(endHandler); | ||
} | ||
} | ||
} | ||
}); | ||
return () => { | ||
// We run end handlers in reverse order of start handlers. That way, the | ||
// first handler in the stack "surrounds" the entire event's process | ||
// (helpful for tracing/reporting!) | ||
endHandlers.reverse(); | ||
endHandlers.forEach(endHandler => endHandler()); | ||
}; | ||
} | ||
format() { | ||
return (this.extensions.map(extension => extension.format && extension.format()).filter(x => x) as [ | ||
string, | ||
any | ||
][]).reduce((extensions, [key, value]) => Object.assign(extensions, { [key]: value }), {}); | ||
} | ||
} | ||
export function enableGraphQLExtensions(schema: GraphQLSchema & { _extensionsEnabled?: boolean }) { | ||
export function enableGraphQLExtensions( | ||
schema: GraphQLSchema & { _extensionsEnabled?: boolean }, | ||
) { | ||
if (schema._extensionsEnabled) { | ||
@@ -151,3 +123,5 @@ return schema; | ||
const extensionStack = context && context._extensionStack; | ||
const handler = extensionStack && extensionStack.willResolveField(source, args, context, info); | ||
const handler = | ||
extensionStack && | ||
extensionStack.willResolveField(source, args, context, info); | ||
@@ -158,9 +132,14 @@ // If no resolver has been defined for a field, use the default field resolver | ||
try { | ||
const result = (fieldResolver || defaultFieldResolver)(source, args, context, info); | ||
const result = (fieldResolver || defaultFieldResolver)( | ||
source, | ||
args, | ||
context, | ||
info, | ||
); | ||
whenResultIsFinished(result, () => { | ||
handler && handler(result); | ||
if (handler) handler(result); | ||
}); | ||
return result; | ||
} catch (error) { | ||
handler && handler(); | ||
if (handler) handler(); | ||
throw error; | ||
@@ -198,3 +177,6 @@ } | ||
if (!getNamedType(type).name.startsWith('__') && type instanceof GraphQLObjectType) { | ||
if ( | ||
!getNamedType(type).name.startsWith('__') && | ||
type instanceof GraphQLObjectType | ||
) { | ||
const fields = type.getFields(); | ||
@@ -209,2 +191,6 @@ Object.keys(fields).forEach(fieldName => { | ||
export type FieldIteratorFn = (fieldDef: GraphQLField<any, any>, typeName: string, fieldName: string) => void; | ||
export type FieldIteratorFn = ( | ||
fieldDef: GraphQLField<any, any>, | ||
typeName: string, | ||
fieldName: string, | ||
) => void; |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
22876
15
456
10