<commit_before>/**
 * Module dependencies.
 */

var EventEmitter = require('events').EventEmitter;
var JSON = require('json3');
var Pending = require('./pending');
var debug = require('debug')('mocha:runnable');
var milliseconds = require('./ms');
var utils = require('./utils');
var create = require('lodash.create');

/**
 * Save timer references to avoid Sinon interfering (see GH-237).
 */

/* eslint-disable no-unused-vars, no-native-reassign */
var Date = global.Date;
var setTimeout = global.setTimeout;
var setInterval = global.setInterval;
var clearTimeout = global.clearTimeout;
var clearInterval = global.clearInterval;
/* eslint-enable no-unused-vars, no-native-reassign */

/**
 * Object#toString().
 */

var toString = Object.prototype.toString;

/**
 * Expose `Runnable`.
 */

module.exports = Runnable;

/**
 * Initialize a new `Runnable` with the given `title` and callback `fn`.
 *
 * @param {String} title
 * @param {Function} fn
 * @api private
 * @param {string} title
 * @param {Function} fn
 */
function Runnable(title, fn) {
  this.title = title;
  this.fn = fn;
  this.body = (fn || '').toString();
  this.async = fn && fn.length;
  this.sync = !this.async;
  this._timeout = 2000;
  this._slow = 75;
  this._enableTimeouts = true;
  this.timedOut = false;
  this._trace = new Error('done() called multiple times');
  this._retries = -1;
  this._currentRetry = 0;
  this.pending = false;
}

/**
 * Inherit from `EventEmitter.prototype`.
 */
Runnable.prototype = create(EventEmitter.prototype, {
  constructor: Runnable
});

/**
 * Set & get timeout `ms`.
 *
 * @api private
 * @param {number|string} ms
 * @return {Runnable|number} ms or Runnable instance.
 */
Runnable.prototype.timeout = function(ms) {
  if (!arguments.length) {
    return this._timeout;
  }
  // see #1652 for reasoning
  if (ms === 0 || ms > Math.pow(2, 31)) {
    this._enableTimeouts = false;
  }
  if (typeof ms === 'string') {
    ms = milliseconds(ms);
  }
  debug('timeout %d', ms);
  this._timeout = ms;
  if (this.timer) {
    this.resetTimeout();
  }
  return this;
};

/**
 * Set & get slow `ms`.
 *
 * @api private
 * @param {number|string} ms
 * @return {Runnable|number} ms or Runnable instance.
 */
Runnable.prototype.slow = function(ms) {
  if (typeof ms === 'undefined') {
    return this._slow;
  }
  if (typeof ms === 'string') {
    ms = milliseconds(ms);
  }
  debug('timeout %d', ms);
  this._slow = ms;
  return this;
};

/**
 * Set and get whether timeout is `enabled`.
 *
 * @api private
 * @param {boolean} enabled
 * @return {Runnable|boolean} enabled or Runnable instance.
 */
Runnable.prototype.enableTimeouts = function(enabled) {
  if (!arguments.length) {
    return this._enableTimeouts;
  }
  debug('enableTimeouts %s', enabled);
  this._enableTimeouts = enabled;
  return this;
};

/**
 * Halt and mark as pending.
 *
 * @api public
 */
Runnable.prototype.skip = function() {
  throw new Pending();
};

/**
 * Check if this runnable or its parent suite is marked as pending.
 *
 * @api private
 */
Runnable.prototype.isPending = function() {
  return this.pending || (this.parent && this.parent.isPending());
};

/**
 * Set number of retries.
 *
 * @api private
 */
Runnable.prototype.retries = function(n) {
  if (!arguments.length) {
    return this._retries;
  }
  this._retries = n;
};

/**
 * Get current retry
 *
 * @api private
 */
Runnable.prototype.currentRetry = function(n) {
  if (!arguments.length) {
    return this._currentRetry;
  }
  this._currentRetry = n;
};

/**
 * Return the full title generated by recursively concatenating the parent's
 * full title.
 *
 * @api public
 * @return {string}
 */
Runnable.prototype.fullTitle = function() {
  return this.parent.fullTitle() + ' ' + this.title;
};

/**
 * Clear the timeout.
 *
 * @api private
 */
Runnable.prototype.clearTimeout = function() {
  clearTimeout(this.timer);
};

/**
 * Inspect the runnable void of private properties.
 *
 * @api private
 * @return {string}
 */
Runnable.prototype.inspect = function() {
  return JSON.stringify(this, function(key, val) {
    if (key[0] === '_') {
      return;
    }
    if (key === 'parent') {
      return '#<Suite>';
    }
    if (key === 'ctx') {
      return '#<Context>';
    }
    return val;
  }, 2);
};

/**
 * Reset the timeout.
 *
 * @api private
 */
Runnable.prototype.resetTimeout = function() {
  var self = this;
  var ms = this.timeout() || 1e9;

  if (!this._enableTimeouts) {
    return;
  }
  this.clearTimeout();
  this.timer = setTimeout(function() {
    if (!self._enableTimeouts) {
      return;
    }
    self.callback(new Error('timeout of ' + ms + 'ms exceeded. Ensure the done() callback is being called in this test.'));
    self.timedOut = true;
  }, ms);
};

/**
 * Whitelist a list of globals for this test run.
 *
 * @api private
 * @param {string[]} globals
 */
Runnable.prototype.globals = function(globals) {
  if (!arguments.length) {
    return this._allowedGlobals;
  }
  this._allowedGlobals = globals;
};

/**
 * Run the test and invoke `fn(err)`.
 *
 * @param {Function} fn
 * @api private
 */
Runnable.prototype.run = function(fn) {
  var self = this;
  var start = new Date();
  var ctx = this.ctx;
  var finished;
  var emitted;

  // Sometimes the ctx exists, but it is not runnable
  if (ctx && ctx.runnable) {
    ctx.runnable(this);
  }

  // called multiple times
  function multiple(err) {
    if (emitted) {
      return;
    }
    emitted = true;
    self.emit('error', err || new Error('done() called multiple times; stacktrace may be inaccurate'));
  }

  // finished
  function done(err) {
    var ms = self.timeout();
    if (self.timedOut) {
      return;
    }
    if (finished) {
      return multiple(err || self._trace);
    }

    self.clearTimeout();
    self.duration = new Date() - start;
    finished = true;
    if (!err && self.duration > ms && self._enableTimeouts) {
      err = new Error('timeout of ' + ms + 'ms exceeded. Ensure the done() callback is being called in this test.');
    }
    fn(err);
  }

  // for .resetTimeout()
  this.callback = done;

  // explicit async with `done` argument
  if (this.async) {
    this.resetTimeout();

    if (this.allowUncaught) {
      return callFnAsync(this.fn);
    }
    try {
      // allows skip() to be used in an explicit async context
      this.skip = function() {
        done(new Pending());
      };
      callFnAsync(this.fn);
    } catch (err) {
      done(utils.getError(err));
    }
    return;
  }

  if (this.allowUncaught) {
    callFn(this.fn);
    done();
    return;
  }

  // sync or promise-returning
  try {
    if (this.isPending()) {
      done();
    } else {
      callFn(this.fn);
    }
  } catch (err) {
    done(utils.getError(err));
  }

  function callFn(fn) {
    var result = fn.call(ctx);
    if (result && typeof result.then === 'function') {
      self.resetTimeout();
      result
        .then(function() {
          done();
          // Return null so libraries like bluebird do not warn about
          // subsequently constructed Promises.
          return null;
        },
        function(reason) {
          done(reason || new Error('Promise rejected with no or falsy reason'));
        });
    } else {
      if (self.asyncOnly) {
        return done(new Error('--async-only option in use without declaring `done()` or returning a promise'));
      }

      done();
    }
  }

  function callFnAsync(fn) {
    var result = fn.call(ctx, function(err) {
      if (err instanceof Error || toString.call(err) === '[object Error]') {
        return done(err);
      }
      if (err) {
        if (Object.prototype.toString.call(err) === '[object Object]') {
          return done(new Error('done() invoked with non-Error: '
            + JSON.stringify(err)));
        }
        return done(new Error('done() invoked with non-Error: ' + err));
      }
      if (result && utils.isPromise(result)) {
        return done(new Error('Asynchronous resolution method is overspecified. Specify a callback *or* return a Promise, not both.'));
      }

      done();
    });
  }
};
<commit_msg>tweak wording on "overspecification" exception<commit_after>/**
 * Module dependencies.
 */

var EventEmitter = require('events').EventEmitter;
var JSON = require('json3');
var Pending = require('./pending');
var debug = require('debug')('mocha:runnable');
var milliseconds = require('./ms');
var utils = require('./utils');
var create = require('lodash.create');

/**
 * Save timer references to avoid Sinon interfering (see GH-237).
 */

/* eslint-disable no-unused-vars, no-native-reassign */
var Date = global.Date;
var setTimeout = global.setTimeout;
var setInterval = global.setInterval;
var clearTimeout = global.clearTimeout;
var clearInterval = global.clearInterval;
/* eslint-enable no-unused-vars, no-native-reassign */

/**
 * Object#toString().
 */

var toString = Object.prototype.toString;

/**
 * Expose `Runnable`.
 */

module.exports = Runnable;

/**
 * Initialize a new `Runnable` with the given `title` and callback `fn`.
 *
 * @param {String} title
 * @param {Function} fn
 * @api private
 * @param {string} title
 * @param {Function} fn
 */
function Runnable(title, fn) {
  this.title = title;
  this.fn = fn;
  this.body = (fn || '').toString();
  this.async = fn && fn.length;
  this.sync = !this.async;
  this._timeout = 2000;
  this._slow = 75;
  this._enableTimeouts = true;
  this.timedOut = false;
  this._trace = new Error('done() called multiple times');
  this._retries = -1;
  this._currentRetry = 0;
  this.pending = false;
}

/**
 * Inherit from `EventEmitter.prototype`.
 */
Runnable.prototype = create(EventEmitter.prototype, {
  constructor: Runnable
});

/**
 * Set & get timeout `ms`.
 *
 * @api private
 * @param {number|string} ms
 * @return {Runnable|number} ms or Runnable instance.
 */
Runnable.prototype.timeout = function(ms) {
  if (!arguments.length) {
    return this._timeout;
  }
  // see #1652 for reasoning
  if (ms === 0 || ms > Math.pow(2, 31)) {
    this._enableTimeouts = false;
  }
  if (typeof ms === 'string') {
    ms = milliseconds(ms);
  }
  debug('timeout %d', ms);
  this._timeout = ms;
  if (this.timer) {
    this.resetTimeout();
  }
  return this;
};

