@twilio/conversations 2.0.1-rc.6 → 2.1.0-rc.0

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 (55) hide show
  1. package/CHANGELOG.md +55 -0
  2. package/builds/browser.js +248 -64
  3. package/builds/browser.js.map +1 -1
  4. package/builds/lib.d.ts +86 -9
  5. package/builds/lib.js +248 -64
  6. package/builds/lib.js.map +1 -1
  7. package/builds/twilio-conversations.js +253 -250
  8. package/builds/twilio-conversations.min.js +3 -3
  9. package/dist/conversation.js +24 -10
  10. package/dist/conversation.js.map +1 -1
  11. package/dist/data/messages.js +1 -1
  12. package/dist/data/messages.js.map +1 -1
  13. package/dist/data/participants.js +7 -3
  14. package/dist/data/participants.js.map +1 -1
  15. package/dist/index.js +1 -0
  16. package/dist/index.js.map +1 -1
  17. package/dist/interfaces/attributes.js +147 -0
  18. package/dist/interfaces/attributes.js.map +1 -0
  19. package/dist/message-builder.js +52 -0
  20. package/dist/message-builder.js.map +1 -1
  21. package/dist/message.js +35 -4
  22. package/dist/message.js.map +1 -1
  23. package/dist/packages/conversations/package.json.js +1 -1
  24. package/dist/participant.js +20 -3
  25. package/dist/participant.js.map +1 -1
  26. package/dist/user.js +2 -1
  27. package/dist/user.js.map +1 -1
  28. package/docs/assets/js/search.js +1 -1
  29. package/docs/classes/AggregatedDeliveryReceipt.html +15 -0
  30. package/docs/classes/Client.html +15 -0
  31. package/docs/classes/Conversation.html +24 -2
  32. package/docs/classes/DetailedDeliveryReceipt.html +15 -0
  33. package/docs/classes/Media.html +15 -0
  34. package/docs/classes/Message.html +83 -2
  35. package/docs/classes/MessageBuilder.html +91 -0
  36. package/docs/classes/Participant.html +45 -1
  37. package/docs/classes/PushNotification.html +15 -0
  38. package/docs/classes/RestPaginator.html +15 -0
  39. package/docs/classes/UnsentMessage.html +15 -0
  40. package/docs/classes/User.html +15 -0
  41. package/docs/index.html +37 -3
  42. package/docs/interfaces/ClientOptions.html +15 -0
  43. package/docs/interfaces/ConversationBindings.html +3118 -0
  44. package/docs/interfaces/ConversationEmailBinding.html +3118 -0
  45. package/docs/interfaces/ConversationState.html +15 -0
  46. package/docs/interfaces/CreateConversationOptions.html +15 -0
  47. package/docs/interfaces/LastMessage.html +15 -0
  48. package/docs/interfaces/Paginator.html +15 -0
  49. package/docs/interfaces/ParticipantBindings.html +3118 -0
  50. package/docs/interfaces/ParticipantEmailBinding.html +3118 -0
  51. package/docs/interfaces/PushNotificationData.html +15 -0
  52. package/docs/interfaces/SendEmailOptions.html +15 -0
  53. package/docs/interfaces/SendMediaOptions.html +15 -0
  54. package/docs/modules.html +37 -3
  55. package/package.json +10 -12
@@ -133,6 +133,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
133
133
  var tslib_es6 = require('./node_modules/tslib/tslib.es6.js');
134
134
  var index = require('./util/index.js');
135
135
  var logger = require('./logger.js');
136
+ var attributes = require('./interfaces/attributes.js');
136
137
  var declarativeTypeValidator = require('@twilio/declarative-type-validator');
137
138
  var replayEventEmitter = require('@twilio/replay-event-emitter');
138
139
  var isEqual = require('lodash.isequal');
