<commit_before>// Staging config. Also the default config that prod and dev are based off of.

const ExtractTextPlugin = require('extract-text-webpack-plugin');
const ManifestPlugin = require('webpack-manifest-plugin');
const bourbon = require('bourbon').includePaths;
const neat = require('bourbon-neat').includePaths;
const path = require('path');
const webpack = require('webpack');
const _ = require('lodash');

require('babel-polyfill');

const entryFiles = {
  'disability-benefits': './src/js/disability-benefits/disability-benefits-entry.jsx',
  'edu-benefits': './src/js/edu-benefits/edu-benefits-entry.jsx',
  facilities: './src/js/facility-locator/facility-locator-entry.jsx',
  hca: './src/js/hca/hca-entry.jsx',
  messaging: './src/js/messaging/messaging-entry.jsx',
  rx: './src/js/rx/rx-entry.jsx',
  'no-react': './src/js/no-react-entry.js',
  'user-profile': './src/js/user-profile/user-profile-entry.jsx',
  auth: './src/js/auth/auth-entry.jsx'
};

const configGenerator = (options) => {
  var filesToBuild = entryFiles; // eslint-disable-line no-var
  if (options.entry) {
    filesToBuild = _.pick(entryFiles, options.entry.split(',').map(x => x.trim()));
  }
  filesToBuild['vendor'] = [
    'core-js',
    'history',
    'lodash',
    'jquery',
    'react',
    'react-dom',
    'react-redux',
    'react-router',
    'redux',
    'redux-thunk'
  ];
  const baseConfig = {
    entry: filesToBuild,
    output: {
      path: path.join(__dirname, `../build/${options.buildtype}/generated`),
      publicPath: '/generated/',
      filename: (options.buildtype === 'development') ? '[name].entry.js' : '[name].entry.[chunkhash].js'
    },
    module: {
      loaders: [
        {
          test: /\.js$/,
          exclude: /node_modules/,
          loader: 'babel',
          query: {
            // Speed up compilation.
            cacheDirectory: '.babelcache'

            // Also see .babelrc
          }
        },
        {
          test: /\.jsx$/,
          exclude: /node_modules/,
          loader: 'babel',
          query: {
            presets: ['react'],
            // Speed up compilation.
            cacheDirectory: '.babelcache'

            // Also see .babelrc
          }
        },
        {
          // components.js is effectively a hand-rolled bundle.js. Break it apart.
          test: /components\.js$/,
          loader: 'imports?this=>window'
        },
        {
          test: /foundation\.js$/,
          loader: 'imports?this=>window'
        },
        {
          test: /modernizrrc/,
          loader: 'modernizr'
        },
        {
          test: /\.scss$/,
          loader: ExtractTextPlugin.extract('style-loader', `css!resolve-url!sass?includePaths[]=${bourbon}&includePaths[]=${neat}&includePaths[]=~/uswds/src/stylesheets&sourceMap`)
        },
        {
          test: /\.(jpe?g|png|gif)$/i,
          loader: 'url?limit=10000!img?progressive=true&-minimize'
        },
        {
          test: /\.svg/,
          loader: 'svg-url'
        },
        {
          test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
          loader: 'url-loader?limit=10000&minetype=application/font-woff'
        },
        {
          test: /\.(ttf|eot)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
          loader: 'file-loader'
        }
      ],
      noParse: [/mapbox\/vendor\/promise.js$/],
    },
    resolve: {
      alias: {
        modernizr$: path.resolve(__dirname, './modernizrrc'),
        jquery: 'jquery/src/jquery'
      },
      extensions: ['', '.js', '.jsx']
    },
    plugins: [
      new webpack.DefinePlugin({
        __BUILDTYPE__: JSON.stringify(options.buildtype),
        __ALL_CLAIMS_ENABLED__: (options.buildtype === 'development' || process.env.ALL_CLAIMS_ENABLED === 'true'),
        __SAMPLE_ENABLED__: (process.env.SAMPLE_ENABLED === 'true'),
        'process.env': {
          NODE_ENV: JSON.stringify(process.env.NODE_ENV || 'development'),
          API_PORT: (process.env.API_PORT || 4000),
          WEB_PORT: (process.env.WEB_PORT || 3333),
        }
      }),

      // See http://stackoverflow.com/questions/28969861/managing-jquery-plugin-dependency-in-webpack
      new webpack.ProvidePlugin({
        $: 'jquery',
        jQuery: 'jquery',
        'window.jQuery': 'jquery'
      }),

      new ExtractTextPlugin((options.buildtype === 'development') ? '[name].css' : '[name].[chunkhash].css'),
      new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
      new ManifestPlugin({
        fileName: 'file-manifest.json'
      }),
      new webpack.optimize.CommonsChunkPlugin(
        'vendor',
        (options.buildtype === 'development') ? 'vendor.js' : 'vendor.[chunkhash].js'
      )
    ],
  };

  if (options.buildtype === 'production' || options.buildtype === 'staging') {
    baseConfig.devtool = '#source-map';
    baseConfig.module.loaders.push({
      test: /debug\/PopulateVeteranButton/,
      loader: 'null'
    });
    baseConfig.module.loaders.push({
      test: /debug\/PerfPanel/,
      loader: 'null'
    });
    baseConfig.module.loaders.push({
      test: /debug\/RoutesDropdown/,
      loader: 'null'
    });

    baseConfig.plugins.push(new webpack.optimize.DedupePlugin());
    baseConfig.plugins.push(new webpack.optimize.OccurrenceOrderPlugin(true));
    baseConfig.plugins.push(new webpack.optimize.UglifyJsPlugin({
      beautify: false,
      compress: { warnings: false },
      comments: false
    }));
  } else {
    baseConfig.devtool = '#eval-source-map';
  }

  return baseConfig;
};

module.exports = configGenerator;
<commit_msg>fix linting<commit_after>// Staging config. Also the default config that prod and dev are based off of.

const ExtractTextPlugin = require('extract-text-webpack-plugin');
const ManifestPlugin = require('webpack-manifest-plugin');
const bourbon = require('bourbon').includePaths;
const neat = require('bourbon-neat').includePaths;
const path = require('path');
const webpack = require('webpack');
const _ = require('lodash');

require('babel-polyfill');

const entryFiles = {
  'disability-benefits': './src/js/disability-benefits/disability-benefits-entry.jsx',
  'edu-benefits': './src/js/edu-benefits/edu-benefits-entry.jsx',
  facilities: './src/js/facility-locator/facility-locator-entry.jsx',
  hca: './src/js/hca/hca-entry.jsx',
  messaging: './src/js/messaging/messaging-entry.jsx',
  rx: './src/js/rx/rx-entry.jsx',
  'no-react': './src/js/no-react-entry.js',
  'user-profile': './src/js/user-profile/user-profile-entry.jsx',
  auth: './src/js/auth/auth-entry.jsx'
};

const configGenerator = (options) => {
  var filesToBuild = entryFiles; // eslint-disable-line no-var
  if (options.entry) {
    filesToBuild = _.pick(entryFiles, options.entry.split(',').map(x => x.trim()));
  }
  filesToBuild.vendor = [
    'core-js',
    'history',
    'lodash',
    'jquery',
    'react',
    'react-dom',
    'react-redux',
    'react-router',
    'redux',
    'redux-thunk'
  ];
  const baseConfig = {
    entry: filesToBuild,
    output: {
      path: path.join(__dirname, `../build/${options.buildtype}/generated`),
      publicPath: '/generated/',
      filename: (options.buildtype === 'development') ? '[name].entry.js' : '[name].entry.[chunkhash].js'
    },
    module: {
      loaders: [
        {
          test: /\.js$/,
          exclude: /node_modules/,
          loader: 'babel',
          query: {
            // Speed up compilation.
            cacheDirectory: '.babelcache'

            // Also see .babelrc
          }
        },
        {
          test: /\.jsx$/,
          exclude: /node_modules/,
          loader: 'babel',
          query: {
            presets: ['react'],
            // Speed up compilation.
            cacheDirectory: '.babelcache'

            // Also see .babelrc
          }
        },
        {
          // components.js is effectively a hand-rolled bundle.js. Break it apart.
          test: /components\.js$/,
          loader: 'imports?this=>window'
        },
        {
          test: /foundation\.js$/,
          loader: 'imports?this=>window'
        },
        {
          test: /modernizrrc/,
          loader: 'modernizr'
        },
        {
          test: /\.scss$/,
          loader: ExtractTextPlugin.extract('style-loader', `css!resolve-url!sass?includePaths[]=${bourbon}&includePaths[]=${neat}&includePaths[]=~/uswds/src/stylesheets&sourceMap`)
        },
        {
          test: /\.(jpe?g|png|gif)$/i,
          loader: 'url?limit=10000!img?progressive=true&-minimize'
        },
        {
          test: /\.svg/,
          loader: 'svg-url'
        },
        {
          test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
          loader: 'url-loader?limit=10000&minetype=application/font-woff'
        },
        {
          test: /\.(ttf|eot)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
          loader: 'file-loader'
        }
      ],
      noParse: [/mapbox\/vendor\/promise.js$/],
    },
    resolve: {
      alias: {
        modernizr$: path.resolve(__dirname, './modernizrrc'),
        jquery: 'jquery/src/jquery'
      },
      extensions: ['', '.js', '.jsx']
    },
    plugins: [
      new webpack.DefinePlugin({
        __BUILDTYPE__: JSON.stringify(options.buildtype),
        __ALL_CLAIMS_ENABLED__: (options.buildtype === 'development' || process.env.ALL_CLAIMS_ENABLED === 'true'),
        __SAMPLE_ENABLED__: (process.env.SAMPLE_ENABLED === 'true'),
        'process.env': {
          NODE_ENV: JSON.stringify(process.env.NODE_ENV || 'development'),
          API_PORT: (process.env.API_PORT || 4000),
          WEB_PORT: (process.env.WEB_PORT || 3333),
        }
      }),

      // See http://stackoverflow.com/questions/28969861/managing-jquery-plugin-dependency-in-webpack
      new webpack.ProvidePlugin({
        $: 'jquery',
        jQuery: 'jquery',
        'window.jQuery': 'jquery'
      }),

      new ExtractTextPlugin((options.buildtype === 'development') ? '[name].css' : '[name].[chunkhash].css'),
      new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
      new ManifestPlugin({
        fileName: 'file-manifest.json'
      }),
      new webpack.optimize.CommonsChunkPlugin(
        'vendor',
        (options.buildtype === 'development') ? 'vendor.js' : 'vendor.[chunkhash].js'
      )
    ],
  };

  if (options.buildtype === 'production' || options.buildtype === 'staging') {
    baseConfig.devtool = '#source-map';
    baseConfig.module.loaders.push({
      test: /debug\/PopulateVeteranButton/,
      loader: 'null'
    });
    baseConfig.module.loaders.push({
      test: /debug\/PerfPanel/,
      loader: 'null'
    });
    baseConfig.module.loaders.push({
      test: /debug\/RoutesDropdown/,
      loader: 'null'
    });

    baseConfig.plugins.push(new webpack.optimize.DedupePlugin());
    baseConfig.plugins.push(new webpack.optimize.OccurrenceOrderPlugin(true));
    baseConfig.plugins.push(new webpack.optimize.UglifyJsPlugin({
      beautify: false,
      compress: { warnings: false },
      comments: false
    }));
  } else {
    baseConfig.devtool = '#eval-source-map';
  }

  return baseConfig;
};

