diff --git a/src/collections/config/types.ts b/src/collections/config/types.ts index be2e515955..0bf8f1ece6 100644 --- a/src/collections/config/types.ts +++ b/src/collections/config/types.ts @@ -11,7 +11,12 @@ import { Auth, IncomingAuthType, User } from '../../auth/types'; import { IncomingUploadType, Upload } from '../../uploads/types'; import { IncomingCollectionVersions, SanitizedCollectionVersions } from '../../versions/types'; import { BuildQueryArgs } from '../../mongoose/queries/buildQuery'; -import { CustomPreviewButtonProps, CustomPublishButtonProps, CustomSaveButtonProps, CustomSaveDraftButtonProps } from '../../admin/components/elements/types'; +import { + CustomPreviewButtonProps, + CustomPublishButtonProps, + CustomSaveButtonProps, + CustomSaveDraftButtonProps, +} from '../../admin/components/elements/types'; import type { Props as ListProps } from '../../admin/components/views/collections/List/types'; import type { Props as EditProps } from '../../admin/components/views/collections/Edit/types'; @@ -354,7 +359,7 @@ export interface SanitizedCollectionConfig extends Omit, } export type Globals = { - Model: GlobalModel + Model?: GlobalModel config: SanitizedGlobalConfig[] graphQL?: { [slug: string]: { diff --git a/src/globals/graphql/init.ts b/src/globals/graphql/init.ts index 87d1d431bf..2e9ad5105c 100644 --- a/src/globals/graphql/init.ts +++ b/src/globals/graphql/init.ts @@ -1,5 +1,5 @@ /* eslint-disable no-param-reassign */ -import { GraphQLNonNull, GraphQLBoolean, GraphQLInt, GraphQLString } from 'graphql'; +import { GraphQLBoolean, GraphQLInt, GraphQLNonNull, GraphQLString } from 'graphql'; import { singular } from 'pluralize'; import formatName from '../../graphql/utilities/formatName'; import { buildVersionGlobalFields } from '../../versions/buildGlobalFields'; @@ -20,138 +20,136 @@ import { buildPolicyType } from '../../graphql/schema/buildPoliciesType'; import { docAccessResolver } from './resolvers/docAccess'; function initGlobalsGraphQL(payload: Payload): void { - if (payload.config.globals) { - Object.keys(payload.globals.config).forEach((slug) => { - const global: SanitizedGlobalConfig = payload.globals.config[slug]; - const { + Object.keys(payload.globals.config).forEach((slug) => { + const global: SanitizedGlobalConfig = payload.globals.config[slug]; + const { + fields, + versions, + } = global; + + const formattedName = global.graphQL?.name ? global.graphQL.name : singular(toWords(global.slug, true)); + + const forceNullableObjectType = Boolean(versions?.drafts); + + if (!payload.globals.graphQL) payload.globals.graphQL = {}; + + payload.globals.graphQL[slug] = { + type: buildObjectType({ + payload, + name: formattedName, + parentName: formattedName, fields, - versions, - } = global; + forceNullable: forceNullableObjectType, + }), + mutationInputType: new GraphQLNonNull(buildMutationInputType( + payload, + formattedName, + fields, + formattedName, + )), + }; - const formattedName = global.graphQL?.name ? global.graphQL.name : singular(toWords(global.slug, true)); + payload.Query.fields[formattedName] = { + type: payload.globals.graphQL[slug].type, + args: { + draft: { type: GraphQLBoolean }, + ...(payload.config.localization ? { + locale: { type: payload.types.localeInputType }, + fallbackLocale: { type: payload.types.fallbackLocaleInputType }, + } : {}), + }, + resolve: findOneResolver(global), + }; - const forceNullableObjectType = Boolean(versions?.drafts); + payload.Mutation.fields[`update${formattedName}`] = { + type: payload.globals.graphQL[slug].type, + args: { + data: { type: payload.globals.graphQL[slug].mutationInputType }, + draft: { type: GraphQLBoolean }, + ...(payload.config.localization ? { + locale: { type: payload.types.localeInputType }, + } : {}), + }, + resolve: updateResolver(global), + }; - if (!payload.globals.graphQL) payload.globals.graphQL = {}; + payload.Query.fields[`docAccess${formattedName}`] = { + type: buildPolicyType({ + typeSuffix: 'DocAccess', + entity: global, + type: 'global', + scope: 'docAccess', + }), + resolve: docAccessResolver(global), + }; - payload.globals.graphQL[slug] = { - type: buildObjectType({ - payload, - name: formattedName, - parentName: formattedName, - fields, - forceNullable: forceNullableObjectType, - }), - mutationInputType: new GraphQLNonNull(buildMutationInputType( - payload, - formattedName, - fields, - formattedName, - )), - }; + if (global.versions) { + const versionGlobalFields: Field[] = [ + ...buildVersionGlobalFields(global), + { + name: 'id', + type: 'text', + }, + { + name: 'createdAt', + label: 'Created At', + type: 'date', + }, + { + name: 'updatedAt', + label: 'Updated At', + type: 'date', + }, + ]; - payload.Query.fields[formattedName] = { - type: payload.globals.graphQL[slug].type, + payload.globals.graphQL[slug].versionType = buildObjectType({ + payload, + name: `${formattedName}Version`, + parentName: `${formattedName}Version`, + fields: versionGlobalFields, + forceNullable: forceNullableObjectType, + }); + + payload.Query.fields[`version${formatName(formattedName)}`] = { + type: payload.globals.graphQL[slug].versionType, args: { - draft: { type: GraphQLBoolean }, + id: { type: GraphQLString }, ...(payload.config.localization ? { locale: { type: payload.types.localeInputType }, fallbackLocale: { type: payload.types.fallbackLocaleInputType }, } : {}), }, - resolve: findOneResolver(global), + resolve: findVersionByIDResolver(global), }; - - payload.Mutation.fields[`update${formattedName}`] = { - type: payload.globals.graphQL[slug].type, + payload.Query.fields[`versions${formattedName}`] = { + type: buildPaginatedListType(`versions${formatName(formattedName)}`, payload.globals.graphQL[slug].versionType), args: { - data: { type: payload.globals.graphQL[slug].mutationInputType }, - draft: { type: GraphQLBoolean }, + where: { + type: buildWhereInputType( + `versions${formattedName}`, + versionGlobalFields, + `versions${formattedName}`, + ), + }, ...(payload.config.localization ? { locale: { type: payload.types.localeInputType }, + fallbackLocale: { type: payload.types.fallbackLocaleInputType }, } : {}), + page: { type: GraphQLInt }, + limit: { type: GraphQLInt }, + sort: { type: GraphQLString }, }, - resolve: updateResolver(global), + resolve: findVersionsResolver(global), }; - - payload.Query.fields[`docAccess${formattedName}`] = { - type: buildPolicyType({ - typeSuffix: 'DocAccess', - entity: global, - type: 'global', - scope: 'docAccess', - }), - resolve: docAccessResolver(global), + payload.Mutation.fields[`restoreVersion${formatName(formattedName)}`] = { + type: payload.globals.graphQL[slug].type, + args: { + id: { type: GraphQLString }, + }, + resolve: restoreVersionResolver(global), }; - - if (global.versions) { - const versionGlobalFields: Field[] = [ - ...buildVersionGlobalFields(global), - { - name: 'id', - type: 'text', - }, - { - name: 'createdAt', - label: 'Created At', - type: 'date', - }, - { - name: 'updatedAt', - label: 'Updated At', - type: 'date', - }, - ]; - - payload.globals.graphQL[slug].versionType = buildObjectType({ - payload, - name: `${formattedName}Version`, - parentName: `${formattedName}Version`, - fields: versionGlobalFields, - forceNullable: forceNullableObjectType, - }); - - payload.Query.fields[`version${formatName(formattedName)}`] = { - type: payload.globals.graphQL[slug].versionType, - args: { - id: { type: GraphQLString }, - ...(payload.config.localization ? { - locale: { type: payload.types.localeInputType }, - fallbackLocale: { type: payload.types.fallbackLocaleInputType }, - } : {}), - }, - resolve: findVersionByIDResolver(global), - }; - payload.Query.fields[`versions${formattedName}`] = { - type: buildPaginatedListType(`versions${formatName(formattedName)}`, payload.globals.graphQL[slug].versionType), - args: { - where: { - type: buildWhereInputType( - `versions${formattedName}`, - versionGlobalFields, - `versions${formattedName}`, - ), - }, - ...(payload.config.localization ? { - locale: { type: payload.types.localeInputType }, - fallbackLocale: { type: payload.types.fallbackLocaleInputType }, - } : {}), - page: { type: GraphQLInt }, - limit: { type: GraphQLInt }, - sort: { type: GraphQLString }, - }, - resolve: findVersionsResolver(global), - }; - payload.Mutation.fields[`restoreVersion${formatName(formattedName)}`] = { - type: payload.globals.graphQL[slug].type, - args: { - id: { type: GraphQLString }, - }, - resolve: restoreVersionResolver(global), - }; - } - }); - } + } + }); } export default initGlobalsGraphQL; diff --git a/src/mongoose/init.ts b/src/mongoose/init.ts index 650fecf426..fff231156c 100644 --- a/src/mongoose/init.ts +++ b/src/mongoose/init.ts @@ -41,16 +41,23 @@ export async function init( if (collection.indexes) { collection.indexes.forEach((index) => { // prefix 'version.' to each field in the index - const versionIndex = { fields: {}, options: index.options }; - Object.entries(index.fields).forEach(([key, value]) => { - versionIndex.fields[`version.${key}`] = value; - }); + const versionIndex = { + fields: {}, + options: index.options, + }; + Object.entries(index.fields) + .forEach(([key, value]) => { + versionIndex.fields[`version.${key}`] = value; + }); versionSchema.index(versionIndex.fields, versionIndex.options); }); } versionSchema.plugin(paginate, { useEstimatedCount: true }) - .plugin(getBuildQueryPlugin({ collectionSlug: collection.slug, versionsFields: versionCollectionFields })); + .plugin(getBuildQueryPlugin({ + collectionSlug: collection.slug, + versionsFields: versionCollectionFields, + })); if (collection.versions?.drafts) { versionSchema.plugin(mongooseAggregatePaginate); @@ -70,43 +77,38 @@ export async function init( }; }); - if (payload.config.globals) { - const model = buildGlobalModel(payload.config); - this.globals = model; + const model = buildGlobalModel(payload.config); + this.globals = model; - payload.globals = { - Model: model, - config: payload.config.globals, - }; + payload.globals.Model = model; - payload.config.globals.forEach((global) => { - if (global.versions) { - const versionModelName = getVersionsModelName(global); + payload.config.globals.forEach((global) => { + if (global.versions) { + const versionModelName = getVersionsModelName(global); - const versionGlobalFields = buildVersionGlobalFields(global); + const versionGlobalFields = buildVersionGlobalFields(global); - const versionSchema = buildSchema( - payload.config, - versionGlobalFields, - { - indexSortableFields: payload.config.indexSortableFields, - disableUnique: true, - draftsEnabled: true, - options: { - timestamps: false, - minimize: false, - }, + const versionSchema = buildSchema( + payload.config, + versionGlobalFields, + { + indexSortableFields: payload.config.indexSortableFields, + disableUnique: true, + draftsEnabled: true, + options: { + timestamps: false, + minimize: false, }, - ); + }, + ); - versionSchema.plugin(paginate, { useEstimatedCount: true }) - .plugin(getBuildQueryPlugin({ versionsFields: versionGlobalFields })); + versionSchema.plugin(paginate, { useEstimatedCount: true }) + .plugin(getBuildQueryPlugin({ versionsFields: versionGlobalFields })); - const versionsModel = mongoose.model(versionModelName, versionSchema) as CollectionModel; - this.versions[global.slug] = versionsModel; + const versionsModel = mongoose.model(versionModelName, versionSchema) as CollectionModel; + this.versions[global.slug] = versionsModel; - payload.versions[global.slug] = versionsModel; - } - }); - } + payload.versions[global.slug] = versionsModel; + } + }); } diff --git a/src/payload.ts b/src/payload.ts index b23074c652..de8bed6c94 100644 --- a/src/payload.ts +++ b/src/payload.ts @@ -194,6 +194,15 @@ export class BasePayload { this.config = await loadConfig(this.logger); } + this.globals = { + config: this.config.globals, + }; + this.config.collections.forEach((collection) => { + this.collections[collection.slug] = { + config: collection, + }; + }); + // THIS BLOCK IS TEMPORARY UNTIL 2.0.0 // We automatically add the Mongoose adapter // if there is no defined database adapter @@ -209,7 +218,9 @@ export class BasePayload { } this.db = this.config.db; - this.mongoMemoryServer = await this.db.connect({ payload: this, config: this.config }); + if (this.db?.connect) { + this.mongoMemoryServer = await this.db.connect({ payload: this, config: this.config }); + } // Configure email service const emailOptions = options.email ? { ...(options.email) } : this.config.email; @@ -221,12 +232,13 @@ export class BasePayload { this.email = buildEmail(this.emailOptions, this.logger); this.sendEmail = sendEmail.bind(this); - await this.db.init({ payload: this, config: this.config }); - if (!this.config.graphQL.disable) { registerGraphQLSchema(this); } + if (this.db.init) { + await this.db?.init({ payload: this, config: this.config }); + } this.preferences = { Model: PreferencesModel }; serverInitTelemetry(this); diff --git a/test/graphql-schema-gen/schema.graphql b/test/graphql-schema-gen/schema.graphql index dbb6689389..149edd2b6d 100644 --- a/test/graphql-schema-gen/schema.graphql +++ b/test/graphql-schema-gen/schema.graphql @@ -861,7 +861,7 @@ type User { id: String updatedAt: DateTime createdAt: DateTime - email: EmailAddress + email: EmailAddress! resetPasswordToken: String resetPasswordExpiration: DateTime salt: String @@ -929,7 +929,6 @@ input User_email_operator { in: [EmailAddress] not_in: [EmailAddress] all: [EmailAddress] - exists: Boolean } input User_id_operator { @@ -1855,7 +1854,7 @@ input mutationCollection2Update_NestedGroup_MetaInput { input mutationUserInput { updatedAt: String createdAt: String - email: String + email: String! resetPasswordToken: String resetPasswordExpiration: String salt: String