<commit_before>export {
  version
} from "./build/package";

export {
  Axis,
  AxisBottom,
  AxisLeft,
  AxisRight,
  AxisTop,
  date
} from "d3plus-axis";

export {
  add as colorAdd,
  assign as colorAssign,
  contrast as colorContrast,
  defaults as colorDefaults,
  legible as colorLegible,
  lighter as colorLighter,
  subtract as colorSubtract
} from "d3plus-color";

export {
  accessor,
  assign,
  attrize,
  BaseClass,
  closest,
  constant,
  elem,
  isObject,
  locale,
  merge,
  prefix,
  stylize
} from "d3plus-common";

export {
  Geomap
} from "d3plus-geomap";

export {
  Donut,
  Pie,
  Tree,
  Treemap
} from "d3plus-hierarchy";

export {
  Legend
} from "d3plus-legend";

export {
  Network
} from "d3plus-network";

export {
  AreaPlot,
  LinePlot,
  Plot,
  StackedArea
} from "d3plus-plot";

export {
  Priestley
} from "d3plus-priestley";

export {
  Area,
  Bar,
  Circle,
  Image,
  Line,
  Path,
  pointDistance,
  Rect,
  Shape
} from "d3plus-shape";

export {
  stringify,
  strip,
  TextBox,
  textSplit,
  textWidth,
  textWrap,
  titleCase
} from "d3plus-text";

export {
  Timeline
} from "d3plus-timeline";

export {
  Tooltip
} from "d3plus-tooltip";

export {
  Viz
} from "d3plus-viz";
<commit_msg>exports BarChart from d3plus-plot<commit_after>export {
  version
} from "./build/package";

export {
  Axis,
  AxisBottom,
  AxisLeft,
  AxisRight,
  AxisTop,
  date
} from "d3plus-axis";

export {
  add as colorAdd,
  assign as colorAssign,
  contrast as colorContrast,
  defaults as colorDefaults,
  legible as colorLegible,
  lighter as colorLighter,
  subtract as colorSubtract
} from "d3plus-color";

export {
  accessor,
  assign,
  attrize,
  BaseClass,
  closest,
  constant,
  elem,
  isObject,
  locale,
  merge,
  prefix,
  stylize
} from "d3plus-common";

export {
  Geomap
} from "d3plus-geomap";

export {
  Donut,
  Pie,
  Tree,
  Treemap
} from "d3plus-hierarchy";

export {
  Legend
} from "d3plus-legend";

export {
  Network
} from "d3plus-network";

export {
  AreaPlot,
  BarChart,
  LinePlot,
  Plot,
  StackedArea
} from "d3plus-plot";

export {
  Priestley
} from "d3plus-priestley";

export {
  Area,
  Bar,
  Circle,
  Image,
  Line,
  Path,
  pointDistance,
  Rect,
  Shape
} from "d3plus-shape";

export {
  stringify,
  strip,
  TextBox,
  textSplit,
  textWidth,
  textWrap,
  titleCase
} from "d3plus-text";

export {
  Timeline
} from "d3plus-timeline";

export {
  Tooltip
} from "d3plus-tooltip";

export {
  Viz
} from "d3plus-viz";
<|endoftext|>


<commit_before>/**
 * Created by dcordova on 8/16/17.
 */

const GLOBAL    = global || window;
const MAWS      = require('./mock/mochaAws');
const NOCK      = require('./mock/mochaNock');
const CONFIG    = require('./config/mochaConfig');
const EXPECT    = require('chai').expect;

(function constructor( ){

    const env_Var = process.env.IS_MOCKED;
    let isMocked = true;
    if( env_Var ){
        isMocked = env_Var === 'false' ? false: !!env_Var;
    } else {
        isMocked = env_Var === 0 ? false: isMocked;
    }

    CONFIG.setIsMock( isMocked );
    MAWS.init();

    GLOBAL['expect'] = EXPECT;
    GLOBAL['mochaTest'] = GLOBAL.it;

    if( isMocked ){
        GLOBAL.it = function(){};
    }
    GLOBAL.it.EtoE = GLOBAL.mochaTest;

    delete GLOBAL.mochaTest;
})();

module.exports = {
    clean: function(){
        NOCK.clean();
        MAWS.clean();
    },
    aws: MAWS.mock,
    expect: EXPECT,
    nock: NOCK.nock,
    setPayload: CONFIG.setPayload,
    getPayload: CONFIG.getPayload,
    setIsMock: CONFIG.setIsMock
};
<commit_msg>frappless 2.0.2<commit_after>/**
 * Created by dcordova on 8/16/17.
 */

const GLOBAL    = global || window;
const MAWS      = require('./mock/mochaAws');
const NOCK      = require('./mock/mochaNock');
const CONFIG    = require('./config/mochaConfig');
const EXPECT    = require('chai').expect;

(function constructor( ){

    const env_Var = process.env.IS_MOCKED;
    let isMocked = true;
    if( env_Var ){
        isMocked = env_Var === 'false' ? false: !!env_Var;
    } else {
        isMocked = env_Var === 0 ? false: isMocked;
    }

    CONFIG.setIsMock( isMocked );
    MAWS.init();

    GLOBAL['expect'] = EXPECT;
    GLOBAL['mochaTest'] = GLOBAL.it;

    if( !isMocked ){
        GLOBAL.it = function(){};
    }
    GLOBAL.it.EtoE = GLOBAL.mochaTest;

    delete GLOBAL.mochaTest;
})();

module.exports = {
    clean: function(){
        NOCK.clean();
        MAWS.clean();
    },
    aws: MAWS.mock,
    expect: EXPECT,
    nock: NOCK.nock,
    setPayload: CONFIG.setPayload,
    getPayload: CONFIG.getPayload,
    setIsMock: CONFIG.setIsMock
};
<|endoftext|>


<commit_before>var moment = require('moment');
var through2 = require('through2');
var Joi = require('joi');

module.exports = function build(db) {
  var now;
  var count;

  var incCounter = function () {
    var current = Date.now();

    if (current === now) {
      count++;
    } else {
      count = 0;
    }
    now = current;

    return now;
  };

  var addValueSchema = Joi.object().keys({
    assetId: Joi.string().required(),
    date: Joi.date(),
    value: Joi.any().required()
  });

  function add(value, cb) {

    var validationResult = Joi.validate(value, addValueSchema);

    if (validationResult.error !== null) {

      console.error("add validation error is", validationResult.error);
      cb(validationResult.error);
      return;
    }

    value.date = value.date || moment().toDate();

    incCounter();

    var formattedDate = Math.floor(value.date / 1000)

    var keyTs = "ts::" + formattedDate + ":" + count;
    var keyAs = "as::" + value.assetId + "--" + formattedDate + ":" + count;

    db.batch()
      .put(keyTs, value, { valueEncoding: 'json' })
      .put(keyAs, value, { valueEncoding: 'json' })
      .write(function () {
      cb(null, value);
    });
  }

  var getQueryValuesSchema = Joi.object().keys({
    assetId: Joi.string().required(),
    from: Joi.date(),
    to: Joi.date()
  });

  function getDataStream(queryValues) {

    var validationResult = Joi.validate(queryValues, getQueryValuesSchema);

    if (validationResult.error !== null) {

      console.error("getDataStream error is", validationResult.error);

      var stream = through2.obj()

      process.nextTick(function () {
        stream.emit('error', validationResult.error)
      })

      return stream;
    }

    var gt;
    var lt;
    var prefix;
    var options;
    var assetId;

    queryValues.from = queryValues.from || "";
    queryValues.to = queryValues.to || '\xff';

    if (!queryValues.assetId) {
      prefix = "ts::";
      assetId = "";
    }
    else {
      prefix = "as::";
      assetId = queryValues.assetId + "--";
    }

    gt = prefix + assetId + queryValues.from;
    lt = prefix + assetId + queryValues.to;

    options = {
      valueEncoding: 'json',
      lte: lt,
      gte: gt
    };

    return db.createReadStream(options).pipe(through2.obj(function (chunk, enc, callback) {
    	this.push(chunk.value);
    	callback();
    }));

  }

  return {
    addSchema: function () { return addValueSchema; },
    add: add,
    getQuerySchema: function () { return getQueryValuesSchema; },
    getDataStream: getDataStream
  };
};<commit_msg>created a write stream stub<commit_after>var moment = require('moment');
var through2 = require('through2');
var Joi = require('joi');
var util = require('util');
var stream = require('stream');

module.exports = function build(db) {
  var now;
  var count;

  var incCounter = function () {
    var current = Date.now();

    if (current === now) {
      count++;
    } else {
      count = 0;
    }
    now = current;

    return now;
  };

  var addValueSchema = Joi.object().keys({
    assetId: Joi.string().required(),
    date: Joi.date(),
    value: Joi.any().required()
  });

  function generateWriteStream(){
  	return util.inherits({
  		_write:function (chunk, encoding, done) {
  			console.log(chunk.toString());
  			done();
		}
  	}, stream.Writable);
  };

  function add(value, cb) {

    var validationResult = Joi.validate(value, addValueSchema);

    if (validationResult.error !== null) {

      console.error("add validation error is", validationResult.error);
      cb(validationResult.error);
      return;
    }

    value.date = value.date || moment().toDate();

    incCounter();

    var formattedDate = Math.floor(value.date / 1000)

    var keyTs = "ts::" + formattedDate + ":" + count;
    var keyAs = "as::" + value.assetId + "--" + formattedDate + ":" + count;

    db.batch()
      .put(keyTs, value, { valueEncoding: 'json' })
      .put(keyAs, value, { valueEncoding: 'json' })
      .write(function () {
      cb(null, value);
    });
  }

  var getQueryValuesSchema = Joi.object().keys({
    assetId: Joi.string().required(),
    from: Joi.date(),
    to: Joi.date()
  });

  function getDataStream(queryValues) {

    var validationResult = Joi.validate(queryValues, getQueryValuesSchema);

    if (validationResult.error !== null) {

      console.error("getDataStream error is", validationResult.error);

      var stream = through2.obj()

      process.nextTick(function () {
        stream.emit('error', validationResult.error)
      })

      return stream;
    }

    var gt;
    var lt;
    var prefix;
    var options;
    var assetId;

    queryValues.from = queryValues.from || "";
    queryValues.to = queryValues.to || '\xff';

    if (!queryValues.assetId) {
      prefix = "ts::";
      assetId = "";
    }
    else {
      prefix = "as::";
      assetId = queryValues.assetId + "--";
    }

    gt = prefix + assetId + queryValues.from;
    lt = prefix + assetId + queryValues.to;

    options = {
      valueEncoding: 'json',
      lte: lt,
      gte: gt
    };

    return db.createReadStream(options).pipe(through2.obj(function (chunk, enc, callback) {
    	this.push(chunk.value);
    	callback();
    }));

  }

  return {
    addSchema: function () { return addValueSchema; },
    add: add,
    getQuerySchema: function () { return getQueryValuesSchema; },
    getDataStream: getDataStream,
    generateWriteStream:generateWriteStream
  };
};<|endoftext|>


