<commit_before>'use strict';
var util = require('util');
var bcrypt = require('bcrypt');
var TokenStore = require('passwordless-tokenstore');
var r = require('rethinkdb');

/**
 * RethinkDBStore constructor
 * @param {Object} options RethinkDB options
 */
function RethinkDBStore(options, hashLib) {
    this.options = options || {};
    this.hashLib = hashLib || {
        hash: function(token, cb) {
            bcrypt.hash(token, 10, cb);
        },
        verify: function(token, hashedToken, cb) {
            bcrypt.compare(token, hashedToken, cb);
        }
    };
    TokenStore.call(this);
    this.connection = null;
};

util.inherits(RethinkDBStore, TokenStore);

/**
 * Open a connection to RethinkDB and create `pwdless`
 * table if it doesn't exist
 * @param  {Function} callback
 * @return {Connection}
 */
RethinkDBStore.prototype.getConnection = function getConnection(callback) {
    var self = this;
    if (this.connection) return callback(this.connection);
    r.connect(this.options, function (err, connection) {
        if (err) throw err;
        self.connection = connection;
        r.tableList().run(self.connection, function (err, list) {
            if (!list.length || list.indexOf('pwdless') == -1) {
                r.tableCreate('pwdless').run(connection, function (err, res) {
                    if (err) throw err;
                    return callback(connection);
                });
            }
            return callback(connection);
        });
    });
};

/**
 * Checks if the provided token / user id combination exists and is
 * valid in terms of time-to-live. If yes, the method provides the
 * the stored referrer URL if any.
 * @param  {String}   token to be authenticated
 * @param  {String}   uid Unique identifier of an user
 * @param  {Function} callback in the format (error, valid, referrer).
 * In case of error, error will provide details, valid will be false and
 * referrer will be null. If the token / uid combination was not found
 * found, valid will be false and all else null. Otherwise, valid will
 * be true, referrer will (if provided when the token was stored) the
 * original URL requested and error will be null.
 */
RethinkDBStore.prototype.authenticate = function authenticate(token, uid, callback) {
    if(!token || !uid || !callback) {
        throw new Error('TokenStore:authenticate called with invalid parameters');
    }
    var hashLib = this.hashLib;
    this.getConnection(function (conn) {
        r.table('pwdless').get(uid).run(conn, function (err, doc) {
            if (err) return callback(err, false, null);
            if (doc == null || doc.ttl < Date.now()) return callback(null, false, null);
            hashLib.verify(token, doc.hashedToken, function (err, res) {
                if (err) return callback(err, false, null);
                if (res) return callback(null, true, doc.originUrl);
                return callback(null, false, null);
            });
        });
    });
};

/**
 * Stores a new token / user ID combination or updates the token of an
 * existing user ID if that ID already exists. Hence, a user can only
 * have one valid token at a time
 * @param  {String}   token Token that allows authentication of _uid_
 * @param  {String}   uid Unique identifier of an user
 * @param  {Number}   msToLive Validity of the token in ms
 * @param  {String}   originUrl Originally requested URL or null
 * @param  {Function} callback Called with callback(error) in case of an
 * error or as callback() if the token was successully stored / updated
 */
RethinkDBStore.prototype.storeOrUpdate = function(token, uid, msToLive, originUrl, callback) {
    if(!token || !uid || !msToLive || !callback || !isNumber(msToLive)) {
        throw new Error('TokenStore:storeOrUpdate called with invalid parameters');
    }

    var hashLib = this.hashLib;
    this.getConnection(function (conn) {
        hashLib.hash(token, function (err, hashedToken) {
            if (err) return callback(err);
            var newRecord = {
                id: uid,
                hashedToken: hashedToken,
                ttl: Date.now() + msToLive,
                originUrl: originUrl || ''
            };
            r.table('pwdless').get(uid).run(conn, function (err, doc) {
                if (err) return callback(err);
                if (doc == null) {
                    r.table('pwdless').insert(newRecord).run(conn, function (err, doc) {
                        if (err) return callback(err);
                        return callback();
                    });
                } else {
                    r.table('pwdless').get(uid).update(newRecord).run(conn, function (err, res) {
                        if (err) return callback(err);
                        return callback();
                    });
                }
            });
        });
    });
};

/**
 * Invalidates and removes a user and the linked token
 * @param  {String}   user ID
 * @param  {Function} callback called with callback(error) in case of an
 * error or as callback() if the uid was successully invalidated
 */
RethinkDBStore.prototype.invalidateUser = function(uid, callback) {
    if(!uid || !callback) {
        throw new Error('TokenStore:invalidateUser called with invalid parameters');
    }

    this.getConnection(function (conn) {
        r.table('pwdless').get(uid).run(conn, function (err, doc) {
            if (err) return callback();
            r.table('pwdless').get(uid).delete().run(conn, function (err) {
                return callback();
            });
        });
    });
};

/**
 * Removes and invalidates all token
 * @param  {Function} callback Called with callback(error) in case of an
 * error or as callback() otherwise
 */
RethinkDBStore.prototype.clear = function(callback) {
    if(!callback) {
        throw new Error('TokenStore:clear called with invalid parameters');
    }
    var self = this;
    this.getConnection(function (conn) {
        r.table('pwdless').delete().run(conn);
        self.connection = null;
        callback();
    });
};

/**
 * Number of tokens stored (no matter the validity)
 * @param  {Function} callback Called with callback(null, count) in case
 * of success or with callback(error) in case of an error
 */
RethinkDBStore.prototype.length = function(callback) {
    if(!callback) {
        throw new Error('TokenStore:length called with invalid parameters');
    }
    this.getConnection(function (conn) {
        r.table('pwdless').count().run(conn, function (err, count) {
            if (err) return callback(err);
            return callback(null, count);
        });
    });
};

function isNumber(n) {
    return !isNaN(parseFloat(n)) && isFinite(n);
};

module.exports = RethinkDBStore;
<commit_msg>doc: add comment for hashLib param of ctor<commit_after>'use strict';
var util = require('util');
var bcrypt = require('bcrypt');
var TokenStore = require('passwordless-tokenstore');
var r = require('rethinkdb');

/**
 * RethinkDBStore constructor
 * @param {Object} options RethinkDB options
 * @param {Object} hashLib Hash and verify function for the token
 */
function RethinkDBStore(options, hashLib) {
    this.options = options || {};
    this.hashLib = hashLib || {
        hash: function(token, cb) {
            bcrypt.hash(token, 10, cb);
        },
        verify: function(token, hashedToken, cb) {
            bcrypt.compare(token, hashedToken, cb);
        }
    };
    TokenStore.call(this);
    this.connection = null;
};

util.inherits(RethinkDBStore, TokenStore);

/**
 * Open a connection to RethinkDB and create `pwdless`
 * table if it doesn't exist
 * @param  {Function} callback
 * @return {Connection}
 */
RethinkDBStore.prototype.getConnection = function getConnection(callback) {
    var self = this;
    if (this.connection) return callback(this.connection);
    r.connect(this.options, function (err, connection) {
        if (err) throw err;
        self.connection = connection;
        r.tableList().run(self.connection, function (err, list) {
            if (!list.length || list.indexOf('pwdless') == -1) {
                r.tableCreate('pwdless').run(connection, function (err, res) {
                    if (err) throw err;
                    return callback(connection);
                });
            }
            return callback(connection);
        });
    });
};

/**
 * Checks if the provided token / user id combination exists and is
 * valid in terms of time-to-live. If yes, the method provides the
 * the stored referrer URL if any.
 * @param  {String}   token to be authenticated
 * @param  {String}   uid Unique identifier of an user
 * @param  {Function} callback in the format (error, valid, referrer).
 * In case of error, error will provide details, valid will be false and
 * referrer will be null. If the token / uid combination was not found
 * found, valid will be false and all else null. Otherwise, valid will
 * be true, referrer will (if provided when the token was stored) the
 * original URL requested and error will be null.
 */
RethinkDBStore.prototype.authenticate = function authenticate(token, uid, callback) {
    if(!token || !uid || !callback) {
        throw new Error('TokenStore:authenticate called with invalid parameters');
    }
    var hashLib = this.hashLib;
    this.getConnection(function (conn) {
        r.table('pwdless').get(uid).run(conn, function (err, doc) {
            if (err) return callback(err, false, null);
            if (doc == null || doc.ttl < Date.now()) return callback(null, false, null);
            hashLib.verify(token, doc.hashedToken, function (err, res) {
                if (err) return callback(err, false, null);
                if (res) return callback(null, true, doc.originUrl);
                return callback(null, false, null);
            });
        });
    });
};

/**
 * Stores a new token / user ID combination or updates the token of an
 * existing user ID if that ID already exists. Hence, a user can only
 * have one valid token at a time
 * @param  {String}   token Token that allows authentication of _uid_
 * @param  {String}   uid Unique identifier of an user
 * @param  {Number}   msToLive Validity of the token in ms
 * @param  {String}   originUrl Originally requested URL or null
 * @param  {Function} callback Called with callback(error) in case of an
 * error or as callback() if the token was successully stored / updated
 */
RethinkDBStore.prototype.storeOrUpdate = function(token, uid, msToLive, originUrl, callback) {
    if(!token || !uid || !msToLive || !callback || !isNumber(msToLive)) {
        throw new Error('TokenStore:storeOrUpdate called with invalid parameters');
    }

    var hashLib = this.hashLib;
    this.getConnection(function (conn) {
        hashLib.hash(token, function (err, hashedToken) {
            if (err) return callback(err);
            var newRecord = {
                id: uid,
                hashedToken: hashedToken,
                ttl: Date.now() + msToLive,
                originUrl: originUrl || ''
            };
            r.table('pwdless').get(uid).run(conn, function (err, doc) {
                if (err) return callback(err);
                if (doc == null) {
                    r.table('pwdless').insert(newRecord).run(conn, function (err, doc) {
                        if (err) return callback(err);
                        return callback();
                    });
                } else {
                    r.table('pwdless').get(uid).update(newRecord).run(conn, function (err, res) {
                        if (err) return callback(err);
                        return callback();
                    });
                }
            });
        });
    });
};

/**
 * Invalidates and removes a user and the linked token
 * @param  {String}   user ID
 * @param  {Function} callback called with callback(error) in case of an
 * error or as callback() if the uid was successully invalidated
 */
RethinkDBStore.prototype.invalidateUser = function(uid, callback) {
    if(!uid || !callback) {
        throw new Error('TokenStore:invalidateUser called with invalid parameters');
    }

    this.getConnection(function (conn) {
        r.table('pwdless').get(uid).run(conn, function (err, doc) {
            if (err) return callback();
            r.table('pwdless').get(uid).delete().run(conn, function (err) {
                return callback();
            });
        });
    });
};

/**
 * Removes and invalidates all token
 * @param  {Function} callback Called with callback(error) in case of an
 * error or as callback() otherwise
 */
