dotansimha / graphql-code-generator

A tool for generating code based on a GraphQL schema and GraphQL operations (query/mutation/subscription), with flexible support for custom plugins.
https://the-guild.dev/graphql/codegen/
MIT License
10.78k stars 1.32k forks source link

[RFC] Automate enumValues generation #3623

Open darkbasic opened 4 years ago

darkbasic commented 4 years ago

When dealing with SQL databases most of the times the enums will store simply integer values, like:

enum Sex {
  Male = 0,
  Female = 1
}

Having to specify the following for each of them could be annoying:

enumValues:
  Sex:
    MALE: 0
    FEMALE: 1

It would be nice to have a way to specify defaults other than the name of the value.

Something like:

enumDefaultValues: to-integer#toInteger

which would be obviously overridden by enumValues itself.

dotansimha commented 4 years ago

@darkbasic with enumValues you can point to a file and a enum identifier, without the need to deal specifically with each value. Does that help you? It should allow you to point it like that: enumValues: ./my-file#Sex

darkbasic commented 4 years ago

without the need to deal specifically with each value

@dotansimha in the codegen config maybe, but I will still have to specify the following in my-file:

export enum Sex {
  MALE = 0,
  FEMALE = 1
}

With your solution I will still have to manually create the enums I use for the SQL tables, which could be fine if our source of truth wasn't the schema. Because of that I'd rather generate the enums from the schema instead of having to duplicate them (one time is the schema and another time in the SQL-related code). If I use enumValues: ./all-my-enums and for some reason I want to add more keys to one of my enums (for example I want to add the Blue key to the Color enum because I want to support additional colors) then I will have to remember to update both the schema and all-my-enums.

On the contrary if we use functions to generate the enum values for us that won't be a problem anymore because we will have a single source of truth: the schema.

The following

enumDefaultType: enums#NumericFromZero
enumType:
  Sex: enums#NumericFromOne
  Color: enums#AllUppercase

would generate something like

export enum Status {
  PENDING = 0,
  ACCEPTED = 1,
  DECLINED = 2,
  BLOCKED = 3
}

export enum Cover {
  INDOOR = 0,
  BOTH = 1,
  OUTDOOR = 2
}

export enum Sex {
  MALE = 1,
  FEMALE = 2
}

export enum Color {
  GREEN = "GREEN",
  RED = "RED",
  BLUE = "BLUE"
}

and thus eliminating every kind of duplication, allowing to have a single source of thruth: the schema.

Obviously if you need a custom enum which doesn't obey any linear function to translate its keys to values, then you will still have to specify enumValues for that one.

dotansimha commented 4 years ago

I see. Got it. PRs are welcome ;)