apollo-server-express#ApolloError TypeScript Examples

The following examples show how to use apollo-server-express#ApolloError. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: room-resolver.ts    From convoychat with GNU General Public License v3.0 6 votes vote down vote up
@Authorized()
  @UseMiddleware(RateLimit({ limit: 20 }))
  @Mutation(() => Room)
  async createRoom(@Args() { name }: createRoomArgs, @Ctx() context: Context) {
    try {
      const room = new RoomModel({
        name: name,
        messages: [],
        members: [context.currentUser.id],
        owner: context.currentUser.id,
      });
      await room.populate("members").execPopulate();

      await UserModel.findByIdAndUpdate(
        context.currentUser.id,
        { $addToSet: { rooms: room._id } },
        { new: true }
      );
      const savedRoom = await room.save();

      return savedRoom;
    } catch (err) {
      throw new ApolloError(err);
    }
  }
Example #2
Source File: apollo-server-resolver-adapter.ts    From clean-ts-api with GNU General Public License v3.0 6 votes vote down vote up
adaptResolver = async (controller: Controller, args?: any, context?: any): Promise<any> => {
  const request = {
    ...(args || {}),
    accountId: context?.req?.accountId
  }
  const httpResponse = await controller.handle(request)
  switch (httpResponse.statusCode) {
    case 200:
    case 204: return httpResponse.body
    case 400: throw new UserInputError(httpResponse.body.message)
    case 401: throw new AuthenticationError(httpResponse.body.message)
    case 403: throw new ForbiddenError(httpResponse.body.message)
    default: throw new ApolloError(httpResponse.body.message)
  }
}
Example #3
Source File: CommentStat.resolver.ts    From bouncecode-cms with GNU General Public License v3.0 6 votes vote down vote up
@Query(() => CommentStatObject, {nullable: true})
  async commentStat(@Arg('where') where: CommentStatUniqueWhereInput) {
    try {
      const result = await getRepository(CommentStatEntity)
        .createQueryBuilder('commentStat')
        .where('commentStat.postId = :postId', {
          postId: where.postId,
        })
        .getOne();

      return result;
    } catch (e) {
      console.log(e);
      return new ApolloError(e);
    }
  }
Example #4
Source File: CommentEmotion.resolver.ts    From bouncecode-cms with GNU General Public License v3.0 6 votes vote down vote up
@Query(() => CommentEmotionObject, {nullable: true})
  async commentMyEmotion(
    @Arg('where') where: CommentUniqueWhereInput,
    @Ctx() ctx: Context,
  ) {
    try {
      const userId = ctx.user.id;
      const commentId = where.id;

      const commentEmotion = await getRepository(CommentEmotionEntity)
        .createQueryBuilder('commentEmotion')
        .where('commentEmotion.userId = :userId', {userId})
        .andWhere('commentEmotion.commentId = :commentId', {commentId})
        .getOne();

      return commentEmotion;
    } catch (e) {
      console.log(e);
      return new ApolloError(e);
    }
  }
Example #5
Source File: Comment.resolver.ts    From bouncecode-cms with GNU General Public License v3.0 6 votes vote down vote up
@Mutation(() => CommentObject)
  async commentUpdate(
    @Arg('where') where: CommentUniqueWhereInput,
    @Arg('data') data: CommentUpdateInput,
    @Ctx() ctx: Context,
  ) {
    try {
      const userId = ctx.user.id;

      const comment = await getRepository(CommentEntity)
        .createQueryBuilder('comment')
        .leftJoinAndSelect('comment.user', 'user')
        .getOne();

      if (comment.user.id !== userId) {
        throw new ApolloError('권한이 없습니다.');
      }

      const queryBuilder = await getConnection()
        .createQueryBuilder()
        .update(CommentEntity)
        .set(data)
        .where('id = :id', {id: where.id})
        .returning('*')
        .execute();

      const raw = queryBuilder.raw;

      return raw[0];
    } catch (e) {
      console.log(e);
      return new ApolloError(e);
    }
  }