RethinkDBStore.prototype.clear = function(callback) {
    if(!callback) {
        throw new Error('TokenStore:clear called with invalid parameters');
    }
    var self = this;
    this.getConnection(function (conn) {
        r.table('pwdless').delete().run(conn);
        self.connection = null;
        callback();
    });
};

/**
 * Number of tokens stored (no matter the validity)
 * @param  {Function} callback Called with callback(null, count) in case
 * of success or with callback(error) in case of an error
 */
RethinkDBStore.prototype.length = function(callback) {
    if(!callback) {
        throw new Error('TokenStore:length called with invalid parameters');
    }
    this.getConnection(function (conn) {
        r.table('pwdless').count().run(conn, function (err, count) {
            if (err) return callback(err);
            return callback(null, count);
        });
    });
};

function isNumber(n) {
    return !isNaN(parseFloat(n)) && isFinite(n);
};

module.exports = RethinkDBStore;
<|endoftext|>


<commit_before>const http = require('http');
const ws = require('ws');
const path = require('path');
const events = require('events');
const util = require('util');
const async = require('async');
const url = require('url');
const stream = require('stream');

function Client() {
  events.EventEmitter.call(this);

  this._socket = null;

  this._callbacks = [];
  this._counter = 0;

  this._scripts = [];
  this._console = new stream.Readable({ objectMode: true });
  this._console._read = function() { };
}

util.inherits(Client, events.EventEmitter);

Object.defineProperty(Client.prototype, 'socket', {
  get: function() {
    return this._socket;
  },
});

Object.defineProperty(Client.prototype, 'console', {
  get: function() {
    return this._console;
  },
});

Client.prototype.sendCommand = function(method, params, callback) {
  try {
    var id = this._counter++;

    this._socket.send(JSON.stringify({
      id: id,
      method: method,
      params: params
    }));
    this._callbacks[id] = callback;
  } catch (error) {
    return callback(error);
  }
};

Client.prototype.processCommand = function(message) {
  var callback = this._callbacks[message.id];

  if (callback) {
    if (message.error) {
      return callback(message.error);
    } else if (message.result) {
      return callback(null, message.result);
    } else if (message.params) {
      return callback(null, message.params);
    }
  }

  if (message.method === 'Console.messageAdded') {
    return this._console.push(message.params.message);
  }

  if (message.method === 'Debugger.scriptParsed') {
    this._scripts = this._scripts.filter(function(script) {
      return message.params.url !== script.url;
    });

    this._scripts.push(message.params);
    return this.emit('scriptParse', message.params);
  }
};

Client.prototype.attach = function attach(target) {
  var socket = ws.connect(target.webSocketDebuggerUrl);

  var self = this;

  socket.on('open', function() {
    self.emit('attach');
  });

  socket.on('close', function() {
    self.emit('detatch');
  });

  socket.on('error', function(error) {
    self.emit('error', error);
  });

  socket.on('message', function(data) {
    try {
      var message = JSON.parse(data);
      self.processCommand(message);
    } catch (error) {
      self.emit('error', error);
    }
  });

  this._socket = socket;
};

Client.prototype.detatch = function() {
  if (this._socket) {
    this._socket.close();
  }
};

Client.prototype.evaluate = function evaluate(expression, callback) {
  this.sendCommand('Runtime.evaluate', {
    expression: expression,
  }, callback);
};

Client.prototype.getScripts = function scripts(callback) {
  callback(this._scripts);
};

Client.prototype.getScriptSource = function(script, callback) {
  this.sendCommand('Debugger.getScriptSource', {
    scriptId: script.scriptId,
  }, callback);
};

Client.prototype.setScriptSource = function source(script, contents, callback) {
  this.sendCommand('Debugger.setScriptSource', {
    scriptId: script.scriptId,
    scriptSource: contents
  }, callback);
};

module.exports.Client = Client;

function createClient() {
  var client = new Client();
  return client;
}

module.exports.createClient = createClient;

function get(port, host, callback) {
  var request = http.get({
    port: port,
    host: host,
    path: '/json'
  });

  request.on('response', function(response) {
    var body = '';

    response.on('data', function(chunk) {
      body += chunk;
    });

    response.on('end', function() {
      try {
        var targets = JSON.parse(body);
        return callback(null, targets);
      } catch (error) {
        return callback(error);
      }
    });
  });

  request.on('error', function(error) {
    return callback(error);
  });
};

module.exports.get = get;
<commit_msg>Allow target parameter of Client.prototype.attach to be a url string or target object<commit_after>const http = require('http');
const ws = require('ws');
const path = require('path');
const events = require('events');
const util = require('util');
const async = require('async');
const url = require('url');
const stream = require('stream');

function Client() {
  events.EventEmitter.call(this);

  this._socket = null;

  this._callbacks = [];
  this._counter = 0;

  this._scripts = [];
  this._console = new stream.Readable({ objectMode: true });
  this._console._read = function() { };
}

util.inherits(Client, events.EventEmitter);

Object.defineProperty(Client.prototype, 'socket', {
  get: function() {
    return this._socket;
  },
});

Object.defineProperty(Client.prototype, 'console', {
  get: function() {
    return this._console;
  },
});

Client.prototype.sendCommand = function(method, params, callback) {
  try {
    var id = this._counter++;

    this._socket.send(JSON.stringify({
      id: id,
      method: method,
      params: params
    }));
    this._callbacks[id] = callback;
  } catch (error) {
    return callback(error);
  }
};

Client.prototype.processCommand = function(message) {
  var callback = this._callbacks[message.id];

  if (callback) {
    if (message.error) {
      return callback(message.error);
    } else if (message.result) {
      return callback(null, message.result);
    } else if (message.params) {
      return callback(null, message.params);
    }
  }

  if (message.method === 'Console.messageAdded') {
    return this._console.push(message.params.message);
  }

  if (message.method === 'Debugger.scriptParsed') {
    this._scripts = this._scripts.filter(function(script) {
      return message.params.url !== script.url;
    });

    this._scripts.push(message.params);
    return this.emit('scriptParse', message.params);
  }
};

Client.prototype.attach = function attach(target) {
  if (typeof target === 'object') {
    target = target.webSocketDebuggerUrl;
  }

  var socket = ws.connect(target);
  var self = this;

  socket.on('open', function() {
    self.emit('attach');
  });

  socket.on('close', function() {
    self.emit('detatch');
  });

  socket.on('error', function(error) {
    self.emit('error', error);
  });

  socket.on('message', function(data) {
    try {
      var message = JSON.parse(data);
      self.processCommand(message);
    } catch (error) {
      self.emit('error', error);
    }
  });

  this._socket = socket;
};

Client.prototype.detatch = function() {
  if (this._socket) {
    this._socket.close();
  }
};

Client.prototype.evaluate = function evaluate(expression, callback) {
  this.sendCommand('Runtime.evaluate', {
    expression: expression,
  }, callback);
};

Client.prototype.getScripts = function scripts(callback) {
  callback(this._scripts);
};

Client.prototype.getScriptSource = function(script, callback) {
  this.sendCommand('Debugger.getScriptSource', {
    scriptId: script.scriptId,
  }, callback);
};

Client.prototype.setScriptSource = function source(script, contents, callback) {
  this.sendCommand('Debugger.setScriptSource', {
    scriptId: script.scriptId,
    scriptSource: contents
  }, callback);
};

module.exports.Client = Client;

function createClient() {
  var client = new Client();
  return client;
}

module.exports.createClient = createClient;

function get(port, host, callback) {
  var request = http.get({
    port: port,
    host: host,
    path: '/json'
  });

  request.on('response', function(response) {
    var body = '';

    response.on('data', function(chunk) {
      body += chunk;
    });

    response.on('end', function() {
      try {
        var targets = JSON.parse(body);
        return callback(null, targets);
      } catch (error) {
        return callback(error);
      }
    });
  });

  request.on('error', function(error) {
    return callback(error);
  });
};

module.exports.get = get;
<|endoftext|>


<commit_before>var restify = require('restify');
var bunyan = require('bunyan');
var q = require('q');
var debug = require('debug')('bravado:server');
var path = require('path');
var inflection = require('inflection');
var package = require('../package.json');
var config = require('./config');
var bravado = require('bravado-core');
var cors = require('./cors');
var routeHandler = require('./route');
var indexRouteHandler = require('./index-route');

var server = undefined;

module.exports = {

  start: function (api, options) {
    debug('starting server');
    if (options) {
      config.load(options);
      config.validate({strict: true});
    }

    var serverOptions = {
      name: config.get('name'),
      version: package.version
    };

    server = restify.createServer(serverOptions);
    server.use(restify.queryParser({ mapParams: false }));
    server.use(restify.gzipResponse());
    server.use(restify.bodyParser({
      mapParams: false,
      mapFiles: false
    }));

    // load api definitions
    var loadPromise;
    if ('string' === typeof api) {
      loadPromise = bravado.ApiDefinition.load(api);
    } else if (Array.isArray(api)) {
      loadPromise = q.all(api.map(function (item) {
        return bravado.ApiDefinition.load(item);
      }));
    }

    return loadPromise
      .then(function (defs) {
        var routes = {};
        debug('api definition loaded: %j', api);
        if (!Array.isArray(defs)) {
          defs = [defs];
        }
        defs.forEach(function (def) {
          def.validate();
          var resourcePath = path.resolve(path.dirname(def['x-bravado-sourceFile']), config.get('path'));
          for (var r in def.resources) {
            var resource = def.resources[r];
            var controllerPath = path.resolve(resourcePath, resource['x-bravado-controller']);
            for (var a in resource.actions) {
              var action = resource.actions[a];
              var method = action.method.toLowerCase();
              if (method === 'delete') { method = 'del'; }
              if (method === 'options') { method = 'opts'; }
              var fullPath = action['x-bravado-fullPath'];
              var routePath = fullPath.replace(/\{((?:[\w.~-]|(?:%[0-9A-F]{2}))+)\}/g, ':$1');
              if (!routes[routePath]) {
                routes[routePath] = [];
              }
              routes[routePath].push({
                name: [r, a].join('.'),
                method: method,
                version: def.info.version,
                handler: routeHandler(def, r, a, require(controllerPath), options.context)
              });
            }
          }
          routes[def.basePath] = [{
            name: 'index',
            method: 'get',
            version: def.info.version,
            handler: indexRouteHandler(def)
          }];
        });
        Object.keys(routes).sort().reverse().forEach(function (routePath) {
          routes[routePath].forEach(function (route) {
            debug('routing %s@%s for %s', routePath, route.version, route.name);
            server.opts(routePath, cors.preflight());
            server[route.method](
              { path: routePath, version: route.version },
              cors.headers(),
              route.handler
            );
          });
        });
        return q.resolve();
      })
      .then(function () {
        var logger = restify.auditLogger({
          log: bunyan.createLogger({
            name: 'audit',
            stream: process.stdout
          })
        });
        server.on('after', function (req, res, route, err) {
          logger(req, res, route, err);
        });
        server.on('NotFound', function (req, res, err, cb) {
          res.send(404, { type: 'NotFound', message: err.message });
          cb();
        });
        server.on('MethodNotAllowed', function (req, res, err, cb) {
          res.send(405, { type: 'MethodNotAllowed', message: err.message });
          cb();
        });
        server.on('VersionNotAllowed', function (req, res, err, cb) {
          res.send(400, { type: 'VersionNotAllowed', message: err.message });
          cb();
        });
        server.on('InternalServer', function (req, res, err, cb) {
          res.send(500, { type: 'ServerError', message: err.message });
          cb();
        });
        server.on('uncaughtException', function (req, res, route, err) {
          logger(req, res, route, err);
          res.send(err.statusCode || 500, { type: err.type || 'Error', message: err.message });
        });

        server.listen(
          config.get('port'),
          config.get('host'),
          function () {
            debug('%s listening at %s', server.name, server.url);
          }
        );

        return server;

      }).catch(function (err) {
        debug(err);
        throw err;
      });

  },

  stop: function () {
    debug('stopping server');
    server.close();
  }

};
<commit_msg>updates to support updates to core ApiDefinition<commit_after>var restify = require('restify');
var bunyan = require('bunyan');
var q = require('q');
var debug = require('debug')('bravado:server');
var path = require('path');
var inflection = require('inflection');
var package = require('../package.json');
var config = require('./config');
var bravado = require('bravado-core');
var cors = require('./cors');
var routeHandler = require('./route');
var indexRouteHandler = require('./index-route');