<commit_before>module.exports = function (bookshelf) {
  var modelPrototype = bookshelf.Model.prototype

  bookshelf.Model = bookshelf.Model.extend({
    sync: function (options) {
      var sync = modelPrototype.sync.apply(this, arguments)

      if (this.softDelete === true && options.withDeleted !== true) {
        var originalSelect = sync.select

        sync.select = function () {
          sync.query.whereNull('deleted_at')
          return originalSelect.call(sync)
        }
      }

      if (options.hardDelete !== true && (this.softDelete === true || options.softDelete === true)) {
        /* eslint-disable no-useless-call */
        sync.del = function () {
          return sync.update.call(sync, { deleted_at: new Date() })
        }
        /* eslint-enable no-useless-call */
      }

      return sync
    }
  })
}
<commit_msg>Rewrote using fetching event and overwriting destroy method<commit_after>module.exports = function (bookshelf) {
  var modelPrototype = bookshelf.Model.prototype

  bookshelf.Model = bookshelf.Model.extend({
    initialize: function () {
      modelPrototype.initialize.call(this)

      this.on('fetching', skipDeleted)
      this.on('fetching:collection', skipDeleted)

      function skipDeleted (model, column, options) {
        if (this.softDelete === true && options.withDeleted !== true) {
          return options.query.whereNotNull('deleted_at')
        } else {
          return
        }
      }
    },

    destroy: function (options) {
      options = options || {}
      if (this.softDelete === true && options.hardDelete !== true) {
        options.patch = true
        return this.save({ deleted_at: new Date() })
      } else {
        return modelPrototype.destroy.apply(this, arguments)
      }
    }
  })
}

<|endoftext|>


<commit_before>var AWS = require('aws-sdk'),
	Promise = require("bluebird"),
	shortid = require('shortid');

var utils = require("./utils");

module.exports = function(awsconfig, dynamodboptions) {

	AWS.config.update(awsconfig);

	var dynamodb = new Promise.promisifyAll(new AWS.DynamoDB(dynamodboptions));

	var query = function(table, conditions, index, options) {

		var params = {
			TableName: table
		};

		if (index) {
			params.IndexName = index;
		}

		// Legacy KeyConditions are in use
		if (conditions.constructor === Array) {

			var keys = {};
			conditions.forEach(function(condition) {

				keys[condition.key] = {
					ComparisonOperator: condition.operator,
					AttributeValueList: [utils.itemize(condition.value)],
				};

			});

			params.KeyConditions = keys;

		}

		// KeyConditionExpression are in use
		if (conditions.constructor === Object) {

			params.KeyConditionExpression = conditions.KeyConditionExpression;
			params.ExpressionAttributeNames = conditions.ExpressionAttributeNames;

			var ExpressionAttributeValues = {};

			var values = conditions.ExpressionAttributeValues;

			for (var p in values) {
				if (!values.hasOwnProperty(p)) {
					continue;
				}
				ExpressionAttributeValues[p] = utils.itemize(values[p]);
			}

			params.ExpressionAttributeValues = ExpressionAttributeValues;

		}

		if (options && options.reverse) {
			params.ScanIndexForward = false;
		}

		if (options && options.limit) {
			params.Limit = options.limit;
		}

		if (options && options.filter) {

			var queryFilter = {};

			options.filter.forEach(function(condition) {

				queryFilter[condition.key] = {
					ComparisonOperator: condition.operator,
					AttributeValueList: [utils.itemize(condition.value)],
				};

			});

			params.QueryFilter = queryFilter;

		}

		return dynamodb.queryAsync(params).then(function(data) {

			var items = [];
			data.Items.forEach(function(item) {
				items.push(utils.deitemize(item));
			});
			return items;

		});

	};

	var list = function(table, conditions) {

		var params = {
			TableName: table
		};

		var keys = {};
		conditions.forEach(function(condition) {

			keys[condition.key] = {
				ComparisonOperator: condition.operator,
				AttributeValueList: [utils.itemize(condition.value)],
			};

		});

		params.ScanFilter = keys;

		return dynamodb.scanAsync(params).then(function(data) {

			var items = [];
			data.Items.forEach(function(item) {
				items.push(utils.deitemize(item));
			});

			return items;

		});

	};

	var get = function(table, id) {

		var params = {
			TableName: table,
			Key: {
				"id": {
					"S": id
				}
			}
		};

		return dynamodb.getItemAsync(params).then(function(data) {

			return utils.deitemize(data.Item);

		});

	};

	var getItems = function(table, ids) {

		var params = {
			RequestItems: {}
		};

		var keys = ids.map(function(id) {
			return {
				"id": utils.itemize(id)
			};
		});

		params.RequestItems[table] = {
			ConsistentRead: true,
			Keys: keys
		};

		return dynamodb.batchGetItemAsync(params).then(function(data) {

			var output = [];
			if (!data.Responses) {
				return output;
			}

			data.Responses[table].forEach(function(item) {
				output.push(utils.deitemize(item));
			});

			return output;

		});

	};

	var create = function(table, document, conditions) {

		document.id = shortid.generate();

		var item = {};
		Object.keys(document).forEach(function(key) {
			item[key] = utils.itemize(document[key]);
		});

		var params = {
			ReturnConsumedCapacity: "TOTAL",
			ReturnItemCollectionMetrics: "SIZE",
			ReturnValues: "ALL_OLD",
			TableName: table,
			Item: item
		};

		// KeyConditionExpression are in use
		if (conditions && conditions.constructor === Object) {

			params.ConditionExpression = conditions.ConditionExpression;

			if (conditions.ExpressionAttributeNames) {
				params.ExpressionAttributeNames = conditions.ExpressionAttributeNames;
			}

			var ExpressionAttributeValues = {};

			var values = conditions.ExpressionAttributeValues;

			for (var p in values) {
				if (!values.hasOwnProperty(p)) {
					continue;
				}
				ExpressionAttributeValues[p] = utils.itemize(values[p]);
			}

			params.ExpressionAttributeValues = ExpressionAttributeValues;

		}

		return dynamodb.putItemAsync(params).then(function(data) {

			return document;

		});

	};

	var createItems = function(table, documents) {

		var maxWriteItems = 25; // Currently 25 on AWS

		// Returns a promise of the wripte operation
		var getWriteOperation = function(documentsToWrite) {

			// Constructs the request
			var params = {
				RequestItems: {}
			};

			params.RequestItems[table] = [];

			documentsToWrite.forEach(function(document) {

				// Dop not generate id if already present
				if (!document.id) {
					document.id = shortid.generate();
				}

				var item = {};
				Object.keys(document).forEach(function(key) {
					item[key] = utils.itemize(document[key]);
				});

				params.RequestItems[table].push({
					PutRequest: {
						Item: item
					}
				});

			});

			// Sends the request
			return dynamodb.batchWriteItemAsync(params);

		};

		var writeRequests = [];

		while (documents.length) {

			var documentsToWrite = documents.splice(0, maxWriteItems);

			var writeOperation = getWriteOperation(documentsToWrite);

			writeRequests.push(writeOperation);

		}

		// Wait for all promisses to be fullfilled
		return Promise.all(writeRequests).then(function() {

			// Return documents
			return documents;

		});

	};

	var update = function(table, document) {

		var items = {};
		Object.keys(document).forEach(function(key) {

			if (key === "id") {
				return;
			}

			if (document[key]) {
				items[key] = {
					Value: utils.itemize(document[key]),
					Action: "PUT"
				};
			} else {
				items[key] = {
					Action: "DELETE"
				};
			}

		});

		var params = {
			ReturnConsumedCapacity: "TOTAL",
			ReturnItemCollectionMetrics: "SIZE",
			ReturnValues: "ALL_NEW",
			Key: {
				"id": utils.itemize(document.id)
			},
			AttributeUpdates: items,
			TableName: table,
		};

		return dynamodb.updateItemAsync(params).then(function() {

			return document;

		});

	};

	var remove = function(table, document) {

		var key = {};
		Object.keys(document).forEach(function(k) {
			key[k] = utils.itemize(document[k]);
		});

		var params = {
			TableName: table,
			Key: key
		};

		return dynamodb.deleteItemAsync(params);

	};

	return {
		list: list,
		query: query,
		get: get,
		getItems: getItems,
		create: create,
		createItems: createItems,
		update: update,
		remove: remove,
	};

};<commit_msg>Empty array check for getItems<commit_after>var AWS = require('aws-sdk'),
	Promise = require("bluebird"),
	shortid = require('shortid');

var utils = require("./utils");

