<commit_before>var _, app, badge, bodyParser, config, cors, docket, docs, express, expressSession, fs, http, httpServer, io, LocalStrategy, logger, login, mongoose, notAllowed, options, passport, path, port, Rat, rat, register, Rescue, rescue, router, socket;

// IMPORT
// =============================================================================

// Import libraries
_ = require( 'lodash' );
bodyParser = require( 'body-parser' );
cors = require( 'cors' );
// docket = require( './docket.js' );
docs = require( 'express-mongoose-docs' );
express = require( 'express' );
expressSession = require( 'express-session' );
fs = require( 'fs' );
http = require( 'http' );
mongoose = require( 'mongoose' );
passport = require( 'passport' );
path = require( 'path' );
io = require( 'socket.io' );
LocalStrategy = require( 'passport-local' ).Strategy;

// Import config
if ( fs.existsSync( './config.json' ) ) {
  config = require( './config' )
} else {
  config = require( './config-example' )
}

// Import models
Rat = require( './api/models/rat' );
Rescue = require( './api/models/rescue' );
User = require( './api/models/user' );

// Import controllers
badge = require( './api/controllers/badge' );
login = require( './api/controllers/login' );
rat = require( './api/controllers/rat' );
register = require( './api/controllers/register' );
rescue = require( './api/controllers/rescue' );

// Connect to MongoDB
mongoose.connect( 'mongodb://localhost/fuelrats' );

options = {
  logging: true,
  test: false
};

// SHARED METHODS
// =============================================================================

// Function for disallowed methods
notAllowed = function notAllowed ( request, response ) {
  response.status( 405 );
  response.send();
};

// Parse command line arguments
// =============================================================================

if ( process.argv ) {
  for ( var i = 0; i < process.argv.length; i++ ) {
    var arg;

    arg = process.argv[i];

    switch ( arg ) {
      case '--no-log':
        options.logging = false;
        break;

      case '--test':
        options.test = true;
        break;
    }
  }
}

// MIDDLEWARE
// =============================================================================

app = express();
app.use( cors() );
app.use( bodyParser.urlencoded( { extended: true } ) );
app.use( bodyParser.json() );
app.use( expressSession({
  secret: config.secretSauce,
  resave: false,
  saveUninitialized: false
}));
app.use( passport.initialize() );
app.use( passport.session() );

app.set( 'json spaces', 2 );
app.set( 'x-powered-by', false );

httpServer = http.Server( app );

port = process.env.PORT || config.port;

passport.use( User.createStrategy() );
passport.serializeUser( User.serializeUser() );
passport.deserializeUser( User.deserializeUser() );

app.use( expressSession({
  secret: 'foobarbazdiddlydingdongsdf]08st0agf/b',
  resave: false,
  saveUninitialized: false
}));
app.use( passport.initialize() );
app.use( passport.session() );

docs( app, mongoose );
// docket( app, mongoose );

// Combine query parameters with the request body, prioritizing the body
app.use( function ( request, response, next ) {
  request.body = _.extend( request.query, request.body );
  next();
});

// Add logging
if ( options.logging || options.test ) {
  app.use( function ( request, response, next ) {
    console.log( '' );
    console.log( 'ENDPOINT:', request.originalUrl );
    console.log( 'METHOD:', request.method );
    console.log( 'DATA:', request.body );
    next();
  });
}

// ROUTER
// =============================================================================

// Create router
router = express.Router();

// ROUTES
// =============================================================================

app.get( '/badge/:rat', badge.get );

app.get( '/register', register.get );
app.post( '/register', register.post );

app.get( '/login', login.get );
app.post( '/login', passport.authenticate( 'local' ), login.post );

router.get( '/rats/:id', rat.get );
router.post( '/rats/:id', rat.post );
router.put( '/rats/:id', rat.put );
router.delete( '/rats/:id', notAllowed );

router.get( '/rats', rat.get );
router.post( '/rats', rat.post );
router.put( '/rescues', notAllowed );
router.delete( '/rescues', notAllowed );

router.get( '/rescues/:id', rescue.get );
router.post( '/rescues/:id', rescue.post );
router.put( '/rescues/:id', rescue.put );
router.delete( '/rescues/:id', notAllowed );

router.get( '/rescues', rescue.get );
router.post( '/rescues', rescue.post );
router.put( '/rescues', notAllowed );
router.delete( '/rescues', notAllowed );

router.get( '/search/rescues', rescue.get );

router.get( '/search/rats', rat.get );

// Register routes
app.use( '/api', router );
app.use( '/assets', express.static( __dirname + '/assets' ) );
app.use( '/bower_components', express.static( __dirname + '/bower_components' ) );
app.use( '/node_modules', express.static( __dirname + '/node_modules' ) );

// SOCKET
// =============================================================================

socket = io( httpServer );

socket.on( 'connection', function ( socket ) {
  console.log( 'a user connected' );
});

// START THE SERVER
// =============================================================================

module.exports = httpServer.listen( port );

if ( !module.parent ) {
  console.log( 'Listening for requests on port ' + port + '...' );
}
<commit_msg>Forgot to remove lodash from index file<commit_after>var _, app, badge, bodyParser, config, cors, docket, docs, express, expressSession, fs, http, httpServer, io, LocalStrategy, logger, login, mongoose, notAllowed, options, passport, path, port, Rat, rat, register, Rescue, rescue, router, socket;

// IMPORT
// =============================================================================

// Import libraries
_ = require( 'underscore' );
bodyParser = require( 'body-parser' );
cors = require( 'cors' );
// docket = require( './docket.js' );
docs = require( 'express-mongoose-docs' );
express = require( 'express' );
expressSession = require( 'express-session' );
fs = require( 'fs' );
http = require( 'http' );
mongoose = require( 'mongoose' );
passport = require( 'passport' );
path = require( 'path' );
io = require( 'socket.io' );
LocalStrategy = require( 'passport-local' ).Strategy;

// Import config
if ( fs.existsSync( './config.json' ) ) {
  config = require( './config' )
} else {
  config = require( './config-example' )
}

// Import models
Rat = require( './api/models/rat' );
Rescue = require( './api/models/rescue' );
User = require( './api/models/user' );

// Import controllers
badge = require( './api/controllers/badge' );
login = require( './api/controllers/login' );
rat = require( './api/controllers/rat' );
register = require( './api/controllers/register' );
rescue = require( './api/controllers/rescue' );

// Connect to MongoDB
mongoose.connect( 'mongodb://localhost/fuelrats' );

options = {
  logging: true,
  test: false
};

// SHARED METHODS
// =============================================================================

// Function for disallowed methods
notAllowed = function notAllowed ( request, response ) {
  response.status( 405 );
  response.send();
};

// Parse command line arguments
// =============================================================================

if ( process.argv ) {
  for ( var i = 0; i < process.argv.length; i++ ) {
    var arg;

    arg = process.argv[i];

    switch ( arg ) {
      case '--no-log':
        options.logging = false;
        break;

      case '--test':
        options.test = true;
        break;
    }
  }
}

// MIDDLEWARE
// =============================================================================

app = express();
app.use( cors() );
app.use( bodyParser.urlencoded( { extended: true } ) );
app.use( bodyParser.json() );
app.use( expressSession({
  secret: config.secretSauce,
  resave: false,
  saveUninitialized: false
}));
app.use( passport.initialize() );
app.use( passport.session() );

app.set( 'json spaces', 2 );
app.set( 'x-powered-by', false );

httpServer = http.Server( app );

port = process.env.PORT || config.port;

passport.use( User.createStrategy() );
passport.serializeUser( User.serializeUser() );
passport.deserializeUser( User.deserializeUser() );

app.use( expressSession({
  secret: 'foobarbazdiddlydingdongsdf]08st0agf/b',
  resave: false,
  saveUninitialized: false
}));
app.use( passport.initialize() );
app.use( passport.session() );

docs( app, mongoose );
// docket( app, mongoose );

// Combine query parameters with the request body, prioritizing the body
app.use( function ( request, response, next ) {
  request.body = _.extend( request.query, request.body );
  next();
});

// Add logging
if ( options.logging || options.test ) {
  app.use( function ( request, response, next ) {
    console.log( '' );
    console.log( 'ENDPOINT:', request.originalUrl );
    console.log( 'METHOD:', request.method );
    console.log( 'DATA:', request.body );
    next();
  });
}

// ROUTER
// =============================================================================

// Create router
router = express.Router();

// ROUTES
// =============================================================================

app.get( '/badge/:rat', badge.get );

app.get( '/register', register.get );
app.post( '/register', register.post );

app.get( '/login', login.get );
app.post( '/login', passport.authenticate( 'local' ), login.post );

router.get( '/rats/:id', rat.get );
router.post( '/rats/:id', rat.post );
router.put( '/rats/:id', rat.put );
router.delete( '/rats/:id', notAllowed );

router.get( '/rats', rat.get );
router.post( '/rats', rat.post );
router.put( '/rescues', notAllowed );
router.delete( '/rescues', notAllowed );

router.get( '/rescues/:id', rescue.get );
router.post( '/rescues/:id', rescue.post );
router.put( '/rescues/:id', rescue.put );
router.delete( '/rescues/:id', notAllowed );

router.get( '/rescues', rescue.get );
router.post( '/rescues', rescue.post );
router.put( '/rescues', notAllowed );
router.delete( '/rescues', notAllowed );

router.get( '/search/rescues', rescue.get );

router.get( '/search/rats', rat.get );

// Register routes
app.use( '/api', router );
app.use( '/assets', express.static( __dirname + '/assets' ) );
app.use( '/bower_components', express.static( __dirname + '/bower_components' ) );
app.use( '/node_modules', express.static( __dirname + '/node_modules' ) );

// SOCKET
// =============================================================================

socket = io( httpServer );

socket.on( 'connection', function ( socket ) {
  console.log( 'a user connected' );
});

// START THE SERVER
// =============================================================================

module.exports = httpServer.listen( port );

if ( !module.parent ) {
  console.log( 'Listening for requests on port ' + port + '...' );
}
<|endoftext|>


<commit_before>'use strict';

var path = require('path');
var fs = require('graceful-fs');
var _ = require('lodash');
var through = require('through2');
var convert = require('convert-source-map');

/*
 Postprocessor for wallaby.js runs module bundler compiler incrementally
 to only build changed or not yet built modules. The compiler is stopped from emitting the bundle/chunks to disk,
 because while concatenating files is beneficial for production environment, in testing environment it is different.
 Serving a large bundle/chunk every time when one of many files (that the bundle consists of) changes, is wasteful.
 So instead, each compiled module code is passed to wallaby,  wallaby caches it in memory (and when required, writes
 it on disk) and serves each requested module file separately to properly leverage browser caching.

 Apart from emitting module files, the postprocessor also emits a test loader script that executes in browser before
 any modules. The test loader sets up a global object so that each wrapped module can add itself to the loader cache.

 Each module code is wrapped in such a way that when the module file is loaded in browser, it doesn't execute
 the module code immediately. Instead, it just adds the function that executes the module code to test loader's cache.

 Modules are loaded from tests (that are entry points) when the tests are loaded. The tests are loaded from wallaby
 bootstrap function, by calling `__moduleBundler.loadTests()`.

 When wallaby runs tests first time, browser caches all modules and each subsequent test run only needs to load  a
 changed module files from the server (and not the full bundle).
 */

class Wallabify {

  constructor(opts, initializer) {
    this._patchModuleDependenciesModule();

    this._opts = opts || {};
    this._initializer = initializer;

    this._b = null;
    this._browserifyCache = {};
    this._affectedFilesCache = {};
    this._initRequired = false;
    this._allTrackedFiles = {};
  }