module.exports = configGenerator;
<|endoftext|>


<commit_before>var secrets = require('../config/secrets');
var User = require('../models/User');
var querystring = require('querystring');
var validator = require('validator');
var async = require('async');
var cheerio = require('cheerio');
var request = require('request');
var _ = require('underscore');
var graph = require('fbgraph');
var LastFmNode = require('lastfm').LastFmNode;
var tumblr = require('tumblr.js');
var foursquare = require('node-foursquare')({ secrets: secrets.foursquare });
var Github = require('github-api');
var Twit = require('twit');
var paypal = require('paypal-rest-sdk');
var twilio = require('twilio')(secrets.twilio.sid, secrets.twilio.token);

/**
 * GET /api
 * List of API examples.
 */

exports.getApi = function(req, res) {
  res.render('api/index', {
    title: 'API Browser'
  });
};

/**
 * GET /api/foursquare
 * Foursquare API example.
 */

exports.getFoursquare = function(req, res, next) {
  var token = _.findWhere(req.user.tokens, { kind: 'foursquare' });
  async.parallel({
      trendingVenues: function(callback) {
        foursquare.Venues.getTrending('40.7222756', '-74.0022724', { limit: 50 }, token.accessToken, function(err, results) {
          callback(err, results);
        });
      },
      venueDetail: function(callback) {
        foursquare.Venues.getVenue('49da74aef964a5208b5e1fe3', token.accessToken, function(err, results) {
          callback(err, results);
        });
      },
      userCheckins: function(callback) {
        foursquare.Users.getCheckins('self', null, token.accessToken, function(err, results) {
          callback(err, results);
        });
      }
    },
    function(err, results) {
      if (err) return next(err);
      res.render('api/foursquare', {
        title: 'Foursquare API',
        trendingVenues: results.trendingVenues,
        venueDetail: results.venueDetail,
        userCheckins: results.userCheckins
      });
    });
};

/**
 * GET /api/tumblr
 * Tumblr API example.
 */

exports.getTumblr = function(req, res) {
  var token = _.findWhere(req.user.tokens, { kind: 'tumblr' });
  var client = tumblr.createClient({
    consumer_key: secrets.tumblr.consumerKey,
    consumer_secret: secrets.tumblr.consumerSecret,
    token: token.accessToken,
    token_secret: token.tokenSecret
  });
  client.posts('goddess-of-imaginary-light.tumblr.com', { type: 'photo' }, function(err, data) {
    res.render('api/tumblr', {
      title: 'Tumblr API',
      blog: data.blog,
      photoset: data.posts[0].photos
    });
  });
};

/**
 * GET /api/facebook
 * Facebook API example.
 */

exports.getFacebook = function(req, res, next) {
  var token = _.findWhere(req.user.tokens, { kind: 'facebook' });
  graph.setAccessToken(token.accessToken);
  async.parallel({
      getMe: function(done) {
        graph.get(req.user.facebook, function(err, me) {
          done(err, me);
        });
      },
      getMyFriends: function(done) {
        graph.get(req.user.facebook + '/friends', function(err, friends) {
          done(err, friends.data);
        });
      }
    },
    function(err, results) {
      if (err) return next(err);
      res.render('api/facebook', {
        title: 'Facebook API',
        me: results.getMe,
        friends: results.getMyFriends
      });
    });
};

/**
 * GET /api/scraping
 * Web scraping example using Cheerio library.
 */

exports.getScraping = function(req, res, next) {
  request.get('https://news.ycombinator.com/', function(err, request, body) {
    if (err) return next(err);
    var $ = cheerio.load(body);
    var links = [];
    $('.title a').each(function() {
      links.push($(this));
    });
    res.render('api/scraping', {
      title: 'Web Scraping',
      links: links
    });
  });
};

/**
 * GET /api/github
 * GitHub API Example.
 */
exports.getGithub = function(req, res) {
  var token = _.findWhere(req.user.tokens, { kind: 'github' });
  var github = new Github({ token: token.accessToken });
  var repo = github.getRepo('sahat', 'requirejs-library');
  repo.show(function(err, repo) {
    res.render('api/github', {
      title: 'GitHub API',
      repo: repo
    });
  });

};

/**
 * GET /api/aviary
 * Aviary image processing example.
 */

exports.getAviary = function(req, res) {
  res.render('api/aviary', {
    title: 'Aviary API'
  });
};

/**
 * GET /api/nyt
 * New York Times API example.
 */

exports.getNewYorkTimes = function(req, res, next) {
  var query = querystring.stringify({ 'api-key': secrets.nyt.key, 'list-name': 'young-adult' });
  var url = 'http://api.nytimes.com/svc/books/v2/lists?' + query;
  request.get(url, function(error, request, body) {
    if (request.statusCode === 403) return next(Error('Missing or Invalid New York Times API Key'));
    var bestsellers = JSON.parse(body);
    res.render('api/nyt', {
      title: 'New York Times API',
      books: bestsellers.results
    });
  });
};

/**
 * GET /api/lastfm
 * Last.fm API example.
 */

exports.getLastfm = function(req, res, next) {
  var lastfm = new LastFmNode(secrets.lastfm);
  async.parallel({
      artistInfo: function(done) {
        lastfm.request("artist.getInfo", {
          artist: 'Epica',
          handlers: {
            success: function(data) {
              done(null, data);
            },
            error: function(err) {
              done(err);
            }
          }
        });
      },
      artistTopAlbums: function(done) {
        lastfm.request("artist.getTopAlbums", {
          artist: 'Epica',
          handlers: {
            success: function(data) {
              var albums = [];
              _.each(data.topalbums.album, function(album) {
                albums.push(album.image.slice(-1)[0]['#text']);
              });
              done(null, albums.slice(0, 4));
            },
            error: function(err) {
              done(err);
            }
          }
        });
      }
    },
    function(err, results) {
      if (err) return next(err.message);
      var artist = {
        name: results.artistInfo.artist.name,
        image: results.artistInfo.artist.image.slice(-1)[0]['#text'],
        tags: results.artistInfo.artist.tags.tag,
        bio: results.artistInfo.artist.bio.summary,
        stats: results.artistInfo.artist.stats,
        similar: results.artistInfo.artist.similar.artist,
        topAlbums: results.artistTopAlbums
      };
      res.render('api/lastfm', {
        title: 'Last.fm API',
        artist: artist
      });
    });
};

/**
 * GET /api/twitter
 * Twiter API example.
 */

exports.getTwitter = function(req, res, next) {
  var token = _.findWhere(req.user.tokens, { kind: 'twitter' });
  var T = new Twit({
    consumer_key: secrets.twitter.consumerKey,
    consumer_secret: secrets.twitter.consumerSecret,
    access_token: token.accessToken,
    access_token_secret: token.tokenSecret
  });
  T.get('search/tweets', { q: 'hackathon since:2013-01-01', geocode: '40.71448,-74.00598,5mi', count: 50 }, function(err, reply) {
    if (err) return next(err);
    res.render('api/twitter', {
      title: 'Twitter API',
      tweets: reply.statuses
    });
  });
};

