<commit_before>/*
 * NodeJS HL7 Server
 * Copyright (c) 2012 Eric Kryski
 * MIT Licensed
 */

var net = require('net'),
    util = require('util'),
    EventEmitter = require('events').EventEmitter,
    hl7 = require('./parser.js'),
    xml2js = require('xml2js'),
    fs = require('fs');

/*
 * Supported HL7 protocol version
 */

exports.protocol = '2.6';

/**
 * Creates a HL7 Server
 *
 * @param String host to listen for HL7 data
 * @param Integer port to listen to HL7 data - default is 59895
 * @param {Object} options
 * @api public
 */

function Server(host, port, options) {
    var self = this;

    // Needed to convert this constructor into EventEmitter
    EventEmitter.call(this);

    options = options || {};
    this.host = host || '127.0.0.1';
    this.port = port || 59895;
    this.debug = options.debug || false;
    this.json = options.json || true;

    var parser = new xml2js.Parser();
    var responseMessageNumber = 0;

    // TODO: Build up proper ACKS
    var applicationAcceptACK = 'MSH|^~\\&|||||20121217154325.194-0700||ACK^RO1|101|T|2.6\nMSA|AA|17';
    var applicationErrorACK = 'MSH|^~\\&|NES|NINTENDO|TESTSYSTEM|TESTFACILITY|20121217158325.194-0700||ACK^RO1|101|T|2.6\nMSA|AE|17';

    // Bind to TCP socket for HL7
    this.socket = net.createServer({ allowHalfOpen: false}, function(socket){

        socket.setEncoding("utf8");

        function handleError(error){
            socket.write(applicationErrorACK);

            self.emit('error', error);
            console.log("HL7 TCP Server ERROR: ", error);
        }

        function createEL7AckForMessageNumber(messageNumber) {
      var ack = 'MSH|^~\\&|MediDoc||HSTPathways||' + generateTimeStamp() + '|1100|ACK^RO1|'+ messageNumber +'|P|2.3\rMSA|AA|' + messageNumber + '|MSG Received Successfully\r';
            return ack;
        }

        function zeroFill( number, width ) {
            width -= number.toString().length;
            if ( width > 0 ) {
                return new Array( width + (/\./.test( number ) ? 2 : 1) ).join( '0' ) + number;
            }
            return number + ""; // always return a string
        }

        function generateTimeStamp() {
            var now = new Date();

            var month = zeroFill(now.getUTCMonth() + 1, 2);
            var date = zeroFill(now.getUTCDate(), 2);
            var hours = zeroFill(now.getUTCHours(), 2);
            var minutes = zeroFill(now.getUTCMinutes(), 2);
            var seconds = zeroFill(now.getUTCSeconds(), 2);

            var timestamp = now.getUTCFullYear().toString()
                + month
                + date
                + hours
                + minutes
                + seconds
                + '.'
                + now.getUTCMilliseconds().toString()
                + '+0000'
            return timestamp;
        }

        function getUniqueMessageNumber() {
            responseMessageNumber = responseMessageNumber + 1;
            return responseMessageNumber;
        }

        function createXMLAckForMessageNumber(messageNumber) {
            var ack = String.fromCharCode(0x0b) + '<?xml version="1.0" encoding="UTF-8"?>' +
                '\n<ACK xmlns="urn:hl7-org:v2xml">'+
                '\n<MSH>' +
                '\n<MSH.1>|</MSH.1>' +
                '\n<MSH.2>^~\&</MSH.2>' +
                '\n<MSH.7>' + generateTimeStamp() + '</MSH.7>' +
                '\n<MSH.9>' +
                '\n<MSG.1>ACK</MSG.1>' +
                '\n<MSG.2>R01</MSG.2>' +
                '\n</MSH.9>' +
                '\n<MSH.10>' + getUniqueMessageNumber() + '</MSH.10>' +
                '\n<MSH.11>' +
                '\n<PT.1>T</PT.1>' +
                '\n</MSH.11>' +
                '\n<MSH.12>' +
                '\n<VID.1>2.6</VID.1>' +
                '\n</MSH.12>' +
                '\n</MSH>' +
                '\n<MSA>' +
                '\n<MSA.1>AA</MSA.1>' +
                '\n<MSA.2>' + messageNumber +'</MSA.2>' +
                '\n</MSA>' +
                '\n</ACK>\n' + String.fromCharCode(0x1c) + '\r';
            console.log("Generated ACK: " + ack);
            return ack;
        }

        function handleXML(xml, sendEL7Ack, packet){
            parser.parseString(xml, function(error, result){
                if (error) return handleError(error);

                if (self.debug) {
                    console.log("Message: ", util.inspect(result, false, 7, true));
                    console.log('Sending ACK');
                }
                self.emit('hl7', result, packet);

                //console.log(result.ADT_A08);

                var messageNumber = 0;

                for (var key in result) {
                    if (result.hasOwnProperty(key)) {
                        if (result[key].MSH) {
                            var msg = result[key].MSH[0]["MSH.10"][0];
                            messageNumber = msg;
                        }
                    }
                }

                console.log("Sending ACK for messageNumber "+messageNumber);

                if (sendEL7Ack) {
                    var ack = createEL7AckForMessageNumber(messageNumber);
                    socket.write(ack);
                }
                else {
                    var ack = createXMLAckForMessageNumber(messageNumber);
                    socket.write(new Buffer(ack, encoding = "utf8"));
                }
                //socket.end();
            });
        }

        socket.on('connect', function() {
            if (self.debug) {
                var now = new Date();
                console.log(now + " - HL7 TCP Client Connected");
            }
        });

        socket.on('data', function(packet) {
            if (self.debug) {
                console.log(packet);
            }

            if (!packet) return handleError(new Error('Packet is empty'));

            // It is XML format
            if (packet.indexOf('<?xml') !== -1) {
                handleXML(packet.trim(), false, packet.trim());
            }
            // It is EL7 format
            else {
                hl7.toXml(packet, function(error, xml){
                    if (error) return handleError(error);

                    handleXML(xml, true, packet);
                });
            }
        });

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

        socket.on('close', function(){
            if (self.debug) {
                var now = new Date();
                console.log(now + " - HL7 TCP Server Disconnected");
            }

            self.emit('close');
        });

        socket.on('end', function() {
            if (self.debug) {
                var now = new Date();
                console.log(now + " - HL7 TCP Client Disconnected");
            }

            self.emit('end');
        });
    });

    this.socket.listen( this.port, function(){
        var address = this.socket.address();
        console.log("HL7 TCP Server listening on: " + address.address + ":" + address.port);
    });
}

// Needed to convert this constructor into EventEmitter
util.inherits(Server, EventEmitter);

/**
 * Expose HL7 Server constructor
 */
exports = module.exports = Server;
<commit_msg>this handling using arrow function<commit_after>/*
 * NodeJS HL7 Server
 * Copyright (c) 2012 Eric Kryski
 * MIT Licensed
 */

var net = require('net'),
    util = require('util'),
    EventEmitter = require('events').EventEmitter,
    hl7 = require('./parser.js'),
    xml2js = require('xml2js'),
    fs = require('fs');

/*
 * Supported HL7 protocol version
 */

exports.protocol = '2.6';

/**
 * Creates a HL7 Server
 *
 * @param String host to listen for HL7 data
 * @param Integer port to listen to HL7 data - default is 59895
 * @param {Object} options
 * @api public
 */

function Server(host, port, options) {
    var self = this;

    // Needed to convert this constructor into EventEmitter
    EventEmitter.call(this);

    options = options || {};
    this.host = host || '127.0.0.1';
    this.port = port || 59895;
    this.debug = options.debug || false;
    this.json = options.json || true;

    var parser = new xml2js.Parser();
    var responseMessageNumber = 0;

    // TODO: Build up proper ACKS
    var applicationAcceptACK = 'MSH|^~\\&|||||20121217154325.194-0700||ACK^RO1|101|T|2.6\nMSA|AA|17';
    var applicationErrorACK = 'MSH|^~\\&|NES|NINTENDO|TESTSYSTEM|TESTFACILITY|20121217158325.194-0700||ACK^RO1|101|T|2.6\nMSA|AE|17';

    // Bind to TCP socket for HL7
    this.socket = net.createServer({ allowHalfOpen: false}, function(socket){

        socket.setEncoding("utf8");

        function handleError(error){
            socket.write(applicationErrorACK);

            self.emit('error', error);
            console.log("HL7 TCP Server ERROR: ", error);
        }

        function createEL7AckForMessageNumber(messageNumber) {
      var ack = 'MSH|^~\\&|MediDoc||HSTPathways||' + generateTimeStamp() + '|1100|ACK^RO1|'+ messageNumber +'|P|2.3\rMSA|AA|' + messageNumber + '|MSG Received Successfully\r';
            return ack;
        }

        function zeroFill( number, width ) {
            width -= number.toString().length;
            if ( width > 0 ) {
                return new Array( width + (/\./.test( number ) ? 2 : 1) ).join( '0' ) + number;
            }
            return number + ""; // always return a string
        }

        function generateTimeStamp() {
            var now = new Date();

            var month = zeroFill(now.getUTCMonth() + 1, 2);
            var date = zeroFill(now.getUTCDate(), 2);
            var hours = zeroFill(now.getUTCHours(), 2);
            var minutes = zeroFill(now.getUTCMinutes(), 2);
            var seconds = zeroFill(now.getUTCSeconds(), 2);

            var timestamp = now.getUTCFullYear().toString()
                + month
                + date
                + hours
                + minutes
                + seconds
                + '.'
                + now.getUTCMilliseconds().toString()
                + '+0000'
            return timestamp;
        }

        function getUniqueMessageNumber() {
            responseMessageNumber = responseMessageNumber + 1;
            return responseMessageNumber;
        }

        function createXMLAckForMessageNumber(messageNumber) {
            var ack = String.fromCharCode(0x0b) + '<?xml version="1.0" encoding="UTF-8"?>' +
                '\n<ACK xmlns="urn:hl7-org:v2xml">'+
                '\n<MSH>' +
                '\n<MSH.1>|</MSH.1>' +
                '\n<MSH.2>^~\&</MSH.2>' +
                '\n<MSH.7>' + generateTimeStamp() + '</MSH.7>' +
                '\n<MSH.9>' +
                '\n<MSG.1>ACK</MSG.1>' +
                '\n<MSG.2>R01</MSG.2>' +
                '\n</MSH.9>' +
                '\n<MSH.10>' + getUniqueMessageNumber() + '</MSH.10>' +
                '\n<MSH.11>' +
                '\n<PT.1>T</PT.1>' +
                '\n</MSH.11>' +
                '\n<MSH.12>' +
                '\n<VID.1>2.6</VID.1>' +
                '\n</MSH.12>' +
                '\n</MSH>' +
                '\n<MSA>' +
                '\n<MSA.1>AA</MSA.1>' +
                '\n<MSA.2>' + messageNumber +'</MSA.2>' +
                '\n</MSA>' +
                '\n</ACK>\n' + String.fromCharCode(0x1c) + '\r';
            console.log("Generated ACK: " + ack);
            return ack;
        }

        function handleXML(xml, sendEL7Ack, packet){
            parser.parseString(xml, function(error, result){
                if (error) return handleError(error);

                if (self.debug) {
                    console.log("Message: ", util.inspect(result, false, 7, true));
                    console.log('Sending ACK');
                }
                self.emit('hl7', result, packet);

                //console.log(result.ADT_A08);

                var messageNumber = 0;

                for (var key in result) {
                    if (result.hasOwnProperty(key)) {
                        if (result[key].MSH) {
                            var msg = result[key].MSH[0]["MSH.10"][0];
                            messageNumber = msg;
                        }
                    }
                }

                console.log("Sending ACK for messageNumber "+messageNumber);

                if (sendEL7Ack) {
                    var ack = createEL7AckForMessageNumber(messageNumber);
                    socket.write(ack);
                }
                else {
                    var ack = createXMLAckForMessageNumber(messageNumber);
                    socket.write(new Buffer(ack, encoding = "utf8"));
                }
                //socket.end();
            });
        }

        socket.on('connect', function() {
            if (self.debug) {
                var now = new Date();
                console.log(now + " - HL7 TCP Client Connected");
            }
        });

        socket.on('data', function(packet) {
            if (self.debug) {
                console.log(packet);
            }

            if (!packet) return handleError(new Error('Packet is empty'));

            // It is XML format
            if (packet.indexOf('<?xml') !== -1) {
                handleXML(packet.trim(), false, packet.trim());
            }
            // It is EL7 format
            else {
                hl7.toXml(packet, function(error, xml){
                    if (error) return handleError(error);

                    handleXML(xml, true, packet);
                });
            }
        });

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

        socket.on('close', function(){
            if (self.debug) {
                var now = new Date();
                console.log(now + " - HL7 TCP Server Disconnected");
            }

            self.emit('close');
        });

        socket.on('end', function() {
            if (self.debug) {
                var now = new Date();
                console.log(now + " - HL7 TCP Client Disconnected");
            }

            self.emit('end');
        });
    });

    this.socket.listen( this.port, () => {
        var address = this.socket.address();
        console.log("HL7 TCP Server listening on: " + address.address + ":" + address.port);
    });
}

