From b696b0106da82f71833c2e3ef06c7677b8df54cb Mon Sep 17 00:00:00 2001 From: Daniel Cousens <413395+dcousens@users.noreply.github.com> Date: Wed, 31 Jul 2024 17:07:19 +1000 Subject: [PATCH 1/9] tidy up --- packages/auth/src/schema.ts | 15 ++--- packages/core/src/admin-ui/context.tsx | 54 ++++++++--------- .../core/src/admin-ui/utils/useAdminMeta.tsx | 32 +++++----- .../core/src/admin-ui/utils/useCreateItem.ts | 4 +- .../core/src/lib/core/initialise-lists.ts | 58 +++++++------------ packages/core/src/lib/createExpressServer.ts | 1 - packages/core/src/lib/createGraphQLSchema.ts | 4 +- packages/core/src/lib/createSystem.ts | 5 +- packages/core/src/types/next-fields.ts | 4 +- 9 files changed, 74 insertions(+), 103 deletions(-) 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/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..424f791b1f3 100644 --- a/packages/core/src/admin-ui/utils/useAdminMeta.tsx +++ b/packages/core/src/admin-ui/utils/useAdminMeta.tsx @@ -1,11 +1,17 @@ import { useEffect, useMemo, useState } from 'react' import hashString from '@emotion/hash' -import { type AdminMeta, type FieldViews, getGqlNames } from '../../types' +import { + type AdminMeta, + type FieldViews, + getGqlNames +} 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 +23,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 +59,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: {}, } 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/lib/core/initialise-lists.ts b/packages/core/src/lib/core/initialise-lists.ts index c8e91675393..33da7408801 100644 --- a/packages/core/src/lib/core/initialise-lists.ts +++ b/packages/core/src/lib/core/initialise-lists.ts @@ -34,7 +34,10 @@ import { parseFieldAccessControl, } from './access-control' import { areArraysEqual, getNamesFromList } from './utils' -import { type ResolvedDBField, resolveRelationships } from './resolve-relationships' +import { + type ResolvedDBField, + resolveRelationships +} from './resolve-relationships' import { outputTypeField } from './queries/output-field' import { assertFieldsValid } from './field-assertions' @@ -84,6 +87,8 @@ export type InitialisedField = { > export type InitialisedList = { + listKey: string + access: ResolvedListAccessControl fields: Record @@ -99,14 +104,11 @@ export type InitialisedList = { resolvedDbFields: Record lists: Record - cacheHint: ((args: CacheHintArgs) => CacheHint) | undefined - listKey: string - graphql: { types: GraphQLTypesForList names: ReturnType namePlural: string // TODO: remove - isEnabled: IsEnabled + isEnabled: IsListEnabled } prisma: { @@ -123,9 +125,10 @@ export type InitialisedList = { } isSingleton: boolean + cacheHint: ((args: CacheHintArgs) => CacheHint) | undefined } -type IsEnabled = { +type IsListEnabled = { type: boolean query: boolean create: boolean @@ -137,15 +140,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 +183,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 @@ -440,8 +440,7 @@ function getListsWithInitialisedFields ( getAdminMeta: f.getAdminMeta, input: { ...f.input }, output: { ...f.output }, - unreferencedConcreteInterfaceImplementations: - f.unreferencedConcreteInterfaceImplementations, + unreferencedConcreteInterfaceImplementations: f.unreferencedConcreteInterfaceImplementations, views: f.views, } } @@ -493,10 +492,9 @@ function getListsWithInitialisedFields ( listKey, cacheHint: (() => { const cacheHint = list.graphql?.cacheHint - if (cacheHint === undefined) { - return undefined - } - return typeof cacheHint === 'function' ? cacheHint : () => cacheHint + if (typeof cacheHint === 'function') return cacheHint + if (cacheHint !== undefined) return () => cacheHint + return undefined })(), isSingleton: list.isSingleton ?? false, } @@ -512,9 +510,7 @@ function introspectGraphQLTypes (lists: Record) { } = 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` - ) + 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() @@ -826,14 +822,6 @@ function getListGraphqlTypes ( return graphQLTypes } -/** - * 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 @@ -849,12 +837,6 @@ export function initialiseLists (config: __ResolvedKeystoneConfig): Record = {} { @@ -926,7 +908,7 @@ export function initialiseLists (config: __ResolvedKeystoneConfig): Record 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/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 From 6481e7a0be263fe5a80b38fb04f462584b742c4f Mon Sep 17 00:00:00 2001 From: Daniel Cousens <413395+dcousens@users.noreply.github.com> Date: Wed, 31 Jul 2024 16:27:35 +1000 Subject: [PATCH 2/9] add fieldKey to InitialisedField --- packages/core/src/lib/core/initialise-lists.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/core/src/lib/core/initialise-lists.ts b/packages/core/src/lib/core/initialise-lists.ts index 33da7408801..8cb57bff7ca 100644 --- a/packages/core/src/lib/core/initialise-lists.ts +++ b/packages/core/src/lib/core/initialise-lists.ts @@ -42,6 +42,8 @@ import { outputTypeField } from './queries/output-field' import { assertFieldsValid } from './field-assertions' export type InitialisedField = { + fieldKey: string + access: ResolvedFieldAccessControl dbField: ResolvedDBField hooks: ResolvedFieldHooks @@ -400,6 +402,8 @@ function getListsWithInitialisedFields ( } resultFields[fieldKey] = { + fieldKey, + dbField: f.dbField as ResolvedDBField, access: parseFieldAccessControl(f.access), hooks: parseFieldHooks(fieldKey, f.hooks ?? {}), From b3fcc4a42d34edb1bc526aba1ea65ac928e737f0 Mon Sep 17 00:00:00 2001 From: Daniel Cousens <413395+dcousens@users.noreply.github.com> Date: Thu, 1 Aug 2024 11:44:43 +1000 Subject: [PATCH 3/9] add listKey to __ResolvedKeystoneConfig.lists --- .../core/src/lib/core/initialise-lists.ts | 75 +++++++++---------- packages/core/src/lib/defaults.ts | 4 +- packages/core/src/types/config/index.ts | 6 +- 3 files changed, 45 insertions(+), 40 deletions(-) diff --git a/packages/core/src/lib/core/initialise-lists.ts b/packages/core/src/lib/core/initialise-lists.ts index 8cb57bff7ca..1b7a6b5268d 100644 --- a/packages/core/src/lib/core/initialise-lists.ts +++ b/packages/core/src/lib/core/initialise-lists.ts @@ -359,13 +359,14 @@ function getListsWithInitialisedFields ( ) { const result: Record = {} - for (const [listKey, list] of Object.entries(listsConfig)) { + for (const listConfig of Object.values(listsConfig)) { + const { listKey } = listConfig const intermediateList = intermediateLists[listKey] const resultFields: Record = {} const groups = [] - const fieldKeys = Object.keys(list.fields) + const fieldKeys = Object.keys(listConfig.fields) - for (const [idx, [fieldKey, fieldFunc]] of Object.entries(list.fields).entries()) { + for (const [idx, [fieldKey, fieldFunc]] of Object.entries(listConfig.fields).entries()) { if (fieldKey.startsWith('__group')) { const group = fieldFunc as any if ( @@ -396,9 +397,9 @@ function getListsWithInitialisedFields ( 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', + 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] = { @@ -451,24 +452,23 @@ function getListsWithInitialisedFields ( // Default the labelField to `name`, `label`, or `title` if they exist; otherwise fall back to `id` const labelField = - list.ui?.labelField ?? - (list.fields.label + listConfig.ui?.labelField ?? + (listConfig.fields.label ? 'label' - : list.fields.name + : listConfig.fields.name ? 'name' - : list.fields.title + : listConfig.fields.title ? 'title' : 'id') - const searchFields = new Set(list.ui?.searchFields ?? []) + const searchFields = new Set(listConfig.ui?.searchFields ?? []) if (searchFields.has('id')) { throw new Error(`${listKey}.ui.searchFields cannot include 'id'`) } - const names = getNamesFromList(listKey, list) - + const names = getNamesFromList(listKey, listConfig) result[listKey] = { - access: parseListAccessControl(list.access), + access: parseListAccessControl(listConfig.access), fields: resultFields, groups, @@ -482,8 +482,8 @@ function getListsWithInitialisedFields ( prisma: { listKey: listKey[0].toLowerCase() + listKey.slice(1), - mapping: list.db?.map, - extendPrismaSchema: list.db?.extendPrismaSchema, + mapping: listConfig.db?.map, + extendPrismaSchema: listConfig.db?.extendPrismaSchema, }, ui: { @@ -492,15 +492,15 @@ function getListsWithInitialisedFields ( searchFields, searchableFields: new Map(), }, - hooks: parseListHooks(list.hooks ?? {}), + hooks: parseListHooks(listConfig.hooks ?? {}), listKey, cacheHint: (() => { - const cacheHint = list.graphql?.cacheHint + const cacheHint = listConfig.graphql?.cacheHint if (typeof cacheHint === 'function') return cacheHint if (cacheHint !== undefined) return () => cacheHint return undefined })(), - isSingleton: list.isSingleton ?? false, + isSingleton: listConfig.isSingleton ?? false, } } @@ -508,8 +508,9 @@ function getListsWithInitialisedFields ( } function introspectGraphQLTypes (lists: Record) { - for (const [listKey, list] of Object.entries(lists)) { + for (const list of Object.values(lists)) { const { + listKey, ui: { searchFields, searchableFields }, } = list @@ -575,7 +576,8 @@ function getListGraphqlTypes ( ): Record { const graphQLTypes: 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) @@ -827,42 +829,39 @@ function getListGraphqlTypes ( } export function initialiseLists (config: __ResolvedKeystoneConfig): Record { - const listsConfig = config.lists - let intermediateLists intermediateLists = Object.fromEntries( - Object.entries(listsConfig).map(([key, listConfig]) => [ - key, + Object.values(config.lists).map((listConfig) => [ + listConfig.listKey, { graphql: { - isEnabled: getIsEnabled(key, listConfig) + isEnabled: getIsEnabled(listConfig.listKey, listConfig) } }, ]) ) const listsRef: Record = {} - { - const listGraphqlTypes = getListGraphqlTypes(listsConfig, listsRef, intermediateLists) + const listGraphqlTypes = getListGraphqlTypes(config.lists, listsRef, intermediateLists) intermediateLists = getListsWithInitialisedFields(config, listGraphqlTypes, intermediateLists) } { const resolvedDBFieldsForLists = resolveRelationships(intermediateLists) intermediateLists = Object.fromEntries( - Object.entries(intermediateLists).map(([listKey, list]) => [ - listKey, + Object.values(intermediateLists).map((list) => [ + list.listKey, { ...list, - resolvedDbFields: resolvedDBFieldsForLists[listKey], + resolvedDbFields: resolvedDBFieldsForLists[list.listKey], }, ]) ) } intermediateLists = Object.fromEntries( - Object.entries(intermediateLists).map(([listKey, list]) => { + Object.values(intermediateLists).map((list) => { const fields: Record = {} for (const [fieldKey, field] of Object.entries(list.fields)) { @@ -872,7 +871,7 @@ export function initialiseLists (config: __ResolvedKeystoneConfig): Record['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 From dc9a8bbeac8a1fb0a621260010febdacdf35221f Mon Sep 17 00:00:00 2001 From: Daniel Cousens <413395+dcousens@users.noreply.github.com> Date: Wed, 31 Jul 2024 15:05:53 +1000 Subject: [PATCH 4/9] move getNamesFromList to types/utils, rename to __getNames --- examples/assets-local/schema.graphql | 28 +++++++ examples/assets-s3/schema.graphql | 28 +++++++ examples/auth/schema.graphql | 28 +++++++ examples/cloudinary/schema.graphql | 28 +++++++ examples/custom-admin-ui-logo/schema.graphql | 28 +++++++ .../custom-admin-ui-navigation/schema.graphql | 28 +++++++ examples/custom-admin-ui-pages/schema.graphql | 28 +++++++ examples/custom-field-view/schema.graphql | 28 +++++++ examples/custom-field/schema.graphql | 28 +++++++ examples/custom-id/schema.graphql | 28 +++++++ .../custom-output-paths/my-graphql.graphql | 28 +++++++ .../schema.graphql | 28 +++++++ examples/custom-session-jwt/schema.graphql | 28 +++++++ .../custom-session-next-auth/schema.graphql | 28 +++++++ .../custom-session-passport/schema.graphql | 28 +++++++ examples/custom-session-redis/schema.graphql | 28 +++++++ examples/custom-session/schema.graphql | 28 +++++++ examples/default-values/schema.graphql | 28 +++++++ .../keystone-server/schema.graphql | 28 +++++++ examples/document-field/schema.graphql | 28 +++++++ examples/extend-express-app/schema.graphql | 28 +++++++ .../schema.graphql | 28 +++++++ .../schema.graphql | 28 +++++++ .../schema.graphql | 28 +++++++ .../schema.graphql | 28 +++++++ examples/extend-prisma-schema/schema.graphql | 28 +++++++ examples/field-groups/schema.graphql | 28 +++++++ examples/framework-astro/schema.graphql | 28 +++++++ .../schema.graphql | 28 +++++++ .../schema.graphql | 28 +++++++ .../keystone-server/schema.graphql | 28 +++++++ examples/framework-remix/schema.graphql | 28 +++++++ examples/graphql-ts-gql/schema.graphql | 28 +++++++ examples/hooks/schema.graphql | 28 +++++++ examples/limits/schema.graphql | 28 +++++++ examples/omit/schema.graphql | 28 +++++++ examples/reuse/schema.graphql | 28 +++++++ examples/script/schema.graphql | 28 +++++++ examples/singleton/schema.graphql | 28 +++++++ examples/testing/schema.graphql | 28 +++++++ examples/transactions/schema.graphql | 28 +++++++ .../usecase-blog-moderated/schema.graphql | 28 +++++++ examples/usecase-blog/schema.graphql | 28 +++++++ .../usecase-relationship-union/schema.graphql | 28 +++++++ examples/usecase-roles/schema.graphql | 28 +++++++ examples/usecase-todo/schema.graphql | 28 +++++++ examples/usecase-versioning/schema.graphql | 28 +++++++ examples/virtual-field/schema.graphql | 28 +++++++ .../core/src/admin-ui/admin-meta-graphql.ts | 36 ++++++++- .../core/src/admin-ui/utils/useAdminMeta.tsx | 5 +- .../core/src/lib/core/initialise-lists.ts | 16 ++-- packages/core/src/lib/core/utils.ts | 46 ----------- packages/core/src/lib/create-admin-meta.ts | 30 +++++--- packages/core/src/lib/createGraphQLSchema.ts | 2 +- ...meta-resolver.ts => resolve-admin-meta.ts} | 45 +++++++++++ packages/core/src/types/admin-meta.ts | 4 +- packages/core/src/types/utils.ts | 77 ++++++++++++++++--- tests/sandbox/schema.graphql | 28 +++++++ tests/test-projects/basic/schema.graphql | 28 +++++++ .../crud-notifications/schema.graphql | 28 +++++++ .../live-reloading/schema.graphql | 28 +++++++ 61 files changed, 1633 insertions(+), 84 deletions(-) rename packages/core/src/lib/{admin-meta-resolver.ts => resolve-admin-meta.ts} (82%) 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/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/utils/useAdminMeta.tsx b/packages/core/src/admin-ui/utils/useAdminMeta.tsx index 424f791b1f3..acfc83e430e 100644 --- a/packages/core/src/admin-ui/utils/useAdminMeta.tsx +++ b/packages/core/src/admin-ui/utils/useAdminMeta.tsx @@ -2,8 +2,7 @@ import { useEffect, useMemo, useState } from 'react' import hashString from '@emotion/hash' import { type AdminMeta, - type FieldViews, - getGqlNames + type FieldViews } from '../../types' import { useLazyQuery } from '../apollo' import { @@ -72,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/lib/core/initialise-lists.ts b/packages/core/src/lib/core/initialise-lists.ts index 1b7a6b5268d..85c4090d15a 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,7 +37,7 @@ import { parseListAccessControl, parseFieldAccessControl, } from './access-control' -import { areArraysEqual, getNamesFromList } from './utils' +import { areArraysEqual } from './utils' import { type ResolvedDBField, resolveRelationships @@ -108,7 +112,7 @@ export type InitialisedList = { graphql: { types: GraphQLTypesForList - names: ReturnType + names: GraphQLNames namePlural: string // TODO: remove isEnabled: IsListEnabled } @@ -466,7 +470,7 @@ function getListsWithInitialisedFields ( throw new Error(`${listKey}.ui.searchFields cannot include 'id'`) } - const names = getNamesFromList(listKey, listConfig) + const names = __getNames(listKey, listConfig) result[listKey] = { access: parseListAccessControl(listConfig.access), @@ -572,7 +576,7 @@ function graphqlForOutputField (field: InitialisedField) { function getListGraphqlTypes ( listsConfig: __ResolvedKeystoneConfig['lists'], lists: Record, - intermediateLists: Record + intermediateLists: Record ): Record { const graphQLTypes: Record = {} @@ -580,7 +584,7 @@ function getListGraphqlTypes ( const { listKey } = listConfig const { graphql: { names }, - } = getNamesFromList(listKey, listConfig) + } = __getNames(listKey, listConfig) const output = graphql.object()({ name: names.outputTypeName, 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/createGraphQLSchema.ts b/packages/core/src/lib/createGraphQLSchema.ts index c7f8c1bbc85..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' 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/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/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! From ccd3fddd2d8d2b2049a99286c1df09eda62e6fe0 Mon Sep 17 00:00:00 2001 From: Daniel Cousens <413395+dcousens@users.noreply.github.com> Date: Wed, 31 Jul 2024 16:57:03 +1000 Subject: [PATCH 5/9] fix internal GraphQL type references --- .../core/src/lib/core/initialise-lists.ts | 598 +++++++++--------- 1 file changed, 298 insertions(+), 300 deletions(-) diff --git a/packages/core/src/lib/core/initialise-lists.ts b/packages/core/src/lib/core/initialise-lists.ts index 85c4090d15a..d911b101fd8 100644 --- a/packages/core/src/lib/core/initialise-lists.ts +++ b/packages/core/src/lib/core/initialise-lists.ts @@ -357,10 +357,283 @@ function parseFieldHooks ( } function getListsWithInitialisedFields ( - { storage: configStorage, lists: listsConfig, db: { provider } }: __ResolvedKeystoneConfig, - listGraphqlTypes: Record, - intermediateLists: Record + config: __ResolvedKeystoneConfig, + listsRef: Record, ) { + const { storage: configStorage, lists: listsConfig, db: { provider } } = config + const intermediateLists = Object.fromEntries(Object.values(config.lists).map((listConfig) => [ + listConfig.listKey, + { + graphql: { + isEnabled: getIsEnabled(listConfig.listKey, listConfig) + } + }, + ])) + + const listGraphqlTypes: Record = {} + + for (const listConfig of Object.values(listsConfig)) { + const { listKey } = listConfig + const { + graphql: { names }, + } = __getNames(listKey, listConfig) + + const output = graphql.object()({ + name: names.outputTypeName, + fields: () => { + 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) + ) { + return [] + } + + const outputFieldRoot = graphqlForOutputField(field) + return [ + [fieldPath, outputFieldRoot] as const, + ...Object.entries(field.extraOutputFields || {}), + ].map(([outputTypeFieldName, outputField]) => { + return [ + outputTypeFieldName, + outputTypeField( + outputField, + field.dbField, + field.graphql?.cacheHint, + field.access.read, + listKey, + fieldPath, + listsRef + ), + ] + }) + }) + ), + } + }, + }) + + const uniqueWhere = graphql.inputObject({ + name: names.whereUniqueInputName, + fields: () => { + const { fields } = listsRef[listKey] + return { + ...Object.fromEntries( + Object.entries(fields).flatMap(([key, field]) => { + if ( + !field.input?.uniqueWhere?.arg || + !field.graphql.isEnabled.read || + !field.graphql.isEnabled.filter + ) { + return [] + } + return [[key, field.input.uniqueWhere.arg]] as const + }) + ), + // this is exactly what the id field will add + // but this does it more explicitly so that typescript understands + id: graphql.arg({ type: graphql.ID }), + } + }, + }) + + const where: GraphQLTypesForList['where'] = graphql.inputObject({ + name: names.whereInputName, + fields: () => { + const { fields } = listsRef[listKey] + return Object.assign( + { + AND: graphql.arg({ type: graphql.list(graphql.nonNull(where)) }), + OR: graphql.arg({ type: graphql.list(graphql.nonNull(where)) }), + NOT: graphql.arg({ type: graphql.list(graphql.nonNull(where)) }), + }, + ...Object.entries(fields).map( + ([fieldKey, field]) => + field.input?.where?.arg && + field.graphql.isEnabled.read && + field.graphql.isEnabled.filter && { [fieldKey]: field.input?.where?.arg } + ) + ) + }, + }) + + const create = graphql.inputObject({ + name: names.createInputName, + fields: () => { + const { fields } = listsRef[listKey] + const ret: Record> = {} + + for (const key in fields) { + const arg = graphqlArgForInputField(fields[key], 'create') + if (!arg) continue + ret[key] = arg + } + + return ret + }, + }) + + const update = graphql.inputObject({ + name: names.updateInputName, + fields: () => { + const { fields } = listsRef[listKey] + const ret: Record> = {} + + for (const key in fields) { + const arg = graphqlArgForInputField(fields[key], 'update') + if (!arg) continue + ret[key] = arg + } + + return ret + }, + }) + + const orderBy = graphql.inputObject({ + name: names.listOrderName, + fields: () => { + const { fields } = listsRef[listKey] + return Object.fromEntries( + Object.entries(fields).flatMap(([key, field]) => { + if ( + !field.input?.orderBy?.arg || + !field.graphql.isEnabled.read || + !field.graphql.isEnabled.orderBy + ) { + return [] + } + return [[key, field.input.orderBy.arg]] as const + }) + ) + }, + }) + + let take: any = graphql.arg({ type: graphql.Int }) + if (listConfig.graphql?.maxTake !== undefined) { + take = graphql.arg({ + type: graphql.nonNull(graphql.Int), + // WARNING: used by queries/resolvers.ts to enforce the limit + defaultValue: listConfig.graphql.maxTake, + }) + } + + const findManyArgs: FindManyArgs = { + where: graphql.arg({ + type: graphql.nonNull(where), + defaultValue: listConfig.isSingleton ? ({ id: { equals: '1' } } as {}) : {}, + }), + orderBy: graphql.arg({ + type: graphql.nonNull(graphql.list(graphql.nonNull(orderBy))), + defaultValue: [], + }), + take, + skip: graphql.arg({ + type: graphql.nonNull(graphql.Int), + defaultValue: 0 + }), + cursor: graphql.arg({ type: uniqueWhere }), + } + + 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(listRef.graphql.types.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)) }), + } + }, + }) + + 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 }), + } + }, + }) + + 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 }), + } + }, + }) + + listGraphqlTypes[listKey] = { + types: { + output, + uniqueWhere, + where, + create, + orderBy, + update, + findManyArgs, + relateTo: { + one: { + create: relateToOneForCreate, + update: relateToOneForUpdate + }, + many: { + where: graphql.inputObject({ + name: `${listKey}ManyRelationFilter`, + fields: { + every: graphql.arg({ type: where }), + some: graphql.arg({ type: where }), + none: graphql.arg({ type: where }), + }, + }), + create: relateToManyForCreate, + update: relateToManyForUpdate, + }, + }, + }, + } + } + const result: Record = {} for (const listConfig of Object.values(listsConfig)) { @@ -573,311 +846,36 @@ function graphqlForOutputField (field: InitialisedField) { }) } -function getListGraphqlTypes ( - listsConfig: __ResolvedKeystoneConfig['lists'], - lists: Record, - intermediateLists: Record -): Record { - const graphQLTypes: Record = {} - - for (const listConfig of Object.values(listsConfig)) { - const { listKey } = listConfig - const { - graphql: { names }, - } = __getNames(listKey, listConfig) - - const output = graphql.object()({ - name: names.outputTypeName, - fields: () => { - const { fields } = lists[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) - ) { - return [] - } - - const outputFieldRoot = graphqlForOutputField(field) - return [ - [fieldPath, outputFieldRoot] as const, - ...Object.entries(field.extraOutputFields || {}), - ].map(([outputTypeFieldName, outputField]) => { - return [ - outputTypeFieldName, - outputTypeField( - outputField, - field.dbField, - field.graphql?.cacheHint, - field.access.read, - listKey, - fieldPath, - lists - ), - ] - }) - }) - ), - } - }, - }) - - const uniqueWhere = graphql.inputObject({ - name: names.whereUniqueInputName, - fields: () => { - const { fields } = lists[listKey] - return { - ...Object.fromEntries( - Object.entries(fields).flatMap(([key, field]) => { - if ( - !field.input?.uniqueWhere?.arg || - !field.graphql.isEnabled.read || - !field.graphql.isEnabled.filter - ) { - return [] - } - return [[key, field.input.uniqueWhere.arg]] as const - }) - ), - // this is exactly what the id field will add - // but this does it more explicitly so that typescript understands - id: graphql.arg({ type: graphql.ID }), - } - }, - }) - - const where: GraphQLTypesForList['where'] = graphql.inputObject({ - name: names.whereInputName, - fields: () => { - const { fields } = lists[listKey] - return Object.assign( - { - AND: graphql.arg({ type: graphql.list(graphql.nonNull(where)) }), - OR: graphql.arg({ type: graphql.list(graphql.nonNull(where)) }), - NOT: graphql.arg({ type: graphql.list(graphql.nonNull(where)) }), - }, - ...Object.entries(fields).map( - ([fieldKey, field]) => - field.input?.where?.arg && - field.graphql.isEnabled.read && - field.graphql.isEnabled.filter && { [fieldKey]: field.input?.where?.arg } - ) - ) - }, - }) - - const create = graphql.inputObject({ - name: names.createInputName, - fields: () => { - const { fields } = lists[listKey] - const ret: Record> = {} - - for (const key in fields) { - const arg = graphqlArgForInputField(fields[key], 'create') - if (!arg) continue - ret[key] = arg - } - - return ret - }, - }) - - const update = graphql.inputObject({ - name: names.updateInputName, - fields: () => { - const { fields } = lists[listKey] - const ret: Record> = {} - - for (const key in fields) { - const arg = graphqlArgForInputField(fields[key], 'update') - if (!arg) continue - ret[key] = arg - } - - return ret - }, - }) - - const orderBy = graphql.inputObject({ - name: names.listOrderName, - fields: () => { - const { fields } = lists[listKey] - return Object.fromEntries( - Object.entries(fields).flatMap(([key, field]) => { - if ( - !field.input?.orderBy?.arg || - !field.graphql.isEnabled.read || - !field.graphql.isEnabled.orderBy - ) { - return [] - } - return [[key, field.input.orderBy.arg]] as const - }) - ) - }, - }) - - let take: any = graphql.arg({ type: graphql.Int }) - 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 - defaultValue: listConfig.graphql.maxTake, - }) - } - - const findManyArgs: FindManyArgs = { - where: graphql.arg({ - type: graphql.nonNull(where), - defaultValue: listConfig.isSingleton ? ({ id: { equals: '1' } } as {}) : {}, - }), - orderBy: graphql.arg({ - type: graphql.nonNull(graphql.list(graphql.nonNull(orderBy))), - defaultValue: [], - }), - take, - 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)) }), - }), - connect: graphql.arg({ type: graphql.list(graphql.nonNull(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)) }), - } - }, - }) - - 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 }), - } - }, - }) - - 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 }), - } - }, - }) - } - - graphQLTypes[listKey] = { - types: { - output, - uniqueWhere, - where, - create, - orderBy, - update, - findManyArgs, - relateTo: { - many: { - where: graphql.inputObject({ - name: `${listKey}ManyRelationFilter`, - fields: { - every: graphql.arg({ type: where }), - some: graphql.arg({ type: where }), - none: graphql.arg({ type: where }), - }, - }), - create: relateToManyForCreate, - update: relateToManyForUpdate, - }, - one: { create: relateToOneForCreate, update: relateToOneForUpdate }, - }, - }, - } - } - - return graphQLTypes -} - export function initialiseLists (config: __ResolvedKeystoneConfig): Record { + const listsRef: Record = {} let intermediateLists - intermediateLists = Object.fromEntries( - Object.values(config.lists).map((listConfig) => [ - listConfig.listKey, - { - graphql: { - isEnabled: getIsEnabled(listConfig.listKey, listConfig) - } - }, - ]) - ) - const listsRef: Record = {} - { - const listGraphqlTypes = getListGraphqlTypes(config.lists, listsRef, intermediateLists) - intermediateLists = getListsWithInitialisedFields(config, listGraphqlTypes, intermediateLists) - } + // step 1 + intermediateLists = getListsWithInitialisedFields(config, listsRef) - { - const resolvedDBFieldsForLists = resolveRelationships(intermediateLists) - intermediateLists = Object.fromEntries( - Object.values(intermediateLists).map((list) => [ - list.listKey, - { - ...list, - resolvedDbFields: resolvedDBFieldsForLists[list.listKey], - }, - ]) - ) - } + // step 2 + const resolvedDBFieldsForLists = resolveRelationships(intermediateLists) + intermediateLists = Object.fromEntries(Object.values(intermediateLists).map((list) => [ + list.listKey, + { + ...list, + resolvedDbFields: resolvedDBFieldsForLists[list.listKey], + }, + ])) - intermediateLists = Object.fromEntries( - Object.values(intermediateLists).map((list) => { - const fields: Record = {} + // 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], - } + for (const [fieldKey, field] of Object.entries(list.fields)) { + fields[fieldKey] = { + ...field, + dbField: list.resolvedDbFields[fieldKey], } + } - return [list.listKey, { ...list, fields }] - }) - ) + return [list.listKey, { ...list, fields }] + })) for (const list of Object.values(intermediateLists)) { let hasAnEnabledCreateField = false From 43f5b8f520c23718b9a46ac8076d92b0ea0146b5 Mon Sep 17 00:00:00 2001 From: Daniel Cousens <413395+dcousens@users.noreply.github.com> Date: Wed, 31 Jul 2024 16:32:03 +1000 Subject: [PATCH 6/9] handle nulls from input data --- packages/core/src/lib/core/mutations/index.ts | 65 ++++++++++--------- 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/packages/core/src/lib/core/mutations/index.ts b/packages/core/src/lib/core/mutations/index.ts index 409e7913035..d735c250478 100644 --- a/packages/core/src/lib/core/mutations/index.ts +++ b/packages/core/src/lib/core/mutations/index.ts @@ -69,7 +69,7 @@ async function getFilteredItem ( } async function createSingle ( - { data: rawData }: { data: 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) }, }) From fa89058b04f51fd9deac4fba2c5287611e6a0747 Mon Sep 17 00:00:00 2001 From: Daniel Cousens <413395+dcousens@users.noreply.github.com> Date: Thu, 1 Aug 2024 22:20:06 +1000 Subject: [PATCH 7/9] fix missing isEnabled.type for relational queries --- packages/core/src/lib/core/initialise-lists.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/core/src/lib/core/initialise-lists.ts b/packages/core/src/lib/core/initialise-lists.ts index d911b101fd8..e492a26bede 100644 --- a/packages/core/src/lib/core/initialise-lists.ts +++ b/packages/core/src/lib/core/initialise-lists.ts @@ -388,8 +388,7 @@ function getListsWithInitialisedFields ( 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 [] } @@ -603,6 +602,7 @@ function getListsWithInitialisedFields ( }, }) + const hasType = intermediateLists[listKey].graphql.isEnabled.type listGraphqlTypes[listKey] = { types: { output, @@ -614,8 +614,8 @@ function getListsWithInitialisedFields ( findManyArgs, relateTo: { one: { - create: relateToOneForCreate, - update: relateToOneForUpdate + create: hasType ? relateToOneForCreate : undefined, + update: hasType ? relateToOneForUpdate : undefined, }, many: { where: graphql.inputObject({ @@ -626,8 +626,8 @@ function getListsWithInitialisedFields ( none: graphql.arg({ type: where }), }, }), - create: relateToManyForCreate, - update: relateToManyForUpdate, + create: hasType ? relateToManyForCreate : undefined, + update: hasType ? relateToManyForUpdate : undefined, }, }, }, From 746fec7c6de0c02c190e42227fb9ae8b27c727af Mon Sep 17 00:00:00 2001 From: Daniel Cousens <413395+dcousens@users.noreply.github.com> Date: Thu, 1 Aug 2024 22:20:14 +1000 Subject: [PATCH 8/9] tidy up vritual field --- .../core/src/fields/types/virtual/index.ts | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) 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 || '' + }), }) } +} From 71aee68b7ebf6cf484ea9731c4bcb9fc18a2c31c Mon Sep 17 00:00:00 2001 From: Daniel Cousens <413395+dcousens@users.noreply.github.com> Date: Thu, 1 Aug 2024 22:22:31 +1000 Subject: [PATCH 9/9] fix broken tests --- tests/api-tests/admin-meta.test.ts | 24 ++++++++++++++++ .../fixtures/basic-project/schema.graphql | 28 +++++++++++++++++++ 2 files changed, 52 insertions(+) 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!