<commit_before>/**
 * stateless-session
 * Secure client stored session management middleware
 * Copyright 2016 Skevos Papamichail
 * Licensed under MIT license
 */

"use strict";

/**
 * Dependencies
 */
var crypto = require('crypto');
var cookieparser = require('cookie');
var compare = require('scmp');
var onheaders = require('on-headers');
var filter = require('object-filter');
var model = require('./session')

/**
 * Module exports a new StatelessSession instance
 */
module.exports = (function () {
	/**
	 * Constructor
	 */
	function StatelessSession() {
		StatelessSession.server_key = crypto.randomBytes(32);
		StatelessSession.options = {};
	}

	/**
	 * Middleware function
	 * @param options Object
	 * @returns {Function} Middleware
	 */
	StatelessSession.prototype.middleware = function(options) {
		options = options || {};
		StatelessSession.options.key = options.key || StatelessSession.server_key;
		StatelessSession.options.autostart = options.autostart || false;
		StatelessSession.options.c_options = options.c_options || {
			"path":"/"
		};
		StatelessSession.options.prefix = options.prefix || "s_d_";

		return function(req, res, next){
			//Parse cookies into an object
			var sobj = StatelessSession.parseCookies(req);

			//Create a new session instance and assign it to req.session
			req.session = new model.Session(sobj);

			//Autostart session if needed
			if(StatelessSession.options.autostart){
				req.session.start();
			}

			//Listener for headers in order to save the cookies
			onheaders(res, function(){
				StatelessSession.saveCookies(req,res);
			});

			//call next middleware in line
			next();
		}
	};

	/**
	 * Parses session related cookies ( if any ) from request
	 * @param req Request Object
	 * @returns {JSON} decrypted data
	 */
	StatelessSession.parseCookies = function(req){
		var token;
		var cookies = req.headers['cookie']
	   				? cookieparser.parse(req.headers['cookie'])
	   				: {};

	   	//Select only session related cookies
	   	cookies = filter(cookies,function(v,k){
	   		return k.indexOf(StatelessSession.options.prefix) === 0
	   	});;

	   	//if no cookies found return null
	   	StatelessSession.cookies_count = Object.keys(cookies).length;
	   	if(!StatelessSession.cookies_count){
	   		return null;
	   	}

	   	//merge cookies' values into a single token string
	   	for(var i in cookies){
	   		token = token ? token + cookies[i] : cookies[i];
	   	}

	   	//decrypt token and return the resulted object
	   	return StatelessSession.decrypt(token);
	}

	/**
	 * Writes session related cookies to response if needed
	 * @param req Request Object
	 * @param res Response Object
	 */
	StatelessSession.saveCookies = function(req, res) {
		var session_obj,
			token,
	   		token_length,
	   		cookies,
	   		delete_options,
	   		i = 0;

	    //load cookies and exclude the ones related to session
		cookies = res.getHeader('Set-Cookie') || [];
		cookies = cookies.filter(function(c){
			return c.indexOf(StatelessSession.options.prefix) !== 0;
		});

		//create session related cookies
		if(!!req.session && req.session.hasStarted()){
			//The session data that needs to be saved
			session_obj = req.session.exportObject() || {};

			//Create a new buffer with encrypted session data
			token = new Buffer(StatelessSession.encrypt(session_obj),'utf8');
			token_length = token.length;
			//break buffer into smaller pieces and push a new cookie for each piece
			for(i = 0; i < token_length; i+=3500){
				cookies.push(cookieparser.serialize(
					StatelessSession.options.prefix+((i/3500)+1),
					token.slice(i,(i+3500)>token_length?token_length:(i+3500)).toString('utf8'),
					StatelessSession.options.c_options
				));
			}
			i /= 3500;
		}

		//delete old and unused session cookies
		delete_options = JSON.parse(JSON.stringify(StatelessSession.options.c_options));
		delete_options.expires = new Date(1);
		while(i<StatelessSession.cookies_count){
			cookies.push(cookieparser.serialize(StatelessSession.options.prefix+(i+1),"",delete_options));
			i++;
		}

		//save cookies
		res.setHeader('Set-Cookie', cookies)

	};

	/**
	 * Encrypts an object
	 * @param session_obj Object to encrypt
	 * @returns {String} the resulted token
	 */
	StatelessSession.encrypt = function(session_obj){
		//serialize
		var original = JSON.stringify(session_obj);

		//initialization vector
		var vector = new Buffer(crypto.randomBytes(16));

		//new cipher
		var cipher = crypto.createCipheriv('aes256', StatelessSession.options.key, vector);

		//the encrypted text
		var encrypted = cipher.update(original,'utf8','base64') + cipher.final('base64');

		//a hash for the combination of encrypted text and initialization vector
		var hash = crypto.createHmac('sha256', StatelessSession.options.key).update(encrypted+vector.toString('base64')).digest('base64');

		//return token ecrypted.vector.hash
		return encrypted + "." + vector.toString('base64') + "." + hash;
	};

	/**
	 * Decrypts a token
	 * @param token string
	 * @returns {JSON} object
	 */
	StatelessSession.decrypt = function(token){
		var decipher;
		// split token and save each value (encrypted text,vector,hash)
		var t=token.split(".");
		var encrypted = t[0];
		var vector = new Buffer(t[1], 'base64');
		var hash = t[2];

		// calculate hash
		var new_hash = crypto.createHmac('sha256', StatelessSession.options.key).update(encrypted+t[1]).digest('base64');

		//check data integrity by comparing the two hash values
		if(!compare(hash,new_hash)){
			return null;
		}

		//new decipher
		decipher = crypto.createDecipheriv('aes256', StatelessSession.options.key, vector);

		//return the resulted object
		return JSON.parse(decipher.update(encrypted, 'base64', 'utf8') + decipher.final('utf8'));
	};

	//return StatelessSession instance
	return new StatelessSession;

}());
<commit_msg>alt cookie values merging<commit_after>/**
 * stateless-session
 * Secure client stored session management middleware
 * Copyright 2016 Skevos Papamichail
 * Licensed under MIT license
 */

"use strict";

/**
 * Dependencies
 */
var crypto = require('crypto');
var cookieparser = require('cookie');
var compare = require('scmp');
var onheaders = require('on-headers');
var filter = require('object-filter');
var model = require('./session')

/**
 * Module exports a new StatelessSession instance
 */
module.exports = (function () {
	/**
	 * Constructor
	 */
	function StatelessSession() {
		StatelessSession.server_key = crypto.randomBytes(32);
		StatelessSession.options = {};
	}

	/**
	 * Middleware function
	 * @param options Object
	 * @returns {Function} Middleware
	 */
	StatelessSession.prototype.middleware = function(options) {
		options = options || {};
		StatelessSession.options.key = options.key || StatelessSession.server_key;
		StatelessSession.options.autostart = options.autostart || false;
		StatelessSession.options.c_options = options.c_options || {
			"path":"/"
		};
		StatelessSession.options.prefix = options.prefix || "s_d_";

		return function(req, res, next){
			//Parse cookies into an object
			var sobj = StatelessSession.parseCookies(req);

			//Create a new session instance and assign it to req.session
			req.session = new model.Session(sobj);

			//Autostart session if needed
			if(StatelessSession.options.autostart){
				req.session.start();
			}

			//Listener for headers in order to save the cookies
			onheaders(res, function(){
				StatelessSession.saveCookies(req,res);
			});

			//call next middleware in line
			next();
		}
	};

	/**
	 * Parses session related cookies ( if any ) from request
	 * @param req Request Object
	 * @returns {JSON} decrypted data
	 */
	StatelessSession.parseCookies = function(req){
		var token;
		var cookies = req.headers['cookie']
	   				? cookieparser.parse(req.headers['cookie'])
	   				: {};

	   	//Select only session related cookies
	   	cookies = filter(cookies,function(v,k){
	   		return k.indexOf(StatelessSession.options.prefix) === 0
	   	});;

	   	//if no cookies found return null
	   	StatelessSession.cookies_count = Object.keys(cookies).length;
	   	if(!StatelessSession.cookies_count){
	   		return null;
	   	}

	   	//merge cookies' values into a single token string
	   	for(var i=1; i<=StatelessSession.cookies_count; i++){
	   		token = token ? token + cookies[StatelessSession.options.prefix+i] : cookies[StatelessSession.options.prefix+i];
	   	}

	   	//decrypt token and return the resulted object
	   	return StatelessSession.decrypt(token);
	}

	/**
	 * Writes session related cookies to response if needed
	 * @param req Request Object
	 * @param res Response Object
	 */
	StatelessSession.saveCookies = function(req, res) {
		var session_obj,
			token,
	   		token_length,
	   		cookies,
	   		delete_options,
	   		i = 0;

	    //load cookies and exclude the ones related to session
		cookies = res.getHeader('Set-Cookie') || [];
		cookies = cookies.filter(function(c){
			return c.indexOf(StatelessSession.options.prefix) !== 0;
		});

		//create session related cookies
		if(!!req.session && req.session.hasStarted()){
			//The session data that needs to be saved
			session_obj = req.session.exportObject() || {};

			//Create a new buffer with encrypted session data
			token = new Buffer(StatelessSession.encrypt(session_obj),'utf8');
			token_length = token.length;
			//break buffer into smaller pieces and push a new cookie for each piece
			for(i = 0; i < token_length; i+=3500){
				cookies.push(cookieparser.serialize(
					StatelessSession.options.prefix+((i/3500)+1),
					token.slice(i,(i+3500)>token_length?token_length:(i+3500)).toString('utf8'),
					StatelessSession.options.c_options
				));
			}
			i /= 3500;
		}

		//delete old and unused session cookies
		delete_options = JSON.parse(JSON.stringify(StatelessSession.options.c_options));
		delete_options.expires = new Date(1);
		while(i<StatelessSession.cookies_count){
			cookies.push(cookieparser.serialize(StatelessSession.options.prefix+(i+1),"",delete_options));
			i++;
		}

		//save cookies
		res.setHeader('Set-Cookie', cookies)

	};

	/**
	 * Encrypts an object
	 * @param session_obj Object to encrypt
	 * @returns {String} the resulted token
	 */
	StatelessSession.encrypt = function(session_obj){
		//serialize
		var original = JSON.stringify(session_obj);

		//initialization vector
		var vector = new Buffer(crypto.randomBytes(16));

		//new cipher
		var cipher = crypto.createCipheriv('aes256', StatelessSession.options.key, vector);

		//the encrypted text
		var encrypted = cipher.update(original,'utf8','base64') + cipher.final('base64');

		//a hash for the combination of encrypted text and initialization vector
		var hash = crypto.createHmac('sha256', StatelessSession.options.key).update(encrypted+vector.toString('base64')).digest('base64');

		//return token ecrypted.vector.hash
		return encrypted + "." + vector.toString('base64') + "." + hash;
	};

	/**
	 * Decrypts a token
	 * @param token string
	 * @returns {JSON} object
	 */
	StatelessSession.decrypt = function(token){
		var decipher;
		// split token and save each value (encrypted text,vector,hash)
		var t=token.split(".");
		var encrypted = t[0];
		var vector = new Buffer(t[1], 'base64');
		var hash = t[2];

		// calculate hash
		var new_hash = crypto.createHmac('sha256', StatelessSession.options.key).update(encrypted+t[1]).digest('base64');

		//check data integrity by comparing the two hash values
		if(!compare(hash,new_hash)){
			return null;
		}

		//new decipher
		decipher = crypto.createDecipheriv('aes256', StatelessSession.options.key, vector);

		//return the resulted object
		return JSON.parse(decipher.update(encrypted, 'base64', 'utf8') + decipher.final('utf8'));
	};

	//return StatelessSession instance
	return new StatelessSession;

}());
<|endoftext|>


