diff options
Diffstat (limited to 'finished-application/backend/src')
| -rw-r--r-- | finished-application/backend/src/createServer.js | 8 | ||||
| -rw-r--r-- | finished-application/backend/src/db.js | 9 | ||||
| -rw-r--r-- | finished-application/backend/src/generated/prisma.graphql | 549 | ||||
| -rw-r--r-- | finished-application/backend/src/index.js | 18 | ||||
| -rw-r--r-- | finished-application/backend/src/mail.js | 14 | ||||
| -rw-r--r-- | finished-application/backend/src/resolvers/Mutation.js | 380 | ||||
| -rw-r--r-- | finished-application/backend/src/resolvers/Query.js | 65 | ||||
| -rw-r--r-- | finished-application/backend/src/schema.graphql | 40 |
8 files changed, 398 insertions, 685 deletions
diff --git a/finished-application/backend/src/createServer.js b/finished-application/backend/src/createServer.js index 036d15a..c552b02 100644 --- a/finished-application/backend/src/createServer.js +++ b/finished-application/backend/src/createServer.js @@ -3,16 +3,18 @@ const Mutation = require('./resolvers/Mutation'); const Query = require('./resolvers/Query'); const db = require('./db'); +// Create the GraphQL Yoga Server + function createServer() { return new GraphQLServer({ typeDefs: 'src/schema.graphql', - resolverValidationOptions: { - requireResolversForResolveType: false, - }, resolvers: { Mutation, Query, }, + resolverValidationOptions: { + requireResolversForResolveType: false, + }, context: req => ({ ...req, db }), }); } diff --git a/finished-application/backend/src/db.js b/finished-application/backend/src/db.js index e8caa14..8f66240 100644 --- a/finished-application/backend/src/db.js +++ b/finished-application/backend/src/db.js @@ -1,10 +1,11 @@ +// This file connects to the remote prisma DB and gives us the ability to query it with JS const { Prisma } = require('prisma-binding'); const db = new Prisma({ typeDefs: 'src/generated/prisma.graphql', - endpoint: process.env.PRISMA_ENDPOINT, // the endpoint of the Prisma DB service (value is set in variables.env) - secret: process.env.PRISMA_SECRET, // taken from prisma/prisma.yml (value is set in .env) - debug: false, // log all GraphQL queries & mutations + endpoint: process.env.PRISMA_ENDPOINT, + secret: process.env.PRISMA_SECRET, + debug: false, }); -module.exports = db;
\ No newline at end of file +module.exports = db; diff --git a/finished-application/backend/src/generated/prisma.graphql b/finished-application/backend/src/generated/prisma.graphql index 64f39a4..cc13ecf 100644 --- a/finished-application/backend/src/generated/prisma.graphql +++ b/finished-application/backend/src/generated/prisma.graphql @@ -1,5 +1,5 @@ -# source: https://us1.prisma.sh/wesbos/sick-fits/dev -# timestamp: Thu Jun 21 2018 15:13:13 GMT-0400 (EDT) +# source: https://us1.prisma.sh/wesbos/siccccccccck-fits/dev +# timestamp: Tue Sep 11 2018 16:26:22 GMT-0400 (EDT) type AggregateCartItem { count: Int! @@ -31,8 +31,6 @@ type CartItem implements Node { quantity: Int! item(where: ItemWhereInput): Item user(where: UserWhereInput): User! - createdAt: DateTime! - updatedAt: DateTime! } """A connection to a list of items.""" @@ -75,17 +73,15 @@ enum CartItemOrderByInput { id_DESC quantity_ASC quantity_DESC - createdAt_ASC - createdAt_DESC updatedAt_ASC updatedAt_DESC + createdAt_ASC + createdAt_DESC } type CartItemPreviousValues { id: ID! quantity: Int! - createdAt: DateTime! - updatedAt: DateTime! } type CartItemSubscriptionPayload { @@ -130,7 +126,7 @@ input CartItemSubscriptionWhereInput { input CartItemUpdateInput { quantity: Int item: ItemUpdateOneInput - user: UserUpdateOneWithoutCartInput + user: UserUpdateOneRequiredWithoutCartInput } input CartItemUpdateManyWithoutUserInput { @@ -229,50 +225,6 @@ input CartItemWhereInput { """All values greater than or equal the given value.""" quantity_gte: Int - createdAt: DateTime - - """All values that are not equal to given value.""" - createdAt_not: DateTime - - """All values that are contained in given list.""" - createdAt_in: [DateTime!] - - """All values that are not contained in given list.""" - createdAt_not_in: [DateTime!] - - """All values less than the given value.""" - createdAt_lt: DateTime - - """All values less than or equal the given value.""" - createdAt_lte: DateTime - - """All values greater than the given value.""" - createdAt_gt: DateTime - - """All values greater than or equal the given value.""" - createdAt_gte: DateTime - updatedAt: DateTime - - """All values that are not equal to given value.""" - updatedAt_not: DateTime - - """All values that are contained in given list.""" - updatedAt_in: [DateTime!] - - """All values that are not contained in given list.""" - updatedAt_not_in: [DateTime!] - - """All values less than the given value.""" - updatedAt_lt: DateTime - - """All values less than or equal the given value.""" - updatedAt_lte: DateTime - - """All values greater than the given value.""" - updatedAt_gt: DateTime - - """All values greater than or equal the given value.""" - updatedAt_gte: DateTime item: ItemWhereInput user: UserWhereInput } @@ -290,8 +242,6 @@ type Item implements Node { image: String largeImage: String price: Int! - createdAt: DateTime! - updatedAt: DateTime! user(where: UserWhereInput): User! } @@ -341,10 +291,10 @@ enum ItemOrderByInput { largeImage_DESC price_ASC price_DESC - createdAt_ASC - createdAt_DESC updatedAt_ASC updatedAt_DESC + createdAt_ASC + createdAt_DESC } type ItemPreviousValues { @@ -354,8 +304,6 @@ type ItemPreviousValues { image: String largeImage: String price: Int! - createdAt: DateTime! - updatedAt: DateTime! } type ItemSubscriptionPayload { @@ -403,7 +351,7 @@ input ItemUpdateDataInput { image: String largeImage: String price: Int - user: UserUpdateOneInput + user: UserUpdateOneRequiredInput } input ItemUpdateInput { @@ -412,7 +360,7 @@ input ItemUpdateInput { image: String largeImage: String price: Int - user: UserUpdateOneInput + user: UserUpdateOneRequiredInput } input ItemUpdateOneInput { @@ -660,54 +608,7 @@ input ItemWhereInput { """All values greater than or equal the given value.""" price_gte: Int - createdAt: DateTime - - """All values that are not equal to given value.""" - createdAt_not: DateTime - - """All values that are contained in given list.""" - createdAt_in: [DateTime!] - - """All values that are not contained in given list.""" - createdAt_not_in: [DateTime!] - - """All values less than the given value.""" - createdAt_lt: DateTime - - """All values less than or equal the given value.""" - createdAt_lte: DateTime - - """All values greater than the given value.""" - createdAt_gt: DateTime - - """All values greater than or equal the given value.""" - createdAt_gte: DateTime - updatedAt: DateTime - - """All values that are not equal to given value.""" - updatedAt_not: DateTime - - """All values that are contained in given list.""" - updatedAt_in: [DateTime!] - - """All values that are not contained in given list.""" - updatedAt_not_in: [DateTime!] - - """All values less than the given value.""" - updatedAt_lt: DateTime - - """All values less than or equal the given value.""" - updatedAt_lte: DateTime - - """All values greater than the given value.""" - updatedAt_gt: DateTime - - """All values greater than or equal the given value.""" - updatedAt_gte: DateTime user: UserWhereInput - _MagicalBackRelation_CartItemToItem_every: CartItemWhereInput - _MagicalBackRelation_CartItemToItem_some: CartItemWhereInput - _MagicalBackRelation_CartItemToItem_none: CartItemWhereInput } input ItemWhereUniqueInput { @@ -723,34 +624,34 @@ scalar Long type Mutation { createCartItem(data: CartItemCreateInput!): CartItem! createOrder(data: OrderCreateInput!): Order! - createUser(data: UserCreateInput!): User! createItem(data: ItemCreateInput!): Item! createOrderItem(data: OrderItemCreateInput!): OrderItem! + createUser(data: UserCreateInput!): User! updateCartItem(data: CartItemUpdateInput!, where: CartItemWhereUniqueInput!): CartItem updateOrder(data: OrderUpdateInput!, where: OrderWhereUniqueInput!): Order - updateUser(data: UserUpdateInput!, where: UserWhereUniqueInput!): User updateItem(data: ItemUpdateInput!, where: ItemWhereUniqueInput!): Item updateOrderItem(data: OrderItemUpdateInput!, where: OrderItemWhereUniqueInput!): OrderItem + updateUser(data: UserUpdateInput!, where: UserWhereUniqueInput!): User deleteCartItem(where: CartItemWhereUniqueInput!): CartItem deleteOrder(where: OrderWhereUniqueInput!): Order - deleteUser(where: UserWhereUniqueInput!): User deleteItem(where: ItemWhereUniqueInput!): Item deleteOrderItem(where: OrderItemWhereUniqueInput!): OrderItem + deleteUser(where: UserWhereUniqueInput!): User upsertCartItem(where: CartItemWhereUniqueInput!, create: CartItemCreateInput!, update: CartItemUpdateInput!): CartItem! upsertOrder(where: OrderWhereUniqueInput!, create: OrderCreateInput!, update: OrderUpdateInput!): Order! - upsertUser(where: UserWhereUniqueInput!, create: UserCreateInput!, update: UserUpdateInput!): User! upsertItem(where: ItemWhereUniqueInput!, create: ItemCreateInput!, update: ItemUpdateInput!): Item! upsertOrderItem(where: OrderItemWhereUniqueInput!, create: OrderItemCreateInput!, update: OrderItemUpdateInput!): OrderItem! + upsertUser(where: UserWhereUniqueInput!, create: UserCreateInput!, update: UserUpdateInput!): User! updateManyCartItems(data: CartItemUpdateInput!, where: CartItemWhereInput): BatchPayload! updateManyOrders(data: OrderUpdateInput!, where: OrderWhereInput): BatchPayload! - updateManyUsers(data: UserUpdateInput!, where: UserWhereInput): BatchPayload! updateManyItems(data: ItemUpdateInput!, where: ItemWhereInput): BatchPayload! updateManyOrderItems(data: OrderItemUpdateInput!, where: OrderItemWhereInput): BatchPayload! + updateManyUsers(data: UserUpdateInput!, where: UserWhereInput): BatchPayload! deleteManyCartItems(where: CartItemWhereInput): BatchPayload! deleteManyOrders(where: OrderWhereInput): BatchPayload! - deleteManyUsers(where: UserWhereInput): BatchPayload! deleteManyItems(where: ItemWhereInput): BatchPayload! deleteManyOrderItems(where: OrderItemWhereInput): BatchPayload! + deleteManyUsers(where: UserWhereInput): BatchPayload! } enum MutationType { @@ -770,9 +671,9 @@ type Order implements Node { items(where: OrderItemWhereInput, orderBy: OrderItemOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [OrderItem!] total: Int! user(where: UserWhereInput): User! + charge: String! createdAt: DateTime! updatedAt: DateTime! - charge: String! } """A connection to a list of items.""" @@ -789,18 +690,7 @@ input OrderCreateInput { total: Int! charge: String! items: OrderItemCreateManyInput - user: UserCreateOneWithoutOrdersInput! -} - -input OrderCreateManyWithoutUserInput { - create: [OrderCreateWithoutUserInput!] - connect: [OrderWhereUniqueInput!] -} - -input OrderCreateWithoutUserInput { - total: Int! - charge: String! - items: OrderItemCreateManyInput + user: UserCreateOneInput! } """An edge in a connection.""" @@ -816,11 +706,9 @@ type OrderItem implements Node { id: ID! title: String! description: String! - image: String - largeImage: String + image: String! + largeImage: String! price: Int! - createdAt: DateTime! - updatedAt: DateTime! quantity: Int! user(where: UserWhereInput): User } @@ -838,8 +726,8 @@ type OrderItemConnection { input OrderItemCreateInput { title: String! description: String! - image: String - largeImage: String + image: String! + largeImage: String! price: Int! quantity: Int user: UserCreateOneInput @@ -872,23 +760,21 @@ enum OrderItemOrderByInput { largeImage_DESC price_ASC price_DESC - createdAt_ASC - createdAt_DESC - updatedAt_ASC - updatedAt_DESC quantity_ASC quantity_DESC + updatedAt_ASC + updatedAt_DESC + createdAt_ASC + createdAt_DESC } type OrderItemPreviousValues { id: ID! title: String! description: String! - image: String - largeImage: String + image: String! + largeImage: String! price: Int! - createdAt: DateTime! - updatedAt: DateTime! quantity: Int! } @@ -1202,50 +1088,6 @@ input OrderItemWhereInput { """All values greater than or equal the given value.""" price_gte: Int - createdAt: DateTime - - """All values that are not equal to given value.""" - createdAt_not: DateTime - - """All values that are contained in given list.""" - createdAt_in: [DateTime!] - - """All values that are not contained in given list.""" - createdAt_not_in: [DateTime!] - - """All values less than the given value.""" - createdAt_lt: DateTime - - """All values less than or equal the given value.""" - createdAt_lte: DateTime - - """All values greater than the given value.""" - createdAt_gt: DateTime - - """All values greater than or equal the given value.""" - createdAt_gte: DateTime - updatedAt: DateTime - - """All values that are not equal to given value.""" - updatedAt_not: DateTime - - """All values that are contained in given list.""" - updatedAt_in: [DateTime!] - - """All values that are not contained in given list.""" - updatedAt_not_in: [DateTime!] - - """All values less than the given value.""" - updatedAt_lt: DateTime - - """All values less than or equal the given value.""" - updatedAt_lte: DateTime - - """All values greater than the given value.""" - updatedAt_gt: DateTime - - """All values greater than or equal the given value.""" - updatedAt_gte: DateTime quantity: Int """All values that are not equal to given value.""" @@ -1269,9 +1111,6 @@ input OrderItemWhereInput { """All values greater than or equal the given value.""" quantity_gte: Int user: UserWhereInput - _MagicalBackRelation_OrderToOrderItem_every: OrderWhereInput - _MagicalBackRelation_OrderToOrderItem_some: OrderWhereInput - _MagicalBackRelation_OrderToOrderItem_none: OrderWhereInput } input OrderItemWhereUniqueInput { @@ -1283,20 +1122,20 @@ enum OrderOrderByInput { id_DESC total_ASC total_DESC + charge_ASC + charge_DESC createdAt_ASC createdAt_DESC updatedAt_ASC updatedAt_DESC - charge_ASC - charge_DESC } type OrderPreviousValues { id: ID! total: Int! + charge: String! createdAt: DateTime! updatedAt: DateTime! - charge: String! } type OrderSubscriptionPayload { @@ -1342,33 +1181,7 @@ input OrderUpdateInput { total: Int charge: String items: OrderItemUpdateManyInput - user: UserUpdateOneWithoutOrdersInput -} - -input OrderUpdateManyWithoutUserInput { - create: [OrderCreateWithoutUserInput!] - connect: [OrderWhereUniqueInput!] - disconnect: [OrderWhereUniqueInput!] - delete: [OrderWhereUniqueInput!] - update: [OrderUpdateWithWhereUniqueWithoutUserInput!] - upsert: [OrderUpsertWithWhereUniqueWithoutUserInput!] -} - -input OrderUpdateWithoutUserDataInput { - total: Int - charge: String - items: OrderItemUpdateManyInput -} - -input OrderUpdateWithWhereUniqueWithoutUserInput { - where: OrderWhereUniqueInput! - data: OrderUpdateWithoutUserDataInput! -} - -input OrderUpsertWithWhereUniqueWithoutUserInput { - where: OrderWhereUniqueInput! - update: OrderUpdateWithoutUserDataInput! - create: OrderCreateWithoutUserInput! + user: UserUpdateOneRequiredInput } input OrderWhereInput { @@ -1442,6 +1255,46 @@ input OrderWhereInput { """All values greater than or equal the given value.""" total_gte: Int + charge: String + + """All values that are not equal to given value.""" + charge_not: String + + """All values that are contained in given list.""" + charge_in: [String!] + + """All values that are not contained in given list.""" + charge_not_in: [String!] + + """All values less than the given value.""" + charge_lt: String + + """All values less than or equal the given value.""" + charge_lte: String + + """All values greater than the given value.""" + charge_gt: String + + """All values greater than or equal the given value.""" + charge_gte: String + + """All values containing the given string.""" + charge_contains: String + + """All values not containing the given string.""" + charge_not_contains: String + + """All values starting with the given string.""" + charge_starts_with: String + + """All values not starting with the given string.""" + charge_not_starts_with: String + + """All values ending with the given string.""" + charge_ends_with: String + + """All values not ending with the given string.""" + charge_not_ends_with: String createdAt: DateTime """All values that are not equal to given value.""" @@ -1486,46 +1339,6 @@ input OrderWhereInput { """All values greater than or equal the given value.""" updatedAt_gte: DateTime - charge: String - - """All values that are not equal to given value.""" - charge_not: String - - """All values that are contained in given list.""" - charge_in: [String!] - - """All values that are not contained in given list.""" - charge_not_in: [String!] - - """All values less than the given value.""" - charge_lt: String - - """All values less than or equal the given value.""" - charge_lte: String - - """All values greater than the given value.""" - charge_gt: String - - """All values greater than or equal the given value.""" - charge_gte: String - - """All values containing the given string.""" - charge_contains: String - - """All values not containing the given string.""" - charge_not_contains: String - - """All values starting with the given string.""" - charge_starts_with: String - - """All values not starting with the given string.""" - charge_not_starts_with: String - - """All values ending with the given string.""" - charge_ends_with: String - - """All values not ending with the given string.""" - charge_not_ends_with: String items_every: OrderItemWhereInput items_some: OrderItemWhereInput items_none: OrderItemWhereInput @@ -1563,19 +1376,19 @@ enum Permission { type Query { cartItems(where: CartItemWhereInput, orderBy: CartItemOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [CartItem]! orders(where: OrderWhereInput, orderBy: OrderOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [Order]! - users(where: UserWhereInput, orderBy: UserOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [User]! items(where: ItemWhereInput, orderBy: ItemOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [Item]! orderItems(where: OrderItemWhereInput, orderBy: OrderItemOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [OrderItem]! + users(where: UserWhereInput, orderBy: UserOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [User]! cartItem(where: CartItemWhereUniqueInput!): CartItem order(where: OrderWhereUniqueInput!): Order - user(where: UserWhereUniqueInput!): User item(where: ItemWhereUniqueInput!): Item orderItem(where: OrderItemWhereUniqueInput!): OrderItem + user(where: UserWhereUniqueInput!): User cartItemsConnection(where: CartItemWhereInput, orderBy: CartItemOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): CartItemConnection! ordersConnection(where: OrderWhereInput, orderBy: OrderOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): OrderConnection! - usersConnection(where: UserWhereInput, orderBy: UserOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): UserConnection! itemsConnection(where: ItemWhereInput, orderBy: ItemOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): ItemConnection! orderItemsConnection(where: OrderItemWhereInput, orderBy: OrderItemOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): OrderItemConnection! + usersConnection(where: UserWhereInput, orderBy: UserOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): UserConnection! """Fetches an object given its ID""" node( @@ -1587,23 +1400,20 @@ type Query { type Subscription { cartItem(where: CartItemSubscriptionWhereInput): CartItemSubscriptionPayload order(where: OrderSubscriptionWhereInput): OrderSubscriptionPayload - user(where: UserSubscriptionWhereInput): UserSubscriptionPayload item(where: ItemSubscriptionWhereInput): ItemSubscriptionPayload orderItem(where: OrderItemSubscriptionWhereInput): OrderItemSubscriptionPayload + user(where: UserSubscriptionWhereInput): UserSubscriptionPayload } type User implements Node { id: ID! + name: String! email: String! password: String! - name: String! - orders(where: OrderWhereInput, orderBy: OrderOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [Order!] resetToken: String resetTokenExpiry: String - cart(where: CartItemWhereInput, orderBy: CartItemOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [CartItem!] - createdAt: DateTime! - updatedAt: DateTime! permissions: [Permission!]! + cart(where: CartItemWhereInput, orderBy: CartItemOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [CartItem!] } """A connection to a list of items.""" @@ -1617,13 +1427,12 @@ type UserConnection { } input UserCreateInput { + name: String! email: String! password: String! - name: String! resetToken: String resetTokenExpiry: String permissions: UserCreatepermissionsInput - orders: OrderCreateManyWithoutUserInput cart: CartItemCreateManyWithoutUserInput } @@ -1637,33 +1446,17 @@ input UserCreateOneWithoutCartInput { connect: UserWhereUniqueInput } -input UserCreateOneWithoutOrdersInput { - create: UserCreateWithoutOrdersInput - connect: UserWhereUniqueInput -} - input UserCreatepermissionsInput { set: [Permission!] } input UserCreateWithoutCartInput { - email: String! - password: String! name: String! - resetToken: String - resetTokenExpiry: String - permissions: UserCreatepermissionsInput - orders: OrderCreateManyWithoutUserInput -} - -input UserCreateWithoutOrdersInput { email: String! password: String! - name: String! resetToken: String resetTokenExpiry: String permissions: UserCreatepermissionsInput - cart: CartItemCreateManyWithoutUserInput } """An edge in a connection.""" @@ -1678,31 +1471,29 @@ type UserEdge { enum UserOrderByInput { id_ASC id_DESC + name_ASC + name_DESC email_ASC email_DESC password_ASC password_DESC - name_ASC - name_DESC resetToken_ASC resetToken_DESC resetTokenExpiry_ASC resetTokenExpiry_DESC - createdAt_ASC - createdAt_DESC updatedAt_ASC updatedAt_DESC + createdAt_ASC + createdAt_DESC } type UserPreviousValues { id: ID! + name: String! email: String! password: String! - name: String! resetToken: String resetTokenExpiry: String - createdAt: DateTime! - updatedAt: DateTime! permissions: [Permission!]! } @@ -1746,49 +1537,46 @@ input UserSubscriptionWhereInput { } input UserUpdateDataInput { + name: String email: String password: String - name: String resetToken: String resetTokenExpiry: String permissions: UserUpdatepermissionsInput - orders: OrderUpdateManyWithoutUserInput cart: CartItemUpdateManyWithoutUserInput } input UserUpdateInput { + name: String email: String password: String - name: String resetToken: String resetTokenExpiry: String permissions: UserUpdatepermissionsInput - orders: OrderUpdateManyWithoutUserInput cart: CartItemUpdateManyWithoutUserInput } input UserUpdateOneInput { create: UserCreateInput connect: UserWhereUniqueInput + disconnect: Boolean delete: Boolean update: UserUpdateDataInput upsert: UserUpsertNestedInput } -input UserUpdateOneWithoutCartInput { - create: UserCreateWithoutCartInput +input UserUpdateOneRequiredInput { + create: UserCreateInput connect: UserWhereUniqueInput - delete: Boolean - update: UserUpdateWithoutCartDataInput - upsert: UserUpsertWithoutCartInput + update: UserUpdateDataInput + upsert: UserUpsertNestedInput } -input UserUpdateOneWithoutOrdersInput { - create: UserCreateWithoutOrdersInput +input UserUpdateOneRequiredWithoutCartInput { + create: UserCreateWithoutCartInput connect: UserWhereUniqueInput - delete: Boolean - update: UserUpdateWithoutOrdersDataInput - upsert: UserUpsertWithoutOrdersInput + update: UserUpdateWithoutCartDataInput + upsert: UserUpsertWithoutCartInput } input UserUpdatepermissionsInput { @@ -1796,23 +1584,12 @@ input UserUpdatepermissionsInput { } input UserUpdateWithoutCartDataInput { - email: String - password: String name: String - resetToken: String - resetTokenExpiry: String - permissions: UserUpdatepermissionsInput - orders: OrderUpdateManyWithoutUserInput -} - -input UserUpdateWithoutOrdersDataInput { email: String password: String - name: String resetToken: String resetTokenExpiry: String permissions: UserUpdatepermissionsInput - cart: CartItemUpdateManyWithoutUserInput } input UserUpsertNestedInput { @@ -1825,11 +1602,6 @@ input UserUpsertWithoutCartInput { create: UserCreateWithoutCartInput! } -input UserUpsertWithoutOrdersInput { - update: UserUpdateWithoutOrdersDataInput! - create: UserCreateWithoutOrdersInput! -} - input UserWhereInput { """Logical AND on all given filters.""" AND: [UserWhereInput!] @@ -1879,6 +1651,46 @@ input UserWhereInput { """All values not ending with the given string.""" id_not_ends_with: ID + name: String + + """All values that are not equal to given value.""" + name_not: String + + """All values that are contained in given list.""" + name_in: [String!] + + """All values that are not contained in given list.""" + name_not_in: [String!] + + """All values less than the given value.""" + name_lt: String + + """All values less than or equal the given value.""" + name_lte: String + + """All values greater than the given value.""" + name_gt: String + + """All values greater than or equal the given value.""" + name_gte: String + + """All values containing the given string.""" + name_contains: String + + """All values not containing the given string.""" + name_not_contains: String + + """All values starting with the given string.""" + name_starts_with: String + + """All values not starting with the given string.""" + name_not_starts_with: String + + """All values ending with the given string.""" + name_ends_with: String + + """All values not ending with the given string.""" + name_not_ends_with: String email: String """All values that are not equal to given value.""" @@ -1959,46 +1771,6 @@ input UserWhereInput { """All values not ending with the given string.""" password_not_ends_with: String - name: String - - """All values that are not equal to given value.""" - name_not: String - - """All values that are contained in given list.""" - name_in: [String!] - - """All values that are not contained in given list.""" - name_not_in: [String!] - - """All values less than the given value.""" - name_lt: String - - """All values less than or equal the given value.""" - name_lte: String - - """All values greater than the given value.""" - name_gt: String - - """All values greater than or equal the given value.""" - name_gte: String - - """All values containing the given string.""" - name_contains: String - - """All values not containing the given string.""" - name_not_contains: String - - """All values starting with the given string.""" - name_starts_with: String - - """All values not starting with the given string.""" - name_not_starts_with: String - - """All values ending with the given string.""" - name_ends_with: String - - """All values not ending with the given string.""" - name_not_ends_with: String resetToken: String """All values that are not equal to given value.""" @@ -2079,62 +1851,9 @@ input UserWhereInput { """All values not ending with the given string.""" resetTokenExpiry_not_ends_with: String - createdAt: DateTime - - """All values that are not equal to given value.""" - createdAt_not: DateTime - - """All values that are contained in given list.""" - createdAt_in: [DateTime!] - - """All values that are not contained in given list.""" - createdAt_not_in: [DateTime!] - - """All values less than the given value.""" - createdAt_lt: DateTime - - """All values less than or equal the given value.""" - createdAt_lte: DateTime - - """All values greater than the given value.""" - createdAt_gt: DateTime - - """All values greater than or equal the given value.""" - createdAt_gte: DateTime - updatedAt: DateTime - - """All values that are not equal to given value.""" - updatedAt_not: DateTime - - """All values that are contained in given list.""" - updatedAt_in: [DateTime!] - - """All values that are not contained in given list.""" - updatedAt_not_in: [DateTime!] - - """All values less than the given value.""" - updatedAt_lt: DateTime - - """All values less than or equal the given value.""" - updatedAt_lte: DateTime - - """All values greater than the given value.""" - updatedAt_gt: DateTime - - """All values greater than or equal the given value.""" - updatedAt_gte: DateTime - orders_every: OrderWhereInput - orders_some: OrderWhereInput - orders_none: OrderWhereInput cart_every: CartItemWhereInput cart_some: CartItemWhereInput cart_none: CartItemWhereInput - _MagicalBackRelation_OrderItemToUser_every: OrderItemWhereInput - _MagicalBackRelation_OrderItemToUser_some: OrderItemWhereInput - _MagicalBackRelation_OrderItemToUser_none: OrderItemWhereInput - _MagicalBackRelation_ItemToUser_every: ItemWhereInput - _MagicalBackRelation_ItemToUser_some: ItemWhereInput - _MagicalBackRelation_ItemToUser_none: ItemWhereInput } input UserWhereUniqueInput { diff --git a/finished-application/backend/src/index.js b/finished-application/backend/src/index.js index 2a1b433..804d6d6 100644 --- a/finished-application/backend/src/index.js +++ b/finished-application/backend/src/index.js @@ -1,30 +1,33 @@ -/* eslint-disable */ -require('dotenv').config({ path: 'variables.env' }); -/* eslint-enable */ +const cookieParser = require('cookie-parser'); const jwt = require('jsonwebtoken'); + +require('dotenv').config({ path: 'variables.env' }); const createServer = require('./createServer'); const db = require('./db'); -const cookieParser = require('cookie-parser'); const server = createServer(); server.express.use(cookieParser()); +// decode the JWT so we can get the user Id on each request server.express.use((req, res, next) => { const { token } = req.cookies; if (token) { const { userId } = jwt.verify(token, process.env.APP_SECRET); + // put the userId onto the req for future requests to access req.userId = userId; } next(); }); -// 2. Get User from their ID +// 2. Create a middleware that populates the user on each request + server.express.use(async (req, res, next) => { + // if they aren't logged in, skip this if (!req.userId) return next(); const user = await db.query.user( { where: { id: req.userId } }, - `{ id, permissions, email, name }` + '{ id, permissions, email, name }' ); req.user = user; next(); @@ -36,9 +39,8 @@ server.start( credentials: true, origin: process.env.FRONTEND_URL, }, - port: process.env.PORT, }, deets => { - console.log(`Server is running on http://localhost:${deets.port}`); + console.log(`Server is now running on port http://localhost:${deets.port}`); } ); diff --git a/finished-application/backend/src/mail.js b/finished-application/backend/src/mail.js index fc4a47b..5274310 100644 --- a/finished-application/backend/src/mail.js +++ b/finished-application/backend/src/mail.js @@ -1,26 +1,26 @@ const nodemailer = require('nodemailer'); const transport = nodemailer.createTransport({ - host: 'smtp.mailtrap.io', - port: 2525, + host: process.env.MAIL_HOST, + port: process.env.MAIL_PORT, auth: { - user: 'c41bab08214808', - pass: '04992d4af4bdcf', + user: process.env.MAIL_USER, + pass: process.env.MAIL_PASS, }, }); const makeANiceEmail = text => ` <div className="email" style=" - border:1px solid black; + border: 1px solid black; padding: 20px; font-family: sans-serif; line-height: 2; font-size: 20px; "> - <h2>Hello There</h2> + <h2>Hello There!</h2> <p>${text}</p> - <p>😘 Wes Bos</p> + <p>😘, Wes Bos</p> </div> `; diff --git a/finished-application/backend/src/resolvers/Mutation.js b/finished-application/backend/src/resolvers/Mutation.js index 80ff3f2..f0ea6a8 100644 --- a/finished-application/backend/src/resolvers/Mutation.js +++ b/finished-application/backend/src/resolvers/Mutation.js @@ -1,16 +1,75 @@ const bcrypt = require('bcryptjs'); const jwt = require('jsonwebtoken'); -const { hasPermission } = require('../utils'); const { randomBytes } = require('crypto'); const { promisify } = require('util'); -const mail = require('../mail'); +const { transport, makeANiceEmail } = require('../mail'); +const { hasPermission } = require('../utils'); const stripe = require('../stripe'); -const mutations = { - // Signup Mutations +const Mutations = { + async createItem(parent, args, ctx, info) { + if (!ctx.request.userId) { + throw new Error('You must be logged in to do that!'); + } + + const item = await ctx.db.mutation.createItem( + { + data: { + // This is how to create a relationship between the Item and the User + user: { + connect: { + id: ctx.request.userId, + }, + }, + ...args, + }, + }, + info + ); + + console.log(item); + + return item; + }, + updateItem(parent, args, ctx, info) { + // first take a copy of the updates + const updates = { ...args }; + // remove the ID from the updates + delete updates.id; + // run the update method + return ctx.db.mutation.updateItem( + { + data: updates, + where: { + id: args.id, + }, + }, + info + ); + }, + async deleteItem(parent, args, ctx, info) { + const where = { id: args.id }; + // 1. find the item + const item = await ctx.db.query.item({ where }, `{ id title user { id }}`); + // 2. Check if they own that item, or have the permissions + const ownsItem = item.user.id === ctx.request.userId; + const hasPermissions = ctx.request.user.permissions.some(permission => + ['ADMIN', 'ITEMDELETE'].includes(permission) + ); + + if (!ownsItem && hasPermissions) { + throw new Error("You don't have permission to do that!"); + } + + // 3. Delete it! + return ctx.db.mutation.deleteItem({ where }, info); + }, async signup(parent, args, ctx, info) { + // lowercase their email args.email = args.email.toLowerCase(); + // hash their password const password = await bcrypt.hash(args.password, 10); + // create the user in the database const user = await ctx.db.mutation.createUser( { data: { @@ -21,153 +80,88 @@ const mutations = { }, info ); + // create the JWT token for them const token = jwt.sign({ userId: user.id }, process.env.APP_SECRET); + // We set the jwt as a cookie on the response ctx.response.cookie('token', token, { - maxAge: 1000 * 60 * 60 * 24 * 365, httpOnly: true, + maxAge: 1000 * 60 * 60 * 24 * 365, // 1 year cookie }); + // Finalllllly we return the user to the browser return user; }, - - async signout(parent, args, ctx, info) { - ctx.response.clearCookie('token'); - return { message: 'goodbye!' }; - }, - async signin(parent, { email, password }, ctx, info) { + // 1. check if there is a user with that email const user = await ctx.db.query.user({ where: { email } }); if (!user) { - throw new Error(`No such user found for email: ${email}`); + throw new Error(`No such user found for email ${email}`); } - + // 2. Check if their password is correct const valid = await bcrypt.compare(password, user.password); if (!valid) { - throw new Error('Invalid password'); + throw new Error('Invalid Password!'); } - // set the cookie + // 3. generate the JWT Token const token = jwt.sign({ userId: user.id }, process.env.APP_SECRET); + // 4. Set the cookie with the token ctx.response.cookie('token', token, { - maxAge: 1000 * 60 * 60 * 24 * 365, httpOnly: true, + maxAge: 1000 * 60 * 60 * 24 * 365, }); + // 5. Return the user return user; }, - - // Create An Item - async createItem(parent, args, ctx, info) { - if (!ctx.request.userId) { - throw new Error('You must be logged in to create an item'); - } - - const item = await ctx.db.mutation.createItem( - { - data: { - user: { - connect: { - id: ctx.request.userId, - }, - }, - ...args, - }, - }, - info - ); - return item; - }, - - async deleteItem(parent, args, ctx, info) { - const where = { - id: args.id, - }; - // 1. find the item - const item = await ctx.db.query.item({ where }, `{ user {id}, title, id, description }`); - // 2. if they 1. Don't own it AND 2. aren't an admin - if (item.user.id !== ctx.request.user.id && !ctx.request.user.permissions.includes('ADMIN')) { - throw new Error("You aren't allowed to delete that item!"); - } - - // 3. remove any orderItems this item is in - - return ctx.db.mutation.deleteItem({ where }, info); - }, - - async updateItem(parent, args, ctx, info) { - const user = ctx.request.user; - const item = await ctx.db.query.item({ where: { id: args.id } }, `{ user { id } }`); - - if (item.user.id !== user.id || !hasPermission(user, ['ADMIN'])) { - throw new Error('You are not allowed to update that item!'); - } - - const updates = { ...args }; - // remove the ID because you can't update that - delete updates.id; - return ctx.db.mutation.updateItem( - { - where: { id: args.id }, - data: { - ...updates, - }, - }, - info - ); + signout(parent, args, ctx, info) { + ctx.response.clearCookie('token'); + return { message: 'Goodbye!' }; }, - - // Send password request async requestReset(parent, args, ctx, info) { - // 1. find if there is a user with that email + // 1. Check if this is a real user const user = await ctx.db.query.user({ where: { email: args.email } }); - if (!user) { - throw new Error(`No user with the email ${args.email}`); + throw new Error(`No such user found for email ${args.email}`); } - // 2. Set a reset token, and a reset date - const resetToken = (await promisify(randomBytes)(20)).toString('hex'); + // 2. Set a reset token and expiry on that user + const randomBytesPromiseified = promisify(randomBytes); + const resetToken = (await randomBytesPromiseified(20)).toString('hex'); const resetTokenExpiry = Date.now() + 3600000; // 1 hour from now - console.log({ resetToken, resetTokenExpiry }); const res = await ctx.db.mutation.updateUser({ where: { email: args.email }, data: { resetToken, resetTokenExpiry }, }); - - // 3. Send them their token via email - const mailRes = await mail.transport.sendMail({ - from: 'wesbos@gmail.com', + // 3. Email them that reset token + const mailRes = await transport.sendMail({ + from: 'wes@wesbos.com', to: user.email, - subject: 'Your password reset token', - html: mail.makeANiceEmail( - `Your password reset link is here! \n\n<a href="${process.env - .FRONTEND_URL}/reset?resetToken=${resetToken}">Click Here to reset</a>` - ), + subject: 'Your Password Reset Token', + html: makeANiceEmail(`Your Password Reset Token is here! + \n\n + <a href="${process.env + .FRONTEND_URL}/reset?resetToken=${resetToken}">Click Here to Reset</a>`), }); - return res.updateUser; - }, + // 4. Return the message + return { message: 'Thanks!' }; + }, async resetPassword(parent, args, ctx, info) { - // 1. Check that the passwords match + // 1. check if the passwords match if (args.password !== args.confirmPassword) { - throw new Error('Passwords do not match'); + throw new Error("Yo Passwords don't match!"); } - - // 2. Check that this is a legit resetToken - // 3. Check that it's not expired - // Note: If we didn't need the user here, we could also use db.exists() + // 2. check if its a legit reset token + // 3. Check if its expired const [user] = await ctx.db.query.users({ where: { resetToken: args.resetToken, - resetTokenExpiry_gte: Date.now() - 3600000, // within the last hour + resetTokenExpiry_gte: Date.now() - 3600000, }, }); - if (!user) { - throw new Error('This token is either invalid or expired.'); + throw new Error('This token is either invalid or expired!'); } - - // 4. Hash the password + // 4. Hash their new password const password = await bcrypt.hash(args.password, 10); - - // 5. Update the users password - // clean up the resetToken fields at the same time + // 5. Save the new password to the user and remove old resetToken fields const updatedUser = await ctx.db.mutation.updateUser({ where: { email: user.email }, data: { @@ -176,34 +170,63 @@ const mutations = { resetTokenExpiry: null, }, }); + // 6. Generate JWT const token = jwt.sign({ userId: updatedUser.id }, process.env.APP_SECRET); + // 7. Set the JWT cookie ctx.response.cookie('token', token, { - maxAge: 1000 * 60 * 60 * 24 * 365, httpOnly: true, + maxAge: 1000 * 60 * 60 * 24 * 365, }); - - // 6. send back the User for the GraphQL request on the client + // 8. return the new user return updatedUser; }, - /* - Add to cart - */ + async updatePermissions(parent, args, ctx, info) { + // 1. Check if they are logged in + if (!ctx.request.userId) { + throw new Error('You must be logged in!'); + } + // 2. Query the current user + const currentUser = await ctx.db.query.user( + { + where: { + id: ctx.request.userId, + }, + }, + info + ); + // 3. Check if they have permissions to do this + hasPermission(currentUser, ['ADMIN', 'PERMISSIONUPDATE']); + // 4. Update the permissions + return ctx.db.mutation.updateUser( + { + data: { + permissions: { + set: args.permissions, + }, + }, + where: { + id: args.userId, + }, + }, + info + ); + }, async addToCart(parent, args, ctx, info) { - const userId = ctx.request.userId; - + // 1. Make sure they are signed in + const { userId } = ctx.request; if (!userId) { - throw new Error('You must be signed in to add to cart!'); + throw new Error('You must be signed in soooon'); } - - // 1. Check if there is a CartItem for this user and item already + // 2. Query the users current cart const [existingCartItem] = await ctx.db.query.cartItems({ where: { user: { id: userId }, item: { id: args.id }, }, }); - + // 3. Check if that item is already in their cart and increment by 1 if it is if (existingCartItem) { + console.log('This item is already in their cart'); return ctx.db.mutation.updateCartItem( { where: { id: existingCartItem.id }, @@ -212,15 +235,12 @@ const mutations = { info ); } - - // Otherwise create a new cartItem + // 4. If its not, create a fresh CartItem for that user! return ctx.db.mutation.createCartItem( { data: { user: { - connect: { - id: userId, - }, + connect: { id: userId }, }, item: { connect: { id: args.id }, @@ -230,126 +250,88 @@ const mutations = { info ); }, - - // delete that cart item async removeFromCart(parent, args, ctx, info) { - console.log(args.id); - // 1. Find the CartItem + // 1. Find the cart item const cartItem = await ctx.db.query.cartItem( { - where: { id: args.id }, + where: { + id: args.id, + }, }, - `{ id, user { id, permissions }}` + `{ id, user { id }}` ); - // 2. Check they own it + // 1.5 Make sure we found an item + if (!cartItem) throw new Error('No CartItem Found!'); + // 2. Make sure they own that cart item if (cartItem.user.id !== ctx.request.userId) { - throw new Error("Cheatin' huh"); + throw new Error('Cheatin huhhhh'); } - // 3. Delete it + // 3. Delete that cart item return ctx.db.mutation.deleteCartItem( { - where: { - id: args.id, - }, + where: { id: args.id }, }, info ); }, - async createOrder(parent, args, ctx, info) { - const userId = ctx.request.userId; + // 1. Query the current user and make sure they are signed in + const { userId } = ctx.request; + if (!userId) throw new Error('You must be signed in to complete this order.'); const user = await ctx.db.query.user( { where: { id: userId } }, - '{ id, name, email, cart { id, quantity, item { title, price, id, description, image } }}' + `{ + id + name + email + cart { + id + quantity + item { title price id description image largeImage } + }}` ); - // 1. Recalculate the total for the price + // 2. recalculate the total for the price const amount = user.cart.reduce( (tally, cartItem) => tally + cartItem.item.price * cartItem.quantity, 0 ); - // 2. Create a stripe charge + console.log(`Going to charge for a total of ${amount}`); + // 3. Create the stripe charge (turn token into $$$) const charge = await stripe.charges.create({ amount, - currency: 'usd', + currency: 'USD', source: args.token, }); - - // 3. convert the items they want to OrderItems + // 4. Convert the CartItems to OrderItems const orderItems = user.cart.map(cartItem => { - console.log(cartItem); const orderItem = { - quantity: cartItem.quantity, - // copy all the item details so it's there forever ...cartItem.item, - // item: { - // // relationship to the Item incase we need it - // connect: { id: cartItem.item.id }, - // }, - user: { connect: { id: user.id } }, + quantity: cartItem.quantity, + user: { connect: { id: userId } }, }; - // scrub the ID from it because the orderItem will have it's own ID delete orderItem.id; return orderItem; }); - // 4. Create the Order + // 5. create the Order const order = await ctx.db.mutation.createOrder({ data: { total: charge.amount, charge: charge.id, - items: { - create: orderItems, - }, - user: { - connect: { - id: user.id, - }, - }, + items: { create: orderItems }, + user: { connect: { id: userId } }, }, }); - - // 5. Clean up, clear the users cart and send back { user, order } - // Delete the users current cart items + // 6. Clean up - clear the users cart, delete cartItems const cartItemIds = user.cart.map(cartItem => cartItem.id); await ctx.db.mutation.deleteManyCartItems({ where: { id_in: cartItemIds, }, }); - - // 6. Send the order back to the client + // 7. Return the Order to the client return order; }, - - async updateUser(parent, args, ctx, info) { - const userId = ctx.request.userId; - const updatedUser = await ctx.db.mutation.updateUser( - { - data: args, - where: { id: userId }, - }, - info - ); - return updatedUser; - }, - - async updatePermissions(parent, args, ctx, info) { - const userId = ctx.request.userId; - const currentUser = await ctx.db.query.user({ where: { id: userId } }, info); - if (!currentUser) throw new Error('You Must be logged in to updat permissions!'); - hasPermission(currentUser, ['ADMIN', 'PERMISSIONUPDATE']); - return ctx.db.mutation.updateUser( - { - data: { - permissions: { - set: args.permissions, - }, - }, - where: { id: args.userId }, - }, - info - ); - }, }; -module.exports = mutations; +module.exports = Mutations; diff --git a/finished-application/backend/src/resolvers/Query.js b/finished-application/backend/src/resolvers/Query.js index 51c2c42..22a6414 100644 --- a/finished-application/backend/src/resolvers/Query.js +++ b/finished-application/backend/src/resolvers/Query.js @@ -1,52 +1,59 @@ -const { hasPermission } = require('../utils'); - const { forwardTo } = require('prisma-binding'); +const { hasPermission } = require('../utils'); const Query = { items: forwardTo('db'), + item: forwardTo('db'), itemsConnection: forwardTo('db'), - - async order(parent, args, ctx, info) { - // 1. make sure they are signed in + me(parent, args, ctx, info) { + // check if there is a current user ID if (!ctx.request.userId) { - throw new Error('You Must be signed in to view an order'); + return null; } - - // 2. Create the query - const where = { - id: args.id, - user: { - id: ctx.request.userId, + return ctx.db.query.user( + { + where: { id: ctx.request.userId }, }, - }; - // 3. Fire off the query - const [order] = await ctx.db.query.orders({ where }, info); - - // 4. Check that they are allowed to view the order - if (order.user.id !== ctx.request.userId || hasPermission(ctx.request.user, ['ADMIN'])) { - throw new Error("You don't have permission"); - } - // 5. If everything checks out, return the order - return order; + info + ); }, - - me(parent, args, ctx, info) { + async users(parent, args, ctx, info) { + // 1. Check if they are logged in if (!ctx.request.userId) { - return null; // don't error out, just return nothing + throw new Error('You must be logged in!'); } + console.log(ctx.request.userId); + // 2. Check if the user has the permissions to query all the users + hasPermission(ctx.request.user, ['ADMIN', 'PERMISSIONUPDATE']); - return ctx.db.query.user( + // 2. if they do, query all the users! + return ctx.db.query.users({}, info); + }, + async order(parent, args, ctx, info) { + // 1. Make sure they are logged in + if (!ctx.request.userId) { + throw new Error('You arent logged in!'); + } + // 2. Query the current order + const order = await ctx.db.query.order( { - where: { id: ctx.request.userId }, + where: { id: args.id }, }, info ); + // 3. Check if the have the permissions to see this order + const ownsOrder = order.user.id === ctx.request.userId; + const hasPermissionToSeeOrder = ctx.request.user.permissions.includes('ADMIN'); + if (!ownsOrder || !hasPermission) { + throw new Error('You cant see this buddd'); + } + // 4. Return the order + return order; }, - async orders(parent, args, ctx, info) { const { userId } = ctx.request; if (!userId) { - throw new Error('You must be signed in to see your orders'); + throw new Error('you must be signed in!'); } return ctx.db.query.orders( { diff --git a/finished-application/backend/src/schema.graphql b/finished-application/backend/src/schema.graphql index 07533eb..8a8eeeb 100644 --- a/finished-application/backend/src/schema.graphql +++ b/finished-application/backend/src/schema.graphql @@ -1,39 +1,39 @@ -# The Below line looks like a comment, but it's not! # import * from './generated/prisma.graphql' -type Query { - me: User - order(id: ID!): Order! - orders(where: OrderWhereInput, orderBy: OrderOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [Order]! - items(where: ItemWhereInput, orderBy: ItemOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [Item]! - itemsConnection(where: ItemWhereInput, orderBy: ItemOrderByInput, first: Int, last: Int, skip: Int): ItemConnection! +type SuccessMessage { + message: String } type Mutation { + createItem(title: String, description: String, price: Int, image: String, largeImage: String): Item! + updateItem(id: ID!, title: String, description: String, price: Int): Item! + deleteItem(id: ID!): Item signup(email: String!, password: String!, name: String!): User! signin(email: String!, password: String!): User! - requestReset(email: String!): User + signout: SuccessMessage + requestReset(email: String!): SuccessMessage resetPassword(resetToken: String!, password: String!, confirmPassword: String!): User! - createItem(title: String, description: String, price: Int, image: String, largeImage: String): Item! - deleteItem(id: ID!): Item! - updateItem(id: ID!, title: String, description: String, price: Int): Item! + updatePermissions(permissions: [Permission], userId: ID!): User addToCart(id: ID!): CartItem removeFromCart(id: ID!): CartItem createOrder(token: String!): Order! - updateUser(name: String): User - signout: SuccessMessage - updatePermissions(permissions: [Permission], userId: ID!): User } -type SuccessMessage { - message: String +type Query { + items(where: ItemWhereInput, orderBy: ItemOrderByInput, skip: Int, first: Int): [Item]! + item(where: ItemWhereUniqueInput!): Item + itemsConnection(where: ItemWhereInput): ItemConnection! + me: User + users: [User]! + order(id: ID!): Order + orders(orderBy: OrderOrderByInput): [Order]! } -type User { +type User{ id: ID! - email: String! name: String! - orders: [Order!]! + email: String! + permissions: [Permission!]! cart: [CartItem!]! - permissions: [Permission]! + orders: [OrderItem] } |