Example #6
Source File: Comment.resolver.ts    From bouncecode-cms with GNU General Public License v3.0 6 votes vote down vote up
@Mutation(() => CommentObject)
  async commentCreate(
    @Arg('data') data: CommentCreateInput,
    @Ctx() ctx: Context,
  ) {
    try {
      const userId = ctx.user.id;
      const postId = data.postId;

      const raw = await getConnection().transaction(
        async transactionalEntityManager => {
          const queryBuilder = await transactionalEntityManager
            .createQueryBuilder()
            .insert()
            .into(CommentEntity)
            .values([{...data, user: {id: userId}}])
            .execute();

          await transactionalEntityManager
            .createQueryBuilder()
            .insert()
            .into(CommentStatEntity)
            .values([{postId, count: 1}])
            .onConflict(
              `("postId") DO UPDATE SET "count" = comment_stat_entity.count + 1`,
            )
            .execute();

          return queryBuilder.raw;
        },
      );

      return raw[0];
    } catch (e) {
      console.log(e);
      return new ApolloError(e);
    }
  }
Example #7
Source File: Comment.resolver.ts    From bouncecode-cms with GNU General Public License v3.0 6 votes vote down vote up
@Query(() => [CommentObject])
  async comments(
    @Arg('where') where: CommentWhereInput,
    @Arg('skip', () => Int, {nullable: true}) skip: number = 0,
    @Arg('take', () => Int, {nullable: true}) take: number = 10,
  ) {
    try {
      const queryBuilder = getRepository(CommentEntity)
        .createQueryBuilder('comment')
        .leftJoinAndSelect('comment.user', 'user');

      if (where.postId) {
        queryBuilder.andWhere('comment.postId = :postId', {
          postId: where.postId,
        });
      }

      if (where.user?.id) {
        queryBuilder.andWhere('user.userId = :userId', {
          userId: where.user?.id,
        });
      } else if (where.user?.email) {
        queryBuilder.andWhere('user.userEmail = :userEmail', {
          userEmail: where.user?.email,
        });
      }

      const result = await queryBuilder
        .orderBy('comment.id', 'DESC')
        .offset(skip)
        .limit(take)
        .getMany();

      return result;
    } catch (e) {
      console.log(e);
      return new ApolloError(e);
    }
  }
Example #8
Source File: user-resolver.ts    From convoychat with GNU General Public License v3.0 6 votes vote down vote up
@Authorized()
  @UseMiddleware(RateLimit({ limit: 500 }))
  @Mutation(returns => Member)
  async setUserLinks(@Args() links: setUserLinksArgs, @Ctx() context: Context) {
    try {
      const foundUser = await UserModel.findOne({
        _id: context.currentUser.id,
      });
      if (!foundUser) throw new ApolloError("User not found with id");

      const linksToBeUpdated = { ...foundUser.toObject().links, ...links };

      const user = await UserModel.findOneAndUpdate(
        { _id: context.currentUser.id },
        {
          $set: { links: linksToBeUpdated },
        },
        { new: true }
      );
      return user;
    } catch (err) {
      throw new ApolloError(err);
    }
  }
Example #9
Source File: user-resolver.ts    From convoychat with GNU General Public License v3.0 6 votes vote down vote up
@Authorized()
  @UseMiddleware(RateLimit({ limit: 500 }))
  @Mutation(returns => Member)
  async setColor(@Args() { color }: setColorArgs, @Ctx() context: Context) {
    try {
      const user = await UserModel.findOneAndUpdate(
        { _id: context.currentUser.id },
        { color: color },
        { new: true }
      );
      if (!user) throw new ApolloError("User not found with id");
      return user;
    } catch (err) {
      throw new ApolloError(err);
    }
  }