/**
 * Set & get slow `ms`.
 *
 * @api private
 * @param {number|string} ms
 * @return {Runnable|number} ms or Runnable instance.
 */
Runnable.prototype.slow = function(ms) {
  if (typeof ms === 'undefined') {
    return this._slow;
  }
  if (typeof ms === 'string') {
    ms = milliseconds(ms);
  }
  debug('timeout %d', ms);
  this._slow = ms;
  return this;
};

/**
 * Set and get whether timeout is `enabled`.
 *
 * @api private
 * @param {boolean} enabled
 * @return {Runnable|boolean} enabled or Runnable instance.
 */
Runnable.prototype.enableTimeouts = function(enabled) {
  if (!arguments.length) {
    return this._enableTimeouts;
  }
  debug('enableTimeouts %s', enabled);
  this._enableTimeouts = enabled;
  return this;
};

/**
 * Halt and mark as pending.
 *
 * @api public
 */
Runnable.prototype.skip = function() {
  throw new Pending();
};

/**
 * Check if this runnable or its parent suite is marked as pending.
 *
 * @api private
 */
Runnable.prototype.isPending = function() {
  return this.pending || (this.parent && this.parent.isPending());
};

/**
 * Set number of retries.
 *
 * @api private
 */
Runnable.prototype.retries = function(n) {
  if (!arguments.length) {
    return this._retries;
  }
  this._retries = n;
};

/**
 * Get current retry
 *
 * @api private
 */
Runnable.prototype.currentRetry = function(n) {
  if (!arguments.length) {
    return this._currentRetry;
  }
  this._currentRetry = n;
};

/**
 * Return the full title generated by recursively concatenating the parent's
 * full title.
 *
 * @api public
 * @return {string}
 */
Runnable.prototype.fullTitle = function() {
  return this.parent.fullTitle() + ' ' + this.title;
};

/**
 * Clear the timeout.
 *
 * @api private
 */
Runnable.prototype.clearTimeout = function() {
  clearTimeout(this.timer);
};

/**
 * Inspect the runnable void of private properties.
 *
 * @api private
 * @return {string}
 */
Runnable.prototype.inspect = function() {
  return JSON.stringify(this, function(key, val) {
    if (key[0] === '_') {
      return;
    }
    if (key === 'parent') {
      return '#<Suite>';
    }
    if (key === 'ctx') {
      return '#<Context>';
    }
    return val;
  }, 2);
};

/**
 * Reset the timeout.
 *
 * @api private
 */
Runnable.prototype.resetTimeout = function() {
  var self = this;
  var ms = this.timeout() || 1e9;

  if (!this._enableTimeouts) {
    return;
  }
  this.clearTimeout();
  this.timer = setTimeout(function() {
    if (!self._enableTimeouts) {
      return;
    }
    self.callback(new Error('timeout of ' + ms + 'ms exceeded. Ensure the done() callback is being called in this test.'));
    self.timedOut = true;
  }, ms);
};

/**
 * Whitelist a list of globals for this test run.
 *
 * @api private
 * @param {string[]} globals
 */
Runnable.prototype.globals = function(globals) {
  if (!arguments.length) {
    return this._allowedGlobals;
  }
  this._allowedGlobals = globals;
};

/**
 * Run the test and invoke `fn(err)`.
 *
 * @param {Function} fn
 * @api private
 */
Runnable.prototype.run = function(fn) {
  var self = this;
  var start = new Date();
  var ctx = this.ctx;
  var finished;
  var emitted;

  // Sometimes the ctx exists, but it is not runnable
  if (ctx && ctx.runnable) {
    ctx.runnable(this);
  }

  // called multiple times
  function multiple(err) {
    if (emitted) {
      return;
    }
    emitted = true;
    self.emit('error', err || new Error('done() called multiple times; stacktrace may be inaccurate'));
  }

  // finished
  function done(err) {
    var ms = self.timeout();
    if (self.timedOut) {
      return;
    }
    if (finished) {
      return multiple(err || self._trace);
    }

    self.clearTimeout();
    self.duration = new Date() - start;
    finished = true;
    if (!err && self.duration > ms && self._enableTimeouts) {
      err = new Error('timeout of ' + ms + 'ms exceeded. Ensure the done() callback is being called in this test.');
    }
    fn(err);
  }

  // for .resetTimeout()
  this.callback = done;

  // explicit async with `done` argument
  if (this.async) {
    this.resetTimeout();

    if (this.allowUncaught) {
      return callFnAsync(this.fn);
    }
    try {
      // allows skip() to be used in an explicit async context
      this.skip = function() {
        done(new Pending());
      };
      callFnAsync(this.fn);
    } catch (err) {
      done(utils.getError(err));
    }
    return;
  }

  if (this.allowUncaught) {
    callFn(this.fn);
    done();
    return;
  }

  // sync or promise-returning
  try {
    if (this.isPending()) {
      done();
    } else {
      callFn(this.fn);
    }
  } catch (err) {
    done(utils.getError(err));
  }

  function callFn(fn) {
    var result = fn.call(ctx);
    if (result && typeof result.then === 'function') {
      self.resetTimeout();
      result
        .then(function() {
          done();
          // Return null so libraries like bluebird do not warn about
          // subsequently constructed Promises.
          return null;
        },
        function(reason) {
          done(reason || new Error('Promise rejected with no or falsy reason'));
        });
    } else {
      if (self.asyncOnly) {
        return done(new Error('--async-only option in use without declaring `done()` or returning a promise'));
      }

      done();
    }
  }

  function callFnAsync(fn) {
    var result = fn.call(ctx, function(err) {
      if (err instanceof Error || toString.call(err) === '[object Error]') {
        return done(err);
      }
      if (err) {
        if (Object.prototype.toString.call(err) === '[object Object]') {
          return done(new Error('done() invoked with non-Error: '
            + JSON.stringify(err)));
        }
        return done(new Error('done() invoked with non-Error: ' + err));
      }
      if (result && utils.isPromise(result)) {
        return done(new Error('Resolution method is overspecified. Specify a callback *or* return a Promise; not both.'));
      }

      done();
    });
  }
};
<|endoftext|>


<commit_before>"use strict"

const cayley = require('./cayley');

exports.flow = (scope, state, args, data, next) => {

    if (!data.id) {
        return next(new Error('Flow-api.get.flow: missing sequence id.'));
    }

    let role = !data.session || !data.session.role ? scope.env.role : data.session.role;

    data.readable = cayley.flow(state.g, data.id, role);
    data.readable[0].pause();
    data.readable[1].pause();
    data.readable[2].pause();
    data.resume = data.readable;
    next(null, data);
};

exports.networks = (scope, state, args, data, next) => {

    if (!data.id) {
        return next(new Error('Flow-api.get.flow: Missing user info.'));
    }

    let role = !data.session || !data.session.role ? scope.env.role : data.session.role;

    data.readable = cayley.networks(state.g, data.id, role);
    data.readable.pause();
    data.resume = data.readable;
    next(null, data);
};

exports.entrypoints = (scope, state, args, data, next) => {

    if (!data.id) {
        return next(new Error('Flow-api.get.flow: Missing network id.'));
    }

    let role = !data.session || !data.session.role ? scope.env.role : data.session.role;

    data.readable = cayley.entrypoints(state.g, data.id, role);
    data.readable[0].pause();
    data.readable[1].pause();
    data.resume = data.readable;
    next(null, data);
};

exports.entrypoint = (scope, state, args, data, next) => {

    if (!data.id) {
        return next(new Error('Flow-api.get.flow: Missing entrypoint id.'));
    }

    let role = !data.session || !data.session.role ? scope.env.role : data.session.role;

    data.readable = cayley.entrypoint(state.g, data.id, role);
    data.readable[0].pause();
    data.readable[1].pause();
    data.readable[2].pause();
    data.readable[3].pause();
    data.resume = data.readable;
    next(null, data);
};

exports.sequence = (scope, state, args, data, next) => {

    if (!data.id) {
        return next(new Error('Flow-api.get.flow: Missing sequence id.'));
    }

    let role = !data.session || !data.session.role ? scope.env.role : data.session.role;

    data.readable = cayley.sequence(state.g, data.id, role);
    data.readable[0].pause();
    data.readable[1].pause();
    data.readable[2].pause();
    data.resume = data.readable;
    next(null, data);
};

exports.handler = (scope, state, args, data, next) => {

    if (!data.id) {
        return next(new Error('Flow-api.get.flow: Missing handler id.'));
    }

    let role = !data.session || !data.session.role ? scope.env.role : data.session.role;

    data.readable = cayley.handler(state.g, data.id, role);
    data.readable.pause();
    data.resume = data.readable;
    next(null, data);
};
<commit_msg>pause streams<commit_after>"use strict"

const cayley = require('./cayley');

exports.flow = (scope, state, args, data, next) => {

    if (!data.id) {
        return next(new Error('Flow-api.get.flow: missing sequence id.'));
    }

    let role = !data.session || !data.session.role ? scope.env.role : data.session.role;

    data.readable = cayley.flow(state.g, data.id, role);
    data.readable[0].pause();
    data.readable[1].pause();
    data.readable[2].pause();
    data.resume = data.readable;
    next(null, data);
};

exports.networks = (scope, state, args, data, next) => {

    if (!data.id) {
        return next(new Error('Flow-api.get.flow: Missing user info.'));
    }

    let role = !data.session || !data.session.role ? scope.env.role : data.session.role;

    data.readable = cayley.networks(state.g, data.id, role);
    data.readable.pause();
    data.resume = data.readable;
    next(null, data);
};

exports.entrypoints = (scope, state, args, data, next) => {

    if (!data.id) {
        return next(new Error('Flow-api.get.flow: Missing network id.'));
    }

    let role = !data.session || !data.session.role ? scope.env.role : data.session.role;

    data.readable = cayley.entrypoints(state.g, data.id, role);
    data.readable[0].pause();
    data.readable[1].pause();
    data.resume = data.readable;
    next(null, data);
};

exports.entrypoint = (scope, state, args, data, next) => {

    if (!data.id) {
        return next(new Error('Flow-api.get.flow: Missing entrypoint id.'));
    }

    let role = !data.session || !data.session.role ? scope.env.role : data.session.role;

    data.readable = cayley.entrypoint(state.g, data.id, role);
    data.readable[0].pause();
    data.readable[1].pause();
    data.readable[2].pause();
    data.readable[3].pause();
    data.resume = data.readable;
    next(null, data);
};

