feat(graphql): improve non-nullability in query result types (#11952)
### What?
Makes several fields and list item types in query results (e.g. `docs`)
non-nullable.
### Why?
When dealing with code generated from a Payload GraphQL schema, it is
often necessary to use type guards and optional chaining.
For example:
```graphql
type Posts {
docs: [Post]
...
}
```
This implies that the `docs` field itself is nullable and that the array
can contain nulls. In reality, neither of these is true. But because of
the types generated by tools like `graphql-code-generator`, the way to
access `posts` ends up something like this:
```ts
const posts = (query.data.docs ?? []).filter(doc => doc != null);
```
Instead, we would like the schema to be:
```graphql
type Posts {
docs: [Post!]!
...
}
```
### How?
The proposed change involves adding `GraphQLNonNull` where appropriate.
---------
Co-authored-by: Dan Ribbens <dan.ribbens@gmail.com>
This commit is contained in:
@@ -1,21 +1,21 @@
|
||||
import { GraphQLBoolean, GraphQLInt, GraphQLList, GraphQLObjectType } from 'graphql'
|
||||
import { GraphQLBoolean, GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLObjectType } from 'graphql'
|
||||
|
||||
export const buildPaginatedListType = (name, docType) =>
|
||||
new GraphQLObjectType({
|
||||
name,
|
||||
fields: {
|
||||
docs: {
|
||||
type: new GraphQLList(docType),
|
||||
type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(docType))),
|
||||
},
|
||||
hasNextPage: { type: GraphQLBoolean },
|
||||
hasPrevPage: { type: GraphQLBoolean },
|
||||
limit: { type: GraphQLInt },
|
||||
nextPage: { type: GraphQLInt },
|
||||
hasNextPage: { type: new GraphQLNonNull(GraphQLBoolean) },
|
||||
hasPrevPage: { type: new GraphQLNonNull(GraphQLBoolean) },
|
||||
limit: { type: new GraphQLNonNull(GraphQLInt) },
|
||||
nextPage: { type: new GraphQLNonNull(GraphQLInt) },
|
||||
offset: { type: GraphQLInt },
|
||||
page: { type: GraphQLInt },
|
||||
pagingCounter: { type: GraphQLInt },
|
||||
prevPage: { type: GraphQLInt },
|
||||
totalDocs: { type: GraphQLInt },
|
||||
totalPages: { type: GraphQLInt },
|
||||
page: { type: new GraphQLNonNull(GraphQLInt) },
|
||||
pagingCounter: { type: new GraphQLNonNull(GraphQLInt) },
|
||||
prevPage: { type: new GraphQLNonNull(GraphQLInt) },
|
||||
totalDocs: { type: new GraphQLNonNull(GraphQLInt) },
|
||||
totalPages: { type: new GraphQLNonNull(GraphQLInt) },
|
||||
},
|
||||
})
|
||||
|
||||
@@ -348,11 +348,15 @@ export const fieldToSchemaMap: FieldToSchemaMap = {
|
||||
name: joinName,
|
||||
fields: {
|
||||
docs: {
|
||||
type: Array.isArray(field.collection)
|
||||
type: new GraphQLNonNull(
|
||||
Array.isArray(field.collection)
|
||||
? GraphQLJSON
|
||||
: new GraphQLList(graphqlResult.collections[field.collection].graphQL.type),
|
||||
: new GraphQLList(
|
||||
new GraphQLNonNull(graphqlResult.collections[field.collection].graphQL.type),
|
||||
),
|
||||
),
|
||||
},
|
||||
hasNextPage: { type: GraphQLBoolean },
|
||||
hasNextPage: { type: new GraphQLNonNull(GraphQLBoolean) },
|
||||
},
|
||||
}),
|
||||
args: {
|
||||
@@ -428,7 +432,7 @@ export const fieldToSchemaMap: FieldToSchemaMap = {
|
||||
...objectTypeConfig,
|
||||
[formatName(field.name)]: formattedNameResolver({
|
||||
type: withNullableType({
|
||||
type: field?.hasMany === true ? new GraphQLList(type) : type,
|
||||
type: field?.hasMany === true ? new GraphQLList(new GraphQLNonNull(type)) : type,
|
||||
field,
|
||||
forceNullable,
|
||||
parentIsLocalized,
|
||||
@@ -856,7 +860,10 @@ export const fieldToSchemaMap: FieldToSchemaMap = {
|
||||
...objectTypeConfig,
|
||||
[formatName(field.name)]: formattedNameResolver({
|
||||
type: withNullableType({
|
||||
type: field.hasMany === true ? new GraphQLList(GraphQLString) : GraphQLString,
|
||||
type:
|
||||
field.hasMany === true
|
||||
? new GraphQLList(new GraphQLNonNull(GraphQLString))
|
||||
: GraphQLString,
|
||||
field,
|
||||
forceNullable,
|
||||
parentIsLocalized,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user