@@ -150,6 +151,7 @@ class Participant extends replayEventEmitter.ReplayEventEmitter {
150
151
  * @internal
151
152
  */
152
153
  constructor(data, sid, conversation, links, services) {
154
+ var _a;
153
155
  super();
154
156
  this.conversation = conversation;
155
157
  this.links = links;
@@ -166,7 +168,8 @@ class Participant extends replayEventEmitter.ReplayEventEmitter {
166
168
  lastReadMessageIndex: Number.isInteger(data.lastConsumedMessageIndex) ? data.lastConsumedMessageIndex : null,
167
169
  lastReadTimestamp: data.lastConsumptionTimestamp ? index.parseTime(data.lastConsumptionTimestamp) : null,
168
170
  type: data.type || 'chat',
169
- userInfo: data.userInfo
171
+ userInfo: data.userInfo,
172
+ bindings: (_a = data.bindings) !== null && _a !== void 0 ? _a : {},
170
173
  };
171
174
  if (!data.identity && !data.type) {
172
175
  throw new Error('Received invalid Participant object from server: Missing identity or type of Participant.');
@@ -209,9 +212,19 @@ class Participant extends replayEventEmitter.ReplayEventEmitter {
209
212
  get lastReadTimestamp() { return this.state.lastReadTimestamp; }
210
213
  get roleSid() { return this.state.roleSid; }
211
214
  /**
212
- * Message type of the participant.
215
+ * Type of the participant.
213
216
  */
214
217
  get type() { return this.state.type; }
218
+ /**
219
+ * Get the bindings mapping for the current participant.
220
+ * Available binding depends on the participant type.
221
+ * You could access it as `participant.bindings.sms?.address` or
222
+ * using the type dynamically `participant.bindings[participant.type]`
223
+ * just be aware that the binding information has different structure for
224
+ * each participant type.
225
+ * See also {ParticipantEmailBinding}, the only available currently binding descriptor.
226
+ */
227
+ get bindings() { return this.state.bindings; }
215
228
  /**
216
229
  * Internal method used to start or reset the typing indicator timeout (with event emitting).
217
230
  * @internal
@@ -278,6 +291,10 @@ class Participant extends replayEventEmitter.ReplayEventEmitter {
278
291
  updateReasons.push('lastReadTimestamp');
279
292
  }
280
293
  }
294
+ if (data.bindings && !isEqual__default['default'](this.state.bindings, data.bindings)) {
295
+ this.state.bindings = data.bindings;
296
+ updateReasons.push('bindings');
297
+ }
281
298
  if (updateReasons.length > 0) {
282
299
  this.emit('updated', { participant: this, updateReasons: updateReasons });
283
300
  }
@@ -336,7 +353,7 @@ Participant.typingEnded = 'typingEnded';
336
353
  */
337
354
  Participant.updated = 'updated';
338
355
  tslib_es6.__decorate([
339
- declarativeTypeValidator.validateTypesAsync(['string', 'number', 'boolean', 'object', declarativeTypeValidator.literal(null)]),
356
+ declarativeTypeValidator.validateTypesAsync(attributes.attributesValidator),
340
357
  tslib_es6.__metadata("design:type", Function),
341
358
  tslib_es6.__metadata("design:paramtypes", [Object]),
342
359
  tslib_es6.__metadata("design:returntype", Promise)
@@ -1 +1 @@
1
- {"version":3,"file":"participant.js","sources":["../src/participant.ts"],"sourcesContent":["import { Users } from './data/users';\nimport { User } from './user';\nimport { parseTime, parseAttributes } from './util';\nimport { Logger } from './logger';\nimport { Conversation } from './conversation';\nimport { validateTypesAsync, literal } from '@twilio/declarative-type-validator';\nimport { CommandExecutor } from './command-executor';\nimport { EditParticipantRequest } from './interfaces/commands/edit-participant';\nimport { ParticipantResponse } from './interfaces/commands/participant-response';\nimport { ReplayEventEmitter } from '@twilio/replay-event-emitter';\nimport isEqual from 'lodash.isequal';\n\ntype ParticipantEvents = {\n typingEnded: (participant: Participant) => void;\n typingStarted: (participant: Participant) => void;\n updated: (data: {\n participant: Participant;\n updateReasons: ParticipantUpdateReason[];\n }) => void;\n};\n\nconst log = Logger.scope('Participant');\n\ninterface ParticipantDescriptor {\n attributes?: Object;\n dateCreated: any;\n dateUpdated: any;\n identity: string;\n roleSid?: string;\n lastConsumedMessageIndex: number;\n lastConsumptionTimestamp: number;\n type: ParticipantType;\n userInfo: string;\n}\n\ninterface ParticipantState {\n attributes: any;\n dateCreated: Date;\n dateUpdated: Date;\n identity: string;\n isTyping: boolean;\n lastReadMessageIndex: number | null;\n lastReadTimestamp: Date;\n roleSid: string;\n sid: string;\n type: ParticipantType;\n typingTimeout: any;\n userInfo: string;\n}\n\ninterface ParticipantServices {\n users: Users;\n commandExecutor: CommandExecutor;\n}\n\ninterface ParticipantLinks {\n self: string;\n}\n\n/**\n * The reason for the `updated` event being emitted by a participant.\n */\ntype ParticipantUpdateReason =\n | 'attributes'\n | 'dateCreated'\n | 'dateUpdated'\n | 'roleSid'\n | 'lastReadMessageIndex'\n | 'lastReadTimestamp';\n\n/**\n * Type of a participant.\n */\ntype ParticipantType = 'chat' | 'sms' | 'whatsapp';\n\ninterface ParticipantUpdatedEventArgs {\n participant: Participant;\n updateReasons: ParticipantUpdateReason[];\n}\n\n/**\n * A participant represents a remote client in a conversation.\n */\nclass Participant extends ReplayEventEmitter<ParticipantEvents> {\n private state: ParticipantState;\n private readonly links: ParticipantLinks;\n private readonly services: ParticipantServices;\n\n /**\n * Conversation that the remote client is a participant of.\n */\n public readonly conversation: Conversation;\n\n /**\n * The server-assigned unique identifier for the participant.\n */\n public get sid(): string { return this.state.sid; }\n\n /**\n * Custom attributes of the participant.\n */\n public get attributes(): Object { return this.state.attributes; }\n\n /**\n * Date this participant was created on.\n */\n public get dateCreated(): Date { return this.state.dateCreated; }\n\n /**\n * Date this participant was last updated on.\n */\n public get dateUpdated(): Date { return this.state.dateUpdated; }\n\n /**\n * Identity of the participant.\n */\n public get identity(): string { return this.state.identity; }\n\n /**\n * Indicates whether the participant is currently typing.\n */\n public get isTyping(): boolean { return this.state.isTyping; }\n\n /**\n * The index of the last read message by the participant.\n * Note that retrieving messages on a client endpoint does not mean that messages are read,\n * please consider reading about the [Read Horizon feature](https://www.twilio.com/docs/api/chat/guides/consumption-horizon)\n * to find out about the proper way to mark messages as read.\n */\n public get lastReadMessageIndex(): number | null { return this.state.lastReadMessageIndex; }\n\n /**\n * Date of the most recent read horizon update.\n */\n public get lastReadTimestamp(): Date { return this.state.lastReadTimestamp; }\n\n public get roleSid(): string { return this.state.roleSid; }\n\n /**\n * Message type of the participant.\n */\n public get type(): ParticipantType { return this.state.type; }\n\n /**\n * @internal\n */\n constructor(\n data: ParticipantDescriptor,\n sid: string,\n conversation: Conversation,\n links: ParticipantLinks,\n services: ParticipantServices,\n ) {\n super();\n\n this.conversation = conversation;\n this.links = links;\n this.services = services;\n this.state = {\n attributes: parseAttributes(data.attributes,\n 'Retrieved malformed attributes from the server for participant: ' + sid,\n log),\n dateCreated: data.dateCreated ? parseTime(data.dateCreated) : null,\n dateUpdated: data.dateCreated ? parseTime(data.dateUpdated) : null,\n sid: sid,\n typingTimeout: null,\n isTyping: false,\n identity: data.identity || null,\n roleSid: data.roleSid || null,\n lastReadMessageIndex: Number.isInteger(data.lastConsumedMessageIndex) ? data.lastConsumedMessageIndex : null,\n lastReadTimestamp: data.lastConsumptionTimestamp ? parseTime(data.lastConsumptionTimestamp) : null,\n type: data.type || 'chat',\n userInfo: data.userInfo\n };\n\n if (!data.identity && !data.type) {\n throw new Error('Received invalid Participant object from server: Missing identity or type of Participant.');\n }\n }\n\n /**\n * Fired when the participant has started typing.\n *\n * Parameters:\n * 1. {@link Participant} `participant` - the participant in question\n * @event\n */\n static readonly typingStarted = 'typingStarted';\n\n /**\n * Fired when the participant has stopped typing.\n *\n * Parameters:\n * 1. {@link Participant} `participant` - the participant in question\n * @event\n */\n static readonly typingEnded = 'typingEnded';\n\n /**\n * Fired when the fields of the participant have been updated.\n *\n * Parameters:\n * 1. object `data` - info object provided with the event. It has the following properties:\n * * {@link Participant} participant - the participant in question\n * * {@link ParticipantUpdateReason}[] updateReasons - array of reasons for the update\n * @event\n */\n static readonly updated = 'updated';\n\n /**\n * Internal method used to start or reset the typing indicator timeout (with event emitting).\n * @internal\n */\n _startTyping(timeout) {\n clearTimeout(this.state.typingTimeout);\n\n this.state.isTyping = true;\n this.emit('typingStarted', this);\n this.conversation.emit('typingStarted', this);\n\n this.state.typingTimeout = setTimeout(() => this._endTyping(), timeout);\n return this;\n }\n\n /**\n * Internal method function used to stop the typing indicator timeout (with event emitting).\n * @internal\n */\n _endTyping() {\n if (!this.state.typingTimeout) { return; }\n\n this.state.isTyping = false;\n this.emit('typingEnded', this);\n this.conversation.emit('typingEnded', this);\n\n clearInterval(this.state.typingTimeout);\n this.state.typingTimeout = null;\n }\n\n /**\n * Internal method function used update local object's property roleSid with a new value.\n * @internal\n */\n _update(data) {\n let updateReasons: ParticipantUpdateReason[] = [];\n\n let updateAttributes =\n parseAttributes(\n data.attributes,\n 'Retrieved malformed attributes from the server for participant: ' + this.state.sid,\n log);\n\n if (data.attributes && !isEqual(this.state.attributes, updateAttributes)) {\n this.state.attributes = updateAttributes;\n updateReasons.push('attributes');\n }\n\n let updatedDateUpdated = parseTime(data.dateUpdated);\n if (data.dateUpdated &&\n updatedDateUpdated.getTime() !== (this.state.dateUpdated && this.state.dateUpdated.getTime())) {\n this.state.dateUpdated = updatedDateUpdated;\n updateReasons.push('dateUpdated');\n }\n\n let updatedDateCreated = parseTime(data.dateCreated);\n if (data.dateCreated &&\n updatedDateCreated.getTime() !== (this.state.dateCreated && this.state.dateCreated.getTime())) {\n this.state.dateCreated = updatedDateCreated;\n updateReasons.push('dateCreated');\n }\n\n if (data.roleSid && this.state.roleSid !== data.roleSid) {\n this.state.roleSid = data.roleSid;\n updateReasons.push('roleSid');\n }\n\n if ((Number.isInteger(data.lastConsumedMessageIndex) || data.lastConsumedMessageIndex === null)\n && this.state.lastReadMessageIndex !== data.lastConsumedMessageIndex) {\n this.state.lastReadMessageIndex = data.lastConsumedMessageIndex;\n updateReasons.push('lastReadMessageIndex');\n }\n\n if (data.lastConsumptionTimestamp) {\n let lastReadTimestamp = new Date(data.lastConsumptionTimestamp);\n if (!this.state.lastReadTimestamp ||\n this.state.lastReadTimestamp.getTime() !== lastReadTimestamp.getTime()) {\n this.state.lastReadTimestamp = lastReadTimestamp;\n updateReasons.push('lastReadTimestamp');\n }\n }\n\n if (updateReasons.length > 0) {\n this.emit('updated', { participant: this, updateReasons: updateReasons });\n }\n\n return this;\n }\n\n /**\n * Get the user for this participant and subscribes to it. Supported only for participants of type `chat`.\n */\n async getUser(): Promise<User> {\n if (this.type != 'chat') {\n throw new Error('Getting User is not supported for this Participant type: ' + this.type);\n }\n\n return this.services.users.getUser(this.state.identity, this.state.userInfo);\n }\n\n /**\n * Remove the participant from the conversation.\n */\n async remove() {\n return this.conversation.removeParticipant(this);\n }\n\n /**\n * Update the attributes of the participant.\n * @param attributes New attributes.\n */\n @validateTypesAsync(['string', 'number', 'boolean', 'object', literal(null)])\n async updateAttributes(attributes: any): Promise<Participant> {\n await this.services.commandExecutor.mutateResource<EditParticipantRequest, ParticipantResponse>(\n 'post',\n this.links.self,\n {\n attributes: JSON.stringify(attributes)\n }\n );\n\n return this;\n }\n}\n\nexport {\n ParticipantDescriptor,\n ParticipantServices,\n Participant,\n ParticipantUpdateReason,\n ParticipantType,\n ParticipantUpdatedEventArgs\n};\n"],"names":["Logger","ReplayEventEmitter","parseAttributes","parseTime","isEqual","__decorate","validateTypesAsync","literal"],"mappings":"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"}
1
+ {"version":3,"file":"participant.js","sources":["../src/participant.ts"],"sourcesContent":["import { Users } from './data/users';\nimport { User } from './user';\nimport { parseTime, parseAttributes } from './util';\nimport { Logger } from './logger';\nimport { Conversation } from './conversation';\nimport { attributesValidator } from './interfaces/attributes';\nimport { validateTypesAsync, literal } from '@twilio/declarative-type-validator';\nimport { CommandExecutor } from './command-executor';\nimport { EditParticipantRequest } from './interfaces/commands/edit-participant';\nimport { ParticipantResponse } from './interfaces/commands/participant-response';\nimport { ReplayEventEmitter } from '@twilio/replay-event-emitter';\nimport isEqual from 'lodash.isequal';\n\ntype ParticipantEvents = {\n typingEnded: (participant: Participant) => void;\n typingStarted: (participant: Participant) => void;\n updated: (data: {\n participant: Participant;\n updateReasons: ParticipantUpdateReason[];\n }) => void;\n};\n\nconst log = Logger.scope('Participant');\n\ninterface ParticipantDescriptor {\n attributes?: Object;\n dateCreated: any;\n dateUpdated: any;\n identity: string;\n roleSid?: string;\n lastConsumedMessageIndex: number;\n lastConsumptionTimestamp: number;\n type: ParticipantType;\n userInfo: string;\n bindings?: Object;\n}\n\ninterface ParticipantState {\n attributes: any;\n dateCreated: Date;\n dateUpdated: Date;\n identity: string;\n isTyping: boolean;\n lastReadMessageIndex: number | null;\n lastReadTimestamp: Date;\n roleSid: string;\n sid: string;\n type: ParticipantType;\n typingTimeout: any;\n userInfo: string;\n bindings: ParticipantBindings;\n}\n\ninterface ParticipantServices {\n users: Users;\n commandExecutor: CommandExecutor;\n}\n\ninterface ParticipantLinks {\n self: string;\n}\n\n/**\n * The reason for the `updated` event being emitted by a participant.\n */\ntype ParticipantUpdateReason =\n | 'attributes'\n | 'dateCreated'\n | 'dateUpdated'\n | 'roleSid'\n | 'lastReadMessageIndex'\n | 'lastReadTimestamp'\n | 'bindings';\n\n/**\n * Type of a participant.\n */\ntype ParticipantType = 'chat' | 'sms' | 'whatsapp' | 'email';\n\ninterface ParticipantUpdatedEventArgs {\n participant: Participant;\n updateReasons: ParticipantUpdateReason[];\n}\n\n/**\n * Bindings for conversation participant.\n */\ninterface ParticipantBindings {\n email?: ParticipantEmailBinding;\n}\n\n/**\n * Email participation level.\n * to = to/from\n * cc = cc\n */\ntype ParticipantEmailLevel = 'to' | 'cc';\n\n/**\n * Bindings for email participant.\n */\ninterface ParticipantEmailBinding {\n name: string;\n address: string;\n level: ParticipantEmailLevel;\n}\n\n/**\n * A participant represents a remote client in a conversation.\n */\nclass Participant extends ReplayEventEmitter<ParticipantEvents> {\n private state: ParticipantState;\n private readonly links: ParticipantLinks;\n private readonly services: ParticipantServices;\n\n /**\n * Conversation that the remote client is a participant of.\n */\n public readonly conversation: Conversation;\n\n /**\n * The server-assigned unique identifier for the participant.\n */\n public get sid(): string { return this.state.sid; }\n\n /**\n * Custom attributes of the participant.\n */\n public get attributes(): Object { return this.state.attributes; }\n\n /**\n * Date this participant was created on.\n */\n public get dateCreated(): Date { return this.state.dateCreated; }\n\n /**\n * Date this participant was last updated on.\n */\n public get dateUpdated(): Date { return this.state.dateUpdated; }\n\n /**\n * Identity of the participant.\n */\n public get identity(): string { return this.state.identity; }\n\n /**\n * Indicates whether the participant is currently typing.\n */\n public get isTyping(): boolean { return this.state.isTyping; }\n\n /**\n * The index of the last read message by the participant.\n * Note that retrieving messages on a client endpoint does not mean that messages are read,\n * please consider reading about the [Read Horizon feature](https://www.twilio.com/docs/api/chat/guides/consumption-horizon)\n * to find out about the proper way to mark messages as read.\n */\n public get lastReadMessageIndex(): number | null { return this.state.lastReadMessageIndex; }\n\n /**\n * Date of the most recent read horizon update.\n */\n public get lastReadTimestamp(): Date { return this.state.lastReadTimestamp; }\n\n public get roleSid(): string { return this.state.roleSid; }\n\n /**\n * Type of the participant.\n */\n public get type(): ParticipantType { return this.state.type; }\n\n /**\n * Get the bindings mapping for the current participant.\n * Available binding depends on the participant type.\n * You could access it as `participant.bindings.sms?.address` or\n * using the type dynamically `participant.bindings[participant.type]`\n * just be aware that the binding information has different structure for\n * each participant type.\n * See also {ParticipantEmailBinding}, the only available currently binding descriptor.\n */\n public get bindings(): ParticipantBindings { return this.state.bindings; }\n\n /**\n * @internal\n */\n constructor(\n data: ParticipantDescriptor,\n sid: string,\n conversation: Conversation,\n links: ParticipantLinks,\n services: ParticipantServices,\n ) {\n super();\n\n this.conversation = conversation;\n this.links = links;\n this.services = services;\n this.state = {\n attributes: parseAttributes(data.attributes,\n 'Retrieved malformed attributes from the server for participant: ' + sid,\n log),\n dateCreated: data.dateCreated ? parseTime(data.dateCreated) : null,\n dateUpdated: data.dateCreated ? parseTime(data.dateUpdated) : null,\n sid: sid,\n typingTimeout: null,\n isTyping: false,\n identity: data.identity || null,\n roleSid: data.roleSid || null,\n lastReadMessageIndex: Number.isInteger(data.lastConsumedMessageIndex) ? data.lastConsumedMessageIndex : null,\n lastReadTimestamp: data.lastConsumptionTimestamp ? parseTime(data.lastConsumptionTimestamp) : null,\n type: data.type || 'chat',\n userInfo: data.userInfo,\n bindings: data.bindings ?? {},\n };\n\n if (!data.identity && !data.type) {\n throw new Error('Received invalid Participant object from server: Missing identity or type of Participant.');\n }\n }\n\n /**\n * Fired when the participant has started typing.\n *\n * Parameters:\n * 1. {@link Participant} `participant` - the participant in question\n * @event\n */\n static readonly typingStarted = 'typingStarted';\n\n /**\n * Fired when the participant has stopped typing.\n *\n * Parameters:\n * 1. {@link Participant} `participant` - the participant in question\n * @event\n */\n static readonly typingEnded = 'typingEnded';\n\n /**\n * Fired when the fields of the participant have been updated.\n *\n * Parameters:\n * 1. object `data` - info object provided with the event. It has the following properties:\n * * {@link Participant} participant - the participant in question\n * * {@link ParticipantUpdateReason}[] updateReasons - array of reasons for the update\n * @event\n */\n static readonly updated = 'updated';\n\n /**\n * Internal method used to start or reset the typing indicator timeout (with event emitting).\n * @internal\n */\n _startTyping(timeout) {\n clearTimeout(this.state.typingTimeout);\n\n this.state.isTyping = true;\n this.emit('typingStarted', this);\n this.conversation.emit('typingStarted', this);\n\n this.state.typingTimeout = setTimeout(() => this._endTyping(), timeout);\n return this;\n }\n\n /**\n * Internal method function used to stop the typing indicator timeout (with event emitting).\n * @internal\n */\n _endTyping() {\n if (!this.state.typingTimeout) { return; }\n\n this.state.isTyping = false;\n this.emit('typingEnded', this);\n this.conversation.emit('typingEnded', this);\n\n clearInterval(this.state.typingTimeout);\n this.state.typingTimeout = null;\n }\n\n /**\n * Internal method function used update local object's property roleSid with a new value.\n * @internal\n */\n _update(data) {\n let updateReasons: ParticipantUpdateReason[] = [];\n\n let updateAttributes =\n parseAttributes(\n data.attributes,\n 'Retrieved malformed attributes from the server for participant: ' + this.state.sid,\n log);\n\n if (data.attributes && !isEqual(this.state.attributes, updateAttributes)) {\n this.state.attributes = updateAttributes;\n updateReasons.push('attributes');\n }\n\n let updatedDateUpdated = parseTime(data.dateUpdated);\n if (data.dateUpdated &&\n updatedDateUpdated.getTime() !== (this.state.dateUpdated && this.state.dateUpdated.getTime())) {\n this.state.dateUpdated = updatedDateUpdated;\n updateReasons.push('dateUpdated');\n }\n\n let updatedDateCreated = parseTime(data.dateCreated);\n if (data.dateCreated &&\n updatedDateCreated.getTime() !== (this.state.dateCreated && this.state.dateCreated.getTime())) {\n this.state.dateCreated = updatedDateCreated;\n updateReasons.push('dateCreated');\n }\n\n if (data.roleSid && this.state.roleSid !== data.roleSid) {\n this.state.roleSid = data.roleSid;\n updateReasons.push('roleSid');\n }\n\n if ((Number.isInteger(data.lastConsumedMessageIndex) || data.lastConsumedMessageIndex === null)\n && this.state.lastReadMessageIndex !== data.lastConsumedMessageIndex) {\n this.state.lastReadMessageIndex = data.lastConsumedMessageIndex;\n updateReasons.push('lastReadMessageIndex');\n }\n\n if (data.lastConsumptionTimestamp) {\n let lastReadTimestamp = new Date(data.lastConsumptionTimestamp);\n if (!this.state.lastReadTimestamp ||\n this.state.lastReadTimestamp.getTime() !== lastReadTimestamp.getTime()) {\n this.state.lastReadTimestamp = lastReadTimestamp;\n updateReasons.push('lastReadTimestamp');\n }\n }\n\n if (data.bindings && !isEqual(this.state.bindings, data.bindings)) {\n this.state.bindings = data.bindings;\n updateReasons.push('bindings');\n }\n\n if (updateReasons.length > 0) {\n this.emit('updated', { participant: this, updateReasons: updateReasons });\n }\n\n return this;\n }\n\n /**\n * Get the user for this participant and subscribes to it. Supported only for participants of type `chat`.\n */\n async getUser(): Promise<User> {\n if (this.type != 'chat') {\n throw new Error('Getting User is not supported for this Participant type: ' + this.type);\n }\n\n return this.services.users.getUser(this.state.identity, this.state.userInfo);\n }\n\n /**\n * Remove the participant from the conversation.\n */\n async remove() {\n return this.conversation.removeParticipant(this);\n }\n\n /**\n * Update the attributes of the participant.\n * @param attributes New attributes.\n */\n @validateTypesAsync(attributesValidator)\n async updateAttributes(attributes: any): Promise<Participant> {\n await this.services.commandExecutor.mutateResource<EditParticipantRequest, ParticipantResponse>(\n 'post',\n this.links.self,\n {\n attributes: JSON.stringify(attributes)\n }\n );\n\n return this;\n }\n}\n\nexport {\n ParticipantDescriptor,\n ParticipantServices,\n Participant,\n ParticipantUpdateReason,\n ParticipantType,\n ParticipantUpdatedEventArgs,\n ParticipantBindings,\n ParticipantEmailBinding,\n ParticipantEmailLevel\n};\n"],"names":["Logger","ReplayEventEmitter","parseAttributes","parseTime","isEqual","__decorate","validateTypesAsync","attributesValidator"],"mappings":"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"}
package/dist/user.js CHANGED
@@ -134,6 +134,7 @@ var tslib_es6 = require('./node_modules/tslib/tslib.es6.js');
134
134
  var logger = require('./logger.js');
135
135
  var index = require('./util/index.js');
136
136
  var declarativeTypeValidator = require('@twilio/declarative-type-validator');
137
+ var attributes = require('./interfaces/attributes.js');
137
138
  var replayEventEmitter = require('@twilio/replay-event-emitter');
138
139
  var isEqual = require('lodash.isequal');
139
140
 
@@ -376,7 +377,7 @@ class User extends replayEventEmitter.ReplayEventEmitter {
376
377
  }
377
378
  }
378
379
  tslib_es6.__decorate([
379
- declarativeTypeValidator.validateTypesAsync(['string', 'number', 'boolean', 'object', declarativeTypeValidator.literal(null)]),
380
+ declarativeTypeValidator.validateTypesAsync(attributes.attributesValidator),
380
381
  tslib_es6.__metadata("design:type", Function),
381
382
  tslib_es6.__metadata("design:paramtypes", [Object]),
382
383
  tslib_es6.__metadata("design:returntype", Promise)
package/dist/user.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"user.js","sources":["../src/user.ts"],"sourcesContent":["import { Logger } from './logger';\nimport { SyncClient } from 'twilio-sync';\nimport { parseAttributes } from './util';\nimport { validateTypesAsync, literal } from '@twilio/declarative-type-validator';\nimport { Configuration } from './configuration';\nimport { CommandExecutor } from './command-executor';\nimport { EditUserRequest, EditUserResponse } from './interfaces/commands/edit-user';\nimport { ReplayEventEmitter } from '@twilio/replay-event-emitter';\nimport isEqual from 'lodash.isequal';\n\ntype UserEvents = {\n updated: (data: {\n user: User,\n updateReasons: UserUpdateReason[]\n }) => void;\n userSubscribed: (user: User) => void;\n userUnsubscribed: (user: User) => void;\n};\n\nconst log = Logger.scope('User');\n\ninterface UserState {\n identity: string;\n entityName: string;\n friendlyName: string;\n attributes: any;\n online: boolean;\n notifiable: boolean;\n}\n\ninterface UserServices {\n syncClient: SyncClient;\n commandExecutor: CommandExecutor;\n}\n\ninterface UserLinks {\n self: string;\n}\n\ntype SubscriptionState = 'initializing' | 'subscribed' | 'unsubscribed';\n\n/**\n * The reason for the `updated` event being emitted by a user.\n */\ntype UserUpdateReason =\n | 'friendlyName'\n | 'attributes'\n | 'reachabilityOnline'\n | 'reachabilityNotifiable';\n\ninterface UserUpdatedEventArgs {\n user: User;\n updateReasons: UserUpdateReason[];\n}\n\n/**\n * Extended user information.\n * Note that `isOnline` and `isNotifiable` properties are eligible\n * for use only if the reachability function is enabled.\n * You may check if it is enabled by reading the value of {@link Client.reachabilityEnabled}.\n */\nclass User extends ReplayEventEmitter<UserEvents> {\n private links: UserLinks;\n private configuration: Configuration;\n private readonly services: UserServices;\n\n private entity: any;\n private state: UserState;\n private promiseToFetch: Promise<User> | null = null;\n private subscribed: SubscriptionState;\n\n private _initializationPromise: Promise<void>;\n private _resolveInitializationPromise: any;\n\n /**\n * @internal\n */\n constructor(\n identity: string,\n entityName: string,\n configuration: Configuration | null,\n services: UserServices\n ) {\n super();\n\n this.services = services;\n\n this.subscribed = 'initializing';\n this.setMaxListeners(0);\n\n this.state = {\n identity,\n entityName,\n friendlyName: null,\n attributes: {},\n online: null,\n notifiable: null\n };\n\n this._initializationPromise = new Promise((resolve) => {\n this._resolveInitializationPromise = resolve;\n });\n\n if (configuration !== null) {\n this._resolveInitialization(\n configuration,\n identity,\n entityName,\n false\n );\n }\n }\n\n /**\n * Fired when the properties or the reachability status of the message has been updated.\n *\n * Parameters:\n * 1. object `data` - info object provided with the event. It has the following properties:\n * * {@link User} `user` - the user in question\n * * {@link UserUpdateReason}[] `updateReasons` - array of reasons for the update\n * @event\n */\n public readonly updated = 'updated';\n\n /**\n * Fired when the client has subscribed to the user.\n *\n * Parameters:\n * 1. {@link User} `user` - the user in question\n * @event\n */\n public readonly userSubscribed = 'userSubscribed';\n\n /**\n * Fired when the client has unsubscribed from the user.\n *\n * Parameters:\n * 1. {@link User} `user` - the user in question\n * @event\n */\n public readonly userUnsubscribed = 'userUnsubscribed';\n\n /**\n * User identity.\n */\n public get identity(): string { return this.state.identity; }\n\n public set identity(identity: string) { this.state.identity = identity; }\n\n public set entityName(name: string) { this.state.entityName = name; }\n\n /**\n * Custom attributes of the user.\n */\n public get attributes() { return this.state.attributes; }\n\n /**\n * Friendly name of the user, null if not set.\n */\n public get friendlyName(): string { return this.state.friendlyName; }\n\n /**\n * Status of the real-time conversation connection of the user.\n */\n public get isOnline(): boolean { return this.state.online; }\n\n /**\n * User push notification registration status.\n */\n public get isNotifiable(): boolean { return this.state.notifiable; }\n\n /**\n * True if this user is receiving real-time status updates.\n */\n public get isSubscribed(): boolean { return this.subscribed == 'subscribed'; }\n\n // Handles service updates\n async _update(key: string, value: any) {\n await this._initializationPromise;\n\n let updateReasons: UserUpdateReason[] = [];\n log.debug('User for', this.state.identity, 'updated:', key, value);\n switch (key) {\n case 'friendlyName':\n if (this.state.friendlyName !== value.value) {\n updateReasons.push('friendlyName');\n this.state.friendlyName = value.value;\n }\n break;\n case 'attributes':\n const updateAttributes = parseAttributes(value.value, `Retrieved malformed attributes from the server for user: ${this.state.identity}`, log);\n if (!isEqual(this.state.attributes, updateAttributes)) {\n this.state.attributes = updateAttributes;\n updateReasons.push('attributes');\n }\n break;\n case 'reachability':\n if (this.state.online !== value.online) {\n this.state.online = value.online;\n updateReasons.push('reachabilityOnline');\n }\n if (this.state.notifiable !== value.notifiable) {\n this.state.notifiable = value.notifiable;\n updateReasons.push('reachabilityNotifiable');\n }\n break;\n default:\n return;\n }\n if (updateReasons.length > 0) {\n this.emit('updated', { user: this, updateReasons: updateReasons });\n }\n }\n\n // Fetch reachability info\n private async _updateReachabilityInfo(map, update) {\n await this._initializationPromise;\n\n if (!this.configuration.reachabilityEnabled) {\n return Promise.resolve();\n }\n\n return map.get('reachability')\n .then(update)\n .catch(err => { log.warn('Failed to get reachability info for ', this.state.identity, err); });\n }\n\n // Fetch user\n async _fetch(): Promise<User> {\n await this._initializationPromise;\n\n if (!this.state.entityName) {\n return this;\n }\n\n this.promiseToFetch = this.services.syncClient.map({\n id: this.state.entityName,\n mode: 'open_existing',\n includeItems: true\n })\n .then(map => {\n this.entity = map;\n map.on('itemUpdated', args => {\n log.debug(this.state.entityName + ' (' + this.state.identity + ') itemUpdated: ' + args.item.key);\n return this._update(args.item.key, args.item.data);\n });\n return Promise.all([\n map.get('friendlyName')\n .then(item => this._update(item.key, item.data)),\n map.get('attributes')\n .then(item => this._update(item.key, item.data)),\n this._updateReachabilityInfo(map,\n item => this._update(item.key, item.data))\n ]);\n })\n .then(() => {\n log.debug('Fetched for', this.identity);\n this.subscribed = 'subscribed';\n this.emit('userSubscribed', this);\n return this;\n })\n .catch(err => {\n this.promiseToFetch = null;\n throw err;\n });\n return this.promiseToFetch;\n }\n\n async _ensureFetched() {\n await this._initializationPromise;\n return this.promiseToFetch || this._fetch();\n }\n\n /**\n * Edit user attributes.\n * @param attributes New attributes.\n */\n @validateTypesAsync(['string', 'number', 'boolean', 'object', literal(null)])\n public async updateAttributes(attributes: any): Promise<User> {\n await this._initializationPromise;\n\n if (this.subscribed == 'unsubscribed') {\n throw new Error('Can\\'t modify unsubscribed object');\n }\n\n await this.services.commandExecutor.mutateResource<EditUserRequest, EditUserResponse>(\n 'post',\n this.links.self,\n {\n attributes: JSON.stringify(attributes)\n }\n );\n\n return this;\n }\n\n /**\n * Update the friendly name of the user.\n * @param friendlyName New friendly name.\n */\n @validateTypesAsync(['string'])\n public async updateFriendlyName(friendlyName: string): Promise<User> {\n await this._initializationPromise;\n\n if (this.subscribed == 'unsubscribed') {\n throw new Error('Can\\'t modify unsubscribed object');\n }\n\n await this.services.commandExecutor.mutateResource<EditUserRequest, EditUserResponse>(\n 'post',\n this.links.self,\n {\n friendly_name: friendlyName\n }\n );\n\n return this;\n }\n\n /**\n * Remove the user from the subscription list.\n * @return A promise of completion.\n */\n async unsubscribe(): Promise<void> {\n await this._initializationPromise;\n\n if (this.promiseToFetch) {\n await this.promiseToFetch;\n this.entity.close();\n this.promiseToFetch = null;\n this.subscribed = 'unsubscribed';\n this.emit('userUnsubscribed', this);\n }\n }\n\n public _resolveInitialization(\n configuration: Configuration,\n identity: string,\n entityName: string,\n emitUpdated: boolean\n ): void {\n this.configuration = configuration;\n this.identity = identity;\n this.entityName = entityName;\n this.links = {\n self: `${this.configuration.links.users}/${this.identity}`\n };\n this._resolveInitializationPromise();\n\n if (emitUpdated) {\n this.emit('updated', {\n user: this,\n updateReasons: [\n 'friendlyName',\n 'attributes',\n 'reachabilityOnline',\n 'reachabilityNotifiable'\n ]\n });\n }\n }\n}\n\nexport {\n User,\n UserServices,\n SubscriptionState,\n UserUpdateReason,\n UserUpdatedEventArgs\n};\n"],"names":["Logger","ReplayEventEmitter","parseAttributes","isEqual","__decorate","validateTypesAsync","literal"],"mappings":"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"}
1
+ {"version":3,"file":"user.js","sources":["../src/user.ts"],"sourcesContent":["import { Logger } from './logger';\nimport { SyncClient } from 'twilio-sync';\nimport { parseAttributes } from './util';\nimport { validateTypesAsync, literal } from '@twilio/declarative-type-validator';\nimport { attributesValidator } from './interfaces/attributes';\nimport { Configuration } from './configuration';\nimport { CommandExecutor } from './command-executor';\nimport { EditUserRequest, EditUserResponse } from './interfaces/commands/edit-user';\nimport { ReplayEventEmitter } from '@twilio/replay-event-emitter';\nimport isEqual from 'lodash.isequal';\n\ntype UserEvents = {\n updated: (data: {\n user: User,\n updateReasons: UserUpdateReason[]\n }) => void;\n userSubscribed: (user: User) => void;\n userUnsubscribed: (user: User) => void;\n};\n\nconst log = Logger.scope('User');\n\ninterface UserState {\n identity: string;\n entityName: string;\n friendlyName: string;\n attributes: any;\n online: boolean;\n notifiable: boolean;\n}\n\ninterface UserServices {\n syncClient: SyncClient;\n commandExecutor: CommandExecutor;\n}\n\ninterface UserLinks {\n self: string;\n}\n\ntype SubscriptionState = 'initializing' | 'subscribed' | 'unsubscribed';\n\n/**\n * The reason for the `updated` event being emitted by a user.\n */\ntype UserUpdateReason =\n | 'friendlyName'\n | 'attributes'\n | 'reachabilityOnline'\n | 'reachabilityNotifiable';\n\ninterface UserUpdatedEventArgs {\n user: User;\n updateReasons: UserUpdateReason[];\n}\n\n/**\n * Extended user information.\n * Note that `isOnline` and `isNotifiable` properties are eligible\n * for use only if the reachability function is enabled.\n * You may check if it is enabled by reading the value of {@link Client.reachabilityEnabled}.\n */\nclass User extends ReplayEventEmitter<UserEvents> {\n private links: UserLinks;\n private configuration: Configuration;\n private readonly services: UserServices;\n\n private entity: any;\n private state: UserState;\n private promiseToFetch: Promise<User> | null = null;\n private subscribed: SubscriptionState;\n\n private _initializationPromise: Promise<void>;\n private _resolveInitializationPromise: any;\n\n /**\n * @internal\n */\n constructor(\n identity: string,\n entityName: string,\n configuration: Configuration | null,\n services: UserServices\n ) {\n super();\n\n this.services = services;\n\n this.subscribed = 'initializing';\n this.setMaxListeners(0);\n\n this.state = {\n identity,\n entityName,\n friendlyName: null,\n attributes: {},\n online: null,\n notifiable: null\n };\n\n this._initializationPromise = new Promise((resolve) => {\n this._resolveInitializationPromise = resolve;\n });\n\n if (configuration !== null) {\n this._resolveInitialization(\n configuration,\n identity,\n entityName,\n false\n );\n }\n }\n\n /**\n * Fired when the properties or the reachability status of the message has been updated.\n *\n * Parameters:\n * 1. object `data` - info object provided with the event. It has the following properties:\n * * {@link User} `user` - the user in question\n * * {@link UserUpdateReason}[] `updateReasons` - array of reasons for the update\n * @event\n */\n public readonly updated = 'updated';\n\n /**\n * Fired when the client has subscribed to the user.\n *\n * Parameters:\n * 1. {@link User} `user` - the user in question\n * @event\n */\n public readonly userSubscribed = 'userSubscribed';\n\n /**\n * Fired when the client has unsubscribed from the user.\n *\n * Parameters:\n * 1. {@link User} `user` - the user in question\n * @event\n */\n public readonly userUnsubscribed = 'userUnsubscribed';\n\n /**\n * User identity.\n */\n public get identity(): string { return this.state.identity; }\n\n public set identity(identity: string) { this.state.identity = identity; }\n\n public set entityName(name: string) { this.state.entityName = name; }\n\n /**\n * Custom attributes of the user.\n */\n public get attributes() { return this.state.attributes; }\n\n /**\n * Friendly name of the user, null if not set.\n */\n public get friendlyName(): string { return this.state.friendlyName; }\n\n /**\n * Status of the real-time conversation connection of the user.\n */\n public get isOnline(): boolean { return this.state.online; }\n\n /**\n * User push notification registration status.\n */\n public get isNotifiable(): boolean { return this.state.notifiable; }\n\n /**\n * True if this user is receiving real-time status updates.\n */\n public get isSubscribed(): boolean { return this.subscribed == 'subscribed'; }\n\n // Handles service updates\n async _update(key: string, value: any) {\n await this._initializationPromise;\n\n let updateReasons: UserUpdateReason[] = [];\n log.debug('User for', this.state.identity, 'updated:', key, value);\n switch (key) {\n case 'friendlyName':\n if (this.state.friendlyName !== value.value) {\n updateReasons.push('friendlyName');\n this.state.friendlyName = value.value;\n }\n break;\n case 'attributes':\n const updateAttributes = parseAttributes(value.value, `Retrieved malformed attributes from the server for user: ${this.state.identity}`, log);\n if (!isEqual(this.state.attributes, updateAttributes)) {\n this.state.attributes = updateAttributes;\n updateReasons.push('attributes');\n }\n break;\n case 'reachability':\n if (this.state.online !== value.online) {\n this.state.online = value.online;\n updateReasons.push('reachabilityOnline');\n }\n if (this.state.notifiable !== value.notifiable) {\n this.state.notifiable = value.notifiable;\n updateReasons.push('reachabilityNotifiable');\n }\n break;\n default:\n return;\n }\n if (updateReasons.length > 0) {\n this.emit('updated', { user: this, updateReasons: updateReasons });\n }\n }\n\n // Fetch reachability info\n private async _updateReachabilityInfo(map, update) {\n await this._initializationPromise;\n\n if (!this.configuration.reachabilityEnabled) {\n return Promise.resolve();\n }\n\n return map.get('reachability')\n .then(update)\n .catch(err => { log.warn('Failed to get reachability info for ', this.state.identity, err); });\n }\n\n // Fetch user\n async _fetch(): Promise<User> {\n await this._initializationPromise;\n\n if (!this.state.entityName) {\n return this;\n }\n\n this.promiseToFetch = this.services.syncClient.map({\n id: this.state.entityName,\n mode: 'open_existing',\n includeItems: true\n })\n .then(map => {\n this.entity = map;\n map.on('itemUpdated', args => {\n log.debug(this.state.entityName + ' (' + this.state.identity + ') itemUpdated: ' + args.item.key);\n return this._update(args.item.key, args.item.data);\n });\n return Promise.all([\n map.get('friendlyName')\n .then(item => this._update(item.key, item.data)),\n map.get('attributes')\n .then(item => this._update(item.key, item.data)),\n this._updateReachabilityInfo(map,\n item => this._update(item.key, item.data))\n ]);\n })\n .then(() => {\n log.debug('Fetched for', this.identity);\n this.subscribed = 'subscribed';\n this.emit('userSubscribed', this);\n return this;\n })\n .catch(err => {\n this.promiseToFetch = null;\n throw err;\n });\n return this.promiseToFetch;\n }\n\n async _ensureFetched() {\n await this._initializationPromise;\n return this.promiseToFetch || this._fetch();\n }\n\n /**\n * Edit user attributes.\n * @param attributes New attributes.\n */\n @validateTypesAsync(attributesValidator)\n public async updateAttributes(attributes: any): Promise<User> {\n await this._initializationPromise;\n\n if (this.subscribed == 'unsubscribed') {\n throw new Error('Can\\'t modify unsubscribed object');\n }\n\n await this.services.commandExecutor.mutateResource<EditUserRequest, EditUserResponse>(\n 'post',\n this.links.self,\n {\n attributes: JSON.stringify(attributes)\n }\n );\n\n return this;\n }\n\n /**\n * Update the friendly name of the user.\n * @param friendlyName New friendly name.\n */\n @validateTypesAsync(['string'])\n public async updateFriendlyName(friendlyName: string): Promise<User> {\n await this._initializationPromise;\n\n if (this.subscribed == 'unsubscribed') {\n throw new Error('Can\\'t modify unsubscribed object');\n }\n\n await this.services.commandExecutor.mutateResource<EditUserRequest, EditUserResponse>(\n 'post',\n this.links.self,\n {\n friendly_name: friendlyName\n }\n );\n\n return this;\n }\n\n /**\n * Remove the user from the subscription list.\n * @return A promise of completion.\n */\n async unsubscribe(): Promise<void> {\n await this._initializationPromise;\n\n if (this.promiseToFetch) {\n await this.promiseToFetch;\n this.entity.close();\n this.promiseToFetch = null;\n this.subscribed = 'unsubscribed';\n this.emit('userUnsubscribed', this);\n }\n }\n\n public _resolveInitialization(\n configuration: Configuration,\n identity: string,\n entityName: string,\n emitUpdated: boolean\n ): void {\n this.configuration = configuration;\n this.identity = identity;\n this.entityName = entityName;\n this.links = {\n self: `${this.configuration.links.users}/${this.identity}`\n };\n this._resolveInitializationPromise();\n\n if (emitUpdated) {\n this.emit('updated', {\n user: this,\n updateReasons: [\n 'friendlyName',\n 'attributes',\n 'reachabilityOnline',\n 'reachabilityNotifiable'\n ]\n });\n }\n }\n}\n\nexport {\n User,\n UserServices,\n SubscriptionState,\n UserUpdateReason,\n UserUpdatedEventArgs\n};\n"],"names":["Logger","ReplayEventEmitter","parseAttributes","isEqual","__decorate","validateTypesAsync","attributesValidator"],"mappings":"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"}