From 89f1c1d466bc12c614d2230c462a17ed38acd4a2 Mon Sep 17 00:00:00 2001 From: veeramarni Date: Sat, 11 Feb 2017 10:58:57 -0500 Subject: [PATCH] Squashed 'app/packages/meteor-integration/' changes from d5bee6f..8535ff5 8535ff5 Merge branch 'apollographql-master' a0bcdeb updated to 0.3.1 9c0165b Release 0.3.1 8b17a20 Release 0.3.0 f2a6044 Update CHANGELOG 99d7c8c Add note to README about testing warning 0864876 Write tests for batching interface & restructure tests (#68) 624e46b Update versions 8677c36 Add batching (#62) 37497ea Enable SSR, fixes #56 (#57) 7eadb9d Fix #3 test runner (#63) 39d2c91 batching interface by default, extend interface option only when relevant ec1e8cc client: allow to configure 'createMeteorNetworkInterface' to use a batching interface; pass opts to fetch; add comments to default config git-subtree-dir: app/packages/meteor-integration git-subtree-split: 8535ff51a9b3ad39792903ea9259f956158d34e7 --- .babelrc | 6 + .eslintignore | 4 + .eslintrc | 58 +++++++ .gitignore | 3 + .versions | 4 +- CHANGELOG.md | 18 ++ README.md | 13 +- check-npm.js | 14 +- main-client.js | 66 +++++--- main-server.js | 3 +- package.js | 3 +- package.json | 46 +++++ tests/client.js | 98 ++++++++++- tests/server.js | 54 +++++- yarn.lock | 438 ++++++++++++++++++++++++++++++++++++++++++++++++ 15 files changed, 780 insertions(+), 48 deletions(-) create mode 100644 .babelrc create mode 100644 .eslintignore create mode 100644 .eslintrc create mode 100644 .gitignore create mode 100644 package.json create mode 100644 yarn.lock diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..6cb4824 --- /dev/null +++ b/.babelrc @@ -0,0 +1,6 @@ +{ + "presets": ["es2015", "stage-0"], + "plugins": [ + "transform-runtime" +] +} \ No newline at end of file diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..058a701 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,4 @@ +bin/** +build/** +app/node_modules/** +packages/** diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..3b42566 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,58 @@ +{ + "parser" : "babel-eslint", + "plugins": [ + "react", + "jsx-a11y", + "import", + "meteor", + "fp", + "graphql" + ], + "extends" : [ + "airbnb", + "plugin:meteor/recommended" + ], + "settings": { + "import/resolver": { + "meteor": { + "extensions": [ + ".js", + ".jsx" + ], + "moduleDirectory": [ + "node_modules" + ] + } + } + }, + "rules": { + // Soft some rules. + "global-require": 0, // Used by webpack-isomorphic-tools and React Native. + "no-class-assign": 0, // Class assign is used for higher order components. + "no-nested-ternary": 0, // It's nice for JSX. + "no-param-reassign": 0, // We love param reassignment. Naming is hard. + "no-shadow": 0, // Shadowing is a nice language feature. Naming is hard. + "import/first": 0, // Este sorts by atom/sort-lines natural order. + "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }], // No, JSX belongs to .js files + "react/react-in-jsx-scope": 0, + "react/forbid-prop-types": [0, { "forbid": [] }], + "jsx-a11y/html-has-lang": 0, // Can't recognize the Helmet. + "no-confusing-arrow": 0, // This rule is super confusing. + "react/no-unused-prop-types": 0, // Este is going to use Flow types. + "react/jsx-indent": 0, // Damn. We need Yarn asap. + "import/prefer-default-export": 0, // No. Actions can have just one action. + "no-duplicate-imports": 0, // github.com/babel/eslint-plugin-babel/issues/59#issuecomment-230118848 + "import/no-duplicates": 2, + // Rules for functional programming. We do not need Object.freeze. + "fp/no-mutating-assign": 2 + // TODO: Can't be enabled now, it requires a lot of refactoring. + // "fp/no-mutating-methods": 2, + // "fp/no-mutation": ["error", { + // "commonjs": true, + // "allowThis": true, + // "exceptions": [ + // {"property": "propTypes"} + // ] + // }] + } +} \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5ea2ebf --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +node_modules +.idea +.iron \ No newline at end of file diff --git a/.versions b/.versions index aa143c5..bf9aa8a 100644 --- a/.versions +++ b/.versions @@ -1,6 +1,6 @@ accounts-base@1.2.9 allow-deny@1.0.5 -apollo@0.2.0 +apollo@0.3.1 autoupdate@1.2.11 babel-compiler@6.9.0 babel-runtime@0.1.10 @@ -30,7 +30,7 @@ htmljs@1.0.10 http@1.1.8 id-map@1.0.8 jquery@1.11.9 -local-test:apollo@0.2.0 +local-test:apollo@0.3.1 localstorage@1.0.11 logging@1.1.14 meteor@1.2.16 diff --git a/CHANGELOG.md b/CHANGELOG.md index 30da16d..056fa3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,24 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## vNEXT +## [0.3.1] +### Fixed + +- Fixed bug in `v0.3.0` [#69](https://github.com/apollographql/meteor-integration/issues/69) + +## [0.3.0] - 2017-02-08 +AKA The Xavier Release 👍 + +### Updated + +- `apollo-client` [`^0.7.0 || ^0.8.0'`](https://github.com/apollographql/apollo-client/blob/master/CHANGELOG.md#080) +- `apollo-server-express` [`^0.5.0`](https://github.com/apollographql/graphql-server/blob/master/CHANGELOG.md#v050) + +### Added + +- Export `createMeteorNetworkInterface` and `meteorClientConfig` server-side to allow server-side rendering, accept a `loginToken` option in the config of Apollo Client (for example the cookie from `meteorhacks:fast-render` used for SSR) [#57](https://github.com/apollostack/meteor-integration/pull/57) +- Tests! [#63](https://github.com/apollographql/meteor-integration/pull/63) and [#68](https://github.com/apollographql/meteor-integration/pull/68) + ## [0.2.1] - 2016-12-23 ### Added diff --git a/README.md b/README.md index dcee18f..736cc65 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,25 @@ -Use the [Apollo Stack](http://dev.apollodata.com/) in your [Meteor](https://www.meteor.com/) app. +Use the [Apollo GraphQL Client and Server](http://dev.apollodata.com/) in your [Meteor](https://www.meteor.com/) app. ```sh meteor add apollo ``` -# Docs - **[The docs](http://dev.apollodata.com/core/meteor.html)** # Package dev ## Tests -TODO broken, see #3 - ```bash git clone git@github.com:apollostack/meteor-integration.git cd meteor-integration -meteor test-packages ./ --driver-package practicalmeteor:mocha -open localhost:3000 +npm install +npm run test +open http://localhost:3000 ``` +Ignore the npm peer requirements warning that appears on client and server consoles. + ## Credits [Contributors](https://github.com/apollostack/meteor-integration/graphs/contributors) diff --git a/check-npm.js b/check-npm.js index 985f7c0..dce6b68 100644 --- a/check-npm.js +++ b/check-npm.js @@ -3,17 +3,17 @@ import { checkNpmVersions } from 'meteor/tmeasday:check-npm-versions'; if (Meteor.isClient) { checkNpmVersions({ - 'apollo-client': '^0.5.0', + 'apollo-client': '^0.7.0 || ^0.8.0', }, 'apollo'); } else { checkNpmVersions({ - 'graphql-server-express': '^0.4.3', + 'graphql-server-express': '^0.6.0', "body-parser": "^1.15.2", "express": "^4.14.0", - "graphql": "^0.7.0 || ^0.8.0", - "graphql-tools": "^0.8.0", - "subscriptions-transport-ws": "^0.3.0", - "graphql-tag": "^1.1.0", - "graphql-subscriptions": "^0.2.0" + "graphql": "^0.8.0 || ^0.9.0", + "subscriptions-transport-ws": "^0.5.1", + "graphql-tag": "^1.1.2", + "graphql-subscriptions": "^0.3.0", + "graphql-tools": "^0.9.0 || 0.10.0", }, 'apollo'); } diff --git a/main-client.js b/main-client.js index 07b6e28..6675477 100644 --- a/main-client.js +++ b/main-client.js @@ -1,16 +1,18 @@ import './check-npm.js'; -import { createNetworkInterface } from 'apollo-client'; +import { createNetworkInterface, createBatchingNetworkInterface } from 'apollo-client'; import { Accounts } from 'meteor/accounts-base'; +import { Meteor } from 'meteor/meteor'; import { _ } from 'meteor/underscore'; import { print } from 'graphql-tag/printer'; import { Client } from 'subscriptions-transport-ws'; const defaultNetworkInterfaceConfig = { - path: '/graphql', - options: {}, - useMeteorAccounts: true, - useSubscription: true, + path: '/graphql', // default graphql server endpoint + opts: {}, // additional fetch options like `credentials` or `headers` + useMeteorAccounts: true, // if true, send an eventual Meteor login token to identify the current user with every request + batchingInterface: true, // use a BatchingNetworkInterface by default instead of a NetworkInterface + batchInterval: 10, // default batch interval }; const getDefaultWsClient = () => new Client('ws://localhost:8080'); @@ -24,14 +26,44 @@ export const createMeteorNetworkInterface = (givenConfig) => { path = path.slice(1); } - // For SSR - const uri = Meteor.absoluteUrl(path); - const networkInterface = createNetworkInterface({ uri }); + // allow the use of a batching network interface; if the options.batchingInterface is not specified, fallback to the standard network interface + const interfaceToUse = config.batchingInterface ? createBatchingNetworkInterface : createNetworkInterface; + + // default interface options + let interfaceOptions = { + uri: Meteor.absoluteUrl(path), + }; + + // if a BatchingNetworkInterface is used with a correct batch interval, add it to the options + if(config.batchingInterface && config.batchInterval) { + interfaceOptions.batchInterval = config.batchInterval; + } + + // if 'fetch' has been configured to be called with specific opts, add it to the options + if(!_.isEmpty(config.opts)) { + interfaceOptions.opts = config.opts; + } + + const networkInterface = interfaceToUse(interfaceOptions); if (config.useMeteorAccounts) { networkInterface.use([{ applyMiddleware(request, next) { - const currentUserToken = Accounts._storedLoginToken() ? Accounts._storedLoginToken() : null; + + // cookie login token created by meteorhacks:fast-render and caught during server-side rendering by rr:react-router-ssr + const { loginToken: cookieLoginToken } = config; + // Meteor accounts-base login token stored in local storage, only exists client-side + const localStorageLoginToken = Meteor.isClient && Accounts._storedLoginToken(); + + // on initial load, prefer to use the token grabbed server-side if existing + let currentUserToken = cookieLoginToken || localStorageLoginToken; + + // ...a login token has been passed to the config, however the "true" one is different ⚠️ + // https://github.com/apollostack/meteor-integration/pull/57/files#r96745502 + if (Meteor.isClient && cookieLoginToken && cookieLoginToken !== localStorageLoginToken) { + // be sure to pass the right token to the request! + currentUserToken = localStorageLoginToken; + } if (!currentUserToken) { next(); @@ -62,18 +94,7 @@ export const createMeteorNetworkInterface = (givenConfig) => { } return networkInterface; }; -// const configureSubscription = (wsClientProvided) => { -// const wsClient = wsClientProvided ? wsClientProvided : getDefaultWsClient(); -// return { -// subscribe: (request, handler) => wsClient.subscribe({ -// query: print(request.query), -// variables: request.variables, -// }, handler), -// unsubscribe: (id) => { -// wsClient.unsubscribe(id); -// }, -// }; -// } + export const meteorClientConfig = (networkInterfaceConfig) => { const networkInterface = createMeteorNetworkInterface(networkInterfaceConfig); let { initialState } = networkInterface; @@ -86,12 +107,15 @@ export const meteorClientConfig = (networkInterfaceConfig) => { return { networkInterface, initialState, + ssrMode: Meteor.isServer, + // Default to using Mongo _id, must use _id for queries. dataIdFromObject: (result) => { if (result._id && result.__typename) { const dataId = result.__typename + result._id; return dataId; } + return null; }, }; diff --git a/main-server.js b/main-server.js index ede3f7e..b4c2e33 100644 --- a/main-server.js +++ b/main-server.js @@ -11,7 +11,7 @@ import { Accounts } from 'meteor/accounts-base'; import { _ } from 'meteor/underscore'; import { SubscriptionServer } from 'subscriptions-transport-ws'; -export { meteorClientConfig, createMeteorNetworkInterface } from './main-client'; +export { createMeteorNetworkInterface, meteorClientConfig } from './main-client'; const defaultConfig = { path: '/graphql', @@ -91,7 +91,6 @@ export const createApolloServer = (givenOptions = {}, givenConfig = {}) => { } return options; - })); // Start GraphiQL if enabled diff --git a/package.js b/package.js index 6be302c..3e3969a 100644 --- a/package.js +++ b/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'apollo', - version: '0.2.1', + version: '0.3.1', summary: ' 🚀 Add Apollo to your Meteor app', git: 'https://github.com/apollostack/meteor-integration' }); @@ -20,6 +20,7 @@ Package.onTest(function(api) { api.use(['ecmascript', 'practicalmeteor:mocha', 'practicalmeteor:chai', + 'http', 'apollo']); api.mainModule('tests/client.js', 'client'); diff --git a/package.json b/package.json new file mode 100644 index 0000000..666f10a --- /dev/null +++ b/package.json @@ -0,0 +1,46 @@ +{ + "name": "apollo-meteor-integration", + "version": "0.2.1", + "description": " 🚀 Add Apollo to your Meteor app", + "directories": { + "test": "tests" + }, + "scripts": { + "test": "meteor test-packages ./ --driver-package practicalmeteor:mocha" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/apollostack/meteor-integration.git" + }, + "author": "", + "license": "MIT", + "bugs": { + "url": "https://github.com/apollostack/meteor-integration/issues" + }, + "homepage": "https://github.com/apollostack/meteor-integration#readme", + "dependencies": { + "apollo-client": "^0.8.4", + "babel": "^6.5.2", + "babel-core": "^6.22.1", + "babel-eslint": "^7.1.1", + "babel-plugin-add-module-exports": "^0.2.1", + "babel-preset-es2015": "^6.22.0", + "babel-preset-stage-2": "^6.22.0", + "body-parser": "^1.15.2", + "express": "^4.14.0", + "graphql": "^0.9.1", + "graphql-server-express": "^0.6.0", + "graphql-subscriptions": "^0.3.0", + "graphql-tools": "^0.10.0", + "subscriptions-transport-ws": "^0.5.1", + "whatwg-fetch": "^2.0.2" + }, + "devDependencies": { + "eslint": "^3.15.0", + "eslint-config-airbnb": "^14.1.0", + "eslint-import-resolver-meteor": "^0.3.4", + "eslint-plugin-import": "^2.2.0", + "eslint-plugin-jsx-a11y": "^4.0.0", + "eslint-plugin-react": "^6.9.0" + } +} diff --git a/tests/client.js b/tests/client.js index 24fd71a..dd10fec 100644 --- a/tests/client.js +++ b/tests/client.js @@ -1,11 +1,103 @@ import { assert } from 'meteor/practicalmeteor:chai'; import { createMeteorNetworkInterface } from 'meteor/apollo'; +import gql from 'graphql-tag'; +import { print } from 'graphql-tag/printer'; +import 'whatwg-fetch'; -describe('client', function() { +// Some helper queries + results +const authorQuery = gql` + query { + author { + firstName + lastName + } + }`; - it('works', function() { - assert.ok(createMeteorNetworkInterface()); +const authorResult = { + data: { + author: { + firstName: 'John', + lastName: 'Smith', + }, + }, +}; + +const personQuery = gql` + query { + person { + name + } + }`; + +const personResult = { + data: { + person: { + name: 'John Smith', + }, + }, +}; + +describe('Network interface', function() { + + it('should create a network interface', function() { + assert.ok(createMeteorNetworkInterface({batchingInterface: false})); + }); + +}); + +describe('Batching network interface', function() { + + // from apollo-client/src/transport/networkInterface + const printRequest = request => ({...request, query: print(request.query)}); + + // from apollo-client/test + // Helper method that tests a roundtrip given a particular set of requests to the + // batched network interface + const assertRoundtrip = ({ + requestResultPairs, + opts = {}, + }) => { + const batchedNetworkInterface = createMeteorNetworkInterface({ + batchingInterface: true, + opts + }); + + const printedRequests = []; + const resultList = []; + requestResultPairs.forEach(({ request, result }) => { + printedRequests.push(printRequest(request)); + resultList.push(result); + }); + + return batchedNetworkInterface.batchQuery(requestResultPairs.map(({ request }) => request)) + .then((results) => { + assert.deepEqual(results, resultList); + }); + }; + + it('should create a batching interface & correctly return the result for a single request', () => { + return assertRoundtrip({ + requestResultPairs: [{ + request: { query: authorQuery }, + result: authorResult, + }], + }); + }); + + it('should should create a batching interface & correctly return the results for multiple requests', () => { + return assertRoundtrip({ + requestResultPairs: [ + { + request: { query: authorQuery }, + result: authorResult, + }, + { + request: { query: personQuery }, + result: personResult, + }, + ], + }); }); }); diff --git a/tests/server.js b/tests/server.js index 1efc010..b66afa6 100644 --- a/tests/server.js +++ b/tests/server.js @@ -1,12 +1,56 @@ import { assert } from 'meteor/practicalmeteor:chai'; - +import { HTTP } from 'meteor/http'; import { createApolloServer } from 'meteor/apollo'; -describe('server', function() { +import { makeExecutableSchema } from 'graphql-tools'; - it('works', function() { - assert.ok(createApolloServer()); +describe('Graphql Server', function() { + + // create schema + const typeDefs = [` + type Query { + test(who: String): String + author: Author + person: Person + } + + type Author { + firstName: String + lastName: String + } + + type Person { + name: String + } + `]; + + const resolvers = { + Query: { + test: (root, { who }) => `Hello ${who}`, + author: __ => ({firstName: 'John', lastName: 'Smith'}), + person: __ => ({name: 'John Smith'}), + } + }; + + const schema = makeExecutableSchema({ typeDefs, resolvers, }); + + it('should create an express graphql server accepting a test query', async function() { + + // instantiate the apollo server + const apolloServer = createApolloServer({ schema, }); + + // send a query to the server + const { data: queryResult } = await HTTP.post(Meteor.absoluteUrl('/graphql'), { + data: { query: '{ test(who: "World") }' } + }); + + expect(queryResult).to.deep.equal({ + data: { + test: 'Hello World' + } + }); + }); - + }); diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..a62ea5d --- /dev/null +++ b/yarn.lock @@ -0,0 +1,438 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@types/async@^2.0.31": + version "2.0.38" + resolved "https://registry.yarnpkg.com/@types/async/-/async-2.0.38.tgz#5c369dcb14788da0621daafa8594a053b0edcb21" + +"@types/express-serve-static-core@*": + version "4.0.40" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.0.40.tgz#168e82978bffc81ee7737bc60728d64733a4f37b" + dependencies: + "@types/node" "*" + +"@types/express@^4.0.35": + version "4.0.35" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.0.35.tgz#6267c7b60a51fac473467b3c4a02cd1e441805fe" + dependencies: + "@types/express-serve-static-core" "*" + "@types/serve-static" "*" + +"@types/graphql@^0.8.0", "@types/graphql@^0.8.5", "@types/graphql@^0.8.6": + version "0.8.6" + resolved "https://registry.yarnpkg.com/@types/graphql/-/graphql-0.8.6.tgz#b34fb880493ba835b0c067024ee70130d6f9bb68" + +"@types/isomorphic-fetch@0.0.30": + version "0.0.30" + resolved "https://registry.yarnpkg.com/@types/isomorphic-fetch/-/isomorphic-fetch-0.0.30.tgz#a21717624cde9a48c2db53a4e500fc5c32a99bbc" + +"@types/mime@*": + version "0.0.29" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-0.0.29.tgz#fbcfd330573b912ef59eeee14602bface630754b" + +"@types/node@*": + version "7.0.5" + resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.5.tgz#96a0f0a618b7b606f1ec547403c00650210bfbb7" + +"@types/serve-static@*": + version "1.7.31" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.7.31.tgz#15456de8d98d6b4cff31be6c6af7492ae63f521a" + dependencies: + "@types/express-serve-static-core" "*" + "@types/mime" "*" + +accepts@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.3.tgz#c3ca7434938648c3e0d9c1e328dd68b622c284ca" + dependencies: + mime-types "~2.1.11" + negotiator "0.6.1" + +apollo-client@^0.7.3: + version "0.7.3" + resolved "https://registry.yarnpkg.com/apollo-client/-/apollo-client-0.7.3.tgz#f27702409ce4b90c3adbd78d8434c3e8d762c7dd" + dependencies: + graphql-anywhere "^2.0.0" + graphql-tag "^1.1.1" + redux "^3.4.0" + symbol-observable "^1.0.2" + whatwg-fetch "^2.0.0" + optionalDependencies: + "@types/async" "^2.0.31" + "@types/graphql" "^0.8.0" + "@types/isomorphic-fetch" "0.0.30" + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + +body-parser@^1.15.2: + version "1.16.0" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.16.0.tgz#924a5e472c6229fb9d69b85a20d5f2532dec788b" + dependencies: + bytes "2.4.0" + content-type "~1.0.2" + debug "2.6.0" + depd "~1.1.0" + http-errors "~1.5.1" + iconv-lite "0.4.15" + on-finished "~2.3.0" + qs "6.2.1" + raw-body "~2.2.0" + type-is "~1.6.14" + +bytes@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-2.4.0.tgz#7d97196f9d5baf7f6935e25985549edd2a6c2339" + +content-disposition@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" + +content-type@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.2.tgz#b7d113aee7a8dd27bd21133c4dc2529df1721eed" + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + +cookie@0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" + +debug@2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.0.tgz#bc596bcabe7617f11d9fa15361eded5608b8499b" + dependencies: + ms "0.7.2" + +debug@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" + dependencies: + ms "0.7.1" + +depd@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.0.tgz#e1bd82c6aab6ced965b97b88b17ed3e528ca18c3" + +deprecated-decorator@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/deprecated-decorator/-/deprecated-decorator-0.1.6.tgz#00966317b7a12fe92f3cc831f7583af329b86c37" + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + +encodeurl@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.1.tgz#79e3d58655346909fe6f0f45a5de68103b294d20" + +es6-shim@^0.35.3: + version "0.35.3" + resolved "https://registry.yarnpkg.com/es6-shim/-/es6-shim-0.35.3.tgz#9bfb7363feffff87a6cdb6cd93e405ec3c4b6f26" + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + +etag@~1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.7.0.tgz#03d30b5f67dd6e632d2945d30d6652731a34d5d8" + +express@^4.14.0: + version "4.14.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.14.1.tgz#646c237f766f148c2120aff073817b9e4d7e0d33" + dependencies: + accepts "~1.3.3" + array-flatten "1.1.1" + content-disposition "0.5.2" + content-type "~1.0.2" + cookie "0.3.1" + cookie-signature "1.0.6" + debug "~2.2.0" + depd "~1.1.0" + encodeurl "~1.0.1" + escape-html "~1.0.3" + etag "~1.7.0" + finalhandler "0.5.1" + fresh "0.3.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.1" + path-to-regexp "0.1.7" + proxy-addr "~1.1.3" + qs "6.2.0" + range-parser "~1.2.0" + send "0.14.2" + serve-static "~1.11.2" + type-is "~1.6.14" + utils-merge "1.0.0" + vary "~1.1.0" + +finalhandler@0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-0.5.1.tgz#2c400d8d4530935bc232549c5fa385ec07de6fcd" + dependencies: + debug "~2.2.0" + escape-html "~1.0.3" + on-finished "~2.3.0" + statuses "~1.3.1" + unpipe "~1.0.0" + +forwarded@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.0.tgz#19ef9874c4ae1c297bcf078fde63a09b66a84363" + +fresh@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.3.0.tgz#651f838e22424e7566de161d8358caa199f83d4f" + +graphql-anywhere@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/graphql-anywhere/-/graphql-anywhere-2.2.0.tgz#652c3fa23a4a6cfeb98817512fb48100b97f3d5c" + +graphql-server-core@^0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/graphql-server-core/-/graphql-server-core-0.5.2.tgz#7e23fc516cb754e42c16f92928b595c354d6c8a7" + dependencies: + es6-shim "^0.35.3" + optionalDependencies: + "@types/graphql" "^0.8.5" + +graphql-server-express@^0.5.0: + version "0.5.2" + resolved "https://registry.yarnpkg.com/graphql-server-express/-/graphql-server-express-0.5.2.tgz#c358110ddb2f82939b4d4c9d97ffb5afded7944a" + dependencies: + graphql-server-core "^0.5.2" + graphql-server-module-graphiql "^0.5.2" + optionalDependencies: + "@types/express" "^4.0.35" + "@types/graphql" "^0.8.6" + +graphql-server-module-graphiql@^0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/graphql-server-module-graphiql/-/graphql-server-module-graphiql-0.5.2.tgz#7e2a0c78b0267e784f8483ce5633810baf558dee" + +graphql-tag@^1.1.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-1.2.4.tgz#90c59bea41378513fd7213dc92537fcd20e4570f" + +graphql-tools@^0.9.0: + version "0.9.2" + resolved "https://registry.yarnpkg.com/graphql-tools/-/graphql-tools-0.9.2.tgz#c3f42d0b78d2d6c57cea5ef2894863de34af9a11" + dependencies: + deprecated-decorator "^0.1.6" + lodash "^4.3.0" + uuid "^3.0.1" + optionalDependencies: + "@types/graphql" "^0.8.5" + +graphql@^0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/graphql/-/graphql-0.8.2.tgz#eb1bb524b38104bbf2c9157f9abc67db2feba7d2" + dependencies: + iterall "1.0.2" + +http-errors@~1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.5.1.tgz#788c0d2c1de2c81b9e6e8c01843b6b97eb920750" + dependencies: + inherits "2.0.3" + setprototypeof "1.0.2" + statuses ">= 1.3.1 < 2" + +iconv-lite@0.4.15: + version "0.4.15" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.15.tgz#fe265a218ac6a57cfe854927e9d04c19825eddeb" + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + +ipaddr.js@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.2.0.tgz#8aba49c9192799585bdd643e0ccb50e8ae777ba4" + +iterall@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.0.2.tgz#41a2e96ce9eda5e61c767ee5dc312373bb046e91" + +js-tokens@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.1.tgz#08e9f132484a2c45a30907e9dc4d5567b7f114d7" + +lodash-es@^4.2.1: + version "4.17.4" + resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.4.tgz#dcc1d7552e150a0640073ba9cb31d70f032950e7" + +lodash@^4.2.1, lodash@^4.3.0: + version "4.17.4" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" + +loose-envify@^1.1.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" + dependencies: + js-tokens "^3.0.0" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + +mime-db@~1.26.0: + version "1.26.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.26.0.tgz#eaffcd0e4fc6935cf8134da246e2e6c35305adff" + +mime-types@~2.1.11, mime-types@~2.1.13: + version "2.1.14" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.14.tgz#f7ef7d97583fcaf3b7d282b6f8b5679dab1e94ee" + dependencies: + mime-db "~1.26.0" + +mime@1.3.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.4.tgz#115f9e3b6b3daf2959983cb38f149a2d40eb5d53" + +ms@0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098" + +ms@0.7.2: + version "0.7.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.2.tgz#ae25cf2512b3885a1d95d7f037868d8431124765" + +negotiator@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + dependencies: + ee-first "1.1.1" + +parseurl@~1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.1.tgz#c8ab8c9223ba34888aa64a297b28853bec18da56" + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + +proxy-addr@~1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-1.1.3.tgz#dc97502f5722e888467b3fa2297a7b1ff47df074" + dependencies: + forwarded "~0.1.0" + ipaddr.js "1.2.0" + +qs@6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.2.0.tgz#3b7848c03c2dece69a9522b0fae8c4126d745f3b" + +qs@6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.2.1.tgz#ce03c5ff0935bc1d9d69a9f14cbd18e568d67625" + +range-parser@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" + +raw-body@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.2.0.tgz#994976cf6a5096a41162840492f0bdc5d6e7fb96" + dependencies: + bytes "2.4.0" + iconv-lite "0.4.15" + unpipe "1.0.0" + +redux@^3.4.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/redux/-/redux-3.6.0.tgz#887c2b3d0b9bd86eca2be70571c27654c19e188d" + dependencies: + lodash "^4.2.1" + lodash-es "^4.2.1" + loose-envify "^1.1.0" + symbol-observable "^1.0.2" + +send@0.14.2: + version "0.14.2" + resolved "https://registry.yarnpkg.com/send/-/send-0.14.2.tgz#39b0438b3f510be5dc6f667a11f71689368cdeef" + dependencies: + debug "~2.2.0" + depd "~1.1.0" + destroy "~1.0.4" + encodeurl "~1.0.1" + escape-html "~1.0.3" + etag "~1.7.0" + fresh "0.3.0" + http-errors "~1.5.1" + mime "1.3.4" + ms "0.7.2" + on-finished "~2.3.0" + range-parser "~1.2.0" + statuses "~1.3.1" + +serve-static@~1.11.2: + version "1.11.2" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.11.2.tgz#2cf9889bd4435a320cc36895c9aa57bd662e6ac7" + dependencies: + encodeurl "~1.0.1" + escape-html "~1.0.3" + parseurl "~1.3.1" + send "0.14.2" + +setprototypeof@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.2.tgz#81a552141ec104b88e89ce383103ad5c66564d08" + +"statuses@>= 1.3.1 < 2", statuses@~1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" + +symbol-observable@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.4.tgz#29bf615d4aa7121bdd898b22d4b3f9bc4e2aa03d" + +type-is@~1.6.14: + version "1.6.14" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.14.tgz#e219639c17ded1ca0789092dd54a03826b817cb2" + dependencies: + media-typer "0.3.0" + mime-types "~2.1.13" + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + +utils-merge@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.0.tgz#0294fb922bb9375153541c4f7096231f287c8af8" + +uuid@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1" + +vary@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.0.tgz#e1e5affbbd16ae768dd2674394b9ad3022653140" + +whatwg-fetch@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.2.tgz#fe294d1d89e36c5be8b3195057f2e4bc74fc980e"