-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathgraphqljs.node.txt
641 lines (550 loc) · 36.4 KB
/
graphqljs.node.txt
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
┏━━━━━━━━━━━━━━━┓
┃ GRAPHQLJS ┃
┗━━━━━━━━━━━━━━━┛
VERSION ==> #0.10.1
#Node.js server-side implementation of GraphQL
#Only includes the bare minimum
#Core:
# - performs operation according to spec
# - must:
# - provide definition as SCHEMA:
# - using either:
# - JavaScript (e.g. GraphQLInt)
# - 'DEFINITIONS' string
# - DOCUMENT_NODE
# - can be printed back to 'DEFINITIONS'
# - provide 'QUERY' (and VARIABLES, 'OPNAME'), which is lexed and parsed into
# plain object DOCUMENT_NODE (which includes AST_NODEs)
# - resolvers:
# - default one returns RPARENT.FIELD[(ARGS, CONTEXT, RESINFO)]
# - can provide ROOTVAL, CONTEXT
# - provides fourth argument RESINFO with extra info
# - lots of validation:
# - including anything that can be done before performing operation
# - can perform it manually
# - can validate against deprecation
# - can check if schema changes introduce breaking changes
┌────────────┐
│ LEXING │
└────────────┘
new Source('QUERY'[, 'FILE']) #'FILE' is for debugging (def: 'GraphQL')
getLocation(SOURCE, NUM)->OBJ #Converts NUM of characters into OBJ: line NUM, column NUM
#I.e. after taking into account newlines as formatting
lex(SOURCE)->LEXER #
LEXER([NUM])->AST_TOKEN #Returns next AST_TOKEN, or EOF if none
#NUM is position to seek (def: next one)
AST_TOKEN.kind #Among Kind.*:
# - SOF|EOF (start|end)
# - BANG: !
# - DOLLAR: $
# - COLON: :
# - EQUALS: =
# - AT: @
# - PIPE: |
# - BRACKET_L|BRACKET_R: [ ]
# - BRACE_L|BRACE_R: { }
# - PAREN_L|PAREN_R: ( )
# - SPREAD: ...
# - COMMENT: #COMMENT
# - NAME: 'ATTR', etc.
# - INT|FLOAT|STRING
AST_TOKEN.value #STR
AST_TOKEN.start|end #Position NUM (in characters)
AST_TOKEN.line|column #NUM
AST_TOKEN.prev|next #AST_TOKEN2|null
┌─────────────┐
│ PARSING │
└─────────────┘
parse(STR|SOURCE[, POPTS])
->DOCUMENT_NODE
parseType(STR|SOURCE[, POPTS])
->TYPE_NODE
parse[Const]Value
(STR|SOURCE[, POPTS]) #Internally creates LEXER
->VALUE_NODE #If "Const", do not allow $VARs
POPTS.maxTokens #Throws if more than NUM tokens
getOperationAST
(DOCUMENT_NODE[, 'OPNAME'])
->OPERATION_DEFINITION_NODE #
valueFromAST(VALUE_NODE,
INPUT_TYPE[, VARIABLES])->VAL #
astFromValue(VAL, INPUT_TYPE)
->VALUE_NODE #
typeFromAST
(SCHEMA, TYPE_NODE)->TYPE #
gql`QUERY`->DOCUMENT_NODE ##Like parse('QUERY') except:
## - memoized
## - can use ${AST_NODE}
## - remove AST_NODE.loc
##Package graphql-tag (1.2.4)
GRAPHQL-LOADER ##Loads 'QUERY' files as DOCUMENT_NODE, using gql`QUERY`
##QUERY can contain #import "FILE" to include another file (must contain top-level operation)
##Package graphql-tag (1.2.4)
┌───────────┐
│ NODES │
└───────────┘
AST_NODE #Parsed node of a client operation
#Any of following *_NODE
# - kind: CamelCase, e.g. OPERATION_DEFINITION_NODE has kind 'OperationDefinition'
# - loc (absent if POPTS.noLocation true)
# - start|end NUM
# - start|endToken AST_TOKEN
# - source SOURCE
NAME_NODE #OBJ: value STR
TYPE_NODE #Any of the following *_TYPE_NODE
NAMED_TYPE_NODE #OBJ: name NAME_NODE
LIST_TYPE_NODE #OBJ: type TYPE_NODE
NON_NULL_TYPE_NODE #OBJ: type NAMED_TYPE_NODE|LIST_TYPE_NODE
VALUE_NODE #Any of the following *_VALUE_NODE or VARIABLE_NODE
VARIABLE_NODE #OBJ: name NAME_NODE
INT_VALUE_NODE #OBJ: value STR
FLOAT_VALUE_NODE #OBJ: value STR
STRING_VALUE_NODE #OBJ:
# - value STR
# - block BOOL
BOOLEAN_VALUE_NODE #OBJ: value BOOL
NULL_VALUE_NODE #OBJ.
ENUM_VALUE_NODE #OBJ: value STR
LIST_VALUE_NODE #OBJ: values VALUE_NODE_ARR
OBJECT_VALUE_NODE #OBJ: fields OBJECT_FIELD_NODE_ARR
# - name NAME_NODE
# - value VALUE_NODE
CONST_VALUE|LIST|OBJECT[_FIELD]|
DIRECTIVE|ARGUMENT_NODE #Exclude VARIABLE_NODE
ARGUMENT_NODE #OBJ:
# - name NAME_NODE
# - value VALUE_NODE
INPUT_VALUE_DEFINITION_NODE_ARR #OBJ:
# - name NAME_NODE
# - type TYPE_NODE
# - defaultValue VALUE_NODE
# - directives DIRECTIVE_NODE_ARR
# - description STRING_VALUE_NODE
DIRECTIVE_NODE #OBJ:
# - name NAME_NODE
# - arguments ARGUMENT_NODE_ARR
DOCUMENT_NODE #OBJ: definitions OBJ_ARR, of either:
# (OPERATION_DEFINITION_NODE)
# (FRAGMENT_DEFINITION_NODE)
# (TYPE_SYSTEM_DEFINITION_NODE), of either
# (SCHEMA_DEFINITION_NODE)
# (TYPE_DEFINITION_NODE), of either
# (SCALAR_TYPE_DEFINITION_NODE)
# (OBJECT_TYPE_DEFINITION_NODE)
# (INTERFACE_TYPE_DEFINITION_NODE)
# (UNION_TYPE_DEFINITION_NODE)
# (ENUM_TYPE_DEFINITION_NODE)
# (INPUT_OBJECT_TYPE_DEFINITION_NODE)
# (DIRECTIVE_DEFINITION_NODE)
# (TYPE_EXTENSION_DEFINITION_NODE)
OPERATION_DEFINITION_NODE #OBJ:
# - operation 'OPTYPE'
# - name NAME_NODE
# - variableDefinitions VARIABLE_DEFINITION_NODE_ARR
# - directives DIRECTIVE_NODE_ARR
# - selectionSet SELECTION_SET_NODE
VARIABLE_DEFINITION_NODE #OBJ:
# - variable VARIABLE_NODE
# - type TYPE_NODE
# - defaultValue VALUE_NODE
# - directives DIRECTIVE_NODE_ARR
SELECTION_SET_NODE #OBJ: selections SELECTION_NODE_ARR, of either
# (FIELD_NODE)
# (FRAGMENT_SPREAD_NODE)
# (INLINE_FRAGMENT_NODE)
FIELD_NODE #OBJ:
# - alias NAME_NODE
# - name NAME_NODE
# - arguments ARGUMENT_NODE_ARR
# - directives DIRECTIVE_NODE_ARR
# - selectionSet SELECTION_SET_NODE
FRAGMENT_SPREAD_NODE #OBJ:
# - name NAME_NODE
# - directives DIRECTIVE_NODE_ARR
INLINE_FRAGMENT_NODE #OBJ:
# - typeCondition NAMED_TYPE_NODE
# - directives DIRECTIVE_NODE_ARR
# - selectionSet SELECTION_SET_NODE
FRAGMENT_DEFINITION_NODE #OBJ:
# - name NAME_NODE
# - typeCondition NAMED_TYPE_NODE
# - directives DIRECTIVE_NODE_ARR
# - selectionSet SELECTION_SET_NODE
SCHEMA_DEFINITION_NODE #OBJ:
# - directives DIRECTIVE_NODE_ARR
# - operationTypes OPERATION_TYPE_DEFINITION_NODE_ARR
# - description STRING_VALUE_NODE
OPERATION_TYPE_DEFINITION_NODE #OBJ:
# - operation 'OPTYPE'
# - type NAMED_TYPE_NODE
SCALAR_TYPE_DEFINITION_NODE #OBJ:
# - name NAME_NODE
# - directives DIRECTIVE_NODE_ARR
# - description STRING_VALUE_NODE
OBJECT_TYPE_DEFINITION_NODE #OBJ:
# - name NAME_NODE
# - interfaces NAMED_TYPE_NODE_ARR
# - directives DIRECTIVE_NODE_ARR
# - fields FIELD_DEFINITION_NODE_ARR
# - description STRING_VALUE_NODE
FIELD_DEFINITION_NODE #OBJ:
# - name NAME_NODE
# - arguments INPUT_VALUE_DEFINITION_NODE_ARR
# - type TYPE_NODE
# - directives DIRECTIVE_NODE_ARR
# - description STRING_VALUE_NODE
INTERFACE_TYPE_DEFINITION_NODE #OBJ:
# - name NAME_NODE
# - directives DIRECTIVE_NODE_ARR
# - fields FIELD_DEFINITION_NODE_ARR
# - interfaces NAMED_TYPE_NODE_ARR
# - description STRING_VALUE_NODE
UNION_TYPE_DEFINITION_NODE #OBJ:
# - name NAME_NODE
# - directives DIRECTIVE_NODE_ARR
# - types NAMED_TYPE_NODE_ARR
# - description STRING_VALUE_NODE
ENUM_TYPE_DEFINITION_NODE #OBJ:
# - name NAME_NODE
# - directives DIRECTIVE_NODE_ARR
# - values ENUM_VALUE_DEFINITION_NODE_ARR
# - description STRING_VALUE_NODE
ENUM_VALUE_DEFINITION_NODE #OBJ:
# - name NAME_NODE
# - directives DIRECTIVE_NODE_ARR
# - description STRING_VALUE_NODE
INPUT_OBJECT_TYPE_DEFINITION_NODE #OBJ:
# - name NAME_NODE
# - directives DIRECTIVE_NODE_ARR
# - fields INPUT_VALUE_DEFINITION_NODE_ARR
# - description STRING_VALUE_NODE
DIRECTIVE_DEFINITION_NODE #OBJ:
# - name NAME_NODE
# - arguments INPUT_VALUE_DEFINITION_NODE_ARR
# - locations NAME_NODE_ARR
# - repeatable BOOL
# - description STRING_VALUE_NODE
isNode(VAL)->BOOL #
┌────────────────┐
│ DEFINITION │
└────────────────┘
TYPE #Parsed node of a server operations definitions
TYPE.name #'TYPE'.
#Not with GraphQLList|GraphQLNonNull
TYPE.toString|toJSON()->STR #Returns TYPE.name, with also ! [] for GraphQLList|GraphQLNonNull
TYPE.description #STR
#Not with GraphQLList|GraphQLNonNull
TYPE.ofType #TYPE2
#Only with GraphQLList|GraphQLNonNull
new GraphQL*(...) #Create new TYPEs, not TYPE instances
#E.g. GraphQLInt is not constructor
#If argument is OPTS, always have:
# - name STR
# - description STR
new GraphQLList(TYPE) #ARR modifier
getNamedType(TYPE)->TYPE2 #Removes NonNull|ARR modifiers, if present
new GraphQLNonNull(TYPE) #NonNull (!) modifier
getNullableType(TYPE)->TYPE2 #Removes NonNull modifier, if present
new GraphQLScalarType(OPTS) #SCALARTYPE. Constructor is used for custom ones
#OPTS:
# - name STR
# - description STR (def: none)
# - specifiedByUrl STR (def: none): documentation URL
# (server -> client)
# - serialize(VAL)->STR (def: identity)
# (client -> server)
# - parseLiteral(VALUE_NODE[, OBJ])->VAL
# - OBJ are variables
# - def:
# - use VALUE_NODE.value transtyped to STR|NUM|BOOL
# - deeply for ARR|OBJ
# - replace $VAR
# - then call parseValue()
# - parseValue(VAL)->VAL
# - def: identity
# - called after parseLiteral()
#VAL is of any type
#Should throw TypeError if wrong input
GraphQLInt #INT TYPE
GraphQLFloat #FLOAT TYPE
GraphQLString #STR TYPE
GraphQLBoolean #BOOL TYPE
GraphQLID #ID TYPE
GraphQLJSON ##'JSON' [non-]OBJ|ARR TYPE
GraphQLJSONObject ##'JSON' OBJ|ARR TYPE
##Package graphql-type-json (version 0.3.2)
PACKAGE ==> ##Package graphql-iso-date (version 3.6.1)
GraphQLDate ##Serialized as 'YYYY-MM-DD' (ISO-8601), parsed as DATE
GraphQLTime ##Same for 'HH:MM:SSZ' (ISO-8601), parsed as DATE
GraphQLDateTime ##Same for 'YYYY-MM-DDTHH:MM:SSZ' (ISO-8601), parsed as DATE
PACKAGE ==> ##Package graphql-custom-types (version 1.7.0)
GraphQLDateTime ##Of type string, validating using Date.parse()
GraphQLEmail ##Of type string, using regexp validation
##Checks:
## - characters are not among <>()[\]\.,;:\s@\", unless surrounded by "..." (username only)
## - @ in middle
## - possible subdomains
## - TLD with min 2 characters
GraphQLURL ##Of type string, using regexp validation
##Only for HTTP[S] and FTP
GraphQLUUID ##Of type string, using regexp validation. Any UUID version, i.e. just check AAAAAAAA-BBBB-CDDD-EEFF-GGGGGGGGGGGG with hexs
new GraphQLLimitedString ##Of type string. Must:
(MIN[, MAX][, 'ALPHABET']) ## - have length between MIN and MAX (inclusive)
## - only contains characters from 'ALPHABET'
new GraphQLPassword ##Same but must also contain at least:
(MIN[, MAX][, 'ALPHABET'][,OPTS])## - one number and one letter, if OPTS.alphaNumeric true
## - one uppercase and one lowercase letter, if OPTS.mixedCase true
## - one non-alphanumeric, if OPTS.specialChars true
Factory.getRegexScalar(OPTS) ##Creates SCALARTYPE of type string, using OPTS:
## - name, description
## - regex REGEXP: for validation
## - error 'ERROR' (def: 'Query error: NAME'): message from the GraphQLError exception thrown on validation
Factory.getCustomScalar ##Creates SCALARTYPE using:
('NAME', 'DESCRIPTION', ## - serialize(): identity
FUNC(AST_NODE)->VAL) ## - parseLiteral: FUNC
->SCALARTYPE ## - parseValue: FUNC({ kind: Kind.STRING, value: VAL })
new GraphQLEnumType(OPTS) #OPTS.values.ENUM_VAL:
# - value ENUM_INTERNAL_NUM
# - description STR
# - deprecationReason STR
new GraphQLObjectType(OPTS) #OPTS:
# - fields[()].FIELD:
# - type OUTPUTTYPE
# - args.ARG:
# - type INPUTTYPE
# - defaultValue VAL
# - description STR
# - resolve(RPARENT, ARGS, CONTEXT, RESINFO)->[PROMISE_]RATTR
# - resolve function
## - can validate all resolvers are defined, using GraphQL-tools (see its doc)
# - subscribe(RPARENT, ARGS, CONTEXT, RESINFO)->SPAYLOAD_ASYNC_ITERABLE: subscribe function
# - description STR
# - deprecationReason STR
# - interfaces[()] INTERFACETYPE_ARR
# - isTypeOf(VAL, RESINFO)->[PROMISE_]BOOL:
# - VAL is RESOLVER return value
# - def: VAL.__typename === 'TYPE'
new GraphQLInputObjectType(OPTS) #OPTS.fields[()].FIELD:
# - type INPUTTYPE
# - defaultValue VAL
# - description STR
new GraphQLInterfaceType(OPTS) #OPTS:
# - fields: like OBJTYPE
# - resolveType(VAL, RESINFO)->OBJTYPE
# - used to determine which child type to pick
# - def: call each defined OBJTYPE.isTypeOf()
new GraphQLUnionType(OPTS) #OPTS:
# - types OBJTYPE_ARR[()]
# - resolveType: like INTERFACETYPE
new GraphQLDirective(OPTS) #OPTS:
# - locations ARR: among DirectiveLocation.*
# - args.ARG:
# - type INPUTTYPE
# - description STR
# - defaultValue VAL
# - isRepeatable BOOL (def: false)
GraphQLInclude|SkipDirective #Possible locations: FIELD, FRAGMENT_SPREAD, INLINE_FRAGMENT
GraphQLDeprecatedDirective #Possible locations: FIELD_DEFINITION, ENUM_VALUE
GraphQLSpecifiedByDirective #Possible locations: SCALAR
GraphQLDeferDirective #Possible locations: FRAGMENT_SPREAD, INLINE_FRAGMENT
GraphQLStreamDirective #Possible locations: FIELD
new GraphQLSchema(OPTS) #OPTS:
# - query|mutation|subscription OBJTYPE
# - types NAMEDTYPE_ARR:
# - all possible types, used by introspection __schema.types
# - def: guessed by going through schema
# - useful to specify when SCHEMA uses INTERFACE|UNIONs, i.e. subtypes might be missing
# from definition, but usable by clients
# - directives DIRECTIVE_ARR
specifiedDirectives #Def value of GraphQLSchema OPTS.directives.
#Includes: @include|skip|deprecated|specifiedBy
#To add new ones (such as @defer|@stream), must be passed together with specifiedDirectives
#to new GraphQLSchema() OPTS.directives
__Schema|__Type|__Directive|
__Field|__InputValue|__EnumValue|
__TypeKind|__Directive| #
__DirectiveLocation #OBJTYPE, related to introspection, with default resolvers
isLeafType(VAL)->BOOL #GraphQLScalarType + GraphQLEnumType
isAbstractType(VAL)->BOOL #GraphQLInterfaceType + GraphQLUnionType
isCompositeType(VAL)->BOOL #AbstractType + GraphQLObjectType
isInputType(VAL)->BOOL #Any type except CompositeType
isOutputType(VAL)->BOOL #Any type except GraphQLInputObjectType
isNamedType(VAL)->BOOL #Any type except GraphQLNonNull|GraphQLList
isType(VAL)->BOOL #Any type
assert*Type(VAL) #Throws unless is*Type(VAL)
isEqualType(TYPE, TYPE2)->BOOL #Recursively
┌───────────┐
│ BUILD │
└───────────┘
buildSchema('DEFINITIONS') #Shortcut.
->SCHEMA #Instead of using new GraphQL*Type(...), let graphql.js create them by parsing 'DEFINITIONS' or DOCUMENT_NODE
buildASTSchema(DOCUMENT_NODE) #Will also add:
->SCHEMA # - comments before anything -> description
# - @deprecated REASON -> deprecationReason
#Problem:
# - does not add resolvers
# - does not add resolveType|isTypeOf(), so cannot use interface|union
# - does not add serialize|parseValue|parseLiteral(), so cannot use custom scalars
## - GraphQL-tools fixes all this (see its doc)
extendSchema(SCHEMA,DOCUMENT_NODE)#Proper way to add new definitions (DOCUMENT_NODE) to existing SCHEMA
->SCHEMA #Also the only way to use "extend type ..." definitions (GraphQL-tools fixes all this (see its doc))
┌────────────────┐
│ VALIDATION │
└────────────────┘
validate(SCHEMA, DOCUMENT_NODE) #Validates query (not against deprecation)
->GRAPHQLERROR_ARR|null #Using spec-defined validation rules, also available one by one if necessary (see source)
findDeprecatedUsages
(SCHEMA, DOCUMENT_NODE)
->GRAPHQL_ERROR_ARR #Validates against deprecation
assertValidName('TYPE'[, BOOL]) #Used internally to check against all names, including 'TYPE', 'ATTR', 'ENUM_VAL', 'DIRECTIVE', 'ARG', etc:
# - check regexp /^[_a-zA-Z][_a-zA-Z0-9]*$/
# - check does not start with __, unless BOOL true
# - can ignore error with OPTS.isIntrospection true for OBJTYPE|ENUMTYPE
# - throws exception if error
isValidJSValue(VAL, TYPE)->BOOL #From server to client
isValidLiteralValue
(TYPE, VALUE_NODE)->BOOL #From client to server
┌───────────────┐
│ EXECUTION │
└───────────────┘
graphqlSync(OBJ)->RES_OBJ2 #Same as:
# validateSchema(OBJ.schema)
# DOCUMENT_NODE = parse(OBJ.source)
# validate(OBJ.schema, DOCUMENT_NODE)
# return execute({ document: DOCUMENT_NODE, ...OBJ })
#Returns { errors } if validate*() fails
graphql(OBJ)->PROMISE_RES_OBJ2 #Same but OBJ.fieldResolver can return a PROMISE
execute(OBJ)->PROMISE_RES_OBJ2 #Perform query against a schema.
#OBJ:
# - schema SCHEMA
# - document DOCUMENT_NODE
# - contextValue CONTEXT: request-wide object passed to resolvers. Can be anything
# - variableValues OBJ3: list of $VAR values
# - rootValue ROOTVAL
# - operationName 'OPNAME': if query contains several possible
# - fieldResolver FUNC: default value for OBJTYPE.FIELD.resolve(...)
# - subscribeFieldResolver FUNC: default value for OBJTYPE.FIELD.subscribe(...)
#Can throw GraphQLError if something wrong in query
RES_OBJ #OBJ2: data OBJ|null[, errors OBJ_ARR][, extensions OBJ]
#Use OBJTYPE.FIELD.resolve(...) if defined
#Otherwise, use TYPE.serialize(VAL)
RESINFO #OBJ:
# - schema SCHEMA
# - rootValue ROOTVAL
# - variableValues VARIABLES: after coercion
# - operation OPERATION_DEFINITION_NODE: from DOCUMENT_NODE + 'OPNAME'
# - fragments.FRAGMENT FRAGMENT_DEFINITION_NODE: from DOCUMENT_NODE
# - fieldName 'ATTR'
# - fieldNodes FIELD_NODE_ARR (siblings, including itself)
# - returnType OUTPUTTYPE (field's type)
# - parentType COMPOSITETYPE (parent field's type)
# - path null|OBJ: prev PATH, key NUM|'VAR', typename 'OPTYPE'
┌────────────┐
│ STREAM │
└────────────┘
experimentalExecuteIncrementally #Like execute(OBJ), except can use @defer|@stream
(OBJ)->PROMISE_OBJ2 #Must add them to new GraphQLSchema() OPTS.directives
#OBJ2 is either:
# - if @defer|@stream:
# - initialResult RES_OBJ
# - subsequentResults RES_OBJ_ASYNC_ITERABLETOR
# - otherwise: RES_OBJ
┌───────────────┐
│ SUBSCRIBE │
└───────────────┘
subscribe(OBJ)->PROMISE_VAL #Like execute() but for subscriptions.
#Return VAL is:
# - success: RES_OBJ_ASYNC_ITERABLE
# - iterate over OBJ_TYPE.subscribe()->SPAYLOAD_ASYNC_ITERABLE
# - then call execute(...) with SPAYLOAD as ROOTVAL
# - error: RES_OBJ
#Does not implement the networking part, i.e.:
# - responding to initial subscription request
# - creating long-lived connection (like WebSocket) and pushing responses to it
createSourceEventStream(OBJ)
->PROMISE_VAL #Same except does not call execute(...), i.e. return SPAYLOAD instead of RES_OBJ
┌────────────┐
│ ERRORS │
└────────────┘
ERRORS ==> #On exceptions inside resolvers: ouputs in return value "errors" field, as GraphQLError
#On everything else: throws error
##Can use GraphQL-tools (see its doc) to use custom function
GraphQLError #Every exception|error is of that type, including the ones below
#OBJ:
# - message STR
# - stack STR
# - originalError ERROR
# - locations OBJ_ARR: line|column
# - path 'VAR'|NUM_ARR
# - nodes AST_NODE_ARR
# - source SOURCE
# - positions NUM_ARR
syntaxError #On parsing|lexing
locatedError #During resolvers
┌───────────────────┐
│ INTROSPECTION │
└───────────────────┘
getIntrospectionQuery([OPTS]) #Returns 'query IntrospectionQuery { __schema { ... } }'
->'QUERY' #All __schema fields except:
# - queryType|mutationType|subscriptionType: name only
# - mentioned below
#OPTS (all BOOL with default false):
# - schemaDescription: include __schema.description
# - directiveIsRepeatable: include __schema.directives.isRepeatable
# - specifiedByUrl: include __schema.types.specifiedByUrl
# - inputValueDeprecation: `includeDeprecated: true`
# - exception: always true with __schema.types.fields|enumValues
introspectionFromSchema #Call executeSync() with getIntrospectionQuery(OPTS)
(SCHEMA[, OPTS])->OBJ #OPTS all with default true instead
┌─────────────┐
│ VISITOR │
└─────────────┘
visit(AST_NODE, OPTS[, MAP]) #Iterates over AST_NODE and descendants
->AST_NODE2 #OPTS visitor function return values can modify|skip part of the tree, returning new AST_NODE2
#OPTS:
# - enter|leave[.KIND](AST_NODE, KEY, PARENT_AST_NODE, PATH, ANCESTORS_AST_NODE_ARR)
# - KIND is NODE.kind (def: any)
# - KEY is NUM (if iterating over ARR) or 'VAR' (if iterating over OBJ)
# - PATH is KEY_ARR, including ancestors
# - enter|leave is when starting|stopping to iterate over the AST_NODE and its descendants
# - can return:
# - undefined: no action
# - VAL: replace node by VAL
# - null: erase node
# - false: skips visiting current node, but keep it
# - BREAK: skips visiting any node
# - KIND[.enter|leave](...): same (def: enter)
#MAP:
# - define which attribute each node has
# - only need to specify if adding custom AST_NODEs
# - default one is QueryDocumentKeys
# - key is KIND
# - value is 'ATTR'_ARR:
# - attributes to iterate over, in each AST_NODE
# - e.g. for 'Directive', ['name', 'value']
visitInParallel(OPTS_ARR)->OPTS #Return OPTS that applies several OPTs
visitWithTypeInfo(OBJ, OPTS)
->OPTS #Returns OPTS that also fires OBJ.enter|leave(AST_NODE), for debugging
┌───────────────────┐
│ SERIALIZATION │
└───────────────────┘
print(AST_NODE)->STR #Serialize AST_NODE to graphQL query format
print[Introspection]Schema #Serialize SCHEMA into graphQL query format, underlyingly using print(...)
(SCHEMA)->STR #Automatically sorts
#Includes:
# - no "Introspection": not @DIRECTIVE nor builtin scalar types nor introspection types
# - "Introspection": only introspection types
printType(TYPE)-STR #
printLocation(AST_NODE.loc)->STR #
┌───────────────┐
│ MIGRATION │
└───────────────┘
findBreakingChanges #Returns possible breaking changes from one schema to another
(OLD_SCHEMA, NEW_SCHEMA)->OBJ_ARR #OBJ:
# - type STR
# - description STR
#Possible:
# - 'TYPE|ARG_REMOVED[_FROM_UNION|ENUM]'
# - 'TYPE|FIELD|ARG_CHANGED_KIND'
findDangerousChanges(...) #Same but for non-breaking changes but still dangerous:
# - 'ARG_DEFAULT_VALUE_CHANGE'