generateLibrarySpec function

Spec generateLibrarySpec(
  1. LibraryDefinition definition,
  2. GeneratorOptions options
)

Gathers and generates a Spec of a whole query/mutation and its dependencies into a single library file.

Implementation

Spec generateLibrarySpec(
  LibraryDefinition definition,
  GeneratorOptions options,
) {
  final importDirectives = [
    Directive.import('package:json_annotation/json_annotation.dart'),
    Directive.import('package:gql/ast.dart'),
    Directive.import('package:equatable/equatable.dart'),
  ];

  if (definition.queries.any((q) => q.generateHelpers)) {
    importDirectives.insertAll(0, [
      Directive.import('package:dartpollo/dartpollo.dart'),
    ]);
  }

  importDirectives.addAll(definition.customImports.map(Directive.import));

  final bodyDirectives = <Spec>[
    CodeExpression(Code('part \'${definition.basename}.g.dart\';')),
  ];

  final uniqueDefinitions = definition.queries
      .map((e) => e.classes.map((e) => e))
      .expand((e) => e)
      .fold<Map<String?, Definition>>(<String?, Definition>{}, (acc, element) {
        acc[element.name.name] = element;

        return acc;
      })
      .values;

  final fragments = uniqueDefinitions.whereType<FragmentClassDefinition>();
  final classes = uniqueDefinitions.whereType<ClassDefinition>();
  var enums = uniqueDefinitions.whereType<EnumDefinition>();

  if (definition.schemaMap?.convertEnumToString ?? false) {
    // Filter out enums that are not referenced in any class
    final enumNames = classes
        .expand((c) => c.properties)
        .map((p) => p.type.dartTypeSafe)
        .whereType<String>()
        .toSet();

    enums = enums.where((e) => enumNames.contains(e.name.namePrintable));
  }

  bodyDirectives
    ..addAll(fragments.map(fragmentClassDefinitionToSpec))
    ..addAll(
      classes.map((cDef) => classDefinitionToSpec(cDef, fragments, classes)),
    )
    ..addAll(enums.map(enumDefinitionToSpec));

  for (final queryDef in definition.queries) {
    if (queryDef.inputs.isNotEmpty &&
        (queryDef.generateHelpers || queryDef.generateQueries)) {
      bodyDirectives.add(generateArgumentClassSpec(queryDef));
    }

    if (queryDef.generateHelpers || queryDef.generateQueries) {
      bodyDirectives.add(
        generateQuerySpec(
          queryDef,
          optimizeDocumentNodes: options.optimizeDocumentNodes,
        ),
      );
    }

    if (queryDef.generateHelpers) {
      bodyDirectives.add(generateQueryClassSpec(queryDef));
    }
  }

  return Library(
    (b) => b
      ..directives.addAll(importDirectives)
      ..body.addAll(bodyDirectives),
  );
}