Example #10
Source File: user-resolver.ts    From convoychat with GNU General Public License v3.0 6 votes vote down vote up
@Authorized()
  @Query(() => User)
  async getUser(@Arg("id", { nullable: false }) id: ObjectID): Promise<User> {
    try {
      const user = await UserModel.findOne({ _id: id }).populate("rooms");
      if (!user) throw new ApolloError(`User not found with id ${id}`);
      return user;
    } catch (err) {
      throw new ApolloError(err);
    }
  }
Example #11
Source File: user-resolver.ts    From convoychat with GNU General Public License v3.0 6 votes vote down vote up
@Authorized()
  @Query(() => [Member])
  async listUsers(@Ctx() context: Context): Promise<Member[]> {
    try {
      const users = await UserModel.find({
        _id: { $ne: context.currentUser.id },
      });
      return users;
    } catch (err) {
      throw new ApolloError(err);
    }
  }
Example #12
Source File: room-resolver.ts    From convoychat with GNU General Public License v3.0 6 votes vote down vote up
@Authorized()
  @UseMiddleware(RateLimit())
  @Mutation(() => Member, { nullable: true })
  async removeMemberFromRoom(
    @Args() { roomId, memberId }: removeMembersArgs,
    @Ctx() context: Context
  ): Promise<Member> {
    try {
      if (memberId.equals(context.currentUser.id)) {
        throw new ApolloError("You cannot not remove yourself from room");
      }

      const room = await RoomModel.findOneAndUpdate(
        {
          _id: roomId,
          owner: context.currentUser.id,
        },
        { $pull: { members: memberId } },
        { new: true }
      );

      const removedMember = await UserModel.findOneAndUpdate(
        { _id: memberId },
        { $pull: { rooms: roomId } },
        { new: true }
      );

      if (!removedMember || !room) {
        throw new ApolloError("Could not remove member from room");
      }

      return removedMember;
    } catch (err) {
      throw new ApolloError(err);
    }
  }
Example #13
Source File: room-resolver.ts    From convoychat with GNU General Public License v3.0 6 votes vote down vote up
@Authorized()
  @Mutation(() => Room, { nullable: true })
  async deleteRoom(
    @Arg("roomId", { nullable: false }) roomId: ObjectID,
    @Ctx() context: Context
  ) {
    try {
      const room = await RoomModel.findOneAndDelete({
        _id: roomId,
        owner: context.currentUser.id,
      });

      await UserModel.update(
        { _id: context.currentUser.id },
        {
          $pull: { rooms: { _id: roomId } },
        },
        { new: true, multi: true }
      );

      return room;
    } catch (err) {
      throw new ApolloError(err);
    }
  }
Example #14
Source File: room-resolver.ts    From convoychat with GNU General Public License v3.0 6 votes vote down vote up
@Authorized()
  @Query(() => Room)
  async getRoom(
    @Arg("id", { nullable: false }) id: ObjectID,
    @Ctx() context: Context
  ): Promise<Room> {
    try {
      const user = await RoomModel.findOne({
        _id: id,
        members: { $in: [context.currentUser] },
      })
        .populate("members")
        .populate({
          path: "messages",
          model: "message",
          populate: { path: "author", model: "user" },
        });

      if (!user) throw new ApolloError("Room not found with id");
      return user;
    } catch (err) {
      throw new ApolloError(err);
    }
  }
Example #15
Source File: room-resolver.ts    From convoychat with GNU General Public License v3.0 6 votes vote down vote up
@Authorized()
  @Query(() => [Room])
  async listRooms(): Promise<Room[]> {
    try {
      const rooms = await RoomModel.find({})
        .populate("members")
        .populate({
          path: "messages",
          model: "message",
          populate: { path: "author", model: "user" },
        });

      return rooms;
    } catch (err) {
      throw new ApolloError(err);
    }
  }
