@twilio/conversations 2.0.1 → 2.1.0-rc.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/CHANGELOG.md +74 -0
  2. package/NOTICE.txt +679 -0
  3. package/builds/browser.js +889 -619
  4. package/builds/browser.js.map +1 -1
  5. package/builds/lib.d.ts +384 -129
  6. package/builds/lib.js +889 -619
  7. package/builds/lib.js.map +1 -1
  8. package/builds/twilio-conversations.js +1065 -939
  9. package/builds/twilio-conversations.min.js +2 -14
  10. package/dist/aggregated-delivery-receipt.js +6 -1
  11. package/dist/aggregated-delivery-receipt.js.map +1 -1
  12. package/dist/client.js +165 -142
  13. package/dist/client.js.map +1 -1
  14. package/dist/command-executor.js +16 -14
  15. package/dist/command-executor.js.map +1 -1
  16. package/dist/configuration.js +14 -10
  17. package/dist/configuration.js.map +1 -1
  18. package/dist/conversation.js +232 -159
  19. package/dist/conversation.js.map +1 -1
  20. package/dist/data/conversations.js +82 -78
  21. package/dist/data/conversations.js.map +1 -1
  22. package/dist/data/messages.js +43 -39
  23. package/dist/data/messages.js.map +1 -1
  24. package/dist/data/participants.js +100 -78
  25. package/dist/data/participants.js.map +1 -1
  26. package/dist/data/users.js +24 -22
  27. package/dist/data/users.js.map +1 -1
  28. package/dist/detailed-delivery-receipt.js +1 -1
  29. package/dist/detailed-delivery-receipt.js.map +1 -1
  30. package/dist/interfaces/attributes.js +147 -0
  31. package/dist/interfaces/attributes.js.map +1 -0
  32. package/dist/interfaces/notification-types.js +5 -5
  33. package/dist/interfaces/notification-types.js.map +1 -1
  34. package/dist/logger.js +36 -15
  35. package/dist/logger.js.map +1 -1
  36. package/dist/media.js +21 -9
  37. package/dist/media.js.map +1 -1
  38. package/dist/message-builder.js +56 -3
  39. package/dist/message-builder.js.map +1 -1
  40. package/dist/message.js +157 -78
  41. package/dist/message.js.map +1 -1
  42. package/dist/packages/conversations/package.json.js +1 -1
  43. package/dist/participant.js +101 -50
  44. package/dist/participant.js.map +1 -1
  45. package/dist/push-notification.js.map +1 -1
  46. package/dist/rest-paginator.js +16 -6
  47. package/dist/rest-paginator.js.map +1 -1
  48. package/dist/services/network.js +18 -14
  49. package/dist/services/network.js.map +1 -1
  50. package/dist/services/typing-indicator.js +20 -17
  51. package/dist/services/typing-indicator.js.map +1 -1
  52. package/dist/unsent-message.js.map +1 -1
  53. package/dist/user.js +87 -60
  54. package/dist/user.js.map +1 -1
  55. package/dist/util/deferred.js +3 -1
  56. package/dist/util/deferred.js.map +1 -1
  57. package/dist/util/index.js +6 -6
  58. package/dist/util/index.js.map +1 -1
  59. package/docs/assets/js/search.js +1 -1
  60. package/docs/classes/AggregatedDeliveryReceipt.html +0 -102
  61. package/docs/classes/Client.html +24 -132
  62. package/docs/classes/Conversation.html +37 -132
  63. package/docs/classes/DetailedDeliveryReceipt.html +1 -103
  64. package/docs/classes/Media.html +0 -102
  65. package/docs/classes/Message.html +73 -109
  66. package/docs/classes/MessageBuilder.html +78 -104
  67. package/docs/classes/Participant.html +37 -110
  68. package/docs/classes/PushNotification.html +0 -102
  69. package/docs/classes/RestPaginator.html +0 -102
  70. package/docs/classes/UnsentMessage.html +0 -102
  71. package/docs/classes/User.html +7 -109
  72. package/docs/index.html +93 -3
  73. package/docs/interfaces/ClientOptions.html +0 -102
  74. package/docs/interfaces/ConversationBindings.html +3001 -0
  75. package/docs/interfaces/ConversationEmailBinding.html +3001 -0
  76. package/docs/interfaces/ConversationState.html +0 -102
  77. package/docs/interfaces/CreateConversationOptions.html +1 -103
  78. package/docs/interfaces/LastMessage.html +0 -102
  79. package/docs/interfaces/Paginator.html +0 -102
  80. package/docs/interfaces/ParticipantBindings.html +3001 -0
  81. package/docs/interfaces/ParticipantEmailBinding.html +3001 -0
  82. package/docs/interfaces/PushNotificationData.html +0 -102
  83. package/docs/interfaces/SendEmailOptions.html +0 -102
  84. package/docs/interfaces/SendMediaOptions.html +0 -102
  85. package/docs/modules.html +93 -3
  86. package/package.json +23 -17
@@ -137,6 +137,7 @@ var participant = require('./participant.js');
137
137
  var messages = require('./data/messages.js');
138
138
  var index = require('./util/index.js');
139
139
  var declarativeTypeValidator = require('@twilio/declarative-type-validator');
140
+ var attributes = require('./interfaces/attributes.js');
140
141
  var messageBuilder = require('./message-builder.js');
141
142
  var replayEventEmitter = require('@twilio/replay-event-emitter');
142
143
  var isEqual = require('lodash.isequal');
@@ -145,20 +146,21 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'defau
145
146
 
146
147
  var isEqual__default = /*#__PURE__*/_interopDefaultLegacy(isEqual);
147
148
 