var server = undefined;

module.exports = {

  start: function (apis, options) {
    debug('starting server');
    if (options) {
      config.load(options);
      config.validate({strict: true});
    }

    var serverOptions = {
      name: config.get('name'),
      version: package.version
    };

    server = restify.createServer(serverOptions);
    server.use(restify.queryParser({ mapParams: false }));
    server.use(restify.gzipResponse());
    server.use(restify.bodyParser({
      mapParams: false,
      mapFiles: false
    }));

    // load api definitions
    var loadPromise;
    debug('loading api definition %s', apis);
    if ('string' === typeof apis) {
      loadPromise = bravado.ApiDefinition.build(apis);
    } else if (Array.isArray(apis)) {
      loadPromise = q.all(apis.map(function (item) {
        return bravado.ApiDefinition.build(item);
      }));
    }

    return loadPromise
      .then(function (apis) {
        if (!Array.isArray(apis)) {
          apis = [apis];
        }
        return q.all(apis.map(function (api) {
          return q.all([api, api.resolveRefs()]);
        }));
      })
      .then(function (defs) {
        var routes = {};
        defs.forEach(function (def) {
          var api = def[0];
          var resolved = def[1];
          api.validate();
          var resourcePath = path.resolve(path.dirname(api['x-bravado-sourceFile']), config.get('path'));
          for (var r in api.resources) {
            var resource = api.resources[r];
            var controllerPath = path.resolve(resourcePath, resource['x-bravado-controller']);
            for (var a in resource.actions) {
              var action = resource.actions[a];
              var method = action.method.toLowerCase();
              if (method === 'delete') { method = 'del'; }
              if (method === 'options') { method = 'opts'; }
              var fullPath = action['x-bravado-fullPath'];
              var routePath = fullPath.replace(/\{((?:[\w.~-]|(?:%[0-9A-F]{2}))+)\}/g, ':$1');
              if (!routes[routePath]) {
                routes[routePath] = [];
              }
              routes[routePath].push({
                name: [r, a].join('.'),
                method: method,
                version: api.info.version,
                handler: routeHandler(resolved, r, a, require(controllerPath), options.context)
              });
            }
          }
          routes[api.basePath] = [{
            name: 'index',
            method: 'get',
            version: api.info.version,
            handler: indexRouteHandler(api)
          }];
        });
        Object.keys(routes).sort().reverse().forEach(function (routePath) {
          routes[routePath].forEach(function (route) {
            debug('routing %s@%s for %s', routePath, route.version, route.name);
            server.opts(routePath, cors.preflight());
            server[route.method](
              { path: routePath, version: route.version },
              cors.headers(),
              route.handler
            );
          });
        });
        return q.resolve();
      })
      .then(function () {
        var logger = restify.auditLogger({
          log: bunyan.createLogger({
            name: 'audit',
            stream: process.stdout
          })
        });
        server.on('after', function (req, res, route, err) {
          logger(req, res, route, err);
        });
        server.on('NotFound', function (req, res, err, cb) {
          res.send(404, { type: 'NotFound', message: err.message });
          cb();
        });
        server.on('MethodNotAllowed', function (req, res, err, cb) {
          res.send(405, { type: 'MethodNotAllowed', message: err.message });
          cb();
        });
        server.on('VersionNotAllowed', function (req, res, err, cb) {
          res.send(400, { type: 'VersionNotAllowed', message: err.message });
          cb();
        });
        server.on('InternalServer', function (req, res, err, cb) {
          res.send(500, { type: 'ServerError', message: err.message });
          cb();
        });
        server.on('uncaughtException', function (req, res, route, err) {
          logger(req, res, route, err);
          res.send(err.statusCode || 500, { type: err.type || 'Error', message: err.message });
        });

        server.listen(
          config.get('port'),
          config.get('host'),
          function () {
            debug('%s listening at %s', server.name, server.url);
          }
        );

        return server;

      }).catch(function (err) {
        debug(err);
        throw err;
      });

  },

  stop: function () {
    debug('stopping server');
    server.close();
  }

};
<|endoftext|>


<commit_before>/**
 * TODO: Remove `mkdirp`. Use `fs-extra` instead.
 */

var path        = require("path")
var fs          = require("fs-extra")
var pkg         = require('../package.json')
var polymer     = require('terraform')
var helpers     = require("./helpers")
var async       = require("async")
var connect     = require("connect")
var middleware  = require("./middleware")
var mime        = require('mime')

/**
 * Server
 *
 * Host a single Harp Application.
 *
 */

exports.server = function(dirPath, options, callback){
  connect.createServer(
    middleware.regProjectFinder(dirPath),
    middleware.setup,
    middleware.basicAuth,
    middleware.underscore,
    middleware.mwl,
    middleware.static,
    middleware.poly,
    middleware.process,
    middleware.fallback
  ).listen(options.port || 9966, callback)
}

/**
 * Multihost
 *
 * Host a single Harp Application.
 *
 */

exports.multihost = function(dirPath, options, callback){
  connect.createServer(
    middleware.notMultihostURL,
    middleware.index(dirPath),
    middleware.hostProjectFinder(dirPath),
    middleware.setup,
    middleware.basicAuth,
    middleware.underscore,
    middleware.mwl,
    middleware.static,
    middleware.poly,
    middleware.process,
    middleware.fallback
  ).listen(options.port || 9966, callback)
}

/**
 * Mount
 *
 * Offer the asset pipeline as connect middleware
 *
 */

exports.mount = function(mountPoint, root){

  if(!root){
    root = mountPoint
    mountPoint = null
  }else{
    var rx = new RegExp("^" + mountPoint)
  }

  var finder = middleware.regProjectFinder(root)

  return function(req, rsp, next){

    if(rx){
      if(!req.url.match(rx)) return next()
      var originalUrl = req.url
      req.url         = req.url.replace(rx, "/")
    }

    finder(req, rsp, function(){
      middleware.setup(req, rsp, function(){
        middleware.static(req, rsp, function(){
          middleware.poly(req, rsp, function(){
            middleware.process(req, rsp, function(){
              if(originalUrl) req.url = originalUrl
              next()
            })
          })
        })
      })
    })
  }
}

/**
 * Pipeline
 *
 * Offer the asset pipeline as connect middleware
 *
 */

exports.pipeline = function(root){
  var publicPath = path.resolve(root)
  var poly = polymer.root(publicPath)

  return function(req, rsp, next){
    var normalizedPath  = helpers.normalizeUrl(req.url)
    var priorityList    = polymer.helpers.buildPriorityList(normalizedPath)
    var sourceFile      = polymer.helpers.findFirstFile(publicPath, priorityList)

    if(!sourceFile) return next()

    poly.render(sourceFile, function(error, body){
      if(error) return next(error)
      if(!body) return next() // 404

      var outputType = polymer.helpers.outputType(sourceFile)
      var mimeType   = helpers.mimeType(outputType)
      var charset    = mime.charsets.lookup(mimeType)
      rsp.statusCode = 200
      rsp.setHeader('Content-Type', mimeType + (charset ? '; charset=' + charset : ''))
      rsp.setHeader('Content-Length', body.length)
      rsp.end(body)
    })

  }

}

exports.pkg = pkg

/**
 * Compile
 *
 * Compiles Single Harp Application.
 *
 */

exports.compile = function(projectPath, outputPath, callback){

  /**
   * Both projectPath and outputPath are optional
   */

  if(!callback){
    callback   = outputPath
    outputPath = "www"
  }

  if(!outputPath){
    outputPath = "www"
  }

  /**
   * Setup all the paths and collect all the data
   */

  try{
    outputPath = path.resolve(projectPath, outputPath)
    var setup  = helpers.setup(projectPath, "production")
    var poly   = polymer.root(setup.publicPath, setup.config.globals)
  }catch(err){
    return callback(err)
  }

  /**
   * Protect the user (as much as possible) from compiling up the tree
   * resulting in the project deleting its own source code.
   */

  if(!helpers.willAllow(projectPath, outputPath)){
    return callback({
      type: "Invalid Output Path",
      message: "Output path cannot be greater then one level up from project path and must be in directory starting with `_` (underscore).",
      projectPath: projectPath,
      outputPath: outputPath
    })
  }

  /**
   * Compile and save file
   */

  var compileFile = function(file, done){
    poly.render(file, function(error, body){
      if(error){
        done(error)
      }else{
        if(body){
          var dest = path.resolve(outputPath, polymer.helpers.outputPath(file))
          fs.mkdirp(path.dirname(dest), function(err){
            fs.writeFile(dest, body, done)
          })
        }else{
          done()
        }
      }
    })

  }

  /**
   * Copy File
   *
   * TODO: reference ignore extensions from a terraform helper.
   */
  var copyFile = function(file, done){
    var ext = path.extname(file)
    if(!polymer.helpers.shouldIgnore(file) && [".jade", ".ejs", ".md", ".styl", ".less", ".scss", ".coffee"].indexOf(ext) === -1){
      var localPath = path.resolve(outputPath, file)
      fs.mkdirp(path.dirname(localPath), function(err){
        fs.copy(path.resolve(setup.publicPath, file), localPath, done)
      })
    }else{
      done()
    }
  }

  /**
   * Scan dir, Compile Less and Jade, Copy the others
   */

  helpers.prime(outputPath, { ignore: projectPath }, function(err){
    if(err) console.log(err)

    helpers.ls(setup.publicPath, function(err, results){
      async.eachLimit(results, 72, compileFile, function(err){
        if(err){
          callback(err)
        }else{
          async.eachLimit(results, 72, copyFile, function(err){
            setup.config['harp_version'] = pkg.version
            delete setup.config.globals
            callback(null, setup.config)
          })
        }
      })
    })
  })

}