module.exports = function(awsconfig, dynamodboptions) {

	AWS.config.update(awsconfig);

	var dynamodb = new Promise.promisifyAll(new AWS.DynamoDB(dynamodboptions));

	var query = function(table, conditions, index, options) {

		var params = {
			TableName: table
		};

		if (index) {
			params.IndexName = index;
		}

		// Legacy KeyConditions are in use
		if (conditions.constructor === Array) {

			var keys = {};
			conditions.forEach(function(condition) {

				keys[condition.key] = {
					ComparisonOperator: condition.operator,
					AttributeValueList: [utils.itemize(condition.value)],
				};

			});

			params.KeyConditions = keys;

		}

		// KeyConditionExpression are in use
		if (conditions.constructor === Object) {

			params.KeyConditionExpression = conditions.KeyConditionExpression;
			params.ExpressionAttributeNames = conditions.ExpressionAttributeNames;

			var ExpressionAttributeValues = {};

			var values = conditions.ExpressionAttributeValues;

			for (var p in values) {
				if (!values.hasOwnProperty(p)) {
					continue;
				}
				ExpressionAttributeValues[p] = utils.itemize(values[p]);
			}

			params.ExpressionAttributeValues = ExpressionAttributeValues;

		}

		if (options && options.reverse) {
			params.ScanIndexForward = false;
		}

		if (options && options.limit) {
			params.Limit = options.limit;
		}

		if (options && options.filter) {

			var queryFilter = {};

			options.filter.forEach(function(condition) {

				queryFilter[condition.key] = {
					ComparisonOperator: condition.operator,
					AttributeValueList: [utils.itemize(condition.value)],
				};

			});

			params.QueryFilter = queryFilter;

		}

		return dynamodb.queryAsync(params).then(function(data) {

			var items = [];
			data.Items.forEach(function(item) {
				items.push(utils.deitemize(item));
			});
			return items;

		});

	};

	var list = function(table, conditions) {

		var params = {
			TableName: table
		};

		var keys = {};
		conditions.forEach(function(condition) {

			keys[condition.key] = {
				ComparisonOperator: condition.operator,
				AttributeValueList: [utils.itemize(condition.value)],
			};

		});

		params.ScanFilter = keys;

		return dynamodb.scanAsync(params).then(function(data) {

			var items = [];
			data.Items.forEach(function(item) {
				items.push(utils.deitemize(item));
			});

			return items;

		});

	};

	var get = function(table, id) {

		var params = {
			TableName: table,
			Key: {
				"id": {
					"S": id
				}
			}
		};

		return dynamodb.getItemAsync(params).then(function(data) {

			return utils.deitemize(data.Item);

		});

	};

	var getItems = function(table, ids) {

		if (ids.constructor !== Array) {
			throw Error("ids is not an Array");
		}

		if (ids.length === 0) {
			return Promise.resolve([]);
		}

 		var params = {
			RequestItems: {}
		};

		var keys = ids.map(function(id) {
			return {
				"id": utils.itemize(id)
			};
		});

		params.RequestItems[table] = {
			ConsistentRead: true,
			Keys: keys
		};

		return dynamodb.batchGetItemAsync(params).then(function(data) {

			var output = [];
			if (!data.Responses) {
				return output;
			}

			data.Responses[table].forEach(function(item) {
				output.push(utils.deitemize(item));
			});

			return output;

		});

	};

	var create = function(table, document, conditions) {

		document.id = shortid.generate();

		var item = {};
		Object.keys(document).forEach(function(key) {
			item[key] = utils.itemize(document[key]);
		});

		var params = {
			ReturnConsumedCapacity: "TOTAL",
			ReturnItemCollectionMetrics: "SIZE",
			ReturnValues: "ALL_OLD",
			TableName: table,
			Item: item
		};

		// KeyConditionExpression are in use
		if (conditions && conditions.constructor === Object) {

			params.ConditionExpression = conditions.ConditionExpression;

			if (conditions.ExpressionAttributeNames) {
				params.ExpressionAttributeNames = conditions.ExpressionAttributeNames;
			}

			var ExpressionAttributeValues = {};

			var values = conditions.ExpressionAttributeValues;

			for (var p in values) {
				if (!values.hasOwnProperty(p)) {
					continue;
				}
				ExpressionAttributeValues[p] = utils.itemize(values[p]);
			}

			params.ExpressionAttributeValues = ExpressionAttributeValues;

		}

		return dynamodb.putItemAsync(params).then(function(data) {

			return document;

		});

	};

	var createItems = function(table, documents) {

		var maxWriteItems = 25; // Currently 25 on AWS

		// Returns a promise of the wripte operation
		var getWriteOperation = function(documentsToWrite) {

			// Constructs the request
			var params = {
				RequestItems: {}
			};

			params.RequestItems[table] = [];

			documentsToWrite.forEach(function(document) {

				// Dop not generate id if already present
				if (!document.id) {
					document.id = shortid.generate();
				}

				var item = {};
				Object.keys(document).forEach(function(key) {
					item[key] = utils.itemize(document[key]);
				});

				params.RequestItems[table].push({
					PutRequest: {
						Item: item
					}
				});

			});

			// Sends the request
			return dynamodb.batchWriteItemAsync(params);

		};

		var writeRequests = [];

		while (documents.length) {

			var documentsToWrite = documents.splice(0, maxWriteItems);

			var writeOperation = getWriteOperation(documentsToWrite);

			writeRequests.push(writeOperation);

		}

		// Wait for all promisses to be fullfilled
		return Promise.all(writeRequests).then(function() {

			// Return documents
			return documents;

		});

	};

	var update = function(table, document) {

		var items = {};
		Object.keys(document).forEach(function(key) {

			if (key === "id") {
				return;
			}

			if (document[key]) {
				items[key] = {
					Value: utils.itemize(document[key]),
					Action: "PUT"
				};
			} else {
				items[key] = {
					Action: "DELETE"
				};
			}

		});

		var params = {
			ReturnConsumedCapacity: "TOTAL",
			ReturnItemCollectionMetrics: "SIZE",
			ReturnValues: "ALL_NEW",
			Key: {
				"id": utils.itemize(document.id)
			},
			AttributeUpdates: items,
			TableName: table,
		};

		return dynamodb.updateItemAsync(params).then(function() {

			return document;

		});

	};

	var remove = function(table, document) {

		var key = {};
		Object.keys(document).forEach(function(k) {
			key[k] = utils.itemize(document[k]);
		});

		var params = {
			TableName: table,
			Key: key
		};

		return dynamodb.deleteItemAsync(params);

	};

	return {
		list: list,
		query: query,
		get: get,
		getItems: getItems,
		create: create,
		createItems: createItems,
		update: update,
		remove: remove,
	};

};<|endoftext|>


<commit_before>#!/usr/bin/env node

const _ = require('lodash/fp')
const axios = require('axios')
const moment = require('moment')
const asciichart = require ('asciichart')
const param = require('commander')

// command line parsing
param
    .version('1.0.1')
    .option('-d, --days <n>', 'number of days the chart will go back', parseInt)
    .option('-w, --width <n>', 'max terminal chart width', parseInt)
    .option('-h, --height <n>', 'max terminal chart height', parseInt)
    .parse(process.argv)

const days = _.defaultTo(300)(param.days)
const maxWidth = _.defaultTo(100)(param.width)
const maxHeight = _.defaultTo(14)(param.height)

const today = moment().format('YYYY-MM-DD')
const past = moment().subtract(days, 'days').format('YYYY-MM-DD')
const coindesk = `http://api.coindesk.com/v1/bpi/historical/close.json?start=${past}&end=${today}`
const coindeskCurrent = 'http://api.coindesk.com/v1/bpi/currentprice.json'

const current = async url => {
    const res = await axios.get(url)
    return _.flow(
        _.get('data.bpi'),
        _.at(['USD.rate_float', 'EUR.rate_float']),
        _.map(x => Number(x).toFixed(2))
    )(res)
}

const bitcoin = async url => {
    const res = await axios.get(url)
    return _.flow(
        _.get('data.bpi'),
        _.values,
        _.chunk(_.ceil(days/maxWidth)),
        _.map(_.mean)
    )(res)
}

const main = async () => {
    const history = await bitcoin(coindesk)
    const [dollar, euro] = await current(coindeskCurrent)
    console.log(asciichart.plot (history, { height: maxHeight }))
    console.log(`\t\t Bitcoin chart from ${past} to ${today}`)
    console.log(`\t\t Bitcoin current price ${dollar} US-Dollar / ${euro} Euro`)
}

main()
<commit_msg>explicit lodash import and parallel api requesting<commit_after>#!/usr/bin/env node

const {get, defaultTo, map, flow, at,
    values, chunk, ceil, mean} = require('lodash/fp')
const axios = require('axios')
const moment = require('moment')
const asciichart = require ('asciichart')
const param = require('commander')

// command line parsing
param
    .version('1.0.1')
    .option('-d, --days <n>', 'number of days the chart will go back', parseInt)
    .option('-w, --width <n>', 'max terminal chart width', parseInt)
    .option('-h, --height <n>', 'max terminal chart height', parseInt)
    .parse(process.argv)

const days = defaultTo(300)(param.days)
const maxWidth = defaultTo(100)(param.width)
const maxHeight = defaultTo(14)(param.height)

const today = moment().format('YYYY-MM-DD')
const past = moment().subtract(days, 'days').format('YYYY-MM-DD')
const coindesk = `http://api.coindesk.com/v1/bpi/historical/close.json?start=${past}&end=${today}`
const coindeskCurrent = 'http://api.coindesk.com/v1/bpi/currentprice.json'

const current = async url => {
    const res = await axios.get(url)
    return flow(
        get('data.bpi'),
        at(['USD.rate_float', 'EUR.rate_float']),
        map(x => Number(x).toFixed(2))
    )(res)
}

const bitcoin = async url => {
    const res = await axios.get(url)
    return flow(
        get('data.bpi'),
        values,
        chunk(ceil(days/maxWidth)),
        map(mean)
    )(res)
}

const main = async () => {
    const fetchApi = [bitcoin(coindesk), current(coindeskCurrent)]
    const [history, [dollar, euro]] = await Promise.all(fetchApi)
    console.log(asciichart.plot (history, { height: maxHeight }))
    console.log(`\t\t Bitcoin chart from ${past} to ${today}`)
    console.log(`\t\t Bitcoin current price ${dollar} US-Dollar / ${euro} Euro`)
}

main()
<|endoftext|>


<commit_before>var request = require('request');
var crypto = require('crypto');

module.exports = function (api_key, api_secret, api_url, version) {
  return new Buttercoin(api_key, api_secret, api_url, version);
};

function Buttercoin (api_key, api_secret, api_url, version) {
  this.apiKey = api_key;
  this.apiSecret = api_secret;
  this.version = version || "v1"
  this.apiUrl = api_url || "https://api.buttercoin.com"
};

Buttercoin.prototype.buildUrl = function (endpoint) {
  return this.apiUrl + "/" + this.version + "/" + endpoint;
}

Buttercoin.prototype.signUrl = function (urlString, timestamp) {
  var urlString = timestamp + urlString
  var hmac = crypto.createHmac('sha256', this.apiSecret).update(urlString).digest('base64');
  signedHash = new Buffer(hmac, 'base64').toString('utf8');
  return signedHash;
};

Buttercoin.prototype.getHeaders = function (signature, timestamp) {
  var headers = {
    'X-Buttercoin-Access-Key': this.apiKey,
    'X-Buttercoin-Signature': signature,
    'X-Buttercoin-Date': timestamp
  }
  return headers;
};

Buttercoin.prototype.getKey = function (timestamp, callback) {
  var url = this.buildUrl('key');
  var signature = this.signUrl(url, timestamp);

  request.get({
    url: url,
    json: true,
    strictSSL: true,
    headers: this.getHeaders(signature, timestamp)
  }, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 200) {
        callback(null, body);
      } else {
        callback(body);
      }
    }
  });
};

Buttercoin.prototype.getAccount = function (timestamp, callback) {
  var url = this.buildUrl('account');
  var signature = this.signUrl(url, timestamp);

  request.get({
    url: url,
    json: true,
    strictSSL: true,
    headers: this.getHeaders(signature, timestamp)
  }, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 200) {
        callback(null, body);
      } else {
        callback(body);
      }
    }
  });
};

Buttercoin.prototype.getBalances = function (timestamp, callback) {
  var url = this.buildUrl('account/balances');
  var signature = this.signUrl(url, timestamp);

  request.get({
    url: url,
    json: true,
    strictSSL: true,
    headers: this.getHeaders(signature, timestamp)
  }, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 200) {
        callback(null, body);
      } else {
        callback(body);
      }
    }
  });
};

Buttercoin.prototype.getDepositAddress = function (timestamp, callback) {
  var url = this.buildUrl('account/depositAddress');
  var signature = this.signUrl(url, timestamp);

  request.get({
    url: url,
    json: true,
    strictSSL: true,
    headers: this.getHeaders(signature, timestamp)
  }, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 200) {
        callback(null, body);
      } else {
        callback(body);
      }
    }
  });
};

