├── .gitignore ├── LICENSE ├── README.md ├── api ├── .gitignore ├── index.ts ├── package.json ├── tsconfig.json └── tslint.json ├── now.json ├── package.json ├── www ├── .babelrc ├── .gitignore ├── .nowignore ├── __generated__ │ ├── BooksQuery.ts │ └── globalTypes.ts ├── apollo.config.js ├── lib │ ├── init-apollo.js │ └── with-apollo-client.js ├── next.config.js ├── package.json ├── pages │ ├── _app.js │ └── index.tsx ├── schema.json ├── tsconfig.json └── yarn.lock └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Soft Spiders 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [SOFTSPIDERS](https://github.com/softspiders/softspiders) 2 | 3 | # An Apollo Server & Client in a Next.js in a yarn Workspace deployed with Now 2.0 4 | 5 | This example combines: 6 | 7 | - [Yarn Workspaces](https://yarnpkg.com/lang/en/docs/workspaces/) 8 | - [React Apollo](https://github.com/apollographql/react-apollo) 9 | - [Apollo Server](https://github.com/apollographql/apollo-server) 10 | - [Apollo Codegen](https://github.com/apollographql/apollo-tooling) 11 | - [Next.js](https://github.com/zeit/next.js/) 12 | - [Now 2.0](https://github.com/zeit/now-cli) 13 | - [Typescript](https://github.com/Microsoft/TypeScript) 14 | 15 | to build a Monorepo FullStack GraphQL App which can be deployed by a single command `now`. 16 | 17 | ## Feature tags 18 | 19 | - apollo 20 | - graphql 21 | - next 22 | - now 23 | - react 24 | - starter 25 | - template 26 | - typescript 27 | - yarn-workspaces 28 | - zeit 29 | 30 | ## Direct ancestors 31 | 32 | - [Minimal Next in TypeScript](https://github.com/softspiders/next-typescript) 33 | - [Zeit Now "HelloWorld" example](https://github.com/softspiders/now) 34 | 35 | --- 36 | 37 | ## Install 38 | 39 | ```sh 40 | yarn 41 | ``` 42 | 43 | ## Running dev-mode 44 | 45 | ```sh 46 | cd api && yarn dev 47 | ``` 48 | 49 | ```sh 50 | cd www && yarn dev 51 | ``` 52 | 53 | ## Generate Types 54 | 55 | With api running 56 | 57 | ```sh 58 | cd www && yarn gen 59 | ``` 60 | 61 | ## Deploy 62 | 63 | ```sh 64 | now 65 | ``` 66 | 67 | ## Authors 68 | 69 | * [Dennis Kortsch](https://github.com/DennisKo) - original code 70 | * [Alexander Lapygin](https://github.com/AlexanderLapygin) - catching in [Soft Spiders Net](https://github.com/softspider) 71 | 72 | ## Inspired by 73 | 74 | [An Apollo Server & Client in a yarn Workspace deployed with Zeit 2.0](https://github.com/DennisKo/zeit-now-next-apollo-typescript-example) 75 | 76 | ## License 77 | 78 | Licensed under the [MIT license](./LICENSE). 79 | -------------------------------------------------------------------------------- /api/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | yarn-error.log -------------------------------------------------------------------------------- /api/index.ts: -------------------------------------------------------------------------------- 1 | import { ApolloServer, gql } from "apollo-server-express"; 2 | import express from "express"; 3 | 4 | const books = [ 5 | { 6 | title: "Harry Potter and the Chamber of Secrets", 7 | author: "J.K. Rowling" 8 | }, 9 | { 10 | title: "Jurassic Park", 11 | author: "Michael Crichton" 12 | } 13 | ]; 14 | 15 | const typeDefs = gql` 16 | type Book { 17 | title: String 18 | author: String 19 | } 20 | 21 | type Query { 22 | books: [Book] 23 | } 24 | `; 25 | 26 | const resolvers = { 27 | Query: { 28 | books: () => books 29 | } 30 | }; 31 | 32 | const server = new ApolloServer({ 33 | typeDefs, 34 | resolvers, 35 | introspection: true, 36 | playground: { endpoint: "/api" } 37 | }); 38 | 39 | const app = express(); 40 | 41 | server.applyMiddleware({ app, path: "/api" }); 42 | 43 | const port = process.env.PORT || 4000; 44 | 45 | app.listen({ port }, () => 46 | console.log(`🚀 Server ready at ${server.graphqlPath}`) 47 | ); 48 | 49 | export default app; 50 | -------------------------------------------------------------------------------- /api/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "api", 3 | "version": "1.0.0", 4 | "main": "index.ts", 5 | "license": "MIT", 6 | "scripts": { 7 | "dev": "nodemon -e ts,graphql --ignore tmp/**/* --exec ts-node index.ts" 8 | }, 9 | "dependencies": { 10 | "apollo-server-express": "^2.3.1", 11 | "express": "^4.16.4", 12 | "graphql": "^14.0.2" 13 | }, 14 | "devDependencies": { 15 | "@types/express": "^4.16.0", 16 | "@types/graphql": "^14.0.3", 17 | "nodemon": "^1.18.9", 18 | "ts-node": "^7.0.1", 19 | "tslint": "^5.12.0", 20 | "tslint-config-prettier": "^1.17.0", 21 | "typescript": "^3.2.2" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /api/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "moduleResolution": "node", 4 | "target": "es2017", 5 | "outDir": "dist", 6 | "lib": ["esnext"], 7 | "esModuleInterop": true 8 | }, 9 | "exclude": ["node_modules"] 10 | } 11 | -------------------------------------------------------------------------------- /api/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultSeverity": "error", 3 | "extends": ["tslint:recommended", "tslint-config-prettier"], 4 | "jsRules": {}, 5 | "rules": { 6 | "object-literal-sort-keys": false 7 | }, 8 | "rulesDirectory": [], 9 | "linterOptions": { 10 | "exclude": ["node_modules/**/*.ts"] 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /now.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 2, 3 | "name": "apollo-zeit", 4 | "regions": ["bru"], 5 | "builds": [ 6 | { "src": "www/next.config.js", "use": "@now/next" }, 7 | { "src": "api/index.ts", "use": "@now/node@canary" } 8 | ], 9 | "routes": [ 10 | { "src": "/api", "dest": "api/index.ts" }, 11 | { "src": "/(.*)", "dest": "www/$1" } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "workspaces": [ 4 | "api", 5 | "www" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /www/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["next/babel", "@zeit/next-typescript/babel"] 3 | } 4 | -------------------------------------------------------------------------------- /www/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | yarn-error.log 3 | .next -------------------------------------------------------------------------------- /www/.nowignore: -------------------------------------------------------------------------------- 1 | README.md 2 | .next -------------------------------------------------------------------------------- /www/__generated__/BooksQuery.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | // This file was automatically generated and should not be edited. 3 | 4 | // ==================================================== 5 | // GraphQL query operation: BooksQuery 6 | // ==================================================== 7 | 8 | export interface BooksQuery_books { 9 | __typename: "Book"; 10 | title: string | null; 11 | author: string | null; 12 | } 13 | 14 | export interface BooksQuery { 15 | books: (BooksQuery_books | null)[] | null; 16 | } 17 | -------------------------------------------------------------------------------- /www/__generated__/globalTypes.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | // This file was automatically generated and should not be edited. 3 | 4 | //============================================================== 5 | // START Enums and Input Objects 6 | //============================================================== 7 | 8 | //============================================================== 9 | // END Enums and Input Objects 10 | //============================================================== 11 | -------------------------------------------------------------------------------- /www/apollo.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | client: { 3 | name: "React Next App", 4 | includes: ["pages/**", "lib/**"], 5 | service: { 6 | name: "api", 7 | url: "http://localhost:4000/api", 8 | // optional disable SSL validation check 9 | skipSSLValidation: true 10 | } 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /www/lib/init-apollo.js: -------------------------------------------------------------------------------- 1 | import { ApolloClient, InMemoryCache, HttpLink } from "apollo-boost"; 2 | import fetch from "isomorphic-unfetch"; 3 | 4 | let apolloClient = null; 5 | 6 | // Polyfill fetch() on the server (used by apollo-client) 7 | if (!process.browser) { 8 | global.fetch = fetch; 9 | } 10 | 11 | function create(initialState) { 12 | // Check out https://github.com/zeit/next.js/pull/4611 if you want to use the AWSAppSyncClient 13 | return new ApolloClient({ 14 | connectToDevTools: process.browser, 15 | ssrMode: !process.browser, // Disables forceFetch on the server (so queries are only run once) 16 | 17 | link: new HttpLink({ 18 | uri: 19 | process.env.NODE_ENV === "production" 20 | ? "/api" 21 | : "http://localhost:4000/api", // Server URL (must be absolute) 22 | credentials: "same-origin" // Additional fetch() options like `credentials` or `headers` 23 | }), 24 | cache: new InMemoryCache().restore(initialState || {}) 25 | }); 26 | } 27 | 28 | export default function initApollo(initialState) { 29 | // Make sure to create a new client for every server-side request so that data 30 | // isn't shared between connections (which would be bad) 31 | if (!process.browser) { 32 | return create(initialState); 33 | } 34 | 35 | // Reuse client on the client-side 36 | if (!apolloClient) { 37 | apolloClient = create(initialState); 38 | } 39 | 40 | return apolloClient; 41 | } 42 | -------------------------------------------------------------------------------- /www/lib/with-apollo-client.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import initApollo from "./init-apollo"; 3 | import Head from "next/head"; 4 | import { getDataFromTree } from "react-apollo"; 5 | 6 | export default App => { 7 | return class Apollo extends React.Component { 8 | static displayName = "withApollo(App)"; 9 | static async getInitialProps(ctx) { 10 | const { Component, router } = ctx; 11 | 12 | let appProps = {}; 13 | if (App.getInitialProps) { 14 | appProps = await App.getInitialProps(ctx); 15 | } 16 | 17 | // Run all GraphQL queries in the component tree 18 | // and extract the resulting data 19 | const apollo = initApollo(); 20 | if (!process.browser) { 21 | try { 22 | // Run all GraphQL queries 23 | await getDataFromTree( 24 | 30 | ); 31 | } catch (error) { 32 | // Prevent Apollo Client GraphQL errors from crashing SSR. 33 | // Handle them in components via the data.error prop: 34 | // https://www.apollographql.com/docs/react/api/react-apollo.html#graphql-query-data-error 35 | console.error("Error while running `getDataFromTree`", error); 36 | } 37 | 38 | // getDataFromTree does not call componentWillUnmount 39 | // head side effect therefore need to be cleared manually 40 | Head.rewind(); 41 | } 42 | 43 | // Extract query data from the Apollo store 44 | const apolloState = apollo.cache.extract(); 45 | 46 | return { 47 | ...appProps, 48 | apolloState 49 | }; 50 | } 51 | 52 | constructor(props) { 53 | super(props); 54 | this.apolloClient = initApollo(props.apolloState); 55 | } 56 | 57 | render() { 58 | return ; 59 | } 60 | }; 61 | }; 62 | -------------------------------------------------------------------------------- /www/next.config.js: -------------------------------------------------------------------------------- 1 | const { PHASE_PRODUCTION_SERVER } = 2 | process.env.NODE_ENV === "development" 3 | ? {} // We're never in "production server" phase when in development mode 4 | : !process.env.NOW_REGION 5 | ? require("next/constants") // Get values from `next` package when building locally 6 | : require("next-server/constants"); // Get values from `next-server` package when building on now v2 7 | 8 | module.exports = (phase, { defaultConfig }) => { 9 | if (phase === PHASE_PRODUCTION_SERVER) { 10 | // Config used to run in production. 11 | return {}; 12 | } 13 | 14 | const withTypescript = require("@zeit/next-typescript"); 15 | 16 | return withTypescript(); 17 | }; 18 | -------------------------------------------------------------------------------- /www/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "www", 3 | "version": "1.0.0", 4 | "scripts": { 5 | "dev": "next", 6 | "build": "next build", 7 | "start": "next start", 8 | "gen": "apollo service:download && apollo client:codegen --target typescript --localSchemaFile=schema.json --outputFlat" 9 | }, 10 | "dependencies": { 11 | "@zeit/next-typescript": "^1.1.1", 12 | "apollo-boost": "^0.1.23", 13 | "graphql": "^14.0.2", 14 | "isomorphic-unfetch": "3.0.0", 15 | "next": "^7.0.2", 16 | "react": "^16.7.0", 17 | "react-apollo": "^2.3.3", 18 | "react-dom": "^16.7.0" 19 | }, 20 | "devDependencies": { 21 | "@types/graphql": "^14.0.3", 22 | "@types/next": "^7.0.5", 23 | "@types/react": "^16.7.18", 24 | "@types/react-dom": "^16.0.11", 25 | "apollo": "^2.1.8" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /www/pages/_app.js: -------------------------------------------------------------------------------- 1 | import App, { Container } from "next/app"; 2 | import React from "react"; 3 | import withApolloClient from "../lib/with-apollo-client"; 4 | import { ApolloProvider } from "react-apollo"; 5 | 6 | class MyApp extends App { 7 | render() { 8 | const { Component, pageProps, apolloClient } = this.props; 9 | return ( 10 | 11 | 12 | 13 | 14 | 15 | ); 16 | } 17 | } 18 | 19 | export default withApolloClient(MyApp); 20 | -------------------------------------------------------------------------------- /www/pages/index.tsx: -------------------------------------------------------------------------------- 1 | import { Query } from "react-apollo"; 2 | import gql from "graphql-tag"; 3 | import * as React from "react"; 4 | import { BooksQuery } from "../__generated__/BooksQuery"; 5 | 6 | const booksQuery = gql` 7 | query BooksQuery { 8 | books { 9 | title 10 | author 11 | } 12 | } 13 | `; 14 | 15 | export default class BookList extends React.Component<{}, {}> { 16 | render() { 17 | return ( 18 | query={booksQuery}> 19 | {({ loading, error, data: { books } }) => { 20 | if (error) return
{JSON.stringify(error)}
; 21 | if (loading) return
Loading
; 22 | 23 | return ( 24 |
25 |
    26 | {books.map((book, index) => ( 27 |
  • 28 | {index + 1}. 29 |
    {book.title}
    30 |
    {book.author}
    31 |
  • 32 | ))} 33 |
34 |
35 | ); 36 | }} 37 | 38 | ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /www/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "__schema": { 3 | "queryType": { 4 | "name": "Query" 5 | }, 6 | "mutationType": null, 7 | "subscriptionType": null, 8 | "types": [ 9 | { 10 | "kind": "OBJECT", 11 | "name": "Query", 12 | "description": null, 13 | "fields": [ 14 | { 15 | "name": "books", 16 | "description": null, 17 | "args": [], 18 | "type": { 19 | "kind": "LIST", 20 | "name": null, 21 | "ofType": { 22 | "kind": "OBJECT", 23 | "name": "Book", 24 | "ofType": null 25 | } 26 | }, 27 | "isDeprecated": false, 28 | "deprecationReason": null 29 | } 30 | ], 31 | "inputFields": null, 32 | "interfaces": [], 33 | "enumValues": null, 34 | "possibleTypes": null 35 | }, 36 | { 37 | "kind": "OBJECT", 38 | "name": "Book", 39 | "description": null, 40 | "fields": [ 41 | { 42 | "name": "title", 43 | "description": null, 44 | "args": [], 45 | "type": { 46 | "kind": "SCALAR", 47 | "name": "String", 48 | "ofType": null 49 | }, 50 | "isDeprecated": false, 51 | "deprecationReason": null 52 | }, 53 | { 54 | "name": "author", 55 | "description": null, 56 | "args": [], 57 | "type": { 58 | "kind": "SCALAR", 59 | "name": "String", 60 | "ofType": null 61 | }, 62 | "isDeprecated": false, 63 | "deprecationReason": null 64 | } 65 | ], 66 | "inputFields": null, 67 | "interfaces": [], 68 | "enumValues": null, 69 | "possibleTypes": null 70 | }, 71 | { 72 | "kind": "SCALAR", 73 | "name": "String", 74 | "description": "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.", 75 | "fields": null, 76 | "inputFields": null, 77 | "interfaces": null, 78 | "enumValues": null, 79 | "possibleTypes": null 80 | }, 81 | { 82 | "kind": "OBJECT", 83 | "name": "__Schema", 84 | "description": "A GraphQL Schema defines the capabilities of a GraphQL server. It exposes all available types and directives on the server, as well as the entry points for query, mutation, and subscription operations.", 85 | "fields": [ 86 | { 87 | "name": "types", 88 | "description": "A list of all types supported by this server.", 89 | "args": [], 90 | "type": { 91 | "kind": "NON_NULL", 92 | "name": null, 93 | "ofType": { 94 | "kind": "LIST", 95 | "name": null, 96 | "ofType": { 97 | "kind": "NON_NULL", 98 | "name": null, 99 | "ofType": { 100 | "kind": "OBJECT", 101 | "name": "__Type", 102 | "ofType": null 103 | } 104 | } 105 | } 106 | }, 107 | "isDeprecated": false, 108 | "deprecationReason": null 109 | }, 110 | { 111 | "name": "queryType", 112 | "description": "The type that query operations will be rooted at.", 113 | "args": [], 114 | "type": { 115 | "kind": "NON_NULL", 116 | "name": null, 117 | "ofType": { 118 | "kind": "OBJECT", 119 | "name": "__Type", 120 | "ofType": null 121 | } 122 | }, 123 | "isDeprecated": false, 124 | "deprecationReason": null 125 | }, 126 | { 127 | "name": "mutationType", 128 | "description": "If this server supports mutation, the type that mutation operations will be rooted at.", 129 | "args": [], 130 | "type": { 131 | "kind": "OBJECT", 132 | "name": "__Type", 133 | "ofType": null 134 | }, 135 | "isDeprecated": false, 136 | "deprecationReason": null 137 | }, 138 | { 139 | "name": "subscriptionType", 140 | "description": "If this server support subscription, the type that subscription operations will be rooted at.", 141 | "args": [], 142 | "type": { 143 | "kind": "OBJECT", 144 | "name": "__Type", 145 | "ofType": null 146 | }, 147 | "isDeprecated": false, 148 | "deprecationReason": null 149 | }, 150 | { 151 | "name": "directives", 152 | "description": "A list of all directives supported by this server.", 153 | "args": [], 154 | "type": { 155 | "kind": "NON_NULL", 156 | "name": null, 157 | "ofType": { 158 | "kind": "LIST", 159 | "name": null, 160 | "ofType": { 161 | "kind": "NON_NULL", 162 | "name": null, 163 | "ofType": { 164 | "kind": "OBJECT", 165 | "name": "__Directive", 166 | "ofType": null 167 | } 168 | } 169 | } 170 | }, 171 | "isDeprecated": false, 172 | "deprecationReason": null 173 | } 174 | ], 175 | "inputFields": null, 176 | "interfaces": [], 177 | "enumValues": null, 178 | "possibleTypes": null 179 | }, 180 | { 181 | "kind": "OBJECT", 182 | "name": "__Type", 183 | "description": "The fundamental unit of any GraphQL Schema is the type. There are many kinds of types in GraphQL as represented by the `__TypeKind` enum.\n\nDepending on the kind of a type, certain fields describe information about that type. Scalar types provide no information beyond a name and description, while Enum types provide their values. Object and Interface types provide the fields they describe. Abstract types, Union and Interface, provide the Object types possible at runtime. List and NonNull types compose other types.", 184 | "fields": [ 185 | { 186 | "name": "kind", 187 | "description": null, 188 | "args": [], 189 | "type": { 190 | "kind": "NON_NULL", 191 | "name": null, 192 | "ofType": { 193 | "kind": "ENUM", 194 | "name": "__TypeKind", 195 | "ofType": null 196 | } 197 | }, 198 | "isDeprecated": false, 199 | "deprecationReason": null 200 | }, 201 | { 202 | "name": "name", 203 | "description": null, 204 | "args": [], 205 | "type": { 206 | "kind": "SCALAR", 207 | "name": "String", 208 | "ofType": null 209 | }, 210 | "isDeprecated": false, 211 | "deprecationReason": null 212 | }, 213 | { 214 | "name": "description", 215 | "description": null, 216 | "args": [], 217 | "type": { 218 | "kind": "SCALAR", 219 | "name": "String", 220 | "ofType": null 221 | }, 222 | "isDeprecated": false, 223 | "deprecationReason": null 224 | }, 225 | { 226 | "name": "fields", 227 | "description": null, 228 | "args": [ 229 | { 230 | "name": "includeDeprecated", 231 | "description": null, 232 | "type": { 233 | "kind": "SCALAR", 234 | "name": "Boolean", 235 | "ofType": null 236 | }, 237 | "defaultValue": "false" 238 | } 239 | ], 240 | "type": { 241 | "kind": "LIST", 242 | "name": null, 243 | "ofType": { 244 | "kind": "NON_NULL", 245 | "name": null, 246 | "ofType": { 247 | "kind": "OBJECT", 248 | "name": "__Field", 249 | "ofType": null 250 | } 251 | } 252 | }, 253 | "isDeprecated": false, 254 | "deprecationReason": null 255 | }, 256 | { 257 | "name": "interfaces", 258 | "description": null, 259 | "args": [], 260 | "type": { 261 | "kind": "LIST", 262 | "name": null, 263 | "ofType": { 264 | "kind": "NON_NULL", 265 | "name": null, 266 | "ofType": { 267 | "kind": "OBJECT", 268 | "name": "__Type", 269 | "ofType": null 270 | } 271 | } 272 | }, 273 | "isDeprecated": false, 274 | "deprecationReason": null 275 | }, 276 | { 277 | "name": "possibleTypes", 278 | "description": null, 279 | "args": [], 280 | "type": { 281 | "kind": "LIST", 282 | "name": null, 283 | "ofType": { 284 | "kind": "NON_NULL", 285 | "name": null, 286 | "ofType": { 287 | "kind": "OBJECT", 288 | "name": "__Type", 289 | "ofType": null 290 | } 291 | } 292 | }, 293 | "isDeprecated": false, 294 | "deprecationReason": null 295 | }, 296 | { 297 | "name": "enumValues", 298 | "description": null, 299 | "args": [ 300 | { 301 | "name": "includeDeprecated", 302 | "description": null, 303 | "type": { 304 | "kind": "SCALAR", 305 | "name": "Boolean", 306 | "ofType": null 307 | }, 308 | "defaultValue": "false" 309 | } 310 | ], 311 | "type": { 312 | "kind": "LIST", 313 | "name": null, 314 | "ofType": { 315 | "kind": "NON_NULL", 316 | "name": null, 317 | "ofType": { 318 | "kind": "OBJECT", 319 | "name": "__EnumValue", 320 | "ofType": null 321 | } 322 | } 323 | }, 324 | "isDeprecated": false, 325 | "deprecationReason": null 326 | }, 327 | { 328 | "name": "inputFields", 329 | "description": null, 330 | "args": [], 331 | "type": { 332 | "kind": "LIST", 333 | "name": null, 334 | "ofType": { 335 | "kind": "NON_NULL", 336 | "name": null, 337 | "ofType": { 338 | "kind": "OBJECT", 339 | "name": "__InputValue", 340 | "ofType": null 341 | } 342 | } 343 | }, 344 | "isDeprecated": false, 345 | "deprecationReason": null 346 | }, 347 | { 348 | "name": "ofType", 349 | "description": null, 350 | "args": [], 351 | "type": { 352 | "kind": "OBJECT", 353 | "name": "__Type", 354 | "ofType": null 355 | }, 356 | "isDeprecated": false, 357 | "deprecationReason": null 358 | } 359 | ], 360 | "inputFields": null, 361 | "interfaces": [], 362 | "enumValues": null, 363 | "possibleTypes": null 364 | }, 365 | { 366 | "kind": "ENUM", 367 | "name": "__TypeKind", 368 | "description": "An enum describing what kind of type a given `__Type` is.", 369 | "fields": null, 370 | "inputFields": null, 371 | "interfaces": null, 372 | "enumValues": [ 373 | { 374 | "name": "SCALAR", 375 | "description": "Indicates this type is a scalar.", 376 | "isDeprecated": false, 377 | "deprecationReason": null 378 | }, 379 | { 380 | "name": "OBJECT", 381 | "description": "Indicates this type is an object. `fields` and `interfaces` are valid fields.", 382 | "isDeprecated": false, 383 | "deprecationReason": null 384 | }, 385 | { 386 | "name": "INTERFACE", 387 | "description": "Indicates this type is an interface. `fields` and `possibleTypes` are valid fields.", 388 | "isDeprecated": false, 389 | "deprecationReason": null 390 | }, 391 | { 392 | "name": "UNION", 393 | "description": "Indicates this type is a union. `possibleTypes` is a valid field.", 394 | "isDeprecated": false, 395 | "deprecationReason": null 396 | }, 397 | { 398 | "name": "ENUM", 399 | "description": "Indicates this type is an enum. `enumValues` is a valid field.", 400 | "isDeprecated": false, 401 | "deprecationReason": null 402 | }, 403 | { 404 | "name": "INPUT_OBJECT", 405 | "description": "Indicates this type is an input object. `inputFields` is a valid field.", 406 | "isDeprecated": false, 407 | "deprecationReason": null 408 | }, 409 | { 410 | "name": "LIST", 411 | "description": "Indicates this type is a list. `ofType` is a valid field.", 412 | "isDeprecated": false, 413 | "deprecationReason": null 414 | }, 415 | { 416 | "name": "NON_NULL", 417 | "description": "Indicates this type is a non-null. `ofType` is a valid field.", 418 | "isDeprecated": false, 419 | "deprecationReason": null 420 | } 421 | ], 422 | "possibleTypes": null 423 | }, 424 | { 425 | "kind": "SCALAR", 426 | "name": "Boolean", 427 | "description": "The `Boolean` scalar type represents `true` or `false`.", 428 | "fields": null, 429 | "inputFields": null, 430 | "interfaces": null, 431 | "enumValues": null, 432 | "possibleTypes": null 433 | }, 434 | { 435 | "kind": "OBJECT", 436 | "name": "__Field", 437 | "description": "Object and Interface types are described by a list of Fields, each of which has a name, potentially a list of arguments, and a return type.", 438 | "fields": [ 439 | { 440 | "name": "name", 441 | "description": null, 442 | "args": [], 443 | "type": { 444 | "kind": "NON_NULL", 445 | "name": null, 446 | "ofType": { 447 | "kind": "SCALAR", 448 | "name": "String", 449 | "ofType": null 450 | } 451 | }, 452 | "isDeprecated": false, 453 | "deprecationReason": null 454 | }, 455 | { 456 | "name": "description", 457 | "description": null, 458 | "args": [], 459 | "type": { 460 | "kind": "SCALAR", 461 | "name": "String", 462 | "ofType": null 463 | }, 464 | "isDeprecated": false, 465 | "deprecationReason": null 466 | }, 467 | { 468 | "name": "args", 469 | "description": null, 470 | "args": [], 471 | "type": { 472 | "kind": "NON_NULL", 473 | "name": null, 474 | "ofType": { 475 | "kind": "LIST", 476 | "name": null, 477 | "ofType": { 478 | "kind": "NON_NULL", 479 | "name": null, 480 | "ofType": { 481 | "kind": "OBJECT", 482 | "name": "__InputValue", 483 | "ofType": null 484 | } 485 | } 486 | } 487 | }, 488 | "isDeprecated": false, 489 | "deprecationReason": null 490 | }, 491 | { 492 | "name": "type", 493 | "description": null, 494 | "args": [], 495 | "type": { 496 | "kind": "NON_NULL", 497 | "name": null, 498 | "ofType": { 499 | "kind": "OBJECT", 500 | "name": "__Type", 501 | "ofType": null 502 | } 503 | }, 504 | "isDeprecated": false, 505 | "deprecationReason": null 506 | }, 507 | { 508 | "name": "isDeprecated", 509 | "description": null, 510 | "args": [], 511 | "type": { 512 | "kind": "NON_NULL", 513 | "name": null, 514 | "ofType": { 515 | "kind": "SCALAR", 516 | "name": "Boolean", 517 | "ofType": null 518 | } 519 | }, 520 | "isDeprecated": false, 521 | "deprecationReason": null 522 | }, 523 | { 524 | "name": "deprecationReason", 525 | "description": null, 526 | "args": [], 527 | "type": { 528 | "kind": "SCALAR", 529 | "name": "String", 530 | "ofType": null 531 | }, 532 | "isDeprecated": false, 533 | "deprecationReason": null 534 | } 535 | ], 536 | "inputFields": null, 537 | "interfaces": [], 538 | "enumValues": null, 539 | "possibleTypes": null 540 | }, 541 | { 542 | "kind": "OBJECT", 543 | "name": "__InputValue", 544 | "description": "Arguments provided to Fields or Directives and the input fields of an InputObject are represented as Input Values which describe their type and optionally a default value.", 545 | "fields": [ 546 | { 547 | "name": "name", 548 | "description": null, 549 | "args": [], 550 | "type": { 551 | "kind": "NON_NULL", 552 | "name": null, 553 | "ofType": { 554 | "kind": "SCALAR", 555 | "name": "String", 556 | "ofType": null 557 | } 558 | }, 559 | "isDeprecated": false, 560 | "deprecationReason": null 561 | }, 562 | { 563 | "name": "description", 564 | "description": null, 565 | "args": [], 566 | "type": { 567 | "kind": "SCALAR", 568 | "name": "String", 569 | "ofType": null 570 | }, 571 | "isDeprecated": false, 572 | "deprecationReason": null 573 | }, 574 | { 575 | "name": "type", 576 | "description": null, 577 | "args": [], 578 | "type": { 579 | "kind": "NON_NULL", 580 | "name": null, 581 | "ofType": { 582 | "kind": "OBJECT", 583 | "name": "__Type", 584 | "ofType": null 585 | } 586 | }, 587 | "isDeprecated": false, 588 | "deprecationReason": null 589 | }, 590 | { 591 | "name": "defaultValue", 592 | "description": "A GraphQL-formatted string representing the default value for this input value.", 593 | "args": [], 594 | "type": { 595 | "kind": "SCALAR", 596 | "name": "String", 597 | "ofType": null 598 | }, 599 | "isDeprecated": false, 600 | "deprecationReason": null 601 | } 602 | ], 603 | "inputFields": null, 604 | "interfaces": [], 605 | "enumValues": null, 606 | "possibleTypes": null 607 | }, 608 | { 609 | "kind": "OBJECT", 610 | "name": "__EnumValue", 611 | "description": "One possible value for a given Enum. Enum values are unique values, not a placeholder for a string or numeric value. However an Enum value is returned in a JSON response as a string.", 612 | "fields": [ 613 | { 614 | "name": "name", 615 | "description": null, 616 | "args": [], 617 | "type": { 618 | "kind": "NON_NULL", 619 | "name": null, 620 | "ofType": { 621 | "kind": "SCALAR", 622 | "name": "String", 623 | "ofType": null 624 | } 625 | }, 626 | "isDeprecated": false, 627 | "deprecationReason": null 628 | }, 629 | { 630 | "name": "description", 631 | "description": null, 632 | "args": [], 633 | "type": { 634 | "kind": "SCALAR", 635 | "name": "String", 636 | "ofType": null 637 | }, 638 | "isDeprecated": false, 639 | "deprecationReason": null 640 | }, 641 | { 642 | "name": "isDeprecated", 643 | "description": null, 644 | "args": [], 645 | "type": { 646 | "kind": "NON_NULL", 647 | "name": null, 648 | "ofType": { 649 | "kind": "SCALAR", 650 | "name": "Boolean", 651 | "ofType": null 652 | } 653 | }, 654 | "isDeprecated": false, 655 | "deprecationReason": null 656 | }, 657 | { 658 | "name": "deprecationReason", 659 | "description": null, 660 | "args": [], 661 | "type": { 662 | "kind": "SCALAR", 663 | "name": "String", 664 | "ofType": null 665 | }, 666 | "isDeprecated": false, 667 | "deprecationReason": null 668 | } 669 | ], 670 | "inputFields": null, 671 | "interfaces": [], 672 | "enumValues": null, 673 | "possibleTypes": null 674 | }, 675 | { 676 | "kind": "OBJECT", 677 | "name": "__Directive", 678 | "description": "A Directive provides a way to describe alternate runtime execution and type validation behavior in a GraphQL document.\n\nIn some cases, you need to provide options to alter GraphQL's execution behavior in ways field arguments will not suffice, such as conditionally including or skipping a field. Directives provide this by describing additional information to the executor.", 679 | "fields": [ 680 | { 681 | "name": "name", 682 | "description": null, 683 | "args": [], 684 | "type": { 685 | "kind": "NON_NULL", 686 | "name": null, 687 | "ofType": { 688 | "kind": "SCALAR", 689 | "name": "String", 690 | "ofType": null 691 | } 692 | }, 693 | "isDeprecated": false, 694 | "deprecationReason": null 695 | }, 696 | { 697 | "name": "description", 698 | "description": null, 699 | "args": [], 700 | "type": { 701 | "kind": "SCALAR", 702 | "name": "String", 703 | "ofType": null 704 | }, 705 | "isDeprecated": false, 706 | "deprecationReason": null 707 | }, 708 | { 709 | "name": "locations", 710 | "description": null, 711 | "args": [], 712 | "type": { 713 | "kind": "NON_NULL", 714 | "name": null, 715 | "ofType": { 716 | "kind": "LIST", 717 | "name": null, 718 | "ofType": { 719 | "kind": "NON_NULL", 720 | "name": null, 721 | "ofType": { 722 | "kind": "ENUM", 723 | "name": "__DirectiveLocation", 724 | "ofType": null 725 | } 726 | } 727 | } 728 | }, 729 | "isDeprecated": false, 730 | "deprecationReason": null 731 | }, 732 | { 733 | "name": "args", 734 | "description": null, 735 | "args": [], 736 | "type": { 737 | "kind": "NON_NULL", 738 | "name": null, 739 | "ofType": { 740 | "kind": "LIST", 741 | "name": null, 742 | "ofType": { 743 | "kind": "NON_NULL", 744 | "name": null, 745 | "ofType": { 746 | "kind": "OBJECT", 747 | "name": "__InputValue", 748 | "ofType": null 749 | } 750 | } 751 | } 752 | }, 753 | "isDeprecated": false, 754 | "deprecationReason": null 755 | } 756 | ], 757 | "inputFields": null, 758 | "interfaces": [], 759 | "enumValues": null, 760 | "possibleTypes": null 761 | }, 762 | { 763 | "kind": "ENUM", 764 | "name": "__DirectiveLocation", 765 | "description": "A Directive can be adjacent to many parts of the GraphQL language, a __DirectiveLocation describes one such possible adjacencies.", 766 | "fields": null, 767 | "inputFields": null, 768 | "interfaces": null, 769 | "enumValues": [ 770 | { 771 | "name": "QUERY", 772 | "description": "Location adjacent to a query operation.", 773 | "isDeprecated": false, 774 | "deprecationReason": null 775 | }, 776 | { 777 | "name": "MUTATION", 778 | "description": "Location adjacent to a mutation operation.", 779 | "isDeprecated": false, 780 | "deprecationReason": null 781 | }, 782 | { 783 | "name": "SUBSCRIPTION", 784 | "description": "Location adjacent to a subscription operation.", 785 | "isDeprecated": false, 786 | "deprecationReason": null 787 | }, 788 | { 789 | "name": "FIELD", 790 | "description": "Location adjacent to a field.", 791 | "isDeprecated": false, 792 | "deprecationReason": null 793 | }, 794 | { 795 | "name": "FRAGMENT_DEFINITION", 796 | "description": "Location adjacent to a fragment definition.", 797 | "isDeprecated": false, 798 | "deprecationReason": null 799 | }, 800 | { 801 | "name": "FRAGMENT_SPREAD", 802 | "description": "Location adjacent to a fragment spread.", 803 | "isDeprecated": false, 804 | "deprecationReason": null 805 | }, 806 | { 807 | "name": "INLINE_FRAGMENT", 808 | "description": "Location adjacent to an inline fragment.", 809 | "isDeprecated": false, 810 | "deprecationReason": null 811 | }, 812 | { 813 | "name": "VARIABLE_DEFINITION", 814 | "description": "Location adjacent to a variable definition.", 815 | "isDeprecated": false, 816 | "deprecationReason": null 817 | }, 818 | { 819 | "name": "SCHEMA", 820 | "description": "Location adjacent to a schema definition.", 821 | "isDeprecated": false, 822 | "deprecationReason": null 823 | }, 824 | { 825 | "name": "SCALAR", 826 | "description": "Location adjacent to a scalar definition.", 827 | "isDeprecated": false, 828 | "deprecationReason": null 829 | }, 830 | { 831 | "name": "OBJECT", 832 | "description": "Location adjacent to an object type definition.", 833 | "isDeprecated": false, 834 | "deprecationReason": null 835 | }, 836 | { 837 | "name": "FIELD_DEFINITION", 838 | "description": "Location adjacent to a field definition.", 839 | "isDeprecated": false, 840 | "deprecationReason": null 841 | }, 842 | { 843 | "name": "ARGUMENT_DEFINITION", 844 | "description": "Location adjacent to an argument definition.", 845 | "isDeprecated": false, 846 | "deprecationReason": null 847 | }, 848 | { 849 | "name": "INTERFACE", 850 | "description": "Location adjacent to an interface definition.", 851 | "isDeprecated": false, 852 | "deprecationReason": null 853 | }, 854 | { 855 | "name": "UNION", 856 | "description": "Location adjacent to a union definition.", 857 | "isDeprecated": false, 858 | "deprecationReason": null 859 | }, 860 | { 861 | "name": "ENUM", 862 | "description": "Location adjacent to an enum definition.", 863 | "isDeprecated": false, 864 | "deprecationReason": null 865 | }, 866 | { 867 | "name": "ENUM_VALUE", 868 | "description": "Location adjacent to an enum value definition.", 869 | "isDeprecated": false, 870 | "deprecationReason": null 871 | }, 872 | { 873 | "name": "INPUT_OBJECT", 874 | "description": "Location adjacent to an input object type definition.", 875 | "isDeprecated": false, 876 | "deprecationReason": null 877 | }, 878 | { 879 | "name": "INPUT_FIELD_DEFINITION", 880 | "description": "Location adjacent to an input object field definition.", 881 | "isDeprecated": false, 882 | "deprecationReason": null 883 | } 884 | ], 885 | "possibleTypes": null 886 | }, 887 | { 888 | "kind": "ENUM", 889 | "name": "CacheControlScope", 890 | "description": null, 891 | "fields": null, 892 | "inputFields": null, 893 | "interfaces": null, 894 | "enumValues": [ 895 | { 896 | "name": "PUBLIC", 897 | "description": null, 898 | "isDeprecated": false, 899 | "deprecationReason": null 900 | }, 901 | { 902 | "name": "PRIVATE", 903 | "description": null, 904 | "isDeprecated": false, 905 | "deprecationReason": null 906 | } 907 | ], 908 | "possibleTypes": null 909 | }, 910 | { 911 | "kind": "SCALAR", 912 | "name": "Upload", 913 | "description": "The `Upload` scalar type represents a file upload.", 914 | "fields": null, 915 | "inputFields": null, 916 | "interfaces": null, 917 | "enumValues": null, 918 | "possibleTypes": null 919 | }, 920 | { 921 | "kind": "SCALAR", 922 | "name": "Int", 923 | "description": "The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. ", 924 | "fields": null, 925 | "inputFields": null, 926 | "interfaces": null, 927 | "enumValues": null, 928 | "possibleTypes": null 929 | } 930 | ], 931 | "directives": [ 932 | { 933 | "name": "cacheControl", 934 | "description": null, 935 | "locations": [ 936 | "FIELD_DEFINITION", 937 | "OBJECT", 938 | "INTERFACE" 939 | ], 940 | "args": [ 941 | { 942 | "name": "maxAge", 943 | "description": null, 944 | "type": { 945 | "kind": "SCALAR", 946 | "name": "Int", 947 | "ofType": null 948 | }, 949 | "defaultValue": null 950 | }, 951 | { 952 | "name": "scope", 953 | "description": null, 954 | "type": { 955 | "kind": "ENUM", 956 | "name": "CacheControlScope", 957 | "ofType": null 958 | }, 959 | "defaultValue": null 960 | } 961 | ] 962 | }, 963 | { 964 | "name": "skip", 965 | "description": "Directs the executor to skip this field or fragment when the `if` argument is true.", 966 | "locations": [ 967 | "FIELD", 968 | "FRAGMENT_SPREAD", 969 | "INLINE_FRAGMENT" 970 | ], 971 | "args": [ 972 | { 973 | "name": "if", 974 | "description": "Skipped when true.", 975 | "type": { 976 | "kind": "NON_NULL", 977 | "name": null, 978 | "ofType": { 979 | "kind": "SCALAR", 980 | "name": "Boolean", 981 | "ofType": null 982 | } 983 | }, 984 | "defaultValue": null 985 | } 986 | ] 987 | }, 988 | { 989 | "name": "include", 990 | "description": "Directs the executor to include this field or fragment only when the `if` argument is true.", 991 | "locations": [ 992 | "FIELD", 993 | "FRAGMENT_SPREAD", 994 | "INLINE_FRAGMENT" 995 | ], 996 | "args": [ 997 | { 998 | "name": "if", 999 | "description": "Included when true.", 1000 | "type": { 1001 | "kind": "NON_NULL", 1002 | "name": null, 1003 | "ofType": { 1004 | "kind": "SCALAR", 1005 | "name": "Boolean", 1006 | "ofType": null 1007 | } 1008 | }, 1009 | "defaultValue": null 1010 | } 1011 | ] 1012 | }, 1013 | { 1014 | "name": "deprecated", 1015 | "description": "Marks an element of a GraphQL schema as no longer supported.", 1016 | "locations": [ 1017 | "FIELD_DEFINITION", 1018 | "ENUM_VALUE" 1019 | ], 1020 | "args": [ 1021 | { 1022 | "name": "reason", 1023 | "description": "Explains why this element was deprecated, usually also including a suggestion for how to access supported similar data. Formatted using the Markdown syntax (as specified by [CommonMark](https://commonmark.org/).", 1024 | "type": { 1025 | "kind": "SCALAR", 1026 | "name": "String", 1027 | "ofType": null 1028 | }, 1029 | "defaultValue": "\"No longer supported\"" 1030 | } 1031 | ] 1032 | } 1033 | ] 1034 | } 1035 | } -------------------------------------------------------------------------------- /www/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2016", 4 | "module": "esnext", 5 | "lib": ["es6", "dom", "esnext.asynciterable"], 6 | "sourceMap": true, 7 | "allowJs": true, 8 | "jsx": "react", 9 | "moduleResolution": "node", 10 | "forceConsistentCasingInFileNames": true, 11 | "noImplicitReturns": true, 12 | "noImplicitThis": true, 13 | "importHelpers": true, 14 | "strictNullChecks": false, 15 | "suppressImplicitAnyIndexErrors": true, 16 | "noUnusedLocals": true 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /www/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | isomorphic-unfetch@3.0.0: 6 | version "3.0.0" 7 | resolved "https://registry.yarnpkg.com/isomorphic-unfetch/-/isomorphic-unfetch-3.0.0.tgz#de6d80abde487b17de2c400a7ef9e5ecc2efb362" 8 | integrity sha512-V0tmJSYfkKokZ5mgl0cmfQMTb7MLHsBMngTkbLY0eXvKqiVRRoZP04Ly+KhKrJfKtzC9E6Pp15Jo+bwh7Vi2XQ== 9 | dependencies: 10 | node-fetch "^2.2.0" 11 | unfetch "^4.0.0" 12 | 13 | node-fetch@^2.2.0: 14 | version "2.3.0" 15 | resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.3.0.tgz#1a1d940bbfb916a1d3e0219f037e89e71f8c5fa5" 16 | integrity sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA== 17 | 18 | unfetch@^4.0.0: 19 | version "4.0.1" 20 | resolved "https://registry.yarnpkg.com/unfetch/-/unfetch-4.0.1.tgz#8750c4c7497ade75d40387d7dbc4ba024416b8f6" 21 | integrity sha512-HzDM9NgldcRvHVDb/O9vKoUszVij30Yw5ePjOZJig8nF/YisG7QN/9CBXZ8dsHLouXMeLZ82r+Jod9M2wFkEbQ== 22 | --------------------------------------------------------------------------------