exports.sequence = (scope, state, args, data, next) => {

    if (!data.id) {
        return next(new Error('Flow-api.get.flow: Missing sequence id.'));
    }

    let role = !data.session || !data.session.role ? scope.env.role : data.session.role;

    data.readable = cayley.sequence(state.g, data.id, role);
    data.readable[0].pause();
    data.readable[1].pause();
    data.readable[2].pause();
    data.resume = data.readable;
    next(null, data);
};

exports.handler = (scope, state, args, data, next) => {

    if (!data.id) {
        return next(new Error('Flow-api.get.flow: Missing handler id.'));
    }

    let role = !data.session || !data.session.role ? scope.env.role : data.session.role;

    data.readable = cayley.handler(state.g, data.id, role);
    data.readable[0].pause();
    data.readable[1].pause();
    data.readable[2].pause();
    data.readable[3].pause();
    data.readable[4].pause();
    data.resume = data.readable;
    next(null, data);
};
<|endoftext|>


<commit_before>module.exports = function init(____0) {
  const sessions = function () {};
  sessions.list = [];
  sessions.path = ____0.path.resolve(____0.cwd + '/' + ____0.options.name + '_' + 'sessions.db');
  sessions.$collection = ____0.connectCollection({ collection: ____0.options.session.collection, db: ____0.options.session.db });

  sessions.loadAll = function (callback) {
    callback =
      callback ||
      function (err, docs) {
        if (!err && docs) {
          sessions.list = docs;
        }
      };
    if (____0.options.session.storage === 'mongodb') {
      sessions.$collection.findAll({}, (err, docs) => {
        callback(err, docs);
      });
    } else {
      let ss = ____0.readFileSync(sessions.path);
      if (ss) {
        try {
          ss = JSON.parse(ss);
          callback(null, ss);
          console.log(' ... sessions Loaded From ...' + sessions.path);
        } catch (err) {
          console.log(err.message);
        }
      }
    }

    return;
  };

  sessions.saveAll = function (callback) {

    callback =
      callback ||
      function (err) {
        if (err) {
          console.log(err.message);
        }
      };

    if (____0.options.session.timeout === 0 || !____0.options.session.enabled) {
      callback({
        message: 'Timout is Zero or not Enabled , Sessions Will Not Saved',
      });
      return;
    }

    if (____0.options.session.storage === 'mongodb') {
      sessions.list.forEach((s, i) => {
        if (new Date().getTime() - s.createdTime > 1000 * 60 * ____0.options.session.timeout) {
          sessions.list.splice(i, 1);
          sessions.$collection.delete(s);
        } else {
          if (s.id) {
            sessions.$collection.update(s, (err, result) => {
              if (!err && result) {
                sessions.list[i] = result.doc;
              }
            });
          } else {
            sessions.$collection.insert(s, (err, doc) => {
              if (!err && doc) {
                sessions.list[i] = doc;
              }
            });
          }
        }
      });

      sessions.$collection.deleteAll({}, (err, docs) => {
        sessions.$collection.insertAll(sessions.list, (err, docs) => {
          callback(err, docs);
        });
      });
    } else {
      sessions.list.forEach((s, i) => {
        let online = new Date().getTime() - s.createdTime;
        let timeout = 1000 * 60 * ____0.options.session.timeout;
        if (online > timeout) {
          sessions.list.splice(i, 1);
        }
      });

      ____0.writeFile(sessions.path, JSON.stringify(sessions.list), () => {
        callback(null, sessions.list);
        console.log(' ... sessions Saved to ...' + sessions.path);
      });
    }

    return;
  };

  ____0.getSession = sessions.attach = function (session, callback) {
    callback = callback || function () {};
    session.$exists = !1;

    if (session.accessToken) {
      sessions.list.forEach((s, i) => {
        if (s.accessToken && s.accessToken == session.accessToken) {
          session.$exists = !0;
          session.$index = i;
          sessions.list[session.$index].requestesCount++;
        }
      });
    }
    if (!session.$exists) {
      if (____0.options.session.storage === 'mongodb') {
        sessions.$collection.find({ accessToken: session.accessToken }, (err, doc) => {
          if (!err && doc) {
            session.$exists = !0;
            session = { ...session, ...doc };
            session.requestesCount++;
            session.$index = sessions.list.length;
            sessions.list.push(session);
            callback(sessions.list[session.$index]);
          } else {
            session.$new = !0;
            session.lang = ____0.options.lang;
            session.theme = ____0.options.theme;
            session.data = [];
            session.ip_list = [];
            session.requestesCount = 1;
            session.createdTime = new Date().getTime();
            session.$index = sessions.list.length;
            sessions.list.push(session);
            callback(sessions.list[session.$index]);
          }
        });
      } else {
        session.$new = !0;
        session.lang = ____0.options.lang;
        session.theme = ____0.options.theme;
        session.data = [];
        session.ip_list = session.ip_list || [];
        session.requestesCount = 1;
        session.createdTime = new Date().getTime();
        session.$index = sessions.list.length;
        sessions.list.push(session);
        callback(sessions.list[session.$index]);
      }
    } else {
      callback(sessions.list[session.$index]);
    }
  };

  ____0.saveSession = sessions.save = function (session, callback) {
    callback = callback || function () {};
    session.$exists = !1;

    if (session.$index && sessions.list[session.$index]) {
      sessions.list[session.$index] = { ...sessions.list[session.$index], ...session };
      callback(sessions.list[session.$index]);
      return sessions.list[session.$index];
    } else {
      sessions.list.forEach((s, i) => {
        if (session.$exists) {
          return;
        }
        if (s.accessToken == session.accessToken) {
          sessions.list[i] = { ...sessions.list[i], ...session };
          session.$exists = !0;
          session.$index = i;
          callback(sessions.list[session.$index]);
          return sessions.list[session.$index];
        }
      });
    }
    return sessions.list[session.$index];
  };

  ____0.on('[session][update]', (session) => {
    sessions.list.forEach((s) => {
      if (s.accessToken == session.accessToken) {
        for (let key in session) {
          if (session.hasOwnProperty(key) && key !== 'accessToken') {
            key = key.toLowerCase();
            for (let i = 0; i < s.data.length; i++) {
              let obj = s.data[i];
              if (obj.key === key) {
                s.data[i] = {
                  key: key,
                  value: session[key],
                };
              }
            }
            s.data.push({
              key: key,
              value: session[key],
            });
          }
        }
      }
    });
  });
  ____0.on('[session][delete]', (session) => {
    sessions.list.forEach((s, i) => {
      if (s.accessToken == session.accessToken) {
        sessions.list.splice(i, 1);
      }
    });
  });
  ____0.on('[session][user][update]', (user) => {
    sessions.list.forEach((s) => {
      if (s.user && s.user.id == user.id) {
        s.user = user;
      }
    });
  });

  ____0.on('[any][saving data]', function () {
    sessions.saveAll();
  });

  ____0.onPOST({ name: '/x-language/change', public: true }, (req, res) => {
    req.session.lang = req.data.name;
    ____0.saveSession(req.session);
    res.json({
      done: true,
      lang: req.data.name,
    });
  });

  ____0.onPOST('x-api/session', (req, res) => {
    res.json({
      done: !0,
      session: req.session,
    });
  });

  ____0.onPOST('x-api/sessions', (req, res) => {
    res.json({
      done: !0,
      list: sessions.list,
    });
  });

  ____0.onPOST('x-api/sessions/save', (req, res) => {
    sessions.saveAll();
    res.json({
      done: !0,
    });
  });
  ____0.onPOST('x-api/sessions/delete', (req, res) => {
    sessions.list = [];
    sessions.saveAll((err, docs) => {
      res.json({
        err: err,
        docs: docs,
        done: !0,
      });
    });
  });

  if (!____0.options.session.storage === 'mongodb') {
    sessions.loadAll();
  }
  return sessions;
};
<commit_msg>update<commit_after>module.exports = function init(____0) {
  const sessions = function () {};
  sessions.list = [];
  sessions.path = ____0.path.resolve(____0.cwd + '/' + ____0.options.name + '_' + 'sessions.db');
  sessions.$collection = ____0.connectCollection({ collection: ____0.options.session.collection, db: ____0.options.session.db });

  sessions.loadAll = function (callback) {
    callback =
      callback ||
      function (err, docs) {
        if (!err && docs) {
          sessions.list = docs;
        }
      };
    if (____0.options.session.storage === 'mongodb') {
      sessions.$collection.findAll({}, (err, docs) => {
        callback(err, docs);
      });
    } else {
      let ss = ____0.readFileSync(sessions.path);
      if (ss) {
        try {
          ss = JSON.parse(ss);
          callback(null, ss);
          console.log(' ... sessions Loaded From ...' + sessions.path);
        } catch (err) {
          console.log(err.message);
        }
      }
    }

    return;
  };

  sessions.saveAll = function (callback) {

    callback =
      callback ||
      function (err) {
        if (err) {
          console.log(err.message);
        }
      };

    if (____0.options.session.timeout === 0 || !____0.options.session.enabled) {
      callback({
        message: 'Timout is Zero or not Enabled , Sessions Will Not Saved',
      });
      return;
    }

    if (____0.options.session.storage === 'mongodb') {
      sessions.list.forEach((s, i) => {
        if (new Date().getTime() - s.createdTime > 1000 * 60 * ____0.options.session.timeout) {
          sessions.list.splice(i, 1);
          sessions.$collection.delete(s);
        } else {
          if (s.id) {
            sessions.$collection.update(s, (err, result) => {
              if (!err && result) {
                sessions.list[i] = result.doc;
              }
            });
          } else {
            sessions.$collection.insert(s, (err, doc) => {
              if (!err && doc) {
                sessions.list[i] = doc;
              }
            });
          }
        }
      });

      sessions.$collection.deleteAll({}, (err, docs) => {
        sessions.$collection.insertAll(sessions.list, (err, docs) => {
          callback(err, docs);
        });
      });
    } else {
      sessions.list.forEach((s, i) => {
        let online = new Date().getTime() - s.createdTime;
        let timeout = 1000 * 60 * ____0.options.session.timeout;
        if (online > timeout) {
          sessions.list.splice(i, 1);
        }
      });

      ____0.writeFile(sessions.path, JSON.stringify(sessions.list), () => {
        callback(null, sessions.list);
        console.log(' ... sessions Saved to ...' + sessions.path);
      });
    }

    return;
  };

  ____0.getSession = sessions.attach = function (session, callback) {
    callback = callback || function () {};
    session.$exists = !1;

    if (session.accessToken) {
      sessions.list.forEach((s, i) => {
        if (s && s.accessToken && s.accessToken == session.accessToken) {
          session.$exists = !0;
          session.$index = i;
          sessions.list[session.$index].requestesCount++;
        }
      });
    }
    if (!session.$exists) {
      if (____0.options.session.storage === 'mongodb') {
        sessions.$collection.find({ accessToken: session.accessToken }, (err, doc) => {
          if (!err && doc) {
            session.$exists = !0;
            session = { ...session, ...doc };
            session.requestesCount++;
            session.$index = sessions.list.length;
            sessions.list.push(session);
            callback(sessions.list[session.$index]);
          } else {
            session.$new = !0;
            session.lang = ____0.options.lang;
            session.theme = ____0.options.theme;
            session.data = [];
            session.ip_list = [];
            session.requestesCount = 1;
            session.createdTime = new Date().getTime();
            session.$index = sessions.list.length;
            sessions.list.push(session);
            callback(sessions.list[session.$index]);
          }
        });
      } else {
        session.$new = !0;
        session.lang = ____0.options.lang;
        session.theme = ____0.options.theme;
        session.data = [];
        session.ip_list = session.ip_list || [];
        session.requestesCount = 1;
        session.createdTime = new Date().getTime();
        session.$index = sessions.list.length;
        sessions.list.push(session);
        callback(sessions.list[session.$index]);
      }
    } else {
      callback(sessions.list[session.$index]);
    }
  };

  ____0.saveSession = sessions.save = function (session, callback) {
    callback = callback || function () {};
    session.$exists = !1;

    if (session.$index && sessions.list[session.$index]) {
      sessions.list[session.$index] = { ...sessions.list[session.$index], ...session };
      callback(sessions.list[session.$index]);
      return sessions.list[session.$index];
    } else {
      sessions.list.forEach((s, i) => {
        if (session.$exists) {
          return;
        }
        if (s.accessToken == session.accessToken) {
          sessions.list[i] = { ...sessions.list[i], ...session };
          session.$exists = !0;
          session.$index = i;
          callback(sessions.list[session.$index]);
          return sessions.list[session.$index];
        }
      });
    }
    return sessions.list[session.$index];
  };

  ____0.on('[session][update]', (session) => {
    sessions.list.forEach((s) => {
      if (s.accessToken == session.accessToken) {
        for (let key in session) {
          if (session.hasOwnProperty(key) && key !== 'accessToken') {
            key = key.toLowerCase();
            for (let i = 0; i < s.data.length; i++) {
              let obj = s.data[i];
              if (obj.key === key) {
                s.data[i] = {
                  key: key,
                  value: session[key],
                };
              }
            }
            s.data.push({
              key: key,
              value: session[key],
            });
          }
        }
      }
    });
  });
  ____0.on('[session][delete]', (session) => {
    sessions.list.forEach((s, i) => {
      if (s.accessToken == session.accessToken) {
        sessions.list.splice(i, 1);
      }
    });
  });
  ____0.on('[session][user][update]', (user) => {
    sessions.list.forEach((s) => {
      if (s.user && s.user.id == user.id) {
        s.user = user;
      }
    });
  });

  ____0.on('[any][saving data]', function () {
    sessions.saveAll();
  });

  ____0.onPOST({ name: '/x-language/change', public: true }, (req, res) => {
    req.session.lang = req.data.name;
    ____0.saveSession(req.session);
    res.json({
      done: true,
      lang: req.data.name,
    });
  });

  ____0.onPOST('x-api/session', (req, res) => {
    res.json({
      done: !0,
      session: req.session,
    });
  });

  ____0.onPOST('x-api/sessions', (req, res) => {
    res.json({
      done: !0,
      list: sessions.list,
    });
  });

  ____0.onPOST('x-api/sessions/save', (req, res) => {
    sessions.saveAll();
    res.json({
      done: !0,
    });
  });
  ____0.onPOST('x-api/sessions/delete', (req, res) => {
    sessions.list = [];
    sessions.saveAll((err, docs) => {
      res.json({
        err: err,
        docs: docs,
        done: !0,
      });
    });
  });

  if (!____0.options.session.storage === 'mongodb') {
    sessions.loadAll();
  }
  return sessions;
};
<|endoftext|>