  createPostprocessor() {
    var self = this;
    try {
      this._browserify = require('browserify');
    }
    catch (e) {
      console.error('Browserify node module is not found, missing `npm install browserify --save-dev`?');
      return;
    }

    return wallaby => {
      var logger = wallaby.logger;
      var affectedFiles = wallaby.affectedFiles;
      if (!self._b || wallaby.anyFilesAdded || wallaby.anyFilesDeleted) {

        if (!self._b) {
          logger.debug('New browserify instance created');
        }
        else {
          logger.debug('Browserify instance re-created because some tracked files were added or deleted');
        }

        self._initRequired = true;
        self._affectedFilesCache = {};
        self._allTrackedFiles = _.reduce(wallaby.allFiles, function (memo, file) {
          memo[file.fullPath] = file;
          return memo;
        }, {});
        affectedFiles = wallaby.allFiles;

        self._b = self._createBrowserify({
          entries: _.map(wallaby.allTestFiles, testFile => testFile.fullPath),
          paths: wallaby.nodeModulesDir ? [wallaby.nodeModulesDir] : [],
          cache: {}, packageCache: {}, fullPaths: true,
          debug: true
        });

        self._browserifyCache = self._b._options.cache;

        self._b.on('dep', function (dep) {
          if (typeof dep.id === 'string') {
            var key = dep.id;
            if (!self._browserifyCache[key]) {
              self._browserifyCache[key] = dep;
              // external files are cached by file name as well to avoid re-processing them every time
              if (dep.expose) {
                self._browserifyCache[dep.file] = dep;
              }
              // new file that has not been cached before (node module or a source file)
              self._affectedFilesCache[key] = dep;
            }
          }
        });

        // no need to pack the bundle, wallaby.js serves files one by one to leverage browser caching
        self._b.pipeline.splice('pack');
      }

      // removing changed files tracked by wallaby.js from browserify cache
      if (!self._initRequired) {
        _.each(affectedFiles, file => {
          delete self._browserifyCache[file.fullPath];
        });
      }

      return new Promise(
        function (resolve, reject) {
          try {
            // incremental bundling
            self._b.bundle()
              .on('data', () => {
              })
              .on('error', err => reject(err))
              .on('end', () => resolve());
          } catch (err) {
            reject(err);
          }
        })
        .then(function () {
          var createFilePromises = [];

          // test loader for wallaby.js
          // works exactly as browserify bundle loading, but with separate files as opposed to a single bundle file
          if (self._initRequired) {
            self._initRequired = false;

            createFilePromises.push(wallaby.createFile({
              order: -1,  // need to be the first file to load
              path: 'wallabify.js',
              content: Wallabify._getLoaderContent()
            }));
          }

          // handling changed files tracked by wallaby.js
          _.each(affectedFiles, function (file) {
            var cached = self._browserifyCache[file.fullPath];
            if (cached) {
              var code = cached.source;
              var sourceMap;
              var sourceMapConverter = convert.fromSource(code);
              if (sourceMapConverter) {
                sourceMap = sourceMapConverter.toJSON();
                code = convert.removeComments(code);
              }

              // cloning an original file and browserify-ing it
              createFilePromises.push(wallaby.createFile({
                // adding the suffix to store browserified file along with the original copies
                path: file.path + '.bro.js',
                original: file,
                content: Wallabify._wallabifyFile(file.fullPath, code, cached.deps),
                sourceMap: sourceMap
              }));
              delete self._affectedFilesCache[file.fullPath];
            }
          });

          // handling externally added and not tracked files (such as node modules and external files)
          try {
            _.each(self._affectedFilesCache, function (file) {
              var ext = path.extname(file.id);
              var basename = path.basename(file.id, ext);
              createFilePromises.push(wallaby.createFile({
                // file path/name doesn't matter, just has to be unique for each file
                path: path.join('__modules', basename + '.' + require('crypto').createHash('md5').update(file.id).digest('hex') + '.js'),
                content: Wallabify._wallabifyFile(file.id, file.source, file.deps),
                ts: 1   // constant timestamp to cache the file in browser/phantomjs forever (until wallaby restarts)
              }));
            });
          }
          catch (e) {
            return Promise.reject(e);
          }

          // resetting till next incremental bundle run
          self._affectedFilesCache = {};

          logger.debug('Emitting %s files', createFilePromises.length);

          return Promise.all(createFilePromises);
        });
    }
  }

  _createBrowserify(mandatoryOpts) {
    var paths = mandatoryOpts.paths.concat(this._opts.paths || []);
    var mergedOpts = _.extend(this._opts, mandatoryOpts);
    mergedOpts.paths = paths;

    var instance = this._browserify(mergedOpts);
    if (this._initializer && _.isFunction(this._initializer)) {
      return this._initializer(instance) || instance;
    }

    return instance;
  }

  static _wallabifyFile(id, content, deps) {
    return 'window.__moduleBundler.cache[' + JSON.stringify(id) + '] = [function(require, module, exports) {'
      + content + '\n}, ' + JSON.stringify(deps) + '];';
  }

  static _getLoaderContent() {
    return 'window.__moduleBundler = {};'
      + 'window.__moduleBundler.cache = {};'
      + 'window.__moduleBundler.loadTests = function () {'
        // browser pack prelude
      + '(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module \'"+o+"\'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})'
        // passing accumulated files and entry points (browserified tests for the current sandbox)
      + '(window.__moduleBundler.cache, {}, (function(){ var testIds = []; for(var i = 0, len = wallaby.loadedTests.length; i < len; i++) { var test = wallaby.loadedTests[i]; if (test.substr(-7) === ".bro.js") testIds.push(wallaby.baseDir + test.substr(0, test.length - 7)); } return testIds; })()); };'
  }

  _patchModuleDependenciesModule() {
    var wallabify = this;
    // patching module dependencies to use wallaby cache
    try {
      require('browserify/node_modules/module-deps').prototype.readFile = function (file, id) {
        var self = this;
        var tr = through();
        if (this.cache && this.cache[file]) {
          tr.push(this.cache[file].source);
          tr.push(null);
          return tr;
        }

        // wallaby.js may already have the file cached (if not, it will just read it from disk)
        if (wallabify._allTrackedFiles && wallabify._allTrackedFiles[file]) {
          wallabify._allTrackedFiles[file].getContent().then(function (source) {
            tr.push(source);
            tr.push(null);
          });
          return tr;
        }

        var rs = fs.createReadStream(file);
        rs.on('error', function (err) {
          self.emit('error', err)
        });
        this.emit('file', file, id);
        return rs;
      };
    }
    catch (e) {
      // not critical
      console.warn('Failed to patch `module-deps` module, wallaby.js file cache will not be used.'
      + '\nIt\'s not a critical issue, however tests will run faster when wallaby.js file cache is used.');
    }
  }
}

module.exports = function (opts, initializer) {
  return new Wallabify(opts, initializer).createPostprocessor();
};<commit_msg>Fixed the issue when passed options are not merged but overwritten by the mandatory ones<commit_after>'use strict';

var path = require('path');
var fs = require('graceful-fs');
var _ = require('lodash');
var through = require('through2');
var convert = require('convert-source-map');

/*
 Postprocessor for wallaby.js runs module bundler compiler incrementally
 to only build changed or not yet built modules. The compiler is stopped from emitting the bundle/chunks to disk,
 because while concatenating files is beneficial for production environment, in testing environment it is different.
 Serving a large bundle/chunk every time when one of many files (that the bundle consists of) changes, is wasteful.
 So instead, each compiled module code is passed to wallaby,  wallaby caches it in memory (and when required, writes
 it on disk) and serves each requested module file separately to properly leverage browser caching.

 Apart from emitting module files, the postprocessor also emits a test loader script that executes in browser before
 any modules. The test loader sets up a global object so that each wrapped module can add itself to the loader cache.

 Each module code is wrapped in such a way that when the module file is loaded in browser, it doesn't execute
 the module code immediately. Instead, it just adds the function that executes the module code to test loader's cache.

 Modules are loaded from tests (that are entry points) when the tests are loaded. The tests are loaded from wallaby
 bootstrap function, by calling `__moduleBundler.loadTests()`.

 When wallaby runs tests first time, browser caches all modules and each subsequent test run only needs to load  a
 changed module files from the server (and not the full bundle).
 */

class Wallabify {

  constructor(opts, initializer) {
    this._patchModuleDependenciesModule();

    this._opts = opts || {};
    this._initializer = initializer;

    this._b = null;
    this._browserifyCache = {};
    this._affectedFilesCache = {};
    this._initRequired = false;
    this._allTrackedFiles = {};
  }

  createPostprocessor() {
    var self = this;
    try {
      this._browserify = require('browserify');
    }
    catch (e) {
      console.error('Browserify node module is not found, missing `npm install browserify --save-dev`?');
      return;
    }

    return wallaby => {
      var logger = wallaby.logger;
      var affectedFiles = wallaby.affectedFiles;
      if (!self._b || wallaby.anyFilesAdded || wallaby.anyFilesDeleted) {

        if (!self._b) {
          logger.debug('New browserify instance created');
        }
        else {
          logger.debug('Browserify instance re-created because some tracked files were added or deleted');
        }

        self._initRequired = true;
        self._affectedFilesCache = {};
        self._allTrackedFiles = _.reduce(wallaby.allFiles, function (memo, file) {
          memo[file.fullPath] = file;
          return memo;
        }, {});
        affectedFiles = wallaby.allFiles;

        self._b = self._createBrowserify({
          entries: _.map(wallaby.allTestFiles, testFile => testFile.fullPath),
          paths: wallaby.nodeModulesDir ? [wallaby.nodeModulesDir] : [],
          cache: {}, packageCache: {}, fullPaths: true,
          debug: true
        });

        self._browserifyCache = self._b._options.cache;

        self._b.on('dep', function (dep) {
          if (typeof dep.id === 'string') {
            var key = dep.id;
            if (!self._browserifyCache[key]) {
              self._browserifyCache[key] = dep;
              // external files are cached by file name as well to avoid re-processing them every time
              if (dep.expose) {
                self._browserifyCache[dep.file] = dep;
              }
              // new file that has not been cached before (node module or a source file)
              self._affectedFilesCache[key] = dep;
            }
          }
        });

        // no need to pack the bundle, wallaby.js serves files one by one to leverage browser caching
        self._b.pipeline.splice('pack');
      }

      // removing changed files tracked by wallaby.js from browserify cache
      if (!self._initRequired) {
        _.each(affectedFiles, file => {
          delete self._browserifyCache[file.fullPath];
        });
      }

      return new Promise(
        function (resolve, reject) {
          try {
            // incremental bundling
            self._b.bundle()
              .on('data', () => {
              })
              .on('error', err => reject(err))
              .on('end', () => resolve());
          } catch (err) {
            reject(err);
          }
        })
        .then(function () {
          var createFilePromises = [];

          // test loader for wallaby.js
          // works exactly as browserify bundle loading, but with separate files as opposed to a single bundle file
          if (self._initRequired) {
            self._initRequired = false;

            createFilePromises.push(wallaby.createFile({
              order: -1,  // need to be the first file to load
              path: 'wallabify.js',
              content: Wallabify._getLoaderContent()
            }));
          }

          // handling changed files tracked by wallaby.js
          _.each(affectedFiles, function (file) {
            var cached = self._browserifyCache[file.fullPath];
            if (cached) {
              var code = cached.source;
              var sourceMap;
              var sourceMapConverter = convert.fromSource(code);
              if (sourceMapConverter) {
                sourceMap = sourceMapConverter.toJSON();
                code = convert.removeComments(code);
              }

              // cloning an original file and browserify-ing it
              createFilePromises.push(wallaby.createFile({
                // adding the suffix to store browserified file along with the original copies
                path: file.path + '.bro.js',
                original: file,
                content: Wallabify._wallabifyFile(file.fullPath, code, cached.deps),
                sourceMap: sourceMap
              }));
              delete self._affectedFilesCache[file.fullPath];
            }
          });

          // handling externally added and not tracked files (such as node modules and external files)
          try {
            _.each(self._affectedFilesCache, function (file) {
              var ext = path.extname(file.id);
              var basename = path.basename(file.id, ext);
              createFilePromises.push(wallaby.createFile({
                // file path/name doesn't matter, just has to be unique for each file
                path: path.join('__modules', basename + '.' + require('crypto').createHash('md5').update(file.id).digest('hex') + '.js'),
                content: Wallabify._wallabifyFile(file.id, file.source, file.deps),
                ts: 1   // constant timestamp to cache the file in browser/phantomjs forever (until wallaby restarts)
              }));
            });
          }
          catch (e) {
            return Promise.reject(e);
          }

          // resetting till next incremental bundle run
          self._affectedFilesCache = {};

          logger.debug('Emitting %s files', createFilePromises.length);

          return Promise.all(createFilePromises);
        });
    }
  }