Buttercoin.prototype.getOrders = function (queryParams, timestamp, callback) {
  var url = this.buildUrl('orders');
  var signature = this.signUrl(url, timestamp);

  request.get({
    url: url,
    qs: queryParams,
    json: true,
    strictSSL: true,
    headers: this.getHeaders(signature, timestamp)
  }, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 200) {
        callback(null, body);
      } else {
        callback(body);
      }
    }
  });
};

Buttercoin.prototype.getOrder = function (orderId, timestamp, callback) {
  var url = this.buildUrl('orders/' + orderId);
  var signature = this.signUrl(url, timestamp);

  request.get({
    url: url,
    json: true,
    strictSSL: true,
    headers: this.getHeaders(signature, timestamp)
  }, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 200) {
        callback(null, body);
      } else {
        callback(body);
      }
    }
  });
};

Buttercoin.prototype.cancelOrder = function (orderId, timestamp, callback) {
  var url = this.buildUrl('orders/' + orderId);
  var signature = this.signUrl(url, timestamp);

  request.del({
    url: url,
    json: true,
    strictSSL: true,
    headers: this.getHeaders(signature, timestamp)
  }, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 204) {
        callback(null, { status: 'Order canceled successfully' });
      } else {
        callback(body);
      }
    }
  });
};

Buttercoin.prototype.createOrder = function (params, timestamp, callback) {
  var url = this.buildUrl('orders');
  var signature = this.signUrl(url, timestamp);

  request.post({
    url: url,
    body: JSON.stringify(params),
    json: true,
    strictSSL: true,
    headers: this.getHeaders(signature, timestamp)
  }, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 202) {
        callback(null, { order: res.headers.location });
      } else {
        callback(body);
      }
    }
  });
};

Buttercoin.prototype.getTransactions = function (queryParams, timestamp, callback) {
  var url = this.buildUrl('transactions');
  var signature = this.signUrl(url, timestamp);

  request.get({
    url: url,
    qs: queryParams,
    json: true,
    strictSSL: true,
    headers: this.getHeaders(signature, timestamp)
  }, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 200) {
        callback(null, body);
      } else {
        callback(body);
      }
    }
  });
};

Buttercoin.prototype.getTransaction = function (trxnId, timestamp, callback) {
  var url = this.buildUrl('transactions/' + trxnId);
  var signature = this.signUrl(url, timestamp);

  request.get({
    url: url,
    json: true,
    strictSSL: true,
    headers: this.getHeaders(signature, timestamp)
  }, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 200) {
        callback(null, body);
      } else {
        callback(body);
      }
    }
  });
};

Buttercoin.prototype.cancelTransaction = function (orderId, timestamp, callback) {
  var url = this.buildUrl('transactions/' + trxnId);
  var signature = this.signUrl(url, timestamp);

  request.del({
    url: url,
    json: true,
    strictSSL: true,
    headers: this.getHeaders(signature, timestamp)
  }, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 204) {
        callback(null, { status: 'Order canceled successfully' });
      } else {
        callback(body);
      }
    }
  });
};

Buttercoin.prototype.createDeposit = function (params, timestamp, callback) {
  var url = this.buildUrl('transactions/deposit');
  var signature = this.signUrl(url, timestamp);

  request.post({
    url: url,
    body: JSON.stringify(params),
    json: true,
    strictSSL: true,
    headers: this.getHeaders(signature, timestamp)
  }, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 202) {
        callback(null, { transaction: res.headers.location });
      } else {
        callback(body);
      }
    }
  });
};

Buttercoin.prototype.createWithdrawal = function (params, timestamp, callback) {
  var url = this.buildUrl('transactions/withdrawal');
  var signature = this.signUrl(url, timestamp);

  request.post({
    url: url,
    body: JSON.stringify(params),
    json: true,
    strictSSL: true,
    headers: this.getHeaders(signature, timestamp)
  }, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 201) {
        callback(null, { status: 'Withdraw request created, but email confirmation is required' });
      } else if (res.statusCode === 202) {
        callback(null, { transaction: res.headers.location });
      } else {
        callback(body);
      }
    }
  });
};

Buttercoin.prototype.send = function (params, timestamp, callback) {
  var url = this.buildUrl('transactions/send');
  var signature = this.signUrl(url, timestamp);

  request.post({
    url: url,
    body: JSON.stringify(params),
    json: true,
    strictSSL: true,
    headers: this.getHeaders(signature, timestamp)
  }, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 201) {
        callback(null, { status: 'Send request created, but email confirmation is required' });
      } else if (res.statusCode === 202) {
        callback(null, { transaction: res.headers.location });
      } else {
        callback(body);
      }
    }
  });
};

Buttercoin.prototype.getOrderbook = function (timestamp, callback) {
  var url = this.buildUrl('orderbook');
  var signature = this.signUrl(url, timestamp);

  request.get({
    url: url,
    json: true,
    strictSSL: true,
    headers: this.getHeaders(signature, timestamp)
  }, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 200) {
        callback(null, body);
      } else {
        callback(body);
      }
    }
  });
};

Buttercoin.prototype.getTicker = function (timestamp, callback) {
  var url = this.buildUrl('ticker');
  var signature = this.signUrl(url, timestamp);

  request.get({
    url: url,
    json: true,
    strictSSL: true,
    headers: this.getHeaders(signature, timestamp)
  }, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 200) {
        callback(null, body);
      } else {
        callback(body);
      }
    }
  });
};

<commit_msg>all methods coded for first pass, still have to refine return values<commit_after>var request = require('request');
var crypto = require('crypto');

module.exports = function (api_key, api_secret, mode, version) {
  var api_url = 'http://api.qa.dcxft.com';
  if (mode && mode === 'production')
    api_url = 'http://api.buttercoin.com';
  return new Buttercoin(api_key, api_secret, api_url, version);
};

function Buttercoin (api_key, api_secret, api_url, version) {
  this.apiKey = api_key;
  this.apiSecret = api_secret;
  this.version = version || "v1" // default to latest version
  this.apiUrl = api_url || "https://api.buttercoin.com" // default to production
};

Buttercoin.prototype.buildUrl = function (endpoint) {
  return this.apiUrl + "/" + this.version + "/" + endpoint;
}

Buttercoin.prototype.signUrl = function (urlString, timestamp) {
  urlString = new Buffer(timestamp + urlString, 'UTF-8').toString('base64');
  var signedHash = crypto.createHmac('sha256', this.apiSecret).update(urlString).digest('base64');
  return signedHash;
};

Buttercoin.prototype.getHeaders = function (signature, timestamp) {
  var headers = {
    'X-Buttercoin-Access-Key': this.apiKey,
    'X-Buttercoin-Signature': signature,
    'X-Buttercoin-Date': timestamp
  }
  return headers;
};

Buttercoin.prototype.getKey = function (timestamp, callback) {
  var url = this.buildUrl('key');
  var signature = this.signUrl(url, timestamp);

  request.get({
    url: url,
    json: true,
    strictSSL: true,
    headers: this.getHeaders(signature, timestamp)
  }, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 200) {
        callback(null, body);
      } else {
        callback(body);
      }
    }
  });
};

Buttercoin.prototype.getBalances = function (timestamp, callback) {
  var url = this.buildUrl('account/balances');
  var signature = this.signUrl(url, timestamp);

  request.get({
    url: url,
    json: true,
    strictSSL: true,
    headers: this.getHeaders(signature, timestamp)
  }, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 200) {
        callback(null, body);
      } else {
        callback(body);
      }
    }
  });
};

Buttercoin.prototype.getDepositAddress = function (timestamp, callback) {
  var url = this.buildUrl('account/depositAddress');
  var signature = this.signUrl(url, timestamp);

  request.get({
    url: url,
    json: true,
    strictSSL: true,
    headers: this.getHeaders(signature, timestamp)
  }, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 200) {
        callback(null, body);
      } else {
        callback(body);
      }
    }
  });
};

Buttercoin.prototype.getOrders = function (queryParams, timestamp, callback) {
  var url = this.buildUrl('orders');
  var signature = this.signUrl(url, timestamp);

  request.get({
    url: url,
    qs: queryParams,
    json: true,
    strictSSL: true,
    headers: this.getHeaders(signature, timestamp)
  }, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 200) {
        callback(null, body);
      } else {
        callback(body);
      }
    }
  });
};

Buttercoin.prototype.getOrder = function (orderId, timestamp, callback) {
  var url = this.buildUrl('orders/' + orderId);
  var signature = this.signUrl(url, timestamp);

  request.get({
    url: url,
    json: true,
    strictSSL: true,
    headers: this.getHeaders(signature, timestamp)
  }, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 200) {
        callback(null, body);
      } else {
        callback(body);
      }
    }
  });
};

Buttercoin.prototype.cancelOrder = function (orderId, timestamp, callback) {
  var url = this.buildUrl('orders/' + orderId);
  var signature = this.signUrl(url, timestamp);

  request.del({
    url: url,
    json: true,
    strictSSL: true,
    headers: this.getHeaders(signature, timestamp)
  }, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 204) {
        callback(null, { status: 'Order canceled successfully' });
      } else {
        callback(body);
      }
    }
  });
};

Buttercoin.prototype.createOrder = function (params, timestamp, callback) {
  var url = this.buildUrl('orders');
  var signature = this.signUrl(url, timestamp);

  request.post({
    url: url,
    json: params,
    strictSSL: true,
    headers: this.getHeaders(signature, timestamp)
  }, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 202) {
        callback(null, { order: res.headers.location });
      } else {
        callback(body);
      }
    }
  });
};

Buttercoin.prototype.getTransactions = function (queryParams, timestamp, callback) {
  var url = this.buildUrl('transactions');
  var signature = this.signUrl(url, timestamp);

  request.get({
    url: url,
    qs: queryParams,
    json: true,
    strictSSL: true,
    headers: this.getHeaders(signature, timestamp)
  }, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 200) {
        callback(null, body);
      } else {
        callback(body);
      }
    }
  });
};

Buttercoin.prototype.getTransaction = function (trxnId, timestamp, callback) {
  var url = this.buildUrl('transactions/' + trxnId);
  var signature = this.signUrl(url, timestamp);

  request.get({
    url: url,
    json: true,
    strictSSL: true,
    headers: this.getHeaders(signature, timestamp)
  }, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 200) {
        callback(null, body);
      } else {
        callback(body);
      }
    }
  });
};

Buttercoin.prototype.cancelTransaction = function (trxnId, timestamp, callback) {
  var url = this.buildUrl('transactions/' + trxnId);
  var signature = this.signUrl(url, timestamp);

  request.del({
    url: url,
    json: true,
    strictSSL: true,
    headers: this.getHeaders(signature, timestamp)
  }, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 204) {
        callback(null, { status: 'Order canceled successfully' });
      } else {
        callback(body);
      }
    }
  });
};