/**
 * GET /api/paypal
 * PayPal SDK example.
 */

exports.getPayPal = function(req, res, next) {
  paypal.configure(secrets.paypal);
  var payment_details = {
    'intent': 'sale',
    'payer': {
      'payment_method': 'paypal'
    },
    'redirect_urls': {
      'return_url': secrets.paypal.returnUrl,
      'cancel_url': secrets.paypal.cancelUrl
    },
    'transactions': [
      {
        'description': 'Node.js Boilerplate',
        'amount': {
          'currency': 'USD',
          'total': '2.99'
        }
      }
    ]
  };
  paypal.payment.create(payment_details, function(error, payment) {
    if (error) {
      console.log(error);
    } else {
      req.session.payment_id = payment.id;
      var links = payment.links;
      for (var i = 0; i < links.length; i++) {
        if (links[i].rel === 'approval_url') {
          res.render('api/paypal', {
            approval_url: links[i].href
          });
        }
      }
    }
  });
};

/**
 * GET /api/paypal/success
 * PayPal SDK example.
 */

exports.getPayPalSuccess = function(req, res, next) {
  var payment_id = req.session.payment_id;
  var payment_details = { 'payer_id': req.query.PayerID };
  paypal.payment.execute(payment_id, payment_details, function(error, payment) {
    if (error) {
      res.render('api/paypal', {
        result: true,
        success: false
      });
    } else {
      res.render('api/paypal', {
        result: true,
        success: true
      });
    }
  });
};

/**
 * GET /api/paypal/cancel
 * PayPal SDK example.
 */

exports.getPayPalCancel = function(req, res, next) {
  req.session.payment_id = null;
  res.render('api/paypal', {
    result: true,
    canceled: true
  });
};

/**
 * GET /api/steam
 * Steam API example.
 */

exports.getSteam = function(req, res, next) {
  var steamId = '76561197982488301';
  var query = { l: 'english', steamid: steamId, key: secrets.steam.apiKey };

  async.parallel({
    playerAchievements: function(done) {
      query.appid = '49520';
      var qs = querystring.stringify(query);
      request.get({ url: 'http://api.steampowered.com/ISteamUserStats/GetPlayerAchievements/v0001/?' + qs, json: true }, function(error, request, body) {
        if (request.statusCode === 401) return done(new Error('Missing or Invalid Steam API Key'));
        done(error, body);
      });
    },
    playerSummaries: function(done) {
      query.steamids = steamId;
      var qs = querystring.stringify(query);
      request.get({ url: 'http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?' + qs, json: true }, function(error, request, body) {
        if (request.statusCode === 401) return done(new Error('Missing or Invalid Steam API Key'));
        done(error, body);
      });
    },
    ownedGames: function(done) {
      query.include_appinfo = 1;
      query.include_played_free_games = 1;
      var qs = querystring.stringify(query);
      request.get({ url: 'http://api.steampowered.com/IPlayerService/GetOwnedGames/v0001/?' + qs, json: true }, function(error, request, body) {
        if (request.statusCode === 401) return done(new Error('Missing or Invalid Steam API Key'));
        done(error, body);
      });
    }
  },
  function(err, results) {
    if (err) return next(err);
      res.render('api/steam', {
      title: 'Steam Web API',
      ownedGames: results.ownedGames.response.games,
      playerAchievemments: results.playerAchievements.playerstats,
      playerSummary: results.playerSummaries.response.players[0]
    });
  });
};

/**
 * GET /api/twilio
 * Twilio API example.
 */

exports.getTwilio = function(req, res, next) {
  res.render('api/twilio', {
    title: 'Twilio API'
  });
};

/**
 * POST /api/twilio
 * Twilio API example.
 * @param telephone
 */

exports.postTwilio = function(req, res, next) {
  var message = {
    to: req.body.telephone,
    from: '+13472235148',
    body: 'Hello from the Hackathon Starter'
  };
  twilio.sendMessage(message, function(err, responseData) {
    if (err) return next(err.message);
    req.flash('success', { msg: 'Text sent to ' + responseData.to + '.'})
    res.redirect('/api/twilio');
  });
};

exports.getVenmo = function(req, res, next) {
  var token = _.findWhere(req.user.tokens, { kind: 'venmo' });
  var query = querystring.stringify({ access_token: token.accessToken });

  // Get profile information
  request.get({ url: 'https://api.venmo.com/v1/me?' + query, json: true }, function(err, request, body) {
    if (err) return next(err);

    res.render('api/venmo', {
      title: 'Venmo API',
      profile: body.data
    });
  });
};

exports.postVenmo = function(req, res, next) {
  req.assert('user', 'Phone, Email or Venmo User ID cannot be blank').notEmpty();
  req.assert('note', 'Please enter a message to accompany the payment').notEmpty();
  req.assert('amount', 'They amount you want to pay cannot be blank').notEmpty();

  var errors = req.validationErrors();

  if (errors) {
    req.flash('errors', errors);
    return res.redirect('/api/venmo');
  }

  var token = _.findWhere(req.user.tokens, { kind: 'venmo' });
  var formData = {
    access_token: token.accessToken,
    note: req.body.note,
    amount: req.body.amount
  };

  if (validator.isEmail(req.body.user)) {
    formData.email = req.body.user;
  } else if (validator.isLength(req.body.user, 10, 11)) {
    formData.phone = req.body.user;
  } else {
    formData.user_id = req.body.user;
  }

  // Send money
  request.post('https://api.venmo.com/v1/payments', { form: formData }, function(err, request, body) {
    if (err) return next(err);
    if (request.statusCode !== 200) {
      req.flash('errors', { msg: JSON.parse(body).error.message });
      return res.redirect('/api/venmo');
    }
    req.flash('success', 'Venmo money transfer complete');
    res.redirect('/api/venmo');
  });
};

// remove thumb css
// add venmo instructions
// update auth optional instructions<commit_msg>Add isNumeric constraint on Venmo phone validation<commit_after>var secrets = require('../config/secrets');
var User = require('../models/User');
var querystring = require('querystring');
var validator = require('validator');
var async = require('async');
var cheerio = require('cheerio');
var request = require('request');
var _ = require('underscore');
var graph = require('fbgraph');
var LastFmNode = require('lastfm').LastFmNode;
var tumblr = require('tumblr.js');
var foursquare = require('node-foursquare')({ secrets: secrets.foursquare });
var Github = require('github-api');
var Twit = require('twit');
var paypal = require('paypal-rest-sdk');
var twilio = require('twilio')(secrets.twilio.sid, secrets.twilio.token);

/**
 * GET /api
 * List of API examples.
 */

exports.getApi = function(req, res) {
  res.render('api/index', {
    title: 'API Browser'
  });
};

/**
 * GET /api/foursquare
 * Foursquare API example.
 */

exports.getFoursquare = function(req, res, next) {
  var token = _.findWhere(req.user.tokens, { kind: 'foursquare' });
  async.parallel({
      trendingVenues: function(callback) {
        foursquare.Venues.getTrending('40.7222756', '-74.0022724', { limit: 50 }, token.accessToken, function(err, results) {
          callback(err, results);
        });
      },
      venueDetail: function(callback) {
        foursquare.Venues.getVenue('49da74aef964a5208b5e1fe3', token.accessToken, function(err, results) {
          callback(err, results);
        });
      },
      userCheckins: function(callback) {
        foursquare.Users.getCheckins('self', null, token.accessToken, function(err, results) {
          callback(err, results);
        });
      }
    },
    function(err, results) {
      if (err) return next(err);
      res.render('api/foursquare', {
        title: 'Foursquare API',
        trendingVenues: results.trendingVenues,
        venueDetail: results.venueDetail,
        userCheckins: results.userCheckins
      });
    });
};

/**
 * GET /api/tumblr
 * Tumblr API example.
 */

exports.getTumblr = function(req, res) {
  var token = _.findWhere(req.user.tokens, { kind: 'tumblr' });
  var client = tumblr.createClient({
    consumer_key: secrets.tumblr.consumerKey,
    consumer_secret: secrets.tumblr.consumerSecret,
    token: token.accessToken,
    token_secret: token.tokenSecret
  });
  client.posts('goddess-of-imaginary-light.tumblr.com', { type: 'photo' }, function(err, data) {
    res.render('api/tumblr', {
      title: 'Tumblr API',
      blog: data.blog,
      photoset: data.posts[0].photos
    });
  });
};

/**
 * GET /api/facebook
 * Facebook API example.
 */

exports.getFacebook = function(req, res, next) {
  var token = _.findWhere(req.user.tokens, { kind: 'facebook' });
  graph.setAccessToken(token.accessToken);
  async.parallel({
      getMe: function(done) {
        graph.get(req.user.facebook, function(err, me) {
          done(err, me);
        });
      },
      getMyFriends: function(done) {
        graph.get(req.user.facebook + '/friends', function(err, friends) {
          done(err, friends.data);
        });
      }
    },
    function(err, results) {
      if (err) return next(err);
      res.render('api/facebook', {
        title: 'Facebook API',
        me: results.getMe,
        friends: results.getMyFriends
      });
    });
};

/**
 * GET /api/scraping
 * Web scraping example using Cheerio library.
 */