<commit_before>var format = require('util').format
var Build = require('./build')().Build
var Binary = require('./build')().Binary

module.exports = {
  name: 'jxcore',
  distributionListing: 'https://raw.githubusercontent.com/ktrzeciaknubisa/jxcore-issues/master/index.json',
  distToBuild: function (release) {
    release.jxcore = release.jxcore.replace(/^Beta-/, '')
    var binaries = release.dist
    .map(normalizePlatform)
    .filter(supportedPlatforms)
    .reduce(expandDebianArm, [])

    var v8Build = Object.assign(Object.create(V8Build), {
      version: release.jxcore,
      url: release.source.tar.url,
      shasum: release.source.tar.sha256,
      binaries: binaries,
      npm: 'foo#bar'
    })
    var spiderMonkeyBuild = Object.assign(Object.create(SMBuild), {
      version: release.jxcore,
      url: release.source.tar.url,
      shasum: release.source.tar.sha256,
      binaries: binaries,
      npm: 'foo#bar'
    })

    return [ v8Build, spiderMonkeyBuild ]
  }
}

// private

var JxcoreBuild = Object.create(Build, {
  binaries: {
    get: function () {
      return this._binaries
    },
    set: function (binaries) {
      this._binaries = binaries.filter(engine(this.engine)).map(createBinary)
    }
  },
  install: {
    get: function () {
      return format('install_package %s "%s"\n', this.packageName, this.downloadUri)
    }
  },
  name: {
    get: function () {
      return 'jxcore+' + this.engine
    }
  },
  packageName: {
    get: function () {
      return format('jxcore-%s', this.version)
    }
  },
  preamble: {
    value: 'after_install_package() {\n  fix_jxcore_directory_structure\n}\n\n'
  },
  postamble: {
    get: function () {
      return format('install_package npm "%s" jxcore_npm\n', this.npm)
    }
  }
})

var V8Build = Object.create(JxcoreBuild, {
  engine: { value: 'v8' }
})

var SMBuild = Object.create(JxcoreBuild, {
  engine: { value: 'sm' },
  install: {
    get: function () {
      return format('install_package %s "%s" jxcore_spidermonkey standard\n', this.packageName, this.downloadUri)
    }
  }
})

function normalizePlatform (dist) {
  dist.platform = dist.platform.toLowerCase().replace(/\s/g, '')
  .replace(/osxintel/, 'darwin')
  .replace(/rh\/centos\/fedora/, 'redhat')
  .replace(/ubuntu\/mint/, 'ubuntu')

  dist.arch = (dist.arch || '').toLowerCase()
  .replace(/ia32/, 'x86')

  return dist
}

function supportedPlatforms (dist) {
  return dist.platform !== 'windows' && dist.platform !== 'android' && dist.platform !== 'ios'
}

function expandDebianArm (binaries, binary) {
  if (binary.platform === 'debian' && binary.arch === 'arm') {
    binaries.push(
      Object.assign(Object.create(binary), {arch: 'arm64'}),
      Object.assign(Object.create(binary), {arch: 'armv7l'})
    )
  } else {
    binaries.push(binary)
  }
  return binaries
}

function engine (engine) {
  return function (dist) { return dist.engine === engine }
}

function createBinary (dist) {
  return Object.assign(Object.create(Binary), {
    arch: dist.arch,
    os: dist.platform,
    shasum: dist.sha256,
    url: dist.url
  })
}
<commit_msg>Scrape npmjx per jxcore release<commit_after>var format = require('util').format
var Build = require('./build')().Build
var Binary = require('./build')().Binary

module.exports = {
  name: 'jxcore',
  distributionListing: 'https://raw.githubusercontent.com/ktrzeciaknubisa/jxcore-issues/master/index.json',
  distToBuild: function (release) {
    release.jxcore = release.jxcore.replace(/^Beta-/, '')
    var binaries = release.dist
    .map(normalizePlatform)
    .filter(supportedPlatforms)
    .reduce(expandDebianArm, [])

    var v8Build = Object.assign(Object.create(V8Build), {
      version: release.jxcore,
      url: release.source.tar.url,
      shasum: release.source.tar.sha256,
      binaries: binaries,
      npm: release.npmjx.url + '#' + release.npmjx.sha256
    })
    var spiderMonkeyBuild = Object.assign(Object.create(SMBuild), {
      version: release.jxcore,
      url: release.source.tar.url,
      shasum: release.source.tar.sha256,
      binaries: binaries,
      npm: release.npmjx.url + '#' + release.npmjx.sha256
    })

    return [ v8Build, spiderMonkeyBuild ]
  }
}

// private

var JxcoreBuild = Object.create(Build, {
  binaries: {
    get: function () {
      return this._binaries
    },
    set: function (binaries) {
      this._binaries = binaries.filter(engine(this.engine)).map(createBinary)
    }
  },
  install: {
    get: function () {
      return format('install_package %s "%s"\n', this.packageName, this.downloadUri)
    }
  },
  name: {
    get: function () {
      return 'jxcore+' + this.engine
    }
  },
  packageName: {
    get: function () {
      return format('jxcore-%s', this.version)
    }
  },
  preamble: {
    value: 'after_install_package() {\n  fix_jxcore_directory_structure\n}\n\n'
  },
  postamble: {
    get: function () {
      return format('install_package npm "%s" jxcore_npm\n', this.npm)
    }
  }
})

var V8Build = Object.create(JxcoreBuild, {
  engine: { value: 'v8' }
})

var SMBuild = Object.create(JxcoreBuild, {
  engine: { value: 'sm' },
  install: {
    get: function () {
      return format('install_package %s "%s" jxcore_spidermonkey standard\n', this.packageName, this.downloadUri)
    }
  }
})

function normalizePlatform (dist) {
  dist.platform = dist.platform.toLowerCase().replace(/\s/g, '')
  .replace(/osxintel/, 'darwin')
  .replace(/rh\/centos\/fedora/, 'redhat')
  .replace(/ubuntu\/mint/, 'ubuntu')

  dist.arch = (dist.arch || '').toLowerCase()
  .replace(/ia32/, 'x86')

  return dist
}

function supportedPlatforms (dist) {
  return dist.platform !== 'windows' && dist.platform !== 'android' && dist.platform !== 'ios'
}

function expandDebianArm (binaries, binary) {
  if (binary.platform === 'debian' && binary.arch === 'arm') {
    binaries.push(
      Object.assign(Object.create(binary), {arch: 'arm64'}),
      Object.assign(Object.create(binary), {arch: 'armv7l'})
    )
  } else {
    binaries.push(binary)
  }
  return binaries
}

function engine (engine) {
  return function (dist) { return dist.engine === engine }
}