Buttercoin.prototype.createDeposit = function (params, timestamp, callback) {
  var url = this.buildUrl('transactions/deposit');
  var signature = this.signUrl(url, timestamp);

  request.post({
    url: url,
    body: JSON.stringify(params),
    json: true,
    strictSSL: true,
    headers: this.getHeaders(signature, timestamp)
  }, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 202) {
        callback(null, { transaction: res.headers.location });
      } else {
        callback(body);
      }
    }
  });
};

Buttercoin.prototype.createWithdrawal = function (params, timestamp, callback) {
  var url = this.buildUrl('transactions/withdrawal');
  var signature = this.signUrl(url, timestamp);

  request.post({
    url: url,
    body: JSON.stringify(params),
    json: true,
    strictSSL: true,
    headers: this.getHeaders(signature, timestamp)
  }, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 201) {
        callback(null, { status: 'Withdraw request created, but email confirmation is required' });
      } else if (res.statusCode === 202) {
        callback(null, { transaction: res.headers.location });
      } else {
        callback(body);
      }
    }
  });
};

Buttercoin.prototype.send = function (params, timestamp, callback) {
  var url = this.buildUrl('transactions/send');
  var signature = this.signUrl(url, timestamp);

  request.post({
    url: url,
    body: JSON.stringify(params),
    json: true,
    strictSSL: true,
    headers: this.getHeaders(signature, timestamp)
  }, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 201) {
        callback(null, { status: 'Send request created, but email confirmation is required' });
      } else if (res.statusCode === 202) {
        callback(null, { transaction: res.headers.location });
      } else {
        callback(body);
      }
    }
  });
};

Buttercoin.prototype.getOrderbook = function (timestamp, callback) {
  var url = this.buildUrl('orderbook');
  var signature = this.signUrl(url, timestamp);

  request.get({
    url: url,
    json: true,
    strictSSL: true,
    headers: this.getHeaders(signature, timestamp)
  }, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 200) {
        callback(null, body);
      } else {
        callback(body);
      }
    }
  });
};

Buttercoin.prototype.getTicker = function (timestamp, callback) {
  var url = this.buildUrl('ticker');
  var signature = this.signUrl(url, timestamp);

  request.get({
    url: url,
    json: true,
    strictSSL: true,
    headers: this.getHeaders(signature, timestamp)
  }, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 200) {
        callback(null, body);
      } else {
        callback(body);
      }
    }
  });
};
<|endoftext|>


<commit_before>var express = require('express'),
    bodyParser = require('body-parser'),
    mongoose = require('mongoose'),
    config = require('./config.js'),
    app = express();

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
  extended: true
}));

mongoose.connect(process.env.MONGOLAB_URI || process.env.MONGOHQ_URL || config.database);
var db = mongoose.connection;
db.on('error', console.error);
db.once('open', function(){
	console.log('Mongoose is working!');
});

var router = express.Router();
require('./routes/entry.js')(router);
require('./routes/contributor.js')(router);
require('./routes/tag.js')(router);
app.use('/api/v1', router);

var server = app.listen(process.env.PORT || config.port, function() {

  var host = server.address().address;
  var port = server.address().port;

  console.log('Spendy API server started at port', port);

});<commit_msg>delete duplicate file<commit_after><|endoftext|>


<commit_before>var discovery = require('discovery-channel')
var pump = require('pump')
var events = require('events')
var util = require('util')
var net = require('net')
var equals = require('buffer-equals')
var toBuffer = require('to-buffer')
var crypto = require('crypto')
var lpmessage = require('length-prefixed-message')
var connections = require('connections')

try {
  var utp = require('utp-native')
} catch (err) {
  // do nothing
}

var PEER_SEEN = 1
var PEER_BANNED = 2

var HANDSHAKE_TIMEOUT = 5000
var CONNECTION_TIMEOUT = 3000
var RECONNECT_WAIT = [1000, 1000, 5000, 15000]
// var DEFAULT_SIZE = 100 // TODO enable max connections

module.exports = Swarm

function Swarm (opts) {
  if (!(this instanceof Swarm)) return new Swarm(opts)
  if (!opts) opts = {}
  events.EventEmitter.call(this)

  var self = this

  this.maxConnections = opts.maxConnections || 0
  this.totalConnections = 0

  this.connections = []
  this.id = opts.id || crypto.randomBytes(32)
  this.destroyed = false

  this._stream = opts.stream
  this._options = opts || {}
  this._discovery = null
  this._tcp = opts.tcp === false ? null : net.createServer().on('connection', onconnection)
  this._utp = opts.utp === false || !utp ? null : utp().on('connection', onconnection)
  this._tcpConnections = this._tcp && connections(this._tcp)
  this._adding = null
  this._listening = false

  this._peersIds = {}
  this._peersSeen = {}
  this._peersQueued = []

  if (this._options.discovery !== false) this.on('listening', this._ondiscover)

  function onconnection (connection) {
    var type = this === this._tcp ? 'tcp' : 'utp'
    connection.on('error', onerror)
    self._onconnection(connection, type, null)
  }
}

util.inherits(Swarm, events.EventEmitter)

Swarm.prototype.close =
Swarm.prototype.destroy = function (onclose) {
  if (this.destroyed) return process.nextTick(onclose || noop)
  if (onclose) this.once('close', onclose)
  if (this._listening && this._adding) return this.once('listening', this.destroy)

  this.destroyed = true
  if (this._discovery) this._discovery.destroy()

  var self = this
  var missing = 0

  if (this._utp) {
    missing++
    for (var i = 0; i < this._utp.connections.length; i++) {
      this._utp.connections[i].destroy()
    }
  }

  if (this._tcp) {
    missing++
    this._tcpConnections.destroy()
  }

  if (this._listening) {
    if (this._tcp) this._tcp.close(onserverclose)
    if (this._utp) this._utp.close(onserverclose)
  }

  function onserverclose () {
    if (!--missing) self.emit('close')
  }
}

Swarm.prototype.__defineGetter__('queued', function () {
  return this._peersQueued.length
})

Swarm.prototype.__defineGetter__('connecting', function () {
  return this.totalConnections - this.connections.length
})

Swarm.prototype.__defineGetter__('connected', function () {
  return this.connections.length
})

Swarm.prototype.join = function (name) {
  name = toBuffer(name)

  if (!this._listening && !this._adding) this._listenNext()

  if (this._adding) {
    this._adding.push(name)
  } else {
    this._discovery.join(name, this._tcp.address().port, {impliedPort: !!this._utp})
  }
}

Swarm.prototype.leave = function (name) {
  name = toBuffer(name)

  if (this._adding) {
    for (var i = 0; i < this._adding.length; i++) {
      if (equals(this._adding[i], name)) {
        this._adding.splice(i, 1)
        return
      }
    }
  } else {
    this._discovery.leave(name, this._tcp.address().port)
  }
}

Swarm.prototype.addPeer = function (peer) {
  peer = peerify(peer)
  if (this._peersSeen[peer.id]) return
  this._peersSeen[peer.id] = PEER_SEEN
  this._peersQueued.push(peer)
  this.emit('peer', peer)
  this._kick()
}

Swarm.prototype.removePeer = function (peer) {
  peer = peerify(peer)
  this._peersSeen[peer.id] = PEER_BANNED
  // delete this._peersSeen[peer.id]
}

Swarm.prototype.address = function () {
  return this._tcp ? this._tcp.address() : this._utp.address()
}

Swarm.prototype._ondiscover = function () {
  var self = this
  var names = this._adding

  if (this._options.dns !== false) {
    if (!this._options.dns || this._options.dns === true) this._options.dns = {}
    this._options.dns.socket = this._utp
  }

  if (this._options.dht !== false) {
    if (!this._options.dht || this._options.dht === true) this._options.dht = {}
    this._options.dht.socket = this._utp
  }

  this._discovery = discovery(this._options)
  this._discovery.on('peer', onpeer)
  this._discovery.on('whoami', onwhoami)
  this._adding = null

  if (!names) return
  for (var i = 0; i < names.length; i++) this.join(names[i])

  function onwhoami (me) {
    self._peersSeen[me.host + ':' + me.port] = PEER_BANNED
  }

  function onpeer (channel, peer) {
    var id = peer.host + ':' + peer.port
    if (self._peersSeen[id]) return
    self._peersSeen[id] = PEER_SEEN
    self._peersQueued.push(peerify(peer))
    self.emit('peer', peer)
    self._kick()
  }
}

Swarm.prototype._kick = function () {
  if (this.maxConnections && this.totalConnections >= this.maxConnections) return
  if (this.destroyed) return

  var self = this
  var connected = false
  var next = this._peersQueued.shift()
  while (next && this._peersSeen[next.id] === PEER_BANNED) {
    next = this._peersQueued.shift()
  }

  if (!next) return

  this.totalConnections++
  this.emit('connecting', next)

  var tcpSocket = null
  var utpSocket = null
  var tcpClosed = true
  var utpClosed = true

  if (this._tcp) {
    tcpClosed = false
    tcpSocket = net.connect(next.port, next.host)
    tcpSocket.on('connect', onconnect)
    tcpSocket.on('error', onerror)
    tcpSocket.on('close', onclose)
    this._tcpConnections.add(tcpSocket)
  }

  if (this._utp) {
    utpClosed = false
    utpSocket = this._utp.connect(next.port, next.host)
    utpSocket.on('connect', onconnect)
    utpSocket.on('error', onerror)
    utpSocket.on('close', onclose)
  }

  var timeout = setTimeoutUnref(ontimeout, CONNECTION_TIMEOUT)

  function ontimeout () {
    if (utpSocket) utpSocket.destroy()
    if (tcpSocket) tcpSocket.destroy()
  }

  function onclose () {
    if (this === utpSocket) utpClosed = true
    if (this === tcpSocket) tcpClosed = true
    if (tcpClosed && utpClosed) {
      clearTimeout(timeout)
      if (utpSocket) utpSocket.removeListener('close', onclose)
      if (tcpSocket) tcpSocket.removeListener('close', onclose)
      self.totalConnections--
      if (!connected) self._requeue(next)
    }
  }

  function onconnect () {
    connected = true
    utpClosed = tcpClosed = true
    onclose() // decs totalConnections which _onconnection also incs

    var type = this === utpSocket ? 'utp' : 'tcp'

    if (type === 'utp' && tcpSocket) tcpSocket.destroy()
    if (type === 'tcp' && utpSocket) utpSocket.destroy()

    self._onconnection(this, type, next)
  }
}

Swarm.prototype._requeue = function (peer) {
  if (this.destroyed) return

  var self = this
  var wait = peer.retries >= RECONNECT_WAIT.length ? 0 : RECONNECT_WAIT[peer.retries++]
  if (wait) setTimeoutUnref(requeue, wait)
  else this.emit('drop', peer)

  function requeue () {
    self._peersQueued.push(peer)
    self._kick()
  }
}