exports.getScraping = function(req, res, next) {
  request.get('https://news.ycombinator.com/', function(err, request, body) {
    if (err) return next(err);
    var $ = cheerio.load(body);
    var links = [];
    $('.title a').each(function() {
      links.push($(this));
    });
    res.render('api/scraping', {
      title: 'Web Scraping',
      links: links
    });
  });
};

/**
 * GET /api/github
 * GitHub API Example.
 */
exports.getGithub = function(req, res) {
  var token = _.findWhere(req.user.tokens, { kind: 'github' });
  var github = new Github({ token: token.accessToken });
  var repo = github.getRepo('sahat', 'requirejs-library');
  repo.show(function(err, repo) {
    res.render('api/github', {
      title: 'GitHub API',
      repo: repo
    });
  });

};

/**
 * GET /api/aviary
 * Aviary image processing example.
 */

exports.getAviary = function(req, res) {
  res.render('api/aviary', {
    title: 'Aviary API'
  });
};

/**
 * GET /api/nyt
 * New York Times API example.
 */

exports.getNewYorkTimes = function(req, res, next) {
  var query = querystring.stringify({ 'api-key': secrets.nyt.key, 'list-name': 'young-adult' });
  var url = 'http://api.nytimes.com/svc/books/v2/lists?' + query;
  request.get(url, function(error, request, body) {
    if (request.statusCode === 403) return next(Error('Missing or Invalid New York Times API Key'));
    var bestsellers = JSON.parse(body);
    res.render('api/nyt', {
      title: 'New York Times API',
      books: bestsellers.results
    });
  });
};

/**
 * GET /api/lastfm
 * Last.fm API example.
 */

exports.getLastfm = function(req, res, next) {
  var lastfm = new LastFmNode(secrets.lastfm);
  async.parallel({
      artistInfo: function(done) {
        lastfm.request("artist.getInfo", {
          artist: 'Epica',
          handlers: {
            success: function(data) {
              done(null, data);
            },
            error: function(err) {
              done(err);
            }
          }
        });
      },
      artistTopAlbums: function(done) {
        lastfm.request("artist.getTopAlbums", {
          artist: 'Epica',
          handlers: {
            success: function(data) {
              var albums = [];
              _.each(data.topalbums.album, function(album) {
                albums.push(album.image.slice(-1)[0]['#text']);
              });
              done(null, albums.slice(0, 4));
            },
            error: function(err) {
              done(err);
            }
          }
        });
      }
    },
    function(err, results) {
      if (err) return next(err.message);
      var artist = {
        name: results.artistInfo.artist.name,
        image: results.artistInfo.artist.image.slice(-1)[0]['#text'],
        tags: results.artistInfo.artist.tags.tag,
        bio: results.artistInfo.artist.bio.summary,
        stats: results.artistInfo.artist.stats,
        similar: results.artistInfo.artist.similar.artist,
        topAlbums: results.artistTopAlbums
      };
      res.render('api/lastfm', {
        title: 'Last.fm API',
        artist: artist
      });
    });
};

/**
 * GET /api/twitter
 * Twiter API example.
 */

exports.getTwitter = function(req, res, next) {
  var token = _.findWhere(req.user.tokens, { kind: 'twitter' });
  var T = new Twit({
    consumer_key: secrets.twitter.consumerKey,
    consumer_secret: secrets.twitter.consumerSecret,
    access_token: token.accessToken,
    access_token_secret: token.tokenSecret
  });
  T.get('search/tweets', { q: 'hackathon since:2013-01-01', geocode: '40.71448,-74.00598,5mi', count: 50 }, function(err, reply) {
    if (err) return next(err);
    res.render('api/twitter', {
      title: 'Twitter API',
      tweets: reply.statuses
    });
  });
};

/**
 * GET /api/paypal
 * PayPal SDK example.
 */

exports.getPayPal = function(req, res, next) {
  paypal.configure(secrets.paypal);
  var payment_details = {
    'intent': 'sale',
    'payer': {
      'payment_method': 'paypal'
    },
    'redirect_urls': {
      'return_url': secrets.paypal.returnUrl,
      'cancel_url': secrets.paypal.cancelUrl
    },
    'transactions': [
      {
        'description': 'Node.js Boilerplate',
        'amount': {
          'currency': 'USD',
          'total': '2.99'
        }
      }
    ]
  };
  paypal.payment.create(payment_details, function(error, payment) {
    if (error) {
      console.log(error);
    } else {
      req.session.payment_id = payment.id;
      var links = payment.links;
      for (var i = 0; i < links.length; i++) {
        if (links[i].rel === 'approval_url') {
          res.render('api/paypal', {
            approval_url: links[i].href
          });
        }
      }
    }
  });
};

/**
 * GET /api/paypal/success
 * PayPal SDK example.
 */

exports.getPayPalSuccess = function(req, res, next) {
  var payment_id = req.session.payment_id;
  var payment_details = { 'payer_id': req.query.PayerID };
  paypal.payment.execute(payment_id, payment_details, function(error, payment) {
    if (error) {
      res.render('api/paypal', {
        result: true,
        success: false
      });
    } else {
      res.render('api/paypal', {
        result: true,
        success: true
      });
    }
  });
};

/**
 * GET /api/paypal/cancel
 * PayPal SDK example.
 */

exports.getPayPalCancel = function(req, res, next) {
  req.session.payment_id = null;
  res.render('api/paypal', {
    result: true,
    canceled: true
  });
};

/**
 * GET /api/steam
 * Steam API example.
 */

exports.getSteam = function(req, res, next) {
  var steamId = '76561197982488301';
  var query = { l: 'english', steamid: steamId, key: secrets.steam.apiKey };

  async.parallel({
    playerAchievements: function(done) {
      query.appid = '49520';
      var qs = querystring.stringify(query);
      request.get({ url: 'http://api.steampowered.com/ISteamUserStats/GetPlayerAchievements/v0001/?' + qs, json: true }, function(error, request, body) {
        if (request.statusCode === 401) return done(new Error('Missing or Invalid Steam API Key'));
        done(error, body);
      });
    },
    playerSummaries: function(done) {
      query.steamids = steamId;
      var qs = querystring.stringify(query);
      request.get({ url: 'http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?' + qs, json: true }, function(error, request, body) {
        if (request.statusCode === 401) return done(new Error('Missing or Invalid Steam API Key'));
        done(error, body);
      });
    },
    ownedGames: function(done) {
      query.include_appinfo = 1;
      query.include_played_free_games = 1;
      var qs = querystring.stringify(query);
      request.get({ url: 'http://api.steampowered.com/IPlayerService/GetOwnedGames/v0001/?' + qs, json: true }, function(error, request, body) {
        if (request.statusCode === 401) return done(new Error('Missing or Invalid Steam API Key'));
        done(error, body);
      });
    }
  },
  function(err, results) {
    if (err) return next(err);
      res.render('api/steam', {
      title: 'Steam Web API',
      ownedGames: results.ownedGames.response.games,
      playerAchievemments: results.playerAchievements.playerstats,
      playerSummary: results.playerSummaries.response.players[0]
    });
  });
};

/**
 * GET /api/twilio
 * Twilio API example.
 */

exports.getTwilio = function(req, res, next) {
  res.render('api/twilio', {
    title: 'Twilio API'
  });
};

/**
 * POST /api/twilio
 * Twilio API example.
 * @param telephone
 */

exports.postTwilio = function(req, res, next) {
  var message = {
    to: req.body.telephone,
    from: '+13472235148',
    body: 'Hello from the Hackathon Starter'
  };
  twilio.sendMessage(message, function(err, responseData) {
    if (err) return next(err.message);
    req.flash('success', { msg: 'Text sent to ' + responseData.to + '.'})
    res.redirect('/api/twilio');
  });
};

exports.getVenmo = function(req, res, next) {
  var token = _.findWhere(req.user.tokens, { kind: 'venmo' });
  var query = querystring.stringify({ access_token: token.accessToken });

  // Get profile information
  request.get({ url: 'https://api.venmo.com/v1/me?' + query, json: true }, function(err, request, body) {
    if (err) return next(err);

    res.render('api/venmo', {
      title: 'Venmo API',
      profile: body.data
    });
  });
};

exports.postVenmo = function(req, res, next) {
  req.assert('user', 'Phone, Email or Venmo User ID cannot be blank').notEmpty();
  req.assert('note', 'Please enter a message to accompany the payment').notEmpty();
  req.assert('amount', 'They amount you want to pay cannot be blank').notEmpty();

  var errors = req.validationErrors();

  if (errors) {
    req.flash('errors', errors);
    return res.redirect('/api/venmo');
  }

  var token = _.findWhere(req.user.tokens, { kind: 'venmo' });

  var formData = {
    access_token: token.accessToken,
    note: req.body.note,
    amount: req.body.amount
  };

  if (validator.isEmail(req.body.user)) {
    formData.email = req.body.user;
  } else if (validator.isNumberic(req.body.user) &&
    validator.isLength(req.body.user, 10, 11)) {
    formData.phone = req.body.user;
  } else {
    formData.user_id = req.body.user;
  }

  // Send money
  request.post('https://sandbox-api.venmo.com/v1/payments', { form: formData }, function(err, request, body) {
    if (err) return next(err);
    if (request.statusCode !== 200) {
      req.flash('errors', { msg: JSON.parse(body).error.message });
      return res.redirect('/api/venmo');
    }
    req.flash('success', { msg: 'Venmo money transfer complete' });
    res.redirect('/api/venmo');
  });
};

