in src/main/com/intellij/lang/jsgraphql/types/schema/idl/ArgValueOfAllowedTypeChecker.java [129:184]
private void checkArgValueMatchesAllowedInputType(List<GraphQLError> errors,
@Nullable Value<?> instanceValue,
InputObjectTypeDefinition allowedTypeDefinition) {
if (!(instanceValue instanceof ObjectValue objectValue)) {
if (instanceValue != null) {
addValidationError(errors, EXPECTED_OBJECT_MESSAGE, instanceValue.getClass().getSimpleName());
}
return;
}
// duck typing validation, if it looks like the definition
// then it must be the same type as the definition
List<ObjectField> fields = objectValue.getObjectFields();
List<InputObjectTypeExtensionDefinition> inputObjExt =
typeRegistry.inputObjectTypeExtensions().getOrDefault(allowedTypeDefinition.getName(), emptyList());
Stream<InputValueDefinition> inputObjExtValues = inputObjExt.stream().flatMap(inputObj -> inputObj.getInputValueDefinitions().stream());
List<InputValueDefinition> inputValueDefinitions =
Stream.concat(allowedTypeDefinition.getInputValueDefinitions().stream(), inputObjExtValues).toList();
// check for duplicated fields
Map<String, Long> fieldsToOccurrenceMap = fields.stream().map(ObjectField::getName)
.collect(groupingBy(Function.identity(), counting()));
if (ContainerUtil.exists(fieldsToOccurrenceMap.values(), count -> count > 1)) {
addValidationError(errors, DUPLICATED_KEYS_MESSAGE, fieldsToOccurrenceMap.entrySet().stream()
.filter(entry -> entry.getValue() > 1)
.map(Map.Entry::getKey)
.collect(joining(",")));
return;
}
// check for unknown fields
Map<String, InputValueDefinition> nameToInputValueDefMap = inputValueDefinitions.stream()
.collect(toMap(InputValueDefinition::getName, inputValueDef -> inputValueDef));
List<ObjectField> unknownFields = ContainerUtil.filter(fields, field -> !nameToInputValueDefMap.containsKey(field.getName()));
if (!unknownFields.isEmpty()) {
addValidationError(errors, UNKNOWN_FIELDS_MESSAGE,
unknownFields.stream()
.map(ObjectField::getName)
.collect(joining(",")),
allowedTypeDefinition.getName());
return;
}
// fields to map for easy access
Map<String, ObjectField> nameToFieldsMap = fields.stream()
.collect(toMap(ObjectField::getName, objectField -> objectField));
// check each single field with its definition
inputValueDefinitions.forEach(allowedValueDef -> {
ObjectField objectField = nameToFieldsMap.get(allowedValueDef.getName());
checkArgInputObjectValueFieldMatchesAllowedDefinition(errors, objectField, allowedValueDef);
});
}