Swarm.prototype._onconnection = function (connection, type, peer) {
  var self = this
  var idHex = this.id.toString('hex')
  var remoteIdHex

  this.totalConnections++
  connection.on('close', onclose)

  if (this._stream) {
    var wire = connection
    connection = this._stream()
    if (connection.id) idHex = connection.id.toString('hex')
    connection.on('handshake', onhandshake)
    pump(wire, connection, wire)
  } else {
    handshake(connection, this.id, onhandshake)
  }

  var timeout = setTimeoutUnref(ontimeout, HANDSHAKE_TIMEOUT)
  if (this.destroyed) connection.destroy()

  function ontimeout () {
    connection.destroy()
  }

  function onclose () {
    clearTimeout(timeout)
    self.totalConnections--

    var i = self.connections.indexOf(connection)
    if (i > -1) {
      var last = self.connections.pop()
      if (last !== connection) self.connections[i] = last
    }

    if (remoteIdHex && self._peersIds[remoteIdHex] === connection) {
      delete self._peersIds[remoteIdHex]
      if (peer) self._requeue(peer)
    }
  }

  function onhandshake (remoteId) {
    if (!remoteId) remoteId = connection.remoteId
    clearTimeout(timeout)
    remoteIdHex = remoteId.toString('hex')
    if (peer) peer.retries = 0

    if (idHex === remoteIdHex) {
      if (peer) self._peersSeen[peer.id] = PEER_BANNED
      connection.destroy()
      return
    }

    var old = self._peersIds[remoteIdHex]

    if (old) {
      if ((peer && remoteIdHex < idHex) || (!peer && remoteIdHex > idHex)) {
        connection.destroy()
        return
      }
      delete self._peersIds[remoteIdHex] // delete to not trigger re-queue
      old.destroy()
      old = null // help gc
    }

    self._peersIds[remoteIdHex] = connection
    self.connections.push(connection)
    self.emit('connection', connection, remoteId)
  }
}

Swarm.prototype._listenNext = function () {
  var self = this
  if (!this._adding) this._adding = []
  process.nextTick(function () {
    if (!self._listening) self.listen()
  })
}

Swarm.prototype.listen = function (port, onlistening) {
  if (this._tcp && this._utp) return this._listenBoth(port, onlistening)
  if (!port) port = 0
  if (onlistening) this.once('listening', onlistening)

  var self = this
  var server = this._tcp || this._utp

  if (!this._listening) {
    this._listening = true
    server.on('error', onerror)
    server.on('listening', onlisten)
  }

  if (!this._adding) this._adding = []
  server.listen(port)

  function onerror (err) {
    self.emit('error', err)
  }

  function onlisten () {
    self.emit('listening')
  }
}

Swarm.prototype._listenBoth = function (port, onlistening) {
  if (typeof port === 'function') return this.listen(0, port)
  if (!port) port = 0
  if (onlistening) this.once('listening', onlistening)

  var self = this

  if (!this._adding) this._adding = []
  this._listening = true

  this._utp.on('error', onerror)
  this._utp.on('listening', onutplisten)
  this._tcp.on('listening', ontcplisten)
  this._tcp.on('error', onerror)
  this._tcp.listen(port)

  function cleanup () {
    self._utp.removeListener('error', onerror)
    self._tcp.removeListener('error', onerror)
    self._utp.removeListener('listening', onutplisten)
    self._tcp.removeListener('listening', ontcplisten)
  }

  function onerror (err) {
    cleanup()
    self._tcp.close(function () {
      if (!port) return self.listen() // retry
      self.emit('error', err)
    })
  }

  function onutplisten () {
    cleanup()
    self._utp.on('error', forward)
    self._tcp.on('error', forward)
    self.emit('listening')
  }

  function ontcplisten () {
    self._utp.listen(this.address().port)
  }

  function forward (err) {
    self.emit('error', err)
  }
}

function handshake (socket, id, cb) {
  lpmessage.write(socket, id)
  lpmessage.read(socket, cb)
}

function onerror () {
  this.destroy()
}

function peerify (peer) {
  if (typeof peer === 'number') peer = {port: peer}
  if (!peer.host) peer.host = '127.0.0.1'
  peer.id = peer.host + ':' + peer.port
  peer.retries = 0
  return peer
}

function setTimeoutUnref (fn, time) {
  var timeout = setTimeout(fn, time)
  if (timeout.unref) timeout.unref()
  return timeout
}

function noop () {}
<commit_msg>when dropping, allow re-discovery<commit_after>var discovery = require('discovery-channel')
var pump = require('pump')
var events = require('events')
var util = require('util')
var net = require('net')
var equals = require('buffer-equals')
var toBuffer = require('to-buffer')
var crypto = require('crypto')
var lpmessage = require('length-prefixed-message')
var connections = require('connections')

try {
  var utp = require('utp-native')
} catch (err) {
  // do nothing
}

var PEER_SEEN = 1
var PEER_BANNED = 2

var HANDSHAKE_TIMEOUT = 5000
var CONNECTION_TIMEOUT = 3000
var RECONNECT_WAIT = [1000, 1000, 5000, 15000]
// var DEFAULT_SIZE = 100 // TODO enable max connections

module.exports = Swarm

function Swarm (opts) {
  if (!(this instanceof Swarm)) return new Swarm(opts)
  if (!opts) opts = {}
  events.EventEmitter.call(this)

  var self = this

  this.maxConnections = opts.maxConnections || 0
  this.totalConnections = 0

  this.connections = []
  this.id = opts.id || crypto.randomBytes(32)
  this.destroyed = false

  this._stream = opts.stream
  this._options = opts || {}
  this._discovery = null
  this._tcp = opts.tcp === false ? null : net.createServer().on('connection', onconnection)
  this._utp = opts.utp === false || !utp ? null : utp().on('connection', onconnection)
  this._tcpConnections = this._tcp && connections(this._tcp)
  this._adding = null
  this._listening = false

  this._peersIds = {}
  this._peersSeen = {}
  this._peersQueued = []

  if (this._options.discovery !== false) this.on('listening', this._ondiscover)

  function onconnection (connection) {
    var type = this === this._tcp ? 'tcp' : 'utp'
    connection.on('error', onerror)
    self._onconnection(connection, type, null)
  }
}

util.inherits(Swarm, events.EventEmitter)

Swarm.prototype.close =
Swarm.prototype.destroy = function (onclose) {
  if (this.destroyed) return process.nextTick(onclose || noop)
  if (onclose) this.once('close', onclose)
  if (this._listening && this._adding) return this.once('listening', this.destroy)

  this.destroyed = true
  if (this._discovery) this._discovery.destroy()

  var self = this
  var missing = 0

  if (this._utp) {
    missing++
    for (var i = 0; i < this._utp.connections.length; i++) {
      this._utp.connections[i].destroy()
    }
  }

  if (this._tcp) {
    missing++
    this._tcpConnections.destroy()
  }

  if (this._listening) {
    if (this._tcp) this._tcp.close(onserverclose)
    if (this._utp) this._utp.close(onserverclose)
  }

  function onserverclose () {
    if (!--missing) self.emit('close')
  }
}

Swarm.prototype.__defineGetter__('queued', function () {
  return this._peersQueued.length
})

Swarm.prototype.__defineGetter__('connecting', function () {
  return this.totalConnections - this.connections.length
})

Swarm.prototype.__defineGetter__('connected', function () {
  return this.connections.length
})

Swarm.prototype.join = function (name) {
  name = toBuffer(name)

  if (!this._listening && !this._adding) this._listenNext()

  if (this._adding) {
    this._adding.push(name)
  } else {
    this._discovery.join(name, this._tcp.address().port, {impliedPort: !!this._utp})
  }
}

Swarm.prototype.leave = function (name) {
  name = toBuffer(name)

  if (this._adding) {
    for (var i = 0; i < this._adding.length; i++) {
      if (equals(this._adding[i], name)) {
        this._adding.splice(i, 1)
        return
      }
    }
  } else {
    this._discovery.leave(name, this._tcp.address().port)
  }
}

Swarm.prototype.addPeer = function (peer) {
  peer = peerify(peer)
  if (this._peersSeen[peer.id]) return
  this._peersSeen[peer.id] = PEER_SEEN
  this._peersQueued.push(peer)
  this.emit('peer', peer)
  this._kick()
}

Swarm.prototype.removePeer = function (peer) {
  peer = peerify(peer)
  this._peersSeen[peer.id] = PEER_BANNED
}

Swarm.prototype._dropPeer = function (peer) {
  delete this._peersSeen[peer.id]
  this.emit('drop', peer)
}

Swarm.prototype.address = function () {
  return this._tcp ? this._tcp.address() : this._utp.address()
}

Swarm.prototype._ondiscover = function () {
  var self = this
  var names = this._adding

  if (this._options.dns !== false) {
    if (!this._options.dns || this._options.dns === true) this._options.dns = {}
    this._options.dns.socket = this._utp
  }

  if (this._options.dht !== false) {
    if (!this._options.dht || this._options.dht === true) this._options.dht = {}
    this._options.dht.socket = this._utp
  }

  this._discovery = discovery(this._options)
  this._discovery.on('peer', onpeer)
  this._discovery.on('whoami', onwhoami)
  this._adding = null

  if (!names) return
  for (var i = 0; i < names.length; i++) this.join(names[i])

  function onwhoami (me) {
    self._peersSeen[me.host + ':' + me.port] = PEER_BANNED
  }

  function onpeer (channel, peer) {
    var id = peer.host + ':' + peer.port
    if (self._peersSeen[id]) return
    self._peersSeen[id] = PEER_SEEN
    self._peersQueued.push(peerify(peer))
    self.emit('peer', peer)
    self._kick()
  }
}

