@graphprotocol/graph-cli 0.37.2-alpha-20221219142030-0cf2a37 → 0.37.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,9 @@
1
1
  const fs = require('fs')
2
2
  const graphql = require('graphql/language')
3
+ const immutable = require('immutable')
4
+
5
+ const List = immutable.List
6
+ const Set = immutable.Set
3
7
 
4
8
  // Builtin scalar types
5
9
  const BUILTIN_SCALAR_TYPES = [
@@ -72,26 +76,26 @@ const parseSchema = doc => {
72
76
 
73
77
  const validateEntityDirective = def =>
74
78
  def.directives.find(directive => directive.name.value === 'entity')
75
- ? []
76
- : [
77
- {
78
- loc: def.loc,
79
- entity: def.name.value,
80
- message: `Defined without @entity directive`,
81
- },
82
- ]
79
+ ? List()
80
+ : immutable.fromJS([
81
+ {
82
+ loc: def.loc,
83
+ entity: def.name.value,
84
+ message: `Defined without @entity directive`,
85
+ },
86
+ ])
83
87
 
84
88
  const validateEntityID = def => {
85
89
  let idField = def.fields.find(field => field.name.value === 'id')
86
90
 
87
91
  if (idField === undefined) {
88
- return [
92
+ return immutable.fromJS([
89
93
  {
90
94
  loc: def.loc,
91
95
  entity: def.name.value,
92
96
  message: `Missing field: id: ID!`,
93
97
  },
94
- ]
98
+ ])
95
99
  }
96
100
 
97
101
  if (
@@ -101,36 +105,36 @@ const validateEntityID = def => {
101
105
  idField.type.type.name.value === 'Bytes' ||
102
106
  idField.type.type.name.value === 'String')
103
107
  ) {
104
- return []
108
+ return List()
105
109
  } else {
106
- return [
110
+ return immutable.fromJS([
107
111
  {
108
112
  loc: idField.loc,
109
113
  entity: def.name.value,
110
114
  message: `Field 'id': Entity ids must be of type Bytes! or String!`,
111
115
  },
112
- ]
116
+ ])
113
117
  }
114
118
  }
115
119
 
116
120
  const validateListFieldType = (def, field) =>
117
121
  field.type.kind === 'NonNullType' &&
118
- field.type.kind === 'ListType' &&
119
- field.type.type.kind !== 'NonNullType'
120
- ? [
121
- {
122
- loc: field.loc,
123
- entity: def.name.value,
124
- message: `\
122
+ field.type.kind === 'ListType' &&
123
+ field.type.type.kind !== 'NonNullType'
124
+ ? immutable.fromJS([
125
+ {
126
+ loc: field.loc,
127
+ entity: def.name.value,
128
+ message: `\
125
129
  Field '${field.name.value}':
126
130
  Field has type [${field.type.type.name.value}]! but
127
131
  must have type [${field.type.type.name.value}!]!
128
132
 
129
133
  Reason: Lists with null elements are not supported.`,
130
- },
131
- ]
134
+ },
135
+ ])
132
136
  : field.type.kind === 'ListType' && field.type.type.kind !== 'NonNullType'
133
- ? [
137
+ ? immutable.fromJS([
134
138
  {
135
139
  loc: field.loc,
136
140
  entity: def.name.value,
@@ -141,8 +145,8 @@ must have type [${field.type.type.name.value}!]
141
145
 
142
146
  Reason: Lists with null elements are not supported.`,
143
147
  },
144
- ]
145
- : []
148
+ ])
149
+ : List()
146
150
 
147
151
  const unwrapType = type => {
148
152
  let innerTypeFromList = listType =>
@@ -159,8 +163,8 @@ const unwrapType = type => {
159
163
  return type.kind === 'NonNullType'
160
164
  ? innerTypeFromNonNull(type)
161
165
  : type.kind === 'ListType'
162
- ? innerTypeFromList(type)
163
- : type
166
+ ? innerTypeFromList(type)
167
+ : type
164
168
  }
165
169
 
166
170
  const gatherLocalTypes = defs =>
@@ -206,8 +210,8 @@ const gatherImportedTypes = defs =>
206
210
  type.fields.find(
207
211
  field => field.name.value == 'as' && field.value.kind == 'StringValue',
208
212
  )
209
- ? type.fields.find(field => field.name.value == 'as').value.value
210
- : undefined,
213
+ ? type.fields.find(field => field.name.value == 'as').value.value
214
+ : undefined,
211
215
  ),
212
216
  ),
213
217
  )