<commit_before>import axios from 'axios';
import {
    get_edit_window_timespan,
    get_selected_words,
    get_subs_chunks,
} from 'routes/TrackDetail/module';

const endpoint = API_BASE + '/subsubmit/';

export function send_subs(form_values, dispatch, props) {
    return (dispatch, get_state) => {
        const state = get_state();
        const selw = get_selected_words(state);
        const subs_chunks = get_subs_chunks(state);
        dispatch({
            type: 'send_subs',
            words: selw,
            subs_chunks,
        });
        const timespan = get_edit_window_timespan(state);
        axios.request({
            url: endpoint,
            method: 'POST',
            params: {
                filestem: props.stem,
                start: timespan.start,
                end:   timespan.end,
                trans: form_values.edited_subtitles,
                author: state.form.username.values.username,
                session: localStorage.getItem('session'),
            },
        }).then(res => {
            if (res.data && res.data.success) {
                dispatch({
                    type: 'accepted_submission',
                    replaced_words: selw,
                    accepted_words: res.data.data,
                });
            }
            else {
                dispatch({
                    type: 'failed_submission',
                    words: selw,
                    subs_chunks,
                });
            }
        })
        .catch(() => {
            dispatch({
                type: 'submission_error',
                words: selw,
            });
        });
    };
};
<commit_msg>continue playback at edit window end after subsubmit<commit_after>import axios from 'axios';
import {
    get_edit_window_timespan,
    get_selected_words,
    get_subs_chunks,
} from 'routes/TrackDetail/module';

const endpoint = API_BASE + '/subsubmit/';

export function send_subs(form_values, dispatch, props) {
    return (dispatch, get_state) => {
        const state = get_state();
        const selw = get_selected_words(state);
        const subs_chunks = get_subs_chunks(state);
        dispatch({
            type: 'send_subs',
            words: selw,
            subs_chunks,
        });
        const timespan = get_edit_window_timespan(state);
        dispatch({
            type: 'force_current_time',
            current_time: timespan.end,
        });
        axios.request({
            url: endpoint,
            method: 'POST',
            params: {
                filestem: props.stem,
                start: timespan.start,
                end:   timespan.end,
                trans: form_values.edited_subtitles,
                author: state.form.username.values.username,
                session: localStorage.getItem('session'),
            },
        }).then(res => {
            if (res.data && res.data.success) {
                dispatch({
                    type: 'accepted_submission',
                    replaced_words: selw,
                    accepted_words: res.data.data,
                });
            }
            else {
                dispatch({
                    type: 'failed_submission',
                    words: selw,
                    subs_chunks,
                });
            }
        })
        .catch(() => {
            dispatch({
                type: 'submission_error',
                words: selw,
            });
        });
    };
};
<|endoftext|>


<commit_before>"use strict";

module.exports = {
    // location of Sqlite DB file
    Cache: `${process.cwd()}/themeparks.db`,
    // default time to cache any data
    DefaultCacheLength: 60 * 60 * 6, // 6 hours
    // default request timeout values
    OpenTimeout: 10000, // 10 seconds; timeout in milliseconds
    ReadTimeout: 0, // 0 seconds; timeout in milliseconds
    // cache settings (in seconds)
    CacheWaitTimesLength: 60 * 5, // 5 minutes
    CacheOpeningTimesLength: 60 * 60, // 1 hour
};<commit_msg>[!] Build a basic util.promisify shim for NodeJS 6<commit_after>"use strict";

// shim promisify into older NodeJS versions (6)
const util = require("util");
if (util.promisify === undefined) {
    Object.defineProperty(util, "promisify", {
        configurable: true,
        enumerable: true,
        value: (func) => (...args) => new Promise((resolve, reject) => func(...args, (err, res) => err ? reject(err) : resolve(res))),
        writable: true
    });
}

module.exports = {
    // location of Sqlite DB file
    Cache: `${process.cwd()}/themeparks.db`,
    // default time to cache any data
    DefaultCacheLength: 60 * 60 * 6, // 6 hours
    // default request timeout values
    OpenTimeout: 10000, // 10 seconds; timeout in milliseconds
    ReadTimeout: 0, // 0 seconds; timeout in milliseconds
    // cache settings (in seconds)
    CacheWaitTimesLength: 60 * 5, // 5 minutes
    CacheOpeningTimesLength: 60 * 60, // 1 hour
};<|endoftext|>


<commit_before>import React from 'react'
import Input from './input'

export default class CheckboxList extends Input {
  onChange(value) {
    this.setState({ value: [value] })
    this.onUpdate([value])
  }

  render() {
    return (

        {this.props.property.options.map((option) => {
          let checked = false

          for (let item in this.state.value || []) {
            if (item.value === option.value) {
              checked = true
            }
          }

          return (

              <input
                checked={checked}
                onChange={(e) => this.onChange([option.value])}
                name={this.props.property.id}
                type='checkbox'
                value={option.value} />
              {option.title}

          )
        })}

    )
  }
}
<commit_msg>Add support for updating checkbox list values.<commit_after>import React from 'react'
import Input from './input'

function isChecked(values, option) {
  for (let value of values || []) {
    if (option.value === value) {
      return true
    }
  }
}

export default class CheckboxList extends Input {
  onChange(e, value) {
    let values = [...this.state.value || []]

    if (e.target.checked) {
      values.push(value)
    }
    else {
      values.splice(values.indexOf(value), 1)
    }

    if (!values.length) {
      values = null
    }

    this.setState({ value: values })
    this.onUpdate(values)
  }

  render() {
    return (

        {this.props.property.options.map((option) => {
          return (

              <input
                checked={isChecked(this.state.value, option)}
                onChange={(e) => this.onChange(e, option.value)}
                name={this.props.property.id}
                type='checkbox'
                value={option.value} />
              {option.title}

          )
        })}

    )
  }
}
<|endoftext|>


<commit_before>/**
 * Expose `Resource`.
 */

module.exports = require('./resource');

/**
 * Sourcery version.
 */

module.exports.version = require('../package.json').version;

/**
 * Expose `BasicAuth`.
 */

module.exports.BasicAuth = require('./basic-auth');

/**
 * Expose `Response`
 */

module.exports.Response = require('./response');

/**
 * Expose `RequestBuilder`
 */

module.exports.RequestBuilder = require('./request-builder');
<commit_msg>Coding style<commit_after>/**
 * Exports.
 */

