chore: normalize payload collections and globals outside db adapter
This commit is contained in:
@@ -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<DeepRequired<CollectionC
|
||||
}
|
||||
|
||||
export type Collection = {
|
||||
Model: CollectionModel;
|
||||
Model?: CollectionModel;
|
||||
config: SanitizedCollectionConfig;
|
||||
graphQL?: {
|
||||
type: GraphQLObjectType
|
||||
|
||||
@@ -7,7 +7,12 @@ import { PayloadRequest } from '../../express/types';
|
||||
import { Access, Endpoint, EntityDescription, GeneratePreviewURL } from '../../config/types';
|
||||
import { Field } from '../../fields/config/types';
|
||||
import { IncomingGlobalVersions, SanitizedGlobalVersions } from '../../versions/types';
|
||||
import { CustomSaveButtonProps, CustomSaveDraftButtonProps, CustomPublishButtonProps, CustomPreviewButtonProps } from '../../admin/components/elements/types';
|
||||
import {
|
||||
CustomPreviewButtonProps,
|
||||
CustomPublishButtonProps,
|
||||
CustomSaveButtonProps,
|
||||
CustomSaveDraftButtonProps,
|
||||
} from '../../admin/components/elements/types';
|
||||
|
||||
export type TypeWithID = {
|
||||
id: string | number
|
||||
@@ -143,7 +148,7 @@ export interface SanitizedGlobalConfig extends Omit<DeepRequired<GlobalConfig>,
|
||||
}
|
||||
|
||||
export type Globals = {
|
||||
Model: GlobalModel
|
||||
Model?: GlobalModel
|
||||
config: SanitizedGlobalConfig[]
|
||||
graphQL?: {
|
||||
[slug: string]: {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -194,6 +194,15 @@ export class BasePayload<TGeneratedTypes extends GeneratedTypes> {
|
||||
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<TGeneratedTypes extends GeneratedTypes> {
|
||||
}
|
||||
|
||||
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<TGeneratedTypes extends GeneratedTypes> {
|
||||
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);
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user