Example #16
Source File: GqlResolverExceptions.filter.ts    From amplication with Apache License 2.0 6 votes vote down vote up
catch(exception: Error, host: ArgumentsHost): Error {
    const requestData = this.prepareRequestData(host);
    let clientError: Error;
    /**@todo: Complete the list or expected error codes */
    if (
      exception instanceof Prisma.PrismaClientKnownRequestError &&
      exception.code === PRISMA_CODE_UNIQUE_KEY_VIOLATION
    ) {
      // Convert PrismaClientKnownRequestError to UniqueKeyException and pass the error to the client
      const fields = (exception.meta as { target: string[] }).target;
      clientError = new UniqueKeyException(fields);
      this.logger.info(clientError.message, { requestData });
    } else if (exception instanceof AmplicationError) {
      // Convert AmplicationError to ApolloError and pass the error to the client
      clientError = new ApolloError(exception.message);
      this.logger.info(clientError.message, { requestData });
    } else if (exception instanceof HttpException) {
      // Return HTTP Exceptions to the client
      clientError = exception;
      this.logger.info(clientError.message, { requestData });
    } else {
      // Log the original exception and return a generic server error to client
      // eslint-disable-next-line
      // @ts-ignore
      exception.requestData = requestData;
      this.logger.error(exception);
      clientError =
        this.configService.get('NODE_ENV') === 'production'
          ? new InternalServerError()
          : new ApolloError(exception.message);
    }

    return clientError;
  }
Example #17
Source File: invitation-resolver.ts    From convoychat with GNU General Public License v3.0 6 votes vote down vote up
@Authorized()
  @Query(() => InvitationDetails)
  async getInvitationInfo(
    @Arg("token", { nullable: false }) token: string,
    @Ctx() context: Context
  ) {
    const invite = await InvitationModel.findOne({
      token: token,
    })
      .populate("roomId")
      .populate("invitedBy");

    if (!invite) {
      throw new ApolloError("Could not get invitation info");
    }

    const userid = new ObjectID(context.currentUser.id);
    const currentUserInvite = userid.equals(invite.userId as ObjectId);
    if (!currentUserInvite && !invite.isPublic) {
      throw new ApolloError("Could not get invitation info");
    }

    return {
      id: invite.id,
      room: invite.roomId,
      invitedBy: invite.invitedBy,
      isPublic: invite.isPublic,
      createdAt: invite.createdAt,
    };
  }
Example #18
Source File: message-resolver.ts    From convoychat with GNU General Public License v3.0 6 votes vote down vote up
@Authorized()
  @UseMiddleware(RateLimit({ limit: 1000 }))
  @Mutation(() => Message)
  async deleteMessage(
    @Arg("messageId") messageId: ObjectID,
    @Ctx() context: Context,
    @PubSub() pubsub: PubSubEngine
  ) {
    try {
      const message = await MessageModel.findOneAndDelete({
        _id: messageId,
        author: context.currentUser.id,
      });

      if (!message) throw new ApolloError("Cannot find message with ID");

      await message.populate("author").execPopulate();
      pubsub.publish(CONSTANTS.DELETE_MESSAGE, message.toObject());

      return message;
    } catch (err) {
      throw new ApolloError(err);
    }
  }
Example #19
Source File: message-resolver.ts    From convoychat with GNU General Public License v3.0 6 votes vote down vote up
@Authorized()
  @UseMiddleware(RateLimit({ limit: 2000 }))
  @Mutation(() => Message)
  async editMessage(
    @Args() { messageId, content }: editMessageArgs,
    @Ctx() context: Context,
    @PubSub() pubsub: PubSubEngine
  ) {
    try {
      const message = await MessageModel.findOneAndUpdate(
        {
          _id: messageId,
          author: context.currentUser.id,
        },
        { content: content },
        { new: true }
      );
      if (!message) throw new ApolloError("Cannot find message with ID");

      await message.populate("author").execPopulate();
      pubsub.publish(CONSTANTS.UPDATE_MESSAGE, message.toObject());

      return message;
    } catch (err) {
      throw new ApolloError(err);
    }
  }
Example #20
Source File: notification-resolver.ts    From convoychat with GNU General Public License v3.0 6 votes vote down vote up
@Authorized()
  @Query(() => [Notification])
  async getNotifications(@Ctx() context: Context) {
    try {
      const notifications = await NotificationModel.find({
        receiver: context.currentUser.id,
      })
        .populate("sender")
        .sort({ createdAt: -1 });

      return notifications;
    } catch (err) {
      throw new ApolloError(err);
    }
  }