module.exports = require('./resource');
module.exports.version = require('../package.json').version;
module.exports.BasicAuth = require('./basic-auth');
module.exports.Response = require('./response');
module.exports.RequestBuilder = require('./request-builder');
<|endoftext|>


<commit_before>/*
Copyright 2016 OpenMarket Ltd

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

'use strict';

var React = require('react');

var sdk = require('../../../index');
var MatrixClientPeg = require('../../../MatrixClientPeg');
var ImageUtils = require('../../../ImageUtils');
var Modal = require('../../../Modal');

var linkify = require('linkifyjs');
var linkifyElement = require('linkifyjs/element');
var linkifyMatrix = require('../../../linkify-matrix');
linkifyMatrix(linkify);

module.exports = React.createClass({
    displayName: 'LinkPreviewWidget',

    propTypes: {
        link: React.PropTypes.string.isRequired, // the URL being previewed
        mxEvent: React.PropTypes.object.isRequired, // the Event associated with the preview
        onCancelClick: React.PropTypes.func, // called when the preview's cancel ('hide') button is clicked
        onWidgetLoad: React.PropTypes.func, // called when the preview's contents has loaded
    },

    getInitialState: function() {
        return {
            preview: null
        };
    },

    componentWillMount: function() {
        this.unmounted = false;
        MatrixClientPeg.get().getUrlPreview(this.props.link, this.props.mxEvent.getTs()).then((res)=>{
            if (this.unmounted) {
                return;
            }
            this.setState(
                { preview: res },
                this.props.onWidgetLoad
            );
        }, (error)=>{
            console.error("Failed to get preview for " + this.props.link + " " + error);
        }).done();
    },

    componentDidMount: function() {
        if (this.refs.description)
            linkifyElement(this.refs.description, linkifyMatrix.options);
    },

    componentDidUpdate: function() {
        if (this.refs.description)
            linkifyElement(this.refs.description, linkifyMatrix.options);
    },

    componentWillUnmount: function() {
        this.unmounted = true;
    },

    onImageClick: function(ev) {
        var p = this.state.preview;
        if (ev.button != 0 || ev.metaKey) return;
        ev.preventDefault();
        var ImageView = sdk.getComponent("elements.ImageView");

        var src = p["og:image"];
        if (src && src.startsWith("mxc://")) {
            src = MatrixClientPeg.get().mxcUrlToHttp(src);
        }

        var params = {
            src: src,
            width: p["og:image:width"],
            height: p["og:image:height"],
            name: p["og:title"] || p["og:description"] || this.props.link,
            fileSize: p["matrix:image:size"],
            link: this.props.link,
        };

        Modal.createDialog(ImageView, params, "mx_Dialog_lightbox");
    },

    render: function() {
        var p = this.state.preview;
        if (!p) return
;

        // FIXME: do we want to factor out all image displaying between this and MImageBody - especially for lightboxing?
        var image = p["og:image"];
        var imageMaxWidth = 100, imageMaxHeight = 100;
        if (image && image.startsWith("mxc://")) {
            image = MatrixClientPeg.get().mxcUrlToHttp(image, imageMaxWidth, imageMaxHeight);
        }

        var thumbHeight = imageMaxHeight;
        if (p["og:image:width"] && p["og:image:height"]) {
            thumbHeight = ImageUtils.thumbHeight(p["og:image:width"], p["og:image:height"], imageMaxWidth, imageMaxHeight);
        }

        var img;
        if (image) {
            img =

        }

        return (

                { img }

{ p["og:title"] }

{ p["og:site_name"] ? (" - " + p["og:site_name"]) : null }

                        { p["og:description"] }

        );
    }
});
<commit_msg>amends react template and removes opening image in lightbox<commit_after>/*
Copyright 2016 OpenMarket Ltd

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

'use strict';

var React = require('react');

var sdk = require('../../../index');
var MatrixClientPeg = require('../../../MatrixClientPeg');
var ImageUtils = require('../../../ImageUtils');
var Modal = require('../../../Modal');

var linkify = require('linkifyjs');
var linkifyElement = require('linkifyjs/element');
var linkifyMatrix = require('../../../linkify-matrix');
linkifyMatrix(linkify);

module.exports = React.createClass({
    displayName: 'LinkPreviewWidget',

    propTypes: {
        link: React.PropTypes.string.isRequired, // the URL being previewed
        mxEvent: React.PropTypes.object.isRequired, // the Event associated with the preview
        onCancelClick: React.PropTypes.func, // called when the preview's cancel ('hide') button is clicked
        onWidgetLoad: React.PropTypes.func, // called when the preview's contents has loaded
    },

    getInitialState: function() {
        return {
            preview: null
        };
    },

    componentWillMount: function() {
        this.unmounted = false;
        MatrixClientPeg.get().getUrlPreview(this.props.link, this.props.mxEvent.getTs()).then((res)=>{
            if (this.unmounted) {
                return;
            }
            this.setState(
                { preview: res },
                this.props.onWidgetLoad
            );
        }, (error)=>{
            console.error("Failed to get preview for " + this.props.link + " " + error);
        }).done();
    },

    componentDidMount: function() {
        if (this.refs.description)
            linkifyElement(this.refs.description, linkifyMatrix.options);
    },

    componentDidUpdate: function() {
        if (this.refs.description)
            linkifyElement(this.refs.description, linkifyMatrix.options);
    },

    componentWillUnmount: function() {
        this.unmounted = true;
    },

    render: function() {
        var p = this.state.preview;
        if (!p) return
;

        // FIXME: do we want to factor out all image displaying between this and MImageBody - especially for lightboxing?
        var image = p["og:image"];
        var imageMaxWidth = 600, imageMaxHeight = 400;
        if (image && image.startsWith("mxc://")) {
            image = MatrixClientPeg.get().mxcUrlToHttp(image, imageMaxWidth, imageMaxHeight);
        }

        var thumbHeight = imageMaxHeight;
        if (p["og:image:width"] && p["og:image:height"]) {
            thumbHeight = ImageUtils.thumbHeight(p["og:image:width"], p["og:image:height"], imageMaxWidth, imageMaxHeight);
        }

        var img;
        if (image) {
            img = (

            );
        }

        return (

{ p["og:title"] }

{ p["og:site_name"] ? ("from " + p["og:site_name"]) : null }

                { img }

{ p["og:description"] } Read more

        );
    }
});
<|endoftext|>


<commit_before>'use strict'

const axios = require('axios')
const pkg = require('../package.json')

const bindResources = require('./helpers/bindResources')

class SparkPay {
  constructor (conf) {
    if (!conf) {
      throw new Error('Missing SparkPay configuration!')
    } else if (!conf.domain || !conf.token) {
      throw new Error('SparkPay configuration requires both domain and token.')
    }

    this.dispatch = axios.create({
      baseURL: 'https://' + conf.domain + '/api/v1',
      headers: {
        'X-AC-Auth-Token': conf.token,
        'User-Agent': 'sparkpay-node/' + pkg.version
      }
    })

    this.dispatch.interceptors.response.use(null, err => {
      if (err.status === 429) return this.retry(err)

      throw err
    })

    bindResources(this, this.dispatch)
  }

  retry (req) {
    return new Promise((resolve, reject) => {
      let retryTimeout = 0

      if (req.headers['retry-after']) {
        retryTimeout = new Date(req.headers['retry-after']) - Date.now()
      }

      setTimeout(() => {
        this.dispatch.request(req.config).then(resolve).catch(reject)
      }, retryTimeout)
    })
  }

  static init (conf) {
    return new SparkPay(conf)
  }
}

module.exports = SparkPay
<commit_msg>no to magic numbers<commit_after>'use strict'

const TOO_MANY_REQUESTS = 429

const axios = require('axios')
const pkg = require('../package.json')

const bindResources = require('./helpers/bindResources')

class SparkPay {
  constructor (conf) {
    if (!conf) {
      throw new Error('Missing SparkPay configuration!')
    } else if (!conf.domain || !conf.token) {
      throw new Error('SparkPay configuration requires both domain and token.')
    }

    this.dispatch = axios.create({
      baseURL: 'https://' + conf.domain + '/api/v1',
      headers: {
        'X-AC-Auth-Token': conf.token,
        'User-Agent': 'sparkpay-node/' + pkg.version
      }
    })

    this.dispatch.interceptors.response.use(null, err => {
      if (err.status === TOO_MANY_REQUESTS) return this.retry(err)

      throw err
    })

    bindResources(this, this.dispatch)
  }

  retry (req) {
    return new Promise((resolve, reject) => {
      let retryTimeout = 0

      if (req.headers['retry-after']) {
        retryTimeout = new Date(req.headers['retry-after']) - Date.now()
      }

      setTimeout(() => {
        this.dispatch.request(req.config).then(resolve).catch(reject)
      }, retryTimeout)
    })
  }

  static init (conf) {
    return new SparkPay(conf)
  }
}

module.exports = SparkPay
<|endoftext|>


<commit_before>/**
 * @chill- All is silent, lucid, and self-illumination: There is no exertion, no waste of energy- This is where thinking never attains.
 * This is where the imagination fails to measure. - Seng-t'san
 *
 * @file- Onboarding.js
 * @description- This file is the Onboarding page. This is what shown to user first time.
 * @author- heartIT pirates were here
 */

"use strict";

import React, { Component } from "react";
import { connect } from "react-redux";
import { Image } from "react-native";
import { StyleProvider, Content, View, Button, Text } from "native-base";
import Swiper from "react-native-swiper";

import * as actionCreators from "../../badlee__redux/action_creators";
import getTheme from "../../theme/components";
import Icon from "../../components/Icon";
import Login from "./Login";

class BackgroundImage extends Component {
  render() {
    let image = require("../../images/welcome__bg.png");
    return (
      <Image source={image} style={styles.backgroundImage}>
        {this.props.children}
      </Image>
    );
  }
}

class Onboarding extends Component {
  handleLogin() {
    requestAnimationFrame(() => {
      this.props.navigate({
        navigator: this.props.navigator,
        component: Login
      });
    });
  }

