├── src ├── resolvers │ ├── Query.js │ ├── AuthPayload.js │ ├── Subscription.js │ └── Mutation.js ├── utils.js ├── schema.graphql ├── index.js └── generated │ └── prisma.graphql ├── README.md ├── .graphqlconfig.yml ├── database ├── datamodel.graphql ├── prisma.yml └── docker-compose.yml ├── package.json ├── .gitignore └── LICENSE /src/resolvers/Query.js: -------------------------------------------------------------------------------- 1 | function websites(parent, args, context, info) { 2 | return context.db.query.websites({}, info); 3 | } 4 | 5 | module.exports = { 6 | websites, 7 | } -------------------------------------------------------------------------------- /src/resolvers/AuthPayload.js: -------------------------------------------------------------------------------- 1 | function user(root, args, context, info) { 2 | return context.db.query.user({ where: { id: root.user.id } }, info); 3 | } 4 | 5 | module.exports = { user }; 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## LinkShare-Server 2 | 3 | This is a graphQL-Server build with graphql-yoga and backed by a prisma-container. 4 | 5 | WARNING: This project is in development right now and not stable nor finished. 6 | -------------------------------------------------------------------------------- /.graphqlconfig.yml: -------------------------------------------------------------------------------- 1 | projects: 2 | app: 3 | schemaPath: src/schema.graphql 4 | extensions: 5 | endpoints: 6 | default: http://localhost:4000 7 | database: 8 | schemaPath: src/generated/prisma.graphql 9 | extensions: 10 | prisma: database/prisma.yml -------------------------------------------------------------------------------- /database/datamodel.graphql: -------------------------------------------------------------------------------- 1 | type Website { 2 | id: ID! @unique 3 | createdAt: DateTime! 4 | url: String! 5 | belongsTo: User 6 | } 7 | 8 | type User { 9 | id: ID! @unique 10 | name: String! 11 | email: String! @unique 12 | password: String! 13 | websites: [Website!]! 14 | } -------------------------------------------------------------------------------- /src/resolvers/Subscription.js: -------------------------------------------------------------------------------- 1 | function newWebsiteSubscribe (parent, args, context, info) { 2 | return context.db.subscription.website( 3 | { where: { mutation_in: ['CREATED'] } }, 4 | info, 5 | ) 6 | } 7 | 8 | const newWebsite = { 9 | subscribe: newWebsiteSubscribe 10 | } 11 | 12 | module.exports = { 13 | newWebsite, 14 | } -------------------------------------------------------------------------------- /database/prisma.yml: -------------------------------------------------------------------------------- 1 | # The HTTP endpoint for your Prisma API 2 | endpoint: 'http://localhost:4466' 3 | 4 | # Points to the file that holds your data model 5 | datamodel: datamodel.graphql 6 | 7 | # You can only access the API when providing JWTs that are signed with this secret 8 | secret: mysecret123 9 | 10 | hooks: 11 | post-deploy: 12 | - graphql get-schema --project database -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "link-share-server", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "bcryptjs": "^2.4.3", 14 | "graphql-yoga": "^1.16.2", 15 | "jsonwebtoken": "^8.3.0", 16 | "prisma-binding": "^2.1.5" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/utils.js: -------------------------------------------------------------------------------- 1 | const jwt = require('jsonwebtoken'); 2 | const APP_SECRET = 'GraphQL-is-aw3some'; 3 | const API_SECRET = 'mysecret123'; 4 | 5 | function getUserId(context) { 6 | const Authorization = context.request.get('Authorization'); 7 | if (Authorization) { 8 | const token = Authorization.replace('Bearer ', ''); 9 | const { userId } = jwt.verify(token, APP_SECRET); 10 | return userId 11 | } 12 | 13 | throw new Error('Not authenticated'); 14 | } 15 | 16 | module.exports = { 17 | API_SECRET, 18 | APP_SECRET, 19 | getUserId, 20 | } 21 | -------------------------------------------------------------------------------- /src/schema.graphql: -------------------------------------------------------------------------------- 1 | # import Website, WebsiteSubscriptionPayload from "./generated/prisma.graphql" 2 | 3 | type Query { 4 | info: String! 5 | websites: [Website!]! 6 | website(id: ID!): Website 7 | } 8 | 9 | type Mutation { 10 | addWebsite(url: String!): Website! 11 | signup(email: String!, password: String!, name: String!): AuthPayload 12 | login(email: String!, password: String!): AuthPayload 13 | } 14 | 15 | type Subscription { 16 | newWebsite: WebsiteSubscriptionPayload 17 | } 18 | 19 | 20 | type AuthPayload { 21 | token: String 22 | user: User 23 | } 24 | 25 | type User { 26 | id: ID! 27 | name: String! 28 | email: String! 29 | websites: [Website!]! 30 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | 8 | # dependencies 9 | /node_modules 10 | 11 | # IDEs and editors 12 | /.idea 13 | .project 14 | .classpath 15 | .c9/ 16 | *.launch 17 | .settings/ 18 | *.sublime-workspace 19 | 20 | # IDE - VSCode 21 | .vscode/* 22 | !.vscode/settings.json 23 | !.vscode/tasks.json 24 | !.vscode/launch.json 25 | !.vscode/extensions.json 26 | 27 | # misc 28 | /.sass-cache 29 | /connect.lock 30 | /coverage 31 | /libpeerconnection.log 32 | npm-debug.log 33 | yarn-error.log 34 | testem.log 35 | /typings 36 | 37 | # System Files 38 | .DS_Store 39 | Thumbs.db 40 | -------------------------------------------------------------------------------- /database/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | prisma: 4 | image: prismagraphql/prisma:1.14 5 | restart: always 6 | ports: 7 | - "4466:4466" 8 | environment: 9 | PRISMA_CONFIG: | 10 | port: 4466 11 | # uncomment the next line and provide the env var PRISMA_MANAGEMENT_API_SECRET=my-secret to activate cluster security 12 | # managementApiSecret: my-secret 13 | databases: 14 | default: 15 | connector: postgres 16 | host: postgres 17 | port: 5432 18 | user: prisma 19 | password: prisma 20 | migrations: true 21 | postgres: 22 | image: postgres 23 | restart: always 24 | environment: 25 | POSTGRES_USER: prisma 26 | POSTGRES_PASSWORD: prisma 27 | volumes: 28 | - postgres:/var/lib/postgresql/data 29 | volumes: 30 | postgres: -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | const {GraphQLServer} = require('graphql-yoga'); 2 | const {Prisma} = require('prisma-binding'); 3 | const {API_SECRET} = require('../utils'); 4 | 5 | const Query = require('./resolvers/Query'); 6 | const Mutation = require('./resolvers/Mutation'); 7 | const AuthPayload = require('./resolvers/AuthPayload'); 8 | const Subscription = require('./resolvers/Subscription'); 9 | 10 | const resolvers = { 11 | Query, 12 | Mutation, 13 | AuthPayload, 14 | Subscription, 15 | }; 16 | 17 | const server = new GraphQLServer({ 18 | typeDefs: './src/schema.graphql', 19 | resolvers, 20 | context: req => ({ 21 | ...req, 22 | db: new Prisma({ 23 | typeDefs: 'src/generated/prisma.graphql', 24 | endpoint: 'http://localhost:4466', 25 | secret: API_SECRET, 26 | debug: true, 27 | }), 28 | }), 29 | }); 30 | server.start(() => console.log(`Server is running on http://localhost:4000`)); -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 SilvanCodes 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/resolvers/Mutation.js: -------------------------------------------------------------------------------- 1 | const bcrypt = require('bcryptjs'); 2 | const jwt = require('jsonwebtoken'); 3 | const {APP_SECRET, getUserId} = require('../utils'); 4 | 5 | 6 | async function signup(parent, args, context, info) { 7 | 8 | const password = await bcrypt.hash(args.password, 10); 9 | 10 | const user = await context.db.mutation.createUser({ 11 | data: { ...args, password }, 12 | }, `{ id }`); 13 | 14 | const token = jwt.sign({ userId: user.id }, APP_SECRET); 15 | 16 | return { 17 | token, 18 | user, 19 | }; 20 | } 21 | 22 | async function login(parent, args, context, info) { 23 | 24 | const user = await context.db.query.user({ where: { email: args.email } }, ` { id password } `); 25 | if (!user) { 26 | throw new Error('No such user found'); 27 | } 28 | 29 | const valid = await bcrypt.compare(args.password, user.password); 30 | if (!valid) { 31 | throw new Error('Invalid password'); 32 | } 33 | 34 | const token = jwt.sign({ userId: user.id }, APP_SECRET); 35 | 36 | return { 37 | token, 38 | user, 39 | }; 40 | } 41 | 42 | function addWebsite(parent, args, context, info) { 43 | const userId = getUserId(context); 44 | return context.db.mutation.createWebsite( 45 | { 46 | data: { 47 | url: args.url, 48 | belongsTo: { connect: { id: userId } }, 49 | }, 50 | }, 51 | info, 52 | ) 53 | } 54 | 55 | 56 | module.exports = { 57 | signup, 58 | login, 59 | addWebsite, 60 | } 61 | -------------------------------------------------------------------------------- /src/generated/prisma.graphql: -------------------------------------------------------------------------------- 1 | # source: http://localhost:4466 2 | # timestamp: Sat Sep 01 2018 22:03:45 GMT+0200 (CEST) 3 | 4 | type AggregateUser { 5 | count: Int! 6 | } 7 | 8 | type AggregateWebsite { 9 | count: Int! 10 | } 11 | 12 | type BatchPayload { 13 | """The number of nodes that have been affected by the Batch operation.""" 14 | count: Long! 15 | } 16 | 17 | scalar DateTime 18 | 19 | """ 20 | The `Long` scalar type represents non-fractional signed whole numeric values. 21 | Long can represent values between -(2^63) and 2^63 - 1. 22 | """ 23 | scalar Long 24 | 25 | type Mutation { 26 | createWebsite(data: WebsiteCreateInput!): Website! 27 | createUser(data: UserCreateInput!): User! 28 | updateWebsite(data: WebsiteUpdateInput!, where: WebsiteWhereUniqueInput!): Website 29 | updateUser(data: UserUpdateInput!, where: UserWhereUniqueInput!): User 30 | deleteWebsite(where: WebsiteWhereUniqueInput!): Website 31 | deleteUser(where: UserWhereUniqueInput!): User 32 | upsertWebsite(where: WebsiteWhereUniqueInput!, create: WebsiteCreateInput!, update: WebsiteUpdateInput!): Website! 33 | upsertUser(where: UserWhereUniqueInput!, create: UserCreateInput!, update: UserUpdateInput!): User! 34 | updateManyWebsites(data: WebsiteUpdateInput!, where: WebsiteWhereInput): BatchPayload! 35 | updateManyUsers(data: UserUpdateInput!, where: UserWhereInput): BatchPayload! 36 | deleteManyWebsites(where: WebsiteWhereInput): BatchPayload! 37 | deleteManyUsers(where: UserWhereInput): BatchPayload! 38 | } 39 | 40 | enum MutationType { 41 | CREATED 42 | UPDATED 43 | DELETED 44 | } 45 | 46 | """An object with an ID""" 47 | interface Node { 48 | """The id of the object.""" 49 | id: ID! 50 | } 51 | 52 | """Information about pagination in a connection.""" 53 | type PageInfo { 54 | """When paginating forwards, are there more items?""" 55 | hasNextPage: Boolean! 56 | 57 | """When paginating backwards, are there more items?""" 58 | hasPreviousPage: Boolean! 59 | 60 | """When paginating backwards, the cursor to continue.""" 61 | startCursor: String 62 | 63 | """When paginating forwards, the cursor to continue.""" 64 | endCursor: String 65 | } 66 | 67 | type Query { 68 | websites(where: WebsiteWhereInput, orderBy: WebsiteOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [Website]! 69 | users(where: UserWhereInput, orderBy: UserOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [User]! 70 | website(where: WebsiteWhereUniqueInput!): Website 71 | user(where: UserWhereUniqueInput!): User 72 | websitesConnection(where: WebsiteWhereInput, orderBy: WebsiteOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): WebsiteConnection! 73 | usersConnection(where: UserWhereInput, orderBy: UserOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): UserConnection! 74 | 75 | """Fetches an object given its ID""" 76 | node( 77 | """The ID of an object""" 78 | id: ID! 79 | ): Node 80 | } 81 | 82 | type Subscription { 83 | website(where: WebsiteSubscriptionWhereInput): WebsiteSubscriptionPayload 84 | user(where: UserSubscriptionWhereInput): UserSubscriptionPayload 85 | } 86 | 87 | type User implements Node { 88 | id: ID! 89 | name: String! 90 | email: String! 91 | password: String! 92 | websites(where: WebsiteWhereInput, orderBy: WebsiteOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [Website!] 93 | } 94 | 95 | """A connection to a list of items.""" 96 | type UserConnection { 97 | """Information to aid in pagination.""" 98 | pageInfo: PageInfo! 99 | 100 | """A list of edges.""" 101 | edges: [UserEdge]! 102 | aggregate: AggregateUser! 103 | } 104 | 105 | input UserCreateInput { 106 | name: String! 107 | email: String! 108 | password: String! 109 | websites: WebsiteCreateManyWithoutBelongsToInput 110 | } 111 | 112 | input UserCreateOneWithoutWebsitesInput { 113 | create: UserCreateWithoutWebsitesInput 114 | connect: UserWhereUniqueInput 115 | } 116 | 117 | input UserCreateWithoutWebsitesInput { 118 | name: String! 119 | email: String! 120 | password: String! 121 | } 122 | 123 | """An edge in a connection.""" 124 | type UserEdge { 125 | """The item at the end of the edge.""" 126 | node: User! 127 | 128 | """A cursor for use in pagination.""" 129 | cursor: String! 130 | } 131 | 132 | enum UserOrderByInput { 133 | id_ASC 134 | id_DESC 135 | name_ASC 136 | name_DESC 137 | email_ASC 138 | email_DESC 139 | password_ASC 140 | password_DESC 141 | updatedAt_ASC 142 | updatedAt_DESC 143 | createdAt_ASC 144 | createdAt_DESC 145 | } 146 | 147 | type UserPreviousValues { 148 | id: ID! 149 | name: String! 150 | email: String! 151 | password: String! 152 | } 153 | 154 | type UserSubscriptionPayload { 155 | mutation: MutationType! 156 | node: User 157 | updatedFields: [String!] 158 | previousValues: UserPreviousValues 159 | } 160 | 161 | input UserSubscriptionWhereInput { 162 | """Logical AND on all given filters.""" 163 | AND: [UserSubscriptionWhereInput!] 164 | 165 | """Logical OR on all given filters.""" 166 | OR: [UserSubscriptionWhereInput!] 167 | 168 | """Logical NOT on all given filters combined by AND.""" 169 | NOT: [UserSubscriptionWhereInput!] 170 | 171 | """ 172 | The subscription event gets dispatched when it's listed in mutation_in 173 | """ 174 | mutation_in: [MutationType!] 175 | 176 | """ 177 | The subscription event gets only dispatched when one of the updated fields names is included in this list 178 | """ 179 | updatedFields_contains: String 180 | 181 | """ 182 | The subscription event gets only dispatched when all of the field names included in this list have been updated 183 | """ 184 | updatedFields_contains_every: [String!] 185 | 186 | """ 187 | The subscription event gets only dispatched when some of the field names included in this list have been updated 188 | """ 189 | updatedFields_contains_some: [String!] 190 | node: UserWhereInput 191 | } 192 | 193 | input UserUpdateInput { 194 | name: String 195 | email: String 196 | password: String 197 | websites: WebsiteUpdateManyWithoutBelongsToInput 198 | } 199 | 200 | input UserUpdateOneWithoutWebsitesInput { 201 | create: UserCreateWithoutWebsitesInput 202 | connect: UserWhereUniqueInput 203 | disconnect: Boolean 204 | delete: Boolean 205 | update: UserUpdateWithoutWebsitesDataInput 206 | upsert: UserUpsertWithoutWebsitesInput 207 | } 208 | 209 | input UserUpdateWithoutWebsitesDataInput { 210 | name: String 211 | email: String 212 | password: String 213 | } 214 | 215 | input UserUpsertWithoutWebsitesInput { 216 | update: UserUpdateWithoutWebsitesDataInput! 217 | create: UserCreateWithoutWebsitesInput! 218 | } 219 | 220 | input UserWhereInput { 221 | """Logical AND on all given filters.""" 222 | AND: [UserWhereInput!] 223 | 224 | """Logical OR on all given filters.""" 225 | OR: [UserWhereInput!] 226 | 227 | """Logical NOT on all given filters combined by AND.""" 228 | NOT: [UserWhereInput!] 229 | id: ID 230 | 231 | """All values that are not equal to given value.""" 232 | id_not: ID 233 | 234 | """All values that are contained in given list.""" 235 | id_in: [ID!] 236 | 237 | """All values that are not contained in given list.""" 238 | id_not_in: [ID!] 239 | 240 | """All values less than the given value.""" 241 | id_lt: ID 242 | 243 | """All values less than or equal the given value.""" 244 | id_lte: ID 245 | 246 | """All values greater than the given value.""" 247 | id_gt: ID 248 | 249 | """All values greater than or equal the given value.""" 250 | id_gte: ID 251 | 252 | """All values containing the given string.""" 253 | id_contains: ID 254 | 255 | """All values not containing the given string.""" 256 | id_not_contains: ID 257 | 258 | """All values starting with the given string.""" 259 | id_starts_with: ID 260 | 261 | """All values not starting with the given string.""" 262 | id_not_starts_with: ID 263 | 264 | """All values ending with the given string.""" 265 | id_ends_with: ID 266 | 267 | """All values not ending with the given string.""" 268 | id_not_ends_with: ID 269 | name: String 270 | 271 | """All values that are not equal to given value.""" 272 | name_not: String 273 | 274 | """All values that are contained in given list.""" 275 | name_in: [String!] 276 | 277 | """All values that are not contained in given list.""" 278 | name_not_in: [String!] 279 | 280 | """All values less than the given value.""" 281 | name_lt: String 282 | 283 | """All values less than or equal the given value.""" 284 | name_lte: String 285 | 286 | """All values greater than the given value.""" 287 | name_gt: String 288 | 289 | """All values greater than or equal the given value.""" 290 | name_gte: String 291 | 292 | """All values containing the given string.""" 293 | name_contains: String 294 | 295 | """All values not containing the given string.""" 296 | name_not_contains: String 297 | 298 | """All values starting with the given string.""" 299 | name_starts_with: String 300 | 301 | """All values not starting with the given string.""" 302 | name_not_starts_with: String 303 | 304 | """All values ending with the given string.""" 305 | name_ends_with: String 306 | 307 | """All values not ending with the given string.""" 308 | name_not_ends_with: String 309 | email: String 310 | 311 | """All values that are not equal to given value.""" 312 | email_not: String 313 | 314 | """All values that are contained in given list.""" 315 | email_in: [String!] 316 | 317 | """All values that are not contained in given list.""" 318 | email_not_in: [String!] 319 | 320 | """All values less than the given value.""" 321 | email_lt: String 322 | 323 | """All values less than or equal the given value.""" 324 | email_lte: String 325 | 326 | """All values greater than the given value.""" 327 | email_gt: String 328 | 329 | """All values greater than or equal the given value.""" 330 | email_gte: String 331 | 332 | """All values containing the given string.""" 333 | email_contains: String 334 | 335 | """All values not containing the given string.""" 336 | email_not_contains: String 337 | 338 | """All values starting with the given string.""" 339 | email_starts_with: String 340 | 341 | """All values not starting with the given string.""" 342 | email_not_starts_with: String 343 | 344 | """All values ending with the given string.""" 345 | email_ends_with: String 346 | 347 | """All values not ending with the given string.""" 348 | email_not_ends_with: String 349 | password: String 350 | 351 | """All values that are not equal to given value.""" 352 | password_not: String 353 | 354 | """All values that are contained in given list.""" 355 | password_in: [String!] 356 | 357 | """All values that are not contained in given list.""" 358 | password_not_in: [String!] 359 | 360 | """All values less than the given value.""" 361 | password_lt: String 362 | 363 | """All values less than or equal the given value.""" 364 | password_lte: String 365 | 366 | """All values greater than the given value.""" 367 | password_gt: String 368 | 369 | """All values greater than or equal the given value.""" 370 | password_gte: String 371 | 372 | """All values containing the given string.""" 373 | password_contains: String 374 | 375 | """All values not containing the given string.""" 376 | password_not_contains: String 377 | 378 | """All values starting with the given string.""" 379 | password_starts_with: String 380 | 381 | """All values not starting with the given string.""" 382 | password_not_starts_with: String 383 | 384 | """All values ending with the given string.""" 385 | password_ends_with: String 386 | 387 | """All values not ending with the given string.""" 388 | password_not_ends_with: String 389 | websites_every: WebsiteWhereInput 390 | websites_some: WebsiteWhereInput 391 | websites_none: WebsiteWhereInput 392 | } 393 | 394 | input UserWhereUniqueInput { 395 | id: ID 396 | email: String 397 | } 398 | 399 | type Website implements Node { 400 | id: ID! 401 | createdAt: DateTime! 402 | url: String! 403 | belongsTo(where: UserWhereInput): User 404 | } 405 | 406 | """A connection to a list of items.""" 407 | type WebsiteConnection { 408 | """Information to aid in pagination.""" 409 | pageInfo: PageInfo! 410 | 411 | """A list of edges.""" 412 | edges: [WebsiteEdge]! 413 | aggregate: AggregateWebsite! 414 | } 415 | 416 | input WebsiteCreateInput { 417 | url: String! 418 | belongsTo: UserCreateOneWithoutWebsitesInput 419 | } 420 | 421 | input WebsiteCreateManyWithoutBelongsToInput { 422 | create: [WebsiteCreateWithoutBelongsToInput!] 423 | connect: [WebsiteWhereUniqueInput!] 424 | } 425 | 426 | input WebsiteCreateWithoutBelongsToInput { 427 | url: String! 428 | } 429 | 430 | """An edge in a connection.""" 431 | type WebsiteEdge { 432 | """The item at the end of the edge.""" 433 | node: Website! 434 | 435 | """A cursor for use in pagination.""" 436 | cursor: String! 437 | } 438 | 439 | enum WebsiteOrderByInput { 440 | id_ASC 441 | id_DESC 442 | createdAt_ASC 443 | createdAt_DESC 444 | url_ASC 445 | url_DESC 446 | updatedAt_ASC 447 | updatedAt_DESC 448 | } 449 | 450 | type WebsitePreviousValues { 451 | id: ID! 452 | createdAt: DateTime! 453 | url: String! 454 | } 455 | 456 | type WebsiteSubscriptionPayload { 457 | mutation: MutationType! 458 | node: Website 459 | updatedFields: [String!] 460 | previousValues: WebsitePreviousValues 461 | } 462 | 463 | input WebsiteSubscriptionWhereInput { 464 | """Logical AND on all given filters.""" 465 | AND: [WebsiteSubscriptionWhereInput!] 466 | 467 | """Logical OR on all given filters.""" 468 | OR: [WebsiteSubscriptionWhereInput!] 469 | 470 | """Logical NOT on all given filters combined by AND.""" 471 | NOT: [WebsiteSubscriptionWhereInput!] 472 | 473 | """ 474 | The subscription event gets dispatched when it's listed in mutation_in 475 | """ 476 | mutation_in: [MutationType!] 477 | 478 | """ 479 | The subscription event gets only dispatched when one of the updated fields names is included in this list 480 | """ 481 | updatedFields_contains: String 482 | 483 | """ 484 | The subscription event gets only dispatched when all of the field names included in this list have been updated 485 | """ 486 | updatedFields_contains_every: [String!] 487 | 488 | """ 489 | The subscription event gets only dispatched when some of the field names included in this list have been updated 490 | """ 491 | updatedFields_contains_some: [String!] 492 | node: WebsiteWhereInput 493 | } 494 | 495 | input WebsiteUpdateInput { 496 | url: String 497 | belongsTo: UserUpdateOneWithoutWebsitesInput 498 | } 499 | 500 | input WebsiteUpdateManyWithoutBelongsToInput { 501 | create: [WebsiteCreateWithoutBelongsToInput!] 502 | connect: [WebsiteWhereUniqueInput!] 503 | disconnect: [WebsiteWhereUniqueInput!] 504 | delete: [WebsiteWhereUniqueInput!] 505 | update: [WebsiteUpdateWithWhereUniqueWithoutBelongsToInput!] 506 | upsert: [WebsiteUpsertWithWhereUniqueWithoutBelongsToInput!] 507 | } 508 | 509 | input WebsiteUpdateWithoutBelongsToDataInput { 510 | url: String 511 | } 512 | 513 | input WebsiteUpdateWithWhereUniqueWithoutBelongsToInput { 514 | where: WebsiteWhereUniqueInput! 515 | data: WebsiteUpdateWithoutBelongsToDataInput! 516 | } 517 | 518 | input WebsiteUpsertWithWhereUniqueWithoutBelongsToInput { 519 | where: WebsiteWhereUniqueInput! 520 | update: WebsiteUpdateWithoutBelongsToDataInput! 521 | create: WebsiteCreateWithoutBelongsToInput! 522 | } 523 | 524 | input WebsiteWhereInput { 525 | """Logical AND on all given filters.""" 526 | AND: [WebsiteWhereInput!] 527 | 528 | """Logical OR on all given filters.""" 529 | OR: [WebsiteWhereInput!] 530 | 531 | """Logical NOT on all given filters combined by AND.""" 532 | NOT: [WebsiteWhereInput!] 533 | id: ID 534 | 535 | """All values that are not equal to given value.""" 536 | id_not: ID 537 | 538 | """All values that are contained in given list.""" 539 | id_in: [ID!] 540 | 541 | """All values that are not contained in given list.""" 542 | id_not_in: [ID!] 543 | 544 | """All values less than the given value.""" 545 | id_lt: ID 546 | 547 | """All values less than or equal the given value.""" 548 | id_lte: ID 549 | 550 | """All values greater than the given value.""" 551 | id_gt: ID 552 | 553 | """All values greater than or equal the given value.""" 554 | id_gte: ID 555 | 556 | """All values containing the given string.""" 557 | id_contains: ID 558 | 559 | """All values not containing the given string.""" 560 | id_not_contains: ID 561 | 562 | """All values starting with the given string.""" 563 | id_starts_with: ID 564 | 565 | """All values not starting with the given string.""" 566 | id_not_starts_with: ID 567 | 568 | """All values ending with the given string.""" 569 | id_ends_with: ID 570 | 571 | """All values not ending with the given string.""" 572 | id_not_ends_with: ID 573 | createdAt: DateTime 574 | 575 | """All values that are not equal to given value.""" 576 | createdAt_not: DateTime 577 | 578 | """All values that are contained in given list.""" 579 | createdAt_in: [DateTime!] 580 | 581 | """All values that are not contained in given list.""" 582 | createdAt_not_in: [DateTime!] 583 | 584 | """All values less than the given value.""" 585 | createdAt_lt: DateTime 586 | 587 | """All values less than or equal the given value.""" 588 | createdAt_lte: DateTime 589 | 590 | """All values greater than the given value.""" 591 | createdAt_gt: DateTime 592 | 593 | """All values greater than or equal the given value.""" 594 | createdAt_gte: DateTime 595 | url: String 596 | 597 | """All values that are not equal to given value.""" 598 | url_not: String 599 | 600 | """All values that are contained in given list.""" 601 | url_in: [String!] 602 | 603 | """All values that are not contained in given list.""" 604 | url_not_in: [String!] 605 | 606 | """All values less than the given value.""" 607 | url_lt: String 608 | 609 | """All values less than or equal the given value.""" 610 | url_lte: String 611 | 612 | """All values greater than the given value.""" 613 | url_gt: String 614 | 615 | """All values greater than or equal the given value.""" 616 | url_gte: String 617 | 618 | """All values containing the given string.""" 619 | url_contains: String 620 | 621 | """All values not containing the given string.""" 622 | url_not_contains: String 623 | 624 | """All values starting with the given string.""" 625 | url_starts_with: String 626 | 627 | """All values not starting with the given string.""" 628 | url_not_starts_with: String 629 | 630 | """All values ending with the given string.""" 631 | url_ends_with: String 632 | 633 | """All values not ending with the given string.""" 634 | url_not_ends_with: String 635 | belongsTo: UserWhereInput 636 | } 637 | 638 | input WebsiteWhereUniqueInput { 639 | id: ID 640 | } 641 | --------------------------------------------------------------------------------