UNPKG

mikronode2

Version:
1,472 lines (1,201 loc) 137 kB
(function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(require("util"), require("net"), require("tls"), require("domain"), require("rxjs"), require("core-decorators"), require("crypto"), require("dns"), require("events")); else if(typeof define === 'function' && define.amd) define(["util", "net", "tls", "domain", "rxjs", "core-decorators", "crypto", "dns", "events"], factory); else if(typeof exports === 'object') exports["MikroNode"] = factory(require("util"), require("net"), require("tls"), require("domain"), require("rxjs"), require("core-decorators"), require("crypto"), require("dns"), require("events")); else root["MikroNode"] = factory(root["util"], root["net"], root["tls"], root["domain"], root["rxjs"], root["core-decorators"], root["crypto"], root["dns"], root["events"]); })(this, function(__WEBPACK_EXTERNAL_MODULE_3__, __WEBPACK_EXTERNAL_MODULE_4__, __WEBPACK_EXTERNAL_MODULE_5__, __WEBPACK_EXTERNAL_MODULE_10__, __WEBPACK_EXTERNAL_MODULE_17__, __WEBPACK_EXTERNAL_MODULE_18__, __WEBPACK_EXTERNAL_MODULE_19__, __WEBPACK_EXTERNAL_MODULE_20__, __WEBPACK_EXTERNAL_MODULE_25__) { 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__) { module.exports = __webpack_require__(1); /***/ }), /* 1 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _desc, _value, _class; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _simpleAssign3 = __webpack_require__(2); var _simpleAssign4 = _interopRequireDefault(_simpleAssign3); var _simpleAssign = __webpack_require__(2); var _simpleAssign2 = _interopRequireDefault(_simpleAssign); var _util = __webpack_require__(3); var _util2 = _interopRequireDefault(_util); var _net = __webpack_require__(4); var _net2 = _interopRequireDefault(_net); var _tls2 = __webpack_require__(5); var _tls3 = _interopRequireDefault(_tls2); var _promise = __webpack_require__(6); var _promise2 = _interopRequireDefault(_promise); var _rxjs = __webpack_require__(17); var _coreDecorators = __webpack_require__(18); var _crypto = __webpack_require__(19); var _crypto2 = _interopRequireDefault(_crypto); var _dns = __webpack_require__(20); var _dns2 = _interopRequireDefault(_dns); var _Util = __webpack_require__(21); var _constants = __webpack_require__(22); var _parser = __webpack_require__(23); var _parser2 = _interopRequireDefault(_parser); var _Connection = __webpack_require__(24); var _Connection2 = _interopRequireDefault(_Connection); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) { var desc = {}; Object['ke' + 'ys'](descriptor).forEach(function (key) { desc[key] = descriptor[key]; }); desc.enumerable = !!desc.enumerable; desc.configurable = !!desc.configurable; if ('value' in desc || desc.initializer) { desc.writable = true; } desc = decorators.slice().reverse().reduce(function (desc, decorator) { return decorator(target, property, desc) || desc; }, desc); if (context && desc.initializer !== void 0) { desc.value = desc.initializer ? desc.initializer.call(context) : void 0; desc.initializer = undefined; } if (desc.initializer === void 0) { Object['define' + 'Property'](target, property, desc); desc = null; } return desc; } function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } function _toArray(arr) { return Array.isArray(arr) ? arr : Array.from(arr); } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var Socket = _net2.default.Socket; var nullString = String.fromCharCode(0); var _host = new WeakMap(); var _port = new WeakMap(); var _debug = new WeakMap(); var _timeout = new WeakMap(); var _sock = new WeakMap(); var _status = new WeakMap(); var _tls = new WeakMap(); var _socketOpts = new WeakMap(); var _socketProto = new WeakMap(); var MikroNode = function () { /** * Creates a MikroNode API object. * @exports mikronode * @function * @static * @param {string} host - The host name or ip address * @param {number} [port=8728] - Sets the port if not the standard 8728 (8729 for * TLS). * @param {number} [timeout=0] - Sets the socket inactivity timeout. A timeout * does not necessarily mean that an error has occurred, especially if you're * only listening for events. * @param {(object|boolean)} [options.tls] - Set to true to use TLS for this connection. * Set to an object to use TLS and pass the object to tls.connect as the tls * options. If your device uses self-signed certificates, you'll either have to * set 'rejectUnauthorized : false' or supply the proper CA certificate. See the * options for * {@link https://nodejs.org/api/tls.html#tls_tls_connect_port_host_options_callback|tls.connect()} * for more info. * @throws <strong>WARNING: If you do not listen for 'error' or 'timeout' events and one * occurrs during the initial connection (host unreachable, connection refused, * etc.), an "Unhandled 'error' event" exception will be thrown.</strong> * * @example * * <pre> * var MikroNode = require('mikronode'); * * var device1 = new MikroNode('192.168.88.1') * var device2 = new MikroNode('192.168.88.2') * var promise1 = Observable.fromPromise(device1.connect('admin', 'mypassword')); * var promise2 = Observable.fromPromise(device2.connect('admin', 'mypassword')); * * // When connected to both servers. * Observable.zip(promise1,promise2).subscribe(function(connections) { * connections[0].closeOnDone(true); // Set close on done for the connection. All channels must be done before this will issue done. * connections[1].closeOnDone(true); * var channel1=connections[0].openChannel(null,true); // choose chanel number for me, close chanel on done. * var channel2=connections[1].openChannel(null,true); // choose chanel number for me, close chanel on done. * // Everything is an observable stream now. Much more powerful * channel1.data.merge(channel2.data).map(function(sentence){ return sentence; // do something cool mapping streams from both devices }) .filter(function(sentence){ return sentence.type!='trap'}) // filter out traps. We could split off the stream and handle it somewhere else. * .subscribe(function(sentence){ console.log(sentence)} * } * , null * , function(err) * console.error('Error when connecting: ', err); * }); * * </pre> */ /** Timeout for connecting. */ /** Port to connect */ function MikroNode(host) { var port = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 8728; var timeout = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 5; _classCallCheck(this, MikroNode); _debug.set(this, _constants.DEBUG.NONE); _status.set(this, _constants.CONNECTION.DISCONNECTED); _tls.set(this, null); _socketOpts.set(this, {}); _socketProto.set(this, 'tcp4'); // const {debug,port,timeout}=opts; _host.set(this, host); _port.set(this, port); _timeout.set(this, timeout); } /** Change debug level **/ /** Socket connected to mikrotik device */ /** Debug Level */ _createClass(MikroNode, [{ key: 'setDebug', value: function setDebug(debug) { _debug.set(this, debug); if (_sock.get(this)) _sock.get(this).setDebug(debug); if (this.connection) this.connection.setDebug(debug); } /** Change the port */ }, { key: 'setPort', value: function setPort(port) { _port.set(this, port); } /** get/set tls options for this connection */ }, { key: 'TLS', value: function TLS() { var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; if (opts) { _tls.set(this, opts); if (opts.host) _host.set(this, opts.host); if (opts.port) _port.set(this, opts.port); return this; } return _tls.get(this); } }, { key: 'setTimeout', /** Set timeout for socket connecion */ value: function setTimeout(timeout) { _timeout.set(this, timeout); _sock.get(this).setTimeout(timeout); } /** Connect to remote server using ID and password */ }, { key: 'connect', value: function connect(arg1, arg2) { var _this = this; _debug.get(this) >= _constants.DEBUG.INFO && console.log('Connecting to ' + _host.get(this)); var cb = void 0; _debug.get(this) >= _constants.DEBUG.SILLY && console.log('Creating socket'); _sock.set(this, new SocketStream(_timeout.get(this), _debug.get(this), _tls.get(this) ? _typeof(_tls.get(this)) === _typeof({}) ? _tls.get(this) : {} : false)); var stream = _sock.get(this).getStream(); if ((typeof arg1 === 'undefined' ? 'undefined' : _typeof(arg1)) === _typeof({})) { _socketOpts.set(this, _extends({}, _socketOpts.get(this), { arg1: arg1 })); if ((typeof arg1 === 'undefined' ? 'undefined' : _typeof(arg1)) === _typeof(function () {})) cb = arg2; } else if ((typeof arg1 === 'undefined' ? 'undefined' : _typeof(arg1)) === _typeof(function () {})) cb = arg1; var close = function close() { return _sock.get(_this).getStream().sentence.complete(); }; /** Flag added to choose between pre-v6.43 and post-v6.43 (post-v6.43 by default)*/ var login = function login(user, password, post, cb) { if (post === undefined) { post = true; } _debug.get(_this) >= _constants.DEBUG.DEBUG && console.log('Logging in'); stream.write('/login'); var _getUnwrappedPromise = (0, _Util.getUnwrappedPromise)(), promise = _getUnwrappedPromise.promise, resolve = _getUnwrappedPromise.resolve, reject = _getUnwrappedPromise.reject; // Create a connection handler _this.connection = new _Connection2.default(_extends({}, stream, { close: close }), function (challenge) { if (post) { stream.write(["/login", "=name=" + user, "=password=" + password]); } else { var md5 = _crypto2.default.createHash('md5'); md5.update(Buffer.concat([Buffer.from(nullString + password), Buffer.from(challenge)])); stream.write(["/login", "=name=" + user, "=response=00" + md5.digest("hex")]); } }, { resolve: resolve, reject: reject }); _this.connection.setDebug(_debug.get(_this)); promise.then(function () { if (cb) cb(null, _this.connection); }, function (err) { if (cb) cb(err, null); }); return promise; }; _debug.get(this) >= _constants.DEBUG.SILLY && console.log('Creating promise for socket connect'); var promise = new _promise2.default(function (resolve, reject) { _debug.get(_this) >= _constants.DEBUG.SILLY && console.log('Connecting to remote host. Detected %s', _net2.default.isIPv6(_host.get(_this)) ? 'ipv6' : _net2.default.isIPv4(_host.get(_this)) ? 'ipv4' : 'DNS lookup'); var fn = _net2.default.isIPv4(_host.get(_this)) || _net2.default.isIPv6(_host.get(_this)) ? (_socketOpts.get(_this).family = _net2.default.isIPv6(_host.get(_this)) ? 6 : 4, function (a, b) { return b(null, [a]); }) : _socketOpts.get(_this).family == 6 ? _dns2.default.resolve4 : _dns2.default.resolve6; fn(_host.get(_this), function (err, data) { if (err) { return reject("Host resolve error: ", err); } // this.debug>=DEBUG.DEBUG&&console.log('Socket connect: ',{...this.socketOpts,...this.tls,host:this.host,port:this.port}); _sock.get(_this).connect(_extends({}, _socketOpts.get(_this), _tls.get(_this), { host: data[0], port: _port.get(_this) })).then(function (_ref) { var _ref2 = _toArray(_ref), socketOpts = _ref2[0], args = _ref2.slice(1); _debug.get(_this) >= _constants.DEBUG.DEBUG && console.log('Connected. Waiting for login.'); // initiate the login process resolve([login, socketOpts].concat(_toConsumableArray(args))); if (cb) cb.apply(undefined, [null, login, socketOpts].concat(_toConsumableArray(args))); /* Initiate Login */ _sock.get(_this).getStream().sentence.take(1).subscribe(null, reject, null); }).catch(function (err) { if (cb) cb(err, null); reject(err); }); // reject connect promise if the socket throws an error. }); }); // Connect to the server. return promise; } }, { key: 'socketOpts', set: function set(opts) { _socketOpts.set(this, opts); if (opts.host) _host.set(this, opts.host); if (opts.port) _port.set(this, opts.port); } }]); return MikroNode; }(); // Object.keys(DEBUG).forEach(k=>MikroNode[k]=DEBUG[k]); var api = (0, _simpleAssign2.default)(MikroNode, _constants.DEBUG); exports.default = (0, _simpleAssign2.default)(api, { CONNECTION: _constants.CONNECTION, CHANNEL: _constants.CHANNEL, EVENT: _constants.EVENT, resultsToObj: _Util.resultsToObj, getUnwrappedPromise: _Util.getUnwrappedPromise }); /** Handles the socket connection and parsing of infcoming data. */ /* This entire class is private (not exported) */ var _rawSocket = new WeakMap(); var _socket = new WeakMap(); var _status2 = new WeakMap(); var _debug2 = new WeakMap(); var _sentence$ = new WeakMap(); var _parsed$ = new WeakMap(); var _data$ = new WeakMap(); var _closeSocket = new WeakMap(); var SocketStream = (_class = function () { function SocketStream(timeout, debug, tls) { var _this2 = this; _classCallCheck(this, SocketStream); _status2.set(this, _constants.CONNECTION.NONE); _debug2.set(this, _constants.DEBUG.NONE); _closeSocket.set(this, function (e) { _debug2.get(this) >= _constants.DEBUG.DEBUG && console.log("Closing Socket ", e); e ? _rawSocket.get(this).destroy(e) : _rawSocket.get(this).destroy(); }.bind(this)); debug >= _constants.DEBUG.DEBUG && console.log('SocketStream::new', [timeout, debug]); _debug2.set(this, debug); _rawSocket.set(this, new Socket()); _socket.set(this, tls ? new _tls3.default.TLSSocket(_rawSocket.get(this), tls) : _rawSocket.get(this)); _sentence$.set(this, new _rxjs.Subject()); // Each raw sentence from the stream passes through this parser. var holdBuffer = []; _parsed$.set(this, _sentence$.get(this).do(function (d) { return _debug2.get(_this2) >= _constants.DEBUG.SILLY && console.log("Data to parse:", JSON.stringify(d)); }).map(function (o) { return o.map(function (x) { return x.split("\r").join("\\r").split("\n").join("\\n"); }).join('\n'); }) // Make array string. .map(function (d) { if (holdBuffer.length) { console.log("Hold buffer:", holdBuffer); holdBuffer = []; } var s = _parser2.default.parse(d); s.host = _this2.host; return s; }).catch(function (e) { holdBuffer = []; console.error("***************************************************************************"); console.error("***************************************************************************"); console.error("Error processing sentence:", e); console.error("Skipping and continuing"); console.error("***************************************************************************"); console.error("***************************************************************************"); return _parsed$.get(_this2); }).filter(function (e) { return !!e; }).flatMap(function (d) { Object.keys(d).forEach(function (k) { if (typeof d[k] === "string") d[k] = d[k].split("\\r").join("\r").split("\\n").join("\n"); }); return _rxjs.Observable.from(d); }) // break off observable from parse stream. .share()); // parse the string. // When we receive data, it is pushed into the stream defined below. _data$.set(this, _rxjs.Observable.fromEvent(_socket.get(this), 'data')); // this is the stream reader/parser. // My poor stream parser _data$.get(this).scan(function ( /* @type Buffer */last, /* @type Buffer */stream, i) { var buff = Buffer.concat([last, stream]), end = 0, idx = 0, packet = void 0; _debug2.get(_this2) >= _constants.DEBUG.DEBUG && console.log("Packet received: ", stream.toString().split('\0')); _debug2.get(_this2) >= _constants.DEBUG.DEBUG && last.length > 0 && console.log("Starting parse loop w/existing packet ", last.toString()); while (idx < buff.length && (end = buff.indexOf('\0', idx, "utf8")) !== -1) { _debug2.get(_this2) >= _constants.DEBUG.SILLY && console.log("Decoding: ", idx, end, buff.length, buff.slice(idx, end)); packet = (0, _Util.decodePacket)(buff.slice(idx, end)); idx = end + 1; _debug2.get(_this2) >= _constants.DEBUG.SILLY && console.log('Detected end of sentence, posting existing sentence', packet); _sentence$.get(_this2).next(packet); } return idx >= buff.length ? Buffer.alloc(0) : buff.slice(idx, buff.length); }, Buffer.from([])).subscribe(function (e) { return _debug2.get(_this2) >= _constants.DEBUG.DEBUG && e.length && console.log('Buffer leftover: ', e); }, _closeSocket.get(this), _closeSocket.get(this)); _socket.get(this).on('end', function (a) { _debug2.get(_this2) >= _constants.DEBUG.INFO && console.log('Connection end ' + a); if (_status2.get(_this2) == _constants.CONNECTION.CONNECTED) // Completing the sentence closes all downstream observables and completes any subscriptions. _sentence$.get(_this2).complete(); // this.handler.close(true); }); _socket.get(this).on('error', function (a) { _debug2.get(_this2) >= _constants.DEBUG.ERROR && console.log('Connection error: ' + a); // Erroring the sentence closes all downstream observables and issues error any subscriptions. _sentence$.get(_this2).error(a); }); this.setTimeout(timeout); // This will be called if there is no activity to the server. // If this occurs before the login is successful, it could be // that it is a connection timeout. _socket.get(this).setKeepAlive(true); this.b = []; this.len = 0; this.line = ''; } // This is the function handler for error or complete for the parsing functions. _createClass(SocketStream, [{ key: 'setDebug', value: function setDebug(d) { _debug2.get(this) >= _constants.DEBUG.DEBUG && console.log('SocketStream::setDebug', [d]); _debug2.set(this, d); } }, { key: 'setTimeout', value: function setTimeout(timeout) { var _this3 = this; _debug2.get(this) >= _constants.DEBUG.DEBUG && console.log('SocketStream::setTimeout', [timeout]); _socket.get(this).setTimeout(timeout * 1000, function (e) { // the socket timed out. According to the NodeJS api docs, right after this, it will be._closed. if (_status2.get(_this3) !== _constants.CONNECTION.CONNECTED) { _debug2.get(_this3) && console.log('Socket Timeout'); _sentence$.get(_this3).error("Timeout: ", JSON.stringify(e)); // self.emit('error','Timeout Connecting to host',self); } }); } /** Connect the socket */ }, { key: 'connect', value: function connect(socketOpts) { var _this4 = this; _debug2.get(this) >= _constants.DEBUG.DEBUG && console.log('SocketStream::Connect %s', this.tls ? "(TLS)" : "", socketOpts); _status2.set(this, _constants.CONNECTION.CONNECTING); this.host = socketOpts.host || 'localhost'; return new _promise2.default(function (res, rej) { /** Listen for complete on stream to dictate if socket will close */ _sentence$.get(_this4) // .do(d=>console.log("Sentence: ",d)) .subscribe(null, function (e) { rej(e);_closeSocket.get(_this4)(); }, _closeSocket.get(_this4)); // Connect to the socket. This works for both TLS and non TLS sockets. try { _rawSocket.get(_this4).connect(socketOpts, function () { for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _debug2.get(_this4) >= _constants.DEBUG.INFO && console.log('SocketStream::Connected ', args, socketOpts); _status2.set(_this4, _constants.CONNECTION.CONNECTED); socketOpts = _extends({}, socketOpts, { localAddress: _socket.get(_this4).localAddress, localPort: _socket.get(_this4).localPort }); if (_socket.get(_this4).encrypted) res([_extends({}, socketOpts, { authorized: _socket.get(_this4).authorized, authorizationError: _socket.get(_this4).authorizationError, protocol: _socket.get(_this4).getProtocol(), alpnProtocol: _socket.get(_this4).alpnProtocol, npnProtocol: _socket.get(_this4).npnProtocol, cipher: _socket.get(_this4).getCipher(), cert: _socket.get(_this4).getPeerCertificate() })].concat(args));else res([socketOpts].concat(args)); }); } catch (e) { _debug2.get(_this4) >= _constants.DEBUG.DEBUG && console.error('Caught exception while opening socket: ', e); rej(e); } }); } /** Provides access to all of the different stages of input streams and the write stream. */ }, { key: 'getStream', value: function getStream() { return { sentence: _sentence$.get(this), write: this.write, read: _parsed$.get(this), raw: _data$.get(this) }; } }, { key: 'write', value: function write(data, args) { var _this5 = this; if (args && (typeof args === 'undefined' ? 'undefined' : _typeof(args)) === _typeof({})) { _debug2.get(this) >= _constants.DEBUG.SILLY && console.log("Converting obj to args", args); data = data.concat(Array.isArray(args) ? args : (0, _Util.objToAPIParams)(args, data[0].split('/').pop())); } _debug2.get(this) >= _constants.DEBUG.DEBUG && console.log('SocketStream::write:', [data]); if (!_socket.get(this) || !(_status2.get(this) & (_constants.CONNECTION.CONNECTED | _constants.CONNECTION.CONNECTING))) { _debug2.get(this) > _constants.DEBUG.WARN && console.log('write: not connected '); return; } if ((typeof data === 'undefined' ? 'undefined' : _typeof(data)) === _constants.STRING_TYPE) data = [data];else if (!Array.isArray(data)) return; data.forEach(function (i) { try { _debug2.get(_this5) >= _constants.DEBUG.DEBUG && console.log('SocketStream::write: sending ' + i); _socket.get(_this5).write((0, _Util.encodeString)(i, _debug2.get(_this5) & _constants.DEBUG.SILLY)); } catch (error) { _sentence$.get(_this5).error(error); } }); _socket.get(this).write(nullString); } }]); return SocketStream; }(), (_applyDecoratedDescriptor(_class.prototype, 'write', [_coreDecorators.autobind], Object.getOwnPropertyDescriptor(_class.prototype, 'write'), _class.prototype)), _class); module.exports = exports['default']; /***/ }), /* 2 */ /***/ (function(module, exports) { module.exports = function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; /***/ }), /* 3 */ /***/ (function(module, exports) { module.exports = require("util"); /***/ }), /* 4 */ /***/ (function(module, exports) { module.exports = require("net"); /***/ }), /* 5 */ /***/ (function(module, exports) { module.exports = require("tls"); /***/ }), /* 6 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; module.exports = __webpack_require__(7) /***/ }), /* 7 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; module.exports = __webpack_require__(8); __webpack_require__(11); __webpack_require__(12); __webpack_require__(13); __webpack_require__(14); __webpack_require__(16); /***/ }), /* 8 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; var asap = __webpack_require__(9); function noop() {} // States: // // 0 - pending // 1 - fulfilled with _value // 2 - rejected with _value // 3 - adopted the state of another promise, _value // // once the state is no longer pending (0) it is immutable // All `_` prefixed properties will be reduced to `_{random number}` // at build time to obfuscate them and discourage their use. // We don't use symbols or Object.defineProperty to fully hide them // because the performance isn't good enough. // to avoid using try/catch inside critical functions, we // extract them to here. var LAST_ERROR = null; var IS_ERROR = {}; function getThen(obj) { try { return obj.then; } catch (ex) { LAST_ERROR = ex; return IS_ERROR; } } function tryCallOne(fn, a) { try { return fn(a); } catch (ex) { LAST_ERROR = ex; return IS_ERROR; } } function tryCallTwo(fn, a, b) { try { fn(a, b); } catch (ex) { LAST_ERROR = ex; return IS_ERROR; } } module.exports = Promise; function Promise(fn) { if (typeof this !== 'object') { throw new TypeError('Promises must be constructed via new'); } if (typeof fn !== 'function') { throw new TypeError('Promise constructor\'s argument is not a function'); } this._h = 0; this._i = 0; this._j = null; this._k = null; if (fn === noop) return; doResolve(fn, this); } Promise._l = null; Promise._m = null; Promise._n = noop; Promise.prototype.then = function(onFulfilled, onRejected) { if (this.constructor !== Promise) { return safeThen(this, onFulfilled, onRejected); } var res = new Promise(noop); handle(this, new Handler(onFulfilled, onRejected, res)); return res; }; function safeThen(self, onFulfilled, onRejected) { return new self.constructor(function (resolve, reject) { var res = new Promise(noop); res.then(resolve, reject); handle(self, new Handler(onFulfilled, onRejected, res)); }); } function handle(self, deferred) { while (self._i === 3) { self = self._j; } if (Promise._l) { Promise._l(self); } if (self._i === 0) { if (self._h === 0) { self._h = 1; self._k = deferred; return; } if (self._h === 1) { self._h = 2; self._k = [self._k, deferred]; return; } self._k.push(deferred); return; } handleResolved(self, deferred); } function handleResolved(self, deferred) { asap(function() { var cb = self._i === 1 ? deferred.onFulfilled : deferred.onRejected; if (cb === null) { if (self._i === 1) { resolve(deferred.promise, self._j); } else { reject(deferred.promise, self._j); } return; } var ret = tryCallOne(cb, self._j); if (ret === IS_ERROR) { reject(deferred.promise, LAST_ERROR); } else { resolve(deferred.promise, ret); } }); } function resolve(self, newValue) { // Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure if (newValue === self) { return reject( self, new TypeError('A promise cannot be resolved with itself.') ); } if ( newValue && (typeof newValue === 'object' || typeof newValue === 'function') ) { var then = getThen(newValue); if (then === IS_ERROR) { return reject(self, LAST_ERROR); } if ( then === self.then && newValue instanceof Promise ) { self._i = 3; self._j = newValue; finale(self); return; } else if (typeof then === 'function') { doResolve(then.bind(newValue), self); return; } } self._i = 1; self._j = newValue; finale(self); } function reject(self, newValue) { self._i = 2; self._j = newValue; if (Promise._m) { Promise._m(self, newValue); } finale(self); } function finale(self) { if (self._h === 1) { handle(self, self._k); self._k = null; } if (self._h === 2) { for (var i = 0; i < self._k.length; i++) { handle(self, self._k[i]); } self._k = null; } } function Handler(onFulfilled, onRejected, promise){ this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null; this.onRejected = typeof onRejected === 'function' ? onRejected : null; this.promise = promise; } /** * Take a potentially misbehaving resolver function and make sure * onFulfilled and onRejected are only called once. * * Makes no guarantees about asynchrony. */ function doResolve(fn, promise) { var done = false; var res = tryCallTwo(fn, function (value) { if (done) return; done = true; resolve(promise, value); }, function (reason) { if (done) return; done = true; reject(promise, reason); }); if (!done && res === IS_ERROR) { done = true; reject(promise, LAST_ERROR); } } /***/ }), /* 9 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var domain; // The domain module is executed on demand var hasSetImmediate = typeof setImmediate === "function"; // Use the fastest means possible to execute a task in its own turn, with // priority over other events including network IO events in Node.js. // // An exception thrown by a task will permanently interrupt the processing of // subsequent tasks. The higher level `asap` function ensures that if an // exception is thrown by a task, that the task queue will continue flushing as // soon as possible, but if you use `rawAsap` directly, you are responsible to // either ensure that no exceptions are thrown from your task, or to manually // call `rawAsap.requestFlush` if an exception is thrown. module.exports = rawAsap; function rawAsap(task) { if (!queue.length) { requestFlush(); flushing = true; } // Avoids a function call queue[queue.length] = task; } var queue = []; // Once a flush has been requested, no further calls to `requestFlush` are // necessary until the next `flush` completes. var flushing = false; // The position of the next task to execute in the task queue. This is // preserved between calls to `flush` so that it can be resumed if // a task throws an exception. var index = 0; // If a task schedules additional tasks recursively, the task queue can grow // unbounded. To prevent memory excaustion, the task queue will periodically // truncate already-completed tasks. var capacity = 1024; // The flush function processes all tasks that have been scheduled with // `rawAsap` unless and until one of those tasks throws an exception. // If a task throws an exception, `flush` ensures that its state will remain // consistent and will resume where it left off when called again. // However, `flush` does not make any arrangements to be called again if an // exception is thrown. function flush() { while (index < queue.length) { var currentIndex = index; // Advance the index before calling the task. This ensures that we will // begin flushing on the next task the task throws an error. index = index + 1; queue[currentIndex].call(); // Prevent leaking memory for long chains of recursive calls to `asap`. // If we call `asap` within tasks scheduled by `asap`, the queue will // grow, but to avoid an O(n) walk for every task we execute, we don't // shift tasks off the queue after they have been executed. // Instead, we periodically shift 1024 tasks off the queue. if (index > capacity) { // Manually shift all values starting at the index back to the // beginning of the queue. for (var scan = 0, newLength = queue.length - index; scan < newLength; scan++) { queue[scan] = queue[scan + index]; } queue.length -= index; index = 0; } } queue.length = 0; index = 0; flushing = false; } rawAsap.requestFlush = requestFlush; function requestFlush() { // Ensure flushing is not bound to any domain. // It is not sufficient to exit the domain, because domains exist on a stack. // To execute code outside of any domain, the following dance is necessary. var parentDomain = process.domain; if (parentDomain) { if (!domain) { // Lazy execute the domain module. // Only employed if the user elects to use domains. domain = __webpack_require__(10); } domain.active = process.domain = null; } // `setImmediate` is slower that `process.nextTick`, but `process.nextTick` // cannot handle recursion. // `requestFlush` will only be called recursively from `asap.js`, to resume // flushing after an error is thrown into a domain. // Conveniently, `setImmediate` was introduced in the same version // `process.nextTick` started throwing recursion errors. if (flushing && hasSetImmediate) { setImmediate(flush); } else { process.nextTick(flush); } if (parentDomain) { domain.active = process.domain = parentDomain; } } /***/ }), /* 10 */ /***/ (function(module, exports) { module.exports = require("domain"); /***/ }), /* 11 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; var Promise = __webpack_require__(8); module.exports = Promise; Promise.prototype.done = function (onFulfilled, onRejected) { var self = arguments.length ? this.then.apply(this, arguments) : this; self.then(null, function (err) { setTimeout(function () { throw err; }, 0); }); }; /***/ }), /* 12 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; var Promise = __webpack_require__(8); module.exports = Promise; Promise.prototype.finally = function (f) { return this.then(function (value) { return Promise.resolve(f()).then(function () { return value; }); }, function (err) { return Promise.resolve(f()).then(function () { throw err; }); }); }; /***/ }), /* 13 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; //This file contains the ES6 extensions to the core Promises/A+ API var Promise = __webpack_require__(8); module.exports = Promise; /* Static Functions */ var TRUE = valuePromise(true); var FALSE = valuePromise(false); var NULL = valuePromise(null); var UNDEFINED = valuePromise(undefined); var ZERO = valuePromise(0); var EMPTYSTRING = valuePromise(''); function valuePromise(value) { var p = new Promise(Promise._n); p._i = 1; p._j = value; return p; } Promise.resolve = function (value) { if (value instanceof Promise) return value; if (value === null) return NULL; if (value === undefined) return UNDEFINED; if (value === true) return TRUE; if (value === false) return FALSE; if (value === 0) return ZERO; if (value === '') return EMPTYSTRING; if (typeof value === 'object' || typeof value === 'function') { try { var then = value.then; if (typeof then === 'function') { return new Promise(then.bind(value)); } } catch (ex) { return new Promise(function (resolve, reject) { reject(ex); }); } } return valuePromise(value); }; Promise.all = function (arr) { var args = Array.prototype.slice.call(arr); return new Promise(function (resolve, reject) { if (args.length === 0) return resolve([]); var remaining = args.length; function res(i, val) { if (val && (typeof val === 'object' || typeof val === 'function')) { if (val instanceof Promise && val.then === Promise.prototype.then) { while (val._i === 3) { val = val._j; } if (val._i === 1) return res(i, val._j); if (val._i === 2) reject(val._j); val.then(function (val) { res(i, val); }, reject); return; } else { var then = val.then; if (typeof then === 'function') { var p = new Promise(then.bind(val)); p.then(function (val) { res(i, val); }, reject); return; } } } args[i] = val; if (--remaining === 0) { resolve(args); } } for (var i = 0; i < args.length; i++) { res(i, args[i]); } }); }; Promise.reject = function (value) { return new Promise(function (resolve, reject) { reject(value); }); }; Promise.race = function (values) { return new Promise(function (resolve, reject) { values.forEach(function(value){ Promise.resolve(value).then(resolve, reject); }); }); }; /* Prototype Methods */ Promise.prototype['catch'] = function (onRejected) { return this.then(null, onRejected); }; /***/ }), /* 14 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; // This file contains then/promise specific extensions that are only useful // for node.js interop var Promise = __webpack_require__(8); var asap = __webpack_require__(15); module.exports = Promise; /* Static Functions */ Promise.denodeify = function (fn, argumentCount) { if ( typeof argumentCount === 'number' && argumentCount !== Infinity ) { return denodeifyWithCount(fn, argumentCount); } else { return denodeifyWithoutCount(fn); } }; var callbackFn = ( 'function (err, res) {' + 'if (err) { rj(err); } else { rs(res); }' + '}' ); function denodeifyWithCount(fn, argumentCount) { var args = []; for (var i = 0; i < argumentCount; i++) { args.push('a' + i); } var body = [ 'return function (' + args.join(',') + ') {', 'var self = this;', 'return new Promise(function (rs, rj) {', 'var res = fn.call(', ['self'].concat(args).concat([callbackFn]).join(','), ');', 'if (res &&', '(typeof res === "object" || typeof res === "function") &&', 'typeof res.then === "function"', ') {rs(res);}', '});', '};' ].join(''); return Function(['Promise', 'fn'], body)(Promise, fn); } function denodeifyWithoutCount(fn) { var fnLength = Math.max(fn.length - 1, 3); var args = []; for (var i = 0; i < fnLength; i++) { args.push('a' + i); } var body = [ 'return function (' + args.join(',') + ') {', 'var self = this;', 'var args;', 'var argLength = arguments.length;', 'if (arguments.length > ' + fnLength + ') {', 'args = new Array(arguments.length + 1);', 'for (var i = 0; i < arguments.length; i++) {', 'args[i] = arguments[i];', '}', '}', 'return new Promise(function (rs, rj) {', 'var cb = ' + callbackFn + ';', 'var res;', 'switch (argLength) {', args.concat(['extra']).map(function (_, index) { return ( 'case ' + (index) + ':' + 'res = fn.call(' + ['self'].concat(args.slice(0, index)).concat('cb').join(',') + ');' + 'break;' ); }).join(''), 'default:', 'args[argLength] = cb;', 'res = fn.apply(self, args);', '}', 'if (res &&', '(typeof res === "object" || typeof res === "function") &&', 'typeof res.then === "function"', ') {rs(res);}', '});', '};' ].join(''); return Function( ['Promise', 'fn'], body )(Promise, fn); } Promise.nodeify = function (fn) { return function () { var args = Array.prototype.slice.call(arguments); var callback = typeof args[args.length - 1] === 'function' ? args.pop() : null; var ctx = this; try { return fn.apply(this, arguments).nodeify(callback, ctx); } catch (ex) { if (callback === null || typeof callback == 'undefined') { return new Promise(function (resolve, reject) { reject(ex); }); } else { asap(function () { callback.call(ctx, ex); }) } } } }; Promise.prototype.nodeify = function (callback, ctx) { if (typeof callback != 'function') return this; this.then(function (value) { asap(function () { callback.call(ctx, null, value); }); }, function (err) { asap(function () { callback.call(ctx, err); }); }); }; /***/ }), /* 15 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var rawAsap = __webpack_require__(9); var freeTasks = []; /** * Calls a task as soon as possible after returning, in its own event, with * priority over IO events. An exception thrown in a task can be handled by * `process.on("uncaughtException") or `domain.on("error")`, but will otherwise * crash the process. If the error is handled, all subsequent tasks will * resume. * * @param {{call}} task A callable object, typically a function that takes no * arguments. */ module.exports = asap; function asap(task) { var rawTask; if (freeTasks.length) { rawTask = freeTasks.pop(); } else { rawTask = new RawTask(); } rawTask.task = task; rawTask.domain = process.domain; rawAsap(rawTask); } function RawTask() { this.task = null; this.domain = null; } RawTask.prototype.call = function () { if (this.domain) { this.domain.enter(); } var threw = true; try { this.task.call(); threw = false; // If the task throws an exception (presumably) Node.js restores the // domain stack for the next event. if (this.domain) { this.domain.exit(); } } finally { // We use try/finally and a threw flag to avoid messing up stack traces // when we catch and release errors. if (threw) { // In Node.js, uncaught exceptions are considered fatal errors. // Re-throw them to interrupt flushing! // Ensure that flushing continues if an uncaught exception is // suppressed listening process.on("uncaughtException") or // domain.on("error"). rawAsap.requestFlush(); } // If the task threw an error, we do not want to exit the domain here. // Exiting the domain would prevent the domain from catching the error. this.task = null; this.domain = null; freeTasks.push(this); } }; /***/ }), /* 16 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; var Promise = __webpack_require__(8); module.exports = Promise; Promise.enableSynchronous = function () { Promise.prototype.isPending = function() { return this.getState() == 0; }; Promise.prototype.isFulfilled = function() { return this.getState() == 1; }; Promise.prototype.isRejected = function() { return this.getState() == 2; }; Promise.prototype.getValue = function () { if (this._i === 3) { return this._j.getValue(); } if (!this.isFulfilled()) { throw new Error('Cannot get a value of an unfulfilled promise.'); } return this._j; }; Promise.prototype.getReason = function () { if (this._i === 3) { return this._j.getReason(); } if (!this.isRejected()) { throw new Error('Cannot get a rejection reason of a non-rej