diff --git a/packages/keystone/lib/providers/listCRUD.js b/packages/keystone/lib/providers/listCRUD.js index b9ddba81030..3b2cc0d1f64 100644 --- a/packages/keystone/lib/providers/listCRUD.js +++ b/packages/keystone/lib/providers/listCRUD.js @@ -1,6 +1,8 @@ const { GraphQLJSON } = require('graphql-type-json'); const { flatten, objMerge, unique } = require('@keystonejs/utils'); +const { getListCRUDTypes } = require('./listCRUDTypes'); + class ListCRUDProvider { constructor({ metaPrefix = 'ks' } = {}) { this.lists = []; @@ -13,163 +15,10 @@ class ListCRUDProvider { getTypes({ schemaName }) { return unique([ ...flatten(this.lists.map(list => list.getGqlTypes({ schemaName }))), - `"""NOTE: Can be JSON, or a Boolean/Int/String - Why not a union? GraphQL doesn't support a union including a scalar - (https://github.com/facebook/graphql/issues/215)""" - scalar JSON`, - `type _ListAccess { - """Access Control settings for the currently logged in (or anonymous) - user when performing 'create' operations. - NOTE: 'create' can only return a Boolean. - It is not possible to specify a declarative Where clause for this - operation""" - create: Boolean - - """Access Control settings for the currently logged in (or anonymous) - user when performing 'read' operations.""" - read: JSON - - """Access Control settings for the currently logged in (or anonymous) - user when performing 'update' operations.""" - update: JSON - - """Access Control settings for the currently logged in (or anonymous) - user when performing 'delete' operations.""" - delete: JSON - - """Access Control settings for the currently logged in (or anonymous) - user when performing 'auth' operations.""" - auth: JSON - }`, - `type _ListQueries { - """Single-item query name.""" - item: String - - """All-items query name.""" - list: String - - """List metadata query name.""" - meta: String - }`, - `type _ListMutations { - """Create mutation name.""" - create: String - - """Create many mutation name.""" - createMany: String - - """Update mutation name.""" - update: String - - """Update many mutation name.""" - updateMany: String - - """Delete mutation name.""" - delete: String - - """Delete many mutation name.""" - deleteMany: String - }`, - `type _ListInputTypes { - """Input type for matching multiple items.""" - whereInput: String - - """Input type for matching a unique item.""" - whereUniqueInput: String - - """Create mutation input type name.""" - createInput: String - - """Create many mutation input type name.""" - createManyInput: String - - """Update mutation name input.""" - updateInput: String - - """Update many mutation name input.""" - updateManyInput: String - }`, - `type _ListSchemaFields { - """ The path of the field in its list. """ - path: String - - """The name of the field in its list.""" - name: String @deprecated(reason: "Use \`path\` instead") - - """The field type (ie, Checkbox, Text, etc)""" - type: String - }`, - `type _ListSchemaRelatedFields { - """The typename as used in GraphQL queries""" - type: String - - """A list of GraphQL field names""" - fields: [String] - }`, - `type _ListSchema { - """The typename as used in GraphQL queries""" - type: String - - """Top level GraphQL query names which either return this type, or - provide aggregate information about this type""" - queries: _ListQueries - - """Top-level GraphQL mutation names""" - mutations: _ListMutations - - """Top-level GraphQL input types""" - inputTypes: _ListInputTypes - - """Information about fields defined on this list. """ - fields(where: _ListSchemaFieldsInput): [_ListSchemaFields] - - """Information about fields on other types which return this type, or - provide aggregate information about this type""" - relatedFields: [_ListSchemaRelatedFields] - }`, - `type _ListMeta { - """ The Keystone list key """ - key: String - - """The Keystone List name""" - name: String @deprecated(reason: "Use \`key\` instead") - - """The list's user-facing description""" - description: String - - """The list's display name in the Admin UI""" - label: String - - """The list's singular display name""" - singular: String - - """The list's plural display name""" - plural: String - - """The list's data path""" - path: String - - """Access control configuration for the currently authenticated - request""" - access: _ListAccess - - """Information on the generated GraphQL schema""" - schema: _ListSchema - }`, - `type _QueryMeta { - count: Int - }`, - `input ${this.gqlNames.listsMetaInput} { - key: String - - """Whether this is an auxiliary helper list.""" - auxiliary: Boolean - }`, - `input _ListSchemaFieldsInput { - type: String - }`, + ...getListCRUDTypes(this.gqlNames), ]); } + getQueries({ schemaName }) { // Aux lists are only there for typing and internal operations, they should // not have any GraphQL operations performed on them @@ -180,10 +29,12 @@ class ListCRUDProvider { ${this.gqlNames.listsMeta}(where: ${this.gqlNames.listsMetaInput}): [_ListMeta]`, ]; } + getMutations({ schemaName }) { const firstClassLists = this.lists.filter(list => !list.isAuxList); return flatten(firstClassLists.map(list => list.getGqlMutations({ schemaName }))); } + getSubscriptions({}) { return []; } @@ -257,6 +108,7 @@ class ListCRUDProvider { _ListSchema: listSchemaResolver, }; } + getQueryResolvers({ schemaName }) { const firstClassLists = this.lists.filter(list => !list.isAuxList); return { @@ -277,6 +129,7 @@ class ListCRUDProvider { .map(list => list.listMeta(context)), }; } + getMutationResolvers({ schemaName }) { const firstClassLists = this.lists.filter(list => !list.isAuxList); return { @@ -284,6 +137,7 @@ class ListCRUDProvider { ...objMerge(firstClassLists.map(list => list.gqlMutationResolvers({ schemaName }))), }; } + getSubscriptionResolvers({}) { return {}; } diff --git a/packages/keystone/lib/providers/listCRUDTypes.js b/packages/keystone/lib/providers/listCRUDTypes.js new file mode 100644 index 00000000000..978ad0c2b89 --- /dev/null +++ b/packages/keystone/lib/providers/listCRUDTypes.js @@ -0,0 +1,202 @@ +/** + * Helper function to get the static GraphQL Type definitions for the CRUD provider. + * @param {Object} gqlNames CRUD provider GraphQL type names + */ +const getListCRUDTypes = ({ listsMetaInput }) => [ + ` + """ + NOTE: Can be JSON, or a Boolean/Int/String + Why not a union? GraphQL doesn't support a union including a scalar + (https://github.com/facebook/graphql/issues/215) + """ + scalar JSON + `, + ` + type _ListAccess { + """ + Access Control settings for the currently logged in (or anonymous) + user when performing 'create' operations. + NOTE: 'create' can only return a Boolean. + It is not possible to specify a declarative Where clause for this + operation + """ + create: Boolean + + """ + Access Control settings for the currently logged in (or anonymous) + user when performing 'read' operations. + """ + read: JSON + + """ + Access Control settings for the currently logged in (or anonymous) + user when performing 'update' operations. + """ + update: JSON + + """ + Access Control settings for the currently logged in (or anonymous) + user when performing 'delete' operations. + """ + delete: JSON + + """ + Access Control settings for the currently logged in (or anonymous) + user when performing 'auth' operations. + """ + auth: JSON + } + `, + ` + type _ListQueries { + "Single-item query name" + item: String + + "All-items query name" + list: String + + "List metadata query name" + meta: String + } + `, + ` + type _ListMutations { + "Create mutation name" + create: String + + "Create many mutation name" + createMany: String + + "Update mutation name" + update: String + + "Update many mutation name" + updateMany: String + + "Delete mutation name" + delete: String + + "Delete many mutation name" + deleteMany: String + } + `, + ` + type _ListInputTypes { + "Input type for matching multiple items" + whereInput: String + + "Input type for matching a unique item" + whereUniqueInput: String + + "Create mutation input type name" + createInput: String + + "Create many mutation input type name" + createManyInput: String + + "Update mutation name input" + updateInput: String + + "Update many mutation name input" + updateManyInput: String + } + `, + ` + type _ListSchemaFields { + "The path of the field in its list" + path: String + + "The name of the field in its list" + name: String @deprecated(reason: "Use \`path\` instead") + + "The field type (ie, Checkbox, Text, etc)" + type: String + } + `, + ` + type _ListSchemaRelatedFields { + "The typename as used in GraphQL queries" + type: String + + "A list of GraphQL field names" + fields: [String] + } + `, + ` + type _ListSchema { + "The typename as used in GraphQL queries" + type: String + + """ + Top level GraphQL query names which either return this type, or + provide aggregate information about this type + """ + queries: _ListQueries + + "Top-level GraphQL mutation names" + mutations: _ListMutations + + "Top-level GraphQL input types" + inputTypes: _ListInputTypes + + "Information about fields defined on this list" + fields(where: _ListSchemaFieldsInput): [_ListSchemaFields] + + """ + Information about fields on other types which return this type, or + provide aggregate information about this type + """ + relatedFields: [_ListSchemaRelatedFields] + } + `, + ` + type _ListMeta { + "The Keystone list key" + key: String + + "The Keystone List name" + name: String @deprecated(reason: "Use \`key\` instead") + + "The list's user-facing description" + description: String + + "The list's display name in the Admin UI" + label: String + + "The list's singular display name" + singular: String + + "The list's plural display name" + plural: String + + "The list's data path" + path: String + + "Access control configuration for the currently authenticated request" + access: _ListAccess + + "Information on the generated GraphQL schema" + schema: _ListSchema + } + `, + ` + type _QueryMeta { + count: Int + } + `, + ` + input ${listsMetaInput} { + key: String + + "Whether this is an auxiliary helper list" + auxiliary: Boolean + } + `, + ` + input _ListSchemaFieldsInput { + type: String + } + `, +]; + +module.exports = { getListCRUDTypes };