@@ -227,8 +231,7 @@ const entityTypeByName = (defs, name) =>
227
231
  .filter(
228
232
  def =>
229
233
  def.kind === 'InterfaceTypeDefinition' ||
230
- (def.kind === 'ObjectTypeDefinition' &&
231
- def.directives.find(directive => directive.name.value === 'entity')),
234
+ (def.kind === 'ObjectTypeDefinition' && def.directives.find(directive => directive.name.value === 'entity'))
232
235
  )
233
236
  .find(def => def.name.value === name)
234
237
 
@@ -255,18 +258,17 @@ const validateInnerFieldType = (defs, def, field) => {
255
258
 
256
259
  // Check whether the type name is available, otherwise return an error
257
260
  return availableTypes.includes(typeName)
258
- ? []
259
- : [
260
- {
261
- loc: field.loc,
262
- entity: def.name.value,
263
- message: `\
261
+ ? List()
262
+ : immutable.fromJS([
263
+ {
264
+ loc: field.loc,
265
+ entity: def.name.value,
266
+ message: `\
264
267
  Field '${field.name.value}': \
265
- Unknown type '${typeName}'.${
266
- suggestion !== undefined ? ` Did you mean '${suggestion}'?` : ''
268
+ Unknown type '${typeName}'.${suggestion !== undefined ? ` Did you mean '${suggestion}'?` : ''
267
269
  }`,
268
- },
269
- ]
270
+ },
271
+ ])
270
272
  }
271
273
 
272
274
  const validateEntityFieldType = (defs, def, field) =>
@@ -277,16 +279,16 @@ const validateEntityFieldType = (defs, def, field) =>
277
279
 
278
280
  const validateEntityFieldArguments = (defs, def, field) =>
279
281
  field.arguments.length > 0
280
- ? [
281
- {
282
- loc: field.loc,
283
- entity: def.name.value,
284
- message: `\
282
+ ? immutable.fromJS([
283
+ {
284
+ loc: field.loc,
285
+ entity: def.name.value,
286
+ message: `\
285
287
  Field '${field.name.value}': \
286
288
  Field arguments are not supported.`,
287
- },
288
- ]
289
- : []
289
+ },
290
+ ])
291
+ : List()
290
292
 
291
293
  const entityFieldExists = (entityDef, name) =>
292
294
  entityDef.fields.find(field => field.name.value === name) !== undefined
@@ -294,7 +296,7 @@ const entityFieldExists = (entityDef, name) =>
294
296
  const validateDerivedFromDirective = (defs, def, field, directive) => {
295
297
  // Validate that there is a `field` argument and nothing else
296
298
  if (directive.arguments.length !== 1 || directive.arguments[0].name.value !== 'field') {
297
- return [
299
+ return immutable.fromJS([
298
300
  {
299
301
  loc: directive.loc,
300
302
  entity: def.name.value,
@@ -302,12 +304,12 @@ const validateDerivedFromDirective = (defs, def, field, directive) => {
302
304
  Field '${field.name.value}': \
303
305
  @derivedFrom directive must have a 'field' argument`,
304
306
  },
305
- ]
307
+ ])
306
308
  }
307
309
 
308
310
  // Validate that the "field" argument value is a string
309
311
  if (directive.arguments[0].value.kind !== 'StringValue') {
310
- return [
312
+ return immutable.fromJS([
311
313
  {
312
314
  loc: directive.loc,
313
315
  entity: def.name.value,
@@ -315,7 +317,7 @@ Field '${field.name.value}': \
315
317
  Field '${field.name.value}': \
316
318
  Value of the @derivedFrom 'field' argument must be a string`,
317
319
  },
318
- ]
320
+ ])
319
321
  }
320
322
 
321
323
  let targetEntity = fieldTargetEntity(defs, field)
@@ -323,7 +325,7 @@ Value of the @derivedFrom 'field' argument must be a string`,
323
325
  // This is handled in `validateInnerFieldType` but if we don't catch
324
326
  // the undefined case here, the code below will throw, as it assumes
325
327
  // the target entity exists
326
- return []
328
+ return immutable.fromJS([])
327
329
  }
328
330
 
329
331
  let derivedFromField = targetEntity.fields.find(
@@ -331,7 +333,7 @@ Value of the @derivedFrom 'field' argument must be a string`,
331
333
  )
332
334
 
333
335
  if (derivedFromField === undefined) {
334
- return [
336
+ return immutable.fromJS([
335
337
  {
336
338
  loc: directive.loc,
337
339
  entity: def.name.value,
@@ -340,7 +342,7 @@ Field '${field.name.value}': \
340
342
  @derivedFrom field '${directive.arguments[0].value.value}' \
341
343
  does not exist on type '${targetEntity.name.value}'`,
342
344
  },
343
- ]
345
+ ])
344
346
  }
345
347
 
346
348
  let backrefTypeName = unwrapType(derivedFromField.type)
@@ -348,12 +350,8 @@ does not exist on type '${targetEntity.name.value}'`,
348
350
 
349
351
  // The field we are deriving from must either have type 'def' or one of the
350
352
  // interface types that 'def' is implementing
351
- if (
352
- !backRefEntity ||
353
- (backRefEntity.name.value !== def.name.value &&
354
- !def.interfaces.find(intf => intf.name.value === backRefEntity.name.value))
355
- ) {
356
- return [
353
+ if (!backRefEntity || (backRefEntity.name.value !== def.name.value && !def.interfaces.find(intf => intf.name.value === backRefEntity.name.value))) {
354
+ return immutable.fromJS([
357
355
  {
358
356
  loc: directive.loc,
359
357
  entity: def.name.value,
@@ -364,22 +362,22 @@ on type '${targetEntity.name.value}' must have the type \
364
362
  '${def.name.value}', '${def.name.value}!', '[${def.name.value}!]!', \
365
363
  or one of the interface types that '${def.name.value}' implements`,
366
364
  },
367
- ]
365
+ ])
368
366
  }
369
367
 
370
- return []
368
+ return List()
371
369
  }
372
370
 
373
371
  const validateEntityFieldDirective = (defs, def, field, directive) =>
374
372
  directive.name.value === 'derivedFrom'
375
373
  ? validateDerivedFromDirective(defs, def, field, directive)
376
- : []
374
+ : List()
377
375
 
378
376
  const validateEntityFieldDirectives = (defs, def, field) =>
379
377
  field.directives.reduce(
380
378
  (errors, directive) =>
381
379
  errors.concat(validateEntityFieldDirective(defs, def, field, directive)),
382
- [],
380
+ List(),
383
381
  )
384
382
 
385
383
  const validateEntityFields = (defs, def) =>
@@ -389,73 +387,73 @@ const validateEntityFields = (defs, def) =>
389
387
  .concat(validateEntityFieldType(defs, def, field))
390
388
  .concat(validateEntityFieldArguments(defs, def, field))
391
389
  .concat(validateEntityFieldDirectives(defs, def, field)),
392
- [],
390
+ List(),
393
391
  )
394
392
 
395
393
  const validateNoImportDirective = def =>
396
394
  def.directives.find(directive => directive.name.value == 'import')
397
- ? [
398
- {
399
- loc: def.name.loc,
400
- entity: def.name.value,
401
- message: `@import directive only allowed on '${RESERVED_TYPE}' type`,
402
- },
403
- ]
404
- : []
395
+ ? List([
396
+ immutable.fromJS({
397
+ loc: def.name.loc,
398
+ entity: def.name.value,
399
+ message: `@import directive only allowed on '${RESERVED_TYPE}' type`,
400
+ }),
401
+ ])
402
+ : List()
405
403
 
406
404
  const validateNoFulltext = def =>
407
405
  def.directives.find(directive => directive.name.value == 'fulltext')
408
- ? [
409
- {
410
- loc: def.name.loc,
411
- entity: def.name.value,
412
- message: `@fulltext directive only allowed on '${RESERVED_TYPE}' type`,
413
- },
414
- ]
415
- : []
406
+ ? List([
407
+ immutable.fromJS({
408
+ loc: def.name.loc,
409
+ entity: def.name.value,
410
+ message: `@fulltext directive only allowed on '${RESERVED_TYPE}' type`,
411
+ }),
412
+ ])
413
+ : List()
416
414
 
417
415
  const validateFulltextFields = (def, directive) => {
418
416
  return directive.arguments.reduce((errors, argument) => {
419
417
  return errors.concat(
420
418
  ['name', 'language', 'algorithm', 'include'].includes(argument.name.value)
421
- ? []
422
- : [
423
- {
424
- loc: directive.name.loc,
425
- entity: def.name.value,
426
- directive: fulltextDirectiveName(directive),
427
- message: `found invalid argument: '${argument.name.value}', @fulltext directives only allow 'name', 'language', 'algorithm', and 'includes' arguments`,
428
- },
429
- ],
419
+ ? List([])
420
+ : List([
421
+ immutable.fromJS({
422
+ loc: directive.name.loc,
423
+ entity: def.name.value,
424
+ directive: fulltextDirectiveName(directive),
425
+ message: `found invalid argument: '${argument.name.value}', @fulltext directives only allow 'name', 'language', 'algorithm', and 'includes' arguments`,
426
+ }),
427
+ ]),
430
428
  )
431
- }, [])
429
+ }, List([]))
432
430
  }
433
431
 
434
432
  const validateFulltextName = (def, directive) => {
435
433
  let name = directive.arguments.find(argument => argument.name.value == 'name')
436
434
  return name
437
435
  ? validateFulltextArgumentName(def, directive, name)
438
- : [
439
- {
440
- loc: directive.name.loc,
441
- entity: def.name.value,
442
- directive: fulltextDirectiveName(directive),
443
- message: `@fulltext argument 'name' must be specified`,
444
- },
445
- ]
436
+ : List([
437
+ immutable.fromJS({
438
+ loc: directive.name.loc,
439
+ entity: def.name.value,
440
+ directive: fulltextDirectiveName(directive),
441
+ message: `@fulltext argument 'name' must be specified`,
442
+ }),
443
+ ])
446
444
  }
447
445
 
448
446
  const validateFulltextArgumentName = (def, directive, argument) => {
449
447
  return argument.value.kind != 'StringValue'
450
- ? [
451
- {
452
- loc: directive.name.loc,
453
- entity: def.name.value,
454
- directive: fulltextDirectiveName(directive),
455
- message: `@fulltext argument 'name' must be a string`,
456
- },
457
- ]
458
- : []
448
+ ? List([
449
+ immutable.fromJS({
450
+ loc: directive.name.loc,
451
+ entity: def.name.value,
452
+ directive: fulltextDirectiveName(directive),
453
+ message: `@fulltext argument 'name' must be a string`,
454
+ }),
455
+ ])
456
+ : List([])
459
457
  }
460
458
 
461
459
  const fulltextDirectiveName = directive => {
@@ -467,14 +465,14 @@ const validateFulltextLanguage = (def, directive) => {
467
465
  let language = directive.arguments.find(argument => argument.name.value == 'language')
468
466
  return language
469
467
  ? validateFulltextArgumentLanguage(def, directive, language)
470
- : [
471
- {
472
- loc: directive.name.loc,
473
- entity: def.name.value,
474
- directive: fulltextDirectiveName(directive),
475
- message: `@fulltext argument 'language' must be specified`,
476
- },
477
- ]
468
+ : List([
469
+ immutable.fromJS({
470
+ loc: directive.name.loc,
471
+ entity: def.name.value,
472
+ directive: fulltextDirectiveName(directive),
473
+ message: `@fulltext argument 'language' must be specified`,
474
+ }),
475
+ ])
478
476
  }
479
477
 
480
478
  const validateFulltextArgumentLanguage = (def, directive, argument) => {
@@ -497,27 +495,27 @@ const validateFulltextArgumentLanguage = (def, directive, argument) => {
497
495
  'tr',
498
496
  ]
499
497
  if (argument.value.kind != 'EnumValue') {
500
- return [
501
- {
498
+ return List([
499
+ immutable.fromJS({
502
500
  loc: directive.name.loc,
503
501
  entity: def.name.value,
504
502
  directive: fulltextDirectiveName(directive),
505
503
  message: `@fulltext 'language' value must be one of: ${languages.join(', ')}`,
506
- },
507
- ]
504
+ }),
505
+ ])
508
506
  } else if (!languages.includes(argument.value.value)) {
509
- return [
510
- {
507
+ return List([
508
+ immutable.fromJS({
511
509
  loc: directive.name.loc,
512
510
  entity: def.name.value,
513
511
  directive: fulltextDirectiveName(directive),
514
512
  message: `@fulltext directive 'language' value must be one of: ${languages.join(
515
513
  ', ',
516
514
  )}`,
517
- },
518
- ]
515
+ }),
516
+ ])
519
517
  } else {
520
- return []
518
+ return List([])
521
519
  }
522
520
  }
523
521
 
@@ -525,35 +523,35 @@ const validateFulltextAlgorithm = (def, directive) => {
525
523
  let algorithm = directive.arguments.find(argument => argument.name.value == 'algorithm')
526
524
  return algorithm
527
525
  ? validateFulltextArgumentAlgorithm(def, directive, algorithm)
528
- : [
529
- {
530
- loc: directive.name.loc,
531
- entity: def.name.value,
532
- directive: fulltextDirectiveName(directive),
533
- message: `@fulltext argument 'algorithm' must be specified`,
534
- },
535
- ]
526
+ : List([
527
+ immutable.fromJS({
528
+ loc: directive.name.loc,
529
+ entity: def.name.value,
530
+ directive: fulltextDirectiveName(directive),
531
+ message: `@fulltext argument 'algorithm' must be specified`,
532
+ }),
533
+ ])
536
534
  }
537
535
 
538
536
  const validateFulltextArgumentAlgorithm = (def, directive, argument) => {
539
537
  if (argument.value.kind != 'EnumValue') {
540
- return [
541
- {
538
+ return List([
539
+ immutable.fromJS({
542
540
  loc: directive.name.loc,
543
541
  entity: def.name.value,
544
542
  directive: fulltextDirectiveName(directive),
545
543
  message: `@fulltext argument 'algorithm' must be one of: rank, proximityRank`,
546
- },
547
- ]
544
+ }),
545
+ ])
548
546
  } else if (!['rank', 'proximityRank'].includes(argument.value.value)) {
549
- return [
550
- {
547
+ return List([
548
+ immutable.fromJS({
551
549
  loc: directive.name.loc,
552
550
  entity: def.name.value,
553
551
  directive: fulltextDirectiveName(directive),
554
552
  message: `@fulltext 'algorithm' value, '${argument.value.value}', must be one of: rank, proximityRank`,
555
- },
556
- ]
553
+ }),
554
+ ])
557
555
  } else {
558
556
  return List([])
559
557
  }
@@ -563,52 +561,52 @@ const validateFulltextInclude = (def, directive) => {
563
561
  let include = directive.arguments.find(argument => argument.name.value == 'include')
564
562
  if (include) {
565
563
  if (include.value.kind != 'ListValue') {
566
- return [
567
- {
564
+ return List([
565
+ immutable.fromJS({
568
566
  loc: directive.name.loc,
569
567
  entity: def.name.value,
570
568
  directive: fulltextDirectiveName(directive),
571
569
  message: `@fulltext argument 'include' must be a list`,
572
- },
573
- ]
570
+ }),
571
+ ])
574
572
  }
575
573
  return include.value.values.reduce(
576
574
  (errors, type) =>
577
575
  errors.concat(validateFulltextArgumentInclude(def, directive, type)),
578
- [],
576
+ List(),
579
577
  )
580
578
  } else {
581
- return [
582
- {
579
+ return List([
580
+ immutable.fromJS({
583
581
  loc: directive.name.loc,
584
582
  entity: def.name.value,
585
583
  directive: fulltextDirectiveName(directive),
586
584
  message: `@fulltext argument 'include' must be specified`,
587
- },
588
- ]
585
+ }),
586
+ ])
589
587
  }
590
588
  }
591
589
 
592
590
  const validateFulltextArgumentInclude = (def, directive, argument) => {
593
591
  if (argument.kind != 'ObjectValue') {
594
- return [
595
- {
592
+ return List([
593
+ immutable.fromJS({
596
594
  loc: directive.name.loc,
597
595
  entity: def.name.value,
598
596
  directive: fulltextDirectiveName(directive),
599
597
  message: `@fulltext argument 'include' must have the form '[{entity: "entityName", fields: [{name: "fieldName"}, ...]} ...]`,
600
- },
601
- ]
598
+ }),
599
+ ])
602
600
  }
603
601
  if (argument.fields.length != 2) {
604
- return [
605
- {
602
+ return List([
603
+ immutable.fromJS({
606
604
  loc: directive.name.loc,
607
605
  entity: def.name.value,
608
606
  directive: fulltextDirectiveName(directive),
609
607
  message: `@fulltext argument include must have two fields, 'entity' and 'fields'`,
610
- },
611
- ]
608
+ }),
609
+ ])
612
610
  }
613
611
  return argument.fields.reduce(
614
612
  (errors, field) =>
@@ -619,33 +617,33 @@ const validateFulltextArgumentInclude = (def, directive, argument) => {
619
617
 
620
618
  const validateFulltextArgumentIncludeFields = (def, directive, field) => {
621
619
  if (!['entity', 'fields'].includes(field.name.value)) {
622
- return [
623
- {
620
+ return List([
621
+ immutable.fromJS({
624
622
  loc: directive.name.loc,
625
623
  entity: def.name.value,
626
624
  directive: fulltextDirectiveName(directive),
627
625
  message: `@fulltext argument 'include > ${field.name.value}' must be be one of: entity, fields`,
628
- },
629
- ]
626
+ }),
627
+ ])
630
628
  }
631
629
  if (field.name.value == 'entity' && field.value.kind != 'StringValue') {
632
- return [
633
- {
630
+ return List([
631
+ immutable.fromJS({
634
632
  loc: directive.name.loc,
635
633
  entity: def.name.value,
636
634
  directive: fulltextDirectiveName(directive),
637
635
  message: `@fulltext argument 'include > entity' must be the name of an entity in the schema enclosed in double quotes`,
638
- },
639
- ]
636
+ }),
637
+ ])
640
638
  } else if (field.name.value == 'fields' && field.value.kind != 'ListValue') {
641
- return [
642
- {
639
+ return List([
640
+ immutable.fromJS({
643
641
  loc: directive.name.loc,
644
642
  entity: def.name.value,
645
643
  directive: fulltextDirectiveName(directive),
646
644
  message: `@fulltext argument 'include > fields' must be a list`,
647
- },
648
- ]
645
+ }),
646
+ ])
649
647
  } else if (field.name.value == 'fields' && field.value.kind == 'ListValue') {
650
648
  return field.value.values.reduce(
651
649
  (errors, field) =>
@@ -661,74 +659,80 @@ const validateFulltextArgumentIncludeFields = (def, directive, field) => {
661
659
 
662
660
  const validateFulltextArgumentIncludeFieldsObjects = (def, directive, argument) => {
663
661
  if (argument.kind != 'ObjectValue') {
664
- return [
665
- {
662
+ return List([
663
+ immutable.fromJS({
666
664
  loc: directive.name.loc,
667
665
  entity: def.name.value,
668
666
  directive: fulltextDirectiveName(directive),
669
667
  message: `@fulltext argument 'include > fields' must have the form '[{ name: "fieldName" }, ...]`,
670
- },
671
- ]
668
+ }),
669
+ ])
672
670
  } else {
673
671
  return argument.fields.reduce(
674
672
  (errors, field) =>
675
673
  errors.concat(
676
674
  validateFulltextArgumentIncludeArgumentFieldsObject(def, directive, field),
677
675
  ),
678
- [],
676
+ List(),
679
677
  )
680
678
  }
681
679
  }
682
680
 
683
681
  const validateFulltextArgumentIncludeArgumentFieldsObject = (def, directive, field) => {
684
682
  if (!['name'].includes(field.name.value)) {
685
- return [
686
- {
683
+ return List([
684
+ immutable.fromJS({
687
685
  loc: directive.name.loc,
688
686
  entity: def.name.value,
689
687
  directive: fulltextDirectiveName(directive),
690
688
  message: `@fulltext argument 'include > fields' has invalid member '${field.name.value}', must be one of: name`,
691
- },
692
- ]
689
+ }),
690
+ ])
693
691
  } else if (field.name.value == 'name' && field.value.kind != 'StringValue') {
694
- return [
695
- {
692
+ return List([
693
+ immutable.fromJS({
696
694
  loc: directive.name.loc,
697
695
  entity: def.name.value,
698
696
  directive: fulltextDirectiveName(directive),
699
697
  message: `@fulltext argument 'include > fields > name' must be the name of an entity field enclosed in double quotes`,
700
- },
701
- ]
698
+ }),
699
+ ])
702
700
  } else {
703
701
  return List([])
704
702
  }
705
703
  }
706
704
 
707
705
  const importDirectiveTypeValidators = {
708
- StringValue: (_def, _directive, _type) => [],
706
+ StringValue: (_def, _directive, _type) => List(),
709
707
  ObjectValue: (def, directive, type) => {
710
- let errors = []
708
+ let errors = List()
711
709
  if (type.fields.length != 2) {
712
- return errors.push({
713
- loc: directive.name.loc,
714
- entity: def.name.value,
715
- message: `Import must be one of "Name" or { name: "Name", as: "Alias" }`,
716
- })
710
+ return errors.push(
711
+ immutable.fromJS({
712
+ loc: directive.name.loc,
713
+ entity: def.name.value,
714
+ message: `Import must be one of "Name" or { name: "Name", as: "Alias" }`,
715
+ }),
716
+ )
717
717
  }
718
718
  return type.fields.reduce((errors, field) => {
719
719
  if (!['name', 'as'].includes(field.name.value)) {
720
- return errors.push({
721
- loc: directive.name.loc,
722
- entity: def.name.value,
723
- message: `@import field '${field.name.value}' invalid, may only be one of: name, as`,
724
- })
720
+ return errors.push(
721
+ immutable.fromJS({
722
+ loc: directive.name.loc,
723
+ entity: def.name.value,
724
+ message: `@import field '${field.name.value}' invalid, may only be one of: name, as`,
725
+ }),
726
+ )
725
727
  }
726
728
  if (field.value.kind != 'StringValue') {
727
- return errors.push({
728
- loc: directive.name.loc,
729
- entity: def.name.value,
730
- message: `@import fields [name, as] must be strings`,
731
- })
729
+ return errors.push(
730
+ immutable.fromJS({
731
+ loc: directive.name.loc,
732
+ entity: def.name.value,
733
+ message: `@import fields [name, as] must be strings`,
734
+ }),
735
+ )
732
736
  }
733
737
  return errors
734
738
  }, errors)
@@ -738,112 +742,116 @@ const importDirectiveTypeValidators = {
738
742
  const validateImportDirectiveType = (def, directive, type) => {
739
743
  return importDirectiveTypeValidators[type.kind]
740
744
  ? importDirectiveTypeValidators[type.kind](def, directive, type)
741
- : [
742
- {
743
- loc: directive.name.loc,
744
- entity: def.name.value,
745
- message: `Import must be one of "Name" or { name: "Name", as: "Alias" }`,
746
- },
747
- ]
745
+ : List([
746
+ immutable.fromJS({
747
+ loc: directive.name.loc,
748
+ entity: def.name.value,
749
+ message: `Import must be one of "Name" or { name: "Name", as: "Alias" }`,
750
+ }),
751
+ ])
748
752
  }
749
753
 
750
754
  const validateImportDirectiveArgumentTypes = (def, directive, argument) => {
751
755
  if (argument.value.kind != 'ListValue') {
752
- return [
753
- {
756
+ return List([
757
+ immutable.fromJS({
754
758
  loc: directive.name.loc,
755
759
  entity: def.name.value,
756
760
  message: `@import argument 'types' must be an list`,
757
- },
758
- ]
761
+ }),
762
+ ])
759
763
  }
760
764
 
761
765
  return argument.value.values.reduce(
762
766
  (errors, type) => errors.concat(validateImportDirectiveType(def, directive, type)),
763
- [],
767
+ List(),
764
768
  )
765
769
  }
766
770
 
767
771
  const validateImportDirectiveArgumentFrom = (def, directive, argument) => {
768
772
  if (argument.value.kind != 'ObjectValue') {
769
- return [
770
- {
773
+ return List([
774
+ immutable.fromJS({
771
775
  loc: directive.name.loc,
772
776
  entity: def.name.value,
773
777
  message: `@import argument 'from' must be an object`,
774
- },
775
- ]
778
+ }),
779
+ ])
776
780
  }
777
781
 
778
782
  if (argument.value.fields.length != 1) {
779
- return [
780
- {
783
+ return List([
784
+ immutable.fromJS({
781
785
  loc: directive.name.loc,
782
786
  entity: def.name.value,
783
787
  message: `@import argument 'from' must have an 'id' or 'name' field`,
784
- },
785
- ]
788
+ }),
789
+ ])
786
790
  }
787
791
 
788
792
  return argument.value.fields.reduce((errors, field) => {
789
793
  if (!['name', 'id'].includes(field.name.value)) {
790
- return errors.push({
791
- loc: field.name.loc,
792
- entity: def.name.value,
793
- message: `@import argument 'from' must be one of { name: "Name" } or { id: "ID" }`,
794
- })
794
+ return errors.push(
795
+ immutable.fromJS({
796
+ loc: field.name.loc,
797
+ entity: def.name.value,
798
+ message: `@import argument 'from' must be one of { name: "Name" } or { id: "ID" }`,
799
+ }),
800
+ )
795
801
  }
796
802
  if (field.value.kind != 'StringValue') {
797
- return errors.push({
798
- loc: field.name.loc,
799
- entity: def.name.value,
800
- message: `@import argument 'from' must be one of { name: "Name" } or { id: "ID" } with string values`,
801
- })
803
+ return errors.push(
804
+ immutable.fromJS({
805
+ loc: field.name.loc,
806
+ entity: def.name.value,
807
+ message: `@import argument 'from' must be one of { name: "Name" } or { id: "ID" } with string values`,
808
+ }),
809
+ )
802
810
  }
803
811
  return errors
804
- }, [])
812
+ }, List())
805
813
  }
806
814
 
807
815
  const validateImportDirectiveFields = (def, directive) => {
808
816
  return directive.arguments.reduce((errors, argument) => {
809
817
  return errors.concat(
810
818
  ['types', 'from'].includes(argument.name.value)
811
- ? []
812
- : [
813
- {
814
- loc: directive.name.loc,
815
- entity: def.name.value,
816
- message: `found invalid argument: '${argument.name.value}', @import directives only allow 'types' and 'from' arguments`,
817
- },
818
- ],
819
+ ? List([])
820
+ : List([
821
+ immutable.fromJS({
822
+ loc: directive.name.loc,
823
+ entity: def.name.value,
824
+ message: `found invalid argument: '${argument.name.value}', @import directives only allow 'types' and 'from' arguments`,
825
+ }),
826
+ ]),
819
827
  )
820
- }, [])
828
+ }, List([]))
821
829
  }
822
830
 
823
831
  const validateImportDirectiveTypes = (def, directive) => {
824
832
  let types = directive.arguments.find(argument => argument.name.value == 'types')
825
833
  return types
826
834
  ? validateImportDirectiveArgumentTypes(def, directive, types)
827
- : [
828
- {
829
- loc: directive.name.loc,
830
- entity: def.name.value,
831
- message: `@import argument 'types' must be specified`,
832
- },
833
- ]
835
+ : List([
836
+ immutable.fromJS({
837
+ loc: directive.name.loc,
838
+ entity: def.name.value,
839
+ message: `@import argument 'types' must be specified`,
840
+ }),
841
+ ])
834
842
  }
835
843
 
836
844
  const validateImportDirectiveFrom = (def, directive) => {
837
845
  let from = directive.arguments.find(argument => argument.name.value == 'from')
838
846
  return from
839
847
  ? validateImportDirectiveArgumentFrom(def, directive, from)
840
- : [
841
- {
842
- loc: directive.name.loc,
843
- entity: def.name.value,
844
- message: `@import argument 'from' must be specified`,
845
- },
846
- ]
848
+ : List([
849
+ immutable.fromJS({
850
+ loc: directive.name.loc,
851
+ entity: def.name.value,
852
+ message: `@import argument 'from' must be specified`,
853
+ }),
854
+ ])
847
855
  }
848
856
 
849
857
  const validateImportDirective = (def, directive) =>
@@ -868,73 +876,75 @@ const validateSubgraphSchemaDirective = (def, directive) => {
868
876
  } else if (directive.name.value == 'fulltext') {
869
877
  return validateFulltext(def, directive)
870
878
  } else {
871
- return [
872
- {
879
+ return List([
880
+ immutable.fromJS({
873
881
  loc: directive.name.loc,
874
882
  entity: def.name.value,
875
883
  message: `${RESERVED_TYPE} type only allows @import and @fulltext directives`,
876
- },
877
- ]
884
+ }),
885
+ ])
878
886
  }
879
887
  }
880
888
 
881
889
  const validateSubgraphSchemaDirectives = def =>
882
890
  def.directives.reduce(
883
891
  (errors, directive) => errors.concat(validateSubgraphSchemaDirective(def, directive)),
884
- [],
892
+ List(),
885
893
  )
886
894
 
887
895
  const validateTypeHasNoFields = def =>
888
896
  def.fields.length
889
- ? [
890
- {
891
- loc: def.name.loc,
892
- entity: def.name.value,
893
- message: `${def.name.value} type is not allowed any fields by convention`,
894
- },
895
- ]
896
- : []
897
+ ? List([
898
+ immutable.fromJS({
899
+ loc: def.name.loc,
900
+ entity: def.name.value,
901
+ message: `${def.name.value} type is not allowed any fields by convention`,
902
+ }),
903
+ ])
904
+ : List()
897
905
 
898
- const validateAtLeastOneExtensionField = def => []
906
+ const validateAtLeastOneExtensionField = def => List()
899
907
 
900
908
  const typeDefinitionValidators = {
901
909
  ObjectTypeDefinition: (defs, def) =>
902
910
  def.name && def.name.value == RESERVED_TYPE
903
911
  ? List.of(...validateSubgraphSchemaDirectives(def), ...validateTypeHasNoFields(def))
904
912
  : List.of(
905
- ...validateEntityDirective(def),
906
- ...validateEntityID(def),
907
- ...validateEntityFields(defs, def),
908
- ...validateNoImportDirective(def),
909
- ...validateNoFulltext(def),
910
- ),
913
+ ...validateEntityDirective(def),
914
+ ...validateEntityID(def),
915
+ ...validateEntityFields(defs, def),
916
+ ...validateNoImportDirective(def),
917
+ ...validateNoFulltext(def),
918
+ ),
911
919
  ObjectTypeExtension: (_defs, def) => validateAtLeastOneExtensionField(def),
912
920
  }
913
921
 
914
922
  const validateTypeDefinition = (defs, def) =>
915
923
  typeDefinitionValidators[def.kind] !== undefined
916
924
  ? typeDefinitionValidators[def.kind](defs, def)
917
- : []
925
+ : List()
918
926
 
919
927
  const validateTypeDefinitions = defs =>
920
- defs.reduce((errors, def) => errors.concat(validateTypeDefinition(defs, def)), [])
928
+ defs.reduce((errors, def) => errors.concat(validateTypeDefinition(defs, def)), List())
921
929
 
922
930
  const validateNamingCollisionsInTypes = types => {
923
931
  let seen = Set()
924
932
  let conflicting = Set()
925
933
  return types.reduce((errors, type) => {
926
934
  if (seen.has(type) && !conflicting.has(type)) {
927
- errors = errors.push({
928
- loc: { start: 1, end: 1 },
929
- entity: type,
930
- message: `Type '${type}' is defined more than once`,
931
- })
935
+ errors = errors.push(
936
+ immutable.fromJS({
937
+ loc: { start: 1, end: 1 },
938
+ entity: type,
939
+ message: `Type '${type}' is defined more than once`,
940
+ }),
941
+ )
932
942
  conflicting = conflicting.add(type)
933
943
  } else {
934
944
  seen = seen.add(type)
935
945
  }
936
946
  return errors
937
- }, [])
947
+ }, List())
938
948
  }
939
949
 
940
950
  const validateNamingCollisions = (local, imported) =>