  render() {
    return (
      <StyleProvider style={getTheme()}>
        <Content style={{ flex: 1 }} contentContainerStyle={{ flex: 1 }}>
          <BackgroundImage>
            <View style={styles.container}>
              <Swiper
                loop={false}
                showsButtons={false}
                dot={
                  <View
                    style={{ ...styles.swiperDots, ...styles.inactiveDot }}
                  />
                }
                activeDot={
                  <View style={{ ...styles.swiperDots, ...styles.activeDot }} />
                }
              >
                <View style={styles.view}>
                  <Text style={{ ...styles.head, ...styles.badleeColor }}>
                    Badlee?
                  </Text>
                  <Image
                    source={require("../../images/badlee.png")}
                    style={styles.image}
                  />
                  <View>
                    <Text style={styles.content}>
                      An exclusive social network for your commodity needs.
                    </Text>
                    <Text style={styles.content}>
                      See what you have, see what they got.
                    </Text>
                    <Text style={styles.content}>
                      It's your personal bank of things, where Borrowing and
                      Lending of commodities are done.
                    </Text>
                  </View>
                </View>
                <View style={styles.view}>
                  <Text style={{ ...styles.head, ...styles.lendBorrowColor }}>
                    lend and borrow
                  </Text>
                  <Icon
                    name="exchange"
                    viewBox="0 0 60 60"
                    style={styles.image}
                    width="135"
                    height="135"
                  />
                  <View>
                    <Text style={styles.content}>
                      Post under this badge anything that you're willing to lend
                      to anyone in your community.
                    </Text>
                    <Text style={styles.content}>
                      You can also borrow anything posted by another user under
                      this badge.
                    </Text>
                    <Text style={styles.content}>
                      The true essence of Badlee, it is
                    </Text>
                  </View>
                </View>
                <View style={styles.view}>
                  <Text style={{ ...styles.head, ...styles.showoffColor }}>
                    show off
                  </Text>
                  <Image
                    source={require("../../images/show off 2.png")}
                    style={styles.image}
                  />
                  <View>
                    <Text style={styles.content}>
                      Got something 'premium'? Here's Badlee giving you an
                      exclusive platform to show your premium possession off.
                    </Text>
                    <Text style={styles.content}>
                      Got Something? Brag about it!
                    </Text>
                  </View>
                </View>
                <View style={styles.view}>
                  <Text style={{ ...styles.head, ...styles.shoutColor }}>
                    shout
                  </Text>
                  <Icon
                    name="shoutout"
                    viewBox="0 0 60 60"
                    width="135"
                    height="135"
                    style={styles.image}
                  />
                  <View>
                    <Text style={styles.content}>
                      What if you don't get something you are looking for in the
                      feeds on your homescreen?
                    </Text>
                    <Text style={styles.content}>
                      Yes! You can post your demands under this badge, so that
                      someone who sees your post can offer you what you want.
                    </Text>
                  </View>
                </View>
                <View style={styles.view}>
                  <Text style={{ ...styles.head, ...styles.expressionColor }}>
                    expressions
                  </Text>
                  <View>
                    <Text style={{ ...styles.semihead, ...styles.likeColor }}>
                      like
                    </Text>
                    <Icon
                      name="like"
                      viewBox="0 0 800 800"
                      width="135"
                      height="135"
                      style={styles.image}
                    />
                    <Text
                      style={{
                        ...styles.semihead,
                        ...styles.wishColor,
                        ...styles.likeBorder
                      }}
                    >
                      wish
                    </Text>
                    <Icon
                      name="wish"
                      viewBox="0 0 800 800"
                      width="135"
                      height="135"
                      fill="#EF5454"
                      style={styles.image}
                    />
                    <Button
                      style={{
                        position: "absolute",
                        bottom: -30,
                        right: -24,
                        backgroundColor: "#611265",
                        borderRadius: 12
                      }}
                      onPress={this.handleLogin.bind(this)}
                    >
                      <Text style={{ color: "#FFF" }}>Proceed</Text>
                    </Button>
                  </View>
                </View>
              </Swiper>
            </View>
          </BackgroundImage>
        </Content>
      </StyleProvider>
    );
  }
}

const styles = {
  backgroundImage: {
    display: "flex",
    flex: 1,
    width: null,
    height: null,
    resizeMode: "stretch"
  },
  container: {
    flex: 1,
    justifyContent: "center",
    display: "flex"
  },
  swiperDots: {
    width: 5,
    height: 5,
    borderRadius: 4,
    marginLeft: 3,
    marginRight: 3,
    marginTop: 3,
    marginBottom: 12
  },
  inactiveDot: {
    backgroundColor: "#a763a7"
  },
  activeDot: {
    backgroundColor: "#93298f",
    width: 8,
    height: 8
  },
  view: {
    flex: 1,
    paddingLeft: 42,
    paddingRight: 42,
    paddingTop: 60
  },
  head: {
    textAlign: "center",
    fontSize: 33,
    marginBottom: 30,
    marginTop: 6,
    fontFamily: "Righteous-Regular"
  },
  semihead: {
    textAlign: "center",
    fontSize: 27,
    marginBottom: 0,
    fontFamily: "Righteous-Regular"
  },
  image: {
    width: 135,
    height: 135,
    marginLeft: "auto",
    marginRight: "auto",
    marginBottom: 24
  },
  content: {
    fontSize: 18,
    color: "rgba(0, 0, 0, 0.87)",
    textShadowColor: "rgba(0, 0, 0, 0.23)",
    textShadowOffset: { width: 1, height: 0 },
    fontFamily: "PoiretOne-Regular",
    textAlign: "center",
    lineHeight: 21,
    marginBottom: 9
  },
  badleeColor: {
    color: "#611265"
  },
  lendBorrowColor: {
    color: "#94c655"
  },
  showoffColor: {
    color: "#f3e309"
  },
  shoutColor: {
    color: "#428ee2"
  },
  expressionColor: {
    color: "#6d156c"
  },
  likeColor: {
    color: "#c876e4"
  },
  wishColor: {
    color: "#ee5253"
  },
  likeBorder: {
    borderTopWidth: 2,
    borderColor: "#6d156c"
  }
};

const _Wrapped = connect(
  state => ({ loading: state.getIn(["application", "isLoading"]) }),
  actionCreators
)(Onboarding);

export default _Wrapped;
<commit_msg>fixed typo<commit_after>/**
 * @chill- All is silent, lucid, and self-illumination: There is no exertion, no waste of energy- This is where thinking never attains.
 * This is where the imagination fails to measure. - Seng-t'san
 *
 * @file- Onboarding.js
 * @description- This file is the Onboarding page. This is what shown to user first time.
 * @author- heartIT pirates were here
 */

"use strict";

import React, { Component } from "react";
import { connect } from "react-redux";
import { Image } from "react-native";
import { StyleProvider, Content, View, Button, Text } from "native-base";
import Swiper from "react-native-swiper";

import * as actionCreators from "../../badlee__redux/action_creators";
import getTheme from "../../theme/components";
import Icon from "../../components/Icon";
import Login from "./Login";

class BackgroundImage extends Component {
  render() {
    let image = require("../../images/welcome__bg.png");
    return (
      <Image source={image} style={styles.backgroundImage}>
        {this.props.children}
      </Image>
    );
  }
}

class Onboarding extends Component {
  handleLogin() {
    requestAnimationFrame(() => {
      this.props.navigate({
        navigator: this.props.navigator,
        component: Login
      });
    });
  }

  render() {
    return (
      <StyleProvider style={getTheme()}>
        <Content style={{ flex: 1 }} contentContainerStyle={{ flex: 1 }}>
          <BackgroundImage>
            <View style={styles.container}>
              <Swiper
                loop={false}
                showsButtons={false}
                dot={
                  <View
                    style={{ ...styles.swiperDots, ...styles.inactiveDot }}
                  />
                }
                activeDot={
                  <View style={{ ...styles.swiperDots, ...styles.activeDot }} />
                }
              >
                <View style={styles.view}>
                  <Text style={{ ...styles.head, ...styles.badleeColor }}>
                    Badlee?
                  </Text>
                  <Image
                    source={require("../../images/badlee.png")}
                    style={styles.image}
                  />
                  <View>
                    <Text style={styles.content}>
                      An exclusive social network for your commodity needs.
                    </Text>
                    <Text style={styles.content}>
                      See what you have, see what they got.
                    </Text>
                    <Text style={styles.content}>
                      It's your personal bank of things, where Borrowing and
                      Lending of commodities are done.
                    </Text>
                  </View>
                </View>
                <View style={styles.view}>
                  <Text style={{ ...styles.head, ...styles.lendBorrowColor }}>
                    lend and borrow
                  </Text>
                  <Icon
                    name="exchange"
                    viewBox="0 0 60 60"
                    style={styles.image}
                    width="135"
                    height="135"
                  />
                  <View>
                    <Text style={styles.content}>
                      Post under this badge anything that you're willing to lend
                      to anyone in your community.
                    </Text>
                    <Text style={styles.content}>
                      You can also borrow anything posted by another user under
                      this badge.
                    </Text>
                    <Text style={styles.content}>
                      The true essence of Badlee, it is
                    </Text>
                  </View>
                </View>
                <View style={styles.view}>
                  <Text style={{ ...styles.head, ...styles.showoffColor }}>
                    show off
                  </Text>
                  <Image
                    source={require("../../images/show off 2.png")}
                    style={styles.image}
                  />
                  <View>
                    <Text style={styles.content}>
                      Got something 'premium'? Here's Badlee giving you an
                      exclusive platform to show your premium possessions off.
                    </Text>
                    <Text style={styles.content}>
                      Got Something? Brag about it!
                    </Text>
                  </View>
                </View>
                <View style={styles.view}>
                  <Text style={{ ...styles.head, ...styles.shoutColor }}>
                    shout
                  </Text>
                  <Icon
                    name="shoutout"
                    viewBox="0 0 60 60"
                    width="135"
                    height="135"
                    style={styles.image}
                  />
                  <View>
                    <Text style={styles.content}>
                      What if you don't get something you are looking for in the
                      feeds on your homescreen?
                    </Text>
                    <Text style={styles.content}>
                      Yes! You can post your demands under this badge, so that
                      someone who sees your post can offer you what you want.
                    </Text>
                  </View>
                </View>
                <View style={styles.view}>
                  <Text style={{ ...styles.head, ...styles.expressionColor }}>
                    expressions
                  </Text>
                  <View>
                    <Text style={{ ...styles.semihead, ...styles.likeColor }}>
                      like
                    </Text>
                    <Icon
                      name="like"
                      viewBox="0 0 800 800"
                      width="135"
                      height="135"
                      style={styles.image}
                    />
                    <Text
                      style={{
                        ...styles.semihead,
                        ...styles.wishColor,
                        ...styles.likeBorder
                      }}
                    >
                      wish
                    </Text>
                    <Icon
                      name="wish"
                      viewBox="0 0 800 800"
                      width="135"
                      height="135"
                      fill="#EF5454"
                      style={styles.image}
                    />
                    <Button
                      style={{
                        position: "absolute",
                        bottom: -30,
                        right: -24,
                        backgroundColor: "#611265",
                        borderRadius: 12
                      }}
                      onPress={this.handleLogin.bind(this)}
                    >
                      <Text style={{ color: "#FFF" }}>Proceed</Text>
                    </Button>
                  </View>
                </View>
              </Swiper>
            </View>
          </BackgroundImage>
        </Content>
      </StyleProvider>
    );
  }
}