function createBinary (dist) {
  return Object.assign(Object.create(Binary), {
    arch: dist.arch,
    os: dist.platform,
    shasum: dist.sha256,
    url: dist.url
  })
}
<|endoftext|>


<commit_before>'use strict';
var _ = require('lodash');
var Q = require('q');
var request = require('request');

/**
 * The exemplars are models of the BluePay paremeters we will
 * loop through to build API requests. The value of each member
 * is its required status.
 */
var exemplar = {
    customer: {
        name1: 'NAME1',
        name2: 'NAME2',
        company: 'COMPANY_NAME',
        addr1: 'ADDR1',
        addr2: 'ADDR2',
        city: 'CITY',
        state: 'STATE',
        zip: 'ZIPCODE',
        email: 'EMAIL',
        phone: 'PHONE',
        country: 'COUNTRY',
        remoteIp: 'REMOTE_IP'
    },

    card: {
        account: 'CC_NUM',
        cardExpire: 'CC_EXPIRES',
        cvv2: 'CVCCVV2'
    },

    ach: {
        accountType: 'ACH_ACCOUNT_TYPE',
        docType: 'DOC_TYPE',
        accountNum: 'ACH_ACCOUNT',
        routingNum: 'ACH_ROUTING'
    },

    tranction: {
        amount: 'AMOUNT',
        paymentType: 'PAYMENT_TYPE',
        type: 'TRANSACTION_TYPE',
        masterId: 'RRNO',
        memo: 'COMMENT',
        corporate: 'IS_CORPORATE',
        customId1: 'CUSTOM_ID',
        customId2: 'CUSTOM_ID2',
        invoiceId: 'INVOICE_ID',
        orderId: 'ORDER_ID',
        amountTip: 'AMOUNT_TIP',
        amountTax: 'AMOUNT_TAX',
        amountFood: 'AMOUNT_FOOD',
        amountMisc: 'AMOUNT_MISC',
        dupeOverride: 'DUPLICATE_OVERRIDE'
    },

    rebilling: {
        doRebill: 'REBILLING',
        startDate: 'REB_FIRST_DATE',
        nextDate: '',
        expression: 'REB_EXPR',
        cycles: 'REB_CYCLES',
        amount: 'REB_AMOUNT',
        nextAmount: '',
        status: 'STATUS',
        templateId: 'TEMPLATE_ID'
    },

    response: {
        transID: 'RRNO',
        maskedAccount: 'PAYMENT_ACCOUNT',
        cardType: 'CARD_TYPE',
        customerBank: 'BANK_NAME'
    }
};

/**
 * @class Connection
 */
var Connection = {
    /**
     * Creates an AUTH transaction
     *
     * @param {Float} amount
     * @param {String} masterId
     * @return {Connection}
     */
    auth: function (amount, masterId) {
        this.transaction.amount = amount || 0;
        this.transaction.masterId = masterId;
        this.transaction.type = 'AUTH';

        return this;
    },

    /**
     * Creates a CAPTURE transaction
     *
     * @param {String} masterId
     * @param {Float} amount
     * @return {Connection}
     */
    capture: function (masterId, amount) {
        this.transaction.amount = amount;
        this.transaction.masterId = masterId;
        this.transaciton.type = 'CAPTURE';

        return this;
    },

    /**
     * Creates a REFUND transaction
     *
     * @param {String} masterId
     * @param {Float} amount
     * @return {Connection}
     */
    refund: function (masterId, amount) {
        this.transaction.amount = amount;
        this.transaction.masterId = masterId;
        this.transaction.type = 'CAPTURE';

        return this;
    },

    /**
     * Creates a SALE transaction
     *
     * @param {Float} amount
     * @param {String} masterId
     * @return {Connection}
     */
    sale: function (amount, masterId) {
        this.transaction.amount = amount;
        this.transaction.masterId = masterId;
        this.transaction.type = 'SALE';

        return this;
    },

    /**
     * VOID a transaction
     *
     * @param {String} masterId
     * @return {Connection}
     */
    void: function (masterId) {
        this.transaction.masterId = masterId;
        this.transaction.type = 'VOID';

        return this;
    },

    /**
     * Populates customer information for the transaction. The customer
     * object may contain:
     *
     * customer: {
     *     name1
     *     name2
     *     addr1
     *     addr2
     *     city
     *     state
     *     zip
     *     email
     *     phone
     *     country
     * }
     *
     * @param {Object} customer
     * @returns {Connection}
     */
    setCustomerInformation: function (customer) {
        this.customer = customer;

        return this;
    },

    /**
     * Populates the credit card information and also the payment type of the
     * transaction.
     *
     * @param {String} card
     * @param {Mixed} expire, Must be a 4 digit number or string in the format MMYY, or a Date object.
     * @param {String} cvv2
     * @return {Connection}
     */
    setCardInformation: function (card, expire, cvv2) {
        var month;
        var year;
        if (_.isDate(expire)) {
            month = expire.getMonth() + 1; // getMonth returns value 0-11
            year = expire.getFullYear().toString().substr(2, 2);
            expire = month + year;
        }

        this.creditcard.account = card;
        this.creditcard.expire = expire;
        this.creditcard.cvv2 = cvv2 || '';
        this.transaction.paymentType = 'CREDIT';

        return this;
    },

    /** Populated the ACH information and also the payment type of the
     * transaction.
     *
     * @param {String} routingNumber
     * @param {String} accountNumber
     * @param {String} accountType
     * @param {String} documentType
     * @return {Connection}
     */
    setAchInformation: function (routingNumber, accountNumber, accountType, documentType) {
        this.ach.routingNum = routingNumber;
        this.ach.accountNum = accountNumber;
        this.ach.accountType = accountType;
        this.ach.docType = documentType || '';
        this.transaction.paymentType = 'ACH';

        return this;
    },

    /**
     * Creates a rebilling cycle
     *
     * @param {Date} start
     * @param {String} expression
     * @param {Number} cycles
     * @param {Float} amount
     * @return {Connection}
     */
    setRebillingInformation: function (start, expression, cycles, amount) {
        this.rebilling.doRebill = 1;
        this.rebilling.startDate = start;
        this.rebilling.expression = expression;
        this.rebilling.cycles = cycles;
        this.rebilling.amount = amount;

        return this;
    },

    /**
     * Clears the properties, provided in the `keys` array, from the
     * connection. If no argument is passed clears all properties
     * enumerated in the exemplar.
     *
     * @param {...String} keys
     * @return {Connection}
     */
    reset: function (keys) {
        if (arguments.length) {
            keys = Array.prototype.slice.call(arguments, 0);
        } else {
            keys = Object.keys(exemplar);
        }
        keys.forEach(function (key) {
            this[key] = {};
        });

        return this;
    }
};

var factory = {
    /**
     * Connection factory
     *
     * @param {Object} options
     * @return {Connection}
     */
    connect: function (options) {
        if (!options.hasOwnProperty('accountId') || !options.hasOwnProperty('secretKey')) {
            throw new Error('Must define AccountId and SecretKey when creating a new BluePay connection');
        }
        var connection =  Object.create(Connection, {
            /**
             * BluePay account id
             */
            accountId: {
                value: options.accountId,
                writable: false
            },

            /**
             * BluePay transaction Mode, can be TEST or LIVE.  Defaults to TEST.
             */
            mode: {
                value: options.mode || 'TEST',
                writable: true
            },

            /**
             * BluePay account secret
             */
            secretKey: {
                value: options.secretKey,
                writable: false
            }
        });

        return connection;
    },

    modes: {
        TEST: 'TEST',
        LIVE: 'LIVE'
    },

    payments: {
        CREDIT: 'CREDIT',
        ACH: 'ACH',
    },

    transacitons: {
        AUTH: 'AUTH',
        SALE: 'SALE',
        CAPTURE: 'CAPTURE',
        REFUND: 'REFUND',
        REBCANCEL: 'REBCANCEL'
    }
};

module.exports = factory;

<commit_msg>Rebilling are request processing<commit_after>'use strict';
var _ = require('lodash');
var crypto = require('crypto');
var Q = require('q');
var querystring = require('querystring');
var request = require('request');

/**
 * The exemplars are models of the BluePay paremeters we will
 * loop through to build API requests. The value of each member
 * is its required status.
 */
