fix(graphql): nextPage and prevPage are non nullable even though they can be null sometimes (#12201)

This PR introduced https://github.com/payloadcms/payload/pull/11952
improvement for graphql schema with making fields of the `Paginated<T>`
interface non-nullable.

However, there are a few special ones - `nextPage` and `prevPage`. They
can be `null` when:
The result returned 0 docs.
The result returned `x` docs, but in the DB we don't have `x+1` doc.
Thus, `nextPage` will be `null`. The result will have `nextPage: null`.
Finally, when we query 1st page, `prevPage` is `null` as well.

<img width="873" alt="image"
src="https://github.com/user-attachments/assets/04d04b13-ac26-4fc1-b421-b5f86efc9b65"
/>
This commit is contained in:
Sasha
2025-05-05 16:12:44 +03:00
committed by GitHub
parent 3c9ee5d3b4
commit 3fb81ef43b
2 changed files with 47 additions and 2 deletions

View File

@@ -10,11 +10,11 @@ export const buildPaginatedListType = (name, docType) =>
hasNextPage: { type: new GraphQLNonNull(GraphQLBoolean) }, hasNextPage: { type: new GraphQLNonNull(GraphQLBoolean) },
hasPrevPage: { type: new GraphQLNonNull(GraphQLBoolean) }, hasPrevPage: { type: new GraphQLNonNull(GraphQLBoolean) },
limit: { type: new GraphQLNonNull(GraphQLInt) }, limit: { type: new GraphQLNonNull(GraphQLInt) },
nextPage: { type: new GraphQLNonNull(GraphQLInt) }, nextPage: { type: GraphQLInt },
offset: { type: GraphQLInt }, offset: { type: GraphQLInt },
page: { type: new GraphQLNonNull(GraphQLInt) }, page: { type: new GraphQLNonNull(GraphQLInt) },
pagingCounter: { type: new GraphQLNonNull(GraphQLInt) }, pagingCounter: { type: new GraphQLNonNull(GraphQLInt) },
prevPage: { type: new GraphQLNonNull(GraphQLInt) }, prevPage: { type: GraphQLInt },
totalDocs: { type: new GraphQLNonNull(GraphQLInt) }, totalDocs: { type: new GraphQLNonNull(GraphQLInt) },
totalPages: { type: new GraphQLNonNull(GraphQLInt) }, totalPages: { type: new GraphQLNonNull(GraphQLInt) },
}, },

View File

@@ -104,5 +104,50 @@ describe('graphql', () => {
expect(res.hyphenated_name).toStrictEqual('example-hyphenated-name') expect(res.hyphenated_name).toStrictEqual('example-hyphenated-name')
}) })
it('should not error because of non nullable fields', async () => {
await payload.delete({ collection: 'posts', where: {} })
// this is an array if any errors
const res_1 = await restClient
.GRAPHQL_POST({
body: JSON.stringify({
query: `
query {
Posts {
docs {
title
}
prevPage
}
}
`,
}),
})
.then((res) => res.json())
expect(res_1.errors).toBeFalsy()
await payload.create({
collection: 'posts',
data: { title: 'any-title' },
})
const res_2 = await restClient
.GRAPHQL_POST({
body: JSON.stringify({
query: `
query {
Posts(limit: 1) {
docs {
title
}
}
}
`,
}),
})
.then((res) => res.json())
expect(res_2.errors).toBeFalsy()
})
}) })
}) })