Example #21
Source File: notification-resolver.ts    From convoychat with GNU General Public License v3.0 6 votes vote down vote up
@Authorized()
  @Mutation(() => Notification)
  async readNotification(
    @Arg("id", { nullable: false }) id: ObjectID,
    @Ctx() context: Context
  ) {
    try {
      const notification = await NotificationModel.findOneAndUpdate(
        { _id: id, receiver: context.currentUser.id },
        { seen: true },
        { new: true }
      )
        .populate("sender")
        .sort({ createdAt: -1 });

      return notification;
    } catch (err) {
      throw new ApolloError(err);
    }
  }
Example #22
Source File: room-resolver.ts    From convoychat with GNU General Public License v3.0 6 votes vote down vote up
@Authorized()
  @Query(() => [Room])
  async listCurrentUserRooms(@Ctx() context: Context): Promise<Room[]> {
    try {
      const rooms = await RoomModel.find({ members: context.currentUser.id })
        .populate("members")
        .populate({
          path: "messages",
          model: "message",
          populate: { path: "author", model: "user" },
        });

      return rooms;
    } catch (err) {
      throw new ApolloError(err);
    }
  }
Example #23
Source File: message-resolver.ts    From convoychat with GNU General Public License v3.0 5 votes vote down vote up
@Authorized()
  @UseMiddleware(RateLimit({ limit: 1000 }))
  @Mutation(() => Message)
  async sendMessage(
    @Args() { roomId, content }: sendMessageArgs,
    @Ctx() context: Context,
    @PubSub() pubsub: PubSubEngine
  ) {
    try {
      const room = await RoomModel.findOne({
        _id: roomId,
        members: { $in: [context.currentUser.id] },
      }).populate("members");

      if (!room) {
        throw new ApolloError(
          "Room not found or you are not a member of this room"
        );
      }

      // parse mentions
      const mentions = parseMentions(content);

      // check if mentioned users are member of the room
      const mentioned_users = mentions
        .map(m => {
          const found = room?.members.find((i: Member) => i.username === m);
          if (found) {
            return (found as any)._id;
          }
          return null;
        })
        // remove null values & current user if mentioned
        .filter(userId => {
          if (!userId) return false;
          return `${userId}` !== `${context.currentUser.id}`;
        });

      const message = new MessageModel({
        content: content,
        roomId: roomId,
        author: context.currentUser.id,
        mentions: mentioned_users,
      });
      message.populate("author").execPopulate();

      // filter out the current User id to prevent self notification sending
      const mentionNotifications = message.mentions.map(async id => {
        return sendNotification({
          context: context,
          sender: context.currentUser.id,
          receiver: id as any,
          type: NOTIFICATION_TYPE.MENTION,
          payload: {
            roomName: room?.name,
            message: message.content,
            messageId: message._id,
            roomId: room?._id,
          },
        });
      });

      await Promise.all(mentionNotifications);

      (message as any).$roomId = roomId;
      const savedMessage = await message.save();
      pubsub.publish(CONSTANTS.NEW_MESSAGE, savedMessage.toObject());

      return savedMessage;
    } catch (err) {
      throw new ApolloError(err);
    }
  }