148
- const log = logger.Logger.scope('Conversation');
149
+ const log = logger.Logger.scope("Conversation");
149
150
  const fieldMappings = {
150
- lastMessage: 'lastMessage',
151
- attributes: 'attributes',
152
- createdBy: 'createdBy',
153
- dateCreated: 'dateCreated',
154
- dateUpdated: 'dateUpdated',
155
- friendlyName: 'friendlyName',
156
- lastConsumedMessageIndex: 'lastConsumedMessageIndex',
157
- notificationLevel: 'notificationLevel',
158
- sid: 'sid',
159
- status: 'status',
160
- uniqueName: 'uniqueName',
161
- state: 'state'
151
+ lastMessage: "lastMessage",
152
+ attributes: "attributes",
153
+ createdBy: "createdBy",
154
+ dateCreated: "dateCreated",
155
+ dateUpdated: "dateUpdated",
156
+ friendlyName: "friendlyName",
157
+ lastConsumedMessageIndex: "lastConsumedMessageIndex",
158
+ notificationLevel: "notificationLevel",
159
+ sid: "sid",
160
+ status: "status",
161
+ uniqueName: "uniqueName",
162
+ state: "state",
163
+ bindings: "bindings",
162
164
  };
163
165
  function parseTime(timeString) {
164
166
  try {
@@ -176,96 +178,130 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
176
178
  * @internal
177
179
  */
178
180
  constructor(descriptor, sid, links, configuration, services) {
181
+ var _a;
179
182
  super();
180
183
  this.sid = sid;
181
184
  this.links = links;
182
185
  this.configuration = configuration;
183
186
  this.services = services;
184
- let attributes = descriptor.attributes || {};
185
- let createdBy = descriptor.createdBy;
186
- let dateCreated = parseTime(descriptor.dateCreated);
187
- let dateUpdated = parseTime(descriptor.dateUpdated);
188
- let friendlyName = descriptor.friendlyName || null;
189
- let lastReadMessageIndex = Number.isInteger(descriptor.lastConsumedMessageIndex) ? descriptor.lastConsumedMessageIndex : null;
190
- let uniqueName = descriptor.uniqueName || null;
187
+ const attributes = descriptor.attributes || {};
188
+ const createdBy = descriptor.createdBy;
189
+ const dateCreated = parseTime(descriptor.dateCreated);
190
+ const dateUpdated = parseTime(descriptor.dateUpdated);
191
+ const friendlyName = descriptor.friendlyName || null;
192
+ const lastReadMessageIndex = Number.isInteger(descriptor.lastConsumedMessageIndex)
193
+ ? descriptor.lastConsumedMessageIndex
194
+ : null;
195
+ const uniqueName = descriptor.uniqueName || null;
191
196
  try {
192
197
  JSON.stringify(attributes);
193
198
  }
194
199
  catch (e) {
195
- throw new Error('Attributes must be a valid JSON object.');
200
+ throw new Error("Attributes must be a valid JSON object.");
196
201
  }
197
202
  this.entityName = descriptor.channel;
198
203
  this.channelState = {
199
204
  uniqueName,
200
- status: 'notParticipating',
205
+ status: "notParticipating",
201
206
  attributes,
202
207
  createdBy,
203
208
  dateCreated,
204
209
  dateUpdated,
205
210
  friendlyName,
206
- lastReadMessageIndex: lastReadMessageIndex
211
+ lastReadMessageIndex,
212
+ bindings: (_a = descriptor.bindings) !== null && _a !== void 0 ? _a : {},
207
213
  };
208
214
  if (descriptor.notificationLevel) {
209
215
  this.channelState.notificationLevel = descriptor.notificationLevel;
210
216
  }
211
217
  const participantsLinks = {
212
- participants: this.links.participants
218
+ participants: this.links.participants,
213
219
  };
214
220
  this.participants = new Map();
215
221
  this.participantsEntity = new participants.Participants(this, this.participants, participantsLinks, this.configuration, this.services);
216
- this.participantsEntity.on('participantJoined', this.emit.bind(this, 'participantJoined'));
217
- this.participantsEntity.on('participantLeft', this.emit.bind(this, 'participantLeft'));
218
- this.participantsEntity.on('participantUpdated', (args) => this.emit('participantUpdated', args));
222
+ this.participantsEntity.on("participantJoined", (participant) => this.emit("participantJoined", participant));
223
+ this.participantsEntity.on("participantLeft", (participant) => this.emit("participantLeft", participant));
224
+ this.participantsEntity.on("participantUpdated", (args) => this.emit("participantUpdated", args));
219
225
  this.messagesEntity = new messages.Messages(this, configuration, services);
220
- this.messagesEntity.on('messageAdded', message => this._onMessageAdded(message));
221
- this.messagesEntity.on('messageUpdated', (args) => this.emit('messageUpdated', args));
222
- this.messagesEntity.on('messageRemoved', this.emit.bind(this, 'messageRemoved'));
226
+ this.messagesEntity.on("messageAdded", (message) => this._onMessageAdded(message));
227
+ this.messagesEntity.on("messageUpdated", (args) => this.emit("messageUpdated", args));
228
+ this.messagesEntity.on("messageRemoved", (message) => this.emit("messageRemoved", message));
223
229
  }
224
230
  /**
225
231
  * Unique name of the conversation.
226
232
  */
227
- get uniqueName() { return this.channelState.uniqueName; }
233
+ get uniqueName() {
234
+ return this.channelState.uniqueName;
235
+ }
228
236
  /**
229
237
  * Status of the conversation.
230
238
  */
231
- get status() { return this.channelState.status; }
239
+ get status() {
240
+ return this.channelState.status;
241
+ }
232
242
  /**
233
243
  * Name of the conversation.
234
244
  */
235
- get friendlyName() { return this.channelState.friendlyName; }
245
+ get friendlyName() {
246
+ return this.channelState.friendlyName;
247
+ }
236
248
  /**
237
249
  * Date this conversation was last updated on.
238
250
  */
239
- get dateUpdated() { return this.channelState.dateUpdated; }
251
+ get dateUpdated() {
252
+ return this.channelState.dateUpdated;
253
+ }
240
254
  /**
241
255
  * Date this conversation was created on.
242
256
  */
243
- get dateCreated() { return this.channelState.dateCreated; }
257
+ get dateCreated() {
258
+ return this.channelState.dateCreated;
259
+ }
244
260
  /**
245
261
  * Identity of the user that created this conversation.
246
262
  */
247
- get createdBy() { return this.channelState.createdBy; }
263
+ get createdBy() {
264
+ var _a;
265
+ return (_a = this.channelState.createdBy) !== null && _a !== void 0 ? _a : "";
266
+ }
248
267
  /**
249
268
  * Custom attributes of the conversation.
250
269
  */
251
- get attributes() { return this.channelState.attributes; }
270
+ get attributes() {
271
+ return this.channelState.attributes;
272
+ }
252
273
  /**
253
274
  * Index of the last message the user has read in this conversation.
254
275
  */
255
- get lastReadMessageIndex() { return this.channelState.lastReadMessageIndex; }
276
+ get lastReadMessageIndex() {
277
+ return this.channelState.lastReadMessageIndex;
278
+ }
256
279
  /**
257
280
  * Last message sent to this conversation.
258
281
  */
259
- get lastMessage() { return this.channelState.lastMessage; }
282
+ get lastMessage() {
283
+ var _a;
284
+ return (_a = this.channelState.lastMessage) !== null && _a !== void 0 ? _a : undefined;
285
+ }
260
286
  /**
261
287
  * User notification level for this conversation.
262
288
  */
263
- get notificationLevel() { return this.channelState.notificationLevel; }
264
- get limits() { return this.configuration.limits; }
289
+ get notificationLevel() {
290
+ var _a;
291
+ return (_a = this.channelState.notificationLevel) !== null && _a !== void 0 ? _a : "default";
292
+ }
293
+ get bindings() {
294
+ return this.channelState.bindings;
295
+ }
296
+ get limits() {
297
+ return this.configuration.limits;
298
+ }
265
299
  /**
266
300
  * State of the conversation.
267
301
  */
268
- get state() { return this.channelState.state; }
302
+ get state() {
303
+ return this.channelState.state;
304
+ }
269
305
  /**
270
306
  * Load and subscribe to this conversation and do not subscribe to its participants and messages.
271
307
  * This or _subscribeStreams will need to be called before any events on conversation will fire.
@@ -273,23 +309,27 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
273
309
  */
274
310
  _subscribe() {
275
311
  var _a;
276
- return this.entityPromise = (_a = this.entityPromise) !== null && _a !== void 0 ? _a : this.services.syncClient.document({ id: this.entityName, mode: 'open_existing' })
277
- .then(entity => {
278
- this.entity = entity;
279
- this.entity.on('updated', args => { this._update(args.data); });
280
- this.entity.on('removed', () => this.emit('removed', this));
281
- this._update(this.entity.data);
282
- return entity;
283
- })
284
- .catch(err => {
285
- this.entity = null;
286
- this.entityPromise = null;
287
- if (this.services.syncClient.connectionState != 'disconnected') {
288
- log.error('Failed to get conversation object', err);
289
- }
290
- log.debug('ERROR: Failed to get conversation object', err);
291
- throw err;
292
- });
312
+ return (this.entityPromise =
313
+ (_a = this.entityPromise) !== null && _a !== void 0 ? _a : this.services.syncClient
314
+ .document({ id: this.entityName, mode: "open_existing" })
315
+ .then((entity) => {
316
+ this.entity = entity;
317
+ this.entity.on("updated", (args) => {
318
+ this._update(args.data);
319
+ });
320
+ this.entity.on("removed", () => this.emit("removed", this));
321
+ this._update(this.entity.data);
322
+ return entity;
323
+ })
324
+ .catch((err) => {
325
+ this.entity = null;
326
+ this.entityPromise = null;
327
+ if (this.services.syncClient.connectionState != "disconnected") {
328
+ log.error("Failed to get conversation object", err);
329
+ }
330
+ log.debug("ERROR: Failed to get conversation object", err);
331
+ throw err;
332
+ }));
293
333
  }
294
334
  /**
295
335
  * Load the attributes of this conversation and instantiate its participants and messages.
@@ -298,21 +338,24 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
298
338
  * @internal
299
339
  */
300
340
  async _subscribeStreams() {
341
+ var _a, _b, _c;
301
342
  try {
302
343
  await this._subscribe();
303
- log.trace('_subscribeStreams, this.entity.data=', this.entity.data);
304
- const messagesObjectName = this.entity.data.messages;
305
- const rosterObjectName = this.entity.data.roster;
344
+ log.trace("_subscribeStreams, this.entity.data=", (_a = this.entity) === null || _a === void 0 ? void 0 : _a.data);
345
+ const messagesObjectName = ((_b = this.entity) === null || _b === void 0 ? void 0 : _b.data)
346
+ .messages;
347
+ const rosterObjectName = ((_c = this.entity) === null || _c === void 0 ? void 0 : _c.data)
348
+ .roster;
306
349
  await Promise.all([
307
350
  this.messagesEntity.subscribe(messagesObjectName),
308
- this.participantsEntity.subscribe(rosterObjectName)
351
+ this.participantsEntity.subscribe(rosterObjectName),
309
352
  ]);
310
353
  }
311
354
  catch (err) {
312
- if (this.services.syncClient.connectionState !== 'disconnected') {
313
- log.error('Failed to subscribe on conversation objects', this.sid, err);
355
+ if (this.services.syncClient.connectionState !== "disconnected") {
356
+ log.error("Failed to subscribe on conversation objects", this.sid, err);
314
357
  }
315
- log.debug('ERROR: Failed to subscribe on conversation objects', this.sid, err);
358
+ log.debug("ERROR: Failed to subscribe on conversation objects", this.sid, err);
316
359
  throw err;
317
360
  }
318
361
  }
@@ -328,7 +371,7 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
328
371
  }
329
372
  return Promise.all([
330
373
  this.participantsEntity.unsubscribe(),
331
- this.messagesEntity.unsubscribe()
374
+ this.messagesEntity.unsubscribe(),
332
375
  ]);
333
376
  }
334
377
  /**
@@ -341,19 +384,18 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
341
384
  return;
342
385
  }
343
386
  this.channelState.status = status;
344
- if (status === 'joined') {
345
- this._subscribeStreams()
346
- .catch(err => {
347
- log.debug('ERROR while setting conversation status ' + status, err);
348
- if (this.services.syncClient.connectionState !== 'disconnected') {
387
+ if (status === "joined") {
388
+ this._subscribeStreams().catch((err) => {
389
+ log.debug("ERROR while setting conversation status " + status, err);
390
+ if (this.services.syncClient.connectionState !== "disconnected") {
349
391
  throw err;
350
392
  }
351
393
  });
352
394
  }
353
395
  else if (this.entityPromise) {
354
- this._unsubscribe().catch(err => {
355
- log.debug('ERROR while setting conversation status ' + status, err);
356
- if (this.services.syncClient.connectionState !== 'disconnected') {
396
+ this._unsubscribe().catch((err) => {
397
+ log.debug("ERROR while setting conversation status " + status, err);
398
+ if (this.services.syncClient.connectionState !== "disconnected") {
357
399
  throw err;
358
400
  }
359
401
  });
@@ -368,7 +410,7 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
368
410
  }
369
411
  static preprocessUpdate(update, conversationSid) {
370
412
  try {
371
- if (typeof update.attributes === 'string') {
413
+ if (typeof update.attributes === "string") {
372
414
  update.attributes = JSON.parse(update.attributes);
373
415
  }
374
416
  else if (update.attributes) {
@@ -376,7 +418,8 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
376
418
  }
377
419
  }
378
420
  catch (e) {
379
- log.warn('Retrieved malformed attributes from the server for conversation: ' + conversationSid);
421
+ log.warn("Retrieved malformed attributes from the server for conversation: " +
422
+ conversationSid);
380
423
  update.attributes = {};
381
424
  }
382
425
  try {
@@ -385,7 +428,8 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
385
428
  }
386
429
  }
387
430
  catch (e) {
388
- log.warn('Retrieved malformed dateCreated from the server for conversation: ' + conversationSid);
431
+ log.warn("Retrieved malformed dateCreated from the server for conversation: " +
432
+ conversationSid);
389
433
  delete update.dateCreated;
390
434
  }
391
435
  try {
@@ -394,7 +438,8 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
394
438
  }
395
439
  }
396
440
  catch (e) {
397
- log.warn('Retrieved malformed dateUpdated from the server for conversation: ' + conversationSid);
441
+ log.warn("Retrieved malformed dateUpdated from the server for conversation: " +
442
+ conversationSid);
398
443
  delete update.dateUpdated;
399
444
  }
400
445
  try {
@@ -403,7 +448,8 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
403
448
  }
404
449
  }
405
450
  catch (e) {
406
- log.warn('Retrieved malformed lastMessage.timestamp from the server for conversation: ' + conversationSid);
451
+ log.warn("Retrieved malformed lastMessage.timestamp from the server for conversation: " +
452
+ conversationSid);
407
453
  delete update.lastMessage.timestamp;
408
454
  }
409
455
  }
@@ -413,7 +459,7 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
413
459
  */
414
460
  _update(update) {
415
461
  var _a, _b, _c, _d, _e;
416
- log.trace('_update', update);
462
+ log.trace("_update", update);
417
463
  Conversation.preprocessUpdate(update, this.sid);
418
464
  const updateReasons = new Set();
419
465
  for (const key of Object.keys(update)) {
@@ -423,8 +469,9 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
423
469
  }
424
470
  switch (localKey) {
425
471
  case fieldMappings.status:
426
- if (!update.status || update.status === 'unknown'
427
- || this.channelState.status === update.status) {
472
+ if (!update.status ||
473
+ update.status === "unknown" ||
474
+ this.channelState.status === update.status) {
428
475
  break;
429
476
  }
430
477
  this.channelState.status = update.status;
@@ -438,12 +485,14 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
438
485
  updateReasons.add(localKey);
439
486
  break;
440
487
  case fieldMappings.lastConsumedMessageIndex:
441
- if (update.lastConsumedMessageIndex === undefined
442
- || update.lastConsumedMessageIndex === this.channelState.lastReadMessageIndex) {
488
+ if (update.lastConsumedMessageIndex === undefined ||
489
+ update.lastConsumedMessageIndex ===
490
+ this.channelState.lastReadMessageIndex) {
443
491
  break;
444
492
  }
445
- this.channelState.lastReadMessageIndex = update.lastConsumedMessageIndex;
446
- updateReasons.add('lastReadMessageIndex');
493
+ this.channelState.lastReadMessageIndex =
494
+ update.lastConsumedMessageIndex;
495
+ updateReasons.add("lastReadMessageIndex");
447
496
  break;
448
497
  case fieldMappings.lastMessage:
449
498
  if (this.channelState.lastMessage && !update.lastMessage) {
@@ -452,14 +501,16 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
452
501
  break;
453
502
  }
454
503
  this.channelState.lastMessage = this.channelState.lastMessage || {};
455
- if (((_a = update.lastMessage) === null || _a === void 0 ? void 0 : _a.index) !== undefined
456
- && update.lastMessage.index !== this.channelState.lastMessage.index) {
504
+ if (((_a = update.lastMessage) === null || _a === void 0 ? void 0 : _a.index) !== undefined &&
505
+ update.lastMessage.index !== this.channelState.lastMessage.index) {
457
506
  this.channelState.lastMessage.index = update.lastMessage.index;
458
507
  updateReasons.add(localKey);
459
508
  }
460
- if (((_b = update.lastMessage) === null || _b === void 0 ? void 0 : _b.timestamp) !== undefined
461
- && ((_d = (_c = this.channelState.lastMessage) === null || _c === void 0 ? void 0 : _c.dateCreated) === null || _d === void 0 ? void 0 : _d.getTime()) !== update.lastMessage.timestamp.getTime()) {
462
- this.channelState.lastMessage.dateCreated = update.lastMessage.timestamp;
509
+ if (((_b = update.lastMessage) === null || _b === void 0 ? void 0 : _b.timestamp) !== undefined &&
510
+ ((_d = (_c = this.channelState.lastMessage) === null || _c === void 0 ? void 0 : _c.dateCreated) === null || _d === void 0 ? void 0 : _d.getTime()) !==
511
+ update.lastMessage.timestamp.getTime()) {
512
+ this.channelState.lastMessage.dateCreated =
513
+ update.lastMessage.timestamp;
463
514
  updateReasons.add(localKey);
464
515
  }
465
516
  if (isEqual__default['default'](this.channelState.lastMessage, {})) {
@@ -477,9 +528,17 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
477
528
  this.channelState.state = state;
478
529
  updateReasons.add(localKey);
479
530
  break;
531
+ case fieldMappings.bindings:
532
+ if (isEqual__default['default'](this.channelState.bindings, update.bindings)) {
533
+ break;
534
+ }
535
+ this.channelState.bindings = update.bindings;
536
+ updateReasons.add(localKey);
537
+ break;
480
538
  default:
481
539
  const isDate = update[key] instanceof Date;
482
- const keysMatchAsDates = isDate && ((_e = this.channelState[localKey]) === null || _e === void 0 ? void 0 : _e.getTime()) === update[key].getTime();
540
+ const keysMatchAsDates = isDate &&
541
+ ((_e = this.channelState[localKey]) === null || _e === void 0 ? void 0 : _e.getTime()) === update[key].getTime();
483
542
  const keysMatchAsNonDates = !isDate && this[localKey] === update[key];
484
543
  if (keysMatchAsDates || keysMatchAsNonDates) {
485
544
  break;
@@ -489,24 +548,27 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
489
548
  }
490
549
  }
491
550
  if (updateReasons.size > 0) {
492
- this.emit('updated', { conversation: this, updateReasons: [...updateReasons] });
551
+ this.emit("updated", {
552
+ conversation: this,
553
+ updateReasons: [...updateReasons],
554
+ });
493
555
  }
494
556
  }
495
557
  /**
496
558
  * @internal
497
559
  */
498
560
  _onMessageAdded(message) {
499
- for (let participant of this.participants.values()) {
561
+ for (const participant of this.participants.values()) {
500
562
  if (participant.identity === message.author) {
501
563
  participant._endTyping();
502
564
  break;
503
565
  }
504
566
  }
505
- this.emit('messageAdded', message);
567
+ this.emit("messageAdded", message);
506
568
  }
507
569
  async _setLastReadMessageIndex(index) {
508
- const result = await this.services.commandExecutor.mutateResource('post', `${this.configuration.links.myConversations}/${this.sid}`, {
509
- last_read_message_index: index
570
+ const result = await this.services.commandExecutor.mutateResource("post", `${this.configuration.links.myConversations}/${this.sid}`, {
571
+ last_read_message_index: index,
510
572
  });
511
573
  return result.unread_messages_count;
512
574
  }
@@ -516,16 +578,17 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
516
578
  * @param attributes Attributes to be attached to the participant.
517
579
  */
518
580
  async add(identity, attributes) {
519
- return this.participantsEntity.add(identity, attributes);
581
+ return this.participantsEntity.add(identity, attributes !== null && attributes !== void 0 ? attributes : {});
520
582
  }
521
583
  /**
522
584
  * Add a non-chat participant to the conversation.
523
585
  * @param proxyAddress Proxy (Twilio) address of the participant.
524
586
  * @param address User address of the participant.
525
587
  * @param attributes Attributes to be attached to the participant.
588
+ * @param bindingOptions Options for adding email participants - name and CC/To level.
526
589
  */
527
- async addNonChatParticipant(proxyAddress, address, attributes) {
528
- return this.participantsEntity.addNonChatParticipant(proxyAddress, address, attributes);
590
+ async addNonChatParticipant(proxyAddress, address, attributes = {}, bindingOptions = {}) {
591
+ return this.participantsEntity.addNonChatParticipant(proxyAddress, address, attributes !== null && attributes !== void 0 ? attributes : {}, bindingOptions !== null && bindingOptions !== void 0 ? bindingOptions : {});
529
592
  }
530
593
  /**
531
594
  * Advance the conversation's last read message index to the current read horizon.
@@ -536,7 +599,7 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
536
599
  */
537
600
  async advanceLastReadMessageIndex(index) {
538
601
  await this._subscribeStreams();
539
- if (index < this.lastReadMessageIndex) {
602
+ if (index < (this.lastReadMessageIndex || 0)) {
540
603
  return await this._setLastReadMessageIndex(this.lastReadMessageIndex);
541
604
  }
542
605
  return await this._setLastReadMessageIndex(index);
@@ -545,7 +608,7 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
545
608
  * Delete the conversation and unsubscribe from its events.
546
609
  */
547
610
  async delete() {
548
- await this.services.commandExecutor.mutateResource('delete', this.links.self);
611
+ await this.services.commandExecutor.mutateResource("delete", this.links.self);
549
612
  return this;
550
613
  }
551
614
  /**
@@ -585,11 +648,12 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
585
648
  * logic based on these counters being accurate in real time.
586
649
  */
587
650
  async getParticipantsCount() {
651
+ var _a;
588
652
  const url = new index.UriBuilder(this.configuration.links.conversations)
589
653
  .path(this.sid)
590
654
  .build();
591
655
  const response = await this.services.network.get(url);
592
- return response.body.participants_count;
656
+ return (_a = response.body.participants_count) !== null && _a !== void 0 ? _a : 0;
593
657
  }
594
658
  /**
595
659
  * Get a participant by its SID.
@@ -602,8 +666,8 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
602
666
  * Get a participant by its identity.
603
667
  * @param identity Participant identity.
604
668
  */
605
- async getParticipantByIdentity(identity) {
606
- return this.participantsEntity.getParticipantByIdentity(identity);
669
+ async getParticipantByIdentity(identity = "") {
670
+ return this.participantsEntity.getParticipantByIdentity(identity !== null && identity !== void 0 ? identity : "");
607
671
  }
608
672
  /**
609
673
  * Get the total message count in the conversation.
@@ -616,11 +680,12 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
616
680
  * logic based on these counters being accurate in real time.
617
681
  */
618
682
  async getMessagesCount() {
683
+ var _a;
619
684
  const url = new index.UriBuilder(this.configuration.links.conversations)
620
685
  .path(this.sid)
621
686
  .build();
622
687
  const response = await this.services.network.get(url);
623
- return response.body.messages_count;
688
+ return (_a = response.body.messages_count) !== null && _a !== void 0 ? _a : 0;
624
689
  }
625
690
  /**
626
691
  * Get unread messages count for the user if they are a participant of this conversation.
@@ -643,10 +708,10 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
643
708
  .build();
644
709
  const response = await this.services.network.get(url);
645
710
  if (response.body.conversation_sid !== this.sid) {
646
- throw new Error('Conversation was not found in the user conversations list');
711
+ throw new Error("Conversation was not found in the user conversations list");
647
712
  }
648
713
  const unreadMessageCount = response.body.unread_messages_count;
649
- if (typeof unreadMessageCount === 'number') {
714
+ if (typeof unreadMessageCount === "number") {
650
715
  return unreadMessageCount;
651
716
  }
652
717
  return null;
@@ -655,8 +720,8 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
655
720
  * Join the conversation and subscribe to its events.
656
721
  */
657
722
  async join() {
658
- await this.services.commandExecutor.mutateResource('post', this.links.participants, {
659
- identity: this.configuration.userIdentity
723
+ await this.services.commandExecutor.mutateResource("post", this.links.participants, {
724
+ identity: this.configuration.userIdentity,
660
725
  });
661
726
  return this;
662
727
  }
@@ -664,8 +729,8 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
664
729
  * Leave the conversation.
665
730
  */
666
731
  async leave() {
667
- if (this.channelState.status === 'joined') {
668
- await this.services.commandExecutor.mutateResource('delete', `${this.links.participants}/${this.configuration.userIdentity}`);
732
+ if (this.channelState.status === "joined") {
733
+ await this.services.commandExecutor.mutateResource("delete", `${this.links.participants}/${this.configuration.userIdentity}`);
669
734
  }
670
735
  return this;
671
736
  }
@@ -674,10 +739,10 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
674
739
  * argument, it will assume that the string is an identity or SID.
675
740
  * @param participant Identity, SID or the participant object to remove.
676
741
  */
742
+ /* eslint-disable @typescript-eslint/ban-ts-comment */
743
+ // @ts-ignore TODO: fix validateTypesAsync typing
677
744
  async removeParticipant(participant) {
678
- await this.participantsEntity.remove(typeof participant === 'string'
679
- ? participant
680
- : participant.sid);
745
+ await this.participantsEntity.remove(typeof participant === "string" ? participant : participant.sid);
681
746
  }
682
747
  /**
683
748
  * Send a message to the conversation.
@@ -688,16 +753,18 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
688
753
  * @return Index of the new message.
689
754
  */
690
755
  async sendMessage(message, messageAttributes, emailOptions) {
691
- if (typeof message === 'string' || message === null) {
692
- let response = await this.messagesEntity.send(message, messageAttributes, emailOptions);
693
- return index.parseToNumber(response.index);
756
+ var _a, _b;
757
+ if (typeof message === "string" || message === null) {
758
+ const response = await this.messagesEntity.send(message, messageAttributes, emailOptions);
759
+ return (_a = index.parseToNumber(response.index)) !== null && _a !== void 0 ? _a : 0;
694
760
  }
695
- let response = await this.messagesEntity.sendMedia(message, messageAttributes, emailOptions);
696
- return index.parseToNumber(response.index);
761
+ const response = await this.messagesEntity.sendMedia(message, messageAttributes, emailOptions);
762
+ return (_b = index.parseToNumber(response.index)) !== null && _b !== void 0 ? _b : 0;
697
763
  }
698
764
  /**
699
765
  * New interface to prepare for sending a message.
700
766
  * Use instead of `sendMessage`.
767
+ * @return A MessageBuilder to help set all message sending options.
701
768
  */
702
769
  prepareMessage() {
703
770
  return new messageBuilder.MessageBuilder(this.limits, this.messagesEntity);
@@ -708,7 +775,7 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
708
775
  */
709
776
  async setAllMessagesRead() {
710
777
  await this._subscribeStreams();
711
- let messagesPage = await this.getMessages(1);
778
+ const messagesPage = await this.getMessages(1);
712
779
  if (messagesPage.items.length > 0) {
713
780
  return this.advanceLastReadMessageIndex(messagesPage.items[0].index);
714
781
  }
@@ -727,8 +794,8 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
727
794
  * @param notificationLevel New user notification level.
728
795
  */
729
796
  async setUserNotificationLevel(notificationLevel) {
730
- await this.services.commandExecutor.mutateResource('post', `${this.configuration.links.myConversations}/${this.sid}`, {
731
- notification_level: notificationLevel
797
+ await this.services.commandExecutor.mutateResource("post", `${this.configuration.links.myConversations}/${this.sid}`, {
798
+ notification_level: notificationLevel,
732
799
  });
733
800
  }
734
801
  /**
@@ -743,8 +810,8 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
743
810
  * @param attributes New attributes.
744
811
  */
745
812
  async updateAttributes(attributes) {
746
- await this.services.commandExecutor.mutateResource('post', this.links.self, {
747
- attributes: attributes !== undefined ? JSON.stringify(attributes) : undefined
813
+ await this.services.commandExecutor.mutateResource("post", this.links.self, {
814
+ attributes: attributes !== undefined ? JSON.stringify(attributes) : undefined,
748
815
  });
749
816
  return this;
750
817
  }
@@ -754,7 +821,7 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
754
821
  */
755
822
  async updateFriendlyName(friendlyName) {
756
823
  if (this.channelState.friendlyName !== friendlyName) {
757
- await this.services.commandExecutor.mutateResource('post', this.links.self, { friendly_name: friendlyName });
824
+ await this.services.commandExecutor.mutateResource("post", this.links.self, { friendly_name: friendlyName });
758
825
  }
759
826
  return this;
760
827
  }
@@ -775,10 +842,10 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
775
842
  async updateUniqueName(uniqueName) {
776
843
  if (this.channelState.uniqueName !== uniqueName) {
777
844
  if (!uniqueName) {
778
- uniqueName = '';
845
+ uniqueName = "";
779
846
  }
780
- await this.services.commandExecutor.mutateResource('post', this.links.self, {
781
- unique_name: uniqueName
847
+ await this.services.commandExecutor.mutateResource("post", this.links.self, {
848
+ unique_name: uniqueName,
782
849
  });
783
850
  }
784
851
  return this;
@@ -791,7 +858,7 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
791
858
  * 1. {@link Participant} `participant` - participant that joined the conversation
792
859
  * @event
793
860
  */
794
- Conversation.participantJoined = 'participantJoined';
861
+ Conversation.participantJoined = "participantJoined";
795
862
  /**
796
863
  * Fired when a participant has left the conversation.
797
864
  *
@@ -799,7 +866,7 @@ Conversation.participantJoined = 'participantJoined';
799
866
  * 1. {@link Participant} `participant` - participant that left the conversation
800
867
  * @event
801
868
  */
802
- Conversation.participantLeft = 'participantLeft';
869
+ Conversation.participantLeft = "participantLeft";
803
870
  /**
804
871
  * Fired when data of a participant has been updated.
805
872
  *
@@ -809,7 +876,7 @@ Conversation.participantLeft = 'participantLeft';
809
876
  * * {@link ParticipantUpdateReason}[] `updateReasons` - array of reasons for update
810
877
  * @event
811
878
  */
812
- Conversation.participantUpdated = 'participantUpdated';
879
+ Conversation.participantUpdated = "participantUpdated";
813
880
  /**
814
881
  * Fired when a new message has been added to the conversation.
815
882
  *
@@ -817,7 +884,7 @@ Conversation.participantUpdated = 'participantUpdated';
817
884
  * 1. {@link Message} `message` - message that has been added
818
885
  * @event
819
886
  */
820
- Conversation.messageAdded = 'messageAdded';
887
+ Conversation.messageAdded = "messageAdded";
821
888
  /**
822
889
  * Fired when message is removed from the conversation's message list.
823
890
  *
@@ -825,7 +892,7 @@ Conversation.messageAdded = 'messageAdded';
825
892
  * 1. {@link Message} `message` - message that has been removed
826
893
  * @event
827
894
  */
828
- Conversation.messageRemoved = 'messageRemoved';
895
+ Conversation.messageRemoved = "messageRemoved";
829
896
  /**
830
897
  * Fired when data of a message has been updated.
831
898
  *
@@ -835,7 +902,7 @@ Conversation.messageRemoved = 'messageRemoved';
835
902
  * * {@link MessageUpdateReason}[] `updateReasons` - array of reasons for update
836
903
  * @event
837
904
  */
838
- Conversation.messageUpdated = 'messageUpdated';
905
+ Conversation.messageUpdated = "messageUpdated";
839
906
  /**
840
907
  * Fired when a participant has stopped typing.
841
908
  *
@@ -843,7 +910,7 @@ Conversation.messageUpdated = 'messageUpdated';
843
910
  * 1. {@link Participant} `participant` - the participant that has stopped typing
844
911
  * @event
845
912
  */
846
- Conversation.typingEnded = 'typingEnded';
913
+ Conversation.typingEnded = "typingEnded";
847
914
  /**
848
915
  * Fired when a participant has started typing.
849
916
  *
@@ -851,7 +918,7 @@ Conversation.typingEnded = 'typingEnded';
851
918
  * 1. {@link Participant} `participant` - the participant that has started typing
852
919
  * @event
853
920
  */
854
- Conversation.typingStarted = 'typingStarted';
921
+ Conversation.typingStarted = "typingStarted";
855
922
  /**
856
923
  * Fired when the data of the conversation has been updated.
857
924
  *
@@ -861,7 +928,7 @@ Conversation.typingStarted = 'typingStarted';
861
928
  * * {@link ConversationUpdateReason}[] `updateReasons` - array of reasons for update
862
929
  * @event
863
930
  */
864
- Conversation.updated = 'updated';
931
+ Conversation.updated = "updated";
865
932
  /**
866
933
  * Fired when the conversation was destroyed or the currently-logged-in user has left private conversation.
867
934
  *
@@ -869,17 +936,17 @@ Conversation.updated = 'updated';
869
936
  * 1. {@link Conversation} `conversation` - conversation that has been removed
870
937
  * @event
871
938
  */
872
- Conversation.removed = 'removed';
939
+ Conversation.removed = "removed";
873
940
  tslib_es6.__decorate([
874
- declarativeTypeValidator.validateTypesAsync(declarativeTypeValidator.nonEmptyString, ['undefined', 'string', 'number', 'boolean', 'object', declarativeTypeValidator.literal(null)]),
941
+ declarativeTypeValidator.validateTypesAsync(declarativeTypeValidator.nonEmptyString, attributes.optionalAttributesValidator),
875
942
  tslib_es6.__metadata("design:type", Function),
876
943
  tslib_es6.__metadata("design:paramtypes", [String, Object]),
877
944
  tslib_es6.__metadata("design:returntype", Promise)
878
945
  ], Conversation.prototype, "add", null);
879
946
  tslib_es6.__decorate([
880
- declarativeTypeValidator.validateTypesAsync(declarativeTypeValidator.nonEmptyString, declarativeTypeValidator.nonEmptyString, ['undefined', 'string', 'number', 'boolean', 'object', declarativeTypeValidator.literal(null)]),
947
+ declarativeTypeValidator.validateTypesAsync(declarativeTypeValidator.nonEmptyString, declarativeTypeValidator.nonEmptyString, attributes.optionalAttributesValidator),
881
948
  tslib_es6.__metadata("design:type", Function),
882
- tslib_es6.__metadata("design:paramtypes", [String, String, Object]),
949
+ tslib_es6.__metadata("design:paramtypes", [String, String, Object, Object]),
883
950
  tslib_es6.__metadata("design:returntype", Promise)
884
951
  ], Conversation.prototype, "addNonChatParticipant", null);
885
952
  tslib_es6.__decorate([
@@ -889,7 +956,7 @@ tslib_es6.__decorate([
889
956
  tslib_es6.__metadata("design:returntype", Promise)
890
957
  ], Conversation.prototype, "advanceLastReadMessageIndex", null);
891
958
  tslib_es6.__decorate([
892
- declarativeTypeValidator.validateTypesAsync(['undefined', declarativeTypeValidator.nonNegativeInteger], ['undefined', declarativeTypeValidator.nonNegativeInteger], ['undefined', declarativeTypeValidator.literal('backwards', 'forward')]),
959
+ declarativeTypeValidator.validateTypesAsync(["undefined", declarativeTypeValidator.nonNegativeInteger], ["undefined", declarativeTypeValidator.nonNegativeInteger], ["undefined", declarativeTypeValidator.literal("backwards", "forward")]),
893
960
  tslib_es6.__metadata("design:type", Function),
894
961
  tslib_es6.__metadata("design:paramtypes", [Number, Number, String]),
895
962
  tslib_es6.__metadata("design:returntype", Promise)
@@ -914,44 +981,50 @@ tslib_es6.__decorate([
914
981
  ], Conversation.prototype, "removeParticipant", null);
915
982
  tslib_es6.__decorate([
916
983
  declarativeTypeValidator.validateTypesAsync([
917
- 'string',
984
+ "string",
918
985
  declarativeTypeValidator.literal(null),
919
986
  // Wrapping it into a custom rule is necessary because the FormData class is not available on initialization.
920
- declarativeTypeValidator.custom((value) => [value instanceof FormData, 'an instance of FormData']),
921
- declarativeTypeValidator.objectSchema('media options', {
987
+ declarativeTypeValidator.custom((value) => [value instanceof FormData, "an instance of FormData"]),
988
+ declarativeTypeValidator.objectSchema("media options", {
922
989
  contentType: declarativeTypeValidator.nonEmptyString,
923
990
  media: declarativeTypeValidator.custom((value) => {
924
- let isValid = (typeof value === 'string' && value.length > 0) || value instanceof Uint8Array || value instanceof ArrayBuffer;
925
- if (typeof Blob === 'function') {
991
+ let isValid = (typeof value === "string" && value.length > 0) ||
992
+ value instanceof Uint8Array ||
993
+ value instanceof ArrayBuffer;
994
+ if (typeof Blob === "function") {
926
995
  isValid = isValid || value instanceof Blob;
927
996
  }
928
997
  return [
929
998
  isValid,
930
- 'a non-empty string, an instance of Buffer or an instance of Blob'
999
+ "a non-empty string, an instance of Buffer or an instance of Blob",
931
1000
  ];
932
- })
933
- })
934
- ], ['undefined', 'string', 'number', 'boolean', 'object', declarativeTypeValidator.literal(null)], ['undefined', declarativeTypeValidator.literal(null), declarativeTypeValidator.objectSchema('email attributes', {
935
- subject: [declarativeTypeValidator.nonEmptyString, 'undefined']
936
- })]),
1001
+ }),
1002
+ }),
1003
+ ], attributes.optionalAttributesValidator, [
1004
+ "undefined",
1005
+ declarativeTypeValidator.literal(null),
1006
+ declarativeTypeValidator.objectSchema("email attributes", {
1007
+ subject: [declarativeTypeValidator.nonEmptyString, "undefined"],
1008
+ }),
1009
+ ]),
937
1010
  tslib_es6.__metadata("design:type", Function),
938
1011
  tslib_es6.__metadata("design:paramtypes", [Object, Object, Object]),
939
1012
  tslib_es6.__metadata("design:returntype", Promise)
940
1013
  ], Conversation.prototype, "sendMessage", null);
941
1014
  tslib_es6.__decorate([
942
- declarativeTypeValidator.validateTypesAsync(declarativeTypeValidator.literal('default', 'muted')),
1015
+ declarativeTypeValidator.validateTypesAsync(declarativeTypeValidator.literal("default", "muted")),
943
1016
  tslib_es6.__metadata("design:type", Function),
944
1017
  tslib_es6.__metadata("design:paramtypes", [String]),
945
1018
  tslib_es6.__metadata("design:returntype", Promise)
946
1019
  ], Conversation.prototype, "setUserNotificationLevel", null);
947
1020
  tslib_es6.__decorate([
948
- declarativeTypeValidator.validateTypesAsync(['string', 'number', 'boolean', 'object', declarativeTypeValidator.literal(null)]),
1021
+ declarativeTypeValidator.validateTypesAsync(attributes.attributesValidator),
949
1022
  tslib_es6.__metadata("design:type", Function),
950
1023
  tslib_es6.__metadata("design:paramtypes", [Object]),
951
1024
  tslib_es6.__metadata("design:returntype", Promise)
952
1025
  ], Conversation.prototype, "updateAttributes", null);
953
1026
  tslib_es6.__decorate([
954
- declarativeTypeValidator.validateTypesAsync(['string']),
1027
+ declarativeTypeValidator.validateTypesAsync(["string"]),
955
1028
  tslib_es6.__metadata("design:type", Function),
956
1029
  tslib_es6.__metadata("design:paramtypes", [String]),
957
1030
  tslib_es6.__metadata("design:returntype", Promise)
@@ -963,7 +1036,7 @@ tslib_es6.__decorate([
963
1036
  tslib_es6.__metadata("design:returntype", Promise)
964
1037
  ], Conversation.prototype, "updateLastReadMessageIndex", null);
965
1038
  tslib_es6.__decorate([
966
- declarativeTypeValidator.validateTypesAsync(['string', declarativeTypeValidator.literal(null)]),
1039
+ declarativeTypeValidator.validateTypesAsync(["string", declarativeTypeValidator.literal(null)]),
967
1040
  tslib_es6.__metadata("design:type", Function),
968
1041
  tslib_es6.__metadata("design:paramtypes", [String]),
969
1042
  tslib_es6.__metadata("design:returntype", Promise)