@payloadcms/graphql 3.28.0-internal.b3cf0a3 → 3.28.0

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,783 +1,6 @@
1
- import { GraphQLBoolean, GraphQLEnumType, GraphQLFloat, GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLObjectType, GraphQLString, GraphQLUnionType } from 'graphql';
2
- import { DateTimeResolver, EmailAddressResolver } from 'graphql-scalars';
3
- import { combineQueries, createDataloaderCacheKey, MissingEditorProp, toWords } from 'payload';
4
- import { tabHasName } from 'payload/shared';
5
- import { GraphQLJSON } from '../packages/graphql-type-json/index.js';
6
- import { combineParentName } from '../utilities/combineParentName.js';
7
- import { formatName } from '../utilities/formatName.js';
8
- import { formatOptions } from '../utilities/formatOptions.js';
9
- import { isFieldNullable } from './isFieldNullable.js';
10
- import { withNullableType } from './withNullableType.js';
1
+ import { GraphQLObjectType } from 'graphql';
2
+ import { fieldToSchemaMap } from './fieldToSchemaMap.js';
11
3
  export function buildObjectType({ name, baseFields = {}, config, fields, forceNullable, graphqlResult, parentIsLocalized, parentName }) {
12
- const fieldToSchemaMap = {
13
- array: (objectTypeConfig, field)=>{
14
- const interfaceName = field?.interfaceName || combineParentName(parentName, toWords(field.name, true));
15
- if (!graphqlResult.types.arrayTypes[interfaceName]) {
16
- const objectType = buildObjectType({
17
- name: interfaceName,
18
- config,
19
- fields: field.fields,
20
- forceNullable: isFieldNullable({
21
- field,
22
- forceNullable,
23
- parentIsLocalized
24
- }),
25
- graphqlResult,
26
- parentIsLocalized: field.localized || parentIsLocalized,
27
- parentName: interfaceName
28
- });
29
- if (Object.keys(objectType.getFields()).length) {
30
- graphqlResult.types.arrayTypes[interfaceName] = objectType;
31
- }
32
- }
33
- if (!graphqlResult.types.arrayTypes[interfaceName]) {
34
- return objectTypeConfig;
35
- }
36
- const arrayType = new GraphQLList(new GraphQLNonNull(graphqlResult.types.arrayTypes[interfaceName]));
37
- return {
38
- ...objectTypeConfig,
39
- [field.name]: {
40
- type: withNullableType({
41
- type: arrayType,
42
- field,
43
- parentIsLocalized
44
- })
45
- }
46
- };
47
- },
48
- blocks: (objectTypeConfig, field)=>{
49
- const blockTypes = (field.blockReferences ?? field.blocks).reduce((acc, _block)=>{
50
- const blockSlug = typeof _block === 'string' ? _block : _block.slug;
51
- if (!graphqlResult.types.blockTypes[blockSlug]) {
52
- // TODO: iterate over blocks mapped to block slug in v4, or pass through payload.blocks
53
- const block = typeof _block === 'string' ? config.blocks.find((b)=>b.slug === _block) : _block;
54
- const interfaceName = block?.interfaceName || block?.graphQL?.singularName || toWords(block.slug, true);
55
- const objectType = buildObjectType({
56
- name: interfaceName,
57
- config,
58
- fields: [
59
- ...block.fields,
60
- {
61
- name: 'blockType',
62
- type: 'text'
63
- }
64
- ],
65
- forceNullable,
66
- graphqlResult,
67
- parentIsLocalized,
68
- parentName: interfaceName
69
- });
70
- if (Object.keys(objectType.getFields()).length) {
71
- graphqlResult.types.blockTypes[block.slug] = objectType;
72
- }
73
- }
74
- if (graphqlResult.types.blockTypes[blockSlug]) {
75
- acc.push(graphqlResult.types.blockTypes[blockSlug]);
76
- }
77
- return acc;
78
- }, []);
79
- if (blockTypes.length === 0) {
80
- return objectTypeConfig;
81
- }
82
- const fullName = combineParentName(parentName, toWords(field.name, true));
83
- const type = new GraphQLList(new GraphQLNonNull(new GraphQLUnionType({
84
- name: fullName,
85
- resolveType: (data)=>graphqlResult.types.blockTypes[data.blockType].name,
86
- types: blockTypes
87
- })));
88
- return {
89
- ...objectTypeConfig,
90
- [field.name]: {
91
- type: withNullableType({
92
- type,
93
- field,
94
- parentIsLocalized
95
- })
96
- }
97
- };
98
- },
99
- checkbox: (objectTypeConfig, field)=>({
100
- ...objectTypeConfig,
101
- [field.name]: {
102
- type: withNullableType({
103
- type: GraphQLBoolean,
104
- field,
105
- forceNullable,
106
- parentIsLocalized
107
- })
108
- }
109
- }),
110
- code: (objectTypeConfig, field)=>({
111
- ...objectTypeConfig,
112
- [field.name]: {
113
- type: withNullableType({
114
- type: GraphQLString,
115
- field,
116
- forceNullable,
117
- parentIsLocalized
118
- })
119
- }
120
- }),
121
- collapsible: (objectTypeConfig, field)=>field.fields.reduce((objectTypeConfigWithCollapsibleFields, subField)=>{
122
- const addSubField = fieldToSchemaMap[subField.type];
123
- if (addSubField) {
124
- return addSubField(objectTypeConfigWithCollapsibleFields, subField);
125
- }
126
- return objectTypeConfigWithCollapsibleFields;
127
- }, objectTypeConfig),
128
- date: (objectTypeConfig, field)=>({
129
- ...objectTypeConfig,
130
- [field.name]: {
131
- type: withNullableType({
132
- type: DateTimeResolver,
133
- field,
134
- forceNullable,
135
- parentIsLocalized
136
- })
137
- }
138
- }),
139
- email: (objectTypeConfig, field)=>({
140
- ...objectTypeConfig,
141
- [field.name]: {
142
- type: withNullableType({
143
- type: EmailAddressResolver,
144
- field,
145
- forceNullable,
146
- parentIsLocalized
147
- })
148
- }
149
- }),
150
- group: (objectTypeConfig, field)=>{
151
- const interfaceName = field?.interfaceName || combineParentName(parentName, toWords(field.name, true));
152
- if (!graphqlResult.types.groupTypes[interfaceName]) {
153
- const objectType = buildObjectType({
154
- name: interfaceName,
155
- config,
156
- fields: field.fields,
157
- forceNullable: isFieldNullable({
158
- field,
159
- forceNullable,
160
- parentIsLocalized
161
- }),
162
- graphqlResult,
163
- parentIsLocalized: field.localized || parentIsLocalized,
164
- parentName: interfaceName
165
- });
166
- if (Object.keys(objectType.getFields()).length) {
167
- graphqlResult.types.groupTypes[interfaceName] = objectType;
168
- }
169
- }
170
- if (!graphqlResult.types.groupTypes[interfaceName]) {
171
- return objectTypeConfig;
172
- }
173
- return {
174
- ...objectTypeConfig,
175
- [field.name]: {
176
- type: graphqlResult.types.groupTypes[interfaceName],
177
- resolve: (parent, args, context)=>{
178
- return {
179
- ...parent[field.name],
180
- _id: parent._id ?? parent.id
181
- };
182
- }
183
- }
184
- };
185
- },
186
- join: (objectTypeConfig, field)=>{
187
- const joinName = combineParentName(parentName, toWords(field.name, true));
188
- const joinType = {
189
- type: new GraphQLObjectType({
190
- name: joinName,
191
- fields: {
192
- docs: {
193
- type: Array.isArray(field.collection) ? GraphQLJSON : new GraphQLList(graphqlResult.collections[field.collection].graphQL.type)
194
- },
195
- hasNextPage: {
196
- type: GraphQLBoolean
197
- }
198
- }
199
- }),
200
- args: {
201
- limit: {
202
- type: GraphQLInt
203
- },
204
- page: {
205
- type: GraphQLInt
206
- },
207
- sort: {
208
- type: GraphQLString
209
- },
210
- where: {
211
- type: Array.isArray(field.collection) ? GraphQLJSON : graphqlResult.collections[field.collection].graphQL.whereInputType
212
- }
213
- },
214
- extensions: {
215
- complexity: typeof field?.graphQL?.complexity === 'number' ? field.graphQL.complexity : 10
216
- },
217
- async resolve (parent, args, context) {
218
- const { collection } = field;
219
- const { limit, page, sort, where } = args;
220
- const { req } = context;
221
- const fullWhere = combineQueries(where, {
222
- [field.on]: {
223
- equals: parent._id ?? parent.id
224
- }
225
- });
226
- if (Array.isArray(collection)) {
227
- throw new Error('GraphQL with array of join.field.collection is not implemented');
228
- }
229
- return await req.payload.find({
230
- collection,
231
- depth: 0,
232
- fallbackLocale: req.fallbackLocale,
233
- limit,
234
- locale: req.locale,
235
- overrideAccess: false,
236
- page,
237
- req,
238
- sort,
239
- where: fullWhere
240
- });
241
- }
242
- };
243
- return {
244
- ...objectTypeConfig,
245
- [field.name]: joinType
246
- };
247
- },
248
- json: (objectTypeConfig, field)=>({
249
- ...objectTypeConfig,
250
- [field.name]: {
251
- type: withNullableType({
252
- type: GraphQLJSON,
253
- field,
254
- forceNullable,
255
- parentIsLocalized
256
- })
257
- }
258
- }),
259
- number: (objectTypeConfig, field)=>{
260
- const type = field?.name === 'id' ? GraphQLInt : GraphQLFloat;
261
- return {
262
- ...objectTypeConfig,
263
- [field.name]: {
264
- type: withNullableType({
265
- type: field?.hasMany === true ? new GraphQLList(type) : type,
266
- field,
267
- forceNullable,
268
- parentIsLocalized
269
- })
270
- }
271
- };
272
- },
273
- point: (objectTypeConfig, field)=>({
274
- ...objectTypeConfig,
275
- [field.name]: {
276
- type: withNullableType({
277
- type: new GraphQLList(new GraphQLNonNull(GraphQLFloat)),
278
- field,
279
- forceNullable,
280
- parentIsLocalized
281
- })
282
- }
283
- }),
284
- radio: (objectTypeConfig, field)=>({
285
- ...objectTypeConfig,
286
- [field.name]: {
287
- type: withNullableType({
288
- type: new GraphQLEnumType({
289
- name: combineParentName(parentName, field.name),
290
- values: formatOptions(field)
291
- }),
292
- field,
293
- forceNullable,
294
- parentIsLocalized
295
- })
296
- }
297
- }),
298
- relationship: (objectTypeConfig, field)=>{
299
- const { relationTo } = field;
300
- const isRelatedToManyCollections = Array.isArray(relationTo);
301
- const hasManyValues = field.hasMany;
302
- const relationshipName = combineParentName(parentName, toWords(field.name, true));
303
- let type;
304
- let relationToType = null;
305
- const graphQLCollections = config.collections.filter((collectionConfig)=>collectionConfig.graphQL !== false);
306
- if (Array.isArray(relationTo)) {
307
- relationToType = new GraphQLEnumType({
308
- name: `${relationshipName}_RelationTo`,
309
- values: relationTo.filter((relation)=>graphQLCollections.some((collection)=>collection.slug === relation)).reduce((relations, relation)=>({
310
- ...relations,
311
- [formatName(relation)]: {
312
- value: relation
313
- }
314
- }), {})
315
- });
316
- // Only pass collections that are GraphQL enabled
317
- const types = relationTo.filter((relation)=>graphQLCollections.some((collection)=>collection.slug === relation)).map((relation)=>graphqlResult.collections[relation]?.graphQL.type);
318
- type = new GraphQLObjectType({
319
- name: `${relationshipName}_Relationship`,
320
- fields: {
321
- relationTo: {
322
- type: relationToType
323
- },
324
- value: {
325
- type: new GraphQLUnionType({
326
- name: relationshipName,
327
- resolveType (data) {
328
- return graphqlResult.collections[data.collection].graphQL.type.name;
329
- },
330
- types
331
- })
332
- }
333
- }
334
- });
335
- } else {
336
- ;
337
- ({ type } = graphqlResult.collections[relationTo].graphQL);
338
- }
339
- // If the relationshipType is undefined at this point,
340
- // it can be assumed that this blockType can have a relationship
341
- // to itself. Therefore, we set the relationshipType equal to the blockType
342
- // that is currently being created.
343
- type = type || newlyCreatedBlockType;
344
- const relationshipArgs = {};
345
- const relationsUseDrafts = (Array.isArray(relationTo) ? relationTo : [
346
- relationTo
347
- ]).filter((relation)=>graphQLCollections.some((collection)=>collection.slug === relation)).some((relation)=>graphqlResult.collections[relation].config.versions?.drafts);
348
- if (relationsUseDrafts) {
349
- relationshipArgs.draft = {
350
- type: GraphQLBoolean
351
- };
352
- }
353
- if (config.localization) {
354
- relationshipArgs.locale = {
355
- type: graphqlResult.types.localeInputType
356
- };
357
- relationshipArgs.fallbackLocale = {
358
- type: graphqlResult.types.fallbackLocaleInputType
359
- };
360
- }
361
- const relationship = {
362
- type: withNullableType({
363
- type: hasManyValues ? new GraphQLList(new GraphQLNonNull(type)) : type,
364
- field,
365
- forceNullable,
366
- parentIsLocalized
367
- }),
368
- args: relationshipArgs,
369
- extensions: {
370
- complexity: typeof field?.graphQL?.complexity === 'number' ? field.graphQL.complexity : 10
371
- },
372
- async resolve (parent, args, context) {
373
- const value = parent[field.name];
374
- const locale = args.locale || context.req.locale;
375
- const fallbackLocale = args.fallbackLocale || context.req.fallbackLocale;
376
- let relatedCollectionSlug = field.relationTo;
377
- const draft = Boolean(args.draft ?? context.req.query?.draft);
378
- if (hasManyValues) {
379
- const results = [];
380
- const resultPromises = [];
381
- const createPopulationPromise = async (relatedDoc, i)=>{
382
- let id = relatedDoc;
383
- let collectionSlug = field.relationTo;
384
- const isValidGraphQLCollection = isRelatedToManyCollections ? graphQLCollections.some((collection)=>collectionSlug.includes(collection.slug)) : graphQLCollections.some((collection)=>collectionSlug === collection.slug);
385
- if (isValidGraphQLCollection) {
386
- if (isRelatedToManyCollections) {
387
- collectionSlug = relatedDoc.relationTo;
388
- id = relatedDoc.value;
389
- }
390
- const result = await context.req.payloadDataLoader.load(createDataloaderCacheKey({
391
- collectionSlug: collectionSlug,
392
- currentDepth: 0,
393
- depth: 0,
394
- docID: id,
395
- draft,
396
- fallbackLocale,
397
- locale,
398
- overrideAccess: false,
399
- showHiddenFields: false,
400
- transactionID: context.req.transactionID
401
- }));
402
- if (result) {
403
- if (isRelatedToManyCollections) {
404
- results[i] = {
405
- relationTo: collectionSlug,
406
- value: {
407
- ...result,
408
- collection: collectionSlug
409
- }
410
- };
411
- } else {
412
- results[i] = result;
413
- }
414
- }
415
- }
416
- };
417
- if (value) {
418
- value.forEach((relatedDoc, i)=>{
419
- resultPromises.push(createPopulationPromise(relatedDoc, i));
420
- });
421
- }
422
- await Promise.all(resultPromises);
423
- return results;
424
- }
425
- let id = value;
426
- if (isRelatedToManyCollections && value) {
427
- id = value.value;
428
- relatedCollectionSlug = value.relationTo;
429
- }
430
- if (id) {
431
- if (graphQLCollections.some((collection)=>collection.slug === relatedCollectionSlug)) {
432
- const relatedDocument = await context.req.payloadDataLoader.load(createDataloaderCacheKey({
433
- collectionSlug: relatedCollectionSlug,
434
- currentDepth: 0,
435
- depth: 0,
436
- docID: id,
437
- draft,
438
- fallbackLocale,
439
- locale,
440
- overrideAccess: false,
441
- showHiddenFields: false,
442
- transactionID: context.req.transactionID
443
- }));
444
- if (relatedDocument) {
445
- if (isRelatedToManyCollections) {
446
- return {
447
- relationTo: relatedCollectionSlug,
448
- value: {
449
- ...relatedDocument,
450
- collection: relatedCollectionSlug
451
- }
452
- };
453
- }
454
- return relatedDocument;
455
- }
456
- }
457
- return null;
458
- }
459
- return null;
460
- }
461
- };
462
- return {
463
- ...objectTypeConfig,
464
- [field.name]: relationship
465
- };
466
- },
467
- richText: (objectTypeConfig, field)=>({
468
- ...objectTypeConfig,
469
- [field.name]: {
470
- type: withNullableType({
471
- type: GraphQLJSON,
472
- field,
473
- forceNullable,
474
- parentIsLocalized
475
- }),
476
- args: {
477
- depth: {
478
- type: GraphQLInt
479
- }
480
- },
481
- async resolve (parent, args, context) {
482
- let depth = config.defaultDepth;
483
- if (typeof args.depth !== 'undefined') {
484
- depth = args.depth;
485
- }
486
- if (!field?.editor) {
487
- throw new MissingEditorProp(field) // while we allow disabling editor functionality, you should not have any richText fields defined if you do not have an editor
488
- ;
489
- }
490
- if (typeof field?.editor === 'function') {
491
- throw new Error('Attempted to access unsanitized rich text editor.');
492
- }
493
- const editor = field?.editor;
494
- // RichText fields have their own depth argument in GraphQL.
495
- // This is why the populationPromise (which populates richtext fields like uploads and relationships)
496
- // is run here again, with the provided depth.
497
- // In the graphql find.ts resolver, the depth is then hard-coded to 0.
498
- // Effectively, this means that the populationPromise for GraphQL is only run here, and not in the find.ts resolver / normal population promise.
499
- if (editor?.graphQLPopulationPromises) {
500
- const fieldPromises = [];
501
- const populationPromises = [];
502
- const populateDepth = field?.maxDepth !== undefined && field?.maxDepth < depth ? field?.maxDepth : depth;
503
- editor?.graphQLPopulationPromises({
504
- context,
505
- depth: populateDepth,
506
- draft: args.draft,
507
- field,
508
- fieldPromises,
509
- findMany: false,
510
- flattenLocales: false,
511
- overrideAccess: false,
512
- parentIsLocalized,
513
- populationPromises,
514
- req: context.req,
515
- showHiddenFields: false,
516
- siblingDoc: parent
517
- });
518
- await Promise.all(fieldPromises);
519
- await Promise.all(populationPromises);
520
- }
521
- return parent[field.name];
522
- }
523
- }
524
- }),
525
- row: (objectTypeConfig, field)=>field.fields.reduce((objectTypeConfigWithRowFields, subField)=>{
526
- const addSubField = fieldToSchemaMap[subField.type];
527
- if (addSubField) {
528
- return addSubField(objectTypeConfigWithRowFields, subField);
529
- }
530
- return objectTypeConfigWithRowFields;
531
- }, objectTypeConfig),
532
- select: (objectTypeConfig, field)=>{
533
- const fullName = combineParentName(parentName, field.name);
534
- let type = new GraphQLEnumType({
535
- name: fullName,
536
- values: formatOptions(field)
537
- });
538
- type = field.hasMany ? new GraphQLList(new GraphQLNonNull(type)) : type;
539
- type = withNullableType({
540
- type,
541
- field,
542
- forceNullable,
543
- parentIsLocalized
544
- });
545
- return {
546
- ...objectTypeConfig,
547
- [field.name]: {
548
- type
549
- }
550
- };
551
- },
552
- tabs: (objectTypeConfig, field)=>field.tabs.reduce((tabSchema, tab)=>{
553
- if (tabHasName(tab)) {
554
- const interfaceName = tab?.interfaceName || combineParentName(parentName, toWords(tab.name, true));
555
- if (!graphqlResult.types.groupTypes[interfaceName]) {
556
- const objectType = buildObjectType({
557
- name: interfaceName,
558
- config,
559
- fields: tab.fields,
560
- forceNullable,
561
- graphqlResult,
562
- parentIsLocalized: tab.localized || parentIsLocalized,
563
- parentName: interfaceName
564
- });
565
- if (Object.keys(objectType.getFields()).length) {
566
- graphqlResult.types.groupTypes[interfaceName] = objectType;
567
- }
568
- }
569
- if (!graphqlResult.types.groupTypes[interfaceName]) {
570
- return tabSchema;
571
- }
572
- return {
573
- ...tabSchema,
574
- [tab.name]: {
575
- type: graphqlResult.types.groupTypes[interfaceName],
576
- resolve (parent, args, context) {
577
- return {
578
- ...parent[tab.name],
579
- _id: parent._id ?? parent.id
580
- };
581
- }
582
- }
583
- };
584
- }
585
- return {
586
- ...tabSchema,
587
- ...tab.fields.reduce((subFieldSchema, subField)=>{
588
- const addSubField = fieldToSchemaMap[subField.type];
589
- if (addSubField) {
590
- return addSubField(subFieldSchema, subField);
591
- }
592
- return subFieldSchema;
593
- }, tabSchema)
594
- };
595
- }, objectTypeConfig),
596
- text: (objectTypeConfig, field)=>({
597
- ...objectTypeConfig,
598
- [field.name]: {
599
- type: withNullableType({
600
- type: field.hasMany === true ? new GraphQLList(GraphQLString) : GraphQLString,
601
- field,
602
- forceNullable,
603
- parentIsLocalized
604
- })
605
- }
606
- }),
607
- textarea: (objectTypeConfig, field)=>({
608
- ...objectTypeConfig,
609
- [field.name]: {
610
- type: withNullableType({
611
- type: GraphQLString,
612
- field,
613
- forceNullable,
614
- parentIsLocalized
615
- })
616
- }
617
- }),
618
- upload: (objectTypeConfig, field)=>{
619
- const { relationTo } = field;
620
- const isRelatedToManyCollections = Array.isArray(relationTo);
621
- const hasManyValues = field.hasMany;
622
- const relationshipName = combineParentName(parentName, toWords(field.name, true));
623
- let type;
624
- let relationToType = null;
625
- if (Array.isArray(relationTo)) {
626
- relationToType = new GraphQLEnumType({
627
- name: `${relationshipName}_RelationTo`,
628
- values: relationTo.reduce((relations, relation)=>({
629
- ...relations,
630
- [formatName(relation)]: {
631
- value: relation
632
- }
633
- }), {})
634
- });
635
- const types = relationTo.map((relation)=>graphqlResult.collections[relation].graphQL.type);
636
- type = new GraphQLObjectType({
637
- name: `${relationshipName}_Relationship`,
638
- fields: {
639
- relationTo: {
640
- type: relationToType
641
- },
642
- value: {
643
- type: new GraphQLUnionType({
644
- name: relationshipName,
645
- resolveType (data) {
646
- return graphqlResult.collections[data.collection].graphQL.type.name;
647
- },
648
- types
649
- })
650
- }
651
- }
652
- });
653
- } else {
654
- ;
655
- ({ type } = graphqlResult.collections[relationTo].graphQL);
656
- }
657
- // If the relationshipType is undefined at this point,
658
- // it can be assumed that this blockType can have a relationship
659
- // to itself. Therefore, we set the relationshipType equal to the blockType
660
- // that is currently being created.
661
- type = type || newlyCreatedBlockType;
662
- const relationshipArgs = {};
663
- const relationsUseDrafts = (Array.isArray(relationTo) ? relationTo : [
664
- relationTo
665
- ]).some((relation)=>graphqlResult.collections[relation].config.versions?.drafts);
666
- if (relationsUseDrafts) {
667
- relationshipArgs.draft = {
668
- type: GraphQLBoolean
669
- };
670
- }
671
- if (config.localization) {
672
- relationshipArgs.locale = {
673
- type: graphqlResult.types.localeInputType
674
- };
675
- relationshipArgs.fallbackLocale = {
676
- type: graphqlResult.types.fallbackLocaleInputType
677
- };
678
- }
679
- const relationship = {
680
- type: withNullableType({
681
- type: hasManyValues ? new GraphQLList(new GraphQLNonNull(type)) : type,
682
- field,
683
- forceNullable,
684
- parentIsLocalized
685
- }),
686
- args: relationshipArgs,
687
- extensions: {
688
- complexity: typeof field?.graphQL?.complexity === 'number' ? field.graphQL.complexity : 10
689
- },
690
- async resolve (parent, args, context) {
691
- const value = parent[field.name];
692
- const locale = args.locale || context.req.locale;
693
- const fallbackLocale = args.fallbackLocale || context.req.fallbackLocale;
694
- let relatedCollectionSlug = field.relationTo;
695
- const draft = Boolean(args.draft ?? context.req.query?.draft);
696
- if (hasManyValues) {
697
- const results = [];
698
- const resultPromises = [];
699
- const createPopulationPromise = async (relatedDoc, i)=>{
700
- let id = relatedDoc;
701
- let collectionSlug = field.relationTo;
702
- if (isRelatedToManyCollections) {
703
- collectionSlug = relatedDoc.relationTo;
704
- id = relatedDoc.value;
705
- }
706
- const result = await context.req.payloadDataLoader.load(createDataloaderCacheKey({
707
- collectionSlug,
708
- currentDepth: 0,
709
- depth: 0,
710
- docID: id,
711
- draft,
712
- fallbackLocale,
713
- locale,
714
- overrideAccess: false,
715
- showHiddenFields: false,
716
- transactionID: context.req.transactionID
717
- }));
718
- if (result) {
719
- if (isRelatedToManyCollections) {
720
- results[i] = {
721
- relationTo: collectionSlug,
722
- value: {
723
- ...result,
724
- collection: collectionSlug
725
- }
726
- };
727
- } else {
728
- results[i] = result;
729
- }
730
- }
731
- };
732
- if (value) {
733
- value.forEach((relatedDoc, i)=>{
734
- resultPromises.push(createPopulationPromise(relatedDoc, i));
735
- });
736
- }
737
- await Promise.all(resultPromises);
738
- return results;
739
- }
740
- let id = value;
741
- if (isRelatedToManyCollections && value) {
742
- id = value.value;
743
- relatedCollectionSlug = value.relationTo;
744
- }
745
- if (id) {
746
- const relatedDocument = await context.req.payloadDataLoader.load(createDataloaderCacheKey({
747
- collectionSlug: relatedCollectionSlug,
748
- currentDepth: 0,
749
- depth: 0,
750
- docID: id,
751
- draft,
752
- fallbackLocale,
753
- locale,
754
- overrideAccess: false,
755
- showHiddenFields: false,
756
- transactionID: context.req.transactionID
757
- }));
758
- if (relatedDocument) {
759
- if (isRelatedToManyCollections) {
760
- return {
761
- relationTo: relatedCollectionSlug,
762
- value: {
763
- ...relatedDocument,
764
- collection: relatedCollectionSlug
765
- }
766
- };
767
- }
768
- return relatedDocument;
769
- }
770
- return null;
771
- }
772
- return null;
773
- }
774
- };
775
- return {
776
- ...objectTypeConfig,
777
- [field.name]: relationship
778
- };
779
- }
780
- };
781
4
  const objectSchema = {
782
5
  name,
783
6
  fields: ()=>fields.reduce((objectTypeConfig, field)=>{
@@ -787,7 +10,16 @@ export function buildObjectType({ name, baseFields = {}, config, fields, forceNu
787
10
  }
788
11
  return {
789
12
  ...objectTypeConfig,
790
- ...fieldSchema(objectTypeConfig, field)
13
+ ...fieldSchema({
14
+ config,
15
+ field,
16
+ forceNullable,
17
+ graphqlResult,
18
+ newlyCreatedBlockType,
19
+ objectTypeConfig,
20
+ parentIsLocalized,
21
+ parentName
22
+ })
791
23
  };
792
24
  }, baseFields)
793
25
  };