diff --git a/examples/assets-local/schema.graphql b/examples/assets-local/schema.graphql index aa2c66202d4..57f46bfc559 100644 --- a/examples/assets-local/schema.graphql +++ b/examples/assets-local/schema.graphql @@ -170,6 +170,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -242,6 +243,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/assets-s3/schema.graphql b/examples/assets-s3/schema.graphql index aa2c66202d4..57f46bfc559 100644 --- a/examples/assets-s3/schema.graphql +++ b/examples/assets-s3/schema.graphql @@ -170,6 +170,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -242,6 +243,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/auth/schema.graphql b/examples/auth/schema.graphql index 3bbe083ed5c..5911c4e2af4 100644 --- a/examples/auth/schema.graphql +++ b/examples/auth/schema.graphql @@ -135,6 +135,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -207,6 +208,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/cloudinary/schema.graphql b/examples/cloudinary/schema.graphql index 3f72e019b47..45d9b255d02 100644 --- a/examples/cloudinary/schema.graphql +++ b/examples/cloudinary/schema.graphql @@ -185,6 +185,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -257,6 +258,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/custom-admin-ui-logo/schema.graphql b/examples/custom-admin-ui-logo/schema.graphql index bfe08296c8c..29b110dadf9 100644 --- a/examples/custom-admin-ui-logo/schema.graphql +++ b/examples/custom-admin-ui-logo/schema.graphql @@ -254,6 +254,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -326,6 +327,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/custom-admin-ui-navigation/schema.graphql b/examples/custom-admin-ui-navigation/schema.graphql index bfe08296c8c..29b110dadf9 100644 --- a/examples/custom-admin-ui-navigation/schema.graphql +++ b/examples/custom-admin-ui-navigation/schema.graphql @@ -254,6 +254,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -326,6 +327,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/custom-admin-ui-pages/schema.graphql b/examples/custom-admin-ui-pages/schema.graphql index bfe08296c8c..29b110dadf9 100644 --- a/examples/custom-admin-ui-pages/schema.graphql +++ b/examples/custom-admin-ui-pages/schema.graphql @@ -254,6 +254,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -326,6 +327,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/custom-field-view/schema.graphql b/examples/custom-field-view/schema.graphql index 27d0a6f5ba3..131d30965d2 100644 --- a/examples/custom-field-view/schema.graphql +++ b/examples/custom-field-view/schema.graphql @@ -257,6 +257,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -329,6 +330,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/custom-field/schema.graphql b/examples/custom-field/schema.graphql index 7f23d54c25e..e3f5631272b 100644 --- a/examples/custom-field/schema.graphql +++ b/examples/custom-field/schema.graphql @@ -149,6 +149,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -221,6 +222,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/custom-id/schema.graphql b/examples/custom-id/schema.graphql index 9fc7bc6af82..bedfde42bf0 100644 --- a/examples/custom-id/schema.graphql +++ b/examples/custom-id/schema.graphql @@ -415,6 +415,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -487,6 +488,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/custom-output-paths/my-graphql.graphql b/examples/custom-output-paths/my-graphql.graphql index fc3788e549e..3a606a23739 100644 --- a/examples/custom-output-paths/my-graphql.graphql +++ b/examples/custom-output-paths/my-graphql.graphql @@ -149,6 +149,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -221,6 +222,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/custom-session-invalidation/schema.graphql b/examples/custom-session-invalidation/schema.graphql index 0d14c689015..d32b434c826 100644 --- a/examples/custom-session-invalidation/schema.graphql +++ b/examples/custom-session-invalidation/schema.graphql @@ -131,6 +131,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -203,6 +204,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/custom-session-jwt/schema.graphql b/examples/custom-session-jwt/schema.graphql index 70a5505dc80..0fece306d03 100644 --- a/examples/custom-session-jwt/schema.graphql +++ b/examples/custom-session-jwt/schema.graphql @@ -186,6 +186,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -258,6 +259,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/custom-session-next-auth/schema.graphql b/examples/custom-session-next-auth/schema.graphql index 48ffae3a67b..9841cd65684 100644 --- a/examples/custom-session-next-auth/schema.graphql +++ b/examples/custom-session-next-auth/schema.graphql @@ -220,6 +220,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -292,6 +293,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/custom-session-passport/schema.graphql b/examples/custom-session-passport/schema.graphql index 48ffae3a67b..9841cd65684 100644 --- a/examples/custom-session-passport/schema.graphql +++ b/examples/custom-session-passport/schema.graphql @@ -220,6 +220,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -292,6 +293,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/custom-session-redis/schema.graphql b/examples/custom-session-redis/schema.graphql index c2b13378f9c..940b508b6f6 100644 --- a/examples/custom-session-redis/schema.graphql +++ b/examples/custom-session-redis/schema.graphql @@ -125,6 +125,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -197,6 +198,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/custom-session/schema.graphql b/examples/custom-session/schema.graphql index 70a5505dc80..0fece306d03 100644 --- a/examples/custom-session/schema.graphql +++ b/examples/custom-session/schema.graphql @@ -186,6 +186,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -258,6 +259,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/default-values/schema.graphql b/examples/default-values/schema.graphql index 8cebb817bb7..a6561bf53e0 100644 --- a/examples/default-values/schema.graphql +++ b/examples/default-values/schema.graphql @@ -273,6 +273,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -345,6 +346,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/document-field-customisation/keystone-server/schema.graphql b/examples/document-field-customisation/keystone-server/schema.graphql index aebb622ed7c..3b6eed0d900 100644 --- a/examples/document-field-customisation/keystone-server/schema.graphql +++ b/examples/document-field-customisation/keystone-server/schema.graphql @@ -245,6 +245,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -317,6 +318,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/document-field/schema.graphql b/examples/document-field/schema.graphql index f67f010e7fa..b9b8ec8b95d 100644 --- a/examples/document-field/schema.graphql +++ b/examples/document-field/schema.graphql @@ -269,6 +269,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -341,6 +342,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/extend-express-app/schema.graphql b/examples/extend-express-app/schema.graphql index 5dfe53d71cc..8cf5f29c967 100644 --- a/examples/extend-express-app/schema.graphql +++ b/examples/extend-express-app/schema.graphql @@ -141,6 +141,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -213,6 +214,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/extend-graphql-schema-graphql-tools/schema.graphql b/examples/extend-graphql-schema-graphql-tools/schema.graphql index 739f80a8508..4ac23c7526b 100644 --- a/examples/extend-graphql-schema-graphql-tools/schema.graphql +++ b/examples/extend-graphql-schema-graphql-tools/schema.graphql @@ -266,6 +266,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -338,6 +339,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/extend-graphql-schema-graphql-ts/schema.graphql b/examples/extend-graphql-schema-graphql-ts/schema.graphql index 1a005548cd0..12f0b6c5d87 100644 --- a/examples/extend-graphql-schema-graphql-ts/schema.graphql +++ b/examples/extend-graphql-schema-graphql-ts/schema.graphql @@ -264,6 +264,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -336,6 +337,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/extend-graphql-schema-nexus/schema.graphql b/examples/extend-graphql-schema-nexus/schema.graphql index 5108ae391dd..c5fa5e113d8 100644 --- a/examples/extend-graphql-schema-nexus/schema.graphql +++ b/examples/extend-graphql-schema-nexus/schema.graphql @@ -250,6 +250,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -322,6 +323,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/extend-graphql-subscriptions/schema.graphql b/examples/extend-graphql-subscriptions/schema.graphql index 32a0bea129d..2436a4f6874 100644 --- a/examples/extend-graphql-subscriptions/schema.graphql +++ b/examples/extend-graphql-subscriptions/schema.graphql @@ -257,6 +257,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -329,6 +330,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/extend-prisma-schema/schema.graphql b/examples/extend-prisma-schema/schema.graphql index 1cb96a88099..8f61539c5f9 100644 --- a/examples/extend-prisma-schema/schema.graphql +++ b/examples/extend-prisma-schema/schema.graphql @@ -277,6 +277,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -349,6 +350,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/field-groups/schema.graphql b/examples/field-groups/schema.graphql index b071d3c2619..68e0ef42ac9 100644 --- a/examples/field-groups/schema.graphql +++ b/examples/field-groups/schema.graphql @@ -150,6 +150,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -222,6 +223,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/framework-astro/schema.graphql b/examples/framework-astro/schema.graphql index 59c42dfe410..6f5f7b1186a 100644 --- a/examples/framework-astro/schema.graphql +++ b/examples/framework-astro/schema.graphql @@ -131,6 +131,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -203,6 +204,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/framework-nextjs-app-directory/schema.graphql b/examples/framework-nextjs-app-directory/schema.graphql index ca5648cc601..90c1572b808 100644 --- a/examples/framework-nextjs-app-directory/schema.graphql +++ b/examples/framework-nextjs-app-directory/schema.graphql @@ -151,6 +151,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -223,6 +224,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/framework-nextjs-pages-directory/schema.graphql b/examples/framework-nextjs-pages-directory/schema.graphql index ba3afafd528..29cc0b87624 100644 --- a/examples/framework-nextjs-pages-directory/schema.graphql +++ b/examples/framework-nextjs-pages-directory/schema.graphql @@ -149,6 +149,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -221,6 +222,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/framework-nextjs-two-servers/keystone-server/schema.graphql b/examples/framework-nextjs-two-servers/keystone-server/schema.graphql index aebb622ed7c..3b6eed0d900 100644 --- a/examples/framework-nextjs-two-servers/keystone-server/schema.graphql +++ b/examples/framework-nextjs-two-servers/keystone-server/schema.graphql @@ -245,6 +245,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -317,6 +318,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/framework-remix/schema.graphql b/examples/framework-remix/schema.graphql index e530b0f0f15..961fe642c7c 100644 --- a/examples/framework-remix/schema.graphql +++ b/examples/framework-remix/schema.graphql @@ -131,6 +131,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -203,6 +204,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/graphql-ts-gql/schema.graphql b/examples/graphql-ts-gql/schema.graphql index 883055ca943..87456fb2737 100644 --- a/examples/graphql-ts-gql/schema.graphql +++ b/examples/graphql-ts-gql/schema.graphql @@ -265,6 +265,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -337,6 +338,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/hooks/schema.graphql b/examples/hooks/schema.graphql index 49335e243c1..6d403d4e9f1 100644 --- a/examples/hooks/schema.graphql +++ b/examples/hooks/schema.graphql @@ -170,6 +170,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -242,6 +243,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/limits/schema.graphql b/examples/limits/schema.graphql index 7e53eff22da..769e62e5e45 100644 --- a/examples/limits/schema.graphql +++ b/examples/limits/schema.graphql @@ -126,6 +126,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -198,6 +199,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/omit/schema.graphql b/examples/omit/schema.graphql index b186aa35151..d586fe6bdce 100644 --- a/examples/omit/schema.graphql +++ b/examples/omit/schema.graphql @@ -186,6 +186,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -258,6 +259,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/reuse/schema.graphql b/examples/reuse/schema.graphql index a0038899353..01e0d766de1 100644 --- a/examples/reuse/schema.graphql +++ b/examples/reuse/schema.graphql @@ -266,6 +266,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -338,6 +339,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/script/schema.graphql b/examples/script/schema.graphql index 20d1647cce6..eb970242f05 100644 --- a/examples/script/schema.graphql +++ b/examples/script/schema.graphql @@ -144,6 +144,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -216,6 +217,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/singleton/schema.graphql b/examples/singleton/schema.graphql index b96987fac29..784785c74d4 100644 --- a/examples/singleton/schema.graphql +++ b/examples/singleton/schema.graphql @@ -221,6 +221,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -293,6 +294,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/testing/schema.graphql b/examples/testing/schema.graphql index 3f6eac5c130..6453d7cef28 100644 --- a/examples/testing/schema.graphql +++ b/examples/testing/schema.graphql @@ -284,6 +284,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -356,6 +357,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/transactions/schema.graphql b/examples/transactions/schema.graphql index 3d39d847a3d..7082a652fba 100644 --- a/examples/transactions/schema.graphql +++ b/examples/transactions/schema.graphql @@ -308,6 +308,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -380,6 +381,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/usecase-blog-moderated/schema.graphql b/examples/usecase-blog-moderated/schema.graphql index 31b1086239d..2f38bea442b 100644 --- a/examples/usecase-blog-moderated/schema.graphql +++ b/examples/usecase-blog-moderated/schema.graphql @@ -368,6 +368,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -440,6 +441,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/usecase-blog/schema.graphql b/examples/usecase-blog/schema.graphql index 34a2e018932..118722dee9b 100644 --- a/examples/usecase-blog/schema.graphql +++ b/examples/usecase-blog/schema.graphql @@ -311,6 +311,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -383,6 +384,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/usecase-relationship-union/schema.graphql b/examples/usecase-relationship-union/schema.graphql index 54ea2fbb059..d7f977bf4f9 100644 --- a/examples/usecase-relationship-union/schema.graphql +++ b/examples/usecase-relationship-union/schema.graphql @@ -255,6 +255,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -327,6 +328,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/usecase-roles/schema.graphql b/examples/usecase-roles/schema.graphql index fd2f1122126..e15469434a3 100644 --- a/examples/usecase-roles/schema.graphql +++ b/examples/usecase-roles/schema.graphql @@ -367,6 +367,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -439,6 +440,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/usecase-todo/schema.graphql b/examples/usecase-todo/schema.graphql index b9130c3383f..bf97fcb90f0 100644 --- a/examples/usecase-todo/schema.graphql +++ b/examples/usecase-todo/schema.graphql @@ -255,6 +255,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -327,6 +328,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/usecase-versioning/schema.graphql b/examples/usecase-versioning/schema.graphql index 9a6339e4ca5..fe3e766c10d 100644 --- a/examples/usecase-versioning/schema.graphql +++ b/examples/usecase-versioning/schema.graphql @@ -147,6 +147,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -219,6 +220,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples/virtual-field/schema.graphql b/examples/virtual-field/schema.graphql index c859efc58e9..19e855c2377 100644 --- a/examples/virtual-field/schema.graphql +++ b/examples/virtual-field/schema.graphql @@ -156,6 +156,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -228,6 +229,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/packages/auth/src/schema.ts b/packages/auth/src/schema.ts index 652ecb7d4cd..b4c65067ab5 100644 --- a/packages/auth/src/schema.ts +++ b/packages/auth/src/schema.ts @@ -94,26 +94,19 @@ export const getSchemaExtension = ({ // technically this will incorrectly error if someone has a schema extension that adds a field to the list output type // and then wants to fetch that field with `sessionData` but it's extremely unlikely someone will do that since if // they want to add a GraphQL field, they'll probably use a virtual field - const query = `query($id: ID!) { ${ - getGqlNames({ listKey, pluralGraphQLName: '' }).itemQueryName - }(where: { id: $id }) { ${sessionData} } }` + const { itemQueryName } = getGqlNames({ listKey, pluralGraphQLName: '' }) + const query = `query($id: ID!) { ${itemQueryName}(where: { id: $id }) { ${sessionData} } }` let ast try { ast = parse(query) } catch (err) { - throw new Error( - `The query to get session data has a syntax error, the sessionData option in your createAuth usage is likely incorrect\n${err}` - ) + throw new Error( `The query to get session data has a syntax error, the sessionData option in your createAuth usage is likely incorrect\n${err}`) } const errors = validate(base.schema, ast) if (errors.length) { - throw new Error( - `The query to get session data has validation errors, the sessionData option in your createAuth usage is likely incorrect\n${errors.join( - '\n' - )}` - ) + throw new Error(`The query to get session data has validation errors, the sessionData option in your createAuth usage is likely incorrect\n${errors.join('\n')}`) } return [ diff --git a/packages/core/src/admin-ui/admin-meta-graphql.ts b/packages/core/src/admin-ui/admin-meta-graphql.ts index 7d2e6ae6d3f..c6a501b520d 100644 --- a/packages/core/src/admin-ui/admin-meta-graphql.ts +++ b/packages/core/src/admin-ui/admin-meta-graphql.ts @@ -1,4 +1,7 @@ -import type { JSONValue } from '../types' +import { + type GraphQLNames, + type JSONValue, +} from '../types/utils' import { gql } from './apollo' export const staticAdminMetaQuery = gql` @@ -34,6 +37,34 @@ export const staticAdminMetaQuery = gql` path } } + graphql { + names { + outputTypeName + whereInputName + whereUniqueInputName + + createInputName + createMutationName + createManyMutationName + relateToOneForCreateInputName + relateToManyForCreateInputName + + itemQueryName + listQueryName + listQueryCountName + listOrderName + + updateInputName + updateMutationName + updateManyInputName + updateManyMutationName + relateToOneForUpdateInputName + relateToManyForUpdateInputName + + deleteMutationName + deleteManyMutationName + } + } fields { __typename path @@ -95,6 +126,9 @@ export type StaticAdminMetaQuery = { path: string }> }> + graphql: { + names: GraphQLNames + }, pageSize: number initialColumns: Array diff --git a/packages/core/src/admin-ui/context.tsx b/packages/core/src/admin-ui/context.tsx index cdfadb27ffa..e634ca48997 100644 --- a/packages/core/src/admin-ui/context.tsx +++ b/packages/core/src/admin-ui/context.tsx @@ -4,14 +4,24 @@ import { ToastProvider } from '@keystone-ui/toast' import { LoadingDots } from '@keystone-ui/loading' import { DrawerProvider } from '@keystone-ui/modals' import { createUploadLink } from 'apollo-upload-client' -import type { AdminConfig, AdminMeta, FieldViews } from '../types' +import { + type AdminConfig, + type AdminMeta, + type FieldViews +} from '../types' import { useAdminMeta } from './utils/useAdminMeta' -import { ApolloProvider, ApolloClient, InMemoryCache, type ApolloError, type DocumentNode } from './apollo' +import { + type ApolloError, + type DocumentNode, + ApolloProvider, + ApolloClient, + InMemoryCache, +} from './apollo' import { type AuthenticatedItem, + type CreateViewFieldModes, type VisibleLists, useLazyMetadata, - type CreateViewFieldModes, } from './utils/useLazyMetadata' type KeystoneContextType = { @@ -103,21 +113,18 @@ export function KeystoneProvider (props: KeystoneProviderProps) { ) } -export const useKeystone = (): { +export function useKeystone (): { adminConfig: AdminConfig adminMeta: AdminMeta authenticatedItem: AuthenticatedItem visibleLists: VisibleLists createViewFieldModes: CreateViewFieldModes apiPath: string -} => { +} { const value = useContext(KeystoneContext) - if (!value) { - throw new Error('useKeystone must be called inside a KeystoneProvider component') - } - if (value.adminMeta.state === 'error') { - throw new Error('An error occurred when loading Admin Metadata') - } + if (!value) throw new Error('useKeystone must be called inside a KeystoneProvider component') + if (value.adminMeta.state === 'error') throw new Error('An error occurred when loading Admin Metadata') + return { adminConfig: value.adminConfig, adminMeta: value.adminMeta.value, @@ -128,29 +135,22 @@ export const useKeystone = (): { } } -export const useReinitContext = () => { +export function useReinitContext () { const value = useContext(KeystoneContext) - if (!value) { - throw new Error('useReinitContext must be called inside a KeystoneProvider component') - } - return value.reinitContext + if (value) return value.reinitContext + throw new Error('useReinitContext must be called inside a KeystoneProvider component') } -export const useRawKeystone = () => { +export function useRawKeystone () { const value = useContext(KeystoneContext) - if (!value) { - throw new Error('useRawKeystone must be called inside a KeystoneProvider component') - } - return value + if (value) return value + throw new Error('useRawKeystone must be called inside a KeystoneProvider component') } -export const useList = (key: string) => { +export function useList (key: string) { const { adminMeta: { lists }, } = useKeystone() - if (lists[key]) { - return lists[key] - } else { - throw new Error(`Invalid list key provided to useList: ${key}`) - } + if (key in lists) return lists[key] + throw new Error(`Invalid list key provided to useList: ${key}`) } diff --git a/packages/core/src/admin-ui/utils/useAdminMeta.tsx b/packages/core/src/admin-ui/utils/useAdminMeta.tsx index a83a11ff2c4..acfc83e430e 100644 --- a/packages/core/src/admin-ui/utils/useAdminMeta.tsx +++ b/packages/core/src/admin-ui/utils/useAdminMeta.tsx @@ -1,11 +1,16 @@ import { useEffect, useMemo, useState } from 'react' import hashString from '@emotion/hash' -import { type AdminMeta, type FieldViews, getGqlNames } from '../../types' +import { + type AdminMeta, + type FieldViews +} from '../../types' import { useLazyQuery } from '../apollo' -import { type StaticAdminMetaQuery, staticAdminMetaQuery } from '../admin-meta-graphql' +import { + type StaticAdminMetaQuery, + staticAdminMetaQuery +} from '../admin-meta-graphql' const expectedExports = new Set(['Cell', 'Field', 'controller', 'CardValue']) - const adminMetaLocalStorageKey = 'keystone.adminMeta' let _mustRenderServerResult = true @@ -17,22 +22,18 @@ function useMustRenderServerResult () { forceUpdate(1) }, []) - if (typeof window === 'undefined') { - return true - } + if (typeof window === 'undefined') return true return _mustRenderServerResult } export function useAdminMeta (adminMetaHash: string, fieldViews: FieldViews) { const adminMetaFromLocalStorage = useMemo(() => { - if (typeof window === 'undefined') { - return - } + if (typeof window === 'undefined') return + const item = localStorage.getItem(adminMetaLocalStorageKey) - if (item === null) { - return - } + if (item === null) return + try { let parsed = JSON.parse(item) if (parsed.hash === adminMetaHash) { @@ -57,12 +58,12 @@ export function useAdminMeta (adminMetaHash: string, fieldViews: FieldViews) { }, [shouldFetchAdminMeta, fetchStaticAdminMeta]) const runtimeAdminMeta = useMemo(() => { - if ((!data || error) && !adminMetaFromLocalStorage) { - return undefined - } + if ((!data || error) && !adminMetaFromLocalStorage) return undefined + const adminMeta: StaticAdminMetaQuery['keystone']['adminMeta'] = adminMetaFromLocalStorage ? adminMetaFromLocalStorage : data.keystone.adminMeta + const runtimeAdminMeta: AdminMeta = { lists: {}, } @@ -70,8 +71,8 @@ export function useAdminMeta (adminMetaHash: string, fieldViews: FieldViews) { for (const list of adminMeta.lists) { runtimeAdminMeta.lists[list.key] = { ...list, + gqlNames: list.graphql.names, groups: [], - gqlNames: getGqlNames({ listKey: list.key, pluralGraphQLName: list.listQueryName }), // TODO: replace with an object fields: {}, } diff --git a/packages/core/src/admin-ui/utils/useCreateItem.ts b/packages/core/src/admin-ui/utils/useCreateItem.ts index cc6f9d46c68..3c3aa79001c 100644 --- a/packages/core/src/admin-ui/utils/useCreateItem.ts +++ b/packages/core/src/admin-ui/utils/useCreateItem.ts @@ -26,8 +26,8 @@ export function useCreateItem (list: ListMeta): CreateItemHookResult { item: ${list.gqlNames.createMutationName}(data: $data) { id label: ${list.labelField} - } - }` + } + }` ) const [value, setValue] = useState(() => { diff --git a/packages/core/src/fields/types/virtual/index.ts b/packages/core/src/fields/types/virtual/index.ts index 060b1ee8df9..d8b11971431 100644 --- a/packages/core/src/fields/types/virtual/index.ts +++ b/packages/core/src/fields/types/virtual/index.ts @@ -42,12 +42,11 @@ export type VirtualFieldConfig = } } -export const virtual = - ({ - field, - ...config - }: VirtualFieldConfig): FieldTypeFunc => - meta => { +export function virtual ({ + field, + ...config +}: VirtualFieldConfig): FieldTypeFunc { + return (meta) => { const usableField = typeof field === 'function' ? field(meta.lists) : field const namedType = getNamedType(usableField.type.graphQLType) const hasRequiredArgs = @@ -55,6 +54,7 @@ export const virtual = Object.values( usableField.args as Record> ).some(x => x.type.kind === 'non-null' && x.defaultValue === undefined) + if ( (!isLeafType(namedType) || hasRequiredArgs) && !config.ui?.query && @@ -73,9 +73,8 @@ export const virtual = `}` ) } - return fieldType({ - kind: 'none', - })({ + + return fieldType({ kind: 'none', })({ ...config, output: graphql.field({ ...(usableField as any), @@ -85,6 +84,9 @@ export const virtual = }), __ksTelemetryFieldTypeName: '@keystone-6/virtual', views: '@keystone-6/core/fields/types/virtual/views', - getAdminMeta: () => ({ query: config.ui?.query || '' }), + getAdminMeta: () => ({ + query: config.ui?.query || '' + }), }) } +} diff --git a/packages/core/src/lib/core/initialise-lists.ts b/packages/core/src/lib/core/initialise-lists.ts index c8e91675393..e492a26bede 100644 --- a/packages/core/src/lib/core/initialise-lists.ts +++ b/packages/core/src/lib/core/initialise-lists.ts @@ -1,6 +1,5 @@ import { type CacheHint } from '@apollo/cache-control-types' import { GraphQLString, isInputObjectType } from 'graphql' -import { type getGqlNames, QueryMode } from '../../types' import { type BaseItem, type BaseListTypeInfo, @@ -13,7 +12,12 @@ import { type MaybePromise, type NextFieldType, type FieldTypeFunc, + QueryMode } from '../../types' +import { + type GraphQLNames, + __getNames, +} from '../../types/utils' import { graphql } from '../..' import { type FieldHooks, @@ -33,12 +37,17 @@ import { parseListAccessControl, parseFieldAccessControl, } from './access-control' -import { areArraysEqual, getNamesFromList } from './utils' -import { type ResolvedDBField, resolveRelationships } from './resolve-relationships' +import { areArraysEqual } from './utils' +import { + type ResolvedDBField, + resolveRelationships +} from './resolve-relationships' import { outputTypeField } from './queries/output-field' import { assertFieldsValid } from './field-assertions' export type InitialisedField = { + fieldKey: string + access: ResolvedFieldAccessControl dbField: ResolvedDBField hooks: ResolvedFieldHooks @@ -84,6 +93,8 @@ export type InitialisedField = { > export type InitialisedList = { + listKey: string + access: ResolvedListAccessControl fields: Record @@ -99,14 +110,11 @@ export type InitialisedList = { resolvedDbFields: Record lists: Record - cacheHint: ((args: CacheHintArgs) => CacheHint) | undefined - listKey: string - graphql: { types: GraphQLTypesForList - names: ReturnType + names: GraphQLNames namePlural: string // TODO: remove - isEnabled: IsEnabled + isEnabled: IsListEnabled } prisma: { @@ -123,9 +131,10 @@ export type InitialisedList = { } isSingleton: boolean + cacheHint: ((args: CacheHintArgs) => CacheHint) | undefined } -type IsEnabled = { +type IsListEnabled = { type: boolean query: boolean create: boolean @@ -137,15 +146,12 @@ type IsEnabled = { function throwIfNotAFilter (x: unknown, listKey: string, fieldKey: string) { if (['boolean', 'undefined', 'function'].includes(typeof x)) return - - throw new Error( - `Configuration option '${listKey}.${fieldKey}' must be either a boolean value or a function. Received '${x}'.` - ) + throw new Error(`Configuration option '${listKey}.${fieldKey}' must be either a boolean value or a function. Received '${x}'.`) } type ListConfigType = __ResolvedKeystoneConfig['lists'][string] type FieldConfigType = ReturnType> -type PartiallyInitialisedList1 = { graphql: { isEnabled: IsEnabled } } +type PartiallyInitialisedList1 = { graphql: { isEnabled: IsListEnabled } } type PartiallyInitialisedList2 = Omit function getIsEnabled (listKey: string, listConfig: ListConfigType) { @@ -183,11 +189,11 @@ function getIsEnabled (listKey: string, listConfig: ListConfigType) { } } -function getIsEnabledField (f: FieldConfigType, listKey: string, listConfig: PartiallyInitialisedList1) { +function getIsEnabledField (f: FieldConfigType, listKey: string, list: PartiallyInitialisedList1) { const omit = f.graphql?.omit ?? false const { - isFilterable = listConfig.graphql.isEnabled.filter, - isOrderable = listConfig.graphql.isEnabled.orderBy, + isFilterable = list.graphql.isEnabled.filter, + isOrderable = list.graphql.isEnabled.orderBy, } = f // TODO: check types in initConfig @@ -351,247 +357,38 @@ function parseFieldHooks ( } function getListsWithInitialisedFields ( - { storage: configStorage, lists: listsConfig, db: { provider } }: __ResolvedKeystoneConfig, - listGraphqlTypes: Record, - intermediateLists: Record + config: __ResolvedKeystoneConfig, + listsRef: Record, ) { - const result: Record = {} - - for (const [listKey, list] of Object.entries(listsConfig)) { - const intermediateList = intermediateLists[listKey] - const resultFields: Record = {} - const groups = [] - const fieldKeys = Object.keys(list.fields) - - for (const [idx, [fieldKey, fieldFunc]] of Object.entries(list.fields).entries()) { - if (fieldKey.startsWith('__group')) { - const group = fieldFunc as any - if ( - typeof group === 'object' && - group !== null && - typeof group.label === 'string' && - (group.description === null || typeof group.description === 'string') && - Array.isArray(group.fields) && - areArraysEqual(group.fields, fieldKeys.slice(idx + 1, idx + 1 + group.fields.length)) - ) { - groups.push(group) - continue - } - throw new Error(`unexpected value for a group at ${listKey}.${fieldKey}`) - } - - if (typeof fieldFunc !== 'function') { - throw new Error(`The field at ${listKey}.${fieldKey} does not provide a function`) - } - - const f = fieldFunc({ - fieldKey, - listKey, - lists: listGraphqlTypes, - provider, - getStorage: storage => configStorage?.[storage], - }) - - const isEnabledField = getIsEnabledField(f, listKey, intermediateList) - const fieldModes = { - create: f.ui?.createView?.fieldMode ?? list.ui?.createView?.defaultFieldMode ?? 'edit', - item: f.ui?.itemView?.fieldMode ?? list.ui?.itemView?.defaultFieldMode ?? 'edit', - list: f.ui?.listView?.fieldMode ?? list.ui?.listView?.defaultFieldMode ?? 'read', - } - - resultFields[fieldKey] = { - dbField: f.dbField as ResolvedDBField, - access: parseFieldAccessControl(f.access), - hooks: parseFieldHooks(fieldKey, f.hooks ?? {}), - graphql: { - 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, - }, - }, - ui: { - label: f.label ?? null, - description: f.ui?.description ?? null, - views: f.ui?.views ?? null, - createView: { - fieldMode: isEnabledField.create ? fieldModes.create : 'hidden', - }, - - itemView: { - fieldPosition: f.ui?.itemView?.fieldPosition ?? 'form', - fieldMode: isEnabledField.update - ? fieldModes.item - : isEnabledField.read && fieldModes.item !== 'hidden' - ? 'read' - : 'hidden', - }, - - listView: { - fieldMode: isEnabledField.read ? fieldModes.list : 'hidden', - }, - }, - - // copy - __ksTelemetryFieldTypeName: f.__ksTelemetryFieldTypeName, - extraOutputFields: f.extraOutputFields, - getAdminMeta: f.getAdminMeta, - input: { ...f.input }, - output: { ...f.output }, - unreferencedConcreteInterfaceImplementations: - f.unreferencedConcreteInterfaceImplementations, - views: f.views, - } - } - - // Default the labelField to `name`, `label`, or `title` if they exist; otherwise fall back to `id` - const labelField = - list.ui?.labelField ?? - (list.fields.label - ? 'label' - : list.fields.name - ? 'name' - : list.fields.title - ? 'title' - : 'id') - - const searchFields = new Set(list.ui?.searchFields ?? []) - if (searchFields.has('id')) { - throw new Error(`${listKey}.ui.searchFields cannot include 'id'`) - } - - const names = getNamesFromList(listKey, list) - - result[listKey] = { - access: parseListAccessControl(list.access), - - fields: resultFields, - groups, - + const { storage: configStorage, lists: listsConfig, db: { provider } } = config + const intermediateLists = Object.fromEntries(Object.values(config.lists).map((listConfig) => [ + listConfig.listKey, + { graphql: { - types: listGraphqlTypes[listKey].types, - names: names.graphql.names, - namePlural: names.graphql.namePlural, // TODO: remove - ...intermediateList.graphql, - }, - - prisma: { - listKey: listKey[0].toLowerCase() + listKey.slice(1), - mapping: list.db?.map, - extendPrismaSchema: list.db?.extendPrismaSchema, - }, - - ui: { - labels: names.ui.labels, - labelField, - searchFields, - searchableFields: new Map(), - }, - hooks: parseListHooks(list.hooks ?? {}), - listKey, - cacheHint: (() => { - const cacheHint = list.graphql?.cacheHint - if (cacheHint === undefined) { - return undefined - } - return typeof cacheHint === 'function' ? cacheHint : () => cacheHint - })(), - isSingleton: list.isSingleton ?? false, - } - } - - return result -} - -function introspectGraphQLTypes (lists: Record) { - for (const [listKey, list] of Object.entries(lists)) { - const { - ui: { searchFields, searchableFields }, - } = list - - if (searchFields.has('id')) { - throw new Error( - `The ui.searchFields option on the ${listKey} list includes 'id'. Lists can always be searched by an item's id so it must not be specified as a search field` - ) - } - - const whereInputFields = list.graphql.types.where.graphQLType.getFields() - for (const fieldKey of Object.keys(list.fields)) { - const filterType = whereInputFields[fieldKey]?.type - const fieldFilterFields = isInputObjectType(filterType) ? filterType.getFields() : undefined - if (fieldFilterFields?.contains?.type === GraphQLString) { - searchableFields.set( - fieldKey, - fieldFilterFields?.mode?.type === QueryMode.graphQLType ? 'insensitive' : 'default' - ) - } - } - - if (searchFields.size === 0) { - if (searchableFields.has(list.ui.labelField)) { - searchFields.add(list.ui.labelField) + isEnabled: getIsEnabled(listConfig.listKey, listConfig) } - } - } -} - -function stripDefaultValue (thing: graphql.Arg) { - return graphql.arg({ - ...thing, - defaultValue: undefined, - }) -} - -function graphqlArgForInputField (field: InitialisedField, operation: 'create' | 'update') { - const input = field.input?.[operation] - if (!input?.arg || !field.graphql.isEnabled[operation]) return - if (!field.graphql.isNonNull[operation]) return stripDefaultValue(input.arg) - if (input.arg.type.kind === 'non-null') return - - return graphql.arg({ - ...input.arg, - type: graphql.nonNull(input.arg.type), - }) -} - -function graphqlForOutputField (field: InitialisedField) { - const output = field.output - if (!output || !field.graphql.isEnabled.read) return output - if (!field.graphql.isNonNull.read) return output - if (output.type.kind === 'non-null') return output - - return graphql.field({ - ...(output as any), - type: graphql.nonNull(output.type), - }) -} + }, + ])) -function getListGraphqlTypes ( - listsConfig: __ResolvedKeystoneConfig['lists'], - lists: Record, - intermediateLists: Record -): Record { - const graphQLTypes: Record = {} + const listGraphqlTypes: Record = {} - for (const [listKey, listConfig] of Object.entries(listsConfig)) { + for (const listConfig of Object.values(listsConfig)) { + const { listKey } = listConfig const { graphql: { names }, - } = getNamesFromList(listKey, listConfig) + } = __getNames(listKey, listConfig) const output = graphql.object()({ name: names.outputTypeName, fields: () => { - const { fields } = lists[listKey] + const { fields } = listsRef[listKey] return { ...Object.fromEntries( Object.entries(fields).flatMap(([fieldPath, field]) => { if ( !field.output || !field.graphql.isEnabled.read || - (field.dbField.kind === 'relation' && - !intermediateLists[field.dbField.list].graphql.isEnabled.query) + (field.dbField.kind === 'relation' && !intermediateLists[field.dbField.list].graphql.isEnabled.query) ) { return [] } @@ -610,7 +407,7 @@ function getListGraphqlTypes ( field.access.read, listKey, fieldPath, - lists + listsRef ), ] }) @@ -623,7 +420,7 @@ function getListGraphqlTypes ( const uniqueWhere = graphql.inputObject({ name: names.whereUniqueInputName, fields: () => { - const { fields } = lists[listKey] + const { fields } = listsRef[listKey] return { ...Object.fromEntries( Object.entries(fields).flatMap(([key, field]) => { @@ -647,7 +444,7 @@ function getListGraphqlTypes ( const where: GraphQLTypesForList['where'] = graphql.inputObject({ name: names.whereInputName, fields: () => { - const { fields } = lists[listKey] + const { fields } = listsRef[listKey] return Object.assign( { AND: graphql.arg({ type: graphql.list(graphql.nonNull(where)) }), @@ -667,7 +464,7 @@ function getListGraphqlTypes ( const create = graphql.inputObject({ name: names.createInputName, fields: () => { - const { fields } = lists[listKey] + const { fields } = listsRef[listKey] const ret: Record> = {} for (const key in fields) { @@ -683,7 +480,7 @@ function getListGraphqlTypes ( const update = graphql.inputObject({ name: names.updateInputName, fields: () => { - const { fields } = lists[listKey] + const { fields } = listsRef[listKey] const ret: Record> = {} for (const key in fields) { @@ -699,7 +496,7 @@ function getListGraphqlTypes ( const orderBy = graphql.inputObject({ name: names.listOrderName, fields: () => { - const { fields } = lists[listKey] + const { fields } = listsRef[listKey] return Object.fromEntries( Object.entries(fields).flatMap(([key, field]) => { if ( @@ -719,7 +516,7 @@ function getListGraphqlTypes ( if (listConfig.graphql?.maxTake !== undefined) { take = graphql.arg({ type: graphql.nonNull(graphql.Int), - // warning: this is used by queries/resolvers.ts to enforce the limit + // WARNING: used by queries/resolvers.ts to enforce the limit defaultValue: listConfig.graphql.maxTake, }) } @@ -734,68 +531,79 @@ function getListGraphqlTypes ( defaultValue: [], }), take, - skip: graphql.arg({ type: graphql.nonNull(graphql.Int), defaultValue: 0 }), + skip: graphql.arg({ + type: graphql.nonNull(graphql.Int), + defaultValue: 0 + }), cursor: graphql.arg({ type: uniqueWhere }), } - const isEnabled = intermediateLists[listKey].graphql.isEnabled - let relateToManyForCreate, relateToManyForUpdate, relateToOneForCreate, relateToOneForUpdate - if (isEnabled.type) { - relateToManyForCreate = graphql.inputObject({ - name: names.relateToManyForCreateInputName, - fields: () => { - return { - // Create via a relationship is only supported if this list allows create - ...(isEnabled.create && { - create: graphql.arg({ type: graphql.list(graphql.nonNull(create)) }), + const relateToManyForCreate = graphql.inputObject({ + name: names.relateToManyForCreateInputName, + fields: () => { + const listRef = listsRef[listKey] + return { + ...(listRef.graphql.isEnabled.create && { + create: graphql.arg({ + type: graphql.list(graphql.nonNull(listRef.graphql.types.create)) }), - connect: graphql.arg({ type: graphql.list(graphql.nonNull(uniqueWhere)) }), - } - }, - }) + }), + connect: graphql.arg({ + type: graphql.list(graphql.nonNull(listRef.graphql.types.uniqueWhere)) + }), + } + }, + }) - relateToManyForUpdate = graphql.inputObject({ - name: names.relateToManyForUpdateInputName, - fields: () => { - return { - // The order of these fields reflects the order in which they are applied - // in the mutation. - disconnect: graphql.arg({ type: graphql.list(graphql.nonNull(uniqueWhere)) }), - set: graphql.arg({ type: graphql.list(graphql.nonNull(uniqueWhere)) }), - // Create via a relationship is only supported if this list allows create - ...(isEnabled.create && { - create: graphql.arg({ type: graphql.list(graphql.nonNull(create)) }), - }), - connect: graphql.arg({ type: graphql.list(graphql.nonNull(uniqueWhere)) }), - } - }, - }) + const relateToManyForUpdate = graphql.inputObject({ + name: names.relateToManyForUpdateInputName, + fields: () => { + const listRef = listsRef[listKey] + return { + // WARNING: the order of these fields reflects the order of mutations + disconnect: graphql.arg({ + type: graphql.list(graphql.nonNull(listRef.graphql.types.uniqueWhere)) + }), + set: graphql.arg({ + type: graphql.list(graphql.nonNull(listRef.graphql.types.uniqueWhere)) + }), + ...(listRef.graphql.isEnabled.create && { + create: graphql.arg({ type: graphql.list(graphql.nonNull(listRef.graphql.types.create)) }), + }), + connect: graphql.arg({ type: graphql.list(graphql.nonNull(listRef.graphql.types.uniqueWhere)) }), + } + }, + }) - relateToOneForCreate = graphql.inputObject({ - name: names.relateToOneForCreateInputName, - fields: () => { - return { - // Create via a relationship is only supported if this list allows create - ...(isEnabled.create && { create: graphql.arg({ type: create }) }), - connect: graphql.arg({ type: uniqueWhere }), - } - }, - }) + const relateToOneForCreate = graphql.inputObject({ + name: names.relateToOneForCreateInputName, + fields: () => { + const listRef = listsRef[listKey] + return { + ...(listRef.graphql.isEnabled.create && { + create: graphql.arg({ type: listRef.graphql.types.create }) + }), + connect: graphql.arg({ type: listRef.graphql.types.uniqueWhere }), + } + }, + }) - relateToOneForUpdate = graphql.inputObject({ - name: names.relateToOneForUpdateInputName, - fields: () => { - return { - // Create via a relationship is only supported if this list allows create - ...(isEnabled.create && { create: graphql.arg({ type: create }) }), - connect: graphql.arg({ type: uniqueWhere }), - disconnect: graphql.arg({ type: graphql.Boolean }), - } - }, - }) - } + const relateToOneForUpdate = graphql.inputObject({ + name: names.relateToOneForUpdateInputName, + fields: () => { + const listRef = listsRef[listKey] + return { + ...(listRef.graphql.isEnabled.create && { + create: graphql.arg({ type: listRef.graphql.types.create }) + }), + connect: graphql.arg({ type: listRef.graphql.types.uniqueWhere }), + disconnect: graphql.arg({ type: graphql.Boolean }), + } + }, + }) - graphQLTypes[listKey] = { + const hasType = intermediateLists[listKey].graphql.isEnabled.type + listGraphqlTypes[listKey] = { types: { output, uniqueWhere, @@ -805,6 +613,10 @@ function getListGraphqlTypes ( update, findManyArgs, relateTo: { + one: { + create: hasType ? relateToOneForCreate : undefined, + update: hasType ? relateToOneForUpdate : undefined, + }, many: { where: graphql.inputObject({ name: `${listKey}ManyRelationFilter`, @@ -814,81 +626,256 @@ function getListGraphqlTypes ( none: graphql.arg({ type: where }), }, }), - create: relateToManyForCreate, - update: relateToManyForUpdate, + create: hasType ? relateToManyForCreate : undefined, + update: hasType ? relateToManyForUpdate : undefined, }, - one: { create: relateToOneForCreate, update: relateToOneForUpdate }, }, }, } } - return graphQLTypes -} + const result: Record = {} -/** - * 1. Get the `isEnabled` config object from the listConfig - the returned object will be modified later - * 2. Instantiate `lists` object - it is done here as the object will be added to the listGraphqlTypes - * 3. Get graphqlTypes - * 4. Initialise fields - field functions are called - * 5. Handle relationships - ensure correct linking between two sides of all relationships (including one-sided relationships) - * 6. - */ -export function initialiseLists (config: __ResolvedKeystoneConfig): Record { - const listsConfig = config.lists + for (const listConfig of Object.values(listsConfig)) { + const { listKey } = listConfig + const intermediateList = intermediateLists[listKey] + const resultFields: Record = {} + const groups = [] + const fieldKeys = Object.keys(listConfig.fields) - let intermediateLists - intermediateLists = Object.fromEntries( - Object.entries(listsConfig).map(([key, listConfig]) => [ - key, - { - graphql: { - isEnabled: getIsEnabled(key, listConfig) + for (const [idx, [fieldKey, fieldFunc]] of Object.entries(listConfig.fields).entries()) { + if (fieldKey.startsWith('__group')) { + const group = fieldFunc as any + if ( + typeof group === 'object' && + group !== null && + typeof group.label === 'string' && + (group.description === null || typeof group.description === 'string') && + Array.isArray(group.fields) && + areArraysEqual(group.fields, fieldKeys.slice(idx + 1, idx + 1 + group.fields.length)) + ) { + groups.push(group) + continue } - }, - ]) - ) - - /** - * Lists is instantiated here so that it can be passed into the `getListGraphqlTypes` function - * This function binds the listsRef object to the various graphql functions - * - * The object will be populated at the end of this function, and the reference will be maintained - */ - const listsRef: Record = {} + throw new Error(`unexpected value for a group at ${listKey}.${fieldKey}`) + } - { - const listGraphqlTypes = getListGraphqlTypes(listsConfig, listsRef, intermediateLists) - intermediateLists = getListsWithInitialisedFields(config, listGraphqlTypes, intermediateLists) - } + if (typeof fieldFunc !== 'function') { + throw new Error(`The field at ${listKey}.${fieldKey} does not provide a function`) + } - { - const resolvedDBFieldsForLists = resolveRelationships(intermediateLists) - intermediateLists = Object.fromEntries( - Object.entries(intermediateLists).map(([listKey, list]) => [ + const f = fieldFunc({ + fieldKey, listKey, - { - ...list, - resolvedDbFields: resolvedDBFieldsForLists[listKey], + lists: listGraphqlTypes, + provider, + getStorage: storage => configStorage?.[storage], + }) + + const isEnabledField = getIsEnabledField(f, listKey, intermediateList) + const fieldModes = { + create: f.ui?.createView?.fieldMode ?? listConfig.ui?.createView?.defaultFieldMode ?? 'edit', + item: f.ui?.itemView?.fieldMode ?? listConfig.ui?.itemView?.defaultFieldMode ?? 'edit', + list: f.ui?.listView?.fieldMode ?? listConfig.ui?.listView?.defaultFieldMode ?? 'read', + } + + resultFields[fieldKey] = { + fieldKey, + + dbField: f.dbField as ResolvedDBField, + access: parseFieldAccessControl(f.access), + hooks: parseFieldHooks(fieldKey, f.hooks ?? {}), + graphql: { + 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, + }, }, - ]) - ) + ui: { + label: f.label ?? null, + description: f.ui?.description ?? null, + views: f.ui?.views ?? null, + createView: { + fieldMode: isEnabledField.create ? fieldModes.create : 'hidden', + }, + + itemView: { + fieldPosition: f.ui?.itemView?.fieldPosition ?? 'form', + fieldMode: isEnabledField.update + ? fieldModes.item + : isEnabledField.read && fieldModes.item !== 'hidden' + ? 'read' + : 'hidden', + }, + + listView: { + fieldMode: isEnabledField.read ? fieldModes.list : 'hidden', + }, + }, + + // copy + __ksTelemetryFieldTypeName: f.__ksTelemetryFieldTypeName, + extraOutputFields: f.extraOutputFields, + getAdminMeta: f.getAdminMeta, + input: { ...f.input }, + output: { ...f.output }, + unreferencedConcreteInterfaceImplementations: f.unreferencedConcreteInterfaceImplementations, + views: f.views, + } + } + + // Default the labelField to `name`, `label`, or `title` if they exist; otherwise fall back to `id` + const labelField = + listConfig.ui?.labelField ?? + (listConfig.fields.label + ? 'label' + : listConfig.fields.name + ? 'name' + : listConfig.fields.title + ? 'title' + : 'id') + + const searchFields = new Set(listConfig.ui?.searchFields ?? []) + if (searchFields.has('id')) { + throw new Error(`${listKey}.ui.searchFields cannot include 'id'`) + } + + const names = __getNames(listKey, listConfig) + result[listKey] = { + access: parseListAccessControl(listConfig.access), + + fields: resultFields, + groups, + + graphql: { + types: listGraphqlTypes[listKey].types, + names: names.graphql.names, + namePlural: names.graphql.namePlural, // TODO: remove + ...intermediateList.graphql, + }, + + prisma: { + listKey: listKey[0].toLowerCase() + listKey.slice(1), + mapping: listConfig.db?.map, + extendPrismaSchema: listConfig.db?.extendPrismaSchema, + }, + + ui: { + labels: names.ui.labels, + labelField, + searchFields, + searchableFields: new Map(), + }, + hooks: parseListHooks(listConfig.hooks ?? {}), + listKey, + cacheHint: (() => { + const cacheHint = listConfig.graphql?.cacheHint + if (typeof cacheHint === 'function') return cacheHint + if (cacheHint !== undefined) return () => cacheHint + return undefined + })(), + isSingleton: listConfig.isSingleton ?? false, + } } - intermediateLists = Object.fromEntries( - Object.entries(intermediateLists).map(([listKey, list]) => { - const fields: Record = {} + return result +} - for (const [fieldKey, field] of Object.entries(list.fields)) { - fields[fieldKey] = { - ...field, - dbField: list.resolvedDbFields[fieldKey], - } +function introspectGraphQLTypes (lists: Record) { + for (const list of Object.values(lists)) { + const { + listKey, + ui: { searchFields, searchableFields }, + } = list + + if (searchFields.has('id')) { + throw new Error(`The ui.searchFields option on the ${listKey} list includes 'id'. Lists can always be searched by an item's id so it must not be specified as a search field`) + } + + const whereInputFields = list.graphql.types.where.graphQLType.getFields() + for (const fieldKey of Object.keys(list.fields)) { + const filterType = whereInputFields[fieldKey]?.type + const fieldFilterFields = isInputObjectType(filterType) ? filterType.getFields() : undefined + if (fieldFilterFields?.contains?.type === GraphQLString) { + searchableFields.set( + fieldKey, + fieldFilterFields?.mode?.type === QueryMode.graphQLType ? 'insensitive' : 'default' + ) + } + } + + if (searchFields.size === 0) { + if (searchableFields.has(list.ui.labelField)) { + searchFields.add(list.ui.labelField) } + } + } +} - return [listKey, { ...list, fields }] - }) - ) +function stripDefaultValue (thing: graphql.Arg) { + return graphql.arg({ + ...thing, + defaultValue: undefined, + }) +} + +function graphqlArgForInputField (field: InitialisedField, operation: 'create' | 'update') { + const input = field.input?.[operation] + if (!input?.arg || !field.graphql.isEnabled[operation]) return + if (!field.graphql.isNonNull[operation]) return stripDefaultValue(input.arg) + if (input.arg.type.kind === 'non-null') return + + return graphql.arg({ + ...input.arg, + type: graphql.nonNull(input.arg.type), + }) +} + +function graphqlForOutputField (field: InitialisedField) { + const output = field.output + if (!output || !field.graphql.isEnabled.read) return output + if (!field.graphql.isNonNull.read) return output + if (output.type.kind === 'non-null') return output + + return graphql.field({ + ...(output as any), + type: graphql.nonNull(output.type), + }) +} + +export function initialiseLists (config: __ResolvedKeystoneConfig): Record { + const listsRef: Record = {} + let intermediateLists + + // step 1 + intermediateLists = getListsWithInitialisedFields(config, listsRef) + + // step 2 + const resolvedDBFieldsForLists = resolveRelationships(intermediateLists) + intermediateLists = Object.fromEntries(Object.values(intermediateLists).map((list) => [ + list.listKey, + { + ...list, + resolvedDbFields: resolvedDBFieldsForLists[list.listKey], + }, + ])) + + // step 3 + intermediateLists = Object.fromEntries(Object.values(intermediateLists).map((list) => { + const fields: Record = {} + + for (const [fieldKey, field] of Object.entries(list.fields)) { + fields[fieldKey] = { + ...field, + dbField: list.resolvedDbFields[fieldKey], + } + } + + return [list.listKey, { ...list, fields }] + })) for (const list of Object.values(intermediateLists)) { let hasAnEnabledCreateField = false @@ -914,19 +901,19 @@ export function initialiseLists (config: __ResolvedKeystoneConfig): Record }, + inputData: Record, list: InitialisedList, context: KeystoneContext ) { @@ -78,7 +78,7 @@ async function createSingle ( context, 'create', list, - rawData, + inputData, undefined, ) @@ -86,14 +86,14 @@ async function createSingle ( context, 'create', list, - rawData, + inputData, undefined, ) const { afterOperation, data } = await resolveInputForCreateOrUpdate( list, context, - rawData, + inputData, undefined ) @@ -116,7 +116,7 @@ export class NestedMutationState { const operationAccess = await getOperationAccess(list, context, 'create') if (!operationAccess) throw accessDeniedError(cannotForItem('create', list)) - const { item, afterOperation } = await createSingle({ data }, list, context) + const { item, afterOperation } = await createSingle(data, list, context) this.#afterOperations.push(() => afterOperation(item)) return { id: item.id as IdType } @@ -127,8 +127,10 @@ export class NestedMutationState { } } +type InputData = Record | null + export async function createOne ( - createInput: { data: Record }, + inputData: InputData, list: InitialisedList, context: KeystoneContext ) { @@ -136,7 +138,7 @@ export async function createOne ( if (!operationAccess) throw accessDeniedError(cannotForItem('create', list)) // operation - const { item, afterOperation } = await createSingle(createInput, list, context) + const { item, afterOperation } = await createSingle(inputData ?? {}, list, context) // after operation await afterOperation(item) @@ -145,18 +147,18 @@ export async function createOne ( } export async function createMany ( - createInputs: { data: Record[] }, + inputDatas: InputData[], list: InitialisedList, context: KeystoneContext ) { const operationAccess = await getOperationAccess(list, context, 'create') - return createInputs.data.map(async data => { + return inputDatas.map(async inputData => { // throw for each attempt if (!operationAccess) throw accessDeniedError(cannotForItem('create', list)) // operation - const { item, afterOperation } = await createSingle({ data }, list, context) + const { item, afterOperation } = await createSingle(inputData ?? {}, list, context) // after operation await afterOperation(item) @@ -167,19 +169,20 @@ export async function createMany ( type UpdateInput = { where: UniqueInputFilter - data: Record + data: InputData } async function updateSingle ( - updateInput: UpdateInput, + { + where, + data: inputData + }: UpdateInput, list: InitialisedList, context: KeystoneContext, accessFilters: boolean | InputFilter ) { - const { where: uniqueInput, data: rawData } = updateInput - // validate and resolve the input filter - const uniqueWhere = await resolveUniqueWhereInput(uniqueInput, list, context) + const uniqueWhere = await resolveUniqueWhereInput(where, list, context) // check filter access const fieldKey = Object.keys(uniqueWhere)[0] @@ -193,7 +196,7 @@ async function updateSingle ( context, 'update', list, - updateInput.data, + inputData ?? {}, item, ) @@ -201,14 +204,14 @@ async function updateSingle ( context, 'update', list, - updateInput.data, + inputData ?? {}, item, ) const { afterOperation, data } = await resolveInputForCreateOrUpdate( list, context, - rawData, + inputData ?? {}, item ) @@ -257,13 +260,13 @@ export async function updateMany ( } async function deleteSingle ( - uniqueInput: UniqueInputFilter, + where: UniqueInputFilter, list: InitialisedList, context: KeystoneContext, accessFilters: boolean | InputFilter ) { // validate and resolve the input filter - const uniqueWhere = await resolveUniqueWhereInput(uniqueInput, list, context) + const uniqueWhere = await resolveUniqueWhereInput(where, list, context) // check filter access const fieldKey = Object.keys(uniqueWhere)[0] @@ -310,7 +313,7 @@ async function deleteSingle ( } export async function deleteOne ( - deleteInput: UniqueInputFilter, + where: UniqueInputFilter, list: InitialisedList, context: KeystoneContext ) { @@ -320,11 +323,11 @@ export async function deleteOne ( // get list-level access control filters const accessFilters = await getAccessFilters(list, context, 'delete') - return deleteSingle(deleteInput, list, context, accessFilters) + return deleteSingle(where, list, context, accessFilters) } export async function deleteMany ( - deleteManyInput: UniqueInputFilter[], + wheres: UniqueInputFilter[], list: InitialisedList, context: KeystoneContext ) { @@ -333,11 +336,11 @@ export async function deleteMany ( // get list-level access control filters const accessFilters = await getAccessFilters(list, context, 'delete') - return deleteManyInput.map(async deleteInput => { + return wheres.map(async where => { // throw for each attempt if (!operationAccess) throw accessDeniedError(cannotForItem('delete', list)) - return deleteSingle(deleteInput, list, context, accessFilters) + return deleteSingle(where, list, context, accessFilters) }) } @@ -612,7 +615,7 @@ export function getMutationsForList (list: InitialisedList) { data: graphql.arg({ type: graphql.nonNull(list.graphql.types.create) }), }, resolve (_rootVal, { data }, context) { - return createOne({ data }, list, context) + return createOne(data, list, context) }, }) @@ -623,10 +626,8 @@ export function getMutationsForList (list: InitialisedList) { type: graphql.nonNull(graphql.list(graphql.nonNull(list.graphql.types.create))), }), }, - async resolve (_rootVal, args, context) { - return promisesButSettledWhenAllSettledAndInOrder( - await createMany(args, list, context) - ) + async resolve (_rootVal, { data }, context) { + return promisesButSettledWhenAllSettledAndInOrder(await createMany(data, list, context)) }, }) @@ -639,8 +640,8 @@ export function getMutationsForList (list: InitialisedList) { }), data: graphql.arg({ type: graphql.nonNull(list.graphql.types.update) }), }, - resolve (_rootVal, args, context) { - return updateOne(args, list, context) + resolve (_rootVal, { where, data }, context) { + return updateOne({ where, data }, list, context) }, }) diff --git a/packages/core/src/lib/core/utils.ts b/packages/core/src/lib/core/utils.ts index 0dddcb28dbf..993f64e443a 100644 --- a/packages/core/src/lib/core/utils.ts +++ b/packages/core/src/lib/core/utils.ts @@ -1,8 +1,3 @@ -import pluralize from 'pluralize' -import { type KeystoneConfig } from '../../types' -import { getGqlNames } from '../../types/utils' -import { humanize } from '../utils' - // this is wrong // all the things should be generic over the id type // i don't want to deal with that right now though @@ -33,47 +28,6 @@ export async function promiseAllRejectWithAllErrors ( return results.map((x: any) => x.value) as any } -export function getNamesFromList ( - listKey: string, - { graphql, ui, isSingleton }: KeystoneConfig['lists'][string] -) { - if (ui?.path !== undefined && !/^[a-z-_][a-z0-9-_]*$/.test(ui.path)) { - throw new Error( - `ui.path for ${listKey} is ${ui.path} but it must only contain lowercase letters, numbers, dashes, and underscores and not start with a number` - ) - } - - const computedSingular = humanize(listKey) - const computedPlural = pluralize.plural(computedSingular) - const computedLabel = isSingleton ? computedSingular : computedPlural - const path = ui?.path || labelToPath(computedLabel) - - const pluralGraphQLName = graphql?.plural || labelToClass(computedPlural) - if (pluralGraphQLName === listKey) { - throw new Error( - `The list key and the plural name used in GraphQL must be different but the list key ${listKey} is the same as the plural GraphQL name, please specify graphql.plural` - ) - } - - return { - graphql: { - names: getGqlNames({ listKey, pluralGraphQLName }), - namePlural: pluralGraphQLName, - }, - ui: { - labels: { - label: ui?.label || computedLabel, - singular: ui?.singular || computedSingular, - plural: ui?.plural || computedPlural, - path, - }, - }, - } -} - -const labelToPath = (str: string) => str.split(' ').join('-').toLowerCase() -const labelToClass = (str: string) => str.replace(/\s+/g, '') - export function getDBFieldKeyForFieldOnMultiField (fieldKey: string, subField: string) { return `${fieldKey}_${subField}` } diff --git a/packages/core/src/lib/create-admin-meta.ts b/packages/core/src/lib/create-admin-meta.ts index 747d7f753f6..7785a90c537 100644 --- a/packages/core/src/lib/create-admin-meta.ts +++ b/packages/core/src/lib/create-admin-meta.ts @@ -1,17 +1,20 @@ -import path from 'path' -import type { - BaseListTypeInfo, - JSONValue, - KeystoneContext, - MaybeItemFunction, - MaybePromise, - MaybeSessionFunction, - __ResolvedKeystoneConfig, +import path from 'node:path' +import { + type BaseListTypeInfo, + type JSONValue, + type KeystoneContext, + type MaybeItemFunction, + type MaybePromise, + type MaybeSessionFunction, + type __ResolvedKeystoneConfig, } from '../types' -import type { FilterOrderArgs } from '../types/config/fields' +import { + type GraphQLNames +} from '../types/utils' +import { type FilterOrderArgs } from '../types/config/fields' import { humanize } from './utils' -import type { InitialisedList } from './core/initialise-lists' +import { type InitialisedList } from './core/initialise-lists' type ContextFunction = (context: KeystoneContext) => MaybePromise @@ -60,7 +63,7 @@ export type ListMetaRootVal = { fields: FieldMetaRootVal[] fieldsByKey: Record groups: Array - + graphql: { names: GraphQLNames } pageSize: number initialColumns: string[] initialSort: { field: string, direction: 'ASC' | 'DESC' } | null @@ -140,6 +143,9 @@ export function createAdminMeta ( fields: [], fieldsByKey: {}, groups: [], + graphql: { + names: list.graphql.names, + }, pageSize: maximumPageSize, initialColumns, diff --git a/packages/core/src/lib/createExpressServer.ts b/packages/core/src/lib/createExpressServer.ts index 00e14f1e776..a63af48780e 100644 --- a/packages/core/src/lib/createExpressServer.ts +++ b/packages/core/src/lib/createExpressServer.ts @@ -87,7 +87,6 @@ export async function createExpressServer ( formatError: formatError(config.graphql), includeStacktraceInErrorResponses: config.graphql.debug, ...apolloConfig, - schema: context.graphql.schema, plugins: config.graphql.playground === 'apollo' diff --git a/packages/core/src/lib/createGraphQLSchema.ts b/packages/core/src/lib/createGraphQLSchema.ts index 277d97b2239..c4938bd976f 100644 --- a/packages/core/src/lib/createGraphQLSchema.ts +++ b/packages/core/src/lib/createGraphQLSchema.ts @@ -4,7 +4,7 @@ import { graphql } from '../types/schema' import { type __ResolvedKeystoneConfig } from '../types' -import { KeystoneMeta } from './admin-meta-resolver' +import { KeystoneMeta } from './resolve-admin-meta' import type { AdminMetaRootVal } from './create-admin-meta' import type { InitialisedList } from './core/initialise-lists' @@ -75,9 +75,7 @@ function collectTypes ( field.unreferencedConcreteInterfaceImplementations ) { // this _IS_ actually necessary since they aren't implicitly referenced by other types, unlike the types above - collectedTypes.push( - ...field.unreferencedConcreteInterfaceImplementations.map(x => x.graphQLType) - ) + collectedTypes.push(...field.unreferencedConcreteInterfaceImplementations.map(x => x.graphQLType)) } } collectedTypes.push(list.graphql.types.where.graphQLType) diff --git a/packages/core/src/lib/createSystem.ts b/packages/core/src/lib/createSystem.ts index a557ffe4bff..78b039d8627 100644 --- a/packages/core/src/lib/createSystem.ts +++ b/packages/core/src/lib/createSystem.ts @@ -223,10 +223,7 @@ export function createSystem (config_: KeystoneConfig) { log: config.db.enableLogging }) - const prismaClient = config.db.extendPrismaClient( - injectNewDefaults(prePrismaClient, lists) - ) - + const prismaClient = config.db.extendPrismaClient(injectNewDefaults(prePrismaClient, lists)) const context = createContext({ config, lists, diff --git a/packages/core/src/lib/defaults.ts b/packages/core/src/lib/defaults.ts index ebba71ff481..9cdea00b6a3 100644 --- a/packages/core/src/lib/defaults.ts +++ b/packages/core/src/lib/defaults.ts @@ -22,11 +22,12 @@ function injectDefaults (config: KeystoneConfig, defaultIdField: IdFieldConfig) } } - const updated: KeystoneConfig['lists'] = {} + const updated: __ResolvedKeystoneConfig['lists'] = {} for (const [listKey, list] of Object.entries(config.lists)) { if (list.isSingleton) { updated[listKey] = { + listKey, ...list, fields: { id: idFieldType({ kind: 'number', type: 'Int' }), @@ -38,6 +39,7 @@ function injectDefaults (config: KeystoneConfig, defaultIdField: IdFieldConfig) } updated[listKey] = { + listKey, ...list, fields: { id: idFieldType(list.db?.idField ?? defaultIdField), diff --git a/packages/core/src/lib/admin-meta-resolver.ts b/packages/core/src/lib/resolve-admin-meta.ts similarity index 82% rename from packages/core/src/lib/admin-meta-resolver.ts rename to packages/core/src/lib/resolve-admin-meta.ts index 387275aa60b..02ce0fdc004 100644 --- a/packages/core/src/lib/admin-meta-resolver.ts +++ b/packages/core/src/lib/resolve-admin-meta.ts @@ -11,6 +11,9 @@ import { type KeystoneContext, type MaybePromise } from '../types' +import { + type GraphQLNames, +} from '../types/utils' import { QueryMode } from '../types' import { graphql as graphqlBoundToKeystoneContext } from '../types/schema' import { @@ -175,6 +178,47 @@ const KeystoneAdminUISort = graphql.object()({ + name: 'KeystoneAdminUIGraphQLNames', + fields: { + outputTypeName: graphql.field({ type: graphql.nonNull(graphql.String) }), + whereInputName: graphql.field({ type: graphql.nonNull(graphql.String) }), + whereUniqueInputName: graphql.field({ type: graphql.nonNull(graphql.String) }), + + // create + createInputName: graphql.field({ type: graphql.nonNull(graphql.String) }), + createMutationName: graphql.field({ type: graphql.nonNull(graphql.String) }), + createManyMutationName: graphql.field({ type: graphql.nonNull(graphql.String) }), + relateToOneForCreateInputName: graphql.field({ type: graphql.nonNull(graphql.String) }), + relateToManyForCreateInputName: graphql.field({ type: graphql.nonNull(graphql.String) }), + + // read + itemQueryName: graphql.field({ type: graphql.nonNull(graphql.String) }), + listOrderName: graphql.field({ type: graphql.nonNull(graphql.String) }), + listQueryCountName: graphql.field({ type: graphql.nonNull(graphql.String) }), + listQueryName: graphql.field({ type: graphql.nonNull(graphql.String) }), + + // update + updateInputName: graphql.field({ type: graphql.nonNull(graphql.String) }), + updateMutationName: graphql.field({ type: graphql.nonNull(graphql.String) }), + updateManyInputName: graphql.field({ type: graphql.nonNull(graphql.String) }), + updateManyMutationName: graphql.field({ type: graphql.nonNull(graphql.String) }), + relateToOneForUpdateInputName: graphql.field({ type: graphql.nonNull(graphql.String) }), + relateToManyForUpdateInputName: graphql.field({ type: graphql.nonNull(graphql.String) }), + + // delete + deleteMutationName: graphql.field({ type: graphql.nonNull(graphql.String) }), + deleteManyMutationName: graphql.field({ type: graphql.nonNull(graphql.String) }), + } +}) + +const KeystoneAdminUIGraphQL = graphql.object()({ + name: 'KeystoneAdminUIGraphQL', + fields: { + names: graphql.field({ type: graphql.nonNull(KeystoneAdminUIGraphQLNames) }), + } +}) + const KeystoneAdminUIListMeta = graphql.object()({ name: 'KeystoneAdminUIListMeta', fields: { @@ -199,6 +243,7 @@ const KeystoneAdminUIListMeta = graphql.object()({ groups: graphql.field({ type: graphql.nonNull(graphql.list(graphql.nonNull(KeystoneAdminUIFieldGroupMeta))), }), + graphql: graphql.field({ type: graphql.nonNull(KeystoneAdminUIGraphQL) }), initialSort: graphql.field({ type: KeystoneAdminUISort }), ...contextFunctionField('isHidden', graphql.Boolean), isSingleton: graphql.field({ type: graphql.nonNull(graphql.Boolean) }), diff --git a/packages/core/src/types/admin-meta.ts b/packages/core/src/types/admin-meta.ts index 8d893c980eb..170e0f72a09 100644 --- a/packages/core/src/types/admin-meta.ts +++ b/packages/core/src/types/admin-meta.ts @@ -111,11 +111,9 @@ export type ListMeta = { singular: string plural: string - /** @deprecated */ - gqlNames: InitialisedList['graphql']['names'] - fields: { [path: string]: FieldMeta } groups: FieldGroupMeta[] + gqlNames: InitialisedList['graphql']['names'] /** deprecated */ pageSize: number initialColumns: string[] diff --git a/packages/core/src/types/config/index.ts b/packages/core/src/types/config/index.ts index da6e03c2813..0e08f70241d 100644 --- a/packages/core/src/types/config/index.ts +++ b/packages/core/src/types/config/index.ts @@ -259,7 +259,11 @@ export type __ResolvedKeystoneConfig['graphql']> & { path: Exclude['graphql'], undefined> } - lists: KeystoneConfig['lists'] + lists: { + [listKey: string]: { + listKey: string + } & KeystoneConfig['lists'][string] + } server: Omit['server']>>, 'cors' | 'port'> & { cors: CorsOptions | null options: ListenOptions diff --git a/packages/core/src/types/next-fields.ts b/packages/core/src/types/next-fields.ts index fa3cadc1b8d..0fe004faf7e 100644 --- a/packages/core/src/types/next-fields.ts +++ b/packages/core/src/types/next-fields.ts @@ -252,9 +252,9 @@ type FieldInputResolver = ( relationshipInputResolver: RelationshipInputResolver ) => MaybePromise - + type DBFieldFiltersInner = Record - + type DBFieldFilters = | ({ AND?: DBFieldFiltersInner diff --git a/packages/core/src/types/utils.ts b/packages/core/src/types/utils.ts index 430cd38cfc6..9146abdad4f 100644 --- a/packages/core/src/types/utils.ts +++ b/packages/core/src/types/utils.ts @@ -1,3 +1,9 @@ +import pluralize from 'pluralize' +import { humanize } from '../lib/utils' +import { + type __ResolvedKeystoneConfig +} from '../types' + export type JSONValue = | string | number @@ -8,6 +14,9 @@ export type JSONValue = export type MaybePromise = T | Promise +// WARNING: may break in patch +export type GraphQLNames = ReturnType + export function getGqlNames ({ listKey, pluralGraphQLName, @@ -19,24 +28,68 @@ export function getGqlNames ({ const lowerSingularName = listKey.charAt(0).toLowerCase() + listKey.slice(1) return { outputTypeName: listKey, + whereInputName: `${listKey}WhereInput`, + whereUniqueInputName: `${listKey}WhereUniqueInput`, + + // create + createInputName: `${listKey}CreateInput`, + createMutationName: `create${listKey}`, + createManyMutationName: `create${pluralGraphQLName}`, + relateToOneForCreateInputName: `${listKey}RelateToOneForCreateInput`, + relateToManyForCreateInputName: `${listKey}RelateToManyForCreateInput`, + + // read itemQueryName: lowerSingularName, listQueryName: lowerPluralName, listQueryCountName: `${lowerPluralName}Count`, listOrderName: `${listKey}OrderByInput`, - deleteMutationName: `delete${listKey}`, - updateMutationName: `update${listKey}`, - createMutationName: `create${listKey}`, - deleteManyMutationName: `delete${pluralGraphQLName}`, - updateManyMutationName: `update${pluralGraphQLName}`, - createManyMutationName: `create${pluralGraphQLName}`, - whereInputName: `${listKey}WhereInput`, - whereUniqueInputName: `${listKey}WhereUniqueInput`, + + // update updateInputName: `${listKey}UpdateInput`, - createInputName: `${listKey}CreateInput`, + updateMutationName: `update${listKey}`, updateManyInputName: `${listKey}UpdateArgs`, - relateToManyForCreateInputName: `${listKey}RelateToManyForCreateInput`, - relateToManyForUpdateInputName: `${listKey}RelateToManyForUpdateInput`, - relateToOneForCreateInputName: `${listKey}RelateToOneForCreateInput`, + updateManyMutationName: `update${pluralGraphQLName}`, relateToOneForUpdateInputName: `${listKey}RelateToOneForUpdateInput`, + relateToManyForUpdateInputName: `${listKey}RelateToManyForUpdateInput`, + + // delete + deleteMutationName: `delete${listKey}`, + deleteManyMutationName: `delete${pluralGraphQLName}`, + } +} + +const labelToPath = (str: string) => str.split(' ').join('-').toLowerCase() +const labelToClass = (str: string) => str.replace(/\s+/g, '') + +// WARNING: may break in patch +export function __getNames (listKey: string, list: __ResolvedKeystoneConfig['lists'][string]) { + const { graphql, ui, isSingleton } = list + if (ui?.path !== undefined && !/^[a-z-_][a-z0-9-_]*$/.test(ui.path)) { + throw new Error(`ui.path for ${listKey} is ${ui.path} but it must only contain lowercase letters, numbers, dashes, and underscores and not start with a number`) + } + + const computedSingular = humanize(listKey) + const computedPlural = pluralize.plural(computedSingular) + const computedLabel = isSingleton ? computedSingular : computedPlural + const path = ui?.path || labelToPath(computedLabel) + + const pluralGraphQLName = graphql?.plural || labelToClass(computedPlural) + if (pluralGraphQLName === listKey) { + throw new Error(`The list key and the plural name used in GraphQL must be different but the list key ${listKey} is the same as the plural GraphQL name, please specify graphql.plural`) + } + + return { + graphql: { + names: getGqlNames({ listKey, pluralGraphQLName }), + namePlural: pluralGraphQLName, + }, + ui: { + labels: { + label: ui?.label || computedLabel, + singular: ui?.singular || computedSingular, + plural: ui?.plural || computedPlural, + path, + }, + }, } } diff --git a/tests/api-tests/admin-meta.test.ts b/tests/api-tests/admin-meta.test.ts index 806045ae4d9..c8eb1b3e96d 100644 --- a/tests/api-tests/admin-meta.test.ts +++ b/tests/api-tests/admin-meta.test.ts @@ -130,6 +130,30 @@ test( viewsIndex: 2, }, ], + graphql: { + names: { + createInputName: 'UserCreateInput', + createManyMutationName: 'createUsers', + createMutationName: 'createUser', + deleteManyMutationName: 'deleteUsers', + deleteMutationName: 'deleteUser', + itemQueryName: 'user', + listOrderName: 'UserOrderByInput', + listQueryCountName: 'usersCount', + listQueryName: 'users', + outputTypeName: 'User', + relateToManyForCreateInputName: 'UserRelateToManyForCreateInput', + relateToManyForUpdateInputName: 'UserRelateToManyForUpdateInput', + relateToOneForCreateInputName: 'UserRelateToOneForCreateInput', + relateToOneForUpdateInputName: 'UserRelateToOneForUpdateInput', + updateInputName: 'UserUpdateInput', + updateManyInputName: 'UserUpdateArgs', + updateManyMutationName: 'updateUsers', + updateMutationName: 'updateUser', + whereInputName: 'UserWhereInput', + whereUniqueInputName: 'UserWhereUniqueInput', + }, + }, groups: [], initialColumns: ['name', 'something'], initialSort: null, diff --git a/tests/cli-tests/fixtures/basic-project/schema.graphql b/tests/cli-tests/fixtures/basic-project/schema.graphql index 4d83de34c37..e8522762af5 100644 --- a/tests/cli-tests/fixtures/basic-project/schema.graphql +++ b/tests/cli-tests/fixtures/basic-project/schema.graphql @@ -126,6 +126,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -198,6 +199,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/tests/sandbox/schema.graphql b/tests/sandbox/schema.graphql index 6bf41715e93..a8db725b82f 100644 --- a/tests/sandbox/schema.graphql +++ b/tests/sandbox/schema.graphql @@ -696,6 +696,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -763,6 +764,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/tests/test-projects/basic/schema.graphql b/tests/test-projects/basic/schema.graphql index f15389a1b56..cd37f6ad695 100644 --- a/tests/test-projects/basic/schema.graphql +++ b/tests/test-projects/basic/schema.graphql @@ -303,6 +303,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -375,6 +376,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/tests/test-projects/crud-notifications/schema.graphql b/tests/test-projects/crud-notifications/schema.graphql index bfe08296c8c..29b110dadf9 100644 --- a/tests/test-projects/crud-notifications/schema.graphql +++ b/tests/test-projects/crud-notifications/schema.graphql @@ -254,6 +254,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -326,6 +327,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/tests/test-projects/live-reloading/schema.graphql b/tests/test-projects/live-reloading/schema.graphql index d8cee91c5ed..56db1ba889a 100644 --- a/tests/test-projects/live-reloading/schema.graphql +++ b/tests/test-projects/live-reloading/schema.graphql @@ -127,6 +127,7 @@ type KeystoneAdminUIListMeta { labelField: String! fields: [KeystoneAdminUIFieldMeta!]! groups: [KeystoneAdminUIFieldGroupMeta!]! + graphql: KeystoneAdminUIGraphQL! initialSort: KeystoneAdminUISort isHidden: Boolean! isSingleton: Boolean! @@ -199,6 +200,33 @@ type KeystoneAdminUIFieldGroupMeta { fields: [KeystoneAdminUIFieldMeta!]! } +type KeystoneAdminUIGraphQL { + names: KeystoneAdminUIGraphQLNames! +} + +type KeystoneAdminUIGraphQLNames { + outputTypeName: String! + whereInputName: String! + whereUniqueInputName: String! + createInputName: String! + createMutationName: String! + createManyMutationName: String! + relateToOneForCreateInputName: String! + relateToManyForCreateInputName: String! + itemQueryName: String! + listOrderName: String! + listQueryCountName: String! + listQueryName: String! + updateInputName: String! + updateMutationName: String! + updateManyInputName: String! + updateManyMutationName: String! + relateToOneForUpdateInputName: String! + relateToManyForUpdateInputName: String! + deleteMutationName: String! + deleteManyMutationName: String! +} + type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection!