diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 0fe75aea..5c91a667 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -34,6 +34,7 @@ When releasing a new version: - Fixed non-deterministic generated code when querying graphql interfaces. - Fixed generated code when last component of package name is not a valid identifier (e.g. `"path/to/my-package"`). - Fixed incorrect documentation of `for` directive. +- Fixed bug where `omitempty` JSON tags were not being correctly applied to `__premarshal` structs. ## v0.5.0 diff --git a/generate/marshal.go.tmpl b/generate/marshal.go.tmpl index 19f1ea91..87718578 100644 --- a/generate/marshal.go.tmpl +++ b/generate/marshal.go.tmpl @@ -31,9 +31,9 @@ type __premarshal{{.GoName}} struct{ {{range .FlattenedFields -}} {{if .NeedsMarshaling -}} - {{.GoName}} {{repeat .GoType.SliceDepth "[]"}}{{ref "encoding/json.RawMessage"}} `json:"{{.JSONName}}"` + {{.GoName}} {{repeat .GoType.SliceDepth "[]"}}{{ref "encoding/json.RawMessage"}} `json:"{{.JSONName}}{{if .Omitempty -}},omitempty{{end}}"` {{else}} - {{.GoName}} {{.GoType.Reference}} `json:"{{.JSONName}}"` + {{.GoName}} {{.GoType.Reference}} `json:"{{.JSONName}}{{if .Omitempty -}},omitempty{{end}}"` {{end}} {{end}} } diff --git a/generate/testdata/queries/Hasura.graphql b/generate/testdata/queries/Hasura.graphql new file mode 100644 index 00000000..52cb3fac --- /dev/null +++ b/generate/testdata/queries/Hasura.graphql @@ -0,0 +1,7 @@ +# @genqlient(pointer: true) +query GetPokemon($where: getPokemonBoolExp!) { + getPokemon(where: $where) { + species + level + } +} diff --git a/generate/testdata/queries/schema.graphql b/generate/testdata/queries/schema.graphql index a83396f7..f6b3a689 100644 --- a/generate/testdata/queries/schema.graphql +++ b/generate/testdata/queries/schema.graphql @@ -180,8 +180,28 @@ type Query { listOfListsOfListsOfContent: [[[Content!]!]!]! recur(input: RecursiveInput!): Recursive acceptsListOfListOfListsOfDates(datesss: [[[Date!]!]!]!): Boolean + getPokemon(where: getPokemonBoolExp): [Pokemon!]! } type Mutation { createUser(name: String!, email: String): User } + +input getPokemonBoolExp { + _and: [getPokemonBoolExp!] + _not: getPokemonBoolExp + _or: [getPokemonBoolExp!] + level: IntComparisonExp +} + +input IntComparisonExp { + _eq: Int + _gt: Int + _gte: Int + _in: [Int!] + _isNull: Boolean + _lt: Int + _lte: Int + _neq: Int + _nin: [Int!] +} \ No newline at end of file diff --git a/generate/testdata/snapshots/TestGenerate-Hasura.graphql-Hasura.graphql.go b/generate/testdata/snapshots/TestGenerate-Hasura.graphql-Hasura.graphql.go new file mode 100644 index 00000000..313b82e9 --- /dev/null +++ b/generate/testdata/snapshots/TestGenerate-Hasura.graphql-Hasura.graphql.go @@ -0,0 +1,118 @@ +// Code generated by github.com/Khan/genqlient, DO NOT EDIT. + +package test + +import ( + "github.com/Khan/genqlient/graphql" + "github.com/Khan/genqlient/internal/testutil" +) + +type GetPokemonBoolExp struct { + And []*GetPokemonBoolExp `json:"_and"` + Not *GetPokemonBoolExp `json:"_not"` + Or []*GetPokemonBoolExp `json:"_or"` + Level *IntComparisonExp `json:"level"` +} + +// GetAnd returns GetPokemonBoolExp.And, and is useful for accessing the field via an interface. +func (v *GetPokemonBoolExp) GetAnd() []*GetPokemonBoolExp { return v.And } + +// GetNot returns GetPokemonBoolExp.Not, and is useful for accessing the field via an interface. +func (v *GetPokemonBoolExp) GetNot() *GetPokemonBoolExp { return v.Not } + +// GetOr returns GetPokemonBoolExp.Or, and is useful for accessing the field via an interface. +func (v *GetPokemonBoolExp) GetOr() []*GetPokemonBoolExp { return v.Or } + +// GetLevel returns GetPokemonBoolExp.Level, and is useful for accessing the field via an interface. +func (v *GetPokemonBoolExp) GetLevel() *IntComparisonExp { return v.Level } + +// GetPokemonResponse is returned by GetPokemon on success. +type GetPokemonResponse struct { + GetPokemon []*testutil.Pokemon `json:"getPokemon"` +} + +// GetGetPokemon returns GetPokemonResponse.GetPokemon, and is useful for accessing the field via an interface. +func (v *GetPokemonResponse) GetGetPokemon() []*testutil.Pokemon { return v.GetPokemon } + +type IntComparisonExp struct { + Eq *int `json:"_eq"` + Gt *int `json:"_gt"` + Gte *int `json:"_gte"` + In []*int `json:"_in"` + IsNull *bool `json:"_isNull"` + Lt *int `json:"_lt"` + Lte *int `json:"_lte"` + Neq *int `json:"_neq"` + Nin []*int `json:"_nin"` +} + +// GetEq returns IntComparisonExp.Eq, and is useful for accessing the field via an interface. +func (v *IntComparisonExp) GetEq() *int { return v.Eq } + +// GetGt returns IntComparisonExp.Gt, and is useful for accessing the field via an interface. +func (v *IntComparisonExp) GetGt() *int { return v.Gt } + +// GetGte returns IntComparisonExp.Gte, and is useful for accessing the field via an interface. +func (v *IntComparisonExp) GetGte() *int { return v.Gte } + +// GetIn returns IntComparisonExp.In, and is useful for accessing the field via an interface. +func (v *IntComparisonExp) GetIn() []*int { return v.In } + +// GetIsNull returns IntComparisonExp.IsNull, and is useful for accessing the field via an interface. +func (v *IntComparisonExp) GetIsNull() *bool { return v.IsNull } + +// GetLt returns IntComparisonExp.Lt, and is useful for accessing the field via an interface. +func (v *IntComparisonExp) GetLt() *int { return v.Lt } + +// GetLte returns IntComparisonExp.Lte, and is useful for accessing the field via an interface. +func (v *IntComparisonExp) GetLte() *int { return v.Lte } + +// GetNeq returns IntComparisonExp.Neq, and is useful for accessing the field via an interface. +func (v *IntComparisonExp) GetNeq() *int { return v.Neq } + +// GetNin returns IntComparisonExp.Nin, and is useful for accessing the field via an interface. +func (v *IntComparisonExp) GetNin() []*int { return v.Nin } + +// __GetPokemonInput is used internally by genqlient +type __GetPokemonInput struct { + Where *GetPokemonBoolExp `json:"where"` +} + +// GetWhere returns __GetPokemonInput.Where, and is useful for accessing the field via an interface. +func (v *__GetPokemonInput) GetWhere() *GetPokemonBoolExp { return v.Where } + +// The query or mutation executed by GetPokemon. +const GetPokemon_Operation = ` +query GetPokemon ($where: getPokemonBoolExp!) { + getPokemon(where: $where) { + species + level + } +} +` + +func GetPokemon( + client graphql.Client, + where *GetPokemonBoolExp, +) (*GetPokemonResponse, error) { + req := &graphql.Request{ + OpName: "GetPokemon", + Query: GetPokemon_Operation, + Variables: &__GetPokemonInput{ + Where: where, + }, + } + var err error + + var data GetPokemonResponse + resp := &graphql.Response{Data: &data} + + err = client.MakeRequest( + nil, + req, + resp, + ) + + return &data, err +} + diff --git a/generate/testdata/snapshots/TestGenerate-Hasura.graphql-Hasura.graphql.json b/generate/testdata/snapshots/TestGenerate-Hasura.graphql-Hasura.graphql.json new file mode 100644 index 00000000..ede08125 --- /dev/null +++ b/generate/testdata/snapshots/TestGenerate-Hasura.graphql-Hasura.graphql.json @@ -0,0 +1,9 @@ +{ + "operations": [ + { + "operationName": "GetPokemon", + "query": "\nquery GetPokemon ($where: getPokemonBoolExp!) {\n\tgetPokemon(where: $where) {\n\t\tspecies\n\t\tlevel\n\t}\n}\n", + "sourceLocation": "testdata/queries/Hasura.graphql" + } + ] +} diff --git a/generate/testdata/snapshots/TestGenerate-MultipleDirectives.graphql-MultipleDirectives.graphql.go b/generate/testdata/snapshots/TestGenerate-MultipleDirectives.graphql-MultipleDirectives.graphql.go index 6be4489b..356eef40 100644 --- a/generate/testdata/snapshots/TestGenerate-MultipleDirectives.graphql-MultipleDirectives.graphql.go +++ b/generate/testdata/snapshots/TestGenerate-MultipleDirectives.graphql-MultipleDirectives.graphql.go @@ -83,19 +83,19 @@ func (v *MyInput) UnmarshalJSON(b []byte) error { } type __premarshalMyInput struct { - Email *string `json:"email"` + Email *string `json:"email,omitempty"` - Name *string `json:"name"` + Name *string `json:"name,omitempty"` - Id *testutil.ID `json:"id"` + Id *testutil.ID `json:"id,omitempty"` - Role *Role `json:"role"` + Role *Role `json:"role,omitempty"` - Names []*string `json:"names"` + Names []*string `json:"names,omitempty"` - HasPokemon *testutil.Pokemon `json:"hasPokemon"` + HasPokemon *testutil.Pokemon `json:"hasPokemon,omitempty"` - Birthdate json.RawMessage `json:"birthdate"` + Birthdate json.RawMessage `json:"birthdate,omitempty"` } func (v *MyInput) MarshalJSON() ([]byte, error) { @@ -264,19 +264,19 @@ func (v *UserQueryInput) UnmarshalJSON(b []byte) error { } type __premarshalUserQueryInput struct { - Email *string `json:"email"` + Email *string `json:"email,omitempty"` - Name *string `json:"name"` + Name *string `json:"name,omitempty"` - Id *testutil.ID `json:"id"` + Id *testutil.ID `json:"id,omitempty"` - Role *Role `json:"role"` + Role *Role `json:"role,omitempty"` - Names []*string `json:"names"` + Names []*string `json:"names,omitempty"` - HasPokemon *testutil.Pokemon `json:"hasPokemon"` + HasPokemon *testutil.Pokemon `json:"hasPokemon,omitempty"` - Birthdate json.RawMessage `json:"birthdate"` + Birthdate json.RawMessage `json:"birthdate,omitempty"` } func (v *UserQueryInput) MarshalJSON() ([]byte, error) { diff --git a/generate/testdata/snapshots/TestGenerate-Omitempty.graphql-Omitempty.graphql.go b/generate/testdata/snapshots/TestGenerate-Omitempty.graphql-Omitempty.graphql.go index 5d8a9664..11c7fb0d 100644 --- a/generate/testdata/snapshots/TestGenerate-Omitempty.graphql-Omitempty.graphql.go +++ b/generate/testdata/snapshots/TestGenerate-Omitempty.graphql-Omitempty.graphql.go @@ -148,19 +148,19 @@ func (v *UserQueryInput) UnmarshalJSON(b []byte) error { } type __premarshalUserQueryInput struct { - Email string `json:"email"` + Email string `json:"email,omitempty"` - Name string `json:"name"` + Name string `json:"name,omitempty"` Id testutil.ID `json:"id"` - Role Role `json:"role"` + Role Role `json:"role,omitempty"` - Names []string `json:"names"` + Names []string `json:"names,omitempty"` - HasPokemon testutil.Pokemon `json:"hasPokemon"` + HasPokemon testutil.Pokemon `json:"hasPokemon,omitempty"` - Birthdate json.RawMessage `json:"birthdate"` + Birthdate json.RawMessage `json:"birthdate,omitempty"` } func (v *UserQueryInput) MarshalJSON() ([]byte, error) {