// Needed to convert this constructor into EventEmitter
util.inherits(Server, EventEmitter);

/**
 * Expose HL7 Server constructor
 */
exports = module.exports = Server;
<|endoftext|>


<commit_before>var http = require('http')
var socket = require('net')
var mysql = require('mysql')

var events = require('events');
var eventEmitter = new events.EventEmitter();

module.id = 'statis'

var Statis = {
	// events: eventEmitter,
	notify: function(message)
	{
		eventEmitter.emit('result', message)
		// Statis.events.emit('result', message)
	},

	doHttp: function(node)
	{
		var node_label = node.label
		var request = http.request(
			node.http,
			function(res) {
				request.destroy()

				if (res.statusCode >= 400) {
					Statis.notify({"status": "error", "label": node_label, "message": node_label + " [ERROR] Status " + res.statusCode})
				} else {
					Statis.notify({"status": "success", "label": node_label, "message": node_label + " [OK]"})
				}
			}
		)
		request.setTimeout(2 * 1000, function() {
			request.destroy()
			Statis.notify({"status": "error", "label": node_label, "message": node_label + " [WARNING] Reached timeout"})
		})
		request.on('error', function(e) {
			Statis.notify({"status": "error", "label": node_label, "message": node_label + " [ERROR] " + e.message})
		})
		request.end()
	},

	doSocket: function(node)
	{
		var node_label = node.label
		var s = socket.connect(node.socket.port, node.socket.host)
		s.on('connect', function() {
			s.destroy()
			Statis.notify({"status": "success", "label": node_label, "message": node_label + " [OK] "})
		}).on('error', function(e) {
			Statis.notify({"status": "error", "label": node_label, "message": node_label + " [ERROR] " + e.message})
		})
	},

	doMysql: function(node)
	{
		var node_label = node.label
		var connection = mysql.createConnection(node.mysql)
		connection.connect(function(err) {
			connection.destroy()
			if (!err) {
				Statis.notify({"status": "success", "label": node_label, "message": node_label + " [OK] "})
			} else {
				Statis.notify({"status": "error", "label": node_label, "message": node_label + " [ERROR] " + err.message})
			}
		})
	}
}

module.exports.http = function(node) { Statis.doHttp(node) }
module.exports.socket = function(node) { Statis.doSocket(node) }
module.exports.mysql = function(node) { Statis.doMysql(node) }
module.exports.on = function(event, listener) { eventEmitter.on(event, listener) }
module.exports.removeListener = function(event, listener) { eventEmitter.removeListener(event, listener) }
<commit_msg>remove [WARNING] and [ERROR]<commit_after>var http = require('http')
var socket = require('net')
var mysql = require('mysql')

var events = require('events');
var eventEmitter = new events.EventEmitter();

module.id = 'statis'

var Statis = {
	// events: eventEmitter,
	notify: function(message)
	{
		eventEmitter.emit('result', message)
		// Statis.events.emit('result', message)
	},

	doHttp: function(node)
	{
		var node_label = node.label
		var request = http.request(
			node.http,
			function(res) {
				request.destroy()

				if (res.statusCode >= 400) {
					Statis.notify({"status": "error", "label": node_label, "message": node_label + " Status " + res.statusCode})
				} else {
					Statis.notify({"status": "success", "label": node_label, "message": node_label + " [OK]"})
				}
			}
		)
		request.setTimeout(2 * 1000, function() {
			request.destroy()
			Statis.notify({"status": "error", "label": node_label, "message": node_label + " [WARNING] Reached timeout"})
		})
		request.on('error', function(e) {
			Statis.notify({"status": "error", "label": node_label, "message": node_label + " [ERROR] " + e.message})
		})
		request.end()
	},

	doSocket: function(node)
	{
		var node_label = node.label
		var s = socket.connect(node.socket.port, node.socket.host)
		s.on('connect', function() {
			s.destroy()
			Statis.notify({"status": "success", "label": node_label, "message": node_label + " [OK] "})
		}).on('error', function(e) {
			Statis.notify({"status": "error", "label": node_label, "message": node_label + " [ERROR] " + e.message})
		})
	},

	doMysql: function(node)
	{
		var node_label = node.label
		var connection = mysql.createConnection(node.mysql)
		connection.connect(function(err) {
			connection.destroy()
			if (!err) {
				Statis.notify({"status": "success", "label": node_label, "message": node_label + " [OK] "})
			} else {
				Statis.notify({"status": "error", "label": node_label, "message": node_label + " " + err.message})
			}
		})
	}
}

module.exports.http = function(node) { Statis.doHttp(node) }
module.exports.socket = function(node) { Statis.doSocket(node) }
module.exports.mysql = function(node) { Statis.doMysql(node) }
module.exports.on = function(event, listener) { eventEmitter.on(event, listener) }
module.exports.removeListener = function(event, listener) { eventEmitter.removeListener(event, listener) }
<|endoftext|>


<commit_before>// App.ApplicationAdapter = DS.RESTAdapter.extend()
App.ApplicationAdapter = DS.FixtureAdapter.extend()<commit_msg>Activate REST adapter<commit_after>App.ApplicationAdapter = DS.RESTAdapter.extend()
// App.ApplicationAdapter = DS.FixtureAdapter.extend()<|endoftext|>


<commit_before>var util = require('util');
var async = require('async');
var Transform = require('readable-stream').Transform;

/**
 * @param {Object} options
 * @param {Number} [options.concurrency]
 * @constructor
 */
function ParallelWriteStream(options) {

	options = options || {};
	this._concurrency = typeof options.concurrency == 'undefined' ? 1 : options.concurrency;
	this._storage = [];

	delete options.concurrency;
	options.highWaterMark = this._concurrency;
	options.objectMode = true;

	Transform.call(this, options);

	this.once('pipe', function () {
		this.resume();
	}.bind(this));

}
util.inherits(ParallelWriteStream, Transform);

ParallelWriteStream.prototype._transform = function (doc, encoding, callback) {
	this.push(doc);
	this._storage.push(doc);

	if (this._storage.length >= this._concurrency) {
		this._flush(callback);
	} else {
		callback(null);
	}
};

ParallelWriteStream.prototype._flush = function (callback) {
	var storage = this._storage;
	this._storage = [];
	async.each(storage, this._save.bind(this), function (err) {
		process.nextTick(function () {
			callback(err);
		});
	});
};

ParallelWriteStream.prototype._save = function (doc, callback) {
	callback(new Error('_save method is not implemented yet.'));
};

module.exports = exports = ParallelWriteStream;
<commit_msg>allow implementers to provide highWaterMark option<commit_after>var util = require('util');
var async = require('async');
var Transform = require('readable-stream').Transform;

/**
 * @param {Object} options
 * @param {Number} [options.concurrency]
 * @constructor
 */
function ParallelWriteStream(options) {

	options = options || {};
	this._concurrency = typeof options.concurrency == 'undefined' ? 1 : options.concurrency;
	this._storage = [];

	delete options.concurrency;
	options.highWaterMark = options.highWaterMark || this._concurrency;
	options.objectMode = true;

	Transform.call(this, options);

	this.once('pipe', function () {
		this.resume();
	}.bind(this));

}
util.inherits(ParallelWriteStream, Transform);

ParallelWriteStream.prototype._transform = function (doc, encoding, callback) {
	this.push(doc);
	this._storage.push(doc);

	if (this._storage.length >= this._concurrency) {
		this._flush(callback);
	} else {
		callback(null);
	}
};

ParallelWriteStream.prototype._flush = function (callback) {
	var storage = this._storage;
	this._storage = [];
	async.each(storage, this._save.bind(this), function (err) {
		process.nextTick(function () {
			callback(err);
		});
	});
};

ParallelWriteStream.prototype._save = function (doc, callback) {
	callback(new Error('_save method is not implemented yet.'));
};

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


<commit_before>import Link from 'next/link';
import GithubButton from 'react-github-button';

export default () => (

      <Link href="/">

      </Link>

        <Item href="/">Home</Item>
        <Item href="/docs">Docs</Item>
        <Item href="/gallery">Gallery</Item>

      <GithubButton
        type="stargazers"
        namespace="hshoff"
        repo="vx"
      />

)

const Item = ({ href, children, className }) => (

    <Link prefetch href={href}>
      { children }
    </Link>

)
<commit_msg>[demo] add blog link to nav<commit_after>import Link from 'next/link';
import GithubButton from 'react-github-button';

export default () => (

      <Link href="/">

      </Link>

        <Item href="/">Home</Item>
        <Item href="/docs">Docs</Item>
        <Item href="/gallery">Gallery</Item>
        <Item href="https://medium.com/vx-code">Blog</Item>

      <GithubButton
        type="stargazers"
        namespace="hshoff"
        repo="vx"
      />

)

const Item = ({ href, children, className }) => (

    <Link prefetch href={href}>
      { children }
    </Link>

)
<|endoftext|>


<commit_before>const path = require('path');
const fse = require('fs-extra'); // eslint-disable-line
const glob = require('glob'); // eslint-disable-line

function typescriptCopy(from, to) {
	const files = glob.sync('**/*.d.ts', { cwd: from });
	const cmds = files.map(file =>
		fse.copy(path.resolve(from, file), path.resolve(to, file)));
	return Promise.all(cmds);
}

async function run() {
	const from = path.resolve(__dirname, '../src');
	await typescriptCopy(from, path.resolve(__dirname, '../lib'));
}

run();
<commit_msg>web: copy typings to lib #466<commit_after>const path = require('path');
const fse = require('fs-extra'); // eslint-disable-line
const glob = require('glob'); // eslint-disable-line

function typescriptCopy(from, to) {
	const files = glob.sync('**/*.ts', { cwd: from });
	const cmds = files.map(file =>
		fse.copy(path.resolve(from, file), path.resolve(to, file)));
	return Promise.all(cmds);
}