// remove thumb css
// add venmo instructions
// update auth optional instructions<|endoftext|>


<commit_before>$(function() {
  $('input.better_text_field, textarea.better_text_field').focus(function() {
    // If this field contains the default value, clear the field
		if (this.value == this.defaultValue) {
      this.value = '';
    }
  });

  $(':text.better_text_field, textarea.better_text_field').blur(function() {
    // If a required field is blank, restore its default value
    if ($(this).hasClass('better_required_field') && (this.value == '')) {
      this.value = this.defaultValue;
      removeValidationOutput(this.id);
    // Else mark the field as completed
    } else {
      $(this).addClass('better_completed_field');
    }
  });

  $(':checkbox.better_validated_field').focus(validateField);
  $(':radio.better_validated_field').focus(validateField);
  $(':file.better_validated_field').change(validateField);
  $('select.better_validated_field').change(validateField);
  $(':password.better_validated_field').blur(validateField);
  $(':text.better_validated_field').blur(validateField);
  $('textarea.better_validated_field').blur(validateField);

  $(':input.better_text_field').focus(function() {
    $(this).parent('p').addClass('better_focused_field');
  });

  $(':input.better_text_field').blur(function() {
    $(this).parent('p').removeClass('better_focused_field');
  });
});

function validateField() {
  // If the field is a text_field and its value has not been changed from the default value
  if ($(this).is(':text, textarea, :password') && (this.value == this.defaultValue)) {
    return;
  }

  $.ajax({data:'authenticity_token=' + encodeURIComponent('iH4oAzNSO8OUiyFjVksfIdjEzmiWbL5BfM3mgp4rws4=')+ '&' + this.name + '=' + this.value + '&field_id=' + this.id, dataType:'script', type:'post', url: 'ajax_validate_' + this.id, async: false});
  checkFormIsCompleted(this.form);
}

function checkFormIsCompleted(form) {
  var validForm = false;
  var form = "#" + form.id;
  var validatedFields = $(form + ' input.better_validated_field');
  // For each validated field
  for (i = 0; i < validatedFields.length; i++) {
    // If any field is invalid, disable the form submit button
    if ($(validatedFields[i]).hasClass('better_invalid_field')) {
      $(form + ' :submit').disable();
      return;
		// If the field is valid, set validForm to true
    } else if ($(validatedFields[i]).hasClass('better_valid_field')) {
      validForm = true;
    }
  }
  if (validForm == true) {
    $(form + ' :submit').enable();
  }
}

function removeValidationOutput(id) {
  field = "#" + id;
  $(field).removeClass('better_invalid_field');
  $(field).removeClass('better_valid_field');
  $(field).removeClass('better_completed_field');
  $(field + " ~ .better_invalid_field").remove();
  $(field + " ~ .better_valid_field").remove();
  $(field + " ~ .better_error_message").remove();
}

function markFieldValid(id) {
  // Remove existing invalid/valid notifications
  removeValidationOutput(id);

  field = "#" + id;
  $(field + ' ~ br').before('');
  $(field).addClass('better_valid_field');
}

function markFieldInvalid(id, errorMessage) {
  // Remove existing invalid/valid notifications
  removeValidationOutput(id);

  field = "#" + id;
  $(field + ' ~ br').before('');
  $(field).addClass('better_invalid_field');
  $(field).parent('p').append('' + errorMessage + '');
}
<commit_msg>Added separate handling for validation of radio buttons - the whole group is now marked as valid<commit_after>$(function() {
  $('input.better_text_field, textarea.better_text_field').focus(function() {
    // If this field contains the default value, clear the field
		if (this.value == this.defaultValue) {
      this.value = '';
    }
  });

  $(':text.better_text_field, textarea.better_text_field').blur(function() {
    // If a required field is blank, restore its default value
    if ($(this).hasClass('better_required_field') && (this.value == '')) {
      this.value = this.defaultValue;
      removeValidationOutput(this.id);
    // Else mark the field as completed
    } else {
      $(this).addClass('better_completed_field');
    }
  });

  $(':checkbox.better_validated_field').focus(validateField);
  $(':radio.better_validated_field').focus(validateField);
  $(':file.better_validated_field').change(validateField);
  $('select.better_validated_field').change(validateField);
  $(':password.better_validated_field').blur(validateField);
  $(':text.better_validated_field').blur(validateField);
  $('textarea.better_validated_field').blur(validateField);

  $(':input.better_text_field').focus(function() {
    $(this).parent('p').addClass('better_focused_field');
  });

  $(':input.better_text_field').blur(function() {
    $(this).parent('p').removeClass('better_focused_field');
  });
});

function validateField() {
  // If the field is a text_field and its value has not been changed from the default value
  if ($(this).is(':text, textarea, :password') && (this.value == this.defaultValue)) {
    return;
  }

	// If this field is a radio button, use the associated label's `for` attribute as the method to call
	// This ensures that a group of radio buttons call the _same_ method, rather than each having a unique validation method
	// ie don't call user_plan_free or user_plan_corporate, call user_plan with the argument free or corporate
	if ($(this).is(':radio')) {
		method = $(this).prevAll("label.better_label").attr('for');
	} else {
		method = this.id;
	}

  $.ajax({data:'authenticity_token=' + encodeURIComponent('iH4oAzNSO8OUiyFjVksfIdjEzmiWbL5BfM3mgp4rws4=')+ '&' + this.name + '=' + this.value + '&field_id=' + this.id, dataType:'script', type:'post', url: 'ajax_validate_' + method, async: false});
  checkFormIsCompleted(this.form);
}

function checkFormIsCompleted(form) {
  var validForm = false;
  var form = "#" + form.id;
  var validatedFields = $(form + ' input.better_validated_field');
  // For each validated field
  for (i = 0; i < validatedFields.length; i++) {
    // If any field is invalid, disable the form submit button
    if ($(validatedFields[i]).hasClass('better_invalid_field')) {
      $(form + ' :submit').disable();
      return;
		// If the field is valid, set validForm to true
    } else if ($(validatedFields[i]).hasClass('better_valid_field')) {
      validForm = true;
    }
  }
  if (validForm == true) {
    $(form + ' :submit').enable();
  }
}

function removeValidationOutput(id) {
  field = "#" + id;
  $(field).removeClass('better_invalid_field');
  $(field).removeClass('better_valid_field');
  $(field).removeClass('better_completed_field');
  $(field).parent().children('span.better_invalid_field').remove();
  $(field).parent().children('span.better_valid_field').remove();
  $(field).parent().children('span.better_error_message').remove();
}

function markFieldValid(id) {
  // Remove existing invalid/valid notifications
  removeValidationOutput(id);

  field = "#" + id;

	// If the valid field is a radio button, add the validation output next to the group of radio buttons' label
	if ($(field).is(':radio')) {
		label = $(field).siblings('label.better_label').nextAll('br').first().before('');
	// For all other field types, add the validation output just after the field
	} else {
		$(field + ' ~ br').before('');
	}
  $(field).addClass('better_valid_field');
}

function markFieldInvalid(id, errorMessage) {
  // Remove existing invalid/valid notifications
  removeValidationOutput(id);

  field = "#" + id;
  $(field + ' ~ br').before('');
  $(field).addClass('better_invalid_field');
  $(field).parent('p').append('' + errorMessage + '');
}
<|endoftext|>


<commit_before>// Note: You must restart bin/webpack-dev-server for changes to take effect

/* eslint global-require: 0 */
/* eslint import/no-dynamic-require: 0 */

const webpack = require('webpack');
const { basename, dirname, join, resolve } = require('path');
const { sync } = require('glob');
const ManifestPlugin = require('webpack-manifest-plugin');
const extname = require('path-complete-extname');
const DuplicatePackageCheckerPlugin = require('duplicate-package-checker-webpack-plugin');
const { SplitChunksPlugin } = require('webpack').optimize;

const { env, settings, output, engines } = require('./configuration.js');
const loaders = require('./loaders.js');
const RailsEnginesPlugin = require('./RailsEnginesPlugin');

const extensionGlob = `**/*{${settings.extensions.join(',')}}*`; // */
const entryPath = join(settings.source_path, settings.source_entry_path);
const moduleDir = engines['manageiq-ui-classic'].node_modules;

const sharedPackages = [
  'jquery',
  'lodash',
  'patternfly-react',
  'patternfly-sass',
  'react',
  'react-dom',
  'prop-types',
  'graphql', // TODO remove once this gets added in manageiq-graphql
];

let packPaths = {};

Object.keys(engines).forEach(function(k) {
  let root = engines[k].root;
  let glob = join(root, entryPath, extensionGlob);
  packPaths[k] = sync(glob);
});

const nodeModulesNotShims = (module) => {
  const inNodeModules = SplitChunksPlugin.checkTest(/node_modules/, module);
  const inShims = SplitChunksPlugin.checkTest(/shims/, module);

  return inNodeModules && !inShims;
};
const notShims = (module) => (!SplitChunksPlugin.checkTest(/shims/, module));

