diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e389aa2..23d2e630 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # CHANGELOG +## 6.9.2-beta.1 +- Fixed `toJson() doesn't remove "kw$" prefix` + ## 6.8.2-beta.1 - test fix diff --git a/lib/generator.dart b/lib/generator.dart index 66b0d6d7..40df47a7 100644 --- a/lib/generator.dart +++ b/lib/generator.dart @@ -338,8 +338,14 @@ Make sure your query is correct and your schema is updated.'''); ); } + final name = fieldAlias ?? fieldName; + // On custom scalars - final annotations = []; + final jsonKeyAnnotation = {}; + if (name.namePrintable != name.name) { + jsonKeyAnnotation['name'] = '\'${name.name}\''; + } + if (nextType is ScalarTypeDefinitionNode) { final scalar = gql.getSingleScalarMap(context.options, nextType.name.value); @@ -351,8 +357,10 @@ Make sure your query is correct and your schema is updated.'''); dartType: false, schema: context.schema) .dartTypeSafe); final dartTypeSafeStr = TypeName(name: dartTypeName.dartTypeSafe); - annotations.add( - 'JsonKey(fromJson: fromGraphQL${graphqlTypeSafeStr.namePrintable}ToDart${dartTypeSafeStr.namePrintable}, toJson: fromDart${dartTypeSafeStr.namePrintable}ToGraphQL${graphqlTypeSafeStr.namePrintable},)'); + jsonKeyAnnotation['fromJson'] = + 'fromGraphQL${graphqlTypeSafeStr.namePrintable}ToDart${dartTypeSafeStr.namePrintable}'; + jsonKeyAnnotation['toJson'] = + 'fromDart${dartTypeSafeStr.namePrintable}ToGraphQL${graphqlTypeSafeStr.namePrintable}'; } } // On enums else if (nextType is EnumTypeDefinitionNode) { @@ -361,20 +369,22 @@ Make sure your query is correct and your schema is updated.'''); } if (fieldType is! ListTypeNode) { - annotations.add( - 'JsonKey(unknownEnumValue: ${dartTypeName.namePrintable}.${ARTEMIS_UNKNOWN.name.namePrintable})'); + jsonKeyAnnotation['unknownEnumValue'] = + '${dartTypeName.namePrintable}.${ARTEMIS_UNKNOWN.name.namePrintable}'; } } - final name = fieldAlias ?? fieldName; - - if (name.namePrintable != name.name) { - annotations.add('JsonKey(name: \'${name.name}\')'); - } - final fieldDirectives = regularField?.directives ?? regularInputField?.directives; + var annotations = []; + + if (jsonKeyAnnotation.isNotEmpty) { + final jsonKey = jsonKeyAnnotation.entries + .map((e) => '${e.key}: ${e.value}') + .join(', '); + annotations.add('JsonKey(${jsonKey})'); + } annotations.addAll(_proceedDeprecated(fieldDirectives)); return ClassProperty( @@ -553,12 +563,13 @@ class _GeneratorVisitor extends RecursiveVisitor { replaceLeafWith: ClassName.fromPath(path: nextClassName), schema: context.schema); - final annotations = []; + final jsonKeyAnnotation = {}; + if (leafType is EnumTypeDefinitionNode) { context.usedEnums.add(EnumName(name: leafType.name.value)); if (node.type is! ListTypeNode) { - annotations.add( - 'JsonKey(unknownEnumValue: ${EnumName(name: dartTypeName.name).namePrintable}.${ARTEMIS_UNKNOWN.name.namePrintable})'); + jsonKeyAnnotation['unknownEnumValue'] = + '${EnumName(name: dartTypeName.name).namePrintable}.${ARTEMIS_UNKNOWN.name.namePrintable}'; } } else if (leafType is InputObjectTypeDefinitionNode) { addUsedInputObjectsAndEnums(leafType); @@ -574,11 +585,22 @@ class _GeneratorVisitor extends RecursiveVisitor { dartType: false, schema: context.schema) .dartTypeSafe); final dartTypeSafeStr = TypeName(name: dartTypeName.dartTypeSafe); - annotations.add( - 'JsonKey(fromJson: fromGraphQL${graphqlTypeSafeStr.namePrintable}ToDart${dartTypeSafeStr.namePrintable}, toJson: fromDart${dartTypeSafeStr.namePrintable}ToGraphQL${graphqlTypeSafeStr.namePrintable},)'); + jsonKeyAnnotation['fromJson'] = + 'fromGraphQL${graphqlTypeSafeStr.namePrintable}ToDart${dartTypeSafeStr.namePrintable}'; + jsonKeyAnnotation['toJson'] = + 'fromDart${dartTypeSafeStr.namePrintable}ToGraphQL${graphqlTypeSafeStr.namePrintable}'; } } + var annotations = []; + + if (jsonKeyAnnotation.isNotEmpty) { + final jsonKey = jsonKeyAnnotation.entries + .map((e) => '${e.key}: ${e.value}') + .join(', '); + annotations.add('JsonKey(${jsonKey})'); + } + context.inputsClasses.add(QueryInput( type: dartTypeName, name: QueryInputName(name: node.variable.name.value), diff --git a/pubspec.yaml b/pubspec.yaml index 9f09fa9b..8e77684f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: artemis -version: 6.8.2-beta.1 +version: 6.9.2-beta.1 description: Build dart types from GraphQL schemas and queries (using Introspection Query). homepage: https://github.com/comigor/artemis diff --git a/test/query_generator/enums/input_enum_list_test.dart b/test/query_generator/enums/input_enum_list_test.dart index f876f0fb..669a3951 100644 --- a/test/query_generator/enums/input_enum_list_test.dart +++ b/test/query_generator/enums/input_enum_list_test.dart @@ -78,8 +78,7 @@ final LibraryDefinition libraryDefinition = type: TypeName(name: r'ArticleType'), name: ClassPropertyName(name: r'article_type'), annotations: [ - r'JsonKey(unknownEnumValue: ArticleType.artemisUnknown)', - r'''JsonKey(name: 'article_type')''' + r'''JsonKey(name: 'article_type', unknownEnumValue: ArticleType.artemisUnknown)''' ], isNonNull: true, isResolveType: false) @@ -129,8 +128,7 @@ class BrowseArticles$Query$Article with EquatableMixin { String title; - @JsonKey(unknownEnumValue: ArticleType.artemisUnknown) - @JsonKey(name: 'article_type') + @JsonKey(name: 'article_type', unknownEnumValue: ArticleType.artemisUnknown) ArticleType articleType; @override diff --git a/test/query_generator/enums/kw_prefix_test.dart b/test/query_generator/enums/kw_prefix_test.dart new file mode 100644 index 00000000..a8463e1c --- /dev/null +++ b/test/query_generator/enums/kw_prefix_test.dart @@ -0,0 +1,184 @@ +// @dart = 2.8 + +import 'package:artemis/generator/data/data.dart'; +import 'package:artemis/generator/data/enum_value_definition.dart'; +import 'package:test/test.dart'; + +import '../../helpers.dart'; + +void main() { + group('On enums', () { + test( + 'Should correctly proceed enum fields with `kw` prefix', + () async => testGenerator( + query: query, + schema: r''' + type Query { + articles(titleWhere: ArticleTitleWhereConditions): [Article!] + } + + input ArticleTitleWhereConditions { + operator: SQLOperator + value: String + } + + type Article { + id: ID! + title: String! + } + + enum SQLOperator { + EQ + IN + } + ''', + libraryDefinition: libraryDefinition, + generatedFile: generatedFile, + ), + ); + }); +} + +const query = r''' + query SearchArticles($titleWhere: ArticleTitleWhereConditions) { + articles(titleWhere: $titleWhere) { + id + title + } + } +'''; + +final LibraryDefinition libraryDefinition = + LibraryDefinition(basename: r'query.graphql', queries: [ + QueryDefinition( + name: QueryName(name: r'SearchArticles$_Query'), + operationName: r'SearchArticles', + classes: [ + EnumDefinition(name: EnumName(name: r'SQLOperator'), values: [ + EnumValueDefinition(name: EnumValueName(name: r'EQ')), + EnumValueDefinition(name: EnumValueName(name: r'IN')), + EnumValueDefinition(name: EnumValueName(name: r'ARTEMIS_UNKNOWN')) + ]), + ClassDefinition( + name: ClassName(name: r'SearchArticles$_Query$_Article'), + properties: [ + ClassProperty( + type: TypeName(name: r'String'), + name: ClassPropertyName(name: r'id'), + isNonNull: true, + isResolveType: false), + ClassProperty( + type: TypeName(name: r'String'), + name: ClassPropertyName(name: r'title'), + isNonNull: true, + isResolveType: false) + ], + factoryPossibilities: {}, + typeNameField: TypeName(name: r'__typename'), + isInput: false), + ClassDefinition( + name: ClassName(name: r'SearchArticles$_Query'), + properties: [ + ClassProperty( + type: TypeName(name: r'List'), + name: ClassPropertyName(name: r'articles'), + isNonNull: false, + isResolveType: false) + ], + factoryPossibilities: {}, + typeNameField: TypeName(name: r'__typename'), + isInput: false), + ClassDefinition( + name: ClassName(name: r'ArticleTitleWhereConditions'), + properties: [ + ClassProperty( + type: TypeName(name: r'SQLOperator'), + name: ClassPropertyName(name: r'operator'), + annotations: [ + r'''JsonKey(name: 'operator', unknownEnumValue: SQLOperator.artemisUnknown)''' + ], + isNonNull: false, + isResolveType: false), + ClassProperty( + type: TypeName(name: r'String'), + name: ClassPropertyName(name: r'value'), + isNonNull: false, + isResolveType: false) + ], + factoryPossibilities: {}, + typeNameField: TypeName(name: r'__typename'), + isInput: true) + ], + inputs: [ + QueryInput( + type: TypeName(name: r'ArticleTitleWhereConditions'), + name: QueryInputName(name: r'titleWhere'), + isNonNull: false) + ], + generateHelpers: false, + suffix: r'Query') +]); + +const generatedFile = r'''// GENERATED CODE - DO NOT MODIFY BY HAND + +import 'package:json_annotation/json_annotation.dart'; +import 'package:equatable/equatable.dart'; +import 'package:gql/ast.dart'; +part 'query.graphql.g.dart'; + +@JsonSerializable(explicitToJson: true) +class SearchArticles$Query$Article with EquatableMixin { + SearchArticles$Query$Article(); + + factory SearchArticles$Query$Article.fromJson(Map json) => + _$SearchArticles$Query$ArticleFromJson(json); + + String id; + + String title; + + @override + List get props => [id, title]; + Map toJson() => _$SearchArticles$Query$ArticleToJson(this); +} + +@JsonSerializable(explicitToJson: true) +class SearchArticles$Query with EquatableMixin { + SearchArticles$Query(); + + factory SearchArticles$Query.fromJson(Map json) => + _$SearchArticles$QueryFromJson(json); + + List articles; + + @override + List get props => [articles]; + Map toJson() => _$SearchArticles$QueryToJson(this); +} + +@JsonSerializable(explicitToJson: true) +class ArticleTitleWhereConditions with EquatableMixin { + ArticleTitleWhereConditions({this.kw$operator, this.value}); + + factory ArticleTitleWhereConditions.fromJson(Map json) => + _$ArticleTitleWhereConditionsFromJson(json); + + @JsonKey(name: 'operator', unknownEnumValue: SQLOperator.artemisUnknown) + SQLOperator kw$operator; + + String value; + + @override + List get props => [kw$operator, value]; + Map toJson() => _$ArticleTitleWhereConditionsToJson(this); +} + +enum SQLOperator { + @JsonValue('EQ') + eq, + @JsonValue('IN') + kw$IN, + @JsonValue('ARTEMIS_UNKNOWN') + artemisUnknown, +} +'''; diff --git a/test/query_generator/mutations_and_inputs/custom_scalars_on_input_objects_test.dart b/test/query_generator/mutations_and_inputs/custom_scalars_on_input_objects_test.dart index 5e112bfc..05aad3b3 100644 --- a/test/query_generator/mutations_and_inputs/custom_scalars_on_input_objects_test.dart +++ b/test/query_generator/mutations_and_inputs/custom_scalars_on_input_objects_test.dart @@ -96,7 +96,7 @@ final LibraryDefinition libraryDefinition = type: TypeName(name: r'MyUuid'), name: ClassPropertyName(name: r'id'), annotations: [ - r'JsonKey(fromJson: fromGraphQLMyUuidToDartMyUuid, toJson: fromDartMyUuidToGraphQLMyUuid,)' + r'JsonKey(fromJson: fromGraphQLMyUuidToDartMyUuid, toJson: fromDartMyUuidToGraphQLMyUuid)' ], isNonNull: true, isResolveType: false) @@ -115,14 +115,14 @@ final LibraryDefinition libraryDefinition = name: QueryInputName(name: r'previousId'), isNonNull: false, annotations: [ - r'JsonKey(fromJson: fromGraphQLMyUuidToDartMyUuid, toJson: fromDartMyUuidToGraphQLMyUuid,)' + r'JsonKey(fromJson: fromGraphQLMyUuidToDartMyUuid, toJson: fromDartMyUuidToGraphQLMyUuid)' ]), QueryInput( type: TypeName(name: r'List'), name: QueryInputName(name: r'listIds'), isNonNull: false, annotations: [ - r'JsonKey(fromJson: fromGraphQLListMyUuidToDartListMyUuid, toJson: fromDartListMyUuidToGraphQLListMyUuid,)' + r'JsonKey(fromJson: fromGraphQLListMyUuidToDartListMyUuid, toJson: fromDartListMyUuidToGraphQLListMyUuid)' ]) ], generateHelpers: true, @@ -180,9 +180,8 @@ class Input with EquatableMixin { factory Input.fromJson(Map json) => _$InputFromJson(json); @JsonKey( - fromJson: fromGraphQLMyUuidToDartMyUuid, - toJson: fromDartMyUuidToGraphQLMyUuid, - ) + fromJson: fromGraphQLMyUuidToDartMyUuid, + toJson: fromDartMyUuidToGraphQLMyUuid) MyUuid id; @override @@ -201,15 +200,13 @@ class CustomArguments extends JsonSerializable with EquatableMixin { final Input input; @JsonKey( - fromJson: fromGraphQLMyUuidToDartMyUuid, - toJson: fromDartMyUuidToGraphQLMyUuid, - ) + fromJson: fromGraphQLMyUuidToDartMyUuid, + toJson: fromDartMyUuidToGraphQLMyUuid) final MyUuid previousId; @JsonKey( - fromJson: fromGraphQLListMyUuidToDartListMyUuid, - toJson: fromDartListMyUuidToGraphQLListMyUuid, - ) + fromJson: fromGraphQLListMyUuidToDartListMyUuid, + toJson: fromDartListMyUuidToGraphQLListMyUuid) final List listIds; @override diff --git a/test/query_generator/scalars/custom_scalars_test.dart b/test/query_generator/scalars/custom_scalars_test.dart index 8659b37b..d41961ae 100644 --- a/test/query_generator/scalars/custom_scalars_test.dart +++ b/test/query_generator/scalars/custom_scalars_test.dart @@ -136,7 +136,7 @@ final LibraryDefinition libraryDefinitionWithCustomParserFns = type: TypeName(name: r'MyDartUuid'), name: ClassPropertyName(name: r'a'), annotations: [ - r'JsonKey(fromJson: fromGraphQLMyUuidToDartMyDartUuid, toJson: fromDartMyDartUuidToGraphQLMyUuid,)' + r'JsonKey(fromJson: fromGraphQLMyUuidToDartMyDartUuid, toJson: fromDartMyDartUuidToGraphQLMyUuid)' ], isNonNull: false, isResolveType: false) @@ -164,7 +164,7 @@ final LibraryDefinition libraryDefinitionWithCustomImports = type: TypeName(name: r'MyUuid'), name: ClassPropertyName(name: r'a'), annotations: [ - r'JsonKey(fromJson: fromGraphQLMyUuidToDartMyUuid, toJson: fromDartMyUuidToGraphQLMyUuid,)' + r'JsonKey(fromJson: fromGraphQLMyUuidToDartMyUuid, toJson: fromDartMyUuidToGraphQLMyUuid)' ], isNonNull: false, isResolveType: false) @@ -219,9 +219,8 @@ class Query$SomeObject with EquatableMixin { _$Query$SomeObjectFromJson(json); @JsonKey( - fromJson: fromGraphQLMyUuidToDartMyDartUuid, - toJson: fromDartMyDartUuidToGraphQLMyUuid, - ) + fromJson: fromGraphQLMyUuidToDartMyDartUuid, + toJson: fromDartMyDartUuidToGraphQLMyUuid) MyDartUuid a; @override @@ -248,9 +247,8 @@ class Query$SomeObject with EquatableMixin { _$Query$SomeObjectFromJson(json); @JsonKey( - fromJson: fromGraphQLMyUuidToDartMyUuid, - toJson: fromDartMyUuidToGraphQLMyUuid, - ) + fromJson: fromGraphQLMyUuidToDartMyUuid, + toJson: fromDartMyUuidToGraphQLMyUuid) MyUuid a; @override