enables User and Upload graphql CRUD

This commit is contained in:
James
2020-04-12 15:54:21 -04:00
parent cfffe52e88
commit 94fd642e5c
10 changed files with 231 additions and 25 deletions

View File

@@ -0,0 +1,100 @@
const {
GraphQLString,
GraphQLNonNull,
GraphQLInt,
} = require('graphql');
const formatName = require('../../graphql/utilities/formatName');
const {
getCreate, getFind, getFindByID, getDelete, getUpdate,
} = require('../../collections/graphql/resolvers');
const buildPaginatedListType = require('../../graphql/schema/buildPaginatedListType');
function registerUser() {
const {
config: {
labels: {
singular,
plural,
},
fields,
},
} = this.User;
const singularLabel = formatName(singular);
const pluralLabel = formatName(plural);
this.User.graphQL = {};
this.User.graphQL.type = this.buildObjectType(
singularLabel,
fields,
singularLabel,
{
id: { type: GraphQLString },
},
);
this.User.graphQL.whereInputType = this.buildWhereInputType(
singularLabel,
fields,
singularLabel,
);
this.User.graphQL.mutationInputType = this.buildMutationInputType(
singularLabel,
fields,
singularLabel,
);
this.Query.fields[singularLabel] = {
type: this.User.graphQL.type,
args: {
id: { type: GraphQLString },
locale: { type: this.types.localeInputType },
fallbackLocale: { type: this.types.fallbackLocaleInputType },
},
resolve: getFindByID(this.config, this.User),
};
this.Query.fields[pluralLabel] = {
type: buildPaginatedListType(pluralLabel, this.User.graphQL.type),
args: {
where: { type: this.User.graphQL.whereInputType },
locale: { type: this.types.localeInputType },
fallbackLocale: { type: this.types.fallbackLocaleInputType },
page: { type: GraphQLInt },
limit: { type: GraphQLInt },
sort: { type: GraphQLString },
},
resolve: getFind(this.config, this.User),
};
this.Mutation.fields[`create${singularLabel}`] = {
type: this.User.graphQL.type,
args: {
data: { type: this.User.graphQL.mutationInputType },
},
resolve: getCreate(this.config, this.User),
};
this.Mutation.fields[`update${singularLabel}`] = {
type: this.User.graphQL.type,
args: {
id: { type: new GraphQLNonNull(GraphQLString) },
data: { type: this.User.graphQL.mutationInputType },
},
resolve: getUpdate(this.config, this.User),
};
this.Mutation.fields[`delete${singularLabel}`] = {
type: this.User.graphQL.type,
args: {
id: { type: new GraphQLNonNull(GraphQLString) },
},
resolve: getDelete(this.User),
};
}
module.exports = registerUser;

View File

@@ -12,20 +12,20 @@ function registerUser() {
this.config.user.fields.push(...baseUserFields);
const userSchema = buildCollectionSchema(this.config.user, this.config);
userSchema.plugin(passportLocalMongoose, { usernameField: this.config.user.auth.useAsUsername });
this.User = mongoose.model(this.config.user.labels.singular, userSchema);
this.User = {
config: this.config.user,
model: mongoose.model(this.config.user.labels.singular, userSchema),
};
passport.use(this.User.createStrategy());
passport.use(jwtStrategy(this.User, this.config));
passport.serializeUser(this.User.serializeUser());
passport.deserializeUser(this.User.deserializeUser());
passport.use(this.User.model.createStrategy());
passport.use(jwtStrategy(this.User.model, this.config));
passport.serializeUser(this.User.model.serializeUser());
passport.deserializeUser(this.User.model.deserializeUser());
passport.use(new AnonymousStrategy.Strategy());
this.router.use(authRoutes(this.config, this.User));
this.router.use(authRoutes(this.config, this.User.model));
this.router.use(collectionRoutes({
model: this.User,
config: this.config.user,
}));
this.router.use(collectionRoutes(this.User));
}
module.exports = registerUser;

View File