Swarm.prototype._kick = function () {
  if (this.maxConnections && this.totalConnections >= this.maxConnections) return
  if (this.destroyed) return

  var self = this
  var connected = false
  var next = this._peersQueued.shift()
  while (next && this._peersSeen[next.id] === PEER_BANNED) {
    next = this._peersQueued.shift()
  }

  if (!next) return

  this.totalConnections++
  this.emit('connecting', next)

  var tcpSocket = null
  var utpSocket = null
  var tcpClosed = true
  var utpClosed = true

  if (this._tcp) {
    tcpClosed = false
    tcpSocket = net.connect(next.port, next.host)
    tcpSocket.on('connect', onconnect)
    tcpSocket.on('error', onerror)
    tcpSocket.on('close', onclose)
    this._tcpConnections.add(tcpSocket)
  }

  if (this._utp) {
    utpClosed = false
    utpSocket = this._utp.connect(next.port, next.host)
    utpSocket.on('connect', onconnect)
    utpSocket.on('error', onerror)
    utpSocket.on('close', onclose)
  }

  var timeout = setTimeoutUnref(ontimeout, CONNECTION_TIMEOUT)

  function ontimeout () {
    if (utpSocket) utpSocket.destroy()
    if (tcpSocket) tcpSocket.destroy()
  }

  function onclose () {
    if (this === utpSocket) utpClosed = true
    if (this === tcpSocket) tcpClosed = true
    if (tcpClosed && utpClosed) {
      clearTimeout(timeout)
      if (utpSocket) utpSocket.removeListener('close', onclose)
      if (tcpSocket) tcpSocket.removeListener('close', onclose)
      self.totalConnections--
      if (!connected) self._requeue(next)
    }
  }

  function onconnect () {
    connected = true
    utpClosed = tcpClosed = true
    onclose() // decs totalConnections which _onconnection also incs

    var type = this === utpSocket ? 'utp' : 'tcp'

    if (type === 'utp' && tcpSocket) tcpSocket.destroy()
    if (type === 'tcp' && utpSocket) utpSocket.destroy()

    self._onconnection(this, type, next)
  }
}

Swarm.prototype._requeue = function (peer) {
  if (this.destroyed) return

  var self = this
  var wait = peer.retries >= RECONNECT_WAIT.length ? 0 : RECONNECT_WAIT[peer.retries++]
  if (wait) setTimeoutUnref(requeue, wait)
  else this._dropPeer(peer)

  function requeue () {
    self._peersQueued.push(peer)
    self._kick()
  }
}

Swarm.prototype._onconnection = function (connection, type, peer) {
  var self = this
  var idHex = this.id.toString('hex')
  var remoteIdHex

  this.totalConnections++
  connection.on('close', onclose)

  if (this._stream) {
    var wire = connection
    connection = this._stream()
    if (connection.id) idHex = connection.id.toString('hex')
    connection.on('handshake', onhandshake)
    pump(wire, connection, wire)
  } else {
    handshake(connection, this.id, onhandshake)
  }

  var timeout = setTimeoutUnref(ontimeout, HANDSHAKE_TIMEOUT)
  if (this.destroyed) connection.destroy()

  function ontimeout () {
    connection.destroy()
  }

  function onclose () {
    clearTimeout(timeout)
    self.totalConnections--

    var i = self.connections.indexOf(connection)
    if (i > -1) {
      var last = self.connections.pop()
      if (last !== connection) self.connections[i] = last
    }

    if (remoteIdHex && self._peersIds[remoteIdHex] === connection) {
      delete self._peersIds[remoteIdHex]
      if (peer) self._requeue(peer)
    }
  }

  function onhandshake (remoteId) {
    if (!remoteId) remoteId = connection.remoteId
    clearTimeout(timeout)
    remoteIdHex = remoteId.toString('hex')
    if (peer) peer.retries = 0

    if (idHex === remoteIdHex) {
      if (peer) self._peersSeen[peer.id] = PEER_BANNED
      connection.destroy()
      return
    }

    var old = self._peersIds[remoteIdHex]

    if (old) {
      if ((peer && remoteIdHex < idHex) || (!peer && remoteIdHex > idHex)) {
        connection.destroy()
        return
      }
      delete self._peersIds[remoteIdHex] // delete to not trigger re-queue
      old.destroy()
      old = null // help gc
    }

    self._peersIds[remoteIdHex] = connection
    self.connections.push(connection)
    self.emit('connection', connection, remoteId)
  }
}

Swarm.prototype._listenNext = function () {
  var self = this
  if (!this._adding) this._adding = []
  process.nextTick(function () {
    if (!self._listening) self.listen()
  })
}

Swarm.prototype.listen = function (port, onlistening) {
  if (this._tcp && this._utp) return this._listenBoth(port, onlistening)
  if (!port) port = 0
  if (onlistening) this.once('listening', onlistening)

  var self = this
  var server = this._tcp || this._utp

  if (!this._listening) {
    this._listening = true
    server.on('error', onerror)
    server.on('listening', onlisten)
  }

  if (!this._adding) this._adding = []
  server.listen(port)

  function onerror (err) {
    self.emit('error', err)
  }

  function onlisten () {
    self.emit('listening')
  }
}

Swarm.prototype._listenBoth = function (port, onlistening) {
  if (typeof port === 'function') return this.listen(0, port)
  if (!port) port = 0
  if (onlistening) this.once('listening', onlistening)

  var self = this

  if (!this._adding) this._adding = []
  this._listening = true

  this._utp.on('error', onerror)
  this._utp.on('listening', onutplisten)
  this._tcp.on('listening', ontcplisten)
  this._tcp.on('error', onerror)
  this._tcp.listen(port)

  function cleanup () {
    self._utp.removeListener('error', onerror)
    self._tcp.removeListener('error', onerror)
    self._utp.removeListener('listening', onutplisten)
    self._tcp.removeListener('listening', ontcplisten)
  }

  function onerror (err) {
    cleanup()
    self._tcp.close(function () {
      if (!port) return self.listen() // retry
      self.emit('error', err)
    })
  }

  function onutplisten () {
    cleanup()
    self._utp.on('error', forward)
    self._tcp.on('error', forward)
    self.emit('listening')
  }

  function ontcplisten () {
    self._utp.listen(this.address().port)
  }

  function forward (err) {
    self.emit('error', err)
  }
}

function handshake (socket, id, cb) {
  lpmessage.write(socket, id)
  lpmessage.read(socket, cb)
}

function onerror () {
  this.destroy()
}

function peerify (peer) {
  if (typeof peer === 'number') peer = {port: peer}
  if (!peer.host) peer.host = '127.0.0.1'
  peer.id = peer.host + ':' + peer.port
  peer.retries = 0
  return peer
}

function setTimeoutUnref (fn, time) {
  var timeout = setTimeout(fn, time)
  if (timeout.unref) timeout.unref()
  return timeout
}

function noop () {}
<|endoftext|>


<commit_before>process.setMaxListeners(100);

const Discord = require('discord.js');
const tokens = require("./token");
const instantiateCommands = require("./instantiateCommands");
const instantiateUtilities = require("./instantiateUtilities");
const client = new Discord.Client();
client.setMaxListeners(0);

const commandList = new (require('./src/CommandContainer'));
const dependencyGraph = {
	'discordClient': client,
	'commandPrefix': '!',
	'commandList': commandList,
	'https': require('https')
};
for (let key in instantiateCommands) {
	if (!instantiateCommands.hasOwnProperty(key)) continue;
	let commandPath = './src/Command/' + instantiateCommands[key];
	let command = new (require(commandPath));
	command.initialize(dependencyGraph);

	commandList.add(key, command);
}

for (let key in instantiateUtilities) {
	if (!instantiateUtilities.hasOwnProperty(key)) continue;
	let utilityPath = './src/Utility/' + instantiateUtilities[key];
	let utility = new (require(utilityPath));
	utility.initialize(dependencyGraph);
}

client.on('ready', () => {
	client.user.setActivity("on Shotbow");
	console.log("Successfully logged in!");
});

client.login(tokens.getToken());<commit_msg>Remove unnecessary line<commit_after>const Discord = require('discord.js');
const tokens = require("./token");
const instantiateCommands = require("./instantiateCommands");
const instantiateUtilities = require("./instantiateUtilities");
const client = new Discord.Client();
client.setMaxListeners(0);

const commandList = new (require('./src/CommandContainer'));
const dependencyGraph = {
	'discordClient': client,
	'commandPrefix': '!',
	'commandList': commandList,
	'https': require('https')
};
for (let key in instantiateCommands) {
	if (!instantiateCommands.hasOwnProperty(key)) continue;
	let commandPath = './src/Command/' + instantiateCommands[key];
	let command = new (require(commandPath));
	command.initialize(dependencyGraph);

	commandList.add(key, command);
}

for (let key in instantiateUtilities) {
	if (!instantiateUtilities.hasOwnProperty(key)) continue;
	let utilityPath = './src/Utility/' + instantiateUtilities[key];
	let utility = new (require(utilityPath));
	utility.initialize(dependencyGraph);
}

client.on('ready', () => {
	client.user.setActivity("on Shotbow");
	console.log("Successfully logged in!");
});

client.login(tokens.getToken());<|endoftext|>


<commit_before>'use strict';

var self = module.exports;

var verbose = false;

var arrayRegex = /\[(string|number|boolean|date|object|array)]/;

var checker = {};

self.errorType = undefined;
self.apiVersion = 1;

// Casts value as string,
// this will always be valid unless the string is empty
checker.string = function (value) {
    // TODO (Doug): This may not capture everything we want
    if (!value) {
        return null;
    }
    return value.toString();
};

checker.number = function (value) {
    value = parseFloat(value);

    if (isNaN(value)) {
        return null;
    }

    return value;
};

checker.date = function (value) {
    value = new Date(value);

    if (value.toString() === 'Invalid Date') {
        return null;
    }

    return value;
};

checker.array = function (value, apiVersion) {
    if (!Array.isArray(value)) {
        return null;
    }
    if (apiVersion >= 1.5) {
        // Reject empty arrays (Why would they pass that?)
        if (!value.length) {
            return null;
        }
    }

    return value;
};

// TODO (Doug): I'm sure this isn't working right
checker.typedArray = function (value, type, apiVersion) {
    var cleanArray = [];
    if (!Array.isArray(value)) {
        return null;
    }

    if (apiVersion >= 1.5) {
        // Reject empty arrays (Why would they pass that?)
        if (!value.length) {
            return null;
        }
    }

    value.forEach(function (item) {
        cleanArray.push(checker[type](item));
    });

    var incorrectValues = cleanArray.filter(function (item) {
        return (item === null);
    });

    if (incorrectValues.length) {
        return null;
    }

    return cleanArray;
};

// TODO (Doug): This needs some work
checker.object = function (value, apiVersion) {
    if (typeof value !== 'object') {
        return null;
    }
    // Reject empty objects
    if (apiVersion >= 1.5) {
        if (!Object.keys(value).length) {
            return null;
        }
    }

    return value;
};

// TODO (Doug): May want to re-evaluate this
checker.boolean = function (value) {
    if (value === undefined || value === null) {
        return null;
    }

    if (typeof value === 'boolean') {
        return value;
    }

    if (value === 1 || value === '1') {
        return true;
    }

    if (value === 0 || value === '0') {
        return false;
    }

    if (/^true$/i.test(value)) {
        return true;
    }

    if (/^false$/i.test(value)) {
        return false;
    }

    return null;
};

// Sets all properties to their clean value or null
var checkPropertiesTypes = function (params, schema, apiVersion) {
    var cleanParams = {};

    Object.keys(schema).forEach(function (key) {
        var requiredType = schema[key],
            value = params[key];

        // Don't check properties that don't exist
        if (!params.hasOwnProperty(key)) {
            return;
        }

        if (arrayRegex.test(requiredType)) {
            var arrayType = arrayRegex.exec(requiredType)[1];
            cleanParams[key] = checker.typedArray(value, arrayType, apiVersion);
            return;
        }

        cleanParams[key] = checker[requiredType](value, apiVersion);
    });

    return cleanParams;
};