  _createBrowserify(mandatoryOpts) {
    var paths = mandatoryOpts.paths.concat(this._opts.paths || []);
    var mergedOpts = _.merge({}, this._opts, mandatoryOpts);
    mergedOpts.paths = paths;

    var instance = this._browserify(mergedOpts);
    if (this._initializer && _.isFunction(this._initializer)) {
      return this._initializer(instance) || instance;
    }

    return instance;
  }

  static _wallabifyFile(id, content, deps) {
    return 'window.__moduleBundler.cache[' + JSON.stringify(id) + '] = [function(require, module, exports) {'
      + content + '\n}, ' + JSON.stringify(deps) + '];';
  }

  static _getLoaderContent() {
    return 'window.__moduleBundler = {};'
      + 'window.__moduleBundler.cache = {};'
      + 'window.__moduleBundler.loadTests = function () {'
        // browser pack prelude
      + '(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module \'"+o+"\'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})'
        // passing accumulated files and entry points (browserified tests for the current sandbox)
      + '(window.__moduleBundler.cache, {}, (function(){ var testIds = []; for(var i = 0, len = wallaby.loadedTests.length; i < len; i++) { var test = wallaby.loadedTests[i]; if (test.substr(-7) === ".bro.js") testIds.push(wallaby.baseDir + test.substr(0, test.length - 7)); } return testIds; })()); };'
  }

  _patchModuleDependenciesModule() {
    var wallabify = this;
    // patching module dependencies to use wallaby cache
    try {
      require('browserify/node_modules/module-deps').prototype.readFile = function (file, id) {
        var self = this;
        var tr = through();
        if (this.cache && this.cache[file]) {
          tr.push(this.cache[file].source);
          tr.push(null);
          return tr;
        }

        // wallaby.js may already have the file cached (if not, it will just read it from disk)
        if (wallabify._allTrackedFiles && wallabify._allTrackedFiles[file]) {
          wallabify._allTrackedFiles[file].getContent().then(function (source) {
            tr.push(source);
            tr.push(null);
          });
          return tr;
        }

        var rs = fs.createReadStream(file);
        rs.on('error', function (err) {
          self.emit('error', err)
        });
        this.emit('file', file, id);
        return rs;
      };
    }
    catch (e) {
      // not critical
      console.warn('Failed to patch `module-deps` module, wallaby.js file cache will not be used.'
      + '\nIt\'s not a critical issue, however tests will run faster when wallaby.js file cache is used.');
    }
  }
}

module.exports = function (opts, initializer) {
  return new Wallabify(opts, initializer).createPostprocessor();
};<|endoftext|>


<commit_before>import React from 'react';
import Match from 'react-router/Match';
import Miss from 'react-router/Miss';
import Users from './Users';

const NoMatch = ({ location }) => (

Whoops

Sorry but {location.pathname} didn’t match any pages

);

export default ({pathname, connect}) => {
  console.log("matching", pathname);
  return

Users module

    <Match exactly pattern={`${pathname}`} component={connect(Users)}/>
    <Match pattern={`${pathname}/:query`} component={connect(Users)}/>
    <Miss component={NoMatch}/>

};
<commit_msg>The location parameter that gets passed to the Miss handler is undefined for some reason, so rewrite not to attempt to use it.<commit_after>import React from 'react';
import Match from 'react-router/Match';
import Miss from 'react-router/Miss';
import Users from './Users';

const NoMatch = ({ location }) => (
  // Why is location undefined here?

Uh-oh!

How did you get here?

);

export default ({pathname, connect}) => {
  console.log("matching", pathname);
  return

Users module

    <Match exactly pattern={`${pathname}`} component={connect(Users)}/>
    <Match pattern={`${pathname}/:query`} component={connect(Users)}/>
    <Miss component={NoMatch}/>

};
<|endoftext|>


<commit_before>
import { NativeModules } from 'react-native'

let RNPS = NativeModules.RNPasscodeStatus

// written out for clarity
const { supported, status, get } = RNPS
export default { supported, status, get }
<commit_msg>Remove unnecessary destructure to fix Jest tests<commit_after>
import { NativeModules } from 'react-native'

let RNPS = NativeModules.RNPasscodeStatus

// written out for clarity
// { supported, status, get } = RNPS
export default RNPS
<|endoftext|>


<commit_before>var path = require('path');
var Promise = require('node_modules/bluebird');
var _ = require('node_modules/lazy.js');
var rc = require('node_modules/rc');
var Editor = require('lib/ui/Editor');
var util = require('lib/util');
var clipboard = Promise.promisifyAll(require('copy-paste'));

var package = require('./package');
var configFile = path.join(__dirname, package.name + '.ini');
var opts = util.parseOpts(rc(package.name, configFile));

Editor.prototype.copy = Promise.method(function () {
  var self = this;
  var text = self.textBuf.getTextInRange(self.selection.getRange());
  var promise = Promise.resolve(self);
  if (text) promise = clipboard.copyAsync(self.data.clipboard = text).then(promise);
  return promise;
});
Editor.prototype.paste = Promise.method(function () {
  var self = this;
  return clipboard.pasteAsync()
    .catch(function (err) {
      switch (err.code) {
        case 'ENOENT':
          self.slap.header.message("install xclip to use system clipboard", 'warning');
          break;
      }
      return self.data.clipboard;
    })
    .then(function (text) {
      if (typeof text === 'string') {
        self.textBuf.setTextInRange(self.selection.getRange(), text);
        self.selection.reversed = false;
        self.selection.clearTail();
      }
      return self;
    });
});

var _initHandlers = Editor.prototype._initHandlers;
Editor.prototype._initHandlers = function () {
  self.ready.then(function () { self._initSlapClipboardPlugin(); }).done();
  return _initHandlers.apply(self, arguments);
};

Editor.prototype._initSlapClipboardPlugin = function () {
  var self = this;
  var bindings = _(opts.editor.bindings).merge(self.options.bindings || {}).toObject();
  self.on('keypress', function (ch, key) {
    var binding = util.getBinding(bindings, key);
    switch (binding) {
      case 'copy':
      case 'cut':
        self.copy().done();
        if (binding === 'cut') self.delete();
        return false;
      case 'paste': self.paste().done(); return false;
    };
  });
};

module.exports = function (slap) {
  slap.panes.forEach(function (pane) {
    pane.editor._initSlapClipboardPlugin();
  });
};
<commit_msg>Fixes bug<commit_after>var path = require('path');
var Promise = require('node_modules/bluebird');
var _ = require('node_modules/lazy.js');
var rc = require('node_modules/rc');
var Editor = require('lib/ui/Editor');
var util = require('lib/util');
var clipboard = Promise.promisifyAll(require('copy-paste'));

var package = require('./package');
var configFile = path.join(__dirname, package.name + '.ini');
var opts = util.parseOpts(rc(package.name, configFile));

Editor.prototype.copy = Promise.method(function () {
  var self = this;
  var text = self.textBuf.getTextInRange(self.selection.getRange());
  var promise = Promise.resolve(self);
  if (text) promise = clipboard.copyAsync(self.data.clipboard = text).then(promise);
  return promise;
});
Editor.prototype.paste = Promise.method(function () {
  var self = this;
  return clipboard.pasteAsync()
    .catch(function (err) {
      switch (err.code) {
        case 'ENOENT':
          self.slap.header.message("install xclip to use system clipboard", 'warning');
          break;
      }
      return self.data.clipboard;
    })
    .then(function (text) {
      if (typeof text === 'string') {
        self.textBuf.setTextInRange(self.selection.getRange(), text);
        self.selection.reversed = false;
        self.selection.clearTail();
      }
      return self;
    });
});

var _initHandlers = Editor.prototype._initHandlers;
Editor.prototype._initHandlers = function () {
  var self = this;
  self.ready.then(function () { self._initSlapClipboardPlugin(); }).done();
  return _initHandlers.apply(self, arguments);
};

Editor.prototype._initSlapClipboardPlugin = function () {
  var self = this;
  var bindings = _(opts.editor.bindings).merge(self.options.bindings || {}).toObject();
  self.on('keypress', function (ch, key) {
    var binding = util.getBinding(bindings, key);
    switch (binding) {
      case 'copy':
      case 'cut':
        self.copy().done();
        if (binding === 'cut') self.delete();
        return false;
      case 'paste': self.paste().done(); return false;
    };
  });
};

module.exports = function (slap) {
  slap.panes.forEach(function (pane) {
    pane.editor._initSlapClipboardPlugin();
  });
};
<|endoftext|>


<commit_before>// Load required modules
const jsonfile = require('jsonfile');
// const electron = require('electron');
const path = require('path');
const fs = require('fs');
const os = require('os');

// const app = electron.app || electron.remote.app;
// const userData = app.getPath('userData');

const platform = os.platform();

let appName = '';
if (JSON.parse(fs.readFileSync('package.json', 'utf-8')).productName) {
  appName = JSON.parse(fs.readFileSync('package.json', 'utf-8')).productName;
}else{
  appName = JSON.parse(fs.readFileSync('package.json', 'utf-8')).name;
}

let userData = '';

if (platform === 'win32') {
  userData = path.join(process.env.APPDATA, appName);
} else if (platform === 'darwin') {
  userData = path.join(process.env.HOME, 'Library', 'Application Support', appName);
} else {
  userData = path.join('var', 'local', appName);
}

/**
 * Create a table | a json file
 * @param  {[string]} tableName [Table name]
 */
function createTable(tableName, callback) {
  // Define the filename
  let fname = path.join(userData, tableName + '.json');

  // Check if the file with the tablename.json exists
  let exists = fs.existsSync(fname);

  if (exists) {
    // The file exists, do not recreate the table/json file
    callback(false, tableName + '.json already exists!');
    return;
  }else{
    // Create an empty object and pass an empty array as value
    let obj = new Object();
    obj[tableName] = [];

    // Write the object to json file
    try {
      jsonfile.writeFile(fname, obj, {spaces: 2}, function (err){
        console.log(err);
      });
      callback(true, "Success!")
      return;
    } catch (e) {
      callback(false, e.toString());
    }

  }
}

/**
 * Insert object to table. The object will be appended with the property, id
 * which uses timestamp as value.
 * @param  {string} tableName  [Table name]
 * @param  {string} tableField [Field name]
 * @param  {value} fieldValue [Value (string, number, list, etc.)]
 * @param {Function} callback [Callback function]
 */