var exemplar = {
    customer: {
        name1: 'NAME1',
        name2: 'NAME2',
        company: 'COMPANY_NAME',
        addr1: 'ADDR1',
        addr2: 'ADDR2',
        city: 'CITY',
        state: 'STATE',
        zip: 'ZIPCODE',
        email: 'EMAIL',
        phone: 'PHONE',
        country: 'COUNTRY',
        remoteIp: 'REMOTE_IP'
    },

    card: {
        account: 'CC_NUM',
        cardExpire: 'CC_EXPIRES',
        cvv2: 'CVCCVV2'
    },

    ach: {
        accountType: 'ACH_ACCOUNT_TYPE',
        docType: 'DOC_TYPE',
        accountNum: 'ACH_ACCOUNT',
        routingNum: 'ACH_ROUTING'
    },

    tranction: {
        amount: 'AMOUNT',
        paymentType: 'PAYMENT_TYPE',
        type: 'TRANSACTION_TYPE',
        masterId: 'RRNO',
        memo: 'COMMENT',
        corporate: 'IS_CORPORATE',
        customId1: 'CUSTOM_ID',
        customId2: 'CUSTOM_ID2',
        invoiceId: 'INVOICE_ID',
        orderId: 'ORDER_ID',
        amountTip: 'AMOUNT_TIP',
        amountTax: 'AMOUNT_TAX',
        amountFood: 'AMOUNT_FOOD',
        amountMisc: 'AMOUNT_MISC',
        dupeOverride: 'DUPLICATE_OVERRIDE'
    },

    rebilling: {
        id: 'REBILL_ID',
        doRebill: 'REBILLING',
        startDate: 'REB_FIRST_DATE',
        nextDate: 'NEXT_DATE',
        expression: 'REB_EXPR',
        cycles: 'REB_CYCLES',
        amount: 'REB_AMOUNT',
        nextAmount: '',
        status: 'STATUS',
        templateId: 'TEMPLATE_ID'
    },

    response: {
        transId: 'RRNO',
        maskedAccount: 'PAYMENT_ACCOUNT',
        cardType: 'CARD_TYPE',
        customerBank: 'BANK_NAME',
        message: 'MESSAGE',
        status: 'Result',
        rebillId: 'rebill_id',
        templateId: 'template_id',
        masterId: 'id',
        paymentType: 'payment_type',
        type: 'trans_type',
        amount: 'amount'
    }
};

/**
 * @class BluePay
 */
var BluePay = {
    /**
     * Creates an AUTH transaction
     *
     * @param {Float} amount
     * @param {String} masterId
     * @return {Connection}
     */
    auth: function (amount, masterId) {
        this.transaction.amount = amount || 0;
        this.transaction.masterId = masterId;
        this.transaction.type = 'AUTH';

        return this;
    },

    /**
     * Creates a CAPTURE transaction
     *
     * @param {String} masterId
     * @param {Float} amount
     * @return {Connection}
     */
    capture: function (masterId, amount) {
        this.transaction.amount = amount;
        this.transaction.masterId = masterId;
        this.transaction.type = 'CAPTURE';

        return this;
    },

    /**
     * Creates a REFUND transaction
     *
     * @param {String} masterId
     * @param {Float} amount
     * @return {Connection}
     */
    refund: function (masterId, amount) {
        this.transaction.amount = amount;
        this.transaction.masterId = masterId;
        this.transaction.type = 'CAPTURE';

        return this;
    },

    /**
     * Creates a SALE transaction
     *
     * @param {Float} amount
     * @param {String} masterId
     * @return {Connection}
     */
    sale: function (amount, masterId) {
        this.transaction.amount = amount;
        this.transaction.masterId = masterId;
        this.transaction.type = 'SALE';

        return this;
    },

    /**
     * VOID a transaction
     *
     * @param {String} masterId
     * @return {Connection}
     */
    void: function (masterId) {
        this.transaction.masterId = masterId;
        this.transaction.type = 'VOID';

        return this;
    },

    /**
     * Populates customer information for the transaction. The customer
     * object may contain:
     *
     * customer: {
     *     name1
     *     name2
     *     addr1
     *     addr2
     *     city
     *     state
     *     zip
     *     email
     *     phone
     *     country
     * }
     *
     * @param {Object} customer
     * @returns {Connection}
     */
    setCustomerInformation: function (customer) {
        this.customer = customer;

        return this;
    },

    /**
     * Populates the credit card information and also the payment type of the
     * transaction.
     *
     * @param {String} card
     * @param {Mixed} expire, Must be a 4 digit number or string in the format MMYY, or a Date object.
     * @param {String} cvv2
     * @return {Connection}
     */
    setCardInformation: function (card, expire, cvv2) {
        var month;
        var year;
        if (_.isDate(expire)) {
            month = expire.getMonth() + 1; // getMonth returns value 0-11
            year = expire.getFullYear().toString().substr(2, 2);
            expire = month + year;
        }

        this.creditcard.account = card;
        this.creditcard.expire = expire;
        this.creditcard.cvv2 = cvv2 || '';
        this.transaction.paymentType = 'CREDIT';

        return this;
    },

    /** Populated the ACH information and also the payment type of the
     * transaction.
     *
     * @param {String} routingNumber
     * @param {String} accountNumber
     * @param {String} accountType
     * @param {String} documentType
     * @return {Connection}
     */
    setAchInformation: function (routingNumber, accountNumber, accountType, documentType) {
        this.ach.routingNum = routingNumber;
        this.ach.accountNum = accountNumber;
        this.ach.accountType = accountType;
        this.ach.docType = documentType || '';
        this.transaction.paymentType = 'ACH';

        return this;
    },

    /**
     * Creates a rebilling cycle
     *
     * @param {Date} start
     * @param {String} expression
     * @param {Number} cycles
     * @param {Float} amount
     * @return {Connection}
     */
    setRebillingInformation: function (start, expression, cycles, amount) {
        this.rebilling.doRebill = 1;
        this.rebilling.startDate = start;
        this.rebilling.expression = expression;
        this.rebilling.cycles = cycles;
        this.rebilling.amount = amount;

        return this;
    },

    /**
     * Clears the properties, provided in the `keys` array, from the
     * connection. If no argument is passed clears all properties
     * enumerated in the exemplar.
     *
     * @param {...String} keys
     * @return {Connection}
     */
    reset: function () {
        var keys;
        if (arguments.length) {
            keys = Array.prototype.slice.call(arguments, 0);
        } else {
            keys = Object.keys(exemplar);
        }
        keys.forEach(function (key) {
            this[key] = {};
        });

        return this;
    },

    /**
     * Updates the Transaction type and adjusts the rebilling parameters
     *
     * @param {String} id, The 12-digit ID of the Rebilling to modify/view
     * @param {Date} next, Set the next rebill date to this date
     * @param {String} expression
     * @param {Number} cycles, Number of billings to complete.
     * @param {Float} amount, Amount to charge for the each billing
     * @return {Connection}
     */
    updateRebillingCycle: function (id, next, expression, cycle, amount) {
        this.transaction.type = 'SET';
        this.rebilling.id = id;
        this.rebilling.nextDate = next;
        this.rebilling.expression = expression;
        this.rebilling.cycle = cycle;
        this.rebilling.amount = amount;

        return this;
    },

    /**
     * Sets the rebilling template.
     *
     * @param {String} id, The 12-digit ID of the template for this rebilling.
     * @return {Connection}
     */
    setRebillingTemplate: function (id) {
        this.rebilling.templateId = id;

        return this;
    },

    /**
     * Cancel a rebilling
     *
     * @param {String} id, The 12-digit ID specifying this rebilling.
     * @return {Connection}
     */
    cancelRebilling: function (id) {
        this.transaction.type = 'SET';
        this.rebilling.status = 'stopped';
        this.rebilling.id = id;

        return this;
    },

    /**
     * Get the current status of a rebilling
     *
     * @param {String} id, The 12-digit ID specifying this rebilling.
     * @return {Connection}
     */
    getRebillingStatus: function (id) {
        this.transaction.type = 'GET';
        this.rebilling.id = id;

        return this;
    },

    /**
     * Process the transaction on the current connection.
     *
     */
    process: function () {
        var deferred = Q.defer();
        var parameters = {};
        var self = this;
        var url = 'https://secure.bluepay.com/interfaces/bp10emu';
        function copyConfig(item) {
            self[item].forEach(function (key) {
                parameters[exemplar[item][key]] = self[item][key];
            });

        }

        parameters.mode = this.mode;

        if (this.transaction.type === 'SET' && this.transaction.type === 'GET') {
            copyConfig('transaction');
            copyConfig('customer');

            if (this.transaction.paymentType === 'CREDIT') {
                copyConfig('credit');
            } else {
                copyConfig('ach');
            }

            if (this.rebilling.doRebill) {
                copyConfig('rebilling');
            }
            parameters.TAMPER_PROOF_SEAL = this.seal(parameters);
            url = 'https://secure.bluepay.com/interfaces/bp10emu';
        } else {
            parameters.ACCOUNT_ID = this.accountId;
            copyConfig('transaction');
            copyConfig('rebilling');
            parameters.TAMPER_PROOF_SEAL = this.seal(parameters);
            url = 'https://secure.bluepay.com/interfaces/bp20rebadmin';
        }

        request.post(url, parameters, function (err, response, body) {
            var result;
            if (err) {
                return deferred.reject(err);
            }
            result = querystring.parse(body);
            exemplar.response.forEach(function (key) {
                self.response[exemplar.response[key]] = result[key];
            });
        });
    },

    /**
     * Creates a tamper proof seal for the message
     *
     * @param {Object} parameters
     * @return {String}
     */
    seal: function (parameters) {
      var md5 = crypto.createHash('md5');
      md5.update(parameters.SECRET_KEY);
      md5.update(parameters.ACCOUNT_ID);
      md5.update(parameters.TRANS_TYPE);
      md5.update(parameters.AMOUNT);
      md5.update(parameters.MASTER_ID || '');
      md5.update(parameters.NAME1 || '');
      md5.update(parameters.PAYMENT_ACCOUNT);
      return md5.digest('hex');
    }
};