module.exports = {
  entry: {
    ...Object.keys(packPaths).reduce(
      (map, pluginName) => {
        packPaths[pluginName].forEach(function(entry) {
          map[join(pluginName, basename(entry, extname(entry)))] = resolve(entry);
        });
        return map;
      }, {}
    ),
    'shims': [
      'es6-shim',
      'array-includes',
      'whatwg-fetch',
      'babel-polyfill',
    ],
  },

  output: {
    filename: '[name]-[chunkhash].js',
    path: output.path,
    publicPath: output.publicPath,
  },

  module: {
    rules: loaders,
  },

  plugins: [
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify(env.NODE_ENV || 'development'),
    }),

    // Workaround for graphql/graphql-language-service#128
    new webpack.ContextReplacementPlugin(
      /graphql-language-service-interface[\\\/]dist$/,
      /\.js$/
    ),

    new ManifestPlugin({
      publicPath: output.publicPath,
      writeToFileEmit: true,
    }),

    new DuplicatePackageCheckerPlugin({
      verbose: true,
      showHelp: false,
    }),
  ],

  optimization: {
    runtimeChunk: 'single',
    splitChunks: {
      minChunks: 1,
      minSize: 0,
      cacheGroups: {
        vendor: {
          chunks: 'all',
          name: 'vendor',
          priority: -10,
          reuseExistingChunk: true,
          test: nodeModulesNotShims,
        },
        default: {
          chunks: 'all',
          minChunks: 2,
          name: 'vendor',
          priority: -20,
          reuseExistingChunk: true,
          test: notShims,
        },
      },
    },
  },

  resolve: {
    alias: {
      'react': resolve(dirname(__filename), '../../node_modules', 'react'),
      'bootstrap-select': '@pf3/select',  // never use vanilla bootstrap-select
    },
    extensions: settings.extensions,
    modules: [],
    plugins: [
      new RailsEnginesPlugin('module', 'resolve', engines, { packages: sharedPackages, root: moduleDir }),
    ],
  },

  resolveLoader: {
    // only read loaders from ui-classic
    modules: [moduleDir],
  },
};
<commit_msg>alias moment to fix moment-strftime dependency<commit_after>// Note: You must restart bin/webpack-dev-server for changes to take effect

/* eslint global-require: 0 */
/* eslint import/no-dynamic-require: 0 */

const webpack = require('webpack');
const { basename, dirname, join, resolve } = require('path');
const { sync } = require('glob');
const ManifestPlugin = require('webpack-manifest-plugin');
const extname = require('path-complete-extname');
const DuplicatePackageCheckerPlugin = require('duplicate-package-checker-webpack-plugin');
const { SplitChunksPlugin } = require('webpack').optimize;

const { env, settings, output, engines } = require('./configuration.js');
const loaders = require('./loaders.js');
const RailsEnginesPlugin = require('./RailsEnginesPlugin');

const extensionGlob = `**/*{${settings.extensions.join(',')}}*`; // */
const entryPath = join(settings.source_path, settings.source_entry_path);
const moduleDir = engines['manageiq-ui-classic'].node_modules;

const sharedPackages = [
  'jquery',
  'lodash',
  'patternfly-react',
  'patternfly-sass',
  'react',
  'react-dom',
  'prop-types',
  'graphql', // TODO remove once this gets added in manageiq-graphql
];

let packPaths = {};

Object.keys(engines).forEach(function(k) {
  let root = engines[k].root;
  let glob = join(root, entryPath, extensionGlob);
  packPaths[k] = sync(glob);
});

const nodeModulesNotShims = (module) => {
  const inNodeModules = SplitChunksPlugin.checkTest(/node_modules/, module);
  const inShims = SplitChunksPlugin.checkTest(/shims/, module);

  return inNodeModules && !inShims;
};
const notShims = (module) => (!SplitChunksPlugin.checkTest(/shims/, module));

module.exports = {
  entry: {
    ...Object.keys(packPaths).reduce(
      (map, pluginName) => {
        packPaths[pluginName].forEach(function(entry) {
          map[join(pluginName, basename(entry, extname(entry)))] = resolve(entry);
        });
        return map;
      }, {}
    ),
    'shims': [
      'es6-shim',
      'array-includes',
      'whatwg-fetch',
      'babel-polyfill',
    ],
  },

  output: {
    filename: '[name]-[chunkhash].js',
    path: output.path,
    publicPath: output.publicPath,
  },

  module: {
    rules: loaders,
  },

  plugins: [
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify(env.NODE_ENV || 'development'),
    }),

    // Workaround for graphql/graphql-language-service#128
    new webpack.ContextReplacementPlugin(
      /graphql-language-service-interface[\\\/]dist$/,
      /\.js$/
    ),

    new ManifestPlugin({
      publicPath: output.publicPath,
      writeToFileEmit: true,
    }),

    new DuplicatePackageCheckerPlugin({
      verbose: true,
      showHelp: false,
    }),
  ],

  optimization: {
    runtimeChunk: 'single',
    splitChunks: {
      minChunks: 1,
      minSize: 0,
      cacheGroups: {
        vendor: {
          chunks: 'all',
          name: 'vendor',
          priority: -10,
          reuseExistingChunk: true,
          test: nodeModulesNotShims,
        },
        default: {
          chunks: 'all',
          minChunks: 2,
          name: 'vendor',
          priority: -20,
          reuseExistingChunk: true,
          test: notShims,
        },
      },
    },
  },

  resolve: {
    alias: {
      'react': resolve(dirname(__filename), '../../node_modules', 'react'),
      'bootstrap-select': '@pf3/select',  // never use vanilla bootstrap-select
      'moment': resolve(dirname(__filename), '../../node_modules', 'moment'), // fix moment-strftime peerDependency issue
    },
    extensions: settings.extensions,
    modules: [],
    plugins: [
      new RailsEnginesPlugin('module', 'resolve', engines, { packages: sharedPackages, root: moduleDir }),
    ],
  },

  resolveLoader: {
    // only read loaders from ui-classic
    modules: [moduleDir],
  },
};
<|endoftext|>


<commit_before>'use strict';

/**
* Module dependencies.
*/
const mongoose = require('mongoose');
const Game = require('../models/game');
const Score = require('../models/score');
const Team = require('../models/team');
const Player = require('../models/player');

/**
* GET /api/games/
* Get all the games
*/
exports.getGames = function getGames(req, res) {
    Game.find({}, (err, games) => {
        if (err) {
            res.status(403).send('${err}');
            return;
        }
        res.json(games);
    });
}

/**
* POST /api/games/
* Create a new game
*/
exports.postGame = function game(req, res) {
    const newGame = new Game({ teams: [], scores: [] });
    const teamIds = req.body.teams;

    if (teamIds && teamIds.length > 0) {
        var tasksToGo = teamIds.length;

        teamIds.forEach(function (id) {
            if (!mongoose.Types.ObjectId.isValid(id)) {
                if (--tasksToGo === 0) {
                    newGame.save((err, game) => {
                        if (err) {
                            res.status(403).send(`${err}`);
                            return;
                        }
                        res.status(201).send(game);
                    });
                }
                return;
            }

            Team.findById(id, (err, team) => {
                if (!err && team) {
                    // if (!newGame.teams.includes(id)) {
                    newGame.teams.push(id);
                    newGame.scores.push(new Score({ team: id }));
                    // }
                }

                if (--tasksToGo === 0) {
                    newGame.save((err, game) => {
                        if (err) {
                            res.status(403).send(`${err}`);
                            return;
                        }
                        res.status(201).send(game);
                    });
                }
            });
        });
    } else {
        newGame.save((err, game) => {
            if (err) {
                res.status(403).send(`${err}`);
                return;
            }
            res.status(201).send(game);
        });
    }
}

/**
* PUT /api/games/:gameId/addTeam
* Add teams to a game
*/
exports.addTeam = function game(req, res) {
    const gameId = req.params.gameId;

    if (!mongoose.Types.ObjectId.isValid(gameId)) {
        res.status(403).send("Invalid player id");
        return;
    }

    Game.findById(gameId, (err, game) => {
        if (err) {
            res.status(403).send(`${err}`);
            return;
        }

        if (!game) {
            res.status(403).send('No game found');
            return;
        }

        if (game.started_at) {
            res.status(403).send('Game has started cannot add a team');
            return;
        }

        const teamIds = req.body.teams;

        if (!teamIds && teamIds.length <= 0) {
            res.status(403).send('body empty');
            return;
        }

        var tasksToGo = teamIds.length;

        teamIds.forEach(function (id) {
            if (!mongoose.Types.ObjectId.isValid(id)) {
                if (--tasksToGo === 0) {
                    game.save((err, game) => {
                        if (err) {
                            res.status(403).send(`${err}`);
                            return;
                        }
                        res.status(201).send(game);
                    });
                }
                return;
            }

            Team.findById(id, (err, team) => {
                if (!err && team) {
                    // if (!game.teams.includes(id)) {
                    game.teams.push(id);
                    // }
                }

                if (--tasksToGo === 0) {
                    game.save((err, game) => {
                        if (err) {
                            res.status(403).send(`${err}`);
                            return;
                        }
                        res.status(201).send(game);
                    });
                }
            });
        });
    });
}

