@theguild/federation-composition
Version:
Open Source Composition library for Apollo Federation
43 lines (42 loc) • 1.94 kB
JavaScript
import { GraphQLError, Kind } from 'graphql';
import { print } from '../../../graphql/printer.js';
export function ProvidedRequiredArgumentsOnDirectivesRule(context) {
const requiredArgsMap = Object.create(null);
const astDefinitions = context.getDocument().definitions;
for (const def of astDefinitions) {
if (def.kind === Kind.DIRECTIVE_DEFINITION) {
const argNodes = def.arguments ?? [];
const requiredArgs = argNodes.filter(isRequiredArgumentNode);
requiredArgsMap[def.name.value] = {};
for (const requiredArg of requiredArgs) {
requiredArgsMap[def.name.value][requiredArg.name.value] = requiredArg;
}
}
}
return {
Directive: {
leave(directiveNode) {
const directiveName = directiveNode.name.value;
const requiredArgs = requiredArgsMap[directiveName];
if (requiredArgs) {
const argNodes = directiveNode.arguments ?? [];
const argNodeMap = new Set(argNodes.map(arg => arg.name.value));
for (const [argName, argDef] of Object.entries(requiredArgs)) {
if (!argNodeMap.has(argName)) {
const argType = print(argDef.type);
context.reportError(new GraphQLError(`Directive "@${directiveName}" argument "${argName}" of type "${argType}" is required, but it was not provided.`, {
nodes: directiveNode,
extensions: {
code: 'INVALID_GRAPHQL',
},
}));
}
}
}
},
},
};
}
function isRequiredArgumentNode(arg) {
return arg.type.kind === Kind.NON_NULL_TYPE && arg.defaultValue == null;
}