const styles = {
  backgroundImage: {
    display: "flex",
    flex: 1,
    width: null,
    height: null,
    resizeMode: "stretch"
  },
  container: {
    flex: 1,
    justifyContent: "center",
    display: "flex"
  },
  swiperDots: {
    width: 5,
    height: 5,
    borderRadius: 4,
    marginLeft: 3,
    marginRight: 3,
    marginTop: 3,
    marginBottom: 12
  },
  inactiveDot: {
    backgroundColor: "#a763a7"
  },
  activeDot: {
    backgroundColor: "#93298f",
    width: 8,
    height: 8
  },
  view: {
    flex: 1,
    paddingLeft: 42,
    paddingRight: 42,
    paddingTop: 60
  },
  head: {
    textAlign: "center",
    fontSize: 33,
    marginBottom: 30,
    marginTop: 6,
    fontFamily: "Righteous-Regular"
  },
  semihead: {
    textAlign: "center",
    fontSize: 27,
    marginBottom: 0,
    fontFamily: "Righteous-Regular"
  },
  image: {
    width: 135,
    height: 135,
    marginLeft: "auto",
    marginRight: "auto",
    marginBottom: 24
  },
  content: {
    fontSize: 18,
    color: "rgba(0, 0, 0, 0.87)",
    textShadowColor: "rgba(0, 0, 0, 0.23)",
    textShadowOffset: { width: 1, height: 0 },
    fontFamily: "PoiretOne-Regular",
    textAlign: "center",
    lineHeight: 21,
    marginBottom: 9
  },
  badleeColor: {
    color: "#611265"
  },
  lendBorrowColor: {
    color: "#94c655"
  },
  showoffColor: {
    color: "#f3e309"
  },
  shoutColor: {
    color: "#428ee2"
  },
  expressionColor: {
    color: "#6d156c"
  },
  likeColor: {
    color: "#c876e4"
  },
  wishColor: {
    color: "#ee5253"
  },
  likeBorder: {
    borderTopWidth: 2,
    borderColor: "#6d156c"
  }
};

const _Wrapped = connect(
  state => ({ loading: state.getIn(["application", "isLoading"]) }),
  actionCreators
)(Onboarding);

export default _Wrapped;
<|endoftext|>


<commit_before>'use strict';

const path = require('path');
const {EventEmitter} = require('events');
const util = require('util');
const assert = require('assert');
const {exec, spawn} = require('child_process');

const tryCatch = require('try-catch');
const tildify = require('tildify');
const untildify = require('untildify');

const WIN = process.platform === 'win32';

const find = require('glob');
const win = require('win32');

const newLine = (error) => {
    error.message += '\n';
    return error;
};

util.inherits(Spawnify, EventEmitter);
win.prepareCodePage();

module.exports = (command, options) => {
    options = options || {};

    assert(command, 'command could not be empty!');

    const isCWD = options.cwd;
    const cwd = isCWD ? untildify(options.cwd) : process.cwd();

    return new Spawnify(command, {
        ...options,
        cwd,
    });
};

function Spawnify(command, options) {
    EventEmitter.call(this);

    process.nextTick(() => {
        this._onMessage(command, options);
    });
}

Spawnify.prototype._onMessage = function onMessage(command, options) {
    const dir = options.cwd;
    const isVolume = win.isChangeVolume(command);

    const regExpCD = /^cd ?/;
    const regExpCDWin = /^cd ?/i;

    const isCD = regExpCD.test(command);
    const isCDWin = regExpCDWin.test(command);

    const symbolsExec = [
        '~', '>', '<', '#',
        '*', '&', '{', '}',
        '|', '\'', '"', ';',
        '`', '$',
    ];

    const isSymbol = isContain(command, symbolsExec);

    assert(command, 'command could not be empty!');
    assert(command, 'options could not be empty!');

    if (isCD || isCDWin && WIN || isVolume) {
        command = command
            .replace(WIN ? regExpCDWin : regExpCD, '');

        this._onCD(command || '~', dir);
    } else {
        if (WIN)
            command = 'cmd /C ' + command;

        const [firstChar] = command;

        if (firstChar === ' ' || isSymbol)
            this._set('exec', command, options);
        else
            this._set('spawn', command, options);
    }
};

Spawnify.prototype._emit = function emit(event, data) {
    const count = (event) => {
        const listeners = this.listeners(event);

        return listeners.length;
    };

    assert(event, 'event could not be empty!');

    if (count(event) || event === 'error') {
        this.emit(event, data);

        /*
         * when code is EACESS
         * close and exit events
         * whould not be emitted
         */
        if (event === 'error' && data.code === 'EACCES') {
            if (count('close'))
                this.emit('close');

            if (count('exit'))
                this.emit('exit');
        }
    }
};

Spawnify.prototype._set = function set(type, command, options) {
    let args;
    let error;
    let child;
    let result;

    assert(type, 'event could not be empty!');
    assert(command, 'command could not be empty!');
    assert(options, 'options could not be empty!');

    options.encoding = 'buffer';

    switch(type) {
    default:
        throw Error('type could be exec or spawn only!');

    case 'exec':
        result = tryCatch(exec, command, options);
        [error, child] = result;
        break;

    case 'spawn':
        args = command.split(' ');
        command = args.shift();

        result = tryCatch(spawn, command, args, options);

        [error, child] = result;
        break;
    }

    if (error) {
        if (error.code === 'ENOTDIR')
            error.message += ': ' + options.cwd;

        this._emit('error', newLine(error));
        this._emit('close');
        this._emit('exit');
    } else {
        /*
         * would be null
         * when options.stdio: 'inherit' used
         */
        this._setListeners(child);

        this.on('kill', (code) => {
            child.kill(code);
        });

        this.on('write', (data) => {
            child.stdin.write(data);
        });

        this._emit('start');
    }
};

Spawnify.prototype.kill = function(code) {
    this._emit('kill', code);
};

Spawnify.prototype.write = function(data) {
    this._emit('write', data);
};

Spawnify.prototype._setListeners = function setListeners(child) {
    assert(child, 'child could not be empty!');

    /*
     * would be null
     * when options.stdio: 'inherit' used
     */
    if (child.stdin)
        child.stdin.on('error', (error) => {
            this._emit('error', newLine(error));
        });

    if (child.stdout) {
        child.stdout
            .pipe(win.unicodify())
            .setEncoding('utf8')
            .on('data', (data) => {
                this._emit('data', data);
            });

        child.stdout.on('error', (error) => {
            this._emit('error', newLine(error));
        });
    }

    if (child.stderr) {
        child.stderr.pipe(win.unicodify())
            .setEncoding('utf8')
            .on('data', (error) => {
                this._emit('error', Error(error));
            });

        child.stderr.on('error', (error) => {
            this._emit('error', newLine(error));
        });
    }

    child.on('error', (error) => {
        this._emit('error', newLine(error));
    });

    child.on('exit', () => {
        child = null;
        this._emit('exit');
    });

    child.on('close', () => {
        child = null;
        this._emit('close');
    });
};

Spawnify.prototype._onCD = function onCD(command, currDir) {
    let wasError;

    const CD = 'cd ';
    const isChangeVolume = win.isChangeVolume(command);
    const isVolume = win.isVolume(command);
    const regExpRoot = /^[/\\]/;

    this.on('error', () => {
        wasError = true;
    });

    this.on('close', () => {
        if (!wasError)
            this._emit('path', tildify(paramDir));
    });

    let paramDir = untildify(command);
    const isWildCard = isContain(paramDir, ['*', '?']);

    if (!paramDir && !WIN)
        paramDir = '.';

    if (!isChangeVolume || isVolume) {
        paramDir = this._getFirstWord(paramDir);
        paramDir = path.normalize(paramDir);

        const isRoot = regExpRoot.test(paramDir);

        const strs = [
            CD,
            paramDir,
            '\'' + paramDir + '\'',
            '"' + paramDir + '"',
        ];

        for (const str of strs) {
            command = command.replace(str, '');
        }

        if (!isRoot)
            paramDir = path.join(currDir, paramDir);

        if (isWildCard)
            command = CD + paramDir + ' ' + command;
        else
            command = CD + '"' + paramDir + '" ' + command;
    }

    if (!isWildCard)
        return this._set('exec', command, {cwd: paramDir});

    find(paramDir, (error, dirs) => {
        let cwd;

        if (!error)
            [cwd] = dirs;

        this._set('exec', command, {
            cwd,
        });
    });
};

Spawnify.prototype._getFirstWord = function getFirstWord(str) {
    const regStrEnd = getRegStrEnd();
    const regStr = '^(.*?)';
    const regStrQuotes = '^"(.*)"';
    const regExp = RegExp(regStr + regStrEnd);
    const regExpQuotes = RegExp(regStrQuotes + regStrEnd + '?');
    const is = typeof str === 'string';

    if (!is)
        return str;

    let result = str.match(regExpQuotes);

    if (result)
        return result[1] || str;

    result = str.match(regExp);
    return result?.[1] || str;
};

function getRegStrEnd() {
    const chars = ['s', ';', '&&', '\\', '|'];
    const escaped = chars
        .map((char) => {
            return '\\' + char;
        }).join('|');

    const regStr = '(' + escaped + ')';

    return regStr;
}

function isContain(str, symbols) {
    assert(str, 'str could not be empty!');
    assert(symbols, 'symbols could not be empty!');

    return symbols.some((symbol) => {
        return str.includes(symbol);
    });
}

<commit_msg>fix(spawnify) unicodify do not returns a function<commit_after>'use strict';

const path = require('path');
const {EventEmitter} = require('events');
const util = require('util');
const assert = require('assert');
const {exec, spawn} = require('child_process');

const tryCatch = require('try-catch');
const tildify = require('tildify');
const untildify = require('untildify');

const WIN = process.platform === 'win32';

const find = require('glob');
const win = require('win32');

const newLine = (error) => {
    error.message += '\n';
    return error;
};

util.inherits(Spawnify, EventEmitter);
win.prepareCodePage();