async function run() {
	const from = path.resolve(__dirname, '../src');
	await typescriptCopy(from, path.resolve(__dirname, '../lib'));
}

run();
<|endoftext|>


<commit_before>const { multiPromisify } = require("./utils");

function shimLegacy(method) {
  return async config => {
    const compile = multiPromisify(method);

    const [contracts, sourceIndexes, compiler] = await compile(config);

    return [
      {
        contracts: shimContracts(contracts),
        sourceIndexes,
        compiler
      }
    ];
  };
}

function shimContracts(contracts) {
  // convert to list
  return Object.values(contracts).map(shimContract);
}

function shimContract(contract) {
  const {
    contractName,
    contract_name,
    sourcePath,
    source,
    sourceMap,
    deployedSourceMap,
    legacyAST,
    ast,
    abi,
    metadata,
    bytecode,
    deployedBytecode,
    compiler,
    devdoc,
    userdoc,
    immutableReferences
  } = contract;

  return {
    contractName: contract_name || contractName,
    sourcePath,
    source,
    sourceMap,
    deployedSourceMap,
    legacyAST,
    ast,
    abi,
    metadata,
    bytecode: shimBytecode(bytecode),
    deployedBytecode: shimBytecode(deployedBytecode),
    compiler,
    devdoc,
    userdoc,
    immutableReferences
  };
}

function shimBytecode(bytecode) {
  if (!bytecode) {
    return undefined;
  }
  if (typeof bytecode === "object") {
    return bytecode;
  }

  const linkReferences = [];

  const bytes = bytecode
    .slice(2) // remove 0x prefix
    .replace(/__[^_]+_*/g, (linkReference, characterOffset) => {
      const [, name] = linkReference.match(/__([^_]+)_*/);

      const characterLength = linkReference.length;

      const offset = characterOffset / 2;
      const length = characterLength / 2;

      linkReferences.push({
        offsets: [offset],
        name,
        length
      });

      return "0".repeat(characterLength);
    });

  return { bytes, linkReferences };
}

module.exports = {
  shimLegacy,
  shimContracts,
  shimContract,
  shimBytecode
};
<commit_msg>Get rid of legacy shim<commit_after>function shimContracts(contracts) {
  // convert to list
  return Object.values(contracts).map(shimContract);
}

function shimContract(contract) {
  const {
    contractName,
    contract_name,
    sourcePath,
    source,
    sourceMap,
    deployedSourceMap,
    legacyAST,
    ast,
    abi,
    metadata,
    bytecode,
    deployedBytecode,
    compiler,
    devdoc,
    userdoc,
    immutableReferences
  } = contract;

  return {
    contractName: contract_name || contractName,
    sourcePath,
    source,
    sourceMap,
    deployedSourceMap,
    legacyAST,
    ast,
    abi,
    metadata,
    bytecode: shimBytecode(bytecode),
    deployedBytecode: shimBytecode(deployedBytecode),
    compiler,
    devdoc,
    userdoc,
    immutableReferences
  };
}

function shimBytecode(bytecode) {
  if (!bytecode) {
    return undefined;
  }
  if (typeof bytecode === "object") {
    return bytecode;
  }

  const linkReferences = [];

  const bytes = bytecode
    .slice(2) // remove 0x prefix
    .replace(/__[^_]+_*/g, (linkReference, characterOffset) => {
      const [, name] = linkReference.match(/__([^_]+)_*/);

      const characterLength = linkReference.length;

      const offset = characterOffset / 2;
      const length = characterLength / 2;

      linkReferences.push({
        offsets: [offset],
        name,
        length
      });

      return "0".repeat(characterLength);
    });

  return { bytes, linkReferences };
}

module.exports = {
  shimLegacy,
  shimContracts,
  shimContract,
  shimBytecode
};
<|endoftext|>


<commit_before>import appConf from 'app-conf'
import get from 'lodash/get'
import highland from 'highland'
import levelup from 'level-party'
import ndjson from 'ndjson'
import parseArgs from 'minimist'
import sublevel from 'subleveldown'
import util from 'util'
import { join as joinPath } from 'path'

import { forEach } from './utils'
import globMatcher from './glob-matcher'

// ===================================================================

async function printLogs(db, args) {
  let stream = highland(db.createReadStream({ reverse: true }))

  if (args.since) {
    stream = stream.filter(({ value }) => value.time >= args.since)
  }

  if (args.until) {
    stream = stream.filter(({ value }) => value.time <= args.until)
  }

  const fields = Object.keys(args.matchers)

  if (fields.length > 0) {
    stream = stream.filter(({ value }) => {
      for (const field of fields) {
        const fieldValue = get(value, field)
        if (fieldValue === undefined || !args.matchers[field](fieldValue)) {
          return false
        }
      }

      return true
    })
  }

  stream = stream.take(args.limit)

  if (args.json) {
    stream = highland(stream.pipe(ndjson.serialize())).each(value => {
      process.stdout.write(value)
    })
  } else {
    stream = stream.each(value => {
      console.log(util.inspect(value, { depth: null }))
    })
  }

  return new Promise(resolve => {
    stream.done(resolve)
  })
}

// ===================================================================

function helper() {
  console.error(`
xo-server-logs --help, -h

    Display this help message.

xo-server-logs [--json] [--limit=<limit>] [--since=<date>] [--until=<date>] [<pattern>...]

    Prints the logs.

    --json
      Display the results as new line delimited JSON for consumption
      by another program.

    --limit=<limit>, -n <limit>
      Limit the number of results to be displayed (default 100)

    --since=<date>, --until=<date>
      Start showing entries on or newer than the specified date, or on
      or older than the specified date.

      <date> should use the format \`YYYY-MM-DD\`.

    <pattern>
      Patterns can be used to filter the entries.

      Patterns have the following format \`<field>=<value>\`/\`<field>\`.

xo-server-logs --repair

    Repair/compact the database.

    This is an advanced operation and should be used only when necessary and offline (xo-server should be stopped).
`)
}

// ===================================================================

function getArgs() {
  const stringArgs = ['since', 'until', 'limit']
  const args = parseArgs(process.argv.slice(2), {
    string: stringArgs,
    boolean: ['help', 'json', 'repair'],
    default: {
      limit: 100,
      json: false,
      help: false,
    },
    alias: {
      limit: 'n',
      help: 'h',
    },
  })

  const patterns = {}

  for (let value of args._) {
    value = String(value)

    const i = value.indexOf('=')

    if (i !== -1) {
      const field = value.slice(0, i)
      const pattern = value.slice(i + 1)

      patterns[pattern]
        ? patterns[field].push(pattern)
        : (patterns[field] = [pattern])
    } else if (!patterns[value]) {
      patterns[value] = null
    }
  }

  const trueFunction = () => true
  args.matchers = {}

  for (const field in patterns) {
    const values = patterns[field]
    args.matchers[field] = values === null ? trueFunction : globMatcher(values)
  }

  // Warning: minimist makes one array of values if the same option is used many times.
  // (But only for strings args, not boolean)
  forEach(stringArgs, arg => {
    if (args[arg] instanceof Array) {
      throw new Error(`error: too many values for ${arg} argument`)
    }
  })
  ;['since', 'until'].forEach(arg => {
    if (args[arg] !== undefined) {
      args[arg] = Date.parse(args[arg])

      if (isNaN(args[arg])) {
        throw new Error(`error: bad ${arg} timestamp format`)
      }
    }
  })

  if (isNaN((args.limit = +args.limit))) {
    throw new Error('error: limit is not a valid number')
  }

  return args
}

// ===================================================================

export default async function main() {
  const args = getArgs()

  if (args.help) {
    helper()
    return
  }

  const config = await appConf.load('xo-server', {
    appDir: joinPath(__dirname, '..'),
    ignoreUnknownFormats: true,
  })

  if (args.repair) {
    // eslint-disable-next-line node/no-extraneous-require
    const { repair } = require(require.resolve('level', {
      paths: [require.resolve('level-party')],
    }))
    await new Promise((resolve, reject) => {
      repair(`${config.datadir}/leveldb`, error => {
        if (error) {
          reject(error)
        } else {
          resolve()
        }
      })
    })

    return
  }

  const db = sublevel(
    levelup(`${config.datadir}/leveldb`, { valueEncoding: 'json' }),
    'logs',
    {
      valueEncoding: 'json',
    }
  )

  return printLogs(db, args)
}
<commit_msg>feat(xo-server/logs-cli): implement `--gc`<commit_after>import appConf from 'app-conf'
import get from 'lodash/get'
import highland from 'highland'
import levelup from 'level-party'
import ndjson from 'ndjson'
import parseArgs from 'minimist'
import sublevel from 'subleveldown'
import util from 'util'
import { join as joinPath } from 'path'

import { forEach } from './utils'
import globMatcher from './glob-matcher'

// ===================================================================

const GC_KEEP = 2e4

const gc = (db, args) =>
  new Promise((resolve, reject) => {
    let keep = GC_KEEP

    let count = 1
    const cb = () => {
      if (--count === 0) {
        resolve()
      }
    }
    const stream = db.createKeyStream({
      reverse: true,
    })

    const deleteEntry = key => {
      ++count
      db.del(key, cb)
    }

    let onData =
      keep !== 0
        ? () => {
            if (--keep === 0) {
              stream.removeListener('data', onData)
              onData = deleteEntry
              stream.on('data', onData)
            }
          }
        : deleteEntry
    const onEnd = () => {
      console.log('end')
      removeListeners()
      cb()
    }
    const onError = error => {
      console.log('error')
      removeListeners()
      reject(error)
    }
    const removeListeners = () => {
      stream
        .removeListener('data', onData)
        .removeListener('end', onEnd)
        .removeListener('error', onError)
    }
    stream.on('data', onData).on('end', onEnd).on('error', onError)
  })

async function printLogs(db, args) {
  let stream = highland(db.createReadStream({ reverse: true }))

  if (args.since) {
    stream = stream.filter(({ value }) => value.time >= args.since)
  }

  if (args.until) {
    stream = stream.filter(({ value }) => value.time <= args.until)
  }

  const fields = Object.keys(args.matchers)

  if (fields.length > 0) {
    stream = stream.filter(({ value }) => {
      for (const field of fields) {
        const fieldValue = get(value, field)
        if (fieldValue === undefined || !args.matchers[field](fieldValue)) {
          return false
        }
      }

      return true
    })
  }

  stream = stream.take(args.limit)

  if (args.json) {
    stream = highland(stream.pipe(ndjson.serialize())).each(value => {
      process.stdout.write(value)
    })
  } else {
    stream = stream.each(value => {
      console.log(util.inspect(value, { depth: null }))
    })
  }

  return new Promise(resolve => {
    stream.done(resolve)
  })
}

// ===================================================================

function helper() {
  console.error(`
xo-server-logs --help, -h

    Display this help message.

xo-server-logs [--json] [--limit=<limit>] [--since=<date>] [--until=<date>] [<pattern>...]

    Prints the logs.

    --json
      Display the results as new line delimited JSON for consumption
      by another program.

    --limit=<limit>, -n <limit>
      Limit the number of results to be displayed (default 100)

    --since=<date>, --until=<date>
      Start showing entries on or newer than the specified date, or on
      or older than the specified date.

      <date> should use the format \`YYYY-MM-DD\`.

    <pattern>
      Patterns can be used to filter the entries.

      Patterns have the following format \`<field>=<value>\`/\`<field>\`.

xo-server-logs --gc

    Remove all but the ${GC_KEEP}th most recent log entries.

xo-server-logs --repair

    Repair/compact the database.

    This is an advanced operation and should be used only when necessary and offline (xo-server should be stopped).
`)
}