<commit_msg>Cleanup and renamed poly to terraform<commit_after>/**
 * TODO: Remove `mkdirp`. Use `fs-extra` instead.
 */

var path        = require('path')
var fs          = require('fs-extra')
var pkg         = require('../package.json')
var terraform   = require('terraform')
var helpers     = require('./helpers')
var async       = require('async')
var connect     = require('connect')
var middleware  = require('./middleware')
var mime        = require('mime')

/**
 * Server
 *
 * Host a single Harp Application.
 *
 */

exports.server = function(dirPath, options, callback){
  connect.createServer(
    middleware.regProjectFinder(dirPath),
    middleware.setup,
    middleware.basicAuth,
    middleware.underscore,
    middleware.mwl,
    middleware.static,
    middleware.poly,
    middleware.process,
    middleware.fallback
  ).listen(options.port || 9966, callback)
}

/**
 * Multihost
 *
 * Host a single Harp Application.
 *
 */

exports.multihost = function(dirPath, options, callback){
  connect.createServer(
    middleware.notMultihostURL,
    middleware.index(dirPath),
    middleware.hostProjectFinder(dirPath),
    middleware.setup,
    middleware.basicAuth,
    middleware.underscore,
    middleware.mwl,
    middleware.static,
    middleware.poly,
    middleware.process,
    middleware.fallback
  ).listen(options.port || 9966, callback)
}

/**
 * Mount
 *
 * Offer the asset pipeline as connect middleware
 *
 */

exports.mount = function(mountPoint, root){

  if(!root){
    root = mountPoint
    mountPoint = null
  }else{
    var rx = new RegExp("^" + mountPoint)
  }

  var finder = middleware.regProjectFinder(root)

  return function(req, rsp, next){

    if(rx){
      if(!req.url.match(rx)) return next()
      var originalUrl = req.url
      req.url         = req.url.replace(rx, "/")
    }

    finder(req, rsp, function(){
      middleware.setup(req, rsp, function(){
        middleware.static(req, rsp, function(){
          middleware.poly(req, rsp, function(){
            middleware.process(req, rsp, function(){
              if(originalUrl) req.url = originalUrl
              next()
            })
          })
        })
      })
    })
  }
}

/**
 * Pipeline
 *
 * Offer the asset pipeline as connect middleware
 *
 */

exports.pipeline = function(root){
  console.log("Depricated, please use MOUNT instead, this will be removed in a future version.");
  var publicPath = path.resolve(root)
  var terra = terraform.root(publicPath)

  return function(req, rsp, next){
    var normalizedPath  = helpers.normalizeUrl(req.url)
    var priorityList    = terraform.helpers.buildPriorityList(normalizedPath)
    var sourceFile      = terraform.helpers.findFirstFile(publicPath, priorityList)

    if(!sourceFile) return next()

    terra.render(sourceFile, function(error, body){
      if(error) return next(error)
      if(!body) return next() // 404

      var outputType = terraform.helpers.outputType(sourceFile)
      var mimeType   = helpers.mimeType(outputType)
      var charset    = mime.charsets.lookup(mimeType)
      rsp.statusCode = 200
      rsp.setHeader('Content-Type', mimeType + (charset ? '; charset=' + charset : ''))
      rsp.setHeader('Content-Length', body.length)
      rsp.end(body)
    })

  }

}

exports.pkg = pkg

/**
 * Compile
 *
 * Compiles Single Harp Application.
 *
 */

exports.compile = function(projectPath, outputPath, callback){

  /**
   * Both projectPath and outputPath are optional
   */

  if(!callback){
    callback   = outputPath
    outputPath = "www"
  }

  if(!outputPath){
    outputPath = "www"
  }

  /**
   * Setup all the paths and collect all the data
   */

  try{
    outputPath = path.resolve(projectPath, outputPath)
    var setup  = helpers.setup(projectPath, "production")
    var terra   = terraform.root(setup.publicPath, setup.config.globals)
  }catch(err){
    return callback(err)
  }

  /**
   * Protect the user (as much as possible) from compiling up the tree
   * resulting in the project deleting its own source code.
   */

  if(!helpers.willAllow(projectPath, outputPath)){
    return callback({
      type: "Invalid Output Path",
      message: "Output path cannot be greater then one level up from project path and must be in directory starting with `_` (underscore).",
      projectPath: projectPath,
      outputPath: outputPath
    })
  }

  /**
   * Compile and save file
   */

  var compileFile = function(file, done){
    terra.render(file, function(error, body){
      if(error){
        done(error)
      }else{
        if(body){
          var dest = path.resolve(outputPath, terraform.helpers.outputPath(file))
          fs.mkdirp(path.dirname(dest), function(err){
            fs.writeFile(dest, body, done)
          })
        }else{
          done()
        }
      }
    })

  }

  /**
   * Copy File
   *
   * TODO: reference ignore extensions from a terraform helper.
   */
  var copyFile = function(file, done){
    var ext = path.extname(file)
    if(!terraform.helpers.shouldIgnore(file) && [".jade", ".ejs", ".md", ".styl", ".less", ".scss", ".coffee"].indexOf(ext) === -1){
      var localPath = path.resolve(outputPath, file)
      fs.mkdirp(path.dirname(localPath), function(err){
        fs.copy(path.resolve(setup.publicPath, file), localPath, done)
      })
    }else{
      done()
    }
  }

  /**
   * Scan dir, Compile Less and Jade, Copy the others
   */

  helpers.prime(outputPath, { ignore: projectPath }, function(err){
    if(err) console.log(err)

    helpers.ls(setup.publicPath, function(err, results){
      async.eachLimit(results, 72, compileFile, function(err){
        if(err){
          callback(err)
        }else{
          async.eachLimit(results, 72, copyFile, function(err){
            setup.config['harp_version'] = pkg.version
            delete setup.config.globals
            callback(null, setup.config)
          })
        }
      })
    })
  })

}

<|endoftext|>


<commit_before>import { createCollectionDelegate } from './AngularCollectionDelegate';
import { createCursor } from './AngularCursorObservable';
const angular = typeof window !== 'undefined' && window.angular
  ? window.angular : require('angular');
const Collection = typeof window !== 'undefined' && window.Mars
  ? window.Mars.Collection : require('marsdb').Collection;

// Setup mars $collection provider
angular.module('MarsDB', [])
.provider('$collection', function() {
  Collection.defaultDelegate( createCollectionDelegate() );
  Collection.defaultCursor( createCursor() );

  this.defaultDelegate = function(delegate) {
    Collection.defaultDelegate(delegate);
    return this;
  };

  this.defaultStorageManager = function(storageManager) {
    Collection.defaultStorageManager(storageManager);
    return this;
  };

  this.defaultIdGenerator = function(idGenerator) {
    Collection.defaultIdGenerator(idGenerator);
    return this;
  };

  const collections = {};
  this.$get = ['$q', function($q) {
    return function(name, options = {}) {
      // For using within delegate
      options._$q = $q;

      // Use cache or create new Colleciton
      if (collections[name] && !options.noCache) {
        return collections[name];
      } else {
        const newInstance = new Collection(name, options);
        if (!options.noCache) {
          collections[name] = newInstance;
        }
        return newInstance;
      }
    };
  }];

});

module.export = 'MarsDB';
<commit_msg>fixed lint<commit_after>import { createCollectionDelegate } from './AngularCollectionDelegate';
import { createCursor } from './AngularCursorObservable';
const angular = typeof window !== 'undefined' && window.angular
  ? window.angular : require('angular');
const Collection = typeof window !== 'undefined' && window.Mars
  ? window.Mars.Collection : require('marsdb').Collection;

// Setup mars $collection provider
angular.module('MarsDB', [])
.provider('$collection', function() {
  Collection.defaultDelegate(createCollectionDelegate());
  Collection.defaultCursor(createCursor());

  this.defaultDelegate = function(delegate) {
    Collection.defaultDelegate(delegate);
    return this;
  };

  this.defaultStorageManager = function(storageManager) {
    Collection.defaultStorageManager(storageManager);
    return this;
  };

  this.defaultIdGenerator = function(idGenerator) {
    Collection.defaultIdGenerator(idGenerator);
    return this;
  };

  const collections = {};
  this.$get = ['$q', function($q) {
    return function(name, options = {}) {
      // For using within delegate
      options._$q = $q;

      // Use cache or create new Colleciton
      if (collections[name] && !options.noCache) {
        return collections[name];
      } else {
        const newInstance = new Collection(name, options);
        if (!options.noCache) {
          collections[name] = newInstance;
        }
        return newInstance;
      }
    };
  }];

});

module.export = 'MarsDB';
<|endoftext|>


<commit_before>'use strict';

/*!
 * Module dependencies.
 */
var async	= require('async');
var path = require('path');
var juice 	= require('juice');
var cons 	= require('consolidate');
var htmlMinify = require('html-minifier').minify;

var diskLoader = require('./loader/disk');
//var mongoLoader = require('./loader/mongodb');

function Render () {
  this.options = {
    renderEngine: 'ejs',
  };
}

var allowedType = ['file'/*, 'db'*/];

Render.prototype._loadTemplate = function (options, callback) {
  if (!options.template) {
    return callback(new Error({message: 'Missing template arguments'}));
  }
  if (!options.template.type) {
		options.template.type = 'file';
  }

	if (allowedType.indexOf(options.template.type) === -1) {
		return callback(new Error({message: 'Wrong template type'}));
  }

	if (options.layout) {
    if (!options.layout.type) {
      options.layout.type = 'file';
    } else if (allowedType.indexOf(options.layout.type) === -1) {
      return callback(new Error({message: 'Wrong layout type'}));
    }
  }

	var templateHtml;
	var templateStylesheet;
	var templateText;

  var afterLayoutCb = function (err, layoutHtml, layoutStylesheet) {
		if (err) {
      return callback(err);
    }

		if (layoutHtml) {
			templateHtml = layoutHtml.replace(/<%-body %>/i, templateHtml);
			if (layoutStylesheet) {
				templateStylesheet = layoutStylesheet + '\n' + templateStylesheet;
      }

			templateHtml = htmlMinify(
        templateHtml,
        {
          removeComments: true,
          collapseWhitespace: true,
          removeAttributeQuotes: true,
        });
			callback(null, templateHtml, templateStylesheet);
		}
	};

	var afterTemplateCb = function (err, html, stylesheet, text) {
    if (err) {
      return callback(err);
    }
		templateHtml = html;
		templateStylesheet = stylesheet;
		templateText = text;

		if (options.layout) {
			if (options.layout.type === 'file') {
				diskLoader.load(path.join(options.layout.dir, options.layout.name), afterLayoutCb);
			} else if (options.layout.type === 'db') {
				mongoLoader.load(options.layout.id, afterLayoutCb);
      }
		} else {
			templateHtml = htmlMinify(
        templateHtml,
        {
          removeComments: true,
          collapseWhitespace: true,
          removeAttributeQuotes: true,
        });
			callback(null, templateHtml, templateStylesheet);
		}
  };

  if (options.template.type === 'file') {
    diskLoader.load(path.join(options.template.dir, options.template.name), afterTemplateCb);
  } else if (options.template.type === 'db') {
    mongoLoader.load(options.template.id, afterTemplateCb);
  }
};