/**
* DELETE /api/games/:gameId
* Delete a game
*/
exports.deleteGame = function game(req, res) {
    const gameId = req.params.gameId;

    if (!mongoose.Types.ObjectId.isValid(gameId)) {
        res.status(403).send("Invalid player id");
        return;
    }

    Game.findByIdAndRemove(gameId, (err, game) => {
        if (err) {
            res.status(403).send(`${err}`);
            return;
        }

        if (!game) {
            res.status(403).send('No game found');
            return;
        }

        res.status(201).json(game);
    });
}
}

/**
* GET /api/teams
* List of teams.
*/
exports.getTeams = function get(req, res) {
    res.json({ teams: [] });
};

/**
* POST /api/teams
* Create a new team.
*/
exports.postTeam = function post(req, res) {
    res.status(201).send("Created new team");
}

/**
* POST /api/teams/:teamId
* Update a team by id.
*/
exports.putTeam = function put(req, res) {
    res.status(204).send("Updated a team");
}

/**
* POST /api/teams/:teamId
* Delete a team by id.
*/
exports.deleteTeam = function deleteTeam(req, res) {
    res.status(204).send("Deleted a team");
}
<commit_msg>Add Put to start and finish a game<commit_after>'use strict';

/**
* Module dependencies.
*/
const mongoose = require('mongoose');
const Game = require('../models/game');
const Score = require('../models/score');
const Team = require('../models/team');
const Player = require('../models/player');

/**
* GET /api/games/
* Get all the games
*/
exports.getGames = function getGames(req, res) {
    Game.find({}, (err, games) => {
        if (err) {
            res.status(403).send('${err}');
            return;
        }
        res.json(games);
    });
}

/**
* POST /api/games/
* Create a new game
*/
exports.postGame = function game(req, res) {
    const newGame = new Game({ teams: [], scores: [] });
    const teamIds = req.body.teams;

    if (teamIds && teamIds.length > 0) {
        var tasksToGo = teamIds.length;

        teamIds.forEach(function (id) {
            if (!mongoose.Types.ObjectId.isValid(id)) {
                if (--tasksToGo === 0) {
                    newGame.save((err, game) => {
                        if (err) {
                            res.status(403).send(`${err}`);
                            return;
                        }
                        res.status(201).send(game);
                    });
                }
                return;
            }

            Team.findById(id, (err, team) => {
                if (!err && team) {
                    // if (!newGame.teams.includes(id)) {
                    newGame.teams.push(id);
                    newGame.scores.push(new Score({ team: id }));
                    // }
                }

                if (--tasksToGo === 0) {
                    newGame.save((err, game) => {
                        if (err) {
                            res.status(403).send(`${err}`);
                            return;
                        }
                        res.status(201).send(game);
                    });
                }
            });
        });
    } else {
        newGame.save((err, game) => {
            if (err) {
                res.status(403).send(`${err}`);
                return;
            }
            res.status(201).send(game);
        });
    }
}

/**
* PUT /api/games/:gameId/addTeam
* Add teams to a game
*/
exports.addTeam = function game(req, res) {
    const gameId = req.params.gameId;

    if (!mongoose.Types.ObjectId.isValid(gameId)) {
        res.status(403).send("Invalid player id");
        return;
    }

    Game.findById(gameId, (err, game) => {
        if (err) {
            res.status(403).send(`${err}`);
            return;
        }

        if (!game) {
            res.status(403).send('No game found');
            return;
        }

        if (game.started_at) {
            res.status(403).send('Game has started cannot add a team');
            return;
        }

        const teamIds = req.body.teams;

        if (!teamIds && teamIds.length <= 0) {
            res.status(403).send('body empty');
            return;
        }

        var tasksToGo = teamIds.length;

        teamIds.forEach(function (id) {
            if (!mongoose.Types.ObjectId.isValid(id)) {
                if (--tasksToGo === 0) {
                    game.save((err, game) => {
                        if (err) {
                            res.status(403).send(`${err}`);
                            return;
                        }
                        res.status(201).send(game);
                    });
                }
                return;
            }

            Team.findById(id, (err, team) => {
                if (!err && team) {
                    // if (!game.teams.includes(id)) {
                    game.teams.push(id);
                    // }
                }

                if (--tasksToGo === 0) {
                    game.save((err, game) => {
                        if (err) {
                            res.status(403).send(`${err}`);
                            return;
                        }
                        res.status(201).send(game);
                    });
                }
            });
        });
    });
}

/**
* DELETE /api/games/:gameId
* Delete a game
*/
exports.deleteGame = function game(req, res) {
    const gameId = req.params.gameId;

    if (!mongoose.Types.ObjectId.isValid(gameId)) {
        res.status(403).send("Invalid player id");
        return;
    }

    Game.findByIdAndRemove(gameId, (err, game) => {
        if (err) {
            res.status(403).send(`${err}`);
            return;
        }

        if (!game) {
            res.status(403).send('No game found');
            return;
        }

        res.status(201).json(game);
    });
}

/**
* PUT /api/games/:gameId/start
* Start game
*/
exports.startGame = function game(req, res) {
    const gameId = req.params.gameId;

    if (!mongoose.Types.ObjectId.isValid(gameId)) {
        res.status(403).send("Invalid player id");
        return;
    }

    Game.findById(gameId, (err, game) => {
        if (err) {
            res.status(403).send(`${err}`);
            return;
        }

        if (!game) {
            res.status(403).send('player not found');
            return;
        }

        game.start(() => {
            game.save((err, game) => {
                if (err) {
                    res.status(403).send(`${err}`);
                    return;
                }
                res.status(201).json(game);
            });
        });
    });
}

/**
* PUT /api/games/:gameId/finish
* Finish game
*/
exports.finishGame = function game(req, res) {
    const gameId = req.params.gameId;

    if (!mongoose.Types.ObjectId.isValid(gameId)) {
        res.status(403).send("Invalid player id");
        return;
    }

    Game.findById(gameId, (err, game) => {
        if (err) {
            res.status(403).send(`${err}`);
            return;
        }

        if (!game) {
            res.status(403).send('player not found');
            return;
        }

        game.finish(() => {
            game.save((err, game) => {
                if (err) {
                    res.status(403).send(`${err}`);
                    return;
                }
                res.status(201).json(game);
            });
        });
    });
}

}

/**
* GET /api/teams
* List of teams.
*/
exports.getTeams = function get(req, res) {
    res.json({ teams: [] });
};

/**
* POST /api/teams
* Create a new team.
*/
exports.postTeam = function post(req, res) {
    res.status(201).send("Created new team");
}

/**
* POST /api/teams/:teamId
* Update a team by id.
*/
exports.putTeam = function put(req, res) {
    res.status(204).send("Updated a team");
}

/**
* POST /api/teams/:teamId
* Delete a team by id.
*/
exports.deleteTeam = function deleteTeam(req, res) {
    res.status(204).send("Deleted a team");
}
<|endoftext|>


<commit_before>const _ = require('lodash');
const {
  Readable
} = require('stream');
const oboe = require('oboe');

/**
 * Reads input streams sequencially and transforms data to output object stream
 */
class JsonSequentialStreamsReader extends Readable {
  /**
   * @constructor
   * @param {JsonSequentialStreamsReader~InputStreamFactory} inputStreamFactory Input stream factory
   * @param {object} [inputStreamFactoryParams={}] Input stream factory parameters
   * @param {string} [selector='!.*'] Output data selector
   */
  constructor(inputStreamFactory, inputStreamFactoryParams = {}, selector = '!.*') {
    super({
      objectMode: true
    });

    this._selector = selector;

    this._onInputStreamEndedHandler = () => {
      this._onInputStreamEnded();
    };
    this._inputStreamFactory = inputStreamFactory;
    this._inputStreamFactoryParams = _.cloneDeep(inputStreamFactoryParams);
    this._inputStream = null;

    this._onParserDoneHandler = (json) => {
      this._onParserDone(json);
    };
    this._onParserFailHandler = (reason) => {
      this._onParserFail(reason);
    };
    this._parser = null;
  }

  /**
   * https://nodejs.org/api/stream.html#stream_readable_read_size_1
   */
  _read(size) {
    //console.log('read');
    if (!this._inputStream) {
      this._setupInputStream();
    }
  }

  /**
   * Setups input stream
   *
   * @param {Object} [previousData=undefined] Data obtained from previous input stream
   */
  _setupInputStream(previousData = undefined) {
    this._inputStreamFactory(this._inputStreamFactoryParams, previousData)
      .then((inputStream) => {
        //console.log('got input stream');
        this._inputStream = inputStream
          .on('end', this._onInputStreamEndedHandler);

        this._parser = oboe(inputStream)
          .done(this._onParserDoneHandler)
          .fail(this._onParserFailHandler)
          .node(this._selector, (node) => {
            this._onParserData(node);
            return oboe.drop;
          });
      })
      .catch((reason) => {
        //TODO: this._reset(error);
        setImmediate(() => {
          this.push(null);
        });

        if (reason) {
          this.emit('error', new Error('Failed to create input stream: ' + JSON.stringify(reason)));
        }
      });
  }

  /**
   * Detaches from parser and input
   */
  _detachFromCurrentStream() {
    if (this._parser) {
      this._parser.removeListener('done', this._onParserDoneHandler);
      this._parser.removeListener('fail', this._onParserFailHandler);
    }
    if (this._inputStream) {
      this._inputStream.removeListener('end', this._onInputStreamEndedHandler);
    }
  }

