buildGraphQLCode function

CodeBuilder buildGraphQLCode(
  1. GraphQLScanResult model
)

Implementation

CodeBuilder buildGraphQLCode(GraphQLScanResult model) {
  final query = model.query;
  final mutation = model.mutation;
  final concreteName = model.className;

  var code = CodeBuilder();
  code += Field((f) => f
    ..name = '_nullDefaultValue'
    ..modifier = FieldModifier.constant
    ..assignment = Code("const DefaultValueNode(value: null)"));

  _log.info('Writing Operations');

  var allOperations = {'query': query.values, 'mutation': mutation.values};
  code += Class(
    (c) => c
      ..name = 'I${concreteName}'
      ..abstract = true
      ..methods.addAll([
        for (var operation in allOperations.values.expand((e) => e))
          Method((m) => m
            ..name = operation.name.value
            ..returns = refer('Future<${operation.type.toDartType()}>')
            ..body = null
            ..optionalParameters.addAll(
              operation.args.map(
                (p) => p.toParameter(),
              ),
            )),

        // ..requiredParameters = Future<${operation.type.toDartType()}>
        // ${operation.name.value}(${opParamDeclaration(doc, operation.args)});',
      ]),
  );

  model.addAllModels(code);

  _log.info('Writing Class');
  code += [
    'class ${concreteName} extends _${concreteName} implements I${concreteName} {',
    '  final GraphQLClientGetter client;',
    '  final GraphSerializer serializer;',
    '  ${concreteName}({GraphQLClientGetter? client, GraphSerializer? serializer,}):',
    '       client = client ?? (()=>GraphClientConfig.client),',
    '       serializer = serializer ?? FactoryGraphSerializer()',
    ';',
    '',
  ];

  _log.info('Writing Operation Schemas');
  for (var set in allOperations.entries) {
    for (var query in set.value) {
      code += [
        """
  static const ${query.name.value}Op = const OperationDefinitionNode(
    type: OperationType.${set.key.toLowerCase()},
    name: NameNode(value: "${query.name.value}"),
    variableDefinitions: [
    """,
        for (var variable in query.args)
          """
      VariableDefinitionNode(
        variable: VariableNode(
            name: NameNode( value: "${variable.name.value}"),
          ),
          defaultValue: _nullDefaultValue,
          type: NamedTypeNode(
            name: NameNode(
                value: '${variable.type.toGQLType()}'
              ),
            isNonNull: ${variable.type.isNonNull},
        ),
      ),
            """,
        """
    ],
    selectionSet: SelectionSetNode(
      selections: [
        FieldNode(
            name: NameNode(value: "${query.name.value}"),
            arguments: [""",
        for (var arg in query.args)
          '            ArgumentNode(name: NameNode(value: "${arg.name.value}"), value: VariableNode(name: NameNode(value: "${arg.name.value}"))),',
        """
            ],
            selectionSet: SelectionSetNode(selections: [
              ${query.type.toSelectionNode(model.doc)}
            ],
          ),
        )
      ],
    ),
  );
  """,
        '',
        '  @override',
        '  Future<${query.type.toDartType()}> ${query.name.value}(${opParamDeclaration(model.doc, query.args)}) async {',
        """
      var result = await this.client().queryManager.${set == 'query' ? 'query(Query' : 'mutate(Mutation'}Options(
                              document: DocumentNode(definitions: [${query.name.value}Op, ${model.fragmentDepends.getAll(query).join(',')}]),
                              operationName: "${query.name.value}",
                              variables: {${opParams(model.doc, query.args)}}));

      if (result.hasException) {
        throw result.exception!;
      }

      return this.serializer.read${query.type is ListTypeNode ? 'List' : ''}(result.data!["${query.name.value}"], typeName: "${query.type.toRawType()}", isNullable: ${!query.type.isNonNull});
                """,
        '  }',
      ];
    }
  }
  code += '}';

  buildSerializer(model, code);
  _log.info('Writing Subqueries');
  model.subqueries.forEach((objName, q) {
    code += Class((c) => c
      ..name = '${objName.capitalize()}Api'
      ..abstract = true
      ..methods.addAll([
        for (var sub in q.values)
          Method((m) => m
            ..name = 'load${sub.field.name.value.capitalize()}'
            ..optionalParameters.addAll(sub.field.args.map((a) => a.toParameter()))),
      ]));
  });
  _log.info('Done!');
  return code;
}