@twilio/notifications
Advanced tools
Comparing version 1.0.1 to 1.0.2-rc.0
@@ -6,2 +6,11 @@ # Change Log | ||
### [1.0.2-rc.0](https://github.com/twilio/twilio-notifications.js/compare/@twilio/notifications@1.0.1...@twilio/notifications@1.0.2-rc.0) (2021-07-29) | ||
### Bug Fixes | ||
* Add missing browserslist ([173b2cd](https://github.com/twilio/twilio-notifications.js/commit/173b2cdf5c71b3585c6843a6a0852d5839b69ef0)) | ||
### 1.0.1 (2021-07-26) | ||
@@ -8,0 +17,0 @@ |
1464
dist/browser.js
@@ -30,10 +30,21 @@ /* | ||
require('core-js/modules/es.reflect.construct.js'); | ||
var _asyncToGenerator = require('@babel/runtime/helpers/asyncToGenerator'); | ||
var _classCallCheck = require('@babel/runtime/helpers/classCallCheck'); | ||
var _createClass = require('@babel/runtime/helpers/createClass'); | ||
var _inherits = require('@babel/runtime/helpers/inherits'); | ||
var _possibleConstructorReturn = require('@babel/runtime/helpers/possibleConstructorReturn'); | ||
var _getPrototypeOf = require('@babel/runtime/helpers/getPrototypeOf'); | ||
var _regeneratorRuntime = require('@babel/runtime/regenerator'); | ||
require('core-js/modules/es.array.iterator.js'); | ||
require('core-js/modules/es.map.js'); | ||
require('core-js/modules/es.object.to-string.js'); | ||
require('core-js/modules/es.string.iterator.js'); | ||
require('core-js/modules/web.dom-collections.iterator.js'); | ||
require('core-js/modules/es.array.concat.js'); | ||
require('core-js/modules/web.dom-collections.for-each.js'); | ||
require('core-js/modules/es.promise.js'); | ||
var twilsock = require('@twilio/twilsock'); | ||
var _typeof = require('@babel/runtime/helpers/typeof'); | ||
var twilsock = require('twilsock'); | ||
var _assertThisInitialized = require('@babel/runtime/helpers/assertThisInitialized'); | ||
var _defineProperty = require('@babel/runtime/helpers/defineProperty'); | ||
@@ -45,4 +56,7 @@ require('core-js/modules/es.regexp.to-string.js'); | ||
var _slicedToArray = require('@babel/runtime/helpers/slicedToArray'); | ||
var _toConsumableArray = require('@babel/runtime/helpers/toConsumableArray'); | ||
require('core-js/modules/es.set.js'); | ||
require('core-js/modules/es.array.filter.js'); | ||
var logger = require('loglevel'); | ||
var twilsock_connector = require('./twilsock.connector'); | ||
var declarativeTypeValidator = require('@twilio/declarative-type-validator'); | ||
@@ -73,21 +87,15 @@ | ||
var _asyncToGenerator__default = /*#__PURE__*/_interopDefaultLegacy(_asyncToGenerator); | ||
var _classCallCheck__default = /*#__PURE__*/_interopDefaultLegacy(_classCallCheck); | ||
var _createClass__default = /*#__PURE__*/_interopDefaultLegacy(_createClass); | ||
var _inherits__default = /*#__PURE__*/_interopDefaultLegacy(_inherits); | ||
var _possibleConstructorReturn__default = /*#__PURE__*/_interopDefaultLegacy(_possibleConstructorReturn); | ||
var _getPrototypeOf__default = /*#__PURE__*/_interopDefaultLegacy(_getPrototypeOf); | ||
var _regeneratorRuntime__default = /*#__PURE__*/_interopDefaultLegacy(_regeneratorRuntime); | ||
var _typeof__default = /*#__PURE__*/_interopDefaultLegacy(_typeof); | ||
var _assertThisInitialized__default = /*#__PURE__*/_interopDefaultLegacy(_assertThisInitialized); | ||
var _defineProperty__default = /*#__PURE__*/_interopDefaultLegacy(_defineProperty); | ||
var _slicedToArray__default = /*#__PURE__*/_interopDefaultLegacy(_slicedToArray); | ||
var _toConsumableArray__default = /*#__PURE__*/_interopDefaultLegacy(_toConsumableArray); | ||
var logger__namespace = /*#__PURE__*/_interopNamespace(logger); | ||
/*! ***************************************************************************** | ||
Copyright (c) Microsoft Corporation. | ||
Permission to use, copy, modify, and/or distribute this software for any | ||
purpose with or without fee is hereby granted. | ||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH | ||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY | ||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, | ||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM | ||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR | ||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | ||
PERFORMANCE OF THIS SOFTWARE. | ||
***************************************************************************** */ | ||
function __decorate(decorators, target, key, desc) { | ||
@@ -97,3 +105,3 @@ var c = arguments.length, | ||
d; | ||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);else for (var i = decorators.length - 1; i >= 0; i--) { | ||
if ((typeof Reflect === "undefined" ? "undefined" : _typeof__default['default'](Reflect)) === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);else for (var i = decorators.length - 1; i >= 0; i--) { | ||
if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; | ||
@@ -104,3 +112,3 @@ } | ||
function __metadata(metadataKey, metadataValue) { | ||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); | ||
if ((typeof Reflect === "undefined" ? "undefined" : _typeof__default['default'](Reflect)) === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); | ||
} | ||
@@ -586,65 +594,86 @@ | ||
class Logger { | ||
setLevel(level) { | ||
log.setLevel(level); | ||
var Logger = /*#__PURE__*/function () { | ||
function Logger() { | ||
_classCallCheck__default['default'](this, Logger); | ||
} | ||
trace() { | ||
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { | ||
args[_key] = arguments[_key]; | ||
_createClass__default['default'](Logger, [{ | ||
key: "setLevel", | ||
value: function setLevel(level) { | ||
log.setLevel(level); | ||
} | ||
}, { | ||
key: "trace", | ||
value: function trace() { | ||
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { | ||
args[_key] = arguments[_key]; | ||
} | ||
log.trace.apply(null, prepareLine("T", args)); | ||
} | ||
log.trace.apply(null, prepareLine("T", args)); | ||
} | ||
}, { | ||
key: "debug", | ||
value: function debug() { | ||
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { | ||
args[_key2] = arguments[_key2]; | ||
} | ||
debug() { | ||
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { | ||
args[_key2] = arguments[_key2]; | ||
log.debug.apply(null, prepareLine("D", args)); | ||
} | ||
}, { | ||
key: "info", | ||
value: function info() { | ||
for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { | ||
args[_key3] = arguments[_key3]; | ||
} | ||
log.debug.apply(null, prepareLine("D", args)); | ||
} | ||
log.info.apply(null, prepareLine("I", args)); | ||
} | ||
}, { | ||
key: "warn", | ||
value: function warn() { | ||
for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { | ||
args[_key4] = arguments[_key4]; | ||
} | ||
info() { | ||
for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { | ||
args[_key3] = arguments[_key3]; | ||
log.warn.apply(null, prepareLine("W", args)); | ||
} | ||
}, { | ||
key: "error", | ||
value: function error() { | ||
for (var _len5 = arguments.length, args = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) { | ||
args[_key5] = arguments[_key5]; | ||
} | ||
log.info.apply(null, prepareLine("I", args)); | ||
} | ||
warn() { | ||
for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { | ||
args[_key4] = arguments[_key4]; | ||
log.error.apply(null, prepareLine("E", args)); | ||
} | ||
}]); | ||
log.warn.apply(null, prepareLine("W", args)); | ||
} | ||
return Logger; | ||
}(); | ||
error() { | ||
for (var _len5 = arguments.length, args = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) { | ||
args[_key5] = arguments[_key5]; | ||
} | ||
var logInstance = new Logger(); | ||
log.error.apply(null, prepareLine("E", args)); | ||
} | ||
function _createSuper$2(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$2(); return function _createSuperInternal() { var Super = _getPrototypeOf__default['default'](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default['default'](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default['default'](this, result); }; } | ||
} | ||
function _isNativeReflectConstruct$2() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } | ||
var logInstance = new Logger(); | ||
var RegistrationState = function RegistrationState() { | ||
var token = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ""; | ||
var notificationId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ""; | ||
var messageTypes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : new Set(); | ||
class RegistrationState { | ||
constructor() { | ||
var token = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ""; | ||
var notificationId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ""; | ||
var messageTypes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : new Set(); | ||
this.token = token; | ||
this.notificationId = notificationId; | ||
this.messageTypes = messageTypes; | ||
} | ||
_classCallCheck__default['default'](this, RegistrationState); | ||
} | ||
this.token = token; | ||
this.notificationId = notificationId; | ||
this.messageTypes = messageTypes; | ||
}; | ||
function setDifference(a, b) { | ||
return [...[...a].filter(x => !b.has(x)), ...[...b].filter(x => !a.has(x))]; | ||
return [].concat(_toConsumableArray__default['default'](_toConsumableArray__default['default'](a).filter(function (x) { | ||
return !b.has(x); | ||
})), _toConsumableArray__default['default'](_toConsumableArray__default['default'](b).filter(function (x) { | ||
return !a.has(x); | ||
}))); | ||
} | ||
@@ -670,14 +699,23 @@ | ||
class Connector extends EventEmitter { | ||
var Connector = /*#__PURE__*/function (_EventEmitter) { | ||
_inherits__default['default'](Connector, _EventEmitter); | ||
var _super = _createSuper$2(Connector); | ||
// @todo replace with FSM | ||
constructor(channelType) { | ||
super(); | ||
function Connector(channelType) { | ||
var _this; | ||
_defineProperty__default['default'](this, "desiredState", new RegistrationState()); | ||
_classCallCheck__default['default'](this, Connector); | ||
_defineProperty__default['default'](this, "currentState", new RegistrationState()); | ||
_this = _super.call(this); | ||
_defineProperty__default['default'](this, "_hasActiveAttempt", false); | ||
_defineProperty__default['default'](_assertThisInitialized__default['default'](_this), "desiredState", new RegistrationState()); | ||
this.channelType = channelType; | ||
_defineProperty__default['default'](_assertThisInitialized__default['default'](_this), "currentState", new RegistrationState()); | ||
_defineProperty__default['default'](_assertThisInitialized__default['default'](_this), "_hasActiveAttempt", false); | ||
_this.channelType = channelType; | ||
return _this; | ||
} | ||
@@ -691,130 +729,142 @@ /** | ||
setNotificationId(notificationId) { | ||
this.desiredState.notificationId = notificationId; | ||
} | ||
_createClass__default['default'](Connector, [{ | ||
key: "setNotificationId", | ||
value: function setNotificationId(notificationId) { | ||
this.desiredState.notificationId = notificationId; | ||
} | ||
}, { | ||
key: "subscribe", | ||
value: function subscribe(messageType) { | ||
if (this.desiredState.messageTypes.has(messageType)) { | ||
logInstance.debug("message type '".concat(messageType, "' for channel ").concat(this.channelType, " is already registered")); | ||
return; | ||
} | ||
subscribe(messageType) { | ||
if (this.desiredState.messageTypes.has(messageType)) { | ||
logInstance.debug("message type '".concat(messageType, "' for channel ").concat(this.channelType, " is already registered")); | ||
return; | ||
this.desiredState.messageTypes.add(messageType); | ||
} | ||
}, { | ||
key: "unsubscribe", | ||
value: function unsubscribe(messageType) { | ||
if (!this.desiredState.messageTypes.has(messageType)) { | ||
return; | ||
} | ||
this.desiredState.messageTypes.add(messageType); | ||
} | ||
unsubscribe(messageType) { | ||
if (!this.desiredState.messageTypes.has(messageType)) { | ||
return; | ||
this.desiredState.messageTypes.delete(messageType); | ||
} | ||
}, { | ||
key: "updateToken", | ||
value: function updateToken(token) { | ||
// @todo not entirely correct? | ||
this.desiredState.token = token; | ||
} | ||
/** | ||
* Perform actual registration after all required changes are settled. | ||
*/ | ||
this.desiredState.messageTypes.delete(messageType); | ||
} | ||
}, { | ||
key: "commitChanges", | ||
value: function () { | ||
var _commitChanges = _asyncToGenerator__default['default']( /*#__PURE__*/_regeneratorRuntime__default['default'].mark(function _callee() { | ||
var _hasDifference, _hasDifference2, needToUpdate, reasons, stateToPersist, persistedState; | ||
updateToken(token) { | ||
// @todo not entirely correct? | ||
this.desiredState.token = token; | ||
} | ||
/** | ||
* Perform actual registration after all required changes are settled. | ||
*/ | ||
return _regeneratorRuntime__default['default'].wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
if (!this._hasActiveAttempt) { | ||
_context.next = 3; | ||
break; | ||
} | ||
// Concurrent access violation | ||
logInstance.error("One registration attempt is already in progress"); | ||
throw new Error("One registration attempt is already in progress"); | ||
commitChanges() { | ||
var _this = this; | ||
case 3: | ||
_hasDifference = hasDifference(this.desiredState, this.currentState), _hasDifference2 = _slicedToArray__default['default'](_hasDifference, 2), needToUpdate = _hasDifference2[0], reasons = _hasDifference2[1]; | ||
return _asyncToGenerator__default['default']( /*#__PURE__*/_regeneratorRuntime__default['default'].mark(function _callee() { | ||
var _hasDifference, _hasDifference2, needToUpdate, reasons, stateToPersist, persistedState; | ||
if (needToUpdate) { | ||
_context.next = 6; | ||
break; | ||
} | ||
return _regeneratorRuntime__default['default'].wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
if (!_this._hasActiveAttempt) { | ||
_context.next = 3; | ||
break; | ||
} | ||
return _context.abrupt("return"); | ||
// Concurrent access violation | ||
logInstance.error("One registration attempt is already in progress"); | ||
throw new Error("One registration attempt is already in progress"); | ||
case 6: | ||
if (!this.currentState.notificationId) { | ||
reasons.delete("notificationId"); | ||
} | ||
case 3: | ||
_hasDifference = hasDifference(_this.desiredState, _this.currentState), _hasDifference2 = _slicedToArray__default['default'](_hasDifference, 2), needToUpdate = _hasDifference2[0], reasons = _hasDifference2[1]; | ||
logInstance.trace("Persisting ".concat(this.channelType, " registration"), reasons, this.desiredState); | ||
_context.prev = 8; | ||
this._hasActiveAttempt = true; | ||
stateToPersist = new RegistrationState(); | ||
stateToPersist.token = this.desiredState.token; | ||
stateToPersist.notificationId = this.desiredState.notificationId; | ||
stateToPersist.messageTypes = new Set(this.desiredState.messageTypes); | ||
if (needToUpdate) { | ||
_context.next = 6; | ||
break; | ||
} | ||
if (!(stateToPersist.messageTypes.size > 0)) { | ||
_context.next = 24; | ||
break; | ||
} | ||
return _context.abrupt("return"); | ||
_context.next = 17; | ||
return this.updateRegistration(stateToPersist, reasons); | ||
case 6: | ||
if (!_this.currentState.notificationId) { | ||
reasons.delete("notificationId"); | ||
} | ||
case 17: | ||
persistedState = _context.sent; | ||
this.currentState.token = persistedState.token; | ||
this.currentState.notificationId = persistedState.notificationId; | ||
this.currentState.messageTypes = new Set(persistedState.messageTypes); // @todo twilsock emits registered(notificationContextId) when this context is reg'd | ||
logInstance.trace("Persisting ".concat(_this.channelType, " registration"), reasons, _this.desiredState); | ||
_context.prev = 8; | ||
_this._hasActiveAttempt = true; | ||
stateToPersist = new RegistrationState(); | ||
stateToPersist.token = _this.desiredState.token; | ||
stateToPersist.notificationId = _this.desiredState.notificationId; | ||
stateToPersist.messageTypes = new Set(_this.desiredState.messageTypes); | ||
if (!(stateToPersist.messageTypes.size > 0)) { | ||
_context.next = 24; | ||
this.emit("stateChanged", this.channelType, "registered", this.currentState); | ||
_context.next = 30; | ||
break; | ||
} | ||
_context.next = 17; | ||
return _this.updateRegistration(stateToPersist, reasons); | ||
case 24: | ||
_context.next = 26; | ||
return this.removeRegistration(); | ||
case 17: | ||
persistedState = _context.sent; | ||
_this.currentState.token = persistedState.token; | ||
_this.currentState.notificationId = persistedState.notificationId; | ||
_this.currentState.messageTypes = new Set(persistedState.messageTypes); // @todo twilsock emits registered(notificationContextId) when this context is reg'd | ||
case 26: | ||
this.currentState.token = stateToPersist.token; | ||
this.currentState.notificationId = stateToPersist.notificationId; | ||
this.currentState.messageTypes.clear(); | ||
this.emit("stateChanged", this.channelType, "unregistered", this.currentState); | ||
_this.emit("stateChanged", _this.channelType, "registered", _this.currentState); | ||
case 30: | ||
_context.next = 35; | ||
break; | ||
_context.next = 30; | ||
break; | ||
case 32: | ||
_context.prev = 32; | ||
_context.t0 = _context["catch"](8); | ||
throw _context.t0; | ||
case 24: | ||
_context.next = 26; | ||
return _this.removeRegistration(); | ||
case 35: | ||
_context.prev = 35; | ||
this._hasActiveAttempt = false; | ||
return _context.finish(35); | ||
case 26: | ||
_this.currentState.token = stateToPersist.token; | ||
_this.currentState.notificationId = stateToPersist.notificationId; | ||
case 38: | ||
case "end": | ||
return _context.stop(); | ||
} | ||
} | ||
}, _callee, this, [[8, 32, 35, 38]]); | ||
})); | ||
_this.currentState.messageTypes.clear(); | ||
function commitChanges() { | ||
return _commitChanges.apply(this, arguments); | ||
} | ||
_this.emit("stateChanged", _this.channelType, "unregistered", _this.currentState); | ||
return commitChanges; | ||
}() | ||
}]); | ||
case 30: | ||
_context.next = 35; | ||
break; | ||
return Connector; | ||
}(EventEmitter); | ||
case 32: | ||
_context.prev = 32; | ||
_context.t0 = _context["catch"](8); | ||
throw _context.t0; | ||
function _createSuper$1(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$1(); return function _createSuperInternal() { var Super = _getPrototypeOf__default['default'](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default['default'](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default['default'](this, result); }; } | ||
case 35: | ||
_context.prev = 35; | ||
_this._hasActiveAttempt = false; | ||
return _context.finish(35); | ||
case 38: | ||
case "end": | ||
return _context.stop(); | ||
} | ||
} | ||
}, _callee, null, [[8, 32, 35, 38]]); | ||
}))(); | ||
} | ||
} | ||
function _isNativeReflectConstruct$1() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } | ||
var retrierConfig = { | ||
@@ -830,3 +880,7 @@ min: 2000, | ||
class RegistrarConnector extends Connector { | ||
var RegistrarConnector = /*#__PURE__*/function (_Connector) { | ||
_inherits__default['default'](RegistrarConnector, _Connector); | ||
var _super = _createSuper$1(RegistrarConnector); | ||
/** | ||
@@ -840,495 +894,229 @@ * Creates new instance of the ERS registrar | ||
*/ | ||
constructor(channelType, context, // context is separate from config because it's not shared with other connectors | ||
function RegistrarConnector(channelType, context, // context is separate from config because it's not shared with other connectors | ||
twilsock, registrarUrl) { | ||
super(channelType); | ||
var _this; | ||
_defineProperty__default['default'](this, "registrationId", null); | ||
_classCallCheck__default['default'](this, RegistrarConnector); | ||
this.context = context; | ||
this.twilsock = twilsock; | ||
this.registrarUrl = registrarUrl; | ||
} | ||
_this = _super.call(this, channelType); | ||
updateRegistration(registration, reasons) { | ||
var _this = this; | ||
_defineProperty__default['default'](_assertThisInitialized__default['default'](_this), "registrationId", null); | ||
return _asyncToGenerator__default['default']( /*#__PURE__*/_regeneratorRuntime__default['default'].mark(function _callee() { | ||
var registrarRequest, url, headers, response; | ||
return _regeneratorRuntime__default['default'].wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
if (!reasons.has("notificationId")) { | ||
_context.next = 3; | ||
break; | ||
} | ||
_context.next = 3; | ||
return _this.removeRegistration(); | ||
case 3: | ||
if (!(!registration.notificationId || !registration.notificationId.length)) { | ||
_context.next = 6; | ||
break; | ||
} | ||
logInstance.error("No push notification ID for registration"); | ||
throw new Error("No push notification ID for registration"); | ||
case 6: | ||
logInstance.trace("Registering", _this.channelType, registration); | ||
registrarRequest = { | ||
endpoint_platform: _this.context.platform, | ||
channel_type: _this.channelType, | ||
version: _this.context.protocolVersion.toString(), | ||
message_types: Array.from(registration.messageTypes), | ||
data: { | ||
registration_id: registration.notificationId | ||
} //ttl: 'PT24H' - This is totally ignored by notify, all bindings use PT1Y ttl. | ||
}; | ||
url = "".concat(_this.registrarUrl, "?productId=").concat(_this.context.productId); | ||
headers = { | ||
"Content-Type": "application/json" // 'X-Twilio-Token': registration.token | ||
}; | ||
logInstance.trace("Creating registration for channel ".concat(_this.channelType)); | ||
_context.prev = 11; | ||
_context.next = 14; | ||
return new operationRetrier.AsyncRetrier(retrierConfig).run(() => _this.twilsock.post(url, headers, registrarRequest)); | ||
case 14: | ||
response = _context.sent; | ||
_this.registrationId = response.body.id; | ||
logInstance.debug("Registration created: ", response); | ||
_context.next = 23; | ||
break; | ||
case 19: | ||
_context.prev = 19; | ||
_context.t0 = _context["catch"](11); | ||
logInstance.error("Registration failed: ", _context.t0); | ||
throw _context.t0; | ||
case 23: | ||
return _context.abrupt("return", registration); | ||
case 24: | ||
case "end": | ||
return _context.stop(); | ||
} | ||
} | ||
}, _callee, null, [[11, 19]]); | ||
}))(); | ||
_this.context = context; | ||
_this.twilsock = twilsock; | ||
_this.registrarUrl = registrarUrl; | ||
return _this; | ||
} | ||
removeRegistration() { | ||
var _this2 = this; | ||
_createClass__default['default'](RegistrarConnector, [{ | ||
key: "updateRegistration", | ||
value: function () { | ||
var _updateRegistration = _asyncToGenerator__default['default']( /*#__PURE__*/_regeneratorRuntime__default['default'].mark(function _callee(registration, reasons) { | ||
var _this2 = this; | ||
return _asyncToGenerator__default['default']( /*#__PURE__*/_regeneratorRuntime__default['default'].mark(function _callee2() { | ||
var url, headers; | ||
return _regeneratorRuntime__default['default'].wrap(function _callee2$(_context2) { | ||
while (1) { | ||
switch (_context2.prev = _context2.next) { | ||
case 0: | ||
if (_this2.registrationId) { | ||
_context2.next = 2; | ||
break; | ||
} | ||
var registrarRequest, url, headers, response; | ||
return _regeneratorRuntime__default['default'].wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
if (!reasons.has("notificationId")) { | ||
_context.next = 3; | ||
break; | ||
} | ||
return _context2.abrupt("return"); | ||
_context.next = 3; | ||
return this.removeRegistration(); | ||
case 2: | ||
url = "".concat(_this2.registrarUrl, "/").concat(_this2.registrationId, "?productId=").concat(_this2.context.productId); | ||
headers = { | ||
"Content-Type": "application/json" // 'X-Twilio-Token': this.config.token | ||
case 3: | ||
if (!(!registration.notificationId || !registration.notificationId.length)) { | ||
_context.next = 6; | ||
break; | ||
} | ||
}; | ||
logInstance.trace("Removing registration for ".concat(_this2.channelType)); | ||
_context2.prev = 5; | ||
_context2.next = 8; | ||
return new operationRetrier.AsyncRetrier(Object.assign(retrierConfig, { | ||
maxAttemptsCount: 3 | ||
})).run(() => _this2.twilsock.delete(url, headers)); | ||
logInstance.error("No push notification ID for registration"); | ||
throw new Error("No push notification ID for registration"); | ||
case 8: | ||
logInstance.debug("Registration removed for ".concat(_this2.channelType)); | ||
_context2.next = 15; | ||
break; | ||
case 6: | ||
logInstance.trace("Registering", this.channelType, registration); | ||
registrarRequest = { | ||
endpoint_platform: this.context.platform, | ||
channel_type: this.channelType, | ||
version: this.context.protocolVersion.toString(), | ||
message_types: Array.from(registration.messageTypes), | ||
data: { | ||
registration_id: registration.notificationId | ||
} //ttl: 'PT24H' - This is totally ignored by notify, all bindings use PT1Y ttl. | ||
case 11: | ||
_context2.prev = 11; | ||
_context2.t0 = _context2["catch"](5); | ||
logInstance.error("Failed to remove registration ", _this2.channelType, _context2.t0); | ||
throw _context2.t0; | ||
}; | ||
url = "".concat(this.registrarUrl, "?productId=").concat(this.context.productId); | ||
headers = { | ||
"Content-Type": "application/json" // 'X-Twilio-Token': registration.token | ||
case 15: | ||
case "end": | ||
return _context2.stop(); | ||
} | ||
} | ||
}, _callee2, null, [[5, 11]]); | ||
}))(); | ||
} | ||
}; | ||
logInstance.trace("Creating registration for channel ".concat(this.channelType)); | ||
_context.prev = 11; | ||
_context.next = 14; | ||
return new operationRetrier.AsyncRetrier(retrierConfig).run(function () { | ||
return _this2.twilsock.post(url, headers, registrarRequest); | ||
}); | ||
sendDeviceRemoveRequest(registrationId) { | ||
var _this3 = this; | ||
return _asyncToGenerator__default['default']( /*#__PURE__*/_regeneratorRuntime__default['default'].mark(function _callee3() { | ||
var url, headers, payload; | ||
return _regeneratorRuntime__default['default'].wrap(function _callee3$(_context3) { | ||
while (1) { | ||
switch (_context3.prev = _context3.next) { | ||
case 0: | ||
if (!(registrationId === "")) { | ||
_context3.next = 2; | ||
case 14: | ||
response = _context.sent; | ||
this.registrationId = response.body.id; | ||
logInstance.debug("Registration created: ", response); | ||
_context.next = 23; | ||
break; | ||
} | ||
throw new Error("Empty registration ID"); | ||
case 19: | ||
_context.prev = 19; | ||
_context.t0 = _context["catch"](11); | ||
logInstance.error("Registration failed: ", _context.t0); | ||
throw _context.t0; | ||
case 2: | ||
url = "".concat(_this3.registrarUrl, "?productId=").concat(_this3.context.productId); | ||
headers = { | ||
"Content-Type": "application/json" // @todo Content-Length?? | ||
case 23: | ||
return _context.abrupt("return", registration); | ||
}; | ||
payload = { | ||
binding_type: _this3.channelType, | ||
address: registrationId | ||
}; | ||
_context3.prev = 5; | ||
logInstance.trace("Removing old registrations for ".concat(_this3.channelType)); | ||
_context3.next = 9; | ||
return new operationRetrier.AsyncRetrier(Object.assign(retrierConfig, { | ||
maxAttemptsCount: 3 | ||
})).run(() => _this3.twilsock.delete(url, headers, payload)); | ||
case 9: | ||
logInstance.debug("Registration removed for ".concat(_this3.channelType)); | ||
_context3.next = 16; | ||
break; | ||
case 12: | ||
_context3.prev = 12; | ||
_context3.t0 = _context3["catch"](5); | ||
logInstance.error("Failed to remove registration ", _this3.channelType, _context3.t0); | ||
throw _context3.t0; | ||
case 16: | ||
case "end": | ||
return _context3.stop(); | ||
case 24: | ||
case "end": | ||
return _context.stop(); | ||
} | ||
} | ||
} | ||
}, _callee3, null, [[5, 12]]); | ||
}))(); | ||
} | ||
}, _callee, this, [[11, 19]]); | ||
})); | ||
} | ||
function updateRegistration(_x, _x2) { | ||
return _updateRegistration.apply(this, arguments); | ||
} | ||
var rngBrowser = {exports: {}}; | ||
return updateRegistration; | ||
}() | ||
}, { | ||
key: "removeRegistration", | ||
value: function () { | ||
var _removeRegistration = _asyncToGenerator__default['default']( /*#__PURE__*/_regeneratorRuntime__default['default'].mark(function _callee2() { | ||
var _this3 = this; | ||
// browser this is a little complicated due to unknown quality of Math.random() | ||
// and inconsistent support for the `crypto` API. We do the best we can via | ||
// feature-detection | ||
// getRandomValues needs to be invoked in a context where "this" is a Crypto | ||
// implementation. Also, find the complete implementation of crypto on IE11. | ||
var url, headers; | ||
return _regeneratorRuntime__default['default'].wrap(function _callee2$(_context2) { | ||
while (1) { | ||
switch (_context2.prev = _context2.next) { | ||
case 0: | ||
if (this.registrationId) { | ||
_context2.next = 2; | ||
break; | ||
} | ||
var getRandomValues = typeof crypto != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto) || typeof msCrypto != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto); | ||
return _context2.abrupt("return"); | ||
if (getRandomValues) { | ||
// WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto | ||
var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef | ||
case 2: | ||
url = "".concat(this.registrarUrl, "/").concat(this.registrationId, "?productId=").concat(this.context.productId); | ||
headers = { | ||
"Content-Type": "application/json" // 'X-Twilio-Token': this.config.token | ||
rngBrowser.exports = function whatwgRNG() { | ||
getRandomValues(rnds8); | ||
return rnds8; | ||
}; | ||
} else { | ||
// Math.random()-based (RNG) | ||
// | ||
// If all else fails, use Math.random(). It's fast, but is of unspecified | ||
// quality. | ||
var rnds = new Array(16); | ||
}; | ||
logInstance.trace("Removing registration for ".concat(this.channelType)); | ||
_context2.prev = 5; | ||
_context2.next = 8; | ||
return new operationRetrier.AsyncRetrier(Object.assign(retrierConfig, { | ||
maxAttemptsCount: 3 | ||
})).run(function () { | ||
return _this3.twilsock.delete(url, headers); | ||
}); | ||
rngBrowser.exports = function mathRNG() { | ||
for (var i = 0, r; i < 16; i++) { | ||
if ((i & 0x03) === 0) r = Math.random() * 0x100000000; | ||
rnds[i] = r >>> ((i & 0x03) << 3) & 0xff; | ||
} | ||
case 8: | ||
logInstance.debug("Registration removed for ".concat(this.channelType)); | ||
_context2.next = 15; | ||
break; | ||
return rnds; | ||
}; | ||
} | ||
case 11: | ||
_context2.prev = 11; | ||
_context2.t0 = _context2["catch"](5); | ||
logInstance.error("Failed to remove registration ", this.channelType, _context2.t0); | ||
throw _context2.t0; | ||
/** | ||
* Convert array of 16 byte values to UUID string format of the form: | ||
* XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX | ||
*/ | ||
var byteToHex = []; | ||
case 15: | ||
case "end": | ||
return _context2.stop(); | ||
} | ||
} | ||
}, _callee2, this, [[5, 11]]); | ||
})); | ||
for (var i = 0; i < 256; ++i) { | ||
byteToHex[i] = (i + 0x100).toString(16).substr(1); | ||
} | ||
function removeRegistration() { | ||
return _removeRegistration.apply(this, arguments); | ||
} | ||
function bytesToUuid$2(buf, offset) { | ||
var i = offset || 0; | ||
var bth = byteToHex; // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4 | ||
return removeRegistration; | ||
}() | ||
}, { | ||
key: "sendDeviceRemoveRequest", | ||
value: function () { | ||
var _sendDeviceRemoveRequest = _asyncToGenerator__default['default']( /*#__PURE__*/_regeneratorRuntime__default['default'].mark(function _callee3(registrationId) { | ||
var _this4 = this; | ||
return [bth[buf[i++]], bth[buf[i++]], bth[buf[i++]], bth[buf[i++]], '-', bth[buf[i++]], bth[buf[i++]], '-', bth[buf[i++]], bth[buf[i++]], '-', bth[buf[i++]], bth[buf[i++]], '-', bth[buf[i++]], bth[buf[i++]], bth[buf[i++]], bth[buf[i++]], bth[buf[i++]], bth[buf[i++]]].join(''); | ||
} | ||
var url, headers, payload; | ||
return _regeneratorRuntime__default['default'].wrap(function _callee3$(_context3) { | ||
while (1) { | ||
switch (_context3.prev = _context3.next) { | ||
case 0: | ||
if (!(registrationId === "")) { | ||
_context3.next = 2; | ||
break; | ||
} | ||
var bytesToUuid_1 = bytesToUuid$2; | ||
throw new Error("Empty registration ID"); | ||
var rng$1 = rngBrowser.exports; | ||
var bytesToUuid$1 = bytesToUuid_1; // **`v1()` - Generate time-based UUID** | ||
// | ||
// Inspired by https://github.com/LiosK/UUID.js | ||
// and http://docs.python.org/library/uuid.html | ||
case 2: | ||
url = "".concat(this.registrarUrl, "?productId=").concat(this.context.productId); | ||
headers = { | ||
"Content-Type": "application/json" // @todo Content-Length?? | ||
var _nodeId; | ||
}; | ||
payload = { | ||
binding_type: this.channelType, | ||
address: registrationId | ||
}; | ||
_context3.prev = 5; | ||
logInstance.trace("Removing old registrations for ".concat(this.channelType)); | ||
_context3.next = 9; | ||
return new operationRetrier.AsyncRetrier(Object.assign(retrierConfig, { | ||
maxAttemptsCount: 3 | ||
})).run(function () { | ||
return _this4.twilsock.delete(url, headers, payload); | ||
}); | ||
var _clockseq; // Previous uuid creation time | ||
var _lastMSecs = 0; | ||
var _lastNSecs = 0; // See https://github.com/uuidjs/uuid for API details | ||
function v1$1(options, buf, offset) { | ||
var i = buf && offset || 0; | ||
var b = buf || []; | ||
options = options || {}; | ||
var node = options.node || _nodeId; | ||
var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; // node and clockseq need to be initialized to random values if they're not | ||
// specified. We do this lazily to minimize issues related to insufficient | ||
// system entropy. See #189 | ||
if (node == null || clockseq == null) { | ||
var seedBytes = rng$1(); | ||
if (node == null) { | ||
// Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) | ||
node = _nodeId = [seedBytes[0] | 0x01, seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]]; | ||
} | ||
if (clockseq == null) { | ||
// Per 4.2.2, randomize (14 bit) clockseq | ||
clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff; | ||
} | ||
} // UUID timestamps are 100 nano-second units since the Gregorian epoch, | ||
// (1582-10-15 00:00). JSNumbers aren't precise enough for this, so | ||
// time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' | ||
// (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. | ||
var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime(); // Per 4.2.1.2, use count of uuid's generated during the current clock | ||
// cycle to simulate higher resolution clock | ||
var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; // Time since last uuid creation (in msecs) | ||
var dt = msecs - _lastMSecs + (nsecs - _lastNSecs) / 10000; // Per 4.2.1.2, Bump clockseq on clock regression | ||
if (dt < 0 && options.clockseq === undefined) { | ||
clockseq = clockseq + 1 & 0x3fff; | ||
} // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new | ||
// time interval | ||
if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) { | ||
nsecs = 0; | ||
} // Per 4.2.1.2 Throw error if too many uuids are requested | ||
if (nsecs >= 10000) { | ||
throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec'); | ||
} | ||
_lastMSecs = msecs; | ||
_lastNSecs = nsecs; | ||
_clockseq = clockseq; // Per 4.1.4 - Convert from unix epoch to Gregorian epoch | ||
msecs += 12219292800000; // `time_low` | ||
var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; | ||
b[i++] = tl >>> 24 & 0xff; | ||
b[i++] = tl >>> 16 & 0xff; | ||
b[i++] = tl >>> 8 & 0xff; | ||
b[i++] = tl & 0xff; // `time_mid` | ||
var tmh = msecs / 0x100000000 * 10000 & 0xfffffff; | ||
b[i++] = tmh >>> 8 & 0xff; | ||
b[i++] = tmh & 0xff; // `time_high_and_version` | ||
b[i++] = tmh >>> 24 & 0xf | 0x10; // include version | ||
b[i++] = tmh >>> 16 & 0xff; // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) | ||
b[i++] = clockseq >>> 8 | 0x80; // `clock_seq_low` | ||
b[i++] = clockseq & 0xff; // `node` | ||
for (var n = 0; n < 6; ++n) { | ||
b[i + n] = node[n]; | ||
} | ||
return buf ? buf : bytesToUuid$1(b); | ||
} | ||
var v1_1 = v1$1; | ||
var rng = rngBrowser.exports; | ||
var bytesToUuid = bytesToUuid_1; | ||
function v4$1(options, buf, offset) { | ||
var i = buf && offset || 0; | ||
if (typeof options == 'string') { | ||
buf = options === 'binary' ? new Array(16) : null; | ||
options = null; | ||
} | ||
options = options || {}; | ||
var rnds = options.random || (options.rng || rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` | ||
rnds[6] = rnds[6] & 0x0f | 0x40; | ||
rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided | ||
if (buf) { | ||
for (var ii = 0; ii < 16; ++ii) { | ||
buf[i + ii] = rnds[ii]; | ||
} | ||
} | ||
return buf || bytesToUuid(rnds); | ||
} | ||
var v4_1 = v4$1; | ||
var v1 = v1_1; | ||
var v4 = v4_1; | ||
var uuid = v4; | ||
uuid.v1 = v1; | ||
uuid.v4 = v4; | ||
var uuid_1 = uuid; | ||
/** | ||
* Registrar connector implementation for twilsock -- @todo Drop twilsock.connector COMPLETELY?! | ||
*/ | ||
class TwilsockConnector extends Connector { | ||
/** | ||
* Create twilsock registration connector. | ||
* @param productId product ID | ||
* @param platform platform ID string | ||
* @param twilsock {TwilsockClient} connection transport. | ||
*/ | ||
constructor(productId, platform, twilsock) { | ||
super("twilsock"); | ||
_defineProperty__default['default'](this, "contextId", uuid_1.v4()); | ||
this.productId = productId; | ||
this.platform = platform; | ||
this.twilsock = twilsock; | ||
} | ||
updateRegistration(registration, reasons) { | ||
var _this = this; | ||
return _asyncToGenerator__default['default']( /*#__PURE__*/_regeneratorRuntime__default['default'].mark(function _callee() { | ||
var messageTypes, context; | ||
return _regeneratorRuntime__default['default'].wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
if (reasons.has("messageType")) { | ||
_context.next = 2; | ||
case 9: | ||
logInstance.debug("Registration removed for ".concat(this.channelType)); | ||
_context3.next = 16; | ||
break; | ||
} | ||
return _context.abrupt("return", registration); | ||
case 12: | ||
_context3.prev = 12; | ||
_context3.t0 = _context3["catch"](5); | ||
logInstance.error("Failed to remove registration ", this.channelType, _context3.t0); | ||
throw _context3.t0; | ||
case 2: | ||
messageTypes = Array.from(registration.messageTypes); | ||
context = { | ||
product_id: _this.productId, | ||
notification_protocol_version: 4, | ||
endpoint_platform: _this.platform, | ||
message_types: messageTypes | ||
}; | ||
_context.prev = 4; | ||
_context.next = 7; | ||
return _this.twilsock.setNotificationsContext(_this.contextId, context); | ||
case 7: | ||
_context.next = 13; | ||
break; | ||
case 9: | ||
_context.prev = 9; | ||
_context.t0 = _context["catch"](4); | ||
logInstance.error("Failed to update twilsock notification context: ".concat(_context.t0)); | ||
throw _context.t0; | ||
case 13: | ||
return _context.abrupt("return", registration); | ||
case 14: | ||
case "end": | ||
return _context.stop(); | ||
case 16: | ||
case "end": | ||
return _context3.stop(); | ||
} | ||
} | ||
} | ||
}, _callee, null, [[4, 9]]); | ||
}))(); | ||
} | ||
}, _callee3, this, [[5, 12]]); | ||
})); | ||
removeRegistration() { | ||
var _this2 = this; | ||
function sendDeviceRemoveRequest(_x3) { | ||
return _sendDeviceRemoveRequest.apply(this, arguments); | ||
} | ||
return _asyncToGenerator__default['default']( /*#__PURE__*/_regeneratorRuntime__default['default'].mark(function _callee2() { | ||
return _regeneratorRuntime__default['default'].wrap(function _callee2$(_context2) { | ||
while (1) { | ||
switch (_context2.prev = _context2.next) { | ||
case 0: | ||
_context2.prev = 0; | ||
_context2.next = 3; | ||
return _this2.twilsock.removeNotificationsContext(_this2.contextId); | ||
return sendDeviceRemoveRequest; | ||
}() | ||
}]); | ||
case 3: | ||
_context2.next = 9; | ||
break; | ||
return RegistrarConnector; | ||
}(Connector); | ||
case 5: | ||
_context2.prev = 5; | ||
_context2.t0 = _context2["catch"](0); | ||
logInstance.error("Failed to remove twilsock notification context: ".concat(_context2.t0)); | ||
throw _context2.t0; | ||
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf__default['default'](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default['default'](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default['default'](this, result); }; } | ||
case 9: | ||
case "end": | ||
return _context2.stop(); | ||
} | ||
} | ||
}, _callee2, null, [[0, 5]]); | ||
}))(); | ||
} // eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } | ||
sendDeviceRemoveRequest(registrationId) {// no need to do anything here, twilsock backend handles it on its own | ||
return _asyncToGenerator__default['default']( /*#__PURE__*/_regeneratorRuntime__default['default'].mark(function _callee3() { | ||
return _regeneratorRuntime__default['default'].wrap(function _callee3$(_context3) { | ||
while (1) { | ||
switch (_context3.prev = _context3.next) { | ||
case 0: | ||
case "end": | ||
return _context3.stop(); | ||
} | ||
} | ||
}, _callee3); | ||
}))(); | ||
} | ||
} | ||
var Client_1; | ||
@@ -1353,8 +1141,17 @@ | ||
exports.Notifications = Client_1 = class Client extends EventEmitter { | ||
constructor(token) { | ||
exports.Notifications = Client_1 = /*#__PURE__*/function (_EventEmitter) { | ||
_inherits__default['default'](Client, _EventEmitter); | ||
var _super = _createSuper(Client); | ||
function Client(token) { | ||
var _options$logLevel, _options$productId, _options$twilsockClie, _options$notification, _ref, _config$region; | ||
var _this; | ||
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
super(); | ||
_classCallCheck__default['default'](this, Client); | ||
_this = _super.call(this); | ||
options.logLevel = (_options$logLevel = options.logLevel) !== null && _options$logLevel !== void 0 ? _options$logLevel : "error"; | ||
@@ -1369,253 +1166,298 @@ logInstance.setLevel(options.logLevel); | ||
var registrarUrl = config.ersUrl || defaultUrl; | ||
this.connectors = new Map(); | ||
_this.connectors = new Map(); | ||
var platform = Client_1._detectPlatform(); | ||
this.connectors.set("apn", new RegistrarConnector("apn", { | ||
_this.connectors.set("apn", new RegistrarConnector("apn", { | ||
protocolVersion: 4, | ||
productId, | ||
platform | ||
productId: productId, | ||
platform: platform | ||
}, twilsock$1, registrarUrl)); | ||
this.connectors.set("fcm", new RegistrarConnector("fcm", { | ||
_this.connectors.set("fcm", new RegistrarConnector("fcm", { | ||
protocolVersion: 3, | ||
productId, | ||
platform | ||
productId: productId, | ||
platform: platform | ||
}, twilsock$1, registrarUrl)); | ||
this.connectors.set("twilsock", new TwilsockConnector(productId, platform, twilsock$1)); | ||
twilsock$1.on("stateChanged", state => this.emit("transportState", state)); | ||
this._connector("twilsock").on("stateChanged", (type, value, state) => this.emit("stateChanged", type, value, state)); | ||
_this.connectors.set("twilsock", new twilsock_connector.TwilsockConnector(productId, platform, twilsock$1)); | ||
this._connector("apn").on("stateChanged", (type, value, state) => this.emit("stateChanged", type, value, state)); | ||
twilsock$1.on("stateChanged", function (state) { | ||
return _this.emit("transportState", state); | ||
}); | ||
this._connector("fcm").on("stateChanged", (type, value, state) => this.emit("stateChanged", type, value, state)); // Router | ||
_this._connector("twilsock").on("stateChanged", function (type, value, state) { | ||
return _this.emit("stateChanged", type, value, state); | ||
}); | ||
_this._connector("apn").on("stateChanged", function (type, value, state) { | ||
return _this.emit("stateChanged", type, value, state); | ||
}); | ||
twilsock$1.on("message", (type, message) => this._routeMessage(type, message)); | ||
this.updateToken(token); // Start only if we created twilsock locally, | ||
_this._connector("fcm").on("stateChanged", function (type, value, state) { | ||
return _this.emit("stateChanged", type, value, state); | ||
}); // Router | ||
twilsock$1.on("message", function (type, message) { | ||
return _this._routeMessage(type, message); | ||
}); | ||
_this.updateToken(token); // Start only if we created twilsock locally, | ||
// otherwise it's the responsibility of whoever created the Twilsock client. | ||
if (startTwilsock) { | ||
twilsock$1.connect(); | ||
this.twilsock = twilsock$1; | ||
_this.twilsock = twilsock$1; | ||
} | ||
return _this; | ||
} | ||
shutdown() { | ||
var _this = this; | ||
_createClass__default['default'](Client, [{ | ||
key: "shutdown", | ||
value: function () { | ||
var _shutdown = _asyncToGenerator__default['default']( /*#__PURE__*/_regeneratorRuntime__default['default'].mark(function _callee() { | ||
return _regeneratorRuntime__default['default'].wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
this.connectors.clear(); | ||
return _asyncToGenerator__default['default']( /*#__PURE__*/_regeneratorRuntime__default['default'].mark(function _callee() { | ||
return _regeneratorRuntime__default['default'].wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
_this.connectors.clear(); | ||
if (!this.twilsock) { | ||
_context.next = 4; | ||
break; | ||
} | ||
if (!_this.twilsock) { | ||
_context.next = 4; | ||
break; | ||
} | ||
return this.twilsock.disconnect(); | ||
_context.next = 4; | ||
return _this.twilsock.disconnect(); | ||
case 4: | ||
case "end": | ||
return _context.stop(); | ||
case 4: | ||
case "end": | ||
return _context.stop(); | ||
} | ||
} | ||
} | ||
}, _callee); | ||
}))(); | ||
} | ||
/** | ||
* Set OS-provided APNS/FCM registration binding for the given channel type. Not used for 'twilsock'. | ||
* | ||
* You must call this function once you've received the ID of your device from the underlying OS. | ||
* | ||
* @param {ChannelType} channelType Channel type ('apn'/'fcm'). | ||
* @param {string} pushRegistrationId Token received from FCM/APNS system on device. | ||
*/ | ||
}, _callee, this); | ||
})); | ||
function shutdown() { | ||
return _shutdown.apply(this, arguments); | ||
} | ||
setPushRegistrationId(channelType, pushRegistrationId) { | ||
logInstance.debug("Set ".concat(channelType, " push registration id '").concat(pushRegistrationId, "'")); | ||
return shutdown; | ||
}() | ||
/** | ||
* Set OS-provided APNS/FCM registration binding for the given channel type. Not used for 'twilsock'. | ||
* | ||
* You must call this function once you've received the ID of your device from the underlying OS. | ||
* | ||
* @param {ChannelType} channelType Channel type ('apn'/'fcm'). | ||
* @param {string} pushRegistrationId Token received from FCM/APNS system on device. | ||
*/ | ||
this._connector(channelType).setNotificationId(pushRegistrationId); | ||
} | ||
/** | ||
* Subscribe to a given message type for a given channel type. | ||
* | ||
* Creates a subscriptions to receive incoming messages according to message type. | ||
* Subscription establishes a binding and you will receive a signal when a notification | ||
* of this type has been received by the library. | ||
* | ||
* Subscribed binding is preserved for 1 year, after which time it needs to be re-subscribed. | ||
* This is the responsibility of the client SDK. | ||
* | ||
* @param {ChannelType} channelType Supported are 'twilsock', 'apn' and 'fcm' | ||
* @param {string} messageType The type of message that you want to receive | ||
*/ | ||
}, { | ||
key: "setPushRegistrationId", | ||
value: function setPushRegistrationId(channelType, pushRegistrationId) { | ||
logInstance.debug("Set ".concat(channelType, " push registration id '").concat(pushRegistrationId, "'")); | ||
this._connector(channelType).setNotificationId(pushRegistrationId); | ||
} | ||
/** | ||
* Subscribe to a given message type for a given channel type. | ||
* | ||
* Creates a subscriptions to receive incoming messages according to message type. | ||
* Subscription establishes a binding and you will receive a signal when a notification | ||
* of this type has been received by the library. | ||
* | ||
* Subscribed binding is preserved for 1 year, after which time it needs to be re-subscribed. | ||
* This is the responsibility of the client SDK. | ||
* | ||
* @param {ChannelType} channelType Supported are 'twilsock', 'apn' and 'fcm' | ||
* @param {string} messageType The type of message that you want to receive | ||
*/ | ||
subscribe(channelType, messageType) { | ||
logInstance.debug("Add ".concat(channelType, " subscriptions for message type ").concat(messageType)); | ||
}, { | ||
key: "subscribe", | ||
value: function subscribe(channelType, messageType) { | ||
logInstance.debug("Add ".concat(channelType, " subscriptions for message type ").concat(messageType)); | ||
this._connector(channelType).subscribe(messageType); | ||
} | ||
/** | ||
* Unsubscribe from a given message type. | ||
* | ||
* Unsubscribing breaks a binding and you will not receive more notifications for this message type. | ||
* Please note that you have to call commitChanges() and receive a successful result before | ||
* the subscription is actually removed. | ||
* | ||
* @param {ChannelType} channelType Supported are 'twilsock', 'apn' and 'fcm' | ||
* @param {string} messageType The type of message that you don't want to receive anymore | ||
*/ | ||
this._connector(channelType).subscribe(messageType); | ||
} | ||
/** | ||
* Unsubscribe from a given message type. | ||
* | ||
* Unsubscribing breaks a binding and you will not receive more notifications for this message type. | ||
* Please note that you have to call commitChanges() and receive a successful result before | ||
* the subscription is actually removed. | ||
* | ||
* @param {ChannelType} channelType Supported are 'twilsock', 'apn' and 'fcm' | ||
* @param {string} messageType The type of message that you don't want to receive anymore | ||
*/ | ||
}, { | ||
key: "unsubscribe", | ||
value: function unsubscribe(channelType, messageType) { | ||
logInstance.debug("Remove ".concat(channelType, " subscriptions for message type ").concat(messageType)); | ||
unsubscribe(channelType, messageType) { | ||
logInstance.debug("Remove ".concat(channelType, " subscriptions for message type ").concat(messageType)); | ||
this._connector(channelType).unsubscribe(messageType); | ||
} | ||
/** | ||
* Update subscription token. You must update the token when the old one expires. | ||
* | ||
* When you receive onTokenWillExpire event from twilsock, call this function with the new refreshed | ||
* token _after_ you have updated twilsock and other associated objects with the new token. | ||
* | ||
* @param {string} token Authentication token for registrations | ||
*/ | ||
this._connector(channelType).unsubscribe(messageType); | ||
} | ||
/** | ||
* Update subscription token. You must update the token when the old one expires. | ||
* | ||
* When you receive onTokenWillExpire event from twilsock, call this function with the new refreshed | ||
* token _after_ you have updated twilsock and other associated objects with the new token. | ||
* | ||
* @param {string} token Authentication token for registrations | ||
*/ | ||
}, { | ||
key: "updateToken", | ||
value: function updateToken(token) { | ||
this.connectors.forEach(function (connector) { | ||
return connector.updateToken(token); | ||
}); | ||
} | ||
/** | ||
* Commit all collected subscription changes as a batched update. This function tries to reduce | ||
* number of network calls necessary to update bindings status. | ||
*/ | ||
}, { | ||
key: "commitChanges", | ||
value: function () { | ||
var _commitChanges = _asyncToGenerator__default['default']( /*#__PURE__*/_regeneratorRuntime__default['default'].mark(function _callee2() { | ||
var promises; | ||
return _regeneratorRuntime__default['default'].wrap(function _callee2$(_context2) { | ||
while (1) { | ||
switch (_context2.prev = _context2.next) { | ||
case 0: | ||
promises = []; | ||
this.connectors.forEach(function (connector) { | ||
return promises.push(connector.commitChanges()); | ||
}); | ||
_context2.next = 4; | ||
return Promise.all(promises); | ||
updateToken(token) { | ||
this.connectors.forEach(connector => connector.updateToken(token)); | ||
} | ||
/** | ||
* Commit all collected subscription changes as a batched update. This function tries to reduce | ||
* number of network calls necessary to update bindings status. | ||
*/ | ||
commitChanges() { | ||
var _this2 = this; | ||
return _asyncToGenerator__default['default']( /*#__PURE__*/_regeneratorRuntime__default['default'].mark(function _callee2() { | ||
var promises; | ||
return _regeneratorRuntime__default['default'].wrap(function _callee2$(_context2) { | ||
while (1) { | ||
switch (_context2.prev = _context2.next) { | ||
case 0: | ||
promises = []; | ||
_this2.connectors.forEach(connector => promises.push(connector.commitChanges())); | ||
_context2.next = 4; | ||
return Promise.all(promises); | ||
case 4: | ||
case "end": | ||
return _context2.stop(); | ||
case 4: | ||
case "end": | ||
return _context2.stop(); | ||
} | ||
} | ||
} | ||
}, _callee2); | ||
}))(); | ||
} | ||
/** | ||
* Clear existing registrations directly using provided device token. | ||
* This is useful to ensure stopped subscriptions without resubscribing. | ||
* | ||
* This function goes completely beside the state machine and removes all registrations. | ||
* Use with caution: if it races with current state machine operations, madness will ensue. | ||
* | ||
* @param {ChannelType} channelType Channel type ('apn'/'fcm'). | ||
* @param {string} registrationId Token received from FCM/APNS system on device. | ||
*/ | ||
}, _callee2, this); | ||
})); | ||
function commitChanges() { | ||
return _commitChanges.apply(this, arguments); | ||
} | ||
removeRegistrations(channelType, registrationId) { | ||
var _this3 = this; | ||
return commitChanges; | ||
}() | ||
/** | ||
* Clear existing registrations directly using provided device token. | ||
* This is useful to ensure stopped subscriptions without resubscribing. | ||
* | ||
* This function goes completely beside the state machine and removes all registrations. | ||
* Use with caution: if it races with current state machine operations, madness will ensue. | ||
* | ||
* @param {ChannelType} channelType Channel type ('apn'/'fcm'). | ||
* @param {string} registrationId Token received from FCM/APNS system on device. | ||
*/ | ||
return _asyncToGenerator__default['default']( /*#__PURE__*/_regeneratorRuntime__default['default'].mark(function _callee3() { | ||
return _regeneratorRuntime__default['default'].wrap(function _callee3$(_context3) { | ||
while (1) { | ||
switch (_context3.prev = _context3.next) { | ||
case 0: | ||
_context3.next = 2; | ||
return _this3._connector(channelType).sendDeviceRemoveRequest(registrationId); | ||
}, { | ||
key: "removeRegistrations", | ||
value: function () { | ||
var _removeRegistrations = _asyncToGenerator__default['default']( /*#__PURE__*/_regeneratorRuntime__default['default'].mark(function _callee3(channelType, registrationId) { | ||
return _regeneratorRuntime__default['default'].wrap(function _callee3$(_context3) { | ||
while (1) { | ||
switch (_context3.prev = _context3.next) { | ||
case 0: | ||
_context3.next = 2; | ||
return this._connector(channelType).sendDeviceRemoveRequest(registrationId); | ||
case 2: | ||
case "end": | ||
return _context3.stop(); | ||
case 2: | ||
case "end": | ||
return _context3.stop(); | ||
} | ||
} | ||
} | ||
}, _callee3); | ||
}))(); | ||
} | ||
/** | ||
* Handle incoming push notification. | ||
* Client application should call this method when it receives push notifications and pass the received data. | ||
* @param {Object} message push message | ||
* @return {PushNotification} A reformatted payload with extracted message type. | ||
*/ | ||
}, _callee3, this); | ||
})); | ||
function removeRegistrations(_x, _x2) { | ||
return _removeRegistrations.apply(this, arguments); | ||
} | ||
handlePushNotification(message) { | ||
return { | ||
messageType: message.twi_message_type, | ||
payload: message.payload | ||
}; | ||
} | ||
/** | ||
* Routes messages to the external subscribers | ||
*/ | ||
return removeRegistrations; | ||
}() | ||
/** | ||
* Handle incoming push notification. | ||
* Client application should call this method when it receives push notifications and pass the received data. | ||
* @param {Object} message push message | ||
* @return {PushNotification} A reformatted payload with extracted message type. | ||
*/ | ||
}, { | ||
key: "handlePushNotification", | ||
value: function handlePushNotification(message) { | ||
return { | ||
messageType: message.twi_message_type, | ||
payload: message.payload | ||
}; | ||
} | ||
/** | ||
* Routes messages to the external subscribers | ||
*/ | ||
_routeMessage(type, message) { | ||
logInstance.debug("Notification message arrived: ", type, message); | ||
this.emit("message", type, message); | ||
} | ||
/** | ||
* @param {String} type Channel type | ||
* @throws {Error} Error with description | ||
*/ | ||
}, { | ||
key: "_routeMessage", | ||
value: function _routeMessage(type, message) { | ||
logInstance.debug("Notification message arrived: ", type, message); | ||
this.emit("message", type, message); | ||
} | ||
/** | ||
* @param {String} type Channel type | ||
* @throws {Error} Error with description | ||
*/ | ||
}, { | ||
key: "_connector", | ||
value: function _connector(type) { | ||
var connector = this.connectors.get(type); | ||
_connector(type) { | ||
var connector = this.connectors.get(type); | ||
if (!connector) { | ||
throw new Error("Unknown channel type: ".concat(type)); | ||
} | ||
if (!connector) { | ||
throw new Error("Unknown channel type: ".concat(type)); | ||
return connector; | ||
} | ||
/** | ||
* Returns platform string limited to max 128 chars | ||
*/ | ||
return connector; | ||
} | ||
/** | ||
* Returns platform string limited to max 128 chars | ||
*/ | ||
}], [{ | ||
key: "_detectPlatform", | ||
value: function _detectPlatform() { | ||
var platform = ""; | ||
if (typeof navigator !== "undefined") { | ||
platform = "unknown"; | ||
static _detectPlatform() { | ||
var platform = ""; | ||
if (typeof navigator.product !== "undefined") { | ||
platform = navigator.product; | ||
} | ||
if (typeof navigator !== "undefined") { | ||
platform = "unknown"; | ||
if (typeof navigator.product !== "undefined") { | ||
platform = navigator.product; | ||
if (typeof navigator.userAgent !== "undefined") { | ||
platform = navigator.userAgent; | ||
} | ||
} else { | ||
platform = "web"; | ||
} | ||
if (typeof navigator.userAgent !== "undefined") { | ||
platform = navigator.userAgent; | ||
} | ||
} else { | ||
platform = "web"; | ||
return platform.substring(0, 128); | ||
} | ||
}]); | ||
return platform.substring(0, 128); | ||
} | ||
return Client; | ||
}(EventEmitter); | ||
}; | ||
__decorate([declarativeTypeValidator.validateTypes(channelTypeRule, declarativeTypeValidator.nonEmptyString), __metadata("design:type", Function), __metadata("design:paramtypes", [String, String]), __metadata("design:returntype", void 0)], exports.Notifications.prototype, "setPushRegistrationId", null); | ||
@@ -1622,0 +1464,0 @@ |
import { EventEmitter } from "events"; | ||
import { TwilsockClient, ConnectionState } from "@twilio/twilsock"; | ||
import { TwilsockClient, ConnectionState } from "twilsock"; | ||
import { LogLevelDesc } from "loglevel"; | ||
@@ -4,0 +4,0 @@ type ChannelType = "twilsock" | "apn" | "fcm"; |
1439
dist/lib.js
@@ -30,11 +30,22 @@ /* | ||
require('core-js/modules/es.reflect.construct.js'); | ||
var _asyncToGenerator = require('@babel/runtime/helpers/asyncToGenerator'); | ||
var _classCallCheck = require('@babel/runtime/helpers/classCallCheck'); | ||
var _createClass = require('@babel/runtime/helpers/createClass'); | ||
var _inherits = require('@babel/runtime/helpers/inherits'); | ||
var _possibleConstructorReturn = require('@babel/runtime/helpers/possibleConstructorReturn'); | ||
var _getPrototypeOf = require('@babel/runtime/helpers/getPrototypeOf'); | ||
var _regeneratorRuntime = require('@babel/runtime/regenerator'); | ||
require('core-js/modules/es.array.iterator.js'); | ||
require('core-js/modules/es.map.js'); | ||
require('core-js/modules/es.object.to-string.js'); | ||
require('core-js/modules/es.string.iterator.js'); | ||
require('core-js/modules/web.dom-collections.iterator.js'); | ||
require('core-js/modules/es.array.concat.js'); | ||
require('core-js/modules/web.dom-collections.for-each.js'); | ||
require('core-js/modules/es.promise.js'); | ||
var _typeof = require('@babel/runtime/helpers/typeof'); | ||
var events = require('events'); | ||
var twilsock = require('@twilio/twilsock'); | ||
var twilsock = require('twilsock'); | ||
var _assertThisInitialized = require('@babel/runtime/helpers/assertThisInitialized'); | ||
var _defineProperty = require('@babel/runtime/helpers/defineProperty'); | ||
@@ -46,5 +57,7 @@ require('core-js/modules/es.regexp.to-string.js'); | ||
var _slicedToArray = require('@babel/runtime/helpers/slicedToArray'); | ||
var _toConsumableArray = require('@babel/runtime/helpers/toConsumableArray'); | ||
require('core-js/modules/es.set.js'); | ||
require('core-js/modules/es.array.filter.js'); | ||
var logger = require('loglevel'); | ||
var require$$0 = require('crypto'); | ||
var twilsock_connector = require('./twilsock.connector'); | ||
var declarativeTypeValidator = require('@twilio/declarative-type-validator'); | ||
@@ -75,22 +88,15 @@ | ||
var _asyncToGenerator__default = /*#__PURE__*/_interopDefaultLegacy(_asyncToGenerator); | ||
var _classCallCheck__default = /*#__PURE__*/_interopDefaultLegacy(_classCallCheck); | ||
var _createClass__default = /*#__PURE__*/_interopDefaultLegacy(_createClass); | ||
var _inherits__default = /*#__PURE__*/_interopDefaultLegacy(_inherits); | ||
var _possibleConstructorReturn__default = /*#__PURE__*/_interopDefaultLegacy(_possibleConstructorReturn); | ||
var _getPrototypeOf__default = /*#__PURE__*/_interopDefaultLegacy(_getPrototypeOf); | ||
var _regeneratorRuntime__default = /*#__PURE__*/_interopDefaultLegacy(_regeneratorRuntime); | ||
var _typeof__default = /*#__PURE__*/_interopDefaultLegacy(_typeof); | ||
var _assertThisInitialized__default = /*#__PURE__*/_interopDefaultLegacy(_assertThisInitialized); | ||
var _defineProperty__default = /*#__PURE__*/_interopDefaultLegacy(_defineProperty); | ||
var _slicedToArray__default = /*#__PURE__*/_interopDefaultLegacy(_slicedToArray); | ||
var _toConsumableArray__default = /*#__PURE__*/_interopDefaultLegacy(_toConsumableArray); | ||
var logger__namespace = /*#__PURE__*/_interopNamespace(logger); | ||
var require$$0__default = /*#__PURE__*/_interopDefaultLegacy(require$$0); | ||
/*! ***************************************************************************** | ||
Copyright (c) Microsoft Corporation. | ||
Permission to use, copy, modify, and/or distribute this software for any | ||
purpose with or without fee is hereby granted. | ||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH | ||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY | ||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, | ||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM | ||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR | ||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | ||
PERFORMANCE OF THIS SOFTWARE. | ||
***************************************************************************** */ | ||
function __decorate(decorators, target, key, desc) { | ||
@@ -100,3 +106,3 @@ var c = arguments.length, | ||
d; | ||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);else for (var i = decorators.length - 1; i >= 0; i--) { | ||
if ((typeof Reflect === "undefined" ? "undefined" : _typeof__default['default'](Reflect)) === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);else for (var i = decorators.length - 1; i >= 0; i--) { | ||
if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; | ||
@@ -107,3 +113,3 @@ } | ||
function __metadata(metadataKey, metadataValue) { | ||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); | ||
if ((typeof Reflect === "undefined" ? "undefined" : _typeof__default['default'](Reflect)) === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); | ||
} | ||
@@ -117,65 +123,86 @@ | ||
class Logger { | ||
setLevel(level) { | ||
log.setLevel(level); | ||
var Logger = /*#__PURE__*/function () { | ||
function Logger() { | ||
_classCallCheck__default['default'](this, Logger); | ||
} | ||
trace() { | ||
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { | ||
args[_key] = arguments[_key]; | ||
_createClass__default['default'](Logger, [{ | ||
key: "setLevel", | ||
value: function setLevel(level) { | ||
log.setLevel(level); | ||
} | ||
}, { | ||
key: "trace", | ||
value: function trace() { | ||
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { | ||
args[_key] = arguments[_key]; | ||
} | ||
log.trace.apply(null, prepareLine("T", args)); | ||
} | ||
log.trace.apply(null, prepareLine("T", args)); | ||
} | ||
}, { | ||
key: "debug", | ||
value: function debug() { | ||
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { | ||
args[_key2] = arguments[_key2]; | ||
} | ||
debug() { | ||
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { | ||
args[_key2] = arguments[_key2]; | ||
log.debug.apply(null, prepareLine("D", args)); | ||
} | ||
}, { | ||
key: "info", | ||
value: function info() { | ||
for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { | ||
args[_key3] = arguments[_key3]; | ||
} | ||
log.debug.apply(null, prepareLine("D", args)); | ||
} | ||
log.info.apply(null, prepareLine("I", args)); | ||
} | ||
}, { | ||
key: "warn", | ||
value: function warn() { | ||
for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { | ||
args[_key4] = arguments[_key4]; | ||
} | ||
info() { | ||
for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { | ||
args[_key3] = arguments[_key3]; | ||
log.warn.apply(null, prepareLine("W", args)); | ||
} | ||
}, { | ||
key: "error", | ||
value: function error() { | ||
for (var _len5 = arguments.length, args = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) { | ||
args[_key5] = arguments[_key5]; | ||
} | ||
log.info.apply(null, prepareLine("I", args)); | ||
} | ||
warn() { | ||
for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { | ||
args[_key4] = arguments[_key4]; | ||
log.error.apply(null, prepareLine("E", args)); | ||
} | ||
}]); | ||
log.warn.apply(null, prepareLine("W", args)); | ||
} | ||
return Logger; | ||
}(); | ||
error() { | ||
for (var _len5 = arguments.length, args = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) { | ||
args[_key5] = arguments[_key5]; | ||
} | ||
var logInstance = new Logger(); | ||
log.error.apply(null, prepareLine("E", args)); | ||
} | ||
function _createSuper$2(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$2(); return function _createSuperInternal() { var Super = _getPrototypeOf__default['default'](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default['default'](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default['default'](this, result); }; } | ||
} | ||
function _isNativeReflectConstruct$2() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } | ||
var logInstance = new Logger(); | ||
var RegistrationState = function RegistrationState() { | ||
var token = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ""; | ||
var notificationId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ""; | ||
var messageTypes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : new Set(); | ||
class RegistrationState { | ||
constructor() { | ||
var token = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ""; | ||
var notificationId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ""; | ||
var messageTypes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : new Set(); | ||
this.token = token; | ||
this.notificationId = notificationId; | ||
this.messageTypes = messageTypes; | ||
} | ||
_classCallCheck__default['default'](this, RegistrationState); | ||
} | ||
this.token = token; | ||
this.notificationId = notificationId; | ||
this.messageTypes = messageTypes; | ||
}; | ||
function setDifference(a, b) { | ||
return [...[...a].filter(x => !b.has(x)), ...[...b].filter(x => !a.has(x))]; | ||
return [].concat(_toConsumableArray__default['default'](_toConsumableArray__default['default'](a).filter(function (x) { | ||
return !b.has(x); | ||
})), _toConsumableArray__default['default'](_toConsumableArray__default['default'](b).filter(function (x) { | ||
return !a.has(x); | ||
}))); | ||
} | ||
@@ -201,14 +228,23 @@ | ||
class Connector extends events.EventEmitter { | ||
var Connector = /*#__PURE__*/function (_EventEmitter) { | ||
_inherits__default['default'](Connector, _EventEmitter); | ||
var _super = _createSuper$2(Connector); | ||
// @todo replace with FSM | ||
constructor(channelType) { | ||
super(); | ||
function Connector(channelType) { | ||
var _this; | ||
_defineProperty__default['default'](this, "desiredState", new RegistrationState()); | ||
_classCallCheck__default['default'](this, Connector); | ||
_defineProperty__default['default'](this, "currentState", new RegistrationState()); | ||
_this = _super.call(this); | ||
_defineProperty__default['default'](this, "_hasActiveAttempt", false); | ||
_defineProperty__default['default'](_assertThisInitialized__default['default'](_this), "desiredState", new RegistrationState()); | ||
this.channelType = channelType; | ||
_defineProperty__default['default'](_assertThisInitialized__default['default'](_this), "currentState", new RegistrationState()); | ||
_defineProperty__default['default'](_assertThisInitialized__default['default'](_this), "_hasActiveAttempt", false); | ||
_this.channelType = channelType; | ||
return _this; | ||
} | ||
@@ -222,130 +258,142 @@ /** | ||
setNotificationId(notificationId) { | ||
this.desiredState.notificationId = notificationId; | ||
} | ||
_createClass__default['default'](Connector, [{ | ||
key: "setNotificationId", | ||
value: function setNotificationId(notificationId) { | ||
this.desiredState.notificationId = notificationId; | ||
} | ||
}, { | ||
key: "subscribe", | ||
value: function subscribe(messageType) { | ||
if (this.desiredState.messageTypes.has(messageType)) { | ||
logInstance.debug("message type '".concat(messageType, "' for channel ").concat(this.channelType, " is already registered")); | ||
return; | ||
} | ||
subscribe(messageType) { | ||
if (this.desiredState.messageTypes.has(messageType)) { | ||
logInstance.debug("message type '".concat(messageType, "' for channel ").concat(this.channelType, " is already registered")); | ||
return; | ||
this.desiredState.messageTypes.add(messageType); | ||
} | ||
}, { | ||
key: "unsubscribe", | ||
value: function unsubscribe(messageType) { | ||
if (!this.desiredState.messageTypes.has(messageType)) { | ||
return; | ||
} | ||
this.desiredState.messageTypes.add(messageType); | ||
} | ||
unsubscribe(messageType) { | ||
if (!this.desiredState.messageTypes.has(messageType)) { | ||
return; | ||
this.desiredState.messageTypes.delete(messageType); | ||
} | ||
}, { | ||
key: "updateToken", | ||
value: function updateToken(token) { | ||
// @todo not entirely correct? | ||
this.desiredState.token = token; | ||
} | ||
/** | ||
* Perform actual registration after all required changes are settled. | ||
*/ | ||
this.desiredState.messageTypes.delete(messageType); | ||
} | ||
}, { | ||
key: "commitChanges", | ||
value: function () { | ||
var _commitChanges = _asyncToGenerator__default['default']( /*#__PURE__*/_regeneratorRuntime__default['default'].mark(function _callee() { | ||
var _hasDifference, _hasDifference2, needToUpdate, reasons, stateToPersist, persistedState; | ||
updateToken(token) { | ||
// @todo not entirely correct? | ||
this.desiredState.token = token; | ||
} | ||
/** | ||
* Perform actual registration after all required changes are settled. | ||
*/ | ||
return _regeneratorRuntime__default['default'].wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
if (!this._hasActiveAttempt) { | ||
_context.next = 3; | ||
break; | ||
} | ||
// Concurrent access violation | ||
logInstance.error("One registration attempt is already in progress"); | ||
throw new Error("One registration attempt is already in progress"); | ||
commitChanges() { | ||
var _this = this; | ||
case 3: | ||
_hasDifference = hasDifference(this.desiredState, this.currentState), _hasDifference2 = _slicedToArray__default['default'](_hasDifference, 2), needToUpdate = _hasDifference2[0], reasons = _hasDifference2[1]; | ||
return _asyncToGenerator__default['default']( /*#__PURE__*/_regeneratorRuntime__default['default'].mark(function _callee() { | ||
var _hasDifference, _hasDifference2, needToUpdate, reasons, stateToPersist, persistedState; | ||
if (needToUpdate) { | ||
_context.next = 6; | ||
break; | ||
} | ||
return _regeneratorRuntime__default['default'].wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
if (!_this._hasActiveAttempt) { | ||
_context.next = 3; | ||
break; | ||
} | ||
return _context.abrupt("return"); | ||
// Concurrent access violation | ||
logInstance.error("One registration attempt is already in progress"); | ||
throw new Error("One registration attempt is already in progress"); | ||
case 6: | ||
if (!this.currentState.notificationId) { | ||
reasons.delete("notificationId"); | ||
} | ||
case 3: | ||
_hasDifference = hasDifference(_this.desiredState, _this.currentState), _hasDifference2 = _slicedToArray__default['default'](_hasDifference, 2), needToUpdate = _hasDifference2[0], reasons = _hasDifference2[1]; | ||
logInstance.trace("Persisting ".concat(this.channelType, " registration"), reasons, this.desiredState); | ||
_context.prev = 8; | ||
this._hasActiveAttempt = true; | ||
stateToPersist = new RegistrationState(); | ||
stateToPersist.token = this.desiredState.token; | ||
stateToPersist.notificationId = this.desiredState.notificationId; | ||
stateToPersist.messageTypes = new Set(this.desiredState.messageTypes); | ||
if (needToUpdate) { | ||
_context.next = 6; | ||
break; | ||
} | ||
if (!(stateToPersist.messageTypes.size > 0)) { | ||
_context.next = 24; | ||
break; | ||
} | ||
return _context.abrupt("return"); | ||
_context.next = 17; | ||
return this.updateRegistration(stateToPersist, reasons); | ||
case 6: | ||
if (!_this.currentState.notificationId) { | ||
reasons.delete("notificationId"); | ||
} | ||
case 17: | ||
persistedState = _context.sent; | ||
this.currentState.token = persistedState.token; | ||
this.currentState.notificationId = persistedState.notificationId; | ||
this.currentState.messageTypes = new Set(persistedState.messageTypes); // @todo twilsock emits registered(notificationContextId) when this context is reg'd | ||
logInstance.trace("Persisting ".concat(_this.channelType, " registration"), reasons, _this.desiredState); | ||
_context.prev = 8; | ||
_this._hasActiveAttempt = true; | ||
stateToPersist = new RegistrationState(); | ||
stateToPersist.token = _this.desiredState.token; | ||
stateToPersist.notificationId = _this.desiredState.notificationId; | ||
stateToPersist.messageTypes = new Set(_this.desiredState.messageTypes); | ||
if (!(stateToPersist.messageTypes.size > 0)) { | ||
_context.next = 24; | ||
this.emit("stateChanged", this.channelType, "registered", this.currentState); | ||
_context.next = 30; | ||
break; | ||
} | ||
_context.next = 17; | ||
return _this.updateRegistration(stateToPersist, reasons); | ||
case 24: | ||
_context.next = 26; | ||
return this.removeRegistration(); | ||
case 17: | ||
persistedState = _context.sent; | ||
_this.currentState.token = persistedState.token; | ||
_this.currentState.notificationId = persistedState.notificationId; | ||
_this.currentState.messageTypes = new Set(persistedState.messageTypes); // @todo twilsock emits registered(notificationContextId) when this context is reg'd | ||
case 26: | ||
this.currentState.token = stateToPersist.token; | ||
this.currentState.notificationId = stateToPersist.notificationId; | ||
this.currentState.messageTypes.clear(); | ||
this.emit("stateChanged", this.channelType, "unregistered", this.currentState); | ||
_this.emit("stateChanged", _this.channelType, "registered", _this.currentState); | ||
case 30: | ||
_context.next = 35; | ||
break; | ||
_context.next = 30; | ||
break; | ||
case 32: | ||
_context.prev = 32; | ||
_context.t0 = _context["catch"](8); | ||
throw _context.t0; | ||
case 24: | ||
_context.next = 26; | ||
return _this.removeRegistration(); | ||
case 35: | ||
_context.prev = 35; | ||
this._hasActiveAttempt = false; | ||
return _context.finish(35); | ||
case 26: | ||
_this.currentState.token = stateToPersist.token; | ||
_this.currentState.notificationId = stateToPersist.notificationId; | ||
case 38: | ||
case "end": | ||
return _context.stop(); | ||
} | ||
} | ||
}, _callee, this, [[8, 32, 35, 38]]); | ||
})); | ||
_this.currentState.messageTypes.clear(); | ||
function commitChanges() { | ||
return _commitChanges.apply(this, arguments); | ||
} | ||
_this.emit("stateChanged", _this.channelType, "unregistered", _this.currentState); | ||
return commitChanges; | ||
}() | ||
}]); | ||
case 30: | ||
_context.next = 35; | ||
break; | ||
return Connector; | ||
}(events.EventEmitter); | ||
case 32: | ||
_context.prev = 32; | ||
_context.t0 = _context["catch"](8); | ||
throw _context.t0; | ||
function _createSuper$1(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$1(); return function _createSuperInternal() { var Super = _getPrototypeOf__default['default'](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default['default'](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default['default'](this, result); }; } | ||
case 35: | ||
_context.prev = 35; | ||
_this._hasActiveAttempt = false; | ||
return _context.finish(35); | ||
case 38: | ||
case "end": | ||
return _context.stop(); | ||
} | ||
} | ||
}, _callee, null, [[8, 32, 35, 38]]); | ||
}))(); | ||
} | ||
} | ||
function _isNativeReflectConstruct$1() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } | ||
var retrierConfig = { | ||
@@ -361,3 +409,7 @@ min: 2000, | ||
class RegistrarConnector extends Connector { | ||
var RegistrarConnector = /*#__PURE__*/function (_Connector) { | ||
_inherits__default['default'](RegistrarConnector, _Connector); | ||
var _super = _createSuper$1(RegistrarConnector); | ||
/** | ||
@@ -371,468 +423,229 @@ * Creates new instance of the ERS registrar | ||
*/ | ||
constructor(channelType, context, // context is separate from config because it's not shared with other connectors | ||
function RegistrarConnector(channelType, context, // context is separate from config because it's not shared with other connectors | ||
twilsock, registrarUrl) { | ||
super(channelType); | ||
var _this; | ||
_defineProperty__default['default'](this, "registrationId", null); | ||
_classCallCheck__default['default'](this, RegistrarConnector); | ||
this.context = context; | ||
this.twilsock = twilsock; | ||
this.registrarUrl = registrarUrl; | ||
} | ||
_this = _super.call(this, channelType); | ||
updateRegistration(registration, reasons) { | ||
var _this = this; | ||
_defineProperty__default['default'](_assertThisInitialized__default['default'](_this), "registrationId", null); | ||
return _asyncToGenerator__default['default']( /*#__PURE__*/_regeneratorRuntime__default['default'].mark(function _callee() { | ||
var registrarRequest, url, headers, response; | ||
return _regeneratorRuntime__default['default'].wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
if (!reasons.has("notificationId")) { | ||
_context.next = 3; | ||
break; | ||
} | ||
_context.next = 3; | ||
return _this.removeRegistration(); | ||
case 3: | ||
if (!(!registration.notificationId || !registration.notificationId.length)) { | ||
_context.next = 6; | ||
break; | ||
} | ||
logInstance.error("No push notification ID for registration"); | ||
throw new Error("No push notification ID for registration"); | ||
case 6: | ||
logInstance.trace("Registering", _this.channelType, registration); | ||
registrarRequest = { | ||
endpoint_platform: _this.context.platform, | ||
channel_type: _this.channelType, | ||
version: _this.context.protocolVersion.toString(), | ||
message_types: Array.from(registration.messageTypes), | ||
data: { | ||
registration_id: registration.notificationId | ||
} //ttl: 'PT24H' - This is totally ignored by notify, all bindings use PT1Y ttl. | ||
}; | ||
url = "".concat(_this.registrarUrl, "?productId=").concat(_this.context.productId); | ||
headers = { | ||
"Content-Type": "application/json" // 'X-Twilio-Token': registration.token | ||
}; | ||
logInstance.trace("Creating registration for channel ".concat(_this.channelType)); | ||
_context.prev = 11; | ||
_context.next = 14; | ||
return new operationRetrier.AsyncRetrier(retrierConfig).run(() => _this.twilsock.post(url, headers, registrarRequest)); | ||
case 14: | ||
response = _context.sent; | ||
_this.registrationId = response.body.id; | ||
logInstance.debug("Registration created: ", response); | ||
_context.next = 23; | ||
break; | ||
case 19: | ||
_context.prev = 19; | ||
_context.t0 = _context["catch"](11); | ||
logInstance.error("Registration failed: ", _context.t0); | ||
throw _context.t0; | ||
case 23: | ||
return _context.abrupt("return", registration); | ||
case 24: | ||
case "end": | ||
return _context.stop(); | ||
} | ||
} | ||
}, _callee, null, [[11, 19]]); | ||
}))(); | ||
_this.context = context; | ||
_this.twilsock = twilsock; | ||
_this.registrarUrl = registrarUrl; | ||
return _this; | ||
} | ||
removeRegistration() { | ||
var _this2 = this; | ||
_createClass__default['default'](RegistrarConnector, [{ | ||
key: "updateRegistration", | ||
value: function () { | ||
var _updateRegistration = _asyncToGenerator__default['default']( /*#__PURE__*/_regeneratorRuntime__default['default'].mark(function _callee(registration, reasons) { | ||
var _this2 = this; | ||
return _asyncToGenerator__default['default']( /*#__PURE__*/_regeneratorRuntime__default['default'].mark(function _callee2() { | ||
var url, headers; | ||
return _regeneratorRuntime__default['default'].wrap(function _callee2$(_context2) { | ||
while (1) { | ||
switch (_context2.prev = _context2.next) { | ||
case 0: | ||
if (_this2.registrationId) { | ||
_context2.next = 2; | ||
break; | ||
} | ||
var registrarRequest, url, headers, response; | ||
return _regeneratorRuntime__default['default'].wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
if (!reasons.has("notificationId")) { | ||
_context.next = 3; | ||
break; | ||
} | ||
return _context2.abrupt("return"); | ||
_context.next = 3; | ||
return this.removeRegistration(); | ||
case 2: | ||
url = "".concat(_this2.registrarUrl, "/").concat(_this2.registrationId, "?productId=").concat(_this2.context.productId); | ||
headers = { | ||
"Content-Type": "application/json" // 'X-Twilio-Token': this.config.token | ||
case 3: | ||
if (!(!registration.notificationId || !registration.notificationId.length)) { | ||
_context.next = 6; | ||
break; | ||
} | ||
}; | ||
logInstance.trace("Removing registration for ".concat(_this2.channelType)); | ||
_context2.prev = 5; | ||
_context2.next = 8; | ||
return new operationRetrier.AsyncRetrier(Object.assign(retrierConfig, { | ||
maxAttemptsCount: 3 | ||
})).run(() => _this2.twilsock.delete(url, headers)); | ||
logInstance.error("No push notification ID for registration"); | ||
throw new Error("No push notification ID for registration"); | ||
case 8: | ||
logInstance.debug("Registration removed for ".concat(_this2.channelType)); | ||
_context2.next = 15; | ||
break; | ||
case 6: | ||
logInstance.trace("Registering", this.channelType, registration); | ||
registrarRequest = { | ||
endpoint_platform: this.context.platform, | ||
channel_type: this.channelType, | ||
version: this.context.protocolVersion.toString(), | ||
message_types: Array.from(registration.messageTypes), | ||
data: { | ||
registration_id: registration.notificationId | ||
} //ttl: 'PT24H' - This is totally ignored by notify, all bindings use PT1Y ttl. | ||
case 11: | ||
_context2.prev = 11; | ||
_context2.t0 = _context2["catch"](5); | ||
logInstance.error("Failed to remove registration ", _this2.channelType, _context2.t0); | ||
throw _context2.t0; | ||
}; | ||
url = "".concat(this.registrarUrl, "?productId=").concat(this.context.productId); | ||
headers = { | ||
"Content-Type": "application/json" // 'X-Twilio-Token': registration.token | ||
case 15: | ||
case "end": | ||
return _context2.stop(); | ||
} | ||
} | ||
}, _callee2, null, [[5, 11]]); | ||
}))(); | ||
} | ||
}; | ||
logInstance.trace("Creating registration for channel ".concat(this.channelType)); | ||
_context.prev = 11; | ||
_context.next = 14; | ||
return new operationRetrier.AsyncRetrier(retrierConfig).run(function () { | ||
return _this2.twilsock.post(url, headers, registrarRequest); | ||
}); | ||
sendDeviceRemoveRequest(registrationId) { | ||
var _this3 = this; | ||
return _asyncToGenerator__default['default']( /*#__PURE__*/_regeneratorRuntime__default['default'].mark(function _callee3() { | ||
var url, headers, payload; | ||
return _regeneratorRuntime__default['default'].wrap(function _callee3$(_context3) { | ||
while (1) { | ||
switch (_context3.prev = _context3.next) { | ||
case 0: | ||
if (!(registrationId === "")) { | ||
_context3.next = 2; | ||
case 14: | ||
response = _context.sent; | ||
this.registrationId = response.body.id; | ||
logInstance.debug("Registration created: ", response); | ||
_context.next = 23; | ||
break; | ||
} | ||
throw new Error("Empty registration ID"); | ||
case 19: | ||
_context.prev = 19; | ||
_context.t0 = _context["catch"](11); | ||
logInstance.error("Registration failed: ", _context.t0); | ||
throw _context.t0; | ||
case 2: | ||
url = "".concat(_this3.registrarUrl, "?productId=").concat(_this3.context.productId); | ||
headers = { | ||
"Content-Type": "application/json" // @todo Content-Length?? | ||
case 23: | ||
return _context.abrupt("return", registration); | ||
}; | ||
payload = { | ||
binding_type: _this3.channelType, | ||
address: registrationId | ||
}; | ||
_context3.prev = 5; | ||
logInstance.trace("Removing old registrations for ".concat(_this3.channelType)); | ||
_context3.next = 9; | ||
return new operationRetrier.AsyncRetrier(Object.assign(retrierConfig, { | ||
maxAttemptsCount: 3 | ||
})).run(() => _this3.twilsock.delete(url, headers, payload)); | ||
case 9: | ||
logInstance.debug("Registration removed for ".concat(_this3.channelType)); | ||
_context3.next = 16; | ||
break; | ||
case 12: | ||
_context3.prev = 12; | ||
_context3.t0 = _context3["catch"](5); | ||
logInstance.error("Failed to remove registration ", _this3.channelType, _context3.t0); | ||
throw _context3.t0; | ||
case 16: | ||
case "end": | ||
return _context3.stop(); | ||
case 24: | ||
case "end": | ||
return _context.stop(); | ||
} | ||
} | ||
} | ||
}, _callee3, null, [[5, 12]]); | ||
}))(); | ||
} | ||
}, _callee, this, [[11, 19]]); | ||
})); | ||
} | ||
function updateRegistration(_x, _x2) { | ||
return _updateRegistration.apply(this, arguments); | ||
} | ||
// this is pretty straight-forward - we use the crypto API. | ||
return updateRegistration; | ||
}() | ||
}, { | ||
key: "removeRegistration", | ||
value: function () { | ||
var _removeRegistration = _asyncToGenerator__default['default']( /*#__PURE__*/_regeneratorRuntime__default['default'].mark(function _callee2() { | ||
var _this3 = this; | ||
var crypto = require$$0__default['default']; | ||
var url, headers; | ||
return _regeneratorRuntime__default['default'].wrap(function _callee2$(_context2) { | ||
while (1) { | ||
switch (_context2.prev = _context2.next) { | ||
case 0: | ||
if (this.registrationId) { | ||
_context2.next = 2; | ||
break; | ||
} | ||
var rng$2 = function nodeRNG() { | ||
return crypto.randomBytes(16); | ||
}; | ||
return _context2.abrupt("return"); | ||
/** | ||
* Convert array of 16 byte values to UUID string format of the form: | ||
* XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX | ||
*/ | ||
var byteToHex = []; | ||
case 2: | ||
url = "".concat(this.registrarUrl, "/").concat(this.registrationId, "?productId=").concat(this.context.productId); | ||
headers = { | ||
"Content-Type": "application/json" // 'X-Twilio-Token': this.config.token | ||
for (var i = 0; i < 256; ++i) { | ||
byteToHex[i] = (i + 0x100).toString(16).substr(1); | ||
} | ||
}; | ||
logInstance.trace("Removing registration for ".concat(this.channelType)); | ||
_context2.prev = 5; | ||
_context2.next = 8; | ||
return new operationRetrier.AsyncRetrier(Object.assign(retrierConfig, { | ||
maxAttemptsCount: 3 | ||
})).run(function () { | ||
return _this3.twilsock.delete(url, headers); | ||
}); | ||
function bytesToUuid$2(buf, offset) { | ||
var i = offset || 0; | ||
var bth = byteToHex; // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4 | ||
case 8: | ||
logInstance.debug("Registration removed for ".concat(this.channelType)); | ||
_context2.next = 15; | ||
break; | ||
return [bth[buf[i++]], bth[buf[i++]], bth[buf[i++]], bth[buf[i++]], '-', bth[buf[i++]], bth[buf[i++]], '-', bth[buf[i++]], bth[buf[i++]], '-', bth[buf[i++]], bth[buf[i++]], '-', bth[buf[i++]], bth[buf[i++]], bth[buf[i++]], bth[buf[i++]], bth[buf[i++]], bth[buf[i++]]].join(''); | ||
} | ||
case 11: | ||
_context2.prev = 11; | ||
_context2.t0 = _context2["catch"](5); | ||
logInstance.error("Failed to remove registration ", this.channelType, _context2.t0); | ||
throw _context2.t0; | ||
var bytesToUuid_1 = bytesToUuid$2; | ||
case 15: | ||
case "end": | ||
return _context2.stop(); | ||
} | ||
} | ||
}, _callee2, this, [[5, 11]]); | ||
})); | ||
var rng$1 = rng$2; | ||
var bytesToUuid$1 = bytesToUuid_1; // **`v1()` - Generate time-based UUID** | ||
// | ||
// Inspired by https://github.com/LiosK/UUID.js | ||
// and http://docs.python.org/library/uuid.html | ||
function removeRegistration() { | ||
return _removeRegistration.apply(this, arguments); | ||
} | ||
var _nodeId; | ||
return removeRegistration; | ||
}() | ||
}, { | ||
key: "sendDeviceRemoveRequest", | ||
value: function () { | ||
var _sendDeviceRemoveRequest = _asyncToGenerator__default['default']( /*#__PURE__*/_regeneratorRuntime__default['default'].mark(function _callee3(registrationId) { | ||
var _this4 = this; | ||
var _clockseq; // Previous uuid creation time | ||
var url, headers, payload; | ||
return _regeneratorRuntime__default['default'].wrap(function _callee3$(_context3) { | ||
while (1) { | ||
switch (_context3.prev = _context3.next) { | ||
case 0: | ||
if (!(registrationId === "")) { | ||
_context3.next = 2; | ||
break; | ||
} | ||
throw new Error("Empty registration ID"); | ||
var _lastMSecs = 0; | ||
var _lastNSecs = 0; // See https://github.com/uuidjs/uuid for API details | ||
case 2: | ||
url = "".concat(this.registrarUrl, "?productId=").concat(this.context.productId); | ||
headers = { | ||
"Content-Type": "application/json" // @todo Content-Length?? | ||
function v1$1(options, buf, offset) { | ||
var i = buf && offset || 0; | ||
var b = buf || []; | ||
options = options || {}; | ||
var node = options.node || _nodeId; | ||
var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; // node and clockseq need to be initialized to random values if they're not | ||
// specified. We do this lazily to minimize issues related to insufficient | ||
// system entropy. See #189 | ||
}; | ||
payload = { | ||
binding_type: this.channelType, | ||
address: registrationId | ||
}; | ||
_context3.prev = 5; | ||
logInstance.trace("Removing old registrations for ".concat(this.channelType)); | ||
_context3.next = 9; | ||
return new operationRetrier.AsyncRetrier(Object.assign(retrierConfig, { | ||
maxAttemptsCount: 3 | ||
})).run(function () { | ||
return _this4.twilsock.delete(url, headers, payload); | ||
}); | ||
if (node == null || clockseq == null) { | ||
var seedBytes = rng$1(); | ||
if (node == null) { | ||
// Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) | ||
node = _nodeId = [seedBytes[0] | 0x01, seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]]; | ||
} | ||
if (clockseq == null) { | ||
// Per 4.2.2, randomize (14 bit) clockseq | ||
clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff; | ||
} | ||
} // UUID timestamps are 100 nano-second units since the Gregorian epoch, | ||
// (1582-10-15 00:00). JSNumbers aren't precise enough for this, so | ||
// time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' | ||
// (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. | ||
var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime(); // Per 4.2.1.2, use count of uuid's generated during the current clock | ||
// cycle to simulate higher resolution clock | ||
var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; // Time since last uuid creation (in msecs) | ||
var dt = msecs - _lastMSecs + (nsecs - _lastNSecs) / 10000; // Per 4.2.1.2, Bump clockseq on clock regression | ||
if (dt < 0 && options.clockseq === undefined) { | ||
clockseq = clockseq + 1 & 0x3fff; | ||
} // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new | ||
// time interval | ||
if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) { | ||
nsecs = 0; | ||
} // Per 4.2.1.2 Throw error if too many uuids are requested | ||
if (nsecs >= 10000) { | ||
throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec'); | ||
} | ||
_lastMSecs = msecs; | ||
_lastNSecs = nsecs; | ||
_clockseq = clockseq; // Per 4.1.4 - Convert from unix epoch to Gregorian epoch | ||
msecs += 12219292800000; // `time_low` | ||
var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; | ||
b[i++] = tl >>> 24 & 0xff; | ||
b[i++] = tl >>> 16 & 0xff; | ||
b[i++] = tl >>> 8 & 0xff; | ||
b[i++] = tl & 0xff; // `time_mid` | ||
var tmh = msecs / 0x100000000 * 10000 & 0xfffffff; | ||
b[i++] = tmh >>> 8 & 0xff; | ||
b[i++] = tmh & 0xff; // `time_high_and_version` | ||
b[i++] = tmh >>> 24 & 0xf | 0x10; // include version | ||
b[i++] = tmh >>> 16 & 0xff; // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) | ||
b[i++] = clockseq >>> 8 | 0x80; // `clock_seq_low` | ||
b[i++] = clockseq & 0xff; // `node` | ||
for (var n = 0; n < 6; ++n) { | ||
b[i + n] = node[n]; | ||
} | ||
return buf ? buf : bytesToUuid$1(b); | ||
} | ||
var v1_1 = v1$1; | ||
var rng = rng$2; | ||
var bytesToUuid = bytesToUuid_1; | ||
function v4$1(options, buf, offset) { | ||
var i = buf && offset || 0; | ||
if (typeof options == 'string') { | ||
buf = options === 'binary' ? new Array(16) : null; | ||
options = null; | ||
} | ||
options = options || {}; | ||
var rnds = options.random || (options.rng || rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` | ||
rnds[6] = rnds[6] & 0x0f | 0x40; | ||
rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided | ||
if (buf) { | ||
for (var ii = 0; ii < 16; ++ii) { | ||
buf[i + ii] = rnds[ii]; | ||
} | ||
} | ||
return buf || bytesToUuid(rnds); | ||
} | ||
var v4_1 = v4$1; | ||
var v1 = v1_1; | ||
var v4 = v4_1; | ||
var uuid = v4; | ||
uuid.v1 = v1; | ||
uuid.v4 = v4; | ||
var uuid_1 = uuid; | ||
/** | ||
* Registrar connector implementation for twilsock -- @todo Drop twilsock.connector COMPLETELY?! | ||
*/ | ||
class TwilsockConnector extends Connector { | ||
/** | ||
* Create twilsock registration connector. | ||
* @param productId product ID | ||
* @param platform platform ID string | ||
* @param twilsock {TwilsockClient} connection transport. | ||
*/ | ||
constructor(productId, platform, twilsock) { | ||
super("twilsock"); | ||
_defineProperty__default['default'](this, "contextId", uuid_1.v4()); | ||
this.productId = productId; | ||
this.platform = platform; | ||
this.twilsock = twilsock; | ||
} | ||
updateRegistration(registration, reasons) { | ||
var _this = this; | ||
return _asyncToGenerator__default['default']( /*#__PURE__*/_regeneratorRuntime__default['default'].mark(function _callee() { | ||
var messageTypes, context; | ||
return _regeneratorRuntime__default['default'].wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
if (reasons.has("messageType")) { | ||
_context.next = 2; | ||
case 9: | ||
logInstance.debug("Registration removed for ".concat(this.channelType)); | ||
_context3.next = 16; | ||
break; | ||
} | ||
return _context.abrupt("return", registration); | ||
case 12: | ||
_context3.prev = 12; | ||
_context3.t0 = _context3["catch"](5); | ||
logInstance.error("Failed to remove registration ", this.channelType, _context3.t0); | ||
throw _context3.t0; | ||
case 2: | ||
messageTypes = Array.from(registration.messageTypes); | ||
context = { | ||
product_id: _this.productId, | ||
notification_protocol_version: 4, | ||
endpoint_platform: _this.platform, | ||
message_types: messageTypes | ||
}; | ||
_context.prev = 4; | ||
_context.next = 7; | ||
return _this.twilsock.setNotificationsContext(_this.contextId, context); | ||
case 7: | ||
_context.next = 13; | ||
break; | ||
case 9: | ||
_context.prev = 9; | ||
_context.t0 = _context["catch"](4); | ||
logInstance.error("Failed to update twilsock notification context: ".concat(_context.t0)); | ||
throw _context.t0; | ||
case 13: | ||
return _context.abrupt("return", registration); | ||
case 14: | ||
case "end": | ||
return _context.stop(); | ||
case 16: | ||
case "end": | ||
return _context3.stop(); | ||
} | ||
} | ||
} | ||
}, _callee, null, [[4, 9]]); | ||
}))(); | ||
} | ||
}, _callee3, this, [[5, 12]]); | ||
})); | ||
removeRegistration() { | ||
var _this2 = this; | ||
function sendDeviceRemoveRequest(_x3) { | ||
return _sendDeviceRemoveRequest.apply(this, arguments); | ||
} | ||
return _asyncToGenerator__default['default']( /*#__PURE__*/_regeneratorRuntime__default['default'].mark(function _callee2() { | ||
return _regeneratorRuntime__default['default'].wrap(function _callee2$(_context2) { | ||
while (1) { | ||
switch (_context2.prev = _context2.next) { | ||
case 0: | ||
_context2.prev = 0; | ||
_context2.next = 3; | ||
return _this2.twilsock.removeNotificationsContext(_this2.contextId); | ||
return sendDeviceRemoveRequest; | ||
}() | ||
}]); | ||
case 3: | ||
_context2.next = 9; | ||
break; | ||
return RegistrarConnector; | ||
}(Connector); | ||
case 5: | ||
_context2.prev = 5; | ||
_context2.t0 = _context2["catch"](0); | ||
logInstance.error("Failed to remove twilsock notification context: ".concat(_context2.t0)); | ||
throw _context2.t0; | ||
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf__default['default'](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default['default'](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default['default'](this, result); }; } | ||
case 9: | ||
case "end": | ||
return _context2.stop(); | ||
} | ||
} | ||
}, _callee2, null, [[0, 5]]); | ||
}))(); | ||
} // eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } | ||
sendDeviceRemoveRequest(registrationId) {// no need to do anything here, twilsock backend handles it on its own | ||
return _asyncToGenerator__default['default']( /*#__PURE__*/_regeneratorRuntime__default['default'].mark(function _callee3() { | ||
return _regeneratorRuntime__default['default'].wrap(function _callee3$(_context3) { | ||
while (1) { | ||
switch (_context3.prev = _context3.next) { | ||
case 0: | ||
case "end": | ||
return _context3.stop(); | ||
} | ||
} | ||
}, _callee3); | ||
}))(); | ||
} | ||
} | ||
var Client_1; | ||
@@ -857,8 +670,17 @@ | ||
exports.Notifications = Client_1 = class Client extends events.EventEmitter { | ||
constructor(token) { | ||
exports.Notifications = Client_1 = /*#__PURE__*/function (_EventEmitter) { | ||
_inherits__default['default'](Client, _EventEmitter); | ||
var _super = _createSuper(Client); | ||
function Client(token) { | ||
var _options$logLevel, _options$productId, _options$twilsockClie, _options$notification, _ref, _config$region; | ||
var _this; | ||
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
super(); | ||
_classCallCheck__default['default'](this, Client); | ||
_this = _super.call(this); | ||
options.logLevel = (_options$logLevel = options.logLevel) !== null && _options$logLevel !== void 0 ? _options$logLevel : "error"; | ||
@@ -873,253 +695,298 @@ logInstance.setLevel(options.logLevel); | ||
var registrarUrl = config.ersUrl || defaultUrl; | ||
this.connectors = new Map(); | ||
_this.connectors = new Map(); | ||
var platform = Client_1._detectPlatform(); | ||
this.connectors.set("apn", new RegistrarConnector("apn", { | ||
_this.connectors.set("apn", new RegistrarConnector("apn", { | ||
protocolVersion: 4, | ||
productId, | ||
platform | ||
productId: productId, | ||
platform: platform | ||
}, twilsock$1, registrarUrl)); | ||
this.connectors.set("fcm", new RegistrarConnector("fcm", { | ||
_this.connectors.set("fcm", new RegistrarConnector("fcm", { | ||
protocolVersion: 3, | ||
productId, | ||
platform | ||
productId: productId, | ||
platform: platform | ||
}, twilsock$1, registrarUrl)); | ||
this.connectors.set("twilsock", new TwilsockConnector(productId, platform, twilsock$1)); | ||
twilsock$1.on("stateChanged", state => this.emit("transportState", state)); | ||
this._connector("twilsock").on("stateChanged", (type, value, state) => this.emit("stateChanged", type, value, state)); | ||
_this.connectors.set("twilsock", new twilsock_connector.TwilsockConnector(productId, platform, twilsock$1)); | ||
this._connector("apn").on("stateChanged", (type, value, state) => this.emit("stateChanged", type, value, state)); | ||
twilsock$1.on("stateChanged", function (state) { | ||
return _this.emit("transportState", state); | ||
}); | ||
this._connector("fcm").on("stateChanged", (type, value, state) => this.emit("stateChanged", type, value, state)); // Router | ||
_this._connector("twilsock").on("stateChanged", function (type, value, state) { | ||
return _this.emit("stateChanged", type, value, state); | ||
}); | ||
_this._connector("apn").on("stateChanged", function (type, value, state) { | ||
return _this.emit("stateChanged", type, value, state); | ||
}); | ||
twilsock$1.on("message", (type, message) => this._routeMessage(type, message)); | ||
this.updateToken(token); // Start only if we created twilsock locally, | ||
_this._connector("fcm").on("stateChanged", function (type, value, state) { | ||
return _this.emit("stateChanged", type, value, state); | ||
}); // Router | ||
twilsock$1.on("message", function (type, message) { | ||
return _this._routeMessage(type, message); | ||
}); | ||
_this.updateToken(token); // Start only if we created twilsock locally, | ||
// otherwise it's the responsibility of whoever created the Twilsock client. | ||
if (startTwilsock) { | ||
twilsock$1.connect(); | ||
this.twilsock = twilsock$1; | ||
_this.twilsock = twilsock$1; | ||
} | ||
return _this; | ||
} | ||
shutdown() { | ||
var _this = this; | ||
_createClass__default['default'](Client, [{ | ||
key: "shutdown", | ||
value: function () { | ||
var _shutdown = _asyncToGenerator__default['default']( /*#__PURE__*/_regeneratorRuntime__default['default'].mark(function _callee() { | ||
return _regeneratorRuntime__default['default'].wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
this.connectors.clear(); | ||
return _asyncToGenerator__default['default']( /*#__PURE__*/_regeneratorRuntime__default['default'].mark(function _callee() { | ||
return _regeneratorRuntime__default['default'].wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
_this.connectors.clear(); | ||
if (!this.twilsock) { | ||
_context.next = 4; | ||
break; | ||
} | ||
if (!_this.twilsock) { | ||
_context.next = 4; | ||
break; | ||
} | ||
return this.twilsock.disconnect(); | ||
_context.next = 4; | ||
return _this.twilsock.disconnect(); | ||
case 4: | ||
case "end": | ||
return _context.stop(); | ||
case 4: | ||
case "end": | ||
return _context.stop(); | ||
} | ||
} | ||
} | ||
}, _callee); | ||
}))(); | ||
} | ||
/** | ||
* Set OS-provided APNS/FCM registration binding for the given channel type. Not used for 'twilsock'. | ||
* | ||
* You must call this function once you've received the ID of your device from the underlying OS. | ||
* | ||
* @param {ChannelType} channelType Channel type ('apn'/'fcm'). | ||
* @param {string} pushRegistrationId Token received from FCM/APNS system on device. | ||
*/ | ||
}, _callee, this); | ||
})); | ||
function shutdown() { | ||
return _shutdown.apply(this, arguments); | ||
} | ||
setPushRegistrationId(channelType, pushRegistrationId) { | ||
logInstance.debug("Set ".concat(channelType, " push registration id '").concat(pushRegistrationId, "'")); | ||
return shutdown; | ||
}() | ||
/** | ||
* Set OS-provided APNS/FCM registration binding for the given channel type. Not used for 'twilsock'. | ||
* | ||
* You must call this function once you've received the ID of your device from the underlying OS. | ||
* | ||
* @param {ChannelType} channelType Channel type ('apn'/'fcm'). | ||
* @param {string} pushRegistrationId Token received from FCM/APNS system on device. | ||
*/ | ||
this._connector(channelType).setNotificationId(pushRegistrationId); | ||
} | ||
/** | ||
* Subscribe to a given message type for a given channel type. | ||
* | ||
* Creates a subscriptions to receive incoming messages according to message type. | ||
* Subscription establishes a binding and you will receive a signal when a notification | ||
* of this type has been received by the library. | ||
* | ||
* Subscribed binding is preserved for 1 year, after which time it needs to be re-subscribed. | ||
* This is the responsibility of the client SDK. | ||
* | ||
* @param {ChannelType} channelType Supported are 'twilsock', 'apn' and 'fcm' | ||
* @param {string} messageType The type of message that you want to receive | ||
*/ | ||
}, { | ||
key: "setPushRegistrationId", | ||
value: function setPushRegistrationId(channelType, pushRegistrationId) { | ||
logInstance.debug("Set ".concat(channelType, " push registration id '").concat(pushRegistrationId, "'")); | ||
this._connector(channelType).setNotificationId(pushRegistrationId); | ||
} | ||
/** | ||
* Subscribe to a given message type for a given channel type. | ||
* | ||
* Creates a subscriptions to receive incoming messages according to message type. | ||
* Subscription establishes a binding and you will receive a signal when a notification | ||
* of this type has been received by the library. | ||
* | ||
* Subscribed binding is preserved for 1 year, after which time it needs to be re-subscribed. | ||
* This is the responsibility of the client SDK. | ||
* | ||
* @param {ChannelType} channelType Supported are 'twilsock', 'apn' and 'fcm' | ||
* @param {string} messageType The type of message that you want to receive | ||
*/ | ||
subscribe(channelType, messageType) { | ||
logInstance.debug("Add ".concat(channelType, " subscriptions for message type ").concat(messageType)); | ||
}, { | ||
key: "subscribe", | ||
value: function subscribe(channelType, messageType) { | ||
logInstance.debug("Add ".concat(channelType, " subscriptions for message type ").concat(messageType)); | ||
this._connector(channelType).subscribe(messageType); | ||
} | ||
/** | ||
* Unsubscribe from a given message type. | ||
* | ||
* Unsubscribing breaks a binding and you will not receive more notifications for this message type. | ||
* Please note that you have to call commitChanges() and receive a successful result before | ||
* the subscription is actually removed. | ||
* | ||
* @param {ChannelType} channelType Supported are 'twilsock', 'apn' and 'fcm' | ||
* @param {string} messageType The type of message that you don't want to receive anymore | ||
*/ | ||
this._connector(channelType).subscribe(messageType); | ||
} | ||
/** | ||
* Unsubscribe from a given message type. | ||
* | ||
* Unsubscribing breaks a binding and you will not receive more notifications for this message type. | ||
* Please note that you have to call commitChanges() and receive a successful result before | ||
* the subscription is actually removed. | ||
* | ||
* @param {ChannelType} channelType Supported are 'twilsock', 'apn' and 'fcm' | ||
* @param {string} messageType The type of message that you don't want to receive anymore | ||
*/ | ||
}, { | ||
key: "unsubscribe", | ||
value: function unsubscribe(channelType, messageType) { | ||
logInstance.debug("Remove ".concat(channelType, " subscriptions for message type ").concat(messageType)); | ||
unsubscribe(channelType, messageType) { | ||
logInstance.debug("Remove ".concat(channelType, " subscriptions for message type ").concat(messageType)); | ||
this._connector(channelType).unsubscribe(messageType); | ||
} | ||
/** | ||
* Update subscription token. You must update the token when the old one expires. | ||
* | ||
* When you receive onTokenWillExpire event from twilsock, call this function with the new refreshed | ||
* token _after_ you have updated twilsock and other associated objects with the new token. | ||
* | ||
* @param {string} token Authentication token for registrations | ||
*/ | ||
this._connector(channelType).unsubscribe(messageType); | ||
} | ||
/** | ||
* Update subscription token. You must update the token when the old one expires. | ||
* | ||
* When you receive onTokenWillExpire event from twilsock, call this function with the new refreshed | ||
* token _after_ you have updated twilsock and other associated objects with the new token. | ||
* | ||
* @param {string} token Authentication token for registrations | ||
*/ | ||
}, { | ||
key: "updateToken", | ||
value: function updateToken(token) { | ||
this.connectors.forEach(function (connector) { | ||
return connector.updateToken(token); | ||
}); | ||
} | ||
/** | ||
* Commit all collected subscription changes as a batched update. This function tries to reduce | ||
* number of network calls necessary to update bindings status. | ||
*/ | ||
}, { | ||
key: "commitChanges", | ||
value: function () { | ||
var _commitChanges = _asyncToGenerator__default['default']( /*#__PURE__*/_regeneratorRuntime__default['default'].mark(function _callee2() { | ||
var promises; | ||
return _regeneratorRuntime__default['default'].wrap(function _callee2$(_context2) { | ||
while (1) { | ||
switch (_context2.prev = _context2.next) { | ||
case 0: | ||
promises = []; | ||
this.connectors.forEach(function (connector) { | ||
return promises.push(connector.commitChanges()); | ||
}); | ||
_context2.next = 4; | ||
return Promise.all(promises); | ||
updateToken(token) { | ||
this.connectors.forEach(connector => connector.updateToken(token)); | ||
} | ||
/** | ||
* Commit all collected subscription changes as a batched update. This function tries to reduce | ||
* number of network calls necessary to update bindings status. | ||
*/ | ||
commitChanges() { | ||
var _this2 = this; | ||
return _asyncToGenerator__default['default']( /*#__PURE__*/_regeneratorRuntime__default['default'].mark(function _callee2() { | ||
var promises; | ||
return _regeneratorRuntime__default['default'].wrap(function _callee2$(_context2) { | ||
while (1) { | ||
switch (_context2.prev = _context2.next) { | ||
case 0: | ||
promises = []; | ||
_this2.connectors.forEach(connector => promises.push(connector.commitChanges())); | ||
_context2.next = 4; | ||
return Promise.all(promises); | ||
case 4: | ||
case "end": | ||
return _context2.stop(); | ||
case 4: | ||
case "end": | ||
return _context2.stop(); | ||
} | ||
} | ||
} | ||
}, _callee2); | ||
}))(); | ||
} | ||
/** | ||
* Clear existing registrations directly using provided device token. | ||
* This is useful to ensure stopped subscriptions without resubscribing. | ||
* | ||
* This function goes completely beside the state machine and removes all registrations. | ||
* Use with caution: if it races with current state machine operations, madness will ensue. | ||
* | ||
* @param {ChannelType} channelType Channel type ('apn'/'fcm'). | ||
* @param {string} registrationId Token received from FCM/APNS system on device. | ||
*/ | ||
}, _callee2, this); | ||
})); | ||
function commitChanges() { | ||
return _commitChanges.apply(this, arguments); | ||
} | ||
removeRegistrations(channelType, registrationId) { | ||
var _this3 = this; | ||
return commitChanges; | ||
}() | ||
/** | ||
* Clear existing registrations directly using provided device token. | ||
* This is useful to ensure stopped subscriptions without resubscribing. | ||
* | ||
* This function goes completely beside the state machine and removes all registrations. | ||
* Use with caution: if it races with current state machine operations, madness will ensue. | ||
* | ||
* @param {ChannelType} channelType Channel type ('apn'/'fcm'). | ||
* @param {string} registrationId Token received from FCM/APNS system on device. | ||
*/ | ||
return _asyncToGenerator__default['default']( /*#__PURE__*/_regeneratorRuntime__default['default'].mark(function _callee3() { | ||
return _regeneratorRuntime__default['default'].wrap(function _callee3$(_context3) { | ||
while (1) { | ||
switch (_context3.prev = _context3.next) { | ||
case 0: | ||
_context3.next = 2; | ||
return _this3._connector(channelType).sendDeviceRemoveRequest(registrationId); | ||
}, { | ||
key: "removeRegistrations", | ||
value: function () { | ||
var _removeRegistrations = _asyncToGenerator__default['default']( /*#__PURE__*/_regeneratorRuntime__default['default'].mark(function _callee3(channelType, registrationId) { | ||
return _regeneratorRuntime__default['default'].wrap(function _callee3$(_context3) { | ||
while (1) { | ||
switch (_context3.prev = _context3.next) { | ||
case 0: | ||
_context3.next = 2; | ||
return this._connector(channelType).sendDeviceRemoveRequest(registrationId); | ||
case 2: | ||
case "end": | ||
return _context3.stop(); | ||
case 2: | ||
case "end": | ||
return _context3.stop(); | ||
} | ||
} | ||
} | ||
}, _callee3); | ||
}))(); | ||
} | ||
/** | ||
* Handle incoming push notification. | ||
* Client application should call this method when it receives push notifications and pass the received data. | ||
* @param {Object} message push message | ||
* @return {PushNotification} A reformatted payload with extracted message type. | ||
*/ | ||
}, _callee3, this); | ||
})); | ||
function removeRegistrations(_x, _x2) { | ||
return _removeRegistrations.apply(this, arguments); | ||
} | ||
handlePushNotification(message) { | ||
return { | ||
messageType: message.twi_message_type, | ||
payload: message.payload | ||
}; | ||
} | ||
/** | ||
* Routes messages to the external subscribers | ||
*/ | ||
return removeRegistrations; | ||
}() | ||
/** | ||
* Handle incoming push notification. | ||
* Client application should call this method when it receives push notifications and pass the received data. | ||
* @param {Object} message push message | ||
* @return {PushNotification} A reformatted payload with extracted message type. | ||
*/ | ||
}, { | ||
key: "handlePushNotification", | ||
value: function handlePushNotification(message) { | ||
return { | ||
messageType: message.twi_message_type, | ||
payload: message.payload | ||
}; | ||
} | ||
/** | ||
* Routes messages to the external subscribers | ||
*/ | ||
_routeMessage(type, message) { | ||
logInstance.debug("Notification message arrived: ", type, message); | ||
this.emit("message", type, message); | ||
} | ||
/** | ||
* @param {String} type Channel type | ||
* @throws {Error} Error with description | ||
*/ | ||
}, { | ||
key: "_routeMessage", | ||
value: function _routeMessage(type, message) { | ||
logInstance.debug("Notification message arrived: ", type, message); | ||
this.emit("message", type, message); | ||
} | ||
/** | ||
* @param {String} type Channel type | ||
* @throws {Error} Error with description | ||
*/ | ||
}, { | ||
key: "_connector", | ||
value: function _connector(type) { | ||
var connector = this.connectors.get(type); | ||
_connector(type) { | ||
var connector = this.connectors.get(type); | ||
if (!connector) { | ||
throw new Error("Unknown channel type: ".concat(type)); | ||
} | ||
if (!connector) { | ||
throw new Error("Unknown channel type: ".concat(type)); | ||
return connector; | ||
} | ||
/** | ||
* Returns platform string limited to max 128 chars | ||
*/ | ||
return connector; | ||
} | ||
/** | ||
* Returns platform string limited to max 128 chars | ||
*/ | ||
}], [{ | ||
key: "_detectPlatform", | ||
value: function _detectPlatform() { | ||
var platform = ""; | ||
if (typeof navigator !== "undefined") { | ||
platform = "unknown"; | ||
static _detectPlatform() { | ||
var platform = ""; | ||
if (typeof navigator.product !== "undefined") { | ||
platform = navigator.product; | ||
} | ||
if (typeof navigator !== "undefined") { | ||
platform = "unknown"; | ||
if (typeof navigator.product !== "undefined") { | ||
platform = navigator.product; | ||
if (typeof navigator.userAgent !== "undefined") { | ||
platform = navigator.userAgent; | ||
} | ||
} else { | ||
platform = "web"; | ||
} | ||
if (typeof navigator.userAgent !== "undefined") { | ||
platform = navigator.userAgent; | ||
} | ||
} else { | ||
platform = "web"; | ||
return platform.substring(0, 128); | ||
} | ||
}]); | ||
return platform.substring(0, 128); | ||
} | ||
return Client; | ||
}(events.EventEmitter); | ||
}; | ||
__decorate([declarativeTypeValidator.validateTypes(channelTypeRule, declarativeTypeValidator.nonEmptyString), __metadata("design:type", Function), __metadata("design:paramtypes", [String, String]), __metadata("design:returntype", void 0)], exports.Notifications.prototype, "setPushRegistrationId", null); | ||
@@ -1126,0 +993,0 @@ |
{ | ||
"name": "@twilio/notifications", | ||
"version": "1.0.1", | ||
"version": "1.0.2-rc.0", | ||
"description": "Client library for Twilio Notifications service", | ||
@@ -41,6 +41,6 @@ "author": "Twilio", | ||
"@twilio/declarative-type-validator": "^0.1.7", | ||
"@twilio/operation-retrier": "^4.0.3", | ||
"@twilio/twilsock": "^0.11.4", | ||
"@twilio/operation-retrier": "^4.0.4-rc.0", | ||
"core-js": "^3.14.0", | ||
"loglevel": "^1.6.3" | ||
"loglevel": "^1.6.3", | ||
"twilsock": "^0.11.5-rc.0" | ||
}, | ||
@@ -77,3 +77,15 @@ "devDependencies": { | ||
"node": ">=10" | ||
} | ||
}, | ||
"browserslist": [ | ||
"IE 11", | ||
"last 3 Chrome versions", | ||
"last 3 Firefox versions", | ||
"last 3 Safari versions", | ||
"last 3 Edge versions", | ||
"last 2 iOS version", | ||
"last 2 ChromeAndroid version", | ||
"last 2 FirefoxAndroid version", | ||
"last 2 Samsung versions", | ||
"last 2 UCAndroid versions" | ||
] | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1009343
17812
2
+ Addedtwilsock@^0.11.5-rc.0
+ Addedasync-limiter@1.0.1(transitive)
+ Addedjavascript-state-machine@3.1.0(transitive)
+ Addedplatform@1.3.6(transitive)
+ Addedtwilsock@0.11.5(transitive)
+ Addeduuid@3.4.0(transitive)
+ Addedws@5.2.4(transitive)
- Removed@twilio/twilsock@^0.11.4