function insertTableContent(tableName, tableRow, callback) {
  let fname = path.join(userData, tableName + '.json');
  let exists = fs.existsSync(fname);

  if (exists) {
    // Table | json parsed
    let table = JSON.parse(fs.readFileSync(fname));

    let date = new Date();
    let id = date.getTime();
    tableRow['id'] = id;

    table[tableName].push(tableRow);

    try {
      jsonfile.writeFile(fname, table, {spaces: 2}, function (err){
        console.log(err);
      });
      callback(true, "Object written successfully!");
      return;
    } catch (e) {
      callback(false, "Error writing object.");
      return;
    }
  }
  callback(false, "Table/json file doesn't exist!");
  return;
}

/**
 * Get all contents of the table/json file object
 * @param  {[string]}   tableName [Table name]
 * @param  {Function} callback  [callback]
 */
function getAll(tableName, callback) {
  let fname = path.join(userData, tableName + '.json');
  let exists = fs.existsSync(fname);

  if (exists) {
    try {
      let table = JSON.parse(fs.readFileSync(fname));
      callback(true, table[tableName]);
      return;
    } catch (e) {
      callback(false, []);
      return;
    }
  } else {
    callback(false, []);
    return;
  }
}

/**
 * Get row or rows that matched the given condition(s) in WHERE argument
 * @param {string} tableName Table name
 * @param {object} where Collection of conditions to be met
 * @param {callback} callback Function callback
 */
function getRows(tableName, where, callback) {
  let fname = path.join(userData, tableName + '.json');
  let exists = fs.existsSync(fname);
  let whereKeys;

  // Check if where is an object
  if (Object.prototype.toString.call(where) === "[object Object]" ) {
    // Check for number of keys
    whereKeys = Object.keys(where);
    if (whereKeys === 0) {
      callback(false, "There are no conditions passed to the WHERE clause.");
      return;
    }
  } else {
    callback(false, "WHERE clause should be an object.");
    return;
  }

  // Check if the json file exists, if it is, parse it.
  if (exists) {
    try {
      let table = JSON.parse(fs.readFileSync(fname));
      let rows = table[tableName];

      let objs = [];

      for (let i = 0; i < rows.length; i++) {
        let matched = 0;    // Number of matched complete where clause
        for (var j = 0; j < whereKeys.length; j++) {
          // Test if there is a matched key with where clause
          if (rows[i].hasOwnProperty(whereKeys[j])) {
            if (rows[i][whereKeys[j]] === where[whereKeys[j]]) {
              matched++;
            }
          }
        }

        // Check if all conditions in the WHERE clause are matched
        if (matched === whereKeys.length) {
          objs.push(rows[i])
        }
      }

      callback(true, objs);
      return;
    }catch (e) {
      callback(false, e.toString());
      return;
    }
  } else {
    callback(false, "JSON file does not exist.");
    return;
  }
}

/**
 * Update a row or record which satisfies the where clause
 * @param  {[string]}   tableName [Table name]
 * @param  {[object]}   where     [Objet for WHERE clause]
 * @param  {[object]}   set       [Object for SET clause]
 * @param  {Function} callback  [Callback function]
 */
function updateRow(tableName, where, set, callback) {
  let fname = path.join(userData, tableName + '.json');
  let exists = fs.existsSync(fname);

  let whereKeys = Object.keys(where);
  let setKeys = Object.keys(set);

  if (exists) {
    let table = JSON.parse(fs.readFileSync(fname));
    let rows = table[tableName];

    for (var i = 0; i < rows.length; i++) {
      let matched = 0;    // Number of matched complete where clause
      for (var j = 0; j < whereKeys.length; j++) {
        // Test if there is a matched key with where clause and single row of table
        if (rows[i].hasOwnProperty(whereKeys[j])) {
          if (rows[i][whereKeys[j]] === where[whereKeys]) {
            matched++;
          }
        }
      }

      if (matched === whereKeys.length) {
        // All field from where clause are present in this particular
        // row of the database table
        try {
          for (var k = 0; k < setKeys.length; k++) {
            rows[i][setKeys[k]] = set[setKeys[k]];
          }

          // Create a new object and pass the rows
          let obj = new Object();
          obj[tableName] = rows;

          // Write the object to json file
          try {
            jsonfile.writeFile(fname, obj, {spaces: 2}, function (err){
              console.log(err);
            });
            callback(true, "Success!")
            return;
          } catch (e) {
            callback(false, e.toString());
          }

          callback(true, rows);
        } catch (e) {
          callback(false, e.toString());
        }
      } else {
        callback(false, "Cannot find the specified record.")
      }

    }
  }
}

/**
 *
 * @param {*} tableName Name of the table to search for
 * @param {*} field Name of the column/key to match
 * @param {*} keyword The part of the value of the key that is being lookup
 * @param {*} callback Callback function
 */
function search(tableName, field, keyword, callback) {
  let fname = path.join(userData, tableName + '.json');
  let exists = fs.existsSync(fname);

  if (exists) {
    let table = JSON.parse(fs.readFileSync(fname));
    let rows = table[tableName];

    if (rows.length > 0) {

      // Declare an empty list
      let foundRows = [];

      for (var i = 0; i < rows.length; i++) {
        // Check if key exists
        if (rows[i].hasOwnProperty(field)) {
          // Get the index of the search term
          let value = rows[i][field].toLowerCase();
          let n = value.search(keyword.toLowerCase());

          if (n !== -1) {
            // The substring is found, add object to the list.
            foundRows.push(rows[i]);
          }

        }else{
          callback(false, 2);
          return;
        }
      }

      callback(true, foundRows);
      return;

    } else {
      callback(false, 1);
      return;
    }
  } else {
    callback(false, 0);
    return;
  }
}

function deleteRow(tableName, where, callback) {
  let fname = path.join(userData, tableName + '.json');
  let exists = fs.existsSync(fname);

  let whereKeys = Object.keys(where);

  if (exists) {
    let table = JSON.parse(fs.readFileSync(fname));
    let rows = table[tableName];

    if (rows.length > 0) {
      for (let i = 0; i < rows.length; i++) {
        // Iterate throught the rows
        let matched = 0;
        let matchedIndices = [];

        for (var j = 0; j < whereKeys.length; j++) {
          // Test if there is a matched key with where clause and single row of table
          if (rows[i].hasOwnProperty(whereKeys[j])) {
            if (rows[i][whereKeys[j]] === where[whereKeys]) {
              matched++;
              matchedIndices.push(i);
            }
          }
        }

        for (let i = 0; i < matchedIndices.length; i++) {
          rows.splice(matchedIndices[i], 1);
        }

      }

      // Create a new object and pass the rows
      let obj = new Object();
      obj[tableName] = rows;

      console.log(rows);

      // Write the object to json file
      try {
        jsonfile.writeFile(fname, obj, {spaces: 2}, function (err){

        });
        callback(true, "Row(s) deleted successfully!")
        return;
      } catch (e) {
        callback(false, e.toString());
        return;
      }

    } else {
      callback(false, 'Table is empty!');
      return;
    }
  }

}

// Export the public available functions
module.exports = {
  createTable,
  insertTableContent,
  getAll,
  getRows,
  updateRow,
  search,
  deleteRow
};
<commit_msg>Update updateRow. Show all possible errors in callback message<commit_after>// Load required modules
const jsonfile = require('jsonfile');
// const electron = require('electron');
const path = require('path');
const fs = require('fs');
const os = require('os');

// const app = electron.app || electron.remote.app;
// const userData = app.getPath('userData');

const platform = os.platform();

let appName = '';
if (JSON.parse(fs.readFileSync('package.json', 'utf-8')).productName) {
  appName = JSON.parse(fs.readFileSync('package.json', 'utf-8')).productName;
}else{
  appName = JSON.parse(fs.readFileSync('package.json', 'utf-8')).name;
}

let userData = '';

if (platform === 'win32') {
  userData = path.join(process.env.APPDATA, appName);
} else if (platform === 'darwin') {
  userData = path.join(process.env.HOME, 'Library', 'Application Support', appName);
} else {
  userData = path.join('var', 'local', appName);
}

/**
 * Create a table | a json file
 * @param  {[string]} tableName [Table name]
 */
function createTable(tableName, callback) {
  // Define the filename
  let fname = path.join(userData, tableName + '.json');

  // Check if the file with the tablename.json exists
  let exists = fs.existsSync(fname);

  if (exists) {
    // The file exists, do not recreate the table/json file
    callback(false, tableName + '.json already exists!');
    return;
  }else{
    // Create an empty object and pass an empty array as value
    let obj = new Object();
    obj[tableName] = [];

    // Write the object to json file
    try {
      jsonfile.writeFile(fname, obj, {spaces: 2}, function (err){
        console.log(err);
      });
      callback(true, "Success!")
      return;
    } catch (e) {
      callback(false, e.toString());
    }

  }
}

/**
 * Insert object to table. The object will be appended with the property, id
 * which uses timestamp as value.
 * @param  {string} tableName  [Table name]
 * @param  {string} tableField [Field name]
 * @param  {value} fieldValue [Value (string, number, list, etc.)]
 * @param {Function} callback [Callback function]
 */
function insertTableContent(tableName, tableRow, callback) {
  let fname = path.join(userData, tableName + '.json');
  let exists = fs.existsSync(fname);

  if (exists) {
    // Table | json parsed
    let table = JSON.parse(fs.readFileSync(fname));

    let date = new Date();
    let id = date.getTime();
    tableRow['id'] = id;

    table[tableName].push(tableRow);

    try {
      jsonfile.writeFile(fname, table, {spaces: 2}, function (err){
        console.log(err);
      });
      callback(true, "Object written successfully!");
      return;
    } catch (e) {
      callback(false, "Error writing object.");
      return;
    }
  }
  callback(false, "Table/json file doesn't exist!");
  return;
}

/**
 * Get all contents of the table/json file object
 * @param  {[string]}   tableName [Table name]
 * @param  {Function} callback  [callback]
 */
function getAll(tableName, callback) {
  let fname = path.join(userData, tableName + '.json');
  let exists = fs.existsSync(fname);

  if (exists) {
    try {
      let table = JSON.parse(fs.readFileSync(fname));
      callback(true, table[tableName]);
      return;
    } catch (e) {
      callback(false, []);
      return;
    }
  } else {
    callback(false, []);
    return;
  }
}

/**
 * Get row or rows that matched the given condition(s) in WHERE argument
 * @param {string} tableName Table name
 * @param {object} where Collection of conditions to be met
 * @param {callback} callback Function callback
 */
function getRows(tableName, where, callback) {
  let fname = path.join(userData, tableName + '.json');
  let exists = fs.existsSync(fname);
  let whereKeys;

  // Check if where is an object
  if (Object.prototype.toString.call(where) === "[object Object]" ) {
    // Check for number of keys
    whereKeys = Object.keys(where);
    if (whereKeys === 0) {
      callback(false, "There are no conditions passed to the WHERE clause.");
      return;
    }
  } else {
    callback(false, "WHERE clause should be an object.");
    return;
  }

  // Check if the json file exists, if it is, parse it.
  if (exists) {
    try {
      let table = JSON.parse(fs.readFileSync(fname));
      let rows = table[tableName];

      let objs = [];

      for (let i = 0; i < rows.length; i++) {
        let matched = 0;    // Number of matched complete where clause
        for (var j = 0; j < whereKeys.length; j++) {
          // Test if there is a matched key with where clause
          if (rows[i].hasOwnProperty(whereKeys[j])) {
            if (rows[i][whereKeys[j]] === where[whereKeys[j]]) {
              matched++;
            }
          }
        }

        // Check if all conditions in the WHERE clause are matched
        if (matched === whereKeys.length) {
          objs.push(rows[i])
        }
      }

      callback(true, objs);
      return;
    }catch (e) {
      callback(false, e.toString());
      return;
    }
  } else {
    callback(false, "JSON file does not exist.");
    return;
  }
}