  /**
   * Handle end of input stream
   */
  _onInputStreamEnded() {
    //console.log('input end, push nothing');
    this.push(null);
  }

  /**
   * Handles parser complete event
   */
  _onParserDone(json) {
    //console.log('parser done');
    this._detachFromCurrentStream();
    this._setupInputStream(json);
  }

  /**
   * Handles parser failure event
   */
  _onParserFail(reason) {
    //console.log('parser fail', reason);
    this.emit('error', new Error('Parser failed: ' + JSON.stringify(reason)));
  }

  /**
   * Processes parsed data
   */
  _onParserData(data) {
    //console.log('parser data');
    this.push(data);
  }
};

module.exports = JsonSequentialStreamsReader;
<commit_msg>Pass previous params also in JsonSequentialStreamsReader<commit_after>const _ = require('lodash');
const {
  Readable
} = require('stream');
const oboe = require('oboe');

/**
 * Reads input streams sequencially and transforms data to output object stream
 */
class JsonSequentialStreamsReader extends Readable {
  /**
   * @constructor
   * @param {JsonSequentialStreamsReader~InputStreamFactory} inputStreamFactory Input stream factory
   * @param {object} [inputStreamFactoryParams={}] Input stream factory parameters
   * @param {string} [selector='!.*'] Output data selector
   */
  constructor(inputStreamFactory, inputStreamFactoryParams = {}, selector = '!.*') {
    super({
      objectMode: true
    });

    this._selector = selector;

    this._onInputStreamEndedHandler = () => {
      this._onInputStreamEnded();
    };
    this._inputStreamFactory = inputStreamFactory;
    this._inputStreamFactoryParams = _.cloneDeep(inputStreamFactoryParams);
    this._inputStream = null;
    this._inputStreamParams = null;

    this._onParserDoneHandler = (data) => {
      this._onParserDone(data, this._inputStreamParams);
    };
    this._onParserFailHandler = (reason) => {
      this._onParserFail(reason);
    };
    this._parser = null;
  }

  /**
   * https://nodejs.org/api/stream.html#stream_readable_read_size_1
   */
  _read(size) {
    //console.log('read');
    if (!this._inputStream) {
      this._setupInputStream();
    }
  }

  /**
   * Setups input stream
   *
   * @param {Object} [previousData=undefined] Data obtained from previous input stream
   * @param {Object} [previousParams=undefined] Params used to setup previous input stream
   */
  _setupInputStream(previousData = undefined, previousParams = undefined) {
    this._inputStreamFactory(this._inputStreamFactoryParams, previousData, previousParams)
      .then((inputStream, params) => {
        //console.log('got input stream');
        this._inputStream = inputStream
          .on('end', this._onInputStreamEndedHandler);
        this._inputStreamParams = Object.assign({}, params);

        this._parser = oboe(inputStream)
          .done(this._onParserDoneHandler)
          .fail(this._onParserFailHandler)
          .node(this._selector, (dataChunk) => {
            this._onParserDataChunk(dataChunk);
            return oboe.drop;
          });
      })
      .catch((reason) => {
        //TODO: this._reset(error);
        setImmediate(() => {
          this.push(null);
        });

        if (reason) {
          this.emit('error', new Error('Failed to create input stream: ' + JSON.stringify(reason)));
        }
      });
  }

  /**
   * Detaches from parser and input
   */
  _detachFromCurrentStream() {
    if (this._parser) {
      this._parser.removeListener('done', this._onParserDoneHandler);
      this._parser.removeListener('fail', this._onParserFailHandler);
    }
    if (this._inputStream) {
      this._inputStream.removeListener('end', this._onInputStreamEndedHandler);
    }
  }

  /**
   * Handle end of input stream
   */
  _onInputStreamEnded() {
    //console.log('input end, push nothing');
    this.push(null);
  }

  /**
   * Handles parser complete event
   */
  _onParserDone(data, params) {
    //console.log('parser done');
    this._detachFromCurrentStream();
    this._setupInputStream(data, params);
  }

  /**
   * Handles parser failure event
   */
  _onParserFail(reason) {
    //console.log('parser fail', reason);
    this.emit('error', new Error('Parser failed: ' + JSON.stringify(reason)));
  }

  /**
   * Processes parsed data chunk
   */
  _onParserDataChunk(dataChunk) {
    //console.log('parser data');
    this.push(dataChunk);
  }
};

module.exports = JsonSequentialStreamsReader;
<|endoftext|>


<commit_before>var _ = require('lodash');
var async = require('async');
var urljoin = require('url-join');
var urlFormat = require('url').format;
var parseUrl = require('url').parse;
var debug = require('debug')('4front:apphost:dev-sandbox-page');

module.exports = function(options) {
  options = _.defaults(options || {}, {
    // short-lived cookie used to track the lifecycle of loading the sandbox page.
    cookieName: '_sandboxPage'
  });

  return function(req, res, next) {
    var cacheKey = urljoin(req.ext.user.userId, req.ext.virtualApp.appId, req.ext.htmlPagePath);

    if (req.cookies[options.cookieName]) {
      debug("sandboxPage already loaded");
      res.clearCookie(options.cookieName);

      req.app.settings.cache.exists(cacheKey, function(err, exists) {
        if (err) return next(err);

        if (!exists)
          return next(Error.http(404, 'Page ' + req.ext.htmlPagePath + ' not found.', {code: "pageNotFound"}));

        req.ext.htmlPageStream = req.app.settings.cache.readStream(cacheKey);
        next();
      });
    }
    else {
      debug("sandbox page needs to be loaded");
      res.cookie(options.cookieName, '1', {httpOnly: true});

      var redirectUrl = {
        protocol: req.secure ? 'https' : 'http',
        hostname: 'localhost',
        port: options.port,
        pathname: urljoin('sandbox', req.ext.htmlPagePath)
      };

      // Check if we already have the specified page in the cache and a sha value.
      async.parallel({
        exists: function(cb) {
          req.app.settings.cache.exists(cacheKey, cb);
        },
        hash: function(cb) {
          req.app.settings.cache.get(cacheKey + '/hash', cb);
        }
      }, function(err, results) {
        if (err) return next(err);

        // Pass the original url as the return query parameter
        // so the localhost sandbox can redirect back to the same place.
        var returnUrl = {};
        returnUrl.protocol = req.secure ? 'https' : 'http';
        returnUrl.host = req.hostname;
        returnUrl.pathname = req.path;
        returnUrl.query = req.query;

        redirectUrl.query = {return: urlFormat(returnUrl)};

        // If we have a hash for the requested file, pass it back as a
        // querystring parameter. The localhost sandbox will only re-upload
        // the file if the hash is different.
        if (results.exists === true && _.isEmpty(results.hash) === false)
          redirectUrl.query.hash = results.hash;

        res.redirect(urlFormat(redirectUrl));
      });
    }
  };
};
<commit_msg>Relax the exists check so either number 1 or true works<commit_after>var _ = require('lodash');
var async = require('async');
var urljoin = require('url-join');
var urlFormat = require('url').format;
var parseUrl = require('url').parse;
var debug = require('debug')('4front:apphost:dev-sandbox-page');

module.exports = function(options) {
  options = _.defaults(options || {}, {
    // short-lived cookie used to track the lifecycle of loading the sandbox page.
    cookieName: '_sandboxPage'
  });

  return function(req, res, next) {
    var cacheKey = urljoin(req.ext.user.userId, req.ext.virtualApp.appId, req.ext.htmlPagePath);

    if (req.cookies[options.cookieName]) {
      debug("sandboxPage already loaded");
      res.clearCookie(options.cookieName);

      req.app.settings.cache.exists(cacheKey, function(err, exists) {
        if (err) return next(err);

        if (!exists)
          return next(Error.http(404, 'Page ' + req.ext.htmlPagePath + ' not found.', {code: "pageNotFound"}));

        req.ext.htmlPageStream = req.app.settings.cache.readStream(cacheKey);
        next();
      });
    }
    else {
      debug("sandbox page needs to be loaded");
      res.cookie(options.cookieName, '1', {httpOnly: true});

      var redirectUrl = {
        protocol: req.secure ? 'https' : 'http',
        hostname: 'localhost',
        port: options.port,
        pathname: urljoin('sandbox', req.ext.htmlPagePath)
      };

      // Check if we already have the specified page in the cache and a hash value.
      async.parallel({
        exists: function(cb) {
          req.app.settings.cache.exists(cacheKey, cb);
        },
        hash: function(cb) {
          req.app.settings.cache.get(cacheKey + '/hash', cb);
        }
      }, function(err, results) {
        if (err) return next(err);

        // Pass the original url as the return query parameter
        // so the localhost sandbox can redirect back to the same place.
        var returnUrl = {};
        returnUrl.protocol = req.secure ? 'https' : 'http';
        returnUrl.host = req.hostname;
        returnUrl.pathname = req.path;
        returnUrl.query = req.query;

        redirectUrl.query = {return: urlFormat(returnUrl)};

        // If we have a hash for the requested file, pass it back as a
        // querystring parameter. The localhost sandbox will only re-upload
        // the file if the hash is different.
        if (results.exists && _.isEmpty(results.hash) === false)
          redirectUrl.query.hash = results.hash;

        res.redirect(urlFormat(redirectUrl));
      });
    }
  };
};
<|endoftext|>