UNPKG

npdynamodb

Version:

A Node.js Simple Query Builder and ORM for AWS DynamoDB.

1,694 lines (1,436 loc) 84.3 kB
(function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(require("lodash"), require("aws-sdk"), require("bluebird")); else if(typeof define === 'function' && define.amd) define(["lodash", "aws-sdk", "bluebird"], factory); else if(typeof exports === 'object') exports["npdynamodb"] = factory(require("lodash"), require("aws-sdk"), require("bluebird")); else root["npdynamodb"] = factory(root["_"], root["AWS"], root["Promise"]); })(this, function(__WEBPACK_EXTERNAL_MODULE_2__, __WEBPACK_EXTERNAL_MODULE_4__, __WEBPACK_EXTERNAL_MODULE_10__) { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) /******/ return installedModules[moduleId].exports; /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ exports: {}, /******/ id: moduleId, /******/ loaded: false /******/ }; /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ // Flag the module as loaded /******/ module.loaded = true; /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ // Load entry module and return exports /******/ return __webpack_require__(0); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var _ = __webpack_require__(2); // For Browser if(typeof(window) === 'object') { window.npdynamodb = exports; window.DynamoDBDatatype = __webpack_require__(3).DynamoDBDatatype; window.DynamoDBFormatter = __webpack_require__(5).DynamoDBFormatter; } exports.version = __webpack_require__(6).version; exports.createClient = __webpack_require__(7); exports.define = __webpack_require__(27); exports.Migrator = __webpack_require__(1); var QueryBuilder = __webpack_require__(8), Collection = __webpack_require__(29), Model = __webpack_require__(28) ; [QueryBuilder, Collection, Model].forEach(function(Klass){ Klass.extend = function(protoProps, staticProps){ _.extend(Klass.prototype, protoProps || {}); _.extend(Klass, staticProps || {}); }; }); exports.plugin = function(pluginFn){ if(typeof pluginFn !== 'function') { throw new Error('The plugin must be function.'); } pluginFn({ QueryBuilder: QueryBuilder, Collection: Collection, Model: Model }); }; /******* TODO Will be duplicated in 0.3.x *******/ exports.Collection = __webpack_require__(29); exports.Model = __webpack_require__(28); /******* TODO Will be duplicated in 0.3.x *******/ /***/ }, /* 1 */ /***/ function(module, exports) { /* (ignored) */ /***/ }, /* 2 */ /***/ function(module, exports) { module.exports = __WEBPACK_EXTERNAL_MODULE_2__; /***/ }, /* 3 */ /***/ function(module, exports, __webpack_require__) { "use strict"; /** * @class Creates a DynamoDBDatatype that takes care of all datatype handling. * * @name DynamoDBDatatype */ function DynamoDBDatatype() { var AWS = typeof(window) === "undefined" ? __webpack_require__(4) : window.AWS; var Uint8ArrayError = "Uint8Array can only be used for Binary in Browser."; var ScalarDatatypeError = "Unrecognized Scalar Datatype to be formatted."; var GeneralDatatypeError = "Unrecognized Datatype to be formatted."; var BinConversionError = "Need to pass in Buffer or Uint8Array. "; var StrConversionError = "Need to pass in string primitive to be converted to binary."; function isScalarType(dataType) { var type = typeof(dataType); return type === "number" || type === "string" || type === "boolean" || (dataType instanceof(Uint8Array) && AWS.util.isBrowser()) || dataType instanceof(AWS.util.Buffer) || dataType === null; } function isSetType(dataType) { return dataType.datatype === "SS" || dataType.datatype === "NS" || dataType.datatype === "BS"; } function isRecursiveType(dataType) { return Array.isArray(dataType) || typeof(dataType) === "object"; } function formatSetValues(datatype, values) { if(datatype === "NS") { return values.map(function (n) { return n.toString(); }); } else { return values; } }; function formatRecursiveType(dataType) { var recursiveDoc = {}; var value = {}; var type = "M"; if (Array.isArray(dataType)) { value = []; type = "L"; } for (var key in dataType) { value[key] = this.formatDataType(dataType[key]); } recursiveDoc[type] = value; return recursiveDoc; } /** @throws Uint8ArrayError, ScalarDatatypeError * @private */ function formatScalarType(dataType) { if (dataType == null) { return { "NULL" : true }; } var type = typeof(dataType); if (type === "string") { return { "S" : dataType }; } else if (type === "number") { return { "N" : String(dataType) }; } else if (type === "boolean") { return { "BOOL" : dataType }; } else if (dataType instanceof(AWS.util.Buffer)) { return { "B" : dataType }; } else if (dataType instanceof(Uint8Array)) { if (AWS.util.isBrowser()) { return { "B" : dataType }; } else { throw new Error(Uint8ArrayError); } } else { throw new Error(ScalarDatatypeError); } } /** * Formats Javascript datatypes into DynamoDB wire format. * * @name formatDataType * @function * @memberOf DynamoDBDatatype# * @param dataType Javascript datatype (i.e. string, number. For full information, check out the README). * @return {object} DynamoDB JSON-like wire format. * @throws GeneralDatatypeError */ this.formatDataType = function(dataType) { if (isScalarType(dataType)) { return formatScalarType(dataType); } else if (isSetType(dataType)) { return dataType.format(); } else if (isRecursiveType(dataType)) { return formatRecursiveType.call(this, dataType); } else { throw new Error(GeneralDatatypeError); } }; function str2Bin(value) { if (typeof(value) !== "string") { throw new Error(StrConversionError); } if (AWS.util.isBrowser()) { var len = value.length; var bin = new Uint8Array(new ArrayBuffer(len)); for (var i = 0; i < len; i++) { bin[i] = value.charCodeAt(i); } return bin; } else { return AWS.util.Buffer(value); } } /** * Utility to convert a String to a Binary object. * * @function strToBin * @memberOf DynamoDBDatatype# * @param {string} value String value to converted to Binary object. * @return {object} (Buffer | Uint8Array) depending on Node or browser. * @throws StrConversionError */ this.strToBin = function(value) { return str2Bin.call(this, value); }; function bin2Str(value) { if (!(value instanceof(AWS.util.Buffer)) && !(value instanceof(Uint8Array))) { throw new Error(BinConversionError); } if (AWS.util.isBrowser()) { return String.fromCharCode.apply(null, value); } else { return value.toString("utf-8").valueOf(); } } /** * Utility to convert a Binary object into a decoded String. * * @function binToStr * @memberOf DynamoDBDatatype# * @param {object} value Binary value (Buffer | Uint8Array) depending on Node or browser. * @return {string} decoded String in UTF-8 * @throws BinConversionError */ this.binToStr = function(value) { return bin2Str.call(this, value); }; /** * Utility to create the DynamoDB Set Datatype. * * @function createSet * @memberOf DynamoDBDatatype# * @param {array} set An array that contains elements of the same typed as defined by {type}. * @param {string} type Can only be a [S]tring, [N]umber, or [B]inary type. * @return {Set} Custom Set object that follow {type}. * @throws InvalidSetType, InconsistentType */ this.createSet = function(set, type) { if (type !== "N" && type !== "S" && type !== "B") { throw new Error(type + " is an invalid type for Set"); } var setObj = function Set(set, type) { this.datatype = type + "S"; this.contents = {}; this.add = function(value) { if (this.datatype === "SS" && typeof(value) === "string") { this.contents[value] = value; } else if (this.datatype === "NS" && typeof(value) === "number") { this.contents[value] = value; } else if (this.datatype === "BS" && value instanceof(AWS.util.Buffer)) { this.contents[bin2Str(value)] = value; } else if (this.datatype === "BS" && value instanceof(Uint8Array)) { if (AWS.util.isBrowser()) { this.contents[bin2Str(value)] = value; } else { throw new Error(Uint8ArrayError); } } else { throw new Error("Inconsistent in this " + type + " Set"); } }; this.contains = function(content) { var value = content; if (content instanceof AWS.util.Buffer || content instanceof(Uint8Array)) { value = bin2Str(content); } if (this.contents[value] === undefined) { return false; } return true; }; this.remove = function(content) { var value = content; if (content instanceof AWS.util.Buffer || content instanceof(Uint8Array)) { value = bin2Str(content); } delete this.contents[value]; }; this.toArray = function() { var keys = Object.keys(this.contents); var arr = []; for (var keyIndex in keys) { var key = keys[keyIndex]; if (this.contents.hasOwnProperty(key)) { arr.push(this.contents[key]); } } return arr; }; this.format = function() { var values = this.toArray(); var result = {}; result[this.datatype] = formatSetValues(this.datatype, values); return result; }; if (set) { for (var index in set) { this.add(set[index]); } } }; return new setObj(set, type); }; /** * Formats DynamoDB wire format into javascript datatypes. * * @name formatWireType * @function * @memberOf DynamoDBDatatype# * @param {string} key Key that represents the type of the attribute value * @param value Javascript datatype of the attribute value produced by DynamoDB * @throws GeneralDatatypeError */ this.formatWireType = function(key, value) { switch (key) { case "S": case "B": case "BOOL": return value; case "N": return Number(value); case "NULL": return null; case "L": for (var lIndex = 0; lIndex < value.length; lIndex++) { var lValue = value[lIndex]; var lKey = Object.keys(lValue)[0]; value[lIndex] = this.formatWireType(lKey, lValue[lKey]); } return value; case "M": for (var mIndex in value) { var mValue = value[mIndex]; var mKey = Object.keys(mValue)[0]; value[mIndex] = this.formatWireType(mKey, mValue[mKey]); } return value; case "SS": return new this.createSet(value, "S"); case "NS": value = value.map(function(each) { return Number(each);}); return new this.createSet(value, "N"); case "BS": return new this.createSet(value, "B"); default: throw "Service returned unrecognized datatype " + key; } } } if (true) { var exports = module.exports = {}; exports.DynamoDBDatatype = DynamoDBDatatype; } /***/ }, /* 4 */ /***/ function(module, exports) { module.exports = __WEBPACK_EXTERNAL_MODULE_4__; /***/ }, /* 5 */ /***/ function(module, exports, __webpack_require__) { "use strict"; /** * Create an instance of the DynamoDBFormatter. * @constructor * @return {DynamoDBFormatter} A Formatter object that provides methods for formatting DynamoDB requests and responses. */ function DynamoDBFormatter() { var datatypes = typeof(window) === "undefined" ? __webpack_require__(3).DynamoDBDatatype : window.DynamoDBDatatype; var t = new datatypes(); var EmptyConditionArray = "Need to pass in an array with 1 or more Condition Objects."; var BadElementInConditionArray = "Only Condition objects are allowed as members of the array."; var InvalidCondition = "Need to pass in a valid Condition Object."; function formatAttrValInput(attrValueMap) { var attributeValueMap = {}; for (var attr in attrValueMap) { var value = attrValueMap[attr]; attributeValueMap[attr] = t.formatDataType(value); } return attributeValueMap; } function formatConditions(conditions) { if (conditions.prototype && conditions.prototype.instanceOf === "DynamoDBConditionObject") { conditions = [conditions]; } else { if (Array.isArray(conditions)) { if (conditions.length === 0) { throw new Error(EmptyConditionArray); } for (var index in conditions) { var condition = conditions[index]; if (!(condition.prototype) || !(condition.prototype.instanceOf === "DynamoDBConditionObject")) { throw new Error(BadElementInConditionArray); } } } else { throw new Error(InvalidCondition); } } var expected = {}; for (var index in conditions) { var condition = conditions[index]; expected[condition.key] = condition.format(); } return expected; } function formatUpdates(updates) { var attrUpdates = {}; for (var attr in updates) { if (updates.hasOwnProperty(attr)) { var actionValue = {}; var value = updates[attr].Value; var action = updates[attr].Action; actionValue.Action = action; actionValue.Value = t.formatDataType(value); attrUpdates[attr] = actionValue; } } return attrUpdates; } function handleWriteRequest(request) { var requestCopy = {}; if (request.DeleteRequest) { var key = request.DeleteRequest.Key; requestCopy.DeleteRequest = {}; requestCopy.DeleteRequest.Key = formatAttrValInput(key); } else { var item = request.PutRequest.Item; requestCopy.PutRequest = {}; requestCopy.PutRequest.Item = formatAttrValInput(item); } return requestCopy; } function formatRequestItems(requests) { var requestItems = {}; for (var table in requests) { if (requests.hasOwnProperty(table)) { requestItems[table] = {}; var request = requests[table]; if (Array.isArray(request)) { var writeRequests = []; for (var wIndex in request) { writeRequests.push(handleWriteRequest(request[wIndex])); } requestItems[table] = writeRequests; } else { if (request.AttributesToGet) { requestItems[table].AttributesToGet = request.AttributesToGet; } if (request.ConsistentRead) { requestItems[table].ConsistentRead = request.ConsistentRead; } if (request.ProjectionExpression) { requestItems[table].ProjectionExpression = request.ProjectionExpression; } if (request.ExpressionAttributeNames) { requestItems[table].ExpressionAttributeNames = request.ExpressionAttributeNames; } if (request.Keys) { var keys = []; for (var gIndex in request.Keys) { var key = request.Keys[gIndex]; keys.push(formatAttrValInput(key)); } requestItems[table].Keys = keys; } } } } return requestItems; } var inputMap = { "AttributeUpdates": formatUpdates, "ExclusiveStartKey": formatAttrValInput, "Expected": formatConditions, "ExpressionAttributeValues": formatAttrValInput, "Item": formatAttrValInput, "Key": formatAttrValInput, "KeyConditions": formatConditions, "RequestItems": formatRequestItems, "ScanFilter": formatConditions, "QueryFilter": formatConditions}; function formatAttrValOutput(item) { var attrList = {}; for (var attribute in item) { var keys = Object.keys(item[attribute]); var key = keys[0]; var value = item[attribute][key]; value = t.formatWireType(key, value); attrList[attribute] = value; } return attrList; } function formatItems(items) { for (var index in items) { items[index] = formatAttrValOutput(items[index]); } return items; } function handleCollectionKey(metrics) { var collectionKey = metrics.ItemCollectionKey; metrics.ItemCollectionKey = formatAttrValOutput(collectionKey); return metrics; } function handleBatchMetrics(metrics) { for (var table in metrics) { if (metrics.hasOwnProperty(table)) { var listOfKeys = metrics[table]; for (var index in listOfKeys) { listOfKeys[index] = handleCollectionKey(listOfKeys[index]); } } } return metrics; } function formatMetrics(metrics) { var collectionKey = metrics.ItemCollectionKey; if (collectionKey) { metrics = handleCollectionKey(metrics); } else { metrics = handleBatchMetrics(metrics); } return metrics; } function formatResponses(responses) { for (var table in responses) { if (responses.hasOwnProperty(table)) { var listOfItems = responses[table]; for (var index in listOfItems) { listOfItems[index] = formatAttrValOutput(listOfItems[index]); } } } return responses; } function formatUnprocessedItems(unprocessedItems) { for(var table in unprocessedItems) { if (unprocessedItems.hasOwnProperty(table)) { var tableInfo = unprocessedItems[table]; for (var index in tableInfo) { var request = tableInfo[index]; if (request.DeleteRequest) { tableInfo[index].DeleteRequest.Key = formatAttrValOutput(request.DeleteRequest.Key); } else { tableInfo[index].PutRequest.Item = formatAttrValOutput(request.PutRequest.Item); } } } } return unprocessedItems; } function formatUnprocessedKeys(unprocessedKeys) { for (var table in unprocessedKeys) { if (unprocessedKeys.hasOwnProperty(table)) { var tableInfo = unprocessedKeys[table]; var listOfKeys = tableInfo.Keys; for (var index in listOfKeys) { tableInfo.Keys[index] = formatAttrValOutput(listOfKeys[index]); } } } return unprocessedKeys; } /** * DynamoDBFormatter specifically for wrapping DynamoDB response objects. * * @function formatOutput * @memberOf DynamoDBFormatter# * @params {object} response Response object directly passed out by the service. * @returns {object} Wrapped up response object. */ this.formatOutput = function(response) { var outputMap = {"Attributes": formatAttrValOutput, "Item": formatAttrValOutput, "Items": formatItems, "ItemCollectionMetrics": formatMetrics, "LastEvaluatedKey": formatAttrValOutput, "Responses": formatResponses, "UnprocessedKeys": formatUnprocessedKeys, "UnprocessedItems": formatUnprocessedItems}; var data = response.data; if (data) { for (var key in data) { if (data.hasOwnProperty(key)) { var formatFunc = outputMap[key]; if (formatFunc) { response.data[key] = formatFunc(data[key]); } } } } }; /** * DynamoDBFormatter specifically for unwrapping DynamoDB request objects. * * @function formatInput * @memberOf DynamoDBFormatter# * @params {object} request Request object created by the service. * @return {object} Returns aws sdk version of the request. */ this.formatInput = function (request) { var paramsCopy = {}; var params = request.params; for (var key in params) { if (params.hasOwnProperty(key)) { var param = params[key]; var formatFunc = inputMap[key]; if (formatFunc) { param = formatFunc(param); } paramsCopy[key] = param; } } request.params = paramsCopy; }; } if (true) { var exports = module.exports = {}; exports.DynamoDBFormatter = DynamoDBFormatter; } /***/ }, /* 6 */ /***/ function(module, exports) { module.exports = { "name": "npdynamodb", "version": "0.2.11", "description": "A Node.js Simple Query Builder and ORM for AWS DynamoDB.", "main": "index.js", "scripts": { "test": "find ./test -name *_spec.js | xargs mocha --reporter spec -t 20000" }, "keywords": [ "dynamodb", "aws", "activerecord", "orm", "migration" ], "bin": { "npd": "./lib/bin/npd" }, "repository": { "type": "git", "url": "https://github.com/noppoMan/npdynamodb.git" }, "author": "noppoMan <yuki@miketokyo.com> (http://miketokyo.com)", "license": "MIT", "bugs": { "url": "https://github.com/noppoMan/npdynamodb/issues" }, "homepage": "https://github.com/noppoMan/npdynamodb", "dependencies": { "bluebird": "^2.9.24", "chalk": "^1.0.0", "commander": "^2.7.1", "dynamodb-doc": "^1.0.0", "glob": "^5.0.3", "interpret": "^0.5.2", "liftoff": "^2.0.3", "lodash": "^3.5.0", "minimist": "^1.1.1", "readline": "0.0.7", "v8flags": "^2.0.3" }, "devDependencies": { "aws-sdk": "^2.1.18", "chai": "^2.2.0" }, "browser": { "./lib/migrate/migrator.js": false, "./lib/dialects/2012-08-10/schema.js": false, "aws-sdk": false } } /***/ }, /* 7 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var QueryBuilder = __webpack_require__(8); var promisify = __webpack_require__(25); var DOC = __webpack_require__(18); var promisifiedPool = {}; function npdynamodb(clients, options){ var qb = new QueryBuilder(clients, options); return qb; } module.exports = function(dynamodb, options){ var v = dynamodb.config.apiVersion, api = __webpack_require__(26)("./" + v + '/' + 'api') ; if(!promisifiedPool[v]) { promisifiedPool[v] = promisify(dynamodb, api.originalApis); } var clients = { dynamodb: typeof dynamodb.Condition === 'function' ? dynamodb: new DOC.DynamoDB(dynamodb), promisifidRawClient: promisifiedPool[v] }; return function(){ return npdynamodb(clients, options); }; }; /***/ }, /* 8 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var interfaces = __webpack_require__(9); var _ = __webpack_require__(2); var Promise = __webpack_require__(10); var EventEmitter = __webpack_require__(11).EventEmitter; var util = __webpack_require__(12); var utils = __webpack_require__(16); var Features = { '2012-08-10': __webpack_require__(17) }; module.exports = QueryBuilder; function QueryBuilder(clients, options){ EventEmitter.call(this); var feature = new Features[clients.dynamodb.config.apiVersion](clients); var opts = options || {}; var initialize = opts.initialize; this.apiVersion = feature.client.config.apiVersion; this._feature = feature; this._options = _.omit(opts, 'initialize'); this._initializer = opts.initialize; this._callbacks = {}; if(typeof this._initializer === 'function') { this._initializer.bind(this)(); } } util.inherits(QueryBuilder, EventEmitter); interfaces.forEach(function(m){ QueryBuilder.prototype[m] = function(){ this._feature[m].apply(this._feature, _.toArray(arguments)); return this; }; }); QueryBuilder.prototype.freshBuilder = function(){ return new QueryBuilder({ dynamodb: this._feature.client, promisifidRawClient: this._feature.promisifidRawClient }, _.clone(_.extend(this._options, {initialize: this._initializer})) ); }; QueryBuilder.prototype.tableName = function(){ return this._feature.conditions.TableName; }; QueryBuilder.prototype.normalizationRawResponse = function(data){ return this._feature.normalizationRawResponse(data); }; QueryBuilder.prototype.feature = function(cb){ cb(this._feature); return this; }; QueryBuilder.prototype.rawClient = function(cb){ return this._feature.promisifidRawClient; }; QueryBuilder.prototype.callbacks = function(name, fn){ if(!this._callbacks[name]){ this._callbacks[name] = []; } this._callbacks[name].push(fn); return this; }; function callbacksPromisified(callbacks, data){ return (callbacks || []).map(function(f){ return f.bind(this)(data); }.bind(this)); } _.each([ 'then', ], function(promiseInterface){ QueryBuilder.prototype[promiseInterface] = function(cb){ var self = this; var feature = self._feature; var callbacks = this._callbacks; var timer; return Promise.all(callbacksPromisified.bind(self)(callbacks.beforeQuery)).then(function(){ var built = feature.buildQuery(); self.emit('beforeQuery', built.params); return new Promise(function(resolve, reject){ var request = feature.client[built.method](built.params, function(err, data){ if(timer) { clearTimeout(timer); timer = null; } if(err) { return reject(err); } resolve(data); }); // Handle timeout if(self._options.timeout !== null) { timer = setTimeout(function(){ request.abort(); reject(new Error("The connection has timed out.")); }, self._options.timeout || 5000); } }); }) .then(function(data){ return Promise.all(callbacksPromisified.bind(self)(callbacks.afterQuery, data)).then(function(){ self.emit('afterQuery', data); return data; }); }) .then(function(data){ return cb.bind(self)(data); }); }; }); /***/ }, /* 9 */ /***/ function(module, exports) { 'use strict'; module.exports = [ 'select', 'table', 'count', 'all', 'where', 'first', 'whereIn', 'whereBetween', 'whereBeginsWith', 'filterBetween', 'filterBeginsWith', 'filter', 'filterIn', 'filterNull', 'filterNotNull', 'filterContains', 'filterNotContains', 'limit', 'offset', 'desc', 'asc', 'create', 'update', 'set', 'delete', 'showTables', 'indexName', 'describe', 'createTable', 'deleteTable', ]; /***/ }, /* 10 */ /***/ function(module, exports) { module.exports = __WEBPACK_EXTERNAL_MODULE_10__; /***/ }, /* 11 */ /***/ function(module, exports) { // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. function EventEmitter() { this._events = this._events || {}; this._maxListeners = this._maxListeners || undefined; } module.exports = EventEmitter; // Backwards-compat with node 0.10.x EventEmitter.EventEmitter = EventEmitter; EventEmitter.prototype._events = undefined; EventEmitter.prototype._maxListeners = undefined; // By default EventEmitters will print a warning if more than 10 listeners are // added to it. This is a useful default which helps finding memory leaks. EventEmitter.defaultMaxListeners = 10; // Obviously not all Emitters should be limited to 10. This function allows // that to be increased. Set to zero for unlimited. EventEmitter.prototype.setMaxListeners = function(n) { if (!isNumber(n) || n < 0 || isNaN(n)) throw TypeError('n must be a positive number'); this._maxListeners = n; return this; }; EventEmitter.prototype.emit = function(type) { var er, handler, len, args, i, listeners; if (!this._events) this._events = {}; // If there is no 'error' event listener then throw. if (type === 'error') { if (!this._events.error || (isObject(this._events.error) && !this._events.error.length)) { er = arguments[1]; if (er instanceof Error) { throw er; // Unhandled 'error' event } throw TypeError('Uncaught, unspecified "error" event.'); } } handler = this._events[type]; if (isUndefined(handler)) return false; if (isFunction(handler)) { switch (arguments.length) { // fast cases case 1: handler.call(this); break; case 2: handler.call(this, arguments[1]); break; case 3: handler.call(this, arguments[1], arguments[2]); break; // slower default: len = arguments.length; args = new Array(len - 1); for (i = 1; i < len; i++) args[i - 1] = arguments[i]; handler.apply(this, args); } } else if (isObject(handler)) { len = arguments.length; args = new Array(len - 1); for (i = 1; i < len; i++) args[i - 1] = arguments[i]; listeners = handler.slice(); len = listeners.length; for (i = 0; i < len; i++) listeners[i].apply(this, args); } return true; }; EventEmitter.prototype.addListener = function(type, listener) { var m; if (!isFunction(listener)) throw TypeError('listener must be a function'); if (!this._events) this._events = {}; // To avoid recursion in the case that type === "newListener"! Before // adding it to the listeners, first emit "newListener". if (this._events.newListener) this.emit('newListener', type, isFunction(listener.listener) ? listener.listener : listener); if (!this._events[type]) // Optimize the case of one listener. Don't need the extra array object. this._events[type] = listener; else if (isObject(this._events[type])) // If we've already got an array, just append. this._events[type].push(listener); else // Adding the second element, need to change to array. this._events[type] = [this._events[type], listener]; // Check for listener leak if (isObject(this._events[type]) && !this._events[type].warned) { var m; if (!isUndefined(this._maxListeners)) { m = this._maxListeners; } else { m = EventEmitter.defaultMaxListeners; } if (m && m > 0 && this._events[type].length > m) { this._events[type].warned = true; console.error('(node) warning: possible EventEmitter memory ' + 'leak detected. %d listeners added. ' + 'Use emitter.setMaxListeners() to increase limit.', this._events[type].length); if (typeof console.trace === 'function') { // not supported in IE 10 console.trace(); } } } return this; }; EventEmitter.prototype.on = EventEmitter.prototype.addListener; EventEmitter.prototype.once = function(type, listener) { if (!isFunction(listener)) throw TypeError('listener must be a function'); var fired = false; function g() { this.removeListener(type, g); if (!fired) { fired = true; listener.apply(this, arguments); } } g.listener = listener; this.on(type, g); return this; }; // emits a 'removeListener' event iff the listener was removed EventEmitter.prototype.removeListener = function(type, listener) { var list, position, length, i; if (!isFunction(listener)) throw TypeError('listener must be a function'); if (!this._events || !this._events[type]) return this; list = this._events[type]; length = list.length; position = -1; if (list === listener || (isFunction(list.listener) && list.listener === listener)) { delete this._events[type]; if (this._events.removeListener) this.emit('removeListener', type, listener); } else if (isObject(list)) { for (i = length; i-- > 0;) { if (list[i] === listener || (list[i].listener && list[i].listener === listener)) { position = i; break; } } if (position < 0) return this; if (list.length === 1) { list.length = 0; delete this._events[type]; } else { list.splice(position, 1); } if (this._events.removeListener) this.emit('removeListener', type, listener); } return this; }; EventEmitter.prototype.removeAllListeners = function(type) { var key, listeners; if (!this._events) return this; // not listening for removeListener, no need to emit if (!this._events.removeListener) { if (arguments.length === 0) this._events = {}; else if (this._events[type]) delete this._events[type]; return this; } // emit removeListener for all listeners on all events if (arguments.length === 0) { for (key in this._events) { if (key === 'removeListener') continue; this.removeAllListeners(key); } this.removeAllListeners('removeListener'); this._events = {}; return this; } listeners = this._events[type]; if (isFunction(listeners)) { this.removeListener(type, listeners); } else { // LIFO order while (listeners.length) this.removeListener(type, listeners[listeners.length - 1]); } delete this._events[type]; return this; }; EventEmitter.prototype.listeners = function(type) { var ret; if (!this._events || !this._events[type]) ret = []; else if (isFunction(this._events[type])) ret = [this._events[type]]; else ret = this._events[type].slice(); return ret; }; EventEmitter.listenerCount = function(emitter, type) { var ret; if (!emitter._events || !emitter._events[type]) ret = 0; else if (isFunction(emitter._events[type])) ret = 1; else ret = emitter._events[type].length; return ret; }; function isFunction(arg) { return typeof arg === 'function'; } function isNumber(arg) { return typeof arg === 'number'; } function isObject(arg) { return typeof arg === 'object' && arg !== null; } function isUndefined(arg) { return arg === void 0; } /***/ }, /* 12 */ /***/ function(module, exports, __webpack_require__) { /* WEBPACK VAR INJECTION */(function(global, process) {// Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. var formatRegExp = /%[sdj%]/g; exports.format = function(f) { if (!isString(f)) { var objects = []; for (var i = 0; i < arguments.length; i++) { objects.push(inspect(arguments[i])); } return objects.join(' '); } var i = 1; var args = arguments; var len = args.length; var str = String(f).replace(formatRegExp, function(x) { if (x === '%%') return '%'; if (i >= len) return x; switch (x) { case '%s': return String(args[i++]); case '%d': return Number(args[i++]); case '%j': try { return JSON.stringify(args[i++]); } catch (_) { return '[Circular]'; } default: return x; } }); for (var x = args[i]; i < len; x = args[++i]) { if (isNull(x) || !isObject(x)) { str += ' ' + x; } else { str += ' ' + inspect(x); } } return str; }; // Mark that a method should not be used. // Returns a modified function which warns once by default. // If --no-deprecation is set, then it is a no-op. exports.deprecate = function(fn, msg) { // Allow for deprecating things in the process of starting up. if (isUndefined(global.process)) { return function() { return exports.deprecate(fn, msg).apply(this, arguments); }; } if (process.noDeprecation === true) { return fn; } var warned = false; function deprecated() { if (!warned) { if (process.throwDeprecation) { throw new Error(msg); } else if (process.traceDeprecation) { console.trace(msg); } else { console.error(msg); } warned = true; } return fn.apply(this, arguments); } return deprecated; }; var debugs = {}; var debugEnviron; exports.debuglog = function(set) { if (isUndefined(debugEnviron)) debugEnviron = process.env.NODE_DEBUG || ''; set = set.toUpperCase(); if (!debugs[set]) { if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { var pid = process.pid; debugs[set] = function() { var msg = exports.format.apply(exports, arguments); console.error('%s %d: %s', set, pid, msg); }; } else { debugs[set] = function() {}; } } return debugs[set]; }; /** * Echos the value of a value. Trys to print the value out * in the best way possible given the different types. * * @param {Object} obj The object to print out. * @param {Object} opts Optional options object that alters the output. */ /* legacy: obj, showHidden, depth, colors*/ function inspect(obj, opts) { // default options var ctx = { seen: [], stylize: stylizeNoColor }; // legacy... if (arguments.length >= 3) ctx.depth = arguments[2]; if (arguments.length >= 4) ctx.colors = arguments[3]; if (isBoolean(opts)) { // legacy... ctx.showHidden = opts; } else if (opts) { // got an "options" object exports._extend(ctx, opts); } // set default options if (isUndefined(ctx.showHidden)) ctx.showHidden = false; if (isUndefined(ctx.depth)) ctx.depth = 2; if (isUndefined(ctx.colors)) ctx.colors = false; if (isUndefined(ctx.customInspect)) ctx.customInspect = true; if (ctx.colors) ctx.stylize = stylizeWithColor; return formatValue(ctx, obj, ctx.depth); } exports.inspect = inspect; // http://en.wikipedia.org/wiki/ANSI_escape_code#graphics inspect.colors = { 'bold' : [1, 22], 'italic' : [3, 23], 'underline' : [4, 24], 'inverse' : [7, 27], 'white' : [37, 39], 'grey' : [90, 39], 'black' : [30, 39], 'blue' : [34, 39], 'cyan' : [36, 39], 'green' : [32, 39], 'magenta' : [35, 39], 'red' : [31, 39], 'yellow' : [33, 39] }; // Don't use 'blue' not visible on cmd.exe inspect.styles = { 'special': 'cyan', 'number': 'yellow', 'boolean': 'yellow', 'undefined': 'grey', 'null': 'bold', 'string': 'green', 'date': 'magenta', // "name": intentionally not styling 'regexp': 'red' }; function stylizeWithColor(str, styleType) { var style = inspect.styles[styleType]; if (style) { return '\u001b[' + inspect.colors[style][0] + 'm' + str + '\u001b[' + inspect.colors[style][1] + 'm'; } else { return str; } } function stylizeNoColor(str, styleType) { return str; } function arrayToHash(array) { var hash = {}; array.forEach(function(val, idx) { hash[val] = true; }); return hash; } function formatValue(ctx, value, recurseTimes) { // Provide a hook for user-specified inspect functions. // Check that value is an object with an inspect function on it if (ctx.customInspect && value && isFunction(value.inspect) && // Filter out the util module, it's inspect function is special value.inspect !== exports.inspect && // Also filter out any prototype objects using the circular check. !(value.constructor && value.constructor.prototype === value)) { var ret = value.inspect(recurseTimes, ctx); if (!isString(ret)) { ret = formatValue(ctx, ret, recurseTimes); } return ret; } // Primitive types cannot have properties var primitive = formatPrimitive(ctx, value); if (primitive) { return primitive; } // Look up the keys of the object. var keys = Object.keys(value); var visibleKeys = arrayToHash(keys); if (ctx.showHidden) { keys = Object.getOwnPropertyNames(value); } // IE doesn't make error fields non-enumerable // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx if (isError(value) && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { return formatError(value); } // Some type of object without properties can be shortcutted. if (keys.length === 0) { if (isFunction(value)) { var name = value.name ? ': ' + value.name : ''; return ctx.stylize('[Function' + name + ']', 'special'); } if (isRegExp(value)) { return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); } if (isDate(value)) { return ctx.stylize(Date.prototype.toString.call(value), 'date'); } if (isError(value)) { return formatError(value); } } var base = '', array = false, braces = ['{', '}']; // Make Array say that they are Array if (isArray(value)) { array = true; braces = ['[', ']']; } // Make functions say that they are functions if (isFunction(value)) { var n = value.name ? ': ' + value.name : ''; base = ' [Function' + n + ']'; } // Make RegExps say that they are RegExps if (isRegExp(value)) { base = ' ' + RegExp.prototype.toString.call(value); } // Make dates with properties first say the date if (isDate(value)) { base = ' ' + Date.prototype.toUTCString.call(value); } // Make error with message first say the error if (isError(value)) { base = ' ' + formatError(value); } if (keys.length === 0 && (!array || value.length == 0)) { return braces[0] + base + braces[1]; } if (recurseTimes < 0) { if (isRegExp(value)) { return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); } else { return ctx.stylize('[Object]', 'special'); } } ctx.seen.push(value); var output; if (array) { output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); } else { output = keys.map(function(key) { return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); }); } ctx.seen.pop(); return reduceToSingleString(output, base, braces); } function formatPrimitive(ctx, value) { if (isUndefined(value)) return ctx.stylize('undefined', 'undefined'); if (isString(value)) { var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') .replace(/'/g, "\\'") .replace(/\\"/g, '"') + '\''; return ctx.stylize(simple, 'string'); } if (isNumber(value)) return ctx.stylize('' + value, 'number'); if (isBoolean(value)) return ctx.stylize('' + value, 'boolean'); // For some reason typeof null is "object", so special case here. if (isNull(value)) return ctx.stylize('null', 'null'); } function formatError(value) { return '[' + Error.prototype.toString.call(value) + ']'; } function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { var output = []; for (var i = 0, l = value.length; i < l; ++i) { if (hasOwnProperty(value, String(i))) { output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, String(i), true)); } else { output.push(''); } } keys.forEach(function(key) { if (!key.match(/^\d+$/)) { output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, key, true)); } }); return output; } function formatProperty(ctx, value, recurseTimes, visi