Skip to content

Commit

Permalink
Squashed 'app/packages/meteor-integration/' content from commit d5bee6f
Browse files Browse the repository at this point in the history
git-subtree-dir: app/packages/meteor-integration
git-subtree-split: d5bee6f274d01f72f4c6a88d866e78a00e2f965e
  • Loading branch information
cdmbase committed Jan 6, 2017
0 parents commit 55c3ac2
Show file tree
Hide file tree
Showing 9 changed files with 439 additions and 0 deletions.
71 changes: 71 additions & 0 deletions .versions
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
accounts-base@1.2.9
allow-deny@1.0.5
apollo@0.2.0
autoupdate@1.2.11
babel-compiler@6.9.0
babel-runtime@0.1.10
base64@1.0.9
binary-heap@1.0.9
blaze@2.1.8
blaze-tools@1.0.9
boilerplate-generator@1.0.9
caching-compiler@1.0.6
caching-html-compiler@1.0.6
callback-hook@1.0.9
check@1.2.3
coffeescript@1.1.3
ddp@1.2.5
ddp-client@1.2.9
ddp-common@1.2.6
ddp-rate-limiter@1.0.5
ddp-server@1.2.9
deps@1.0.12
diff-sequence@1.0.6
ecmascript@0.5.7
ecmascript-runtime@0.3.12
ejson@1.0.12
geojson-utils@1.0.9
html-tools@1.0.10
htmljs@1.0.10
http@1.1.8
id-map@1.0.8
jquery@1.11.9
local-test:apollo@0.2.0
localstorage@1.0.11
logging@1.1.14
meteor@1.2.16
minifier-js@1.1.13
minimongo@1.0.17
modules@0.7.5
modules-runtime@0.7.5
mongo@1.1.10
mongo-id@1.0.5
npm-mongo@1.5.45
observe-sequence@1.0.12
ordered-dict@1.0.8
practicalmeteor:chai@2.1.0_1
practicalmeteor:loglevel@1.2.0_2
practicalmeteor:mocha@2.1.0_7
practicalmeteor:mocha-core@0.1.4
practicalmeteor:sinon@1.14.1_2
promise@0.8.3
random@1.0.10
rate-limit@1.0.5
reactive-dict@1.1.8
reactive-var@1.0.10
reload@1.1.10
retry@1.0.8
routepolicy@1.0.11
service-configuration@1.0.10
session@1.1.6
spacebars@1.0.12
spacebars-compiler@1.0.12
templating@1.1.13
templating-tools@1.0.4
tmeasday:check-npm-versions@0.3.1
tracker@1.1.0
ui@1.0.11
underscore@1.0.9
url@1.0.10
webapp@1.3.10
webapp-hashing@1.0.9
50 changes: 50 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Change Log
All notable changes to this project will be documented in this file. [*File syntax*](http://keepachangelog.com/).
This project adheres to [Semantic Versioning](http://semver.org/).

## vNEXT

## [0.2.1] - 2016-12-23
### Added

- Support for `v0.8.x` of `graphql` [#54](https://github.com/apollostack/meteor-integration/pull/54)
- When user is not logged in, provide `{}` as context [#55](https://github.com/apollostack/meteor-integration/pull/55)

## [0.2.0] - 2016-11-04
### Updated

- `apollo-client` [v0.5.x](https://github.com/apollostack/apollo-client/blob/master/CHANGELOG.md#v050)
- Updated createNetworkInterface call to match new signature ([@jasonphillips](https://github.com/jasonphillips) in [#43](https://github.com/apollostack/meteor-integration/pull/43)).
- `graphql-server` [v0.4.2](https://github.com/apollostack/graphql-server/blob/master/CHANGELOG.md#v042)

### Added

- Added the logged-in user's doc to `context.user`

## [0.1.2] - 2016-10-04
### Added

- Pass a function to configure the express server in createApolloServer ([@nicolaslopezj](https://github.com/nicolaslopezj) in [#32](https://github.com/apollostack/meteor-integration/pull/32)).
- Automatically pass Meteor authentication in GraphiQL ([@nicolaslopezj](https://github.com/nicolaslopezj) in [#35](https://github.com/apollostack/meteor-integration/pull/35)).

## [0.1.1] - 2016-09-21
### Fixed

- Fix userId persisting in options.context (reported in [#37](https://github.com/apollostack/meteor-integration/pull/37))

## [0.1.0] - 2016-09-09
### Updated

- `apollo-server` [v0.2.x](https://github.com/apollostack/apollo-server/blob/cc15ebfb1c9637989e09976c8416b4fd5c2b6728/CHANGELOG.md)
- Updated interface to reflect `apollo-server` refactor.
- `apollo-client` [v0.4.x](https://github.com/apollostack/apollo-client/blob/master/CHANGELOG.md#v040)

## [0.0.4] - 2016-08-24
### Fixed

- Fixed global auth issue

## [0.0.2] - 2016-06-17
### Fixed

- Fix dependencies #17
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
Use the [Apollo Stack](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
```

## Credits

[Contributors](https://github.com/apollostack/meteor-integration/graphs/contributors)
19 changes: 19 additions & 0 deletions check-npm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Meteor } from 'meteor/meteor';
import { checkNpmVersions } from 'meteor/tmeasday:check-npm-versions';

if (Meteor.isClient) {
checkNpmVersions({
'apollo-client': '^0.5.0',
}, 'apollo');
} else {
checkNpmVersions({
'graphql-server-express': '^0.4.3',
"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"
}, 'apollo');
}
98 changes: 98 additions & 0 deletions main-client.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import './check-npm.js';

import { createNetworkInterface } from 'apollo-client';
import { Accounts } from 'meteor/accounts-base';
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,
};

const getDefaultWsClient = () => new Client('ws://localhost:8080');

export const createMeteorNetworkInterface = (givenConfig) => {
const config = _.extend(defaultNetworkInterfaceConfig, givenConfig);
const wsClient = givenConfig && givenConfig.wsClient ? givenConfig.wsClient : getDefaultWsClient();
// absoluteUrl adds a '/', so let's remove it first
let path = config.path;
if (path[0] === '/') {
path = path.slice(1);
}

// For SSR
const uri = Meteor.absoluteUrl(path);
const networkInterface = createNetworkInterface({ uri });

if (config.useMeteorAccounts) {
networkInterface.use([{
applyMiddleware(request, next) {
const currentUserToken = Accounts._storedLoginToken() ? Accounts._storedLoginToken() : null;

if (!currentUserToken) {
next();
return;
}

if (!request.options.headers) {
request.options.headers = new Headers();
}

request.options.headers.Authorization = currentUserToken;

next();
},
}]);
}

if (config.useSubscription) {
return _.extend(networkInterface, {
subscribe: (request, handler) => wsClient.subscribe({
query: print(request.query),
variables: request.variables,
}, handler),
unsubscribe: (id) => {
wsClient.unsubscribe(id);
},
});
}
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;
if(initialState){
// Temporary workaround for bug in AC@0.5.0: https://github.com/apollostack/apollo-client/issues/845
delete initialState.apollo.queries;
delete initialState.apollo.mutations;
}

return {
networkInterface,
initialState,
// 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;
},
};
};
124 changes: 124 additions & 0 deletions main-server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import './check-npm.js';

import { graphqlExpress, graphiqlExpress } from 'graphql-server-express';
import bodyParser from 'body-parser';
import express from 'express';
import { createServer } from 'http';
import { Meteor } from 'meteor/meteor';
import { WebApp } from 'meteor/webapp';
import { check } from 'meteor/check';
import { Accounts } from 'meteor/accounts-base';
import { _ } from 'meteor/underscore';
import { SubscriptionServer } from 'subscriptions-transport-ws';

export { meteorClientConfig, createMeteorNetworkInterface } from './main-client';

const defaultConfig = {
path: '/graphql',
maxAccountsCacheSizeInMB: 1,
graphiql : Meteor.isDevelopment,
graphiqlPath : '/graphiql',
graphiqlOptions : {
passHeader : "'Authorization': localStorage['Meteor.loginToken']"
},
useSubscription: true,
subscriptionPort: 8080,
configServer: (graphQLServer) => {},
};

const defaultOptions = {
formatError: e => ({
message: e.message,
locations: e.locations,
path: e.path
}),
};

if (Meteor.isDevelopment) {
defaultOptions.debug = true;
}

export const createApolloServer = (givenOptions = {}, givenConfig = {}) => {
const { subscriptionManager, ...restOfConfig } = givenConfig;
let graphiqlOptions = Object.assign({}, defaultConfig.graphiqlOptions, restOfConfig.graphiqlOptions);
let config = Object.assign({}, defaultConfig, restOfConfig);
config.graphiqlOptions = graphiqlOptions;

const graphQLServer = express();

config.configServer(graphQLServer)

// GraphQL endpoint
graphQLServer.use(config.path, bodyParser.json(), graphqlExpress(async (req) => {
let options,
user = null;

if (_.isFunction(givenOptions))
options = givenOptions(req);
else
options = givenOptions;

// Merge in the defaults
options = Object.assign({}, defaultOptions, options);
if (options.context) {
// don't mutate the context provided in options
options.context = Object.assign({}, options.context);
} else {
options.context = {};
}

// Get the token from the header
if (req.headers.authorization) {
const token = req.headers.authorization;
check(token, String);
const hashedToken = Accounts._hashLoginToken(token);

// Get the user from the database
user = await Meteor.users.findOne(
{"services.resume.loginTokens.hashedToken": hashedToken}
);

if (user) {
const loginToken = _.findWhere(user.services.resume.loginTokens, { hashedToken });
const expiresAt = Accounts._tokenExpiration(loginToken.when);
const isExpired = expiresAt < new Date();

if (!isExpired) {
options.context.userId = user._id;
options.context.user = user;
}
}
}

return options;

}));

// Start GraphiQL if enabled
if (config.graphiql) {
graphQLServer.use(config.graphiqlPath, graphiqlExpress(_.extend(config.graphiqlOptions, {endpointURL : config.path})));
}

// create http server for subscription
const server = createServer(graphQLServer);

// This binds the specified paths to the Express server running Apollo + GraphiQL
WebApp.connectHandlers.use(Meteor.bindEnvironment(graphQLServer));

// Add subscriptionManager here
if (config.useSubscription) {
if (!subscriptionManager) {
throw new Meteor.Error('SubscriptionManager which is mandatory missing.');
}
new SubscriptionServer({
subscriptionManager,
}, server);
try {
server.listen(config.subscriptionPort, () => {
console.log('Subscription manager running ' + config.subscriptionPort);
});
} catch (e) {
console.log(e);
}
}
};
Loading

0 comments on commit 55c3ac2

Please sign in to comment.