Render.prototype.renderTemplate = function (data, options, callback) {
  var self = this;
	this._loadTemplate(options, function (err, html, stylesheet) {
		if (err) {
      return callback(err);
    }
		data.content = data.content || '';
    var renderEngine = cons[options.renderEngine || self.options.renderEngine];
		renderEngine.render(data.content, data, function (err, content) {
			if (err) {
        return callback(err);
      }
			data.content = content;
			renderEngine.render(html, data, function (err, html) {
        if (err) {
          return callback(err);
        }

				if (stylesheet && stylesheet.length) {
					html = juice.inlineContent(html, stylesheet);
        }

				callback(null, html);
			});
		});
	});
};

Render.prototype.renderTemplateBulk = function (dataArray, options, callbackEach, callbackFinal) {
	if (!callbackFinal) {
    callbackFinal = callbackEach;
		callbackEach = undefined;
	}

  var self = this;
	this._loadTemplate(options, function (err, html, stylesheet) {
		if (err) {
      return callbackFinal(err);
    }

		async.map(
			dataArray,
			function (data, cb) {
        var dataObj = data.data ? data.data : data;

				dataObj.content = dataObj.content || '';
        var renderEngine = cons[options.renderEngine || self.options.renderEngine];
				renderEngine.render(dataObj.content, dataObj, function (err, content) {
					if (err) {
						if (callbackEach) {
							callbackEach(err, data, null, null, cb);
						} else {
							cb(err);
            }
					}

					dataObj.content = content;
					renderEngine.render(html, dataObj, function (err, html, text) {
            if (stylesheet && stylesheet.length) {
							html = juice.inlineContent(html, stylesheet);
            }

						if (callbackEach) {
							callbackEach(err, data, html, text, cb);
						} else {
							cb(err, html);
            }
					});
				});
			}, callbackFinal);
	});
};

module.exports = new Render();
<commit_msg>add moment<commit_after>'use strict';

/*!
 * Module dependencies.
 */
var async	= require('async');
var path = require('path');
var juice 	= require('juice');
var cons 	= require('consolidate');
var htmlMinify = require('html-minifier').minify;

var diskLoader = require('./loader/disk');
//var mongoLoader = require('./loader/mongodb');

function Render () {
  this.options = {
    renderEngine: 'ejs',
  };
}

var allowedType = ['file'/*, 'db'*/];

Render.prototype._loadTemplate = function (options, callback) {
  if (!options.template) {
    return callback(new Error({message: 'Missing template arguments'}));
  }
  if (!options.template.type) {
		options.template.type = 'file';
  }

	if (allowedType.indexOf(options.template.type) === -1) {
		return callback(new Error({message: 'Wrong template type'}));
  }

	if (options.layout) {
    if (!options.layout.type) {
      options.layout.type = 'file';
    } else if (allowedType.indexOf(options.layout.type) === -1) {
      return callback(new Error({message: 'Wrong layout type'}));
    }
  }

	var templateHtml;
	var templateStylesheet;
	var templateText;

  var afterLayoutCb = function (err, layoutHtml, layoutStylesheet) {
		if (err) {
      return callback(err);
    }

		if (layoutHtml) {
			templateHtml = layoutHtml.replace(/<%-body %>/i, templateHtml);
			if (layoutStylesheet) {
				templateStylesheet = layoutStylesheet + '\n' + templateStylesheet;
      }

			templateHtml = htmlMinify(
        templateHtml,
        {
          removeComments: true,
          collapseWhitespace: true,
          removeAttributeQuotes: true,
        });
			callback(null, templateHtml, templateStylesheet);
		}
	};

	var afterTemplateCb = function (err, html, stylesheet, text) {
    if (err) {
      return callback(err);
    }
		templateHtml = html;
		templateStylesheet = stylesheet;
		templateText = text;

		if (options.layout) {
			if (options.layout.type === 'file') {
				diskLoader.load(path.join(options.layout.dir, options.layout.name), afterLayoutCb);
			} else if (options.layout.type === 'db') {
				mongoLoader.load(options.layout.id, afterLayoutCb);
      }
		} else {
			templateHtml = htmlMinify(
        templateHtml,
        {
          removeComments: true,
          collapseWhitespace: true,
          removeAttributeQuotes: true,
        });
			callback(null, templateHtml, templateStylesheet);
		}
  };

  if (options.template.type === 'file') {
    diskLoader.load(path.join(options.template.dir, options.template.name), afterTemplateCb);
  } else if (options.template.type === 'db') {
    mongoLoader.load(options.template.id, afterTemplateCb);
  }
};

Render.prototype.renderTemplate = function (data, options, callback) {
  var moment = require('moment-timezone');
  moment.locale(options.defaultLanguage || 'it');
  moment.tz.setDefault(options.timezone || 'Europe/Rome');
  var self = this;
	this._loadTemplate(options, function (err, html, stylesheet) {
		if (err) {
      return callback(err);
    }
		data.content = data.content || '';
    var renderEngine = cons[options.renderEngine || self.options.renderEngine];
		renderEngine.render(data.content, data, function (err, content) {
			if (err) {
        return callback(err);
      }
			data.content = content;
      data.moment = moment;
			renderEngine.render(html, data, function (err, html) {
        if (err) {
          return callback(err);
        }

				if (stylesheet && stylesheet.length) {
					html = juice.inlineContent(html, stylesheet);
        }

				callback(null, html);
			});
		});
	});
};

Render.prototype.renderTemplateBulk = function (dataArray, options, callbackEach, callbackFinal) {
  var moment = require('moment-timezone');
  moment.locale(options.defaultLanguage || 'it');
  moment.tz.setDefault(options.timezone || 'Europe/Rome');

	if (!callbackFinal) {
    callbackFinal = callbackEach;
		callbackEach = undefined;
	}

  var self = this;
	this._loadTemplate(options, function (err, html, stylesheet) {
		if (err) {
      return callbackFinal(err);
    }

		async.map(
			dataArray,
			function (data, cb) {
        var dataObj = data.data ? data.data : data;

				dataObj.content = dataObj.content || '';
        var renderEngine = cons[options.renderEngine || self.options.renderEngine];
				renderEngine.render(dataObj.content, dataObj, function (err, content) {
					if (err) {
						if (callbackEach) {
							callbackEach(err, data, null, null, cb);
						} else {
							cb(err);
            }
					}

					dataObj.content = content;
          data.moment = moment;
					renderEngine.render(html, dataObj, function (err, html, text) {
            if (stylesheet && stylesheet.length) {
							html = juice.inlineContent(html, stylesheet);
            }

						if (callbackEach) {
							callbackEach(err, data, html, text, cb);
						} else {
							cb(err, html);
            }
					});
				});
			}, callbackFinal);
	});
};

module.exports = new Render();
<|endoftext|>


<commit_before>/*!
 * index.js - Main Entry Point
 *
 * Copyright (c) 2015 Cisco Systems, Inc. See LICENSE file.
 */
"use strict";

if (typeof Promise === "undefined") {
  require("es6-promise").polyfill();
}