var factory = {
    /**
     * Connection factory
     *
     * @param {Object} options
     * @return {Connection}
     */
    connect: function (options) {
        if (!options.hasOwnProperty('accountId') || !options.hasOwnProperty('secretKey')) {
            throw new Error('Must define AccountId and SecretKey when creating a new BluePay connection');
        }
        var connection =  Object.create(BluePay, {
            /**
             * BluePay account id
             */
            accountId: {
                value: options.accountId,
                writable: false
            },

            /**
             * BluePay transaction Mode, can be TEST or LIVE.  Defaults to TEST.
             */
            mode: {
                value: options.mode || 'TEST',
                writable: true
            },

            /**
             * BluePay account secret
             */
            secretKey: {
                value: options.secretKey,
                writable: false
            }
        });

        return connection;
    },

    modes: {
        TEST: 'TEST',
        LIVE: 'LIVE'
    },

    payments: {
        CREDIT: 'CREDIT',
        ACH: 'ACH',
    },

    transactions: {
        AUTH: 'AUTH',
        SALE: 'SALE',
        CAPTURE: 'CAPTURE',
        REFUND: 'REFUND',
        REBCANCEL: 'REBCANCEL'
    }
};

module.exports = factory;

<|endoftext|>


<commit_before>'use strict';

var method = require('./../method');
var assign = require('lodash.assign');

/**
 * @memberof scripts
 * @method create
 * @description Creates a new startup script.  Optionally specify a machine to use this startup script.
 * Note: currently only Linux based machines support startup scripts.  Also, note: script data is limited to 16KB per script.
 * @param {object} params - Script create parameters
 * @param {string} params.scriptName - A unique name for the script
 * @param {string} [params.scriptFile] - File path to a file containing the script data; either scriptFile or scriptText must be provide.
 * @param {string} [params.scriptText] - A string containing the script text; either scriptFile or scriptText must be provide.
 * @param {string} [params.scriptDescription] - Description of the script
 * @param {boolean} [params.isEnabled] - Determines if the script is enabled or not.  Defaults to true
 * @param {boolean} [params.runOnce] - Determines if the script is run on first boot or every boot.  Defaults to false
 * @param {string} [params.machineId] - Machine id of a machine that should execute this script at startup
 * @param {function} cb - Node-style error-first callback function
 * @returns {object} script - The created script JSON object
 * @example
 * paperspace.scripts.create({
 *   scriptName: 'My Script',
 *   scriptFile: './my_script_file.sh', // must specify either scriptFile or scriptText
 *   scriptDescription: 'A startup script', // optional
 *   isEnabled: true, // optional
 *   runOnce: false, // optional
 *   machineId: 'ps123abc', // optional
 * }, function(err, resp) {
 *   // handle error or http response
 * });
 * @example
 * $ paperspace accounts create \
 *     --scriptName "My Script" \
 *     --scriptDescription "A startup script" \
 *     --scriptText "services start nginx" \
 *     --isEnabled true \
 *     --runOnce false \
 *     --machineId "ps123abc"
 * @example
 * # HTTP request:
 * https://api.paperspace.io
 * POST /account/setStartupScript {"scriptName": "My Script", "scriptDescription": "A startup script", "isEnabled": true, "runOnce": false, "machineId": "ps123abc"}
 * x-api-key: 1ba4f98e7c0...
 * (file contents as multipart form data)
 * # Returns 200 on success
 * @example
 * // Example return value:
 * {
 *   "id": "sc123abc",
 *   "ownerType": "user",
 *   "ownerId": "u456def",
 *   "name": "My Script",
 *   "description": "my_script_file.sh",
 *   "dtCreated": "2017-06-15T19:22:13.507Z",
 *   "isEnabled": true,
 *   "runOnce": false
 * }
 */

function create(params, cb) {
	if (!params.scriptFile && !params.scriptText) return cb(new Error('Missing required parameter: either scriptFile or scriptText'));
	if (params.scriptFile && params.scriptText) return cb(new Error('Only one of scriptFile or scriptText allowed'));
	return method(create, params, cb);
}

assign(create, {
	auth: true,
	group: 'scripts',
	name: 'create',
	method: 'post',
	route: '/scripts/createScript',
	requires: {
		scriptName: 'string',
	},
	file: 'scriptFile',
	returns: {},
});

module.exports = create;
<commit_msg>request path doc fix for scripts create<commit_after>'use strict';

var method = require('./../method');
var assign = require('lodash.assign');

/**
 * @memberof scripts
 * @method create
 * @description Creates a new startup script.  Optionally specify a machine to use this startup script.
 * Note: currently only Linux based machines support startup scripts.  Also, note: script data is limited to 16KB per script.
 * @param {object} params - Script create parameters
 * @param {string} params.scriptName - A unique name for the script
 * @param {string} [params.scriptFile] - File path to a file containing the script data; either scriptFile or scriptText must be provide.
 * @param {string} [params.scriptText] - A string containing the script text; either scriptFile or scriptText must be provide.
 * @param {string} [params.scriptDescription] - Description of the script
 * @param {boolean} [params.isEnabled] - Determines if the script is enabled or not.  Defaults to true
 * @param {boolean} [params.runOnce] - Determines if the script is run on first boot or every boot.  Defaults to false
 * @param {string} [params.machineId] - Machine id of a machine that should execute this script at startup
 * @param {function} cb - Node-style error-first callback function
 * @returns {object} script - The created script JSON object
 * @example
 * paperspace.scripts.create({
 *   scriptName: 'My Script',
 *   scriptFile: './my_script_file.sh', // must specify either scriptFile or scriptText
 *   scriptDescription: 'A startup script', // optional
 *   isEnabled: true, // optional
 *   runOnce: false, // optional
 *   machineId: 'ps123abc', // optional
 * }, function(err, resp) {
 *   // handle error or http response
 * });
 * @example
 * $ paperspace scripts create \
 *     --scriptName "My Script" \
 *     --scriptDescription "A startup script" \
 *     --scriptText "services start nginx" \
 *     --isEnabled true \
 *     --runOnce false \
 *     --machineId "ps123abc"
 * @example
 * # HTTP request:
 * https://api.paperspace.io
 * POST /scripts/createScript {"scriptName": "My Script", "scriptDescription": "A startup script", "isEnabled": true, "runOnce": false, "machineId": "ps123abc"}
 * x-api-key: 1ba4f98e7c0...
 * (file contents as multipart form data)
 * # Returns 200 on success
 * @example
 * // Example return value:
 * {
 *   "id": "sc123abc",
 *   "ownerType": "user",
 *   "ownerId": "u456def",
 *   "name": "My Script",
 *   "description": "my_script_file.sh",
 *   "dtCreated": "2017-06-15T19:22:13.507Z",
 *   "isEnabled": true,
 *   "runOnce": false
 * }
 */

function create(params, cb) {
	if (!params.scriptFile && !params.scriptText) return cb(new Error('Missing required parameter: either scriptFile or scriptText'));
	if (params.scriptFile && params.scriptText) return cb(new Error('Only one of scriptFile or scriptText allowed'));
	return method(create, params, cb);
}

assign(create, {
	auth: true,
	group: 'scripts',
	name: 'create',
	method: 'post',
	route: '/scripts/createScript',
	requires: {
		scriptName: 'string',
	},
	file: 'scriptFile',
	returns: {},
});

module.exports = create;
<|endoftext|>


<commit_before>
var Slack = require('node-slack');
var express = require('express');
var bodyParser = require('body-parser')

function initSlack() {
    if (process.env.HOOK_URL) {
        hookURL = process.env.HOOK_URL;
    } else {
        console.log("Must configure HOOK_URL!");
        process.exit(1);
    }
    return new Slack(hookURL);
}

function main()  {
    var slack = initSlack();
    var app = newServer(slack);
    app.listen(8080);
}

function newServer(slack) {
    var app = express();

    app.use(bodyParser.json())

    var handlers = {};

    var newHandler = function(handler) {
        return handler(slack);
    };

    handlers['ping'] = newHandler(pingHandler);
    handlers['commit_comment'] = newHandler(commitCommentHandler);
    handlers['pull_request'] = newHandler(pullRequestHandler);
    handlers['pull_request_review_comment'] = newHandler(pullRequestCommentHandler);
    handlers['status'] = newHandler(statusHandler);

    app.post('/', function (req, res) {
        var event = req.headers['x-github-event'];
        if (!handlers[event]) {
            res.send('Unhandled event: ' + handlers[event]);
            res.end();
            return;
        }

        res.sendStatus(handlers[event](req.body));
        res.end();
    });
    return app;
}

function pingHandler(slack) {
    return function(data) {
        return 200;
    }
}

function commitCommentHandler(slack) {
    return function(data) {
        return 200;
    }
}

function pullRequestHandler(slack) {
    return function(data) {
        return 200;
    }
}

function pullRequestCommentHandler(slack) {
    return function(data) {
        return 200;
    }
}

function statusHandler(slack) {
    return function(data) {
        return 200;
    }
}

if (require.main === module) {
    main();
}
<commit_msg>Change port configuration<commit_after>
var Slack = require('node-slack');
var express = require('express');
var bodyParser = require('body-parser')

