Skip to content

Commit cdf0207

Browse files
authored
Merge branch 'master' into master
2 parents 424d61d + fd79992 commit cdf0207

File tree

11 files changed

+326
-148
lines changed

11 files changed

+326
-148
lines changed

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,15 @@ Supports: queries, mutations & subscriptions.
88

99
godoc: https://pkg.go.dev/github.com/graphql-go/graphql
1010

11+
### Contribute Back
12+
13+
Friendly reminder links are available in case you would like to contribute back into our commitment with Go and open-source.
14+
15+
| Author | PayPal Link |
16+
|:-------------:|:-------------:|
17+
| [Hafiz Ismail](https://github.com/sogko) | Not available yet. |
18+
| [Chris Ramón](https://github.com/chris-ramon) | https://www.paypal.com/donate/?hosted_button_id=WHUQQYEMTRQBJ |
19+
1120
### Getting Started
1221

1322
To install the library, run:

definition.go

Lines changed: 128 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -193,13 +193,12 @@ func GetNamed(ttype Type) Named {
193193
//
194194
// Example:
195195
//
196-
// var OddType = new Scalar({
197-
// name: 'Odd',
198-
// serialize(value) {
199-
// return value % 2 === 1 ? value : null;
200-
// }
201-
// });
202-
//
196+
// var OddType = new Scalar({
197+
// name: 'Odd',
198+
// serialize(value) {
199+
// return value % 2 === 1 ? value : null;
200+
// }
201+
// });
203202
type Scalar struct {
204203
PrivateName string `json:"name"`
205204
PrivateDescription string `json:"description"`
@@ -306,33 +305,33 @@ func (st *Scalar) Error() error {
306305
// have a name, but most importantly describe their fields.
307306
// Example:
308307
//
309-
// var AddressType = new Object({
310-
// name: 'Address',
311-
// fields: {
312-
// street: { type: String },
313-
// number: { type: Int },
314-
// formatted: {
315-
// type: String,
316-
// resolve(obj) {
317-
// return obj.number + ' ' + obj.street
318-
// }
319-
// }
320-
// }
321-
// });
308+
// var AddressType = new Object({
309+
// name: 'Address',
310+
// fields: {
311+
// street: { type: String },
312+
// number: { type: Int },
313+
// formatted: {
314+
// type: String,
315+
// resolve(obj) {
316+
// return obj.number + ' ' + obj.street
317+
// }
318+
// }
319+
// }
320+
// });
322321
//
323322
// When two types need to refer to each other, or a type needs to refer to
324323
// itself in a field, you can use a function expression (aka a closure or a
325324
// thunk) to supply the fields lazily.
326325
//
327326
// Example:
328327
//
329-
// var PersonType = new Object({
330-
// name: 'Person',
331-
// fields: () => ({
332-
// name: { type: String },
333-
// bestFriend: { type: PersonType },
334-
// })
335-
// });
328+
// var PersonType = new Object({
329+
// name: 'Person',
330+
// fields: () => ({
331+
// name: { type: String },
332+
// bestFriend: { type: PersonType },
333+
// })
334+
// });
336335
//
337336
// /
338337
type Object struct {
@@ -419,7 +418,7 @@ func (gt *Object) Name() string {
419418
return gt.PrivateName
420419
}
421420
func (gt *Object) Description() string {
422-
return ""
421+
return gt.PrivateDescription
423422
}
424423
func (gt *Object) String() string {
425424
return gt.PrivateName
@@ -669,14 +668,12 @@ func (st *Argument) Error() error {
669668
//
670669
// Example:
671670
//
672-
// var EntityType = new Interface({
673-
// name: 'Entity',
674-
// fields: {
675-
// name: { type: String }
676-
// }
677-
// });
678-
//
679-
//
671+
// var EntityType = new Interface({
672+
// name: 'Entity',
673+
// fields: {
674+
// name: { type: String }
675+
// }
676+
// });
680677
type Interface struct {
681678
PrivateName string `json:"name"`
682679
PrivateDescription string `json:"description"`
@@ -780,32 +777,36 @@ func (it *Interface) Error() error {
780777
//
781778
// Example:
782779
//
783-
// var PetType = new Union({
784-
// name: 'Pet',
785-
// types: [ DogType, CatType ],
786-
// resolveType(value) {
787-
// if (value instanceof Dog) {
788-
// return DogType;
789-
// }
790-
// if (value instanceof Cat) {
791-
// return CatType;
792-
// }
793-
// }
794-
// });
780+
// var PetType = new Union({
781+
// name: 'Pet',
782+
// types: [ DogType, CatType ],
783+
// resolveType(value) {
784+
// if (value instanceof Dog) {
785+
// return DogType;
786+
// }
787+
// if (value instanceof Cat) {
788+
// return CatType;
789+
// }
790+
// }
791+
// });
795792
type Union struct {
796793
PrivateName string `json:"name"`
797794
PrivateDescription string `json:"description"`
798795
ResolveType ResolveTypeFn
799796

800-
typeConfig UnionConfig
801-
types []*Object
802-
possibleTypes map[string]bool
797+
typeConfig UnionConfig
798+
initalizedTypes bool
799+
types []*Object
800+
possibleTypes map[string]bool
803801

804802
err error
805803
}
804+
805+
type UnionTypesThunk func() []*Object
806+
806807
type UnionConfig struct {
807-
Name string `json:"name"`
808-
Types []*Object `json:"types"`
808+
Name string `json:"name"`
809+
Types interface{} `json:"types"`
809810
ResolveType ResolveTypeFn
810811
Description string `json:"description"`
811812
}
@@ -823,48 +824,80 @@ func NewUnion(config UnionConfig) *Union {
823824
objectType.PrivateDescription = config.Description
824825
objectType.ResolveType = config.ResolveType
825826

826-
if objectType.err = invariantf(
827-
len(config.Types) > 0,
828-
`Must provide Array of types for Union %v.`, config.Name,
829-
); objectType.err != nil {
830-
return objectType
827+
objectType.typeConfig = config
828+
829+
return objectType
830+
}
831+
832+
func (ut *Union) Types() []*Object {
833+
if ut.initalizedTypes {
834+
return ut.types
835+
}
836+
837+
var unionTypes []*Object
838+
switch utype := ut.typeConfig.Types.(type) {
839+
case UnionTypesThunk:
840+
unionTypes = utype()
841+
case []*Object:
842+
unionTypes = utype
843+
case nil:
844+
default:
845+
ut.err = fmt.Errorf("Unknown Union.Types type: %T", ut.typeConfig.Types)
846+
ut.initalizedTypes = true
847+
return nil
831848
}
832-
for _, ttype := range config.Types {
833-
if objectType.err = invariantf(
849+
850+
ut.types, ut.err = defineUnionTypes(ut, unionTypes)
851+
ut.initalizedTypes = true
852+
return ut.types
853+
}
854+
855+
func defineUnionTypes(objectType *Union, unionTypes []*Object) ([]*Object, error) {
856+
definedUnionTypes := []*Object{}
857+
858+
if err := invariantf(
859+
len(unionTypes) > 0,
860+
`Must provide Array of types for Union %v.`, objectType.Name(),
861+
); err != nil {
862+
return definedUnionTypes, err
863+
}
864+
865+
for _, ttype := range unionTypes {
866+
if err := invariantf(
834867
ttype != nil,
835868
`%v may only contain Object types, it cannot contain: %v.`, objectType, ttype,
836-
); objectType.err != nil {
837-
return objectType
869+
); err != nil {
870+
return definedUnionTypes, err
838871
}
839872
if objectType.ResolveType == nil {
840-
if objectType.err = invariantf(
873+
if err := invariantf(
841874
ttype.IsTypeOf != nil,
842875
`Union Type %v does not provide a "resolveType" function `+
843876
`and possible Type %v does not provide a "isTypeOf" `+
844877
`function. There is no way to resolve this possible type `+
845878
`during execution.`, objectType, ttype,
846-
); objectType.err != nil {
847-
return objectType
879+
); err != nil {
880+
return definedUnionTypes, err
848881
}
849882
}
883+
definedUnionTypes = append(definedUnionTypes, ttype)
850884
}
851-
objectType.types = config.Types
852-
objectType.typeConfig = config
853885

854-
return objectType
855-
}
856-
func (ut *Union) Types() []*Object {
857-
return ut.types
886+
return definedUnionTypes, nil
858887
}
888+
859889
func (ut *Union) String() string {
860890
return ut.PrivateName
861891
}
892+
862893
func (ut *Union) Name() string {
863894
return ut.PrivateName
864895
}
896+
865897
func (ut *Union) Description() string {
866898
return ut.PrivateDescription
867899
}
900+
868901
func (ut *Union) Error() error {
869902
return ut.err
870903
}
@@ -1050,18 +1083,18 @@ func (gt *Enum) getNameLookup() map[string]*EnumValueDefinition {
10501083
// An input object defines a structured collection of fields which may be
10511084
// supplied to a field argument.
10521085
//
1053-
// Using `NonNull` will ensure that a value must be provided by the query
1086+
// # Using `NonNull` will ensure that a value must be provided by the query
10541087
//
10551088
// Example:
10561089
//
1057-
// var GeoPoint = new InputObject({
1058-
// name: 'GeoPoint',
1059-
// fields: {
1060-
// lat: { type: new NonNull(Float) },
1061-
// lon: { type: new NonNull(Float) },
1062-
// alt: { type: Float, defaultValue: 0 },
1063-
// }
1064-
// });
1090+
// var GeoPoint = new InputObject({
1091+
// name: 'GeoPoint',
1092+
// fields: {
1093+
// lat: { type: new NonNull(Float) },
1094+
// lon: { type: new NonNull(Float) },
1095+
// alt: { type: Float, defaultValue: 0 },
1096+
// }
1097+
// });
10651098
type InputObject struct {
10661099
PrivateName string `json:"name"`
10671100
PrivateDescription string `json:"description"`
@@ -1200,14 +1233,13 @@ func (gt *InputObject) Error() error {
12001233
//
12011234
// Example:
12021235
//
1203-
// var PersonType = new Object({
1204-
// name: 'Person',
1205-
// fields: () => ({
1206-
// parents: { type: new List(Person) },
1207-
// children: { type: new List(Person) },
1208-
// })
1209-
// })
1210-
//
1236+
// var PersonType = new Object({
1237+
// name: 'Person',
1238+
// fields: () => ({
1239+
// parents: { type: new List(Person) },
1240+
// children: { type: new List(Person) },
1241+
// })
1242+
// })
12111243
type List struct {
12121244
OfType Type `json:"ofType"`
12131245

@@ -1226,14 +1258,14 @@ func NewList(ofType Type) *List {
12261258
return gl
12271259
}
12281260
func (gl *List) Name() string {
1229-
return fmt.Sprintf("%v", gl.OfType)
1261+
return fmt.Sprintf("[%v]", gl.OfType)
12301262
}
12311263
func (gl *List) Description() string {
12321264
return ""
12331265
}
12341266
func (gl *List) String() string {
12351267
if gl.OfType != nil {
1236-
return fmt.Sprintf("[%v]", gl.OfType)
1268+
return gl.Name()
12371269
}
12381270
return ""
12391271
}
@@ -1251,12 +1283,12 @@ func (gl *List) Error() error {
12511283
//
12521284
// Example:
12531285
//
1254-
// var RowType = new Object({
1255-
// name: 'Row',
1256-
// fields: () => ({
1257-
// id: { type: new NonNull(String) },
1258-
// })
1259-
// })
1286+
// var RowType = new Object({
1287+
// name: 'Row',
1288+
// fields: () => ({
1289+
// id: { type: new NonNull(String) },
1290+
// })
1291+
// })
12601292
//
12611293
// Note: the enforcement of non-nullability occurs within the executor.
12621294
type NonNull struct {

0 commit comments

Comments
 (0)