// Public Methods

self.setVerbose = function (flag) {
    if (flag === undefined) return (verbose = true);
    if (flag) return (verbose = true);
    verbose = false;
};

self.errorType = function (type) {
    if (type === 'throw') {
        self.errorType = 'throw';
    }
};

self.validate = function (params, schema, optional, errorType, apiVersion) {
    // If no errorType is specified, check for global errorType
    if (errorType === undefined) {
        errorType = self.errorType;
    }
    if (apiVersion === undefined) {
        apiVersion = self.apiVersion;
    }

    var cleanParams = {},
        cleanOptionalParams = {};

    optional = optional || {};

    Object.keys(schema).forEach(key => {
        if (schema[key].slice(-1) === '?') {
            optional[key] = schema[key].slice(0, -1);
            delete schema[key];
        }
    });

    // Check that every required property exists
    var missingProperties = Object.keys(schema).filter(function (key) {
        return (!params.hasOwnProperty([key]));
    });

    if (missingProperties.length) {
        let errorMsg = 'Missing properties: ' + missingProperties.join(', ');
        if (verbose) {
            console.error(errorMsg);
        }
        if (errorType === 'throw') {
            throw new Error(errorMsg);
        }

        return null;
    }

    // Check that every required property is of the required type
    cleanParams = checkPropertiesTypes(params, schema, apiVersion);
    var incorrectTypes = Object.keys(cleanParams).filter(function (key) {
        return (cleanParams[key] === null);
    });
    if (incorrectTypes.length) {
        let errorMsg = 'Incorrect required type: ' + incorrectTypes.join(', ');
        if (verbose) {
            console.error(errorMsg);
        }
        if (errorType === 'throw') {
            throw new Error(errorMsg);
        }

        return null;
    }

    // Check that every optional request is of the required type
    cleanOptionalParams = checkPropertiesTypes(params, optional);
    var incorrectOptionalTypes = Object.keys(cleanOptionalParams).filter(function (key) {
        return (cleanOptionalParams[key] === null);
    });
    if (incorrectOptionalTypes.length) {
        let errorMsg = 'Incorrect optional type:' + incorrectOptionalTypes.join(', ');
        if (verbose) {
            console.error(errorMsg);
        }
        if (errorType === 'throw') {
            throw new Error(errorMsg);
        }

        return null;
    }

    // Join the cleaned optional types to the cleaned required types
    Object.keys(cleanOptionalParams).forEach(function (key) {
        cleanParams[key] = cleanOptionalParams[key];
    });

    // TODO: This was a bugfix, needs a test
    if (Object.keys(cleanParams).length === 0) {
        return null;
    }

    return cleanParams;
};

self.create = function (opts) {
    opts = opts || {};
    const _errorType = opts.errorType,
        _apiVersion = opts.apiVersion;

    return {
        validate: function (params, schema, optional, errorType, apiVersion) {
            errorType = errorType || _errorType;
            apiVersion = apiVersion || _apiVersion;
            return self.validate(params, schema, optional, errorType, apiVersion);
        }
    };
};

self.attach = function (object) {
    // Set hidden flag to determine if object has been validated
    Object.defineProperty(object, '__validated', {
        value: false,
        enumerable: false,
        configurable: false,
        writable: true
    });

    // Replace all properties with getters, throw an error if not validated
    Object.keys(object).forEach(function (key) {
        var property = object[key];
        object.__defineGetter__(key, function () {
            if (!this.__validated) throw new Error('This object has not been validated');
            return property;
        });
    });

    // Validate the object and set the internal flag
    Object.defineProperty(object, 'validate', {
        value: function (schema, optional) {
            this.__validated = true;
            return self.validate(object, schema, optional);
        },
        writable: false,
        enumerable: false,
        configurable: false
    });
};
<commit_msg>optional types now checked with updated api when updated api specified<commit_after>'use strict';

var self = module.exports;

var verbose = false;

var arrayRegex = /\[(string|number|boolean|date|object|array)]/;

var validTypes = [
    'string',
    'number',
    'boolean',
    'date',
    'object',
    'array'
];

var checker = {};

self.errorType = undefined;
self.apiVersion = 1;

// Casts value as string,
// this will always be valid unless the string is empty
checker.string = function (value) {
    // TODO (Doug): This may not capture everything we want
    if (!value) {
        return null;
    }
    return value.toString();
};

checker.number = function (value) {
    value = parseFloat(value);

    if (isNaN(value)) {
        return null;
    }

    return value;
};

checker.date = function (value) {
    value = new Date(value);

    if (value.toString() === 'Invalid Date') {
        return null;
    }

    return value;
};

checker.array = function (value, apiVersion) {
    if (!Array.isArray(value)) {
        return null;
    }
    if (apiVersion >= 1.5) {
        // Reject empty arrays (Why would they pass that?)
        if (!value.length) {
            return null;
        }
    }

    return value;
};

// TODO (Doug): I'm sure this isn't working right
checker.typedArray = function (value, type, apiVersion) {
    var cleanArray = [];
    if (!Array.isArray(value)) {
        return null;
    }

    if (apiVersion >= 1.5) {
        // Reject empty arrays (Why would they pass that?)
        if (!value.length) {
            return null;
        }
    }

    value.forEach(function (item) {
        cleanArray.push(checker[type](item));
    });

    var incorrectValues = cleanArray.filter(function (item) {
        return (item === null);
    });

    if (incorrectValues.length) {
        return null;
    }

    return cleanArray;
};

// TODO (Doug): This needs some work
checker.object = function (value, apiVersion) {
    if (typeof value !== 'object') {
        return null;
    }
    // Reject empty objects
    if (apiVersion >= 1.5) {
        if (!Object.keys(value).length) {
            return null;
        }
    }

    return value;
};

// TODO (Doug): May want to re-evaluate this
checker.boolean = function (value) {
    if (value === undefined || value === null) {
        return null;
    }

    if (typeof value === 'boolean') {
        return value;
    }

    if (value === 1 || value === '1') {
        return true;
    }

    if (value === 0 || value === '0') {
        return false;
    }

    if (/^true$/i.test(value)) {
        return true;
    }

    if (/^false$/i.test(value)) {
        return false;
    }

    return null;
};

// Sets all properties to their clean value or null
var checkPropertiesTypes = function (params, schema, apiVersion) {
    var cleanParams = {};

    Object.keys(schema).forEach(function (key) {
        var requiredType = schema[key],
            value = params[key];

        // Don't check properties that don't exist
        if (!params.hasOwnProperty(key)) {
            return;
        }

        if (arrayRegex.test(requiredType)) {
            var arrayType = arrayRegex.exec(requiredType)[1];
            cleanParams[key] = checker.typedArray(value, arrayType, apiVersion);
            return;
        }

        cleanParams[key] = checker[requiredType](value, apiVersion);
    });

    return cleanParams;
};

// Public Methods

self.setVerbose = function (flag) {
    if (flag === undefined) return (verbose = true);
    if (flag) return (verbose = true);
    verbose = false;
};

self.errorType = function (type) {
    if (type === 'throw') {
        self.errorType = 'throw';
    }
};

self.validate = function (params, schema, optional, errorType, apiVersion) {
    // If no errorType is specified, check for global errorType
    if (errorType === undefined) {
        errorType = self.errorType;
    }
    if (apiVersion === undefined) {
        apiVersion = self.apiVersion;
    }

    var cleanParams = {},
        cleanOptionalParams = {};

    optional = optional || {};

    Object.keys(schema).forEach(function (key) {
        if (schema[key].slice(-1) === '?') {
            optional[key] = schema[key].slice(0, -1);
            delete schema[key];
        }
    });

    // Check that every required property exists
    var missingProperties = Object.keys(schema).filter(function (key) {
        return (!params.hasOwnProperty([key]));
    });

    if (missingProperties.length) {
        let errorMsg = 'Missing properties: ' + missingProperties.join(', ');
        if (verbose) {
            console.error(errorMsg);
        }
        if (errorType === 'throw') {
            throw new Error(errorMsg);
        }

        return null;
    }

    // Check that every required property is of the required type
    cleanParams = checkPropertiesTypes(params, schema, apiVersion);
    var incorrectTypes = Object.keys(cleanParams).filter(function (key) {
        return (cleanParams[key] === null);
    });
    if (incorrectTypes.length) {
        let errorMsg = 'Incorrect required type: ' + incorrectTypes.join(', ');
        if (verbose) {
            console.error(errorMsg);
        }
        if (errorType === 'throw') {
            throw new Error(errorMsg);
        }

        return null;
    }

    // Check that every optional request is of the required type
    cleanOptionalParams = checkPropertiesTypes(params, optional, apiVersion);
    var incorrectOptionalTypes = Object.keys(cleanOptionalParams).filter(function (key) {
        return (cleanOptionalParams[key] === null);
    });
    if (incorrectOptionalTypes.length) {
        let errorMsg = 'Incorrect optional type:' + incorrectOptionalTypes.join(', ');
        if (verbose) {
            console.error(errorMsg);
        }
        if (errorType === 'throw') {
            throw new Error(errorMsg);
        }

        return null;
    }

    // Join the cleaned optional types to the cleaned required types
    Object.keys(cleanOptionalParams).forEach(function (key) {
        cleanParams[key] = cleanOptionalParams[key];
    });

    // TODO: This was a bugfix, needs a test
    if (Object.keys(cleanParams).length === 0) {
        return null;
    }

    return cleanParams;
};

self.create = function (opts) {
    opts = opts || {};
    const _errorType = opts.errorType,
        _apiVersion = opts.apiVersion;

    return {
        validate: function (params, schema, optional, errorType, apiVersion) {
            errorType = errorType || _errorType;
            apiVersion = apiVersion || _apiVersion;
            return self.validate(params, schema, optional, errorType, apiVersion);
        }
    };
};

self.attach = function (object) {
    // Set hidden flag to determine if object has been validated
    Object.defineProperty(object, '__validated', {
        value: false,
        enumerable: false,
        configurable: false,
        writable: true
    });

    // Replace all properties with getters, throw an error if not validated
    Object.keys(object).forEach(function (key) {
        var property = object[key];
        object.__defineGetter__(key, function () {
            if (!this.__validated) throw new Error('This object has not been validated');
            return property;
        });
    });

    // Validate the object and set the internal flag
    Object.defineProperty(object, 'validate', {
        value: function (schema, optional) {
            this.__validated = true;
            return self.validate(object, schema, optional);
        },
        writable: false,
        enumerable: false,
        configurable: false
    });
};
<|endoftext|>