function initSlack() {
    if (process.env.HOOK_URL) {
        hookURL = process.env.HOOK_URL;
    } else {
        console.log("Must configure HOOK_URL!");
        process.exit(1);
    }
    return new Slack(hookURL);
}

function main()  {
    var slack = initSlack();
    var app = newServer(slack);

    app.set('port', (process.env.PORT || 5000));
    app.listen(app.get('port'), function() {
        console.log('Node app is running on port', app.get('port'));
    });
}

function newServer(slack) {
    var app = express();

    app.use(bodyParser.json())

    var handlers = {};

    var newHandler = function(handler) {
        return handler(slack);
    };

    handlers['ping'] = newHandler(pingHandler);
    handlers['commit_comment'] = newHandler(commitCommentHandler);
    handlers['pull_request'] = newHandler(pullRequestHandler);
    handlers['pull_request_review_comment'] = newHandler(pullRequestCommentHandler);
    handlers['status'] = newHandler(statusHandler);

    app.post('/', function (req, res) {
        var event = req.headers['x-github-event'];
        if (!handlers[event]) {
            res.send('Unhandled event: ' + handlers[event]);
            res.end();
            return;
        }

        res.sendStatus(handlers[event](req.body));
        res.end();
    });
    return app;
}

function pingHandler(slack) {
    return function(data) {
        return 200;
    }
}

function commitCommentHandler(slack) {
    return function(data) {
        return 200;
    }
}

function pullRequestHandler(slack) {
    return function(data) {
        return 200;
    }
}

function pullRequestCommentHandler(slack) {
    return function(data) {
        return 200;
    }
}

function statusHandler(slack) {
    return function(data) {
        return 200;
    }
}

if (require.main === module) {
    main();
}
<|endoftext|>


<commit_before>/*jslint indent:2, node:true*/

'use strict';

var Hapi = require('hapi');

// Create a server with a host and port
var server = Hapi.createServer('0.0.0.0', process.env.PORT || 8000, {
  origin: [
    'http://jokeyrhy.me',
    'https://jokeyrhy.me',
    'http://localhost:4000',
    'https://localhost:4000'
  ],
  isOriginExposed: false,
  credentials: false
});

// Add the route
server.route({
  method: 'GET',
  path: '/hello',
  handler: function (request, reply) {
    reply('hello world');
  }
});

// Start the server
server.start();
<commit_msg>fix CORS settings declaration<commit_after>/*jslint indent:2, node:true*/

'use strict';

var Hapi = require('hapi');

// Create a server with a host and port
var server = Hapi.createServer('0.0.0.0', process.env.PORT || 8000, {
  cors: {
    origin: [
      'http://jokeyrhy.me',
      'https://jokeyrhy.me',
      'http://localhost:4000',
      'https://localhost:4000'
    ],
    isOriginExposed: false,
    credentials: false
  }
});

// Add the route
server.route({
  method: 'GET',
  path: '/hello',
  handler: function (request, reply) {
    reply('hello world');
  }
});

// Start the server
server.start();
<|endoftext|>


<commit_before>var ___ = '___send-to-shoulder___';
var _ = '_hole_';
//var log = 1 ? console.log : function(){} ;

var purry = module.exports = function(f){
  if (f.length === 0) throw new Error('purry is not compatible with variable-argument functions.')
  var initial_stock = [];
  var i = f.length;
  while(i > 0){
    initial_stock.push(_);
    i--;
  }
  return (function accumulate_arguments(capacity, _capacity_used, _stock){
    return function(/* ...args_new */){
      var arguments_count = arguments.length;

      // Bail ASAP if no arguments given
      if (!arguments_count) {
        return capacity - _capacity_used ?
          accumulate_arguments(capacity, _capacity_used, _stock) :
          f.apply(null, _stock) ;
      }
      // index for various loops below
      var i;
      // TODO optimization case: 0 arguments_count
      // TODO optimization case: capacity === _capacity_used
      //log('\n\nInvoked: capacity %d | instance capacity %d | stock %j | new args %j', capacity, capacity - _capacity_used, _stock, args_new.map(function(x){ return x === _ ? '_' : x === ___ ? '___' : x ; }))

      // Clone stock, to avoid clobbering
      var stock = [];
      var _stock_count = _stock.length;
      i = 0;
      for (; i < _stock_count; i++ ) {
        stock[i] = _stock[i];
      }

      // Shadow capacity_used, to avoid clobbering
      var capacity_used = _capacity_used;

      // enter new arguments into instance
      var is_args_partial = false;
      var arg_new;
      var stock_i = 0;
      var incby = 1;
      var endloop = arguments_count;
      var offset = 0;
      i = 0;
      process_new_arguments:
      for (; i !== endloop; i += incby) {
        //if (stock_i >= (capacity || i < 0) break;
        // TODO needed? if (capacity === capacity_used) break;
        //log('\nend condition: %d !== %d | stock_i: %d', i, endloop, stock_i);
        arg_new = arguments[i];

        if (arg_new === _) {
          is_args_partial = true;
          offset++;
          //log('Hit Hole _, offset @ %d', offset);
          continue;
        }

        if (arg_new === ___) {
          is_args_partial = true;
          incby = -1
          stock_i = capacity - 1;
          //log('Hit shoulder ___ of size (%d)', (arguments_count - (i + 1)));
          endloop = i;
          i = arguments_count;
          continue
        }

        while (true) {
          if (stock_i >= capacity) break process_new_arguments;
          if (stock[stock_i] !== _) {
            stock_i += incby;
          } else if(offset) {
            stock_i += incby;
            offset--;
          } else {
            break;
          }
        }
        //log('Add argument: %j @ i%d', arg_new, stock_i);
        stock[stock_i] = arg_new;
        //log('stock: %j', stock);
        capacity_used++;
      }

      //log('\nProcessing Complete. ')
      if (is_args_partial || capacity - capacity_used) {
        //log('Not applicable, stock: %j', stock);
        return accumulate_arguments(capacity, capacity_used, stock);
      } else {
        //log('Applicable! %j', stock);
        return f.apply(null, stock);
      }
    };
  }(f.length, 0, initial_stock));
};

purry._ = _;
purry.___ = ___;<commit_msg>Break accumulator out into module closure, seems to have no noteably performance impact but is easier to read<commit_after>var ___ = '___send-to-shoulder___';
var _ = '_hole_';
//var log = 1 ? console.log : function(){} ;

var purry = module.exports = function(f){
  if (f.length === 0) throw new Error('purry is not compatible with variable-argument functions.')
  var initial_stock = [];
  var i = f.length;
  while(i > 0){
    initial_stock.push(_);
    i--;
  }
  return accumulate_arguments(f, f.length, 0, initial_stock);
};

function accumulate_arguments(f, capacity, _capacity_used, _stock){
  return function(){
    var arguments_count = arguments.length;

    // Bail ASAP if no arguments given
    if (!arguments_count) {
      return capacity === _capacity_used ?
        f.apply(null, _stock) :
        accumulate_arguments(f, capacity, _capacity_used, _stock) ;
    }

    // TODO? Bail ASAP if all arguments given in single shot
    // if (!_capacity_used && arguments_count === capacity)

    // index for various loops below
    var i;

    //log('\n\nInvoked: capacity %d | instance capacity %d | stock %j | new args %j', capacity, capacity - _capacity_used, _stock, args_new.map(function(x){ return x === _ ? '_' : x === ___ ? '___' : x ; }))

    // Clone stock, to avoid clobbering
    var stock = [];

    var _stock_count = _stock.length;
    i = 0;
    for (; i < _stock_count; i++ ) {
      stock[i] = _stock[i];
    }

    // Shadow capacity_used, to avoid clobbering
    var capacity_used = _capacity_used;

    // enter new arguments into instance
    var is_arguments_partial = false;

    var argument;
    var stock_i = 0;
    var incby = 1;
    var endloop = arguments_count;
    var offset = 0;
    i = 0;
    process_new_arguments:
    for (; i !== endloop; i += incby) {
      //if (stock_i >= (capacity || i < 0) break;
      // TODO needed? if (capacity === capacity_used) break;
      //log('\nend condition: %d !== %d | stock_i: %d', i, endloop, stock_i);
      argument = arguments[i];

      if (argument === _) {
        is_arguments_partial = true;
        offset++;
        //log('Hit Hole _, offset @ %d', offset);
        continue;
      }

      if (argument === ___) {
        is_arguments_partial = true;
        incby = -1
        stock_i = capacity - 1;
        //log('Hit shoulder ___ of size (%d)', (arguments_count - (i + 1)));
        endloop = i;
        i = arguments_count;
        continue;
      }

      while (true) {
        if (stock_i >= capacity) break process_new_arguments;
        if (stock[stock_i] !== _) {
          stock_i += incby;
        } else if(offset) {
          stock_i += incby;
          offset--;
        } else {
          break;
        }
      }
      //log('Add argument: %j @ i%d', argument, stock_i);
      stock[stock_i] = argument;
      //log('stock: %j', stock);
      capacity_used++;
    }

    //log('\nProcessing Complete. ')
    if (is_arguments_partial || capacity !== capacity_used) {
      //log('Not applicable, stock: %j', stock);
      return accumulate_arguments(f, capacity, capacity_used, stock);
    } else {
      //log('Applicable! %j', stock);
      return f.apply(null, stock);
    }
  };
}

