├── .gitignore ├── js ├── store.js ├── routes │ └── AppHomeRoute.js ├── app.js ├── mutations │ └── LikeItemMutation.js ├── components │ └── App.js └── redux-compat.js ├── public └── index.html ├── README.md ├── scripts └── updateSchema.js ├── package.json ├── server.js ├── LICENSE ├── PATENTS ├── data ├── database.js ├── schema.js └── schema.json └── .eslintrc /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | npm-debug.log 4 | /data/schema.json 5 | .idea -------------------------------------------------------------------------------- /js/store.js: -------------------------------------------------------------------------------- 1 | export function count(state=0, action) { 2 | switch (action.type) { 3 | case 'inc': 4 | return state + 1; 5 | default: 6 | return state; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Relay • Starter Kit 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /js/routes/AppHomeRoute.js: -------------------------------------------------------------------------------- 1 | import * as Relay from 'react-relay'; 2 | 3 | export default class extends Relay.Route { 4 | static path = '/'; 5 | static queries = { 6 | page: (Component) => Relay.QL` 7 | query { 8 | home { 9 | ${Component.getFragment('page')} 10 | } 11 | } 12 | ` 13 | }; 14 | static routeName = 'AppHomeRoute'; 15 | } 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # relay / redux example 2 | 3 | sample app using `relay` and `redux` together in one component, 4 | storing relay data in `mongodb` as a bonus 5 | 6 | ## developing 7 | 8 | ensure you have mongodb running 9 | 10 | if at any time you make changes to `data/schema.js`, stop the server, 11 | regenerate `data/schema.json`, and restart the server: 12 | 13 | ``` 14 | npm install 15 | npm run update-schema 16 | npm start 17 | ``` 18 | 19 | ## license 20 | based on Relay Starter Kit (BSD licensed) 21 | -------------------------------------------------------------------------------- /js/app.js: -------------------------------------------------------------------------------- 1 | import App from './components/App'; 2 | import AppHomeRoute from './routes/AppHomeRoute'; 3 | import {createStore, combineReducers} from 'redux'; 4 | import {Provider} from './redux-compat'; 5 | import * as store from './store'; 6 | import * as React from 'react'; 7 | import * as Relay from 'react-relay'; 8 | import * as ReactDOM from 'react-dom'; 9 | 10 | const redux = createStore(combineReducers(store)); 11 | 12 | 13 | ReactDOM.render( 14 | 15 | 16 | , 17 | document.getElementById('root') 18 | ); 19 | -------------------------------------------------------------------------------- /scripts/updateSchema.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env babel-node --optional es7.asyncFunctions 2 | 3 | import fs from 'fs'; 4 | import path from 'path'; 5 | import { Schema } from '../data/schema'; 6 | import { graphql } from 'graphql'; 7 | import { introspectionQuery } from 'graphql/utilities'; 8 | 9 | async () => { 10 | var result = await (graphql(Schema, introspectionQuery)); 11 | if (result.errors) { 12 | console.error('ERROR: ', JSON.stringify(result.errors, null, 2)); 13 | } else { 14 | fs.writeFileSync( 15 | path.join(__dirname, '../data/schema.json'), 16 | JSON.stringify(result, null, 2) 17 | ); 18 | process.exit(0); 19 | } 20 | }(); 21 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-redux-relay", 3 | "private": true, 4 | "version": "0.1.0", 5 | "scripts": { 6 | "start": "babel-node ./server.js", 7 | "update-schema": "babel-node ./scripts/updateSchema.js" 8 | }, 9 | "dependencies": { 10 | "babel": "5.8.21", 11 | "babel-core": "5.8.22", 12 | "babel-eslint": "4.0.5", 13 | "babel-loader": "5.3.2", 14 | "babel-relay-plugin": "0.7.0", 15 | "babel-runtime": "5.8.20", 16 | "eslint": "1.0.0", 17 | "eslint-loader": "1.0.0", 18 | "eslint-plugin-react": "3.2.0", 19 | "express": "4.13.4", 20 | "express-graphql": "0.4.9", 21 | "graphql": "0.4.18", 22 | "graphql-relay": "0.3.6", 23 | "mongodb": "2.1.7", 24 | "react": "0.14.7", 25 | "react-dom": "0.14.7", 26 | "react-relay": "0.7.0", 27 | "redux": "3.3.1", 28 | "webpack": "1.12.13", 29 | "webpack-dev-server": "1.14.1" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /js/mutations/LikeItemMutation.js: -------------------------------------------------------------------------------- 1 | import * as Relay from 'react-relay'; 2 | 3 | export default class LikeItemMutation extends Relay.Mutation { 4 | 5 | static fragments = { 6 | item: () => Relay.QL` 7 | fragment on Item { 8 | id, 9 | likes 10 | } 11 | ` 12 | } 13 | 14 | getMutation() { 15 | return Relay.QL` 16 | mutation { 17 | likeItem 18 | } 19 | `; 20 | } 21 | 22 | getCollisionKey() { 23 | return `check_${this.props.item.id}`; 24 | } 25 | 26 | getFatQuery() { 27 | return Relay.QL` 28 | fragment on LikeItemPayload { 29 | item { 30 | likes 31 | } 32 | } 33 | `; 34 | } 35 | 36 | getConfigs() { 37 | return [{ 38 | type: 'FIELDS_CHANGE', 39 | fieldIDs: { 40 | item: this.props.item.id 41 | } 42 | }]; 43 | } 44 | 45 | getVariables() { 46 | return { 47 | id: this.props.item.id 48 | }; 49 | } 50 | 51 | getOptimisticResponse() { 52 | return { 53 | item: { 54 | id: this.props.item.id, 55 | likes: this.props.item.likes + 1 56 | } 57 | }; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /js/components/App.js: -------------------------------------------------------------------------------- 1 | import LikeItemMutation from '../mutations/LikeItemMutation'; 2 | import { connect } from '../redux-compat'; 3 | import * as Relay from 'react-relay'; 4 | import * as React from 'react'; 5 | 6 | 7 | @connect(state => ({ 8 | count: state.count 9 | })) 10 | class App extends React.Component { 11 | 12 | likeItem(item) { 13 | Relay.Store.commitUpdate(new LikeItemMutation({item})); 14 | } 15 | 16 | reduxInc() { 17 | this.props.dispatch({type: 'inc'}); 18 | } 19 | 20 | render() { 21 | return ( 22 |
23 |

redux

24 |
this.reduxInc()}> 25 | count = {this.props.count} 26 |
27 |

relay

28 | {this.props.page.items.edges.map(e => e.node).map(item => 29 |
this.likeItem(item)}> 30 | Item (name = {item.name}, likes = {item.likes}) 31 |
32 | )} 33 |
34 | ); 35 | } 36 | } 37 | 38 | 39 | export default Relay.createContainer(App, { 40 | fragments: { 41 | page: () => Relay.QL` 42 | fragment on Page { 43 | items { 44 | edges { 45 | node { 46 | id, 47 | name, 48 | likes 49 | ${LikeItemMutation.getFragment('item')} 50 | } 51 | } 52 | } 53 | } 54 | ` 55 | }, 56 | }); 57 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | import express from 'express'; 2 | import graphQLHTTP from 'express-graphql'; 3 | import path from 'path'; 4 | import webpack from 'webpack'; 5 | import WebpackDevServer from 'webpack-dev-server'; 6 | import {Schema} from './data/schema'; 7 | 8 | const APP_PORT = 3000; 9 | const GRAPHQL_PORT = 8080; 10 | 11 | // Expose a GraphQL endpoint 12 | var graphQLServer = express(); 13 | graphQLServer.use('/', graphQLHTTP({schema: Schema, pretty: true})); 14 | graphQLServer.listen(GRAPHQL_PORT, () => console.log( 15 | `GraphQL Server is now running on http://localhost:${GRAPHQL_PORT}` 16 | )); 17 | 18 | // Serve the Relay app 19 | var compiler = webpack({ 20 | entry: path.resolve(__dirname, 'js', 'app.js'), 21 | module: { 22 | loaders: [ 23 | { 24 | test: /\.js$/, 25 | loader: 'babel', 26 | query: {stage: 0, plugins: ['./build/babelRelayPlugin']} 27 | } 28 | ] 29 | }, 30 | output: {filename: 'app.js', path: '/'} 31 | }); 32 | var app = new WebpackDevServer(compiler, { 33 | contentBase: '/public/', 34 | proxy: {'/graphql': `http://localhost:${GRAPHQL_PORT}`}, 35 | publicPath: '/js/', 36 | stats: {colors: true} 37 | }); 38 | // Serve static resources 39 | app.use('/', express.static('public')); 40 | app.use('/node_modules/react', express.static('node_modules/react')); 41 | app.use('/node_modules/react-relay', express.static('node_modules/react-relay')); 42 | app.use('/node_modules/react-dom', express.static('node_modules/react-dom')); 43 | app.listen(APP_PORT, () => { 44 | console.log(`App is now running on http://localhost:${APP_PORT}`); 45 | }); 46 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD License 2 | 3 | For Relay Starter Kit software 4 | 5 | Copyright (c) 2013-2015, Facebook, Inc. 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without modification, 9 | are permitted provided that the following conditions are met: 10 | 11 | * Redistributions of source code must retain the above copyright notice, this 12 | list of conditions and the following disclaimer. 13 | 14 | * Redistributions in binary form must reproduce the above copyright notice, 15 | this list of conditions and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name Facebook nor the names of its contributors may be used to 19 | endorse or promote products derived from this software without specific 20 | prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 23 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 24 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 26 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 27 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 29 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | -------------------------------------------------------------------------------- /js/redux-compat.js: -------------------------------------------------------------------------------- 1 | import shallowCompare from 'react/lib/shallowCompare'; 2 | import * as React from 'react'; 3 | 4 | function getConnectName(cls) { 5 | const displayName = (cls.displayName || cls.name || 'Component'); 6 | return `Connect(${displayName})`; 7 | } 8 | 9 | export function connect(getState) { 10 | return function (cls) { 11 | 12 | class Connect extends React.Component { 13 | 14 | static displayName = getConnectName(cls) 15 | 16 | static contextTypes = { 17 | store: React.PropTypes.object 18 | } 19 | 20 | constructor(props, context) { 21 | super(props, context); 22 | this.state = getState(context.store.getState()); 23 | } 24 | 25 | componentDidMount() { 26 | this.unsubscribe = this.context.store.subscribe(::this.refresh); 27 | } 28 | 29 | componentWillUnmount() { 30 | if (this.unsubscribe) { 31 | this.unsubscribe(); 32 | } 33 | } 34 | 35 | shouldComponentUpdate(nextProps, nextState) { 36 | return shallowCompare(this, nextProps, nextState); 37 | } 38 | 39 | refresh() { 40 | this.setState(getState(this.context.store.getState())); 41 | } 42 | 43 | render() { 44 | return React.createElement(cls, { 45 | dispatch: this.context.store.dispatch, 46 | ...this.props, 47 | ...this.state 48 | }); 49 | } 50 | } 51 | 52 | return Connect; 53 | }; 54 | } 55 | 56 | 57 | export class Provider extends React.Component { 58 | 59 | static childContextTypes = { 60 | store: React.PropTypes.object 61 | } 62 | 63 | getChildContext() { 64 | return { 65 | store: this.props.store 66 | }; 67 | } 68 | 69 | render() { 70 | return this.props.children; 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /PATENTS: -------------------------------------------------------------------------------- 1 | Additional Grant of Patent Rights Version 2 2 | 3 | "Software" means the Relay Starter Kit software distributed by Facebook, Inc. 4 | 5 | Facebook, Inc. ("Facebook") hereby grants to each recipient of the Software 6 | ("you") a perpetual, worldwide, royalty-free, non-exclusive, irrevocable 7 | (subject to the termination provision below) license under any Necessary 8 | Claims, to make, have made, use, sell, offer to sell, import, and otherwise 9 | transfer the Software. For avoidance of doubt, no license is granted under 10 | Facebook's rights in any patent claims that are infringed by (i) modifications 11 | to the Software made by you or any third party or (ii) the Software in 12 | combination with any software or other technology. 13 | 14 | The license granted hereunder will terminate, automatically and without notice, 15 | if you (or any of your subsidiaries, corporate affiliates or agents) initiate 16 | directly or indirectly, or take a direct financial interest in, any Patent 17 | Assertion: (i) against Facebook or any of its subsidiaries or corporate 18 | affiliates, (ii) against any party if such Patent Assertion arises in whole or 19 | in part from any software, technology, product or service of Facebook or any of 20 | its subsidiaries or corporate affiliates, or (iii) against any party relating 21 | to the Software. Notwithstanding the foregoing, if Facebook or any of its 22 | subsidiaries or corporate affiliates files a lawsuit alleging patent 23 | infringement against you in the first instance, and you respond by filing a 24 | patent infringement counterclaim in that lawsuit against that party that is 25 | unrelated to the Software, the license granted hereunder will not terminate 26 | under section (i) of this paragraph due to such counterclaim. 27 | 28 | A "Necessary Claim" is a claim of a patent owned by Facebook that is 29 | necessarily infringed by the Software standing alone. 30 | 31 | A "Patent Assertion" is any lawsuit or other action alleging direct, indirect, 32 | or contributory infringement or inducement to infringe any patent, including a 33 | cross-claim or counterclaim. 34 | -------------------------------------------------------------------------------- /data/database.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | import {MongoClient, ObjectID} from 'mongodb'; 11 | 12 | let itemsCollection; 13 | 14 | MongoClient.connect('mongodb://127.0.0.1:27017/relay', (error, db) => { 15 | if (error) { 16 | console.error(error); 17 | process.exit(-1); 18 | } 19 | itemsCollection = db.collection('items'); 20 | itemsCollection.find().toArray((error, result) => { 21 | if (error) { 22 | console.error(error); 23 | process.exit(-1); 24 | } else { 25 | if (!result.length) { 26 | console.log('inserting initial data'); 27 | itemsCollection.insert([ 28 | {name: 'foo', likes: 0}, 29 | {name: 'bar', likes: 0} 30 | ]); 31 | } 32 | } 33 | }); 34 | }); 35 | 36 | 37 | export class Item extends Object {} 38 | 39 | 40 | function itemsFromData(data) { 41 | const item = new Item(); 42 | item.id = data._id.toString(); 43 | item.name = data.name; 44 | item.likes = data.likes; 45 | return item; 46 | } 47 | 48 | export function getItems() { 49 | return new Promise((resolve, reject) => { 50 | itemsCollection.find().toArray((error, result) => { 51 | if (error) { 52 | reject(error); 53 | } else { 54 | resolve(result.map(itemsFromData)); 55 | } 56 | }); 57 | }); 58 | } 59 | 60 | export function getItem(id) { 61 | return new Promise((resolve, reject) => { 62 | itemsCollection.findOne({_id: new ObjectID(id)}, (error, data) => { 63 | if (error) { 64 | reject(error); 65 | } else { 66 | resolve(itemsFromData(data)); 67 | } 68 | }); 69 | }); 70 | } 71 | 72 | export function likeItem(id) { 73 | return new Promise((resolve, reject) => { 74 | itemsCollection.update({_id: new ObjectID(id)}, {$inc: {likes: 1}}, (error) => { 75 | if (error) { 76 | reject(error); 77 | } else { 78 | resolve(); 79 | } 80 | }); 81 | }); 82 | } 83 | -------------------------------------------------------------------------------- /data/schema.js: -------------------------------------------------------------------------------- 1 | import { 2 | GraphQLID, 3 | GraphQLInt, 4 | GraphQLNonNull, 5 | GraphQLObjectType, 6 | GraphQLSchema, 7 | GraphQLString, 8 | } from 'graphql'; 9 | 10 | import { 11 | connectionDefinitions, 12 | connectionFromArray, 13 | fromGlobalId, 14 | globalIdField, 15 | mutationWithClientMutationId, 16 | nodeDefinitions, 17 | } from 'graphql-relay'; 18 | 19 | import { 20 | Item, 21 | likeItem, 22 | getItem, 23 | getItems 24 | } from './database'; 25 | 26 | 27 | class Page extends Object { 28 | 29 | } 30 | 31 | const home = new Page(); 32 | home.id = 'home'; 33 | 34 | const {nodeInterface, nodeField} = nodeDefinitions( 35 | globalId => { 36 | const {type, id} = fromGlobalId(globalId); 37 | if (type === 'Page') { 38 | return home; 39 | } else if (type === 'Item') { 40 | return getItem(id); 41 | } else { 42 | return null; 43 | } 44 | }, 45 | obj => { 46 | if (obj instanceof Item) { 47 | return itemType; 48 | } else if (obj instanceof Page) { 49 | return pageType; 50 | } else { 51 | return null; 52 | } 53 | } 54 | ); 55 | 56 | const pageType = new GraphQLObjectType({ 57 | name: 'Page', 58 | fields() { 59 | return { 60 | id: globalIdField('Page'), 61 | items: { 62 | type: itemsConnection, 63 | async resolve(_, args) { 64 | const items = await getItems(); 65 | return connectionFromArray(items, args); 66 | } 67 | } 68 | }; 69 | } 70 | }); 71 | 72 | 73 | const itemType = new GraphQLObjectType({ 74 | name: 'Item', 75 | fields: () => ({ 76 | id: globalIdField('Item'), 77 | name: { 78 | type: GraphQLString 79 | }, 80 | likes: { 81 | type: GraphQLInt 82 | } 83 | }), 84 | interfaces: [nodeInterface], 85 | }); 86 | 87 | 88 | const {connectionType: itemsConnection} = connectionDefinitions({ 89 | name: 'Item', 90 | nodeType: itemType 91 | }); 92 | 93 | 94 | const queryType = new GraphQLObjectType({ 95 | name: 'Query', 96 | fields: () => ({ 97 | node: nodeField, 98 | home: { 99 | type: pageType, 100 | resolve() { 101 | return home; 102 | } 103 | } 104 | }), 105 | }); 106 | 107 | 108 | const LikeItemMutation = mutationWithClientMutationId({ 109 | name: 'LikeItem', 110 | 111 | inputFields: { 112 | id: { 113 | type: new GraphQLNonNull(GraphQLID) 114 | } 115 | }, 116 | 117 | outputFields: { 118 | item: { 119 | type: itemType, 120 | resolve({itemId}) { 121 | return getItem(itemId); 122 | } 123 | } 124 | }, 125 | 126 | async mutateAndGetPayload({id}) { 127 | const itemId = fromGlobalId(id).id; 128 | await likeItem(itemId); 129 | return {itemId}; 130 | } 131 | 132 | }); 133 | 134 | 135 | const mutationType = new GraphQLObjectType({ 136 | name: 'Mutation', 137 | fields: () => ({ 138 | likeItem: LikeItemMutation 139 | }), 140 | }); 141 | 142 | 143 | export const Schema = new GraphQLSchema({ 144 | query: queryType, 145 | mutation: mutationType 146 | }); 147 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | --- 2 | parser: babel-eslint 3 | 4 | plugins: 5 | - react 6 | 7 | env: 8 | node: true 9 | es6: true 10 | 11 | globals: 12 | document: false 13 | React: false 14 | Relay: false 15 | 16 | arrowFunctions: true 17 | blockBindings: true 18 | classes: true 19 | defaultParams: true 20 | destructuring: true 21 | forOf: true 22 | generators: true 23 | modules: true 24 | objectLiteralComputedProperties: true 25 | objectLiteralShorthandMethods: true 26 | objectLiteralShorthandProperties: true 27 | spread: true 28 | templateStrings: true 29 | 30 | rules: 31 | # ERRORS 32 | brace-style: [2, 1tbs, allowSingleLine: true] 33 | camelcase: [2, properties: always] 34 | comma-style: [2, last] 35 | curly: [2, all] 36 | eol-last: 2 37 | eqeqeq: 2 38 | guard-for-in: 2 39 | handle-callback-err: [2, error] 40 | key-spacing: [2, {beforeColon: false, afterColon: true}] 41 | max-len: [2, 120, 4, ignorePattern: "^(\\s*var\\s.+=\\s*require\\s*\\(|import )"] 42 | new-parens: 2 43 | no-alert: 2 44 | no-array-constructor: 2 45 | no-caller: 2 46 | no-catch-shadow: 2 47 | no-cond-assign: 2 48 | no-constant-condition: 2 49 | no-delete-var: 2 50 | no-div-regex: 2 51 | no-dupe-args: 2 52 | no-dupe-keys: 2 53 | no-duplicate-case: 2 54 | no-empty-character-class: 2 55 | no-empty-label: 2 56 | no-empty: 2 57 | no-eval: 2 58 | no-ex-assign: 2 59 | no-extend-native: 2 60 | no-extra-bind: 2 61 | no-extra-boolean-cast: 2 62 | no-extra-semi: 2 63 | no-fallthrough: 2 64 | no-floating-decimal: 2 65 | no-func-assign: 2 66 | no-implied-eval: 2 67 | no-inner-declarations: [2, functions] 68 | no-invalid-regexp: 2 69 | no-irregular-whitespace: 2 70 | no-iterator: 2 71 | no-label-var: 2 72 | no-mixed-requires: [2, true] 73 | no-mixed-spaces-and-tabs: 2 74 | no-multi-spaces: 2 75 | no-multi-str: 2 76 | no-negated-in-lhs: 2 77 | no-new-object: 2 78 | no-new-require: 2 79 | no-new-wrappers: 2 80 | no-new: 2 81 | no-obj-calls: 2 82 | no-octal-escape: 2 83 | no-octal: 2 84 | no-param-reassign: 2 85 | no-path-concat: 2 86 | no-proto: 2 87 | no-redeclare: 2 88 | no-regex-spaces: 2 89 | no-return-assign: 2 90 | no-script-url: 2 91 | no-sequences: 2 92 | no-shadow-restricted-names: 2 93 | no-spaced-func: 2 94 | no-sparse-arrays: 2 95 | no-sync: 0 96 | no-throw-literal: 2 97 | no-trailing-spaces: 2 98 | no-undef-init: 2 99 | no-undef: 2 100 | no-unreachable: 2 101 | no-unused-expressions: 2 102 | no-unused-vars: [2, {vars: all, args: after-used}] 103 | no-void: 2 104 | no-with: 2 105 | one-var: [2, never] 106 | operator-assignment: [2, always] 107 | quote-props: [2, as-needed] 108 | quotes: [2, single] 109 | radix: 2 110 | semi-spacing: [2, {before: false, after: true}] 111 | semi: [2, always] 112 | space-after-keywords: [2, always] 113 | space-before-blocks: [2, always] 114 | space-before-function-paren: [2, {anonymous: always, named: never}] 115 | space-infix-ops: [2, int32Hint: false] 116 | space-return-throw-case: 2 117 | space-unary-ops: [2, {words: true, nonwords: false}] 118 | spaced-comment: [2, always] 119 | use-isnan: 2 120 | valid-typeof: 2 121 | wrap-iife: 2 122 | yoda: [2, never, exceptRange: true] 123 | 124 | # WARNINGS 125 | 126 | # DISABLED 127 | block-scoped-var: 0 128 | comma-dangle: 0 129 | complexity: 0 130 | consistent-return: 0 131 | consistent-this: 0 132 | default-case: 0 133 | dot-notation: 0 134 | func-names: 0 135 | func-style: 0 136 | max-nested-callbacks: 0 137 | new-cap: 0 138 | newline-after-var: 0 139 | no-console: 0 140 | no-control-regex: 0 141 | no-debugger: 0 142 | no-eq-null: 0 143 | no-inline-comments: 0 144 | no-labels: 0 145 | no-lone-blocks: 0 146 | no-loop-func: 0 147 | no-multiple-empty-lines: 0 148 | no-native-reassign: 0 149 | no-nested-ternary: 0 150 | no-new-func: 0 151 | no-process-env: 0 152 | no-process-exit: 0 153 | no-reserved-keys: 0 154 | no-restricted-modules: 0 155 | no-self-compare: 0 156 | no-ternary: 0 157 | no-undefined: 0 158 | no-underscore-dangle: 0 159 | no-use-before-define: 0 160 | no-var: 0 161 | no-warning-comments: 0 162 | padded-blocks: 0 163 | sort-vars: 0 164 | space-in-brackets: 0 165 | space-in-parens: 0 166 | strict: 0 167 | valid-jsdoc: 0 168 | vars-on-top: 0 169 | wrap-regex: 0 170 | -------------------------------------------------------------------------------- /data/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "__schema": { 4 | "queryType": { 5 | "name": "Query" 6 | }, 7 | "mutationType": { 8 | "name": "Mutation" 9 | }, 10 | "subscriptionType": null, 11 | "types": [ 12 | { 13 | "kind": "OBJECT", 14 | "name": "Query", 15 | "description": null, 16 | "fields": [ 17 | { 18 | "name": "node", 19 | "description": "Fetches an object given its ID", 20 | "args": [ 21 | { 22 | "name": "id", 23 | "description": "The ID of an object", 24 | "type": { 25 | "kind": "NON_NULL", 26 | "name": null, 27 | "ofType": { 28 | "kind": "SCALAR", 29 | "name": "ID", 30 | "ofType": null 31 | } 32 | }, 33 | "defaultValue": null 34 | } 35 | ], 36 | "type": { 37 | "kind": "INTERFACE", 38 | "name": "Node", 39 | "ofType": null 40 | }, 41 | "isDeprecated": false, 42 | "deprecationReason": null 43 | }, 44 | { 45 | "name": "home", 46 | "description": null, 47 | "args": [], 48 | "type": { 49 | "kind": "OBJECT", 50 | "name": "Page", 51 | "ofType": null 52 | }, 53 | "isDeprecated": false, 54 | "deprecationReason": null 55 | } 56 | ], 57 | "inputFields": null, 58 | "interfaces": [], 59 | "enumValues": null, 60 | "possibleTypes": null 61 | }, 62 | { 63 | "kind": "SCALAR", 64 | "name": "ID", 65 | "description": "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.", 66 | "fields": null, 67 | "inputFields": null, 68 | "interfaces": null, 69 | "enumValues": null, 70 | "possibleTypes": null 71 | }, 72 | { 73 | "kind": "INTERFACE", 74 | "name": "Node", 75 | "description": "An object with an ID", 76 | "fields": [ 77 | { 78 | "name": "id", 79 | "description": "The id of the object.", 80 | "args": [], 81 | "type": { 82 | "kind": "NON_NULL", 83 | "name": null, 84 | "ofType": { 85 | "kind": "SCALAR", 86 | "name": "ID", 87 | "ofType": null 88 | } 89 | }, 90 | "isDeprecated": false, 91 | "deprecationReason": null 92 | } 93 | ], 94 | "inputFields": null, 95 | "interfaces": null, 96 | "enumValues": null, 97 | "possibleTypes": [ 98 | { 99 | "kind": "OBJECT", 100 | "name": "Item", 101 | "ofType": null 102 | } 103 | ] 104 | }, 105 | { 106 | "kind": "OBJECT", 107 | "name": "Item", 108 | "description": null, 109 | "fields": [ 110 | { 111 | "name": "id", 112 | "description": "The ID of an object", 113 | "args": [], 114 | "type": { 115 | "kind": "NON_NULL", 116 | "name": null, 117 | "ofType": { 118 | "kind": "SCALAR", 119 | "name": "ID", 120 | "ofType": null 121 | } 122 | }, 123 | "isDeprecated": false, 124 | "deprecationReason": null 125 | }, 126 | { 127 | "name": "name", 128 | "description": null, 129 | "args": [], 130 | "type": { 131 | "kind": "SCALAR", 132 | "name": "String", 133 | "ofType": null 134 | }, 135 | "isDeprecated": false, 136 | "deprecationReason": null 137 | }, 138 | { 139 | "name": "likes", 140 | "description": null, 141 | "args": [], 142 | "type": { 143 | "kind": "SCALAR", 144 | "name": "Int", 145 | "ofType": null 146 | }, 147 | "isDeprecated": false, 148 | "deprecationReason": null 149 | } 150 | ], 151 | "inputFields": null, 152 | "interfaces": [ 153 | { 154 | "kind": "INTERFACE", 155 | "name": "Node", 156 | "ofType": null 157 | } 158 | ], 159 | "enumValues": null, 160 | "possibleTypes": null 161 | }, 162 | { 163 | "kind": "SCALAR", 164 | "name": "String", 165 | "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.", 166 | "fields": null, 167 | "inputFields": null, 168 | "interfaces": null, 169 | "enumValues": null, 170 | "possibleTypes": null 171 | }, 172 | { 173 | "kind": "SCALAR", 174 | "name": "Int", 175 | "description": "The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. ", 176 | "fields": null, 177 | "inputFields": null, 178 | "interfaces": null, 179 | "enumValues": null, 180 | "possibleTypes": null 181 | }, 182 | { 183 | "kind": "OBJECT", 184 | "name": "Page", 185 | "description": null, 186 | "fields": [ 187 | { 188 | "name": "id", 189 | "description": "The ID of an object", 190 | "args": [], 191 | "type": { 192 | "kind": "NON_NULL", 193 | "name": null, 194 | "ofType": { 195 | "kind": "SCALAR", 196 | "name": "ID", 197 | "ofType": null 198 | } 199 | }, 200 | "isDeprecated": false, 201 | "deprecationReason": null 202 | }, 203 | { 204 | "name": "items", 205 | "description": null, 206 | "args": [], 207 | "type": { 208 | "kind": "OBJECT", 209 | "name": "ItemConnection", 210 | "ofType": null 211 | }, 212 | "isDeprecated": false, 213 | "deprecationReason": null 214 | } 215 | ], 216 | "inputFields": null, 217 | "interfaces": [], 218 | "enumValues": null, 219 | "possibleTypes": null 220 | }, 221 | { 222 | "kind": "OBJECT", 223 | "name": "ItemConnection", 224 | "description": "A connection to a list of items.", 225 | "fields": [ 226 | { 227 | "name": "pageInfo", 228 | "description": "Information to aid in pagination.", 229 | "args": [], 230 | "type": { 231 | "kind": "NON_NULL", 232 | "name": null, 233 | "ofType": { 234 | "kind": "OBJECT", 235 | "name": "PageInfo", 236 | "ofType": null 237 | } 238 | }, 239 | "isDeprecated": false, 240 | "deprecationReason": null 241 | }, 242 | { 243 | "name": "edges", 244 | "description": "Information to aid in pagination.", 245 | "args": [], 246 | "type": { 247 | "kind": "LIST", 248 | "name": null, 249 | "ofType": { 250 | "kind": "OBJECT", 251 | "name": "ItemEdge", 252 | "ofType": null 253 | } 254 | }, 255 | "isDeprecated": false, 256 | "deprecationReason": null 257 | } 258 | ], 259 | "inputFields": null, 260 | "interfaces": [], 261 | "enumValues": null, 262 | "possibleTypes": null 263 | }, 264 | { 265 | "kind": "OBJECT", 266 | "name": "PageInfo", 267 | "description": "Information about pagination in a connection.", 268 | "fields": [ 269 | { 270 | "name": "hasNextPage", 271 | "description": "When paginating forwards, are there more items?", 272 | "args": [], 273 | "type": { 274 | "kind": "NON_NULL", 275 | "name": null, 276 | "ofType": { 277 | "kind": "SCALAR", 278 | "name": "Boolean", 279 | "ofType": null 280 | } 281 | }, 282 | "isDeprecated": false, 283 | "deprecationReason": null 284 | }, 285 | { 286 | "name": "hasPreviousPage", 287 | "description": "When paginating backwards, are there more items?", 288 | "args": [], 289 | "type": { 290 | "kind": "NON_NULL", 291 | "name": null, 292 | "ofType": { 293 | "kind": "SCALAR", 294 | "name": "Boolean", 295 | "ofType": null 296 | } 297 | }, 298 | "isDeprecated": false, 299 | "deprecationReason": null 300 | }, 301 | { 302 | "name": "startCursor", 303 | "description": "When paginating backwards, the cursor to continue.", 304 | "args": [], 305 | "type": { 306 | "kind": "SCALAR", 307 | "name": "String", 308 | "ofType": null 309 | }, 310 | "isDeprecated": false, 311 | "deprecationReason": null 312 | }, 313 | { 314 | "name": "endCursor", 315 | "description": "When paginating forwards, the cursor to continue.", 316 | "args": [], 317 | "type": { 318 | "kind": "SCALAR", 319 | "name": "String", 320 | "ofType": null 321 | }, 322 | "isDeprecated": false, 323 | "deprecationReason": null 324 | } 325 | ], 326 | "inputFields": null, 327 | "interfaces": [], 328 | "enumValues": null, 329 | "possibleTypes": null 330 | }, 331 | { 332 | "kind": "SCALAR", 333 | "name": "Boolean", 334 | "description": "The `Boolean` scalar type represents `true` or `false`.", 335 | "fields": null, 336 | "inputFields": null, 337 | "interfaces": null, 338 | "enumValues": null, 339 | "possibleTypes": null 340 | }, 341 | { 342 | "kind": "OBJECT", 343 | "name": "ItemEdge", 344 | "description": "An edge in a connection.", 345 | "fields": [ 346 | { 347 | "name": "node", 348 | "description": "The item at the end of the edge", 349 | "args": [], 350 | "type": { 351 | "kind": "OBJECT", 352 | "name": "Item", 353 | "ofType": null 354 | }, 355 | "isDeprecated": false, 356 | "deprecationReason": null 357 | }, 358 | { 359 | "name": "cursor", 360 | "description": "A cursor for use in pagination", 361 | "args": [], 362 | "type": { 363 | "kind": "NON_NULL", 364 | "name": null, 365 | "ofType": { 366 | "kind": "SCALAR", 367 | "name": "String", 368 | "ofType": null 369 | } 370 | }, 371 | "isDeprecated": false, 372 | "deprecationReason": null 373 | } 374 | ], 375 | "inputFields": null, 376 | "interfaces": [], 377 | "enumValues": null, 378 | "possibleTypes": null 379 | }, 380 | { 381 | "kind": "OBJECT", 382 | "name": "Mutation", 383 | "description": null, 384 | "fields": [ 385 | { 386 | "name": "likeItem", 387 | "description": null, 388 | "args": [ 389 | { 390 | "name": "input", 391 | "description": null, 392 | "type": { 393 | "kind": "NON_NULL", 394 | "name": null, 395 | "ofType": { 396 | "kind": "INPUT_OBJECT", 397 | "name": "LikeItemInput", 398 | "ofType": null 399 | } 400 | }, 401 | "defaultValue": null 402 | } 403 | ], 404 | "type": { 405 | "kind": "OBJECT", 406 | "name": "LikeItemPayload", 407 | "ofType": null 408 | }, 409 | "isDeprecated": false, 410 | "deprecationReason": null 411 | } 412 | ], 413 | "inputFields": null, 414 | "interfaces": [], 415 | "enumValues": null, 416 | "possibleTypes": null 417 | }, 418 | { 419 | "kind": "INPUT_OBJECT", 420 | "name": "LikeItemInput", 421 | "description": null, 422 | "fields": null, 423 | "inputFields": [ 424 | { 425 | "name": "id", 426 | "description": null, 427 | "type": { 428 | "kind": "NON_NULL", 429 | "name": null, 430 | "ofType": { 431 | "kind": "SCALAR", 432 | "name": "ID", 433 | "ofType": null 434 | } 435 | }, 436 | "defaultValue": null 437 | }, 438 | { 439 | "name": "clientMutationId", 440 | "description": null, 441 | "type": { 442 | "kind": "NON_NULL", 443 | "name": null, 444 | "ofType": { 445 | "kind": "SCALAR", 446 | "name": "String", 447 | "ofType": null 448 | } 449 | }, 450 | "defaultValue": null 451 | } 452 | ], 453 | "interfaces": null, 454 | "enumValues": null, 455 | "possibleTypes": null 456 | }, 457 | { 458 | "kind": "OBJECT", 459 | "name": "LikeItemPayload", 460 | "description": null, 461 | "fields": [ 462 | { 463 | "name": "item", 464 | "description": null, 465 | "args": [], 466 | "type": { 467 | "kind": "OBJECT", 468 | "name": "Item", 469 | "ofType": null 470 | }, 471 | "isDeprecated": false, 472 | "deprecationReason": null 473 | }, 474 | { 475 | "name": "clientMutationId", 476 | "description": null, 477 | "args": [], 478 | "type": { 479 | "kind": "NON_NULL", 480 | "name": null, 481 | "ofType": { 482 | "kind": "SCALAR", 483 | "name": "String", 484 | "ofType": null 485 | } 486 | }, 487 | "isDeprecated": false, 488 | "deprecationReason": null 489 | } 490 | ], 491 | "inputFields": null, 492 | "interfaces": [], 493 | "enumValues": null, 494 | "possibleTypes": null 495 | }, 496 | { 497 | "kind": "OBJECT", 498 | "name": "__Schema", 499 | "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.", 500 | "fields": [ 501 | { 502 | "name": "types", 503 | "description": "A list of all types supported by this server.", 504 | "args": [], 505 | "type": { 506 | "kind": "NON_NULL", 507 | "name": null, 508 | "ofType": { 509 | "kind": "LIST", 510 | "name": null, 511 | "ofType": { 512 | "kind": "NON_NULL", 513 | "name": null, 514 | "ofType": { 515 | "kind": "OBJECT", 516 | "name": "__Type" 517 | } 518 | } 519 | } 520 | }, 521 | "isDeprecated": false, 522 | "deprecationReason": null 523 | }, 524 | { 525 | "name": "queryType", 526 | "description": "The type that query operations will be rooted at.", 527 | "args": [], 528 | "type": { 529 | "kind": "NON_NULL", 530 | "name": null, 531 | "ofType": { 532 | "kind": "OBJECT", 533 | "name": "__Type", 534 | "ofType": null 535 | } 536 | }, 537 | "isDeprecated": false, 538 | "deprecationReason": null 539 | }, 540 | { 541 | "name": "mutationType", 542 | "description": "If this server supports mutation, the type that mutation operations will be rooted at.", 543 | "args": [], 544 | "type": { 545 | "kind": "OBJECT", 546 | "name": "__Type", 547 | "ofType": null 548 | }, 549 | "isDeprecated": false, 550 | "deprecationReason": null 551 | }, 552 | { 553 | "name": "subscriptionType", 554 | "description": "If this server support subscription, the type that subscription operations will be rooted at.", 555 | "args": [], 556 | "type": { 557 | "kind": "OBJECT", 558 | "name": "__Type", 559 | "ofType": null 560 | }, 561 | "isDeprecated": false, 562 | "deprecationReason": null 563 | }, 564 | { 565 | "name": "directives", 566 | "description": "A list of all directives supported by this server.", 567 | "args": [], 568 | "type": { 569 | "kind": "NON_NULL", 570 | "name": null, 571 | "ofType": { 572 | "kind": "LIST", 573 | "name": null, 574 | "ofType": { 575 | "kind": "NON_NULL", 576 | "name": null, 577 | "ofType": { 578 | "kind": "OBJECT", 579 | "name": "__Directive" 580 | } 581 | } 582 | } 583 | }, 584 | "isDeprecated": false, 585 | "deprecationReason": null 586 | } 587 | ], 588 | "inputFields": null, 589 | "interfaces": [], 590 | "enumValues": null, 591 | "possibleTypes": null 592 | }, 593 | { 594 | "kind": "OBJECT", 595 | "name": "__Type", 596 | "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.", 597 | "fields": [ 598 | { 599 | "name": "kind", 600 | "description": null, 601 | "args": [], 602 | "type": { 603 | "kind": "NON_NULL", 604 | "name": null, 605 | "ofType": { 606 | "kind": "ENUM", 607 | "name": "__TypeKind", 608 | "ofType": null 609 | } 610 | }, 611 | "isDeprecated": false, 612 | "deprecationReason": null 613 | }, 614 | { 615 | "name": "name", 616 | "description": null, 617 | "args": [], 618 | "type": { 619 | "kind": "SCALAR", 620 | "name": "String", 621 | "ofType": null 622 | }, 623 | "isDeprecated": false, 624 | "deprecationReason": null 625 | }, 626 | { 627 | "name": "description", 628 | "description": null, 629 | "args": [], 630 | "type": { 631 | "kind": "SCALAR", 632 | "name": "String", 633 | "ofType": null 634 | }, 635 | "isDeprecated": false, 636 | "deprecationReason": null 637 | }, 638 | { 639 | "name": "fields", 640 | "description": null, 641 | "args": [ 642 | { 643 | "name": "includeDeprecated", 644 | "description": null, 645 | "type": { 646 | "kind": "SCALAR", 647 | "name": "Boolean", 648 | "ofType": null 649 | }, 650 | "defaultValue": "false" 651 | } 652 | ], 653 | "type": { 654 | "kind": "LIST", 655 | "name": null, 656 | "ofType": { 657 | "kind": "NON_NULL", 658 | "name": null, 659 | "ofType": { 660 | "kind": "OBJECT", 661 | "name": "__Field", 662 | "ofType": null 663 | } 664 | } 665 | }, 666 | "isDeprecated": false, 667 | "deprecationReason": null 668 | }, 669 | { 670 | "name": "interfaces", 671 | "description": null, 672 | "args": [], 673 | "type": { 674 | "kind": "LIST", 675 | "name": null, 676 | "ofType": { 677 | "kind": "NON_NULL", 678 | "name": null, 679 | "ofType": { 680 | "kind": "OBJECT", 681 | "name": "__Type", 682 | "ofType": null 683 | } 684 | } 685 | }, 686 | "isDeprecated": false, 687 | "deprecationReason": null 688 | }, 689 | { 690 | "name": "possibleTypes", 691 | "description": null, 692 | "args": [], 693 | "type": { 694 | "kind": "LIST", 695 | "name": null, 696 | "ofType": { 697 | "kind": "NON_NULL", 698 | "name": null, 699 | "ofType": { 700 | "kind": "OBJECT", 701 | "name": "__Type", 702 | "ofType": null 703 | } 704 | } 705 | }, 706 | "isDeprecated": false, 707 | "deprecationReason": null 708 | }, 709 | { 710 | "name": "enumValues", 711 | "description": null, 712 | "args": [ 713 | { 714 | "name": "includeDeprecated", 715 | "description": null, 716 | "type": { 717 | "kind": "SCALAR", 718 | "name": "Boolean", 719 | "ofType": null 720 | }, 721 | "defaultValue": "false" 722 | } 723 | ], 724 | "type": { 725 | "kind": "LIST", 726 | "name": null, 727 | "ofType": { 728 | "kind": "NON_NULL", 729 | "name": null, 730 | "ofType": { 731 | "kind": "OBJECT", 732 | "name": "__EnumValue", 733 | "ofType": null 734 | } 735 | } 736 | }, 737 | "isDeprecated": false, 738 | "deprecationReason": null 739 | }, 740 | { 741 | "name": "inputFields", 742 | "description": null, 743 | "args": [], 744 | "type": { 745 | "kind": "LIST", 746 | "name": null, 747 | "ofType": { 748 | "kind": "NON_NULL", 749 | "name": null, 750 | "ofType": { 751 | "kind": "OBJECT", 752 | "name": "__InputValue", 753 | "ofType": null 754 | } 755 | } 756 | }, 757 | "isDeprecated": false, 758 | "deprecationReason": null 759 | }, 760 | { 761 | "name": "ofType", 762 | "description": null, 763 | "args": [], 764 | "type": { 765 | "kind": "OBJECT", 766 | "name": "__Type", 767 | "ofType": null 768 | }, 769 | "isDeprecated": false, 770 | "deprecationReason": null 771 | } 772 | ], 773 | "inputFields": null, 774 | "interfaces": [], 775 | "enumValues": null, 776 | "possibleTypes": null 777 | }, 778 | { 779 | "kind": "ENUM", 780 | "name": "__TypeKind", 781 | "description": "An enum describing what kind of type a given `__Type` is.", 782 | "fields": null, 783 | "inputFields": null, 784 | "interfaces": null, 785 | "enumValues": [ 786 | { 787 | "name": "SCALAR", 788 | "description": "Indicates this type is a scalar.", 789 | "isDeprecated": false, 790 | "deprecationReason": null 791 | }, 792 | { 793 | "name": "OBJECT", 794 | "description": "Indicates this type is an object. `fields` and `interfaces` are valid fields.", 795 | "isDeprecated": false, 796 | "deprecationReason": null 797 | }, 798 | { 799 | "name": "INTERFACE", 800 | "description": "Indicates this type is an interface. `fields` and `possibleTypes` are valid fields.", 801 | "isDeprecated": false, 802 | "deprecationReason": null 803 | }, 804 | { 805 | "name": "UNION", 806 | "description": "Indicates this type is a union. `possibleTypes` is a valid field.", 807 | "isDeprecated": false, 808 | "deprecationReason": null 809 | }, 810 | { 811 | "name": "ENUM", 812 | "description": "Indicates this type is an enum. `enumValues` is a valid field.", 813 | "isDeprecated": false, 814 | "deprecationReason": null 815 | }, 816 | { 817 | "name": "INPUT_OBJECT", 818 | "description": "Indicates this type is an input object. `inputFields` is a valid field.", 819 | "isDeprecated": false, 820 | "deprecationReason": null 821 | }, 822 | { 823 | "name": "LIST", 824 | "description": "Indicates this type is a list. `ofType` is a valid field.", 825 | "isDeprecated": false, 826 | "deprecationReason": null 827 | }, 828 | { 829 | "name": "NON_NULL", 830 | "description": "Indicates this type is a non-null. `ofType` is a valid field.", 831 | "isDeprecated": false, 832 | "deprecationReason": null 833 | } 834 | ], 835 | "possibleTypes": null 836 | }, 837 | { 838 | "kind": "OBJECT", 839 | "name": "__Field", 840 | "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.", 841 | "fields": [ 842 | { 843 | "name": "name", 844 | "description": null, 845 | "args": [], 846 | "type": { 847 | "kind": "NON_NULL", 848 | "name": null, 849 | "ofType": { 850 | "kind": "SCALAR", 851 | "name": "String", 852 | "ofType": null 853 | } 854 | }, 855 | "isDeprecated": false, 856 | "deprecationReason": null 857 | }, 858 | { 859 | "name": "description", 860 | "description": null, 861 | "args": [], 862 | "type": { 863 | "kind": "SCALAR", 864 | "name": "String", 865 | "ofType": null 866 | }, 867 | "isDeprecated": false, 868 | "deprecationReason": null 869 | }, 870 | { 871 | "name": "args", 872 | "description": null, 873 | "args": [], 874 | "type": { 875 | "kind": "NON_NULL", 876 | "name": null, 877 | "ofType": { 878 | "kind": "LIST", 879 | "name": null, 880 | "ofType": { 881 | "kind": "NON_NULL", 882 | "name": null, 883 | "ofType": { 884 | "kind": "OBJECT", 885 | "name": "__InputValue" 886 | } 887 | } 888 | } 889 | }, 890 | "isDeprecated": false, 891 | "deprecationReason": null 892 | }, 893 | { 894 | "name": "type", 895 | "description": null, 896 | "args": [], 897 | "type": { 898 | "kind": "NON_NULL", 899 | "name": null, 900 | "ofType": { 901 | "kind": "OBJECT", 902 | "name": "__Type", 903 | "ofType": null 904 | } 905 | }, 906 | "isDeprecated": false, 907 | "deprecationReason": null 908 | }, 909 | { 910 | "name": "isDeprecated", 911 | "description": null, 912 | "args": [], 913 | "type": { 914 | "kind": "NON_NULL", 915 | "name": null, 916 | "ofType": { 917 | "kind": "SCALAR", 918 | "name": "Boolean", 919 | "ofType": null 920 | } 921 | }, 922 | "isDeprecated": false, 923 | "deprecationReason": null 924 | }, 925 | { 926 | "name": "deprecationReason", 927 | "description": null, 928 | "args": [], 929 | "type": { 930 | "kind": "SCALAR", 931 | "name": "String", 932 | "ofType": null 933 | }, 934 | "isDeprecated": false, 935 | "deprecationReason": null 936 | } 937 | ], 938 | "inputFields": null, 939 | "interfaces": [], 940 | "enumValues": null, 941 | "possibleTypes": null 942 | }, 943 | { 944 | "kind": "OBJECT", 945 | "name": "__InputValue", 946 | "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.", 947 | "fields": [ 948 | { 949 | "name": "name", 950 | "description": null, 951 | "args": [], 952 | "type": { 953 | "kind": "NON_NULL", 954 | "name": null, 955 | "ofType": { 956 | "kind": "SCALAR", 957 | "name": "String", 958 | "ofType": null 959 | } 960 | }, 961 | "isDeprecated": false, 962 | "deprecationReason": null 963 | }, 964 | { 965 | "name": "description", 966 | "description": null, 967 | "args": [], 968 | "type": { 969 | "kind": "SCALAR", 970 | "name": "String", 971 | "ofType": null 972 | }, 973 | "isDeprecated": false, 974 | "deprecationReason": null 975 | }, 976 | { 977 | "name": "type", 978 | "description": null, 979 | "args": [], 980 | "type": { 981 | "kind": "NON_NULL", 982 | "name": null, 983 | "ofType": { 984 | "kind": "OBJECT", 985 | "name": "__Type", 986 | "ofType": null 987 | } 988 | }, 989 | "isDeprecated": false, 990 | "deprecationReason": null 991 | }, 992 | { 993 | "name": "defaultValue", 994 | "description": "A GraphQL-formatted string representing the default value for this input value.", 995 | "args": [], 996 | "type": { 997 | "kind": "SCALAR", 998 | "name": "String", 999 | "ofType": null 1000 | }, 1001 | "isDeprecated": false, 1002 | "deprecationReason": null 1003 | } 1004 | ], 1005 | "inputFields": null, 1006 | "interfaces": [], 1007 | "enumValues": null, 1008 | "possibleTypes": null 1009 | }, 1010 | { 1011 | "kind": "OBJECT", 1012 | "name": "__EnumValue", 1013 | "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.", 1014 | "fields": [ 1015 | { 1016 | "name": "name", 1017 | "description": null, 1018 | "args": [], 1019 | "type": { 1020 | "kind": "NON_NULL", 1021 | "name": null, 1022 | "ofType": { 1023 | "kind": "SCALAR", 1024 | "name": "String", 1025 | "ofType": null 1026 | } 1027 | }, 1028 | "isDeprecated": false, 1029 | "deprecationReason": null 1030 | }, 1031 | { 1032 | "name": "description", 1033 | "description": null, 1034 | "args": [], 1035 | "type": { 1036 | "kind": "SCALAR", 1037 | "name": "String", 1038 | "ofType": null 1039 | }, 1040 | "isDeprecated": false, 1041 | "deprecationReason": null 1042 | }, 1043 | { 1044 | "name": "isDeprecated", 1045 | "description": null, 1046 | "args": [], 1047 | "type": { 1048 | "kind": "NON_NULL", 1049 | "name": null, 1050 | "ofType": { 1051 | "kind": "SCALAR", 1052 | "name": "Boolean", 1053 | "ofType": null 1054 | } 1055 | }, 1056 | "isDeprecated": false, 1057 | "deprecationReason": null 1058 | }, 1059 | { 1060 | "name": "deprecationReason", 1061 | "description": null, 1062 | "args": [], 1063 | "type": { 1064 | "kind": "SCALAR", 1065 | "name": "String", 1066 | "ofType": null 1067 | }, 1068 | "isDeprecated": false, 1069 | "deprecationReason": null 1070 | } 1071 | ], 1072 | "inputFields": null, 1073 | "interfaces": [], 1074 | "enumValues": null, 1075 | "possibleTypes": null 1076 | }, 1077 | { 1078 | "kind": "OBJECT", 1079 | "name": "__Directive", 1080 | "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.", 1081 | "fields": [ 1082 | { 1083 | "name": "name", 1084 | "description": null, 1085 | "args": [], 1086 | "type": { 1087 | "kind": "NON_NULL", 1088 | "name": null, 1089 | "ofType": { 1090 | "kind": "SCALAR", 1091 | "name": "String", 1092 | "ofType": null 1093 | } 1094 | }, 1095 | "isDeprecated": false, 1096 | "deprecationReason": null 1097 | }, 1098 | { 1099 | "name": "description", 1100 | "description": null, 1101 | "args": [], 1102 | "type": { 1103 | "kind": "SCALAR", 1104 | "name": "String", 1105 | "ofType": null 1106 | }, 1107 | "isDeprecated": false, 1108 | "deprecationReason": null 1109 | }, 1110 | { 1111 | "name": "args", 1112 | "description": null, 1113 | "args": [], 1114 | "type": { 1115 | "kind": "NON_NULL", 1116 | "name": null, 1117 | "ofType": { 1118 | "kind": "LIST", 1119 | "name": null, 1120 | "ofType": { 1121 | "kind": "NON_NULL", 1122 | "name": null, 1123 | "ofType": { 1124 | "kind": "OBJECT", 1125 | "name": "__InputValue" 1126 | } 1127 | } 1128 | } 1129 | }, 1130 | "isDeprecated": false, 1131 | "deprecationReason": null 1132 | }, 1133 | { 1134 | "name": "onOperation", 1135 | "description": null, 1136 | "args": [], 1137 | "type": { 1138 | "kind": "NON_NULL", 1139 | "name": null, 1140 | "ofType": { 1141 | "kind": "SCALAR", 1142 | "name": "Boolean", 1143 | "ofType": null 1144 | } 1145 | }, 1146 | "isDeprecated": false, 1147 | "deprecationReason": null 1148 | }, 1149 | { 1150 | "name": "onFragment", 1151 | "description": null, 1152 | "args": [], 1153 | "type": { 1154 | "kind": "NON_NULL", 1155 | "name": null, 1156 | "ofType": { 1157 | "kind": "SCALAR", 1158 | "name": "Boolean", 1159 | "ofType": null 1160 | } 1161 | }, 1162 | "isDeprecated": false, 1163 | "deprecationReason": null 1164 | }, 1165 | { 1166 | "name": "onField", 1167 | "description": null, 1168 | "args": [], 1169 | "type": { 1170 | "kind": "NON_NULL", 1171 | "name": null, 1172 | "ofType": { 1173 | "kind": "SCALAR", 1174 | "name": "Boolean", 1175 | "ofType": null 1176 | } 1177 | }, 1178 | "isDeprecated": false, 1179 | "deprecationReason": null 1180 | } 1181 | ], 1182 | "inputFields": null, 1183 | "interfaces": [], 1184 | "enumValues": null, 1185 | "possibleTypes": null 1186 | } 1187 | ], 1188 | "directives": [ 1189 | { 1190 | "name": "include", 1191 | "description": "Directs the executor to include this field or fragment only when the `if` argument is true.", 1192 | "args": [ 1193 | { 1194 | "name": "if", 1195 | "description": "Included when true.", 1196 | "type": { 1197 | "kind": "NON_NULL", 1198 | "name": null, 1199 | "ofType": { 1200 | "kind": "SCALAR", 1201 | "name": "Boolean", 1202 | "ofType": null 1203 | } 1204 | }, 1205 | "defaultValue": null 1206 | } 1207 | ], 1208 | "onOperation": false, 1209 | "onFragment": true, 1210 | "onField": true 1211 | }, 1212 | { 1213 | "name": "skip", 1214 | "description": "Directs the executor to skip this field or fragment when the `if` argument is true.", 1215 | "args": [ 1216 | { 1217 | "name": "if", 1218 | "description": "Skipped when true.", 1219 | "type": { 1220 | "kind": "NON_NULL", 1221 | "name": null, 1222 | "ofType": { 1223 | "kind": "SCALAR", 1224 | "name": "Boolean", 1225 | "ofType": null 1226 | } 1227 | }, 1228 | "defaultValue": null 1229 | } 1230 | ], 1231 | "onOperation": false, 1232 | "onFragment": true, 1233 | "onField": true 1234 | } 1235 | ] 1236 | } 1237 | } 1238 | } --------------------------------------------------------------------------------