createClassProperty function

ClassProperty createClassProperty({
  1. required ClassPropertyName fieldName,
  2. ClassPropertyName? fieldAlias,
  3. required Context context,
  4. OnNewClassFoundCallback? onNewClassFound,
  5. bool markAsUsed = true,
})

Creates class property object

Implementation

ClassProperty createClassProperty({
  required ClassPropertyName fieldName,
  ClassPropertyName? fieldAlias,
  required Context context,
  OnNewClassFoundCallback? onNewClassFound,
  bool markAsUsed = true,
}) {
  if (fieldName.name == context.schemaMap.typeNameField) {
    return ClassProperty(
      type: TypeName(name: 'String'),
      name: fieldName,
      annotations: ['JsonKey(name: \'${context.schemaMap.typeNameField}\')'],
      isResolveType: true,
    );
  }

  var finalFields = <Node>[];

  if (context.currentType is ObjectTypeDefinitionNode) {
    finalFields = (context.currentType as ObjectTypeDefinitionNode).fields;
  } else if (context.currentType is InterfaceTypeDefinitionNode) {
    finalFields = (context.currentType as InterfaceTypeDefinitionNode).fields;
  } else if (context.currentType is InputObjectTypeDefinitionNode) {
    finalFields = (context.currentType as InputObjectTypeDefinitionNode).fields;
  }

  final regularField = finalFields
      .whereType<FieldDefinitionNode>()
      .firstWhereOrNull((f) => f.name.value == fieldName.name);
  final regularInputField = finalFields
      .whereType<InputValueDefinitionNode>()
      .firstWhereOrNull((f) => f.name.value == fieldName.name);

  final fieldType = regularField?.type ?? regularInputField?.type;

  if (fieldType == null) {
    throw Exception(
        '''Field $fieldName was not found in GraphQL type ${context.currentType?.name.value}.
Make sure your query is correct and your schema is updated.''');
  }

  final nextType =
      gql.getTypeByName(context.typeDefinitionNodeVisitor, fieldType);

  final aliasedContext = context.withAlias(
    nextFieldName: fieldName,
    nextClassName: ClassName(name: nextType.name.value),
    alias: fieldAlias,
  );

  final nextClassName = aliasedContext.fullPathName();

  final dartTypeName = gql.buildTypeName(
    fieldType,
    context.options,
    dartType: true,
    replaceLeafWith: ClassName.fromPath(path: nextClassName),
    typeDefinitionNodeVisitor: context.typeDefinitionNodeVisitor,
  );

  logFn(context, aliasedContext.align + 1,
      '${aliasedContext.path}[${aliasedContext.currentType!.name.value}][${aliasedContext.currentClassName} ${aliasedContext.currentFieldName}] ${fieldAlias == null ? '' : '($fieldAlias) '}-> ${dartTypeName.namePrintable}');

  if ((nextType is ObjectTypeDefinitionNode ||
          nextType is UnionTypeDefinitionNode ||
          nextType is InterfaceTypeDefinitionNode) &&
      onNewClassFound != null) {
    ClassPropertyName? nextFieldName;

    if (regularField != null) {
      nextFieldName = ClassPropertyName(name: regularField.name.value);
    } else if (regularInputField != null) {
      nextFieldName = ClassPropertyName(name: regularInputField.name.value);
    }

    onNewClassFound(
      aliasedContext.next(
        nextType: nextType,
        nextFieldName: nextFieldName,
        nextClassName: ClassName(name: nextType.name.value),
        alias: fieldAlias,
        ofUnion: Nullable<TypeDefinitionNode?>(null),
      ),
    );
  }

  final name = fieldAlias ?? fieldName;

  // On custom scalars
  final jsonKeyAnnotation = <String, String>{};
  if (name.namePrintable != name.name) {
    jsonKeyAnnotation['name'] = '\'${name.name}\'';
  }

  if (nextType is ScalarTypeDefinitionNode) {
    final scalar = gql.getSingleScalarMap(context.options, nextType.name.value);

    if (scalar?.customParserImport != null &&
        nextType.name.value == scalar?.graphQLType) {
      final graphqlTypeName = gql.buildTypeName(
        fieldType,
        context.options,
        dartType: false,
        typeDefinitionNodeVisitor: context.typeDefinitionNodeVisitor,
      );

      jsonKeyAnnotation['fromJson'] =
          'fromGraphQL${graphqlTypeName.parserSafe}ToDart${dartTypeName.parserSafe}';
      jsonKeyAnnotation['toJson'] =
          'fromDart${dartTypeName.parserSafe}ToGraphQL${graphqlTypeName.parserSafe}';
    }
  } // On enums
  else if (nextType is EnumTypeDefinitionNode) {
    if (markAsUsed) {
      context.usedEnums.add(EnumName(name: nextType.name.value));
    }

    if (fieldType is ListTypeNode) {
      final innerDartTypeName = gql.buildTypeName(
        fieldType.type,
        context.options,
        dartType: true,
        replaceLeafWith: ClassName.fromPath(path: nextClassName),
        typeDefinitionNodeVisitor: context.typeDefinitionNodeVisitor,
      );
      jsonKeyAnnotation['unknownEnumValue'] =
          '${innerDartTypeName.dartTypeSafe}.${artemisUnknown.name.namePrintable}';
    } else {
      jsonKeyAnnotation['unknownEnumValue'] =
          '${dartTypeName.dartTypeSafe}.${artemisUnknown.name.namePrintable}';
    }
  }

  final fieldDirectives =
      regularField?.directives ?? regularInputField?.directives;

  var annotations = <String>[];

  if (jsonKeyAnnotation.isNotEmpty) {
    final jsonKey = jsonKeyAnnotation.entries
        .map<String>((e) => '${e.key}: ${e.value}')
        .join(', ');
    annotations.add('JsonKey($jsonKey)');
  }
  annotations.addAll(proceedDeprecated(fieldDirectives));

  return ClassProperty(
    type: dartTypeName,
    name: name,
    annotations: annotations,
  );
}