/**
 * Update a row or record which satisfies the where clause
 * @param  {[string]}   tableName [Table name]
 * @param  {[object]}   where     [Objet for WHERE clause]
 * @param  {[object]}   set       [Object for SET clause]
 * @param  {Function} callback  [Callback function]
 */
function updateRow(tableName, where, set, callback) {
  let fname = path.join(userData, tableName + '.json');
  let exists = fs.existsSync(fname);

  let whereKeys = Object.keys(where);
  let setKeys = Object.keys(set);

  if (exists) {
    let table = JSON.parse(fs.readFileSync(fname));
    let rows = table[tableName];

    for (var i = 0; i < rows.length; i++) {
      let matched = 0;    // Number of matched complete where clause
      for (var j = 0; j < whereKeys.length; j++) {
        // Test if there is a matched key with where clause and single row of table
        if (rows[i].hasOwnProperty(whereKeys[j])) {
          if (rows[i][whereKeys[j]] === where[whereKeys]) {
            matched++;
          }
        }
      }

      if (matched === whereKeys.length) {
        // All field from where clause are present in this particular
        // row of the database table
        try {
          for (var k = 0; k < setKeys.length; k++) {
            rows[i][setKeys[k]] = set[setKeys[k]];
          }

          // Create a new object and pass the rows
          let obj = new Object();
          obj[tableName] = rows;

          // Write the object to json file
          try {
            jsonfile.writeFile(fname, obj, {spaces: 2}, function (err){
              console.log(err);
            });
            callback(true, "Success!")
            return;
          } catch (e) {
            callback(false, e.toString());
            return;
          }

          callback(true, rows);
        } catch (e) {
          callback(false, e.toString());
          return;
        }
      } else {
        callback(false, "Cannot find the specified record.");
        return;
      }

    }
  } else {
    callback(false, "JSON file does not exist.");
    return;
  }
}

/**
 *
 * @param {*} tableName Name of the table to search for
 * @param {*} field Name of the column/key to match
 * @param {*} keyword The part of the value of the key that is being lookup
 * @param {*} callback Callback function
 */
function search(tableName, field, keyword, callback) {
  let fname = path.join(userData, tableName + '.json');
  let exists = fs.existsSync(fname);

  if (exists) {
    let table = JSON.parse(fs.readFileSync(fname));
    let rows = table[tableName];

    if (rows.length > 0) {

      // Declare an empty list
      let foundRows = [];

      for (var i = 0; i < rows.length; i++) {
        // Check if key exists
        if (rows[i].hasOwnProperty(field)) {
          // Get the index of the search term
          let value = rows[i][field].toLowerCase();
          let n = value.search(keyword.toLowerCase());

          if (n !== -1) {
            // The substring is found, add object to the list.
            foundRows.push(rows[i]);
          }

        }else{
          callback(false, 2);
          return;
        }
      }

      callback(true, foundRows);
      return;

    } else {
      callback(false, 1);
      return;
    }
  } else {
    callback(false, 0);
    return;
  }
}

function deleteRow(tableName, where, callback) {
  let fname = path.join(userData, tableName + '.json');
  let exists = fs.existsSync(fname);

  let whereKeys = Object.keys(where);

  if (exists) {
    let table = JSON.parse(fs.readFileSync(fname));
    let rows = table[tableName];

    if (rows.length > 0) {
      for (let i = 0; i < rows.length; i++) {
        // Iterate throught the rows
        let matched = 0;
        let matchedIndices = [];

        for (var j = 0; j < whereKeys.length; j++) {
          // Test if there is a matched key with where clause and single row of table
          if (rows[i].hasOwnProperty(whereKeys[j])) {
            if (rows[i][whereKeys[j]] === where[whereKeys]) {
              matched++;
              matchedIndices.push(i);
            }
          }
        }

        for (let i = 0; i < matchedIndices.length; i++) {
          rows.splice(matchedIndices[i], 1);
        }

      }

      // Create a new object and pass the rows
      let obj = new Object();
      obj[tableName] = rows;

      console.log(rows);

      // Write the object to json file
      try {
        jsonfile.writeFile(fname, obj, {spaces: 2}, function (err){

        });
        callback(true, "Row(s) deleted successfully!")
        return;
      } catch (e) {
        callback(false, e.toString());
        return;
      }

    } else {
      callback(false, 'Table is empty!');
      return;
    }
  }

}

// Export the public available functions
module.exports = {
  createTable,
  insertTableContent,
  getAll,
  getRows,
  updateRow,
  search,
  deleteRow
};
<|endoftext|>


<commit_before>import {ContainerPlugin, Log, Events} from 'clappr'
import get from 'lodash.get'

const REPORT_EVENT = 'clappr:stats:report'

export default class ClapprStats extends ContainerPlugin {
  get name() { return 'clappr_stats' }

  get _playbackName() {return this.container.playback.name}
  get _playbackType() {return this.container.getPlaybackType()}
  _now() {
    var hasPerformanceSupport = performance && typeof(performance.now) === "function"
    return (hasPerformanceSupport)?performance.now():new Date()
  }
  _inc(counter) {this._metrics.counters[counter] += 1}
  _timerHasStarted(timer){return this[`_start${timer}`] !== undefined}
  _start(timer) {this[`_start${timer}`] = this._now()}
  _stop(timer) {this._metrics.timers[timer] += this._now() - this[`_start${timer}`]}
  _defaultReport(metrics) {console.log(metrics)}

  constructor(container) {
    super(container)
    this._runEach = get(container, 'options.clapprStats.runEach', 5000)
    this._onReport = get(container, 'options.clapprStats.onReport', this._defaultReport)
    this._uriToMeasureLatency = get(container, 'options.clapprStats.uriToMeasureLatency')

    this._metrics = {
      counters: {
	play: 0, pause: 0, error: 0, buffering: 0, decodedFrames: 0, droppedFrames: 0,
	fps: 0, changeLevel: 0, seek: 0, fullscreen: 0, dvrUsage: 0
      },
      timers: {
	startup: 0, watch: 0, pause: 0, buffering: 0, session: 0, latency: 0
      },
      extra: {playbackName: '', playbackType: '', lastBitrate: ''} //buffersize, all playbacks???
    }

    this.on(REPORT_EVENT, this._onReport)
  }

  bindEvents() {
    this.listenTo(this.container, Events.CONTAINER_BITRATE, this.onBitrate)
    this.listenTo(this.container, Events.CONTAINER_STOP, this.stopReporting)
    this.listenTo(this.container, Events.CONTAINER_ENDED, this.stopReporting)
    this.listenToOnce(this.container.playback, Events.PLAYBACK_PLAY_INTENT, this.startTimers)
    this.listenToOnce(this.container, Events.CONTAINER_PLAY, () => this._start('watch'))
    this.listenTo(this.container, Events.CONTAINER_PLAY, this.onPlay)
    this.listenTo(this.container, Events.CONTAINER_PAUSE, this.onPause)
    this.listenToOnce(this.container, Events.CONTAINER_TIMEUPDATE, this.measureStartup)
    this.listenTo(this.container, Events.CONTAINER_TIMEUPDATE, () => this.container.playback.isPlaying() && this.onContainerUpdateWhilePlaying())
    this.listenToOnce(this.container, Events.CONTAINER_STATE_BUFFERING, this.onBuffering)
    this.listenTo(this.container, Events.CONTAINER_SEEK, () => this._inc('seek'))
    this.listenTo(this.container, Events.CONTAINER_ERROR, () => this._inc('error'))
    this.listenTo(this.container, Events.CONTAINER_FULLSCREEN, () => this._inc('fullscreen'))
    this.listenTo(this.container, Events.CONTAINER_PLAYBACKDVRSTATECHANGED, (dvrInUse) => {dvrInUse && this._inc('dvrUsage')})
    this.once(REPORT_EVENT, this._fetchLatency)
  }

  onBitrate(bitrate) {
    this._metrics.extra.lastBitrate = get(bitrate, 'height', '')
    this._inc('changeLevel')
  }

  stopReporting() {
    this._buildReport()
    clearInterval(this._intervalId)
  }

  startTimers() {
    this._intervalId = setInterval(this._buildReport.bind(this), this._runEach)
    this._start('session')
    this._start('watch')
    this._start('startup')
  }

  playAfterPause() {
    this._stop('pause')
    this._start('watch')
  }

  onPlay() {
    this._inc('play')
  }

  onPause() {
    this._start('pause')
    this._inc('pause')
    this.listenToOnce(this.container, Events.CONTAINER_PLAY, this.playAfterPause)
  }

  // the first time update from html5 fires before user hit play
  startStartup() {this._timerHasStarted('startup') && this._stop('startup')}

  onContainerUpdateWhilePlaying() {
    this._stop('watch')
    this._start('watch')
  }

  onBuffering() {
    this._inc('buffering')
    this._start('buffering')
    this.listenToOnce(this.container, Events.CONTAINER_STATE_BUFFERFULL, this.onBufferfull)
  }

  onBufferfull() {
    this._stop('buffering')
    this.listenToOnce(this.container, Events.CONTAINER_STATE_BUFFERING, this.onBuffering)
  }

  //measuring only two times is enough => "take(2)" of events
  _fetchLatency() {
    this._measureLatency()
    this.once(REPORT_EVENT, this._measureLatency)
  }

  _buildReport() {
    this._stop('session')
    this._start('session')

    this._fetchExtras()

    this.trigger(REPORT_EVENT, JSON.parse(JSON.stringify(this._metrics)))
  }

  _fetchExtras() {
    // flashls ??? - hls.droppedFramesl hls.stream.bufferLength (seconds)
    // hls ??? (use the same?)
    var videoTag = this.container.playback.el
    var decodedFrames = videoTag.webkitDecodedFrameCount || videoTag.mozDecodedFrames || 0
    var droppedFrames = (videoTag.webkitDroppedFrameCount || (videoTag.mozParsedFrames - videoTag.mozDecodedFrames)) || 0
    var decodedFramesLastTime = decodedFrames - (this._lastDecodedFramesCount || 0)

    this._metrics.counters.decodedFrames = decodedFrames
    this._metrics.counters.droppedFrames = droppedFrames
    this._metrics.counters.fps = decodedFramesLastTime / (this._runEach / 1000)

    this._lastDecodedFramesCount = decodedFrames

    this._metrics.extra.playbackName = this._playbackName
    this._metrics.extra.playbackType = this._playbackType
  }

  // originally from https://www.smashingmagazine.com/2011/11/analyzing-network-characteristics-using-javascript-and-the-dom-part-1/
  _measureLatency() {
    if (this._uriToMeasureLatency) {
      var t=[], n=2, tcp, rtt;
      var ld = () => {
	t.push(this._now());
	if(t.length > n)
	  done();
	else {
	  var img = new Image;
	  img.onload = ld;
	  img.src=this._uriToMeasureLatency + '?' + Math.random()
	  + '=' + this._now();
	}
      };
      var done = () => {
	rtt=t[2]-t[1]
	tcp=t[1]-t[0]-rtt
        this._metrics.timers.latency = rtt
      };
      ld();
    }
  }
}
<commit_msg>minor refactoring<commit_after>import {ContainerPlugin, Log, Events} from 'clappr'
import get from 'lodash.get'

const REPORT_EVENT = 'clappr:stats:report'

export default class ClapprStats extends ContainerPlugin {
  get name() { return 'clappr_stats' }

