61 lines
2.7 KiB
JavaScript
61 lines
2.7 KiB
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
|