@kamilkisiela/graphql-tools
Version:
Useful tools to create and manipulate GraphQL schemas.
61 lines • 2.79 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
var graphql_1 = require("graphql");
// wraps all resolve functions of query, mutation or subscription fields
// with the provided function to simulate a root schema level resolve funciton
function addSchemaLevelResolveFunction(schema, fn) {
// TODO test that schema is a schema, fn is a function
var rootTypes = [
schema.getQueryType(),
schema.getMutationType(),
schema.getSubscriptionType(),
].filter(function (x) { return !!x; });
rootTypes.forEach(function (type) {
// XXX this should run at most once per request to simulate a true root resolver
// for graphql-js this is an approximation that works with queries but not mutations
var rootResolveFn = runAtMostOncePerRequest(fn);
var fields = type.getFields();
Object.keys(fields).forEach(function (fieldName) {
// XXX if the type is a subscription, a same query AST will be ran multiple times so we
// deactivate here the runOnce if it's a subscription. This may not be optimal though...
if (type === schema.getSubscriptionType()) {
fields[fieldName].resolve = wrapResolver(fields[fieldName].resolve, fn);
}
else {
fields[fieldName].resolve = wrapResolver(fields[fieldName].resolve, rootResolveFn);
}
});
});
}
// XXX badly named function. this doesn't really wrap, it just chains resolvers...
function wrapResolver(innerResolver, outerResolver) {
return function (obj, args, ctx, info) {
return Promise.resolve(outerResolver(obj, args, ctx, info)).then(function (root) {
if (innerResolver) {
return innerResolver(root, args, ctx, info);
}
return graphql_1.defaultFieldResolver(root, args, ctx, info);
});
};
}
// XXX this function only works for resolvers
// XXX very hacky way to remember if the function
// already ran for this request. This will only work
// if people don't actually cache the operation.
// if they do cache the operation, they will have to
// manually remove the __runAtMostOnce before every request.
function runAtMostOncePerRequest(fn) {
var value;
var randomNumber = Math.random();
return function (root, args, ctx, info) {
if (!info.operation['__runAtMostOnce']) {
info.operation['__runAtMostOnce'] = {};
}
if (!info.operation['__runAtMostOnce'][randomNumber]) {
info.operation['__runAtMostOnce'][randomNumber] = true;
value = fn(root, args, ctx, info);
}
return value;
};
}
exports.default = addSchemaLevelResolveFunction;
//# sourceMappingURL=addSchemaLevelResolveFunction.js.map