@@ -32,7 +32,9 @@ function registerCollections() {
singularLabel,
fields,
singularLabel,
true,
{
id: { type: GraphQLString },
},
);
collection.graphQL.whereInputType = this.buildWhereInputType(

View File

@@ -7,11 +7,15 @@ const buildBlockType = require('./schema/buildBlockType');
const buildLocaleInputType = require('./schema/buildLocaleInputType');
const buildFallbackLocaleInputType = require('./schema/buildFallbackLocaleInputType');
const registerCollections = require('../collections/graphql/register');
const registerUser = require('../auth/graphql/register');
const registerUpload = require('../uploads/graphql/register');
const buildWhereInputType = require('./schema/buildWhereInputType');
class GraphQL {
constructor(config, collections) {
constructor(config, collections, User, Upload) {
this.config = config;
this.User = User;
this.Upload = Upload;
this.collections = collections;
this.init = this.init.bind(this);
@@ -30,10 +34,14 @@ class GraphQL {
this.buildWhereInputType = buildWhereInputType;
this.buildObjectType = buildObjectType.bind(this);
this.registerCollections = registerCollections.bind(this);
this.registerUser = registerUser.bind(this);
this.registerUpload = registerUpload.bind(this);
}
init() {
this.registerCollections();
this.registerUser();
this.registerUpload();
const query = new GraphQLObjectType(this.Query);
const mutation = new GraphQLObjectType(this.Mutation);

View File

@@ -17,7 +17,7 @@ const combineParentName = require('../utilities/combineParentName');
const withNullableType = require('./withNullableType');
const find = require('../../collections/queries/find');
function buildObjectType(name, fields, parentName, addID) {
function buildObjectType(name, fields, parentName, baseFields = {}) {
const fieldToSchemaMap = {
number: field => ({ type: withNullableType(field, GraphQLFloat) }),
text: field => ({ type: withNullableType(field, GraphQLString) }),
@@ -241,9 +241,6 @@ function buildObjectType(name, fields, parentName, addID) {
},
};
const baseFields = {};
if (addID) baseFields.id = { type: GraphQLString };
const objectSchema = {
name,
fields: () => fields.reduce((schema, field) => {

View File

@@ -56,7 +56,7 @@ class Payload {
next();
},
passport.authenticate(['jwt', 'anonymous'], { session: false }),
new GraphQL(this.config, this.collections).init(),
new GraphQL(this.config, this.collections, this.User, this.Upload).init(),
);
}

View File

@@ -0,0 +1,92 @@
const {
GraphQLString,
GraphQLNonNull,
GraphQLInt,
} = require('graphql');
const formatName = require('../../graphql/utilities/formatName');
const {
getCreate, getFind, getFindByID, getDelete, getUpdate,
} = require('../../collections/graphql/resolvers');
const buildPaginatedListType = require('../../graphql/schema/buildPaginatedListType');
function registerUpload() {
const {
config: {
labels: {
singular,
plural,
},
fields,
},
} = this.Upload;
const singularLabel = formatName(singular);
const pluralLabel = formatName(plural);
this.Upload.graphQL = {};
this.Upload.graphQL.type = this.buildObjectType(
singularLabel,
fields,
singularLabel,
{
id: { type: GraphQLString },
},
);
this.Upload.graphQL.whereInputType = this.buildWhereInputType(
singularLabel,
fields,
singularLabel,
);
this.Upload.graphQL.mutationInputType = this.buildMutationInputType(
singularLabel,
fields,
singularLabel,
);
this.Query.fields[singularLabel] = {
type: this.Upload.graphQL.type,
args: {
id: { type: GraphQLString },
locale: { type: this.types.localeInputType },
fallbackLocale: { type: this.types.fallbackLocaleInputType },
},
resolve: getFindByID(this.config, this.Upload),
};
this.Query.fields[pluralLabel] = {
type: buildPaginatedListType(pluralLabel, this.Upload.graphQL.type),
args: {
where: { type: this.Upload.graphQL.whereInputType },
locale: { type: this.types.localeInputType },
fallbackLocale: { type: this.types.fallbackLocaleInputType },
page: { type: GraphQLInt },
limit: { type: GraphQLInt },
sort: { type: GraphQLString },
},
resolve: getFind(this.config, this.Upload),
};
this.Mutation.fields[`update${singularLabel}`] = {
type: this.Upload.graphQL.type,
args: {
id: { type: new GraphQLNonNull(GraphQLString) },
data: { type: this.Upload.graphQL.mutationInputType },
},
resolve: getUpdate(this.config, this.Upload),
};
this.Mutation.fields[`delete${singularLabel}`] = {
type: this.Upload.graphQL.type,
args: {
id: { type: new GraphQLNonNull(GraphQLString) },
},
resolve: getDelete(this.Upload),
};
}
module.exports = registerUpload;

View File

@@ -19,17 +19,17 @@ function registerUpload() {
discriminatorKey: 'type',
});
this.Upload = mongoose.model(this.config.upload.labels.singular, uploadSchema);
this.Upload = {
model: mongoose.model(this.config.upload.labels.singular, uploadSchema),
config: this.config.upload,
};
// TODO: image type hard coded, but in the future we need some way of customizing how uploads are handled in customizable pattern
this.Upload.discriminator('image', imageSchema);
this.Upload.model.discriminator('image', imageSchema);
this.router.use(uploadRoutes(this.config, this.Upload));
this.router.use(collectionRoutes({
model: this.Upload,
config: this.config.upload,
}));
this.router.use(collectionRoutes(this.Upload));
}
module.exports = registerUpload;

View File

@@ -7,12 +7,12 @@ const uploadMiddleware = require('./middleware');
const router = express.Router();
const uploadRoutes = (config, Upload) => {
const { upload: uploadConfig } = config;
const { config: uploadConfig, model } = Upload;
router.all(`/${uploadConfig.slug}*`,
fileUpload(),
passport.authenticate('jwt', { session: false }),
uploadMiddleware(config, Upload));
uploadMiddleware(config, model));
router.route(`/${uploadConfig.slug}`)
.post(