  get _playbackName() {return this.container.playback.name}
  get _playbackType() {return this.container.getPlaybackType()}
  _now() {
    const hasPerformanceSupport = performance && typeof(performance.now) === "function"
    return (hasPerformanceSupport)?performance.now():new Date()
  }
  _inc(counter) {this._metrics.counters[counter] += 1}
  _timerHasStarted(timer){return this[`_start${timer}`] !== undefined}
  _start(timer) {this[`_start${timer}`] = this._now()}
  _stop(timer) {this._metrics.timers[timer] += this._now() - this[`_start${timer}`]}
  _defaultReport(metrics) {console.log(metrics)}

  constructor(container) {
    super(container)
    this._runEach = get(container, 'options.clapprStats.runEach', 5000)
    this._onReport = get(container, 'options.clapprStats.onReport', this._defaultReport)
    this._uriToMeasureLatency = get(container, 'options.clapprStats.uriToMeasureLatency')

    this._metrics = {
      counters: {
	play: 0, pause: 0, error: 0, buffering: 0, decodedFrames: 0, droppedFrames: 0,
	fps: 0, changeLevel: 0, seek: 0, fullscreen: 0, dvrUsage: 0
      },
      timers: {
	startup: 0, watch: 0, pause: 0, buffering: 0, session: 0, latency: 0
      },
      extra: {playbackName: '', playbackType: '', lastBitrate: ''} //buffersize, all playbacks???
    }

    this.on(REPORT_EVENT, this._onReport)
  }

  bindEvents() {
    this.listenTo(this.container, Events.CONTAINER_BITRATE, this.onBitrate)
    this.listenTo(this.container, Events.CONTAINER_STOP, this.stopReporting)
    this.listenTo(this.container, Events.CONTAINER_ENDED, this.stopReporting)
    this.listenToOnce(this.container.playback, Events.PLAYBACK_PLAY_INTENT, this.startTimers)
    this.listenToOnce(this.container, Events.CONTAINER_PLAY, () => this._start('watch'))
    this.listenTo(this.container, Events.CONTAINER_PLAY, this.onPlay)
    this.listenTo(this.container, Events.CONTAINER_PAUSE, this.onPause)
    this.listenToOnce(this.container, Events.CONTAINER_TIMEUPDATE, this.measureStartup)
    this.listenTo(this.container, Events.CONTAINER_TIMEUPDATE, () => this.container.playback.isPlaying() && this.onContainerUpdateWhilePlaying())
    this.listenToOnce(this.container, Events.CONTAINER_STATE_BUFFERING, this.onBuffering)
    this.listenTo(this.container, Events.CONTAINER_SEEK, () => this._inc('seek'))
    this.listenTo(this.container, Events.CONTAINER_ERROR, () => this._inc('error'))
    this.listenTo(this.container, Events.CONTAINER_FULLSCREEN, () => this._inc('fullscreen'))
    this.listenTo(this.container, Events.CONTAINER_PLAYBACKDVRSTATECHANGED, (dvrInUse) => {dvrInUse && this._inc('dvrUsage')})
    this.once(REPORT_EVENT, this._fetchLatency)
  }

  onBitrate(bitrate) {
    this._metrics.extra.lastBitrate = get(bitrate, 'height', '')
    this._inc('changeLevel')
  }

  stopReporting() {
    this._buildReport()
    clearInterval(this._intervalId)
  }

  startTimers() {
    this._intervalId = setInterval(this._buildReport.bind(this), this._runEach)
    this._start('session')
    this._start('startup')
  }

  playAfterPause() {
    this._stop('pause')
    this._start('watch')
  }

  onPlay() {
    this._inc('play')
  }

  onPause() {
    this._start('pause')
    this._inc('pause')
    this.listenToOnce(this.container, Events.CONTAINER_PLAY, this.playAfterPause)
  }

  // the first time update from html5 fires before user hit play
  measureStartup() {this._timerHasStarted('startup') && this._stop('startup')}

  onContainerUpdateWhilePlaying() {
    this._stop('watch')
    this._start('watch')
  }

  onBuffering() {
    this._inc('buffering')
    this._start('buffering')
    this.listenToOnce(this.container, Events.CONTAINER_STATE_BUFFERFULL, this.onBufferfull)
  }

  onBufferfull() {
    this._stop('buffering')
    this.listenToOnce(this.container, Events.CONTAINER_STATE_BUFFERING, this.onBuffering)
  }

  //measuring only two times is enough => "take(2)" of events
  _fetchLatency() {
    this._measureLatency()
    this.once(REPORT_EVENT, this._measureLatency)
  }

  _buildReport() {
    this._stop('session')
    this._start('session')

    this._fetchExtras()

    this.trigger(REPORT_EVENT, JSON.parse(JSON.stringify(this._metrics)))
  }

  _fetchExtras() {
    // flashls ??? - hls.droppedFramesl hls.stream.bufferLength (seconds)
    // hls ??? (use the same?)
    const fetchFPS = {
     'html5_video': this._html5FetchFPS,
     'hls': this._html5FetchFPS,
     'dash_shaka_playback': this._html5FetchFPS
    }

    fetchFPS[this._playbackName] && fetchFPS[this._playbackName].call(this)

    this._metrics.extra.playbackName = this._playbackName
    this._metrics.extra.playbackType = this._playbackType
  }

  _html5FetchFPS() {
    const videoTag = this.container.playback.el
    const decodedFrames = videoTag.webkitDecodedFrameCount || videoTag.mozDecodedFrames || 0
    const droppedFrames = (videoTag.webkitDroppedFrameCount || (videoTag.mozParsedFrames - videoTag.mozDecodedFrames)) || 0
    const decodedFramesLastTime = decodedFrames - (this._lastDecodedFramesCount || 0)

    this._metrics.counters.decodedFrames = decodedFrames
    this._metrics.counters.droppedFrames = droppedFrames
    this._metrics.counters.fps = decodedFramesLastTime / (this._runEach / 1000)

    this._lastDecodedFramesCount = decodedFrames
  }

  // originally from https://www.smashingmagazine.com/2011/11/analyzing-network-characteristics-using-javascript-and-the-dom-part-1/
  _measureLatency() {
    if (this._uriToMeasureLatency) {
      var t=[], n=2, tcp, rtt;
      var ld = () => {
	t.push(this._now());
	if(t.length > n)
	  done();
	else {
	  var img = new Image;
	  img.onload = ld;
	  img.src=this._uriToMeasureLatency + '?' + Math.random()
	  + '=' + this._now();
	}
      };
      var done = () => {
	rtt=t[2]-t[1]
	tcp=t[1]-t[0]-rtt
        this._metrics.timers.latency = rtt
      };
      ld();
    }
  }
}
<|endoftext|>


<commit_before>var batch = require('level-create-batch');
var sublevel = require('level-sublevel/bytewise');

var bytewise = require('bytewise');
var isarray = require('isarray');
var through = require('through2');
var defined = require('defined');
var readonly = require('read-only-stream');

module.exports = Account;

function Account (db, opts) {
    var self = this;
    if (!(this instanceof Account)) return new Account(db, opts);
    if (!opts) opts = {};

    this._db = sublevel(db).sublevel('account', {
        keyEncoding: bytewise,
        valueEncoding: opts.valueEncoding || 'json'
    });

    this._logins = opts.login || {};
    Object.keys(opts.login || {}).forEach(function (key) {
        var lg = opts.login[key];
        self._logins[key] = lg(self._db, {
            data: function (x) { return [ 'login', key ].concat(x) },
            id: function (x) { return [ 'login-id' ].concat(x).concat(key) }
        });
    });
}

Account.prototype.register = function (type, lg) {
    this._logins[type] = lg(this._db, [ 'login', type ]);
};

Account.prototype.create = function (id, opts, cb) {
    if (!opts) opts = {};
    var rows = [];
    var value = opts.value === undefined ? {} : opts.value;

    var rows = [
        { key: [ 'account', id ], value: value }
    ];

    var keys = Object.keys(opts.login || {});
    for (var i = 0; i < keys.length; i++) {
        var key = keys[i];
        var lg = this._logins[key];

        var creds = opts.login[key];
        if (!lg) return nextErr(cb, 'login not registered for type: ' + key);

        var xrows = lg.create(id, creds);
        if (!xrows) return nextErr(cb, 'login did not return any rows');
        if (!isarray(xrows)) return nextErr(cb, xrows);

        rows.push.apply(rows, xrows);
    }
    batch(this._db, rows, function (err) { if (cb) cb(err) });
};

Account.prototype.get = function (id, cb) {
    this._db.get([ 'account', id ], cb);
};

Account.prototype.put = function (id, value, cb) {
    // TODO: refuse to create new entries, should use create() for that
    this._db.put([ 'account', id ], value, cb);
};

Account.prototype.remove = function (id, cb) {
    // TODO: batch delete all login data for the given id
    this._db.del([ 'account', id ], cb);
};

Account.prototype.list = function (opts) {
    if (!opts) opts = {};
    var gt = defined(opts.gt, opts.start, null);
    var lt = defined(opts.lt, opts.end, undefined);
    // todo: gte, lte

    var dopts = {
        gt: [ 'account', gt ],
        lt: [ 'account', lt ],
        keys: defined(opts.keys, true),
        values: defined(opts.values, true)
    };
    var s = this._db.createReadStream(dopts);

    return s.pipe(through.obj(function (row, enc, next) {
        if (dopts.keys && !dopts.values) {
            this.push(row.key[1]);
        }
        else if (!dopts.keys && dopts.values) {
            this.push(row);
        }
        else {
            this.push({
                key: row.key[1],
                value: row.value
            });
        }
        next();
    }));
};

Account.prototype.addLogin = function (id, type, creds, cb) {
    var lg = this._logins[type];
    if (!lg) return nextErr(cb, 'No login registered for type: ' + type);
    var xrows = lg.create(id, creds);
    if (!xrows) return nextErr(cb, 'login did not return any rows');
    if (!isarray(xrows)) return nextErr(cb, xrows);
    batch(this._db, xrows, function (err) {
        if (err && cb) cb(err)
        else if (cb) cb(null)
    });
};

Account.prototype.listLogin = function (id, cb) {
    var s = this._db.createReadStream({
        gt: [ 'login-id', id, null ],
        lt: [ 'login-id', id, undefined ]
    });
    var tr = through.obj(function (row, enc, next) {
        this.push(row.key.slice(2));
        next();
    });
    return readonly(s.pipe(tr));
};

Account.prototype.verify = function (type, creds, cb) {
    var lg = this._logins[type];
    if (!lg) return nextErr(cb, 'No login registered for type: ' + type);
    lg.verify(creds, cb);
};

function nextErr (cb, msg) {
    if (cb) process.nextTick(function () {
        cb(typeof msg === 'string' ? new Error(msg) : msg);
    });
}
<commit_msg>listLogin in a way that doesn't interfere with existing plugins<commit_after>var batch = require('level-create-batch');
var sublevel = require('level-sublevel/bytewise');

var bytewise = require('bytewise');
var isarray = require('isarray');
var through = require('through2');
var defined = require('defined');
var readonly = require('read-only-stream');

module.exports = Account;

function Account (db, opts) {
    var self = this;
    if (!(this instanceof Account)) return new Account(db, opts);
    if (!opts) opts = {};

    this._db = sublevel(db).sublevel('account', {
        keyEncoding: bytewise,
        valueEncoding: opts.valueEncoding || 'json'
    });

    this._logins = opts.login || {};
    Object.keys(opts.login || {}).forEach(function (key) {
        var lg = opts.login[key];
        self._logins[key] = lg(self._db, [ 'login', key ]);
    });
}