module.exports = {
  JWA: require("./algorithms"),
  JWE: require("./jwe"),
  JWK: require("./jwk"),
  JWS: require("./jws"),
  util: require("./util"),
  parse: require("./parse")
};
<commit_msg>Update: alias JWS.createVerify to construct a sentence (#127)<commit_after>/*!
 * index.js - Main Entry Point
 *
 * Copyright (c) 2015 Cisco Systems, Inc. See LICENSE file.
 */
"use strict";

if (typeof Promise === "undefined") {
  require("es6-promise").polyfill();
}

var JWS = require("./jws");

module.exports = {
  JWA: require("./algorithms"),
  JWE: require("./jwe"),
  JWK: require("./jwk"),
  JWS: JWS,
  util: require("./util"),
  parse: require("./parse"),
  canYouSee: JWS.createVerify
};
<|endoftext|>


<commit_before>'use strict';

// MODULES //

var copy = require( 'utils-copy' );
var deepGet = require( 'utils-deep-get' ).factory;
var isArray = require( 'validate.io-array' );
var defaults = require( './defaults.json' );
var validate = require( './validate.js' );

// PLUCK //

/**
* FUNCTION: pluck( arr, path[, options] )
*	Extracts a nested property value from each element of an object array.
*
* @param {Object[]} arr - source array
* @param {String|String[]} path - key path
* @param {Object} [options] - function options
* @param {Boolean} [options.copy=true] - boolean indicating whether to return a new data structure
* @param {String} [options.sep="."] - key path separator
* @returns {Array} destination array
*/
function pluck( arr, path, options ) {
	var dget;
	var opts;
	var out;
	var err;
	var i;

	if ( !isArray( arr ) ) {
		throw new TypeError( 'invalid input argument. First argument must be an array. Value: `' + arr + '`.' );
	}
	opts = copy( defaults );
	if ( arguments.length > 2 ) {
		err = validate( opts, options );
		if ( err ) {
			throw err;
		}
	}
	if ( opts.copy ) {
		out = new Array( arr.length );
	} else {
		out = arr;
	}
	dget = deepGet( path, {'sep': opts.sep} );
	for ( i = 0; i < arr.length; i++ ) {
		out[ i ] = dget( arr[ i ] );
	}
	return out;
} // end FUNCTION pluck()

// EXPORTS //

module.exports = pluck;
<commit_msg>Update JSDoc type annotation<commit_after>'use strict';

// MODULES //

var copy = require( 'utils-copy' );
var deepGet = require( 'utils-deep-get' ).factory;
var isArray = require( 'validate.io-array' );
var defaults = require( './defaults.json' );
var validate = require( './validate.js' );

// PLUCK //

/**
* FUNCTION: pluck( arr, path[, options] )
*	Extracts a nested property value from each element of an object array.
*
* @param {Object[]} arr - source array
* @param {String|Array} path - key path
* @param {Object} [options] - function options
* @param {Boolean} [options.copy=true] - boolean indicating whether to return a new data structure
* @param {String} [options.sep="."] - key path separator
* @returns {Array} destination array
*/
function pluck( arr, path, options ) {
	var dget;
	var opts;
	var out;
	var err;
	var i;

	if ( !isArray( arr ) ) {
		throw new TypeError( 'invalid input argument. First argument must be an array. Value: `' + arr + '`.' );
	}
	opts = copy( defaults );
	if ( arguments.length > 2 ) {
		err = validate( opts, options );
		if ( err ) {
			throw err;
		}
	}
	if ( opts.copy ) {
		out = new Array( arr.length );
	} else {
		out = arr;
	}
	dget = deepGet( path, {'sep': opts.sep} );
	for ( i = 0; i < arr.length; i++ ) {
		out[ i ] = dget( arr[ i ] );
	}
	return out;
} // end FUNCTION pluck()

// EXPORTS //

module.exports = pluck;
<|endoftext|>


<commit_before>var SteamCommunity = require('steamcommunity');
var SteamID = require('steamid');

module.exports = TradeOfferManager;

TradeOfferManager.SteamID = SteamID;
TradeOfferManager.ETradeOfferState = require('../resources/ETradeOfferState.js');
TradeOfferManager.EOfferFilter = require('../resources/EOfferFilter.js');
TradeOfferManager.EResult = require('../resources/EResult.js');
TradeOfferManager.EConfirmationMethod = require('../resources/EConfirmationMethod.js');

TradeOfferManager.getStateName = function(state) {
	for(var i in TradeOfferManager.ETradeOfferState) {
		if(TradeOfferManager.ETradeOfferState[i] == state) {
			return i;
		}
	}

	return state;
};

require('util').inherits(TradeOfferManager, require('events').EventEmitter);

function TradeOfferManager(options) {
	options = options || {};

	this._steam = options.steam;
	this._domain = options.domain || 'localhost';
	this._language = options.language;

	this._community = new SteamCommunity();
	this._request = this._community.request;
	this._assetCache = {};
	this._pollTimer = null;
	this._lastPoll = 0;

	this.pollInterval = options.pollInterval || 30000;
	this.cancelTime = options.cancelTime;
	this.pendingCancelTime = options.pendingCancelTime;
	this.cancelOfferCount = options.cancelOfferCount;
	this.cancelOfferCountMinAge = options.cancelOfferCountMinAge || 0;

	this.pollData = {};
	this.apiKey = null;
	this.steamID = null;

	if(this._language) {
		var lang = require('languages').getLanguageInfo(this._language);
		if(!lang.name) {
			this._language = null;
			this._languageName = null;
		} else {
			this._languageName = lang.name.toLowerCase();
		}
	}

	if(this._steam) {
		this._steam.on('tradeOffers', function(count) {
			this.doPoll();
		}.bind(this));

		// This is an instance of https://www.npmjs.com/package/steam-user, and newItems is emitted when new items are announced
		this._steam.on('newItems', function(count) {
			this.doPoll();
		}.bind(this));
	}
}

TradeOfferManager.prototype.setCookies = function(cookies, callback) {
	this._community.setCookies(cookies);
	this.steamID = this._community.steamID;
	this._checkApiKey(function(err) {
		if(!err) {
			if(this._languageName) {
				this._community.setCookies(['Steam_Language=' + this._languageName]);
			}

			if(!this._pollTimer && this.pollInterval >= 1000) {
				this.doPoll();
			}
		}

		if(callback) {
			callback(err);
		}
	}.bind(this));
};

TradeOfferManager.prototype.shutdown = function() {
	clearTimeout(this._pollTimer);
	this._community = new SteamCommunity();
	this._request = this._community.request;
	this._steam = null;
};

TradeOfferManager.prototype.parentalUnlock = function(pin, callback) {
	this._community.parentalUnlock(pin, function(err) {
		if(err && callback) {
			callback(err);
		}
	});
};

TradeOfferManager.prototype._checkApiKey = function(callback) {
	if(this.apiKey) {
		if(callback) {
			callback();
		}

		return;
	}

	this._community.getWebApiKey(this._domain, function(err, key) {
		if(err) {
			callback(err);
			return;
		}

		this.apiKey = key;
		callback();
	}.bind(this));
};

TradeOfferManager.prototype.loadInventory = function(appid, contextid, tradableOnly, callback) {
	this._community.getUserInventory(this._community.steamID, appid, contextid, tradableOnly, callback);
};

TradeOfferManager.prototype.getOfferToken = function(callback) {
	this._request("https://steamcommunity.com/my/tradeoffers/privacy", function(err, response, body) {
		if(err || response.statusCode != 200) {
			callback(err || new Error("HTTP error " + response.statusCode));
			return;
		}

		var match = body.match(/https?:\/\/(www.)?steamcommunity.com\/tradeoffer\/new\/?\?partner=\d+(&|&)token=([a-zA-Z0-9-_]+)/);
		if(match) {
			callback(null, match[3]);
		} else {
			callback(new Error("Malformed response"));
		}
	});
};

TradeOfferManager.prototype.getEscrowDuration = function(steamID, token, callback) {
	if(typeof token === 'function') {
		callback = token;
		token = undefined;
	}

	if(typeof steamID !== 'object') {
		steamID = new SteamID(steamID);
	}

	this._request.get({
		"uri": "https://steamcommunity.com/tradeoffer/new/",
		"qs": {
			"partner": steamID.accountid,
			"token": token || undefined
		}
	}, this._escrowDurationResponse.bind(callback));
};

TradeOfferManager.prototype._escrowDurationResponse = function(err, response, body) {
	var callback = this; // horrible hack but I don't care

	if(err || response.statusCode != 200) {
		callback(err || new Error("HTTP error " + response.statusCode));
		return;
	}

	var mine = body.match(/var g_daysMyEscrow = (\d+);/);
	var theirs = body.match(/var g_daysTheirEscrow = (\d+);/);
	if(mine && theirs) {
		callback(null, parseInt(theirs[1], 10), parseInt(mine[1], 10));
		return;
	}

	// No escrow stuff found, look for an error message
	var error = body.match(/
([^<]+)<\/div>/);
	if(error) {
		callback(new Error(error[1].trim()));
		return;
	}

	callback(new Error("Malformed response"));
};

function makeAnError(error, callback) {
	if(callback) {
		callback(error);
	}
}

require('./webapi.js');
require('./assets.js');
require('./polling.js');
require('./classes/TradeOffer.js');
<commit_msg>Added method to load inventory of any steam user<commit_after>var SteamCommunity = require('steamcommunity');
var SteamID = require('steamid');

module.exports = TradeOfferManager;

TradeOfferManager.SteamID = SteamID;
TradeOfferManager.ETradeOfferState = require('../resources/ETradeOfferState.js');
TradeOfferManager.EOfferFilter = require('../resources/EOfferFilter.js');
TradeOfferManager.EResult = require('../resources/EResult.js');
TradeOfferManager.EConfirmationMethod = require('../resources/EConfirmationMethod.js');

TradeOfferManager.getStateName = function(state) {
	for(var i in TradeOfferManager.ETradeOfferState) {
		if(TradeOfferManager.ETradeOfferState[i] == state) {
			return i;
		}
	}

	return state;
};

require('util').inherits(TradeOfferManager, require('events').EventEmitter);

function TradeOfferManager(options) {
	options = options || {};

	this._steam = options.steam;
	this._domain = options.domain || 'localhost';
	this._language = options.language;

	this._community = new SteamCommunity();
	this._request = this._community.request;
	this._assetCache = {};
	this._pollTimer = null;
	this._lastPoll = 0;

	this.pollInterval = options.pollInterval || 30000;
	this.cancelTime = options.cancelTime;
	this.pendingCancelTime = options.pendingCancelTime;
	this.cancelOfferCount = options.cancelOfferCount;
	this.cancelOfferCountMinAge = options.cancelOfferCountMinAge || 0;

	this.pollData = {};
	this.apiKey = null;
	this.steamID = null;

	if(this._language) {
		var lang = require('languages').getLanguageInfo(this._language);
		if(!lang.name) {
			this._language = null;
			this._languageName = null;
		} else {
			this._languageName = lang.name.toLowerCase();
		}
	}

	if(this._steam) {
		this._steam.on('tradeOffers', function(count) {
			this.doPoll();
		}.bind(this));

		// This is an instance of https://www.npmjs.com/package/steam-user, and newItems is emitted when new items are announced
		this._steam.on('newItems', function(count) {
			this.doPoll();
		}.bind(this));
	}
}

TradeOfferManager.prototype.setCookies = function(cookies, callback) {
	this._community.setCookies(cookies);
	this.steamID = this._community.steamID;
	this._checkApiKey(function(err) {
		if(!err) {
			if(this._languageName) {
				this._community.setCookies(['Steam_Language=' + this._languageName]);
			}

			if(!this._pollTimer && this.pollInterval >= 1000) {
				this.doPoll();
			}
		}

		if(callback) {
			callback(err);
		}
	}.bind(this));
};

TradeOfferManager.prototype.shutdown = function() {
	clearTimeout(this._pollTimer);
	this._community = new SteamCommunity();
	this._request = this._community.request;
	this._steam = null;
};

TradeOfferManager.prototype.parentalUnlock = function(pin, callback) {
	this._community.parentalUnlock(pin, function(err) {
		if(err && callback) {
			callback(err);
		}
	});
};

TradeOfferManager.prototype._checkApiKey = function(callback) {
	if(this.apiKey) {
		if(callback) {
			callback();
		}

		return;
	}

	this._community.getWebApiKey(this._domain, function(err, key) {
		if(err) {
			callback(err);
			return;
		}

		this.apiKey = key;
		callback();
	}.bind(this));
};

TradeOfferManager.prototype.loadInventory = function(appid, contextid, tradableOnly, callback) {
	this.loadUserInventory(this._community.steamID, appid, contextid, tradableOnly, callback);
};

TradeOfferManager.prototype.loadUserInventory = function(uid, appid, contextid, tradableOnly, callback) {
	this._community.getUserInventory(uid, appid, contextid, tradableOnly, callback);
};

TradeOfferManager.prototype.getOfferToken = function(callback) {
	this._request("https://steamcommunity.com/my/tradeoffers/privacy", function(err, response, body) {
		if(err || response.statusCode != 200) {
			callback(err || new Error("HTTP error " + response.statusCode));
			return;
		}

		var match = body.match(/https?:\/\/(www.)?steamcommunity.com\/tradeoffer\/new\/?\?partner=\d+(&|&)token=([a-zA-Z0-9-_]+)/);
		if(match) {
			callback(null, match[3]);
		} else {
			callback(new Error("Malformed response"));
		}
	});
};

TradeOfferManager.prototype.getEscrowDuration = function(steamID, token, callback) {
	if(typeof token === 'function') {
		callback = token;
		token = undefined;
	}

	if(typeof steamID !== 'object') {
		steamID = new SteamID(steamID);
	}

	this._request.get({
		"uri": "https://steamcommunity.com/tradeoffer/new/",
		"qs": {
			"partner": steamID.accountid,
			"token": token || undefined
		}
	}, this._escrowDurationResponse.bind(callback));
};

TradeOfferManager.prototype._escrowDurationResponse = function(err, response, body) {
	var callback = this; // horrible hack but I don't care

	if(err || response.statusCode != 200) {
		callback(err || new Error("HTTP error " + response.statusCode));
		return;
	}

	var mine = body.match(/var g_daysMyEscrow = (\d+);/);
	var theirs = body.match(/var g_daysTheirEscrow = (\d+);/);
	if(mine && theirs) {
		callback(null, parseInt(theirs[1], 10), parseInt(mine[1], 10));
		return;
	}

	// No escrow stuff found, look for an error message
	var error = body.match(/
([^<]+)<\/div>/);
	if(error) {
		callback(new Error(error[1].trim()));
		return;
	}

	callback(new Error("Malformed response"));
};

function makeAnError(error, callback) {
	if(callback) {
		callback(error);
	}
}

require('./webapi.js');
require('./assets.js');
require('./polling.js');
require('./classes/TradeOffer.js');
<|endoftext|>


<commit_before>module.exports = function(deps) {
  return function() {
    return function(next) {
      return function(action) {
        next(typeof action === 'function' ? action(deps) : action);
      };
    };
  };
};
<commit_msg>Add missing return<commit_after>module.exports = function(deps) {
  return function() {
    return function(next) {
      return function(action) {
        return next(typeof action === 'function' ? action(deps) : action);
      };
    };
  };
};
<|endoftext|>


<commit_before>var io = require('socket.io-client');
var EE = require('events').EventEmitter;
var inherits = require('util').inherits;

var CONNECTION = 'http://scorebot2.hltv.org';
var PORT = 10022;

var self;

function Livescore(options) {
    self = this;

    options = options || {};

    self.connected = false;
    self.started = false;

    self.matchid = options.matchid || null;
    self.listid = options.listid || null;
    self.url = options.url || CONNECTION;
    self.port = options.port || PORT;

    self.socket = io(self.url + ':' + self.port);
    self.reconnect = false;

    self.time = 0;
    self.map;
    self.interval;

    self.scoreboard;

    self.players = {};
    self.teams = {};

    self.kills = 0;
    self.knifeKills = 0;

    self.options = {};

    self.options[Livescore.Enums.EOption['ROUND_TIME']] = options.roundTime || 115; // 105 before update
    self.options[Livescore.Enums.EOption['BOMB_TIME']] = options.bombTime || 40; // 35 before update
    self.options[Livescore.Enums.EOption['FREEZE_TIME']] = options.freezeTime || 15;

    self.socket.on('connect', self._onConnect);
}

inherits(Livescore, EE);

Livescore.Enums = require('../Livescore.js').Enums;
Livescore.Classes = require('../Livescore.js').Classes;

Livescore.prototype.start = function(options, callback) {
    if (typeof options === 'function') {
        callback = options;
        options = {};
    }

    options = options || {};

    self.matchid = options.matchid || self.matchid;
    self.listid = options.listid || self.listid;

    if (self.connected) {
        self.socket.emit('readyForMatch', self.listid);

        if (callback) {
            callback(null);
        }
    } else if (callback) {
        callback(new Error('Not yet connected to HLTV'));
    }
};

Livescore.prototype.disconnect = function() {
    self.connected = false;
    self.socket.disconnect();
};

Livescore.prototype.getPlayers = function(callback) {
    callback(self.players);
};

Livescore.prototype.getTeams = function(callback) {
    callback(self.teams);
};

Livescore.prototype.setTime = function(time) {
    clearInterval(self.interval);

    self.time = time;
    self.interval = setInterval(function() {
        self.time = self.time - 1;
        self.emit('time', self.time);
    }, 1000);
};

Livescore.prototype.getTime = function(callback) {
    callback(self.time);
};

Livescore.prototype._onConnect = function() {
    if (!self.reconnect) {
        self.socket.on('log', self._onLog);
        self.socket.on('scoreboard', self._onScoreboard);
    }

    if (!self.connected) {
        self.connected = true;
        self.emit('connected');
    }

    if (self.matchid && self.listid) {
        self.socket.emit('readyForMatch', self.listid);
    }
};

Livescore.prototype._onReconnect = function() {
    self.reconnect = true;
    self.socket.emit('readyForMatch', self.listid);
};

Livescore.prototype._onLog = function(logs) {
    try {
        logs = JSON.parse(logs).log.reverse();

        self.emit('log', logs);
    } catch (err) {
        logs = undefined;

        self.emit('debug', err);
    }

    self.getPlayers(function(players) {
        if (Object.keys(players).length && logs) {
            logs.forEach(function(log) {
                var event;
                for (event in log) {
                    self.emit('debug', 'received event: ' + event);

                    switch (event) {
                        case 'Kill':
                        case 'Assist':
                        case 'BombPlanted':
                        case 'BombDefused':
                        case 'RoundStart':
                        case 'RoundEnd':
                        case 'PlayerJoin':
                        case 'PlayerQuit':
                        case 'MapChange':
                        case 'MatchStarted':
                        case 'Restart':
                        case 'Suicide':
                            self['_on' + event](log[event]);
                            break;
                        default:
                            self.emit('debug', 'unrecognized event: ' + event);
                            break;
                    }
                }
            });
        }
    });
};

Livescore.prototype._onScoreboard = function(event) {
    if (!self.started) {
        self.started = true;
        self.emit('started');
    }

    updateGame(event);

    self.getTeams(function(teams) {
        var scoreboard = new Livescore.Classes.Scoreboard(event);

        scoreboard.teams[Livescore.Enums.ESide['TERRORIST']] = teams[Livescore.Enums.ESide['TERRORIST']];
        scoreboard.teams[Livescore.Enums.ESide['COUNTERTERRORIST']] = teams[Livescore.Enums.ESide['COUNTERTERRORIST']];

        self.emit('scoreboard', scoreboard);
    });
};

Livescore.prototype._onKill = function(event) {
    self.getPlayers(function(players) {
        self.emit('kill', {
            killer: players[event.killerName],
            victim: players[event.victimName],
            weapon: event.weapon,
            headshot: event.headShot
        });
    });

    self.kills++;
    if (event.weapon.indexOf('knife') > -1) {
        self.knifeKills++;
    }
};

Livescore.prototype._onSuicide = function(event) {
    self.getPlayers(function(players) {
        self.emit('suicide', {
            player: players[event.playerName]
        });
    });
};

Livescore.prototype._onBombPlanted = function(event) {
    self.setTime(self.options[Livescore.Enums.EOption['BOMB_TIME']]);

    self.getPlayers(function(players) {
        self.emit('bombPlanted', {
            player: players[event.playerName]
        });
    });
};

Livescore.prototype._onBombDefused = function(event) {
    self.getPlayers(function(players) {
        self.emit('bombDefused', {
            player: players[event.playerName]
        });
    });
};

Livescore.prototype._onMatchStarted = function(event) {
    self.emit('matchStart', event);
};

Livescore.prototype._onRoundStart = function() {
    self.setTime(self.options[Livescore.Enums.EOption["ROUND_TIME"]]);
    self.emit('roundStart', {
        round: self.scoreboard.currentRound
    });

    self.kills = 0;
    self.knifeKills = 0;
};

Livescore.prototype._onRoundEnd = function(event) {
    var winner = Livescore.Enums.ESide[event.winner === 'TERRORIST' ? 'TERRORIST' : 'COUNTERTERRORIST'];

    self.setTime(self.options[Livescore.Enums.EOption["FREEZE_TIME"]]);

    self.getTeams(function(teams) {
        if (Object.keys(teams).length) {
            teams[Livescore.Enums.ESide['TERRORIST']].score = event.terroristScore;
            teams[Livescore.Enums.ESide['COUNTERTERRORIST']].score = event.counterTerroristScore;

            // If at least 80% of the kills are knife kills, count it as a knife
            // round. Sometimes players will have pistols on knife rounds and
            // kill teammates after the round is over, so self takes that into
            // account.
            self.emit('roundEnd', {
                teams: teams,
                winner: teams[winner],
                roundType: Livescore.Enums.ERoundType[event.winType],
                knifeRound: (self.knifeKills/self.kills) >= 0.8
            });
        }
    });
};

Livescore.prototype._onPlayerJoin = function(event) {
    self.emit('playerJoin', {
        playerName: event.playerName
    });
};

Livescore.prototype._onPlayerQuit = function(event) {
    self.getPlayers(function(players) {
        self.emit('playerQuit', {
            player: players[event.playerName]
        });
    });
};

Livescore.prototype._onRestart = function() {
    self.emit('restart');
};

Livescore.prototype._onMapChange = function(event) {
    self.emit('mapChange', event);
};

function updateGame(scoreboard) {
    var tPlayers = [];
    var ctPlayers = [];

    self.teams[Livescore.Enums.ESide['TERRORIST']] = new Livescore.Classes.Team({
        name: scoreboard.terroristTeamName,
        id: scoreboard.tTeamId,
        score: scoreboard.terroristScore,
        side: Livescore.Enums.ESide['TERRORIST'],
        players: tPlayers,
        history: scoreboard.terroristMatchHistory
    });

    self.teams[Livescore.Enums.ESide['COUNTERTERRORIST']] = new Livescore.Classes.Team({
        name: scoreboard.ctTeamName,
        id: scoreboard.ctTeamId,
        score: scoreboard.counterTerroristScore,
        side: Livescore.Enums.ESide['COUNTERTERRORIST'],
        players: ctPlayers,
        history: scoreboard.ctMatchHistory
    });

    self.getTeams(function(teams) {
        scoreboard.TERRORIST.forEach(function(pl) {
            var player = new Livescore.Classes.Player(pl);
            player.team = teams[Livescore.Enums.ESide['TERRORIST']];

            self.players[player.name] = player;
            tPlayers.push(player);
        });

        scoreboard.CT.forEach(function(pl) {
            var player = new Livescore.Classes.Player(pl);
            player.team = teams[Livescore.Enums.ESide['COUNTERTERRORIST']];

            self.players[player.name] = player;
            ctPlayers.push(player);
        });
    });

    self.scoreboard = scoreboard;
}

module.exports = Livescore;
<commit_msg>Fix events being emitted multiple times<commit_after>var io = require('socket.io-client');
var EE = require('events').EventEmitter;
var inherits = require('util').inherits;

var CONNECTION = 'http://scorebot2.hltv.org';
var PORT = 10022;

var self;

function Livescore(options) {
    self = this;

    options = options || {};

    self.connected = false;
    self.started = false;

    self.matchid = options.matchid || null;
    self.listid = options.listid || null;
    self.url = options.url || CONNECTION;
    self.port = options.port || PORT;

    self.socket = io(self.url + ':' + self.port);

    self.time = 0;
    self.map;
    self.interval;

    self.scoreboard;

    self.players = {};
    self.teams = {};

    self.kills = 0;
    self.knifeKills = 0;

    self._lastLog;

    self.options = {};

    self.options[Livescore.Enums.EOption['ROUND_TIME']] = options.roundTime || 115; // 105 before update
    self.options[Livescore.Enums.EOption['BOMB_TIME']] = options.bombTime || 40; // 35 before update
    self.options[Livescore.Enums.EOption['FREEZE_TIME']] = options.freezeTime || 15;

    self.socket.on('connect', self._onConnect);
}

inherits(Livescore, EE);

Livescore.Enums = require('../Livescore.js').Enums;
Livescore.Classes = require('../Livescore.js').Classes;

Livescore.prototype.start = function(options, callback) {
    if (typeof options === 'function') {
        callback = options;
        options = {};
    }

    options = options || {};

    self.matchid = options.matchid || self.matchid;
    self.listid = options.listid || self.listid;

    if (self.connected) {
        self.socket.emit('readyForMatch', self.listid);

        if (callback) {
            callback(null);
        }
    } else if (callback) {
        callback(new Error('Not yet connected to HLTV'));
    }
};

Livescore.prototype.disconnect = function() {
    self.connected = false;
    self.socket.disconnect();
};

Livescore.prototype.getPlayers = function(callback) {
    callback(self.players);
};

Livescore.prototype.getTeams = function(callback) {
    callback(self.teams);
};

Livescore.prototype.setTime = function(time) {
    clearInterval(self.interval);

    self.time = time;
    self.interval = setInterval(function() {
        self.time = self.time - 1;
        self.emit('time', self.time);
    }, 1000);
};

Livescore.prototype.getTime = function(callback) {
    callback(self.time);
};

Livescore.prototype._onConnect = function() {
    if (!self.connected) {
        self.connected = true;

        self.socket.on('log', self._onLog);
        self.socket.on('scoreboard', self._onScoreboard);

        self.emit('connected');
    }

    if (self.matchid && self.listid) {
        self.socket.emit('readyForMatch', self.listid);
    }
};

Livescore.prototype._onReconnect = function() {
    self.socket.emit('readyForMatch', self.listid);
};

Livescore.prototype._onLog = function(logs) {
    try {
        logs = JSON.parse(logs).log.reverse();
    } catch (err) {
        logs = null;

        self.emit('debug', err);
    }

    if (logs && logs !== self._lastLog) {
        self.emit('log', logs);

        self.getPlayers(function(players) {
            if (Object.keys(players).length && logs) {
                logs.forEach(function(log) {
                    var event;
                    for (event in log) {
                        self.emit('debug', 'received event: ' + event);

                        switch (event) {
                            case 'Kill':
                            case 'Assist':
                            case 'BombPlanted':
                            case 'BombDefused':
                            case 'RoundStart':
                            case 'RoundEnd':
                            case 'PlayerJoin':
                            case 'PlayerQuit':
                            case 'MapChange':
                            case 'MatchStarted':
                            case 'Restart':
                            case 'Suicide':
                                self['_on' + event](log[event]);
                                break;
                            default:
                                self.emit('debug', 'unrecognized event: ' + event);
                                break;
                        }
                    }
                });
            }
        });

        self._lastLog = logs;
    }
};

Livescore.prototype._onScoreboard = function(event) {
    if (!self.started) {
        self.started = true;
        self.emit('started');
    }

    updateGame(event);

    self.getTeams(function(teams) {
        var scoreboard = new Livescore.Classes.Scoreboard(event);

        scoreboard.teams[Livescore.Enums.ESide['TERRORIST']] = teams[Livescore.Enums.ESide['TERRORIST']];
        scoreboard.teams[Livescore.Enums.ESide['COUNTERTERRORIST']] = teams[Livescore.Enums.ESide['COUNTERTERRORIST']];

        self.emit('scoreboard', scoreboard);
    });
};

Livescore.prototype._onKill = function(event) {
    self.getPlayers(function(players) {
        self.emit('kill', {
            killer: players[event.killerName],
            victim: players[event.victimName],
            weapon: event.weapon,
            headshot: event.headShot
        });
    });

    self.kills++;
    if (event.weapon.indexOf('knife') > -1) {
        self.knifeKills++;
    }
};

Livescore.prototype._onSuicide = function(event) {
    self.getPlayers(function(players) {
        self.emit('suicide', {
            player: players[event.playerName]
        });
    });
};

Livescore.prototype._onBombPlanted = function(event) {
    self.setTime(self.options[Livescore.Enums.EOption['BOMB_TIME']]);

    self.getPlayers(function(players) {
        self.emit('bombPlanted', {
            player: players[event.playerName]
        });
    });
};

Livescore.prototype._onBombDefused = function(event) {
    self.getPlayers(function(players) {
        self.emit('bombDefused', {
            player: players[event.playerName]
        });
    });
};

Livescore.prototype._onMatchStarted = function(event) {
    self.emit('matchStart', event);
};

Livescore.prototype._onRoundStart = function() {
    self.setTime(self.options[Livescore.Enums.EOption["ROUND_TIME"]]);
    self.emit('roundStart', {
        round: self.scoreboard.currentRound
    });

    self.kills = 0;
    self.knifeKills = 0;
};

Livescore.prototype._onRoundEnd = function(event) {
    var winner = Livescore.Enums.ESide[event.winner === 'TERRORIST' ? 'TERRORIST' : 'COUNTERTERRORIST'];

    self.setTime(self.options[Livescore.Enums.EOption["FREEZE_TIME"]]);

    self.getTeams(function(teams) {
        if (Object.keys(teams).length) {
            teams[Livescore.Enums.ESide['TERRORIST']].score = event.terroristScore;
            teams[Livescore.Enums.ESide['COUNTERTERRORIST']].score = event.counterTerroristScore;

            // If at least 80% of the kills are knife kills, count it as a knife
            // round. Sometimes players will have pistols on knife rounds and
            // kill teammates after the round is over, so self takes that into
            // account.
            self.emit('roundEnd', {
                teams: teams,
                winner: teams[winner],
                roundType: Livescore.Enums.ERoundType[event.winType],
                knifeRound: (self.knifeKills/self.kills) >= 0.8
            });
        }
    });
};

Livescore.prototype._onPlayerJoin = function(event) {
    self.emit('playerJoin', {
        playerName: event.playerName
    });
};

Livescore.prototype._onPlayerQuit = function(event) {
    self.getPlayers(function(players) {
        self.emit('playerQuit', {
            player: players[event.playerName]
        });
    });
};

Livescore.prototype._onRestart = function() {
    self.emit('restart');
};

Livescore.prototype._onMapChange = function(event) {
    self.emit('mapChange', event);
};

function updateGame(scoreboard) {
    var tPlayers = [];
    var ctPlayers = [];

    self.teams[Livescore.Enums.ESide['TERRORIST']] = new Livescore.Classes.Team({
        name: scoreboard.terroristTeamName,
        id: scoreboard.tTeamId,
        score: scoreboard.terroristScore,
        side: Livescore.Enums.ESide['TERRORIST'],
        players: tPlayers,
        history: scoreboard.terroristMatchHistory
    });

    self.teams[Livescore.Enums.ESide['COUNTERTERRORIST']] = new Livescore.Classes.Team({
        name: scoreboard.ctTeamName,
        id: scoreboard.ctTeamId,
        score: scoreboard.counterTerroristScore,
        side: Livescore.Enums.ESide['COUNTERTERRORIST'],
        players: ctPlayers,
        history: scoreboard.ctMatchHistory
    });

    self.getTeams(function(teams) {
        scoreboard.TERRORIST.forEach(function(pl) {
            var player = new Livescore.Classes.Player(pl);
            player.team = teams[Livescore.Enums.ESide['TERRORIST']];

            self.players[player.name] = player;
            tPlayers.push(player);
        });

        scoreboard.CT.forEach(function(pl) {
            var player = new Livescore.Classes.Player(pl);
            player.team = teams[Livescore.Enums.ESide['COUNTERTERRORIST']];

            self.players[player.name] = player;
            ctPlayers.push(player);
        });
    });

    self.scoreboard = scoreboard;
}

module.exports = Livescore;
<|endoftext|>


<commit_before>var counter = 0;
var previousCharacter = null;

const Bird = require('./bird');
const Level = require('./level');
const KeyStroke = require('./keystroke');
const Game = require('./game');

var bird = new Bird(1);
var highScore = localStorage['high score'] || 0;
var levelOne = new Level(1, highScore, bird);

document.addEventListener('keyup', function startLevelOne(event){
  levelOne.removeInstructions();
	levelOne.render(0);
	bird.fall();
	this.removeEventListener('keyup', startLevelOne)
})

document.addEventListener('keyup', function keyStore(event){
	let currentText = $('#challenge-text').text()
	let char = event.key;
	var levelNumber = Number($('#level').text())
	let level = new Level(levelNumber, Number($('#score').text()), bird)
	let stroke = new KeyStroke(char, currentText, level)
	stroke.score().prepareForNext().updateScoreCard();
})

window.addEventListener('load', function startGame(event){
	var game = new Game();
  game.start();
})
<commit_msg>Prevent backspace from default behavior without input focus (aka leaving the page to go back)<commit_after>var counter = 0;
var previousCharacter = null;

const Bird = require('./bird');
const Level = require('./level');
const KeyStroke = require('./keystroke');
const Game = require('./game');

var bird = new Bird(1);
var highScore = localStorage['high score'] || 0;
var levelOne = new Level(1, highScore, bird);

document.addEventListener('keyup', function startLevelOne(event){
  levelOne.removeInstructions();
	levelOne.render(0);
	bird.fall();
	this.removeEventListener('keyup', startLevelOne)
})

document.addEventListener('keyup', function keyStore(event){
	let currentText = $('#challenge-text').text()
	let char = event.key;
	var levelNumber = Number($('#level').text())
	let level = new Level(levelNumber, Number($('#score').text()), bird)
	let stroke = new KeyStroke(char, currentText, level)
	stroke.score().prepareForNext().updateScoreCard();
})

window.addEventListener('load', function startGame(event){
	var game = new Game();
  game.start();
})

window.addEventListener('keydown', function() {
  if (event.which == 8) { event.preventDefault(); };
})
<|endoftext|>


<commit_before>var fs = require('fs');
var middleware = [];

fs.readdirSync(__dirname + '/middleware').forEach(function (filename) {
    if (/\.js$/.test(filename)) {
        var name = filename.substr(0, filename.lastIndexOf('.'));
        middleware.push(name);
        exports.__defineGetter__(name, function () {
            return require('./middleware/' + name);
        });
    }
});

exports.defaults = function (app, overrides) {
    overrides = overrides || {};
    middleware.forEach(function _eachMiddleware(m) {
        if (overrides[m] !== false) {
            app.use(require('./middleware/' + m)());
        }
    });
};
<commit_msg>CSP off by default in defaults<commit_after>var fs = require('fs');
var middleware = [];

fs.readdirSync(__dirname + '/middleware').forEach(function (filename) {
    if (/\.js$/.test(filename)) {
        var name = filename.substr(0, filename.lastIndexOf('.'));
        middleware.push(name);
        exports.__defineGetter__(name, function () {
            return require('./middleware/' + name);
        });
    }
});

exports.defaults = function (app, overrides) {
    overrides = overrides || {csp: false};
    middleware.forEach(function _eachMiddleware(m) {
        if (overrides[m] !== false) {
            app.use(require('./middleware/' + m)());
        }
    });
};
<|endoftext|>