Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 20s
Build & Deploy / 🧪 QA (push) Failing after 34s
Build & Deploy / 🏗️ Build (push) Has started running
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Smoke Test (push) Has been cancelled
Build & Deploy / ⚡ Lighthouse (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
599 lines
25 KiB
Plaintext
599 lines
25 KiB
Plaintext
import { GraphQLBoolean, GraphQLInt, GraphQLNonNull, GraphQLObjectType, GraphQLString } from 'graphql';
|
|
import { buildVersionCollectionFields, flattenTopLevelFields, formatNames, toWords } from 'payload';
|
|
import { fieldAffectsData, getLoginOptions } from 'payload/shared';
|
|
import { forgotPassword } from '../resolvers/auth/forgotPassword.js';
|
|
import { init } from '../resolvers/auth/init.js';
|
|
import { login } from '../resolvers/auth/login.js';
|
|
import { logout } from '../resolvers/auth/logout.js';
|
|
import { me } from '../resolvers/auth/me.js';
|
|
import { refresh } from '../resolvers/auth/refresh.js';
|
|
import { resetPassword } from '../resolvers/auth/resetPassword.js';
|
|
import { unlock } from '../resolvers/auth/unlock.js';
|
|
import { verifyEmail } from '../resolvers/auth/verifyEmail.js';
|
|
import { countResolver } from '../resolvers/collections/count.js';
|
|
import { createResolver } from '../resolvers/collections/create.js';
|
|
import { getDeleteResolver } from '../resolvers/collections/delete.js';
|
|
import { docAccessResolver } from '../resolvers/collections/docAccess.js';
|
|
import { duplicateResolver } from '../resolvers/collections/duplicate.js';
|
|
import { findResolver } from '../resolvers/collections/find.js';
|
|
import { findByIDResolver } from '../resolvers/collections/findByID.js';
|
|
import { findVersionByIDResolver } from '../resolvers/collections/findVersionByID.js';
|
|
import { findVersionsResolver } from '../resolvers/collections/findVersions.js';
|
|
import { restoreVersionResolver } from '../resolvers/collections/restoreVersion.js';
|
|
import { updateResolver } from '../resolvers/collections/update.js';
|
|
import { formatName } from '../utilities/formatName.js';
|
|
import { buildMutationInputType, getCollectionIDType } from './buildMutationInputType.js';
|
|
import { buildObjectType } from './buildObjectType.js';
|
|
import { buildPaginatedListType } from './buildPaginatedListType.js';
|
|
import { buildPolicyType } from './buildPoliciesType.js';
|
|
import { buildWhereInputType } from './buildWhereInputType.js';
|
|
export function initCollections({ config, graphqlResult }) {
|
|
Object.keys(graphqlResult.collections).forEach((slug)=>{
|
|
const collection = graphqlResult.collections[slug];
|
|
const { config: collectionConfig, config: { fields, graphQL = {}, versions } } = collection;
|
|
if (!graphQL) {
|
|
return;
|
|
}
|
|
let singularName;
|
|
let pluralName;
|
|
const fromSlug = formatNames(collection.config.slug);
|
|
if (graphQL.singularName) {
|
|
singularName = toWords(graphQL.singularName, true);
|
|
} else {
|
|
singularName = fromSlug.singular;
|
|
}
|
|
if (graphQL.pluralName) {
|
|
pluralName = toWords(graphQL.pluralName, true);
|
|
} else {
|
|
pluralName = fromSlug.plural;
|
|
}
|
|
// For collections named 'Media' or similar,
|
|
// there is a possibility that the singular name
|
|
// will equal the plural name. Append `all` to the beginning
|
|
// of potential conflicts
|
|
if (singularName === pluralName) {
|
|
pluralName = `all${singularName}`;
|
|
}
|
|
collection.graphQL = {};
|
|
const hasIDField = flattenTopLevelFields(fields).findIndex((field)=>fieldAffectsData(field) && field.name === 'id') > -1;
|
|
const idType = getCollectionIDType(config.db.defaultIDType, collectionConfig);
|
|
const baseFields = {};
|
|
const whereInputFields = [
|
|
...fields
|
|
];
|
|
if (!hasIDField) {
|
|
baseFields.id = {
|
|
type: new GraphQLNonNull(idType)
|
|
};
|
|
whereInputFields.push({
|
|
name: 'id',
|
|
type: config.db.defaultIDType
|
|
});
|
|
}
|
|
const forceNullableObjectType = Boolean(versions?.drafts);
|
|
collection.graphQL.type = buildObjectType({
|
|
name: singularName,
|
|
baseFields,
|
|
collectionSlug: collectionConfig.slug,
|
|
config,
|
|
fields,
|
|
forceNullable: forceNullableObjectType,
|
|
graphqlResult,
|
|
parentName: singularName
|
|
});
|
|
collection.graphQL.paginatedType = buildPaginatedListType(pluralName, collection.graphQL.type);
|
|
collection.graphQL.whereInputType = buildWhereInputType({
|
|
name: singularName,
|
|
fields: whereInputFields,
|
|
parentName: singularName
|
|
});
|
|
const mutationInputFields = [
|
|
...fields
|
|
];
|
|
if (collectionConfig.auth && (!collectionConfig.auth.disableLocalStrategy || typeof collectionConfig.auth.disableLocalStrategy === 'object' && collectionConfig.auth.disableLocalStrategy.optionalPassword)) {
|
|
mutationInputFields.push({
|
|
name: 'password',
|
|
type: 'text',
|
|
label: 'Password',
|
|
required: !(typeof collectionConfig.auth.disableLocalStrategy === 'object' && collectionConfig.auth.disableLocalStrategy.optionalPassword)
|
|
});
|
|
}
|
|
let mutationCreateInputFields = mutationInputFields;
|
|
if (config.db.allowIDOnCreate && !collectionConfig.flattenedFields.some((field)=>field.name === 'id')) {
|
|
mutationCreateInputFields = [
|
|
...mutationCreateInputFields,
|
|
{
|
|
name: 'id',
|
|
type: config.db.defaultIDType
|
|
}
|
|
];
|
|
}
|
|
const createMutationInputType = buildMutationInputType({
|
|
name: singularName,
|
|
config,
|
|
fields: mutationCreateInputFields,
|
|
graphqlResult,
|
|
parentIsLocalized: false,
|
|
parentName: singularName
|
|
});
|
|
if (createMutationInputType) {
|
|
collection.graphQL.mutationInputType = new GraphQLNonNull(createMutationInputType);
|
|
}
|
|
const updateMutationInputType = buildMutationInputType({
|
|
name: `${singularName}Update`,
|
|
config,
|
|
fields: mutationInputFields.filter((field)=>!(fieldAffectsData(field) && field.name === 'id')),
|
|
forceNullable: true,
|
|
graphqlResult,
|
|
parentIsLocalized: false,
|
|
parentName: `${singularName}Update`
|
|
});
|
|
if (updateMutationInputType) {
|
|
collection.graphQL.updateMutationInputType = new GraphQLNonNull(updateMutationInputType);
|
|
}
|
|
const queriesEnabled = typeof collectionConfig.graphQL !== 'object' || !collectionConfig.graphQL.disableQueries;
|
|
const mutationsEnabled = typeof collectionConfig.graphQL !== 'object' || !collectionConfig.graphQL.disableMutations;
|
|
if (queriesEnabled) {
|
|
graphqlResult.Query.fields[singularName] = {
|
|
type: collection.graphQL.type,
|
|
args: {
|
|
id: {
|
|
type: new GraphQLNonNull(idType)
|
|
},
|
|
draft: {
|
|
type: GraphQLBoolean
|
|
},
|
|
...config.localization ? {
|
|
fallbackLocale: {
|
|
type: graphqlResult.types.fallbackLocaleInputType
|
|
},
|
|
locale: {
|
|
type: graphqlResult.types.localeInputType
|
|
}
|
|
} : {},
|
|
select: {
|
|
type: GraphQLBoolean
|
|
},
|
|
trash: {
|
|
type: GraphQLBoolean
|
|
}
|
|
},
|
|
resolve: findByIDResolver(collection)
|
|
};
|
|
graphqlResult.Query.fields[pluralName] = {
|
|
type: buildPaginatedListType(pluralName, collection.graphQL.type),
|
|
args: {
|
|
draft: {
|
|
type: GraphQLBoolean
|
|
},
|
|
where: {
|
|
type: collection.graphQL.whereInputType
|
|
},
|
|
...config.localization ? {
|
|
fallbackLocale: {
|
|
type: graphqlResult.types.fallbackLocaleInputType
|
|
},
|
|
locale: {
|
|
type: graphqlResult.types.localeInputType
|
|
}
|
|
} : {},
|
|
limit: {
|
|
type: GraphQLInt
|
|
},
|
|
page: {
|
|
type: GraphQLInt
|
|
},
|
|
pagination: {
|
|
type: GraphQLBoolean
|
|
},
|
|
select: {
|
|
type: GraphQLBoolean
|
|
},
|
|
sort: {
|
|
type: GraphQLString
|
|
},
|
|
trash: {
|
|
type: GraphQLBoolean
|
|
}
|
|
},
|
|
resolve: findResolver(collection)
|
|
};
|
|
graphqlResult.Query.fields[`count${pluralName}`] = {
|
|
type: new GraphQLObjectType({
|
|
name: `count${pluralName}`,
|
|
fields: {
|
|
totalDocs: {
|
|
type: GraphQLInt
|
|
}
|
|
}
|
|
}),
|
|
args: {
|
|
draft: {
|
|
type: GraphQLBoolean
|
|
},
|
|
trash: {
|
|
type: GraphQLBoolean
|
|
},
|
|
where: {
|
|
type: collection.graphQL.whereInputType
|
|
},
|
|
...config.localization ? {
|
|
locale: {
|
|
type: graphqlResult.types.localeInputType
|
|
}
|
|
} : {}
|
|
},
|
|
resolve: countResolver(collection)
|
|
};
|
|
graphqlResult.Query.fields[`docAccess${singularName}`] = {
|
|
type: buildPolicyType({
|
|
type: 'collection',
|
|
entity: collectionConfig,
|
|
scope: 'docAccess',
|
|
typeSuffix: 'DocAccess'
|
|
}),
|
|
args: {
|
|
id: {
|
|
type: new GraphQLNonNull(idType)
|
|
}
|
|
},
|
|
resolve: docAccessResolver(collection)
|
|
};
|
|
}
|
|
if (mutationsEnabled) {
|
|
graphqlResult.Mutation.fields[`create${singularName}`] = {
|
|
type: collection.graphQL.type,
|
|
args: {
|
|
...createMutationInputType ? {
|
|
data: {
|
|
type: collection.graphQL.mutationInputType
|
|
}
|
|
} : {},
|
|
draft: {
|
|
type: GraphQLBoolean
|
|
},
|
|
...config.localization ? {
|
|
locale: {
|
|
type: graphqlResult.types.localeInputType
|
|
}
|
|
} : {}
|
|
},
|
|
resolve: createResolver(collection)
|
|
};
|
|
graphqlResult.Mutation.fields[`update${singularName}`] = {
|
|
type: collection.graphQL.type,
|
|
args: {
|
|
id: {
|
|
type: new GraphQLNonNull(idType)
|
|
},
|
|
autosave: {
|
|
type: GraphQLBoolean
|
|
},
|
|
...updateMutationInputType ? {
|
|
data: {
|
|
type: collection.graphQL.updateMutationInputType
|
|
}
|
|
} : {},
|
|
draft: {
|
|
type: GraphQLBoolean
|
|
},
|
|
...config.localization ? {
|
|
locale: {
|
|
type: graphqlResult.types.localeInputType
|
|
}
|
|
} : {},
|
|
trash: {
|
|
type: GraphQLBoolean
|
|
}
|
|
},
|
|
resolve: updateResolver(collection)
|
|
};
|
|
graphqlResult.Mutation.fields[`delete${singularName}`] = {
|
|
type: collection.graphQL.type,
|
|
args: {
|
|
id: {
|
|
type: new GraphQLNonNull(idType)
|
|
},
|
|
trash: {
|
|
type: GraphQLBoolean
|
|
}
|
|
},
|
|
resolve: getDeleteResolver(collection)
|
|
};
|
|
if (collectionConfig.disableDuplicate !== true) {
|
|
graphqlResult.Mutation.fields[`duplicate${singularName}`] = {
|
|
type: collection.graphQL.type,
|
|
args: {
|
|
id: {
|
|
type: new GraphQLNonNull(idType)
|
|
},
|
|
...createMutationInputType ? {
|
|
data: {
|
|
type: collection.graphQL.mutationInputType
|
|
}
|
|
} : {}
|
|
},
|
|
resolve: duplicateResolver(collection)
|
|
};
|
|
}
|
|
}
|
|
if (collectionConfig.versions) {
|
|
const versionIDType = config.db.defaultIDType === 'text' ? GraphQLString : GraphQLInt;
|
|
const versionCollectionFields = [
|
|
...buildVersionCollectionFields(config, collectionConfig),
|
|
{
|
|
name: 'id',
|
|
type: config.db.defaultIDType
|
|
},
|
|
{
|
|
name: 'createdAt',
|
|
type: 'date',
|
|
label: ({ t })=>t('general:createdAt')
|
|
},
|
|
{
|
|
name: 'updatedAt',
|
|
type: 'date',
|
|
label: ({ t })=>t('general:updatedAt')
|
|
}
|
|
];
|
|
collection.graphQL.versionType = buildObjectType({
|
|
name: `${singularName}Version`,
|
|
collectionSlug: collectionConfig.slug,
|
|
config,
|
|
fields: versionCollectionFields,
|
|
forceNullable: forceNullableObjectType,
|
|
graphqlResult,
|
|
parentName: `${singularName}Version`
|
|
});
|
|
if (queriesEnabled) {
|
|
graphqlResult.Query.fields[`version${formatName(singularName)}`] = {
|
|
type: collection.graphQL.versionType,
|
|
args: {
|
|
id: {
|
|
type: versionIDType
|
|
},
|
|
...config.localization ? {
|
|
fallbackLocale: {
|
|
type: graphqlResult.types.fallbackLocaleInputType
|
|
},
|
|
locale: {
|
|
type: graphqlResult.types.localeInputType
|
|
}
|
|
} : {},
|
|
trash: {
|
|
type: GraphQLBoolean
|
|
}
|
|
},
|
|
resolve: findVersionByIDResolver(collection)
|
|
};
|
|
graphqlResult.Query.fields[`versions${pluralName}`] = {
|
|
type: buildPaginatedListType(`versions${formatName(pluralName)}`, collection.graphQL.versionType),
|
|
args: {
|
|
where: {
|
|
type: buildWhereInputType({
|
|
name: `versions${singularName}`,
|
|
fields: versionCollectionFields,
|
|
parentName: `versions${singularName}`
|
|
})
|
|
},
|
|
...config.localization ? {
|
|
fallbackLocale: {
|
|
type: graphqlResult.types.fallbackLocaleInputType
|
|
},
|
|
locale: {
|
|
type: graphqlResult.types.localeInputType
|
|
}
|
|
} : {},
|
|
limit: {
|
|
type: GraphQLInt
|
|
},
|
|
page: {
|
|
type: GraphQLInt
|
|
},
|
|
pagination: {
|
|
type: GraphQLBoolean
|
|
},
|
|
select: {
|
|
type: GraphQLBoolean
|
|
},
|
|
sort: {
|
|
type: GraphQLString
|
|
},
|
|
trash: {
|
|
type: GraphQLBoolean
|
|
}
|
|
},
|
|
resolve: findVersionsResolver(collection)
|
|
};
|
|
}
|
|
if (mutationsEnabled) {
|
|
graphqlResult.Mutation.fields[`restoreVersion${formatName(singularName)}`] = {
|
|
type: collection.graphQL.type,
|
|
args: {
|
|
id: {
|
|
type: versionIDType
|
|
},
|
|
draft: {
|
|
type: GraphQLBoolean
|
|
}
|
|
},
|
|
resolve: restoreVersionResolver(collection)
|
|
};
|
|
}
|
|
}
|
|
if (collectionConfig.auth) {
|
|
const authFields = collectionConfig.auth.disableLocalStrategy || collectionConfig.auth.loginWithUsername && !collectionConfig.auth.loginWithUsername.allowEmailLogin && !collectionConfig.auth.loginWithUsername.requireEmail ? [] : [
|
|
{
|
|
name: 'email',
|
|
type: 'email',
|
|
required: true
|
|
}
|
|
];
|
|
collection.graphQL.JWT = buildObjectType({
|
|
name: formatName(`${slug}JWT`),
|
|
config,
|
|
fields: [
|
|
...collectionConfig.fields.filter((field)=>fieldAffectsData(field) && field.saveToJWT),
|
|
...authFields,
|
|
{
|
|
name: 'collection',
|
|
type: 'text',
|
|
required: true
|
|
}
|
|
],
|
|
graphqlResult,
|
|
parentName: formatName(`${slug}JWT`)
|
|
});
|
|
if (queriesEnabled) {
|
|
graphqlResult.Query.fields[`me${singularName}`] = {
|
|
type: new GraphQLObjectType({
|
|
name: formatName(`${slug}Me`),
|
|
fields: {
|
|
collection: {
|
|
type: GraphQLString
|
|
},
|
|
exp: {
|
|
type: GraphQLInt
|
|
},
|
|
strategy: {
|
|
type: GraphQLString
|
|
},
|
|
token: {
|
|
type: GraphQLString
|
|
},
|
|
user: {
|
|
type: collection.graphQL.type
|
|
}
|
|
}
|
|
}),
|
|
resolve: me(collection)
|
|
};
|
|
graphqlResult.Query.fields[`initialized${singularName}`] = {
|
|
type: GraphQLBoolean,
|
|
resolve: init(collection.config.slug)
|
|
};
|
|
}
|
|
if (mutationsEnabled) {
|
|
graphqlResult.Mutation.fields[`refreshToken${singularName}`] = {
|
|
type: new GraphQLObjectType({
|
|
name: formatName(`${slug}Refreshed${singularName}`),
|
|
fields: {
|
|
exp: {
|
|
type: GraphQLInt
|
|
},
|
|
refreshedToken: {
|
|
type: GraphQLString
|
|
},
|
|
strategy: {
|
|
type: GraphQLString
|
|
},
|
|
user: {
|
|
type: collection.graphQL.JWT
|
|
}
|
|
}
|
|
}),
|
|
resolve: refresh(collection)
|
|
};
|
|
graphqlResult.Mutation.fields[`logout${singularName}`] = {
|
|
type: GraphQLString,
|
|
args: {
|
|
allSessions: {
|
|
type: GraphQLBoolean
|
|
}
|
|
},
|
|
resolve: logout(collection)
|
|
};
|
|
if (!collectionConfig.auth.disableLocalStrategy) {
|
|
const authArgs = {};
|
|
const { canLoginWithEmail, canLoginWithUsername } = getLoginOptions(collectionConfig.auth.loginWithUsername);
|
|
if (canLoginWithEmail) {
|
|
authArgs['email'] = {
|
|
type: new GraphQLNonNull(GraphQLString)
|
|
};
|
|
}
|
|
if (canLoginWithUsername) {
|
|
authArgs['username'] = {
|
|
type: new GraphQLNonNull(GraphQLString)
|
|
};
|
|
}
|
|
if (collectionConfig.auth.maxLoginAttempts > 0) {
|
|
graphqlResult.Mutation.fields[`unlock${singularName}`] = {
|
|
type: new GraphQLNonNull(GraphQLBoolean),
|
|
args: authArgs,
|
|
resolve: unlock(collection)
|
|
};
|
|
}
|
|
graphqlResult.Mutation.fields[`login${singularName}`] = {
|
|
type: new GraphQLObjectType({
|
|
name: formatName(`${slug}LoginResult`),
|
|
fields: {
|
|
exp: {
|
|
type: GraphQLInt
|
|
},
|
|
token: {
|
|
type: GraphQLString
|
|
},
|
|
user: {
|
|
type: collection.graphQL.type
|
|
}
|
|
}
|
|
}),
|
|
args: {
|
|
...authArgs,
|
|
password: {
|
|
type: GraphQLString
|
|
}
|
|
},
|
|
resolve: login(collection)
|
|
};
|
|
graphqlResult.Mutation.fields[`forgotPassword${singularName}`] = {
|
|
type: new GraphQLNonNull(GraphQLBoolean),
|
|
args: {
|
|
disableEmail: {
|
|
type: GraphQLBoolean
|
|
},
|
|
expiration: {
|
|
type: GraphQLInt
|
|
},
|
|
...authArgs
|
|
},
|
|
resolve: forgotPassword(collection)
|
|
};
|
|
graphqlResult.Mutation.fields[`resetPassword${singularName}`] = {
|
|
type: new GraphQLObjectType({
|
|
name: formatName(`${slug}ResetPassword`),
|
|
fields: {
|
|
token: {
|
|
type: GraphQLString
|
|
},
|
|
user: {
|
|
type: collection.graphQL.type
|
|
}
|
|
}
|
|
}),
|
|
args: {
|
|
password: {
|
|
type: GraphQLString
|
|
},
|
|
token: {
|
|
type: GraphQLString
|
|
}
|
|
},
|
|
resolve: resetPassword(collection)
|
|
};
|
|
graphqlResult.Mutation.fields[`verifyEmail${singularName}`] = {
|
|
type: GraphQLBoolean,
|
|
args: {
|
|
token: {
|
|
type: GraphQLString
|
|
}
|
|
},
|
|
resolve: verifyEmail(collection)
|
|
};
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
//# sourceMappingURL=initCollections.js.map |