Skip to content

Commit

Permalink
fix: graphql schema generation for fields without queryable subfields (
Browse files Browse the repository at this point in the history
  • Loading branch information
JarrodMFlesch committed Dec 12, 2023
1 parent 77ebba3 commit 13e3e06
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 44 deletions.
35 changes: 23 additions & 12 deletions packages/payload/src/collections/graphql/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,19 +120,26 @@ function initCollectionsGraphQL(payload: Payload): void {
})
}

collection.graphQL.mutationInputType = new GraphQLNonNull(
buildMutationInputType(payload, singularName, fields, singularName),
const createMutationInputType = buildMutationInputType(
payload,
singularName,
fields,
singularName,
)
if (createMutationInputType) {
collection.graphQL.mutationInputType = new GraphQLNonNull(createMutationInputType)
}

collection.graphQL.updateMutationInputType = new GraphQLNonNull(
buildMutationInputType(
payload,
`${singularName}Update`,
fields.filter((field) => !(fieldAffectsData(field) && field.name === 'id')),
`${singularName}Update`,
true,
),
const updateMutationInputType = buildMutationInputType(
payload,
`${singularName}Update`,
fields.filter((field) => !(fieldAffectsData(field) && field.name === 'id')),
`${singularName}Update`,
true,
)
if (updateMutationInputType) {
collection.graphQL.updateMutationInputType = new GraphQLNonNull(updateMutationInputType)
}

payload.Query.fields[singularName] = {
args: {
Expand Down Expand Up @@ -182,7 +189,9 @@ function initCollectionsGraphQL(payload: Payload): void {

payload.Mutation.fields[`create${singularName}`] = {
args: {
data: { type: collection.graphQL.mutationInputType },
...(createMutationInputType
? { data: { type: collection.graphQL.mutationInputType } }
: {}),
draft: { type: GraphQLBoolean },
...(payload.config.localization
? {
Expand All @@ -198,7 +207,9 @@ function initCollectionsGraphQL(payload: Payload): void {
args: {
id: { type: new GraphQLNonNull(idType) },
autosave: { type: GraphQLBoolean },
data: { type: collection.graphQL.updateMutationInputType },
...(updateMutationInputType
? { data: { type: collection.graphQL.updateMutationInputType } }
: {}),
draft: { type: GraphQLBoolean },
...(payload.config.localization
? {
Expand Down
16 changes: 12 additions & 4 deletions packages/payload/src/globals/graphql/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,16 @@ function initGlobalsGraphQL(payload: Payload): void {

if (!payload.globals.graphQL) payload.globals.graphQL = {}

const updateMutationInputType = buildMutationInputType(
payload,
formattedName,
fields,
formattedName,
)
payload.globals.graphQL[slug] = {
mutationInputType: new GraphQLNonNull(
buildMutationInputType(payload, formattedName, fields, formattedName),
),
mutationInputType: updateMutationInputType
? new GraphQLNonNull(updateMutationInputType)
: null,
type: buildObjectType({
name: formattedName,
fields,
Expand All @@ -65,7 +71,9 @@ function initGlobalsGraphQL(payload: Payload): void {

payload.Mutation.fields[`update${formattedName}`] = {
args: {
data: { type: payload.globals.graphQL[slug].mutationInputType },
...(updateMutationInputType
? { data: { type: payload.globals.graphQL[slug].mutationInputType } }
: {}),
draft: { type: GraphQLBoolean },
...(payload.config.localization
? {
Expand Down
47 changes: 33 additions & 14 deletions packages/payload/src/graphql/schema/buildMutationInputType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ function buildMutationInputType(
fields: Field[],
parentName: string,
forceNullable = false,
): GraphQLInputObjectType {
): GraphQLInputObjectType | null {
const fieldToSchemaMap = {
array: (inputObjectTypeConfig: InputObjectTypeConfig, field: ArrayField) => {
const fullName = combineParentName(parentName, toWords(field.name, true))
Expand All @@ -84,6 +84,9 @@ function buildMutationInputType(
field.fields,
fullName,
)

if (!type) return inputObjectTypeConfig

type = new GraphQLList(withNullableType(field, type, forceNullable))
return {
...inputObjectTypeConfig,
Expand Down Expand Up @@ -120,6 +123,9 @@ function buildMutationInputType(
const requiresAtLeastOneField = groupOrTabHasRequiredSubfield(field)
const fullName = combineParentName(parentName, toWords(field.name, true))
let type: GraphQLType = buildMutationInputType(payload, fullName, field.fields, fullName)

if (!type) return inputObjectTypeConfig

if (requiresAtLeastOneField) type = new GraphQLNonNull(type)
return {
...inputObjectTypeConfig,
Expand Down Expand Up @@ -240,8 +246,10 @@ function buildMutationInputType(
const fullName = combineParentName(parentName, toWords(tab.name, true))
const requiresAtLeastOneField = groupOrTabHasRequiredSubfield(field)
let type: GraphQLType = buildMutationInputType(payload, fullName, tab.fields, fullName)
if (requiresAtLeastOneField) type = new GraphQLNonNull(type)

if (!type) return acc

if (requiresAtLeastOneField) type = new GraphQLNonNull(type)
return {
...acc,
[tab.name]: { type },
Expand Down Expand Up @@ -274,20 +282,31 @@ function buildMutationInputType(

const fieldName = formatName(name)

return new GraphQLInputObjectType({
name: `mutation${fieldName}Input`,
fields: fields.reduce((inputObjectTypeConfig, field) => {
const fieldSchema = fieldToSchemaMap[field.type]
const fieldSchemas = fields.reduce((inputObjectTypeConfig, field) => {
const fieldSchema = fieldToSchemaMap[field.type]

if (typeof fieldSchema !== 'function') {
return inputObjectTypeConfig
}
if (typeof fieldSchema !== 'function') {
return inputObjectTypeConfig
}

return {
...inputObjectTypeConfig,
...fieldSchema(inputObjectTypeConfig, field),
}
}, {}),
const schema = fieldSchema(inputObjectTypeConfig, field)
if (Object.keys(schema).length === 0) {
return inputObjectTypeConfig
}

return {
...inputObjectTypeConfig,
...fieldSchema(inputObjectTypeConfig, field),
}
}, {})

if (Object.keys(fieldSchemas).length === 0) {
return null
}

return new GraphQLInputObjectType({
name: `mutation${fieldName}Input`,
fields: fieldSchemas,
})
}

Expand Down
58 changes: 44 additions & 14 deletions packages/payload/src/graphql/schema/buildObjectType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,21 @@ function buildObjectType({
field?.interfaceName || combineParentName(parentName, toWords(field.name, true))

if (!payload.types.arrayTypes[interfaceName]) {
// eslint-disable-next-line no-param-reassign
payload.types.arrayTypes[interfaceName] = buildObjectType({
const objectType = buildObjectType({
name: interfaceName,
fields: field.fields,
forceNullable: isFieldNullable(field, forceNullable),
parentName: interfaceName,
payload,
})

if (Object.keys(objectType.getFields()).length) {
payload.types.arrayTypes[interfaceName] = objectType
}
}

if (!payload.types.arrayTypes[interfaceName]) {
return objectTypeConfig
}

const arrayType = new GraphQLList(new GraphQLNonNull(payload.types.arrayTypes[interfaceName]))
Expand All @@ -110,12 +117,12 @@ function buildObjectType({
}
},
blocks: (objectTypeConfig: ObjectTypeConfig, field: BlockField) => {
const blockTypes = field.blocks.map((block) => {
const blockTypes: GraphQLObjectType<any, any>[] = field.blocks.reduce((acc, block) => {
if (!payload.types.blockTypes[block.slug]) {
const interfaceName =
block?.interfaceName || block?.graphQL?.singularName || toWords(block.slug, true)
// eslint-disable-next-line no-param-reassign
payload.types.blockTypes[block.slug] = buildObjectType({

const objectType = buildObjectType({
name: interfaceName,
fields: [
...block.fields,
Expand All @@ -128,10 +135,22 @@ function buildObjectType({
parentName: interfaceName,
payload,
})

if (Object.keys(objectType.getFields()).length) {
payload.types.blockTypes[block.slug] = objectType
}
}

return payload.types.blockTypes[block.slug]
})
if (payload.types.blockTypes[block.slug]) {
acc.push(payload.types.blockTypes[block.slug])
}

return acc
}, [])

if (blockTypes.length === 0) {
return objectTypeConfig
}

const fullName = combineParentName(parentName, toWords(field.name, true))

Expand Down Expand Up @@ -177,14 +196,21 @@ function buildObjectType({
field?.interfaceName || combineParentName(parentName, toWords(field.name, true))

if (!payload.types.groupTypes[interfaceName]) {
// eslint-disable-next-line no-param-reassign
payload.types.groupTypes[interfaceName] = buildObjectType({
const objectType = buildObjectType({
name: interfaceName,
fields: field.fields,
forceNullable: isFieldNullable(field, forceNullable),
parentName: interfaceName,
payload,
})

if (Object.keys(objectType.getFields()).length) {
payload.types.groupTypes[interfaceName] = objectType
}
}

if (!payload.types.groupTypes[interfaceName]) {
return objectTypeConfig
}

return {
Expand Down Expand Up @@ -483,19 +509,23 @@ function buildObjectType({
tab?.interfaceName || combineParentName(parentName, toWords(tab.name, true))

if (!payload.types.tabTypes[interfaceName]) {
payload.types.tabTypes[interfaceName] = buildObjectType({
const objectType = buildObjectType({
name: interfaceName,
fields: tab.fields,
forceNullable,
parentName: interfaceName,
payload,
})
}

return {
...tabSchema,
[tab.name]: { type: payload.types.tabTypes[interfaceName] },
if (Object.keys(objectType.getFields()).length) {
return {
...tabSchema,
[tab.name]: { type: objectType },
}
}
}

return tabSchema
}

return {
Expand Down

0 comments on commit 13e3e06

Please sign in to comment.