Skip to content

Commit

Permalink
feat: update user and inverse populate
Browse files Browse the repository at this point in the history
  • Loading branch information
gabrielferreiraa committed Dec 21, 2020
1 parent ab1b90a commit 8576629
Show file tree
Hide file tree
Showing 8 changed files with 127 additions and 831 deletions.
18 changes: 0 additions & 18 deletions ecosystem.config.js

This file was deleted.

5 changes: 1 addition & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,9 @@
"graphql": "^15.4.0",
"jsonwebtoken": "^8.5.1",
"lodash.merge": "^4.6.2",
"mongoose": "^5.10.6",
"pm2": "^4.4.1"
"mongoose": "^5.10.6"
},
"scripts": {
"start": "pm2-runtime start ecosystem.config.js",
"dev": "yarn start --watch",
"watch-node": "nodemon src/index.ts",
"build-ts": "tsc",
"watch-ts": "tsc -w",
Expand Down
29 changes: 24 additions & 5 deletions src/graphql/resolvers/postResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,42 @@ import { AuthenticationError } from "apollo-server";
import { Resolvers } from "../../types";
import { Context } from "../../context";

const buildFilters = (args: any) => {
if (!args) return {};

return Object.keys(args).reduce((acc, val) => {
return { ...acc, [val]: args[val] };
}, {});
};

const resolvers: Resolvers<Context> = {
Post: {
isOwner: async (parent, __, ctx) => parent.user.equals(ctx.me?._id),
},
Query: {
posts: async (_: any, __: any, { me, models: { post } }) => {
posts: async (_, args, { me, models: { post } }) => {
if (!me) throw new AuthenticationError("You are not authenticated");

return await post.find().populate("user");
const filters = buildFilters(args.filter);

return await post.find(filters).populate("user");
},
},
Mutation: {
createPost: (_: any, { title, content }, { me, models: { post } }) => {
createPost: async (
_: any,
{ title, content },
{ me, models: { post } }
) => {
if (!me) throw new AuthenticationError("You are not authenticated");

return new post({
const newPost = new post({
title,
content,
user: me._id,
}).save();
});

return await (await newPost.populate("user").save()).execPopulate();
},
deletePost: async (_: any, { id }, { me, models: { post } }) => {
if (!me) throw new AuthenticationError("You are not authenticated");
Expand Down
27 changes: 22 additions & 5 deletions src/graphql/resolvers/userResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,48 @@ import { Context } from "../../context";
import { generateToken } from "../auth";

const resolvers: Resolvers<Context> = {
User: {
posts: async (parent, __, ctx) => {
if (!ctx.me) throw new AuthenticationError("You are not authenticated");

const { models } = ctx;
return await models.post.find({ user: parent._id });
},
},
Query: {
users: async (_: any, __: any, ctx) => {
users: async (_, __, ctx) => {
if (!ctx.me) throw new AuthenticationError("You are not authenticated");

const { models } = ctx;
return await models.user.find().populate("post");
},
user: async (_: any, args, ctx) => {
user: async (_, args, ctx) => {
if (!ctx.me) throw new AuthenticationError("You are not authenticated");

const { models } = ctx;
return await models.user.findOne({ email: args.email });
},
me: async (_: any, __: any, { me }) => {
me: async (_, __, { me }) => {
if (!me) throw new AuthenticationError("You are not authenticated");

return me;
},
},
Mutation: {
async createUser(_: any, args, ctx) {
async createUser(_, args, ctx) {
const { models } = ctx;
return new models.user(args).save();
},
async auth(_: any, args, ctx) {
updateUser: async (_, args, ctx) => {
if (!ctx.me) throw new AuthenticationError("You are not authenticated");

const {
models,
me: { _id },
} = ctx;
return await models.user.findOneAndUpdate({ _id }, args, { new: true });
},
async auth(_, args, ctx) {
const { models } = ctx;
const me = await models.user.findOne({
email: args.email.toLowerCase(),
Expand Down
9 changes: 7 additions & 2 deletions src/graphql/schemas/post.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,18 @@ type Post {
title: String!
content: String!
user: User!
isOwner: Boolean!
}

input PostFilters {
user: ID
}

extend type Query {
posts: [Post!]!
posts(filter: PostFilters): [Post!]!
}

extend type Mutation {
createPost(title: String!, content: String!): Post
createPost(title: String!, content: String!): Post!
deletePost(id: ID!): Post
}
4 changes: 3 additions & 1 deletion src/graphql/schemas/user.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ type User {
name: String!
email: String!
picture: String
posts: [Post!]!
}

extend type Query {
Expand All @@ -21,6 +22,7 @@ extend type Mutation {
password: String!
email: String!
picture: String
): User
): User!
updateUser(name: String!, email: String!, picture: String): User
auth(email: String!, password: String!): Token
}
36 changes: 29 additions & 7 deletions src/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ export type Query = {
};


export type QueryPostsArgs = {
filter?: Maybe<PostFilters>;
};


export type QueryUserArgs = {
email: Scalars['String'];
};
Expand All @@ -34,9 +39,10 @@ export type Mutation = {
__typename?: 'Mutation';
_?: Maybe<Scalars['Boolean']>;
auth?: Maybe<Token>;
createPost?: Maybe<Post>;
createUser?: Maybe<User>;
createPost: Post;
createUser: User;
deletePost?: Maybe<Post>;
updateUser?: Maybe<User>;
};


Expand Down Expand Up @@ -64,12 +70,24 @@ export type MutationDeletePostArgs = {
id: Scalars['ID'];
};


export type MutationUpdateUserArgs = {
name: Scalars['String'];
email: Scalars['String'];
picture?: Maybe<Scalars['String']>;
};

export type Post = {
__typename?: 'Post';
id: Scalars['ID'];
title: Scalars['String'];
content: Scalars['String'];
user: User;
isOwner: Scalars['Boolean'];
};

export type PostFilters = {
user?: Maybe<Scalars['ID']>;
};

export type User = {
Expand All @@ -78,7 +96,7 @@ export type User = {
name: Scalars['String'];
email: Scalars['String'];
picture?: Maybe<Scalars['String']>;
posts: Array<Maybe<Post>>;
posts: Array<Post>;
};

export type Token = {
Expand Down Expand Up @@ -171,6 +189,7 @@ export type ResolversTypes = ResolversObject<{
Mutation: ResolverTypeWrapper<{}>;
ID: ResolverTypeWrapper<Scalars['ID']>;
Post: ResolverTypeWrapper<Post>;
PostFilters: PostFilters;
User: ResolverTypeWrapper<User>;
Token: ResolverTypeWrapper<Token>;
}>;
Expand All @@ -183,31 +202,34 @@ export type ResolversParentTypes = ResolversObject<{
Mutation: {};
ID: Scalars['ID'];
Post: Post;
PostFilters: PostFilters;
User: User;
Token: Token;
}>;

export type QueryResolvers<ContextType = Context, ParentType extends ResolversParentTypes['Query'] = ResolversParentTypes['Query']> = ResolversObject<{
_?: Resolver<Maybe<ResolversTypes['Boolean']>, ParentType, ContextType>;
me?: Resolver<ResolversTypes['User'], ParentType, ContextType>;
posts?: Resolver<Array<ResolversTypes['Post']>, ParentType, ContextType>;
posts?: Resolver<Array<ResolversTypes['Post']>, ParentType, ContextType, RequireFields<QueryPostsArgs, never>>;
user?: Resolver<Maybe<ResolversTypes['User']>, ParentType, ContextType, RequireFields<QueryUserArgs, 'email'>>;
users?: Resolver<Array<ResolversTypes['User']>, ParentType, ContextType>;
}>;

export type MutationResolvers<ContextType = Context, ParentType extends ResolversParentTypes['Mutation'] = ResolversParentTypes['Mutation']> = ResolversObject<{
_?: Resolver<Maybe<ResolversTypes['Boolean']>, ParentType, ContextType>;
auth?: Resolver<Maybe<ResolversTypes['Token']>, ParentType, ContextType, RequireFields<MutationAuthArgs, 'email' | 'password'>>;
createPost?: Resolver<Maybe<ResolversTypes['Post']>, ParentType, ContextType, RequireFields<MutationCreatePostArgs, 'title' | 'content'>>;
createUser?: Resolver<Maybe<ResolversTypes['User']>, ParentType, ContextType, RequireFields<MutationCreateUserArgs, 'name' | 'password' | 'email'>>;
createPost?: Resolver<ResolversTypes['Post'], ParentType, ContextType, RequireFields<MutationCreatePostArgs, 'title' | 'content'>>;
createUser?: Resolver<ResolversTypes['User'], ParentType, ContextType, RequireFields<MutationCreateUserArgs, 'name' | 'password' | 'email'>>;
deletePost?: Resolver<Maybe<ResolversTypes['Post']>, ParentType, ContextType, RequireFields<MutationDeletePostArgs, 'id'>>;
updateUser?: Resolver<Maybe<ResolversTypes['User']>, ParentType, ContextType, RequireFields<MutationUpdateUserArgs, 'name' | 'email'>>;
}>;

export type PostResolvers<ContextType = Context, ParentType extends ResolversParentTypes['Post'] = ResolversParentTypes['Post']> = ResolversObject<{
id?: Resolver<ResolversTypes['ID'], ParentType, ContextType>;
title?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
content?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
user?: Resolver<ResolversTypes['User'], ParentType, ContextType>;
isOwner?: Resolver<ResolversTypes['Boolean'], ParentType, ContextType>;
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
}>;

Expand All @@ -216,7 +238,7 @@ export type UserResolvers<ContextType = Context, ParentType extends ResolversPar
name?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
email?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
picture?: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>;
posts?: Resolver<Array<Maybe<ResolversTypes['Post']>>, ParentType, ContextType>;
posts?: Resolver<Array<ResolversTypes['Post']>, ParentType, ContextType>;
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
}>;

Expand Down
Loading

0 comments on commit 8576629

Please sign in to comment.