Files
payload/src/collections/graphql/init.ts
2021-12-29 21:32:16 -05:00

318 lines
8.3 KiB
TypeScript

import { DateTimeResolver } from 'graphql-scalars';
import {
GraphQLString,
GraphQLObjectType,
GraphQLBoolean,
GraphQLNonNull,
GraphQLInt,
} from 'graphql';
import formatName from '../../graphql/utilities/formatName';
import buildPaginatedListType from '../../graphql/schema/buildPaginatedListType';
import { BaseFields } from './types';
import { getCollectionIDType } from '../../graphql/schema/buildMutationInputType';
function registerCollections(): void {
const {
create, find, findByID, deleteResolver, update,
} = this.graphQL.resolvers.collections;
const {
login, logout, me, init, refresh, forgotPassword, resetPassword, verifyEmail, unlock,
} = this.graphQL.resolvers.collections.auth;
Object.keys(this.collections).forEach((slug) => {
const collection = this.collections[slug];
const {
config: {
labels: {
singular,
plural,
},
fields,
timestamps,
},
} = collection;
const singularLabel = formatName(singular);
let pluralLabel = formatName(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 (singularLabel === pluralLabel) {
pluralLabel = `all${singularLabel}`;
}
collection.graphQL = {};
const idField = fields.find(({ name }) => name === 'id');
const idType = getCollectionIDType(collection.config);
const baseFields: BaseFields = {};
const whereInputFields = [
...fields,
];
if (!idField) {
baseFields.id = { type: idType };
whereInputFields.push({
name: 'id',
type: 'text',
});
}
if (timestamps) {
baseFields.createdAt = {
type: new GraphQLNonNull(DateTimeResolver),
};
baseFields.updatedAt = {
type: new GraphQLNonNull(DateTimeResolver),
};
whereInputFields.push({
name: 'createdAt',
label: 'Created At',
type: 'date',
});
whereInputFields.push({
name: 'updatedAt',
label: 'Upated At',
type: 'date',
});
}
collection.graphQL.type = this.buildObjectType(
singularLabel,
fields,
singularLabel,
baseFields,
);
collection.graphQL.whereInputType = this.buildWhereInputType(
singularLabel,
whereInputFields,
singularLabel,
);
if (collection.config.auth) {
fields.push({
name: 'password',
label: 'Password',
type: 'text',
required: true,
});
}
collection.graphQL.mutationInputType = new GraphQLNonNull(this.buildMutationInputType(
singularLabel,
fields,
singularLabel,
));
collection.graphQL.updateMutationInputType = new GraphQLNonNull(this.buildMutationInputType(
`${singularLabel}Update`,
fields.filter((field) => field.name !== 'id'),
`${singularLabel}Update`,
true,
));
this.Query.fields[singularLabel] = {
type: collection.graphQL.type,
args: {
id: { type: idType },
...(this.config.localization ? {
locale: { type: this.types.localeInputType },
fallbackLocale: { type: this.types.fallbackLocaleInputType },
} : {}),
},
resolve: findByID(collection),
};
this.Query.fields[pluralLabel] = {
type: buildPaginatedListType(pluralLabel, collection.graphQL.type),
args: {
where: { type: collection.graphQL.whereInputType },
...(this.config.localization ? {
locale: { type: this.types.localeInputType },
fallbackLocale: { type: this.types.fallbackLocaleInputType },
} : {}),
page: { type: GraphQLInt },
limit: { type: GraphQLInt },
sort: { type: GraphQLString },
},
resolve: find(collection),
};
this.Mutation.fields[`create${singularLabel}`] = {
type: collection.graphQL.type,
args: {
data: { type: collection.graphQL.mutationInputType },
autosave: { type: GraphQLBoolean },
},
resolve: create(collection),
};
this.Mutation.fields[`update${singularLabel}`] = {
type: collection.graphQL.type,
args: {
id: { type: new GraphQLNonNull(idType) },
data: { type: collection.graphQL.updateMutationInputType },
autosave: { type: GraphQLBoolean },
},
resolve: update(collection),
};
this.Mutation.fields[`delete${singularLabel}`] = {
type: collection.graphQL.type,
args: {
id: { type: new GraphQLNonNull(idType) },
},
resolve: deleteResolver(collection),
};
if (collection.config.auth) {
collection.graphQL.JWT = this.buildObjectType(
formatName(`${slug}JWT`),
collection.config.fields.filter((field) => field.saveToJWT).concat([
{
name: 'email',
type: 'email',
required: true,
},
{
name: 'collection',
type: 'text',
required: true,
},
]),
formatName(`${slug}JWT`),
);
this.Query.fields[`me${singularLabel}`] = {
type: new GraphQLObjectType({
name: formatName(`${slug}Me`),
fields: {
token: {
type: GraphQLString,
},
user: {
type: collection.graphQL.type,
},
exp: {
type: GraphQLInt,
},
collection: {
type: GraphQLString,
},
},
}),
resolve: me(slug),
};
if (collection.config.auth.maxLoginAttempts > 0) {
this.Mutation.fields[`unlock${singularLabel}`] = {
type: new GraphQLNonNull(GraphQLBoolean),
args: {
email: { type: new GraphQLNonNull(GraphQLString) },
},
resolve: unlock(collection),
};
}
this.Query.fields[`initialized${singularLabel}`] = {
type: GraphQLBoolean,
resolve: init(collection),
};
this.Mutation.fields[`login${singularLabel}`] = {
type: new GraphQLObjectType({
name: formatName(`${slug}LoginResult`),
fields: {
token: {
type: GraphQLString,
},
user: {
type: collection.graphQL.type,
},
exp: {
type: GraphQLInt,
},
},
}),
args: {
email: { type: GraphQLString },
password: { type: GraphQLString },
},
resolve: login(collection),
};
this.Mutation.fields[`logout${singularLabel}`] = {
type: GraphQLString,
resolve: logout(collection),
};
this.Mutation.fields[`forgotPassword${singularLabel}`] = {
type: new GraphQLNonNull(GraphQLBoolean),
args: {
email: { type: new GraphQLNonNull(GraphQLString) },
disableEmail: { type: GraphQLBoolean },
expiration: { type: GraphQLInt },
},
resolve: forgotPassword(collection),
};
this.Mutation.fields[`resetPassword${singularLabel}`] = {
type: new GraphQLObjectType({
name: formatName(`${slug}ResetPassword`),
fields: {
token: { type: GraphQLString },
user: { type: collection.graphQL.type },
},
}),
args: {
token: { type: GraphQLString },
password: { type: GraphQLString },
},
resolve: resetPassword(collection),
};
this.Mutation.fields[`verifyEmail${singularLabel}`] = {
type: GraphQLBoolean,
args: {
token: { type: GraphQLString },
},
resolve: verifyEmail(collection),
};
this.Mutation.fields[`refreshToken${singularLabel}`] = {
type: new GraphQLObjectType({
name: formatName(`${slug}Refreshed${singularLabel}`),
fields: {
user: {
type: collection.graphQL.JWT,
},
refreshedToken: {
type: GraphQLString,
},
exp: {
type: GraphQLInt,
},
},
}),
args: {
token: { type: GraphQLString },
},
resolve: refresh(collection),
};
}
});
}
export default registerCollections;