purry._ = _;
purry.___ = ___;<|endoftext|>


<commit_before>(function() {
    'use strict';

    var DIR             = '../',
        DIR_ROOT        = DIR + '../',
        DIR_SERVER      = './',

        path            = require('path'),
        child_process   = require('child_process'),
        exec            = child_process.exec,
        spawn           = child_process.spawn,

        Util            = require(DIR           + 'util'),
        CloudFunc       = require(DIR           + 'cloudfunc'),

        win             = require(DIR_SERVER    + 'win'),
        update          = require(DIR_SERVER    + 'update'),
        socket          = require(DIR_SERVER    + 'socket'),
        find            = require(DIR_SERVER    + 'find'),

        mainpackage     = require(DIR_ROOT      + 'package'),
        CLOUDCMD        = mainpackage.name,

        equalPart       = Util.isContainStrAtBegin,

        ClientFuncs     = [],
        ClientDirs      = [],
        Clients         = [],
        WIN             = process.platform === 'win32',

        addNewLine      = CloudFunc.addNewLine,
        rmNewLine       = CloudFunc.rmNewLine,

        ConNum          = 0,

        CHANNEL         = CloudFunc.CHANNEL_CONSOLE,

        HELP            = {
            stdout  : CLOUDCMD + ' exit     \n' +
                      CLOUDCMD + ' update   \n',
        };

        Util.exec.try(function() {
            find = require('glob');
        });

    /**
     * function listen on servers port
     * @pServer {Object} started server object
     */
    exports.init = function() {
        var ret;

        ret = socket.on('connection', function(clientSocket) {
            onConnection(clientSocket, function(json) {
                socket.emit(CHANNEL, json, clientSocket);
            });
        });

        return ret;
    };

    function onConnection(clientSocket, callback) {
        var msg, onDisconnect, onMessage;

        ++ConNum;

        if (!Clients[ConNum]) {
            msg = log(ConNum, 'console connected');

            callback({
                stdout  : addNewLine(msg),
                path    : process.cwd()
            });

            Clients[ConNum]             = true;

            onMessage                   = Util.exec.with(getOnMessage, ConNum, callback);
            onDisconnect                = function(conNum) {
                Clients[conNum]         =
                ClientFuncs[conNum]     = null;

                log(conNum, 'console disconnected');

                socket.removeListener(CHANNEL, onMessage, clientSocket);
                socket.removeListener('disconnect', onDisconnect, clientSocket);
            }.bind(null, ConNum);

            socket.on(CHANNEL, onMessage, clientSocket);
            socket.on('disconnect', onDisconnect, clientSocket);
        } else {
            msg = log(ConNum, ' in use. Reconnecting...\n');

            Util.exec(callback, {
                stdout: msg
            });

            socket.disconnect();
        }
    }

    /**
     * function gets onMessage function
     * that execute needed command
     *
     * @param pConnNum
     * @param callback
     */
    function getOnMessage(connNum, callback, command) {
        var funcExec, firstChar,
            connName, ret,

            isVolume    = win.isChangeVolume(command),
            isCD        = command.match(new RegExp('^cd ?')),
            isCDWin     = command.match(new RegExp('^cd ?', 'i')),

            symbolsExec = ['*', '&', '{', '}', '|', '\'', '"'],
            isSymbol    = Util.isContainStr(command, symbolsExec),

            CWD         = process.cwd(),
            dir         = ClientDirs[connNum],
            options     = {
                cwd:    dir || CWD
            };

        if (!dir)
            dir = ClientDirs[connNum] = CWD;

        connName = '#' + connNum + ': ';
        Util.log(connName + command);

        if (equalPart(command, CLOUDCMD))
            ret = onCloudCmd(command, callback);
        else if (isCD || isCDWin && WIN || isVolume) {
            ret = true;

            onCD(command, dir, function(error, json) {
                var path;

                if (json.path) {
                    path                = json.path;
                    ClientDirs[connNum] = path;
                }

                callback(json);
            });
        }

        if (!ret) {
            if (WIN)
                command    = 'cmd /C ' + command;

            if (!ClientFuncs[connNum])
                ClientFuncs[connNum] = Util.exec.with(setExec, function(json, error, stderr) {
                    log(connNum, error, 'error');
                    log(connNum, stderr, 'stderror');

                    Util.exec(callback, json);
                });

            funcExec        = ClientFuncs[connNum];
            firstChar       = command[0];

            if (firstChar === '#') {
                command     = command.slice(1);
                command     = connName + command;
                command     = addNewLine(command);

                Util.exec(callback, {
                    stdout: command
                }, true);
            } else if (WIN || firstChar === ' ' || isSymbol)
                exec(command, options, funcExec);
            else
                setSpawn(command, options, callback);
        }
    }

    /**
     * function send result of command to client
     * @param callback
     */
    function setExec(callback, error, stdout, stderr) {
        var json,
            errorStr    = '';

        if (stderr)
            errorStr    = stderr;
        else if (error)
            errorStr    = error.message;

        json            = {
            stdout : stdout,
            stderr : errorStr
        };

        Util.exec(callback, json, error, stderr);
    }

    function setSpawn(сommand, options, callback) {
        var cmd, error,
            isSended    = false,
            args        = сommand.split(' '),
            send        = function(error, data) {
                isSended = true;

                callback({
                    stderr: error,
                    stdout: data
                });
            },
            sendError     = function(error) {
                isSended = true;

                send(error, null);
            };

        сommand    = args.shift();

        error       = Util.exec.tryLog(function() {
            cmd = spawn(сommand, args, options);
        });

        if (error) {
            sendError(error);
        } else {
            cmd.stderr.setEncoding('utf8');
            cmd.stdout.setEncoding('utf8');

            cmd.stdout.on('data', function(data) {
                send(null, data);
            });

            cmd.stderr.on('data', function(error) {
                sendError(error);
            });

            cmd.on('error', function(error) {
                var errorStr    = addNewLine(error + '');

                Util.log(error);
                sendError(errorStr);
            });

            cmd.on('close', function () {
                cmd = null;

                if (!isSended)
                    send(null, null);
            });
        }
    }

    function onCloudCmd(command, callback) {
        var is;

        command = Util.rmStr(command, CLOUDCMD);
        is      = !equalPart(command, ' ');

        if (is) {
            Util.exec(callback, HELP);
        } else {
            command = Util.rmStr(command, ' ');
            is  = update && equalPart(command, 'update');

            if (is) {
                update.get();

                Util.exec(callback, {
                    stdout: addNewLine('update: ok')
                });
            }

            is = Util.strCmp(command, 'exit');

            if (is)
                process.exit();
        }

        return is;
    }

     function onCD(command, currDir, callback) {
        var CD              = 'cd ',
            HOME            = process.env.HOME,

            isChangeVolume  = win.isChangeVolume(command),
            isVolume        = win.isVolume(command),
            paramDir        = Util.rmStrOnce(command, [CD, 'cd']),

            regExpHome      = new RegExp('^~'),

            isWildCard      = Util.isContainStr(paramDir, ['*', '?']),
            isHome          = paramDir.match(regExpHome) && !WIN,

            onExec          = function (error, stdout, stderr) {
                var path        = paramDir,
                    errorStr    = '';

                if (stderr) {
                    errorStr    = stderr;
                } else if (error) {
                    errorStr    = error.message;
                    path        = '';
                }

                callback(error || stderr, {
                    stderr  : addNewLine(errorStr),
                    stdout  : stdout,
                    path    : path
                });
            };

        if (isHome) {
            command     = command.replace('~', HOME);
            paramDir    = paramDir.replace('~', HOME);
        }

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

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

            command     = Util.rmStrOnce(command, [
                CD,
                paramDir,
                '\'' + paramDir + '\'',
                '"'  + paramDir + '"',
            ]);

            if (!isHome && paramDir !== '/')
                paramDir    = path.join(currDir, paramDir);

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

        if (!isWildCard)
            exec(command, {cwd: paramDir}, onExec);
        else
            find(paramDir, function(error, dirs) {
                var dir;

                if (!error)
                    dir = dirs[0];

                paramDir = dir;
                exec(command, {cwd: dir}, onExec);
            });
    }

    function getFirstWord(str) {
        var word, result,
            regStrEnd       = getRegStrEnd(),
            regStr          = '^(.*?)',
            regStrQuotes    = '^"(.*)"',
            regExp          = new RegExp(regStr + regStrEnd),
            regExpQuotes    = new RegExp(regStrQuotes + regStrEnd + '?'),
            is              = Util.isString(str);

        if (is) {
            result  = str.match(regExpQuotes);

            if (result) {
                word    = result[1];
            } else {
                result  = str.match(regExp);
                word    = result && result[1];
            }

            if (!word)
                word    = str;
        }

        return word;
    }

    function getRegStrEnd() {
        var regStrEnd = '(\\s|\\;|&&|\\|\\|)';

        return regStrEnd;
    }

    function log(connNum, str, typeParam) {
        var ret,
            type       = ' ';

        if (str) {

            if (typeParam)
                type  += typeParam + ':';

            ret        = 'client #' + connNum + type + str;

            Util.log(ret);
        }

        return ret;
    }
})();
<commit_msg>fix(console) cd to full path<commit_after>(function() {
    'use strict';

    var DIR             = '../',
        DIR_ROOT        = DIR + '../',
        DIR_SERVER      = './',

        path            = require('path'),
        child_process   = require('child_process'),
        exec            = child_process.exec,
        spawn           = child_process.spawn,

        Util            = require(DIR           + 'util'),
        CloudFunc       = require(DIR           + 'cloudfunc'),

        win             = require(DIR_SERVER    + 'win'),
        update          = require(DIR_SERVER    + 'update'),
        socket          = require(DIR_SERVER    + 'socket'),
        find            = require(DIR_SERVER    + 'find'),

        mainpackage     = require(DIR_ROOT      + 'package'),
        CLOUDCMD        = mainpackage.name,

        equalPart       = Util.isContainStrAtBegin,

        ClientFuncs     = [],
        ClientDirs      = [],
        Clients         = [],
        WIN             = process.platform === 'win32',

        addNewLine      = CloudFunc.addNewLine,
        rmNewLine       = CloudFunc.rmNewLine,

        ConNum          = 0,

        CHANNEL         = CloudFunc.CHANNEL_CONSOLE,

        HELP            = {
            stdout  : CLOUDCMD + ' exit     \n' +
                      CLOUDCMD + ' update   \n',
        };

        Util.exec.try(function() {
            find = require('glob');
        });

    /**
     * function listen on servers port
     * @pServer {Object} started server object
     */
    exports.init = function() {
        var ret;

        ret = socket.on('connection', function(clientSocket) {
            onConnection(clientSocket, function(json) {
                socket.emit(CHANNEL, json, clientSocket);
            });
        });

        return ret;
    };

    function onConnection(clientSocket, callback) {
        var msg, onDisconnect, onMessage;

        ++ConNum;

        if (!Clients[ConNum]) {
            msg = log(ConNum, 'console connected');

            callback({
                stdout  : addNewLine(msg),
                path    : process.cwd()
            });

            Clients[ConNum]             = true;

            onMessage                   = Util.exec.with(getOnMessage, ConNum, callback);
            onDisconnect                = function(conNum) {
                Clients[conNum]         =
                ClientFuncs[conNum]     = null;

                log(conNum, 'console disconnected');

                socket.removeListener(CHANNEL, onMessage, clientSocket);
                socket.removeListener('disconnect', onDisconnect, clientSocket);
            }.bind(null, ConNum);

            socket.on(CHANNEL, onMessage, clientSocket);
            socket.on('disconnect', onDisconnect, clientSocket);
        } else {
            msg = log(ConNum, ' in use. Reconnecting...\n');

            Util.exec(callback, {
                stdout: msg
            });

            socket.disconnect();
        }
    }

    /**
     * function gets onMessage function
     * that execute needed command
     *
     * @param pConnNum
     * @param callback
     */
    function getOnMessage(connNum, callback, command) {
        var funcExec, firstChar,
            connName, ret,

            isVolume    = win.isChangeVolume(command),
            isCD        = command.match(new RegExp('^cd ?')),
            isCDWin     = command.match(new RegExp('^cd ?', 'i')),

            symbolsExec = ['*', '&', '{', '}', '|', '\'', '"'],
            isSymbol    = Util.isContainStr(command, symbolsExec),

            CWD         = process.cwd(),
            dir         = ClientDirs[connNum],
            options     = {
                cwd:    dir || CWD
            };

        if (!dir)
            dir = ClientDirs[connNum] = CWD;

        connName = '#' + connNum + ': ';
        Util.log(connName + command);

        if (equalPart(command, CLOUDCMD))
            ret = onCloudCmd(command, callback);
        else if (isCD || isCDWin && WIN || isVolume) {
            ret = true;

            onCD(command, dir, function(error, json) {
                var path;

                if (json.path) {
                    path                = json.path;
                    ClientDirs[connNum] = path;
                }

                callback(json);
            });
        }

        if (!ret) {
            if (WIN)
                command    = 'cmd /C ' + command;

            if (!ClientFuncs[connNum])
                ClientFuncs[connNum] = Util.exec.with(setExec, function(json, error, stderr) {
                    log(connNum, error, 'error');
                    log(connNum, stderr, 'stderror');

                    Util.exec(callback, json);
                });

            funcExec        = ClientFuncs[connNum];
            firstChar       = command[0];

            if (firstChar === '#') {
                command     = command.slice(1);
                command     = connName + command;
                command     = addNewLine(command);

                Util.exec(callback, {
                    stdout: command
                }, true);
            } else if (WIN || firstChar === ' ' || isSymbol)
                exec(command, options, funcExec);
            else
                setSpawn(command, options, callback);
        }
    }

    /**
     * function send result of command to client
     * @param callback
     */
    function setExec(callback, error, stdout, stderr) {
        var json,
            errorStr    = '';

        if (stderr)
            errorStr    = stderr;
        else if (error)
            errorStr    = error.message;

        json            = {
            stdout : stdout,
            stderr : errorStr
        };

        Util.exec(callback, json, error, stderr);
    }

    function setSpawn(сommand, options, callback) {
        var cmd, error,
            isSended    = false,
            args        = сommand.split(' '),
            send        = function(error, data) {
                isSended = true;

                callback({
                    stderr: error,
                    stdout: data
                });
            },
            sendError     = function(error) {
                isSended = true;

                send(error, null);
            };

        сommand    = args.shift();

        error       = Util.exec.tryLog(function() {
            cmd = spawn(сommand, args, options);
        });

        if (error) {
            sendError(error);
        } else {
            cmd.stderr.setEncoding('utf8');
            cmd.stdout.setEncoding('utf8');

            cmd.stdout.on('data', function(data) {
                send(null, data);
            });

            cmd.stderr.on('data', function(error) {
                sendError(error);
            });

            cmd.on('error', function(error) {
                var errorStr    = addNewLine(error + '');

                Util.log(error);
                sendError(errorStr);
            });

            cmd.on('close', function () {
                cmd = null;

                if (!isSended)
                    send(null, null);
            });
        }
    }

    function onCloudCmd(command, callback) {
        var is;

        command = Util.rmStr(command, CLOUDCMD);
        is      = !equalPart(command, ' ');

        if (is) {
            Util.exec(callback, HELP);
        } else {
            command = Util.rmStr(command, ' ');
            is  = update && equalPart(command, 'update');

            if (is) {
                update.get();

                Util.exec(callback, {
                    stdout: addNewLine('update: ok')
                });
            }

            is = Util.strCmp(command, 'exit');

            if (is)
                process.exit();
        }

        return is;
    }

     function onCD(command, currDir, callback) {
        var CD              = 'cd ',
            HOME            = process.env.HOME,

            isChangeVolume  = win.isChangeVolume(command),
            isVolume        = win.isVolume(command),
            paramDir        = Util.rmStrOnce(command, [CD, 'cd']),

            regExpHome      = new RegExp('^~'),
            regExpRoot      = new RegExp('^[/\\\\]'),

            isWildCard      = Util.isContainStr(paramDir, ['*', '?']),
            isHome          = paramDir.match(regExpHome) && !WIN,
            isRoot          = paramDir.match(regExpRoot),

            onExec          = function (error, stdout, stderr) {
                var path        = paramDir,
                    errorStr    = '';

                if (stderr) {
                    errorStr    = stderr;
                } else if (error) {
                    errorStr    = error.message;
                    path        = '';
                }

                callback(error || stderr, {
                    stderr  : addNewLine(errorStr),
                    stdout  : stdout,
                    path    : path
                });
            };

        if (isHome) {
            command     = command.replace('~', HOME);
            paramDir    = paramDir.replace('~', HOME);
        }

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

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

            command     = Util.rmStrOnce(command, [
                CD,
                paramDir,
                '\'' + paramDir + '\'',
                '"'  + paramDir + '"',
            ]);

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

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

        if (!isWildCard)
            exec(command, {cwd: paramDir}, onExec);
        else
            find(paramDir, function(error, dirs) {
                var dir;

                if (!error)
                    dir = dirs[0];

                paramDir = dir;
                exec(command, {cwd: dir}, onExec);
            });
    }

    function getFirstWord(str) {
        var word, result,
            regStrEnd       = getRegStrEnd(),
            regStr          = '^(.*?)',
            regStrQuotes    = '^"(.*)"',
            regExp          = new RegExp(regStr + regStrEnd),
            regExpQuotes    = new RegExp(regStrQuotes + regStrEnd + '?'),
            is              = Util.isString(str);

        if (is) {
            result  = str.match(regExpQuotes);

            if (result) {
                word    = result[1];
            } else {
                result  = str.match(regExp);
                word    = result && result[1];
            }

            if (!word)
                word    = str;
        }

        return word;
    }

    function getRegStrEnd() {
        var regStrEnd = '(\\s|\\;|&&|\\|\\|)';

        return regStrEnd;
    }

    function log(connNum, str, typeParam) {
        var ret,
            type       = ' ';

        if (str) {

            if (typeParam)
                type  += typeParam + ':';

            ret        = 'client #' + connNum + type + str;

            Util.log(ret);
        }

        return ret;
    }
})();
<|endoftext|>