diff --git a/example/generated.go b/example/generated.go index 03607e4..a287c78 100644 --- a/example/generated.go +++ b/example/generated.go @@ -9,21 +9,31 @@ import ( "github.com/Khan/genqlient/graphql" ) +// getUserResponse is returned by getUser on success. type getUserResponse struct { + // Lookup a user by login. User getUserUser `json:"user"` } +// A user is an individual's account on GitHub that owns repositories and can make new content. type getUserUser struct { - TheirName string `json:"theirName"` + // The user's public profile name. + TheirName string `json:"theirName"` + // Identifies the date and time when the object was created. CreatedAt time.Time `json:"createdAt"` } +// getViewerResponse is returned by getViewer on success. type getViewerResponse struct { + // The currently authenticated user. Viewer getViewerViewerUser `json:"viewer"` } +// A user is an individual's account on GitHub that owns repositories and can make new content. type getViewerViewerUser struct { - MyName string `json:"MyName"` + // The user's public profile name. + MyName string `json:"MyName"` + // Identifies the date and time when the object was created. CreatedAt time.Time `json:"createdAt"` } diff --git a/generate/testdata/queries/DateTime.graphql.go b/generate/testdata/queries/DateTime.graphql.go index 58d5997..6063f36 100644 --- a/generate/testdata/queries/DateTime.graphql.go +++ b/generate/testdata/queries/DateTime.graphql.go @@ -8,6 +8,7 @@ import ( "github.com/Khan/genqlient/graphql" ) +// convertTimezoneResponse is returned by convertTimezone on success. type convertTimezoneResponse struct { Convert time.Time `json:"convert"` } diff --git a/generate/testdata/queries/EmptyInterface.graphql.go b/generate/testdata/queries/EmptyInterface.graphql.go index 0a8702f..5862462 100644 --- a/generate/testdata/queries/EmptyInterface.graphql.go +++ b/generate/testdata/queries/EmptyInterface.graphql.go @@ -6,6 +6,7 @@ import ( "github.com/Khan/genqlient/graphql" ) +// EmptyInterfaceResponse is returned by EmptyInterface on success. type EmptyInterfaceResponse struct { GetJunk interface{} `json:"getJunk"` GetComplexJunk []map[string]*[]*map[string]interface{} `json:"getComplexJunk"` diff --git a/generate/testdata/queries/InputEnum.graphql.go b/generate/testdata/queries/InputEnum.graphql.go index 3ccf7ae..fb6d6d8 100644 --- a/generate/testdata/queries/InputEnum.graphql.go +++ b/generate/testdata/queries/InputEnum.graphql.go @@ -7,18 +7,31 @@ import ( "github.com/me/mypkg" ) +// InputEnumQueryResponse is returned by InputEnumQuery on success. type InputEnumQueryResponse struct { + // usersWithRole looks a user up by role. UsersWithRole []InputEnumQueryUsersWithRoleUser `json:"usersWithRole"` } +// A User is a user! type InputEnumQueryUsersWithRoleUser struct { + // id is the user's ID. + // + // It is stable, unique, and opaque, like all good IDs. Id mypkg.ID `json:"id"` } +// Role is a type a user may have. type Role string const ( + // What is a student? + // + // A student is primarily a person enrolled in a school or other educational institution and who is under learning with goals of acquiring knowledge, developing professions and achieving employment at desired field. In the broader sense, a student is anyone who applies themselves to the intensive intellectual engagement with some matter necessary to master it as part of some practical affair in which such mastery is basic or decisive. + // + // (from [Wikipedia](https://en.wikipedia.org/wiki/Student)) RoleStudent Role = "STUDENT" + // Teacher is a teacher, who teaches the students. RoleTeacher Role = "TEACHER" ) diff --git a/generate/testdata/queries/InputObject.graphql.go b/generate/testdata/queries/InputObject.graphql.go index 834c49b..8ca67d3 100644 --- a/generate/testdata/queries/InputObject.graphql.go +++ b/generate/testdata/queries/InputObject.graphql.go @@ -7,24 +7,46 @@ import ( "github.com/me/mypkg" ) +// InputObjectQueryResponse is returned by InputObjectQuery on success. type InputObjectQueryResponse struct { + // user looks up a user by some stuff. + // + // See UserQueryInput for what stuff is supported. + // If query is null, returns the current user. User InputObjectQueryUser `json:"user"` } +// A User is a user! type InputObjectQueryUser struct { + // id is the user's ID. + // + // It is stable, unique, and opaque, like all good IDs. Id mypkg.ID `json:"id"` } +// Role is a type a user may have. type Role string const ( + // What is a student? + // + // A student is primarily a person enrolled in a school or other educational institution and who is under learning with goals of acquiring knowledge, developing professions and achieving employment at desired field. In the broader sense, a student is anyone who applies themselves to the intensive intellectual engagement with some matter necessary to master it as part of some practical affair in which such mastery is basic or decisive. + // + // (from [Wikipedia](https://en.wikipedia.org/wiki/Student)) RoleStudent Role = "STUDENT" + // Teacher is a teacher, who teaches the students. RoleTeacher Role = "TEACHER" ) +// UserQueryInput is the argument to Query.users. +// +// Ideally this would support anything and everything! +// Or maybe ideally it wouldn't. +// Really I'm just talking to make this documentation longer. type UserQueryInput struct { - Email string `json:"email"` - Name string `json:"name"` + Email string `json:"email"` + Name string `json:"name"` + // id looks the user up by ID. It's a great way to look up users. Id mypkg.ID `json:"id"` Role Role `json:"role"` Names []string `json:"names"` diff --git a/generate/testdata/queries/InterfaceNesting.graphql.go b/generate/testdata/queries/InterfaceNesting.graphql.go index a9047bd..f5fd0e1 100644 --- a/generate/testdata/queries/InterfaceNesting.graphql.go +++ b/generate/testdata/queries/InterfaceNesting.graphql.go @@ -9,11 +9,13 @@ import ( "github.com/me/mypkg" ) +// InterfaceNestingResponse is returned by InterfaceNesting on success. type InterfaceNestingResponse struct { Root InterfaceNestingRootTopic `json:"root"` } type InterfaceNestingRootTopic struct { + // ID is documented in the Content interface. Id mypkg.ID `json:"id"` Children []InterfaceNestingRootTopicChildrenContent `json:"-"` } @@ -66,6 +68,7 @@ func (v *InterfaceNestingRootTopic) UnmarshalJSON(b []byte) error { } type InterfaceNestingRootTopicChildrenArticle struct { + // ID is the identifier of the content. Id mypkg.ID `json:"id"` Parent InterfaceNestingRootTopicChildrenArticleParentTopic `json:"parent"` } @@ -74,6 +77,7 @@ func (v InterfaceNestingRootTopicChildrenArticle) implementsGraphQLInterfaceInte } type InterfaceNestingRootTopicChildrenArticleParentTopic struct { + // ID is documented in the Content interface. Id mypkg.ID `json:"id"` Children []InterfaceNestingRootTopicChildrenArticleParentTopicChildrenContent `json:"-"` } @@ -126,17 +130,20 @@ func (v *InterfaceNestingRootTopicChildrenArticleParentTopic) UnmarshalJSON(b [] } type InterfaceNestingRootTopicChildrenArticleParentTopicChildrenArticle struct { + // ID is the identifier of the content. Id mypkg.ID `json:"id"` } func (v InterfaceNestingRootTopicChildrenArticleParentTopicChildrenArticle) implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenArticleParentTopicChildrenContent() { } +// Content is implemented by various types like Article, Video, and Topic. type InterfaceNestingRootTopicChildrenArticleParentTopicChildrenContent interface { implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenArticleParentTopicChildrenContent() } type InterfaceNestingRootTopicChildrenArticleParentTopicChildrenTopic struct { + // ID is the identifier of the content. Id mypkg.ID `json:"id"` } @@ -144,17 +151,20 @@ func (v InterfaceNestingRootTopicChildrenArticleParentTopicChildrenTopic) implem } type InterfaceNestingRootTopicChildrenArticleParentTopicChildrenVideo struct { + // ID is the identifier of the content. Id mypkg.ID `json:"id"` } func (v InterfaceNestingRootTopicChildrenArticleParentTopicChildrenVideo) implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenArticleParentTopicChildrenContent() { } +// Content is implemented by various types like Article, Video, and Topic. type InterfaceNestingRootTopicChildrenContent interface { implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenContent() } type InterfaceNestingRootTopicChildrenTopic struct { + // ID is the identifier of the content. Id mypkg.ID `json:"id"` Parent InterfaceNestingRootTopicChildrenTopicParentTopic `json:"parent"` } @@ -163,6 +173,7 @@ func (v InterfaceNestingRootTopicChildrenTopic) implementsGraphQLInterfaceInterf } type InterfaceNestingRootTopicChildrenTopicParentTopic struct { + // ID is documented in the Content interface. Id mypkg.ID `json:"id"` Children []InterfaceNestingRootTopicChildrenTopicParentTopicChildrenContent `json:"-"` } @@ -215,17 +226,20 @@ func (v *InterfaceNestingRootTopicChildrenTopicParentTopic) UnmarshalJSON(b []by } type InterfaceNestingRootTopicChildrenTopicParentTopicChildrenArticle struct { + // ID is the identifier of the content. Id mypkg.ID `json:"id"` } func (v InterfaceNestingRootTopicChildrenTopicParentTopicChildrenArticle) implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenTopicParentTopicChildrenContent() { } +// Content is implemented by various types like Article, Video, and Topic. type InterfaceNestingRootTopicChildrenTopicParentTopicChildrenContent interface { implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenTopicParentTopicChildrenContent() } type InterfaceNestingRootTopicChildrenTopicParentTopicChildrenTopic struct { + // ID is the identifier of the content. Id mypkg.ID `json:"id"` } @@ -233,6 +247,7 @@ func (v InterfaceNestingRootTopicChildrenTopicParentTopicChildrenTopic) implemen } type InterfaceNestingRootTopicChildrenTopicParentTopicChildrenVideo struct { + // ID is the identifier of the content. Id mypkg.ID `json:"id"` } @@ -240,6 +255,7 @@ func (v InterfaceNestingRootTopicChildrenTopicParentTopicChildrenVideo) implemen } type InterfaceNestingRootTopicChildrenVideo struct { + // ID is the identifier of the content. Id mypkg.ID `json:"id"` Parent InterfaceNestingRootTopicChildrenVideoParentTopic `json:"parent"` } @@ -248,6 +264,7 @@ func (v InterfaceNestingRootTopicChildrenVideo) implementsGraphQLInterfaceInterf } type InterfaceNestingRootTopicChildrenVideoParentTopic struct { + // ID is documented in the Content interface. Id mypkg.ID `json:"id"` Children []InterfaceNestingRootTopicChildrenVideoParentTopicChildrenContent `json:"-"` } @@ -300,17 +317,20 @@ func (v *InterfaceNestingRootTopicChildrenVideoParentTopic) UnmarshalJSON(b []by } type InterfaceNestingRootTopicChildrenVideoParentTopicChildrenArticle struct { + // ID is the identifier of the content. Id mypkg.ID `json:"id"` } func (v InterfaceNestingRootTopicChildrenVideoParentTopicChildrenArticle) implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenVideoParentTopicChildrenContent() { } +// Content is implemented by various types like Article, Video, and Topic. type InterfaceNestingRootTopicChildrenVideoParentTopicChildrenContent interface { implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenVideoParentTopicChildrenContent() } type InterfaceNestingRootTopicChildrenVideoParentTopicChildrenTopic struct { + // ID is the identifier of the content. Id mypkg.ID `json:"id"` } @@ -318,6 +338,7 @@ func (v InterfaceNestingRootTopicChildrenVideoParentTopicChildrenTopic) implemen } type InterfaceNestingRootTopicChildrenVideoParentTopicChildrenVideo struct { + // ID is the identifier of the content. Id mypkg.ID `json:"id"` } diff --git a/generate/testdata/queries/InterfaceNoFragments.graphql.go b/generate/testdata/queries/InterfaceNoFragments.graphql.go index d6ddc18..245f668 100644 --- a/generate/testdata/queries/InterfaceNoFragments.graphql.go +++ b/generate/testdata/queries/InterfaceNoFragments.graphql.go @@ -9,11 +9,13 @@ import ( "github.com/me/mypkg" ) +// InterfaceNoFragmentsQueryResponse is returned by InterfaceNoFragmentsQuery on success. type InterfaceNoFragmentsQueryResponse struct { Root InterfaceNoFragmentsQueryRootTopic `json:"root"` } type InterfaceNoFragmentsQueryRootTopic struct { + // ID is documented in the Content interface. Id mypkg.ID `json:"id"` Name string `json:"name"` Children []InterfaceNoFragmentsQueryRootTopicChildrenContent `json:"-"` @@ -67,6 +69,7 @@ func (v *InterfaceNoFragmentsQueryRootTopic) UnmarshalJSON(b []byte) error { } type InterfaceNoFragmentsQueryRootTopicChildrenArticle struct { + // ID is the identifier of the content. Id mypkg.ID `json:"id"` Name string `json:"name"` } @@ -74,11 +77,13 @@ type InterfaceNoFragmentsQueryRootTopicChildrenArticle struct { func (v InterfaceNoFragmentsQueryRootTopicChildrenArticle) implementsGraphQLInterfaceInterfaceNoFragmentsQueryRootTopicChildrenContent() { } +// Content is implemented by various types like Article, Video, and Topic. type InterfaceNoFragmentsQueryRootTopicChildrenContent interface { implementsGraphQLInterfaceInterfaceNoFragmentsQueryRootTopicChildrenContent() } type InterfaceNoFragmentsQueryRootTopicChildrenTopic struct { + // ID is the identifier of the content. Id mypkg.ID `json:"id"` Name string `json:"name"` } @@ -87,6 +92,7 @@ func (v InterfaceNoFragmentsQueryRootTopicChildrenTopic) implementsGraphQLInterf } type InterfaceNoFragmentsQueryRootTopicChildrenVideo struct { + // ID is the identifier of the content. Id mypkg.ID `json:"id"` Name string `json:"name"` } diff --git a/generate/testdata/queries/ListInput.graphql.go b/generate/testdata/queries/ListInput.graphql.go index 3728eb2..517b217 100644 --- a/generate/testdata/queries/ListInput.graphql.go +++ b/generate/testdata/queries/ListInput.graphql.go @@ -7,11 +7,20 @@ import ( "github.com/me/mypkg" ) +// ListInputQueryResponse is returned by ListInputQuery on success. type ListInputQueryResponse struct { + // user looks up a user by some stuff. + // + // See UserQueryInput for what stuff is supported. + // If query is null, returns the current user. User ListInputQueryUser `json:"user"` } +// A User is a user! type ListInputQueryUser struct { + // id is the user's ID. + // + // It is stable, unique, and opaque, like all good IDs. Id mypkg.ID `json:"id"` } diff --git a/generate/testdata/queries/ListOfListsOfLists.graphql.go b/generate/testdata/queries/ListOfListsOfLists.graphql.go index 88b8450..df67fce 100644 --- a/generate/testdata/queries/ListOfListsOfLists.graphql.go +++ b/generate/testdata/queries/ListOfListsOfLists.graphql.go @@ -6,6 +6,7 @@ import ( "github.com/Khan/genqlient/graphql" ) +// ListOfListsOfListsResponse is returned by ListOfListsOfLists on success. type ListOfListsOfListsResponse struct { ListOfListsOfLists [][][]string `json:"listOfListsOfLists"` } diff --git a/generate/testdata/queries/Omitempty.graphql.go b/generate/testdata/queries/Omitempty.graphql.go index 99d099f..fc5b900 100644 --- a/generate/testdata/queries/Omitempty.graphql.go +++ b/generate/testdata/queries/Omitempty.graphql.go @@ -9,26 +9,48 @@ import ( "github.com/me/mypkg" ) +// OmitEmptyQueryResponse is returned by OmitEmptyQuery on success. type OmitEmptyQueryResponse struct { + // user looks up a user by some stuff. + // + // See UserQueryInput for what stuff is supported. + // If query is null, returns the current user. User OmitEmptyQueryUser `json:"user"` MaybeConvert time.Time `json:"maybeConvert"` Convert2 time.Time `json:"convert2"` } +// A User is a user! type OmitEmptyQueryUser struct { + // id is the user's ID. + // + // It is stable, unique, and opaque, like all good IDs. Id mypkg.ID `json:"id"` } +// Role is a type a user may have. type Role string const ( + // What is a student? + // + // A student is primarily a person enrolled in a school or other educational institution and who is under learning with goals of acquiring knowledge, developing professions and achieving employment at desired field. In the broader sense, a student is anyone who applies themselves to the intensive intellectual engagement with some matter necessary to master it as part of some practical affair in which such mastery is basic or decisive. + // + // (from [Wikipedia](https://en.wikipedia.org/wiki/Student)) RoleStudent Role = "STUDENT" + // Teacher is a teacher, who teaches the students. RoleTeacher Role = "TEACHER" ) +// UserQueryInput is the argument to Query.users. +// +// Ideally this would support anything and everything! +// Or maybe ideally it wouldn't. +// Really I'm just talking to make this documentation longer. type UserQueryInput struct { - Email string `json:"email"` - Name string `json:"name"` + Email string `json:"email"` + Name string `json:"name"` + // id looks the user up by ID. It's a great way to look up users. Id mypkg.ID `json:"id"` Role Role `json:"role"` Names []string `json:"names"` diff --git a/generate/testdata/queries/Pointers.graphql.go b/generate/testdata/queries/Pointers.graphql.go index eb46e05..c716cb5 100644 --- a/generate/testdata/queries/Pointers.graphql.go +++ b/generate/testdata/queries/Pointers.graphql.go @@ -9,17 +9,34 @@ import ( "github.com/me/mypkg" ) +// A User is a user! type PointersQueryOtherUser struct { + // id is the user's ID. + // + // It is stable, unique, and opaque, like all good IDs. Id *mypkg.ID `json:"id"` } +// PointersQueryResponse is returned by PointersQuery on success. type PointersQueryResponse struct { - User *PointersQueryUser `json:"user"` + // user looks up a user by some stuff. + // + // See UserQueryInput for what stuff is supported. + // If query is null, returns the current user. + User *PointersQueryUser `json:"user"` + // user looks up a user by some stuff. + // + // See UserQueryInput for what stuff is supported. + // If query is null, returns the current user. OtherUser *PointersQueryOtherUser `json:"otherUser"` MaybeConvert *time.Time `json:"maybeConvert"` } +// A User is a user! type PointersQueryUser struct { + // id is the user's ID. + // + // It is stable, unique, and opaque, like all good IDs. Id *mypkg.ID `json:"id"` Roles []*Role `json:"roles"` Name *string `json:"name"` @@ -27,16 +44,29 @@ type PointersQueryUser struct { EmailsNoPtr []string `json:"emailsNoPtr"` } +// Role is a type a user may have. type Role string const ( + // What is a student? + // + // A student is primarily a person enrolled in a school or other educational institution and who is under learning with goals of acquiring knowledge, developing professions and achieving employment at desired field. In the broader sense, a student is anyone who applies themselves to the intensive intellectual engagement with some matter necessary to master it as part of some practical affair in which such mastery is basic or decisive. + // + // (from [Wikipedia](https://en.wikipedia.org/wiki/Student)) RoleStudent Role = "STUDENT" + // Teacher is a teacher, who teaches the students. RoleTeacher Role = "TEACHER" ) +// UserQueryInput is the argument to Query.users. +// +// Ideally this would support anything and everything! +// Or maybe ideally it wouldn't. +// Really I'm just talking to make this documentation longer. type UserQueryInput struct { - Email *string `json:"email"` - Name *string `json:"name"` + Email *string `json:"email"` + Name *string `json:"name"` + // id looks the user up by ID. It's a great way to look up users. Id *mypkg.ID `json:"id"` Role *Role `json:"role"` Names []*string `json:"names"` diff --git a/generate/testdata/queries/PointersInline.graphql.go b/generate/testdata/queries/PointersInline.graphql.go index c598041..8696432 100644 --- a/generate/testdata/queries/PointersInline.graphql.go +++ b/generate/testdata/queries/PointersInline.graphql.go @@ -9,17 +9,34 @@ import ( "github.com/me/mypkg" ) +// A User is a user! type PointersQueryOtherUser struct { + // id is the user's ID. + // + // It is stable, unique, and opaque, like all good IDs. Id mypkg.ID `json:"id"` } +// PointersQueryResponse is returned by PointersQuery on success. type PointersQueryResponse struct { - User *PointersQueryUser `json:"user"` + // user looks up a user by some stuff. + // + // See UserQueryInput for what stuff is supported. + // If query is null, returns the current user. + User *PointersQueryUser `json:"user"` + // user looks up a user by some stuff. + // + // See UserQueryInput for what stuff is supported. + // If query is null, returns the current user. OtherUser *PointersQueryOtherUser `json:"otherUser"` MaybeConvert time.Time `json:"maybeConvert"` } +// A User is a user! type PointersQueryUser struct { + // id is the user's ID. + // + // It is stable, unique, and opaque, like all good IDs. Id mypkg.ID `json:"id"` Roles []Role `json:"roles"` Name *string `json:"name"` @@ -27,16 +44,29 @@ type PointersQueryUser struct { EmailsNoPtr []*string `json:"emailsNoPtr"` } +// Role is a type a user may have. type Role string const ( + // What is a student? + // + // A student is primarily a person enrolled in a school or other educational institution and who is under learning with goals of acquiring knowledge, developing professions and achieving employment at desired field. In the broader sense, a student is anyone who applies themselves to the intensive intellectual engagement with some matter necessary to master it as part of some practical affair in which such mastery is basic or decisive. + // + // (from [Wikipedia](https://en.wikipedia.org/wiki/Student)) RoleStudent Role = "STUDENT" + // Teacher is a teacher, who teaches the students. RoleTeacher Role = "TEACHER" ) +// UserQueryInput is the argument to Query.users. +// +// Ideally this would support anything and everything! +// Or maybe ideally it wouldn't. +// Really I'm just talking to make this documentation longer. type UserQueryInput struct { - Email string `json:"email"` - Name string `json:"name"` + Email string `json:"email"` + Name string `json:"name"` + // id looks the user up by ID. It's a great way to look up users. Id mypkg.ID `json:"id"` Role Role `json:"role"` Names []string `json:"names"` diff --git a/generate/testdata/queries/QueryWithAlias.graphql.go b/generate/testdata/queries/QueryWithAlias.graphql.go index a860ea3..e5af030 100644 --- a/generate/testdata/queries/QueryWithAlias.graphql.go +++ b/generate/testdata/queries/QueryWithAlias.graphql.go @@ -7,12 +7,24 @@ import ( "github.com/me/mypkg" ) +// QueryWithAliasResponse is returned by QueryWithAlias on success. type QueryWithAliasResponse struct { + // user looks up a user by some stuff. + // + // See UserQueryInput for what stuff is supported. + // If query is null, returns the current user. User QueryWithAliasUser `json:"User"` } +// A User is a user! type QueryWithAliasUser struct { - ID mypkg.ID `json:"ID"` + // id is the user's ID. + // + // It is stable, unique, and opaque, like all good IDs. + ID mypkg.ID `json:"ID"` + // id is the user's ID. + // + // It is stable, unique, and opaque, like all good IDs. OtherID mypkg.ID `json:"otherID"` } diff --git a/generate/testdata/queries/QueryWithDoubleAlias.graphql.go b/generate/testdata/queries/QueryWithDoubleAlias.graphql.go index 562dee8..5e98721 100644 --- a/generate/testdata/queries/QueryWithDoubleAlias.graphql.go +++ b/generate/testdata/queries/QueryWithDoubleAlias.graphql.go @@ -7,12 +7,24 @@ import ( "github.com/me/mypkg" ) +// QueryWithDoubleAliasResponse is returned by QueryWithDoubleAlias on success. type QueryWithDoubleAliasResponse struct { + // user looks up a user by some stuff. + // + // See UserQueryInput for what stuff is supported. + // If query is null, returns the current user. User QueryWithDoubleAliasUser `json:"user"` } +// A User is a user! type QueryWithDoubleAliasUser struct { - ID mypkg.ID `json:"ID"` + // id is the user's ID. + // + // It is stable, unique, and opaque, like all good IDs. + ID mypkg.ID `json:"ID"` + // id is the user's ID. + // + // It is stable, unique, and opaque, like all good IDs. AlsoID mypkg.ID `json:"AlsoID"` } diff --git a/generate/testdata/queries/QueryWithEnums.graphql.go b/generate/testdata/queries/QueryWithEnums.graphql.go index dbd14c6..7ff1c74 100644 --- a/generate/testdata/queries/QueryWithEnums.graphql.go +++ b/generate/testdata/queries/QueryWithEnums.graphql.go @@ -6,23 +6,41 @@ import ( "github.com/Khan/genqlient/graphql" ) +// A User is a user! type QueryWithEnumsOtherUser struct { Roles []Role `json:"roles"` } +// QueryWithEnumsResponse is returned by QueryWithEnums on success. type QueryWithEnumsResponse struct { - User QueryWithEnumsUser `json:"user"` + // user looks up a user by some stuff. + // + // See UserQueryInput for what stuff is supported. + // If query is null, returns the current user. + User QueryWithEnumsUser `json:"user"` + // user looks up a user by some stuff. + // + // See UserQueryInput for what stuff is supported. + // If query is null, returns the current user. OtherUser QueryWithEnumsOtherUser `json:"otherUser"` } +// A User is a user! type QueryWithEnumsUser struct { Roles []Role `json:"roles"` } +// Role is a type a user may have. type Role string const ( + // What is a student? + // + // A student is primarily a person enrolled in a school or other educational institution and who is under learning with goals of acquiring knowledge, developing professions and achieving employment at desired field. In the broader sense, a student is anyone who applies themselves to the intensive intellectual engagement with some matter necessary to master it as part of some practical affair in which such mastery is basic or decisive. + // + // (from [Wikipedia](https://en.wikipedia.org/wiki/Student)) RoleStudent Role = "STUDENT" + // Teacher is a teacher, who teaches the students. RoleTeacher Role = "TEACHER" ) diff --git a/generate/testdata/queries/QueryWithSlices.graphql.go b/generate/testdata/queries/QueryWithSlices.graphql.go index 6199565..bb729f5 100644 --- a/generate/testdata/queries/QueryWithSlices.graphql.go +++ b/generate/testdata/queries/QueryWithSlices.graphql.go @@ -6,10 +6,16 @@ import ( "github.com/Khan/genqlient/graphql" ) +// QueryWithSlicesResponse is returned by QueryWithSlices on success. type QueryWithSlicesResponse struct { + // user looks up a user by some stuff. + // + // See UserQueryInput for what stuff is supported. + // If query is null, returns the current user. User QueryWithSlicesUser `json:"user"` } +// A User is a user! type QueryWithSlicesUser struct { Emails []string `json:"emails"` EmailsOrNull []string `json:"emailsOrNull"` diff --git a/generate/testdata/queries/QueryWithStructs.graphql.go b/generate/testdata/queries/QueryWithStructs.graphql.go index 2e6ddf7..946727b 100644 --- a/generate/testdata/queries/QueryWithStructs.graphql.go +++ b/generate/testdata/queries/QueryWithStructs.graphql.go @@ -6,10 +6,16 @@ import ( "github.com/Khan/genqlient/graphql" ) +// QueryWithStructsResponse is returned by QueryWithStructs on success. type QueryWithStructsResponse struct { + // user looks up a user by some stuff. + // + // See UserQueryInput for what stuff is supported. + // If query is null, returns the current user. User QueryWithStructsUser `json:"user"` } +// A User is a user! type QueryWithStructsUser struct { AuthMethods []QueryWithStructsUserAuthMethodsAuthMethod `json:"authMethods"` } diff --git a/generate/testdata/queries/SimpleInput.graphql.go b/generate/testdata/queries/SimpleInput.graphql.go index 0aa7aa3..a01b42a 100644 --- a/generate/testdata/queries/SimpleInput.graphql.go +++ b/generate/testdata/queries/SimpleInput.graphql.go @@ -7,11 +7,20 @@ import ( "github.com/me/mypkg" ) +// SimpleInputQueryResponse is returned by SimpleInputQuery on success. type SimpleInputQueryResponse struct { + // user looks up a user by some stuff. + // + // See UserQueryInput for what stuff is supported. + // If query is null, returns the current user. User SimpleInputQueryUser `json:"user"` } +// A User is a user! type SimpleInputQueryUser struct { + // id is the user's ID. + // + // It is stable, unique, and opaque, like all good IDs. Id mypkg.ID `json:"id"` } diff --git a/generate/testdata/queries/SimpleMutation.graphql.go b/generate/testdata/queries/SimpleMutation.graphql.go index e38a345..6a22491 100644 --- a/generate/testdata/queries/SimpleMutation.graphql.go +++ b/generate/testdata/queries/SimpleMutation.graphql.go @@ -7,11 +7,16 @@ import ( "github.com/me/mypkg" ) +// A User is a user! type SimpleMutationCreateUser struct { + // id is the user's ID. + // + // It is stable, unique, and opaque, like all good IDs. Id mypkg.ID `json:"id"` Name string `json:"name"` } +// SimpleMutationResponse is returned by SimpleMutation on success. type SimpleMutationResponse struct { CreateUser SimpleMutationCreateUser `json:"createUser"` } diff --git a/generate/testdata/queries/SimpleQuery.graphql.go b/generate/testdata/queries/SimpleQuery.graphql.go index 4dde932..59e6d82 100644 --- a/generate/testdata/queries/SimpleQuery.graphql.go +++ b/generate/testdata/queries/SimpleQuery.graphql.go @@ -7,11 +7,20 @@ import ( "github.com/me/mypkg" ) +// SimpleQueryResponse is returned by SimpleQuery on success. type SimpleQueryResponse struct { + // user looks up a user by some stuff. + // + // See UserQueryInput for what stuff is supported. + // If query is null, returns the current user. User SimpleQueryUser `json:"user"` } +// A User is a user! type SimpleQueryUser struct { + // id is the user's ID. + // + // It is stable, unique, and opaque, like all good IDs. Id mypkg.ID `json:"id"` } diff --git a/generate/testdata/queries/TypeName.graphql.go b/generate/testdata/queries/TypeName.graphql.go index e286303..5d8f945 100644 --- a/generate/testdata/queries/TypeName.graphql.go +++ b/generate/testdata/queries/TypeName.graphql.go @@ -7,13 +7,22 @@ import ( "github.com/me/mypkg" ) +// TypeNameQueryResponse is returned by TypeNameQuery on success. type TypeNameQueryResponse struct { + // user looks up a user by some stuff. + // + // See UserQueryInput for what stuff is supported. + // If query is null, returns the current user. User TypeNameQueryUser `json:"user"` } +// A User is a user! type TypeNameQueryUser struct { - Typename string `json:"__typename"` - Id mypkg.ID `json:"id"` + Typename string `json:"__typename"` + // id is the user's ID. + // + // It is stable, unique, and opaque, like all good IDs. + Id mypkg.ID `json:"id"` } func TypeNameQuery( diff --git a/generate/testdata/queries/UnionNoFragments.graphql.go b/generate/testdata/queries/UnionNoFragments.graphql.go index 3907bea..7140826 100644 --- a/generate/testdata/queries/UnionNoFragments.graphql.go +++ b/generate/testdata/queries/UnionNoFragments.graphql.go @@ -15,6 +15,7 @@ type UnionNoFragmentsQueryRandomLeafArticle struct { func (v UnionNoFragmentsQueryRandomLeafArticle) implementsGraphQLInterfaceUnionNoFragmentsQueryRandomLeafLeafContent() { } +// LeafContent represents content items that can't have child-nodes. type UnionNoFragmentsQueryRandomLeafLeafContent interface { implementsGraphQLInterfaceUnionNoFragmentsQueryRandomLeafLeafContent() } @@ -26,6 +27,7 @@ type UnionNoFragmentsQueryRandomLeafVideo struct { func (v UnionNoFragmentsQueryRandomLeafVideo) implementsGraphQLInterfaceUnionNoFragmentsQueryRandomLeafLeafContent() { } +// UnionNoFragmentsQueryResponse is returned by UnionNoFragmentsQuery on success. type UnionNoFragmentsQueryResponse struct { RandomLeaf UnionNoFragmentsQueryRandomLeafLeafContent `json:"-"` } diff --git a/generate/testdata/queries/UsesEnumTwice.graphql.go b/generate/testdata/queries/UsesEnumTwice.graphql.go index 7b3978c..d19675b 100644 --- a/generate/testdata/queries/UsesEnumTwice.graphql.go +++ b/generate/testdata/queries/UsesEnumTwice.graphql.go @@ -6,23 +6,41 @@ import ( "github.com/Khan/genqlient/graphql" ) +// Role is a type a user may have. type Role string const ( + // What is a student? + // + // A student is primarily a person enrolled in a school or other educational institution and who is under learning with goals of acquiring knowledge, developing professions and achieving employment at desired field. In the broader sense, a student is anyone who applies themselves to the intensive intellectual engagement with some matter necessary to master it as part of some practical affair in which such mastery is basic or decisive. + // + // (from [Wikipedia](https://en.wikipedia.org/wiki/Student)) RoleStudent Role = "STUDENT" + // Teacher is a teacher, who teaches the students. RoleTeacher Role = "TEACHER" ) +// A User is a user! type UsesEnumTwiceQueryMeUser struct { Roles []Role `json:"roles"` } +// A User is a user! type UsesEnumTwiceQueryOtherUser struct { Roles []Role `json:"roles"` } +// UsesEnumTwiceQueryResponse is returned by UsesEnumTwiceQuery on success. type UsesEnumTwiceQueryResponse struct { - Me UsesEnumTwiceQueryMeUser `json:"Me"` + // user looks up a user by some stuff. + // + // See UserQueryInput for what stuff is supported. + // If query is null, returns the current user. + Me UsesEnumTwiceQueryMeUser `json:"Me"` + // user looks up a user by some stuff. + // + // See UserQueryInput for what stuff is supported. + // If query is null, returns the current user. OtherUser UsesEnumTwiceQueryOtherUser `json:"OtherUser"` } diff --git a/generate/testdata/queries/schema.graphql b/generate/testdata/queries/schema.graphql index 8691207..9d93abc 100644 --- a/generate/testdata/queries/schema.graphql +++ b/generate/testdata/queries/schema.graphql @@ -1,15 +1,35 @@ +"""DateTime is a scalar. + +We don't really have anything useful to do with this description though. +""" scalar DateTime scalar Junk scalar ComplexJunk +"""Role is a type a user may have.""" enum Role { + """What is a student? + + A student is primarily a person enrolled in a school or other educational institution and who is under learning with goals of acquiring knowledge, developing professions and achieving employment at desired field. In the broader sense, a student is anyone who applies themselves to the intensive intellectual engagement with some matter necessary to master it as part of some practical affair in which such mastery is basic or decisive. + + (from [Wikipedia](https://en.wikipedia.org/wiki/Student)) + """ STUDENT + + """Teacher is a teacher, who teaches the students.""" TEACHER } +"""UserQueryInput is the argument to Query.users. + +Ideally this would support anything and everything! +Or maybe ideally it wouldn't. +Really I'm just talking to make this documentation longer. +""" input UserQueryInput { email: String name: String + """id looks the user up by ID. It's a great way to look up users.""" id: ID role: Role names: [String] @@ -20,7 +40,11 @@ type AuthMethod { email: String } +"""A User is a user!""" type User { + """id is the user's ID. + + It is stable, unique, and opaque, like all good IDs.""" id: ID! roles: [Role!] name: String @@ -31,15 +55,19 @@ type User { authMethods: [AuthMethod!]! } +"""Content is implemented by various types like Article, Video, and Topic.""" interface Content { + """ID is the identifier of the content.""" id: ID! name: String! parent: Topic } +"""LeafContent represents content items that can't have child-nodes.""" union LeafContent = Article | Video type Article implements Content { + """ID is documented in the Content interface.""" id: ID! name: String! parent: Topic! @@ -47,6 +75,7 @@ type Article implements Content { } type Video implements Content { + """ID is documented in the Content interface.""" id: ID! name: String! parent: Topic! @@ -54,14 +83,23 @@ type Video implements Content { } type Topic implements Content { + """ID is documented in the Content interface.""" id: ID! name: String! parent: Topic children: [Content!]! } +"""Query's description is probably ignored by almost all callers.""" type Query { + """user looks up a user by some stuff. + + See UserQueryInput for what stuff is supported. + If query is null, returns the current user. + """ user(query: UserQueryInput): User + + """usersWithRole looks a user up by role.""" usersWithRole(role: Role!): [User!]! root: Topic! randomLeaf: LeafContent! diff --git a/generate/testdata/queries/unexported.graphql.go b/generate/testdata/queries/unexported.graphql.go index 1ab92f7..aca5447 100644 --- a/generate/testdata/queries/unexported.graphql.go +++ b/generate/testdata/queries/unexported.graphql.go @@ -7,24 +7,46 @@ import ( "github.com/me/mypkg" ) +// Role is a type a user may have. type Role string const ( + // What is a student? + // + // A student is primarily a person enrolled in a school or other educational institution and who is under learning with goals of acquiring knowledge, developing professions and achieving employment at desired field. In the broader sense, a student is anyone who applies themselves to the intensive intellectual engagement with some matter necessary to master it as part of some practical affair in which such mastery is basic or decisive. + // + // (from [Wikipedia](https://en.wikipedia.org/wiki/Student)) RoleStudent Role = "STUDENT" + // Teacher is a teacher, who teaches the students. RoleTeacher Role = "TEACHER" ) +// unexportedResponse is returned by unexported on success. type unexportedResponse struct { + // user looks up a user by some stuff. + // + // See UserQueryInput for what stuff is supported. + // If query is null, returns the current user. User unexportedUser `json:"user"` } +// A User is a user! type unexportedUser struct { + // id is the user's ID. + // + // It is stable, unique, and opaque, like all good IDs. Id mypkg.ID `json:"id"` } +// UserQueryInput is the argument to Query.users. +// +// Ideally this would support anything and everything! +// Or maybe ideally it wouldn't. +// Really I'm just talking to make this documentation longer. type userQueryInput struct { - Email string `json:"email"` - Name string `json:"name"` + Email string `json:"email"` + Name string `json:"name"` + // id looks the user up by ID. It's a great way to look up users. Id mypkg.ID `json:"id"` Role Role `json:"role"` Names []string `json:"names"` diff --git a/generate/types.go b/generate/types.go index 2550abe..e338706 100644 --- a/generate/types.go +++ b/generate/types.go @@ -54,9 +54,11 @@ func (g *generator) getTypeForOperation(operation *ast.OperationDefinition, quer return "", errorf(operation.Position, "%v", err) } + description := fmt.Sprintf("%v is returned by %v on success.", name, operation.Name) + builder := &typeBuilder{generator: g} err = builder.writeTypedef( - name, operation.Name, baseType, operation.Position, fields, queryOptions) + name, operation.Name, baseType, operation.Position, fields, queryOptions, description) return name, err } @@ -129,6 +131,7 @@ func (g *generator) getTypeForInputType(opName string, typ *ast.Type, options, q type field interface { Alias() string Options() (*GenqlientDirective, error) + Description() string Type() *ast.Type Pos() *ast.Position SubFields() ([]field, error) @@ -154,6 +157,13 @@ func (s outputField) Options() (*GenqlientDirective, error) { return s.queryOptions.merge(directive), nil } +func (s outputField) Description() string { + if s.field.Definition == nil { + return "" + } + return s.field.Definition.Description +} + func (s outputField) Type() *ast.Type { if s.field.Definition == nil { return nil @@ -200,8 +210,9 @@ func (s inputField) Options() (*GenqlientDirective, error) { } return s.queryOptions.merge(directive), nil } -func (s inputField) Type() *ast.Type { return s.field.Type } -func (s inputField) Pos() *ast.Position { return s.field.Position } +func (s inputField) Description() string { return s.field.Description } +func (s inputField) Type() *ast.Type { return s.field.Type } +func (s inputField) Pos() *ast.Position { return s.field.Position } func (s inputField) SubFields() ([]field, error) { return selectionsForInputType(s.generator, s.field.Type, s.queryOptions), nil @@ -221,9 +232,6 @@ func (builder *typeBuilder) writeField(typeNamePrefix string, field field) error // We need an exportable name for JSON-marshaling. goName := upperFirst(jsonName) - builder.WriteString(goName) - builder.WriteRune(' ') - typ := field.Type() if typ == nil { // Unclear why gqlparser hasn't already rejected this, @@ -243,6 +251,10 @@ func (builder *typeBuilder) writeField(typeNamePrefix string, field field) error typedef := builder.schema.Types[typ.Name()] + builder.writeDescription(field.Description()) + builder.WriteString(goName) + builder.WriteRune(' ') + // Note we don't deduplicate suffixes here -- if our prefix is GetUser // and the field name is User, we do GetUserUser. This is important // because if you have a field called user on a type called User we @@ -301,7 +313,7 @@ func (builder *typeBuilder) writeType(name, namePrefix string, typ *ast.Type, fi builder.WriteString(name) childBuilder := &typeBuilder{generator: builder.generator} - return childBuilder.writeTypedef(name, namePrefix, def, typ.Position, fields, options) + return childBuilder.writeTypedef(name, namePrefix, def, typ.Position, fields, options, "") } func (builder *typeBuilder) writeTypedef( @@ -310,6 +322,7 @@ func (builder *typeBuilder) writeTypedef( pos *ast.Position, fields []field, options *GenqlientDirective, + description string, // defaults to typedef.Description ) (err error) { defer func() { // Whenever we're done, add the type to the type-map. @@ -321,6 +334,11 @@ func (builder *typeBuilder) writeTypedef( } }() + if description == "" { + description = typedef.Description + } + builder.writeDescription(description) + fmt.Fprintf(builder, "type %s ", typeName) switch typedef.Kind { case ast.Object, ast.InputObject: @@ -355,7 +373,7 @@ func (builder *typeBuilder) writeTypedef( for _, impldef := range builder.schema.GetPossibleTypes(typedef) { name, namePrefix := builder.typeName(typeNamePrefix, impldef) implBuilder := &typeBuilder{generator: builder.generator} - err := implBuilder.writeTypedef(name, namePrefix, impldef, pos, fields, options) + err := implBuilder.writeTypedef(name, namePrefix, impldef, pos, fields, options, "") if err != nil { return err } @@ -371,6 +389,7 @@ func (builder *typeBuilder) writeTypedef( builder.WriteString("string\n") builder.WriteString("const (\n") for _, val := range typedef.EnumValues { + builder.writeDescription(val.Description) fmt.Fprintf(builder, "%s %s = \"%s\"\n", typeName+goConstName(val.Name), typeName, val.Name) @@ -383,3 +402,11 @@ func (builder *typeBuilder) writeTypedef( return errorf(pos, "unexpected kind: %v", typedef.Kind) } } + +func (builder *typeBuilder) writeDescription(desc string) { + if desc != "" { + for _, line := range strings.Split(desc, "\n") { + builder.WriteString("// " + strings.TrimLeft(line, " \t") + "\n") + } + } +}