Guest User

Untitled

a guest
Sep 27th, 2018
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.16 KB | None | 0 0
  1. const { ApolloServer, SchemaDirectiveVisitor, gql } = require("apollo-server");
  2. const DataLoader = require("dataloader");
  3. const jwt = require("jsonwebtoken");
  4. const keyBy = require("lodash/keyBy");
  5. const groupBy = require("lodash/groupBy");
  6. const squel = require("squel").useFlavour("postgres");
  7. const pgp = require("pg-promise")();
  8.  
  9. const db = pgp({
  10. host: "localhost",
  11. port: 5432,
  12. user: "",
  13. database: "goodwatch",
  14. password: ""
  15. });
  16.  
  17. const queries = {
  18. register: () => {
  19. return squel
  20. .insert()
  21. .into("users")
  22. .set("is_guest", true)
  23. .returning("*")
  24. .toString();
  25. },
  26. getMe: ({ id }) => {
  27. return squel
  28. .select()
  29. .from("users")
  30. .where("id = ?", id)
  31. .toString();
  32. },
  33. listUsers: () => {
  34. return squel
  35. .select()
  36. .from("users")
  37. .toString();
  38. },
  39. listGoodsByUserId: ({ id }) => {
  40. return squel
  41. .select()
  42. .from("users_goods")
  43. .field("goods.*")
  44. .where("users_goods.user_id = ?", id)
  45. .join("goods", null, "goods.id = users_goods.good_id")
  46. .toString();
  47. },
  48. listUsersGoods: ({ userIds }) => {
  49. return squel
  50. .select()
  51. .from("users_goods")
  52. .field("goods.*")
  53. .field("users_goods.user_id")
  54. .where("user_id IN ?", userIds)
  55. .join("goods", null, "goods.id = users_goods.good_id")
  56. .toString();
  57. },
  58. listUsersSignals: ({ userIds }) => {
  59. return squel
  60. .select()
  61. .from("signals")
  62. .where("user_id IN ?", userIds)
  63. .toString();
  64. },
  65. listGoodsSignals: ({ goodIds }) => {
  66. return squel
  67. .select()
  68. .from("signals")
  69. .where("good_id IN ?", goodIds)
  70. .toString();
  71. },
  72. listReasonsByIds: ({ ids }) => {
  73. return squel
  74. .select()
  75. .from("reasons")
  76. .where("id IN ?", ids)
  77. .toString();
  78. },
  79. getGoodByIdentification: ({ identification }) => {
  80. return squel
  81. .select()
  82. .from("goods")
  83. .where("identification = ?", identification)
  84. .toString();
  85. },
  86. createGood: ({ identification }) => {
  87. return squel
  88. .insert()
  89. .into("goods")
  90. .set("identification", identification)
  91. .returning("*")
  92. .toString();
  93. },
  94. followGood: ({ goodId, userId }) => {
  95. return squel
  96. .insert()
  97. .into("users_goods")
  98. .set("user_id", userId)
  99. .set("good_id", goodId)
  100. .returning("*")
  101. .toString();
  102. }
  103. };
  104.  
  105. const typeDefs = gql`
  106. directive @isAuthenticated on FIELD_DEFINITION
  107.  
  108. type User {
  109. id: Int
  110. token: String
  111. is_guest: Boolean
  112. email: String
  113. password: String
  114. phone: String
  115. goods: [Good]
  116. signals: [Signal]
  117. }
  118. type Good {
  119. id: Int
  120. identification: String
  121. signals: [Signal]
  122. }
  123. type Reason {
  124. id: Int
  125. name: String
  126. }
  127. type Signal {
  128. id: Int
  129. good: Good
  130. reason: Reason
  131. }
  132. type Query {
  133. listMyGoods: [Good] @isAuthenticated
  134. listUsers: [User] @isAuthenticated
  135. getMe: User @isAuthenticated
  136. }
  137. type Mutation {
  138. register: User
  139. login(email: String!, password: String!): User
  140. }
  141. `;
  142.  
  143. const getLoaders = ({ db }) => ({
  144. goodsByUserIdLoader: createGoodsByUserIdLoader({ db }),
  145. signalsByUserIdLoader: createSignalsByUserIdLoader({ db }),
  146. signalsByGoodIdLoader: createSignalsByGoodIdLoader({ db }),
  147. reasonsLoader: createReasonsLoader({ db })
  148. });
  149.  
  150. const createGoodsByUserIdLoader = ({ db }) =>
  151. new DataLoader(async userIds => {
  152. const usersGoods = await db.manyOrNone(queries.listUsersGoods({ userIds }));
  153. const usersGoodsById = groupBy(usersGoods, "user_id");
  154. return userIds.map(id => usersGoodsById[id]);
  155. });
  156.  
  157. const createSignalsByUserIdLoader = ({ db }) =>
  158. new DataLoader(async userIds => {
  159. const usersSignals = await db.manyOrNone(
  160. queries.listUsersSignals({ userIds })
  161. );
  162. const usersSignalsById = groupBy(usersSignals, "user_id");
  163. return userIds.map(id => usersSignalsById[id]);
  164. });
  165.  
  166. const createSignalsByGoodIdLoader = ({ db }) =>
  167. new DataLoader(async goodIds => {
  168. const goodsSignals = await db.manyOrNone(
  169. queries.listGoodsSignals({ goodIds })
  170. );
  171. const goodsSignalsById = groupBy(goodsSignals, "good_id");
  172. return goodIds.map(id => goodsSignalsById[id]);
  173. });
  174.  
  175. const createReasonsLoader = ({ db }) =>
  176. new DataLoader(async ids => {
  177. const reasons = await db.manyOrNone(queries.listReasonsByIds({ ids }));
  178. const reasonsById = keyBy(reasons, "id");
  179. return ids.map(id => reasonsById[id]);
  180. });
  181.  
  182. const resolvers = {
  183. User: {
  184. goods: async (parent, args, context) => {
  185. return context.loaders.goodsByUserIdLoader.load(parent.id);
  186. },
  187. signals: async (parent, args, context) => {
  188. return context.loaders.signalsByUserIdLoader.load(parent.id);
  189. }
  190. },
  191. Signal: {
  192. good: async (parent, args, context) => {
  193. return context.loaders.goodLoader.load(parent.good_id);
  194. },
  195. reason: async (parent, args, context) => {
  196. return context.loaders.reasonsLoader.load(parent.reason_id);
  197. }
  198. },
  199. Good: {
  200. signals: async (parent, args, context) => {
  201. return context.loaders.signalsByGoodIdLoader.load(parent.id);
  202. }
  203. },
  204. Mutation: {
  205. register: async (parent, args) => {
  206. const user = await db.one(queries.register());
  207. return { ...user, token: jwt.sign({ id: user.id }, "123abc") };
  208. },
  209.  
  210. login: async (parent, args) => {
  211. const user = await db.oneOrNone(queries.getUser(args));
  212. return { ...user, token: jwt.sign({ id: user.id }, "123abc") };
  213. }
  214. },
  215. Query: {
  216. listMyGoods: async (parent, args, context) => {
  217. return await db.manyOrNone(
  218. queries.listGoodsByUserId({ id: context.user.id })
  219. );
  220. },
  221. listUsers: async (parent, args, context) => {
  222. return await db.manyOrNone(queries.listUsers());
  223. },
  224. getMe: async (parent, args, context) => {
  225. return await db.one(queries.getMe({ id: context.user.id }));
  226. }
  227. }
  228. };
  229.  
  230. class IsAuthDirective extends SchemaDirectiveVisitor {
  231. visitFieldDefinition(field, details) {
  232. console.log("details", details);
  233.  
  234. const resolver = field.resolve;
  235. field.resolve = async (parent, args, context) => {
  236. const token = context.req.headers.authorization;
  237. if (!token)
  238. throw new Error({
  239. message: "You must supply a JWT for authorization!"
  240. });
  241. try {
  242. const decoded = jwt.verify(token, "123abc");
  243. context.user = decoded;
  244. return resolver(parent, args, context);
  245. } catch (err) {
  246. throw new Error({ message: "Not Authorized" });
  247. }
  248. };
  249. }
  250. }
  251.  
  252. const schemaDirectives = {
  253. isAuthenticated: IsAuthDirective
  254. };
  255.  
  256. const context = ({ req }) => {
  257. return { req, loaders: getLoaders({ db }) };
  258. };
  259.  
  260. const server = new ApolloServer({
  261. typeDefs,
  262. resolvers,
  263. context,
  264. schemaDirectives,
  265. tracing: true
  266. });
  267.  
  268. server.listen().then(({ url }) => {
  269. console.log(`🚀 Server ready at ${url}`);
  270. });
  271.  
  272. /*
  273.  
  274.  
  275. follow: async (parent, args, context) => {
  276. const good = await db.oneOrNone(queries.getGood(args));
  277. if(good) return await db.one(queries.followGood({goodId: good.id, userId: context.user.id}));
  278. return await db.tx(async transaction => {
  279. const good = await transaction.one(queries.createGood(args));
  280. return await transaction.one(queries.followGood({goodId: good.id, userId: context.user.id}));
  281. });
  282. }
  283.  
  284. */
Add Comment
Please, Sign In to add comment