WhatsApp-Clone-Tutorial icon indicating copy to clipboard operation
WhatsApp-Clone-Tutorial copied to clipboard

resolver.ts in Part13/Authentication not compiling

Open idkjs opened this issue 5 years ago • 0 comments

participantId has type any.

The edits look like this example:

const participantId:string = chat.participants.find((p:User) => p !== currentUser.id);

This version of complete file compiles:

import { withFilter } from 'apollo-server-express';
import { DateTimeResolver, URLResolver } from 'graphql-scalars';
import { User, Message, Chat, chats, messages, users } from '../db';
import { Resolvers } from '../types/graphql';
import { secret, expiration } from '../env';
import bcrypt from 'bcrypt';
import jwt from 'jsonwebtoken';
import { validateLength, validatePassword } from '../validators';

const resolvers: Resolvers = {
  Date: DateTimeResolver,
  URL: URLResolver,

  Message: {
    chat(message) {
      return (
        chats.find((c) => c.messages.some((m) => m === message.id)) || null
      );
    },

    sender(message) {
      return users.find((u) => u.id === message.sender) || null;
    },

    recipient(message) {
      return users.find((u) => u.id === message.recipient) || null;
    },

    isMine(message, args, { currentUser }) {
      return message.sender === currentUser.id;
    },
  },

  Chat: {
    name(chat, args, { currentUser }) {
      if (!currentUser) return null;

      const participantId:string = chat.participants.find((p:User) => p !== currentUser.id);

      if (!participantId) return null;

      const participant = users.find((u) => u.id === participantId);

      return participant ? participant.name : null;
    },

    picture(chat, args, { currentUser }) {
      if (!currentUser) return null;

      const participantId:string = chat.participants.find((p:User) => p !== currentUser.id);

      if (!participantId) return null;

      const participant = users.find((u) => u.id === participantId);

      return participant ? participant.picture : null;
    },

    messages(chat) {
      return messages.filter((m) => chat.messages.includes(m.id));
    },

    lastMessage(chat) {
      const lastMessage = chat.messages[chat.messages.length - 1];

      return messages.find((m) => m.id === lastMessage) || null;
    },

    participants(chat) {
      return chat.participants
        .map((p:User) => users.find((u:User) => u.id === p.id))
        .filter(Boolean) as User[];
    },
  },

  Query: {
    me(root, args, { currentUser }) {
      return currentUser || null;
    },
    chats(root, args, { currentUser }) {
      if (!currentUser) return [];

      return chats.filter((c) => c.participants.includes(currentUser.id));
    },

    chat(root, { chatId }, { currentUser }) {
      if (!currentUser) return null;

      const chat = chats.find((c) => c.id === chatId);

      if (!chat) return null;

      return chat.participants.includes(currentUser.id) ? chat : null;
    },

    users(root, args, { currentUser }) {
      if (!currentUser) return [];

      return users.filter((u) => u.id !== currentUser.id);
    },
  },

  Mutation: {
    signIn(root, { username, password }, { res }) {
      const user = users.find((u) => u.username === username);

      if (!user) {
        throw new Error('user not found');
      }

      const passwordsMatch = bcrypt.compareSync(password, user.password);

      if (!passwordsMatch) {
        throw new Error('password is incorrect');
      }

      const authToken = jwt.sign(username, secret);

      res.cookie('authToken', authToken, { maxAge: expiration });

      return user;
    },
    signUp(root, { name, username, password, passwordConfirm }) {
      validateLength('req.name', name, 3, 50);
      validateLength('req.username', username, 3, 18);
      validatePassword('req.password', password);
 
      if (password !== passwordConfirm) {
        throw Error("req.password and req.passwordConfirm don't match");
      }
 
      if (users.some(u => u.username === username)) {
        throw Error('username already exists');
      }
 
      const passwordHash = bcrypt.hashSync(password, bcrypt.genSaltSync(8));
 
      const user: User = {
        id: String(users.length + 1),
        password: passwordHash,
        picture: '',
        username,
        name,
      };
 
      users.push(user);
 
      return user;
    },
    addMessage(root, { chatId, content }, { currentUser, pubsub }) {
      if (!currentUser) return null;

      const chatIndex = chats.findIndex((c) => c.id === chatId);

      if (chatIndex === -1) return null;

      const chat = chats[chatIndex];
      if (!chat.participants.includes(currentUser.id)) return null;

      const messagesIds = messages.map((currentMessage) =>
        Number(currentMessage.id)
      );
      const messageId = String(Math.max(...messagesIds) + 1);
      const message: Message = {
        id: messageId,
        createdAt: new Date(),
        sender: currentUser.id,
        recipient: chat.participants.find(
          (p) => p !== currentUser.id
        ) as string,
        content,
      };

      messages.push(message);
      chat.messages.push(messageId);
      // The chat will appear at the top of the ChatsList component
      chats.splice(chatIndex, 1);
      chats.unshift(chat);

      pubsub.publish('messageAdded', {
        messageAdded: message,
      });

      return message;
    },

    addChat(root, { recipientId }, { currentUser, pubsub }) {
      if (!currentUser) return null;
      if (!users.some((u) => u.id === recipientId)) return null;

      let chat = chats.find(
        (c) =>
          c.participants.includes(currentUser.id) &&
          c.participants.includes(recipientId)
      );

      if (chat) return chat;

      const chatsIds = chats.map((c) => Number(c.id));

      chat = {
        id: String(Math.max(...chatsIds) + 1),
        participants: [currentUser.id, recipientId],
        messages: [],
      };

      chats.push(chat);

      pubsub.publish('chatAdded', {
        chatAdded: chat,
      });

      return chat;
    },

    removeChat(root, { chatId }, { currentUser, pubsub }) {
      if (!currentUser) return null;

      const chatIndex = chats.findIndex((c) => c.id === chatId);

      if (chatIndex === -1) return null;

      const chat = chats[chatIndex];

      if (!chat.participants.some((p) => p === currentUser.id)) return null;

      chat.messages.forEach((chatMessage) => {
        const chatMessageIndex = messages.findIndex(
          (m) => m.id === chatMessage
        );

        if (chatMessageIndex !== -1) {
          messages.splice(chatMessageIndex, 1);
        }
      });

      chats.splice(chatIndex, 1);

      pubsub.publish('chatRemoved', {
        chatRemoved: chat.id,
        targetChat: chat,
      });

      return chatId;
    },
  },

  Subscription: {
    messageAdded: {
      subscribe: withFilter(
        (root, args, { pubsub }) => pubsub.asyncIterator('messageAdded'),
        ({ messageAdded }, args, { currentUser }) => {
          if (!currentUser) return false;

          return [messageAdded.sender, messageAdded.recipient].includes(
            currentUser.id
          );
        }
      ),
    },

    chatAdded: {
      subscribe: withFilter(
        (root, args, { pubsub }) => pubsub.asyncIterator('chatAdded'),
        ({ chatAdded }: { chatAdded: Chat }, args, { currentUser }) => {
          if (!currentUser) return false;

          return chatAdded.participants.some((p) => p === currentUser.id);
        }
      ),
    },

    chatRemoved: {
      subscribe: withFilter(
        (root, args, { pubsub }) => pubsub.asyncIterator('chatRemoved'),
        ({ targetChat }: { targetChat: Chat }, args, { currentUser }) => {
          if (!currentUser) return false;

          return targetChat.participants.some((p) => p === currentUser.id);
        }
      ),
    },
  },
};

export default resolvers;

idkjs avatar May 22 '20 16:05 idkjs