├── .babelrc
├── .editorconfig
├── .eslintrc
├── .gitignore
├── README.md
├── build
└── babelRelayPlugin.js
├── data
├── defaultDefinitions.js
├── models
│ ├── Cart.js
│ ├── CartEntry.js
│ ├── Product.js
│ └── ProductList.js
├── mutations
│ ├── addToCartMutation.js
│ └── removeFromCartMutation.js
├── schema.graphqls
├── schema.js
├── schema.json
├── services
│ ├── cartService.js
│ └── productService.js
└── types
│ ├── cartEntryType.js
│ ├── cartType.js
│ ├── imageType.js
│ ├── productListType.js
│ ├── productType.js
│ ├── productsType.js
│ └── viewerType.js
├── graphql.config.json
├── graphql.schema.json
├── gulpfile.babel.js
├── js
├── app.js
├── components
│ ├── App.js
│ ├── cart
│ │ ├── Cart.js
│ │ ├── Cart.scss
│ │ ├── CartEntry.js
│ │ ├── CartEntry.scss
│ │ ├── CartWidget.js
│ │ └── CartWidget.scss
│ ├── common
│ │ ├── Ball.js
│ │ ├── CurveBall.js
│ │ ├── CurveBall.scss
│ │ ├── Portal.js
│ │ ├── Portal.scss
│ │ ├── Price.js
│ │ ├── Price.scss
│ │ ├── Scroll.js
│ │ └── Scroll.scss
│ ├── form
│ │ ├── InputQuantity.js
│ │ └── InputQuantity.scss
│ ├── product
│ │ ├── ProductEntry.js
│ │ ├── ProductEntry.scss
│ │ ├── ProductList.js
│ │ └── ProductList.scss
│ └── styles
│ │ ├── animations.scss
│ │ ├── animations
│ │ ├── fade.scss
│ │ ├── scale.scss
│ │ ├── shake.scss
│ │ └── slide.scss
│ │ ├── common.scss
│ │ ├── entries.scss
│ │ ├── icons.scss
│ │ ├── shape.scss
│ │ └── variables.scss
├── mutations
│ ├── AddToCartMutation.js
│ └── RemoveFromCartMutation.js
├── queries
│ └── viewerQueries.js
├── routes
│ ├── cartRoute.js
│ ├── productListRoute.js
│ └── rootRoute.js
└── utils
│ └── RegExes.js
├── logger.js
├── package.json
├── postcss.config.js
├── public
└── index.html
├── scripts
└── updateSchema.js
├── server.js
├── tasks
└── dev.js
└── webpack.dev.config.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "passPerPreset": true,
3 | "presets": [
4 | {
5 | "plugins": [
6 | "./build/babelRelayPlugin"
7 | ]
8 | },
9 | "react",
10 | ["es2015", {"loose": true}],
11 | "stage-0"
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | end_of_line = lf
7 | indent_size = 2
8 | indent_style = space
9 | max_line_length = 80
10 | trim_trailing_whitespace = true
11 |
12 | [*.md]
13 | max_line_length = 0
14 | trim_trailing_whitespace = false
15 |
16 | [COMMIT_EDITMSG]
17 | max_line_length = 0
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "airbnb"
3 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules
2 | /logs
3 | /dist
4 | .idea
5 | *.iml
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # relay-cart
2 | A simple shopping cart example leveraging relay & GraphQL with routing and pagination
3 |
4 | ## Usage
5 | clone this repo and run:
6 |
7 | ```shell
8 | npm install
9 | npm start
10 | ```
11 | and then visit [http://localhost:3000/](http://localhost:3000/)
12 |
13 | ## Demo
14 |
15 | View a demo here: [http://120.76.218.113/relay-cart/demo.html](http://120.76.218.113/relay-cart/demo.html).
16 | Add items to the cart and change the quantities.
17 |
18 | ## Developing
19 |
20 | Any changes to files in the 'js' directory the server to automatically rebuild the app and refresh your browser.
21 | If at any time you make changes to data/schema.js, stop the server, regenerate data/schema.json, and restart the server:
22 |
23 | ```shell
24 | npm run updateSchema
25 | npm start
26 | ```
27 |
--------------------------------------------------------------------------------
/build/babelRelayPlugin.js:
--------------------------------------------------------------------------------
1 | var getBabelRelayPlugin = require('babel-relay-plugin');
2 | var schema = require('../data/schema.json');
3 |
4 | module.exports = getBabelRelayPlugin(schema.data);
5 |
--------------------------------------------------------------------------------
/data/defaultDefinitions.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by Soon on 2/22/16.
3 | */
4 |
5 | import {
6 | GraphQLID,
7 | GraphQLList,
8 | GraphQLNonNull,
9 | GraphQLObjectType,
10 | GraphQLSchema,
11 | GraphQLString,
12 | } from 'graphql';
13 |
14 | import {
15 | connectionArgs,
16 | connectionDefinitions,
17 | connectionFromArray,
18 | fromGlobalId,
19 | globalIdField,
20 | mutationWithClientMutationId,
21 | nodeDefinitions,
22 | } from 'graphql-relay';
23 |
24 | import logger from '../logger';
25 |
26 | import { productType, productListType, cartType, cartEntryType } from './schema';
27 |
28 | import CartEntry from './models/CartEntry';
29 | import cartService from './services/cartService';
30 |
31 | import ProductList from './models/ProductList';
32 |
33 |
34 | export const { nodeInterface, nodeField } = nodeDefinitions(
35 | async(globalId, session) => {
36 | logger.info(`Getting node data from globalId(${globalId})`);
37 |
38 | const { type, id } = fromGlobalId(globalId);
39 |
40 | if (type === 'CartEntry') {
41 | const cart = cartService.getSessionCart(session);
42 | return cart.entries.find((entry)=> entry.id === id);
43 | }
44 |
45 | if (type === 'ProductList') {
46 | return new ProductList({});
47 | }
48 |
49 | return null;
50 | },
51 | (obj) => {
52 | if (obj instanceof CartEntry) {
53 | return cartEntryType;
54 | }
55 |
56 | if (obj instanceof ProductList) {
57 | return productListType;
58 | }
59 |
60 | return null;
61 | }
62 | );
63 |
64 |
--------------------------------------------------------------------------------
/data/models/Cart.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by Soon on 2/26/16.
3 | */
4 |
5 | export default class Cart {
6 |
7 | constructor({ entries }) {
8 | this.entries = entries;
9 | }
10 |
11 | get totalNumberOfItems() {
12 | let totalNumberOfItems = 0;
13 | if (this.entries.length > 0) {
14 | for (let i = 0; i < this.entries.length; ++i) {
15 | totalNumberOfItems += this.entries[i].quantity;
16 | }
17 | }
18 |
19 | return totalNumberOfItems;
20 | }
21 |
22 | get totalPriceOfItems() {
23 | let totalPriceOfItems = 0;
24 | if (this.entries.length > 0) {
25 | for (let i = 0; i < this.entries.length; ++i) {
26 | const entry = this.entries[i];
27 | totalPriceOfItems += entry.quantity * entry.product.price;
28 | }
29 | }
30 |
31 | return totalPriceOfItems.toFixed(2);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/data/models/CartEntry.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by Soon on 2/26/16.
3 | */
4 |
5 | export default class CartEntry {
6 | constructor({ id, product, quantity }) {
7 | this.id = id;
8 | this.product = product;
9 | this.quantity = quantity;
10 | this.price = product.price;
11 | this.totalPrice = (product.price * quantity).toFixed(2);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/data/models/Product.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by Soon on 2/25/16.
3 | */
4 |
5 | const PRODUCTS = [
6 | {
7 | id: '1118531647', productCode: '1118531647',
8 | name: 'JavaScript and JQuery: Interactive Front-End Web Development',
9 | price: 28.85,
10 | images: [{
11 | format: 'thumbnail',
12 | url: 'http://ecx.images-amazon.com/images/I/41PhOmFQTTL._AA320_QL65_.jpg',
13 | }],
14 | },
15 | {
16 | id: '0596517742', productCode: '0596517742',
17 | name: 'JavaScript: The Good Parts',
18 | price: 20.46,
19 | images: [{
20 | format: 'thumbnail',
21 | url: 'http://ecx.images-amazon.com/images/I/518QVtPWA7L._AA320_QL65_.jpg',
22 | }],
23 | },
24 | {
25 | id: '1593275404', productCode: '1593275404',
26 | name: 'The Principles of Object-Oriented JavaScript',
27 | price: 15.87,
28 | images: [{
29 | format: 'thumbnail',
30 | url: 'http://ecx.images-amazon.com/images/I/51+Uy4JxjVL._AA320_QL65_.jpg',
31 | }],
32 | },
33 | {
34 | id: '1593275846', productCode: '1593275846',
35 | name: 'Eloquent JavaScript: A Modern Introduction to Programming',
36 | price: 27.92,
37 | images: [{
38 | format: 'thumbnail',
39 | url: 'http://ecx.images-amazon.com/images/I/51pLAgSXOzL._AA320_QL65_.jpg',
40 | }],
41 | },
42 | {
43 | id: '1118026691', productCode: '1118026691',
44 | name: 'Professional JavaScript for Web Developers',
45 | price: 26.45,
46 | images: [{
47 | format: 'thumbnail',
48 | url: 'http://ecx.images-amazon.com/images/I/51bRhyVTVGL._AA320_QL65_.jpg',
49 | }],
50 | },
51 | {
52 | id: '1493692615', productCode: '1493692615',
53 | name: 'A Software Engineer Learns HTML5, JavaScript and jQuery',
54 | price: 13.49,
55 | images: [{
56 | format: 'thumbnail',
57 | url: 'http://ecx.images-amazon.com/images/I/41XtnwhGs6L._AA320_QL65_.jpg',
58 | }],
59 | },
60 | {
61 | id: '1495233006', productCode: '1495233006',
62 | name: 'Learn JavaScript VISUALLY',
63 | price: 13.46,
64 | images: [{
65 | format: 'thumbnail',
66 | url: 'http://ecx.images-amazon.com/images/I/51F1TUdNOKL._AA320_QL65_.jpg',
67 | }],
68 | },
69 | {
70 | id: '0596806752', productCode: '0596806752',
71 | name: 'JavaScript Patterns',
72 | price: 18.09,
73 | images: [{
74 | format: 'thumbnail',
75 | url: 'http://ecx.images-amazon.com/images/I/51ACzMjH6rL._AA320_QL65_.jpg',
76 | }],
77 | },
78 | {
79 | id: '1491924462', productCode: '1491924462',
80 | name: "You Don't Know JS: Up & Going",
81 | price: 4.99,
82 | images: [{
83 | format: 'thumbnail',
84 | url: 'http://ecx.images-amazon.com/images/I/41FhogvNebL._AA320_QL65_.jpg',
85 | }],
86 | },
87 | {
88 | id: '0321812182', productCode: '0321812182',
89 | name: 'Effective JavaScript: 68 Specific Ways to Harness the Power of JavaScript (Effective Software Development Series)',
90 | price: 29.48,
91 | images: [{
92 | format: 'thumbnail',
93 | url: 'http://ecx.images-amazon.com/images/I/51t8vT-IvqL._AA320_QL65_.jpg',
94 | }],
95 | },
96 | {
97 | id: '144934013X', productCode: '144934013X',
98 | name: 'Head First JavaScript Programming',
99 | price: 38.89,
100 | images: [{
101 | format: 'thumbnail',
102 | url: 'http://ecx.images-amazon.com/images/I/51qpyuO-ANL._AA320_QL65_.jpg',
103 | }],
104 | },
105 | {
106 | id: '1519638779', productCode: '1519638779',
107 | name: "JavaScript: Crash Course - The Ultimate Beginner's Course to Learning JavaScript Programming in Under 12 Hours",
108 | price: 9.99,
109 | images: [{
110 | format: 'thumbnail',
111 | url: 'http://ecx.images-amazon.com/images/I/51d6QOwdxXL._AA320_QL65_.jpg',
112 | }],
113 | },
114 | {
115 | id: '067233738X', productCode: '067233738X',
116 | name: 'JavaScript in 24 Hours, Sams Teach Yourself (6th Edition)',
117 | price: 27.95,
118 | images: [{
119 | format: 'thumbnail',
120 | url: 'http://ecx.images-amazon.com/images/I/512+yH2PsbL._AA320_QL65_.jpg',
121 | }],
122 | },
123 | {
124 | id: '152373082X', productCode: '152373082X',
125 | name: "JavaScript: The Ultimate Beginner's Guide!",
126 | price: 9.99,
127 | images: [{
128 | format: 'thumbnail',
129 | url: 'http://ecx.images-amazon.com/images/I/41pLEp5yd7L._AA320_QL65_.jpg',
130 | }],
131 | },
132 | ];
133 |
134 | export default class Product {
135 | static getAll = () => PRODUCTS.map(p => new Product(p));
136 |
137 | static findOne = ({ productCode }) => PRODUCTS.find(p => p.productCode === productCode);
138 | static findById = (id) => PRODUCTS.find(p => p.id === id);
139 |
140 | constructor({ id, name, price, color, images }) {
141 | this.id = id;
142 | this.name = name;
143 | this.color = color;
144 | this.price = price;
145 | this.images = images;
146 | }
147 | }
148 |
--------------------------------------------------------------------------------
/data/models/ProductList.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by Soon on 2/25/16.
3 | */
4 |
5 | import Product from './Product';
6 |
7 | export default class ProductList {
8 | static findAll = ({ start, size })=> {
9 | const products = Product.getAll();
10 | const items = products.slice(start, start + size);
11 | const totalNumberOfItems = products.length;
12 |
13 | return new ProductList({
14 | items,
15 | totalNumberOfItems,
16 | });
17 | };
18 |
19 | constructor({ items, totalNumberOfItems }) {
20 | this.items = items;
21 | this.totalNumberOfItems = totalNumberOfItems;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/data/mutations/addToCartMutation.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by Soon on 2/23/16.
3 | */
4 |
5 | import {
6 | GraphQLBoolean,
7 | GraphQLFloat,
8 | GraphQLID,
9 | GraphQLList,
10 | GraphQLNonNull,
11 | GraphQLObjectType,
12 | GraphQLSchema,
13 | GraphQLInt,
14 | GraphQLString,
15 | } from 'graphql';
16 |
17 | import {
18 | connectionArgs,
19 | connectionDefinitions,
20 | connectionFromArray,
21 | cursorForObjectInConnection,
22 | fromGlobalId,
23 | globalIdField,
24 | mutationWithClientMutationId,
25 | nodeDefinitions,
26 | offsetToCursor,
27 | toGlobalId,
28 | } from 'graphql-relay';
29 |
30 | import logger from '../../logger';
31 |
32 | import cartEntryType, { cartEntryEdgeType } from '../types/cartEntryType';
33 | import cartType from '../types/cartType';
34 |
35 | import cartService from '../services/cartService';
36 | import productService from '../services/productService';
37 |
38 | const addToCartMutation = mutationWithClientMutationId({
39 | name: 'AddToCart',
40 | inputFields: {
41 | id: { type: new GraphQLNonNull(GraphQLID) },
42 | quantity: { type: GraphQLInt },
43 | },
44 | outputFields: {
45 | cartEntryEdge: {
46 | type: cartEntryEdgeType,
47 | },
48 | cartEntry: {
49 | type: cartEntryType,
50 | },
51 | cart: {
52 | type: cartType,
53 | },
54 | },
55 | mutateAndGetPayload: async({ id, quantity }, session) => {
56 | logger.info('Invoke addToCartMutation with params:', { id, quantity });
57 | const cart = cartService.getSessionCart(session);
58 |
59 | const localProductId = fromGlobalId(id).id;
60 | const product = productService.findById(localProductId);
61 |
62 | const cartEntry = cartService.addToCart(cart, product.productCode, quantity);
63 | const cartEntryEdge = {
64 | cursor: cursorForObjectInConnection(cart.entries, cartEntry),
65 | node: cartEntry,
66 | };
67 |
68 | return { cartEntry, cartEntryEdge, cart };
69 | },
70 | });
71 |
72 | export default addToCartMutation;
73 |
--------------------------------------------------------------------------------
/data/mutations/removeFromCartMutation.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by Soon on 3/1/16.
3 | */
4 |
5 | import {
6 | GraphQLBoolean,
7 | GraphQLFloat,
8 | GraphQLID,
9 | GraphQLList,
10 | GraphQLNonNull,
11 | GraphQLObjectType,
12 | GraphQLSchema,
13 | GraphQLInt,
14 | GraphQLString,
15 | } from 'graphql';
16 |
17 | import {
18 | connectionArgs,
19 | connectionDefinitions,
20 | connectionFromArray,
21 | cursorForObjectInConnection,
22 | fromGlobalId,
23 | globalIdField,
24 | mutationWithClientMutationId,
25 | nodeDefinitions,
26 | offsetToCursor,
27 | toGlobalId,
28 | } from 'graphql-relay';
29 |
30 | import logger from '../../logger';
31 |
32 | import cartService from '../services/cartService';
33 |
34 | import cartType from '../types/cartType';
35 |
36 | const removeFromCartMutation = mutationWithClientMutationId({
37 | name: 'RemoveFromCart',
38 | inputFields: {
39 | id: { type: new GraphQLNonNull(GraphQLID) },
40 | },
41 | outputFields: {
42 | deletedCartEntryId: {
43 | type: GraphQLID,
44 | resolve: async({ deletedCartEntryId }) =>deletedCartEntryId,
45 | },
46 | cart: {
47 | type: cartType,
48 | resolve: ({ cart })=> cart,
49 | },
50 | },
51 | mutateAndGetPayload: async({ id }, session) => {
52 | logger.info('Invoke removeFromCartMutation with params:', { id });
53 |
54 | const cart = cartService.getSessionCart(session);
55 | const localCartEntryId = fromGlobalId(id).id;
56 | cartService.removeFromCart(cart, localCartEntryId);
57 |
58 | return { deletedCartEntryId: id, cart };
59 | },
60 | });
61 |
62 | export default removeFromCartMutation;
63 |
--------------------------------------------------------------------------------
/data/schema.graphqls:
--------------------------------------------------------------------------------
1 | input AddToCartInput {
2 | id: ID!
3 | quantity: Int
4 | clientMutationId: String
5 | }
6 |
7 | type AddToCartPayload {
8 | cartEntryEdge: CartEntryEdge
9 | cartEntry: CartEntry
10 | cart: Cart
11 | clientMutationId: String
12 | }
13 |
14 | type Cart implements Node {
15 | # The ID of an object
16 | id: ID!
17 | entries(after: String, first: Int, before: String, last: Int): CartEntryConnection
18 | totalNumberOfItems: Int
19 | totalPriceOfItems: Float
20 | }
21 |
22 | type CartEntry implements Node {
23 | # The ID of an object
24 | id: ID!
25 | product: Product
26 | quantity: Float
27 | price: Float
28 | totalPrice: Float
29 | }
30 |
31 | # A connection to a list of items.
32 | type CartEntryConnection {
33 | # Information to aid in pagination.
34 | pageInfo: PageInfo!
35 |
36 | # A list of edges.
37 | edges: [CartEntryEdge]
38 | }
39 |
40 | # An edge in a connection.
41 | type CartEntryEdge {
42 | # The item at the end of the edge
43 | node: CartEntry
44 |
45 | # A cursor for use in pagination
46 | cursor: String!
47 | }
48 |
49 | # Just image
50 | type Image {
51 | # The format of image.
52 | format: String
53 |
54 | # The url of image.
55 | url: String
56 | }
57 |
58 | type Mutation {
59 | addToCart(input: AddToCartInput!): AddToCartPayload
60 | removeFromCart(input: RemoveFromCartInput!): RemoveFromCartPayload
61 | }
62 |
63 | # An object with an ID
64 | interface Node {
65 | # The id of the object.
66 | id: ID!
67 | }
68 |
69 | # Information about pagination in a connection.
70 | type PageInfo {
71 | # When paginating forwards, are there more items?
72 | hasNextPage: Boolean!
73 |
74 | # When paginating backwards, are there more items?
75 | hasPreviousPage: Boolean!
76 |
77 | # When paginating backwards, the cursor to continue.
78 | startCursor: String
79 |
80 | # When paginating forwards, the cursor to continue.
81 | endCursor: String
82 | }
83 |
84 | type Product implements Node {
85 | # The ID of an object
86 | id: ID!
87 |
88 | # 商品名称
89 | name: String
90 |
91 | # 商品颜色
92 | color: String
93 |
94 | # 商品描述
95 | description: String
96 |
97 | # 商品价格,保留两位小数
98 | price: Float
99 |
100 | # 商品图片,['primary': 主图,'thumbnail':缩略图,'zoom':大图]
101 | images(format: String = "any", after: String, first: Int, before: String, last: Int): [Image]
102 | }
103 |
104 | # A connection to a list of items.
105 | type ProductConnection {
106 | # Information to aid in pagination.
107 | pageInfo: PageInfo!
108 |
109 | # A list of edges.
110 | edges: [ProductEdge]
111 | totalNumberOfItems: Int
112 | }
113 |
114 | # An edge in a connection.
115 | type ProductEdge {
116 | # The item at the end of the edge
117 | node: Product
118 |
119 | # A cursor for use in pagination
120 | cursor: String!
121 | }
122 |
123 | type ProductList implements Node {
124 | # The ID of an object
125 | id: ID!
126 | items(after: String, first: Int, before: String, last: Int): ProductConnection
127 | }
128 |
129 | type Query {
130 | product(id: ID): Product
131 | productList: ProductList
132 | cart: Cart
133 | viewer(id: ID): Viewer
134 |
135 | # Fetches an object given its ID
136 | node(
137 | # The ID of an object
138 | id: ID!
139 | ): Node
140 | }
141 |
142 | input RemoveFromCartInput {
143 | id: ID!
144 | clientMutationId: String
145 | }
146 |
147 | type RemoveFromCartPayload {
148 | deletedCartEntryId: ID
149 | cart: Cart
150 | clientMutationId: String
151 | }
152 |
153 | type Viewer implements Node {
154 | # The ID of an object
155 | id: ID!
156 | name: String
157 | cart: Cart
158 | products(after: String, first: Int, before: String, last: Int): ProductConnection
159 | }
160 |
--------------------------------------------------------------------------------
/data/schema.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by Soon on 2/22/16.
3 | */
4 |
5 | import {
6 | GraphQLID,
7 | GraphQLList,
8 | GraphQLNonNull,
9 | GraphQLObjectType,
10 | GraphQLSchema,
11 | GraphQLString,
12 | } from 'graphql';
13 |
14 | import { nodeField } from './defaultDefinitions';
15 | export * from './defaultDefinitions';
16 |
17 | import { viewerType, queryViewer } from './types/viewerType';
18 | export * from './types/viewerType';
19 |
20 | import { productType, queryProduct } from './types/productType';
21 | export * from './types/productType';
22 |
23 | import { productListType, queryProductList } from './types/productListType';
24 | export * from './types/productListType';
25 |
26 | import { cartType, queryCart } from './types/cartType';
27 | export * from './types/cartType';
28 |
29 | import { cartEntryType, queryCartEntry } from './types/cartEntryType';
30 | export * from './types/cartEntryType';
31 |
32 |
33 | const queryType = new GraphQLObjectType({
34 | name: 'Query',
35 | fields: () => ({
36 |
37 | product: queryProduct,
38 | productList: queryProductList,
39 | cart: queryCart,
40 | viewer: queryViewer,
41 |
42 | node: nodeField,
43 | }),
44 | });
45 |
46 | const mutationType = new GraphQLObjectType({
47 | name: 'Mutation',
48 | fields: () => ({
49 | addToCart: require('./mutations/addToCartMutation').default,
50 | removeFromCart: require('./mutations/removeFromCartMutation').default,
51 | }),
52 | });
53 |
54 | export const Schema = new GraphQLSchema({
55 | query: queryType,
56 | mutation: mutationType,
57 | });
58 |
59 | export default Schema;
60 |
--------------------------------------------------------------------------------
/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": "product",
19 | "description": null,
20 | "args": [
21 | {
22 | "name": "id",
23 | "description": null,
24 | "type": {
25 | "kind": "SCALAR",
26 | "name": "ID",
27 | "ofType": null
28 | },
29 | "defaultValue": null
30 | }
31 | ],
32 | "type": {
33 | "kind": "OBJECT",
34 | "name": "Product",
35 | "ofType": null
36 | },
37 | "isDeprecated": false,
38 | "deprecationReason": null
39 | },
40 | {
41 | "name": "productList",
42 | "description": null,
43 | "args": [],
44 | "type": {
45 | "kind": "OBJECT",
46 | "name": "ProductList",
47 | "ofType": null
48 | },
49 | "isDeprecated": false,
50 | "deprecationReason": null
51 | },
52 | {
53 | "name": "cart",
54 | "description": null,
55 | "args": [],
56 | "type": {
57 | "kind": "OBJECT",
58 | "name": "Cart",
59 | "ofType": null
60 | },
61 | "isDeprecated": false,
62 | "deprecationReason": null
63 | },
64 | {
65 | "name": "viewer",
66 | "description": null,
67 | "args": [
68 | {
69 | "name": "id",
70 | "description": null,
71 | "type": {
72 | "kind": "SCALAR",
73 | "name": "ID",
74 | "ofType": null
75 | },
76 | "defaultValue": null
77 | }
78 | ],
79 | "type": {
80 | "kind": "OBJECT",
81 | "name": "Viewer",
82 | "ofType": null
83 | },
84 | "isDeprecated": false,
85 | "deprecationReason": null
86 | },
87 | {
88 | "name": "node",
89 | "description": "Fetches an object given its ID",
90 | "args": [
91 | {
92 | "name": "id",
93 | "description": "The ID of an object",
94 | "type": {
95 | "kind": "NON_NULL",
96 | "name": null,
97 | "ofType": {
98 | "kind": "SCALAR",
99 | "name": "ID",
100 | "ofType": null
101 | }
102 | },
103 | "defaultValue": null
104 | }
105 | ],
106 | "type": {
107 | "kind": "INTERFACE",
108 | "name": "Node",
109 | "ofType": null
110 | },
111 | "isDeprecated": false,
112 | "deprecationReason": null
113 | }
114 | ],
115 | "inputFields": null,
116 | "interfaces": [],
117 | "enumValues": null,
118 | "possibleTypes": null
119 | },
120 | {
121 | "kind": "SCALAR",
122 | "name": "ID",
123 | "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.",
124 | "fields": null,
125 | "inputFields": null,
126 | "interfaces": null,
127 | "enumValues": null,
128 | "possibleTypes": null
129 | },
130 | {
131 | "kind": "OBJECT",
132 | "name": "Product",
133 | "description": null,
134 | "fields": [
135 | {
136 | "name": "id",
137 | "description": "The ID of an object",
138 | "args": [],
139 | "type": {
140 | "kind": "NON_NULL",
141 | "name": null,
142 | "ofType": {
143 | "kind": "SCALAR",
144 | "name": "ID",
145 | "ofType": null
146 | }
147 | },
148 | "isDeprecated": false,
149 | "deprecationReason": null
150 | },
151 | {
152 | "name": "name",
153 | "description": "商品名称",
154 | "args": [],
155 | "type": {
156 | "kind": "SCALAR",
157 | "name": "String",
158 | "ofType": null
159 | },
160 | "isDeprecated": false,
161 | "deprecationReason": null
162 | },
163 | {
164 | "name": "color",
165 | "description": "商品颜色",
166 | "args": [],
167 | "type": {
168 | "kind": "SCALAR",
169 | "name": "String",
170 | "ofType": null
171 | },
172 | "isDeprecated": false,
173 | "deprecationReason": null
174 | },
175 | {
176 | "name": "description",
177 | "description": "商品描述",
178 | "args": [],
179 | "type": {
180 | "kind": "SCALAR",
181 | "name": "String",
182 | "ofType": null
183 | },
184 | "isDeprecated": false,
185 | "deprecationReason": null
186 | },
187 | {
188 | "name": "price",
189 | "description": "商品价格,保留两位小数",
190 | "args": [],
191 | "type": {
192 | "kind": "SCALAR",
193 | "name": "Float",
194 | "ofType": null
195 | },
196 | "isDeprecated": false,
197 | "deprecationReason": null
198 | },
199 | {
200 | "name": "images",
201 | "description": "商品图片,['primary': 主图,'thumbnail':缩略图,'zoom':大图]",
202 | "args": [
203 | {
204 | "name": "format",
205 | "description": null,
206 | "type": {
207 | "kind": "SCALAR",
208 | "name": "String",
209 | "ofType": null
210 | },
211 | "defaultValue": "\"any\""
212 | },
213 | {
214 | "name": "after",
215 | "description": null,
216 | "type": {
217 | "kind": "SCALAR",
218 | "name": "String",
219 | "ofType": null
220 | },
221 | "defaultValue": null
222 | },
223 | {
224 | "name": "first",
225 | "description": null,
226 | "type": {
227 | "kind": "SCALAR",
228 | "name": "Int",
229 | "ofType": null
230 | },
231 | "defaultValue": null
232 | },
233 | {
234 | "name": "before",
235 | "description": null,
236 | "type": {
237 | "kind": "SCALAR",
238 | "name": "String",
239 | "ofType": null
240 | },
241 | "defaultValue": null
242 | },
243 | {
244 | "name": "last",
245 | "description": null,
246 | "type": {
247 | "kind": "SCALAR",
248 | "name": "Int",
249 | "ofType": null
250 | },
251 | "defaultValue": null
252 | }
253 | ],
254 | "type": {
255 | "kind": "LIST",
256 | "name": null,
257 | "ofType": {
258 | "kind": "OBJECT",
259 | "name": "Image",
260 | "ofType": null
261 | }
262 | },
263 | "isDeprecated": false,
264 | "deprecationReason": null
265 | }
266 | ],
267 | "inputFields": null,
268 | "interfaces": [
269 | {
270 | "kind": "INTERFACE",
271 | "name": "Node",
272 | "ofType": null
273 | }
274 | ],
275 | "enumValues": null,
276 | "possibleTypes": null
277 | },
278 | {
279 | "kind": "INTERFACE",
280 | "name": "Node",
281 | "description": "An object with an ID",
282 | "fields": [
283 | {
284 | "name": "id",
285 | "description": "The id of the object.",
286 | "args": [],
287 | "type": {
288 | "kind": "NON_NULL",
289 | "name": null,
290 | "ofType": {
291 | "kind": "SCALAR",
292 | "name": "ID",
293 | "ofType": null
294 | }
295 | },
296 | "isDeprecated": false,
297 | "deprecationReason": null
298 | }
299 | ],
300 | "inputFields": null,
301 | "interfaces": null,
302 | "enumValues": null,
303 | "possibleTypes": [
304 | {
305 | "kind": "OBJECT",
306 | "name": "Product",
307 | "ofType": null
308 | },
309 | {
310 | "kind": "OBJECT",
311 | "name": "ProductList",
312 | "ofType": null
313 | },
314 | {
315 | "kind": "OBJECT",
316 | "name": "Cart",
317 | "ofType": null
318 | },
319 | {
320 | "kind": "OBJECT",
321 | "name": "CartEntry",
322 | "ofType": null
323 | },
324 | {
325 | "kind": "OBJECT",
326 | "name": "Viewer",
327 | "ofType": null
328 | }
329 | ]
330 | },
331 | {
332 | "kind": "SCALAR",
333 | "name": "String",
334 | "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.",
335 | "fields": null,
336 | "inputFields": null,
337 | "interfaces": null,
338 | "enumValues": null,
339 | "possibleTypes": null
340 | },
341 | {
342 | "kind": "SCALAR",
343 | "name": "Float",
344 | "description": "The `Float` scalar type represents signed double-precision fractional values as specified by [IEEE 754](http://en.wikipedia.org/wiki/IEEE_floating_point). ",
345 | "fields": null,
346 | "inputFields": null,
347 | "interfaces": null,
348 | "enumValues": null,
349 | "possibleTypes": null
350 | },
351 | {
352 | "kind": "SCALAR",
353 | "name": "Int",
354 | "description": "The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. ",
355 | "fields": null,
356 | "inputFields": null,
357 | "interfaces": null,
358 | "enumValues": null,
359 | "possibleTypes": null
360 | },
361 | {
362 | "kind": "OBJECT",
363 | "name": "Image",
364 | "description": "Just image",
365 | "fields": [
366 | {
367 | "name": "format",
368 | "description": "The format of image.",
369 | "args": [],
370 | "type": {
371 | "kind": "SCALAR",
372 | "name": "String",
373 | "ofType": null
374 | },
375 | "isDeprecated": false,
376 | "deprecationReason": null
377 | },
378 | {
379 | "name": "url",
380 | "description": "The url of image.",
381 | "args": [],
382 | "type": {
383 | "kind": "SCALAR",
384 | "name": "String",
385 | "ofType": null
386 | },
387 | "isDeprecated": false,
388 | "deprecationReason": null
389 | }
390 | ],
391 | "inputFields": null,
392 | "interfaces": [],
393 | "enumValues": null,
394 | "possibleTypes": null
395 | },
396 | {
397 | "kind": "OBJECT",
398 | "name": "ProductList",
399 | "description": null,
400 | "fields": [
401 | {
402 | "name": "id",
403 | "description": "The ID of an object",
404 | "args": [],
405 | "type": {
406 | "kind": "NON_NULL",
407 | "name": null,
408 | "ofType": {
409 | "kind": "SCALAR",
410 | "name": "ID",
411 | "ofType": null
412 | }
413 | },
414 | "isDeprecated": false,
415 | "deprecationReason": null
416 | },
417 | {
418 | "name": "items",
419 | "description": null,
420 | "args": [
421 | {
422 | "name": "after",
423 | "description": null,
424 | "type": {
425 | "kind": "SCALAR",
426 | "name": "String",
427 | "ofType": null
428 | },
429 | "defaultValue": null
430 | },
431 | {
432 | "name": "first",
433 | "description": null,
434 | "type": {
435 | "kind": "SCALAR",
436 | "name": "Int",
437 | "ofType": null
438 | },
439 | "defaultValue": null
440 | },
441 | {
442 | "name": "before",
443 | "description": null,
444 | "type": {
445 | "kind": "SCALAR",
446 | "name": "String",
447 | "ofType": null
448 | },
449 | "defaultValue": null
450 | },
451 | {
452 | "name": "last",
453 | "description": null,
454 | "type": {
455 | "kind": "SCALAR",
456 | "name": "Int",
457 | "ofType": null
458 | },
459 | "defaultValue": null
460 | }
461 | ],
462 | "type": {
463 | "kind": "OBJECT",
464 | "name": "ProductConnection",
465 | "ofType": null
466 | },
467 | "isDeprecated": false,
468 | "deprecationReason": null
469 | }
470 | ],
471 | "inputFields": null,
472 | "interfaces": [
473 | {
474 | "kind": "INTERFACE",
475 | "name": "Node",
476 | "ofType": null
477 | }
478 | ],
479 | "enumValues": null,
480 | "possibleTypes": null
481 | },
482 | {
483 | "kind": "OBJECT",
484 | "name": "ProductConnection",
485 | "description": "A connection to a list of items.",
486 | "fields": [
487 | {
488 | "name": "pageInfo",
489 | "description": "Information to aid in pagination.",
490 | "args": [],
491 | "type": {
492 | "kind": "NON_NULL",
493 | "name": null,
494 | "ofType": {
495 | "kind": "OBJECT",
496 | "name": "PageInfo",
497 | "ofType": null
498 | }
499 | },
500 | "isDeprecated": false,
501 | "deprecationReason": null
502 | },
503 | {
504 | "name": "edges",
505 | "description": "A list of edges.",
506 | "args": [],
507 | "type": {
508 | "kind": "LIST",
509 | "name": null,
510 | "ofType": {
511 | "kind": "OBJECT",
512 | "name": "ProductEdge",
513 | "ofType": null
514 | }
515 | },
516 | "isDeprecated": false,
517 | "deprecationReason": null
518 | },
519 | {
520 | "name": "totalNumberOfItems",
521 | "description": null,
522 | "args": [],
523 | "type": {
524 | "kind": "SCALAR",
525 | "name": "Int",
526 | "ofType": null
527 | },
528 | "isDeprecated": false,
529 | "deprecationReason": null
530 | }
531 | ],
532 | "inputFields": null,
533 | "interfaces": [],
534 | "enumValues": null,
535 | "possibleTypes": null
536 | },
537 | {
538 | "kind": "OBJECT",
539 | "name": "PageInfo",
540 | "description": "Information about pagination in a connection.",
541 | "fields": [
542 | {
543 | "name": "hasNextPage",
544 | "description": "When paginating forwards, are there more items?",
545 | "args": [],
546 | "type": {
547 | "kind": "NON_NULL",
548 | "name": null,
549 | "ofType": {
550 | "kind": "SCALAR",
551 | "name": "Boolean",
552 | "ofType": null
553 | }
554 | },
555 | "isDeprecated": false,
556 | "deprecationReason": null
557 | },
558 | {
559 | "name": "hasPreviousPage",
560 | "description": "When paginating backwards, are there more items?",
561 | "args": [],
562 | "type": {
563 | "kind": "NON_NULL",
564 | "name": null,
565 | "ofType": {
566 | "kind": "SCALAR",
567 | "name": "Boolean",
568 | "ofType": null
569 | }
570 | },
571 | "isDeprecated": false,
572 | "deprecationReason": null
573 | },
574 | {
575 | "name": "startCursor",
576 | "description": "When paginating backwards, the cursor to continue.",
577 | "args": [],
578 | "type": {
579 | "kind": "SCALAR",
580 | "name": "String",
581 | "ofType": null
582 | },
583 | "isDeprecated": false,
584 | "deprecationReason": null
585 | },
586 | {
587 | "name": "endCursor",
588 | "description": "When paginating forwards, the cursor to continue.",
589 | "args": [],
590 | "type": {
591 | "kind": "SCALAR",
592 | "name": "String",
593 | "ofType": null
594 | },
595 | "isDeprecated": false,
596 | "deprecationReason": null
597 | }
598 | ],
599 | "inputFields": null,
600 | "interfaces": [],
601 | "enumValues": null,
602 | "possibleTypes": null
603 | },
604 | {
605 | "kind": "SCALAR",
606 | "name": "Boolean",
607 | "description": "The `Boolean` scalar type represents `true` or `false`.",
608 | "fields": null,
609 | "inputFields": null,
610 | "interfaces": null,
611 | "enumValues": null,
612 | "possibleTypes": null
613 | },
614 | {
615 | "kind": "OBJECT",
616 | "name": "ProductEdge",
617 | "description": "An edge in a connection.",
618 | "fields": [
619 | {
620 | "name": "node",
621 | "description": "The item at the end of the edge",
622 | "args": [],
623 | "type": {
624 | "kind": "OBJECT",
625 | "name": "Product",
626 | "ofType": null
627 | },
628 | "isDeprecated": false,
629 | "deprecationReason": null
630 | },
631 | {
632 | "name": "cursor",
633 | "description": "A cursor for use in pagination",
634 | "args": [],
635 | "type": {
636 | "kind": "NON_NULL",
637 | "name": null,
638 | "ofType": {
639 | "kind": "SCALAR",
640 | "name": "String",
641 | "ofType": null
642 | }
643 | },
644 | "isDeprecated": false,
645 | "deprecationReason": null
646 | }
647 | ],
648 | "inputFields": null,
649 | "interfaces": [],
650 | "enumValues": null,
651 | "possibleTypes": null
652 | },
653 | {
654 | "kind": "OBJECT",
655 | "name": "Cart",
656 | "description": null,
657 | "fields": [
658 | {
659 | "name": "id",
660 | "description": "The ID of an object",
661 | "args": [],
662 | "type": {
663 | "kind": "NON_NULL",
664 | "name": null,
665 | "ofType": {
666 | "kind": "SCALAR",
667 | "name": "ID",
668 | "ofType": null
669 | }
670 | },
671 | "isDeprecated": false,
672 | "deprecationReason": null
673 | },
674 | {
675 | "name": "entries",
676 | "description": null,
677 | "args": [
678 | {
679 | "name": "after",
680 | "description": null,
681 | "type": {
682 | "kind": "SCALAR",
683 | "name": "String",
684 | "ofType": null
685 | },
686 | "defaultValue": null
687 | },
688 | {
689 | "name": "first",
690 | "description": null,
691 | "type": {
692 | "kind": "SCALAR",
693 | "name": "Int",
694 | "ofType": null
695 | },
696 | "defaultValue": null
697 | },
698 | {
699 | "name": "before",
700 | "description": null,
701 | "type": {
702 | "kind": "SCALAR",
703 | "name": "String",
704 | "ofType": null
705 | },
706 | "defaultValue": null
707 | },
708 | {
709 | "name": "last",
710 | "description": null,
711 | "type": {
712 | "kind": "SCALAR",
713 | "name": "Int",
714 | "ofType": null
715 | },
716 | "defaultValue": null
717 | }
718 | ],
719 | "type": {
720 | "kind": "OBJECT",
721 | "name": "CartEntryConnection",
722 | "ofType": null
723 | },
724 | "isDeprecated": false,
725 | "deprecationReason": null
726 | },
727 | {
728 | "name": "totalNumberOfItems",
729 | "description": null,
730 | "args": [],
731 | "type": {
732 | "kind": "SCALAR",
733 | "name": "Int",
734 | "ofType": null
735 | },
736 | "isDeprecated": false,
737 | "deprecationReason": null
738 | },
739 | {
740 | "name": "totalPriceOfItems",
741 | "description": null,
742 | "args": [],
743 | "type": {
744 | "kind": "SCALAR",
745 | "name": "Float",
746 | "ofType": null
747 | },
748 | "isDeprecated": false,
749 | "deprecationReason": null
750 | }
751 | ],
752 | "inputFields": null,
753 | "interfaces": [
754 | {
755 | "kind": "INTERFACE",
756 | "name": "Node",
757 | "ofType": null
758 | }
759 | ],
760 | "enumValues": null,
761 | "possibleTypes": null
762 | },
763 | {
764 | "kind": "OBJECT",
765 | "name": "CartEntryConnection",
766 | "description": "A connection to a list of items.",
767 | "fields": [
768 | {
769 | "name": "pageInfo",
770 | "description": "Information to aid in pagination.",
771 | "args": [],
772 | "type": {
773 | "kind": "NON_NULL",
774 | "name": null,
775 | "ofType": {
776 | "kind": "OBJECT",
777 | "name": "PageInfo",
778 | "ofType": null
779 | }
780 | },
781 | "isDeprecated": false,
782 | "deprecationReason": null
783 | },
784 | {
785 | "name": "edges",
786 | "description": "A list of edges.",
787 | "args": [],
788 | "type": {
789 | "kind": "LIST",
790 | "name": null,
791 | "ofType": {
792 | "kind": "OBJECT",
793 | "name": "CartEntryEdge",
794 | "ofType": null
795 | }
796 | },
797 | "isDeprecated": false,
798 | "deprecationReason": null
799 | }
800 | ],
801 | "inputFields": null,
802 | "interfaces": [],
803 | "enumValues": null,
804 | "possibleTypes": null
805 | },
806 | {
807 | "kind": "OBJECT",
808 | "name": "CartEntryEdge",
809 | "description": "An edge in a connection.",
810 | "fields": [
811 | {
812 | "name": "node",
813 | "description": "The item at the end of the edge",
814 | "args": [],
815 | "type": {
816 | "kind": "OBJECT",
817 | "name": "CartEntry",
818 | "ofType": null
819 | },
820 | "isDeprecated": false,
821 | "deprecationReason": null
822 | },
823 | {
824 | "name": "cursor",
825 | "description": "A cursor for use in pagination",
826 | "args": [],
827 | "type": {
828 | "kind": "NON_NULL",
829 | "name": null,
830 | "ofType": {
831 | "kind": "SCALAR",
832 | "name": "String",
833 | "ofType": null
834 | }
835 | },
836 | "isDeprecated": false,
837 | "deprecationReason": null
838 | }
839 | ],
840 | "inputFields": null,
841 | "interfaces": [],
842 | "enumValues": null,
843 | "possibleTypes": null
844 | },
845 | {
846 | "kind": "OBJECT",
847 | "name": "CartEntry",
848 | "description": null,
849 | "fields": [
850 | {
851 | "name": "id",
852 | "description": "The ID of an object",
853 | "args": [],
854 | "type": {
855 | "kind": "NON_NULL",
856 | "name": null,
857 | "ofType": {
858 | "kind": "SCALAR",
859 | "name": "ID",
860 | "ofType": null
861 | }
862 | },
863 | "isDeprecated": false,
864 | "deprecationReason": null
865 | },
866 | {
867 | "name": "product",
868 | "description": null,
869 | "args": [],
870 | "type": {
871 | "kind": "OBJECT",
872 | "name": "Product",
873 | "ofType": null
874 | },
875 | "isDeprecated": false,
876 | "deprecationReason": null
877 | },
878 | {
879 | "name": "quantity",
880 | "description": null,
881 | "args": [],
882 | "type": {
883 | "kind": "SCALAR",
884 | "name": "Float",
885 | "ofType": null
886 | },
887 | "isDeprecated": false,
888 | "deprecationReason": null
889 | },
890 | {
891 | "name": "price",
892 | "description": null,
893 | "args": [],
894 | "type": {
895 | "kind": "SCALAR",
896 | "name": "Float",
897 | "ofType": null
898 | },
899 | "isDeprecated": false,
900 | "deprecationReason": null
901 | },
902 | {
903 | "name": "totalPrice",
904 | "description": null,
905 | "args": [],
906 | "type": {
907 | "kind": "SCALAR",
908 | "name": "Float",
909 | "ofType": null
910 | },
911 | "isDeprecated": false,
912 | "deprecationReason": null
913 | }
914 | ],
915 | "inputFields": null,
916 | "interfaces": [
917 | {
918 | "kind": "INTERFACE",
919 | "name": "Node",
920 | "ofType": null
921 | }
922 | ],
923 | "enumValues": null,
924 | "possibleTypes": null
925 | },
926 | {
927 | "kind": "OBJECT",
928 | "name": "Viewer",
929 | "description": null,
930 | "fields": [
931 | {
932 | "name": "id",
933 | "description": "The ID of an object",
934 | "args": [],
935 | "type": {
936 | "kind": "NON_NULL",
937 | "name": null,
938 | "ofType": {
939 | "kind": "SCALAR",
940 | "name": "ID",
941 | "ofType": null
942 | }
943 | },
944 | "isDeprecated": false,
945 | "deprecationReason": null
946 | },
947 | {
948 | "name": "name",
949 | "description": null,
950 | "args": [],
951 | "type": {
952 | "kind": "SCALAR",
953 | "name": "String",
954 | "ofType": null
955 | },
956 | "isDeprecated": false,
957 | "deprecationReason": null
958 | },
959 | {
960 | "name": "cart",
961 | "description": null,
962 | "args": [],
963 | "type": {
964 | "kind": "OBJECT",
965 | "name": "Cart",
966 | "ofType": null
967 | },
968 | "isDeprecated": false,
969 | "deprecationReason": null
970 | },
971 | {
972 | "name": "products",
973 | "description": null,
974 | "args": [
975 | {
976 | "name": "after",
977 | "description": null,
978 | "type": {
979 | "kind": "SCALAR",
980 | "name": "String",
981 | "ofType": null
982 | },
983 | "defaultValue": null
984 | },
985 | {
986 | "name": "first",
987 | "description": null,
988 | "type": {
989 | "kind": "SCALAR",
990 | "name": "Int",
991 | "ofType": null
992 | },
993 | "defaultValue": null
994 | },
995 | {
996 | "name": "before",
997 | "description": null,
998 | "type": {
999 | "kind": "SCALAR",
1000 | "name": "String",
1001 | "ofType": null
1002 | },
1003 | "defaultValue": null
1004 | },
1005 | {
1006 | "name": "last",
1007 | "description": null,
1008 | "type": {
1009 | "kind": "SCALAR",
1010 | "name": "Int",
1011 | "ofType": null
1012 | },
1013 | "defaultValue": null
1014 | }
1015 | ],
1016 | "type": {
1017 | "kind": "OBJECT",
1018 | "name": "ProductConnection",
1019 | "ofType": null
1020 | },
1021 | "isDeprecated": false,
1022 | "deprecationReason": null
1023 | }
1024 | ],
1025 | "inputFields": null,
1026 | "interfaces": [
1027 | {
1028 | "kind": "INTERFACE",
1029 | "name": "Node",
1030 | "ofType": null
1031 | }
1032 | ],
1033 | "enumValues": null,
1034 | "possibleTypes": null
1035 | },
1036 | {
1037 | "kind": "OBJECT",
1038 | "name": "Mutation",
1039 | "description": null,
1040 | "fields": [
1041 | {
1042 | "name": "addToCart",
1043 | "description": null,
1044 | "args": [
1045 | {
1046 | "name": "input",
1047 | "description": null,
1048 | "type": {
1049 | "kind": "NON_NULL",
1050 | "name": null,
1051 | "ofType": {
1052 | "kind": "INPUT_OBJECT",
1053 | "name": "AddToCartInput",
1054 | "ofType": null
1055 | }
1056 | },
1057 | "defaultValue": null
1058 | }
1059 | ],
1060 | "type": {
1061 | "kind": "OBJECT",
1062 | "name": "AddToCartPayload",
1063 | "ofType": null
1064 | },
1065 | "isDeprecated": false,
1066 | "deprecationReason": null
1067 | },
1068 | {
1069 | "name": "removeFromCart",
1070 | "description": null,
1071 | "args": [
1072 | {
1073 | "name": "input",
1074 | "description": null,
1075 | "type": {
1076 | "kind": "NON_NULL",
1077 | "name": null,
1078 | "ofType": {
1079 | "kind": "INPUT_OBJECT",
1080 | "name": "RemoveFromCartInput",
1081 | "ofType": null
1082 | }
1083 | },
1084 | "defaultValue": null
1085 | }
1086 | ],
1087 | "type": {
1088 | "kind": "OBJECT",
1089 | "name": "RemoveFromCartPayload",
1090 | "ofType": null
1091 | },
1092 | "isDeprecated": false,
1093 | "deprecationReason": null
1094 | }
1095 | ],
1096 | "inputFields": null,
1097 | "interfaces": [],
1098 | "enumValues": null,
1099 | "possibleTypes": null
1100 | },
1101 | {
1102 | "kind": "INPUT_OBJECT",
1103 | "name": "AddToCartInput",
1104 | "description": null,
1105 | "fields": null,
1106 | "inputFields": [
1107 | {
1108 | "name": "id",
1109 | "description": null,
1110 | "type": {
1111 | "kind": "NON_NULL",
1112 | "name": null,
1113 | "ofType": {
1114 | "kind": "SCALAR",
1115 | "name": "ID",
1116 | "ofType": null
1117 | }
1118 | },
1119 | "defaultValue": null
1120 | },
1121 | {
1122 | "name": "quantity",
1123 | "description": null,
1124 | "type": {
1125 | "kind": "SCALAR",
1126 | "name": "Int",
1127 | "ofType": null
1128 | },
1129 | "defaultValue": null
1130 | },
1131 | {
1132 | "name": "clientMutationId",
1133 | "description": null,
1134 | "type": {
1135 | "kind": "SCALAR",
1136 | "name": "String",
1137 | "ofType": null
1138 | },
1139 | "defaultValue": null
1140 | }
1141 | ],
1142 | "interfaces": null,
1143 | "enumValues": null,
1144 | "possibleTypes": null
1145 | },
1146 | {
1147 | "kind": "OBJECT",
1148 | "name": "AddToCartPayload",
1149 | "description": null,
1150 | "fields": [
1151 | {
1152 | "name": "cartEntryEdge",
1153 | "description": null,
1154 | "args": [],
1155 | "type": {
1156 | "kind": "OBJECT",
1157 | "name": "CartEntryEdge",
1158 | "ofType": null
1159 | },
1160 | "isDeprecated": false,
1161 | "deprecationReason": null
1162 | },
1163 | {
1164 | "name": "cartEntry",
1165 | "description": null,
1166 | "args": [],
1167 | "type": {
1168 | "kind": "OBJECT",
1169 | "name": "CartEntry",
1170 | "ofType": null
1171 | },
1172 | "isDeprecated": false,
1173 | "deprecationReason": null
1174 | },
1175 | {
1176 | "name": "cart",
1177 | "description": null,
1178 | "args": [],
1179 | "type": {
1180 | "kind": "OBJECT",
1181 | "name": "Cart",
1182 | "ofType": null
1183 | },
1184 | "isDeprecated": false,
1185 | "deprecationReason": null
1186 | },
1187 | {
1188 | "name": "clientMutationId",
1189 | "description": null,
1190 | "args": [],
1191 | "type": {
1192 | "kind": "SCALAR",
1193 | "name": "String",
1194 | "ofType": null
1195 | },
1196 | "isDeprecated": false,
1197 | "deprecationReason": null
1198 | }
1199 | ],
1200 | "inputFields": null,
1201 | "interfaces": [],
1202 | "enumValues": null,
1203 | "possibleTypes": null
1204 | },
1205 | {
1206 | "kind": "INPUT_OBJECT",
1207 | "name": "RemoveFromCartInput",
1208 | "description": null,
1209 | "fields": null,
1210 | "inputFields": [
1211 | {
1212 | "name": "id",
1213 | "description": null,
1214 | "type": {
1215 | "kind": "NON_NULL",
1216 | "name": null,
1217 | "ofType": {
1218 | "kind": "SCALAR",
1219 | "name": "ID",
1220 | "ofType": null
1221 | }
1222 | },
1223 | "defaultValue": null
1224 | },
1225 | {
1226 | "name": "clientMutationId",
1227 | "description": null,
1228 | "type": {
1229 | "kind": "SCALAR",
1230 | "name": "String",
1231 | "ofType": null
1232 | },
1233 | "defaultValue": null
1234 | }
1235 | ],
1236 | "interfaces": null,
1237 | "enumValues": null,
1238 | "possibleTypes": null
1239 | },
1240 | {
1241 | "kind": "OBJECT",
1242 | "name": "RemoveFromCartPayload",
1243 | "description": null,
1244 | "fields": [
1245 | {
1246 | "name": "deletedCartEntryId",
1247 | "description": null,
1248 | "args": [],
1249 | "type": {
1250 | "kind": "SCALAR",
1251 | "name": "ID",
1252 | "ofType": null
1253 | },
1254 | "isDeprecated": false,
1255 | "deprecationReason": null
1256 | },
1257 | {
1258 | "name": "cart",
1259 | "description": null,
1260 | "args": [],
1261 | "type": {
1262 | "kind": "OBJECT",
1263 | "name": "Cart",
1264 | "ofType": null
1265 | },
1266 | "isDeprecated": false,
1267 | "deprecationReason": null
1268 | },
1269 | {
1270 | "name": "clientMutationId",
1271 | "description": null,
1272 | "args": [],
1273 | "type": {
1274 | "kind": "SCALAR",
1275 | "name": "String",
1276 | "ofType": null
1277 | },
1278 | "isDeprecated": false,
1279 | "deprecationReason": null
1280 | }
1281 | ],
1282 | "inputFields": null,
1283 | "interfaces": [],
1284 | "enumValues": null,
1285 | "possibleTypes": null
1286 | },
1287 | {
1288 | "kind": "OBJECT",
1289 | "name": "__Schema",
1290 | "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.",
1291 | "fields": [
1292 | {
1293 | "name": "types",
1294 | "description": "A list of all types supported by this server.",
1295 | "args": [],
1296 | "type": {
1297 | "kind": "NON_NULL",
1298 | "name": null,
1299 | "ofType": {
1300 | "kind": "LIST",
1301 | "name": null,
1302 | "ofType": {
1303 | "kind": "NON_NULL",
1304 | "name": null,
1305 | "ofType": {
1306 | "kind": "OBJECT",
1307 | "name": "__Type",
1308 | "ofType": null
1309 | }
1310 | }
1311 | }
1312 | },
1313 | "isDeprecated": false,
1314 | "deprecationReason": null
1315 | },
1316 | {
1317 | "name": "queryType",
1318 | "description": "The type that query operations will be rooted at.",
1319 | "args": [],
1320 | "type": {
1321 | "kind": "NON_NULL",
1322 | "name": null,
1323 | "ofType": {
1324 | "kind": "OBJECT",
1325 | "name": "__Type",
1326 | "ofType": null
1327 | }
1328 | },
1329 | "isDeprecated": false,
1330 | "deprecationReason": null
1331 | },
1332 | {
1333 | "name": "mutationType",
1334 | "description": "If this server supports mutation, the type that mutation operations will be rooted at.",
1335 | "args": [],
1336 | "type": {
1337 | "kind": "OBJECT",
1338 | "name": "__Type",
1339 | "ofType": null
1340 | },
1341 | "isDeprecated": false,
1342 | "deprecationReason": null
1343 | },
1344 | {
1345 | "name": "subscriptionType",
1346 | "description": "If this server support subscription, the type that subscription operations will be rooted at.",
1347 | "args": [],
1348 | "type": {
1349 | "kind": "OBJECT",
1350 | "name": "__Type",
1351 | "ofType": null
1352 | },
1353 | "isDeprecated": false,
1354 | "deprecationReason": null
1355 | },
1356 | {
1357 | "name": "directives",
1358 | "description": "A list of all directives supported by this server.",
1359 | "args": [],
1360 | "type": {
1361 | "kind": "NON_NULL",
1362 | "name": null,
1363 | "ofType": {
1364 | "kind": "LIST",
1365 | "name": null,
1366 | "ofType": {
1367 | "kind": "NON_NULL",
1368 | "name": null,
1369 | "ofType": {
1370 | "kind": "OBJECT",
1371 | "name": "__Directive",
1372 | "ofType": null
1373 | }
1374 | }
1375 | }
1376 | },
1377 | "isDeprecated": false,
1378 | "deprecationReason": null
1379 | }
1380 | ],
1381 | "inputFields": null,
1382 | "interfaces": [],
1383 | "enumValues": null,
1384 | "possibleTypes": null
1385 | },
1386 | {
1387 | "kind": "OBJECT",
1388 | "name": "__Type",
1389 | "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.",
1390 | "fields": [
1391 | {
1392 | "name": "kind",
1393 | "description": null,
1394 | "args": [],
1395 | "type": {
1396 | "kind": "NON_NULL",
1397 | "name": null,
1398 | "ofType": {
1399 | "kind": "ENUM",
1400 | "name": "__TypeKind",
1401 | "ofType": null
1402 | }
1403 | },
1404 | "isDeprecated": false,
1405 | "deprecationReason": null
1406 | },
1407 | {
1408 | "name": "name",
1409 | "description": null,
1410 | "args": [],
1411 | "type": {
1412 | "kind": "SCALAR",
1413 | "name": "String",
1414 | "ofType": null
1415 | },
1416 | "isDeprecated": false,
1417 | "deprecationReason": null
1418 | },
1419 | {
1420 | "name": "description",
1421 | "description": null,
1422 | "args": [],
1423 | "type": {
1424 | "kind": "SCALAR",
1425 | "name": "String",
1426 | "ofType": null
1427 | },
1428 | "isDeprecated": false,
1429 | "deprecationReason": null
1430 | },
1431 | {
1432 | "name": "fields",
1433 | "description": null,
1434 | "args": [
1435 | {
1436 | "name": "includeDeprecated",
1437 | "description": null,
1438 | "type": {
1439 | "kind": "SCALAR",
1440 | "name": "Boolean",
1441 | "ofType": null
1442 | },
1443 | "defaultValue": "false"
1444 | }
1445 | ],
1446 | "type": {
1447 | "kind": "LIST",
1448 | "name": null,
1449 | "ofType": {
1450 | "kind": "NON_NULL",
1451 | "name": null,
1452 | "ofType": {
1453 | "kind": "OBJECT",
1454 | "name": "__Field",
1455 | "ofType": null
1456 | }
1457 | }
1458 | },
1459 | "isDeprecated": false,
1460 | "deprecationReason": null
1461 | },
1462 | {
1463 | "name": "interfaces",
1464 | "description": null,
1465 | "args": [],
1466 | "type": {
1467 | "kind": "LIST",
1468 | "name": null,
1469 | "ofType": {
1470 | "kind": "NON_NULL",
1471 | "name": null,
1472 | "ofType": {
1473 | "kind": "OBJECT",
1474 | "name": "__Type",
1475 | "ofType": null
1476 | }
1477 | }
1478 | },
1479 | "isDeprecated": false,
1480 | "deprecationReason": null
1481 | },
1482 | {
1483 | "name": "possibleTypes",
1484 | "description": null,
1485 | "args": [],
1486 | "type": {
1487 | "kind": "LIST",
1488 | "name": null,
1489 | "ofType": {
1490 | "kind": "NON_NULL",
1491 | "name": null,
1492 | "ofType": {
1493 | "kind": "OBJECT",
1494 | "name": "__Type",
1495 | "ofType": null
1496 | }
1497 | }
1498 | },
1499 | "isDeprecated": false,
1500 | "deprecationReason": null
1501 | },
1502 | {
1503 | "name": "enumValues",
1504 | "description": null,
1505 | "args": [
1506 | {
1507 | "name": "includeDeprecated",
1508 | "description": null,
1509 | "type": {
1510 | "kind": "SCALAR",
1511 | "name": "Boolean",
1512 | "ofType": null
1513 | },
1514 | "defaultValue": "false"
1515 | }
1516 | ],
1517 | "type": {
1518 | "kind": "LIST",
1519 | "name": null,
1520 | "ofType": {
1521 | "kind": "NON_NULL",
1522 | "name": null,
1523 | "ofType": {
1524 | "kind": "OBJECT",
1525 | "name": "__EnumValue",
1526 | "ofType": null
1527 | }
1528 | }
1529 | },
1530 | "isDeprecated": false,
1531 | "deprecationReason": null
1532 | },
1533 | {
1534 | "name": "inputFields",
1535 | "description": null,
1536 | "args": [],
1537 | "type": {
1538 | "kind": "LIST",
1539 | "name": null,
1540 | "ofType": {
1541 | "kind": "NON_NULL",
1542 | "name": null,
1543 | "ofType": {
1544 | "kind": "OBJECT",
1545 | "name": "__InputValue",
1546 | "ofType": null
1547 | }
1548 | }
1549 | },
1550 | "isDeprecated": false,
1551 | "deprecationReason": null
1552 | },
1553 | {
1554 | "name": "ofType",
1555 | "description": null,
1556 | "args": [],
1557 | "type": {
1558 | "kind": "OBJECT",
1559 | "name": "__Type",
1560 | "ofType": null
1561 | },
1562 | "isDeprecated": false,
1563 | "deprecationReason": null
1564 | }
1565 | ],
1566 | "inputFields": null,
1567 | "interfaces": [],
1568 | "enumValues": null,
1569 | "possibleTypes": null
1570 | },
1571 | {
1572 | "kind": "ENUM",
1573 | "name": "__TypeKind",
1574 | "description": "An enum describing what kind of type a given `__Type` is.",
1575 | "fields": null,
1576 | "inputFields": null,
1577 | "interfaces": null,
1578 | "enumValues": [
1579 | {
1580 | "name": "SCALAR",
1581 | "description": "Indicates this type is a scalar.",
1582 | "isDeprecated": false,
1583 | "deprecationReason": null
1584 | },
1585 | {
1586 | "name": "OBJECT",
1587 | "description": "Indicates this type is an object. `fields` and `interfaces` are valid fields.",
1588 | "isDeprecated": false,
1589 | "deprecationReason": null
1590 | },
1591 | {
1592 | "name": "INTERFACE",
1593 | "description": "Indicates this type is an interface. `fields` and `possibleTypes` are valid fields.",
1594 | "isDeprecated": false,
1595 | "deprecationReason": null
1596 | },
1597 | {
1598 | "name": "UNION",
1599 | "description": "Indicates this type is a union. `possibleTypes` is a valid field.",
1600 | "isDeprecated": false,
1601 | "deprecationReason": null
1602 | },
1603 | {
1604 | "name": "ENUM",
1605 | "description": "Indicates this type is an enum. `enumValues` is a valid field.",
1606 | "isDeprecated": false,
1607 | "deprecationReason": null
1608 | },
1609 | {
1610 | "name": "INPUT_OBJECT",
1611 | "description": "Indicates this type is an input object. `inputFields` is a valid field.",
1612 | "isDeprecated": false,
1613 | "deprecationReason": null
1614 | },
1615 | {
1616 | "name": "LIST",
1617 | "description": "Indicates this type is a list. `ofType` is a valid field.",
1618 | "isDeprecated": false,
1619 | "deprecationReason": null
1620 | },
1621 | {
1622 | "name": "NON_NULL",
1623 | "description": "Indicates this type is a non-null. `ofType` is a valid field.",
1624 | "isDeprecated": false,
1625 | "deprecationReason": null
1626 | }
1627 | ],
1628 | "possibleTypes": null
1629 | },
1630 | {
1631 | "kind": "OBJECT",
1632 | "name": "__Field",
1633 | "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.",
1634 | "fields": [
1635 | {
1636 | "name": "name",
1637 | "description": null,
1638 | "args": [],
1639 | "type": {
1640 | "kind": "NON_NULL",
1641 | "name": null,
1642 | "ofType": {
1643 | "kind": "SCALAR",
1644 | "name": "String",
1645 | "ofType": null
1646 | }
1647 | },
1648 | "isDeprecated": false,
1649 | "deprecationReason": null
1650 | },
1651 | {
1652 | "name": "description",
1653 | "description": null,
1654 | "args": [],
1655 | "type": {
1656 | "kind": "SCALAR",
1657 | "name": "String",
1658 | "ofType": null
1659 | },
1660 | "isDeprecated": false,
1661 | "deprecationReason": null
1662 | },
1663 | {
1664 | "name": "args",
1665 | "description": null,
1666 | "args": [],
1667 | "type": {
1668 | "kind": "NON_NULL",
1669 | "name": null,
1670 | "ofType": {
1671 | "kind": "LIST",
1672 | "name": null,
1673 | "ofType": {
1674 | "kind": "NON_NULL",
1675 | "name": null,
1676 | "ofType": {
1677 | "kind": "OBJECT",
1678 | "name": "__InputValue",
1679 | "ofType": null
1680 | }
1681 | }
1682 | }
1683 | },
1684 | "isDeprecated": false,
1685 | "deprecationReason": null
1686 | },
1687 | {
1688 | "name": "type",
1689 | "description": null,
1690 | "args": [],
1691 | "type": {
1692 | "kind": "NON_NULL",
1693 | "name": null,
1694 | "ofType": {
1695 | "kind": "OBJECT",
1696 | "name": "__Type",
1697 | "ofType": null
1698 | }
1699 | },
1700 | "isDeprecated": false,
1701 | "deprecationReason": null
1702 | },
1703 | {
1704 | "name": "isDeprecated",
1705 | "description": null,
1706 | "args": [],
1707 | "type": {
1708 | "kind": "NON_NULL",
1709 | "name": null,
1710 | "ofType": {
1711 | "kind": "SCALAR",
1712 | "name": "Boolean",
1713 | "ofType": null
1714 | }
1715 | },
1716 | "isDeprecated": false,
1717 | "deprecationReason": null
1718 | },
1719 | {
1720 | "name": "deprecationReason",
1721 | "description": null,
1722 | "args": [],
1723 | "type": {
1724 | "kind": "SCALAR",
1725 | "name": "String",
1726 | "ofType": null
1727 | },
1728 | "isDeprecated": false,
1729 | "deprecationReason": null
1730 | }
1731 | ],
1732 | "inputFields": null,
1733 | "interfaces": [],
1734 | "enumValues": null,
1735 | "possibleTypes": null
1736 | },
1737 | {
1738 | "kind": "OBJECT",
1739 | "name": "__InputValue",
1740 | "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.",
1741 | "fields": [
1742 | {
1743 | "name": "name",
1744 | "description": null,
1745 | "args": [],
1746 | "type": {
1747 | "kind": "NON_NULL",
1748 | "name": null,
1749 | "ofType": {
1750 | "kind": "SCALAR",
1751 | "name": "String",
1752 | "ofType": null
1753 | }
1754 | },
1755 | "isDeprecated": false,
1756 | "deprecationReason": null
1757 | },
1758 | {
1759 | "name": "description",
1760 | "description": null,
1761 | "args": [],
1762 | "type": {
1763 | "kind": "SCALAR",
1764 | "name": "String",
1765 | "ofType": null
1766 | },
1767 | "isDeprecated": false,
1768 | "deprecationReason": null
1769 | },
1770 | {
1771 | "name": "type",
1772 | "description": null,
1773 | "args": [],
1774 | "type": {
1775 | "kind": "NON_NULL",
1776 | "name": null,
1777 | "ofType": {
1778 | "kind": "OBJECT",
1779 | "name": "__Type",
1780 | "ofType": null
1781 | }
1782 | },
1783 | "isDeprecated": false,
1784 | "deprecationReason": null
1785 | },
1786 | {
1787 | "name": "defaultValue",
1788 | "description": "A GraphQL-formatted string representing the default value for this input value.",
1789 | "args": [],
1790 | "type": {
1791 | "kind": "SCALAR",
1792 | "name": "String",
1793 | "ofType": null
1794 | },
1795 | "isDeprecated": false,
1796 | "deprecationReason": null
1797 | }
1798 | ],
1799 | "inputFields": null,
1800 | "interfaces": [],
1801 | "enumValues": null,
1802 | "possibleTypes": null
1803 | },
1804 | {
1805 | "kind": "OBJECT",
1806 | "name": "__EnumValue",
1807 | "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.",
1808 | "fields": [
1809 | {
1810 | "name": "name",
1811 | "description": null,
1812 | "args": [],
1813 | "type": {
1814 | "kind": "NON_NULL",
1815 | "name": null,
1816 | "ofType": {
1817 | "kind": "SCALAR",
1818 | "name": "String",
1819 | "ofType": null
1820 | }
1821 | },
1822 | "isDeprecated": false,
1823 | "deprecationReason": null
1824 | },
1825 | {
1826 | "name": "description",
1827 | "description": null,
1828 | "args": [],
1829 | "type": {
1830 | "kind": "SCALAR",
1831 | "name": "String",
1832 | "ofType": null
1833 | },
1834 | "isDeprecated": false,
1835 | "deprecationReason": null
1836 | },
1837 | {
1838 | "name": "isDeprecated",
1839 | "description": null,
1840 | "args": [],
1841 | "type": {
1842 | "kind": "NON_NULL",
1843 | "name": null,
1844 | "ofType": {
1845 | "kind": "SCALAR",
1846 | "name": "Boolean",
1847 | "ofType": null
1848 | }
1849 | },
1850 | "isDeprecated": false,
1851 | "deprecationReason": null
1852 | },
1853 | {
1854 | "name": "deprecationReason",
1855 | "description": null,
1856 | "args": [],
1857 | "type": {
1858 | "kind": "SCALAR",
1859 | "name": "String",
1860 | "ofType": null
1861 | },
1862 | "isDeprecated": false,
1863 | "deprecationReason": null
1864 | }
1865 | ],
1866 | "inputFields": null,
1867 | "interfaces": [],
1868 | "enumValues": null,
1869 | "possibleTypes": null
1870 | },
1871 | {
1872 | "kind": "OBJECT",
1873 | "name": "__Directive",
1874 | "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.",
1875 | "fields": [
1876 | {
1877 | "name": "name",
1878 | "description": null,
1879 | "args": [],
1880 | "type": {
1881 | "kind": "NON_NULL",
1882 | "name": null,
1883 | "ofType": {
1884 | "kind": "SCALAR",
1885 | "name": "String",
1886 | "ofType": null
1887 | }
1888 | },
1889 | "isDeprecated": false,
1890 | "deprecationReason": null
1891 | },
1892 | {
1893 | "name": "description",
1894 | "description": null,
1895 | "args": [],
1896 | "type": {
1897 | "kind": "SCALAR",
1898 | "name": "String",
1899 | "ofType": null
1900 | },
1901 | "isDeprecated": false,
1902 | "deprecationReason": null
1903 | },
1904 | {
1905 | "name": "locations",
1906 | "description": null,
1907 | "args": [],
1908 | "type": {
1909 | "kind": "NON_NULL",
1910 | "name": null,
1911 | "ofType": {
1912 | "kind": "LIST",
1913 | "name": null,
1914 | "ofType": {
1915 | "kind": "NON_NULL",
1916 | "name": null,
1917 | "ofType": {
1918 | "kind": "ENUM",
1919 | "name": "__DirectiveLocation",
1920 | "ofType": null
1921 | }
1922 | }
1923 | }
1924 | },
1925 | "isDeprecated": false,
1926 | "deprecationReason": null
1927 | },
1928 | {
1929 | "name": "args",
1930 | "description": null,
1931 | "args": [],
1932 | "type": {
1933 | "kind": "NON_NULL",
1934 | "name": null,
1935 | "ofType": {
1936 | "kind": "LIST",
1937 | "name": null,
1938 | "ofType": {
1939 | "kind": "NON_NULL",
1940 | "name": null,
1941 | "ofType": {
1942 | "kind": "OBJECT",
1943 | "name": "__InputValue",
1944 | "ofType": null
1945 | }
1946 | }
1947 | }
1948 | },
1949 | "isDeprecated": false,
1950 | "deprecationReason": null
1951 | },
1952 | {
1953 | "name": "onOperation",
1954 | "description": null,
1955 | "args": [],
1956 | "type": {
1957 | "kind": "NON_NULL",
1958 | "name": null,
1959 | "ofType": {
1960 | "kind": "SCALAR",
1961 | "name": "Boolean",
1962 | "ofType": null
1963 | }
1964 | },
1965 | "isDeprecated": true,
1966 | "deprecationReason": "Use `locations`."
1967 | },
1968 | {
1969 | "name": "onFragment",
1970 | "description": null,
1971 | "args": [],
1972 | "type": {
1973 | "kind": "NON_NULL",
1974 | "name": null,
1975 | "ofType": {
1976 | "kind": "SCALAR",
1977 | "name": "Boolean",
1978 | "ofType": null
1979 | }
1980 | },
1981 | "isDeprecated": true,
1982 | "deprecationReason": "Use `locations`."
1983 | },
1984 | {
1985 | "name": "onField",
1986 | "description": null,
1987 | "args": [],
1988 | "type": {
1989 | "kind": "NON_NULL",
1990 | "name": null,
1991 | "ofType": {
1992 | "kind": "SCALAR",
1993 | "name": "Boolean",
1994 | "ofType": null
1995 | }
1996 | },
1997 | "isDeprecated": true,
1998 | "deprecationReason": "Use `locations`."
1999 | }
2000 | ],
2001 | "inputFields": null,
2002 | "interfaces": [],
2003 | "enumValues": null,
2004 | "possibleTypes": null
2005 | },
2006 | {
2007 | "kind": "ENUM",
2008 | "name": "__DirectiveLocation",
2009 | "description": "A Directive can be adjacent to many parts of the GraphQL language, a __DirectiveLocation describes one such possible adjacencies.",
2010 | "fields": null,
2011 | "inputFields": null,
2012 | "interfaces": null,
2013 | "enumValues": [
2014 | {
2015 | "name": "QUERY",
2016 | "description": "Location adjacent to a query operation.",
2017 | "isDeprecated": false,
2018 | "deprecationReason": null
2019 | },
2020 | {
2021 | "name": "MUTATION",
2022 | "description": "Location adjacent to a mutation operation.",
2023 | "isDeprecated": false,
2024 | "deprecationReason": null
2025 | },
2026 | {
2027 | "name": "SUBSCRIPTION",
2028 | "description": "Location adjacent to a subscription operation.",
2029 | "isDeprecated": false,
2030 | "deprecationReason": null
2031 | },
2032 | {
2033 | "name": "FIELD",
2034 | "description": "Location adjacent to a field.",
2035 | "isDeprecated": false,
2036 | "deprecationReason": null
2037 | },
2038 | {
2039 | "name": "FRAGMENT_DEFINITION",
2040 | "description": "Location adjacent to a fragment definition.",
2041 | "isDeprecated": false,
2042 | "deprecationReason": null
2043 | },
2044 | {
2045 | "name": "FRAGMENT_SPREAD",
2046 | "description": "Location adjacent to a fragment spread.",
2047 | "isDeprecated": false,
2048 | "deprecationReason": null
2049 | },
2050 | {
2051 | "name": "INLINE_FRAGMENT",
2052 | "description": "Location adjacent to an inline fragment.",
2053 | "isDeprecated": false,
2054 | "deprecationReason": null
2055 | },
2056 | {
2057 | "name": "SCHEMA",
2058 | "description": "Location adjacent to a schema definition.",
2059 | "isDeprecated": false,
2060 | "deprecationReason": null
2061 | },
2062 | {
2063 | "name": "SCALAR",
2064 | "description": "Location adjacent to a scalar definition.",
2065 | "isDeprecated": false,
2066 | "deprecationReason": null
2067 | },
2068 | {
2069 | "name": "OBJECT",
2070 | "description": "Location adjacent to an object type definition.",
2071 | "isDeprecated": false,
2072 | "deprecationReason": null
2073 | },
2074 | {
2075 | "name": "FIELD_DEFINITION",
2076 | "description": "Location adjacent to a field definition.",
2077 | "isDeprecated": false,
2078 | "deprecationReason": null
2079 | },
2080 | {
2081 | "name": "ARGUMENT_DEFINITION",
2082 | "description": "Location adjacent to an argument definition.",
2083 | "isDeprecated": false,
2084 | "deprecationReason": null
2085 | },
2086 | {
2087 | "name": "INTERFACE",
2088 | "description": "Location adjacent to an interface definition.",
2089 | "isDeprecated": false,
2090 | "deprecationReason": null
2091 | },
2092 | {
2093 | "name": "UNION",
2094 | "description": "Location adjacent to a union definition.",
2095 | "isDeprecated": false,
2096 | "deprecationReason": null
2097 | },
2098 | {
2099 | "name": "ENUM",
2100 | "description": "Location adjacent to an enum definition.",
2101 | "isDeprecated": false,
2102 | "deprecationReason": null
2103 | },
2104 | {
2105 | "name": "ENUM_VALUE",
2106 | "description": "Location adjacent to an enum value definition.",
2107 | "isDeprecated": false,
2108 | "deprecationReason": null
2109 | },
2110 | {
2111 | "name": "INPUT_OBJECT",
2112 | "description": "Location adjacent to an input object type definition.",
2113 | "isDeprecated": false,
2114 | "deprecationReason": null
2115 | },
2116 | {
2117 | "name": "INPUT_FIELD_DEFINITION",
2118 | "description": "Location adjacent to an input object field definition.",
2119 | "isDeprecated": false,
2120 | "deprecationReason": null
2121 | }
2122 | ],
2123 | "possibleTypes": null
2124 | }
2125 | ],
2126 | "directives": [
2127 | {
2128 | "name": "include",
2129 | "description": "Directs the executor to include this field or fragment only when the `if` argument is true.",
2130 | "locations": [
2131 | "FIELD",
2132 | "FRAGMENT_SPREAD",
2133 | "INLINE_FRAGMENT"
2134 | ],
2135 | "args": [
2136 | {
2137 | "name": "if",
2138 | "description": "Included when true.",
2139 | "type": {
2140 | "kind": "NON_NULL",
2141 | "name": null,
2142 | "ofType": {
2143 | "kind": "SCALAR",
2144 | "name": "Boolean",
2145 | "ofType": null
2146 | }
2147 | },
2148 | "defaultValue": null
2149 | }
2150 | ]
2151 | },
2152 | {
2153 | "name": "skip",
2154 | "description": "Directs the executor to skip this field or fragment when the `if` argument is true.",
2155 | "locations": [
2156 | "FIELD",
2157 | "FRAGMENT_SPREAD",
2158 | "INLINE_FRAGMENT"
2159 | ],
2160 | "args": [
2161 | {
2162 | "name": "if",
2163 | "description": "Skipped when true.",
2164 | "type": {
2165 | "kind": "NON_NULL",
2166 | "name": null,
2167 | "ofType": {
2168 | "kind": "SCALAR",
2169 | "name": "Boolean",
2170 | "ofType": null
2171 | }
2172 | },
2173 | "defaultValue": null
2174 | }
2175 | ]
2176 | },
2177 | {
2178 | "name": "deprecated",
2179 | "description": "Marks an element of a GraphQL schema as no longer supported.",
2180 | "locations": [
2181 | "FIELD_DEFINITION",
2182 | "ENUM_VALUE"
2183 | ],
2184 | "args": [
2185 | {
2186 | "name": "reason",
2187 | "description": "Explains why this element was deprecated, usually also including a suggestion for how to access supported similar data. Formatted in [Markdown](https://daringfireball.net/projects/markdown/).",
2188 | "type": {
2189 | "kind": "SCALAR",
2190 | "name": "String",
2191 | "ofType": null
2192 | },
2193 | "defaultValue": "\"No longer supported\""
2194 | }
2195 | ]
2196 | }
2197 | ]
2198 | }
2199 | }
2200 | }
--------------------------------------------------------------------------------
/data/services/cartService.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by Soon on 2/26/16.
3 | */
4 | import Cart from '../models/Cart';
5 | import CartEntry from '../models/CartEntry';
6 | import Product from '../models/Product';
7 | export const cartService = {
8 | addToCart: (cart, productCode, quantity)=> {
9 | let cartEntry = cart.entries.find((entry)=>entry.product.productCode === productCode);
10 | const product = Product.findOne({ productCode });
11 |
12 | if (cartEntry) {
13 | cartEntry.quantity = quantity;
14 | cartEntry.price = product.price;
15 | cartEntry.totalPrice = (product.price * quantity).toFixed(2);
16 | } else {
17 | cartEntry = new CartEntry({ id: product.id, product, quantity });
18 | cart.entries.push(cartEntry);
19 | }
20 |
21 | return cartEntry;
22 | },
23 | removeFromCart: (cart, cartEntryId)=> {
24 | cart.entries = cart.entries.filter((entry)=>entry.id !== cartEntryId);
25 | },
26 | createNewCart: (session)=> {
27 | const cart = new Cart({
28 | entries: [],
29 | });
30 |
31 | Object.defineProperty(session, 'cart', {
32 | enumerable: true,
33 | writeable: true,
34 | value: cart,
35 | });
36 |
37 | return cart;
38 | },
39 | getSessionCart: (session)=> {
40 | let cart = session.cart;
41 |
42 | if (!cart) {
43 | cart = cartService.createNewCart(session);
44 | }
45 |
46 | return cart;
47 | },
48 | };
49 |
50 | export default cartService;
51 |
--------------------------------------------------------------------------------
/data/services/productService.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by Soon on 2/23/16.
3 | */
4 |
5 | import ProductList from '../models/ProductList';
6 | import Product from '../models/Product';
7 |
8 | export const productService = {
9 | findAll: ({ start, size }) => ProductList.findAll({ start, size }),
10 | findOne: ({ productCode }) => Product.findOne({ productCode }),
11 | findById: id => Product.findById(id),
12 | };
13 |
14 | export default productService;
15 |
--------------------------------------------------------------------------------
/data/types/cartEntryType.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by Soon on 2/26/16.
3 | */
4 |
5 | import {
6 | GraphQLBoolean,
7 | GraphQLFloat,
8 | GraphQLID,
9 | GraphQLInt,
10 | GraphQLList,
11 | GraphQLNonNull,
12 | GraphQLObjectType,
13 | GraphQLSchema,
14 | GraphQLString,
15 | } from 'graphql';
16 |
17 | import {
18 | connectionArgs,
19 | connectionDefinitions,
20 | connectionFromArray,
21 | cursorForObjectInConnection,
22 | fromGlobalId,
23 | globalIdField,
24 | mutationWithClientMutationId,
25 | nodeDefinitions,
26 | toGlobalId,
27 | } from 'graphql-relay';
28 |
29 | import logger from '../../logger';
30 | import productType from './productType';
31 |
32 | import { nodeInterface } from '../defaultDefinitions';
33 | export const cartEntryType = new GraphQLObjectType({
34 | name: 'CartEntry',
35 | fields: () => ({
36 | id: globalIdField('CartEntry'),
37 | product: {
38 | type: productType,
39 | },
40 | quantity: {
41 | type: GraphQLFloat,
42 | },
43 | price: {
44 | type: GraphQLFloat,
45 | },
46 | totalPrice: {
47 | type: GraphQLFloat,
48 | },
49 | }),
50 | interfaces: [nodeInterface],
51 | });
52 |
53 | export const { connectionType: cartEntryConnectionType, edgeType: cartEntryEdgeType } =
54 | connectionDefinitions({ name: 'CartEntry', nodeType: cartEntryType });
55 |
56 | export const queryCartEntry = {
57 | type: cartEntryType,
58 | args: {
59 | id: {
60 | type: GraphQLID,
61 | },
62 | },
63 | resolve: ({}, { id }) => {
64 | logger.info('Resolving queryCartEntry with params:', { id });
65 |
66 | return {};
67 | },
68 | };
69 |
70 |
71 | export default cartEntryType;
72 |
--------------------------------------------------------------------------------
/data/types/cartType.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by Soon on 2/23/16.
3 | */
4 |
5 | import {
6 | GraphQLBoolean,
7 | GraphQLFloat,
8 | GraphQLID,
9 | GraphQLInt,
10 | GraphQLList,
11 | GraphQLNonNull,
12 | GraphQLObjectType,
13 | GraphQLSchema,
14 | GraphQLString,
15 | } from 'graphql';
16 |
17 | import {
18 | connectionArgs,
19 | connectionDefinitions,
20 | connectionFromArray,
21 | cursorForObjectInConnection,
22 | cursorToOffset,
23 | fromGlobalId,
24 | globalIdField,
25 | mutationWithClientMutationId,
26 | nodeDefinitions,
27 | toGlobalId,
28 | } from 'graphql-relay';
29 |
30 | import logger from '../../logger';
31 | import cartEntryType, { cartEntryConnectionType } from './cartEntryType';
32 |
33 | import cartService from '../services/cartService';
34 |
35 | import { nodeInterface } from '../defaultDefinitions';
36 | export const cartType = new GraphQLObjectType({
37 | name: 'Cart',
38 | fields: () => ({
39 | id: globalIdField('Cart'),
40 | entries: {
41 | type: cartEntryConnectionType,
42 | args: connectionArgs,
43 | resolve: ({ entries }, args) => {
44 | logger.info('Resolving cartType.entries with params:', args);
45 |
46 | const connection = connectionFromArray(
47 | entries,
48 | args,
49 | );
50 | return connection;
51 | },
52 | },
53 | totalNumberOfItems: {
54 | type: GraphQLInt,
55 | },
56 | totalPriceOfItems: {
57 | type: GraphQLFloat,
58 | },
59 | }),
60 | interfaces: [nodeInterface],
61 | });
62 |
63 | export const { connectionType: cartConnectionType, edgeType: cartEdgeType } =
64 | connectionDefinitions({
65 | name: 'Cart',
66 | nodeType: cartType,
67 | connectionFields: {
68 | totalNumberOfItems: {
69 | type: GraphQLInt,
70 | },
71 | },
72 | });
73 |
74 | export const queryCart = {
75 | type: cartType,
76 | args: {},
77 | resolve: ({}, {}, session) => {
78 | logger.info('Resolving queryCart with params:', {});
79 |
80 | return cartService.getSessionCart(session);
81 | },
82 | };
83 |
84 |
85 | export default cartType;
86 |
--------------------------------------------------------------------------------
/data/types/imageType.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by Soon on 2/24/16.
3 | */
4 |
5 | import {
6 | GraphQLBoolean,
7 | GraphQLFloat,
8 | GraphQLID,
9 | GraphQLInt,
10 | GraphQLList,
11 | GraphQLNonNull,
12 | GraphQLObjectType,
13 | GraphQLSchema,
14 | GraphQLString,
15 | } from 'graphql';
16 |
17 | import {
18 | connectionArgs,
19 | connectionDefinitions,
20 | connectionFromArray,
21 | cursorForObjectInConnection,
22 | fromGlobalId,
23 | globalIdField,
24 | mutationWithClientMutationId,
25 | nodeDefinitions,
26 | toGlobalId,
27 | } from 'graphql-relay';
28 |
29 | import logger from '../../logger';
30 |
31 | import { nodeInterface } from '../defaultDefinitions';
32 | export const imageType = new GraphQLObjectType({
33 | name: 'Image',
34 | description: 'Just image',
35 | fields: () => ({
36 | format: {
37 | type: GraphQLString,
38 | description: 'The format of image.',
39 | },
40 | url: {
41 | type: GraphQLString,
42 | description: 'The url of image.',
43 | },
44 | }),
45 | });
46 |
47 | export const { connectionType: imageConnection, edgeType: imageEdge } =
48 | connectionDefinitions({ name: 'Image', nodeType: imageType });
49 |
50 | export const queryImage = {
51 | type: imageType,
52 | args: {
53 | id: {
54 | type: GraphQLID,
55 | },
56 | },
57 | resolve: ({}, { id }) => {
58 | logger.info('Resolving queryImage with params:', { id });
59 |
60 | return {};
61 | },
62 | };
63 |
64 |
65 | export default imageType;
66 |
--------------------------------------------------------------------------------
/data/types/productListType.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by Soon on 2/23/16.
3 | */
4 |
5 | import {
6 | GraphQLBoolean,
7 | GraphQLFloat,
8 | GraphQLID,
9 | GraphQLInt,
10 | GraphQLList,
11 | GraphQLNonNull,
12 | GraphQLObjectType,
13 | GraphQLSchema,
14 | GraphQLString,
15 | } from 'graphql';
16 |
17 | import {
18 | connectionArgs,
19 | connectionDefinitions,
20 | connectionFromArray,
21 | cursorForObjectInConnection,
22 | cursorToOffset,
23 | fromGlobalId,
24 | globalIdField,
25 | mutationWithClientMutationId,
26 | nodeDefinitions,
27 | toGlobalId,
28 | } from 'graphql-relay';
29 |
30 | import logger from '../../logger';
31 | import { productConnectionType } from './productType';
32 |
33 | import productService from '../services/productService';
34 |
35 | import { nodeInterface } from '../defaultDefinitions';
36 | export const productListType = new GraphQLObjectType({
37 | name: 'ProductList',
38 | fields: () => ({
39 | id: globalIdField('ProductList'),
40 | items: {
41 | type: productConnectionType,
42 | args: connectionArgs,
43 | resolve: ({}, args) => {
44 | logger.info('Resolving queryProductList with params:', { args });
45 | const start = args.after ? cursorToOffset(args.after) + 1 : 0;
46 | const size = (args.first || 8) + 1;
47 |
48 | const result = productService.findAll({ start, size });
49 |
50 | // support pagination
51 | const array = args.after ? new Array(start).concat(result.items) : result.items;
52 |
53 | return connectionFromArray(
54 | array,
55 | args,
56 | );
57 | },
58 | },
59 | }),
60 | interfaces: [nodeInterface],
61 | });
62 |
63 | export const { connectionType: productListConnectionType, edgeType: productListEdgeType } =
64 | connectionDefinitions({ name: 'ProductList', nodeType: productListType });
65 |
66 | export const queryProductList = {
67 | type: productListType,
68 | args: {},
69 | resolve: ({}) => {
70 | logger.info('Resolving queryProductList with params:', {});
71 |
72 | return {};
73 | },
74 | };
75 |
76 |
77 | export default productListType;
78 |
--------------------------------------------------------------------------------
/data/types/productType.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by Soon on 2/22/16.
3 | */
4 |
5 | import {
6 | GraphQLBoolean,
7 | GraphQLFloat,
8 | GraphQLID,
9 | GraphQLInt,
10 | GraphQLList,
11 | GraphQLNonNull,
12 | GraphQLObjectType,
13 | GraphQLSchema,
14 | GraphQLString,
15 | } from 'graphql';
16 |
17 | import {
18 | connectionArgs,
19 | connectionDefinitions,
20 | connectionFromArray,
21 | cursorForObjectInConnection,
22 | fromGlobalId,
23 | globalIdField,
24 | mutationWithClientMutationId,
25 | nodeDefinitions,
26 | toGlobalId,
27 | } from 'graphql-relay';
28 |
29 | import logger from '../../logger';
30 | import imageType from './imageType';
31 |
32 | import { nodeInterface } from '../defaultDefinitions';
33 | import productService from '../services/productService';
34 |
35 |
36 | export const productType = new GraphQLObjectType({
37 | name: 'Product',
38 | fields: () => ({
39 | id: globalIdField('Product'),
40 | name: {
41 | type: GraphQLString,
42 | description: '商品名称',
43 | },
44 | color: {
45 | type: GraphQLString,
46 | description: '商品颜色',
47 | },
48 | description: {
49 | type: GraphQLString,
50 | description: '商品描述',
51 | },
52 | price: {
53 | type: GraphQLFloat,
54 | description: '商品价格,保留两位小数',
55 | },
56 | images: {
57 | type: new GraphQLList(imageType),
58 | description: "商品图片,['primary': 主图,'thumbnail':缩略图,'zoom':大图]",
59 | args: {
60 | format: {
61 | type: GraphQLString,
62 | defaultValue: 'any',
63 | },
64 | ...connectionArgs,
65 | },
66 | resolve: async ({ images }, { format, ...args }) => {
67 | if (format !== 'any') {
68 | images = images.filter((image) => image.format === format);
69 | }
70 | return images.slice(0, args.first);
71 | },
72 | },
73 | }),
74 | interfaces: [nodeInterface],
75 | });
76 |
77 | export const { connectionType: productConnectionType, edgeType: productEdgeType } =
78 | connectionDefinitions({
79 | name: 'Product',
80 | nodeType: productType,
81 | connectionFields: {
82 | totalNumberOfItems: {
83 | type: GraphQLInt,
84 | },
85 | },
86 | });
87 |
88 | export const queryProduct = {
89 | type: productType,
90 | args: {
91 | id: {
92 | type: GraphQLID,
93 | },
94 | },
95 | resolve: ({}, { id }) => {
96 | logger.info('Resolving queryProduct with params:', { id });
97 | const result = productService.findAll({ start: 0, size: 100 });
98 |
99 | return result.items.find(p => p.id === id);
100 | },
101 | };
102 |
103 |
104 | export default productType;
105 |
--------------------------------------------------------------------------------
/data/types/productsType.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by Xin on 17/04/2017.
3 | */
4 |
5 | import {
6 | GraphQLBoolean,
7 | GraphQLFloat,
8 | GraphQLID,
9 | GraphQLInt,
10 | GraphQLList,
11 | GraphQLNonNull,
12 | GraphQLObjectType,
13 | GraphQLSchema,
14 | GraphQLString,
15 | } from 'graphql';
16 |
17 | import {
18 | connectionArgs,
19 | connectionDefinitions,
20 | connectionFromArray,
21 | cursorForObjectInConnection, cursorToOffset,
22 | fromGlobalId,
23 | globalIdField,
24 | mutationWithClientMutationId,
25 | nodeDefinitions,
26 | toGlobalId,
27 | } from 'graphql-relay';
28 |
29 | import { nodeInterface } from '../defaultDefinitions';
30 |
31 | import logger from '../../logger';
32 | import { productConnectionType } from './productType';
33 | import productService from '../services/productService';
34 |
35 |
36 | export const productsType = new GraphQLObjectType({
37 | name: 'Products',
38 | fields: () => ({
39 | id: globalIdField('Products'),
40 | items: {
41 | type: productConnectionType,
42 | args: connectionArgs,
43 | resolve: ({ items, totalNumberOfItems }, args) => {
44 | logger.info('Resolving queryProductList with params:', { args });
45 | // const start = args.after ? cursorToOffset(args.after) + 1 : 0;
46 | // const size = (args.first || 8) + 1;
47 |
48 | // const result = productService.findAll({ start, size });
49 |
50 | // support pagination
51 | // const array = args.after ? new Array(start).concat(result.items) : result.items;
52 | const connection = connectionFromArray(
53 | items,
54 | args,
55 | );
56 |
57 | connection.totalElements = totalNumberOfItems;
58 | connection.pageInfo.hasNextPage = !args.last;
59 | connection.pageInfo.hasPreviousPage = !args.first;
60 |
61 | return connection;
62 | },
63 | },
64 | }),
65 | interfaces: [nodeInterface],
66 | });
67 |
68 | export const { connectionType: productsConnectionType, edgeType: productsEdgeType } =
69 | connectionDefinitions({
70 | name: 'Products',
71 | nodeType: productsType,
72 | connectionFields: {
73 | totalNumberOfItems: {
74 | type: GraphQLInt,
75 | },
76 | },
77 | });
78 |
79 | export const queryProducts = {
80 | type: productsType,
81 | args: {
82 | id: {
83 | type: GraphQLID,
84 | },
85 | },
86 | resolve: async (rootValue, { id }, { api }) => {
87 | logger.info('Resolving queryProducts with params:', { id });
88 |
89 | return {};
90 | },
91 | };
92 |
93 |
94 | export default productsType;
95 |
--------------------------------------------------------------------------------
/data/types/viewerType.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by Xin on 17/04/2017.
3 | */
4 |
5 | import {
6 | GraphQLBoolean,
7 | GraphQLFloat,
8 | GraphQLID,
9 | GraphQLInt,
10 | GraphQLList,
11 | GraphQLNonNull,
12 | GraphQLObjectType,
13 | GraphQLSchema,
14 | GraphQLString,
15 | } from 'graphql';
16 |
17 | import {
18 | connectionArgs,
19 | connectionDefinitions,
20 | connectionFromArray,
21 | cursorForObjectInConnection, cursorToOffset,
22 | fromGlobalId,
23 | globalIdField,
24 | mutationWithClientMutationId,
25 | nodeDefinitions,
26 | toGlobalId,
27 | } from 'graphql-relay';
28 |
29 | import { nodeInterface } from '../defaultDefinitions';
30 |
31 | import logger from '../../logger';
32 | import { cartType } from './cartType';
33 | import cartService from '../services/cartService';
34 | import productService from '../services/productService';
35 | import { productsType } from './productsType';
36 | import { productConnectionType } from './productType';
37 |
38 |
39 | export const viewerType = new GraphQLObjectType({
40 | name: 'Viewer',
41 | fields: () => ({
42 | id: globalIdField('Viewer'),
43 | name: {
44 | type: GraphQLString,
45 | },
46 | cart: {
47 | type: cartType,
48 | resolve: ({}, { args }, session) => cartService.getSessionCart(session),
49 | },
50 | products: {
51 | type: productConnectionType,
52 | args: connectionArgs,
53 | resolve: ({}, args) => {
54 | logger.info('Resolving queryProductList with params:', { args });
55 | const start = args.after ? cursorToOffset(args.after) + 1 : 0;
56 | const size = (args.first || 8) + 1;
57 |
58 | const result = productService.findAll({ start, size });
59 |
60 | // support pagination
61 | const array = args.after ? new Array(start).concat(result.items) : result.items;
62 | const connection = connectionFromArray(
63 | array,
64 | args,
65 | );
66 |
67 | connection.totalNumberOfItems = result.totalNumberOfItems;
68 | connection.pageInfo.hasNextPage = !args.last;
69 | connection.pageInfo.hasPreviousPage = !args.first;
70 |
71 | return connection;
72 | },
73 | },
74 | }),
75 | interfaces: [nodeInterface],
76 | });
77 |
78 | export const { connectionType: viewerConnectionType, edgeType: viewerEdgeType } =
79 | connectionDefinitions({ name: 'Viewer', nodeType: viewerType });
80 |
81 | export const queryViewer = {
82 | type: viewerType,
83 | args: {
84 | id: {
85 | type: GraphQLID,
86 | },
87 | },
88 | resolve: async (rootValue, { id }) => {
89 | logger.info('Resolving queryViewer with params:', { id });
90 |
91 | return {};
92 | },
93 | };
94 |
95 |
96 | export default viewerType;
97 |
--------------------------------------------------------------------------------
/graphql.config.json:
--------------------------------------------------------------------------------
1 | {
2 |
3 | "README_schema" : "Specifies how to load the GraphQL schema that completion, error highlighting, and documentation is based on in the IDE",
4 | "schema": {
5 |
6 | "README_file" : "Remove 'file' to use request url below. A relative or absolute path to the JSON from a schema introspection query, e.g. '{ data: ... }'. Changes to the file are watched.",
7 | "file": "./data/schema.json",
8 |
9 | "README_request" : "To request the schema from a url instead, remove the 'file' JSON property above (and optionally delete the default graphql.schema.json file).",
10 | "request": {
11 | "url" : "http://localhost:8080/graphql",
12 | "method" : "POST",
13 | "README_postIntrospectionQuery" : "Whether to POST an introspectionQuery to the url. If the url always returns the schema JSON, set to false and consider using GET",
14 | "postIntrospectionQuery" : true,
15 | "README_options" : "See the 'Options' section at https://github.com/then/then-request",
16 | "options" : {
17 | "headers": {
18 | "user-agent" : "JS GraphQL"
19 | }
20 | }
21 | }
22 |
23 | },
24 |
25 | "README_endpoints": "A list of GraphQL endpoints that can be queried from '.graphql' files in the IDE",
26 | "endpoints" : [
27 | {
28 | "name": "Default (http://localhost:8080/graphql)",
29 | "url": "http://localhost:8080/graphql",
30 | "options" : {
31 | "headers": {
32 | "user-agent" : "JS GraphQL"
33 | }
34 | }
35 | }
36 | ]
37 |
38 | }
--------------------------------------------------------------------------------
/graphql.schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "README" : "This is a bare-bones schema generated by JS GraphQL. Replace it with your own schema file or load it from a url by editing graphql.config.json",
3 | "data": {
4 | "__schema": {
5 | "queryType": {
6 | "name": "Query"
7 | },
8 | "mutationType": {
9 | "name": "Mutation"
10 | },
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 | "inputFields": null,
46 | "interfaces": [],
47 | "enumValues": null,
48 | "possibleTypes": null
49 | },
50 | {
51 | "kind": "SCALAR",
52 | "name": "ID",
53 | "description": null,
54 | "fields": null,
55 | "inputFields": null,
56 | "interfaces": null,
57 | "enumValues": null,
58 | "possibleTypes": null
59 | },
60 | {
61 | "kind": "INTERFACE",
62 | "name": "Node",
63 | "description": "An object with an ID",
64 | "fields": [
65 | {
66 | "name": "id",
67 | "description": "The id of the object.",
68 | "args": [],
69 | "type": {
70 | "kind": "NON_NULL",
71 | "name": null,
72 | "ofType": {
73 | "kind": "SCALAR",
74 | "name": "ID",
75 | "ofType": null
76 | }
77 | },
78 | "isDeprecated": false,
79 | "deprecationReason": null
80 | }
81 | ],
82 | "inputFields": null,
83 | "interfaces": null,
84 | "enumValues": null,
85 | "possibleTypes": [
86 | ]
87 | },
88 | {
89 | "kind": "SCALAR",
90 | "name": "String",
91 | "description": null,
92 | "fields": null,
93 | "inputFields": null,
94 | "interfaces": null,
95 | "enumValues": null,
96 | "possibleTypes": null
97 | },
98 | {
99 | "kind": "SCALAR",
100 | "name": "Int",
101 | "description": null,
102 | "fields": null,
103 | "inputFields": null,
104 | "interfaces": null,
105 | "enumValues": null,
106 | "possibleTypes": null
107 | },
108 | {
109 | "kind": "OBJECT",
110 | "name": "PageInfo",
111 | "description": "Information about pagination in a connection.",
112 | "fields": [
113 | {
114 | "name": "hasNextPage",
115 | "description": "When paginating forwards, are there more items?",
116 | "args": [],
117 | "type": {
118 | "kind": "NON_NULL",
119 | "name": null,
120 | "ofType": {
121 | "kind": "SCALAR",
122 | "name": "Boolean",
123 | "ofType": null
124 | }
125 | },
126 | "isDeprecated": false,
127 | "deprecationReason": null
128 | },
129 | {
130 | "name": "hasPreviousPage",
131 | "description": "When paginating backwards, are there more items?",
132 | "args": [],
133 | "type": {
134 | "kind": "NON_NULL",
135 | "name": null,
136 | "ofType": {
137 | "kind": "SCALAR",
138 | "name": "Boolean",
139 | "ofType": null
140 | }
141 | },
142 | "isDeprecated": false,
143 | "deprecationReason": null
144 | },
145 | {
146 | "name": "startCursor",
147 | "description": "When paginating backwards, the cursor to continue.",
148 | "args": [],
149 | "type": {
150 | "kind": "SCALAR",
151 | "name": "String",
152 | "ofType": null
153 | },
154 | "isDeprecated": false,
155 | "deprecationReason": null
156 | },
157 | {
158 | "name": "endCursor",
159 | "description": "When paginating forwards, the cursor to continue.",
160 | "args": [],
161 | "type": {
162 | "kind": "SCALAR",
163 | "name": "String",
164 | "ofType": null
165 | },
166 | "isDeprecated": false,
167 | "deprecationReason": null
168 | }
169 | ],
170 | "inputFields": null,
171 | "interfaces": [],
172 | "enumValues": null,
173 | "possibleTypes": null
174 | },
175 | {
176 | "kind": "SCALAR",
177 | "name": "Boolean",
178 | "description": null,
179 | "fields": null,
180 | "inputFields": null,
181 | "interfaces": null,
182 | "enumValues": null,
183 | "possibleTypes": null
184 | },
185 | {
186 | "kind": "OBJECT",
187 | "name": "Mutation",
188 | "description": null,
189 | "fields": [
190 | {
191 | "name": "id",
192 | "description": "The id of the object.",
193 | "args": [],
194 | "type": {
195 | "kind": "NON_NULL",
196 | "name": null,
197 | "ofType": {
198 | "kind": "SCALAR",
199 | "name": "ID",
200 | "ofType": null
201 | }
202 | },
203 | "isDeprecated": false,
204 | "deprecationReason": null
205 | }
206 | ],
207 | "inputFields": null,
208 | "interfaces": [],
209 | "enumValues": null,
210 | "possibleTypes": null
211 | },
212 | {
213 | "kind": "OBJECT",
214 | "name": "__Schema",
215 | "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 and mutation operations.",
216 | "fields": [
217 | {
218 | "name": "types",
219 | "description": "A list of all types supported by this server.",
220 | "args": [],
221 | "type": {
222 | "kind": "NON_NULL",
223 | "name": null,
224 | "ofType": {
225 | "kind": "LIST",
226 | "name": null,
227 | "ofType": {
228 | "kind": "NON_NULL",
229 | "name": null,
230 | "ofType": {
231 | "kind": "OBJECT",
232 | "name": "__Type"
233 | }
234 | }
235 | }
236 | },
237 | "isDeprecated": false,
238 | "deprecationReason": null
239 | },
240 | {
241 | "name": "queryType",
242 | "description": "The type that query operations will be rooted at.",
243 | "args": [],
244 | "type": {
245 | "kind": "NON_NULL",
246 | "name": null,
247 | "ofType": {
248 | "kind": "OBJECT",
249 | "name": "__Type",
250 | "ofType": null
251 | }
252 | },
253 | "isDeprecated": false,
254 | "deprecationReason": null
255 | },
256 | {
257 | "name": "mutationType",
258 | "description": "If this server supports mutation, the type that mutation operations will be rooted at.",
259 | "args": [],
260 | "type": {
261 | "kind": "OBJECT",
262 | "name": "__Type",
263 | "ofType": null
264 | },
265 | "isDeprecated": false,
266 | "deprecationReason": null
267 | },
268 | {
269 | "name": "directives",
270 | "description": "A list of all directives supported by this server.",
271 | "args": [],
272 | "type": {
273 | "kind": "NON_NULL",
274 | "name": null,
275 | "ofType": {
276 | "kind": "LIST",
277 | "name": null,
278 | "ofType": {
279 | "kind": "NON_NULL",
280 | "name": null,
281 | "ofType": {
282 | "kind": "OBJECT",
283 | "name": "__Directive"
284 | }
285 | }
286 | }
287 | },
288 | "isDeprecated": false,
289 | "deprecationReason": null
290 | }
291 | ],
292 | "inputFields": null,
293 | "interfaces": [],
294 | "enumValues": null,
295 | "possibleTypes": null
296 | },
297 | {
298 | "kind": "OBJECT",
299 | "name": "__Type",
300 | "description": null,
301 | "fields": [
302 | {
303 | "name": "kind",
304 | "description": null,
305 | "args": [],
306 | "type": {
307 | "kind": "NON_NULL",
308 | "name": null,
309 | "ofType": {
310 | "kind": "ENUM",
311 | "name": "__TypeKind",
312 | "ofType": null
313 | }
314 | },
315 | "isDeprecated": false,
316 | "deprecationReason": null
317 | },
318 | {
319 | "name": "name",
320 | "description": null,
321 | "args": [],
322 | "type": {
323 | "kind": "SCALAR",
324 | "name": "String",
325 | "ofType": null
326 | },
327 | "isDeprecated": false,
328 | "deprecationReason": null
329 | },
330 | {
331 | "name": "description",
332 | "description": null,
333 | "args": [],
334 | "type": {
335 | "kind": "SCALAR",
336 | "name": "String",
337 | "ofType": null
338 | },
339 | "isDeprecated": false,
340 | "deprecationReason": null
341 | },
342 | {
343 | "name": "fields",
344 | "description": null,
345 | "args": [
346 | {
347 | "name": "includeDeprecated",
348 | "description": null,
349 | "type": {
350 | "kind": "SCALAR",
351 | "name": "Boolean",
352 | "ofType": null
353 | },
354 | "defaultValue": "false"
355 | }
356 | ],
357 | "type": {
358 | "kind": "LIST",
359 | "name": null,
360 | "ofType": {
361 | "kind": "NON_NULL",
362 | "name": null,
363 | "ofType": {
364 | "kind": "OBJECT",
365 | "name": "__Field",
366 | "ofType": null
367 | }
368 | }
369 | },
370 | "isDeprecated": false,
371 | "deprecationReason": null
372 | },
373 | {
374 | "name": "interfaces",
375 | "description": null,
376 | "args": [],
377 | "type": {
378 | "kind": "LIST",
379 | "name": null,
380 | "ofType": {
381 | "kind": "NON_NULL",
382 | "name": null,
383 | "ofType": {
384 | "kind": "OBJECT",
385 | "name": "__Type",
386 | "ofType": null
387 | }
388 | }
389 | },
390 | "isDeprecated": false,
391 | "deprecationReason": null
392 | },
393 | {
394 | "name": "possibleTypes",
395 | "description": null,
396 | "args": [],
397 | "type": {
398 | "kind": "LIST",
399 | "name": null,
400 | "ofType": {
401 | "kind": "NON_NULL",
402 | "name": null,
403 | "ofType": {
404 | "kind": "OBJECT",
405 | "name": "__Type",
406 | "ofType": null
407 | }
408 | }
409 | },
410 | "isDeprecated": false,
411 | "deprecationReason": null
412 | },
413 | {
414 | "name": "enumValues",
415 | "description": null,
416 | "args": [
417 | {
418 | "name": "includeDeprecated",
419 | "description": null,
420 | "type": {
421 | "kind": "SCALAR",
422 | "name": "Boolean",
423 | "ofType": null
424 | },
425 | "defaultValue": "false"
426 | }
427 | ],
428 | "type": {
429 | "kind": "LIST",
430 | "name": null,
431 | "ofType": {
432 | "kind": "NON_NULL",
433 | "name": null,
434 | "ofType": {
435 | "kind": "OBJECT",
436 | "name": "__EnumValue",
437 | "ofType": null
438 | }
439 | }
440 | },
441 | "isDeprecated": false,
442 | "deprecationReason": null
443 | },
444 | {
445 | "name": "inputFields",
446 | "description": null,
447 | "args": [],
448 | "type": {
449 | "kind": "LIST",
450 | "name": null,
451 | "ofType": {
452 | "kind": "NON_NULL",
453 | "name": null,
454 | "ofType": {
455 | "kind": "OBJECT",
456 | "name": "__InputValue",
457 | "ofType": null
458 | }
459 | }
460 | },
461 | "isDeprecated": false,
462 | "deprecationReason": null
463 | },
464 | {
465 | "name": "ofType",
466 | "description": null,
467 | "args": [],
468 | "type": {
469 | "kind": "OBJECT",
470 | "name": "__Type",
471 | "ofType": null
472 | },
473 | "isDeprecated": false,
474 | "deprecationReason": null
475 | }
476 | ],
477 | "inputFields": null,
478 | "interfaces": [],
479 | "enumValues": null,
480 | "possibleTypes": null
481 | },
482 | {
483 | "kind": "ENUM",
484 | "name": "__TypeKind",
485 | "description": "An enum describing what kind of type a given __Type is",
486 | "fields": null,
487 | "inputFields": null,
488 | "interfaces": null,
489 | "enumValues": [
490 | {
491 | "name": "SCALAR",
492 | "description": "Indicates this type is a scalar.",
493 | "isDeprecated": false,
494 | "deprecationReason": null
495 | },
496 | {
497 | "name": "OBJECT",
498 | "description": "Indicates this type is an object. `fields` and `interfaces` are valid fields.",
499 | "isDeprecated": false,
500 | "deprecationReason": null
501 | },
502 | {
503 | "name": "INTERFACE",
504 | "description": "Indicates this type is an interface. `fields` and `possibleTypes` are valid fields.",
505 | "isDeprecated": false,
506 | "deprecationReason": null
507 | },
508 | {
509 | "name": "UNION",
510 | "description": "Indicates this type is a union. `possibleTypes` is a valid field.",
511 | "isDeprecated": false,
512 | "deprecationReason": null
513 | },
514 | {
515 | "name": "ENUM",
516 | "description": "Indicates this type is an enum. `enumValues` is a valid field.",
517 | "isDeprecated": false,
518 | "deprecationReason": null
519 | },
520 | {
521 | "name": "INPUT_OBJECT",
522 | "description": "Indicates this type is an input object. `inputFields` is a valid field.",
523 | "isDeprecated": false,
524 | "deprecationReason": null
525 | },
526 | {
527 | "name": "LIST",
528 | "description": "Indicates this type is a list. `ofType` is a valid field.",
529 | "isDeprecated": false,
530 | "deprecationReason": null
531 | },
532 | {
533 | "name": "NON_NULL",
534 | "description": "Indicates this type is a non-null. `ofType` is a valid field.",
535 | "isDeprecated": false,
536 | "deprecationReason": null
537 | }
538 | ],
539 | "possibleTypes": null
540 | },
541 | {
542 | "kind": "OBJECT",
543 | "name": "__Field",
544 | "description": null,
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": "args",
576 | "description": null,
577 | "args": [],
578 | "type": {
579 | "kind": "NON_NULL",
580 | "name": null,
581 | "ofType": {
582 | "kind": "LIST",
583 | "name": null,
584 | "ofType": {
585 | "kind": "NON_NULL",
586 | "name": null,
587 | "ofType": {
588 | "kind": "OBJECT",
589 | "name": "__InputValue"
590 | }
591 | }
592 | }
593 | },
594 | "isDeprecated": false,
595 | "deprecationReason": null
596 | },
597 | {
598 | "name": "type",
599 | "description": null,
600 | "args": [],
601 | "type": {
602 | "kind": "NON_NULL",
603 | "name": null,
604 | "ofType": {
605 | "kind": "OBJECT",
606 | "name": "__Type",
607 | "ofType": null
608 | }
609 | },
610 | "isDeprecated": false,
611 | "deprecationReason": null
612 | },
613 | {
614 | "name": "isDeprecated",
615 | "description": null,
616 | "args": [],
617 | "type": {
618 | "kind": "NON_NULL",
619 | "name": null,
620 | "ofType": {
621 | "kind": "SCALAR",
622 | "name": "Boolean",
623 | "ofType": null
624 | }
625 | },
626 | "isDeprecated": false,
627 | "deprecationReason": null
628 | },
629 | {
630 | "name": "deprecationReason",
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 | "inputFields": null,
643 | "interfaces": [],
644 | "enumValues": null,
645 | "possibleTypes": null
646 | },
647 | {
648 | "kind": "OBJECT",
649 | "name": "__InputValue",
650 | "description": null,
651 | "fields": [
652 | {
653 | "name": "name",
654 | "description": null,
655 | "args": [],
656 | "type": {
657 | "kind": "NON_NULL",
658 | "name": null,
659 | "ofType": {
660 | "kind": "SCALAR",
661 | "name": "String",
662 | "ofType": null
663 | }
664 | },
665 | "isDeprecated": false,
666 | "deprecationReason": null
667 | },
668 | {
669 | "name": "description",
670 | "description": null,
671 | "args": [],
672 | "type": {
673 | "kind": "SCALAR",
674 | "name": "String",
675 | "ofType": null
676 | },
677 | "isDeprecated": false,
678 | "deprecationReason": null
679 | },
680 | {
681 | "name": "type",
682 | "description": null,
683 | "args": [],
684 | "type": {
685 | "kind": "NON_NULL",
686 | "name": null,
687 | "ofType": {
688 | "kind": "OBJECT",
689 | "name": "__Type",
690 | "ofType": null
691 | }
692 | },
693 | "isDeprecated": false,
694 | "deprecationReason": null
695 | },
696 | {
697 | "name": "defaultValue",
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 | "inputFields": null,
710 | "interfaces": [],
711 | "enumValues": null,
712 | "possibleTypes": null
713 | },
714 | {
715 | "kind": "OBJECT",
716 | "name": "__EnumValue",
717 | "description": null,
718 | "fields": [
719 | {
720 | "name": "name",
721 | "description": null,
722 | "args": [],
723 | "type": {
724 | "kind": "NON_NULL",
725 | "name": null,
726 | "ofType": {
727 | "kind": "SCALAR",
728 | "name": "String",
729 | "ofType": null
730 | }
731 | },
732 | "isDeprecated": false,
733 | "deprecationReason": null
734 | },
735 | {
736 | "name": "description",
737 | "description": null,
738 | "args": [],
739 | "type": {
740 | "kind": "SCALAR",
741 | "name": "String",
742 | "ofType": null
743 | },
744 | "isDeprecated": false,
745 | "deprecationReason": null
746 | },
747 | {
748 | "name": "isDeprecated",
749 | "description": null,
750 | "args": [],
751 | "type": {
752 | "kind": "NON_NULL",
753 | "name": null,
754 | "ofType": {
755 | "kind": "SCALAR",
756 | "name": "Boolean",
757 | "ofType": null
758 | }
759 | },
760 | "isDeprecated": false,
761 | "deprecationReason": null
762 | },
763 | {
764 | "name": "deprecationReason",
765 | "description": null,
766 | "args": [],
767 | "type": {
768 | "kind": "SCALAR",
769 | "name": "String",
770 | "ofType": null
771 | },
772 | "isDeprecated": false,
773 | "deprecationReason": null
774 | }
775 | ],
776 | "inputFields": null,
777 | "interfaces": [],
778 | "enumValues": null,
779 | "possibleTypes": null
780 | },
781 | {
782 | "kind": "OBJECT",
783 | "name": "__Directive",
784 | "description": null,
785 | "fields": [
786 | {
787 | "name": "name",
788 | "description": null,
789 | "args": [],
790 | "type": {
791 | "kind": "NON_NULL",
792 | "name": null,
793 | "ofType": {
794 | "kind": "SCALAR",
795 | "name": "String",
796 | "ofType": null
797 | }
798 | },
799 | "isDeprecated": false,
800 | "deprecationReason": null
801 | },
802 | {
803 | "name": "description",
804 | "description": null,
805 | "args": [],
806 | "type": {
807 | "kind": "SCALAR",
808 | "name": "String",
809 | "ofType": null
810 | },
811 | "isDeprecated": false,
812 | "deprecationReason": null
813 | },
814 | {
815 | "name": "args",
816 | "description": null,
817 | "args": [],
818 | "type": {
819 | "kind": "NON_NULL",
820 | "name": null,
821 | "ofType": {
822 | "kind": "LIST",
823 | "name": null,
824 | "ofType": {
825 | "kind": "NON_NULL",
826 | "name": null,
827 | "ofType": {
828 | "kind": "OBJECT",
829 | "name": "__InputValue"
830 | }
831 | }
832 | }
833 | },
834 | "isDeprecated": false,
835 | "deprecationReason": null
836 | },
837 | {
838 | "name": "onOperation",
839 | "description": null,
840 | "args": [],
841 | "type": {
842 | "kind": "NON_NULL",
843 | "name": null,
844 | "ofType": {
845 | "kind": "SCALAR",
846 | "name": "Boolean",
847 | "ofType": null
848 | }
849 | },
850 | "isDeprecated": false,
851 | "deprecationReason": null
852 | },
853 | {
854 | "name": "onFragment",
855 | "description": null,
856 | "args": [],
857 | "type": {
858 | "kind": "NON_NULL",
859 | "name": null,
860 | "ofType": {
861 | "kind": "SCALAR",
862 | "name": "Boolean",
863 | "ofType": null
864 | }
865 | },
866 | "isDeprecated": false,
867 | "deprecationReason": null
868 | },
869 | {
870 | "name": "onField",
871 | "description": null,
872 | "args": [],
873 | "type": {
874 | "kind": "NON_NULL",
875 | "name": null,
876 | "ofType": {
877 | "kind": "SCALAR",
878 | "name": "Boolean",
879 | "ofType": null
880 | }
881 | },
882 | "isDeprecated": false,
883 | "deprecationReason": null
884 | }
885 | ],
886 | "inputFields": null,
887 | "interfaces": [],
888 | "enumValues": null,
889 | "possibleTypes": null
890 | }
891 | ],
892 | "directives": [
893 | {
894 | "name": "include",
895 | "description": "Directs the executor to include this field or fragment only when the `if` argument is true.",
896 | "args": [
897 | {
898 | "name": "if",
899 | "description": "Included when true.",
900 | "type": {
901 | "kind": "NON_NULL",
902 | "name": null,
903 | "ofType": {
904 | "kind": "SCALAR",
905 | "name": "Boolean",
906 | "ofType": null
907 | }
908 | },
909 | "defaultValue": null
910 | }
911 | ],
912 | "onOperation": false,
913 | "onFragment": true,
914 | "onField": true
915 | },
916 | {
917 | "name": "skip",
918 | "description": "Directs the executor to skip this field or fragment when the `if` argument is true.",
919 | "args": [
920 | {
921 | "name": "if",
922 | "description": "Skipped when true.",
923 | "type": {
924 | "kind": "NON_NULL",
925 | "name": null,
926 | "ofType": {
927 | "kind": "SCALAR",
928 | "name": "Boolean",
929 | "ofType": null
930 | }
931 | },
932 | "defaultValue": null
933 | }
934 | ],
935 | "onOperation": false,
936 | "onFragment": true,
937 | "onField": true
938 | }
939 | ]
940 | }
941 | }
942 | }
--------------------------------------------------------------------------------
/gulpfile.babel.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by Soon on 10/18/2015.
3 | */
4 | import requireDir from 'require-dir';
5 | let tasks = requireDir('./tasks');
6 |
7 |
--------------------------------------------------------------------------------
/js/app.js:
--------------------------------------------------------------------------------
1 | import 'babel-polyfill';
2 | import { Router, browserHistory, applyRouterMiddleware } from 'react-router';
3 | import React from 'react';
4 | import ReactDOM from 'react-dom';
5 | import Relay from 'react-relay';
6 | import useRelay from 'react-router-relay';
7 | import FastClick from 'fastclick';
8 |
9 | import rootRoute from './routes/rootRoute';
10 |
11 | const networkLayerOptions = {
12 | fetchTimeout: 30000, // Timeout after 30s.
13 | retryDelays: [5000], // Only retry once after a 5s delay.
14 | credentials: 'same-origin', // pass cookies when request.
15 | };
16 |
17 | /* inject DefaultNetworkLayer with options */
18 | Relay.injectNetworkLayer(
19 | new Relay.DefaultNetworkLayer('/graphql', networkLayerOptions),
20 | );
21 |
22 | ReactDOM.render(
23 |
Subtotal ({cart.totalNumberOfItems} items):
{products.totalNumberOfItems} results.
175 |