Example #24
Source File: invitation-resolver.ts    From convoychat with GNU General Public License v3.0 5 votes vote down vote up
@Authorized()
  @Mutation(() => Boolean)
  async acceptInvitation(
    @Arg("token", { nullable: false }) token: string,
    @Ctx() context: Context
  ) {
    // find invitation with token & userId
    const invitation = await InvitationModel.findOne({
      token: token,
    });

    if (!invitation) throw new ApolloError("Invalid Invitation");

    let userToAdd: Ref<User> = null;
    // if invitation is public add the current user
    if (invitation.isPublic === true) {
      userToAdd = context.currentUser.id;
    }

    // if invitation is not public add the invitation.userId
    if (
      invitation.isPublic === false &&
      `${invitation.userId}` === `${context.currentUser.id}`
    ) {
      userToAdd = invitation.userId;
    }

    if (!userToAdd) {
      throw new ApolloError("Something went wrong while accepting invite");
    }

    // throw error and delete the invitation if maximum uses is reached
    if (invitation.uses.length >= invitation.maxUses) {
      await InvitationModel.findOneAndRemove({
        token: token,
      });
      throw new ApolloError("Maximum invitation usage limit exceeded");
    }

    // add user to the room
    const room = await RoomModel.findOneAndUpdate(
      { _id: invitation.roomId },
      { $addToSet: { members: userToAdd } },
      { new: true }
    );

    if (!room) throw new ApolloError("Could not add members to room");

    // update user.rooms
    await UserModel.update(
      { _id: userToAdd },
      { $addToSet: { rooms: room.id } },
      { new: true }
    );

    // delete the notification
    if (!invitation.isPublic) {
      await InvitationModel.findOneAndRemove({ token: token });
    } else {
      await InvitationModel.findOneAndUpdate(
        { token: token },
        { $addToSet: { uses: userToAdd } }
      );
    }

    return true;
  }
Example #25
Source File: invitation-resolver.ts    From convoychat with GNU General Public License v3.0 5 votes vote down vote up
@Authorized()
  @UseMiddleware(RateLimit({ limit: 15 }))
  @Mutation(() => [Invitation])
  async inviteMembers(
    @Args() { roomId, members }: inviteMembersArgs,
    @Ctx() context: Context
  ) {
    try {
      // check if user is a memeber of the specified room
      const user = await UserModel.findOne({
        _id: context.currentUser.id,
        rooms: { $in: [roomId] },
      });

      if (!user) {
        throw new ApolloError(
          "You are not a member of room, Cannot invite members"
        );
      }

      let token = null;

      // create invitations
      const invitations = members.map(memberId => {
        token = crypto.randomBytes(16).toString("hex");
        const invite = new InvitationModel({
          roomId: roomId,
          userId: memberId,
          invitedBy: context.currentUser.id,
          token: token,
        });

        return invite.save();
      });

      // @ts-ignore
      const savedInvites: Invitation[] = await Promise.all(invitations);

      const foundRoom = await RoomModel.findOne({ _id: roomId });

      // send notification
      const notifications = members.map(async (id, index) => {
        return sendNotification({
          context: context,
          sender: context.currentUser.id,
          receiver: id,
          type: NOTIFICATION_TYPE.INVITATION,
          payload: {
            userId: id,
            roomName: foundRoom.name,
            roomId: roomId,
            invitedBy: context.currentUser.id,
            token: savedInvites[index].token,
          },
        });
      });

      await Promise.all(notifications);

      // TODO: Send Email invitations

      return savedInvites;
    } catch (err) {
      console.log(err);
      throw new ApolloError(err);
    }
  }
Example #26
Source File: Comment.resolver.ts    From bouncecode-cms with GNU General Public License v3.0 5 votes vote down vote up
@Mutation(() => Number)
  async commentDelete(
    @Arg('where') where: CommentUniqueWhereInput,
    @Ctx() ctx: Context,
  ) {
    try {
      const userId = ctx.user.id;

      const comment = await getRepository(CommentEntity)
        .createQueryBuilder('comment')
        .leftJoinAndSelect('comment.user', 'user')
        .getOne();
      const postId = comment.postId;

      if (comment.user.id !== userId) {
        throw new ApolloError('권한이 없습니다.');
      }

      const affected = await getConnection().transaction(
        async transactionalEntityManager => {
          const queryBuilder = await getConnection()
            .createQueryBuilder()
            .delete()
            .from(CommentEntity)
            .where('id = :id', {id: where.id})
            .execute();

          await transactionalEntityManager
            .createQueryBuilder()
            .update(CommentStatEntity)
            .set({
              count: () => 'count - 1',
            })
            .where('postId = :postId', {postId: postId})
            .execute();

          return queryBuilder.affected;
        },
      );

      return affected;
    } catch (e) {
      console.log(e);
      return new ApolloError(e);
    }
  }