Account.prototype.register = function (type, lg) {
    this._logins[type] = lg(this._db, [ 'login', type ]);
};

Account.prototype.create = function (id, opts, cb) {
    if (!opts) opts = {};
    var rows = [];
    var value = opts.value === undefined ? {} : opts.value;

    var rows = [
        { key: [ 'account', id ], value: value }
    ];

    var keys = Object.keys(opts.login || {});
    for (var i = 0; i < keys.length; i++) {
        var key = keys[i];
        var lg = this._logins[key];

        var creds = opts.login[key];
        if (!lg) return nextErr(cb, 'login not registered for type: ' + key);

        var xrows = lg.create(id, creds);
        if (!xrows) return nextErr(cb, 'login did not return any rows');
        if (!isarray(xrows)) return nextErr(cb, xrows);

        rows.push.apply(rows, xrows);
        rows.push({ key: [ 'login-id', id, key ], value: 0 });
    }
    batch(this._db, rows, function (err) { if (cb) cb(err) });
};

Account.prototype.get = function (id, cb) {
    this._db.get([ 'account', id ], cb);
};

Account.prototype.put = function (id, value, cb) {
    // TODO: refuse to create new entries, should use create() for that
    this._db.put([ 'account', id ], value, cb);
};

Account.prototype.remove = function (id, cb) {
    // TODO: batch delete all login data for the given id
    this._db.del([ 'account', id ], cb);
};

Account.prototype.list = function (opts) {
    if (!opts) opts = {};
    var gt = defined(opts.gt, opts.start, null);
    var lt = defined(opts.lt, opts.end, undefined);
    // todo: gte, lte

    var dopts = {
        gt: [ 'account', gt ],
        lt: [ 'account', lt ],
        keys: defined(opts.keys, true),
        values: defined(opts.values, true)
    };
    var s = this._db.createReadStream(dopts);

    return s.pipe(through.obj(function (row, enc, next) {
        if (dopts.keys && !dopts.values) {
            this.push(row.key[1]);
        }
        else if (!dopts.keys && dopts.values) {
            this.push(row);
        }
        else {
            this.push({
                key: row.key[1],
                value: row.value
            });
        }
        next();
    }));
};

Account.prototype.addLogin = function (id, type, creds, cb) {
    var lg = this._logins[type];
    if (!lg) return nextErr(cb, 'No login registered for type: ' + type);
    var xrows = lg.create(id, creds);
    if (!xrows) return nextErr(cb, 'login did not return any rows');
    if (!isarray(xrows)) return nextErr(cb, xrows);

    xrows.push({ key: [ 'login-id', id, type ], value: 0 });

    batch(this._db, xrows, function (err) {
        if (err && cb) cb(err)
        else if (cb) cb(null)
    });
};

Account.prototype.listLogin = function (id, cb) {
    var s = this._db.createReadStream({
        gt: [ 'login-id', id, null ],
        lt: [ 'login-id', id, undefined ]
    });
    var tr = through.obj(function (row, enc, next) {
        this.push(row.key[2]);
        next();
    });
    return readonly(s.pipe(tr));
};

Account.prototype.verify = function (type, creds, cb) {
    var lg = this._logins[type];
    if (!lg) return nextErr(cb, 'No login registered for type: ' + type);
    lg.verify(creds, cb);
};

function nextErr (cb, msg) {
    if (cb) process.nextTick(function () {
        cb(typeof msg === 'string' ? new Error(msg) : msg);
    });
}
<|endoftext|>


<commit_before>'use strict';

const glob = require('glob-all');
const fs = require('fs');
const path = require('path');
const mime = require('mime-types');
const BbPromise = require('bluebird');

const globOpts = {
  nodir: true
};

class Assets {
  constructor (serverless, options) {
    this.serverless = serverless;
    this.options = options;
    this.provider = this.serverless.getProvider('aws');

    let config = this.serverless.service.custom.assets;
    if(Array.isArray(config)) {
      config = {targets: config};
    }

    this.config = Object.assign({}, {
      auto: false,
      verbose: false,
      resolveReferences: true,
      targets: [],
      uploadConcurrency: 3,
    }, config);

    this.commands = {
      s3deploy: {
        usage: 'Deploy assets to S3 bucket',
        lifecycleEvents: [
          'deploy'
        ],
        options: {
          verbose: {
            usage: 'Increase verbosity',
            shortcut: 'v'
          },
          bucket: {
            usage: 'Limit the deploy to a specific bucket',
            shortcut: 'b'
          }
        }
      }
    };

    this.hooks = {
      's3deploy:deploy': () => Promise.resolve().then(this.deployS3.bind(this)),
      'after:deploy:finalize': () => Promise.resolve().then(this.afterDeploy.bind(this))
    };
  }

  /*
   * Handy method for logging (when `verbose` is set)
   * Also log on the default serverless SLS_DEBUG env
   */
  log(message) {
    if(this.options.verbose || process.env.SLS_DEBUG || this.config.verbose) {
      this.serverless.cli.log(message);
    }
  }

  afterDeploy() {
    if(this.config.auto) {
      return this.deployS3();
    }
  }

  listStackResources(resources, nextToken) {
    resources = resources || [];
    if (!this.config.resolveReferences) {
      return BbPromise.resolve(resources);
    }
    return this.provider.request('CloudFormation', 'listStackResources', { StackName: this.provider.naming.getStackName(), NextToken: nextToken })
      .then(response => {
        resources.push.apply(resources, response.StackResourceSummaries);
        if (response.NextToken) {
        // Query next page
          return this.listStackResources(resources, response.NextToken);
        }
      })
      .return(resources);
  }

  resolveBucket(resources, value) {
    if (typeof value === 'string') {
      return BbPromise.resolve(value);
    }
    else if (value && value.Ref) {
      let resolved;
      resources.forEach(resource => {
        if (resource && resource.LogicalResourceId === value.Ref) {
          resolved = resource.PhysicalResourceId;
        }
      });

      if (!resolved) {
        this.serverless.cli.log(`WARNING: Failed to resolve reference ${value.Ref}`);
      }
      return BbPromise.resolve(resolved);
    }
    else {
      return BbPromise.reject(new Error(`Invalid bucket name ${value}`));
    }
  }

  emptyBucket(bucket, dir) {
    const listParams = {
      Bucket: bucket,
      Prefix: dir
    };

    return this.provider.request('S3', 'listObjectsV2', listParams)
      .then((listedObjects) => {
        if (listedObjects.Contents.length === 0) return;

        const deleteParams = {
          Bucket: bucket,
          Delete: { Objects: [] }
        };

        listedObjects.Contents.forEach(({ Key }) => {
          deleteParams.Delete.Objects.push({ Key });
        });
        return this.provider.request('S3', 'deleteObjects', deleteParams)
          .then(() => {
            if (listedObjects.Contents.IsTruncated) {
              this.log('Is not finished. Rerun emptyBucket');
              return this.emptyBucket(bucket, dir);
            }
          });
      });
  }

  deployS3() {
    let assetSets = this.config.targets;
    let uploadConcurrency = this.config.uploadConcurrency;

    // Read existing stack resources so we can resolve references if necessary
    return this.listStackResources()
      .then(resources => {
      // Process asset sets in parallel (up to 3)
        return BbPromise.map(assetSets, assets => {
          const prefix = assets.prefix || '';
          // Try to resolve the bucket name
          return this.resolveBucket(resources, assets.bucket)
            .then((bucket) => {
              if (this.options.bucket && this.options.bucket !== bucket) {
                this.log(`Skipping bucket: ${bucket}`);
                return Promise.resolve('');
              }

              if(assets.empty) {
                this.log(`Emptying bucket: ${bucket}`);
                return this.emptyBucket(bucket, prefix)
                  .then(() => bucket);
              }
              return Promise.resolve(bucket);
            }).then(bucket => {
              if (!bucket) {
                return;
              }

              // Process files serially to not overload the network
              return BbPromise.each(assets.files, (opt) => {
                this.log(`Sync bucket: ${bucket}:${prefix}`);
                this.log(`Path: ${opt.source}`);

                const cfg = Object.assign({}, globOpts, { cwd: opt.source });
                const filenames = glob.sync(opt.globs, cfg);
                return BbPromise.each(filenames, (filename) => {
                  const body = fs.readFileSync(path.join(opt.source, filename));
                  const type = mime.lookup(filename) || opt.defaultContentType || 'application/octet-stream';

                  this.log(`\tFile:  ${filename} (${type})`);

                  // when using windows path join resolves to backslashes, but s3 is expecting a slash
                  // therefore replace all backslashes with slashes
                  const key = path
                    .join(prefix, filename)
                    .replace(/\\/g, '/');

                  const details = Object.assign(
                    {
                      ACL: assets.acl || 'private',
                      Body: body,
                      Bucket: bucket,
                      Key: key,
                      ContentType: type
                    },
                    opt.headers || {}
                  );

                  return this.provider.request('S3', 'putObject', details);
                });
              });
            });
        },
        { concurrency: uploadConcurrency }
        );
      });
  }
}

module.exports = Assets;
<commit_msg>List stack resources function fixed<commit_after>'use strict';

const glob = require('glob-all');
const fs = require('fs');
const path = require('path');
const mime = require('mime-types');
const BbPromise = require('bluebird');

const globOpts = {
  nodir: true
};

class Assets {
  constructor (serverless, options) {
    this.serverless = serverless;
    this.options = options;
    this.provider = this.serverless.getProvider('aws');

    let config = this.serverless.service.custom.assets;
    if(Array.isArray(config)) {
      config = {targets: config};
    }

    this.config = Object.assign({}, {
      auto: false,
      verbose: false,
      resolveReferences: true,
      targets: [],
      uploadConcurrency: 3,
    }, config);

    this.commands = {
      s3deploy: {
        usage: 'Deploy assets to S3 bucket',
        lifecycleEvents: [
          'deploy'
        ],
        options: {
          verbose: {
            usage: 'Increase verbosity',
            shortcut: 'v'
          },
          bucket: {
            usage: 'Limit the deploy to a specific bucket',
            shortcut: 'b'
          }
        }
      }
    };

    this.hooks = {
      's3deploy:deploy': () => Promise.resolve().then(this.deployS3.bind(this)),
      'after:deploy:finalize': () => Promise.resolve().then(this.afterDeploy.bind(this))
    };
  }

  /*
   * Handy method for logging (when `verbose` is set)
   * Also log on the default serverless SLS_DEBUG env
   */
  log(message) {
    if(this.options.verbose || process.env.SLS_DEBUG || this.config.verbose) {
      this.serverless.cli.log(message);
    }
  }

  afterDeploy() {
    if(this.config.auto) {
      return this.deployS3();
    }
  }

  listStackResources(resources, nextToken) {
    resources = resources || [];
    if (!this.config.resolveReferences) {
      return BbPromise.resolve(resources);
    }
    return this.provider.request('CloudFormation', 'listStackResources', { StackName: this.provider.naming.getStackName(), NextToken: nextToken })
      .then(response => {
        resources.push.apply(resources, response.StackResourceSummaries);
        if (response.NextToken) {
        // Query next page
          return this.listStackResources(resources, response.NextToken);
        }
      })
      .then(() => {
        return resources;
      });
  }

  resolveBucket(resources, value) {
    if (typeof value === 'string') {
      return BbPromise.resolve(value);
    }
    else if (value && value.Ref) {
      let resolved;
      resources.forEach(resource => {
        if (resource && resource.LogicalResourceId === value.Ref) {
          resolved = resource.PhysicalResourceId;
        }
      });

      if (!resolved) {
        this.serverless.cli.log(`WARNING: Failed to resolve reference ${value.Ref}`);
      }
      return BbPromise.resolve(resolved);
    }
    else {
      return BbPromise.reject(new Error(`Invalid bucket name ${value}`));
    }
  }

