From ecee3a4828ad201f3cd7ef80c258f1fc5e3aaec6 Mon Sep 17 00:00:00 2001 From: Sriram Patibanda Date: Wed, 31 Mar 2021 17:36:54 +0530 Subject: [PATCH 01/10] Adds graphql event type --- server/schema/event/event.type.js | 46 +++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/server/schema/event/event.type.js b/server/schema/event/event.type.js index e69de29b..8705ce9f 100644 --- a/server/schema/event/event.type.js +++ b/server/schema/event/event.type.js @@ -0,0 +1,46 @@ +/** + * @module app.schema.EventType + * @description User Type + * + * @requires module:app.schema.scalars + * + * @version v1 + * @since 0.1.0 + */ + +const { + GraphQLObjectType, + GraphQLString, + GraphQLSchema, + GraphQLID, + GraphQLList, + GraphQLBoolean, + GraphQLInt, + GraphQLNonNull, + GraphQLDate, + GraphQLTime, + GraphQLDateTime, + GraphQLJSON, + GraphQLJSONObject, +} = require('../scalars'); + +const EventType = new GraphQLObjectType({ + name: 'Event', + fields: () => ({ + id: { type: GraphQLID }, + name: { type: GraphQLString }, + startTS: { type: GraphQLDateTime }, + endTS: { type: GraphQLDateTime }, + poster: { type: GraphQLID }, + type: { type: GraphQLInt }, + host: { type: GraphQLID }, + url: { type: GraphQLString }, + venue: { type: GraphQLString }, + hits: { type: GraphQLInt }, + createdAt: { type: GraphQLID }, + createdBy: { type: GraphQLID }, + updatedAt: { type: GraphQLDateTime }, + updatedBy: { type: GraphQLID }, + schemaVersion: { type: GraphQLInt }, + }), +}); From b246236c254e7b492bf7a90f1a998285031294fb Mon Sep 17 00:00:00 2001 From: Sriram Patibanda Date: Sat, 17 Apr 2021 15:52:48 +0530 Subject: [PATCH 02/10] Adds eventSchema to mergeSchemas --- server/schema/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/schema/index.js b/server/schema/index.js index c2e8c2ca..7946a480 100644 --- a/server/schema/index.js +++ b/server/schema/index.js @@ -13,7 +13,8 @@ const { mergeSchemas } = require('graphql-tools'); const UserSchema = require('./user/user.schema'); +const EventSchema = require('./event/event.schema'); module.exports = mergeSchemas({ - schemas: [UserSchema], + schemas: [UserSchema, EventSchema], }); From ed2b13f099db93d945a0bba83eef18b5cecfc710 Mon Sep 17 00:00:00 2001 From: Sriram Patibanda Date: Sat, 17 Apr 2021 15:55:14 +0530 Subject: [PATCH 03/10] Exports EventType module --- server/schema/event/event.type.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/schema/event/event.type.js b/server/schema/event/event.type.js index 8705ce9f..c00edd0c 100644 --- a/server/schema/event/event.type.js +++ b/server/schema/event/event.type.js @@ -44,3 +44,5 @@ const EventType = new GraphQLObjectType({ schemaVersion: { type: GraphQLInt }, }), }); + +module.exports = EventType; From 9fa0f243f2d958564a1fd1964f9339503e0d4173 Mon Sep 17 00:00:00 2001 From: Sriram Patibanda Date: Sat, 17 Apr 2021 15:56:45 +0530 Subject: [PATCH 04/10] Creates event schema --- server/schema/event/event.schema.js | 34 +++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 server/schema/event/event.schema.js diff --git a/server/schema/event/event.schema.js b/server/schema/event/event.schema.js new file mode 100644 index 00000000..a8daa901 --- /dev/null +++ b/server/schema/event/event.schema.js @@ -0,0 +1,34 @@ +/** + * @module app.schema.Event + * @description Event Schema + * + * @requires module:app.schema.scalars + * @requires module:app.schema.Event Query + * @requires module:app.schema.Event Mutation + * + * @version v1 + * @since 0.1.0 + */ + +const { + // GraphQLObjectType, + // GraphQLString, + GraphQLSchema, + // GraphQLID, + // GraphQLList, + // GraphQLBoolean, + // GraphQLInt, + // GraphQLNonNull, + // GraphQLDate, + // GraphQLTime, + // GraphQLDateTime, + // GraphQLJSON, + // GraphQLJSONObject, +} = require('../scalars'); +const EventMutation = require('./event.mutation'); +const EventQuery = require('./event.query'); + +module.exports = new GraphQLSchema({ + query: EventQuery, + mutation: EventMutation, +}); From bcb46b0cbf278044dc25e153b2c3a39f5529fc47 Mon Sep 17 00:00:00 2001 From: Sriram Patibanda Date: Sat, 17 Apr 2021 15:58:05 +0530 Subject: [PATCH 05/10] Creates graphql queries for events which include getEvent, listEvents and SearchEvents --- server/schema/event/event.query.js | 59 ++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/server/schema/event/event.query.js b/server/schema/event/event.query.js index e69de29b..6931742b 100644 --- a/server/schema/event/event.query.js +++ b/server/schema/event/event.query.js @@ -0,0 +1,59 @@ +/** + * @module app.schema.EventQuery + * @description Event Query + * + * @requires module:app.schema.scalars + * + * @version v1 + * @since 0.1.0 + */ + +const { + GraphQLObjectType, + GraphQLString, + // GraphQLSchema, + GraphQLID, + GraphQLList, + // GraphQLBoolean, + // GraphQLInt, + GraphQLNonNull, + // GraphQLDate, + // GraphQLTime, + // GraphQLDateTime, + // GraphQLJSON, + // GraphQLJSONObject, +} = require('../scalars'); +const EventType = require('./event.type'); +const { getEvent, listEvents, searchEvents } = require('./event.resolver'); + +module.exports = new GraphQLObjectType({ + name: 'EventQuery', + fields: { + getEvent: { + description: 'Retrieves a single event', + type: EventType, + args: { + id: { + type: GraphQLNonNull(GraphQLID), + description: "The event's mongo ID.", + }, + }, + resolve: getEvent, + }, + listEvents: { + type: GraphQLList(EventType), + resolve: listEvents, + }, + searchEvents: { + description: 'Searches a event for keywords', + type: GraphQLList(EventType), + args: { + keywords: { + description: 'The search keywords', + type: new GraphQLNonNull(GraphQLString), + }, + }, + resolve: searchEvents, + }, + }, +}); From 516dd245da25e6d33137abbb8ff3c2c8d01acd15 Mon Sep 17 00:00:00 2001 From: Sriram Patibanda Date: Sat, 17 Apr 2021 15:59:06 +0530 Subject: [PATCH 06/10] Creates graphql mutations for events which include createEvent and updateEvent --- server/schema/event/event.mutation.js | 64 +++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/server/schema/event/event.mutation.js b/server/schema/event/event.mutation.js index e69de29b..7c1f9785 100644 --- a/server/schema/event/event.mutation.js +++ b/server/schema/event/event.mutation.js @@ -0,0 +1,64 @@ +/** + * @module app.schema.EventMutation + * @description Event Mutation + * + * @requires module:app.schema.scalars + * + * @version v1 + * @since 0.1.0 + */ + +const { + GraphQLObjectType, + GraphQLString, + // GraphQLSchema, + GraphQLID, + GraphQLList, + // GraphQLBoolean, + GraphQLInt, + GraphQLNonNull, + // GraphQLDate, + // GraphQLTime, + GraphQLDateTime, + //GraphQLJSON, + GraphQLJSONObject, +} = require('../scalars'); +const { createEvent, updateEvent } = require('./event.resolver'); +const EventType = require('./event.type'); + +module.exports = new GraphQLObjectType({ + name: 'EventMutation', + fields: { + createEvent: { + description: 'Creates an event', + type: EventType, + args: { + name: { type: GraphQLNonNull(GraphQLString) }, + startTS: { type: GraphQLNonNull(GraphQLDateTime) }, + endTS: { type: GraphQLNonNull(GraphQLDateTime) }, + poster: { type: GraphQLID }, + type: { type: GraphQLInt, description: '0- Club, 1- Institute, 2- Fest, 3- Holiday' }, + host: { type: GraphQLID }, + url: { type: GraphQLString }, + venue: { type: GraphQLNonNull(GraphQLString) }, + }, + resolve: createEvent, + }, + updateEvent: { + description: 'Updates a pre-existing event', + type: EventType, + args: { + id:{type: GraphQLID}, + name: { type: GraphQLString }, + startTS: { type: GraphQLDateTime }, + endTS: { type: GraphQLDateTime }, + poster: { type: GraphQLID }, + type: { type: GraphQLInt }, + host: { type: GraphQLID }, + url: { type: GraphQLString }, + venue: { type: GraphQLString }, + }, + resolve: updateEvent, + }, + }, +}); From 5139ff07e6ecba2286fe56da7d8f0b01e0769d07 Mon Sep 17 00:00:00 2001 From: Sriram Patibanda Date: Sat, 17 Apr 2021 16:00:02 +0530 Subject: [PATCH 07/10] Creates resolvers for all the required queries and mutations --- server/schema/event/event.resolver.js | 132 ++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) diff --git a/server/schema/event/event.resolver.js b/server/schema/event/event.resolver.js index e69de29b..60f93d18 100644 --- a/server/schema/event/event.resolver.js +++ b/server/schema/event/event.resolver.js @@ -0,0 +1,132 @@ +/** + * @module app.schema.EventResolver + * @description Event Resolver + * + * @requires module:app.schema.EventType + * @requires module:app.schema.EventModel + * @requires module:app.authorization + * @version v1 + * @since 0.1.0 + */ + +const { GraphQLError, APIError } = require('../../helpers/errorHandler'); +const { Model } = require('mongoose'); + +/** + * @type {Model} + */ +//const { HasPermission } = require('../../helpers/authorization'); +const EventModel = require('./event.model'); + +const DEF_LIMIT = 10; +const DEF_OFFSET = 0; +module.exports = { + getEvent: async (parent, { id }, context, info, _EventModel = EventModel) => { + try { + if (!id) { + return APIError('BAD_REQUEST'); + } + const _event = await _EventModel.findById(id); + if (!_event) { + return APIError('NOT_FOUND'); + } + return _event; + } catch (e) { + if (e instanceof GraphQLError) { + return e; + } + return APIError(null, e); + } + }, + + createEvent: async ( + parent, + { name, startTS, endTS, poster, type, host, url, venue }, + context, + info, + _EventModel = EventModel + ) => { + try { + /** + * stores current DateTime + */ + let date = new Date(); + /** + * Checks if the start time of the event is before the end time of the + * event and if the event is scheduled after the current time. + */ + if (startTS >= endTS || startTS < date.toISOString()) { + return APIError('BAD_REQUEST'); + } + const _event = await _EventModel.create({ + name: name, + startTS: startTS, + endTS: endTS, + poster: poster, + type: type, + host: host, + url: url, + venue: venue, + }); + return _event; + } catch (e) { + if (e instanceof GraphQLError) { + return e; + } + return APIError(null, e); + } + }, + + updateEvent: async ( + parent, + { id, name, startTS, endTS, poster, type, host, url, venue }, + context, + info, + _EventModel = EventModel + ) => { + try { + /** + * The getUpdateObject function returns an object that contains the + * key-value pairs of the event fields that are needed to be updated. + */ + const getUpdateObject = (propertiesObject) => { + /** + * Initialises an empty object that stores the updated fields. + */ + const updateObject = {}; + /** + * The propertiesObject(an object which contains the event fields that + * can be updated) is looped through and only the fields that are + * required to be updated are added to updateObject. + */ + for (key in propertiesObject) { + if (propertiesObject[key]) { + updateObject[key] = propertiesObject[key]; + } + } + + return updateObject; + }; + + const updateEvent = getUpdateObject({ name, startTS, endTS, poster, type, host, url, venue }); + const _event = await _EventModel.findByIdAndUpdate(id, updateEvent); + return _event; + } catch (e) { + if (e instanceof GraphQLError) { + return e; + } + return APIError(null, e); + } + }, + listEvents: async (parent, { limit = DEF_LIMIT, offset = DEF_OFFSET }, context, info, _EventModel = EventModel) => { + try { + const _events = await _EventModel.find().skip(offset).limit(limit); + return _events; + } catch (e) { + if (e instanceof GraphQLError) { + return e; + } + return APIError(null, e); + } + }, +}; From 65bc90ed226e6647b3db582e66fa18e85e292b3b Mon Sep 17 00:00:00 2001 From: Sriram Patibanda Date: Sat, 17 Apr 2021 16:33:03 +0530 Subject: [PATCH 08/10] Comments out unnecessary imports --- server/schema/event/event.mutation.js | 4 ++-- server/schema/event/event.query.js | 2 +- server/schema/event/event.type.js | 16 ++++++++-------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/server/schema/event/event.mutation.js b/server/schema/event/event.mutation.js index 7c1f9785..4f5c8623 100644 --- a/server/schema/event/event.mutation.js +++ b/server/schema/event/event.mutation.js @@ -13,7 +13,7 @@ const { GraphQLString, // GraphQLSchema, GraphQLID, - GraphQLList, + //GraphQLList, // GraphQLBoolean, GraphQLInt, GraphQLNonNull, @@ -21,7 +21,7 @@ const { // GraphQLTime, GraphQLDateTime, //GraphQLJSON, - GraphQLJSONObject, + //GraphQLJSONObject, } = require('../scalars'); const { createEvent, updateEvent } = require('./event.resolver'); const EventType = require('./event.type'); diff --git a/server/schema/event/event.query.js b/server/schema/event/event.query.js index 6931742b..bf67199c 100644 --- a/server/schema/event/event.query.js +++ b/server/schema/event/event.query.js @@ -1,5 +1,5 @@ /** - * @module app.schema.EventQuery + * @module app.schema.EventQuery * @description Event Query * * @requires module:app.schema.scalars diff --git a/server/schema/event/event.type.js b/server/schema/event/event.type.js index c00edd0c..ed777408 100644 --- a/server/schema/event/event.type.js +++ b/server/schema/event/event.type.js @@ -11,17 +11,17 @@ const { GraphQLObjectType, GraphQLString, - GraphQLSchema, + //GraphQLSchema, GraphQLID, - GraphQLList, - GraphQLBoolean, + //GraphQLList, + // GraphQLBoolean, GraphQLInt, - GraphQLNonNull, - GraphQLDate, - GraphQLTime, + // GraphQLNonNull, + // GraphQLDate, + // GraphQLTime, GraphQLDateTime, - GraphQLJSON, - GraphQLJSONObject, + // GraphQLJSON, + // GraphQLJSONObject, } = require('../scalars'); const EventType = new GraphQLObjectType({ From 5a7e2a6f4cc1cee13b48022325d451fb7df9927f Mon Sep 17 00:00:00 2001 From: Sriram Patibanda Date: Fri, 23 Apr 2021 15:47:12 +0530 Subject: [PATCH 09/10] Adds deleteEvent mutation, fixes grammatical errors and error handling for listEvents --- server/schema/event/event.mutation.js | 12 +++++- server/schema/event/event.query.js | 11 ++--- server/schema/event/event.resolver.js | 62 +++++++++++++++++++-------- 3 files changed, 59 insertions(+), 26 deletions(-) diff --git a/server/schema/event/event.mutation.js b/server/schema/event/event.mutation.js index 4f5c8623..ab1aea22 100644 --- a/server/schema/event/event.mutation.js +++ b/server/schema/event/event.mutation.js @@ -23,7 +23,7 @@ const { //GraphQLJSON, //GraphQLJSONObject, } = require('../scalars'); -const { createEvent, updateEvent } = require('./event.resolver'); +const { createEvent, updateEvent, deleteEvent } = require('./event.resolver'); const EventType = require('./event.type'); module.exports = new GraphQLObjectType({ @@ -48,7 +48,7 @@ module.exports = new GraphQLObjectType({ description: 'Updates a pre-existing event', type: EventType, args: { - id:{type: GraphQLID}, + id: { type: GraphQLID }, name: { type: GraphQLString }, startTS: { type: GraphQLDateTime }, endTS: { type: GraphQLDateTime }, @@ -60,5 +60,13 @@ module.exports = new GraphQLObjectType({ }, resolve: updateEvent, }, + deleteEvent: { + description: 'Deletes a pre-existing event using mongo ID', + type: EventType, + args: { + id: { type: GraphQLID }, + }, + resolve: deleteEvent, + }, }, }); diff --git a/server/schema/event/event.query.js b/server/schema/event/event.query.js index bf67199c..164dc853 100644 --- a/server/schema/event/event.query.js +++ b/server/schema/event/event.query.js @@ -1,5 +1,5 @@ /** - * @module app.schema.EventQuery + * @module app.schema.EventQuery * @description Event Query * * @requires module:app.schema.scalars @@ -24,12 +24,12 @@ const { // GraphQLJSONObject, } = require('../scalars'); const EventType = require('./event.type'); -const { getEvent, listEvents, searchEvents } = require('./event.resolver'); +const { getEventByID, listEvents, searchEvents } = require('./event.resolver'); module.exports = new GraphQLObjectType({ name: 'EventQuery', fields: { - getEvent: { + getEventByID: { description: 'Retrieves a single event', type: EventType, args: { @@ -38,14 +38,15 @@ module.exports = new GraphQLObjectType({ description: "The event's mongo ID.", }, }, - resolve: getEvent, + resolve: getEventByID, }, listEvents: { type: GraphQLList(EventType), + description: 'Retrieves a list of all the Events sorted from the lastest to the oldest.', resolve: listEvents, }, searchEvents: { - description: 'Searches a event for keywords', + description: 'Searches a event by keywords', type: GraphQLList(EventType), args: { keywords: { diff --git a/server/schema/event/event.resolver.js b/server/schema/event/event.resolver.js index 60f93d18..dad0486c 100644 --- a/server/schema/event/event.resolver.js +++ b/server/schema/event/event.resolver.js @@ -21,11 +21,8 @@ const EventModel = require('./event.model'); const DEF_LIMIT = 10; const DEF_OFFSET = 0; module.exports = { - getEvent: async (parent, { id }, context, info, _EventModel = EventModel) => { + getEventByID: async (parent, { id }, context, info, _EventModel = EventModel) => { try { - if (!id) { - return APIError('BAD_REQUEST'); - } const _event = await _EventModel.findById(id); if (!_event) { return APIError('NOT_FOUND'); @@ -47,26 +44,22 @@ module.exports = { _EventModel = EventModel ) => { try { - /** - * stores current DateTime - */ - let date = new Date(); /** * Checks if the start time of the event is before the end time of the * event and if the event is scheduled after the current time. */ - if (startTS >= endTS || startTS < date.toISOString()) { + if (new Date(startTS) > new Date(endTS) || new Date(startTS) < Date.now()) { return APIError('BAD_REQUEST'); } const _event = await _EventModel.create({ - name: name, - startTS: startTS, - endTS: endTS, - poster: poster, - type: type, - host: host, - url: url, - venue: venue, + name, + startTS, + endTS, + poster, + type, + host, + url, + venue, }); return _event; } catch (e) { @@ -85,12 +78,17 @@ module.exports = { _EventModel = EventModel ) => { try { + if (!_EventModel.exists(id)) { + return APIError('NOT_FOUND'); + } + + //TODO: Resolver for search events to be written after the approach is finalised. /** * The getUpdateObject function returns an object that contains the * key-value pairs of the event fields that are needed to be updated. */ const getUpdateObject = (propertiesObject) => { - /** + /**propertiesObject * Initialises an empty object that stores the updated fields. */ const updateObject = {}; @@ -120,8 +118,32 @@ module.exports = { }, listEvents: async (parent, { limit = DEF_LIMIT, offset = DEF_OFFSET }, context, info, _EventModel = EventModel) => { try { + /** + * _allEvents is returned when all the events including the old events are + * required in the descending order(mainly for admin pannel) while + * _upcomingEvents is returned when only the upcoming events are + * required in an ascending order (mainly for the client). + */ const _events = await _EventModel.find().skip(offset).limit(limit); - return _events; + const _allEvents = await _EventModel.find().skip(offset).limit(limit).sort({ startTS: 'desc' }); + + const _upcomingEvents = _events.filter((event) => Date.now() < new Date(event.endTS)); + + return _upcomingEvents; + } catch (e) { + if (e instanceof GraphQLError) { + return e; + } + return APIError(null, e); + } + }, + deleteEvent: async (parent, { id }, context, info, _EventModel = EventModel) => { + try { + if (!_EventModel.exists(id)) { + return APIError('NOT_FOUND'); + } + const _event = await _EventModel.findByIdAndDelete(id); + return _event; } catch (e) { if (e instanceof GraphQLError) { return e; @@ -129,4 +151,6 @@ module.exports = { return APIError(null, e); } }, + //TODO: Resolver for search events to be written after the approach is finalised. + searchEvents: async (parent, args, context, info, _EventModel = EventModel) => {}, }; From c430100e688aeb974185fc2bd3c88c8ce5b83d78 Mon Sep 17 00:00:00 2001 From: Sriram Patibanda Date: Fri, 23 Apr 2021 21:22:08 +0530 Subject: [PATCH 10/10] Adds Error handling for deleteEvent and updateEvent --- server/schema/event/event.resolver.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/schema/event/event.resolver.js b/server/schema/event/event.resolver.js index dad0486c..df79824f 100644 --- a/server/schema/event/event.resolver.js +++ b/server/schema/event/event.resolver.js @@ -78,7 +78,7 @@ module.exports = { _EventModel = EventModel ) => { try { - if (!_EventModel.exists(id)) { + if (!(await _EventModel.exists({ id }))) { return APIError('NOT_FOUND'); } @@ -139,7 +139,7 @@ module.exports = { }, deleteEvent: async (parent, { id }, context, info, _EventModel = EventModel) => { try { - if (!_EventModel.exists(id)) { + if (!(await _EventModel.exists({ id }))) { return APIError('NOT_FOUND'); } const _event = await _EventModel.findByIdAndDelete(id);