// ===================================================================

function getArgs() {
  const stringArgs = ['since', 'until', 'limit']
  const args = parseArgs(process.argv.slice(2), {
    string: stringArgs,
    boolean: ['help', 'json', 'gc', 'repair'],
    default: {
      limit: 100,
      json: false,
      help: false,
    },
    alias: {
      limit: 'n',
      help: 'h',
    },
  })

  const patterns = {}

  for (let value of args._) {
    value = String(value)

    const i = value.indexOf('=')

    if (i !== -1) {
      const field = value.slice(0, i)
      const pattern = value.slice(i + 1)

      patterns[pattern]
        ? patterns[field].push(pattern)
        : (patterns[field] = [pattern])
    } else if (!patterns[value]) {
      patterns[value] = null
    }
  }

  const trueFunction = () => true
  args.matchers = {}

  for (const field in patterns) {
    const values = patterns[field]
    args.matchers[field] = values === null ? trueFunction : globMatcher(values)
  }

  // Warning: minimist makes one array of values if the same option is used many times.
  // (But only for strings args, not boolean)
  forEach(stringArgs, arg => {
    if (args[arg] instanceof Array) {
      throw new Error(`error: too many values for ${arg} argument`)
    }
  })
  ;['since', 'until'].forEach(arg => {
    if (args[arg] !== undefined) {
      args[arg] = Date.parse(args[arg])

      if (isNaN(args[arg])) {
        throw new Error(`error: bad ${arg} timestamp format`)
      }
    }
  })

  if (isNaN((args.limit = +args.limit))) {
    throw new Error('error: limit is not a valid number')
  }

  return args
}

// ===================================================================

export default async function main() {
  const args = getArgs()

  if (args.help) {
    helper()
    return
  }

  const config = await appConf.load('xo-server', {
    appDir: joinPath(__dirname, '..'),
    ignoreUnknownFormats: true,
  })

  if (args.repair) {
    // eslint-disable-next-line node/no-extraneous-require
    const { repair } = require(require.resolve('level', {
      paths: [require.resolve('level-party')],
    }))
    await new Promise((resolve, reject) => {
      repair(`${config.datadir}/leveldb`, error => {
        if (error) {
          reject(error)
        } else {
          resolve()
        }
      })
    })

    return
  }

  const db = sublevel(
    levelup(`${config.datadir}/leveldb`, { valueEncoding: 'json' }),
    'logs',
    {
      valueEncoding: 'json',
    }
  )

  return args.gc ? gc(db) : printLogs(db, args)
}
<|endoftext|>


<commit_before>/**
 * Created by nitaip on 19/07/2015.
 */

var divBase = '

Repository	Title	Author	Reviewers			Source	Destination	Updated

';

function host(uri) {
    return localStorage["settings.server"] + uri;
}

function mkTD(pr, tdType) {
    switch (tdType) {
        case 'repository':
            return $(
                '' +
                '' +
                '' +
                '' +
                '' +
                '' +
                '' + pr['fromRef']['repository']['name'] + '' +
                '	'
            );
        case 'title':
            return $(
                '' +
                '' + pr['title'] + '' +
                '	');
        case 'author':
            return $(
                '' +
                '
' +
                '' +
                '' +
                '' +
                '' + pr['author']['user']['displayName'] + '' +
                '
' +
                '	');
        case 'reviewers':
            var td = $('	');
            var revs = _.sortBy(pr['reviewers'],
                function (rev) {
                    return -1 * (rev.user.id);
                });
            revs.forEach(function (rev) {
                td.append($(
                    '' +
                    '' +
                    '' +
                    '' +
                    '?' +
                    ''
                ));
            });
            return td;

        case 'comment-count':
            var comments = pr['attributes']['commentCount'] || 0;
            var td_comm = $('	');
            if (Number(comments)) {
                td_comm.append($(
                    '' +
                    '' + comments + ' comments' + comments + '' +
                    ''
                ));
            }
            return td_comm;

        case 'task-count':
            var tasks = pr['attributes']['openTaskCount'] || 0;
            var td_tasks = $('	');
            if (Number(tasks)) {
                td_tasks.append($(
                    '' +
                    '' +
                    'Open tasks: ' +
                    '' + tasks + ''
                ));
            }
            return td_tasks;

        case 'source':
            return $('' +
                '' +
                '' +
                '' + pr['fromRef']['displayId'] + '' +
                '' +
                '' +
                '	');

        case 'destination':
            return $(
                '' +
                '' +
                '' +
                '' + pr['toRef']['displayId'] + '' +
                '' +
                '' +
                '	');

        case 'updated':
            return $('<time title="16 July 2015 04:37 PM" datetime="2015-07-16T16:37:07+0300">2 days ago</time>	');

        default:
            return $('	');
    }
}