  emptyBucket(bucket, dir) {
    const listParams = {
      Bucket: bucket,
      Prefix: dir
    };

    return this.provider.request('S3', 'listObjectsV2', listParams)
      .then((listedObjects) => {
        if (listedObjects.Contents.length === 0) return;

        const deleteParams = {
          Bucket: bucket,
          Delete: { Objects: [] }
        };

        listedObjects.Contents.forEach(({ Key }) => {
          deleteParams.Delete.Objects.push({ Key });
        });
        return this.provider.request('S3', 'deleteObjects', deleteParams)
          .then(() => {
            if (listedObjects.Contents.IsTruncated) {
              this.log('Is not finished. Rerun emptyBucket');
              return this.emptyBucket(bucket, dir);
            }
          });
      });
  }

  deployS3() {
    let assetSets = this.config.targets;
    let uploadConcurrency = this.config.uploadConcurrency;

    // Read existing stack resources so we can resolve references if necessary
    return this.listStackResources()
      .then(resources => {
      // Process asset sets in parallel (up to 3)
        return BbPromise.map(assetSets, assets => {
          const prefix = assets.prefix || '';
          // Try to resolve the bucket name
          return this.resolveBucket(resources, assets.bucket)
            .then((bucket) => {
              if (this.options.bucket && this.options.bucket !== bucket) {
                this.log(`Skipping bucket: ${bucket}`);
                return Promise.resolve('');
              }

              if(assets.empty) {
                this.log(`Emptying bucket: ${bucket}`);
                return this.emptyBucket(bucket, prefix)
                  .then(() => bucket);
              }
              return Promise.resolve(bucket);
            }).then(bucket => {
              if (!bucket) {
                return;
              }

              // Process files serially to not overload the network
              return BbPromise.each(assets.files, (opt) => {
                this.log(`Sync bucket: ${bucket}:${prefix}`);
                this.log(`Path: ${opt.source}`);

                const cfg = Object.assign({}, globOpts, { cwd: opt.source });
                const filenames = glob.sync(opt.globs, cfg);
                return BbPromise.each(filenames, (filename) => {
                  const body = fs.readFileSync(path.join(opt.source, filename));
                  const type = mime.lookup(filename) || opt.defaultContentType || 'application/octet-stream';

                  this.log(`\tFile:  ${filename} (${type})`);

                  // when using windows path join resolves to backslashes, but s3 is expecting a slash
                  // therefore replace all backslashes with slashes
                  const key = path
                    .join(prefix, filename)
                    .replace(/\\/g, '/');

                  const details = Object.assign(
                    {
                      ACL: assets.acl || 'private',
                      Body: body,
                      Bucket: bucket,
                      Key: key,
                      ContentType: type
                    },
                    opt.headers || {}
                  );

                  return this.provider.request('S3', 'putObject', details);
                });
              });
            });
        },
        { concurrency: uploadConcurrency }
        );
      });
  }
}

module.exports = Assets;
<|endoftext|>


<commit_before>'use strict'

const express = require('express')
const app = express()
const bodyParser = require('body-parser')
const twitterParse = require('twitter-url-parser')
const twitterAPI = require('node-twitter-api')
const twitter = new twitterAPI({
  consumerKey: process.env.TWITTER_CONSUMER_KEY,
  consumerSecret: process.env.TWITTER_CONSUMER_SECRET,
  callback: process.env.TWITTER_OAUTH_CALLBACK || 'http://localhost:8080/oauth'
})
let sessionRequestToken
let sessionRequestTokenSecret
let sessionAccessToken
let sessionAccessTokenSecret

twitter.getRequestToken(function (error, requestToken, requestTokenSecret, results) {
  if (error) {
    console.log('Error getting OAuth request token : ' + error)
  } else {
    sessionRequestToken = requestToken
    sessionRequestTokenSecret = requestTokenSecret

    console.log(twitter.getAuthUrl(sessionRequestToken))
  }
})

app.use(bodyParser.json())

app.post('/', (req, res) => {
  twitter.search(
    { q: '"' + req.body.text + '"' },
    sessionRequestToken,
    sessionRequestTokenSecret,
    (err, data, response) => {
      console.log('error: ' + err)
      console.log('data: ' + data)
    })

  res.end()
})

app.get('/oauth', (req, res) => {
  twitter.getAccessToken(
    sessionRequestToken,
    sessionRequestTokenSecret,
    req.query.oauth_verifier,
    (error, accessToken, accessTokenSecret, results) => {
      if (error) {
        console.log(error)
      } else {
        sessionAccessToken = accessToken
        sessionAccessTokenSecret = accessTokenSecret
        twitter.verifyCredentials(
          sessionAccessToken,
          sessionAccessTokenSecret,
          {},
          (error, data, response) => {
            if (error) {
              console.log(error)
            } else {
              // accessToken and accessTokenSecret can now be used to make api-calls (not yet implemented)
              // data contains the user-data described in the official Twitter-API-docs
              // you could e.g. display his screen_name
              console.log(data['screen_name'])
            }
          })
      }
    })

  res.end()
})

app.listen(process.env.PORT || 8080, () => console.log('listening ' + (process.env.PORT || 8080)))
<commit_msg>Rever to using access token<commit_after>'use strict'

const express = require('express')
const app = express()
const bodyParser = require('body-parser')
const twitterParse = require('twitter-url-parser')
const twitterAPI = require('node-twitter-api')
const twitter = new twitterAPI({
  consumerKey: process.env.TWITTER_CONSUMER_KEY,
  consumerSecret: process.env.TWITTER_CONSUMER_SECRET,
  callback: process.env.TWITTER_OAUTH_CALLBACK || 'http://localhost:8080/oauth'
})
let sessionRequestToken
let sessionRequestTokenSecret
let sessionAccessToken
let sessionAccessTokenSecret

twitter.getRequestToken(function (error, requestToken, requestTokenSecret, results) {
  if (error) {
    console.log('Error getting OAuth request token : ' + error)
  } else {
    sessionRequestToken = requestToken
    sessionRequestTokenSecret = requestTokenSecret

    console.log(twitter.getAuthUrl(sessionRequestToken))
  }
})

app.use(bodyParser.json())

app.post('/', (req, res) => {
  twitter.search(
    { q: '"' + req.body.text + '"' },
    sessionAccessToken,
    sessionAccessTokenSecret,
    (err, data, response) => {
      console.log('error: ' + err)
      console.log('data: ' + data)
    })

  res.end()
})

app.get('/oauth', (req, res) => {
  twitter.getAccessToken(
    sessionRequestToken,
    sessionRequestTokenSecret,
    req.query.oauth_verifier,
    (error, accessToken, accessTokenSecret, results) => {
      if (error) {
        console.log(error)
      } else {
        sessionAccessToken = accessToken
        sessionAccessTokenSecret = accessTokenSecret
        twitter.verifyCredentials(
          sessionAccessToken,
          sessionAccessTokenSecret,
          {},
          (error, data, response) => {
            if (error) {
              console.log(error)
            } else {
              // accessToken and accessTokenSecret can now be used to make api-calls (not yet implemented)
              // data contains the user-data described in the official Twitter-API-docs
              // you could e.g. display his screen_name
              console.log(data['screen_name'])
            }
          })
      }
    })

  res.end()
})

app.listen(process.env.PORT || 8080, () => console.log('listening ' + (process.env.PORT || 8080)))
<|endoftext|>


<commit_before>/*!
 * docket <https://github.com/doowb/docket>
 *
 * Copyright (c) 2015, Brian Woodward.
 * Licensed under the MIT License.
 */

'use strict';

var Base = require('base-methods').namespace('cache');
var Scaffold = require('scaffold');

var utils = require('./lib/utils');

function Docket (cache, options) {
  if (!(this instanceof Docket)) {
    return new Docket(cache, options);
  }
  Base.call(this);
  this.options = options || {};

  this.define('cache', cache || {});
  this.define('plugins', []);

  utils.defaultProperties(this);
  this.set('config', {});
  this.set('isDocket', true);
}

Base.extend(Docket);

Docket.prototype.use = function(fn) {
  var plugin = fn.call(this, this, this.options);
  if (typeof plugin === 'function') {
    this.plugins.push(plugin);
  }
  this.emit('use');
  return this;
};

/**
 * Add a property to the `Docket` prototype
 */

Docket.prototype.mixin = function(key, value) {
  Docket.prototype[key] = value;
};

Docket.prototype.addScaffold = function(key, config) {
  var scaffold = new Scaffold(config);
  scaffold.key = scaffold.key || key;
  this.cache.targets[key] = scaffold;
  this.plugins.forEach(function (fn) {
    fn.call(this, scaffold, this.options);
  }.bind(this));
};

Docket.prototype.addScaffolds = function(config) {
  return this.visit('addScaffold', config);
};

Docket.prototype.toJSON = function() {
  return this.cache;
};

Docket.prototype.load = function(manifest) {
  if (typeof manifest === 'object') {
    if (manifest.isDocket) {
      this.cache = manifest;
      return this;
    }
    var targets = {};
    if (manifest.hasOwnProperty('targets')) {
      targets = manifest.targets;
      delete manifest.targets;
    }
    return this.visit('set', manifest)
      .addScaffolds(targets);
  }
};

module.exports = Docket;
<commit_msg>start adding dependencies<commit_after>/*!
 * docket <https://github.com/doowb/docket>
 *
 * Copyright (c) 2015, Brian Woodward.
 * Licensed under the MIT License.
 */

'use strict';

var Base = require('base-methods').namespace('cache');
var Scaffold = require('scaffold');

var utils = require('./lib/utils');

function Docket (cache, options) {
  if (!(this instanceof Docket)) {
    return new Docket(cache, options);
  }
  Base.call(this);
  this.options = options || {};

  this.define('cache', cache || {});
  this.define('plugins', []);

  utils.defaultProperties(this);
  this.set('config', {});
  this.set('isDocket', true);
}

Base.extend(Docket);

Docket.prototype.use = function(fn) {
  var plugin = fn.call(this, this, this.options);
  if (typeof plugin === 'function') {
    this.plugins.push(plugin);
  }
  this.emit('use');
  return this;
};

/**
 * Add a property to the `Docket` prototype
 */

Docket.prototype.mixin = function(key, value) {
  Docket.prototype[key] = value;
};

Docket.prototype.addDependency = function(key, val) {
  if (typeof key === 'object') {
    return this.visit('addDependency', key);
  }
  return this.set('dependencies.' + key, val);
};

Docket.prototype.addDependencies = function(deps) {
  return this.visit('addDependency', deps);
};

Docket.prototype.addTarget = function(key, config) {
  var scaffold = new Scaffold(config);
  scaffold.key = scaffold.key || key;
  this.cache.targets[key] = scaffold;
  this.plugins.forEach(function (fn) {
    fn.call(this, scaffold, this.options);
  }.bind(this));
};

Docket.prototype.addTargets = function(config) {
  return this.visit('addTarget', config);
};

Docket.prototype.toJSON = function() {
  return this.cache;
};

Docket.prototype.load = function(manifest) {
  if (typeof manifest === 'object') {
    if (manifest.isDocket) {
      this.cache = manifest;
      return this;
    }
    var targets = {};
    if (manifest.hasOwnProperty('targets')) {
      targets = manifest.targets;
      delete manifest.targets;
    }
    return this.visit('set', manifest)
      .addTargets(targets);
  }
};

module.exports = Docket;
<|endoftext|>