Example #27
Source File: GqlResolverExceptions.filter.ts    From amplication with Apache License 2.0 5 votes vote down vote up
export class InternalServerError extends ApolloError {
  constructor() {
    super('Internal server error');
  }
}
Example #28
Source File: CommentEmotion.resolver.ts    From bouncecode-cms with GNU General Public License v3.0 5 votes vote down vote up
@Mutation(() => CommentObject)
  async commentEmotion(
    @Arg('where') where: CommentUniqueWhereInput,
    @Arg('data') data: CommentEmotionInput,
    @Ctx() ctx: Context,
  ) {
    try {
      const userId = ctx.user.id;
      const commentId = where.id;
      const emotion = data.emotion;

      const commentEmotion = await getRepository(CommentEmotionEntity)
        .createQueryBuilder('commentEmotion')
        .where('commentEmotion.userId = :userId', {userId})
        .andWhere('commentEmotion.commentId = :commentId', {commentId})
        .getOne();
      const oldEmotion = commentEmotion?.emotion;

      const raw = await getConnection().transaction(
        async transactionalEntityManager => {
          if (commentEmotion) {
            await transactionalEntityManager
              .createQueryBuilder()
              .update(CommentEntity)
              .set({
                [oldEmotion]: () => `comment_entity.${oldEmotion} - 1`,
              })
              .where('id = :commentId', {commentId})
              .execute();
          }

          const queryBuilder = await transactionalEntityManager
            .createQueryBuilder()
            .update(CommentEntity)
            .set({
              [emotion]: () => `comment_entity.${emotion} + 1`,
            })
            .where('id = :commentId', {commentId})
            .returning('*')
            .execute();

          await transactionalEntityManager
            .createQueryBuilder()
            .insert()
            .into(CommentEmotionEntity)
            .values([{commentId, userId, emotion}])
            .onConflict(
              `("commentId", "userId") DO UPDATE SET "emotion" = :emotion`,
            )
            .setParameters({emotion})
            .execute();

          return queryBuilder.raw;
        },
      );

      return raw[0];
    } catch (e) {
      console.log(e);
      return new ApolloError(e);
    }
  }
Example #29
Source File: CommentEmotion.resolver.ts    From bouncecode-cms with GNU General Public License v3.0 5 votes vote down vote up
@Mutation(() => CommentObject)
  async commentEmotionUndo(
    @Arg('where') where: CommentUniqueWhereInput,
    @Ctx() ctx: Context,
  ) {
    try {
      const userId = ctx.user.id;
      const commentId = where.id;

      const commentEmotion = await getRepository(CommentEmotionEntity)
        .createQueryBuilder('commentEmotion')
        .where('commentEmotion.userId = :userId', {userId})
        .andWhere('commentEmotion.commentId = :commentId', {commentId})
        .getOne();
      const oldEmotion = commentEmotion?.emotion;
      if (!commentEmotion) {
        return new ApolloError('선택된 감정이 없습니다.');
      }

      const raw = await getConnection().transaction(
        async transactionalEntityManager => {
          const queryBuilder = await transactionalEntityManager
            .createQueryBuilder()
            .update(CommentEntity)
            .set({
              [oldEmotion]: () => `comment_entity.${oldEmotion} - 1`,
            })
            .where('id = :commentId', {commentId})
            .returning('*')
            .execute();

          await transactionalEntityManager
            .createQueryBuilder()
            .delete()
            .from(CommentEmotionEntity)
            .where('commentId = :commentId', {commentId})
            .andWhere('userId = :userId', {userId})
            .execute();

          return queryBuilder.raw;
        },
      );

      return raw[0];
    } catch (e) {
      console.log(e);
      return new ApolloError(e);
    }
  }