Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- const { ApolloServer, SchemaDirectiveVisitor, gql } = require("apollo-server");
- const DataLoader = require("dataloader");
- const jwt = require("jsonwebtoken");
- const keyBy = require("lodash/keyBy");
- const groupBy = require("lodash/groupBy");
- const squel = require("squel").useFlavour("postgres");
- const pgp = require("pg-promise")();
- const db = pgp({
- host: "localhost",
- port: 5432,
- user: "",
- database: "goodwatch",
- password: ""
- });
- const queries = {
- register: () => {
- return squel
- .insert()
- .into("users")
- .set("is_guest", true)
- .returning("*")
- .toString();
- },
- getMe: ({ id }) => {
- return squel
- .select()
- .from("users")
- .where("id = ?", id)
- .toString();
- },
- listUsers: () => {
- return squel
- .select()
- .from("users")
- .toString();
- },
- listGoodsByUserId: ({ id }) => {
- return squel
- .select()
- .from("users_goods")
- .field("goods.*")
- .where("users_goods.user_id = ?", id)
- .join("goods", null, "goods.id = users_goods.good_id")
- .toString();
- },
- listUsersGoods: ({ userIds }) => {
- return squel
- .select()
- .from("users_goods")
- .field("goods.*")
- .field("users_goods.user_id")
- .where("user_id IN ?", userIds)
- .join("goods", null, "goods.id = users_goods.good_id")
- .toString();
- },
- listUsersSignals: ({ userIds }) => {
- return squel
- .select()
- .from("signals")
- .where("user_id IN ?", userIds)
- .toString();
- },
- listGoodsSignals: ({ goodIds }) => {
- return squel
- .select()
- .from("signals")
- .where("good_id IN ?", goodIds)
- .toString();
- },
- listReasonsByIds: ({ ids }) => {
- return squel
- .select()
- .from("reasons")
- .where("id IN ?", ids)
- .toString();
- },
- getGoodByIdentification: ({ identification }) => {
- return squel
- .select()
- .from("goods")
- .where("identification = ?", identification)
- .toString();
- },
- createGood: ({ identification }) => {
- return squel
- .insert()
- .into("goods")
- .set("identification", identification)
- .returning("*")
- .toString();
- },
- followGood: ({ goodId, userId }) => {
- return squel
- .insert()
- .into("users_goods")
- .set("user_id", userId)
- .set("good_id", goodId)
- .returning("*")
- .toString();
- }
- };
- const typeDefs = gql`
- directive @isAuthenticated on FIELD_DEFINITION
- type User {
- id: Int
- token: String
- is_guest: Boolean
- email: String
- password: String
- phone: String
- goods: [Good]
- signals: [Signal]
- }
- type Good {
- id: Int
- identification: String
- signals: [Signal]
- }
- type Reason {
- id: Int
- name: String
- }
- type Signal {
- id: Int
- good: Good
- reason: Reason
- }
- type Query {
- listMyGoods: [Good] @isAuthenticated
- listUsers: [User] @isAuthenticated
- getMe: User @isAuthenticated
- }
- type Mutation {
- register: User
- login(email: String!, password: String!): User
- }
- `;
- const getLoaders = ({ db }) => ({
- goodsByUserIdLoader: createGoodsByUserIdLoader({ db }),
- signalsByUserIdLoader: createSignalsByUserIdLoader({ db }),
- signalsByGoodIdLoader: createSignalsByGoodIdLoader({ db }),
- reasonsLoader: createReasonsLoader({ db })
- });
- const createGoodsByUserIdLoader = ({ db }) =>
- new DataLoader(async userIds => {
- const usersGoods = await db.manyOrNone(queries.listUsersGoods({ userIds }));
- const usersGoodsById = groupBy(usersGoods, "user_id");
- return userIds.map(id => usersGoodsById[id]);
- });
- const createSignalsByUserIdLoader = ({ db }) =>
- new DataLoader(async userIds => {
- const usersSignals = await db.manyOrNone(
- queries.listUsersSignals({ userIds })
- );
- const usersSignalsById = groupBy(usersSignals, "user_id");
- return userIds.map(id => usersSignalsById[id]);
- });
- const createSignalsByGoodIdLoader = ({ db }) =>
- new DataLoader(async goodIds => {
- const goodsSignals = await db.manyOrNone(
- queries.listGoodsSignals({ goodIds })
- );
- const goodsSignalsById = groupBy(goodsSignals, "good_id");
- return goodIds.map(id => goodsSignalsById[id]);
- });
- const createReasonsLoader = ({ db }) =>
- new DataLoader(async ids => {
- const reasons = await db.manyOrNone(queries.listReasonsByIds({ ids }));
- const reasonsById = keyBy(reasons, "id");
- return ids.map(id => reasonsById[id]);
- });
- const resolvers = {
- User: {
- goods: async (parent, args, context) => {
- return context.loaders.goodsByUserIdLoader.load(parent.id);
- },
- signals: async (parent, args, context) => {
- return context.loaders.signalsByUserIdLoader.load(parent.id);
- }
- },
- Signal: {
- good: async (parent, args, context) => {
- return context.loaders.goodLoader.load(parent.good_id);
- },
- reason: async (parent, args, context) => {
- return context.loaders.reasonsLoader.load(parent.reason_id);
- }
- },
- Good: {
- signals: async (parent, args, context) => {
- return context.loaders.signalsByGoodIdLoader.load(parent.id);
- }
- },
- Mutation: {
- register: async (parent, args) => {
- const user = await db.one(queries.register());
- return { ...user, token: jwt.sign({ id: user.id }, "123abc") };
- },
- login: async (parent, args) => {
- const user = await db.oneOrNone(queries.getUser(args));
- return { ...user, token: jwt.sign({ id: user.id }, "123abc") };
- }
- },
- Query: {
- listMyGoods: async (parent, args, context) => {
- return await db.manyOrNone(
- queries.listGoodsByUserId({ id: context.user.id })
- );
- },
- listUsers: async (parent, args, context) => {
- return await db.manyOrNone(queries.listUsers());
- },
- getMe: async (parent, args, context) => {
- return await db.one(queries.getMe({ id: context.user.id }));
- }
- }
- };
- class IsAuthDirective extends SchemaDirectiveVisitor {
- visitFieldDefinition(field, details) {
- console.log("details", details);
- const resolver = field.resolve;
- field.resolve = async (parent, args, context) => {
- const token = context.req.headers.authorization;
- if (!token)
- throw new Error({
- message: "You must supply a JWT for authorization!"
- });
- try {
- const decoded = jwt.verify(token, "123abc");
- context.user = decoded;
- return resolver(parent, args, context);
- } catch (err) {
- throw new Error({ message: "Not Authorized" });
- }
- };
- }
- }
- const schemaDirectives = {
- isAuthenticated: IsAuthDirective
- };
- const context = ({ req }) => {
- return { req, loaders: getLoaders({ db }) };
- };
- const server = new ApolloServer({
- typeDefs,
- resolvers,
- context,
- schemaDirectives,
- tracing: true
- });
- server.listen().then(({ url }) => {
- console.log(`🚀 Server ready at ${url}`);
- });
- /*
- follow: async (parent, args, context) => {
- const good = await db.oneOrNone(queries.getGood(args));
- if(good) return await db.one(queries.followGood({goodId: good.id, userId: context.user.id}));
- return await db.tx(async transaction => {
- const good = await transaction.one(queries.createGood(args));
- return await transaction.one(queries.followGood({goodId: good.id, userId: context.user.id}));
- });
- }
- */
Add Comment
Please, Sign In to add comment