├── .gitignore ├── prisma-client ├── datamodel.prisma ├── prisma.yml ├── generated │ └── prisma-client │ │ ├── index.js │ │ ├── prisma-schema.js │ │ └── index.d.ts └── docker-compose.yml ├── index.js ├── decodedToken.js ├── README.md ├── package.json ├── schema.js └── resolvers.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /prisma-client/datamodel.prisma: -------------------------------------------------------------------------------- 1 | type User { 2 | id: ID! @id 3 | email: String! @unique 4 | name: String! 5 | password: String! 6 | } 7 | -------------------------------------------------------------------------------- /prisma-client/prisma.yml: -------------------------------------------------------------------------------- 1 | endpoint: http://localhost:4466 2 | datamodel: datamodel.prisma 3 | 4 | generate: 5 | - generator: javascript-client 6 | output: ./generated/prisma-client/ -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const { ApolloServer } = require('apollo-server'); 2 | const typeDefs = require('./schema.js'); 3 | const { prisma } = require('./prisma-client/generated/prisma-client') 4 | const resolvers = require('./resolvers'); 5 | 6 | 7 | const server = new ApolloServer({ 8 | typeDefs, 9 | resolvers, 10 | context : req => ({ 11 | prisma, 12 | req 13 | }) 14 | }); 15 | 16 | server.listen().then(({ url }) => { 17 | console.log(`🚀 Server ready at ${url}`); 18 | }); 19 | -------------------------------------------------------------------------------- /decodedToken.js: -------------------------------------------------------------------------------- 1 | const jwt = require('jsonwebtoken'); 2 | 3 | const decodedToken = (req, requireAuth = true) => { 4 | const header = req.req.headers.authorization; 5 | 6 | if ( header ){ 7 | const token = header.replace('Bearer ', ''); 8 | const decoded = jwt.verify(token, 'supersecret'); 9 | return decoded; 10 | } 11 | 12 | if (requireAuth) { 13 | throw new Error('Login in to access resource'); 14 | } 15 | 16 | return null 17 | } 18 | module.exports = { decodedToken } -------------------------------------------------------------------------------- /prisma-client/generated/prisma-client/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var prisma_lib_1 = require("prisma-client-lib"); 4 | var typeDefs = require("./prisma-schema").typeDefs; 5 | 6 | var models = [ 7 | { 8 | name: "User", 9 | embedded: false 10 | } 11 | ]; 12 | exports.Prisma = prisma_lib_1.makePrismaClientClass({ 13 | typeDefs, 14 | models, 15 | endpoint: `http://localhost:4466` 16 | }); 17 | exports.prisma = new exports.Prisma(); 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JWT Authentication With Apollo Sever. 2 | 3 | This is a little project to demostrate how authentication will be done using Jsonwebtokens(JWT) and Bcrypt on an Apollo GraphQL Server. 4 | 5 | ## To Run the Project on Your Local Machine. 6 | 1. Download and Install Docker Local Machine. 7 | 2. git clone `https://github.com/gbols/Jwt-authentication-apollo-server.git` 8 | 3. run `npm install prisma -g` 9 | 4. cd into `jwt-authentication/prisma-client/generated/prisma-client` 10 | 5. run `npm run setup` 11 | 6. run `npm install` 12 | 7. run `npm run dev` -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jwt-authentication", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "setup": "prisma deploy && prisma generate", 9 | "dev": "nodemon index.js" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC", 14 | "dependencies": { 15 | "apollo-server": "^2.9.6", 16 | "bcrypt": "^3.0.6", 17 | "graphql": "^14.5.8", 18 | "jsonwebtoken": "^8.5.1", 19 | "prisma-client-lib": "^1.34.10" 20 | }, 21 | "devDependencies": { 22 | "nodemon": "^1.19.4" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /schema.js: -------------------------------------------------------------------------------- 1 | const { gql } = require('apollo-server'); 2 | const typeDefs = gql` 3 | type User { 4 | name: String! 5 | email: String! 6 | password: String! 7 | id: Int 8 | } 9 | 10 | type Mutation { 11 | signupUser(data: UserCreateInput!) : AuthPayLoad! 12 | loginUser(data: UserLoginInput!): AuthPayLoad! 13 | } 14 | 15 | input UserCreateInput { 16 | email: String! 17 | name: String! 18 | password: String! 19 | } 20 | 21 | input UserLoginInput { 22 | email: String! 23 | password: String! 24 | } 25 | 26 | type AuthPayLoad { 27 | token: String! 28 | } 29 | type Query { 30 | users: [User] 31 | } 32 | `; 33 | 34 | module.exports = typeDefs; -------------------------------------------------------------------------------- /prisma-client/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | prisma: 4 | image: prismagraphql/prisma:1.34 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 | user: prisma 18 | password: prisma 19 | rawAccess: true 20 | port: 5432 21 | migrations: true 22 | postgres: 23 | image: postgres 24 | restart: always 25 | # Uncomment the next two lines to connect to your your database from outside the Docker environment, e.g. using a database GUI like Postico 26 | # ports: 27 | # - "5432:5432" 28 | environment: 29 | POSTGRES_USER: prisma 30 | POSTGRES_PASSWORD: prisma 31 | volumes: 32 | - postgres:/var/lib/postgresql/data 33 | volumes: 34 | postgres: 35 | -------------------------------------------------------------------------------- /resolvers.js: -------------------------------------------------------------------------------- 1 | const bcrypt = require('bcrypt'); 2 | const jwt = require('jsonwebtoken'); 3 | const { decodedToken } = require('./decodedToken'); 4 | 5 | 6 | const resolvers = { 7 | Query: { 8 | users: async (root, args, { prisma, req }, info) => { 9 | const decoded = decodedToken(req); 10 | return prisma.users(); 11 | }, 12 | }, 13 | Mutation: { 14 | signupUser: async (root, args, { prisma }, info) => { 15 | const { data: { email, name, password } } = args; 16 | const newUser = await prisma.createUser({ 17 | email, 18 | name, 19 | password: bcrypt.hashSync(password, 3) 20 | }); 21 | 22 | return {token : jwt.sign(newUser, "supersecret")}; 23 | }, 24 | loginUser: async (root, args, { prisma }, info) => { 25 | const { data: { email, password } } = args; 26 | const [ theUser ] = await prisma.users({ 27 | where: { 28 | email 29 | } 30 | }) 31 | if (!theUser) throw new Error('Unable to Login'); 32 | const isMatch = bcrypt.compareSync(password, theUser.password); 33 | if (!isMatch) throw new Error('Unable to Login'); 34 | return {token : jwt.sign(theUser, "supersecret")}; 35 | } 36 | } 37 | }; 38 | 39 | module.exports = resolvers; -------------------------------------------------------------------------------- /prisma-client/generated/prisma-client/prisma-schema.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | typeDefs: // Code generated by Prisma (prisma@1.34.8). DO NOT EDIT. 3 | // Please don't change this file manually but run `prisma generate` to update it. 4 | // For more information, please read the docs: https://www.prisma.io/docs/prisma-client/ 5 | 6 | /* GraphQL */ `type AggregateUser { 7 | count: Int! 8 | } 9 | 10 | type BatchPayload { 11 | count: Long! 12 | } 13 | 14 | scalar Long 15 | 16 | type Mutation { 17 | createUser(data: UserCreateInput!): User! 18 | updateUser(data: UserUpdateInput!, where: UserWhereUniqueInput!): User 19 | updateManyUsers(data: UserUpdateManyMutationInput!, where: UserWhereInput): BatchPayload! 20 | upsertUser(where: UserWhereUniqueInput!, create: UserCreateInput!, update: UserUpdateInput!): User! 21 | deleteUser(where: UserWhereUniqueInput!): User 22 | deleteManyUsers(where: UserWhereInput): BatchPayload! 23 | } 24 | 25 | enum MutationType { 26 | CREATED 27 | UPDATED 28 | DELETED 29 | } 30 | 31 | interface Node { 32 | id: ID! 33 | } 34 | 35 | type PageInfo { 36 | hasNextPage: Boolean! 37 | hasPreviousPage: Boolean! 38 | startCursor: String 39 | endCursor: String 40 | } 41 | 42 | type Query { 43 | user(where: UserWhereUniqueInput!): User 44 | users(where: UserWhereInput, orderBy: UserOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [User]! 45 | usersConnection(where: UserWhereInput, orderBy: UserOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): UserConnection! 46 | node(id: ID!): Node 47 | } 48 | 49 | type Subscription { 50 | user(where: UserSubscriptionWhereInput): UserSubscriptionPayload 51 | } 52 | 53 | type User { 54 | id: ID! 55 | email: String! 56 | name: String! 57 | password: String! 58 | } 59 | 60 | type UserConnection { 61 | pageInfo: PageInfo! 62 | edges: [UserEdge]! 63 | aggregate: AggregateUser! 64 | } 65 | 66 | input UserCreateInput { 67 | id: ID 68 | email: String! 69 | name: String! 70 | password: String! 71 | } 72 | 73 | type UserEdge { 74 | node: User! 75 | cursor: String! 76 | } 77 | 78 | enum UserOrderByInput { 79 | id_ASC 80 | id_DESC 81 | email_ASC 82 | email_DESC 83 | name_ASC 84 | name_DESC 85 | password_ASC 86 | password_DESC 87 | } 88 | 89 | type UserPreviousValues { 90 | id: ID! 91 | email: String! 92 | name: String! 93 | password: String! 94 | } 95 | 96 | type UserSubscriptionPayload { 97 | mutation: MutationType! 98 | node: User 99 | updatedFields: [String!] 100 | previousValues: UserPreviousValues 101 | } 102 | 103 | input UserSubscriptionWhereInput { 104 | mutation_in: [MutationType!] 105 | updatedFields_contains: String 106 | updatedFields_contains_every: [String!] 107 | updatedFields_contains_some: [String!] 108 | node: UserWhereInput 109 | AND: [UserSubscriptionWhereInput!] 110 | OR: [UserSubscriptionWhereInput!] 111 | NOT: [UserSubscriptionWhereInput!] 112 | } 113 | 114 | input UserUpdateInput { 115 | email: String 116 | name: String 117 | password: String 118 | } 119 | 120 | input UserUpdateManyMutationInput { 121 | email: String 122 | name: String 123 | password: String 124 | } 125 | 126 | input UserWhereInput { 127 | id: ID 128 | id_not: ID 129 | id_in: [ID!] 130 | id_not_in: [ID!] 131 | id_lt: ID 132 | id_lte: ID 133 | id_gt: ID 134 | id_gte: ID 135 | id_contains: ID 136 | id_not_contains: ID 137 | id_starts_with: ID 138 | id_not_starts_with: ID 139 | id_ends_with: ID 140 | id_not_ends_with: ID 141 | email: String 142 | email_not: String 143 | email_in: [String!] 144 | email_not_in: [String!] 145 | email_lt: String 146 | email_lte: String 147 | email_gt: String 148 | email_gte: String 149 | email_contains: String 150 | email_not_contains: String 151 | email_starts_with: String 152 | email_not_starts_with: String 153 | email_ends_with: String 154 | email_not_ends_with: String 155 | name: String 156 | name_not: String 157 | name_in: [String!] 158 | name_not_in: [String!] 159 | name_lt: String 160 | name_lte: String 161 | name_gt: String 162 | name_gte: String 163 | name_contains: String 164 | name_not_contains: String 165 | name_starts_with: String 166 | name_not_starts_with: String 167 | name_ends_with: String 168 | name_not_ends_with: String 169 | password: String 170 | password_not: String 171 | password_in: [String!] 172 | password_not_in: [String!] 173 | password_lt: String 174 | password_lte: String 175 | password_gt: String 176 | password_gte: String 177 | password_contains: String 178 | password_not_contains: String 179 | password_starts_with: String 180 | password_not_starts_with: String 181 | password_ends_with: String 182 | password_not_ends_with: String 183 | AND: [UserWhereInput!] 184 | OR: [UserWhereInput!] 185 | NOT: [UserWhereInput!] 186 | } 187 | 188 | input UserWhereUniqueInput { 189 | id: ID 190 | email: String 191 | } 192 | ` 193 | } 194 | -------------------------------------------------------------------------------- /prisma-client/generated/prisma-client/index.d.ts: -------------------------------------------------------------------------------- 1 | // Code generated by Prisma (prisma@1.34.8). DO NOT EDIT. 2 | // Please don't change this file manually but run `prisma generate` to update it. 3 | // For more information, please read the docs: https://www.prisma.io/docs/prisma-client/ 4 | 5 | import { DocumentNode } from "graphql"; 6 | import { 7 | makePrismaClientClass, 8 | BaseClientOptions, 9 | Model 10 | } from "prisma-client-lib"; 11 | import { typeDefs } from "./prisma-schema"; 12 | 13 | export type AtLeastOne }> = Partial & 14 | U[keyof U]; 15 | 16 | export type Maybe = T | undefined | null; 17 | 18 | export interface Exists { 19 | user: (where?: UserWhereInput) => Promise; 20 | } 21 | 22 | export interface Node {} 23 | 24 | export type FragmentableArray = Promise> & Fragmentable; 25 | 26 | export interface Fragmentable { 27 | $fragment(fragment: string | DocumentNode): Promise; 28 | } 29 | 30 | export interface Prisma { 31 | $exists: Exists; 32 | $graphql: ( 33 | query: string, 34 | variables?: { [key: string]: any } 35 | ) => Promise; 36 | 37 | /** 38 | * Queries 39 | */ 40 | 41 | user: (where: UserWhereUniqueInput) => UserNullablePromise; 42 | users: (args?: { 43 | where?: UserWhereInput; 44 | orderBy?: UserOrderByInput; 45 | skip?: Int; 46 | after?: String; 47 | before?: String; 48 | first?: Int; 49 | last?: Int; 50 | }) => FragmentableArray; 51 | usersConnection: (args?: { 52 | where?: UserWhereInput; 53 | orderBy?: UserOrderByInput; 54 | skip?: Int; 55 | after?: String; 56 | before?: String; 57 | first?: Int; 58 | last?: Int; 59 | }) => UserConnectionPromise; 60 | node: (args: { id: ID_Output }) => Node; 61 | 62 | /** 63 | * Mutations 64 | */ 65 | 66 | createUser: (data: UserCreateInput) => UserPromise; 67 | updateUser: (args: { 68 | data: UserUpdateInput; 69 | where: UserWhereUniqueInput; 70 | }) => UserPromise; 71 | updateManyUsers: (args: { 72 | data: UserUpdateManyMutationInput; 73 | where?: UserWhereInput; 74 | }) => BatchPayloadPromise; 75 | upsertUser: (args: { 76 | where: UserWhereUniqueInput; 77 | create: UserCreateInput; 78 | update: UserUpdateInput; 79 | }) => UserPromise; 80 | deleteUser: (where: UserWhereUniqueInput) => UserPromise; 81 | deleteManyUsers: (where?: UserWhereInput) => BatchPayloadPromise; 82 | 83 | /** 84 | * Subscriptions 85 | */ 86 | 87 | $subscribe: Subscription; 88 | } 89 | 90 | export interface Subscription { 91 | user: ( 92 | where?: UserSubscriptionWhereInput 93 | ) => UserSubscriptionPayloadSubscription; 94 | } 95 | 96 | export interface ClientConstructor { 97 | new (options?: BaseClientOptions): T; 98 | } 99 | 100 | /** 101 | * Types 102 | */ 103 | 104 | export type UserOrderByInput = 105 | | "id_ASC" 106 | | "id_DESC" 107 | | "email_ASC" 108 | | "email_DESC" 109 | | "name_ASC" 110 | | "name_DESC" 111 | | "password_ASC" 112 | | "password_DESC"; 113 | 114 | export type MutationType = "CREATED" | "UPDATED" | "DELETED"; 115 | 116 | export interface UserCreateInput { 117 | id?: Maybe; 118 | email: String; 119 | name: String; 120 | password: String; 121 | } 122 | 123 | export interface UserUpdateInput { 124 | email?: Maybe; 125 | name?: Maybe; 126 | password?: Maybe; 127 | } 128 | 129 | export interface UserUpdateManyMutationInput { 130 | email?: Maybe; 131 | name?: Maybe; 132 | password?: Maybe; 133 | } 134 | 135 | export interface UserWhereInput { 136 | id?: Maybe; 137 | id_not?: Maybe; 138 | id_in?: Maybe; 139 | id_not_in?: Maybe; 140 | id_lt?: Maybe; 141 | id_lte?: Maybe; 142 | id_gt?: Maybe; 143 | id_gte?: Maybe; 144 | id_contains?: Maybe; 145 | id_not_contains?: Maybe; 146 | id_starts_with?: Maybe; 147 | id_not_starts_with?: Maybe; 148 | id_ends_with?: Maybe; 149 | id_not_ends_with?: Maybe; 150 | email?: Maybe; 151 | email_not?: Maybe; 152 | email_in?: Maybe; 153 | email_not_in?: Maybe; 154 | email_lt?: Maybe; 155 | email_lte?: Maybe; 156 | email_gt?: Maybe; 157 | email_gte?: Maybe; 158 | email_contains?: Maybe; 159 | email_not_contains?: Maybe; 160 | email_starts_with?: Maybe; 161 | email_not_starts_with?: Maybe; 162 | email_ends_with?: Maybe; 163 | email_not_ends_with?: Maybe; 164 | name?: Maybe; 165 | name_not?: Maybe; 166 | name_in?: Maybe; 167 | name_not_in?: Maybe; 168 | name_lt?: Maybe; 169 | name_lte?: Maybe; 170 | name_gt?: Maybe; 171 | name_gte?: Maybe; 172 | name_contains?: Maybe; 173 | name_not_contains?: Maybe; 174 | name_starts_with?: Maybe; 175 | name_not_starts_with?: Maybe; 176 | name_ends_with?: Maybe; 177 | name_not_ends_with?: Maybe; 178 | password?: Maybe; 179 | password_not?: Maybe; 180 | password_in?: Maybe; 181 | password_not_in?: Maybe; 182 | password_lt?: Maybe; 183 | password_lte?: Maybe; 184 | password_gt?: Maybe; 185 | password_gte?: Maybe; 186 | password_contains?: Maybe; 187 | password_not_contains?: Maybe; 188 | password_starts_with?: Maybe; 189 | password_not_starts_with?: Maybe; 190 | password_ends_with?: Maybe; 191 | password_not_ends_with?: Maybe; 192 | AND?: Maybe; 193 | OR?: Maybe; 194 | NOT?: Maybe; 195 | } 196 | 197 | export interface UserSubscriptionWhereInput { 198 | mutation_in?: Maybe; 199 | updatedFields_contains?: Maybe; 200 | updatedFields_contains_every?: Maybe; 201 | updatedFields_contains_some?: Maybe; 202 | node?: Maybe; 203 | AND?: Maybe; 204 | OR?: Maybe; 205 | NOT?: Maybe; 206 | } 207 | 208 | export type UserWhereUniqueInput = AtLeastOne<{ 209 | id: Maybe; 210 | email?: Maybe; 211 | }>; 212 | 213 | export interface NodeNode { 214 | id: ID_Output; 215 | } 216 | 217 | export interface AggregateUser { 218 | count: Int; 219 | } 220 | 221 | export interface AggregateUserPromise 222 | extends Promise, 223 | Fragmentable { 224 | count: () => Promise; 225 | } 226 | 227 | export interface AggregateUserSubscription 228 | extends Promise>, 229 | Fragmentable { 230 | count: () => Promise>; 231 | } 232 | 233 | export interface BatchPayload { 234 | count: Long; 235 | } 236 | 237 | export interface BatchPayloadPromise 238 | extends Promise, 239 | Fragmentable { 240 | count: () => Promise; 241 | } 242 | 243 | export interface BatchPayloadSubscription 244 | extends Promise>, 245 | Fragmentable { 246 | count: () => Promise>; 247 | } 248 | 249 | export interface UserPreviousValues { 250 | id: ID_Output; 251 | email: String; 252 | name: String; 253 | password: String; 254 | } 255 | 256 | export interface UserPreviousValuesPromise 257 | extends Promise, 258 | Fragmentable { 259 | id: () => Promise; 260 | email: () => Promise; 261 | name: () => Promise; 262 | password: () => Promise; 263 | } 264 | 265 | export interface UserPreviousValuesSubscription 266 | extends Promise>, 267 | Fragmentable { 268 | id: () => Promise>; 269 | email: () => Promise>; 270 | name: () => Promise>; 271 | password: () => Promise>; 272 | } 273 | 274 | export interface UserEdge { 275 | node: User; 276 | cursor: String; 277 | } 278 | 279 | export interface UserEdgePromise extends Promise, Fragmentable { 280 | node: () => T; 281 | cursor: () => Promise; 282 | } 283 | 284 | export interface UserEdgeSubscription 285 | extends Promise>, 286 | Fragmentable { 287 | node: () => T; 288 | cursor: () => Promise>; 289 | } 290 | 291 | export interface UserSubscriptionPayload { 292 | mutation: MutationType; 293 | node: User; 294 | updatedFields: String[]; 295 | previousValues: UserPreviousValues; 296 | } 297 | 298 | export interface UserSubscriptionPayloadPromise 299 | extends Promise, 300 | Fragmentable { 301 | mutation: () => Promise; 302 | node: () => T; 303 | updatedFields: () => Promise; 304 | previousValues: () => T; 305 | } 306 | 307 | export interface UserSubscriptionPayloadSubscription 308 | extends Promise>, 309 | Fragmentable { 310 | mutation: () => Promise>; 311 | node: () => T; 312 | updatedFields: () => Promise>; 313 | previousValues: () => T; 314 | } 315 | 316 | export interface User { 317 | id: ID_Output; 318 | email: String; 319 | name: String; 320 | password: String; 321 | } 322 | 323 | export interface UserPromise extends Promise, Fragmentable { 324 | id: () => Promise; 325 | email: () => Promise; 326 | name: () => Promise; 327 | password: () => Promise; 328 | } 329 | 330 | export interface UserSubscription 331 | extends Promise>, 332 | Fragmentable { 333 | id: () => Promise>; 334 | email: () => Promise>; 335 | name: () => Promise>; 336 | password: () => Promise>; 337 | } 338 | 339 | export interface UserNullablePromise 340 | extends Promise, 341 | Fragmentable { 342 | id: () => Promise; 343 | email: () => Promise; 344 | name: () => Promise; 345 | password: () => Promise; 346 | } 347 | 348 | export interface UserConnection { 349 | pageInfo: PageInfo; 350 | edges: UserEdge[]; 351 | } 352 | 353 | export interface UserConnectionPromise 354 | extends Promise, 355 | Fragmentable { 356 | pageInfo: () => T; 357 | edges: >() => T; 358 | aggregate: () => T; 359 | } 360 | 361 | export interface UserConnectionSubscription 362 | extends Promise>, 363 | Fragmentable { 364 | pageInfo: () => T; 365 | edges: >>() => T; 366 | aggregate: () => T; 367 | } 368 | 369 | export interface PageInfo { 370 | hasNextPage: Boolean; 371 | hasPreviousPage: Boolean; 372 | startCursor?: String; 373 | endCursor?: String; 374 | } 375 | 376 | export interface PageInfoPromise extends Promise, Fragmentable { 377 | hasNextPage: () => Promise; 378 | hasPreviousPage: () => Promise; 379 | startCursor: () => Promise; 380 | endCursor: () => Promise; 381 | } 382 | 383 | export interface PageInfoSubscription 384 | extends Promise>, 385 | Fragmentable { 386 | hasNextPage: () => Promise>; 387 | hasPreviousPage: () => Promise>; 388 | startCursor: () => Promise>; 389 | endCursor: () => Promise>; 390 | } 391 | 392 | /* 393 | The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text. 394 | */ 395 | export type String = string; 396 | 397 | export type Long = string; 398 | 399 | /* 400 | The `ID` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `"4"`) or integer (such as `4`) input value will be accepted as an ID. 401 | */ 402 | export type ID_Input = string | number; 403 | export type ID_Output = string; 404 | 405 | /* 406 | The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. 407 | */ 408 | export type Int = number; 409 | 410 | /* 411 | The `Boolean` scalar type represents `true` or `false`. 412 | */ 413 | export type Boolean = boolean; 414 | 415 | /** 416 | * Model Metadata 417 | */ 418 | 419 | export const models: Model[] = [ 420 | { 421 | name: "User", 422 | embedded: false 423 | } 424 | ]; 425 | 426 | /** 427 | * Type Defs 428 | */ 429 | 430 | export const prisma: Prisma; 431 | --------------------------------------------------------------------------------