R/validation-input-coercion.R

Defines functions validate_value_can_be_coerced

validate_value_can_be_coerced <- function(
  from_input,
  to_type,
  ...,
  oh,
  rule_code
) {
  # A value must be provided if the type is non-null.
  if (inherits(to_type, "NonNullType")) {
    if (is.null(from_input)) {
      oh$error_list$add(
        rule_code,
        "Expected ",
        format(to_type),
        " found missing value.",
        loc = from_input$loc
      )
      return(FALSE)
    }

    if (inherits(from_input, "NullValue")) {
      oh$error_list$add(
        rule_code,
        "Expected ",
        format(to_type),
        " found null value.",
        loc = from_input$loc
      )
    }
    return(
      validate_value_can_be_coerced(
        from_input,
        to_type$type,
        oh = oh,
        rule_code = rule_code
      )
    )
  }
  # if null, then return valid
  if (is.null(from_input) || inherits(from_input, "NullValue")) {
    return(TRUE)
  }

  # // This function only tests literals, and assumes variables will provide
  # // values of the correct type.
  if (inherits(from_input, "Variable")) {
    str(from_input)
    stop("variables should not be sent here")
  }

  if (inherits(to_type, "ListType")) {
    list_type <- to_type$type

    if (inherits(from_input, "ListValue")) {
      for (from_value in from_input$values) {
        validate_value_can_be_coerced(
          from_value,
          list_type,
          oh = oh,
          rule_code = rule_code
        )
      }
      return(TRUE)
    }

    # a single item can be given as a list of size one
    return(
      validate_value_can_be_coerced(
        from_input,
        list_type,
        oh = oh,
        rule_code = rule_code
      )
    )
  }

  to_obj <- oh$schema$get_type(to_type)

  # // Input objects check each defined field and look for undefined fields.
  if (inherits(to_obj, "InputObjectTypeDefinition")) {
    if (!inherits(from_input, "ObjectValue")) {
      oh$error_list$add(
        rule_code,
        "Expected ",
        class(to_obj)[1],
        ", found not an object",
        loc = from_input$loc
      )
      return(FALSE)
    }

    # validate field names are unique
    validate_input_object_fields(from_input, oh = oh)

    # for each field...
    for (from_field in from_input$fields) {
      to_field <- to_obj$.get_field(from_field)

      # ensure matching field exists
      if (is.null(to_field)) {
        oh$error_list$add(
          rule_code,
          "In field: ",
          from_field$name$value,
          ": unknown field",
          loc = from_field$loc
        )
      }
    }

    # for "to field", make sure it is valid
    for (to_field in to_obj$fields) {
      from_field <- from_input$.get_field(to_field)
      # ensure field is valid
      validate_value_can_be_coerced(
        from_field$value,
        to_field$type,
        oh = oh,
        rule_code = rule_code
      )
    }

    return(TRUE)
  }

  ## should always be the case as it only can be fed from the json AST generated by graphql
  # invariant(
  #   type instanceof GraphQLScalarType || type instanceof GraphQLEnumType,
  #   'Must be input type'
  # );
  if (
    !(inherits(to_obj, "ScalarTypeDefinition") ||
      inherits(to_obj, "EnumTypeDefinition"))
  ) {
    str(to_obj)
    stop("Must be input type")
  }

  # make sure the resulting type can be coerced.  if it produces a NULL value, it can not be coerced
  result <- to_obj$.parse_ast(from_input, oh$schema)
  if (is.null(result)) {
    oh$error_list$add(
      rule_code,
      "Expected type ",
      format(to_type),
      ", found ",
      class(from_input)[1],
      loc = from_input$loc
    )
  }

  return(TRUE)
}

Try the gqlr package in your browser

Any scripts or data that you put into this service are public.

gqlr documentation built on Jan. 10, 2026, 1:06 a.m.