function mkTR(pr) {
    var tr = $('

');
    var tds = ['repository', 'title', 'author', 'reviewers', 'comment-count', 'task-count', 'source', 'destination', 'updated'];
    tds.forEach(function (tdType) {
        tr.append(mkTD(pr, tdType));
    });
    return tr;
}

function mkDIV() {
    var div = $(divBase);
    var data = JSON.parse(localStorage.prData);
    data.values.forEach(function (pr) {
        div.find('tbody').append(mkTR(pr));
    });
    return div.html();
}<commit_msg>Fixed popup text.<commit_after>/**
 * Created by nitaip on 19/07/2015.
 */

var divBase = '

Repository	Title	Author	Reviewers			Source	Destination	Updated

';

function host(uri) {
    return localStorage["settings.server"] + uri;
}

function mkTD(pr, tdType) {
    switch (tdType) {
        case 'repository':
            return $(
                '' +
                '' +
                '' +
                '' +
                '' +
                '' +
                '' + pr['fromRef']['repository']['name'] + '' +
                '	'
            );
        case 'title':
            return $(
                '' +
                '' + pr['title'] + '' +
                '	');
        case 'author':
            return $(
                '' +
                '
' +
                '' +
                '' +
                '' +
                '' + pr['author']['user']['displayName'] + '' +
                '
' +
                '	');
        case 'reviewers':
            var td = $('	');
            var revs = _.sortBy(pr['reviewers'],
                function (rev) {
                    return -1 * (rev.user.id);
                });
            revs.forEach(function (rev) {
                td.append($(
                    '' +
                    '' +
                    '' +
                    '' +
                    '?' +
                    ''
                ));
            });
            return td;

        case 'comment-count':
            var comments = pr['attributes']['commentCount'] || 0;
            var td_comm = $('	');
            if (Number(comments)) {
                td_comm.append($(
                    '' +
                    '' + comments + ' comments' + comments + '' +
                    ''
                ));
            }
            return td_comm;

        case 'task-count':
            var tasks = pr['attributes']['openTaskCount'] || 0;
            var td_tasks = $('	');
            if (Number(tasks)) {
                td_tasks.append($(
                    '' +
                    '' +
                    'Open tasks: ' +
                    '' + tasks + ''
                ));
            }
            return td_tasks;

        case 'source':
            return $('' +
                '' +
                '' +
                '' + pr['fromRef']['displayId'] + '' +
                '' +
                '' +
                '	');

        case 'destination':
            return $(
                '' +
                '' +
                '' +
                '' + pr['toRef']['displayId'] + '' +
                '' +
                '' +
                '	');

        case 'updated':
            return $('<time title="16 July 2015 04:37 PM" datetime="2015-07-16T16:37:07+0300">2 days ago</time>	');

        default:
            return $('	');
    }
}

function mkTR(pr) {
    var tr = $('

');
    var tds = ['repository', 'title', 'author', 'reviewers', 'comment-count', 'task-count', 'source', 'destination', 'updated'];
    tds.forEach(function (tdType) {
        tr.append(mkTD(pr, tdType));
    });
    return tr;
}

function mkDIV() {
    var div = $(divBase);
    var data = JSON.parse(localStorage.prData);
    data.values.forEach(function (pr) {
        div.find('tbody').append(mkTR(pr));
    });
    return div.html();
}<|endoftext|>


<commit_before>/* eslint camelcase: 0 */
const { get, assign } = require('lodash')

const {
  accessTokenForInstallation,
  branchHasFixup,
  createCommitStatus
} = require('../github')

const { log } = require('../logging')

/* POST Github hook
 * Accepts a webhook call from Github details a Git Push.
 * Analyses the push and sets a status to indicate if the
 * branch if belongs to has a fixup commit
 * 'success' indicates no fixups
 * 'failure' indicates branch contains a fixup
*/
async function postHook (req, res, next) {
  try {
    const eventType = get(req, 'headers.x-github-event', 'n/a')

    if (eventType !== 'push') {
      log({ text: `Invalid event, ignoring: ${eventType}` })
      return res.status(202).send('Invalid event, ignoring')
    }

    const pushData = req.body
    const { default_branch: defaultBranch, full_name: repoName } = pushData.repository
    const branch = pushData.ref.substr(11)
    const headCommit = get(pushData, 'head_commit.id')
    const installationId = get(pushData, 'installation.id')

    if (!headCommit) {
      log({ text: 'Ignoring event, no commits to analyse' })
      return res.status(202).send('Ignoring event, no commits to analyse')
    }

    if (branch === defaultBranch) {
      log({ text: 'Ignoring event, default branch' })
      return res.status(202).send('Ignoring event, default branch')
    }

    log({ text: 'Processing hook',
      fields: {
        'Repository': repoName,
        'Branch': branch
      }
    })

    const token = await accessTokenForInstallation(installationId)
    const hasFixup = await branchHasFixup({ token, repoName, branch, defaultBranch })
    const baseStatus = { token, repoName, sha: headCommit }
    const status = hasFixup
      ? assign({}, baseStatus, { state: 'failure', description: 'Branch contains fixup!' })
      : assign({}, baseStatus, { state: 'success', description: 'No fixups found' })

    log({
      text: status.description,
      status: status.state,
      fields: {
        'Repository': repoName,
        'Branch': branch
      }
    })

    await createCommitStatus(status)
  } catch (error) {
    await log({ error })
    return res.status(500).send(error.message)
  }

  res.status(200).send('Webhook handled successfully')
}

module.exports = { postHook }
<commit_msg>Call google analytics event logger<commit_after>/* eslint camelcase: 0 */
const { get, assign } = require('lodash')

const {
  accessTokenForInstallation,
  branchHasFixup,
  createCommitStatus
} = require('../github')

const { log, logEvent } = require('../logging')

/* POST Github hook
 * Accepts a webhook call from Github details a Git Push.
 * Analyses the push and sets a status to indicate if the
 * branch if belongs to has a fixup commit
 * 'success' indicates no fixups
 * 'failure' indicates branch contains a fixup
*/
async function postHook (req, res, next) {
  try {
    const eventType = get(req, 'headers.x-github-event', 'n/a')

    if (eventType !== 'push') {
      log({ text: `Invalid event, ignoring: ${eventType}` })
      return res.status(202).send('Invalid event, ignoring')
    }

    const pushData = req.body
    const { default_branch: defaultBranch, full_name: repoName } = pushData.repository
    const branch = pushData.ref.substr(11)
    const headCommit = get(pushData, 'head_commit.id')
    const installationId = get(pushData, 'installation.id')

    if (!headCommit) {
      log({ text: 'Ignoring event, no commits to analyse' })
      return res.status(202).send('Ignoring event, no commits to analyse')
    }

    if (branch === defaultBranch) {
      log({ text: 'Ignoring event, default branch' })
      return res.status(202).send('Ignoring event, default branch')
    }

    log({ text: 'Processing hook',
      fields: {
        'Repository': repoName,
        'Branch': branch
      }
    })

    const token = await accessTokenForInstallation(installationId)
    const hasFixup = await branchHasFixup({ token, repoName, branch, defaultBranch })
    const baseStatus = { token, repoName, sha: headCommit }
    const status = hasFixup
      ? assign({}, baseStatus, { state: 'failure', description: 'Branch contains fixup!' })
      : assign({}, baseStatus, { state: 'success', description: 'No fixups found' })

    await createCommitStatus(status)

    await log({
      text: status.description,
      status: status.state,
      fields: {
        'Repository': repoName,
        'Branch': branch
      }
    })

    await logEvent(status.state)
  } catch (error) {
    await log({ error })
    return res.status(500).send(error.message)
  }

  res.status(200).send('Webhook handled successfully')
}

module.exports = { postHook }
<|endoftext|>


<commit_before>import { Forbidden } from 'feathers-errors';
import fp from 'mostly-func';
import { AceBuilder, Aces, toMongoQuery } from 'playing-permissions';
import { getHookDataAsArray } from '../helpers';

function getPermissions(user) {
  if (user) {
    const groupPermissions = fp.flatMap(fp.path(['group', 'permissions']), user.groups || []);
    return fp.concat(groupPermissions, user.permissions || []);
  }
  return [];
}

function defineAcesFor(permissions, { TypeKey = 'type' }) {
  const builder = new AceBuilder();

  for (const permission of permissions) {
    builder.allow(permission);
  }

  return new Aces(builder.rules, { TypeKey });
}

export default function authorize(name = null, opts = {}) {
  const TypeKey = opts.TypeKey || 'type';

  return async function(context) {
    if (context.type !== 'before') {
      throw new Error(`The 'authorize' hook should only be used as a 'before' hook.`);
    }

    let params = fp.assign({ query: {} }, context.params);

    // If it was an internal call then skip this hook
    if (!params.provider) return context;

    const action = params.__action || context.method;
    const serviceName = name || context.path;

    const userPermissions = getPermissions(params.user);
    const userAces = defineAcesFor(userPermissions , { TypeKey });

    const throwDisallowed = (action, resources) => {
      let disallow = true;
      // reverse loop to check inheritance
      for (let i = resources.length - 1; i >= 0; i--) {
        if (!resources[i]) break;
        const resource = fp.assoc(TypeKey, resources[i][TypeKey] || serviceName, resources[i]);
        disallow = disallow && userAces.disallow(action, resource);
        if (!resource.inherited) break;
      }
      if (disallow) {
        throw new Forbidden(`You are not allowed to ${action} ${resources[0] && resources[0].id}, with ${context.path}/${context.id}`);
      }
    };

    if (context.method === 'create') {
      throwDisallowed('create', [context.data]);
    }

     // find, multi update/patch/remove
    if (!context.id) {
      const rules = userAces.rulesFor(action, serviceName);
      const query = toMongoQuery(rules);

      if (query) {
        params.query = fp.assign(params.query, query);
      } else {
        params.query.$limit = 0; // TODO skip the mongoose query
      }

      context.params = params;
      return context;
    }
    // get, update, patch, remove, action
    else {
      // get the resource by id for checking permissions
      const resource = await context.service.get(context.id, {
        query: { $select: 'ancestors,*' }
      });
      throwDisallowed(action, fp.concat(resource && resource.ancestors || [], [resource]));

      return context;
    }
  };
}
<commit_msg>Fix get group permissions in authorize<commit_after>import { Forbidden } from 'feathers-errors';
import fp from 'mostly-func';
import { AceBuilder, Aces, toMongoQuery } from 'playing-permissions';
import { getHookDataAsArray } from '../helpers';

function getPermissions(user) {
  if (user) {
    const groupPermissions = fp.flatMap(fp.pathOr([], ['group', 'permissions']), user.groups || []);
    return fp.concat(groupPermissions, user.permissions || []);
  }
  return [];
}

function defineAcesFor(permissions, { TypeKey = 'type' }) {
  const builder = new AceBuilder();

  for (const permission of permissions) {
    builder.allow(permission);
  }

  return new Aces(builder.rules, { TypeKey });
}

export default function authorize(name = null, opts = {}) {
  const TypeKey = opts.TypeKey || 'type';

  return async function(context) {
    if (context.type !== 'before') {
      throw new Error(`The 'authorize' hook should only be used as a 'before' hook.`);
    }

    let params = fp.assign({ query: {} }, context.params);

    // If it was an internal call then skip this hook
    if (!params.provider) return context;

    const action = params.__action || context.method;
    const serviceName = name || context.path;

    const userPermissions = getPermissions(params.user);
    const userAces = defineAcesFor(userPermissions , { TypeKey });

    const throwDisallowed = (action, resources) => {
      let disallow = true;
      // reverse loop to check inheritance
      for (let i = resources.length - 1; i >= 0; i--) {
        if (!resources[i]) break;
        const resource = fp.assoc(TypeKey, resources[i][TypeKey] || serviceName, resources[i]);
        disallow = disallow && userAces.disallow(action, resource);
        if (!resource.inherited) break;
      }
      if (disallow) {
        throw new Forbidden(`You are not allowed to ${action} ${resources[0] && resources[0].id}, with ${context.path}/${context.id}`);
      }
    };

    if (context.method === 'create') {
      throwDisallowed('create', [context.data]);
    }

     // find, multi update/patch/remove
    if (!context.id) {
      const rules = userAces.rulesFor(action, serviceName);
      const query = toMongoQuery(rules);

      if (query) {
        params.query = fp.assign(params.query, query);
      } else {
        context.result = {
          message: 'No data found for your account permissions',
          metadata: {
            total: 0,
            limit: context.params.query.$limit || 10,
            skip: context.params.query.$skip || 0,
          },
          data: []
        };
      }

      context.params = params;
      return context;
    }
    // get, update, patch, remove, action
    else {
      // get the resource by id for checking permissions
      const resource = await context.service.get(context.id, {
        query: { $select: 'ancestors,*' }
      });
      throwDisallowed(action, fp.concat(resource && resource.ancestors || [], [resource]));

      return context;
    }
  };
}
<|endoftext|>


<commit_before>var _ = require('lodash'),
	acorn = require('acorn'),
	async = require('async'),
	constants = require('./constants'),
	fs = require('fs-extra'),
	logger = require('./logger'),
	path = require('path'),
	readline = require('readline'),
	request = require('request'),
	server = require('./server'),
	spinner = require('char-spinner'),
	tiappXml = require('tiapp.xml'),
	titanium = require('./titanium'),
	util = require('./util');

var DEFAULTS = {
	PROJECT: '_tmp',
	ID: 'triple.tmpapp'
};

var requireRE = /\brequire\s*\(['"](([\w\.\/-]+\/)?([\w\.\/-]*))/,
	simpleExpressionRE = /(([a-zA-Z_$](?:\w|\$)*)\.)*([a-zA-Z_$](?:\w|\$)*)\.?$/,
	tabCompletionNS = {};

module.exports = function(opts, callback) {
	var buffer = [];

	callback = arguments[arguments.length-1];
	if (!opts || _.isFunction(opts)) {
		opts = {};
	}

	if (opts.verbose) {
		titanium.verbose = true;
	}

	var rl = readline.createInterface({
		input: process.stdin,
		output: process.stdout,
		completer: tabCompletion(rl)
	});

	async.series([

		// make sure we're logged in
		function(cb) {
			titanium.loggedIn(function(err, loggedIn) {
				if (err) {
					return cb('error checking status: ' + err);
				} else if (!loggedIn) {
					return cb('You must be logged in to use triple. Use `titanium login`.');
				}
				return cb();
			});
		},

		// setup titanium completion database
		function (cb) {
			titanium.sdk(function(err,sdk, version, info){
				var cacheFile = path.join(sdk.path,'triple.cache');
				if (fs.existsSync(cacheFile)) {
					return fs.readFile(cacheFile, function(err,contents){
						contents && (tabCompletionSetup(JSON.parse(contents.toString())));
						cb(err);
					});
				}
				var interval = spinner();
				fs.readFile(path.join(sdk.path,'api.jsca'), function(err,buf){
					if (err) {
						clearInterval(interval);
						logger.warn('warn: could not find api.jsca file, auto-complete disabled');
						return cb();
					}
					var tabCompletionDB = [];
					JSON.parse(buf.toString()).types.forEach(function(entry){
						tabCompletionDB.push(entry.name);
						entry.properties && entry.properties.forEach(function(prop){
							tabCompletionDB.push(entry.name+'.'+prop.name);
						});
						entry.functions && entry.functions.forEach(function(fn){
							tabCompletionDB.push(entry.name+'.'+fn.name);
						});
					});
					fs.writeFile(cacheFile, JSON.stringify(tabCompletionDB), function(err){
						clearInterval(interval);
						tabCompletionSetup(tabCompletionDB);
						cb(err);
					});
				});
			});
		},

		// create the repl project
		function(cb) {
			if (!fs.existsSync(DEFAULTS.PROJECT)) {
				logger.log('[creating app]');
				var interval = spinner();
				var createOpts = _.defaults(opts.create || {}, {
					name: DEFAULTS.PROJECT,
					id: DEFAULTS.ID,
					logLevel: 'error'
				});
				titanium.create(createOpts, function(err, results) {
					clearInterval(interval);
					cb(err, results);
				});
			} else {
				cb();
			}
		},

		// prep app
		function(cb) {
			var resources = path.join(DEFAULTS.PROJECT, 'Resources'),
				app = path.join(__dirname, '..', 'app');

			// copy in all app files
			fs.readdirSync(app).forEach(function(file) {
				copy(path.join(app, file), path.join(resources, file));
			});

			// copy in shared constants file
			copy(path.join(__dirname, 'constants.js'), path.join(resources, 'constants.js'));

			// load native modules into tiapp.xml
			if(opts.module) {
				var tiapp = tiappXml.load(path.resolve(DEFAULTS.PROJECT, 'tiapp.xml'));
				opts.module.forEach(function(id) {
					logger.log('[Injecting module: %s]', id);
					tiapp.setModule(id);
				});
				tiapp.write();
			}

			cb();
		},

		// // start up repl server
		function(cb) {
			server.on('end', function(data) {
				return cb(data);
			});
			server.listen(constants.PORT, cb);
		},

		// build the repl project
		function(cb) {
			logger.log('[launching app]');
			var interval = spinner();
			var buildOpts = _.defaults(opts.build || {}, {
				projectDir: DEFAULTS.PROJECT,
				platform: 'ios',
				iosVersion: '7.1',
				noSimFocus: true,
				server: server
			});
			titanium.build(buildOpts);
			server.on('ready', function() {
				clearInterval(interval);
				cb();
			});
		},

		// prompt
		function(cb) {

			// clear spinner and prompt
			process.stdout.write('\r \r');
			rl.setPrompt(constants.PROMPT);
			rl.prompt();

			// handle each line of input
			rl.on('line', function(line) {
				var match;

				// skip empty lines
				if (!line) {
					rl.prompt();
					return;

				// handle triple commands
				} else if (match = line.match(/^\s*(\.\w*)(?:\s|$)/)) {
					var args = match.input.trim().split(/\s+/).slice(1);

					// don't put triple commands on history
					rl.history.shift();

					// execute the command
					switch(match[1].substring(1)) {
						case 'add':
							for (var i = 0; i < args.length; i++) {
								util.addToApp(args[i]);
							}
							break;
						case 'break':
							buffer = [];
							rl.setPrompt(constants.PROMPT);
							break;
						case 'clear':
							server.emit('message', constants.CLEAR_MESSAGE);
							break;
						case 'load':
							load(args, rl);
							break;
						case 'exit':
							return cb();
						case 'save':
							var file = args[0];
							if (!file) {
								logger.error('must specify path for save');
							} else {
								fs.ensureDir(path.dirname(file));
								fs.writeFileSync(file, rl.history.slice(0).reverse().join('\n'));
							}
							break;
						default:
							logger.error('invalid command "' + match[1] + '"');
							break;
					}
					rl.prompt();

				// process code
				} else {
					try {

						// handle requires
						var requireRE = /(\brequire\s*\(\s*['"])([^'"]+)(['"]\s*\))/;

						// if it contains a require(), but isn't a native require
						if ((match = line.match(requireRE)) && !_.contains(opts.module, match[2])) {
							var moduleId = match[2],
								modulePath;

							// get absolute path
							if (moduleId.indexOf('/') === 0) {
								modulePath = moduleId;
							} else {
								modulePath = path.join(process.cwd(), moduleId);
							}

							// .add it
							var addPath = modulePath + (!/\.js$/.test(modulePath) ? '.js' : '');
							util.addToApp(addPath);

							// modify the line before sending it to the app
							line = line.substring(0, match.index) + match[1] + '__modules' + modulePath +
								match[3] + line.substring(match.index + match[0].length);

						}

						// assemble code from buffer
						buffer.push(line);
						var code = buffer.join('\n');

						// validate the buffered code
						acorn.parse(code);

						// send code to server
						server.emit('message', code);

						// reset buffer and prompt
						buffer = [];
						rl.setPrompt(constants.PROMPT);
					} catch (e) {

						// prompt for multi-line statement
						rl.setPrompt(constants.CONTINUE_PROMPT);
						rl.prompt();
					}
				}

			});

			// handle CTRL+C
			rl.on('SIGINT', function() {

				// If we're in a multi-line statement, break out of it
				if (buffer.length) {
					buffer = [];
					logger.log('\n(^C again to quit)');
					rl.setPrompt(constants.PROMPT);
					rl.prompt();

				// quit
				} else {
					cb();
				}
			});

			// do we have a file to load?
			if (opts.args && opts.args.length) {
				load(opts.args, rl);
			}

		}

	], callback);
};

function copy(src, dst) {
	fs.writeFileSync(dst, fs.readFileSync(src));
}

function sendLoadCommand(rl, location, content, delay) {
	try {
		acorn.parse(content);
	} catch (err) {
		logger.error('error parsing "' + location + '"');
		logger.error(err);
		return rl.prompt();
	}

	var tasks = [];
	content.split('\n').forEach(function(line){
		line = line.trim();
		if (line) {
			tasks.push(function(next){
				setTimeout(function(){
					rl.write(line + '\n');
					next();
				}, delay || 25);
			});
		}
	});
	return async.series(tasks);
}

function load(tokens, rl) {
	var location = tokens[0],
		delay = tokens[1] || 0;

	// looks like a url, fetch it
	if (/^https?:\/\//.test(location)) {
		var interval = spinner();
		return request(location, function(err,content) {
			clearInterval(interval);
			if (err) {
				logger.error('error loading "' + location + '"');
				logger.error(err);
				rl.prompt();
				return;
			}
			sendLoadCommand(rl, location, content.body, delay);
		});

	// probably a file
	} else {
		if (fs.existsSync(location)) {
			return sendLoadCommand(rl, location, fs.readFileSync(location).toString(), delay);
		}
	}

	logger.error('not sure how to load "' + location + '". does it exist?');
	rl.prompt();
}

function tabCompletionSetup(tabCompletionDB) {
	if (tabCompletionDB && tabCompletionDB.length) {
		tabCompletionDB.forEach(function(name){
			var tokens = name.split('.'),
				obj = tabCompletionNS;
			for (var c=0;c<tokens.length;c++){
				var cname = tokens[c];
				var entry = obj[cname];
				if (!entry) {
					obj[cname] = entry = {};
				}
				obj = entry;
			}
		});
		tabCompletionDB = null;
		tabCompletionNS.Ti = tabCompletionNS.Titanium;
	}
}

function tabCompletion(rl) {
	return function(line) {

		var match = line.match(simpleExpressionRE);
		line = match[0];

		var tokens = line.split('.'),
			obj = tabCompletionNS,
			hits = [];

		for (var c=0;c<tokens.length;c++) {
			var token = tokens[c];
			if (token) {
				var entry = obj[token];
				if (!entry) {
					hits = Object.keys(obj).filter(function(e){
						return e.indexOf(token)===0;
					});
					obj = null;
					line = token;
					break;
				}
				obj = entry;
			}
		}

		if (obj) {
			hits = Object.keys(obj);
		}

		return [!hits.length && !line ? Object.keys(tabCompletionNS) : hits, line];
	};
}
<commit_msg>enable verbose logging in logger<commit_after>var _ = require('lodash'),
	acorn = require('acorn'),
	async = require('async'),
	constants = require('./constants'),
	fs = require('fs-extra'),
	logger = require('./logger'),
	path = require('path'),
	readline = require('readline'),
	request = require('request'),
	server = require('./server'),
	spinner = require('char-spinner'),
	tiappXml = require('tiapp.xml'),
	titanium = require('./titanium'),
	util = require('./util');

var DEFAULTS = {
	PROJECT: '_tmp',
	ID: 'triple.tmpapp'
};

var requireRE = /\brequire\s*\(['"](([\w\.\/-]+\/)?([\w\.\/-]*))/,
	simpleExpressionRE = /(([a-zA-Z_$](?:\w|\$)*)\.)*([a-zA-Z_$](?:\w|\$)*)\.?$/,
	tabCompletionNS = {};

module.exports = function(opts, callback) {
	var buffer = [];

	callback = arguments[arguments.length-1];
	if (!opts || _.isFunction(opts)) {
		opts = {};
	}

	if (opts.verbose) {
		titanium.verbose = true;
		logger.verbose = true;
	}

	var rl = readline.createInterface({
		input: process.stdin,
		output: process.stdout,
		completer: tabCompletion(rl)
	});

	async.series([

		// make sure we're logged in
		function(cb) {
			titanium.loggedIn(function(err, loggedIn) {
				if (err) {
					return cb('error checking status: ' + err);
				} else if (!loggedIn) {
					return cb('You must be logged in to use triple. Use `titanium login`.');
				}
				return cb();
			});
		},

		// setup titanium completion database
		function (cb) {
			titanium.sdk(function(err,sdk, version, info){
				var cacheFile = path.join(sdk.path,'triple.cache');
				if (fs.existsSync(cacheFile)) {
					return fs.readFile(cacheFile, function(err,contents){
						contents && (tabCompletionSetup(JSON.parse(contents.toString())));
						cb(err);
					});
				}
				var interval = spinner();
				fs.readFile(path.join(sdk.path,'api.jsca'), function(err,buf){
					if (err) {
						clearInterval(interval);
						logger.warn('warn: could not find api.jsca file, auto-complete disabled');
						return cb();
					}
					var tabCompletionDB = [];
					JSON.parse(buf.toString()).types.forEach(function(entry){
						tabCompletionDB.push(entry.name);
						entry.properties && entry.properties.forEach(function(prop){
							tabCompletionDB.push(entry.name+'.'+prop.name);
						});
						entry.functions && entry.functions.forEach(function(fn){
							tabCompletionDB.push(entry.name+'.'+fn.name);
						});
					});
					fs.writeFile(cacheFile, JSON.stringify(tabCompletionDB), function(err){
						clearInterval(interval);
						tabCompletionSetup(tabCompletionDB);
						cb(err);
					});
				});
			});
		},

		// create the repl project
		function(cb) {
			if (!fs.existsSync(DEFAULTS.PROJECT)) {
				logger.log('[creating app]');
				var interval = spinner();
				var createOpts = _.defaults(opts.create || {}, {
					name: DEFAULTS.PROJECT,
					id: DEFAULTS.ID,
					logLevel: 'error'
				});
				titanium.create(createOpts, function(err, results) {
					clearInterval(interval);
					cb(err, results);
				});
			} else {
				cb();
			}
		},

		// prep app
		function(cb) {
			var resources = path.join(DEFAULTS.PROJECT, 'Resources'),
				app = path.join(__dirname, '..', 'app');

			// copy in all app files
			fs.readdirSync(app).forEach(function(file) {
				copy(path.join(app, file), path.join(resources, file));
			});

			// copy in shared constants file
			copy(path.join(__dirname, 'constants.js'), path.join(resources, 'constants.js'));

			// load native modules into tiapp.xml
			if(opts.module) {
				var tiapp = tiappXml.load(path.resolve(DEFAULTS.PROJECT, 'tiapp.xml'));
				opts.module.forEach(function(id) {
					logger.log('[Injecting module: %s]', id);
					tiapp.setModule(id);
				});
				tiapp.write();
			}

			cb();
		},

		// // start up repl server
		function(cb) {
			server.on('end', function(data) {
				return cb(data);
			});
			server.listen(constants.PORT, cb);
		},

		// build the repl project
		function(cb) {
			logger.log('[launching app]');
			var interval = spinner();
			var buildOpts = _.defaults(opts.build || {}, {
				projectDir: DEFAULTS.PROJECT,
				platform: 'ios',
				iosVersion: '7.1',
				noSimFocus: true,
				server: server
			});
			titanium.build(buildOpts);
			server.on('ready', function() {
				clearInterval(interval);
				cb();
			});
		},

		// prompt
		function(cb) {

			// clear spinner and prompt
			process.stdout.write('\r \r');
			rl.setPrompt(constants.PROMPT);
			rl.prompt();

			// handle each line of input
			rl.on('line', function(line) {
				var match;

				// skip empty lines
				if (!line) {
					rl.prompt();
					return;

				// handle triple commands
				} else if (match = line.match(/^\s*(\.\w*)(?:\s|$)/)) {
					var args = match.input.trim().split(/\s+/).slice(1);

					// don't put triple commands on history
					rl.history.shift();

					// execute the command
					switch(match[1].substring(1)) {
						case 'add':
							for (var i = 0; i < args.length; i++) {
								util.addToApp(args[i]);
							}
							break;
						case 'break':
							buffer = [];
							rl.setPrompt(constants.PROMPT);
							break;
						case 'clear':
							server.emit('message', constants.CLEAR_MESSAGE);
							break;
						case 'load':
							load(args, rl);
							break;
						case 'exit':
							return cb();
						case 'save':
							var file = args[0];
							if (!file) {
								logger.error('must specify path for save');
							} else {
								fs.ensureDir(path.dirname(file));
								fs.writeFileSync(file, rl.history.slice(0).reverse().join('\n'));
							}
							break;
						default:
							logger.error('invalid command "' + match[1] + '"');
							break;
					}
					rl.prompt();

				// process code
				} else {
					try {

						// handle requires
						var requireRE = /(\brequire\s*\(\s*['"])([^'"]+)(['"]\s*\))/;

						// if it contains a require(), but isn't a native require
						if ((match = line.match(requireRE)) && !_.contains(opts.module, match[2])) {
							var moduleId = match[2],
								modulePath;

							// get absolute path
							if (moduleId.indexOf('/') === 0) {
								modulePath = moduleId;
							} else {
								modulePath = path.join(process.cwd(), moduleId);
							}

							// .add it
							var addPath = modulePath + (!/\.js$/.test(modulePath) ? '.js' : '');
							util.addToApp(addPath);

							// modify the line before sending it to the app
							line = line.substring(0, match.index) + match[1] + '__modules' + modulePath +
								match[3] + line.substring(match.index + match[0].length);

						}

						// assemble code from buffer
						buffer.push(line);
						var code = buffer.join('\n');

						// validate the buffered code
						acorn.parse(code);

						// send code to server
						server.emit('message', code);

						// reset buffer and prompt
						buffer = [];
						rl.setPrompt(constants.PROMPT);
					} catch (e) {

						// prompt for multi-line statement
						rl.setPrompt(constants.CONTINUE_PROMPT);
						rl.prompt();
					}
				}

			});

			// handle CTRL+C
			rl.on('SIGINT', function() {

				// If we're in a multi-line statement, break out of it
				if (buffer.length) {
					buffer = [];
					logger.log('\n(^C again to quit)');
					rl.setPrompt(constants.PROMPT);
					rl.prompt();

				// quit
				} else {
					cb();
				}
			});

			// do we have a file to load?
			if (opts.args && opts.args.length) {
				load(opts.args, rl);
			}

		}

	], callback);
};

function copy(src, dst) {
	fs.writeFileSync(dst, fs.readFileSync(src));
}

function sendLoadCommand(rl, location, content, delay) {
	try {
		acorn.parse(content);
	} catch (err) {
		logger.error('error parsing "' + location + '"');
		logger.error(err);
		return rl.prompt();
	}

	var tasks = [];
	content.split('\n').forEach(function(line){
		line = line.trim();
		if (line) {
			tasks.push(function(next){
				setTimeout(function(){
					rl.write(line + '\n');
					next();
				}, delay || 25);
			});
		}
	});
	return async.series(tasks);
}

function load(tokens, rl) {
	var location = tokens[0],
		delay = tokens[1] || 0;

	// looks like a url, fetch it
	if (/^https?:\/\//.test(location)) {
		var interval = spinner();
		return request(location, function(err,content) {
			clearInterval(interval);
			if (err) {
				logger.error('error loading "' + location + '"');
				logger.error(err);
				rl.prompt();
				return;
			}
			sendLoadCommand(rl, location, content.body, delay);
		});

	// probably a file
	} else {
		if (fs.existsSync(location)) {
			return sendLoadCommand(rl, location, fs.readFileSync(location).toString(), delay);
		}
	}

	logger.error('not sure how to load "' + location + '". does it exist?');
	rl.prompt();
}

function tabCompletionSetup(tabCompletionDB) {
	if (tabCompletionDB && tabCompletionDB.length) {
		tabCompletionDB.forEach(function(name){
			var tokens = name.split('.'),
				obj = tabCompletionNS;
			for (var c=0;c<tokens.length;c++){
				var cname = tokens[c];
				var entry = obj[cname];
				if (!entry) {
					obj[cname] = entry = {};
				}
				obj = entry;
			}
		});
		tabCompletionDB = null;
		tabCompletionNS.Ti = tabCompletionNS.Titanium;
	}
}

function tabCompletion(rl) {
	return function(line) {

		var match = line.match(simpleExpressionRE);
		line = match[0];

		var tokens = line.split('.'),
			obj = tabCompletionNS,
			hits = [];

		for (var c=0;c<tokens.length;c++) {
			var token = tokens[c];
			if (token) {
				var entry = obj[token];
				if (!entry) {
					hits = Object.keys(obj).filter(function(e){
						return e.indexOf(token)===0;
					});
					obj = null;
					line = token;
					break;
				}
				obj = entry;
			}
		}

		if (obj) {
			hits = Object.keys(obj);
		}

		return [!hits.length && !line ? Object.keys(tabCompletionNS) : hits, line];
	};
}
<|endoftext|>


<commit_before>
/*!
 * Cluster - Worker
 * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
 * MIT Licensed
 */

/**
 * Module dependencies.
 */

var EventEmitter = require('events').EventEmitter
  , spawn = require('child_process').spawn
  , binding = process.binding('net')
  , utils = require('./utils')
  , net = require('net');

// COMPAT:

net.Socket = net.Stream;

/**
 * Node binary.
 */

var node = process.execPath;

/**
 * Initialize a new `Worker` with the given `master`.
 *
 * Signals:
 *
 *   - `SIGINT`   immediately exit
 *   - `SIGTERM`  immediately exit
 *   - `SIGQUIT`  graceful exit
 *
 * @param {Master} master
 * @api private
 */

var Worker = module.exports = function Worker(master) {
  this.master = master;
  this.server = master.server;
  this.uid = Date.now() + Math.random();
};

/**
 * Inherit from `EventEmitter.prototype`.
 */

Worker.prototype.__proto__ = EventEmitter.prototype;

/**
 * Worker is a receiver.
 */

require('./mixins/receiver')(Worker.prototype);

/**
 * Start worker.
 *
 * @api private
 */

Worker.prototype.start = function(){
  var self = this
    , call = this.master.call;

  // proxy to provide worker id
  this.master.call = function(){
    var args = utils.toArray(arguments);
    args.unshift(self.id);
    return call.apply(this, args);
  };

  // stdin
  this.stdin = new net.Socket(0, 'unix');
  this.stdin.setEncoding('ascii');
  this.stdin.on('data', function(chunk){ self.frame(chunk, self.uid); });
  this.stdin.resume();

  // demote usr/group
  if (this.server) {
    this.server.on('listening', function(){
      var group = self.options.group;
      if (group) process.setgid(group);
      var user = self.options.user;
      if (user) process.setuid(user);
    });

    // stdin
    this.stdin.on('fd', this.server.listenFD.bind(this.server));
  }

  // signal handlers
  process.on('SIGINT', this.destroy.bind(this));
  process.on('SIGTERM', this.destroy.bind(this));
  process.on('SIGQUIT', this.close.bind(this));

  // conditionally handle uncaughtException
  if (!process.listeners('uncaughtException').length) {
    process.on('uncaughtException', function(err){
      // stderr for logs
      console.error(err.stack || err.message);

      // report exception
      self.master.call('workerException', err);

      // exit
      process.nextTick(function(){
        self.destroy();
      });
    });
  }
};

/**
 * Received connect event, set the worker `id`
 * and `options`.
 *
 * @param {String} id
 * @param {Object} options
 * @api private
 */

Worker.prototype.connect = function(id, options){
  this.options = options;

  // worker id
  this.id = id;

  // timeout
  this.timeout = options.timeout;

  // title
  process.title = options['worker title'].replace('{n}', id);

  // notify master of connection
  this.master.call('connect');
};

/**
 * Immediate shutdown.
 *
 * @api private
 */

Worker.prototype.destroy = function(){
  process.exit();
};

/**
 * Perform graceful shutdown.
 *
 * @api private
 */

Worker.prototype.close = function(){
  var self = this
    , server = this.server;

  if (server && server.connections) {
    // stop accepting
    server.watcher.stop();

    // check pending connections
    setInterval(function(){
      self.master.call('workerWaiting', server.connections);
      server.connections || self.destroy();
    }, 2000);

    // timeout
    if (this.timeout) {
      setTimeout(function(){
        self.master.call('workerTimeout', self.timeout);
        self.destroy();
      }, this.timeout);
    }
  } else {
    this.destroy();
  }
};

/**
 * Spawn the worker with the given `id`.
 *
 * @param {Number} id
 * @return {Worker} for chaining
 * @api private
 */

Worker.prototype.spawn = function(id){
  var fds = binding.socketpair()
    , customFds = [fds[0]].concat(this.master.customFds)
    , env = {};

  // merge env
  for (var key in process.env) {
    env[key] = process.env[key];
  }

  this.id = env.CLUSTER_WORKER = id;

  // spawn worker process
  this.proc = spawn(
      node
    , this.master.cmd
    , { customFds: customFds, env: env });

  // unix domain socket for ICP + fd passing
  this.sock = new net.Socket(fds[1], 'unix');

  // saving file descriptors for later use
  this.fds = fds;

  return this;
};

/**
 * Invoke worker's `method` (called from Master).
 *
 * @param {String} method
 * @param {...} args
 * @api private
 */

Worker.prototype.call = function(method){
  this.sock.write(utils.frame({
      args: utils.toArray(arguments, 1)
    , method: method
  }), 'ascii');
};
<commit_msg>Allow calling all master methods from worker<commit_after>
/*!
 * Cluster - Worker
 * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
 * MIT Licensed
 */

/**
 * Module dependencies.
 */

var EventEmitter = require('events').EventEmitter
  , spawn = require('child_process').spawn
  , binding = process.binding('net')
  , utils = require('./utils')
  , net = require('net');

// COMPAT:

net.Socket = net.Stream;

/**
 * Node binary.
 */

var node = process.execPath;

/**
 * Initialize a new `Worker` with the given `master`.
 *
 * Signals:
 *
 *   - `SIGINT`   immediately exit
 *   - `SIGTERM`  immediately exit
 *   - `SIGQUIT`  graceful exit
 *
 * @param {Master} master
 * @api private
 */

var Worker = module.exports = function Worker(master) {
  this.master = master;
  this.server = master.server;
  this.uid = Date.now() + Math.random();
};

/**
 * Inherit from `EventEmitter.prototype`.
 */

Worker.prototype.__proto__ = EventEmitter.prototype;

/**
 * Worker is a receiver.
 */

require('./mixins/receiver')(Worker.prototype);

/**
 * Start worker.
 *
 * @api private
 */

Worker.prototype.start = function(){
  var self = this
    , call = this.master.call;

  // proxy to provide worker id
  this.master.call = function(){
    var args = utils.toArray(arguments);
    // Allow calling master methods that don't take worker as first argument
    if (args[0] !== false) {
      args.unshift(self.id);
    }
    return call.apply(this, args);
  };

  // stdin
  this.stdin = new net.Socket(0, 'unix');
  this.stdin.setEncoding('ascii');
  this.stdin.on('data', function(chunk){ self.frame(chunk, self.uid); });
  this.stdin.resume();

  // demote usr/group
  if (this.server) {
    this.server.on('listening', function(){
      var group = self.options.group;
      if (group) process.setgid(group);
      var user = self.options.user;
      if (user) process.setuid(user);
    });

    // stdin
    this.stdin.on('fd', this.server.listenFD.bind(this.server));
  }

  // signal handlers
  process.on('SIGINT', this.destroy.bind(this));
  process.on('SIGTERM', this.destroy.bind(this));
  process.on('SIGQUIT', this.close.bind(this));

  // conditionally handle uncaughtException
  if (!process.listeners('uncaughtException').length) {
    process.on('uncaughtException', function(err){
      // stderr for logs
      console.error(err.stack || err.message);

      // report exception
      self.master.call('workerException', err);

      // exit
      process.nextTick(function(){
        self.destroy();
      });
    });
  }
};

/**
 * Received connect event, set the worker `id`
 * and `options`.
 *
 * @param {String} id
 * @param {Object} options
 * @api private
 */

Worker.prototype.connect = function(id, options){
  this.options = options;

  // worker id
  this.id = id;

  // timeout
  this.timeout = options.timeout;

  // title
  process.title = options['worker title'].replace('{n}', id);

  // notify master of connection
  this.master.call('connect');
};

/**
 * Immediate shutdown.
 *
 * @api private
 */

Worker.prototype.destroy = function(){
  process.exit();
};

/**
 * Perform graceful shutdown.
 *
 * @api private
 */

Worker.prototype.close = function(){
  var self = this
    , server = this.server;

  if (server && server.connections) {
    // stop accepting
    server.watcher.stop();

    // check pending connections
    setInterval(function(){
      self.master.call('workerWaiting', server.connections);
      server.connections || self.destroy();
    }, 2000);

    // timeout
    if (this.timeout) {
      setTimeout(function(){
        self.master.call('workerTimeout', self.timeout);
        self.destroy();
      }, this.timeout);
    }
  } else {
    this.destroy();
  }
};

/**
 * Spawn the worker with the given `id`.
 *
 * @param {Number} id
 * @return {Worker} for chaining
 * @api private
 */

Worker.prototype.spawn = function(id){
  var fds = binding.socketpair()
    , customFds = [fds[0]].concat(this.master.customFds)
    , env = {};

  // merge env
  for (var key in process.env) {
    env[key] = process.env[key];
  }

  this.id = env.CLUSTER_WORKER = id;

  // spawn worker process
  this.proc = spawn(
      node
    , this.master.cmd
    , { customFds: customFds, env: env });

  // unix domain socket for ICP + fd passing
  this.sock = new net.Socket(fds[1], 'unix');

  // saving file descriptors for later use
  this.fds = fds;

  return this;
};

/**
 * Invoke worker's `method` (called from Master).
 *
 * @param {String} method
 * @param {...} args
 * @api private
 */

Worker.prototype.call = function(method){
  this.sock.write(utils.frame({
      args: utils.toArray(arguments, 1)
    , method: method
  }), 'ascii');
};
<|endoftext|>


<commit_before>var glowbug = {
	errors: []
	,
	log: function(message, fileName, lineNumber) {
		this._add('Log', message, fileName, lineNumber);
	}
	,
	warn: function(message, fileName, lineNumber) {
		this._add('Warn', message, fileName, lineNumber);
	}
	,
	error: function(message, fileName, lineNumber) {
		this._add('Error', message, fileName, lineNumber);
	}
	,
	_add: function(level, message, fileName, lineNumber) {
		var e = new Error(message, fileName, lineNumber);

		e.message = message;
		e.name = 'Glow'+level;
		e.level = level.toLowerCase();

		var match = /\[([^\]]+)\]/.exec(message);
		if (match) e.type = match[1]; // may be undefined
		else e.type = 'message';

		this.errors.push(e);

		this.out(e);
	}
	,
	out: function(e) {
		var message = '['+e.level+'] '+e.message;

		if (window.console) {
			if (e.level === 'warn' && window.console.warn) {
				console.warn(message);
			}
			else if (e.level === 'error' && window.console.error) {
				console.error(message);
			}
			else if (window.console.log) {
				console.log(message);
			}
		}
		else if (window.opera && opera.postError) {
			opera.postError(message);
		}
		else { // use our own console
			glowbug.console.log(e.level, message);
		}
	}
};

glowbug.console = {
	messages: [],
	log: function(level, message) {
		if (!this._w) {
			this._w = window.open('', 'report', 'width=350,height=250,menubar=0,toolbar=0,location=no,status=0,scrollbars=1,resizable=1');
			this._w.document.write(
				'<title>Console<\/title>


<commit_before>class Website {
	constructor() {
		// class wide variables
		this.loading = false;
		this.hasMouse = false;

		// insert calculated age
		document.querySelector( "#age" ).innerHTML = `${this.calculateAge( "1994-5-18" )} years old`;

		// bound event to a function to be able to call `this` inside the event and but also call removeEventListener
		this.boundNoTouch = ( event ) =>  this.noTouch( event );
		document.addEventListener( "mousemove", this.boundNoTouch );
		// if a mobile use clicks a link mousemove is triggered, to prevent this touchstart will unbind the mousemove listener
		// (only works if the touchstart is triggered before mousemove which seems to be the case)
		document.addEventListener( "touchstart", ( event ) => {
			document.removeEventListener( "mousemove",  this.boundNoTouch );
		});

		// show/hide button when scrolling
		this.toggleFAB();
		window.addEventListener( "scroll", this.toggleFAB );

		if (history.pushState) {

			// create initial state for history api
			this.getJson( location.href, ( json ) => {
				history.replaceState( json, "", location.href );
			});

			// add eventlisteners for the history api functions
			this.forEach( document.querySelectorAll( ".pagenav" ), ( element ) => {
				element.addEventListener( "click",  ( event ) => this.navPushState( event ) );
			});

			// restore window after popstate
			window.addEventListener( "popstate", ( event ) => {
				this.renderPage( event.state );
				ga( "send", "pageview", location.pathname );
			});

			// stop the logo from spinning when in the correct orientation
			this.forEach( document.querySelectorAll( ".logo" ), ( element ) => {
				element.addEventListener( "animationiteration", ( event ) => {
					if( !this.loading ) {
						event.currentTarget.classList.remove( "spin" );
					}
				});
			});

		}
	}

	// function to calculate the age for a given date of birth
	calculateAge( dateOfBirth ) {
		let dob = new Date( dateOfBirth );
		let today = new Date();
		let age = new Date( today - dob ).getFullYear() - 1970; // 1970 is the beginning of unix time
	}

	// move the fab button
	toggleFAB() {
		if( window.scrollY > 50 ) {
			fab.classList.remove( "fab-hidden" );
			fab.style.bottom =  "";
		}
		else if( !fab.classList.contains( "fab-hidden" ) ) {
			fab.classList.add( "fab-hidden" );
			fab.style.bottom = "-" + getComputedStyle( fab ).height;
		}
	}

	// if a user uses mouse hide titles and show on hover
	noTouch( event ) {
		this.hasMouse = true;
		this.forEach( document.querySelectorAll( ".title" ), ( element ) => {
			element.classList.add( "no-touch" );
		});
		document.removeEventListener( "mousemove", this.boundNoTouch );
	}

	// internal navigation
	navPushState( event ) {
		event.preventDefault();

		this.forEach( document.querySelectorAll( ".logo" ), ( element ) => {
			element.classList.add( "spin" );
		});

		this.loading = true;

		let url = event.currentTarget.href.replace( location.origin, "" );

		this.getJson( url, ( json ) => {
			history.pushState( json, "", url );
			this.renderPage( json );
			this.loading = false;
			ga( "send", "pageview", url );
		});
	}

	// render the page from the json data
	// move fade in/out to css (toggle a class in js)
	renderPage( json ) {
		$( "#content" ).fadeOut( 500, () => {
			$( "#content" ).html( json.data ).fadeIn( 500 );

			this.forEach( document.querySelector( "#content" ).querySelectorAll( ".pagenav" ), ( element ) => {
				element.addEventListener( "click",  ( event ) => this.navPushState( event ) );
			});

			if( this.hasMouse ) {
				document.querySelector( ".title" ).classList.add( "no-touch" );
			}
		});
	}

	// helper function for looping over nodeLists returned by querySelectorAll
	forEach( array, callback, scope ) {
		for( let i = 0; i < array.length; i++ ) {
			callback.call( scope, array[i] );
		}
	}

	// shorthand for the jQuery ajax function
	// replace with own get request
	getJson( url, callback ) {
		$.ajax({
			dataType: "json",
			url: url,
			cache: false,
			success: callback
		});
	}
}

// run the whole thing
let website = new Website();<commit_msg>Fixed some bugs, cleaned some code<commit_after>class Website {
	constructor() {
		// class wide variables
		this.loading = false;
		this.hasMouse = false;

		// insert calculated age
		document.querySelector( "#age" ).innerHTML = `${this.calculateAge( "1994-5-18" )} years old`;

		// bound event to a function to be able to call `this` inside the event but also call removeEventListener later
		this.boundNoTouch = ( event ) =>  this.noTouch( event );

		// on mousemove add no-touch class that hides the titles until hover
		document.addEventListener( "mousemove", this.boundNoTouch );

		// if a mobile use clicks a link mousemove is triggered, to prevent this touchstart will unbind the mousemove listener
		// (only works if the touchstart is triggered before mousemove which seems to be the case)
		document.addEventListener( "touchstart", ( event ) => document.removeEventListener( "mousemove",  this.boundNoTouch ) );

		// show/hide floating action button when scrolling
		window.addEventListener( "scroll", this.toggleFAB );

		// check if pushstate is available
		if (history.pushState) {

			// create initial state for history api
			this.getRequest( location.href, ( data ) => history.replaceState( data, "", location.href ) );

			// add eventlisteners for the history api functions
			this.forEach( document.querySelectorAll( ".pagenav" ), ( element ) => {
				element.addEventListener( "click",  ( event ) => this.navPushState( event ) );
			});

			// restore window after popstate
			window.addEventListener( "popstate", ( event ) => this.renderPage( event.state ) );

			// stop the logo from spinning when in the correct orientation
			this.forEach( document.querySelectorAll( ".logo" ), ( element ) => {
				element.addEventListener( "animationiteration", ( event ) => {
					if( !this.loading ) {
						event.currentTarget.classList.remove( "spin" );
					}
				});
			});

		}
	}

	// function to the number of years since a given date
	calculateAge( dateOfBirth ) {
		let dob = new Date( dateOfBirth );
		let today = new Date();
		// calculates the amount of milliseconds between the two dates
		// 1970 is the beginning of unix time, subtract that to get the amount of time between the two dates
		let age = new Date( today - dob ).getFullYear() - 1970;
	}

	// toggle the floating action button
	toggleFAB() {
		let fab = document.querySelector( "#fab" );
		if( window.scrollY > 50 ) {
			fab.classList.remove( "fab-hidden" );
			fab.style.bottom =  "";
		}
		else if( !fab.classList.contains( "fab-hidden" ) ) {
			fab.classList.add( "fab-hidden" );
			let height = getComputedStyle( fab ).height;
			fab.style.bottom = `-${height}`;
		}
	}

	// if a user uses mouse hide titles and show on hover
	noTouch( event ) {
		this.hasMouse = true;
		this.forEach( document.querySelectorAll( ".title" ), ( element ) => element.classList.add( "no-touch" ) );
		document.removeEventListener( "mousemove", this.boundNoTouch );
	}

	// function for pushstate navigation
	navPushState( event ) {
		event.preventDefault();

		this.forEach( document.querySelectorAll( ".logo" ), ( element ) => element.classList.add( "spin" ) );

		this.loading = true;

		let url = event.currentTarget.href.replace( location.origin, "" );

		this.getRequest( url, ( data ) => {
			history.pushState( data, "", url );
			this.renderPage( data );
			this.loading = false;
		});
	}

	// put html on page
	// move fade in/out to css (toggle a class in js)
	// remove jquery fade out/in dependency
	renderPage( html ) {
		$( "#content" ).fadeOut( 500, () => {
			// insert html and fade in
			$( "#content" ).html( html ).fadeIn( 500 );

			// reaply all the pushstate events
			this.forEach( document.querySelector( "#content" ).querySelectorAll( ".pagenav" ), ( element ) => {
				element.addEventListener( "click",  ( event ) => this.navPushState( event ) );
			});

			// if has mouse reaply title no-touch style
			if( this.hasMouse ) {
				this.forEach( document.querySelectorAll( ".title" ), ( element ) => element.classList.add( "no-touch" ) );
			}

			// update google analytics stats
			ga( "send", "pageview", location.pathname );
		});
	}

	// helper function for looping over nodeLists returned by querySelectorAll
	forEach( array, callback, scope ) {
		for( let i = 0; i < array.length; i++ ) {
			callback.call( scope, array[i] );
		}
	}

	// shorthand for the jQuery ajax function
	// replace with own get request
	getRequest( url, callback ) {
		$.ajax({
			url: url,
			cache: false,
			success: callback
		});
	}
}

// run the whole thing
let website = new Website();<|endoftext|>