astFromValue function

ValueNode? astFromValue(
  1. Object? value,
  2. GraphQLType type
)

Returns an GraphQL Ast node from a Dart value, given the value's type

throws ArgumentError if type is not a GraphQL input type.

Implementation

ast.ValueNode? astFromValue(Object? value, GraphQLType type) {
  if (type is GraphQLNonNullType) {
    final astNode = astFromValue(value, type.ofType);
    if (astNode == const ast.NullValueNode()) {
      return null;
    }
    return astNode;
  }
  if (value == null) {
    return const ast.NullValueNode();
  }

  ast.ObjectValueNode astFromObject(
    Map<String, Object?> value,
    Iterable<ObjectField> fields,
  ) {
    return ast.ObjectValueNode(fields: [
      ...value.entries.map(
        (e) {
          final astNode = astFromValue(
            e.value,
            fields.firstWhere((f) => f.name == e.key).type,
          );
          if (astNode == null) {
            return null;
          }
          return ast.ObjectFieldNode(
            name: ast.NameNode(
              value: e.key,
            ),
            value: astNode,
          );
        },
      ).whereType(),
    ]);
  }

  return type.when(
    enum_: (enum_) => ast.EnumValueNode(
      name: ast.NameNode(
        value: enum_.serialize(value),
      ),
    ),
    scalar: (scalar) {
      final Object? serialized = type.serialize(value);
      return astFromUntypedValue(serialized);
    },
    input: (input) {
      return astFromObject(input.serializeSafe(value), input.fields);
    },
    object: (object) => throw ArgumentError(
      'astFromValue can only be called with input types,'
      ' received Object $object.',
    ),
    union: (union) => throw ArgumentError(
      'astFromValue can only be called with input types,'
      ' received Union $union.',
    ),
    list: (list) {
      if (value is List) {
        return ast.ListValueNode(values: [
          ...value.map((Object? e) => astFromValue(e, list.ofType)).whereType(),
        ]);
      }
      return astFromValue(value, list.ofType);
    },
    nonNullable: (nonNullable) => astFromValue(value, nonNullable.ofType),
  );
}