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) =>
|
export const buildPaginatedListType = (name, docType) =>
|
||||||
new GraphQLObjectType({
|
new GraphQLObjectType({
|
||||||
name,
|
name,
|
||||||
fields: {
|
fields: {
|
||||||
docs: {
|
docs: {
|
||||||
type: new GraphQLList(docType),
|
type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(docType))),
|
||||||
},
|
},
|
||||||
hasNextPage: { type: GraphQLBoolean },
|
hasNextPage: { type: new GraphQLNonNull(GraphQLBoolean) },
|
||||||
hasPrevPage: { type: GraphQLBoolean },
|
hasPrevPage: { type: new GraphQLNonNull(GraphQLBoolean) },
|
||||||
limit: { type: GraphQLInt },
|
limit: { type: new GraphQLNonNull(GraphQLInt) },
|
||||||
nextPage: { type: GraphQLInt },
|
nextPage: { type: new GraphQLNonNull(GraphQLInt) },
|
||||||
offset: { type: GraphQLInt },
|
offset: { type: GraphQLInt },
|
||||||
page: { type: GraphQLInt },
|
page: { type: new GraphQLNonNull(GraphQLInt) },
|
||||||
pagingCounter: { type: GraphQLInt },
|
pagingCounter: { type: new GraphQLNonNull(GraphQLInt) },
|
||||||
prevPage: { type: GraphQLInt },
|
prevPage: { type: new GraphQLNonNull(GraphQLInt) },
|
||||||
totalDocs: { type: GraphQLInt },
|
totalDocs: { type: new GraphQLNonNull(GraphQLInt) },
|
||||||
totalPages: { type: GraphQLInt },
|
totalPages: { type: new GraphQLNonNull(GraphQLInt) },
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -348,11 +348,15 @@ export const fieldToSchemaMap: FieldToSchemaMap = {
|
|||||||
name: joinName,
|
name: joinName,
|
||||||
fields: {
|
fields: {
|
||||||
docs: {
|
docs: {
|
||||||
type: Array.isArray(field.collection)
|
type: new GraphQLNonNull(
|
||||||
? GraphQLJSON
|
Array.isArray(field.collection)
|
||||||
: new GraphQLList(graphqlResult.collections[field.collection].graphQL.type),
|
? GraphQLJSON
|
||||||
|
: new GraphQLList(
|
||||||
|
new GraphQLNonNull(graphqlResult.collections[field.collection].graphQL.type),
|
||||||
|
),
|
||||||
|
),
|
||||||
},
|
},
|
||||||
hasNextPage: { type: GraphQLBoolean },
|
hasNextPage: { type: new GraphQLNonNull(GraphQLBoolean) },
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
args: {
|
args: {
|
||||||
@@ -428,7 +432,7 @@ export const fieldToSchemaMap: FieldToSchemaMap = {
|
|||||||
...objectTypeConfig,
|
...objectTypeConfig,
|
||||||
[formatName(field.name)]: formattedNameResolver({
|
[formatName(field.name)]: formattedNameResolver({
|
||||||
type: withNullableType({
|
type: withNullableType({
|
||||||
type: field?.hasMany === true ? new GraphQLList(type) : type,
|
type: field?.hasMany === true ? new GraphQLList(new GraphQLNonNull(type)) : type,
|
||||||
field,
|
field,
|
||||||
forceNullable,
|
forceNullable,
|
||||||
parentIsLocalized,
|
parentIsLocalized,
|
||||||
@@ -856,7 +860,10 @@ export const fieldToSchemaMap: FieldToSchemaMap = {
|
|||||||
...objectTypeConfig,
|
...objectTypeConfig,
|
||||||
[formatName(field.name)]: formattedNameResolver({
|
[formatName(field.name)]: formattedNameResolver({
|
||||||
type: withNullableType({
|
type: withNullableType({
|
||||||
type: field.hasMany === true ? new GraphQLList(GraphQLString) : GraphQLString,
|
type:
|
||||||
|
field.hasMany === true
|
||||||
|
? new GraphQLList(new GraphQLNonNull(GraphQLString))
|
||||||
|
: GraphQLString,
|
||||||
field,
|
field,
|
||||||
forceNullable,
|
forceNullable,
|
||||||
parentIsLocalized,
|
parentIsLocalized,
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user