Skip to content

Commit

Permalink
Add support for [field].graphql.isNonNull: true (#9234)
Browse files Browse the repository at this point in the history
  • Loading branch information
dcousens authored Feb 10, 2025
1 parent 1d127c8 commit 7a4624f
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 28 deletions.
5 changes: 5 additions & 0 deletions .changeset/add-isnonnull-true.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@keystone-6/core': major
---

Add support for [field].graphql.isNonNull: true
7 changes: 4 additions & 3 deletions packages/core/src/fields/non-null-graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export function makeValidateHook <ListTypeInfo extends BaseListTypeInfo> (
isNullable?: boolean
}
graphql?: {
isNonNull?: {
isNonNull?: boolean | {
read?: boolean
}
}
Expand Down Expand Up @@ -75,15 +75,16 @@ export function assertReadIsNonNullAllowed<ListTypeInfo extends BaseListTypeInfo
meta: FieldData,
config: {
graphql?: {
isNonNull?: {
isNonNull?: boolean | {
read?: boolean
}
}
},
dbNullable: boolean
) {
if (!dbNullable) return
if (!config.graphql?.isNonNull?.read) return
if (!config.graphql?.isNonNull) return
if (typeof config.graphql?.isNonNull === 'object' && !config.graphql.isNonNull.read) return

throw new Error(
`${meta.listKey}.${meta.fieldKey} sets graphql.isNonNull.read: true, but not validation.isRequired: true (or db.isNullable: false)\n` +
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/lib/core/initialise-lists.ts
Original file line number Diff line number Diff line change
Expand Up @@ -700,9 +700,9 @@ function getListsWithInitialisedFields (
cacheHint: f.graphql?.cacheHint,
isEnabled: isEnabledField,
isNonNull: {
read: f.graphql?.isNonNull?.read ?? false,
create: f.graphql?.isNonNull?.create ?? false,
update: f.graphql?.isNonNull?.update ?? false,
read: typeof f.graphql?.isNonNull === 'boolean' ? f.graphql.isNonNull : f.graphql?.isNonNull?.read ?? false,
create: typeof f.graphql?.isNonNull === 'boolean' ? f.graphql.isNonNull : f.graphql?.isNonNull?.create ?? false,
update: typeof f.graphql?.isNonNull === 'boolean' ? f.graphql.isNonNull : f.graphql?.isNonNull?.update ?? false,
},
},
ui: {
Expand Down
10 changes: 3 additions & 7 deletions packages/core/src/lib/typescript-schema-printer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ function printInterimType<L extends InitialisedList> (
const prismaType = `import('${prismaClientPath}').Prisma.${name}`
return [
`type Resolved${name} = {`,
...Object.entries(list.fields).map(([fieldKey, { dbField }]) => {
...Object.entries(list.fields).map(([fieldKey, { dbField, graphql }]) => {
if (dbField.kind === 'none') return ` ${fieldKey}?: undefined`

// TODO: this could be elsewhere, maybe id-field.ts
Expand All @@ -78,18 +78,14 @@ function printInterimType<L extends InitialisedList> (
return [
` ${fieldKey}: {`,
...Object.entries(dbField.fields).map(([subFieldKey, subDbField]) => {
// TODO: untrue if a db defaultValue is set
// const optional = operation === 'Create' && subDbField.mode === 'required' ? '' : '?'
const optional = '?'
const optional = operation === 'create' && subDbField.mode === 'required' && !subDbField.default ? '' : '?'
return ` ${subFieldKey}${optional}: ${prismaType}['${fieldKey}_${subFieldKey}']`
}),
` }`,
].join('\n')
}

// TODO: untrue if a db defaultValue is set
// const optional = operation === 'Create' && dbField.mode === 'required' ? '' : '?'
const optional = '?'
const optional = (operation === 'create' && dbField.mode === 'required' && !dbField.default) || graphql.isNonNull[operation] ? '' : '?'
return ` ${fieldKey}${optional}: ${prismaType}['${fieldKey}']`
}),
`}`,
Expand Down
32 changes: 17 additions & 15 deletions packages/core/src/types/config/fields.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,25 +37,27 @@ export type CommonFieldConfig<ListTypeInfo extends BaseListTypeInfo> = {
}
graphql?: {
cacheHint?: CacheHint
isNonNull?: {
// should this field be non-nullable on the {List} GraphQL type?
read?: boolean
// should this field be non-nullable on the {List}CreateInput GraphQL type?
create?: boolean
// should this field be non-nullable on the {List}UpdateInput GraphQL type?
update?: boolean
}
isNonNull?:
| boolean
| {
// whether this field is non-nullable on the {List} GraphQL type
read?: boolean
// whether this field is non-nullable on the {List}CreateInput GraphQL type
create?: boolean
// whether this field is non-nullable on the {List}UpdateInput GraphQL type
update?: boolean
}

omit?:
| boolean
| {
// should this field be omitted from the {List} GraphQL type?
read?: boolean
// should this field be omitted from the {List}CreateInput GraphQL type?
create?: boolean
// should this field be omitted from the {List}UpdateInput GraphQL type?
update?: boolean
}
// whether this field is omitted from the {List} GraphQL type
read?: boolean
// whether this field is omitted from the {List}CreateInput GraphQL type
create?: boolean
// whether this field is omitted from the {List}UpdateInput GraphQL type
update?: boolean
}
}
isFilterable?: MaybeFieldFunction<ListTypeInfo>
isOrderable?: MaybeFieldFunction<ListTypeInfo>
Expand Down

0 comments on commit 7a4624f

Please sign in to comment.