├── .gitignore ├── .babelrc ├── src ├── config │ └── config.js ├── resolvers │ ├── Subscription.js │ ├── index.js │ ├── User.js │ ├── Query.js │ └── Mutation │ │ ├── auth.js │ │ ├── post.js │ │ └── comment.js ├── utils │ └── getUserId.js ├── index.js ├── schema.graphql └── generated │ └── prisma.graphql ├── tests ├── utils │ ├── client.js │ └── seed.js └── index.test.js ├── package.json └── readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | config.json -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "env" 4 | ], 5 | "plugins": [ 6 | "transform-object-rest-spread" 7 | ] 8 | } -------------------------------------------------------------------------------- /src/config/config.js: -------------------------------------------------------------------------------- 1 | var env = process.env.NODE_ENV || 'development'; 2 | 3 | if (env === 'development' || env === 'test') { 4 | var config = require('../../config.json'); 5 | var envConfig = config[env]; 6 | 7 | Object.keys(envConfig).forEach((key) => { 8 | process.env[key] = envConfig[key]; 9 | }); 10 | } -------------------------------------------------------------------------------- /src/resolvers/Subscription.js: -------------------------------------------------------------------------------- 1 | export const Subscription = { 2 | comments: { 3 | async subscribe(obj, { postId }, { pubsub }) { 4 | // const post = await Post.findById(postId) 5 | 6 | // if (!post) { 7 | // throw new Error('Unable to suscribe to post comments') 8 | // } 9 | 10 | // return pubsub.asyncIterator(`COMMENTS_FOR_${post._id}`) 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /src/utils/getUserId.js: -------------------------------------------------------------------------------- 1 | import jwt from 'jsonwebtoken' 2 | 3 | export default (ctx, silent = false) => { 4 | const header = ctx.request ? ctx.request.headers.authorization : ctx.connection.context.authorization 5 | let user 6 | 7 | if (header) { 8 | const token = header.replace('Bearer ', '') 9 | const { userId } = jwt.verify(token, process.env.JWT_SECRET) 10 | return userId 11 | } 12 | 13 | if (!silent) { 14 | throw new Error('Please authentication') 15 | } 16 | } -------------------------------------------------------------------------------- /src/resolvers/index.js: -------------------------------------------------------------------------------- 1 | import { extractFragmentReplacements } from 'prisma-binding' 2 | 3 | import getUserId from '../utils/getUserId' 4 | import { Query } from './Query' 5 | import { User } from './User' 6 | import { Subscription } from './Subscription' 7 | import { auth } from './Mutation/auth' 8 | import { post } from './Mutation/post' 9 | import { comment } from './Mutation/comment' 10 | 11 | const resolvers = { 12 | Query, 13 | User, 14 | Mutation: { 15 | ...auth, 16 | ...post, 17 | ...comment, 18 | }, 19 | Subscription 20 | } 21 | 22 | const fragmentReplacements = extractFragmentReplacements(resolvers) 23 | 24 | export { resolvers, fragmentReplacements } -------------------------------------------------------------------------------- /src/resolvers/User.js: -------------------------------------------------------------------------------- 1 | import getUserId from '../utils/getUserId' 2 | 3 | export const User = { 4 | posts: { 5 | fragment: `fragment UserId on User { id }`, 6 | async resolve(obj, args, ctx, info) { 7 | return await ctx.db.query.posts({ where: { published: true, author: { id: obj.id } } }) 8 | } 9 | }, 10 | email: { 11 | fragment: `fragment UserId on User { id }`, 12 | async resolve(parent, args, ctx, info) { 13 | try { 14 | const userId = getUserId(ctx) 15 | return parent.id === userId ? parent.email : null 16 | } catch (e) { 17 | return null 18 | } 19 | }, 20 | }, 21 | } -------------------------------------------------------------------------------- /src/resolvers/Query.js: -------------------------------------------------------------------------------- 1 | import getUserId from '../utils/getUserId' 2 | 3 | export const Query = { 4 | async me(obj, args, ctx, info) { 5 | const userId = getUserId(ctx) 6 | return ctx.db.query.user({ where: { id: userId } }, info) 7 | }, 8 | async posts(obj, { page = 1, pageSize = 10 }, ctx, info) { 9 | const first = pageSize 10 | const skip = (page - 1) * pageSize 11 | 12 | return ctx.db.query.posts({ first, skip, orderBy: 'createdAt_DESC', where: { published: true } }, info) 13 | }, 14 | async drafts(obj, { page = 1, pageSize = 10 }, ctx, info) { 15 | const userId = getUserId(ctx) 16 | const first = pageSize 17 | const skip = (page - 1) * pageSize 18 | 19 | return ctx.db.query.posts({ first, skip, orderBy: 'updatedAt_DESC', where: { published: false, author: { id: userId } } }, info) 20 | } 21 | } -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import fs from 'fs' 2 | import path from 'path' 3 | import { GraphQLServer } from 'graphql-yoga' 4 | import { PubSub } from 'graphql-yoga' 5 | import { Prisma } from 'prisma-binding' 6 | 7 | import './config/config' 8 | import { resolvers, fragmentReplacements } from './resolvers/index' 9 | 10 | const prisma = new Prisma({ 11 | typeDefs: 'src/generated/prisma.graphql', 12 | endpoint: 'http://localhost:4467', 13 | secret: 'my-super-secret-secret', 14 | fragmentReplacements 15 | }) 16 | 17 | const pubsub = new PubSub() 18 | 19 | const server = new GraphQLServer({ 20 | typeDefs: './src/schema.graphql', 21 | resolvers, 22 | fragmentReplacements, 23 | context: req => ({ ...req, db: prisma, pubsub }), 24 | }) 25 | 26 | server.start({ 27 | port: process.env.PORT || 3000 28 | }, ({ port }) => { 29 | console.log(`Server is running on port ${port}`) 30 | }) -------------------------------------------------------------------------------- /src/resolvers/Mutation/auth.js: -------------------------------------------------------------------------------- 1 | import bcrypt from 'bcryptjs' 2 | import jwt from 'jsonwebtoken' 3 | 4 | export const auth = { 5 | async signup(obj, args, ctx, info) { 6 | const password = await bcrypt.hash(args.password, 10) 7 | const user = await ctx.db.mutation.createUser({ data: { ...args, password } }, `{ id, name, email }`) 8 | 9 | return { 10 | token: jwt.sign({ userId: user.id }, process.env.JWT_SECRET), 11 | user: user 12 | } 13 | }, 14 | async login(obj, { email, password }, ctx) { 15 | const user = await ctx.db.query.user({ where: { email } }) 16 | if (!user) { 17 | throw new Error('No user found') 18 | } 19 | 20 | const isValid = await bcrypt.compare(password, user.password) 21 | if (!user) { 22 | throw new Error('No user found') 23 | } 24 | 25 | return { 26 | token: jwt.sign({ userId: user.id }, process.env.JWT_SECRET), 27 | user: user 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /tests/utils/client.js: -------------------------------------------------------------------------------- 1 | import ApolloClient from 'apollo-client' 2 | import { ApolloLink } from 'apollo-link' 3 | import { createHttpLink } from "apollo-link-http" 4 | import { WebSocketLink } from "apollo-link-ws" 5 | import { InMemoryCache } from 'apollo-cache-inmemory' 6 | import { getMainDefinition } from 'apollo-utilities' 7 | import fetch from 'unfetch' 8 | 9 | // Setup the links for the apollo client 10 | const port = process.env.PORT || 3000 11 | const httpLink = createHttpLink({ uri: `http://localhost:${port}/`, fetch }) 12 | const cache = new InMemoryCache() 13 | const wsLink = new WebSocketLink({ 14 | uri: `ws://localhost:${port}/`, 15 | options: { 16 | reconnect: true 17 | } 18 | }) 19 | 20 | // Configure apollo split to use multiple links 21 | const link = ApolloLink.split( 22 | // Pick which links get the data based on the operation kind 23 | ({ query }) => { 24 | const { kind, operation } = getMainDefinition(query) 25 | return kind === 'OperationDefinition' && operation === 'subscription' 26 | }, 27 | wsLink, 28 | httpLink, 29 | ); 30 | 31 | // Create the client 32 | const client = new ApolloClient({ 33 | link: link, 34 | cache 35 | }) 36 | 37 | export { client } -------------------------------------------------------------------------------- /src/schema.graphql: -------------------------------------------------------------------------------- 1 | type Query { 2 | me: User! 3 | drafts (page: Int, pageSize: Int): [Post!]! 4 | posts (page: Int, pageSize: Int): [Post!]! 5 | } 6 | 7 | type Mutation { 8 | signup(name: String!, email: String!, password: String!): AuthPayload! 9 | login(email: String!, password: String!): AuthPayload! 10 | createPost(title: String, body: String): Post! 11 | editPost(id: ID!, title: String, body: String, published: Boolean): Post! 12 | deletePost(id: ID!): Post! 13 | createComment(postId: ID!, parentId: ID, text: String!): Comment! 14 | editComment(id: ID!, text: String!): Comment! 15 | deleteComment(id: ID!): Comment! 16 | } 17 | 18 | type AuthPayload { 19 | token: String! 20 | user: User! 21 | } 22 | 23 | type Subscription { 24 | comments(postId: ID!): Comment! 25 | } 26 | 27 | type User { 28 | id: ID! 29 | name: String! 30 | email: String 31 | posts: [Post]! 32 | drafts: [Post] 33 | comments: [Comment!]! 34 | } 35 | 36 | type Post { 37 | id: ID! 38 | title: String! 39 | body: String! 40 | published: Boolean! 41 | author: User! 42 | comments: [Comment]! 43 | createdAt: String! 44 | updatedAt: String! 45 | } 46 | 47 | type Comment { 48 | id: ID! 49 | text: String! 50 | parent: Comment 51 | post: Post! 52 | author: User! 53 | createdAt: String! 54 | updatedAt: String! 55 | } -------------------------------------------------------------------------------- /src/resolvers/Mutation/post.js: -------------------------------------------------------------------------------- 1 | import getUserId from '../../utils/getUserId' 2 | 3 | export const post = { 4 | async createPost(obj, { title, body }, ctx, info) { 5 | const userId = getUserId(ctx) 6 | const data = { 7 | title, 8 | body, 9 | published: false, 10 | author: { 11 | connect: { id: userId } 12 | } 13 | } 14 | return ctx.db.mutation.createPost({ data }, info) 15 | }, 16 | async editPost(obj, { id, title, body, published }, ctx, info) { 17 | const userId = getUserId(ctx) 18 | const exists = await ctx.db.exists.Post({ id, author: { id: userId } }) 19 | const isPublished = await ctx.db.exists.Post({ id, published: true, author: { id: userId } }) 20 | 21 | if (!exists) { 22 | throw new Error('Post not found') 23 | } 24 | 25 | if (isPublished && published === false) { 26 | await ctx.db.mutation.deleteManyComments({ where: { post: { id } } }) 27 | } 28 | 29 | return ctx.db.mutation.updatePost({ where: { id }, data: { title, body, published } }, info) 30 | }, 31 | async deletePost(obj, { id }, ctx, info) { 32 | const userId = getUserId(ctx) 33 | const exists = await ctx.db.exists.Post({ id, author: { id: userId } }) 34 | 35 | if (!exists) { 36 | throw new Error('Post not found') 37 | } 38 | 39 | await ctx.db.mutation.deleteManyComments({ where: { post: { id } } }) 40 | // Can't query relational data until this is fixed: https://github.com/prismagraphql/prisma/issues/2347 41 | return ctx.db.mutation.deletePost({ where: { id } }, info) 42 | } 43 | } -------------------------------------------------------------------------------- /tests/index.test.js: -------------------------------------------------------------------------------- 1 | import expect from 'expect' 2 | import gql from 'graphql-tag' 3 | import { client } from './utils/client' 4 | 5 | // Start up the yoga server 6 | import '../src/index' 7 | import { users, populateUsers, posts, populatePosts, comments, populateComments } from './utils/seed' 8 | 9 | beforeEach(populateUsers) 10 | beforeEach(populatePosts) 11 | beforeEach(populateComments) 12 | 13 | it('should create a new account', async () => { 14 | const variables = { 15 | email: 'new@example.com', 16 | name: 'Some user', 17 | password: 'password123abc' 18 | } 19 | const mutation = gql` 20 | mutation ($name: String!, $email: String!, $password: String!) { 21 | signup(name: $name, email: $email, password: $password) { 22 | _id 23 | email 24 | name 25 | } 26 | } 27 | ` 28 | 29 | const response = await client.mutate({ mutation, variables }) 30 | expect(response.data.signup.email).toBe(variables.email) 31 | expect(response.data.signup.name).toBe(variables.name) 32 | }) 33 | 34 | 35 | it('should not create a new account if invalid email') 36 | it('should not create a new account if invalid password') 37 | 38 | 39 | // it('should return the hello greeting', async () => { 40 | // const query = gql` 41 | // query { 42 | // hello 43 | // } 44 | // ` 45 | // const response = await client.query({ query }) 46 | // expect(response.data.hello).toBe('Hello!') 47 | // }) 48 | 49 | // it('should increase the count over time', (done) => { 50 | // const query = gql` 51 | // subscription { 52 | // count 53 | // } 54 | // ` 55 | // client.subscribe({ 56 | // query 57 | // }).subscribe({ 58 | // next(response) { 59 | // expect(response.data.count).toBe(0) 60 | // done() 61 | // } 62 | // }); 63 | // }) -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "graphql-boilerplate", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "directories": { 7 | "test": "tests" 8 | }, 9 | "scripts": { 10 | "start": "babel src -d dist && cp ./src/graphql/schema.gql ./dist/graphql/ && node dist/index.js", 11 | "dev": "nodemon src/index.js --ext js,gql --exec babel-node", 12 | "get-schema": "graphql get-schema -p database -e http://localhost:4467 -o src/generated/prisma.graphql --no-all --header Authorization=\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7InNlcnZpY2UiOiJkZWZhdWx0QGRlZmF1bHQiLCJyb2xlcyI6WyJhZG1pbiJdfSwiaWF0IjoxNTI3NzgzNzY3LCJleHAiOjE1MjgzODg1Njd9.zea5QlzFBwxFxzDf_Aj9KuFzjxEx9bEIeWO-y26MbMs\"", 13 | "test": "jest --watch" 14 | }, 15 | "repository": { 16 | "type": "git", 17 | "url": "git+https://github.com/andrewjmead/graphql-research-boilerplate.git" 18 | }, 19 | "keywords": [], 20 | "author": "", 21 | "license": "ISC", 22 | "bugs": { 23 | "url": "https://github.com/andrewjmead/graphql-research-boilerplate/issues" 24 | }, 25 | "homepage": "https://github.com/andrewjmead/graphql-research-boilerplate#readme", 26 | "dependencies": { 27 | "babel-cli": "^6.26.0", 28 | "babel-core": "^6.26.3", 29 | "babel-jest": "^22.4.4", 30 | "babel-plugin-transform-object-rest-spread": "^6.26.0", 31 | "babel-preset-env": "^1.7.0", 32 | "bcryptjs": "^2.4.3", 33 | "graphql-binding": "^2.1.0", 34 | "graphql-cli": "^2.16.0", 35 | "graphql-request": "^1.6.0", 36 | "graphql-tools": "^3.0.2", 37 | "graphql-yoga": "^1.14.0", 38 | "jsonwebtoken": "^8.2.1", 39 | "mongoose": "^5.1.2", 40 | "prisma-binding": "^2.0.2" 41 | }, 42 | "devDependencies": { 43 | "apollo-cache-inmemory": "^1.2.1", 44 | "apollo-client": "^2.3.1", 45 | "apollo-link": "^1.2.2", 46 | "apollo-link-http": "^1.5.4", 47 | "apollo-link-ws": "^1.0.8", 48 | "apollo-utilities": "^1.0.12", 49 | "expect": "^22.4.3", 50 | "graphql-tag": "^2.9.2", 51 | "jest": "^22.4.4", 52 | "jest-cli": "^22.4.4", 53 | "nodemon": "^1.17.4", 54 | "unfetch": "^3.0.0" 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/resolvers/Mutation/comment.js: -------------------------------------------------------------------------------- 1 | import getUserId from '../../utils/getUserId' 2 | 3 | export const comment = { 4 | async createComment(obj, { postId, parentId, text }, ctx, info) { 5 | const userId = getUserId(ctx) 6 | const postExists = await ctx.db.exists.Post({ id: postId, published: true }) 7 | 8 | if (!postExists) { 9 | throw new Error('Post not found') 10 | } 11 | 12 | const data = { 13 | text, 14 | author: { 15 | connect: { id: userId } 16 | }, 17 | post: { 18 | connect: { id: postId } 19 | } 20 | } 21 | 22 | if (parentId) { 23 | const parentCommentExists = await ctx.db.exists.Comment({ id: parentId }) 24 | 25 | if (!parentCommentExists) { 26 | throw new Error('Parent comment not found') 27 | } 28 | 29 | data.parent = { 30 | connect: { id: parentId } 31 | } 32 | } 33 | 34 | // TODO - publish 35 | // pubsub.publish(`COMMENTS_FOR_${comment.post}`, {comments: comment}) 36 | 37 | return ctx.db.mutation.createComment({ data }, info) 38 | }, 39 | async editComment(obj, { id, text }, ctx, info) { 40 | const userId = getUserId(ctx) 41 | const exists = await ctx.db.exists.Comment({ id, author: { id: userId } }) 42 | 43 | if (!exists) { 44 | throw new Error('Post not found') 45 | } 46 | 47 | return ctx.db.mutation.updateComment({ where: { id }, data: { text } }, info) 48 | }, 49 | async deleteComment(obj, { id }, ctx, info) { 50 | const userId = getUserId(ctx) 51 | const isAuthor = await ctx.db.exists.Comment({ id, author: { id: userId } }) 52 | const isPostOwner = await ctx.db.exists.Comment({ id, post: { author: { id: userId } } }) 53 | 54 | if (!isAuthor && !isPostOwner) { 55 | throw new Error('Comment not found') 56 | } 57 | 58 | // Can't query relational data until this is fixed: https://github.com/prismagraphql/prisma/issues/2347 59 | return ctx.db.mutation.deleteComment({ where: { id } }, info) 60 | } 61 | } -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # GraphQL Boilerplate Project 2 | 3 | A GraphQL boilerplate that supports GraphQL, subscriptions, and testing. 4 | 5 | This boilerplate was created using [graphql-yoga](https://github.com/prismagraphql/graphql-yoga) for the GraphQL server. The test environment uses [jest](https://github.com/facebook/jest) for the testing framework and [apollo-client](https://github.com/apollographql/apollo-client) to make the GraphQL requests. 6 | 7 | ## Get Started 8 | 9 | 1. Clone the repo 10 | 11 | 2. Run `npm install` 12 | 13 | 3. Set up a config file. Here's an example for your dev and test environments. 14 | 15 | ```json 16 | { 17 | "development": { 18 | "DATABASE_URL": "mongodb://localhost/graphql-blog-dev", 19 | "JWT_SECRET": "abc123098!!!" 20 | }, 21 | "test": { 22 | "DATABASE_URL": "mongodb://localhost/graphql-blog-test", 23 | "JWT_SECRET": "abc123098!!!" 24 | } 25 | } 26 | ``` 27 | 28 | 4. Run `npm run dev` to start up the development environment 29 | 30 | 5. Head over to `localhost:3000` to make some GraphQL requests using GraphQL Playground 31 | 32 | ## Get Started with Tests 33 | 34 | 1. Run `npm test` to execute the jest test suite 35 | 36 | ## To Add 37 | 38 | - [ ] Testing 39 | 40 | ## The MIT License 41 | 42 | Copyright (c) 2018 Andrew Mead LLC 43 | 44 | Permission is hereby granted, free of charge, to any person obtaining a copy 45 | of this software and associated documentation files (the "Software"), to deal 46 | in the Software without restriction, including without limitation the rights 47 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 48 | copies of the Software, and to permit persons to whom the Software is 49 | furnished to do so, subject to the following conditions: 50 | 51 | The above copyright notice and this permission notice shall be included in all 52 | copies or substantial portions of the Software. 53 | 54 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 55 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 56 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 57 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 58 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 59 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 60 | SOFTWARE. -------------------------------------------------------------------------------- /tests/utils/seed.js: -------------------------------------------------------------------------------- 1 | import mongoose from 'mongoose' 2 | import jwt from 'jsonwebtoken' 3 | import User from '../../src/models/user' 4 | import Post from '../../src/models/post' 5 | import Comment from '../../src/models/comment' 6 | 7 | const ObjectId = mongoose.Types.ObjectId 8 | 9 | 10 | // Set up users 11 | const users = [{ 12 | _id: new ObjectId(), 13 | email: 'andrew@example.com', 14 | name: 'Andrew', 15 | password: 'andrewpass098!' 16 | }, { 17 | _id: new ObjectId(), 18 | email: 'isabell@example.com', 19 | name: 'Isabell', 20 | password: 'isabellpass098!' 21 | }] 22 | 23 | const authTokens = [ 24 | jwt.sign({ _id: users[0]._id }, process.env.JWT_SECRET).toString(), 25 | jwt.sign({ _id: users[1]._id }, process.env.JWT_SECRET).toString() 26 | ] 27 | 28 | // Set up posts 29 | const posts = [{ 30 | _id: new ObjectId(), 31 | title: 'First post from Andrew', 32 | body: 'Post body', 33 | published: false, 34 | author: users[0]._id 35 | }, { 36 | _id: new ObjectId(), 37 | title: 'Second post from Andrew', 38 | body: 'Post body', 39 | published: true, 40 | author: users[0]._id 41 | }, { 42 | _id: new ObjectId(), 43 | title: 'First post from Isabell', 44 | body: 'Post body', 45 | published: true, 46 | author: users[1]._id 47 | }] 48 | 49 | // Set up comments 50 | const firstCommentId = new ObjectId() 51 | const comments = [{ 52 | _id: firstCommentId, 53 | text: 'Comment from Isabell', 54 | author: users[1]._id, 55 | post: posts[1]._id 56 | }, { 57 | _id: new ObjectId(), 58 | text: 'Comment from Andrew to Isabell', 59 | author: users[0]._id, 60 | post: posts[1]._id, 61 | parent: firstCommentId 62 | }, { 63 | _id: new ObjectId(), 64 | text: 'Comment from Andrew', 65 | author: users[0]._id, 66 | post: posts[2]._id 67 | }] 68 | 69 | const populateUsers = async () => { 70 | await User.remove({}) 71 | await Promise.all(users.map((user) => { 72 | return new User(user).save() 73 | })) 74 | } 75 | 76 | const populatePosts = async () => { 77 | await Post.remove({}) 78 | await Promise.all(posts.map((post) => { 79 | return new Post(post).save() 80 | })) 81 | } 82 | 83 | const populateComments = async () => { 84 | await Comment.remove({}) 85 | await Promise.all(comments.map((comment) => { 86 | return new Comment(comment).save() 87 | })) 88 | } 89 | 90 | export { users, populateUsers, posts, populatePosts, comments, populateComments } -------------------------------------------------------------------------------- /src/generated/prisma.graphql: -------------------------------------------------------------------------------- 1 | # source: http://localhost:4467 2 | # timestamp: Mon Jun 11 2018 10:52:48 GMT-0400 (EDT) 3 | 4 | type AggregateComment { 5 | count: Int! 6 | } 7 | 8 | type AggregatePost { 9 | count: Int! 10 | } 11 | 12 | type AggregateUser { 13 | count: Int! 14 | } 15 | 16 | type BatchPayload { 17 | """The number of nodes that have been affected by the Batch operation.""" 18 | count: Long! 19 | } 20 | 21 | type Comment implements Node { 22 | id: ID! 23 | text: String! 24 | parent(where: CommentWhereInput): Comment 25 | post(where: PostWhereInput): Post! 26 | author(where: UserWhereInput): User! 27 | createdAt: DateTime! 28 | updatedAt: DateTime! 29 | } 30 | 31 | """A connection to a list of items.""" 32 | type CommentConnection { 33 | """Information to aid in pagination.""" 34 | pageInfo: PageInfo! 35 | 36 | """A list of edges.""" 37 | edges: [CommentEdge]! 38 | aggregate: AggregateComment! 39 | } 40 | 41 | input CommentCreateInput { 42 | text: String! 43 | parent: CommentCreateOneInput 44 | post: PostCreateOneWithoutCommentsInput! 45 | author: UserCreateOneWithoutCommentsInput! 46 | } 47 | 48 | input CommentCreateManyWithoutAuthorInput { 49 | create: [CommentCreateWithoutAuthorInput!] 50 | connect: [CommentWhereUniqueInput!] 51 | } 52 | 53 | input CommentCreateManyWithoutPostInput { 54 | create: [CommentCreateWithoutPostInput!] 55 | connect: [CommentWhereUniqueInput!] 56 | } 57 | 58 | input CommentCreateOneInput { 59 | create: CommentCreateInput 60 | connect: CommentWhereUniqueInput 61 | } 62 | 63 | input CommentCreateWithoutAuthorInput { 64 | text: String! 65 | parent: CommentCreateOneInput 66 | post: PostCreateOneWithoutCommentsInput! 67 | } 68 | 69 | input CommentCreateWithoutPostInput { 70 | text: String! 71 | parent: CommentCreateOneInput 72 | author: UserCreateOneWithoutCommentsInput! 73 | } 74 | 75 | """An edge in a connection.""" 76 | type CommentEdge { 77 | """The item at the end of the edge.""" 78 | node: Comment! 79 | 80 | """A cursor for use in pagination.""" 81 | cursor: String! 82 | } 83 | 84 | enum CommentOrderByInput { 85 | id_ASC 86 | id_DESC 87 | text_ASC 88 | text_DESC 89 | createdAt_ASC 90 | createdAt_DESC 91 | updatedAt_ASC 92 | updatedAt_DESC 93 | } 94 | 95 | type CommentPreviousValues { 96 | id: ID! 97 | text: String! 98 | createdAt: DateTime! 99 | updatedAt: DateTime! 100 | } 101 | 102 | type CommentSubscriptionPayload { 103 | mutation: MutationType! 104 | node: Comment 105 | updatedFields: [String!] 106 | previousValues: CommentPreviousValues 107 | } 108 | 109 | input CommentSubscriptionWhereInput { 110 | """Logical AND on all given filters.""" 111 | AND: [CommentSubscriptionWhereInput!] 112 | 113 | """Logical OR on all given filters.""" 114 | OR: [CommentSubscriptionWhereInput!] 115 | 116 | """Logical NOT on all given filters combined by AND.""" 117 | NOT: [CommentSubscriptionWhereInput!] 118 | 119 | """ 120 | The subscription event gets dispatched when it's listed in mutation_in 121 | """ 122 | mutation_in: [MutationType!] 123 | 124 | """ 125 | The subscription event gets only dispatched when one of the updated fields names is included in this list 126 | """ 127 | updatedFields_contains: String 128 | 129 | """ 130 | The subscription event gets only dispatched when all of the field names included in this list have been updated 131 | """ 132 | updatedFields_contains_every: [String!] 133 | 134 | """ 135 | The subscription event gets only dispatched when some of the field names included in this list have been updated 136 | """ 137 | updatedFields_contains_some: [String!] 138 | node: CommentWhereInput 139 | } 140 | 141 | input CommentUpdateDataInput { 142 | text: String 143 | parent: CommentUpdateOneInput 144 | post: PostUpdateOneWithoutCommentsInput 145 | author: UserUpdateOneWithoutCommentsInput 146 | } 147 | 148 | input CommentUpdateInput { 149 | text: String 150 | parent: CommentUpdateOneInput 151 | post: PostUpdateOneWithoutCommentsInput 152 | author: UserUpdateOneWithoutCommentsInput 153 | } 154 | 155 | input CommentUpdateManyWithoutAuthorInput { 156 | create: [CommentCreateWithoutAuthorInput!] 157 | connect: [CommentWhereUniqueInput!] 158 | disconnect: [CommentWhereUniqueInput!] 159 | delete: [CommentWhereUniqueInput!] 160 | update: [CommentUpdateWithWhereUniqueWithoutAuthorInput!] 161 | upsert: [CommentUpsertWithWhereUniqueWithoutAuthorInput!] 162 | } 163 | 164 | input CommentUpdateManyWithoutPostInput { 165 | create: [CommentCreateWithoutPostInput!] 166 | connect: [CommentWhereUniqueInput!] 167 | disconnect: [CommentWhereUniqueInput!] 168 | delete: [CommentWhereUniqueInput!] 169 | update: [CommentUpdateWithWhereUniqueWithoutPostInput!] 170 | upsert: [CommentUpsertWithWhereUniqueWithoutPostInput!] 171 | } 172 | 173 | input CommentUpdateOneInput { 174 | create: CommentCreateInput 175 | connect: CommentWhereUniqueInput 176 | disconnect: Boolean 177 | delete: Boolean 178 | update: CommentUpdateDataInput 179 | upsert: CommentUpsertNestedInput 180 | } 181 | 182 | input CommentUpdateWithoutAuthorDataInput { 183 | text: String 184 | parent: CommentUpdateOneInput 185 | post: PostUpdateOneWithoutCommentsInput 186 | } 187 | 188 | input CommentUpdateWithoutPostDataInput { 189 | text: String 190 | parent: CommentUpdateOneInput 191 | author: UserUpdateOneWithoutCommentsInput 192 | } 193 | 194 | input CommentUpdateWithWhereUniqueWithoutAuthorInput { 195 | where: CommentWhereUniqueInput! 196 | data: CommentUpdateWithoutAuthorDataInput! 197 | } 198 | 199 | input CommentUpdateWithWhereUniqueWithoutPostInput { 200 | where: CommentWhereUniqueInput! 201 | data: CommentUpdateWithoutPostDataInput! 202 | } 203 | 204 | input CommentUpsertNestedInput { 205 | update: CommentUpdateDataInput! 206 | create: CommentCreateInput! 207 | } 208 | 209 | input CommentUpsertWithWhereUniqueWithoutAuthorInput { 210 | where: CommentWhereUniqueInput! 211 | update: CommentUpdateWithoutAuthorDataInput! 212 | create: CommentCreateWithoutAuthorInput! 213 | } 214 | 215 | input CommentUpsertWithWhereUniqueWithoutPostInput { 216 | where: CommentWhereUniqueInput! 217 | update: CommentUpdateWithoutPostDataInput! 218 | create: CommentCreateWithoutPostInput! 219 | } 220 | 221 | input CommentWhereInput { 222 | """Logical AND on all given filters.""" 223 | AND: [CommentWhereInput!] 224 | 225 | """Logical OR on all given filters.""" 226 | OR: [CommentWhereInput!] 227 | 228 | """Logical NOT on all given filters combined by AND.""" 229 | NOT: [CommentWhereInput!] 230 | id: ID 231 | 232 | """All values that are not equal to given value.""" 233 | id_not: ID 234 | 235 | """All values that are contained in given list.""" 236 | id_in: [ID!] 237 | 238 | """All values that are not contained in given list.""" 239 | id_not_in: [ID!] 240 | 241 | """All values less than the given value.""" 242 | id_lt: ID 243 | 244 | """All values less than or equal the given value.""" 245 | id_lte: ID 246 | 247 | """All values greater than the given value.""" 248 | id_gt: ID 249 | 250 | """All values greater than or equal the given value.""" 251 | id_gte: ID 252 | 253 | """All values containing the given string.""" 254 | id_contains: ID 255 | 256 | """All values not containing the given string.""" 257 | id_not_contains: ID 258 | 259 | """All values starting with the given string.""" 260 | id_starts_with: ID 261 | 262 | """All values not starting with the given string.""" 263 | id_not_starts_with: ID 264 | 265 | """All values ending with the given string.""" 266 | id_ends_with: ID 267 | 268 | """All values not ending with the given string.""" 269 | id_not_ends_with: ID 270 | text: String 271 | 272 | """All values that are not equal to given value.""" 273 | text_not: String 274 | 275 | """All values that are contained in given list.""" 276 | text_in: [String!] 277 | 278 | """All values that are not contained in given list.""" 279 | text_not_in: [String!] 280 | 281 | """All values less than the given value.""" 282 | text_lt: String 283 | 284 | """All values less than or equal the given value.""" 285 | text_lte: String 286 | 287 | """All values greater than the given value.""" 288 | text_gt: String 289 | 290 | """All values greater than or equal the given value.""" 291 | text_gte: String 292 | 293 | """All values containing the given string.""" 294 | text_contains: String 295 | 296 | """All values not containing the given string.""" 297 | text_not_contains: String 298 | 299 | """All values starting with the given string.""" 300 | text_starts_with: String 301 | 302 | """All values not starting with the given string.""" 303 | text_not_starts_with: String 304 | 305 | """All values ending with the given string.""" 306 | text_ends_with: String 307 | 308 | """All values not ending with the given string.""" 309 | text_not_ends_with: String 310 | createdAt: DateTime 311 | 312 | """All values that are not equal to given value.""" 313 | createdAt_not: DateTime 314 | 315 | """All values that are contained in given list.""" 316 | createdAt_in: [DateTime!] 317 | 318 | """All values that are not contained in given list.""" 319 | createdAt_not_in: [DateTime!] 320 | 321 | """All values less than the given value.""" 322 | createdAt_lt: DateTime 323 | 324 | """All values less than or equal the given value.""" 325 | createdAt_lte: DateTime 326 | 327 | """All values greater than the given value.""" 328 | createdAt_gt: DateTime 329 | 330 | """All values greater than or equal the given value.""" 331 | createdAt_gte: DateTime 332 | updatedAt: DateTime 333 | 334 | """All values that are not equal to given value.""" 335 | updatedAt_not: DateTime 336 | 337 | """All values that are contained in given list.""" 338 | updatedAt_in: [DateTime!] 339 | 340 | """All values that are not contained in given list.""" 341 | updatedAt_not_in: [DateTime!] 342 | 343 | """All values less than the given value.""" 344 | updatedAt_lt: DateTime 345 | 346 | """All values less than or equal the given value.""" 347 | updatedAt_lte: DateTime 348 | 349 | """All values greater than the given value.""" 350 | updatedAt_gt: DateTime 351 | 352 | """All values greater than or equal the given value.""" 353 | updatedAt_gte: DateTime 354 | parent: CommentWhereInput 355 | post: PostWhereInput 356 | author: UserWhereInput 357 | } 358 | 359 | input CommentWhereUniqueInput { 360 | id: ID 361 | } 362 | 363 | scalar DateTime 364 | 365 | """ 366 | The `Long` scalar type represents non-fractional signed whole numeric values. 367 | Long can represent values between -(2^63) and 2^63 - 1. 368 | """ 369 | scalar Long 370 | 371 | type Mutation { 372 | createUser(data: UserCreateInput!): User! 373 | createPost(data: PostCreateInput!): Post! 374 | createComment(data: CommentCreateInput!): Comment! 375 | updateUser(data: UserUpdateInput!, where: UserWhereUniqueInput!): User 376 | updatePost(data: PostUpdateInput!, where: PostWhereUniqueInput!): Post 377 | updateComment(data: CommentUpdateInput!, where: CommentWhereUniqueInput!): Comment 378 | deleteUser(where: UserWhereUniqueInput!): User 379 | deletePost(where: PostWhereUniqueInput!): Post 380 | deleteComment(where: CommentWhereUniqueInput!): Comment 381 | upsertUser(where: UserWhereUniqueInput!, create: UserCreateInput!, update: UserUpdateInput!): User! 382 | upsertPost(where: PostWhereUniqueInput!, create: PostCreateInput!, update: PostUpdateInput!): Post! 383 | upsertComment(where: CommentWhereUniqueInput!, create: CommentCreateInput!, update: CommentUpdateInput!): Comment! 384 | updateManyUsers(data: UserUpdateInput!, where: UserWhereInput): BatchPayload! 385 | updateManyPosts(data: PostUpdateInput!, where: PostWhereInput): BatchPayload! 386 | updateManyComments(data: CommentUpdateInput!, where: CommentWhereInput): BatchPayload! 387 | deleteManyUsers(where: UserWhereInput): BatchPayload! 388 | deleteManyPosts(where: PostWhereInput): BatchPayload! 389 | deleteManyComments(where: CommentWhereInput): BatchPayload! 390 | } 391 | 392 | enum MutationType { 393 | CREATED 394 | UPDATED 395 | DELETED 396 | } 397 | 398 | """An object with an ID""" 399 | interface Node { 400 | """The id of the object.""" 401 | id: ID! 402 | } 403 | 404 | """Information about pagination in a connection.""" 405 | type PageInfo { 406 | """When paginating forwards, are there more items?""" 407 | hasNextPage: Boolean! 408 | 409 | """When paginating backwards, are there more items?""" 410 | hasPreviousPage: Boolean! 411 | 412 | """When paginating backwards, the cursor to continue.""" 413 | startCursor: String 414 | 415 | """When paginating forwards, the cursor to continue.""" 416 | endCursor: String 417 | } 418 | 419 | type Post implements Node { 420 | id: ID! 421 | title: String! 422 | body: String! 423 | published: Boolean! 424 | author(where: UserWhereInput): User! 425 | comments(where: CommentWhereInput, orderBy: CommentOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [Comment!] 426 | createdAt: DateTime! 427 | updatedAt: DateTime! 428 | } 429 | 430 | """A connection to a list of items.""" 431 | type PostConnection { 432 | """Information to aid in pagination.""" 433 | pageInfo: PageInfo! 434 | 435 | """A list of edges.""" 436 | edges: [PostEdge]! 437 | aggregate: AggregatePost! 438 | } 439 | 440 | input PostCreateInput { 441 | title: String! 442 | body: String! 443 | published: Boolean! 444 | author: UserCreateOneWithoutPostsInput! 445 | comments: CommentCreateManyWithoutPostInput 446 | } 447 | 448 | input PostCreateManyWithoutAuthorInput { 449 | create: [PostCreateWithoutAuthorInput!] 450 | connect: [PostWhereUniqueInput!] 451 | } 452 | 453 | input PostCreateOneWithoutCommentsInput { 454 | create: PostCreateWithoutCommentsInput 455 | connect: PostWhereUniqueInput 456 | } 457 | 458 | input PostCreateWithoutAuthorInput { 459 | title: String! 460 | body: String! 461 | published: Boolean! 462 | comments: CommentCreateManyWithoutPostInput 463 | } 464 | 465 | input PostCreateWithoutCommentsInput { 466 | title: String! 467 | body: String! 468 | published: Boolean! 469 | author: UserCreateOneWithoutPostsInput! 470 | } 471 | 472 | """An edge in a connection.""" 473 | type PostEdge { 474 | """The item at the end of the edge.""" 475 | node: Post! 476 | 477 | """A cursor for use in pagination.""" 478 | cursor: String! 479 | } 480 | 481 | enum PostOrderByInput { 482 | id_ASC 483 | id_DESC 484 | title_ASC 485 | title_DESC 486 | body_ASC 487 | body_DESC 488 | published_ASC 489 | published_DESC 490 | createdAt_ASC 491 | createdAt_DESC 492 | updatedAt_ASC 493 | updatedAt_DESC 494 | } 495 | 496 | type PostPreviousValues { 497 | id: ID! 498 | title: String! 499 | body: String! 500 | published: Boolean! 501 | createdAt: DateTime! 502 | updatedAt: DateTime! 503 | } 504 | 505 | type PostSubscriptionPayload { 506 | mutation: MutationType! 507 | node: Post 508 | updatedFields: [String!] 509 | previousValues: PostPreviousValues 510 | } 511 | 512 | input PostSubscriptionWhereInput { 513 | """Logical AND on all given filters.""" 514 | AND: [PostSubscriptionWhereInput!] 515 | 516 | """Logical OR on all given filters.""" 517 | OR: [PostSubscriptionWhereInput!] 518 | 519 | """Logical NOT on all given filters combined by AND.""" 520 | NOT: [PostSubscriptionWhereInput!] 521 | 522 | """ 523 | The subscription event gets dispatched when it's listed in mutation_in 524 | """ 525 | mutation_in: [MutationType!] 526 | 527 | """ 528 | The subscription event gets only dispatched when one of the updated fields names is included in this list 529 | """ 530 | updatedFields_contains: String 531 | 532 | """ 533 | The subscription event gets only dispatched when all of the field names included in this list have been updated 534 | """ 535 | updatedFields_contains_every: [String!] 536 | 537 | """ 538 | The subscription event gets only dispatched when some of the field names included in this list have been updated 539 | """ 540 | updatedFields_contains_some: [String!] 541 | node: PostWhereInput 542 | } 543 | 544 | input PostUpdateInput { 545 | title: String 546 | body: String 547 | published: Boolean 548 | author: UserUpdateOneWithoutPostsInput 549 | comments: CommentUpdateManyWithoutPostInput 550 | } 551 | 552 | input PostUpdateManyWithoutAuthorInput { 553 | create: [PostCreateWithoutAuthorInput!] 554 | connect: [PostWhereUniqueInput!] 555 | disconnect: [PostWhereUniqueInput!] 556 | delete: [PostWhereUniqueInput!] 557 | update: [PostUpdateWithWhereUniqueWithoutAuthorInput!] 558 | upsert: [PostUpsertWithWhereUniqueWithoutAuthorInput!] 559 | } 560 | 561 | input PostUpdateOneWithoutCommentsInput { 562 | create: PostCreateWithoutCommentsInput 563 | connect: PostWhereUniqueInput 564 | delete: Boolean 565 | update: PostUpdateWithoutCommentsDataInput 566 | upsert: PostUpsertWithoutCommentsInput 567 | } 568 | 569 | input PostUpdateWithoutAuthorDataInput { 570 | title: String 571 | body: String 572 | published: Boolean 573 | comments: CommentUpdateManyWithoutPostInput 574 | } 575 | 576 | input PostUpdateWithoutCommentsDataInput { 577 | title: String 578 | body: String 579 | published: Boolean 580 | author: UserUpdateOneWithoutPostsInput 581 | } 582 | 583 | input PostUpdateWithWhereUniqueWithoutAuthorInput { 584 | where: PostWhereUniqueInput! 585 | data: PostUpdateWithoutAuthorDataInput! 586 | } 587 | 588 | input PostUpsertWithoutCommentsInput { 589 | update: PostUpdateWithoutCommentsDataInput! 590 | create: PostCreateWithoutCommentsInput! 591 | } 592 | 593 | input PostUpsertWithWhereUniqueWithoutAuthorInput { 594 | where: PostWhereUniqueInput! 595 | update: PostUpdateWithoutAuthorDataInput! 596 | create: PostCreateWithoutAuthorInput! 597 | } 598 | 599 | input PostWhereInput { 600 | """Logical AND on all given filters.""" 601 | AND: [PostWhereInput!] 602 | 603 | """Logical OR on all given filters.""" 604 | OR: [PostWhereInput!] 605 | 606 | """Logical NOT on all given filters combined by AND.""" 607 | NOT: [PostWhereInput!] 608 | id: ID 609 | 610 | """All values that are not equal to given value.""" 611 | id_not: ID 612 | 613 | """All values that are contained in given list.""" 614 | id_in: [ID!] 615 | 616 | """All values that are not contained in given list.""" 617 | id_not_in: [ID!] 618 | 619 | """All values less than the given value.""" 620 | id_lt: ID 621 | 622 | """All values less than or equal the given value.""" 623 | id_lte: ID 624 | 625 | """All values greater than the given value.""" 626 | id_gt: ID 627 | 628 | """All values greater than or equal the given value.""" 629 | id_gte: ID 630 | 631 | """All values containing the given string.""" 632 | id_contains: ID 633 | 634 | """All values not containing the given string.""" 635 | id_not_contains: ID 636 | 637 | """All values starting with the given string.""" 638 | id_starts_with: ID 639 | 640 | """All values not starting with the given string.""" 641 | id_not_starts_with: ID 642 | 643 | """All values ending with the given string.""" 644 | id_ends_with: ID 645 | 646 | """All values not ending with the given string.""" 647 | id_not_ends_with: ID 648 | title: String 649 | 650 | """All values that are not equal to given value.""" 651 | title_not: String 652 | 653 | """All values that are contained in given list.""" 654 | title_in: [String!] 655 | 656 | """All values that are not contained in given list.""" 657 | title_not_in: [String!] 658 | 659 | """All values less than the given value.""" 660 | title_lt: String 661 | 662 | """All values less than or equal the given value.""" 663 | title_lte: String 664 | 665 | """All values greater than the given value.""" 666 | title_gt: String 667 | 668 | """All values greater than or equal the given value.""" 669 | title_gte: String 670 | 671 | """All values containing the given string.""" 672 | title_contains: String 673 | 674 | """All values not containing the given string.""" 675 | title_not_contains: String 676 | 677 | """All values starting with the given string.""" 678 | title_starts_with: String 679 | 680 | """All values not starting with the given string.""" 681 | title_not_starts_with: String 682 | 683 | """All values ending with the given string.""" 684 | title_ends_with: String 685 | 686 | """All values not ending with the given string.""" 687 | title_not_ends_with: String 688 | body: String 689 | 690 | """All values that are not equal to given value.""" 691 | body_not: String 692 | 693 | """All values that are contained in given list.""" 694 | body_in: [String!] 695 | 696 | """All values that are not contained in given list.""" 697 | body_not_in: [String!] 698 | 699 | """All values less than the given value.""" 700 | body_lt: String 701 | 702 | """All values less than or equal the given value.""" 703 | body_lte: String 704 | 705 | """All values greater than the given value.""" 706 | body_gt: String 707 | 708 | """All values greater than or equal the given value.""" 709 | body_gte: String 710 | 711 | """All values containing the given string.""" 712 | body_contains: String 713 | 714 | """All values not containing the given string.""" 715 | body_not_contains: String 716 | 717 | """All values starting with the given string.""" 718 | body_starts_with: String 719 | 720 | """All values not starting with the given string.""" 721 | body_not_starts_with: String 722 | 723 | """All values ending with the given string.""" 724 | body_ends_with: String 725 | 726 | """All values not ending with the given string.""" 727 | body_not_ends_with: String 728 | published: Boolean 729 | 730 | """All values that are not equal to given value.""" 731 | published_not: Boolean 732 | createdAt: DateTime 733 | 734 | """All values that are not equal to given value.""" 735 | createdAt_not: DateTime 736 | 737 | """All values that are contained in given list.""" 738 | createdAt_in: [DateTime!] 739 | 740 | """All values that are not contained in given list.""" 741 | createdAt_not_in: [DateTime!] 742 | 743 | """All values less than the given value.""" 744 | createdAt_lt: DateTime 745 | 746 | """All values less than or equal the given value.""" 747 | createdAt_lte: DateTime 748 | 749 | """All values greater than the given value.""" 750 | createdAt_gt: DateTime 751 | 752 | """All values greater than or equal the given value.""" 753 | createdAt_gte: DateTime 754 | updatedAt: DateTime 755 | 756 | """All values that are not equal to given value.""" 757 | updatedAt_not: DateTime 758 | 759 | """All values that are contained in given list.""" 760 | updatedAt_in: [DateTime!] 761 | 762 | """All values that are not contained in given list.""" 763 | updatedAt_not_in: [DateTime!] 764 | 765 | """All values less than the given value.""" 766 | updatedAt_lt: DateTime 767 | 768 | """All values less than or equal the given value.""" 769 | updatedAt_lte: DateTime 770 | 771 | """All values greater than the given value.""" 772 | updatedAt_gt: DateTime 773 | 774 | """All values greater than or equal the given value.""" 775 | updatedAt_gte: DateTime 776 | author: UserWhereInput 777 | comments_every: CommentWhereInput 778 | comments_some: CommentWhereInput 779 | comments_none: CommentWhereInput 780 | } 781 | 782 | input PostWhereUniqueInput { 783 | id: ID 784 | } 785 | 786 | type Query { 787 | users(where: UserWhereInput, orderBy: UserOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [User]! 788 | posts(where: PostWhereInput, orderBy: PostOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [Post]! 789 | comments(where: CommentWhereInput, orderBy: CommentOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [Comment]! 790 | user(where: UserWhereUniqueInput!): User 791 | post(where: PostWhereUniqueInput!): Post 792 | comment(where: CommentWhereUniqueInput!): Comment 793 | usersConnection(where: UserWhereInput, orderBy: UserOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): UserConnection! 794 | postsConnection(where: PostWhereInput, orderBy: PostOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): PostConnection! 795 | commentsConnection(where: CommentWhereInput, orderBy: CommentOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): CommentConnection! 796 | 797 | """Fetches an object given its ID""" 798 | node( 799 | """The ID of an object""" 800 | id: ID! 801 | ): Node 802 | } 803 | 804 | type Subscription { 805 | user(where: UserSubscriptionWhereInput): UserSubscriptionPayload 806 | post(where: PostSubscriptionWhereInput): PostSubscriptionPayload 807 | comment(where: CommentSubscriptionWhereInput): CommentSubscriptionPayload 808 | } 809 | 810 | type User implements Node { 811 | id: ID! 812 | name: String! 813 | email: String! 814 | password: String! 815 | posts(where: PostWhereInput, orderBy: PostOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [Post!] 816 | comments(where: CommentWhereInput, orderBy: CommentOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [Comment!] 817 | } 818 | 819 | """A connection to a list of items.""" 820 | type UserConnection { 821 | """Information to aid in pagination.""" 822 | pageInfo: PageInfo! 823 | 824 | """A list of edges.""" 825 | edges: [UserEdge]! 826 | aggregate: AggregateUser! 827 | } 828 | 829 | input UserCreateInput { 830 | name: String! 831 | email: String! 832 | password: String! 833 | posts: PostCreateManyWithoutAuthorInput 834 | comments: CommentCreateManyWithoutAuthorInput 835 | } 836 | 837 | input UserCreateOneWithoutCommentsInput { 838 | create: UserCreateWithoutCommentsInput 839 | connect: UserWhereUniqueInput 840 | } 841 | 842 | input UserCreateOneWithoutPostsInput { 843 | create: UserCreateWithoutPostsInput 844 | connect: UserWhereUniqueInput 845 | } 846 | 847 | input UserCreateWithoutCommentsInput { 848 | name: String! 849 | email: String! 850 | password: String! 851 | posts: PostCreateManyWithoutAuthorInput 852 | } 853 | 854 | input UserCreateWithoutPostsInput { 855 | name: String! 856 | email: String! 857 | password: String! 858 | comments: CommentCreateManyWithoutAuthorInput 859 | } 860 | 861 | """An edge in a connection.""" 862 | type UserEdge { 863 | """The item at the end of the edge.""" 864 | node: User! 865 | 866 | """A cursor for use in pagination.""" 867 | cursor: String! 868 | } 869 | 870 | enum UserOrderByInput { 871 | id_ASC 872 | id_DESC 873 | name_ASC 874 | name_DESC 875 | email_ASC 876 | email_DESC 877 | password_ASC 878 | password_DESC 879 | updatedAt_ASC 880 | updatedAt_DESC 881 | createdAt_ASC 882 | createdAt_DESC 883 | } 884 | 885 | type UserPreviousValues { 886 | id: ID! 887 | name: String! 888 | email: String! 889 | password: String! 890 | } 891 | 892 | type UserSubscriptionPayload { 893 | mutation: MutationType! 894 | node: User 895 | updatedFields: [String!] 896 | previousValues: UserPreviousValues 897 | } 898 | 899 | input UserSubscriptionWhereInput { 900 | """Logical AND on all given filters.""" 901 | AND: [UserSubscriptionWhereInput!] 902 | 903 | """Logical OR on all given filters.""" 904 | OR: [UserSubscriptionWhereInput!] 905 | 906 | """Logical NOT on all given filters combined by AND.""" 907 | NOT: [UserSubscriptionWhereInput!] 908 | 909 | """ 910 | The subscription event gets dispatched when it's listed in mutation_in 911 | """ 912 | mutation_in: [MutationType!] 913 | 914 | """ 915 | The subscription event gets only dispatched when one of the updated fields names is included in this list 916 | """ 917 | updatedFields_contains: String 918 | 919 | """ 920 | The subscription event gets only dispatched when all of the field names included in this list have been updated 921 | """ 922 | updatedFields_contains_every: [String!] 923 | 924 | """ 925 | The subscription event gets only dispatched when some of the field names included in this list have been updated 926 | """ 927 | updatedFields_contains_some: [String!] 928 | node: UserWhereInput 929 | } 930 | 931 | input UserUpdateInput { 932 | name: String 933 | email: String 934 | password: String 935 | posts: PostUpdateManyWithoutAuthorInput 936 | comments: CommentUpdateManyWithoutAuthorInput 937 | } 938 | 939 | input UserUpdateOneWithoutCommentsInput { 940 | create: UserCreateWithoutCommentsInput 941 | connect: UserWhereUniqueInput 942 | delete: Boolean 943 | update: UserUpdateWithoutCommentsDataInput 944 | upsert: UserUpsertWithoutCommentsInput 945 | } 946 | 947 | input UserUpdateOneWithoutPostsInput { 948 | create: UserCreateWithoutPostsInput 949 | connect: UserWhereUniqueInput 950 | delete: Boolean 951 | update: UserUpdateWithoutPostsDataInput 952 | upsert: UserUpsertWithoutPostsInput 953 | } 954 | 955 | input UserUpdateWithoutCommentsDataInput { 956 | name: String 957 | email: String 958 | password: String 959 | posts: PostUpdateManyWithoutAuthorInput 960 | } 961 | 962 | input UserUpdateWithoutPostsDataInput { 963 | name: String 964 | email: String 965 | password: String 966 | comments: CommentUpdateManyWithoutAuthorInput 967 | } 968 | 969 | input UserUpsertWithoutCommentsInput { 970 | update: UserUpdateWithoutCommentsDataInput! 971 | create: UserCreateWithoutCommentsInput! 972 | } 973 | 974 | input UserUpsertWithoutPostsInput { 975 | update: UserUpdateWithoutPostsDataInput! 976 | create: UserCreateWithoutPostsInput! 977 | } 978 | 979 | input UserWhereInput { 980 | """Logical AND on all given filters.""" 981 | AND: [UserWhereInput!] 982 | 983 | """Logical OR on all given filters.""" 984 | OR: [UserWhereInput!] 985 | 986 | """Logical NOT on all given filters combined by AND.""" 987 | NOT: [UserWhereInput!] 988 | id: ID 989 | 990 | """All values that are not equal to given value.""" 991 | id_not: ID 992 | 993 | """All values that are contained in given list.""" 994 | id_in: [ID!] 995 | 996 | """All values that are not contained in given list.""" 997 | id_not_in: [ID!] 998 | 999 | """All values less than the given value.""" 1000 | id_lt: ID 1001 | 1002 | """All values less than or equal the given value.""" 1003 | id_lte: ID 1004 | 1005 | """All values greater than the given value.""" 1006 | id_gt: ID 1007 | 1008 | """All values greater than or equal the given value.""" 1009 | id_gte: ID 1010 | 1011 | """All values containing the given string.""" 1012 | id_contains: ID 1013 | 1014 | """All values not containing the given string.""" 1015 | id_not_contains: ID 1016 | 1017 | """All values starting with the given string.""" 1018 | id_starts_with: ID 1019 | 1020 | """All values not starting with the given string.""" 1021 | id_not_starts_with: ID 1022 | 1023 | """All values ending with the given string.""" 1024 | id_ends_with: ID 1025 | 1026 | """All values not ending with the given string.""" 1027 | id_not_ends_with: ID 1028 | name: String 1029 | 1030 | """All values that are not equal to given value.""" 1031 | name_not: String 1032 | 1033 | """All values that are contained in given list.""" 1034 | name_in: [String!] 1035 | 1036 | """All values that are not contained in given list.""" 1037 | name_not_in: [String!] 1038 | 1039 | """All values less than the given value.""" 1040 | name_lt: String 1041 | 1042 | """All values less than or equal the given value.""" 1043 | name_lte: String 1044 | 1045 | """All values greater than the given value.""" 1046 | name_gt: String 1047 | 1048 | """All values greater than or equal the given value.""" 1049 | name_gte: String 1050 | 1051 | """All values containing the given string.""" 1052 | name_contains: String 1053 | 1054 | """All values not containing the given string.""" 1055 | name_not_contains: String 1056 | 1057 | """All values starting with the given string.""" 1058 | name_starts_with: String 1059 | 1060 | """All values not starting with the given string.""" 1061 | name_not_starts_with: String 1062 | 1063 | """All values ending with the given string.""" 1064 | name_ends_with: String 1065 | 1066 | """All values not ending with the given string.""" 1067 | name_not_ends_with: String 1068 | email: String 1069 | 1070 | """All values that are not equal to given value.""" 1071 | email_not: String 1072 | 1073 | """All values that are contained in given list.""" 1074 | email_in: [String!] 1075 | 1076 | """All values that are not contained in given list.""" 1077 | email_not_in: [String!] 1078 | 1079 | """All values less than the given value.""" 1080 | email_lt: String 1081 | 1082 | """All values less than or equal the given value.""" 1083 | email_lte: String 1084 | 1085 | """All values greater than the given value.""" 1086 | email_gt: String 1087 | 1088 | """All values greater than or equal the given value.""" 1089 | email_gte: String 1090 | 1091 | """All values containing the given string.""" 1092 | email_contains: String 1093 | 1094 | """All values not containing the given string.""" 1095 | email_not_contains: String 1096 | 1097 | """All values starting with the given string.""" 1098 | email_starts_with: String 1099 | 1100 | """All values not starting with the given string.""" 1101 | email_not_starts_with: String 1102 | 1103 | """All values ending with the given string.""" 1104 | email_ends_with: String 1105 | 1106 | """All values not ending with the given string.""" 1107 | email_not_ends_with: String 1108 | password: String 1109 | 1110 | """All values that are not equal to given value.""" 1111 | password_not: String 1112 | 1113 | """All values that are contained in given list.""" 1114 | password_in: [String!] 1115 | 1116 | """All values that are not contained in given list.""" 1117 | password_not_in: [String!] 1118 | 1119 | """All values less than the given value.""" 1120 | password_lt: String 1121 | 1122 | """All values less than or equal the given value.""" 1123 | password_lte: String 1124 | 1125 | """All values greater than the given value.""" 1126 | password_gt: String 1127 | 1128 | """All values greater than or equal the given value.""" 1129 | password_gte: String 1130 | 1131 | """All values containing the given string.""" 1132 | password_contains: String 1133 | 1134 | """All values not containing the given string.""" 1135 | password_not_contains: String 1136 | 1137 | """All values starting with the given string.""" 1138 | password_starts_with: String 1139 | 1140 | """All values not starting with the given string.""" 1141 | password_not_starts_with: String 1142 | 1143 | """All values ending with the given string.""" 1144 | password_ends_with: String 1145 | 1146 | """All values not ending with the given string.""" 1147 | password_not_ends_with: String 1148 | posts_every: PostWhereInput 1149 | posts_some: PostWhereInput 1150 | posts_none: PostWhereInput 1151 | comments_every: CommentWhereInput 1152 | comments_some: CommentWhereInput 1153 | comments_none: CommentWhereInput 1154 | } 1155 | 1156 | input UserWhereUniqueInput { 1157 | id: ID 1158 | email: String 1159 | } 1160 | --------------------------------------------------------------------------------