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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
|
package graphql
const (
// Operations
DirectiveLocationQuery = "QUERY"
DirectiveLocationMutation = "MUTATION"
DirectiveLocationSubscription = "SUBSCRIPTION"
DirectiveLocationField = "FIELD"
DirectiveLocationFragmentDefinition = "FRAGMENT_DEFINITION"
DirectiveLocationFragmentSpread = "FRAGMENT_SPREAD"
DirectiveLocationInlineFragment = "INLINE_FRAGMENT"
// Schema Definitions
DirectiveLocationSchema = "SCHEMA"
DirectiveLocationScalar = "SCALAR"
DirectiveLocationObject = "OBJECT"
DirectiveLocationFieldDefinition = "FIELD_DEFINITION"
DirectiveLocationArgumentDefinition = "ARGUMENT_DEFINITION"
DirectiveLocationInterface = "INTERFACE"
DirectiveLocationUnion = "UNION"
DirectiveLocationEnum = "ENUM"
DirectiveLocationEnumValue = "ENUM_VALUE"
DirectiveLocationInputObject = "INPUT_OBJECT"
DirectiveLocationInputFieldDefinition = "INPUT_FIELD_DEFINITION"
)
// DefaultDeprecationReason Constant string used for default reason for a deprecation.
const DefaultDeprecationReason = "No longer supported"
// SpecifiedRules The full list of specified directives.
var SpecifiedDirectives = []*Directive{
IncludeDirective,
SkipDirective,
DeprecatedDirective,
}
// Directive structs are used by the GraphQL runtime as a way of modifying execution
// behavior. Type system creators will usually not create these directly.
type Directive struct {
Name string `json:"name"`
Description string `json:"description"`
Locations []string `json:"locations"`
Args []*Argument `json:"args"`
err error
}
// DirectiveConfig options for creating a new GraphQLDirective
type DirectiveConfig struct {
Name string `json:"name"`
Description string `json:"description"`
Locations []string `json:"locations"`
Args FieldConfigArgument `json:"args"`
}
func NewDirective(config DirectiveConfig) *Directive {
dir := &Directive{}
// Ensure directive is named
err := invariant(config.Name != "", "Directive must be named.")
if err != nil {
dir.err = err
return dir
}
// Ensure directive name is valid
err = assertValidName(config.Name)
if err != nil {
dir.err = err
return dir
}
// Ensure locations are provided for directive
err = invariant(len(config.Locations) > 0, "Must provide locations for directive.")
if err != nil {
dir.err = err
return dir
}
args := []*Argument{}
for argName, argConfig := range config.Args {
err := assertValidName(argName)
if err != nil {
dir.err = err
return dir
}
args = append(args, &Argument{
PrivateName: argName,
PrivateDescription: argConfig.Description,
Type: argConfig.Type,
DefaultValue: argConfig.DefaultValue,
})
}
dir.Name = config.Name
dir.Description = config.Description
dir.Locations = config.Locations
dir.Args = args
return dir
}
// IncludeDirective is used to conditionally include fields or fragments.
var IncludeDirective = NewDirective(DirectiveConfig{
Name: "include",
Description: "Directs the executor to include this field or fragment only when " +
"the `if` argument is true.",
Locations: []string{
DirectiveLocationField,
DirectiveLocationFragmentSpread,
DirectiveLocationInlineFragment,
},
Args: FieldConfigArgument{
"if": &ArgumentConfig{
Type: NewNonNull(Boolean),
Description: "Included when true.",
},
},
})
// SkipDirective Used to conditionally skip (exclude) fields or fragments.
var SkipDirective = NewDirective(DirectiveConfig{
Name: "skip",
Description: "Directs the executor to skip this field or fragment when the `if` " +
"argument is true.",
Args: FieldConfigArgument{
"if": &ArgumentConfig{
Type: NewNonNull(Boolean),
Description: "Skipped when true.",
},
},
Locations: []string{
DirectiveLocationField,
DirectiveLocationFragmentSpread,
DirectiveLocationInlineFragment,
},
})
// DeprecatedDirective Used to declare element of a GraphQL schema as deprecated.
var DeprecatedDirective = NewDirective(DirectiveConfig{
Name: "deprecated",
Description: "Marks an element of a GraphQL schema as no longer supported.",
Args: FieldConfigArgument{
"reason": &ArgumentConfig{
Type: String,
Description: "Explains why this element was deprecated, usually also including a " +
"suggestion for how to access supported similar data. Formatted" +
"in [Markdown](https://daringfireball.net/projects/markdown/).",
DefaultValue: DefaultDeprecationReason,
},
},
Locations: []string{
DirectiveLocationFieldDefinition,
DirectiveLocationEnumValue,
},
})
|