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