module.exports = (command, options) => {
    options = options || {};

    assert(command, 'command could not be empty!');

    const isCWD = options.cwd;
    const cwd = isCWD ? untildify(options.cwd) : process.cwd();

    return new Spawnify(command, {
        ...options,
        cwd,
    });
};

function Spawnify(command, options) {
    EventEmitter.call(this);

    process.nextTick(() => {
        this._onMessage(command, options);
    });
}

Spawnify.prototype._onMessage = function onMessage(command, options) {
    const dir = options.cwd;
    const isVolume = win.isChangeVolume(command);

    const regExpCD = /^cd ?/;
    const regExpCDWin = /^cd ?/i;

    const isCD = regExpCD.test(command);
    const isCDWin = regExpCDWin.test(command);

    const symbolsExec = [
        '~', '>', '<', '#',
        '*', '&', '{', '}',
        '|', '\'', '"', ';',
        '`', '$',
    ];

    const isSymbol = isContain(command, symbolsExec);

    assert(command, 'command could not be empty!');
    assert(command, 'options could not be empty!');

    if (isCD || isCDWin && WIN || isVolume) {
        command = command
            .replace(WIN ? regExpCDWin : regExpCD, '');

        this._onCD(command || '~', dir);
    } else {
        if (WIN)
            command = 'cmd /C ' + command;

        const [firstChar] = command;

        if (firstChar === ' ' || isSymbol)
            this._set('exec', command, options);
        else
            this._set('spawn', command, options);
    }
};

Spawnify.prototype._emit = function emit(event, data) {
    const count = (event) => {
        const listeners = this.listeners(event);

        return listeners.length;
    };

    assert(event, 'event could not be empty!');

    if (count(event) || event === 'error') {
        this.emit(event, data);

        /*
         * when code is EACESS
         * close and exit events
         * whould not be emitted
         */
        if (event === 'error' && data.code === 'EACCES') {
            if (count('close'))
                this.emit('close');

            if (count('exit'))
                this.emit('exit');
        }
    }
};

Spawnify.prototype._set = function set(type, command, options) {
    let args;
    let error;
    let child;
    let result;

    assert(type, 'event could not be empty!');
    assert(command, 'command could not be empty!');
    assert(options, 'options could not be empty!');

    options.encoding = 'buffer';

    switch(type) {
    default:
        throw Error('type could be exec or spawn only!');

    case 'exec':
        result = tryCatch(exec, command, options);
        [error, child] = result;
        break;

    case 'spawn':
        args = command.split(' ');
        command = args.shift();

        result = tryCatch(spawn, command, args, options);

        [error, child] = result;
        break;
    }

    if (error) {
        if (error.code === 'ENOTDIR')
            error.message += ': ' + options.cwd;

        this._emit('error', newLine(error));
        this._emit('close');
        this._emit('exit');
    } else {
        /*
         * would be null
         * when options.stdio: 'inherit' used
         */
        this._setListeners(child);

        this.on('kill', (code) => {
            child.kill(code);
        });

        this.on('write', (data) => {
            child.stdin.write(data);
        });

        this._emit('start');
    }
};

Spawnify.prototype.kill = function(code) {
    this._emit('kill', code);
};

Spawnify.prototype.write = function(data) {
    this._emit('write', data);
};

Spawnify.prototype._setListeners = function setListeners(child) {
    assert(child, 'child could not be empty!');

    /*
     * would be null
     * when options.stdio: 'inherit' used
     */
    if (child.stdin)
        child.stdin.on('error', (error) => {
            this._emit('error', newLine(error));
        });

    if (child.stdout) {
        child.stdout
            .pipe(win.unicodify)
            .setEncoding('utf8')
            .on('data', (data) => {
                this._emit('data', data);
            });

        child.stdout.on('error', (error) => {
            this._emit('error', newLine(error));
        });
    }

    if (child.stderr) {
        child.stderr.pipe(win.unicodify())
            .setEncoding('utf8')
            .on('data', (error) => {
                this._emit('error', Error(error));
            });

        child.stderr.on('error', (error) => {
            this._emit('error', newLine(error));
        });
    }

    child.on('error', (error) => {
        this._emit('error', newLine(error));
    });

    child.on('exit', () => {
        child = null;
        this._emit('exit');
    });

    child.on('close', () => {
        child = null;
        this._emit('close');
    });
};

Spawnify.prototype._onCD = function onCD(command, currDir) {
    let wasError;

    const CD = 'cd ';
    const isChangeVolume = win.isChangeVolume(command);
    const isVolume = win.isVolume(command);
    const regExpRoot = /^[/\\]/;

    this.on('error', () => {
        wasError = true;
    });

    this.on('close', () => {
        if (!wasError)
            this._emit('path', tildify(paramDir));
    });

    let paramDir = untildify(command);
    const isWildCard = isContain(paramDir, ['*', '?']);

    if (!paramDir && !WIN)
        paramDir = '.';

    if (!isChangeVolume || isVolume) {
        paramDir = this._getFirstWord(paramDir);
        paramDir = path.normalize(paramDir);

        const isRoot = regExpRoot.test(paramDir);

        const strs = [
            CD,
            paramDir,
            '\'' + paramDir + '\'',
            '"' + paramDir + '"',
        ];

        for (const str of strs) {
            command = command.replace(str, '');
        }

        if (!isRoot)
            paramDir = path.join(currDir, paramDir);

        if (isWildCard)
            command = CD + paramDir + ' ' + command;
        else
            command = CD + '"' + paramDir + '" ' + command;
    }

    if (!isWildCard)
        return this._set('exec', command, {cwd: paramDir});

    find(paramDir, (error, dirs) => {
        let cwd;

        if (!error)
            [cwd] = dirs;

        this._set('exec', command, {
            cwd,
        });
    });
};

Spawnify.prototype._getFirstWord = function getFirstWord(str) {
    const regStrEnd = getRegStrEnd();
    const regStr = '^(.*?)';
    const regStrQuotes = '^"(.*)"';
    const regExp = RegExp(regStr + regStrEnd);
    const regExpQuotes = RegExp(regStrQuotes + regStrEnd + '?');
    const is = typeof str === 'string';

    if (!is)
        return str;

    let result = str.match(regExpQuotes);

    if (result)
        return result[1] || str;

    result = str.match(regExp);
    return result?.[1] || str;
};

function getRegStrEnd() {
    const chars = ['s', ';', '&&', '\\', '|'];
    const escaped = chars
        .map((char) => {
            return '\\' + char;
        }).join('|');

    const regStr = '(' + escaped + ')';

    return regStr;
}

function isContain(str, symbols) {
    assert(str, 'str could not be empty!');
    assert(symbols, 'symbols could not be empty!');

    return symbols.some((symbol) => {
        return str.includes(symbol);
    });
}

<|endoftext|>


<commit_before>/*
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

'use strict';

var bunyan = require('bunyan');

var accumulator = function() {
  var so = '';
  var se = '';

  var stdout = function(str) {
    so += str;
  };
  var stderr = function(str) {
    se += str;
  };
  var output = function() {
    return so + se;
  };
  return {
    stdout: stdout,
    stderr: stderr,
    output: output
  };
};

module.exports = function(logger) {
  var executor = require('./executor')(logger);
  logger = logger || bunyan.createLogger({name: 'nscale-util'});

  var check = function(host, user, keyPath, out, cb) {
    var completed = false;
    var calledback = false;
    var cmd;
    var w = accumulator();

    if (keyPath) {
      cmd = 'ssh -i ' + keyPath + ' -o batchMode=yes -o StrictHostKeyChecking=no -T ' + user + '@' + host + ' true';
    }
    else {
      cmd = 'ssh -o batchMode=yes -o StrictHostKeyChecking=no -T ' + user + '@' + host + ' true';
    }
    logger.info('sshcheck: ' + cmd);
    var op = {cmd: cmd,
              host: host,
              user: user,
              keyPath: keyPath,
              loc: __dirname};

    // in some cases the ssh check will connect BUT there will be no close event on the socket, this can occurr
    // when the OS is configured to hold open ssh connections. Trap this condition here...
    setTimeout(function() {
      if (!completed) {
        calledback = true;
        cb(null, op);
      }
    }, 6000);

    executor.exec('live', op.cmd, op.loc, w, function() {
      completed = true;
      if (!calledback) {
        if (w.output().indexOf('Permission denied') !== -1 || w.output().indexOf('Authentication failure') !== -1) {
          logger.error('sshcheck ERROR: ' + w.output);
          cb(new Error('permission denied - possible ssh key or key password problem'));
        }
        else {
          cb(null, op);
        }
      }
    });
  };

  return {
    check: check
  };
};

<commit_msg>Do not error if the host key changed.<commit_after>/*
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

'use strict';

var bunyan = require('bunyan');

var accumulator = function() {
  var so = '';
  var se = '';

  var stdout = function(str) {
    so += str;
  };
  var stderr = function(str) {
    se += str;
  };
  var output = function() {
    return so + se;
  };
  return {
    stdout: stdout,
    stderr: stderr,
    output: output
  };
};

module.exports = function(logger) {
  var executor = require('./executor')(logger);
  logger = logger || bunyan.createLogger({name: 'nscale-util'});

  var check = function(host, user, keyPath, out, cb) {
    var completed = false;
    var calledback = false;
    var cmd;
    var w = accumulator();
    var opts = ' -o ConnectTimeout=5 -o UserKnownHostsFile=/dev/null -o batchMode=yes -o StrictHostKeyChecking=no -T ' + user + '@' + host + ' true';

    if (keyPath) {
      cmd = 'ssh -i ' + keyPath + opts;
    }
    else {
      cmd = 'ssh ' + opts;
    }
    logger.info('sshcheck: ' + cmd);
    var op = {cmd: cmd,
              host: host,
              user: user,
              keyPath: keyPath,
              loc: __dirname};

    // in some cases the ssh check will connect BUT there will be no close event on the socket, this can occurr
    // when the OS is configured to hold open ssh connections. Trap this condition here...
    setTimeout(function() {
      if (!completed) {
        calledback = true;
        cb(null, op);
      }
    }, 6000);

    executor.exec('live', op.cmd, op.loc, w, function() {
      completed = true;
      if (!calledback) {
        if (w.output().indexOf('Permission denied') !== -1 || w.output().indexOf('Authentication failure') !== -1) {
          logger.error('sshcheck ERROR: ' + w.output);
          cb(new Error('permission denied - possible ssh key or key password problem'));
        }
        else {
          cb(null, op);
        }
      }
    });
  };

  return {
    check: check
  };
};

<|endoftext|>