- FIELDS_ARE_VALID =
Rules.assert_named_items_are_valid("field", ->(type) { type.all_fields })
- HAS_ONE_OR_MORE_POSSIBLE_TYPES =
->(type) {
type.possible_types.length >= 1 ? nil : "must have at least one possible type"
}
- NAME_IS_STRING =
Rules.assert_property(:name, String)
- DESCRIPTION_IS_STRING_OR_NIL =
Rules.assert_property(:description, String, NilClass)
- ARGUMENTS_ARE_STRING_TO_ARGUMENT =
Rules.assert_property_mapping(:arguments, String, GraphQL::Argument)
- ARGUMENTS_ARE_VALID =
Rules.assert_named_items_are_valid("argument", ->(type) { type.arguments.values })
- DEFAULT_VALUE_IS_VALID_FOR_TYPE =
->(type) {
if !type.default_value.nil? && type.type.is_a?(NonNullType)
return %Q(Variable #{type.name} of type "#{type.type}" is required and will not use the default value. Perhaps you meant to use type "#{type.type.of_type}".)
end
if !type.default_value.nil?
coerced_value = begin
type.type.coerce_isolated_result(type.default_value)
rescue => ex
ex
end
if coerced_value.nil? || coerced_value.is_a?(StandardError)
msg = "default value #{type.default_value.inspect} is not valid for type #{type.type}"
msg += " (#{coerced_value})" if coerced_value.is_a?(StandardError)
msg
end
end
}
- TYPE_IS_VALID_INPUT_TYPE =
->(type) {
outer_type = type.type
inner_type = outer_type.is_a?(GraphQL::BaseType) ? outer_type.unwrap : nil
case inner_type
when GraphQL::ScalarType, GraphQL::InputObjectType, GraphQL::EnumType
else
"type must be a valid input type (Scalar or InputObject), not #{outer_type.class} (#{outer_type})"
end
}
- SCHEMA_CAN_RESOLVE_TYPES =
->(schema) {
if schema.types.values.any? { |type| type.kind.resolves? } && schema.resolve_type_proc.nil?
"schema contains Interfaces or Unions, so you must define a `resolve_type -> (obj, ctx) { ... }` function"
else
end
}
- SCHEMA_CAN_FETCH_IDS =
->(schema) {
has_node_field = schema.query && schema.query.all_fields.any?(&:relay_node_field)
if has_node_field && schema.object_from_id_proc.nil?
"schema contains `node(id:...)` field, so you must define a `object_from_id -> (id, ctx) { ... }` function"
else
end
}
- SCHEMA_CAN_GENERATE_IDS =
->(schema) {
has_id_field = schema.types.values.any? { |t| t.kind.fields? && t.all_fields.any? { |f| f.resolve_proc.is_a?(GraphQL::Relay::GlobalIdResolve) } }
if has_id_field && schema.id_from_object_proc.nil?
"schema contains `global_id_field`, so you must define a `id_from_object -> (obj, type, ctx) { ... }` function"
else
end
}
- SCHEMA_INSTRUMENTERS_ARE_VALID =
->(schema) {
errs = []
schema.instrumenters[:query].each do |inst|
if !inst.respond_to?(:before_query) || !inst.respond_to?(:after_query)
errs << "`instrument(:query, #{inst})` is invalid: must respond to `before_query(query)` and `after_query(query)` "
end
end
schema.instrumenters[:field].each do |inst|
if !inst.respond_to?(:instrument)
errs << "`instrument(:field, #{inst})` is invalid: must respond to `instrument(type, field)`"
end
end
if errs.any?
errs.join("Invalid instrumenters:\n" + errs.join("\n"))
else
nil
end
}
- RESERVED_TYPE_NAME =
->(type) {
if type.name.start_with?('__') && !type.introspection?
warn("Name #{type.name.inspect} must not begin with \"__\", which is reserved by GraphQL introspection.")
nil
else
end
}
- RESERVED_NAME =
->(named_thing) {
if named_thing.name.start_with?('__')
warn("Name #{named_thing.name.inspect} must not begin with \"__\", which is reserved by GraphQL introspection.")
nil
else
end
}
- INTERFACES_ARE_IMPLEMENTED =
->(obj_type) {
field_errors = []
obj_type.interfaces.each do |interface_type|
interface_type.fields.each do |field_name, field_defn|
object_field = obj_type.get_field(field_name)
if object_field.nil?
field_errors << %|"#{field_name}" is required by #{interface_type.name} but not implemented by #{obj_type.name}|
elsif !GraphQL::Execution::Typecast.subtype?(field_defn.type, object_field.type)
field_errors << %|"#{field_name}" is required by #{interface_type.name} to return #{field_defn.type} but #{obj_type.name}.#{field_name} returns #{object_field.type}|
else
field_defn.arguments.each do |arg_name, arg_defn|
object_field_arg = object_field.arguments[arg_name]
if object_field_arg.nil?
field_errors << %|"#{arg_name}" argument is required by #{interface_type.name}.#{field_name} but not accepted by #{obj_type.name}.#{field_name}|
elsif arg_defn.type != object_field_arg.type
field_errors << %|"#{arg_name}" is required by #{interface_type.name}.#{field_defn.name} to accept #{arg_defn.type} but #{obj_type.name}.#{field_name} accepts #{object_field_arg.type} for "#{arg_name}"|
end
end
object_field.arguments.each do |arg_name, arg_defn|
if field_defn.arguments[arg_name].nil? && arg_defn.type.is_a?(GraphQL::NonNullType)
field_errors << %|"#{arg_name}" is not accepted by #{interface_type.name}.#{field_name} but required by #{obj_type.name}.#{field_name}|
end
end
end
end
end
if field_errors.any?
"#{obj_type.name} failed to implement some interfaces: #{field_errors.join(", ")}"
else
nil
end
}