private NodePrinter<InputValueDefinition> inputValueDefinition() { String nameTypeSep = compactMode ? ":" : ": "; String defaultValueEquals = compactMode ? "=" : "= "; return (out, node) -> { Value defaultValue = node.getDefaultValue(); out.printf("%s", comments(node)); out.printf("%s", spaced( node.getName() + nameTypeSep + type(node.getType()), wrap(defaultValueEquals, defaultValue, ""), directives(node.getDirectives()) ) ); }; }
@Override public InputValueDefinition deepCopy() { return new InputValueDefinition(name, deepCopy(type), deepCopy(defaultValue), deepCopy(directives), description, getSourceLocation(), getComments(), getIgnoredChars()); }
private Builder(InputValueDefinition existing) { this.sourceLocation = existing.getSourceLocation(); this.comments = existing.getComments(); this.name = existing.getName(); this.type = existing.getType(); this.defaultValue = existing.getDefaultValue(); this.description = existing.getDescription(); this.directives = existing.getDirectives(); }
private boolean isNoNullArgWithoutDefaultValue(InputValueDefinition definitionArgument) { return definitionArgument.getType() instanceof NonNullType && definitionArgument.getDefaultValue() == null; } }
private void checkArgInputObjectValueFieldMatchesAllowedDefinition(List<GraphQLError> errors, ObjectField objectField, InputValueDefinition allowedValueDef) { if (objectField != null) { checkArgValueMatchesAllowedType(errors, objectField.getValue(), allowedValueDef.getType()); return; } // check if field definition is required and has no default value if (allowedValueDef.getType() instanceof NonNullType && allowedValueDef.getDefaultValue() == null) { addValidationError(errors, MISSING_REQUIRED_FIELD_MESSAGE, allowedValueDef.getName()); } // other cases are // - field definition is marked as non-null but has a default value, so the default value can be used // - field definition is nullable hence null can be used }
private void checkForInputValueRedefinition(List<GraphQLError> errors, InputObjectTypeExtensionDefinition typeDefinition, List<InputValueDefinition> inputValueDefinitions, List<InputValueDefinition> referenceInputValues) { Map<String, InputValueDefinition> referenceMap = FpKit.getByName(referenceInputValues, InputValueDefinition::getName, mergeFirst()); inputValueDefinitions.forEach(fld -> { InputValueDefinition reference = referenceMap.get(fld.getName()); if (referenceMap.containsKey(fld.getName())) { // ok they have the same field but is it the same type if (!isSameType(fld.getType(), reference.getType())) { errors.add(new TypeExtensionFieldRedefinitionError(typeDefinition, fld)); } } }); }
public TypeExtensionFieldRedefinitionError(TypeDefinition typeDefinition, InputValueDefinition fieldDefinition) { super(typeDefinition, formatMessage(typeDefinition, fieldDefinition.getName(), fieldDefinition)); }
private void checkFieldsDirectives(List<GraphQLError> errors, TypeDefinitionRegistry typeRegistry, List<FieldDefinition> fieldDefinitions) { fieldDefinitions.forEach(definition -> { checkDirectives(FIELD_DEFINITION, errors, typeRegistry, definition, definition.getName(), definition.getDirectives()); // // and check its arguments definition.getInputValueDefinitions().forEach(arg -> checkDirectives(ARGUMENT_DEFINITION, errors, typeRegistry, arg, arg.getName(), arg.getDirectives())); }); }
@Override public TraversalControl visitInputValueDefinition(InputValueDefinition node, TraverserContext<Node> context) { InputValueDefinition changedNode = node.transform(builder -> { List<Directive> directives = sort(node.getDirectives(), comparing(Directive::getName)); builder.directives(directives); }); return changeNode(context, changedNode); }
private void checkDirectiveArguments(List<GraphQLError> errors, TypeDefinitionRegistry typeRegistry, Node element, String elementName, Directive directive, DirectiveDefinition directiveDefinition) { Map<String, InputValueDefinition> allowedArgs = getByName(directiveDefinition.getInputValueDefinitions(), (InputValueDefinition::getName), mergeFirst()); Map<String, Argument> providedArgs = getByName(directive.getArguments(), (Argument::getName), mergeFirst()); directive.getArguments().forEach(argument -> { InputValueDefinition allowedArg = allowedArgs.get(argument.getName()); if (allowedArg == null) { errors.add(new DirectiveUnknownArgumentError(element, elementName, directive.getName(), argument.getName())); } else { ArgValueOfAllowedTypeChecker argValueOfAllowedTypeChecker = new ArgValueOfAllowedTypeChecker(directive, element, elementName, argument, typeRegistry, runtimeWiring); argValueOfAllowedTypeChecker.checkArgValueMatchesAllowedType(errors, argument.getValue(), allowedArg.getType()); } }); allowedArgs.forEach((argName, definitionArgument) -> { if (isNoNullArgWithoutDefaultValue(definitionArgument)) { if (!providedArgs.containsKey(argName)) { errors.add(new DirectiveMissingNonNullArgumentError(element, elementName, directive.getName(), argName)); } } }); }
/** * Parses an AST value literal into the correct {@link graphql.language.Value} which * MUST be of the correct shape eg '"string"' or 'true' or '1' or '{ "object", "form" }' * or '[ "array", "form" ]' otherwise an exception is thrown * * @param astLiteral the string to parse an AST literal * * @return a valid Value * * @throws graphql.AssertException if the input can be parsed */ public static Value valueFromAst(String astLiteral) { // we use the parser to give us the AST elements as if we defined an inputType String toParse = "input X { x : String = " + astLiteral + "}"; try { Document doc = new Parser().parseDocument(toParse); InputObjectTypeDefinition inputType = (InputObjectTypeDefinition) doc.getDefinitions().get(0); InputValueDefinition inputValueDefinition = inputType.getInputValueDefinitions().get(0); return inputValueDefinition.getDefaultValue(); } catch (Exception e) { return Assert.assertShouldNeverHappen("valueFromAst of '%s' failed because of '%s'", astLiteral, e.getMessage()); } } }
private void checkInputValues(List<GraphQLError> errors, InputObjectTypeDefinition inputType, List<InputValueDefinition> inputValueDefinitions) { // field unique ness checkNamedUniqueness(errors, inputValueDefinitions, InputValueDefinition::getName, (name, inputValueDefinition) -> { // not sure why this is needed but inlining breaks it @SuppressWarnings("UnnecessaryLocalVariable") InputObjectTypeDefinition as = inputType; return new NonUniqueNameError(as, inputValueDefinition); }); // directive checks inputValueDefinitions.forEach(inputValueDef -> checkNamedUniqueness(errors, inputValueDef.getDirectives(), Directive::getName, (directiveName, directive) -> new NonUniqueDirectiveError(inputType, inputValueDef, directiveName))); inputValueDefinitions.forEach(inputValueDef -> inputValueDef.getDirectives().forEach(directive -> { checkDeprecatedDirective(errors, directive, () -> new InvalidDeprecationDirectiveError(inputType, inputValueDef)); checkNamedUniqueness(errors, directive.getArguments(), Argument::getName, (argumentName, argument) -> new NonUniqueArgumentError(inputType, inputValueDef, argumentName)); })); }
public InputValueDefinition build() { InputValueDefinition inputValueDefinition = new InputValueDefinition(name, type, defaultValue, directives, description, sourceLocation, comments, ignoredChars); return inputValueDefinition; } }
} else if (descriptionHolder instanceof GraphQLInputObjectField) { GraphQLInputObjectField type = (GraphQLInputObjectField) descriptionHolder; return descriptionAndComments(type::getDescription, type::getDefinition, () -> type.getDefinition().getDescription()); } else if (descriptionHolder instanceof GraphQLInterfaceType) { GraphQLInterfaceType type = (GraphQLInterfaceType) descriptionHolder; } else if (descriptionHolder instanceof GraphQLArgument) { GraphQLArgument type = (GraphQLArgument) descriptionHolder; return descriptionAndComments(type::getDescription, type::getDefinition, () -> type.getDefinition().getDescription()); } else { return Assert.assertShouldNeverHappen();
private GraphQLArgument buildDirectiveArgumentFromDefinition(InputValueDefinition arg, Function<Type, GraphQLInputType> inputTypeFactory) { GraphQLArgument.Builder builder = GraphQLArgument.newArgument() .name(arg.getName()) .definition(arg); GraphQLInputType inputType = inputTypeFactory.apply(arg.getType()); builder.type(inputType); builder.value(buildValue(arg.getDefaultValue(), inputType)); builder.defaultValue(buildValue(arg.getDefaultValue(), inputType)); return builder.build(); }
.typeName(old.getName()) .typeKind(getTypeKind(old)) .fieldName(oldField.getName()) .reasonMsg("\tExamining input field '%s' ...", mkDotName(old.getName(), oldField.getName())) .build()); .typeName(old.getName()) .typeKind(getTypeKind(old)) .fieldName(oldField.getName()) .reasonMsg("The new API is missing an input field '%s'", mkDotName(old.getName(), oldField.getName())) .build()); } else { DiffCategory category = checkTypeWithNonNullAndList(oldField.getType(), newField.get().getType()); if (category != null) { ctx.report(DiffEvent.apiBreakage() .typeName(old.getName()) .typeKind(getTypeKind(old)) .fieldName(oldField.getName()) .components(getAstDesc(oldField.getType()), getAstDesc(newField.get().getType())) .reasonMsg("The new API has changed input field '%s' from type '%s' to '%s'", oldField.getName(), getAstDesc(oldField.getType()), getAstDesc(newField.get().getType())) .build()); if (typeInfo(newField.getType()).isNonNull()) { ctx.report(DiffEvent.apiBreakage() .category(DiffCategory.STRICTER) .typeName(old.getName()) .typeKind(getTypeKind(old))
public NonUniqueNameError(InputObjectTypeDefinition typeDefinition, InputValueDefinition inputValueDefinition) { super(typeDefinition, format("The type '%s' %s has declared an input field with a non unique name '%s'", typeDefinition.getName(), lineCol(typeDefinition), inputValueDefinition.getName())); }
private void checkDirectives(DirectiveLocation expectedLocation, List<GraphQLError> errors, TypeDefinition<?> typeDef) { checkDirectives(expectedLocation, errors, typeRegistry, typeDef, typeDef.getName(), typeDef.getDirectives()); if (typeDef instanceof ObjectTypeDefinition) { List<FieldDefinition> fieldDefinitions = ((ObjectTypeDefinition) typeDef).getFieldDefinitions(); checkFieldsDirectives(errors, typeRegistry, fieldDefinitions); } if (typeDef instanceof InterfaceTypeDefinition) { List<FieldDefinition> fieldDefinitions = ((InterfaceTypeDefinition) typeDef).getFieldDefinitions(); checkFieldsDirectives(errors, typeRegistry, fieldDefinitions); } if (typeDef instanceof EnumTypeDefinition) { List<EnumValueDefinition> enumValueDefinitions = ((EnumTypeDefinition) typeDef).getEnumValueDefinitions(); enumValueDefinitions.forEach(definition -> checkDirectives(ENUM_VALUE, errors, typeRegistry, definition, definition.getName(), definition.getDirectives())); } if (typeDef instanceof InputObjectTypeDefinition) { List<InputValueDefinition> inputValueDefinitions = ((InputObjectTypeDefinition) typeDef).getInputValueDefinitions(); inputValueDefinitions.forEach(definition -> checkDirectives(INPUT_FIELD_DEFINITION, errors, typeRegistry, definition, definition.getName(), definition.getDirectives())); } }
private boolean isNoNullArgWithoutDefaultValue(InputValueDefinition definitionArgument) { return definitionArgument.getType() instanceof NonNullType && definitionArgument.getDefaultValue() == null; } }
@Override public TraversalControl visitInputValueDefinition(InputValueDefinition node, TraverserContext<Node> context) { InputValueDefinition changedNode = node.transform(builder -> { List<Directive> directives = sort(node.getDirectives(), comparing(Directive::getName)); builder.directives(directives); }); return changeNode(context, changedNode); }