forked from graphql-go/relay
/
connection.go
135 lines (123 loc) · 3.7 KB
/
connection.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package relay
import "github.com/housinganywhere/graphql"
/*
Returns a GraphQLFieldConfigArgumentMap appropriate to include
on a field whose return type is a connection type.
*/
var ConnectionArgs = graphql.FieldConfigArgument{
"before": &graphql.ArgumentConfig{
Type: graphql.String,
},
"after": &graphql.ArgumentConfig{
Type: graphql.String,
},
"first": &graphql.ArgumentConfig{
Type: graphql.Int,
},
"last": &graphql.ArgumentConfig{
Type: graphql.Int,
},
"offset": &graphql.ArgumentConfig{
Type: graphql.Int,
},
"limit": &graphql.ArgumentConfig{
Type: graphql.Int,
},
}
func NewConnectionArgs(configMap graphql.FieldConfigArgument) graphql.FieldConfigArgument {
for fieldName, argConfig := range ConnectionArgs {
configMap[fieldName] = argConfig
}
return configMap
}
type ConnectionConfig struct {
Name string `json:"name"`
NodeType *graphql.Object `json:"nodeType"`
EdgeFields graphql.Fields `json:"edgeFields"`
ConnectionFields graphql.Fields `json:"connectionFields"`
}
type EdgeType struct {
Node interface{} `json:"node"`
Cursor ConnectionCursor `json:"cursor"`
}
type GraphQLConnectionDefinitions struct {
EdgeType *graphql.Object `json:"edgeType"`
ConnectionType *graphql.Object `json:"connectionType"`
}
/*
The common page info type used by all connections.
*/
var pageInfoType = graphql.NewObject(graphql.ObjectConfig{
Name: "PageInfo",
Description: "Information about pagination in a connection.",
Fields: graphql.Fields{
"hasNextPage": &graphql.Field{
Type: graphql.NewNonNull(graphql.Boolean),
Description: "When paginating forwards, are there more items?",
},
"hasPreviousPage": &graphql.Field{
Type: graphql.NewNonNull(graphql.Boolean),
Description: "When paginating backwards, are there more items?",
},
"startCursor": &graphql.Field{
Type: graphql.String,
Description: "When paginating backwards, the cursor to continue.",
},
"endCursor": &graphql.Field{
Type: graphql.String,
Description: "When paginating forwards, the cursor to continue.",
},
"offset": &graphql.Field{
Type: graphql.Int,
Description: "The used value of offset.",
},
"limit": &graphql.Field{
Type: graphql.Int,
Description: "The used value of limit.",
},
},
})
/*
Returns a GraphQLObjectType for a connection with the given name,
and whose nodes are of the specified type.
*/
func ConnectionDefinitions(config ConnectionConfig) *GraphQLConnectionDefinitions {
edgeType := graphql.NewObject(graphql.ObjectConfig{
Name: config.Name + "Edge",
Description: "An edge in a connection",
Fields: graphql.Fields{
"node": &graphql.Field{
Type: config.NodeType,
Description: "The item at the end of the edge",
},
"cursor": &graphql.Field{
Type: graphql.NewNonNull(graphql.String),
Description: " cursor for use in pagination",
},
},
})
for fieldName, fieldConfig := range config.EdgeFields {
edgeType.AddFieldConfig(fieldName, fieldConfig)
}
connectionType := graphql.NewObject(graphql.ObjectConfig{
Name: config.Name + "Connection",
Description: "A connection to a list of items.",
Fields: graphql.Fields{
"pageInfo": &graphql.Field{
Type: graphql.NewNonNull(pageInfoType),
Description: "Information to aid in pagination.",
},
"edges": &graphql.Field{
Type: graphql.NewList(edgeType),
Description: "Information to aid in pagination.",
},
},
})
for fieldName, fieldConfig := range config.ConnectionFields {
connectionType.AddFieldConfig(fieldName, fieldConfig)
}
return &GraphQLConnectionDefinitions{
EdgeType: edgeType,
ConnectionType: connectionType,
}
}