[@graphql-codegen/flutter-freezed] Generated enums are not used in freezed models, advanced codegen configuration is not possible
Which packages are impacted by your issue?
@graphql-codegen/flutter-freezed
Describe the bug
I have the following schema:
enum REAL_ESTATE_TYPE {
APARTMENT
DETACHED_HOUSE
APARTMENT_BUILDING
PROPERTY
COMMERCIAL
}
type RealEstate{
type: REAL_ESTATE_TYPE!
monthly_rent: Int!
property_value: Int!
year_of_purchase: Int!
postal_code: String!
}
All of our enums are named in all caps and snake case. The enum gets generated correctly and looks like this:
enum RealEstateType {
@JsonKey(name: 'APARTMENT')
apartment,
@JsonKey(name: 'APARTMENT_BUILDING')
apartmentBuilding,
@JsonKey(name: 'COMMERCIAL')
commercial,
@JsonKey(name: 'DETACHED_HOUSE')
detachedHouse,
@JsonKey(name: 'PROPERTY')
property,
}
Unfortunately this enum is not used and reflected in the resulting class:
@Freezed(
copyWith: true,
)
class RealEstate with _$RealEstate {
const RealEstate._();
const factory RealEstate({
@JsonKey(name: 'monthly_rent')
required int monthlyRent,
@JsonKey(name: 'postal_code')
required String postalCode,
@JsonKey(name: 'property_value')
required int propertyValue,
required REAL_ESTATE_TYPE type,
@JsonKey(name: 'year_of_purchase')
required int yearOfPurchase,
}) = _RealEstate;
factory RealEstate.fromJson(Map<String, dynamic> json) => _$RealEstateFromJson(json);
}
Your Example Website or App
https://stackblitz.com/edit/github-wt29hz?file=schema.graphql
Steps to Reproduce the Bug or Issue
npm run generate
Expected behavior
I would like to do more customization via the codegen.ts file but I'm unable to do that since the types used for advanced configuration options are not exported by the flutter-freezed package itself as mentioned in this issue. Because of this I'm not able to used the Config type that is used in the guide.
How can I customize the naming of enums in my GraphQL schema and how should this be configured in my codegen.ts? Should the building block APPLIES_ON_ENUM be used?
Screenshots or Videos
No response
Platform
"dependencies": { "graphql": "^16.2.0" }, "devDependencies": { "@graphql-codegen/cli": "^3.3.0", "@graphql-codegen/flutter-freezed": "^3.0.2", "typescript": "^4.8.4" }
Codegen Config File
import { CodegenConfig } from '@graphql-codegen/cli';
const config: CodegenConfig = {
schema: 'schema.graphql',
generates: {
'entities_gen.dart': {
plugins: {
'flutter-freezed': {
copyWith: true,
},
},
},
},
};
export default config;
Additional context
I would really appreciate a small example on how to configure this correctly in my codegen.ts file. Thank you!
@peer-f
I apologize for the delay in my response. I was away for some time but I am back now and ready to assist you.
Thank you for bringing the issue to my attention. I assure you that I will resolve it as soon as possible.
I am grateful that you tried out the flutter-freezed plugin.
Thank you again.
To address your issue flutter-freezed v3.1.0 will include a renameAs option in the config,
allowing you to map the TypeNames and FieldNames in your GraphQL schema to custom ones.
I will give you a sample and update your stackblitz example .
@peer-f
a temporal workaround to fix this issue until flutter-freezed v3.1.0 is released,
use the customScalar option to treat the current type as a custom type.
I forked and updated your Stackblitz demo
import { CodegenConfig } from '@graphql-codegen/cli';
const config: CodegenConfig = {
schema: 'schema.graphql',
generates: {
'entities_gen.dart': {
plugins: {
'flutter-freezed': {
copyWith: true,
customScalars: {
REAL_ESTATE_TYPE: 'RealEstateType',
},
},
},
},
},
};
export default config;
which produces the following output
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:flutter/foundation.dart';
part 'entities_gen.freezed.dart';
part 'entities_gen.g.dart';
enum RealEstateType {
@JsonKey(name: 'APARTMENT')
apartment,
@JsonKey(name: 'APARTMENT_BUILDING')
apartmentBuilding,
@JsonKey(name: 'COMMERCIAL')
commercial,
@JsonKey(name: 'DETACHED_HOUSE')
detachedHouse,
@JsonKey(name: 'PROPERTY')
property,
}
@Freezed(
copyWith: true,
)
class RealEstate with _$RealEstate {
const RealEstate._();
const factory RealEstate({
@JsonKey(name: 'monthly_rent')
required int monthlyRent,
@JsonKey(name: 'postal_code')
required String postalCode,
@JsonKey(name: 'property_value')
required int propertyValue,
required RealEstateType type,
@JsonKey(name: 'year_of_purchase')
required int yearOfPurchase,
}) = _RealEstate;
factory RealEstate.fromJson(Map<String, dynamic> json) => _$RealEstateFromJson(json);
}
After carefully looking at the issue, here is what is caused the issue:
This plugin tries to follow Dart recommended linting rules. Therefore:
classes and Enums are PascalCased
all fields/properties/parameters are camelCased
except for Enum values which can be configured using the camelCasedEnums option
In your graphql schema, your Enum was named REAL_ESTATE_TYPE
and that's why the plugin PascalCased it to RealEstateType
This is not a bug with the plugin. On the contrary, it is a feature.
If you have control over the GraphQL Schema, I suggest you stick with standard naming conventions: PascalCase for your GraphQL Types and camelCase for the fields.
If not, then what I earlier on called a workaround is your only solution.
The customScalar option will allow you to specify how to handle custom types.
The GraphQL TypeName is specified as the key, and how it should be generated as the value.
If the key is missing in the customScalar config option, then the GraphQL TypeName is used as it is.
That is why the plugin generated REAL_ESTATE_TYPE as the dart type of the type parameter
instead of RealEstateType.
Implementing a config option renameAs as I proposed earlier will make this plugin quite complex
and would take some time to get it done right so I am dropping that feature.
Please close this issue if I have addressed your problem.
Thank you for surfacing this up.
P.s: I have fixed this issue so update the plugin once the PR is merged and released
https://github.com/dotansimha/graphql-code-generator-community/issues/319
@peer-f install the latest version: npm i @graphql-codegen/[email protected]
https://www.npmjs.com/package/@graphql-codegen/flutter-freezed/v/4.0.0-alpha-20230823221342-8db60f2d0
https://stackblitz.com/edit/github-jzk7hh-emmwwm?file=package.json
Schema.graphql
enum BookCategory {
BusinessCareer
Family
}
Generate
enum BookCategory {
@JsonKey(name: 'BusinessCareer')
businessCareer,
@JsonKey(name: 'Family')
family,
}
freezed generate
const _$BookCategoryEnumMap = {
BookCategory.businessCareer: 'businessCareer',
BookCategory.family: 'family',
}
freezed use $enumDecode(_$BookCategoryEnumMap, e); to trans from json.
got error
Invalid argument(s): `BusinessCareer` is not one of the supported values: businessCareer, family,